7 #include FORMS_H_LOCATION
10 #include "lyx_gui_misc.h"
11 #include "bufferlist.h"
12 #include "support/syscall.h"
13 #include "support/path.h"
14 #include "support/filetools.h"
15 #include "support/FileInfo.h"
19 #include "latexoptions.h"
21 extern BufferList bufferlist;
22 extern void MenuWrite(Buffer *);
25 extern bool gsworking();
30 backend = UNKNOWN_VCS;
39 if (browser->LaTeXLog->visible)
40 fl_hide_form(browser->LaTeXLog);
41 fl_free_form(browser->LaTeXLog);
46 bool LyXVC::file_found_hook(string const & fn)
50 // Check if *,v exists.
52 lyxerr[Debug::LYXVC] << "Checking if file is under vc: "
54 if (f.newFile(tmp).readable()) {
55 lyxerr[Debug::LYXVC] << "Yes it is under vc." << endl;
61 // Check if RCS/*,v exists.
62 tmp = AddName(AddPath(OnlyPath(fn), "RCS"), fn);
64 lyxerr[Debug::LYXVC] << "Checking if file is under vc: "
66 if (f.newFile(tmp).readable()) {
67 lyxerr[Debug::LYXVC] << "Yes it is under vc."<< endl;
74 // If either one, return true
76 // file is not under any VCS.
81 bool LyXVC::file_not_found_hook(string const &)
83 // file is not under any VCS.
88 void LyXVC::scanMaster()
90 lyxerr[Debug::LYXVC] << "LyXVC: This file is a VC file." << endl;
96 bool read_enough = false;
97 while (lex.IsOK() && !read_enough) {
99 token = lex.GetString();
101 lyxerr[Debug::LYXVC] <<"LyXVC::scanMaster: current lex text: `"
102 << token << "'" << endl;
106 else if (token == "head") {
109 string tmv = strip(lex.GetString(), ';');
111 } else if (contains(token, "access")
112 || contains(token, "symbols")
113 || contains(token, "strict")) {
115 } else if (contains(token, "locks")) {
117 if (contains(token, ";")) {
125 s1 = strip(tmpt = lex.GetString(), ';');
126 // tmp is now in the format <user>:<version>
127 s1 = split(s1, s2, ':');
128 // s2 is user, and s1 is version
134 } while (!contains(tmpt, ";"));
136 } else if (token == "comment") {
137 // we don't need to read any further than this.
142 << "LyXVC::scanMaster(): unexpected token"
149 void LyXVC::setBuffer(Buffer *buf)
156 // I will probably add some backend_xxxx functions later to perform the
157 // version control system specific commands. Something like:
158 // void backend_revert(<params>) {
159 // if (backend == "RCS") {
160 // } else if (backend == "CVS") {
161 // } else if (backend == "SCCS") {
164 // But for 0.12 we will only support RCS.
167 void LyXVC::registrer()
169 // If the document is changed, we might want to save it
170 if (!_owner->isLyxClean() &&
171 AskQuestion(_("Changes in document:"),
172 MakeDisplayPath(_owner->getFileName(),50),
173 _("Save document and proceed?"))) {
177 // Maybe the save fails, or we answered "no". In both cases,
178 // the document will be dirty, and we abort.
179 if (!_owner->isLyxClean()) {
183 lyxerr[Debug::LYXVC] << "LyXVC: registrer" << endl;
184 string tmp = askForText(_("LyX VC: Initial description"),
185 _("(no initial description)"));
187 lyxerr[Debug::LYXVC] << "LyXVC: user cancelled" << endl;
188 WriteAlert(_("Info"), _("This document has NOT been registered."));
191 string cmd = "ci -q -u -i -t-\"";
194 cmd += OnlyFilename(_owner->getFileName());
197 _owner->getUser()->getOwner()->getLyXFunc()->Dispatch("buffer-reload");
201 void LyXVC::checkIn()
203 // If the document is changed, we might want to save it
204 if (!_owner->isLyxClean() &&
205 AskQuestion(_("Changes in document:"),
206 MakeDisplayPath(_owner->getFileName(),50),
207 _("Save document and proceed?"))) {
211 // Maybe the save fails, or we answered "no". In both cases,
212 // the document will be dirty, and we abort.
213 if (!_owner->isLyxClean()) {
217 lyxerr[Debug::LYXVC] << "LyXVC: checkIn" << endl;
218 _owner->getUser()->getOwner()->getLyXFunc()->Dispatch(LFUN_MENUWRITE);
219 string tmp = askForText(_("LyX VC: Log Message"));
220 if (tmp.empty()) tmp = "(no log msg)";
221 doVCCommand("ci -q -u -m\"" + tmp + "\" \""
222 + OnlyFilename(_owner->getFileName()) + "\"");
223 _owner->getUser()->getOwner()->getLyXFunc()->Dispatch("buffer-reload");
227 void LyXVC::checkOut()
229 lyxerr[Debug::LYXVC] << "LyXVC: checkOut" << endl;
230 if (!_owner->isLyxClean()
231 && !AskQuestion(_("Changes in document:"),
232 MakeDisplayPath(_owner->getFileName(),50),
233 _("Ignore changes and proceed with check out?"))) {
237 _owner->markLyxClean();
238 doVCCommand("co -q -l \""
239 + OnlyFilename(_owner->getFileName()) + "\"");
240 _owner->getUser()->getOwner()->getLyXFunc()->Dispatch("buffer-reload");
246 lyxerr[Debug::LYXVC] << "LyXVC: revert" << endl;
247 // Here we should check if the buffer is dirty. And if it is
248 // we should warn the user that reverting will discard all
249 // changes made since the last check in.
250 if (AskQuestion(_("When you revert, you will loose all changes made"),
251 _("to the document since the last check in."),
252 _("Do you still want to do it?"))) {
254 doVCCommand("co -f -u" + getVersion() + " \""
255 + OnlyFilename(_owner->getFileName()) + "\"");
256 // We ignore changes and just reload!
257 _owner->markLyxClean();
258 _owner->getUser()->getOwner()->
259 getLyXFunc()->Dispatch("buffer-reload");
264 void LyXVC::undoLast()
266 lyxerr[Debug::LYXVC] << "LyXVC: undoLast" << endl;
267 doVCCommand("rcs -o" + getVersion() + " \""
268 + OnlyFilename(_owner->getFileName()) + "\"");
272 void LyXVC::toggleReadOnly()
293 string const LyXVC::getVersion() const
299 string const LyXVC::getLocker() const
304 // This is a hack anyway so I'll put it here in the mean time.
305 void LyXVC::logClose(FL_OBJECT *obj, long)
307 LyXVC *This = (LyXVC*)obj->form->u_vdata;
308 fl_hide_form(This->browser->LaTeXLog);
311 // and, hack over hack, here is a C wrapper :)
312 extern "C" void C_LyXVC_logClose(FL_OBJECT *ob, long data)
314 LyXVC::logClose(ob, data);
318 void LyXVC::logUpdate(FL_OBJECT *obj, long)
320 LyXVC *This = (LyXVC*)obj->form->u_vdata;
324 extern "C" void C_LyXVC_logUpdate(FL_OBJECT *ob, long data)
326 LyXVC::logUpdate(ob, data);
330 void LyXVC::viewLog(string const & fil)
332 static int ow = -1, oh;
336 browser = (FD_LaTeXLog *) fl_calloc(1, sizeof(*browser));
338 browser->LaTeXLog = fl_bgn_form(FL_NO_BOX, 470, 380);
339 browser->LaTeXLog->u_vdata = (void*)this;
340 obj = fl_add_box(FL_UP_BOX, 0, 0, 470, 380, "");
341 browser->browser_latexlog = fl_add_browser(FL_NORMAL_BROWSER, 10, 10, 450, 320, "");
342 obj = fl_add_button(FL_RETURN_BUTTON, 270, 340, 90, 30, _("Close"));
343 fl_set_object_lsize(obj, FL_NORMAL_SIZE);
344 fl_set_object_callback(obj, C_LyXVC_logClose, 0);
345 obj = fl_add_button(FL_NORMAL_BUTTON,370,340,90,30,
346 idex(_("Update|#Uu")));
347 fl_set_button_shortcut(obj,scex(_("Update|#Uu")),1);
348 fl_set_object_lsize(obj,FL_NORMAL_SIZE);
349 fl_set_object_callback(obj, C_LyXVC_logUpdate,0);
351 fl_set_form_atclose(browser->LaTeXLog, CancelCloseBoxCB, 0);
354 if (!fl_load_browser(browser->browser_latexlog, fil.c_str()))
355 fl_add_browser_line(browser->browser_latexlog, _("No RCS History!"));
357 if (browser->LaTeXLog->visible) {
358 fl_raise_form(browser->LaTeXLog);
360 fl_show_form(browser->LaTeXLog,
361 FL_PLACE_MOUSE | FL_FREE_SIZE, FL_FULLBORDER,
364 ow = browser->LaTeXLog->w;
365 oh = browser->LaTeXLog->h;
367 fl_set_form_minsize(browser->LaTeXLog, ow, oh);
372 void LyXVC::showLog()
374 // This I really don't like, but we'll look at this problem
375 // in 0.13. Then we can make a clean solution.
378 WriteAlert(_("Sorry, can't do this while"
379 " pictures are being rendered."),
380 _("Please wait a few seconds for"
381 " this to finish and try again."),
382 _("(or kill runaway gs processes"
383 " by hand and try again.)"));
386 extern pid_t isp_pid; // from spellchecker.C
388 WriteAlert(_("Can't do this while the"
389 " spellchecker is running."),
390 _("Stop the spellchecker first."));
394 string tmpf = tmpnam(0);
395 doVCCommand("rlog \""
396 + OnlyFilename(_owner->getFileName()) + "\" > " + tmpf);
398 unlink(tmpf.c_str());
402 int LyXVC::doVCCommand(string const & cmd)
404 lyxerr[Debug::LYXVC] << "doVCCommand: " << cmd << endl;
406 Path p(_owner->filepath);
407 int ret = one.startscript(Systemcalls::System, cmd);