author | llornkcor <llornkcor> | 2006-07-09 18:56:40 (UTC) |
---|---|---|
committer | llornkcor <llornkcor> | 2006-07-09 18:56:40 (UTC) |
commit | 36dece4760b1ac1799929221b49eb3bee98c2367 (patch) (side-by-side diff) | |
tree | a45f66d2d90bd9fbbff8e8903cd1cb9323c39f6e | |
parent | 604065c6e662cb3894acf03abadafacc3ab52913 (diff) | |
download | opie-36dece4760b1ac1799929221b49eb3bee98c2367.zip opie-36dece4760b1ac1799929221b49eb3bee98c2367.tar.gz opie-36dece4760b1ac1799929221b49eb3bee98c2367.tar.bz2 |
initial commit to add video4linux camera app from qtopia 2, needs more work
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 @@ -1,229 +1,230 @@ /********************************************************************** ** Copyright (C) 2000 Trolltech AS. All rights reserved. ** ** This file is part of 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 file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING ** THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A ** PARTICULAR PURPOSE. ** ** 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 QTPALMTOP_CATEGORIES_H #define QTPALMTOP_CATEGORIES_H #include <qstring.h> #include <qstringlist.h> #include <qmap.h> #include <qlistview.h> #include <qarray.h> #include "qpcglobal.h" #include "palmtopuidgen.h" class CategoryGroup; +QString categoryFileName(); #if defined(QPC_TEMPLATEDLL) // MOC_SKIP_BEGIN template class QPC_EXPORT QMap<int, QString>; template class QPC_EXPORT QMap<QString, int>; template class QPC_EXPORT QMap< QString, CategoryGroup >; // MOC_SKIP_END #endif class QPC_EXPORT CategoryGroup { friend class Categories; public: CategoryGroup(): mIdLabelMap(), mLabelIdMap() { } CategoryGroup( const CategoryGroup &c ) : mIdLabelMap( c.mIdLabelMap), mLabelIdMap( c.mLabelIdMap ) { } void clear() { mIdLabelMap.clear(); mLabelIdMap.clear(); } int add( const QString &label ); bool add( int uid, const QString &label ); bool remove( const QString &label ); bool remove( int uid ); bool rename( int uid, const QString &newLabel ); bool rename( const QString &oldLabel, const QString &newLabel ); bool contains(int id) const; bool contains(const QString &label) const; /** Returns label associated with the uid or QString::null if * not found */ const QString &label(int id) const; /** Returns the uid associated with label or 0 if not found */ int id(const QString &label) const; /** Returns a sorted list of labels */ QStringList labels() const; QStringList labels( const QArray<int> &catids ) const; const QMap<int, QString> &idMap() const { return mIdLabelMap; } private: void insert( int uid, const QString &label ); QMap<int, QString> mIdLabelMap; QMap<QString, int> mLabelIdMap; static Qtopia::UidGen &uidGen() { return sUidGen; } static Qtopia::UidGen sUidGen; }; /* Map from application name to categories */ class QPC_EXPORT Categories : public QObject { Q_OBJECT public: Categories( QObject *parent=0, const char *name = 0 ) : QObject( parent, name ), mGlobalCats(), mAppCats() { } Categories( const Categories ©From ) : QObject( copyFrom.parent() ), mGlobalCats( copyFrom.mGlobalCats ), mAppCats( copyFrom.mAppCats ) { } virtual ~Categories() { } Categories &operator= ( const Categories &c ) { mAppCats = c.mAppCats; mGlobalCats = c.mGlobalCats; return *this; } void clear(); /** Add the category name as long as it doesn't already exist * locally or globally. Return UID if added, 0 if conflicts * (error). */ int addCategory( const QString &appname, const QString &catname); /** Add the category name as long as it doesn't already exist * locally or globally. Return UID if added, 0 if conflicts * (error). */ int addCategory( const QString &appname, const QString &catname, int uid); /** Add the global category just checking that it doesn't * already exist globally. Return UID if added, 0 if conflicts. */ int addGlobalCategory( const QString &catname ); /** Add the global category just checking that it doesn't * already exist globally. Return UID if added, 0 if conflicts. */ int addGlobalCategory( const QString &catname, int uid ); /** Removes the category from the application; if it is not found * in the application, then it removes it from the global list */ bool removeCategory( const QString &appName, const QString &catName, bool checkGlobal = TRUE); bool removeCategory( const QString &appName, int uid ); bool removeGlobalCategory( const QString &catName ); bool removeGlobalCategory( int uid ); QArray<int> ids( const QString &app, const QStringList &labels) const; /** Returns the id associated with the app */ int id( const QString &app, const QString &cat ) const; /** Returns the label associated with the id */ QString label( const QString &app, int id ) const; enum ExtraLabels { NoExtra, AllUnfiled, AllLabel, UnfiledLabel }; /** Returns the sorted list of all categories that are * associated with the app. * If includeGlobal parameter is TRUE then the returned * categories will include the global category items. * If extra = NoExtra, then * If extra = AllUnfiled, then All and Unfiled will be prepended to * the list * If extra = AllLabel, then All is prepended * If extra = UnfiledLabel, then Unfiled is prepended */ QStringList labels( const QString &app, bool includeGlobal = TRUE, ExtraLabels extra = NoExtra ) const; QStringList labels( const QString &app, const QArray<int> &catids ) const; enum DisplaySingle { ShowMulti, ShowAll, ShowFirst }; /** Returns a single string associated with the cat ids for display in * a combobox or any area that requires one string. If catids are empty * then "Unfiled" will be returned. If multiple categories are assigned * then the behavior depends on the DisplaySingle type. * If /a display is set to ShowMulti then " (multi)" appended to the * first string. If /a display is set to ShowAll, then a space seperated * string is returned with all categories. If ShowFirst is returned, * the just the first string is returned. */ QString displaySingle( const QString &app, const QArray<int> &catids, DisplaySingle display ) const; QStringList globalCategories() const { return mGlobalCats.labels();} bool renameCategory( const QString &appname, const QString &oldName, const QString &newName ); bool renameGlobalCategory( const QString &oldName, const QString &newName ); void setGlobal( const QString &appname, const QString &catname, bool value ); bool isGlobal( const QString &catname ) const; /** Returns true if the catname is associated with any application */ bool exists( const QString &catname ) const; bool exists( const QString &appname, const QString &catname) const; bool save( const QString &fname ) const; bool load( const QString &fname ); // for debugging void dump() const; const QMap<QString, CategoryGroup> &appGroupMap() const{ return mAppCats; } const CategoryGroup &globalGroup() const { return mGlobalCats; } signals: /** emitted if added a category; * the second param is the application the category was added to * or null if global * the third param is the uid of the newly added category */ void categoryAdded( const Categories &, const QString &, int ); /** emitted if removed a category * the second param is the application the category was removed from * or null if global * the third param is the uid of the removed category */ void categoryRemoved( const Categories &, const QString &, int ); /** emitted if a category is renamed; the second param is the uid of * the removed category */ void categoryRenamed( const Categories &, const QString &, int ); private: CategoryGroup mGlobalCats; QMap< QString, CategoryGroup > mAppCats; }; class QPC_EXPORT CheckedListView : public QListView { public: void addCheckableList( const QStringList &options ); void setChecked( const QStringList &checked ); QStringList checked() const; }; #endif diff --git a/library/global.cpp b/library/global.cpp index ec87555..f7a0767 100644 --- a/library/global.cpp +++ b/library/global.cpp @@ -427,386 +427,435 @@ void Global::showInputMethod() } /*! Explicitly hide the current input method. The current input method is still indicated in the taskbar, but no longer takes up screen space, and can no longer be interacted with. \sa showInputMethod() */ void Global::hideInputMethod() { #if !defined(QT_NO_COP) QCopChannel::send( "QPE/TaskBar", "hideInputMethod()" ); #endif } /*! \internal */ bool Global::isBuiltinCommand( const QString &name ) { if(!builtin) return FALSE; // yes, it can happen for (int i = 0; builtin[i].file; i++) { if ( builtin[i].file == name ) { return TRUE; } } return FALSE; } Global::Command* Global::builtin=0; QGuardedPtr<QWidget> *Global::running=0; /*! \class Global::Command \brief The Global::Command class is internal. \internal */ /*! \internal */ void Global::setBuiltinCommands( Command* list ) { if ( running ) delete [] running; builtin = list; int count = 0; if (!builtin) return; while ( builtin[count].file ) count++; running = new QGuardedPtr<QWidget> [ count ]; } /*! \internal */ void Global::setDocument( QWidget* receiver, const QString& document ) { Emitter emitter(receiver,document); } /*! \internal */ bool Global::terminateBuiltin( const QString& n ) { if (!builtin) return FALSE; for (int i = 0; builtin[i].file; i++) { if ( builtin[i].file == n ) { delete running[i]; return TRUE; } } return FALSE; } /*! \internal */ void Global::terminate( const AppLnk* app ) { //if ( terminateBuiltin(app->exec()) ) return; // maybe? haven't tried this #ifndef QT_NO_COP QCString channel = "QPE/Application/" + app->exec().utf8(); if ( QCopChannel::isRegistered(channel) ) { QCopEnvelope e(channel, "quit()"); } #endif } /*! Low-level function to run command \a c. \warning Do not use this function. Use execute instead. \sa execute() */ void Global::invoke(const QString &c) { // Convert the command line in to a list of arguments QStringList list = QStringList::split(QRegExp(" *"),c); #if !defined(QT_NO_COP) QString ap=list[0]; // see if the application is already running // XXX should lock file /tmp/qcop-msg-ap if ( QCopChannel::isRegistered( ("QPE/Application/" + ap).latin1() ) ) { // If the channel is already register, the app is already running, so show it. { QCopEnvelope env( ("QPE/Application/" + ap).latin1(), "raise()" ); } //QCopEnvelope e("QPE/System", "notBusy(QString)" ); //e << ap; return; } // XXX should unlock file /tmp/qcop-msg-ap //see if it is being started if ( StartingAppList::isStarting( ap ) ) { // FIXME take it out for now, since it leads to a much to short showing of wait if // some entry is clicked. // Real cause is that ::execute is called twice for document tab. But it would need some larger changes // to fix that, and with future syncs with qtopia 1.6 it will change anyway big time since somebody there // had the idea that an apploader belongs to the launcher ... //QCopEnvelope e("QPE/System", "notBusy(QString)" ); //e << ap; return; } #endif #ifdef QT_NO_QWS_MULTIPROCESS QMessageBox::warning( 0, "Error", "Could not find the application " + c, "Ok", 0, 0, 0, 1 ); #else QStrList slist; unsigned int j; for ( j = 0; j < list.count(); j++ ) slist.append( list[j].utf8() ); const char **args = new const char *[slist.count() + 1]; for ( j = 0; j < slist.count(); j++ ) args[j] = slist.at(j); args[j] = NULL; #if !defined(QT_NO_COP) // an attempt to show a wait... // more logic should be used, but this will be fine for the moment... QCopEnvelope ( "QPE/System", "busy()" ); #endif #ifdef HAVE_QUICKEXEC #ifdef Q_OS_MACX QString libexe = qpeDir()+"/binlib/lib"+args[0] + ".dylib"; #else QString libexe = qpeDir()+"/binlib/lib"+args[0] + ".so"; #endif qDebug("libfile = %s", libexe.latin1() ); if ( QFile::exists( libexe ) ) { qDebug("calling quickexec %s", libexe.latin1() ); quickexecv( libexe.utf8().data(), (const char **)args ); } else #endif { bool success = false; int pfd [2]; if ( ::pipe ( pfd ) < 0 ) pfd [0] = pfd [1] = -1; pid_t pid = ::fork ( ); if ( pid == 0 ) { // child for ( int fd = 3; fd < 100; fd++ ) { if ( fd != pfd [1] ) ::close ( fd ); } ::setpgid ( ::getpid ( ), ::getppid ( )); // Closing of fd[1] indicates that the execvp succeeded! if ( pfd [1] >= 0 ) ::fcntl ( pfd [1], F_SETFD, FD_CLOEXEC ); // Try bindir first, so that foo/bar works too ::execv ( qpeDir ( ) + "/bin/" + args [0], (char * const *) args ); ::execvp ( args [0], (char * const *) args ); char resultByte = 1; if ( pfd [1] >= 0 ) ::write ( pfd [1], &resultByte, 1 ); ::_exit ( -1 ); } else if ( pid > 0 ) { success = true; if ( pfd [1] >= 0 ) ::close ( pfd [1] ); if ( pfd [0] >= 0 ) { while ( true ) { char resultByte; int n = ::read ( pfd [0], &resultByte, 1 ); if ( n == 1 ) { success = false; break; } if (( n == -1 ) && (( errno == ECHILD ) || ( errno == EINTR ))) continue; break; // success } ::close ( pfd [0] ); } } if ( success ) StartingAppList::add( list[0] ); else QMessageBox::warning( 0, "Error", "Could not start the application " + c, "Ok", 0, 0, 0, 1 ); } #endif //QT_NO_QWS_MULTIPROCESS } /*! Executes the application identfied by \a c, passing \a document if it isn't null. Note that a better approach might be to send a QCop message to the application's QPE/Application/\e{appname} channel. */ void Global::execute( const QString &c, const QString& document ) { // ask the server to do the work #if !defined(QT_NO_COP) if ( document.isNull() ) { QCopEnvelope e( "QPE/System", "execute(QString)" ); e << c; } else { QCopEnvelope e( "QPE/System", "execute(QString,QString)" ); e << c << document; } #endif return; } /*! Returns the string \a s with the characters '\', '"', and '$' quoted by a preceeding '\'. \sa stringQuote() */ QString Global::shellQuote(const QString& s) { QString r="\""; for (int i=0; i<(int)s.length(); i++) { char c = s[i].latin1(); switch (c) { case '\\': case '"': case '$': r+="\\"; } r += s[i]; } r += "\""; return r; } /*! Returns the string \a s with the characters '\' and '"' quoted by a preceeding '\'. \sa shellQuote() */ QString Global::stringQuote(const QString& s) { QString r="\""; for (int i=0; i<(int)s.length(); i++) { char c = s[i].latin1(); switch (c) { case '\\': case '"': r+="\\"; } r += s[i]; } r += "\""; return r; } /*! Finds all documents on the system's document directories which match the filter \a mimefilter, and appends the resulting DocLnk objects to \a folder. */ void Global::findDocuments(DocLnkSet* folder, const QString &mimefilter) { QString homedocs = QString(getenv("HOME")) + "/Documents"; DocLnkSet d(homedocs,mimefilter); folder->appendFrom(d); /** let's do intellegint way of searching these files * a) the user don't want to check mediums global * b) the user wants to check but use the global options for it * c) the user wants to check it but not this medium * d) the user wants to check and this medium as well * * In all cases we need to apply a different mimefilter to * the medium. * a) mimefilter.isEmpty() we need to apply the responding filter * either the global or the one on the medium * * b) mimefilter is set to an application we need to find out if the * mimetypes are included in the mime mask of the medium */ StorageInfo storage; const QList<FileSystem> &fs = storage.fileSystems(); QListIterator<FileSystem> it ( fs ); for ( ; it.current(); ++it ) { if ( (*it)->isRemovable() ) { // let's find out if we should search on it // this is a candidate look at the cf and see if we should search on it QString path = (*it)->path(); Config conf((*it)->path() + "/.opiestorage.cf", Config::File ); conf.setGroup("main"); if (!conf.readBoolEntry("check",true)) { continue; } conf.setGroup("subdirs"); if (conf.readBoolEntry("wholemedia",true)) { DocLnkSet ide( path,mimefilter); folder->appendFrom(ide); } else { QStringList subDirs = conf.readListEntry("subdirs",':'); if (subDirs.isEmpty()) { subDirs.append("Documents"); } for (unsigned c = 0; c < subDirs.count();++c) { DocLnkSet ide( path+"/"+subDirs[c], mimefilter ); folder->appendFrom(ide); } } } else if ( (*it)->disk() == "/dev/mtdblock6" || (*it)->disk() == "tmpfs" ) { QString path = (*it)->path() + "/Documents"; DocLnkSet ide( path, mimefilter ); folder->appendFrom(ide); } } } QStringList Global::languageList() { QString lang = getenv("LANG"); QStringList langs; langs.append(lang); int i = lang.find("."); if ( i > 0 ) lang = lang.left( i ); i = lang.find( "_" ); if ( i > 0 ) langs.append(lang.left(i)); return langs; } QStringList Global::helpPath() { QString qpeDir = QPEApplication::qpeDir(); QStringList path; QStringList langs = Global::languageList(); for (QStringList::ConstIterator it = langs.fromLast(); it!=langs.end(); --it) { QString lang = *it; if ( !lang.isEmpty() ) path += qpeDir + "/help/" + lang + "/html"; } path += qpeDir + "/pics"; path += qpeDir + "/help/html"; /* we even put english into the en dir so try it as fallback as well for opie */ path += qpeDir + "/help/en/html"; path += qpeDir + "/docs"; 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 @@ -1,90 +1,94 @@ /********************************************************************** ** Copyright (C) 2000-2002 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 file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. ** ** 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 GLOBAL_H #define GLOBAL_H #include <qstringlist.h> #include <qguardedptr.h> class QDawg; class QLabel; class QWidget; class AppLnk; class DocLnkSet; - +class QFile; class Global { public: Global(); // Dictionaries static const QDawg& fixedDawg(); static const QDawg& addedDawg(); static const QDawg& dawg(const QString& name); static void addWords(const QStringList& word); static void addWords(const QString& dictname, const QStringList& word); // static void removeWords(const QStringList& word); -- if someone wants it static void createDocDir(); static void findDocuments(DocLnkSet* folder, const QString &mimefilter=QString::null); static QString applicationFileName(const QString& appname, const QString& filename); struct Command { const char *file; QWidget *(*func)( bool ); bool maximized; bool documentary; }; static void setBuiltinCommands( Command* ); static void execute( const QString &exec, const QString &document=QString::null ); static void setDocument( QWidget* receiver, const QString& document ); static bool terminateBuiltin( const QString& ); static void terminate( const AppLnk* ); static bool isBuiltinCommand( const QString &name ); // system messaging static void applyStyle(); static void statusMessage(const QString&); static QWidget *shutdown( bool = FALSE ); static QWidget *restart( bool = FALSE ); static void hideInputMethod(); static void showInputMethod(); static void writeHWClock(); static QString shellQuote(const QString& s); static QString stringQuote(const QString& s); #ifdef QTOPIA_INTERNAL_LANGLIST 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); static Command* builtin; static QGuardedPtr<QWidget> *running; }; #endif diff --git a/library/library.pro b/library/library.pro index 7143454..4142529 100644 --- a/library/library.pro +++ b/library/library.pro @@ -1,141 +1,143 @@ TEMPLATE = lib #CONFIG += qt warn_on release CONFIG += qt warn_on debug HEADERS = calendar.h \ global.h \ resource.h \ xmlreader.h \ mimetype.h \ menubutton.h \ network.h \ networkinterface.h \ filemanager.h \ fontmanager.h \ qdawg.h \ datebookmonth.h \ fileselector.h \ fileselector_p.h \ imageedit.h \ qcopenvelope_qws.h \ qpedecoration_qws.h \ qpeapplication.h \ qpestyle.h \ qpedialog.h \ lightstyle.h \ config.h \ applnk.h \ sound.h \ tzselect.h \ qmath.h \ datebookdb.h \ alarmserver.h \ process.h \ password.h \ timestring.h \ fontfactoryinterface.h \ fontdatabase.h \ power.h \ storage.h \ qpemessagebox.h \ timeconversion.h \ qpedebug.h \ qpemenubar.h \ qpetoolbar.h \ backend/categories.h \ stringutil.h \ backend/palmtoprecord.h \ backend/task.h \ backend/event.h \ backend/contact.h\ categorymenu.h \ categoryedit_p.h \ categoryselect.h \ categorywidget.h \ ir.h \ backend/vobject_p.h \ findwidget_p.h \ finddialog.h \ lnkproperties.h \ windowdecorationinterface.h \ textcodecinterface.h \ imagecodecinterface.h \ + locationcombo.h \ qpeglobal.h SOURCES = calendar.cpp \ global.cpp \ xmlreader.cpp \ mimetype.cpp \ menubutton.cpp \ network.cpp \ networkinterface.cpp \ filemanager.cpp \ fontmanager.cpp \ qdawg.cpp \ datebookmonth.cpp \ fileselector.cpp \ imageedit.cpp \ resource.cpp \ qpedecoration_qws.cpp \ qcopenvelope_qws.cpp \ qpeapplication.cpp \ qpestyle.cpp \ qpedialog.cpp \ lightstyle.cpp \ config.cpp \ applnk.cpp \ sound.cpp \ tzselect.cpp \ qmath.c \ datebookdb.cpp \ alarmserver.cpp \ password.cpp \ process.cpp \ process_unix.cpp \ timestring.cpp \ fontdatabase.cpp \ power.cpp \ storage.cpp \ qpemessagebox.cpp \ backend/timeconversion.cpp \ qpedebug.cpp \ qpemenubar.cpp \ qpetoolbar.cpp \ backend/categories.cpp \ backend/stringutil.cpp \ backend/palmtoprecord.cpp \ backend/task.cpp \ backend/event.cpp \ backend/contact.cpp \ categorymenu.cpp \ categoryedit_p.cpp \ categoryselect.cpp \ categorywidget.cpp \ ir.cpp \ backend/vcc_yacc.cpp \ backend/vobject.cpp \ findwidget_p.cpp \ finddialog.cpp \ lnkproperties.cpp \ + locationcombo.cpp \ widget_showing.cpp # Qt 3 compatibility HEADERS += quuid.h qcom.h qlibrary.h qlibrary_p.h SOURCES += quuid.cpp qlibrary.cpp qlibrary_unix.cpp DEFINES += OPIE_INTERNAL_LIBRARY_BUILD INCLUDEPATH += $(OPIEDIR)/include backend LIBS += -ldl -lcrypt -lm INTERFACES = passwordbase_p.ui categoryeditbase_p.ui findwidgetbase_p.ui lnkpropertiesbase_p.ui TARGET = qpe DESTDIR = $(OPIEDIR)/lib$(PROJMAK) VERSION = 1.5.0.1 include( $(OPIEDIR)/include.pro ) contains( CONFIG, LIBQPE_WITHROHFEEDBACK ){ DEFINES += OPIE_WITHROHFEEDBACK SOURCES += backend/rohfeedback.cpp HEADERS += backend/rohfeedback.h } 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 @@ -1,243 +1,243 @@ /********************************************************************** ** Copyright (C) 2000-2002 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 file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. ** ** 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 "qlibrary_p.h" #ifndef QT_NO_COMPONENT /* The platform dependent implementations of - loadLibrary - freeLibrary - resolveSymbol It's not too hard to guess what the functions do. */ #if defined(Q_OS_HPUX) // for HP-UX < 11.x and 32 bit #include <dl.h> bool QLibraryPrivate::loadLibrary() { if ( pHnd ) return TRUE; QString filename = library->library(); pHnd = (void*)shl_load( filename.latin1(), BIND_DEFERRED | BIND_NONFATAL | DYNAMIC_PATH, 0 ); #if defined(QT_DEBUG) || defined(QT_DEBUG_COMPONENT) if ( !pHnd ) qDebug( "Failed to load library %s!", filename.latin1() ); #endif return pHnd != 0; } bool QLibraryPrivate::freeLibrary() { if ( !pHnd ) return TRUE; if ( !shl_unload( (shl_t)pHnd ) ) { pHnd = 0; return TRUE; } return FALSE; } void* QLibraryPrivate::resolveSymbol( const char* symbol ) { if ( !pHnd ) return 0; void* address = 0; if ( shl_findsym( (shl_t*)&pHnd, symbol, TYPE_UNDEFINED, address ) < 0 ) { #if defined(QT_DEBUG) || defined(QT_DEBUG_COMPONENT) qDebug( "Couldn't resolve symbol \"%s\"", symbol ); #endif return 0; } return address; } #elif defined(_NULL_LIB_) bool QLibraryPrivate::loadLibrary() { //qDebug("QLibraryPrivate::loadLibrary\n"); return FALSE; } bool QLibraryPrivate::freeLibrary() { //qDebug("QLibraryPrivate::freeLibrary\n"); return FALSE; } void* QLibraryPrivate::resolveSymbol( const char* symbol ) { //qDebug("QLibraryPrivate::resolveSymbol\n"); return FALSE; } #elif defined(Q_OS_MACX) #define ENUM_DYLD_BOOL enum DYLD_BOOL { DYLD_FALSE, DYLD_TRUE }; #include <mach-o/dyld.h> typedef struct { NSObjectFileImage img; NSModule mod; } DyldLibDesc; bool QLibraryPrivate::loadLibrary() { // qDebug("QLibraryPrivate::loadLibrary\n"); // return FALSE; if ( pHnd ) return TRUE; QString filename = library->library(); NSObjectFileImage img = 0; NSModule mod = 0; NSObjectFileImageReturnCode ret = NSCreateObjectFileImageFromFile( filename.latin1() , &img ); if ( ret != NSObjectFileImageSuccess ) { qWarning( "Error in NSCreateObjectFileImageFromFile(): %d; Filename: %s", ret, filename.latin1() ); if (ret == NSObjectFileImageAccess) { qWarning ("(NSObjectFileImageAccess)" ); } } else { mod = NSLinkModule(img, filename.latin1(), NSLINKMODULE_OPTION_BINDNOW | NSLINKMODULE_OPTION_PRIVATE | NSLINKMODULE_OPTION_RETURN_ON_ERROR); if (mod == 0) { qWarning( "Error in NSLinkModule()" ); NSDestroyObjectFileImage(img); } } DyldLibDesc* desc = 0; if (img != 0 && mod != 0) { desc = new DyldLibDesc; desc->img = img; desc->mod = mod; } pHnd = desc; return pHnd != 0; } bool QLibraryPrivate::freeLibrary() { //qDebug("QLibraryPrivate::freeLibrary\n"); //return FALSE; if ( !pHnd ) return TRUE; DyldLibDesc* desc = (DyldLibDesc*) pHnd; NSModule mod = desc->mod; NSObjectFileImage img = desc->img; bool success = NSUnLinkModule(mod, NSUNLINKMODULE_OPTION_NONE); if ( success ) { NSDestroyObjectFileImage(img); delete desc; pHnd = 0; } #if defined(QT_DEBUG) || defined(QT_DEBUG_COMPONENT) else { qWarning( "Error in NSUnLinkModule()" ); } #endif return pHnd == 0; } void* QLibraryPrivate::resolveSymbol( const char* symbol ) { //qDebug("QLibraryPrivate::resolveSymbol\n"); //return FALSE; if ( !pHnd ) return 0; DyldLibDesc* desc = (DyldLibDesc*) pHnd; NSSymbol sym = NSLookupSymbolInModule(desc->mod, symbol); void* address = 0; if (sym != 0) { address = NSAddressOfSymbol(sym); } #if defined(QT_DEBUG) || defined(QT_DEBUG_COMPONENT) if ( address == 0 ) qWarning( "Cannot find symbol: %s", symbol ); #endif return address; } #else // Something else, assuming POSIX #include <dlfcn.h> bool QLibraryPrivate::loadLibrary() { if ( pHnd ) return TRUE; 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() ); // #endif return pHnd != 0; } 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) else { const char* error = dlerror(); if ( error ) qWarning( "%s", error ); } #endif return pHnd == 0; } void* QLibraryPrivate::resolveSymbol( const char* f ) { if ( !pHnd ) return 0; void* address = dlsym( pHnd, f ); #if defined(QT_DEBUG) || defined(QT_DEBUG_COMPONENT) const char* error = dlerror(); if ( error ) qWarning( "%s", error ); #endif return address; } #endif // POSIX #endif // QT_NO_COMPONENT diff --git a/library/timestring.cpp b/library/timestring.cpp index 91c29ae..afd162d 100644 --- a/library/timestring.cpp +++ b/library/timestring.cpp @@ -1,365 +1,466 @@ /********************************************************************** -** 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. ** ** Contact info@trolltech.com if any conditions of this licensing are ** not clear to you. ** **********************************************************************/ #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: void formatChanged( DateFormat f ) { 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 { QString buf = ""; // for each part of the order for (int i = 0; i < 3; i++) { // 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) buf += _shortSeparator; } return buf; } QString DateFormat::toWordString() const { QString buf = ""; // for each part of the order for (int i = 0; i < 3; i++) { // 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 += ", "; else buf += " "; } 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; } } return buf; } QString DateFormat::numberDate(const QDate &d, int v) const { QString buf = ""; int pad = 2; // for each part of the order for (int i = 0; i < 3; i++) { // switch on the relavent 3 bits. switch((_shortOrder >> (i * 3)) & 0x0007) { case 0x0001: if (pad==2) buf += QString().sprintf("%02d",d.day()); else buf += QString().sprintf("%d",d.day()); break; case 0x0002: if (i==0) { // no padding with only MM/DD/YY format pad=0; } if (pad==2) buf += QString().sprintf("%02d",d.month()); else buf += QString().sprintf("%d",d.month()); break; case 0x0004: { int year = d.year(); if (!(v & longNumber)) year = year % 100; buf += QString().sprintf("%02d",year); } break; } if (i < 2) buf += _shortSeparator; } 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 void DateFormat::save(QDataStream &d) const { d << _shortSeparator.unicode(); uint v= _shortOrder; d << v; v = _longOrder; d << v; } void DateFormat::load(QDataStream &d) { ushort value; d >> value; _shortSeparator = QChar(value); uint v = 0; d >> v; _shortOrder = (Order)v; v = 0; d >> v; _longOrder = (Order)v; } QDataStream &operator<<(QDataStream &s, const DateFormat&df) { df.save(s); return s; } QDataStream &operator>>(QDataStream &s, DateFormat&df) { df.load(s); return s; } #endif QString TimeString::shortDate( const QDate &d, DateFormat dtf ) { return dtf.wordDate(d); } 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(); } QString TimeString::dateString( const QDateTime &dt, bool ampm, bool seconds, DateFormat dtf ) { const QDate& d = dt.date(); const QTime& t = dt.time(); // based on QDateTime::toString() QString buf = timeString(t,ampm,seconds); buf += " "; buf += longDateString( d, dtf ); return buf; } QString TimeString::timeString( const QTime &t, bool ampm, bool seconds ) { if ( !ampm ) { if ( seconds ) return t.toString(); QString r = QString::number(t.hour()); if ( t.hour() < 10 ) r.prepend( "0" ); r.append( ":" ); if ( t.minute() < 10 ) r.append( "0" ); r.append(QString::number(t.minute())); return r; } // ### else the hard case that should disappear in Qt 3.0 QString argString = seconds ? "%4:%5:%6 %7" : "%4:%5 %7"; int hour = t.hour(); QString strMin = QString::number( t.minute() ); QString strSec = QString::number( t.second() ); if ( hour > 12 ) argString = argString.arg( hour - 12, 2 ); else { if ( hour == 0 ) argString = argString.arg( 12 ); else argString = argString.arg( hour, 2 ); } if ( t.minute() < 10 ) strMin.prepend( "0" ); if ( t.second() < 10 ) strSec.prepend( "0" ); argString = argString.arg( strMin ); 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; } QString TimeString::dateString( const QDateTime &t, bool ampm ) { return dateString(t,ampm,FALSE); } QString TimeString::timeString( const QTime &t, bool ampm) { return timeString(t,ampm,FALSE); } QString TimeString::shortTime( bool ampm ) { return shortTime(ampm,FALSE); } QString TimeString::numberDateString( const QDate &d, DateFormat dtf ) { return dtf.numberDate(d); } 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,150 +1,182 @@ /********************************************************************** -** 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 ** not clear to you. ** **********************************************************************/ #ifndef _TIMESTRING_H_ #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), _longOrder(so), _shortSeparator(s) { } DateFormat(QChar s, Order so, Order lo) : _shortOrder(so), _longOrder(lo), _shortSeparator(s) { } DateFormat(const DateFormat &o) : _shortOrder(o._shortOrder), _longOrder(o._longOrder), _shortSeparator(o._shortSeparator) { } bool operator==(const DateFormat &o) { if (o._shortOrder == _shortOrder && o._longOrder == _longOrder && o._shortSeparator == _shortSeparator) return TRUE; return FALSE; } // verbosity specifiers enum Verbosity { shortNumber = 0x01, // default longNumber = 0x02, padNumber = 0x04, shortWord = 0x08, // default longWord = 0x10, showWeekDay = 0x20 }; QString toNumberString() const; // the M/D/Y string. QString toWordString() const; // the Month day, year string. QString numberDate(const QDate &d, int v = 0) const; QString wordDate(const QDate &d, int v = 0) const; #ifndef QT_NO_DATASTREAM void load(QDataStream&); void save(QDataStream&) const; #endif QChar separator() const { return _shortSeparator; }; Order shortOrder() const { return _shortOrder; }; Order longOrder() const { return _longOrder; }; private: Order _shortOrder; Order _longOrder; QChar _shortSeparator; }; #ifndef QT_NO_DATASTREAM QDataStream &operator<<(QDataStream &s, const DateFormat&df); QDataStream &operator>>(QDataStream &s, DateFormat&df); #endif 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 ) { return numberDateString( d, currentDateFormat() ); } static QString longNumberDateString( const QDate &d, DateFormat ); static QString longNumberDateString( const QDate &d ) { return longNumberDateString( d, currentDateFormat() ); } static QString shortDate( const QDate &, DateFormat ); 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 ); - + }; #endif 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 + @@ -1,263 +1,264 @@ CONFIG_ABOUTAPPLET core/applets/aboutapplet aboutapplet.pro CONFIG_ADDRESSBOOK core/pim/addressbook addressbook.pro CONFIG_ADVANCEDFM noncore/apps/advancedfm advancedfm.pro CONFIG_APPEARANCE2 noncore/settings/appearance2 appearance2.pro CONFIG_APPSKEY noncore/settings/appskey appskey.pro CONFIG_AQPKG noncore/settings/aqpkg aqpkg.pro CONFIG_AUTOROTATEAPPLET noncore/applets/autorotateapplet autorotateapplet.pro CONFIG_BACKGAMMON noncore/games/backgammon backgammon.pro CONFIG_BACKUP noncore/settings/backup backup.pro CONFIG_BARTENDER noncore/apps/opie-bartender bartender.pro CONFIG_BATTERYAPPLET core/applets/batteryapplet batteryapplet.pro CONFIG_BEND noncore/unsupported/mail2/bend bend.pro CONFIG_BIGSCREEN_EXAMPLE unsupported/libopie/big-screen/example osplitter_mail.pro CONFIG_BLUE-PIN noncore/net/opietooth/blue-pin blue-pin.pro CONFIG_BOUNCE noncore/games/bounce bounce.pro CONFIG_BRIGHTNESSAPPLET noncore/applets/brightnessapplet brightnessapplet.pro CONFIG_BUTTON-SETTINGS core/settings/button button.pro CONFIG_BUZZWORD noncore/games/buzzword buzzword.pro 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 CONFIG_CLIPBOARDAPPLET core/applets/clipboardapplet clipboardapplet.pro CONFIG_CLOCKAPPLET core/applets/clockapplet clockapplet.pro CONFIG_CLOCK noncore/tools/clock clock.pro CONFIG_CONFEDIT noncore/apps/confedit confedit.pro CONFIG_DAGGER noncore/apps/dagger dagger.pro CONFIG_DASHER inputmethods/dasher dasher.pro CONFIG_DATEBOOK2 core/pim/datebook2 datebook2.pro CONFIG_DATEBOOK core/pim/datebook datebook.pro CONFIG_DATEBOOK_BIRTHDAYS_HOLIDAY core/pim/datebook/holiday/birthday birthdays.pro CONFIG_DATEBOOK_CHRISTIAN_HOLIDAY core/pim/datebook/holiday/christian christian-holidays.pro CONFIG_DATEBOOK_NATIONAL_HOLIDAY core/pim/datebook/holiday/national national-holidays.pro CONFIG_DECO_FLAT noncore/decorations/flat flat.pro CONFIG_DECO_LIQUID noncore/decorations/liquid liquid.pro CONFIG_DECO_POLISHED noncore/decorations/polished polished.pro CONFIG_DICTIONARY noncore/apps/dictionary dictionary.pro CONFIG_DOCTAB noncore/settings/doctab doctab.pro CONFIG_DRAWPAD noncore/graphics/drawpad drawpad.pro CONFIG_DVORAK inputmethods/dvorak dvorak.pro CONFIG_EMBEDDEDKONSOLE core/apps/embeddedkonsole embeddedkonsole.pro CONFIG_EUROCONV noncore/tools/euroconv/ euroconv.pro CONFIG_EXAMPLE_APPLET examples/applet applet.pro CONFIG_EXAMPLE_BOARD examples/inputmethod inputmethod.pro CONFIG_EXAMPLE_LIBOPIE2BLUEZ examples/opiebluez opiebluez.pro CONFIG_EXAMPLE_LIBOPIE2CORE examples/opiecore opiecore.pro CONFIG_EXAMPLE_LIBOPIE2DB examples/opiedb opiedb.pro CONFIG_EXAMPLE_LIBOPIE2MM examples/opiemm opiemm.pro CONFIG_EXAMPLE_LIBOPIE2NET examples/opienet opienet.pro CONFIG_EXAMPLE_LIBOPIE2PIM examples/opiepim opiepim.pro CONFIG_EXAMPLE_LIBOPIE2SECURITY examples/opiesecurity opiesecurity.pro CONFIG_EXAMPLE_LIBOPIE2UI examples/opieui opieui.pro CONFIG_EXAMPLE_MENU examples/menuapplet menuapplet.pro CONFIG_EXAMPLE_VPN examples/networksettings networksettings.pro CONFIG_FIFTEEN noncore/games/fifteen fifteen.pro CONFIG_FILEBROWSER noncore/unsupported/filebrowser filebrowser.pro CONFIG_FLAT noncore/styles/flat flat.pro CONFIG_FORMATTER noncore/tools/formatter formatter.pro CONFIG_FREETYPE freetype freetype.pro CONFIG_FRESH noncore/styles/fresh fresh.pro CONFIG_FTPLIB noncore/net/ftplib ftplib.pro CONFIG_GO noncore/games/go go.pro CONFIG_GSMTOOL noncore/unsupported/gsmtool gsmtool.pro CONFIG_GUTENBROWSER noncore/apps/opie-gutenbrowser opie-gutenbrowser.pro CONFIG_HANDWRITING inputmethods/handwriting handwriting.pro CONFIG_HELPBROWSER core/apps/helpbrowser helpbrowser.pro CONFIG_HOMEAPPLET core/applets/homeapplet homeapplet.pro CONFIG_HOTPLUG_QCOP core/tools/hotplug-qcop hotplug-qcop.pro CONFIG_INTERFACES noncore/settings/networksettings/interfaces interfaces.pro CONFIG_IRDAAPPLET core/applets/irdaapplet irdaapplet.pro CONFIG_JUMPX inputmethods/jumpx jumpx.pro CONFIG_KBILL noncore/games/kbill kbill.pro CONFIG_KCHECKERS noncore/games/kcheckers kcheckers.pro CONFIG_KEYBOARD inputmethods/keyboard keyboard.pro CONFIG_KEYHELPER noncore/applets/keyhelper keyhelper.pro CONFIG_KEYPEBBLE noncore/comm/keypebble keypebble.pro CONFIG_KEYVIEW development/keyview keyview.pro CONFIG_KJUMPX inputmethods/kjumpx kjumpx.pro CONFIG_KPACMAN noncore/games/kpacman kpacman.pro CONFIG_LANGUAGE noncore/settings/language language.pro CONFIG_LAUNCHER core/launcher server.pro CONFIG_LAUNCHER-SETTINGS core/settings/launcher launcher.pro CONFIG_LIBFFMPEG core/multimedia/opieplayer/libffmpeg libffmpeg.pro CONFIG_LIBFLASH core/multimedia/opieplayer/libflash libflash.pro CONFIG_LIBMAD core/multimedia/opieplayer/libmad libmad.pro CONFIG_LIBMAIL noncore/unsupported/mail2/libmail libmail.pro CONFIG_LIBMAILWRAPPER noncore/net/mail/libmailwrapper libmailwrapper.pro CONFIG_LIBMPEG3 core/multimedia/opieplayer/libmpeg3 libmpeg3.pro CONFIG_LIBOPIE2BLUEZ libopie2/opiebluez opiebluez.pro CONFIG_LIBOPIE2CORE libopie2/opiecore opiecore.pro CONFIG_LIBOPIE2DB libopie2/opiedb opiedb.pro CONFIG_LIBOPIE2EXAMPLES libopie2/examples examples.pro CONFIG_LIBOPIE2MM libopie2/opiemm opiemm.pro CONFIG_LIBOPIE2NET libopie2/opienet opienet.pro CONFIG_LIBOPIE2PIM libopie2/opiepim opiepim.pro CONFIG_LIBOPIE2SECURITY libopie2/opiesecurity opiesecurity.pro CONFIG_LIBOPIE2UI libopie2/opieui opieui.pro CONFIG_LIBOPIETOOTH noncore/net/opietooth/lib lib.pro CONFIG_LIBOPIE noncore/unsupported/libopie libopie.pro CONFIG_LIBQPE library library.pro CONFIG_LIBQPE-X11 x11/libqpe-x11 libqpe-x11.pro CONFIG_LIBQRSYNC rsync rsync.pro CONFIG_LIBQTAUX libqtaux libqtaux.pro CONFIG_LIBSQL libsql libsql.pro CONFIG_LIBTREMOR core/multimedia/opieplayer/vorbis/tremor tremor.pro CONFIG_LIBTREMORPLUGIN core/multimedia/opieplayer/vorbis libtremor.pro CONFIG_LIGHT-AND-POWER core/settings/light-and-power light-and-power.pro CONFIG_LIQUID noncore/styles/liquid liquid.pro CONFIG_LOCKAPPLET core/applets/lockapplet lockapplet.pro CONFIG_LOGOUTAPPLET core/applets/logoutapplet logoutapplet.pro CONFIG_MAIL3 noncore/net/mail mail.pro CONFIG_MAILAPPLET noncore/net/mail/taskbarapplet taskbarapplet.pro CONFIG_MAILIT noncore/unsupported/mailit mailit.pro CONFIG_MAIN_TAB_EXAMPLE examples/main-tab main-tab.pro CONFIG_MEDIUMMOUNT noncore/settings/mediummount mediummount.pro CONFIG_MEMORYAPPLET noncore/applets/memoryapplet memoryapplet.pro CONFIG_METAL noncore/styles/metal metal.pro CONFIG_MINDBREAKER noncore/games/mindbreaker mindbreaker.pro CONFIG_MINESWEEP noncore/games/minesweep minesweep.pro CONFIG_MOBILEMSG noncore/unsupported/mobilemsg mobilemsg.pro CONFIG_MODPLUG core/multimedia/opieplayer/modplug modplug.pro CONFIG_MULTIAUTH_BLUEPING noncore/securityplugins/blueping bluepingplugin.pro CONFIG_MULTIAUTH_DUMMY noncore/securityplugins/dummy dummyplugin.pro CONFIG_MULTIAUTH_NOTICE noncore/securityplugins/notice noticeplugin.pro CONFIG_MULTIAUTH_PIN noncore/securityplugins/pin pinplugin.pro CONFIG_MULTIKEYAPPLET core/applets/multikeyapplet multikeyapplet.pro CONFIG_MULTIKEY inputmethods/multikey multikey.pro CONFIG_NETSYSTEMTIME noncore/settings/netsystemtime netsystemtime.pro CONFIG_NETWORKAPPLET noncore/applets/networkapplet networkapplet.pro CONFIG_NETWORKSETUP noncore/settings/networksettings networksettings.pro CONFIG_NOTES core/pim/notes opie-notes.pro CONFIG_NOTESAPPLET noncore/applets/notesapplet notesapplet.pro CONFIG_NS2BT noncore/settings/networksettings2/bluetooth bluetooth.pro CONFIG_NS2GPRS noncore/settings/networksettings2/gprs GPRS.pro CONFIG_NS2CABLE noncore/settings/networksettings2/cable cable.pro CONFIG_NS2CORE noncore/settings/networksettings2/networksettings2 networksettings2.pro CONFIG_NS2OPIETOOTH noncore/settings/networksettings2/opietooth2 opietooth2.pro CONFIG_NS2OPIETOOTHAPPLET noncore/settings/networksettings2/opietooth2_applet opietooth2_applet.pro CONFIG_NS2IRDA noncore/settings/networksettings2/irda irda.pro CONFIG_NS2LANCARD noncore/settings/networksettings2/lancard lancard.pro CONFIG_NS2MODEM noncore/settings/networksettings2/modem modem.pro CONFIG_NS2NETWORK noncore/settings/networksettings2/network network.pro CONFIG_NS2 noncore/settings/networksettings2 networksettings.pro CONFIG_NS2PPP noncore/settings/networksettings2/ppp ppp.pro CONFIG_NS2PROFILE noncore/settings/networksettings2/profile profile.pro CONFIG_NS2USB noncore/settings/networksettings2/usb usb.pro CONFIG_NS2VPN noncore/settings/networksettings2/vpn vpn.pro CONFIG_NS2WLAN noncore/settings/networksettings2/wlan wlan.pro CONFIG_OAPP core/apps/oapp oapp.pro CONFIG_OBEX core/obex obex.pro CONFIG_ODICT noncore/apps/odict odict.pro CONFIG_OIPKG noncore/unsupported/oipkg oipkg.pro CONFIG_OPIEALARM core/opiealarm opiealarm.pro CONFIG_OPIE-CONSOLE noncore/apps/opie-console opie-console.pro CONFIG_OPIE_EYE noncore/graphics/opie-eye phunk_view.pro CONFIG_OPIE_EYE_SLAVE noncore/graphics/opie-eye/slave slave.pro CONFIG_OPIEFTP noncore/net/opieftp opieftp.pro CONFIG_OPIEIRC noncore/net/opieirc opieirc.pro CONFIG_OPIE-LOGIN core/opie-login opie-login.pro CONFIG_OPIEMAIL2 noncore/unsupported/mail2 mail.pro CONFIG_OPIEPLAYER2 noncore/multimedia/opieplayer2 opieplayer2.pro CONFIG_OPIEPLAYER3 noncore/multimedia/opieplayer3 opieplayer3.pro CONFIG_OPIEPLAYER core/multimedia/opieplayer opieplayer.pro CONFIG_OPIE-RDESKTOP noncore/net/opierdesktop opierdesktop.pro CONFIG_OPIE-READER noncore/apps/opie-reader opie-reader.pro CONFIG_OPIE-READER-FLITEDYN noncore/apps/opie-reader/FliteDyn FliteDyn.pro CONFIG_OPIE-READER-FLITEDYN16 noncore/apps/opie-reader/FliteDyn16 FliteDyn16.pro CONFIG_OPIEREC noncore/multimedia/opierec opierec.pro CONFIG_OPIESMB noncore/net/opie-smb opie-smb.pro CONFIG_OPIE-SHEET noncore/apps/opie-sheet opie-sheet.pro CONFIG_OPIE-SH noncore/tools/opie-sh opie-sh.pro CONFIG_OPIETOOTH-APPLET noncore/net/opietooth/applet applet.pro CONFIG_OPIETOOTH-MANAGER noncore/net/opietooth/manager manager.pro CONFIG_OPIE-WRITE noncore/apps/opie-write opie-write.pro CONFIG_OSEARCH core/pim/osearch osearch.pro CONFIG_OXYGEN noncore/apps/oxygen oxygen.pro CONFIG_PACKAGEMANAGER noncore/settings/packagemanager packagemanager.pro CONFIG_PARASHOOT noncore/games/parashoot parashoot.pro CONFIG_PCMCIA-APPLET noncore/applets/pcmcia pcmcia.pro CONFIG_PHASE noncore/styles/phase phase.pro CONFIG_PICKBOARD inputmethods/pickboard pickboard.pro CONFIG_PIMCONVERTER noncore/tools/pimconverter converter.pro CONFIG_POWERCHORD noncore/multimedia/powerchord powerchord.pro CONFIG_PPP noncore/settings/networksettings/ppp ppp.pro CONFIG_PYQUICKLAUNCH-APPLET noncore/applets/pyquicklaunch pyquicklaunch.pro CONFIG_PYQUICKLAUNCHER noncore/tools/pyquicklauncher pyquicklauncher.pro CONFIG_PYTHON-EXAMPLES examples/python bla.pro CONFIG_QASHMONEY noncore/unsupported/qashmoney qashmoney.pro CONFIG_QASTEROIDS noncore/games/qasteroids qasteroids.pro CONFIG_QCOP core/apps/qcop qcop.pro CONFIG_QPDF noncore/unsupported/qpdf qpdf.pro CONFIG_QSS core/apps/qss qss.pro CONFIG_QUICKLAUNCHER core/tools/quicklauncher quicklauncher.pro CONFIG_QWS core/qws qws.pro CONFIG_REMOTE noncore/tools/remote remote.pro CONFIG_RESTARTAPPLET2 core/applets/restartapplet2 restartapplet2.pro CONFIG_RESTARTAPPLET core/applets/restartapplet restartapplet.pro CONFIG_ROTATEAPPLET core/applets/rotateapplet rotateapplet.pro CONFIG_ROTATION noncore/settings/rotation rotation.pro CONFIG_RUNAPPLET core/applets/runapplet runapplet.pro CONFIG_SCREENSHOTAPPLET core/applets/screenshotapplet screenshotapplet.pro CONFIG_SECURITY core/settings/security security.pro CONFIG_MULTIAUTH_DEMO core/settings/security/demo multiauth.pro CONFIG_SFCAVE noncore/games/sfcave sfcave.pro CONFIG_SFCAVE-SDL noncore/games/sfcave-sdl sfcave-sdl.pro CONFIG_SHOWIMG noncore/unsupported/showimg showimg.pro CONFIG_SIMPLE_EXAMPLE examples/simple simple.pro CONFIG_SIMPLE_ICON examples/simple-icon simple-icon.pro CONFIG_SIMPLE_MAIN examples/simple-main simple-main.pro CONFIG_SIMPLE_PIM examples/simple-pim simple-pim.pro CONFIG_SINGLE single single.pro CONFIG_SNAKE noncore/games/snake snake.pro CONFIG_SOLITAIRE noncore/games/solitaire solitaire.pro CONFIG_SOUND noncore/settings/sound sound.pro CONFIG_SSHKEYS noncore/settings/sshkeys sshkeys.pro CONFIG_SUSPENDAPPLET core/applets/suspendapplet suspendapplet.pro CONFIG_SYMLINKER core/symlinker symlinker.pro CONFIG_SYSINFO noncore/settings/sysinfo sysinfo.pro CONFIG_TABLEVIEWER noncore/apps/tableviewer tableviewer.pro CONFIG_TABMANAGER noncore/unsupported/tabmanager tabmanager.pro CONFIG_TABOAPP core/apps/taboapp taboapp.pro CONFIG_TEST libsql/test test.pro CONFIG_TEST noncore/apps/opie-console/test test.pro CONFIG_TETRIX noncore/games/tetrix tetrix.pro CONFIG_TEXTEDIT core/apps/textedit textedit.pro CONFIG_THEME noncore/styles/theme theme.pro CONFIG_TICTAC noncore/games/tictac tictac.pro CONFIG_TINYKATE noncore/apps/tinykate tinykate.pro CONFIG_TODAY_ADDRESSBOOK core/pim/today/plugins/addressbook addressbook.pro CONFIG_TODAY core/pim/today today.pro CONFIG_TODAY_DATEBOOK core/pim/today/plugins/datebook datebook.pro CONFIG_TODAY_EXAMPLE examples/todayplugin todayplugin.pro CONFIG_TODAY_FORTUNE noncore/todayplugins/fortune fortune.pro CONFIG_TODAY_MAIL core/pim/today/plugins/mail mail.pro CONFIG_TODAY_STOCKTICKERLIB noncore/todayplugins/stockticker/stocktickerlib stocktickerlib.pro CONFIG_TODAY_STOCKTICKER noncore/todayplugins/stockticker/stockticker stockticker.pro CONFIG_TODAY_TODOLIST core/pim/today/plugins/todolist todolist.pro CONFIG_TODAY_WEATHER noncore/todayplugins/weather weather.pro CONFIG_TODO core/pim/todo todo.pro CONFIG_TONLEITER noncore/multimedia/tonleiter tonleiter.pro CONFIG_TRACKER noncore/multimedia/tracker tracker.pro CONFIG_UBROWSER noncore/unsupported/ubrowser ubrowser.pro CONFIG_UNIKEYBOARD inputmethods/unikeyboard unikeyboard.pro CONFIG_USERMANAGER noncore/settings/usermanager usermanager.pro CONFIG_VMEMO core/applets/vmemo vmemo.pro CONFIG_VOLUMEAPPLET core/applets/volumeapplet volumeapplet.pro CONFIG_VOLUMEAPPLET2 noncore/applets/volumeapplet2 volumeapplet2.pro CONFIG_VTAPPLET core/applets/vtapplet vtapplet.pro CONFIG_WAVPLUGIN core/multimedia/opieplayer/wavplugin wavplugin.pro CONFIG_WEBSTYLE noncore/styles/web web.pro CONFIG_WELLENREITER noncore/net/wellenreiter wellenreiter.pro CONFIG_WIRELESSAPPLET noncore/applets/wirelessapplet wirelessapplet.pro CONFIG_WLAN noncore/settings/networksettings/wlan wlan.pro CONFIG_WORDGAME noncore/games/wordgame wordgame.pro CONFIG_YATZEE noncore/games/oyatzee oyatzee.pro CONFIG_ZKBAPPLET noncore/applets/zkbapplet zkbapplet.pro CONFIG_ZLINES noncore/games/zlines zlines.pro CONFIG_ZSAFE noncore/apps/zsafe zsafe.pro CONFIG_ZSAME noncore/games/zsame zsame.pro CONFIG_OPIESTUMBLER noncore/net/opiestumbler opiestumbler.pro diff --git a/pics/camera2/Camera.png b/pics/camera2/Camera.png Binary files differnew file mode 100644 index 0000000..e619c11 --- a/dev/null +++ b/pics/camera2/Camera.png diff --git a/pics/camera2/Camera_48.png b/pics/camera2/Camera_48.png Binary files differnew file mode 100644 index 0000000..00b8585 --- a/dev/null +++ b/pics/camera2/Camera_48.png diff --git a/pics/camera2/Camera_48_anim.mng b/pics/camera2/Camera_48_anim.mng Binary files differnew file mode 100644 index 0000000..6b19394 --- a/dev/null +++ b/pics/camera2/Camera_48_anim.mng diff --git a/pics/camera2/settings.png b/pics/camera2/settings.png Binary files differnew file mode 100644 index 0000000..05bfdf7 --- a/dev/null +++ b/pics/camera2/settings.png |