Krita Source Code Documentation
Loading...
Searching...
No Matches
KisSafeDocumentLoader Class Reference

#include <kis_safe_document_loader.h>

+ Inheritance diagram for KisSafeDocumentLoader:

Classes

struct  Private
 

Signals

void fileExistsStateChanged (bool fileExists)
 
void loadingFailed ()
 
void loadingFinished (KisPaintDeviceSP paintDevice, qreal xRes, qreal yRes, const QSize &size)
 

Public Member Functions

 KisSafeDocumentLoader (const QString &path="", QObject *parent=0)
 
void reloadImage ()
 
void setPath (const QString &path)
 
 ~KisSafeDocumentLoader () override
 

Private Slots

void delayedLoadStart ()
 
void fileChanged (QString)
 
void fileChangedCompressed (bool sync=false)
 
void slotFileExistsStateChanged (const QString &path, bool fileExists)
 

Private Attributes

Private *const m_d
 

Detailed Description

Definition at line 14 of file kis_safe_document_loader.h.

Constructor & Destructor Documentation

◆ KisSafeDocumentLoader()

KisSafeDocumentLoader::KisSafeDocumentLoader ( const QString & path = "",
QObject * parent = 0 )

Definition at line 224 of file kis_safe_document_loader.cpp.

225 : QObject(parent),
226 m_d(new Private())
227{
228 connect(s_fileSystemWatcher, SIGNAL(fileChanged(QString)),
229 SLOT(fileChanged(QString)));
230
231 connect(s_fileSystemWatcher, SIGNAL(fileExistsStateChanged(QString, bool)),
232 SLOT(slotFileExistsStateChanged(QString, bool)));
233
234 connect(&m_d->fileChangedSignalCompressor, SIGNAL(timeout()),
235 SLOT(fileChangedCompressed()));
236
237 setPath(path);
238}
connect(this, SIGNAL(optionsChanged()), this, SLOT(saveOptions()))
void fileChangedCompressed(bool sync=false)
void fileExistsStateChanged(bool fileExists)
void setPath(const QString &path)
void slotFileExistsStateChanged(const QString &path, bool fileExists)

References connect(), fileChanged(), fileChangedCompressed(), KisSafeDocumentLoader::Private::fileChangedSignalCompressor, fileExistsStateChanged(), m_d, setPath(), and slotFileExistsStateChanged().

◆ ~KisSafeDocumentLoader()

KisSafeDocumentLoader::~KisSafeDocumentLoader ( )
override

Definition at line 240 of file kis_safe_document_loader.cpp.

241{
242 if (!m_d->path.isEmpty()) {
243 s_fileSystemWatcher->removePath(m_d->path);
244 }
245
246 delete m_d;
247}

References m_d, and KisSafeDocumentLoader::Private::path.

Member Function Documentation

◆ delayedLoadStart

void KisSafeDocumentLoader::delayedLoadStart ( )
privateslot

Definition at line 317 of file kis_safe_document_loader.cpp.

