StrokesPlus Forum
                       
StrokesPlus Forum
Home | Profile | Register | Active Topics
Members | Search | FAQ
Username:
Password:
Save Password
Forgot your Password?

 All Forums
 Lua Scripts
 General Action Scripts
 Recent 15 copies list popup
 New Topic  Reply to Topic
 Printer Friendly
Author Previous Topic Topic Next Topic  

gopikrish2000

34 Posts

Posted - 11/07/2013 :  13:58:52  Show Profile  Reply with Quote
Below script will give a popup of recent 15 copies (configurable) which you have done through copy gestures (not ctrl +c , create new gesture for copy as below ) And upon clicking on item will send the text to the last focused window like notepad , browser input box etc. This is very useful for people who does multiple copies and want to paste one of the recent copy which is not the last one.

Following are the things you need to do to make it work .
1. First create a file "temp.txt" (without quotes) in the same folder as StrokesPlus.exe is there will all possible permissions ( read , write ... )
2. Create a copy gesture with code

acSendKeys("^c")
local recentCopyText = acGetClipboardText()
addClipItem(recentCopyText)


3. Create a Recent copies popup gestures with code

local res = renderCopyPopup()
local swnd = acFindWindow("STROKESPLUS",nil)
acActivateWindow(swnd)
acDelay(100)
acPostMessage(swnd, 0x0000, 0, 0) 
acDelay(100)
acCreatePopupMenu(gex,gey, res, ",","popupMenuForCopy")


4. Add following code to your Global lua tab of file

pattern = "||"
fileToBeStored = "temp.txt"
lines = {}
function file_exists(file)
  local f = io.open(file, "r")
  if f then f:close() end
  return f ~= nil
end

