Commit a2f0275b authored by Dmitry Kazakov's avatar Dmitry Kazakov

Implement progress reporting for asynchronous saving

This patch refactors KoProgresssUpdater a bit:

1) Multiple subtasks are handled correctly now
2) Subtasks names can be nested
3) KisViewManager creates not KoProgressUpdater, but KoUpdater class,
   which is a part of the global progress queue. Therefore, there
   in no concurrent access to the progress bar now.
parent 20e980c4
...@@ -44,7 +44,7 @@ void KisProjectionBenchmark::benchmarkProjection() ...@@ -44,7 +44,7 @@ void KisProjectionBenchmark::benchmarkProjection()
KisDocument *doc = KisPart::instance()->createDocument(); KisDocument *doc = KisPart::instance()->createDocument();
doc->loadNativeFormat(QString(FILES_DATA_DIR) + QDir::separator() + "load_test.kra"); doc->loadNativeFormat(QString(FILES_DATA_DIR) + QDir::separator() + "load_test.kra");
doc->image()->refreshGraph(); doc->image()->refreshGraph();
doc->exportDocument(QUrl::fromLocalFile(QString(FILES_OUTPUT_DIR) + QDir::separator() + "save_test.kra"), doc->mimeType()); doc->exportDocumentSync(QUrl::fromLocalFile(QString(FILES_OUTPUT_DIR) + QDir::separator() + "save_test.kra"), doc->mimeType());
delete doc; delete doc;
} }
} }
......
...@@ -64,3 +64,10 @@ void KisCompositeProgressProxy::setFormat(const QString &format) ...@@ -64,3 +64,10 @@ void KisCompositeProgressProxy::setFormat(const QString &format)
} }
} }
void KisCompositeProgressProxy::setAutoNestedName(const QString &name)
{
Q_FOREACH (KoProgressProxy *proxy, m_uniqueProxies) {
proxy->setAutoNestedName(name);
}
}
...@@ -30,10 +30,11 @@ public: ...@@ -30,10 +30,11 @@ public:
void addProxy(KoProgressProxy *proxy); void addProxy(KoProgressProxy *proxy);
void removeProxy(KoProgressProxy *proxy); void removeProxy(KoProgressProxy *proxy);
int maximum() const; int maximum() const override;
void setValue(int value); void setValue(int value) override;
void setRange(int minimum, int maximum); void setRange(int minimum, int maximum) override;
void setFormat(const QString &format); void setFormat(const QString &format) override;
void setAutoNestedName(const QString &name) override;
private: private:
QList<KoProgressProxy*> m_proxies; QList<KoProgressProxy*> m_proxies;
......
...@@ -42,10 +42,10 @@ class KRITAIMAGE_EXPORT KisNodeProgressProxy : public QObject, public KoProgress ...@@ -42,10 +42,10 @@ class KRITAIMAGE_EXPORT KisNodeProgressProxy : public QObject, public KoProgress
~KisNodeProgressProxy(); ~KisNodeProgressProxy();
public: public:
virtual int maximum() const ; int maximum() const override;
virtual void setValue(int value); void setValue(int value) override;
virtual void setRange(int minimum, int maximum); void setRange(int minimum, int maximum) override;
virtual void setFormat(const QString & format); void setFormat(const QString & format) override;
/** /**
* @return the current percentage (return -1 if no progress) * @return the current percentage (return -1 if no progress)
*/ */
......
...@@ -123,7 +123,13 @@ void KisQueuesProgressUpdater::timerTicked() ...@@ -123,7 +123,13 @@ void KisQueuesProgressUpdater::timerTicked()
{ {
QMutexLocker locker(&m_d->mutex); QMutexLocker locker(&m_d->mutex);
m_d->progressProxy->setRange(0, m_d->initialQueueSizeMetric); if (!m_d->initialQueueSizeMetric) {
m_d->progressProxy->setValue(m_d->initialQueueSizeMetric - m_d->queueSizeMetric); m_d->progressProxy->setRange(0, 100);
m_d->progressProxy->setFormat(m_d->jobName); m_d->progressProxy->setValue(100);
m_d->progressProxy->setFormat("%p%");
} else {
m_d->progressProxy->setRange(0, m_d->initialQueueSizeMetric);
m_d->progressProxy->setValue(m_d->initialQueueSizeMetric - m_d->queueSizeMetric);
m_d->progressProxy->setFormat(m_d->jobName);
}
} }
...@@ -460,7 +460,7 @@ bool Node::save(const QString &filename, double xRes, double yRes) ...@@ -460,7 +460,7 @@ bool Node::save(const QString &filename, double xRes, double yRes)
dst->addNode(paintLayer, dst->rootLayer(), KisLayerSP(0)); dst->addNode(paintLayer, dst->rootLayer(), KisLayerSP(0));
dst->initialRefreshGraph(); dst->initialRefreshGraph();
bool r = doc->exportDocument(QUrl::fromLocalFile(filename), mimeType.toLatin1()); bool r = doc->exportDocumentSync(QUrl::fromLocalFile(filename), mimeType.toLatin1());
if (!r) { if (!r) {
qWarning() << doc->errorMessage(); qWarning() << doc->errorMessage();
} }
......
...@@ -467,7 +467,7 @@ bool KisApplication::start(const KisApplicationArguments &args) ...@@ -467,7 +467,7 @@ bool KisApplication::start(const KisApplicationArguments &args)
qApp->processEvents(); // For vector layers to be updated qApp->processEvents(); // For vector layers to be updated
doc->setFileBatchMode(true); doc->setFileBatchMode(true);
if (!doc->exportDocument(QUrl::fromLocalFile(exportFileName), outputMimetype.toLatin1())) { if (!doc->exportDocumentSync(QUrl::fromLocalFile(exportFileName), outputMimetype.toLatin1())) {
dbgKrita << "Could not export " << fileName << "to" << exportFileName << ":" << doc->errorMessage(); dbgKrita << "Could not export " << fileName << "to" << exportFileName << ":" << doc->errorMessage();
} }
nPrinted++; nPrinted++;
......
This diff is collapsed.
...@@ -52,8 +52,6 @@ class KoShapeLayer; ...@@ -52,8 +52,6 @@ class KoShapeLayer;
class KoStore; class KoStore;
class KoOdfReadStore; class KoOdfReadStore;
class KoDocumentInfo; class KoDocumentInfo;
class KoProgressUpdater;
class KoProgressProxy;
class KoDocumentInfoDlg; class KoDocumentInfoDlg;
class KisImportExportManager; class KisImportExportManager;
class KisUndoStore; class KisUndoStore;
...@@ -113,6 +111,13 @@ public: ...@@ -113,6 +111,13 @@ public:
*/ */
bool reload(); bool reload();
/**
* @brief try to clone the image. This method handles all the locking for you. If locking
* has failed, no cloning happens
* @return cloned document on success, null otherwise
*/
KisDocument *safeCreateClone();
/** /**
* @brief openUrl Open an URL * @brief openUrl Open an URL
* @param url The URL to open * @param url The URL to open
...@@ -141,6 +146,8 @@ public: ...@@ -141,6 +146,8 @@ public:
*/ */
bool exportDocument(const QUrl &url, const QByteArray &mimeType, bool showWarnings = false, KisPropertiesConfigurationSP exportConfiguration = 0); bool exportDocument(const QUrl &url, const QByteArray &mimeType, bool showWarnings = false, KisPropertiesConfigurationSP exportConfiguration = 0);
bool exportDocumentSync(const QUrl &url, const QByteArray &mimeType, KisPropertiesConfigurationSP exportConfiguration = 0);
bool exportDocumentImpl(const KritaUtils::ExportFileJob &job, KisPropertiesConfigurationSP exportConfiguration); bool exportDocumentImpl(const KritaUtils::ExportFileJob &job, KisPropertiesConfigurationSP exportConfiguration);
/** /**
...@@ -277,23 +284,6 @@ public: ...@@ -277,23 +284,6 @@ public:
*/ */
KoDocumentInfo *documentInfo() const; KoDocumentInfo *documentInfo() const;
/**
* @return the object to report progress to.
*
* This is only not zero if loading or saving is in progress.
*
* One can add more KoUpdaters to it to make the progress reporting more
* accurate. If no active progress reporter is present, 0 is returned.
**/
KoProgressUpdater *progressUpdater() const;
/**
* Set a custom progress proxy to use to report loading
* progress to.
*/
void setProgressProxy(KoProgressProxy *progressProxy);
KoProgressProxy* progressProxy() const;
/** /**
* Performs a cleanup of unneeded backup files * Performs a cleanup of unneeded backup files
*/ */
...@@ -458,12 +448,12 @@ private: ...@@ -458,12 +448,12 @@ private:
friend class KisPart; friend class KisPart;
friend class SafeSavingLocker; friend class SafeSavingLocker;
bool initiateSavingInBackground(const QString statusMessage, bool initiateSavingInBackground(const QString actionName,
const QObject *receiverObject, const char *receiverMethod, const QObject *receiverObject, const char *receiverMethod,
const KritaUtils::ExportFileJob &job, const KritaUtils::ExportFileJob &job,
KisPropertiesConfigurationSP exportConfiguration); KisPropertiesConfigurationSP exportConfiguration);
bool startExportInBackground(const QString &location, bool startExportInBackground(const QString &actionName, const QString &location,
const QString &realLocation, const QString &realLocation,
const QByteArray &mimeType, const QByteArray &mimeType,
bool showWarnings, bool showWarnings,
...@@ -533,26 +523,6 @@ public: ...@@ -533,26 +523,6 @@ public:
*/ */
KisImageSP savingImage() const; KisImageSP savingImage() const;
/**
* Adds progressproxy for file operations
*/
void setFileProgressProxy();
/**
* Clears progressproxy for file operations
*/
void clearFileProgressProxy();
/**
* Adds progressupdater for file operations
*/
void setFileProgressUpdater(const QString &text);
/**
* Clears progressupdater for file operations
*/
void clearFileProgressUpdater();
/** /**
* Set the current image to the specified image and turn undo on. * Set the current image to the specified image and turn undo on.
*/ */
...@@ -606,8 +576,6 @@ private Q_SLOTS: ...@@ -606,8 +576,6 @@ private Q_SLOTS:
private: private:
KisDocument *safeCreateClone();
QString exportErrorToUserMessage(KisImportExportFilter::ConversionStatus status, const QString &errorMessage); QString exportErrorToUserMessage(KisImportExportFilter::ConversionStatus status, const QString &errorMessage);
QString prettyPathOrUrl() const; QString prettyPathOrUrl() const;
......
...@@ -71,7 +71,7 @@ class Q_DECL_HIDDEN KisImportExportManager::Private ...@@ -71,7 +71,7 @@ class Q_DECL_HIDDEN KisImportExportManager::Private
{ {
public: public:
bool batchMode {false}; bool batchMode {false};
QPointer<KoProgressUpdater> progressUpdater {0}; KoUpdaterPtr updater;
}; };
struct KisImportExportManager::ConversionResult { struct KisImportExportManager::ConversionResult {
...@@ -242,9 +242,9 @@ bool KisImportExportManager::batchMode(void) const ...@@ -242,9 +242,9 @@ bool KisImportExportManager::batchMode(void) const
return d->batchMode; return d->batchMode;
} }
void KisImportExportManager::setProgresUpdater(KoProgressUpdater *updater) void KisImportExportManager::setUpdater(KoUpdaterPtr updater)
{ {
d->progressUpdater = updater; d->updater = updater;
} }
QString KisImportExportManager::askForAudioFileName(const QString &defaultDir, QWidget *parent) QString KisImportExportManager::askForAudioFileName(const QString &defaultDir, QWidget *parent)
...@@ -289,8 +289,11 @@ KisImportExportManager::ConversionResult KisImportExportManager::convert(KisImpo ...@@ -289,8 +289,11 @@ KisImportExportManager::ConversionResult KisImportExportManager::convert(KisImpo
filter->setBatchMode(batchMode()); filter->setBatchMode(batchMode());
filter->setMimeType(typeName); filter->setMimeType(typeName);
if (d->progressUpdater) { if (!d->updater.isNull()) {
filter->setUpdater(d->progressUpdater->startSubtask()); // WARNING: The updater is not guaranteed to be persistent! If you ever want
// to add progress reporting to "Save also as .kra", make sure you create
// a separate KoProgressUpdater for that!
filter->setUpdater(d->updater);
} }
QByteArray from, to; QByteArray from, to;
......
...@@ -122,7 +122,7 @@ public: ...@@ -122,7 +122,7 @@ public:
*/ */
bool batchMode(void) const; bool batchMode(void) const;
void setProgresUpdater(KoProgressUpdater *updater); void setUpdater(KoUpdaterPtr updater);
static QString askForAudioFileName(const QString &defaultDir, QWidget *parent); static QString askForAudioFileName(const QString &defaultDir, QWidget *parent);
......
...@@ -94,6 +94,7 @@ ...@@ -94,6 +94,7 @@
#include <KoDockRegistry.h> #include <KoDockRegistry.h>
#include <KoPluginLoader.h> #include <KoPluginLoader.h>
#include <KoColorSpaceEngine.h> #include <KoColorSpaceEngine.h>
#include <KoUpdater.h>
#include <KisMimeDatabase.h> #include <KisMimeDatabase.h>
#include <brushengine/kis_paintop_settings.h> #include <brushengine/kis_paintop_settings.h>
...@@ -1659,12 +1660,10 @@ void KisMainWindow::importAnimation() ...@@ -1659,12 +1660,10 @@ void KisMainWindow::importAnimation()
int firstFrame = dlg.firstFrame(); int firstFrame = dlg.firstFrame();
int step = dlg.step(); int step = dlg.step();
document->setFileProgressProxy(); KoUpdaterPtr updater =
document->setFileProgressUpdater(i18n("Import frames")); !document->fileBatchMode() ? viewManager()->createUpdater(i18n("Import frames"), false) : 0;
KisAnimationImporter importer(document); KisAnimationImporter importer(document->image(), updater);
KisImportExportFilter::ConversionStatus status = importer.import(files, firstFrame, step); KisImportExportFilter::ConversionStatus status = importer.import(files, firstFrame, step);
document->clearFileProgressUpdater();
document->clearFileProgressProxy();
if (status != KisImportExportFilter::OK && status != KisImportExportFilter::InternalError) { if (status != KisImportExportFilter::OK && status != KisImportExportFilter::InternalError) {
QString msg = KisImportExportFilter::conversionStatusString(status); QString msg = KisImportExportFilter::conversionStatusString(status);
......
...@@ -373,24 +373,12 @@ KisAnimationCachePopulator* KisPart::cachePopulator() const ...@@ -373,24 +373,12 @@ KisAnimationCachePopulator* KisPart::cachePopulator() const
void KisPart::openExistingFile(const QUrl &url) void KisPart::openExistingFile(const QUrl &url)
{ {
Q_ASSERT(url.isLocalFile()); // TODO: refactor out this method!
qApp->setOverrideCursor(Qt::BusyCursor);
KisDocument *document = createDocument();
if (!document->openUrl(url)) {
delete document;
return;
}
if (!document->image()) {
delete document;
return;
}
document->setModified(false);
addDocument(document);
KisMainWindow *mw = currentMainwindow(); KisMainWindow *mw = currentMainwindow();
mw->addViewAndNotifyLoadingCompleted(document); KIS_SAFE_ASSERT_RECOVER_RETURN(mw);
qApp->restoreOverrideCursor(); mw->openDocument(url, KisMainWindow::None);
} }
void KisPart::updateShortcuts() void KisPart::updateShortcuts()
......
...@@ -121,7 +121,7 @@ bool KisSaveGroupVisitor::visit(KisGroupLayer *layer) ...@@ -121,7 +121,7 @@ bool KisSaveGroupVisitor::visit(KisGroupLayer *layer)
QUrl url = QUrl::fromLocalFile(path); QUrl url = QUrl::fromLocalFile(path);
exportDocument->setFileBatchMode(true); exportDocument->setFileBatchMode(true);
exportDocument->exportDocument(url, m_mimeFilter.toLatin1()); exportDocument->exportDocumentSync(url, m_mimeFilter.toLatin1());
if (!m_saveTopLevelOnly) { if (!m_saveTopLevelOnly) {
KisGroupLayerSP child = dynamic_cast<KisGroupLayer*>(layer->firstChild().data()); KisGroupLayerSP child = dynamic_cast<KisGroupLayer*>(layer->firstChild().data());
......
...@@ -207,7 +207,7 @@ void KisTemplateCreateDia::createTemplate(const QString &templatesResourcePath, ...@@ -207,7 +207,7 @@ void KisTemplateCreateDia::createTemplate(const QString &templatesResourcePath,
} }
fileName = tempFile.fileName(); fileName = tempFile.fileName();
} }
bool retval = document->exportDocument(QUrl::fromLocalFile(fileName), document->mimeType()); bool retval = document->exportDocumentSync(QUrl::fromLocalFile(fileName), document->mimeType());
if (!retval) { if (!retval) {
qWarning("Could not save template"); qWarning("Could not save template");
return; return;
......
...@@ -81,10 +81,8 @@ ...@@ -81,10 +81,8 @@
#include "KisUndoStackAction.h" #include "KisUndoStackAction.h"
#include "KisViewManager.h" #include "KisViewManager.h"
#include "kis_zoom_manager.h" #include "kis_zoom_manager.h"
#include "kis_composite_progress_proxy.h"
#include "kis_statusbar.h" #include "kis_statusbar.h"
#include "kis_painting_assistants_decoration.h" #include "kis_painting_assistants_decoration.h"
#include "kis_progress_widget.h"
#include "kis_signal_compressor.h" #include "kis_signal_compressor.h"
#include "kis_filter_manager.h" #include "kis_filter_manager.h"
#include "kis_file_layer.h" #include "kis_file_layer.h"
...@@ -261,10 +259,6 @@ KisView::KisView(KisDocument *document, KoCanvasResourceManager *resourceManager ...@@ -261,10 +259,6 @@ KisView::KisView(KisDocument *document, KoCanvasResourceManager *resourceManager
KisView::~KisView() KisView::~KisView()
{ {
if (d->viewManager) { if (d->viewManager) {
KoProgressProxy *proxy = d->viewManager->statusBar()->progress()->progressProxy();
KIS_ASSERT_RECOVER_NOOP(proxy);
image()->compositeProgressProxy()->removeProxy(proxy);
if (d->viewManager->filterManager()->isStrokeRunning()) { if (d->viewManager->filterManager()->isStrokeRunning()) {
d->viewManager->filterManager()->cancel(); d->viewManager->filterManager()->cancel();
} }
...@@ -358,15 +352,6 @@ void KisView::setViewManager(KisViewManager *view) ...@@ -358,15 +352,6 @@ void KisView::setViewManager(KisViewManager *view)
SLOT(slotContinueRemoveNode(KisNodeSP)), SLOT(slotContinueRemoveNode(KisNodeSP)),
Qt::AutoConnection); Qt::AutoConnection);
/*
* WARNING: Currently we access the global progress bar in two ways:
* connecting to composite progress proxy (strokes) and creating
* progress updaters. The latter way should be deprecated in favour
* of displaying the status of the global strokes queue
*/
image()->compositeProgressProxy()->addProxy(d->viewManager->statusBar()->progress()->progressProxy());
connect(d->viewManager->statusBar()->progress(), SIGNAL(sigCancellationRequested()), image(), SLOT(requestStrokeCancellation()));
d->viewManager->updateGUI(); d->viewManager->updateGUI();
KoToolManager::instance()->switchToolRequested("KritaShape/KisToolBrush"); KoToolManager::instance()->switchToolRequested("KritaShape/KisToolBrush");
...@@ -681,7 +666,7 @@ void KisView::closeEvent(QCloseEvent *event) ...@@ -681,7 +666,7 @@ void KisView::closeEvent(QCloseEvent *event)
} }
if (queryClose()) { if (queryClose()) {
d->viewManager->removeStatusBarItem(zoomManager()->zoomActionWidget()); d->viewManager->statusBar()->setView(0);
event->accept(); event->accept();
return; return;
} }
......
...@@ -83,6 +83,7 @@ ...@@ -83,6 +83,7 @@
#include "kis_canvas_controls_manager.h" #include "kis_canvas_controls_manager.h"
#include "kis_canvas_resource_provider.h" #include "kis_canvas_resource_provider.h"
#include "kis_composite_progress_proxy.h" #include "kis_composite_progress_proxy.h"
#include <KoProgressUpdater.h>
#include "kis_config.h" #include "kis_config.h"
#include "kis_config_notifier.h" #include "kis_config_notifier.h"
#include "kis_control_frame.h" #include "kis_control_frame.h"
...@@ -107,7 +108,7 @@ ...@@ -107,7 +108,7 @@
#include <brushengine/kis_paintop_preset.h> #include <brushengine/kis_paintop_preset.h>
#include "KisPart.h" #include "KisPart.h"
#include "KisPrintJob.h" #include "KisPrintJob.h"
#include "kis_progress_widget.h" #include <KoUpdater.h>
#include "kis_resource_server_provider.h" #include "kis_resource_server_provider.h"
#include "kis_selection.h" #include "kis_selection.h"
#include "kis_selection_manager.h" #include "kis_selection_manager.h"
...@@ -128,6 +129,7 @@ ...@@ -128,6 +129,7 @@
#include "kis_guides_manager.h" #include "kis_guides_manager.h"
#include "kis_derived_resources.h" #include "kis_derived_resources.h"
#include "dialogs/kis_delayed_save_dialog.h" #include "dialogs/kis_delayed_save_dialog.h"
#include <kis_image.h>
class BlockingUserInputEventFilter : public QObject class BlockingUserInputEventFilter : public QObject
...@@ -221,6 +223,7 @@ public: ...@@ -221,6 +223,7 @@ public:
KisSelectionManager selectionManager; KisSelectionManager selectionManager;
KisGuidesManager guidesManager; KisGuidesManager guidesManager;
KisStatusBar statusBar; KisStatusBar statusBar;
QPointer<KoUpdater> persistentImageProgressUpdater;
KisControlFrame controlFrame; KisControlFrame controlFrame;
KisNodeManager nodeManager; KisNodeManager nodeManager;
...@@ -264,6 +267,13 @@ KisViewManager::KisViewManager(QWidget *parent, KActionCollection *_actionCollec ...@@ -264,6 +267,13 @@ KisViewManager::KisViewManager(QWidget *parent, KActionCollection *_actionCollec
// These initialization functions must wait until KisViewManager ctor is complete. // These initialization functions must wait until KisViewManager ctor is complete.
d->statusBar.setup(); d->statusBar.setup();
d->persistentImageProgressUpdater =
d->statusBar.progressUpdater()->startSubtask(1, "", true);
// reset state to nil
d->persistentImageProgressUpdater->setRange(0,100);
d->persistentImageProgressUpdater->setValue(100);
d->controlFrame.setup(parent); d->controlFrame.setup(parent);
//Check to draw scrollbars after "Canvas only mode" toggle is created. //Check to draw scrollbars after "Canvas only mode" toggle is created.
...@@ -347,6 +357,7 @@ void KisViewManager::setCurrentView(KisView *view) ...@@ -347,6 +357,7 @@ void KisViewManager::setCurrentView(KisView *view)
first = false; first = false;
KisDocument* doc = d->currentImageView->document(); KisDocument* doc = d->currentImageView->document();
if (doc) { if (doc) {
doc->image()->compositeProgressProxy()->removeProxy(d->persistentImageProgressUpdater);
doc->disconnect(this); doc->disconnect(this);
} }
d->currentImageView->canvasController()->proxyObject->disconnect(&d->statusBar); d->currentImageView->canvasController()->proxyObject->disconnect(&d->statusBar);
...@@ -413,6 +424,10 @@ void KisViewManager::setCurrentView(KisView *view) ...@@ -413,6 +424,10 @@ void KisViewManager::setCurrentView(KisView *view)
d->viewConnections.addUniqueConnection(d->softProof, SIGNAL(toggled(bool)), view, SLOT(slotSoftProofing(bool)) ); d->viewConnections.addUniqueConnection(d->softProof, SIGNAL(toggled(bool)), view, SLOT(slotSoftProofing(bool)) );
d->viewConnections.addUniqueConnection(d->gamutCheck, SIGNAL(toggled(bool)), view, SLOT(slotGamutCheck(bool)) ); d->viewConnections.addUniqueConnection(d->gamutCheck, SIGNAL(toggled(bool)), view, SLOT(slotGamutCheck(bool)) );
// set up progrress reporting
doc->image()->compositeProgressProxy()->addProxy(d->persistentImageProgressUpdater);
d->viewConnections.addUniqueConnection(&d->statusBar, SIGNAL(sigCancellationRequested()), doc->image(), SLOT(requestStrokeCancellation()));
imageView->zoomManager()->setShowRulers(d->showRulersAction->isChecked()); imageView->zoomManager()->setShowRulers(d->showRulersAction->isChecked());
imageView->zoomManager()->setRulersTrackMouse(d->rulersTrackMouseAction->isChecked()); imageView->zoomManager()->setRulersTrackMouse(d->rulersTrackMouseAction->isChecked());
...@@ -521,9 +536,14 @@ KisPaintopBox* KisViewManager::paintOpBox() const ...@@ -521,9 +536,14 @@ KisPaintopBox* KisViewManager::paintOpBox() const
return d->controlFrame.paintopBox(); return d->controlFrame.paintopBox();
} }
KoProgressUpdater* KisViewManager::createProgressUpdater(KoProgressUpdater::Mode mode) QPointer<KoUpdater> KisViewManager::createUpdater(const QString &name, bool isPersistent)
{ {
return new KisProgressUpdater(d->statusBar.progress(), document()->progressProxy(), mode); return d->statusBar.progressUpdater()->startSubtask(1, name, isPersistent);
}
void KisViewManager::removePersistentUpdater(QPointer<KoUpdater> updater)
{
return d->statusBar.progressUpdater()->removePersistentSubtask(updater);
} }
KisSelectionManager * KisViewManager::selectionManager() KisSelectionManager * KisViewManager::selectionManager()
...@@ -787,19 +807,19 @@ void KisViewManager::slotCreateTemplate() ...@@ -787,19 +807,19 @@ void KisViewManager::slotCreateTemplate()
void KisViewManager::slotCreateCopy() void KisViewManager::slotCreateCopy()
{ {
if (!document()) return; KisDocument *srcDoc = document();
KisDocument *doc = KisPart::instance()->createDocument(); if (!srcDoc) return;
KisDocument *doc = srcDoc->safeCreateClone();
if (!doc) return;
QString name = document()->documentInfo()->aboutInfo("name"); QString name = srcDoc->documentInfo()->aboutInfo("name");
if (name.isEmpty()) { if (name.isEmpty()) {
name = document()->url().toLocalFile(); name = document()->url().toLocalFile();
} }
name = i18n("%1 (Copy)", name); name = i18n("%1 (Copy)", name);
doc->documentInfo()->setAboutInfo("title", name); doc->documentInfo()->setAboutInfo("title", name);
KisImageWSP image = document()->image();
KisImageSP newImage = new KisImage(doc->createUndoStore(), image->width(), image->height(), image->colorSpace(), name);
newImage->setRootLayer(dynamic_cast<KisGroupLayer*>(image->rootLayer()->clone().data()));
doc->setCurrentImage(newImage);
KisPart::instance()->addDocument(doc); KisPart::instance()->addDocument(doc);
KisMainWindow *mw = qobject_cast<KisMainWindow*>(d->mainWindow); KisMainWindow *mw = qobject_cast<KisMainWindow*>(d->mainWindow);
mw->addViewAndNotifyLoadingCompleted(doc); mw->addViewAndNotifyLoadingCompleted(doc);
......
...@@ -24,7 +24,6 @@ ...@@ -24,7 +24,6 @@
#include <QPointer> #include <QPointer>
#include <KisMainWindow.h> #include <KisMainWindow.h>
#include <KoProgressUpdater.h>
#include <KoToolManager.h> #include <KoToolManager.h>
#include <kritaui_export.h> #include <kritaui_export.h>
...@@ -53,6 +52,8 @@ class KisPaintopBox; ...@@ -53,6 +52,8 @@ class KisPaintopBox;
class KisActionManager; class KisActionManager;
class KisScriptManager; class KisScriptManager;
class KisInputManager; class KisInputManager;
class KoUpdater;
class KoProgressUpdater;
/** /**
* Krita view class * Krita view class
...@@ -118,7 +119,8 @@ public: // Krita specific interfaces ...@@ -118,7 +119,8 @@ public: // Krita specific interfaces
KisPaintopBox* paintOpBox() const; KisPaintopBox* paintOpBox() const;
/// create a new progress updater /// create a new progress updater
KoProgressUpdater *createProgressUpdater(KoProgressUpdater::Mode mode = KoProgressUpdater::Threaded); QPointer<KoUpdater> createUpdater(const QString &name, bool isPersistent);
void removePersistentUpdater(QPointer<KoUpdater> updater);
/// The selection manager handles everything action related to /// The selection manager handles everything action related to
/// selections. /// selections.
......
...@@ -26,6 +26,7 @@ ...@@ -26,6 +26,7 @@
#include "KoFileDialog.h" #include "KoFileDialog.h"
#include "KisDocument.h" #include "KisDocument.h"
#include <KoUpdater.h>