Old 12-21-2018, 04:39 PM   #1
foxAsteria
Human being with feelings
 
foxAsteria's Avatar
 
Join Date: Dec 2009
Location: Oblivion
Posts: 10,272
Default "Deleted Stuff Info" Script Request

Hello clever scripters! I've got a little request...Sometimes I hit "delete" and nothing appears to happen, usually because the Window I want to delete something from is not in focus. So I focus the window and try again. Problem is, that I often have deleted something that I just couldn't see and only discover this later (or maybe not at all).

Request: It would give me peace of mind if any time something is deleted from the project, Reaper could display a text overlay with info on what was deleted. E.g. "7 items deleted" or "3 tracks deleted." Red text at 75% opacity for a couple seconds whenever something is deleted with the delete key would be ideal.

Thanks either way!
__________________
foxyyymusic

Last edited by foxAsteria; 12-22-2018 at 01:07 PM.
foxAsteria is offline   Reply With Quote
Old 12-21-2018, 04:59 PM   #2
karbomusic
Human being with feelings
 
karbomusic's Avatar
 
Join Date: May 2009
Posts: 29,269
Default

Probably not what you need but FWIW, I just open the undo history.
__________________
Music is what feelings sound like.
karbomusic is offline   Reply With Quote
Old 12-21-2018, 06:18 PM   #3
foxAsteria
Human being with feelings
 
foxAsteria's Avatar
 
Join Date: Dec 2009
Location: Oblivion
Posts: 10,272
Default

Yea, the last undo point shows in the menu bar, but I'm just looking for something more idiot-proof. More often than I can live with, whole tracks have gone missing from projects. I keep versions, so all is never lost, but still...
__________________
foxyyymusic
foxAsteria is offline   Reply With Quote
Old 12-22-2018, 02:12 AM   #4
X-Raym
Human being with feelings
 
X-Raym's Avatar
 
Join Date: Apr 2013
Location: France
Posts: 9,902
Default

ReaScript API isnt event based, we cant say 'if something is deleted then do that', we have to analyze all the items, points, tracks and compare their state every 33Hz (rate of background script approx), so thos would be extremly inefficient on CPU :S
All you can do is checking is the undo history of have the svript display the last ubdo history entry. It give less detail but good thing is that is leaves an entryv only if the action has been successful (at least the default remove function).

EDIT: I just see undos have State information... ! Not sure if it can get returned from ReaScript though.

using the Tooltip function would be the better way I think.
X-Raym is offline   Reply With Quote
Old 12-22-2018, 03:43 AM   #5
mpl
Human being with feelings
 
mpl's Avatar
 
Join Date: Oct 2013
Location: Moscow, Russia
Posts: 3,984
Default

Quote:
Originally Posted by X-Raym View Post
we have to analyze all the items, points, tracks and compare their state every 33Hz (rate of background script approx), so thos would be extremly inefficient on CPU :S
Not necessary. It could be only checking for changes of GetProjectStateChangeCount(proj), while keeping data in the script memory. Like this:

Code:
[defer loop start]
count = GetProjectStateChangeCount(proj)
if not last_count or last_count ~= count then
  read / calculate or show something
  as well as update internal data
end
last_count = count
[defer loop end]
There could be even easier script with logic like:
Code:
1) read / calculate current project data
2) delete stuff with native action
3) read / calculate data again and show difference

Last edited by mpl; 12-22-2018 at 06:51 AM.
mpl is offline   Reply With Quote
Old 12-22-2018, 06:00 AM   #6
X-Raym
Human being with feelings
 
X-Raym's Avatar
 
Join Date: Apr 2013
Location: France
Posts: 9,902
Default

@mpl
Indeed it only matters of how precise the report must be.
X-Raym is offline   Reply With Quote
Old 12-22-2018, 10:11 AM   #7
foxAsteria
Human being with feelings
 
foxAsteria's Avatar
 
Join Date: Dec 2009
Location: Oblivion
Posts: 10,272
Default

Hey guys! If you think this would be useful/possible/easy I think it would be cool. But if it's hard/resource intensive/likely-to-be-used-only-by-me, I've also been thinking of just having EventGhost play a little sound when I hit delete in Reaper. At least then it will give me a little alarm to check the undo points. That could get annoying af, but if you guys think this is worthwhile, perhaps it could be open to other uses. Maybe people could have some other uses for big text overlays for different situations.... Thanks for your consideration!
__________________
foxyyymusic
foxAsteria is offline   Reply With Quote
Old 12-22-2018, 10:32 AM   #8
nofish
Human being with feelings
 
