001package org.vishia.commander;
002
003import java.util.Iterator;
004import java.util.Map;
005import java.util.TreeMap;
006
007import org.vishia.gral.base.GralButton;
008import org.vishia.gral.base.GralMenu;
009import org.vishia.gral.base.GralPos;
010import org.vishia.gral.base.GralWidget;
011import org.vishia.gral.base.GralMng;
012import org.vishia.gral.ifc.GralButtonKeyMenu;
013import org.vishia.gral.ifc.GralUserAction;
014import org.vishia.gral.ifc.GralWidget_ifc;
015import org.vishia.util.KeyCode;
016
017/**This class contains all functionality of the function buttons in The-file-Commander.
018 * @author Hartmut Schorrig
019 *
020 */
021public class FcmdButtons
022{
023  
024  /**Version, history and copyright/copyleft.
025   * <ul>
026   * <li>2012-06-16 Hartmut new: {@link #processKey(int)}: Now all control keys are set together with the buttons
027   *   in {@link #setBtnMenuAndKeys(GralUserAction, String)}.
028   * <li>2012-01-01 created. 
029   * </ul>
030   * 
031   * <b>Copyright/Copyleft</b>:<br>
032   * For this source the LGPL Lesser General Public License,
033   * published by the Free Software Foundation is valid.
034   * It means:
035   * <ol>
036   * <li> You can use this source without any restriction for any desired purpose.
037   * <li> You can redistribute copies of this source to everybody.
038   * <li> Every user of this source, also the user of redistribute copies
039   *    with or without payment, must accept this license for further using.
040   * <li> But the LPGL is not appropriate for a whole software product,
041   *    if this source is only a part of them. It means, the user
042   *    must publish this part of source,
043   *    but doesn't need to publish the whole source of the own product.
044   * <li> You can study and modify (improve) this source
045   *    for own using or for redistribution, but you have to license the
046   *    modified sources likewise under this LGPL Lesser General Public License.
047   *    You mustn't delete this Copyright/Copyleft inscription in this source file.
048   * </ol>
049   * If you intent to use this source without publishing its usage, you can get
050   * a second license subscribing a special contract with the author. 
051   * 
052   * @author Hartmut Schorrig = hartmut.schorrig@vishia.de
053   */
054  public static final int version = 20120617;
055
056  private final Fcmd main;
057  
058  GralButton buttonDel;
059  
060  boolean bButtonVisible = true;
061
062  FcmdButtons(Fcmd main){
063    this.main = main;
064    main._gralMng.setMainKeyAction(actionMainKeys);
065  }
066  
067  static class ButtonAction{
068    final GralUserAction action;
069    final String button;
070    final String text;
071    public ButtonAction(GralUserAction action, String button, String text)
072    { this.action = action;
073      this.button = button;
074      this.text = text;
075    }
076  }
077  
078  ButtonAction emptyButton = new ButtonAction(null, "", "");
079  
080  Map<String, ButtonAction> idxButtons = new TreeMap<String, ButtonAction>();
081  
082  /**This is only a helper String array to associate button texts from {@link FCmdIdent} in form "aF1:Text"
083   * and there action to the viewable buttons.
084   * The order of character are in alphabetic one because the given button control texts are processed in that order.
085   */
086  final String[] b1 = 
087    {  "F1",  "F2",  "F3",  "F4",  "F5",  "F6",  "F7",  "F8",  "F9", "F10"
088    , "aF1", "aF2", "aF3", "aF4", "aF5", "aF6", "aF7", "aF8", "aF9", "aF10"
089    , "cF1", "cF2", "cF3", "cF4", "cF5", "cF6", "cF7", "cF8", "cF9", "cF10"
090    , "gF1", "gF2", "gF3", "gF4", "gF5", "gF6", "gF7", "gF8", "gF9", "gF10"
091    , "sF1", "sF2", "sF3", "sF4", "sF5", "sF6", "sF7", "sF8", "sF9", "sF10"
092    };
093  
094  /*
095  int[] keys = { KeyCode.F1, KeyCode.F2, KeyCode.F3, KeyCode.F4, KeyCode.F5, KeyCode.F6, KeyCode.F7, KeyCode.F8, KeyCode.F9, KeyCode.F10
096      , KeyCode.alt + KeyCode.F1, KeyCode.alt + KeyCode.F2, KeyCode.alt + KeyCode.F3, KeyCode.alt + KeyCode.F4, KeyCode.alt + KeyCode.F5, KeyCode.alt + KeyCode.F6
097      , KeyCode.alt + KeyCode.F7, KeyCode.alt + KeyCode.F8, KeyCode.alt + KeyCode.F9, KeyCode.alt + KeyCode.F10
098      , KeyCode.ctrl + KeyCode.F1, KeyCode.ctrl + KeyCode.F2, KeyCode.ctrl + KeyCode.F3, KeyCode.ctrl + KeyCode.F4, KeyCode.ctrl + KeyCode.F5, KeyCode.ctrl + KeyCode.F6
099      , KeyCode.ctrl + KeyCode.F7, KeyCode.ctrl + KeyCode.F8, KeyCode.ctrl + KeyCode.F9, KeyCode.ctrl + KeyCode.F10
100      , KeyCode.shiftCtrl + KeyCode.F1, KeyCode.shiftCtrl + KeyCode.F2, KeyCode.shiftCtrl + KeyCode.F3, KeyCode.shiftCtrl + KeyCode.F4, KeyCode.shiftCtrl + KeyCode.F5, KeyCode.shiftCtrl + KeyCode.F6
101      , KeyCode.shiftCtrl + KeyCode.F7, KeyCode.shiftCtrl + KeyCode.F8, KeyCode.shiftCtrl + KeyCode.F9, KeyCode.shiftCtrl + KeyCode.F10
102      , KeyCode.shift + KeyCode.F1, KeyCode.shift + KeyCode.F2, KeyCode.shift + KeyCode.F3, KeyCode.shift + KeyCode.F4, KeyCode.shift + KeyCode.F5, KeyCode.shift + KeyCode.F6
103      , KeyCode.shift + KeyCode.F7, KeyCode.shift + KeyCode.F8, KeyCode.shift + KeyCode.F9, KeyCode.shift + KeyCode.F10
104  };
105  */
106  
107  /**Actions for all keys in {@link #keys}. */
108  //GralUserAction[] keyAction = new GralUserAction[50];
109  
110  Map<Integer, GralUserAction> idxKeyAction = new TreeMap<Integer, GralUserAction>();
111  
112  ButtonAction currentButton;
113  
114  
115  /**Assign an action to any function button, menu and key.
116   * @param action The action
117   * @param buttonText use the form "Btn:text" where button is F1..F12, aF1 etc. text is the text.
118   */
119  void setBtnMenuAndKeys(GralUserAction action, String buttonText, int key, int key2, String menu){
120    if(buttonText !=null){
121      int posSep = buttonText.indexOf(':');
122      if(posSep > 0){
123        ButtonAction buttonAction = new ButtonAction(action, buttonText.substring(0, posSep), buttonText.substring(posSep+1));
124        idxButtons.put(buttonAction.button, buttonAction);
125      } else {
126        System.err.println("faulty button text, should have format \"F1:text\"");
127      }
128    }
129    if(key !=0){
130      idxKeyAction.put(key, action);
131    }
132    if(key2 !=0){
133      idxKeyAction.put(key2, action);
134    }
135    if(menu !=null){
136      GralMenu menuBar = main.gui.getMenuBar();
137      menuBar.addMenuItem(menu, action);
138      //main.gui.addMenuBarArea9ItemGThread(null, menu, action);
139    }
140  }
141  
142  
143  /**Assign an action to any function button, menu and key.
144   * @param action The action
145   * @param buttonText use the form "Btn:text" where button is F1..F12, aF1 etc. text is the text.
146   */
147  void setBtnMenuAndKeys(GralUserAction action, String buttonText, int key, String menu){
148    setBtnMenuAndKeys(action, buttonText, key, 0, menu);
149  }
150  
151  
152  /**Get the proper button for the requested idx in {@link #b1}.
153   * @param idx
154   * @param iterButtonAction
155   * @return the {@link #emptyButton} if no button matches.
156   */
157  ButtonAction getNext(int idx, Iterator<Map.Entry<String, ButtonAction>> iterButtonAction){
158    String button = b1[idx];
159    while(iterButtonAction.hasNext() && (currentButton == null || currentButton.button.compareTo(button) < 0)){
160      currentButton = iterButtonAction.next().getValue();
161    }
162    if(currentButton.button.equals(button)){ return currentButton; }
163    else return emptyButton;
164  }
165  
166  
167  /**Assigns the next action to the {@link #keyAction} and creates the button.
168   * @param idx
169   * @param iterButtonAction
170   */
171  private void addButton(int idx, Iterator<Map.Entry<String, ButtonAction>> iterButtonAction){
172    ButtonAction button = getNext(idx, iterButtonAction);
173    GralButton gralButton = main._gralMng.addButton(button.button, button.action, button.text);
174    gralButton.setHtmlHelp(main.cargs.dirHtmlHelp + "/Fcmd.html#Topic.FcmdHelp.Button." + button.text + ".");
175    //keyAction[idx] = button.action;
176  }
177  
178  
179  void initPanelButtons()
180  {
181    //This calls creates the menu entries in the menu bar. The order determines the order in menu bar. It registeres the button strings and keys.
182    setBtnMenuAndKeys(main.filePropsCmd.actionOpenDialog, main.idents.buttonFileProps, main.idents.keyFileProps, main.idents.menuFilePropsBar);
183    setBtnMenuAndKeys(main.viewCmd.actionOpenView, main.idents.buttonFileView, main.idents.keyFileView, main.idents.menuFileViewBar);
184    setBtnMenuAndKeys(main.viewCmd.actionQuickView, null, main.idents.key1QuickView, main.idents.key2QuickView, main.idents.menuBarQuickView);
185    setBtnMenuAndKeys(main.editWind.actionOpenEdit, main.idents.buttonEditIntern, main.idents.keyEditIntern, main.idents.menuBarEditIntern);
186    setBtnMenuAndKeys(main.actionEdit, main.idents.buttonFileEdit, main.idents.keyFileEdit, main.idents.menuFileEditBar);
187    setBtnMenuAndKeys(main.copyCmd.actionConfirmCopy, main.idents.buttonFileCopy, main.idents.keyFileCopy, main.idents.menuConfirmCopyBar);
188    setBtnMenuAndKeys(main.mkCmd.actionOpenDialog, main.idents.buttonMkdirFile, main.idents.keyFileCreate, main.idents.menuConfirmMkdirFileBar);
189    setBtnMenuAndKeys(main.deleteCmd.actionConfirmDelete, main.idents.buttonFileDel, main.idents.keyFileDel1, main.idents.menuConfirmFileDelBar);
190    setBtnMenuAndKeys(main.deleteCmd.actionConfirmDelete, null, main.idents.keyFileDel2, null);
191    setBtnMenuAndKeys(main.favorPathSelector.actionSetDirOrigin, main.idents.buttonSetOriginDir, main.idents.keyOriginDir1, main.idents.keyOriginDir1, main.idents.menuBarSetOriginDir);
192    setBtnMenuAndKeys(main.executer.actionExecuteFileByExtension, main.idents.buttonExecute, main.idents.keyExecuteExt, main.idents.menuExecuteBar);
193    setBtnMenuAndKeys(main.favorPathSelector.actionRefreshFileTable, main.idents.buttonRefereshFiles, main.idents.keyRefresh1, main.idents.menuFileNaviRefreshBar);
194    setBtnMenuAndKeys(main.favorPathSelector.actionRefreshFileTable, null, main.idents.keyRefresh2, null);
195    setBtnMenuAndKeys(main.favorPathSelector.actionRefreshFileTable, null, main.idents.keyRefresh3, null);
196    
197    setBtnMenuAndKeys(main.selectCardThemesLeft, main.idents.buttonFavorLeft, main.idents.keyFavorLeft, main.idents.menuBarNavigationLeft);
198    setBtnMenuAndKeys(main.selectCardThemesMiddle, main.idents.buttonFavorMiddle, main.idents.keyFavorMiddle, main.idents.menuBarNavigationMiddle);
199    setBtnMenuAndKeys(main.selectCardThemesRight, main.idents.buttonFavorRight, main.idents.keyFavorRight, main.idents.menuBarNavigationRight);
200    
201    setBtnMenuAndKeys(main.selectFileCardLeft,  main.idents.buttonSelectPanelLeft,    main.idents.keySelectPanelLeft,   main.idents.menuBarSelectPanelLeft);
202    setBtnMenuAndKeys(main.selectFileCardLeft,  null,                                main.idents.keySelectPanelLeft2,   null);
203    setBtnMenuAndKeys(main.selectFileCardMid,   main.idents.buttonSelectPanelMiddle,  main.idents.keySelectPanelMiddle, main.idents.menuBarSelectPanelMiddle);
204    setBtnMenuAndKeys(main.selectFileCardMid,   null,                                main.idents.keySelectPanelMiddle2, null);
205    setBtnMenuAndKeys(main.selectFileCardRight, main.idents.buttonSelectPanelRight,   main.idents.keySelectPanelRight,  main.idents.menuBarSelectPanelRight);
206    setBtnMenuAndKeys(main.selectFileCardRight, null,                                main.idents.keySelectPanelRight2,  null);
207    setBtnMenuAndKeys(main.selectFileCardOther, main.idents.buttonSelectPanelOther,   main.idents.keySelectPanelOther,  main.idents.menuBarSelectPanelOther);
208
209    setBtnMenuAndKeys(main.actionFocusCardInPanelToLeft, main.idents.buttonFocusLeftCard,   main.idents.keyFocusLeftCard,  main.idents.menuBarFocusLeftCard);
210    setBtnMenuAndKeys(main.actionFocusCardInPanelToRight, main.idents.buttonFocusRightCard,   main.idents.keyFocusRightCard,  main.idents.menuBarFocusRightCard);
211    setBtnMenuAndKeys(main.actionFocusFileCard, main.idents.buttonFocusFileCard,   main.idents.keyFocusFileCard,  main.idents.menuBarFocusFileCard);
212    setBtnMenuAndKeys(main.actionFocusThemeCard, main.idents.buttonFocusThemeCard,   main.idents.keyFocusThemeCard,  main.idents.menuBarFocusThemeCard);
213    setBtnMenuAndKeys(main.actionFocusPanelToLeft, main.idents.buttonFocusPanelToLeft,   main.idents.keyFocusPanelToLeft,  main.idents.menuBarFocusPaneltoLeft);
214    setBtnMenuAndKeys(main.actionFocusPanelToRight, main.idents.buttonFocusPanelToRight,   main.idents.keyFocusPanelToRight,  main.idents.menuBarFocusPanelToRight);
215
216    
217    setBtnMenuAndKeys(main.actionFocusCmdCard, main.idents.buttonFocusCmd, main.idents.keyFocusCmd, main.idents.menuBarNavigatonCmd);
218    setBtnMenuAndKeys(main.favorPathSelector.actionSortFilePerNameNonCase, main.idents.buttonFileSortNameNonCase, main.idents.keyFileSortNameNonCase, main.idents.menuBarFileSortNameNonCase);
219    setBtnMenuAndKeys(main.favorPathSelector.actionSortFilePerNameCase, main.idents.buttonFileSortNameCase, main.idents.keyFileSortNameCase, main.idents.menuBarFileSortNameCase);
220    setBtnMenuAndKeys(main.favorPathSelector.actionSortFilePerExtensionNonCase, main.idents.buttonFileSortExtNonCase, main.idents.keyFileSortExtNonCase, main.idents.menuBarFileSortExtNonCase);
221    setBtnMenuAndKeys(main.favorPathSelector.actionSortFilePerExtensionCase, main.idents.buttonFileSortExtCase, main.idents.keyFileSortExtCase, main.idents.menuBarFileSortExtCase);
222    setBtnMenuAndKeys(main.favorPathSelector.actionSortFilePerTimestamp, main.idents.buttonFileSortDateNewest, main.idents.keyFileSortDateNewest, main.idents.menuBarFileSortDateNewest);
223    setBtnMenuAndKeys(main.favorPathSelector.actionSortFilePerTimestampOldestFirst, main.idents.buttonFileSortOldest, main.idents.keyFileSortDateLast, main.idents.menuBarFileSortDateOldest);
224    setBtnMenuAndKeys(main.favorPathSelector.actionSortFilePerLenghLargestFirst, main.idents.buttonFileSortSizeLarge, main.idents.keyFileSortSizeLarge, main.idents.menuBarFileSortSizeLarge);
225    setBtnMenuAndKeys(main.favorPathSelector.actionSortFilePerLenghSmallestFirst, main.idents.buttonFileSortSizeSmall, main.idents.keyFileSortSizeSmall, main.idents.menuBarFileSortSizeSmall);
226    setBtnMenuAndKeys(main.favorPathSelector.actionSearchFiles, main.idents.buttonSearchFiles, main.idents.keySearchFiles, main.idents.menuBarSearchFiles);
227    
228    setBtnMenuAndKeys(main.executer.cmdSelector.actionExecCmdWithFiles, main.idents.buttonExecuteCmdWithFile, main.idents.keyExecuteCmdWithFile, main.idents.keyExecuteCmdWithFile2, main.idents.menuBarExecuteCmdWithFile);
229    setBtnMenuAndKeys(main.executer.actionEditCmdCfgAct, main.idents.buttonEditCmdCfg, main.idents.keyEditCmdCfg, 0, main.idents.menuBarEditCmdCfg);
230    setBtnMenuAndKeys(main.executer.actionSetCmdCfgAct, main.idents.buttonReadCmdCfgAct, main.idents.keyReadCmdCfgAct, 0, main.idents.menuBarReadCmdCfgAct);
231    setBtnMenuAndKeys(actionViewButtons, main.idents.buttonViewButtons, main.idents.keyViewButtons, main.idents.menuBarViewButtons);
232    setBtnMenuAndKeys(main.windMng.actionWindFullOut, main.idents.buttonWindowOutput, main.idents.keyWindowOutput, main.idents.keyWindowOutput2, main.idents.menuBarWindowOutput);
233
234    setBtnMenuAndKeys(main.settings.actionOpenDialog, main.idents.buttonSettings, main.idents.key1Settings, main.idents.key2Settings, main.idents.menuBarSettings);
235    setBtnMenuAndKeys(main.status.actionOpenDialog, main.idents.buttonStatus, main.idents.key1Status, main.idents.key2Status, main.idents.menuBarStatus);
236    //setBtnMenuAndKeys(main.actionReadMsgConfig, main.idents.readMsg.buttontext, main.idents.readMsg.key1, main.idents.readMsg.key2, main.idents.readMsg.menu);
237    for(GralButtonKeyMenu entry: main.idents.entries){
238      if(entry.action !=null){
239        setBtnMenuAndKeys(entry.action, entry.buttontext, entry.key1, entry.key2, entry.menu);
240      }
241    }
242    main.gui.addMenuBarArea9ItemGThread("menuBarViewButtons", main.idents.menuBarViewButtons, actionViewButtons);
243
244    setBtnMenuAndKeys(main.gui.getActionHelp(), main.idents.buttonHelp, main.idents.keyHelp,main.idents.menuHelpBar);
245    
246    Iterator<Map.Entry<String, ButtonAction>> iterButtonAction = idxButtons.entrySet().iterator();
247    
248    main._gralMng.selectPanel("Buttons");
249    main.statusLine.buildGraphic();
250    
251    main._gralMng.setPosition(4, GralPos.size + 1, 10, 20, 1, 'r');
252    main._gralMng.addText("F1");
253    main._gralMng.addText("F2");
254    main._gralMng.addText("F3");
255    main._gralMng.addText("F4");
256    main._gralMng.addText("F5");
257    main._gralMng.addText("F6");
258    main._gralMng.addText("F7");
259    main._gralMng.addText("F8");
260    main._gralMng.addText("F9");
261    main._gralMng.addText("F10");
262    main._gralMng.setPosition(7, GralPos.size +2, 0, 4, 1, 'd');
263    main._gralMng.addText("alt -");
264    main._gralMng.addText("ctr -");
265    main._gralMng.addText("shctr-");
266    main._gralMng.addText("sh  -");
267
268    main._gralMng.setPosition(5, 7, 4, 14, 1, 'r');
269    int idx;
270    for(idx = 0; idx < 10; ++idx){
271      addButton(idx, iterButtonAction);
272    }
273    main._gralMng.setPosition(7, 9, 4, 14, 1, 'r');
274    for(idx = 10; idx < 20; ++idx){
275      addButton(idx, iterButtonAction);
276    }
277    main._gralMng.setPosition(9, 11, 4, 14, 1, 'r');
278    for(idx = 20; idx < 30; ++idx){
279      addButton(idx, iterButtonAction);
280    }
281    main._gralMng.setPosition(11, 13, 4, 14, 1, 'r');
282    for(idx = 30; idx < 40; ++idx){
283      addButton(idx, iterButtonAction);
284    }
285    main._gralMng.setPosition(13, 15, 4, 14, 1, 'r');
286    for(idx = 40; idx < 50; ++idx){
287      addButton(idx, iterButtonAction);
288    }
289    main.gui.setMinMaxSizeArea("A3C3", 15, 15, 0, 0);
290  }
291
292
293  
294  /**Searches the given keyCode and processes its action. 
295   * The action was set initially from the {@link #setBtnMenuAndKeys(GralUserAction, String)} with key assignment in {@link FcmdIdents}.
296   * @param keyCode
297   * @return true if done.
298   */
299  boolean processKey(int keyCode, GralWidget_ifc widg){
300    GralUserAction action = idxKeyAction.get(keyCode);
301    if(action !=null){
302      boolean bDone = action.exec(keyCode, widg);
303      return bDone;
304    } else {
305      return false;
306    }
307  }
308  
309
310  
311  /**The main key action registered in the {@link GralMng#setMainKeyAction(GralUserAction)}.
312   */
313  GralUserAction actionMainKeys = new GralUserAction("actionMainKeys")
314  {
315    @Override public boolean exec(int key, GralWidget_ifc widg, Object... params){ 
316      return processKey(key, widg);
317    }
318  };
319  
320  
321  
322  
323  /**Action to focus the cmd card.
324   */
325  GralUserAction actionViewButtons = new GralUserAction("actionViewButtons")
326  {
327    @Override public boolean userActionGui(int key, GralWidget infos, Object... params){ 
328      if(KeyCode.isControlFunctionMouseUpOrMenu(key)){  //supress both mouse up and down reaction
329      if(bButtonVisible){
330        bButtonVisible = false;
331        main.gui.setMinMaxSizeArea("A3C3", 4, 4, 0, 0);
332      } else {
333        bButtonVisible = true;
334        main.gui.setMinMaxSizeArea("A3C3", 15, 15, 0, 0);
335      }
336      return true;
337      } else return false;
338    }
339  };
340
341
342}