]> git.lyx.org Git - lyx.git/blob - src/callback.cpp
XXXX --> ??
[lyx.git] / src / callback.cpp
1 /**
2  * \file callback.cpp
3  * This file is part of LyX, the document processor.
4  * Licence details can be found in the file COPYING.
5  *
6  * \author Lars Gullik Bjønnes
7  * \author Angus Leeming
8  * \author John Levon
9  * \author André Pönitz
10  * \author Jürgen Vigna
11  *
12  * Full author contact details are available in file CREDITS.
13  */
14
15 #include <config.h>
16
17 #include "callback.h"
18
19 #include "Buffer.h"
20 #include "BufferList.h"
21 #include "BufferView.h"
22 #include "buffer_funcs.h"
23 #include "Cursor.h"
24 #include "CutAndPaste.h"
25 #include "debug.h"
26 #include "gettext.h"
27 #include "Session.h"
28 #include "LaTeXFeatures.h"
29 #include "LyX.h"
30 #include "Layout.h"
31 #include "LyXRC.h"
32 #include "Text.h"
33 #include "Undo.h"
34
35 #include "frontends/alert.h"
36 #include "frontends/Application.h"
37 #include "frontends/FileDialog.h"
38 #include "frontends/LyXView.h"
39
40 #include "support/FileFilterList.h"
41 #include "support/filetools.h"
42 #include "support/Forkedcall.h"
43 #include "support/fs_extras.h"
44 #include "support/lyxlib.h"
45 #include "support/Package.h"
46 #include "support/Path.h"
47 #include "support/Systemcall.h"
48
49 #if !defined (HAVE_FORK)
50 # define fork() -1
51 #endif
52
53 #include <boost/shared_ptr.hpp>
54 #include <boost/filesystem/operations.hpp>
55
56 #include <cerrno>
57 #include <fstream>
58
59 using std::back_inserter;
60 using std::copy;
61 using std::endl;
62 using std::make_pair;
63 using std::string;
64 using std::ifstream;
65 using std::ios;
66 using std::istream_iterator;
67
68 using boost::shared_ptr;
69 namespace fs = boost::filesystem;
70
71 namespace lyx {
72
73 using support::bformat;
74 using support::FileFilterList;
75 using support::FileName;
76 using support::ForkedProcess;
77 using support::isLyXFilename;
78 using support::libFileSearch;
79 using support::makeAbsPath;
80 using support::makeDisplayPath;
81 using support::onlyFilename;
82 using support::onlyPath;
83 using support::package;
84 using support::removeAutosaveFile;
85 using support::rename;
86 using support::split;
87 using support::Systemcall;
88 using support::tempName;
89 using support::unlink;
90 using frontend::LyXView;
91
92 namespace Alert = frontend::Alert;
93
94 //
95 // Copyright CHT Software Service GmbH
96 // Uwe C. Schroeder
97 //
98 // create new file with template
99 // SERVERCMD !
100 //
101 void newFile(LyXView & lv, string const & filename)
102 {
103         // Split argument by :
104         string name;
105         string tmpname = split(filename, name, ':');
106         LYXERR(Debug::INFO) << "Arg is " << filename
107                             << "\nName is " << name
108                             << "\nTemplate is " << tmpname << endl;
109
110         Buffer * const b = newFile(name, tmpname);
111         if (b)
112                 lv.setBuffer(b);
113 }
114
115
116 // Insert plain text file (if filename is empty, prompt for one)
117 void insertPlaintextFile(BufferView * bv, string const & f, bool asParagraph)
118 {
119         docstring const tmpstr =
120           getContentsOfPlaintextFile(bv, f, asParagraph);
121
122         if (tmpstr.empty())
123                 return;
124
125         Cursor & cur = bv->cursor();
126         cap::replaceSelection(cur);
127         recordUndo(cur);
128         if (asParagraph)
129                 cur.innerText()->insertStringAsParagraphs(cur, tmpstr);
130         else
131                 cur.innerText()->insertStringAsLines(cur, tmpstr);
132 }
133
134
135 docstring const getContentsOfPlaintextFile(BufferView * bv, string const & f,
136                                            bool asParagraph)
137 {
138         FileName fname(f);
139
140         if (fname.empty()) {
141                 FileDialog fileDlg(_("Select file to insert"),
142                                    ( (asParagraph)
143                                      ? LFUN_FILE_INSERT_PLAINTEXT_PARA 
144                                      : LFUN_FILE_INSERT_PLAINTEXT) );
145
146                 FileDialog::Result result =
147                         fileDlg.open(from_utf8(bv->buffer().filePath()),
148                                      FileFilterList(), docstring());
149
150                 if (result.first == FileDialog::Later)
151                         return docstring();
152
153                 fname = makeAbsPath(to_utf8(result.second));
154
155                 if (fname.empty())
156                         return docstring();
157         }
158
159         if (!fs::is_readable(fname.toFilesystemEncoding())) {
160                 docstring const error = from_ascii(strerror(errno));
161                 docstring const file = makeDisplayPath(fname.absFilename(), 50);
162                 docstring const text =
163                   bformat(_("Could not read the specified document\n"
164                             "%1$s\ndue to the error: %2$s"), file, error);
165                 Alert::error(_("Could not read file"), text);
166                 return docstring();
167         }
168
169         ifstream ifs(fname.toFilesystemEncoding().c_str());
170         if (!ifs) {
171                 docstring const error = from_ascii(strerror(errno));
172                 docstring const file = makeDisplayPath(fname.absFilename(), 50);
173                 docstring const text =
174                   bformat(_("Could not open the specified document\n"
175                             "%1$s\ndue to the error: %2$s"), file, error);
176                 Alert::error(_("Could not open file"), text);
177                 return docstring();
178         }
179
180         ifs.unsetf(ios::skipws);
181         istream_iterator<char> ii(ifs);
182         istream_iterator<char> end;
183 #if !defined(USE_INCLUDED_STRING) && !defined(STD_STRING_IS_GOOD)
184         // We use this until the compilers get better...
185         std::vector<char> tmp;
186         copy(ii, end, back_inserter(tmp));
187         string const tmpstr(tmp.begin(), tmp.end());
188 #else
189         // This is what we want to use and what we will use once the
190         // compilers get good enough.
191         //string tmpstr(ii, end); // yet a reason for using std::string
192         // alternate approach to get the file into a string:
193         string tmpstr;
194         copy(ii, end, back_inserter(tmpstr));
195 #endif
196
197         // FIXME UNICODE: We don't know the encoding of the file
198         docstring file_content = from_utf8(tmpstr);
199         if (file_content.empty()) {
200                 Alert::error(_("Reading not UTF-8 encoded file"),
201                              _("The file is not UTF-8 encoded.\n"
202                                "It will be read as local 8Bit-encoded.\n"
203                                "If this does not give the correct result\n"
204                                "then please change the encoding of the file\n"
205                                "to UTF-8 with a program other than LyX.\n"));
206                 file_content = from_local8bit(tmpstr);
207         }
208
209         return normalize_c(file_content);
210 }
211
212
213 // This function runs "configure" and then rereads lyx.defaults to
214 // reconfigure the automatic settings.
215 void reconfigure(LyXView & lv, string const & option)
216 {
217         // emit message signal.
218         lv.message(_("Running configure..."));
219
220         // Run configure in user lyx directory
221         support::Path p(package().user_support());
222         string configure_command = package().configure_command();
223         configure_command += option;
224         Systemcall one;
225         one.startscript(Systemcall::Wait, configure_command);
226         p.pop();
227         // emit message signal.
228         lv.message(_("Reloading configuration..."));
229         lyxrc.read(libFileSearch(string(), "lyxrc.defaults"));
230         // Re-read packages.lst
231         LaTeXFeatures::getAvailable();
232
233         Alert::information(_("System reconfigured"),
234                            _("The system has been reconfigured.\n"
235                              "You need to restart LyX to make use of any\n"
236                              "updated document class specifications."));
237 }
238
239
240 } // namespace lyx