#include "camera.h"
#include "ui_camera.h"
#include "videosettings.h"
#include "imagesettings.h"
#include <qmediaservice.h>
#include <qmediarecorder.h>
#include <qcamera.h>
#include <qcameraviewfinder.h>
#include <qmessagebox.h>
#include <qpalette.h>
#include <QtWidgets>
#if (defined(Q_WS_MAEMO_6)) && QT_VERSION >= 0x040700
#define HAVE_CAMERA_BUTTONS
#endif
Camera::Camera(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::Camera),
camera(0),
imageCapture(0),
mediaRecorder(0),
isCapturingImage(false),
applicationExiting(false)
{
ui->setupUi(this);
QByteArray cameraDevice;
QActionGroup *videoDevicesGroup = new QActionGroup(this);
videoDevicesGroup->setExclusive(true);
foreach(const QByteArray &deviceName, QCamera::availableDevices()) {
QString description = camera->deviceDescription(deviceName);
QAction *videoDeviceAction = new QAction(description, videoDevicesGroup);
videoDeviceAction->setCheckable(true);
videoDeviceAction->setData(QVariant(deviceName));
if (cameraDevice.isEmpty()) {
cameraDevice = deviceName;
videoDeviceAction->setChecked(true);
}
ui->menuDevices->addAction(videoDeviceAction);
}
connect(videoDevicesGroup, SIGNAL(triggered(QAction*)), this, SLOT(updateCameraDevice(QAction*)));
connect(ui->captureWidget, SIGNAL(currentChanged(int)), SLOT(updateCaptureMode()));
#ifdef HAVE_CAMERA_BUTTONS
ui->lockButton->hide();
#endif
setCamera(cameraDevice);
}
Camera::~Camera()
{
delete mediaRecorder;
delete imageCapture;
delete camera;
}
void Camera::setCamera(const QByteArray &cameraDevice)
{
delete imageCapture;
delete mediaRecorder;
delete camera;
if (cameraDevice.isEmpty())
camera = new QCamera;
else
camera = new QCamera(cameraDevice);
connect(camera, SIGNAL(stateChanged(QCamera::State)), this, SLOT(updateCameraState(QCamera::State)));
connect(camera, SIGNAL(error(QCamera::Error)), this, SLOT(displayCameraError()));
mediaRecorder = new QMediaRecorder(camera);
connect(mediaRecorder, SIGNAL(stateChanged(QMediaRecorder::State)), this, SLOT(updateRecorderState(QMediaRecorder::State)));
imageCapture = new QCameraImageCapture(camera);
connect(mediaRecorder, SIGNAL(durationChanged(qint64)), this, SLOT(updateRecordTime()));
connect(mediaRecorder, SIGNAL(error(QMediaRecorder::Error)), this, SLOT(displayRecorderError()));
mediaRecorder->setMetaData(QtMultimedia::MetaData::Title, QVariant(QLatin1String("Test Title")));
connect(ui->exposureCompensation, SIGNAL(valueChanged(int)), SLOT(setExposureCompensation(int)));
camera->setViewfinder(ui->viewfinder);
updateCameraState(camera->state());
updateLockStatus(camera->lockStatus(), QCamera::UserRequest);
updateRecorderState(mediaRecorder->state());
connect(imageCapture, SIGNAL(readyForCaptureChanged(bool)), this, SLOT(readyForCapture(bool)));
connect(imageCapture, SIGNAL(imageCaptured(int,QImage)), this, SLOT(processCapturedImage(int,QImage)));
connect(imageCapture, SIGNAL(imageSaved(int,QString)), this, SLOT(imageSaved(int,QString)));
connect(camera, SIGNAL(lockStatusChanged(QCamera::LockStatus, QCamera::LockChangeReason)),
this, SLOT(updateLockStatus(QCamera::LockStatus, QCamera::LockChangeReason)));
ui->captureWidget->setTabEnabled(0, (camera->isCaptureModeSupported(QCamera::CaptureStillImage)));
ui->captureWidget->setTabEnabled(1, (camera->isCaptureModeSupported(QCamera::CaptureVideo)));
updateCaptureMode();
camera->start();
}
void Camera::keyPressEvent(QKeyEvent * event)
{
if (event->isAutoRepeat())
return;
switch (event->key()) {
#if QT_VERSION >= 0x040700
case Qt::Key_CameraFocus:
displayViewfinder();
camera->searchAndLock();
event->accept();
break;
case Qt::Key_Camera:
if (camera->captureMode() == QCamera::CaptureStillImage) {
takeImage();
} else {
if (mediaRecorder->state() == QMediaRecorder::RecordingState)
stop();
else
record();
}
event->accept();
break;
#endif
default:
QMainWindow::keyPressEvent(event);
}
}
void Camera::keyReleaseEvent(QKeyEvent * event)
{
if (event->isAutoRepeat())
return;
switch (event->key()) {
#if QT_VERSION >= 0x040700
case Qt::Key_CameraFocus:
camera->unlock();
break;
#endif
default:
QMainWindow::keyReleaseEvent(event);
}
}
void Camera::updateRecordTime()
{
QString str = QString("Recorded %1 sec").arg(mediaRecorder->duration()/1000);
ui->statusbar->showMessage(str);
}
void Camera::processCapturedImage(int requestId, const QImage& img)
{
Q_UNUSED(requestId);
QImage scaledImage = img.scaled(ui->viewfinder->size(),
Qt::KeepAspectRatio,
Qt::SmoothTransformation);
ui->lastImagePreviewLabel->setPixmap(QPixmap::fromImage(scaledImage));
displayCapturedImage();
QTimer::singleShot(4000, this, SLOT(displayViewfinder()));
}
void Camera::configureCaptureSettings()
{
switch (camera->captureMode()) {
case QCamera::CaptureStillImage:
configureImageSettings();
break;
case QCamera::CaptureVideo:
configureVideoSettings();
break;
default:
break;
}
}
void Camera::configureVideoSettings()
{
VideoSettings settingsDialog(mediaRecorder);
settingsDialog.setAudioSettings(audioSettings);
settingsDialog.setVideoSettings(videoSettings);
settingsDialog.setFormat(videoContainerFormat);
if (settingsDialog.exec()) {
audioSettings = settingsDialog.audioSettings();
videoSettings = settingsDialog.videoSettings();
videoContainerFormat = settingsDialog.format();
mediaRecorder->setEncodingSettings(
audioSettings,
videoSettings,
videoContainerFormat);
}
}
void Camera::configureImageSettings()
{
ImageSettings settingsDialog(imageCapture);
settingsDialog.setImageSettings(imageSettings);
if (settingsDialog.exec()) {
imageSettings = settingsDialog.imageSettings();
imageCapture->setEncodingSettings(imageSettings);
}
}
void Camera::record()
{
mediaRecorder->record();
updateRecordTime();
}
void Camera::pause()
{
mediaRecorder->pause();
}
void Camera::stop()
{
mediaRecorder->stop();
}
void Camera::setMuted(bool muted)
{
mediaRecorder->setMuted(muted);
}
void Camera::toggleLock()
{
switch (camera->lockStatus()) {
case QCamera::Searching:
case QCamera::Locked:
camera->unlock();
break;
case QCamera::Unlocked:
camera->searchAndLock();
}
}
void Camera::updateLockStatus(QCamera::LockStatus status, QCamera::LockChangeReason reason)
{
QColor indicationColor = Qt::black;
switch (status) {
case QCamera::Searching:
indicationColor = Qt::yellow;
ui->statusbar->showMessage(tr("Focusing..."));
ui->lockButton->setText(tr("Focusing..."));
break;
case QCamera::Locked:
indicationColor = Qt::darkGreen;
ui->lockButton->setText(tr("Unlock"));
ui->statusbar->showMessage(tr("Focused"), 2000);
break;
case QCamera::Unlocked:
indicationColor = reason == QCamera::LockFailed ? Qt::red : Qt::black;
ui->lockButton->setText(tr("Focus"));
if (reason == QCamera::LockFailed)
ui->statusbar->showMessage(tr("Focus Failed"), 2000);
}
QPalette palette = ui->lockButton->palette();
palette.setColor(QPalette::ButtonText, indicationColor);
ui->lockButton->setPalette(palette);
}
void Camera::takeImage()
{
isCapturingImage = true;
imageCapture->capture();
}
void Camera::startCamera()
{
camera->start();
}
void Camera::stopCamera()
{
camera->stop();
}
void Camera::updateCaptureMode()
{
int tabIndex = ui->captureWidget->currentIndex();
QCamera::CaptureModes captureMode = tabIndex == 0 ? QCamera::CaptureStillImage : QCamera::CaptureVideo;
if (camera->isCaptureModeSupported(captureMode))
camera->setCaptureMode(captureMode);
}
void Camera::updateCameraState(QCamera::State state)
{
switch (state) {
case QCamera::ActiveState:
ui->actionStartCamera->setEnabled(false);
ui->actionStopCamera->setEnabled(true);
ui->captureWidget->setEnabled(true);
ui->actionSettings->setEnabled(true);
break;
case QCamera::UnloadedState:
case QCamera::LoadedState:
ui->actionStartCamera->setEnabled(true);
ui->actionStopCamera->setEnabled(false);
ui->captureWidget->setEnabled(false);
ui->actionSettings->setEnabled(false);
}
}
void Camera::updateRecorderState(QMediaRecorder::State state)
{
switch (state) {
case QMediaRecorder::StoppedState:
ui->recordButton->setEnabled(true);
ui->pauseButton->setEnabled(true);
ui->stopButton->setEnabled(false);
break;
case QMediaRecorder::PausedState:
ui->recordButton->setEnabled(true);
ui->pauseButton->setEnabled(false);
ui->stopButton->setEnabled(true);
break;
case QMediaRecorder::RecordingState:
ui->recordButton->setEnabled(false);
ui->pauseButton->setEnabled(true);
ui->stopButton->setEnabled(true);
break;
}
}
void Camera::setExposureCompensation(int index)
{
camera->exposure()->setExposureCompensation(index*0.5);
}
void Camera::displayRecorderError()
{
QMessageBox::warning(this, tr("Capture error"), mediaRecorder->errorString());
}
void Camera::displayCameraError()
{
QMessageBox::warning(this, tr("Camera error"), camera->errorString());
}
void Camera::updateCameraDevice(QAction *action)
{
setCamera(action->data().toByteArray());
}
void Camera::displayViewfinder()
{
ui->stackedWidget->setCurrentIndex(0);
}
void Camera::displayCapturedImage()
{
ui->stackedWidget->setCurrentIndex(1);
}
void Camera::readyForCapture(bool ready)
{
ui->takeImageButton->setEnabled(ready);
}
void Camera::imageSaved(int id, const QString &fileName)
{
Q_UNUSED(id);
Q_UNUSED(fileName);
isCapturingImage = false;
if (applicationExiting)
close();
}
void Camera::closeEvent(QCloseEvent *event)
{
if (isCapturingImage) {
setEnabled(false);
applicationExiting = true;
event->ignore();
} else {
event->accept();
}
}