Am 04.11.2010 um 16:52 schrieb Stephan Witt:

> Am 04.11.2010 um 16:15 schrieb Pavel Sanda:
> 
>> Stephan Witt wrote:
>>>>> I'll use an explicit getRevisionInfo() success state flag and return 
>>>>> string() instead. Ok?
>>>> 
>>>> not sure what exactly do you mean :)
>>> 
>>> That's how I understood your comment, but the new patch is not ready...
>>> 
>>> Like that:
>>> 
>> 
>> i'm basically happy that the duplicated strings disappeared.
>> lyxerr looks more approriate inside getRevisionInfo.
> 
> Ok.

Now I've finished the patch and have a fundamental problem:
When a document contains vcs buffer-info insets like vcs-author the reload
crashes. The culprit is the owner_->setBusy(false); in VCS::doVCCommand().
The cursor cannot be changed when the buffer load is in progress - it seems.
I solved it with using the reportError flag to suppress the cursor changes.
I'm sure - it's not the correct solution. But I cannot solve this in a better 
way.
Please help. I'm frustrated. One possible change is to move the info inset 
variable
initialization into file_found_hook()... but this is a static method - again
more to change then planned.
Anyway, the patch is attached (with the reportError/cursor logic).
I'd appreciate any comment. (I fear SVN is affected by that too!)

Stephan

Index: src/VCBackend.h
===================================================================
--- src/VCBackend.h     (Revision 36088)
+++ src/VCBackend.h     (Arbeitskopie)
@@ -261,6 +261,21 @@
        // revision number from scanMaster
        std::string version_;
 
+       /**
+        * doVCCommandWithOutput
+        * - call out to the version control utility
+        * - it is able to collect output in a file
+        * @param cmd the command to execute
+        * @param path the path from which to execute
+        * @param output the path where to store output
+        * @param reportError display of low level error message dialog
+        * @return exit status
+        */
+       int doVCCommandWithOutput(std::string const & cmd,
+                       support::FileName const & path,
+                       support::FileName const & output,
+                       bool reportError = true);
+
        /// return the quoted pathname if Directory or filename if File
        virtual std::string const getTarget(OperationMode opmode) const;
        /// collect the diff of file or directory against repository
@@ -280,6 +295,15 @@
        virtual CvsStatus getStatus();
        /// convert enum to string
        virtual docstring toString(CvsStatus status) const;
+
+       /// cache the info values of current file revision
+       /// author, date and time of commit
+       std::string rev_author_cache_;
+       std::string rev_date_cache_;
+       std::string rev_time_cache_;
+       /// fills the cache values, returns true if successfull.
+       void getRevisionInfo();
+       bool have_rev_info_;
 };
 
 
Index: src/VCBackend.cpp
===================================================================
--- src/VCBackend.cpp   (Revision 36088)
+++ src/VCBackend.cpp   (Arbeitskopie)
@@ -49,18 +49,19 @@
 
 int VCS::doVCCommand(string const & cmd, FileName const & path, bool 
reportError)
 {
-       if (owner_)
+       if (owner_ && reportError)
                owner_->setBusy(true);
 
        int const ret = doVCCommandCall(cmd, path);
 
-       if (owner_)
+       if (owner_ && reportError)
                owner_->setBusy(false);
-       if (ret && reportError)
+       if (ret && reportError) {
                frontend::Alert::error(_("Revision control error."),
                        bformat(_("Some problem occured while running the 
command:\n"
-                                 "'%1$s'."),
-                       from_utf8(cmd)));
+                                         "'%1$s'.\n"),
+                                       from_utf8(cmd)));
+       }
        return ret;
 }
 
@@ -366,6 +367,7 @@
 {
        master_ = m;
        file_ = f;
+       have_rev_info_ = false;
        scanMaster();
 }
 
@@ -478,6 +480,14 @@
 }
 
 
+int CVS::doVCCommandWithOutput(string const & cmd, FileName const & path,
+       FileName const & output, bool reportError)
+{
+       string redirection = output.empty() ? "" : " > " + 
quoteName(output.toFilesystemEncoding());
+       return doVCCommand(cmd + redirection, path, reportError);
+}
+
+
 CVS::CvsStatus CVS::getStatus()
 {
        FileName tmpf = FileName::tempName("lyxvcout");
@@ -486,9 +496,8 @@
                return StatusError;
        }
 
-       if (doVCCommand("cvs status " + getTarget(File)
-               + " > " + quoteName(tmpf.toFilesystemEncoding()),
-               FileName(owner_->filePath()))) {
+       if (doVCCommandWithOutput("cvs status " + getTarget(File),
+               FileName(owner_->filePath()), tmpf)) {
                tmpf.removeFile();
                return StatusError;
        }
@@ -517,7 +526,51 @@
        return status;
 }
 
