summaryrefslogtreecommitdiff
Side-by-side diff
Diffstat (more/less context) (ignore whitespace changes)
-rw-r--r--apps/Applications/camera2.desktop26
-rw-r--r--library/backend/categories.h1
-rw-r--r--library/global.cpp49
-rw-r--r--library/global.h6
-rw-r--r--library/library.pro2
-rw-r--r--library/locationcombo.cpp295
-rw-r--r--library/locationcombo.h88
-rw-r--r--library/qlibrary_unix.cpp4
-rw-r--r--library/timestring.cpp255
-rw-r--r--library/timestring.h94
-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
-rw-r--r--packages1
-rw-r--r--pics/camera2/Camera.pngbin0 -> 1668 bytes
-rw-r--r--pics/camera2/Camera_48.pngbin0 -> 3161 bytes
-rw-r--r--pics/camera2/Camera_48_anim.mngbin0 -> 13700 bytes
-rw-r--r--pics/camera2/settings.pngbin0 -> 745 bytes
32 files changed, 3723 insertions, 111 deletions
diff --git a/apps/Applications/camera2.desktop b/apps/Applications/camera2.desktop
new file mode 100644
index 0000000..4662080
--- a/dev/null
+++ b/apps/Applications/camera2.desktop
@@ -0,0 +1,26 @@
+[Desktop Entry]
+Exec=camera2
+File=camera2
+Icon=camera2/Camera
+Type=Application
+Name=OpieCam2
+Comment=A Camera Program
+Name[de]=Kamera2
+Comment[de]=Ein Kamera-Programm
+Name[fr]=Photo2
+Comment[fr]=Gestionnaire de photos et images
+Name[it]=Telecamera2
+Comment[it]=Programma per telecamera
+Name[pt]=Câmera2
+Comment[pt]=Uma aplicação de câmera
+Name[pt_BR]=Câmera2
+Comment[pt_BR]=Uma aplicação de câmera
+Name[sl]=OpieKamera2
+Comment[sl]=Program za kamero
+Naam[nl]=Camera2
+Comment[nl]=Een camerabesturingsprogramma
+Name[ru]=Камера2
+Comment[ru]=Программа для управления (фото)камерой
+Name[lv]=OpieCam2
+Comment[lv]=Opie Kameras Programma
+
diff --git a/library/backend/categories.h b/library/backend/categories.h
index 91c93e7..6be3bc0 100644
--- a/library/backend/categories.h
+++ b/library/backend/categories.h
@@ -31,6 +31,7 @@
#include "palmtopuidgen.h"
class CategoryGroup;
+QString categoryFileName();
#if defined(QPC_TEMPLATEDLL)
// MOC_SKIP_BEGIN
diff --git a/library/global.cpp b/library/global.cpp
index ec87555..f7a0767 100644
--- a/library/global.cpp
+++ b/library/global.cpp
@@ -808,5 +808,54 @@ QStringList Global::helpPath()
return path;
}
+/*!
+ \internal
+ Truncate file to size specified
+ \a f must be an open file
+ \a size must be a positive value
+ */
+bool Global::truncateFile(QFile &f, int size){
+ if (!f.isOpen())
+ return FALSE;
+
+ return ::ftruncate(f.handle(), size) != -1;
+}
+
+
+
+
+// #if defined(Q_OS_UNIX) && defined(Q_WS_QWS)
+// extern int qws_display_id;
+// #endif
+
+/*!
+ /internal
+ Returns the default system path for storing temporary files.
+ Note: This does not it ensure that the provided directory exists
+*/
+QString Global::tempDir()
+{
+ QString result;
+#ifdef Q_OS_UNIX
+#ifdef Q_WS_QWS
+ result = QString("/tmp/qtopia-%1/").arg(QString::number(qws_display_id));
+#else
+ result="/tmp/";
+#endif
+#else
+ if (getenv("TEMP"))
+ result = getenv("TEMP");
+ else
+ result = getenv("TMP");
+
+ if (result[(int)result.length() - 1] != QDir::separator())
+ result.append(QDir::separator());
+#endif
+
+ return result;
+}
+
+//#endif
+
#include "global.moc"
diff --git a/library/global.h b/library/global.h
index 1136b12..f32c498 100644
--- a/library/global.h
+++ b/library/global.h
@@ -27,7 +27,7 @@ class QLabel;
class QWidget;
class AppLnk;
class DocLnkSet;
-
+class QFile;
class Global
{
public:
@@ -80,6 +80,10 @@ public:
static QStringList languageList();
static QStringList helpPath();
#endif
+//#ifdef QTOPIA_INTERNAL_FILEOPERATIONS
+ static bool truncateFile(QFile &f, int size);
+ static QString tempDir( );
+//#endif
private:
static void invoke( const QString &exec);
diff --git a/library/library.pro b/library/library.pro
index 7143454..4142529 100644
--- a/library/library.pro
+++ b/library/library.pro
@@ -59,6 +59,7 @@ HEADERS = calendar.h \
windowdecorationinterface.h \
textcodecinterface.h \
imagecodecinterface.h \
+ locationcombo.h \
qpeglobal.h
SOURCES = calendar.cpp \
@@ -116,6 +117,7 @@ SOURCES = calendar.cpp \
findwidget_p.cpp \
finddialog.cpp \
lnkproperties.cpp \
+ locationcombo.cpp \
widget_showing.cpp
diff --git a/library/locationcombo.cpp b/library/locationcombo.cpp
new file mode 100644
index 0000000..31429f5
--- a/dev/null
+++ b/library/locationcombo.cpp
@@ -0,0 +1,295 @@
+/**********************************************************************
+** 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 "locationcombo.h"
+
+#include <qpe/ir.h>
+#include <qpe/applnk.h>
+#include <qpe/global.h>
+#include <qpe/categorywidget.h>
+#include <qpe/categoryselect.h>
+#ifdef QWS
+#include <qpe/qcopenvelope_qws.h>
+#endif
+#include <qpe/filemanager.h>
+#include <qpe/config.h>
+#include <qpe/storage.h>
+#include <qpe/global.h>
+#include <qtopia/qpemessagebox.h>
+
+#include <qlineedit.h>
+#include <qtoolbutton.h>
+#include <qpushbutton.h>
+#include <qgroupbox.h>
+#include <qcheckbox.h>
+#include <qlabel.h>
+#include <qlayout.h>
+#include <qfile.h>
+#include <qdir.h>
+#include <qfileinfo.h>
+#include <qmessagebox.h>
+#include <qsize.h>
+#include <qcombobox.h>
+#include <qregexp.h>
+
+#include <qradiobutton.h>
+#include <qlayout.h>
+
+#include <stdlib.h>
+
+/*!
+ \class LocationCombo locationcombo.h
+ \brief The LocationCombo class displays a list of available storage
+ locations.
+
+ First availability: Qtopia 1.6
+
+ \ingroup qtopiaemb
+ \sa DocPropertiesDialog
+ */
+
+
+class LocationComboPrivate
+{
+public:
+ LocationComboPrivate() : homeLocation(-1), fileSize(0), listEmpty(TRUE) {}
+ QString originalPath;
+ int homeLocation;
+ int fileSize;
+ bool listEmpty;
+};
+
+/*!
+ Constructs a LocationCombo with parent \a parent and name \a name.
+ */
+LocationCombo::LocationCombo( QWidget *parent, const char *name )
+ : QComboBox( FALSE, parent, name )
+{
+ storage = new StorageInfo;
+ d = new LocationComboPrivate;
+ setLocation( 0 );
+ connect( this, SIGNAL(activated(int)), this, SIGNAL(newPath()) );
+ connect( storage, SIGNAL(disksChanged()), this, SLOT(updatePaths()) );
+}
+
+/*!
+ Constructs a LocationCombo with parent \a parent and name \a name.
+ \a lnk is pointer to an existing AppLnk.
+ */
+LocationCombo::LocationCombo( const AppLnk * lnk, QWidget *parent, const char *name )
+ : QComboBox( FALSE, parent, name )
+{
+ storage = new StorageInfo;
+ d = new LocationComboPrivate;
+ setLocation(lnk);
+ connect( this, SIGNAL(activated(int)), this, SIGNAL(newPath()) );
+ connect( storage, SIGNAL(disksChanged()), this, SLOT(updatePaths()) );
+}
+
+/*!
+ Destroys the widget.
+ */
+LocationCombo::~LocationCombo()
+{
+ delete storage;
+ delete d;
+}
+
+/*!
+ Sets the display of the LocationCombo to the location associated with the
+ AppLnk \a lnk.
+ */
+void LocationCombo::setLocation( const AppLnk * lnk )
+{
+ // NB: setLocation(const QString) assumes only lnk->file() is used.
+
+ if ( lnk ) {
+ QFileInfo fi( lnk->file() );
+ d->fileSize = fi.size();
+ const FileSystem *fs = storage->fileSystemOf( lnk->file() );
+ d->originalPath = fs ? fs->path() : QString::null;
+ } else {
+ d->fileSize = 0;
+ d->originalPath = QString::null;
+ }
+
+ setupCombo();
+
+ int currentLocation = -1;
+ if ( lnk ) {
+ int n = locations.count();
+ for ( int i = 0; i < n; i++ ) {
+ if ( lnk->file().contains( locations[i] ) )
+ currentLocation = i;
+ }
+ }
+ if ( currentLocation == -1 )
+ currentLocation = 0; //default to the first one
+
+ setCurrentItem( currentLocation );
+}
+
+/*!
+ \internal
+*/
+void LocationCombo::setupCombo()
+{
+ clear();
+ locations.clear();
+
+ const QList<FileSystem> &fs = storage->fileSystems();
+ QListIterator<FileSystem> it ( fs );
+ QString s;
+ QString homeDir = QDir::homeDirPath();
+ QString homeFs;
+ QString homeFsPath;
+ int index = 0;
+ for ( ; it.current(); ++it ) {
+ // we add 10k to the file size so we are sure we can also save the desktop file
+ if ( !d->fileSize || (*it)->path() == d->originalPath ||
+ (ulong)(*it)->availBlocks() * (ulong)(*it)->blockSize()
+ > (ulong)d->fileSize + 10000 )
+ {
+ if ( (*it)->isRemovable() ) {
+ insertItem( (*it)->name(), index );
+ locations.append( (*it)->path() );
+ index++;
+ } else if ( homeDir.contains( (*it)->path() ) &&
+ (*it)->path().length() > homeFsPath.length() ) {
+ homeFs = (*it)->name();
+ homeFsPath = (*it)->path();
+ }
+ }
+ }
+
+ // $HOME is *somewhere*, but not shown in Storage::fileSystems(),
+ // eg. because it's mounted in some unexpected way.
+ if ( homeFsPath.isEmpty() ) {
+ homeFs = StorageInfo::tr("Internal Storage");
+ homeFsPath = homeDir;
+ }
+
+ if ( !homeFsPath.isEmpty() ) {
+ d->homeLocation = 0;
+ insertItem( homeFs, d->homeLocation );
+ locations.prepend( homeDir );
+ } else {
+ d->homeLocation = -1;
+ }
+
+ d->listEmpty = locations.count() == 0;
+ if ( d->listEmpty ) {
+ insertItem( tr("No FileSystems Available!"), 0 );
+ locations.append( "" );
+ }
+}
+
+/*!
+ \internal
+ */
+void LocationCombo::updatePaths()
+{
+ QString oldPath = locations[currentItem()];
+
+ setupCombo();
+
+ int currentLocation = 0;
+ int n = locations.count();
+ for ( int i = 0; i < n; i++ ) {
+ if ( oldPath == locations[i] ) {
+ currentLocation = i;
+ }
+ }
+ setCurrentItem( currentLocation );
+ if ( locations[currentItem()] != oldPath )
+ emit newPath();
+}
+
+/*!
+ Returns TRUE to indicate that the user has changed the location displayed
+ by the LocationCombo. Most useful when the LocationCombo is part of a
+ dialog; when the dialog is accept()ed, LocationCombo::isChanged() can be
+ examined to check for a change of location.
+ */
+bool LocationCombo::isChanged() const
+{
+ if ( const FileSystem *fs = storage->fileSystemOf(locations[currentItem()]) )
+ return fs->path() != d->originalPath;
+
+ return TRUE;
+}
+
+/*!
+ Returns the default (home) location for the file associated with this
+ LocationCombo.
+ */
+QString LocationCombo::installationPath() const
+{
+ return currentItem() == d->homeLocation ?
+ QString("/") : locations[ currentItem() ]+"/";
+}
+
+/*!
+ Returns the document path associated with this LocationCombo. This
+ will be "\<path\>/Documents".
+ */
+QString LocationCombo::documentPath() const
+{
+ return locations[ currentItem() ]+"/Documents/";
+}
+
+/*!
+ Returns a pointer to FileSystem object, associated with the current
+ selection of the LocationCombo.
+ */
+const FileSystem *LocationCombo::fileSystem() const
+{
+ if ( d->listEmpty )
+ return 0;
+ return storage->fileSystemOf( locations[ currentItem() ] );
+}
+
+/*!
+ \fn LocationCombo::newPath()
+ Emitted when the LocationCombo changes to a new location.
+ */
+
+
+#if 0
+void LocationCombo::apply()
+{
+}
+#endif
+
diff --git a/library/locationcombo.h b/library/locationcombo.h
new file mode 100644
index 0000000..fab3dfc
--- a/dev/null
+++ b/library/locationcombo.h
@@ -0,0 +1,88 @@
+/**********************************************************************
+** 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 LOCATIONCOMBO_H
+#define LOCATIONCOMBO_H
+
+#include <qpe/qpeglobal.h>
+
+#ifdef Q_WS_QWS
+
+#include <qstringlist.h>
+#include <qcombobox.h>
+
+class AppLnk;
+class QListViewItem;
+class DocLnk;
+class FileSystem;
+class StorageInfo;
+
+
+class LocationComboPrivate;
+
+class LocationCombo : public QComboBox
+{
+ Q_OBJECT
+public:
+ LocationCombo( QWidget *parent, const char *name=0 );
+ LocationCombo( const AppLnk * lnk, QWidget *parent, const char *name=0 );
+
+ ~LocationCombo();
+
+ void setLocation( const QString& path ); // qtopia 2
+ void setLocation( const AppLnk * );
+
+ QString installationPath() const;
+ QString documentPath() const;
+ const FileSystem *fileSystem() const;
+
+ bool isChanged() const;
+
+signals:
+ void newPath();
+
+private slots:
+ void updatePaths();
+
+private:
+ void setupCombo();
+ QStringList locations;
+ StorageInfo *storage;
+ LocationComboPrivate *d;
+};
+
+
+#endif // QWS
+#endif // LNKPROPERTIES_H
diff --git a/library/qlibrary_unix.cpp b/library/qlibrary_unix.cpp
index fee73c2..f4d60cb 100644
--- a/library/qlibrary_unix.cpp
+++ b/library/qlibrary_unix.cpp
@@ -198,7 +198,7 @@ bool QLibraryPrivate::loadLibrary()
QString filename = library->library();
- pHnd = dlopen( filename.latin1() , RTLD_LAZY );
+ pHnd = ::dlopen( filename.latin1() , RTLD_LAZY );
// #if defined(QT_DEBUG) || defined(QT_DEBUG_COMPONENT)
if ( !pHnd )
qWarning( "%s", dlerror() );
@@ -211,7 +211,7 @@ bool QLibraryPrivate::freeLibrary()
if ( !pHnd )
return TRUE;
- int ec = dlclose( pHnd );
+ int ec = ::dlclose( pHnd );
if ( !ec )
pHnd = 0;
#if defined(QT_DEBUG) || defined(QT_DEBUG_COMPONENT)
diff --git a/library/timestring.cpp b/library/timestring.cpp
index 91c29ae..afd162d 100644
--- a/library/timestring.cpp
+++ b/library/timestring.cpp
@@ -1,15 +1,30 @@
/**********************************************************************
-** Copyright (C) 2000-2002 Trolltech AS. All rights reserved.
+** Copyright (C) 2000-2006 Trolltech AS. All rights reserved.
**
** This file is part of the Qtopia Environment.
**
-** This file may be distributed and/or modified under the terms of the
-** GNU General Public License version 2 as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL included in the
-** packaging of this file.
+** 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.
**
-** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
-** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+** 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.
**
@@ -20,18 +35,21 @@
#include "timestring.h"
#include <qobject.h>
-#include <qpe/qpeapplication.h> //for qApp
+#include <qdatetime.h>
+#include <qapplication.h>
#include "config.h"
+#include <time.h>
+
-class TimeStringFormatKeeper : public QObject
+class TimeStringFormat : public QObject
{
Q_OBJECT
public:
static DateFormat currentFormat()
{
if ( !self )
- self = new TimeStringFormatKeeper;
+ self = new TimeStringFormat;
return self->format;
}
private slots:
@@ -40,24 +58,24 @@ private slots:
format = f;
}
private:
- static TimeStringFormatKeeper *self;
+ static TimeStringFormat *self;
DateFormat format;
- TimeStringFormatKeeper()
+ TimeStringFormat()
: QObject( qApp )
{
Config config("qpe");
config.setGroup( "Date" );
- format = DateFormat(QChar(config.readEntry("Separator", "/")[0]),
- (DateFormat::Order)config .readNumEntry("ShortOrder", DateFormat::DayMonthYear),
- (DateFormat::Order)config.readNumEntry("LongOrder", DateFormat::DayMonthYear));
+ format = ::DateFormat(QChar(config.readEntry("Separator", "/")[0]),
+ (::DateFormat::Order)config.readNumEntry("ShortOrder", ::DateFormat::DayMonthYear),
+ (::DateFormat::Order)config.readNumEntry("LongOrder", ::DateFormat::DayMonthYear));
connect( qApp, SIGNAL( dateFormatChanged(DateFormat) ),
this, SLOT( formatChanged(DateFormat) ) );
}
};
-TimeStringFormatKeeper *TimeStringFormatKeeper::self = 0;
+TimeStringFormat *TimeStringFormat::self = 0;
QString DateFormat::toNumberString() const
{
@@ -67,13 +85,13 @@ QString DateFormat::toNumberString() const
// switch on the relavent 3 bits.
switch((_shortOrder >> (i * 3)) & 0x0007) {
case 0x0001:
- buf += QObject::tr( "D" , "Shortcut for Day");
+ buf += TimeStringFormat::tr( "D", "first letter of the word 'Day'" );
break;
case 0x0002:
- buf += QObject::tr( "M", "Shortcur for Month" );
+ buf += TimeStringFormat::tr( "M" , "first letter of the word 'Month'" );
break;
case 0x0004:
- buf += QObject::tr( "Y" );
+ buf += TimeStringFormat::tr( "Y" , "first letter of the word 'Year'" );
break;
}
if (i < 2)
@@ -90,7 +108,7 @@ QString DateFormat::toWordString() const
// switch on the relavent 3 bits.
switch((_longOrder >> (i * 3)) & 0x0007) {
case 0x0001:
- buf += QObject::tr( "day" );
+ buf += TimeStringFormat::tr( "day", "in month" );
if (i < 2) {
if ((_shortOrder << ((i+1) * 3)) & 0x0007)
buf += ", ";
@@ -99,12 +117,12 @@ QString DateFormat::toWordString() const
}
break;
case 0x0002:
- buf += QObject::tr( "month" );
+ buf += TimeStringFormat::tr( "month" );
if (i < 2)
buf += " ";
break;
case 0x0004:
- buf += QObject::tr( "year" );
+ buf += TimeStringFormat::tr( "year" );
if (i < 2)
buf += ", ";
break;
@@ -149,64 +167,140 @@ QString DateFormat::numberDate(const QDate &d, int v) const
return buf;
}
+static const char* unTranslatedFullMonthNames[] = {
+ QT_TRANSLATE_NOOP( "QDate", "January" ),
+ QT_TRANSLATE_NOOP( "QDate", "February" ),
+ QT_TRANSLATE_NOOP( "QDate", "March" ),
+ QT_TRANSLATE_NOOP( "QDate", "April" ),
+ QT_TRANSLATE_NOOP( "QDate", "May" ),
+ QT_TRANSLATE_NOOP( "QDate", "June" ),
+ QT_TRANSLATE_NOOP( "QDate", "July" ),
+ QT_TRANSLATE_NOOP( "QDate", "August" ),
+ QT_TRANSLATE_NOOP( "QDate", "September" ),
+ QT_TRANSLATE_NOOP( "QDate", "October" ),
+ QT_TRANSLATE_NOOP( "QDate", "November" ),
+ QT_TRANSLATE_NOOP( "QDate", "December" )
+};
+
+static const char* unTranslatedFullDayNames[] = {
+ QT_TRANSLATE_NOOP( "QDate", "Monday" ),
+ QT_TRANSLATE_NOOP( "QDate", "Tuesday" ),
+ QT_TRANSLATE_NOOP( "QDate", "Wednesday" ),
+ QT_TRANSLATE_NOOP( "QDate", "Thursday" ),
+ QT_TRANSLATE_NOOP( "QDate", "Friday" ),
+ QT_TRANSLATE_NOOP( "QDate", "Saturday" ),
+ QT_TRANSLATE_NOOP( "QDate", "Sunday" )
+};
+
+#ifdef QTOPIA_DESKTOP
+//translations in qt.qm
+static const char* unTranslatedMediumDayNames[] = {
+ "Mon" , "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"
+};
+
+static const char* unTranslatedMediumMonthNames[] = {
+ "Jan", "Feb", "Mar", "Apr", "May", "Jun",
+ "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
+};
+#endif
+
+static QString dayname(const QDate& d, bool lng)
+{
+ if (lng && qApp)
+ return qApp->translate("QDate", unTranslatedFullDayNames[d.dayOfWeek()-1]);
+ else {
+#ifdef QTOPIA_DESKTOP
+ if (qApp)
+ return qApp->translate("QDate", unTranslatedMediumDayNames[ d.dayOfWeek()-1]);
+#endif
+ return d.dayName(d.dayOfWeek());
+ }
+}
+
QString DateFormat::wordDate(const QDate &d, int v) const
{
- QString buf = "";
// for each part of the order
- if (v & showWeekDay) {
- QString weekDay = d.dayName(d.dayOfWeek());
- if (!(v & longWord)) {
- weekDay = weekDay.left(3);
- }
- buf += weekDay;
- if ((_longOrder & 0x0007) == 0x0002)
- buf += ' ';
- else
- buf += ", ";
- }
+ QString weekDay;
+ if (v & showWeekDay)
+ weekDay = ::dayname(d,(v & longWord));
+ QString date="";
+ QString sep="";
for (int i = 0; i < 3; i++) {
// switch on the relavent 3 bits.
- switch((_longOrder >> (i * 3)) & 0x0007) {
- case 0x0001:
- if (i==1) {
- buf += QString().sprintf("%02d, ",d.day());
- } else {
- buf += QString().sprintf("%2d",d.day());
- if (separator()=='.') // 2002/1/11
- buf += ". ";
- else
- buf += " ";
- }
+ int field = (_longOrder >> (i * 3)) & 0x0007;
+ if ( field && !date.isEmpty() )
+ date += sep;
+ switch (field) {
+ case 0x0001: // Day
+ {
+ QString daysuffix = TimeStringFormat::tr("@day", "day suffix - applies to some asian languages (e.g. Japanese and Trad. Chinese). If it doesn't apply to your language it has to be translated to an '@day' " );
+ if (i==1) {
+ date += QString().sprintf("%02d",d.day());
+ if (daysuffix != "@day")
+ date+=daysuffix;
+ sep = TimeStringFormat::tr(",","day-date separator") + " ";
+ } else {
+ date += QString().sprintf("%2d",d.day());
+ if (daysuffix == "@day") {
+ if (separator()=='.') // 2002/1/11
+ sep = ". ";
+ else
+ sep = " ";
+ } else {
+ date += daysuffix+" ";
+ sep = " ";
+ }
+ }
+ }
break;
- case 0x0002:
+ case 0x0002: // Month
{
- QString monthName = d.monthName(d.month());
- if (!(v & longWord)) {
- monthName = monthName.left(3);
- }
- buf += monthName;
+ QString monthName;
+
+ if (v & longWord)
+ monthName = qApp->translate("QDate", unTranslatedFullMonthNames[d.month()-1] );
+ else {
+#ifdef QTOPIA_DESKTOP
+ monthName = qApp->translate("QDate", unTranslatedMediumMonthNames[d.month()-1] );
+#else
+ monthName = d.monthName( d.month() );
+#endif
+ }
+ date += monthName;
}
- if (i < 2)
- buf += " ";
+ sep = " ";//TimeStringFormat::tr(" ","month-date separator");
break;
- case 0x0004:
+ case 0x0004: // Year
{
int year = d.year();
if (!(v & longNumber))
year = year % 100;
if (year < 10)
- buf += "0";
+ date += "0";
+
+ date += QString::number(year);
+ QString yearsuffix = TimeStringFormat::tr("@year", "year suffix - applies to some asian languages (e.g. Japanese and Trad. Chinese). If it doesn't apply to your language it has to be translated to an '@year' " );
+ if (yearsuffix != "@year")
+ date += yearsuffix;
- buf += QString::number(year);
}
- if (i < 2)
- buf += ", ";
+ sep = TimeStringFormat::tr(",","year-date seperator") + " ";
break;
}
}
- return buf;
+
+ QString r = "";
+ if ( weekDay.isEmpty() )
+ r = date;
+ else if ((_longOrder & 0x0007) == 0x0002)
+ r = TimeStringFormat::tr("%1 %2","1=Monday 2=January 12").arg(weekDay).arg(date);
+ else if ( _longOrder )
+ r = TimeStringFormat::tr("%1, %2","1=Monday 2=12 January").arg(weekDay).arg(date);
+ else
+ r = weekDay;
+ return r;
}
#ifndef QT_NO_DATASTREAM
@@ -251,19 +345,19 @@ QString TimeString::shortDate( const QDate &d, DateFormat dtf )
QString TimeString::dateString( const QDate &d, DateFormat dtf )
{
- return QObject::tr( dtf.wordDate(d, DateFormat::longNumber | DateFormat::longWord) );
+ return dtf.wordDate(d, DateFormat::longNumber);
}
QString TimeString::longDateString( const QDate &d, DateFormat dtf )
{
- return QObject::tr( dtf.wordDate(d, DateFormat::showWeekDay | DateFormat::longNumber
- | DateFormat::longWord) );
+ return dtf.wordDate(d, DateFormat::showWeekDay | DateFormat::longNumber
+ | DateFormat::longWord);
}
DateFormat TimeString::currentDateFormat()
{
- return TimeStringFormatKeeper::currentFormat();
+ return TimeStringFormat::currentFormat();
}
@@ -313,28 +407,19 @@ QString TimeString::timeString( const QTime &t, bool ampm, bool seconds )
if ( seconds )
argString = argString.arg( strSec );
if ( hour >= 12 )
- argString = argString.arg( QObject::tr("PM") );
+ argString = argString.arg( TimeStringFormat::tr("PM") );
else
- argString = argString.arg( QObject::tr("AM") );
+ argString = argString.arg( TimeStringFormat::tr("AM") );
return argString;
}
QString TimeString::shortTime( bool ampm, bool seconds )
{
- static const char* const day[] = {
- QT_TRANSLATE_NOOP( "QObject", "Mon" ),
- QT_TRANSLATE_NOOP( "QObject", "Tue" ),
- QT_TRANSLATE_NOOP( "QObject", "Wed" ),
- QT_TRANSLATE_NOOP( "QObject", "Thu" ),
- QT_TRANSLATE_NOOP( "QObject", "Fri" ),
- QT_TRANSLATE_NOOP( "QObject", "Sat" ),
- QT_TRANSLATE_NOOP( "QObject", "Sun" )
- };
// just create a shorter time String
QDateTime dtTmp = QDateTime::currentDateTime();
- QString strTime;
- strTime = QObject::tr( day[dtTmp.date().dayOfWeek()-1] ) + " " +
- timeString( dtTmp.time(), ampm, seconds );
+ QString strTime = TimeStringFormat::tr( "%1 %2", "1=Monday 2=12:45" )
+ .arg(::dayname(dtTmp.date(),FALSE))
+ .arg(timeString( dtTmp.time(), ampm, seconds ));
return strTime;
}
@@ -361,5 +446,21 @@ QString TimeString::longNumberDateString( const QDate &d, DateFormat dtf )
{
return dtf.numberDate(d,DateFormat::longNumber);
}
+/*!
+ Returns date/time \a dt as a string,
+ showing year, month, date, hours, minutes, and seconds.
+ \a len determines the length of the resulting string.
+
+ The format, including order depends on the user's settings.
+
+ First availability: Qtopia 1.6
+*/
+//QString TimeString::localYMDHMS( const QDateTime &dt, Length len )
+//{
+// const QDate& d = dt.date();
+// const QTime& t = dt.time();
+// return LocalTimeFormat::tr("%1 %2","date,time").arg(localYMD(d,len)).arg(localHMS(t));
+//}
+
#include "timestring.moc"
diff --git a/library/timestring.h b/library/timestring.h
index 875c8bf..b8d1aea 100644
--- a/library/timestring.h
+++ b/library/timestring.h
@@ -1,16 +1,31 @@
/**********************************************************************
-** Copyright (C) 2000-2002 Trolltech AS. All rights reserved.
+** 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 file may be distributed and/or modified under the terms of the
-** GNU General Public License version 2 as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL included in the
-** packaging of this file.
-**
-** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
-** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+** 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
@@ -22,23 +37,28 @@
#define _TIMESTRING_H_
#include <qdatetime.h>
#include <qstring.h>
+#include <qarray.h>
#if (QT_VERSION-0 >= 0x030000)
#define DateFormat QPEDateFormat
#endif
+#include <qtopia/qpeglobal.h>
+
+class QObject;
+
// return a string with the time based on whether or not you want
// you want it in 12 hour form. if ampm is true, then return
// it in 12 hour (am/pm) form otherwise return it in 24 hour form
// in theory Qt 3,0 handles this better (hopefully obsoleteing this)
-class DateFormat
+class DateFormat
{
public:
- // date format type 001,010,100 = day month year
+ // date format type 1,2,4 = day,month,year
enum Order {
- DayMonthYear = 0x0111, // 0x001 + 0x010(0x2 << 3) + 0x100(0x4 << 3)
- MonthDayYear = 0x010A,
- YearMonthDay = 0x0054
+ DayMonthYear = 0421, // right-to-left
+ MonthDayYear = 0412,
+ YearMonthDay = 0124
};
DateFormat(QChar s = '/', Order so = MonthDayYear) : _shortOrder(so),
@@ -99,34 +119,48 @@ class TimeString
{
public:
- //enum DateFormat { MonthDayYear, DayMonthYear, ISO8601,
+ //enum DateFormat { MonthDayYear, DayMonthYear, ISO8601,
//YearMonthDay = ISO8601 };
-/**
- * @name Convience functions which use currentDateFormat
- */
-//@{
- static QString shortDate( const QDate &d )
+
+//private:
+ static QString shortDate( const QDate &d )
{ return shortDate( d, currentDateFormat() ); }
static QString dateString( const QDate &d )
{ return dateString( d, currentDateFormat() ); }
static QString longDateString( const QDate &d )
{ return longDateString( d, currentDateFormat() ); }
-//@}
static QString dateString( const QDateTime &dt, bool ampm, bool seconds )
{ return dateString( dt, ampm, seconds, currentDateFormat() ); }
+public:
+ enum Length { Short, Medium, Long };
+ static QString localH( int hour );
+ static QString localHM( const QTime & );
+ static QString localHM( const QTime &, Length ); // qtopia 2.1.0
+ static QString localHMS( const QTime & );
+ static QString localHMDayOfWeek( const QDateTime &t );
+ static QString localHMSDayOfWeek( const QDateTime &t );
+ static QString localMD( const QDate &, Length=Medium );
+ static QString localYMD( const QDate &, Length=Medium );
+ static QString localYMDHMS( const QDateTime &, Length=Medium );
+ static QString localDayOfWeek( const QDate&, Length=Medium );
+ static QString localDayOfWeek( int day1to7, Length=Medium );
+
+ static QString hourString( int hour, bool ampm );
+ static bool currentAMPM();
+ static DateFormat currentDateFormat();
+ static QArray<DateFormat> formatOptions(); // qtopia 1.6.0
+
+ static void connectChange(QObject*,const char* member);
+ static void disconnectChange(QObject*,const char* member);
- /** @name Do not use as they don't honor system settings for AMPM
- *
- */
- //@{
- static QString dateString( const QDateTime &t, bool ampm = false );
+ // Not recommended to call these (they don't honor system ampm)
+ static QString dateString( const QDateTime &t, bool ampm );
static QString timeString( const QTime &t, bool ampm, bool seconds );
- static QString timeString( const QTime &t, bool ampm = false );
+ static QString timeString( const QTime &t, bool ampm );
static QString shortTime( bool ampm, bool seconds );
- static QString shortTime( bool ampm = false );
- //@}
+ static QString shortTime( bool ampm );
static QString numberDateString( const QDate &d, DateFormat );
static QString numberDateString( const QDate &d )
@@ -139,11 +173,9 @@ public:
static QString dateString( const QDate &, DateFormat );
static QString longDateString( const QDate &, DateFormat );
- static DateFormat currentDateFormat();
-
private:
static QString dateString( const QDateTime &t, bool ampm, bool seconds, DateFormat );
-
+
};
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
+
diff --git a/packages b/packages
index 08e1ea9..d45dbf7 100644
--- a/packages
+++ b/packages
@@ -20,6 +20,7 @@ CONFIG_CALC2 noncore/tools/calc2 calc2.pro
CONFIG_CALCULATOR noncore/tools/calculator calculator.pro
CONFIG_CALIBRATE core/apps/calibrate calibrate.pro
CONFIG_CAMERA noncore/multimedia/camera camera.pro
+CONFIG_CAMERA2 noncore/multimedia/camera2 camera2.pro
CONFIG_CARDMON core/applets/cardmon cardmon.pro
CONFIG_CHECKBOOK noncore/apps/checkbook checkbook.pro
CONFIG_CITYTIME core/settings/citytime citytime.pro
diff --git a/pics/camera2/Camera.png b/pics/camera2/Camera.png
new file mode 100644
index 0000000..e619c11
--- a/dev/null
+++ b/pics/camera2/Camera.png
Binary files differ
diff --git a/pics/camera2/Camera_48.png b/pics/camera2/Camera_48.png
new file mode 100644
index 0000000..00b8585
--- a/dev/null
+++ b/pics/camera2/Camera_48.png
Binary files differ
diff --git a/pics/camera2/Camera_48_anim.mng b/pics/camera2/Camera_48_anim.mng
new file mode 100644
index 0000000..6b19394
--- a/dev/null
+++ b/pics/camera2/Camera_48_anim.mng
Binary files differ
diff --git a/pics/camera2/settings.png b/pics/camera2/settings.png
new file mode 100644
index 0000000..05bfdf7
--- a/dev/null
+++ b/pics/camera2/settings.png
Binary files differ