Скрипт Indesign работает дважды

Собираю скрипт для автоматизации создания разных версий отчета. Сценарий сначала импортирует XML-файл, а затем запускает некоторые другие функции для очистки проекта Indesign.

Когда я запускаю этот скрипт,

var myMenuAction = app.menuActions.item("Import XML...");
myMenuAction.invoke();

открывается диалоговое окно «Импорт XML», в котором мне предлагается выбрать XML-файл для импорта, и после того, как я нажимаю «Открыть», появляется окно «Параметры импорта XML». Все идет нормально. Но после того, как я нажму «ОК», снова появится окно «Импорт XML».

Это не очень критическая проблема, если я выберу нужный файл и параметры, которые мне нужны в первый раз, похоже, не имеет значения, выберу ли я их снова или просто нажму «отмена», поэтому скрипт все еще делает то, что я хочу, просто это не кажется очень аккуратным.

Итак, мой вопрос: что мне нужно сделать, чтобы получить только один раунд диалоговых окон импорта XML?


person PaulTong    schedule 10.04.2014    source источник
comment
Можете ли вы указать причины использования вызова меню вместо app.activeDocument.importXMl ? Кроме того, что делает этот вызов второго меню? (Догадываюсь, я бы сказал, что он также пытается импортировать.) Пожалуйста, покажите больше своего кода.   -  person Jongware    schedule 11.04.2014
comment
Jongware здесь? Вы в хороших руках. Этот парень — гуру расширенного сценария. Делай все, что он от тебя попросит.   -  person bgmCoder    schedule 11.04.2014
comment
Боюсь, я использовал Menu Invoke, потому что это было первое, что я попробовал, и оно сработало, и, будучи новичком в Extendscript, я был очень доволен собой и назвал его хорошим.   -  person PaulTong    schedule 12.04.2014
comment
Второй вызов меню, похоже, не делает ничего такого, чего еще не делал первый. Как я уже сказал, это на самом деле не влияет на полезность скрипта, это просто заставляет меня щелкать дополнительные диалоговые окна. Я не думаю, что остальная часть кода имеет какое-либо отношение к этой части, потому что, если я просто запущу код, как показано выше, независимо, я получу тот же результат.   -  person PaulTong    schedule 12.04.2014
comment
Я попытался использовать вызов меню с другими пунктами меню, и они не вели себя так же. Эта теория может только еще больше раскрыть мое невежество, но возможно ли, что из-за того, что в меню есть два экземпляра Import XML... (один в разделе «Файл», другой в раскрывающемся меню в окне «Структура»), оба вызываются?   -  person PaulTong    schedule 12.04.2014


Ответы (1)


Провозглашен Гуру или нет, меня это тоже смутило. Но вы правильно поняли со своим наблюдением!

... возможно ли, что из-за того, что в меню есть два экземпляра «Импорт XML ...» (один в разделе «Файл», другой в раскрывающемся меню в окне «Структура»), оба вызываются?

Это действительно правильно. xx.item(yy) извлекает один или несколько элементов из коллекции. Из блога Марка Отре:

Большой секрет в том, что ни один из вышеперечисленных методов фактически не возвращает какой-либо элемент. . . за исключением понимания «элемента» как спецификатора объекта.

Вы получаете ссылку на «несколько объектов», и да, есть два меню под названием «Импорт XML...». Довольно сложно убедить InDesign показать, что их два; myMenuAction.length не работает (это "один элемент", поэтому он не имеет длины), а myMenuAction.constructor.name показывает [Object MenuAction] -- опять же, для одного элемента. Однако alert (myMenuAction.name);, наконец, показывает (не)ожидаемый результат:

окно предупреждения с двумя меню

Потребовалось удивительно много обхода DOM, чтобы узнать, как вызывать только один. Я выбрал «Файл» -> «Импорт XML ...», и это то, что нужно:

var myMenu = app.menus.item("Main");
var fileMenu = myMenu.menuElements.item("File");
alert (fileMenu.menuItems.everyItem().name);
var myXmlMenu = fileMenu.menuItems.item("Import XML...");
alert (myXmlMenu.name);
myMenuAction = myXmlMenu.associatedMenuAction;
alert (myMenuAction.name);
myMenuAction.invoke();

Вы можете не включать оповещения, если хотите использовать это. Имейте в виду, что эти строки не в их локализуемых формах — этот пример будет работать только в InDesign на английском языке, но не при использовании другого языка интерфейса.

Лучший способ — по возможности избегать вызова меню. В этом случае вы, вероятно, можете безопасно заменить свой код следующим:

folder = Folder.myDocuments;
if (File.fs == "Windows")
    myFile = folder.openDlg( 'Load XML', "XML files,*.xml;All files:*.*", false);
else
    myFile = folder.openDlg( 'Load XML', function(file)
        {
            return file instanceof Folder ||
            (!(file.hidden) && file.name.match(/\.(xml)$/i));
        }, false );
}
if (myFile)
    xml = app.activeDocument.importXml(myFile);

Несколько преимуществ заключаются в том, что он не зависит от локали; вы можете настроить диалоговое окно «Открыть» так, чтобы оно запускалось в другой папке (например, в той, в которой сохранен ваш текущий документ) и использовать другие или несколько файловых фильтров; вы можете импортировать свой XML в текущий документ или прямо в существующий элемент (версия скрипта «Импортировать в выбранный элемент» в диалоговом окне «Импорт XML»); вы получаете ссылку на только что загруженный XML-объект, поэтому вы можете сразу после импорта обработать его.

person Jongware    schedule 19.04.2014
comment
Дальнейшее размышление над сообщением в блоге Марка: вы можете фактически использовать свою собственную строку, только слегка измененную: var myMenuAction = app.menuActions.item("Import XML...").getElements()[0]; Это приводит к преобразованию в фактический массив. Однако это усложняет работу ID. - person Jongware; 25.04.2014