ダイアログの再表示

[9076]ダイアログの再表示 投稿者:kuw 投稿日:2016/12/12 10:45:21
InDesignCC以降で困っています。

InDesignダイアログのScriptで以下の物が上手く処理されません。

(function(){
//ダイアログ
var myDialog = app.dialogs.add({name:"タイトル"});
var dlgColumn = myDialog.dialogColumns.add();
dlgColumn.dialogRows.add().staticTexts.add({staticLabel:"1行目"});

var result=myDialog.show();// ←ここは問題無し
alert(result);
dlgColumn.dialogRows.add().staticTexts.add({staticLabel:"2行目"});
var result=myDialog.show();// ←ここで待ってくれない
alert(result);
dlgColumn.dialogRows.add().staticTexts.add({staticLabel:"3行目"});
var result=myDialog.show();
alert(result);
})();

CS6迄は上手く動いていたのですが、
CC以降で上手く処理されなくなってしまいました。
(モーダルダイアログの内部処理が変わった?)

new Windowを使う事も検討したのですが、
修正箇所が多すぎて難しそうです。

お知恵を貸して下さい。お願いします。
[9077]Re: ダイアログの再表示 投稿者:LinkCube Ishio 投稿日:2016/12/12 23:27:25
var result=myDialog.show();// ←ここで待ってくれない
の箇所ですが、これはmyDialogオブジェクトが既に破棄されている状態だからだと思います。

ですので、コードは以下のようになります。(CC2017で確認しました)

CS6で動作して、CCで動作しなくなったのは、厳密になりメモリリークを発生させないためかもしれません。
逆にいえば、CS6ではメモリリークしているかもしれません。(作業に影響がでるほどではないと思いますが。。。)

(function(){
//ダイアログ
var myDialog1 = app.dialogs.add({name:"タイトル"});
var dlgColumn1 = myDialog1.dialogColumns.add();
dlgColumn1.dialogRows.add().staticTexts.add({staticLabel:"1行目"});
var result=myDialog1.show();
//この時点でmyDialog1やdlgColumn1は破棄された状態で、以後使用しないほうが良いと思います。
alert(result);

var myDialog2 = app.dialogs.add({name:"タイトル"});
var dlgColumn2 = myDialog2.dialogColumns.add();
dlgColumn2.dialogRows.add().staticTexts.add({staticLabel:"1行目"});
dlgColumn2.dialogRows.add().staticTexts.add({staticLabel:"2行目"});
var result=myDialog2.show();
alert(result);

var myDialog3 = app.dialogs.add({name:"タイトル"});
var dlgColumn3 = myDialog3.dialogColumns.add();
dlgColumn3.dialogRows.add().staticTexts.add({staticLabel:"1行目"});
dlgColumn3.dialogRows.add().staticTexts.add({staticLabel:"2行目"});
dlgColumn3.dialogRows.add().staticTexts.add({staticLabel:"3行目"});
var result=myDialog3.show();
alert(result);
})();
[9078]Re: ダイアログの再表示 投稿者:kuw 投稿日:2016/12/13 17:07:52
ありがとうございます!

//この時点でmyDialog1やdlgColumn1は破棄された状態で、以後使用しないほうが良いと思います。
調べてみたのですが、
show()の後でもidでのdialogオブジェクトの再取得やnameプロパティ等の参照が出来るので、
myDialogの参照オブジェクトその物は残っているみたいです。
show()の後は使用しない方が良いでしょうか?

すみません。もう少し具体的に書きます。
困っているのは、以下のようなダイアログ処理がもっと複雑になった物を
かなりの場所で大量に使用してしまっているのです。
(CS6迄であれば問題無く実行できます。CC以降で問題あり。)

