/* * $VER: DOpus4-Intersect 1.4 (04 Jul 2015) by Wizardry and Steamworks * * © 2015 Wizardry and Steamworks * * PROGRAMNAME: * DOpus4-Intersect * * FUNCTION: * Deselects all the selected entries in one window pane that cannot * be found amongst the items selected in the other window pane. * * USAGE: * ARexx command DOpus4-Intersect.rexx (from DOpus) * * $HISTORY: * * 04 Jul 2015 : 1.4 : scrolling fix, normalize to upper * 27 Jun 2015 : 1.3 : cleanups and fixes * 25 Jun 2015 : 1.2 : remove DOpus port check, allow selection, support for space, removed BSort * 24 Jun 2015 : 1.1 : use spaces: incorrect but fast * 22 Jun 2015 : 1.0 : initial release */ Opus = Address() /* Get the DOpus address. */ Options RESULTS /* Request results. */ Address value Opus /* Use the DOpus address. */ Busy On Status 3 /* Get this window. */ ThisWindow = RESULT ThatWindow = ~ThisWindow /* That window is not this window. */ /* Get this window's selected items. */ TopText "Getting this window's items..." GetSelectedAll '*' ThisWindow /* Split entries by delimiter since we may have spaces. */ ThisItems = RESULT If ThisItems = 'RESULT' Then /* If no items in this window then bail. */ Do TopText "No items selected in this window!" Busy Off Exit End /* Normalize, heh... */ ThisItems = Upper(Translate(Translate(ThisItems, '/', ' '), ' ', '*')) /* Get all that window's items. */ TopText "Getting that window's items..." GetSelectedAll '*' ThatWindow /* Split entries by delimiter since we may have spaces. */ ThatItems = RESULT If ThatItems = 'RESULT' Then /* If no items in that window then bail. */ Do TopText "No items selected in that window!" Busy Off Exit End /* Normalize, heh... */ ThatItems = Upper(Translate(Translate(ThatItems, '/', ' '), ' ', '*')) /* Sort this items. */ TopText "Sorting this items... Please wait..." ThisItems = wasStringQuicksort(ThisItems, 'TopText "Sorting ["Pivot"]"') /* Sort that items. */ TopText "Sorting that items... Please wait..." ThatItems = wasStringQuicksort(ThatItems, 'TopText "Sorting ["Pivot"]"') /* Find the common entries between two windows. */ TopText "Intersecting..." Intersect = wasSortedSetsIntersect(ThisItems, ThatItems, 'TopText "Intersecting: ["AHead" - "BHead"]"') /* Deselect entries that are not part of the intersection. */ /* Get all the items first, then search the each item in */ /* the intersection set and deselect non-matching items. */ TopText "Selecting and deselecting..." GetAll '*' ThisWindow AllItems = RESULT /* Normalize, heh... */ AllItems = Translate(Translate(AllItems, '/', ' '), ' ', '*') /* Deselect items... */ TopText "Deselecting items... Please wait..." Count = Words(AllItems) Do i = 1 To Count ThisName = SubWord(AllItems, i, 1) ThisNameUp = Upper(ThisName) If Find(Intersect, ThisNameUp) = 0 Then Do If Find(ThisItems, ThisNameUp) ~= 0 Then Do ScrollToShow Translate(ThisName, ' ', '/') SelectEntry i - 1 ||' '|| 0 ||' '|| 1 End End End TopText "<(^.-)> There you go!" Busy Off Exit /*************************************************************************/ /* Copyright (C) 2015 Wizardry and Steamworks - License: GNU GPLv3 */ /*************************************************************************/ wasStringCompare: procedure /* Compares two strings lexicographically. */ Parse ARG One,Two Select When One = '' & Two ~= '' Then Return 1 When One ~= '' & Two = '' Then Return -1 When One = '' & Two = '' Then Return 0 Otherwise Nop End a = Upper(Left(One, 1)); b = Upper(Left(Two, 1)); If C2D(a) < C2D(b) Then Return 1 If C2D(a) > C2D(b) Then Return -1 a = Right(One, Length(One)-1) b = Right(Two, Length(Two)-1) Return wasStringCompare(a, b) /*************************************************************************/ /* Copyright (C) 2015 Wizardry and Steamworks - License: GNU GPLv3 */ /*************************************************************************/ wasSortedSetsIntersect: procedure /* Intersects two sorted sets. */ Parse ARG A,B,Lambda If A = '' | B = '' Then Return '' Parse VAR A AHead ' ' ATail Parse VAR B BHead ' ' BTail Interpret Lambda If AHead ~= BHead Then Do Compare = wasStringCompare(AHead, BHead) If Compare < 0 Then Return wasSortedSetsIntersect(A, BTail, Lambda) If Compare > 0 Then Return wasSortedSetsIntersect(ATail, B, Lambda) End Look = wasSortedSetsIntersect(ATail, BTail, Lambda) If Look ~= '' Then Return AHead||' '||Look Return AHead /*************************************************************************/ /* Copyright (C) 2015 Wizardry and Steamworks - License: GNU GPLv3 */ /*************************************************************************/ wasStringQuicksort: procedure /* Sorts strings separated by token. */ Parse ARG String,Lambda Count = Words(String) If Count <= 1 Then Return String Middle = Trunc(Count/2) Pivot = SubWord(String,Middle,1) String = DelWord(String,Middle,1) Count = Count - 1 Less = '' More = '' Do i = 1 To Count Word = SubWord(String,i,1) Compare = wasStringCompare(Word, Pivot) Select When Compare = 1 Then Select When Less ~= '' Then Less = Less||' '||Word Otherwise Less = Word End Otherwise Select When More ~= '' Then More = More||' '||Word Otherwise More = Word End End End Interpret Lambda Less = wasStringQuicksort(Less,Lambda) More = wasStringQuicksort(More,Lambda) If Less = '' & More ~= '' Then Return Pivot||' '||More If Less ~= '' & More = '' Then Return Less||' '||Pivot Return Less||' ' ||Pivot||' '||More