nofish's Avatar
 
Join Date: Oct 2007
Location: home is where the heart is
Posts: 12,110
Default

Can we get undo history via script?
Then maybe just a matter of parsing current undo entry and check for 'delete', 'remove' etc. in it.

Just thinking out loud...
nofish is offline   Reply With Quote
Old 12-22-2018, 01:02 PM   #9
snooks
Banned
 
Join Date: Sep 2015
Posts: 1,650
Default

Good idea... here's a script that pops up a tooltip whenever the last entry in the undo history contains delete/remove:

Code:
-- countdown timer so we only execute every x calls to reaper.defer, to save CPU
local defer = {}
defer.EVERY_X_CALLS = 15
defer.timer = defer.EVERY_X_CALLS

local tooltip = {} 
tooltip.TIME = 4    -- (multiple of defer.EVERY_X_CALLS) - time tooltip is on screen
tooltip.x = 820     --\ 
tooltip.y = -2      -- tooltip position
tooltip.timer = -1

-- these are Lua patterns, so we're not limited to searching for keywords
local check_list = {
  "Delete", 
  "Remove"
}

--
local function hasCheckListWord(str)
  for _, entry in pairs(check_list) do
    if str:match(entry) then return true end
  end
  return false
end

--
local function main()
  defer.timer = defer.timer - 1
  if defer.timer == 0 then
    defer.timer = defer.EVERY_X_CALLS
    
    if tooltip.timer == 0 then
      -- remove tooltip by setting it to ""
      reaper.TrackCtl_SetToolTip("", tooltip.x, tooltip.y, false)
      tooltip.timer = -1
    elseif tooltip.timer > 0 then
      tooltip.timer = tooltip.timer - 1
    end

    local last_undo = reaper.Undo_CanUndo2(0)
    if last_undo ~= prev_last_undo and hasCheckListWord(last_undo) then
      reaper.TrackCtl_SetToolTip(
        "\n   " .. last_undo
        .. "   \n ", tooltip.x, tooltip.y, false
      )
      tooltip.timer = tooltip.TIME
    end
    prev_last_undo = last_undo
  end
  
  reaper.defer(main)
end

main()

Last edited by snooks; 12-22-2018 at 05:03 PM.
snooks is offline   Reply With Quote
Old 12-22-2018, 01:04 PM   #10
foxAsteria
Human being with feelings
 
foxAsteria's Avatar
 
Join Date: Dec 2009
Location: Oblivion
Posts: 10,272
Default

Quote:
Originally Posted by nofish View Post
Can we get undo history via script?
Then maybe just a matter of parsing current undo entry and check for 'delete', 'remove' etc. in it.

Just thinking out loud...
Well the undo history doesn't say how many of anything has been deleted does it? But if you can access undo list via script, a script to list its contents and filter them by text would be hella useful! Would make it worthwhile to save entire undo history with projects. Currently it's too much of a chore to find anything in there.
__________________
foxyyymusic
foxAsteria is offline   Reply With Quote
Old 12-22-2018, 01:06 PM   #11
foxAsteria
Human being with feelings
 
foxAsteria's Avatar
 
Join Date: Dec 2009
Location: Oblivion
Posts: 10,272
Default

Gosh you guys are the best! Thanks Snooks! Will test after work...
__________________
foxyyymusic
foxAsteria is offline   Reply With Quote
Old 12-22-2018, 01:17 PM   #12
amagalma
Human being with feelings
 
amagalma's Avatar
 
Join Date: Apr 2011
Posts: 3,458
Default

I personally never unintentionally delete something without noticing it... but... there are often times (when deleting or altering something) that I DO unintentionally delete something else which was not visible in the arrange and I had not noticed that it had been selected too.

I would love to have a native option to restrict edits to only what is visible in the arrange...
__________________
Most of my scripts can be found in ReaPack.
If you find them useful, a donation would be greatly appreciated! Thank you! :)
amagalma is offline   Reply With Quote
Old 12-22-2018, 01:55 PM   #13
foxAsteria
Human being with feelings
 
foxAsteria's Avatar
 
Join Date: Dec 2009
Location: Oblivion
Posts: 10,272
Default