(function(){
//ダイアログ
var myDialog = app.dialogs.add({name:"タイトル"});
var dlgColumn = myDialog.dialogColumns.add();
dlgColumn.dialogRows.add().staticTexts.add({staticLabel:"「ひらがな」を入力"});
var dlgRow1 = dlgColumn.dialogRows.add();
var dlgEdtBoxObj = dlgRow1.textEditboxes.add({editContents:"",minWidth:200});
var dlgRow2 = dlgColumn.dialogRows.add();
var dlgTxtMsg=dlgRow2.staticTexts.add({staticLabel:""});

while(1){
//ダイアログ表示
if(!myDialog.show()){
alert("キャンセル");
myDialog.destroy(); //ダイアログメモリ解放
return false;
}
if(!/[ぁ-ん].*/.test(dlgEdtBoxObj.editContents)){
alert("「ひらがな」を入力して下さい");
dlgTxtMsg.staticLabel="↑「ひらがな」が未入力です";
continue;
}
break;
}
alert("以下の文字が入力されました\n"+dlgEdtBoxObj.editContents);
myDialog.destroy(); //ダイアログメモリ解放
return true;

})();
exit();

別のダイアログを表示し、
そこでの操作内容を取得後元のダイアログに戻ってくるような事も
あちこちでしているので、頭を悩ましています。
できればソースの変更を最小限に抑えたいのです。

わがままな要求なのかもしれませんが、
何か良い方法は無いでしょうか?
[9082]Re: ダイアログの再表示 投稿者:LinkCube Ishio 投稿日:2016/12/14 18:10:13

>myDialogの参照オブジェクトその物は残っているみたいです。
>show()の後は使用しない方が良いでしょうか?

はい。使用しない方が良いと思います。
調査したところ、破棄というより破壊された?が正解かもしれません。(InDesignのバグかと)

>できればソースの変更を最小限に抑えたいのです。

お気持ちは大変よくわかります!ですが
最初にkuw様が記載されたnew Windowを使用するか、
dialogを使いまわししないように書き直すか、
ぐらいしか思いつかず、私の力不足で良い方法は見つかりませんでした。

app.scriptPreferences.versionを変更しても、InDesignはおかまいなしに、dialogを壊してきますし。。
[9083]Re: ダイアログの再表示 投稿者:kuw 投稿日:2016/12/15 17:03:10
LinkCube Ishio様
助かります。

> 調査したところ、破棄というより破壊された?が正解かもしれません。(InDesignのバグかと)
色々調べたのですが、オブジェクトが破壊?されているのを調査される際、
どのようにすれば状況を調べる事ができるのかが分かりませんでした。

今の自分の知識だとshow()でDialogのリユースが出来ない状況でしか、
オブジェクトが破壊されている事を識別する事ができません。
プロパティなども全て調べて見ましたが、
show()の前と後で違いを見つける事が出来ませんでした。

もし、よろしければ調査の方法をご教授頂けると助かります。
(確信はまったくないのですが挙動を見ていると、
2回目以降のshow()は内部でpaletteのような動き?非同期?っぽくなっているようにも感じます。
気のせいかもしれませんが…
もしくは、次のダイアログが出た際、
モーダルダイアログFormインスタンスの破棄が上手く行っていないとか…
的外れだったらゴメンナサイ。)


> app.scriptPreferences.versionを変更しても、InDesignはおかまいなしに、dialogを壊してきますし。。
ありがとうございます。
これ、自分も試しましたが駄目でした^^;
[9085]Re: ダイアログの再表示 投稿者:LinkCube Ishio 投稿日:2016/12/22 22:59:49
返信がとんでもなく遅くなりすみません!

>もし、よろしければ調査の方法をご教授頂けると助かります。

調査方法は、特になく挙動だけです。
ただInDesignは、JavaScriptを通してInDesignオブジェクトにアクセスしているだけで
JavaScriptからInDesignオブジェクトの状態が、完全に見えているわけではないと思います。
(JavaScriptオブジェクトからはわからない)

