summaryrefslogtreecommitdiff
path: root/library/filemanager.cpp
Unidiff
Diffstat (limited to 'library/filemanager.cpp') (more/less context) (ignore whitespace changes)
-rw-r--r--library/filemanager.cpp3
1 files changed, 0 insertions, 3 deletions
diff --git a/library/filemanager.cpp b/library/filemanager.cpp
index 408be20..1e7384e 100644
--- a/library/filemanager.cpp
+++ b/library/filemanager.cpp
@@ -1,411 +1,408 @@
1/********************************************************************** 1/**********************************************************************
2** Copyright (C) 2000 Trolltech AS. All rights reserved. 2** Copyright (C) 2000 Trolltech AS. All rights reserved.
3** 3**
4** This file is part of Qtopia Environment. 4** This file is part of Qtopia Environment.
5** 5**
6** This file may be distributed and/or modified under the terms of the 6** This file may be distributed and/or modified under the terms of the
7** GNU General Public License version 2 as published by the Free Software 7** GNU General Public License version 2 as published by the Free Software
8** Foundation and appearing in the file LICENSE.GPL included in the 8** Foundation and appearing in the file LICENSE.GPL included in the
9** packaging of this file. 9** packaging of this file.
10** 10**
11** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE 11** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
12** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. 12** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
13** 13**
14** See http://www.trolltech.com/gpl/ for GPL licensing information. 14** See http://www.trolltech.com/gpl/ for GPL licensing information.
15** 15**
16** Contact info@trolltech.com if any conditions of this licensing are 16** Contact info@trolltech.com if any conditions of this licensing are
17** not clear to you. 17** not clear to you.
18** 18**
19**********************************************************************/ 19**********************************************************************/
20#include "filemanager.h" 20#include "filemanager.h"
21#include "applnk.h" 21#include "applnk.h"
22 22
23#include <qdir.h>
24#include <qfile.h>
25#include <qfileinfo.h> 23#include <qfileinfo.h>
26#include <qtextstream.h> 24#include <qtextstream.h>
27#include <qtextcodec.h>
28 25
29#include <errno.h> 26#include <errno.h>
30#include <stdlib.h> 27#include <stdlib.h>
31#include <unistd.h> 28#include <unistd.h>
32#include <sys/stat.h> 29#include <sys/stat.h>
33#include <dirent.h> 30#include <dirent.h>
34#ifdef Q_OS_MACX 31#ifdef Q_OS_MACX
35// MacOS X does not have sendfile.. :( 32// MacOS X does not have sendfile.. :(
36// But maybe in the future.. !? 33// But maybe in the future.. !?
37# ifdef SENDFILE 34# ifdef SENDFILE
38# include <sys/types.h> 35# include <sys/types.h>
39# include <sys/socket.h> 36# include <sys/socket.h>
40# endif 37# endif
41#else 38#else
42# include <sys/sendfile.h> 39# include <sys/sendfile.h>
43#endif /* Q_OS_MACX */ 40#endif /* Q_OS_MACX */
44#include <fcntl.h> 41#include <fcntl.h>
45 42
46/*! 43/*!
47 \class FileManager 44 \class FileManager
48 \brief The FileManager class assists with AppLnk input/output. 45 \brief The FileManager class assists with AppLnk input/output.
49*/ 46*/
50 47
51/*! 48/*!
52 Constructs a FileManager. 49 Constructs a FileManager.
53*/ 50*/
54FileManager::FileManager() 51FileManager::FileManager()
55{ 52{
56} 53}
57 54
58/*! 55/*!
59 Destroys a FileManager. 56 Destroys a FileManager.
60*/ 57*/
61FileManager::~FileManager() 58FileManager::~FileManager()
62{ 59{
63 60
64} 61}
65 62
66/*! 63/*!
67 Saves \a data as the document specified by \a f. 64 Saves \a data as the document specified by \a f.
68 65
69 Returns whether the operation succeeded. 66 Returns whether the operation succeeded.
70*/ 67*/
71bool FileManager::saveFile( const DocLnk &f, const QByteArray &data ) 68bool FileManager::saveFile( const DocLnk &f, const QByteArray &data )
72{ 69{
73 QString fn = f.file() + ".new"; 70 QString fn = f.file() + ".new";
74 ensurePathExists( fn ); 71 ensurePathExists( fn );
75 QFile fl( fn ); 72 QFile fl( fn );
76 if ( !fl.open( IO_WriteOnly|IO_Raw ) ) { 73 if ( !fl.open( IO_WriteOnly|IO_Raw ) ) {
77 qWarning("open failed"); 74 qWarning("open failed");
78 return FALSE; 75 return FALSE;
79 } 76 }
80 int total_written = fl.writeBlock( data ); 77 int total_written = fl.writeBlock( data );
81 fl.close(); 78 fl.close();
82 if ( total_written != int(data.size()) || !f.writeLink() ) { 79 if ( total_written != int(data.size()) || !f.writeLink() ) {
83 QFile::remove( fn ); 80 QFile::remove( fn );
84 return FALSE; 81 return FALSE;
85 } 82 }
86 qDebug("total written %d out of %d", total_written, data.size()); 83 qDebug("total written %d out of %d", total_written, data.size());
87 // else rename the file... 84 // else rename the file...
88 if ( !renameFile( fn.latin1(), f.file().latin1() ) ) { 85 if ( !renameFile( fn.latin1(), f.file().latin1() ) ) {
89 qWarning( "problem renaming file %s to %s, errno: %d", fn.latin1(), 86 qWarning( "problem renaming file %s to %s, errno: %d", fn.latin1(),
90 f.file().latin1(), errno ); 87 f.file().latin1(), errno );
91 // remove the file... 88 // remove the file...
92 } 89 }
93 return TRUE; 90 return TRUE;
94} 91}
95 92
96/*! 93/*!
97 Saves \a text as the document specified by \a f. 94 Saves \a text as the document specified by \a f.
98 95
99 The text is saved in UTF8 format. 96 The text is saved in UTF8 format.
100 97
101 Returns whether the operation succeeded. 98 Returns whether the operation succeeded.
102*/ 99*/
103bool FileManager::saveFile( const DocLnk &f, const QString &text ) 100bool FileManager::saveFile( const DocLnk &f, const QString &text )
104{ 101{
105 QString fn = f.file() + ".new"; 102 QString fn = f.file() + ".new";
106 ensurePathExists( fn ); 103 ensurePathExists( fn );
107 QFile fl( fn ); 104 QFile fl( fn );
108 if ( !fl.open( IO_WriteOnly|IO_Raw ) ) { 105 if ( !fl.open( IO_WriteOnly|IO_Raw ) ) {
109 qWarning("open failed"); 106 qWarning("open failed");
110 return FALSE; 107 return FALSE;
111 } 108 }
112 109
113 QCString cstr = text.utf8(); 110 QCString cstr = text.utf8();
114 int total_written; 111 int total_written;
115 total_written = fl.writeBlock( cstr.data(), cstr.length() ); 112 total_written = fl.writeBlock( cstr.data(), cstr.length() );
116 fl.close(); 113 fl.close();
117 if ( total_written != int(cstr.length()) || !f.writeLink() ) { 114 if ( total_written != int(cstr.length()) || !f.writeLink() ) {
118 QFile::remove( fn ); 115 QFile::remove( fn );
119 return FALSE; 116 return FALSE;
120 } 117 }
121 // okay now rename the file.. 118 // okay now rename the file..
122 if ( !renameFile( fn.latin1(), f.file().latin1() ) ) { 119 if ( !renameFile( fn.latin1(), f.file().latin1() ) ) {
123 qWarning( "problem renaming file %s to %s, errno: %d", fn.latin1(), 120 qWarning( "problem renaming file %s to %s, errno: %d", fn.latin1(),
124 f.file().latin1(), errno ); 121 f.file().latin1(), errno );
125 122
126 } 123 }
127 return TRUE; 124 return TRUE;
128} 125}
129 126
130 127
131/*! 128/*!
132 Loads \a text from the document specified by \a f. 129 Loads \a text from the document specified by \a f.
133 130
134 The text is required to be in UTF8 format. 131 The text is required to be in UTF8 format.
135 132
136 Returns whether the operation succeeded. 133 Returns whether the operation succeeded.
137*/ 134*/
138bool FileManager::loadFile( const DocLnk &f, QString &text ) 135bool FileManager::loadFile( const DocLnk &f, QString &text )
139{ 136{
140 QString fn = f.file(); 137 QString fn = f.file();
141 QFile fl( fn ); 138 QFile fl( fn );
142 if ( !fl.open( IO_ReadOnly ) ) 139 if ( !fl.open( IO_ReadOnly ) )
143 return FALSE; 140 return FALSE;
144 QTextStream ts( &fl ); 141 QTextStream ts( &fl );
145#if QT_VERSION <= 230 && defined(QT_NO_CODECS) 142#if QT_VERSION <= 230 && defined(QT_NO_CODECS)
146 // The below should work, but doesn't in Qt 2.3.0 143 // The below should work, but doesn't in Qt 2.3.0
147 ts.setCodec( QTextCodec::codecForMib( 106 ) ); 144 ts.setCodec( QTextCodec::codecForMib( 106 ) );
148#else 145#else
149 ts.setEncoding( QTextStream::UnicodeUTF8 ); 146 ts.setEncoding( QTextStream::UnicodeUTF8 );
150#endif 147#endif
151 text = ts.read(); 148 text = ts.read();
152 fl.close(); 149 fl.close();
153 return TRUE; 150 return TRUE;
154} 151}
155 152
156 153
157/*! 154/*!
158 Loads \a ba from the document specified by \a f. 155 Loads \a ba from the document specified by \a f.
159 156
160 Returns whether the operation succeeded. 157 Returns whether the operation succeeded.
161*/ 158*/
162bool FileManager::loadFile( const DocLnk &f, QByteArray &ba ) 159bool FileManager::loadFile( const DocLnk &f, QByteArray &ba )
163{ 160{
164 QString fn = f.file(); 161 QString fn = f.file();
165 QFile fl( fn ); 162 QFile fl( fn );
166 if ( !fl.open( IO_ReadOnly ) ) 163 if ( !fl.open( IO_ReadOnly ) )
167 return FALSE; 164 return FALSE;
168 ba.resize( fl.size() ); 165 ba.resize( fl.size() );
169 if ( fl.size() > 0 ) 166 if ( fl.size() > 0 )
170 fl.readBlock( ba.data(), fl.size() ); 167 fl.readBlock( ba.data(), fl.size() );
171 fl.close(); 168 fl.close();
172 return TRUE; 169 return TRUE;
173} 170}
174 171
175/*! 172/*!
176 Copies the document specified by \a src to the document specified 173 Copies the document specified by \a src to the document specified
177 by \a dest. 174 by \a dest.
178 175
179 Returns whether the operation succeeded. 176 Returns whether the operation succeeded.
180*/ 177*/
181bool FileManager::copyFile( const AppLnk &src, const AppLnk &dest ) 178bool FileManager::copyFile( const AppLnk &src, const AppLnk &dest )
182{ 179{
183 QFile sf( src.file() ); 180 QFile sf( src.file() );
184 if ( !sf.open( IO_ReadOnly ) ) 181 if ( !sf.open( IO_ReadOnly ) )
185 return FALSE; 182 return FALSE;
186 183
187 QString fn = dest.file() + ".new"; 184 QString fn = dest.file() + ".new";
188 ensurePathExists( fn ); 185 ensurePathExists( fn );
189 QFile df( fn ); 186 QFile df( fn );
190 if ( !df.open( IO_WriteOnly|IO_Raw ) ) 187 if ( !df.open( IO_WriteOnly|IO_Raw ) )
191 return FALSE; 188 return FALSE;
192 189
193 const int bufsize = 16384; 190 const int bufsize = 16384;
194 char buffer[bufsize]; 191 char buffer[bufsize];
195 bool ok = TRUE; 192 bool ok = TRUE;
196 int bytesRead = 0; 193 int bytesRead = 0;
197 while ( ok && !sf.atEnd() ) { 194 while ( ok && !sf.atEnd() ) {
198 bytesRead = sf.readBlock( buffer, bufsize ); 195 bytesRead = sf.readBlock( buffer, bufsize );
199 if ( bytesRead < 0 ) 196 if ( bytesRead < 0 )
200 ok = FALSE; 197 ok = FALSE;
201 while ( ok && bytesRead > 0 ) { 198 while ( ok && bytesRead > 0 ) {
202 int bytesWritten = df.writeBlock( buffer, bytesRead ); 199 int bytesWritten = df.writeBlock( buffer, bytesRead );
203 if ( bytesWritten < 0 ) 200 if ( bytesWritten < 0 )
204 ok = FALSE; 201 ok = FALSE;
205 else 202 else
206 bytesRead -= bytesWritten; 203 bytesRead -= bytesWritten;
207 } 204 }
208 } 205 }
209 206
210 if ( ok ) 207 if ( ok )
211 ok = dest.writeLink(); 208 ok = dest.writeLink();
212 209
213 if ( ok ) { 210 if ( ok ) {
214 // okay now rename the file... 211 // okay now rename the file...
215 if ( !renameFile( fn.latin1(), dest.file().latin1() ) ) { 212 if ( !renameFile( fn.latin1(), dest.file().latin1() ) ) {
216 qWarning( "problem renaming file %s to %s, errno: %d", fn.latin1(), 213 qWarning( "problem renaming file %s to %s, errno: %d", fn.latin1(),
217 dest.file().latin1(), errno ); 214 dest.file().latin1(), errno );
218 // remove the tmp file, otherwise, it will just lay around... 215 // remove the tmp file, otherwise, it will just lay around...
219 QFile::remove( fn.latin1() ); 216 QFile::remove( fn.latin1() );
220 } 217 }
221 } else { 218 } else {
222 QFile::remove( fn.latin1() ); 219 QFile::remove( fn.latin1() );
223 } 220 }
224 221
225 return ok; 222 return ok;
226} 223}
227 224
228bool FileManager::copyFile( const QString & src, const QString & dest ) { 225bool FileManager::copyFile( const QString & src, const QString & dest ) {
229 bool success = true; 226 bool success = true;
230 struct stat status; 227 struct stat status;
231 int read_fd=0; 228 int read_fd=0;
232 int write_fd=0; 229 int write_fd=0;
233 struct stat stat_buf; 230 struct stat stat_buf;
234 off_t offset = 0; 231 off_t offset = 0;
235 QFile srcFile(src); 232 QFile srcFile(src);
236 QFile destFile(dest); 233 QFile destFile(dest);
237 234
238 if(!srcFile.open( IO_ReadOnly|IO_Raw)) { 235 if(!srcFile.open( IO_ReadOnly|IO_Raw)) {
239 return success = false; 236 return success = false;
240 } 237 }
241 read_fd = srcFile.handle(); 238 read_fd = srcFile.handle();
242 if(read_fd != -1) { 239 if(read_fd != -1) {
243 fstat (read_fd, &stat_buf); 240 fstat (read_fd, &stat_buf);
244 if( !destFile.open( IO_WriteOnly|IO_Raw ) ) 241 if( !destFile.open( IO_WriteOnly|IO_Raw ) )
245 return success = false; 242 return success = false;
246 write_fd = destFile.handle(); 243 write_fd = destFile.handle();
247 if(write_fd != -1) { 244 if(write_fd != -1) {
248 int err=0; 245 int err=0;
249 QString msg; 246 QString msg;
250#ifdef Q_OS_MACX 247#ifdef Q_OS_MACX
251#ifdef SENDFILE 248#ifdef SENDFILE
252 /* FreeBSD does support a different kind of 249 /* FreeBSD does support a different kind of
253 * sendfile. (eilers) 250 * sendfile. (eilers)
254 * I took this from Very Secure FTPd 251 * I took this from Very Secure FTPd
255 * Licence: GPL 252 * Licence: GPL
256 * Author: Chris Evans 253 * Author: Chris Evans
257 * sysdeputil.c 254 * sysdeputil.c
258 */ 255 */
259 /* XXX - start_pos will truncate on 32-bit machines - can we 256 /* XXX - start_pos will truncate on 32-bit machines - can we
260 * say "start from current pos"? 257 * say "start from current pos"?
261 */ 258 */
262 off_t written = 0; 259 off_t written = 0;
263 int retval = 0; 260 int retval = 0;
264 retval = sendfile(read_fd, write_fd, offset, stat_buf.st_size, NULL, 261 retval = sendfile(read_fd, write_fd, offset, stat_buf.st_size, NULL,
265 &written, 0); 262 &written, 0);
266 /* Translate to Linux-like retval */ 263 /* Translate to Linux-like retval */
267 if (written > 0) 264 if (written > 0)
268 { 265 {
269 err = (int) written; 266 err = (int) written;
270 } 267 }
271#else /* SENDFILE */ 268#else /* SENDFILE */
272 err == -1; 269 err == -1;
273 msg = "FAILURE: Using unsupported function \"sendfile()\" Need Workaround !!"; 270 msg = "FAILURE: Using unsupported function \"sendfile()\" Need Workaround !!";
274 success = false; 271 success = false;
275# warning "Need workaround for sendfile!!(eilers)" 272# warning "Need workaround for sendfile!!(eilers)"
276#endif /* SENDFILE */ 273#endif /* SENDFILE */
277 274
278#else 275#else
279 err = sendfile(write_fd, read_fd, &offset, stat_buf.st_size); 276 err = sendfile(write_fd, read_fd, &offset, stat_buf.st_size);
280 if( err == -1) { 277 if( err == -1) {
281 switch(err) { 278 switch(err) {
282 case EBADF : msg = "The input file was not opened for reading or the output file was not opened for writing. "; 279 case EBADF : msg = "The input file was not opened for reading or the output file was not opened for writing. ";
283 case EINVAL: msg = "Descriptor is not valid or locked. "; 280 case EINVAL: msg = "Descriptor is not valid or locked. ";
284 case ENOMEM: msg = "Insufficient memory to read from in_fd."; 281 case ENOMEM: msg = "Insufficient memory to read from in_fd.";
285 case EIO: msg = "Unspecified error while reading from in_fd."; 282 case EIO: msg = "Unspecified error while reading from in_fd.";
286 }; 283 };
287 success = false; 284 success = false;
288 } 285 }
289#endif /* Q_OS_MACX */ 286#endif /* Q_OS_MACX */
290 if( !success ) 287 if( !success )
291 qWarning( msg ); 288 qWarning( msg );
292 } else { 289 } else {
293 qWarning("open write failed %s, %s",src.latin1(), dest.latin1()); 290 qWarning("open write failed %s, %s",src.latin1(), dest.latin1());
294 success = false; 291 success = false;
295 } 292 }
296 } else { 293 } else {
297 qWarning("open read failed %s, %s",src.latin1(), dest.latin1()); 294 qWarning("open read failed %s, %s",src.latin1(), dest.latin1());
298 success = false; 295 success = false;
299 } 296 }
300 srcFile.close(); 297 srcFile.close();
301 destFile.close(); 298 destFile.close();
302 // Set file permissions 299 // Set file permissions
303 if( stat( (const char *) src, &status ) == 0 ) { 300 if( stat( (const char *) src, &status ) == 0 ) {
304 chmod( (const char *) dest, status.st_mode ); 301 chmod( (const char *) dest, status.st_mode );
305 } 302 }
306 303
307 return success; 304 return success;
308} 305}
309 306
310 307
311bool FileManager::renameFile( const QString & src, const QString & dest ) { 308bool FileManager::renameFile( const QString & src, const QString & dest ) {
312 if(copyFile( src, dest )) { 309 if(copyFile( src, dest )) {
313 if(QFile::remove(src) ) { 310 if(QFile::remove(src) ) {
314 return true; 311 return true;
315 } 312 }
316 } 313 }
317 return false; 314 return false;
318} 315}
319 316
320/* 317/*
321bool FileManager::copyFile( const QString & src, const QString & dest ) { 318bool FileManager::copyFile( const QString & src, const QString & dest ) {
322 bool success = true; 319 bool success = true;
323 struct stat status; 320 struct stat status;
324 int read_fd=0; 321 int read_fd=0;
325 int write_fd=0; 322 int write_fd=0;
326 struct stat stat_buf; 323 struct stat stat_buf;
327 off_t offset = 0; 324 off_t offset = 0;
328 QFile srcFile(src); 325 QFile srcFile(src);
329 QFile destFile(dest); 326 QFile destFile(dest);
330 327
331 if(!srcFile.open( IO_ReadOnly|IO_Raw)) { 328 if(!srcFile.open( IO_ReadOnly|IO_Raw)) {
332 return success = false; 329 return success = false;
333 } 330 }
334 read_fd = srcFile.handle(); 331 read_fd = srcFile.handle();
335 if(read_fd != -1) { 332 if(read_fd != -1) {
336 fstat (read_fd, &stat_buf); 333 fstat (read_fd, &stat_buf);
337 if( !destFile.open( IO_WriteOnly|IO_Raw ) ) 334 if( !destFile.open( IO_WriteOnly|IO_Raw ) )
338 return success = false; 335 return success = false;
339 write_fd = destFile.handle(); 336 write_fd = destFile.handle();
340 if(write_fd != -1) { 337 if(write_fd != -1) {
341 int err=0; 338 int err=0;
342 QString msg; 339 QString msg;
343 err = sendfile(write_fd, read_fd, &offset, stat_buf.st_size); 340 err = sendfile(write_fd, read_fd, &offset, stat_buf.st_size);
344 if( err == -1) { 341 if( err == -1) {
345 switch(err) { 342 switch(err) {
346 case EBADF : msg = "The input file was not opened for reading or the output file was not opened for writing. "; 343 case EBADF : msg = "The input file was not opened for reading or the output file was not opened for writing. ";
347 case EINVAL: msg = "Descriptor is not valid or locked. "; 344 case EINVAL: msg = "Descriptor is not valid or locked. ";
348 case ENOMEM: msg = "Insufficient memory to read from in_fd."; 345 case ENOMEM: msg = "Insufficient memory to read from in_fd.";
349 case EIO: msg = "Unspecified error while reading from in_fd."; 346 case EIO: msg = "Unspecified error while reading from in_fd.";
350 }; 347 };
351 success = false; 348 success = false;
352 } 349 }
353 } else { 350 } else {
354 qWarning("open write failed %s, %s",src.latin1(), dest.latin1()); 351 qWarning("open write failed %s, %s",src.latin1(), dest.latin1());
355 success = false; 352 success = false;
356 } 353 }
357 } else { 354 } else {
358 qWarning("open read failed %s, %s",src.latin1(), dest.latin1()); 355 qWarning("open read failed %s, %s",src.latin1(), dest.latin1());
359 success = false; 356 success = false;
360 } 357 }
361 srcFile.close(); 358 srcFile.close();
362 destFile.close(); 359 destFile.close();
363 // Set file permissions 360 // Set file permissions
364 if( stat( (const char *) src, &status ) == 0 ) { 361 if( stat( (const char *) src, &status ) == 0 ) {
365 chmod( (const char *) dest, status.st_mode ); 362 chmod( (const char *) dest, status.st_mode );
366 } 363 }
367 364
368 return success; 365 return success;
369} 366}
370 367
371 368
372bool FileManager::renameFile( const QString & src, const QString & dest ) { 369bool FileManager::renameFile( const QString & src, const QString & dest ) {
373 if(copyFile( src, dest )) { 370 if(copyFile( src, dest )) {
374 if(QFile::remove(src) ) { 371 if(QFile::remove(src) ) {
375 return true; 372 return true;
376 } 373 }
377 } 374 }
378 return false; 375 return false;
379} 376}
380*/ 377*/
381 378
382/*! 379/*!
383 Opens the document specified by \a f as a readable QIODevice. 380 Opens the document specified by \a f as a readable QIODevice.
384 The caller must delete the return value. 381 The caller must delete the return value.
385 382
386 Returns 0 if the operation fails. 383 Returns 0 if the operation fails.
387*/ 384*/
388QIODevice* FileManager::openFile( const DocLnk& f ) 385QIODevice* FileManager::openFile( const DocLnk& f )
389{ 386{
390 QString fn = f.file(); 387 QString fn = f.file();
391 QFile* fl = new QFile( fn ); 388 QFile* fl = new QFile( fn );
392 if ( !fl->open( IO_ReadOnly ) ) { 389 if ( !fl->open( IO_ReadOnly ) ) {
393 delete fl; 390 delete fl;
394 fl = 0; 391 fl = 0;
395 } 392 }
396 return fl; 393 return fl;
397} 394}
398 395
399/*! 396/*!
400 Opens the document specified by \a f as a writable QIODevice. 397 Opens the document specified by \a f as a writable QIODevice.
401 The caller must delete the return value. 398 The caller must delete the return value.
402 399
403 Returns 0 if the operation fails. 400 Returns 0 if the operation fails.
404*/ 401*/
405QIODevice* FileManager::saveFile( const DocLnk& f ) 402QIODevice* FileManager::saveFile( const DocLnk& f )
406{ 403{
407 QString fn = f.file(); 404 QString fn = f.file();
408 ensurePathExists( fn ); 405 ensurePathExists( fn );
409 QFile* fl = new QFile( fn ); 406 QFile* fl = new QFile( fn );
410 if ( fl->open( IO_WriteOnly ) ) { 407 if ( fl->open( IO_WriteOnly ) ) {
411 f.writeLink(); 408 f.writeLink();