function lines_from(file)
  if not file_exists(file) then return {} end
  local matchCountAry = {}
  local fi = io.open("temp.txt","r")
  local completeStr = fi:read("*all")
  fi:close()
  
  for i in string.gmatch(completeStr, "([^"..pattern.."]+)") do
	matchCountAry[#matchCountAry + 1] = i
  end
	    --acMessageBox(matchCountAry[2])
  return matchCountAry
end

function addClipItem(item) 
  if string.len(item) <= 0 then 
    return
  end
  for k,v in pairs(lines) do
	if v == item then 
      return 
    end 
  end
 if #lines >= 15 then
   for index = 2,15 do
     lines[index] = lines[index-1] 
   end
   lines[15] = item
 else
	lines[#lines+1] = item  
 end

local writingStr = ""
for k,v in pairs(lines) do
 if string.len(v) > 0 then
  writingStr = writingStr..v..pattern
 end
end

local fi = io.open("temp.txt","w")
if string.len(writingStr) > 0 then
fi:write(writingStr)
end
fi:close()
end  -- end of clipItem method

function popupMenuForCopy(id) 
  acActivateWindow(acGetOwnerWindowByPoint(gsx, gsy))
  local itemVal = lines[id]

  if itemVal then
   local prevCopyVal = acGetClipboardText()
   acSetClipboardText(itemVal) 
   acSendKeys("{DELAY 100}^v")
   acSetClipboardText(prevCopyVal)
  end	
end

function renderCopyPopup()
  local result = ""
  for k,v in pairs(lines) do
    v = string.sub(v,0,20)
    result = result..v..","
  end 
  return result
end

function sp_init()
   lines = lines_from(fileToBeStored)
end


5. Note if sp_init() function is already be present in your global lua then add lines = lines_from(fileToBeStored) line to that , ie ( you shouldn't have two methods of sp_init())

6. If you copy big text , in popup i'm trimming to first 20 characters and showing otherwise popup willn't look good ( but on clicking will paste complete result)

7. If above thing is done correctly , then use copy gesture (of point 2 ) and do some copies then do recent copy gesture to show popup and upon clicking on item will send that text to last focused window like notepad,firefox search input etc. (acSendKeys(<item clicked text>) [ Also check the file text.txt , every time you copy using copy gesture the copied text should be appended there ]

Actually I didn't found a clipboard change event or listener kind of thing in lua other wise you can track the copies of ctrl+c as well

Edited by - gopikrish2000 on 11/09/2013 02:11:08

Rob

USA
2573 Posts

Posted - 11/07/2013 :  14:19:56  Show Profile  Visit Rob's Homepage  Reply with Quote
Nice work!

You are correct, the proper way of monitoring the Windows clipboard is via SetClipboardViewer which requires a window handle and that window to receive and process the WM_DRAWCLIPBOARD and WM_CHANGECBCHAIN messages (sent each time the clipboard contents or chain has changed).

I'd like to note that sp_init() is only executed in Lua state 1 as it was intended only to be executed once on load, but not for anything which affects data within Lua states; see here for details.

Although, 95% of the time, you'll be executing in Lua state 1 anyway, but I wanted to make sure I mentioned this fact.

You should be able to simply put the following line in Global Lua (not within sp_init() or any other function):
lines = lines_from(fileToBeStored)
This will execute within both Lua states; and since you're saving the file each time a clip is added, there's no harm in the code being executed again when you click OK on the S+ window or otherwise reload the Lua states. Though, I haven't tested it out.

Very handy script, though!
Go to Top of Page

gopikrish2000

34 Posts

Posted - 11/07/2013 :  14:34:04  Show Profile  Reply with Quote
I want to keep it in sp_init() because you should not unnecessarily do I/O operations unless very much required , also user's should not change the text in temp.txt directly ( if they do they have to reload/apply it , that's fine because they r tweaking) . So it shouldn't effect performance of all users who r using.

Only copy i'm putting it in file because i didn't find any sp_close() function which will be called once S+ closes , so OK i guess.

I still have problems in displaying the exact copied text because in acSendKeys() special characters we need to replace before insertion ( see convertItemAccordingToRules() ) , still some of the special characters after replacing also not working ( not sure why ) but general text copies shouldn't have problem.
Go to Top of Page

Rob

USA
2573 Posts

Posted - 11/08/2013 :  15:15:10  Show Profile  Visit Rob's Homepage  Reply with Quote
You could always call acSetClipboardText(value) then acSendKeys("^v") to avoid converting characters.
Go to Top of Page

gopikrish2000

34 Posts

Posted - 11/09/2013 :  01:58:31  Show Profile  Reply with Quote
Yes working like a charm , I didn't got this idea , Thanks . I'm modifying above script

Edited by - gopikrish2000 on 11/09/2013 02:04:28
Go to Top of Page

chandisciple

75 Posts

Posted - 03/22/2016 :  01:22:44  Show Profile  Reply with Quote
Another amazing code ! thanks GopiKrish.

I followed everything from the first post and did not make the changes suggested by ROB. Because i am not sure where to make the change. So i skipped ,
acSetClipboardText(value) then acSendKeys("^v") to avoid converting characters
lines = lines_from(fileToBeStored)


The script works fine until i select one from the pop up window, it does not take the focus to where i executed the paste gesture and so does not pate the selected line anywhere !

Can anyone help on this please ? Also , where would i add the lines suggested by ROB ?

Edited by - chandisciple on 03/22/2016 20:10:47
Go to Top of Page

chandisciple

75 Posts

Posted - 03/22/2016 :  20:11:13  Show Profile  Reply with Quote
Rob :May i please request your help here. :)
Go to Top of Page

Rob

USA
2573 Posts

Posted - 03/22/2016 :  22:27:37  Show Profile  Visit Rob's Homepage  Reply with Quote
Changed the line in red in this function:
function popupMenuForCopy(id) 
  acActivateWindow(acGetOwnerWindowByPoint(acGetMouseLocationX(), acGetMouseLocationY()))
  local itemVal = lines[id]

  if itemVal then
   local prevCopyVal = acGetClipboardText()
   acSetClipboardText(itemVal) 
   acSendKeys("{DELAY 100}^v")
   acSetClipboardText(prevCopyVal)
  end	
end
I haven't tested it out thoroughly, but it fixed it for me. The problem is that the original was referencing gsx and gsy, but those variables are not in scope within that function at that time. So this updates it to activate the window at the current mouse location.
Go to Top of Page

chandisciple

75 Posts

Posted - 03/23/2016 :  01:47:51  Show Profile  Reply with Quote
Cooooooool , i am modifying the script. it works but i see some extra clip board line. i will figure it out and update you .

But can you give a script to erase all in the pop up menu ? That I can trigger with another gesture to add new clip items ?
Go to Top of Page

Rob

USA
2573 Posts

Posted - 03/23/2016 :  10:10:34  Show Profile  Visit Rob's Homepage  Reply with Quote
Made these changes to address timing and getting rid of the blank menu item:
function popupMenuForCopy(id) 
  acActivateWindow(acGetOwnerWindowByPoint(acGetMouseLocationX(), acGetMouseLocationY()))
  acDelay(50)
  local itemVal = lines[id]

  if itemVal then
   local prevCopyVal = acGetClipboardText()
   acSetClipboardText(itemVal) 
   acSendKeys("{DELAY 100}^v")
   acSetClipboardText(prevCopyVal)
  end	
end

function renderCopyPopup()
  local result = ""
  local delim = ""
  for k,v in pairs(lines) do
    v = string.sub(v,0,20)
	result = result..delim..v
	delim = ","
  end 
  return result
end
You should be able to use something like this to erase the file:
local fi = io.open("temp.txt","w")
fi:write("")
fi:close()

lines = {}--clear the lines in the variable since S+ is running
That's about as much as I'm going to spend on this! :) Google is your friend, and definitely practice scripting using many of the websites out there. Remember that S+ uses Lua, so always include that in your search, like last night I searched for "Lua trim string" to find the script to trim the whitespace.

Best of luck!
Go to Top of Page

chandisciple

75 Posts

Posted - 03/24/2016 :  00:05:25  Show Profile  Reply with Quote
All the above script worked perfectly ROB.

Thanks and yes will start practicing more on lua !!! Thanks appreciate your effort :):):)
Go to Top of Page
  Previous Topic Topic Next Topic  
 New Topic  Reply to Topic
 Printer Friendly
Jump To:
StrokesPlus Forum © 2011-2018 Rob Yapchanyk Go To Top Of Page
Snitz Forums 2000