[Add] Export dialogue.

This commit is contained in:
Rtch90 2014-12-22 11:06:01 +00:00
parent 05d42cf2eb
commit cc955d6489
40 changed files with 2246 additions and 1485 deletions

View File

@ -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/
}
}

View File

@ -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>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 850 B

After

Width:  |  Height:  |  Size: 244 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 893 B

After

Width:  |  Height:  |  Size: 387 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.2 KiB

After

Width:  |  Height:  |  Size: 1.1 KiB

229
src/PDFExportDialog.cpp Normal file
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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();
}

View File

@ -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*);
};

View File

@ -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();
}

View File

@ -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;
}

View File

@ -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;
};

View File

@ -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>

View File

@ -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);
}
}
}

View File

@ -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;
};

View File

@ -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();
}

View File

@ -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*);
};

View File

@ -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;
}
}

View File

@ -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;
};

View File

@ -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();
}

View File

@ -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*);
};

View File

@ -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);
}
}

View File

@ -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);
};

View File

@ -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);*/
}
}

View File

@ -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);
};

View File

@ -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();
}