]> git.lyx.org Git - features.git/blobdiff - src/insets/insetgraphics.C
small stuff
[features.git] / src / insets / insetgraphics.C
index a5e6b8adea3fd6f310773229a38147dbf2ac10d6..6ffb2d4155ed3475b7601549e7c7813914abc524 100644 (file)
@@ -3,7 +3,7 @@
  * 
  *           LyX, The Document Processor
  *      
- *           Copyright 1995-2000 the LyX Team.
+ *           Copyright 1995-2001 the LyX Team.
  *           
  *           This file Copyright 2000 Baruch Even.
  * ====================================================== */
@@ -14,19 +14,14 @@ How to use it for now:
 */
 
 /*
-Immediate tasks:
-       * Make the inline viewing work, there is a preliminary work going on,
-               need to finish it up.
-       * Support automatic image format conversion, create both a PNG and EPS output.
-
-       * Polishing tasks:
-               * Add messages in the empty rectangle (in the buffer view) to say how are 
-                 we doing.
-                       - Implemented, needs testing.
-               * Clean up GraphicsCacheItem(_pimpl)
-       * Pop up a dialog if the widget version is higher than what we accept.
-               * Prepare code to read FigInset insets to upgrade upwards
-               * Provide sed/awk/C code to downgrade from InsetGraphics to FigInset.
+Major tasks:
+       * Switch to convert the images in the background, this requires work on
+               the converter, the systemcontroller and the graphics cache.
+
+Minor tasks:
+    * Pop up a dialog if the widget version is higher than what we accept.
+       * Prepare code to read FigInset insets to upgrade upwards
+       * Provide sed/awk/C code to downgrade from InsetGraphics to FigInset(?)
         
 */
 
@@ -42,13 +37,17 @@ Known BUGS:
     * Bug in FileDlg class (src/filedlg.[hC]) when selecting a file and then
         pressing ok, it counts as if no real selection done. Apparently
         when choosing a file it doesn't update the select file input line.
-       * Inline viewing is still not completely operational, in fact it is now
-               disabled. To enable it enable the define:
-               INSETGRAPHICS_INLINE_VIEW
+               
        * If we are trying to create a file in a read-only directory and there
                are graphics that need converting, the converting will fail because
                it is done in-place, into the same directory as the original image.
+               This needs to be fixed in the src/converter.C file
+               [ This is presumed to be fixed, needs testing.]
+
+       * We do not dither or resize the image in a WYSIWYM way, we load it at
+               its original size and color, resizing is done in the final output,
+               but not in the LyX window.
+               
 TODO Before initial production release:
     * Replace insetfig everywhere
         * Read it's file format
@@ -57,11 +56,6 @@ TODO Before initial production release:
             // INSET_GRAPHICS: remove this when InsetFig is thrown.
           And act upon them.
  
-    * Finish the basic To-do list.
-    * Extract the general logic of the dialog in order to allow easier porting
-        to Gnome/KDE, and put the general logic in frontends and the inherited
-        platform dependent code in the appropriate dirs.
-   
 TODO Extended features:
  
     * Advanced Latex tab folder.
@@ -129,8 +123,6 @@ TODO Extended features:
 #pragma implementation
 #endif 
 
-#define INSETGRAPHICS_INLINE_VIEW
-
 #include "insets/insetgraphics.h"
 #include "insets/insetgraphicsParams.h"
 #include "graphics/GraphicsCache.h"
@@ -153,12 +145,11 @@ TODO Extended features:
 #include <algorithm> // For the std::max
 #include "support/lyxmanip.h"
 #include "debug.h"
+#include "gettext.h"
 
 extern string system_tempdir;
 
 using std::ostream;
-using std::endl;
-using std::max;
 
 // This function is a utility function
 inline
@@ -170,22 +161,34 @@ string const RemoveExtension(string const & filename)
 
 // Initialize only those variables that do not have a constructor.
 InsetGraphics::InsetGraphics()
-       : cacheHandle(0), pixmap(0), updateImage(false)
+       : cacheHandle(0), imageLoaded(false)
 {}
 
+
+InsetGraphics::InsetGraphics(InsetGraphics const & ig, bool same_id)
+       : Inset(), SigC::Object()
+       , cacheHandle(ig.cacheHandle)
+       , imageLoaded(ig.imageLoaded)
+{
+       setParams(ig.getParams());
+       if (same_id)
+               id_ = ig.id_;
+}
+
+
 InsetGraphics::~InsetGraphics()
 {
        // Emits the hide signal to the dialog connected (if any)
-       hide();
+       hideDialog();
 }
 
