Angus Leeming wrote:
> 
> There are two problems to address.
> 1. Updating the image on screen. 
> 
> I think you should just use the FileMonitor.[Ch] files that we use in 
> 1.3.0cvs because I know that they work and they're a clean and minimal 
> solution. I attach them for your perusal. You'll have to replace the 
> boost::signal stuff with its SigC::signal equivalent but that's trivial and I 
> can definitely help you there if you get stuck.
> You'll then just need to add a FileMonitor instance to GraphicsCacheItem, 
> connect to the signal and start it off. Same as is done in the 1.3.0cvs code.
> 
> 2. Re-running latex.
> 
> The latex compiler is activated only if the checksum of the .tex file has 
> changed. Changes to included files are not taken into account. I have no real 
> ideas about how to fix this properly.
> 

I think I've solved the latex problem:
even when the latex compiler is activated, the preview of the
image still refers to the old one.
This is because InsetGraphics::prepareFile check for the existance
of the graphic file (to be converted to eps) in lyx_tempbuf, and
the file is not copied if an old version is already there.
I think it shold check for the existence of the file AND
compare the timestamp (copy_tempfile.patch). The problem
is independent from the cache behaviour. With S-C-t
the document's .ps file is regenerated correctly even if the
.lyx file is unchanged.

For the cache behaviour, I'm slowly working on it, but don't expect
anaything soon. I've replaced the boost::signal in FileMonitor. Could
you please check the two files? In particular, is it ok to derive
FileMonitor::Impl from SigC::Object? And what about
FileMonitor::Impl::Impl:

timer_.timeout.connect(slot(this, &FileMonitor::Impl::monitorFile));
?

Thanks in advance,

Marco Morandini

Index: src/insets/insetgraphics.C
===================================================================
RCS file: /cvs/lyx/lyx-devel/src/insets/insetgraphics.C,v
retrieving revision 1.109.2.5
diff -u -r1.109.2.5 insetgraphics.C
--- src/insets/insetgraphics.C  2002/07/16 22:11:17     1.109.2.5
+++ src/insets/insetgraphics.C  2002/09/09 08:43:10
@@ -80,6 +80,7 @@
 
 #include "support/LAssert.h"
 #include "support/filetools.h"
+#include "support/FileInfo.h"
 #include "support/lyxalgo.h" // lyx::count
 #include "support/path.h"
 #include "support/os.h"
@@ -689,17 +690,31 @@
                lyxerr[Debug::GRAPHICS]
                        << "\tchanged to: " << temp_file << endl;
 
