Subsection partially selected

From NSIS Wiki
Jump to navigationJump to search
Author: PerditionC (talk, contrib)


Description

This macro can be used to determine if any one of the sections within a subsection is selected.

Note: if you know the section names ahead of time and there aren't too many then use a method similar to one-section, i.e. directly query each.

The Script

Note: Using current NSIS 2, this can be more easily achieved using the partially selected flag in combination with the selected flag. You must check both unless you only want cases where some and NOT all sections in a subsection are selected.

!include Sections.nsh
!insertmacro SectionFlagIsSet ${ssection_XXX} ${SF_PSELECTED} isSel chkAll
chkAll: 
!insertmacro SectionFlagIsSet ${ssection_XXX} ${SF_SELECTED} isSel notSel
  isSel:
  ; ... do actions if any or all sections in a subsection are selected
  notSel:
  ; ... do actions if no sections in a subsection are selected (all unselected)

Deprecated (Tested with NSIS 2.0b0)

This is only tested with NSIS 2.0b0 and relies on my observation of the value of section #s, so may or may not work with other versions. Until I can find a better approach this is used to determine whether to display a page to select a download mirror or not (i.e. you only choose a download mirror if you happened to select a component in a subsection that contains optional downloadable components).

Basically, we use the section# of the parent subsection as the base, then cycle through the next MY_SUBSECTION_CNT entries and if any of them are selected (SF_SELECTED is set) we consider the subsection partially selected.

; this is the count of sections in the given subsection
!define MY_SUBSECTION_CNT 27	; used to query sections & set description text
 
; determine if section selected by user
!define SF_SELECTED   1
 
; RESULT should be one of the R set $R0-$R9
; on return RESULT is 0 if none are selected else it is 1 == ${SF_SELECTED}
!macro isMySubSectionSelected RESULT
  ; we !!!assume!!! that section# of 1st section is # of the subsection + 1
 
  ; save called values of our temp variables
  push $0	; used for the 1st section
  push $1	; used for the last section
 
  ; initialize result to none selected
  StrCpy ${RESULT} 0
  StrCpy $0 ${ssection_dl_opt_XXX}  ; replace with parent subsection#
 
  ; $0=section of 1st downloadable component's section
  ; $0 = ${ssection_dl_opt_XXX} + 1
  ; $1=section of last downloadable component's section + 1
  ; $1 = ${ssection_dl_opt_XXX} + 1 + ${DICTIONARY_COUNT}
  IntOp $0 $0 + 1                    ; order here
  IntOp $1 $0 + ${MY_SUBSECTION_CNT} ; matters   
 
  loop_start:
    ; check if flag set
    SectionGetFlags $0 ${RESULT}
    IntOp ${RESULT} ${RESULT} & ${SF_SELECTED}
    IntCmp ${RESULT} ${SF_SELECTED} loop_end 0 0
    ; loop through sections
    IntOp $0 $0 + 1  
    IntCmpU $0 $1 loop_end
  Goto loop_start 
  loop_end:
  pop $1
  pop $0
!macroend

And if you support multiple languages, but you want all your sections in a given subsection to have the same description as the subsection itself, then use something like this:

!insertmacro MUI_DESCRIPTION_TEXT ${ssection_dl_opt_XXX} $(DESC_ssection_dl_opt_XXX)
 
push $R1	; the 1st section
push $R2	; the last section
 
StrCpy $R1 ${ssection_dl_opt_XXX}
IntOp $R1 $R1 + 1 
IntOp $R2 $R1 + ${MY_SUBSECTION_CNT}
loop_start:  
  !insertmacro MUI_DESCRIPTION_TEXT $R1 $(DESC_ssection_dl_opt_XXX)
  IntOp $R1 $R1 + 1  
  IntCmpU $R1 $R2 loop_end
Goto loop_start 
loop_end:
 
pop $R2
pop $R1