Subversion Repositories Scribus

Rev

Rev 22598 | 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.
*/

/***************************************************************************
        copyright            : (C) 2010 by Marcus Holland-Moritz
        email                : scribus@mhxnet.de
***************************************************************************/


/***************************************************************************
*                                                                         *
*   This program is free software; you can redistribute it and/or modify  *
*   it under the terms of the GNU General Public License as published by  *
*   the Free Software Foundation; either version 2 of the License, or     *
*   (at your option) any later version.                                   *
*                                                                         *
***************************************************************************/


#include <QDir>
#include <QFileInfo>

#include "sclockedfile.h"

#define SC_DEBUG_FILE defined(DEBUG_SCLOCKEDFILE)
#include "scdebug.h"

const QString ScLockedFile::lockSuffix("lock");

ScLockedFile::ScLockedFile(const QString& name)
        : m_fileName(name)
{
}

ScLockedFile::~ScLockedFile()
{
        if (m_isLocked)
                unlock();
}

void ScLockedFile::setName(const QString& name)
{
        m_fileName = name;
}

QString ScLockedFile::lockName() const
{
        return m_fileName + "." + lockSuffix;
}

bool ScLockedFile::lock()
{
        Q_ASSERT(!m_isLocked);
        if (m_isLocked)
        {
                scDebug() << "BUG:" << m_fileName << "is already locked";
                return false;
        }
        QDir cdir;
        m_isLocked = cdir.mkdir(lockName());
        if (!m_isLocked)
                scDebug() << "cannot lock" << m_fileName;
        return m_isLocked;
}

bool ScLockedFile::unlock()
{
        Q_ASSERT(m_isLocked);
        if (!m_isLocked)
        {
                scDebug() << "BUG:" << m_fileName << "is not locked";
                return false;
        }
        QDir cdir;
        m_isLocked = !cdir.rmdir(lockName());
        if (m_isLocked)
                scDebug() << "cannot unlock" << m_fileName;
        return !m_isLocked;
}

bool ScLockedFile::exists() const
{
        return QFile::exists(m_fileName);
}

bool ScLockedFile::remove() const
{
        return QFile::remove(m_fileName);
}

bool ScLockedFile::createPath() const
{
        QFileInfo info(m_fileName);
        QString path = info.path();
        QDir dir(path);
        if (dir.exists())
                return true;
        scDebug() << "creating directory" << path;
        return dir.mkpath(path);
}


ScLockedFileRW::ScLockedFileRW(const QString & name)
        : ScLockedFile(name)
{
}

QString ScLockedFileRW::templateName(const QFileInfo & info)
{
        return info.dir().path() + "/" + info.baseName() + "_XXXXXX." + info.completeSuffix();
}

bool ScLockedFileRW::open()
{
        Q_ASSERT(!m_fileName.isEmpty());

        if (m_fileName.isEmpty())
        {
                scDebug() << "BUG: file name not set";
                return false;
        }

        QFileInfo info(m_fileName);
        if (info.exists() && !info.isWritable())
        {
                scDebug() << "final file is not writeable, aborting open for" << m_fileName;
                return false;
        }

        m_file.setFileTemplate(templateName(info));
        m_isOpened = m_file.open();

        if (!m_isOpened)
                scDebug() << "could not open read/write" << m_fileName;

        return m_isOpened;
}

bool ScLockedFileRW::commit()
{
        Q_ASSERT(m_isOpened);

        if (!m_isOpened)
        {
                scDebug() << "BUG: cannot commit," << m_fileName << "is not opened";
                return false;
        }

        if (exists() && !remove())
        {
                scDebug() << "cannot commit," << m_fileName << "cannot be removed";
                return false;
        }
               
        m_isOpened = false;

        QString tmpName = m_file.fileName();

        if (!m_file.rename(m_fileName))
        {
                scDebug() << "cannot commit," << tmpName << "cannot be renamed to" << m_fileName;
                return false;
        }

        m_file.setAutoRemove(false);

        return true;
}


ScLockedFileRO::ScLockedFileRO()
{
}

ScLockedFileRO::ScLockedFileRO(const QString& name)
        : ScLockedFile(name)
{
}

bool ScLockedFileRO::open()
{
        Q_ASSERT(!m_fileName.isEmpty());

        if (m_fileName.isEmpty())
        {
                scDebug() << "BUG: file name not set";
                return false;
        }

        m_file.setFileName(m_fileName);
        m_isOpened = m_file.open(QIODevice::ReadOnly);

        if (!m_isOpened && exists())
                scDebug() << "could not open read-only" << m_fileName;

        return m_isOpened;
}

bool ScLockedFileRO::commit()
{
        Q_ASSERT(false);
        scDebug() << "BUG: cannot commit," << m_fileName << "is read-only";
        return false;
}