summaryrefslogtreecommitdiff
authormickeyl <mickeyl>2005-06-02 21:44:41 (UTC)
committer mickeyl <mickeyl>2005-06-02 21:44:41 (UTC)
commitd0f6a0721d7ab67a115d08990143944ee71d54ba (patch) (side-by-side diff)
treeba22ad18027419a6417f3d6439a2faf67917ab74
parentf55a56f54de1d3fa9084160159a379079a317d96 (diff)
downloadopie-d0f6a0721d7ab67a115d08990143944ee71d54ba.zip
opie-d0f6a0721d7ab67a115d08990143944ee71d54ba.tar.gz
opie-d0f6a0721d7ab67a115d08990143944ee71d54ba.tar.bz2
- move addLanguage.sh and mkipks to scripts/ directory
- finish recursive directory locks and mention in ChangeLog beginning with `CVS:' are removed automatically CVS: CVS: Committing in . CVS: CVS: Modified Files: CVS: ChangeLog libopie2/opiecore/linux/ofilenotify.cpp CVS: libopie2/opiecore/linux/ofilenotify.h CVS: examples/opiecore/onotifytest/main.cpp CVS: examples/opiecore/onotifytest/main.h CVS: Added Files: CVS: scripts/addLanguage.sh scripts/mkipks CVS: ----------------------------------------------------------------------
Diffstat (more/less context) (ignore whitespace changes)
-rw-r--r--ChangeLog3
-rw-r--r--examples/opiecore/onotifytest/main.cpp18
-rw-r--r--examples/opiecore/onotifytest/main.h10
-rw-r--r--libopie2/opiecore/linux/ofilenotify.cpp40
-rw-r--r--libopie2/opiecore/linux/ofilenotify.h3
-rwxr-xr-xscripts/addLanguage.sh33
-rwxr-xr-xscripts/mkipks261
7 files changed, 343 insertions, 25 deletions
diff --git a/ChangeLog b/ChangeLog
index bce86d1..4dcee93 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,292 +1,293 @@
2005-??-?? Opie 1.2.1
New Features
------------
* OpieStumbler: Scans WiFi networks using the wireless extension scanning (skyhusker)
* Opie-Reader: Support for document formats ArriereGo and Reb, add flite output (tim,pohly)
* Opie-Networksettings: Add support for wlan-ng devices and improve WEP handling (Dirk Opfer)
* Wellenreiter: Remove Joining networks - use OpieStumbler for that (mickeyl)
* Opie-Mobilemsg has gone unsupported - it never really worked and there will be a replacement (mickeyl)
* Opie-Tabmanager has gone unsupported - it barely works and there is not much of a use of it anyway (mickeyl)
Fixed Bugs
----------
* #1476 - Wrong order of application entries in the O-menu (skyhusker)
* #1535 - Missing line break and unnecessary location shown with Today-Calendar plugin (deller)
* #1565 - crash-fix in odevice.cpp while scanning the distribution table (deller)
* #1614 - Make Opie-console start in $HOME instead of / (skyhusker)
* n.a. - always show volume and wireless applet popups inside visible screen (deller)
* n.a. - scale O-Menu-Applets appropriately (mickeyl)
* n.a. - libopienet: fix bugs in wireless scanning and setting SSID (skyhusker)
* n.a. - Wellenreiter: relax WE version matching test a bit (mickeyl)
* n.a. - scale BluezApplet appropriately and use larger icons (mickeyl)
* n.a. - memoryapplet: fix crash in memoryapplet on kernels without swap support (seneca cunningham)
* n.a. - networksettings: ignore hostap control interfaces wifi* (mickeyl)
Internal
--------
* Make BluezApplet use OTaskbarApplet (mickeyl)
- * Rewrite OFileNotification to use the upcoming inotify interface instead of the deprecated dnotify (mickeyl)
+ * libopiecore: rewrite OFileNotification to use the Linux 2.6 inotify interface (mickeyl)
+ * libopiecore: add ODirNotification - recursive directory notifications (mickeyl)
* libopienet: Skip hostap control interfaces 'wifi' and improve robustness in ONetworkInterface (mickeyl)
* libopieui: Remove OVersatileView and OVersatileViewItem (mickeyl)
* libopienet: Miscellaneous API cleanups (mickeyl)
* libopiecore: Add linux pcmcia system abstraction classes (mickeyl)
2005-03-25 Opie 1.2.0
Fixed Bugs
----------
* #1613 - AdvancedFM - scale toolbar icons appropriately (drw)
* #1620 - OFileSelector - show the button on press and not on press on hold (alwin)
* #1473 - Opie-Eye - Same as #1620 but we lack a common FileSystem Button class (zecke)
* n.a. - PackageManager - fix bug where messages show up multiple times in install dialog (drw)
* n.a. - make qpeglobal.h include qglobal.h (zecke)
2005-03-20 Opie 1.2.0-rc1
New Features
------------
* Launcher: Support a static background pixmap (mickeyl)
* LauncherSettings: Choose whether to have a static background pixmap (mickeyl)
* PackageManager supports the 'lists_dir' ipkg configuration option (drw)
* Added hi-res inline images for large resolution devices (drw)
* Improved launcher icons for consistency (ar)
* Datebook: Added plugin system to datebook so holidays and birthdays from contacts may displayed in datebook (alwin)
Fixed Bugs
----------
* #1236 - VCards contained empty home and work address entries causing Palms to crash (eilers)
* #1412 - Launcher Settings - fixed default settings for background in Edit tab dialog (drw)
* #1472 - Opie textedit now check for unsaved changes on ESC key (ljp)
* #1474 - Implement GUI for Scrollbars on the Left in Appearance (zecke)
* #1482 - Fix double '/' in paths (zecke)
* #1536 - Autosave of custom locations in opie backup (ar)
* #1539 - Fixed displaying too long path in the delete dialog in opie-eye (zecke)
* #1540 - Implemented deletion of DocLnks in opie-eye (zecke)
* #1542 - Fixed Todo crash when priority < 1 or > 5 (drw)
* #1550 - Browse for alarm sound start in QPEDIR/sounds/ (zecke)
* #1554 - Fixed Opie-Console name in .desktop file (mickeyl)
* #1556 - Start to look for sound files in /opt/QtPalmtop/sounds (zecke)
* #1558 - Fixed opie-login breaking opie startup (mickeyl)
* #1560 - Fixed Opie-Console picking up the wrong shell (bluelightning)
* #1570 - Confirmation needed befor Restore a backup and overwrite local data (ar)
* #1591 - Addressbook sortorder changed by clicking on column 0 (eilers)
* #1599 - Security - change recommendation for opie-multiauth to opie-securityplugin (gints)
* #1604 - Checkbook crashed on startup (drw)
* #1608 - Addressbook crashed after search, which may caused by not initialzed member variable (eilers)
* #1608 - QueryByExampe-Datediff on SQL database did not worked properly (eilers)
* n.a. - Netsystemtime - fixed UI to prevent error dialog from displaying when it shouldn't, get rid of some compiler warnings (drw)
* n.a. - PackageManager - fixed where last package in status file was not shown as installed when it should be (drw)
* n.a. - PackageManager - fixed bug where lists_dir was not being honored at startup (drw)
* n.a. - PackageManager - provided default value for lists_dir when none is entered in configuration dialog (drw)
* n.a. - OTabWidget - fixed scroll buttons, fix display position of tabs (drw)
* n.a. - AddressBook - fixed sorting by 'File As' name (drw)
* n.a. - AddressBook - fixed category handling for 'All' and 'Unfiled' (eilers)
* n.a. - AddressBook - fixed letter picker record selection and sort records afterwards (drw)
Internal
--------
* Worked around bug in Qt/Embedded 2.3.10: qt_version() returns 231 (mickeyl)
* Killed the need for weak symbols in QtE (zecke)
* Added optional building libqpe without inline images (mickeyl)
* OColorButton - fixed so does not emit a colorSelected signal inside of resizeEvent (drw)
2005-02-03 Opie 1.1.9
New Features
------------
* Number of icon columns in Launcher is customizable through Launcher.conf (hrw,zecke,mickeyl)
* Number of icon columns in Launcher is customizable through LauncherSettings (mickeyl)
* Usability enhancements in OpieIRC (skyhusker)
Fixed Bugs
----------
* #1501 - Fixed bug in todo sql backend (eilers)
* #1505 - Added more Swap sizes in memoryapplet (mickeyl)
* #1525 - Hopefully fixed double alarms and not removing alarms set with the Clock application (zecke)
* #1533 - Security Owner Dialog (shown in case of unsuccessfull authentiacation) wasn't able to display information in non latin1 encoding (zecke)
* n.a. - Removed hard coded font sizes in a couple of inputmethods (mickeyl)
* n.a. - Removed MediumDlg appearing prior to FirstUsage wizard (i.e. calibration) (mickeyl)
* n.a. - Fixed numerous buglets in OpieIRC (skyhusker)
Internal
--------
* Added the Qtopia 1.7 SDK macros for quick-apps to easa compilation of 3rd party apps against our headers (mickeyl)
* You can now use the Opie build system in combination with a OpenEmbedded staging area which makes a nice cross development environment (mickeyl)
* Made Opie compilable with Qt/Embedded 2.3.10 (ar)
* Changed Launcher to get default orientation from ODevice w/ QWS_DISPLAY overriding (mickeyl)
* Build tree cleanups (mickeyl)
2004-11-26 Opie 1.1.8
New Features
------------
* PackageManager supports installation of local ipkg files (drw)
* PackageManager supports linking of applications to root (drw)
* PackageManager supports src/gz feeds (drw,wimpie)
* Added a syslog information tab to sysinfo (mickeyl)
* Added new, more consistent, PIM icons + a GIMP teplate (ar)
Fixed Bugs
----------
* #1017 - Tetrix doesn't display correctly for high resolution screens (drw)
* #1269 - VCards were imported into personal area if it was activated (eilers)
* #1464 - Packagemanager dont set active filter after install a package (drw)
* #1479 - Improved VCard-Parser to import VCards created by Evolution 2 and Apple Addressbook (eilers)
* #1493 - Fixed one column layout bug of the launcher (hrw)
* n.a. - PackageManager - (Minor UI tweak) in filter dialog, when option is enabled, set focus to widget that corresponds to that option (drw)
* n.a. - PackageManager - (Minor UI tweak) fix double entry in source feed configuration when adding a new feed (drw)
* n.a. - Battery Applet - fix sizing of battery info popup (drw,mickeyl)
Internal
--------
* Moved libopie1 to unsupported (mickeyl)
* Implemented generic queryByExample() with incremental searching. A lot of internal changes of the Pim2-library (eilers)
* Added fast and full featured and incremental sorted() for SQL addressbook backend (eilers)
2004-11-14 Opie 1.1.7
New Features
------------
* libOpieDB now uses SQLite V3 instead V2. Remember to upgrade your database files! (eilers)
* Backup now uses the busy indicator when backing up and restore (ar)
* OpiePlayer2 gained adding of Directories to the playlist (zecke)
* OpiePlayer2 better error handling (zecke)
* OpiePlayer2 progress indication while streaming (zecke)
* OpiePlayer2 ported to use libxine 1.0.0-rc6a (brad,zecke)
* Ported brightnessapplet from Qtopia 1.7 (mickeyl)
* Opie-Eye got a Digital Camera File Backend (alwin,zecke)
* Support for Tuxpad1 of Tradesquare.NL (mickeyl,zecke)
* Opie-Console use Custom Font and Size in a Profile (harlekin)
* Opie-Console transparently log the Output and Input to a file (harlekin)
* Added new O-menu icon to lock the PDA immediately: opie-lockapplet (clem)
* Opie-Security now hides the plugin-based authentication tabs if no auth. plugin package is installed (clem)
* Opie-Security gained a 'test authentication' button (clem)
* Opie-Eye got a more unique layout (menubar), a slideshow, user can setup some defaults
* Opie-Mail improve the handling of POP mail boxes (alwin)
* Both Opie-Eye and Opie-Mail were greatly improved due the hard work of Rajko Albrecht(alwin)
* Opie IRC - backports of the 'NeIRC fork' (zecke)
Fixed Bugs
----------
* #501 - Pickboard is able to show 'Umlaute' (TT,zecke)
* #608 - Make Opie usable for left handed users (zecke)
* #957 - Import of VCards/VTodos/VEvents with BASE64 encoding (ljp,zecke)
* #1245 - Opie-Go 'paused' (zecke)
* #1358 - DocTab didn't show any MimeTypes (was fixed earlier) (zecke)
* #1380 - QDateBookAccess::remove() doesn't remove entries (eilers, zecke)
* #1395 - Build VNC Backend with gcc3.4
* #1440 - The icon of opie-mobilemsg is missing (CoreDump)
* #1426 - Add missing opie-bartender Icon (CoreDump)
* #1445 - Opie-Sheet Has No Icon (CoreDump)
* #1448 - Brightness Applet added (mickeyl)
* #1450 - ZSame didn't clear the bonus item after winning a game (zecke)
* #1482 - Fix OFileSelector to be able to sort by size (zecke)
* n.a. - Opie-mail: fixed some crasher, some layout-problems
* n.a. - Converted applications to not hardcode /opt/QtPalmtop but to use QPEApplication::qpeDir (zecke)
* n.a. - Converted usage of qpeDir() not to include a '/' as first charachter of the string (zecke)
* n.a. - Build system: Enable distcc and ccache when crosscompiling too, and use them everywhere we can (clem)
* n.a. - Build system: Fix deps in several config.in (and fix scripts/deps.pl too) to stop breaking builds, especially with make -j highNumber (clem)
* n.a. - Removed hardcoded icon size in a couple of applets (mickeyl)
Internal
--------
* Opie-Qashmoney has been moved to unsupported (mickeyl)
* Opie-Ubrowser has been moved to unsupported (mickeyl)
2004-09-17 Opie 1.1.6
New Features
------------
* Fifteen gained configurable number of items (zecke)
* Fifteen can have custom background images (zecke)
* Added daemonizing capabilities to QWS Server [via Qt/Embedded] (mickeyl)
* Integrated the new security framework into libopie2 (zecke,clem)
* Converted the launcher to use the new security framework (zecke)
* Backup can now handle custom locations for backup and restore (ar)
* Implemented right-on-hold feedback (wimpie,zecke)
* Lots of new features in opie-reader (tim,pohly)
* Build system cleanups (schurig)
Fixed Bugs
--------
* #1005 - Fixed backup to CompactFlash (ar)
* #1167 - Fixed Opie write crashing on more text than one page (ar)
* #1225 - Fixed repeated light flashing on Zaurus with keyz (mickeyl)
* #1359 - Fixed bookmarks in Gutenbrowser (ljp)
* #1361 - Fixed auto upercase in Opie-Addressbook (eilers)
* #1370 - Pimconverter now reacts on cancel key (eilers)
* #1376 - Bring back the capslock/numlock display (zecke)
* #1383 - Language settings now warns about losing open apps (Markus Litz)
* #1393 - Fixed line wrap issues in opie-console for the default profile (mickeyl)
* #1394 - Fixed oversized headline in opie-login (coredump)
* #1396 - Opie-console captures the escape key and vim is working (zecke)
* #1401 - Scrollbar is now only visible if necessary in DocTab (mickeyl)
2004-07-06 Opie 1.1.4
New Features
------------
* Added four themes courtesy Robert Griebl (http://www.softforge.de/zstyle)
* Added Conversion tool for pim-data (eilers)
* Introduced new OPimAccessFactory and OBackendFactory which simplyfies database access (eilers)
* Modified the PIM API for providing generic use of OPimRecords (eilers)
* Clicking on the application symbol now iterates over the application's top level widgets if already raised (zecke)
Fixed Bugs
--------
* #1068 - Country Drop Down Box Off Screen
* #1291 - Opie tinykate does not open .desktop files (ar)
* #1291 - Opie sheet not saving correctly (ar)
* #1294 - Opie does not know about British Summer Time
* #1314 - Drawpad initialization (mickeyl)
* #1317 - Packagemanager crashes on hold-down or install (chicken)
* #1321 - Batteryapplet graphic glitch (harlekin)
* #1324 - ZSafe not starting up (mickeyl)
* #1328 - Personal Home Address fields is trimmed to 1char (eilers)
* #1327 - Opie-mail ipk does not depend on libopiedb2 (chicken)
* #1345 - Networksettingsplugin wlan plugin dependency on libpcap0 (mickeyl)
* #1348 - Datebook dependency on libopiedb2 (chicken)
* #1328 - Switched SQLDatabase and VCards char encoding from latin1 to unicode (eilers)
2004-04-25 Opie 1.1.3
* Introduced first implementation of SQL-Support using SQLite (eilers)
* Added a new Gutenberg Project reader app - opie-gutenbrowser (ljp)
* Added a real system graffiti character set (brad)
* Added Generic Keyconfig Widget (zecke)
* Improved Screenshotapplet and Drawpad integration. You can now open a screenshot in drawpad and take notes (zecke)
* Added new Bible reader app - opie-dagger (drw)
* Added a new Image Viewer. Work is ongoing (zecke,alwin)
* Added namespace usage in libopie2 and everywhere (zecke,alwin)
* Enabled the possibility to pass command line arguments to applications (mickeyl)
* Added an about applet showing some credits and information about Opie (mickeyl)
* Added benchmarking functionality to sysinfo (mickeyl)
* Added applet and configuration application for switching hardware keyboard layouts (alwin)
* Ported applications from libopie1 to libopie2* (drw,ar,alwin)
* Imported fullscreen and font improvements from the Qkonsole fork to embeddedkonsole (waspe)
* Clean-up of package information in control files (drw)
* Repaired mediummount which was broken since integrating the quicklauncher (alwin)
* Improved big-screen support (zecke,ar)
* Improved multikeyboard support, added keyboard layout switching applet (mouse)
* Added a new mail client based on libetpan (harlekin,alwin,jgf)
* Added new package manager - opie-packagemanager (drw)
* Improved light-n-power for C7x0 (mickeyl)
* Added automatic rotation support for C7x0 (treke)
* Split libopie1 up into a set of smaller - functionally grouped - libraries (mickeyl)
* Added scanning the wireless network neighbourhood to networksettings (mickeyl)
2003-11-29 Opie 1.0.3
* Released as Version 1.0.3
* Improved i18n (various contributors)
* Reduced application startup time by integrating the TT quicklauncher (zecke,harlekin)
* Made the Documents Tab optional (mickeyl)
* Integrated basic support for HP iPAQ 54xx and the Jornada 5xx (chicken)
2003-08-04 Opie 1.0.0
* Released as Version 1.0.0
* Including a PPP module for easy dial up (tille,harlekin,zecke)
diff --git a/examples/opiecore/onotifytest/main.cpp b/examples/opiecore/onotifytest/main.cpp
index b773da9..7b7b0bc 100644
--- a/examples/opiecore/onotifytest/main.cpp
+++ b/examples/opiecore/onotifytest/main.cpp
@@ -1,66 +1,76 @@
// (C) Michael 'Mickey' Lauer <mickey@Vanille.de>
// LICENSE = "GPLv2"
#include "main.h"
/* OPIE */
#include <opie2/odebug.h>
#include <opie2/oapplication.h>
#include <opie2/ofilenotify.h>
using namespace Opie::Core;
/* QT */
#include <qdir.h>
#include <qpushbutton.h>
#include <qstringlist.h>
#include <qtextstream.h>
#include <qmessagebox.h>
App::App( int argc, char** argv ) : QApplication( argc, argv )
{
odebug << "App()" << oendl;
#if 0
tmpfoo = new OFile( "/tmp/foo" );
if ( tmpfoo->open( IO_ReadWrite ) )
{
QTextStream stream( tmpfoo );
stream << "This is my content";
}
QObject::connect( tmpfoo, SIGNAL(accessed(const QString&)), this, SLOT(quit()) );
QObject::connect( tmpfoo, SIGNAL(closed(const QString&,bool)), this, SLOT(quit()) );
#endif
- ODirNotification* tmpfoo = new ODirNotification( 0, 0 );
+ tmpfoo = new ODirNotification( 0, 0 );
int result = tmpfoo->watch( "/tmp/foo", false, CreateFile, 2 );
- QObject::connect( tmpfoo, SIGNAL(triggered(const QString&,unsigned int,const QString&)),
- this, SLOT(triggered(const QString&,unsigned int,const QString&)) );
+
+ if ( result != -1 )
+ {
+ QObject::connect( tmpfoo, SIGNAL(triggered(const QString&,unsigned int,const QString&)),
+ this, SLOT(triggered(const QString&,unsigned int,const QString&)) );
+ }
+ else
+ {
+ QMessageBox::warning( qApp->desktop(), "info", "Couldn't watch /tmp/foo\nDoes it exist?" );
+ }
}
App::~App()
{
odebug << "~App()" << oendl;
+ delete tmpfoo;
}
void App::triggered( const QString& str1, unsigned int id, const QString& str2 )
{
- QMessageBox::information( qApp->desktop(), "info", QString( "%1\n%2\n%3" ).arg( str1 ).arg( id ).arg( str2 ) );
+ QMessageBox::information( qApp->desktop(), "info", QString().sprintf( "%s\n0x%08x\n%s",
+ (const char*) str1, id, (const char*) str2 ) );
}
int main( int argc, char** argv )
{
App* app = new App( argc, argv );
QPushButton* b = new QPushButton( "Click me to close", 0 );
QObject::connect( b, SIGNAL(clicked()), qApp, SLOT(quit()) );
b->resize( 200, 200 );
b->move( 150, 150 );
b->show();
app->setMainWidget( b );
app->exec();
delete app;
return 0;
}
diff --git a/examples/opiecore/onotifytest/main.h b/examples/opiecore/onotifytest/main.h
index afad947..7ce4b9f 100644
--- a/examples/opiecore/onotifytest/main.h
+++ b/examples/opiecore/onotifytest/main.h
@@ -1,23 +1,29 @@
// (C) Michael 'Mickey' Lauer <mickey@Vanille.de>
// LICENSE = "GPLv2"
#ifndef MAIN_H
#define MAIN_H
+/* OPIE */
+#include <opie2/ofilenotify.h>
+
/* QT */
#include <qapplication.h>
#include <qpushbutton.h>
#include <qtextstream.h>
class App : public QApplication
{
Q_OBJECT
-public:
+ public:
App( int argc, char** argv );
~App();
-public slots:
+ public slots:
void triggered( const QString&, unsigned int, const QString& );
+
+ private:
+ Opie::Core::ODirNotification* tmpfoo;
};
#endif
diff --git a/libopie2/opiecore/linux/ofilenotify.cpp b/libopie2/opiecore/linux/ofilenotify.cpp
index a7820ee..68c5a96 100644
--- a/libopie2/opiecore/linux/ofilenotify.cpp
+++ b/libopie2/opiecore/linux/ofilenotify.cpp
@@ -1,444 +1,450 @@
/*
                This file is part of the Opie Project
=. Copyright (C) 2004-2005 Michael 'Mickey' Lauer <mickey@Vanille.de>
.=l. Copyright (C) The Opie Team <opie-devel@handhelds.org>
         .>+-=
_;:,     .>    :=|. This program is free software; you can
.> <`_,   >  .   <= redistribute it and/or modify it under
:`=1 )Y*s>-.--   : the terms of the GNU Library General Public
.="- .-=="i,     .._ License as published by the Free Software
- .   .-<_>     .<> Foundation; version 2 of the License.
   ._= =}       :
  .%`+i>       _;_.
  .i_,=:_.      -<s. 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
