X-Git-Url: https://git.lyx.org/gitweb/?a=blobdiff_plain;f=src%2Flyxfunc.C;h=4570bfba8f511ab85c6e4ac5f501e9d105ff67ce;hb=969ab85d985485f503790cb13f98a582d4e1cdb5;hp=147592e729c37e0458461889648952e5cbcbd0dd;hpb=5ce7ae18839c85ff6341a643c5bf061c24fc37ff;p=lyx.git diff --git a/src/lyxfunc.C b/src/lyxfunc.C index 147592e729..4570bfba8f 100644 --- a/src/lyxfunc.C +++ b/src/lyxfunc.C @@ -27,6 +27,7 @@ #include "bufferlist.h" #include "bufferparams.h" #include "BufferView.h" +#include "bufferview_funcs.h" #include "cursor.h" #include "CutAndPaste.h" #include "debug.h" @@ -241,6 +242,42 @@ void LyXFunc::handleKeyFunc(kb_action action) } +void LyXFunc::gotoBookmark(unsigned int idx, bool openFile, bool switchToBuffer) +{ + BOOST_ASSERT(lyx_view_); + if (!LyX::ref().session().bookmarks().isValid(idx)) + return; + BookmarksSection::Bookmark const & bm = LyX::ref().session().bookmarks().bookmark(idx); + BOOST_ASSERT(!bm.filename.empty()); + string const file = bm.filename.absFilename(); + // if the file is not opened, open it. + if (!theBufferList().exists(file)) { + if (openFile) + dispatch(FuncRequest(LFUN_FILE_OPEN, file)); + else + return; + } + // open may fail, so we need to test it again + if (theBufferList().exists(file)) { + // if the current buffer is not that one, switch to it. + if (lyx_view_->buffer()->fileName() != file) { + if (switchToBuffer) + dispatch(FuncRequest(LFUN_BUFFER_SWITCH, file)); + else + return; + } + // moveToPosition use par_id, and par_pit and return new par_id. + pit_type new_pit; + int new_id; + boost::tie(new_pit, new_id) = view()->moveToPosition(bm.par_pit, bm.par_id, bm.par_pos); + // if par_id or pit has been changed, reset par_pit and par_id + // see http://bugzilla.lyx.org/show_bug.cgi?id=3092 + if (bm.par_pit != new_pit || bm.par_id != new_id) + const_cast(bm).setPos(new_pit, new_id); + } +} + + void LyXFunc::processKeySym(LyXKeySymPtr keysym, key_modifier::state state) { lyxerr[Debug::KEY] << "KeySym is " << keysym->getSymbolName() << endl; @@ -259,7 +296,9 @@ void LyXFunc::processKeySym(LyXKeySymPtr keysym, key_modifier::state state) //Encoding const * encoding = view()->cursor().getEncoding(); //encoded_last_key = keysym->getISOEncoded(encoding ? encoding->name() : ""); - size_t encoded_last_key = keysym->getUCSEncoded(); + // FIXME: encoded_last_key shadows the member variable of the same + // name. Is that intended? + char_type encoded_last_key = keysym->getUCSEncoded(); // Do a one-deep top-level lookup for // cancel and meta-fake keys. RVDK_PATCH_5 @@ -293,7 +332,7 @@ void LyXFunc::processKeySym(LyXKeySymPtr keysym, key_modifier::state state) lyxerr << BOOST_CURRENT_FUNCTION << " Key [action=" << func.action << "][" - << keyseq->print() << ']' + << to_utf8(keyseq->print(false)) << ']' << endl; } @@ -302,7 +341,7 @@ void LyXFunc::processKeySym(LyXKeySymPtr keysym, key_modifier::state state) // num_bytes == 0? (Lgb) if (keyseq->length() > 1) { - lyx_view_->message(from_utf8(keyseq->print())); + lyx_view_->message(keyseq->print(true)); } @@ -349,24 +388,6 @@ FuncStatus LyXFunc::getStatus(FuncRequest const & cmd) const //lyxerr << "LyXFunc::getStatus: cmd: " << cmd << endl; FuncStatus flag; - if (cmd.action == LFUN_LYX_QUIT) { - flag.message(from_utf8(N_("Exiting"))); - flag.enabled(true); - return flag; - } else if (cmd.action == LFUN_BOOKMARK_GOTO) { - // bookmarks can be valid even if there is no opened buffer - flag.enabled(LyX::ref().session().bookmarks().isValid(convert(to_utf8(cmd.argument())))); - return flag; - } else if (cmd.action == LFUN_BOOKMARK_CLEAR) { - flag.enabled(LyX::ref().session().bookmarks().size() > 0); - return flag; - } else if (cmd.action == LFUN_TOOLBAR_TOGGLE_STATE) { - ToolbarBackend::Flags flags = lyx_view_->getToolbarState(to_utf8(cmd.argument())); - if (!(flags & ToolbarBackend::AUTO)) - flag.setOnOff(flags & ToolbarBackend::ON); - return flag; - } - LCursor & cur = view()->cursor(); /* In LyX/Mac, when a dialog is open, the menus of the @@ -515,9 +536,10 @@ FuncStatus LyXFunc::getStatus(FuncRequest const & cmd) const if (inset) { FuncRequest fr(LFUN_INSET_MODIFY, cmd.argument()); FuncStatus fs; - bool const success = inset->getStatus(cur, fr, fs); - // Every inset is supposed to handle this - BOOST_ASSERT(success); + if (!inset->getStatus(cur, fr, fs)) { + // Every inset is supposed to handle this + BOOST_ASSERT(false); + } flag |= fs; } else { FuncRequest fr(LFUN_INSET_INSERT, cmd.argument()); @@ -555,6 +577,11 @@ FuncStatus LyXFunc::getStatus(FuncRequest const & cmd) const case LFUN_DIALOG_SHOW_NEW_INSET: enable = cur.inset().lyxCode() != InsetBase::ERT_CODE; + if (cur.inset().lyxCode() == InsetBase::CAPTION_CODE) { + FuncStatus flag; + if (cur.inset().getStatus(cur, cmd, flag)) + return flag; + } break; case LFUN_DIALOG_UPDATE: { @@ -576,6 +603,22 @@ FuncStatus LyXFunc::getStatus(FuncRequest const & cmd) const break; } + case LFUN_BOOKMARK_GOTO: { + const unsigned int num = convert(to_utf8(cmd.argument())); + enable = LyX::ref().session().bookmarks().isValid(num); + break; + } + + case LFUN_BOOKMARK_CLEAR: + enable = LyX::ref().session().bookmarks().size() > 0; + break; + + case LFUN_TOOLBAR_TOGGLE_STATE: { + ToolbarBackend::Flags flags = lyx_view_->getToolbarState(to_utf8(cmd.argument())); + if (!(flags & ToolbarBackend::AUTO)) + flag.setOnOff(flags & ToolbarBackend::ON); + break; + } // this one is difficult to get right. As a half-baked // solution, we consider only the first action of the sequence @@ -639,6 +682,7 @@ FuncStatus LyXFunc::getStatus(FuncRequest const & cmd) const case LFUN_BUFFER_PREVIOUS: case LFUN_WINDOW_NEW: case LFUN_WINDOW_CLOSE: + case LFUN_LYX_QUIT: // these are handled in our dispatch() break; @@ -764,12 +808,12 @@ void LyXFunc::dispatch(FuncRequest const & cmd) case LFUN_WORD_FIND_FORWARD: case LFUN_WORD_FIND_BACKWARD: { BOOST_ASSERT(lyx_view_ && lyx_view_->view()); - static string last_search; - string searched_string; + static docstring last_search; + docstring searched_string; - if (!argument.empty()) { - last_search = argument; - searched_string = argument; + if (!cmd.argument().empty()) { + last_search = cmd.argument(); + searched_string = cmd.argument(); } else { searched_string = last_search; } @@ -778,7 +822,7 @@ void LyXFunc::dispatch(FuncRequest const & cmd) break; bool const fw = action == LFUN_WORD_FIND_FORWARD; - string const data = + docstring const data = find2string(searched_string, true, false, fw); find(view(), FuncRequest(LFUN_WORD_FIND, data)); break; @@ -786,7 +830,7 @@ void LyXFunc::dispatch(FuncRequest const & cmd) case LFUN_COMMAND_PREFIX: BOOST_ASSERT(lyx_view_); - lyx_view_->message(from_utf8(keyseq->printOptions())); + lyx_view_->message(keyseq->printOptions(true)); break; case LFUN_COMMAND_EXECUTE: @@ -807,7 +851,7 @@ void LyXFunc::dispatch(FuncRequest const & cmd) case LFUN_META_PREFIX: meta_fake_bit = key_modifier::alt; - setMessage(from_utf8(keyseq->print())); + setMessage(keyseq->print(true)); break; case LFUN_BUFFER_TOGGLE_READ_ONLY: @@ -841,8 +885,9 @@ void LyXFunc::dispatch(FuncRequest const & cmd) lyx_view_->message(str); menuWrite(lyx_view_->buffer()); lyx_view_->message(str + _(" done.")); - } else - writeAs(lyx_view_->buffer()); + } else { + writeAs(lyx_view_->buffer()); + } updateFlags = Update::None; break; @@ -861,7 +906,7 @@ void LyXFunc::dispatch(FuncRequest const & cmd) text, 0, 1, _("&Revert"), _("&Cancel")); if (ret == 0) - view()->reload(); + reloadBuffer(); break; } @@ -1015,9 +1060,20 @@ void LyXFunc::dispatch(FuncRequest const & cmd) } else { // case 1: print to a file + FileName const filename(makeAbsPath(target_name, path)); + if (fs::exists(filename.toFilesystemEncoding())) { + docstring text = bformat( + _("The file %1$s already exists.\n\n" + "Do you want to over-write that file?"), + makeDisplayPath(filename.absFilename())); + if (Alert::prompt(_("Over-write file?"), + text, 0, 1, _("&Over-write"), _("&Cancel")) != 0) { + showPrintError(buffer->fileName()); + break; + } + } command += lyxrc.print_to_file - + quoteName(makeAbsPath(target_name, - path)) + + quoteName(filename.toFilesystemEncoding()) + ' ' + quoteName(dviname); res = one.startscript(Systemcall::DontWait, @@ -1034,19 +1090,11 @@ void LyXFunc::dispatch(FuncRequest const & cmd) break; case LFUN_LYX_QUIT: - // FIXME: this code needs to be transfered somewhere else - // as lyx_view_ will most certainly be null and a same buffer - // might be visible in more than one LyXView. - if (lyx_view_ && lyx_view_->view()->buffer()) { - // save cursor Position for opened files to .lyx/session - LyX::ref().session().lastFilePos().save(FileName(lyx_view_->buffer()->fileName()), - boost::tie(view()->cursor().pit(), view()->cursor().pos()) ); - } - - // save the geometry of the current view - lyx_view_->saveGeometry(); - // quitting is triggered by the gui code (leaving the event loop) - theApp()->gui().closeAllViews(); + // quitting is triggered by the gui code + // (leaving the event loop). + lyx_view_->message(from_utf8(N_("Exiting."))); + if (theBufferList().quitWriteAll()) + theApp()->gui().closeAllViews(); break; case LFUN_TOC_VIEW: { @@ -1092,8 +1140,9 @@ void LyXFunc::dispatch(FuncRequest const & cmd) break; if (!lyx_view_->buffer()->lyxvc().inUse()) { lyx_view_->buffer()->lyxvc().registrer(); - view()->reload(); + reloadBuffer(); } + updateFlags = Update::Force; break; case LFUN_VC_CHECK_IN: @@ -1103,7 +1152,7 @@ void LyXFunc::dispatch(FuncRequest const & cmd) if (lyx_view_->buffer()->lyxvc().inUse() && !lyx_view_->buffer()->isReadonly()) { lyx_view_->buffer()->lyxvc().checkIn(); - view()->reload(); + reloadBuffer(); } break; @@ -1114,20 +1163,20 @@ void LyXFunc::dispatch(FuncRequest const & cmd) if (lyx_view_->buffer()->lyxvc().inUse() && lyx_view_->buffer()->isReadonly()) { lyx_view_->buffer()->lyxvc().checkOut(); - view()->reload(); + reloadBuffer(); } break; case LFUN_VC_REVERT: BOOST_ASSERT(lyx_view_ && lyx_view_->buffer()); lyx_view_->buffer()->lyxvc().revert(); - view()->reload(); + reloadBuffer(); break; case LFUN_VC_UNDO_LAST: BOOST_ASSERT(lyx_view_ && lyx_view_->buffer()); lyx_view_->buffer()->lyxvc().undoLast(); - view()->reload(); + reloadBuffer(); break; // --- buffers ---------------------------------------- @@ -1176,7 +1225,7 @@ void LyXFunc::dispatch(FuncRequest const & cmd) break; case LFUN_SERVER_NOTIFY: - dispatch_buffer = from_utf8(keyseq->print()); + dispatch_buffer = keyseq->print(false); theLyXServer().notifyClient(to_utf8(dispatch_buffer)); break; @@ -1204,8 +1253,7 @@ void LyXFunc::dispatch(FuncRequest const & cmd) view()->setCursorFromRow(row); - view()->center(); - // see BufferView::center() + updateFlags = Update::FitCursor; break; } @@ -1255,6 +1303,11 @@ void LyXFunc::dispatch(FuncRequest const & cmd) InsetCommandParams p(name); data = InsetCommandMailer::params2string(name, p); } else if (name == "include") { + // data is the include type: one of "include", + // "input", "verbatiminput" or "verbatiminput*" + if (data.empty()) + // default type is requested + data = "include"; InsetCommandParams p(data); data = InsetIncludeMailer::params2string(p); } else if (name == "box") { @@ -1346,17 +1399,17 @@ void LyXFunc::dispatch(FuncRequest const & cmd) case LFUN_BUFFER_CHILD_OPEN: { BOOST_ASSERT(lyx_view_); - string const filename = + FileName const filename = makeAbsPath(argument, lyx_view_->buffer()->filePath()); // FIXME Should use bformat setMessage(_("Opening child document ") + - makeDisplayPath(filename) + "..."); + makeDisplayPath(filename.absFilename()) + "..."); view()->saveBookmark(false); string const parentfilename = lyx_view_->buffer()->fileName(); - if (theBufferList().exists(filename)) - lyx_view_->setBuffer(theBufferList().getBuffer(filename)); + if (theBufferList().exists(filename.absFilename())) + lyx_view_->setBuffer(theBufferList().getBuffer(filename.absFilename())); else - lyx_view_->loadLyXFile(FileName(filename)); + lyx_view_->loadLyXFile(filename); // Set the parent name of the child document. // This makes insertion of citations and references in the child work, // when the target is in the parent or another child document. @@ -1416,8 +1469,8 @@ void LyXFunc::dispatch(FuncRequest const & cmd) } case LFUN_PREFERENCES_SAVE: { - lyxrc.write(FileName(makeAbsPath("preferences", - package().user_support())), + lyxrc.write(makeAbsPath("preferences", + package().user_support()), false); break; } @@ -1427,8 +1480,9 @@ void LyXFunc::dispatch(FuncRequest const & cmd) // handle the screen font changes. lyxrc.set_font_norm_type(); theFontLoader().update(); - // All visible buffers will need resize - view()->resize(); + /// FIXME: only the current view will be updated. the Gui + /// class is able to furnish the list of views. + updateFlags = Update::Force; break; case LFUN_SET_COLOR: { @@ -1656,6 +1710,12 @@ void LyXFunc::dispatch(FuncRequest const & cmd) } actOnUpdatedPrefs(lyxrc_orig, lyxrc); + + /// We force the redraw in any case because there might be + /// some screen font changes. + /// FIXME: only the current view will be updated. the Gui + /// class is able to furnish the list of views. + updateFlags = Update::Force; break; } @@ -1666,28 +1726,19 @@ void LyXFunc::dispatch(FuncRequest const & cmd) case LFUN_WINDOW_CLOSE: BOOST_ASSERT(lyx_view_); BOOST_ASSERT(theApp()); + // update bookmark pit of the current buffer before window close + for (size_t i = 0; i < LyX::ref().session().bookmarks().size(); ++i) + gotoBookmark(i+1, false, false); + // ask the user for saving changes or cancel quit + if (!theBufferList().quitWriteAll()) + break; lyx_view_->close(); return; - case LFUN_BOOKMARK_GOTO: { - BOOST_ASSERT(lyx_view_); - unsigned int idx = convert(to_utf8(cmd.argument())); - BookmarksSection::Bookmark const bm = LyX::ref().session().bookmarks().bookmark(idx); - BOOST_ASSERT(!bm.filename.empty()); - string const file = bm.filename.absFilename(); - // if the file is not opened, open it. - if (!theBufferList().exists(file)) - dispatch(FuncRequest(LFUN_FILE_OPEN, file)); - // open may fail, so we need to test it again - if (theBufferList().exists(file)) { - // if the current buffer is not that one, switch to it. - if (lyx_view_->buffer()->fileName() != file) - dispatch(FuncRequest(LFUN_BUFFER_SWITCH, file)); - // BOOST_ASSERT(lyx_view_->buffer()->fileName() != file); - view()->moveToPosition(bm.par_id, bm.par_pos); - } + case LFUN_BOOKMARK_GOTO: + // go to bookmark, open unopened file and switch to buffer if necessary + gotoBookmark(convert(to_utf8(cmd.argument())), true, true); break; - } case LFUN_BOOKMARK_CLEAR: LyX::ref().session().bookmarks().clear(); @@ -1702,8 +1753,7 @@ void LyXFunc::dispatch(FuncRequest const & cmd) view()->cursor().dispatch(cmd); updateFlags = view()->cursor().result().update(); if (!view()->cursor().result().dispatched()) - if (view()->dispatch(cmd)) - updateFlags = Update::Force | Update::FitCursor; + updateFlags = view()->dispatch(cmd); break; } } @@ -1724,8 +1774,8 @@ void LyXFunc::dispatch(FuncRequest const & cmd) // if we executed a mutating lfun, mark the buffer as dirty if (flag.enabled() - && !lyxaction.funcHasFlag(cmd.action, LyXAction::NoBuffer) - && !lyxaction.funcHasFlag(cmd.action, LyXAction::ReadOnly)) + && !lyxaction.funcHasFlag(action, LyXAction::NoBuffer) + && !lyxaction.funcHasFlag(action, LyXAction::ReadOnly)) view()->buffer()->markDirty(); if (view()->cursor().inTexted()) { @@ -1758,27 +1808,27 @@ void LyXFunc::sendDispatchMessage(docstring const & msg, FuncRequest const & cmd if (!dispatch_msg.empty()) dispatch_msg += ' '; - string comname = lyxaction.getActionName(cmd.action); + docstring comname = from_utf8(lyxaction.getActionName(cmd.action)); bool argsadded = false; if (!cmd.argument().empty()) { if (cmd.action != LFUN_UNKNOWN_ACTION) { - comname += ' ' + to_utf8(cmd.argument()); + comname += ' ' + cmd.argument(); argsadded = true; } } - string const shortcuts = theTopLevelKeymap().printbindings(cmd); + docstring const shortcuts = theTopLevelKeymap().printbindings(cmd); if (!shortcuts.empty()) comname += ": " + shortcuts; else if (!argsadded && !cmd.argument().empty()) - comname += ' ' + to_utf8(cmd.argument()); + comname += ' ' + cmd.argument(); if (!comname.empty()) { comname = rtrim(comname); - dispatch_msg += from_utf8('(' + rtrim(comname) + ')'); + dispatch_msg += '(' + rtrim(comname) + ')'; } lyxerr[Debug::ACTION] << "verbose dispatch msg " @@ -1797,7 +1847,7 @@ void LyXFunc::menuNew(string const & name, bool fromTemplate) if (view()->buffer()) { string const trypath = lyx_view_->buffer()->filePath(); // If directory is writeable, use this as default. - if (isDirWriteable(trypath)) + if (isDirWriteable(FileName(trypath))) initpath = trypath; } @@ -1848,7 +1898,7 @@ void LyXFunc::open(string const & fname) if (view()->buffer()) { string const trypath = lyx_view_->buffer()->filePath(); // If directory is writeable, use this as default. - if (isDirWriteable(trypath)) + if (isDirWriteable(FileName(trypath))) initpath = trypath; } @@ -1921,7 +1971,7 @@ void LyXFunc::doImport(string const & argument) if (view()->buffer()) { string const trypath = lyx_view_->buffer()->filePath(); // If directory is writeable, use this as default. - if (isDirWriteable(trypath)) + if (isDirWriteable(FileName(trypath))) initpath = trypath; } @@ -1998,6 +2048,9 @@ void LyXFunc::closeBuffer() // save current cursor position LyX::ref().session().lastFilePos().save(FileName(lyx_view_->buffer()->fileName()), boost::tie(view()->cursor().pit(), view()->cursor().pos()) ); + // goto bookmark to update bookmark pit. + for (size_t i = 0; i < LyX::ref().session().bookmarks().size(); ++i) + gotoBookmark(i+1, false, false); if (theBufferList().close(lyx_view_->buffer(), true) && !quitting) { if (theBufferList().empty()) { // need this otherwise SEGV may occur while @@ -2011,6 +2064,13 @@ void LyXFunc::closeBuffer() } +void LyXFunc::reloadBuffer() +{ + FileName filename(lyx_view_->buffer()->fileName()); + closeBuffer(); + lyx_view_->loadLyXFile(filename); +} + // Each "lyx_view_" should have it's own message method. lyxview and // the minibuffer would use the minibuffer, but lyxserver would // send an ERROR signal to its client. Alejandro 970603 @@ -2030,19 +2090,19 @@ void LyXFunc::setMessage(docstring const & m) const } -string const LyXFunc::viewStatusMessage() +docstring const LyXFunc::viewStatusMessage() { // When meta-fake key is pressed, show the key sequence so far + "M-". if (wasMetaKey()) - return keyseq->print() + "M-"; + return keyseq->print(true) + "M-"; // Else, when a non-complete key sequence is pressed, // show the available options. if (keyseq->length() > 0 && !keyseq->deleted()) - return keyseq->printOptions(); + return keyseq->printOptions(true); if (!view()->buffer()) - return to_utf8(_("Welcome to LyX!")); + return _("Welcome to LyX!"); return view()->cursor().currentState(); } @@ -2074,8 +2134,8 @@ void actOnUpdatedPrefs(LyXRC const & lyxrc_orig, LyXRC const & lyxrc_new) switch (tag) { case LyXRC::RC_ACCEPT_COMPOUND: case LyXRC::RC_ALT_LANG: - case LyXRC::RC_ASCIIROFF_COMMAND: - case LyXRC::RC_ASCII_LINELEN: + case LyXRC::RC_PLAINTEXT_ROFF_COMMAND: + case LyXRC::RC_PLAINTEXT_LINELEN: case LyXRC::RC_AUTOREGIONDELETE: case LyXRC::RC_AUTORESET_OPTIONS: case LyXRC::RC_AUTOSAVE: