diff --git a/lib/configure.py b/lib/configure.py index 97cd0a2418..a8a9cdb2be 100644 --- a/lib/configure.py +++ b/lib/configure.py @@ -178,7 +178,6 @@ def checkProg(description, progs, rc_entry = [], path = [], not_found = ''): return ['', not_found] -## Searching some useful programs def checkProgAlternatives(description, progs, rc_entry = [], alt_rc_entry = [], path = [], not_found = ''): ''' The same as checkProg, but additionally, all found programs will be added @@ -188,10 +187,6 @@ def checkProgAlternatives(description, progs, rc_entry = [], alt_rc_entry = [], if len(rc_entry) > 1 and len(rc_entry) != len(progs) + 1: logger.error("rc entry should have one item or item for each prog and not_found.") sys.exit(2) - # check if alt rcs are given - if len(alt_rc_entry) > 1 and len(alt_rc_entry) != len(rc_entry): - logger.error("invalid alt_rc_entry specification.") - sys.exit(2) logger.info('checking for ' + description + '...') ## print '(' + ','.join(progs) + ')', found_prime = False @@ -221,9 +216,17 @@ def checkProgAlternatives(description, progs, rc_entry = [], alt_rc_entry = [], real_ac_word = ac_word found_prime = True if len(alt_rc_entry) == 1: - addToRC(alt_rc_entry[0].replace('%%', ac_prog)) + alt_rc = alt_rc_entry[0] + if alt_rc == "": + # if no explicit alt_rc is given, construct one + alt_rc = rc_entry[0] + "_alternatives" + addToRC(alt_rc.replace('%%', ac_prog)) elif len(alt_rc_entry) > 1: - addToRC(alt_rc_entry[idx].replace('%%', ac_prog)) + alt_rc = alt_rc_entry[idx] + if alt_rc == "": + # if no explicit alt_rc is given, construct one + alt_rc = rc_entry[idx] + "_alternatives" + addToRC(alt_rc.replace('%%', ac_prog)) found_alt = True break if found_alt: @@ -239,9 +242,128 @@ def checkProgAlternatives(description, progs, rc_entry = [], alt_rc_entry = [], return ['', not_found] +def addViewerAlternatives(rcs): + r = re.compile(r'\\Format (\S+).*$') + m = None + alt = '' + for idxx in range(len(rcs)): + if len(rcs) == 1: + m = r.match(rcs[0]) + if m: + alt = r'\viewer_alternatives ' + m.group(1) + " %%" + elif len(rcs) > 1: + m = r.match(rcs[idxx]) + if m: + if idxx > 0: + alt += '\n' + alt += r'\viewer_alternatives ' + m.group(1) + " %%" + return alt + + +def addEditorAlternatives(rcs): + r = re.compile(r'\\Format (\S+).*$') + m = None + alt = '' + for idxx in range(len(rcs)): + if len(rcs) == 1: + m = r.match(rcs[0]) + if m: + alt = r'\editor_alternatives ' + m.group(1) + " %%" + elif len(rcs) > 1: + m = r.match(rcs[idxx]) + if m: + if idxx > 0: + alt += '\n' + alt += r'\editor_alternatives ' + m.group(1) + " %%" + return alt + + def checkViewer(description, progs, rc_entry = [], path = []): - ''' The same as checkProg, but for viewers and editors ''' - return checkProg(description, progs, rc_entry, path, not_found = 'auto') + ''' The same as checkProgAlternatives, but for viewers ''' + if len(rc_entry) > 1 and len(rc_entry) != len(progs) + 1: + logger.error("rc entry should have one item or item for each prog and not_found.") + sys.exit(2) + alt_rc_entry = [] + for idx in range(len(progs)): + if len(rc_entry) == 1: + logger.info("rc_entry: " + rc_entry[0]) + rcs = rc_entry[0].split('\n') + alt = addViewerAlternatives(rcs) + alt_rc_entry.insert(0, alt) + elif len(rc_entry) > 1: + logger.info("rc_entry: " + rc_entry[idx]) + rcs = rc_entry[idx].split('\n') + alt = addViewerAlternatives(rcs) + alt_rc_entry.insert(idx, alt) + return checkProgAlternatives(description, progs, rc_entry, alt_rc_entry, path, not_found = 'auto') + + +def checkEditor(description, progs, rc_entry = [], path = []): + ''' The same as checkProgAlternatives, but for editors ''' + if len(rc_entry) > 1 and len(rc_entry) != len(progs) + 1: + logger.error("rc entry should have one item or item for each prog and not_found.") + sys.exit(2) + alt_rc_entry = [] + for idx in range(len(progs)): + if len(rc_entry) == 1: + logger.info("rc_entry: " + rc_entry[0]) + rcs = rc_entry[0].split('\n') + alt = addEditorAlternatives(rcs) + alt_rc_entry.insert(0, alt) + elif len(rc_entry) > 1: + logger.info("rc_entry: " + rc_entry[idx]) + rcs = rc_entry[idx].split('\n') + alt = addEditorAlternatives(rcs) + alt_rc_entry.insert(idx, alt) + return checkProgAlternatives(description, progs, rc_entry, alt_rc_entry, path, not_found = 'auto') + + +def checkViewerNoRC(description, progs, rc_entry = [], path = []): + ''' The same as checkViewer, but do not add rc entry ''' + if len(rc_entry) > 1 and len(rc_entry) != len(progs) + 1: + logger.error("rc entry should have one item or item for each prog and not_found.") + sys.exit(2) + alt_rc_entry = [] + for idx in range(len(progs)): + if len(rc_entry) == 1: + logger.info("rc_entry: " + rc_entry[0]) + rcs = rc_entry[0].split('\n') + alt = addViewerAlternatives(rcs) + alt_rc_entry.insert(0, alt) + elif len(rc_entry) > 1: + logger.info("rc_entry: " + rc_entry[idx]) + rcs = rc_entry[idx].split('\n') + alt = addViewerAlternatives(rcs) + alt_rc_entry.insert(idx, alt) + rc_entry = [] + return checkProgAlternatives(description, progs, rc_entry, alt_rc_entry, path, not_found = 'auto') + + +def checkEditorNoRC(description, progs, rc_entry = [], path = []): + ''' The same as checkViewer, but do not add rc entry ''' + if len(rc_entry) > 1 and len(rc_entry) != len(progs) + 1: + logger.error("rc entry should have one item or item for each prog and not_found.") + sys.exit(2) + alt_rc_entry = [] + for idx in range(len(progs)): + if len(rc_entry) == 1: + logger.info("rc_entry: " + rc_entry[0]) + rcs = rc_entry[0].split('\n') + alt = addEditorAlternatives(rcs) + alt_rc_entry.insert(0, alt) + elif len(rc_entry) > 1: + logger.info("rc_entry: " + rc_entry[idx]) + rcs = rc_entry[idx].split('\n') + alt = addEditorAlternatives(rcs) + alt_rc_entry.insert(idx, alt) + rc_entry = [] + return checkProgAlternatives(description, progs, rc_entry, alt_rc_entry, path, not_found = 'auto') + + +def checkViewerEditor(description, progs, rc_entry = [], path = []): + ''' The same as checkProgAlternatives, but for viewers and editors ''' + checkEditorNoRC(description, progs, rc_entry, path) + return checkViewer(description, progs, rc_entry, path) def checkDTLtools(): @@ -309,23 +431,43 @@ def checkLatex(dtl_tools): def checkFormatEntries(dtl_tools): ''' Check all formats (\Format entries) ''' - checkViewer('a Tgif viewer and editor', ['tgif'], + checkViewerEditor('a Tgif viewer and editor', ['tgif'], rc_entry = [r'\Format tgif obj Tgif "" "%%" "%%" "vector"']) # - checkViewer('a FIG viewer and editor', ['xfig', 'jfig3-itext.jar', 'jfig3.jar'], + checkViewerEditor('a FIG viewer and editor', ['xfig', 'jfig3-itext.jar', 'jfig3.jar'], rc_entry = [r'\Format fig fig FIG "" "%%" "%%" "vector"']) # - checkViewer('a Dia viewer and editor', ['dia'], + checkViewerEditor('a Dia viewer and editor', ['dia'], rc_entry = [r'\Format dia dia DIA "" "%%" "%%" "vector"']) # - checkViewer('a Grace viewer and editor', ['xmgrace'], + checkViewerEditor('a Grace viewer and editor', ['xmgrace'], rc_entry = [r'\Format agr agr Grace "" "%%" "%%" "vector"']) # - checkViewer('a FEN viewer and editor', ['xboard -lpf $$i -mode EditPosition'], + checkViewerEditor('a FEN viewer and editor', ['xboard -lpf $$i -mode EditPosition'], rc_entry = [r'\Format fen fen FEN "" "%%" "%%" ""']) # - path, iv = checkViewer('a raster image viewer', ['xv', 'kview', 'gimp-remote', 'gimp']) - path, ie = checkViewer('a raster image editor', ['gimp-remote', 'gimp']) + path, iv = checkViewerNoRC('a raster image viewer', ['xv', 'kview', 'gimp-remote', 'gimp'], + rc_entry = [r'''\Format bmp bmp BMP "" "%s" "%s" "" +\Format gif gif GIF "" "%s" "%s" "" +\Format jpg jpg JPEG "" "%s" "%s" "" +\Format pbm pbm PBM "" "%s" "%s" "" +\Format pgm pgm PGM "" "%s" "%s" "" +\Format png png PNG "" "%s" "%s" "" +\Format ppm ppm PPM "" "%s" "%s" "" +\Format tiff tif TIFF "" "%s" "%s" "" +\Format xbm xbm XBM "" "%s" "%s" "" +\Format xpm xpm XPM "" "%s" "%s" ""''']) + path, ie = checkEditorNoRC('a raster image editor', ['gimp-remote', 'gimp'], + rc_entry = [r'''\Format bmp bmp BMP "" "%s" "%s" "" +\Format gif gif GIF "" "%s" "%s" "" +\Format jpg jpg JPEG "" "%s" "%s" "" +\Format pbm pbm PBM "" "%s" "%s" "" +\Format pgm pgm PGM "" "%s" "%s" "" +\Format png png PNG "" "%s" "%s" "" +\Format ppm ppm PPM "" "%s" "%s" "" +\Format tiff tif TIFF "" "%s" "%s" "" +\Format xbm xbm XBM "" "%s" "%s" "" +\Format xpm xpm XPM "" "%s" "%s" ""''']) addToRC(r'''\Format bmp bmp BMP "" "%s" "%s" "" \Format gif gif GIF "" "%s" "%s" "" \Format jpg jpg JPEG "" "%s" "%s" "" @@ -338,7 +480,7 @@ def checkFormatEntries(dtl_tools): \Format xpm xpm XPM "" "%s" "%s" ""''' % \ (iv, ie, iv, ie, iv, ie, iv, ie, iv, ie, iv, ie, iv, ie, iv, ie, iv, ie, iv, ie) ) # - checkViewer('a text editor', ['sensible-editor', 'xemacs', 'gvim', 'kedit', 'kwrite', 'kate', \ + checkViewerEditor('a text editor', ['sensible-editor', 'xemacs', 'gvim', 'kedit', 'kwrite', 'kate', \ 'nedit', 'gedit', 'notepad'], rc_entry = [r'''\Format asciichess asc "Plain text (chess output)" "" "" "%%" "" \Format asciiimage asc "Plain text (image)" "" "" "%%" "" @@ -365,7 +507,7 @@ def checkFormatEntries(dtl_tools): if xhtmlview == "": addToRC(r'\Format xhtml html "LyX HTML" "" "" "%%" "document"') # - checkViewer('a BibTeX editor', ['sensible-editor', 'jabref', 'JabRef', \ + checkEditor('a BibTeX editor', ['sensible-editor', 'jabref', 'JabRef', \ 'pybliographic', 'bibdesk', 'gbib', 'kbib', \ 'kbibtex', 'sixpack', 'bibedit', 'tkbibtex' \ 'xemacs', 'gvim', 'kedit', 'kwrite', 'kate', \ @@ -394,10 +536,10 @@ def checkFormatEntries(dtl_tools): checkViewer('an HTML previewer', ['firefox', 'mozilla file://$$p$$i', 'netscape'], rc_entry = [r'\Format html html HTML H "%%" "" "document"']) # - checkViewer('Noteedit', ['noteedit'], + checkViewerEditor('Noteedit', ['noteedit'], rc_entry = [r'\Format noteedit not Noteedit "" "%%" "%%" "vector"']) # - checkViewer('an OpenDocument viewer', ['swriter', 'oowriter'], + checkViewerEditor('an OpenDocument viewer', ['swriter', 'oowriter'], rc_entry = [r'\Format odt odt OpenDocument "" "%%" "%%" "document,vector"']) # # entried that do not need checkProg diff --git a/src/LyXFunc.cpp b/src/LyXFunc.cpp index 9a2969d2db..f44c587b6b 100644 --- a/src/LyXFunc.cpp +++ b/src/LyXFunc.cpp @@ -1978,6 +1978,7 @@ void actOnUpdatedPrefs(LyXRC const & lyxrc_orig, LyXRC const & lyxrc_new) if (path.exists() && path.isDirectory()) package().document_dir() = FileName(lyxrc.document_path); } + case LyXRC::RC_EDITOR_ALTERNATIVES: case LyXRC::RC_ESC_CHARS: case LyXRC::RC_EXAMPLEPATH: case LyXRC::RC_FONT_ENCODING: @@ -2085,6 +2086,7 @@ void actOnUpdatedPrefs(LyXRC const & lyxrc_orig, LyXRC const & lyxrc_new) case LyXRC::RC_FULL_SCREEN_WIDTH: case LyXRC::RC_VISUAL_CURSOR: case LyXRC::RC_VIEWER: + case LyXRC::RC_VIEWER_ALTERNATIVES: case LyXRC::RC_LAST: break; } diff --git a/src/LyXRC.cpp b/src/LyXRC.cpp index aec66ee898..438714cfe3 100644 --- a/src/LyXRC.cpp +++ b/src/LyXRC.cpp @@ -87,6 +87,7 @@ LexerKeyword lyxrcTags[] = { { "\\dialogs_iconify_with_main", LyXRC::RC_DIALOGS_ICONIFY_WITH_MAIN }, { "\\display_graphics", LyXRC::RC_DISPLAY_GRAPHICS }, { "\\document_path", LyXRC::RC_DOCUMENTPATH }, + { "\\editor_alternatives", LyXRC::RC_EDITOR_ALTERNATIVES }, { "\\escape_chars", LyXRC::RC_ESC_CHARS }, { "\\example_path", LyXRC::RC_EXAMPLEPATH }, { "\\font_encoding", LyXRC::RC_FONT_ENCODING }, @@ -195,6 +196,7 @@ LexerKeyword lyxrcTags[] = { { "\\view_dvi_paper_option", LyXRC::RC_VIEWDVI_PAPEROPTION }, // compatibility with versions older than 1.4.0 only { "\\viewer", LyXRC::RC_VIEWER}, + { "\\viewer_alternatives", LyXRC::RC_VIEWER_ALTERNATIVES }, { "\\visual_cursor" ,LyXRC::RC_VISUAL_CURSOR} }; @@ -1032,6 +1034,19 @@ int LyXRC::read(Lexer & lexrc) } break; } + case RC_VIEWER_ALTERNATIVES: { + string format, command; + lexrc >> format >> command; + viewer_alternatives.push_back(make_pair(format, command)); + break; + } + case RC_EDITOR_ALTERNATIVES: { + string format, command; + lexrc >> format >> command; + editor_alternatives.push_back(make_pair(format, command)); + break; + } + case RC_DEFAULT_VIEW_FORMAT: lexrc >> default_view_format; break; @@ -2459,6 +2474,26 @@ void LyXRC::write(ostream & os, bool ignore_system_lyxrc, string const & name) c << "\" \"\" \"\" \"\" \"\" \"\" \"\"\n"; if (tag != RC_LAST) break; + case RC_VIEWER_ALTERNATIVES: + if (ignore_system_lyxrc || + viewer_alternatives != system_lyxrc.viewer_alternatives) { + for (vector >::const_iterator it = viewer_alternatives.begin(); + it != viewer_alternatives.end(); ++it) + os << "\\viewer_alternatives " + << it->first << " " << it->second << "\n"; + } + if (tag != RC_LAST) + break; + case RC_EDITOR_ALTERNATIVES: + if (ignore_system_lyxrc || + editor_alternatives != system_lyxrc.editor_alternatives) { + for (vector >::const_iterator it = editor_alternatives.begin(); + it != editor_alternatives.end(); ++it) + os << "\\editor_alternatives " + << it->first << " " << it->second << "\n"; + } + if (tag != RC_LAST) + break; case RC_DEFAULT_VIEW_FORMAT: if (ignore_system_lyxrc || default_view_format != system_lyxrc.default_view_format) { diff --git a/src/LyXRC.h b/src/LyXRC.h index afb0dfb2af..4468af9387 100644 --- a/src/LyXRC.h +++ b/src/LyXRC.h @@ -24,6 +24,7 @@ #include #include +#include namespace lyx { @@ -71,6 +72,7 @@ public: RC_DIALOGS_ICONIFY_WITH_MAIN, RC_DISPLAY_GRAPHICS, RC_DOCUMENTPATH, + RC_EDITOR_ALTERNATIVES, RC_ESC_CHARS, RC_EXAMPLEPATH, RC_FONT_ENCODING, @@ -177,6 +179,7 @@ public: RC_USE_SPELL_LIB, RC_VIEWDVI_PAPEROPTION, RC_VIEWER, + RC_VIEWER_ALTERNATIVES, RC_VISUAL_CURSOR, RC_LAST }; @@ -383,6 +386,10 @@ public: std::string gui_language; /// std::string default_view_format; + /// all available viewers + std::vector > viewer_alternatives; + /// all available editors + std::vector > editor_alternatives; /// bool mac_like_word_movement; /// diff --git a/src/frontends/qt4/GuiPrefs.cpp b/src/frontends/qt4/GuiPrefs.cpp index 6b07c21424..f9ebae1fd8 100644 --- a/src/frontends/qt4/GuiPrefs.cpp +++ b/src/frontends/qt4/GuiPrefs.cpp @@ -1632,6 +1632,10 @@ PrefFileformats::PrefFileformats(GuiPreferences * form) this, SIGNAL(changed())); connect(defaultFormatCB, SIGNAL(activated(QString)), this, SIGNAL(changed())); + connect(viewerCO, SIGNAL(activated(int)), + this, SIGNAL(changed())); + connect(editorCO, SIGNAL(activated(int)), + this, SIGNAL(changed())); } @@ -1660,6 +1664,8 @@ void PrefFileformats::apply(LyXRC & rc) const void PrefFileformats::update(LyXRC const & rc) { + viewer_alternatives = rc.viewer_alternatives; + editor_alternatives = rc.editor_alternatives; bool const init = defaultFormatCB->currentText().isEmpty(); updateView(); if (init) { @@ -1713,10 +1719,10 @@ void PrefFileformats::on_formatsCB_currentIndexChanged(int i) extensionED->setText(toqstr(f.extension())); shortcutED->setText( toqstr(l10n_shortcut(f.prettyname(), f.shortcut()))); - viewerED->setText(toqstr(f.viewer())); - editorED->setText(toqstr(f.editor())); documentCB->setChecked((f.documentFormat())); vectorCB->setChecked((f.vectorFormat())); + updateViewers(); + updateEditors(); } @@ -1813,6 +1819,68 @@ void PrefFileformats::updatePrettyname() } +void PrefFileformats::updateViewers() +{ + Format const f = currentFormat(); + viewerCO->clear(); + viewerCO->addItem(qt_("None"), QString()); + for (vector >::const_iterator it = viewer_alternatives.begin(); + it != viewer_alternatives.end(); ++it) { + if (it->first == f.name()) + viewerCO->addItem(toqstr(it->second), toqstr(it->second)); + } + viewerCO->addItem(qt_("Custom"), QString("custom viewer")); + + int pos = viewerCO->findData(toqstr(f.viewer())); + if (pos != -1) { + viewerED->clear(); + viewerED->setEnabled(false); + viewerCO->setCurrentIndex(pos); + } else { + viewerED->setEnabled(true); + viewerED->setText(toqstr(f.viewer())); + viewerCO->setCurrentIndex(viewerCO->findData(toqstr("custom viewer"))); + } +} + + +void PrefFileformats::updateEditors() +{ + Format const f = currentFormat(); + editorCO->clear(); + editorCO->addItem(qt_("None"), QString()); + for (vector >::const_iterator it = editor_alternatives.begin(); + it != editor_alternatives.end(); ++it) { + if (it->first == f.name()) + editorCO->addItem(toqstr(it->second), toqstr(it->second)); + } + editorCO->addItem(qt_("Custom"), QString("custom editor")); + + int pos = editorCO->findData(toqstr(f.editor())); + if (pos != -1) { + editorED->clear(); + editorED->setEnabled(false); + editorCO->setCurrentIndex(pos); + } else { + editorED->setEnabled(true); + editorED->setText(toqstr(f.viewer())); + editorCO->setCurrentIndex(viewerCO->findData(toqstr("custom editor"))); + } +} + + +void PrefFileformats::on_viewerCO_currentIndexChanged(int i) +{ + viewerED->setEnabled(viewerCO->itemData(i).toString() == "custom viewer"); +} + + +void PrefFileformats::on_editorCO_currentIndexChanged(int i) +{ + editorED->setEnabled(editorCO->itemData(i).toString() == "custom editor"); +} + + Format & PrefFileformats::currentFormat() { int const i = formatsCB->currentIndex(); diff --git a/src/frontends/qt4/GuiPrefs.h b/src/frontends/qt4/GuiPrefs.h index 5e5d03a9c7..1c39119584 100644 --- a/src/frontends/qt4/GuiPrefs.h +++ b/src/frontends/qt4/GuiPrefs.h @@ -367,11 +367,21 @@ private Q_SLOTS: void on_formatsCB_editTextChanged(const QString &); void on_formatNewPB_clicked(); void on_formatRemovePB_clicked(); + void on_viewerCO_currentIndexChanged(int i); + void on_editorCO_currentIndexChanged(int i); void setFlags(); void updatePrettyname(); private: Format & currentFormat(); + /// + void updateViewers(); + /// + void updateEditors(); + /// + std::vector > viewer_alternatives; + /// + std::vector > editor_alternatives; }; diff --git a/src/frontends/qt4/ui/PrefFileformatsUi.ui b/src/frontends/qt4/ui/PrefFileformatsUi.ui index 2f8141dd4b..37828c4068 100644 --- a/src/frontends/qt4/ui/PrefFileformatsUi.ui +++ b/src/frontends/qt4/ui/PrefFileformatsUi.ui @@ -1,64 +1,177 @@ - + + PrefFileformatsUi - - + + 0 0 - 427 - 413 + 443 + 477 - + - - - 9 - - - 6 - - - - - Specify the default output format when using (PDF)LaTeX + + + + + &Format: - - Default Format + + formatsCB - - true - - - - 9 - - - 6 - - - - - De&fault Output Format: - - - defaultFormatCB - - - - - - - - + + + + + 0 + 0 + + + + true + + + 20 + + + QComboBox::InsertAtCurrent + + + 1 + + + + + + + &New... + + + + + + + Re&move + + + + + + + &Document format + + + + + + + Vector &graphics format + + + + + + + S&hort Name: + + + formatED + + + + + + + + + + E&xtension: + + + extensionED + + + + + + + + + + Shortc&ut: + + + shortcutED + + + + + + + + + + Ed&itor: + + + editorCO + + + + + + + + + + + + + + + + + &Viewer: + + + viewerCO + + + + + + + + + + + + + + + + + Co&pier: + + + copierED + + + + + + + - + Qt::Vertical - + 124 21 @@ -66,144 +179,38 @@ - - - - - - - - - - &New... + + + + Specify the default output format when using (PDF)LaTeX - - - - - - Re&move + + Default Format - - - - - - - - - - - - S&hort Name: - - - formatED - - - - - - - - 7 - 0 - 0 - 0 - - - + true - - 20 - - - QComboBox::InsertAtCurrent - - - 1 - - - - - - - Vector &graphics format - - - - - - - &Format: - - - formatsCB - - - - - - - &Document format - - - - - - - &Viewer: - - - viewerED - - - - - - - - - - Ed&itor: - - - editorED - - - - - - - Shortc&ut: - - - shortcutED - - - - - - - E&xtension: - - - extensionED - - - - - - - - - - Co&pier: - - - copierED - + + + 9 + + + 6 + + + + + De&fault Output Format: + + + defaultFormatCB + + + + + + + @@ -222,7 +229,7 @@ copierED - qt_i18n.h + qt_i18n.h