    001package org.vishia.guiBzr;
    002
    003import java.io.File;
    004import java.util.LinkedList;
    005import java.util.List;
    006import java.util.Map;
    007import java.util.TreeMap;
    008
    009import org.vishia.gral.base.GralTable;
    010import org.vishia.gral.base.GralTable;
    011import org.vishia.gral.base.GralWidget;
    012import org.vishia.gral.ifc.GralColor;
    013import org.vishia.gral.ifc.GralMngBuild_ifc;
    014import org.vishia.gral.ifc.GralMng_ifc;
    015import org.vishia.gral.ifc.GralTable_ifc;
    016import org.vishia.gral.ifc.GralUserAction;
    017import org.vishia.gral.ifc.GralTableLine_ifc;
    018import org.vishia.util.KeyCode;
    019
    020public class GuiFilesDiffPanel
    021{
    022  /**Version, able to read as hex yyyymmdd.
    023   * Changes:
    024   * <ul>
    025   * <li>2011-05-17 Button view & diff now used. It produces bzr diff FILE in the output panel.
    026   * <li>2011-05-01 Hartmut: Created
    027   * </ul>
    028   */
    029  public final static int version = 0x20110617;
    030
    031  /**Aggregation to the main data of the GUI. */
    032  final MainData mainData;
    033
    034  /**Aggregation to the build interface of the manager where the panel is member of. */
    035  final GralMngBuild_ifc panelBuildifc;
    036
    037  final StringBuilder uRenameOut =  new StringBuilder();
    038
    039  /**The table (list) which contains the selectable project paths. */
    040  private GralTable widgdTableFilesCmpn;
    041
    042
    043  private static final int columnMark = 2;
    044
    045  private static final GralColor colorMarked = new GralColor(128,255, 128);  //light green
    046
    047  private static final GralColor colorNonMarked = new GralColor(255,255, 255);  //white
    048
    049  final Map<String, GralTableLine_ifc> indexMarkedFiles = new TreeMap<String, GralTableLine_ifc>();
    050
    051
    052  public GuiFilesDiffPanel(MainData mainData, GralMngBuild_ifc panelBuildifc)
    053  {
    054    this.panelBuildifc = panelBuildifc;
    055    this.mainData = mainData;
    056  }
    057
    058  /**Initializes the graphic.
    059   * It will be called in the GUI-Thread.
    060   */
    061  void initGui()
    062  { panelBuildifc.selectPanel("FilesDiff");
    063    panelBuildifc.setPositionSize(2,0, 30, 60, 'r');
    064    int[] columnWidths = {40, 10, 2,8};
    065
    066    widgdTableFilesCmpn = panelBuildifc.addTable("selectFile", 20, columnWidths);
    067    widgdTableFilesCmpn.setActionChange(actionTableLineFile);
    068    panelBuildifc.setPositionSize(2, 61, 3, 9, 'd');
    069    panelBuildifc.addButton("refresh", actionRefresh, "&refresh");
    070    panelBuildifc.addButton("view", actionView, "&view");
    071    panelBuildifc.addButton("diff", actionViewdiff, "view &diff");
    072    //panelBuildifc.addButton("add", actionAdd, "&add");
    073    panelBuildifc.setPositionSize(13, 61, 3, 9, 'd');
    074    panelBuildifc.addButton("rename", actionRename, "&rename");
    075    panelBuildifc.addButton("commit", actionCommit, "&commit");
    076
    077  }
    078
    079
    080  void fillFileTable(DataCmpn cmpn)
    081  {
    082    widgdTableFilesCmpn.setValue(GralMng_ifc.cmdClear, -1, null);  //clear the whole table
    083    String sLastDirectory = "";
    084    List<DataFile> listDataFileInDirectory = new LinkedList<DataFile>();
    085    boolean bLastWasDirectoryBlock = false;
    086    for(Map.Entry<String, DataFile> entry: cmpn.indexFiles.entrySet()){
    087        DataFile dataFile = entry.getValue();
    088        int pos =       dataFile.sLocalpath.lastIndexOf('/');
    089        String sDirectory = dataFile.sLocalpath.substring(0, pos+1);
    090      if(!sDirectory.equals(sLastDirectory)){
    091        //write the last appendix of a directory block or file.
    092        bLastWasDirectoryBlock = writeAppendixInFileTable(listDataFileInDirectory, sLastDirectory
    093                , bLastWasDirectoryBlock);
    094        //clear and init:
    095        listDataFileInDirectory.clear();
    096        sLastDirectory = sDirectory;
    097      }
    098      listDataFileInDirectory.add(dataFile);
    099    }
    100    //write the last appendix:
    101    writeAppendixInFileTable(listDataFileInDirectory, sLastDirectory, bLastWasDirectoryBlock);
    102  }
    103
    104
    105  private boolean writeAppendixInFileTable(List<DataFile> listDataFileInDirectory, String sLastDirectory
    106        , boolean bLastWasDirectoryBlock)
    107  { StringBuilder uLine = new StringBuilder(200);
    108          if(listDataFileInDirectory.size() >=3){ //if at least 3 files, write directory line above
    109                  uLine.setLength(0);
    110                        uLine.append(sLastDirectory).append("\t------------\t \tdir");
    111            widgdTableFilesCmpn.setValue(GralMng_ifc.cmdInsert, 99999, uLine.toString());
    112            bLastWasDirectoryBlock = true;
    113                } else {
    114                        if(bLastWasDirectoryBlock){
    115                                uLine.setLength(0);
    116                        uLine.append("----------------------------\t------------\t \tdir");
    117              widgdTableFilesCmpn.setValue(GralMng_ifc.cmdInsert, 99999, uLine.toString());
    118            }
    119                        bLastWasDirectoryBlock = false;
    120                }
    121                //TODO add at last!!!
    122                for(DataFile file: listDataFileInDirectory){
    123                  uLine.setLength(0);
    124                        uLine.append(file.sLocalpath).append("\t");
    125            if(file.dateFile !=0){
    126              uLine.append(mainData.formatTimestampYesterday(file.dateFile));
    127            } else {
    128              uLine.append("unknown");
    129            }
    130            uLine.append("\t \t").append(file.sType);
    131            widgdTableFilesCmpn.setValue(GralMng_ifc.cmdInsert, 99999, uLine.toString());
    132                }
    133                return bLastWasDirectoryBlock;
    134  }
    135
    136
    137
    138
    139  void xxxfillFileTable(DataCmpn cmpn)
    140  {
    141    widgdTableFilesCmpn.setValue(GralMng_ifc.cmdClear, -1, null);  //clear the whole table
    142    if(cmpn.listModifiedFiles !=null) for(DataFile file: cmpn.listModifiedFiles){
    143      //String name = file.getName();
    144      StringBuilder uLine = new StringBuilder(200);
    145      uLine.append(file.sLocalpath).append("\t");
    146      if(file.dateFile !=0){
    147        uLine.append(mainData.formatTimestampYesterday(file.dateFile));
    148      } else {
    149        uLine.append("unknown");
    150      }
    151      uLine.append("\t \tchg");
    152      widgdTableFilesCmpn.setValue(GralMng_ifc.cmdInsert, 99999, uLine.toString());
    153    }
    154    if(cmpn.listAddFiles !=null) for(DataFile file: cmpn.listAddFiles){
    155      //String name = file.getName();
    156      StringBuilder uLine = new StringBuilder(200);
    157      uLine.append(file.sLocalpath).append("\t");
    158      if(file.dateFile !=0){
    159        uLine.append(mainData.formatTimestampYesterday(file.dateFile));
    160      } else {
    161        uLine.append("unknown");
    162      }
    163      uLine.append("\t \tadd");
    164      widgdTableFilesCmpn.setValue(GralMng_ifc.cmdInsert, 99999, uLine.toString());
    165    }
    166    if(cmpn.listNewFiles !=null) for(DataFile file: cmpn.listNewFiles){
    167      //String name = file.getName();
    168      StringBuilder uLine = new StringBuilder(200);
    169      uLine.append(file.sLocalpath).append("\t");
    170      if(file.dateFile !=0){
    171        uLine.append(mainData.formatTimestampYesterday(file.dateFile));
    172      } else {
    173        uLine.append("unknown");
    174      }
    175      uLine.append("\t \tnew");
    176      widgdTableFilesCmpn.setValue(GralMng_ifc.cmdInsert, 99999, uLine.toString());
    177    }
    178    if(cmpn.listRenamedFiles !=null) for(DataFile file: cmpn.listRenamedFiles){
    179      //String name = file.getName();
    180      StringBuilder uLine = new StringBuilder(200);
    181      uLine.append(file.sLocalpath).append("\t");
    182      if(file.dateFile !=0){
    183        uLine.append(mainData.formatTimestampYesterday(file.dateFile));
    184      } else {
    185        uLine.append("unknown");
    186      }
    187      uLine.append("\t \tmove");
    188      widgdTableFilesCmpn.setValue(GralMng_ifc.cmdInsert, 99999, uLine.toString());
    189    }
    190    if(cmpn.listRemovedFiles !=null) for(DataFile file: cmpn.listRemovedFiles){
    191      //String name = file.getName();
    192      StringBuilder uLine = new StringBuilder(200);
    193      uLine.append(file.sLocalpath).append("\t");
    194      if(file.dateFile !=0){
    195        uLine.append(mainData.formatTimestampYesterday(file.dateFile));
    196      } else {
    197        uLine.append("unknown");
    198      }
    199      uLine.append("\t \tdel");
    200      widgdTableFilesCmpn.setValue(GralMng_ifc.cmdInsert, 99999, uLine.toString());
    201    }
    202  }
    203
    204
    205
    206
    207  /**Action for mark a line. It is the actionChange for the table. This action will be called
    208   * on any key events or mouse events on the table.
    209   * The action method returns true if the key or mouse is used.
    210   * Here it is the space bar or enter to mark a line.
    211   * */
    212  private final GralUserAction actionTableLineFile = new GralUserAction()
    213  {
    214    @Override
    215    public boolean userActionGui(String sCmd, GralWidget widgetInfos, Object... values)
    216    { boolean bDone = false;
    217      return bDone;
    218    }
    219
    220    @Override
    221    public boolean userActionGui(int key, GralWidget widgetInfos, Object... values)
    222    { boolean bDone = true;
    223      if(key == KeyCode.enter || key == ' '){
    224        GralTableLine_ifc line = (GralTableLine_ifc) values[0];
    225        String isMarked = line.getCellText(columnMark);
    226        if(isMarked.equals("*")) {
    227          line.setCellText("", columnMark);
    228          line.setBackgroundColor(colorNonMarked);
    229          String sFile = line.getCellText(0);
    230          indexMarkedFiles.remove(sFile);
    231        } else {
    232          line.setCellText("*", columnMark);
    233          line.setBackgroundColor(colorMarked);
    234          String sFile = line.getCellText(0);
    235          String sType = line.getCellText(3);
    236          indexMarkedFiles.put(sFile, line);
    237        }
    238      } else { bDone = false; }
    239      return bDone;
    240    }
    241  };
    242
    243
    244  private final GralUserAction actionAdd = new GralUserAction()
    245  {
    246    @Override
    247    public boolean userActionGui(int key, GralWidget widgetInfos, Object... values)
    248    {
    249      return true;
    250    }
    251  };
    252
    253
    254  private final GralUserAction actionRename = new GralUserAction()
    255  {
    256    @Override
    257    public boolean userActionGui(int key, GralWidget widgetInfos, Object... values)
    258    { if(KeyCode.isControlFunctionMouseUpOrMenu(key)){
    259        String sFileOld =null, sFileNew =null;
    260        GralTableLine_ifc lineOld = null, lineNew = null;
    261        for(Map.Entry<String, GralTableLine_ifc> entry: indexMarkedFiles.entrySet()){
    262          GralTableLine_ifc line = entry.getValue();
    263          String sType = line.getCellText(3);
    264          String sFile = entry.getKey();
    265          if(sType.equals("del")){
    266            sFileOld = sFile;
    267            lineOld = line;
    268          }
    269          else if(sType.equals("new")){
    270            sFileNew = sFile;
    271            lineNew = line;
    272          }
    273        }
    274
    275        if(sFileOld !=null && sFileNew !=null){
    276          //mainData.log
    277          lineOld.setCellText("old", 3);
    278          lineNew.setCellText("ren", 3);
    279          //String sCmd = "bzr mv " + sFileOld + " " + sFileNew;
    280          StringBuilder uCmd = new StringBuilder(200);
    281          String sCmd = mainData.cfg.indexCmds.get("moveFile");
    282          uCmd.append(sCmd);
    283          int pos = uCmd.indexOf("$Oldfile");
    284          if(pos >=0){
    285                uCmd.replace(pos, pos + 8, sFileOld);
    286          } else {
    287                //what todo
    288          }
    289          pos = uCmd.indexOf("$Newfile");
    290          if(pos >=0){
    291                uCmd.replace(pos, pos + 8, sFileNew);
    292          } else {
    293                //what todo
    294          }
    295          mainData.cmdExec.execute(uCmd.toString(), null, uRenameOut, uRenameOut);
    296          mainData.mainCmdifc.writeInfoln(sCmd + "\n" + uRenameOut);
    297        }
    298        refreshFiles();
    299      }
    300      return true;
    301    }
    302  };
    303
    304
    305
    306  private void refreshFiles()
    307  {
    308        indexMarkedFiles.clear();
    309        //gets the status of the components archive in the GUI-action,
    310    //because the appearance of the GUI should be updated:
    311    mainData.getterStatus.captureStatus(mainData.currCmpn);
    312    //
    313    mainData.getterStatus.initListFiles();
    314    fillFileTable(mainData.currCmpn);
    315    mainData.panelAccess.redrawWidget("selectFile");
    316  }
    317
    318
    319
    320  void commitSelectedFiles()
    321  {
    322        File fileCommitText = mainData.mainAction.getContentofCommitText();
    323    if(fileCommitText == null){
    324      mainData.mainCmdifc.writeError("The commit text is empty. Please write there: Commit-Tab");
    325    } else {
    326      //String sCmd = "bzr commit -F " + fileCommitText.getAbsolutePath();
    327
    328        StringBuilder uFilesAdd = new StringBuilder(1000);
    329        //
    330      String sCmdAdd = mainData.cfg.indexCmds.get("add");
    331      StringBuilder uCmdAdd = new StringBuilder(1000);
    332        uCmdAdd.append(sCmdAdd);
    333        int posFile = uCmdAdd.indexOf("$Files");
    334      if(posFile >=0){
    335        uCmdAdd.replace(posFile, posFile + 6, "");  //idea: $Files<-F $$> prescript to replace
    336      } else {
    337        //what todo
    338      }
    339      //
    340      String sCmdCommit = mainData.cfg.indexCmds.get("commit");
    341      StringBuilder uCmdCommit = new StringBuilder(1000);
    342      uCmdCommit.append(sCmdCommit);
    343      posFile = uCmdCommit.indexOf("$CommitDescrFile");
    344      if(posFile >=0){
    345        uCmdCommit.replace(posFile, posFile + 16, fileCommitText.getAbsolutePath());
    346      } else {
    347        //what todo
    348      }
    349      posFile = uCmdCommit.indexOf("$Files");
    350      if(posFile >=0){
    351        uCmdCommit.replace(posFile, posFile + 6, "");  //idea: $Files<-F $$> prescript to replace
    352      } else {
    353        //what todo
    354      }
    355      //
    356      //assemble the files to add and to commit:
    357      boolean bAdd = false;
    358      boolean bCommitSel = false;
    359      for(Map.Entry<String, GralTableLine_ifc> entry: indexMarkedFiles.entrySet()){
    360        GralTableLine_ifc line = entry.getValue();
    361        String sType = line.getCellText(3);
    362        String sFile = entry.getKey();
    363        if(sType.equals("new")){
    364          bAdd = true;
    365          uFilesAdd.append(" ").append(sFile);
    366        }
    367        else if(sType.equals("chg") || sType.equals("add") || sType.equals("mov") || sType.equals("dir")){
    368          bCommitSel = true;
    369          uCmdCommit.append(" ").append(sFile);
    370        }
    371      }
    372      mainData.cmdExec.setCurrentDir(mainData.currCmpn.dirWorkingtree);
    373      if(bAdd){
    374        //mainData.log
    375        uCmdAdd.append(uFilesAdd);
    376        mainData.cmdExec.execute(uCmdAdd.toString(), null, uRenameOut, uRenameOut);
    377        mainData.mainCmdifc.writeInfoln(uCmdAdd + "\n" + uRenameOut);
    378      }
    379      if(bCommitSel && bAdd){
    380        uCmdCommit.append(uFilesAdd);
    381      }
    382      if(bCommitSel || bAdd){
    383        uRenameOut.setLength(0);
    384        mainData.cmdExec.execute(uCmdCommit.toString(), null, uRenameOut, uRenameOut);
    385        mainData.mainCmdifc.writeInfoln(uCmdAdd + "\n" + uRenameOut);
    386      } else {
    387        mainData.mainCmdifc.writeError("Nothing to commit - Please select files with space-bar");
    388      }
    389      refreshFiles();
    390    }
    391
    392  }
    393
    394
    395
    396  private final GralUserAction actionCommit = new GralUserAction()
    397  {
    398    @Override
    399    public boolean userActionGui(int key, GralWidget widgetInfos, Object... values)
    400    { boolean bDone = true;
    401      if(KeyCode.isControlFunctionMouseUpOrMenu(key)){
    402        commitSelectedFiles();
    403      }
    404      return bDone;
    405    }
    406  };
    407
    408
    409
    410
    411  private final GralUserAction actionRefresh = new GralUserAction()
    412  {
    413    @Override
    414    public boolean userActionGui(int key, GralWidget widgetInfos, Object... values)
    415    { boolean bDone = true;
    416      if(KeyCode.isControlFunctionMouseUpOrMenu(key)){
    417        refreshFiles();
    418      }
    419      return bDone;
    420    }
    421  };
    422
    423
    424
    425  private final GralUserAction actionView = new GralUserAction()
    426  {
    427    @Override
    428    public boolean userActionGui(int key, GralWidget widgetInfos, Object... values)
    429    {
    430      return true;
    431    }
    432  };
    433
    434
    435  private final GralUserAction actionViewdiff = new GralUserAction()
    436  {
    437    @Override
    438    public boolean userActionGui(int key, GralWidget widgetInfos, Object... values)
    439    {
    440      StringBuilder uCmd = new StringBuilder(200);
    441      String[] sValue = widgdTableFilesCmpn.getValue().split("\t");
    442      mainData.mainCmdifc.writeInfoln(sValue[0]);
    443      String sCmd = mainData.cfg.indexCmds.get("fileDiff");
    444      uCmd.append(sCmd);
    445      int posFile = sCmd.indexOf("$File");
    446      if(posFile >=0){
    447        uCmd.replace(posFile, posFile + 5, sValue[0]);  //idea: $Files<-F $$> prescript to replace
    448      } else {
    449        //what todo
    450      }
    451      StringBuilder out = new StringBuilder();
    452      mainData.cmdExec.execute(uCmd.toString(), null, out, out);
    453      //mainData.mainAction.panelOutput.widgdOutputText.setValue(GralMng_ifc.cmdSet, 0, out.toString());
    454      mainData.infoBox.setText(out);
    455      mainData.infoWindow.setWindowVisible(true);
    456      stop();
    457      return true;
    458    }
    459  };
    460
    461
    462
    463  void stop(){}
    464
    465
    466}