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) (unidiff)
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 @@
1DESTDIR = $(OPIEDIR)/bin
2TEMPLATE = app
3CONFIG += qte warn_on quick_app
4INTERFACES=camerabase.ui camerasettings.ui
5 HEADERS = mainwindow.h \
6 image.h \
7 thumbbutton.h \
8 videocaptureview.h
9 SOURCES = mainwindow.cpp\
10 image.cpp \
11 videocaptureview.cpp \
12 main.cpp
13
14 TARGET = camera2
15DEFINES += HAVE_VIDEO4LINUX
16
17LIBS += -lopiecore2 -lopieui2
18INCLUDEPATH += $(OPIEDIR)/include
19DEPENDPATH += $(OPIEDIR)/include
20contains(CONFIG,quick-app) {
21 DESTDIR = $(OPIEDIR)/bin
22 DEFINES += NOQUICKLAUNCH
23}
24
25
26include( $(OPIEDIR)/include.pro )
27
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 @@
1/****************************************************************************
2** Form implementation generated from reading ui file 'camerabase.ui'
3**
4** Created: Mon Jul 10 04:21:25 2006
5** by: The User Interface Compiler (uic)
6**
7** WARNING! All changes made in this file will be lost!
8****************************************************************************/
9#include "camerabase.h"
10
11#include <qframe.h>
12#include <qpushbutton.h>
13#include "thumbbutton.h"
14#include "videocaptureview.h"
15#include <qlayout.h>
16#include <qvariant.h>
17#include <qtooltip.h>
18#include <qwhatsthis.h>
19
20/*
21 * Constructs a CameraBase which is a child of 'parent', with the
22 * name 'name' and widget flags set to 'f'
23 */
24CameraBase::CameraBase( QWidget* parent, const char* name, WFlags fl )
25 : QWidget( parent, name, fl )
26{
27 if ( !name )
28 setName( "camera" );
29 resize( 311, 381 );
30 setCaption( tr( "Camera" ) );
31 cameraLayout = new QGridLayout( this );
32 cameraLayout->setSpacing( 0 );
33 cameraLayout->setMargin( 0 );
34
35 Frame3 = new QFrame( this, "Frame3" );
36 Frame3->setFrameShape( QFrame::Panel );
37 Frame3->setFrameShadow( QFrame::Sunken );
38 Frame3->setLineWidth( 4 );
39 Frame3->setMargin( 4 );
40 Frame3->setMidLineWidth( 3 );
41 Frame3Layout = new QVBoxLayout( Frame3 );
42 Frame3Layout->setSpacing( 6 );
43 Frame3Layout->setMargin( 4 );
44
45 videocaptureview = new VideoCaptureView( Frame3, "videocaptureview" );
46 videocaptureview->setSizePolicy( QSizePolicy( (QSizePolicy::SizeType)7, (QSizePolicy::SizeType)7, videocaptureview->sizePolicy().hasHeightForWidth() ) );
47 Frame3Layout->addWidget( videocaptureview );
48
49 cameraLayout->addMultiCellWidget( Frame3, 0, 0, 0, 1 );
50
51 photo = new QPushButton( this, "photo" );
52 photo->setText( tr( "Photo" ) );
53
54 cameraLayout->addWidget( photo, 1, 0 );
55
56 video = new QPushButton( this, "video" );
57 video->setText( tr( "Video" ) );
58
59 cameraLayout->addWidget( video, 1, 1 );
60
61 thumbs = new QFrame( this, "thumbs" );
62 thumbs->setFrameShape( QFrame::NoFrame );
63 thumbs->setFrameShadow( QFrame::Plain );
64 thumbsLayout = new QHBoxLayout( thumbs );
65 thumbsLayout->setSpacing( 0 );
66 thumbsLayout->setMargin( 0 );
67
68 thumb1 = new ThumbButton( thumbs, "thumb1" );
69 thumbsLayout->addWidget( thumb1 );
70
71 thumb2 = new ThumbButton( thumbs, "thumb2" );
72 thumbsLayout->addWidget( thumb2 );
73
74 thumb3 = new ThumbButton( thumbs, "thumb3" );
75 thumbsLayout->addWidget( thumb3 );
76
77 thumb4 = new ThumbButton( thumbs, "thumb4" );
78 thumbsLayout->addWidget( thumb4 );
79
80 thumb5 = new ThumbButton( thumbs, "thumb5" );
81 thumbsLayout->addWidget( thumb5 );
82
83 cameraLayout->addMultiCellWidget( thumbs, 2, 2, 0, 1 );
84}
85
86/*
87 * Destroys the object and frees any allocated resources
88 */
89CameraBase::~CameraBase()
90{
91 // no need to delete child widgets, Qt does it all for us
92}
93
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 @@
1/****************************************************************************
2** Form interface generated from reading ui file 'camerabase.ui'
3**
4** Created: Mon Jul 10 04:21:22 2006
5** by: The User Interface Compiler (uic)
6**
7** WARNING! All changes made in this file will be lost!
8****************************************************************************/
9#ifndef CAMERA_H
10#define CAMERA_H
11
12#include <qvariant.h>
13#include <qwidget.h>
14class QVBoxLayout;
15class QHBoxLayout;
16class QGridLayout;
17class QFrame;
18class QPushButton;
19class ThumbButton;
20class VideoCaptureView;
21
22class CameraBase : public QWidget
23{
24 Q_OBJECT
25
26public:
27 CameraBase( QWidget* parent = 0, const char* name = 0, WFlags fl = 0 );
28 ~CameraBase();
29
30 QFrame* Frame3;
31 VideoCaptureView* videocaptureview;
32 QPushButton* photo;
33 QPushButton* video;
34 QFrame* thumbs;
35 ThumbButton* thumb1;
36 ThumbButton* thumb2;
37 ThumbButton* thumb3;
38 ThumbButton* thumb4;
39 ThumbButton* thumb5;
40
41protected:
42 QGridLayout* cameraLayout;
43 QVBoxLayout* Frame3Layout;
44 QHBoxLayout* thumbsLayout;
45};
46
47#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 @@
1<!DOCTYPE UI><UI>
2<class>CameraBase</class>
3<widget>
4 <class>QWidget</class>
5 <property stdset="1">
6 <name>name</name>
7 <cstring>camera</cstring>
8 </property>
9 <property stdset="1">
10 <name>geometry</name>
11 <rect>
12 <x>0</x>
13 <y>0</y>
14 <width>311</width>
15 <height>381</height>
16 </rect>
17 </property>
18 <property stdset="1">
19 <name>caption</name>
20 <string>Camera</string>
21 </property>
22 <grid>
23 <property stdset="1">
24 <name>margin</name>
25 <number>0</number>
26 </property>
27 <property stdset="1">
28 <name>spacing</name>
29 <number>0</number>
30 </property>
31 <widget row="0" column="0" rowspan="1" colspan="2" >
32 <class>QFrame</class>
33 <property stdset="1">
34 <name>name</name>
35 <cstring>Frame3</cstring>
36 </property>
37 <property stdset="1">
38 <name>frameShape</name>
39 <enum>Panel</enum>
40 </property>
41 <property stdset="1">
42 <name>frameShadow</name>
43 <enum>Sunken</enum>
44 </property>
45 <property stdset="1">
46 <name>lineWidth</name>
47 <number>4</number>
48 </property>
49 <property stdset="1">
50 <name>margin</name>
51 <number>4</number>
52 </property>
53 <property stdset="1">
54 <name>midLineWidth</name>
55 <number>3</number>
56 </property>
57 <property>
58 <name>layoutMargin</name>
59 </property>
60 <vbox>
61 <property stdset="1">
62 <name>margin</name>
63 <number>4</number>
64 </property>
65 <property stdset="1">
66 <name>spacing</name>
67 <number>6</number>
68 </property>
69 <widget>
70 <class>VideoCaptureView</class>
71 <property stdset="1">
72 <name>name</name>
73 <cstring>videocaptureview</cstring>
74 </property>
75 <property stdset="1">
76 <name>sizePolicy</name>
77 <sizepolicy>
78 <hsizetype>7</hsizetype>
79 <vsizetype>7</vsizetype>
80 </sizepolicy>
81 </property>
82 </widget>
83 </vbox>
84 </widget>
85 <widget row="1" column="0" >
86 <class>QPushButton</class>
87 <property stdset="1">
88 <name>name</name>
89 <cstring>photo</cstring>
90 </property>
91 <property stdset="1">
92 <name>text</name>
93 <string>Photo</string>
94 </property>
95 </widget>
96 <widget row="1" column="1" >
97 <class>QPushButton</class>
98 <property stdset="1">
99 <name>name</name>
100 <cstring>video</cstring>
101 </property>
102 <property stdset="1">
103 <name>text</name>
104 <string>Video</string>
105 </property>
106 </widget>
107 <widget row="2" column="0" rowspan="1" colspan="2" >
108 <class>QFrame</class>
109 <property stdset="1">
110 <name>name</name>
111 <cstring>thumbs</cstring>
112 </property>
113 <property stdset="1">
114 <name>frameShape</name>
115 <enum>NoFrame</enum>
116 </property>
117 <property stdset="1">
118 <name>frameShadow</name>
119 <enum>Plain</enum>
120 </property>
121 <hbox>
122 <property stdset="1">
123 <name>margin</name>
124 <number>0</number>
125 </property>
126 <property stdset="1">
127 <name>spacing</name>
128 <number>0</number>
129 </property>
130 <widget>
131 <class>ThumbButton</class>
132 <property stdset="1">
133 <name>name</name>
134 <cstring>thumb1</cstring>
135 </property>
136 </widget>
137 <widget>
138 <class>ThumbButton</class>
139 <property stdset="1">
140 <name>name</name>
141 <cstring>thumb2</cstring>
142 </property>
143 </widget>
144 <widget>
145 <class>ThumbButton</class>
146 <property stdset="1">
147 <name>name</name>
148 <cstring>thumb3</cstring>
149 </property>
150 </widget>
151 <widget>
152 <class>ThumbButton</class>
153 <property stdset="1">
154 <name>name</name>
155 <cstring>thumb4</cstring>
156 </property>
157 </widget>
158 <widget>
159 <class>ThumbButton</class>
160 <property stdset="1">
161 <name>name</name>
162 <cstring>thumb5</cstring>
163 </property>
164 </widget>
165 </hbox>
166 </widget>
167 </grid>
168</widget>
169<customwidgets>
170 <customwidget>
171 <class>VideoCaptureView</class>
172 <header location="local">videocaptureview.h</header>
173 <sizehint>
174 <width>-1</width>
175 <height>-1</height>
176 </sizehint>
177 <container>0</container>
178 <sizepolicy>
179 <hordata>7</hordata>
180 <verdata>7</verdata>
181 </sizepolicy>
182 <pixmap>image0</pixmap>
183 </customwidget>
184 <customwidget>
185 <class>ThumbButton</class>
186 <header location="local">thumbbutton.h</header>
187 <sizehint>
188 <width>-1</width>
189 <height>-1</height>
190 </sizehint>
191 <container>0</container>
192 <sizepolicy>
193 <hordata>5</hordata>
194 <verdata>5</verdata>
195 </sizepolicy>
196 <pixmap>image1</pixmap>
197 </customwidget>
198</customwidgets>
199<images>
200 <image>
201 <name>image0</name>
202 <data format="XPM.GZ" length="646">789c6dd2c10ac2300c00d07bbf2234b7229d1be245fc04c5a3201e4615f430059d0711ff5ddb2e6bb236ec90eed134cb5a19d8ef36602af5ecdbfeeac05dda0798d3abebde87e3faa374d3807fa0d633a52d38d8de6f679fe33fc776e196f53cd010188256a3600a292882096246517815ca99884606e18044a3a40d91824820924265a7923a2e8bcd05f33db1173e002913175f2a6be6d3294871a2d95fa00e8a94ee017b69d339d90df1e77c57ea072ede6758</data>
203 </image>
204 <image>
205 <name>image1</name>
206 <data format="XPM.GZ" length="646">789c6dd2c10ac2300c00d07bbf2234b7229d1ddec44f503c0ae2a154410f53d0ed20e2bf6bdb656dd6861dd23d9a66591b0587fd1654235ebded6f0edcd53e419d87ae7b1f4f9b8f906d0bfe012317426a70b07bdc2f3ec77f8ed6b89559061a0343d06a124cc105596482585094bc0ae599b04646c9018926491b2205e140c485cace25755c175d0a967b622ff900b8cc9c7d29af594ea722d589167f813aa852ba07d94b9dce296e883fe7bb163f23896753</data>
207 </image>
208</images>
209</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 @@
1/****************************************************************************
2** Form implementation generated from reading ui file 'camerasettings.ui'
3**
4** Created: Mon Jul 10 04:21:25 2006
5** by: The User Interface Compiler (uic)
6**
7** WARNING! All changes made in this file will be lost!
8****************************************************************************/
9#include "camerasettings.h"
10
11#include <qcombobox.h>
12#include <qgroupbox.h>
13#include <qlabel.h>
14#include <qpushbutton.h>
15#include <qslider.h>
16#include <qtopia/locationcombo.h>
17#include <qlayout.h>
18#include <qvariant.h>
19#include <qtooltip.h>
20#include <qwhatsthis.h>
21
22/*
23 * Constructs a CameraSettings which is a child of 'parent', with the
24 * name 'name' and widget flags set to 'f'
25 *
26 * The dialog will by default be modeless, unless you set 'modal' to
27 * TRUE to construct a modal dialog.
28 */
29CameraSettings::CameraSettings( QWidget* parent, const char* name, bool modal, WFlags fl )
30 : QDialog( parent, name, modal, fl )
31{
32 if ( !name )
33 setName( "CameraSettings" );
34 resize( 324, 465 );
35 setCaption( tr( "Settings" ) );
36 CameraSettingsLayout = new QVBoxLayout( this );
37 CameraSettingsLayout->setSpacing( 6 );
38 CameraSettingsLayout->setMargin( 11 );
39
40 location = new LocationCombo( this, "location" );
41 CameraSettingsLayout->addWidget( location );
42
43 photo = new QGroupBox( this, "photo" );
44 photo->setTitle( tr( "Photo" ) );
45 photo->setColumnLayout(0, Qt::Vertical );
46 photo->layout()->setSpacing( 0 );
47 photo->layout()->setMargin( 0 );
48 photoLayout = new QVBoxLayout( photo->layout() );
49 photoLayout->setAlignment( Qt::AlignTop );
50 photoLayout->setSpacing( 2 );
51 photoLayout->setMargin( 4 );
52
53 Layout1 = new QHBoxLayout;
54 Layout1->setSpacing( 6 );
55 Layout1->setMargin( 0 );
56
57 TextLabel1 = new QLabel( photo, "TextLabel1" );
58 TextLabel1->setText( tr( "Size" ) );
59 Layout1->addWidget( TextLabel1 );
60
61 photo_size = new QComboBox( FALSE, photo, "photo_size" );
62 photo_size->setSizePolicy( QSizePolicy( (QSizePolicy::SizeType)7, (QSizePolicy::SizeType)0, photo_size->sizePolicy().hasHeightForWidth() ) );
63 Layout1->addWidget( photo_size );
64 photoLayout->addLayout( Layout1 );
65
66 Layout2 = new QHBoxLayout;
67 Layout2->setSpacing( 6 );
68 Layout2->setMargin( 0 );
69
70 TextLabel2 = new QLabel( photo, "TextLabel2" );
71 TextLabel2->setText( tr( "Quality" ) );
72 Layout2->addWidget( TextLabel2 );
73
74 photo_quality = new QSlider( photo, "photo_quality" );
75 photo_quality->setMinValue( 0 );
76 photo_quality->setMaxValue( 100 );
77 photo_quality->setValue( 75 );
78 photo_quality->setOrientation( QSlider::Horizontal );
79 Layout2->addWidget( photo_quality );
80
81 photo_quality_n = new QLabel( photo, "photo_quality_n" );
82 photo_quality_n->setText( tr( "75" ) );
83 Layout2->addWidget( photo_quality_n );
84 photoLayout->addLayout( Layout2 );
85 CameraSettingsLayout->addWidget( photo );
86
87 video = new QGroupBox( this, "video" );
88 video->setTitle( tr( "Video" ) );
89 video->setColumnLayout(0, Qt::Vertical );
90 video->layout()->setSpacing( 0 );
91 video->layout()->setMargin( 0 );
92 videoLayout = new QVBoxLayout( video->layout() );
93 videoLayout->setAlignment( Qt::AlignTop );
94 videoLayout->setSpacing( 2 );
95 videoLayout->setMargin( 4 );
96
97 Layout1_2 = new QHBoxLayout;
98 Layout1_2->setSpacing( 6 );
99 Layout1_2->setMargin( 0 );
100
101 TextLabel1_2 = new QLabel( video, "TextLabel1_2" );
102 TextLabel1_2->setText( tr( "Size" ) );
103 Layout1_2->addWidget( TextLabel1_2 );
104
105 video_size = new QComboBox( FALSE, video, "video_size" );
106 video_size->setSizePolicy( QSizePolicy( (QSizePolicy::SizeType)7, (QSizePolicy::SizeType)0, video_size->sizePolicy().hasHeightForWidth() ) );
107 Layout1_2->addWidget( video_size );
108 videoLayout->addLayout( Layout1_2 );
109
110 Layout2_2 = new QHBoxLayout;
111 Layout2_2->setSpacing( 6 );
112 Layout2_2->setMargin( 0 );
113
114 TextLabel2_2 = new QLabel( video, "TextLabel2_2" );
115 TextLabel2_2->setText( tr( "Quality" ) );
116 Layout2_2->addWidget( TextLabel2_2 );
117
118 video_quality = new QSlider( video, "video_quality" );
119 video_quality->setMinValue( 0 );
120 video_quality->setMaxValue( 100 );
121 video_quality->setValue( 75 );
122 video_quality->setOrientation( QSlider::Horizontal );
123 Layout2_2->addWidget( video_quality );
124
125 video_quality_n = new QLabel( video, "video_quality_n" );
126 video_quality_n->setText( tr( "75" ) );
127 Layout2_2->addWidget( video_quality_n );
128 videoLayout->addLayout( Layout2_2 );
129
130 Layout6 = new QHBoxLayout;
131 Layout6->setSpacing( 6 );
132 Layout6->setMargin( 0 );
133
134 TextLabel4 = new QLabel( video, "TextLabel4" );
135 TextLabel4->setText( tr( "Frame rate" ) );
136 Layout6->addWidget( TextLabel4 );
137
138 video_framerate = new QSlider( video, "video_framerate" );
139 video_framerate->setMinValue( 1 );
140 video_framerate->setMaxValue( 60 );
141 video_framerate->setValue( 5 );
142 video_framerate->setOrientation( QSlider::Horizontal );
143 Layout6->addWidget( video_framerate );
144
145 TextLabel6 = new QLabel( video, "TextLabel6" );
146 TextLabel6->setText( tr( "5" ) );
147 Layout6->addWidget( TextLabel6 );
148 videoLayout->addLayout( Layout6 );
149 CameraSettingsLayout->addWidget( video );
150 QSpacerItem* spacer = new QSpacerItem( 20, 20, QSizePolicy::Minimum, QSizePolicy::Expanding );
151 CameraSettingsLayout->addItem( spacer );
152
153 // signals and slots connections
154 connect( photo_quality, SIGNAL( valueChanged(int) ), photo_quality_n, SLOT( setNum(int) ) );
155 connect( video_quality, SIGNAL( valueChanged(int) ), video_quality_n, SLOT( setNum(int) ) );
156 connect( video_framerate, SIGNAL( valueChanged(int) ), TextLabel6, SLOT( setNum(int) ) );
157}
158
159/*
160 * Destroys the object and frees any allocated resources
161 */
162CameraSettings::~CameraSettings()
163{
164 // no need to delete child widgets, Qt does it all for us
165}
166
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 @@
1/****************************************************************************
2** Form interface generated from reading ui file 'camerasettings.ui'
3**
4** Created: Mon Jul 10 04:21:22 2006
5** by: The User Interface Compiler (uic)
6**
7** WARNING! All changes made in this file will be lost!
8****************************************************************************/
9#ifndef CAMERASETTINGS_H
10#define CAMERASETTINGS_H
11
12#include <qvariant.h>
13#include <qdialog.h>
14class QVBoxLayout;
15class QHBoxLayout;
16class QGridLayout;
17class LocationCombo;
18class QComboBox;
19class QGroupBox;
20class QLabel;
21class QSlider;
22
23class CameraSettings : public QDialog
24{
25 Q_OBJECT
26
27public:
28 CameraSettings( QWidget* parent = 0, const char* name = 0, bool modal = FALSE, WFlags fl = 0 );
29 ~CameraSettings();
30
31 LocationCombo* location;
32 QGroupBox* photo;
33 QLabel* TextLabel1;
34 QComboBox* photo_size;
35 QLabel* TextLabel2;
36 QSlider* photo_quality;
37 QLabel* photo_quality_n;
38 QGroupBox* video;
39 QLabel* TextLabel1_2;
40 QComboBox* video_size;
41 QLabel* TextLabel2_2;
42 QSlider* video_quality;
43 QLabel* video_quality_n;
44 QLabel* TextLabel4;
45 QSlider* video_framerate;
46 QLabel* TextLabel6;
47
48protected:
49 QVBoxLayout* CameraSettingsLayout;
50 QVBoxLayout* photoLayout;
51 QHBoxLayout* Layout1;
52 QHBoxLayout* Layout2;
53 QVBoxLayout* videoLayout;
54 QHBoxLayout* Layout1_2;
55 QHBoxLayout* Layout2_2;
56 QHBoxLayout* Layout6;
57};
58
59#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 @@
1<!DOCTYPE UI><UI>
2<class>CameraSettings</class>
3<widget>
4 <class>QDialog</class>
5 <property stdset="1">
6 <name>name</name>
7 <cstring>CameraSettings</cstring>
8 </property>
9 <property stdset="1">
10 <name>geometry</name>
11 <rect>
12 <x>0</x>
13 <y>0</y>
14 <width>324</width>
15 <height>465</height>
16 </rect>
17 </property>
18 <property stdset="1">
19 <name>caption</name>
20 <string>Settings</string>
21 </property>
22 <property>
23 <name>layoutMargin</name>
24 </property>
25 <property>
26 <name>layoutSpacing</name>
27 </property>
28 <vbox>
29 <property stdset="1">
30 <name>margin</name>
31 <number>11</number>
32 </property>
33 <property stdset="1">
34 <name>spacing</name>
35 <number>6</number>
36 </property>
37 <widget>
38 <class>LocationCombo</class>
39 <property stdset="1">
40 <name>name</name>
41 <cstring>location</cstring>
42 </property>
43 </widget>
44 <widget>
45 <class>QGroupBox</class>
46 <property stdset="1">
47 <name>name</name>
48 <cstring>photo</cstring>
49 </property>
50 <property stdset="1">
51 <name>title</name>
52 <string>Photo</string>
53 </property>
54 <property>
55 <name>layoutMargin</name>
56 </property>
57 <property>
58 <name>layoutSpacing</name>
59 </property>
60 <vbox>
61 <property stdset="1">
62 <name>margin</name>
63 <number>4</number>
64 </property>
65 <property stdset="1">
66 <name>spacing</name>
67 <number>2</number>
68 </property>
69 <widget>
70 <class>QLayoutWidget</class>
71 <property stdset="1">
72 <name>name</name>
73 <cstring>Layout1</cstring>
74 </property>
75 <hbox>
76 <property stdset="1">
77 <name>margin</name>
78 <number>0</number>
79 </property>
80 <property stdset="1">
81 <name>spacing</name>
82 <number>6</number>
83 </property>
84 <widget>
85 <class>QLabel</class>
86 <property stdset="1">
87 <name>name</name>
88 <cstring>TextLabel1</cstring>
89 </property>
90 <property stdset="1">
91 <name>text</name>
92 <string>Size</string>
93 </property>
94 </widget>
95 <widget>
96 <class>QComboBox</class>
97 <property stdset="1">
98 <name>name</name>
99 <cstring>photo_size</cstring>
100 </property>
101 <property stdset="1">
102 <name>sizePolicy</name>
103 <sizepolicy>
104 <hsizetype>7</hsizetype>
105 <vsizetype>0</vsizetype>
106 </sizepolicy>
107 </property>
108 </widget>
109 </hbox>
110 </widget>
111 <widget>
112 <class>QLayoutWidget</class>
113 <property stdset="1">
114 <name>name</name>
115 <cstring>Layout2</cstring>
116 </property>
117 <hbox>
118 <property stdset="1">
119 <name>margin</name>
120 <number>0</number>
121 </property>
122 <property stdset="1">
123 <name>spacing</name>
124 <number>6</number>
125 </property>
126 <widget>
127 <class>QLabel</class>
128 <property stdset="1">
129 <name>name</name>
130 <cstring>TextLabel2</cstring>
131 </property>
132 <property stdset="1">
133 <name>text</name>
134 <string>Quality</string>
135 </property>
136 </widget>
137 <widget>
138 <class>QSlider</class>
139 <property stdset="1">
140 <name>name</name>
141 <cstring>photo_quality</cstring>
142 </property>
143 <property stdset="1">
144 <name>minValue</name>
145 <number>0</number>
146 </property>
147 <property stdset="1">
148 <name>maxValue</name>
149 <number>100</number>
150 </property>
151 <property stdset="1">
152 <name>value</name>
153 <number>75</number>
154 </property>
155 <property stdset="1">
156 <name>orientation</name>
157 <enum>Horizontal</enum>
158 </property>
159 </widget>
160 <widget>
161 <class>QLabel</class>
162 <property stdset="1">
163 <name>name</name>
164 <cstring>photo_quality_n</cstring>
165 </property>
166 <property stdset="1">
167 <name>text</name>
168 <string>75</string>
169 </property>
170 </widget>
171 </hbox>
172 </widget>
173 </vbox>
174 </widget>
175 <widget>
176 <class>QGroupBox</class>
177 <property stdset="1">
178 <name>name</name>
179 <cstring>video</cstring>
180 </property>
181 <property stdset="1">
182 <name>title</name>
183 <string>Video</string>
184 </property>
185 <property>
186 <name>layoutMargin</name>
187 </property>
188 <property>
189 <name>layoutSpacing</name>
190 </property>
191 <vbox>
192 <property stdset="1">
193 <name>margin</name>
194 <number>4</number>
195 </property>
196 <property stdset="1">
197 <name>spacing</name>
198 <number>2</number>
199 </property>
200 <widget>
201 <class>QLayoutWidget</class>
202 <property stdset="1">
203 <name>name</name>
204 <cstring>Layout1_2</cstring>
205 </property>
206 <hbox>
207 <property stdset="1">
208 <name>margin</name>
209 <number>0</number>
210 </property>
211 <property stdset="1">
212 <name>spacing</name>
213 <number>6</number>
214 </property>
215 <widget>
216 <class>QLabel</class>
217 <property stdset="1">
218 <name>name</name>
219 <cstring>TextLabel1_2</cstring>
220 </property>
221 <property stdset="1">
222 <name>text</name>
223 <string>Size</string>
224 </property>
225 </widget>
226 <widget>
227 <class>QComboBox</class>
228 <property stdset="1">
229 <name>name</name>
230 <cstring>video_size</cstring>
231 </property>
232 <property stdset="1">
233 <name>sizePolicy</name>
234 <sizepolicy>
235 <hsizetype>7</hsizetype>
236 <vsizetype>0</vsizetype>
237 </sizepolicy>
238 </property>
239 </widget>
240 </hbox>
241 </widget>
242 <widget>
243 <class>QLayoutWidget</class>
244 <property stdset="1">
245 <name>name</name>
246 <cstring>Layout2_2</cstring>
247 </property>
248 <hbox>
249 <property stdset="1">
250 <name>margin</name>
251 <number>0</number>
252 </property>
253 <property stdset="1">
254 <name>spacing</name>
255 <number>6</number>
256 </property>
257 <widget>
258 <class>QLabel</class>
259 <property stdset="1">
260 <name>name</name>
261 <cstring>TextLabel2_2</cstring>
262 </property>
263 <property stdset="1">
264 <name>text</name>
265 <string>Quality</string>
266 </property>
267 </widget>
268 <widget>
269 <class>QSlider</class>
270 <property stdset="1">
271 <name>name</name>
272 <cstring>video_quality</cstring>
273 </property>
274 <property stdset="1">
275 <name>minValue</name>
276 <number>0</number>
277 </property>
278 <property stdset="1">
279 <name>maxValue</name>
280 <number>100</number>
281 </property>
282 <property stdset="1">
283 <name>value</name>
284 <number>75</number>
285 </property>
286 <property stdset="1">
287 <name>orientation</name>
288 <enum>Horizontal</enum>
289 </property>
290 </widget>
291 <widget>
292 <class>QLabel</class>
293 <property stdset="1">
294 <name>name</name>
295 <cstring>video_quality_n</cstring>
296 </property>
297 <property stdset="1">
298 <name>text</name>
299 <string>75</string>
300 </property>
301 </widget>
302 </hbox>
303 </widget>
304 <widget>
305 <class>QLayoutWidget</class>
306 <property stdset="1">
307 <name>name</name>
308 <cstring>Layout6</cstring>
309 </property>
310 <hbox>
311 <property stdset="1">
312 <name>margin</name>
313 <number>0</number>
314 </property>
315 <property stdset="1">
316 <name>spacing</name>
317 <number>6</number>
318 </property>
319 <widget>
320 <class>QLabel</class>
321 <property stdset="1">
322 <name>name</name>
323 <cstring>TextLabel4</cstring>
324 </property>
325 <property stdset="1">
326 <name>text</name>
327 <string>Frame rate</string>
328 </property>
329 </widget>
330 <widget>
331 <class>QSlider</class>
332 <property stdset="1">
333 <name>name</name>
334 <cstring>video_framerate</cstring>
335 </property>
336 <property stdset="1">
337 <name>minValue</name>
338 <number>1</number>
339 </property>
340 <property stdset="1">
341 <name>maxValue</name>
342 <number>60</number>
343 </property>
344 <property stdset="1">
345 <name>value</name>
346 <number>5</number>
347 </property>
348 <property stdset="1">
349 <name>orientation</name>
350 <enum>Horizontal</enum>
351 </property>
352 </widget>
353 <widget>
354 <class>QLabel</class>
355 <property stdset="1">
356 <name>name</name>
357 <cstring>TextLabel6</cstring>
358 </property>
359 <property stdset="1">
360 <name>text</name>
361 <string>5</string>
362 </property>
363 </widget>
364 </hbox>
365 </widget>
366 </vbox>
367 </widget>
368 <spacer>
369 <property>
370 <name>name</name>
371 <cstring>Spacer1</cstring>
372 </property>
373 <property stdset="1">
374 <name>orientation</name>
375 <enum>Vertical</enum>
376 </property>
377 <property stdset="1">
378 <name>sizeType</name>
379 <enum>Expanding</enum>
380 </property>
381 <property>
382 <name>sizeHint</name>
383 <size>
384 <width>20</width>
385 <height>20</height>
386 </size>
387 </property>
388 </spacer>
389 </vbox>
390</widget>
391<customwidgets>
392 <customwidget>
393 <class>LocationCombo</class>
394 <header location="global">qtopia/locationcombo.h</header>
395 <sizehint>
396 <width>-1</width>
397 <height>-1</height>
398 </sizehint>
399 <container>0</container>
400 <sizepolicy>
401 <hordata>5</hordata>
402 <verdata>5</verdata>
403 </sizepolicy>
404 <pixmap>image0</pixmap>
405 </customwidget>
406</customwidgets>
407<images>
408 <image>
409 <name>image0</name>
410 <data format="XPM.GZ" length="646">789c6dd2c10ac2300c00d07bbf2234b7229d1be245fc04c5a3201e4615f430059d0711ff5ddb2e6bb236ec90eed134cb5a19d8ef36602af5ecdbfeeac05dda0798d3abebde87e3faa374d3807fa0d633a52d38d8de6f679fe33fc776e196f53cd010188256a3600a292882096246517815ca99884606e18044a3a40d91824820924265a7923a2e8bcd05f33db1173e002913175f2a6be6d3294871a2d95fa00e8a94ee017b69d339d90df1e77c57ea072ede6758</data>
411 </image>
412</images>
413<connections>
414 <connection>
415 <sender>photo_quality</sender>
416 <signal>valueChanged(int)</signal>
417 <receiver>photo_quality_n</receiver>
418 <slot>setNum(int)</slot>
419 </connection>
420 <connection>
421 <sender>video_quality</sender>
422 <signal>valueChanged(int)</signal>
423 <receiver>video_quality_n</receiver>
424 <slot>setNum(int)</slot>
425 </connection>
426 <connection>
427 <sender>video_framerate</sender>
428 <signal>valueChanged(int)</signal>
429 <receiver>TextLabel6</receiver>
430 <slot>setNum(int)</slot>
431 </connection>
432</connections>
433</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 @@
1 config CAMERA2
2 boolean "opie-camera2 (camera app to use with Video4Linux)"
3 default "n"
4 depends ( LIBQPE || LIBQPE-X11 ) && LIBOPIE2CORE && LIBOPIE2UI
5 comment "opie-camera needs a libqpe, libopie2core & libopie2ui"
6 depends !(( LIBQPE || LIBQPE-X11 ) && LIBOPIE2CORE && LIBOPIE2UI )
7
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 @@
1/**********************************************************************
2** Copyright (C) 2000-2006 Trolltech AS. All rights reserved.
3**
4** This file is part of the Qtopia Environment.
5**
6** This program is free software; you can redistribute it and/or modify it
7** under the terms of the GNU General Public License as published by the
8** Free Software Foundation; either version 2 of the License, or (at your
9** option) any later version.
10**
11** A copy of the GNU GPL license version 2 is included in this package as
12** LICENSE.GPL.
13**
14** This program is distributed in the hope that it will be useful, but
15** WITHOUT ANY WARRANTY; without even the implied warranty of
16** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
17** See the GNU General Public License for more details.
18**
19** In addition, as a special exception Trolltech gives permission to link
20** the code of this program with Qtopia applications copyrighted, developed
21** and distributed by Trolltech under the terms of the Qtopia Personal Use
22** License Agreement. You must comply with the GNU General Public License
23** in all respects for all of the code used other than the applications
24** licensed under the Qtopia Personal Use License Agreement. If you modify
25** this file, you may extend this exception to your version of the file,
26** but you are not obligated to do so. If you do not wish to do so, delete
27** this exception statement from your version.
28**
29** See http://www.trolltech.com/gpl/ for GPL licensing information.
30**
31** Contact info@trolltech.com if any conditions of this licensing are
32** not clear to you.
33**
34**********************************************************************/
35
36#include "image.h"
37
38#include <qfileinfo.h>
39#include <qimage.h>
40#include <qstring.h>
41
42/*!
43 Returns an image created by loading the \a filename,
44 and scalining it, preserving aspect ratio, to fit in
45 \a width by \a height pixels.
46
47 First availability: Qtopia 2.0
48*/
49QImage Image::loadScaled(const QString & filename, const int width, const int height,
50 ScaleMode mode)
51{
52 QImageIO iio;
53 QString param;
54 int w = width;
55 int h = height;
56
57 if (width == 0 || height == 0)
58 return QImage();
59
60 iio.setFileName(filename);
61
62 //
63 // Try and load and scale the image in one hit.
64 //
65 param.sprintf("GetHeaderInformation");
66 iio.setParameters(param);
67 iio.read();
68
69 //
70 // If we don't have bits(), read() understands parameters,
71 // and we can setup for fast reading. Otherwise, take the
72 // performance hit and do things slowly.
73 //
74 if (!iio.image().bits()) {
75 if ((iio.image().width() < w) && (iio.image().height() < h)) {
76 param.sprintf("%s", "Fast"); // No Tr
77 }
78 else {
79 int shrink_factor = 1;
80 QString smode;
81 switch (mode) {
82 case ScaleMin:
83 smode = "ScaleMin";
84 shrink_factor = QMAX(iio.image().width() / w, iio.image().height() / h);
85 break;
86 case ScaleMax:
87 smode = "ScaleMax";
88 shrink_factor = QMIN(iio.image().width() / w, iio.image().height() / h);
89 break;
90 case ScaleFree:
91 smode = "ScaleFree";
92 shrink_factor = QMIN(iio.image().width() / w, iio.image().height() / h);
93 break;
94 }
95 param.sprintf("Scale( %i, %i, %s )%s, Shrink( %i )", // No tr
96 w, h, smode.latin1(), ", Fast", shrink_factor); // No tr
97 }
98
99 iio.setParameters(param);
100 iio.read();
101 return iio.image();
102 }
103
104 if ((iio.image().width() > w) || (iio.image().height() > h)) {
105 QSize s = aspectScaleSize(iio.image().width(), iio.image().height(), w, h, mode);
106 return iio.image().smoothScale(s.width(), s.height());
107 }
108
109 return iio.image();
110}
111
112//
113// Returns new size of image, scaled to target_width and target_height,
114// whilst preserving aspect ratio. Useful when it's not possible to
115// scale an image prior to using it (eg. using RichText). Should be in
116// global image utils.
117//
118// NOTE
119// - expensive for images whose drivers do not allow us to retrieve
120// parameters without reading the entire image. Currently (20030930)
121// only the jpeg driver allows parameter reading.
122//
123QSize Image::loadScaledImageSize(const QString & filename, int target_width, int target_height,
124 int maxscale, ScaleMode mode)
125{
126 QImageIO iio;
127 iio.setFileName(filename);
128 iio.setParameters("GetHeaderInformation");
129 iio.read();
130
131 int w = iio.image().width();
132 int h = iio.image().height();
133
134 //
135 // Scaling up small pictures can be very ugly.
136 // Leave them alone if they are too small.
137 //
138 if (maxscale && w * maxscale < target_width && h * maxscale < target_height)
139 return QSize(w * maxscale, h * maxscale);
140
141 return aspectScaleSize(w, h, target_width, target_height, mode);
142}
143
144// Load an image to be used as a portrait. Force its height to height,
145// scale width to new height, and crop the width if it's still > width
146// XXX : Should be using integer math
147QImage Image::loadPortrait(const QString & filename, const int width, const int height)
148{
149 QImageIO iio;
150 QString param;
151 int w = width;
152 int h = height;
153
154 if (width == 0 || height == 0)
155 return QImage();
156
157 iio.setFileName(filename);
158
159 //
160 // Try and load and scale the image in one hit.
161 //
162 param.sprintf("GetHeaderInformation");
163 iio.setParameters(param);
164 iio.read();
165
166 //
167 // If we don't have bits(), read() understands parameters,
168 // and we can setup for fast reading. Otherwise, take the
169 // performance hit and do things slowly.
170 //
171 if (!iio.image().bits()) {
172
173 w = (int) ((double) iio.image().width() / (double) (iio.image().height()) *
174 (double) height);
175 param.sprintf("Scale( %i, %i, ScaleFree )%s", // No tr
176 w, h, ", Fast"); // No tr
177
178 iio.setParameters(param);
179 iio.read();
180
181 if (w > width) {
182 int x = (int) ((double) (w - width) / 2);
183 QRect r(x, 0, width, height);
184 return iio.image().copy(r);
185 }
186 else
187 return iio.image();
188 }
189 else
190 //scale width to the new height
191 return sizeToPortrait(iio.image(), width, height);
192}
193
194QImage Image::sizeToPortrait(const QImage & image, const int width, const int height)
195{
196 int w = (image.width() * height) / image.height();
197 if (w > width) {
198 int x = (w - width) / 2;
199 QRect r(x, 0, width, height);
200 return image.smoothScale(w, height).copy(r);
201 }
202 else
203 return image.smoothScale(width, height);
204}
205
206//
207// Return (w x h) scaled to (target_width x target_height) with aspect
208// ratio preserved.
209//
210QSize
211 Image::aspectScaleSize(const int w, const int h, const int target_width,
212 const int target_height, ScaleMode mode)
213{
214 QSize s;
215 if (mode == ScaleFree) {
216 s = QSize(target_width, target_height);
217 }
218 else {
219 bool useHeight = TRUE;
220 int rw = target_height * w / h;
221
222 if (mode == ScaleMin) {
223 useHeight = (rw <= target_width);
224 }
225 else { // mode == ScaleMax
226 useHeight = (rw >= target_width);
227 }
228
229 if (useHeight) {
230 s = QSize(rw, target_height);
231 }
232 else {
233 s = QSize(target_width, target_width * h / w);
234 }
235 }
236
237 return s;
238}
239
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 @@
1/**********************************************************************
2** Copyright (C) 2000-2006 Trolltech AS. All rights reserved.
3**
4** This file is part of the Qtopia Environment.
5**
6** This program is free software; you can redistribute it and/or modify it
7** under the terms of the GNU General Public License as published by the
8** Free Software Foundation; either version 2 of the License, or (at your
9** option) any later version.
10**
11** A copy of the GNU GPL license version 2 is included in this package as
12** LICENSE.GPL.
13**
14** This program is distributed in the hope that it will be useful, but
15** WITHOUT ANY WARRANTY; without even the implied warranty of
16** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
17** See the GNU General Public License for more details.
18**
19** In addition, as a special exception Trolltech gives permission to link
20** the code of this program with Qtopia applications copyrighted, developed
21** and distributed by Trolltech under the terms of the Qtopia Personal Use
22** License Agreement. You must comply with the GNU General Public License
23** in all respects for all of the code used other than the applications
24** licensed under the Qtopia Personal Use License Agreement. If you modify
25** this file, you may extend this exception to your version of the file,
26** but you are not obligated to do so. If you do not wish to do so, delete
27** this exception statement from your version.
28**
29** See http://www.trolltech.com/gpl/ for GPL licensing information.
30**
31** Contact info@trolltech.com if any conditions of this licensing are
32** not clear to you.
33**
34**********************************************************************/
35
36#ifndef IMAGE_H
37#define IMAGE_H
38
39#include <qimage.h>
40#include <qtopia/qpeglobal.h>
41
42class Image {
43public:
44 // namespace
45 enum ScaleMode { ScaleFree, ScaleMin, ScaleMax };
46 static QImage loadScaled(const QString &filename, const int width, const int height, ScaleMode mode=ScaleMin);
47 static QSize loadScaledImageSize(const QString &filename, int target_width, int target_height, int maxscale=1, ScaleMode mode=ScaleMin);
48 static QImage loadPortrait(const QString &filename, const int width, const int height);
49 static QImage sizeToPortrait(const QImage &image, const int width, const int height);
50 static QSize aspectScaleSize(const int w, const int h, const int target_width, const int target_height, ScaleMode mode=ScaleMin);
51};
52
53#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 @@
1/**********************************************************************
2** Copyright (C) 2000-2006 Trolltech AS. All rights reserved.
3**
4** This file is part of the Qtopia Environment.
5**
6** This program is free software; you can redistribute it and/or modify it
7** under the terms of the GNU General Public License as published by the
8** Free Software Foundation; either version 2 of the License, or (at your
9** option) any later version.
10**
11** A copy of the GNU GPL license version 2 is included in this package as
12** LICENSE.GPL.
13**
14** This program is distributed in the hope that it will be useful, but
15** WITHOUT ANY WARRANTY; without even the implied warranty of
16** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
17** See the GNU General Public License for more details.
18**
19** In addition, as a special exception Trolltech gives permission to link
20** the code of this program with Qtopia applications copyrighted, developed
21** and distributed by Trolltech under the terms of the Qtopia Personal Use
22** License Agreement. You must comply with the GNU General Public License
23** in all respects for all of the code used other than the applications
24** licensed under the Qtopia Personal Use License Agreement. If you modify
25** this file, you may extend this exception to your version of the file,
26** but you are not obligated to do so. If you do not wish to do so, delete
27** this exception statement from your version.
28**
29** See http://www.trolltech.com/gpl/ for GPL licensing information.
30**
31** Contact info@trolltech.com if any conditions of this licensing are
32** not clear to you.
33**
34**********************************************************************/
35
36#include "mainwindow.h"
37#include <opie2/oapplication.h>
38#include <opie2/oapplicationfactory.h>
39
40using namespace Opie::Core;
41OPIE_EXPORT_APP(OApplicationFactory < CameraMainWindow >)
42// QTOPIA_ADD_APPLICATION("camera",CameraMainWindow)
43// QTOPIA_MAIN
44
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 @@
1/**********************************************************************
2 ** Copyright (C) 2000-2006 Trolltech AS. All rights reserved.
3 **
4 ** This file is part of the Qtopia Environment.
5 **
6 ** This program is free software; you can redistribute it and/or modify it
7 ** under the terms of the GNU General Public License as published by the
8 ** Free Software Foundation; either version 2 of the License, or (at your
9 ** option) any later version.
10 **
11 ** A copy of the GNU GPL license version 2 is included in this package as
12 ** LICENSE.GPL.
13 **
14 ** This program is distributed in the hope that it will be useful, but
15 ** WITHOUT ANY WARRANTY; without even the implied warranty of
16 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
17 ** See the GNU General Public License for more details.
18 **
19 ** In addition, as a special exception Trolltech gives permission to link
20 ** the code of this program with Qtopia applications copyrighted, developed
21 ** and distributed by Trolltech under the terms of the Qtopia Personal Use
22 ** License Agreement. You must comply with the GNU General Public License
23 ** in all respects for all of the code used other than the applications
24 ** licensed under the Qtopia Personal Use License Agreement. If you modify
25 ** this file, you may extend this exception to your version of the file,
26 ** but you are not obligated to do so. If you do not wish to do so, delete
27 ** this exception statement from your version.
28 **
29 ** See http://www.trolltech.com/gpl/ for GPL licensing information.
30 **
31 ** Contact info@trolltech.com if any conditions of this licensing are
32 ** not clear to you.
33 **
34 **********************************************************************/
35
36#define QTOPIA_INTERNAL_FILEOPERATIONS
37#include "mainwindow.h"
38#include "videocaptureview.h"
39#include "camerasettings.h"
40#include "thumbbutton.h"
41
42#include "image.h"
43
44/* OPIE */
45#include <opie2/odebug.h>
46#include <opie2/oresource.h>
47using namespace Opie::Core;
48
49#include <qpe/config.h>
50#include <qpe/qpeapplication.h>
51#include <qpe/locationcombo.h>
52//#include <qtopia/contextmenu.h>
53#include <qpe/qcopenvelope_qws.h>
54#include <qpe/resource.h>
55//#include <qtopia/services.h>
56#include <qpe/categories.h>
57#include <qpe/qpetoolbar.h>
58#include <qpe/global.h>
59
60#include <qaction.h>
61#include <qlabel.h>
62#include <qtoolbutton.h>
63#include <qpushbutton.h>
64#include <qgroupbox.h>
65#include <qsignalmapper.h>
66#include <qdir.h>
67#include <qimage.h>
68#include <qslider.h>
69#include <qtimer.h>
70#include <qmessagebox.h>
71
72#include <stdlib.h>
73
74#include <sys/types.h>
75#include <sys/stat.h>
76
77static const int thmarg = 2;
78static const bool video_supported = FALSE;
79
80CameraMainWindow::CameraMainWindow(QWidget * parent, const char *name, WFlags f)
81:QMainWindow(parent, name, f)
82{
83 setCaption(tr("Camera"));
84
85 picfile = Global::tempDir() + "image.jpg";
86 camera = new CameraBase(this);
87 setCentralWidget(camera);
88
89 connect(qApp, SIGNAL(appMessage(const QCString &, const QByteArray &)),
90 this, SLOT(appMessage(const QCString &, const QByteArray &)));
91 connect(qApp, SIGNAL(linkChanged(const QString &)), this, SLOT(linkChanged(const QString &)));
92
93 Categories cats;
94 cats.load(categoryFileName());
95 camcat = cats.id("Document View", "_Camera"); // No tr
96 if (!camcat) {
97 camcat = cats.addCategory("Document View", "_Camera"); // No tr
98 cats.save(categoryFileName());
99 }
100
101 camera->photo->setFocus();
102
103 connect(camera->photo, SIGNAL(clicked()), this, SLOT(takePhoto()));
104 connect(camera->video, SIGNAL(clicked()), this, SLOT(toggleVideo()));
105
106 refocusTimer = new QTimer(this);
107 connect(refocusTimer, SIGNAL(timeout()), this, SLOT(takePhotoNow()));
108
109 thumb[0] = camera->thumb1;
110 thumb[1] = camera->thumb2;
111 thumb[2] = camera->thumb3;
112 thumb[3] = camera->thumb4;
113 thumb[4] = camera->thumb5;
114 cur_thumb = -1;
115
116 QSignalMapper *sm = new QSignalMapper(this);
117 for (int i = 0; i < nthumb; i++) {
118 sm->setMapping(thumb[i], i);
119 connect(thumb[i], SIGNAL(clicked()), sm, SLOT(map()));
120 thumb[i]->installEventFilter(this);
121 }
122 connect(sm, SIGNAL(mapped(int)), this, SLOT(thumbClicked(int)));
123
124#warning fixme
125// AppLnk picture_viewer = Service::appLnk("PhotoEdit");
126// AppLnk video_viewer = Service::appLnk("Open/video/mpeg");
127
128 a_pview = new QAction(tr("%1...", "app name").arg("" /*picture_viewer.name() */ ),
129 Resource::loadPixmap(NULL /*picture_viewer.icon() */ ), QString::null, 0,
130 this, 0);
131 connect(a_pview, SIGNAL(activated()), this, SLOT(viewPictures()));
132 a_vview = new QAction(tr("%1...", "app name").arg("" /*video_viewer.name() */ ),
133 Resource::loadIconSet(NULL /*video_viewer.icon() */ ), QString::null, 0,
134 this, 0);
135 connect(a_vview, SIGNAL(activated()), this, SLOT(viewVideos()));
136
137 a_settings =
138 new QAction(tr("Settings..."), Opie::Core::OResource::loadPixmap("camera2/settings", Opie::Core::OResource::SmallIcon),
139 QString::null, 0, this, 0);
140 connect(a_settings, SIGNAL(activated()), this, SLOT(doSettings()));
141
142 a_th_edit = new QAction(tr("Edit"), Opie::Core::OResource::loadPixmap("edit", Opie::Core::OResource::SmallIcon),
143 QString::null, 0, this, 0);
144 connect(a_th_edit, SIGNAL(activated()), this, SLOT(editThumb()));
145 a_th_del = new QAction(tr("Delete"), Opie::Core::OResource::loadPixmap("trash", Opie::Core::OResource::SmallIcon),
146 QString::null, 0, this, 0);
147 connect(a_th_del, SIGNAL(activated()), this, SLOT(delThumb()));
148 a_th_add =
149 new QAction(tr("Move to Contact..."), Opie::Core::OResource::loadPixmap("addressbook/generic-contact", Opie::Core::OResource::SmallIcon),
150 QString::null, 0, this, 0);
151 connect(a_th_add, SIGNAL(activated()), this, SLOT(moveToContact()));
152 a_send =
153 new QAction(tr("Beam to Contact..."), Opie::Core::OResource::loadPixmap("beam", Opie::Core::OResource::SmallIcon),
154 QString::null, 0, this, 0);
155 connect(a_send, SIGNAL(activated()), this, SLOT(sendFile()));
156
157
158#ifndef QTOPIA_PHONE
159 // Create Toolbars
160 QPEToolBar *bar = new QPEToolBar(this);
161 bar->setHorizontalStretchable(TRUE);
162 setToolBarsMovable(FALSE);
163
164 a_pview->addTo(bar);
165 if (video_supported)
166 a_vview->addTo(bar);
167 a_th_edit->addTo(bar);
168 a_th_del->addTo(bar);
169 a_th_add->addTo(bar);
170 a_send->addTo(bar);
171 a_settings->addTo(bar);
172#else
173 ContextMenu *contextMenu = new ContextMenu(this);
174 a_pview->addTo(contextMenu);
175 if (video_supported)
176 a_vview->addTo(contextMenu);
177 a_th_edit->addTo(contextMenu);
178 a_th_del->addTo(contextMenu);
179 a_th_add->addTo(contextMenu);
180 a_send->addTo(contextMenu);
181 a_settings->addTo(contextMenu);
182#endif
183
184 installEventFilter(camera->photo);
185 installEventFilter(camera->video);
186 camera->photo->installEventFilter(this);
187 camera->video->installEventFilter(this);
188
189 // Load the allowable sizes from the camera hardware.
190 photo_size = camera->videocaptureview->photoSizes();
191 video_size = camera->videocaptureview->videoSizes();
192
193 settings = new CameraSettings(this, 0, TRUE);
194 // load settings from config
195 Config cfg("Camera");
196 cfg.setGroup("General");
197 QString l = cfg.readEntry("location");
198
199#warning fixme
200 /*if ( !l.isEmpty() )
201 settings->location->setLocation(l);
202 */
203
204 storagepath = settings->location->documentPath();
205 cfg.setGroup("Photo");
206 int w;
207 w = cfg.readNumEntry("width", camera->videocaptureview->recommendedPhotoSize().width());
208 for (psize = 0; psize < (int) photo_size.count() - 1 && photo_size[psize].width() > w;)
209 psize++;
210 pquality = cfg.readNumEntry("quality", settings->photo_quality->value());
211 cfg.setGroup("Video");
212 w = cfg.readNumEntry("width", camera->videocaptureview->recommendedVideoSize().width());
213 for (vsize = 0; vsize < (int) video_size.count() - 1 && video_size[vsize].width() > w;)
214 vsize++;
215 vquality = cfg.readNumEntry("quality", settings->video_quality->value());
216 vframerate = cfg.readNumEntry("framerate", settings->video_framerate->value());
217
218 for (int i = 0; i < (int) photo_size.count(); i++) {
219 settings->photo_size->insertItem(tr("%1 x %2").arg(photo_size[i].width()).
220 arg(photo_size[i].height()));
221 }
222 for (int i = 0; i < (int) video_size.count(); i++) {
223 settings->video_size->insertItem(tr("%1 x %2").arg(video_size[i].width()).
224 arg(video_size[i].height()));
225 }
226
227 namehint = 0;
228 recording = FALSE;
229
230 preview();
231
232 if (!video_supported) {
233 // Room for longer text
234 camera->photo->setText(tr("Take Photo"));
235 camera->video->setEnabled(FALSE);
236 camera->video->hide();
237 }
238}
239
240CameraMainWindow::~CameraMainWindow()
241{
242}
243
244void CameraMainWindow::resizeEvent(QResizeEvent *)
245{
246 thumbw = width() / 5 - 4;
247 thumbh = thumbw * 3 / 4;
248 thumb[0]->setFixedHeight(thumbh + thmarg * 2);
249 loadThumbs();
250}
251
252bool CameraMainWindow::event(QEvent * e)
253{
254 if (e->type() == QEvent::WindowActivate) {
255 if (cur_thumb < 0)
256 camera->videocaptureview->setLive();
257 }
258 else if (e->type() == QEvent::WindowDeactivate) {
259 camera->videocaptureview->setLive(-1);
260 }
261 return QMainWindow::event(e);
262}
263
264bool CameraMainWindow::eventFilter(QObject * o, QEvent * e)
265{
266 if (e->type() == QEvent::KeyPress) {
267 QKeyEvent *ke = (QKeyEvent *) e;
268
269#if QTOPIA_PHONE
270 if (!ke->isAutoRepeat()) {
271 if (ke->key() == Key_1) {
272 takePhoto();
273 return TRUE;
274 }
275 else if (ke->key() == Key_2) {
276 toggleVideo();
277 return TRUE;
278 }
279 }
280#endif
281 if (ke->key() == Key_Up) {
282 camera->photo->setFocus();
283 return TRUE;
284 }
285 else if (ke->key() == Key_Down) {
286 thumb[0]->setFocus();
287 return TRUE;
288 }
289 else if (ke->key() == Key_Left) {
290 if (o == camera->video) {
291 camera->photo->setFocus();
292 return TRUE;
293 }
294 else {
295 if (o == thumb[0])
296 return TRUE;
297 for (int i = 1; i < nthumb; ++i) {
298 if (o == thumb[i]) {
299 thumb[i - 1]->setFocus();
300 return TRUE;
301 }
302 }
303 }
304 }
305 else if (ke->key() == Key_Right) {
306 if (o == camera->photo) {
307 camera->video->setFocus();
308 return TRUE;
309 }
310 else {
311 if (o == thumb[nthumb - 1])
312 return TRUE;
313 for (int i = 0; i < nthumb - 1; ++i) {
314 if (o == thumb[i]) {
315 thumb[i + 1]->setFocus();
316 return TRUE;
317 }
318 }
319 }
320 }
321 }
322 else if (e->type() == QEvent::FocusIn) {
323 if (o == camera->photo)
324 camera->photo->setText(tr("Take Photo"));
325 updateActions();
326 }
327 else if (e->type() == QEvent::FocusOut) {
328 if (o == camera->photo)
329 camera->photo->setText(tr("Activate Camera"));
330 }
331 return QWidget::eventFilter(o, e);
332}
333
334void CameraMainWindow::updateActions()
335{
336 bool p = FALSE, v = FALSE;
337 QWidget *foc = focusWidget();
338 if (foc == camera->photo) {
339 p = TRUE;
340 v = FALSE;
341 }
342 else if (foc == camera->video) {
343 v = TRUE;
344 p = FALSE;
345 }
346 a_pview->setEnabled(p);
347 a_vview->setEnabled(v);
348 a_settings->setEnabled(p || v);
349 bool th = !p && !v;
350 if (th) {
351 int i;
352 for (i = 0; i < nthumb; i++) {
353 if (thumb[i] == foc) {
354 selectThumb(i);
355 break;
356 }
357 }
358 if (i == nthumb || !thumb[i]->pixmap())
359 th = FALSE;
360 }
361 else {
362 selectThumb(-1);
363 }
364}
365
366void CameraMainWindow::viewPictures()
367{
368#warning fixme
369// ServiceRequest req("PhotoEdit","showCategory(int)");
370// req << camcat;
371// req.send();
372}
373
374void CameraMainWindow::viewVideos()
375{
376#warning fixme
377// Service::appLnk("Open/video/mpeg").execute();
378}
379
380void CameraMainWindow::doSettings()
381{
382 bool v = video_supported;
383#ifdef QTOPIA_PHONE
384 bool p;
385 p = a_pview->isEnabled();
386 v = v && a_vview->isEnabled();
387 if (p)
388 settings->photo->show();
389 else
390 settings->photo->hide();
391#endif
392 if (v)
393 settings->video->show();
394 else
395 settings->video->hide();
396 settings->photo_size->setCurrentItem(psize);
397 settings->video_size->setCurrentItem(vsize);
398 settings->photo_quality->setValue(pquality);
399 settings->video_quality->setValue(vquality);
400 settings->video_framerate->setValue(vframerate);
401 settings->video_quality_n->setFixedWidth(fontMetrics().width("100"));
402 settings->photo_quality_n->setFixedWidth(fontMetrics().width("100"));
403
404 if (QPEApplication::execDialog(settings)) {
405 confirmSettings();
406 }
407 else {
408#warning fixme
409// settings->location->setLocation(storagepath);
410 }
411}
412
413void CameraMainWindow::confirmSettings()
414{
415 storagepath = settings->location->documentPath();
416 psize = settings->photo_size->currentItem();
417 vsize = settings->video_size->currentItem();
418 pquality = settings->photo_quality->value();
419 vquality = settings->video_quality->value();
420 vframerate = settings->video_framerate->value();
421
422 // save settings
423 Config cfg("Camera");
424 cfg.setGroup("General");
425 cfg.writeEntry("location", storagepath);
426 cfg.setGroup("Photo");
427 cfg.writeEntry("width", photo_size[psize].width());
428 cfg.writeEntry("quality", pquality);
429 cfg.setGroup("Video");
430 cfg.writeEntry("width", video_size[vsize].width());
431 cfg.writeEntry("quality", vquality);
432 cfg.writeEntry("framerate", vframerate);
433
434 loadThumbs();
435
436 preview();
437}
438
439static int cmpDocLnk(const void *a, const void *b)
440{
441 const DocLnk *la = *(const DocLnk **) a;
442 const DocLnk *lb = *(const DocLnk **) b;
443 QFileInfo fa(la->linkFileKnown()? la->linkFile() : la->file());
444 QFileInfo fb(lb->linkFileKnown()? lb->linkFile() : lb->file());
445 return fa.lastModified().secsTo(fb.lastModified());
446}
447
448void CameraMainWindow::loadThumbs()
449{
450 if (storagepath.isEmpty()) {
451 updateActions();
452 return;
453 }
454
455 DocLnkSet set(storagepath, "image/jpeg");
456 const QList < DocLnk > &l = set.children();
457
458 DocLnk *lnk;
459 DocLnk **array = new DocLnk *[l.count()];
460 int n = 0;
461 for (QListIterator < DocLnk > it(l); (lnk = it.current()); ++it) {
462 if (lnk->categories().contains(camcat))
463 array[n++] = lnk;
464 }
465 qsort(array, n, sizeof(array[0]), cmpDocLnk);
466 for (int i = 0; i < nthumb; i++) {
467 QPixmap pm;
468 if (i < n) {
469 picturefile[i] = *array[i];
470 QImage img = Image::loadScaled(picturefile[i].file(), thumbw, thumbh);
471 pm.convertFromImage(img);
472 }
473 if (pm.isNull()) {
474 thumb[i]->setText("");
475 }
476 else {
477 thumb[i]->setPixmap(pm);
478 }
479 thumb[i]->setEnabled(!pm.isNull());
480 }
481 if (cur_thumb >= 0)
482 selectThumb(cur_thumb);
483
484 if (!camera->videocaptureview->available()) {
485 camera->photo->setEnabled(FALSE);
486 camera->video->setEnabled(FALSE);
487 if (!n) {
488 thumb[0]->setEnabled(FALSE);
489 }
490 else {
491 thumb[0]->setFocus();
492 thumb[0]->setEnabled(TRUE);
493 }
494 }
495
496 updateActions();
497}
498
499void CameraMainWindow::delThumb(int th)
500{
501 switch (QMessageBox::warning(0, tr("Confirmation"),
502 tr("<qt>Delete '%1'?</qt>",
503 "%1 = file name").arg(picturefile[th].name()), QMessageBox::Yes,
504 QMessageBox::No)) {
505 case QMessageBox::Yes:
506 picturefile[th].removeFiles();
507
508 // Rhys Hack - if we have just deleted the last image and there
509 // is no camera connected, then exit the application. This
510 // avoids a focus problem where it is impossible to exit with
511 // the back button due to the focus being in a stupid place.
512 loadThumbs();
513 if (!camera->videocaptureview->available() && !(thumb[0]->isEnabled())) {
514 close();
515 }
516 break;
517 default:
518 //nothing
519 break;
520 }
521}
522
523void CameraMainWindow::pushThumb(const DocLnk & f, const QImage & img)
524{
525 for (int i = nthumb; --i;) {
526 bool en = thumb[i - 1]->isEnabled();
527 thumb[i]->setEnabled(en);
528 picturefile[i] = picturefile[i - 1];
529 const QPixmap *pm = thumb[i - 1]->pixmap();
530 if (en && pm) {
531 thumb[i]->setPixmap(*pm);
532 }
533 else {
534 thumb[i]->setText("");
535 }
536 }
537 QPixmap pm;
538 QSize sz = Image::aspectScaleSize(img.width(), img.height(), thumbw, thumbh);
539 QImage simg = img.smoothScale(sz.width(), sz.height());
540 pm.convertFromImage(simg);
541 thumb[0]->setPixmap(pm);
542 thumb[0]->setEnabled(TRUE);
543 picturefile[0] = f;
544}
545
546void CameraMainWindow::takePhoto()
547{
548 if (camera->photo != focusWidget()) {
549 camera->photo->setFocus();
550 return;
551 }
552 QSize size = photo_size[psize];
553 if (size == camera->videocaptureview->captureSize() ||
554 camera->videocaptureview->refocusDelay() == 0) {
555
556 // We can grab the current image immediately.
557 takePhotoNow();
558
559 }
560 else {
561
562 // Change the camera size and then wait for the camera to refocus.
563 camera->videocaptureview->setCaptureSize(size);
564 refocusTimer->start(camera->videocaptureview->refocusDelay(), TRUE);
565
566 }
567}
568
569void CameraMainWindow::takePhotoNow()
570{
571 QImage img = camera->videocaptureview->image();
572
573 if (inSnapMode()) {
574 QCopEnvelope e(snap_ch, "valueSupplied(QString,QImage)");
575 QSize s = Image::aspectScaleSize(img.width(), img.height(), snap_maxw, snap_maxh);
576 e << snap_id << img.smoothScale(s.width(), s.height());
577 setSnapMode(FALSE);
578 close();
579 }
580 else {
581 DocLnk f;
582 //f.setLocation(storagepath);
583 f.setType("image/jpeg");
584 QDateTime dt = QDateTime::currentDateTime();
585 QString date = dt.toString();
586 f.setName(tr("Photo, " + date));
587
588 QArray < int >c(1);
589 c[0] = camcat;
590 f.setCategories(c);
591 img.save(f.file(), "JPEG", pquality); // Save the image in its original size.
592 f.writeLink();
593 pushThumb(f, img);
594 }
595
596 preview();
597}
598
599bool CameraMainWindow::inSnapMode() const
600{
601 return !snap_ch.isEmpty();
602}
603
604void CameraMainWindow::setSnapMode(bool y)
605{
606 if (y) {
607 camera->thumbs->hide();
608 camera->video->hide();
609 }
610 else {
611 camera->thumbs->show();
612 if (video_supported)
613 camera->video->show();
614 else
615 camera->video->hide();
616 snap_ch = QString::null;
617 }
618}
619
620void CameraMainWindow::toggleVideo()
621{
622 if (recording)
623 stopVideo();
624 else
625 startVideo();
626 recording = !recording;
627 camera->video->setText(recording ? tr("Stop") : tr("Video"));
628 camera->photo->setEnabled(!recording);
629 for (int i = 0; i < nthumb; i++)
630 thumb[i]->setEnabled(!recording && thumb[i]->pixmap());
631}
632
633void CameraMainWindow::startVideo()
634{
635 // XXX eg. MJPG
636}
637void CameraMainWindow::stopVideo()
638{
639}
640
641void CameraMainWindow::thumbClicked(int i)
642{
643 selectThumb(i);
644}
645
646void CameraMainWindow::editThumb()
647{
648 picturefile[cur_thumb].execute();
649}
650
651void CameraMainWindow::selectThumb(int i)
652{
653 cur_thumb = i;
654 if (i >= 0) {
655 QImage img(picturefile[i].file());
656 camera->videocaptureview->setStill(img);
657 thumb[i]->setFocus();
658 }
659 else {
660 camera->videocaptureview->setLive();
661 }
662 a_th_edit->setEnabled(i >= 0);
663 a_th_del->setEnabled(i >= 0);
664 a_th_add->setEnabled(i >= 0);
665 a_send->setEnabled(i >= 0);
666}
667
668void CameraMainWindow::moveToContact()
669{
670 if (cur_thumb >= 0) {
671#warning fixme
672// QCopEnvelope e(Service::channel("Contacts"),"setContactImage(QImage)");
673// QImage img;
674// img.load(picturefile[cur_thumb].file());
675// e << img;
676 }
677}
678
679void CameraMainWindow::delThumb()
680{
681 if (cur_thumb >= 0) {
682 int d = cur_thumb;
683 if (cur_thumb > 0)
684 selectThumb(cur_thumb - 1);
685 delThumb(d);
686 }
687}
688
689void CameraMainWindow::linkChanged(const QString &)
690{
691 loadThumbs();
692}
693
694void CameraMainWindow::appMessage(const QCString & msg, const QByteArray & data)
695{
696 if (msg == "getImage(QCString,QString,int,int,QImage)") {
697 QDataStream ds(data, IO_ReadOnly);
698 ds >> snap_ch >> snap_id >> snap_maxw >> snap_maxh;
699 setSnapMode(TRUE);
700 QPEApplication::setKeepRunning();
701 }
702}
703
704void CameraMainWindow::preview()
705{
706 if (camera->videocaptureview->refocusDelay() > 200) {
707 camera->videocaptureview->setCaptureSize(photo_size[psize]);
708 }
709 else {
710 camera->videocaptureview->setCaptureSize(camera->videocaptureview->
711 recommendedPreviewSize());
712 }
713}
714
715void CameraMainWindow::sendFile()
716{
717 if (cur_thumb >= 0) {
718 //copy file
719 QFile input(picturefile[cur_thumb].file());
720 if (!input.open(IO_ReadOnly)) {
721 return; //error
722 }
723 QFile output(picfile);
724 if (!output.open(IO_WriteOnly)) {
725 return;
726 }
727
728 const int BUFFER_SIZE = 1024;
729 Q_INT8 buffer[BUFFER_SIZE];
730
731 QDataStream srcStr(&input);
732 QDataStream destStr(&output);
733
734 while (!srcStr.atEnd()) {
735 int i = 0;
736 while (!srcStr.atEnd() && i < BUFFER_SIZE) {
737 srcStr >> buffer[i];
738 i++;
739 }
740 for (int k = 0; k < i; k++) {
741 destStr << buffer[k];
742 }
743 }
744
745#warning fixme
746// QCopEnvelope e(Service::channel("Email"),"writeMessage(QString,QString,QStringList,QStringList)");
747// e << QString() << QString() << QStringList() << QStringList( QString( picfile ) );
748 }
749}
750
751void ThumbButton::drawButtonLabel(QPainter * p)
752{
753 const QPixmap *pm = pixmap();
754 if (pm) {
755 QSize s = (size() - pm->size()) / 2;
756 p->drawPixmap(s.width(), s.height(), *pm);
757 }
758}
759
760ThumbButton::ThumbButton(QWidget * parent, const char *name):QToolButton(parent, name)
761{
762}
763
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 @@
1/**********************************************************************
2** Copyright (C) 2000-2006 Trolltech AS. All rights reserved.
3**
4** This file is part of the Qtopia Environment.
5**
6** This program is free software; you can redistribute it and/or modify it
7** under the terms of the GNU General Public License as published by the
8** Free Software Foundation; either version 2 of the License, or (at your
9** option) any later version.
10**
11** A copy of the GNU GPL license version 2 is included in this package as
12** LICENSE.GPL.
13**
14** This program is distributed in the hope that it will be useful, but
15** WITHOUT ANY WARRANTY; without even the implied warranty of
16** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
17** See the GNU General Public License for more details.
18**
19** In addition, as a special exception Trolltech gives permission to link
20** the code of this program with Qtopia applications copyrighted, developed
21** and distributed by Trolltech under the terms of the Qtopia Personal Use
22** License Agreement. You must comply with the GNU General Public License
23** in all respects for all of the code used other than the applications
24** licensed under the Qtopia Personal Use License Agreement. If you modify
25** this file, you may extend this exception to your version of the file,
26** but you are not obligated to do so. If you do not wish to do so, delete
27** this exception statement from your version.
28**
29** See http://www.trolltech.com/gpl/ for GPL licensing information.
30**
31** Contact info@trolltech.com if any conditions of this licensing are
32** not clear to you.
33**
34**********************************************************************/
35#ifndef MAINWINDOW_H
36#define MAINWINDOW_H
37
38#include "camerabase.h"
39#include <qvaluelist.h>
40#include <qmainwindow.h>
41#include <qpe/applnk.h>
42
43class LocationCombo;
44class QAction;
45class QTimer;
46class CameraSettings;
47
48
49class CameraMainWindow : public QMainWindow
50{
51 Q_OBJECT
52public:
53 static QString appName() { return QString::fromLatin1("camera2"); }
54
55 CameraMainWindow( QWidget *parent=0, const char *name=0, WFlags fl=0 );
56 ~CameraMainWindow();
57
58public slots:
59 void takePhoto();
60 void toggleVideo();
61 void selectThumb(int i);
62 void thumbClicked(int i);
63
64private slots:
65 void viewPictures();
66 void viewVideos();
67 void doSettings();
68 void appMessage(const QCString& msg, const QByteArray& data);
69 void editThumb();
70 void delThumb();
71 void moveToContact();
72 void takePhotoNow();
73 void sendFile();
74 void linkChanged(const QString&);
75
76private:
77 bool event(QEvent* e);
78 void updateActions();
79 void resizeEvent(QResizeEvent*);
80
81 bool eventFilter(QObject*, QEvent*);
82 QString nextFileName();
83 void loadThumbs();
84 void pushThumb(const DocLnk& f, const QImage& img);
85 static const int nthumb = 5;
86 QToolButton* thumb[nthumb];
87 DocLnk picturefile[nthumb];
88 int cur_thumb;
89 void delThumb(int th);
90
91 // Settings
92 void confirmSettings();
93 CameraSettings *settings;
94 QString storagepath;
95 int thumbw;
96 int thumbh;
97 int psize;
98 int vsize;
99 int pquality;
100 int vquality;
101 int vframerate;
102
103 // Snap
104 QCString snap_ch;
105 QString snap_id;
106 int snap_maxw, snap_maxh;
107 bool inSnapMode() const;
108 void setSnapMode(bool);
109
110 CameraBase *camera;
111
112 int namehint;
113 QAction *a_pview, *a_vview, *a_settings;
114 QAction *a_th_edit, *a_th_del, *a_th_add;
115 QAction *a_send;
116 QValueList<QSize> photo_size;
117 QValueList<QSize> video_size;
118
119 QTimer *refocusTimer;
120 QString picfile;
121
122 bool recording;
123 void stopVideo();
124 void startVideo();
125
126 void preview();
127
128 int camcat;
129};
130
131#endif
132
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 @@
1Package: opie-camera2
2Files: bin/camerapics/camera2 apps/Applications/camera2.desktop
3Priority: optional
4Section: opie/multimedia
5Maintainer: Lorn "ljp" Potter <lorn.potter@trolltech.com>
6Architecture: arm
7Version: 1.0.1$EXTRAVERSION
8Depends: libqpe1, libopiecore2, libopieui2
9Description: A Camera Application
10 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 @@
1/**********************************************************************
2** Copyright (C) 2000-2006 Trolltech AS. All rights reserved.
3**
4** This file is part of the Qtopia Environment.
5**
6** This program is free software; you can redistribute it and/or modify it
7** under the terms of the GNU General Public License as published by the
8** Free Software Foundation; either version 2 of the License, or (at your
9** option) any later version.
10**
11** A copy of the GNU GPL license version 2 is included in this package as
12** LICENSE.GPL.
13**
14** This program is distributed in the hope that it will be useful, but
15** WITHOUT ANY WARRANTY; without even the implied warranty of
16** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
17** See the GNU General Public License for more details.
18**
19** In addition, as a special exception Trolltech gives permission to link
20** the code of this program with Qtopia applications copyrighted, developed
21** and distributed by Trolltech under the terms of the Qtopia Personal Use
22** License Agreement. You must comply with the GNU General Public License
23** in all respects for all of the code used other than the applications
24** licensed under the Qtopia Personal Use License Agreement. If you modify
25** this file, you may extend this exception to your version of the file,
26** but you are not obligated to do so. If you do not wish to do so, delete
27** this exception statement from your version.
28**
29** See http://www.trolltech.com/gpl/ for GPL licensing information.
30**
31** Contact info@trolltech.com if any conditions of this licensing are
32** not clear to you.
33**
34**********************************************************************/
35#ifndef THUMBBUTTON_H
36#define THUMBBUTTON_H
37
38#include <qtoolbutton.h>
39
40class ThumbButton : public QToolButton
41{
42 Q_OBJECT
43public:
44 ThumbButton( QWidget *parent, const char* name );
45
46 void drawButtonLabel( QPainter * );
47};
48
49#endif
50
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 @@
1/**********************************************************************
2** Copyright (C) 2000-2006 Trolltech AS. All rights reserved.
3**
4** This file is part of the Qtopia Environment.
5**
6** This program is free software; you can redistribute it and/or modify it
7** under the terms of the GNU General Public License as published by the
8** Free Software Foundation; either version 2 of the License, or (at your
9** option) any later version.
10**
11** A copy of the GNU GPL license version 2 is included in this package as
12** LICENSE.GPL.
13**
14** This program is distributed in the hope that it will be useful, but
15** WITHOUT ANY WARRANTY; without even the implied warranty of
16** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
17** See the GNU General Public License for more details.
18**
19** In addition, as a special exception Trolltech gives permission to link
20** the code of this program with Qtopia applications copyrighted, developed
21** and distributed by Trolltech under the terms of the Qtopia Personal Use
22** License Agreement. You must comply with the GNU General Public License
23** in all respects for all of the code used other than the applications
24** licensed under the Qtopia Personal Use License Agreement. If you modify
25** this file, you may extend this exception to your version of the file,
26** but you are not obligated to do so. If you do not wish to do so, delete
27** this exception statement from your version.
28**
29** See http://www.trolltech.com/gpl/ for GPL licensing information.
30**
31** Contact info@trolltech.com if any conditions of this licensing are
32** not clear to you.
33**
34**********************************************************************/
35
36#include "videocaptureview.h"
37#include <qimage.h>
38#include <qpainter.h>
39#ifdef Q_WS_QWS
40#include <qgfx_qws.h>
41#include <qdirectpainter_qws.h>
42#endif
43
44#ifdef __linux__
45 #defineHAVE_VIDEO4LINUX 1
46#endif
47
48#ifdef HAVE_VIDEO4LINUX
49
50#include <sys/types.h>
51#include <sys/ioctl.h>
52#include <unistd.h>
53#include <fcntl.h>
54#include <linux/videodev.h>
55#include <errno.h>
56#include <string.h>
57#include <stdlib.h>
58#include <sys/mman.h>
59
60#endif /* HAVE_VIDEO4LINUX */
61
62class VideoCapture {
63 public:
64 VideoCapture();
65 ~VideoCapture();
66
67 bool hasCamera() const;
68 void getCameraImage(QImage & img, bool copy = FALSE);
69
70 QValueList < QSize > photoSizes() const;
71 QValueList < QSize > videoSizes() const;
72
73 QSize recommendedPhotoSize() const;
74 QSize recommendedVideoSize() const;
75 QSize recommendedPreviewSize() const;
76
77 QSize captureSize() const;
78 void setCaptureSize(QSize size);
79
80 uint refocusDelay() const;
81 int minimumFramePeriod() const;
82
83 private:
84#ifdef HAVE_VIDEO4LINUX
85 int fd;
86 int width, height;
87 struct video_capability caps;
88 struct video_mbuf mbuf;
89 unsigned char *frames;
90 int currentFrame;
91
92 void setupCamera(QSize size);
93 void shutdown();
94#endif
95};
96
97#ifdef HAVE_VIDEO4LINUX
98
99 #define VIDEO_DEVICE "/dev/video"
100
101bool VideoCapture::hasCamera() const
102{
103 return (fd != -1);
104}
105
106QSize VideoCapture::captureSize() const
107{
108 return QSize(width, height);
109}
110
111uint VideoCapture::refocusDelay() const
112{
113 return 250;
114}
115
116int VideoCapture::minimumFramePeriod() const
117{
118 return 40; // milliseconds
119}
120
121VideoCapture::VideoCapture()
122{
123 setupCamera(QSize(0, 0));
124}
125
126VideoCapture::~VideoCapture()
127{
128 shutdown();
129}
130
131void VideoCapture::setupCamera(QSize size)
132{
133 qWarning(" VideoCapture::setupCamera");
134 // Clear important variables.
135 frames = 0;
136 currentFrame = 0;
137 width = 640;
138 height = 480;
139 caps.minwidth = width;
140 caps.minheight = height;
141 caps.maxwidth = width;
142 caps.maxheight = height;
143
144 // Open the video device.
145 fd = open(VIDEO_DEVICE, O_RDWR);
146 if (fd == -1) {
147 qWarning("%s: %s", VIDEO_DEVICE, strerror(errno));
148 return;
149 }
150
151 // Get the device's current capabilities.
152 memset(&caps, 0, sizeof(caps));
153 if (ioctl(fd, VIDIOCGCAP, &caps) < 0) {
154 qWarning("%s: could not retrieve the video capabilities", VIDEO_DEVICE);
155 close(fd);
156 fd = -1;
157 return;
158 }
159
160 // Change the channel to the first-connected camera, skipping TV inputs.
161 // If there are multiple cameras, this may need to be modified.
162 int chan;
163 struct video_channel chanInfo;
164 qWarning("available video capture inputs:");
165 for (chan = 0; chan < caps.channels; ++chan) {
166 chanInfo.channel = chan;
167 if (ioctl(fd, VIDIOCGCHAN, &chanInfo) >= 0) {
168 if (chanInfo.type == VIDEO_TYPE_CAMERA)
169 qWarning(" %s (camera)", chanInfo.name);
170 else if (chanInfo.type == VIDEO_TYPE_TV)
171 qWarning(" %s (tv)", chanInfo.name);
172 else
173 qWarning(" %s (unknown)", chanInfo.name);
174 }
175 }
176 for (chan = 0; chan < caps.channels; ++chan) {
177 chanInfo.channel = chan;
178 if (ioctl(fd, VIDIOCGCHAN, &chanInfo) >= 0) {
179 if (chanInfo.type == VIDEO_TYPE_CAMERA) {
180 qWarning("selecting camera on input %s", chanInfo.name);
181 if (ioctl(fd, VIDIOCSCHAN, &chan) < 0) {
182 qWarning("%s: could not set the channel", VIDEO_DEVICE);
183 }
184 break;
185 }
186 }
187 }
188
189 // Set the desired picture mode to RGB32.
190 struct video_picture pict;
191 memset(&pict, 0, sizeof(pict));
192 ioctl(fd, VIDIOCGPICT, &pict);
193 pict.palette = VIDEO_PALETTE_RGB32;
194 if (ioctl(fd, VIDIOCSPICT, &pict) < 0) {
195 qWarning("%s: could not set the picture mode", VIDEO_DEVICE);
196 close(fd);
197 fd = -1;
198 return;
199 }
200
201 // Determine the capture size to use. Zero indicates "preview mode".
202 if (size.width() == 0) {
203 size = QSize(caps.minwidth, caps.minheight);
204 }
205
206 // Get the current capture window.
207 struct video_window wind;
208 memset(&wind, 0, sizeof(wind));
209 ioctl(fd, VIDIOCGWIN, &wind);
210
211 // Adjust the capture size to match the camera's aspect ratio.
212 if (caps.maxwidth > 0 && caps.maxheight > 0) {
213 if (size.width() > size.height()) {
214 size = QSize(size.height() * caps.maxwidth / caps.maxheight, size.height());
215 }
216 else {
217 size = QSize(size.width(), size.width() * caps.maxheight / caps.maxwidth);
218 }
219 }
220
221 // Set the new capture window.
222 wind.x = 0;
223 wind.y = 0;
224 wind.width = size.width();
225 wind.height = size.height();
226 if (ioctl(fd, VIDIOCSWIN, &wind) < 0) {
227 qWarning("%s: could not set the capture window", VIDEO_DEVICE);
228 }
229
230 // Re-read the capture window, to see what it was adjusted to.
231 ioctl(fd, VIDIOCGWIN, &wind);
232 width = wind.width;
233 height = wind.height;
234
235 // Enable mmap-based access to the camera.
236 memset(&mbuf, 0, sizeof(mbuf));
237 if (ioctl(fd, VIDIOCGMBUF, &mbuf) < 0) {
238 qWarning("%s: mmap-based camera access is not available", VIDEO_DEVICE);
239 close(fd);
240 fd = -1;
241 return;
242 }
243
244 // Mmap the designated memory region.
245 frames = (unsigned char *) mmap(0, mbuf.size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
246 if (!frames || frames == (unsigned char *) (long) (-1)) {
247 qWarning("%s: could not mmap the device", VIDEO_DEVICE);
248 close(fd);
249 fd = -1;
250 return;
251 }
252
253 // Start capturing of the first frame.
254 struct video_mmap capture;
255 currentFrame = 0;
256 capture.frame = currentFrame;
257 capture.width = width;
258 capture.height = height;
259 capture.format = VIDEO_PALETTE_RGB32;
260 ioctl(fd, VIDIOCMCAPTURE, &capture);
261}
262
263void VideoCapture::shutdown()
264{
265 if (frames != 0) {
266 munmap(frames, mbuf.size);
267 frames = 0;
268 }
269 if (fd != -1) {
270 int flag = 0;
271 ioctl(fd, VIDIOCSYNC, 0);
272 ioctl(fd, VIDIOCCAPTURE, &flag);
273 close(fd);
274 fd = -1;
275 }
276}
277
278void VideoCapture::getCameraImage(QImage & img, bool copy)
279{
280 if (fd == -1) {
281 if (img.isNull()) {
282 img.create(width, height, 32);
283 }
284 return;
285 }
286
287 // Start capturing the next frame (we alternate between 0 and 1).
288 int frame = currentFrame;
289 struct video_mmap capture;
290 if (mbuf.frames > 1) {
291 currentFrame = !currentFrame;
292 capture.frame = currentFrame;
293 capture.width = width;
294 capture.height = height;
295 capture.format = VIDEO_PALETTE_RGB32;
296 ioctl(fd, VIDIOCMCAPTURE, &capture);
297 }
298
299 // Wait for the current frame to complete.
300 ioctl(fd, VIDIOCSYNC, &frame);
301
302 // Create an image that refers directly to the kernel's
303 // frame buffer, to avoid having to copy the data.
304 if (!copy) {
305 img = QImage(frames + mbuf.offsets[frame], width, height, 32, 0, 0, QImage::IgnoreEndian);
306 }
307 else {
308 img.create(width, height, 32);
309 memcpy(img.bits(), frames + mbuf.offsets[frame], width * height * 4);
310 }
311
312 // Queue up another frame if the device only supports one at a time.
313 if (mbuf.frames <= 1) {
314 capture.frame = currentFrame;
315 capture.width = width;
316 capture.height = height;
317 capture.format = VIDEO_PALETTE_RGB32;
318 ioctl(fd, VIDIOCMCAPTURE, &capture);
319 }
320}
321
322QValueList < QSize > VideoCapture::photoSizes() const
323{
324 QValueList < QSize > list;
325 list.append(QSize(caps.maxwidth, caps.maxheight));
326 if (caps.maxwidth != caps.minwidth || caps.maxheight != caps.minheight)
327 list.append(QSize(caps.minwidth, caps.minheight));
328 return list;
329}
330
331QValueList < QSize > VideoCapture::videoSizes() const
332{
333 // We use the same sizes for both.
334 return photoSizes();
335}
336
337QSize VideoCapture::recommendedPhotoSize() const
338{
339 return QSize(caps.maxwidth, caps.maxheight);
340}
341
342QSize VideoCapture::recommendedVideoSize() const
343{
344 return QSize(caps.minwidth, caps.minheight);
345}
346
347QSize VideoCapture::recommendedPreviewSize() const
348{
349 return QSize(caps.minwidth, caps.minheight);
350}
351
352void VideoCapture::setCaptureSize(QSize size)
353{
354 if (size.width() != width || size.height() != height) {
355 shutdown();
356 setupCamera(size);
357 }
358}
359
360#else /* !HAVE_VIDEO4LINUX */
361
362// Dummy implementation for systems without video.
363
364VideoCapture::VideoCapture()
365{
366}
367
368VideoCapture::~VideoCapture()
369{
370}
371
372bool VideoCapture::hasCamera() const
373{
374 return TRUE;
375}
376
377QSize VideoCapture::captureSize() const
378{
379 return QSize(640, 480);
380}
381
382uint VideoCapture::refocusDelay() const
383{
384 return 0;
385}
386
387int VideoCapture::minimumFramePeriod() const
388{
389 return 100;
390}
391
392static unsigned int nextrand()
393{
394#define A 16807
395#define M 2147483647
396#define Q 127773
397#define R 2836
398 static unsigned int rnd = 1;
399 unsigned long hi = rnd / Q;
400 unsigned long lo = rnd % Q;
401 unsigned long test = A * lo - R * hi;
402 if (test > 0)
403 rnd = test;
404 else
405 rnd = test + M;
406 return rnd;
407}
408
409void VideoCapture::getCameraImage(QImage & img, bool)
410{
411 // Just generate something dynamic (rectangles)
412 static QImage cimg;
413 int x, y, w, h;
414 if (cimg.isNull()) {
415 x = y = 0;
416 w = 640;
417 h = 480;
418 cimg.create(w, h, 32);
419 }
420 else {
421 w = nextrand() % (cimg.width() - 10) + 10;
422 h = nextrand() % (cimg.height() - 10) + 10;
423 x = nextrand() % (cimg.width() - w);
424 y = nextrand() % (cimg.height() - h);
425 }
426 QRgb c = qRgb(nextrand() % 255, nextrand() % 255, nextrand() % 255);
427 for (int j = 0; j < h; j++) {
428 QRgb *l = (QRgb *) cimg.scanLine(y + j) + x;
429 for (int i = 0; i < w; i++)
430 l[i] = c;
431 }
432 img = cimg;
433}
434
435QValueList < QSize > VideoCapture::photoSizes() constconst
436{
437 QValueList < QSize > list;
438 list.append(QSize(640, 480));
439 list.append(QSize(320, 240));
440 return list;
441}
442
443QValueList < QSize > VideoCapture::videoSizes() constconst
444{
445 QValueList < QSize > list;
446 list.append(QSize(640, 480));
447 list.append(QSize(320, 240));
448 return list;
449}
450
451QSize VideoCapture::recommendedPhotoSize() const
452{
453 return QSize(640, 480);
454}
455
456QSize VideoCapture::recommendedVideoSize() const
457{
458 return QSize(320, 240);
459}
460
461QSize VideoCapture::recommendedPreviewSize() const
462{
463 return QSize(320, 240);
464}
465
466void VideoCapture::setCaptureSize(QSize size)
467{
468}
469
470#endif /* !HAVE_VIDEO4LINUX */
471
472VideoCaptureView::VideoCaptureView(QWidget * parent, const char *name, WFlags fl):QWidget(parent,
473 name, fl)
474{
475 capture = new VideoCapture();
476 QSizePolicy sp(QSizePolicy::Expanding, QSizePolicy::Expanding);
477 setSizePolicy(sp);
478 tid_update = 0;
479 setLive();
480}
481
482VideoCaptureView::~VideoCaptureView()
483{
484 delete capture;
485}
486
487void VideoCaptureView::setLive(int period)
488{
489 if (tid_update)
490 killTimer(tid_update);
491 if (period == 0)
492 tid_update = startTimer(capture->minimumFramePeriod());
493 else if (period > 0)
494 tid_update = startTimer(period);
495 else
496 tid_update = 0;
497}
498
499void VideoCaptureView::setStill(const QImage & i)
500{
501 setLive(-1);
502 img = i;
503 repaint(TRUE);
504}
505
506QValueList < QSize > VideoCaptureView::photoSizes() const
507{
508 return capture->photoSizes();
509}
510
511QValueList < QSize > VideoCaptureView::videoSizes() const
512{
513 return capture->videoSizes();
514}
515
516QSize VideoCaptureView::recommendedPhotoSize() const
517{
518 return capture->recommendedPhotoSize();
519}
520
521QSize VideoCaptureView::recommendedVideoSize() const
522{
523 return capture->recommendedVideoSize();
524}
525
526QSize VideoCaptureView::recommendedPreviewSize() const
527{
528 return capture->recommendedPreviewSize();
529}
530
531QSize VideoCaptureView::captureSize() const
532{
533 return capture->captureSize();
534}
535
536void VideoCaptureView::setCaptureSize(QSize size)
537{
538 capture->setCaptureSize(size);
539}
540
541uint VideoCaptureView::refocusDelay() const
542{
543 return capture->refocusDelay();
544}
545
546bool VideoCaptureView::available() const
547{
548 return capture->hasCamera();
549}
550
551void VideoCaptureView::paintEvent(QPaintEvent *)
552{
553 if (tid_update && !capture->hasCamera()) {
554 QPainter p(this);
555 p.drawText(rect(), AlignCenter, tr("No Camera"));
556 return;
557 }
558
559 if (tid_update)
560 capture->getCameraImage(img);
561 int w = img.width();
562 int h = img.height();
563
564 if (!w || !h)
565 return;
566
567 if (width() * w > height() * h) {
568 w = w * height() / h;
569 h = height();
570 }
571 else {
572 h = h * width() / w;
573 w = width();
574 }
575
576 if (qt_screen->transformOrientation() == 0) {
577 // Stretch and draw the image.
578 QDirectPainter p(this);
579 QGfx *gfx = p.internalGfx();
580 if (gfx) {
581 gfx->setSource(&img);
582 gfx->setAlphaType(QGfx::IgnoreAlpha);
583 gfx->stretchBlt((width() - w) / 2, (height() - h) / 2, w, h, img.width(), img.height());
584 }
585 }
586 else {
587 // This code is nowhere near efficient enough (hence the above).
588 // TODO - handle rotations during direct painting.
589 QImage scimg = img.smoothScale(w, h);
590 QPainter p(this);
591 p.drawImage((width() - w) / 2, (height() - h) / 2, scimg);
592 }
593}
594
595void VideoCaptureView::timerEvent(QTimerEvent *)
596{
597 repaint(FALSE);
598}
599
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 @@
1/**********************************************************************
2** Copyright (C) 2000-2006 Trolltech AS. All rights reserved.
3**
4** This file is part of the Qtopia Environment.
5**
6** This program is free software; you can redistribute it and/or modify it
7** under the terms of the GNU General Public License as published by the
8** Free Software Foundation; either version 2 of the License, or (at your
9** option) any later version.
10**
11** A copy of the GNU GPL license version 2 is included in this package as
12** LICENSE.GPL.
13**
14** This program is distributed in the hope that it will be useful, but
15** WITHOUT ANY WARRANTY; without even the implied warranty of
16** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
17** See the GNU General Public License for more details.
18**
19** In addition, as a special exception Trolltech gives permission to link
20** the code of this program with Qtopia applications copyrighted, developed
21** and distributed by Trolltech under the terms of the Qtopia Personal Use
22** License Agreement. You must comply with the GNU General Public License
23** in all respects for all of the code used other than the applications
24** licensed under the Qtopia Personal Use License Agreement. If you modify
25** this file, you may extend this exception to your version of the file,
26** but you are not obligated to do so. If you do not wish to do so, delete
27** this exception statement from your version.
28**
29** See http://www.trolltech.com/gpl/ for GPL licensing information.
30**
31** Contact info@trolltech.com if any conditions of this licensing are
32** not clear to you.
33**
34**********************************************************************/
35#ifndef VIDEOVIEW_H
36#define VIDEOVIEW_H
37
38#include <qwidget.h>
39#include <qimage.h>
40#include <qvaluelist.h>
41
42class VideoCapture;
43
44
45class VideoCaptureView : public QWidget
46{
47 Q_OBJECT
48
49public:
50 VideoCaptureView( QWidget *parent=0, const char *name=0, WFlags fl=0 );
51 ~VideoCaptureView();
52
53 bool available() const;
54
55 QImage image() const { return img; }
56 void setLive(int period=0);
57 void setStill(const QImage&);
58
59 QValueList<QSize> photoSizes() const;
60 QValueList<QSize> videoSizes() const;
61
62 QSize recommendedPhotoSize() const;
63 QSize recommendedVideoSize() const;
64 QSize recommendedPreviewSize() const;
65
66 QSize captureSize() const;
67 void setCaptureSize( QSize size );
68
69 uint refocusDelay() const;
70
71protected:
72 void paintEvent(QPaintEvent*);
73 void timerEvent(QTimerEvent*);
74
75private:
76 QImage img;
77 int tid_update;
78 VideoCapture *capture;
79};
80
81#endif
82