Geant4 Cross Reference |
1 // ******************************************* 1 // ******************************************************************** 2 // * License and Disclaimer 2 // * License and Disclaimer * 3 // * 3 // * * 4 // * The Geant4 software is copyright of th 4 // * The Geant4 software is copyright of the Copyright Holders of * 5 // * the Geant4 Collaboration. It is provided 5 // * the Geant4 Collaboration. It is provided under the terms and * 6 // * conditions of the Geant4 Software License 6 // * conditions of the Geant4 Software License, included in the file * 7 // * LICENSE and available at http://cern.ch/ 7 // * LICENSE and available at http://cern.ch/geant4/license . These * 8 // * include a list of copyright holders. 8 // * include a list of copyright holders. * 9 // * 9 // * * 10 // * Neither the authors of this software syst 10 // * Neither the authors of this software system, nor their employing * 11 // * institutes,nor the agencies providing fin 11 // * institutes,nor the agencies providing financial support for this * 12 // * work make any representation or warran 12 // * work make any representation or warranty, express or implied, * 13 // * regarding this software system or assum 13 // * regarding this software system or assume any liability for its * 14 // * use. Please see the license in the file 14 // * use. Please see the license in the file LICENSE and URL above * 15 // * for the full disclaimer and the limitatio 15 // * for the full disclaimer and the limitation of liability. * 16 // * 16 // * * 17 // * This code implementation is the result 17 // * This code implementation is the result of the scientific and * 18 // * technical work of the GEANT4 collaboratio 18 // * technical work of the GEANT4 collaboration. * 19 // * By using, copying, modifying or distri 19 // * By using, copying, modifying or distributing the software (or * 20 // * any work based on the software) you ag 20 // * any work based on the software) you agree to acknowledge its * 21 // * use in resulting scientific publicati 21 // * use in resulting scientific publications, and indicate your * 22 // * acceptance of all terms of the Geant4 Sof 22 // * acceptance of all terms of the Geant4 Software license. * 23 // ******************************************* 23 // ******************************************************************** 24 // 24 // 25 // G4UIcommandTree 25 // G4UIcommandTree 26 // 26 // 27 // Author: Makoto Asai (SLAC), 1998 27 // Author: Makoto Asai (SLAC), 1998 28 // Midified: Makoto Asai (SLAC), 2021 28 // Midified: Makoto Asai (SLAC), 2021 29 // Improve output HTML file layout and add o 29 // Improve output HTML file layout and add option to sort 30 // command/directory names in alphabetic ord 30 // command/directory names in alphabetic order 31 // ------------------------------------------- 31 // -------------------------------------------------------------------- 32 32 33 #include "G4UIcommandTree.hh" 33 #include "G4UIcommandTree.hh" 34 34 35 #include "G4StateManager.hh" 35 #include "G4StateManager.hh" 36 #include "G4UIdirectory.hh" 36 #include "G4UIdirectory.hh" 37 #include "G4UImanager.hh" 37 #include "G4UImanager.hh" 38 #include "G4ios.hh" 38 #include "G4ios.hh" 39 39 40 #include <fstream> 40 #include <fstream> 41 41 42 // ------------------------------------------- 42 // -------------------------------------------------------------------- 43 G4UIcommandTree::G4UIcommandTree(const char* t 43 G4UIcommandTree::G4UIcommandTree(const char* thePathName) 44 { 44 { 45 pathName = thePathName; 45 pathName = thePathName; 46 } 46 } 47 47 48 // ------------------------------------------- 48 // -------------------------------------------------------------------- 49 G4UIcommandTree::~G4UIcommandTree() 49 G4UIcommandTree::~G4UIcommandTree() 50 { 50 { 51 for (auto& i : tree) { 51 for (auto& i : tree) { 52 delete i; 52 delete i; 53 } 53 } 54 } 54 } 55 55 56 // ------------------------------------------- 56 // -------------------------------------------------------------------- 57 G4bool G4UIcommandTree::operator==(const G4UIc 57 G4bool G4UIcommandTree::operator==(const G4UIcommandTree& right) const 58 { 58 { 59 return (pathName == right.GetPathName()); 59 return (pathName == right.GetPathName()); 60 } 60 } 61 61 62 // ------------------------------------------- 62 // -------------------------------------------------------------------- 63 G4bool G4UIcommandTree::operator!=(const G4UIc 63 G4bool G4UIcommandTree::operator!=(const G4UIcommandTree& right) const 64 { 64 { 65 return (pathName != right.GetPathName()); 65 return (pathName != right.GetPathName()); 66 } 66 } 67 67 68 // ------------------------------------------- 68 // -------------------------------------------------------------------- 69 void G4UIcommandTree::AddNewCommand(G4UIcomman 69 void G4UIcommandTree::AddNewCommand(G4UIcommand* newCommand, G4bool workerThreadOnly) 70 { 70 { 71 G4String commandPath = newCommand->GetComman 71 G4String commandPath = newCommand->GetCommandPath(); 72 G4String remainingPath = commandPath; 72 G4String remainingPath = commandPath; 73 remainingPath.erase(0, pathName.length()); 73 remainingPath.erase(0, pathName.length()); 74 if (remainingPath.empty()) { 74 if (remainingPath.empty()) { 75 if (guidance == nullptr) { 75 if (guidance == nullptr) { 76 guidance = newCommand; 76 guidance = newCommand; 77 if (!(newCommand->ToBeBroadcasted())) { 77 if (!(newCommand->ToBeBroadcasted())) { 78 broadcastCommands = false; 78 broadcastCommands = false; 79 } 79 } 80 if (workerThreadOnly) { 80 if (workerThreadOnly) { 81 newCommand->SetWorkerThreadOnly(); 81 newCommand->SetWorkerThreadOnly(); 82 } 82 } 83 } 83 } 84 return; 84 return; 85 } 85 } 86 86 87 if (guidance != nullptr) { 87 if (guidance != nullptr) { 88 auto* dir = static_cast<G4UIdirectory*>(gu 88 auto* dir = static_cast<G4UIdirectory*>(guidance); 89 ifSort = dir->IfSort(); 89 ifSort = dir->IfSort(); 90 } 90 } 91 std::size_t i = remainingPath.find('/'); 91 std::size_t i = remainingPath.find('/'); 92 if (i == std::string::npos) { 92 if (i == std::string::npos) { 93 // Adding a new command to this directory 93 // Adding a new command to this directory 94 std::size_t n_commandEntry = command.size( 94 std::size_t n_commandEntry = command.size(); 95 for (std::size_t i_thCommand = 0; i_thComm 95 for (std::size_t i_thCommand = 0; i_thCommand < n_commandEntry; ++i_thCommand) { 96 if (remainingPath == command[i_thCommand 96 if (remainingPath == command[i_thCommand]->GetCommandName()) { 97 // a command of same name has already 97 // a command of same name has already defined. do nothing and return. 98 if (G4UImanager::GetUIpointer()->GetVe 98 if (G4UImanager::GetUIpointer()->GetVerboseLevel() > 8) { 99 G4ExceptionDescription ed; 99 G4ExceptionDescription ed; 100 ed << "Command <" << commandPath << 100 ed << "Command <" << commandPath << "> already exist. New command is not added."; 101 G4Exception("G4UIcommandTree::AddNew 101 G4Exception("G4UIcommandTree::AddNewCommand", "UI_ComTree_001", 102 // FatalException, 102 // FatalException, 103 JustWarning, ed); 103 JustWarning, ed); 104 } 104 } 105 return; 105 return; 106 } 106 } 107 } 107 } 108 if (!broadcastCommands) { 108 if (!broadcastCommands) { 109 newCommand->SetToBeBroadcasted(false); 109 newCommand->SetToBeBroadcasted(false); 110 } 110 } 111 if (workerThreadOnly) { 111 if (workerThreadOnly) { 112 newCommand->SetWorkerThreadOnly(); 112 newCommand->SetWorkerThreadOnly(); 113 } 113 } 114 if (ifSort) { 114 if (ifSort) { 115 auto j = command.cbegin(); 115 auto j = command.cbegin(); 116 for (; j != command.cend(); ++j) { 116 for (; j != command.cend(); ++j) { 117 if (newCommand->GetCommandPath() < (*j 117 if (newCommand->GetCommandPath() < (*j)->GetCommandPath()) { 118 break; 118 break; 119 } 119 } 120 } 120 } 121 command.insert(j, newCommand); 121 command.insert(j, newCommand); 122 } 122 } 123 else { 123 else { 124 command.push_back(newCommand); 124 command.push_back(newCommand); 125 } 125 } 126 return; 126 return; 127 } 127 } 128 128 129 // Adding a new command to a sub-directory 129 // Adding a new command to a sub-directory 130 G4String nextPath = pathName; 130 G4String nextPath = pathName; 131 nextPath.append(remainingPath.substr(0, i + 131 nextPath.append(remainingPath.substr(0, i + 1)); 132 std::size_t n_treeEntry = tree.size(); 132 std::size_t n_treeEntry = tree.size(); 133 for (std::size_t i_thTree = 0; i_thTree < n_ 133 for (std::size_t i_thTree = 0; i_thTree < n_treeEntry; ++i_thTree) { 134 if (nextPath == tree[i_thTree]->GetPathNam 134 if (nextPath == tree[i_thTree]->GetPathName()) { 135 if (!broadcastCommands) { 135 if (!broadcastCommands) { 136 newCommand->SetToBeBroadcasted(false); 136 newCommand->SetToBeBroadcasted(false); 137 } 137 } 138 tree[i_thTree]->AddNewCommand(newCommand 138 tree[i_thTree]->AddNewCommand(newCommand, workerThreadOnly); 139 return; 139 return; 140 } 140 } 141 } 141 } 142 // Creating a new sub-directory 142 // Creating a new sub-directory 143 auto* newTree = new G4UIcommandTree(nextPath 143 auto* newTree = new G4UIcommandTree(nextPath); 144 if (ifSort) { 144 if (ifSort) { 145 auto j = tree.cbegin(); 145 auto j = tree.cbegin(); 146 for (; j != tree.cend(); ++j) { 146 for (; j != tree.cend(); ++j) { 147 if (newTree->GetPathName() < (*j)->GetPa 147 if (newTree->GetPathName() < (*j)->GetPathName()) { 148 break; 148 break; 149 } 149 } 150 } 150 } 151 tree.insert(j, newTree); 151 tree.insert(j, newTree); 152 } 152 } 153 else { 153 else { 154 tree.push_back(newTree); 154 tree.push_back(newTree); 155 } 155 } 156 if (!broadcastCommands) { 156 if (!broadcastCommands) { 157 newCommand->SetToBeBroadcasted(false); 157 newCommand->SetToBeBroadcasted(false); 158 } 158 } 159 // In case a new sub-directry is created wit 159 // In case a new sub-directry is created with a new G4UIdirectory 160 // (most-likely this is the case), inherit t 160 // (most-likely this is the case), inherit the sort flag 161 newCommand->SetDefaultSortFlag(ifSort); 161 newCommand->SetDefaultSortFlag(ifSort); 162 newTree->AddNewCommand(newCommand, workerThr 162 newTree->AddNewCommand(newCommand, workerThreadOnly); 163 return; 163 return; 164 } 164 } 165 165 166 // ------------------------------------------- 166 // -------------------------------------------------------------------- 167 void G4UIcommandTree::RemoveCommand(G4UIcomman 167 void G4UIcommandTree::RemoveCommand(G4UIcommand* aCommand, G4bool workerThreadOnly) 168 { 168 { 169 if (workerThreadOnly && !(aCommand->IsWorker 169 if (workerThreadOnly && !(aCommand->IsWorkerThreadOnly())) { 170 return; 170 return; 171 } 171 } 172 G4String commandPath = aCommand->GetCommandP 172 G4String commandPath = aCommand->GetCommandPath(); 173 commandPath.erase(0, pathName.length()); << 173 G4String remainingPath = commandPath; 174 if (commandPath.empty()) { << 174 remainingPath.erase(0, pathName.length()); >> 175 if (remainingPath.empty()) { 175 guidance = nullptr; 176 guidance = nullptr; 176 } 177 } 177 else { 178 else { 178 std::size_t i = commandPath.find('/'); << 179 std::size_t i = remainingPath.find('/'); 179 if (i == std::string::npos) { 180 if (i == std::string::npos) { 180 // Find command 181 // Find command 181 std::size_t n_commandEntry = command.siz 182 std::size_t n_commandEntry = command.size(); 182 for (std::size_t i_thCommand = 0; i_thCo 183 for (std::size_t i_thCommand = 0; i_thCommand < n_commandEntry; ++i_thCommand) { 183 if (commandPath == command[i_thCommand << 184 if (remainingPath == command[i_thCommand]->GetCommandName()) { 184 command.erase(command.begin() + i_th 185 command.erase(command.begin() + i_thCommand); 185 break; 186 break; 186 } 187 } 187 } 188 } 188 } 189 } 189 else { 190 else { 190 // Find path 191 // Find path 191 G4String nextPath = pathName; 192 G4String nextPath = pathName; 192 nextPath.append(commandPath.substr(0, i << 193 nextPath.append(remainingPath.substr(0, i + 1)); 193 std::size_t n_treeEntry = tree.size(); 194 std::size_t n_treeEntry = tree.size(); 194 for (std::size_t i_thTree = 0; i_thTree 195 for (std::size_t i_thTree = 0; i_thTree < n_treeEntry; ++i_thTree) { 195 if (nextPath == tree[i_thTree]->GetPat 196 if (nextPath == tree[i_thTree]->GetPathName()) { 196 tree[i_thTree]->RemoveCommand(aComma 197 tree[i_thTree]->RemoveCommand(aCommand); 197 G4int n_commandRemain = tree[i_thTre 198 G4int n_commandRemain = tree[i_thTree]->GetCommandEntry(); 198 G4int n_treeRemain = tree[i_thTree]- 199 G4int n_treeRemain = tree[i_thTree]->GetTreeEntry(); 199 if (n_commandRemain == 0 && n_treeRe 200 if (n_commandRemain == 0 && n_treeRemain == 0) { 200 G4UIcommandTree* emptyTree = tree[ 201 G4UIcommandTree* emptyTree = tree[i_thTree]; 201 tree.erase(tree.begin() + i_thTree 202 tree.erase(tree.begin() + i_thTree); 202 delete emptyTree; 203 delete emptyTree; 203 } 204 } 204 break; 205 break; 205 } 206 } 206 } 207 } 207 } 208 } 208 } 209 } 209 } 210 } 210 211 211 // ------------------------------------------- 212 // -------------------------------------------------------------------- 212 G4UIcommand* G4UIcommandTree::FindPath(const c 213 G4UIcommand* G4UIcommandTree::FindPath(const char* commandPath) const 213 { 214 { 214 // This function tries to match a command na 215 // This function tries to match a command name 215 216 216 G4String remainingPath = commandPath; 217 G4String remainingPath = commandPath; 217 if (remainingPath.find(pathName) == std::str 218 if (remainingPath.find(pathName) == std::string::npos) { 218 return nullptr; 219 return nullptr; 219 } 220 } 220 remainingPath.erase(0, pathName.length()); 221 remainingPath.erase(0, pathName.length()); 221 std::size_t i = remainingPath.find('/'); 222 std::size_t i = remainingPath.find('/'); 222 if (i == std::string::npos) { 223 if (i == std::string::npos) { 223 // Find command 224 // Find command 224 std::size_t n_commandEntry = command.size( 225 std::size_t n_commandEntry = command.size(); 225 for (std::size_t i_thCommand = 0; i_thComm 226 for (std::size_t i_thCommand = 0; i_thCommand < n_commandEntry; ++i_thCommand) { 226 if (remainingPath == command[i_thCommand 227 if (remainingPath == command[i_thCommand]->GetCommandName()) { 227 return command[i_thCommand]; 228 return command[i_thCommand]; 228 } 229 } 229 } 230 } 230 } 231 } 231 else { 232 else { 232 // Find path 233 // Find path 233 G4String nextPath = pathName; 234 G4String nextPath = pathName; 234 nextPath.append(remainingPath.substr(0, i 235 nextPath.append(remainingPath.substr(0, i + 1)); 235 std::size_t n_treeEntry = tree.size(); 236 std::size_t n_treeEntry = tree.size(); 236 for (std::size_t i_thTree = 0; i_thTree < 237 for (std::size_t i_thTree = 0; i_thTree < n_treeEntry; ++i_thTree) { 237 if (nextPath == tree[i_thTree]->GetPathN 238 if (nextPath == tree[i_thTree]->GetPathName()) { 238 return tree[i_thTree]->FindPath(comman 239 return tree[i_thTree]->FindPath(commandPath); 239 } 240 } 240 } 241 } 241 } 242 } 242 return nullptr; 243 return nullptr; 243 } 244 } 244 245 245 // ------------------------------------------- 246 // -------------------------------------------------------------------- 246 G4UIcommandTree* G4UIcommandTree::FindCommandT 247 G4UIcommandTree* G4UIcommandTree::FindCommandTree(const char* commandPath) 247 { 248 { 248 // Try to match a command or a path with the 249 // Try to match a command or a path with the one given. 249 // @commandPath : command or path to match 250 // @commandPath : command or path to match 250 // @return the commandTree found or nullptr 251 // @return the commandTree found or nullptr if not 251 252 252 G4String remainingPath = commandPath; 253 G4String remainingPath = commandPath; 253 if (remainingPath.find(pathName) == std::str 254 if (remainingPath.find(pathName) == std::string::npos) { 254 return nullptr; 255 return nullptr; 255 } 256 } 256 remainingPath.erase(0, pathName.length()); 257 remainingPath.erase(0, pathName.length()); 257 std::size_t i = remainingPath.find('/'); 258 std::size_t i = remainingPath.find('/'); 258 if (i != std::string::npos) { 259 if (i != std::string::npos) { 259 // Find path 260 // Find path 260 G4String nextPath = pathName; 261 G4String nextPath = pathName; 261 nextPath.append(remainingPath.substr(0, i 262 nextPath.append(remainingPath.substr(0, i + 1)); 262 std::size_t n_treeEntry = tree.size(); 263 std::size_t n_treeEntry = tree.size(); 263 for (std::size_t i_thTree = 0; i_thTree < 264 for (std::size_t i_thTree = 0; i_thTree < n_treeEntry; ++i_thTree) { 264 if (tree[i_thTree]->GetPathName() == com 265 if (tree[i_thTree]->GetPathName() == commandPath) { 265 return tree[i_thTree]; 266 return tree[i_thTree]; 266 } 267 } 267 if (nextPath == tree[i_thTree]->GetPathN 268 if (nextPath == tree[i_thTree]->GetPathName()) { 268 return tree[i_thTree]->FindCommandTree 269 return tree[i_thTree]->FindCommandTree(commandPath); 269 } 270 } 270 } 271 } 271 } 272 } 272 else { 273 else { 273 return this; 274 return this; 274 } 275 } 275 return nullptr; 276 return nullptr; 276 } 277 } 277 278 278 // ------------------------------------------- 279 // -------------------------------------------------------------------- 279 G4String G4UIcommandTree::CompleteCommandPath( 280 G4String G4UIcommandTree::CompleteCommandPath(const G4String& aCommandPath) 280 { 281 { 281 G4String pName = aCommandPath; 282 G4String pName = aCommandPath; 282 G4String remainingPath = aCommandPath; 283 G4String remainingPath = aCommandPath; 283 G4String empty = ""; 284 G4String empty = ""; 284 G4String matchingPath = empty; 285 G4String matchingPath = empty; 285 286 286 // find the tree 287 // find the tree 287 auto jpre = pName.rfind('/'); 288 auto jpre = pName.rfind('/'); 288 if (jpre != G4String::npos) { 289 if (jpre != G4String::npos) { 289 pName.erase(jpre + 1); 290 pName.erase(jpre + 1); 290 } 291 } 291 G4UIcommandTree* aTree = FindCommandTree(pNa 292 G4UIcommandTree* aTree = FindCommandTree(pName); 292 293 293 if (aTree == nullptr) { 294 if (aTree == nullptr) { 294 return empty; 295 return empty; 295 } 296 } 296 297 297 if (pName.find(pName) == std::string::npos) 298 if (pName.find(pName) == std::string::npos) { 298 return empty; 299 return empty; 299 } 300 } 300 301 301 std::vector<G4String> paths; 302 std::vector<G4String> paths; 302 303 303 // list matched directories/commands 304 // list matched directories/commands 304 G4String strtmp; 305 G4String strtmp; 305 G4int nMatch = 0; 306 G4int nMatch = 0; 306 307 307 G4int Ndir = aTree->GetTreeEntry(); 308 G4int Ndir = aTree->GetTreeEntry(); 308 G4int Ncmd = aTree->GetCommandEntry(); 309 G4int Ncmd = aTree->GetCommandEntry(); 309 310 310 // directory ... 311 // directory ... 311 for (G4int idir = 1; idir <= Ndir; ++idir) { 312 for (G4int idir = 1; idir <= Ndir; ++idir) { 312 const G4String& fpdir = aTree->GetTree(idi << 313 G4String fpdir = aTree->GetTree(idir)->GetPathName(); 313 // matching test 314 // matching test 314 if (fpdir.find(remainingPath, 0) == 0) { 315 if (fpdir.find(remainingPath, 0) == 0) { 315 if (nMatch == 0) { 316 if (nMatch == 0) { 316 matchingPath = fpdir; 317 matchingPath = fpdir; 317 } 318 } 318 else { 319 else { 319 matchingPath = GetFirstMatchedString(f 320 matchingPath = GetFirstMatchedString(fpdir, matchingPath); 320 } 321 } 321 ++nMatch; 322 ++nMatch; 322 paths.push_back(fpdir); 323 paths.push_back(fpdir); 323 } 324 } 324 } 325 } 325 326 326 if (paths.size() >= 2) { 327 if (paths.size() >= 2) { 327 G4cout << "Matching directories :" << G4en 328 G4cout << "Matching directories :" << G4endl; 328 for (const auto& path : paths) { 329 for (const auto& path : paths) { 329 G4cout << path << G4endl; 330 G4cout << path << G4endl; 330 } 331 } 331 } 332 } 332 333 333 // command ... 334 // command ... 334 std::vector<G4String> commands; 335 std::vector<G4String> commands; 335 336 336 for (G4int icmd = 1; icmd <= Ncmd; ++icmd) { 337 for (G4int icmd = 1; icmd <= Ncmd; ++icmd) { 337 G4String fpcmd = aTree->GetPathName() + aT 338 G4String fpcmd = aTree->GetPathName() + aTree->GetCommand(icmd)->GetCommandName(); 338 // matching test 339 // matching test 339 if (fpcmd.find(remainingPath, 0) == 0) { 340 if (fpcmd.find(remainingPath, 0) == 0) { 340 if (nMatch == 0) { 341 if (nMatch == 0) { 341 matchingPath = fpcmd + " "; 342 matchingPath = fpcmd + " "; 342 } 343 } 343 else { 344 else { 344 strtmp = fpcmd + " "; 345 strtmp = fpcmd + " "; 345 matchingPath = GetFirstMatchedString(m 346 matchingPath = GetFirstMatchedString(matchingPath, strtmp); 346 } 347 } 347 nMatch++; 348 nMatch++; 348 commands.emplace_back(fpcmd + " "); 349 commands.emplace_back(fpcmd + " "); 349 } 350 } 350 } 351 } 351 352 352 if (commands.size() >= 2) { 353 if (commands.size() >= 2) { 353 G4cout << "Matching commands :" << G4endl; 354 G4cout << "Matching commands :" << G4endl; 354 for (const auto& matched : commands) { 355 for (const auto& matched : commands) { 355 G4cout << matched << G4endl; 356 G4cout << matched << G4endl; 356 } 357 } 357 } 358 } 358 359 359 return matchingPath; 360 return matchingPath; 360 } 361 } 361 362 362 // ------------------------------------------- 363 // -------------------------------------------------------------------- 363 G4String G4UIcommandTree::GetFirstMatchedStrin 364 G4String G4UIcommandTree::GetFirstMatchedString(const G4String& str1, const G4String& str2) const 364 { 365 { 365 std::size_t nlen1 = str1.length(); 366 std::size_t nlen1 = str1.length(); 366 std::size_t nlen2 = str2.length(); 367 std::size_t nlen2 = str2.length(); 367 368 368 std::size_t nmin = nlen1 < nlen2 ? nlen1 : n 369 std::size_t nmin = nlen1 < nlen2 ? nlen1 : nlen2; 369 370 370 G4String strMatched; 371 G4String strMatched; 371 for (G4int i = 0; i < (G4int)nmin; ++i) { 372 for (G4int i = 0; i < (G4int)nmin; ++i) { 372 if (str1[i] == str2[i]) { 373 if (str1[i] == str2[i]) { 373 strMatched += str1[i]; 374 strMatched += str1[i]; 374 } 375 } 375 else { 376 else { 376 break; 377 break; 377 } 378 } 378 } 379 } 379 380 380 return strMatched; 381 return strMatched; 381 } 382 } 382 383 383 // ------------------------------------------- 384 // -------------------------------------------------------------------- 384 void G4UIcommandTree::ListCurrent() const 385 void G4UIcommandTree::ListCurrent() const 385 { 386 { 386 G4cout << "Command directory path : " << pat 387 G4cout << "Command directory path : " << pathName << G4endl; 387 if (guidance != nullptr) { 388 if (guidance != nullptr) { 388 guidance->List(); 389 guidance->List(); 389 } 390 } 390 G4cout << " Sub-directories : " << G4endl; 391 G4cout << " Sub-directories : " << G4endl; 391 std::size_t n_treeEntry = tree.size(); 392 std::size_t n_treeEntry = tree.size(); 392 for (std::size_t i_thTree = 0; i_thTree < n_ 393 for (std::size_t i_thTree = 0; i_thTree < n_treeEntry; ++i_thTree) { 393 G4cout << " " << tree[i_thTree]->GetPath 394 G4cout << " " << tree[i_thTree]->GetPathName(); 394 if ((tree[i_thTree]->GetGuidance() != null 395 if ((tree[i_thTree]->GetGuidance() != nullptr) 395 && tree[i_thTree]->GetGuidance()->IsWo 396 && tree[i_thTree]->GetGuidance()->IsWorkerThreadOnly()) 396 { 397 { 397 G4cout << " @ "; 398 G4cout << " @ "; 398 } 399 } 399 else { 400 else { 400 G4cout << " "; 401 G4cout << " "; 401 } 402 } 402 G4cout << tree[i_thTree]->GetTitle() << G4 403 G4cout << tree[i_thTree]->GetTitle() << G4endl; 403 } 404 } 404 G4cout << " Commands : " << G4endl; 405 G4cout << " Commands : " << G4endl; 405 std::size_t n_commandEntry = command.size(); 406 std::size_t n_commandEntry = command.size(); 406 for (std::size_t i_thCommand = 0; i_thComman 407 for (std::size_t i_thCommand = 0; i_thCommand < n_commandEntry; ++i_thCommand) { 407 G4cout << " " << command[i_thCommand]->G 408 G4cout << " " << command[i_thCommand]->GetCommandName(); 408 if (command[i_thCommand]->IsWorkerThreadOn 409 if (command[i_thCommand]->IsWorkerThreadOnly()) { 409 G4cout << " @ "; 410 G4cout << " @ "; 410 } 411 } 411 else { 412 else { 412 G4cout << " * "; 413 G4cout << " * "; 413 } 414 } 414 G4cout << command[i_thCommand]->GetTitle() 415 G4cout << command[i_thCommand]->GetTitle() << G4endl; 415 } 416 } 416 } 417 } 417 418 418 // ------------------------------------------- 419 // -------------------------------------------------------------------- 419 void G4UIcommandTree::ListCurrentWithNum() con 420 void G4UIcommandTree::ListCurrentWithNum() const 420 { 421 { 421 G4cout << "Command directory path : " << pat 422 G4cout << "Command directory path : " << pathName << G4endl; 422 if (guidance != nullptr) { 423 if (guidance != nullptr) { 423 guidance->List(); 424 guidance->List(); 424 } 425 } 425 G4int i = 0; 426 G4int i = 0; 426 G4cout << " Sub-directories : " << G4endl; 427 G4cout << " Sub-directories : " << G4endl; 427 std::size_t n_treeEntry = tree.size(); 428 std::size_t n_treeEntry = tree.size(); 428 for (std::size_t i_thTree = 0; i_thTree < n_ 429 for (std::size_t i_thTree = 0; i_thTree < n_treeEntry; ++i_thTree) { 429 ++i; 430 ++i; 430 G4cout << " " << i << ") " << tree[i_thTre 431 G4cout << " " << i << ") " << tree[i_thTree]->GetPathName() << " " 431 << tree[i_thTree]->GetTitle() << G4 432 << tree[i_thTree]->GetTitle() << G4endl; 432 } 433 } 433 G4cout << " Commands : " << G4endl; 434 G4cout << " Commands : " << G4endl; 434 std::size_t n_commandEntry = command.size(); 435 std::size_t n_commandEntry = command.size(); 435 for (std::size_t i_thCommand = 0; i_thComman 436 for (std::size_t i_thCommand = 0; i_thCommand < n_commandEntry; ++i_thCommand) { 436 ++i; 437 ++i; 437 G4cout << " " << i << ") " << command[i_th 438 G4cout << " " << i << ") " << command[i_thCommand]->GetCommandName() << " * " 438 << command[i_thCommand]->GetTitle() 439 << command[i_thCommand]->GetTitle() << G4endl; 439 } 440 } 440 } 441 } 441 442 442 // ------------------------------------------- 443 // -------------------------------------------------------------------- 443 void G4UIcommandTree::List() const 444 void G4UIcommandTree::List() const 444 { 445 { 445 ListCurrent(); 446 ListCurrent(); 446 std::size_t n_commandEntry = command.size(); 447 std::size_t n_commandEntry = command.size(); 447 for (std::size_t i_thCommand = 0; i_thComman 448 for (std::size_t i_thCommand = 0; i_thCommand < n_commandEntry; ++i_thCommand) { 448 command[i_thCommand]->List(); 449 command[i_thCommand]->List(); 449 } 450 } 450 std::size_t n_treeEntry = tree.size(); 451 std::size_t n_treeEntry = tree.size(); 451 for (std::size_t i_thTree = 0; i_thTree < n_ 452 for (std::size_t i_thTree = 0; i_thTree < n_treeEntry; ++i_thTree) { 452 tree[i_thTree]->List(); 453 tree[i_thTree]->List(); 453 } 454 } 454 } 455 } 455 456 456 // ------------------------------------------- 457 // -------------------------------------------------------------------- 457 G4String G4UIcommandTree::CreateFileName(const 458 G4String G4UIcommandTree::CreateFileName(const char* pName) 458 { 459 { 459 G4String fn = pName; 460 G4String fn = pName; 460 std::size_t idxs; 461 std::size_t idxs; 461 while ((idxs = fn.find('/')) != std::string: 462 while ((idxs = fn.find('/')) != std::string::npos) { 462 fn[(G4int)idxs] = '_'; 463 fn[(G4int)idxs] = '_'; 463 } 464 } 464 fn += ".html"; 465 fn += ".html"; 465 return fn; 466 return fn; 466 } 467 } 467 468 468 // ------------------------------------------- 469 // -------------------------------------------------------------------- 469 G4String G4UIcommandTree::ModStr(const char* s 470 G4String G4UIcommandTree::ModStr(const char* strS) 470 { 471 { 471 G4String sx; 472 G4String sx; 472 G4String str = strS; 473 G4String str = strS; 473 for (G4int i = 0; i < G4int(str.length()); + 474 for (G4int i = 0; i < G4int(str.length()); ++i) { 474 char c = str[i]; 475 char c = str[i]; 475 switch (c) { 476 switch (c) { 476 case '<': 477 case '<': 477 sx += "<"; 478 sx += "<"; 478 break; 479 break; 479 case '>': 480 case '>': 480 sx += ">"; 481 sx += ">"; 481 break; 482 break; 482 case '&': 483 case '&': 483 sx += "&"; 484 sx += "&"; 484 break; 485 break; 485 default: 486 default: 486 sx += c; 487 sx += c; 487 } 488 } 488 } 489 } 489 return sx; 490 return sx; 490 } 491 } 491 492 492 // ------------------------------------------- 493 // -------------------------------------------------------------------- 493 void G4UIcommandTree::CreateHTML(const G4Strin 494 void G4UIcommandTree::CreateHTML(const G4String& sideBar) 494 { 495 { 495 G4String ofileName = CreateFileName(pathName 496 G4String ofileName = CreateFileName(pathName); 496 std::ofstream oF(ofileName, std::ios::out); 497 std::ofstream oF(ofileName, std::ios::out); 497 498 498 oF << "<html><head><title>Commands in " << M 499 oF << "<html><head><title>Commands in " << ModStr(pathName) << "</title></head>" << G4endl; 499 oF << "<style> \ 500 oF << "<style> \ 500 table,table td,table th { \ 501 table,table td,table th { \ 501 border:1px solid #eee \ 502 border:1px solid #eee \ 502 } \ 503 } \ 503 table td,table th { \ 504 table td,table th { \ 504 padding:5px 20px; \ 505 padding:5px 20px; \ 505 line-height:1.3; \ 506 line-height:1.3; \ 506 text-align:inherit \ 507 text-align:inherit \ 507 } \ 508 } \ 508 a { \ 509 a { \ 509 color:#17a81a; \ 510 color:#17a81a; \ 510 text-decoration:none; \ 511 text-decoration:none; \ 511 transition-duration:0.3s \ 512 transition-duration:0.3s \ 512 } \ 513 } \ 513 a:hover { \ 514 a:hover { \ 514 color:#17a81a \ 515 color:#17a81a \ 515 } \ 516 } \ 516 table { \ 517 table { \ 517 border-collapse:collapse; \ 518 border-collapse:collapse; \ 518 border-spacing:0; \ 519 border-spacing:0; \ 519 margin-bottom:5px; \ 520 margin-bottom:5px; \ 520 } \ 521 } \ 521 h1 { \ 522 h1 { \ 522 font-size:2.25em; \ 523 font-size:2.25em; \ 523 font-weight:300; \ 524 font-weight:300; \ 524 letter-spacing:-1px; \ 525 letter-spacing:-1px; \ 525 line-height:1.15em; \ 526 line-height:1.15em; \ 526 margin-bottom:0.5em; \ 527 margin-bottom:0.5em; \ 527 word-wrap:break-word \ 528 word-wrap:break-word \ 528 } \ 529 } \ 529 h2 { \ 530 h2 { \ 530 font-size:1.5em; \ 531 font-size:1.5em; \ 531 font-weight:300; \ 532 font-weight:300; \ 532 letter-spacing:-1px; \ 533 letter-spacing:-1px; \ 533 line-height:1.15em; \ 534 line-height:1.15em; \ 534 margin-bottom:0.5em; \ 535 margin-bottom:0.5em; \ 535 word-wrap:break-word \ 536 word-wrap:break-word \ 536 } \ 537 } \ 537 h3 { \ 538 h3 { \ 538 color:#26282a; \ 539 color:#26282a; \ 539 font-weight:300; \ 540 font-weight:300; \ 540 font-size:1.3em; \ 541 font-size:1.3em; \ 541 padding:15px 0 15px 0; \ 542 padding:15px 0 15px 0; \ 542 border-bottom:2px #eee solid; \ 543 border-bottom:2px #eee solid; \ 543 word-wrap:break-word \ 544 word-wrap:break-word \ 544 } \ 545 } \ 545 .sidebar { \ 546 .sidebar { \ 546 display:block; \ 547 display:block; \ 547 position:relative; \ 548 position:relative; \ 548 position:sticky; \ 549 position:sticky; \ 549 float:left; \ 550 float:left; \ 550 -webkit-box-sizing:border-box; \ 551 -webkit-box-sizing:border-box; \ 551 -moz-box-sizing:border-box; \ 552 -moz-box-sizing:border-box; \ 552 -ms-box-sizing:border-box; \ 553 -ms-box-sizing:border-box; \ 553 box-sizing:border-box; \ 554 box-sizing:border-box; \ 554 width:20%; \ 555 width:20%; \ 555 padding-right:20px \ 556 padding-right:20px \ 556 } \ 557 } \ 557 .context { \ 558 .context { \ 558 width:80%; \ 559 width:80%; \ 559 display:inline-block; \ 560 display:inline-block; \ 560 background-color:#fff; \ 561 background-color:#fff; \ 561 padding: 25px 35px 20px 30px; \ 562 padding: 25px 35px 20px 30px; \ 562 -webkit-box-sizing:border-box; \ 563 -webkit-box-sizing:border-box; \ 563 -moz-box-sizing:border-box; \ 564 -moz-box-sizing:border-box; \ 564 -ms-box-sizing:border-box; \ 565 -ms-box-sizing:border-box; \ 565 box-sizing:border-box \ 566 box-sizing:border-box \ 566 } \ 567 } \ 567 </style>" 568 </style>" 568 << G4endl; 569 << G4endl; 569 oF << "<body bgcolor=\"#ffffff\">" << G4endl 570 oF << "<body bgcolor=\"#ffffff\">" << G4endl; 570 571 571 // Left Panel 572 // Left Panel 572 if (createHTMLTreeLevel == 0) { 573 if (createHTMLTreeLevel == 0) { 573 oF << "<div class=\"sidebar\">" << sideBar 574 oF << "<div class=\"sidebar\">" << sideBar << "</div>" << G4endl; 574 } 575 } 575 // Right Panel 576 // Right Panel 576 oF << "<div class=\"context\">"; 577 oF << "<div class=\"context\">"; 577 oF << "<h1>" << ModStr(pathName) << "</h1>" 578 oF << "<h1>" << ModStr(pathName) << "</h1>" << G4endl; 578 579 579 if (guidance != nullptr) { 580 if (guidance != nullptr) { 580 for (G4int i = 0; i < (G4int)guidance->Get 581 for (G4int i = 0; i < (G4int)guidance->GetGuidanceEntries(); ++i) { 581 oF << ModStr(guidance->GetGuidanceLine(i 582 oF << ModStr(guidance->GetGuidanceLine(i)) << "<br>" << G4endl; 582 } 583 } 583 } 584 } 584 if (!tree.empty()) { 585 if (!tree.empty()) { 585 G4String menu = ""; 586 G4String menu = ""; 586 G4String newSideBar = ""; 587 G4String newSideBar = ""; 587 menu += "<h2>Sub-directories </h2><table>" 588 menu += "<h2>Sub-directories </h2><table>"; 588 newSideBar += "<h2><a href=\"" + ofileName 589 newSideBar += "<h2><a href=\"" + ofileName + "\">Top level </a></h2><table>"; 589 // Build menu short version 590 // Build menu short version 590 for (auto& i_thTree : tree) { 591 for (auto& i_thTree : tree) { 591 newSideBar += "<tr><td><a href=\"" + Cre 592 newSideBar += "<tr><td><a href=\"" + CreateFileName(i_thTree->GetPathName()) + "\">" 592 + ModStr(i_thTree->GetPath 593 + ModStr(i_thTree->GetPathName()) + "</a>"; 593 } 594 } 594 // Build menu 595 // Build menu 595 for (auto& i_thTree : tree) { 596 for (auto& i_thTree : tree) { 596 menu += "<tr><td><a href=\"" + CreateFil 597 menu += "<tr><td><a href=\"" + CreateFileName(i_thTree->GetPathName()) + "\">" 597 + ModStr(i_thTree->GetPathName() 598 + ModStr(i_thTree->GetPathName()) + "</a>"; 598 menu += "</td><td>" + ModStr(i_thTree->G 599 menu += "</td><td>" + ModStr(i_thTree->GetTitle()) + "</tr>"; 599 } 600 } 600 menu += "</table>"; 601 menu += "</table>"; 601 newSideBar += "</table>"; 602 newSideBar += "</table>"; 602 for (auto& i_thTree : tree) { 603 for (auto& i_thTree : tree) { 603 createHTMLTreeLevel++; 604 createHTMLTreeLevel++; 604 i_thTree->CreateHTML(newSideBar); 605 i_thTree->CreateHTML(newSideBar); 605 createHTMLTreeLevel--; 606 createHTMLTreeLevel--; 606 } 607 } 607 oF << menu << G4endl; 608 oF << menu << G4endl; 608 } 609 } 609 610 610 if (!command.empty()) { 611 if (!command.empty()) { 611 oF << "<h2>Commands </h2>" << G4endl; 612 oF << "<h2>Commands </h2>" << G4endl; 612 613 613 // resume 614 // resume 614 oF << "<table>" << G4endl; 615 oF << "<table>" << G4endl; 615 for (std::size_t i_thCommand = 0; i_thComm 616 for (std::size_t i_thCommand = 0; i_thCommand < command.size(); ++i_thCommand) { 616 G4UIcommand* cmd = command[i_thCommand]; 617 G4UIcommand* cmd = command[i_thCommand]; 617 oF << "<tr><td><a href=\"#c" << i_thComm 618 oF << "<tr><td><a href=\"#c" << i_thCommand << "\">" << ModStr(cmd->GetCommandName()); 618 oF << "</a></td></tr>" << G4endl; 619 oF << "</a></td></tr>" << G4endl; 619 } 620 } 620 oF << "</table>" << G4endl; 621 oF << "</table>" << G4endl; 621 for (std::size_t i_thCommand = 0; i_thComm 622 for (std::size_t i_thCommand = 0; i_thCommand < command.size(); ++i_thCommand) { 622 G4UIcommand* cmd = command[i_thCommand]; 623 G4UIcommand* cmd = command[i_thCommand]; 623 oF << "<h3 id=\"c" << i_thCommand << "\" 624 oF << "<h3 id=\"c" << i_thCommand << "\">" << ModStr(cmd->GetCommandName()); 624 if (cmd->GetParameterEntries() > 0) { 625 if (cmd->GetParameterEntries() > 0) { 625 for (G4int i_thParam = 0; i_thParam < 626 for (G4int i_thParam = 0; i_thParam < (G4int)cmd->GetParameterEntries(); ++i_thParam) { 626 oF << " [<i>" << ModStr(cmd->GetPara 627 oF << " [<i>" << ModStr(cmd->GetParameter(i_thParam)->GetParameterName()) << "</i>]"; 627 } 628 } 628 } 629 } 629 oF << "</h3>" << G4endl; 630 oF << "</h3>" << G4endl; 630 oF << "<p>" << G4endl; 631 oF << "<p>" << G4endl; 631 for (G4int i = 0; i < (G4int)cmd->GetGui 632 for (G4int i = 0; i < (G4int)cmd->GetGuidanceEntries(); ++i) { 632 oF << ModStr(cmd->GetGuidanceLine(i)) 633 oF << ModStr(cmd->GetGuidanceLine(i)) << "<br>" << G4endl; 633 } 634 } 634 if (!(cmd->GetRange()).empty()) { 635 if (!(cmd->GetRange()).empty()) { 635 oF << "<p>Range : " << ModStr(cmd->Get 636 oF << "<p>Range : " << ModStr(cmd->GetRange()) << G4endl; 636 } 637 } 637 std::vector<G4ApplicationState>* availab 638 std::vector<G4ApplicationState>* availabelStateList = cmd->GetStateList(); 638 if (availabelStateList->size() == 6) { 639 if (availabelStateList->size() == 6) { 639 oF << "<p>Available at all Geant4 stat 640 oF << "<p>Available at all Geant4 states." << G4endl; 640 } 641 } 641 else { 642 else { 642 oF << "<p>Available Geant4 state(s) : 643 oF << "<p>Available Geant4 state(s) : "; 643 for (auto& ias : *availabelStateList) 644 for (auto& ias : *availabelStateList) { 644 oF << G4StateManager::GetStateManage 645 oF << G4StateManager::GetStateManager()->GetStateString(ias) << " " << G4endl; 645 } 646 } 646 } 647 } 647 if (cmd->GetParameterEntries() > 0) { 648 if (cmd->GetParameterEntries() > 0) { 648 oF << "<p>Parameters<table border=1>" 649 oF << "<p>Parameters<table border=1>" << G4endl; 649 for (G4int i_thParam = 0; i_thParam < 650 for (G4int i_thParam = 0; i_thParam < (G4int)cmd->GetParameterEntries(); ++i_thParam) { 650 G4UIparameter* prm = cmd->GetParamet 651 G4UIparameter* prm = cmd->GetParameter(i_thParam); 651 oF << "<tr><td>" << ModStr(prm->GetP 652 oF << "<tr><td>" << ModStr(prm->GetParameterName()) << G4endl; 652 oF << "<td>type " << prm->GetParamet 653 oF << "<td>type " << prm->GetParameterType() << G4endl; 653 oF << "<td>"; 654 oF << "<td>"; 654 if (prm->IsOmittable()) { 655 if (prm->IsOmittable()) { 655 oF << "Omittable : "; 656 oF << "Omittable : "; 656 if (prm->GetCurrentAsDefault()) { 657 if (prm->GetCurrentAsDefault()) { 657 oF << "current value is used as 658 oF << "current value is used as the default value." << G4endl; 658 } 659 } 659 else { 660 else { 660 oF << "default value = " << prm- 661 oF << "default value = " << prm->GetDefaultValue() << G4endl; 661 } 662 } 662 } 663 } 663 oF << "<td>"; 664 oF << "<td>"; 664 if (!(prm->GetParameterRange()).empt 665 if (!(prm->GetParameterRange()).empty()) { 665 oF << "Parameter range : " << ModS 666 oF << "Parameter range : " << ModStr(prm->GetParameterRange()) << G4endl; 666 } 667 } 667 else if (!(prm->GetParameterCandidat 668 else if (!(prm->GetParameterCandidates()).empty()) { 668 oF << "Parameter candidates : " << 669 oF << "Parameter candidates : " << ModStr(prm->GetParameterCandidates()) << G4endl; 669 } 670 } 670 } 671 } 671 oF << "</table>" << G4endl; 672 oF << "</table>" << G4endl; 672 } 673 } 673 } 674 } 674 } 675 } 675 oF << "</div></body></html>" << G4endl; 676 oF << "</div></body></html>" << G4endl; 676 oF.close(); 677 oF.close(); 677 } 678 } 678 679 679 // ------------------------------------------- 680 // -------------------------------------------------------------------- 680 G4UIcommandTree* G4UIcommandTree::GetTree(cons 681 G4UIcommandTree* G4UIcommandTree::GetTree(const char* comNameC) 681 { 682 { 682 G4String comName = comNameC; 683 G4String comName = comNameC; 683 for (auto& i : tree) { 684 for (auto& i : tree) { 684 if (comName == i->GetPathName()) { 685 if (comName == i->GetPathName()) { 685 return i; 686 return i; 686 } 687 } 687 } 688 } 688 return nullptr; 689 return nullptr; 689 } 690 } 690 691