mirror of https://github.com/JakubMelka/PDF4QT.git
Save document capability
This commit is contained in:
parent
e6d4eea9a2
commit
4e4bf111da
|
@ -299,5 +299,5 @@ void PDFExamplesGenerator::generateAnnotationsExample()
|
|||
// Write result to a file
|
||||
pdf::PDFDocument document = builder.build();
|
||||
pdf::PDFDocumentWriter writer(nullptr);
|
||||
writer.write("Ex_Annotations.pdf", &document);
|
||||
writer.write("Ex_Annotations.pdf", &document, false);
|
||||
}
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
#include "pdfparser.h"
|
||||
|
||||
#include <QFile>
|
||||
#include <QSaveFile>
|
||||
|
||||
namespace pdf
|
||||
{
|
||||
|
@ -170,19 +171,45 @@ void PDFWriteObjectVisitor::visitReference(const PDFObjectReference reference)
|
|||
m_device->write("R ");
|
||||
}
|
||||
|
||||
PDFOperationResult PDFDocumentWriter::write(const QString& fileName, const PDFDocument* document)
|
||||
PDFOperationResult PDFDocumentWriter::write(const QString& fileName, const PDFDocument* document, bool safeWrite)
|
||||
{
|
||||
QFile file(fileName);
|
||||
|
||||
if (file.open(QFile::WriteOnly | QFile::Truncate))
|
||||
if (safeWrite)
|
||||
{
|
||||
PDFOperationResult result = write(&file, document);
|
||||
file.close();
|
||||
return result;
|
||||
QSaveFile file(fileName);
|
||||
file.setDirectWriteFallback(true);
|
||||
|
||||
if (file.open(QFile::WriteOnly | QFile::Truncate))
|
||||
{
|
||||
PDFOperationResult result = write(&file, document);
|
||||
if (result)
|
||||
{
|
||||
file.commit();
|
||||
}
|
||||
else
|
||||
{
|
||||
file.cancelWriting();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
else
|
||||
{
|
||||
return tr("File '%1' can't be opened for writing. %2").arg(fileName, file.errorString());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return tr("File '%1' can't be opened for writing. %2").arg(fileName, file.errorString());
|
||||
QFile file(fileName);
|
||||
|
||||
if (file.open(QFile::WriteOnly | QFile::Truncate))
|
||||
{
|
||||
PDFOperationResult result = write(&file, document);
|
||||
file.close();
|
||||
return result;
|
||||
}
|
||||
else
|
||||
{
|
||||
return tr("File '%1' can't be opened for writing. %2").arg(fileName, file.errorString());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -40,7 +40,20 @@ public:
|
|||
|
||||
}
|
||||
|
||||
PDFOperationResult write(const QString& fileName, const PDFDocument* document);
|
||||
/// Writes document to the file. If \p safeWrite is true, then document is first
|
||||
/// written to the temporary file, and then renamed to original file name atomically,
|
||||
/// so no data can be lost on, for example, power failure. If it is not possible to
|
||||
/// create temporary file, then writing operation will attempt to write to the file
|
||||
/// directly.
|
||||
/// \param fileName File name
|
||||
/// \param document Document
|
||||
/// \param safeWrite Write document to the temporary file and then rename
|
||||
PDFOperationResult write(const QString& fileName, const PDFDocument* document, bool safeWrite);
|
||||
|
||||
/// Write document to the output device. Device must be writable (i.e. opened
|
||||
/// for writing).
|
||||
/// \param device Output device
|
||||
/// \param document Document
|
||||
PDFOperationResult write(QIODevice* device, const PDFDocument* document);
|
||||
|
||||
/// Calculates document file size, as if it is written to the disk.
|
||||
|
|
|
@ -38,6 +38,7 @@
|
|||
#include "pdfsendmail.h"
|
||||
#include "pdfexecutionpolicy.h"
|
||||
#include "pdfwidgetutils.h"
|
||||
#include "pdfdocumentwriter.h"
|
||||
|
||||
#include <QPainter>
|
||||
#include <QSettings>
|
||||
|
@ -56,6 +57,7 @@
|
|||
#include <QLabel>
|
||||
#include <QDoubleSpinBox>
|
||||
#include <QDesktopServices>
|
||||
#include <QFileDialog>
|
||||
#include <QtPrintSupport/QPrinter>
|
||||
#include <QtPrintSupport/QPrintDialog>
|
||||
#include <QtConcurrent/QtConcurrent>
|
||||
|
@ -122,6 +124,8 @@ PDFViewerMainWindow::PDFViewerMainWindow(QWidget* parent) :
|
|||
ui->actionPrint->setShortcut(QKeySequence::Print);
|
||||
ui->actionUndo->setShortcut(QKeySequence::Undo);
|
||||
ui->actionRedo->setShortcut(QKeySequence::Redo);
|
||||
ui->actionSave->setShortcut(QKeySequence::Save);
|
||||
ui->actionSave_As->setShortcut(QKeySequence::SaveAs);
|
||||
|
||||
for (QAction* action : m_recentFileManager->getActions())
|
||||
{
|
||||
|
@ -764,9 +768,9 @@ void PDFViewerMainWindow::updateTitle()
|
|||
QString title = m_pdfDocument->getInfo()->title;
|
||||
if (title.isEmpty())
|
||||
{
|
||||
title = m_currentFile;
|
||||
title = m_fileInfo.fileName;
|
||||
}
|
||||
setWindowTitle(tr("%1 - PDF Viewer").arg(m_currentFile));
|
||||
setWindowTitle(tr("%1 - PDF Viewer").arg(m_fileInfo.fileName));
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -888,6 +892,8 @@ void PDFViewerMainWindow::updateActionsAvailability()
|
|||
ui->actionPrint->setEnabled(hasValidDocument && canPrint);
|
||||
ui->actionRender_to_Images->setEnabled(hasValidDocument && canPrint);
|
||||
ui->actionOptimize->setEnabled(hasValidDocument);
|
||||
ui->actionSave->setEnabled(hasValidDocument);
|
||||
ui->actionSave_As->setEnabled(hasValidDocument);
|
||||
setEnabled(!isBusy);
|
||||
updateUndoRedoActions();
|
||||
}
|
||||
|
@ -917,11 +923,8 @@ void PDFViewerMainWindow::onRenderingOptionTriggered(bool checked)
|
|||
m_settings->setFeatures(features);
|
||||
}
|
||||
|
||||
void PDFViewerMainWindow::openDocument(const QString& fileName)
|
||||
void PDFViewerMainWindow::updateFileInfo(const QString& fileName)
|
||||
{
|
||||
// First close old document
|
||||
closeDocument();
|
||||
|
||||
QFileInfo fileInfo(fileName);
|
||||
m_fileInfo.originalFileName = fileName;
|
||||
m_fileInfo.fileName = fileInfo.fileName();
|
||||
|
@ -931,6 +934,14 @@ void PDFViewerMainWindow::openDocument(const QString& fileName)
|
|||
m_fileInfo.creationTime = fileInfo.created();
|
||||
m_fileInfo.lastModifiedTime = fileInfo.lastModified();
|
||||
m_fileInfo.lastReadTime = fileInfo.lastRead();
|
||||
}
|
||||
|
||||
void PDFViewerMainWindow::openDocument(const QString& fileName)
|
||||
{
|
||||
// First close old document
|
||||
closeDocument();
|
||||
|
||||
updateFileInfo(fileName);
|
||||
|
||||
QApplication::setOverrideCursor(Qt::WaitCursor);
|
||||
auto readDocument = [this, fileName]() -> AsyncReadingResult
|
||||
|
@ -981,7 +992,6 @@ void PDFViewerMainWindow::onDocumentReadingFinished()
|
|||
// Mark current directory as this
|
||||
QFileInfo fileInfo(m_fileInfo.originalFileName);
|
||||
m_settings->setDirectory(fileInfo.dir().absolutePath());
|
||||
m_currentFile = fileInfo.fileName();
|
||||
|
||||
// We add file to recent files only, if we have successfully read the document
|
||||
m_recentFileManager->addRecentFile(m_fileInfo.originalFileName);
|
||||
|
@ -1423,5 +1433,36 @@ void PDFViewerMainWindow::on_actionOptimize_triggered()
|
|||
}
|
||||
}
|
||||
|
||||
} // namespace pdfviewer
|
||||
void PDFViewerMainWindow::on_actionSave_As_triggered()
|
||||
{
|
||||
|
||||
QFileInfo fileInfo(m_fileInfo.originalFileName);
|
||||
QString saveFileName = QFileDialog::getSaveFileName(this, tr("Save As"), fileInfo.dir().absoluteFilePath(m_fileInfo.originalFileName), tr("Portable Document (*.pdf);;All files (*.*)"));
|
||||
if (!saveFileName.isEmpty())
|
||||
{
|
||||
saveDocument(saveFileName);
|
||||
}
|
||||
}
|
||||
|
||||
void PDFViewerMainWindow::on_actionSave_triggered()
|
||||
{
|
||||
saveDocument(m_fileInfo.originalFileName);
|
||||
}
|
||||
|
||||
void PDFViewerMainWindow::saveDocument(const QString& fileName)
|
||||
{
|
||||
pdf::PDFDocumentWriter writer(nullptr);
|
||||
pdf::PDFOperationResult result = writer.write(fileName, m_pdfDocument.data(), true);
|
||||
if (result)
|
||||
{
|
||||
updateFileInfo(fileName);
|
||||
updateTitle();
|
||||
m_recentFileManager->addRecentFile(fileName);
|
||||
}
|
||||
else
|
||||
{
|
||||
QMessageBox::critical(this, tr("Error"), result.getErrorMessage());
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace pdfviewer
|
||||
|
|
|
@ -101,6 +101,10 @@ private slots:
|
|||
|
||||
void on_actionOptimize_triggered();
|
||||
|
||||
void on_actionSave_As_triggered();
|
||||
|
||||
void on_actionSave_triggered();
|
||||
|
||||
private:
|
||||
void onActionOpenTriggered();
|
||||
void onActionCloseTriggered();
|
||||
|
@ -139,8 +143,10 @@ private:
|
|||
void openDocument(const QString& fileName);
|
||||
void setDocument(pdf::PDFModifiedDocument document);
|
||||
void closeDocument();
|
||||
void saveDocument(const QString& fileName);
|
||||
|
||||
void setPageLayout(pdf::PageLayout pageLayout);
|
||||
void updateFileInfo(const QString& fileName);
|
||||
|
||||
std::vector<QAction*> getRenderingOptionActions() const;
|
||||
QList<QAction*> getActions() const;
|
||||
|
@ -160,7 +166,6 @@ private:
|
|||
PDFViewerSettings* m_settings;
|
||||
pdf::PDFWidget* m_pdfWidget;
|
||||
pdf::PDFDocumentPointer m_pdfDocument;
|
||||
QString m_currentFile;
|
||||
PDFSidebarWidget* m_sidebarWidget;
|
||||
QDockWidget* m_sidebarDockWidget;
|
||||
PDFAdvancedFindWidget* m_advancedFindWidget;
|
||||
|
|
|
@ -30,6 +30,9 @@
|
|||
<addaction name="actionOpen"/>
|
||||
<addaction name="actionClose"/>
|
||||
<addaction name="separator"/>
|
||||
<addaction name="actionSave"/>
|
||||
<addaction name="actionSave_As"/>
|
||||
<addaction name="separator"/>
|
||||
<addaction name="actionSend_by_E_Mail"/>
|
||||
<addaction name="actionPrint"/>
|
||||
<addaction name="actionRender_to_Images"/>
|
||||
|
@ -536,6 +539,16 @@
|
|||
<string>Optimize</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionSave_As">
|
||||
<property name="text">
|
||||
<string>Save &As</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionSave">
|
||||
<property name="text">
|
||||
<string>Save</string>
|
||||
</property>
|
||||
</action>
|
||||
</widget>
|
||||
<layoutdefault spacing="6" margin="11"/>
|
||||
<resources>
|
||||
|
|
Loading…
Reference in New Issue