]> git.lyx.org Git - features.git/commitdiff
VCS: add svn locking mechanism
authorPavel Sanda <sanda@lyx.org>
Sat, 31 Jan 2009 17:10:56 +0000 (17:10 +0000)
committerPavel Sanda <sanda@lyx.org>
Sat, 31 Jan 2009 17:10:56 +0000 (17:10 +0000)
git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@28302 a592a061-630c-0410-9148-cb99ea01b6c8

src/VCBackend.cpp
src/VCBackend.h

index e0c5a144b9040c93a3d1ed33645ee838857b689e..6e8b5655545e62e9c5e52989aaa6b0d74aa77a22 100644 (file)
@@ -419,8 +419,10 @@ bool CVS::toggleReadOnlyEnabled()
 
 SVN::SVN(FileName const & m, FileName const & f)
 {
+       owner_ = 0;
        master_ = m;
        file_ = f;
+       locked_mode_ = 0;
        scanMaster();
 }
 
@@ -460,6 +462,46 @@ void SVN::scanMaster()
 }
 
 
+bool SVN::checkLockMode()
+{
+       FileName tmpf = FileName::tempName("lyxvcout");
+       if (tmpf.empty()){
+               LYXERR(Debug::LYXVC, "Could not generate logfile " << tmpf);
+               return N_("Error: Could not generate logfile.");
+       }
+
+       LYXERR(Debug::LYXVC, "Detecting locking mode...");
+       if (doVCCommandCall("svn proplist " + quoteName(file_.onlyFileName())
+                   + " > " + quoteName(tmpf.toFilesystemEncoding()),
+                   file_.onlyPath()))
+               return false;
+
+       ifstream ifs(tmpf.toFilesystemEncoding().c_str());
+       string line;
+       bool ret = false;
+
+       while (ifs) {
+               getline(ifs, line);
+               LYXERR(Debug::LYXVC, line);
+               if (contains(line, "svn:needs-lock"))
+                       ret = true;
+       }
+       LYXERR(Debug::LYXVC, "Locking enabled: " << ret);
+       ifs.close();
+       locked_mode_ = ret;
+       return ret;
+
+}
+
+
+bool SVN::isLocked()
+{
+       //refresh file info
+       FileName file(file_.absFilename());
+       return !file.isReadOnly();
+}
+
+
 void SVN::registrer(string const & /*msg*/)
 {
        doVCCommand("svn add -q " + quoteName(onlyFilename(owner_->absFileName())),
@@ -487,6 +529,9 @@ string SVN::checkIn(string const & msg)
                                _("Error when commiting to repository.\n"
                                "You have to manually resolve the problem.\n"
                                "After pressing OK, LyX will reopen the document."));
+       else
+               fileLock(false, tmpf, log);
+
        tmpf.erase();
        return "SVN: " + log;
 }
@@ -494,9 +539,13 @@ string SVN::checkIn(string const & msg)
 
 bool SVN::checkInEnabled()
 {
-       return true;
+       if (locked_mode_)
+               return isLocked();
+       else
+               return true;
 }
 
+
 // FIXME Correctly return code should be checked instead of this.
 // This would need another solution than just plain startscript.
 // Hint from Andre': QProcess::readAllStandardError()...
@@ -519,6 +568,36 @@ string SVN::scanLogFile(FileName const & f, string & status)
 }
 
 
+void SVN::fileLock(bool lock, FileName const & tmpf, string &status)
+{
+       if (!locked_mode_ || (isLocked() == lock))
+               return;
+
+       string arg = lock ? "lock " : "unlock ";
+       doVCCommand("svn "+ arg + quoteName(onlyFilename(owner_->absFileName()))
+                   + " > " + quoteName(tmpf.toFilesystemEncoding()),
+                   FileName(owner_->filePath()));
+
+       ifstream ifs(tmpf.toFilesystemEncoding().c_str());
+       string line;
+       while (ifs) {
+               getline(ifs, line);
+               if (!line.empty()) status += line + "; ";
+       }
+       ifs.close();
+
+       if (!isLocked() && lock)
+               frontend::Alert::error(_("Revision control error."),
+                       _("Error when acquiring write lock.\n"
+                       "Most probably some other user edit the current document now!\n"
+                       "Check also the access to the repository."));
+       if (isLocked() && !lock)
+               frontend::Alert::error(_("Revision control error."),
+                       _("Error when releasing write lock.\n"
+                       "Check the access to the repository."));
+}
+
+
 string SVN::checkOut()
 {
        FileName tmpf = FileName::tempName("lyxvcout");
@@ -539,6 +618,9 @@ string SVN::checkOut()
                                "You have to manually resolve the conflicts NOW!\n'%1$s'.\n\n"
                                "After pressing OK, LyX will try to reopen resolved document."),
                        from_local8bit(res)));
+
+       fileLock(true, tmpf, log);
+
        tmpf.erase();
        return "SVN: " + log;
 }
@@ -546,7 +628,10 @@ string SVN::checkOut()
 
 bool SVN::checkOutEnabled()
 {
-       return true;
+       if (locked_mode_)
+               return !isLocked();
+       else
+               return true;
 }
 
 
index e86f258d700d5869c6251d4d8903c38d703dcb92..23bb162eb5583f32ed1b0d34d0edfc85f64c9a0b 100644 (file)
@@ -225,9 +225,17 @@ protected:
        virtual void scanMaster();
        /// Check for messages in svn output. Returns error.
        std::string scanLogFile(support::FileName const & f, std::string & status);
+       /// checks locking policy and setup locked_mode_
+       bool checkLockMode();
+       /// is the loaded file locked?
+       bool isLocked();
+       /// acquire/release write lock for the current file
+       void fileLock(bool lock, support::FileName const & tmpf, std::string & status);
 
 private:
        support::FileName file_;
+       /// is the loaded file under locking policy?
+       bool locked_mode_;
 };
 
 } // namespace lyx