Archive: Sections and subsections


Sections and subsections
Hello,
I want to achieve something simple, but I don't get it to work like I want to.
I have 2 sections "section1" and "section2". Section2 can not be installed without section1.
So I thought I make them displayed in the components page like the attached picture.

I have done this using the following code:

SectionGroup /e "Section1" SEC1Group
Section "-Section1" SEC1
...
SectionEnd
Section "Section2" SEC2
...
SectionEnd
SectionGroupEnd

This way I thought the behaviour I described above will be automatically implemented, because I thought when a section of a particular sectiongroup is selected, the sectiongroup itself is also selected. But this seems not to be the fact.
When the group is de-selected first, both checkboxes are de-selected, then afterwards the "section2" section can be checked, and the section1 checkbox gets grey (like a 3-state checkbox in the 3rd state). I want it to be checked plain (all the subgroups are checked, so the group should be checked).

Then I thought I override the .OnSelChange as follows:

Function .onSelChange
!insertmacro SectionFlagIsSet ${SEC2} ${SF_SELECTED} endOnSelChange selectSection1
selectSection1:
!insertmacro SelectSection ${SEC1}
endOnSelChange:
FunctionEnd

But this makes it unable to de-select group1.

Am I missing something here? Or is there another way of doing this?

Any help appreciated!

Greetings,

Fretje


First off, change those names cause it's hard to follow when Group and Sub1 have the same name (Section1).

When a Sub is selected, other Sub is not automatically selected even if it's hidden. You have to handle that yourself.
When Group is selected, all Subs are selected. I think you don't want this, you'd only want Sub1 selected in this case.
You also want them all selected when Sub2 is selected, and you want them all unselected when Sub2 is unselected. Correct? If so, what you're trying to achieve is not trivial. You need to keep states and write a more elaborate .onSelChange function. You'll call SectionGetFlags everytime, compare current state to previous one and take action and/or call SectionSetFlags accordingly. Lot of head ache... just for the sake of getting an indented view?


The actual problem is *real simple* : there's one section dependent of another...
So the dependent section has to de-select when the main section is de-selected.
And the main section has to be selected when the dependend section is selected.
How can I establish this behaviour in the components page?


You have a flawed approach to the *real simple* problem then..

The user cannot select/unselect a hidden section. You want a sub selected when the other sub is selected and vice versa.
Then why don't you just merge the two into one? Whats the point of creating subs?

But, since you insist on using your own jargon here (which do you mean by "main section"?), I might well have wasted my time again.
Good luck.


I'm terribly sorry wasting your time, but I think this *real simple* problem is actually so simple nobody understands. Or maybe it's just me not asking it right.

Actually I already solved this problem using your previous comment, but let's just restate everything, because I think this should be something that's implemented in the basic nsis section-stuff.

Just forget about the subsections and the hidden section.
Let's simply say we just have 2 sections: "SectionOne" and "SectionTwo" which both are optional (the user can choose to NOT install them):


Section "SectionOne" SEC1
...
SectionEnd

Section "SectionTwo" SEC2
...
SectionEnd


Now let's say that "SectionTwo" is dependent on "SectionOne" ("SectionTwo" can NOT be installed WITHOUT "SectionOne").
Or to put it in other words: "SectionTwo" REQUIRES "SectionOne".

So if "SectionOne" is de-selected, "SectionTwo" is automatically de-selected as well. And if "SectionTwo" is selected, "SectionOne" is automatically selected.

I now solved this issue by declaring 2 variables which contain the previous selected-state of the concerning sections. Initializing these variables with "1" in .onInit. Then overriding .onSelChange like this:


Function .onSelChange
${If} $SEC2_SEL = 0
${AndIf} ${SectionIsSelected} ${SEC2}
${AndUnless} ${SectionIsSelected} ${SEC1}
!insertmacro SelectSection ${SEC1}
${EndIf}

${If} $SEC1_SEL = 1
${AndUnless} ${SectionIsSelected} ${SEC1}
${AndIf} ${SectionIsSelected} ${SEC2}
!insertmacro UnSelectSection ${SEC2}
${EndIf}

${If} ${SectionIsSelected} ${SEC1}
StrCpy $SEC1_SEL 1
${Else}
StrCpy $SEC1_SEL 0
${EndIf}

${If} ${SectionIsSelected} ${SEC2}
StrCpy $SEC2_SEL 1
${Else}
StrCpy $SEC2_SEL 0
${EndIf}
FunctionEnd


I find it strange that no-one has run into this before... I think it should be possible to achieve this behaviour by a simple command like e.g.

SectionRequires ${SEC1} ${SEC2}

Greetings,

Fretje

Perhaps you could ask for a feature request on the project page.

-Stu


done ;-)


That was actually needed and implemented differently in an old version of the NSIS package installer. Instead of clearing the selection of dependent sections, the required section was set to read-only and its name was suffixed with "(required)" when a dependent section was selected.

I prefer to allow the developer the freedom to implement the logic as required. However, I do agree this can be easier. The .onSelChange callback can be more powerful. It can, for example, receive information about what exactly happened instead of guessing according to saved states.