]> git.lyx.org Git - lyx.git/blobdiff - src/frontends/controllers/ControlExternal.C
fix crash due to invalidated iterator
[lyx.git] / src / frontends / controllers / ControlExternal.C
index f9e357f5660b0672dc95916354decb2fa764a62e..556363ac50d1a6600b24391bb57a8275e2e4e98e 100644 (file)
-/* This file is part of
- * ====================================================== 
- *
- *           LyX, The Document Processor
- *
- *           Copyright 2001 The LyX Team.
- *
- * ======================================================
- *
+/**
  * \file ControlExternal.C
+ * This file is part of LyX, the document processor.
+ * Licence details can be found in the file COPYING.
+ *
  * \author Asger Alstrup
- * \author John Levon, moz@compsoc.man.ac.uk
- * \author Angus Leeming, a.leeming@ic.ac.uk
+ * \author John Levon
+ * \author Angus Leeming
+ *
+ * Full author contact details are available in file CREDITS.
  */
 
 #include <config.h>
 
-#include <utility>
-#include <vector>
+#include "ControlExternal.h"
 
-#ifdef __GNUG__
-#pragma implementation
-#endif
+#include "funcrequest.h"
+#include "gettext.h"
+#include "helper_funcs.h"
+#include "lyxrc.h"
 
-#include "ViewBase.h"
-#include "ButtonControllerBase.h"
-#include "ControlExternal.h"
-#include "buffer.h"
-#include "Dialogs.h"
-#include "Liason.h"
-#include "LyXView.h"
+#include "graphics/GraphicsCache.h"
+#include "graphics/GraphicsCacheItem.h"
+#include "graphics/GraphicsImage.h"
+
+#include "insets/insetexternal.h"
+#include "insets/ExternalSupport.h"
+#include "insets/ExternalTemplate.h"
+
+#include "support/filefilterlist.h"
 #include "support/filetools.h"
-#include "support/lstrings.h"
-#include "frontends/FileDialog.h"
-#include "frontends/Alert.h"
-#include "gettext.h"
-#include "BufferView.h"
+#include "support/convert.h"
 
-using std::make_pair;
+using std::advance;
 using std::vector;
+using std::string;
 
