Add facility to read frames in RGB & RGBA format
[imageviewer.git] / mainwindow.cpp
blob3d5c6a3eadeba06b155bb1cae5658bc082cd33cf
1 /* ***** BEGIN LICENSE BLOCK *****
3 * $Id$
5 * The MIT License
7 * Copyright (c) 2008 BBC Research
9 * Permission is hereby granted, free of charge, to any person obtaining a copy
10 * of this software and associated documentation files (the "Software"), to deal
11 * in the Software without restriction, including without limitation the rights
12 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13 * copies of the Software, and to permit persons to whom the Software is
14 * furnished to do so, subject to the following conditions:
16 * The above copyright notice and this permission notice shall be included in
17 * all copies or substantial portions of the Software.
19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
25 * THE SOFTWARE.
27 * ***** END LICENSE BLOCK ***** */
29 #include "mainwindow.h"
30 #include "view.h"
31 #include "sequenceReader.h"
32 #include "customSizeDialog.h"
34 #include <QtGui>
35 #include <QtGlobal>
37 MainWindow::MainWindow() : assistantClientStarted(false)
39 //central widget is the 'view'
40 view = new View();
41 view->setFrameStyle(QFrame::NoFrame);
42 setCentralWidget(view);
43 setWindowTitle("ImageViewer");
45 //set up menus etc
46 createActions();
47 createStatusBar();
48 createToolBar();
49 setStatusBar(myStatusBar);
50 addToolBar(Qt::TopToolBarArea, myToolBar);
51 assistantClientProcess = new QProcess(this);
53 //when a pixel is clicked on in the view, print info about it
54 connect(view, SIGNAL(pixelInfoMessage(const QString &, int)), myStatusBar, SLOT(showMessage(const QString &, int)));
56 //when the mouse wheel changes to zoom, update the menus and status bar
57 connect(view, SIGNAL(zoomChanged(float)), this, SLOT(viewImageZoomChanged(float)));
59 //each new frame that the sequence reader reads emits these signals
60 connect(&reader, SIGNAL(newFrame(const RawFrame*)), view, SLOT(showFrame(const RawFrame *)));
61 connect(&reader, SIGNAL(frameFileName(const QString &)), fileNameLabel, SLOT(setText(const QString &)));
62 connect(&reader, SIGNAL(frameFormat(const QString &)), fileFormatLabel, SLOT(setText(const QString &)));
63 connect(&reader, SIGNAL(frameSize(QSize &)), this, SLOT(processSize(QSize &)));
64 connect(&reader, SIGNAL(sequencePosition(const QString&, int, int, int, int)), this, SLOT(processSequencePosition(const QString&, int, int, int, int)));
65 connect(&reader, SIGNAL(frameHasHeader(bool)), this, SLOT(processHasHeader(bool)));
66 connect(&reader, SIGNAL(frameBitDepth(int)), this, SLOT(processBitDepth(int)));
68 //load the settings for this application
69 QCoreApplication::setOrganizationName("BBCResearch");
70 QCoreApplication::setOrganizationDomain("rd.bbc.co.uk");
71 QCoreApplication::setApplicationName("RawImageViewer");
72 readSettings();
74 //if there are any parameters, pass these to the view as filenames
75 if (qApp->arguments().count() > 1) {
76 QStringList fileNames = qApp->arguments();
77 fileNames.removeAt(0); //delete the name of the executable
78 reader.setFileNames(fileNames);
79 reader.readFrame(reader.getCurrentFrameNum());
83 //initialise the Qt assistant, pointing it to our help content
84 void MainWindow::initializeAssistant()
86 //set the path to the documentation files
87 QStringList arguments;
89 arguments << QLatin1String("-collectionFile") << QString(DOCDIR) + QString("imageviewer.qhc") << QLatin1String("-enableRemoteControl");
91 //launch the assistant
93 if (false == assistantClientStarted)
95 QString app = QLibraryInfo::location(QLibraryInfo::BinariesPath)
96 + QLatin1String("/assistant");
97 assistantClientProcess->start(app, arguments);
98 if (!assistantClientProcess->waitForStarted()) {
99 QMessageBox::critical(this, tr("Remote Control"),
100 tr("Could not start Qt Assistant from %1.").arg(app));
101 return;
103 connect(assistantClientProcess, SIGNAL(finished(int,QProcess::ExitStatus)),
104 this, SLOT(helpViewerClosed()));
108 //slot to open the assistant when requested from the help menu
109 void MainWindow::assistant()
111 initializeAssistant();
112 QByteArray ba;
113 ba.append("SetSource qthelp://bbcrd/imageviewer_v1.0/index.html\n");
114 assistantClientProcess->write(ba);
117 //open a sequence of files
118 void MainWindow::openSeq()
120 QSettings settings;
121 QStringList fileNames = QFileDialog::getOpenFileNames(
122 this,
123 tr("Open Files"),
124 settings.value("fileopen/directory").toString(),
125 tr("Raw YUV Images (*.v210 *.uy16 *.v216 *.yv12 *.i420 *.uyvy *.yuv *.16P4 *.16P2 *.16P0 *.8P2);;Portable Images (*.pgm *.ppm);;SGI Files (*.sgi);;Any Files(*)"));
127 if (fileNames.size() > 0) {
128 QFileInfo fi(fileNames.at(0));
129 settings.setValue("fileopen/directory", fi.absolutePath());
130 if (!fileNames.isEmpty()) {
131 recentFiles.removeAll(fileNames.at(0));
132 recentFiles.prepend(fileNames.at(0));
133 updateRecentFileActions();
135 reader.setFileNames(fileNames);
136 reader.readFrame(reader.getCurrentFrameNum());
142 //open a directory of files
143 void MainWindow::openDirectory()
145 QSettings settings;
146 QString fileName = QFileDialog::getExistingDirectory(
147 this,
148 tr("Open Directory of images"),
149 settings.value("fileopen/directory").toString(),
150 QFileDialog::ShowDirsOnly);
152 if (fileName.isEmpty() == false) {
153 QFileInfo fi(fileName);
154 settings.setValue("fileopen/directory", fi.absolutePath());
155 reader.setDirectoryOfFiles(fileName);
156 reader.readFrame(reader.getCurrentFrameNum());
160 //slot to handle selection of a recent file from the file menu
161 void MainWindow::openRecentFile()
163 QAction *action = qobject_cast<QAction *>(sender());
164 if (action) {
165 QStringList list = QStringList(action->data().toString());
166 recentFiles.removeAll(list.at(0));
167 recentFiles.prepend(list.at(0));
168 updateRecentFileActions();
169 reader.setFileNames(list);
170 reader.readFrame(reader.getCurrentFrameNum());
174 //populate file menu actions with recent file list
175 void MainWindow::updateRecentFileActions()
177 QMutableStringListIterator i(recentFiles);
178 while (i.hasNext()) {
179 if (!QFile::exists(i.next()))
180 i.remove();
183 for (int j = 0; j < MaxRecentFiles; ++j) {
184 if (j < recentFiles.count()) {
185 QString text = tr("&%1 %2") .arg(j + 1) .arg(recentFiles[j]);
186 recentFileAct[j]->setText(text);
187 recentFileAct[j]->setData(recentFiles[j]);
188 recentFileAct[j]->setVisible(true);
189 } else {
190 recentFileAct[j]->setVisible(false);
194 recentFileSeperatorAct->setVisible(!recentFiles.isEmpty());
197 //status bar
198 void MainWindow::createStatusBar(void)
200 myStatusBar = new QStatusBar;
202 fileFormatLabel = new QLabel("Source Format", this);
203 fileFormatLabel->setFrameStyle(QFrame::Panel | QFrame::Sunken);
205 fileSizeLabel = new QLabel("Image Size Label", this);
206 fileSizeLabel->setFrameStyle(QFrame::Panel | QFrame::Sunken);
208 fileZoomLabel = new QLabel("Image Zoom Label", this);
209 fileZoomLabel->setFrameStyle(QFrame::Panel | QFrame::Sunken);
211 fileNameLabel = new QLabel("Filename", this);
212 fileNameLabel->setFrameStyle(QFrame::Panel | QFrame::Sunken);
214 myStatusBar->insertPermanentWidget(0, fileFormatLabel, 0);
215 myStatusBar->insertPermanentWidget(1, fileSizeLabel, 0);
216 myStatusBar->insertPermanentWidget(2, fileZoomLabel, 0);
217 myStatusBar->insertPermanentWidget(3, fileNameLabel, 0);
220 //tool bar
221 void MainWindow::createToolBar(void)
223 myToolBar = new QToolBar("Navigation", this);
224 connect(myToolBar, SIGNAL(actionTriggered(QAction *)), this, SLOT(jumpToFrameRelative(QAction *)));
225 QAction *a;
227 QIcon firstIcon(":icons/first.svg");
228 a = myToolBar->addAction(firstIcon, tr("First Frame"), this, SLOT(jumpToFirstFrame()));
229 a->setData(0);
231 QIcon back1000Icon(":icons/back1000.svg");
232 a = myToolBar->addAction(back1000Icon, tr("Back 1000"));
233 a->setData(-1000);
235 QIcon back100Icon(":icons/back100.svg");
236 a = myToolBar->addAction(back100Icon, tr("Back 100"));
237 a->setData(-100);
239 QIcon back10Icon(":icons/back10.svg");
240 a = myToolBar->addAction(back10Icon, tr("Back 10"));
241 a->setData(-10);
243 QIcon back1Icon(":icons/back1.svg");
244 a = myToolBar->addAction(back1Icon, tr("Back 1"));
245 a->setData(-1);
247 jumpToFrameSpin = new QSpinBox(this);
248 jumpToFrameSpin->setMinimum(0);
249 jumpToFrameSpin->setMaximum(0);
250 jumpToFrameSpin->setMinimumWidth(100);
251 myToolBar->addWidget(jumpToFrameSpin);
252 connect(jumpToFrameSpin, SIGNAL(editingFinished()), this, SLOT(jumpToFrameAbsolute()));
254 QIcon fwd1Icon(":icons/fwd1.svg");
255 a = myToolBar->addAction(fwd1Icon, tr("Forward 1"));
256 a->setData(1);
258 QIcon fwd10Icon(":icons/fwd10.svg");
259 a = myToolBar->addAction(fwd10Icon, tr("Forward 10"));
260 a->setData(10);
262 QIcon fwd100Icon(":icons/fwd100.svg");
263 a = myToolBar->addAction(fwd100Icon, tr("Forward 100"));
264 a->setData(100);
266 QIcon fwd1000Icon(":icons/fwd1000.svg");
267 a = myToolBar->addAction(fwd1000Icon, tr("Forward 1000"));
268 a->setData(1000);
270 QIcon lastIcon(":icons/last.svg");
271 a = myToolBar->addAction(lastIcon, tr("Last Frame"), this, SLOT(jumpToLastFrame()));
272 a->setData(0);
275 //about box
276 void MainWindow::about()
278 QMessageBox::about(this, tr("Image Viewer"),
279 tr("Image Viewer for raw YCbCr and\n"
280 "PGM / PPM image formats\n"
281 "Version 1.3\n\n"
282 "(c) BBC Research & Development 2009\n"
283 " Jonathan Rosser\n"
284 " David Flynn\n\n"
285 "Win32 binaries: http://diracvideo.org/download/imageviewer\n"
286 "Source code: http://diracvideo.org/git/imageviewer.git"));
289 //generate actions for menus and keypress handlers
290 void MainWindow::createActions()
293 //add a keyboard only shortcut not appearing on a menu
294 #define ADD_SHORTCUT(str, key, target, fn) \
295 do { QAction *a = new QAction(str, this); \
296 a->setShortcut(tr(key)); \
297 addAction(a); \
298 connect(a, SIGNAL(triggered()), target, SLOT(fn())); \
299 } while(0);
301 //add an action to an actiongroup in a menu
302 #define ADD_MENUGROUPITEM(str, data, menu, group, checkable, checked) \
303 do { QAction *a = new QAction(str, this); \
304 a->setData(data); \
305 a->setCheckable(checkable); \
306 a->setChecked(checked); \
307 group->addAction(a); \
308 menu->addAction(a); \
309 } while(0);
311 /////////////
312 // FILE MENU
313 /////////////
314 QMenu *fileMenu = menuBar()->addMenu(tr("&File"));
315 fileMenu->addAction("Open...", this, SLOT(openSeq()), tr("Ctrl+O"));
316 fileMenu->addAction(QString("Open Dir..."), this, SLOT(openDirectory()));
317 fileMenu->addSeparator();
319 //recent files
320 for (int i = 0; i < MaxRecentFiles; ++i) {
321 recentFileAct[i] = fileMenu->addAction("", this, SLOT(openRecentFile()));
322 recentFileAct[i]->setVisible(false);
324 recentFileSeperatorAct = fileMenu->addSeparator();
326 fileMenu->addAction("E&xit", this, SLOT(close()), tr("Ctrl+Q"));
328 /////////////
329 // IMAGE MENU
330 /////////////
331 QMenu *imageMenu = menuBar()->addMenu(tr("&Image"));
333 //Image Format
334 imageFormatMenu = imageMenu->addMenu(tr("YCbCr Image Format"));
335 imageFormatGroup = new QActionGroup(this);
336 ADD_MENUGROUPITEM("Auto", SequenceReader::type_auto, imageFormatMenu, imageFormatGroup, true, false);
337 ADD_MENUGROUPITEM("I420", SequenceReader::type_i420, imageFormatMenu, imageFormatGroup, true, false);
338 ADD_MENUGROUPITEM("YV12", SequenceReader::type_yv12, imageFormatMenu, imageFormatGroup, true, false);
339 ADD_MENUGROUPITEM("UYVY", SequenceReader::type_uyvy, imageFormatMenu, imageFormatGroup, true, false);
340 ADD_MENUGROUPITEM("V210", SequenceReader::type_v210, imageFormatMenu, imageFormatGroup, true, false);
341 ADD_MENUGROUPITEM("V216", SequenceReader::type_v216, imageFormatMenu, imageFormatGroup, true, false);
342 ADD_MENUGROUPITEM("UY16", SequenceReader::type_uy16, imageFormatMenu, imageFormatGroup, true, false);
343 ADD_MENUGROUPITEM("YY16", SequenceReader::type_yy16, imageFormatMenu, imageFormatGroup, true, false);
344 ADD_MENUGROUPITEM("YYY8", SequenceReader::type_yyy8, imageFormatMenu, imageFormatGroup, true, false);
345 ADD_MENUGROUPITEM("16P4", SequenceReader::type_16P4, imageFormatMenu, imageFormatGroup, true, false);
346 ADD_MENUGROUPITEM("16P2", SequenceReader::type_16P2, imageFormatMenu, imageFormatGroup, true, false);
347 ADD_MENUGROUPITEM("16P0", SequenceReader::type_16P0, imageFormatMenu, imageFormatGroup, true, false);
348 ADD_MENUGROUPITEM("8P2", SequenceReader::type_8P2, imageFormatMenu, imageFormatGroup, true, false);
349 connect(imageFormatGroup, SIGNAL(triggered(QAction *)), this, SLOT(setYUVimageFormat(QAction *)));
351 //Image Size
352 imageSizeMenu = imageMenu->addMenu(tr("YCbCr Image Size"));
353 imageSizeGroup = new QActionGroup(this);
354 ADD_MENUGROUPITEM("QSIF : 176x120", SequenceReader::SizeQSIF, imageSizeMenu, imageSizeGroup, true, false);
355 ADD_MENUGROUPITEM("QCIF : 176x144", SequenceReader::SizeQCIF, imageSizeMenu, imageSizeGroup, true, false);
356 ADD_MENUGROUPITEM("SIF : 352x240", SequenceReader::SizeSIF, imageSizeMenu, imageSizeGroup, true, false);
357 ADD_MENUGROUPITEM("CIF : 352x288", SequenceReader::SizeCIF, imageSizeMenu, imageSizeGroup, true, false);
358 ADD_MENUGROUPITEM("4SIF : 704x480", SequenceReader::Size4SIF, imageSizeMenu, imageSizeGroup, true, false);
359 ADD_MENUGROUPITEM("4SIF : 704x576", SequenceReader::Size4CIF, imageSizeMenu, imageSizeGroup, true, false);
360 ADD_MENUGROUPITEM("SD480 : 720x480", SequenceReader::SizeSD480, imageSizeMenu, imageSizeGroup, true, false);
361 ADD_MENUGROUPITEM("SD576 : 720x576", SequenceReader::SizeSD576, imageSizeMenu, imageSizeGroup, true, false);
362 ADD_MENUGROUPITEM("HD720 : 1280x720", SequenceReader::SizeHD720, imageSizeMenu, imageSizeGroup, true, false);
363 ADD_MENUGROUPITEM("HD1080 : 1920x1080", SequenceReader::SizeHD1080, imageSizeMenu, imageSizeGroup, true, false);
364 ADD_MENUGROUPITEM("2K : 2048x1556", SequenceReader::Size2K, imageSizeMenu, imageSizeGroup, true, false);
365 ADD_MENUGROUPITEM("4K : 4096x3112", SequenceReader::Size4K, imageSizeMenu, imageSizeGroup, true, false);
366 ADD_MENUGROUPITEM("SHV : 7680x4320", SequenceReader::SizeSHV, imageSizeMenu, imageSizeGroup, true, false);
367 imageSizeMenu->addSeparator();
368 connect(imageSizeGroup, SIGNAL(triggered(QAction *)), this, SLOT(setPresetSize(QAction *)));
370 imageSizeSetCustomAct = imageSizeMenu->addAction("Custom...", this, SLOT(setCustomSize(bool)));
371 imageSizeSetCustomAct->setCheckable(true);
373 //Image bit depth menu
374 imageDepthMenu = imageMenu->addMenu(tr("Image Bit Depth"));
375 imageDepthGroup = new QActionGroup(this);
376 ADD_MENUGROUPITEM("8 Bit", 8, imageDepthMenu, imageDepthGroup, true, false);
377 ADD_MENUGROUPITEM("10 Bit", 10, imageDepthMenu, imageDepthGroup, true, true);
378 ADD_MENUGROUPITEM("12 Bit", 12, imageDepthMenu, imageDepthGroup, true, false);
379 ADD_MENUGROUPITEM("14 Bit", 14, imageDepthMenu, imageDepthGroup, true, false);
380 ADD_MENUGROUPITEM("16 Bit", 16, imageDepthMenu, imageDepthGroup, true, false);
381 connect(imageDepthGroup, SIGNAL(triggered(QAction *)), this, SLOT(setYUVimageDepth(QAction *)));
383 ////////////
384 // VIEW MENU
385 ////////////
386 QMenu *viewMenu = menuBar()->addMenu(tr("&View"));
388 //YUV display mode action group
389 YUVModeGroup = new QActionGroup(this);
390 ADD_MENUGROUPITEM("YUV in colour", View::YUVdisplayColour, viewMenu, YUVModeGroup, true, true);
391 ADD_MENUGROUPITEM("YUV Y-Only", View::YUVdisplayYOnly, viewMenu, YUVModeGroup, true, false);
392 ADD_MENUGROUPITEM("YUV in planar", View::YUVdisplayPlanar, viewMenu, YUVModeGroup, true, false);
393 connect(YUVModeGroup, SIGNAL(triggered(QAction *)), this, SLOT(setYUVdisplayMode(QAction *)));
394 viewMenu->addSeparator();
396 //rgb scaling action group
397 rgbScalingGroup = new QActionGroup(this);
398 ADD_MENUGROUPITEM("Scaled YCbCr to RGB", true, viewMenu, rgbScalingGroup, true, true);
399 ADD_MENUGROUPITEM("Unscaled YCbCr to RGB", false, viewMenu, rgbScalingGroup, true, false);
400 connect(rgbScalingGroup, SIGNAL(triggered(QAction *)), this, SLOT(setRGBScaling(QAction *)));
401 viewMenu->addSeparator();
403 //colour matrix group
404 matrixGroup = new QActionGroup(this);
405 ADD_MENUGROUPITEM("Use HDTV Matrix", ColourSpace::HDTVtoRGB, viewMenu, matrixGroup, true, true);
406 ADD_MENUGROUPITEM("Use SDTV Matrix", ColourSpace::SDTVtoRGB, viewMenu, matrixGroup, true, false);
407 connect(matrixGroup, SIGNAL(triggered(QAction *)), this, SLOT(setColourMatrix(QAction *)));
408 viewMenu->addSeparator();
410 //Zoom levels
411 zoomGroup = new QActionGroup(this);
412 ADD_MENUGROUPITEM("Zoom 25%", 0.25f, viewMenu, zoomGroup, true, false);
413 ADD_MENUGROUPITEM("Zoom 50%", 0.50f, viewMenu, zoomGroup, true, false);
414 ADD_MENUGROUPITEM("Zoom 100%", 1.0f, viewMenu, zoomGroup, true, true);
415 ADD_MENUGROUPITEM("Zoom 200%", 2.0f, viewMenu, zoomGroup, true, false);
416 ADD_MENUGROUPITEM("Zoom 400%", 4.0f, viewMenu, zoomGroup, true, false);
417 ADD_MENUGROUPITEM("Zoom 800%", 8.0f, viewMenu, zoomGroup, true, false);
418 connect(zoomGroup, SIGNAL(triggered(QAction *)), this, SLOT(setZoom(QAction *)));
419 viewMenu->addSeparator();
421 //scroll bar behaviour
422 scrollBarGroup = new QActionGroup(this);
423 ADD_MENUGROUPITEM("Scroll Bars on", Qt::ScrollBarAlwaysOn, viewMenu, scrollBarGroup, true, true);
424 ADD_MENUGROUPITEM("Scroll Bars as required", Qt::ScrollBarAsNeeded, viewMenu, scrollBarGroup, true, false);
425 ADD_MENUGROUPITEM("Scroll Bars off", Qt::ScrollBarAlwaysOff, viewMenu, scrollBarGroup, true, false);
426 connect(scrollBarGroup, SIGNAL(triggered(QAction *)), this, SLOT(setScrollBar(QAction *)));
427 viewMenu->addSeparator();
429 toggleToolBarAct = new QAction("Show ToolBar", this);
430 toggleToolBarAct->setShortcut(tr("Ctrl+T"));
431 toggleToolBarAct->setCheckable(true);
432 toggleToolBarAct->setChecked(true);
433 addAction(toggleToolBarAct);
434 connect(toggleToolBarAct, SIGNAL(triggered()), this, SLOT(toggleToolBar()));
436 ////////////
437 // HELP MENU
438 ////////////
439 QMenu *helpMenu = menuBar()->addMenu(tr("&Help"));
441 helpMenu->addAction("Help Contents", this, SLOT(assistant()), tr("F1"));
442 helpMenu->addAction("&About", this, SLOT(about()));
443 helpMenu->addAction("About &Qt", qApp, SLOT(aboutQt()));
445 //keyboard shortcuts that do not appear on menus
446 ADD_SHORTCUT("View full screen", "Ctrl+F", this, toggleFullScreen);
447 ADD_SHORTCUT("Escape full screen", "Escape", this, escapeFullScreen);
448 ADD_SHORTCUT("Zoom In", "+", this, zoomIn);
449 ADD_SHORTCUT("Zoom Out", "-", this, zoomOut);
450 ADD_SHORTCUT("Next Frame", " ", &reader, nextInSequence);
451 ADD_SHORTCUT("Next Frame", "n", &reader, nextInSequence);
452 ADD_SHORTCUT("Prev Frame", "p", &reader, prevInSequence);
455 void MainWindow::setScrollBar(QAction *action)
457 Qt::ScrollBarPolicy policy = (Qt::ScrollBarPolicy)action->data().toInt();
459 view->setHorizontalScrollBarPolicy(policy);
460 view->setVerticalScrollBarPolicy(policy);
463 //zoom menu slot
464 void MainWindow::setZoom(QAction *action)
466 float zoom = (float)(action->data().toDouble());
467 view->setZoom(zoom);
470 //rgb scaling menu slot
471 void MainWindow::setRGBScaling(QAction *action)
473 view->setYUVRGBScaling(action->data().toBool());
476 //display mode menu slot
477 void MainWindow::setYUVdisplayMode(QAction *action)
479 view->setYUVdisplayMode((View::YUVdisplayMode)action->data().toInt());
482 //colour matrix menu slot
483 void MainWindow::setColourMatrix(QAction *action)
485 view->setYUVColourMatrix((ColourSpace::MatrixType)action->data().toInt());
488 void MainWindow::setYUVimageFormat(QAction *action)
490 reader.setRawFormat((SequenceReader::RawType)action->data().toInt());
493 void MainWindow::setPresetSize(QAction *action)
495 SequenceReader::ImageSizes size = (SequenceReader::ImageSizes)action->data().toInt();
496 reader.setSizeType(size);
497 updateRawImageSize(size);
500 //image size menu slot
501 void MainWindow::setCustomSize(bool)
503 CustomSizeDialog sizeDialog("Custom Image Size",
504 reader.getCustomWidth(),
505 reader.getCustomHeight(), this);
506 sizeDialog.exec();
507 if (sizeDialog.result() == QDialog::Accepted) {
509 reader.setCustomSize(sizeDialog.getWidth(), sizeDialog.getHeight());
510 reader.setSizeType(SequenceReader::SizeCustom);
511 updateRawImageSize(SequenceReader::SizeCustom);
512 imageSizeSetCustomAct->setText(QString("Custom... [%1x%2]") .arg(reader.getCustomWidth()) .arg(reader.getCustomHeight()));
516 //image depth menu slot
517 void MainWindow::setYUVimageDepth(QAction *action)
519 view->setYUVbitDepth(action->data().toInt());
522 //slot to receive full screen toggle command
523 void MainWindow::toggleFullScreen()
525 setFullScreen(!isFullScreen());
528 void MainWindow::escapeFullScreen()
530 if (isFullScreen())
531 setFullScreen(false);
534 void MainWindow::toggleToolBar()
536 if (myToolBar->isVisible()) {
537 myToolBar->hide();
538 toggleToolBarAct->setChecked(false);
540 else {
541 myToolBar->show();
542 toggleToolBarAct->setChecked(true);
546 //full screen toggle worker
547 void MainWindow::setFullScreen(bool fullscreen)
549 if (fullscreen) {
550 menuBar()->hide();
551 statusBar()->hide();
552 myToolBar->hide();
553 showFullScreen();
555 else {
556 menuBar()->show();
557 statusBar()->show();
558 if (toggleToolBarAct->isChecked())
559 myToolBar->show();
560 showNormal();
564 //zoom in keypress handler
565 void MainWindow::zoomIn()
567 float newZoom = view->getZoom() * 2.0;
568 view->setZoom(view->getZoom() * 2.0);
569 updateZoom(newZoom);
572 //zoom out keypress handler
573 void MainWindow::zoomOut()
575 float newZoom = view->getZoom() / 2.0;
577 //prevent extreme zooming out
578 if (newZoom < 0.01)
579 return;
581 view->setZoom(newZoom);
582 updateZoom(newZoom);
585 //------------------------------------------------------------------------------
586 // slots receiving signals from the toolbar
588 void MainWindow::jumpToFirstFrame()
590 int first = reader.getFirstFrameNum();
591 reader.readFrame(first);
594 void MainWindow::jumpToLastFrame()
596 int last = reader.getLastFrameNum();
597 reader.readFrame(last);
600 void MainWindow::jumpToFrameRelative(QAction *a)
602 int delta = a->data().toInt();
603 int first = reader.getFirstFrameNum();
604 int last = reader.getLastFrameNum();
605 int current = reader.getCurrentFrameNum();
606 int dest = current + delta;
608 if (dest < first)
609 dest = first;
611 if (dest > last)
612 dest = last;
614 reader.readFrame(dest);
617 void MainWindow::jumpToFrameAbsolute()
619 int first = reader.getFirstFrameNum();
620 int last = reader.getLastFrameNum();
621 int n = jumpToFrameSpin->value();
623 if (n < first)
624 n = first;
626 if (n > last)
627 n = last;
629 reader.readFrame(n);
632 //------------------------------------------------------------------------------
633 // slots receiving signals from the sequence reader
635 //sequence reader indicates the bit depth of each frame
636 void MainWindow::processBitDepth(int depth)
638 //enable the image depth menu when the bit depth of the image is unknown
639 //at the moment, this should only be uy16 format
640 if (depth == 0)
641 imageDepthMenu->setEnabled(true);
642 else
643 imageDepthMenu->setEnabled(false);
645 view->setYUVnativeBitDepth(depth);
648 //sequence reader indicates if each new frame has a header or not
649 void MainWindow::processHasHeader(bool header)
651 if (header) {
652 //for frames with a header, we can't select picture size or bit depth
653 imageFormatMenu->setEnabled(false);
654 imageSizeMenu->setEnabled(false);
656 else {
657 //for frames without a header we must set picture size and bit depth by hand
658 imageFormatMenu->setEnabled(true);
659 imageSizeMenu->setEnabled(true);
663 //sequence reader indicates the size of each frame
664 void MainWindow::processSize(QSize &newSize)
666 QString sizeText = QString("Size %1x%2") .arg(newSize.width()) .arg(newSize.height());
667 fileSizeLabel->setText(sizeText);
670 //sequence reader provides new information each time the sequence position changes
671 void MainWindow::processSequencePosition(const QString &filename,
672 int frameInFile,
673 int firstFrame,
674 int currentFrame,
675 int lastFrame)
677 QString positionText = QString("File %1[%2] Frame:%3 [%4-%5]") .arg(filename) .arg(frameInFile) .arg(currentFrame) .arg(firstFrame) .arg(lastFrame);
678 fileNameLabel->setText(positionText);
680 jumpToFrameSpin->setMinimum(firstFrame);
681 jumpToFrameSpin->setMaximum(lastFrame);
682 jumpToFrameSpin->setValue(currentFrame);
685 //view generates signals each time the mouse wheel changes the zoom level
686 void MainWindow::viewImageZoomChanged(float newZoom)
688 QString zoomText = QString("Zoom %1") .arg(newZoom);
689 fileZoomLabel->setText(zoomText);
690 updateZoom(newZoom);
693 //------------------------------------------------------------------------------
694 // Helper functions to keep the menu entries up to date
696 //select the correct menu entry for this RGB scaling
697 void MainWindow::updateRgbScaling(bool scaled)
699 QList<QAction *> actions = rgbScalingGroup->actions();
700 for (int i=0; i<actions.count(); i++) {
702 if (actions.at(i)->data().toBool() == scaled)
703 actions.at(i)->setChecked(true);
707 //select the correct menu entry for this display mode
708 void MainWindow::updateDisplayMode(View::YUVdisplayMode mode)
710 QList<QAction *> actions = YUVModeGroup->actions();
711 for (int i=0; i<actions.count(); i++) {
713 if ((View::YUVdisplayMode)actions.at(i)->data().toInt() == mode)
714 actions.at(i)->setChecked(true);
718 //select the correct menu entry for this colour matrix
719 void MainWindow::updateColourMatrix(ColourSpace::MatrixType matrix)
721 QList<QAction *> actions = matrixGroup->actions();
722 for (int i=0; i<actions.count(); i++) {
723 if ((ColourSpace::MatrixType)actions.at(i)->data().toInt() == matrix)
724 actions.at(i)->setChecked(true);
728 //select the appropriate image size menu for this size
729 void MainWindow::updateRawImageSize(SequenceReader::ImageSizes size)
731 if(size == SequenceReader::SizeCustom) {
733 if(imageSizeGroup->checkedAction())
734 imageSizeGroup->checkedAction()->setChecked(false);
736 imageSizeSetCustomAct->setChecked(true);
737 return;
738 } else {
739 imageSizeSetCustomAct->setChecked(false);
742 QList<QAction *> actions = imageSizeGroup->actions();
743 for (int i=0; i<actions.count(); i++) {
744 if ((SequenceReader::ImageSizes)actions.at(i)->data().toInt() == size) {
745 actions.at(i)->setChecked(true);
746 } else {
747 actions.at(i)->setChecked(false);
752 //select the appropriate bit depth menu for this depth
753 void MainWindow::updateYUVFormat(int format)
755 QList<QAction *> actions = imageFormatGroup->actions();
756 for (int i=0; i<actions.count(); i++) {
757 if (actions.at(i)->data().toInt() == format)
758 actions.at(i)->setChecked(true);
762 //select the appropriate bit depth menu for this depth
763 void MainWindow::updateYUVbitDepth(int depth)
765 QList<QAction *> actions = imageDepthGroup->actions();
766 for (int i=0; i<actions.count(); i++) {
767 if (actions.at(i)->data().toInt() == depth)
768 actions.at(i)->setChecked(true);
772 //select the appropriate zoom menu entry for this zoom level
773 void MainWindow::updateZoom(double zoom)
775 QList<QAction *> actions = zoomGroup->actions();
776 for (int i=0; i<actions.count(); i++) {
777 if (actions.at(i)->data().toDouble() == zoom)
778 actions.at(i)->setChecked(true);
779 else
780 actions.at(i)->setChecked(false);
784 //select the appropriate scrollbar policy menu entry
785 void MainWindow::updateScrollBarPolicy(Qt::ScrollBarPolicy policy)
787 QList<QAction *> actions = scrollBarGroup->actions();
788 for (int i=0; i<actions.count(); i++) {
789 if ((Qt::ScrollBarPolicy)actions.at(i)->data().toInt() == policy)
790 actions.at(i)->setChecked(true);
791 else
792 actions.at(i)->setChecked(false);
796 //read settings, update the menus to suit and apply to the view object where necessary
797 void MainWindow::readSettings()
799 QSettings settings;
800 QRect rect = settings.value("geometry", QRect(200, 200, 400, 400)).toRect();
801 move(rect.topLeft());
802 resize(rect.size());
804 recentFiles = settings.value("recentFiles").toStringList();
805 updateRecentFileActions();
807 bool scaled = settings.value("rgbscaling", true).toBool();
808 updateRgbScaling(scaled);
809 view->setYUVRGBScaling(scaled);
811 View::YUVdisplayMode displayMode = (View::YUVdisplayMode)settings.value("displaymode", View::YUVdisplayColour).toInt();
812 updateDisplayMode(displayMode);
813 view->setYUVdisplayMode(displayMode);
815 ColourSpace::MatrixType matrixType = (ColourSpace::MatrixType)settings.value("colourmatrix", ColourSpace::HDTVtoRGB).toInt();
816 updateColourMatrix(matrixType);
817 view->setYUVColourMatrix(matrixType);
819 SequenceReader::RawType rawType = (SequenceReader::RawType)settings.value("rawimageformat", SequenceReader::type_auto).toInt();
820 updateYUVFormat(rawType);
821 reader.setRawFormat(rawType);
823 reader.setCustomSize(settings.value("customwidth", 640).toInt(), settings.value("customheight", 480).toInt());
824 SequenceReader::ImageSizes imageSize = (SequenceReader::ImageSizes)settings.value("rawimagesize", SequenceReader::SizeHD1080).toInt();
825 updateRawImageSize(imageSize);
826 reader.setSizeType(imageSize);
828 imageSizeSetCustomAct->setText(QString("Custom... [%1x%2]") .arg(reader.getCustomWidth()) .arg(reader.getCustomHeight()));
830 Qt::ScrollBarPolicy scrollBarPolicy = (Qt::ScrollBarPolicy)settings.value("scrollbarpolicy", Qt::ScrollBarAlwaysOn).toInt();
831 view->setHorizontalScrollBarPolicy(scrollBarPolicy);
832 view->setVerticalScrollBarPolicy(scrollBarPolicy);
833 updateScrollBarPolicy(scrollBarPolicy);
835 int bitDepth = settings.value("rawimagedepth", 10).toInt();
836 updateYUVbitDepth(bitDepth);
837 view->setYUVbitDepth(bitDepth);
839 float zoom = (float)settings.value("zoom", 1.0).toDouble();
840 updateZoom(zoom);
841 view->setZoom(zoom);
844 void MainWindow::writeSettings(void)
846 QSettings settings;
848 //user selections from the menu
849 settings.setValue("colourmatrix", matrixGroup->checkedAction()->data().toInt());
851 settings.setValue("customwidth", reader.getCustomWidth());
852 settings.setValue("customheight", reader.getCustomHeight());
854 if(imageSizeSetCustomAct->isChecked())
855 settings.setValue("rawimagesize", SequenceReader::SizeCustom);
856 else
857 settings.setValue("rawimagesize", imageSizeGroup->checkedAction()->data().toInt());
859 settings.setValue("rawimagedepth", imageDepthGroup->checkedAction()->data().toInt());
860 settings.setValue("rawimageformat", imageFormatGroup->checkedAction()->data().toInt());
861 settings.setValue("rgbscaling", rgbScalingGroup->checkedAction()->data().toBool());
862 settings.setValue("displaymode", YUVModeGroup->checkedAction()->data().toInt());
863 settings.setValue("zoom", zoomGroup->checkedAction()->data().toDouble());
864 settings.setValue("scrollbarpolicy", scrollBarGroup->checkedAction()->data().toInt());
866 //information about the window
867 settings.setValue("geometry", geometry());
868 settings.setValue("recentfiles", recentFiles);
871 void MainWindow::closeEvent(QCloseEvent *event)
873 writeSettings();
874 event->accept();
877 void MainWindow::helpViewerClosed()
879 assistantClientStarted = false;