// =========================================================================== // Copyright 2018 Autodesk, Inc. All rights reserved. // // Use of this software is subject to the terms of the Autodesk license // agreement provided at the time of installation or download, or which // otherwise accompanies this software in either electronic or hard copy form. // =========================================================================== // // Description: // create "File Path Editor" window. // // Main entry point: // filePathEditorWin() creates the filePathEditor for viewing all file paths. // ////////////////////////////////////////// // // Implementation Document // ///////////////////////////////////////// // The file path editor lists all file attributes in one treeView. // Several global arrays are used to store these item information, // includes: // $gFPEItemParentDir, $gFPEFileAttributes, $gFPEItemAttrType, // $gFPEFileNames, $gFPEItemResolveState, $gFPEItemSelectState, // $gFPEItemShowState. // All treeView item are created with integer ID. The item data // can be getten from global arrays according to the item ID. // When refresh the treeView, even some file items are removed, // their data in global arrays is not removed. For new file items, // new data are added. // These global arrays are cleared when close the file path editor or // new/open a Maya scene. ////////////////////////////////////////// // // Global Variables // ///////////////////////////////////////// global string $gFPEWindowName = "FilePathEditor"; global string $gFPETreeView; // The mode to list file nodes in treeView: // 0 - list by directory; // 1 - list by node type; // global int $gFPEListType; // Half of default selection color of treeview item. // If part of child items is selected, the parent item is highlit // with this color. // global float $gFPEHalfHighlitColor[]; // ID of parent directory treeView item. // There are four kind treeView items: // a) file attribute items. The array data always points to the item // ID of its directory. So when list mode is by file type, // the array data is not the parent item of the node item. // b) "Top" item. It is the first item and its ID is 0. // c) directory items. The array data always be 0 which point to // the "Top" item. // d) node type items. The array data always be 0 which point to // the "Top" item. // global int $gFPEItemParentDir[]; // For file entry, store the associated Maya node(full path) and // attribute; // For other entry, its value is empty string. // global string $gFPEFileAttributes[]; // Store the type for each file attribute entry. // For other entry, its value is empty string. // global string $gFPEItemAttrType[]; // Store a) file name for file entry; // b) directory for directory entry; // c) empty string for other entry ("Top" and attrType entry) // global string $gFPEFileNames[]; // Resolve state of items. // Three states: // a) 0 - the file is unresolved, or all files under this parent entry are unresolved; // b) 1 - the file is resolved, or all files under this parent entry are resolved; // c) 2 - this state is for directory or parent entry; part of // files under this entry are resolved and parts are // unresolved. // For hierarchy (directory and filetype) items, their resolve // state depends on its visible child items. Invisible child // items are not taken into account. But the state of "Top" item // is not changed with descendant item's visibility. // global int $gFPEItemResolveState[]; // Only used in selectionChangedCommand callback. // Record the item selection state temporarily. // global int $gFPEItemSelectState[]; // TreeView item IDs for attribute types. // If the treeView item has not been created, the value is empty string; // If the treeView item has been created, the value is the item id. // Even switch to list mode of by directory, the attrType items are // reversed. And when switch back to list by fileType, the IDs of attrType // item are reused. // global string $gFPETypeItems[]; // Record current registed attribute types. // User can register and deregister attribute type dynamically, // but the editor only update the types after reopen it. // And all sub-window, for example, the Auto-Resolve window will // keep align with the main editor to use this global array. // global string $gFPEAttrTypes[]; // The visibility of the treeView items. // Three states: // 0 - item is hidden according to the settings of "Show" menu; // 1 - item is shown; // -1 - item is removed after refresh. (The treeView item is not // really removed from UI, just hidden) // global int $gFPEItemShowState[]; ////////////////////////////////////////// // // Localized String Methods // ///////////////////////////////////////// proc string repathStr() { return (uiRes("m_filePathEditorWin.kRepath")); } proc string replaceStr() { return (uiRes("m_filePathEditorWin.kReplaceStr")); } proc string autoResolveStr() { return (uiRes("m_filePathEditorWin.kAutoResolve")); } proc string previewTitleStr() { return (uiRes("m_filePathEditorWin.kPreviewWin")); } proc string previewStr() { return (uiRes("m_filePathEditorWin.kPreview")); } proc string cancelStr() { return (uiRes("m_filePathEditorWin.kCancel")); } proc string browseStr() { return (uiRes("m_filePathEditorWin.kAutoResBrowser")); } proc string nodeStr() { return (uiRes("m_filePathEditorWin.kNode")); } proc string nodesStr() { return (uiRes("m_filePathEditorWin.kNodes")); } proc string pathStr() { return (uiRes("m_filePathEditorWin.kPath")); } proc string pathsStr() { return (uiRes("m_filePathEditorWin.kPaths")); } proc string toBeResolvedStr() { return (uiRes("m_filePathEditorWin.kToBeResolved")); } proc string remainUnresolvedStr() { return (uiRes("m_filePathEditorWin.kRemainingUnresolved")); } proc string repathingStr() { return (uiRes("m_filePathEditorWin.kRepathing")); } proc string resolvedMsgStr() { return (uiRes("m_filePathEditorWin.kResolvedMsg")); } proc string unresolvedMsgStr() { return (uiRes("m_filePathEditorWin.kUnresolvedMsg")); } ////////////////////////////////////////// // // Utility Methods // ///////////////////////////////////////// // get label for file item // proc string getItemLabel(int $index) { global string $gFPEFileAttributes[]; global string $gFPEFileNames[]; return $gFPEFileAttributes[$index] + " [" + $gFPEFileNames[$index] + "]"; } // get full file path (directory and file name) // proc string getFullname(int $item) { global string $gFPEFileNames[]; global int $gFPEItemParentDir[]; string $fullname = $gFPEFileNames[$item]; int $parentItem = $gFPEItemParentDir[$item]; return $gFPEFileNames[$parentItem] + "/" + $fullname; } // get file items under the specified directory item. // when list by file type, the directory treeView item is not // created, but the directory item data is still there. // proc int[] getFileItemsUnderDir(int $dirItem) { global int $gFPEItemParentDir[]; global int $gFPEItemShowState[]; int $fileItems[]; int $fileNum = 0; int $i; for ($i = 0; $i < size($gFPEItemParentDir); $i++) { if ($gFPEItemParentDir[$i] == $dirItem && $gFPEItemShowState[$i] != -1) { $fileItems[$fileNum] = $i; $fileNum++; } } return $fileItems; } // Get directory items in the treeView // proc int[] getDirectoryItems() { global int $gFPEItemParentDir[]; global string $gFPEFileNames[]; global int $gFPEItemShowState[]; int $dirItems[]; int $childNum = 0; int $i; for ($i = 0; $i < size($gFPEItemParentDir); $i++) { if ($gFPEItemParentDir[$i] == 0 && size($gFPEFileNames[$i]) > 0 && $gFPEItemShowState[$i] != -1) { $dirItems[$childNum] = $i; $childNum++; } } return $dirItems; } // Look for the treeView item which is // associated to the specified attribute. // proc int findTreeViewItemForAttr(string $file, string $attr, int $fileItems[]) { global string $gFPEFileNames[]; global string $gFPEFileAttributes[]; int $i; for ($i = 0; $i < size($fileItems); $i++) { if ($gFPEFileAttributes[$fileItems[$i]] == $attr && $gFPEFileNames[$fileItems[$i]] == $file) return $i; } return -1; } // Get all selected attribute items in treeView. // proc int[] getAllSelectedAttributeItems() { global string $gFPETreeView; global string $gFPEFileAttributes[]; global int $gFPEItemShowState[]; int $items[]; string $selectedItems[] = `treeView -q -selectItem $gFPETreeView`; int $j = 0; int $i; for ($i = 0; $i < size($selectedItems); $i++) { int $item = (int)$selectedItems[$i]; // only process file item, ignore hidden items if (size($gFPEFileAttributes[$item]) > 0 && $gFPEItemShowState[$item] == 1) { $items[$j] = $item; $j++; } } return $items; } // the attribute type info is generated on demand. // when generate treeView items, we do not get the attribute type. // So call this function to update it. // proc updateTypeForAttributes() { global string $gFPEFileAttributes[]; global string $gFPEItemAttrType[]; global int $gFPEItemShowState[]; int $i; // If refresh the path info, these item array maybe increase their size. // So the attribute type info may be built incrementally for ($i = size($gFPEItemAttrType); $i < size($gFPEFileAttributes); $i++) { if ($gFPEItemShowState[$i] != -1 && size($gFPEFileAttributes[$i]) > 0) { $gFPEItemAttrType[$i] = `filePathEditor -q -attributeType $gFPEFileAttributes[$i]`; } } } // clear treeView items and global data // proc clearDataAndTreeView() { global string $gFPETreeView; global int $gFPEItemResolveState[]; global int $gFPEItemParentDir[]; global string $gFPEFileAttributes[]; global string $gFPEFileNames[]; global int $gFPEItemSelectState[]; global string $gFPEItemAttrType[]; global string $gFPETypeItems[]; global int $gFPEItemShowState[]; if (`treeView -exists $gFPETreeView`) treeView -edit -removeAll $gFPETreeView; clear($gFPEItemResolveState); clear($gFPEItemParentDir); clear($gFPEFileAttributes); clear($gFPEFileNames); clear($gFPEItemSelectState); clear($gFPEItemAttrType); clear($gFPETypeItems); clear($gFPEItemShowState); // clear all file path information filePathEditor -refresh; } // Popup a dialog with warning message. // proc showWarningDialog(string $msg) { confirmDialog -title (uiRes("m_filePathEditorWin.kConfirm")) -icon "warning" -message $msg -button (uiRes("m_filePathEditorWin.kOk")) ; } // Set item image according file's resolve state // proc setResolveImage(string $item, int $resolveState) { global string $gFPETreeView; switch ($resolveState) { case 0: treeView -edit -image $item 1 fpe_brokenPaths.png $gFPETreeView; break; case 1: treeView -edit -image $item 1 fpe_okPaths.png $gFPETreeView; break; case 2: treeView -edit -image $item 1 fpe_someBrokenPaths.png $gFPETreeView; break; } } // According to selected tree view item, select Maya nodes. // Some nodes may have some of their attributes selected, these // nodes will be selected also. // proc selectMayaNodeFromItems() { global string $gFPETreeView; global string $gFPEFileAttributes[]; // clear selection list // select -clear; // select all Maya nodes for all selected treeView items // string $selectedItems[] = `treeView -q -selectItem $gFPETreeView`; string $command = "select"; int $i; for ($i = 0; $i < size($selectedItems); $i++) { if (size($gFPEFileAttributes[(int)$selectedItems[$i]]) == 0) continue; // skip Non-file item string $nodeName = `plugNode $gFPEFileAttributes[(int)$selectedItems[$i]]`; if (`objExists $nodeName`) $command += " " + $nodeName; } eval $command; } // Save the selection state according to the state of treeView items. // proc setSelectionInfo() { global string $gFPETreeView; global int $gFPEItemSelectState[]; global int $gFPEItemShowState[]; string $selectedItems[] = `treeView -q -selectItem $gFPETreeView`; // reset selection information int $i; for ($i = 0; $i < size($gFPEItemSelectState); $i++) { $gFPEItemSelectState[$i] = 0; } // set the selection information. // for ($i = 0; $i < size($selectedItems); $i++) { if ($gFPEItemShowState[(int)$selectedItems[$i]] != -1) $gFPEItemSelectState[(int)$selectedItems[$i]] = 1; } } // deselect all hierarchy items // proc clearSelectionForHierarchyItems() { global string $gFPEFileAttributes[]; global string $gFPEFileNames[]; global int $gFPEItemSelectState[]; global int $gFPEListType; global string $gFPETreeView; setSelectionInfo(); // travels for all items, only process hierarchy items // for ($i = 0; $i < size($gFPEItemSelectState); $i++) { if (size($gFPEFileAttributes[$i]) == 0) // hierarchy item { if ($gFPEItemSelectState[$i] == 1) { if ($i > 0) // do not skip top item { if ($gFPEListType == 0 && size($gFPEFileNames[$i]) == 0) continue; // skip attribute type entry else if ($gFPEListType == 1 && size($gFPEFileNames[$i]) > 0) continue; // skip directory entry } // deselect the hierarchy item treeView -e -selectItem $i 0 $gFPETreeView; $gFPEItemSelectState[$i] = 0; } } } } // Update selection state and highlight color for deselected // hierarchy items. // proc updateSelectStateForParentItem(int $selInfoReady) { global string $gFPEFileAttributes[]; global string $gFPEFileNames[]; global int $gFPEItemShowState[]; global int $gFPEItemSelectState[]; global float $gFPEHalfHighlitColor[]; global int $gFPEListType; global string $gFPETreeView; if ($selInfoReady == 0) setSelectionInfo(); // travels for all items, only process hierarchy items // for ($i = 0; $i < size($gFPEItemSelectState); $i++) { // only visible item are processed if ($gFPEItemShowState[$i] != 1) continue; if (size($gFPEFileAttributes[$i]) == 0) // hierarchy item { if ($i > 0) // do not skip top item { if ($gFPEListType == 0 && size($gFPEFileNames[$i]) == 0) continue; // skip attribute type entry else if ($gFPEListType == 1 && size($gFPEFileNames[$i]) > 0) continue; // skip directory entry } if ($gFPEItemSelectState[$i] == 0) { string $childItems[] = `treeView -q -children $i $gFPETreeView`; // the hierarchy item is not selected, set its state int $initState = -1; int $j; for ($j = 0; $j < size($childItems); $j++) { int $ci = (int)$childItems[$j]; if ($gFPEItemShowState[$ci] != 1) continue; if ($ci == $i) continue; // skip self if (size($gFPEFileAttributes[$ci]) == 0) continue; // skip child hierarchy item if ($initState == -1) $initState = $gFPEItemSelectState[$ci]; else if ($initState != $gFPEItemSelectState[$ci]) { $initState = 2; break; } } switch ($initState) { case 0: // no child item is selected, restore to default label color treeView -e -labelBackgroundColor $i -1 -1 -1 $gFPETreeView; break; case 1: // all child item are selected, select the parent item treeView -e -selectItem $i true $gFPETreeView; break; case 2: treeView -e -labelBackgroundColor $i $gFPEHalfHighlitColor[0] $gFPEHalfHighlitColor[1] $gFPEHalfHighlitColor[2] $gFPETreeView; break; } } // else the hierarchy item is selected, we have processed it earlier } // else this is leaf item, skip it } selectMayaNodeFromItems(); } ////////////////////////////////////////// // // UI Utility Methods // ///////////////////////////////////////// // update the types checkboxes in auto resolve dialog according to settings // proc updateARTypesUIBySettings() { global string $gFPEAttrTypes[]; string $types[] = stringToStringArray(`optionVar -q fpeAutoResolve_types`, "%"); string $checkBoxes[] = `columnLayout -q -childArray FPEARTypeColumnLayout`; int $i; for ($i = 0; $i < size($gFPEAttrTypes); $i++) { // for deregistered type, its checkbox is disabled. // uncheck it any way. if (! `checkBox -q -enable $checkBoxes[$i]`) { checkBox -e -value 0 $checkBoxes[$i]; continue; } int $j; for ($j = 0; $j < size($types); $j++) { if ($types[$j] == $gFPEAttrTypes[$i]) { checkBox -e -value 0 $checkBoxes[$i]; break; } } if ($j == size($types)) { checkBox -e -value 1 $checkBoxes[$i]; } } } // build types layout in auto resolve dialog dynamically // proc buildARTypesLayout(int $isUpdate) { global string $gFPEAttrTypes[]; if ($isUpdate && ! `window -exists fpeAutoResolveWin`) return; if (`columnLayout -exists FPEARTypeColumnLayout`) { deleteUI -control FPEARTypeColumnLayout; } columnLayout -parent FPEARTypeLayout FPEARTypeColumnLayout; string $label; int $i; for ($i = 0; $i < size($gFPEAttrTypes); $i++) { int $enable = 1; $label = `filePathEditor -q -typeLabel $gFPEAttrTypes[$i]`; // when open the auto reslove dialog, some types may be deregistered, // and fail to get their label if (size($label) == 0) { $label = $gFPEAttrTypes[$i] + "(Deregistered)"; $enable = 0; } checkBox -label $label -enable $enable -parent FPEARTypeColumnLayout; } updateARTypesUIBySettings(); } ////////////////////////////////////////// // // Popup menu // ///////////////////////////////////////// global proc FPEBuildTreeViewPopupMenu() { global string $gFPETreeView; string $popMenu = `popupMenu -ctrlModifier false -button 3 -parent $gFPETreeView ($gFPETreeView + "Popup")`; popupMenu -e -postMenuCommand ("FPEBuildPopupMenu " + $popMenu) $popMenu; } global proc FPEBuildPopupMenu(string $popMenu) { global string $gFPETreeView; menu -e -deleteAllItems $popMenu; setParent -menu $popMenu; string $label = repathStr(); menuItem -l $label -enable true -command "FPERepathRepathBtnCB 0 0"; menuItem -optionBox true -command "filePathRepathWin"; $label = replaceStr(); menuItem -l $label -enable true -command "FPEReplaceButtonCB 0 0"; menuItem -optionBox true -command "filePathReplaceWin"; $label = autoResolveStr(); menuItem -l $label -enable true -command "FPEAutoResolveCB 0 0"; menuItem -optionBox true -command "filePathAutoResolveWin"; menuItem -divider true; string $selectedItems[] = `treeView -q -selectItem $gFPETreeView`; int $enable = size($selectedItems) > 0; menuItem -l (uiRes("m_filePathEditorWin.kGraphInNE")) -enable $enable -command "FPEGraphInNE"; menuItem -l (uiRes("m_filePathEditorWin.kGraphInHS")) -enable $enable -command "FPEGraphInHS"; menuItem -l (uiRes("m_filePathEditorWin.kRevealInExplorer")) -enable $enable -command "FPEExplorerFile"; menuItem -divider true; menuItem -l (uiRes("m_filePathEditorWin.kRefresh")) -enable true -command "FPERefreshCB"; } // Callback for popup menu item "Reveal in Node Editor". // Show selected nodes in node editor. // global proc FPEGraphInNE() { // sync the viewport selection with the selected treeView item. // The nodes shown in NodeEditor is synchronized with viewport // selection. But sometimes viewport selection is not synchronized // with FPE treeView. For example, when operate the viewport, // back to FPE and right click the treeView directly. // selectMayaNodeFromItems(); string $neWin = `nodeEditorWindow`; if ($neWin != "") { // clear the editor nodeEditor -e -rfs 0 -rootNode "" $neWin; flushIdleQueue; // show active objects with upstream and downstream nodes nodeEditor -e -rfs 1 -ups 1 -ds 1 -fa $neWin; flushIdleQueue; nodeEdSyncControls $neWin; } } // Callback for popup menu item "Reveal in Hypershade". // Show selected nodes in hypershade. // global proc FPEGraphInHS() { // sync the viewport selection with the selected treeView item. // same reason with NodeEditor. refer to FPEGraphInNE(). // selectMayaNodeFromItems(); string $hypershadeTitle = localizedPanelLabel("Hypershade"); tearOffRestorePanel $hypershadeTitle "hyperShadePanel" true; flushIdleQueue; refresh; // show active objects in hypershade hyperShadePanelGraphCommand("hyperShadePanel1", "showUpAndDownstream"); } // Callback for popup menu item "Reveal in Explorer". // Open file browser for selected files. // global proc FPEExplorerFile() { global string $gFPEFileNames[]; global int $gFPEItemParentDir[]; int $items[] = getAllSelectedAttributeItems(); if (size($items) == 0) { return; } string $projectDir = `workspace -q -rootDirectory`; int $curDirItem = -1; int $i; for ($i = 0; $i < size($items); $i++) { // get directory path for a file item int $dirItem = $gFPEItemParentDir[$items[$i]]; string $directory = $gFPEFileNames[$dirItem]; // fix for relative path if (startsWith($directory, "../")) { $directory = substitute("../", $directory, $projectDir); } // skip the same directory because only open one window for // same directory of all files // int $itemNumInSameDir = 1; if ($dirItem != $curDirItem) { $curDirItem = $dirItem; // file items in same directory is continious in the array $items // int $j; for ($j = $i + 1; $j < size($items); $j++) { if ($curDirItem == $gFPEItemParentDir[$items[$j]]) { $itemNumInSameDir++; } else { break; } } $i = $j - 1; } // check if the file directory exists if (`filetest -d $directory`) { if (`about -linux`) { // "nautilus" can't support to select file, so open the directory only system("nautilus " + $directory); } else { // get file path string $file = $directory + "/" + $gFPEFileNames[$items[$i]]; int $fileExist = `filetest -e $file`; if (`about -win`) { if ($itemNumInSameDir > 1 || !$fileExist) { // open the directory string $converted = `substituteAllString $directory "/" "\\"`; system("explorer " + $converted); } else { // open the directory and select the file string $converted = `substituteAllString $file "/" "\\"`; system("explorer /select," + $converted); } } else if (`about -mac`) { if ($itemNumInSameDir > 1 || !$fileExist) { system("open " + $directory); } else { // open the directory and select the file system("open --reveal " + $file); } } } } else { string $msg = `format -stringArg $directory (uiRes("m_filePathEditorWin.kNonExistentDirectory"))`; warning $msg; } } } ///////////////////////////////////////////////////////////////////////////// // // "Show" menu of the main window // //////////////////////////////////////////////////////////////////////////// // The "Show" menu is generated dynamically because it depends on // the registered attribute types. // The states of checkbox menuitems in "Show" menu are saved and stored // among Maya sessions. These states are saved in two optionVars: // 1, "fpeShow_resolved" saves states of menuitem "Show Resolved" and // "Show Unresolved", which has four states: // 0 - "Resolved" unchecked, "Unresolved" unchecked // 1 - "Resolved" checked, "Unresolved" unchecked // 2 - "Resolved" unchecked, "Unresolved" checked // 3 - "Resolved" checked, "Unresolved" checked // // 2, "fpeShow_types" saves states of menuitems related to attribute types. // The option var only records unchecked types. If one attribute type is // not in the option var, then its menuitem is checked. // For new registered type, its item is checked by default. // // Set visibility of treeView items according to menu item settings // This method will be called when initialize the treeView items, refresh // the treeView and change the state of "Show" menuitem. // proc setItemVisibilityByShowMenu() { global string $gFPETreeView; global int $gFPEItemResolveState[]; global string $gFPEFileAttributes[]; global string $gFPEItemAttrType[]; global string $gFPEAttrTypes[]; global int $gFPEItemShowState[]; global int $gFPEListType; global string $gFPETypeItems[]; // get type for each attribute updateTypeForAttributes(); // // get settings of "Show" menu items // int $showResolved = 0; int $showUnresolved = 0; int $showTypes[]; int $resState = `optionVar -q fpeShow_resolved`; switch ($resState) { case 0: // use default value break; case 1: $showResolved = 1; break; case 2: $showUnresolved = 1; break; case 3: $showUnresolved = 1; $showResolved = 1; break; } string $uncheckedTypes[] = stringToStringArray(`optionVar -q fpeShow_types`, "%"); int $i; int $j; for ($i = 0; $i < size($gFPEAttrTypes); $i++) { $showTypes[$i] = 1; for ($j = 0; $j < size($uncheckedTypes); $j++) { if ($uncheckedTypes[$j] == $gFPEAttrTypes[$i]) { $showTypes[$i] = 0; break; } } } // // set visibility of items. // the first loop is for file items; then process hierarchy items // at the second loop. // int $dirItems[] = getDirectoryItems(); int $hierarchyItems[]; int $shouldShown; // the first loop: process file items // the "Top" item is skipped for ($i = 1; $i < size($gFPEItemResolveState); $i++) { if ($gFPEItemShowState[$i] == -1) continue; // skip removed item $shouldShown = 0; if (size($gFPEFileAttributes[$i]) > 0) // file entry { // firstly, check resolved state if (($gFPEItemResolveState[$i] == 0 && $showUnresolved == 1) || ($gFPEItemResolveState[$i] == 1 && $showResolved == 1)) { // then check the file type for ($j = 0; $j < size($gFPEAttrTypes); $j++) { if ($gFPEAttrTypes[$j] == $gFPEItemAttrType[$i]) { $shouldShown = $showTypes[$j]; break; } } } if ($shouldShown != $gFPEItemShowState[$i]) { // change the visibility of the item if ($shouldShown) treeView -e -itemVisible $i 1 $gFPETreeView; else { // when item is hidden, always deselect it treeView -e -itemVisible $i 0 -selectItem $i 0 $gFPETreeView; } $gFPEItemShowState[$i] = $shouldShown; } } else { // hierarchy entry (directory or filetype entry) will be // processed in second loop int $skip = 0; if ($gFPEListType == 0) // list by AbsPath { // skip file type items for ($j = 0; $j < size($gFPETypeItems); $j++) { if (size($gFPETypeItems[$j]) > 0 && (int)$gFPETypeItems[$j] == $i) $skip = 1; } } else // list by FileType { // skip directory items for ($j = 0; $j < size($dirItems); $j++) { if ($dirItems[$j] == $i) $skip = 1; } } if ($skip == 0) $hierarchyItems[size($hierarchyItems)] = $i; } } // the second loop: process hierarchy items for ($i = 0; $i < size($hierarchyItems); $i++) { // if all child items are hidden, hide the item. // otherwise set the correct resolved image // string $childItems[] = `treeView -q -children $hierarchyItems[$i] $gFPETreeView`; $shouldShown = 0; int $resolvedState = -1; for ($j = 0; $j < size($childItems); $j++) { int $ci = (int)$childItems[$j]; if ($gFPEItemShowState[$ci] == -1 || // skip removed item $ci == $hierarchyItems[$i]) // skip self continue; if ($gFPEItemShowState[$ci] == 1) { $shouldShown = 1; if ($resolvedState == -1) $resolvedState = $gFPEItemResolveState[$ci]; else if ($resolvedState != $gFPEItemResolveState[$ci]) $resolvedState = 2; } } if ($shouldShown && $gFPEItemResolveState[$hierarchyItems[$i]] != $resolvedState) { setResolveImage($hierarchyItems[$i], $resolvedState); $gFPEItemResolveState[$hierarchyItems[$i]] = $resolvedState; } if ($shouldShown != $gFPEItemShowState[$hierarchyItems[$i]]) { // change the visibility of the item treeView -e -itemVisible $hierarchyItems[$i] $shouldShown $gFPETreeView; $gFPEItemShowState[$hierarchyItems[$i]] = $shouldShown; } } // update the selection relationship. // only the selection state of hierarchy item need to be update. // firstly, clear the selection state of hierarchy item, then update // according to their child items // clearSelectionForHierarchyItems(); updateSelectStateForParentItem(1); } // Toggle check state for checkbox item and update visibility of treeView items. // Callback for menu items of menu "Show". // global proc FPEShowMenuCB(string $item) { global string $gFPEAttrTypes[]; int $state = `optionVar -q fpeShow_resolved`; if ($item == "Resolved") { switch ($state) { case 0: $state = 1; break; case 1: $state = 0; break; case 2: $state = 3; break; case 3: $state = 2; break; } optionVar -intValue fpeShow_resolved $state; } else if ($item == "Unresolved") { switch ($state) { case 0: $state = 2; break; case 1: $state = 3; break; case 2: $state = 0; break; case 3: $state = 1; break; } optionVar -intValue fpeShow_resolved $state; } else if ($item == "All") { optionVar -intValue fpeShow_resolved 3; optionVar -stringValue fpeShow_types ""; string $menuItems[] = `menu -q -itemArray FPEShowMenu`; int $i; for ($i = 0; $i < size($menuItems); $i++) { if (`menuItem -q -isCheckBox $menuItems[$i]`) { menuItem -e -checkBox 1 $menuItems[$i]; } } } else if ($item == "None") { string $types = stringArrayToString($gFPEAttrTypes, "%"); optionVar -intValue fpeShow_resolved 0; optionVar -stringValue fpeShow_types $types; string $menuItems[] = `menu -q -itemArray FPEShowMenu`; int $i; for ($i = 0; $i < size($menuItems); $i++) { if (`menuItem -q -isCheckBox $menuItems[$i]`) { menuItem -e -checkBox 0 $menuItems[$i]; } } } else // attribute type { string $uncheckedTypes[] = stringToStringArray(`optionVar -q fpeShow_types`, "%"); int $i; for ($i = 0; $i < size($uncheckedTypes); $i++) { if ($uncheckedTypes[$i] == $item) { break; } } if ($i == size($uncheckedTypes)) { // type item is unchecked, append the type to the array $uncheckedTypes[$i] = $item; } else { // type item is checked, remove from optionVar $uncheckedTypes[$i] = ""; } // save current state string $types = stringArrayToString($uncheckedTypes, "%"); optionVar -stringValue fpeShow_types $types; } // set visibility of treeView items according to "Show" menu settings setItemVisibilityByShowMenu(); } // Initialize option variables for "Show" menu items // proc setShowOptionVars(int $forceFactorySettings) { if ($forceFactorySettings || !`optionVar -exists fpeShow_resolved`) { optionVar -intValue fpeShow_resolved 3; } if ($forceFactorySettings || !`optionVar -exists fpeShow_types`) { optionVar -stringValue fpeShow_types ""; } } proc buildShowMenu() { global string $gFPEAttrTypes[]; // initialize the option vars if they have not been initialized setShowOptionVars(0); if (`menu -q -exists FPEShowMenu`) { menu -e -deleteAllItems FPEShowMenu; } else { menu -label (uiRes("m_filePathEditorWin.kShow")) -tearOff true FPEShowMenu; } int $showResolvedOpt = `optionVar -q fpeShow_resolved`; int $showResolved = ($showResolvedOpt == 1 || $showResolvedOpt == 3); int $showUnresolved = ($showResolvedOpt == 2 || $showResolvedOpt == 3); menuItem -label (uiRes("m_filePathEditorWin.kResolvedItem")) -parent FPEShowMenu -checkBox $showResolved -command "FPEShowMenuCB Resolved" showResolvedItem; menuItem -label (uiRes("m_filePathEditorWin.kUnresolvedItem")) -parent FPEShowMenu -checkBox $showUnresolved -command "FPEShowMenuCB Unresolved"; menuItem -divider true -parent FPEShowMenu; string $showTypes[] = stringToStringArray(`optionVar -q fpeShow_types`, "%"); for ($i = 0; $i < size($gFPEAttrTypes); $i++) { int $showType = 1; int $j; for ($j = 0; $j < size($showTypes); $j++) { if ($showTypes[$j] == $gFPEAttrTypes[$i]) { $showType = 0; break; } } string $label = `filePathEditor -q -typeLabel $gFPEAttrTypes[$i]`; string $cmdStr = "FPEShowMenuCB " + $gFPEAttrTypes[$i]; menuItem -label $label -parent FPEShowMenu -checkBox $showType -command $cmdStr; } menuItem -divider true -parent FPEShowMenu; menuItem -label (uiRes("m_filePathEditorWin.kCheckAll")) -parent FPEShowMenu -command "FPEShowMenuCB All"; menuItem -label (uiRes("m_filePathEditorWin.kCheckNone")) -parent FPEShowMenu -command "FPEShowMenuCB None"; } ////////////////////////////////////////// // // Callback for "Select" MenuItems // ///////////////////////////////////////// // Callback for "Select" -> "Select All" // global proc FPEselectAllCB() { global string $gFPETreeView; if (`treeView -q -itemSelected "0" $gFPETreeView` == 0) { // select the top item, then update the whole treeView treeView -e -selectItem "0" true $gFPETreeView; FPEItemSelectChangedCB(); } } // Callback for "Select" -> "Select None" // global proc FPEselectNoneCB() { global string $gFPETreeView; treeView -e -clearSelection $gFPETreeView; FPEItemSelectChangedCB(); } // Callback for "Select" -> "Select Unresolved" // global proc FPEselectUnresolvedCB() { global string $gFPETreeView; global string $gFPEFileAttributes[]; global int $gFPEItemResolveState[]; global int $gFPEItemShowState[]; treeView -e -clearSelection $gFPETreeView; // for missing file items, select them // int $i; for ($i = 0; $i < size($gFPEItemResolveState); $i++) { if ($gFPEItemShowState[$i] != 1 || size($gFPEFileAttributes[$i]) == 0) continue; if ($gFPEItemResolveState[$i] == 0) { treeView -e -selectItem $i true $gFPETreeView; } } updateSelectStateForParentItem(0); } proc buildSelectByTypeMenu() { global string $gFPEAttrTypes[]; if (`menu -q -exists FPESelectByTypeMenu`) { menu -e -deleteAllItems FPESelectByTypeMenu; } else { menuItem -label (uiRes("m_filePathEditorWin.kSelectByType")) -subMenu true -tearOff true FPESelectByTypeMenu; } string $label; int $i; for ($i = 0; $i < size($gFPEAttrTypes); $i++) { string $commandString = "FPEselectByTypeCB \"" + $gFPEAttrTypes[$i] + "\""; $label = `filePathEditor -q -typeLabel $gFPEAttrTypes[$i]`; menuItem -label $label -parent FPESelectByTypeMenu -command $commandString; } } // Callback for "Select" -> "Select By Type" // global proc FPEselectByTypeCB(string $attrType) { global string $gFPETreeView; global string $gFPEFileAttributes[]; global int $gFPEItemShowState[]; global string $gFPEItemAttrType[]; updateTypeForAttributes(); treeView -e -clearSelection $gFPETreeView; // for all items, process int $i; for ($i = 0; $i < size($gFPEItemShowState); $i++) { if ($gFPEItemShowState[$i] != 1 || size($gFPEFileAttributes[$i]) == 0) continue; if ($gFPEItemAttrType[$i] == $attrType) { treeView -e -selectItem $i true $gFPETreeView; } } updateSelectStateForParentItem(0); } // Callback for "Select" -> "Invert Selection" // global proc FPEinvertSelectionCB() { global string $gFPETreeView; global string $gFPEFileAttributes[]; global int $gFPEItemShowState[]; global int $gFPEItemSelectState[]; setSelectionInfo(); // unselect hierarchy items, and invert file items // int $i; for ($i = 0; $i < size($gFPEItemShowState); $i++) { if ($gFPEItemShowState[$i] != 1) continue; if ($gFPEItemSelectState[$i] == 0) { // select unselected file items if (size($gFPEFileAttributes[$i]) > 0) { treeView -e -selectItem $i true $gFPETreeView; $gFPEItemSelectState[$i] = 1; } else if ($i == 0) { // special process for the "Top" item when there is only // one "Top" item in the editor string $childItems[] = `treeView -q -children "0" $gFPETreeView`; if (size($childItems) == 1) { treeView -e -selectItem "0" true $gFPETreeView; $gFPEItemSelectState[0] = 1; } } } else { // deselect other selected items treeView -e -selectItem $i false $gFPETreeView; $gFPEItemSelectState[$i] = 0; } } // update the hierarchy items updateSelectStateForParentItem(1); } ////////////////////////////////////////// // // // ///////////////////////////////////////// // Treeview item select callback function. // global proc int FPETreeItemSelectCB(string $item, int $state) { global string $gFPETreeView; global string $gFPEFileAttributes[]; global int $gFPEItemShowState[]; // update the selectin state of parent and descendant item when // deselect an item. // when item is selected, it is processed in FPEItemSelectChangedCB() // if ($state == 0) // deselected { // deselect its parent item string $pItem = `treeView -q -itemParent $item $gFPETreeView`; while (size($pItem) > 0) { treeView -e -selectItem $pItem false $gFPETreeView; $pItem = `treeView -q -itemParent $pItem $gFPETreeView`; } int $index = (int)$item; if (size($gFPEFileAttributes[$index]) == 0) // hierarchy item { // deselect all its descendant items string $childItems[] = `treeView -q -children $item $gFPETreeView`; int $j; for ($j = 0; $j < size($childItems); $j++) { int $ci = (int)$childItems[$j]; if ($ci == $index) continue; // skip self if ($gFPEItemShowState[$ci] != 1) continue; treeView -e -selectItem $childItems[$j] false $gFPETreeView; } } } return 1; } // Treeview item selection changed callback function. // If parent item is selected, select all its child items. // If part of child items is selected, the parent item is // highlit with half selection color. // If all child items are selected, the parent item is also // selected. // global proc FPEItemSelectChangedCB() { global int $gFPEItemSelectState[]; global string $gFPEFileAttributes[]; global int $gFPEItemShowState[]; global string $gFPETreeView; setSelectionInfo(); // select all child items for selected hierarchy item int $i; for ($i = 0; $i < size($gFPEItemSelectState); $i++) { if ($gFPEItemSelectState[$i] == 1) { if (size($gFPEFileAttributes[$i]) == 0) // hierarchy item { string $childItems[] = `treeView -q -children $i $gFPETreeView`; int $j; for ($j = 0; $j < size($childItems); $j++) { int $ci = (int)$childItems[$j]; if ($gFPEItemShowState[$ci] != 1) continue; // skip invisible and removed item if ($gFPEItemSelectState[$ci] == 0) { treeView -e -selectItem $childItems[$j] true $gFPETreeView; $gFPEItemSelectState[$ci] = 1; } } } } } updateSelectStateForParentItem(1); } // Callback for treeView item double click event // Do nothing to supersede the normal item renaming behavior // global proc FPEDummyDblClickCB(string $item) { } // Callback for treeView button click event // Preserver the button state unchanged // global proc FPEItemButtonClickCB(string $item, int $state) { global string $gFPETreeView; treeView -edit -buttonState $item 1 "buttonDown" $gFPETreeView; } // callback when destroy the editor // global proc FPEDestroyCB() { global string $gFPEWindowName; global string $gFPEAttrTypes[]; // clear all data clearDataAndTreeView(); // the attribute types are destroyed only after close the editor clear($gFPEAttrTypes); // delete child windows FPERepathCancelButtonCB(); FPEReplaceCancelButtonCB(); FPEAutoResCancelButtonCB(); } proc updateTopItem() { global string $gFPETreeView; global string $gFPEFileAttributes[]; global int $gFPEItemResolveState[]; global int $gFPEItemShowState[]; // get total number of resolved and unresolved files int $unresolved = 0; int $resolved = 0; int $i; for ($i = 0; $i < size($gFPEFileAttributes); $i++) { if ($gFPEItemShowState[$i] == -1) continue; // skip non-existent item if (size($gFPEFileAttributes[$i]) > 0) // file item { if ($gFPEItemResolveState[$i] == 1) $resolved++; else if ($gFPEItemResolveState[$i] == 0) $unresolved++; } } string $topItem = "0"; string $label = (uiRes("m_filePathEditorWin.kTop")) + " (" + $resolved + " " + (uiRes("m_filePathEditorWin.kResolved")) + ", " + $unresolved + " " + (uiRes("m_filePathEditorWin.kUnresolved")) + ")"; treeView -edit -displayLabel $topItem $label $gFPETreeView; if ($unresolved == 0) { $gFPEItemResolveState[0] = 1; } else if ($resolved == 0) { $gFPEItemResolveState[0] = 0; } else { $gFPEItemResolveState[0] = 2; } setResolveImage($topItem, $gFPEItemResolveState[0]); } proc FPEAddTreeViewItem(string $item, string $label, string $parentItem) { global string $gFPETreeView; global int $gFPEListType; global string $gFPETreeView; global int $gFPEItemShowState[]; treeView -edit -addItem $item $parentItem $gFPETreeView; treeView -edit -displayLabel $item $label -buttonStyle $item 1 "2StateButton" -buttonState $item 1 "buttonDown" $gFPETreeView; // generated item is visible $gFPEItemShowState[(int)$item] = 1; if ($gFPEListType == 1 && ($parentItem != "0" && $parentItem != "")) { // add annotation for treeView file item in list by file type mode // string $annotation = getFullname($item); treeView -e -itemAnnotation $item $annotation $gFPETreeView; } } proc string FPEAddItem(string $fileName, string $attrName, string $parentItem) { global string $gFPETreeView; global string $gFPEFileAttributes[]; global string $gFPEFileNames[]; global int $gFPEItemResolveState[]; global int $gFPEItemParentDir[]; global int $gFPEItemSelectState[]; int $index = size($gFPEItemResolveState); $gFPEFileAttributes[$index] = $attrName; $gFPEFileNames[$index] = $fileName; string $label; if (size($attrName) > 0) { $label = getItemLabel($index); } else // directory entry or other entry { $label = $fileName; } FPEAddTreeViewItem($index, $label, $parentItem); $gFPEItemResolveState[$index] = 2; // add an element for the array $gFPEItemResolveState $gFPEItemSelectState[$index] = 0; if (size($parentItem) > 0) // check if it is the top item $gFPEItemParentDir[$index] = (int)$parentItem; else $gFPEItemParentDir[$index] = -1; // the top item return $index; } // Generate all file items under one directory. // The file array is a pair array of file name, attribute name and resolve state. // proc genFileItemsUnderDir(string $files[], string $dirItem) { global string $gFPETreeView; global int $gFPEItemResolveState[]; int $fi; for ($fi = 0; $fi < size($files); $fi=$fi+3) { string $fileItem = FPEAddItem($files[$fi], $files[$fi+1], $dirItem); string $fullFilename = getFullname($fileItem); // set the resolved status for this file $gFPEItemResolveState[(int)$fileItem] = (int)$files[$fi+2]; // set the image setResolveImage($fileItem, $gFPEItemResolveState[(int)$fileItem]); } // collapse the directory item treeView -e -expandItem $dirItem 0 $gFPETreeView; } // Update the resolved state of attrType treeView items; // Hide the attribute type item if all its child items are removed // proc updateStateOfAttrTypeItems() { global string $gFPETreeView; global string $gFPETypeItems[]; global int $gFPEItemResolveState[]; global int $gFPEItemShowState[]; for ($i = 0; $i < size($gFPETypeItems); $i++) { if (size($gFPETypeItems[$i]) > 0 ) { if (`treeView -q -itemExists $gFPETypeItems[$i] $gFPETreeView`) { int $initState = -1; string $childItems[] = `treeView -q -children $gFPETypeItems[$i] $gFPETreeView`; int $ci; for ($ci = 0; $ci < size($childItems); $ci++) { int $itemIndex = (int)$childItems[$ci]; if ($childItems[$ci] == $gFPETypeItems[$i] || $gFPEItemShowState[$itemIndex] == -1) continue; if ($initState == -1) $initState = $gFPEItemResolveState[$itemIndex]; else if ($initState != $gFPEItemResolveState[$itemIndex]) { $initState = 2; break; } } $gFPEItemResolveState[(int)$gFPETypeItems[$i]] = $initState; if ($initState == -1) { // all child items are removed, hide this one $gFPEItemParentDir[(int)$gFPETypeItems[$i]] = -1; $gFPEItemShowState[(int)$gFPETypeItems[$i]] = -1; treeView -e -itemVisible $gFPETypeItems[$i] 0 $gFPETreeView; treeView -e -selectItem $gFPETypeItems[$i] false $gFPETreeView; } else { setResolveImage($gFPETypeItems[$i], $initState); } } else { // mark 'not created' on this attribute type item $gFPEItemShowState[(int)$gFPETypeItems[$i]] = -1; } } } } // Generate a new file item when list mode is by file type // proc int genFileItemByFileType(string $fileName, string $attrName, int $resolvedState, int $dirItem) { global string $gFPETreeView; global string $gFPEItemAttrType[]; global string $gFPETypeItems[]; global int $gFPEItemResolveState[]; global string $gFPEFileAttributes[]; global string $gFPEFileNames[]; global int $gFPEItemSelectState[]; global int $gFPEItemParentDir[]; global string $gFPEAttrTypes[]; global int $gFPEItemShowState[]; string $attrType = `filePathEditor -q -attributeType $attrName`; // get the attrType treeView item // int $i; for ($i = 0; $i < size($gFPEAttrTypes); $i++) { if ($gFPEAttrTypes[$i] == $attrType) { if (size($gFPETypeItems[$i]) == 0) { // the attrType item has not been created. // create the attrType treeView item on demand // int $item = size($gFPEItemResolveState); $gFPETypeItems[$i] = $item; $gFPEFileAttributes[$item] = ""; $gFPEFileNames[$item] = ""; $gFPEItemResolveState[$item] = 0; $gFPEItemSelectState[$item] = 0; $gFPEItemParentDir[$item] = 0; $gFPEItemAttrType[$item] = ""; $gFPEItemShowState[$item] = 1; string $attrTypeLabel = `filePathEditor -q -typeLabel $attrType`; FPEAddTreeViewItem($gFPETypeItems[$i], $attrTypeLabel, "0"); treeView -e -expandItem $gFPETypeItems[$i] 0 $gFPETreeView; } else if ($gFPEItemShowState[(int)$gFPETypeItems[$i]] == -1) { // the attrType item has been created before, do not need to // setup the data for it again. // if (`treeView -q -itemExists $gFPETypeItems[$i] $gFPETreeView`) { // show the item. // the attrType item is hidden. This can be occurred when: // the attrType item was created, then all file items under it // were removed, and refresh the treeView, the attrType item // was hidden. Now there are new file item with this attrType, // so show this attrType item again. // treeView -e -itemVisible $gFPETypeItems[$i] true $gFPETreeView; } else { // create the item. // the attrType item data is ready, but item is not created. // This can be occurred when: at first, the list mode is by file // type. So the attrType item data was filled. Then switch the list // mode to by directory, the treeView item was removed and all file // items of this attribute type are removed. At last switch back to by // file type, and add file item of this attribute type. // string $attrTypeLabel = `filePathEditor -q -typeLabel $attrType`; FPEAddTreeViewItem($gFPETypeItems[$i], $attrTypeLabel, "0"); treeView -e -expandItem $gFPETypeItems[$i] 0 $gFPETreeView; } $gFPEItemShowState[(int)$gFPETypeItems[$i]] = 1; } break; } } int $index = size($gFPEItemResolveState); // setup the file item $gFPEFileAttributes[$index] = $attrName; $gFPEFileNames[$index] = $fileName; $gFPEItemResolveState[$index] = $resolvedState; $gFPEItemSelectState[$index] = 0; $gFPEItemParentDir[$index] = $dirItem; $gFPEItemAttrType[$index] = $attrType; $gFPEItemShowState[$index] = 1; string $label = $attrName + " [" + $fileName + "]"; FPEAddTreeViewItem($index, $label, $gFPETypeItems[$i]); setResolveImage($index, $resolvedState); return $index; } // Refresh the treeView items when list mode is by directory. // Firstly, we get current directories. If one directory is new, // create the directory item and all its file items. If one // directory matches existent directory, check files in this // directory. // The resolved states of directory and file are also updated. // Because Maya treeView does not support to remove specified item, // the non-existent items (directory or file) are hidden. And the // global data $gFPEItemShowState of this item is set to -1. // Because Maya treeView does not support to insert an item, all new // item are appened to the last of its parent. // proc refreshByAbsPath(string $rootDir, string $parentItem) { global string $gFPETreeView; global int $gFPEItemResolveState[]; global string $gFPEFileNames[]; global int $gFPEItemParentDir[]; global int $gFPEItemShowState[]; string $allDirectory[] = `filePathEditor -q -status -relativeNames -listDirectories $rootDir `; int $dirItems[] = getDirectoryItems(); int $dirMatched[]; // flag that existed directory item match new item int $dmi; for ($dmi = 0; $dmi < size($dirItems); $dmi++) { $dirMatched[$dmi] = 0; } int $i; for ($i = 0; $i < size($allDirectory); $i=$i+2) { // get all files under this directory string $files[] = `filePathEditor -q -withAttribute -status -listFiles $allDirectory[$i]`; // find if this directory item exists int $di; for ($di = 0; $di < size($dirItems); $di++) { if ($gFPEFileNames[$dirItems[$di]] == $allDirectory[$i]) { $dirMatched[$di] = 1; break; } } if ($di == size($dirItems)) { // new directory, create the item // string $item = FPEAddItem($allDirectory[$i], "", $parentItem); int $dirIndex = $item; $gFPEItemResolveState[$dirIndex] = (int)$allDirectory[$i+1]; setResolveImage($item, $gFPEItemResolveState[$dirIndex]); // creat all file items genFileItemsUnderDir($files, $item); } else { // the directory match existent directory. // check each file under it // int $childFileItems[] = getFileItemsUnderDir($dirItems[$di]); int $fileMatched[]; // flag that existed directory item match new item int $fmi; for ($fmi = 0; $fmi < size($childFileItems); $fmi++) { $fileMatched[$fmi] = 0; } int $fi; for ($fi = 0; $fi < size($files); $fi=$fi+3) { // found if this file item existed int $fileItemIndex = findTreeViewItemForAttr($files[$fi], $files[$fi+1], $childFileItems); int $fileItem; if ($fileItemIndex < 0) { $fileItem = FPEAddItem($files[$fi], $files[$fi+1], $dirItems[$di]); } else { $fileMatched[$fileItemIndex] = 1; $fileItem = $childFileItems[$fileItemIndex]; } // update the resolved status for this file if changed int $resolvedState = (int)$files[$fi+2]; if ($gFPEItemResolveState[$fileItem] != $resolvedState) { $gFPEItemResolveState[$fileItem] = $resolvedState; // set the image setResolveImage($fileItem, $resolvedState); } } // update the resolved status for this directory int $itemIndex = $dirItems[$di]; if ($gFPEItemResolveState[$itemIndex] != (int)$allDirectory[$i+1]) { $gFPEItemResolveState[$itemIndex] = (int)$allDirectory[$i+1]; setResolveImage($dirItems[$di], $gFPEItemResolveState[$itemIndex]); } // hide non-existed file items for ($fmi = 0; $fmi < size($childFileItems); $fmi++) { if ($fileMatched[$fmi] == 0) { // hide this non-existed item treeView -e -itemVisible $childFileItems[$fmi] 0 $gFPETreeView; treeView -e -selectItem $childFileItems[$fmi] false $gFPETreeView; $gFPEItemParentDir[$childFileItems[$fmi]] = -1; $gFPEItemShowState[$childFileItems[$fmi]] = -1; } } } } // hide non-existed directory items for ($dmi = 0; $dmi < size($dirItems); $dmi++) { if ($dirMatched[$dmi] == 0) { // reset global data int $childFileItems[] = getFileItemsUnderDir($dirItems[$dmi]); int $fmi; for ($fmi = 0; $fmi < size($childFileItems); $fmi++) { $gFPEItemParentDir[$childFileItems[$fmi]] = -1; $gFPEItemShowState[$childFileItems[$fmi]] = -1; treeView -e -itemVisible $childFileItems[$fmi] 0 $gFPETreeView; treeView -e -selectItem $childFileItems[$fmi] false $gFPETreeView; } $gFPEItemParentDir[$dirItems[$dmi]] = -1; $gFPEItemShowState[$dirItems[$dmi]] = -1; // hide this non-existed item treeView -e -itemVisible $dirItems[$dmi] 0 $gFPETreeView; treeView -e -selectItem $dirItems[$dmi] false $gFPETreeView; } } // update the resolved number for the "Top" label updateTopItem(); } // Refresh the treeView items when list mode is by file type. // The refresh is similar with by directory. The file items are // matched according to its directory. // proc refreshByFileType(string $rootDir, string $parentItem) { global string $gFPETreeView; global int $gFPEItemResolveState[]; global string $gFPEFileNames[]; global string $gFPEFileAttributes[]; global int $gFPEItemSelectState[]; global int $gFPEItemParentDir[]; global int $gFPEItemShowState[]; string $allDirectory[] = `filePathEditor -q -status -relativeNames -listDirectories $rootDir `; int $dirItems[] = getDirectoryItems(); int $dirMatched[]; // flag that existed directory item match new item int $dmi; for ($dmi = 0; $dmi < size($dirItems); $dmi++) { $dirMatched[$dmi] = 0; } int $i; for ($i = 0; $i < size($allDirectory); $i=$i+2) { // get all files under this directory string $files[] = `filePathEditor -q -withAttribute -status -listFiles $allDirectory[$i]`; // find if this directory item existed int $di; for ($di = 0; $di < size($dirItems); $di++) { if ($gFPEFileNames[$dirItems[$di]] == $allDirectory[$i]) { $dirMatched[$di] = 1; break; } } if ($di == size($dirItems)) { // new directory, create data and its file items // int $dirIndex = size($gFPEItemResolveState); $gFPEFileAttributes[$dirIndex] = ""; $gFPEFileNames[$dirIndex] = $allDirectory[$i]; $gFPEItemResolveState[$dirIndex] = (int)$allDirectory[$i+1]; $gFPEItemSelectState[$dirIndex] = 0; $gFPEItemParentDir[$dirIndex] = 0; int $fi; for ($fi = 0; $fi < size($files); $fi=$fi+3) { int $item = genFileItemByFileType($files[$fi], $files[$fi+1], $files[$fi+2], $dirIndex); } } else { // the directory match existent directory. // check each file under it // int $childFileItems[] = getFileItemsUnderDir($dirItems[$di]); int $fileMatched[]; // flag that existed directory item match new item int $fmi; for ($fmi = 0; $fmi < size($childFileItems); $fmi++) { $fileMatched[$fmi] = 0; } int $fi; for ($fi = 0; $fi < size($files); $fi=$fi+3) { // find if this file item exists int $fileItemIndex = findTreeViewItemForAttr($files[$fi], $files[$fi+1], $childFileItems); int $fileItem; if ($fileItemIndex < 0) { $fileItem = genFileItemByFileType($files[$fi], $files[$fi+1], $files[$fi+2], $dirItems[$di]); } else { $fileMatched[$fileItemIndex] = 1; $fileItem = $childFileItems[$fileItemIndex]; // update the resolved status for this file if changed int $resolvedState = (int)$files[$fi+2]; if ($gFPEItemResolveState[$fileItem] != $resolvedState) { $gFPEItemResolveState[$fileItem] = $resolvedState; // set the image setResolveImage($fileItem, $resolvedState); } } } // update the resolved status for this directory $gFPEItemResolveState[$dirItems[$di]] = (int)$allDirectory[$i+1]; // hide non-existed file items for ($fmi = 0; $fmi < size($childFileItems); $fmi++) { if ($fileMatched[$fmi] == 0) { // hide this non-existed item treeView -e -itemVisible $childFileItems[$fmi] 0 $gFPETreeView; treeView -e -selectItem $childFileItems[$fmi] false $gFPETreeView; $gFPEItemParentDir[$childFileItems[$fmi]] = -1; $gFPEItemShowState[$childFileItems[$fmi]] = -1; } } } } // hide non-existed directory items // for ($dmi = 0; $dmi < size($dirItems); $dmi++) { if ($dirMatched[$dmi] == 0) { // hide file items under this directory int $childFileItems[] = getFileItemsUnderDir($dirItems[$dmi]); int $fmi; for ($fmi = 0; $fmi < size($childFileItems); $fmi++) { $gFPEItemParentDir[$childFileItems[$fmi]] = -1; $gFPEItemShowState[$childFileItems[$fmi]] = -1; treeView -e -itemVisible $childFileItems[$fmi] 0 $gFPETreeView; treeView -e -selectItem $childFileItems[$fmi] false $gFPETreeView; } // the directory item has no treeView UI, only modify the data $gFPEItemParentDir[$dirItems[$dmi]] = -1; $gFPEItemShowState[$dirItems[$dmi]] = -1; } } // update resolve state for attribute type items updateStateOfAttrTypeItems(); // update the resolved number for the "Top" item updateTopItem(); } // refresh registered attribute types // proc refreshAttrType() { global string $gFPEAttrTypes[]; global string $gFPETypeItems[]; global string $gFPETreeView; global int $gFPEItemParentDir[]; global int $gFPEItemShowState[]; // check if registered attribute types changed string $curAttrTypes[] = `filePathEditor -q -listRegisteredTypes`; int $i; if (size($gFPEAttrTypes) == size($curAttrTypes)) { for ($i = 0; $i < size($gFPEAttrTypes); $i++) { if ($gFPEAttrTypes[$i] != $curAttrTypes[$i]) { break; } } // if no registered attribute types changed, just return if ($i == size($gFPEAttrTypes)) return; } // update type item of treeview if (size($gFPETypeItems) > 0) { int $j; // copy $gFPETypeItems to a temp array, then clear $gFPETypeItems string $tmpTypeItems[]; for ($j = 0; $j < size($gFPETypeItems); $j++) { $tmpTypeItems[$j] = $gFPETypeItems[$j]; } clear($gFPETypeItems); // match the old attribute types with new attribute types // for ($i = 0; $i < size($curAttrTypes); $i++) { for ($j = 0; $j < size($gFPEAttrTypes); $j++) { if ($curAttrTypes[$i] == $gFPEAttrTypes[$j]) { // the attribute type is not new $gFPETypeItems[$i] = $tmpTypeItems[$j]; $tmpTypeItems[$j] = ""; break; } } if ($j == size($gFPEAttrTypes)) { // the attribute type is new registered $gFPETypeItems[$i] = ""; } } for ($i = 0; $i < size($tmpTypeItems); $i++) { if ($tmpTypeItems[$i] != "") { // the attribute type is deregistered, // remove (hide) the treeView item $gFPEItemParentDir[(int)$tmpTypeItems[$i]] = -1; $gFPEItemShowState[(int)$tmpTypeItems[$i]] = -1; treeView -e -itemVisible $tmpTypeItems[$i] 0 $gFPETreeView; treeView -e -selectItem $tmpTypeItems[$i] false $gFPETreeView; } } } // update global attribute types array clear($gFPEAttrTypes); for ($i = 0; $i < size($curAttrTypes); $i++) { $gFPEAttrTypes[$i] = $curAttrTypes[$i]; } // update "Show" menu buildShowMenu(); // update menu items under "Select" -> "Select By Type" buildSelectByTypeMenu(); // update attribute type list in auto resolve dialog buildARTypesLayout(1); } // Callback for refresh button // global proc FPERefreshCB() { global int $gFPEListType; filePathEditor -refresh; waitCursor -state on; refreshAttrType(); switch ($gFPEListType) { case 0: // by absolute path refreshByAbsPath("", "0"); break; case 1: // by file type refreshByFileType("", "0"); break; } // set visibility of treeView items according to "Show" menu settings setItemVisibilityByShowMenu(); waitCursor -state off; } // Restore selection state when switch list mode. // The selection state has been saved before switch. // proc restoreSelectState() { global string $gFPETreeView; global int $gFPEItemSelectState[]; global string $gFPEFileAttributes[]; int $i; for ($i = 0; $i < size($gFPEItemSelectState); $i++) { // restore selection state for file items if ( size($gFPEFileAttributes[$i]) > 0) { if ($gFPEItemSelectState[$i] == 1) { treeView -e -selectItem $i true $gFPETreeView; } } } // clear the selection state of hierarchy items. // it is enough to only process the "Top" item. other // old hierarchy items do not exist after switch. // $gFPEItemSelectState[0] = 0; updateSelectStateForParentItem(1); } // Prepare the directory and file data for treeView items. // The attribute type data for each attribute is not setup here. // proc initItemData() { global string $gFPEFileAttributes[]; global string $gFPEFileNames[]; global int $gFPEItemResolveState[]; global int $gFPEItemParentDir[]; global int $gFPEItemSelectState[]; global int $gFPEItemShowState[]; // check if the data has been initialized if (size($gFPEItemParentDir) > 0) return; // Top item $gFPEFileAttributes[0] = ""; $gFPEFileNames[0] = ""; $gFPEItemResolveState[0] = 0; $gFPEItemSelectState[0] = 0; $gFPEItemParentDir[0] = -1; $gFPEItemShowState[0] = 1; string $allDirectory[] = `filePathEditor -q -status -relativeNames -listDirectories "" `; int $index = 1; // 0 is for Top item int $parentID; int $i; for ($i = 0; $i < size($allDirectory); $i=$i+2) { $gFPEFileAttributes[$index] = ""; $gFPEFileNames[$index] = $allDirectory[$i]; $gFPEItemResolveState[$index] = $allDirectory[$i+1]; $gFPEItemSelectState[$index] = 0; $gFPEItemParentDir[$index] = 0; $gFPEItemShowState[$index] = 1; $parentID = $index; $index++; // generate all file items under this directory // the order of result string: fileName nodeName.attributeName resolvedState' string $files[] = `filePathEditor -q -withAttribute -status -listFiles $allDirectory[$i]`; int $fi; for ($fi = 0; $fi < size($files); $fi=$fi+3) { $gFPEFileAttributes[$index] = $files[$fi+1]; $gFPEFileNames[$index] = $files[$fi]; $gFPEItemResolveState[$index] = $files[$fi+2]; $gFPEItemSelectState[$index] = 0; $gFPEItemParentDir[$index] = $parentID; $gFPEItemShowState[$index] = 1; $index++; } } } // Create treeView item from scratch when list mode is by directory. // The directory and file data are ready. // proc createItemsByAbsPath() { global string $gFPETreeView; global float $gFPEHalfHighlitColor[]; global string $gFPEFileAttributes[]; global string $gFPEFileNames[]; global int $gFPEItemResolveState[]; global int $gFPEItemParentDir[]; global int $gFPEItemSelectState[]; global int $gFPEItemShowState[]; int $i; for ($i = 1; $i < size($gFPEItemResolveState); $i++) { if ($gFPEItemShowState[$i] == -1) continue; if (size($gFPEFileAttributes[$i]) > 0) { // file entry string $label = $gFPEFileAttributes[$i] + " [" + $gFPEFileNames[$i] + "]"; FPEAddTreeViewItem($i, $label, $gFPEItemParentDir[$i]); setResolveImage($i, $gFPEItemResolveState[$i]); } else if (size($gFPEFileNames[$i]) > 0) { // directory entry FPEAddTreeViewItem($i, $gFPEFileNames[$i], $gFPEItemParentDir[$i]); setResolveImage($i, $gFPEItemResolveState[$i]); // collapse the directory item treeView -e -expandItem $i 0 $gFPETreeView; } //else { skip attribute type entry } } // restore selection state for file items restoreSelectState(); float $itemSelectedColor[] = `treeView -q -item "0" -selectionColor $gFPETreeView`; // half hightlit color for parent item of selected item $gFPEHalfHighlitColor[0] = $itemSelectedColor[0]/2.0; $gFPEHalfHighlitColor[1] = $itemSelectedColor[1]/2.0; $gFPEHalfHighlitColor[2] = $itemSelectedColor[2]/2.0; } // Create treeView item from scratch when list mode is by attribute type. // The directory and file data are ready. But the attrType data is // not ready. attrType item is created lazily. // proc createItemsByFileType() { global string $gFPETreeView; global int $gFPEItemResolveState[]; global int $gFPEItemSelectState[]; global string $gFPEFileAttributes[]; global string $gFPEFileNames[]; global string $gFPEItemAttrType[]; global string $gFPETypeItems[]; global int $gFPEItemParentDir[]; global string $gFPEAttrTypes[]; global int $gFPEItemShowState[]; // get type for each attribute updateTypeForAttributes(); int $i; if (size($gFPETypeItems) == 0) { for ($i = 0; $i < size($gFPEAttrTypes); $i++) { $gFPETypeItems[$i] = ""; } } // indicate if the attribute type item is created int $itemCreated[]; for ($i = 0; $i < size($gFPEAttrTypes); $i++) { $itemCreated[$i] = 0; } for ($i = 0; $i < size($gFPEItemResolveState); $i++) { // process file entry if ($gFPEItemShowState[$i] != -1 && size($gFPEFileAttributes[$i]) > 0) { // get the attrType treeView item string $attrTypeItem; int $nti; for ($nti = 0; $nti < size($gFPEAttrTypes); $nti++) { if ($gFPEAttrTypes[$nti] == $gFPEItemAttrType[$i]) { if ($itemCreated[$nti] == 0) { // create this attribute type item if (size($gFPETypeItems[$nti]) == 0) { // create the attrType treeView item on demand // this is only called when list by type at the first time int $item = size($gFPEItemResolveState); $gFPETypeItems[$nti] = $item; $gFPEFileAttributes[$item] = ""; $gFPEFileNames[$item] = ""; $gFPEItemResolveState[$item] = 0; $gFPEItemSelectState[$item] = 0; $gFPEItemParentDir[$item] = 0; $gFPEItemAttrType[$item] = ""; $gFPEItemShowState[$item] = 1; } string $attrTypeLabel = `filePathEditor -q -typeLabel $gFPEAttrTypes[$nti]`; FPEAddTreeViewItem($gFPETypeItems[$nti], $attrTypeLabel, "0"); treeView -e -expandItem $gFPETypeItems[$nti] 0 $gFPETreeView; $itemCreated[$nti] = 1; } $attrTypeItem = $gFPETypeItems[$nti]; } } // setup the file item string $label = $gFPEFileAttributes[$i] + " [" + $gFPEFileNames[$i] + "]"; FPEAddTreeViewItem($i, $label, $attrTypeItem); setResolveImage($i, $gFPEItemResolveState[$i]); } } // update the resolved state of attrType treeView item updateStateOfAttrTypeItems(); // restore selection state for file items restoreSelectState(); } proc buildTreeView(int $listType) { global string $gFPETreeView; global int $gFPEListType; $gFPEListType = $listType; // The UI hasn't been built yet // waitCursor -state on; // save previous selection info, the selection state of // file items will be reserved after switch. // setSelectionInfo(); // clear treeView treeView -edit -removeAll $gFPETreeView; initItemData(); // create top item, update the resolve number later // FPEAddTreeViewItem("0", "Top", ""); switch ($listType) { case 0: // by absolute path createItemsByAbsPath(); break; case 1: // by file type createItemsByFileType(); break; } // update the resolved number for the "Top" label updateTopItem(); // set visibility of treeView items according to "Show" menu settings setItemVisibilityByShowMenu(); waitCursor -state off; } // list type: // 0: by absolute path // 1: by file type // global proc FPEupdateTreeView(int $listType) { global string $gFPEWindowName; global int $gFPEListType; // Make sure the window exists // if (!`window -exists $gFPEWindowName`) { return; } if ($listType == $gFPEListType) return; buildTreeView($listType); } // Callback when scriptJob event "deleteAll" occurs (New scene or Open file) // global proc FPEClearAll() { global int $gFPEListType; clearDataAndTreeView(); buildTreeView($gFPEListType); } global proc filePathEditorWin() // // Procedure Name: // filePathEditor // // Description: // opens file path editor window. // // Return Value: // None // { global string $gFPEWindowName; global string $gFPETreeView; global string $gFPEAttrTypes[]; // do nothing if the file path editor is visible if (`window -exists $gFPEWindowName` && `window -q -vis $gFPEWindowName`) { setFocus $gFPEWindowName; return; } //force to recollect the file path data clearDataAndTreeView(); // get registered attribute types. // even new attribute type is registed dynamically, this array // will not be updated until the editor is closed. $gFPEAttrTypes = `filePathEditor -q -listRegisteredTypes`; if (!`window -exists $gFPEWindowName`) { // Create the UI // string $fpEditor = (uiRes("m_filePathEditorWin.kFilepathEditor")); if(`about -mac`) { window -title $fpEditor -menuBar true -wh 550 411 $gFPEWindowName; } else { window -title $fpEditor -menuBar true -wh 450 411 $gFPEWindowName; } menu -label (uiRes("m_filePathEditorWin.kOptions")) -tearOff true; radioMenuItemCollection; menuItem -label (uiRes("m_filePathEditorWin.kListByAbsPath")) -radioButton true -command "FPEupdateTreeView 0"; menuItem -label (uiRes("m_filePathEditorWin.kListByFileType")) -radioButton false -command "FPEupdateTreeView 1"; menu -label (uiRes("m_filePathEditorWin.kMainEdit")) -tearOff true; string $label = repathStr(); menuItem -l $label -enable true -command "FPERepathRepathBtnCB 0 0"; menuItem -optionBox true -command "filePathRepathWin"; $label = replaceStr(); menuItem -l $label -enable true -command "FPEReplaceButtonCB 0 0"; menuItem -optionBox true -command "filePathReplaceWin"; $label = autoResolveStr(); menuItem -l $label -enable true -command "FPEAutoResolveCB 0 0"; menuItem -optionBox true -command "filePathAutoResolveWin"; menu -label (uiRes("m_filePathEditorWin.kSelect")) -tearOff true; menuItem -label (uiRes("m_filePathEditorWin.kSelectAll")) -command "FPEselectAllCB"; menuItem -label (uiRes("m_filePathEditorWin.kSelectNone")) -command "FPEselectNoneCB"; menuItem -label (uiRes("m_filePathEditorWin.kSelectUnresolved")) -command "FPEselectUnresolvedCB"; // generate sub items for the types buildSelectByTypeMenu(); setParent -menu ..; menuItem -divider true; menuItem -label (uiRes("m_filePathEditorWin.kInvertSelect")) -command "FPEinvertSelectionCB"; buildShowMenu(); menu -label (uiRes("m_filePathEditorWin.kHelp")) -helpMenu true; menuItem -label (uiRes("m_filePathEditorWin.kHelpOnFPE")) -enableCommandRepeat false -command "showHelp File_Path_Editor"; // This form layout becomes the default layout for the window // formLayout editorLyt; formLayout -e -width 100 -height 100 editorLyt; treeView -numberOfButtons 1 -allowDragAndDrop 0 -allowReparenting 0 -itemDblClickCommand "FPEDummyDblClickCB" -selectCommand "FPETreeItemSelectCB" -selectionChangedCommand "FPEItemSelectChangedCB" -pressCommand 1 "FPEItemButtonClickCB" filePathTreeView; $gFPETreeView = `treeView -q -fullPathName filePathTreeView`; // create buttons. string $refreshButton = `button -label (uiRes("m_filePathEditorWin.kRefreshList")) -command "FPERefreshCB"`; string $repathButton = `button -label (uiRes("m_filePathEditorWin.kRepathFiles")) -command "filePathRepathWin"`; $label = replaceStr(); string $replaceButton = `button -label $label -command "filePathReplaceWin"`; $label = autoResolveStr(); string $autoResButton = `button -label $label -command "filePathAutoResolveWin"`; //layout buttons and tree view formLayout -e -attachForm $gFPETreeView "top" 5 -attachForm $gFPETreeView "left" 5 -attachControl $gFPETreeView "bottom" 5 $refreshButton -attachForm $gFPETreeView "right" 5 -attachNone $refreshButton "top" -attachForm $refreshButton "left" 5 -attachControl $refreshButton "bottom" 5 $autoResButton -attachForm $refreshButton "right" 5 -attachNone $autoResButton "top" -attachForm $autoResButton "right" 5 -attachForm $autoResButton "bottom" 5 -attachPosition $autoResButton "left" 5 70 -attachNone $replaceButton "top" -attachPosition $replaceButton "right" 5 65 -attachForm $replaceButton "bottom" 5 -attachPosition $replaceButton "left" 5 35 -attachNone $repathButton "top" -attachPosition $repathButton "right" 5 30 -attachForm $repathButton "bottom" 5 -attachForm $repathButton "left" 5 editorLyt; setParent ..; scriptJob -uiDeleted $gFPEWindowName "FPEDestroyCB"; scriptJob -parent $gFPEWindowName -event "quitApplication" "FPEDestroyCB"; // update the file path editor when new scene or open scene scriptJob -parent $gFPEWindowName -event "deleteAll" "FPEClearAll"; FPEBuildTreeViewPopupMenu(); } else { // rebuild Show menu always buildShowMenu(); } // Now build and show the contents // buildTreeView(0); showWindow $gFPEWindowName; } //////////////////////////////////////////////// // // Repath Preview dialog // //////////////////////////////////////////////// // create controls for preview window. // after this, user can fill text for the detail section, // and need to set text for summaryText. // proc previewWinPreCreate() { button -label (uiRes("m_filePathEditorWin.kContinue")) -command "layoutDialog -dismiss \"Continue\"" FPEPreviewContButton; string $label = cancelStr(); button -label $label -command "layoutDialog -dismiss \"\"" FPEPreviewCancelButton; text -label (uiRes("m_filePathEditorWin.kWarning")) -font "boldLabelFont" -align "center" WarningText; text -label (uiRes("m_filePathEditorWin.kOperationMsg")) -align "center" HintText; frameLayout -label (uiRes("m_filePathEditorWin.kSummary")) -collapsable false -marginHeight 8 -marginWidth 10 SummaryFrame; columnLayout; text -align "left" summaryText; setParent ..; setParent ..; frameLayout -label (uiRes("m_filePathEditorWin.kDetails")) -collapsable true -marginHeight 8 -marginWidth 10 DetailFrame; scrollLayout -height 300 -horizontalScrollBarThickness 16 -verticalScrollBarThickness 16; columnLayout; } // finish the creation of controls in preview window, and // layout them. // proc previewWinPostCreate(string $form) { setParent ..; setParent ..; setParent ..; formLayout -edit -attachForm WarningText "top" 8 -attachForm WarningText "left" 5 -attachControl WarningText "bottom" 1 HintText -attachForm WarningText "right" 5 -attachNone HintText "top" -attachForm HintText "left" 5 -attachControl HintText "bottom" 15 SummaryFrame -attachForm HintText "right" 5 -attachNone SummaryFrame "top" -attachForm SummaryFrame "left" 5 -attachControl SummaryFrame "bottom" 5 DetailFrame -attachForm SummaryFrame "right" 5 -attachNone DetailFrame "top" -attachForm DetailFrame "left" 5 -attachControl DetailFrame "bottom" 5 FPEPreviewCancelButton -attachForm DetailFrame "right" 5 -attachNone FPEPreviewCancelButton "top" -attachPosition FPEPreviewCancelButton "left" 5 70 -attachForm FPEPreviewCancelButton "bottom" 5 -attachForm FPEPreviewCancelButton "right" 5 -attachNone FPEPreviewContButton "top" -attachForm FPEPreviewContButton "left" 5 -attachForm FPEPreviewContButton "bottom" 5 -attachPosition FPEPreviewContButton "right" 5 30 $form; setParent ..; } global proc FPERepathPreviewWin(string $resPaths, string $fileStatusStr) { global int $gFPEItemResolveState[]; global string $gFPEFileAttributes[]; global string $gFPEFileNames[]; int $items[]; string $mapResult[]; string $fileStatusStrArr[]; int $fileStatus[]; waitCursor -state on; $items = getAllSelectedAttributeItems(); $mapResult = stringToStringArray($resPaths, "%"); $fileStatusStrArr = stringToStringArray($fileStatusStr, "%"); // int $resolvedNum = 0; int $unresolvedNum = 0; int $repathNum = 0; int $i; int $length = size($fileStatusStrArr); for ($i = 0; $i < $length; $i++) { $fileStatus[$i] = (int) $fileStatusStrArr[$i]; if ( $fileStatus[$i] ) $resolvedNum++; else if (($fileStatus[$i] == 0 && $mapResult[$i] != "-") || ($mapResult[$i] == "-" && $gFPEItemResolveState[$items[$i]] == 0)) $unresolvedNum++; if ($mapResult[$i] != "-") $repathNum++; } string $form = `formLayout -numberOfDivisions 100 -width 411`; previewWinPreCreate(); string $summaryStr = "" + $resolvedNum + " " + resolvedMsgStr() + "\n"; $summaryStr += "" + $unresolvedNum + " " + unresolvedMsgStr(); text -e -label $summaryStr summaryText; string $nodesLabel = nodesStr(); // There are three detail sections: // 1, To be resolved: // nodes will be remaped and their target files exist; // 2, Remaining unresolved: // a) nodes will be remaped and their target files are nonexistent; // b) nodes will not be remaped and the original files are nonexistent; // 3, Repathing: // nodes will be remapped. // string $textLabel; $textLabel = toBeResolvedStr() + " - " + $resolvedNum + " " + $nodesLabel; text -label $textLabel; for ($i = 0; $i < $length; $i++) { if ($fileStatus[$i]) { $textLabel = " " + $gFPEFileAttributes[$items[$i]] + " [" + $gFPEFileNames[$items[$i]] + "]"; text -label $textLabel; } } text -label "\n"; $textLabel = remainUnresolvedStr() + " - " + $unresolvedNum + " " + $nodesLabel; text -label $textLabel; for ($i = 0; $i < $length; $i++) { if (($fileStatus[$i] == 0 && $mapResult[$i] != "-") || ($mapResult[$i] == "-" && $gFPEItemResolveState[$items[$i]] == 0)) { $textLabel = " " + $gFPEFileAttributes[$items[$i]] + " [" + $gFPEFileNames[$items[$i]] + "]"; text -label $textLabel; } } text -label "\n"; $textLabel = repathingStr() + " - " + $repathNum + " " + $nodesLabel; text -label $textLabel; for ($i = 0; $i < $length; $i++) { if ($mapResult[$i] != "-") { $textLabel = " " + $gFPEFileAttributes[$items[$i]] + ":"; text -label $textLabel; $textLabel = " " + $mapResult[$i]; text -label $textLabel; text -label "\n"; } } previewWinPostCreate($form); waitCursor -state off; } //////////////////////////////////////////////// // // Repath file dialog and procedures // //////////////////////////////////////////////// // initialize option variables // proc setRepathOptionVars(int $forceFactorySettings) { if ($forceFactorySettings || !`optionVar -exists fpeRepath_recursive`) { optionVar -intValue fpeRepath_recursive 0; } if ($forceFactorySettings || !`optionVar -exists fpeRepath_resolved`) { optionVar -intValue fpeRepath_resolved 0; } if ($forceFactorySettings || !`optionVar -exists fpeRepath_path`) { string $curWS = `workspace -q -openWorkspace`; optionVar -stringValue fpeRepath_path $curWS; } } proc updateRepathUIBySettings() { checkBox -e -value `optionVar -q fpeRepath_recursive` FPERecursiveCheckBox; checkBox -e -value `optionVar -q fpeRepath_resolved` FPEResolvedCheckBox; textFieldButtonGrp -e -text `optionVar -q fpeRepath_path` FPEBrowseButtonGrp; } // reset option variables and update UI // callback for meun item "Edit" -> "Reset Settings" // global proc FPERepathResetSettingsCB() { setRepathOptionVars(1); updateRepathUIBySettings(); } // save option variables according to UI // callback for meun item "Edit" -> "Save Settings" // global proc FPERepathSaveSettingsCB() { optionVar -intValue fpeRepath_recursive `checkBox -q -value FPERecursiveCheckBox`; optionVar -intValue fpeRepath_resolved `checkBox -q -value FPEResolvedCheckBox`; optionVar -stringValue fpeRepath_path `textFieldButtonGrp -q -text FPEBrowseButtonGrp`; } proc createEditMenu(string $winName) { string $saveCmd = "FPE" + $winName + "SaveSettingsCB"; string $resetCmd = "FPE" + $winName + "ResetSettingsCB"; menu -label (uiRes("m_filePathEditorWin.kEdit")) -tearOff true; menuItem -label (uiRes("m_filePathEditorWin.kSaveSettings")) -command $saveCmd; menuItem -label (uiRes("m_filePathEditorWin.kResetSettings")) -command $resetCmd; } proc createHelpMenu(string $winName, string $subHelpMenu) { string $cmd = "showHelp " + $winName + "_win"; menu -label (uiRes("m_filePathEditorWin.kFPEHelp")) -tearOff true; menuItem -label (uiRes("m_filePathEditorWin.kRepathHelpOnFPE")) -command "showHelp File_Path_Editor"; menuItem -label $subHelpMenu -command $cmd; } proc FPECreateRepathWindow() { string $repath = repathStr(); window -menuBar true -sizeable false -height 200 -width 400 -title $repath fpeRepathWin; createEditMenu("Repath"); createHelpMenu("Repath", (uiRes("m_filePathEditorWin.kHelpOnRepath"))); string $form = `formLayout -numberOfDivisions 100`; string $label = browseStr(); textFieldButtonGrp -columnWidth 1 60 -label (uiRes("m_filePathEditorWin.kNewPath")) -buttonLabel $label -buttonCommand "FPEBrowsePathCB" FPEBrowseButtonGrp; checkBox -label (uiRes("m_filePathEditorWin.kRepathRecursive")) FPERecursiveCheckBox; checkBox -label (uiRes("m_filePathEditorWin.kRepathResolved")) FPEResolvedCheckBox; button -label $repath -command "FPERepathRepathBtnCB 0 1" FPERepathButton; $label = previewStr(); button -label $label -command "FPERepathRepathBtnCB 1 1" FPEPreviewButton; $label = cancelStr(); button -label $label -command "FPERepathCancelButtonCB" FPECancelButton; formLayout -e -attachForm FPEBrowseButtonGrp "top" 15 -attachForm FPEBrowseButtonGrp "left" 25 -attachControl FPEBrowseButtonGrp "bottom" 25 FPERecursiveCheckBox -attachForm FPEBrowseButtonGrp "right" 25 -attachNone FPERecursiveCheckBox "top" -attachForm FPERecursiveCheckBox "left" 55 -attachControl FPERecursiveCheckBox "bottom" 5 FPEResolvedCheckBox -attachForm FPERecursiveCheckBox "right" 5 -attachNone FPEResolvedCheckBox "top" -attachForm FPEResolvedCheckBox "left" 55 -attachControl FPEResolvedCheckBox "bottom" 35 FPECancelButton -attachForm FPEResolvedCheckBox "right" 5 -attachNone FPECancelButton "top" -attachForm FPECancelButton "right" 5 -attachForm FPECancelButton "bottom" 5 -attachPosition FPECancelButton "left" 5 75 -attachNone FPEPreviewButton "top" -attachPosition FPEPreviewButton "right" 5 62 -attachForm FPEPreviewButton "bottom" 5 -attachPosition FPEPreviewButton "left" 5 37 -attachNone FPERepathButton "top" -attachForm FPERepathButton "left" 5 -attachForm FPERepathButton "bottom" 5 -attachPosition FPERepathButton "right" 5 25 $form; } global proc filePathRepathWin() { if (!`window -q -exists fpeRepathWin`) { FPECreateRepathWindow(); setRepathOptionVars(0); updateRepathUIBySettings(); } showWindow fpeRepathWin; } proc string getBrowsePath(string $startDir) { string $newPath[]; string $buttonCaption = (uiRes("m_filePathEditorWin.kSet")); if (size($startDir) > 0) { $newPath = `fileDialog2 -fileMode 3 -startingDirectory $startDir -okCaption $buttonCaption`; } else { $newPath = `fileDialog2 -fileMode 3 -okCaption $buttonCaption`; } if (size($newPath) > 0) return $newPath[0]; else return ""; } // callback for "Browser" button // global proc FPEBrowsePathCB() { string $path = `textFieldButtonGrp -q -text FPEBrowseButtonGrp`; string $newPath = getBrowsePath($path); if (size($newPath) > 0) textFieldButtonGrp -e -text $newPath FPEBrowseButtonGrp; } // callback for "Repath" and "Preview" button in repath window // global proc FPERepathRepathBtnCB(int $isPreview, int $saveSettings) { global string $gFPETreeView; global string $gFPEFileAttributes[]; global int $gFPEItemResolveState[]; // save settings if ($saveSettings) { FPERepathSaveSettingsCB(); } string $path = `optionVar -q fpeRepath_path`; if (size($path) == 0) { showWarningDialog( (uiRes("m_filePathEditorWin.kEmptyPath")) ); return; } // get all selected attributes int $items[] = getAllSelectedAttributeItems(); if (size($items) == 0) { showWarningDialog( (uiRes("m_filePathEditorWin.kNoFileSelected")) ); return; } // compose the command and run it // string $command = ""; if (`optionVar -q fpeRepath_recursive`) $command += "-recursive "; if (`optionVar -q fpeRepath_resolved`) $command += "-force "; $command += "-repath \""; $command += encodeString($path); $command += "\""; int $i; for ($i = 0; $i < size($items); $i++) { $command += " " + $gFPEFileAttributes[$items[$i]]; } if ($isPreview) { string $previewCmd = "filePathEditor -preview " + $command; waitCursor -state on; string $remapping[] = `eval $previewCmd`; // pop up preview window string $title = previewTitleStr(); string $resPaths[]; string $fileStatus[]; int $length = size($remapping); int $j = 0; for ($i = 0; $i < $length - 1; $i += 2) { $resPaths[$j] = (size($remapping[$i]) == 0) ? "-" : $remapping[$i]; $fileStatus[$j] = $remapping[$i + 1]; $j++; } string $resPathsStr = stringArrayToString($resPaths, "%"); string $fileStatusStr = stringArrayToString($fileStatus, "%"); waitCursor -state off; string $res = `layoutDialog -title $title -ui ("FPERepathPreviewWin(\"" + $resPathsStr + "\", \"" + $fileStatusStr + "\")")`; if ($res != "Continue") { // Preview is cancelled, back to repath window setFocus fpeRepathWin; return; } } // close the repath window and continue repath FPERepathCancelButtonCB(); $command = "filePathEditor " + $command; waitCursor -state on; int $changed = `eval $command`; waitCursor -state off; // update the treeview if there are any repath occurred if ($changed == 1) FPERefreshCB(); } // callback for "Cancel" button in repath window // global proc FPERepathCancelButtonCB() { // close repath dialog when "Cancel" button is down if (`window -q -exists fpeRepathWin`) { // QT 4.8.2 crashed when deleteUI window on mac(4.7.1 is ok) // so hide the window instead of deleting it. window -edit -vis 0 fpeRepathWin; } } ///////////////////////////////////////////////////////////////////////////// // // String Search and Replace dialog and procedures // //////////////////////////////////////////////////////////////////////////// global proc FPEReplacePreviewWin(string $newPathsStr, string $fileStatusStr, string $newNodesStr) { global int $gFPEItemResolveState[]; global string $gFPEFileAttributes[]; global string $gFPEFileNames[]; int $items[]; string $newPaths[]; string $fileStatus[]; string $newNodes[]; waitCursor -state on; $items = getAllSelectedAttributeItems(); $newPaths = stringToStringArray($newPathsStr, "%"); $fileStatus= stringToStringArray($fileStatusStr, "%"); $newNodes = stringToStringArray($newNodesStr, "%"); string $form = `formLayout -numberOfDivisions 100 -width 411`; previewWinPreCreate(); // There are four detail sections: // 1, Renamed nodes: // nodes will be renamed; // 2, Renamed file paths: // filepaths will be replaced. // 3, To be resolved: // filepaths will be replaced and their target files exist; // 4, Remaining unresolved: // a) filepaths will be replaced and their target files are nonexistent; // b) filepaths will not be replaced and the original files are nonexistent; // string $summaryStr; int $tempNum; // Renamed Nodes // string $textLabel; $tempNum = 0; int $i; for ($i = 0; $i < size($newNodes); $i++) { if ($newNodes[$i] != "-") { string $orgName = `plugNode $gFPEFileAttributes[$items[$i]]`; $textLabel += " " + $orgName + (uiRes("m_filePathEditorWin.kTo")) + $newNodes[$i] + "\n"; $tempNum++; } } string $label = (uiRes("m_filePathEditorWin.kRenamedNodes")) + " - " + $tempNum + " " + ($tempNum > 1 ? nodesStr() : nodeStr()); text -label $label; text -align "left" -label $textLabel; $summaryStr = $tempNum + " " + (uiRes("m_filePathEditorWin.kNodeRenamed")) + "\n"; // Renamed FilePaths // $tempNum = 0; $textLabel = ""; for ($i = 0; $i < size($newPaths); $i++) { if ($newPaths[$i] != "-") { $textLabel += " " + $gFPEFileAttributes[$items[$i]]; $textLabel += "\n"; $textLabel += " " + getFullname($items[$i]); $textLabel += "\n"; $textLabel += " " + $newPaths[$i]; $textLabel += "\n"; $tempNum++; } } $label = (uiRes("m_filePathEditorWin.kRenamedFile")) + " - " + $tempNum + " "; $label += $tempNum > 1 ? pathsStr() : pathStr(); text -label $label; text -align "left" -label $textLabel; $summaryStr += $tempNum + " " + (uiRes("m_filePathEditorWin.kPathRenamed")) + "\n\n"; // To Be Resolved & Remaining Unresolved int $resolvedNum = 0; int $unresolvedNum = 0; string $resolvedLabel; string $unresolvedLabel; for ($i = 0; $i < size($fileStatus); $i++) { if ($newPaths[$i] != "-") { if ((int)$fileStatus[$i] == 1) { $resolvedLabel += " " + getItemLabel($items[$i]) + "\n"; $resolvedNum++; } else { $unresolvedLabel += " " + getItemLabel($items[$i]) + "\n"; $unresolvedNum++; } } else if ($gFPEItemResolveState[$items[$i]] == 0) { $unresolvedLabel += " " + getItemLabel($items[$i]) + "\n"; $unresolvedNum++; } } $label = toBeResolvedStr() + " - " + $resolvedNum + " " + ($resolvedNum > 1 ? pathsStr() : pathStr()); text -label $label; text -align "left" -label $resolvedLabel; $label = remainUnresolvedStr() + " - " + $unresolvedNum + " " + ($unresolvedNum > 1 ? pathsStr() : pathStr()); text -label $label; text -align "left" -label $unresolvedLabel; $summaryStr += $resolvedNum + " " + resolvedMsgStr() + "\n"; $summaryStr += $unresolvedNum + " " + unresolvedMsgStr() + "\n"; text -e -label $summaryStr summaryText; previewWinPostCreate($form); waitCursor -state off; } // initialize option variables for search & replace dialog // proc setReplaceOptionVars(int $forceFactorySettings) { if ($forceFactorySettings || !`optionVar -exists fpeReplace_affected`) { optionVar -intValue fpeReplace_affected 2; } if ($forceFactorySettings || !`optionVar -exists fpeReplace_search`) { optionVar -stringValue fpeReplace_search ""; } if ($forceFactorySettings || !`optionVar -exists fpeReplace_replace`) { optionVar -stringValue fpeReplace_replace ""; } if ($forceFactorySettings || !`optionVar -exists fpeReplace_instance`) { optionVar -intValue fpeReplace_instance 1; } } proc updateReplaceUIBySettings() { optionMenu -e -select `optionVar -q fpeReplace_affected` affectedMenu; textField -e -text `optionVar -q fpeReplace_search` searchText; textField -e -text `optionVar -q fpeReplace_replace` replaceText; radioButtonGrp -e -select `optionVar -q fpeReplace_instance` instanceMode; } // reset option variables and update UI for search & replace dialog // callback for meun item "Edit" -> "Reset Settings" // global proc FPEReplaceResetSettingsCB() { setReplaceOptionVars(1); updateReplaceUIBySettings(); } // save option variables according to UI for search & replace dialog // callback for meun item "Edit" -> "Save Settings" // global proc FPEReplaceSaveSettingsCB() { optionVar -intValue fpeReplace_affected `optionMenu -q -select affectedMenu`; optionVar -stringValue fpeReplace_search `textField -q -text searchText`; optionVar -stringValue fpeReplace_replace `textField -q -text replaceText`; optionVar -intValue fpeReplace_instance `radioButtonGrp -q -select instanceMode`; } proc FPECreateReplaceWindow() { string $replaceStr = replaceStr(); window -menuBar true -sizeable false -height 250 -width 400 -title $replaceStr fpeReplaceWin; createEditMenu("Replace"); createHelpMenu("Replace", (uiRes("m_filePathEditorWin.kHelpOnReplace"))); string $form = `formLayout -numberOfDivisions 100`; text -label (uiRes("m_filePathEditorWin.kAffectedString")) affectedText; optionMenu affectedMenu; menuItem -en 1 -label (uiRes("m_filePathEditorWin.kNodeName")); menuItem -en 1 -label (uiRes("m_filePathEditorWin.kDirectoryPath")); menuItem -en 1 -label (uiRes("m_filePathEditorWin.kFilename")); menuItem -en 1 -label (uiRes("m_filePathEditorWin.kFullFilepath")); menuItem -en 1 -label (uiRes("m_filePathEditorWin.kAll")); text -label (uiRes("m_filePathEditorWin.kSearchString")) searchLabel; textField searchText; text -label (uiRes("m_filePathEditorWin.kReplaceString")) replaceLabel; textField replaceText; radioButtonGrp -numberOfRadioButtons 2 -label1 (uiRes("m_filePathEditorWin.kReplaceFirst")) -label2 (uiRes("m_filePathEditorWin.kReplaceEvery")) -columnWidth 1 140 -columnWidth 2 80 -columnAttach 2 "left" 10 instanceMode; button -label (uiRes("m_filePathEditorWin.kReplace")) -command "FPEReplaceButtonCB 1 0" replaceBtn; string $label = previewStr(); button -label $label -command "FPEReplaceButtonCB 1 1" previewBtn; $label = cancelStr(); button -label $label -command "FPEReplaceCancelButtonCB" cancelBtn; textField -edit searchText; textField -edit replaceText; formLayout -e -attachForm affectedText "top" 35 -attachNone affectedText "left" -attachPosition affectedText "right" 5 30 -attachForm affectedMenu "top" 35 -attachPosition affectedMenu "left" 5 30 -attachForm affectedMenu "right" 40 -attachControl searchLabel "top" 30 affectedText -attachNone searchLabel "left" -attachPosition searchLabel "right" 5 30 -attachControl searchText "top" 30 affectedText -attachPosition searchText "left" 5 30 -attachForm searchText "right" 40 -attachControl replaceLabel "top" 25 searchLabel -attachNone replaceLabel "left" -attachPosition replaceLabel "right" 5 30 -attachControl replaceText "top" 25 searchLabel -attachPosition replaceText "left" 5 30 -attachForm replaceText "right" 40 -attachControl instanceMode "top" 30 replaceLabel -attachPosition instanceMode "left" 5 10 -attachForm instanceMode "right" 15 -attachNone cancelBtn "top" -attachForm cancelBtn "right" 5 -attachForm cancelBtn "bottom" 8 -attachPosition cancelBtn "left" 5 75 -attachNone previewBtn "top" -attachPosition previewBtn "right" 5 62 -attachForm previewBtn "bottom" 8 -attachPosition previewBtn "left" 5 37 -attachNone replaceBtn "top" -attachForm replaceBtn "left" 5 -attachForm replaceBtn "bottom" 8 -attachPosition replaceBtn "right" 5 25 $form; } global proc filePathReplaceWin() { if (!`window -q -exists fpeReplaceWin`) { FPECreateReplaceWindow(); setReplaceOptionVars(0); updateReplaceUIBySettings(); } showWindow fpeReplaceWin; } proc string replacePreviewNodeName(int $item, string $searchStr, string $replaceStr, int $replaceMode) { global string $gFPEFileAttributes[]; string $nodeName; string $newName; $nodeName = `plugNode $gFPEFileAttributes[$item]`; // strip off any path and namespace info // string $pathless = match("[a-zA-Z0-9_]*$", $nodeName); if ($replaceMode == 1) // replace the first instance { $newName = `substitute $searchStr $pathless $replaceStr`; } else // replace all instance { $newName = `substituteAllString $pathless $searchStr $replaceStr`; } if ($newName == $pathless) // no string replacement { $newName = "-"; } else if ($nodeName != $pathless) // has namespace, reserve the namespace { string $ns = substring($nodeName, 1, size($nodeName) - size($pathless)); $newName = $ns + $newName; } return $newName; } proc string[] replacePreviewNodeNames(int $items[], string $searchStr, string $replaceStr, int $replaceMode) { string $newNames[]; int $i; for ($i = 0; $i < size($items); $i++) { $newNames[$i] = replacePreviewNodeName($items[$i], $searchStr, $replaceStr, $replaceMode); } return $newNames; } // Search and replace node name according to dialog settings // Return true if there is any node renamed. // proc int replaceNodeNames(int $items[], string $searchStr, string $replaceStr, int $replaceMode) { global string $gFPEFileAttributes[]; string $newNames[] = replacePreviewNodeNames($items, $searchStr, $replaceStr, $replaceMode); int $replaced = 0; string $nodeName; int $i; for ($i = 0; $i < size($newNames); $i++) { if ($newNames[$i] != "-") { $nodeName = `plugNode $gFPEFileAttributes[$items[$i]]`; // rename the node // rename will fail for reference node, locked node, so // catch the error. if (catch(`rename $nodeName $newNames[$i]`) == 0) { $replaced = 1; } } } return $replaced; } // callback for "Replace" button in search & replace window // global proc FPEReplaceButtonCB(int $saveSettings, int $isPreview) { global string $gFPEFileAttributes[]; // save UI settings if ($saveSettings) { FPEReplaceSaveSettingsCB(); } // get setting values int $affectedType = `optionVar -q fpeReplace_affected`; string $searchStr = `optionVar -q fpeReplace_search`; if (size($searchStr) == 0) { showWarningDialog( (uiRes("m_filePathEditorWin.kEmptySearchString")) ); return; } string $replaceStr = `optionVar -q fpeReplace_replace`; int $replaceInstance = `optionVar -q fpeReplace_instance`; // get selected items int $items[] = getAllSelectedAttributeItems(); if (size($items) == 0) { showWarningDialog( (uiRes("m_filePathEditorWin.kNoFileSelectedForReplace")) ); return; } string $cmd; if ($affectedType != 1) { $cmd = " -replaceField "; switch ($affectedType) { case 2: // Directory Path $cmd += "\"pathOnly\""; break; case 3: // Filename $cmd += "\"nameOnly\""; break; case 4: // Full Filepath case 5: // All $cmd += "\"fullPath\""; break; } $cmd += " -replaceString \""; $cmd += encodeString($searchStr); $cmd += "\" \""; $cmd += encodeString($replaceStr); $cmd += "\" -replaceAll "; $cmd += $replaceInstance == 2 ? "true" : "false"; int $i; for ($i = 0; $i < size($items); $i++) { $cmd += " " + $gFPEFileAttributes[$items[$i]]; } } if ($isPreview) { string $newPaths[]; string $fileStatus[]; string $newNodeNames[]; waitCursor -state on; if ($affectedType != 1) { string $previewCmd = "filePathEditor -preview " + $cmd; string $replacing[] = `eval $previewCmd`; int $length = size($replacing); int $j = 0; for ($i = 0; $i < $length - 1; $i += 2) { $newPaths[$j] = (size($replacing[$i]) == 0) ? "-" : $replacing[$i]; $fileStatus[$j] = $replacing[$i + 1]; $j++; } } int $doNodeReplace = 0; if ($affectedType == 5) { if ( $replaceInstance == 1) { for ($i = 0; $i < size($newPaths); $i++) { // check if there is filename replaced if ($newPaths[$i] != "-") { $newNodeNames[$i] = "-"; } else { $newNodeNames[$i] = replacePreviewNodeName($items[$i], $searchStr, $replaceStr, $replaceInstance); } } } else { $doNodeReplace = 1; } } // replace string for Node Name if ($affectedType == 1 || $doNodeReplace) { $newNodeNames = replacePreviewNodeNames($items, $searchStr, $replaceStr, $replaceInstance); } string $newPathsStr = stringArrayToString($newPaths, "%"); string $fileStatusStr = stringArrayToString($fileStatus, "%"); string $newNodesStr = stringArrayToString($newNodeNames, "%"); waitCursor -state off; string $title = previewTitleStr(); string $res = `layoutDialog -title $title -ui("FPEReplacePreviewWin(\"" + $newPathsStr + "\", \"" + $fileStatusStr + "\", \"" + $newNodesStr + "\")")`; if ($res != "Continue") { // Preview is cancelled, back to replace window setFocus fpeReplaceWin; return; } } // hide the search & replace dialog FPEReplaceCancelButtonCB(); // do replace action // int $replaced = 0; if ($affectedType != 1) { string $command = "filePathEditor " + $cmd; $replaced = `eval $command`; } // replace string for Node Name if ($affectedType == 1 || ($affectedType == 5 && ($replaced == 0 || $replaceInstance == 2)) ) { $replaced += replaceNodeNames($items, $searchStr, $replaceStr, $replaceInstance); } // refresh treeView // Even the affected string is "Node Name", also need to refresh the // treeView because one node modified may be listed multiple times // with different file attributes // if ($replaced) { FPERefreshCB(); } } // callback for "Cancel" button in search & replace window // global proc FPEReplaceCancelButtonCB() { // hide replace dialog when "Cancel" button is down if (`window -q -exists fpeReplaceWin`) { window -edit -vis 0 fpeReplaceWin; } } //////////////////////////////////////////////////////////////////////////// // // Auto Resolve dialog and procedures // //////////////////////////////////////////////////////////////////////////// // filter items by attribute types checked in auto-resolve dialog // proc int[] filterItemsByAttrType(int $items[]) { global string $gFPEAttrTypes[]; global string $gFPEItemAttrType[]; // 1, get attribute types checked in UI string $checkedTypes[]; string $types[] = stringToStringArray(`optionVar -q fpeAutoResolve_types`, "%"); int $i; int $j; int $index = 0; for ($i = 0; $i < size($gFPEAttrTypes); $i++) { int $checked = true; for ($j = 0; $j < size($types); $j++) { if ($types[$j] == $gFPEAttrTypes[$i]) { $checked = false; break; } } if ($checked) { $checkedTypes[$index] = $gFPEAttrTypes[$i]; $index++; } } // 2, filter selected items int $matchedItems[]; $index = 0; for ($i = 0; $i < size($items); $i++) { for ($j = 0; $j < size($checkedTypes); $j++) { if ($gFPEItemAttrType[$items[$i]] == $checkedTypes[$j]) { $matchedItems[$index] = $items[$i]; $index++; break; } } } return $matchedItems; } // preview window for auto resolve // global proc FPEAutoResPreviewWin(string $srcCopiedPathsStr, string $repathStr, int $ignoreResolvedItem) { global int $gFPEItemResolveState[]; global string $gFPEFileAttributes[]; global string $gFPEFileNames[]; string $srcCopiedPaths[]; string $newPaths[]; waitCursor -state on; int $items[] = getAllSelectedAttributeItems(); int $matchedItems[] = filterItemsByAttrType($items); $newPaths = stringToStringArray($repathStr, "%"); $srcCopiedPaths = stringToStringArray($srcCopiedPathsStr, "%"); string $form = `formLayout -numberOfDivisions 100 -width 411`; previewWinPreCreate(); // There are four detail sections: // 1, Copied Files: // // 2, To be resolved: // filepaths will be replaced and their target files exist; // 3, Remaining unresolved: // // 4, Repathing: // string $summaryStr; int $tempNum; string $dstPath = `optionVar -q fpeAutoResolve_filePath`; // Copied Files // string $textLabel; $tempNum = 0; int $i; int $j = -1; if (size($srcCopiedPaths) > 0) { for ($i = 0; $i < size($matchedItems); $i++) { if ($ignoreResolvedItem == 1 && $gFPEItemResolveState[$matchedItems[$i]] == 1) continue; $j++; if ($srcCopiedPaths[$j] == "-") continue; $textLabel += $gFPEFileAttributes[$matchedItems[$i]] + "\n"; $textLabel += " " + (uiRes("m_filePathEditorWin.kFrom")) + " " + $srcCopiedPaths[$j] + "\n"; $textLabel += " " + (uiRes("m_filePathEditorWin.kTo_")) + " " + $dstPath + "/" + $gFPEFileNames[$matchedItems[$i]] + "\n"; $tempNum++; } } string $fileStr = (uiRes("m_filePathEditorWin.kFile")); string $filesStr = (uiRes("m_filePathEditorWin.kFiles")); string $label = (uiRes("m_filePathEditorWin.kCopiedFiles")) + " - " + $tempNum + ($tempNum > 1 ? $filesStr : $fileStr); text -label $label; text -align "left" -label $textLabel; $summaryStr = $tempNum + " " + (uiRes("m_filePathEditorWin.kFileCopied")) + "\n"; // To Be Resolved & Remaining Unresolved & Repathing // int $resolvedNum = 0; int $unresolvedNum = 0; string $resolvedLabel; string $unresolvedLabel; string $repathingLabel; $j = 0; for ($i = 0; $i < size($matchedItems); $i++) { if ($ignoreResolvedItem == 1 && $gFPEItemResolveState[$matchedItems[$i]] == 1) continue; int $resolved = 1; if (size($srcCopiedPaths) > 0) { if ($srcCopiedPaths[$j] == "-") { $resolved = 0; } } else // size($newPaths) > 0 { if ($newPaths[$j] == "-") { $resolved = 0; } } if ($resolved) { $resolvedLabel += " " + getItemLabel($matchedItems[$i]) + "\n"; $repathingLabel += " " + $gFPEFileAttributes[$matchedItems[$i]] + "\n"; if (size($srcCopiedPaths) > 0) { $repathingLabel += " " + $dstPath + "/" + $gFPEFileNames[$matchedItems[$i]] + "\n"; } else { $repathingLabel += " " + $newPaths[$j] + "\n"; } $resolvedNum++; } else { $unresolvedLabel += " " + getItemLabel($matchedItems[$i]) + "\n"; $unresolvedNum++; } $j++; } $label = toBeResolvedStr() + " - " + $resolvedNum + ($resolvedNum > 1 ? pathsStr() : pathStr()); text -label $label; text -align "left" -label $resolvedLabel; $label = remainUnresolvedStr() + " - " + $unresolvedNum + ($unresolvedNum > 1 ? pathsStr() : pathStr()); text -label $label; text -align "left" -label $unresolvedLabel; $label = repathingStr() + " - " + $resolvedNum + ($resolvedNum > 1 ? $filesStr : $fileStr); text -label $label; text -align "left" -label $repathingLabel; $summaryStr += $resolvedNum + " " + resolvedMsgStr() + "\n"; $summaryStr += $unresolvedNum + " " + unresolvedMsgStr() + "\n"; $summaryStr += $resolvedNum + " " + (uiRes("m_filePathEditorWin.kBeRepathing")) + "\n"; text -e -label $summaryStr summaryText; previewWinPostCreate($form); waitCursor -state off; } // initialize option variables for auto resolve dialog // proc setAutoResolveOptionVars(int $forceFactorySettings) { if ($forceFactorySettings || !`optionVar -exists fpeAutoResolve_basePath`) { optionVar -stringValue fpeAutoResolve_basePath ""; } if ($forceFactorySettings || !`optionVar -exists fpeAutoResolve_types`) { optionVar -stringValue fpeAutoResolve_types ""; } if ($forceFactorySettings || !`optionVar -exists fpeAutoResolve_copy`) { optionVar -intValue fpeAutoResolve_copy 1; } if ($forceFactorySettings || !`optionVar -exists fpeAutoResolve_filePath`) { optionVar -stringValue fpeAutoResolve_filePath ""; } if ($forceFactorySettings || !`optionVar -exists fpeAutoResolve_copyRadio`) { optionVar -intValue fpeAutoResolve_copyRadio 1; } if ($forceFactorySettings || !`optionVar -exists fpeAutoResolve_overwrite`) { optionVar -intValue fpeAutoResolve_overwrite 1; } } proc updateAutoResolveUIBySettings() { textField -e -text `optionVar -q fpeAutoResolve_basePath` basePathText; updateARTypesUIBySettings(); checkBox -e -value `optionVar -q fpeAutoResolve_copy` copyCheckBox; textField -e -text `optionVar -q fpeAutoResolve_filePath` copyPathText; radioButtonGrp -e -select `optionVar -q fpeAutoResolve_copyRadio` copyRadioGrp; checkBox -e -value `optionVar -q fpeAutoResolve_overwrite` overwriteCheckBox; // setup UI control's state according to state of copyCheckBox FPECopyCheckBoxCB(); } // reset option variables and update UI for auto resolve dialog // callback for meun item "Edit" -> "Reset Settings" // global proc FPEAutoResolveResetSettingsCB() { setAutoResolveOptionVars(1); updateAutoResolveUIBySettings(); } // save option variables according to UI for auto resolve dialog // callback for meun item "Edit" -> "Save Settings" // global proc FPEAutoResolveSaveSettingsCB() { global string $gFPEAttrTypes[]; optionVar -stringValue fpeAutoResolve_basePath `textField -q -text basePathText`; // save the state for check boxes of registered types string $types = ""; string $checkBoxes[] = `columnLayout -q -childArray FPEARTypeColumnLayout`; int $i; for ($i = 0; $i < size($gFPEAttrTypes); $i++) { if (! `checkBox -q -value $checkBoxes[$i]`) { if ($types == "") $types = $gFPEAttrTypes[$i]; else $types += "%" + $gFPEAttrTypes[$i]; } } optionVar -stringValue fpeAutoResolve_types $types; optionVar -intValue fpeAutoResolve_copy `checkBox -q -value copyCheckBox`; optionVar -stringValue fpeAutoResolve_filePath `textField -q -text copyPathText`; optionVar -intValue fpeAutoResolve_copyRadio `radioButtonGrp -q -select copyRadioGrp`; optionVar -intValue fpeAutoResolve_overwrite `checkBox -q -value overwriteCheckBox`; } proc createAutoResolveWin() { global string $gFPEAttrTypes[]; string $browseLabel = browseStr(); string $autoResolveLabel = autoResolveStr(); window -menuBar true -sizeable false -width 400 -height 450 -title $autoResolveLabel fpeAutoResolveWin; createEditMenu("AutoResolve"); createHelpMenu("AutoResolve", (uiRes("m_filePathEditorWin.kHelpOnAutoResolve"))); string $form = `formLayout -numberOfDivisions 100`; text -label (uiRes("m_filePathEditorWin.kBasePath")) basePathLabel; textField basePathText; button -label $browseLabel -command "FPEBrowseAutoResPathCB basePathText" browseBtn1; text -label (uiRes("m_filePathEditorWin.kResolveType")) resolveLabel; // list all registered node types, put into a columnLayout scrollLayout -height 120 -width 200 -verticalScrollBarThickness 16 -horizontalScrollBarThickness 16 FPEARTypeLayout; buildARTypesLayout(0); setParent ..; setParent ..; text -label (uiRes("m_filePathEditorWin.kCopyFiles")) copyLabel; checkBox -label "" -changeCommand "FPECopyCheckBoxCB" copyCheckBox; text -label (uiRes("m_filePathEditorWin.kDestination")) destLabel; textField copyPathText; button -label $browseLabel -command "FPEBrowseAutoResPathCB copyPathText" browseBtn2; radioButtonGrp -numberOfRadioButtons 2 -vertical -label1 (uiRes("m_filePathEditorWin.kRepathAll")) -label2 (uiRes("m_filePathEditorWin.kRepathNewly")) copyRadioGrp; checkBox -label (uiRes("m_filePathEditorWin.kOverwrite")) overwriteCheckBox; button -label $autoResolveLabel -command "FPEAutoResolveCB 0 1" autoResolveBtn; button -label (uiRes("m_filePathEditorWin.kAutoResPreview")) -command "FPEAutoResolveCB 1 1" autoResPreviewBtn; button -label (uiRes("m_filePathEditorWin.kAutoResCancel")) -command "FPEAutoResCancelButtonCB" cancelBtn; formLayout -e -attachForm basePathLabel "top" 22 -attachNone basePathLabel "left" -attachPosition basePathLabel "right" 0 20 -attachForm basePathText "top" 20 -attachPosition basePathText "left" 5 20 -attachPosition basePathText "right" 5 70 -attachForm browseBtn1 "top" 20 -attachPosition browseBtn1 "left" 5 70 -attachPosition browseBtn1 "right" 5 85 -attachControl resolveLabel "top" 22 basePathLabel -attachNone resolveLabel "left" -attachPosition resolveLabel "right" 0 20 -attachControl FPEARTypeLayout "top" 20 basePathLabel -attachPosition FPEARTypeLayout "left" 5 20 -attachControl copyLabel "top" 25 FPEARTypeLayout -attachNone copyLabel "left" -attachPosition copyLabel "right" 0 20 -attachControl copyCheckBox "top" 25 FPEARTypeLayout -attachPosition copyCheckBox "left" 5 20 -attachControl destLabel "top" 12 copyCheckBox -attachPosition destLabel "right" 5 30 -attachControl copyPathText "top" 10 copyCheckBox -attachPosition copyPathText "left" 5 30 -attachPosition copyPathText "right" 5 80 -attachControl browseBtn2 "top" 10 copyCheckBox -attachPosition browseBtn2 "left" 5 80 -attachPosition browseBtn2 "right" 5 95 -attachControl copyRadioGrp "top" 10 copyPathText -attachPosition copyRadioGrp "left" 5 20 -attachControl overwriteCheckBox "top" 10 copyRadioGrp -attachPosition overwriteCheckBox "left" 5 20 -attachPosition cancelBtn "left" 5 75 -attachForm cancelBtn "right" 10 -attachForm cancelBtn "bottom" 10 -attachNone autoResPreviewBtn "top" -attachPosition autoResPreviewBtn "right" 7 62 -attachForm autoResPreviewBtn "bottom" 10 -attachPosition autoResPreviewBtn "left" 7 37 -attachForm autoResolveBtn "left" 10 -attachPosition autoResolveBtn "right" 5 25 -attachForm autoResolveBtn "bottom" 10 $form; } global proc filePathAutoResolveWin() { if (!`window -q -exists fpeAutoResolveWin`) { createAutoResolveWin(); setAutoResolveOptionVars(0); updateAutoResolveUIBySettings(); } showWindow fpeAutoResolveWin; } // callback for "Cancel" button in auto resolve window // global proc FPEAutoResCancelButtonCB() { if (`window -q -exists fpeAutoResolveWin`) { deleteUI -window fpeAutoResolveWin; } } // callback for "Browse" button to get a path // global proc FPEBrowseAutoResPathCB(string $tf) { string $startPath = `textField -q -text $tf`; string $newPath = getBrowsePath($startPath); if (size($newPath) > 0) textField -e -text $newPath $tf; } // callback of "Copy" checkbox when change its state // global proc FPECopyCheckBoxCB() { int $state = `checkBox -q -value copyCheckBox`; text -e -enable $state destLabel; textField -e -enable $state copyPathText; button -e -enable $state browseBtn2; radioButtonGrp -e -enable $state copyRadioGrp; checkBox -e -enable $state overwriteCheckBox; } // do auto resolve according to UI settings // global proc FPEAutoResolveCB(int $isPreview, int $saveSettings) { global int $gFPEItemResolveState[]; global string $gFPEFileAttributes[]; // save UI settings if ($saveSettings) FPEAutoResolveSaveSettingsCB(); string $basePath = `optionVar -q fpeAutoResolve_basePath`; if (size($basePath) == 0) { showWarningDialog( (uiRes("m_filePathEditorWin.kEmptyBasePath")) ); return; } // get selected items int $items[] = getAllSelectedAttributeItems(); if (size($items) == 0) { showWarningDialog( (uiRes("m_filePathEditorWin.kNoFileSelectedForAutoRes")) ); return; } int $matchedItems[] = filterItemsByAttrType($items); if (size($matchedItems) == 0) { showWarningDialog( (uiRes("m_filePathEditorWin.kNoMatchedFileSelected")) ); return; } int $ignoreResolvedItem = 1; int $needRefresh = 0; int $doCopy = `optionVar -q fpeAutoResolve_copy`; if ($doCopy) { string $dstPath = `optionVar -q fpeAutoResolve_filePath`; if (size($dstPath) == 0) { showWarningDialog( (uiRes("m_filePathEditorWin.kEmptyDestPath")) ); return; } string $command = "-copyAndRepath \""; $command += encodeString($basePath); $command += "\" \""; $command += encodeString($dstPath); $command += "\""; if ( `optionVar -q fpeAutoResolve_overwrite`) $command += "-force "; int $copyStatus = `optionVar -q fpeAutoResolve_copyRadio`; if ($copyStatus == 1) $ignoreResolvedItem = 0; int $noItemToProcess = 1; for ($i = 0; $i < size($matchedItems); $i++) { if ($copyStatus == 1 || $gFPEItemResolveState[$matchedItems[$i]] == 0) { $command += " " + $gFPEFileAttributes[$matchedItems[$i]]; $noItemToProcess = 0; } } if ($isPreview) { string $previewCmd = "filePathEditor -preview " + $command; waitCursor -state on; string $srcCopiedFiles[]; if ($noItemToProcess == 0) $srcCopiedFiles = `eval $previewCmd`; // pop up preview window string $title = previewTitleStr(); for ($i = 0; $i < size($srcCopiedFiles); $i++) { if ($srcCopiedFiles[$i] == "") $srcCopiedFiles[$i] = "-"; } string $copiedStr = stringArrayToString($srcCopiedFiles, "%"); waitCursor -state off; string $res = `layoutDialog -title $title -ui ("FPEAutoResPreviewWin(\"" + $copiedStr + "\", \"\", " + $ignoreResolvedItem + ")")`; if ($res != "Continue") { // Preview is cancelled, back to repath window setFocus fpeAutoResolveWin; return; } } // close the auto-resolve window and continue FPEAutoResCancelButtonCB(); $command = "filePathEditor " + $command; waitCursor -state on; if ($noItemToProcess == 0) $needRefresh = `eval $command`; waitCursor -state off; } else // do repath simply { // compose the command and run it // string $command = "-recursive "; $command += "-repath \""; $command += encodeString($basePath); $command += "\""; int $hasUnresolvedItem = 0; for ($i = 0; $i < size($matchedItems); $i++) { // ignore resolved attribute file if ($gFPEItemResolveState[$matchedItems[$i]] == 0) { $command += " " + $gFPEFileAttributes[$matchedItems[$i]]; $hasUnresolvedItem = 1; } } if ($isPreview) { string $previewCmd = "filePathEditor -preview " + $command; waitCursor -state on; string $remapping[]; if ($hasUnresolvedItem) $remapping = `eval $previewCmd`; // pop up preview window string $title = previewTitleStr(); string $resPaths[]; int $length = size($remapping); int $j = 0; for ($i = 0; $i < $length - 1; $i += 2) { $resPaths[$j] = (size($remapping[$i]) == 0) ? "-" : $remapping[$i]; $j++; // ignore the returned file status because all remapped path // should be resolved when auto resolve } string $resPathsStr = stringArrayToString($resPaths, "%"); waitCursor -state off; string $res = `layoutDialog -title $title -ui ("FPEAutoResPreviewWin(\"\", \"" + $resPathsStr + "\", " + $ignoreResolvedItem + ")")`; if ($res != "Continue") { // Preview is cancelled, back to repath window setFocus fpeAutoResolveWin; return; } } // close the auto-resolve window and continue FPEAutoResCancelButtonCB(); $command = "filePathEditor " + $command; waitCursor -state on; if ($hasUnresolvedItem) $needRefresh = `eval $command`; waitCursor -state off; } if ($needRefresh == 1) FPERefreshCB(); }