/* * $VER: DOpus4-Subtract 1.0 (04 Jul 2015) by Wizardry and Steamworks * * © 2015 Wizardry and Steamworks * * PROGRAMNAME: * DOpus4-Subtract * * FUNCTION: * Deselects all the selected entries in one window pane that can * also be found amongst the items selected in the other window pane. * * USAGE: * ARexx command DOpus4-Subtract.rexx (from DOpus) * * $HISTORY: * * 04 Jul 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"]"') /* Subtract that items from this items. */ TopText "Subtracting..." Subtract = wasSortedSetsSubtract(ThisItems, ThatItems, 'TopText "Subtracting: ["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(Subtract, 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 */ /*************************************************************************/ wasSortedSetsSubtract: procedure /* Subtract two sorted sets: A \ B */ Parse ARG A,B,Lambda If A = '' Then Return '' If B = '' Then Return A Parse VAR A AHead ' ' ATail Parse VAR B BHead ' ' BTail Interpret Lambda Compare = wasStringCompare(AHead, BHead) Select When Compare < 0 Then Return wasSortedSetsSubtract(A, BTail, Lambda) When Compare > 0 Then Return AHead' 'wasSortedSetsSubtract(ATail, B, Lambda) Otherwise Nop End Return wasSortedSetsSubtract(ATail, BTail, Lambda) /*************************************************************************/ /* 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