I create shortcuts in Shortcuts.app (macOS 12) to resizing/moving the current window by JavaScript.
The question is: there is a delay time (about 0.2~0.3 sec) after I press the keyboard shortcut to launch the scripts. It's quite annoying. How can I improve that?
I used Hammerspoon with Lua scripts to do the same jobs, and it responds very quickly/instantly without any delay.
Shortcuts implementation
Move current window to top left corner (using hotkey ⌘⇧⌥← & you can download this shortcut here):
function run(input, parameters) {
var frontAppName = Application("System Events").processes.whose({frontmost: {'=': true}})[0].name();
var frontApp = Application(frontAppName);
var topWindow = frontApp.windows[0];
var windowBounds = topWindow.bounds();
windowBounds.x = 0;
windowBounds.y = 0;
topWindow.bounds = windowBounds;
}
Move current window to top right corner (using hotkey ⌘⇧⌥→ & you can download this shortcut here):
function run(input, parameters) {
var frontAppName = Application("System Events").processes.whose({frontmost: {'=': true}})[0].name();
var frontApp = Application(frontAppName);
var topWindow = frontApp.windows[0];
var windowBounds = topWindow.bounds();
var desktopBounds = Application("Finder").desktop.window().bounds();
windowBounds.x = desktopBounds.width - windowBounds.width;
windowBounds.y = 0;
topWindow.bounds = windowBounds;
}
Related
I need to add a drawing sketch in Inventor and edit it. However, if another sketch is already being edited, my program terminates and even try/catch does not help. I can't find a property of the sketch showing if it is being edited or not. My main part of code is here:
// All of these three functions pass try/catch perfectly. Program never terminates
Inventor::Application^ App = (Inventor::Application^)Marshal::GetActiveObject("Inventor.Application");
DrawingDocument^ Doc = (DrawingDocument^)App->ActiveDocument;
Sheet^ Sh = Doc->ActiveSheet;
DrawingSketch^ Sk;
try
{
Sh->Sketches->Add();
Sk = Sh->Sketches[Sh->Sketches->Count];
Sk->Edit(); // Crushes the program completely if another sketch is being edited
}
catch (...)
{
return;
}
I tried to cycle through all the sketches and close them all. This behaves in a way I cannot understand.
try
{
// Note: in Inventor indexes definitely start from 1
for (int i = 1; i <= Sh->Sketches->Count; i++)
{
Sk = Sh->Sketches[i];
Sk->ExitEdit();
}
}
catch (...)
{
return;
}
For example, when the sketch 2 is open, the first cycle (i = 1) that tries to close the sketch 1, somehow closes the sketch 2. And the second iteration (i = 2) that now cannot close the sketch 2, as it is already closed, calls 'catch' and further 'return'.
I'm not familiar with C++, but here is VBA sample how to detect the drawing sketch is in edit mode
Dim oDrawing As DrawingDocument
Set oDrawing = ThisApplication.ActiveDocument
Dim oSheet As Sheet
Set oSheet = oDrawing.ActiveSheet
Dim editedObject As Variant
Set editedObject = ThisApplication.ActiveEditObject
If editedObject.Type = ObjectTypeEnum.kDrawingSketchObject Then
Dim activeEditSketch As DrawingSketch
Set activeEditSketch = editedObject
activeEditSketch.ExitEdit
End If
Dim oSketch As DrawingSketch
Set oSketch = oSheet.Sketches.Add()
I hope, you can convert this code to C++
First of all, I am continuing an old thread at this link that I am unable to comment on due to being a newbie.
I have a situation that an answer in that thread given by user Br. Sayan would really improve my Spreadsheet Google App Script. I am making calls to Google Url Shortener API, which puts quotas at 1 call per user per second. I have slowed my script down enough to accommodate this quota, but I then I run over the MAX_RUNNING_TIME for App Scripts execution due to the extended number of calls I need to make, so I need to break the loop when the execution time is exceeded and pick up where I left off.
Here is the code of his answer:
function runMe() {
var startTime= (new Date()).getTime();
//do some work here
var scriptProperties = PropertiesService.getScriptProperties();
var startRow= scriptProperties.getProperty('start_row');
for(var ii = startRow; ii <= size; ii++) {
var currTime = (new Date()).getTime();
if(currTime - startTime >= MAX_RUNNING_TIME) {
scriptProperties.setProperty("start_row", ii);
ScriptApp.newTrigger("runMe")
.timeBased()
.at(new Date(currTime+REASONABLE_TIME_TO_WAIT))
.create();
break;
} else {
doSomeWork();
}
}
//do some more work here
}
My Questions:
Is MAX_RUNNING_TIME a global variable with a value set by Apps Script that I can leave that reference as-is, or must I replace it with a value equalling the 6 minutes listed as the quota for run time on the Google API Console?
How can I place the bulk of my function within this script so that a loop that runs inside my function (say var i = 0; i < data.length; i++) will be synchronized with the loop in the portion given in the above code?
Clarification: when i is incremented up by 1, I need ii to increment by 1.
Does this happen automatically? Do I need one loop nested inside the other? Does the bulk of my function go in the first '//do some work here' or the second '//do some work here' or possibly even doSomeWork()?
#tehhowch agreed! However, HOW I need to adapt my code depends on where I need to put it in the above snippet.
Here is what I have so far:
'function short() {
var = startTime = (new Date()).getTime();
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheets()[0];
var run = 0;
var finc = 50;
var istart = run * finc;
var iLen = (run + 1) * finc;
var startRow = 2 + istart;
var endRow = startRow + finc;
var data = sheet.getSheetValues(startRow,2,endRow,1);
var shortUrl = new Array();
for (var i=istart; i < iLen; i++) {
Utilities.sleep(1100);
var url = UrlShortener.Url.insert({longUrl: data[i][0]});
shortUrl.push([url.id]);
Logger.log([url.id]);
}
var t = ss.setActiveSheet(ss.getSheets()[0]);
t.getRange(startRow,4,finc,data[0].length).clearContent();
t.getRange(startRow,4,finc,data[0].length).setValues(shortUrl);'
So if I update the code after each subsequent run to manually increase the variable 'run' by 1, and manually run the code again, this works.
I have also tried break it down into multiple functions by updating the i= and i < parts for each subsequent function, which also works, but requires much more manual work.
I have also tried, unsuccessfully, to use a prompt with a button press that continues the function, which would be better than the other attempts, but would still require a button press to resume the code after each run.
I want to automate the function as much as possible.
I've got a script that i run each day. it's incredibly slow and i can't figure out what's slowing it down. Anyone have any suggestions? I originally wrote a function to do one sheet, then i added a function to loop and call it on every sheet.
function addAllLog() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var allSheets = ss.getSheets();
// build array of all sheets
for (var i in allSheets) {
if (i == 0) { continue;} // skip first sheet
var tmpName = allSheets[i].getName();
if (tmpName == "Print Sheet") break; //stop at this tab
var tmpName = ss.getSheetByName(allSheets[i].getName());
ss.setActiveSheet(ss.getSheetByName(allSheets[i].getName()));
addLog();
}
}
function addLog () {
var sheet = SpreadsheetApp.getActiveSheet();
var numLastRow = sheet.getLastRow();
var numThisRow = numLastRow+1;
today = new Date();
today.setDate(today.getDate()-1);
today = Utilities.formatDate(today,"EDT","MM/DD/YYYY");
if (sheet.getMaxRows() == numLastRow) sheet.insertRowAfter(numLastRow);
var range = sheet.getRange(numLastRow,2,1,16); // last row, column b, 1 row of 16 columns
var data = range.getValues();
range.copyTo(sheet.getRange(numLastRow+1, 2,1,16)); //you will need to define the size of the copied data see getRange()
sheet.getRange(numThisRow, 1).setValue(today);
sheet.getRange(numThisRow, 4).setValue('Log');
sheet.getRange(numThisRow, 5).setValue(''); //erase copied value if there was anything there
sheet.getRange(numThisRow, 7).setValue(''); //erase copied value if there was anything there
sheet.getRange(numThisRow, 6).setValue('=GoogleFinance(C' + numThisRow + ',"price")');
sheet.getRange(numThisRow, 6).setValues(sheet.getRange(numThisRow,6).getValues());
}
Any suggestions on speeding it up would be greatly appreciated!
Each time you set a value in a range directly over the Spreadsheet, it takes at least 800ms to do it, so the best way to face this problem is create an Object[][] with the values and set it with sheet.getRange(range).setValues(Object[][]), being sure that Object[][] has the same width-height of the range.
In this post, Best Practices | Apps Script, Google explains the difference.
Also, an interesting solution is make an Spreadsheet abstraction in memory. I make my own MemsheetApp, based in this approach and it works very nice. I'm receiving pull request if you want to improve it.
This version doesn't require that you activate each sheet so it may take a little less time.
function addAllLog() {
var ss=SpreadsheetApp.getActive();
var allSheets = ss.getSheets();
for (var i=1;i<allSheets.length;i++){
var shtname = allSheets[i].getName();
if (shtname == "Print Sheet"){
break; //stop at this tab
}else{
addLog(shtname);
}
}
}
function addLog (shtname) {
var sheet = SpreadsheetApp.getSheetByName(shtname);
var numLastRow = sheet.getLastRow();
var numThisRow = numLastRow+1;
today = new Date();
today.setDate(today.getDate()-1);
today = Utilities.formatDate(today,"EDT","MM/DD/YYYY");
if (sheet.getMaxRows() == numLastRow) sheet.insertRowAfter(numLastRow);
var range = sheet.getRange(numLastRow,2,1,16);
range.copyTo(sheet.getRange(numLastRow+1, 2,1,16));
sheet.getRange(numThisRow, 1).setValue(today);
sheet.getRange(numThisRow, 4).setValue('Log');
sheet.getRange(numThisRow, 5).setValue('');
sheet.getRange(numThisRow, 7).setValue('');
sheet.getRange(numThisRow, 6).setFormula('=GoogleFinance(C' + numThisRow + ',"price")');
}
It appears to be Google's fault. Even SpreadsheetApp.getSheetByName() is bottlenecking the script by a minute or so, in my tests.
Im new Firefox addon programming.
I want set default file browse location with firefox addon sdk.
Thank you so much.
open scratchpad copy and paste this:
const nsIFilePicker = Components.interfaces.nsIFilePicker;
var fp = Components.classes["#mozilla.org/filepicker;1"]
.createInstance(nsIFilePicker);
var startDir = FileUtils.File('C:\\');
fp.displayDirectory = startDir;
fp.init(window, "Dialog Title", nsIFilePicker.modeOpen);
fp.appendFilters(nsIFilePicker.filterAll | nsIFilePicker.filterText);
var rv = fp.show();
if (rv == nsIFilePicker.returnOK || rv == nsIFilePicker.returnReplace) {
var file = fp.file;
// Get the path as string. Note that you usually won't
// need to work with the string paths.
var path = fp.file.path;
// work with returned nsILocalFile...
}
if thats what you want let me know, then ill put it in a default location
I am building an installer in VS2010 and want a script to run after uninstall (to remove license files). I have found JScript as a scripting language for Windows 7 and have implemented a simple script to delete a directory (which works fine):
var wshShell = WScript.CreateObject("WScript.Shell");
var result = wshShell.Popup("Remove license?", 0, "Remove license?", 4);
if (result == 6) {
var license_dir = wshShell.ExpandEnvironmentStrings("%ProgramData%");
license_dir += "\\<my product>";
var fso;
fso = new ActiveXObject("Scripting.FileSystemObject");
if (fso.FolderExists(license_dir)) {
fso.DeleteFolder(license_dir, true);
} else {
WScript.Echo(license_dir + " didn't exist. Nothing removed.");
}
}
My question is, is this a valid and (more importantly) portable way of doing this?