How to close hidden InDesign documents? - error-handling

While scripting InDesign, I've had plenty of instances where I create a new document that's hidden until I execute all of the actions, and then I use myDocument.windows.add(); to get it to show. However, I've also had plenty of instances where I get an error before that last step, so the document doesn't materialize. The only way I've been able to get them to close out is to close out InDesign completely; though this works I figure there has to be a better way.
Is there a way, either in the IDE or by a script, to see what's open and/or close all hidden processes?
Cheers,
Brendan

Sure !
app.documents.everyItem().close(SaveOptions.NO); //will close any document visible or not without saving them ).
It's always a good idea to use a try catch statement in case you want to use invisible documents. So in case of errors, you can discard them.
function dealWithInvisibleDocs()
{
var doc;
try
{
doc = app.documents.add();
throw new Error ( "Booom" );
}
catch(e)
{
alert(e);
if ( doc.isValid )
{
doc.close ( SaveOptions.NO );
}
}
}
dealWithInvisibleDocs();
Loic

Related

Can't Print Specific Word Document Using VB.Net [duplicate]

I have a C# WinForm application that opens and fills out a MS Word dotx template by placing text at bookmarks, and then attempts to print it, all using MS Word Interop 15.
Everything seems to go fine, the print dialog shows and completes OK, the print job shows up in the print queue (i.e. the "See what's printing" window from "Devices and Printers" on MS Windows 10). But then the job immediately disappears from the queue before it can be spooled! (document appears very very briefly with "Spooling" status, and does not print - the printer never gets the job)
Here is my code (exception checking removed for brevity):
using Word = Microsoft.Office.Interop.Word;
private void Print_Click(object sender, EventArgs e)
{
// Open the MS Word application via Office Interop
Word.Application wordApp = new Word.Application();
Word.Document wordDoc;
// Open the template
wordDoc = wordApp.Documents.Add(Template: ContractTemplatePath, Visible: false);
// Ensure the opened document is the currently active one
wordDoc.Activate();
// Set the text for each bookmark from the corresponding data in the GUI
SetBookmarkText(wordDoc, "Foo", fooTextBox.Text);
// ... There's a whole bunch of these ... then:
// Instantiate and configure the PrintDialog
var pd = new PrintDialog()
{
UseEXDialog = true,
AllowSomePages = false,
AllowSelection = false,
AllowCurrentPage = false,
AllowPrintToFile = false
};
// Check the response from the PrintDialog
if (pd.ShowDialog(this) == DialogResult.OK)
{
// Print the document
wordApp.ActivePrinter = pd.PrinterSettings.PrinterName;
wordDoc.PrintOut(Copies: pd.PrinterSettings.Copies);
}
// Close the document without saving the changes (once the
// document is printed we don't need it anymore). Then close
// the MS Word application.
wordDoc.Close(SaveChanges: false);
wordApp.Quit(SaveChanges: false);
}
The only thing I can think of here is that maybe because I do away with the document as soon as I've sent it to the printer, then the job hasn't been completely sent so it removes itself or something. If this is the case then how can I determine how long I need to keep the document around for and what's the best way of waiting for that?
EDIT: Ive done another small bit of research (dont have time for more on this just at this moment) that suggests I may be able to use the PrintEnd event, but I couldn't immediately see if this would be applicable when using Interop. Would it be a method of achieving what I want without polling?
One solution is to poll the BackgroundPrintingStatus property of the Word application. It holds a count of the documents still waiting in the printing queue. While this count is greater than 0 there are still documents awaiting printing.
There are many ways you could achieve this. Here's a simple loop which blocks the UI:
// Send document to printing queue here...
while (wordApp.BackgroundPrintingStatus > 0)
{
// Thread.Sleep(500);
}
// Printing finished, continue with logic
Alternatively you may want to wrap it in a task so that you can do other things while waiting:
await Task.Run(async () => { while (wordApp.BackgroundPrintingStatus > 0)
{ await Task.Delay(500); } });

Splitting pages within a PDF with ArcoJS / Acrobat JS with a given array of names

