Subversion Repositories Scribus

Rev

Rev 11781 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | RSS feed

/*
For general Scribus (>=1.3.2) copyright and licensing information please refer
to the COPYING file provided with the program. Following this notice may exist
a copyright and/or license notice that predates the release of Scribus 1.3.2
for which a new license (GPL+exception) is in place.
*/

#include "collect4output.h"
#include "collect4output.moc"

#include "scribus.h"
#include "scribusapp.h"
#include "util.h"
#include "prefscontext.h"
#include "prefsfile.h"
#include "prefsmanager.h"
#include "commonstrings.h"
#include "undomanager.h"
#include "filewatcher.h"
#include "pageitem.h"
#include "scraction.h"
#include "scraction.h"

#include <qmessagebox.h>
#include <qstring.h>
#include <qmap.h>
#include <qdir.h>

extern ScribusQApp* ScQApp;


CollectForOutput::CollectForOutput(bool withFonts, bool compressDoc)
        : QObject(ScQApp, 0)
{
        outputDirectory = QString();
        compressDoc = compressDoc;
        withFonts = withFonts;
        dirs = PrefsManager::instance()->prefsFile->getContext("dirs");
        collectedFiles.clear();
}

bool CollectForOutput::newDirDialog()
{
        QString curDir = QDir::currentDirPath();
        if (ScQApp->usingGUI())
        {
                QString wdir = ".";
                QString prefsDocDir = PrefsManager::instance()->documentDir();
                if (!prefsDocDir.isEmpty())
                        wdir = dirs->get("collect", prefsDocDir);
                else
                        wdir = dirs->get("collect", ".");
                outputDirectory = ScMW->CFileDialog(wdir, tr("Choose a Directory"), "", "", false, false, false, false, true, &compressDoc, &withFonts);
        }
        if (outputDirectory.isEmpty())
                return false;
        if (!outputDirectory.endsWith("/"))
                outputDirectory += "/";
        return true;
}

QString CollectForOutput::collect()
{
        if (!newDirDialog())
                return "";
        ScMW->fileWatcher->forceScan();
        ScMW->fileWatcher->stop();
        dirs->set("collect", outputDirectory.left(outputDirectory.findRev("/",-2)));
        ScMW->mainWindowStatusLabel->setText( tr("Collecting..."));

        if (!collectItems())
        {
                QMessageBox::warning(ScMW, tr("Warning"), "<qt>" + tr("Cannot collect all files for output for file:\n%1").arg(newName) + "</qt>", CommonStrings::tr_OK);
                return "";
        }

        /* collect document must go last because of image paths changes
        in collectItems() */

        if (!collectDocument())
        {
                QMessageBox::warning(ScMW, CommonStrings::trWarning, "<qt>" + tr("Cannot collect the file: \n%1").arg(newName) + "</qt>", CommonStrings::tr_OK);
                return "";
        }

        if (withFonts)
                collectFonts();

        QDir::setCurrent(outputDirectory);
        ScMW->updateActiveWindowCaption(newName);
        UndoManager::instance()->renameStack(newName);
        ScMW->scrActions["fileSave"]->setEnabled(false);
        ScMW->scrActions["fileRevert"]->setEnabled(false);
        ScMW->updateRecent(newName);
        ScMW->mainWindowStatusLabel->setText("");
        ScMW->mainWindowProgressBar->reset();
        ScMW->fileWatcher->start();
        collectedFiles.clear();
        return newName;
}

bool CollectForOutput::collectDocument()
{
        QFileInfo fi = QFileInfo(outputDirectory);
        newName = outputDirectory;
        if (!fi.exists())
                return false;
        if (!fi.isDir() || !fi.isWritable())
                return false;

        if (ScMW->doc->hasName)
        {
                QFileInfo fis(ScMW->doc->DocName);
                newName += fis.fileName();
        }
        else
                newName += ScMW->doc->DocName+".sla";

        ScMW->doc->hasName = true;
        if (compressDoc)
        {
                if (!newName.endsWith(".gz"))
                        newName += ".gz";
                else
                {
                        if (newName.endsWith(".gz"))
                                newName = newName.remove(".gz");
                }
        }

        if (!overwrite(ScMW, newName))
                return false;
        if (!ScMW->DoFileSave(newName))
                return false;
        return true;
}