..}^=.=       =       ; Library General Public License for more
++=   -.     .`     .: details.
:     =  ...= . :.=-
-.   .:....=;==+<; You should have received a copy of the GNU
-_. . .   )=.  = Library General Public License along with
  --        :-=` this library; see the file COPYING.LIB.
If not, write to the Free Software Foundation,
Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA.
*/
#include "ofilenotify.h"
using namespace Opie::Core;
/* OPIE */
/* QT */
#include <qobject.h>
#include <qsocketnotifier.h>
#include <qsignal.h>
#include <qintdict.h>
#include <qdir.h>
/* STD */
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
#include <fcntl.h>
#include <assert.h>
#include <string.h>
#include <errno.h>
#include <unistd.h>
static QIntDict<OFileNotification> notification_list;
QSocketNotifier* OFileNotification::_sn;
int OFileNotification::_fd = -1;
#define INOTIFY_DEVICE "/dev/inotify"
namespace Opie {
namespace Core {
//=================================================================================================
// OFile
//=================================================================================================
OFile::OFile() : QObject( 0, 0 ), QFile()
{
qDebug( "OFile()" );
}
OFile::OFile( const QString& name ) : QObject( 0, 0 ), QFile( name )
{
qDebug( "OFile()" );
}
OFile::~OFile()
{
qDebug( "~OFile()" );
}
void OFile::connectNotify( const char *signal )
{
QString s = normalizeSignalSlot( signal+1 );
qDebug( "OFile::connectNotify() signal = '%s'", (const char*) s );
if ( s.startsWith( "accessed" ) )
QObject::connectNotify( signal );
/*
void accessed( const QString& );
void modified( const QString& );
void attributed( const QString& );
void closed( const QString&, bool );
void opened( const QString& );
void deleted( const QString& );
void unmounted( const QString& );
*/
}
void OFile::disconnectNotify( const char* signal )
{
qDebug( "OFile::disconnectNotify() signal = '%s'", signal );
QObject::disconnectNotify( signal );
}
int OFile::startWatch( int mode )
{
}
//=================================================================================================
// OFileNotificationEvent
//=================================================================================================
OFileNotificationEvent::OFileNotificationEvent( OFileNotification* parent, int wd, unsigned int mask, unsigned int cookie, const QString& name )
:_parent( parent ), _wd( wd ), _mask( mask ), _cookie( cookie ), _name( name )
{
qDebug( "OFileNotificationEvent()" );
}
OFileNotificationEvent::~OFileNotificationEvent()
{
qDebug( "~OFileNotificationEvent()" );
}
//=================================================================================================
// OFileNotification
//=================================================================================================
OFileNotification::OFileNotification( QObject* parent, const char* name )
:QObject( parent, name ), _active( false ), _multi( true )
{
qDebug( "OFileNotification::OFileNotification()" );
}
OFileNotification::~OFileNotification()
{
stop();
qDebug( "OFileNotification::~OFileNotification()" );
}
bool OFileNotification::isActive() const
{
return _active;
}
int OFileNotification::watch( const QString& path, bool sshot, OFileNotificationType type )
{
// check if path exists and is a regular file
struct stat s;
if ( ::stat( (const char*) path, &s ) == -1 )
{
qWarning( "OFileNotification::watch(): Can't watch '%s': %s.", (const char*) path, strerror( errno ) );
return -1;
}
if ( !S_ISREG( s.st_mode ) )
{
qWarning( "OFileNotification::watch(): Can't watch '%s': %s.", (const char*) path, "not a regular file" );
return -1;
}
return startWatching( path, sshot, type );
}
int OFileNotification::startWatching( const QString& path, bool sshot, OFileNotificationType type )
{
if ( notification_list.isEmpty() )
{
OFileNotification::registerEventHandler();
}
struct inotify_watch_request iwr;
::memset( &iwr, 0, sizeof iwr );
iwr.name = const_cast<char*>( (const char*) path );
iwr.mask = type;
_wd = ::ioctl( OFileNotification::_fd, INOTIFY_WATCH, &iwr );
if ( _wd < 0 )
{
qWarning( "OFileNotification::watch(): inotify can't watch '%s': %s.", (const char*) path, strerror( errno ) );
return -1;
}
notification_list.insert( _wd, this );
_path = path;
_multi = !sshot;
_type = type;
_active = true;
qDebug( "OFileNotification::watch(): watching '%s' [wd=%d].", (const char*) path, _wd );
return _wd;
}
void OFileNotification::stop()
{
notification_list.remove( _wd );
_path = QString::null;
_wd = 0;
_active = false;
if ( notification_list.isEmpty() )
{
OFileNotification::unregisterEventHandler();
}
}
OFileNotificationType OFileNotification::type() const
{
return _type;
}
QString OFileNotification::path() const
{
return _path;
}
bool OFileNotification::isSingleShot() const
{
return !_multi;
}
bool OFileNotification::activate( const OFileNotificationEvent* e )
{
qDebug( "OFileNotification::activate(): e = ( %s, %d, 0x%08x, %d, %s )", (const char*) _path, e->descriptor(), e->mask(), e->cookie(), (const char*) e->name() );
+ //FIXME: Should we really deliver QueueOverflow and/or Ignore to user level code?
+
// dumb signal
_signal.activate();
// generic signal
emit triggered( _path, e->mask(), e->name() );
// specialized signals
switch ( e->mask() )
{
- case Access: emit accessed( _path ); break;
- case Modify: emit modified( _path ); break;
- case Attrib: emit attributed( _path); break;
- case CloseWrite: emit closed( _path, true ); break;
- case CloseNoWrite: emit closed( _path, false ); break;
- case Open: emit opened( _path ); break;
- case MovedFrom: emit movedFrom( _path, e->name() ); break;
- case MovedTo: emit movedTo( _path, e->name() ); break;
- case DeleteSubdir: emit deletedSubdir( _path, e->name() ); break;
- case DeleteFile: emit deletedFile( _path, e->name() ); break;
- case CreateSubdir: emit createdSubdir( _path, e->name() ); break;
- case CreateFile: emit createdFile( _path, e->name() ); break;
- case DeleteSelf: emit deleted( _path ); break;
- case Unmount: emit unmounted( _path ); break;
+ case Access: emit accessed( _path ); break;
+ case Modify: emit modified( _path ); break;
+ case Attrib: emit attributed( _path); break;
+ case CloseWrite: emit closed( _path, true ); break;
+ case CloseNoWrite: emit closed( _path, false ); break;
+ case Open: emit opened( _path ); break;
+ case MovedFrom: emit movedFrom( _path, e->name() ); break;
+ case MovedTo: emit movedTo( _path, e->name() ); break;
+ case DeleteSubdir: emit deletedSubdir( _path, e->name() ); break;
+ case DeleteFile: emit deletedFile( _path, e->name() ); break;
+ case CreateSubdir: emit createdSubdir( _path, e->name() ); break;
+ case CreateFile: emit createdFile( _path, e->name() ); break;
+ case DeleteSelf: emit deleted( _path ); break;
+ case Unmount: emit unmounted( _path ); break;
+ case _QueueOverflow: qFatal( "OFileNotification::activate() - Inotify Event Queue Overload!" ); break;
+ case _Ignored: qWarning( "OFileNotification::activate() - Further Events for '%s' will be ignored", (const char*) _path ); break;
default: assert( 0 );
}
+ delete e;
+
if ( !_multi ) stop();
return true;
}
bool OFileNotification::singleShot( const QString& path, QObject* receiver, const char* member, OFileNotificationType type )
{
OFileNotification* ofn = new OFileNotification();
ofn->_signal.connect( receiver, member );
return ofn->watch( path, true, type ) != -1;
}
void OFileNotification::inotifyEventHandler()
{
qDebug( "OFileNotification::inotifyEventHandler(): reached." );
char buffer[16384];
ssize_t buffer_i;
struct inotify_event *pevent, *event;
ssize_t r;
size_t event_size;
int count = 0;
r = ::read(_fd, buffer, 16384);
if ( r <= 0 )
return;
buffer_i = 0;
while ( buffer_i < r )
{
pevent = (struct inotify_event *)&buffer[buffer_i];
event_size = sizeof(struct inotify_event) + pevent->len;
OFileNotificationEvent* e = new OFileNotificationEvent( notification_list[ pevent->wd ], pevent->wd, pevent->mask,
pevent->cookie, pevent->len ? pevent->name : 0 );
e->activate();
buffer_i += event_size;
count++;
}
qDebug( "OFileNotification::inotifyEventHandler(): processed %d events", count );
}
bool OFileNotification::registerEventHandler()
{
OFileNotification::_fd = ::open( INOTIFY_DEVICE, O_RDONLY );
if ( OFileNotification::_fd < 0 )
{
qWarning( "OFileNotification::registerEventHandler(): couldn't register event handler: %s", strerror( errno ) );
return false;
}
- OFileNotification::_sn = new QSocketNotifier( _fd, QSocketNotifier::Read, this, "inotify event" );
+ OFileNotification::_sn = new QSocketNotifier( _fd, QSocketNotifier::Read );
connect( OFileNotification::_sn, SIGNAL( activated(int) ), this, SLOT( inotifyEventHandler() ) );
qDebug( "OFileNotification::registerEventHandler(): done" );
return true;
}
void OFileNotification::unregisterEventHandler()
{
if ( _sn ) delete _sn;
if ( OFileNotification::_fd )
::close( OFileNotification::_fd );
qDebug( "OFileNotification::unregisterEventHandler(): done" );
}
//=================================================================================================
// ODirNotification
//=================================================================================================
ODirNotification::ODirNotification( QObject* parent, const char* name )
:QObject( parent, name ), _topfilenotification( 0 ), _type( Nothing ), _depth( -123 )
{
qDebug( "ODirNotification::ODirNotification()" );
}
ODirNotification::~ODirNotification()
{
qDebug( "ODirNotification::~ODirNotification()" );
}
-/*
+/**
Love-Trowbridge recursive directory scanning algorithm:
Step 1. Start at initial directory foo. Add watch.
Step 2. Setup handlers for watch created in Step 1.
Specifically, ensure that a directory created
in foo will result in a handled CREATE_SUBDIR
event.
Step 3. Read the contents of foo.
Step 4. For each subdirectory of foo read in step 3, repeat
step 1.
Step 5. For any CREATE_SUBDIR event on bar, if a watch is
not yet created on bar, repeat step 1 on bar.
-*/
+**/
int ODirNotification::watch( const QString& path, bool sshot, OFileNotificationType type, int recurse )
{
if ( _type == Nothing ) _type = type; // only set it once - for the top level call
OFileNotificationType subtype = ( recurse != 0 ) ? (OFileNotificationType) int( _type | CreateSubdir ) : _type;
qDebug( "ODirNotification::watch( %s, %d, 0x%08x, %d )", (const char*) path, sshot, subtype, recurse );
OFileNotification* fn = new OFileNotification( this, "ODirNotification delegate" );
int result = fn->startWatching( path, sshot, subtype );
if ( result != -1 )
{
if ( !_topfilenotification ) _topfilenotification = fn; // only set it once - for the top level call
if ( _depth == -123 ) _depth = recurse; // only set it once - for the top level call
connect( fn, SIGNAL( triggered( const QString&, unsigned int, const QString& ) ), this, SIGNAL( triggered( const QString&, unsigned int, const QString& ) ) );
connect( fn, SIGNAL( accessed( const QString& ) ), this, SIGNAL( accessed( const QString& ) ) );
connect( fn, SIGNAL( modified( const QString& ) ), this, SIGNAL( modified( const QString& ) ) );
connect( fn, SIGNAL( attributed( const QString& ) ), this, SIGNAL( attributed( const QString& ) ) );
connect( fn, SIGNAL( closed( const QString&, bool ) ), this, SIGNAL( closed( const QString&, bool ) ) );
connect( fn, SIGNAL( opened( const QString& ) ), this, SIGNAL( opened( const QString& ) ) );
connect( fn, SIGNAL( movedTo( const QString&, const QString& ) ), this, SIGNAL( movedTo( const QString&, const QString& ) ) );
connect( fn, SIGNAL( movedFrom( const QString&, const QString& ) ), this, SIGNAL( movedFrom( const QString&, const QString& ) ) );
connect( fn, SIGNAL( deletedSubdir( const QString&, const QString& ) ), this, SIGNAL( deletedSubdir( const QString&, const QString& ) ) );
connect( fn, SIGNAL( deletedFile( const QString&, const QString& ) ), this, SIGNAL( deletedFile( const QString&, const QString& ) ) );;
connect( fn, SIGNAL( createdSubdir( const QString&, const QString& ) ), this, SIGNAL( createdSubdir( const QString&, const QString& ) ) );
connect( fn, SIGNAL( createdFile( const QString&, const QString& ) ), this, SIGNAL( createdFile( const QString&, const QString& ) ) );
connect( fn, SIGNAL( deleted( const QString& ) ), this, SIGNAL( deleted( const QString& ) ) );
connect( fn, SIGNAL( unmounted( const QString& ) ), this, SIGNAL( unmounted( const QString& ) ) );
if ( recurse != 0 )
{
connect( fn, SIGNAL( createdSubdir( const QString&, const QString& ) ), this, SLOT( subdirCreated( const QString&, const QString& ) ) );
QDir directory( path );
QStringList subdirs = directory.entryList( QDir::Dirs );
for ( QStringList::Iterator it = subdirs.begin(); it != subdirs.end(); ++it )
{
if ( (*it) == "." || (*it) == ".." ) continue;
QString subpath = QString( "%1/%2" ).arg( path ).arg( *it );
int subresult = watch( subpath, sshot, subtype, recurse-1 );
if ( subresult == -1 )
{
qDebug( "ODirNotification::watch(): subresult for '%s' was -1. Interrupting", (const char*) (*it) );
return -1;
}
}
}
}
else return -1;
}
void ODirNotification::subdirCreated( const QString& dir, const QString& subdir )
{
qDebug( "*** ODirNotification::subdirCreated '%s/%s'", (const char*) dir, (const char*) subdir );
QString newdir = dir;
if ( newdir.startsWith( _topfilenotification->path() ) )
{
newdir.replace( _topfilenotification->path(), "" );
int level = newdir.contains( '/' );
qDebug( "*** dirpart = '%s' ==> level = %d", (const char*) newdir, level );
if ( _depth == -1 || _depth > level )
{
watch( QString( "%1/%2" ).arg( dir ).arg( subdir ), _topfilenotification->isSingleShot(), _topfilenotification->type(), _depth == -1 ? -1 : _depth-level-1 );
}
}
}
} // namespace Ui
} // namespace Opie
diff --git a/libopie2/opiecore/linux/ofilenotify.h b/libopie2/opiecore/linux/ofilenotify.h
index 17e6b5d..c713b30 100644
--- a/libopie2/opiecore/linux/ofilenotify.h
+++ b/libopie2/opiecore/linux/ofilenotify.h
@@ -1,339 +1,340 @@
/*
                This file is part of the Opie Project
=. Copyright (C) 2004-2005 Michael 'Mickey' Lauer <mickey@Vanille.de>
.=l. Copyright (C) The Opie Team <opie-devel@handhelds.org>
         .>+-=
_;:,     .>    :=|. This program is free software; you can
.> <`_,   >  .   <= redistribute it and/or modify it under
:`=1 )Y*s>-.--   : the terms of the GNU Library General Public
.="- .-=="i,     .._ License as published by the Free Software
- .   .-<_>     .<> Foundation; version 2 of the License.
   ._= =}       :
  .%`+i>       _;_.
  .i_,=:_.      -<s. 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
..}^=.=       =       ; Library General Public License for more
++=   -.     .`     .: details.
:     =  ...= . :.=-
-.   .:....=;==+<; You should have received a copy of the GNU
-_. . .   )=.  = Library General Public License along with
  --        :-=` this library; see the file COPYING.LIB.
If not, write to the Free Software Foundation,
Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA.
*/
#ifndef OFILENOTIFY_H
#define OFILENOTIFY_H
#if defined (__GNUC__) && (__GNUC__ < 3)
#define _GNU_SOURCE
#endif
#include "linux_inotify.h"
/* QT */
#include <qsocketnotifier.h>
#include <qsignal.h>
#include <qstring.h>
#include <qobject.h>
#include <qfile.h>
namespace Opie {
namespace Core {
class OFile : public QObject, public QFile
{
Q_OBJECT
public:
OFile();
OFile( const QString & name );
virtual ~OFile();
protected:
virtual void connectNotify( const char* signal );
virtual void disconnectNotify( const char* signal );
private:
int startWatch( int mode );
signals:
void accessed( const QString& );
void modified( const QString& );
void attributed( const QString& );
void closed( const QString&, bool );
void opened( const QString& );
void deleted( const QString& );
void unmounted( const QString& );
};
/*
void movedTo( const QString&, const QString& );
void movedFrom( const QString&, const QString& );
void deletedSubdir( const QString&, const QString& );
void deletedFile( const QString&, const QString& );
void createdSubdir( const QString&, const QString& );
void createdFile( const QString&, const QString& );
*/
class OFileNotificationEvent;
/*======================================================================================
* OFileNotificationType
*======================================================================================*/
/**
* @brief An enumerate for the different types of file notifications
*
* This enumerate provides a means to specify the type of events that you are interest in.
* Valid values are:
* <ul>
* <li>Access: The file was accessed (read)
* <li>Modify The file was modified (write,truncate)
* <li>Attrib = The file had its attributes changed (chmod,chown,chgrp)
* <li>CloseWrite = Writable file was closed
* <li>CloseNoWrite = Unwritable file was closed
* <li>Open = File was opened
* <li>MovedFrom = File was moved from X
* <li>MovedTo = File was moved to Y
* <li>DeleteSubdir = Subdir was deleted
* <li>DeleteFile = Subfile was deleted
* <li>CreateSubdir = Subdir was created
* <li>CreateFile = Subfile was created
* <li>DeleteSelf = Self was deleted
* <li>Unmount = The backing filesystem was unmounted
* </ul>
*
**/
enum OFileNotificationType
{
Nothing = 0,
Access = IN_ACCESS,
Modify = IN_MODIFY,
Attrib = IN_ATTRIB,
CloseWrite = IN_CLOSE_WRITE,
CloseNoWrite = IN_CLOSE_NOWRITE,
Open = IN_OPEN,
MovedFrom = IN_MOVED_FROM,
MovedTo = IN_MOVED_TO,
DeleteSubdir = IN_DELETE_SUBDIR,
DeleteFile = IN_DELETE_FILE,
CreateSubdir = IN_CREATE_SUBDIR,
CreateFile = IN_CREATE_FILE,
DeleteSelf = IN_DELETE_SELF,
Unmount = IN_UNMOUNT,
_QueueOverflow = IN_Q_OVERFLOW, /* Internal, don't use this in client code */
_Ignored = IN_IGNORED, /* Internal, don't use this in client code */
};
/*======================================================================================
* OFileNotification
*======================================================================================*/
/**
* @brief Represents a file notification
*
* This class allows to watch for events happening to files.
* It uses the inotify linux (2.6.x) kernel interface.
*
* @see http://www.kernel.org/pub/linux/kernel/people/rml/inotify/
*
* @author Michael 'Mickey' Lauer <mickey@vanille.de>
*
**/
class OFileNotification : public QObject
{
Q_OBJECT
public:
OFileNotification( QObject* parent = 0, const char* name = 0 );
~OFileNotification();
/**
* This static function calls a slot when an event with @a type happens to file @a path.
*
* It is very convenient to use this function because you do not need to
* bother with a timerEvent or to create a local QTimer object.
*
* Example:
* <pre>
*
* #include <opie2/oapplication.h>
* #include <opie2/ofilenotify.h>
* using namespace Opie::Core;
*
* int main( int argc, char **argv )
* {
* OApplication a( argc, argv, "File Notification Example" );
* OFileNotification::singleShot( "/tmp/quit", &a, SLOT(quit()), Access );
* ... // create and show your widgets
* return a.exec();
* }
* </pre>
*
* This sample program automatically terminates when the file "/tmp/quit" has been accessed.
*
*
* The @a receiver is the receiving object and the @a member is the slot.
**/
static bool singleShot( const QString& path, QObject* receiver, const char* member, OFileNotificationType type = Modify );
/**
* Starts to watch for @a type changes to @a path. Set @a sshot to True if you want to be notified only once.
* Note that in that case it may be more convenient to use @ref OFileNotification::singleShot() then.
**/
int watch( const QString& path, bool sshot = false, OFileNotificationType type = Modify );
/**
* Stop watching for file events.
**/
void stop();
/**
* @returns the notification type as set by @ref start().
**/
OFileNotificationType type() const;
/**
* @returns the path to the file being watched by this instance.
**/
QString path() const;
/**
* @returns if the notification is single-shot
*/
bool isSingleShot() const;
/**
* @returns if a file is currently being watched.
**/
bool isActive() const;
/**
* @internal
*/
int startWatching( const QString& path, bool sshot = false, OFileNotificationType type = Modify );
signals:
void triggered( const QString&, unsigned int, const QString& );
void accessed( const QString& );
void modified( const QString& );
void attributed( const QString& );
void closed( const QString&, bool );
void opened( const QString& );
void movedTo( const QString&, const QString& );
void movedFrom( const QString&, const QString& );
void deletedSubdir( const QString&, const QString& );
void deletedFile( const QString&, const QString& );
void createdSubdir( const QString&, const QString& );
void createdFile( const QString&, const QString& );
void deleted( const QString& );
void unmounted( const QString& );
protected:
bool activate( const OFileNotificationEvent* e );
private slots:
void inotifyEventHandler();
private:
bool registerEventHandler();
void unregisterEventHandler();
QString _path;
OFileNotificationType _type;
QSignal _signal;
bool _active;
bool _multi;
static QSocketNotifier* _sn;
int _wd; // inotify watch descriptor
static int _fd; // inotify device descriptor
friend class OFileNotificationEvent;
};
/*======================================================================================
* ODirNotification
*======================================================================================*/
/**
* @brief Represents a directory notification
*
* This class allows to watch for events happening to directories
- * It uses the OFileNotification class
+ * It uses the OFileNotification class and (for recursive watches)
+ * implements the Love-Trowbridge recursive directory scanning algorithm.
*
* @see http://www.kernel.org/pub/linux/kernel/people/rml/inotify/
*
* @author Michael 'Mickey' Lauer <mickey@vanille.de>
*
**/
class ODirNotification : public QObject
{
Q_OBJECT
public:
ODirNotification( QObject* parent = 0, const char* name = 0 );
~ODirNotification();
/**
* Starts to watch for @a type changes to @a path. Recurse @a recurse levels down the filesystem tree,
* use 0 for no recursion and -1 for unlimited recursion.
* Set @a sshot to True if you want to be notified only once.
**/
int watch( const QString& path, bool sshot = false, OFileNotificationType type = Modify, int recurse = 0 );
signals:
/**
* This signal is emitted if an event happens of the specified type happens to the directory being watched.
**/
void triggered( const QString&, unsigned int, const QString& );
void accessed( const QString& );
void modified( const QString& );
void attributed( const QString& );
void closed( const QString&, bool );
void opened( const QString& );
void movedTo( const QString&, const QString& );
void movedFrom( const QString&, const QString& );
void deletedSubdir( const QString&, const QString& );
void deletedFile( const QString&, const QString& );
void createdSubdir( const QString&, const QString& );
void createdFile( const QString&, const QString& );
void deleted( const QString& );
void unmounted( const QString& );
private slots:
void subdirCreated( const QString&, const QString& );
private:
OFileNotification* _topfilenotification;
OFileNotificationType _type;
int _depth;
};
/*======================================================================================
* OFileNotificationEvent
*======================================================================================*/
class OFileNotificationEvent
{
public:
OFileNotificationEvent( OFileNotification* parent, int wd, unsigned int mask, unsigned int cookie, const QString& name );
~OFileNotificationEvent();
OFileNotification* parent() const { return _parent; };
int descriptor() const { return _wd; };
unsigned int mask() const { return _mask; };
unsigned int cookie() const { return _cookie; };
QString name() const { return _name; };
void activate() { _parent->activate( this ); };
private:
OFileNotification* _parent;
int _wd;
unsigned int _mask;
unsigned int _cookie;
QString _name;
};
}
}
#endif
diff --git a/scripts/addLanguage.sh b/scripts/addLanguage.sh
new file mode 100755
index 0000000..e321804
--- a/dev/null
+++ b/scripts/addLanguage.sh
@@ -0,0 +1,33 @@
+#!/bin/bash
+
+# (c) 2002 Bruno Rodrigues <bruno.rodrigues@litux.org>
+# Under GPL Licence
+
+# Add a new TRANSLATION line to every .pro file if there
+# is already at least one TRANSLATION file and this LANG
+# is not present
+# The perl line would grab a TRANSLATION = something and
+# duplicate it to TRANSLATION += .../LANG/...
+
+LANG=$1
+
+if [ "$1x" == "x" ] ; then
+ echo "Usage: $0 <LANG>"
+ exit
+fi
+
+for i in `find . -name "*.pro"` ; do
+ grep TRANSLATIONS $i > /dev/null
+ if [ "$?" != 0 ] ; then
+ echo "$i: No Translations"
+ else
+ grep "../i18n/$LANG/" $i > /dev/null
+ if [ "$?" == 0 ] ; then
+ echo "$i: $LANG already there"
+ else
+ echo "$i: Adding $LANG"
+ perl -p -i.bak -e 's/^(TRANSLATIONS\s*\+?=\s*)(.+?i18n\/)(.+?)(\/.+?\.ts)(.*)$/$1$2$3$4 \\\n\t $2'$LANG'$4$5/' $i
+ fi
+ fi
+done
+
diff --git a/scripts/mkipks b/scripts/mkipks
new file mode 100755
index 0000000..f142029
--- a/dev/null
+++ b/scripts/mkipks
@@ -0,0 +1,261 @@
+#!/bin/sh
+
+if [ -z "$QTE_BASEVERSION" ]
+then
+ if [ -e $QTDIR/include/qglobal.h ]
+ then
+ QTE_BASEVERSION=`cat $QTDIR/include/qglobal.h|grep '^#define QT_VERSION'|grep -v STR|sed -e 's,#define QT_VERSION\t*,,;' -e 's,.*\([0-9]\)\([0-9]\)\([0-9]\).*,\1.\2.\3,;'`
+ else
+ QTE_BASEVERSION=2.3.4
+ fi
+fi
+if [ -z "$QTE_VERSION" ]
+then
+ if [ -e $QTDIR/include/qglobal.h ]
+ then
+ QTE_VERSION=`cat $QTDIR/include/qglobal.h|grep '^#define QT_VERSION_STR'|sed -e 's,#define QT_VERSION_STR\t*,,;' -e 's,.*"\([^"]*\)".*,\1,;'`
+ else
+ QTE_VERSION=2.3.4
+ fi
+fi
+[ -z "$QTE_REVISION" ] && QTE_REVISION=5
+DEB_VERSION=2.0
+
+# Have to do this here, since CVS can't store symlinks
+
+mkdir -p $OPIEDIR/etc/rcS.d
+ln -sf ../init.d/bootsplash $OPIEDIR/etc/rcS.d/S01bootsplash
+
+VERSION_MAJ=$(sed -n -e 's/.*QPE_VERSION "\([0-9]*\)\..*\..*".*/\1/p' <$OPIEDIR/include/qpe/version.h)
+VERSION_MIN=$(sed -n -e 's/.*QPE_VERSION ".*\.\([0-9]*\)\..*".*/\1/p' <$OPIEDIR/include/qpe/version.h)
+VERSION_PAT=$(sed -n -e 's/.*QPE_VERSION ".*\..*\.\([0-9]*\).*/\1/p' <$OPIEDIR/include/qpe/version.h)
+SUB_VERSION=$(sed -n -e 's,.*SUB_VERSION \"\(.*\)\".*,\1,p' <$OPIEDIR/include/qpe/version.h)
+if grep -q 'QPE_VERSION .*snapshot' $OPIEDIR/include/qpe/version.h
+then
+ [ -z "$VERSION_CVS" ] && VERSION_CVS="$(date +%Y%m%d)"
+ SUB_VERSION=$VERSION_CVS
+else
+ VERSION_CVS=""
+fi
+
+QPE_VERSION=$VERSION_MAJ.$VERSION_MIN.$VERSION_PAT
+
+ARCH=arm
+STRIP=arm-linux-strip
+STRIP_FILES="*ARM*not stripped"
+
+TDIR=/tmp/ipk$$
+DATADIR=$TDIR
+CTRLDIR=$TDIR/CONTROL
+
+IMAGEDIR=
+VERB=
+LIST=
+RPM=
+
+while [ $# -ne 0 ]
+do
+ case "$1" in
+ -v)
+ VERB=1
+ echo >&2 "Packaging for version $VERSION_MAJ.$VERSION_MIN.$VERSION_PAT$VERSION_CVS"
+ ;; -l)
+ LIST=1
+ ;; -i)
+ shift
+ IMAGEDIR=$1
+ DATADIR=$IMAGEDIR
+ mkdir -p $IMAGEDIR
+ ;; -classic)
+ classicopts=-c
+ ;; -rpm)
+ if [ "$OPIEDIR" != "/opt/Qtopia" ]
+ then
+ echo >&2 '$OPIEDIR is not the standard /usr/Qtopia directory.'
+ sleep 1
+ #exit 1
+ fi
+ RPM=1
+ ;; -arch)
+ shift
+ ARCH=$1
+ STRIP=
+ STRIP_FILES=
+ ;; /*)
+ FILES="$FILES $1"
+ ;; *)
+ FILES="$FILES $PWD/$1"
+ esac
+ shift
+done
+
+if [ -z "$FILES" ]
+then
+ FILES=`find $OPIEDIR -name "*.control" -print`
+fi
+
+RDIR=$PWD
+ORIGDIR=`pwd`
+cd $OPIEDIR
+
+for i in $FILES
+do
+ rm -rf $TDIR
+
+ mkdir -p $DATADIR
+ mkdir -p $CTRLDIR
+
+ packagename=${i##*/}; packagename=${packagename%.control}
+ version=$(eval echo '"'$(sed -n -e "s/^Version: *//p" $i)'"')
+ depends=$(eval echo '"'$(sed -n -e "s/^Depends: *//p" $i)'"')
+ files=$(eval echo $(sed -n -e "s/^Files://p" $i))
+ arch=$(eval echo $(sed -n -e "s/^Arch://p" $i))
+ section=$(sed -n -e "s/^Section: *//p" $i)
+ provides=$(sed -n -e "s/^Provides: *//p" $i)
+ conflicts=$(sed -n -e "s/^Conflicts: *//p" $i)
+ license=$(sed -n -e "s/^License: *//p" $i)
+ summary=$(sed -n -e "s/^Description: *//p" $i)
+ package=${packagename}_${version}_$ARCH
+ ERROR=
+ if [ -z "$files" ]
+ then
+ mkdir -p $DATADIR/usr/share/doc/$packagename
+ else
+ for f in $files
+ do
+ if [ -d $f ]
+ then
+ ffiles=$(find $f -type f -o -type b -o -type c -o -type l)
+ else
+ ffiles=$f
+ fi
+ for ff in $ffiles
+ do
+ case $ff in
+ */CVS/*)
+ continue
+ ;; *~)
+ continue
+ ;; *.control)
+ continue
+ ;; $QTDIR/*)
+ BASE=$(dirname /opt/QtPalmtop/${ff#$QTDIR/})
+ ;; etc/*.d/*)
+ BASE=$(dirname /$ff)
+ ;; root/*)
+ BASE=$(dirname ${ff#root})
+ ;; lib/*)
+ BASE=$(dirname /opt/QtPalmtop/$ff)
+ ;; $OPIEDIR/lib/*)
+ BASE=$(dirname /opt/QtPalmtop/${ff#$OPIEDIR/})
+ ;; $OPIEDIR/root/*)
+ BASE=$(dirname /${ff#$OPIEDIR/root/})
+ ;; *)
+ # For SHARP ROM compatibility. Should change to Qtopia.
+ BASE=/opt/QtPalmtop/$(dirname $ff)
+ esac
+
+ if [ -f $ff -o -b $ff -o -c $ff ]
+ then
+ D=$DATADIR$BASE
+ if [ -x $ff -a -n "$STRIP" ]
+ then
+ case $(file $ff) in
+ $STRIP_FILES)
+ $STRIP $ff
+ ;; *)
+ esac
+ fi
+ if [ -n "$RPM" ]
+ then
+ case "$ff" in
+ /*) RPMFILES="$RPMFILES $ff"
+ ;; *) RPMFILES="$RPMFILES $OPIEDIR/$ff"
+ esac
+ else
+ mkdir -p $D
+ if cp -a $ff $D
+ then
+ true
+ else
+ ERROR=1
+ fi
+ fi
+ else
+ echo >&2 "$0: $i: No such file: $ff"
+ ERROR=1
+ fi
+ done
+ done
+ fi
+ if [ -z "$ERROR" ]
+ then
+ if [ -n "$RPM" ]
+ then
+ SPEC=/tmp/mkipks-rpm-$$.spec
+ echo >$SPEC "Summary: $summary"
+ echo >>$SPEC "Name: $packagename"
+ echo >>$SPEC "Group: $section" ##########
+ echo >>$SPEC "License: $license"
+ echo >>$SPEC "Version: ${version%-*}"
+ echo >>$SPEC "Release: ${version#*-}"
+
+ echo >>$SPEC "%description"
+ sed -n -e '/^Description:/,$ p' $i | tail +2 >>$SPEC
+ echo >>$SPEC "%files"
+ echo >>$SPEC "%defattr(-,root,root)"
+ /bin/ls $RPMFILES >>$SPEC
+ rpm -bb --target $ARCH-unknown-linux $SPEC
+ # rm $SPEC
+ elif [ -z "$IMAGEDIR" ]
+ then
+ #size=$(du -h -s $DATADIR | sed -e 's/[ ].*//')
+ if (which mkfs.jffs2 >/dev/null 2>&1); then
+ size=$(mkfs.jffs2 -r $DATADIR | wc -c)
+ fi
+ if ! (cat $i|grep -q ^Package:); then
+ echo "Package: $packagename" >$CTRLDIR/control
+ fi
+ if [ ! -z "$size" ]; then
+ echo "Installed-Size: $size" >>$CTRLDIR/control
+ else
+ if [ -z "$SIZEWARNED" ]
+ then
+ echo "Warning, no mkfs.jffs2 found, unable to set Installed-Size."
+ SIZEWARNED=1
+ fi
+ fi
+ echo "Architecture: $ARCH" >>$CTRLDIR/control
+ echo "Version: $version" >>$CTRLDIR/control
+ [ ! -z "$depends" ] && echo "Depends: $depends" >>$CTRLDIR/control
+ [ ! -z "$provides" ] && echo "Provides: $provides" >>$CTRLDIR/control
+ [ ! -z "$conflicts" ] && echo "Conflicts: $conflicts" >>$CTRLDIR/control
+ egrep -v "^(Files|Version|Depends|Provides|Conflicts|Architecture):" >>$CTRLDIR/control $i
+ [ -n "$classicopts" ] && echo "$DEB_VERSION" >$TDIR/debian-binary
+ base=${i%.control}
+ scripts="preinst postinst prerm postrm"
+ for pf in $scripts
+ do
+ if [ -e ${base}.$pf ]
+ then
+ cp ${base}.$pf $CTRLDIR/$pf
+ chmod 755 $CTRLDIR/$pf
+ fi
+ done
+ cd $ORIGDIR; $OPIEDIR/scripts/ipkg-build $classicopts -o root -g root $TDIR; cd $OPIEDIR;
+ RESULT=$package.ipk
+ if [ -n "$VERB" ]
+ then
+ echo >&2 "Built $RESULT ($size)"
+ fi
+ if [ -n "$LIST" ]
+ then
+ echo $RESULT
+ fi
+ fi
+ else
+ echo >&2 "Not building $package package"
+ fi
+done
+# clean up
+rm -rf $TDIR