-               // if the file doen't exists, copy it into the tempdi
-               if (!IsFileReadable(temp_file)) {
-                       bool const success = lyx::copy(orig_file_with_path, temp_file);
-                       lyxerr[Debug::GRAPHICS]
-                               << "\tcopying from " << orig_file_with_path << " to "
-                               << temp_file
-                               << (success ? " succeeded\n" : " failed\n");
-                       if (!success) {
-                               Alert::alert(_("Cannot copy file"), 
orig_file_with_path,
-                                       _("into tempdir"));
-                               return RemoveExtension(orig_file);
+               // if the file doen't exists or is older than the original, copy it 
+into the tempdi
+               {
+                       bool file_exist = IsFileReadable(temp_file);
+                       if (file_exist) {
+                               FileInfo filetemp(temp_file), 
+fileorig(orig_file_with_path);
+                               //check that the orig file is still there
+                               if (fileorig.isOK() && filetemp.isOK()) {
+                                       file_exist = (fileorig.getModificationTime() < 
+                                               filetemp.getModificationTime());
+                               } else {
+                                       //let the code below try to copy the file and 
+issue a warning
+                                       file_exist = false;
+                               }
+                       }
+                       if (!file_exist) {
+                               bool const success = lyx::copy(orig_file_with_path, 
+temp_file);
+                               lyxerr[Debug::GRAPHICS]
+                                       << "\tcopying from " << orig_file_with_path << 
+" to "
+                                       << temp_file
+                                       << (success ? " succeeded\n" : " failed\n");
+                               if (!success) {
+                                       Alert::alert(_("Cannot copy file"), 
+orig_file_with_path,
+                                               _("into tempdir"));
+                                       return RemoveExtension(orig_file);
+                               }
                        }
                }
        }
Index: src/insets/ChangeLog
===================================================================
RCS file: /cvs/lyx/lyx-devel/src/insets/ChangeLog,v
retrieving revision 1.421.2.23
diff -u -r1.421.2.23 ChangeLog
--- src/insets/ChangeLog        2002/08/27 11:27:46     1.421.2.23
+++ src/insets/ChangeLog        2002/09/09 08:43:15
@@ -1,3 +1,7 @@
+2002-08-07  Marco Morandini <[EMAIL PROTECTED]>
+       * insetgraphics.C: (latex) copy file if tmp_file is older 
+       than orig_file
+       
 2002-08-07  Juergen Vigna  <[EMAIL PROTECTED]>
 
        * insettabular.C (localDispatch): make delete not put the stuff
/*
 * \file FileMonitor.C
 * Copyright 2002 the LyX Team
 * Read the file COPYING
 *
 * \author Angus Leeming <[EMAIL PROTECTED]>
 */

#include <config.h>

#ifdef __GNUG__
#pragma implementation
#endif

#include "FileMonitor.h"

#include "frontends/Timeout.h"

#include "support/FileInfo.h"
#include "support/lyxlib.h"

#include <sigc++/bind.h>
//#include <boost/signals/trackable.hpp>
#include <sigc++/marshal.h>

struct FileMonitor::Impl : public SigC::Object {

        ///
        Impl(string const & file_with_path, int interval);

        ///
        void monitorFile();

        ///
        string filename_;

        ///
        Timeout timer_;

        /// This signal is emitted if the file is modified (has a new checksum).
        SigC::Signal0<void> fileChanged_;

        /** We use these to ascertain whether a file (once loaded successfully)
         *  has changed.
         */
        time_t timestamp_;
        ///
        unsigned long checksum_;
};


FileMonitor::FileMonitor(string const & file_with_path, int interval)
        : pimpl_(new Impl(file_with_path, interval))
{}


FileMonitor::~FileMonitor()
{}


void FileMonitor::reset(string const & file_with_path) const
{
        if (pimpl_->filename_ == file_with_path)
                return;

        bool const monitor = pimpl_->timer_.running();
        if (monitor)
                stop();
        
        pimpl_->filename_ = file_with_path;

        if (monitor)
                start();
}


string const & FileMonitor::filename() const
{
        return pimpl_->filename_;
}


void FileMonitor::start() const
{
        if (monitoring())
                return;

        FileInfo finfo(pimpl_->filename_);
        if (!finfo.isOK())
                return;

        pimpl_->timestamp_ = finfo.getModificationTime();
        pimpl_->checksum_ = lyx::sum(pimpl_->filename_);

        if (pimpl_->timestamp_ && pimpl_->checksum_) {
                pimpl_->timer_.start();
        } else {
                pimpl_->timestamp_ = 0;
                pimpl_->checksum_ = 0;
        }
}


void FileMonitor::stop() const
{
        pimpl_->timestamp_ = 0;
        pimpl_->checksum_ = 0;
        pimpl_->timer_.stop();
}


bool FileMonitor::monitoring() const
{
        return pimpl_->timer_.running();
}


unsigned long FileMonitor::checksum() const
{
        // If we aren't actively monitoring the file, then recompute the
        // checksum explicitly.
        if (!pimpl_->timer_.running() && !pimpl_->filename_.empty())
                return lyx::sum(pimpl_->filename_);

        return pimpl_->checksum_;
}


SigC::Connection FileMonitor::connect(slot_type const & slot) const
{
        return pimpl_->fileChanged_.connect(slot);
}


//------------------------------
// Implementation details follow
//------------------------------


FileMonitor::Impl::Impl(string const & file_with_path, int interval)
        : filename_(file_with_path),
          timer_(interval, Timeout::ONETIME),
          timestamp_(0),
          checksum_(0)
{
//      timer_.timeout.connect(boost::bind(&Impl::monitorFile, this));
        timer_.timeout.connect(slot(this, &FileMonitor::Impl::monitorFile));
}


void FileMonitor::Impl::monitorFile()
{
        bool changed = false;

        FileInfo finfo(filename_);
        if (!finfo.isOK()) {
                changed = timestamp_ || checksum_;
                timestamp_ = 0;
                checksum_ = 0;

        } else {
                time_t const new_timestamp = finfo.getModificationTime();

                if (new_timestamp != timestamp_) {
                        timestamp_ = new_timestamp;

                        unsigned long const new_checksum = lyx::sum(filename_);
                        if (new_checksum != checksum_) {
                                checksum_ = new_checksum;
                                changed = true;
                        }
                }
        }

        timer_.start();
        if (changed)
                fileChanged_();
}
// -*- C++ -*-
/*
 * \file FileMonitor.h
 * Copyright 2002 the LyX Team
 * Read the file COPYING
 *
 * \author Angus Leeming <[EMAIL PROTECTED]>
 *
 * FileMonitor monitors a file and informs a listener when that file has
 * changed.
 */

#ifndef FILEMONITOR_H
#define FILEMONITOR_H

#ifdef __GNUG__
#pragma interface
#endif

#include "LString.h"

#include <boost/utility.hpp>
#include <boost/smart_ptr.hpp>
#include <sigc++/basic_signal.h>

class FileMonitor : boost::noncopyable {
public:
        /** Once monitoring begins, the file will be monitored every
         *  interval ms.
         */
        FileMonitor(string const & file_with_path, int interval);

        /// Define an empty d-tor out-of-line to keep boost::scoped_ptr happy.
        ~FileMonitor();

        ///
        void reset(string const & file_with_path) const;

        ///
        string const & filename() const;

        /// Begin monitoring the file
        void start() const;
        ///
        void stop() const;
        ///
        bool monitoring() const;

        /** The checksum is recomputed whenever the file is modified.
         *  If the file is not being monitored, then the checksum will be
         *  recomputed each time this function is called.
         */
        unsigned long checksum() const;

        /// Connect and you'll be informed when the file has changed.
        typedef SigC::Signal0<void>::InSlotType slot_type;
        ///
        SigC::Connection connect(slot_type const &) const;

private:
        /// Use the Pimpl idiom to hide the internals.
        class Impl;

        /// The pointer never changes although *pimpl_'s contents may.
        boost::scoped_ptr<Impl> const pimpl_;
};

#endif // FILEMONITOR_H

Reply via email to