From b68e15a811359f8c7ab6f239cd5e8bf36e854f0e Mon Sep 17 00:00:00 2001 From: Ian Jauslin Date: Sun, 7 Jun 2015 15:28:16 +0000 Subject: Initial commit --- src/mainwindow.cpp | 413 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 413 insertions(+) create mode 100644 src/mainwindow.cpp (limited to 'src/mainwindow.cpp') 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(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(curpagecurpagegotoPage(curpage-1); + } + else{ + secondaryWindow->gotoPage(curpage); + } + } +} +// previous PDF page with offset for secondary screen +void MainWindow::previousPage(){ + if(!secondaryWindow || secondaryWindow->curpagepdfWindow::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 (pagepdfWindow::gotoPage(page+1); + secondaryWindow->gotoPage(page); + } + else{ + this->pdfWindow::gotoPage(totalpages); + secondaryWindow->gotoPage(totalpages); + } +} + +void MainWindow::nextSlide(){ + int i; + for(i=0;isecondaryWindow->curpage+1){ + this->gotoPage(slidelist.at(i)-1); + break; + } + } +} +void MainWindow::previousSlide(){ + int i; + int size=slidelist.size(); + for(i=0;icurpage+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(event); + this->keyPressEvent(keyEvent); + result = true; + }//if type() + + else if (event->type() == QEvent::KeyRelease) + { + keyEvent = dynamic_cast(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(){} -- cgit v1.2.3-54-g00ecf