001package org.vishia.commander; 002 003import java.io.Closeable; 004import java.io.File; 005import java.io.IOException; 006import java.util.ArrayList; 007import java.util.Iterator; 008import java.util.LinkedList; 009import java.util.List; 010import java.util.Map; 011import java.util.TreeMap; 012 013import org.vishia.cmd.CmdGetterArguments; 014import org.vishia.cmd.JZtxtcmdScript; 015import org.vishia.cmd.JZtxtcmdScript.JZcmdClass; 016import org.vishia.cmd.JZtxtcmdScript.Subroutine; 017import org.vishia.commander.target.FcmdtTarget; 018import org.vishia.commander.target.FcmdtTarget_ifc; 019import org.vishia.communication.InterProcessCommFactorySocket; 020import org.vishia.fileLocalAccessor.FileAccessorLocalJava7; 021import org.vishia.fileRemote.FileCluster; 022import org.vishia.fileRemote.FileRemote; 023import org.vishia.gral.area9.GuiCallingArgs; 024import org.vishia.gral.area9.GuiCfg; 025import org.vishia.gral.area9.GralArea9MainCmd; 026import org.vishia.gral.base.GralMenu; 027import org.vishia.gral.base.GralMng; 028import org.vishia.gral.base.GralPanelContent; 029import org.vishia.gral.base.GralWidget; 030import org.vishia.gral.ifc.GralMngBuild_ifc; 031import org.vishia.gral.ifc.GralUserAction; 032import org.vishia.gral.ifc.GralWidget_ifc; 033import org.vishia.gral.widget.GralFileSelector; 034import org.vishia.jztxtcmd.JZtxtcmd; 035import org.vishia.msgDispatch.MsgRedirectConsole; 036import org.vishia.util.DataAccess; 037import org.vishia.util.Debugutil; 038import org.vishia.util.KeyCode; 039 040/**This class is the main class of the-File-commander. 041 * @author Hartmut Schorrig 042 * 043 */ 044public class Fcmd extends GuiCfg 045{ 046 047 048 /**Version, history and license. This String is visible in the about info. 049 * <ul> 050 * <li>2017-08-27 {@link FcmdFavorPathSelector#actionDeselectDirtree} now removes all FileRemote instances of children 051 * because a selection is not necessary furthermore. This is a 'refresh'. But the 'refresh' (F5, ctrl-R) should not change selection, 052 * it must not delete this children-FileRemote. Only deselection is the key action for that. 053 * <li>2016-08-28 see {@link FcmdExecuter#sVersion}, {@link FcmdSettings#sVersion} 054 * <li>2015-07-18 Hartmut chg: Now the output of script errors while executing the JZcmd cmd script is visible 055 * in the output window. 056 * <li>2015-07-12 Hartmut new: Many fixes in the base classes for functionality. See all commit messages of the component. 057 * <li>2014-12-26 Hartmut new: {@link #refreshFilePanel(FileRemote)} can be called in any callback thread. 058 * <li>2011-2013 some changes, see source files. 059 * <li>2011-10-00 Hartmut created 060 * </ul> 061 * 062 * <b>Copyright/Copyleft</b>:<br> 063 * For this source the LGPL Lesser General Public License, 064 * published by the Free Software Foundation is valid. 065 * It means: 066 * <ol> 067 * <li> You can use this source without any restriction for any desired purpose. 068 * <li> You can redistribute copies of this source to everybody. 069 * <li> Every user of this source, also the user of redistribute copies 070 * with or without payment, must accept this license for further using. 071 * <li> But the LPGL is not appropriate for a whole software product, 072 * if this source is only a part of them. It means, the user 073 * must publish this part of source, 074 * but doesn't need to publish the whole source of the own product. 075 * <li> You can study and modify (improve) this source 076 * for own using or for redistribution, but you have to license the 077 * modified sources likewise under this LGPL Lesser General Public License. 078 * You mustn't delete this Copyright/Copyleft inscription in this source file. 079 * </ol> 080 * If you intent to use this source without publishing its usage, you can get 081 * a second license subscribing a special contract with the author. 082 * 083 * @author Hartmut Schorrig = hartmut.schorrig@vishia.de 084 */ 085 //@SuppressWarnings("hiding") 086 public static final String version = "2018-11-02"; 087 088 089 static class CallingArgs extends GuiCallingArgs 090 { 091 File fileCfgCmds; 092 093 File fileCmdsForExt; 094 095 File fileCfgButtonCmds; 096 097 File fileSelectTabPaths; 098 099 File dirCfg; 100 101 } 102 103 /** 104 * This action is invoked for all general key pressed actions. It tests the 105 * key and switches to the concretely action for the pressed key. General keys 106 * are [F1] for help, [F4] for edit etc. 107 */ 108 GralUserAction actionTest = new GralUserAction("actionTest") 109 { 110 @Override public boolean userActionGui(int key, GralWidget infos, Object... params) 111 { 112 GralMng.get().addInfo("Test\n", true); 113 return true; 114 } 115 }; 116 117 /** 118 * This action is invoked for all general key pressed actions. It tests the 119 * key and switches to the concretely action for the pressed key. General keys 120 * are [F1] for help, [F4] for edit etc. 121 */ 122 GralUserAction actionKey = new GralUserAction("actionKey") 123 { 124 @Override 125 public boolean userActionGui(String sIntension, GralWidget infos, 126 Object... params) 127 { 128 Debugutil.stop(); 129 return true; 130 } 131 }; 132 133 /**Key alt-F1 to select a directory/cmd list in a list of directories for the 134 * left panel. The original Norton Commander approach is to select a drive 135 * letter for windows. Selection of paths instead are adequate. 136 */ 137 GralUserAction actionReadMsgConfig = new GralUserAction("actionReadMsgConfig") 138 { 139 @Override public boolean exec(int key, GralWidget_ifc widgi, Object... params){ 140 if(KeyCode.isControlFunctionMouseUpOrMenu(key)){ //supress both mouse up and down reaction 141 if(cargs.msgConfig !=null && cargs.msgConfig.exists()){ 142 msgDisp.readConfig(cargs.msgConfig); 143 } 144 return true; 145 } else return false; 146 } 147 }; 148 149 /**Key alt-F1 to select a directory/cmd list in a list of directories for the 150 * left panel. The original Norton Commander approach is to select a drive 151 * letter for windows. Selection of paths instead are adequate. 152 */ 153 GralUserAction selectCardThemesLeft = new GralUserAction("selectCardThemesLeft") 154 { 155 @Override public boolean userActionGui(int key, GralWidget infos, Object... params){ 156 if(KeyCode.isControlFunctionMouseUpOrMenu(key)){ //supress both mouse up and down reaction 157 favorPathSelector.panelLeft.cardFavorThemes.wdgdTable.setFocus(); 158 return true; 159 } else return false; 160 } 161 }; 162 163 /**Key alt-F2 to select a directory/cmd list in a list of directories for the 164 * middle panel. 165 */ 166 GralUserAction selectCardThemesMiddle = new GralUserAction("selectCardThemesMiddle") 167 { 168 @Override public boolean userActionGui(int key, GralWidget infos, Object... params){ 169 if(KeyCode.isControlFunctionMouseUpOrMenu(key)){ //supress both mouse up and down reaction 170 favorPathSelector.panelMid.cardFavorThemes.wdgdTable.setFocus(); 171 return true; 172 } else return false; 173 } 174 }; 175 176 /**Key alt-F3 to select a directory/cmd list in a list of directories for the 177 * right panel. 178 */ 179 GralUserAction selectCardThemesRight = new GralUserAction("selectCardThemesRight") 180 { 181 @Override public boolean userActionGui(int key, GralWidget infos, Object... params){ 182 if(KeyCode.isControlFunctionMouseUpOrMenu(key)){ 183 favorPathSelector.panelRight.cardFavorThemes.wdgdTable.setFocus(); 184 return true; 185 } else return false; 186 } 187 }; 188 189 /**Key sh-F1 to select a directory/cmd list in a list of directories for the 190 * right panel. 191 */ 192 GralUserAction selectFileCardLeft = new GralUserAction("selectFileCardLeft") 193 { 194 @Override public boolean userActionGui(int key, GralWidget infos, Object... params){ 195 if(KeyCode.isControlFunctionMouseUpOrMenu(key)){ 196 favorPathSelector.panelLeft.setFocus(); 197 return true; 198 } else return false; 199 } 200 }; 201 202 /**Key sh-F2 to select a directory/cmd list in a list of directories for the 203 * right panel. 204 */ 205 GralUserAction selectFileCardMid = new GralUserAction("selectFileCardMid") 206 { 207 @Override public boolean userActionGui(int key, GralWidget infos, Object... params){ 208 if(KeyCode.isControlFunctionMouseUpOrMenu(key)){ 209 favorPathSelector.panelMid.setFocus(); 210 return true; 211 } else return false; 212 } 213 }; 214 215 /**Key sh-F3 to select a directory/cmd list in a list of directories for the 216 * right panel. 217 */ 218 GralUserAction selectFileCardRight = new GralUserAction("selectFileCardRight") 219 { 220 @Override public boolean userActionGui(int key, GralWidget infos, Object... params){ 221 if(KeyCode.isControlFunctionMouseUpOrMenu(key)){ 222 favorPathSelector.panelRight.setFocus(); 223 return true; 224 } else return false; 225 } 226 }; 227 228 /**Key sh-F3 to select a directory/cmd list in a list of directories for the 229 * right panel. 230 */ 231 GralUserAction selectFileCardOther = new GralUserAction("selectFileCardOther") 232 { 233 @Override public boolean userActionGui(int key, GralWidget infos, Object... params){ 234 if(KeyCode.isControlFunctionMouseUpOrMenu(key)){ 235 if(lastFilePanels.size() >=2){ 236 FcmdLeftMidRightPanel otherPanel = lastFilePanels.get(1); 237 otherPanel.setFocus(); 238 } 239 return true; 240 } else return false; 241 } 242 }; 243 244 245 GralUserAction actionFocusPanelToLeft = new GralUserAction("FcmdLeftMidRightPanel.actionRightCard"){ 246 @Override public boolean userActionGui(int actionCode, GralWidget widgd, Object... params){ 247 FcmdLeftMidRightPanel actPanel = lastFilePanels.get(0); 248 if(actPanel.cc == 'm'){ favorPathSelector.panelLeft.setFocus(); } 249 else if(actPanel.cc == 'r'){ favorPathSelector.panelMid.setFocus(); } 250 return true; 251 } 252 }; 253 254 255 GralUserAction actionFocusPanelToRight = new GralUserAction("FcmdLeftMidRightPanel.actionRightCard"){ 256 @Override public boolean userActionGui(int actionCode, GralWidget widgd, Object... params){ 257 FcmdLeftMidRightPanel actPanel = lastFilePanels.get(0); 258 if(actPanel.cc == 'm'){ favorPathSelector.panelRight.setFocus(); } 259 else if(actPanel.cc == 'l'){ favorPathSelector.panelMid.setFocus(); } 260 return true; 261 } 262 }; 263 264 265 GralUserAction actionFocusFileCard = new GralUserAction("FcmdLeftMidRightPanel.actionFileCard"){ 266 @Override public boolean userActionGui(int actionCode, GralWidget widgd, Object... params){ 267 return true; 268 } 269 }; 270 271 272 GralUserAction actionFocusThemeCard = new GralUserAction("FcmdLeftMidRightPanel.actionThemeCard"){ 273 @Override public boolean userActionGui(int actionCode, GralWidget widgd, Object... params){ 274 return true; 275 } 276 }; 277 278 279 280 281 282 /**Action to focus the cmd card. 283 */ 284 GralUserAction actionFocusCmdCard = new GralUserAction("actionFocusCmdCard") 285 { 286 @Override public boolean userActionGui(int key, GralWidget infos, Object... params){ 287 if(KeyCode.isControlFunctionMouseUpOrMenu(key)){ //supress both mouse up and down reaction 288 executer.cmdSelector.wdgdTable.setFocus(); 289 return true; 290 } else return false; 291 } 292 }; 293 294 295 296 GralUserAction actionFocusCardInPanelToLeft = new GralUserAction("FcmdLeftMidRightPanel.actionLeftCard"){ 297 @Override public boolean userActionGui(int actionCode, GralWidget widgd, Object... params){ 298 lastFilePanels.get(0).focusLeftCard(); 299 return true; 300 } 301 }; 302 303 304 GralUserAction actionFocusCardInPanelToRight = new GralUserAction("FcmdLeftMidRightPanel.actionRightCard"){ 305 @Override public boolean userActionGui(int actionCode, GralWidget widgd, Object... params){ 306 //sets focus to right 307 lastFilePanels.get(0).focusRightCard(); 308 return true; 309 } 310 }; 311 312 313 314 315 void openExtEditor(File file){ 316 JZtxtcmdScript.Subroutine jzsub = buttonCmds.get("edit"); 317 if( jzsub == null ) { 318 mainCmd.writeError("internal problem - don't find 'edit' command. "); 319 } else { 320 String sMsg = "GralCommandSelector - put cmd;" + jzsub.toString(); 321 System.out.println(sMsg); 322 List<DataAccess.Variable<Object>> args = new LinkedList< DataAccess.Variable<Object>>(); 323 DataAccess.Variable<Object> var = new DataAccess.Variable<>('O', "file1", file, true); 324 args.add(var); 325 //executer.cmdQueue.addCmd(jzsub, args, file.getParentFile()); // to execute. 326 executer.cmdExecuter.addCmd(jzsub, args, Fcmd.this.gui.getOutputBox(), file.getParentFile()); 327 } 328 329 } 330 331 332 333 /** 334 * Key F4 for edit command. Its like Norton Commander. 335 */ 336 GralUserAction actionEdit = new GralUserAction("actionEdit") 337 { 338 @Override public boolean exec(int key, GralWidget_ifc wdg, Object... params) { 339 if(KeyCode.isControlFunctionMouseUpOrMenu(key)){ //supress both mouse up and down reaction 340 JZtxtcmdScript.Subroutine jzsub = buttonCmds.get("edit"); 341 if (jzsub == null) { 342 mainCmd.writeError("internal problem - don't find 'edit' command. "); 343 } else { 344 345 String sMsg = "GralCommandSelector - put cmd;" + jzsub.toString(); 346 System.out.println(sMsg); 347 List<DataAccess.Variable<Object>> args = main.getterFileArguments.getArguments(jzsub); 348 //executer.cmdQueue.addCmd(jzsub, args, Fcmd.this.currentFileCard.currentDir()); //to execute. 349 executer.cmdExecuter.addCmd(jzsub, args, Fcmd.this.gui.getOutputBox(), Fcmd.this.currentFileCard.currentDir()); 350 } 351 } 352 return true; 353 } 354 }; 355 356 357 358 /**This callback will be invoked in the drag event while the mouse is released in the destination. 359 */ 360 GralUserAction actionDragFileFromStatusLine = new GralUserAction("actionDragFileFromStatusLine"){ 361 @Override public boolean userActionGui(int key, GralWidget widgd, Object... params) { 362 if(key == KeyCode.dragFiles){ 363 String path = widgd.getValue(); 364 String[][] sFiles = (String[][])params[0]; //sFiles has lenght 1 365 sFiles[0] = new String[1]; 366 sFiles[0][0] = path; 367 Debugutil.stop(); 368 } 369 return true; 370 } 371 }; 372 373 /**This implementation resolves the arguments for invoked commands with the capabilities of the Fcmd. 374 * Especially the following argument strings are supported: 375 * <ul> 376 * <li> 377 * </ul> 378 * This instance is used only locally (private). It is designated as protected for documentation. 379 */ 380 protected CmdGetterArguments getterFileArguments = new CmdGetterArguments() 381 { 382 @Override public List<DataAccess.Variable<Object>> getArguments(JZtxtcmdScript.Subroutine subRoutine) { 383 FileRemote[] selFiles = getLastSelectedFiles(true, 1); //The selected 3 files, maybe in one card too. 384 List<DataAccess.Variable<Object>> args = new LinkedList<DataAccess.Variable<Object>>(); 385 if(subRoutine !=null) { 386 if(subRoutine.formalArgs !=null) { 387 for(JZtxtcmdScript.DefVariable arg :subRoutine.formalArgs){ 388 String name1 = arg.getVariableIdent(); 389 if(name1.equals("file1")){ args.add(new DataAccess.Variable<Object>('O', "file1", selFiles[0], true)); } 390 else if(name1.equals("file2")){ args.add(new DataAccess.Variable<Object>('O', "file2", selFiles[1], true)); } 391 else if(name1.equals("file3")){ args.add(new DataAccess.Variable<Object>('O', "file3", selFiles[2], true)); } 392 else if(name1.equals("dir1")){ args.add(new DataAccess.Variable<Object>('O', "dir1", selFiles[0] ==null ? null : selFiles[0].getParentFile(), true)); } 393 else if(name1.equals("dir2")){ 394 FileRemote dir = null; 395 if(lastFilePanels.size() >=2){ 396 FcmdFileCard fileCard = lastFilePanels.get(1).actFileCard; 397 if(fileCard !=null){ dir = fileCard.getCurrentDir(); } 398 } 399 args.add(new DataAccess.Variable<Object>('O', "dir2", dir, true)); 400 } 401 else if(name1.equals("dir3")){ 402 FileRemote dir = null; 403 if(lastFilePanels.size() >=3){ 404 FcmdFileCard fileCard = lastFilePanels.get(2).actFileCard; 405 if(fileCard !=null){ dir = fileCard.getCurrentDir(); } 406 } 407 args.add(new DataAccess.Variable<Object>('O', "dir3", dir, true)); 408 } 409 else if(name1.equals("listfiles1")) { 410 List<FileRemote> files = null; 411 if(lastFilePanels.size() >=1){ 412 FcmdLeftMidRightPanel filePanel = lastFilePanels.get(0); 413 FcmdFileCard fileCard = filePanel.actFileCard; 414 if(fileCard !=null){ 415 files = fileCard.getSelectedFiles(true, 1); 416 } 417 } 418 args.add(new DataAccess.Variable<Object>('L', "listfiles1", files, true)); 419 } 420 else if(name1.equals("listfiles2")) { 421 List<FileRemote> files = null; 422 if(lastFilePanels.size() >=2){ 423 FcmdFileCard fileCard = lastFilePanels.get(1).actFileCard; 424 if(fileCard !=null){ files = fileCard.getSelectedFiles(true, 1); } 425 } 426 args.add(new DataAccess.Variable<Object>('L', "listfiles2", files, true)); 427 } 428 else { 429 System.err.println("failded argument name: " + name1); 430 } 431 } 432 } 433 } else { 434 435 } 436 return args; 437 } 438 439 @Override public final File getCurrDir(){ return Fcmd.this.currentFileCard.currentDir(); } 440 }; 441 442 443 444 //MsgDispatchSystemOutErr msgDisp; 445 446 /**Set the singleton reference before other instances are initialized which uses main. */ 447 { Fcmd.main = this; 448 } 449 450 451 public JZtxtcmdScript.AddSub2List addButtonCmd = new JZtxtcmdScript.AddSub2List() { 452 453 454 @Override public void clear() { buttonCmds.clear(); } 455 456 @Override public void add2List(JZcmdClass jzclass, int level){} //not used 457 458 @Override public void add2List(Subroutine jzsub, int level) 459 { 460 buttonCmds.put(jzsub.name, jzsub); 461 } 462 463 }; 464 465 466 467 final CallingArgs cargs; 468 469 final MsgRedirectConsole msgDisp; 470 471 final FileCluster fileCluster = FileRemote.clusterOfApplication; 472 473 // GralTabbedPanel tabbedPanelsLeft, tabbedPanelsMid, tabbedPanelsRight; 474 475 final FcmdWindowMng windMng = new FcmdWindowMng(this); 476 477 final FcmdButtons fButtons = new FcmdButtons(this); 478 479 final FcmdStatusLine statusLine = new FcmdStatusLine(this); 480 481 final String nameTextFieldInfo = "file-info"; 482 483 final String nameTextFieldFilePath = "file-path"; 484 485 final String nameTextFieldRunInfo = "run-info"; 486 487 GralPanelContent panelButtons; 488 489 490 final FcmdFavorPathSelector favorPathSelector = new FcmdFavorPathSelector(mainCmd, this); 491 492 final FcmdExecuter executer = new FcmdExecuter(mainCmd, gui.getOutputBox(), this); 493 494 final FcmdSettings settings = new FcmdSettings(this); 495 496 final FcmdStatus status = new FcmdStatus(this); 497 498 final FcmdFileProps filePropsCmd = new FcmdFileProps(this); 499 500 final FcmdView viewCmd = new FcmdView(this); 501 502 final FcmdEdit editWind = new FcmdEdit(this); 503 504 final FcmdCopyCmprDel copyCmd = new FcmdCopyCmprDel(this, FcmdCopyCmprDel.Ecmd.copy); 505 506 final FcmdCopyCmprDel delCmd = new FcmdCopyCmprDel(this, FcmdCopyCmprDel.Ecmd.delete); 507 508 final FcmdCopyCmprDel compareCmd = new FcmdCopyCmprDel(this, FcmdCopyCmprDel.Ecmd.compare); 509 510 final FcmdMkDirFile mkCmd = new FcmdMkDirFile(this); 511 512 final FcmdDelete deleteCmd = new FcmdDelete(this); 513 514 final FcmdFilesCp filesCp = new FcmdFilesCp(this); 515 516 final FcmdKeyActions keyActions = new FcmdKeyActions(this); 517 518 /** 519 * Note: this should be the last aggregate of Fcmd because it uses some other ones. */ 520 final FcmdIdents idents = new FcmdIdents(this); 521 522 523 /**The current directory of the last selected file. */ 524 //FileRemote currentFile; 525 526 /**The last selected files of the three panels, [0] for left .. [2] for right. */ 527 final File[] selectedFiles123 = new File[3]; 528 529 530 /**The last selected file panels in its order of selection. 531 * This list contains max 3 entries. 532 * To get the last selected files: The panel knows the last used file card there. 533 */ 534 List<FcmdLeftMidRightPanel> lastFilePanels = new LinkedList<FcmdLeftMidRightPanel>(); 535 536 /**The last used favor card or its last used file card. 537 * It is used for delete tab. */ 538 FcmdFavorCard lastFavorCard; 539 540 FcmdFileCard currentFileCard; 541 542 543 final Map<String, GralFileSelector> idxFileSelector = new TreeMap<String, GralFileSelector>(); 544 545 546 FcmdtTarget_ifc target; 547 548 549 /** 550 * The commands which are used for some buttons or menu items from the 551 * JavaCommander itself. 552 */ 553 final Map<String, JZtxtcmdScript.Subroutine> buttonCmds; 554 555 556 final List<Closeable> threadsToClose = new LinkedList<Closeable>(); 557 558 /**Static reference for the main instance to access from any class in the package. 559 * This static instance is set firstly in constructor, all other constructors in this package 560 * can be used it therefore. Use {@link #main()}*/ 561 private static Fcmd main; 562 563 564 public Fcmd(CallingArgs cargs, GralArea9MainCmd cmdgui) 565 { 566 super(cargs, cmdgui, null, null, null); 567 this.cargs = cargs; 568 //redirect all outputs to System.out, System.err and MainCmd to System.out and System.err with timestamp. 569 msgDisp = new MsgRedirectConsole(cmdgui, 0, null); 570 msgDisp.setIdThreadForMsgDispatching(Thread.currentThread().getId()); 571 //msgDisp.msgDispatcher.setOutputRoutine(4, "MainLogFile", true, true, cmdgui.getLogMessageOutputFile()); 572 //msgDisp.msgDispatcher.setOutputRange(0, 100000, 4, MsgDispatcher.mAdd, 0); 573 actionReadMsgConfig.exec(KeyCode.menuEntered, null); 574 575 target = new FcmdtTarget(); //create the target itself, one process TODO experience with remote target. 576 buttonCmds = new TreeMap<String, JZtxtcmdScript.Subroutine>(); 577 //executer.cmdQueue.setOutput(gui.getOutputBox(), null); 578 } 579 580 581 /**Access the static instance of Fcmd. 582 * This static instance is set firstly in constructor, all other constructors in this package 583 * can be used it therefore. 584 */ 585 static Fcmd main(){ return main; } 586 587 588 /** 589 * Initializes the areas for the panels and configure the panels. Note that 590 * the window is initialized with an output area already. This is used for 591 * output messages if problems occurs while build the rest of the GUI. 592 */ 593 @Override 594 protected void initGuiAreas(String sAreaMainPanel) 595 { 596 //panelBuildIfc.registerUserAction("KeyAction", 597 // keyActions.commanderKeyActions); // all key actions, registered central 598 599 gui.setFrameAreaBorders(30, 65, 70, 85); // x1, x2, y1, y2 600 //gui.setStandardMenusGThread(new File("."), actionFile); 601 //gui.addMenuItemGThread("menuBarFavorsLeft", idents.menuBarNavigationLeft, selectCardThemesLeft); 602 //gui.addMenuItemGThread("menuBarFavorsMiddle", idents.menuBarNavigationMiddle, selectCardThemesMiddle); 603 //gui.addMenuItemGThread("menuBarFavorsRight", idents.menuBarNavigationRight, selectCardThemesRight); 604 //gui.addMenuItemGThread("menuBarNavigatonCmd", idents.menuBarNavigatonCmd, actionFocusCmdCard); 605 606 // gui.set 607 608 // Creates tab-Panels for the file lists and command lists. 609 _gralMng.selectPanel("primaryWindow"); 610 favorPathSelector.panelLeft.tabbedPanelFileCards = _gralMng.addTabbedPanel("File0Tab", null, GralMngBuild_ifc.propZoomedPanel); 611 gui.addFrameArea("A1A1", favorPathSelector.panelLeft.tabbedPanelFileCards); // dialogPanel); 612 613 favorPathSelector.panelLeft.buildInitialTabs(); 614 _gralMng.selectPanel("primaryWindow"); 615 favorPathSelector.panelMid.tabbedPanelFileCards = _gralMng.addTabbedPanel("File1Tab", null, GralMngBuild_ifc.propZoomedPanel); 616 gui.addFrameArea("B1B1", favorPathSelector.panelMid.tabbedPanelFileCards); // dialogPanel); 617 favorPathSelector.panelMid.buildInitialTabs(); 618 619 _gralMng.selectPanel("primaryWindow"); 620 favorPathSelector.panelRight.tabbedPanelFileCards = _gralMng.addTabbedPanel("File2Tab", null, GralMngBuild_ifc.propZoomedPanel); 621 gui.addFrameArea("C1C1", favorPathSelector.panelRight.tabbedPanelFileCards); // dialogPanel); 622 favorPathSelector.panelRight.buildInitialTabs(); 623 624 _gralMng.selectPanel("primaryWindow"); 625 panelButtons = _gralMng.createGridPanel("Buttons", _gralMng.getColor("gr"), 1, 1, 10, 10); 626 gui.addFrameArea("A3C3", panelButtons); // dialogPanel); 627 628 filesCp.buildGraphic(); 629 settings.buildWindow(); //F2 630 status.buildWindow(); //F2 631 filePropsCmd.buildWindow(); //F2 632 viewCmd.buildWindowView(); //F3 633 editWind.buildWindow(); //F3 634 copyCmd.buildWindowConfirmCopy("confirm copy / move / compare"); 635 delCmd.buildWindowConfirmCopy("confirm delete"); 636 compareCmd.buildWindowConfirmCopy("confirm compare"); 637 mkCmd.buildWindowConfirmMk(); 638 executer.buildWindowConfirmExec(); 639 deleteCmd.buildWindowConfirmDelete(); //F8 640 favorPathSelector.buildWindowAddFavorite(); 641 642 fButtons.initPanelButtons(); 643 GralMenu menu = gui.getMenuBar(); 644 menu.addMenuItem("MenuSetWorkingDir", "&Command/Set&WorkingDir", executer.actionSetCmdWorkingDir); // / 645 menu.addMenuItem("MenuCommandAbort", "&Command/&Abort", executer.actionCmdAbort); // / 646 // gui.addMenuItemGThread("&Command/E&xecute", actionSetCmdCurrentDir); /// 647 menu.addMenuItem("MenuCmdCfgSet", "&Command/CmdCf&g - read current file", executer.actionSetCmdCfg); // / 648 649 menu.addMenuItem("menuHelp", idents.menuHelpBar, gui.getActionHelp()); 650 menu.addMenuItem("menuAbout", idents.menuBarAbout, gui.getActionAbout()); 651 menu.addMenuItem("MenuTestInfo", "&Help/&Infobox", actionTest); 652 guiW.outputBox.setActionChange(executer.actionCmdFromOutputBox); 653 String sHelpUrlDir = cargs.dirHtmlHelp.getAbsolutePath(); 654 gui.setHelpUrl(sHelpUrlDir + "/Fcmd.html"); 655 lastFilePanels.clear(); 656 lastFilePanels.add(favorPathSelector.panelMid); 657 lastFilePanels.add(favorPathSelector.panelRight); 658 lastFilePanels.add(favorPathSelector.panelLeft); 659 favorPathSelector.panelMid.cardFavorThemes.setFocus(); 660 } 661 662 @Override 663 protected final void initMain() 664 { 665 if (cargs.fileCfgCmds == null) { 666 mainCmd.writeError("Argument cmdcfg:CONFIGFILE should be given."); 667 // mainCmd.e 668 } else if (cargs.fileCmdsForExt == null) { 669 mainCmd.writeError("Argument cmdext:CONFIGFILE should be given."); 670 // mainCmd.e 671 } else if (cargs.fileCfgButtonCmds == null) { 672 mainCmd.writeError("Argument cmdButton:CONFIGFILE should be given."); 673 // mainCmd.e 674 } else if (cargs.fileSelectTabPaths == null) { 675 mainCmd.writeError("Argument sel:SELECTFILE should be given."); 676 // mainCmd.e 677 } else { 678 String sError; 679 File fileCfg; 680 sError = executer.readCmdCfgSelectList(executer.cmdSelector.addJZsub2SelectTable, fileCfg = cargs.fileCfgCmds, console); 681 if(sError !=null) { 682 showInfoBox(sError); 683 } else { 684 appendTextInfoBox("read config cmd"); 685 } 686 if (sError == null) { 687 //sError = executer.readCmdFile(fileCfg = cargs.fileCmdsForExt); 688 sError = executer.readCfgExt(new File(cargs.dirCfg, "extjz.cfg")); 689 } 690 if (sError == null) { 691 sError = JZtxtcmd.readJZcmdCfg(addButtonCmd, fileCfg = cargs.fileCfgButtonCmds, console, executer.cmdExecuter); 692 } 693 if (sError == null) { 694 sError = favorPathSelector.readCfg(fileCfg = cargs.fileSelectTabPaths); 695 } 696 if (sError != null) { 697 mainCmd.writeError("Error reading " + fileCfg.getAbsolutePath() + ": " 698 + sError); 699 } 700 } 701 super.initMain(); // starts initializing of graphic. Do it after config 702 // command selector! 703 704 } 705 706 /** 707 * Executing in the main thread loop. It handles commands. 708 * 709 * @see org.vishia.gral.area9.GuiCfg#stepMain() 710 */ 711 @Override public void stepMain() 712 { 713 Appendable writeStatusCmd = new Appendable(){ 714 715 @Override public Appendable append(CharSequence csq) throws IOException 716 { statusLine.widgRunInfo.setText(csq); 717 return this; 718 } 719 720 @Override public Appendable append(char c) throws IOException 721 { if(c == '\0') statusLine.widgRunInfo.setText(" "); 722 else statusLine.widgRunInfo.setText("" + c); 723 return this; 724 } 725 726 @Override public Appendable append(CharSequence csq, int start, int end) throws IOException 727 { statusLine.widgRunInfo.setText(csq.subSequence(start, end)); 728 return null; 729 } 730 731 }; 732 733 //executer.cmdQueue.execCmds(writeStatusCmd); 734 executer.cmdExecuter.executeCmdQueue(false); 735 long time = System.currentTimeMillis(); 736 favorPathSelector.panelLeft.checkRefresh(time); 737 favorPathSelector.panelMid.checkRefresh(time); 738 favorPathSelector.panelRight.checkRefresh(time); 739 } 740 741 742 743 /** 744 * Executing in the main thread loop. It handles commands. 745 * 746 * @see org.vishia.gral.area9.GuiCfg#stepMain() 747 */ 748 @Override public void finishMain() 749 { 750 try{ 751 executer.cmdExecuter.close(); //finishes threads. 752 target.close(); 753 FileAccessorLocalJava7.getInstance().close(); 754 } catch(IOException exc){ 755 756 } 757 } 758 759 760 void setLastSelectedPanel(FcmdLeftMidRightPanel panel){ 761 if(lastFilePanels.size() == 0){ 762 lastFilePanels.add(0, panel); //first time only 763 } 764 else if(lastFilePanels.get(0) != panel) { //do nothing if the panel is the first one. 765 if(!lastFilePanels.remove(panel)){ //if it is in list on higher position 766 System.err.println("Fcmd - setLastSelectedPanel() faulty; try remove panel=" + panel.toString()); 767 //The file panel should be known! 768 } 769 lastFilePanels.add(0, panel); 770 } 771 772 } 773 774 /**Get the last selected files in order of selection of the file panels. 775 * If the current file of any panel is marked, then all other marked files (but not directories) 776 * of this panel are taken as next files. But only 3 at all. 777 * It is possible to mark two files in one file panel to execute an application with them. 778 * New method since 2011-12-23 779 * @return array[3] of the last selected files in the file panels. It has always a length of 3 780 * but not all elements are set ( they are ==null) if no files were selected before. 781 * The returned instance is a new one, not referenced elsewhere. It can be stored 782 * and it remains the situation of selection files independently of further user actions. 783 */ 784 FileRemote[] getLastSelectedFiles(boolean bAlsoDirs, int mask){ 785 FileRemote[] ret = new FileRemote[3]; 786 int ix = -1; 787 Iterator<FcmdLeftMidRightPanel> iterPanel = lastFilePanels.iterator(); 788 while(ix < 2 && iterPanel.hasNext() ){ 789 FcmdLeftMidRightPanel panel = iterPanel.next(); 790 //for(FcmdLeftMidRightPanel panel: lastFilePanels){ 791 FcmdFileCard fileCard = panel.actFileCard; 792 if(fileCard !=null){ 793 ret[++ix] = fileCard.currentFile(); 794 if(fileCard.currentFile() !=null && fileCard.currentFile().isMarked(0x1)){ 795 //if the current file is marked, use all marked files. 796 List<FileRemote> listFiles = fileCard.getSelectedFiles(bAlsoDirs, mask); 797 //NOTE: the currentFile was marked, but it was not existing after delete. In this case all is okay but listFiles is empty. 798 assert(listFiles !=null); // && listFiles.size() > 0); //at least the current file is marked. 799 Iterator<FileRemote> iter= listFiles.iterator(); 800 while(ix < 2 && iter.hasNext()){ 801 FileRemote file = iter.next(); 802 if(file != fileCard.currentFile()){ 803 ret[++ix] = file; 804 } 805 } 806 } 807 } else { 808 //ret[++ix] = null; //the panel hasn't a file selected now. 809 } 810 } 811 //Note: There may be less than 3 file panels, rest of files are null. 812 return ret; 813 } 814 815 816 /**Get the last selected file cards in order of selection of the file panels. 817 * @return array[3] of the last selected file cards in the file panels. It has always a length of 3 818 * but not all elements are set ( they are ==null) if the file cards are not opened before 819 * in the panel. 820 * The returned instance is a new one, not referenced elsewhere. It can be stored 821 * and it remains the situation of selection files independently of further user actions. 822 */ 823 FcmdFileCard[] getLastSelectedFileCards(){ 824 FcmdFileCard[] ret = new FcmdFileCard[3]; 825 int ix = -1; 826 for(FcmdLeftMidRightPanel panel: lastFilePanels){ 827 FcmdFileCard fileCard = panel.actFileCard; 828 if(fileCard !=null){ 829 ret[++ix] = fileCard; 830 } else { 831 ret[++ix] = null; //the panel hasn't a file selected now. 832 } 833 if(ix >=2) break; //prevent exception because older error 834 } 835 //Note: There may be less than 3 file panels, rest of files are null. 836 return ret; 837 } 838 839 840 841 /**Get the last selected file cards in order of selection of the file panels. 842 * @return array[3] of the last selected file cards in the file panels. It has always a length of 3 843 * but not all elements are set ( they are ==null) if the file cards are not opened before 844 * in the panel. 845 * The returned instance is a new one, not referenced elsewhere. It can be stored 846 * and it remains the situation of selection files independently of further user actions. 847 */ 848 List<File>[] getLastSelectedFilesPerCard(){ 849 @SuppressWarnings("unchecked") 850 List<File>[] ret = new List[3]; 851 int ix = -1; 852 for(FcmdLeftMidRightPanel panel: lastFilePanels){ 853 FcmdFileCard fileCard = panel.actFileCard; 854 if(fileCard !=null){ 855 List<FileRemote> list = fileCard.getSelectedFiles(true, 0x1); 856 ret[++ix] = new ArrayList<File>(); 857 for(File file: list) { ret[ix].add(file); } 858 } else { 859 ret[++ix] = null; //the panel hasn't a file selected now. 860 } 861 if(ix >=2) break; //prevent exception because older error 862 } 863 //Note: There may be less than 3 file panels, rest of files are null. 864 return ret; 865 } 866 867 868 869 870 871 /**Get the last selected file card in order of selection of the file panels. 872 * @return The file card reference. */ 873 FcmdFileCard getLastSelectedFileCard(){ 874 875 if(lastFavorCard!=null){ 876 return lastFavorCard.fileTable; 877 } else { 878 return null; 879 } 880 } 881 882 883 884 885 FileRemote currentFile(){ 886 if(this.currentFileCard == null) return null; 887 else return this.currentFileCard.currentFile(); 888 } 889 890 891 FileRemote currentDir(){ 892 if(this.currentFileCard == null) return null; 893 else return this.currentFileCard.currentDir(); 894 } 895 896 897 /**Refreshes the {@link FcmdFileCard} if the dir is the current one. 898 * This method can be invoked in any for example callback routine in any thread, which changes the content of directories. 899 * Note: It starts {@link GralFileSelector#fillIn(FileRemote, boolean)} which refreshes the files 900 * @param fileOrDir The changed file or its directory. 901 * it is checked whether the directory is shown currently in one of the three file panels, then the panel will be refreshed. 902 * If the directory is not shown yet then nothing is done. 903 * Note that a directory will be refreshed whenever it will be activated in a panel. 904 */ 905 protected void refreshFilePanel(FileRemote fileOrDir) 906 { 907 FileRemote dir = fileOrDir.isDirectory() ? fileOrDir: fileOrDir.getParentFile(); 908 for(FcmdLeftMidRightPanel panel: lastFilePanels) { 909 if(panel !=null && panel.actFileCard !=null && panel.actFileCard.currentDir() == dir) { 910 panel.actFileCard.fillInCurrentDir(); 911 } 912 } 913 } 914 915 916 917 918 919 /** 920 * This class is instantiated in the static main routine and builds a command 921 * line interface and the graphical frame. The mainly functionality is 922 * contained in the super class. 923 */ 924 private static class FcmdMainCmd extends GralArea9MainCmd 925 { 926 927 private final CallingArgs cargs; 928 929 public FcmdMainCmd(CallingArgs cargs, String[] args) 930 { 931 super(cargs, args); 932 this.cargs = cargs; 933 super.addAboutInfo("The.file.Commander"); 934 super.addAboutInfo("made by Hartmut Schorrig, www.vishia.org, hartmut.schorrig@vishia.de"); 935 super.addAboutInfo("Version-date: " + Fcmd.version); 936 } 937 938 @Override protected boolean testArgument(String arg, int nArg) 939 { 940 boolean bOk = true; 941 if (arg.startsWith("cfg:")) { 942 cargs.dirCfg = new File(arg.substring(4)); 943 } else if (arg.startsWith("cmdcfg:")) { 944 cargs.fileCfgCmds = new File(arg.substring(7)); 945 } else if (arg.startsWith("cmdext:")) { 946 cargs.fileCmdsForExt = new File(arg.substring(7)); 947 } else if (arg.startsWith("cmdButton:")) { 948 cargs.fileCfgButtonCmds = new File(arg.substring(10)); 949 } else if (arg.startsWith("sel:")) { 950 cargs.fileSelectTabPaths = new File(arg.substring(4)); 951 } else { 952 bOk = super.testArgument(arg, nArg); 953 } 954 return bOk; 955 } 956 957 @Override protected boolean checkArguments(){ 958 boolean bOk = true; 959 if(cargs.dirCfg == null) { bOk = false; writeError("cmdline argument cfg:PATHCFG is missing"); } 960 if(bOk){ 961 if(!cargs.dirCfg.exists()){ bOk = false; writeError("cmdline argument cfg is faulty:" + cargs.dirCfg.getAbsolutePath());} 962 } 963 if(bOk){ 964 if(cargs.dirHtmlHelp ==null){ cargs.dirHtmlHelp = new File(cargs.dirCfg, "../help"); } 965 if(cargs.fileCfgCmds ==null){ cargs.fileCfgCmds = new File(cargs.dirCfg, "cmd.cfg"); } 966 if(cargs.fileCmdsForExt ==null){ cargs.fileCmdsForExt = new File(cargs.dirCfg, "ext.cfg"); } 967 if(cargs.fileCfgButtonCmds ==null){ cargs.fileCfgButtonCmds = new File(cargs.dirCfg, "cmdi.cfg"); } 968 if(cargs.fileSelectTabPaths ==null){ cargs.fileSelectTabPaths = new File(cargs.dirCfg, "path.cfg"); } 969 } 970 return bOk; 971 } 972 973 } // class MainCmd 974 975 976 static void testT1() 977 { 978 float R = 10000.0f; 979 float C = 0.000000001f; 980 float tStep = 0.0000001f; 981 float uc = 0.0f; 982 float ue = 1.0f; 983 for (int step = 0; step < 100; ++step) { 984 float iR = (ue - uc) / R; 985 uc = uc + iR / C * tStep; 986 } 987 988 } 989 990 /** 991 * The command-line-invocation (primary command-line-call. 992 * 993 * @param args 994 * Some calling arguments are taken. This is the GUI-configuration 995 * especially. 996 */ 997 public static void main(String[] args) 998 { 999 testT1(); 1000 boolean bOk = true; 1001 CallingArgs cargs = new CallingArgs(); 1002 // Initializes the GUI till a output window to show information. 1003 // Uses the commonly GuiMainCmd class because here are not extra arguments. 1004 GralArea9MainCmd cmdgui = new FcmdMainCmd(cargs, args); // implements MainCmd, parses 1005 //new GralMng(null, cmdgui); 1006 1007 // calling arguments 1008 bOk = cmdgui.parseArgumentsAndInitGraphic("The.file.Commander", "2A2C", '.', "0+50,0+150"); 1009 1010 /* 1011 try { 1012 cmdgui.parseArguments(); 1013 } catch (Exception exception) { 1014 cmdgui.writeError("Cmdline argument error:", exception); 1015 cmdgui.setExitErrorLevel(MainCmd_ifc.exitWithArgumentError); 1016 bOk = false; // not exiting, show error in GUI 1017 } 1018 */ 1019 if (bOk) { 1020 // Uses socket communication for InterprocessComm, therefore load the 1021 // factory. 1022 new InterProcessCommFactorySocket(); 1023 // 1024 // Initialize this main class and execute. 1025 Fcmd main = new Fcmd(cargs, cmdgui); 1026 //main.msgDisp = MsgDispatchSystemOutErr.create(); 1027 main.execute(); 1028 } 1029 cmdgui.exit(); 1030 } 1031 1032 1033 1034 1035}