bool CollectForOutput::collectItems()
{
        uint counter = 0;
        for (uint lc = 0; lc < 3; ++lc)
        {
                PageItem* ite;
                switch (lc)
                {
                        case 0:
                                counter = ScMW->doc->MasterItems.count();
                                break;
                        case 1:
                                counter = ScMW->doc->DocItems.count();
                                break;
                        case 2:
                                counter = ScMW->doc->FrameItems.count();
                                break;
                }
                for (uint b = 0; b < counter; ++b)
                {
                        switch (lc)
                        {
                                case 0:
                                        ite = ScMW->doc->MasterItems.at(b);
                                        break;
                                case 1:
                                        ite = ScMW->doc->DocItems.at(b);
                                        break;
                                case 2:
                                        ite = ScMW->doc->FrameItems.at(b);
                                        break;
                        }
                        if (ite->asImageFrame())
                        {
                                /* hack for subsequent c4o "./" -> "/doc/full/path" */
                                QString ofName(ite->Pfile);
                                QFileInfo itf = QFileInfo(ofName);
                                if (!itf.exists())
                                {
                                        ofName = QDir::convertSeparators(PrefsManager::instance()->documentDir() + "/" + ofName);
                                        itf.setFile(ofName);
                                }
                                // end of hack
                                if (itf.exists())
                                {
                                        QString oldFile = ofName;
                                        ite->Pfile = collectFile(oldFile, itf.fileName());
                                        if (ScMW->fileWatcherActive())
                                        {
                                                ScMW->fileWatcher->removeFile(oldFile);
                                                ScMW->fileWatcher->addFile(ite->Pfile);
                                        }
                                }
                        }
                        if (ite->asTextFrame())
                        {
                                if (ite->isAnnotation())
                                {
                                        QFileInfo itf;
                                        if (!ite->Pfile.isEmpty())
                                        {
                                                itf = QFileInfo(ite->Pfile);
                                                if (itf.exists())
                                                {
                                                        QString oldFile = ite->Pfile;
                                                        ite->Pfile = collectFile(oldFile, itf.fileName());
                                                        if (ScMW->fileWatcherActive())
                                                        {
                                                                ScMW->fileWatcher->removeFile(oldFile);
                                                                ScMW->fileWatcher->addFile(ite->Pfile);
                                                        }
                                                }
                                        }
                                        if (!ite->Pfile2.isEmpty())
                                        {
                                                itf = QFileInfo(ite->Pfile2);
                                                if (itf.exists())
                                                        ite->Pfile2 = collectFile(ite->Pfile2, itf.fileName());
                                        }
                                        if (!ite->Pfile3.isEmpty())
                                        {
                                                itf = QFileInfo(ite->Pfile3);
                                                if (itf.exists())
                                                        ite->Pfile3 = collectFile(ite->Pfile3, itf.fileName());
                                        }
                                }
                        }
                }
        }
        return true;
}

bool CollectForOutput::collectFonts()
{
        PrefsManager *prefsManager = PrefsManager::instance();
        QMap<QString,int>::Iterator it3;
        QMap<QString,int>::Iterator it3end = ScMW->doc->UsedFonts.end();
        for (it3 = ScMW->doc->UsedFonts.begin(); it3 != it3end; ++it3)
        {
                QFileInfo itf = QFileInfo(prefsManager->appPrefs.AvailFonts[it3.key()]->fontFilePath());
                copyFile(prefsManager->appPrefs.AvailFonts[it3.key()]->fontFilePath(), outputDirectory + itf.fileName());
                if (prefsManager->appPrefs.AvailFonts[it3.key()]->typeCode == Foi::TYPE1)
                {
                        QStringList metrics;
                        QString fontDir  = itf.absFilePath();
                        QString fontFile = itf.fileName();
                        metrics += findFontMetrics(fontDir, fontFile);
                        if ( metrics.size() <= 0 )
                        {
                                QDir dir;
                                if (dir.exists(fontDir + "/AFMs"))
                                        metrics += findFontMetrics(fontDir + "/AFMs", fontFile);
                                if (dir.exists(fontDir + "/afm") && metrics.size() <= 0)
                                        metrics += findFontMetrics(fontDir + "/afm", fontFile);
                                if (dir.exists(fontDir + "/Pfm") && metrics.size() <= 0)
                                        metrics += findFontMetrics(fontDir + "/Pfm", fontFile);
                                if (dir.exists(fontDir + "/pfm") && metrics.size() <= 0)
                                        metrics += findFontMetrics(fontDir + "/pfm", fontFile);
                        }
                        for (uint a = 0; a < metrics.size(); a++)
                        {
                                QString origAFM = metrics[a];
                                QFileInfo fi(origAFM);
                                copyFile(origAFM, outputDirectory + fi.fileName());
                        }
                }
        }
        return true;
}

QStringList CollectForOutput::findFontMetrics(const QString& baseDir, const QString& baseName) const
{
        QStringList metricsFiles;
        QString     basePath = baseDir + "/" + baseName;
        QString     afnm = basePath.left(basePath.length()-3);
        // Look for afm files
        QString afmName(afnm+"afm");
        if(QFile::exists(afmName))
                metricsFiles.append(afmName);
        else
        {
                afmName = afnm+"Afm";
                if(QFile::exists(afmName))
                        metricsFiles.append(afmName);
                else
                {
                        afmName = afnm+"AFM";
                        if(QFile::exists(afmName))
                                metricsFiles.append(afmName);
                }
        }
        // Look for pfm files
        QString pfmName(afnm+"pfm");
        if(QFile::exists(pfmName))
                metricsFiles.append(pfmName);
        else
        {
                pfmName = afnm+"Pfm";
                if(QFile::exists(pfmName))
                        metricsFiles.append(pfmName);
                else
                {
                        afmName = afnm+"PFM";
                        if(QFile::exists(pfmName))
                                metricsFiles.append(pfmName);
                }
        }
        return metricsFiles;
}

QString CollectForOutput::collectFile(QString oldFile, QString newFile)
{
        uint cnt = 1;
        bool copy = true;

        while (collectedFiles.contains(newFile))
        {
                // overwrite only different sources
                if (collectedFiles[newFile] == oldFile)
                {
                        copy = false;
                        break;
                }
                QFileInfo fi(newFile);
                QString basename = fi.baseName().left(fi.baseName().findRev("_"));
                newFile = QString("%1_%2.%3").arg(basename).arg(cnt).arg(fi.extension());
                ++cnt;
        }
        if (copy)
                copyFile(oldFile, outputDirectory + newFile);
        collectedFiles[newFile] = oldFile;
        return outputDirectory + newFile;
}