#include #include #include #include "file.h" #include "process.h" #include QString maskPath(QString p) { // Change " " to "\ " to enable blanks in filenames p=p.replace(QChar('&'),"\\&"); return p.replace(QChar(' '),"\\ "); } QString convertToRel (const QString &src, const QString &dst) { QString s=src; QString d=dst; int i; if (s==d) { // Special case, we just need the name of the file, // not the complete path i=d.findRev ("/"); d=d.right (d.length()-i-1); } else { // Find relative path from src to dst // Remove the first "/" if (s.section ("/",0,0).isEmpty()) { s=s.right (s.length()-1); d=d.right (d.length()-1); } // remove identical left parts while (s.section("/",0,0) == d.section("/",0,0) ) { i=s.find ("/"); s=s.right (s.length()-i-1); d=d.right (d.length()-i-1); } // Now take care of paths where we have to go back first int srcsep=s.contains("/"); int dstsep=d.contains("/"); if (srcsep <= dstsep ) { // find path to go up first and then back to dst i=1; while (i<=srcsep) { d="../"+d; i++; } } } return d; } QString makeUniqueDir (QString s) { // Create unique directory e.g. s="/tmp/vym-XXXXXX" // Convert QString to string first char *p; int bytes=s.length(); p=(char*) malloc (bytes+1); int i; for (i=0;ifileName() != "." && fi->fileName() != ".." ) { if ( !d.cd(fi->fileName()) ) qWarning ("removeDir() cannot find the directory "+fi->fileName()); else { // Recursively remove subdirs removeDir (d); d.cdUp(); } } ++itdir; } // Traverse files d.setFilter( QDir::Files| QDir::Hidden | QDir::NoSymLinks ); const QFileInfoList *filelist = d.entryInfoList(); QFileInfoListIterator itfile( *filelist ); while ( (fi = itfile.current()) != 0 ) { QFile (fi->filePath()).remove(); ++itfile; } if (!d.rmdir(d.path())) qWarning ("removeDir("+d.path()+") failed!"); } void makeSubDirs (const QString &s) { QDir d(s); d.mkdir(s); d.mkdir ("images"); d.mkdir ("flags"); } ErrorCode zipDir (const QDir &zipDir, const QString &zipName) { ErrorCode err=success; // zip the temporary directory Process *zipProc=new Process (); zipProc->clearArguments(); zipProc->setWorkingDirectory (QDir(zipDir)); zipProc->addArgument ("zip"); zipProc->addArgument ("-r"); zipProc->addArgument (zipName); zipProc->addArgument ("."); if (!zipProc->start() ) { // zip could not be started QMessageBox::critical( 0, QObject::tr( "Critical Error" ), QObject::tr("Couldn't start zip to compress data.")); err=aborted; } else { // zip could be started zipProc->waitFinished(); if (!zipProc->normalExit() ) { QMessageBox::critical( 0, QObject::tr( "Critical Error" ), QObject::tr("zip didn't exit normally")+ "\n" + zipProc->getErrout()); err=aborted; } else { if (zipProc->exitStatus()>0) { QMessageBox::critical( 0, QObject::tr( "Critical Error" ), QString("zip exit code: %1").arg(zipProc->exitStatus() )+ "\n" + zipProc->getErrout() ); err=aborted; } } } // zip could be started return err; } ErrorCode unzipDir (const QDir &zipDir, const QString &zipName) { ErrorCode err=success; // Try to unzip file Process *zipProc=new Process (); zipProc->clearArguments(); zipProc->setWorkingDirectory (zipDir); zipProc->addArgument ("unzip"); zipProc->addArgument ("-o"); // overwrite existing files! zipProc->addArgument (zipName ); zipProc->addArgument ("-d"); zipProc->addArgument (zipDir.path()); if (!zipProc->start() ) { QMessageBox::critical( 0, QObject::tr( "Critical Error" ), QObject::tr("Couldn't start unzip to decompress data.")); err=aborted; } else { zipProc->waitFinished(); if (!zipProc->normalExit() ) { QMessageBox::critical( 0,QObject::tr( "Critical Error" ), QObject::tr("unzip didn't exit normally") + zipProc->getErrout() ); err=aborted; } else { if (zipProc->exitStatus()>0) { if (zipProc->exitStatus()==9) // no zipped file, but maybe .xml or old version? Try again. err=nozip; else { QMessageBox::critical( 0, QObject::tr( "Critical Error" ), QString("unzip exit code: %1").arg(zipProc->exitStatus() ) + zipProc->getErrout() ); err=aborted; } } } } return err; } bool loadStringFromDisk (const QString &fname, QString &s) { s=""; QFile file ( fname); if ( !file.open( IO_ReadOnly ) ) return false; QTextStream ts( &file ); ts.setEncoding (QTextStream::UnicodeUTF8); while ( !ts.atEnd() ) s+=ts.readLine()+"\n"; file.close(); return true; } bool saveStringToDisk (const QString &fname, const QString &s) { QFile file( fname); file.setName ( fname); if ( !file.open( IO_WriteOnly ) ) { file.close(); return false; } // Write it finally, and write in UTF8, no matter what QTextStream ts( &file ); ts.setEncoding (QTextStream::UnicodeUTF8); ts << s; file.close(); return true; } ImagePreview::ImagePreview (QWidget *par=0): QLabel (par) { fdia=(QFileDialog*)par; } void ImagePreview::previewUrl( const QUrl &u ) { QString path = u.path(); QPixmap pix( path ); if ( pix.isNull() ) { // Strange: If we have fd->setMode (QFileDialog::ExistingFiles) // in the filedialog, then there are 3 calls to previewURL // for each selection. And only the first is the actual selected file // while the following 2 point to the directory above the current one. // So here's my workaround: if (fdia && fdia->selectedFiles().count()==0) setText( QObject::tr("This is not an image.") ); if (fdia &&fdia->selectedFiles().count()>1) setText( QObject::tr("Sorry, no preview for\nmultiple selected files.") ); } else { float max_w=300; float max_h=300; float r; if (pix.width()>max_w) { r=max_w / pix.width(); pix.resize(qRound(pix.width()*r), qRound(pix.height()*r)); // FIXME not a resize, but a shrink/enlarge is needed here... } if (pix.height()>max_h) { r=max_h / pix.height(); pix.resize(qRound(pix.width()*r), qRound(pix.height()*r)); // FIXME not a resize, but a shrink/enlarge is needed here... } setPixmap( pix ); } }