home *** CD-ROM | disk | FTP | other *** search
/ Dream 52 / Amiga_Dream_52.iso / Linux / Divers / lyx-0.13.2.tar.gz / lyx-0.13.2.tar / lyx-0.13.2 / src / LyXAction.C < prev    next >
C/C++ Source or Header  |  1998-04-23  |  28KB  |  746 lines

  1. /* This file is part of
  2. * ======================================================
  3. *           LyX, The Document Processor
  4. *      
  5. *        Copyright (C) 1995 Matthias Ettrich
  6. *           Copyright (C) 1995-1998 The LyX Team.
  7. *
  8. *======================================================*/
  9.  
  10. #include <config.h>
  11.  
  12. #include <stdlib.h>
  13. #include <stdio.h>
  14. #include <ctype.h>
  15. #include <lstrings.h>
  16.  
  17. #if defined(__sgi)
  18. #include <strings.h>
  19. #endif
  20.  
  21. #ifdef __GNUG__
  22. #pragma implementation
  23. #endif
  24.  
  25. #include "LyXAction.h"
  26. #include "error.h"
  27. #include "gettext.h"
  28.  
  29.  /*  
  30.      NAMING RULES FOR USER-COMMANDS
  31.      Here's the set of rules to apply when a new command name is introduced:
  32.  
  33.      1) Use the object.event order. That is, use `word-forward'
  34.         instead of `forward-word'.
  35.      2) Don't introduce an alias for an already named object. Same for events.
  36.      3) Forward movement or focus is called `forward' (not `right').
  37.      4) Backward movement or focus is called `backward' (not `left').
  38.      5) Upward movement of focus is called `up'.
  39.      6) Downward movement is called `down'.
  40.      7) The begin of an object is called `begin' (not `start').
  41.      8) The end of an object is called `end'.
  42.  
  43.      (May 19 1996, 12:04, RvdK)
  44.  */
  45.  
  46.  
  47. // These are globals. 
  48. LyXAction lyxaction;
  49.  
  50.  
  51. /* This table is sorted alphabetically [asierra 14Jan96] */
  52. /* This table MUST be sorted alphabetically, incidentally! */ 
  53. kb_func_table const lyx_func_table[] = {
  54.     { "accent-acute",                         LFUN_ACUTE },
  55.     { "accent-breve",                         LFUN_BREVE },
  56.     { "accent-caron",                         LFUN_CARON },
  57.     { "accent-cedilla",                       LFUN_CEDILLA },
  58.     { "accent-circle",                        LFUN_CIRCLE },
  59.     { "accent-circumflex",                    LFUN_CIRCUMFLEX },
  60.     { "accent-dot",                           LFUN_DOT },
  61.     { "accent-grave",                         LFUN_GRAVE },
  62.     { "accent-hungarian-umlaut",              LFUN_HUNG_UMLAUT },
  63.     { "accent-macron",                        LFUN_MACRON },
  64.     { "accent-ogonek",                        LFUN_OGONEK },
  65.     { "accent-special-caron",                 LFUN_SPECIAL_CARON },
  66.     { "accent-tie",                           LFUN_TIE },
  67.     { "accent-tilde",                         LFUN_TILDE },
  68.     { "accent-umlaut",                        LFUN_UMLAUT },
  69.     { "accent-underbar",                      LFUN_UNDERBAR },
  70.     { "accent-underdot",                      LFUN_UNDERDOT },
  71.     { "accent-vector",                        LFUN_VECTOR }, 
  72.     { "apropos",                  LFUN_APROPOS },
  73.     { "backward-select",                      LFUN_LEFTSEL },
  74.     { "bibtex-database-add",                  LFUN_BIBDB_ADD },
  75.     { "bibtex-database-del",                  LFUN_BIBDB_DEL },
  76.     { "bibtex-insert",                        LFUN_INSERT_BIBTEX },
  77.     { "bibtex-style",                         LFUN_BIBTEX_STYLE },
  78.     { "break-line",                           LFUN_BREAKLINE },
  79.     { "break-paragraph",                      LFUN_BREAKPARAGRAPH },
  80.     { "break-paragraph-keep-layout",          LFUN_BREAKPARAGRAPHKEEPLAYOUT },
  81.     { "break-paragraph-skip",                 LFUN_BREAKPARAGRAPH_SKIP },
  82.     { "buffer-auto-save",                     LFUN_AUTOSAVE },
  83.     { "buffer-begin",                         LFUN_BEGINNINGBUF },
  84.     { "buffer-begin-select",                  LFUN_BEGINNINGBUFSEL },
  85.     { "buffer-child-insert",                  LFUN_CHILDINSERT },  // ale970521
  86.     { "buffer-child-open",                    LFUN_CHILDOPEN },  // ale970528
  87.     { "buffer-chktex",              LFUN_RUNCHKTEX }, // Asger 971030
  88.     { "buffer-close",                         LFUN_CLOSEBUFFER },         
  89.     { "buffer-end",                           LFUN_ENDBUF },
  90.     { "buffer-end-select",                    LFUN_ENDBUFSEL },
  91.     { "buffer-export",                        LFUN_EXPORT },
  92.     { "buffer-fax",                           LFUN_FAX },
  93.     { "buffer-float-insert",                  LFUN_INSERTFOOTNOTE },
  94.     { "buffer-itemize-bullets-select",        LFUN_BUFFERBULLETSSELECT },
  95.     { "buffer-new",                           LFUN_MENUNEW },     
  96.     { "buffer-new-template",                  LFUN_MENUNEWTMPLT },
  97.     { "buffer-open",                          LFUN_MENUOPEN },    
  98.     { "buffer-previous",                      LFUN_PREVBUFFER },  
  99.     { "buffer-print",                         LFUN_MENUPRINT },   
  100.     { "buffer-reload",                        LFUN_MENURELOAD },   
  101.     { "buffer-toggle-read-only",              LFUN_READ_ONLY_TOGGLE },
  102.     { "buffer-typeset",                       LFUN_RUNLATEX },        // Alejandro's proposal
  103.     { "buffer-typeset-ps",              LFUN_RUNDVIPS },
  104.     { "buffer-view",                          LFUN_PREVIEW },
  105.     { "buffer-view-ps",                       LFUN_PREVIEWPS },
  106.     { "buffer-write",                         LFUN_MENUWRITE },   
  107.     { "buffer-write-as",                      LFUN_MENUWRITEAS }, 
  108.     { "cancel",                               LFUN_CANCEL },
  109.     { "char-backward",              LFUN_LEFT },
  110.     { "char-forward",              LFUN_RIGHT },
  111.         { "citation-insert",              LFUN_INSERT_CITATION },
  112.     { "command-execute",               LFUN_EXEC_COMMAND },
  113.     { "command-prefix",                       LFUN_PREFIX },
  114.     { "copy",                                 LFUN_COPY },
  115.     { "cut",                                  LFUN_CUT },
  116.     { "delete-backward",                      LFUN_BACKSPACE },
  117.     { "delete-backward-skip",                 LFUN_BACKSPACE_SKIP },
  118.     { "delete-forward",                       LFUN_DELETE },
  119.     { "delete-forward-skip",                  LFUN_DELETE_SKIP },
  120.     { "depth-decrement",                      LFUN_DEPTH_MIN },
  121.     { "depth-increment",                      LFUN_DEPTH_PLUS },  
  122.     { "depth-next",                           LFUN_DEPTH },
  123.     { "dots-insert",              LFUN_LDOTS },
  124.     { "down",                                 LFUN_DOWN },                 
  125.     { "down-select",                          LFUN_DOWNSEL },
  126.     { "drop-layouts-choice",                  LFUN_DROP_LAYOUTS_CHOICE },
  127.     { "end-of-sentence-period-insert",      LFUN_END_OF_SENTENCE },
  128.     { "error-next",                           LFUN_GOTOERROR },   
  129.     { "error-remove-all",              LFUN_REMOVEERRORS },
  130.     { "figure-insert",                        LFUN_FIGURE },
  131.     { "file-insert",                          LFUN_FILE_INSERT },
  132.     { "file-insert-ascii",                    LFUN_FILE_INSERT_ASCII },
  133.     { "file-new",                             LFUN_FILE_NEW },
  134.     { "file-open",                            LFUN_FILE_OPEN },
  135.     { "find-replace",                         LFUN_MENUSEARCH },  
  136.     { "font-bold",                            LFUN_BOLD },        
  137.     { "font-code",                            LFUN_CODE },        
  138.     { "font-default",                         LFUN_DEFAULT },
  139.     { "font-emph",                            LFUN_EMPH },
  140.     { "font-free",                            LFUN_FREE },
  141.     { "font-noun",                            LFUN_NOUN },
  142.     { "font-roman",                           LFUN_ROMAN },
  143.     { "font-sans",                            LFUN_SANS },
  144.     { "font-size",                            LFUN_FONT_SIZE },
  145.     { "font-state",                           LFUN_FONT_STATE }, 
  146.     { "font-underline",                       LFUN_UNDERLINE },   
  147.     { "footnote-insert",                      LFUN_FOOTMELT },    
  148.     { "forward-select",                       LFUN_RIGHTSEL },
  149.     { "hfill-insert",                         LFUN_HFILL },
  150.     { "html-insert",                          LFUN_HTMLURL },
  151.     { "hyphenation-point-insert",             LFUN_HYPHENATION },
  152.     { "index-insert",                         LFUN_INDEX_INSERT },
  153.     { "index-print",                          LFUN_INDEX_PRINT },
  154.     { "keymap-off",                           LFUN_KMAP_OFF },
  155.     { "keymap-primary",                       LFUN_KMAP_PRIM },
  156.     { "keymap-secondary",                     LFUN_KMAP_SEC },
  157.     { "keymap-toggle",                        LFUN_KMAP_TOGGLE },
  158.     { "label-insert",                         LFUN_INSERT_LABEL },
  159.     { "latex-view-log",                       LFUN_LATEX_LOG },
  160.     { "layout",                               LFUN_LAYOUT },
  161.     { "layout-character",                     LFUN_LAYOUT_CHARACTER },
  162.     { "layout-copy",              LFUN_LAYOUT_COPY },
  163.     { "layout-document",                      LFUN_LAYOUT_DOCUMENT },
  164.     //{ "layout-number",                      LFUN_LAYOUTNO }, // internal only
  165.     { "layout-paper",              LFUN_LAYOUT_PAPER },
  166.     { "layout-paragraph",                     LFUN_LAYOUT_PARAGRAPH },
  167.     { "layout-paste",              LFUN_LAYOUT_PASTE },
  168.     { "layout-preamble",                      LFUN_LAYOUT_PREAMBLE },
  169.     { "layout-quotes",                        LFUN_LAYOUT_QUOTES },
  170.     { "layout-table",                         LFUN_LAYOUT_TABLE },
  171.     { "line-begin",                           LFUN_HOME },        
  172.     { "line-begin-select",                    LFUN_HOMESEL },     
  173.     { "line-delete-forward",                  LFUN_DELETE_LINE_FORWARD },  
  174.     { "line-end",                             LFUN_END },         
  175.     { "line-end-select",                      LFUN_ENDSEL },
  176.     { "loa-insert",                           LFUN_LOA_INSERT },
  177.     { "lof-insert",                           LFUN_LOF_INSERT },
  178.     { "lot-insert",                           LFUN_LOT_INSERT },
  179.     { "lyx-quit",                             LFUN_QUIT },
  180.     { "marginpar-insert",                     LFUN_MARGINMELT },  
  181.     { "mark-off",                             LFUN_MARK_OFF },    
  182.     { "mark-on",                              LFUN_MARK_ON },     
  183.     { "mark-toggle",                          LFUN_SETMARK }, 
  184.     { "math-delim",                           LFUN_MATH_DELIM },
  185.     { "math-display",                         LFUN_MATH_DISPLAY }, // Alejandro's proposal
  186.     { "math-greek",                           LFUN_GREEK },   
  187.     { "math-greek-toggle",                    LFUN_GREEK_TOGGLE },   
  188.     { "math-insert",                          LFUN_INSERT_MATH },   
  189.     { "math-limits",                          LFUN_MATH_LIMITS },
  190.         { "math-macro",                           LFUN_MATH_MACRO },
  191.         { "math-macro-arg",                       LFUN_MATH_MACROARG },
  192.     { "math-matrix",                          LFUN_INSERT_MATRIX }, 
  193.     { "math-mode",                            LFUN_MATH_MODE },
  194.     { "math-nonumber",                        LFUN_MATH_NONUMBER },
  195.     { "math-number",                          LFUN_MATH_NUMBER }, 
  196.     { "math-size",                            LFUN_MATH_SIZE }, 
  197.     { "melt",                                 LFUN_MELT },            // Needs better name. What about "float-disolve" or "float-extract" (Lgb)
  198.     { "menu-open",                            LFUN_MENU_OPEN_BY_NAME },
  199.     { "meta-prefix",                          LFUN_META_FAKE },
  200.     { "note-insert",                          LFUN_INSERT_NOTE },
  201.     { "note-next",                            LFUN_GOTONOTE },
  202.     { "open-stuff",                           LFUN_OPENSTUFF },       // Needs better name.
  203.     { "paragraph-down",              LFUN_DOWN_PARAGRAPH },
  204.     { "paragraph-down-select",          LFUN_DOWN_PARAGRAPHSEL },
  205.     { "paragraph-up",              LFUN_UP_PARAGRAPH },
  206.     { "paragraph-up-select",          LFUN_UP_PARAGRAPHSEL },
  207.         { "parent-insert",                  LFUN_PARENTINSERT },
  208.     { "paste",                                LFUN_PASTE },
  209.     { "primary-selection-paste",              LFUN_PASTESELECTION },
  210.     { "protected-space-insert",               LFUN_PROTECTEDSPACE },
  211.     { "quote-insert",                         LFUN_QUOTE },
  212.     { "reconfigure",              LFUN_RECONFIGURE },
  213.     { "redo",                                 LFUN_REDO },
  214.         { "reference-back",                       LFUN_REFBACK },
  215.         { "reference-goto",                       LFUN_REFGOTO }, 
  216.     { "reference-insert",                     LFUN_INSERT_REF },
  217.     { "reference-toggle",                     LFUN_REFTOGGLE },
  218.     { "screen-down",                          LFUN_NEXT },        
  219.     { "screen-down-select",                   LFUN_NEXTSEL },     
  220.     { "screen-recenter",                      LFUN_CENTER },
  221.     { "screen-up",                            LFUN_PRIOR },       
  222.     { "screen-up-select",                     LFUN_PRIORSEL },    
  223.     { "self-insert",                          LFUN_SELFINSERT },
  224.     { "server-char-after",                    LFUN_CHARATCURSOR },
  225.     { "server-get-font",                      LFUN_GETFONT },
  226.     { "server-get-latex",                     LFUN_GETLATEX },
  227.     { "server-get-layout",                    LFUN_GETLAYOUT },
  228.     { "server-get-name",                      LFUN_GETNAME },
  229.     { "server-get-tip",                       LFUN_GETTIP },
  230.     { "server-get-xy",                        LFUN_GETXY },
  231.     { "server-notify",                        LFUN_NOTIFY },
  232.     { "server-set-xy",                        LFUN_SETXY },
  233.     { "spellchecker",                         LFUN_SPELLCHECK },  
  234.     { "symbol-insert",                        LFUN_INSERT_MATH },
  235.     { "tab-forward",                          LFUN_TAB },
  236.     { "tab-insert",                           LFUN_TABINSERT },
  237.     { "table-insert",                         LFUN_TABLE },
  238.     { "tex-mode",                             LFUN_TEX },
  239.     { "toc-insert",                           LFUN_TOC_INSERT },
  240.     { "toc-view",                             LFUN_TOCVIEW },
  241.     { "toggle-cursor-follows-scrollbar",      LFUN_TOGGLECURSORFOLLOW },
  242.     { "toolbar-add-to",                       LFUN_ADD_TO_TOOLBAR },
  243.     { "toolbar-push",                         LFUN_PUSH_TOOLBAR },
  244.     { "undo",                                 LFUN_UNDO },
  245.     { "up",                                   LFUN_UP },          
  246.     { "up-select",                            LFUN_UPSEL },
  247.     { "url-insert",                           LFUN_URL },
  248.     { "vc-check-in",                          LFUN_VC_CHECKIN }, 
  249.     { "vc-check-out",                         LFUN_VC_CHECKOUT }, 
  250.     { "vc-history",                           LFUN_VC_HISTORY }, 
  251.     { "vc-register",                          LFUN_VC_REGISTER }, 
  252.     { "vc-revert",                            LFUN_VC_REVERT }, 
  253.     { "vc-undo-last",                         LFUN_VC_UNDO }, 
  254.     { "word-backward",                        LFUN_WORDLEFT },
  255.     { "word-backward-select",                 LFUN_WORDLEFTSEL },
  256.     { "word-capitalize",                      LFUN_CAPITALIZE_WORD },
  257.     { "word-delete-backward",                 LFUN_DELETE_WORD_BACKWARD },
  258.     { "word-delete-forward",                  LFUN_DELETE_WORD_FORWARD }, 
  259.     { "word-find-backward",                   LFUN_WORDFINDBACKWARD },
  260.     { "word-find-forward",                    LFUN_WORDFINDFORWARD },
  261.     { "word-forward",                         LFUN_WORDRIGHT },
  262.     { "word-forward-select",                  LFUN_WORDRIGHTSEL },
  263.     { "word-lowcase",                         LFUN_LOWCASE_WORD },
  264.     { "word-upcase",                          LFUN_UPCASE_WORD }
  265. };
  266.  
  267.  
  268. /* 
  269.    This table contains the actions that modify a buffer and therefore
  270.    are not allowed for RO files. Do you think we have too much tables?
  271.    Each single integer in this table replaces 5 lines of code in lyxfunc
  272.    that include at least 3 function calls (several integers in the 
  273.    code segment).
  274.  
  275.    The table could in the near future be expanded adding a second integer 
  276.    field with attributes using these tags:
  277.  
  278. enum FUNC_ATTRIB {
  279.     LFAT_NONE=0,     // Nothing special
  280.     LFAT_ISRO=1,     // Is readonly (does not modify a buffer)
  281.     LFAT_ISIA=2,     // Is interactive (requires a GUI)
  282.     LFAT_REQARG=4,   // Requires argument
  283.     LFAT_ISMO=8,     // Only math mode
  284.     LFAT_ETCETC
  285. };
  286.  
  287. struct {
  288.     kb_action action;
  289.     unsigned  attrib; 
  290. };
  291.  
  292. Alejandro-970604
  293. */
  294.  
  295. kb_action func_attrib_table[] = {
  296.     LFUN_ACUTE,
  297.     LFUN_AUTOSAVE,
  298.     LFUN_BACKSPACE,
  299.     LFUN_BACKSPACE_SKIP,
  300.     LFUN_BIBDB_ADD,
  301.     LFUN_BIBDB_DEL,
  302.     LFUN_BIBTEX_STYLE,
  303.     LFUN_BOLD,
  304.     LFUN_BREAKLINE,
  305.     LFUN_BREAKPARAGRAPH,
  306.     LFUN_BREAKPARAGRAPHKEEPLAYOUT,
  307.     LFUN_BREAKPARAGRAPH_SKIP,
  308.     LFUN_BREVE,
  309.     LFUN_BUFFERBULLETSSELECT,
  310.     LFUN_CAPITALIZE_WORD,
  311.     LFUN_CARON,
  312.     LFUN_CEDILLA,
  313.     LFUN_CHILDINSERT,
  314.     LFUN_CIRCLE,
  315.     LFUN_CIRCUMFLEX,
  316.     LFUN_CODE,
  317.     LFUN_CUT,
  318.     LFUN_DEFAULT,
  319.     LFUN_DELETE,
  320.     LFUN_DELETE_LINE_FORWARD,
  321.     LFUN_DELETE_SKIP,
  322.     LFUN_DELETE_WORD_BACKWARD,
  323.     LFUN_DELETE_WORD_FORWARD,
  324.     LFUN_DEPTH,
  325.     LFUN_DEPTH_MIN,
  326.     LFUN_DEPTH_PLUS,
  327.     LFUN_DOT,
  328.     LFUN_EMPH,
  329.     LFUN_END_OF_SENTENCE,
  330.     LFUN_FIGURE,
  331.     LFUN_FILE_INSERT,
  332.     LFUN_FILE_INSERT_ASCII,
  333.     LFUN_FONT_SIZE,
  334.     LFUN_FOOTMELT,
  335.     LFUN_FREE,
  336.     LFUN_GRAVE,
  337.     LFUN_HFILL,
  338.     LFUN_HTMLURL,
  339.     LFUN_HUNG_UMLAUT,
  340.     LFUN_HYPHENATION,
  341.     LFUN_INDEX_INSERT,
  342.     LFUN_INDEX_PRINT,
  343.     LFUN_INSERTFOOTNOTE,
  344.     LFUN_INSERT_BIBTEX,
  345.     LFUN_INSERT_CITATION,
  346.     LFUN_INSERT_LABEL,
  347.     LFUN_INSERT_MATH,
  348.     LFUN_INSERT_MATRIX,
  349.     LFUN_INSERT_NOTE,
  350.     LFUN_INSERT_REF,
  351.     LFUN_LAYOUT,
  352.     LFUN_LAYOUTNO,
  353.     LFUN_LAYOUT_CHARACTER,
  354.     LFUN_LAYOUT_PASTE,
  355.     LFUN_LAYOUT_QUOTES,
  356.     LFUN_LDOTS,
  357.     LFUN_LOA_INSERT,
  358.     LFUN_LOF_INSERT,
  359.     LFUN_LOT_INSERT,
  360.     LFUN_LOWCASE_WORD,
  361.     LFUN_MACRON,
  362.     LFUN_MARGINMELT,
  363.     LFUN_MATH_DELIM,
  364.     LFUN_MATH_DISPLAY,
  365.     LFUN_MATH_MACRO,
  366.     LFUN_MATH_MACROARG,
  367.     LFUN_MATH_MODE,
  368.     LFUN_MATH_NONUMBER,
  369.     LFUN_MATH_NUMBER,
  370.     LFUN_MATH_SIZE,
  371.     LFUN_MELT,
  372.     LFUN_NOUN,
  373.     LFUN_OGONEK,
  374.     LFUN_PARENTINSERT,
  375.     LFUN_PASTE,
  376.     LFUN_PASTESELECTION,
  377.     LFUN_PROTECTEDSPACE,
  378.     LFUN_QUOTE,
  379.     LFUN_REDO,
  380.     LFUN_REFTOGGLE,
  381.     LFUN_ROMAN,
  382.     LFUN_SANS,
  383.     LFUN_SELFINSERT,
  384.     LFUN_SPECIAL_CARON,
  385.     LFUN_TABINSERT,
  386.     LFUN_TABLE,
  387.     LFUN_TEX,
  388.     LFUN_TIE,
  389.     LFUN_TILDE,
  390.     LFUN_TOC_INSERT,
  391.     LFUN_UMLAUT,
  392.     LFUN_UNDERBAR,
  393.     LFUN_UNDERDOT,
  394.     LFUN_UNDERLINE,
  395.     LFUN_UNDO,
  396.     LFUN_UNKNOWN_ACTION,
  397.     LFUN_UPCASE_WORD,
  398.     LFUN_URL,
  399.     LFUN_VECTOR,
  400.     LFUN_WORDFINDFORWARD,
  401.     LFUN_WORDFINDBACKWARD
  402. };
  403.  
  404. int LyXAction::psd_idx = 0;
  405. kb_func_table const * LyXAction::lyx_func_table = &::lyx_func_table[0];
  406. kb_func_table* LyXAction::lyx_func_args = 0;
  407.  
  408. /* === code ============================================================== */
  409.  
  410. /* This routines allow binding actions with argument.
  411.  * Provisionally a fixed size array and global functions are used.
  412.  * [asierra 20Jan96]
  413.  */
  414. #define MAX_PSEUDO_ACTION 128
  415.  
  416.  
  417. LyXAction::LyXAction()
  418. {
  419.     lyx_func_args= new kb_func_table[MAX_PSEUDO_ACTION];
  420.         funcCount = sizeof(::lyx_func_table) / sizeof(::kb_func_table);
  421. }
  422.  
  423.  
  424. LyXAction::~LyXAction()
  425. {
  426.     if (lyx_func_args) {
  427. // This is wrong, so I'll just disable it for now.
  428. // The problem is that we might free memory twice in some situations...
  429. // It's better to leak a bit that to crash. (Asger)
  430. //        for (int i=0; i < psd_idx; i++) {
  431. //            free(lyx_func_args[i].name);
  432. //        }
  433.         delete[] lyx_func_args;
  434.         lyx_func_args = 0;
  435.     }
  436. }
  437.  
  438.  
  439. // Search for an existent pseudoaction, return -1 if it doesn't exist.
  440. int  LyXAction::searchActionArg(kb_action action, LString const &arg)
  441. {
  442.     kb_func_table *tb = &lyx_func_args[0];
  443.     for (int i=0; i<psd_idx; i++) {
  444.         if (action==tb->action && tb->name == arg) {     
  445.  
  446.             lyxerr.debug(LString("Pseudoaction already exist[") 
  447.                      + int(action) + '|' 
  448.                      + arg + ']',
  449.                      Error::KEY);
  450.  
  451.             return LFUN_LASTACTION+i;
  452.         }
  453.         tb++;
  454.     }
  455.     return -1;
  456. }
  457.  
  458.  
  459. // Returns a pseudo-action given an action and its argument.
  460. int LyXAction::getPseudoAction(kb_action action, LString const &arg)
  461. {
  462.     // Check if the pseudo-action already exist.
  463.     int psdaction = searchActionArg(action, arg);
  464.    
  465.     if (psdaction >= 0) return psdaction;
  466.  
  467.     if (psd_idx>=MAX_PSEUDO_ACTION) {
  468.         lyxerr.print("Lyx Error: No more pseudo-actions allowed");
  469.         return -1;
  470.     }
  471.     lyx_func_args[psd_idx].name = arg.c_str();
  472.     lyx_func_args[psd_idx].action = action;
  473.     psd_idx++;
  474.     return LFUN_LASTACTION+psd_idx-1;
  475. }
  476.  
  477.  
  478. // Retrieves the real action and its argument.
  479. int LyXAction::retrieveActionArg(int i, char const** arg)
  480. {
  481.     i -= LFUN_LASTACTION;
  482.     if (i >= 0 &&  i <psd_idx) {
  483.         *arg = strdup(lyx_func_args[i].name);
  484.         return int(lyx_func_args[i].action);
  485.     } else {
  486.         lyxerr.print("Lyx Error: Unrecognized pseudo-action");
  487.         return -1;
  488.     }
  489. }
  490.  
  491.  
  492. // Returns an action tag from a string.
  493. int LyXAction::LookupFunc(LString const &func)
  494. {
  495.     if (func.empty()) 
  496.         //return LFUN_UNKNOWN_ACTION;         
  497.         //if (func[0] == '\0')
  498.         return LFUN_NOACTION;
  499.  
  500.    /* In the scan loop below, l can never become r, so set r one past the last
  501.       valid func table slot. RVDK_PATCH_5 */
  502.     int k = 0, l = 0, r = funcCount;
  503.     int action = LFUN_UNKNOWN_ACTION;
  504.     char *arg = strchr(func.c_str(), ' ');
  505.  
  506.     if (arg) *(arg++) = '\0';      
  507.  
  508.     while (l < r) {
  509.         last_action_idx = (l+r)/2;
  510.         k = compare(lyx_func_table[last_action_idx].name, func);
  511.         if (k==0) {
  512.             action = lyx_func_table[last_action_idx].action;
  513.             break;
  514.         } else if (k<0)
  515.             l = last_action_idx+1;
  516.         else r = last_action_idx;
  517.     }
  518.     if (arg && action >= 0) {
  519.         action = getPseudoAction((kb_action)action, arg);
  520.         lyxerr.debug(LString("Pseudo action_arg[")
  521.                  + int(action) + '|' 
  522.                  + PTR_AS_INT(arg) + ']',Error::KEY);
  523.     }
  524.     return action;
  525. }
  526.  
  527.  
  528. int LyXAction::getApproxFunc(LString const &func)
  529. {
  530.     int action = LookupFunc(func);
  531.     if (action < 0) {
  532.         int k = compare(lyx_func_table[last_action_idx].name,
  533.                 func, func.length());
  534.         if (k < 0 && last_action_idx < funcCount-1) 
  535.             last_action_idx++;
  536.         else if (k > 0 && last_action_idx > 0)
  537.             last_action_idx--;
  538.         
  539.         action = lyx_func_table[last_action_idx].action;
  540.     } else if (last_action_idx < funcCount - 1)
  541.         last_action_idx++;
  542.     
  543.     return action;
  544. }
  545.  
  546.  
  547. LString LyXAction::getApproxFuncName(LString const &func)
  548. {
  549.     getApproxFunc(func);
  550.     return lyx_func_table[last_action_idx].name;
  551. }
  552.  
  553.  
  554. LString LyXAction::getActionName(int action) const
  555. {
  556.     // why LFUN_LASTACTION -1? Because LFUN_LASTACTION is too
  557.     // large an because there is one internal command, hence
  558.     // lyx_func_table is 2 less then LFUN_LASTACTION (Lgb)
  559.     for (int i=0; i < funcCount; i++) {
  560.     if (lyx_func_table[i].action==action)
  561.       return lyx_func_table[i].name;
  562.     }
  563.     
  564.     // Hmm.. let's see whether this is a pseudoaction
  565.     action -= LFUN_LASTACTION;
  566.     if (action>=0 && action<psd_idx) {
  567.     return lyx_func_args[action].name;
  568.     }
  569.     
  570.     return "";
  571. }
  572.  
  573.  
  574. // Returns one line help associated with function
  575. // Now the missing strings are replaced by the command names. (Alejandro)
  576. LString  LyXAction::helpText(kb_action action) const
  577. {
  578.         static bool is_sorted = false;
  579.     static kb_func_table helpTexts[LFUN_LASTACTION] =
  580.     {
  581.         { _("Describe command"), LFUN_APROPOS },
  582.         { _("Select previous char"), LFUN_LEFTSEL },
  583.         { _("Insert bibtex"), LFUN_INSERT_BIBTEX },
  584.         { _("Autosave"), LFUN_AUTOSAVE },
  585.         { _("Go to beginning of document"), LFUN_BEGINNINGBUF },
  586.         { _("Select to beginning of document"), LFUN_BEGINNINGBUFSEL },
  587.         { _("Close"), LFUN_CLOSEBUFFER },
  588.         { _("Go to end of document"), LFUN_ENDBUF },
  589.         { _("Select to end of document"), LFUN_ENDBUFSEL },
  590.         { _("Fax"), LFUN_FAX },
  591.         { _("New document"), LFUN_MENUNEW },
  592.         { _("New document from template"), LFUN_MENUNEWTMPLT },
  593.         { _("Open"), LFUN_MENUOPEN },
  594.         { _("Switch to previous document"), LFUN_PREVBUFFER },
  595.         { _("Print"), LFUN_MENUPRINT },
  596.         { _("Revert to saved"), LFUN_MENURELOAD },
  597.         { _("Update DVI"), LFUN_RUNLATEX },
  598.         { _("Update PostScript"), LFUN_RUNDVIPS },
  599.         { _("View DVI"), LFUN_PREVIEW },
  600.         { _("View PostScript"), LFUN_PREVIEWPS },
  601.         { _("Check TeX"), LFUN_RUNCHKTEX },
  602.         { _("Save"), LFUN_MENUWRITE },
  603.         { _("Save As"), LFUN_MENUWRITEAS },
  604.         { _("Cancel"), LFUN_CANCEL },
  605.         { _("Go one char back"), LFUN_LEFT },
  606.         { _("Go one char forward"), LFUN_RIGHT },
  607.         { _("Insert citation"), LFUN_INSERT_CITATION },
  608.         { _("Execute command"), LFUN_EXEC_COMMAND },
  609.         { _("Copy"), LFUN_COPY },
  610.         { _("Cut"), LFUN_CUT },
  611.         { _("Decrement environment depth"), LFUN_DEPTH_MIN },
  612.         { _("Increment environment depth"), LFUN_DEPTH_PLUS },
  613.         { _("Change environment depth"), LFUN_DEPTH },
  614.         { _("Change itemize bullet settings"), LFUN_BUFFERBULLETSSELECT },
  615.         { _("Go down"), LFUN_DOWN },
  616.         { _("Select next line"), LFUN_DOWNSEL },
  617.         { _("Choose Paragraph Environment"), LFUN_DROP_LAYOUTS_CHOICE },
  618.         { _("Go to next error"), LFUN_GOTOERROR },
  619.         { _("Insert Figure"), LFUN_FIGURE },
  620.         { _("Find & Replace"), LFUN_MENUSEARCH },
  621.         { _("Toggle cursor does/doesn't follow the scrollbar"), LFUN_TOGGLECURSORFOLLOW },
  622.         { _("Toggle bold"), LFUN_BOLD },
  623.         { _("Toggle code style"), LFUN_CODE },
  624.         { _("Default font style"), LFUN_DEFAULT },
  625.         { _("Toggle emphasize"), LFUN_EMPH },
  626.         { _("Toggle user defined style"), LFUN_FREE },
  627.         { _("Toggle noun style"), LFUN_NOUN },
  628.         { _("Toggle roman font style"), LFUN_ROMAN },
  629.         { _("Toggle sans font style"), LFUN_SANS },
  630.         { _("Set font size"), LFUN_FONT_SIZE },
  631.         { _("Show font state"), LFUN_FONT_STATE },
  632.         { _("Toggle font underline"), LFUN_UNDERLINE },
  633.         { _("Insert Footnote"), LFUN_FOOTMELT },
  634.         { _("Select next char"), LFUN_RIGHTSEL },
  635.         { _("Insert horizontal fill"), LFUN_HFILL },
  636.         { _("Insert hyphenation point"), LFUN_HYPHENATION },
  637.         { _("Insert ... dots"), LFUN_LDOTS },
  638.         { _("Insert end of sentence period"), LFUN_END_OF_SENTENCE },
  639.         { _("Turn off keymap"), LFUN_KMAP_OFF },
  640.         { _("Use primary keymap"), LFUN_KMAP_PRIM },
  641.         { _("Use secondary keymap"), LFUN_KMAP_SEC },
  642.         { _("Toggle keymap"), LFUN_KMAP_TOGGLE },
  643.         { _("Insert Label"), LFUN_INSERT_LABEL },
  644.         { _("Copy paragraph environment type"),    LFUN_LAYOUT_COPY },
  645.         { _("Paste paragraph environment type"), LFUN_LAYOUT_PASTE },
  646.         { _("Specify paper size and margins"), LFUN_LAYOUT_PAPER },
  647.         { _("Go to beginning of line"), LFUN_HOME },
  648.         { _("Select to beginning of line"), LFUN_HOMESEL },
  649.         { _("Go to end of line"), LFUN_END },
  650.         { _("Select to end of line"), LFUN_ENDSEL },
  651.         { _("Exit"), LFUN_QUIT },
  652.         { _("Insert Margin note"), LFUN_MARGINMELT },
  653.         { _("Math Greek"), LFUN_GREEK },   
  654.         { _("Math mode"), LFUN_MATH_MODE },
  655.         { _("Go one paragraph down"), LFUN_DOWN_PARAGRAPH },
  656.         { _("Select next paragraph"), LFUN_DOWN_PARAGRAPHSEL },
  657.         { _("Go one paragraph up"), LFUN_UP_PARAGRAPH },
  658.         { _("Select previous paragraph"), LFUN_UP_PARAGRAPHSEL },
  659.         { _("Paste"), LFUN_PASTE },
  660.         { _("Insert protected space"), LFUN_PROTECTEDSPACE },
  661.         { _("Insert quote"), LFUN_QUOTE },
  662.         { _("Reconfigure"), LFUN_RECONFIGURE },
  663.         { _("Redo"), LFUN_REDO },
  664.         { _("Insert cross reference"), LFUN_INSERT_REF },
  665.         { _("Insert Table"), LFUN_TABLE },
  666.         { _("Toggle TeX style"), LFUN_TEX },
  667.         { _("Undo"), LFUN_UNDO },
  668.         { _("Melt"), LFUN_MELT },
  669.         { _("Remove all error boxes"), LFUN_REMOVEERRORS }
  670. //            { "reference-back", LFUN_REFBACK },
  671. //            { "reference-goto", LFUN_REFGOTO }, 
  672.     };
  673.         
  674.         // Sort to make it faster
  675.         if (!is_sorted) {
  676.         int i=0; 
  677.             while (i < LFUN_LASTACTION-1) {
  678.             if (helpTexts[i].action == 0) {
  679.             helpTexts[i].action = (kb_action)i;
  680.             helpTexts[i].name = getActionName(i).c_str();
  681.             i++;
  682.             } else if (helpTexts[i].action != i) {
  683.             int k = helpTexts[i].action;
  684.                 kb_func_table tmp = helpTexts[k];
  685.             helpTexts[k] = helpTexts[i];
  686.             helpTexts[i] = tmp;
  687.             if (k < i) i++;
  688.             } else {
  689.             i++;
  690.             }
  691.         }
  692.             is_sorted = true;
  693.     }
  694.  
  695.     if (action <=1 || action >=funcCount)
  696.         goto no_desc;
  697.         
  698.         if (helpTexts[action].action == action) {
  699.         return helpTexts[action].name;
  700.     } 
  701.     //      + LString(' ') + int(is_ro) + LString(']'));
  702.   no_desc:
  703.     // In an ideal world, this never happens:
  704.     return _("No description available!");
  705. }
  706.  
  707.  
  708. // Function to compare items from the attrib table.
  709. int actioncomp(const void *a, const void *b)
  710. {
  711.     int const *ia=(int const*)a, *ib=(int const*)b;
  712.     return (*ia)-(*ib);
  713. }
  714.  
  715.  
  716. bool LyXAction::isFuncRO(kb_action action) const
  717. {
  718.     static bool is_sorted = false;    
  719.     static int fCount = sizeof(::func_attrib_table) / sizeof(kb_action);
  720.     
  721.     if (!is_sorted) {
  722.     qsort(func_attrib_table, fCount, sizeof(kb_action), actioncomp);
  723.     is_sorted = true;
  724. //    for (int i=0; i<fCount; i++) 
  725. //      fprintf(stdout, "%d: %d\n", i, func_attrib_table[i]);
  726.     }
  727.  
  728.     int m, k, l= 0, r = fCount;
  729.     int is_ro = false;
  730.  
  731.     while (l < r) {
  732.     m = (l+r)/2;
  733.     k = func_attrib_table[m] - action;
  734.     if (k==0) {
  735.         is_ro = true;
  736.         break;
  737.     } else
  738.       if (k<0) l = m+1; else r = m;
  739.     }
  740.     lyxerr.debug(LString("RO[") + int(action)
  741.           + LString(" ") + int(is_ro) + LString("]"));
  742.     return is_ro;
  743. }
  744.  
  745.