I want to delete all the elements from the combo box on click of the button in the nsis installer
nsDialogs does not have helper macros for every feature implemented by the Windows controls so sometimes you have to consult MSDN to find information about which message to send yourself.
!include nsDialogs.nsh
!include WinMessages.nsh
Page Custom MyPageCreate
Page InstFiles
Var MyComboHandle
Function ResetCombo
Pop $0
SendMessage $MyComboHandle ${CB_RESETCONTENT} 0 0
FunctionEnd
Function DeleteItemsButNotText
Pop $0
${NSD_GetText} $MyComboHandle $0
SendMessage $MyComboHandle ${CB_RESETCONTENT} 0 0
${NSD_SetText} $MyComboHandle $0
FunctionEnd
Function DeleteItemsButNotText_AlternateVersion
Pop $0
loop:
SendMessage $MyComboHandle ${CB_DELETESTRING} 0 0 $0 ; This will also clear the text if it matches the item
IntCmp $0 ${CB_ERR} "" loop loop
FunctionEnd
Function AddItems
Pop $0
${NSD_CB_AddString} $MyComboHandle "Foo"
${NSD_CB_AddString} $MyComboHandle "Bar"
SendMessage $MyComboHandle ${CB_SETCURSEL} 0 ""
FunctionEnd
Function MyPageCreate
nsDialogs::Create 1018
Pop $0
${NSD_CreateCombobox} 0 30u 100% 200u ""
Pop $MyComboHandle
Push ""
Call AddItems
${NSD_CreateButton} 0 50u 33% 12u "Reset"
Pop $0
${NSD_OnClick} $0 ResetCombo
${NSD_CreateButton} 33% 50u 33% 12u "Delete all items"
Pop $0
${NSD_OnClick} $0 DeleteItemsButNotText
${NSD_CreateButton} 66% 50u 33% 12u "Add items"
Pop $0
${NSD_OnClick} $0 AddItems
nsDialogs::Show
FunctionEnd
Related
I need to add each element of the array to the Dialog menu. The problem is that with the command $ {array [#]} the dialog is recognizing each word as an element. Look:
First attempt: Adding element with spaces
list=('Google Chrome' 'Brackets' 'Visual Studio') # my list
declare -a dia # dialog array
for index in ${!list[#]}; do # for each index in the list
dia[${#dia[#]}]=$index # add index
dia[${#dia[#]}]=${list[$index]} #add element
done
dialog --menu "MENU" 0 0 0 $(echo ${dia[#]})
# Format: dialog --menu "TITLE" 0 0 0 'Index1' 'Element1' 'Index2' 'Element2'...
# dia[0] = 0
# dia[1] = 'Google Chrome'
# dia[1] = 1
# dia[2] = 'Brackets'...
PRINT: first attempt
I did this to avoid processing each word, with the return of $ {list [#]} separating word by word, obtaining a sequence of number and string.
Second attempt: Replace ' ' with '-'
for index in ${!list[#]}; do
dgl[${#dgl[#]}]=$index
dgl[${#dgl[#]}]=${list[$index]/' '/'-'}
done
PRINT: Second attempt
What I think is happening
I believe that when passing the elements of the array to the DIALOG command it considers spaces ("Google Chrome", for example). Is there a way for me to show this with spaces?
Made all necessary changes to your code so it now works as expected.
#!/usr/bin/env bash
list=('Google Chrome' 'Brackets' 'Visual Studio') # my list
declare -a dia=() # dialog array
for index in "${!list[#]}"; do # for each index in the list
dia+=("$index" "${list[index]}")
done
choice=$(
dialog --menu "MENU" 0 0 0 "${dia[#]}" \
3>&1 1>&2 2>&3 3>&- # Swap stdout with stderr to capture returned dialog text
)
dialog_rc=$? # Save the dialog return code
clear # restore terminal background and clear
case $dialog_rc in
0)
printf 'Your choice was: %s\n' "${list[choice]}"
;;
1)
echo 'Cancelled menu'
;;
255)
echo 'Closed menu without choice'
;;
*)
printf 'Unknown return code from dialog: %d\n' $dialog_rc >&2
;;
esac
How to customize NSIS checkbox in custom dialog using plugin or bitmap image?
Here is an example of NSIS installer with custom chechboxes
The current checkboxes working in options dialog only.
Maybe there's a way to do this by using OnClick event?
Any idea?
Thanks.
This is not a native NSIS feature but it can be implemented with some custom code:
!include WinMessages.nsh
!include nsDialogs.nsh ; WS_*
ShowInstDetails nevershow
Var Task1
Var Task2
Page InstFiles "" InitTasks FreeTasks
!macro SetTaskIcon hwnd icon
SetDetailsPrint none
Push $0
!if "${icon}" != ""
File "/oname=$PluginsDir\Task${hwnd}.ico" "${icon}"
System::Call 'USER32::LoadImage(i 0, t "$PluginsDir\Task${hwnd}.ico", i ${IMAGE_ICON}, i 32, i 32, i ${LR_LOADFROMFILE})i.r0'
SendMessage ${hwnd} ${STM_SETICON} $0 0 $0
!else
SendMessage ${hwnd} ${STM_GETICON} 0 0 $0
!endif
System::Call 'USER32::DestroyIcon(i $0)'
Pop $0
SetDetailsPrint lastused
!macroend
!macro FreeTask hwnd
!insertmacro SetTaskIcon ${hwnd} ""
!macroend
!macro CreateTask outvar icon text x y
System::Store S
FindWindow $1 "#32770" "" $HWNDPARENT
System::Call 'USER32::CreateWindowEx(i 0, t "Static", t "${text}", i ${WS_CHILD}|${WS_VISIBLE}|${SS_ICON}|${SS_REALSIZEIMAGE}, i ${x}, i ${y}, i 32, i 32, i r1, i 0, i 0, i 0)i.r0'
StrCpy ${outvar} $0
!insertmacro SetTaskIcon ${outvar} "${icon}"
IntOp $2 ${x} + 32
IntOp $2 $2 + 5 ; Padding
System::Call 'USER32::CreateWindowEx(i 0, t "Static", t "${text}", i ${WS_CHILD}|${WS_VISIBLE}|${SS_CENTERIMAGE}, i $2, i ${y}, i 999, i 32, i r1, i 0, i 0, i 0)i.r0'
SendMessage $1 ${WM_GETFONT} 0 0 $2
SendMessage $0 ${WM_SETFONT} $2 1
System::Store L
!macroend
Function InitTasks
!insertmacro CreateTask $Task1 "${NSISDIR}\Contrib\Graphics\Icons\llama-grey.ico" "Foo" 40 50
!insertmacro CreateTask $Task2 "${NSISDIR}\Contrib\Graphics\Icons\llama-grey.ico" "Bar" 40 90
FunctionEnd
Function FreeTasks
!insertmacro FreeTask $Task1
!insertmacro FreeTask $Task2
FunctionEnd
Section "Foo task"
Sleep 2222 ; Pretend to do some work
!insertmacro SetTaskIcon $Task1 "${NSISDIR}\Contrib\Graphics\Icons\llama-blue.ico"
SectionEnd
Section "Bar task"
Sleep 3333 ; Pretend to do some work
!insertmacro SetTaskIcon $Task2 "${NSISDIR}\Contrib\Graphics\Icons\llama-blue.ico"
SectionEnd
this is my file:
$ cat head_datafile_pipe_deleimiter.csv
"Rec_Open_Date"|"MSISDN"|"IMEI"|"Data_Volume_Bytes"|"Device_Manufacturer"|"Device_Model"|"Product_Description"|"Data_Volume_MB"
"2016-07-17"|"686"|"630"|"618320"|"Apple Inc"|"Apple iPhone S A1530"|"PREPAY PLUS - $0 -"|"0.589676"
"2016-07-17"|"560"|"570"|"42841779"|"Motorola Mobility LLC, a Lenovo Company"|"Moto X 2nd Generation, X112360445"|"$39.95 Plan"|"40.8571"
"2016-07-17"|"811"|"340"|"2465082"|"Samsung Korea"|"Samsung SM-G900I"|"$69.95 Plan"|"2.35089"
"2016-07-17"|"785"|"610"|"41498628"|"Apple Inc"|"Apple iPhone 6S Plus A1687"|"$29.95 Carryover Plan 1GB"|"39.5762"
"2016-07-17"|"908"|"310"|"6497563"|"Samsung Korea"|"Samsung GT-I9195"|"PREPAY PLUS - $0 -"|"6.19656"
"2016-07-17"|"919"|"610"|"0"|"Samsung Korea"|"Samsung SM-G925I"|"$19 CO COMBO - NOT RECURRENT"|"0"
"2016-07-17"|"356"|"290"|"33189681"|"Apple Inc"|"Apple iPhone 6S A1688"|"$39.95 Plan"|"31.6521"
"2016-07-17"|"009"|"160"|"30340"|"Samsung Korea"|"Samsung SM-J500Y"|"PREPAY PLUS - $1 - #33"|"0.0289345"
"2016-07-17"|"574"|"400"|"549067"|"HUAWEI Technologies Co Ltd"|"HUAWEI Y6"|"PREPAY PLUS - $0 -"|"0.523631"
and here I am close to what I want but i cannot get it to iterate through the differnet elements in the array. if($7==dq"PREPAY PLUS - $0 -"dq) print $7. It is basically a for loop that iterates trhough the elements in the array, and there for filters out the value I want before moving onto the next element in the array and repeating. But I can only get it to work if I hard code the value, I want it to iterate through the array u_vals
$ for i in "${u_vals[#]}"; do awk -F'|' -v var="${u_vals[*]}" -v j=i -v dq='"' 'NR==1{print $7} NR>1{split(var,list,"|"); if($7==dq"PREPAY PLUS - $0 -"dq) print $7 }' head_datafile_pipe_deleimiter.csv; done
"Product_Description"
"PREPAY PLUS - $0 -"
"PREPAY PLUS - $0 -"
"PREPAY PLUS - $0 -"
"Product_Description"
"PREPAY PLUS - $0 -"
"PREPAY PLUS - $0 -"
"PREPAY PLUS - $0 -"
"Product_Description"
"PREPAY PLUS - $0 -"
"PREPAY PLUS - $0 -"
"PREPAY PLUS - $0 -"
"Product_Description"
"PREPAY PLUS - $0 -"
"PREPAY PLUS - $0 -"
"PREPAY PLUS - $0 -"
"Product_Description"
"PREPAY PLUS - $0 -"
"PREPAY PLUS - $0 -"
"PREPAY PLUS - $0 -"
"Product_Description"
"PREPAY PLUS - $0 -"
"PREPAY PLUS - $0 -"
"PREPAY PLUS - $0 -"
these are all the uniq value in column 7
$ printf "%s\n" "${u_vals[#]}"
"$19 CO COMBO - NOT RECURRENT"
"$29.95 Carryover Plan 1GB"
"$39.95 Plan"
"$69.95 Plan"
"PREPAY PLUS - $0 -"
"PREPAY PLUS - $1 - #33"
How do I make this part
dq"PREPAY PLUS - $0 -"dq
of this
if($7==dq"PREPAY PLUS - $0 -"dq) print $7
iterate through the elements of the array?
EDIT1
this is what I was looking for:
awk -F"|" ...
$ for i in "${u_vals[#]}"; do awk -F"|" -v j="$i" 'NR==1{print $7}NR>1 {if($7==j) print $7 }' head_datafile_pipe_deleimiter.csv ; done
"Product_Description"
"$19 CO COMBO - NOT RECURRENT"
"Product_Description"
"$29.95 Carryover Plan 1GB"
"Product_Description"
"$39.95 Plan"
"$39.95 Plan"
"Product_Description"
"$69.95 Plan"
"Product_Description"
"PREPAY PLUS - $0 -"
"PREPAY PLUS - $0 -"
"PREPAY PLUS - $0 -"
"Product_Description"
"PREPAY PLUS - $1 - #33"
awk -v FS="|" ....
$ for i in "${u_vals[#]}"; do awk -v FS="|" -v j="$i" 'NR==1{print $7}NR>1 {if($7==j) print $7 }' head_datafile_pipe_deleimiter.csv ; done
"Product_Description"
"$19 CO COMBO - NOT RECURRENT"
"Product_Description"
"$29.95 Carryover Plan 1GB"
"Product_Description"
"$39.95 Plan"
"$39.95 Plan"
"Product_Description"
"$69.95 Plan"
"Product_Description"
"PREPAY PLUS - $0 -"
"PREPAY PLUS - $0 -"
"PREPAY PLUS - $0 -"
"Product_Description"
"PREPAY PLUS - $1 - #33"
You got a small syntax error. When you dou in the awk
awk ... -v j=i
It should be
awk ... -v j="$i"
This should work:
for i in "${u_vals[#]}"; do awk -v FS="|" -v j="$i" 'NR==1{print $7}NR>1 {if($7==j) print $7 }' datafile_pipe_deleimiter.csv ; done
The following part of the awk:
split(var,list,"|");
I don't know why do you need it for, so I did not put in my answer
I want to apply onClick event on the combo box in nsis installer,so that I can execute a functionality on the click of button on combo box.
The OnClick event is not suitable for a combo-box, you want the OnChange event because the user can change it with the arrow keys etc.
To fire the change event programmatically you can call your handler directly or trick the combobox control:
!include nsDialogs.nsh
!include WinMessages.nsh
Page Custom MyPageCreate
Page InstFiles
Function OnComboChange
Pop $0
SendMessage $0 ${CB_GETCURSEL} "" "" $2
System::Call 'USER32::SendMessage(i$0,i${CB_GETLBTEXT},i$2,t.r2)'
MessageBox mb_ok "OnComboChange: $2"
FunctionEnd
Function EmulateChangeMethodA
Pop $0 ; Throw away parameter we don't care about
Push $1
Call OnComboChange
FunctionEnd
Function EmulateChangeMethodB
Pop $0 ; Throw away parameter we don't care about
FindWindow $0 "EDIT" "" $1
SendMessage $1 ${WM_COMMAND} 0x4000000 $0 ; Send WM_COMMAND,MAKELONG(0,EN_UPDATE),hwndEdit
FunctionEnd
Function EmulateChangeMethodC
Pop $0 ; Throw away parameter we don't care about
!ifndef CB_GETCOMBOBOXINFO
!define CB_GETCOMBOBOXINFO 0x0164
!endif
System::Call '*(&l4,&i16,&i16,i,i,i,i)i.r2'
SendMessage $1 ${CB_GETCOMBOBOXINFO} "" $2 ; This only works on Vista+?
System::Call '*$2(i,&i16,&i16,i,i,i,i.r0)'
System::Free $2
SendMessage $1 ${WM_COMMAND} 0x30000 $0 ; ; Send WM_COMMAND,MAKELONG(0,LBN_SELCANCEL),hwndList
FunctionEnd
Function MyPageCreate
nsDialogs::Create 1018
Pop $0
${NSD_CreateCombobox} 0 30u 100% 200u ""
Pop $1 ; This is the only control handle we care about in this example so make sure to never overwrite it!
${NSD_CB_AddString} $1 "Foo"
${NSD_CB_AddString} $1 "Bar"
SendMessage $1 ${CB_SETCURSEL} 0 ""
${NSD_OnChange} $1 OnComboChange
${NSD_CreateButton} 0 50u 33% 12u "Emulate change: A"
Pop $0
${NSD_OnClick} $0 EmulateChangeMethodA
${NSD_CreateButton} 33% 50u 33% 12u "Emulate change: B"
Pop $0
${NSD_OnClick} $0 EmulateChangeMethodB
${NSD_CreateButton} 66% 50u 33% 12u "Emulate change: C"
Pop $0
${NSD_OnClick} $0 EmulateChangeMethodC
nsDialogs::Show
FunctionEnd
what I want to do is have a page where the user browses there filesystem for a specific value, and continues on if the filename matches.
To be specific, I would like the user to locate there php executable file, and also the directory I suppose(Not sure how I would extract the directory from the full path).
You can do this with a custom page:
!include nsDialogs.nsh
!include FileFunc.nsh
Page Custom MyPageCreate MyPageLeave
Var PhpPath
Function MyPageLeave
${NSD_GetText} $PhpPath $0
${GetFileName} $0 $1
${IfNot} ${FileExists} $0
${OrIf} $1 != "php.exe"
MessageBox mb_iconstop "You must locate php.exe to continue!"
Abort
${Else}
#php path is in $0, do something with it...
${EndIf}
FunctionEnd
Function MyPageComDlgSelectPHP
Pop $0
${NSD_GetText} $PhpPath $0
nsDialogs::SelectFileDialog open $0 "php.exe|php.exe"
Pop $0
${If} $0 != ""
${NSD_SetText} $PhpPath $0
${EndIf}
FunctionEnd
Function MyPageCreate
nsDialogs::Create 1018
Pop $0
${NSD_CreateText} 0 5u -25u 13u "$ProgramFiles\PHP\php.exe"
Pop $PhpPath
${NSD_CreateBrowseButton} -23u 4u 20u 15u "..."
Pop $0
${NSD_OnClick} $0 MyPageComDlgSelectPHP
nsDialogs::Show
FunctionEnd
or you can use the directory page:
!include LogicLib.nsh
Var PhpPath
Function .onInit
StrCpy $PhpPath "$ProgramFiles\PHP" ; Default (You could probably do better by checking the registry)
FunctionEnd
PageEx Directory
DirVar $PhpPath
DirVerify leave
PageCallbacks "" PhpPageShow PhpPageLeave
DirText "Select PHP folder" "PHP Folder" "" "Select PHP folder"
PageExEnd
Function PhpPageShow
;Hide space texts
FindWindow $0 "#32770" "" $HWNDPARENT
GetDlgItem $1 $0 0x3FF
ShowWindow $1 0
GetDlgItem $1 $0 0x400
ShowWindow $1 0
FunctionEnd
Function PhpPageLeave
GetInstDirError $0
${If} $0 <> 0
${OrIfNot} ${FileExists} "$PhpPath\php.exe"
MessageBox mb_iconstop "You must locate the php folder to continue!"
Abort
${EndIf}
FunctionEnd
This can be achieved very easily with custom nsDialogs page and nsDialogs::SelectFileDialog which is designed for this purpose.
http://nsis.sourceforge.net/Docs/nsDialogs/Readme.html#ref-selectfiledialog