>(確信はまったくないのですが挙動を見ていると、
>2回目以降のshow()は内部でpaletteのような動き?非同期?っぽくなっているようにも感じます。
>気のせいかもしれませんが…
>もしくは、次のダイアログが出た際、
>モーダルダイアログFormインスタンスの破棄が上手く行っていないとか…
>的外れだったらゴメンナサイ。)

私も挙動が、非同期?っぽくなってるので、無理だろうなと思いながら
targetengine
を追加してみたりもしたのですが、駄目でした^^;
[9086]Re: ダイアログの再表示 投稿者:kuw 投稿日:2016/12/26 09:50:20
LinkCube Ishio様
色々と本当にありがとう御座います。

>ただInDesignは、JavaScriptを通してInDesignオブジェクトにアクセスしているだけで
>JavaScriptからInDesignオブジェクトの状態が、完全に見えているわけではないと思います。

そうなんですよねぇ…
toSource()とかしてもInDesign内のオブジェクトIDを階層参照しているだけみたいで、
JavaScriptからだと手が出せません。
(オブジェクトからJSONっぽいやつの取り出しができれば…と思ったのですが…)


なんとかオブジェクトの部分clone()を実装できないか、とか思いまして、
Mementoパターンクラス的なのを作ろうかと思ったのですが、
まず、Dialog内の各オブジェクトの追加された順序を拾う事ができない…
で、今現在手が上がりかけている所です。
(都度コードその物を全部キューに入といてeval()で処理させてオブジェクト生成
させるクラスとかも頭をよぎったのですが、実装を考えたら目眩がします。)
[9097]Re: ダイアログの再表示 投稿者:kuw 投稿日:2017/01/11 10:50:14
ご報告。

とりあえず解決しました。

dialogオブジェクトのcloneを作るReuseDialogと言う名前のクラスを作成しました。
裏側でdialog配下のオブジェクトの参照先をcloneと差し替える事で
既に記述されているコードの変更をできる限り少なくしました。
(あんまり良くないとLinkCube Ishio様にご指摘を受けていたのですが、
show()の後にプロパティの値を取得してcloneを作る形をとってしまいました。
とりあえず問題なく動いているっぽいのでこれで行きたいと今の所思っています。
ゴメンナサイ…)

dialog配下へオブジェクトを追加した順番がどうしても取得できない為、
dialog配下へオブジェクト追加時にはReuseDialogクラスへ登録する形をとりました。


dialogの再利用時の不具合について、
ネットの情報を色々調べてみたのですが、情報が無いです。
現状、困っている方があんまりいないのかなぁ…


作成したReuseDialogクラスのソースを公開しようと思ったのですが、
ちょっとソースが長くなってしまいました。
私がホームページやブログをやっていないので、
どなたか自分のホームページやブログに載せても良いよと言う方は、
教えて下さい。
ソースを評価して頂けると助かります。
[9098]Re: ダイアログの再表示 投稿者:あるふぁ 投稿日:2017/01/12 01:34:52
私はCCユーザーじゃないので話に入れないのですが
dialogObj.dialogColumns[0].widgets.everyItem().getElements()
で追加した順のオブジェクトが取得できませんか?
[9099]Re: ダイアログの再表示 投稿者:kuw 投稿日:2017/01/12 13:53:10
あるふぁ様

昔使った事があったのですが、
widgets完全に失念していました!
Dialog下階層を順に上から複製していけるので
上手くいけばかなり既存のコード変更量がスマートになるかもです!

ちょっと調べてみます。
感謝!
[9100]Re: ダイアログの再表示 投稿者:kuw 投稿日:2017/01/12 19:32:34
作った物を破棄して、
設計をクラスから関数に変更して作り直しました。

おそらく問題なく動きそうです。
ありがとう御座います。
[9109]Re: ダイアログの再表示 投稿者:LinkCube Ishio 投稿日:2017/01/16 00:09:33
解決したのですか!凄いです。
まさにGood Jobですね!
私はすっかりあきらめていました。。。
この記事の書き込み元へのリンク (コメントや質問などはこちらへどうぞ)