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}