Quote:
Originally Posted by amagalma View Post
I would love to have a native option to restrict edits to only what is visible in the arrange...
To deal with this I requested long ago SWS actions for showing if any items offscreen are selected, and we have them now. Search "offscreen" in actions list if you want those. You can add them to a toolbar for visual indication or use them in a cycle action to make sure they are unselected.
__________________
foxyyymusic
foxAsteria is offline   Reply With Quote
Old 12-22-2018, 02:46 PM   #14
Edgemeal
Human being with feelings
 
Edgemeal's Avatar
 
Join Date: Apr 2016
Location: ASU`ogacihC
Posts: 3,921
Default

Quote:
Originally Posted by foxAsteria View Post
Well the undo history doesn't say how many of anything has been deleted does it? But if you can access undo list via script, a script to list its contents and filter them by text would be hella useful! Would make it worthwhile to save entire undo history with projects. Currently it's too much of a chore to find anything in there.
You could possibly do something like that using JS_ReaScriptAPI if you don't mind having to open the Undo history window,..

Code:
-- Undo History Keeper v0.06 --
-- Requires: js_ReaScriptAPI, https://forum.cockos.com/showthread.php?t=212174
-- Testing: x64, Win7, REAPER v5.965, js_ReaScriptAPI v0.962.

local app_name = "Undo History Keeper"

local history = reaper.JS_Window_Find("Undo History", true)
if history == nil then
  reaper.Main_OnCommand(40072, 0) -- View: Show undo history window
  history = reaper.JS_Window_Find("Undo History", true)
end

local LV = reaper.JS_Window_FindChildByID(history, 1106)
local count = reaper.JS_ListView_GetItemCount(LV)-1
if count < 0 then reaper.MB("No history found!", app_name, 0) return end

local ok, filter = reaper.GetUserInputs(app_name, 1, "Enter filter text or * for all items: ,extrawidth=20", "*")
if not ok then
  reaper.JS_WindowMessage_Post(history,"WM_CLOSE",0,0,0,0) -- close history window
  return
end

local items = {}

if filter  == "*" then
  for i = 0, count do
   items[i+1] = {text = reaper.JS_ListView_GetItemText(LV, i, 0), date = reaper.JS_ListView_GetItemText(LV, i, 1)}
  end
else -- filtered
  local index = 0
  for i = 0, count do
    local txt = reaper.JS_ListView_GetItemText(LV, i, 0)
    if string.match(txt, filter) then
      index = index + 1 
      items[index] = {text = txt, date = reaper.JS_ListView_GetItemText(LV, i, 1)} 
    end
  end
end

local output = ""
for i = 1, #items do
  output = output  ..  items[i].text .. " - " .. items[i].date .. '\r\n'
end
  
reaper.CF_SetClipboard(output)  -- copy text to clipboard
reaper.JS_WindowMessage_Post(history,"WM_CLOSE",0,0,0,0) -- close history window
Filter = "FX" (case sensitive) , example output...
Close FX chain: Track 1 - 12/22/2018 3:15:09 PM
Add FX: Track 1: Smooth Limiter - 12/22/2018 3:15:07 PM

Last edited by Edgemeal; 12-22-2018 at 03:48 PM. Reason: v0.06 one more minor tweak
Edgemeal is offline   Reply With Quote
Old 12-22-2018, 03:34 PM   #15
amagalma
Human being with feelings
 
amagalma's Avatar
 
Join Date: Apr 2011
Posts: 3,458
Default

Quote:
Originally Posted by foxAsteria View Post
To deal with this I requested long ago SWS actions for showing if any items offscreen are selected, and we have them now. Search "offscreen" in actions list if you want those. You can add them to a toolbar for visual indication or use them in a cycle action to make sure they are unselected.

You are kidding!! :O:O:O THANK YOU!!!


I wonder what other gems are hidden in the Action List!..
__________________
Most of my scripts can be found in ReaPack.
If you find them useful, a donation would be greatly appreciated! Thank you! :)
amagalma is offline   Reply With Quote
Old 12-22-2018, 05:05 PM   #16
snooks
Banned
 
Join Date: Sep 2015
Posts: 1,650
Default

Quote:
Originally Posted by foxAsteria View Post
Gosh you guys are the best! Thanks Snooks! Will test after work...
No worries, I've updated it so that it only runs every X times to save CPU. Adjust to taste, I find every 15 calls to reaper.defer to be not too laggy.
snooks is offline   Reply With Quote
Old 12-23-2018, 03:48 AM   #17
foxAsteria
Human being with feelings
 
foxAsteria's Avatar
 
Join Date: Dec 2009
Location: Oblivion
Posts: 10,272
Default

Quote:
Originally Posted by snooks View Post
No worries, I've updated it so that it only runs every X times to save CPU. Adjust to taste, I find every 15 calls to reaper.defer to be not too laggy.
But does it have to run always to capture it? Can't it not just trigger when the delete key is pressed?

Quote:
Originally Posted by amagalma View Post
I wonder what other gems are hidden in the Action List!..
oh man... it's endless
__________________
foxyyymusic
foxAsteria is offline   Reply With Quote
Old 12-23-2018, 05:59 AM   #18
snooks
Banned
 
Join Date: Sep 2015
Posts: 1,650
Default

You can make it automatically always run if you use "SWS/S&M Set global startup action" or put it in your __startup.lua file, getting the Command ID from the Action List and doing something like this...
Code:
local cmdID = "_RSa5aef07fbf7180b536c8ff98495424f2e8ecbda6"
reaper.Main_OnCommand(reaper.NamedCommandLookup(cmdID), -1)
It could also be changed and just be triggered by the Delete key, with the script executing whatever action you have it set to. It smells to me like it would be better always monitoring to catch all deletions (the list can be updated for other 'deletey' script undo strings). But that's just me.
snooks is offline   Reply With Quote
Old 12-23-2018, 12:34 PM   #19
foxAsteria
Human being with feelings
 
foxAsteria's Avatar
 
Join Date: Dec 2009
Location: Oblivion
Posts: 10,272
Default

Yes you may be right. It could be that I'm getting deletions happening in some other way, which this would then catch...I also realize now that I'm deleting things with several different actions.

I don't mind running it at startup if it's not eating much cpu. I'm gonna test it out here shortly. Thanks again!
__________________
foxyyymusic
foxAsteria is offline   Reply With Quote
Old 12-23-2018, 01:44 PM   #20
foxAsteria
Human being with feelings
 
foxAsteria's Avatar
 
Join Date: Dec 2009
Location: Oblivion
Posts: 10,272
Default

Holy crap, you guys rock! I just noticed you already whipped up both my ideas! Thanks so much snooks and edgemeal!

@snooks seems the delete info is dependent on the preference to show tooltips for UI elements, which I normally turn off since they tend to get in my way. Is this an inflexible dependency?

@Edgemeal I get this error with the history filter:
Undo History Search Filter.lua:13: attempt to call a nil value (field 'JS_Window_FindChildByID') and if possible, could it be a toggle to open and close from the same shortcut? Also, here is my original FR for this, so I'll add the code there and mark the wish as "fulfilled." https://forum.cockos.com/showthread.php?t=154056
__________________
foxyyymusic
foxAsteria is offline   Reply With Quote
Old 12-23-2018, 02:50 PM   #21
Edgemeal
Human being with feelings
 
Edgemeal's Avatar
 
Join Date: Apr 2016
Location: ASU`ogacihC
Posts: 3,921
Default

