diff options
| author | Ian Jauslin <ian.jauslin@roma1.infn.it> | 2015-06-07 15:28:16 +0000 | 
|---|---|---|
| committer | Ian Jauslin <ian.jauslin@roma1.infn.it> | 2015-06-07 15:28:16 +0000 | 
| commit | b68e15a811359f8c7ab6f239cd5e8bf36e854f0e (patch) | |
| tree | 36f1255651737aa942d50c6ef9be1219266a1404 /src | |
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> | 
