summaryrefslogtreecommitdiff
path: root/noncore
authorllornkcor <llornkcor>2006-07-09 18:56:40 (UTC)
committer llornkcor <llornkcor>2006-07-09 18:56:40 (UTC)
commit36dece4760b1ac1799929221b49eb3bee98c2367 (patch) (side-by-side diff)
treea45f66d2d90bd9fbbff8e8903cd1cb9323c39f6e /noncore
parent604065c6e662cb3894acf03abadafacc3ab52913 (diff)
downloadopie-36dece4760b1ac1799929221b49eb3bee98c2367.zip
opie-36dece4760b1ac1799929221b49eb3bee98c2367.tar.gz
opie-36dece4760b1ac1799929221b49eb3bee98c2367.tar.bz2
initial commit to add video4linux camera app from qtopia 2, needs more work
Diffstat (limited to 'noncore') (more/less context) (ignore whitespace changes)
-rw-r--r--noncore/multimedia/camera2/camera2.pro27
-rw-r--r--noncore/multimedia/camera2/camerabase.cpp93
-rw-r--r--noncore/multimedia/camera2/camerabase.h47
-rw-r--r--noncore/multimedia/camera2/camerabase.ui209
-rw-r--r--noncore/multimedia/camera2/camerasettings.cpp166
-rw-r--r--noncore/multimedia/camera2/camerasettings.h59
-rw-r--r--noncore/multimedia/camera2/camerasettings.ui433
-rw-r--r--noncore/multimedia/camera2/config.in7
-rw-r--r--noncore/multimedia/camera2/image.cpp239
-rw-r--r--noncore/multimedia/camera2/image.h53
-rw-r--r--noncore/multimedia/camera2/main.cpp44
-rw-r--r--noncore/multimedia/camera2/mainwindow.cpp763
-rw-r--r--noncore/multimedia/camera2/mainwindow.h132
-rw-r--r--noncore/multimedia/camera2/opie-camera2.control10
-rw-r--r--noncore/multimedia/camera2/thumbbutton.h50
-rw-r--r--noncore/multimedia/camera2/videocaptureview.cpp599
-rw-r--r--noncore/multimedia/camera2/videocaptureview.h82
17 files changed, 3013 insertions, 0 deletions
diff --git a/noncore/multimedia/camera2/camera2.pro b/noncore/multimedia/camera2/camera2.pro
new file mode 100644
index 0000000..b6e2826
--- a/dev/null
+++ b/noncore/multimedia/camera2/camera2.pro
@@ -0,0 +1,27 @@
+DESTDIR = $(OPIEDIR)/bin
+TEMPLATE = app
+CONFIG += qte warn_on quick_app
+INTERFACES=camerabase.ui camerasettings.ui
+HEADERS = mainwindow.h \
+ image.h \
+ thumbbutton.h \
+ videocaptureview.h
+SOURCES = mainwindow.cpp\
+ image.cpp \
+ videocaptureview.cpp \
+ main.cpp
+
+TARGET = camera2
+DEFINES += HAVE_VIDEO4LINUX
+
+LIBS += -lopiecore2 -lopieui2
+INCLUDEPATH += $(OPIEDIR)/include
+DEPENDPATH += $(OPIEDIR)/include
+contains(CONFIG,quick-app) {
+ DESTDIR = $(OPIEDIR)/bin
+ DEFINES += NOQUICKLAUNCH
+}
+
+
+include( $(OPIEDIR)/include.pro )
+
diff --git a/noncore/multimedia/camera2/camerabase.cpp b/noncore/multimedia/camera2/camerabase.cpp
new file mode 100644
index 0000000..cbb1ba9
--- a/dev/null
+++ b/noncore/multimedia/camera2/camerabase.cpp
@@ -0,0 +1,93 @@
+/****************************************************************************
+** Form implementation generated from reading ui file 'camerabase.ui'
+**
+** Created: Mon Jul 10 04:21:25 2006
+** by: The User Interface Compiler (uic)
+**
+** WARNING! All changes made in this file will be lost!
+****************************************************************************/
+#include "camerabase.h"
+
+#include <qframe.h>
+#include <qpushbutton.h>
+#include "thumbbutton.h"
+#include "videocaptureview.h"
+#include <qlayout.h>
+#include <qvariant.h>
+#include <qtooltip.h>
+#include <qwhatsthis.h>
+
+/*
+ * Constructs a CameraBase which is a child of 'parent', with the
+ * name 'name' and widget flags set to 'f'
+ */
+CameraBase::CameraBase( QWidget* parent, const char* name, WFlags fl )
+ : QWidget( parent, name, fl )
+{
+ if ( !name )
+ setName( "camera" );
+ resize( 311, 381 );
+ setCaption( tr( "Camera" ) );
+ cameraLayout = new QGridLayout( this );
+ cameraLayout->setSpacing( 0 );
+ cameraLayout->setMargin( 0 );
+
+ Frame3 = new QFrame( this, "Frame3" );
+ Frame3->setFrameShape( QFrame::Panel );
+ Frame3->setFrameShadow( QFrame::Sunken );
+ Frame3->setLineWidth( 4 );
+ Frame3->setMargin( 4 );
+ Frame3->setMidLineWidth( 3 );
+ Frame3Layout = new QVBoxLayout( Frame3 );
+ Frame3Layout->setSpacing( 6 );
+ Frame3Layout->setMargin( 4 );
+
+ videocaptureview = new VideoCaptureView( Frame3, "videocaptureview" );
+ videocaptureview->setSizePolicy( QSizePolicy( (QSizePolicy::SizeType)7, (QSizePolicy::SizeType)7, videocaptureview->sizePolicy().hasHeightForWidth() ) );
+ Frame3Layout->addWidget( videocaptureview );
+
+ cameraLayout->addMultiCellWidget( Frame3, 0, 0, 0, 1 );
+
+ photo = new QPushButton( this, "photo" );
+ photo->setText( tr( "Photo" ) );
+
+ cameraLayout->addWidget( photo, 1, 0 );
+
+ video = new QPushButton( this, "video" );
+ video->setText( tr( "Video" ) );
+
+ cameraLayout->addWidget( video, 1, 1 );
+
+ thumbs = new QFrame( this, "thumbs" );
+ thumbs->setFrameShape( QFrame::NoFrame );
+ thumbs->setFrameShadow( QFrame::Plain );
+ thumbsLayout = new QHBoxLayout( thumbs );
+ thumbsLayout->setSpacing( 0 );
+ thumbsLayout->setMargin( 0 );
+
+ thumb1 = new ThumbButton( thumbs, "thumb1" );
+ thumbsLayout->addWidget( thumb1 );
+
+ thumb2 = new ThumbButton( thumbs, "thumb2" );
+ thumbsLayout->addWidget( thumb2 );
+
+ thumb3 = new ThumbButton( thumbs, "thumb3" );
+ thumbsLayout->addWidget( thumb3 );
+
+ thumb4 = new ThumbButton( thumbs, "thumb4" );
+ thumbsLayout->addWidget( thumb4 );
+
+ thumb5 = new ThumbButton( thumbs, "thumb5" );
+ thumbsLayout->addWidget( thumb5 );
+
+ cameraLayout->addMultiCellWidget( thumbs, 2, 2, 0, 1 );
+}
+
+/*
+ * Destroys the object and frees any allocated resources
+ */
+CameraBase::~CameraBase()
+{
+ // no need to delete child widgets, Qt does it all for us
+}
+
diff --git a/noncore/multimedia/camera2/camerabase.h b/noncore/multimedia/camera2/camerabase.h
new file mode 100644
index 0000000..77ab4f0
--- a/dev/null
+++ b/noncore/multimedia/camera2/camerabase.h
@@ -0,0 +1,47 @@
+/****************************************************************************
+** Form interface generated from reading ui file 'camerabase.ui'
+**
+** Created: Mon Jul 10 04:21:22 2006
+** by: The User Interface Compiler (uic)
+**
+** WARNING! All changes made in this file will be lost!
+****************************************************************************/
+#ifndef CAMERA_H
+#define CAMERA_H
+
+#include <qvariant.h>
+#include <qwidget.h>
+class QVBoxLayout;
+class QHBoxLayout;
+class QGridLayout;
+class QFrame;
+class QPushButton;
+class ThumbButton;
+class VideoCaptureView;
+
+class CameraBase : public QWidget
+{
+ Q_OBJECT
+
+public:
+ CameraBase( QWidget* parent = 0, const char* name = 0, WFlags fl = 0 );
+ ~CameraBase();
+
+ QFrame* Frame3;
+ VideoCaptureView* videocaptureview;
+ QPushButton* photo;
+ QPushButton* video;
+ QFrame* thumbs;
+ ThumbButton* thumb1;
+ ThumbButton* thumb2;
+ ThumbButton* thumb3;
+ ThumbButton* thumb4;
+ ThumbButton* thumb5;
+
+protected:
+ QGridLayout* cameraLayout;
+ QVBoxLayout* Frame3Layout;
+ QHBoxLayout* thumbsLayout;
+};
+
+#endif // CAMERA_H
diff --git a/noncore/multimedia/camera2/camerabase.ui b/noncore/multimedia/camera2/camerabase.ui
new file mode 100644
index 0000000..e102f79
--- a/dev/null
+++ b/noncore/multimedia/camera2/camerabase.ui
@@ -0,0 +1,209 @@
+<!DOCTYPE UI><UI>
+<class>CameraBase</class>
+<widget>
+ <class>QWidget</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>camera</cstring>
+ </property>
+ <property stdset="1">
+ <name>geometry</name>
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>311</width>
+ <height>381</height>
+ </rect>
+ </property>
+ <property stdset="1">
+ <name>caption</name>
+ <string>Camera</string>
+ </property>
+ <grid>
+ <property stdset="1">
+ <name>margin</name>
+ <number>0</number>
+ </property>
+ <property stdset="1">
+ <name>spacing</name>
+ <number>0</number>
+ </property>
+ <widget row="0" column="0" rowspan="1" colspan="2" >
+ <class>QFrame</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>Frame3</cstring>
+ </property>
+ <property stdset="1">
+ <name>frameShape</name>
+ <enum>Panel</enum>
+ </property>
+ <property stdset="1">
+ <name>frameShadow</name>
+ <enum>Sunken</enum>
+ </property>
+ <property stdset="1">
+ <name>lineWidth</name>
+ <number>4</number>
+ </property>
+ <property stdset="1">
+ <name>margin</name>
+ <number>4</number>
+ </property>
+ <property stdset="1">
+ <name>midLineWidth</name>
+ <number>3</number>
+ </property>
+ <property>
+ <name>layoutMargin</name>
+ </property>
+ <vbox>
+ <property stdset="1">
+ <name>margin</name>
+ <number>4</number>
+ </property>
+ <property stdset="1">
+ <name>spacing</name>
+ <number>6</number>
+ </property>
+ <widget>
+ <class>VideoCaptureView</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>videocaptureview</cstring>
+ </property>
+ <property stdset="1">
+ <name>sizePolicy</name>
+ <sizepolicy>
+ <hsizetype>7</hsizetype>
+ <vsizetype>7</vsizetype>
+ </sizepolicy>
+ </property>
+ </widget>
+ </vbox>
+ </widget>
+ <widget row="1" column="0" >
+ <class>QPushButton</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>photo</cstring>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>Photo</string>
+ </property>
+ </widget>
+ <widget row="1" column="1" >
+ <class>QPushButton</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>video</cstring>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>Video</string>
+ </property>
+ </widget>
+ <widget row="2" column="0" rowspan="1" colspan="2" >
+ <class>QFrame</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>thumbs</cstring>
+ </property>
+ <property stdset="1">
+ <name>frameShape</name>
+ <enum>NoFrame</enum>
+ </property>
+ <property stdset="1">
+ <name>frameShadow</name>
+ <enum>Plain</enum>
+ </property>
+ <hbox>
+ <property stdset="1">
+ <name>margin</name>
+ <number>0</number>
+ </property>
+ <property stdset="1">
+ <name>spacing</name>
+ <number>0</number>
+ </property>
+ <widget>
+ <class>ThumbButton</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>thumb1</cstring>
+ </property>
+ </widget>
+ <widget>
+ <class>ThumbButton</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>thumb2</cstring>
+ </property>
+ </widget>
+ <widget>
+ <class>ThumbButton</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>thumb3</cstring>
+ </property>
+ </widget>
+ <widget>
+ <class>ThumbButton</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>thumb4</cstring>
+ </property>
+ </widget>
+ <widget>
+ <class>ThumbButton</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>thumb5</cstring>
+ </property>
+ </widget>
+ </hbox>
+ </widget>
+ </grid>
+</widget>
+<customwidgets>
+ <customwidget>
+ <class>VideoCaptureView</class>
+ <header location="local">videocaptureview.h</header>
+ <sizehint>
+ <width>-1</width>
+ <height>-1</height>
+ </sizehint>
+ <container>0</container>
+ <sizepolicy>
+ <hordata>7</hordata>
+ <verdata>7</verdata>
+ </sizepolicy>
+ <pixmap>image0</pixmap>
+ </customwidget>
+ <customwidget>
+ <class>ThumbButton</class>
+ <header location="local">thumbbutton.h</header>
+ <sizehint>
+ <width>-1</width>
+ <height>-1</height>
+ </sizehint>
+ <container>0</container>
+ <sizepolicy>
+ <hordata>5</hordata>
+ <verdata>5</verdata>
+ </sizepolicy>
+ <pixmap>image1</pixmap>
+ </customwidget>
+</customwidgets>
+<images>
+ <image>
+ <name>image0</name>
+ <data format="XPM.GZ" length="646">789c6dd2c10ac2300c00d07bbf2234b7229d1be245fc04c5a3201e4615f430059d0711ff5ddb2e6bb236ec90eed134cb5a19d8ef36602af5ecdbfeeac05dda0798d3abebde87e3faa374d3807fa0d633a52d38d8de6f679fe33fc776e196f53cd010188256a3600a292882096246517815ca99884606e18044a3a40d91824820924265a7923a2e8bcd05f33db1173e002913175f2a6be6d3294871a2d95fa00e8a94ee017b69d339d90df1e77c57ea072ede6758</data>
+ </image>
+ <image>
+ <name>image1</name>
+ <data format="XPM.GZ" length="646">789c6dd2c10ac2300c00d07bbf2234b7229d1ddec44f503c0ae2a154410f53d0ed20e2bf6bdb656dd6861dd23d9a66591b0587fd1654235ebded6f0edcd53e419d87ae7b1f4f9b8f906d0bfe012317426a70b07bdc2f3ec77f8ed6b89559061a0343d06a124cc105596482585094bc0ae599b04646c9018926491b2205e140c485cace25755c175d0a967b622ff900b8cc9c7d29af594ea722d589167f813aa852ba07d94b9dce296e883fe7bb163f23896753</data>
+ </image>
+</images>
+</UI>
diff --git a/noncore/multimedia/camera2/camerasettings.cpp b/noncore/multimedia/camera2/camerasettings.cpp
new file mode 100644
index 0000000..d284128
--- a/dev/null
+++ b/noncore/multimedia/camera2/camerasettings.cpp
@@ -0,0 +1,166 @@
+/****************************************************************************
+** Form implementation generated from reading ui file 'camerasettings.ui'
+**
+** Created: Mon Jul 10 04:21:25 2006
+** by: The User Interface Compiler (uic)
+**
+** WARNING! All changes made in this file will be lost!
+****************************************************************************/
+#include "camerasettings.h"
+
+#include <qcombobox.h>
+#include <qgroupbox.h>
+#include <qlabel.h>
+#include <qpushbutton.h>
+#include <qslider.h>
+#include <qtopia/locationcombo.h>
+#include <qlayout.h>
+#include <qvariant.h>
+#include <qtooltip.h>
+#include <qwhatsthis.h>
+
+/*
+ * Constructs a CameraSettings which is a child of 'parent', with the
+ * name 'name' and widget flags set to 'f'
+ *
+ * The dialog will by default be modeless, unless you set 'modal' to
+ * TRUE to construct a modal dialog.
+ */
+CameraSettings::CameraSettings( QWidget* parent, const char* name, bool modal, WFlags fl )
+ : QDialog( parent, name, modal, fl )
+{
+ if ( !name )
+ setName( "CameraSettings" );
+ resize( 324, 465 );
+ setCaption( tr( "Settings" ) );
+ CameraSettingsLayout = new QVBoxLayout( this );
+ CameraSettingsLayout->setSpacing( 6 );
+ CameraSettingsLayout->setMargin( 11 );
+
+ location = new LocationCombo( this, "location" );
+ CameraSettingsLayout->addWidget( location );
+
+ photo = new QGroupBox( this, "photo" );
+ photo->setTitle( tr( "Photo" ) );
+ photo->setColumnLayout(0, Qt::Vertical );
+ photo->layout()->setSpacing( 0 );
+ photo->layout()->setMargin( 0 );
+ photoLayout = new QVBoxLayout( photo->layout() );
+ photoLayout->setAlignment( Qt::AlignTop );
+ photoLayout->setSpacing( 2 );
+ photoLayout->setMargin( 4 );
+
+ Layout1 = new QHBoxLayout;
+ Layout1->setSpacing( 6 );
+ Layout1->setMargin( 0 );
+
+ TextLabel1 = new QLabel( photo, "TextLabel1" );
+ TextLabel1->setText( tr( "Size" ) );
+ Layout1->addWidget( TextLabel1 );
+
+ photo_size = new QComboBox( FALSE, photo, "photo_size" );
+ photo_size->setSizePolicy( QSizePolicy( (QSizePolicy::SizeType)7, (QSizePolicy::SizeType)0, photo_size->sizePolicy().hasHeightForWidth() ) );
+ Layout1->addWidget( photo_size );
+ photoLayout->addLayout( Layout1 );
+
+ Layout2 = new QHBoxLayout;
+ Layout2->setSpacing( 6 );
+ Layout2->setMargin( 0 );
+
+ TextLabel2 = new QLabel( photo, "TextLabel2" );
+ TextLabel2->setText( tr( "Quality" ) );
+ Layout2->addWidget( TextLabel2 );
+
+ photo_quality = new QSlider( photo, "photo_quality" );
+ photo_quality->setMinValue( 0 );
+ photo_quality->setMaxValue( 100 );
+ photo_quality->setValue( 75 );
+ photo_quality->setOrientation( QSlider::Horizontal );
+ Layout2->addWidget( photo_quality );
+
+ photo_quality_n = new QLabel( photo, "photo_quality_n" );
+ photo_quality_n->setText( tr( "75" ) );
+ Layout2->addWidget( photo_quality_n );
+ photoLayout->addLayout( Layout2 );
+ CameraSettingsLayout->addWidget( photo );
+
+ video = new QGroupBox( this, "video" );
+ video->setTitle( tr( "Video" ) );
+ video->setColumnLayout(0, Qt::Vertical );
+ video->layout()->setSpacing( 0 );
+ video->layout()->setMargin( 0 );
+ videoLayout = new QVBoxLayout( video->layout() );
+ videoLayout->setAlignment( Qt::AlignTop );
+ videoLayout->setSpacing( 2 );
+ videoLayout->setMargin( 4 );
+
+ Layout1_2 = new QHBoxLayout;
+ Layout1_2->setSpacing( 6 );
+ Layout1_2->setMargin( 0 );
+
+ TextLabel1_2 = new QLabel( video, "TextLabel1_2" );
+ TextLabel1_2->setText( tr( "Size" ) );
+ Layout1_2->addWidget( TextLabel1_2 );
+
+ video_size = new QComboBox( FALSE, video, "video_size" );
+ video_size->setSizePolicy( QSizePolicy( (QSizePolicy::SizeType)7, (QSizePolicy::SizeType)0, video_size->sizePolicy().hasHeightForWidth() ) );
+ Layout1_2->addWidget( video_size );
+ videoLayout->addLayout( Layout1_2 );
+
+ Layout2_2 = new QHBoxLayout;
+ Layout2_2->setSpacing( 6 );
+ Layout2_2->setMargin( 0 );
+
+ TextLabel2_2 = new QLabel( video, "TextLabel2_2" );
+ TextLabel2_2->setText( tr( "Quality" ) );
+ Layout2_2->addWidget( TextLabel2_2 );
+
+ video_quality = new QSlider( video, "video_quality" );
+ video_quality->setMinValue( 0 );
+ video_quality->setMaxValue( 100 );
+ video_quality->setValue( 75 );
+ video_quality->setOrientation( QSlider::Horizontal );
+ Layout2_2->addWidget( video_quality );
+
+ video_quality_n = new QLabel( video, "video_quality_n" );
+ video_quality_n->setText( tr( "75" ) );
+ Layout2_2->addWidget( video_quality_n );
+ videoLayout->addLayout( Layout2_2 );
+
+ Layout6 = new QHBoxLayout;
+ Layout6->setSpacing( 6 );
+ Layout6->setMargin( 0 );
+
+ TextLabel4 = new QLabel( video, "TextLabel4" );
+ TextLabel4->setText( tr( "Frame rate" ) );
+ Layout6->addWidget( TextLabel4 );
+
+ video_framerate = new QSlider( video, "video_framerate" );
+ video_framerate->setMinValue( 1 );
+ video_framerate->setMaxValue( 60 );
+ video_framerate->setValue( 5 );
+ video_framerate->setOrientation( QSlider::Horizontal );
+ Layout6->addWidget( video_framerate );
+
+ TextLabel6 = new QLabel( video, "TextLabel6" );
+ TextLabel6->setText( tr( "5" ) );
+ Layout6->addWidget( TextLabel6 );
+ videoLayout->addLayout( Layout6 );
+ CameraSettingsLayout->addWidget( video );
+ QSpacerItem* spacer = new QSpacerItem( 20, 20, QSizePolicy::Minimum, QSizePolicy::Expanding );
+ CameraSettingsLayout->addItem( spacer );
+
+ // signals and slots connections
+ connect( photo_quality, SIGNAL( valueChanged(int) ), photo_quality_n, SLOT( setNum(int) ) );
+ connect( video_quality, SIGNAL( valueChanged(int) ), video_quality_n, SLOT( setNum(int) ) );
+ connect( video_framerate, SIGNAL( valueChanged(int) ), TextLabel6, SLOT( setNum(int) ) );
+}
+
+/*
+ * Destroys the object and frees any allocated resources
+ */
+CameraSettings::~CameraSettings()
+{
+ // no need to delete child widgets, Qt does it all for us
+}
+
diff --git a/noncore/multimedia/camera2/camerasettings.h b/noncore/multimedia/camera2/camerasettings.h
new file mode 100644
index 0000000..dcc48a0
--- a/dev/null
+++ b/noncore/multimedia/camera2/camerasettings.h
@@ -0,0 +1,59 @@
+/****************************************************************************
+** Form interface generated from reading ui file 'camerasettings.ui'
+**
+** Created: Mon Jul 10 04:21:22 2006
+** by: The User Interface Compiler (uic)
+**
+** WARNING! All changes made in this file will be lost!
+****************************************************************************/
+#ifndef CAMERASETTINGS_H
+#define CAMERASETTINGS_H
+
+#include <qvariant.h>
+#include <qdialog.h>
+class QVBoxLayout;
+class QHBoxLayout;
+class QGridLayout;
+class LocationCombo;
+class QComboBox;
+class QGroupBox;
+class QLabel;
+class QSlider;
+
+class CameraSettings : public QDialog
+{
+ Q_OBJECT
+
+public:
+ CameraSettings( QWidget* parent = 0, const char* name = 0, bool modal = FALSE, WFlags fl = 0 );
+ ~CameraSettings();
+
+ LocationCombo* location;
+ QGroupBox* photo;
+ QLabel* TextLabel1;
+ QComboBox* photo_size;
+ QLabel* TextLabel2;
+ QSlider* photo_quality;
+ QLabel* photo_quality_n;
+ QGroupBox* video;
+ QLabel* TextLabel1_2;
+ QComboBox* video_size;
+ QLabel* TextLabel2_2;
+ QSlider* video_quality;
+ QLabel* video_quality_n;
+ QLabel* TextLabel4;
+ QSlider* video_framerate;
+ QLabel* TextLabel6;
+
+protected:
+ QVBoxLayout* CameraSettingsLayout;
+ QVBoxLayout* photoLayout;
+ QHBoxLayout* Layout1;
+ QHBoxLayout* Layout2;
+ QVBoxLayout* videoLayout;
+ QHBoxLayout* Layout1_2;
+ QHBoxLayout* Layout2_2;
+ QHBoxLayout* Layout6;
+};
+
+#endif // CAMERASETTINGS_H
diff --git a/noncore/multimedia/camera2/camerasettings.ui b/noncore/multimedia/camera2/camerasettings.ui
new file mode 100644
index 0000000..276694b
--- a/dev/null
+++ b/noncore/multimedia/camera2/camerasettings.ui
@@ -0,0 +1,433 @@
+<!DOCTYPE UI><UI>
+<class>CameraSettings</class>
+<widget>
+ <class>QDialog</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>CameraSettings</cstring>
+ </property>
+ <property stdset="1">
+ <name>geometry</name>
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>324</width>
+ <height>465</height>
+ </rect>
+ </property>
+ <property stdset="1">
+ <name>caption</name>
+ <string>Settings</string>
+ </property>
+ <property>
+ <name>layoutMargin</name>
+ </property>
+ <property>
+ <name>layoutSpacing</name>
+ </property>
+ <vbox>
+ <property stdset="1">
+ <name>margin</name>
+ <number>11</number>
+ </property>
+ <property stdset="1">
+ <name>spacing</name>
+ <number>6</number>
+ </property>
+ <widget>
+ <class>LocationCombo</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>location</cstring>
+ </property>
+ </widget>
+ <widget>
+ <class>QGroupBox</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>photo</cstring>
+ </property>
+ <property stdset="1">
+ <name>title</name>
+ <string>Photo</string>
+ </property>
+ <property>
+ <name>layoutMargin</name>
+ </property>
+ <property>
+ <name>layoutSpacing</name>
+ </property>
+ <vbox>
+ <property stdset="1">
+ <name>margin</name>
+ <number>4</number>
+ </property>
+ <property stdset="1">
+ <name>spacing</name>
+ <number>2</number>
+ </property>
+ <widget>
+ <class>QLayoutWidget</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>Layout1</cstring>
+ </property>
+ <hbox>
+ <property stdset="1">
+ <name>margin</name>
+ <number>0</number>
+ </property>
+ <property stdset="1">
+ <name>spacing</name>
+ <number>6</number>
+ </property>
+ <widget>
+ <class>QLabel</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>TextLabel1</cstring>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>Size</string>
+ </property>
+ </widget>
+ <widget>
+ <class>QComboBox</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>photo_size</cstring>
+ </property>
+ <property stdset="1">
+ <name>sizePolicy</name>
+ <sizepolicy>
+ <hsizetype>7</hsizetype>
+ <vsizetype>0</vsizetype>
+ </sizepolicy>
+ </property>
+ </widget>
+ </hbox>
+ </widget>
+ <widget>
+ <class>QLayoutWidget</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>Layout2</cstring>
+ </property>
+ <hbox>
+ <property stdset="1">
+ <name>margin</name>
+ <number>0</number>
+ </property>
+ <property stdset="1">
+ <name>spacing</name>
+ <number>6</number>
+ </property>
+ <widget>
+ <class>QLabel</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>TextLabel2</cstring>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>Quality</string>
+ </property>
+ </widget>
+ <widget>
+ <class>QSlider</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>photo_quality</cstring>
+ </property>
+ <property stdset="1">
+ <name>minValue</name>
+ <number>0</number>
+ </property>
+ <property stdset="1">
+ <name>maxValue</name>
+ <number>100</number>
+ </property>
+ <property stdset="1">
+ <name>value</name>
+ <number>75</number>
+ </property>
+ <property stdset="1">
+ <name>orientation</name>
+ <enum>Horizontal</enum>
+ </property>
+ </widget>
+ <widget>
+ <class>QLabel</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>photo_quality_n</cstring>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>75</string>
+ </property>
+ </widget>
+ </hbox>
+ </widget>
+ </vbox>
+ </widget>
+ <widget>
+ <class>QGroupBox</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>video</cstring>
+ </property>
+ <property stdset="1">
+ <name>title</name>
+ <string>Video</string>
+ </property>
+ <property>
+ <name>layoutMargin</name>
+ </property>
+ <property>
+ <name>layoutSpacing</name>
+ </property>
+ <vbox>
+ <property stdset="1">
+ <name>margin</name>
+ <number>4</number>
+ </property>
+ <property stdset="1">
+ <name>spacing</name>
+ <number>2</number>
+ </property>
+ <widget>
+ <class>QLayoutWidget</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>Layout1_2</cstring>
+ </property>
+ <hbox>
+ <property stdset="1">
+ <name>margin</name>
+ <number>0</number>
+ </property>
+ <property stdset="1">
+ <name>spacing</name>
+ <number>6</number>
+ </property>
+ <widget>
+ <class>QLabel</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>TextLabel1_2</cstring>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>Size</string>
+ </property>
+ </widget>
+ <widget>
+ <class>QComboBox</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>video_size</cstring>
+ </property>
+ <property stdset="1">
+ <name>sizePolicy</name>
+ <sizepolicy>
+ <hsizetype>7</hsizetype>
+ <vsizetype>0</vsizetype>
+ </sizepolicy>
+ </property>
+ </widget>
+ </hbox>
+ </widget>
+ <widget>
+ <class>QLayoutWidget</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>Layout2_2</cstring>
+ </property>
+ <hbox>
+ <property stdset="1">
+ <name>margin</name>
+ <number>0</number>
+ </property>
+ <property stdset="1">
+ <name>spacing</name>
+ <number>6</number>
+ </property>
+ <widget>
+ <class>QLabel</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>TextLabel2_2</cstring>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>Quality</string>
+ </property>
+ </widget>
+ <widget>
+ <class>QSlider</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>video_quality</cstring>
+ </property>
+ <property stdset="1">
+ <name>minValue</name>
+ <number>0</number>
+ </property>
+ <property stdset="1">
+ <name>maxValue</name>
+ <number>100</number>
+ </property>
+ <property stdset="1">
+ <name>value</name>
+ <number>75</number>
+ </property>
+ <property stdset="1">
+ <name>orientation</name>
+ <enum>Horizontal</enum>
+ </property>
+ </widget>
+ <widget>
+ <class>QLabel</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>video_quality_n</cstring>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>75</string>
+ </property>
+ </widget>
+ </hbox>
+ </widget>
+ <widget>
+ <class>QLayoutWidget</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>Layout6</cstring>
+ </property>
+ <hbox>
+ <property stdset="1">
+ <name>margin</name>
+ <number>0</number>
+ </property>
+ <property stdset="1">
+ <name>spacing</name>
+ <number>6</number>
+ </property>
+ <widget>
+ <class>QLabel</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>TextLabel4</cstring>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>Frame rate</string>
+ </property>
+ </widget>
+ <widget>
+ <class>QSlider</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>video_framerate</cstring>
+ </property>
+ <property stdset="1">
+ <name>minValue</name>
+ <number>1</number>
+ </property>
+ <property stdset="1">
+ <name>maxValue</name>
+ <number>60</number>
+ </property>
+ <property stdset="1">
+ <name>value</name>
+ <number>5</number>
+ </property>
+ <property stdset="1">
+ <name>orientation</name>
+ <enum>Horizontal</enum>
+ </property>
+ </widget>
+ <widget>
+ <class>QLabel</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>TextLabel6</cstring>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>5</string>
+ </property>
+ </widget>
+ </hbox>
+ </widget>
+ </vbox>
+ </widget>
+ <spacer>
+ <property>
+ <name>name</name>
+ <cstring>Spacer1</cstring>
+ </property>
+ <property stdset="1">
+ <name>orientation</name>
+ <enum>Vertical</enum>
+ </property>
+ <property stdset="1">
+ <name>sizeType</name>
+ <enum>Expanding</enum>
+ </property>
+ <property>
+ <name>sizeHint</name>
+ <size>
+ <width>20</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </vbox>
+</widget>
+<customwidgets>
+ <customwidget>
+ <class>LocationCombo</class>
+ <header location="global">qtopia/locationcombo.h</header>
+ <sizehint>
+ <width>-1</width>
+ <height>-1</height>
+ </sizehint>
+ <container>0</container>
+ <sizepolicy>
+ <hordata>5</hordata>
+ <verdata>5</verdata>
+ </sizepolicy>
+ <pixmap>image0</pixmap>
+ </customwidget>
+</customwidgets>
+<images>
+ <image>
+ <name>image0</name>
+ <data format="XPM.GZ" length="646">789c6dd2c10ac2300c00d07bbf2234b7229d1be245fc04c5a3201e4615f430059d0711ff5ddb2e6bb236ec90eed134cb5a19d8ef36602af5ecdbfeeac05dda0798d3abebde87e3faa374d3807fa0d633a52d38d8de6f679fe33fc776e196f53cd010188256a3600a292882096246517815ca99884606e18044a3a40d91824820924265a7923a2e8bcd05f33db1173e002913175f2a6be6d3294871a2d95fa00e8a94ee017b69d339d90df1e77c57ea072ede6758</data>
+ </image>
+</images>
+<connections>
+ <connection>
+ <sender>photo_quality</sender>
+ <signal>valueChanged(int)</signal>
+ <receiver>photo_quality_n</receiver>
+ <slot>setNum(int)</slot>
+ </connection>
+ <connection>
+ <sender>video_quality</sender>
+ <signal>valueChanged(int)</signal>
+ <receiver>video_quality_n</receiver>
+ <slot>setNum(int)</slot>
+ </connection>
+ <connection>
+ <sender>video_framerate</sender>
+ <signal>valueChanged(int)</signal>
+ <receiver>TextLabel6</receiver>
+ <slot>setNum(int)</slot>
+ </connection>
+</connections>
+</UI>
diff --git a/noncore/multimedia/camera2/config.in b/noncore/multimedia/camera2/config.in
new file mode 100644
index 0000000..8838008
--- a/dev/null
+++ b/noncore/multimedia/camera2/config.in
@@ -0,0 +1,7 @@
+ config CAMERA2
+ boolean "opie-camera2 (camera app to use with Video4Linux)"
+ default "n"
+ depends ( LIBQPE || LIBQPE-X11 ) && LIBOPIE2CORE && LIBOPIE2UI
+ comment "opie-camera needs a libqpe, libopie2core & libopie2ui"
+ depends !(( LIBQPE || LIBQPE-X11 ) && LIBOPIE2CORE && LIBOPIE2UI )
+
diff --git a/noncore/multimedia/camera2/image.cpp b/noncore/multimedia/camera2/image.cpp
new file mode 100644
index 0000000..39b6d8b
--- a/dev/null
+++ b/noncore/multimedia/camera2/image.cpp
@@ -0,0 +1,239 @@
+/**********************************************************************
+** Copyright (C) 2000-2006 Trolltech AS. All rights reserved.
+**
+** This file is part of the Qtopia Environment.
+**
+** This program is free software; you can redistribute it and/or modify it
+** under the terms of the GNU General Public License as published by the
+** Free Software Foundation; either version 2 of the License, or (at your
+** option) any later version.
+**
+** A copy of the GNU GPL license version 2 is included in this package as
+** LICENSE.GPL.
+**
+** This program is distributed in the hope that it will be useful, but
+** WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+** See the GNU General Public License for more details.
+**
+** In addition, as a special exception Trolltech gives permission to link
+** the code of this program with Qtopia applications copyrighted, developed
+** and distributed by Trolltech under the terms of the Qtopia Personal Use
+** License Agreement. You must comply with the GNU General Public License
+** in all respects for all of the code used other than the applications
+** licensed under the Qtopia Personal Use License Agreement. If you modify
+** this file, you may extend this exception to your version of the file,
+** but you are not obligated to do so. If you do not wish to do so, delete
+** this exception statement from your version.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+
+#include "image.h"
+
+#include <qfileinfo.h>
+#include <qimage.h>
+#include <qstring.h>
+
+/*!
+ Returns an image created by loading the \a filename,
+ and scalining it, preserving aspect ratio, to fit in
+ \a width by \a height pixels.
+
+ First availability: Qtopia 2.0
+*/
+QImage Image::loadScaled(const QString & filename, const int width, const int height,
+ ScaleMode mode)
+{
+ QImageIO iio;
+ QString param;
+ int w = width;
+ int h = height;
+
+ if (width == 0 || height == 0)
+ return QImage();
+
+ iio.setFileName(filename);
+
+ //
+ // Try and load and scale the image in one hit.
+ //
+ param.sprintf("GetHeaderInformation");
+ iio.setParameters(param);
+ iio.read();
+
+ //
+ // If we don't have bits(), read() understands parameters,
+ // and we can setup for fast reading. Otherwise, take the
+ // performance hit and do things slowly.
+ //
+ if (!iio.image().bits()) {
+ if ((iio.image().width() < w) && (iio.image().height() < h)) {
+ param.sprintf("%s", "Fast"); // No Tr
+ }
+ else {
+ int shrink_factor = 1;
+ QString smode;
+ switch (mode) {
+ case ScaleMin:
+ smode = "ScaleMin";
+ shrink_factor = QMAX(iio.image().width() / w, iio.image().height() / h);
+ break;
+ case ScaleMax:
+ smode = "ScaleMax";
+ shrink_factor = QMIN(iio.image().width() / w, iio.image().height() / h);
+ break;
+ case ScaleFree:
+ smode = "ScaleFree";
+ shrink_factor = QMIN(iio.image().width() / w, iio.image().height() / h);
+ break;
+ }
+ param.sprintf("Scale( %i, %i, %s )%s, Shrink( %i )", // No tr
+ w, h, smode.latin1(), ", Fast", shrink_factor); // No tr
+ }
+
+ iio.setParameters(param);
+ iio.read();
+ return iio.image();
+ }
+
+ if ((iio.image().width() > w) || (iio.image().height() > h)) {
+ QSize s = aspectScaleSize(iio.image().width(), iio.image().height(), w, h, mode);
+ return iio.image().smoothScale(s.width(), s.height());
+ }
+
+ return iio.image();
+}
+
+//
+// Returns new size of image, scaled to target_width and target_height,
+// whilst preserving aspect ratio. Useful when it's not possible to
+// scale an image prior to using it (eg. using RichText). Should be in
+// global image utils.
+//
+// NOTE
+// - expensive for images whose drivers do not allow us to retrieve
+// parameters without reading the entire image. Currently (20030930)
+// only the jpeg driver allows parameter reading.
+//
+QSize Image::loadScaledImageSize(const QString & filename, int target_width, int target_height,
+ int maxscale, ScaleMode mode)
+{
+ QImageIO iio;
+ iio.setFileName(filename);
+ iio.setParameters("GetHeaderInformation");
+ iio.read();
+
+ int w = iio.image().width();
+ int h = iio.image().height();
+
+ //
+ // Scaling up small pictures can be very ugly.
+ // Leave them alone if they are too small.
+ //
+ if (maxscale && w * maxscale < target_width && h * maxscale < target_height)
+ return QSize(w * maxscale, h * maxscale);
+
+ return aspectScaleSize(w, h, target_width, target_height, mode);
+}
+
+// Load an image to be used as a portrait. Force its height to height,
+// scale width to new height, and crop the width if it's still > width
+// XXX : Should be using integer math
+QImage Image::loadPortrait(const QString & filename, const int width, const int height)
+{
+ QImageIO iio;
+ QString param;
+ int w = width;
+ int h = height;
+
+ if (width == 0 || height == 0)
+ return QImage();
+
+ iio.setFileName(filename);
+
+ //
+ // Try and load and scale the image in one hit.
+ //
+ param.sprintf("GetHeaderInformation");
+ iio.setParameters(param);
+ iio.read();
+
+ //
+ // If we don't have bits(), read() understands parameters,
+ // and we can setup for fast reading. Otherwise, take the
+ // performance hit and do things slowly.
+ //
+ if (!iio.image().bits()) {
+
+ w = (int) ((double) iio.image().width() / (double) (iio.image().height()) *
+ (double) height);
+ param.sprintf("Scale( %i, %i, ScaleFree )%s", // No tr
+ w, h, ", Fast"); // No tr
+
+ iio.setParameters(param);
+ iio.read();
+
+ if (w > width) {
+ int x = (int) ((double) (w - width) / 2);
+ QRect r(x, 0, width, height);
+ return iio.image().copy(r);
+ }
+ else
+ return iio.image();
+ }
+ else
+ //scale width to the new height
+ return sizeToPortrait(iio.image(), width, height);
+}
+
+QImage Image::sizeToPortrait(const QImage & image, const int width, const int height)
+{
+ int w = (image.width() * height) / image.height();
+ if (w > width) {
+ int x = (w - width) / 2;
+ QRect r(x, 0, width, height);
+ return image.smoothScale(w, height).copy(r);
+ }
+ else
+ return image.smoothScale(width, height);
+}
+
+//
+// Return (w x h) scaled to (target_width x target_height) with aspect
+// ratio preserved.
+//
+QSize
+ Image::aspectScaleSize(const int w, const int h, const int target_width,
+ const int target_height, ScaleMode mode)
+{
+ QSize s;
+ if (mode == ScaleFree) {
+ s = QSize(target_width, target_height);
+ }
+ else {
+ bool useHeight = TRUE;
+ int rw = target_height * w / h;
+
+ if (mode == ScaleMin) {
+ useHeight = (rw <= target_width);
+ }
+ else { // mode == ScaleMax
+ useHeight = (rw >= target_width);
+ }
+
+ if (useHeight) {
+ s = QSize(rw, target_height);
+ }
+ else {
+ s = QSize(target_width, target_width * h / w);
+ }
+ }
+
+ return s;
+}
+
diff --git a/noncore/multimedia/camera2/image.h b/noncore/multimedia/camera2/image.h
new file mode 100644
index 0000000..36394ff
--- a/dev/null
+++ b/noncore/multimedia/camera2/image.h
@@ -0,0 +1,53 @@
+/**********************************************************************
+** Copyright (C) 2000-2006 Trolltech AS. All rights reserved.
+**
+** This file is part of the Qtopia Environment.
+**
+** This program is free software; you can redistribute it and/or modify it
+** under the terms of the GNU General Public License as published by the
+** Free Software Foundation; either version 2 of the License, or (at your
+** option) any later version.
+**
+** A copy of the GNU GPL license version 2 is included in this package as
+** LICENSE.GPL.
+**
+** This program is distributed in the hope that it will be useful, but
+** WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+** See the GNU General Public License for more details.
+**
+** In addition, as a special exception Trolltech gives permission to link
+** the code of this program with Qtopia applications copyrighted, developed
+** and distributed by Trolltech under the terms of the Qtopia Personal Use
+** License Agreement. You must comply with the GNU General Public License
+** in all respects for all of the code used other than the applications
+** licensed under the Qtopia Personal Use License Agreement. If you modify
+** this file, you may extend this exception to your version of the file,
+** but you are not obligated to do so. If you do not wish to do so, delete
+** this exception statement from your version.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+
+#ifndef IMAGE_H
+#define IMAGE_H
+
+#include <qimage.h>
+#include <qtopia/qpeglobal.h>
+
+class Image {
+public:
+ // namespace
+ enum ScaleMode { ScaleFree, ScaleMin, ScaleMax };
+ static QImage loadScaled(const QString &filename, const int width, const int height, ScaleMode mode=ScaleMin);
+ static QSize loadScaledImageSize(const QString &filename, int target_width, int target_height, int maxscale=1, ScaleMode mode=ScaleMin);
+ static QImage loadPortrait(const QString &filename, const int width, const int height);
+ static QImage sizeToPortrait(const QImage &image, const int width, const int height);
+ static QSize aspectScaleSize(const int w, const int h, const int target_width, const int target_height, ScaleMode mode=ScaleMin);
+};
+
+#endif // IMAGE_H
diff --git a/noncore/multimedia/camera2/main.cpp b/noncore/multimedia/camera2/main.cpp
new file mode 100644
index 0000000..00e21de
--- a/dev/null
+++ b/noncore/multimedia/camera2/main.cpp
@@ -0,0 +1,44 @@
+/**********************************************************************
+** Copyright (C) 2000-2006 Trolltech AS. All rights reserved.
+**
+** This file is part of the Qtopia Environment.
+**
+** This program is free software; you can redistribute it and/or modify it
+** under the terms of the GNU General Public License as published by the
+** Free Software Foundation; either version 2 of the License, or (at your
+** option) any later version.
+**
+** A copy of the GNU GPL license version 2 is included in this package as
+** LICENSE.GPL.
+**
+** This program is distributed in the hope that it will be useful, but
+** WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+** See the GNU General Public License for more details.
+**
+** In addition, as a special exception Trolltech gives permission to link
+** the code of this program with Qtopia applications copyrighted, developed
+** and distributed by Trolltech under the terms of the Qtopia Personal Use
+** License Agreement. You must comply with the GNU General Public License
+** in all respects for all of the code used other than the applications
+** licensed under the Qtopia Personal Use License Agreement. If you modify
+** this file, you may extend this exception to your version of the file,
+** but you are not obligated to do so. If you do not wish to do so, delete
+** this exception statement from your version.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+
+#include "mainwindow.h"
+#include <opie2/oapplication.h>
+#include <opie2/oapplicationfactory.h>
+
+using namespace Opie::Core;
+OPIE_EXPORT_APP(OApplicationFactory < CameraMainWindow >)
+// QTOPIA_ADD_APPLICATION("camera",CameraMainWindow)
+// QTOPIA_MAIN
+
diff --git a/noncore/multimedia/camera2/mainwindow.cpp b/noncore/multimedia/camera2/mainwindow.cpp
new file mode 100644
index 0000000..45f8cdf
--- a/dev/null
+++ b/noncore/multimedia/camera2/mainwindow.cpp
@@ -0,0 +1,763 @@
+/**********************************************************************
+ ** Copyright (C) 2000-2006 Trolltech AS. All rights reserved.
+ **
+ ** This file is part of the Qtopia Environment.
+ **
+ ** This program is free software; you can redistribute it and/or modify it
+ ** under the terms of the GNU General Public License as published by the
+ ** Free Software Foundation; either version 2 of the License, or (at your
+ ** option) any later version.
+ **
+ ** A copy of the GNU GPL license version 2 is included in this package as
+ ** LICENSE.GPL.
+ **
+ ** This program is distributed in the hope that it will be useful, but
+ ** WITHOUT ANY WARRANTY; without even the implied warranty of
+ ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ ** See the GNU General Public License for more details.
+ **
+ ** In addition, as a special exception Trolltech gives permission to link
+ ** the code of this program with Qtopia applications copyrighted, developed
+ ** and distributed by Trolltech under the terms of the Qtopia Personal Use
+ ** License Agreement. You must comply with the GNU General Public License
+ ** in all respects for all of the code used other than the applications
+ ** licensed under the Qtopia Personal Use License Agreement. If you modify
+ ** this file, you may extend this exception to your version of the file,
+ ** but you are not obligated to do so. If you do not wish to do so, delete
+ ** this exception statement from your version.
+ **
+ ** See http://www.trolltech.com/gpl/ for GPL licensing information.
+ **
+ ** Contact info@trolltech.com if any conditions of this licensing are
+ ** not clear to you.
+ **
+ **********************************************************************/
+
+#define QTOPIA_INTERNAL_FILEOPERATIONS
+#include "mainwindow.h"
+#include "videocaptureview.h"
+#include "camerasettings.h"
+#include "thumbbutton.h"
+
+#include "image.h"
+
+/* OPIE */
+#include <opie2/odebug.h>
+#include <opie2/oresource.h>
+using namespace Opie::Core;
+
+#include <qpe/config.h>
+#include <qpe/qpeapplication.h>
+#include <qpe/locationcombo.h>
+//#include <qtopia/contextmenu.h>
+#include <qpe/qcopenvelope_qws.h>
+#include <qpe/resource.h>
+//#include <qtopia/services.h>
+#include <qpe/categories.h>
+#include <qpe/qpetoolbar.h>
+#include <qpe/global.h>
+
+#include <qaction.h>
+#include <qlabel.h>
+#include <qtoolbutton.h>
+#include <qpushbutton.h>
+#include <qgroupbox.h>
+#include <qsignalmapper.h>
+#include <qdir.h>
+#include <qimage.h>
+#include <qslider.h>
+#include <qtimer.h>
+#include <qmessagebox.h>
+
+#include <stdlib.h>
+
+#include <sys/types.h>
+#include <sys/stat.h>
+
+static const int thmarg = 2;
+static const bool video_supported = FALSE;
+
+CameraMainWindow::CameraMainWindow(QWidget * parent, const char *name, WFlags f)
+:QMainWindow(parent, name, f)
+{
+ setCaption(tr("Camera"));
+
+ picfile = Global::tempDir() + "image.jpg";
+ camera = new CameraBase(this);
+ setCentralWidget(camera);
+
+ connect(qApp, SIGNAL(appMessage(const QCString &, const QByteArray &)),
+ this, SLOT(appMessage(const QCString &, const QByteArray &)));
+ connect(qApp, SIGNAL(linkChanged(const QString &)), this, SLOT(linkChanged(const QString &)));
+
+ Categories cats;
+ cats.load(categoryFileName());
+ camcat = cats.id("Document View", "_Camera"); // No tr
+ if (!camcat) {
+ camcat = cats.addCategory("Document View", "_Camera"); // No tr
+ cats.save(categoryFileName());
+ }
+
+ camera->photo->setFocus();
+
+ connect(camera->photo, SIGNAL(clicked()), this, SLOT(takePhoto()));
+ connect(camera->video, SIGNAL(clicked()), this, SLOT(toggleVideo()));
+
+ refocusTimer = new QTimer(this);
+ connect(refocusTimer, SIGNAL(timeout()), this, SLOT(takePhotoNow()));
+
+ thumb[0] = camera->thumb1;
+ thumb[1] = camera->thumb2;
+ thumb[2] = camera->thumb3;
+ thumb[3] = camera->thumb4;
+ thumb[4] = camera->thumb5;
+ cur_thumb = -1;
+
+ QSignalMapper *sm = new QSignalMapper(this);
+ for (int i = 0; i < nthumb; i++) {
+ sm->setMapping(thumb[i], i);
+ connect(thumb[i], SIGNAL(clicked()), sm, SLOT(map()));
+ thumb[i]->installEventFilter(this);
+ }
+ connect(sm, SIGNAL(mapped(int)), this, SLOT(thumbClicked(int)));
+
+#warning fixme
+// AppLnk picture_viewer = Service::appLnk("PhotoEdit");
+// AppLnk video_viewer = Service::appLnk("Open/video/mpeg");
+
+ a_pview = new QAction(tr("%1...", "app name").arg("" /*picture_viewer.name() */ ),
+ Resource::loadPixmap(NULL /*picture_viewer.icon() */ ), QString::null, 0,
+ this, 0);
+ connect(a_pview, SIGNAL(activated()), this, SLOT(viewPictures()));
+ a_vview = new QAction(tr("%1...", "app name").arg("" /*video_viewer.name() */ ),
+ Resource::loadIconSet(NULL /*video_viewer.icon() */ ), QString::null, 0,
+ this, 0);
+ connect(a_vview, SIGNAL(activated()), this, SLOT(viewVideos()));
+
+ a_settings =
+ new QAction(tr("Settings..."), Opie::Core::OResource::loadPixmap("camera2/settings", Opie::Core::OResource::SmallIcon),
+ QString::null, 0, this, 0);
+ connect(a_settings, SIGNAL(activated()), this, SLOT(doSettings()));
+
+ a_th_edit = new QAction(tr("Edit"), Opie::Core::OResource::loadPixmap("edit", Opie::Core::OResource::SmallIcon),
+ QString::null, 0, this, 0);
+ connect(a_th_edit, SIGNAL(activated()), this, SLOT(editThumb()));
+ a_th_del = new QAction(tr("Delete"), Opie::Core::OResource::loadPixmap("trash", Opie::Core::OResource::SmallIcon),
+ QString::null, 0, this, 0);
+ connect(a_th_del, SIGNAL(activated()), this, SLOT(delThumb()));
+ a_th_add =
+ new QAction(tr("Move to Contact..."), Opie::Core::OResource::loadPixmap("addressbook/generic-contact", Opie::Core::OResource::SmallIcon),
+ QString::null, 0, this, 0);
+ connect(a_th_add, SIGNAL(activated()), this, SLOT(moveToContact()));
+ a_send =
+ new QAction(tr("Beam to Contact..."), Opie::Core::OResource::loadPixmap("beam", Opie::Core::OResource::SmallIcon),
+ QString::null, 0, this, 0);
+ connect(a_send, SIGNAL(activated()), this, SLOT(sendFile()));
+
+
+#ifndef QTOPIA_PHONE
+ // Create Toolbars
+ QPEToolBar *bar = new QPEToolBar(this);
+ bar->setHorizontalStretchable(TRUE);
+ setToolBarsMovable(FALSE);
+
+ a_pview->addTo(bar);
+ if (video_supported)
+ a_vview->addTo(bar);
+ a_th_edit->addTo(bar);
+ a_th_del->addTo(bar);
+ a_th_add->addTo(bar);
+ a_send->addTo(bar);
+ a_settings->addTo(bar);
+#else
+ ContextMenu *contextMenu = new ContextMenu(this);
+ a_pview->addTo(contextMenu);
+ if (video_supported)
+ a_vview->addTo(contextMenu);
+ a_th_edit->addTo(contextMenu);
+ a_th_del->addTo(contextMenu);
+ a_th_add->addTo(contextMenu);
+ a_send->addTo(contextMenu);
+ a_settings->addTo(contextMenu);
+#endif
+
+ installEventFilter(camera->photo);
+ installEventFilter(camera->video);
+ camera->photo->installEventFilter(this);
+ camera->video->installEventFilter(this);
+
+ // Load the allowable sizes from the camera hardware.
+ photo_size = camera->videocaptureview->photoSizes();
+ video_size = camera->videocaptureview->videoSizes();
+
+ settings = new CameraSettings(this, 0, TRUE);
+ // load settings from config
+ Config cfg("Camera");
+ cfg.setGroup("General");
+ QString l = cfg.readEntry("location");
+
+#warning fixme
+ /*if ( !l.isEmpty() )
+ settings->location->setLocation(l);
+ */
+
+ storagepath = settings->location->documentPath();
+ cfg.setGroup("Photo");
+ int w;
+ w = cfg.readNumEntry("width", camera->videocaptureview->recommendedPhotoSize().width());
+ for (psize = 0; psize < (int) photo_size.count() - 1 && photo_size[psize].width() > w;)
+ psize++;
+ pquality = cfg.readNumEntry("quality", settings->photo_quality->value());
+ cfg.setGroup("Video");
+ w = cfg.readNumEntry("width", camera->videocaptureview->recommendedVideoSize().width());
+ for (vsize = 0; vsize < (int) video_size.count() - 1 && video_size[vsize].width() > w;)
+ vsize++;
+ vquality = cfg.readNumEntry("quality", settings->video_quality->value());
+ vframerate = cfg.readNumEntry("framerate", settings->video_framerate->value());
+
+ for (int i = 0; i < (int) photo_size.count(); i++) {
+ settings->photo_size->insertItem(tr("%1 x %2").arg(photo_size[i].width()).
+ arg(photo_size[i].height()));
+ }
+ for (int i = 0; i < (int) video_size.count(); i++) {
+ settings->video_size->insertItem(tr("%1 x %2").arg(video_size[i].width()).
+ arg(video_size[i].height()));
+ }
+
+ namehint = 0;
+ recording = FALSE;
+
+ preview();
+
+ if (!video_supported) {
+ // Room for longer text
+ camera->photo->setText(tr("Take Photo"));
+ camera->video->setEnabled(FALSE);
+ camera->video->hide();
+ }
+}
+
+CameraMainWindow::~CameraMainWindow()
+{
+}
+
+void CameraMainWindow::resizeEvent(QResizeEvent *)
+{
+ thumbw = width() / 5 - 4;
+ thumbh = thumbw * 3 / 4;
+ thumb[0]->setFixedHeight(thumbh + thmarg * 2);
+ loadThumbs();
+}
+
+bool CameraMainWindow::event(QEvent * e)
+{
+ if (e->type() == QEvent::WindowActivate) {
+ if (cur_thumb < 0)
+ camera->videocaptureview->setLive();
+ }
+ else if (e->type() == QEvent::WindowDeactivate) {
+ camera->videocaptureview->setLive(-1);
+ }
+ return QMainWindow::event(e);
+}
+
+bool CameraMainWindow::eventFilter(QObject * o, QEvent * e)
+{
+ if (e->type() == QEvent::KeyPress) {
+ QKeyEvent *ke = (QKeyEvent *) e;
+
+#if QTOPIA_PHONE
+ if (!ke->isAutoRepeat()) {
+ if (ke->key() == Key_1) {
+ takePhoto();
+ return TRUE;
+ }
+ else if (ke->key() == Key_2) {
+ toggleVideo();
+ return TRUE;
+ }
+ }
+#endif
+ if (ke->key() == Key_Up) {
+ camera->photo->setFocus();
+ return TRUE;
+ }
+ else if (ke->key() == Key_Down) {
+ thumb[0]->setFocus();
+ return TRUE;
+ }
+ else if (ke->key() == Key_Left) {
+ if (o == camera->video) {
+ camera->photo->setFocus();
+ return TRUE;
+ }
+ else {
+ if (o == thumb[0])
+ return TRUE;
+ for (int i = 1; i < nthumb; ++i) {
+ if (o == thumb[i]) {
+ thumb[i - 1]->setFocus();
+ return TRUE;
+ }
+ }
+ }
+ }
+ else if (ke->key() == Key_Right) {
+ if (o == camera->photo) {
+ camera->video->setFocus();
+ return TRUE;
+ }
+ else {
+ if (o == thumb[nthumb - 1])
+ return TRUE;
+ for (int i = 0; i < nthumb - 1; ++i) {
+ if (o == thumb[i]) {
+ thumb[i + 1]->setFocus();
+ return TRUE;
+ }
+ }
+ }
+ }
+ }
+ else if (e->type() == QEvent::FocusIn) {
+ if (o == camera->photo)
+ camera->photo->setText(tr("Take Photo"));
+ updateActions();
+ }
+ else if (e->type() == QEvent::FocusOut) {
+ if (o == camera->photo)
+ camera->photo->setText(tr("Activate Camera"));
+ }
+ return QWidget::eventFilter(o, e);
+}
+
+void CameraMainWindow::updateActions()
+{
+ bool p = FALSE, v = FALSE;
+ QWidget *foc = focusWidget();
+ if (foc == camera->photo) {
+ p = TRUE;
+ v = FALSE;
+ }
+ else if (foc == camera->video) {
+ v = TRUE;
+ p = FALSE;
+ }
+ a_pview->setEnabled(p);
+ a_vview->setEnabled(v);
+ a_settings->setEnabled(p || v);
+ bool th = !p && !v;
+ if (th) {
+ int i;
+ for (i = 0; i < nthumb; i++) {
+ if (thumb[i] == foc) {
+ selectThumb(i);
+ break;
+ }
+ }
+ if (i == nthumb || !thumb[i]->pixmap())
+ th = FALSE;
+ }
+ else {
+ selectThumb(-1);
+ }
+}
+
+void CameraMainWindow::viewPictures()
+{
+#warning fixme
+// ServiceRequest req("PhotoEdit","showCategory(int)");
+// req << camcat;
+// req.send();
+}
+
+void CameraMainWindow::viewVideos()
+{
+#warning fixme
+// Service::appLnk("Open/video/mpeg").execute();
+}
+
+void CameraMainWindow::doSettings()
+{
+ bool v = video_supported;
+#ifdef QTOPIA_PHONE
+ bool p;
+ p = a_pview->isEnabled();
+ v = v && a_vview->isEnabled();
+ if (p)
+ settings->photo->show();
+ else
+ settings->photo->hide();
+#endif
+ if (v)
+ settings->video->show();
+ else
+ settings->video->hide();
+ settings->photo_size->setCurrentItem(psize);
+ settings->video_size->setCurrentItem(vsize);
+ settings->photo_quality->setValue(pquality);
+ settings->video_quality->setValue(vquality);
+ settings->video_framerate->setValue(vframerate);
+ settings->video_quality_n->setFixedWidth(fontMetrics().width("100"));
+ settings->photo_quality_n->setFixedWidth(fontMetrics().width("100"));
+
+ if (QPEApplication::execDialog(settings)) {
+ confirmSettings();
+ }
+ else {
+#warning fixme
+// settings->location->setLocation(storagepath);
+ }
+}
+
+void CameraMainWindow::confirmSettings()
+{
+ storagepath = settings->location->documentPath();
+ psize = settings->photo_size->currentItem();
+ vsize = settings->video_size->currentItem();
+ pquality = settings->photo_quality->value();
+ vquality = settings->video_quality->value();
+ vframerate = settings->video_framerate->value();
+
+ // save settings
+ Config cfg("Camera");
+ cfg.setGroup("General");
+ cfg.writeEntry("location", storagepath);
+ cfg.setGroup("Photo");
+ cfg.writeEntry("width", photo_size[psize].width());
+ cfg.writeEntry("quality", pquality);
+ cfg.setGroup("Video");
+ cfg.writeEntry("width", video_size[vsize].width());
+ cfg.writeEntry("quality", vquality);
+ cfg.writeEntry("framerate", vframerate);
+
+ loadThumbs();
+
+ preview();
+}
+
+static int cmpDocLnk(const void *a, const void *b)
+{
+ const DocLnk *la = *(const DocLnk **) a;
+ const DocLnk *lb = *(const DocLnk **) b;
+ QFileInfo fa(la->linkFileKnown()? la->linkFile() : la->file());
+ QFileInfo fb(lb->linkFileKnown()? lb->linkFile() : lb->file());
+ return fa.lastModified().secsTo(fb.lastModified());
+}
+
+void CameraMainWindow::loadThumbs()
+{
+ if (storagepath.isEmpty()) {
+ updateActions();
+ return;
+ }
+
+ DocLnkSet set(storagepath, "image/jpeg");
+ const QList < DocLnk > &l = set.children();
+
+ DocLnk *lnk;
+ DocLnk **array = new DocLnk *[l.count()];
+ int n = 0;
+ for (QListIterator < DocLnk > it(l); (lnk = it.current()); ++it) {
+ if (lnk->categories().contains(camcat))
+ array[n++] = lnk;
+ }
+ qsort(array, n, sizeof(array[0]), cmpDocLnk);
+ for (int i = 0; i < nthumb; i++) {
+ QPixmap pm;
+ if (i < n) {
+ picturefile[i] = *array[i];
+ QImage img = Image::loadScaled(picturefile[i].file(), thumbw, thumbh);
+ pm.convertFromImage(img);
+ }
+ if (pm.isNull()) {
+ thumb[i]->setText("");
+ }
+ else {
+ thumb[i]->setPixmap(pm);
+ }
+ thumb[i]->setEnabled(!pm.isNull());
+ }
+ if (cur_thumb >= 0)
+ selectThumb(cur_thumb);
+
+ if (!camera->videocaptureview->available()) {
+ camera->photo->setEnabled(FALSE);
+ camera->video->setEnabled(FALSE);
+ if (!n) {
+ thumb[0]->setEnabled(FALSE);
+ }
+ else {
+ thumb[0]->setFocus();
+ thumb[0]->setEnabled(TRUE);
+ }
+ }
+
+ updateActions();
+}
+
+void CameraMainWindow::delThumb(int th)
+{
+ switch (QMessageBox::warning(0, tr("Confirmation"),
+ tr("<qt>Delete '%1'?</qt>",
+ "%1 = file name").arg(picturefile[th].name()), QMessageBox::Yes,
+ QMessageBox::No)) {
+ case QMessageBox::Yes:
+ picturefile[th].removeFiles();
+
+ // Rhys Hack - if we have just deleted the last image and there
+ // is no camera connected, then exit the application. This
+ // avoids a focus problem where it is impossible to exit with
+ // the back button due to the focus being in a stupid place.
+ loadThumbs();
+ if (!camera->videocaptureview->available() && !(thumb[0]->isEnabled())) {
+ close();
+ }
+ break;
+ default:
+ //nothing
+ break;
+ }
+}
+
+void CameraMainWindow::pushThumb(const DocLnk & f, const QImage & img)
+{
+ for (int i = nthumb; --i;) {
+ bool en = thumb[i - 1]->isEnabled();
+ thumb[i]->setEnabled(en);
+ picturefile[i] = picturefile[i - 1];
+ const QPixmap *pm = thumb[i - 1]->pixmap();
+ if (en && pm) {
+ thumb[i]->setPixmap(*pm);
+ }
+ else {
+ thumb[i]->setText("");
+ }
+ }
+ QPixmap pm;
+ QSize sz = Image::aspectScaleSize(img.width(), img.height(), thumbw, thumbh);
+ QImage simg = img.smoothScale(sz.width(), sz.height());
+ pm.convertFromImage(simg);
+ thumb[0]->setPixmap(pm);
+ thumb[0]->setEnabled(TRUE);
+ picturefile[0] = f;
+}
+
+void CameraMainWindow::takePhoto()
+{
+ if (camera->photo != focusWidget()) {
+ camera->photo->setFocus();
+ return;
+ }
+ QSize size = photo_size[psize];
+ if (size == camera->videocaptureview->captureSize() ||
+ camera->videocaptureview->refocusDelay() == 0) {
+
+ // We can grab the current image immediately.
+ takePhotoNow();
+
+ }
+ else {
+
+ // Change the camera size and then wait for the camera to refocus.
+ camera->videocaptureview->setCaptureSize(size);
+ refocusTimer->start(camera->videocaptureview->refocusDelay(), TRUE);
+
+ }
+}
+
+void CameraMainWindow::takePhotoNow()
+{
+ QImage img = camera->videocaptureview->image();
+
+ if (inSnapMode()) {
+ QCopEnvelope e(snap_ch, "valueSupplied(QString,QImage)");
+ QSize s = Image::aspectScaleSize(img.width(), img.height(), snap_maxw, snap_maxh);
+ e << snap_id << img.smoothScale(s.width(), s.height());
+ setSnapMode(FALSE);
+ close();
+ }
+ else {
+ DocLnk f;
+ //f.setLocation(storagepath);
+ f.setType("image/jpeg");
+ QDateTime dt = QDateTime::currentDateTime();
+ QString date = dt.toString();
+ f.setName(tr("Photo, " + date));
+
+ QArray < int >c(1);
+ c[0] = camcat;
+ f.setCategories(c);
+ img.save(f.file(), "JPEG", pquality); // Save the image in its original size.
+ f.writeLink();
+ pushThumb(f, img);
+ }
+
+ preview();
+}
+
+bool CameraMainWindow::inSnapMode() const
+{
+ return !snap_ch.isEmpty();
+}
+
+void CameraMainWindow::setSnapMode(bool y)
+{
+ if (y) {
+ camera->thumbs->hide();
+ camera->video->hide();
+ }
+ else {
+ camera->thumbs->show();
+ if (video_supported)
+ camera->video->show();
+ else
+ camera->video->hide();
+ snap_ch = QString::null;
+ }
+}
+
+void CameraMainWindow::toggleVideo()
+{
+ if (recording)
+ stopVideo();
+ else
+ startVideo();
+ recording = !recording;
+ camera->video->setText(recording ? tr("Stop") : tr("Video"));
+ camera->photo->setEnabled(!recording);
+ for (int i = 0; i < nthumb; i++)
+ thumb[i]->setEnabled(!recording && thumb[i]->pixmap());
+}
+
+void CameraMainWindow::startVideo()
+{
+ // XXX eg. MJPG
+}
+void CameraMainWindow::stopVideo()
+{
+}
+
+void CameraMainWindow::thumbClicked(int i)
+{
+ selectThumb(i);
+}
+
+void CameraMainWindow::editThumb()
+{
+ picturefile[cur_thumb].execute();
+}
+
+void CameraMainWindow::selectThumb(int i)
+{
+ cur_thumb = i;
+ if (i >= 0) {
+ QImage img(picturefile[i].file());
+ camera->videocaptureview->setStill(img);
+ thumb[i]->setFocus();
+ }
+ else {
+ camera->videocaptureview->setLive();
+ }
+ a_th_edit->setEnabled(i >= 0);
+ a_th_del->setEnabled(i >= 0);
+ a_th_add->setEnabled(i >= 0);
+ a_send->setEnabled(i >= 0);
+}
+
+void CameraMainWindow::moveToContact()
+{
+ if (cur_thumb >= 0) {
+#warning fixme
+// QCopEnvelope e(Service::channel("Contacts"),"setContactImage(QImage)");
+// QImage img;
+// img.load(picturefile[cur_thumb].file());
+// e << img;
+ }
+}
+
+void CameraMainWindow::delThumb()
+{
+ if (cur_thumb >= 0) {
+ int d = cur_thumb;
+ if (cur_thumb > 0)
+ selectThumb(cur_thumb - 1);
+ delThumb(d);
+ }
+}
+
+void CameraMainWindow::linkChanged(const QString &)
+{
+ loadThumbs();
+}
+
+void CameraMainWindow::appMessage(const QCString & msg, const QByteArray & data)
+{
+ if (msg == "getImage(QCString,QString,int,int,QImage)") {
+ QDataStream ds(data, IO_ReadOnly);
+ ds >> snap_ch >> snap_id >> snap_maxw >> snap_maxh;
+ setSnapMode(TRUE);
+ QPEApplication::setKeepRunning();
+ }
+}
+
+void CameraMainWindow::preview()
+{
+ if (camera->videocaptureview->refocusDelay() > 200) {
+ camera->videocaptureview->setCaptureSize(photo_size[psize]);
+ }
+ else {
+ camera->videocaptureview->setCaptureSize(camera->videocaptureview->
+ recommendedPreviewSize());
+ }
+}
+
+void CameraMainWindow::sendFile()
+{
+ if (cur_thumb >= 0) {
+ //copy file
+ QFile input(picturefile[cur_thumb].file());
+ if (!input.open(IO_ReadOnly)) {
+ return; //error
+ }
+ QFile output(picfile);
+ if (!output.open(IO_WriteOnly)) {
+ return;
+ }
+
+ const int BUFFER_SIZE = 1024;
+ Q_INT8 buffer[BUFFER_SIZE];
+
+ QDataStream srcStr(&input);
+ QDataStream destStr(&output);
+
+ while (!srcStr.atEnd()) {
+ int i = 0;
+ while (!srcStr.atEnd() && i < BUFFER_SIZE) {
+ srcStr >> buffer[i];
+ i++;
+ }
+ for (int k = 0; k < i; k++) {
+ destStr << buffer[k];
+ }
+ }
+
+#warning fixme
+// QCopEnvelope e(Service::channel("Email"),"writeMessage(QString,QString,QStringList,QStringList)");
+// e << QString() << QString() << QStringList() << QStringList( QString( picfile ) );
+ }
+}
+
+void ThumbButton::drawButtonLabel(QPainter * p)
+{
+ const QPixmap *pm = pixmap();
+ if (pm) {
+ QSize s = (size() - pm->size()) / 2;
+ p->drawPixmap(s.width(), s.height(), *pm);
+ }
+}
+
+ThumbButton::ThumbButton(QWidget * parent, const char *name):QToolButton(parent, name)
+{
+}
+
diff --git a/noncore/multimedia/camera2/mainwindow.h b/noncore/multimedia/camera2/mainwindow.h
new file mode 100644
index 0000000..d6c5a7e
--- a/dev/null
+++ b/noncore/multimedia/camera2/mainwindow.h
@@ -0,0 +1,132 @@
+/**********************************************************************
+** Copyright (C) 2000-2006 Trolltech AS. All rights reserved.
+**
+** This file is part of the Qtopia Environment.
+**
+** This program is free software; you can redistribute it and/or modify it
+** under the terms of the GNU General Public License as published by the
+** Free Software Foundation; either version 2 of the License, or (at your
+** option) any later version.
+**
+** A copy of the GNU GPL license version 2 is included in this package as
+** LICENSE.GPL.
+**
+** This program is distributed in the hope that it will be useful, but
+** WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+** See the GNU General Public License for more details.
+**
+** In addition, as a special exception Trolltech gives permission to link
+** the code of this program with Qtopia applications copyrighted, developed
+** and distributed by Trolltech under the terms of the Qtopia Personal Use
+** License Agreement. You must comply with the GNU General Public License
+** in all respects for all of the code used other than the applications
+** licensed under the Qtopia Personal Use License Agreement. If you modify
+** this file, you may extend this exception to your version of the file,
+** but you are not obligated to do so. If you do not wish to do so, delete
+** this exception statement from your version.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+#ifndef MAINWINDOW_H
+#define MAINWINDOW_H
+
+#include "camerabase.h"
+#include <qvaluelist.h>
+#include <qmainwindow.h>
+#include <qpe/applnk.h>
+
+class LocationCombo;
+class QAction;
+class QTimer;
+class CameraSettings;
+
+
+class CameraMainWindow : public QMainWindow
+{
+ Q_OBJECT
+public:
+ static QString appName() { return QString::fromLatin1("camera2"); }
+
+ CameraMainWindow( QWidget *parent=0, const char *name=0, WFlags fl=0 );
+ ~CameraMainWindow();
+
+public slots:
+ void takePhoto();
+ void toggleVideo();
+ void selectThumb(int i);
+ void thumbClicked(int i);
+
+private slots:
+ void viewPictures();
+ void viewVideos();
+ void doSettings();
+ void appMessage(const QCString& msg, const QByteArray& data);
+ void editThumb();
+ void delThumb();
+ void moveToContact();
+ void takePhotoNow();
+ void sendFile();
+ void linkChanged(const QString&);
+
+private:
+ bool event(QEvent* e);
+ void updateActions();
+ void resizeEvent(QResizeEvent*);
+
+ bool eventFilter(QObject*, QEvent*);
+ QString nextFileName();
+ void loadThumbs();
+ void pushThumb(const DocLnk& f, const QImage& img);
+ static const int nthumb = 5;
+ QToolButton* thumb[nthumb];
+ DocLnk picturefile[nthumb];
+ int cur_thumb;
+ void delThumb(int th);
+
+ // Settings
+ void confirmSettings();
+ CameraSettings *settings;
+ QString storagepath;
+ int thumbw;
+ int thumbh;
+ int psize;
+ int vsize;
+ int pquality;
+ int vquality;
+ int vframerate;
+
+ // Snap
+ QCString snap_ch;
+ QString snap_id;
+ int snap_maxw, snap_maxh;
+ bool inSnapMode() const;
+ void setSnapMode(bool);
+
+ CameraBase *camera;
+
+ int namehint;
+ QAction *a_pview, *a_vview, *a_settings;
+ QAction *a_th_edit, *a_th_del, *a_th_add;
+ QAction *a_send;
+ QValueList<QSize> photo_size;
+ QValueList<QSize> video_size;
+
+ QTimer *refocusTimer;
+ QString picfile;
+
+ bool recording;
+ void stopVideo();
+ void startVideo();
+
+ void preview();
+
+ int camcat;
+};
+
+#endif
+
diff --git a/noncore/multimedia/camera2/opie-camera2.control b/noncore/multimedia/camera2/opie-camera2.control
new file mode 100644
index 0000000..a2d0700
--- a/dev/null
+++ b/noncore/multimedia/camera2/opie-camera2.control
@@ -0,0 +1,10 @@
+Package: opie-camera2
+Files: bin/camerapics/camera2 apps/Applications/camera2.desktop
+Priority: optional
+Section: opie/multimedia
+Maintainer: Lorn "ljp" Potter <lorn.potter@trolltech.com>
+Architecture: arm
+Version: 1.0.1$EXTRAVERSION
+Depends: libqpe1, libopiecore2, libopieui2
+Description: A Camera Application
+ A Camera Application to use with Video4Linux.
diff --git a/noncore/multimedia/camera2/thumbbutton.h b/noncore/multimedia/camera2/thumbbutton.h
new file mode 100644
index 0000000..f7ca3b4
--- a/dev/null
+++ b/noncore/multimedia/camera2/thumbbutton.h
@@ -0,0 +1,50 @@
+/**********************************************************************
+** Copyright (C) 2000-2006 Trolltech AS. All rights reserved.
+**
+** This file is part of the Qtopia Environment.
+**
+** This program is free software; you can redistribute it and/or modify it
+** under the terms of the GNU General Public License as published by the
+** Free Software Foundation; either version 2 of the License, or (at your
+** option) any later version.
+**
+** A copy of the GNU GPL license version 2 is included in this package as
+** LICENSE.GPL.
+**
+** This program is distributed in the hope that it will be useful, but
+** WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+** See the GNU General Public License for more details.
+**
+** In addition, as a special exception Trolltech gives permission to link
+** the code of this program with Qtopia applications copyrighted, developed
+** and distributed by Trolltech under the terms of the Qtopia Personal Use
+** License Agreement. You must comply with the GNU General Public License
+** in all respects for all of the code used other than the applications
+** licensed under the Qtopia Personal Use License Agreement. If you modify
+** this file, you may extend this exception to your version of the file,
+** but you are not obligated to do so. If you do not wish to do so, delete
+** this exception statement from your version.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+#ifndef THUMBBUTTON_H
+#define THUMBBUTTON_H
+
+#include <qtoolbutton.h>
+
+class ThumbButton : public QToolButton
+{
+ Q_OBJECT
+public:
+ ThumbButton( QWidget *parent, const char* name );
+
+ void drawButtonLabel( QPainter * );
+};
+
+#endif
+
diff --git a/noncore/multimedia/camera2/videocaptureview.cpp b/noncore/multimedia/camera2/videocaptureview.cpp
new file mode 100644
index 0000000..410634a
--- a/dev/null
+++ b/noncore/multimedia/camera2/videocaptureview.cpp
@@ -0,0 +1,599 @@
+/**********************************************************************
+** Copyright (C) 2000-2006 Trolltech AS. All rights reserved.
+**
+** This file is part of the Qtopia Environment.
+**
+** This program is free software; you can redistribute it and/or modify it
+** under the terms of the GNU General Public License as published by the
+** Free Software Foundation; either version 2 of the License, or (at your
+** option) any later version.
+**
+** A copy of the GNU GPL license version 2 is included in this package as
+** LICENSE.GPL.
+**
+** This program is distributed in the hope that it will be useful, but
+** WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+** See the GNU General Public License for more details.
+**
+** In addition, as a special exception Trolltech gives permission to link
+** the code of this program with Qtopia applications copyrighted, developed
+** and distributed by Trolltech under the terms of the Qtopia Personal Use
+** License Agreement. You must comply with the GNU General Public License
+** in all respects for all of the code used other than the applications
+** licensed under the Qtopia Personal Use License Agreement. If you modify
+** this file, you may extend this exception to your version of the file,
+** but you are not obligated to do so. If you do not wish to do so, delete
+** this exception statement from your version.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+
+#include "videocaptureview.h"
+#include <qimage.h>
+#include <qpainter.h>
+#ifdef Q_WS_QWS
+#include <qgfx_qws.h>
+#include <qdirectpainter_qws.h>
+#endif
+
+#ifdef __linux__
+#define HAVE_VIDEO4LINUX 1
+#endif
+
+#ifdef HAVE_VIDEO4LINUX
+
+#include <sys/types.h>
+#include <sys/ioctl.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <linux/videodev.h>
+#include <errno.h>
+#include <string.h>
+#include <stdlib.h>
+#include <sys/mman.h>
+
+#endif /* HAVE_VIDEO4LINUX */
+
+class VideoCapture {
+ public:
+ VideoCapture();
+ ~VideoCapture();
+
+ bool hasCamera() const;
+ void getCameraImage(QImage & img, bool copy = FALSE);
+
+ QValueList < QSize > photoSizes() const;
+ QValueList < QSize > videoSizes() const;
+
+ QSize recommendedPhotoSize() const;
+ QSize recommendedVideoSize() const;
+ QSize recommendedPreviewSize() const;
+
+ QSize captureSize() const;
+ void setCaptureSize(QSize size);
+
+ uint refocusDelay() const;
+ int minimumFramePeriod() const;
+
+ private:
+#ifdef HAVE_VIDEO4LINUX
+ int fd;
+ int width, height;
+ struct video_capability caps;
+ struct video_mbuf mbuf;
+ unsigned char *frames;
+ int currentFrame;
+
+ void setupCamera(QSize size);
+ void shutdown();
+#endif
+};
+
+#ifdef HAVE_VIDEO4LINUX
+
+#define VIDEO_DEVICE "/dev/video"
+
+bool VideoCapture::hasCamera() const
+{
+ return (fd != -1);
+}
+
+QSize VideoCapture::captureSize() const
+{
+ return QSize(width, height);
+}
+
+uint VideoCapture::refocusDelay() const
+{
+ return 250;
+}
+
+int VideoCapture::minimumFramePeriod() const
+{
+ return 40; // milliseconds
+}
+
+VideoCapture::VideoCapture()
+{
+ setupCamera(QSize(0, 0));
+}
+
+VideoCapture::~VideoCapture()
+{
+ shutdown();
+}
+
+void VideoCapture::setupCamera(QSize size)
+{
+ qWarning(" VideoCapture::setupCamera");
+ // Clear important variables.
+ frames = 0;
+ currentFrame = 0;
+ width = 640;
+ height = 480;
+ caps.minwidth = width;
+ caps.minheight = height;
+ caps.maxwidth = width;
+ caps.maxheight = height;
+
+ // Open the video device.
+ fd = open(VIDEO_DEVICE, O_RDWR);
+ if (fd == -1) {
+ qWarning("%s: %s", VIDEO_DEVICE, strerror(errno));
+ return;
+ }
+
+ // Get the device's current capabilities.
+ memset(&caps, 0, sizeof(caps));
+ if (ioctl(fd, VIDIOCGCAP, &caps) < 0) {
+ qWarning("%s: could not retrieve the video capabilities", VIDEO_DEVICE);
+ close(fd);
+ fd = -1;
+ return;
+ }
+
+ // Change the channel to the first-connected camera, skipping TV inputs.
+ // If there are multiple cameras, this may need to be modified.
+ int chan;
+ struct video_channel chanInfo;
+ qWarning("available video capture inputs:");
+ for (chan = 0; chan < caps.channels; ++chan) {
+ chanInfo.channel = chan;
+ if (ioctl(fd, VIDIOCGCHAN, &chanInfo) >= 0) {
+ if (chanInfo.type == VIDEO_TYPE_CAMERA)
+ qWarning(" %s (camera)", chanInfo.name);
+ else if (chanInfo.type == VIDEO_TYPE_TV)
+ qWarning(" %s (tv)", chanInfo.name);
+ else
+ qWarning(" %s (unknown)", chanInfo.name);
+ }
+ }
+ for (chan = 0; chan < caps.channels; ++chan) {
+ chanInfo.channel = chan;
+ if (ioctl(fd, VIDIOCGCHAN, &chanInfo) >= 0) {
+ if (chanInfo.type == VIDEO_TYPE_CAMERA) {
+ qWarning("selecting camera on input %s", chanInfo.name);
+ if (ioctl(fd, VIDIOCSCHAN, &chan) < 0) {
+ qWarning("%s: could not set the channel", VIDEO_DEVICE);
+ }
+ break;
+ }
+ }
+ }
+
+ // Set the desired picture mode to RGB32.
+ struct video_picture pict;
+ memset(&pict, 0, sizeof(pict));
+ ioctl(fd, VIDIOCGPICT, &pict);
+ pict.palette = VIDEO_PALETTE_RGB32;
+ if (ioctl(fd, VIDIOCSPICT, &pict) < 0) {
+ qWarning("%s: could not set the picture mode", VIDEO_DEVICE);
+ close(fd);
+ fd = -1;
+ return;
+ }
+
+ // Determine the capture size to use. Zero indicates "preview mode".
+ if (size.width() == 0) {
+ size = QSize(caps.minwidth, caps.minheight);
+ }
+
+ // Get the current capture window.
+ struct video_window wind;
+ memset(&wind, 0, sizeof(wind));
+ ioctl(fd, VIDIOCGWIN, &wind);
+
+ // Adjust the capture size to match the camera's aspect ratio.
+ if (caps.maxwidth > 0 && caps.maxheight > 0) {
+ if (size.width() > size.height()) {
+ size = QSize(size.height() * caps.maxwidth / caps.maxheight, size.height());
+ }
+ else {
+ size = QSize(size.width(), size.width() * caps.maxheight / caps.maxwidth);
+ }
+ }
+
+ // Set the new capture window.
+ wind.x = 0;
+ wind.y = 0;
+ wind.width = size.width();
+ wind.height = size.height();
+ if (ioctl(fd, VIDIOCSWIN, &wind) < 0) {
+ qWarning("%s: could not set the capture window", VIDEO_DEVICE);
+ }
+
+ // Re-read the capture window, to see what it was adjusted to.
+ ioctl(fd, VIDIOCGWIN, &wind);
+ width = wind.width;
+ height = wind.height;
+
+ // Enable mmap-based access to the camera.
+ memset(&mbuf, 0, sizeof(mbuf));
+ if (ioctl(fd, VIDIOCGMBUF, &mbuf) < 0) {
+ qWarning("%s: mmap-based camera access is not available", VIDEO_DEVICE);
+ close(fd);
+ fd = -1;
+ return;
+ }
+
+ // Mmap the designated memory region.
+ frames = (unsigned char *) mmap(0, mbuf.size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
+ if (!frames || frames == (unsigned char *) (long) (-1)) {
+ qWarning("%s: could not mmap the device", VIDEO_DEVICE);
+ close(fd);
+ fd = -1;
+ return;
+ }
+
+ // Start capturing of the first frame.
+ struct video_mmap capture;
+ currentFrame = 0;
+ capture.frame = currentFrame;
+ capture.width = width;
+ capture.height = height;
+ capture.format = VIDEO_PALETTE_RGB32;
+ ioctl(fd, VIDIOCMCAPTURE, &capture);
+}
+
+void VideoCapture::shutdown()
+{
+ if (frames != 0) {
+ munmap(frames, mbuf.size);
+ frames = 0;
+ }
+ if (fd != -1) {
+ int flag = 0;
+ ioctl(fd, VIDIOCSYNC, 0);
+ ioctl(fd, VIDIOCCAPTURE, &flag);
+ close(fd);
+ fd = -1;
+ }
+}
+
+void VideoCapture::getCameraImage(QImage & img, bool copy)
+{
+ if (fd == -1) {
+ if (img.isNull()) {
+ img.create(width, height, 32);
+ }
+ return;
+ }
+
+ // Start capturing the next frame (we alternate between 0 and 1).
+ int frame = currentFrame;
+ struct video_mmap capture;
+ if (mbuf.frames > 1) {
+ currentFrame = !currentFrame;
+ capture.frame = currentFrame;
+ capture.width = width;
+ capture.height = height;
+ capture.format = VIDEO_PALETTE_RGB32;
+ ioctl(fd, VIDIOCMCAPTURE, &capture);
+ }
+
+ // Wait for the current frame to complete.
+ ioctl(fd, VIDIOCSYNC, &frame);
+
+ // Create an image that refers directly to the kernel's
+ // frame buffer, to avoid having to copy the data.
+ if (!copy) {
+ img = QImage(frames + mbuf.offsets[frame], width, height, 32, 0, 0, QImage::IgnoreEndian);
+ }
+ else {
+ img.create(width, height, 32);
+ memcpy(img.bits(), frames + mbuf.offsets[frame], width * height * 4);
+ }
+
+ // Queue up another frame if the device only supports one at a time.
+ if (mbuf.frames <= 1) {
+ capture.frame = currentFrame;
+ capture.width = width;
+ capture.height = height;
+ capture.format = VIDEO_PALETTE_RGB32;
+ ioctl(fd, VIDIOCMCAPTURE, &capture);
+ }
+}
+
+QValueList < QSize > VideoCapture::photoSizes() const
+{
+ QValueList < QSize > list;
+ list.append(QSize(caps.maxwidth, caps.maxheight));
+ if (caps.maxwidth != caps.minwidth || caps.maxheight != caps.minheight)
+ list.append(QSize(caps.minwidth, caps.minheight));
+ return list;
+}
+
+QValueList < QSize > VideoCapture::videoSizes() const
+{
+ // We use the same sizes for both.
+ return photoSizes();
+}
+
+QSize VideoCapture::recommendedPhotoSize() const
+{
+ return QSize(caps.maxwidth, caps.maxheight);
+}
+
+QSize VideoCapture::recommendedVideoSize() const
+{
+ return QSize(caps.minwidth, caps.minheight);
+}
+
+QSize VideoCapture::recommendedPreviewSize() const
+{
+ return QSize(caps.minwidth, caps.minheight);
+}
+
+void VideoCapture::setCaptureSize(QSize size)
+{
+ if (size.width() != width || size.height() != height) {
+ shutdown();
+ setupCamera(size);
+ }
+}
+
+#else /* !HAVE_VIDEO4LINUX */
+
+// Dummy implementation for systems without video.
+
+VideoCapture::VideoCapture()
+{
+}
+
+VideoCapture::~VideoCapture()
+{
+}
+
+bool VideoCapture::hasCamera() const
+{
+ return TRUE;
+}
+
+QSize VideoCapture::captureSize() const
+{
+ return QSize(640, 480);
+}
+
+uint VideoCapture::refocusDelay() const
+{
+ return 0;
+}
+
+int VideoCapture::minimumFramePeriod() const
+{
+ return 100;
+}
+
+static unsigned int nextrand()
+{
+#define A 16807
+#define M 2147483647
+#define Q 127773
+#define R 2836
+ static unsigned int rnd = 1;
+ unsigned long hi = rnd / Q;
+ unsigned long lo = rnd % Q;
+ unsigned long test = A * lo - R * hi;
+ if (test > 0)
+ rnd = test;
+ else
+ rnd = test + M;
+ return rnd;
+}
+
+void VideoCapture::getCameraImage(QImage & img, bool)
+{
+ // Just generate something dynamic (rectangles)
+ static QImage cimg;
+ int x, y, w, h;
+ if (cimg.isNull()) {
+ x = y = 0;
+ w = 640;
+ h = 480;
+ cimg.create(w, h, 32);
+ }
+ else {
+ w = nextrand() % (cimg.width() - 10) + 10;
+ h = nextrand() % (cimg.height() - 10) + 10;
+ x = nextrand() % (cimg.width() - w);
+ y = nextrand() % (cimg.height() - h);
+ }
+ QRgb c = qRgb(nextrand() % 255, nextrand() % 255, nextrand() % 255);
+ for (int j = 0; j < h; j++) {
+ QRgb *l = (QRgb *) cimg.scanLine(y + j) + x;
+ for (int i = 0; i < w; i++)
+ l[i] = c;
+ }
+ img = cimg;
+}
+
+QValueList < QSize > VideoCapture::photoSizes() constconst
+{
+ QValueList < QSize > list;
+ list.append(QSize(640, 480));
+ list.append(QSize(320, 240));
+ return list;
+}
+
+QValueList < QSize > VideoCapture::videoSizes() constconst
+{
+ QValueList < QSize > list;
+ list.append(QSize(640, 480));
+ list.append(QSize(320, 240));
+ return list;
+}
+
+QSize VideoCapture::recommendedPhotoSize() const
+{
+ return QSize(640, 480);
+}
+
+QSize VideoCapture::recommendedVideoSize() const
+{
+ return QSize(320, 240);
+}
+
+QSize VideoCapture::recommendedPreviewSize() const
+{
+ return QSize(320, 240);
+}
+
+void VideoCapture::setCaptureSize(QSize size)
+{
+}
+
+#endif /* !HAVE_VIDEO4LINUX */
+
+VideoCaptureView::VideoCaptureView(QWidget * parent, const char *name, WFlags fl):QWidget(parent,
+ name, fl)
+{
+ capture = new VideoCapture();
+ QSizePolicy sp(QSizePolicy::Expanding, QSizePolicy::Expanding);
+ setSizePolicy(sp);
+ tid_update = 0;
+ setLive();
+}
+
+VideoCaptureView::~VideoCaptureView()
+{
+ delete capture;
+}
+
+void VideoCaptureView::setLive(int period)
+{
+ if (tid_update)
+ killTimer(tid_update);
+ if (period == 0)
+ tid_update = startTimer(capture->minimumFramePeriod());
+ else if (period > 0)
+ tid_update = startTimer(period);
+ else
+ tid_update = 0;
+}
+
+void VideoCaptureView::setStill(const QImage & i)
+{
+ setLive(-1);
+ img = i;
+ repaint(TRUE);
+}
+
+QValueList < QSize > VideoCaptureView::photoSizes() const
+{
+ return capture->photoSizes();
+}
+
+QValueList < QSize > VideoCaptureView::videoSizes() const
+{
+ return capture->videoSizes();
+}
+
+QSize VideoCaptureView::recommendedPhotoSize() const
+{
+ return capture->recommendedPhotoSize();
+}
+
+QSize VideoCaptureView::recommendedVideoSize() const
+{
+ return capture->recommendedVideoSize();
+}
+
+QSize VideoCaptureView::recommendedPreviewSize() const
+{
+ return capture->recommendedPreviewSize();
+}
+
+QSize VideoCaptureView::captureSize() const
+{
+ return capture->captureSize();
+}
+
+void VideoCaptureView::setCaptureSize(QSize size)
+{
+ capture->setCaptureSize(size);
+}
+
+uint VideoCaptureView::refocusDelay() const
+{
+ return capture->refocusDelay();
+}
+
+bool VideoCaptureView::available() const
+{
+ return capture->hasCamera();
+}
+
+void VideoCaptureView::paintEvent(QPaintEvent *)
+{
+ if (tid_update && !capture->hasCamera()) {
+ QPainter p(this);
+ p.drawText(rect(), AlignCenter, tr("No Camera"));
+ return;
+ }
+
+ if (tid_update)
+ capture->getCameraImage(img);
+ int w = img.width();
+ int h = img.height();
+
+ if (!w || !h)
+ return;
+
+ if (width() * w > height() * h) {
+ w = w * height() / h;
+ h = height();
+ }
+ else {
+ h = h * width() / w;
+ w = width();
+ }
+
+ if (qt_screen->transformOrientation() == 0) {
+ // Stretch and draw the image.
+ QDirectPainter p(this);
+ QGfx *gfx = p.internalGfx();
+ if (gfx) {
+ gfx->setSource(&img);
+ gfx->setAlphaType(QGfx::IgnoreAlpha);
+ gfx->stretchBlt((width() - w) / 2, (height() - h) / 2, w, h, img.width(), img.height());
+ }
+ }
+ else {
+ // This code is nowhere near efficient enough (hence the above).
+ // TODO - handle rotations during direct painting.
+ QImage scimg = img.smoothScale(w, h);
+ QPainter p(this);
+ p.drawImage((width() - w) / 2, (height() - h) / 2, scimg);
+ }
+}
+
+void VideoCaptureView::timerEvent(QTimerEvent *)
+{
+ repaint(FALSE);
+}
+
diff --git a/noncore/multimedia/camera2/videocaptureview.h b/noncore/multimedia/camera2/videocaptureview.h
new file mode 100644
index 0000000..68c3b68
--- a/dev/null
+++ b/noncore/multimedia/camera2/videocaptureview.h
@@ -0,0 +1,82 @@
+/**********************************************************************
+** Copyright (C) 2000-2006 Trolltech AS. All rights reserved.
+**
+** This file is part of the Qtopia Environment.
+**
+** This program is free software; you can redistribute it and/or modify it
+** under the terms of the GNU General Public License as published by the
+** Free Software Foundation; either version 2 of the License, or (at your
+** option) any later version.
+**
+** A copy of the GNU GPL license version 2 is included in this package as
+** LICENSE.GPL.
+**
+** This program is distributed in the hope that it will be useful, but
+** WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+** See the GNU General Public License for more details.
+**
+** In addition, as a special exception Trolltech gives permission to link
+** the code of this program with Qtopia applications copyrighted, developed
+** and distributed by Trolltech under the terms of the Qtopia Personal Use
+** License Agreement. You must comply with the GNU General Public License
+** in all respects for all of the code used other than the applications
+** licensed under the Qtopia Personal Use License Agreement. If you modify
+** this file, you may extend this exception to your version of the file,
+** but you are not obligated to do so. If you do not wish to do so, delete
+** this exception statement from your version.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+#ifndef VIDEOVIEW_H
+#define VIDEOVIEW_H
+
+#include <qwidget.h>
+#include <qimage.h>
+#include <qvaluelist.h>
+
+class VideoCapture;
+
+
+class VideoCaptureView : public QWidget
+{
+ Q_OBJECT
+
+public:
+ VideoCaptureView( QWidget *parent=0, const char *name=0, WFlags fl=0 );
+ ~VideoCaptureView();
+
+ bool available() const;
+
+ QImage image() const { return img; }
+ void setLive(int period=0);
+ void setStill(const QImage&);
+
+ QValueList<QSize> photoSizes() const;
+ QValueList<QSize> videoSizes() const;
+
+ QSize recommendedPhotoSize() const;
+ QSize recommendedVideoSize() const;
+ QSize recommendedPreviewSize() const;
+
+ QSize captureSize() const;
+ void setCaptureSize( QSize size );
+
+ uint refocusDelay() const;
+
+protected:
+ void paintEvent(QPaintEvent*);
+ void timerEvent(QTimerEvent*);
+
+private:
+ QImage img;
+ int tid_update;
+ VideoCapture *capture;
+};
+
+#endif
+