318{
319 QFileInfo originalInfo(m_d->path);
320 QFileInfo tempInfo(m_d->temporaryPath);
321 bool successfullyLoaded = false;
322
323 if (!m_d->fileChangedFlag &&
324 originalInfo.size() == m_d->initialFileSize &&
325 originalInfo.lastModified() == m_d->initialFileTimeStamp &&
326 tempInfo.size() == m_d->initialFileSize) {
327
328 m_d->doc.reset(KisPart::instance()->createTemporaryDocument());
329 m_d->doc->setFileBatchMode(true);
330
331 if (m_d->path.toLower().endsWith("ora") || m_d->path.toLower().endsWith("kra")) {
332 QScopedPointer<KoStore> store(KoStore::createStore(m_d->temporaryPath, KoStore::Read));
333 if (store && !store->bad()) {
334 if (store->open(QString("mergedimage.png"))) {
335 QByteArray bytes = store->read(store->size());
336 store->close();
337 QImage mergedImage;
338 mergedImage.loadFromData(bytes);
339 Q_ASSERT(!mergedImage.isNull());
340 KisImageSP image = new KisImage(0, mergedImage.width(), mergedImage.height(), KoColorSpaceRegistry::instance()->rgb8(), "");
341
342 constexpr double DOTS_PER_METER_TO_DOTS_PER_INCH = 0.00035285815102328864;
343 double xres = mergedImage.dotsPerMeterX() * DOTS_PER_METER_TO_DOTS_PER_INCH;
344 double yres = mergedImage.dotsPerMeterY() * DOTS_PER_METER_TO_DOTS_PER_INCH;
345
346 image->setResolution(xres, yres);
347 KisPaintLayerSP layer = new KisPaintLayer(image, "", OPACITY_OPAQUE_U8);
348 layer->paintDevice()->convertFromQImage(mergedImage, 0);
349 image->addNode(layer, image->rootLayer());
350 image->initialRefreshGraph();
351 m_d->doc->setCurrentImage(image);
352 successfullyLoaded = true;
353 }
354 else {
355 qWarning() << "delayedLoadStart: Could not open mergedimage.png";
356 }
357 }
358 else {
359 qWarning() << "delayedLoadStart: Store was bad";
360 }
361 }
362 else {
363 successfullyLoaded = m_d->doc->openPath(m_d->temporaryPath,
365
366 if (successfullyLoaded) {
367 // Wait for required updates, if any. BUG: 448256
369 m_d->doc->image()->waitForDone();
370 }
371 }
372 } else {
373 dbgKrita << "File was modified externally. Restarting.";
377 dbgKrita << ppVar(originalInfo.size());
378 dbgKrita << ppVar(originalInfo.lastModified());
379 dbgKrita << ppVar(tempInfo.size());
380 }
381
382 QFile::remove(m_d->temporaryPath);
383 m_d->isLoading = false;
384
385 if (!successfullyLoaded) {
386 // Restart the attempt
387 m_d->failureCount++;
388 if (m_d->failureCount >= 3) {
389 Q_EMIT loadingFailed();
390 }
391 else {
393 }
394 }
395 else {
396 KisPaintDeviceSP paintDevice = new KisPaintDevice(m_d->doc->image()->colorSpace());
397 KisPaintDeviceSP projection = m_d->doc->image()->projection();
398 paintDevice->makeCloneFrom(projection, projection->extent());
399 Q_EMIT loadingFinished(paintDevice,
400 m_d->doc->image()->xRes(),
401 m_d->doc->image()->yRes(),
402 m_d->doc->image()->size());
403 }
404
405 m_d->doc.reset();
406}
const quint8 OPACITY_OPAQUE_U8
KisGroupLayerSP rootLayer() const
void initialRefreshGraph()
void setResolution(double xres, double yres)
QRect extent() const
void convertFromQImage(const QImage &image, const KoColorProfile *profile, qint32 offsetX=0, qint32 offsetY=0)
void makeCloneFrom(KisPaintDeviceSP src, const QRect &rect)
static KisPart * instance()
Definition KisPart.cpp:131
void loadingFinished(KisPaintDeviceSP paintDevice, qreal xRes, qreal yRes, const QSize &size)
@ Read
Definition KoStore.h:29
static KoStore * createStore(const QString &fileName, Mode mode, const QByteArray &appIdentification=QByteArray(), Backend backend=Auto, bool writeMimetype=true)
Definition KoStore.cpp:39
#define dbgKrita
Definition kis_debug.h:45
#define ppVar(var)
Definition kis_debug.h:155
void forceAllDelayedNodesUpdate(KisNodeSP root)
bool addNode(KisNodeSP node, KisNodeSP parent=KisNodeSP(), KisNodeAdditionFlags flags=KisNodeAdditionFlag::None)
KisPaintDeviceSP paintDevice
static KoColorSpaceRegistry * instance()
const KoColorSpace * rgb8(const QString &profileName=QString())

References KisNodeFacade::addNode(), KisPaintDevice::convertFromQImage(), KoStore::createStore(), dbgKrita, KisSafeDocumentLoader::Private::doc, KisDocument::DontAddToRecent, KisPaintDevice::extent(), KisSafeDocumentLoader::Private::failureCount, KisSafeDocumentLoader::Private::fileChangedFlag, KisSafeDocumentLoader::Private::fileChangedSignalCompressor, KisLayerUtils::forceAllDelayedNodesUpdate(), KisSafeDocumentLoader::Private::initialFileSize, KisSafeDocumentLoader::Private::initialFileTimeStamp, KisImage::initialRefreshGraph(), KoColorSpaceRegistry::instance(), KisPart::instance(), KisSafeDocumentLoader::Private::isLoading, loadingFailed(), loadingFinished(), m_d, KisPaintDevice::makeCloneFrom(), OPACITY_OPAQUE_U8, KisPaintLayer::paintDevice, KisSafeDocumentLoader::Private::path, ppVar, KoStore::Read, KoColorSpaceRegistry::rgb8(), KisImage::rootLayer(), KisImage::setResolution(), KisSignalCompressor::start(), and KisSafeDocumentLoader::Private::temporaryPath.

◆ fileChanged

◆ fileChangedCompressed

void KisSafeDocumentLoader::fileChangedCompressed ( bool sync = false)
privateslot

Definition at line 284 of file kis_safe_document_loader.cpp.

285{
286 if (m_d->isLoading) return;
287
288 QFileInfo initialFileInfo(m_d->path);
289 m_d->initialFileSize = initialFileInfo.size();
290 m_d->initialFileTimeStamp = initialFileInfo.lastModified();
291
292 // it may happen when the file is flushed by
293 // so other application
294 if (!m_d->initialFileSize) return;
295
296 m_d->isLoading = true;
297 m_d->fileChangedFlag = false;
298
300 QDir::tempPath() + '/' +
301 QString("krita_file_layer_copy_%1_%2.%3")
302 .arg(QApplication::applicationPid())
303 .arg(QRandomGenerator::global()->generate())
304 .arg(initialFileInfo.suffix());
305
306 QFile::copy(m_d->path, m_d->temporaryPath);
307
308
309 if (!sync) {
310 QTimer::singleShot(100, Qt::CoarseTimer, this, SLOT(delayedLoadStart()));
311 } else {
312 QApplication::processEvents();
314 }
315}

References delayedLoadStart(), KisSafeDocumentLoader::Private::fileChangedFlag, KisSafeDocumentLoader::Private::initialFileSize, KisSafeDocumentLoader::Private::initialFileTimeStamp, KisSafeDocumentLoader::Private::isLoading, m_d, KisSafeDocumentLoader::Private::path, and KisSafeDocumentLoader::Private::temporaryPath.

◆ fileExistsStateChanged

void KisSafeDocumentLoader::fileExistsStateChanged ( bool fileExists)
signal

◆ loadingFailed

void KisSafeDocumentLoader::loadingFailed ( )
signal

◆ loadingFinished

void KisSafeDocumentLoader::loadingFinished ( KisPaintDeviceSP paintDevice,
qreal xRes,
qreal yRes,
const QSize & size )
signal

◆ reloadImage()

void KisSafeDocumentLoader::reloadImage ( )

Definition at line 261 of file kis_safe_document_loader.cpp.

262{
264}

References fileChangedCompressed().

◆ setPath()

void KisSafeDocumentLoader::setPath ( const QString & path)

Definition at line 249 of file kis_safe_document_loader.cpp.

250{
251 if (path.isEmpty()) return;
252
253 if (!m_d->path.isEmpty()) {
254 s_fileSystemWatcher->removePath(m_d->path);
255 }
256
257 m_d->path = path;
258 s_fileSystemWatcher->addPath(m_d->path);
259}

References m_d, and KisSafeDocumentLoader::Private::path.

◆ slotFileExistsStateChanged

void KisSafeDocumentLoader::slotFileExistsStateChanged ( const QString & path,
bool fileExists )
privateslot

Definition at line 274 of file kis_safe_document_loader.cpp.

275{
277 Q_EMIT fileExistsStateChanged(fileExists);
278 if (fileExists) {
279 fileChanged(path);
280 }
281 }
282}

References fileChanged(), fileExistsStateChanged(), m_d, KisSafeDocumentLoader::Private::path, and FileSystemWatcherWrapper::unifyFilePath().

Member Data Documentation

◆ m_d

Private* const KisSafeDocumentLoader::m_d
private

Definition at line 37 of file kis_safe_document_loader.h.


The documentation for this class was generated from the following files: