[Add] Export dialogue.
This commit is contained in:
parent
05d42cf2eb
commit
cc955d6489
67
bin/hpdf.pro
67
bin/hpdf.pro
@ -1,49 +1,30 @@
|
||||
QT += widgets
|
||||
|
||||
TEMPLATE = app
|
||||
TARGET = hpdf
|
||||
DEPENDPATH += .
|
||||
INCLUDEPATH += /usr/include/poppler/qt5/
|
||||
LIBS += -L/usr/lib -lpoppler-qt5
|
||||
TARGET = hpdf
|
||||
DEPENDPATH += .
|
||||
INCLUDEPATH += /usr/include/poppler/qt5
|
||||
LIBS += -L/usr/lib -lpoppler-qt5
|
||||
|
||||
HEADERS += \
|
||||
../src/pdf_factory.h \
|
||||
../src/pdf_page_widget.h \
|
||||
../src/pdf_table_widget.h \
|
||||
../src/pdf_file_widget.h \
|
||||
../src/pdf_jam.h \
|
||||
../src/thumbgen.h \
|
||||
../src/pdf_preview_widget.h
|
||||
# Input
|
||||
HEADERS += ../src/PDFExportDialog.h \
|
||||
../src/PDFFactory.h \
|
||||
../src/PDFFileWidget.h \
|
||||
../src/PDFJam.h \
|
||||
../src/PDFPageWidget.h \
|
||||
../src/PDFPreviewWidget.h \
|
||||
../src/PDFTableWidget.h \
|
||||
../src/PreviewGen.h \
|
||||
../src/ThumbGen.h
|
||||
|
||||
SOURCES += \
|
||||
../src/main.cpp \
|
||||
../src/pdf_factory.cpp \
|
||||
../src/pdf_page_widget.cpp \
|
||||
../src/pdf_table_widget.cpp \
|
||||
../src/pdf_file_widget.cpp \
|
||||
../src/pdf_jam.cpp \
|
||||
../src/thumbgen.cpp \
|
||||
../src/pdf_preview_widget.cpp
|
||||
SOURCES += ../src/main.cpp \
|
||||
../src/PDFExportDialog.cpp \
|
||||
../src/PDFFactory.cpp \
|
||||
../src/PDFFileWidget.cpp \
|
||||
../src/PDFJam.cpp \
|
||||
../src/PDFPageWidget.cpp \
|
||||
../src/PDFPreviewWidget.cpp \
|
||||
../src/PDFTableWidget.cpp \
|
||||
../src/PreviewGen.cpp \
|
||||
../src/ThumbGen.cpp
|
||||
|
||||
RESOURCES += hpdf.qrc
|
||||
|
||||
#CONFIG += console
|
||||
|
||||
macx {
|
||||
CONFIG(release, debug|release) {
|
||||
DESTDIR = ../bin/
|
||||
}
|
||||
}
|
||||
|
||||
win32 {
|
||||
CONFIG(release, debug|release) {
|
||||
DESTDIR = ../bin/
|
||||
}
|
||||
}
|
||||
|
||||
linux {
|
||||
CONFIG(release, debug|release) {
|
||||
DESTDIR = ../bin/
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -13,5 +13,6 @@
|
||||
<file>../img/expand.png</file>
|
||||
<file>../img/remove.png</file>
|
||||
<file>../img/rotate.png</file>
|
||||
<file>../img/delete.png</file>
|
||||
</qresource>
|
||||
</RCC>
|
||||
|
BIN
img/collapse.png
BIN
img/collapse.png
Binary file not shown.
Before Width: | Height: | Size: 850 B After Width: | Height: | Size: 244 B |
BIN
img/expand.png
BIN
img/expand.png
Binary file not shown.
Before Width: | Height: | Size: 893 B After Width: | Height: | Size: 387 B |
BIN
img/export.png
BIN
img/export.png
Binary file not shown.
Before Width: | Height: | Size: 2.2 KiB After Width: | Height: | Size: 1.1 KiB |
229
src/PDFExportDialog.cpp
Normal file
229
src/PDFExportDialog.cpp
Normal file
@ -0,0 +1,229 @@
|
||||
#include <QtWidgets>
|
||||
#include <QtGlobal>
|
||||
#include "PDFExportDialog.h"
|
||||
|
||||
PDFExportDialog::PDFExportDialog(QWidget *parent) :
|
||||
QDialog(parent) {
|
||||
mainLayout = new QGridLayout();
|
||||
mainLayout->setSpacing(15);
|
||||
|
||||
// File list
|
||||
fileListBox = new QGroupBox("Selected files");
|
||||
QVBoxLayout *fileListLayout = new QVBoxLayout();
|
||||
fileList = new QListWidget();
|
||||
connect(fileList, SIGNAL(currentRowChanged(int)), this, SLOT(fileListChanged(int)));
|
||||
fileListLayout->addWidget(fileList);
|
||||
fileListLayout->setContentsMargins(0, 20, 6, 6);
|
||||
fileListBox->setLayout(fileListLayout);
|
||||
mainLayout->addWidget(fileListBox, 0, 0, 4, 2);
|
||||
|
||||
// is landscape
|
||||
landscapeBox = new QGroupBox("Output orientation");
|
||||
QVBoxLayout *landscapeLayout = new QVBoxLayout();
|
||||
chkPortrait = new QRadioButton("Portrait");
|
||||
chkPortrait->setChecked(true);
|
||||
chkLandscape = new QRadioButton("Landscape");
|
||||
connect(chkLandscape, SIGNAL(toggled(bool)), this, SLOT(chkLandscapeChanged(bool)));
|
||||
landscapeLayout->addWidget(chkPortrait);
|
||||
landscapeLayout->addWidget(chkLandscape);
|
||||
landscapeBox->setLayout(landscapeLayout);
|
||||
|
||||
// n-up
|
||||
nupBox = new QGroupBox("N-up option");
|
||||
nupBox->setCheckable(true);
|
||||
nupBox->setChecked(false);
|
||||
connect(nupBox, SIGNAL(toggled(bool)), this, SLOT(nupBoxToggled(bool)));
|
||||
QGridLayout *nupLayout = new QGridLayout();
|
||||
QLabel *lblRow = new QLabel("Col:");
|
||||
QLabel *lblCol = new QLabel("Row:");
|
||||
txtRow = new QLineEdit("1");
|
||||
connect(txtRow, SIGNAL(textEdited(const QString &)), this, SLOT(txtRowChanged(const QString &)));
|
||||
txtCol = new QLineEdit("1");
|
||||
connect(txtCol, SIGNAL(textEdited(const QString &)), this, SLOT(txtColChanged(const QString &)));
|
||||
nupLayout->addWidget(lblRow, 0, 0, 1, 1);
|
||||
nupLayout->addWidget(txtRow, 0, 1, 1, 2);
|
||||
nupLayout->addWidget(lblCol, 1, 0, 1, 1);
|
||||
nupLayout->addWidget(txtCol, 1, 1, 1, 2);
|
||||
nupBox->setLayout(nupLayout);
|
||||
|
||||
// offsets
|
||||
offsetBox = new QGroupBox("Two-sided offset");
|
||||
offsetBox->setCheckable(true);
|
||||
offsetBox->setChecked(false);
|
||||
connect(offsetBox, SIGNAL(toggled(bool)), this, SLOT(offsetBoxToggled(bool)));
|
||||
QGridLayout *offsetLayout = new QGridLayout();
|
||||
QLabel *lblLeft = new QLabel("Left Offset:");
|
||||
txtLeftOffset = new QLineEdit("0");
|
||||
connect(txtLeftOffset, SIGNAL(textEdited(const QString &)), this, SLOT(txtLeftChanged(const QString &)));
|
||||
offsetLayout->addWidget(lblLeft, 0, 0, 1, 1);
|
||||
offsetLayout->addWidget(txtLeftOffset, 0, 1, 1, 2);
|
||||
offsetBox->setLayout(offsetLayout);
|
||||
|
||||
QVBoxLayout *midLayout = new QVBoxLayout();
|
||||
midLayout->addWidget(landscapeBox);midLayout->addWidget(nupBox);midLayout->addWidget(offsetBox);
|
||||
midLayout->addStretch(1);
|
||||
midLayout->setSpacing(10);
|
||||
QFrame *midFrame = new QFrame();
|
||||
midFrame->setFrameStyle(QFrame::StyledPanel | QFrame::Plain);
|
||||
midFrame->setLayout(midLayout);
|
||||
mainLayout->addWidget(midFrame, 0, 2, 4, 2);
|
||||
|
||||
// buttons
|
||||
QVBoxLayout *rightLayout = new QVBoxLayout();
|
||||
btnSave = new QPushButton("&Export...");
|
||||
connect(btnSave, SIGNAL(clicked()), this, SLOT(btnSaveClicked()));
|
||||
rightLayout->addWidget(btnSave);
|
||||
btnSaveAll = new QPushButton("Export &all files using\nthese settings...");
|
||||
connect(btnSaveAll, SIGNAL(clicked()), this, SLOT(btnSaveAllClicked()));
|
||||
rightLayout->addWidget(btnSaveAll);
|
||||
btnCancel = new QPushButton("&Done");
|
||||
connect(btnCancel, SIGNAL(clicked()), this, SLOT(btnCancelClicked()));
|
||||
rightLayout->addWidget(btnCancel);
|
||||
rightLayout->addStretch(1);
|
||||
mainLayout->addLayout(rightLayout, 0, 4, 2, 1);
|
||||
|
||||
setLayout(mainLayout);
|
||||
setGeometry(400, 400, 800, 450);
|
||||
setWindowTitle("Export to file");
|
||||
}
|
||||
|
||||
void PDFExportDialog::setFilesToExport(QVector<PDFFileWidget*> fileWidgets,
|
||||
QVector<QString> fileNames,
|
||||
QVector<int> fileIndices) {
|
||||
this->fileWidgets = fileWidgets;
|
||||
this->fileNames = fileNames;
|
||||
this->fileIndices = fileIndices;
|
||||
|
||||
QStringList modelList;
|
||||
|
||||
foreach (const QString str, fileNames) {
|
||||
modelList << str;
|
||||
|
||||
QVector<QVariant> option; // Landscape, row, col, left, right, twosided
|
||||
bool ok;
|
||||
option.append(QVariant(chkLandscape->isChecked()));
|
||||
option.append(QVariant(nupBox->isChecked()));
|
||||
option.append(QVariant(txtRow->text().toInt(&ok)));
|
||||
option.append(QVariant(txtCol->text().toInt(&ok)));
|
||||
option.append(QVariant(offsetBox->isChecked()));
|
||||
option.append(QVariant(txtLeftOffset->text().toInt(&ok)));
|
||||
|
||||
options.append(option);
|
||||
}
|
||||
|
||||
fileList->addItems(modelList);
|
||||
}
|
||||
|
||||
void PDFExportDialog::btnSaveClicked(void) {
|
||||
int selectedIndex = fileList->currentRow();
|
||||
QVector<QVariant> option = options.at(selectedIndex);
|
||||
|
||||
QString fileName = QFileDialog::getSaveFileName(this,
|
||||
tr("Save PDF file"), ".",
|
||||
tr("PDF file (*.pdf)"));
|
||||
if (!fileName.isEmpty()) {
|
||||
QSize nup;
|
||||
//if (option.at(0).toBool())
|
||||
//nup = QSize(option.at(3).toInt(), option.at(2).toInt());
|
||||
//else
|
||||
nup = QSize(option.at(2).toInt(), option.at(3).toInt());
|
||||
|
||||
pdfJam.exportFile(fileIndices.at(selectedIndex), fileWidgets.at(selectedIndex)->getChildCount(), fileName,
|
||||
option.at(1).toBool(), nup, // nup
|
||||
option.at(0).toBool(), // landscape
|
||||
option.at(4).toBool(), option.at(5).toInt()); //offset
|
||||
|
||||
QMessageBox::information(this, tr("PDFFactory"), tr("Exported succesfully to\n%1.").arg(fileName));
|
||||
}
|
||||
}
|
||||
|
||||
void PDFExportDialog::btnSaveAllClicked(void) {
|
||||
bool ok;
|
||||
for (int i = 0; i < fileNames.size(); i++) {
|
||||
QString fileName = QFileDialog::getSaveFileName(this,
|
||||
tr("Save PDF file"), ".",
|
||||
tr("PDF file (*.pdf)"));
|
||||
|
||||
QSize nup;
|
||||
//if (chkLandscape->isChecked())
|
||||
//nup = QSize(txtCol->text().toInt(&ok), txtRow->text().toInt(&ok));
|
||||
//else
|
||||
nup = QSize(txtRow->text().toInt(&ok), txtCol->text().toInt(&ok));
|
||||
|
||||
if (!fileName.isEmpty()) {
|
||||
pdfJam.exportFile(fileIndices.at(i), fileWidgets.at(i)->getChildCount(), fileName,
|
||||
nupBox->isChecked(), nup,
|
||||
chkLandscape->isChecked(),
|
||||
offsetBox->isChecked(), txtLeftOffset->text().toInt(&ok));
|
||||
QMessageBox::information(this, tr("PDFFactory"), tr("Exported succesfully to\n%1.").arg(fileName));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void PDFExportDialog::btnCancelClicked(void) {
|
||||
accept();
|
||||
}
|
||||
|
||||
void PDFExportDialog::fileListChanged(int row) {
|
||||
QVector<QVariant> option = options.at(row);
|
||||
chkLandscape->setChecked(option.at(0).toBool());
|
||||
nupBox->setChecked(option.at(1).toBool());
|
||||
txtRow->setText(QString::number(option.at(2).toInt()));
|
||||
txtCol->setText(QString::number(option.at(3).toInt()));
|
||||
offsetBox->setChecked(option.at(4).toBool());
|
||||
txtLeftOffset->setText(QString::number(option.at(5).toInt()));
|
||||
}
|
||||
|
||||
void PDFExportDialog::txtRowChanged(const QString &txt) {
|
||||
bool ok;
|
||||
QVector<QVariant> option = options.at(fileList->currentRow());
|
||||
option.remove(2);
|
||||
option.insert(2, QVariant(txt.toInt(&ok)));
|
||||
options.remove(fileList->currentRow());
|
||||
options.insert(fileList->currentRow(), option);
|
||||
}
|
||||
|
||||
void PDFExportDialog::txtColChanged(const QString &txt) {
|
||||
bool ok;
|
||||
QVector<QVariant> option = options.at(fileList->currentRow());
|
||||
option.remove(3);
|
||||
option.insert(3, QVariant(txt.toInt(&ok)));
|
||||
options.remove(fileList->currentRow());
|
||||
options.insert(fileList->currentRow(), option);
|
||||
}
|
||||
|
||||
void PDFExportDialog::txtLeftChanged(const QString &txt) {
|
||||
bool ok;
|
||||
QVector<QVariant> option = options.at(fileList->currentRow());
|
||||
option.remove(5);
|
||||
option.insert(5, QVariant(txt.toInt(&ok)));
|
||||
options.remove(fileList->currentRow());
|
||||
options.insert(fileList->currentRow(), option);
|
||||
}
|
||||
|
||||
void PDFExportDialog::chkLandscapeChanged(bool state) {
|
||||
(void) state;
|
||||
QVector<QVariant> option = options.at(fileList->currentRow());
|
||||
option.remove(0);
|
||||
option.insert(0, QVariant(chkLandscape->isChecked()));
|
||||
options.remove(fileList->currentRow());
|
||||
options.insert(fileList->currentRow(), option);
|
||||
}
|
||||
|
||||
void PDFExportDialog::nupBoxToggled(bool checked) {
|
||||
(void) checked;
|
||||
QVector<QVariant> option = options.at(fileList->currentRow());
|
||||
option.remove(1);
|
||||
option.insert(1, QVariant(nupBox->isChecked()));
|
||||
options.remove(fileList->currentRow());
|
||||
options.insert(fileList->currentRow(), option);
|
||||
}
|
||||
|
||||
void PDFExportDialog::offsetBoxToggled(bool checked) {
|
||||
(void) checked;
|
||||
QVector<QVariant> option = options.at(fileList->currentRow());
|
||||
option.remove(4);
|
||||
option.insert(4, QVariant(offsetBox->isChecked()));
|
||||
options.remove(fileList->currentRow());
|
||||
options.insert(fileList->currentRow(), option);
|
||||
}
|
50
src/PDFExportDialog.h
Normal file
50
src/PDFExportDialog.h
Normal file
@ -0,0 +1,50 @@
|
||||
#pragma once
|
||||
#include <QDialog>
|
||||
#include "PDFFileWidget.h"
|
||||
#include "PDFJam.h"
|
||||
|
||||
class QGridLayout;
|
||||
class QGroupBox;
|
||||
class QListWidget;
|
||||
class QLineEdit;
|
||||
class QRadioButton;
|
||||
|
||||
class PDFExportDialog : public QDialog {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit PDFExportDialog(QWidget *parent = 0);
|
||||
|
||||
private:
|
||||
QVector<PDFFileWidget*> fileWidgets;
|
||||
QVector<QString> fileNames;
|
||||
QVector<int> fileIndices;
|
||||
QVector<QVector<QVariant> > options;
|
||||
|
||||
private:
|
||||
PDFJam pdfJam;
|
||||
QGroupBox *fileListBox, *landscapeBox, *nupBox, *offsetBox;
|
||||
|
||||
QPushButton *btnSave, *btnSaveAll, *btnCancel;
|
||||
QGridLayout *mainLayout;
|
||||
|
||||
QListWidget *fileList;
|
||||
QLineEdit *txtRow, *txtCol;
|
||||
QRadioButton *chkPortrait, *chkLandscape;
|
||||
QLineEdit *txtLeftOffset;
|
||||
|
||||
public:
|
||||
void setFilesToExport(QVector<PDFFileWidget*> fileWidgets, QVector<QString> fileNames, QVector<int> fileIndices);
|
||||
|
||||
private slots:
|
||||
void fileListChanged(int);
|
||||
void btnSaveClicked(void);
|
||||
void btnSaveAllClicked(void);
|
||||
void btnCancelClicked(void);
|
||||
void txtRowChanged(const QString &);
|
||||
void txtColChanged(const QString &);
|
||||
void txtLeftChanged(const QString &);
|
||||
void chkLandscapeChanged(bool);
|
||||
void nupBoxToggled(bool);
|
||||
void offsetBoxToggled(bool);
|
||||
};
|
218
src/PDFFactory.cpp
Normal file
218
src/PDFFactory.cpp
Normal file
@ -0,0 +1,218 @@
|
||||
#include <QtWidgets>
|
||||
#include <QtGlobal>
|
||||
#include "PDFFactory.h"
|
||||
#include "PDFExportDialog.h"
|
||||
#include "PDFTableWidget.h"
|
||||
#include "PDFPreviewWidget.h"
|
||||
#include "PDFPageWidget.h"
|
||||
|
||||
PDFFactory::PDFFactory()
|
||||
{
|
||||
createWidgets();
|
||||
createActions();
|
||||
createToolBars();
|
||||
createRibbon();
|
||||
createStatusBar();
|
||||
}
|
||||
|
||||
void PDFFactory::createWidgets()
|
||||
{
|
||||
// Set central widget to be the container root
|
||||
centralWidget = new QWidget();
|
||||
QVBoxLayout *layout = new QVBoxLayout();
|
||||
layout->setContentsMargins(2,2,2,2);
|
||||
centralWidget->setLayout(layout);
|
||||
setCentralWidget(centralWidget);
|
||||
|
||||
// Create ribbon
|
||||
ribbon = new QTabWidget();
|
||||
ribbon->addTab(new QWidget(), tr("File"));
|
||||
ribbon->addTab(new QWidget(), tr("Edit"));
|
||||
ribbon->addTab(new QWidget(), tr("Tools"));
|
||||
ribbon->addTab(new QWidget(), tr("Help"));
|
||||
ribbon->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
|
||||
ribbon->setFixedHeight(100);
|
||||
layout->addWidget(ribbon);
|
||||
|
||||
// Create main area (table)
|
||||
|
||||
pdfTableView = new PDFTableWidget();
|
||||
pdfPreview = new PDFPreviewWidget();
|
||||
pdfPreview->setMinimumWidth(100);
|
||||
splitter = new QSplitter();
|
||||
splitter->setOrientation(Qt::Horizontal);
|
||||
splitter->addWidget(pdfTableView);
|
||||
splitter->addWidget(pdfPreview);
|
||||
QList<int> splitterWidgetSizes;
|
||||
splitterWidgetSizes << 200 << 1000;
|
||||
splitter->setSizes(splitterWidgetSizes);
|
||||
splitter->setStretchFactor(0, 1);
|
||||
splitter->setStretchFactor(1, 0.5);
|
||||
layout->addWidget(splitter);
|
||||
|
||||
connect(pdfTableView, SIGNAL(previewUpdate(Poppler::Page*, Poppler::Page::Rotation)), pdfPreview, SLOT(previewUpdate(Poppler::Page*, Poppler::Page::Rotation)));
|
||||
connect(pdfTableView, SIGNAL(checkPreviewUpdate(Poppler::Page*, Poppler::Page::Rotation)), pdfPreview, SLOT(checkPreviewUpdate(Poppler::Page*, Poppler::Page::Rotation)));
|
||||
connect(pdfTableView, SIGNAL(checkPagePreviewExisted(Poppler::Page*)), pdfPreview, SLOT(checkPagePreviewExisted(Poppler::Page*)));
|
||||
|
||||
setWindowIcon(QIcon(":/img/hpdf.png"));
|
||||
setWindowTitle(tr("PDF Factory"));
|
||||
setGeometry(0, 0, 1300, 650);
|
||||
}
|
||||
|
||||
|
||||
void PDFFactory::createActions()
|
||||
{
|
||||
openAction = new QAction(tr("&Open"), this);
|
||||
openAction->setIcon(QIcon(":/img/open.png"));
|
||||
openAction->setShortcut(tr("Ctrl+O"));
|
||||
openAction->setStatusTip(tr("Open a PDF"));
|
||||
connect(openAction, SIGNAL(triggered()), this, SLOT(openFile()));
|
||||
|
||||
exportAction = new QAction(tr("&Export a single file"), this);
|
||||
exportAction->setIcon(QIcon(":/img/export.png"));
|
||||
exportAction->setShortcut(tr("Ctrl+S"));
|
||||
exportAction->setStatusTip(tr("Export the selected file to a new PDF"));
|
||||
connect(exportAction, SIGNAL(triggered()), this, SLOT(exportFile()));
|
||||
|
||||
exportAllAction = new QAction(tr("Export all"), this);
|
||||
exportAllAction->setIcon(QIcon(":/img/exportall.png"));
|
||||
exportAllAction->setShortcut(tr("Shift+Ctrl+S"));
|
||||
exportAllAction->setStatusTip(tr("Export all to multiple PDF files"));
|
||||
connect(exportAllAction, SIGNAL(triggered()), this, SLOT(exportAllFiles()));
|
||||
|
||||
cutAction = new QAction(tr("C&ut"), this);
|
||||
cutAction->setIcon(QIcon(":/img/cut.png"));
|
||||
cutAction->setShortcut(tr("Ctrl+X"));
|
||||
cutAction->setStatusTip(tr("Cut selected contents to clipboard"));
|
||||
connect(cutAction, SIGNAL(triggered()), pdfTableView, SLOT(cutSelected()));
|
||||
|
||||
copyAction = new QAction(tr("&Copy"), this);
|
||||
copyAction->setIcon(QIcon(":/img/copy.png"));
|
||||
copyAction->setShortcut(tr("Ctrl+C"));
|
||||
copyAction->setStatusTip(tr("Copy selected contents to clipboard"));
|
||||
connect(copyAction, SIGNAL(triggered()), pdfTableView, SLOT(copySelected()));
|
||||
|
||||
pasteAction = new QAction(tr("&Paste"), this);
|
||||
pasteAction->setIcon(QIcon(":/img/paste.png"));
|
||||
pasteAction->setShortcut(tr("Ctrl+V"));
|
||||
pasteAction->setStatusTip(tr("Paste clipboard's contents into current selection"));
|
||||
//connect(pasteAction, SIGNAL(triggered()), textEdit, SLOT(paste()));
|
||||
|
||||
deleteAction = new QAction(tr("&Delete"), this);
|
||||
deleteAction->setIcon(QIcon(":/img/delete.png"));
|
||||
deleteAction->setShortcut(tr("Ctrl+D"));
|
||||
deleteAction->setStatusTip(tr("Delete selected contents"));
|
||||
connect(deleteAction, SIGNAL(triggered()), pdfTableView, SLOT(deleteSelected()));
|
||||
|
||||
rotateAction = new QAction(tr("&Rotate"), this);
|
||||
rotateAction->setIcon(QIcon(":/img/rotate.png"));
|
||||
rotateAction->setShortcut(tr("Ctrl+R"));
|
||||
rotateAction->setStatusTip(tr("Rotate selected pages"));
|
||||
connect(rotateAction, SIGNAL(triggered()), pdfTableView, SLOT(rotateSelected()));
|
||||
|
||||
aboutAction = new QAction(tr("A&bout"), this);
|
||||
aboutAction->setIcon(QIcon(":/img/about.png"));
|
||||
aboutAction->setStatusTip(tr("About this program"));
|
||||
connect(aboutAction, SIGNAL(triggered()), this, SLOT(about()));
|
||||
}
|
||||
|
||||
void PDFFactory::createToolBars()
|
||||
{
|
||||
fileToolBar = new QToolBar(tr("File"));
|
||||
fileToolBar->addAction(openAction);
|
||||
fileToolBar->addAction(exportAction);
|
||||
fileToolBar->addAction(exportAllAction);
|
||||
fileToolBar->setIconSize(QSize(48, 48));
|
||||
|
||||
editToolBar = new QToolBar(tr("Edit"));
|
||||
editToolBar->addAction(cutAction);
|
||||
editToolBar->addAction(copyAction);
|
||||
editToolBar->addAction(pasteAction);
|
||||
editToolBar->addSeparator();
|
||||
editToolBar->addAction(deleteAction);
|
||||
editToolBar->setIconSize(QSize(48, 48));
|
||||
|
||||
toolsToolBar = new QToolBar(tr("Tools"));
|
||||
toolsToolBar->addAction(rotateAction);
|
||||
toolsToolBar->setIconSize(QSize(48, 48));
|
||||
|
||||
helpToolBar = new QToolBar(tr("Help"));
|
||||
helpToolBar->addAction(aboutAction);
|
||||
helpToolBar->setIconSize(QSize(48, 48));
|
||||
}
|
||||
|
||||
void PDFFactory::createRibbon()
|
||||
{
|
||||
QWidget *tabFile = ribbon->widget(0);
|
||||
QVBoxLayout *layoutTabFile = new QVBoxLayout();
|
||||
layoutTabFile->setContentsMargins(2,0,2,0);
|
||||
layoutTabFile->addWidget(fileToolBar);
|
||||
tabFile->setLayout(layoutTabFile);
|
||||
|
||||
QWidget *tabEdit = ribbon->widget(1);
|
||||
QVBoxLayout *layoutTabEdit = new QVBoxLayout();
|
||||
layoutTabEdit->setContentsMargins(2,0,2,0);
|
||||
layoutTabEdit->addWidget(editToolBar);
|
||||
tabEdit->setLayout(layoutTabEdit);
|
||||
|
||||
QWidget *tabTools = ribbon->widget(2);
|
||||
QVBoxLayout *layoutTabTools = new QVBoxLayout();
|
||||
layoutTabTools->setContentsMargins(2,0,2,0);
|
||||
layoutTabTools->addWidget(toolsToolBar);
|
||||
tabTools->setLayout(layoutTabTools);
|
||||
|
||||
QWidget *tabHelp = ribbon->widget(3);
|
||||
QVBoxLayout *layoutTabHelp = new QVBoxLayout();
|
||||
layoutTabHelp->setContentsMargins(2,0,2,0);
|
||||
layoutTabHelp->addWidget(helpToolBar);
|
||||
tabHelp->setLayout(layoutTabHelp);
|
||||
}
|
||||
|
||||
void PDFFactory::createStatusBar()
|
||||
{
|
||||
statusBar()->showMessage(tr(""));
|
||||
}
|
||||
|
||||
void PDFFactory::openFile(void) {
|
||||
QStringList fileNames = QFileDialog::getOpenFileNames(this,
|
||||
tr("Open PDF file"), ".",
|
||||
tr("PDF file (*.pdf)"));
|
||||
|
||||
for (int i = 0; i < fileNames.size(); i++) {
|
||||
QString fileName = fileNames.at(i);
|
||||
if (!fileName.isEmpty()) {
|
||||
pdfTableView->loadFile(fileName);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void PDFFactory::exportFile(void) {
|
||||
PDFExportDialog *exportDialog = new PDFExportDialog();
|
||||
|
||||
QVector<PDFFileWidget*> selectedFiles = pdfTableView->getSelectedFiles();
|
||||
if (selectedFiles.size() > 0) {
|
||||
exportDialog->setFilesToExport(selectedFiles, pdfTableView->getSelectedFileNames(), pdfTableView->getSelectedIndices());
|
||||
exportDialog->show();
|
||||
}
|
||||
}
|
||||
|
||||
void PDFFactory::exportAllFiles(void) {
|
||||
PDFExportDialog *exportDialog = new PDFExportDialog();
|
||||
|
||||
QVector<PDFFileWidget*> visibleFiles = pdfTableView->getVisibleFiles();
|
||||
|
||||
if (visibleFiles.size() > 0) {
|
||||
exportDialog->setFilesToExport(visibleFiles, pdfTableView->getVisibleFileNames(), pdfTableView->getVisibleIndices());
|
||||
exportDialog->show();
|
||||
}
|
||||
}
|
||||
|
||||
void PDFFactory::about(void) {
|
||||
QMessageBox::information(this, tr("PDFFactory"), tr("HPDF (Harringtons PDF) "
|
||||
"version 0.1.0\nWritten by: Ritchie Cunningham\n\n"
|
||||
"HPDF is primarily a PDF viewer with the prospect of becoming a full "
|
||||
"featured PDF editor.\n\n"
|
||||
"This software is unique in the fact that it automates tasks "
|
||||
"unique to Harringtons Advisory.\n\n"
|
||||
"Need support? Email customerservice@sccsolutions.biz"));
|
||||
}
|
55
src/PDFFactory.h
Normal file
55
src/PDFFactory.h
Normal file
@ -0,0 +1,55 @@
|
||||
#pragma once
|
||||
#include <QMainWindow>
|
||||
|
||||
class PDFTableWidget;
|
||||
class PDFPreviewWidget;
|
||||
|
||||
class QAction;
|
||||
class QWidget;
|
||||
class QTabWidget;
|
||||
class QScrollArea;
|
||||
class QSplitter;
|
||||
class QToolBar;
|
||||
|
||||
class PDFFactory: public QMainWindow
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
PDFFactory();
|
||||
|
||||
private slots:
|
||||
void openFile(void);
|
||||
void exportFile(void);
|
||||
void exportAllFiles(void);
|
||||
void about(void);
|
||||
|
||||
private:
|
||||
void createWidgets(void);
|
||||
void createActions(void);
|
||||
void createToolBars(void);
|
||||
void createRibbon(void);
|
||||
void createStatusBar(void);
|
||||
|
||||
QAction *openAction;
|
||||
QAction *exportAction;
|
||||
QAction *exportAllAction;
|
||||
QAction *cutAction;
|
||||
QAction *copyAction;
|
||||
QAction *pasteAction;
|
||||
QAction *deleteAction;
|
||||
QAction *rotateAction;
|
||||
QAction *aboutAction;
|
||||
|
||||
QWidget *centralWidget;
|
||||
|
||||
QTabWidget *ribbon;
|
||||
QSplitter *splitter;
|
||||
PDFTableWidget *pdfTableView;
|
||||
PDFPreviewWidget *pdfPreview;
|
||||
|
||||
QToolBar *fileToolBar;
|
||||
QToolBar *editToolBar;
|
||||
QToolBar *toolsToolBar;
|
||||
QToolBar *helpToolBar;
|
||||
};
|
232
src/PDFFileWidget.cpp
Normal file
232
src/PDFFileWidget.cpp
Normal file
@ -0,0 +1,232 @@
|
||||
#include <QtGlobal>
|
||||
#include <QtWidgets>
|
||||
|
||||
#include "PDFFileWidget.h"
|
||||
#include "PDFPageWidget.h"
|
||||
#include "PDFTableWidget.h"
|
||||
|
||||
#define COLLAPSE_BUTTON_WIDTH 32
|
||||
#define COLLAPSE_BUTTON_HEIGHT 32
|
||||
|
||||
#define CHILD_AREA_WIDTH 150
|
||||
#define CHILD_AREA_HEIGHT 150
|
||||
#define CHILD_AREA_SIDE_MARGIN 20
|
||||
|
||||
#define DEFAULT_CHILD_SIZE 169
|
||||
|
||||
PagesContainerWidget::PagesContainerWidget(QWidget *parent) {
|
||||
(void) parent;
|
||||
setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
|
||||
setAcceptDrops(true);
|
||||
mainLayout = new QHBoxLayout();
|
||||
|
||||
this->setContextMenuPolicy(Qt::CustomContextMenu);
|
||||
connect(this, SIGNAL(customContextMenuRequested(const QPoint&)),
|
||||
this, SLOT(ShowContextMenu(const QPoint&)));
|
||||
|
||||
setLayout(mainLayout);
|
||||
}
|
||||
|
||||
void PagesContainerWidget::ShowContextMenu(const QPoint& pos){
|
||||
if (((PDFTableWidget*)ancestor)->hasClipboard()){
|
||||
QPoint globalPos = this->mapToGlobal(pos);
|
||||
|
||||
QMenu myMenu;
|
||||
myMenu.addAction(QIcon(":/img/remove.png"), "Paste");
|
||||
|
||||
QAction* selectedItem = myMenu.exec(globalPos);
|
||||
if (selectedItem)
|
||||
{
|
||||
int page;
|
||||
|
||||
if (pageWidgets.size()>=2)
|
||||
page = (pos.x() / (pageWidgets.at(1)->geometry().x() -
|
||||
pageWidgets.at(0)->geometry().x()) );
|
||||
else
|
||||
page = (pos.x() / DEFAULT_CHILD_SIZE );
|
||||
|
||||
|
||||
PDFTableWidget *tableview = (PDFTableWidget*) ancestor;
|
||||
tableview->pastePage((PDFFileWidget*)father, page);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
int PagesContainerWidget::getPagesCount() const {
|
||||
return pageWidgets.size();
|
||||
}
|
||||
|
||||
QSize PagesContainerWidget::sizeHint() const {
|
||||
QSize temp = QSize((CHILD_AREA_SIDE_MARGIN + CHILD_AREA_WIDTH) * getPagesCount(), CHILD_AREA_HEIGHT + 30);
|
||||
return temp;
|
||||
}
|
||||
|
||||
void PagesContainerWidget::addPageWidget(PDFPageWidget *pageWidget){
|
||||
pageWidgets.append(pageWidget);
|
||||
mainLayout->addWidget(pageWidget);
|
||||
adjustSize();
|
||||
}
|
||||
|
||||
void PagesContainerWidget::dragEnterEvent(QDragEnterEvent *event) {
|
||||
event->acceptProposedAction();
|
||||
}
|
||||
|
||||
void PagesContainerWidget::dropEvent(QDropEvent *event) {
|
||||
QPoint pos = event->pos();
|
||||
int page = (pos.x() / (CHILD_AREA_SIDE_MARGIN + CHILD_AREA_WIDTH));
|
||||
((PDFTableWidget*)ancestor)->moveSelectedPages(event->mimeData()->text() , pageWidgets.at(page));
|
||||
event->acceptProposedAction();
|
||||
}
|
||||
|
||||
// ======================================================================
|
||||
|
||||
PDFFileWidget::PDFFileWidget(QWidget *parent):QFrame(parent){
|
||||
setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
|
||||
setFrameStyle(QFrame::Box);
|
||||
|
||||
topLayout = new QGridLayout();
|
||||
|
||||
collapseButton = new QPushButton();
|
||||
collapseButton->resize(QSize(COLLAPSE_BUTTON_WIDTH,COLLAPSE_BUTTON_HEIGHT));
|
||||
collapseButton->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
|
||||
collapseButton->setIcon(QIcon(":/img/collapse.png"));
|
||||
connect(collapseButton, SIGNAL(released()), this, SLOT(collapsedButtonClicked()));
|
||||
topLayout->addWidget(collapseButton, 0, 0);
|
||||
|
||||
fileNameLabel = new QLabel();
|
||||
fileNameLabel->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
|
||||
topLayout->addWidget(fileNameLabel, 0, 1);
|
||||
|
||||
removeButton = new QPushButton();
|
||||
removeButton->resize(QSize(COLLAPSE_BUTTON_WIDTH,COLLAPSE_BUTTON_HEIGHT));
|
||||
removeButton->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
|
||||
removeButton->setIcon(QIcon(":/img/remove.png"));
|
||||
connect(removeButton, SIGNAL(released()), this, SLOT(removeButtonClicked()));
|
||||
topLayout->addWidget(removeButton, 0, 2);
|
||||
|
||||
pagesContainerWidget = new PagesContainerWidget();
|
||||
pagesContainerWidget->setFather(this);
|
||||
scrollArea = new QScrollArea();
|
||||
scrollArea->setWidget(pagesContainerWidget);
|
||||
scrollArea->setVerticalScrollBarPolicy( Qt::ScrollBarAlwaysOff );
|
||||
topLayout->addWidget(scrollArea, 1, 0, 1, 3);
|
||||
|
||||
topLayout->setContentsMargins(6, 10, 6, 10);
|
||||
setLayout(topLayout);
|
||||
|
||||
setCollapsed(false);
|
||||
selected = false;
|
||||
|
||||
connect(&tgen, SIGNAL(updateThumbnail(QImage,PDFPageWidget*)), this, SLOT(updateThumbnail(QImage,PDFPageWidget*)));
|
||||
}
|
||||
|
||||
void PDFFileWidget::setAncestor(QWidget* ancestor) {
|
||||
this->ancestor = ancestor;
|
||||
pagesContainerWidget->setAncestor(ancestor);
|
||||
connect(this, SIGNAL(fileClicked(PDFFileWidget*, QMouseEvent*)), ancestor, SLOT(fileClicked(PDFFileWidget*, QMouseEvent*)));
|
||||
}
|
||||
|
||||
void PDFFileWidget::setSelected(bool select) {
|
||||
selected = select;
|
||||
update();
|
||||
}
|
||||
|
||||
void PDFFileWidget::mousePressEvent(QMouseEvent *event) {
|
||||
emit fileClicked(this, event);
|
||||
}
|
||||
|
||||
void PDFFileWidget::paintEvent(QPaintEvent *event) {
|
||||
QPalette palette = this->palette();
|
||||
QPalette labelPalette = fileNameLabel->palette();
|
||||
if (selected) {
|
||||
palette.setColor( foregroundRole(), palette.color(QPalette::Highlight) );
|
||||
labelPalette.setColor( foregroundRole(), palette.color(QPalette::Highlight) );
|
||||
} else {
|
||||
palette.setColor( foregroundRole(), palette.color(QPalette::Dark) );
|
||||
labelPalette.setColor( foregroundRole(), palette.color(QPalette::Text) );
|
||||
}
|
||||
this->setPalette(palette);
|
||||
fileNameLabel->setPalette(labelPalette);
|
||||
|
||||
QFrame::paintEvent(event);
|
||||
}
|
||||
|
||||
void PDFFileWidget::updateThumbnail(QImage img, PDFPageWidget* pageWidget){
|
||||
pageWidget->setThumbnail(img);
|
||||
}
|
||||
|
||||
void PDFFileWidget::setCollapsed(bool state){
|
||||
collapsed = state;
|
||||
if (state == true) {
|
||||
scrollArea->hide();
|
||||
collapseButton->setIcon(QIcon(":/img/expand.png"));
|
||||
} else {
|
||||
scrollArea->show();
|
||||
collapseButton->setIcon(QIcon(":/img/collapse.png"));
|
||||
}
|
||||
}
|
||||
|
||||
void PDFFileWidget::collapsedButtonClicked(){
|
||||
setCollapsed(!collapsed);
|
||||
}
|
||||
|
||||
void PDFFileWidget::removeButtonClicked() {
|
||||
emit fileRemoveButtonClicked(this);
|
||||
}
|
||||
|
||||
void PDFFileWidget::setDocument(Poppler::Document* document, QString fileName){
|
||||
document->setRenderHint(Poppler::Document::TextAntialiasing);
|
||||
Poppler::Document *previewDoc = Poppler::Document::load(fileName);
|
||||
previewDoc->setRenderHint(Poppler::Document::TextAntialiasing);
|
||||
Poppler::Document *thumbDoc = Poppler::Document::load(fileName);
|
||||
thumbDoc->setRenderHint(Poppler::Document::TextAntialiasing);
|
||||
|
||||
int numPages = document -> numPages();
|
||||
for (int i = 0; i < numPages; i++){
|
||||
Poppler::Page *pdfPage = document->page(i);
|
||||
|
||||
PDFPageWidget *pageWidget = new PDFPageWidget();
|
||||
|
||||
pageWidget->setAncestor(ancestor);
|
||||
pageWidget->setFather(this);
|
||||
pageWidget->setPopplerPage(previewDoc->page(i));
|
||||
pageWidget->setThumbPopplerPage(thumbDoc->page(i));
|
||||
pageWidget->setOriginInfo(fileName,i);
|
||||
tgen.render(pageWidget,pdfPage);
|
||||
|
||||
pagesContainerWidget->addPageWidget(pageWidget);
|
||||
}
|
||||
tgen.start();
|
||||
|
||||
fileNameLabel->setText(fileName);
|
||||
}
|
||||
|
||||
int PDFFileWidget::removeChild(PDFPageWidget* child){
|
||||
int pos = pagesContainerWidget->pageWidgets.indexOf(child);
|
||||
pagesContainerWidget->pageWidgets.remove(pos);
|
||||
pagesContainerWidget->mainLayout->removeWidget(child);
|
||||
child->hide();
|
||||
//pagesContainerWidget->mainLayout->removeItem(pagesContainerWidget->mainLayout->itemAt(pos));
|
||||
|
||||
pagesContainerWidget->adjustSize();
|
||||
return pos;
|
||||
}
|
||||
|
||||
int PDFFileWidget::indexChild(PDFPageWidget* child){
|
||||
return pagesContainerWidget->pageWidgets.indexOf(child);
|
||||
}
|
||||
|
||||
void PDFFileWidget::insertChildAt(PDFPageWidget* child, int pos){
|
||||
child->setFather(this);
|
||||
pagesContainerWidget->mainLayout->insertWidget(pos, child);
|
||||
pagesContainerWidget->pageWidgets.insert(pos,child);
|
||||
tgen.render(child,child->getNewThumbPopplerPage());
|
||||
tgen.start();
|
||||
child->show();
|
||||
|
||||
pagesContainerWidget->adjustSize();
|
||||
}
|
||||
|
||||
int PDFFileWidget::getChildCount() {
|
||||
return pagesContainerWidget->getPagesCount();
|
||||
}
|
102
src/PDFFileWidget.h
Normal file
102
src/PDFFileWidget.h
Normal file
@ -0,0 +1,102 @@
|
||||
#pragma once
|
||||
#include <poppler-qt5.h>
|
||||
#include "ThumbGen.h"
|
||||
|
||||
#include <QWidget>
|
||||
#include <QFrame>
|
||||
|
||||
class QImage;
|
||||
class QHBoxLayout;
|
||||
class QGridLayout;
|
||||
class QScrollArea;
|
||||
class QPushButton;
|
||||
class QLabel;
|
||||
class QString;
|
||||
class QSize;
|
||||
class QPoint;
|
||||
class QDragEnterEvent;
|
||||
class QDropEvent;
|
||||
class QMouseEvent;
|
||||
class QPaintEvent;
|
||||
class ThumbGen;
|
||||
|
||||
class PDFPageWidget;
|
||||
|
||||
class PagesContainerWidget : public QWidget {
|
||||
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
PagesContainerWidget(QWidget *parent = 0);
|
||||
QSize sizeHint() const;
|
||||
QVector<PDFPageWidget*> pageWidgets;
|
||||
QHBoxLayout *mainLayout;
|
||||
|
||||
void addPageWidget(PDFPageWidget *pageWidget);
|
||||
void setAncestor(QWidget* ancestor){ this-> ancestor = ancestor;}
|
||||
void setFather(QWidget* father){this->father = father;}
|
||||
int getPagesCount() const;
|
||||
QWidget* getFather(){return father;}
|
||||
|
||||
protected:
|
||||
void dragEnterEvent(QDragEnterEvent *event);
|
||||
void dropEvent(QDropEvent *event);
|
||||
|
||||
private:
|
||||
QWidget *ancestor;
|
||||
QWidget *father;
|
||||
private slots:
|
||||
void ShowContextMenu(const QPoint&);
|
||||
};
|
||||
|
||||
// ========================================
|
||||
|
||||
class PDFFileWidget : public QFrame {
|
||||
|
||||
Q_OBJECT
|
||||
Q_PROPERTY(bool collapsed READ isCollapsed WRITE setCollapsed)
|
||||
|
||||
public:
|
||||
PDFFileWidget(QWidget *parent = 0);
|
||||
|
||||
public:
|
||||
void setAncestor(QWidget* ancestor);
|
||||
void setDocument(Poppler::Document* document, QString fileName);
|
||||
int removeChild(PDFPageWidget* child);
|
||||
int indexChild(PDFPageWidget* child);
|
||||
void insertChildAt(PDFPageWidget* child, int pos);
|
||||
int getChildCount();
|
||||
|
||||
void setSelected(bool select);
|
||||
bool isSelected() {return selected;}
|
||||
bool isCollapsed(){ return collapsed; }
|
||||
void setCollapsed(bool collapsed);
|
||||
|
||||
protected:
|
||||
void mousePressEvent(QMouseEvent *event);
|
||||
void paintEvent(QPaintEvent *event);
|
||||
|
||||
private slots:
|
||||
void removeButtonClicked(void);
|
||||
void collapsedButtonClicked(void);
|
||||
void updateThumbnail(QImage,PDFPageWidget*);
|
||||
|
||||
public :
|
||||
PagesContainerWidget *pagesContainerWidget;
|
||||
private:
|
||||
ThumbGen tgen;
|
||||
QGridLayout *topLayout;
|
||||
|
||||
QLabel *fileNameLabel;
|
||||
QPushButton *collapseButton;
|
||||
QPushButton *removeButton;
|
||||
QScrollArea *scrollArea;
|
||||
QWidget *ancestor;
|
||||
|
||||
bool collapsed;
|
||||
bool selected;
|
||||
|
||||
signals:
|
||||
void fileRemoveButtonClicked(PDFFileWidget*);
|
||||
void fileClicked(PDFFileWidget*, QMouseEvent*);
|
||||
};
|
183
src/PDFJam.cpp
Normal file
183
src/PDFJam.cpp
Normal file
@ -0,0 +1,183 @@
|
||||
#include <QtGlobal>
|
||||
#include <QtWidgets>
|
||||
#include <unistd.h>
|
||||
#include "stdlib.h"
|
||||
#include "PDFJam.h"
|
||||
|
||||
PDFJam::PDFJam()
|
||||
{
|
||||
|
||||
}
|
||||
//to make sure this folder exists and has no file inside
|
||||
void PDFJam::makeCleanFolder(QString path){
|
||||
QString temp = "mkdir -p %1 && rm %2*";
|
||||
int value = system(temp.arg(path).arg(path).toStdString().c_str());
|
||||
}
|
||||
|
||||
void PDFJam::pushCommand(QString cmd){
|
||||
mutex.lock();
|
||||
cmdQueue.push_back(cmd);
|
||||
mutex.unlock();
|
||||
if(!isRunning()) start();
|
||||
|
||||
}
|
||||
//to rotate a page in a pdf file, clockwise direction
|
||||
bool PDFJam::rotatePage(int fileIndex,int rotatedPageIndex,int degree){
|
||||
if ((degree!=90) && (degree!=180) && (degree!=270)){
|
||||
return false;
|
||||
}
|
||||
|
||||
QString rtTemp = "pdf%1 /tmp/pdffactory/%2/%3.pdf --outfile /tmp/pdffactory/%4/%5.pdf ";
|
||||
QString cmd = rtTemp.arg(QString::number(degree)).arg(QString::number(fileIndex)).arg(QString::number(rotatedPageIndex)).arg(QString::number(fileIndex)).arg(QString::number(rotatedPageIndex));
|
||||
pushCommand(cmd);
|
||||
|
||||
}
|
||||
|
||||
//to remove a page in a pdf file
|
||||
bool PDFJam::removePage(int fileIndex,int numPages, int deletedPageIndex){
|
||||
if ((deletedPageIndex<0)||(deletedPageIndex>=numPages)) {
|
||||
return false;
|
||||
}
|
||||
//QString temp = "file1.pdf '-' file2.pdf '1,2' file3.pdf '2-' --outfile output.pdf"
|
||||
QString rmTemp = "rm /tmp/pdffactory/%1/%2.pdf ";
|
||||
QString cmd = rmTemp.arg(QString::number(fileIndex)).arg(QString::number(deletedPageIndex));
|
||||
QString temp = "mv /tmp/pdffactory/%1/%2.pdf /tmp/pdffactory/%3/%4.pdf ";
|
||||
|
||||
|
||||
|
||||
for (int i = deletedPageIndex+1; i < numPages; i++) {
|
||||
cmd += "&& " + temp.arg(QString::number(fileIndex)).arg(QString::number(i)).arg(QString::number(fileIndex)).arg(QString::number(i-1));
|
||||
}
|
||||
pushCommand(cmd);
|
||||
|
||||
}
|
||||
void PDFJam::cutPage(int fileIndex,int numPages, int pageIndex,int slot=0) {
|
||||
qDebug()<<"cuting page"<<fileIndex << " " << pageIndex;
|
||||
if ((pageIndex<0)||(pageIndex>=numPages)) {
|
||||
return ;
|
||||
}
|
||||
|
||||
copyPage(fileIndex,pageIndex,slot);
|
||||
removePage(fileIndex,numPages,pageIndex);
|
||||
|
||||
}
|
||||
void PDFJam::copyPage(int fileIndex,int pageIndex,int slot=0){
|
||||
QString cpTemp = "cp /tmp/pdffactory/%1/%2.pdf /tmp/pdffactory/clipboard%3.pdf";
|
||||
QString cmd = cpTemp.arg(QString::number(fileIndex)).arg(QString::number(pageIndex)).arg(QString::number(slot));
|
||||
pushCommand(cmd);
|
||||
}
|
||||
void PDFJam::pastePage(int fileIndex,int numPages, int pageIndex, int slot=0){
|
||||
QString cmd = "";
|
||||
QString mvTemp = "mv /tmp/pdffactory/%1/%2.pdf /tmp/pdffactory/%3/%4.pdf ";
|
||||
for (int i = numPages-1; i >= pageIndex; i--) {
|
||||
cmd += mvTemp.arg(QString::number(fileIndex)).arg(QString::number(i)).arg(QString::number(fileIndex)).arg(QString::number(i+1));
|
||||
if (i>pageIndex) cmd+=" && ";
|
||||
}
|
||||
|
||||
QString pasteTemp = "cp /tmp/pdffactory/clipboard%1.pdf /tmp/pdffactory/%2/%3.pdf ";
|
||||
cmd += " && " + pasteTemp.arg(QString::number(slot)).arg(QString::number(fileIndex)).arg(QString::number(pageIndex));
|
||||
pushCommand(cmd);
|
||||
|
||||
}
|
||||
void PDFJam::movePage(int fromFileIndex, int fromFileNumPage, int fromPageIndex, int toFileIndex, int toFileNumPage, int toPageIndex ){
|
||||
//TODO:back up clipboard
|
||||
|
||||
//if this is page moving within files, update file Index.
|
||||
if (toFileIndex == fromFileIndex) {
|
||||
toFileNumPage--;
|
||||
if(toPageIndex>fromPageIndex)
|
||||
toPageIndex--;
|
||||
toPageIndex--;
|
||||
}
|
||||
cutPage(fromFileIndex,fromFileNumPage,fromPageIndex,0);
|
||||
pastePage(toFileIndex,toFileNumPage,toPageIndex,0);
|
||||
}
|
||||
void PDFJam::savePageAsImage(Poppler::Page pp, QString dest,double dpi = 72){
|
||||
(void)pp;
|
||||
(void)dest;
|
||||
(void)dpi;
|
||||
}
|
||||
//to export file number "fileIndex" to destination
|
||||
//support n-up, orientation, offset options
|
||||
void PDFJam::exportFile(int fileIndex,int numPages, QString dest, bool isNup,QSize nup, bool isLandscape , bool hasTwoSidedOffset, int leftOffset){
|
||||
|
||||
QString cmd = "pdfjam ";
|
||||
QString temp = "/tmp/pdffactory/%1/%2.pdf '-' ";
|
||||
|
||||
for (int i = 0; i < numPages; i++) {
|
||||
cmd += temp.arg(QString::number(fileIndex)).arg(QString::number(i));
|
||||
}
|
||||
QString orientation = isLandscape?" --landscape ": " --no-landscape ";
|
||||
cmd += orientation;
|
||||
|
||||
if (isNup) {
|
||||
QString nupTemp = " --nup '%1x%2' --frame true ";
|
||||
cmd += nupTemp.arg(QString::number(nup.width())).arg(QString::number(nup.height()));
|
||||
}
|
||||
//offset
|
||||
if(hasTwoSidedOffset){
|
||||
//pipe to another pdfjam to do offset, after other things are done
|
||||
QString outStdout = " --outfile /dev/stdout | pdfjam ";
|
||||
cmd += outStdout.arg(dest);
|
||||
|
||||
cmd+=" --twoside ";
|
||||
QString offsetTemp =" --offset \"%1cm 0cm\" ";
|
||||
cmd+=offsetTemp.arg(QString::number(leftOffset));
|
||||
|
||||
//TODO - extension: 2 orientations, this one is after n-up, can extend later
|
||||
QString orientation = isLandscape?" --landscape ": " --no-landscape ";
|
||||
cmd += orientation;
|
||||
|
||||
}
|
||||
|
||||
QString outTemp = " --outfile %1 ";
|
||||
cmd += outTemp.arg(dest);
|
||||
pushCommand(cmd);
|
||||
|
||||
|
||||
}
|
||||
|
||||
void PDFJam::loadFile(QString fileName, int fileIndex,Poppler::Document* pd){
|
||||
int numPages = pd->numPages();
|
||||
QString path= "/tmp/pdffactory/%1/";
|
||||
path = path.arg(QString::number(fileIndex));
|
||||
makeCleanFolder(path);
|
||||
|
||||
QString temp = "pdfjam %1 %2 --outfile %3%4.pdf %5";
|
||||
QString cmd="";
|
||||
for (int i = 0; i < numPages; i++) {
|
||||
QString orientation = " --no-landscape ";
|
||||
QSizeF pageSize = pd->page(i)->pageSizeF();
|
||||
if(pageSize.width() > pageSize.height()){
|
||||
orientation = " --landscape ";
|
||||
}
|
||||
cmd += temp.arg(fileName).arg(QString::number(i+1)).arg(path).arg(QString::number(i)).arg(orientation) + " ; ";
|
||||
}
|
||||
pushCommand(cmd);
|
||||
}
|
||||
QString PDFJam::nextCommand(){
|
||||
|
||||
QString cmd;
|
||||
|
||||
mutex.lock();
|
||||
cmd = cmdQueue.first();
|
||||
cmdQueue.pop_front();
|
||||
mutex.unlock();
|
||||
|
||||
return cmd;
|
||||
}
|
||||
bool PDFJam::isQueueEmpty(){
|
||||
return (cmdQueue.size()==0);
|
||||
}
|
||||
|
||||
void PDFJam::run(){
|
||||
while(!isQueueEmpty()){
|
||||
QString cmd = nextCommand();
|
||||
//int value = system(cmd.toStdString().c_str());
|
||||
|
||||
//if(value)
|
||||
//qDebug() << "ERROR: Failed to execute " << cmd;
|
||||
//else
|
||||
//qDebug() << "SUCCESS: executed " << cmd;
|
||||
}
|
||||
}
|
37
src/PDFJam.h
Normal file
37
src/PDFJam.h
Normal file
@ -0,0 +1,37 @@
|
||||
#pragma once
|
||||
|
||||
#include <QThread>
|
||||
#include <QMutex>
|
||||
#include <poppler-qt5.h>
|
||||
#include <QImage>
|
||||
class PDFPageWidget;
|
||||
class QImage;
|
||||
|
||||
class PDFJam: public QThread
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
PDFJam();
|
||||
void pushCommand(QString);
|
||||
void loadFile(QString fileName,int,Poppler::Document*);
|
||||
void exportFile(int ,int , QString , bool ,QSize , bool , bool , int );
|
||||
|
||||
void savePageAsImage(Poppler::Page pp, QString dest, double);
|
||||
void movePage(int , int , int , int , int , int );
|
||||
|
||||
void pastePage(int ,int , int ,int);
|
||||
void copyPage(int , int , int );
|
||||
void cutPage(int ,int , int ,int);
|
||||
|
||||
bool removePage(int ,int , int );
|
||||
bool rotatePage(int,int,int);
|
||||
protected:
|
||||
void run();
|
||||
private:
|
||||
void makeCleanFolder(QString);
|
||||
QVector<QString> cmdQueue;
|
||||
QString nextCommand();
|
||||
bool isQueueEmpty();
|
||||
QMutex mutex;
|
||||
|
||||
};
|
187
src/PDFPageWidget.cpp
Normal file
187
src/PDFPageWidget.cpp
Normal file
@ -0,0 +1,187 @@
|
||||
#include <QtGlobal>
|
||||
#include <QtWidgets>
|
||||
#include "ThumbGen.h"
|
||||
#include "PDFPageWidget.h"
|
||||
#include "PDFTableWidget.h"
|
||||
|
||||
#define PAGE_WIDTH 150
|
||||
#define PAGE_HEIGHT 150
|
||||
|
||||
PDFPageWidget::PDFPageWidget(QWidget *parent) :
|
||||
QFrame(parent)
|
||||
{
|
||||
selected = false;
|
||||
rotation = 0;
|
||||
setAcceptDrops(true);
|
||||
|
||||
this->resize(PAGE_WIDTH, PAGE_HEIGHT);
|
||||
this->setMinimumSize(PAGE_WIDTH, PAGE_HEIGHT);
|
||||
this->setMaximumSize(PAGE_WIDTH, PAGE_HEIGHT);
|
||||
this->setAutoFillBackground(true);
|
||||
|
||||
this->setMouseTracking(true);
|
||||
this->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
|
||||
|
||||
QHBoxLayout *topHBox = new QHBoxLayout();
|
||||
btnRotate = new QPushButton("", this);
|
||||
btnRotate->setObjectName("rotate");
|
||||
btnRotate->setIcon(QPixmap::fromImage(QImage(":/img/rotate.png")));
|
||||
btnRotate->hide();
|
||||
topHBox->addWidget(btnRotate, 0, Qt::AlignLeft);
|
||||
|
||||
btnDelete = new QPushButton("", this);
|
||||
btnDelete->setObjectName("rotate");
|
||||
btnDelete->setIcon(QPixmap::fromImage(QImage(":/img/remove.png")));
|
||||
btnDelete->hide();
|
||||
topHBox->addWidget(btnDelete, 1, Qt::AlignRight);
|
||||
|
||||
QHBoxLayout *bottomHBox = new QHBoxLayout();
|
||||
btnCut = new QPushButton("", this);
|
||||
btnCut->setObjectName("cut");
|
||||
btnCut->setIcon(QPixmap::fromImage(QImage(":/img/cut.png")));
|
||||
btnCut->hide();
|
||||
|
||||
btnCopy = new QPushButton("", this);
|
||||
btnCopy->setObjectName("copy");
|
||||
btnCopy->setIcon(QPixmap::fromImage(QImage(":/img/copy.png")));
|
||||
btnCopy->hide();
|
||||
|
||||
bottomHBox->addWidget(btnCut, 0, Qt::AlignLeft);
|
||||
bottomHBox->addWidget(btnCopy, 1, Qt::AlignRight);
|
||||
|
||||
QVBoxLayout *vbox = new QVBoxLayout();
|
||||
vbox->addLayout(topHBox);
|
||||
vbox->addStretch(1);
|
||||
vbox->addLayout(bottomHBox);
|
||||
vbox->setContentsMargins(0, 3, 0, 3);
|
||||
this->setLayout(vbox);
|
||||
}
|
||||
|
||||
void PDFPageWidget::setAncestor(QWidget* ancestor){
|
||||
this->ancestor = ancestor;
|
||||
((PDFTableWidget*)ancestor)->registerPage(this);
|
||||
connect(this, SIGNAL(pageClicked(PDFPageWidget*, QMouseEvent*, QString)), ancestor, SLOT(pageClicked(PDFPageWidget*, QMouseEvent*, QString)));
|
||||
connect(this, SIGNAL(pageDropped(PDFPageWidget*, QDropEvent*, QString, QString)), ancestor, SLOT(pageDropped(PDFPageWidget*, QDropEvent*, QString, QString)));
|
||||
connect(btnDelete, SIGNAL(clicked()), this, SLOT(pageDelete()));
|
||||
connect(btnCopy, SIGNAL(clicked()), this, SLOT(pageCopy()));
|
||||
connect(btnRotate, SIGNAL(clicked()), this, SLOT(pageRotate()));
|
||||
connect(btnCut, SIGNAL(clicked()), this, SLOT(pageCut()));
|
||||
}
|
||||
|
||||
void PDFPageWidget::pageCut(){
|
||||
((PDFTableWidget*)ancestor)->clearClipboard();
|
||||
((PDFTableWidget*)ancestor)->cutPage(this);
|
||||
}
|
||||
|
||||
void PDFPageWidget::pageDelete(){
|
||||
((PDFTableWidget*)ancestor)->deletePage(this);
|
||||
}
|
||||
|
||||
void PDFPageWidget::pageCopy(){
|
||||
((PDFTableWidget*)ancestor)->clearClipboard();
|
||||
((PDFTableWidget*)ancestor)->copyPage(this);
|
||||
}
|
||||
|
||||
void PDFPageWidget::pageRotate(){
|
||||
((PDFTableWidget*)ancestor)->rotatePage(this);
|
||||
}
|
||||
|
||||
void PDFPageWidget::rotate90() {
|
||||
rotation += 90;
|
||||
if (rotation == 360) rotation = 0;
|
||||
|
||||
ThumbGen *tgen = new ThumbGen();
|
||||
double dpi=tgen->calcDpi(thumbPage,size());
|
||||
|
||||
image = thumbPage->renderToImage(dpi, dpi, -1, -1, -1, -1, getRotation());
|
||||
setThumbnail(image);
|
||||
}
|
||||
|
||||
Poppler::Page::Rotation PDFPageWidget::getRotation() {
|
||||
if (rotation == 0) return Poppler::Page::Rotate0;
|
||||
else if (rotation == 90) return Poppler::Page::Rotate90;
|
||||
else if (rotation == 180) return Poppler::Page::Rotate180;
|
||||
else if (rotation == 270) return Poppler::Page::Rotate270;
|
||||
}
|
||||
|
||||
void PDFPageWidget::setFather(QWidget *father){
|
||||
this->father = father;
|
||||
}
|
||||
|
||||
void PDFPageWidget::setPopplerPage(Poppler::Page* pp) {
|
||||
previewPage = pp;
|
||||
}
|
||||
Poppler::Page* PDFPageWidget::getNewThumbPopplerPage(){
|
||||
Poppler::Document *thumbDoc = Poppler::Document::load(oriFilePath);
|
||||
thumbDoc->setRenderHint(Poppler::Document::TextAntialiasing);
|
||||
return thumbDoc->page(pageNo);
|
||||
}
|
||||
void PDFPageWidget::setThumbPopplerPage(Poppler::Page* pp) {
|
||||
thumbPage = pp;
|
||||
}
|
||||
|
||||
|
||||
void PDFPageWidget::setThumbnail(QImage pageImage) {
|
||||
image = pageImage;
|
||||
pixmap = QPixmap::fromImage(image);
|
||||
pixmap = pixmap.scaled(size() - QSize(6, 6), Qt::KeepAspectRatio);
|
||||
|
||||
update();
|
||||
}
|
||||
|
||||
void PDFPageWidget::setSelected(bool select) {
|
||||
selected = select;
|
||||
update();
|
||||
}
|
||||
|
||||
void PDFPageWidget::mousePressEvent(QMouseEvent *event) {
|
||||
if (previewPage!=NULL){
|
||||
emit pageClicked(this, event, path);
|
||||
}
|
||||
}
|
||||
|
||||
void PDFPageWidget::dragEnterEvent(QDragEnterEvent *event) {
|
||||
event->acceptProposedAction();
|
||||
}
|
||||
|
||||
void PDFPageWidget::dropEvent(QDropEvent *event) {
|
||||
emit pageDropped(this, event, event->mimeData()->text(), path);
|
||||
event->acceptProposedAction();
|
||||
}
|
||||
|
||||
void PDFPageWidget::leaveEvent(QEvent *event) {
|
||||
(void)event;
|
||||
btnRotate->hide();
|
||||
btnCut->hide();
|
||||
btnCopy->hide();
|
||||
btnDelete->hide();
|
||||
|
||||
this->setFrameStyle(QFrame::Plain);
|
||||
}
|
||||
|
||||
void PDFPageWidget::enterEvent(QEvent *event) {
|
||||
(void)event;
|
||||
btnRotate->show();
|
||||
btnCut->show();
|
||||
btnCopy->show();
|
||||
btnDelete->show();
|
||||
|
||||
this->setFrameStyle(QFrame::StyledPanel | QFrame::Raised);
|
||||
}
|
||||
|
||||
void PDFPageWidget::paintEvent(QPaintEvent *event) {
|
||||
QPalette palette = this->palette();
|
||||
if (selected)
|
||||
palette.setColor( backgroundRole(), palette.color(QPalette::Highlight) );
|
||||
else
|
||||
palette.setColor( backgroundRole(), palette.color(QPalette::AlternateBase) );
|
||||
this->setPalette( palette );
|
||||
|
||||
QFrame::paintEvent(event);
|
||||
QPainter painter(this);
|
||||
painter.drawPixmap(QRect((size().width() - pixmap.width()) / 2, (size().height() - pixmap.height()) / 2, pixmap.width(), pixmap.height()), pixmap);
|
||||
}
|
||||
|
||||
QSize PDFPageWidget::sizeHint() const {
|
||||
return size();
|
||||
}
|
84
src/PDFPageWidget.h
Normal file
84
src/PDFPageWidget.h
Normal file
@ -0,0 +1,84 @@
|
||||
#pragma once
|
||||
|
||||
#include <poppler-qt5.h>
|
||||
#include <QFrame>
|
||||
|
||||
class QWidget;
|
||||
class QPushButton;
|
||||
class QImage;
|
||||
class QPixmap;
|
||||
class QEvent;
|
||||
class QMouseEvent;
|
||||
class QPaintEvent;
|
||||
class QDragEnterEvent;
|
||||
class QDropEvent;
|
||||
class QSize;
|
||||
class QString;
|
||||
|
||||
class PDFPageWidget : public QFrame
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
PDFPageWidget(QWidget *parent = 0);
|
||||
QSize sizeHint() const;
|
||||
|
||||
void setThumbnail(QImage pageImage);
|
||||
void setOriginInfo(QString path,int num){pageNo = num;oriFilePath=path;};
|
||||
void setPopplerPage(Poppler::Page*);
|
||||
void setThumbPopplerPage(Poppler::Page*);
|
||||
void setAncestor(QWidget *ancestor);
|
||||
void setFather(QWidget *father);
|
||||
void rotate90();
|
||||
Poppler::Page::Rotation getRotation();
|
||||
int getIntRotation(){return rotation;};
|
||||
int setIntRotation(int r){rotation = r;};
|
||||
QWidget* getFather() const { return father;}
|
||||
void registerName(QString name) { path = name;}
|
||||
QString getName() { return path;}
|
||||
int getPageNo() { return pageNo;}
|
||||
QString getOriFilePath() { return oriFilePath;}
|
||||
Poppler::Page* getNewThumbPopplerPage();
|
||||
|
||||
void setSelected(bool select);
|
||||
bool isSelected() {return selected;}
|
||||
|
||||
Poppler::Page* getPage(){return previewPage;}
|
||||
Poppler::Page* getThumbPage(){return thumbPage;}
|
||||
|
||||
protected:
|
||||
void paintEvent(QPaintEvent *event);
|
||||
void enterEvent(QEvent *event);
|
||||
void leaveEvent(QEvent *event);
|
||||
void mousePressEvent(QMouseEvent *event);
|
||||
void dragEnterEvent(QDragEnterEvent *event);
|
||||
void dropEvent(QDropEvent *event);
|
||||
|
||||
private:
|
||||
//QVector<QPushButton> buttons;
|
||||
QString path;
|
||||
int pageNo;
|
||||
QString oriFilePath;
|
||||
QWidget *ancestor;
|
||||
QWidget *father;
|
||||
|
||||
QImage image;
|
||||
Poppler::Page *previewPage,*thumbPage;
|
||||
QPixmap pixmap;
|
||||
QPushButton *btnRotate, *btnCut, *btnCopy, *btnDelete;
|
||||
|
||||
int rotation;
|
||||
|
||||
|
||||
bool selected;
|
||||
|
||||
signals:
|
||||
void pageClicked(PDFPageWidget*, QMouseEvent*, QString);
|
||||
void pageDropped(PDFPageWidget*, QDropEvent*, QString, QString);
|
||||
|
||||
private slots:
|
||||
void pageDelete();
|
||||
void pageCopy();
|
||||
void pageRotate();
|
||||
void pageCut();
|
||||
};
|
158
src/PDFPreviewWidget.cpp
Normal file
158
src/PDFPreviewWidget.cpp
Normal file
@ -0,0 +1,158 @@
|
||||
#include <QtWidgets>
|
||||
#include "PDFPreviewWidget.h"
|
||||
|
||||
PreviewGen pgen;
|
||||
|
||||
PDFPreviewWidget::PDFPreviewWidget(QWidget *parent) :
|
||||
QFrame(parent)
|
||||
{
|
||||
|
||||
setCursor(Qt::OpenHandCursor);
|
||||
setFrameStyle(QFrame::StyledPanel | QFrame::Plain);
|
||||
pPage = NULL;
|
||||
currentPixmapSize = QSize(0,0);
|
||||
connect(&pgen, SIGNAL(updatePreview(QImage)),
|
||||
this, SLOT(updateImage(QImage)));
|
||||
}
|
||||
|
||||
void PDFPreviewWidget::updateImage(QImage qimg) {
|
||||
previewImage = qimg;
|
||||
regenPixmap();
|
||||
repositionPixmap();
|
||||
update();
|
||||
}
|
||||
|
||||
void PDFPreviewWidget::regenImage() {
|
||||
double dpi;
|
||||
double dpi2;
|
||||
QSize targetSize;
|
||||
|
||||
if (currentPixmapSize == QSize(0,0))
|
||||
currentPixmapSize = this->size();
|
||||
|
||||
targetSize = currentPixmapSize;
|
||||
|
||||
QSizeF oriSize = pPage->pageSizeF();
|
||||
double oriDpi = 72;
|
||||
dpi = targetSize.height()/(float)oriSize.height()*oriDpi;
|
||||
dpi2= targetSize.width()/(float)oriSize.width()*oriDpi;
|
||||
dpi = dpi<dpi2?dpi:dpi2;
|
||||
|
||||
//previewImage = pPage->renderToImage(dpi,dpi, -1, -1, -1, -1, rotation);
|
||||
pgen.render(pPage,dpi,rotation);
|
||||
pgen.start();
|
||||
}
|
||||
|
||||
void PDFPreviewWidget::regenPixmap() {
|
||||
pixmap = QPixmap::fromImage(previewImage);
|
||||
pixmap = pixmap.scaled(currentPixmapSize, Qt::KeepAspectRatioByExpanding);
|
||||
currentPixmapSize = pixmap.size();
|
||||
}
|
||||
|
||||
void PDFPreviewWidget::repositionPixmap() {
|
||||
currentPixmapPos = QPoint((size().width() - pixmap.width()) / 2, (size().height() - pixmap.height()) / 2);
|
||||
}
|
||||
|
||||
void PDFPreviewWidget::previewUpdate(Poppler::Page* pp, Poppler::Page::Rotation rotation) {
|
||||
pPage = pp;
|
||||
this->rotation = rotation;
|
||||
currentPixmapSize = this->size();
|
||||
regenImage();
|
||||
//regenPixmap();
|
||||
//repositionPixmap();
|
||||
//update();
|
||||
}
|
||||
|
||||
void PDFPreviewWidget::checkPreviewUpdate(Poppler::Page* pp, Poppler::Page::Rotation rotation) {
|
||||
//if (pPage != NULL && pPage == pp) {
|
||||
previewUpdate(pp, rotation);
|
||||
//}
|
||||
}
|
||||
|
||||
void PDFPreviewWidget::checkPagePreviewExisted(Poppler::Page* pp) {
|
||||
(void) pp;
|
||||
//if (pPage != NULL && pPage == pp) {
|
||||
pPage = NULL;
|
||||
rotation = Poppler::Page::Rotate0;
|
||||
|
||||
QPainter painter(this);
|
||||
painter.drawPixmap(QRect(0, 0, 0, 0), pixmap);
|
||||
update();
|
||||
//}
|
||||
}
|
||||
|
||||
void PDFPreviewWidget::resizeEvent(QResizeEvent *event) {
|
||||
(void) event;
|
||||
if (pPage!=NULL) {
|
||||
repositionPixmap();
|
||||
update();
|
||||
}
|
||||
}
|
||||
|
||||
void PDFPreviewWidget::wheelEvent(QWheelEvent *event) {
|
||||
if (pPage!=NULL) {
|
||||
if (event->delta() > 0)
|
||||
currentPixmapSize += QSize(30, 30);
|
||||
else if (event->delta() < 0)
|
||||
currentPixmapSize -= QSize(30, 30);
|
||||
|
||||
if (currentPixmapSize.width() < 150 || currentPixmapSize.height() < 150) {
|
||||
currentPixmapSize = QSize(150, 150);
|
||||
}
|
||||
|
||||
regenImage();
|
||||
regenPixmap();
|
||||
repositionPixmap();
|
||||
update();
|
||||
}
|
||||
}
|
||||
|
||||
void PDFPreviewWidget::mousePressEvent(QMouseEvent *event)
|
||||
{
|
||||
if (pPage!=NULL) {
|
||||
setCursor(Qt::ClosedHandCursor);
|
||||
|
||||
if (event->button() == Qt::LeftButton) {
|
||||
dragStartPos = event->pos();
|
||||
lastPixmapPos = currentPixmapPos;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void PDFPreviewWidget::mouseMoveEvent(QMouseEvent *event) {
|
||||
if (pPage!=NULL) {
|
||||
if (!(event->buttons() & Qt::LeftButton)) {
|
||||
return;
|
||||
}
|
||||
|
||||
QPoint currentPos = event->pos();
|
||||
QPoint vector = currentPos - dragStartPos;
|
||||
QPoint newPos = lastPixmapPos + vector;
|
||||
|
||||
if (pixmap.width() > size().width()) {
|
||||
if (newPos.x() <= 0 && newPos.x() >= size().width() - pixmap.width())
|
||||
currentPixmapPos.setX(newPos.x());
|
||||
}
|
||||
|
||||
if (pixmap.height() > size().height()) {
|
||||
if (newPos.y() <= 0 && newPos.y() >= size().height() - pixmap.height())
|
||||
currentPixmapPos.setY(newPos.y());
|
||||
}
|
||||
|
||||
update();
|
||||
}
|
||||
}
|
||||
|
||||
void PDFPreviewWidget::mouseReleaseEvent(QMouseEvent *event) {
|
||||
(void) event;
|
||||
setCursor(Qt::OpenHandCursor);
|
||||
}
|
||||
|
||||
void PDFPreviewWidget::paintEvent(QPaintEvent *event) {
|
||||
(void) event;
|
||||
if (pPage!=NULL) {
|
||||
QPainter painter(this);
|
||||
painter.drawPixmap(QRect(currentPixmapPos.x(), currentPixmapPos.y(), pixmap.width(), pixmap.height()), pixmap);
|
||||
}
|
||||
QFrame::paintEvent(event);
|
||||
}
|
58
src/PDFPreviewWidget.h
Normal file
58
src/PDFPreviewWidget.h
Normal file
@ -0,0 +1,58 @@
|
||||
#pragma once
|
||||
|
||||
#include <QFrame>
|
||||
#include <poppler-qt5.h>
|
||||
#include "PreviewGen.h"
|
||||
|
||||
|
||||
class QImage;
|
||||
class QPixmap;
|
||||
class QSize;
|
||||
class QPoint;
|
||||
class QResizeEvent;
|
||||
class QWheelEvent;
|
||||
class QPaintEvent;
|
||||
class QMouseEvent;
|
||||
class PreviewGen;
|
||||
|
||||
class PDFPreviewWidget : public QFrame
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit PDFPreviewWidget(QWidget *parent = 0);
|
||||
|
||||
public slots:
|
||||
void regenImage();
|
||||
void regenPixmap();
|
||||
void repositionPixmap();
|
||||
void previewUpdate(Poppler::Page*, Poppler::Page::Rotation);
|
||||
void checkPreviewUpdate(Poppler::Page*, Poppler::Page::Rotation);
|
||||
void checkPagePreviewExisted(Poppler::Page*);
|
||||
|
||||
protected:
|
||||
void wheelEvent(QWheelEvent *event);
|
||||
void paintEvent(QPaintEvent *event);
|
||||
void resizeEvent(QResizeEvent *event);
|
||||
void mousePressEvent(QMouseEvent *event);
|
||||
void mouseMoveEvent(QMouseEvent *event);
|
||||
void mouseReleaseEvent(QMouseEvent *event);
|
||||
|
||||
public:
|
||||
Poppler::Page* pPage;
|
||||
|
||||
private:
|
||||
QImage previewImage;
|
||||
QPixmap pixmap;
|
||||
Poppler::Page::Rotation rotation;
|
||||
|
||||
QSize currentPixmapSize;
|
||||
QPoint currentPixmapPos;
|
||||
QPoint lastPixmapPos;
|
||||
QPoint dragStartPos;
|
||||
|
||||
private slots:
|
||||
void updateImage(QImage);
|
||||
|
||||
signals:
|
||||
void updatePreview(QImage);
|
||||
};
|
421
src/PDFTableWidget.cpp
Normal file
421
src/PDFTableWidget.cpp
Normal file
@ -0,0 +1,421 @@
|
||||
#include <QtWidgets>
|
||||
|
||||
#include "PDFTableWidget.h"
|
||||
#include "PDFPageWidget.h"
|
||||
#include "PDFFileWidget.h"
|
||||
#include <QtAlgorithms>
|
||||
#include "PDFJam.h"
|
||||
|
||||
// Constructor
|
||||
PDFTableWidget::PDFTableWidget(QWidget* parent) : QFrame(parent)
|
||||
{
|
||||
// Frame (Expanding with VBox) - Scroll Area (Expanding) - Container (Expanding with VBox) - Children
|
||||
|
||||
setFrameStyle(QFrame::StyledPanel | QFrame::Plain);
|
||||
setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
|
||||
|
||||
outerLayout = new QVBoxLayout();
|
||||
outerLayout->setContentsMargins(0,0,0,0);
|
||||
|
||||
scrollArea = new QScrollArea();
|
||||
scrollArea -> setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
|
||||
scrollArea -> setWidgetResizable(true);
|
||||
scrollArea -> setFrameStyle(QFrame::Plain);
|
||||
|
||||
containerLayout = new QVBoxLayout();
|
||||
containerLayout -> setSpacing(10);
|
||||
containerWidget = new QWidget();
|
||||
containerWidget -> setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
|
||||
QWidget *spacer = new QWidget();
|
||||
spacer -> setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
|
||||
containerLayout -> addWidget(spacer);
|
||||
containerWidget -> setLayout(containerLayout);
|
||||
|
||||
scrollArea -> setWidget(containerWidget);
|
||||
|
||||
outerLayout -> addWidget(scrollArea);
|
||||
|
||||
setLayout(outerLayout);
|
||||
}
|
||||
|
||||
void PDFTableWidget::loadFile(QString fileName){
|
||||
Poppler::Document *doc = Poppler::Document::load(fileName);
|
||||
files.append(doc);
|
||||
|
||||
PDFFileWidget *fileWidget = new PDFFileWidget();
|
||||
fileWidget->setAncestor(this);
|
||||
fileWidget->setDocument(doc,fileName);
|
||||
pdfJam.loadFile(fileName,files.size()-1,doc);
|
||||
|
||||
fileWidgets.append(fileWidget);
|
||||
fileNames.append(fileName);
|
||||
|
||||
containerLayout->insertWidget(containerLayout->count() - 1, fileWidget);
|
||||
connect(fileWidget, SIGNAL(fileRemoveButtonClicked(PDFFileWidget*)), this, SLOT(fileRemoveButtonClicked(PDFFileWidget*)));
|
||||
}
|
||||
|
||||
QVector<PDFFileWidget*> PDFTableWidget::getSelectedFiles() {
|
||||
return selectedFiles;
|
||||
}
|
||||
|
||||
QVector<int> PDFTableWidget::getSelectedIndices() {
|
||||
QVector<int> retVector;
|
||||
for (int i = 0; i < selectedFiles.size(); i++) {
|
||||
retVector.append(fileWidgets.indexOf(selectedFiles.at(i)));
|
||||
}
|
||||
return retVector;
|
||||
}
|
||||
|
||||
QVector<QString> PDFTableWidget::getSelectedFileNames() {
|
||||
QVector<QString> retVector;
|
||||
QVector<int> indices = getSelectedIndices();
|
||||
for (int i = 0; i < indices.size(); i++) {
|
||||
retVector.append(fileNames.at(indices.at(i)));
|
||||
}
|
||||
return retVector;
|
||||
}
|
||||
|
||||
QVector<PDFFileWidget*> PDFTableWidget::getVisibleFiles() {
|
||||
QVector<PDFFileWidget*> retVector;
|
||||
for (int i = 0; i < fileWidgets.size(); i++) {
|
||||
if (fileWidgets.at(i)->isVisible())
|
||||
retVector.append(fileWidgets.at(i));
|
||||
}
|
||||
return retVector;
|
||||
}
|
||||
|
||||
QVector<int> PDFTableWidget::getVisibleIndices() {
|
||||
QVector<int> retVector;
|
||||
QVector<PDFFileWidget*> visibleFiles = getVisibleFiles();
|
||||
for (int i = 0; i < visibleFiles.size(); i++) {
|
||||
retVector.append(fileWidgets.indexOf(visibleFiles.at(i)));
|
||||
}
|
||||
return retVector;
|
||||
}
|
||||
|
||||
QVector<QString> PDFTableWidget::getVisibleFileNames() {
|
||||
QVector<QString> retVector;
|
||||
QVector<int> indices = getVisibleIndices();
|
||||
for (int i = 0; i < indices.size(); i++) {
|
||||
retVector.append(fileNames.at(indices.at(i)));
|
||||
}
|
||||
return retVector;
|
||||
}
|
||||
|
||||
void PDFTableWidget::registerPage(PDFPageWidget* child){
|
||||
//come up with a new name here
|
||||
QString name = QString("/home/pdfpage").append(QString::number(pageChilds.size()));
|
||||
pageChilds[name] = child;
|
||||
child->registerName(name);
|
||||
}
|
||||
|
||||
void PDFTableWidget::copySelected(){
|
||||
clearClipboard();
|
||||
for (int i = 0;i<selectedPages.size();i++)
|
||||
copyPage(selectedPages.at(i));
|
||||
}
|
||||
void PDFTableWidget::cutSelected(){
|
||||
clearClipboard();
|
||||
for (int i = 0;i<selectedPages.size();i++){
|
||||
cutPage(selectedPages.at(i));
|
||||
i=-1;
|
||||
}
|
||||
}
|
||||
void PDFTableWidget::deleteSelected(){
|
||||
for (int i = 0;i<selectedPages.size();i++)
|
||||
deletePageSkipSelection(selectedPages.at(i));
|
||||
selectedPages.clear();
|
||||
}
|
||||
|
||||
void PDFTableWidget::fileClicked(PDFFileWidget* sender, QMouseEvent* event) {
|
||||
if (event->button() == Qt::LeftButton){
|
||||
if (event->modifiers() != Qt::ControlModifier) {
|
||||
for (int i = 0; i < selectedFiles.size(); i++) {
|
||||
selectedFiles.at(i)->setSelected(false);
|
||||
}
|
||||
|
||||
selectedFiles.clear();
|
||||
|
||||
if (!sender->isSelected()) {
|
||||
sender->setSelected(true);
|
||||
selectedFiles.append(sender);
|
||||
}
|
||||
} else {
|
||||
if (!sender->isSelected()) {
|
||||
sender->setSelected(true);
|
||||
selectedFiles.append(sender);
|
||||
} else {
|
||||
sender->setSelected(false);
|
||||
selectedFiles.remove(selectedFiles.indexOf(sender));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void PDFTableWidget::fileRemoveButtonClicked(PDFFileWidget* sender) {
|
||||
if (selectedFiles.indexOf(sender) > 0)
|
||||
selectedFiles.remove(selectedFiles.indexOf(sender));
|
||||
|
||||
for (int i = 0; i < sender->getChildCount(); i++) {
|
||||
PDFPageWidget *pageWidget = sender->pagesContainerWidget->pageWidgets.at(i);
|
||||
pageWidget->setSelected(false);
|
||||
emit checkPagePreviewExisted(pageWidget->getPage());
|
||||
if (selectedPages.indexOf(pageWidget) > 0)
|
||||
selectedPages.remove(selectedPages.indexOf(pageWidget));
|
||||
}
|
||||
|
||||
// Handle remove file
|
||||
sender->hide();
|
||||
}
|
||||
|
||||
void PDFTableWidget::pageClicked(PDFPageWidget *sender, QMouseEvent* event, QString path){
|
||||
if (event->button() == Qt::LeftButton){
|
||||
// Handle selection
|
||||
if (selectedPages.size() > 0 && event->modifiers() != Qt::ControlModifier) {
|
||||
|
||||
if (sender->isSelected() ){
|
||||
QDrag *drag = new QDrag(this);
|
||||
QMimeData *mimeData = new QMimeData;
|
||||
|
||||
mimeData->setText(path);
|
||||
drag->setMimeData(mimeData);
|
||||
drag->setPixmap(QPixmap(":/img/copy.png"));
|
||||
|
||||
drag->exec();
|
||||
}else {
|
||||
for (int i = 0; i < selectedPages.size(); i++) {
|
||||
selectedPages.at(i)->setSelected(false);
|
||||
}
|
||||
selectedPages.clear();
|
||||
sender->setSelected(true);
|
||||
|
||||
selectedPages.insert(0,sender);
|
||||
emit previewUpdate(sender->getNewThumbPopplerPage(), sender->getRotation());
|
||||
}
|
||||
|
||||
} else {
|
||||
if (!sender->isSelected()) {
|
||||
sender->setSelected(true);
|
||||
emit previewUpdate(sender->getNewThumbPopplerPage(), sender->getRotation());
|
||||
|
||||
PDFFileWidget* senderF = (PDFFileWidget*)sender->getFather();
|
||||
int senderPID = senderF->indexChild(sender);
|
||||
int senderFID = fileWidgets.indexOf(senderF);
|
||||
|
||||
int i = 0;
|
||||
for (i = 0;i<selectedPages.size();i++){
|
||||
PDFPageWidget* target = selectedPages.at(i);
|
||||
PDFFileWidget* targetF = (PDFFileWidget*)target->getFather();
|
||||
int targetPID = targetF->indexChild(target);
|
||||
int targetFID = fileWidgets.indexOf(targetF);
|
||||
|
||||
if (targetFID == senderFID && targetPID > senderPID)
|
||||
break;
|
||||
|
||||
if (targetFID > senderFID)
|
||||
break;
|
||||
}
|
||||
|
||||
selectedPages.insert(i,sender);
|
||||
} else {
|
||||
sender->setSelected(false);
|
||||
selectedPages.remove(selectedPages.indexOf(sender));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (event->button() == Qt::RightButton){
|
||||
for (int i = 0; i < selectedPages.size(); i++) {
|
||||
selectedPages.at(i)->setSelected(false);
|
||||
}
|
||||
selectedPages.clear();
|
||||
}
|
||||
}
|
||||
|
||||
void PDFTableWidget::pageDropped(PDFPageWidget *sender, QDropEvent *event, QString pathFrom, QString pathTo){
|
||||
(void)sender;
|
||||
(void)event;
|
||||
moveSelectedPages(pathFrom, pathTo);
|
||||
}
|
||||
|
||||
void PDFTableWidget::moveSelectedPages(QString pathFrom, PDFPageWidget* page){
|
||||
moveSelectedPages(pathFrom, page->getName());
|
||||
}
|
||||
|
||||
void PDFTableWidget::deletePageSkipSelection(PDFPageWidget* pageWidget){
|
||||
if (pageWidget->isSelected())
|
||||
emit checkPagePreviewExisted(pageWidget->getPage());
|
||||
|
||||
PDFFileWidget *daddy = (PDFFileWidget*)pageWidget->getFather();
|
||||
int daddyID = fileWidgets.indexOf(daddy);
|
||||
int pageID = daddy->indexChild(pageWidget);
|
||||
|
||||
pdfJam.removePage(daddyID, daddy->pagesContainerWidget->pageWidgets.size(),pageID);
|
||||
daddy->removeChild(pageWidget);
|
||||
|
||||
int spos = copiedPages.indexOf(pageWidget);
|
||||
if (spos!=-1){
|
||||
copiedPages.remove(spos);
|
||||
}
|
||||
pageChilds.remove(pageWidget->getName());
|
||||
|
||||
|
||||
// PLS ACTIVATE THIS LINE ONCE EVERYTHING HAS BEEN FIXED
|
||||
// :D :D :D :D :D :D
|
||||
//delete page;
|
||||
|
||||
}
|
||||
|
||||
void PDFTableWidget::deletePage(PDFPageWidget* pageWidget){
|
||||
if (pageWidget->isSelected())
|
||||
emit checkPagePreviewExisted(pageWidget->getPage());
|
||||
|
||||
PDFFileWidget *daddy = (PDFFileWidget*)pageWidget->getFather();
|
||||
int daddyID = fileWidgets.indexOf(daddy);
|
||||
int pageID = daddy->indexChild(pageWidget);
|
||||
|
||||
pdfJam.removePage(daddyID, daddy->pagesContainerWidget->pageWidgets.size(),pageID);
|
||||
daddy->removeChild(pageWidget);
|
||||
|
||||
int spos = selectedPages.indexOf(pageWidget);
|
||||
if (spos!=-1){
|
||||
selectedPages.remove(spos);
|
||||
}
|
||||
spos = copiedPages.indexOf(pageWidget);
|
||||
if (spos!=-1){
|
||||
copiedPages.remove(spos);
|
||||
}
|
||||
pageChilds.remove(pageWidget->getName());
|
||||
|
||||
|
||||
// PLS ACTIVATE THIS LINE ONCE EVERYTHING HAS BEEN FIXED
|
||||
// :D :D :D :D :D :D
|
||||
//delete page;
|
||||
|
||||
}
|
||||
|
||||
void PDFTableWidget::cutPage(PDFPageWidget* pageWidget){
|
||||
deletePage(pageWidget);
|
||||
int id = copiedPages.size();
|
||||
copiedPages.push_back(pageWidget);
|
||||
|
||||
PDFFileWidget *daddy = (PDFFileWidget*)pageWidget->getFather();
|
||||
int daddyID = fileWidgets.indexOf(daddy);
|
||||
int pageID = daddy->indexChild(pageWidget);
|
||||
|
||||
pdfJam.cutPage(daddyID, daddy->pagesContainerWidget->pageWidgets.size(),pageID, id);
|
||||
}
|
||||
|
||||
void PDFTableWidget::clearClipboard(){
|
||||
copiedPages.clear();
|
||||
}
|
||||
|
||||
void PDFTableWidget::copyPage(PDFPageWidget* pageWidget){
|
||||
int id = copiedPages.size();
|
||||
copiedPages.push_back(pageWidget);
|
||||
|
||||
PDFFileWidget *daddy = (PDFFileWidget*)pageWidget->getFather();
|
||||
int daddyID = fileWidgets.indexOf(daddy);
|
||||
int pageID = daddy->indexChild(pageWidget);
|
||||
|
||||
pdfJam.copyPage(daddyID, pageID, id);
|
||||
}
|
||||
|
||||
void PDFTableWidget::pastePage(PDFFileWidget* fileWidget, int pageID){
|
||||
if (copiedPages.size() > 0){
|
||||
for (int i = 0;i<copiedPages.size(); i++){
|
||||
PDFPageWidget* page =copiedPages.at(i);
|
||||
|
||||
PDFPageWidget* pageWidget = new PDFPageWidget();
|
||||
pageWidget->setAncestor(this);
|
||||
pageWidget->setFather(page->getFather());
|
||||
pageWidget->setPopplerPage(page->getNewThumbPopplerPage());
|
||||
pageWidget->setThumbPopplerPage(page->getNewThumbPopplerPage());
|
||||
pageWidget->setOriginInfo(page->getOriFilePath(),page->getPageNo());
|
||||
pageWidget->setIntRotation(page->getIntRotation());
|
||||
|
||||
int fileID = fileWidgets.indexOf(fileWidget);
|
||||
pdfJam.pastePage(fileID, fileWidget->pagesContainerWidget->pageWidgets.size(), pageID, i);
|
||||
|
||||
fileWidget->insertChildAt(pageWidget,pageID+i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void PDFTableWidget::rotatePage(PDFPageWidget* pageWidget) {
|
||||
pageWidget->rotate90();
|
||||
|
||||
int fileIndex = fileWidgets.indexOf((PDFFileWidget *)pageWidget->getFather());
|
||||
int pageIndex = fileWidgets.at(fileIndex)->indexChild(pageWidget);
|
||||
pdfJam.rotatePage(fileIndex, pageIndex, pageWidget->getIntRotation());
|
||||
|
||||
if (pageWidget->isSelected())
|
||||
emit checkPreviewUpdate(pageWidget->getPage(), pageWidget->getRotation());
|
||||
}
|
||||
|
||||
void PDFTableWidget::rotateSelected() {
|
||||
for (int i = 0; i < selectedPages.size(); i++) {
|
||||
rotatePage(selectedPages.at(i));
|
||||
}
|
||||
}
|
||||
|
||||
void PDFTableWidget::moveSelectedPages(QString pathFrom, QString pathTo){
|
||||
if (selectedPages.size() == 0)
|
||||
return;
|
||||
|
||||
bool accept = false;
|
||||
for (int i = 0;i<selectedPages.size();i++)
|
||||
if (selectedPages.at(i)->getName() == pathFrom)
|
||||
accept=true;
|
||||
if (!accept)
|
||||
return;
|
||||
/*
|
||||
for (int i = 0;i<selectedPages.size();i++)
|
||||
if (selectedPages.at(i)->getName() == pathTo)
|
||||
return;*/
|
||||
|
||||
PDFPageWidget* childTo = pageChilds[pathTo];
|
||||
PDFFileWidget* fileTo = (PDFFileWidget*) childTo->getFather();
|
||||
|
||||
int posTo= -1;
|
||||
PDFFileWidget* file = NULL;
|
||||
for (int i = selectedPages.size() - 1; i>=0 ;i--){
|
||||
PDFPageWidget* childFrom = selectedPages[i];
|
||||
PDFFileWidget* fileFrom = (PDFFileWidget*) childFrom->getFather();
|
||||
if (file == fileFrom){
|
||||
posTo-=1;
|
||||
}
|
||||
|
||||
if (pathTo==childFrom->getName() ){
|
||||
file = fileFrom;
|
||||
posTo = fileFrom->indexChild(childFrom);
|
||||
}
|
||||
|
||||
|
||||
pdfJam.cutPage(
|
||||
fileWidgets.indexOf(fileFrom),
|
||||
fileFrom->pagesContainerWidget->pageWidgets.size(),
|
||||
fileFrom->indexChild(childFrom),
|
||||
i
|
||||
);
|
||||
|
||||
fileFrom->removeChild(childFrom);
|
||||
|
||||
}
|
||||
if (posTo ==-1)
|
||||
posTo = fileTo->indexChild(childTo);
|
||||
for (int i = selectedPages.size() - 1; i>=0 ;i--){
|
||||
pdfJam.pastePage(
|
||||
fileWidgets.indexOf(fileTo),
|
||||
fileTo->pagesContainerWidget->pageWidgets.size(),
|
||||
posTo,
|
||||
i
|
||||
);
|
||||
|
||||
PDFPageWidget* childFrom = selectedPages[i];
|
||||
//PDFFileWidget* fileFrom = (PDFFileWidget*) childFrom->getFather();
|
||||
fileTo->insertChildAt(childFrom, posTo);
|
||||
|
||||
//fileFrom->insertChildAt(childTo, posFrom);
|
||||
}
|
||||
}
|
87
src/PDFTableWidget.h
Normal file
87
src/PDFTableWidget.h
Normal file
@ -0,0 +1,87 @@
|
||||
#pragma once
|
||||
#include <poppler-qt5.h>
|
||||
#include "PDFJam.h"
|
||||
|
||||
#include <QFrame>
|
||||
#include <QHash>
|
||||
#include "PDFPageWidget.h"
|
||||
#include "ThumbGen.h"
|
||||
|
||||
class QImage;
|
||||
class QVBoxLayout;
|
||||
class QString;
|
||||
class QScrollArea;
|
||||
class QMouseEvent;
|
||||
class QPoint;
|
||||
|
||||
class PDFFileWidget;
|
||||
|
||||
class PDFTableWidget: public QFrame
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
PDFTableWidget(QWidget *parent = 0);
|
||||
void loadFile (QString fileName);
|
||||
void registerPage(PDFPageWidget *child);
|
||||
|
||||
|
||||
public:
|
||||
PDFJam pdfJam;
|
||||
ThumbGen mainTgen;
|
||||
|
||||
private:
|
||||
QVBoxLayout *outerLayout;
|
||||
QScrollArea *scrollArea;
|
||||
QWidget *containerWidget;
|
||||
QVBoxLayout *containerLayout;
|
||||
|
||||
QVector<Poppler::Document*> files;
|
||||
QVector<QString> fileNames;
|
||||
QVector<PDFFileWidget*> fileWidgets;
|
||||
|
||||
QHash<QString, PDFPageWidget*> pageChilds;
|
||||
|
||||
signals:
|
||||
void previewUpdate(Poppler::Page*, Poppler::Page::Rotation);
|
||||
void checkPreviewUpdate(Poppler::Page*, Poppler::Page::Rotation);
|
||||
void checkPagePreviewExisted(Poppler::Page*);
|
||||
|
||||
private slots:
|
||||
void fileRemoveButtonClicked(PDFFileWidget*);
|
||||
void pageClicked(PDFPageWidget*, QMouseEvent*, QString);
|
||||
void pageDropped(PDFPageWidget*, QDropEvent*, QString, QString);
|
||||
|
||||
void fileClicked(PDFFileWidget*, QMouseEvent*);
|
||||
|
||||
private:
|
||||
QVector<PDFPageWidget*> selectedPages;
|
||||
QVector<PDFFileWidget*> selectedFiles;
|
||||
|
||||
QVector<PDFPageWidget*> copiedPages;
|
||||
public:
|
||||
QVector<PDFFileWidget*> getSelectedFiles();
|
||||
QVector<int> getSelectedIndices();
|
||||
QVector<QString> getSelectedFileNames();
|
||||
|
||||
QVector<PDFFileWidget*> getVisibleFiles();
|
||||
QVector<int> getVisibleIndices();
|
||||
QVector<QString> getVisibleFileNames();
|
||||
|
||||
public:
|
||||
void moveSelectedPages(QString, QString);
|
||||
void moveSelectedPages(QString, PDFPageWidget* page);
|
||||
void deletePage(PDFPageWidget* pageWidget);
|
||||
void deletePageSkipSelection(PDFPageWidget* pageWidget);
|
||||
void copyPage(PDFPageWidget* pageWidget);
|
||||
void pastePage(PDFFileWidget* fileWidget, int pageID);
|
||||
void rotatePage(PDFPageWidget* pageWidget);
|
||||
void cutPage(PDFPageWidget* pageWidget);
|
||||
void clearClipboard();
|
||||
bool hasClipboard(){ return copiedPages.size() > 0; }
|
||||
|
||||
public slots:
|
||||
void rotateSelected();
|
||||
void copySelected();
|
||||
void cutSelected();
|
||||
void deleteSelected();
|
||||
};
|
25
src/PreviewGen.cpp
Normal file
25
src/PreviewGen.cpp
Normal file
@ -0,0 +1,25 @@
|
||||
#include <QtGlobal>
|
||||
#include <QtWidgets>
|
||||
#include "PreviewGen.h"
|
||||
PreviewGen::PreviewGen()
|
||||
{
|
||||
|
||||
}
|
||||
void PreviewGen::run(){
|
||||
mutex.lock();
|
||||
Poppler::Page *pp =pPage;
|
||||
double instantDpi =dpi;
|
||||
double instantRotation = rotation;
|
||||
mutex.unlock();
|
||||
|
||||
QImage pageImage = pp->renderToImage(instantDpi, instantDpi,-1,-1,-1,-1,rotation);
|
||||
emit updatePreview(pageImage);
|
||||
}
|
||||
void PreviewGen::render(Poppler::Page* pp,double aDpi,Poppler::Page::Rotation r){
|
||||
mutex.lock();
|
||||
pPage = pp;
|
||||
dpi = aDpi;
|
||||
rotation = r;
|
||||
mutex.unlock();
|
||||
}
|
||||
|
30
src/PreviewGen.h
Normal file
30
src/PreviewGen.h
Normal file
@ -0,0 +1,30 @@
|
||||
#pragma once
|
||||
#include <QThread>
|
||||
#include <QMutex>
|
||||
#include <poppler-qt5.h>
|
||||
#include <QImage>
|
||||
#include "PDFPreviewWidget.h"
|
||||
|
||||
class QImage;
|
||||
|
||||
class PreviewGen: public QThread
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
PreviewGen();
|
||||
void render(Poppler::Page*,double,Poppler::Page::Rotation);
|
||||
|
||||
protected:
|
||||
void run();
|
||||
Poppler::Page* pPage;
|
||||
double dpi;
|
||||
Poppler::Page::Rotation rotation;
|
||||
QMutex mutex;
|
||||
|
||||
public:
|
||||
double calcDpi(Poppler::Page *pdfPage, double dpi);
|
||||
|
||||
signals:
|
||||
void updatePreview(QImage);
|
||||
};
|
46
src/ThumbGen.cpp
Normal file
46
src/ThumbGen.cpp
Normal file
@ -0,0 +1,46 @@
|
||||
#include <QtGlobal>
|
||||
#include <QtWidgets>
|
||||
#include "ThumbGen.h"
|
||||
|
||||
|
||||
#include "PDFPageWidget.h"
|
||||
ThumbGen::ThumbGen()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
double ThumbGen::calcDpi(Poppler::Page *pdfPage, QSize targetSize){
|
||||
double dpi;
|
||||
QSizeF oriSize = pdfPage->pageSizeF();
|
||||
double oriDpi = 72;
|
||||
if (targetSize.width() > targetSize.height()){
|
||||
dpi = targetSize.height()/(float)oriSize.height()*72;
|
||||
}else {
|
||||
dpi= targetSize.width()/(float)oriSize.width()*72;
|
||||
}
|
||||
return dpi;
|
||||
|
||||
}
|
||||
|
||||
void ThumbGen::run(){
|
||||
while(pWidgets.size()!=0){
|
||||
mutex.lock();
|
||||
PDFPageWidget *pw = pWidgets.first();
|
||||
pWidgets.pop_front();
|
||||
Poppler::Page *pp = pPages.first();
|
||||
pPages.pop_front();
|
||||
mutex.unlock();
|
||||
|
||||
double dpi=calcDpi(pp,pw->size());
|
||||
QImage pageImage = pp->renderToImage(dpi, dpi);
|
||||
emit updateThumbnail(pageImage,pw);
|
||||
}
|
||||
}
|
||||
void ThumbGen::render(PDFPageWidget* pw,Poppler::Page* pp){
|
||||
mutex.lock();
|
||||
pWidgets.append(pw);
|
||||
pPages.append(pp);
|
||||
mutex.unlock();
|
||||
|
||||
}
|
||||
|
@ -1,30 +1,30 @@
|
||||
#pragma once
|
||||
|
||||
#include <QThread>
|
||||
#include <QMutex>
|
||||
#include <QImage>
|
||||
#include <poppler-qt5.h>
|
||||
|
||||
#include <QImage>
|
||||
class PDFPageWidget;
|
||||
class QImage;
|
||||
|
||||
class ThumbGen : public QThread {
|
||||
class ThumbGen: public QThread
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
ThumbGen(void);
|
||||
void render(PDFPageWidget*, Poppler::Page*);
|
||||
ThumbGen();
|
||||
void render(PDFPageWidget*,Poppler::Page*);
|
||||
|
||||
protected:
|
||||
void run(void);
|
||||
void run();
|
||||
QVector<PDFPageWidget*> pWidgets;
|
||||
QVector<Poppler::Page*> pPages;
|
||||
|
||||
QMutex mutex;
|
||||
|
||||
private:
|
||||
double calcDpi(Poppler::Page* pdfPage, QSize targetSize);
|
||||
public:
|
||||
double calcDpi(Poppler::Page *pdfPage, QSize targetSize);
|
||||
|
||||
signals:
|
||||
void updateThumbnail(QImage, PDFPageWidget*);
|
||||
|
||||
};
|
||||
|
15
src/main.cpp
15
src/main.cpp
@ -1,10 +1,13 @@
|
||||
#include <QApplication>
|
||||
#include "pdf_factory.h"
|
||||
// main.cpp
|
||||
|
||||
int main(int argc, char* argv[]) {
|
||||
QApplication a(argc, argv);
|
||||
#include <QApplication>
|
||||
#include "PDFFactory.h"
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
QApplication app(argc, argv);
|
||||
PDFFactory pdffactory;
|
||||
pdffactory.show();
|
||||
|
||||
return a.exec();
|
||||
return app.exec();
|
||||
}
|
||||
|
||||
|
@ -1,14 +0,0 @@
|
||||
#include "main_window.h"
|
||||
#include "ui_main_window.h"
|
||||
|
||||
MainWindow::Mainwindow(Qwidget* parent) :
|
||||
QMainWindow(parent),
|
||||
ui(new UI::MainWindow {
|
||||
|
||||
ui->setupUI(this);
|
||||
}
|
||||
|
||||
MainWindow::~MainWindow(void) {
|
||||
delete ui;
|
||||
}
|
||||
|
@ -1,17 +0,0 @@
|
||||
#pragma once
|
||||
#include <QMainWindow>
|
||||
|
||||
namespace Ui {
|
||||
class MainWindow;
|
||||
}
|
||||
|
||||
class MainWindow : public QMainWindow {
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit MainWindow(QWidget* parent = 0);
|
||||
~MainWindow(void);
|
||||
|
||||
private:
|
||||
Ui::MainWindow* ui;
|
||||
};
|
||||
|
@ -1,24 +0,0 @@
|
||||
<ui version="4.0">
|
||||
<class>MainWindow</class>
|
||||
<widget class="QMainWindow" name="MainWindow" >
|
||||
<property name="geometry" >
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>400</width>
|
||||
<height>300</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle" >
|
||||
<string>MainWindow</string>
|
||||
</property>
|
||||
<widget class="QMenuBar" name="menuBar" />
|
||||
<widget class="QToolBar" name="mainToolBar" />
|
||||
<widget class="QWidget" name="centralWidget" />
|
||||
<widget class="QStatusBar" name="statusBar" />
|
||||
</widget>
|
||||
<layoutDefault spacing="6" margin="11" />
|
||||
<pixmapfunction></pixmapfunction>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
@ -1,155 +0,0 @@
|
||||
#include <QtWidgets>
|
||||
#include <QtGlobal>
|
||||
#include "pdf_factory.h"
|
||||
#include "pdf_table_widget.h"
|
||||
#include "pdf_preview_widget.h"
|
||||
#include "pdf_page_widget.h"
|
||||
|
||||
PDFFactory::PDFFactory(void) {
|
||||
createWidgets();
|
||||
createActions();
|
||||
createToolBars();
|
||||
createRibbon();
|
||||
createStatusBar();
|
||||
}
|
||||
|
||||
/* Create the shit we need for our window. */
|
||||
void PDFFactory::createWidgets(void) {
|
||||
/* Set central widget to be the container root. */
|
||||
centralWidget = new QWidget();
|
||||
QVBoxLayout* layout = new QVBoxLayout();
|
||||
layout->setContentsMargins(2, 2, 2, 2);
|
||||
centralWidget->setLayout(layout);
|
||||
setCentralWidget(centralWidget);
|
||||
|
||||
/* Create ribbon. */
|
||||
ribbon = new QTabWidget();
|
||||
ribbon->addTab(new QWidget(), tr("File"));
|
||||
ribbon->addTab(new QWidget(), tr("Edit"));
|
||||
ribbon->addTab(new QWidget(), tr("View"));
|
||||
ribbon->addTab(new QWidget(), tr("Help"));
|
||||
ribbon->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
|
||||
ribbon->setFixedHeight(100);
|
||||
layout->addWidget(ribbon);
|
||||
|
||||
/* Create main area (table). */
|
||||
pdfTableView = new PDFTableWidget();
|
||||
|
||||
pdfPreview = new PDFPreviewWidget();
|
||||
pdfPreview->setMinimumWidth(100);
|
||||
splitter = new QSplitter();
|
||||
splitter->setOrientation(Qt::Horizontal);
|
||||
splitter->addWidget(pdfTableView);
|
||||
splitter->addWidget(pdfPreview);
|
||||
QList<int> splitterWidgetSizes;
|
||||
splitterWidgetSizes << 200 << 1000;
|
||||
splitter->setSizes(splitterWidgetSizes);
|
||||
splitter->setStretchFactor(0, 1);
|
||||
splitter->setStretchFactor(1, 0.5);
|
||||
layout->addWidget(splitter);
|
||||
|
||||
connect(pdfTableView, SIGNAL(previewUpdate(Poppler::Page*)), pdfPreview,
|
||||
SLOT(previewUpdate(Poppler::Page*)));
|
||||
|
||||
setWindowIcon(QIcon(":/img/hpdf.png"));
|
||||
setWindowTitle(tr("HPDF"));
|
||||
setGeometry(0, 0, 1300, 650);
|
||||
}
|
||||
|
||||
void PDFFactory::createActions(void) {
|
||||
openAction = new QAction(tr("&Open"), this);
|
||||
openAction->setIcon(QIcon(":/img/open.png"));
|
||||
openAction->setShortcut(tr("Ctrl+O"));
|
||||
openAction->setStatusTip(tr("Open a PDF"));
|
||||
connect(openAction, SIGNAL(triggered()), this, SLOT(openFile()));
|
||||
|
||||
exportAction = new QAction(tr("&Export a single file"), this);
|
||||
exportAction->setIcon(QIcon(":/img/export.png"));
|
||||
exportAction->setShortcut(tr("Ctrl+S"));
|
||||
exportAction->setStatusTip(tr("Export the selected file to a new PDF"));
|
||||
/*connect(saveAction, SIGNAL(triggered()), this, SLOT(save()))*/
|
||||
|
||||
exportAllAction = new QAction(tr("Combine all"), this);
|
||||
exportAllAction->setIcon(QIcon(":/img/exportall.png"));
|
||||
exportAllAction->setShortcut(tr("Shift+Ctrl+S"));
|
||||
exportAllAction->setStatusTip(tr("Export all to multiple PDF files"));
|
||||
/*connect(saveAsAction, SIGNAL(triggered()), this, SLOT(saveAs()))*/
|
||||
|
||||
cutAction = new QAction(tr("C&ut"), this);
|
||||
cutAction->setIcon(QIcon(":/img/cut.png"));
|
||||
cutAction->setShortcut(tr("Ctrl+X"));
|
||||
cutAction->setStatusTip(tr("Cut selected contents to clipboard"));
|
||||
/*connect(cutAction, SIGNAL(triggered()), this, SLOT(cut()))*/
|
||||
|
||||
copyAction = new QAction(tr("&Copy"), this);
|
||||
copyAction->setIcon(QIcon(":/img/copy.png"));
|
||||
copyAction->setShortcut(tr("Ctrl+C"));
|
||||
copyAction->setStatusTip(tr("Copy selected contents to clipboard"));
|
||||
/*connect(copyAction, SIGNAL(triggered()), this, SLOT(copy()))*/
|
||||
|
||||
pasteAction = new QAction(tr("&Paste"), this);
|
||||
pasteAction->setIcon(QIcon(":/img/paste.png"));
|
||||
pasteAction->setShortcut(tr("Ctrl+V"));
|
||||
pasteAction->setStatusTip(tr("Paste clipboard's contents into current selection"));
|
||||
/*connect(pasteAction, SIGNAL(triggered()), this, SLOT(paste()))*/
|
||||
|
||||
aboutAction = new QAction(tr("A&bout"), this);
|
||||
aboutAction->setIcon(QIcon(":/img/about.png"));
|
||||
aboutAction->setStatusTip(tr("About this program"));
|
||||
}
|
||||
|
||||
void PDFFactory::createToolBars() {
|
||||
fileToolBar = new QToolBar(tr("File"));
|
||||
fileToolBar->addAction(openAction);
|
||||
fileToolBar->addAction(exportAction);
|
||||
fileToolBar->addAction(exportAllAction);
|
||||
fileToolBar->setIconSize(QSize(48, 48));
|
||||
|
||||
editToolBar = new QToolBar(tr("Edit"));
|
||||
editToolBar->addAction(cutAction);
|
||||
editToolBar->addAction(copyAction);
|
||||
editToolBar->addAction(pasteAction);
|
||||
editToolBar->setIconSize(QSize(48, 48));
|
||||
|
||||
helpToolBar = new QToolBar(tr("Help"));
|
||||
helpToolBar->addAction(aboutAction);
|
||||
helpToolBar->setIconSize(QSize(48, 48));
|
||||
}
|
||||
|
||||
void PDFFactory::createRibbon(void) {
|
||||
QWidget* tabFile = ribbon->widget(0);
|
||||
QVBoxLayout* layoutTabFile = new QVBoxLayout();
|
||||
layoutTabFile->setContentsMargins(2, 0, 2, 0);
|
||||
layoutTabFile->addWidget(fileToolBar);
|
||||
tabFile->setLayout(layoutTabFile);
|
||||
|
||||
QWidget* tabEdit = ribbon->widget(1);
|
||||
QVBoxLayout* layoutTabEdit = new QVBoxLayout();
|
||||
layoutTabEdit->setContentsMargins(2, 0, 2, 0);
|
||||
layoutTabEdit->addWidget(editToolBar);
|
||||
tabEdit->setLayout(layoutTabEdit);
|
||||
|
||||
QWidget* tabHelp = ribbon->widget(3);
|
||||
QVBoxLayout* layoutTabHelp = new QVBoxLayout();
|
||||
layoutTabHelp->setContentsMargins(2, 0, 2, 0);
|
||||
layoutTabHelp->addWidget(helpToolBar);
|
||||
tabHelp->setLayout(layoutTabHelp);
|
||||
}
|
||||
|
||||
void PDFFactory::createStatusBar(void) {
|
||||
statusBar()->showMessage(tr(""));
|
||||
}
|
||||
|
||||
void PDFFactory::openFile(void) {
|
||||
QStringList fileNames = QFileDialog::getOpenFileNames(this,
|
||||
tr("Open PDF file"), ".",
|
||||
tr("PDF file (*.pdf)"));
|
||||
|
||||
for(int i = 0; i < fileNames.size(); i++) {
|
||||
QString fileName = fileNames.at(i);
|
||||
if(!fileName.isEmpty()) {
|
||||
pdfTableView->loadFile(fileName);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,52 +0,0 @@
|
||||
#pragma once
|
||||
#include <QMainWindow>
|
||||
|
||||
class QAction;
|
||||
class QWidget;
|
||||
class QTabWidget;
|
||||
class QScrollArea;
|
||||
class QSplitter;
|
||||
class QToolBar;
|
||||
class PDFTableWidget;
|
||||
class PDFPreviewWidget;
|
||||
|
||||
class PDFFactory : public QMainWindow {
|
||||
Q_OBJECT
|
||||
public:
|
||||
PDFFactory();
|
||||
|
||||
protected:
|
||||
/*void closeEvent(QCloseEvent* event);*/
|
||||
|
||||
private slots:
|
||||
void openFile(void);
|
||||
/*void exportFile(void);
|
||||
void exportAllFiles(void);*/
|
||||
|
||||
private:
|
||||
void createWidgets(void);
|
||||
void createActions(void);
|
||||
void createToolBars(void);
|
||||
void createRibbon();
|
||||
void createStatusBar();
|
||||
|
||||
QAction* openAction;
|
||||
QAction* exportAction;
|
||||
QAction* exportAllAction;
|
||||
QAction* cutAction;
|
||||
QAction* copyAction;
|
||||
QAction* pasteAction;
|
||||
QAction* aboutAction;
|
||||
|
||||
QWidget* centralWidget;
|
||||
|
||||
QTabWidget* ribbon;
|
||||
QSplitter* splitter;
|
||||
PDFTableWidget* pdfTableView;
|
||||
PDFPreviewWidget* pdfPreview;
|
||||
|
||||
QToolBar* fileToolBar;
|
||||
QToolBar* editToolBar;
|
||||
QToolBar* helpToolBar;
|
||||
};
|
||||
|
@ -1,185 +0,0 @@
|
||||
#include <QtWidgets>
|
||||
#include <QtGlobal>
|
||||
#include "pdf_file_widget.h"
|
||||
#include "pdf_page_widget.h"
|
||||
#include "pdf_table_widget.h"
|
||||
|
||||
#define COLLAPSE_BUTTON_WIDTH 32
|
||||
#define COLLAPSE_BUTTON_HEIGHT 32
|
||||
|
||||
#define CHILD_AREA_WIDTH 150
|
||||
#define CHILD_AREA_HEIGHT 150
|
||||
|
||||
#define CHILD_AREA_SIDE_MARGIN 20
|
||||
|
||||
PagesContainerWidget::PagesContainerWidget(QWidget* parent) {
|
||||
setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
|
||||
setAcceptDrops(true);
|
||||
mainLayout = new QHBoxLayout();
|
||||
|
||||
setLayout(mainLayout);
|
||||
}
|
||||
|
||||
int PagesContainerWidget::getPagesCount() const {
|
||||
return pageWidgets.size();
|
||||
}
|
||||
|
||||
QSize PagesContainerWidget::sizeHint() const {
|
||||
return QSize((CHILD_AREA_SIDE_MARGIN + CHILD_AREA_WIDTH)*getPagesCount(), CHILD_AREA_HEIGHT + 30);
|
||||
}
|
||||
|
||||
void PagesContainerWidget::addPageWidget(PDFPageWidget* pageWidget) {
|
||||
pageWidgets.append(pageWidget);
|
||||
mainLayout->addWidget(pageWidget);
|
||||
adjustSize();
|
||||
}
|
||||
|
||||
void PagesContainerWidget::dragEnterEvent(QDragEnterEvent* event) {
|
||||
event->acceptProposedAction();
|
||||
}
|
||||
|
||||
void PagesContainerWidget::dropEvent(QDropEvent* event) {
|
||||
QPoint pos = event->pos();
|
||||
int page = (pos.x() / (CHILD_AREA_SIDE_MARGIN + CHILD_AREA_WIDTH));
|
||||
((PDFTableWidget*)ancestor)->moveSelectedPages(event->mimeData()->text(), pageWidgets.at(page));
|
||||
event->acceptProposedAction();
|
||||
}
|
||||
|
||||
PDFFileWidget::PDFFileWidget(QWidget* parent) :QFrame(parent) {
|
||||
setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
|
||||
setFrameStyle(QFrame::Box);
|
||||
|
||||
topLayout = new QGridLayout();
|
||||
|
||||
collapseButton = new QPushButton();
|
||||
collapseButton->resize(QSize(COLLAPSE_BUTTON_WIDTH, COLLAPSE_BUTTON_HEIGHT));
|
||||
collapseButton->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
|
||||
collapseButton->setIcon(QIcon(":/img/collapse.png"));
|
||||
connect(collapseButton, SIGNAL(released()), this, SLOT(collapsedButtonClicked()));
|
||||
topLayout->addWidget(collapseButton, 0, 0);
|
||||
|
||||
fileNameLabel = new QLabel();
|
||||
fileNameLabel->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
|
||||
topLayout->addWidget(fileNameLabel, 0, 1);
|
||||
|
||||
removeButton = new QPushButton();
|
||||
removeButton->resize(QSize(COLLAPSE_BUTTON_WIDTH, COLLAPSE_BUTTON_HEIGHT));
|
||||
removeButton->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
|
||||
removeButton->setIcon(QIcon(":img/remove.png"));
|
||||
connect(collapseButton, SIGNAL(released()), this, SLOT(collapsedButtonClicked()));
|
||||
topLayout->addWidget(removeButton, 0, 2);
|
||||
|
||||
pagesContainerWidget = new PagesContainerWidget();
|
||||
scrollArea = new QScrollArea();
|
||||
scrollArea->setWidget(pagesContainerWidget);
|
||||
scrollArea->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
|
||||
topLayout->addWidget(scrollArea, 1, 0, 1, 3);
|
||||
|
||||
topLayout->setContentsMargins(6, 10, 6, 10);
|
||||
setLayout(topLayout);
|
||||
|
||||
setCollapsed(false);
|
||||
selected = false;
|
||||
|
||||
connect(&tgen, SIGNAL(updateThumbnail(QImage,PDFPageWidget*)), this,
|
||||
SLOT(updateThumbnail(QImage,PDFPageWidget*)));
|
||||
}
|
||||
|
||||
void PDFFileWidget::setAncestor(QWidget* ancestor) {
|
||||
this->ancestor = ancestor;
|
||||
pagesContainerWidget->setAncestor(ancestor);
|
||||
connect(this, SIGNAL(fileClicked(PDFFileWidget*, QMouseEvent*)), ancestor,
|
||||
SLOT(fileClicked(PDFFileWidget*, QMouseEvent*)));
|
||||
}
|
||||
|
||||
void PDFFileWidget::setSelected(bool select) {
|
||||
selected = select;
|
||||
update();
|
||||
}
|
||||
|
||||
void PDFFileWidget::mousePressEvent(QMouseEvent* event) {
|
||||
emit fileClicked(this, event);
|
||||
}
|
||||
|
||||
void PDFFileWidget::paintEvent(QPaintEvent* event) {
|
||||
QPalette palette = this->palette();
|
||||
QPalette labelPalette = fileNameLabel->palette();
|
||||
if(selected) {
|
||||
palette.setColor(foregroundRole(), palette.color(QPalette::Highlight));
|
||||
labelPalette.setColor(foregroundRole(), palette.color(QPalette::Highlight));
|
||||
} else {
|
||||
palette.setColor(foregroundRole(), palette.color(QPalette::Dark));
|
||||
labelPalette.setColor(foregroundRole(), palette.color(QPalette::Text));
|
||||
}
|
||||
this->setPalette(palette);
|
||||
fileNameLabel->setPalette(labelPalette);
|
||||
|
||||
QFrame::paintEvent(event);
|
||||
}
|
||||
|
||||
void PDFFileWidget::updateThumbnail(QImage img, PDFPageWidget* pw) {
|
||||
pw->setThumbnail(img);
|
||||
}
|
||||
|
||||
void PDFFileWidget::setCollapsed(bool state) {
|
||||
collapsed = state;
|
||||
if(state == true) {
|
||||
scrollArea->hide();
|
||||
collapseButton->setIcon(QIcon(":/img/expand.png"));
|
||||
} else {
|
||||
scrollArea->show();
|
||||
collapseButton->setIcon(QIcon(":img/collapse.png"));
|
||||
}
|
||||
}
|
||||
|
||||
void PDFFileWidget::collapsedButtonClicked(void) {
|
||||
setCollapsed(!collapsed);
|
||||
}
|
||||
|
||||
void PDFFileWidget::removeButtonClicked(void) {
|
||||
emit fileRemoveButtonClicked(this);
|
||||
}
|
||||
|
||||
void PDFFileWidget::setDocument(Poppler::Document* document, QString fileName) {
|
||||
document->setRenderHint(Poppler::Document::TextAntialiasing);
|
||||
Poppler::Document* doc = Poppler::Document::load(fileName);
|
||||
doc->setRenderHint(Poppler::Document::TextAntialiasing);
|
||||
|
||||
int numPages = document->numPages();
|
||||
for(int i = 0; i < numPages; i++) {
|
||||
Poppler::Page* pdfPage = document->page(i);
|
||||
|
||||
PDFPageWidget* pageWidget = new PDFPageWidget();
|
||||
|
||||
pageWidget->setAncestor(ancestor);
|
||||
pageWidget->setFather(this);
|
||||
pageWidget->setPopplerPage(doc->page(i));
|
||||
tgen.render(pageWidget, pdfPage);
|
||||
|
||||
pagesContainerWidget->addPageWidget(pageWidget);
|
||||
}
|
||||
tgen.start();
|
||||
fileNameLabel->setText(fileName);
|
||||
}
|
||||
|
||||
int PDFFileWidget::removeChild(PDFPageWidget* child) {
|
||||
int pos = pagesContainerWidget->pageWidgets.indexOf(child);
|
||||
pagesContainerWidget->pageWidgets.remove(pos);
|
||||
pagesContainerWidget->mainLayout->removeItem(pagesContainerWidget->mainLayout->itemAt(pos));
|
||||
|
||||
pagesContainerWidget->adjustSize();
|
||||
return pos;
|
||||
}
|
||||
|
||||
int PDFFileWidget::indexChild(PDFPageWidget* child) {
|
||||
return pagesContainerWidget->pageWidgets.indexOf(child);
|
||||
}
|
||||
|
||||
void PDFFileWidget::insertChildAt(PDFPageWidget* child, int pos) {
|
||||
child->setFather(this);
|
||||
pagesContainerWidget->mainLayout->insertWidget(pos, child);
|
||||
pagesContainerWidget->pageWidgets.insert(pos, child);
|
||||
|
||||
pagesContainerWidget->adjustSize();
|
||||
}
|
||||
|
@ -1,88 +0,0 @@
|
||||
#pragma once
|
||||
#include <QWidget>
|
||||
#include <QFrame>
|
||||
#include <poppler-qt5.h>
|
||||
#include "pdf_page_widget.h"
|
||||
#include "thumbgen.h"
|
||||
|
||||
class QImage;
|
||||
class QHBoxLayout;
|
||||
class QGridLayout;
|
||||
class QScrollArea;
|
||||
class QPushButton;
|
||||
class QLabel;
|
||||
class QString;
|
||||
class QSize;
|
||||
class QPoint;
|
||||
class QDragEnterEvent;
|
||||
class QDropEvent;
|
||||
class QMouseEvent;
|
||||
class QPaintEvent;
|
||||
class ThumbGen;
|
||||
class PDFPageWidget;
|
||||
|
||||
class PagesContainerWidget : public QWidget {
|
||||
Q_OBJECT
|
||||
public:
|
||||
PagesContainerWidget(QWidget* parent = 0);
|
||||
QSize sizeHint() const;
|
||||
QVector<PDFPageWidget*> pageWidgets;
|
||||
QHBoxLayout* mainLayout;
|
||||
|
||||
void addPageWidget(PDFPageWidget* image);
|
||||
void setAncestor(QWidget* ancestor) {this->ancestor = ancestor; }
|
||||
|
||||
protected:
|
||||
void dragEnterEvent(QDragEnterEvent* event);
|
||||
void dropEvent(QDropEvent* event);
|
||||
|
||||
private:
|
||||
int getPagesCount() const;
|
||||
QWidget* ancestor;
|
||||
};
|
||||
|
||||
class PDFFileWidget : public QFrame {
|
||||
Q_OBJECT
|
||||
Q_PROPERTY(bool collapsed READ isCollapsed WRITE setCollapsed)
|
||||
|
||||
public:
|
||||
PDFFileWidget(QWidget* parent = 0);
|
||||
|
||||
void setAncestor(QWidget* ancestor);
|
||||
void setDocument(Poppler::Document* document, QString fileName);
|
||||
int removeChild(PDFPageWidget* child);
|
||||
int indexChild(PDFPageWidget* child);
|
||||
void insertChildAt(PDFPageWidget* child, int pos);
|
||||
|
||||
void setSelected(bool select);
|
||||
bool isSelected(void) { return selected; }
|
||||
bool isCollapsed(void) { return collapsed; }
|
||||
void setCollapsed(bool collapsed);
|
||||
|
||||
protected:
|
||||
void mousePressEvent(QMouseEvent* event);
|
||||
void paintEvent(QPaintEvent* event);
|
||||
|
||||
private slots:
|
||||
void removeButtonClicked(void);
|
||||
void collapsedButtonClicked(void);
|
||||
void updateThumbnail(QImage, PDFPageWidget*);
|
||||
|
||||
private:
|
||||
ThumbGen tgen;
|
||||
QGridLayout* topLayout;
|
||||
|
||||
QLabel* fileNameLabel;
|
||||
QPushButton* collapseButton;
|
||||
QPushButton* removeButton;
|
||||
PagesContainerWidget* pagesContainerWidget;
|
||||
QScrollArea* scrollArea;
|
||||
QWidget* ancestor;
|
||||
bool collapsed;
|
||||
bool selected;
|
||||
|
||||
signals:
|
||||
void fileRemoveButtonClicked(PDFFileWidget*);
|
||||
void fileClicked(PDFFileWidget*, QMouseEvent*);
|
||||
};
|
||||
|
185
src/pdf_jam.cpp
185
src/pdf_jam.cpp
@ -1,185 +0,0 @@
|
||||
#include <QtGlobal>
|
||||
#include <QtWidgets>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include "pdf_jam.h"
|
||||
|
||||
PDFJam::PDFJam(void) {
|
||||
|
||||
}
|
||||
|
||||
/* Ensure the folder exists. */
|
||||
void PDFJam::makeFolder(QString path) {
|
||||
QString tmp = "mkdir -p %1 && rm %2*";
|
||||
int value = system(tmp.arg(path).arg(path).toStdString().c_str());
|
||||
/*if(value != 0)
|
||||
qDebug() << "ERROR: Failed to make " << path;*/
|
||||
}
|
||||
|
||||
void PDFJam::pushCommand(QString cmd) {
|
||||
mutex.lock();
|
||||
cmdQueue.push_back(cmd);
|
||||
mutex.unlock();
|
||||
if(!isRunning()) start();
|
||||
}
|
||||
|
||||
/* Rotate PDF page clockwise. */
|
||||
bool PDFJam::rotatePage(int fileIndex, int rotatedPageIndex, int degree) {
|
||||
if((degree != 90) && (degree != 180) && (degree != 270)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
QString rtTmp = "pdf%1 /tmp/hpdf/%2/%3.pdf --outfile /tmp/hpdf/%4/%5.pdf ";
|
||||
QString cmd = rtTmp.arg(QString::number(degree)).arg(QString::number(fileIndex))
|
||||
.arg(QString::number(rotatedPageIndex)).arg(QString::number(fileIndex))
|
||||
.arg(QString::number(rotatedPageIndex));
|
||||
pushCommand(cmd);
|
||||
}
|
||||
|
||||
/* Remove page in a pdf file. */
|
||||
bool PDFJam::removePage(int fileIndex, int numPages, int deletedPageIndex) {
|
||||
if((deletedPageIndex < 0) || (deletedPageIndex >= numPages)) {
|
||||
return false;
|
||||
}
|
||||
/*QString tmp = "file1.pdf '-' file2.pdf '1,2' file3.pdf '2-2' --outfile output.pdf"*/
|
||||
QString rmTmp = "rm /tmp/hpdf/%1/%2.pdf ";
|
||||
QString cmd = rmTmp.arg(QString::number(fileIndex)).arg(QString::number(deletedPageIndex));
|
||||
QString tmp = "mv /tmp/hpdf/%1/%2.pdf /tmp/hpdf/%3/%4.pdf ";
|
||||
|
||||
for(int i = deletedPageIndex+1; i < numPages; i++) {
|
||||
cmd += "&& " + tmp.arg(QString::number(fileIndex)).arg(QString::number(i))
|
||||
.arg(QString::number(fileIndex)).arg(QString::number(i-1));
|
||||
}
|
||||
|
||||
pushCommand(cmd);
|
||||
}
|
||||
|
||||
void PDFJam::cutPage(int fileIndex, int numPages, int pageIndex, int slot) {
|
||||
if((pageIndex < 0) || (pageIndex >= numPages)) {
|
||||
return;
|
||||
}
|
||||
|
||||
copyPage(fileIndex, numPages, pageIndex, 0);
|
||||
removePage(fileIndex, numPages, pageIndex);
|
||||
}
|
||||
|
||||
void PDFJam::copyPage(int fileIndex, int numPages, int pageIndex, int slot) {
|
||||
QString cpTmp = "cp /tmp/hpdf/%1/%2.pdf /tmp/hpdf/clipboard%3.pdf";
|
||||
QString cmd = cpTmp.arg(QString::number(fileIndex)).arg(QString::number(pageIndex))
|
||||
.arg(QString::number(slot));
|
||||
pushCommand(cmd);
|
||||
}
|
||||
|
||||
void PDFJam::pastePage(int fileIndex, int numPages, int pageIndex, int slot) {
|
||||
/* TODO: Check if the clipboard file exists. */
|
||||
QString cmd = "";
|
||||
QString mvTmp = "mv /tmp/hpdf/%1/%2.pdf /tmp/hpdf/%3/%4.pdf ";
|
||||
for(int i = numPages-1; i >= pageIndex; i--) {
|
||||
cmd += mvTmp.arg(QString::number(fileIndex)).arg(QString::number(i))
|
||||
.arg(QString::number(fileIndex)).arg(QString::number(i+1));
|
||||
if(i > pageIndex) cmd += " && ";
|
||||
}
|
||||
|
||||
QString pasteTmp = "cp /tmp/hpdf/clipboard%3.pdf /tmp/hpdf/%1/%2.pdf ";
|
||||
cmd += " && " + pasteTmp.arg(QString::number(fileIndex))
|
||||
.arg(QString::number(pageIndex)).arg(QString::number(slot));
|
||||
pushCommand(cmd);
|
||||
}
|
||||
|
||||
void PDFJam::movePage(int fromFileIndex, int fromFileNumPage, int fromPageIndex,
|
||||
int toFileIndex, int toFileNumPage, int toPageIndex) {
|
||||
/* TODO: Back up clipboard. */
|
||||
/* If this page is moving with files update to file index. */
|
||||
if(toFileIndex == fromFileIndex) {
|
||||
toFileNumPage--;
|
||||
if(toPageIndex > fromPageIndex)
|
||||
toPageIndex--;
|
||||
toPageIndex--;
|
||||
}
|
||||
|
||||
cutPage(fromFileIndex, fromFileNumPage, fromPageIndex, 0);
|
||||
pastePage(toFileIndex, toFileNumPage, toPageIndex, 0);
|
||||
}
|
||||
|
||||
void PDFJam::savePageAsImage(Poppler::Page pp, QString dst, double dpi = 72) {
|
||||
|
||||
}
|
||||
|
||||
|
||||
/* Export file number 'fileIndex' to destination. */
|
||||
/* Supported n-up, orientation, offset options. */
|
||||
void PDFJam::exportFile(int fileIndex, int numPages, QString dst,
|
||||
QSize nup = QSize(1,1), bool isLandscape = false, bool hasTwoSideOffset = false,
|
||||
int leftOffset = 0, int rightOffset = 0) {
|
||||
|
||||
QString cmd = "pdfjam ";
|
||||
QString tmp = "/tmp/hpdf/%1/%2.pdf '-' ";
|
||||
|
||||
for(int i = 0; i < numPages; i++) {
|
||||
cmd += tmp.arg(QString::number(fileIndex)).arg(QString::number(i));
|
||||
}
|
||||
|
||||
QString orientation = isLandscape?" --landscape ": " --no-landscape ";
|
||||
cmd = orientation;
|
||||
if((nup.width() == 1) || (nup.height() != 1)) {
|
||||
QString nupTmp = " --nup '%1x%1' --frame true ";
|
||||
cmd += nupTmp.arg(QString::number(nup.width())).arg(QString::number(nup.height()));
|
||||
}
|
||||
|
||||
QString outTmp = " --outfile %1 ";
|
||||
cmd += outTmp.arg(dst);
|
||||
pushCommand(cmd);
|
||||
/* Offset comes next. */
|
||||
}
|
||||
|
||||
void PDFJam::loadFile(QString fileName, int fileIndex, Poppler::Document* pd) {
|
||||
int numPages = pd->numPages();
|
||||
QString path = "/tmp/hpdf/%1/";
|
||||
path = path.arg(QString::number(fileIndex));
|
||||
makeFolder(path);
|
||||
|
||||
QString tmp = "pdfjam %1 %2 --outfile %3%4.pdf %5";
|
||||
QString cmd = "";
|
||||
for(int i = 0; i <= numPages; i++) {
|
||||
QString orientation = " --no-landscape ";
|
||||
QSizeF pageSize = pd->page(i)->pageSizeF();
|
||||
if(pageSize.width() > pageSize.height()) {
|
||||
orientation = " --landscape ";
|
||||
}
|
||||
cmd += tmp.arg(fileName).arg(QString::number(i+1)).arg(path)
|
||||
.arg(QString::number(i)).arg(orientation) + " ; ";
|
||||
}
|
||||
pushCommand(cmd);
|
||||
|
||||
/* Test the backend functions. */
|
||||
rotatePage(0, 5, 270);
|
||||
movePage(0, numPages, 5, 0, numPages, 10);
|
||||
/*removePage(0, numPages, 5);*/
|
||||
exportFile(0, numPages, "/home/allanis/conco.pdf", QSize(2, 2), true, true, 1, 0);
|
||||
/* End test. */
|
||||
}
|
||||
|
||||
QString PDFJam::nextCommand(void) {
|
||||
QString cmd;
|
||||
mutex.lock();
|
||||
cmd = cmdQueue.first();
|
||||
cmdQueue.pop_front();
|
||||
mutex.unlock();
|
||||
return cmd;
|
||||
}
|
||||
|
||||
bool PDFJam::isQueueEmpty(void) {
|
||||
return (cmdQueue.size()==0);
|
||||
}
|
||||
|
||||
void PDFJam::run(void) {
|
||||
while(!isQueueEmpty()) {
|
||||
QString cmd = nextCommand();
|
||||
int value = system(cmd.toStdString().c_str());
|
||||
if(value != 0)
|
||||
qDebug() << "ERROR: Failed to execute " << cmd;
|
||||
else
|
||||
qDebug() << "SUCCESS: executed " << cmd;
|
||||
}
|
||||
}
|
||||
|
@ -1,38 +0,0 @@
|
||||
#pragma once
|
||||
#include <QThread>
|
||||
#include <QMutex>
|
||||
#include <QImage>
|
||||
#include <poppler-qt5.h>
|
||||
|
||||
class PDFPageWidget;
|
||||
class QImage;
|
||||
|
||||
class PDFJam : public QThread {
|
||||
Q_OBJECT
|
||||
public:
|
||||
PDFJam(void);
|
||||
|
||||
void pushCommand(QString);
|
||||
void loadFile(QString fileName, int, Poppler::Document*);
|
||||
void exportFile(int, int, QString, QSize, bool, bool, int, int);
|
||||
void savePageAsImage(Poppler::Page pp, QString dst, double);
|
||||
void movePage(int, int, int, int, int, int);
|
||||
|
||||
void pastePage(int, int, int, int);
|
||||
void copyPage(int, int, int, int);
|
||||
void cutPage(int, int, int, int);
|
||||
|
||||
bool removePage(int, int, int);
|
||||
bool rotatePage(int, int, int);
|
||||
void makeFolder(QString);
|
||||
|
||||
protected:
|
||||
void run(void);
|
||||
|
||||
private:
|
||||
QVector<QString> cmdQueue;
|
||||
QString nextCommand(void);
|
||||
bool isQueueEmpty(void);
|
||||
QMutex mutex;
|
||||
};
|
||||
|
@ -1,137 +0,0 @@
|
||||
#include <QtGlobal>
|
||||
#include <QtWidgets>
|
||||
#include "pdf_page_widget.h"
|
||||
#include "pdf_table_widget.h"
|
||||
|
||||
PDFPageWidget::PDFPageWidget(QWidget* parent) :
|
||||
QFrame(parent) {
|
||||
|
||||
selected = false;
|
||||
setAcceptDrops(true);
|
||||
|
||||
this->resize(150, 150);
|
||||
this->setMinimumSize(150, 150);
|
||||
this->setMaximumSize(150, 150);
|
||||
this->setAutoFillBackground(true);
|
||||
|
||||
this->setMouseTracking(true);
|
||||
this->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
|
||||
|
||||
|
||||
QHBoxLayout* topHBox = new QHBoxLayout();
|
||||
btnRotate = new QPushButton("", this);
|
||||
btnRotate->setObjectName("rotate");
|
||||
btnRotate->setIcon(QPixmap::fromImage(QImage("img/rotate.png")));
|
||||
btnRotate->hide();
|
||||
topHBox->addWidget(btnRotate, 0, Qt::AlignLeft);
|
||||
|
||||
QHBoxLayout* bottomHBox = new QHBoxLayout();
|
||||
btnCut = new QPushButton("", this);
|
||||
btnCut->setObjectName("cut");
|
||||
btnCut->setIcon(QPixmap::fromImage(QImage("img/cut.png")));
|
||||
btnCut->hide();
|
||||
|
||||
btnCopy = new QPushButton("", this);
|
||||
btnCopy->setObjectName("copy");
|
||||
|
||||
btnCopy->setIcon(QPixmap::fromImage(QImage("img/copy.png")));
|
||||
btnCopy->hide();
|
||||
|
||||
bottomHBox->addWidget(btnCut, 0, Qt::AlignLeft);
|
||||
bottomHBox->addWidget(btnCopy, 1, Qt::AlignRight);
|
||||
|
||||
QVBoxLayout* vbox = new QVBoxLayout();
|
||||
vbox->addLayout(topHBox);
|
||||
vbox->addStretch(1);
|
||||
vbox->addLayout(bottomHBox);
|
||||
vbox->setContentsMargins(0, 3, 0, 3);
|
||||
this->setLayout(vbox);
|
||||
}
|
||||
|
||||
void PDFPageWidget::setAncestor(QWidget* ancestor) {
|
||||
this->ancestor = ancestor;
|
||||
((PDFTableWidget*)ancestor)->registerPage(this);
|
||||
connect(this, SIGNAL(previewUpdate(Poppler::Page*)), ancestor,
|
||||
SIGNAL(previewUpdate(Poppler::Page*)));
|
||||
|
||||
connect(this, SIGNAL(pageClicked(PDFPageWidget*, QMouseEvent*, QString)),
|
||||
ancestor, SLOT(pageClicked(PDFPageWidget*, QMouseEvent*, QString)));
|
||||
connect(this, SIGNAL(pageDropped(PDFPageWidget*, QDropEvent*, QString,QString)),
|
||||
ancestor, SLOT(pageDropped(PDFPageWidget*, QDropEvent*, QString,QString)));
|
||||
}
|
||||
|
||||
void PDFPageWidget::setFather(QWidget* father) {
|
||||
this->father = father;
|
||||
}
|
||||
|
||||
void PDFPageWidget::setPopplerPage(Poppler::Page* pp) {
|
||||
pPage = pp;
|
||||
}
|
||||
|
||||
void PDFPageWidget::setThumbnail(QImage pageImage) {
|
||||
image = pageImage;
|
||||
pixmap = QPixmap::fromImage(image);
|
||||
pixmap = pixmap.scaled(size() - QSize(6,6), Qt::KeepAspectRatio);
|
||||
|
||||
update();
|
||||
}
|
||||
|
||||
void PDFPageWidget::setSelected(bool select) {
|
||||
selected = select;
|
||||
update();
|
||||
}
|
||||
|
||||
void PDFPageWidget::mousePressEvent(QMouseEvent* event) {
|
||||
if(pPage != NULL) {
|
||||
emit pageClicked(this, event, path);
|
||||
emit previewUpdate(pPage);
|
||||
|
||||
selected = !selected;
|
||||
update();
|
||||
}
|
||||
}
|
||||
|
||||
void PDFPageWidget::dragEnterEvent(QDragEnterEvent* event) {
|
||||
event->acceptProposedAction();
|
||||
}
|
||||
|
||||
void PDFPageWidget::dropEvent(QDropEvent* event) {
|
||||
emit pageDropped(this, event, event->mimeData()->text(), path);
|
||||
event->acceptProposedAction();
|
||||
}
|
||||
|
||||
void PDFPageWidget::leaveEvent(QEvent* event) {
|
||||
btnRotate->hide();
|
||||
btnCut->hide();
|
||||
btnCopy->hide();
|
||||
|
||||
this->setFrameStyle(QFrame::Plain);
|
||||
}
|
||||
|
||||
void PDFPageWidget::enterEvent(QEvent* event) {
|
||||
btnRotate->show();
|
||||
btnCut->show();
|
||||
btnCopy->show();
|
||||
|
||||
this->setFrameStyle(QFrame::StyledPanel | QFrame::Raised);
|
||||
}
|
||||
|
||||
void PDFPageWidget::paintEvent(QPaintEvent* event) {
|
||||
QPalette palette = this->palette();
|
||||
if(selected)
|
||||
palette.setColor(backgroundRole(), palette.color(QPalette::Highlight));
|
||||
else
|
||||
palette.setColor(backgroundRole(), palette.color(QPalette::AlternateBase));
|
||||
this->setPalette(palette);
|
||||
|
||||
QFrame::paintEvent(event);
|
||||
QPainter painter(this);
|
||||
painter.drawPixmap(QRect((size().width() - pixmap.width()) / 2,
|
||||
(size().height() - pixmap.height()) / 2,
|
||||
pixmap.width(), pixmap.height()), pixmap);
|
||||
}
|
||||
|
||||
QSize PDFPageWidget::sizeHint() const {
|
||||
return size();
|
||||
}
|
||||
|
@ -1,57 +0,0 @@
|
||||
#pragma once
|
||||
#include <QFrame>
|
||||
#include <poppler-qt5.h>
|
||||
|
||||
class QWidget;
|
||||
class QPushButton;
|
||||
class QImage;
|
||||
class QPixmap;
|
||||
class QPaintEvent;
|
||||
class QEvent;
|
||||
class QMouseEvent;
|
||||
class QSize;
|
||||
|
||||
class PDFPageWidget : public QFrame {
|
||||
Q_OBJECT
|
||||
public:
|
||||
PDFPageWidget(QWidget* parent = 0);
|
||||
QSize sizeHint(void) const;
|
||||
|
||||
void setThumbnail(QImage pageImage);
|
||||
void setPopplerPage(Poppler::Page*);
|
||||
void setAncestor(QWidget* ancestor);
|
||||
void setFather(QWidget* father);
|
||||
QWidget* getFather(void) const { return father; }
|
||||
void registerName(QString name) { path = name; }
|
||||
QString getName(void) { return path; }
|
||||
|
||||
void setSelected(bool select);
|
||||
bool isSelected(void) { return selected; }
|
||||
|
||||
protected:
|
||||
void paintEvent(QPaintEvent* event);
|
||||
void enterEvent(QEvent* event);
|
||||
void leaveEvent(QEvent* event);
|
||||
void mousePressEvent(QMouseEvent* event);
|
||||
void dragEnterEvent(QDragEnterEvent* event);
|
||||
void dropEvent(QDropEvent* event);
|
||||
|
||||
private:
|
||||
/*QVector<QPushButton> buttons;*/
|
||||
QString path;
|
||||
QWidget* ancestor;
|
||||
QWidget* father;
|
||||
|
||||
QImage image;
|
||||
Poppler::Page* pPage;
|
||||
QPixmap pixmap;
|
||||
QPushButton* btnRotate, *btnCut, *btnCopy;
|
||||
|
||||
bool selected;
|
||||
|
||||
signals:
|
||||
void pageClicked(PDFPageWidget*, QMouseEvent*, QString);
|
||||
void pageDropped(PDFPageWidget*, QDropEvent*, QString, QString);
|
||||
void previewUpdate(Poppler::Page*);
|
||||
};
|
||||
|
@ -1,121 +0,0 @@
|
||||
#include <QtWidgets>
|
||||
#include "pdf_preview_widget.h"
|
||||
|
||||
PDFPreviewWidget::PDFPreviewWidget(QWidget* parent) : QFrame(parent) {
|
||||
setCursor(Qt::OpenHandCursor);
|
||||
setFrameStyle(QFrame::StyledPanel | QFrame::Plain);
|
||||
pPage = NULL;
|
||||
currentPixmapSize = QSize(0,0);
|
||||
}
|
||||
|
||||
void PDFPreviewWidget::regenImage(void) {
|
||||
double dpi;
|
||||
double dpi2;
|
||||
QSize targetSize;
|
||||
|
||||
if(currentPixmapSize == QSize(0,0))
|
||||
currentPixmapSize = this->size();
|
||||
|
||||
targetSize = currentPixmapSize;
|
||||
QSizeF oriSize = pPage->pageSizeF();
|
||||
double oriDpi = 72;
|
||||
dpi = targetSize.height() / (float)oriSize.height()*oriDpi;
|
||||
dpi2 = targetSize.width() / (float)oriSize.width()*oriDpi;
|
||||
dpi = dpi<dpi2?dpi:dpi2;
|
||||
previewImage = pPage->renderToImage(dpi, dpi);
|
||||
}
|
||||
|
||||
void PDFPreviewWidget::regenPixmap(void) {
|
||||
pixmap = QPixmap::fromImage(previewImage);
|
||||
pixmap = pixmap.scaled(currentPixmapSize, Qt::KeepAspectRatioByExpanding);
|
||||
currentPixmapSize = pixmap.size();
|
||||
}
|
||||
|
||||
void PDFPreviewWidget::repositionPixmap(void) {
|
||||
currentPixmapPos = QPoint((size().width() - pixmap.width()) / 2,
|
||||
(size().height() - pixmap.height()) / 2);
|
||||
}
|
||||
|
||||
void PDFPreviewWidget::previewUpdate(Poppler::Page* pp) {
|
||||
pPage = pp;
|
||||
regenImage();
|
||||
regenPixmap();
|
||||
repositionPixmap();
|
||||
update();
|
||||
}
|
||||
|
||||
void PDFPreviewWidget::resizeEvent(QResizeEvent* event) {
|
||||
if(pPage != NULL) {
|
||||
repositionPixmap();
|
||||
update();
|
||||
}
|
||||
}
|
||||
|
||||
void PDFPreviewWidget::wheelEvent(QWheelEvent* event) {
|
||||
if(pPage != NULL) {
|
||||
if(event->delta() > 0)
|
||||
currentPixmapSize += QSize(30, 30);
|
||||
else if(event->delta() < 0)
|
||||
currentPixmapSize -= QSize(30, 30);
|
||||
|
||||
if(currentPixmapSize.width() < 150 || currentPixmapSize.height() < 150) {
|
||||
currentPixmapSize = QSize(150, 150);
|
||||
}
|
||||
|
||||
regenImage();
|
||||
regenPixmap();
|
||||
repositionPixmap();
|
||||
update();
|
||||
}
|
||||
}
|
||||
|
||||
void PDFPreviewWidget::mousePressEvent(QMouseEvent* event) {
|
||||
if(pPage != NULL) {
|
||||
setCursor(Qt::ClosedHandCursor);
|
||||
|
||||
if(event->button() == Qt::LeftButton) {
|
||||
dragStartPos = event->pos();
|
||||
lastPixmapPos = currentPixmapPos;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void PDFPreviewWidget::mouseMoveEvent(QMouseEvent* event) {
|
||||
if(pPage != NULL) {
|
||||
if(!(event->buttons() & Qt::LeftButton)) {
|
||||
return;
|
||||
}
|
||||
|
||||
QPoint currentPos = event->pos();
|
||||
QPoint vector = currentPos - dragStartPos;
|
||||
QPoint newPos = lastPixmapPos + vector;
|
||||
|
||||
if(pixmap.width() > size().width()) {
|
||||
if(newPos.x() <= 0 && newPos.x() >= size().width() - pixmap.width())
|
||||
currentPixmapPos.setX(newPos.x());
|
||||
}
|
||||
|
||||
if(pixmap.height() > size().height()) {
|
||||
if(newPos.y() <= 0 && newPos.y() >= size().height() - pixmap.height())
|
||||
currentPixmapPos.setY(newPos.y());
|
||||
}
|
||||
|
||||
update();
|
||||
}
|
||||
}
|
||||
|
||||
void PDFPreviewWidget::mouseReleaseEvent(QMouseEvent* event) {
|
||||
setCursor(Qt::OpenHandCursor);
|
||||
}
|
||||
|
||||
void PDFPreviewWidget::paintEvent(QPaintEvent* event) {
|
||||
if(pPage != NULL) {
|
||||
|
||||
QPainter painter(this);
|
||||
painter.drawPixmap(QRect(currentPixmapPos.x(), currentPixmapPos.y(),
|
||||
pixmap.width(), pixmap.height()), pixmap);
|
||||
|
||||
QFrame::paintEvent(event);
|
||||
}
|
||||
}
|
||||
|
@ -1,46 +0,0 @@
|
||||
#pragma once
|
||||
#include <QFrame>
|
||||
#include <poppler-qt5.h>
|
||||
|
||||
class QImage;
|
||||
class QPixmap;
|
||||
class QSize;
|
||||
class QPoint;
|
||||
class QResizeEvent;
|
||||
class QWheelEvent;
|
||||
class QPaintEvent;
|
||||
class QMouseEvent;
|
||||
|
||||
class PDFPreviewWidget : public QFrame {
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit PDFPreviewWidget(QWidget* parent = 0);
|
||||
|
||||
public slots:
|
||||
void regenImage(void);
|
||||
void regenPixmap(void);
|
||||
void repositionPixmap(void);
|
||||
void previewUpdate(Poppler::Page*);
|
||||
|
||||
protected:
|
||||
void wheelEvent(QWheelEvent* event);
|
||||
void paintEvent(QPaintEvent* event);
|
||||
void resizeEvent(QResizeEvent* event);
|
||||
void mousePressEvent(QMouseEvent* event);
|
||||
void mouseMoveEvent(QMouseEvent* event);
|
||||
void mouseReleaseEvent(QMouseEvent* event);
|
||||
|
||||
private:
|
||||
QImage previewImage;
|
||||
QPixmap pixmap;
|
||||
Poppler::Page* pPage;
|
||||
|
||||
QSize currentPixmapSize;
|
||||
QPoint currentPixmapPos;
|
||||
QPoint lastPixmapPos;
|
||||
QPoint dragStartPos;
|
||||
|
||||
signals:
|
||||
void updatePreview(QImage);
|
||||
};
|
||||
|
@ -1,203 +0,0 @@
|
||||
#include <QtWidgets>
|
||||
#include <QtAlgorithms>
|
||||
#include "pdf_table_widget.h"
|
||||
#include "pdf_page_widget.h"
|
||||
#include "pdf_file_widget.h"
|
||||
|
||||
PDFTableWidget::PDFTableWidget(QWidget* parent) : QFrame(parent) {
|
||||
/* Frame (Expanding with VBox) - Scroll Area (Expanding)
|
||||
* Container (Expanding with VBox) - Children.
|
||||
*/
|
||||
setFrameStyle(QFrame::StyledPanel | QFrame::Plain);
|
||||
setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
|
||||
|
||||
outerLayout = new QVBoxLayout();
|
||||
outerLayout->setContentsMargins(0, 0, 0, 0);
|
||||
|
||||
scrollArea = new QScrollArea();
|
||||
scrollArea->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
|
||||
scrollArea->setWidgetResizable(true);
|
||||
scrollArea->setFrameStyle(QFrame::Plain);
|
||||
|
||||
containerLayout = new QVBoxLayout();
|
||||
containerLayout->setSpacing(10);
|
||||
containerWidget = new QWidget();
|
||||
containerWidget->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
|
||||
QWidget* spacer = new QWidget();
|
||||
spacer->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
|
||||
containerLayout->addWidget(spacer);
|
||||
containerWidget->setLayout(containerLayout);
|
||||
|
||||
scrollArea->setWidget(containerWidget);
|
||||
|
||||
outerLayout->addWidget(scrollArea);
|
||||
|
||||
setLayout(outerLayout);
|
||||
}
|
||||
|
||||
void PDFTableWidget::loadFile(QString fileName) {
|
||||
Poppler::Document* doc = Poppler::Document::load(fileName);
|
||||
files.append(doc);
|
||||
|
||||
PDFFileWidget* fileWidget = new PDFFileWidget();
|
||||
fileWidget->setAncestor(this);
|
||||
fileWidget->setDocument(doc, fileName);
|
||||
pdfJam.loadFile(fileName, files.size()-1, doc);
|
||||
|
||||
fileWidgets.append(fileWidget);
|
||||
|
||||
fileNames.append(fileName);
|
||||
|
||||
containerLayout->insertWidget(containerLayout->count()-1, fileWidget);
|
||||
connect(fileWidget, SIGNAL(fileRemoveButtonClicked(PDFFileWidget*)), this,
|
||||
SLOT(fileRemoveButtonClicked(PDFFileWidget*)));
|
||||
}
|
||||
|
||||
void PDFTableWidget::registerPage(PDFPageWidget* child) {
|
||||
/* Need new name? */
|
||||
QString name = QString("/home/pdfpage").append(QString::number(pageChilds.size()));
|
||||
qDebug() << "Registering name:";
|
||||
qDebug() << name;
|
||||
pageChilds[name] = child;
|
||||
child->registerName(name);
|
||||
}
|
||||
|
||||
void PDFTableWidget::fileClicked(PDFFileWidget* sender, QMouseEvent* event) {
|
||||
if(event->button() == Qt::LeftButton) {
|
||||
if(event->modifiers() != Qt::LeftButton) {
|
||||
for(int i = 0; i < selectedFiles.size(); i++) {
|
||||
selectedFiles.at(i)->setSelected(false);
|
||||
}
|
||||
|
||||
selectedFiles.clear();
|
||||
|
||||
if(!sender->isSelected()) {
|
||||
sender->setSelected(true);
|
||||
selectedFiles.append(sender);
|
||||
}
|
||||
} else {
|
||||
if(!sender->isSelected()) {
|
||||
sender->setSelected(true);
|
||||
selectedFiles.append(sender);
|
||||
} else {
|
||||
sender->setSelected(false);
|
||||
selectedFiles.remove(selectedFiles.indexOf(sender));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void PDFTableWidget::fileRemoveButtonClicked(PDFFileWidget* sender) {
|
||||
selectedFiles.remove(selectedFiles.indexOf(sender));
|
||||
|
||||
QVector<int> pagesToRemove;
|
||||
for(int i = 0; i < selectedPages.size(); i++) {
|
||||
if(selectedPages.at(i)->getFather() == sender) {
|
||||
pagesToRemove.append(i);
|
||||
}
|
||||
}
|
||||
|
||||
for(int i = 0; i < pagesToRemove.size(); i++) {
|
||||
selectedPages.remove(pagesToRemove.at(i));
|
||||
}
|
||||
|
||||
/* Handle remove file here. */
|
||||
}
|
||||
|
||||
void PDFTableWidget::pageClicked(PDFPageWidget* sender, QMouseEvent* event, QString path) {
|
||||
if(event->button() == Qt::LeftButton) {
|
||||
/* Handle selection. */
|
||||
if(selectedPages.size() > 0 && event->modifiers() != Qt::ControlModifier) {
|
||||
/* Handle Drag. */
|
||||
QDrag* drag = new QDrag(this);
|
||||
QMimeData* mimeData = new QMimeData;
|
||||
|
||||
mimeData->setText(path);
|
||||
drag->setMimeData(mimeData);
|
||||
drag->setPixmap(QPixmap(":/img/copy.png"));
|
||||
|
||||
drag->exec();
|
||||
} else {
|
||||
if(!sender->isSelected()) {
|
||||
sender->setSelected(true);
|
||||
PDFFileWidget* senderF = (PDFFileWidget*)sender->getFather();
|
||||
int senderPID = senderF->indexChild(sender);
|
||||
int senderFID = fileWidgets.indexOf(senderF);
|
||||
|
||||
int i = 0;
|
||||
for(i = 0; i < selectedPages.size(); i++) {
|
||||
PDFPageWidget* target = selectedPages.at(i);
|
||||
PDFFileWidget* targetF = (PDFFileWidget*)target->getFather();
|
||||
int targetPID = targetF->indexChild(target);
|
||||
int targetFID = fileWidgets.indexOf(targetF);
|
||||
|
||||
if(targetFID == senderFID && targetFID > senderFID)
|
||||
break;
|
||||
|
||||
if(targetFID > senderFID)
|
||||
break;
|
||||
}
|
||||
|
||||
selectedPages.insert(i, sender);
|
||||
} else {
|
||||
sender->setSelected(false);
|
||||
selectedPages.remove(selectedPages.indexOf(sender));
|
||||
}
|
||||
}
|
||||
}
|
||||
if(event->button() == Qt::RightButton) {
|
||||
for(int i = 0; i < selectedPages.size(); i++) {
|
||||
selectedPages.at(i)->setSelected(false);
|
||||
}
|
||||
|
||||
selectedPages.clear();
|
||||
}
|
||||
}
|
||||
|
||||
void PDFTableWidget::pageDropped(PDFPageWidget* sender, QDropEvent* event,
|
||||
QString pathFrom, QString pathTo) {
|
||||
|
||||
moveSelectedPages(pathFrom, pathTo);
|
||||
}
|
||||
|
||||
void PDFTableWidget::moveSelectedPages(QString pathFrom, PDFPageWidget* page) {
|
||||
moveSelectedPages(pathFrom, page->getName());
|
||||
}
|
||||
|
||||
void PDFTableWidget::moveSelectedPages(QString pathFrom, QString pathTo) {
|
||||
if(selectedPages.size() == 0)
|
||||
return;
|
||||
|
||||
bool accept = false;
|
||||
for(int i = 0; i < selectedPages.size(); i++)
|
||||
if(selectedPages.at(i)->getName() == pathFrom)
|
||||
accept = true;
|
||||
|
||||
if(!accept)
|
||||
return;
|
||||
|
||||
for(int i = 0; i < selectedPages.size(); i++)
|
||||
if(selectedPages.at(i)->getName() == pathTo)
|
||||
return;
|
||||
|
||||
PDFPageWidget* childTo = pageChilds[pathTo];
|
||||
PDFFileWidget* fileTo = (PDFFileWidget*) childTo->getFather();
|
||||
|
||||
for(int i = selectedPages.size() - 1; i >= 0; i--) {
|
||||
PDFPageWidget* childFrom = selectedPages[i];
|
||||
PDFFileWidget* fileFrom = (PDFFileWidget*) childFrom->getFather();
|
||||
fileFrom->removeChild(childFrom);
|
||||
/*PDFFileWidget* fileFrom = (PDFFileWidget*) childFrom->getFather();*/
|
||||
|
||||
/*int posFrom = fileFrom->removeChild(childFrom);*/
|
||||
}
|
||||
int posTo = fileTo->indexChild(childTo);
|
||||
|
||||
for(int i = selectedPages.size() - 1; i >= 0; i--) {
|
||||
PDFPageWidget* childFrom = selectedPages[i];
|
||||
PDFFileWidget* fileFrom = (PDFFileWidget*)childFrom->getFather();
|
||||
fileTo->insertChildAt(childFrom, posTo);
|
||||
/*fileFrom->insertChildAt(childTo, posFrom);*/
|
||||
}
|
||||
}
|
||||
|
@ -1,59 +0,0 @@
|
||||
#pragma once
|
||||
#include <QFrame>
|
||||
#include <QHash>
|
||||
#include <poppler-qt5.h>
|
||||
|
||||
#include "pdf_jam.h"
|
||||
#include "pdf_page_widget.h"
|
||||
|
||||
class QImage;
|
||||
class QVBoxLayout;
|
||||
class QString;
|
||||
class QScrollArea;
|
||||
class QMouseEvent;
|
||||
class QPoint;
|
||||
class PDFFileWidget;
|
||||
|
||||
class PDFTableWidget : public QFrame {
|
||||
Q_OBJECT
|
||||
public:
|
||||
PDFTableWidget(QWidget* parent = 0);
|
||||
void loadFile(QString fileName);
|
||||
void registerPage(PDFPageWidget* child);
|
||||
|
||||
protected:
|
||||
PDFJam pdfJam;
|
||||
|
||||
private:
|
||||
QVBoxLayout* outerLayout;
|
||||
QScrollArea* scrollArea;
|
||||
QWidget* containerWidget;
|
||||
QVBoxLayout* containerLayout;
|
||||
|
||||
QVector<Poppler::Document*> files;
|
||||
QVector<QString> fileNames;
|
||||
QVector<PDFFileWidget*> fileWidgets;
|
||||
|
||||
QHash<QString, PDFPageWidget*> pageChilds;
|
||||
|
||||
signals:
|
||||
void pageClicked(QMouseEvent*, QImage);
|
||||
void previewUpdate(Poppler::Page*);
|
||||
|
||||
private slots:
|
||||
void fileRemoveButtonClicked(PDFFileWidget*);
|
||||
void pageClicked(PDFPageWidget*, QMouseEvent*, QString);
|
||||
void pageDropped(PDFPageWidget*, QDropEvent*, QString, QString);
|
||||
|
||||
void fileClicked(PDFFileWidget*, QMouseEvent*);
|
||||
|
||||
private:
|
||||
QVector<PDFPageWidget*> selectedPages;
|
||||
QVector<PDFFileWidget*> selectedFiles;
|
||||
|
||||
/*bool operator()(PDFPageWidget* e1, PDFPageWidget* e2);*/
|
||||
public:
|
||||
void moveSelectedPages(QString, QString);
|
||||
void moveSelectedPages(QString, PDFPageWidget* page);
|
||||
};
|
||||
|
@ -1,45 +0,0 @@
|
||||
#include <QtGlobal>
|
||||
#include <QtWidgets>
|
||||
#include "thumbgen.h"
|
||||
#include "pdf_page_widget.h"
|
||||
|
||||
ThumbGen::ThumbGen(void) {
|
||||
|
||||
}
|
||||
|
||||
double ThumbGen::calcDpi(Poppler::Page* pdfPage, QSize targetSize) {
|
||||
double dpi;
|
||||
QSizeF oriSize = pdfPage->pageSizeF();
|
||||
double oriDpi = 72;
|
||||
|
||||
if(targetSize.width() > targetSize.height()) {
|
||||
dpi = targetSize.height() / (float)oriSize.height()*72;
|
||||
} else {
|
||||
dpi = targetSize.width() / (float)oriSize.width()*72;
|
||||
}
|
||||
|
||||
return dpi;
|
||||
}
|
||||
|
||||
void ThumbGen::run(void) {
|
||||
while(pWidgets.size() != 0) {
|
||||
mutex.lock();
|
||||
PDFPageWidget* pw = pWidgets.first();
|
||||
pWidgets.pop_front();
|
||||
Poppler::Page* pp = pPages.first();
|
||||
pPages.pop_front();
|
||||
mutex.unlock();
|
||||
|
||||
double dpi = calcDpi(pp, pw->size());
|
||||
QImage pageImage = pp->renderToImage(dpi, dpi);
|
||||
emit updateThumbnail(pageImage, pw);
|
||||
}
|
||||
}
|
||||
|
||||
void ThumbGen::render(PDFPageWidget* pw, Poppler::Page* pp) {
|
||||
mutex.lock();
|
||||
pWidgets.append(pw);
|
||||
pPages.append(pp);
|
||||
mutex.unlock();
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user