diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/config.cpp | 115 | ||||
-rw-r--r-- | src/config.h | 50 | ||||
-rw-r--r-- | src/main.cpp | 30 | ||||
-rw-r--r-- | src/mainwindow.cpp | 413 | ||||
-rw-r--r-- | src/mainwindow.h | 126 | ||||
-rw-r--r-- | src/mainwindow.ui | 40 | ||||
-rw-r--r-- | src/pdfPresentation2.pro | 34 | ||||
-rw-r--r-- | src/pdfWindow.cpp | 139 | ||||
-rw-r--r-- | src/pdfWindow.h | 68 | ||||
-rw-r--r-- | src/secondarywindow.ui | 39 |
10 files changed, 1054 insertions, 0 deletions
diff --git a/src/config.cpp b/src/config.cpp new file mode 100644 index 0000000..60e3345 --- /dev/null +++ b/src/config.cpp @@ -0,0 +1,115 @@ +/* +Copyright 2015 Ian Jauslin + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +#include "config.h" + +#define READMODE_DEFAULT 0 +#define READMODE_TIME 1 +#define READMODE_SLIDELIST 2 + +// constructor +Config::Config(int argc,char* argv[]){ + // defaults + loadDefaults(); + // CLI options + readconf(argc,argv); +} + +// default values +void Config::loadDefaults(){ + document_path='\0'; + presentation_time=15; + slidelist_path='\0'; +} + +// read CLI options +void Config::readconf(int argc,char* argv[]){ + int i; + // mode specifier (e.g. reading duration?) + int mode=READMODE_DEFAULT; + // loop over arguments + for(i=1;i<argc;i++){ + // the i=th argument + char* arg=argv[i]; + // behavior depends on mode + switch(mode){ + // default mode + case READMODE_DEFAULT: + // - means flagging options should follow + if(arg[0]=='-'){ + // loop over flags following - + for(arg++;*arg!='\0';arg++){ + switch (*arg){ + // duration flag + case 't': + //go into duration reading mode (next argument should be the duration) + mode=READMODE_TIME; + break; + // slidelist flag + case 's': + //go into slidelist reading mode + mode=READMODE_SLIDELIST; + } + } + } + else{ + // if the argument does not start with -, then it must denote the path to the PDF file + document_path=arg; + } + break; + // read duration mode + case READMODE_TIME: + //check that the argument is an integer + if(check_int(arg)){ + sscanf(arg,"%d",&presentation_time); + } + else{ + printf("syntax error: received argument '-t %s' when -t must be followed by an integer\n",arg); + } + // back to default mode for next argument + mode=READMODE_DEFAULT; + break; + + // read slidelist mode + case READMODE_SLIDELIST: + slidelist_path=arg; + // back to default mode for next argument + mode=READMODE_DEFAULT; + } + } +} + +// display configuration options +void Config::showconf(){ + printf("document: %s\n",document_path); + printf("presentation duration: %d\n",presentation_time); + printf("slidelist: %s\n",slidelist_path); +} + +// check whether a string is an integer +bool Config::check_int(char* string){ + // yes? + bool ret=1; + for(;*string!='\0';string++){ + // is the character a digit? + ret=ret && isdigit(*string); + } + return(ret); +} + +// empty destructor +Config::~Config(){ +} diff --git a/src/config.h b/src/config.h new file mode 100644 index 0000000..4b7bd07 --- /dev/null +++ b/src/config.h @@ -0,0 +1,50 @@ +/* +Copyright 2015 Ian Jauslin + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +#ifndef CONFIG_H +#define CONFIG_H + +#include <stdio.h> +#include <cctype> + +// configuration object (holds options) +class Config +{ + public: + // duration of the presentation + int presentation_time; + // document path + char* document_path; + // path to slidelist + char* slidelist_path; + + // constructor + Config(int argc, char* argv[]); + // display current options + void showconf(); + // destructor + ~Config(); + + private: + // default values + void loadDefaults(); + // read CLI options + void readconf(int argc, char* argv[]); + // check whether a string is an integer + bool check_int(char* string); +}; + +#endif // CONFIG_H diff --git a/src/main.cpp b/src/main.cpp new file mode 100644 index 0000000..337ae71 --- /dev/null +++ b/src/main.cpp @@ -0,0 +1,30 @@ +/* +Copyright 2015 Ian Jauslin + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +#include "mainwindow.h" +#include "config.h" +#include <QApplication> + +int main(int argc, char *argv[]) +{ + QApplication a(argc, argv); + Config* config=new Config(argc,argv); + MainWindow w; + w.setConfig(config); + w.show(); + + return a.exec(); +} diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp new file mode 100644 index 0000000..60d51f5 --- /dev/null +++ b/src/mainwindow.cpp @@ -0,0 +1,413 @@ +/* +Copyright 2015 Ian Jauslin + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +#include "mainwindow.h" +#include "ui_mainwindow.h" +#include "ui_secondarywindow.h" + +//constructor +MainWindow::MainWindow(QWidget *parent): + pdfWindow(parent), + ui(new Ui::MainWindow) +{ + //in order to catch arrow keys + QApplication::instance()->installEventFilter(this); + + // reads ui_mainwindow.h + ui->setupUi(this); + // hard coded ui specs + this->loadUi(); +} + +// load global configuration object +void MainWindow::setConfig(Config* config){ + // initialize constants + pres_time_step=0; + secondaryWindow=NULL; + timebar=NULL; + + conf=config; + if(conf->document_path=='\0'){ + std::cout << "error: no document loaded\n"; + return; + } + this->setDoc(conf->document_path); + this->readSlidelist(conf->slidelist_path); + // secondaryScreen must be called after setDoc + this->secondaryScreen(); +} + +// read list of frame numbers +void MainWindow::readSlidelist(char* path){ + // if file has been spcified + if(path!='\0'){ + // list as a vector of integers + slidelist=QVector<int>(100,-1); + QFile file(path); + file.open(QIODevice::ReadOnly | QIODevice::Text); + int i=0; + // number read + int slidenum; + while (!file.atEnd()) { + const char* line = file.readLine().constData(); + // if line is an integer + if(check_int(line)){ + sscanf(line,"%d",&slidenum); + slidelist[i]=slidenum; + i++; + } + } + // resize slidelist to its actual size + slidelist.resize(i); + } +} + +// check whether a string is an integer +bool MainWindow::check_int(const char* string){ + // yes? + bool ret=1; + for(;*string!='\n';string++){ + // is the character a digit? + ret=ret && isdigit(*string); + } + return(ret); +} + + +// setup secondary screen +void MainWindow::secondaryScreen(){ + // desktop manager information + QDesktopWidget* desktop=QApplication::desktop(); + const int nrscreens=desktop->screenCount(); + if(nrscreens>=2){ + // screen indices + nrMainScreen=(int)desktop->primaryScreen(); + nrSecScreen=nrMainScreen+1%nrscreens; + + if(secondaryWindow){delete secondaryWindow;} + secondaryWindow=new SecondaryWindow(this); + secondaryWindow->show(); + secondaryWindow->setDoc(doc); + + moveToScreen(this,nrMainScreen,desktop); + moveToScreen(secondaryWindow,nrSecScreen,desktop); + secondaryWindow->fullscreenPDF(); + + this->showhideTimeBar(); + } +} + +// exchange role of screens +void MainWindow::exchangeScreens(){ + if(secondaryWindow){ + // desktop manager information + QDesktopWidget* desktop=QApplication::desktop(); + // was the main window fullscreen? (the secondary one necessarily was) + bool wasFullscreen=0; + if(this->isFullScreen()){ + wasFullscreen=1; + // no fullscreen when moving + this->showNormal(); + } + secondaryWindow->showNormal(); + moveToScreen(this,nrSecScreen,desktop); + moveToScreen(secondaryWindow,nrMainScreen,desktop); + if(wasFullscreen){ + // workaround: if called immediately, the desktop manager makes the window fullscreen on the wrong screen + QTimer::singleShot(10, this, SLOT(showFullScreen())); + // this->showFullScreen(); + } + // workaround: if called immediately, the desktop manager makes the window fullscreen on the wrong screen + QTimer::singleShot(10, secondaryWindow, SLOT(showFullScreen())); + // secondaryWindow->showFullScreen(); + //exchange the indices + int tmp=nrMainScreen; + nrMainScreen=nrSecScreen; + nrSecScreen=tmp; + } +} + +// next PDF page with offset for secondary screen +void MainWindow::nextPage(){ + // should this be here? + // secondaryWindow->showFullScreen(); + this->pdfWindow::nextPage(); + if(secondaryWindow){ + if(curpage<totalpages-1 || secondaryWindow->curpage<totalpages-2){ + secondaryWindow->gotoPage(curpage-1); + } + else{ + secondaryWindow->gotoPage(curpage); + } + } +} +// previous PDF page with offset for secondary screen +void MainWindow::previousPage(){ + if(!secondaryWindow || secondaryWindow->curpage<totalpages-1){ + this->pdfWindow::previousPage(); + } + if(secondaryWindow){ + if(curpage>0){ + secondaryWindow->gotoPage(curpage-1); + } + else{ + secondaryWindow->gotoPage(curpage); + } + } +} +// go to page on secondary screen +1 page on main screen +void MainWindow::gotoPage(int page){ + if(!secondaryWindow){ + this->pdfWindow::gotoPage(page); + } + else if (page<totalpages-1){ + this->pdfWindow::gotoPage(page+1); + secondaryWindow->gotoPage(page); + } + else{ + this->pdfWindow::gotoPage(totalpages); + secondaryWindow->gotoPage(totalpages); + } +} + +void MainWindow::nextSlide(){ + int i; + for(i=0;i<slidelist.size();i++){ + if(slidelist.at(i)>secondaryWindow->curpage+1){ + this->gotoPage(slidelist.at(i)-1); + break; + } + } +} +void MainWindow::previousSlide(){ + int i; + int size=slidelist.size(); + for(i=0;i<size;i++){ + if(slidelist.at(size-i-1)<secondaryWindow->curpage+1){ + this->gotoPage(slidelist.at(size-i-1)-1); + break; + } + } +} + + +// show/hide time bar +void MainWindow::showhideTimeBar(){ + if(timebar){ + // remove timebar + ui->centralWidget->layout()->removeWidget(timebar); + delete timebar; + timebar=NULL; + // so that the view covers the entire height + this->verticalOffset=0; + this->updatePDF(); + } + else{ + timebar=new TimeIndicator(); + // initial time + timebar->setTime(pres_time_step,conf->presentation_time*60); + // add to window + ui->centralWidget->layout()->addWidget(timebar); + // so that the view leaves room for the bar + this->verticalOffset=timebar->sizeHint().height(); + this->updatePDF(); + } +} + +// start/stop timer +void MainWindow::startstopTimer(){ + if(pres_timer.isActive()){ + pres_timer.stop(); + } + else{ + pres_timer.start(1000,this); + } +} + +//reset timer +void MainWindow::resetTimer(){ + if(pres_timer.isActive()){ + pres_timer.stop(); + } + pres_time_step=0; + timebar->setTime(0,1); +} + +//called when pres_timer clicks: update timebar +void MainWindow::timerEvent(QTimerEvent *event){ + if (event->timerId() == pres_timer.timerId()) { + pres_time_step++; + // stop if end is reached + if(pres_time_step>=conf->presentation_time*60){ + pres_timer.stop(); + } + if(timebar){ + timebar->setTime(pres_time_step,conf->presentation_time*60); + } + } +} + +// move (non-fullscreen) window to a screen +void MainWindow::moveToScreen(QWidget* widget,int ascreen,QDesktopWidget* desktop){ + if(desktop->isVirtualDesktop()){ + QRect geo=desktop->screenGeometry(ascreen); + // move and center + widget->move(QPoint(geo.x()+geo.width()/2-this->width()/2,geo.y()+geo.height()/2-this->height()/2)); + } + else{ + std::cout << "Sorry, so far multiple screens are only supported on X11\n"; + } +} + +// load hard coded UI +void MainWindow::loadUi(){ + // window layout + layout=new QVBoxLayout; + // view + layout->addWidget(pdfView); + // to get rid of extra space + layout->setContentsMargins(0,0,0,0); + layout->setSpacing(0); + // remove scrollbars + pdfView->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); + pdfView->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff); + ui->centralWidget->setLayout(layout); +} + +void MainWindow::keyPressEvent(QKeyEvent* event){ + switch(event->key()){ + case Qt::Key_Right: + this->nextPage(); + break; + case Qt::Key_Left: + this->previousPage(); + break; + case Qt::Key_Down: + this->nextSlide(); + break; + case Qt::Key_Up: + this->previousSlide(); + break; + case Qt::Key_F: + this->fullscreenPDF(); + break; + case Qt::Key_Q: + QApplication::instance()->quit(); + break; + case Qt::Key_S: + this->startstopTimer(); + break; + case Qt::Key_T: + this->showhideTimeBar(); + break; + case Qt::Key_R: + this->resetTimer(); + break; + case Qt::Key_X: + this->exchangeScreens(); + break; + default: + std::cout << "unknown key pressed: " << event->key() << '\n'; + break; + } +} + +// to catch arrow keys +bool MainWindow::eventFilter(QObject *obj, QEvent *event) +{ + QKeyEvent *keyEvent = NULL;//event data, if this is a keystroke event + bool result = false;//return true to consume the keystroke + + if (event->type() == QEvent::KeyPress) + { + keyEvent = dynamic_cast<QKeyEvent*>(event); + this->keyPressEvent(keyEvent); + result = true; + }//if type() + + else if (event->type() == QEvent::KeyRelease) + { + keyEvent = dynamic_cast<QKeyEvent*>(event); + this->keyReleaseEvent(keyEvent); + result = true; + }//else if type() + + //### Standard event processing ### + else + result = QObject::eventFilter(obj, event); + + return result; +}//eventFilter + +// destructor +MainWindow::~MainWindow(){ + if(timebar){delete timebar;} + delete layout; + if(secondaryWindow){delete secondaryWindow;} + delete ui; +} + + + + +//secondary window ---------------------------------- + +// constructor +SecondaryWindow::SecondaryWindow(QWidget *parent): + pdfWindow(parent), + ui(new Ui::SecondaryWindow) +{ + ui->setupUi(this); + this->loadUi(); +} + +// UI +void SecondaryWindow::loadUi(){ + QHBoxLayout* layout=new QHBoxLayout; + layout->addWidget(pdfView); + pdfView->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); + pdfView->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff); + ui->centralWidget->setLayout(layout); + delete layout; +} + +// destructor +SecondaryWindow::~SecondaryWindow(){ + delete ui; +} + + + + +// TimeIndicator-------------------------------------------------- + +//contructor (completely inherited) +TimeIndicator::TimeIndicator(QWidget *parent): QProgressBar(parent){} + +// set value of progress bar as well as text +void TimeIndicator::setTime(int time,int maxtime){ + this->setValue((time*100)/maxtime); + // string representing elapsed time + char timestr[9]; + int hour=time/3600; + int minute=(time-hour*3600)/60; + int second=time-hour*3600-minute*60; + sprintf(timestr,"%02d:%02d:%02d",hour,minute,second); + this->setFormat(QString(timestr)); +} + +// destructor +TimeIndicator::~TimeIndicator(){} diff --git a/src/mainwindow.h b/src/mainwindow.h new file mode 100644 index 0000000..4e4aa77 --- /dev/null +++ b/src/mainwindow.h @@ -0,0 +1,126 @@ +/* +Copyright 2015 Ian Jauslin + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +#ifndef MAINWINDOW_H +#define MAINWINDOW_H + +#include "pdfWindow.h" +#include "config.h" +#include <QKeyEvent> +#include <QDesktopWidget> +#include <QProgressBar> +#include <QBasicTimer> +#include <QTimer> +#include <cctype> + +namespace Ui { + class MainWindow; + class SecondaryWindow; +} + +class SecondaryWindow; +class TimeIndicator; + +class MainWindow : public pdfWindow +{ + Q_OBJECT + + public: + // index of main screen + int nrMainScreen; + // index of secondary screen + int nrSecScreen; + // timer counter + int pres_time_step; + SecondaryWindow* secondaryWindow; + // slidelist + QVector<int> slidelist; + + // constructor + explicit MainWindow(QWidget *parent = 0); + + void setConfig(Config* config); + + //enable secondary screen + void secondaryScreen(); + void exchangeScreens(); + void moveToScreen(QWidget* widget,int screen,QDesktopWidget* desktop); + + void nextPage(); + void previousPage(); + void gotoPage(int page); + void nextSlide(); + void previousSlide(); + + void showhideTimeBar(); + void startstopTimer(); + void resetTimer(); + + // destructor + ~MainWindow(); + + private: + // global comnfiguration object + Config* conf; + // presentation timer + QBasicTimer pres_timer; + // Main layout + QVBoxLayout* layout; + TimeIndicator* timebar; + Ui::MainWindow *ui; + + void loadUi(); + void readSlidelist(char* path); + void keyPressEvent(QKeyEvent* event); + // to get arrow keys + bool eventFilter(QObject *obj, QEvent *event); + + //called by pres_timer + void timerEvent(QTimerEvent *event); + + // check whether a string is an integer + bool check_int(const char* string); +}; + + +class SecondaryWindow : public pdfWindow +{ + Q_OBJECT + + public: + // constructor + explicit SecondaryWindow(QWidget* parent = 0); + // destructor + ~SecondaryWindow(); + + private: + Ui::SecondaryWindow *ui; + void loadUi(); +}; + +// time progress bar +class TimeIndicator : public QProgressBar +{ + Q_OBJECT + public: + // constructor + explicit TimeIndicator(QWidget* parent = 0); + // destructore + ~TimeIndicator(); + void setTime(int time,int maxtime); +}; + +#endif // MAINWINDOW_H diff --git a/src/mainwindow.ui b/src/mainwindow.ui new file mode 100644 index 0000000..fa53891 --- /dev/null +++ b/src/mainwindow.ui @@ -0,0 +1,40 @@ +<?xml version="1.0" encoding="UTF-8"?> + +<!-- +Copyright 2015 Ian Jauslin + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +--> + +<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>pdfPresentation</string> + </property> + <widget class="QWidget" name="centralWidget"> + </widget> + <!-- <widget class="QStatusBar" name="statusBar"/> --> + </widget> + <layoutdefault spacing="0" margin="0"/> + <resources/> + <connections/> +</ui> diff --git a/src/pdfPresentation2.pro b/src/pdfPresentation2.pro new file mode 100644 index 0000000..2d5522f --- /dev/null +++ b/src/pdfPresentation2.pro @@ -0,0 +1,34 @@ +## Copyright 2015 Ian Jauslin +## +## Licensed under the Apache License, Version 2.0 (the "License"); +## you may not use this file except in compliance with the License. +## You may obtain a copy of the License at +## +## http://www.apache.org/licenses/LICENSE-2.0 +## +## Unless required by applicable law or agreed to in writing, software +## distributed under the License is distributed on an "AS IS" BASIS, +## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +## See the License for the specific language governing permissions and +## limitations under the License. + +QT += core gui + +greaterThan(QT_MAJOR_VERSION, 4): QT += widgets + +TARGET = build/pdfPresentation +TEMPLATE = app + +SOURCES += main.cpp\ + mainwindow.cpp\ + pdfWindow.cpp\ + config.cpp + +HEADERS += mainwindow.h\ + pdfWindow.h\ + config.h + +FORMS += mainwindow.ui\ + secondarywindow.ui + +LIBS += -lpoppler-qt4 diff --git a/src/pdfWindow.cpp b/src/pdfWindow.cpp new file mode 100644 index 0000000..e4ca3e4 --- /dev/null +++ b/src/pdfWindow.cpp @@ -0,0 +1,139 @@ +/* +Copyright 2015 Ian Jauslin + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +#include "pdfWindow.h" + +// constructor +pdfWindow::pdfWindow(QWidget *parent) : + QMainWindow(parent) +{ + // set defaults + fullscreen=0; + curpage=0; + totalpages=0; + verticalOffset=0; + document=NULL; + + //scene to draw the view + pdfViewScene=new QGraphicsScene; + pdfView=new QGraphicsView(pdfViewScene); +} + +// set PDF document +void pdfWindow::setDoc(char* file){ + if(document){delete document;} + doc=file; + + QString filename=file; + document = Poppler::Document::load(filename); + if(document){ + // display options + document->setRenderHint(Poppler::Document::Antialiasing,true); + document->setRenderHint(Poppler::Document::TextAntialiasing,true); + + curpage=0; + totalpages=document->numPages(); + this->updatePDF(); + } +} + +void pdfWindow::gotoPage(int page){ + if(page<totalpages && page>=0){ + curpage=page; + this->updatePDF(); + } +} +void pdfWindow::nextPage(){ + if(curpage<totalpages-1){ + curpage++; + this->updatePDF(); + } +} +void pdfWindow::previousPage(){ + if(curpage>0){ + curpage--; + this->updatePDF(); + } +} + +// toggle fullscreen +void pdfWindow::fullscreenPDF(){ + if(!fullscreen){ + fullscreen=1; + this->showFullScreen(); + } + else{ + fullscreen=0; + this->showNormal(); + } +} + +// draw (or redraw) PDF +void pdfWindow::updatePDF(){ + // current page + Poppler::Page* pdfPage = document->page(curpage); + if(!pdfPage){ + std::cout << "Error: could not load page " << curpage << '\n'; + return; + } + + // total size available + QSize windowsize=this->size(); + // verticalOffset to allow timebar + QSize viewSize(windowsize.width()+2,windowsize.height()+2-verticalOffset); + pdfView->setGeometry(-1,-1,viewSize.width(),viewSize.height()); + + // page size in points (1/72 inch) + QSize pageSize=pdfPage->pageSize(); + // aspect ratio + double aspect=double(pageSize.width())/double(pageSize.height()); + // an image to display the page + QImage image; + // keep aspect ratop + if(viewSize.width()<=aspect*viewSize.height()){ + // render PDF page with appropriate resolution (pix/inch) + image = pdfPage->renderToImage(72*viewSize.width()/pageSize.width(),72*viewSize.width()/aspect/pageSize.height(),0,0,viewSize.width(),viewSize.width()/aspect); + } + else{ + // render PDF page with appropriate resolution (pix/inch) + image = pdfPage->renderToImage(72*viewSize.height()*aspect/pageSize.width(),72*viewSize.height()/pageSize.height(),0,0,viewSize.height()*aspect,viewSize.height()); + } + delete pdfPage; + + // update scene + delete pdfViewScene; + pdfViewScene=new QGraphicsScene; + pdfView->setScene(pdfViewScene); + pdfViewScene->setBackgroundBrush(Qt::black); + // draw image + pdfViewScene->addPixmap(QPixmap::fromImage(image)); +} + +// respond to resize +void pdfWindow::resizeEvent(QResizeEvent* event){ + if(document){ + this->updatePDF(); + } + + QMainWindow::resizeEvent(event); +} + +// destructor +pdfWindow::~pdfWindow(){ + if(document){delete document;} + delete pdfView; + delete pdfViewScene; +} diff --git a/src/pdfWindow.h b/src/pdfWindow.h new file mode 100644 index 0000000..e3415d3 --- /dev/null +++ b/src/pdfWindow.h @@ -0,0 +1,68 @@ +/* +Copyright 2015 Ian Jauslin + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +#ifndef PDFWINDOW_H +#define PDFWINDOW_H + +#include <QMainWindow> +#include <poppler/qt4/poppler-qt4.h> +#include <iostream> +#include <QGraphicsScene> +#include <QGraphicsView> +#include <QBoxLayout> + + +class pdfWindow : public QMainWindow +{ + Q_OBJECT + +public: + // PDF document path + char* doc; + // current page + int curpage; + int totalpages; + // is fullscreen ? + bool fullscreen; + // offset for pdfView + int verticalOffset; + + // constructor + explicit pdfWindow(QWidget *parent = 0); + void setDoc(char* file); + void gotoPage(int page); + void nextPage(); + void previousPage(); + // toggle fullscreen + void fullscreenPDF(); + // destructor + ~pdfWindow(); + + +protected: + // document + Poppler::Document* document; + // to draw the view + QGraphicsScene* pdfViewScene; + QGraphicsView* pdfView; + + // display PDF + void updatePDF(); + // respond to window resize + void resizeEvent(QResizeEvent* event); +}; + +#endif // PDFWINDOW_H diff --git a/src/secondarywindow.ui b/src/secondarywindow.ui new file mode 100644 index 0000000..25d7364 --- /dev/null +++ b/src/secondarywindow.ui @@ -0,0 +1,39 @@ +<?xml version="1.0" encoding="UTF-8"?> + +<!-- +Copyright 2015 Ian Jauslin + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +--> + +<ui version="4.0"> + <class>SecondaryWindow</class> + <widget class="QMainWindow" name="SecondaryWindow"> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>400</width> + <height>300</height> + </rect> + </property> + <property name="windowTitle"> + <string>pdfPresentation</string> + </property> + <widget class="QWidget" name="centralWidget"> + </widget> + </widget> + <layoutdefault spacing="6" margin="11"/> + <resources/> + <connections/> +</ui> |