Reputation: 303
I have a simple NSIS script based on the following source code I found on: NSIS Mutually Exclusive Sections. The problem I'm facing is that I'm not able to implement three mutually exclusive sections instead of one.
Section 0 is independent.
For Section 1, 2 and 3 I need to have them mutually exclusive. Being able to select none of them or just one selected at same time.
If you test the example it seems it works well when you select:
The problem starts when you continue selecting options after having section 3 selected and then you go to select section 2 and section 1. Or if you try to doing random selections the selections are messed up.
I'm not able to implement this mutually exclusive between three sections within a SubSection. Can anyone give me some light on this?
Much appreciated.
Thanks,
Here's the script that I have modified so far:
# Example to control section selection.
# It allows only one of three sections to be selected at any
# given time, but unlike one-section, it allows non of them
# to be selected as well.
#
!include Sections.nsh
!include LogicLib.nsh
Name example
OutFile "mutually exclusive.exe"
ComponentText "please choose zero or one but the default"
SubSection /e "Test" SSEC00
Section /o "Test Sec 0" sec0
SectionEnd
Section /o "#2 and #3 unselected" sec1
SectionEnd
Section /o "#1 and #3 unselected" sec2
SectionEnd
Section /o "#1 and #2 unselected" sec3
SectionEnd
SubSectionEnd
Function .onInit
Push $0
SectionGetFlags ${sec1} $0
IntOp $0 $0 & ${SECTION_OFF}
SectionSetFlags ${sec1} $0
SectionGetFlags ${sec2} $0
IntOp $0 $0 & ${SECTION_OFF}
SectionSetFlags ${sec2} $0
SectionGetFlags ${sec3} $0
IntOp $0 $0 & ${SECTION_OFF}
SectionSetFlags ${sec3} $0
Pop $0
FunctionEnd
Function .onSelChange
Push $0
${If} ${SectionIsSelected} ${sec1}
${OrIf} ${SectionIsSelected} ${sec2}
${OrIf} ${SectionIsSelected} ${sec3}
StrCmp $R9 ${sec1} check_sec2 # If last selection was sec1 goto check_sec2
StrCmp $R9 ${sec2} check_sec3 # If last selection was sec2 goto check_sec3
StrCmp $R9 ${sec3} check_sec1
check_sec1:
SectionGetFlags ${sec1} $0
IntOp $0 $0 & ${SF_SELECTED}
IntCmp $0 ${SF_SELECTED} 0 Seldone Seldone
StrCpy $R9 ${sec1}
SectionGetFlags ${sec2} $0
IntOp $0 $0 & ${SECTION_OFF}
SectionSetFlags ${sec2} $0
SectionGetFlags ${sec3} $0
IntOp $0 $0 & ${SECTION_OFF}
SectionSetFlags ${sec3} $0
Goto Seldone
check_sec2:
SectionGetFlags ${sec2} $0
IntOp $0 $0 & ${SF_SELECTED}
IntCmp $0 ${SF_SELECTED} 0 Seldone Seldone
StrCpy $R9 ${sec2}
SectionGetFlags ${sec1} $0
IntOp $0 $0 & ${SECTION_OFF}
SectionSetFlags ${sec1} $0
SectionGetFlags ${sec3} $0
IntOp $0 $0 & ${SECTION_OFF}
SectionSetFlags ${sec3} $0
check_sec3:
SectionGetFlags ${sec3} $0
IntOp $0 $0 & ${SF_SELECTED}
IntCmp $0 ${SF_SELECTED} 0 Seldone Seldone
StrCpy $R9 ${sec3}
SectionGetFlags ${sec1} $0
IntOp $0 $0 & ${SECTION_OFF}
SectionSetFlags ${sec2} $0
SectionGetFlags ${sec2} $0
IntOp $0 $0 & ${SECTION_OFF}
SectionSetFlags ${sec2} $0
Goto check_sec1
Seldone:
${EndIf}
Pop $0
FunctionEnd
Upvotes: 0
Views: 778
Reputation: 101666
In NSIS v3+ the section id of the changed section is stored in $0 when .onSelChange is called, this makes it easier to get the logic correct:
!include Sections.nsh
!include LogicLib.nsh
ComponentText "please choose zero or one but the default"
SubSection /e "Test" SSEC00
Section /o "Test Sec 0" sec0
SectionEnd
Section /o "#2 and #3 unselected" sec1
SectionEnd
Section /o "#1 and #3 unselected" sec2
SectionEnd
Section /o "#1 and #2 unselected" sec3
SectionEnd
SubSectionEnd
Page Components
Page InstFiles
Function .onSelChange
${IfThen} $0 = -1 ${|} Return ${|} ; I don't care about InstType changes
${If} $0 < ${sec1}
${OrIf} $0 > ${sec3}
Return ; I don't care about other sections
${EndIf}
!macro SelectOnlyMe sid
${IfThen} $0 <> ${sid} ${|} !insertmacro UnselectSection ${sid} ${|}
!macroend
!insertmacro SelectOnlyMe ${sec1}
!insertmacro SelectOnlyMe ${sec2}
!insertmacro SelectOnlyMe ${sec3}
FunctionEnd
(If you need multiple groups of mutually exclusive sections you could make the "if/orif" range check part of the helper macro instead)
Upvotes: 1