-ControlExternal::ControlExternal(LyXView & lv, Dialogs & d)
-       : ControlInset<InsetExternal, InsetExternal::Params>(lv, d)
-{
-       d_.showExternal.connect(SigC::slot(this, &ControlExternal::showInset));
-}
+namespace lyx {
 
+using support::FileFilterList;
+using support::MakeAbsPath;
+using support::readBB_from_PSFile;
+
+namespace frontend {
+
+
+ControlExternal::ControlExternal(Dialog & parent)
+       : Dialog::Controller(parent),
+         bb_changed_(false)
+{}
 
-InsetExternal::Params const ControlExternal::getParams(string const &)
-{
-       return InsetExternal::Params();
-}
 
-InsetExternal::Params const 
-ControlExternal::getParams(InsetExternal const & inset)
+bool ControlExternal::initialiseParams(string const & data)
 {
-       return inset.params();
+       params_.reset(new InsetExternalParams);
+       InsetExternalMailer::string2params(data, kernel().buffer(), *params_);
+       return true;
 }
 
 
-void ControlExternal::applyParamsToInset()
+void ControlExternal::clearParams()
 {
-       inset()->setFromParams(params());
-       lv_.view()->updateInset(inset(), true);
+       params_.reset();
 }
 
-void ControlExternal::editExternal()
-{
-       // fill the local, controller's copy of the Params struct with
-       // the contents of the dialog's fields.
-       view().apply();
 
-       // Create a local copy of the inset and initialise it with this
-       // params struct.
-       boost::scoped_ptr<InsetExternal> ie;
-       ie.reset(static_cast<InsetExternal *>(inset()->clone(*lv_.buffer())));
-       ie->setFromParams(params());
+void ControlExternal::dispatchParams()
+{
+       string const lfun = InsetExternalMailer::params2string(params(),
+                                                              kernel().buffer());
 
-       ie->editExternal();
+       kernel().dispatch(FuncRequest(getLfun(), lfun));
 }
 
-void ControlExternal::viewExternal()
+
+void ControlExternal::setParams(InsetExternalParams const & p)
 {
-       view().apply();
+       BOOST_ASSERT(params_.get());
+       *params_ = p;
+}
 
-       boost::scoped_ptr<InsetExternal> ie;
-       ie.reset(static_cast<InsetExternal *>(inset()->clone(*lv_.buffer())));
-       ie->setFromParams(params());
 
-       ie->viewExternal();
+InsetExternalParams const & ControlExternal::params() const
+{
+       BOOST_ASSERT(params_.get());
+       return *params_;
 }
 
-void ControlExternal::updateExternal()
-{
-       view().apply();
 
-       boost::scoped_ptr<InsetExternal> ie;
-       ie.reset(static_cast<InsetExternal *>(inset()->clone(*lv_.buffer())));
-       ie->setFromParams(params());
+void ControlExternal::editExternal()
+{
+       BOOST_ASSERT(params_.get());
 
-       ie->updateExternal();
+       dialog().view().apply();
+       string const lfun =
+               InsetExternalMailer::params2string(params(), kernel().buffer());
+       kernel().dispatch(FuncRequest(LFUN_EXTERNAL_EDIT, lfun));
 }
 
+
 vector<string> const ControlExternal::getTemplates() const
 {
        vector<string> result;
 
-       ExternalTemplateManager::Templates::const_iterator i1, i2;
-       i1 = ExternalTemplateManager::get().getTemplates().begin();
-       i2 = ExternalTemplateManager::get().getTemplates().end();
+       external::TemplateManager::Templates::const_iterator i1, i2;
+       i1 = external::TemplateManager::get().getTemplates().begin();
+       i2 = external::TemplateManager::get().getTemplates().end();
 
        for (; i1 != i2; ++i1) {
                result.push_back(i1->second.lyxName);
@@ -118,15 +115,12 @@ vector<string> const ControlExternal::getTemplates() const
 
 int ControlExternal::getTemplateNumber(string const & name) const
 {
-       int i = 0;
-
-       ExternalTemplateManager::Templates::const_iterator i1, i2;
-       i1 = ExternalTemplateManager::get().getTemplates().begin();
-       i2 = ExternalTemplateManager::get().getTemplates().end();
-       for (; i1 != i2; ++i1) {
+       external::TemplateManager::Templates::const_iterator i1, i2;
+       i1 = external::TemplateManager::get().getTemplates().begin();
+       i2 = external::TemplateManager::get().getTemplates().end();
+       for (int i = 0; i1 != i2; ++i1, ++i) {
                if (i1->second.lyxName == name)
                        return i;
-               ++i;
        }
 
        // we can get here if a LyX document has a template not installed
@@ -135,71 +129,118 @@ int ControlExternal::getTemplateNumber(string const & name) const
 }
 
 
-ExternalTemplate ControlExternal::getTemplate(int i) const
+external::Template ControlExternal::getTemplate(int i) const
 {
-       ExternalTemplateManager::Templates::const_iterator i1;
-       i1 = ExternalTemplateManager::get().getTemplates().begin();
-       for (int n = 1; n < i; ++n)
-               ++i1;
+       external::TemplateManager::Templates::const_iterator i1
+               = external::TemplateManager::get().getTemplates().begin();
+
+       advance(i1, i);
 
        return i1->second;
 }
 
 
-string const ControlExternal::Browse(string const & input) const
+string const ControlExternal::browse(string const & input,
+                                    string const & template_name) const
 {
-       string buf  = MakeAbsPath(lv_.buffer()->fileName());
-       string buf2 = OnlyPath(buf);
-
-       if (!input.empty()) {
-               buf = MakeAbsPath(input, buf2);
-               buf = OnlyPath(buf);
-       } else {
-               buf = OnlyPath(lv_.buffer()->fileName());
-       }
-    
-       FileDialog fileDlg(&lv_,
-                          _("Select external file"),
-                          LFUN_SELECT_FILE_SYNC,
-                          make_pair(string(_("Document")), string(buf)));
-       
+       string const title =  _("Select external file");
+
+       string const bufpath = kernel().bufferFilepath();
+
        /// Determine the template file extension
-       ExternalTemplate const & et = params().templ;
-
-       string regexp = et.fileRegExp;
-       if (regexp.empty())
-               regexp = "*";
-
-       // FIXME: a temporary hack until the FileDialog interface is updated
-       regexp += "|";
-
-       static int once;
-       string current_path;
-
-       while (1) {
-               string const path = (once) ? current_path : buf;
-               FileDialog::Result result = fileDlg.Select(path, regexp, input);
-
-               if (result.second.empty())
-                       return string();
-
-               string p = result.second;
-
-               buf = MakeRelPath(p, buf2);
-               current_path = OnlyPath(p);
-               once = 1;
-               
-               if (contains(p, "#") ||
-                   contains(p, "~") ||
-                   contains(p, "$") ||
-                   contains(p, "%")) {
-                       Alert::alert(_("Filename can't contain any "
-                                    "of these characters:"),
-                                  // xgettext:no-c-format
-                                  _("'#', '~', '$' or '%'."));
-               } else
-                       break;
+       external::TemplateManager const & etm =
+               external::TemplateManager::get();
+       external::Template const * const et_ptr =
+               etm.getTemplateByName(template_name);
+
+       FileFilterList const filter = et_ptr ?
+               FileFilterList(et_ptr->fileRegExp) :
+               FileFilterList();
+
+       std::pair<string, string> dir1(N_("Documents|#o#O"),
+                                      string(lyxrc.document_path));
+
+       return browseRelFile(input, bufpath, title, filter, false, dir1);
+}
+
+
+string const ControlExternal::readBB(string const & file)
+{
+       string const abs_file =
+               MakeAbsPath(file, kernel().bufferFilepath());
+
+       // try to get it from the file, if possible. Zipped files are
+       // unzipped in the readBB_from_PSFile-Function
+       string const bb = readBB_from_PSFile(abs_file);
+       if (!bb.empty())
+               return bb;
+
+       // we don't, so ask the Graphics Cache if it has loaded the file
+       int width = 0;
+       int height = 0;
+
+       graphics::Cache & gc = graphics::Cache::get();
+       if (gc.inCache(abs_file)) {
+               graphics::Image const * image = gc.item(abs_file)->image();
+
+               if (image) {
+                       width  = image->getWidth();
+                       height = image->getHeight();
+               }
        }
 
-       return buf;
+       return ("0 0 " + convert<string>(width) + ' ' + convert<string>(height));
+}
+
+} // namespace frontend
+
+
+namespace external {
+
+namespace {
+
+RotationDataType origins_array[] = {
+       RotationData::DEFAULT,
+       RotationData::TOPLEFT,
+       RotationData::BOTTOMLEFT,
+       RotationData::BASELINELEFT,
+       RotationData::CENTER,
+       RotationData::TOPCENTER,
+       RotationData::BOTTOMCENTER,
+       RotationData::BASELINECENTER,
+       RotationData::TOPRIGHT,
+       RotationData::BOTTOMRIGHT,
+       RotationData::BASELINERIGHT
+};
+
+
+size_type const origins_array_size =
+sizeof(origins_array) / sizeof(origins_array[0]);
+
+vector<RotationDataType> const
+origins(origins_array, origins_array + origins_array_size);
+
+// These are the strings, corresponding to the above, that the GUI should
+// use. Note that they can/should be translated.
+char const * const origin_gui_strs[] = {
+       N_("Default"),
+       N_("Top left"), N_("Bottom left"), N_("Baseline left"),
+       N_("Center"), N_("Top center"), N_("Bottom center"), N_("Baseline center"),
+       N_("Top right"), N_("Bottom right"), N_("Baseline right")
+};
+
+} // namespace anon
+
+
+vector<RotationDataType> const & all_origins()
+{
+       return origins;
 }
+
+string const origin_gui_str(size_type i)
+{
+       return _(origin_gui_strs[i]);
+}
+
+} // namespace external
+} // namespace lyx