]> git.lyx.org Git - lyx.git/blob - src/LyXVC.cpp
Remove question marks from Windows dialogs
[lyx.git] / src / LyXVC.cpp
1 /**
2  * \file LyXVC.cpp
3  * This file is part of LyX, the document processor.
4  * Licence details can be found in the file COPYING.
5  *
6  * \author Lars Gullik Bjønnes
7  * \author Jean-Marc Lasgouttes
8  * \author Angus Leeming
9  * \author John Levon
10  * \author André Pönitz
11  * \author Allan Rae
12  *
13  * Full author contact details are available in file CREDITS.
14  */
15
16 #include <config.h>
17
18 #include "LyXVC.h"
19 #include "VCBackend.h"
20 #include "Buffer.h"
21
22 #include "frontends/alert.h"
23
24 #include "support/debug.h"
25 #include "support/filetools.h"
26 #include "support/gettext.h"
27 #include "support/lstrings.h"
28 #include "support/TempFile.h"
29
30 using namespace std;
31 using namespace lyx::support;
32
33 namespace lyx {
34
35 namespace Alert = frontend::Alert;
36
37
38 LyXVC::LyXVC()
39 {
40         owner_ = 0;
41 }
42
43
44 string LyXVC::vcname() const
45 {
46         return vcs->vcname();
47 }
48
49
50 bool LyXVC::fileInVC(FileName const & fn)
51 {
52         if (!RCS::findFile(fn).empty())
53                 return true;
54         if (!CVS::findFile(fn).empty())
55                 return true;
56         if (!SVN::findFile(fn).empty())
57                 return true;
58         if (!GIT::findFile(fn).empty())
59                 return true;
60         return false;
61 }
62
63
64 bool LyXVC::file_found_hook(FileName const & fn)
65 {
66         FileName found_file;
67         // Check if file is under RCS
68         if (!(found_file = RCS::findFile(fn)).empty()) {
69                 vcs.reset(new RCS(found_file, owner_));
70                 return true;
71         }
72         // Check if file is under CVS
73         if (!(found_file = CVS::findFile(fn)).empty()) {
74                 vcs.reset(new CVS(found_file, owner_));
75                 return true;
76         }
77         // Check if file is under SVN
78         if (!(found_file = SVN::findFile(fn)).empty()) {
79                 vcs.reset(new SVN(found_file, owner_));
80                 return true;
81         }
82         // Check if file is under GIT
83         if (!(found_file = GIT::findFile(fn)).empty()) {
84                 vcs.reset(new GIT(found_file, owner_));
85                 return true;
86         }
87
88         // file is not under any VCS.
89         vcs.reset(0);
90         return false;
91 }
92
93
94 bool LyXVC::file_not_found_hook(FileName const & fn)
95 {
96         // Check if file is under RCS.
97         // This happens if we are trying to load non existent
98         // file on disk, but existent in ,v version.
99         bool foundRCS = !RCS::findFile(fn).empty();
100         bool foundCVS = foundRCS ? false : !CVS::findFile(fn).empty();
101         bool foundSVN = (foundRCS || foundCVS) ? false : !SVN::findFile(fn).empty();
102         bool foundGIT = (foundRCS || foundCVS || foundSVN) ? false : !GIT::findFile(fn).empty();
103         if (foundRCS || foundCVS || foundSVN || foundGIT) {
104                 docstring const file = makeDisplayPath(fn.absFileName(), 20);
105                 docstring const text =
106                         bformat(_("Do you want to retrieve the document"
107                                                    " %1$s from version control?"), file);
108                 int const ret = Alert::prompt(_("Retrieve from version control?"),
109                         text, 0, 1, _("&Retrieve"), _("&Cancel"));
110
111                 if (ret == 0) {
112                         // Since the retrieve commands are implemented using
113                         // more general update commands we need to ensure that
114                         // we do not change an existing file by accident.
115                         if (fn.exists())
116                                 return false;
117                         if (foundRCS)
118                                 return RCS::retrieve(fn);
119                         else if (foundCVS)
120                                 return CVS::retrieve(fn);
121                         else if (foundSVN)
122                                 return SVN::retrieve(fn);
123                         else
124                                 return GIT::retrieve(fn);
125                 }
126         }
127         return false;
128 }
129
130
131 void LyXVC::setBuffer(Buffer * buf)
132 {
133         owner_ = buf;
134 }
135
136
137 bool LyXVC::registrer()
138 {
139         FileName const filename = owner_->fileName();
140
141         // there must be a file to save
142         if (!filename.isReadableFile()) {
143                 Alert::error(_("Document not saved"),
144                              _("You must save the document "
145                                             "before it can be registered."));
146                 return false;
147         }
148
149         // it is very likely here that the vcs is not created yet...
150         if (!vcs) {
151                 //check in the root directory of the document
152                 FileName const cvs_entries(onlyPath(filename.absFileName()) + "/CVS/Entries");
153                 FileName const svn_entries(onlyPath(filename.absFileName()) + "/.svn/entries");
154                 FileName const git_index(onlyPath(filename.absFileName()) + "/.git/index");
155
156                 if (git_index.isReadableFile()) {
157                         LYXERR(Debug::LYXVC, "LyXVC: registering "
158                                 << to_utf8(filename.displayName()) << " with GIT");
159                         vcs.reset(new GIT(git_index, owner_));
160
161                 } else if (svn_entries.isReadableFile()) {
162                         LYXERR(Debug::LYXVC, "LyXVC: registering "
163                                 << to_utf8(filename.displayName()) << " with SVN");
164                         vcs.reset(new SVN(svn_entries, owner_));
165
166                 } else if (cvs_entries.isReadableFile()) {
167                         LYXERR(Debug::LYXVC, "LyXVC: registering "
168                                 << to_utf8(filename.displayName()) << " with CVS");
169                         vcs.reset(new CVS(cvs_entries, owner_));
170
171                 } else {
172                         LYXERR(Debug::LYXVC, "LyXVC: registering "
173                                 << to_utf8(filename.displayName()) << " with RCS");
174                         vcs.reset(new RCS(FileName(), owner_));
175                 }
176         }
177
178         LYXERR(Debug::LYXVC, "LyXVC: registrer");
179         docstring response;
180         bool ok = Alert::askForText(response, _("LyX VC: Initial description"),
181                         _("(no initial description)"));
182         if (!ok) {
183                 LYXERR(Debug::LYXVC, "LyXVC: user cancelled");
184                 vcs.reset(0);
185                 return false;
186         }
187         if (response.empty())
188                 response = _("(no initial description)");
189         vcs->registrer(to_utf8(response));
190         return true;
191 }
192
193
194 string LyXVC::rename(FileName const & fn)
195 {
196         LYXERR(Debug::LYXVC, "LyXVC: rename");
197         if (!vcs || fileInVC(fn))
198                 return string();
199         docstring response;
200         bool ok = Alert::askForText(response, _("LyX VC: Log message"),
201                         _("(no log message)"));
202         if (!ok) {
203                 LYXERR(Debug::LYXVC, "LyXVC: user cancelled");
204                 return string();
205         }
206         if (response.empty())
207                 response = _("(no log message)");
208         string ret = vcs->rename(fn, to_utf8(response));
209         return ret;
210 }
211
212
213 string LyXVC::copy(FileName const & fn)
214 {
215         LYXERR(Debug::LYXVC, "LyXVC: copy");
216         if (!vcs || fileInVC(fn))
217                 return string();
218         docstring response;
219         bool ok = Alert::askForText(response, _("LyX VC: Log message"),
220                         _("(no log message)"));
221         if (!ok) {
222                 LYXERR(Debug::LYXVC, "LyXVC: user cancelled");
223                 return string();
224         }
225         if (response.empty())
226                 response = _("(no log message)");
227         string ret = vcs->copy(fn, to_utf8(response));
228         return ret;
229 }
230
231
232 LyXVC::CommandResult LyXVC::checkIn(string & log)
233 {
234         LYXERR(Debug::LYXVC, "LyXVC: checkIn");
235         if (!vcs)
236                 return ErrorBefore;
237         docstring empty(_("(no log message)"));
238         docstring response;
239         bool ok = true;
240         if (vcs->isCheckInWithConfirmation())
241                 ok = Alert::askForText(response, _("LyX VC: Log Message"));
242         if (ok) {
243                 if (response.empty())
244                         response = empty;
245                 //shell collisions
246                 response = subst(response, from_ascii("\""), from_ascii("\\\""));
247                 return vcs->checkIn(to_utf8(response), log);
248         } else {
249                 LYXERR(Debug::LYXVC, "LyXVC: user cancelled");
250                 return Cancelled;
251         }
252 }
253
254
255 string LyXVC::checkOut()
256 {
257         if (!vcs)
258                 return string();
259         //RCS allows checkOut only in ReadOnly mode
260         if (vcs->toggleReadOnlyEnabled() && !owner_->isReadonly())
261                 return string();
262
263         LYXERR(Debug::LYXVC, "LyXVC: checkOut");
264         return vcs->checkOut();
265 }
266
267
268 string LyXVC::repoUpdate()
269 {
270         LYXERR(Debug::LYXVC, "LyXVC: repoUpdate");
271         if (!vcs)
272                 return string();
273         return vcs->repoUpdate();
274 }
275
276
277 string LyXVC::lockingToggle()
278 {
279         LYXERR(Debug::LYXVC, "LyXVC: toggle locking property");
280         if (!vcs)
281                 return string();
282         return vcs->lockingToggle();
283 }
284
285
286 bool LyXVC::revert()
287 {
288         LYXERR(Debug::LYXVC, "LyXVC: revert");
289         if (!vcs)
290                 return false;
291
292         docstring const file = owner_->fileName().displayName(20);
293         docstring text = bformat(_("Reverting to the stored version of the "
294                                 "document %1$s will lose all current changes.\n\n"
295                                 "Do you want to revert to the older version?"), file);
296         int ret = 0;
297         if (vcs->isRevertWithConfirmation())
298                 ret = Alert::prompt(_("Revert to stored version of document?"),
299                         text, 0, 1, _("&Revert"), _("&Cancel"));
300
301         return ret == 0 && vcs->revert();
302 }
303
304
305 void LyXVC::undoLast()
306 {
307         if (!vcs)
308                 return;
309         vcs->undoLast();
310 }
311
312
313 string LyXVC::toggleReadOnly()
314 {
315         if (!vcs)
316                 return string();
317         if (!vcs->toggleReadOnlyEnabled())
318                 return string();
319
320         switch (vcs->status()) {
321         case VCS::UNLOCKED:
322                 LYXERR(Debug::LYXVC, "LyXVC: toggle to locked");
323                 return checkOut();
324         case VCS::LOCKED: {
325                 LYXERR(Debug::LYXVC, "LyXVC: toggle to unlocked");
326                 string log;
327                 if (checkIn(log) != VCSuccess)
328                         return string();
329                 return log;
330         }
331         case VCS::NOLOCKING:
332                 Buffer * b = vcs->owner();
333                 bool const newstate = !b->isReadonly();
334                 string result = "LyXVC: toggle to ";
335                 result += (newstate ? "readonly" : "readwrite");
336                 LYXERR(Debug::LYXVC, result);
337                 b->setReadonly(newstate);
338                 return result;
339         }
340         return string();
341 }
342
343
344 bool LyXVC::inUse() const
345 {
346         if (vcs)
347                 return true;
348         return false;
349 }
350
351
352 string const LyXVC::versionString() const
353 {
354         if (!vcs)
355                 return string();
356         return vcs->versionString();
357 }
358
359
360 bool LyXVC::locking() const
361 {
362         if (!vcs)
363                 return false;
364         return vcs->status() != VCS::NOLOCKING;
365 }
366
367
368 string const LyXVC::getLogFile() const
369 {
370         if (!vcs)
371                 return string();
372
373         TempFile tempfile("lyxvclog");
374         tempfile.setAutoRemove(false);
375         FileName const tmpf = tempfile.name();
376         if (tmpf.empty()) {
377                 LYXERR(Debug::LYXVC, "Could not generate logfile " << tmpf);
378                 return string();
379         }
380         LYXERR(Debug::LYXVC, "Generating logfile " << tmpf);
381         vcs->getLog(tmpf);
382         return tmpf.absFileName();
383 }
384
385
386 string LyXVC::revisionInfo(RevisionInfo const info) const
387 {
388         if (!vcs)
389                 return string();
390
391         return vcs->revisionInfo(info);
392 }
393
394
395 bool LyXVC::renameEnabled() const
396 {
397         if (!inUse())
398                 return false;
399         return vcs->renameEnabled();
400 }
401
402
403 bool LyXVC::copyEnabled() const
404 {
405         if (!inUse())
406                 return false;
407         return vcs->copyEnabled();
408 }
409
410
411 bool LyXVC::checkOutEnabled() const
412 {
413         return vcs && vcs->checkOutEnabled();
414 }
415
416
417 bool LyXVC::checkInEnabled() const
418 {
419         return vcs && vcs->checkInEnabled();
420 }
421
422
423 bool LyXVC::isCheckInWithConfirmation() const
424 {
425         return vcs && vcs->isCheckInWithConfirmation();
426 }
427
428
429 bool LyXVC::lockingToggleEnabled() const
430 {
431         return vcs && vcs->lockingToggleEnabled();
432 }
433
434
435 bool LyXVC::undoLastEnabled() const
436 {
437         return vcs && vcs->undoLastEnabled();
438 }
439
440
441 bool LyXVC::repoUpdateEnabled() const
442 {
443         return vcs && vcs->repoUpdateEnabled();
444 }
445         
446         
447 bool LyXVC::prepareFileRevision(string const & rev, std::string & f)
448 {
449         return vcs && vcs->prepareFileRevision(rev, f);
450 }
451
452
453 bool LyXVC::prepareFileRevisionEnabled()
454 {
455         return vcs && vcs->prepareFileRevisionEnabled();
456 }
457
458 } // namespace lyx