+void CVS::getRevisionInfo()
+{
+       if (have_rev_info_)
+               return;
+       have_rev_info_ = true;
+       FileName tmpf = FileName::tempName("lyxvcout");
+       if (tmpf.empty()) {
+               LYXERR(Debug::LYXVC, "Could not generate logfile " << tmpf);
+               return;
+       }
+       
+       if (doVCCommandWithOutput("cvs log -r" + version_ 
+               + " " + getTarget(File),
+               FileName(owner_->filePath()), tmpf, false)) {
+               tmpf.removeFile();
+               LYXERR(Debug::LYXVC, "cvs log failed");
+               return;
+       }
+       
+       ifstream ifs(tmpf.toFilesystemEncoding().c_str());
+       static regex const reg("date: (.*) (.*) (.*);  author: (.*);  state: 
(.*);(.*)");
 
+       while (ifs) {
+               string line;
+               getline(ifs, line);
+               LYXERR(Debug::LYXVC, line << "\n");
+               if (prefixIs(line, "date:")) {
+                       smatch sm;
+                       regex_match(line, sm, reg);
+                       //sm[0]; // whole matched string
+                       rev_date_cache_ = sm[1];
+                       rev_time_cache_ = sm[2];
+                       //sm[3]; // GMT offset
+                       rev_author_cache_ = sm[4];
+                       break;
+               }
+       }
+       tmpf.removeFile();
+       if (rev_author_cache_.empty())
+               LYXERR(Debug::LYXVC,
+                  "Could not retrieve revision info for " << version_ <<
+                  " of " << getTarget(File));
+}
+
+
 void CVS::registrer(string const & msg)
 {
        doVCCommand("cvs -q add -m \"" + msg + "\" "
@@ -528,9 +581,8 @@
 
 void CVS::getDiff(OperationMode opmode, FileName const & tmpf)
 {
-       doVCCommand("cvs diff " + getTarget(opmode)
-               + " > " + quoteName(tmpf.toFilesystemEncoding()),
-               FileName(owner_->filePath()), false);
+       doVCCommandWithOutput("cvs diff " + getTarget(opmode),
+               FileName(owner_->filePath()), tmpf, false);
 }
 
 
@@ -552,12 +604,9 @@
 
 int CVS::update(OperationMode opmode, FileName const & tmpf)
 {
-       string const redirection = tmpf.empty() ? ""
-               : " > " + quoteName(tmpf.toFilesystemEncoding());
-
-       return doVCCommand("cvs -q update "
-               + getTarget(opmode) + redirection,
-               FileName(owner_->filePath()));
+       return doVCCommandWithOutput("cvs -q update "
+               + getTarget(opmode),
+               FileName(owner_->filePath()), tmpf, false);
 }
 
 
@@ -650,12 +699,14 @@
        int rc = update(File, tmpf);
        string log;
        string const res = scanLogFile(tmpf, log);
-       if (!res.empty())
+       if (!res.empty()) {
                frontend::Alert::error(_("Revision control error."),
                        bformat(_("Error when updating from repository.\n"
                                "You have to manually resolve the conflicts 
NOW!\n'%1$s'.\n\n"
                                "After pressing OK, LyX will try to reopen the 
resolved document."),
                                from_local8bit(res)));
+               rc = 0;
+       }
        
        tmpf.erase();
        return rc ? string() : log.empty() ? "CVS: Proceeded" : "CVS: " + log;
@@ -704,10 +755,23 @@
 
        int rc = update(Directory, tmpf);
        res += "Update log:\n" + tmpf.fileContents("UTF-8");
+       LYXERR(Debug::LYXVC, res);
+
+       string log;
+       string sres = scanLogFile(tmpf, log);
+       if (!sres.empty()) {
+               docstring const file = owner_->fileName().displayName(20);
+               frontend::Alert::error(_("Revision control error."),
+                       bformat(_("Error when updating document %1$s from 
repository.\n"
+                                         "You have to manually resolve the 
conflicts NOW!\n'%2$s'.\n\n"
+                                         "After pressing OK, LyX will try to 
reopen the resolved document."),
+                               file, from_local8bit(sres)));
+               rc = 0;
+       }
+       
        tmpf.removeFile();
 
-       LYXERR(Debug::LYXVC, res);
-       return rc ? string() : "CVS: Proceeded" ;
+       return rc ? string() : log.empty() ? "CVS: Proceeded" : "CVS: " + log;
 }
 
 
@@ -793,9 +857,9 @@
 
 void CVS::getLog(FileName const & tmpf)
 {
-       doVCCommand("cvs log " + getTarget(File)
-                   + " > " + quoteName(tmpf.toFilesystemEncoding()),
-                   FileName(owner_->filePath()));
+       doVCCommandWithOutput("cvs log " + getTarget(File),
+               FileName(owner_->filePath()),
+               tmpf);
 }
 
 
@@ -807,8 +871,20 @@
 
 string CVS::revisionInfo(LyXVC::RevisionInfo const info)
 {
-       if (info == LyXVC::File)
-               return version_;
+       if (!version_.empty()) {
+               getRevisionInfo();
+               switch (info) {
+               case LyXVC::File:
+                       return version_;
+               case LyXVC::Author:
+                       return rev_author_cache_;
+               case LyXVC::Date:
+                       return rev_date_cache_;
+               case LyXVC::Time:
+                       return rev_time_cache_;
+               default: ;
+               }
+       }
        return string();
 }
 

Reply via email to