1 //this file is part of notepad++
2 //Copyright (C)2003 Don HO <donho@altern.org>
3 //
4 //This program is free software; you can redistribute it and/or
5 //modify it under the terms of the GNU General Public License
6 //as published by the Free Software Foundation; either
7 //version 2 of the License, or (at your option) any later version.
8 //
9 //This program is distributed in the hope that it will be useful,
10 //but WITHOUT ANY WARRANTY; without even the implied warranty of
11 //MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12 //GNU General Public License for more details.
13 //
14 //You should have received a copy of the GNU General Public License
15 //along with this program; if not, write to the Free Software
16 //Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
17 /**
18  * plugin demo
19  *
20  * License: GPL-2.0 or later
21  */
22 module npp_demo.commands;
23 
24 
25 private static import core.stdc.stdint;
26 private static import core.stdc.stdio;
27 private static import core.stdc.stdlib;
28 private static import core.stdc.string;
29 private static import core.stdc.time;
30 private static import core.sys.windows.basetsd;
31 private static import core.sys.windows.winbase;
32 private static import core.sys.windows.windef;
33 private static import core.sys.windows.winnls;
34 private static import core.sys.windows.winnt;
35 private static import core.sys.windows.winuser;
36 private static import npp_api.PowerEditor.MISC.PluginsManager.Notepad_plus_msgs;
37 private static import npp_api.PowerEditor.MISC.PluginsManager.PluginInterface;
38 private static import npp_api.PowerEditor.ScitillaComponent.GoToLineDlg;
39 private static import npp_api.PowerEditor.WinControls.DockingWnd.Docking;
40 private static import npp_api.PowerEditor.menuCmdID;
41 private static import npp_api.pluginfunc.npp_msgs;
42 private static import npp_api.pluginfunc.path;
43 private static import npp_api.pluginfunc.scintilla_msg;
44 private static import npp_api.pluginfunc.string;
45 private static import npp_api.scintilla.Scintilla;
46 private static import npp_demo.GoToLineDlg;
47 private static import npp_demo.plugin_dll;
48 private static import std.path;
49 private static import std.string;
50 
51 version (Windows):
52 
53 //pragma(lib, "kernel32");
54 //pragma(lib, "user32");
55 
56 enum DOCKABLE_DEMO_INDEX = 15;
57 enum bool shortDate = true;
58 enum bool longDate = false;
59 
60 extern (C)
61 extern npp_api.PowerEditor.MISC.PluginsManager.PluginInterface.NppData nppData;
62 
63 extern (C)
64 extern __gshared npp_api.PowerEditor.MISC.PluginsManager.PluginInterface.NppData gshared_nppData;
65 
66 /**
67  * 
68  */
69 extern (Windows)
70 nothrow @nogc
71 package core.sys.windows.windef.DWORD threadZoomer(void*)
72 
73 	in
74 	{
75 	}
76 
77 	do
78 	{
79 		// Get the current scintilla
80 		int currentEdit = -1;
81 		npp_api.pluginfunc.npp_msgs.send_NPPM_GETCURRENTSCINTILLA(.gshared_nppData._nppHandle, currentEdit);
82 
83 		if (currentEdit == -1) {
84 			return core.sys.windows.windef.FALSE;
85 		}
86 
87 		core.sys.windows.windef.HWND curScintilla = (currentEdit == 0) ? (.gshared_nppData._scintillaMainHandle) : (.gshared_nppData._scintillaSecondHandle);
88 
89 		core.stdc.stdint.intptr_t currentZoomLevel = npp_api.pluginfunc.scintilla_msg.send_SCI_GETZOOM(curScintilla);
90 
91 		core.stdc.stdint.intptr_t i = currentZoomLevel;
92 
93 		for (size_t j = 0 ; j < 4 ; ++j) {
94 			for ( ; i >= -10 ; i--) {
95 				npp_api.pluginfunc.scintilla_msg.send_SCI_SETZOOM(curScintilla, i);
96 				core.sys.windows.winbase.Sleep(30);
97 			}
98 
99 			core.sys.windows.winbase.Sleep(100);
100 
101 			for ( ; i <= 20 ; ++i) {
102 				core.sys.windows.winbase.Sleep(30);
103 				npp_api.pluginfunc.scintilla_msg.send_SCI_SETZOOM(curScintilla, i);
104 			}
105 
106 			core.sys.windows.winbase.Sleep(100);
107 		}
108 
109 		core.sys.windows.winbase.Sleep(100);
110 
111 		for ( ; i >= currentZoomLevel ; i--) {
112 			core.sys.windows.winbase.Sleep(30);
113 			npp_api.pluginfunc.scintilla_msg.send_SCI_SETZOOM(curScintilla, i);
114 		}
115 
116 		return core.sys.windows.windef.TRUE;
117 	}
118 
119 /**
120  * 
121  */
122 extern (Windows)
123 nothrow @nogc
124 package core.sys.windows.windef.DWORD threadTextPlayer(void* text2display)
125 
126 	in
127 	{
128 	}
129 
130 	do
131 	{
132 		enum RAND_MAX = 0x7FFF;
133 
134 		// Open a new document
135 		npp_api.pluginfunc.npp_msgs.send_NPPM_MENUCOMMAND(.gshared_nppData._nppHandle, npp_api.PowerEditor.menuCmdID.IDM_FILE_NEW);
136 
137 		// Get the current scintilla
138 		int currentEdit = -1;
139 		npp_api.pluginfunc.npp_msgs.send_NPPM_GETCURRENTSCINTILLA(.gshared_nppData._nppHandle, currentEdit);
140 
141 		if (currentEdit == -1) {
142 			return core.sys.windows.windef.FALSE;
143 		}
144 
145 		core.sys.windows.windef.HWND curScintilla = (currentEdit == 0) ? (.gshared_nppData._scintillaMainHandle) : (.gshared_nppData._scintillaSecondHandle);
146 		core.stdc.stdlib.srand(cast(uint)(core.stdc.time.time(core.sys.windows.windef.NULL)));
147 		int rangeMin = 0;
148 		int rangeMax = 250;
149 		size_t length = core.stdc..string.strlen(cast(char*)(text2display));
150 
151 		for (size_t i = 0 ; i < length; ++i) {
152 			char[2] charToShow = [*((cast(char*)(text2display)) + i), '\0'];
153 
154 			version (none) {
155 				int ranNum = rangeMin + cast(int)(cast(double)(core.stdc.stdlib.rand()) / (cast(double)(RAND_MAX) + 1) * rangeMax);
156 				core.sys.windows.winbase.Sleep(ranNum + 30);
157 			}
158 
159 			npp_api.pluginfunc.scintilla_msg.send_SCI_APPENDTEXT(curScintilla, 1, &(charToShow[0]));
160 			npp_api.pluginfunc.scintilla_msg.send_SCI_GOTOPOS(curScintilla, npp_api.pluginfunc.scintilla_msg.send_SCI_GETLENGTH(curScintilla));
161 		}
162 
163 		return core.sys.windows.windef.TRUE;
164 	}
165 
166 /**
167  * plugin command
168  */
169 extern (C)
170 nothrow @nogc
171 void hello()
172 
173 	do
174 	{
175 		// Open a new document
176 		npp_api.pluginfunc.npp_msgs.send_NPPM_MENUCOMMAND(.nppData._nppHandle, npp_api.PowerEditor.menuCmdID.IDM_FILE_NEW);
177 
178 		// Get the current scintilla
179 		int currentEdit = -1;
180 		npp_api.pluginfunc.npp_msgs.send_NPPM_GETCURRENTSCINTILLA(.nppData._nppHandle, currentEdit);
181 
182 		if (currentEdit == -1) {
183 			return;
184 		}
185 
186 		core.sys.windows.windef.HWND curScintilla = (currentEdit == 0) ? (.nppData._scintillaMainHandle) : (.nppData._scintillaSecondHandle);
187 
188 		// Say hello now :
189 		// Scintilla control has no Unicode mode, so we use (char*) here
190 		enum string msg_text = "Hello, Notepad++!\0";
191 		npp_api.pluginfunc.scintilla_msg.send_SCI_SETTEXT(curScintilla, &(msg_text[0]));
192 	}
193 
194 /**
195  * plugin command
196  */
197 extern (C)
198 nothrow @nogc
199 void helloFX()
200 
201 	do
202 	{
203 		hello();
204 		core.sys.windows.basetsd.HANDLE hThread = core.sys.windows.winbase.CreateThread(core.sys.windows.windef.NULL, 0, &threadZoomer, core.sys.windows.windef.NULL, 0, core.sys.windows.windef.NULL);
205 		core.sys.windows.winbase.CloseHandle(hThread);
206 	}
207 
208 /**
209  * plugin command
210  */
211 extern (C)
212 nothrow @nogc
213 void WhatIsNpp()
214 
215 	do
216 	{
217 		string text2display = `Notepad++ is a free (as in "free speech" and also as in "free beer") source code editor and Notepad replacement that supports several languages.
218 		Running in the MS Windows environment, its use is governed by GPL License.
219 
220 Based on a powerful editing component Scintilla, Notepad++ is written in C++ and uses pure Win32 API and STL which ensures a higher execution speed and smaller program size.
221 By optimizing as many routines as possible without losing user friendliness, Notepad++ is trying to reduce the world carbon dioxide emissions. When using less CPU power, the PC can throttle down and reduce power consumption, resulting in a greener environment.` ~ "\0";
222 		core.sys.windows.basetsd.HANDLE hThread = core.sys.windows.winbase.CreateThread(core.sys.windows.windef.NULL, 0, &.threadTextPlayer, cast(core.sys.windows.winnt.LPVOID*)(&(text2display[0])), 0, core.sys.windows.windef.NULL);
223 		core.sys.windows.winbase.CloseHandle(hThread);
224 	}
225 
226 /**
227  * 
228  */
229 nothrow @nogc
230 void insertCurrentPath(int which)
231 
232 	do
233 	{
234 		int msg;
235 
236 		switch (which) {
237 			case npp_api.PowerEditor.MISC.PluginsManager.Notepad_plus_msgs.FILE_NAME:
238 				msg = npp_api.PowerEditor.MISC.PluginsManager.Notepad_plus_msgs.NPPM_GETFILENAME;
239 
240 				break;
241 
242 			case npp_api.PowerEditor.MISC.PluginsManager.Notepad_plus_msgs.CURRENT_DIRECTORY:
243 				msg = npp_api.PowerEditor.MISC.PluginsManager.Notepad_plus_msgs.NPPM_GETCURRENTDIRECTORY;
244 
245 				break;
246 
247 			default:
248 				msg = npp_api.PowerEditor.MISC.PluginsManager.Notepad_plus_msgs.NPPM_GETFULLCURRENTPATH;
249 
250 				break;
251 		}
252 
253 		int currentEdit;
254 		core.sys.windows.winnt.WCHAR[npp_api.pluginfunc.path.OS_MAX_PATH] path = '\0';
255 
256 		// A message to Notepad++ to get a multibyte string (if ANSI mode) or a wide char string (if Unicode mode)
257 		core.sys.windows.winuser.SendMessageW(.nppData._nppHandle, msg, path.length, cast(core.sys.windows.windef.LPARAM)(&(path[0])));
258 
259 		//
260 		npp_api.pluginfunc.npp_msgs.send_NPPM_GETCURRENTSCINTILLA(.nppData._nppHandle, currentEdit);
261 		core.sys.windows.windef.HWND curScint = (currentEdit == 0) ? (.nppData._scintillaMainHandle) : (.nppData._scintillaSecondHandle);
262 
263 		int encoding = cast(int)(npp_api.pluginfunc.scintilla_msg.send_SCI_GETCODEPAGE(curScint));
264 		char[core.sys.windows.windef.MAX_PATH] pathA;
265 		core.sys.windows.winnls.WideCharToMultiByte(encoding, 0, &(path[0]), -1, &(pathA[0]), core.sys.windows.windef.MAX_PATH, core.sys.windows.windef.NULL, core.sys.windows.windef.NULL);
266 		npp_api.pluginfunc.scintilla_msg.send_SCI_REPLACESEL(curScint, &(pathA[0]));
267 	}
268 
269 /**
270  * plugin command
271  */
272 extern (C)
273 nothrow @nogc
274 void insertCurrentFullPath()
275 
276 	do
277 	{
278 		.insertCurrentPath(npp_api.PowerEditor.MISC.PluginsManager.Notepad_plus_msgs.FULL_CURRENT_PATH);
279 	}
280 
281 /**
282  * plugin command
283  */
284 extern (C)
285 nothrow @nogc
286 void insertCurrentFileName()
287 
288 	do
289 	{
290 		.insertCurrentPath(npp_api.PowerEditor.MISC.PluginsManager.Notepad_plus_msgs.FILE_NAME);
291 	}
292 
293 /**
294  * plugin command
295  */
296 extern (C)
297 nothrow
298 void insertCurrentDirectory()
299 
300 	do
301 	{
302 		.insertCurrentPath(npp_api.PowerEditor.MISC.PluginsManager.Notepad_plus_msgs.CURRENT_DIRECTORY);
303 	}
304 
305 /**
306  * 
307  */
308 nothrow @nogc
309 void insertDateTime(bool format)
310 
311 	do
312 	{
313 		core.sys.windows.winnt.WCHAR[128] date;
314 		core.sys.windows.winnt.WCHAR[128] time;
315 		core.sys.windows.winnt.WCHAR[256] dateTime;
316 
317 		core.sys.windows.winbase.SYSTEMTIME st;
318 		core.sys.windows.winbase.GetLocalTime(&st);
319 		core.sys.windows.winnls.GetDateFormatW(core.sys.windows.winnls.LOCALE_USER_DEFAULT, ((format == .shortDate) ? (core.sys.windows.winnls.DATE_SHORTDATE) : (core.sys.windows.winnls.DATE_LONGDATE)), &st, core.sys.windows.windef.NULL, &(date[0]), 128);
320 		core.sys.windows.winnls.GetTimeFormatW(core.sys.windows.winnls.LOCALE_USER_DEFAULT, core.sys.windows.winnls.TIME_NOSECONDS, &st, core.sys.windows.windef.NULL, &(time[0]), 128);
321 
322 		core.sys.windows.winuser.wsprintfW(&(dateTime[0]), &(npp_api.pluginfunc..string.c_wstring!("%s %s"w)[0]), &(time[0]), &(date[0]));
323 
324 		int currentEdit;
325 		npp_api.pluginfunc.npp_msgs.send_NPPM_GETCURRENTSCINTILLA(.nppData._nppHandle, currentEdit);
326 		core.sys.windows.windef.HWND curScint = (currentEdit == 0) ? (.nppData._scintillaMainHandle) : (.nppData._scintillaSecondHandle);
327 		int encoding = cast(int)(npp_api.pluginfunc.scintilla_msg.send_SCI_GETCODEPAGE(curScint));
328 		char[core.sys.windows.windef.MAX_PATH] dateTimeA;
329 		core.sys.windows.winnls.WideCharToMultiByte(encoding, 0, &(dateTime[0]), -1, &(dateTimeA[0]), core.sys.windows.windef.MAX_PATH, core.sys.windows.windef.NULL, core.sys.windows.windef.NULL);
330 		npp_api.pluginfunc.scintilla_msg.send_SCI_REPLACESEL(curScint, &(dateTimeA[0]));
331 	}
332 
333 /**
334  * plugin command
335  */
336 extern (C)
337 nothrow @nogc
338 void insertShortDateTime()
339 
340 	do
341 	{
342 		.insertDateTime(.shortDate);
343 	}
344 
345 /**
346  * plugin command
347  */
348 extern (C)
349 nothrow @nogc
350 void insertLongDateTime()
351 
352 	do
353 	{
354 		.insertDateTime(.longDate);
355 	}
356 
357 /**
358  * plugin command
359  */
360 extern (C)
361 nothrow @nogc
362 void getFileNamesDemo()
363 
364 	do
365 	{
366 		size_t malloc_count = 0;
367 		int nbFile = cast(int)(npp_api.pluginfunc.npp_msgs.send_NPPM_GETNBOPENFILES(.nppData._nppHandle, npp_api.PowerEditor.MISC.PluginsManager.Notepad_plus_msgs.ALL_OPEN_FILES));
368 		char[16] temp = '\0';
369 
370 		if (nbFile > 1) {
371 			nbFile--;
372 		}
373 
374 		core.stdc.stdio.snprintf(&(temp[0]), 4, &("%d\0"[0]), nbFile);
375 		core.sys.windows.winuser.MessageBoxA(.nppData._nppHandle, &(temp[0]), &("Notepad++ opened files\0"[0]), core.sys.windows.winuser.MB_OK);
376 
377 		core.sys.windows.winnt.WCHAR** fileNames = cast(core.sys.windows.winnt.WCHAR**)(core.stdc.stdlib.malloc((core.sys.windows.winnt.WCHAR*).sizeof * nbFile));
378 
379 		if (fileNames == null) {
380 			return;
381 		}
382 
383 		scope (exit) {
384 			core.stdc.stdlib.free(fileNames);
385 			fileNames = null;
386 		}
387 
388 		for (size_t i = 0 ; i < nbFile; ++i) {
389 			*(fileNames + i) = cast(core.sys.windows.winnt.WCHAR*)(core.stdc.stdlib.malloc(core.sys.windows.winnt.WCHAR.sizeof * core.sys.windows.windef.MAX_PATH));
390 
391 			if ((*(fileNames + i)) == null) {
392 				for (size_t j; j < malloc_count; ++j) {
393 					core.stdc.stdlib.free(*(fileNames + j));
394 				}
395 
396 				return;
397 			}
398 
399 			++malloc_count;
400 		}
401 
402 		scope (exit) {
403 			for (size_t j; j < malloc_count; ++j) {
404 				core.stdc.stdlib.free(*(fileNames + j));
405 				fileNames[j] = null;
406 			}
407 		}
408 
409 		if (npp_api.pluginfunc.npp_msgs.send_NPPM_GETOPENFILENAMES(.nppData._nppHandle, fileNames, nbFile)) {
410 			for (size_t i = 0 ; i < nbFile; ++i) {
411 				core.sys.windows.winuser.MessageBoxW(.nppData._nppHandle, *(fileNames + i), &("\0"w[0]), core.sys.windows.winuser.MB_OK);
412 			}
413 		}
414 	}
415 
416 /**
417  * plugin command
418  */
419 extern (C)
420 nothrow @nogc
421 void getSessionFileNamesDemo()
422 
423 	do
424 	{
425 		size_t malloc_count = 0;
426 		const core.sys.windows.winnt.WCHAR[] sessionFullPath = npp_api.pluginfunc..string.c_wstring!("c:\\test.session"w);
427 		char[16] temp = '\0';
428 		size_t nbFile = npp_api.pluginfunc.npp_msgs.send_NPPM_GETNBSESSIONFILES(.nppData._nppHandle, &(sessionFullPath[0]));
429 
430 		if (nbFile == 0) {
431 			core.sys.windows.winuser.MessageBoxW(.nppData._nppHandle, &(npp_api.pluginfunc..string.c_wstring!("Please modify \"sessionFullPath\" in \"NppInsertPlugin.cpp\" in order to point to a valide session file")[0]), &(npp_api.pluginfunc..string.c_wstring!("Error :"w)[0]), core.sys.windows.winuser.MB_OK);
432 
433 			return;
434 		}
435 
436 		core.stdc.stdio.snprintf(&(temp[0]), 4, &("%d\0"[0]), nbFile);
437 		core.sys.windows.winuser.MessageBoxA(.nppData._nppHandle, &(temp[0]), &("Notepad++ session files\0"[0]), core.sys.windows.winuser.MB_OK);
438 
439 		core.sys.windows.winnt.WCHAR** fileNames = cast(core.sys.windows.winnt.WCHAR**)(core.stdc.stdlib.malloc((core.sys.windows.winnt.WCHAR*).sizeof * nbFile));
440 
441 		if (fileNames == null) {
442 			return;
443 		}
444 
445 		scope (exit) {
446 			core.stdc.stdlib.free(fileNames);
447 			fileNames = null;
448 		}
449 
450 		for (size_t i = 0 ; i < nbFile; ++i) {
451 			*(fileNames + i) = cast(core.sys.windows.winnt.WCHAR*)(core.stdc.stdlib.malloc(core.sys.windows.winnt.WCHAR.sizeof * core.sys.windows.windef.MAX_PATH));
452 
453 			if ((*(fileNames + i)) == null) {
454 				for (size_t j; j < malloc_count; ++j) {
455 					core.stdc.stdlib.free(*(fileNames + j));
456 				}
457 
458 				return;
459 			}
460 
461 			++malloc_count;
462 		}
463 
464 		scope (exit) {
465 			for (size_t j; j < malloc_count; ++j) {
466 				core.stdc.stdlib.free(*(fileNames + j));
467 				fileNames[j] = null;
468 			}
469 		}
470 
471 		if (npp_api.pluginfunc.npp_msgs.send_NPPM_GETSESSIONFILES(.nppData._nppHandle, fileNames, &(sessionFullPath[0]))) {
472 			for (size_t i = 0 ; i < nbFile ; ++i) {
473 				core.sys.windows.winuser.MessageBoxW(.nppData._nppHandle, *(fileNames + i), &(npp_api.pluginfunc..string.c_wstring!("session file name :"w)[0]), core.sys.windows.winuser.MB_OK);
474 			}
475 		}
476 	}
477 
478 /**
479  * plugin command
480  */
481 extern (C)
482 nothrow @nogc
483 void saveCurrentSessionDemo()
484 
485 	do
486 	{
487 		const (core.sys.windows.winnt.WCHAR)* sessionPath = npp_api.pluginfunc.npp_msgs.send_NPPM_SAVECURRENTSESSION(.nppData._nppHandle, core.sys.windows.windef.NULL);
488 
489 		if (sessionPath != null) {
490 			core.sys.windows.winuser.MessageBoxW(.nppData._nppHandle, sessionPath, &(npp_api.pluginfunc..string.c_wstring!("Saved Session File :"w)[0]), core.sys.windows.winuser.MB_OK);
491 		}
492 	}
493 
494 /**
495  * plugin command
496  * Dockable Dialog Demo
497  *
498  * This demonstration shows you how to do a dockable dialog.
499  * You can create your own non dockable dialog - in this case you don't nedd this demonstration.
500  * You have to create your dialog by inherented DockingDlgInterface class in order to make your dialog dockable
501  * - please see DemoDlg.h and DemoDlg.cpp to have more informations.
502  */
503 extern (C)
504 nothrow
505 void DockableDlgDemo()
506 
507 	do
508 	{
509 		npp_demo.GoToLineDlg._goToLine.setParent(.gshared_nppData._nppHandle);
510 		npp_api.PowerEditor.WinControls.DockingWnd.Docking.tTbData data;
511 
512 		try {
513 			if (!npp_demo.GoToLineDlg._goToLine.isCreated()) {
514 				npp_demo.GoToLineDlg._goToLine.create(&npp_demo.GoToLineDlg._goToLine, data);
515 
516 				// define the default docking behaviour
517 				data.uMask = npp_api.PowerEditor.WinControls.DockingWnd.Docking.DWS_DF_CONT_RIGHT;
518 
519 				data.pszModuleName = npp_demo.GoToLineDlg._goToLine.getPluginFileName();
520 
521 				// the dlgDlg should be the index of func_list where the current function pointer is
522 				// in this case is DOCKABLE_DEMO_INDEX
523 				data.dlgID = .DOCKABLE_DEMO_INDEX;
524 				npp_api.pluginfunc.npp_msgs.send_NPPM_DMMREGASDCKDLG(.gshared_nppData._nppHandle, &data);
525 			}
526 
527 			npp_demo.GoToLineDlg._goToLine.display();
528 		} catch (Exception e) {
529 			//ToDo:
530 			core.sys.windows.winuser.MessageBoxW(.nppData._nppHandle, &("Exception\0"w[0]), &(npp_demo.plugin_dll.plugin_name[0]), core.sys.windows.winuser.MB_OK);
531 		}
532 	}