-char const *
+
+string const
 InsetGraphics::statusMessage() const
 {
-       char const * msg = 0;
+       string msg;
 
-#ifdef INSETGRAPHICS_INLINE_VIEW
-       if (cacheHandle) {
+       if (cacheHandle.get()) {
                switch (cacheHandle->getImageStatus()) {
                case GraphicsCacheItem::UnknownError:
                        msg = _("Unknown Error");
@@ -208,16 +211,15 @@ InsetGraphics::statusMessage() const
                        break;
                }
        }
-#else
-       msg = _("Inline view disabled");
-#endif
 
        return msg;
 }
 
+
 int InsetGraphics::ascent(BufferView *, LyXFont const &) const
 {
-       if (pixmap)
+       LyXImage * pixmap = 0;
+       if (cacheHandle.get() && (pixmap = cacheHandle->getImage()))
                return pixmap->getHeight();
        else
                return 50;
@@ -233,19 +235,22 @@ int InsetGraphics::descent(BufferView *, LyXFont const &) const
 
 int InsetGraphics::width(BufferView *, LyXFont const & font) const
 {
-       if (pixmap)
+       LyXImage * pixmap = 0;
+       
+       if (cacheHandle.get() && (pixmap = cacheHandle->getImage()))
                return pixmap->getWidth();
        else {
-               char const * msg = statusMessage();
+               string const msg = statusMessage();
                int font_width = 0;
                
-               if (msg)
+               if (!msg.empty())
                        font_width = lyxfont::width(msg, font);
                
-               return max(50, font_width + 15);
+               return std::max(50, font_width + 15);
        }
 }
 
+
 void InsetGraphics::draw(BufferView * bv, LyXFont const & font,
                          int baseline, float & x, bool) const
 {
@@ -256,84 +261,82 @@ void InsetGraphics::draw(BufferView * bv, LyXFont const & font,
        int lwidth = width(bv, font);
 
        // Make sure x is updated upon exit from this routine
-       float old_x = x;
+       int old_x = int(x);
        x += lwidth;
 
        // This will draw the graphics. If the graphics has not been loaded yet,
        // we draw just a rectangle.
-       if (pixmap) {
+       if (imageLoaded) {
 
-               paint.image(int(old_x) + 2, baseline - lascent,
-                            lwidth - 4, lascent + ldescent,
-                            pixmap);
+               paint.image(old_x + 2, baseline - lascent,
+                           lwidth - 4, lascent + ldescent,
+                           cacheHandle->getImage());
        } else {
-#ifdef INSETGRAPHICS_INLINE_VIEW
-               if (!updateImage) {
-                       updateImage = true;
-                       updateInset();
-               }
                
                // Get the image status, default to unknown error.
                GraphicsCacheItem::ImageStatus status = GraphicsCacheItem::UnknownError;
-               if (cacheHandle)
+               if (cacheHandle.get())
                        status = cacheHandle->getImageStatus();
                
                // Check if the image is now ready.
                if (status == GraphicsCacheItem::Loaded) {
-                       // It is, get it and inform the world.
-                       pixmap = cacheHandle->getImage();
+                       imageLoaded = true;
 
                        // Tell BufferView we need to be updated!
-                       bv->text->status = LyXText::CHANGED_IN_DRAW;
+                       bv->text->status(bv, LyXText::CHANGED_IN_DRAW);
                        return;
                }
-#endif
 
-               char const * msg = statusMessage();
                
-               paint.rectangle(int(old_x) + 2, baseline - lascent,
+               paint.rectangle(old_x + 2, baseline - lascent,
                                lwidth - 4,
                                lascent + ldescent);
 
-               if (msg) {
+               string const msg = statusMessage();
+               if (!msg.empty()) {
                        // Print the message.
                        LyXFont msgFont(font);
                        msgFont.setFamily(LyXFont::SANS_FAMILY);
                        msgFont.setSize(LyXFont::SIZE_FOOTNOTE);
                        string const justname = OnlyFilename (params.filename);
-                       paint.text(int(old_x) + 8, 
-                                       baseline - lyxfont::maxAscent(msgFont) - 4,
-                                   justname, msgFont);
+                       paint.text(old_x + 8, 
+                                  baseline - lyxfont::maxAscent(msgFont) - 4,
+                                  justname, msgFont);
 
                        msgFont.setSize(LyXFont::SIZE_TINY);
-                       paint.text(int(old_x) + 8, baseline - 4, 
-                                       msg, strlen(msg), msgFont);
+                       paint.text(old_x + 8, baseline - 4, msg, msgFont);
                }
        }
 }
 
 
-void InsetGraphics::Edit(BufferView *bv, int, int, unsigned int)
+void InsetGraphics::edit(BufferView *bv, int, int, unsigned int)
 {
        bv->owner()->getDialogs()->showGraphics(this);
 }
 
 
-Inset::EDITABLE InsetGraphics::Editable() const
+void InsetGraphics::edit(BufferView * bv, bool)
+{
+       edit(bv, 0, 0, 0);
+}
+
+
+Inset::EDITABLE InsetGraphics::editable() const
 {
        return IS_EDITABLE;
 }
 
 
-void InsetGraphics::Write(Buffer const * buf, ostream & os) const
+void InsetGraphics::write(Buffer const * buf, ostream & os) const
 {
-       os << "GRAPHICS FormatVersion 1" << endl;
+       os << "GRAPHICS FormatVersion 1\n";
 
        params.Write(buf, os);
 }
 
 
-void InsetGraphics::Read(Buffer const * buf, LyXLex & lex)
+void InsetGraphics::read(Buffer const * buf, LyXLex & lex)
 {
        bool finished = false;
 
@@ -341,7 +344,8 @@ void InsetGraphics::Read(Buffer const * buf, LyXLex & lex)
                lex.next();
 
                string const token = lex.GetString();
-               lyxerr.debug() << "Token: '" << token << '\'' << endl;
+               lyxerr[Debug::INFO] << "Token: '" << token << '\'' 
+                                   << std::endl;
 
                if (token.empty()) {
                        continue;
@@ -355,19 +359,22 @@ void InsetGraphics::Read(Buffer const * buf, LyXLex & lex)
                                << "This document was created with a newer Graphics widget"
                                ", You should use a newer version of LyX to read this"
                                " file."
-                               << endl;
+                               << std::endl;
                        // TODO: Possibly open up a dialog?
                }
                else {
                        if (! params.Read(buf, lex, token))
-                               lyxerr << "Unknown token, " << token << ", skipping." << endl;
+                               lyxerr << "Unknown token, " << token << ", skipping." 
+                                       << std::endl;
                }
        }
 
        updateInset();
 }
 
-static
+
+namespace {
+
 void formatResize(ostream & os, string const & key,
                  InsetGraphicsParams::Resize resizeType, double size)
 {
@@ -394,13 +401,16 @@ void formatResize(ostream & os, string const & key,
        }
 }
 
+} // namespace anon
+
+
 string const
 InsetGraphics::createLatexOptions() const
 {
        // Calculate the options part of the command, we must do it to a string
        // stream since we might have a trailing comma that we would like to remove
        // before writing it to the output stream.
-       std::ostringstream options;
+       ostringstream options;
 
        formatResize(options, "width", params.widthResize, params.widthSize);
        formatResize(options, "height", params.heightResize, params.heightSize);
@@ -417,7 +427,6 @@ InsetGraphics::createLatexOptions() const
 }
 
 
-
 string const 
 InsetGraphics::prepareFile(Buffer const *buf) const
 {
@@ -452,6 +461,11 @@ InsetGraphics::prepareFile(Buffer const *buf) const
        if (!buf->niceFile) {
                string const temp = AddName(buf->tmppath, params.filename);
                outfile = RemoveExtension(temp);
+               
+               //lyxerr << "buf::tmppath = " << buf->tmppath << "\n";
+               //lyxerr << "filename = " << params.filename << "\n";
+               //lyxerr << "temp = " << temp << "\n";
+               //lyxerr << "outfile = " << outfile << endl;
        } else {
                string const path = OnlyPath(buf->fileName());
                string const relname = MakeRelPath(params.filename, path);
@@ -463,8 +477,9 @@ InsetGraphics::prepareFile(Buffer const *buf) const
        return outfile;
 }
 
-int InsetGraphics::Latex(Buffer const *buf, ostream & os,
-               bool /*fragile*/, bool/*fs*/) const
+
+int InsetGraphics::latex(Buffer const *buf, ostream & os,
+                        bool /*fragile*/, bool/*fs*/) const
 {
        // MISSING: We have to decide how to do the order of the options
        // that is dependent of order, like width, height, angle. Should
@@ -530,7 +545,7 @@ int InsetGraphics::Latex(Buffer const *buf, ostream & os,
 }
 
 
-int InsetGraphics::Ascii(Buffer const *, ostream &, int) const
+int InsetGraphics::ascii(Buffer const *, ostream &, int) const
 {
        // No graphics in ascii output. Possible to use gifscii to convert
        // images to ascii approximation.
@@ -542,20 +557,22 @@ int InsetGraphics::Ascii(Buffer const *, ostream &, int) const
 }
 
 
-int InsetGraphics::Linuxdoc(Buffer const *, ostream &) const
+int InsetGraphics::linuxdoc(Buffer const *, ostream &) const
 {
        // No graphics in LinuxDoc output. Should check how/what to add.
        return 0;
 }
 
+
 // For explanation on inserting graphics into DocBook checkout:
 // http://linuxdoc.org/LDP/LDP-Author-Guide/inserting-pictures.html
 // See also the docbook guide at http://www.docbook.org/
-int InsetGraphics::DocBook(Buffer const * buf, ostream & os) const
+int InsetGraphics::docBook(Buffer const * buf, ostream & os) const
 {
        // Change the path to be relative to the main file.
        string const buffer_dir = OnlyPath(buf->fileName());
-       string const filename = RemoveExtension(MakeRelPath(params.filename, buffer_dir));
+       string const filename = RemoveExtension(
+                                  MakeRelPath(params.filename, buffer_dir));
 
        // In DocBook v5.0, the graphic tag will be eliminated from DocBook, will 
        // need to switch to MediaObject. However, for now this is sufficient and 
@@ -565,7 +582,7 @@ int InsetGraphics::DocBook(Buffer const * buf, ostream & os) const
 }
 
 
-void InsetGraphics::Validate(LaTeXFeatures & features) const
+void InsetGraphics::validate(LaTeXFeatures & features) const
 {
        // If we have no image, we should not require anything.
        if (params.filename.empty())
@@ -577,35 +594,35 @@ void InsetGraphics::Validate(LaTeXFeatures & features) const
                features.subfigure = true;
 }
 
+
 // Update the inset after parameters changed (read from file or changed in
 // dialog.
 void InsetGraphics::updateInset() const
 {
-#ifdef INSETGRAPHICS_INLINE_VIEW       
-       if (updateImage) {
-               GraphicsCache * gc = GraphicsCache::getInstance();
-               GraphicsCacheItem * temp = 0;
-
-               if (!params.filename.empty()) {
-                       temp = gc->addFile(params.filename);
-               }
+       GraphicsCache & gc = GraphicsCache::getInstance();
+       boost::shared_ptr<GraphicsCacheItem> temp(0);
 
-               delete cacheHandle;
-               cacheHandle = temp;
+       // We do it this way so that in the face of some error, we will still
+       // be in a valid state.
+       if (!params.filename.empty()) {
+               temp = gc.addFile(params.filename);
        }
-#else
-       cacheHandle = 0;
-#endif
+
+       // Mark the image as unloaded so that it gets updated.
+       imageLoaded = false;
+
+       cacheHandle = temp;
 }
 
-bool InsetGraphics::setParams(InsetGraphicsParams const & params)
+
+bool InsetGraphics::setParams(InsetGraphicsParams const & p)
 {
        // If nothing is changed, just return and say so.
-       if (this->params == params)
+       if (params == p)
                return false;
 
        // Copy the new parameters.
-       this->params = params;
+       params = p;
 
        // Update the inset with the new parameters.
        updateInset();
@@ -614,23 +631,14 @@ bool InsetGraphics::setParams(InsetGraphicsParams const & params)
        return true;
 }
 
+
 InsetGraphicsParams InsetGraphics::getParams() const
 {
        return params;
 }
 
-Inset * InsetGraphics::Clone(Buffer const &) const
-{
-       InsetGraphics * newInset = new InsetGraphics;
-
-       if (cacheHandle)
-               newInset->cacheHandle = cacheHandle->Clone();
-       else
-               newInset->cacheHandle = 0;
-       newInset->pixmap = pixmap;
-       newInset->updateImage = updateImage;
 
-       newInset->setParams(getParams());
-
-       return newInset;
+Inset * InsetGraphics::clone(Buffer const &, bool same_id) const
+{
+       return new InsetGraphics(*this, same_id);
 }