Quote:
Originally Posted by foxAsteria View Post
@Edgemeal I get this error with the history filter:
I only tested it on Win7. Are you on Mac? If you're not on Windows then maybe the Undo History window is a little different and has a different Control ID for the listview? I don't have a Mac so no way to test that here.
Edgemeal is offline   Reply With Quote
Old 12-23-2018, 03:34 PM   #22
snooks
Banned
 
Join Date: Sep 2015
Posts: 1,650
Default

Quote:
Originally Posted by foxAsteria View Post
@snooks seems the delete info is dependent on the preference to show tooltips for UI elements, which I normally turn off since they tend to get in my way. Is this an inflexible dependency?
Oh yeah, I didn't think of that. An alternative is showing a window temporarily, but it steals focus for the time it's popped up where nothing else has been clicked...
Code:
-- countdown timer so we only execute every x calls to reaper.defer, to save CPU
local defer = {}
defer.EVERY_X_CALLS = 15
defer.timer = defer.EVERY_X_CALLS

local tooltip = {} 
tooltip.TIME = 4    -- (multiple of defer.EVERY_X_CALLS) - time tooltip is on screen
tooltip.x = 820     --\ 
tooltip.y = -2      -- tooltip position
tooltip.timer = -1

-- these are Lua patterns, so we're not limited to searching for keywords
local check_list = {
  "Delete", 
  "Remove"
}