So, I am super new to using the JS interface within Acrobat and I am trying to write something for splitting PDF pages easily to an array of file names. I cannot find a lot of snippets around that seems to show me how to work with Acrobat JS. Can you provide some guidance on how a script similar to such will look like and how I can execute it within Acrobat? Thanks!
First, you will need Acrobat Professional or Standard for JS tasks generally. And you will execute code like you do within your normal terminal/immediates window within what they call the debugger tool for Javascript. You will need to first activate JS within Acrobat by going to Preferences and activate the Debugger. After you set the preferences, restart Acrobat, and find the tools for the Javascript debugger (different places based on your version, google it if you can't find it).
Once you get the debugger running, run the code below after modifying for the file names you wish to use and the appropriate file paths. Then highlight the entire code block and hit Ctrl+Enter and it will automatically split the pages for you. Enjoy.
Split();
function Split() {
var totalPages = this.numPages;
var i;
var arrNames = [ "SOME ARRAY" ];
var targetPath = "/C/Users/...SOMEPATH/";
try {
for (i = 0; i < totalPages; i++) {
this.extractPages({
nStart: i,
cPath: targetPath +arrNames[i] + ".pdf"
});
console.println("Completed: " + targetPath + arrNames[i] + ".pdf");
}
} catch (e) {
console.println("Aborted: " + e);
}
}

How to check multiple PDF files for annotations/comments?

Problem: I routinely receive PDF reports and annotate (highlight etc.) some of them. I had the bad habit of saving the annotated PDFs together with the non-annotated PDFs. I now have hundreds of PDF files in the same folder, some annotated and some not. Is there a way to check every PDF file for annotations and copy only the annotated ones to a new folder?
Thanks a lot!
I'm on Win 7 64bit, I have Adobe Acrobat XI installed and I'm able to do some beginner coding in Python and Javascript
Please ignore the following suggestion, since the answers already solved the problem.
EDIT: Following Mr. Wyss' suggestion, I created the following code for Acrobat's Javascript console to be run only once at the beginning:
counter = 1;
// Open a new report
var rep = new Report();
rep.size = 1.2;
rep.color = color.blue;
rep.writeText("Files WITH Annotations");
Then this code should be applied to all PDFs:
this.syncAnnotScan();
annots = this.getAnnots();
path = this.path;
if (annots) {
rep.color = color.black;
rep.writeText(" ");
rep.writeText(counter.toString()+"- "+path);
rep.writeText(" ");
if (counter% 20 == 0) {
rep.breakPage();
}
counter++;
}
And, at last, one code to be run only once at the end:
//Now open the report
var docRep = rep.open("files_with_annots.pdf");
There are two problems with this solution:
1. The "Action Wizard" seems to always apply the same code afresh to each PDF (that means that the "counter" variable, for instance, is meaningless; it will always be = 1. But more importantly, var "rep" will be unassigned when the middle code is run on different PDFs).
2. How can I make the codes that should be run only once run only at the beginning or at the end, instead of running everytime for every single PDF (like it does by default)?
Thank you very much again for your help!
This would be possible using the Action Wizard to put together an action.
The function to determine whether there are annotations in the document would be done in Acrobat JavaScript. Roughly, the core function would look like this:
this.syncAnnotScan() ; // updates all annots
var myAnnots = this.getAnnots() ;
if (myAnnots != null) {
// do something if there are annots
} else {
// do something if there are no annots
}
And that should get you there.
I am not completely positive, but I think there is also a Preflight check which tells you whether there are annotations in the document. If so, you would create a Preflight droplet, which would sort out the annotated and not annotated documents.
Mr. Wyss is right, here's a step-by-step guide:
In Acrobat XI Pro, go to the 'Tools' panel on the right side
Click on the 'Action Wizard' tab (you must first make it visible, though)
Click on 'Create New Action...', choose 'More tools' > 'Execute Javascript' and add it to right-hand pane > click on 'Execute Javascript' > 'Specify Settings' (uncheck 'prompt user' if you want) > paste this code:
.
this.syncAnnotScan();
var annots = this.getAnnots();
var fname = this.documentFileName;
fname = fname.replace(",", ";");
var errormsg = "";
if (annots) {
try {
this.saveAs({
cPath: "/c/folder/"+fname,
bPromptToOverwrite: false //make this 'true' if you want to be prompted on overwrites
});
} catch(e) {
for (var i in e)
{errormsg+= (i + ": " + e[i]+ " / ");}
app.alert({
cMsg: "Error! Unable to save the file under this name ('"+fname+"'- possibly an unicode string?) See this: "+errormsg,
cTitle: "Damn you Acrobat"
});
}
;}
annots = 0;
Save and run it! All your annotated PDFs will be saved to 'c:\folder' (but only if this folder already exists!)
Be sure to enable first Javascript in 'Edit' > 'Preferences...' > 'Javascript' > 'Enable Acrobat Javascript'.
VERY IMPORTANT: Acrobat's JS has a bug that doesn't allow Docs to be saved with commas (",") in their names (e.g., "Meeting with suppliers, May 11th.pdf" - this will get an error). Therefore, I substitute in the code above all "," for ";".

issue with Xrm.Page.data.entity.save("saveandclose")

When i open an opportunity form and from there i have opened an opportunity product, but when i comes back to project and click on save and close it returns back me to opportunity product page (which i have opened last) instead of opportunity list page.
So, i have make custom function on save and close button and write code as following :
function SaveAndClose()
{
Xrm.Page.data.entity.save("saveandclose")
}
but issue remain same.
Please anyonve can you help me out on this?
I have fixed issue by following code:
function SaveAndClose()
{
Xrm.Page.data.entity.save();
if (parent.opener != undefined)
{
window.parent.close();
}
else
Xrm.Page.ui.close();
}
Hope this help !!!!

Chrome WebDriver hungs when currently selected frame closed

I am working on creation of automated test for some Web Application. This application is very complex. In fact it is text editor for specific content. As a part of functionality it has some pop-up frames. You may open this pop-up? make some changes and save them - closing current frame. May problem is in that fact, that close button situated inside frame will be eliminating. And this force Chrome WebDriver to hung. My first try was like this:
driver.findElement(By.xpath("//input[#id='insert']")).click();
driver.switchTo().defaultContent();
But it hungs on first line after executinh click command as this command close frame.
Then I change to this(I have JQuery on the page):
driver.executeScript("$(\"input#insert\").click()");
driver.switchTo().defaultContent();
But this leads to same result.
Then I use this solution:
driver.executeScript("setTimeout(function(){$(\"input#insert\").click()}, 10)");
driver.switchTo().defaultContent();
And it hungs on second line. Only this solution works:
driver.executeScript("setTimeout(function(){$(\"input#insert\").click()}, 100)");
driver.switchTo().defaultContent();
but only if you don't take into account, that it is unstable - some timing issue may occur.
So may question is there more cleaner and more stable way for switch out from closed frame?
P.S.: executeScript - self defined function to decrease amount of code. It simply executer some js on page.
Update:
I realized I was wrong. This problem is not for all iframes. It's occur when tinyMCE popup used. Situation is exactly like in this topic. So it's doubtful I will find answer here, but who knows. Solution described above will help, but only for very short amount of time, meaning that after several seconds pass chromedriver will hangs on next command.
This is how i would do it in Ruby, hopefully you can change it for java
$driver.find_element(:xpath, "//input[#id='insert']").click
$wait.until {$driver.window_handles.size < 2} #this will "explicitly wait" for the window to close
handles = $driver.window_handles #get available window handles
$driver.switch_to.window(handles[0]) #navigate to default in this case the First window handle
hope this helps
Problem was in this line of tinyMCEPopup code:
DOM.setAttrib(id + '_ifr', 'src', 'javascript:""'); // Prevent leak
Executing this script on page fix hang problem(but possibly creates leaks :) ):
(function() {
var domVar;
if (window.tinymce && window.tinymce.DOM) {
domVar = window.tinymce.DOM
}
else if (window.tinyMCE && window.tinyMCE.DOM) {
domVar = window.tinyMCE.DOM
}
else {
return;
}
var tempVar = domVar.setAttrib;console.log(123)
domVar.setAttrib = function(id, attr, val) {
if (attr == 'src' && typeof(val)== 'string' &&(val + "").trim().match(/javascript\s*:\s*("\s*"|'\s*')/)) {
console.log("Cool");
return;
}
else {
tempVar.apply(this, arguments);
}
}
}());
Bug and solution also described here
Note. Code above should be added to parent frame, not into popup frame.