Update kleopatra
[gpg4win.git] / src / Memento.nsh
1 /* FIXME: Taken from nsis 2.28.  Remove when bumping version requirement.  */\r
2 \r
3 !verbose push\r
4 !verbose 3\r
5 \r
6 !include LogicLib.nsh\r
7 !include Sections.nsh\r
8 \r
9 !ifndef ___MEMENTO_NSH___\r
10 !define ___MEMENTO_NSH___\r
11 \r
12 #####################################\r
13 ### Memento                       ###\r
14 #####################################\r
15 \r
16 /*\r
17 \r
18 Memento is a set of macros that allow installers to remember user selection\r
19 across separate runs of the installer. Currently, it can remember the state\r
20 of sections and mark new sections as bold. In the future, it'll integrate\r
21 InstallOptions and maybe even the Modern UI.\r
22 \r
23 A usage example can be found in `Examples\Memento.nsi`.\r
24 \r
25 */\r
26 \r
27 #####################################\r
28 ### Usage Instructions            ###\r
29 #####################################\r
30 \r
31 /*\r
32 \r
33 1. Declare usage of Memento by including Memento.nsh at the top of the script.\r
34 \r
35       !include Memento.nsh\r
36 \r
37 2. Define MEMENTO_REGISTRY_ROOT and MEMENTO_REGISTRY_KEY with the a registry key\r
38    where sections' state should be saved.\r
39 \r
40       !define MEMENTO_REGISTRY_ROOT HKLM\r
41       !define MEMENTO_REGISTRY_KEY \\r
42                 Software\Microsoft\Windows\CurrentVersion\Uninstall\MyProgram\r
43 \r
44 3. Replace Section with ${MementoSection} and SectionEnd with ${MementoSectionEnd}\r
45    for sections that whose state should be remembered by Memento.\r
46 \r
47    For sections that should be unselected by default, use ${MementoSection}'s\r
48    brother - ${MementoUnselectedSection}.\r
49 \r
50    Sections that don't already have an identifier must be assigned one.\r
51 \r
52    Section identifiers must stay the same across different versions of the\r
53    installer or their state will be forgotten.\r
54 \r
55 4. Add a call to ${MementoSectionRestore} to .onInit to restore the state\r
56    of all sections from the registry.\r
57 \r
58       Function .onInit\r
59 \r
60         ${MementoSectionRestore}\r
61 \r
62       FunctionEnd\r
63 \r
64 5. Add a call to ${MementoSectionSave} to .onInstSuccess to save the state\r
65    of all sections to the registry.\r
66 \r
67       Function .onInstSuccess\r
68 \r
69         ${MementoSectionSave}\r
70 \r
71       FunctionEnd\r
72 \r
73 6. Tattoo the location of the chosen registry key on your arm.\r
74 \r
75 */\r
76 \r
77 #####################################\r
78 ### User API                      ###\r
79 #####################################\r
80 \r
81 ;\r
82 ; ${MementoSection}\r
83 ;\r
84 ;   Defines a section whose state is remembered by Memento.\r
85 ;\r
86 ;   Usage is similar to Section.\r
87 ;\r
88 ;     ${MementoSection} "name" "some_id"\r
89 ;\r
90 \r
91 !define MementoSection "!insertmacro MementoSection"\r
92 \r
93 ;\r
94 ; ${MementoSectionEnd}\r
95 ;\r
96 ;   Ends a section previously opened using ${MementoSection}.\r
97 ;\r
98 ;   Usage is similar to SectionEnd.\r
99 ;\r
100 ;     ${MementoSection} "name" "some_id"\r
101 ;        # some code...\r
102 ;     ${MementoSectionEnd}\r
103 ;\r
104 \r
105 ;\r
106 ; ${MementoUnselectedSection}\r
107 ;\r
108 ;   Defines a section whose state is remembered by Memento and is\r
109 ;   unselected by default.\r
110 ;\r
111 ;   Usage is similar to Section with the /o switch.\r
112 ;\r
113 ;     ${MementoUnselectedSection} "name" "some_id"\r
114 ;\r
115 \r
116 !define MementoUnselectedSection "!insertmacro MementoUnselectedSection"\r
117 \r
118 ;\r
119 ; ${MementoSectionEnd}\r
120 ;\r
121 ;   Ends a section previously opened using ${MementoSection}.\r
122 ;\r
123 ;   Usage is similar to SectionEnd.\r
124 ;\r
125 ;     ${MementoSection} "name" "some_id"\r
126 ;        # some code...\r
127 ;     ${MementoSectionEnd}\r
128 ;\r
129 \r
130 !define MementoSectionEnd "!insertmacro MementoSectionEnd"\r
131 \r
132 ;\r
133 ; ${MementoSectionDone}\r
134 ;\r
135 ;   Used after all ${MementoSection} have been set.\r
136 ;\r
137 ;     ${MementoSection} "name1" "some_id1"\r
138 ;        # some code...\r
139 ;     ${MementoSectionEnd}\r
140 ;\r
141 ;     ${MementoSection} "name2" "some_id2"\r
142 ;        # some code...\r
143 ;     ${MementoSectionEnd}\r
144 ;\r
145 ;     ${MementoSection} "name3" "some_id3"\r
146 ;        # some code...\r
147 ;     ${MementoSectionEnd}\r
148 ;\r
149 ;     ${MementoSectionDone}\r
150 ;\r
151 \r
152 !define MementoSectionDone "!insertmacro MementoSectionDone"\r
153 \r
154 ;\r
155 ; ${MementoSectionRestore}\r
156 ;\r
157 ;   Restores the state of all Memento sections from the registry.\r
158 ;\r
159 ;   Commonly used in .onInit.\r
160 ;\r
161 ;     Function .onInit\r
162 ;\r
163 ;       ${MementoSectionRestore}\r
164 ;\r
165 ;     FunctionEnd\r
166 ;\r
167 \r
168 !define MementoSectionRestore "!insertmacro MementoSectionRestore"\r
169 \r
170 ;\r
171 ; ${MementoSectionSave}\r
172 ;\r
173 ;   Saves the state of all Memento sections to the registry.\r
174 ;\r
175 ;   Commonly used in .onInstSuccess.\r
176 ;\r
177 ;     Function .onInstSuccess\r
178 ;\r
179 ;       ${MementoSectionSave}\r
180 ;\r
181 ;     FunctionEnd\r
182 ;\r
183 \r
184 !define MementoSectionSave "!insertmacro MementoSectionSave"\r
185 \r
186 \r
187 #####################################\r
188 ### Internal Defines              ###\r
189 #####################################\r
190 \r
191 !define __MementoSectionIndex 1\r
192 \r
193 #####################################\r
194 ### Internal Macros               ###\r
195 #####################################\r
196 \r
197 !macro __MementoCheckSettings\r
198 \r
199   !ifndef MEMENTO_REGISTRY_ROOT | MEMENTO_REGISTRY_KEY\r
200 \r
201     !error "MEMENTO_REGISTRY_ROOT and MEMENTO_REGISTRY_KEY must be defined before using any of Memento's macros"\r
202 \r
203   !endif\r
204 \r
205 !macroend\r
206 \r
207 !macro __MementoSection flags name id\r
208 \r
209   !insertmacro __MementoCheckSettings\r
210 \r
211   !ifndef __MementoSectionIndex\r
212 \r
213     !error "MementoSectionDone already used!"\r
214 \r
215   !endif\r
216 \r
217   !define __MementoSectionLastSectionId `${id}`\r
218 \r
219   !verbose pop\r
220 \r
221   Section ${flags} `${name}` `${id}`\r
222 \r
223   !verbose push\r
224   !verbose 3\r
225 \r
226 !macroend\r
227 \r
228 #####################################\r
229 ### User Macros                   ###\r
230 #####################################\r
231 \r
232 !macro MementoSection name id\r
233 \r
234   !verbose push\r
235   !verbose 3\r
236 \r
237   !insertmacro __MementoSection "" `${name}` `${id}`\r
238 \r
239   !verbose pop\r
240 \r
241 !macroend\r
242 \r
243 !macro MementoUnselectedSection name id\r
244 \r
245   !verbose push\r
246   !verbose 3\r
247 \r
248   !insertmacro __MementoSection /o `${name}` `${id}`\r
249 \r
250   !define __MementoSectionUnselected\r
251 \r
252   !verbose pop\r
253 \r
254 !macroend\r
255 \r
256 !macro MementoSectionEnd\r
257 \r
258   SectionEnd\r
259 \r
260   !verbose push\r
261   !verbose 3\r
262 \r
263   !insertmacro __MementoCheckSettings\r
264 \r
265   !ifndef __MementoSectionIndex\r
266 \r
267     !error "MementoSectionDone already used!"\r
268 \r
269   !endif\r
270 \r
271   !define /MATH __MementoSectionIndexNext \\r
272       ${__MementoSectionIndex} + 1\r
273 \r
274   Function __MementoSectionMarkNew${__MementoSectionIndex}\r
275 \r
276     ClearErrors\r
277     ReadRegDWORD $0 ${MEMENTO_REGISTRY_ROOT} `${MEMENTO_REGISTRY_KEY}` `MementoSection_${__MementoSectionLastSectionId}`\r
278 \r
279     ${If} ${Errors}\r
280 \r
281       !insertmacro SetSectionFlag `${${__MementoSectionLastSectionId}}` ${SF_BOLD}\r
282 \r
283     ${EndIf}\r
284 \r
285     GetFunctionAddress $0 __MementoSectionMarkNew${__MementoSectionIndexNext}\r
286     Goto $0\r
287 \r
288   FunctionEnd\r
289 \r
290   Function __MementoSectionRestoreStatus${__MementoSectionIndex}\r
291 \r
292     ClearErrors\r
293     ReadRegDWORD $0 ${MEMENTO_REGISTRY_ROOT} `${MEMENTO_REGISTRY_KEY}` `MementoSection_${__MementoSectionLastSectionId}`\r
294 \r
295     !ifndef __MementoSectionUnselected\r
296 \r
297       ${If} ${Errors}\r
298       ${OrIf} $0 != 0\r
299 \r
300         !insertmacro SelectSection `${${__MementoSectionLastSectionId}}`\r
301 \r
302       ${Else}\r
303 \r
304         !insertmacro UnselectSection `${${__MementoSectionLastSectionId}}`\r
305 \r
306       ${EndIf}\r
307 \r
308     !else\r
309 \r
310       !undef __MementoSectionUnselected\r
311 \r
312       ${If} ${Errors}\r
313       ${OrIf} $0 == 0\r
314 \r
315         !insertmacro UnselectSection `${${__MementoSectionLastSectionId}}`\r
316 \r
317       ${Else}\r
318 \r
319         !insertmacro SelectSection `${${__MementoSectionLastSectionId}}`\r
320 \r
321       ${EndIf}\r
322 \r
323     !endif\r
324 \r
325     GetFunctionAddress $0 __MementoSectionRestoreStatus${__MementoSectionIndexNext}\r
326     Goto $0\r
327 \r
328   FunctionEnd\r
329 \r
330   Function __MementoSectionSaveStatus${__MementoSectionIndex}\r
331 \r
332     ${If} ${SectionIsSelected} `${${__MementoSectionLastSectionId}}`\r
333 \r
334       WriteRegDWORD ${MEMENTO_REGISTRY_ROOT} `${MEMENTO_REGISTRY_KEY}` `MementoSection_${__MementoSectionLastSectionId}` 1\r
335 \r
336     ${Else}\r
337 \r
338       WriteRegDWORD ${MEMENTO_REGISTRY_ROOT} `${MEMENTO_REGISTRY_KEY}` `MementoSection_${__MementoSectionLastSectionId}` 0\r
339 \r
340     ${EndIf}\r
341 \r
342     GetFunctionAddress $0 __MementoSectionSaveStatus${__MementoSectionIndexNext}\r
343     Goto $0\r
344 \r
345   FunctionEnd\r
346 \r
347   !undef __MementoSectionIndex\r
348   !define __MementoSectionIndex ${__MementoSectionIndexNext}\r
349   !undef __MementoSectionIndexNext\r
350 \r
351   !undef __MementoSectionLastSectionId\r
352 \r
353   !verbose pop\r
354 \r
355 !macroend\r
356 \r
357 !macro MementoSectionDone\r
358 \r
359   !verbose push\r
360   !verbose 3\r
361 \r
362   !insertmacro __MementoCheckSettings\r
363 \r
364   Function __MementoSectionMarkNew${__MementoSectionIndex}\r
365   FunctionEnd\r
366 \r
367   Function __MementoSectionRestoreStatus${__MementoSectionIndex}\r
368   FunctionEnd\r
369 \r
370   Function __MementoSectionSaveStatus${__MementoSectionIndex}\r
371   FunctionEnd\r
372 \r
373   !undef __MementoSectionIndex\r
374 \r
375   !verbose pop\r
376 \r
377 !macroend\r
378 \r
379 !macro MementoSectionRestore\r
380 \r
381   !verbose push\r
382   !verbose 3\r
383 \r
384   !insertmacro __MementoCheckSettings\r
385 \r
386   Push $0\r
387   Push $1\r
388   Push $2\r
389   Push $3\r
390 \r
391     # check for first usage\r
392 \r
393     ClearErrors\r
394 \r
395     ReadRegStr $0 ${MEMENTO_REGISTRY_ROOT} `${MEMENTO_REGISTRY_KEY}` MementoSectionUsed\r
396 \r
397     ${If} ${Errors}\r
398 \r
399       # use script defaults on first run\r
400       Goto done\r
401 \r
402     ${EndIf}\r
403 \r
404     # mark new components in bold\r
405     \r
406     Call __MementoSectionMarkNew1\r
407 \r
408     # mark section groups in bold\r
409 \r
410     StrCpy $0 0\r
411     StrCpy $1 ""\r
412     StrCpy $2 ""\r
413     StrCpy $3 ""\r
414 \r
415     loop:\r
416 \r
417       ClearErrors\r
418 \r
419       ${If} ${SectionIsBold} $0\r
420 \r
421         ${If} $1 != ""\r
422 \r
423           !insertmacro SetSectionFlag $1 ${SF_BOLD}\r
424 \r
425         ${EndIf}\r
426 \r
427         ${If} $2 != ""\r
428 \r
429           !insertmacro SetSectionFlag $2 ${SF_BOLD}\r
430 \r
431         ${EndIf}\r
432 \r
433         ${If} $3 != ""\r
434 \r
435           !insertmacro SetSectionFlag $3 ${SF_BOLD}\r
436 \r
437         ${EndIf}\r
438 \r
439       ${ElseIf} ${Errors}\r
440 \r
441         Goto loop_end\r
442 \r
443       ${EndIf}\r
444 \r
445       ${If} ${SectionIsSectionGroup} $0\r
446 \r
447         ${If} $1 == ""\r
448 \r
449           StrCpy $1 $0\r
450 \r
451         ${ElseIf} $2 == ""\r
452 \r
453           StrCpy $2 $0\r
454 \r
455         ${ElseIf} $3 == ""\r
456 \r
457           StrCpy $3 $0\r
458 \r
459         ${EndIf}\r
460 \r
461       ${EndIf}\r
462 \r
463       ${If} ${SectionIsSectionGroupEnd} $0\r
464 \r
465         ${If} $3 != ""\r
466 \r
467           StrCpy $3 ""\r
468 \r
469         ${ElseIf} $2 != ""\r
470 \r
471           StrCpy $2 ""\r
472 \r
473         ${ElseIf} $1 != ""\r
474 \r
475           StrCpy $1 ""\r
476 \r
477         ${EndIf}\r
478 \r
479       ${EndIf}\r
480 \r
481       IntOp $0 $0 + 1\r
482 \r
483     Goto loop\r
484     loop_end:\r
485 \r
486     # restore sections' status\r
487 \r
488     Call __MementoSectionRestoreStatus1\r
489 \r
490   # all done\r
491 \r
492   done:\r
493 \r
494   Pop $3\r
495   Pop $2\r
496   Pop $1\r
497   Pop $0\r
498 \r
499   !verbose pop\r
500 \r
501 !macroend\r
502 \r
503 !macro MementoSectionSave\r
504 \r
505   !verbose push\r
506   !verbose 3\r
507 \r
508   !insertmacro __MementoCheckSettings\r
509 \r
510   Push $0\r
511 \r
512     WriteRegStr ${MEMENTO_REGISTRY_ROOT} `${MEMENTO_REGISTRY_KEY}` MementoSectionUsed ""\r
513   \r
514     Call __MementoSectionSaveStatus1\r
515 \r
516   Pop $0\r
517 \r
518   !verbose pop\r
519 \r
520 !macroend\r
521 \r
522 \r
523 \r
524 !endif # ___MEMENTO_NSH___\r
525 \r
526 !verbose pop\r