--
local function hasCheckListWord(str)
  for _, entry in pairs(check_list) do
    if str:match(entry) then return true end
  end
  return false
end

--
local function showMessage(message)
  gfx.init("Deletion warning", 300, 50, false, 700, 10)
  gfx.setfont(1, "Arial", 22, 0)
  gfx.x, gfx.y = 25, 9
  gfx.printf(message)
end

--
local function hideMessage()
  gfx.quit()
end

--
local function main()
  defer.timer = defer.timer - 1
  if defer.timer == 0 then
    defer.timer = defer.EVERY_X_CALLS
    
    if tooltip.timer == 0 then
      tooltip.timer = -1
      hideMessage()
    elseif tooltip.timer > 0 then
      tooltip.timer = tooltip.timer - 1
    end

    local last_undo = reaper.Undo_CanUndo2(0)
    if last_undo ~= prev_last_undo and hasCheckListWord(last_undo) then
      showMessage(last_undo)
      tooltip.timer = tooltip.TIME
    end
    prev_last_undo = last_undo
  end
  
  reaper.defer(main)
end

main()
snooks is offline   Reply With Quote
Old 12-23-2018, 04:12 PM   #23
foxAsteria
Human being with feelings
 
foxAsteria's Avatar
 
Join Date: Dec 2009
Location: Oblivion
Posts: 10,272
Default

Quote:
Originally Posted by snooks View Post
Oh yeah, I didn't think of that. An alternative is showing a window temporarily, but it steals focus for the time it's popped up where nothing else has been clicked...
That shouldn't be a problem...I'll check it out, thanks!

Quote:
Originally Posted by Edgemeal View Post
I only tested it on Win7. Are you on Mac?
I'm also on Win7. I'll try it again.
__________________
foxyyymusic
foxAsteria is offline   Reply With Quote
Old 12-23-2018, 04:22 PM   #24
nofish
Human being with feelings
 
nofish's Avatar
 
Join Date: Oct 2007
Location: home is where the heart is
Posts: 12,110
Default

Quote:
Originally Posted by foxAsteria View Post
I get this error with the history filter: Undo History Search Filter.lua:13: attempt to call a nil value (field 'JS_Window_FindChildByID')
JS_Window_FindChildByID was added just recently
https://forum.cockos.com/showpost.ph...&postcount=163

so maybe you're running an older version of the JS extension?
nofish is offline   Reply With Quote
Old 12-23-2018, 04:55 PM   #25
foxAsteria
Human being with feelings
 
foxAsteria's Avatar
 
Join Date: Dec 2009
Location: Oblivion
Posts: 10,272
Default

Quote:
Originally Posted by nofish View Post
so maybe you're running an older version of the JS extension?
Yep! I updated ReaPack and now the error is gone. I'm not sure how it works though? Hitting enter or ok in the filter just closes both windows.
__________________
foxyyymusic
foxAsteria is offline   Reply With Quote
Old 12-23-2018, 05:07 PM   #26
Edgemeal
Human being with feelings
 
Edgemeal's Avatar
 
Join Date: Apr 2016
Location: ASU`ogacihC
Posts: 3,921
Default

Quote:
Originally Posted by foxAsteria View Post
Yep! I updated ReaPack and now the error is gone. I'm not sure how it works though? Hitting enter or ok in the filter just closes both windows.
Right, the text should be in the clipboard, so do a Paste in notepad or something. Default filter = '*' which means All Text.

And to toogle a window, one way is to start by Finding it by its partial or full titlebar text, so for 'undo history' it should be,..

Code:
-- get handle to the window with exact matching text.
local history = reaper.JS_Window_Find("Undo History", true)
if history == nil then -- if window not found then open it using a reaper action.
  reaper.Main_OnCommand(40072, 0) -- View: Show undo history window
else -- window is open, so lets close it using a js_ReaScriptAPI function.
  reaper.JS_WindowMessage_Post(history,"WM_CLOSE",0,0,0,0) -- close undo history window
end
Note, you don't have to use js_ReaScriptAPI to close the undo history window, you could call the same reaper action thats opens it, seems many of reaper's view actions are actually toggles.

Last edited by Edgemeal; 12-23-2018 at 05:45 PM. Reason: NOTE
Edgemeal is offline   Reply With Quote
Reply

Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


All times are GMT -7. The time now is 04:31 PM.


Powered by vBulletin® Version 3.8.11
Copyright ©2000 - 2024, vBulletin Solutions Inc.