on preOpenStack set the style of stack "revMenubar" to "modeless" -- stops the toolbar overlapping the SE set the windowBoundingRect to the working screenrect -- let's you maximise the SE end preOpenStack
Category Archives: Code
Command prompt blocking policies and the shell function
This week I had a report of an application locking up while executing the shell function. Actually it was executing shell(“ipconfig /all”) in my modification of Ken Ray’s GetMACAddress function to return the machine’s LAN ip.
System administrators tend to like to turn things off so normal human beings can’t make a mess of their nice machines. One thing they can do is set a Windows registry entry to disable cmd.exe for the user. So by checking HKEY_CURRENT_USER\Software\Policies\Microsoft\Windows\System\DisableCMD”=dword:1 we can find out if cmd.exe is disabled for the current user. What this does is when cmd.exe is run it opens the console but all you get is a blocked by admin message and no command prompt. If Bill would just change this so it stopped cmd.exe from launching at all then we wouldn’t have such a problem. LiveCode is therefore able to run cmd.exe and just sits there waiting for it to terminate but it never does.
So I wrote a safer shell function to check for this situation and also possible execution errors from hash rules and renaming of cmd.exe etc. If the registry setting is there it will attempt to execute the command directly using process commands rather than via shell.
<span class="storage storage_type storage_type_handler storage_type_handler_rev">function</span><span> safeShell pCommand</span> <span> </span><span class="comment comment_line comment_line_number-sign comment_line_number-sign_rev">-- assume the shellCommand has been set appropriately</span> <span> </span><span class="entity entity_name entity_name_handler entity_name_handler_rev">set</span><span> </span><span class="keyword keyword_control keyword_control_rev">the</span><span> </span><span class="support support_command support_command_rev">hideConsoleWindows</span><span> </span><span class="keyword keyword_control keyword_control_rev">to</span><span> </span><span class="keyword keyword_control keyword_control_rev">true</span> <span> </span><span class="entity entity_name entity_name_handler entity_name_handler_rev">set</span><span> </span><span class="keyword keyword_control keyword_control_rev">the</span><span> </span><span class="support support_command support_command_rev">itemDel</span><span> </span><span class="keyword keyword_control keyword_control_rev">to</span><span> </span><span class="string string_quoted string_quoted_double string_quoted_double_transcript">"\"</span> <span> </span><span class="keyword keyword_control keyword_control_rev">if</span><span> </span><span class="keyword keyword_control keyword_control_rev">item</span><span> </span><span class="keyword keyword_operator keyword_operator_symbolic keyword_operator_symbolic_rev">-</span><span class="constant constant_numeric constant_numeric_rev">1</span><span> </span><span class="keyword keyword_control keyword_control_rev">of</span><span> </span><span class="keyword keyword_control keyword_control_rev">the</span><span> </span><span class="support support_command support_command_rev">shellCommand</span><span> </span><span class="keyword keyword_control keyword_control_rev">is</span><span> </span><span class="string string_quoted string_quoted_double string_quoted_double_transcript">"cmd.exe"</span><span> </span><span class="keyword keyword_control keyword_control_rev">AND</span><span> \ </span> <span> </span><span class="entity entity_name entity_name_handler entity_name_handler_rev">charToNum</span><span class="keyword keyword_operator keyword_operator_symbolic keyword_operator_symbolic_rev">(</span><span class="entity entity_name entity_name_handler entity_name_handler_rev">queryRegistry</span><span class="keyword keyword_operator keyword_operator_symbolic keyword_operator_symbolic_rev">(</span><span class="string string_quoted string_quoted_double string_quoted_double_transcript">"HKEY_CURRENT_USER\Software\Policies\Microsoft\Windows\System\DisableCMD"</span><span class="keyword keyword_operator keyword_operator_symbolic keyword_operator_symbolic_rev">))</span><span> </span><span class="keyword keyword_operator keyword_operator_symbolic keyword_operator_symbolic_rev">=</span><span> </span><span class="constant constant_numeric constant_numeric_rev">1</span><span> then</span> <span> </span><span class="comment comment_line comment_line_number-sign comment_line_number-sign_rev">-- don't use cmd.exe because shell() won't return</span> <span> </span><span class="comment comment_line comment_line_number-sign comment_line_number-sign_rev">-- don't revert to command.com because there seems to be a problem in the engine</span> <span> </span><span class="entity entity_name entity_name_handler entity_name_handler_rev">return</span><span> executeProcess</span><span class="keyword keyword_operator keyword_operator_symbolic keyword_operator_symbolic_rev">(</span><span>pCommand</span><span class="keyword keyword_operator keyword_operator_symbolic keyword_operator_symbolic_rev">)</span> <span> </span><span class="keyword keyword_control keyword_control_rev">else</span> <span> </span><span class="keyword keyword_control keyword_control_rev">try</span> <span> </span><span class="comment comment_line comment_line_number-sign comment_line_number-sign_rev">-- still check for empty if your are expecting a result</span> <span> </span><span class="comment comment_line comment_line_number-sign comment_line_number-sign_rev">-- because there's no execution error on os x</span> <span> </span><span class="entity entity_name entity_name_handler entity_name_handler_rev">return</span><span> </span><span class="entity entity_name entity_name_handler entity_name_handler_rev">shell</span><span class="keyword keyword_operator keyword_operator_symbolic keyword_operator_symbolic_rev">(</span><span>pCommand</span><span class="keyword keyword_operator keyword_operator_symbolic keyword_operator_symbolic_rev">)</span> <span> </span><span class="keyword keyword_control keyword_control_rev">catch</span><span> e</span> <span> </span><span class="comment comment_line comment_line_number-sign comment_line_number-sign_rev">-- execution error on windows shellCommand doesn't exist</span> <span> </span><span class="comment comment_line comment_line_number-sign comment_line_number-sign_rev">-- hopefully this catches hash rule blocks</span> <span> </span><span class="entity entity_name entity_name_handler entity_name_handler_rev">return</span><span> </span><span class="string string_quoted string_quoted_double string_quoted_double_transcript">"Error executing command"</span> <span> </span><span class="keyword keyword_control keyword_control_rev">end</span><span> </span><span class="keyword keyword_control keyword_control_rev">try</span> <span> </span><span class="keyword keyword_control keyword_control_rev">end</span><span> </span><span class="keyword keyword_control keyword_control_rev">if</span> <span class="keyword keyword_control keyword_control_rev">end</span><span> safeShell</span> <span class="storage storage_type storage_type_handler storage_type_handler_rev">function</span><span> executeProcess pProcess</span><span class="keyword keyword_operator keyword_operator_symbolic keyword_operator_symbolic_rev">,</span><span>pElevate</span> <span> </span><span class="entity entity_name entity_name_handler entity_name_handler_rev">local</span><span> tReturn</span> <span> </span><span class="keyword keyword_control keyword_control_rev">if</span><span> pElevate then</span> <span> </span><span class="entity entity_name entity_name_handler entity_name_handler_rev">open</span><span> </span><span class="keyword keyword_control keyword_control_rev">elevated</span><span> </span><span class="keyword keyword_control keyword_control_rev">process</span><span> pProcess </span><span class="keyword keyword_control keyword_control_rev">for</span><span> </span><span class="support support_command support_command_rev">text</span><span> </span><span class="entity entity_name entity_name_handler entity_name_handler_rev">read</span> <span> </span><span class="keyword keyword_control keyword_control_rev">else</span> <span> </span><span class="entity entity_name entity_name_handler entity_name_handler_rev">open</span><span> </span><span class="keyword keyword_control keyword_control_rev">process</span><span> pProcess </span><span class="keyword keyword_control keyword_control_rev">for</span><span> </span><span class="support support_command support_command_rev">text</span><span> </span><span class="entity entity_name entity_name_handler entity_name_handler_rev">read</span> <span> </span><span class="keyword keyword_control keyword_control_rev">end</span><span> </span><span class="keyword keyword_control keyword_control_rev">if</span> <span> </span><span class="keyword keyword_control keyword_control_rev">repeat</span><span> </span><span class="keyword keyword_control keyword_control_rev">forever</span> <span> </span><span class="comment comment_line comment_line_number-sign comment_line_number-sign_rev"># Loop until there are no more lines to read.</span> <span> </span><span class="entity entity_name entity_name_handler entity_name_handler_rev">read</span><span> </span><span class="keyword keyword_control keyword_control_rev">from</span><span> </span><span class="keyword keyword_control keyword_control_rev">process</span><span> pProcess </span><span class="keyword keyword_control keyword_control_rev">for</span><span> </span><span class="constant constant_numeric constant_numeric_rev">1</span><span> </span><span class="keyword keyword_control keyword_control_rev">line</span> <span> </span><span class="keyword keyword_control keyword_control_rev">if</span><span> </span><span class="keyword keyword_control keyword_control_rev">the</span><span> </span><span class="entity entity_name entity_name_handler entity_name_handler_rev">result</span><span> </span><span class="keyword keyword_operator keyword_operator_symbolic keyword_operator_symbolic_rev">=</span><span> </span><span class="string string_quoted string_quoted_double string_quoted_double_transcript">""</span><span> </span><span class="keyword keyword_control keyword_control_rev">or</span><span> </span><span class="keyword keyword_control keyword_control_rev">the</span><span> </span><span class="entity entity_name entity_name_handler entity_name_handler_rev">result</span><span> </span><span class="keyword keyword_operator keyword_operator_symbolic keyword_operator_symbolic_rev">=</span><span> </span><span class="string string_quoted string_quoted_double string_quoted_double_transcript">"timed out"</span><span> then</span> <span> </span><span class="comment comment_line comment_line_number-sign comment_line_number-sign_rev">-- something to add</span> <span> </span><span class="entity entity_name entity_name_handler entity_name_handler_rev">put</span><span> it </span><span class="keyword keyword_control keyword_control_rev">after</span><span> tReturn</span> <span> </span><span class="keyword keyword_control keyword_control_rev">else</span> <span> </span><span class="entity entity_name entity_name_handler entity_name_handler_rev">close</span><span> </span><span class="keyword keyword_control keyword_control_rev">process</span><span> pProcess</span> <span> </span><span class="entity entity_name entity_name_handler entity_name_handler_rev">return</span><span> tReturn</span> <span> </span><span class="keyword keyword_control keyword_control_rev">end</span><span> </span><span class="keyword keyword_control keyword_control_rev">if</span> <span> </span><span class="keyword keyword_control keyword_control_rev">end</span><span> </span><span class="keyword keyword_control keyword_control_rev">repeat</span> <span class="keyword keyword_control keyword_control_rev">end</span><span> executeProcess</span>
LiveCode DataGrid Drag & Drop Reordering
I have a project where using a data grid form really simplifies things, however, it’s critical that the user can re-order the list in arbitrary way. To do this I needed to add drag and drop to the data grid.
First I wrote rolled my own:
There two main limitations with this code are that it will only work for a data grid form (not table) and only if the cache controls property is true.
<span class="entity entity_name entity_name_handler entity_name_handler_rev">local</span><span> sDragImage</span><span class="keyword keyword_operator keyword_operator_symbolic keyword_operator_symbolic_rev">,</span><span>sControlIndexMap</span><span class="keyword keyword_operator keyword_operator_symbolic keyword_operator_symbolic_rev">,</span><span>sOriginalIndexes</span> <span class="storage storage_type storage_type_handler storage_type_handler_rev">on</span><span> dragStart</span> <span> </span><span class="entity entity_name entity_name_handler entity_name_handler_rev">local</span><span> tControl</span><span class="keyword keyword_operator keyword_operator_symbolic keyword_operator_symbolic_rev">,</span><span>tItem</span> <span> </span><span class="entity entity_name entity_name_handler entity_name_handler_rev">set</span><span> </span><span class="keyword keyword_control keyword_control_rev">the</span><span> </span><span class="support support_command support_command_rev">dragData</span><span class="keyword keyword_operator keyword_operator_symbolic keyword_operator_symbolic_rev">[</span><span class="string string_quoted string_quoted_double string_quoted_double_transcript">"private"</span><span class="keyword keyword_operator keyword_operator_symbolic keyword_operator_symbolic_rev">]</span><span> </span><span class="keyword keyword_control keyword_control_rev">to</span><span> </span><span class="string string_quoted string_quoted_double string_quoted_double_transcript">"dgDragIndex"</span><span class="keyword keyword_operator keyword_operator_symbolic keyword_operator_symbolic_rev">&&</span><span class="keyword keyword_control keyword_control_rev">the</span><span> dgHilitedIndex </span><span class="keyword keyword_control keyword_control_rev">of</span><span> </span><span class="entity entity_name entity_name_handler entity_name_handler_rev">me</span> <span> </span><span class="entity entity_name entity_name_handler entity_name_handler_rev">put</span><span> </span><span class="keyword keyword_control keyword_control_rev">the</span><span> dgDataControlOfIndex</span><span class="keyword keyword_operator keyword_operator_symbolic keyword_operator_symbolic_rev">[</span><span class="keyword keyword_control keyword_control_rev">the</span><span> dgHilitedIndex </span><span class="keyword keyword_control keyword_control_rev">of</span><span> </span><span class="entity entity_name entity_name_handler entity_name_handler_rev">me</span><span class="keyword keyword_operator keyword_operator_symbolic keyword_operator_symbolic_rev">]</span><span> </span><span class="keyword keyword_control keyword_control_rev">of</span><span> </span><span class="entity entity_name entity_name_handler entity_name_handler_rev">me</span><span> </span><span class="keyword keyword_control keyword_control_rev">into</span><span> tControl</span> <span> </span><span class="entity entity_name entity_name_handler entity_name_handler_rev">lock</span><span> </span><span class="support support_command support_command_rev">screen</span> <span> </span><span class="entity entity_name entity_name_handler entity_name_handler_rev">import</span><span> </span><span class="keyword keyword_control keyword_control_rev">snapshot</span><span> </span><span class="keyword keyword_control keyword_control_rev">from</span><span> tControl</span> <span> </span><span class="entity entity_name entity_name_handler entity_name_handler_rev">put</span><span> </span><span class="keyword keyword_control keyword_control_rev">the</span><span> </span><span class="support support_command support_command_rev">long</span><span> </span><span class="support support_command support_command_rev">id</span><span> </span><span class="keyword keyword_control keyword_control_rev">of</span><span> </span><span class="keyword keyword_control keyword_control_rev">the</span><span> </span><span class="keyword keyword_control keyword_control_rev">last</span><span> </span><span class="keyword keyword_control keyword_control_rev">image</span><span> </span><span class="keyword keyword_control keyword_control_rev">into</span><span> sDragImage</span> <span> </span><span class="entity entity_name entity_name_handler entity_name_handler_rev">set</span><span> </span><span class="keyword keyword_control keyword_control_rev">the</span><span> </span><span class="support support_command support_command_rev">visible</span><span> </span><span class="keyword keyword_control keyword_control_rev">of</span><span> sDragImage </span><span class="keyword keyword_control keyword_control_rev">to</span><span> </span><span class="keyword keyword_control keyword_control_rev">false</span> <span> </span><span class="entity entity_name entity_name_handler entity_name_handler_rev">set</span><span> </span><span class="keyword keyword_control keyword_control_rev">the</span><span> </span><span class="support support_command support_command_rev">dragImage</span><span> </span><span class="keyword keyword_control keyword_control_rev">to</span><span> </span><span class="keyword keyword_control keyword_control_rev">the</span><span> </span><span class="support support_command support_command_rev">short</span><span> </span><span class="support support_command support_command_rev">id</span><span> </span><span class="keyword keyword_control keyword_control_rev">of</span><span> sDragImage</span> <span> </span><span class="entity entity_name entity_name_handler entity_name_handler_rev">put</span><span> </span><span class="keyword keyword_control keyword_control_rev">the</span><span> dgIndexes </span><span class="keyword keyword_control keyword_control_rev">of</span><span> </span><span class="entity entity_name entity_name_handler entity_name_handler_rev">me</span><span> </span><span class="keyword keyword_control keyword_control_rev">into</span><span> sOriginalIndexes</span> <span> </span><span class="entity entity_name entity_name_handler entity_name_handler_rev">delete</span><span> </span><span class="keyword keyword_control keyword_control_rev">variable</span><span> sControlIndexMap</span> <span> </span><span class="keyword keyword_control keyword_control_rev">repeat</span><span> </span><span class="keyword keyword_control keyword_control_rev">for</span><span> </span><span class="keyword keyword_control keyword_control_rev">each</span><span> </span><span class="keyword keyword_control keyword_control_rev">item</span><span> tItem </span><span class="keyword keyword_control keyword_control_rev">in</span><span> </span><span class="keyword keyword_control keyword_control_rev">the</span><span> dgIndexes </span><span class="keyword keyword_control keyword_control_rev">of</span><span> </span><span class="entity entity_name entity_name_handler entity_name_handler_rev">me</span> <span> </span><span class="entity entity_name entity_name_handler entity_name_handler_rev">put</span><span> tItem </span><span class="keyword keyword_control keyword_control_rev">into</span><span> sControlIndexMap</span><span class="keyword keyword_operator keyword_operator_symbolic keyword_operator_symbolic_rev">[</span><span class="keyword keyword_control keyword_control_rev">the</span><span> dgDataControlOfIndex</span><span class="keyword keyword_operator keyword_operator_symbolic keyword_operator_symbolic_rev">[</span><span>tItem</span><span class="keyword keyword_operator keyword_operator_symbolic keyword_operator_symbolic_rev">]</span><span> </span><span class="keyword keyword_control keyword_control_rev">of</span><span> </span><span class="entity entity_name entity_name_handler entity_name_handler_rev">me</span><span class="keyword keyword_operator keyword_operator_symbolic keyword_operator_symbolic_rev">]</span> <span> </span><span class="keyword keyword_control keyword_control_rev">end</span><span> </span><span class="keyword keyword_control keyword_control_rev">repeat</span> <span> </span><span class="entity entity_name entity_name_handler entity_name_handler_rev">set</span><span> </span><span class="keyword keyword_control keyword_control_rev">the</span><span> </span><span class="support support_command support_command_rev">allowableDragActions</span><span> </span><span class="keyword keyword_control keyword_control_rev">to</span><span> </span><span class="string string_quoted string_quoted_double string_quoted_double_transcript">"move"</span> <span> </span><span class="entity entity_name entity_name_handler entity_name_handler_rev">pass</span><span> dragStart</span> <span class="keyword keyword_control keyword_control_rev">end</span><span> dragStart</span> <span class="storage storage_type storage_type_handler storage_type_handler_rev">on</span><span> dragMove pX</span><span class="keyword keyword_operator keyword_operator_symbolic keyword_operator_symbolic_rev">,</span><span>pY</span> <span> </span><span class="entity entity_name entity_name_handler entity_name_handler_rev">local</span><span> tDragIndex</span><span class="keyword keyword_operator keyword_operator_symbolic keyword_operator_symbolic_rev">,</span><span>tNewIndexes</span><span class="keyword keyword_operator keyword_operator_symbolic keyword_operator_symbolic_rev">,</span><span>tOverIndex</span> <span> </span><span class="keyword keyword_control keyword_control_rev">if</span><span> </span><span class="keyword keyword_control keyword_control_rev">word</span><span> </span><span class="constant constant_numeric constant_numeric_rev">1</span><span> </span><span class="keyword keyword_control keyword_control_rev">of</span><span> </span><span class="keyword keyword_control keyword_control_rev">the</span><span> </span><span class="support support_command support_command_rev">dragData</span><span class="keyword keyword_operator keyword_operator_symbolic keyword_operator_symbolic_rev">[</span><span class="string string_quoted string_quoted_double string_quoted_double_transcript">"private"</span><span class="keyword keyword_operator keyword_operator_symbolic keyword_operator_symbolic_rev">]</span><span> </span><span class="keyword keyword_operator keyword_operator_symbolic keyword_operator_symbolic_rev">=</span><span> </span><span class="string string_quoted string_quoted_double string_quoted_double_transcript">"dgDragIndex"</span><span> then</span> <span> </span><span class="entity entity_name entity_name_handler entity_name_handler_rev">unlock</span><span> </span><span class="support support_command support_command_rev">screen</span> <span> </span><span class="entity entity_name entity_name_handler entity_name_handler_rev">lock</span><span> </span><span class="support support_command support_command_rev">cursor</span><span> </span><span class="comment comment_line comment_line_number-sign comment_line_number-sign_rev">-- refresh bug workaround on setting the dgIndexes the dragAction seems to get set to none</span> <span> </span><span class="entity entity_name entity_name_handler entity_name_handler_rev">put</span><span> </span><span class="keyword keyword_control keyword_control_rev">word</span><span> </span><span class="constant constant_numeric constant_numeric_rev">2</span><span> </span><span class="keyword keyword_control keyword_control_rev">of</span><span> </span><span class="keyword keyword_control keyword_control_rev">the</span><span> </span><span class="support support_command support_command_rev">dragData</span><span class="keyword keyword_operator keyword_operator_symbolic keyword_operator_symbolic_rev">[</span><span class="string string_quoted string_quoted_double string_quoted_double_transcript">"private"</span><span class="keyword keyword_operator keyword_operator_symbolic keyword_operator_symbolic_rev">]</span><span> </span><span class="keyword keyword_control keyword_control_rev">into</span><span> tDragIndex</span> <span> </span><span class="entity entity_name entity_name_handler entity_name_handler_rev">set</span><span> </span><span class="keyword keyword_control keyword_control_rev">the</span><span> </span><span class="support support_command support_command_rev">dragAction</span><span> </span><span class="keyword keyword_control keyword_control_rev">to</span><span> </span><span class="string string_quoted string_quoted_double string_quoted_double_transcript">"move"</span> <span> </span><span class="keyword keyword_control keyword_control_rev">if</span><span> pY </span><span class="keyword keyword_operator keyword_operator_symbolic keyword_operator_symbolic_rev">></span><span> </span><span class="keyword keyword_control keyword_control_rev">the</span><span> </span><span class="support support_command support_command_rev">bottom</span><span> </span><span class="keyword keyword_control keyword_control_rev">of</span><span> </span><span class="entity entity_name entity_name_handler entity_name_handler_rev">me</span><span class="keyword keyword_operator keyword_operator_symbolic keyword_operator_symbolic_rev">-</span><span class="constant constant_numeric constant_numeric_rev">20</span><span> then</span> <span> </span><span class="keyword keyword_control keyword_control_rev">if</span><span> </span><span class="keyword keyword_control keyword_control_rev">item</span><span> </span><span class="constant constant_numeric constant_numeric_rev">2</span><span> </span><span class="keyword keyword_control keyword_control_rev">of</span><span> </span><span class="keyword keyword_control keyword_control_rev">the</span><span> dgVisibleLines </span><span class="keyword keyword_control keyword_control_rev">of</span><span> </span><span class="entity entity_name entity_name_handler entity_name_handler_rev">me</span><span> </span><span class="keyword keyword_operator keyword_operator_symbolic keyword_operator_symbolic_rev"><</span><span> </span><span class="keyword keyword_control keyword_control_rev">the</span><span> dgNumberOfLines </span><span class="keyword keyword_control keyword_control_rev">of</span><span> </span><span class="entity entity_name entity_name_handler entity_name_handler_rev">me</span><span> </span><span class="keyword keyword_control keyword_control_rev">or</span><span> </span><span class="keyword keyword_control keyword_control_rev">the</span><span> </span><span class="support support_command support_command_rev">scroll</span><span> </span><span class="keyword keyword_control keyword_control_rev">of</span><span> </span><span class="entity entity_name entity_name_handler entity_name_handler_rev">me</span><span> </span><span class="keyword keyword_control keyword_control_rev">is</span><span> </span><span class="keyword keyword_control keyword_control_rev">not</span><span> </span><span class="keyword keyword_control keyword_control_rev">the</span><span> dgFormattedHeight </span><span class="keyword keyword_control keyword_control_rev">of</span><span> </span><span class="entity entity_name entity_name_handler entity_name_handler_rev">me</span><span> then </span> <span> </span><span class="entity entity_name entity_name_handler entity_name_handler_rev">set</span><span> </span><span class="keyword keyword_control keyword_control_rev">the</span><span> dgVscroll </span><span class="keyword keyword_control keyword_control_rev">of</span><span> </span><span class="entity entity_name entity_name_handler entity_name_handler_rev">me</span><span> </span><span class="keyword keyword_control keyword_control_rev">to</span><span> </span><span class="entity entity_name entity_name_handler entity_name_handler_rev">min</span><span class="keyword keyword_operator keyword_operator_symbolic keyword_operator_symbolic_rev">(</span><span class="keyword keyword_control keyword_control_rev">the</span><span> dgVscroll </span><span class="keyword keyword_control keyword_control_rev">of</span><span> </span><span class="entity entity_name entity_name_handler entity_name_handler_rev">me</span><span> </span><span class="keyword keyword_operator keyword_operator_symbolic keyword_operator_symbolic_rev">+</span><span> </span><span class="constant constant_numeric constant_numeric_rev">20</span><span class="keyword keyword_operator keyword_operator_symbolic keyword_operator_symbolic_rev">,</span><span> </span><span class="keyword keyword_control keyword_control_rev">the</span><span> dgFormattedHeight </span><span class="keyword keyword_control keyword_control_rev">of</span><span> </span><span class="entity entity_name entity_name_handler entity_name_handler_rev">me</span><span class="keyword keyword_operator keyword_operator_symbolic keyword_operator_symbolic_rev">)</span> <span> </span><span class="keyword keyword_control keyword_control_rev">end</span><span> </span><span class="keyword keyword_control keyword_control_rev">if</span> <span> </span><span class="keyword keyword_control keyword_control_rev">else</span><span> </span><span class="keyword keyword_control keyword_control_rev">if</span><span> pY </span><span class="keyword keyword_operator keyword_operator_symbolic keyword_operator_symbolic_rev"><</span><span> </span><span class="keyword keyword_control keyword_control_rev">the</span><span> </span><span class="support support_command support_command_rev">top</span><span> </span><span class="keyword keyword_control keyword_control_rev">of</span><span> </span><span class="entity entity_name entity_name_handler entity_name_handler_rev">me</span><span class="keyword keyword_operator keyword_operator_symbolic keyword_operator_symbolic_rev">+</span><span class="constant constant_numeric constant_numeric_rev">20</span><span> then</span> <span> </span><span class="keyword keyword_control keyword_control_rev">if</span><span> </span><span class="keyword keyword_control keyword_control_rev">item</span><span> </span><span class="constant constant_numeric constant_numeric_rev">1</span><span> </span><span class="keyword keyword_control keyword_control_rev">of</span><span> </span><span class="keyword keyword_control keyword_control_rev">the</span><span> dgVisibleLines </span><span class="keyword keyword_control keyword_control_rev">of</span><span> </span><span class="entity entity_name entity_name_handler entity_name_handler_rev">me</span><span> </span><span class="keyword keyword_operator keyword_operator_symbolic keyword_operator_symbolic_rev">></span><span> </span><span class="constant constant_numeric constant_numeric_rev">1</span><span> </span><span class="keyword keyword_control keyword_control_rev">or</span><span> </span><span class="keyword keyword_control keyword_control_rev">the</span><span> </span><span class="support support_command support_command_rev">scroll</span><span> </span><span class="keyword keyword_control keyword_control_rev">of</span><span> </span><span class="entity entity_name entity_name_handler entity_name_handler_rev">me</span><span> </span><span class="keyword keyword_control keyword_control_rev">is</span><span> </span><span class="keyword keyword_control keyword_control_rev">not</span><span> </span><span class="constant constant_numeric constant_numeric_rev">0</span><span> then </span> <span> </span><span class="entity entity_name entity_name_handler entity_name_handler_rev">set</span><span> </span><span class="keyword keyword_control keyword_control_rev">the</span><span> dgVscroll </span><span class="keyword keyword_control keyword_control_rev">of</span><span> </span><span class="entity entity_name entity_name_handler entity_name_handler_rev">me</span><span> </span><span class="keyword keyword_control keyword_control_rev">to</span><span> </span><span class="entity entity_name entity_name_handler entity_name_handler_rev">max</span><span class="keyword keyword_operator keyword_operator_symbolic keyword_operator_symbolic_rev">(</span><span class="keyword keyword_control keyword_control_rev">the</span><span> dgVscroll </span><span class="keyword keyword_control keyword_control_rev">of</span><span> </span><span class="entity entity_name entity_name_handler entity_name_handler_rev">me</span><span> </span><span class="keyword keyword_operator keyword_operator_symbolic keyword_operator_symbolic_rev">-</span><span> </span><span class="constant constant_numeric constant_numeric_rev">20</span><span class="keyword keyword_operator keyword_operator_symbolic keyword_operator_symbolic_rev">,</span><span class="constant constant_numeric constant_numeric_rev">0</span><span class="keyword keyword_operator keyword_operator_symbolic keyword_operator_symbolic_rev">)</span> <span> </span><span class="keyword keyword_control keyword_control_rev">end</span><span> </span><span class="keyword keyword_control keyword_control_rev">if</span> <span> </span><span class="keyword keyword_control keyword_control_rev">end</span><span> </span><span class="keyword keyword_control keyword_control_rev">if</span> <span> </span><span class="keyword keyword_control keyword_control_rev">repeat</span><span> </span><span class="keyword keyword_control keyword_control_rev">with</span><span> X</span><span class="keyword keyword_operator keyword_operator_symbolic keyword_operator_symbolic_rev">=</span><span class="constant constant_numeric constant_numeric_rev">1</span><span> </span><span class="keyword keyword_control keyword_control_rev">to</span><span> </span><span class="keyword keyword_control keyword_control_rev">the</span><span> </span><span class="support support_command support_command_rev">number</span><span> </span><span class="keyword keyword_control keyword_control_rev">of</span><span> </span><span class="keyword keyword_control keyword_control_rev">groups</span><span> </span><span class="keyword keyword_control keyword_control_rev">of</span><span> </span><span class="entity entity_name entity_name_handler entity_name_handler_rev">group</span><span> </span><span class="string string_quoted string_quoted_double string_quoted_double_transcript">"dgList"</span><span> </span><span class="keyword keyword_control keyword_control_rev">of</span><span> </span><span class="entity entity_name entity_name_handler entity_name_handler_rev">me</span> <span> </span><span class="keyword keyword_control keyword_control_rev">if</span><span> </span><span class="keyword keyword_control keyword_control_rev">the</span><span> </span><span class="support support_command support_command_rev">visible</span><span> </span><span class="keyword keyword_control keyword_control_rev">of</span><span> </span><span class="entity entity_name entity_name_handler entity_name_handler_rev">group</span><span> X </span><span class="keyword keyword_control keyword_control_rev">of</span><span> </span><span class="entity entity_name entity_name_handler entity_name_handler_rev">group</span><span> </span><span class="string string_quoted string_quoted_double string_quoted_double_transcript">"dgList"</span><span> </span><span class="keyword keyword_control keyword_control_rev">and</span><span> </span><span class="keyword keyword_control keyword_control_rev">the</span><span> </span><span class="support support_command support_command_rev">short</span><span> </span><span class="support support_command support_command_rev">name</span><span> </span><span class="keyword keyword_control keyword_control_rev">of</span><span> </span><span class="keyword keyword_control keyword_control_rev">the</span><span> </span><span class="entity entity_name entity_name_handler entity_name_handler_rev">owner</span><span> </span><span class="keyword keyword_control keyword_control_rev">of</span><span> </span><span class="entity entity_name entity_name_handler entity_name_handler_rev">group</span><span> X </span><span class="keyword keyword_control keyword_control_rev">of</span><span> </span><span class="entity entity_name entity_name_handler entity_name_handler_rev">group</span><span> </span><span class="string string_quoted string_quoted_double string_quoted_double_transcript">"dgList"</span><span> </span><span class="keyword keyword_control keyword_control_rev">is</span><span> </span><span class="string string_quoted string_quoted_double string_quoted_double_transcript">"dgList"</span><span> then</span> <span> </span><span class="keyword keyword_control keyword_control_rev">if</span><span> </span><span class="keyword keyword_operator keyword_operator_symbolic keyword_operator_symbolic_rev">(</span><span>pY </span><span class="keyword keyword_operator keyword_operator_symbolic keyword_operator_symbolic_rev">>=</span><span> </span><span class="keyword keyword_control keyword_control_rev">the</span><span> </span><span class="support support_command support_command_rev">top</span><span> </span><span class="keyword keyword_control keyword_control_rev">of</span><span> </span><span class="entity entity_name entity_name_handler entity_name_handler_rev">group</span><span> X </span><span class="keyword keyword_control keyword_control_rev">of</span><span> </span><span class="entity entity_name entity_name_handler entity_name_handler_rev">group</span><span> </span><span class="string string_quoted string_quoted_double string_quoted_double_transcript">"dgList"</span><span> </span><span class="keyword keyword_control keyword_control_rev">of</span><span> </span><span class="entity entity_name entity_name_handler entity_name_handler_rev">me</span><span class="keyword keyword_operator keyword_operator_symbolic keyword_operator_symbolic_rev">)</span><span> </span><span class="keyword keyword_control keyword_control_rev">and</span><span> </span><span class="keyword keyword_operator keyword_operator_symbolic keyword_operator_symbolic_rev">(</span><span>pY </span><span class="keyword keyword_operator keyword_operator_symbolic keyword_operator_symbolic_rev"><</span><span> </span><span class="keyword keyword_operator keyword_operator_symbolic keyword_operator_symbolic_rev">(</span><span class="keyword keyword_control keyword_control_rev">the</span><span> </span><span class="support support_command support_command_rev">top</span><span> </span><span class="keyword keyword_control keyword_control_rev">of</span><span> </span><span class="entity entity_name entity_name_handler entity_name_handler_rev">group</span><span> X </span><span class="keyword keyword_control keyword_control_rev">of</span><span> </span><span class="entity entity_name entity_name_handler entity_name_handler_rev">group</span><span> </span><span class="string string_quoted string_quoted_double string_quoted_double_transcript">"dgList"</span><span> </span><span class="keyword keyword_control keyword_control_rev">of</span><span> </span><span class="entity entity_name entity_name_handler entity_name_handler_rev">me</span><span class="keyword keyword_operator keyword_operator_symbolic keyword_operator_symbolic_rev">+(</span><span class="keyword keyword_control keyword_control_rev">the</span><span> </span><span class="support support_command support_command_rev">bottom</span><span> </span><span class="keyword keyword_control keyword_control_rev">of</span><span> </span><span class="entity entity_name entity_name_handler entity_name_handler_rev">group</span><span> X </span><span class="keyword keyword_control keyword_control_rev">of</span><span> </span><span class="entity entity_name entity_name_handler entity_name_handler_rev">group</span><span> </span><span class="string string_quoted string_quoted_double string_quoted_double_transcript">"dgList"</span><span> </span><span class="keyword keyword_control keyword_control_rev">of</span><span> </span><span class="entity entity_name entity_name_handler entity_name_handler_rev">me</span><span class="keyword keyword_operator keyword_operator_symbolic keyword_operator_symbolic_rev">-</span><span class="keyword keyword_control keyword_control_rev">the</span><span> </span><span class="support support_command support_command_rev">top</span><span> </span><span class="keyword keyword_control keyword_control_rev">of</span><span> </span><span class="entity entity_name entity_name_handler entity_name_handler_rev">group</span><span> X </span><span class="keyword keyword_control keyword_control_rev">of</span><span> </span><span class="entity entity_name entity_name_handler entity_name_handler_rev">group</span><span> </span><span class="string string_quoted string_quoted_double string_quoted_double_transcript">"dgList"</span><span> </span><span class="keyword keyword_control keyword_control_rev">of</span><span> </span><span class="entity entity_name entity_name_handler entity_name_handler_rev">me</span><span class="keyword keyword_operator keyword_operator_symbolic keyword_operator_symbolic_rev">)</span><span> </span><span class="keyword keyword_control keyword_control_rev">div</span><span> </span><span class="constant constant_numeric constant_numeric_rev">2</span><span class="keyword keyword_operator keyword_operator_symbolic keyword_operator_symbolic_rev">))</span><span> then</span> <span> </span><span class="comment comment_line comment_line_number-sign comment_line_number-sign_rev">-- place above index</span> <span> </span><span class="entity entity_name entity_name_handler entity_name_handler_rev">put</span><span> sControlIndexMap</span><span class="keyword keyword_operator keyword_operator_symbolic keyword_operator_symbolic_rev">[</span><span class="keyword keyword_control keyword_control_rev">the</span><span> </span><span class="support support_command support_command_rev">long</span><span> </span><span class="support support_command support_command_rev">id</span><span> </span><span class="keyword keyword_control keyword_control_rev">of</span><span> </span><span class="entity entity_name entity_name_handler entity_name_handler_rev">group</span><span> X </span><span class="keyword keyword_control keyword_control_rev">of</span><span> </span><span class="entity entity_name entity_name_handler entity_name_handler_rev">group</span><span> </span><span class="string string_quoted string_quoted_double string_quoted_double_transcript">"dgList"</span><span> </span><span class="keyword keyword_control keyword_control_rev">of</span><span> </span><span class="entity entity_name entity_name_handler entity_name_handler_rev">me</span><span class="keyword keyword_operator keyword_operator_symbolic keyword_operator_symbolic_rev">]</span><span> </span><span class="keyword keyword_control keyword_control_rev">into</span><span> tOverIndex</span> <span> </span><span class="comment comment_line comment_line_number-sign comment_line_number-sign_rev">--put "over"&&tOverIndex</span> <span> </span><span class="keyword keyword_control keyword_control_rev">if</span><span> tDragIndex </span><span class="keyword keyword_operator keyword_operator_symbolic keyword_operator_symbolic_rev">=</span><span> tOverIndex then </span> <span> </span><span class="entity entity_name entity_name_handler entity_name_handler_rev">put</span><span> sOriginalIndexes </span><span class="keyword keyword_control keyword_control_rev">into</span><span> tNewIndexes</span> <span> </span><span class="keyword keyword_control keyword_control_rev">else</span> <span> </span><span class="entity entity_name entity_name_handler entity_name_handler_rev">put</span><span> sOriginalIndexes </span><span class="keyword keyword_control keyword_control_rev">into</span><span> tNewIndexes</span> <span> </span><span class="entity entity_name entity_name_handler entity_name_handler_rev">delete</span><span> </span><span class="keyword keyword_control keyword_control_rev">item</span><span> </span><span class="entity entity_name entity_name_handler entity_name_handler_rev">itemOffset</span><span class="keyword keyword_operator keyword_operator_symbolic keyword_operator_symbolic_rev">(</span><span>tDragIndex</span><span class="keyword keyword_operator keyword_operator_symbolic keyword_operator_symbolic_rev">,</span><span>tNewIndexes</span><span class="keyword keyword_operator keyword_operator_symbolic keyword_operator_symbolic_rev">)</span><span> </span><span class="keyword keyword_control keyword_control_rev">of</span><span> tNewIndexes</span> <span> </span><span class="entity entity_name entity_name_handler entity_name_handler_rev">put</span><span> tDragIndex</span><span class="keyword keyword_operator keyword_operator_symbolic keyword_operator_symbolic_rev">&</span><span class="string string_quoted string_quoted_double string_quoted_double_transcript">","</span><span> </span><span class="keyword keyword_control keyword_control_rev">before</span><span> </span><span class="keyword keyword_control keyword_control_rev">item</span><span> </span><span class="entity entity_name entity_name_handler entity_name_handler_rev">itemOffset</span><span class="keyword keyword_operator keyword_operator_symbolic keyword_operator_symbolic_rev">(</span><span>tOverIndex</span><span class="keyword keyword_operator keyword_operator_symbolic keyword_operator_symbolic_rev">,</span><span>tNewIndexes</span><span class="keyword keyword_operator keyword_operator_symbolic keyword_operator_symbolic_rev">)</span><span> </span><span class="keyword keyword_control keyword_control_rev">of</span><span> tNewIndexes</span> <span> </span><span class="keyword keyword_control keyword_control_rev">end</span><span> </span><span class="keyword keyword_control keyword_control_rev">if</span> <span> </span><span class="entity entity_name entity_name_handler entity_name_handler_rev">set</span><span> </span><span class="keyword keyword_control keyword_control_rev">the</span><span> dgIndexes </span><span class="keyword keyword_control keyword_control_rev">of</span><span> </span><span class="entity entity_name entity_name_handler entity_name_handler_rev">me</span><span> </span><span class="keyword keyword_control keyword_control_rev">to</span><span> tNewIndexes</span> <span> </span><span class="entity entity_name entity_name_handler entity_name_handler_rev">put</span><span> tNewIndexes </span><span class="keyword keyword_control keyword_control_rev">into</span><span> sOriginalIndexes</span> <span> </span><span class="keyword keyword_control keyword_control_rev">else</span><span> </span><span class="keyword keyword_control keyword_control_rev">if</span><span> </span><span class="keyword keyword_operator keyword_operator_symbolic keyword_operator_symbolic_rev">(</span><span>pY </span><span class="keyword keyword_operator keyword_operator_symbolic keyword_operator_symbolic_rev"><=</span><span> </span><span class="keyword keyword_control keyword_control_rev">the</span><span> </span><span class="support support_command support_command_rev">bottom</span><span> </span><span class="keyword keyword_control keyword_control_rev">of</span><span> </span><span class="entity entity_name entity_name_handler entity_name_handler_rev">group</span><span> X </span><span class="keyword keyword_control keyword_control_rev">of</span><span> </span><span class="entity entity_name entity_name_handler entity_name_handler_rev">group</span><span> </span><span class="string string_quoted string_quoted_double string_quoted_double_transcript">"dgList"</span><span> </span><span class="keyword keyword_control keyword_control_rev">of</span><span> </span><span class="entity entity_name entity_name_handler entity_name_handler_rev">me</span><span class="keyword keyword_operator keyword_operator_symbolic keyword_operator_symbolic_rev">)</span><span> </span><span class="keyword keyword_control keyword_control_rev">and</span><span> </span><span class="keyword keyword_operator keyword_operator_symbolic keyword_operator_symbolic_rev">(</span><span>pY </span><span class="keyword keyword_operator keyword_operator_symbolic keyword_operator_symbolic_rev">></span><span> </span><span class="keyword keyword_operator keyword_operator_symbolic keyword_operator_symbolic_rev">(</span><span class="keyword keyword_control keyword_control_rev">the</span><span> </span><span class="support support_command support_command_rev">top</span><span> </span><span class="keyword keyword_control keyword_control_rev">of</span><span> </span><span class="entity entity_name entity_name_handler entity_name_handler_rev">group</span><span> X </span><span class="keyword keyword_control keyword_control_rev">of</span><span> </span><span class="entity entity_name entity_name_handler entity_name_handler_rev">group</span><span> </span><span class="string string_quoted string_quoted_double string_quoted_double_transcript">"dgList"</span><span> </span><span class="keyword keyword_control keyword_control_rev">of</span><span> </span><span class="entity entity_name entity_name_handler entity_name_handler_rev">me</span><span class="keyword keyword_operator keyword_operator_symbolic keyword_operator_symbolic_rev">+(</span><span class="keyword keyword_control keyword_control_rev">the</span><span> </span><span class="support support_command support_command_rev">bottom</span><span> </span><span class="keyword keyword_control keyword_control_rev">of</span><span> </span><span class="entity entity_name entity_name_handler entity_name_handler_rev">group</span><span> X </span><span class="keyword keyword_control keyword_control_rev">of</span><span> </span><span class="entity entity_name entity_name_handler entity_name_handler_rev">group</span><span> </span><span class="string string_quoted string_quoted_double string_quoted_double_transcript">"dgList"</span><span> </span><span class="keyword keyword_control keyword_control_rev">of</span><span> </span><span class="entity entity_name entity_name_handler entity_name_handler_rev">me</span><span class="keyword keyword_operator keyword_operator_symbolic keyword_operator_symbolic_rev">-</span><span class="keyword keyword_control keyword_control_rev">the</span><span> </span><span class="support support_command support_command_rev">top</span><span> </span><span class="keyword keyword_control keyword_control_rev">of</span><span> </span><span class="entity entity_name entity_name_handler entity_name_handler_rev">group</span><span> X </span><span class="keyword keyword_control keyword_control_rev">of</span><span> </span><span class="entity entity_name entity_name_handler entity_name_handler_rev">group</span><span> </span><span class="string string_quoted string_quoted_double string_quoted_double_transcript">"dgList"</span><span> </span><span class="keyword keyword_control keyword_control_rev">of</span><span> </span><span class="entity entity_name entity_name_handler entity_name_handler_rev">me</span><span class="keyword keyword_operator keyword_operator_symbolic keyword_operator_symbolic_rev">)</span><span> </span><span class="keyword keyword_control keyword_control_rev">div</span><span> </span><span class="constant constant_numeric constant_numeric_rev">2</span><span class="keyword keyword_operator keyword_operator_symbolic keyword_operator_symbolic_rev">))</span><span> then</span> <span> </span><span class="comment comment_line comment_line_number-sign comment_line_number-sign_rev">-- place below index</span> <span> </span><span class="entity entity_name entity_name_handler entity_name_handler_rev">put</span><span> sControlIndexMap</span><span class="keyword keyword_operator keyword_operator_symbolic keyword_operator_symbolic_rev">[</span><span class="keyword keyword_control keyword_control_rev">the</span><span> </span><span class="support support_command support_command_rev">long</span><span> </span><span class="support support_command support_command_rev">id</span><span> </span><span class="keyword keyword_control keyword_control_rev">of</span><span> </span><span class="entity entity_name entity_name_handler entity_name_handler_rev">group</span><span> X </span><span class="keyword keyword_control keyword_control_rev">of</span><span> </span><span class="entity entity_name entity_name_handler entity_name_handler_rev">group</span><span> </span><span class="string string_quoted string_quoted_double string_quoted_double_transcript">"dgList"</span><span> </span><span class="keyword keyword_control keyword_control_rev">of</span><span> </span><span class="entity entity_name entity_name_handler entity_name_handler_rev">me</span><span class="keyword keyword_operator keyword_operator_symbolic keyword_operator_symbolic_rev">]</span><span> </span><span class="keyword keyword_control keyword_control_rev">into</span><span> tOverIndex</span> <span> </span><span class="comment comment_line comment_line_number-sign comment_line_number-sign_rev">--put "over"&&tOverIndex</span> <span> </span><span class="keyword keyword_control keyword_control_rev">if</span><span> tDragIndex </span><span class="keyword keyword_operator keyword_operator_symbolic keyword_operator_symbolic_rev">=</span><span> tOverIndex then </span> <span> </span><span class="entity entity_name entity_name_handler entity_name_handler_rev">put</span><span> sOriginalIndexes </span><span class="keyword keyword_control keyword_control_rev">into</span><span> tNewIndexes</span> <span> </span><span class="keyword keyword_control keyword_control_rev">else</span> <span> </span><span class="entity entity_name entity_name_handler entity_name_handler_rev">put</span><span> sOriginalIndexes </span><span class="keyword keyword_control keyword_control_rev">into</span><span> tNewIndexes</span> <span> </span><span class="entity entity_name entity_name_handler entity_name_handler_rev">delete</span><span> </span><span class="keyword keyword_control keyword_control_rev">item</span><span> </span><span class="entity entity_name entity_name_handler entity_name_handler_rev">itemOffset</span><span class="keyword keyword_operator keyword_operator_symbolic keyword_operator_symbolic_rev">(</span><span>tDragIndex</span><span class="keyword keyword_operator keyword_operator_symbolic keyword_operator_symbolic_rev">,</span><span>tNewIndexes</span><span class="keyword keyword_operator keyword_operator_symbolic keyword_operator_symbolic_rev">)</span><span> </span><span class="keyword keyword_control keyword_control_rev">of</span><span> tNewIndexes</span> <span> </span><span class="entity entity_name entity_name_handler entity_name_handler_rev">put</span><span> </span><span class="string string_quoted string_quoted_double string_quoted_double_transcript">","</span><span class="keyword keyword_operator keyword_operator_symbolic keyword_operator_symbolic_rev">&</span><span>tDragIndex </span><span class="keyword keyword_control keyword_control_rev">after</span><span> </span><span class="keyword keyword_control keyword_control_rev">item</span><span> </span><span class="entity entity_name entity_name_handler entity_name_handler_rev">itemOffset</span><span class="keyword keyword_operator keyword_operator_symbolic keyword_operator_symbolic_rev">(</span><span>tOverIndex</span><span class="keyword keyword_operator keyword_operator_symbolic keyword_operator_symbolic_rev">,</span><span>tNewIndexes</span><span class="keyword keyword_operator keyword_operator_symbolic keyword_operator_symbolic_rev">)</span><span> </span><span class="keyword keyword_control keyword_control_rev">of</span><span> tNewIndexes</span> <span> </span><span class="keyword keyword_control keyword_control_rev">end</span><span> </span><span class="keyword keyword_control keyword_control_rev">if</span> <span> </span><span class="entity entity_name entity_name_handler entity_name_handler_rev">set</span><span> </span><span class="keyword keyword_control keyword_control_rev">the</span><span> dgIndexes </span><span class="keyword keyword_control keyword_control_rev">of</span><span> </span><span class="entity entity_name entity_name_handler entity_name_handler_rev">me</span><span> </span><span class="keyword keyword_control keyword_control_rev">to</span><span> tNewIndexes</span> <span> </span><span class="entity entity_name entity_name_handler entity_name_handler_rev">put</span><span> tNewIndexes </span><span class="keyword keyword_control keyword_control_rev">into</span><span> sOriginalIndexes</span> <span> </span><span class="keyword keyword_control keyword_control_rev">end</span><span> </span><span class="keyword keyword_control keyword_control_rev">if</span> <span> </span><span class="keyword keyword_control keyword_control_rev">end</span><span> </span><span class="keyword keyword_control keyword_control_rev">if</span> <span> </span><span class="keyword keyword_control keyword_control_rev">end</span><span> </span><span class="keyword keyword_control keyword_control_rev">repeat</span> <span> </span><span class="keyword keyword_control keyword_control_rev">end</span><span> </span><span class="keyword keyword_control keyword_control_rev">if</span> <span> </span><span class="entity entity_name entity_name_handler entity_name_handler_rev">pass</span><span> dragMove</span> <span class="keyword keyword_control keyword_control_rev">end</span><span> dragMove</span> <span class="storage storage_type storage_type_handler storage_type_handler_rev">on</span><span> dragEnd</span> <span> </span><span class="comment comment_line comment_line_number-sign comment_line_number-sign_rev">-- clean up</span> <span> </span><span class="keyword keyword_control keyword_control_rev">if</span><span> sDragImage </span><span class="keyword keyword_operator keyword_operator_symbolic keyword_operator_symbolic_rev"><></span><span> </span><span class="string string_quoted string_quoted_double string_quoted_double_transcript">""</span><span> then</span> <span> </span><span class="entity entity_name entity_name_handler entity_name_handler_rev">delete</span><span> sDragImage</span> <span> </span><span class="entity entity_name entity_name_handler entity_name_handler_rev">put</span><span> </span><span class="string string_quoted string_quoted_double string_quoted_double_transcript">""</span><span> </span><span class="keyword keyword_control keyword_control_rev">into</span><span> sDragImage</span> <span> </span><span class="keyword keyword_control keyword_control_rev">end</span><span> </span><span class="keyword keyword_control keyword_control_rev">if</span> <span> </span><span class="entity entity_name entity_name_handler entity_name_handler_rev">pass</span><span> dragEnd</span> <span class="keyword keyword_control keyword_control_rev">end</span><span> dragEnd</span>
Then I had a poke around the data grid behavior script and found undocumented support for drag and drop. So here’s the new script that does not have the limitations of the above and is obviously far less verbose:
<span class="storage storage_type storage_type_handler storage_type_handler_rev">on</span><span> dragStart</span> <span> </span><span class="entity entity_name entity_name_handler entity_name_handler_rev">local</span><span> tIndex</span> <span> </span><span class="keyword keyword_control keyword_control_rev">if</span><span> </span><span class="keyword keyword_operator keyword_operator_symbolic keyword_operator_symbolic_rev">(</span><span class="keyword keyword_control keyword_control_rev">the</span><span> dgHeader </span><span class="keyword keyword_control keyword_control_rev">of</span><span> </span><span class="keyword keyword_control keyword_control_rev">the</span><span> </span><span class="entity entity_name entity_name_handler entity_name_handler_rev">target</span><span> </span><span class="keyword keyword_control keyword_control_rev">is</span><span> </span><span class="keyword keyword_control keyword_control_rev">empty</span><span class="keyword keyword_operator keyword_operator_symbolic keyword_operator_symbolic_rev">)</span><span> then</span> <span> </span><span class="entity entity_name entity_name_handler entity_name_handler_rev">put</span><span> </span><span class="keyword keyword_control keyword_control_rev">the</span><span> dgIndex </span><span class="keyword keyword_control keyword_control_rev">of</span><span> </span><span class="keyword keyword_control keyword_control_rev">the</span><span> dgDataControl </span><span class="keyword keyword_control keyword_control_rev">of</span><span> </span><span class="keyword keyword_control keyword_control_rev">the</span><span> </span><span class="entity entity_name entity_name_handler entity_name_handler_rev">target</span><span> </span><span class="keyword keyword_control keyword_control_rev">into</span><span> tIndex</span> <span> </span><span class="entity entity_name entity_name_handler entity_name_handler_rev">set</span><span> </span><span class="keyword keyword_control keyword_control_rev">the</span><span> dgDragImageIndex </span><span class="keyword keyword_control keyword_control_rev">of</span><span> </span><span class="entity entity_name entity_name_handler entity_name_handler_rev">me</span><span> </span><span class="keyword keyword_control keyword_control_rev">to</span><span> tIndex</span> <span> </span><span class="entity entity_name entity_name_handler entity_name_handler_rev">set</span><span> </span><span class="keyword keyword_control keyword_control_rev">the</span><span> </span><span class="support support_command support_command_rev">dragData</span><span class="keyword keyword_operator keyword_operator_symbolic keyword_operator_symbolic_rev">[</span><span class="string string_quoted string_quoted_double string_quoted_double_transcript">"private"</span><span class="keyword keyword_operator keyword_operator_symbolic keyword_operator_symbolic_rev">]</span><span> </span><span class="keyword keyword_control keyword_control_rev">to</span><span> </span><span class="keyword keyword_control keyword_control_rev">empty</span> <span> </span><span class="entity entity_name entity_name_handler entity_name_handler_rev">set</span><span> </span><span class="keyword keyword_control keyword_control_rev">the</span><span> dgTrackDragReorder</span><span class="keyword keyword_operator keyword_operator_symbolic keyword_operator_symbolic_rev">[</span><span>tIndex</span><span class="keyword keyword_operator keyword_operator_symbolic keyword_operator_symbolic_rev">]</span><span> </span><span class="keyword keyword_control keyword_control_rev">of</span><span> </span><span class="entity entity_name entity_name_handler entity_name_handler_rev">me</span><span> </span><span class="keyword keyword_control keyword_control_rev">to</span><span> </span><span class="keyword keyword_control keyword_control_rev">true</span> <span> </span><span class="keyword keyword_control keyword_control_rev">end</span><span> </span><span class="keyword keyword_control keyword_control_rev">if</span> <span class="keyword keyword_control keyword_control_rev">end</span><span> dragStart</span> <span class="storage storage_type storage_type_handler storage_type_handler_rev">on</span><span> DragReorderDrop pOriginatingIndex</span><span class="keyword keyword_operator keyword_operator_symbolic keyword_operator_symbolic_rev">,</span><span> pStartLine</span><span class="keyword keyword_operator keyword_operator_symbolic keyword_operator_symbolic_rev">,</span><span> pDroppedOnLine</span> <span> </span><span class="keyword keyword_control keyword_control_rev">if</span><span> </span><span class="keyword keyword_operator keyword_operator_symbolic keyword_operator_symbolic_rev">(</span><span>pStartLine </span><span class="keyword keyword_control keyword_control_rev">is</span><span> </span><span class="keyword keyword_control keyword_control_rev">not</span><span> pDroppedOnLine</span><span class="keyword keyword_operator keyword_operator_symbolic keyword_operator_symbolic_rev">)</span><span> then</span> <span> SetLineOfIndex pOriginatingIndex</span><span class="keyword keyword_operator keyword_operator_symbolic keyword_operator_symbolic_rev">,</span><span> pDroppedOnLine</span> <span> </span><span class="entity entity_name entity_name_handler entity_name_handler_rev">send</span><span> </span><span class="string string_quoted string_quoted_double string_quoted_double_transcript">"RefreshList"</span><span> </span><span class="keyword keyword_control keyword_control_rev">to</span><span> </span><span class="entity entity_name entity_name_handler entity_name_handler_rev">me</span><span> </span><span class="keyword keyword_control keyword_control_rev">in</span><span> </span><span class="constant constant_numeric constant_numeric_rev">0</span><span> </span><span class="entity entity_name entity_name_handler entity_name_handler_rev">secs</span> <span> </span><span class="keyword keyword_control keyword_control_rev">end</span><span> </span><span class="keyword keyword_control keyword_control_rev">if</span> <span class="keyword keyword_control keyword_control_rev">end</span><span> DragReorderDrop</span> <span class="storage storage_type storage_type_handler storage_type_handler_rev">on</span><span> dragMove</span> <span> </span><span class="entity entity_name entity_name_handler entity_name_handler_rev">set</span><span> </span><span class="keyword keyword_control keyword_control_rev">the</span><span> </span><span class="support support_command support_command_rev">dragaction</span><span> </span><span class="keyword keyword_control keyword_control_rev">to</span><span> </span><span class="string string_quoted string_quoted_double string_quoted_double_transcript">"move"</span> <span class="keyword keyword_control keyword_control_rev">end</span><span> dragMove</span>
Create a disabled version of an image
After a correction on my greyscale formula in my last post from Mark on facebook I reviewed the results of my code and decided the disabled look wasn’t quite right. What I wanted was a a washed out looking version. This code and plugin modifies the alphaData of the image to 33% of the original and greys the imageData 15% more. You can modify the constants in the button code if you want different ratios. Here’s the code:
<code>constant kTranslucencyRatio = 0.33 constant kGreyRatio = 0.15 on fadeImage pImageID local tAlphaData,tOffset,tWidth,tHeight,tAlpha lock screen put the width of pImageID into tWidth put the height of pImageID onto tHeight put the alphaData of pImageID into tAlphaData repeat with tOffset = 0 to tWidth *tHeight put charToNum(char tOffset of tAlphaData) into tAlpha -- handle cases of very low alpha for edge smoothing if round(tAlpha*kTranslucencyRatio) > 0 then put NumToChar(round(tAlpha*kTranslucencyRatio)) into char tOffset of tAlphaData end if end repeat set the alphaData of pImageID to tAlphaData end fadeImage on greyImage pImageID local tImageData, tRed, tGreen, tBlue, tGrey, tOffset,tWidth,tHeight lock screen put the width of pImageID into tWidth put the height of pImageID onto tHeight put the imageData of pImageID into tImageData repeat with tOffset = 0 to tWidth *tHeight * 4 step 4 put charToNum(char tOffset + 2 of tImageData) into tRed put charToNum(char tOffset + 3 of tImageData) into tGreen put charToNum(char tOffset + 4 of tImageData) into tBlue put (30*tRed+59*tGreen+11*tBlue)/100 into tGrey put round(tGrey*kGreyRatio+tRed*(1-kGreyRatio)) into tRed put round(tGrey*kGreyRatio+tGreen*(1-kGreyRatio)) into tGreen put round(tGrey*kGreyRatio+tBlue*(1-kGreyRatio)) into tBlue put NumToChar(tRed) into char tOffset + 2 of tImageData put NumToChar(tGreen) into char tOffset + 3 of tImageData put NumToChar(tBlue) into char tOffset + 4 of tImageData end repeat set the imageData of pImageID to tImageData end greyImage</code>
[dm]10[/dm]
Greyscale an image
Now that I’ve got all my icons into the image library (see my recursive image library creation post) I wanted to limit the number of times I need to go back to an image editor to mess with the original files to create variations. One of the most common variations for button icons is the greyed out disabled icon so I wrote a little rev plugin to greyscale the selected images.
The plugin uses the following command:
<code>on greyscale pImageID local tImageData, tRed, tGreen, tBlue, tGrey, tOffset,tWidth,tHeight lock screen put the width of pImageID into tWidth put the height of pImageID onto tHeight put the imageData of pImageID into tImageData repeat with tOffset = 0 to tWidth *tHeight * 4 step 4 put charToNum(char tOffset + 2 of tImageData) into tRed put charToNum(char tOffset + 3 of tImageData) into tGreen put charToNum(char tOffset + 4 of tImageData) into tBlue --correction for better greyscale from Mark --put (tRed+tGreen+tBlue) div 3 into tGrey put (tRed*30+tGreen*59+tBlue*11) / 100 into tGrey put NumToChar(tGrey) into char tOffset + 2 of tImageData put NumToChar(tGrey) into char tOffset + 3 of tImageData put NumToChar(tGrey) into char tOffset + 4 of tImageData end repeat set the imageData of pImageID to tImageData end greyscale</code>
[dm]9[/dm]
Recursive Image Library Creation In Revolution
I use an icon collection that is a whole pile (around 2000) of png images stored in a hierarchy of folders (eg Objects and People/48×48/plain/). It has become annoying finding and importing these images one by one into my applications as needed so I wrote a little drag and drop plugin to import images into a stack whenever they are dropped. It works until you have an app your working on that uses drag and drop and then it fails so I thought I’d give the rev image library setup a go. Rather than import images into libraries by hand I decided to slap together a little recursive image library from folder script. Copy the code to a button then click it. The library name is built out of the names of the folders starting with the one you selected.
<code>on mouseUp local tLibraryFileA answer folder "Choose a folder:" if the result is "cancel" then exit mouseUp recursiveImageLibrary it,"",tLibraryFileA repeat for each line tLine in the keys of tLibraryFileA createImageLibrary tLine,tLibraryFileA[tLine] end repeat end mouseUp on recursiveImageLibrary pFolder,pLibraryName,@pLibraryFileA local tOldFolder put the defaultFolder into tOldFolder set the defaultFolder to pFolder set the itemDel to "/" if pLibraryName <> "" then put " " after pLibraryName put item -1 of pFolder after pLibraryName set the itemDel to "." repeat for each line tFile in the files if item -1 of tFile is among the items of "jpg.png.gif" then put pFolder&"/"&tFile&cr after pLibraryFileA[pLibraryName] end if end repeat repeat for each line tFolder in line 2 to -1 of the folders recursiveImageLibrary pFolder&"/"&tFolder,pLibraryName,pLibraryFileA end repeat end recursiveImageLibrary on createImageLibrary pLibraryName,pLibraryFiles local tHighID,tList -- create the stack put 230000 into tHighID if char 1 to 6 of pLibraryName is not "revLib" then put "revLib" before pLibraryName if there is a stack pLibraryName then answer error "A library with the same name ("&pLibraryName&") as this library already exists." with "Cancel" exit createImageLibrary end if put revAbsoluteFolderListing(revEnvironmentUserResourcesPath("Icon Libraries",true)) into tList put cr & "revGeneralIcons" & cr & "revCompatibilityIcons1" after tList repeat for each line l in tList if l is empty or there is not a stack l then next repeat if the name of stack l is pLibraryName then answer error "That library already exists." with "Cancel" exit createImageLibrary end if put the ID of stack l into item (the number of items in tHighID+1) of tHighID end repeat if there is a file (pLibraryName & ".rev") then answer error "A library with the name" && pLibraryName & ".rev" && "already exists." with "Cancel" exit createImageLibrary end if set the name of the templateStack to pLibraryName set the destroyStack of the templateStack to false lock messages set the style of the templateStack to "modeless" create invisible stack reset the templateStack set the mainStack of stack pLibraryName to pLibraryName set the ID of stack pLibraryName to (max(tHighID)+1) set the fileName of stack pLibraryName to revEnvironmentUserResourcesPath("Icon Libraries") & "/" & pLibraryName & ".rev" set the defaultStack to pLibraryName -- just to make sure -- now import all the images repeat for each line tImage in pLibraryFiles if there is a file tImage then if tImage is not empty then import paint from file tImage end if end if end repeat compact stack pLibraryName save stack pLibraryName close stack pLibraryName unlock messages end createImageLibrary</code>
OK, once you are done there are two IDE mods that you should make.
If you had a big hierarchy of folders like me you will probably want to sort the image library list so choose View > Revolution UI Elements In Lists from the menu then open up the application browser and find the images card of the revImageLibrary stack and edit the script. Just after “delete last char of tStacksList” add “sort tStacksList”
Next for some reason way back in the depths of time the good people at RunRev forgot to upgrade the icon chooser to support image libraries. “What’s the point of image libraries without them being in the icon chooser?” I hear you ask. Very good question.
Replace the preOpenStack handler in revIconChooser card 1 with:
<code>on preOpenStack put revAbsoluteFolderListing(revEnvironmentResourcesPath("Icon Libraries")) into tEnvironmentIcons put revAbsoluteFolderListing(revEnvironmentUserResourcesPath("Icon Libraries")) into tUserIcons put revCombineFilePaths(tUserIcons,tEnvironmentIcons) into tList repeat for each line l in tList if there is not a stack l then next repeat -- windows placeholder if char 1 to 6 of the short name of stack l is "revLib" then put char 7 to -1 of the short name of stack l & cr after tStacksList else if char 1 to 3 of the short name of stack l is "rev" then put char 4 to -1 of the short name of stack l & cr after tStacksList else put the short name of stack l & cr after tStacksList end repeat delete last char of tStacksList sort tStacksList put the text of btn "library chooser" into tText if the platform is "MacOS" then put "-" into tDivider else put empty into tDivider if tStacksList is not empty then put line 1 to 5 tText & cr & tDivider & cr & tStacksList into btn "library chooser" else put line 1 to 5 of tText into btn "library chooser" send "menuPick" && the label of btn "library chooser" to btn "library chooser" set the thumbPosition of scrollbar "iconchooserscrollbar" to 0 put the cCurrentIcon of this stack into fld "ID" # TH-2008-03-06 : Fix for bug 5987 set the pageIncrement of scrollbar "iconchooserscrollbar" to 20 set the lineIncrement of scrollbar "iconchooserscrollbar" to 10 end preOpenStack</code>
Then edit the script of the “library chooser” button on that card. Where it says:
<code>else put "rev" & pWhich into tStackName</code>
Change to
<code>else put "rev" & pWhich into tStackName if there is not a stack tStackName then put "revLib"&pWhich into tStackName end if end if</code>
Database functions and commands
Some handy little general database functions and commands I wrote for an app I’m working on. They need some extra error handling but they are good for getting up and running quickly.
<code>function getTable pTable local tReturn,tSQL put "SELECT * FROM "&pTable into tSQL put revDataFromQuery(tab ,cr ,sDB ,tSQL) into tReturn if tReturn contains "revdberr" then return "" set the itemDel to tab return tReturn end getTable function getTableRecord pTable,pKey,pID local tReturn,tSQL,tQuery put "SELECT * FROM "&pTable&" WHERE "&pKey&" = "&pID into tSQL put revQueryDatabase(sDB,tSQL) into tQuery if not revdb_iseof(tQuery) then revMoveToFirstRecord tQuery repeat for each item tColumn in revDatabaseColumnNames(tQuery) put unSQLString(revDatabaseColumnNamed(tQuery,tColumn)) into tReturn[tColumn] end repeat end if revCloseCursor tQuery return tReturn end getTableRecord command deleteTableRecord pTable,pKey,pID local tReturn,tSQL,tQuery put "DELETE FROM "&pTable&" WHERE "&pKey&" = "&pID into tSQL revExecuteSQL sDB,tSQL end deleteTableRecord on updateTableRecord pTable,pKey,pID,pRecordA local tSQL,tField put "UPDATE "&pTable&" SET" into tSQL repeat for each line tField in keys(pRecordA) if pRecordA[tField] is a number then put " "&tField&"="&pRecordA[tField]&"," after tSQL else put " "&tField&"="&sqlString(pRecordA[tField])&"," after tSQL end if end repeat delete char -1 of tSQL put " WHERE "&pKey&"="&pID into tSQL revExecuteSQL sDB,tSQL end updateTableRecord</code>
Finding out the LAN IP
I had to work out the LAN IP for the machine my app is running on because the IP is needed to enter into an iPhone app so it can sync to the desktop. This is just an temporary measure while we implement zeroconf. Here’s a little modification of Ken Ray’s great GetMACAddress function to return the LAN IP.
<code>function getLANIP -- value to return local retVal,tCard,ifConfigs,winExists,sys32Exists,temp set the itemDel to "." switch (the platform) case "MacOS" if item 1 of the systemVersion <10 then return "" else -- OS X repeat with X=1 to 10 put "en"&X into tCard put shell("ifconfig "&tCard) into ifConfigs if char 1 to 9 of ifConfigs = "ifconfigs:" then exit repeat else if char 1 to 4 of ifConfigs = "zsh:" then return "" else get matchText(ifconfigs,"(?s)inet (.*?) ",retVal) -- These are spaces on either side of (.*?) if it is false then return "" else exit repeat end if end if end repeat end if break case "Win32" -- All Windows put (there is a file (specialFolderPath("system") & "/IPCONFIG.EXE")) into winExists put (there is a file (specialFolderPath("system") & "/SYSTEM32/IPCONFIG.EXE")) into sys32Exists if winExists or sys32Exists then set the hideConsoleWindows to true put shell("ipconfig /all") into temp if word 2 of systemVersion() < 6 then get matchText(temp,"IP Address[\. ]*: ([A-Z0-9-.]*)",retVal) else get matchText(temp,"IPv4 Address[\. ]*: ([A-Z0-9-.]*)",retVal) end if else return "" end if break end switch return retVal end getLANIP</code>