1 /* ***** BEGIN LICENSE BLOCK *****
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
27 * ***** END LICENSE BLOCK ***** */
29 #include "mainwindow.h"
31 #include "sequenceReader.h"
32 #include "customSizeDialog.h"
37 MainWindow::MainWindow() : assistantClientStarted(false)
39 //central widget is the 'view'
41 view
->setFrameStyle(QFrame::NoFrame
);
42 setCentralWidget(view
);
43 setWindowTitle("ImageViewer");
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");
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
));
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();
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()
121 QStringList fileNames
= QFileDialog::getOpenFileNames(
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()
146 QString fileName
= QFileDialog::getExistingDirectory(
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());
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()))
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);
190 recentFileAct
[j
]->setVisible(false);
194 recentFileSeperatorAct
->setVisible(!recentFiles
.isEmpty());
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);
221 void MainWindow::createToolBar(void)
223 myToolBar
= new QToolBar("Navigation", this);
224 connect(myToolBar
, SIGNAL(actionTriggered(QAction
*)), this, SLOT(jumpToFrameRelative(QAction
*)));
227 QIcon
firstIcon(":icons/first.svg");
228 a
= myToolBar
->addAction(firstIcon
, tr("First Frame"), this, SLOT(jumpToFirstFrame()));
231 QIcon
back1000Icon(":icons/back1000.svg");
232 a
= myToolBar
->addAction(back1000Icon
, tr("Back 1000"));
235 QIcon
back100Icon(":icons/back100.svg");
236 a
= myToolBar
->addAction(back100Icon
, tr("Back 100"));
239 QIcon
back10Icon(":icons/back10.svg");
240 a
= myToolBar
->addAction(back10Icon
, tr("Back 10"));
243 QIcon
back1Icon(":icons/back1.svg");
244 a
= myToolBar
->addAction(back1Icon
, tr("Back 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"));
258 QIcon
fwd10Icon(":icons/fwd10.svg");
259 a
= myToolBar
->addAction(fwd10Icon
, tr("Forward 10"));
262 QIcon
fwd100Icon(":icons/fwd100.svg");
263 a
= myToolBar
->addAction(fwd100Icon
, tr("Forward 100"));
266 QIcon
fwd1000Icon(":icons/fwd1000.svg");
267 a
= myToolBar
->addAction(fwd1000Icon
, tr("Forward 1000"));
270 QIcon
lastIcon(":icons/last.svg");
271 a
= myToolBar
->addAction(lastIcon
, tr("Last Frame"), this, SLOT(jumpToLastFrame()));
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"
282 "(c) BBC Research & Development 2009\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)); \
298 connect(a, SIGNAL(triggered()), target, SLOT(fn())); \
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); \
305 a->setCheckable(checkable); \
306 a->setChecked(checked); \
307 group->addAction(a); \
308 menu->addAction(a); \
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();
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"));
331 QMenu
*imageMenu
= menuBar()->addMenu(tr("&Image"));
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
*)));
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
*)));
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();
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()));
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
);
464 void MainWindow::setZoom(QAction
*action
)
466 float zoom
= (float)(action
->data().toDouble());
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);
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()
531 setFullScreen(false);
534 void MainWindow::toggleToolBar()
536 if (myToolBar
->isVisible()) {
538 toggleToolBarAct
->setChecked(false);
542 toggleToolBarAct
->setChecked(true);
546 //full screen toggle worker
547 void MainWindow::setFullScreen(bool fullscreen
)
558 if (toggleToolBarAct
->isChecked())
564 //zoom in keypress handler
565 void MainWindow::zoomIn()
567 float newZoom
= view
->getZoom() * 2.0;
568 view
->setZoom(view
->getZoom() * 2.0);
572 //zoom out keypress handler
573 void MainWindow::zoomOut()
575 float newZoom
= view
->getZoom() / 2.0;
577 //prevent extreme zooming out
581 view
->setZoom(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
;
614 reader
.readFrame(dest
);
617 void MainWindow::jumpToFrameAbsolute()
619 int first
= reader
.getFirstFrameNum();
620 int last
= reader
.getLastFrameNum();
621 int n
= jumpToFrameSpin
->value();
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
641 imageDepthMenu
->setEnabled(true);
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
)
652 //for frames with a header, we can't select picture size or bit depth
653 imageFormatMenu
->setEnabled(false);
654 imageSizeMenu
->setEnabled(false);
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
,
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
);
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);
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);
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);
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);
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()
800 QRect rect
= settings
.value("geometry", QRect(200, 200, 400, 400)).toRect();
801 move(rect
.topLeft());
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();
844 void MainWindow::writeSettings(void)
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
);
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
)
877 void MainWindow::helpViewerClosed()
879 assistantClientStarted
= false;