]> git.lyx.org Git - lyx.git/blob - src/frontends/controllers/ControlExternal.C
fix crash due to invalidated iterator
[lyx.git] / src / frontends / controllers / ControlExternal.C
1 /**
2  * \file ControlExternal.C
3  * This file is part of LyX, the document processor.
4  * Licence details can be found in the file COPYING.
5  *
6  * \author Asger Alstrup
7  * \author John Levon
8  * \author Angus Leeming
9  *
10  * Full author contact details are available in file CREDITS.
11  */
12
13 #include <config.h>
14
15 #include "ControlExternal.h"
16
17 #include "funcrequest.h"
18 #include "gettext.h"
19 #include "helper_funcs.h"
20 #include "lyxrc.h"
21
22 #include "graphics/GraphicsCache.h"
23 #include "graphics/GraphicsCacheItem.h"
24 #include "graphics/GraphicsImage.h"
25
26 #include "insets/insetexternal.h"
27 #include "insets/ExternalSupport.h"
28 #include "insets/ExternalTemplate.h"
29
30 #include "support/filefilterlist.h"
31 #include "support/filetools.h"
32 #include "support/convert.h"
33
34 using std::advance;
35 using std::vector;
36 using std::string;
37
38 namespace lyx {
39
40 using support::FileFilterList;
41 using support::MakeAbsPath;
42 using support::readBB_from_PSFile;
43
44 namespace frontend {
45
46
47 ControlExternal::ControlExternal(Dialog & parent)
48         : Dialog::Controller(parent),
49           bb_changed_(false)
50 {}
51
52
53 bool ControlExternal::initialiseParams(string const & data)
54 {
55         params_.reset(new InsetExternalParams);
56         InsetExternalMailer::string2params(data, kernel().buffer(), *params_);
57         return true;
58 }
59
60
61 void ControlExternal::clearParams()
62 {
63         params_.reset();
64 }
65
66
67 void ControlExternal::dispatchParams()
68 {
69         string const lfun = InsetExternalMailer::params2string(params(),
70                                                                kernel().buffer());
71
72         kernel().dispatch(FuncRequest(getLfun(), lfun));
73 }
74
75
76 void ControlExternal::setParams(InsetExternalParams const & p)
77 {
78         BOOST_ASSERT(params_.get());
79         *params_ = p;
80 }
81
82
83 InsetExternalParams const & ControlExternal::params() const
84 {
85         BOOST_ASSERT(params_.get());
86         return *params_;
87 }
88
89
90 void ControlExternal::editExternal()
91 {
92         BOOST_ASSERT(params_.get());
93
94         dialog().view().apply();
95         string const lfun =
96                 InsetExternalMailer::params2string(params(), kernel().buffer());
97         kernel().dispatch(FuncRequest(LFUN_EXTERNAL_EDIT, lfun));
98 }
99
100
101 vector<string> const ControlExternal::getTemplates() const
102 {
103         vector<string> result;
104
105         external::TemplateManager::Templates::const_iterator i1, i2;
106         i1 = external::TemplateManager::get().getTemplates().begin();
107         i2 = external::TemplateManager::get().getTemplates().end();
108
109         for (; i1 != i2; ++i1) {
110                 result.push_back(i1->second.lyxName);
111         }
112         return result;
113 }
114
115
116 int ControlExternal::getTemplateNumber(string const & name) const
117 {
118         external::TemplateManager::Templates::const_iterator i1, i2;
119         i1 = external::TemplateManager::get().getTemplates().begin();
120         i2 = external::TemplateManager::get().getTemplates().end();
121         for (int i = 0; i1 != i2; ++i1, ++i) {
122                 if (i1->second.lyxName == name)
123                         return i;
124         }
125
126         // we can get here if a LyX document has a template not installed
127         // on this machine.
128         return -1;
129 }
130
131
132 external::Template ControlExternal::getTemplate(int i) const
133 {
134         external::TemplateManager::Templates::const_iterator i1
135                 = external::TemplateManager::get().getTemplates().begin();
136
137         advance(i1, i);
138
139         return i1->second;
140 }
141
142
143 string const ControlExternal::browse(string const & input,
144                                      string const & template_name) const
145 {
146         string const title =  _("Select external file");
147
148         string const bufpath = kernel().bufferFilepath();
149
150         /// Determine the template file extension
151         external::TemplateManager const & etm =
152                 external::TemplateManager::get();
153         external::Template const * const et_ptr =
154                 etm.getTemplateByName(template_name);
155
156         FileFilterList const filter = et_ptr ?
157                 FileFilterList(et_ptr->fileRegExp) :
158                 FileFilterList();
159
160         std::pair<string, string> dir1(N_("Documents|#o#O"),
161                                        string(lyxrc.document_path));
162
163         return browseRelFile(input, bufpath, title, filter, false, dir1);
164 }
165
166
167 string const ControlExternal::readBB(string const & file)
168 {
169         string const abs_file =
170                 MakeAbsPath(file, kernel().bufferFilepath());
171
172         // try to get it from the file, if possible. Zipped files are
173         // unzipped in the readBB_from_PSFile-Function
174         string const bb = readBB_from_PSFile(abs_file);
175         if (!bb.empty())
176                 return bb;
177
178         // we don't, so ask the Graphics Cache if it has loaded the file
179         int width = 0;
180         int height = 0;
181
182         graphics::Cache & gc = graphics::Cache::get();
183         if (gc.inCache(abs_file)) {
184                 graphics::Image const * image = gc.item(abs_file)->image();
185
186                 if (image) {
187                         width  = image->getWidth();
188                         height = image->getHeight();
189                 }
190         }
191
192         return ("0 0 " + convert<string>(width) + ' ' + convert<string>(height));
193 }
194
195 } // namespace frontend
196
197
198 namespace external {
199
200 namespace {
201
202 RotationDataType origins_array[] = {
203         RotationData::DEFAULT,
204         RotationData::TOPLEFT,
205         RotationData::BOTTOMLEFT,
206         RotationData::BASELINELEFT,
207         RotationData::CENTER,
208         RotationData::TOPCENTER,
209         RotationData::BOTTOMCENTER,
210         RotationData::BASELINECENTER,
211         RotationData::TOPRIGHT,
212         RotationData::BOTTOMRIGHT,
213         RotationData::BASELINERIGHT
214 };
215
216
217 size_type const origins_array_size =
218 sizeof(origins_array) / sizeof(origins_array[0]);
219
220 vector<RotationDataType> const
221 origins(origins_array, origins_array + origins_array_size);
222
223 // These are the strings, corresponding to the above, that the GUI should
224 // use. Note that they can/should be translated.
225 char const * const origin_gui_strs[] = {
226         N_("Default"),
227         N_("Top left"), N_("Bottom left"), N_("Baseline left"),
228         N_("Center"), N_("Top center"), N_("Bottom center"), N_("Baseline center"),
229         N_("Top right"), N_("Bottom right"), N_("Baseline right")
230 };
231
232 } // namespace anon
233
234
235 vector<RotationDataType> const & all_origins()
236 {
237         return origins;
238 }
239
240 string const origin_gui_str(size_type i)
241 {
242         return _(origin_gui_strs[i]);
243 }
244
245 } // namespace external
246 } // namespace lyx