cocoa-applescript: Determinate progress indicator - xcode

I am making an application using Cocoa-Applescript which identifies local IP addresses which are up and running, by pinging x.y.z.[1-255] and appends running IPs to a text file. I already have a GUI for choosing x, y and z and have already made the script to ping each address:
repeat 255 times
try
do shell script "ping -o -t 1 -c 1 " & ipstamp & num4
do shell script "echo " & ipstamp & num4 & " >>/Users/DJ/Desktop/GoodIPs.txt"
end try
set num4 to (num4 + 1)
end repeat
Where ipstamp is x.y.z and num4 is the [1-255]. But now I want a progress indicator to show where it is up to in the process. I know how to get an indeterminate indicator which simply starts and stops:
ProgressBar's startAnimation_(ProgressBar)
## code to ping IP address
ProgressBar's stopAnimation_(ProgressBar)
But that is only indeterminate and I can not find any info on setting determinate ones in Cocoa-Applescript, setting their maximum steps and setting their current step - much like in regular Applescript's:
set progress total steps to x
set progress completed steps to y
Except it is in the GUI, and so i need to use NSProgressIndicators to do it. So summed up, how do you make a determinate progress bar, how do you set its total steps and how do you update its current step?
EDIT
It can be changed to determinate in the menu builder's Attribute Inspector, as can max, min and current steps. However I do need to be able to change the maximum and current steps from within the script, so those still apply.

Well you can make a Determinate progress indercator but the problem is you have to repeat telling it to go to a certain lenght by using the
setDoubleValue_()
message, but anyway here is a simple script to tell it to go to go up to 100
property MyProgressBar : missing value -- Progress Bar IB Outlet
on applicationWillFinishLaunching_(aNotification)
set c to 0
repeat 100 times
set c to c + 1
delay 0.2
tell MyProgressBar to setDoubleValue_(c) -- Tells Progress bar the % to go to
if c > 99 then
exit repeat -- If current repeat is 100 or more then cancels adding more
end if
end repeat
end applicationWillFinishLaunching_
Hope this helped!

just do:
set progress total steps to -1
-- do something
set progress total steps to 0
Remember, that the visualization depends on how the script is executed.

Related

Simple AppleScript for AutoMator

