File indexing completed on 2024-05-12 04:51:04

0001 /*
0002     SPDX-FileCopyrightText: 1998-2008 Sebastian Trueg <trueg@k3b.org>
0003     SPDX-License-Identifier: GPL-2.0-or-later
0004 */
0005 
0006 #include "k3bdatapreparationjob.h"
0007 #include "k3bdatadoc.h"
0008 #include "k3bisooptions.h"
0009 #include "k3bthreadjob.h"
0010 #include "k3bthread.h"
0011 #include "k3bdiritem.h"
0012 #include "k3bfileitem.h"
0013 #include "k3bglobals.h"
0014 #include "k3b_i18n.h"
0015 
0016 #include <KStringHandler>
0017 
0018 #include <QFile>
0019 #include <QFileInfo>
0020 #include <QList>
0021 
0022 namespace {
0023     QString createItemsString( const QList<K3b::DataItem*>& items, int max )
0024     {
0025         QString s;
0026         int cnt = 0;
0027         for( QList<K3b::DataItem*>::const_iterator it = items.constBegin();
0028              it != items.constEnd(); ++it ) {
0029 
0030             s += KStringHandler::csqueeze( (*it)->localPath(), 60 );
0031 
0032             ++cnt;
0033             if( cnt >= max || it == items.constEnd() )
0034                 break;
0035 
0036             s += "<br>";
0037         }
0038 
0039         if( items.count() > max )
0040             s += "...";
0041 
0042         return s;
0043     }
0044 }
0045 
0046 
0047 class K3b::DataPreparationJob::Private
0048 {
0049 public:
0050     K3b::DataDoc* doc;
0051 
0052     QList<K3b::DataItem*> nonExistingItems;
0053     QString listOfRenamedItems;
0054     QList<K3b::DataItem*> folderSymLinkItems;
0055 };
0056 
0057 
0058 
0059 K3b::DataPreparationJob::DataPreparationJob( K3b::DataDoc* doc, K3b::JobHandler* hdl, QObject* parent )
0060     : K3b::ThreadJob( hdl, parent ),
0061       d( new Private() )
0062 {
0063     d->doc = doc;
0064 }
0065 
0066 
0067 K3b::DataPreparationJob::~DataPreparationJob()
0068 {
0069     delete d;
0070 }
0071 
0072 
0073 bool K3b::DataPreparationJob::run()
0074 {
0075     // clean up
0076     d->nonExistingItems.clear();
0077     d->listOfRenamedItems.truncate(0);
0078     d->folderSymLinkItems.clear();
0079 
0080     // initialize filenames in the project
0081     d->doc->prepareFilenames();
0082 
0083     // create the message string for the renamed files
0084     if( d->doc->needToCutFilenames() ) {
0085         int maxlines = 10;
0086         QList<K3b::DataItem*>::const_iterator it;
0087         QList<K3b::DataItem*> items = d->doc->needToCutFilenameItems();
0088         for( it = items.constBegin();
0089              maxlines > 0 && it != items.constEnd();
0090              ++it, --maxlines ) {
0091             K3b::DataItem* item = *it;
0092             d->listOfRenamedItems += i18n("<em>%1</em> renamed to <em>%2</em>",
0093                                           KStringHandler::csqueeze( item->k3bName(), 30 ),
0094                                           KStringHandler::csqueeze( item->writtenName(), 30 ) );
0095             d->listOfRenamedItems += "<br>";
0096         }
0097         if( it != items.constEnd() )
0098             d->listOfRenamedItems += "...";
0099     }
0100 
0101     //
0102     // Check for missing files and folder symlinks
0103     //
0104     K3b::DataItem* item = d->doc->root();
0105     while( (item = item->nextSibling()) ) {
0106 
0107         if( item->isSymLink() ) {
0108             if( d->doc->isoOptions().followSymbolicLinks() ) {
0109                 QFileInfo f( K3b::resolveLink( item->localPath() ) );
0110                 if( !f.exists() ) {
0111                     d->nonExistingItems.append( item );
0112                 }
0113                 else if( f.isDir() ) {
0114                     d->folderSymLinkItems.append( item );
0115                 }
0116             }
0117         }
0118         else if( item->isFile() && !QFile::exists( item->localPath() ) ) {
0119             d->nonExistingItems.append( item );
0120         }
0121 
0122         if( canceled() ) {
0123             return false;
0124         }
0125     }
0126 
0127 
0128     //
0129     // Now ask the user
0130     //
0131     if( !d->listOfRenamedItems.isEmpty() ) {
0132         if( !questionYesNo( "<p>" + i18n("Some filenames need to be shortened due to the %1 char restriction "
0133                                          "of the Joliet extensions. If the Joliet extensions are disabled filenames "
0134                                          "do not have to be shortened but long filenames will not be available on "
0135                                          "Windows systems.",
0136                                          d->doc->isoOptions().jolietLong() ? 103 : 64 )
0137                             + "<p>" + d->listOfRenamedItems,
0138                             i18n("Warning"),
0139                             KGuiItem( i18n("Shorten Filenames") ),
0140                             KGuiItem( i18n("Disable Joliet extensions") ) ) ) {
0141             // No -> disable joliet
0142             // for now we enable RockRidge to be sure we did not lie above (keep long filenames)
0143             K3b::IsoOptions op = d->doc->isoOptions();
0144             op.setCreateJoliet( false );
0145             op.setCreateRockRidge( true );
0146             d->doc->setIsoOptions( op );
0147             d->doc->prepareFilenames();
0148         }
0149     }
0150 
0151     //
0152     // The joliet extension encodes the volume desc in UCS-2, i.e. uses 16 bit for each char.
0153     // Thus, the max length here is 16.
0154     //
0155     if( d->doc->isoOptions().createJoliet() &&
0156         d->doc->isoOptions().volumeID().length() > 16 ) {
0157         if( !questionYesNo( "<p>" + i18n("The Joliet extensions (which are needed for long filenames on Windows systems) "
0158                                          "restrict the length of the volume descriptor (the name of the filesystem) "
0159                                          "to %1 characters. The selected descriptor '%2' is longer than that. Do you "
0160                                          "want it to be cut or do you want to go back and change it manually?",
0161                                          QString::number( 16 ), d->doc->isoOptions().volumeID() ),
0162                             i18n("Warning"),
0163                             KGuiItem( i18n("Cut volume descriptor in the Joliet tree") ),
0164                             KGuiItem( i18n("Cancel and go back") ) ) ) {
0165             cancel();
0166             return false;
0167         }
0168     }
0169 
0170     //
0171     // Check for missing files
0172     //
0173     if( !d->nonExistingItems.isEmpty() ) {
0174         if( questionYesNo( "<p>" + i18n("The following files could not be found. Do you want to remove them from the "
0175                                         "project and continue without adding them to the image?") +
0176                            "<p>" + createItemsString( d->nonExistingItems, 10 ),
0177                            i18n("Warning"),
0178                            KGuiItem( i18n("Remove missing files and continue") ),
0179                            KGuiItem( i18n("Cancel and go back") ) ) ) {
0180             for( QList<K3b::DataItem*>::const_iterator it = d->nonExistingItems.constBegin();
0181                  it != d->nonExistingItems.constEnd(); ++it ) {
0182                 delete *it;
0183             }
0184         }
0185         else {
0186             cancel();
0187             return false;
0188         }
0189     }
0190 
0191     //
0192     // Warn about symlinks to folders
0193     //
0194     if( d->doc->isoOptions().followSymbolicLinks() && !d->folderSymLinkItems.isEmpty() ) {
0195         if( !questionYesNo( "<p>" + i18n("K3b is not able to follow symbolic links to folders after they have been added "
0196                                          "to the project. Do you want to continue "
0197                                          "without writing the symbolic links to the image?") +
0198                             "<p>" + createItemsString( d->folderSymLinkItems, 10 ),
0199                             i18n("Warning"),
0200                             KGuiItem( i18n("Discard symbolic links to folders") ),
0201                             KGuiItem( i18n("Cancel and go back") ) ) ) {
0202             cancel();
0203             return false;
0204         }
0205     }
0206 
0207     return true;
0208 }
0209 
0210 #include "moc_k3bdatapreparationjob.cpp"