From 325dccab098a80c1d43ab76e9a928f937aa04fc4 Mon Sep 17 00:00:00 2001 From: =?utf8?q?J=C3=BCrgen=20Vigna?= Date: Thu, 12 Oct 2000 10:46:06 +0000 Subject: [PATCH] Baruch's InsetGraphics - LyXImage patch git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@1106 a592a061-630c-0410-9148-cb99ea01b6c8 --- ChangeLog | 70 ++++++++++++ configure.in | 1 + development/Code_rules/Rules | 26 ++--- src/Makefile.am | 4 +- src/Painter.C | 12 ++- src/Painter.h | 5 +- src/PainterBase.h | 5 +- src/converter.C | 2 +- src/converter.h | 2 +- src/filedlg.C | 22 ++-- src/frontends/Makefile.am | 2 +- src/frontends/support/.cvsignore | 6 ++ src/frontends/support/LyXImage.C | 25 +++++ src/frontends/support/LyXImage.h | 29 +++++ src/frontends/support/LyXImage_X.C | 43 ++++++++ src/frontends/support/LyXImage_X.h | 43 ++++++++ src/frontends/support/Makefile.am | 11 ++ src/frontends/xforms/FormGraphics.C | 57 ++++++---- src/frontends/xforms/FormGraphics.h | 12 ++- src/graphics/GraphicsCache.C | 2 +- src/graphics/GraphicsCacheItem.C | 16 ++- src/graphics/GraphicsCacheItem.h | 9 +- src/graphics/GraphicsCacheItem_pimpl.C | 2 +- src/graphics/GraphicsCacheItem_pimpl.h | 13 +-- src/graphics/Renderer.C | 22 +--- src/graphics/Renderer.h | 20 ++-- src/graphics/XPM_Renderer.C | 5 +- src/insets/insetgraphics.C | 143 +++++++++++++++++++------ src/insets/insetgraphics.h | 9 +- 29 files changed, 482 insertions(+), 136 deletions(-) create mode 100644 src/frontends/support/.cvsignore create mode 100644 src/frontends/support/LyXImage.C create mode 100644 src/frontends/support/LyXImage.h create mode 100644 src/frontends/support/LyXImage_X.C create mode 100644 src/frontends/support/LyXImage_X.h create mode 100644 src/frontends/support/Makefile.am diff --git a/ChangeLog b/ChangeLog index c1f5a8f1f7..fcb1a3e3cb 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,73 @@ +2000-10-12 Juergen Vigna + + * development/Code_rules/Rules: fixed some typos. + +2000-10-09 Baruch Even + + * src/filedlg.C (GroupCache::find): de-inlined the function, makes + compiling on egcs 1.1.2 possible. + + * src/filedlg.C (comp_direntry::operator() ): ditto. + +2000-08-31 Baruch Even + + * src/lyx_cb.[hC] (ShowMessage): Result of the const-ificiation of the + Buffer parameter. + + * src/frontends/xforms/FormGraphics.C: Changed the dialog to be + transient it now only gets freed when the object is destructed. + +2000-08-24 Baruch Even + + * src/frontends/FormGraphics.h: + * src/frontends/FormGraphics.C: Changed to use ButtonController and + ButtonPolicies. + +2000-08-20 Baruch Even + + * src/insets/insetgraphics.C: + (draw): Added messages to the drawn rectangle to report status. + (updateInset): Disabled the use of the inline graphics, + (draw): ditto. + +2000-08-17 Baruch Even + + * src/frontends/support: Directory added for the support of GUII LyX. + + * src/frontends/support/LyXImage.h: + * src/frontends/support/LyXImage.C: Base class for GUII holding of + images. + + * src/frontends/support/LyXImage_X.h: + * src/frontends/support/LyXImage_X.C: Implementation of the Xlib + version of LyXImage, this uses the Xlib Pixmap. + + * src/PainterBase.h: + * src/PainterBase.C: + * src/Painter.h: + * src/Painter.C: Added a new method image() to draw LyXImage-s, a GUII + replacement to Pixmap. + + * src/insets/insetgraphics.h: + * src/insets/insetgraphics.C: + * src/graphics/GraphicsCacheItem.h: + * src/graphics/GraphicsCacheItem.C: + * src/graphics/GraphicsCacheItem_pimpl.h: + * src/graphics/GraphicsCacheItem_pimpl.C: Changed to use LyXImage + instead of Pixmap. + + * src/graphics/GraphicsCacheItem.h: + * src/graphics/GraphicsCacheItem.C: Added the Clone() method to create + another copy of the object. + + * src/insets/insetgraphics.C (Clone): Changed to create a second copy + of cacheHandle, this fixed a bug that sent LyX crashing. + + * src/graphics/XPM_Renderer.h: + * src/graphics/XPM_Renderer.C: + * src/graphics/EPS_Renderer.h: + * src/graphics/EPS_Renderer.C: Changed to Unix LF from DOS CRLF. + 2000-10-12 Lars Gullik Bjønnes * src/lyxfunc.C (processKeySym): only handle the diff --git a/configure.in b/configure.in index d3a9592a36..0f2c5fd0a5 100644 --- a/configure.in +++ b/configure.in @@ -291,6 +291,7 @@ AC_OUTPUT([Makefile \ src/support/Makefile \ src/xtl/Makefile \ src/frontends/Makefile \ + src/frontends/support/Makefile \ src/frontends/xforms/Makefile \ src/frontends/kde/Makefile \ src/frontends/gnome/Makefile \ diff --git a/development/Code_rules/Rules b/development/Code_rules/Rules index 7e7aaecf52..230d0600a7 100644 --- a/development/Code_rules/Rules +++ b/development/Code_rules/Rules @@ -97,7 +97,7 @@ in C++. aimed especially at loops. Container::iterator end = large.end(); - for (Container::iterator it = large.begin(), it != end; ++it) { + for (Container::iterator it = large.begin(); it != end; ++it) { ...; } -NOT- @@ -139,8 +139,8 @@ different types of exceptions safety: (These are taken from Herb Sutters book[ExC++] " -1. Basic guarantee: Even in te presence of exceptions thrown by T or -other exceptions, Stack objects don't leak resources. +1. Basic guarantee: Even in the presence of exceptions thrown by T or + other exceptions, Stack objects don't leak resources. Note that this also implies that the container will be destructible and usable even if an exception is thrown wile performing some container operation. However, if an exception @@ -149,7 +149,7 @@ other exceptions, Stack objects don't leak resources. basic guarantee can work safely in some settings. 2. Strong guarantee: If an operation terminates because of an -exception, program state will remain uncanged. + exception, program state will remain uncanged. This always implies commit-or-rollback samantics, including that no references or iterators into the container be invalidated if an operation fails. For example, if a Stack @@ -161,29 +161,29 @@ exception, program state will remain uncanged. exception-safe standard library adaption at: http://www.metabyte.com/~fbp/stl/eg_contract.html - Probably te most interesting point here is tat wen you + Probably the most interesting point here is that when you implement the basic guarantee, the strong guarantee often comes for free. For example, in our Stack implementation, alost everything we did was needed to satisfy just the basic - guarantee -- and wath's presented above very nearly satisfires + guarantee -- and what's presented above very nearly satisfires the strong guarantee, with little of no extra work. Not half bad, considering all the trouble we went to. - In addition to tese two guarantees, there is one more + In addition to these two guarantees, there is one more guarantee that certain functions must provide in order to make overall exception safety possible: -3. Nothrow guarantee: Te function will not emit an exception under any - circumstances. +3. Nothrow guarantee: The function will not emit an exception under any + circumstances. Overall exception safety isn't possible unless certain functions are guaranteed not to throw. In particualr, we've - seen that this is true for destructors; later in tis + seen that this is true for destructors; later in this miniseries, we'll see that it's also needed in certain helper functions, such as Swap(). " For all cases where we might be able to write exception safe functions -without using try,throw or catch we should do so. In particular we +without using try, throw or catch we should do so. In particular we should look over all destructors to ensure that they are as exception safe at possible. @@ -256,7 +256,7 @@ Formatting - Long variables are named like thisLongVariableName. - New types are capitalized, so this goes for typedefs,classes,structs + New types are capitalized, so this goes for typedefs, classes, structs and enums. * Formatting @@ -288,7 +288,7 @@ Formatting - Use this order for the access sections of your class: public, protected, private. The public section is interesting for every user of the class. The private section is only of interest for the - implementors of the class (you). [Obvously not true since this is + implementors of the class (you). [Obviously not true since this is for developers, and we do not want one developer only to be able to read and understand the implementation of class internals. Lgb] diff --git a/src/Makefile.am b/src/Makefile.am index 162053e1ea..c35e4f7c1c 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -10,7 +10,9 @@ bin_PROGRAMS = lyx lyx_DEPENDENCIES = mathed/libmathed.la insets/libinsets.la \ graphics/libgraphics.la \ frontends/libfrontends.la @FRONTEND_GUILIB@ \ - frontends/libfrontends.la support/libsupport.la @INCLUDED_SIGC@ + frontends/libfrontends.la \ + frontends/support/libfrontendsupport.la support/libsupport.la \ + @INCLUDED_SIGC@ lyx_LDADD = $(lyx_DEPENDENCIES) @INTLLIBS@ $(LYX_LIBS) $(SIGC_LIBS) \ $(PSPELL_LIBS) @FRONTEND_LDFLAGS@ @FRONTEND_LIBS@ #lyx_LDFLAGS=-Wl,-O1 diff --git a/src/Painter.C b/src/Painter.C index 5836bf50ac..94943ff957 100644 --- a/src/Painter.C +++ b/src/Painter.C @@ -33,6 +33,8 @@ #include "lyxrc.h" #include "encoding.h" +#include "frontends/support/LyXImage.h" + using std::endl; using std::max; @@ -235,7 +237,6 @@ PainterBase & Painter::segments(int const * x1, int const * y1, return *this; } - PainterBase & Painter::pixmap(int x, int y, int w, int h, Pixmap bitmap) { if (lyxerr.debugging(Debug::GUI)) { @@ -244,7 +245,7 @@ PainterBase & Painter::pixmap(int x, int y, int w, int h, Pixmap bitmap) "workarea::workhandler\n"; lyxerr << "Painter drawable: " << owner.getPixmap() << endl; } - + XGCValues val; val.function = GXcopy; GC gc = XCreateGC(display, owner.getPixmap(), @@ -255,6 +256,13 @@ PainterBase & Painter::pixmap(int x, int y, int w, int h, Pixmap bitmap) return *this; } +PainterBase & Painter::image(int x, int y, int w, int h, LyXImage const * image) +{ + Pixmap bitmap = image->getPixmap(); + + return pixmap(x, y, w, h, bitmap); +} + PainterBase & Painter::text(int x, int y, string const & s, LyXFont const & f) { diff --git a/src/Painter.h b/src/Painter.h index 7225500072..35f0a1b8df 100644 --- a/src/Painter.h +++ b/src/Painter.h @@ -77,7 +77,10 @@ public: PainterBase & fillRectangle(int x, int y, int w, int h, LColor::color = LColor::background); - /// For the figure inset + /// For the graphics inset. + PainterBase & image(int x, int y, int w, int h, LyXImage const * image); + + /// For the figinset PainterBase & pixmap(int x, int y, int w, int h, Pixmap bitmap); /// Draw a string at position x, y (y is the baseline) diff --git a/src/PainterBase.h b/src/PainterBase.h index 47fa8c8993..2093646e10 100644 --- a/src/PainterBase.h +++ b/src/PainterBase.h @@ -20,6 +20,7 @@ class WorkArea; class LyXFont; +class LyXImage; /** A painter class to encapsulate all graphics parameters and operations @@ -146,9 +147,7 @@ public: // For the figure inset - // This can't be part of the base since we don't know what window - // system we will be useing, or if are going to use pixmaps at all. - //virtual PainterBase & pixmap(int x, int y, Pixmap bitmap)=0; + virtual PainterBase & image(int x, int y, int w, int h, LyXImage const * image) = 0; /// Draw a string at position x, y (y is the baseline) diff --git a/src/converter.C b/src/converter.C index b778351703..8103832070 100644 --- a/src/converter.C +++ b/src/converter.C @@ -263,7 +263,7 @@ Converter::GetReachable(string const & from, bool only_viewable) } -bool Converter::Convert(Buffer * buffer, string const & from_file, +bool Converter::Convert(Buffer const * buffer, string const & from_file, string const & to_file, string const & using_format, string * view_file) { diff --git a/src/converter.h b/src/converter.h index 92eb41e01f..33d45392c9 100644 --- a/src/converter.h +++ b/src/converter.h @@ -108,7 +108,7 @@ public: bool only_viewable = false); /// static - bool Convert(Buffer * buffer, string const & from_file, + bool Convert(Buffer const * buffer, string const & from_file, string const & to_file, string const & using_format, string * view_file = 0); /// diff --git a/src/filedlg.C b/src/filedlg.C index 43167d9d68..eea8a9e595 100644 --- a/src/filedlg.C +++ b/src/filedlg.C @@ -116,14 +116,7 @@ void UserCache::add(uid_t ID) const class GroupCache { public: /// seeks group name from group ID - string const & find(gid_t ID) const { - Groups::const_iterator cit = groups.find(ID); - if (cit == groups.end()) { - add(ID); - return groups[ID]; - } - return (*cit).second; - } + string const & find(gid_t ID) const ; private: /// void add(gid_t ID) const; @@ -133,6 +126,15 @@ private: mutable Groups groups; }; + string const & GroupCache::find(gid_t ID) const + { + Groups::const_iterator cit = groups.find(ID); + if (cit == groups.end()) { + add(ID); + return groups[ID]; + } + return (*cit).second; + } void GroupCache::add(gid_t ID) const { string pszNewName; @@ -161,6 +163,9 @@ extern "C" int C_LyXFileDlg_CancelCB(FL_FORM *, void *); class comp_direntry { public: int operator()(LyXDirEntry const & r1, + LyXDirEntry const & r2) const ; +}; + int comp_direntry::operator()(LyXDirEntry const & r1, LyXDirEntry const & r2) const { bool r1d = suffixIs(r1.pszName, '/'); bool r2d = suffixIs(r2.pszName, '/'); @@ -168,7 +173,6 @@ public: if (!r1d && r2d) return 0; return r1.pszName < r2.pszName; } -}; // *** LyXFileDlg class implementation diff --git a/src/frontends/Makefile.am b/src/frontends/Makefile.am index abe51ff8e4..88f076857f 100644 --- a/src/frontends/Makefile.am +++ b/src/frontends/Makefile.am @@ -4,7 +4,7 @@ MAINTAINERCLEANFILES = $(srcdir)/Makefile.in # xforms has to be fixed here as we still need object files in this directory # for the compilation of other frontends, so until that we have to let this # here. -SUBDIRS = xforms @FRONTEND@ +SUBDIRS = support xforms @FRONTEND@ ETAGS_ARGS = --lang=c++ BOOST_INCLUDES = -I$(top_srcdir)/boost INCLUDES = ${FRONTEND_INCLUDES} -I${srcdir}/.. -I${srcdir}/xforms ${SIGC_CFLAGS} $(BOOST_INCLUDES) diff --git a/src/frontends/support/.cvsignore b/src/frontends/support/.cvsignore new file mode 100644 index 0000000000..ff27baf37b --- /dev/null +++ b/src/frontends/support/.cvsignore @@ -0,0 +1,6 @@ +Makefile.in +Makefile +*.deps +*.lo +.libs +libfrontendsupport.la diff --git a/src/frontends/support/LyXImage.C b/src/frontends/support/LyXImage.C new file mode 100644 index 0000000000..ba8a5a624a --- /dev/null +++ b/src/frontends/support/LyXImage.C @@ -0,0 +1,25 @@ +// -*- C++ -*- +/* This file is part of + * ================================================= + * + * LyX, The Document Processor + * Copyright 1995 Matthias Ettrich. + * Copyright 1995-2000 The LyX Team. + * + * This file Copyright 2000 Baruch Even + * ================================================= */ + +#ifdef __GNUG__ +#pragma implementation +#endif + +#include +#include "LyXImage.h" + + +#ifndef X_DISPLAY_MISSING + #include "LyXImage_X.C" +#elif defined(DO_WINDOWS) + // Not implemented, for illustration only. + #include "LyXImage_Windows.C" +#endif diff --git a/src/frontends/support/LyXImage.h b/src/frontends/support/LyXImage.h new file mode 100644 index 0000000000..0c82a15e5a --- /dev/null +++ b/src/frontends/support/LyXImage.h @@ -0,0 +1,29 @@ +// -*- C++ -*- +/* This file is part of + * ================================================= + * + * LyX, The Document Processor + * Copyright 1995 Matthias Ettrich. + * Copyright 1995-2000 The LyX Team. + * + * This file Copyright 2000 Baruch Even + * ================================================= */ + +#ifndef LYXIMAGE_H +#define LYXIMAGE_H + +#ifdef __GNUG__ +#pragma interface +#endif + +// We need it to know what version to use. +#include + +#ifndef X_DISPLAY_MISSING + #include "LyXImage_X.h" +#elif defined(DO_WINDOWS) + // Not implemented, for illustration only. + #include "LyXImage_Windows.h" +#endif + +#endif diff --git a/src/frontends/support/LyXImage_X.C b/src/frontends/support/LyXImage_X.C new file mode 100644 index 0000000000..727429b2e1 --- /dev/null +++ b/src/frontends/support/LyXImage_X.C @@ -0,0 +1,43 @@ +// -*- C++ -*- +/* This file is part of + * ================================================= + * + * LyX, The Document Processor + * Copyright 1995 Matthias Ettrich. + * Copyright 1995-2000 The LyX Team. + * + * This file Copyright 2000 Baruch Even + * ================================================= */ + +#ifdef __GNUG__ +#pragma implementation +#endif + +#include +#include "LyXImage.h" + +#include FORMS_H_LOCATION + +#include "support/LAssert.h" + +LyXImage::LyXImage() + : pixmap_(0), pixmapInitialized(false) +{} + +LyXImage::LyXImage(Pixmap pixmap) + : pixmap_(pixmap), pixmapInitialized(true) +{} + +LyXImage::~LyXImage() +{ + if (pixmapInitialized) + XFreePixmap(fl_get_display(), pixmap_); +} + +Pixmap +LyXImage::getPixmap() const +{ + Assert(pixmapInitialized); + + return pixmap_; +} diff --git a/src/frontends/support/LyXImage_X.h b/src/frontends/support/LyXImage_X.h new file mode 100644 index 0000000000..575c64ebcf --- /dev/null +++ b/src/frontends/support/LyXImage_X.h @@ -0,0 +1,43 @@ +// -*- C++ -*- +/* This file is part of + * ================================================= + * + * LyX, The Document Processor + * Copyright 1995 Matthias Ettrich. + * Copyright 1995-2000 The LyX Team. + * + * This file Copyright 2000 Baruch Even + * ================================================= */ + +#ifndef LYXIMAGE_X_H +#define LYXIMAGE_X_H + +#ifdef __GNUG__ +#pragma interface +#endif + +#include "frontends/support/LyXImage.h" +#include + +// This class actually acts as a base class when X-Windows is used. + +class LyXImage { +public: + /// + LyXImage(); + /// + LyXImage(Pixmap pixmap); + /// + ~LyXImage(); + + /// + Pixmap getPixmap() const; + +private: + /// The pixmap itself. + Pixmap pixmap_; + /// Is the pixmap initialized? + bool pixmapInitialized; +}; + +#endif diff --git a/src/frontends/support/Makefile.am b/src/frontends/support/Makefile.am new file mode 100644 index 0000000000..34958972c2 --- /dev/null +++ b/src/frontends/support/Makefile.am @@ -0,0 +1,11 @@ +AUTOMAKE_OPTIONS = foreign 1.4 +DISTCLEANFILES= *.orig *.rej *~ *.bak core +MAINTAINERCLEANFILES = $(srcdir)/Makefile.in +noinst_LTLIBRARIES = libfrontendsupport.la +LIBS = +ETAGS_ARGS = --lang=c++ +INCLUDES = -I${srcdir}/../ $(SIGC_CFLAGS) + +libfrontendsupport_la_SOURCES = \ + LyXImage.h \ + LyXImage.C diff --git a/src/frontends/xforms/FormGraphics.C b/src/frontends/xforms/FormGraphics.C index e76c5d923a..d3501d5df8 100644 --- a/src/frontends/xforms/FormGraphics.C +++ b/src/frontends/xforms/FormGraphics.C @@ -56,9 +56,16 @@ FormGraphics::FormGraphics(LyXView * lv, Dialogs * d) // The buttons c-tor values are the number of buttons we use // This is only to reduce memory waste. widthButtons(5), heightButtons(4), displayButtons(4), + bc_(new ButtonController + (new NoRepeatedApplyReadOnlyPolicy, _("Cancel"), _("Close") ) + ), ih_(0), h_(0), u_(0), last_image_path(".") { + Assert(lv_ != 0); + Assert(d != 0); + Assert(bc_ != 0); + // let the dialog be shown // This is a permanent connection so we won't bother // storing a copy because we won't be disconnecting. @@ -69,6 +76,9 @@ FormGraphics::FormGraphics(LyXView * lv, Dialogs * d) FormGraphics::~FormGraphics() { free(); + + // Free the button controller. + delete bc_; } @@ -76,8 +86,10 @@ void FormGraphics::build() { dialog_ = build_graphics(); Assert(dialog_ != 0); - if (!dialog_) + if (!dialog_) { + lyxerr << "ERROR: Failed to create the Graphics Inset dialog." << endl; return ; + } // This is the place to add settings of the dialog that did not go // to the .fd file. @@ -145,6 +157,12 @@ void FormGraphics::build() // Connect a signal to hide the window when the window manager orders it. fl_set_form_atclose(dialog_->form, C_FormGraphicsWMHideCB, 0); + + bc_->setOK(dialog_->button_ok); + bc_->setApply(dialog_->button_apply); + bc_->setCancel(dialog_->button_cancel); + bc_->setUndoAll(0); + bc_->refresh(); } void FormGraphics::show() @@ -165,7 +183,7 @@ void FormGraphics::show() // Otherwise (invisible), show it. fl_show_form(dialog_->form, FL_PLACE_MOUSE, - FL_FULLBORDER, + FL_TRANSIENT, _("Graphics")); // And connect the signals 'updateBufferDependent', @@ -211,9 +229,6 @@ void FormGraphics::hide() // Forget the inset. inset_ = 0; } - // Most of the time, the dialog is not needed anymore, we'll free it - // now to save memory. - free(); } @@ -224,6 +239,7 @@ void FormGraphics::free() heightButtons.reset(); displayButtons.reset(); + // Free the form. delete dialog_; dialog_ = 0; @@ -311,10 +327,10 @@ void FormGraphics::update() igp.inlineFigure); // Now make sure that the buttons are set correctly. - input(); + checkInput(); } -void FormGraphics::input() +bool FormGraphics::checkInput() { // Put verifications that the dialog shows some sane values, // if not disallow clicking on ok/apply. @@ -358,19 +374,7 @@ void FormGraphics::input() inputOK = false; } - - // Now set the buttons to the correct state. - if (inputOK && ! lv_->buffer()->isReadonly()) { - fl_activate_object(dialog_->button_ok); - fl_activate_object(dialog_->button_apply); - fl_set_object_lcol(dialog_->button_ok, FL_BLACK); - fl_set_object_lcol(dialog_->button_apply, FL_BLACK); - } else { - fl_deactivate_object(dialog_->button_ok); - fl_deactivate_object(dialog_->button_apply); - fl_set_object_lcol(dialog_->button_ok, FL_INACTIVE); - fl_set_object_lcol(dialog_->button_apply, FL_INACTIVE); - } + return inputOK; } @@ -436,7 +440,7 @@ void FormGraphics::browse() // The above set input doesn't cause an input event so we do // it manually. Otherwise the user needs to cause an input event // to get the ok/apply buttons to be activated. - input(); + checkInput(); } } @@ -447,6 +451,9 @@ int FormGraphics::WMHideCB(FL_FORM * form, void *) // window manager is used to close the dialog. FormGraphics * pre = static_cast < FormGraphics* > (form->u_vdata); pre->hide(); + + pre->bc_->hide(); + return FL_CANCEL; } @@ -456,18 +463,24 @@ void FormGraphics::OKCB(FL_OBJECT * ob, long) FormGraphics * pre = static_cast < FormGraphics* > (ob->form->u_vdata); pre->apply(); pre->hide(); + + pre->bc_->ok(); } void FormGraphics::ApplyCB(FL_OBJECT * ob, long) { FormGraphics * pre = static_cast < FormGraphics* > (ob->form->u_vdata); pre->apply(); + + pre->bc_->apply(); } void FormGraphics::CancelCB(FL_OBJECT * ob, long) { FormGraphics * pre = static_cast < FormGraphics* > (ob->form->u_vdata); pre->hide(); + + pre->bc_->cancel(); } void FormGraphics::BrowseCB(FL_OBJECT * ob, long) @@ -488,6 +501,6 @@ void FormGraphics::AdvancedOptionsCB(FL_OBJECT * /* ob */, long) void FormGraphics::InputCB(FL_OBJECT * ob, long) { FormGraphics * pre = static_cast < FormGraphics* > (ob->form->u_vdata); - pre->input(); + pre->bc_->valid(pre->checkInput()); } diff --git a/src/frontends/xforms/FormGraphics.h b/src/frontends/xforms/FormGraphics.h index 88abccabce..8bc15e66d4 100644 --- a/src/frontends/xforms/FormGraphics.h +++ b/src/frontends/xforms/FormGraphics.h @@ -10,8 +10,6 @@ * Copyright 1995 Matthias Ettrich * Copyright 1995-2000 The LyX Team. * - * This file Copyright 2000 - * Baruch Even * ====================================================== */ @@ -22,19 +20,23 @@ #include "frontends/DialogBase.h" #include "RadioButtonGroup.h" #include +#include "ButtonController.h" +#include "ButtonPolicies.h" #ifdef __GNUG__ #pragma interface #endif +// Forward declarations for classes we use only as pointers. class Dialogs; -// same arguement as in Dialogs.h s/LyX/UI/ class LyXView; class InsetGraphics; struct FD_form_graphics; /** This class provides an XForms implementation of the FormGraphics Dialog. + * + * @Author Baruch Even */ class FormGraphics: public DialogBase, public noncopyable { public: @@ -91,7 +93,7 @@ private: /// Apply the changes to the inset. void apply(); /// Verify that the input is correct. If not disable ok/apply buttons. - void input(); + bool checkInput(); /// Open the file browse dialog to select an image file. void browse(); @@ -125,6 +127,8 @@ private: RadioButtonGroup heightButtons; /// RadioButtonGroup displayButtons; + /// Controls the actions of the buttons. + ButtonController * bc_; /// Inset Hide connection, connected to the calling inset hide signal. Connection ih_; diff --git a/src/graphics/GraphicsCache.C b/src/graphics/GraphicsCache.C index 534c984760..01103cc9d3 100644 --- a/src/graphics/GraphicsCache.C +++ b/src/graphics/GraphicsCache.C @@ -39,7 +39,7 @@ GraphicsCache::~GraphicsCache() // Free the map. //std::foreach(map.begin(), map.end(), ...); #warning This is a bogus reason to not clean up after your self. (Lgb) - // Clean up and be done with it. (Lgb) + // TODO: Clean up here (BE) // This is not really needed, it will only happen on program close and in // any case the OS will release those resources (not doing it may have diff --git a/src/graphics/GraphicsCacheItem.C b/src/graphics/GraphicsCacheItem.C index a92f0812b2..c113ee620e 100644 --- a/src/graphics/GraphicsCacheItem.C +++ b/src/graphics/GraphicsCacheItem.C @@ -18,6 +18,7 @@ #include "graphics/GraphicsCache.h" #include "graphics/GraphicsCacheItem.h" #include "graphics/GraphicsCacheItem_pimpl.h" +#include "frontends/support/LyXImage.h" GraphicsCacheItem::GraphicsCacheItem() @@ -63,6 +64,11 @@ GraphicsCacheItem::operator=(GraphicsCacheItem const & gci) return *this; } +GraphicsCacheItem * +GraphicsCacheItem::Clone() const +{ + return new GraphicsCacheItem(*this); +} void GraphicsCacheItem::copy(GraphicsCacheItem const & gci) @@ -78,7 +84,12 @@ GraphicsCacheItem::destroy() if (pimpl) { --(pimpl->refCount); if (pimpl->refCount == 0) { - delete pimpl; + { // We are deleting the pimpl but we want to mark it deleted + // even before it is deleted. + GraphicsCacheItem_pimpl * temp = pimpl; + pimpl = 0; + delete temp; + } GraphicsCache * gc = GraphicsCache::getInstance(); gc->removeFile(filename_); } @@ -97,6 +108,5 @@ GraphicsCacheItem::getHeight() const { return pimpl->height_; } int GraphicsCacheItem::getWidth() const { return pimpl->width_; } - -Pixmap +LyXImage * GraphicsCacheItem::getImage() const { return pimpl->pixmap_; } diff --git a/src/graphics/GraphicsCacheItem.h b/src/graphics/GraphicsCacheItem.h index 01843f46ce..0157d35c97 100644 --- a/src/graphics/GraphicsCacheItem.h +++ b/src/graphics/GraphicsCacheItem.h @@ -37,7 +37,7 @@ using SigC::Signal0; */ class GraphicsCacheItem_pimpl; - +class LyXImage; /// A GraphicsCache item holder. class GraphicsCacheItem { @@ -56,7 +56,7 @@ public: int getWidth() const; /// Return a pixmap that can be displayed on X server. - Pixmap getImage() const; + LyXImage * getImage() const; /// enum ImageStatus { /// @@ -66,6 +66,8 @@ public: /// ErrorReading, /// + UnknownError, + /// Loaded }; @@ -77,6 +79,9 @@ public: */ void imageConverted(int retval); + /// Create another copy of the object. + GraphicsCacheItem * Clone() const; + private: /// Private c-tor so that only GraphicsCache can create an instance. GraphicsCacheItem(); diff --git a/src/graphics/GraphicsCacheItem_pimpl.C b/src/graphics/GraphicsCacheItem_pimpl.C index dddc50da91..c9b2717165 100644 --- a/src/graphics/GraphicsCacheItem_pimpl.C +++ b/src/graphics/GraphicsCacheItem_pimpl.C @@ -22,6 +22,7 @@ #include "GraphicsCacheItem.h" #include "GraphicsCacheItem_pimpl.h" +#include "frontends/support/LyXImage.h" #include "graphics/XPM_Renderer.h" #include "graphics/EPS_Renderer.h" #include "support/filetools.h" @@ -43,7 +44,6 @@ GraphicsCacheItem_pimpl::~GraphicsCacheItem_pimpl() if (imageStatus_ == GraphicsCacheItem::Loaded) { XFreePixmap(fl_get_display(), pixmap_); } - delete renderer; } diff --git a/src/graphics/GraphicsCacheItem_pimpl.h b/src/graphics/GraphicsCacheItem_pimpl.h index ae819a75b2..b32fc47dc7 100644 --- a/src/graphics/GraphicsCacheItem_pimpl.h +++ b/src/graphics/GraphicsCacheItem_pimpl.h @@ -30,14 +30,7 @@ using SigC::Signal0; #endif -/* (Baruch Even 2000-08-05) - * This has a major drawback: it is only designed for X servers, no easy - * porting to non X-server based platform is offered right now, this is done - * in order to get a first version out of the door. - * - * Later versions should consider how to do this with more platform - * independence, this will probably involve changing the Painter class too. - */ +class LyXImage; /// A GraphicsCache item holder. class GraphicsCacheItem_pimpl { @@ -52,7 +45,7 @@ public: int getWidth() const; /// Return a pixmap that can be displayed on X server. - Pixmap getImage() const; + LyXImage * getImage() const; typedef GraphicsCacheItem::ImageStatus ImageStatus; @@ -88,7 +81,7 @@ private: /// Is the pixmap loaded? ImageStatus imageStatus_; /// The image pixmap - Pixmap pixmap_; + LyXImage * pixmap_; /// The rendering object. Renderer * renderer; diff --git a/src/graphics/Renderer.C b/src/graphics/Renderer.C index dcaa821944..1711d864b4 100644 --- a/src/graphics/Renderer.C +++ b/src/graphics/Renderer.C @@ -19,18 +19,17 @@ #include FORMS_H_LOCATION #include "support/filetools.h" +#include "frontends/support/LyXImage.h" Renderer::Renderer() : width_(0), height_(0), pixmapLoaded_(false) {} - - + Renderer::~Renderer() { freePixmap(); } - bool Renderer::setFilename(string const & filename) { // Make sure file exists and is readable. @@ -47,21 +46,17 @@ bool Renderer::setFilename(string const & filename) return true; } - bool Renderer::renderImage() { return false; } - bool Renderer::isImageFormatOK(string const & /*filename*/) const { return false; } - -void Renderer::setPixmap(Pixmap pixmap, - unsigned int width, unsigned int height) +void Renderer::setPixmap(LyXImage * pixmap, unsigned int width, unsigned int height) { freePixmap(); @@ -71,31 +66,24 @@ void Renderer::setPixmap(Pixmap pixmap, pixmapLoaded_ = true; } - -Pixmap Renderer::getPixmap() const +LyXImage * Renderer::getPixmap() const { return pixmap_; } - unsigned int Renderer::getWidth() const -{ - return width_; -} - +{ return width_; } unsigned int Renderer::getHeight() const { return height_; } - string const & Renderer::getFilename() const { return filename_; } - void Renderer::freePixmap() { if (pixmapLoaded_) diff --git a/src/graphics/Renderer.h b/src/graphics/Renderer.h index 4cf56d767a..d7402d5392 100644 --- a/src/graphics/Renderer.h +++ b/src/graphics/Renderer.h @@ -20,13 +20,17 @@ #include "LString.h" #include "X11/Xlib.h" -#include +#include "boost/utility.hpp" + +class LyXImage; /** Renderer is a base class that is used to take an image format, and - render it into a Pixmap in order to be able to display it later on - in LyX. Essentially it's job is to load an image format and create - a Pixmap from it. It also needs to do various transforms on the - image, like Rotation, Resize and color reduction. + * render it into a Pixmap in order to be able to display it later on + * in LyX. Essentially it's job is to load an image format and create + * a Pixmap from it. It also needs to do various transforms on the + * image, like Rotation, Resize and color reduction. + * + * @Author Baruch Even, */ class Renderer : public noncopyable { public: @@ -42,7 +46,7 @@ public: virtual bool renderImage() = 0; /// Get the last rendered pixmap. - Pixmap getPixmap() const; + LyXImage * getPixmap() const; /// Get the width of the pixmap. unsigned int getWidth() const; @@ -55,7 +59,7 @@ protected: virtual bool isImageFormatOK(string const & filename) const = 0; /// Set the pixmap. - void setPixmap(Pixmap pixmap, unsigned int width, unsigned int height); + void setPixmap(LyXImage * pixmap, unsigned int width, unsigned int height); /// string const & getFilename() const; @@ -66,7 +70,7 @@ private: /// The filename of the image file that we are responsible for. string filename_; /// The last rendered pixmap. - Pixmap pixmap_; + LyXImage * pixmap_; /// The width of the rendered pixmap. unsigned int width_; /// The height of the rendered pixmap. diff --git a/src/graphics/XPM_Renderer.C b/src/graphics/XPM_Renderer.C index 87075eabc6..b9fcbf07d6 100644 --- a/src/graphics/XPM_Renderer.C +++ b/src/graphics/XPM_Renderer.C @@ -15,6 +15,7 @@ #include #include "XPM_Renderer.h" +#include "frontends/support/LyXImage.h" #include FORMS_H_LOCATION #include XPM_H_LOCATION @@ -62,7 +63,7 @@ bool XPM_Renderer::renderImage() // This should have been set by the XpmReadFileToPixmap call! Assert(attrib.valuemask & XpmSize); - setPixmap(pixmap, attrib.width, attrib.height); + setPixmap(new LyXImage(pixmap), attrib.width, attrib.height); XpmFreeAttributes(&attrib); @@ -72,7 +73,7 @@ bool XPM_Renderer::renderImage() bool XPM_Renderer::isImageFormatOK(string const & filename) const { - std::ifstream is(filename.c_str()); + std::ifstream is(filename.c_str(), ios::in); // The signature of the file without the spaces. static const char str[] = "/*XPM*/"; diff --git a/src/insets/insetgraphics.C b/src/insets/insetgraphics.C index af5035b804..d750bd4848 100644 --- a/src/insets/insetgraphics.C +++ b/src/insets/insetgraphics.C @@ -15,8 +15,16 @@ How to use it for now: /* Immediate tasks: - * Add the GraphicsCache and FormatTranslator in order to get inline - viewing of the figures. + * Make the inline viewing work, there is a preliminary work going on, + need to finish it up. + + * Polishing tasks: + * Add messages in the empty rectangle 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. */ @@ -30,8 +38,11 @@ Known BUGS: by the file dialog we normally get an absolute path and this may not be what the user meant. * Bug in FileDlg class (src/filedlg.[hC]) when selecting a file and then - pressing ok, it counts as if no real selection done. Apparently it + 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 no + disabled. To enable it enable the define: + INSETGRAPHICS_INLINE_VIEW Current PROBLEMS: @@ -43,17 +54,12 @@ Current PROBLEMS: graphicx package docs it appears that it takes quite a bit of memory on the side of TeXing. - * How do we handle the inline viewing? we may need to show the same image - in several formats (color, monochrome, grayscale) or even in different - sizes, not to mention rotations! - TODO Basics: * Add support for more features so that it will be better than insetfig. * Keep aspect ratio radio button - * Create the GraphicsCache and FormatTranslator - * Add inline viewing of image. + * Work on inline viewing of image. TODO Before initial production release: * Replace insetfig everywhere @@ -63,7 +69,6 @@ TODO Before initial production release: // INSET_GRAPHICS: remove this when InsetFig is thrown. And act upon them. - * Pop up a dialog if the widget version is higher than what we accept. * 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 @@ -80,12 +85,14 @@ TODO Extended features: * Add a way to roll the image file into the file format. * When loading if the image is not found in the expected place, try to find it in the clipart, or in the same directory with the image. - * If the dialog had no real change from previous time, do not mark document - as changed. * Keep a tab on the image file, if it changes, update the lyx view. * The image choosing dialog could show thumbnails of the image formats it knows of, thus selection based on the image instead of based on filename. + * Add support for the 'picins' package. + * Add support for the 'picinpar' package. + * Improve support for 'subfigure' - Allow to set the various options + that are possible. */ /* NOTES: @@ -133,8 +140,6 @@ TODO Extended features: * PLAN: * Finish basic support: * Inline image viewing - * Get into lyx-devel as an unactivated inset for the benefit of those - * who really need it. * * Do Release quality support: * Allow to change display depth @@ -168,19 +173,23 @@ TODO Extended features: #include "LyXView.h" #include "buffer.h" #include "BufferView.h" +#include "converter.h" +#include "frontends/support/LyXImage.h" #include "Painter.h" #include "lyx_gui_misc.h" #include "filedlg.h" #include "support/FileInfo.h" #include "support/filetools.h" #include "lyxtext.h" - +#include "font.h" // For the lyxfont class. +#include // For the std::max + #include "debug.h" using std::ostream; using std::endl; - +using std::max; // Initialize only those variables that do not have a constructor. InsetGraphics::InsetGraphics() @@ -189,7 +198,7 @@ InsetGraphics::InsetGraphics() , keepaspectratio(false), scale(0.0), clip(false), draft(false) , cacheHandle(0) #endif - : cacheHandle(0), pixmapInitialized(false) + : cacheHandle(0), pixmap(0), pixmapInitialized(false) {} InsetGraphics::~InsetGraphics() @@ -198,6 +207,40 @@ InsetGraphics::~InsetGraphics() hide(); } +char const * +InsetGraphics::statusMessage() const +{ + char const * msg = 0; + +#ifdef INSETGRAPHICS_INLINE_VIEW + switch (status) { + case GraphicsCacheItem::UnknownError: + msg = _("Unknown Error"); + break; + + case GraphicsCacheItem::Loading: + msg = _("Loading..."); + break; + + case GraphicsCacheItem::ErrorReading: + msg = _("Error reading"); + break; + + case GraphicsCacheItem::ErrorConverting: + msg = _("Error converting"); + break; + + case GraphicsCacheItem::Loaded: + // No message to write. + break; + } +#else + msg = _("Inline view disabled"); +#endif + + return msg; +} + int InsetGraphics::ascent(BufferView *, LyXFont const &) const { if (pixmapInitialized) @@ -214,12 +257,16 @@ int InsetGraphics::descent(BufferView *, LyXFont const &) const } -int InsetGraphics::width(BufferView *, LyXFont const &) const +int InsetGraphics::width(BufferView *, LyXFont const & font) const { if (pixmapInitialized) return cacheHandle->getWidth(); - else - return 50; + else { + char const * msg = statusMessage(); + int font_width = lyxfont::width(msg, font); + + return max(50, font_width + 15); + } } @@ -236,22 +283,45 @@ void InsetGraphics::draw(BufferView * bv, LyXFont const & font, // we draw just a rectangle. if (pixmapInitialized) { - paint.pixmap(int(x) + 2, baseline - lascent, + paint.image(int(x) + 2, baseline - lascent, lwidth - 4, lascent + ldescent, pixmap); } else { - paint.rectangle(int(x) + 2, baseline - lascent, - lwidth - 4, - lascent + ldescent); - +#ifdef INSETGRAPHICS_INLINE_VIEW + // Get the image status, default to unknown error. + GraphicsCacheItem::ImageStatus status = GraphicsCacheItem::UnknownError; + if (cacheHandle) + status = cacheHandle->getImageStatus(); + // Check if the image is now ready. - if (cacheHandle && - (cacheHandle->getImageStatus() == GraphicsCacheItem::Loaded)) { + if (status == GraphicsCacheItem::Loaded) { + // It is, get it and inform the world. pixmap = cacheHandle->getImage(); pixmapInitialized = true; // Tell BufferView we need to be updated! bv->text->status = LyXText::CHANGED_IN_DRAW; + return; + } +#endif + + char const * msg = statusMessage(); + + paint.rectangle(int(x) + 2, baseline - lascent, + lwidth - 4, + lascent + ldescent); + + if (msg) { + // 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(x + 8), baseline - lyxfont::maxAscent(msgFont) - 4, + justname, msgFont); + + msgFont.setSize(LyXFont::SIZE_TINY); + paint.text(int(x + 8), baseline - 4, msg, strlen(msg), msgFont); } } @@ -585,8 +655,12 @@ int InsetGraphics::Latex(Buffer const *buf, ostream & os, } // How do we decide to what format should we export? - // cacheHandle->>export(ImageType::EPS); - // cacheHandle->>export(ImageType::PNG); + const string empty_string = string(); + const string eps_outfile = ChangeExtension(params.filename, "eps"); + const string png_outfile = ChangeExtension(params.filename, "png"); + + Converter::Convert(buf, params.filename, eps_outfile, empty_string); + Converter::Convert(buf, params.filename, png_outfile, empty_string); return 1; } @@ -627,10 +701,11 @@ void InsetGraphics::Validate(LaTeXFeatures & features) const // Update the inset after parameters changed (read from file or changed in // dialog. -void InsetGraphics::updateInset() +void InsetGraphics::updateInset() const { // If file changed... +#ifdef INSETGRAPHICS_INLINE_VIEW GraphicsCache * gc = GraphicsCache::getInstance(); GraphicsCacheItem * temp = 0; @@ -640,6 +715,9 @@ void InsetGraphics::updateInset() delete cacheHandle; cacheHandle = temp; +#else + cacheHandle = 0; +#endif } bool InsetGraphics::setParams(InsetGraphicsParams const & params) @@ -667,7 +745,10 @@ Inset * InsetGraphics::Clone(Buffer const &) const { InsetGraphics * newInset = new InsetGraphics; - newInset->cacheHandle = cacheHandle; + if (cacheHandle) + newInset->cacheHandle = cacheHandle->Clone(); + else + newInset->cacheHandle = 0; newInset->pixmap = pixmap; newInset->pixmapInitialized = pixmapInitialized; diff --git a/src/insets/insetgraphics.h b/src/insets/insetgraphics.h index ead8ed152c..8e17277614 100644 --- a/src/insets/insetgraphics.h +++ b/src/insets/insetgraphics.h @@ -32,6 +32,7 @@ using SigC::Object; #endif class Dialogs; +class LyXImage; /// #ifdef SIGC_CXX_NAMESPACES @@ -102,13 +103,15 @@ public: Signal0 hide; private: /// Update the inset after parameter change. - void updateInset(); + void updateInset() const; + /// Get the status message, depends on the image loading status. + char const * statusMessage() const; /// The graphics cache handle. - GraphicsCacheItem * cacheHandle; + mutable GraphicsCacheItem * cacheHandle; /// The pixmap - mutable Pixmap pixmap; + mutable LyXImage * pixmap; /// is the pixmap initialized? mutable bool pixmapInitialized; -- 2.39.5