X-Git-Url: https://git.lyx.org/gitweb/?a=blobdiff_plain;f=src%2Flyxvc.C;h=3e09e77d346b5bfffffb89b72d1d2d5a636558dd;hb=c1e009f2d3baa65a05345224ae14f1fe521b8199;hp=f1430b693c6ec9f60255a39f0000a1d8b6384ea2;hpb=35584afc1162dec2cf9fff79305e95cb3b75aefb;p=lyx.git diff --git a/src/lyxvc.C b/src/lyxvc.C index f1430b693c..3e09e77d34 100644 --- a/src/lyxvc.C +++ b/src/lyxvc.C @@ -1,281 +1,218 @@ #include -#ifdef __GNUG__ -#pragma implementation -#endif - -#include FORMS_H_LOCATION #include "lyxvc.h" +#include "vc-backend.h" #include "debug.h" -#include "lyx_gui_misc.h" -#include "bufferlist.h" -#include "support/syscall.h" -#include "pathstack.h" -#include "support/filetools.h" -#include "support/FileInfo.h" +#include "buffer.h" +#include "BufferView.h" #include "gettext.h" -#include "LyXView.h" -#include "lyxfunc.h" -#include "latexoptions.h" +#include "funcrequest.h" + +#include "frontends/Alert.h" +#include "frontends/LyXView.h" + +#include "support/filetools.h" +#include "support/lyxlib.h" -extern BufferList bufferlist; -extern void MenuWrite(Buffer *); +#include -#if 0 -extern bool gsworking(); -#endif +using std::endl; +using std::pair; + + +/* WARNING: Several of the vcs-> methods end up + * deleting this object via BufferView::reload() ! + */ LyXVC::LyXVC() { - backend = UNKNOWN_VCS; - _owner = 0; - browser = 0; + vcs = 0; + owner_ = 0; } LyXVC::~LyXVC() { - if (browser) { - if (browser->LaTeXLog->visible) - fl_hide_form(browser->LaTeXLog); - fl_free_form(browser->LaTeXLog); - } + delete vcs; } bool LyXVC::file_found_hook(string const & fn) { - string tmp(fn); - FileInfo f; - // Check if *,v exists. - tmp += ",v"; - lyxerr[Debug::LYXVC] << "Checking if file is under vc: " - << tmp << endl; - if (f.newFile(tmp).readable()) { - lyxerr[Debug::LYXVC] << "Yes it is under vc." << endl; - master = tmp; - backend = RCS_VCS; - scanMaster(); + string found_file; + // Check if file is under RCS + if (!(found_file = RCS::find_file(fn)).empty()) { + vcs = new RCS(found_file); + vcs->owner(owner_); + return true; + } + // Check if file is under CVS + if (!(found_file = CVS::find_file(fn)).empty()) { + vcs = new CVS(found_file, fn); + vcs->owner(owner_); return true; - } else { - // Check if RCS/*,v exists. - tmp = AddName(AddPath(OnlyPath(fn), "RCS"), fn); - tmp += ",v"; - lyxerr[Debug::LYXVC] << "Checking if file is under vc: " - << tmp << endl; - if (f.newFile(tmp).readable()) { - lyxerr[Debug::LYXVC] << "Yes it is under vc."<< endl; - master = tmp; - backend = RCS_VCS; - scanMaster(); - return true; - } } - // If either one, return true - // file is not under any VCS. return false; } -bool LyXVC::file_not_found_hook(string const &) +bool LyXVC::file_not_found_hook(string const & fn) { - // file is not under any VCS. + // Check if file is under RCS + if (!RCS::find_file(fn).empty()) + return true; + if (!CVS::find_file(fn).empty()) + return true; return false; } -void LyXVC::scanMaster() +void LyXVC::buffer(Buffer * buf) { - lyxerr[Debug::LYXVC] << "LyXVC: This file is a VC file." << endl; - - LyXLex lex(0, 0); - lex.setFile(master); - - string token; - bool read_enough = false; - while (lex.IsOK() && !read_enough) { - lex.next(); - token = lex.GetString(); - - lyxerr[Debug::LYXVC] <<"LyXVC::scanMaster: current lex text: `" - << token << "'" << endl; - - if (token.empty()) - continue; - else if (token == "head") { - // get version here - lex.next(); - string tmv = strip(lex.GetString(), ';'); - version = tmv; - } else if (contains(token, "access") - || contains(token, "symbols") - || contains(token, "strict")) { - // nothing - } else if (contains(token, "locks")) { - // get locker here - if (contains(token, ";")) { - locker = "Unlocked"; - vcstat = UNLOCKED; - continue; - } - string tmpt, s1, s2; - do { - lex.next(); - s1 = strip(tmpt = lex.GetString(), ';'); - // tmp is now in the format : - s1 = split(s1, s2, ':'); - // s2 is user, and s1 is version - if (s1 == version) { - locker = s2; - vcstat = LOCKED; - break; - } - } while (!contains(tmpt, ";")); - - } else if (token == "comment") { - // we don't need to read any further than this. - read_enough = true; - } else { - // unexpected - lyxerr[Debug::LYXVC] - << "LyXVC::scanMaster(): unexpected token" - << endl; - } - } + owner_ = buf; } -void LyXVC::setBuffer(Buffer *buf) +bool LyXVC::ensureClean() { - _owner = buf; -} + if (owner_->isClean()) + return true; + string const file = MakeDisplayPath(owner_->fileName(), 30); + string text = bformat(_("The document %1$s has unsaved changes.\n\n" + "Do you want to save the document?"), file); + int const ret = Alert::prompt(_("Save changed document?"), + text, 0, 1, _("&Save"), _("&Cancel")); + + if (ret == 0) { + vcs->owner()->getUser()->owner()->dispatch(FuncRequest(LFUN_MENUWRITE)); + } + + return owner_->isClean(); +} -// -// I will probably add some backend_xxxx functions later to perform the -// version control system specific commands. Something like: -// void backend_revert() { -// if (backend == "RCS") { -// } else if (backend == "CVS") { -// } else if (backend == "SCCS") { -// } -// -// But for 0.12 we will only support RCS. -// void LyXVC::registrer() { - // If the document is changed, we might want to save it - if (!_owner->isLyxClean() && - AskQuestion(_("Changes in document:"), - MakeDisplayPath(_owner->getFileName(),50), - _("Save document and proceed?"))) { - MenuWrite(_owner); + string const filename = owner_->fileName(); + + // there must be a file to save + if (!IsFileReadable(filename)) { + Alert::error(_("Document not saved"), + _("You must save the document " + "before it can be registered.")); + return; + } + + // it is very likely here that the vcs is not created yet... + if (!vcs) { + string const cvs_entries = "CVS/Entries"; + + if (IsFileReadable(cvs_entries)) { + lyxerr[Debug::LYXVC] + << "LyXVC: registering " + << MakeDisplayPath(filename) + << " with CVS" << endl; + vcs = new CVS(cvs_entries, filename); + + } else { + lyxerr[Debug::LYXVC] + << "LyXVC: registering " + << MakeDisplayPath(filename) + << " with RCS" << endl; + vcs = new RCS(filename); + } + + vcs->owner(owner_); } // Maybe the save fails, or we answered "no". In both cases, // the document will be dirty, and we abort. - if (!_owner->isLyxClean()) { + if (!ensureClean()) return; - } lyxerr[Debug::LYXVC] << "LyXVC: registrer" << endl; - string tmp = askForText(_("LyX VC: Initial description"), - _("(no initial description)")); - if (tmp.empty()) { + pair tmp = + Alert::askForText(_("LyX VC: Initial description"), + _("(no initial description)")); + if (!tmp.first || tmp.second.empty()) { + // should we insist on checking tmp.second.empty()? lyxerr[Debug::LYXVC] << "LyXVC: user cancelled" << endl; - WriteAlert(_("Info"), _("This document has NOT been registered.")); return; } - string cmd = "ci -q -u -i -t-\""; - cmd += tmp; - cmd += "\" \""; - cmd += OnlyFilename(_owner->getFileName()); - cmd += "\""; - doVCCommand(cmd); - _owner->getUser()->getOwner()->getLyXFunc()->Dispatch("buffer-reload"); + + vcs->registrer(tmp.second); } void LyXVC::checkIn() { // If the document is changed, we might want to save it - if (!_owner->isLyxClean() && - AskQuestion(_("Changes in document:"), - MakeDisplayPath(_owner->getFileName(),50), - _("Save document and proceed?"))) { - MenuWrite(_owner); + if (!vcs->owner()->isClean()) { + vcs->owner()->getUser()->owner() + ->dispatch(FuncRequest(LFUN_MENUWRITE)); } // Maybe the save fails, or we answered "no". In both cases, // the document will be dirty, and we abort. - if (!_owner->isLyxClean()) { + if (!vcs->owner()->isClean()) return; - } lyxerr[Debug::LYXVC] << "LyXVC: checkIn" << endl; - _owner->getUser()->getOwner()->getLyXFunc()->Dispatch(LFUN_MENUWRITE); - string tmp = askForText(_("LyX VC: Log Message")); - if (tmp.empty()) tmp = "(no log msg)"; - doVCCommand("ci -q -u -m\"" + tmp + "\" \"" - + OnlyFilename(_owner->getFileName()) + "\""); - _owner->getUser()->getOwner()->getLyXFunc()->Dispatch("buffer-reload"); + pair tmp = Alert::askForText(_("LyX VC: Log Message")); + if (tmp.first) { + if (tmp.second.empty()) { + tmp.second = _("(no log message)"); + } + vcs->checkIn(tmp.second); + } else { + lyxerr[Debug::LYXVC] << "LyXVC: user cancelled" << endl; + } } void LyXVC::checkOut() { lyxerr[Debug::LYXVC] << "LyXVC: checkOut" << endl; - if (!_owner->isLyxClean() - && !AskQuestion(_("Changes in document:"), - MakeDisplayPath(_owner->getFileName(),50), - _("Ignore changes and proceed with check out?"))) { + if (!ensureClean()) return; - } - _owner->markLyxClean(); - doVCCommand("co -q -l \"" - + OnlyFilename(_owner->getFileName()) + "\""); - _owner->getUser()->getOwner()->getLyXFunc()->Dispatch("buffer-reload"); + vcs->checkOut(); } void LyXVC::revert() { lyxerr[Debug::LYXVC] << "LyXVC: revert" << endl; - // Here we should check if the buffer is dirty. And if it is - // we should warn the user that reverting will discard all - // changes made since the last check in. - if (AskQuestion(_("When you revert, you will loose all changes made"), - _("to the document since the last check in."), - _("Do you still want to do it?"))) { - - doVCCommand("co -f -u" + getVersion() + " \"" - + OnlyFilename(_owner->getFileName()) + "\""); - // We ignore changes and just reload! - _owner->markLyxClean(); - _owner->getUser()->getOwner()-> - getLyXFunc()->Dispatch("buffer-reload"); - } + + string const file = MakeDisplayPath(owner_->fileName(), 20); + string text = bformat(_("Reverting to the stored version of the " + "document %1$s will lose all current changes.\n\n" + "Do you want to revert to the saved version?"), file); + int const ret = Alert::prompt(_("Revert to stored version of document?"), + text, 0, 1, _("&Revert"), _("&Cancel")); + + if (ret == 0) + vcs->revert(); } void LyXVC::undoLast() { - lyxerr[Debug::LYXVC] << "LyXVC: undoLast" << endl; - doVCCommand("rcs -o" + getVersion() + " \"" - + OnlyFilename(_owner->getFileName()) + "\""); + vcs->undoLast(); } void LyXVC::toggleReadOnly() { - switch (vcstat) { - case UNLOCKED: + switch (vcs->status()) { + case VCS::UNLOCKED: + lyxerr[Debug::LYXVC] << "LyXVC: toggle to locked" << endl; checkOut(); break; - case LOCKED: + case VCS::LOCKED: + lyxerr[Debug::LYXVC] << "LyXVC: toggle to unlocked" << endl; checkIn(); break; } @@ -284,109 +221,35 @@ void LyXVC::toggleReadOnly() bool LyXVC::inUse() { - if (!master.empty()) - return true; + if (vcs) return true; return false; } -string const LyXVC::getVersion() const -{ - return version; -} - - -string const LyXVC::getLocker() const -{ - return locker; -} +//string const & LyXVC::version() const +//{ +// return vcs->version(); +//} -// This is a hack anyway so I'll put it here in the mean time. -void LyXVC::logClose(FL_OBJECT *obj, long) +string const LyXVC::versionString() const { - LyXVC *This = (LyXVC*)obj->form->u_vdata; - fl_hide_form(This->browser->LaTeXLog); + return vcs->versionString(); } -void LyXVC::logUpdate(FL_OBJECT *obj, long) +string const & LyXVC::locker() const { - LyXVC *This = (LyXVC*)obj->form->u_vdata; - This->showLog(); + return vcs->locker(); } -void LyXVC::viewLog(string const & fil) +const string LyXVC::getLogFile() const { - if (!browser) { - FL_OBJECT *obj; - browser = (FD_LaTeXLog *) fl_calloc(1, sizeof(*browser)); - - browser->LaTeXLog = fl_bgn_form(FL_NO_BOX, 470, 380); - browser->LaTeXLog->u_vdata = (void*)this; - obj = fl_add_box(FL_UP_BOX, 0, 0, 470, 380, ""); - browser->browser_latexlog = fl_add_browser(FL_NORMAL_BROWSER, 10, 10, 450, 320, ""); - obj = fl_add_button(FL_RETURN_BUTTON, 270, 340, 90, 30, _("Close")); - fl_set_object_lsize(obj, FL_NORMAL_SIZE); - fl_set_object_callback(obj, logClose, 0); - obj = fl_add_button(FL_NORMAL_BUTTON,370,340,90,30, - idex(_("Update|#Uu"))); - fl_set_button_shortcut(obj,scex(_("Update|#Uu")),1); - fl_set_object_lsize(obj,FL_NORMAL_SIZE); - fl_set_object_callback(obj,logUpdate,0); - fl_end_form(); - fl_set_form_atclose(browser->LaTeXLog, CancelCloseBoxCB, 0); - } - - if (!fl_load_browser(browser->browser_latexlog, fil.c_str())) - fl_add_browser_line(browser->browser_latexlog, _("No RCS History!")); - - if (browser->LaTeXLog->visible) { - fl_raise_form(browser->LaTeXLog); - } else { - fl_show_form(browser->LaTeXLog, - FL_PLACE_MOUSE | FL_FREE_SIZE, FL_FULLBORDER, - _("RCS History")); - } -} + if (!vcs) + return string(); - -void LyXVC::showLog() -{ - // This I really don't like, but we'll look at this problem - // in 0.13. Then we can make a clean solution. -#if 0 - if (gsworking()) { - WriteAlert(_("Sorry, can't do this while" - " pictures are being rendered."), - _("Please wait a few seconds for" - " this to finish and try again."), - _("(or kill runaway gs processes" - " by hand and try again.)")); - return; - } - extern pid_t isp_pid; // from spellchecker.C - if(isp_pid != -1) { - WriteAlert(_("Can't do this while the" - " spellchecker is running."), - _("Stop the spellchecker first.")); - return; - } -#endif - string tmpf = tmpnam(0); - doVCCommand("rlog \"" - + OnlyFilename(_owner->getFileName()) + "\" > " + tmpf); - viewLog(tmpf); - unlink(tmpf.c_str()); -} - - -int LyXVC::doVCCommand(string const & cmd) -{ - lyxerr[Debug::LYXVC] << "doVCCommand: " << cmd << endl; - Systemcalls one; - PathPush(_owner->filepath); - int ret = one.Startscript(Systemcalls::System, cmd); - PathPop(); - return ret; + string tmpf = lyx::tempName(string(), "lyxvclog"); + lyxerr[Debug::LYXVC] << "Generating logfile " << tmpf << endl; + vcs->getLog(tmpf); + return tmpf; }