I need a simple AppleScript for a game. Can anyone help and dedicate to me 1 minute to make it?
1) Press Esc
2) Press W key and hold it for 10 seconds
3) Press A key and hold it for 10 seconds
4) Press S key and hold it for 10 seconds
5) Press A key and hold it for 10second
Repeat this for unlimited time (BUT NOT STEP 1)
Thanks <3
"Simple" as your wish may be – AppleScript allows "key down > … > key up" events ONLY for modifier keys, so: NOT for "W", "A"….
You MIGHT (with little hope) try to do some repeat loops (with: keystroke "w") in your game, setting a variable myNow (previous to loop) to current time and repeat while current time is less than myNow plus 10 seconds.
[ Obviously, testing this in TextEdit, you'd write a massively long line of wwwwwwwwwwwww … aaaaaaaaaaaaaaaaaa … ssssssssssssssssssss … ]

Is this a problematic design for gdb non-stop mode automation?

I've implemented this code in my .gdbinit file to make stop-requiring gdb commands work(such as x, set etc)
define hook-x
if $pince_debugging_mode == 0
interrupt
end
end
define hook-stop
if $pince_debugging_mode == 0
c &
end
end
The purpose of $pince_debugging_mode variable is to inform gdb if the program is interrupting the target for debugging purposes or not.
I have a concern about signal concurrency with this design: Lets say we put a breakpoint on an address and while waiting it to get triggered we wanted to check some addresses with the x command. After x command gets executed, hook-stop will get executed because we have stopped the thread with the x command. And lets say breakpoint has been reached while hook-post is executing but hook-stop isn't aware of that and the $pince_debugging_mode still equals to 0 so it'll execute the c & command and the target will continue. So the stop at breakpoint won't mean anything because of this concurrency problem.
This problem never occurred yet but I'm afraid of the odds of occurring, even if it's very low, I don't want to take the risk. What can I do to avoid this possible problem?
Note: defining a hookpost-x is problematic because whenever x command throws an exception hookpost won't get executed, so it'll be impossible to continue after a exception-throwing x command

Splitting files into folders

Would someone please get me started with Automator and/or AppleScript. I've gotten more than a little frustrated with it. I'd like to take a very large folder of files (thousands), in a predetermined order (perhaps by name or by date) and move them into subfolders, each of which is no more than a specified size (probably 4.7GB). I don't want ISOs or DMGs or anything just my files nicely split into disk size chunks. No reshuffling of the order either. If a disk only fits a single 10MB file because the next one would blow the limit then so be it. No file will be bigger than the limit either in case your wondering - they will be up to about 50MB tops.
So far I've got a Folder Action with Get Selected Finder Items followed by this AppleScript
on run {input, parameters}
return first item of input
end run
That gets me the first item. I can create a folder e.g. Disk 1 too. And I can move the file also. But how can I work out whether to move to this folder or if it's time for a new folder to be created?
I'd like to do this in Automator if possible, but suspect I'll need a little AppleScript. I'm sure this problem has been solved already, so please just link me if you can. Thanks.
Heres a working AppleScript that will do this. It's imperfect but gets the job done.
It can be very slow with lots of files, I'm sure it can be improved though. High performance is not one of Applescript's strengths.
tell application "Finder"
set files_folder to folder POSIX file "/Users/MonkeyMan/Desktop/MyMessOfFiles"
set destination_folder to folder POSIX file "/Users/MonkeyMan/Desktop/SortedFiles"
set target_size to 250.0 -- size limit your after in MB.
set file_groupings to {} -- list we will store our stuff in
set current_files to {} -- list of the current files we are adding size
set total_files to the count of files in files_folder
set current_size_count to 0
repeat with i from 1 to total_files
set file_size to (the size of file i of files_folder) / 1024.0 / 1024.0 -- convert to MB to help prevent overrunning what the variable can hold
if ((current_size_count + file_size) ≥ target_size) then
-- this will overrun our size limit so store the current_files and reset the counters
set the end of file_groupings to current_files
set current_files to {}
set current_size_count to 0
end if
set current_size_count to current_size_count + file_size
set the end of current_files to (a reference to (file i of files_folder) as alias)
if (i = total_files) then
-- its the last file so add the current files disreagarding current size
copy current_files to the end of file_groupings
end if
end repeat
-- Copy the files into sub folders
set total_groups to the count of file_groupings
repeat with i from 1 to total_groups
set current_group to item i of file_groupings
set dest_folder to my ensureFolderExists(("disk " & i), destination_folder)
move current_group to dest_folder
end repeat
end tell
say "finished"
on ensureFolderExists(fold_name, host_folder)
tell application "Finder"
if not (exists folder fold_name of host_folder) then
return make new folder at host_folder with properties {name:fold_name}
else
return folder fold_name of host_folder
end if
end tell
end ensureFolderExists

Subroutine that stops script to prompt user to hit Enter only works correctly on the first call

I am trying my hand at vbscript and just running very basic code and I am guessing there is a simple solution that I cannot find. I am running this is CMD with cscript.
I have a subroutine named Pause that is suppose to stop the script and ask the user to hit Enter to continue.
sub Pause(strPause)
WScript.Echo (strPause)
Do While Not WScript.StdIn.AtEndOfLine
Input = WScript.StdIn.Read(1)
Loop
End sub
I am calling this subroutine in a simple loop that is printing out 1 to 10. It pauses correctly after the first call but after that it just prints out the rest with no pause. It still echos the Pause String so it seems to be hitting the Sub.
For i = 1 To 10
' Print i to the Output window.
Wscript.echo"loop index is " & i
' Wait for user to resume.
Pause("Press Enter to continue")
Next
Not sure if the Do While loop inside the sub is causing issues or if Input value needs to be cleared somehow? It seems to work a little better when the Do While loop is removed from the Sub, Pausing after every two numbers instead of just printing out everything. Yet I can still not get it to pause after each loop.
Notice the commented out Do Loop and the change to the Input = line. Looks like you don't need the loop, rather just read a line at a time.
Sub Pause(strPause)
WScript.Echo (strPause)
'Do While Not WScript.StdIn.AtEndOfLine
Input = WScript.StdIn.ReadLine
'Loop
End Sub

How can I increase the key repeat rate beyond the OS's limit?

I have a bad habit of using the cursor keys of my keyboard to navigate source code. It's something I've done for 15 years and this of course means that my navigating speed is limited by the speed of the keyboard. On both Vista and OS X (I dual boot a MacBook), I have my key repeat rate turned all the way up. But in Visual Studio, and other apps, the rate is still much slower than I would prefer.
How can I make the key repeat rate faster in Visual Studio and other text editors?
In Windows you can set this with a system call (SystemParametersInfo(SPI_SETFILTERKEYS,...)).
I wrote a utility for myself: keyrate <delay> <repeat>.
Github repository.
Full source in case that link goes away:
#include <windows.h>
#include <stdlib.h>
#include <stdio.h>
BOOL parseDword(const char* in, DWORD* out)
{
char* end;
long result = strtol(in, &end, 10);
BOOL success = (errno == 0 && end != in);
if (success)
{
*out = result;
}
return success;
}
int main(int argc, char* argv[])
{
FILTERKEYS keys = { sizeof(FILTERKEYS) };
if (argc == 1)
{
puts ("No parameters given: disabling.");
}
else if (argc != 3)
{
puts ("Usage: keyrate <delay ms> <repeat ms>\nCall with no parameters to disable.");
return 0;
}
else if (parseDword(argv[1], &keys.iDelayMSec)
&& parseDword(argv[2], &keys.iRepeatMSec))
{
printf("Setting keyrate: delay: %d, rate: %d\n", (int) keys.iDelayMSec, (int) keys.iRepeatMSec);
keys.dwFlags = FKF_FILTERKEYSON|FKF_AVAILABLE;
}
if (!SystemParametersInfo (SPI_SETFILTERKEYS, 0, (LPVOID) &keys, 0))
{
fprintf (stderr, "System call failed.\nUnable to set keyrate.");
}
return 0;
}
On Mac OS X, open the Global Preferences plist
open ~/Library/Preferences/.GlobalPreferences.plist
Then change the KeyRepeat field. Smaller numbers will speed up your cursor rate. The settings dialog will only set it to a minimum of 2, so if you go to 0 or 1, you'll get a faster cursor.
I had to reboot for this to take effect.
Many times I want to center a function in my window. Scrolling is the only way.
Also, Ctrl-left/right can still be slow in code where there are a lot of non-word characters.
I use keyboardking also. It has a couple of isssues for me though. One, it sometimes uses the default speed instead of the actual value I set. The other is sometimes it ignores the initial delay. I still find it very useful though. They said 4 years ago they would release the source in 6 months... :(
Ok, on the suggestion of someone that modified HCU\...\Keyboard Response, this works well for me.
[HKEY_CURRENT_USER\Control Panel\Accessibility\Keyboard Response]
"AutoRepeatDelay"="250"
"AutoRepeatRate"="13"
"BounceTime"="0"
"DelayBeforeAcceptance"="0"
"Flags"="59"
Windows standard AutoRepeat delay.
13 ms (77 char/sec) repeat rate.
flags turns on FilterKeys?
These values are read at login. Remember to log out and back in for this to take effect.
For Windows, open regedit.exe and navigate to HKEY_CURRENT_USER\Control Panel\Keyboard. Change KeyboardSpeed to your liking.
I'm using KeyboardKing on my PC. It's freeware and it can increase the repeat rate up to 200 which is quite enough. I recommend to set the process priority to High for even smoother moves and less "repeat locks" which happen sometime and are very annoying. With high priority, it works perfectly.
No one understands why we navigate by arrows. It's funny.
Visual Assist has an option to double your effective key movements in Visual Studio which I use all the time.
As mentioned by the hyperlogic, on Mac OS X, internally, there are two parameters dealing with the keyboard speed: KeyRepeat and InitialKeyRepeat. In the System Preferences they are mapped to the Key Repeat Rate and the Delay Until Repeat sliders. The slider ranges and the associated internal parameter values (in parenthesis) are show below. They seem to be multipliers of the 15 ms keyboard sampling interval.
Key Repeat Rate (KeyRepeat) Delay Until Repeat (InitialKeyRepeat)
|--------------------------------| |----------------------|-----------------|
slow (120) fast (2) off (30000) long (120) short (25)
0.5 char/s 33 char/s
Fortunately, these parameters can be set beyond the predefined limits directly in the ~/Library/Preferences/.GlobalPreferences.plist file. I found the following values most convenient for myself:
KeyRepeat = 1 --> 1/(1*15 ms) = 66.7 char/s
InitialKeyRepeat = 15 --> 15*15 ms = 225 ms
Note that in the latest Mac OS X revisions the sliders are named slightly differently.
I do like to work on the keyboard alone. Why? Because when you use the mouse you have to grab it. A time loss.
On the other hand sometimes it seems that every application has its own keyboard type-rates built in. Not to speak from BIOS-properties or OS-settings. So I gathered shortkeys which can be pretty fast (i.e. you are faster typing Ctrl + right(arrow)-right-right than keeping your finger on the right(arrow) key :).
Here are some keyboard shortcuts I find most valuable (it works on Windows; I am not sure about OS X):
ctrl-right: Go to the end of the previous/the next word (stated before)
ctrl-left: Go to the beginning of the previous/the word before (stated before)
ctrl-up: Go to the beginning of this paragraph
(or to the next paragraph over this)
ctrl-down: Go to the end of this paragraph
(or to the next paragraph after this)
ctrl-pos1: Go to the beginning of the file
ctrl-end: Go to the end of the file
All these may be combined with the shift-key, so that the text is selected while doing so. Now let's go for more weird stuff:
alt-esc: Get the actual application into the background
ctrl-esc: This is like pressing the "start-button" in Windows: You can
navigate with arrow keys or shortcuts to start programs from here
ctrl-l: While using Firefox this accesses the URL-entry-field to simply
type URLs (does not work on Stack Overflow :)
ctrl-tab,
ctrl-pageup
ctrl-pagedwn Navigate through tabs (even in your development environment)
So these are the most used shortcuts I need while programming.
For OS X, the kernel extension KeyRemap4MacBook will allow you to fine tune all sorts of keyboard parameters, among which the key repeat rate (I set mine to 15 ms, and it works nice).
I don't know how to accelerate beyond the limit, but I know how to skip further in a single press. My knowledge is only in Windows, as I have no Mac to do this in. Ctrl + Arrow skips a word, and depending on the editor it may just skip to the next section of whitespace. You can also use Ctrl + Shift + Arrow to select a word in any direction.
Seems that you can't do this easily on Windows 7.
When you press and hold the button, the speed is controlled by Windows registry key : HCU->Control Panel->Keyboard->Keyboard Delay.
By setting this param to 0 you get maximum repeat rate. The drama is that you can't go below 0 if the repeat speed is still slow for you. 0-delay means that repeat delay is 250ms. But, 250ms delay is still SLOW as hell. See this : http://technet.microsoft.com/en-us/library/cc978658.aspx
You still can go to Accesibility, but you should know that those options are to help disabled people to use their keyboard, not give help for fast-typing geeks. They WON'T help. Use Linux, they tell you.
I bieleve the solution for Windows lies in hardware control. Look for special drivers for your keyboards or try to tweak existing ones.
Although the question is several years old, I still come across the same issue from time to time in several different developer sites. So I thought I may contribute an alternative solution, which I use for my everyday-developer-work (since the Windows registry settings never worked for me).
The following is my small Autorepeat-Script (~ 125 lines), which can be run via AutoHotkey_L (the downside is, it only runs under Windows, at least Vista, 7, 8.1):
; ====================================================================
; DeveloperTools - Autorepeat Key Script
;
; This script provides a mechanism to do key-autorepeat way faster
; than the Windows OS would allow. There are some registry settings
; in Windows to tweak the key-repeat-rate, but according to widely
; spread user feedback, the registry-solution does not work on all
; systems.
;
; See the "Hotkeys" section below. Currently (Version 1.0), there
; are only the arrow keys mapped for faster autorepeat (including
; the control and shift modifiers). Feel free to add your own
; hotkeys.
;
; You need AutoHotkey (http://www.autohotkey.com) to run this script.
; Tested compatibility: AutoHotkey_L, Version v1.1.08.01
;
; (AutoHotkey Copyright © 2004 - 2013 Chris Mallet and
; others - not me!)
;
; #author Timo Rumland <timo.rumland ${at} gmail.com>, 2014-01-05
; #version 1.0
; #updated 2014-01-05
; #license The MIT License (MIT)
; (http://opensource.org/licenses/mit-license.php)
; ====================================================================
; ================
; Script Settings
; ================
#NoEnv
#SingleInstance force
SendMode Input
SetWorkingDir %A_ScriptDir%
; Instantiate the DeveloperTools defined below the hotkey definitions
developerTools := new DeveloperTools()
; ========
; Hotkeys
; ========
; -------------------
; AutoRepeat Hotkeys
; -------------------
~$UP::
~$DOWN::
~$LEFT::
~$RIGHT::
DeveloperTools.startAutorepeatKeyTimer( "" )
return
~$+UP::
~$+DOWN::
~$+LEFT::
~$+RIGHT::
DeveloperTools.startAutorepeatKeyTimer( "+" )
return
~$^UP::
~$^DOWN::
~$^LEFT::
~$^RIGHT::
DeveloperTools.startAutorepeatKeyTimer( "^" )
return
; -------------------------------------------------------
; Jump label used by the hotkeys above. This is how
; AutoHotkey provides "threads" or thread-like behavior.
; -------------------------------------------------------
DeveloperTools_AutoRepeatKey:
SetTimer , , Off
DeveloperTools.startAutorepeatKey()
return
; ========
; Classes
; ========
class DeveloperTools
{
; Configurable by user
autoRepeatDelayMs := 180
autoRepeatRateMs := 40
; Used internally by the script
repeatKey := ""
repeatSendString := ""
keyModifierBaseLength := 2
; -------------------------------------------------------------------------------
; Starts the autorepeat of the current captured hotkey (A_ThisHotKey). The given
; 'keyModifierString' is used for parsing the real key (without hotkey modifiers
; like "~" or "$").
; -------------------------------------------------------------------------------
startAutorepeatKeyTimer( keyModifierString )
{
keyModifierLength := this.keyModifierBaseLength + StrLen( keyModifierString )
this.repeatKey := SubStr( A_ThisHotkey, keyModifierLength + 1 )
this.repeatSendString := keyModifierString . "{" . this.repeatKey . "}"
SetTimer DeveloperTools_AutoRepeatKey, % this.autoRepeatDelayMs
}
; ---------------------------------------------------------------------
; Starts the loop which repeats the key, resulting in a much faster
; autorepeat rate than Windows provides. Internally used by the script
; ---------------------------------------------------------------------
startAutorepeatKey()
{
while ( GetKeyState( this.repeatKey, "P" ) )
{
Send % this.repeatSendString
Sleep this.autoRepeatRateMs
}
}
}
Save the code above in a text file (UTF-8), for example named "AutorepeatScript.ahk"
Install AutoHotkey_L
Double click on "AutorepeatScript.ahk" to enjoy much fast arrow-keys (or put the file into your autostart-folder)
(You can adjust the repeat delay and rate in the script, see '; Configurable by user').
Hope this helps!
On Mac, it's option-arrow to skip a word and ⌥+Shift+Arrow to select. ⌘+Arrow skips to the end or beginning of a line or the end or beginning of a document. There are also the page up, page down, home and end keys ;) Holding shift selects with those too.
Well, it might be obvious, but:
For horizontal navigation, Home (line start), End (line end), Ctrl-Left (word left), Ctrl-Right (word right) work in all editors I know
For vertical navigation, Page Up, Page Down, Ctrl-Home (text start), Ctrl-End (text end) do too
Also (on a side note), I would like to force my Backspace and Delete keys to non-repeat, so that the only way to delete (or replace) text would be to first mark it, then delete it (or type the replacement text).
Don't navigate character-by-character.
In Vim (see ViEmu for Visual Studio):
bw -- prev/next word
() -- prev/next sentence (full stop-delimited text)
{} -- prev/next paragraph (blank-line delimited sections of text)
/? -- move the cursor to the prev/next occurence the text found (w/ set incsearch)
Moreover, each of the movements takes a number as prefix that lets you specify how many times to repeat the command, e.g.:
20j -- jump 20 lines down
3} -- three paragraphs down
4w -- move 4 words forward
40G -- move to (absolute) line number 40
There are most likely equivalent ways to navigate through text in your editor. If not, you should consider switching to a better one.

Resources