1 /** 2 * @fileoverview UAT documentPanel 3 * サーバ対応ドキュメントパネル機能 4 * 調整後はxUIに統合予定 5 * @aouther kiyo@nekomataya.info (ねこまたや) 6 * @version 0.9.1 20190221 7 */ 8 /* 9 ドキュメントパネル自体が、データリストを保持する構造にする 10 11 12 実際にデータを保持しているモジュールに対してリスト取得リクエストを出し、自分自身のデータリストを管理する 13 アプリケーション内の請求手続きは一種類にしてサービスエージェントを通してモジュール間の差異を吸収する 14 15 ローカルストレージを使用した参考リポジトリを設計実装する 16 (サービスモジュールのデフォルト値として登録する) 17 18 UI上のドキュメントパネルのオプションリストは、表示用のバッファとして利用(保持リスト本体ではない) 19 20 リストのソート タイトルソート・話数ソート・フィルタ等の補助機能を実装 21 カット番号リストは、ソートを基本 逆順表示 番号フィルタ を設計実装 22 23 ドキュメントエントリは、SCiオブジェクトにサービスへの参照を拡張して使用 24 25 26 serviceAgent.currentRepository 27 28 現在使用しているリポジトリのリスト 29 サービスにアクセスするごとに更新 30 サービスエージェント上のエントリへの参照 31 32 documentDepot.products 33 34 プロダクトコレクション サービスにアクセスするごとに抽出更新 35 各プロダクトは独立したデータとして一覧アクセスできるようにしておく 36 フィルタは、Depotのオブジェクトメソッドで実装 37 nas.Pm.Opus オブジェクトを使用 リポジトリへの参照を加える 38 opusが同じでもリポジトリが異なる場合は、同エントリ内で複数を保持 39 40 空プロダクトを作成する際は、リポジトリ内に対応する TITLE及びOPUSを同時に作成するようにトライする 41 対応するオブジェクトが存在しないエントリは処理に失敗する 42 43 カット(=ドキュメント)のエントリは空のままでも良いがOPUSを持たないタイトルはアプリの表示規則上許可されない 44 45 46 主にローカルリポジトリや、ホームリポジトリでの使用を前提とする? 47 48 49 documentDepot.documents 50 51 ドキュメントエントリーコレクション サービスにアクセスするごとに更新 52 ドキュメントエントリはカプセル化されたオブジェクトにする SCi互換 53 ListEntry オブジェクトのコレクションとして実装 54 55 currentProduct 現在ブラウザで選択中のプロダクト識別子 56 currentSelection 現在ブラウザで選択中のドキュメント識別子 57 currentDocument 現在編集対象のXps (xUI.XPS の相互参照) 58 currentReferenece 現在表示対象の参考Xps (xUI.referenceXPSの相互参照) 59 として扱う 60 */ 61 //エントリを格納するオブジェクト xUIを再初期化するのでこのコードが消える 62 //良くない 63 /** @class アプリケーション内でドキュメントエントリを格納するクラス 64 */ 65 documentDepot = { 66 products :[], 67 documents :[], 68 currentProduct:null, 69 currentSelection:null, 70 currentDocument:null, 71 currentReferenece:null 72 }; 73 /** 74 * ドキュメントブラウザの保持データを初期化 75 * 76 * ドキュメントセレクタのアップデートを行う<br /> 77 * タイトルリスト及びドキュメントコレクションをクリア後<br /> 78 * リポジトリのエントリリストを走査してコレクションを再構築してブラウザをアップデートする 79 * ** リポジトリ(エントリリスト)の更新は行わない 必要に従って事前に更新の要あり 80 * 81 * 逐次的に画面の再描画が可能なように変更する20170322 82 * 83 * 引数リストを受けて、現在のエントリと比較を行い逐次更新を行うように変更するか? 84 * ならば 事前に引数リスト組む必要あり 85 * または 参照するエントリリストの複製を持って差分のみの更新を行う? 複製が大変? 86 */ 87 documentDepot.documentsUpdate=function(){ 88 console.log('=+=============+++===== documentsUpdate ') 89 /* 既存データをクリアしない 90 引数で受け取ったデータ群は、新規のデータ構造を組んで従来のデータと照合しながら更新を行う 91 既存エントリ>新規データで置き換え 92 新規エントリ>新規データから追加 93 リムーブの機能が必要となるが、それをどうするか? 94 ○エントリそのものにリムーブメソッドを設ける 95 ○アップデートメソッドに第二引数を設けてリストを与えて処理する 96 97 大量のリストが与えられた場合に、逐次的に一定数で画面をリフレッシュする(リストを分割処理する)機能を作る? 98 エントリ全体の比較更新と、逐次リフレッシュを機能分割したほうが良さそう? 99 100 ただし全体のパフォーマンスをひどく下げているのは、ServiceAgent.getList の再帰呼び出しなのでこの処理は後回しでもOK 2017.04.19 101 102 */ 103 documentDepot.products = []; 104 documentDepot.getProducts(); 105 documentDepot.documents = serviceAgent.currentRepository.entryList;//カレントリポジトリのリストのみ 106 } 107 /** 108 * カレントのドキュメント情報からプロダクト識別子の配列を抽出して戻す 109 * @return {Array} 110 */ 111 documentDepot.getProducts=function(){ 112 var myProducts =[]; 113 //productsData を走査してプロダクトリストを作成する 114 for (var idx = 0 ; idx < serviceAgent.currentRepository.productsData.length ; idx ++){ 115 var myTitle = serviceAgent.currentRepository.productsData[idx].name; 116 if(serviceAgent.currentRepository.productsData[idx].episodes){ 117 for (var ide = 0 ; ide < serviceAgent.currentRepository.productsData[idx].episodes[0].length ; ide ++){ 118 var myOpus = serviceAgent.currentRepository.productsData[idx].episodes[0][ide].name; 119 var mySubtitle = serviceAgent.currentRepository.productsData[idx].episodes[0][ide].description; 120 var myIdentifier = 121 encodeURIComponent(myTitle)+ 122 "#" + encodeURIComponent(myOpus)+ 123 ((String(mySubtitle).length)?"["+mySubtitle+"]":"") 124 myProducts.push(myIdentifier); 125 } 126 } 127 } 128 documentDepot.products=myProducts 129 return myProducts; 130 } 131 132 /* OPUSセレクタを更新する 133 引数:エントリフィルタ用正規表現 134 戻値:フィルタリング済のリスト配列 135 更新後のセレクタ内に現在の被選択アイテムがある場合はそれを選択状態にする 136 ない場合は選択アイテムを空に 137 プロダクトリストは、都度生成に変更(スタティックには持たない) 138 */ 139 documentDepot.updateOpusSelector=function(myRegexp,rev){ 140 // if(! serviceAgent.currentRepository.opusList.updated){return;} 141 if(!(myRegexp instanceof RegExp)){ myRegexp = new RegExp(".+");} 142 if(!rev ) rev = false; 143 // ここで正規表現フィルタを引数にする 144 var myContents = ""; 145 // var myProducts = documentDepot.getProducts(); 146 var myProducts = documentDepot.products; 147 var myResult = []; 148 myContents += (myProducts.length)? 149 '<option value="==newTitle==" selected>(*-- no title selected --*)</option>': 150 '<option value="==newTitle==" selected>(*-- no titles --*)</option>'; 151 for( var opid = 0 ; opid < myProducts.length ; opid ++){ 152 var currentText = decodeURIComponent(myProducts[opid]); 153 var show = (currentText.match(myRegexp))? true:false; 154 if(rev) show = !show; 155 if(show){ 156 myContents += '<option'; 157 myContents += ' value="'; 158 myContents += myProducts[opid]; 159 if (documentDepot.currentProduct == myProducts[opid]){ 160 myContents += '" selected>'; 161 }else{ 162 myContents += '">'; 163 documentDepot.currentProduct = null; 164 } 165 myContents += currentText; 166 myContents += '</option>'; 167 myResult.push(myProducts[opid]); 168 } 169 } 170 if(document.getElementById( "opusSelect" ).innerHTML != myContents){ 171 document.getElementById( "opusSelect" ).innerHTML = myContents; 172 document.getElementById( "opusSelect" ).disabled = false; 173 } 174 return myResult; 175 } 176 /* Documentセレクタを更新 177 引数:エントリフィルタ用正規表現 178 戻値:フィルタリング済のリスト配列 179 被選択ドキュメントが更新後のセレクタ内に存在する場合は、それを選択状態にする 180 ない場合は選択アイテムを空にする 181 182 引数は正規表現よりも[開始番号,終了番号(表示個数?)]あたりにしたほうが何かと良いので順次変更 183 ドキュメントエントリは、ステータスを認識するように改修 184 Aborted ステータスのエントリは、制作管理モードでのみ表示 185 */ 186 documentDepot.updateDocumentSelector=function(myRegexp){ 187 // ここで正規表現フィルタを引数にする? 188 if(!(myRegexp instanceof RegExp)){ myRegexp = new RegExp(".+");} 189 // 選択済みタイトルで抽出 190 var myDocuments = documentDepot.getEntriesByOpusid(documentDepot.currentProduct); 191 // 正規表現フィルタで抽出してHTMLを組む 192 var myContents = ""; 193 var myResult = []; 194 myContents +=(myDocuments.length)? 195 '<option value="==newDocument==" selected>(*-- no document selected--*)</option>': 196 '<option value="==newDocument==" selected>(*-- no documents --*)</option>'; 197 for ( var dlid = 0 ; dlid < myDocuments.length ; dlid ++){ 198 //全ドキュメント走査 199 var currentText = decodeURIComponent(myDocuments[dlid].toString(0).split('//')[1]); 200 var currentData = myDocuments[dlid]; 201 //console.log(currentData.cut) 202 var currentStatus = currentData.getStatus(); 203 //console.log(currentData);console.log(currentStatus) 204 if( (currentData.dataInfo.currentStatus.content.indexOf('Aborted') < 0) && 205 (currentData.dataInfo.sci[0].cut.match(myRegexp))){ 206 myContents += '<option'; 207 208 myContents += ' class="docStatus docStatus-'; 209 myContents += currentStatus; 210 if((currentStatus=='Fixed')&&(currentStatus.assign)){ 211 myContents += "-2"; 212 } 213 myContents += '"'; 214 myContents += ' value="'; 215 myContents += myDocuments[dlid]; 216 if(this.currentSelection == myDocuments[dlid]){ 217 myContents += '" selected >'; 218 }else{ 219 myContents += '">'; 220 this.currentSelection = null; 221 }; 222 myContents += currentText; 223 myContents += ' ['+currentStatus.content; 224 myContents += ']</option>'; 225 myResult.push(myDocuments[dlid]); 226 } 227 } 228 if (document.getElementById( "cutList" ).innerHTML != myContents){ 229 document.getElementById( "cutList" ).innerHTML = myContents; 230 document.getElementById( "cutList" ).disabled = false; 231 } 232 return myResult;//抽出したリスト 233 } 234 235 /* 236 現在の全エントリから プロダクトIDが一致するエントリを抽出してカット順にソートして返す 237 引数:プロダクト識別子 238 */ 239 documentDepot.getEntriesByOpusid=function(myIdentifier){ 240 if(! myIdentifier) myIdentifier=documentDepot.currentProduct; 241 myIdentifier+="//"; 242 // タイトルIDで抽出 243 var myDocuments = []; 244 for ( var dcid = 0 ; dcid < documentDepot.documents.length ; dcid ++){ 245 //console.log(documentDepot.documents[dcid].toString());console.log(myIdentifier); 246 if((documentDepot.currentProduct)&&(Xps.compareIdentifier(documentDepot.documents[dcid].toString(),myIdentifier) > -1)){ 247 myDocuments.push(documentDepot.documents[dcid]); 248 } 249 continue; 250 } 251 myDocuments.sort(documentDepot.sortBySCi); 252 return myDocuments; 253 } 254 255 /** 256 listEntryのカット番号順にソートする 評価関数 257 */ 258 documentDepot.sortBySCi = function(val1,val2){return (nas.parseNumber(val1.sci)-nas.parseNumber(val2.sci))}; 259 /** 260 読み出して編集エリアに取り込む 261 識別子が指定されない場合は、セレクタの値を見る 262 ドキュメントリストに識別子が存在しない場合は、falseを返す 263 読み込み成功時はセレクタが開いていたら閉じる 264 */ 265 documentDepot.getEntry =function(myIdentifier){ 266 if(typeof myIdentifier == 'undefined'){ 267 myIdentifier = documentDepot.currentSelection; 268 } 269 for (var did = 0;did < documentDepot.documents.length ; did ++){ 270 if (documentDepot.documents[did].toString() == myIdentifier){ 271 documentDepot.documents[did].parent.getEntry(myIdentifier); 272 return true; 273 } 274 } 275 return false 276 } 277 /** 278 現在のテキスト入力状態から識別子をビルドする。 279 */ 280 documentDepot.buildIdentifier = function(addStatus){ 281 var result=""; 282 result += (document.getElementById('titleInput').value.match(/\(\*.*\*/)) ? "": 283 encodeURIComponent(document.getElementById('titleInput').value); 284 result += (document.getElementById('opusInput').value.match(/\(\*.*\*/)) ? "#": 285 '#'+encodeURIComponent(document.getElementById('opusInput').value); 286 result += (document.getElementById('subtitleInput').value.match(/\(\*.*\*/)) ? '': 287 '['+encodeURIComponent(document.getElementById('subtitleInput').value)+']'; 288 result += '//'; 289 var mySCi =Xps.parseSCi(((document.getElementById('cutInput').value.match(/\(\*.*\*\)/)) ? '': 290 document.getElementById('cutInput').value )+'('+document.getElementById('timeInput').value+')'); 291 if(dbg) console.log(mySCi); 292 var myNames = Xps.parseCutIF(mySCi[0].cut); 293 result += (myNames.length > 1) ? 's'+encodeURIComponent(myNames[1])+'-c':'s-c'; 294 result += (typeof myNames[0] == 'undefined')?"":encodeURIComponent(myNames[0]); 295 var timeSpc = parseInt(nas.FCT2Frm(String(mySCi[0].time))); 296 if(timeSpc > 0){ 297 result += '( '+String(timeSpc)+' )'; 298 } 299 if(addStatus){ 300 result +='//'; 301 result +=document.getElementById('issueSelector').value; 302 } 303 if(dbg) console.log("buildIdentifier::"); 304 if(dbg) console.log(mySCi[0].time); 305 if(dbg) console.log(decodeURIComponent(result)); 306 return result; 307 } 308 /** 309 ドキュメントリストを更新する 310 カレントリポジトリの内容を取得 311 得たリストをブラウザの保持リストとして更新する 312 先に存在するリストは破棄 313 この処理をカットのステータス変更の度に行うとレスポンスの低下が著しいので 314 要変更 315 当該のカットの状況のみをアップデートする手続が必要 316 実際は 317 LocalRepositoryの場合listEntryのアップデートのみでOK 318 NetworkRepositoryの場合はサーバのレスポンスからlistEntryをアップデートする 319 */ 320 documentDepot.rebuildList=function(force,callback){ 321 322 documentDepot.currentProduct =null; 323 documentDepot.currentSelection =null; 324 documentDepot.products =[]; 325 documentDepot.getProducts(); 326 documentDepot.documents = serviceAgent.currentRepository.entryList; 327 // documentDepot.currentDocument =null; 328 // documentDepot.currentReferenece =null; 329 /*=============*/ 330 if(typeof force == 'undefined') force = true; 331 // serviceAgent.currentRepository.getProducts(force,callback); 332 // serviceAgent.currentRepository.getList(force,callback); 333 // テスト中はこれで良いが、その後はあまり良くない 334 //console.log(this); 335 //console.log(callback); 336 // documentDepot.documentsUpdate(); 337 338 } 339 /** 340 読み出し・請求 341 明示的にリスト内のサーバにアクセスする場合は、その時点の最新リストを請求してリストを更新する 342 キャッシュを利用する場合は、リストの更新はなし。 343 344 書き込み・更新 345 データの保存は、 346 アプリケーション終了(ウインドウクローズ)時の自動バックアップ 347 明示的なバックアップへの退避(↑上と同じ領域) 348 349 保存先「リポジトリ」を指定して保存 350 上書き保存 351 「リポジトリ」の指定がない場合は、上書き保存 352 新規作成時 353 カレントリポジトリを使用 354 任意のリポジトリを指定するには保存前にカレントの変更が必要 355 356 リポジトリについて 357 リポジトリは、このシステム上「データ保存場所」に識別用の名前を付けて管理対象としたもの。 358 359 タイムシート・カット袋等の制作管理及びカット内容のメタデータ 及び将来的には、これらのデータに記載された制作データそのものを保存 360 ユーザのリクエストに従って読み書き可能なサービスとする。 361 362 リポジトリには、基本的に制作管理DBの機能はない。 363 制作管理DBの機能は、一般のRDBMサービスを立ち上げそこで利用するものとする。 364 基本的にリポジトリとは別の接続を使用する 365 366 簡易的なデータの解釈は、リポジトリから読み出したデータをアプリケーションがパースして行う。 367 簡易のパース結果を識別子としてリポジトリに送り、それをファイル名又はそれに類するメタ情報として保存して利用する 368 リポジトリにはデータの解釈(解析)を求めない。 369 370 1>必要なデータを保存時に識別子としてデータにつけてアプリケーション側から送信する 371 2>リポジトリサーバは、その識別子を利用して保存を行う 372 リスト要素を分解するか否かはサーバ側の事情で使い分けて良い 373 階層管理する場合は、要素ごとに分解してディレクトリを分ける等の処理を行うとデータの管理が容易になる 374 /(作品)/(話数)/(カット)/(ライン)/(ステージ)/(ジョブ)/(タイムシートデータ) 等のデータ配置にすると 375 バックアップやレストア等の処理に利便性あり 376 377 識別子の型式(埋め込み情報)は以下の様にする(仮仕様 2016/11/20) 378 379 title#opus[subtitle]//SsceneCcut(seconds+frames) / SsceneCcut(seconds+frames) / SsceneCcut(seconds+frames) //lineID//stageID//jobID// 380 381 例: 382 origData 383 かちかち山Max#おためし[サンプルカット] // S-C10(72) //0//0//0 384 encodeURIComponent 385 %E3%81%8B%E3%81%A1%E3%81%8B%E3%81%A1%E5%B1%B1Max#%E3%81%8A%E3%81%9F%E3%82%81%E3%81%97[%E3%82%B5%E3%83%B3%E3%83%97%E3%83%AB%E3%82%AB%E3%83%83%E3%83%88] // S-C10(72) //0//0//0 386 387 388 タイトル・カット番号・サブタイトル等のデータにはセパレータ等の予約文字列が含まれるケースがあるので識別子を作成前にURI置換を行う必要あり 389 置き換え又はエスケープの必要な文字列(使用禁止のセンも考慮) 390 \n 改行 - 使用禁止 391 / スラッシュ - \### 392 ##No. ナンバーサイン - 393 [ ] 角括弧 - 394 「 」 カギ括弧 - 395 "' 引用符 - 396 encodeURIComponent() を識別子組み立て前に通す 397 必要に従ってdecodeURIComponent() 398 399 上記の型式で(今回実装のローカルリポジトリではこの方法を採用する) 400 簡易パース手順 401 split("//") 402 5要素なら上書き可 403 6要素ならロック(fix)されて上書き不可 404 405 第一要素 プロダクト識別子 パース手順あり 406 第二要素 SCi識別子 407 split("/") 408 第一要素代表カット番号 第二要素以降は兼用番号 第一要素と同じ番号が入る場合があるがその場合は無視 409 各要素はカット番号とカット尺に分解して利用 カット尺は省略可能 410 第三要素 ラインID (Int 通番) 各要素にname要素を付加しても良い 0:本線//1:レイアウト//0:打合せ 等 411 第四要素 ステージID (Int 通番) 412 第五要素 ジョブID (Int 通番) 413 第六要素 ジョブステータス 値は文字列 Startup/Active/Hold/Fixed/Aborted いずれか 414 415 * 作業ステージを閉じる処理は、ユーザがアプリケーション側で行う 416 その際、識別子にフィックスのサインを付加する(第六要素'Fixed') 417 フィックスされたデータが上書きされることはない データの請求は常に有効 418 将来的には、ステージ/ジョブを内部に備えたXps,xMap 等が利用されるが、その際もこの識別子はそのまま使用可能 419 420 りまぴんで呼び出しの際は、基本的に既fixのデータはリファレンスに 未fixのデータは編集エリアに読み込む 421 422 第一要素をパースしてタイトル/OPUS情報を取得可能 423 第二要素を split("/") で兼用情報が得られる 第一要素が当該のカット番号 424 各カット情報は カット番号(カット尺) *durationではない transition情報もない(この通信では不用) 425 プロトコル上は(カッコ内)は補助情報とする 426 duration,transition等の情報を追加することも可能? 427 428 以上の機能をアプリケーション側で処理することで、RDBMのない状態で通常のストレージをリポジトリとして使用可能になる 429 とくにローカルファイルシステムを使う際は 430 URIエンコードを施しファイル名規則に抵触するのを避ける 431 長いファイル名を利用できる環境を使用すること 432 識別子は分解してディレクトリをわけて保存するか、又はエスケープしてスラッシュがファイル名に含まれるの避ける 433 434 リポジトリに要求される機能は、 435 1.アプリケーションからの請求に従って、保存しているデータの識別子リストを送り返す 436 2.アプリケーションから送信された(識別子付き)データを受信して、 437 同じ識別子のエントリがあれば上書きする 438 エントリがない場合は新規に保存エントリを作成する 439 3.アプリケーションからの請求に従って、指定された識別子の保存データを送信する 440 441 1. list(filter) 442 あまりエントリ数が多いと待ち時間が増すので、フィルタ機能はあったほうが良い 443 (アプリケーション側でもフィルタするので無くても良い) 444 2. write(identifier) 445 識別子のエントリがない場合は、新規エントリを登録 446 3. read(identifier) 447 識別子のエントリがない場合は。操作失敗のレスポンスを返す 448 449 * webStorage には一般的なリスト機能はないが 全キーを取得してリストを構築することは可能 450 リストオブジェクトをJSONパースしてストレージに一括で納める? 451 ただし、ブラウザ全体で5MB程度ととして、シートエディタのみでこれを専有するわけにもいかないので基本的にはドキュメントエントリ数を限って扱う。 452 試験的には複数エントリが扱えるように組む(ローカルファイルやDropBox/GoogleDrive等のネットストレージに対応するため) 453 454 455 */ 456 /** 457 入力されたタイトルを評価してセレクタを切り替える 458 */ 459 function selectBrowser(){ 460 var myTitle = document.getElementById('titleInput').value; 461 var myOpus = document.getElementById('opusInput').value; 462 var mySubtitle = document.getElementById('subtitleInput').value; 463 var myCutNo = document.getElementById('cutInput').value; 464 var myTime = document.getElementById('timeInput').value; 465 /* 466 セレクタの中から該当するエントリを検索して 存在すればそのエントリを選択状態にする 467 手続きは、セレクタ側の各要素を分解して下位から順に評価 468 明確に異なる値があった時点でエントリをリジェクト 469 すべてリジェクトされた場合フリーエントリを選択状態にする 470 サブタイトル・カット秒数は特に評価しない 471 */ 472 473 } 474 /** 475 タイトルを選択して入力エリア/カットセレクタを更新 476 productNameは以下の型式で分解する 477 (タイトル)[##№](番号)[(サブタイトル)] 478 479 ももたろう#12 [キジ参戦!ももたろう地獄模様!!] 480 源氏物語 #23帖 [初音] 481 482 タイトルと話数はナンバーサイン[##№]で区切る 483 サブタイトルが存在する場合は、[]角括弧,「」カギ括弧,""引用符で区切って記入する 484 */ 485 function setProduct(productName){ 486 console.log('setProduct####') 487 console.log(productName); 488 489 //ドキュメント(カット)ブラウザの表示をリセット(クリア) 490 document.getElementById('cutList').innerHTML = "<option selected>(*-- no document --*)"; 491 documentDepot.updateDocumentSelector(); 492 // selectSCi(); 493 //ブラウザの選択を解除 494 documentDepot.currentSelection=null; 495 document.getElementById( "cutList" ).disabled=true; 496 497 if(typeof productName == "undefined"){ 498 //プロダクト名が引数で与えられない場合はセレクタの値をとる 499 //選択されたアイテムがない場合は、デフォルト値を使用してフリー要素を選択する 500 if ( document.getElementById("opusSelect").selectedIndex >= 0 ){ 501 productName = ( document.getElementById("opusSelect").selectedIndex == 0 )? 502 "#[]": 503 document.getElementById("opusSelect").options[document.getElementById("opusSelect").selectedIndex].text; 504 }else{ 505 document.getElementById("opusSelect").selectedIndex = 0; 506 productName = "#[]"; 507 } 508 }else{ 509 console.log("changeSelector") 510 //プロダクト名が与えられた場合は、セレクタの選択を更新する 511 // document.getElementById('opusSelect').value=productName; 512 for(var pix=0;pix<documentDepot.products.length;pix++){ 513 if(Xps.compareIdentifier(documentDepot.products[pix],productName)>=0){ 514 document.getElementById('opusSelect').value=documentDepot.products[pix];break; 515 } 516 } 517 } 518 productName=String(productName);//明示的にストリング変換する 519 var productInfo=Xps.parseProduct(productName); 520 var subTitle = productInfo.subtitle; 521 var opus = productInfo.opus; 522 var title = productInfo.title; 523 /** パネルテキスト更新 524 リストに存在しないプロダクトの場合は、リスト側で'(* new product *)'を選択する 525 */ 526 document.getElementById("titleInput").value = (title.length)? title:"(*--title--*)"; 527 document.getElementById("opusInput").value = (opus.length)? opus:"(*--opus--*)"; 528 document.getElementById("subtitleInput").value = (subTitle.length)? subTitle:"(*--subtitle--*)"; 529 // selectSCi(); 530 531 // タイトルからカットのリストを構築して右ペインのリストを更新 532 documentDepot.currentProduct=document.getElementById("opusSelect").options[document.getElementById("opusSelect").selectedIndex].value; 533 534 serviceAgent.currentRepository.getEpisodes(function(){ 535 // documentDepot.documentsUpdate(); 536 // documentDepot.updateOpusSelector(); 537 // 選択したプロダクトが存在すればカットを取得 538 console.log(decodeURIComponent(documentDepot.currentProduct)); 539 var currentOpus = serviceAgent.currentRepository.opus(documentDepot.currentProduct); 540 if(currentOpus){ 541 // console.log(currentOpus.token); 542 serviceAgent.currentRepository.getSCi(function(){ 543 // 更新したリストからリスト表示を更新 544 documentDepot.documentsUpdate(); 545 documentDepot.updateDocumentSelector(); 546 },false,currentOpus.token) 547 }else{ 548 console.log("no opus exists ###");console.log(currentOpus); 549 } 550 },false, 551 documentDepot.buildIdentifier(), 552 documentDepot.buildIdentifier() 553 ); 554 /* 555 // 選択したプロダクトが存在すればカットを取得 556 var currentOpus = serviceAgent.currentRepository.opus(documentDepot.currentProduct); 557 if(currentOpus){ 558 // console.log(currentOpus.token); 559 serviceAgent.currentRepository.getSCi(function(){ 560 // 更新したリストからリスト表示を更新 561 documentDepot.documentsUpdate(); 562 documentDepot.updateDocumentSelector(); 563 },false,currentOpus.token); 564 565 }else{ 566 //該当するプロダクトをコンソールへ 567 console.log(documentDepot.currentProduct); 568 } */ 569 //{ documentDepot.updateDocumentSelector(); } 570 /** パネルテキスト更新 571 リストに存在しないプロダクトの場合は、リスト側で'(* new product *)'を選択する 572 */ 573 // document.getElementById("titleInput").value = (title.length)? title:"(*--title--*)"; 574 // document.getElementById("opusInput").value = (opus.length)? opus:"(*--opus--*)"; 575 // document.getElementById("subtitleInput").value = (subTitle.length)? subTitle:"(*--subtitle--*)"; 576 selectSCi(); 577 } 578 //setProduct("源氏物語#二十三帖「初音」"); 579 /** 580 selectSCi 581 */ 582 function selectSCi(sciName){ 583 if(typeof sciName == "undefined"){ 584 //カット名が引数で与えられない場合はセレクタの値をとる 585 //セレクタ値の場合は、ドキュメントリストの対応するエントリを取得 586 //選択されたアイテムがない場合は、デフォルト値を使用してフリー要素を選択する 587 if ( document.getElementById("cutList").selectedIndex > 0 ){ 588 /* セレクタで選択したカットのissuesをドロップダウンリストで閲覧可能にする 589 デフォルト値は最終issue 590 */ 591 var myEntry = serviceAgent.currentRepository.entry(document.getElementById("cutList").options[document.getElementById("cutList").selectedIndex].value); 592 if(myEntry){ 593 var myContents=""; 594 for (var ix=0;ix<myEntry.issues.length;ix++){ 595 myContents += '<option value="'+myEntry.issues[ix].join('//')+'"'; 596 myContents += (ix==(myEntry.issues.length-1))? ' selected >':' >'; 597 myContents += decodeURIComponent(decodeURIComponent(myEntry.issues[ix].join('//')))+"</option>"; 598 } 599 document.getElementById("issueSelector").innerHTML=myContents; 600 if(xUI.uiMode!='management') document.getElementById("issueSelector").disabled=false; 601 602 sciName = document.getElementById("cutList").options[document.getElementById("cutList").selectedIndex].text; 603 }else{console.log(myEntry)} 604 }else{ 605 document.getElementById("issueSelector").innerHTML='<option value="" selected>#:---line//#:---stage//#:---job//(status)</option>'; 606 document.getElementById("issueSelector").disabled=true; 607 document.getElementById("cutList").selectedIndex = 0; 608 sciName = "(*--c#--*)"; 609 var myEntry = null; 610 } 611 } 612 sciName=String(sciName);//明示的にストリング変換する 613 if(sciName.length <= 0){return false;} 614 var sciArray=sciName.split( "/" );//セパレータ"/"で兼用カットを分離 615 //代表カット番号 はsciArray[0] 616 617 if(sciArray[0].match(/^\s*(.+)\s*\(([^\)]+)\)\s*$/)){ 618 var cutNumber = RegExp.$1; 619 var cutTime = parseInt(nas.FCT2Frm(RegExp.$2)); 620 }else{ 621 var cutNumber = sciArray[0]; 622 var cutTime = 6*nas.FRATE;//6秒分フレーム 623 } 624 625 // 状態更新 626 // パネルテキスト更新 627 document.getElementById("cutInput").value = (cutNumber.length)? cutNumber:"(*--c#--*)"; 628 document.getElementById("timeInput").value = (cutTime)? nas.Frm2FCT(nas.FCT2Frm(cutTime),3):"6 + 00 ."; 629 //UIボタンの更新 630 var myInputText=["titleInput","opusInput","subtitleInput","cutInput","timeInput"]; 631 632 if (document.getElementById("cutList").selectedIndex <= 0){} 633 if (! myEntry){ 634 //選択されたドキュメントがリスト内に無い 635 document.getElementById("ddp-readout").disabled = true; 636 document.getElementById("ddp-reference").disabled = true; 637 if(xUI.uiMode=='management') 638 for ( var tidx = 0 ; tidx < myInputText.length ; tidx ++ ){ 639 document.getElementById(myInputText[tidx]).disabled = false; 640 } 641 documentDepot.currentSelection = documentDepot.buildIdentifier();//現在のテキスト入力状態から識別子をビルドする。 642 }else{ 643 //リポジトリ内に指定データが存在する 644 var currentStatus = myEntry.issues[myEntry.issues.length-1][3]; 645 646 document.getElementById("ddp-readout").disabled = ((xUI.onSite)&&(serviceAgent.currentStatus=='online-single'))? true:false;//シングルドキュメント拘束時読出抑制 647 document.getElementById("ddp-reference").disabled = false;//参照は無条件読出可能 648 for ( var tidx = 0 ; tidx < myInputText.length ; tidx ++ ){ 649 document.getElementById(myInputText[tidx]).disabled = true; 650 } 651 documentDepot.currentSelection = document.getElementById("cutList").options[document.getElementById("cutList").selectedIndex].value; 652 } 653 if((xUI.uiMode=='management')&&(!myEntry)){ 654 document.getElementById('ddp-addentry').disabled = false; 655 }else{ 656 document.getElementById('ddp-addentry').disabled = true; 657 } 658 if((myEntry)&&(serviceAgent.currentRepository===localRepository)){ 659 document.getElementById('ddp-removeentry').disabled = false; 660 }else{ 661 document.getElementById('ddp-removeentry').disabled = true; 662 } 663 664 } 665 666 667 /** 668 プロダクト名 カット番号ともに編集可能とそうでないケースをグラフィックで表示する機能が必要 669 選択のみで編集不能な場合、文字をグレーアウトさせるか? 670 最初からグレーアウトで編集キーを押したときのみ編集可能(=新規作成)とするか 要調整 671 */