author | chicken <chicken> | 2004-03-01 15:58:07 (UTC) |
---|---|---|
committer | chicken <chicken> | 2004-03-01 15:58:07 (UTC) |
commit | 931c55406a043195712955c732a875e17899df90 (patch) (side-by-side diff) | |
tree | 8097c88ee3e96f8fb613ccca1ebf36bf73070dcc | |
parent | 87676b131aad1bfe979570a48107527db4040020 (diff) | |
download | opie-931c55406a043195712955c732a875e17899df90.zip opie-931c55406a043195712955c732a875e17899df90.tar.gz opie-931c55406a043195712955c732a875e17899df90.tar.bz2 |
fix includes
25 files changed, 1 insertions, 67 deletions
diff --git a/libopie2/opiecore/odebug.cpp b/libopie2/opiecore/odebug.cpp index 4505ce7..a40ef53 100644 --- a/libopie2/opiecore/odebug.cpp +++ b/libopie2/opiecore/odebug.cpp @@ -1,631 +1,620 @@ /* This file is part of the Opie Project (C) 2003 Michael 'Mickey' Lauer (mickey@tm.informatik.uni-frankfurt.de) (C) 2002 Holger Freyther (freyther@kde.org) (C) 1997 Matthias Kalle Dalheimer (kalle@kde.org) =. .=l. .>+-= _;:, .> :=|. 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; either version 2 of the License, ._= =} : or (at your option) any later version. .%`+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 this header without OPIE_NO_DEBUG defined to avoid having the oDebugInfo // functions inlined to noops (which would then conflict with their definition here). #include <opie2/odebug.h> #ifdef OPIE_NO_DEBUG #undef odDebug #undef odBacktrace #endif /* OPIE */ #include <opie2/oapplication.h> #include <opie2/oglobalsettings.h> #include <opie2/oconfig.h> /* QT */ -#include <qbrush.h> -#include <qdatetime.h> #include <qfile.h> -#include <qhostaddress.h> #include <qmessagebox.h> -#include <qintdict.h> -#include <qpoint.h> -#include <qrect.h> -#include <qregion.h> -#include <qsize.h> #include <qsocketdevice.h> -#include <qstring.h> -#include <qstringlist.h> -#include <qtextstream.h> /* UNIX */ #include <stdlib.h> // abort #include <unistd.h> // getpid #include <stdarg.h> // vararg stuff #include <ctype.h> // isprint #include <syslog.h> #include <errno.h> #include <string.h> #ifndef OPIE_NO_BACKTRACE #include <execinfo.h> #endif /*====================================================================================== * debug levels *======================================================================================*/ enum DebugLevels { ODEBUG_INFO = 0, ODEBUG_WARN = 1, ODEBUG_ERROR = 2, ODEBUG_FATAL = 3 }; /*====================================================================================== * oDebug private data *======================================================================================*/ /*====================================================================================== * the main debug function *======================================================================================*/ static void oDebugBackend( unsigned short level, unsigned int area, const char *data) { //qDebug( "oDebugBackend: Level=%d, Area=%d, Data=%s", level, area, data ); // ML: OPIE doesn't use areacodes at the moment. See the KDE debug classes for an // ML: example use. I think it's not necessary to implement such a strategy here. // ML: Comments? int priority = 0; QString caption; QString lev; switch( level ) { case ODEBUG_INFO: lev = "(Info)"; caption = "Info"; priority = LOG_INFO; break; case ODEBUG_WARN: lev = "(Warn)"; caption = "Warning"; priority = LOG_WARNING; break; case ODEBUG_FATAL: lev = "(Fatal)"; caption = "Fatal Error"; priority = LOG_CRIT; break; default: qDebug( "oDebugBackend: Warning: Unknown debug level! - defaulting to ODEBUG_ERROR." ); case ODEBUG_ERROR: lev = "(Error)"; caption = "Error"; priority = LOG_ERR; break; } short output = OGlobalSettings::debugMode(); if (!oApp && (output == 1)) { qDebug( "oDebugBackend: Warning: no oapplication object - can't use MsgBox" ); output = 2; // need an application object to use MsgBox } // gcc 2.9x is dumb and sucks... can you hear it? //QString areaName = (oApp) ? oApp->appName() : "<unknown>"; QString areaName; if ( oApp ) areaName = oApp->appName(); else areaName = "<unknown>"; // Output switch( output ) { case -1: // ignore { return; } case 0: // File { QString outputFilename = OGlobalSettings::debugOutput(); const int BUFSIZE = 4096; char buf[BUFSIZE] = ""; buf[BUFSIZE-1] = '\0'; int nSize; nSize = snprintf( buf, BUFSIZE-1, "%s: %s", (const char*) areaName, data); QFile outputFile( outputFilename ); if ( outputFile.open( IO_WriteOnly | IO_Append ) ) { if ( ( nSize == -1 ) || ( nSize >= BUFSIZE ) ) { outputFile.writeBlock( buf, BUFSIZE-1 ); } else { outputFile.writeBlock( buf, nSize ); } } else { qDebug( "ODebug: can't write to file '%s' (%s)", (const char*) outputFilename, strerror(errno) ); } break; } // automatic close of file here case 1: // Message Box { // Since we are in opiecore here, we cannot use OMsgBox and use // QMessageBox instead caption += QString("(") + areaName + ")"; QMessageBox::warning( 0L, caption, data, ("&OK") ); // tr? break; } case 2: // Shell { FILE *output = stderr; fprintf( output, "%s: ", (const char*) areaName ); fputs( data, output); break; } case 3: // syslog { syslog( priority, "%s", data); break; } case 4: // socket { QString destination = OGlobalSettings::debugOutput(); if ( destination && destination.find(":") != -1 ) { QString host = destination.left( destination.find(":") ); QString port = destination.right( destination.length()-host.length()-1 ); QHostAddress addr; addr.setAddress( host ); // TODO: sanity check the address QString line; line.sprintf( "%s: %s", (const char*) areaName, (const char*) data ); QSocketDevice s( QSocketDevice::Datagram ); int result = s.writeBlock( (const char*) line, line.length(), addr, port.toInt() ); if ( result == -1 ) { qDebug( "ODebug: can't send to address '%s:%d' (%s)", (const char*) host, port.toInt(), strerror(errno) ); } } break; } } // check if we should abort /* if( ( nLevel == ODEBUG_FATAL ) && ( !oDebug_data->config || oDebug_data->config->readNumEntry( "AbortFatal", 1 ) ) ) abort(); */ } /*====================================================================================== * odbgstream *======================================================================================*/ odbgstream& perror( odbgstream &s) { return s << QString::fromLocal8Bit(strerror(errno)); } odbgstream odDebug(int area) { return odbgstream(area, ODEBUG_INFO); } odbgstream odDebug(bool cond, int area) { if (cond) return odbgstream(area, ODEBUG_INFO); else return odbgstream(0, 0, false); } odbgstream odError(int area) { return odbgstream("ERROR: ", area, ODEBUG_ERROR); } odbgstream odError(bool cond, int area) { if (cond) return odbgstream("ERROR: ", area, ODEBUG_ERROR); else return odbgstream(0,0,false); } odbgstream odWarning(int area) { return odbgstream("WARNING: ", area, ODEBUG_WARN); } odbgstream odWarning(bool cond, int area) { if (cond) return odbgstream("WARNING: ", area, ODEBUG_WARN); else return odbgstream(0,0,false); } odbgstream odFatal(int area) { return odbgstream("FATAL: ", area, ODEBUG_FATAL); } odbgstream odFatal(bool cond, int area) { if (cond) return odbgstream("FATAL: ", area, ODEBUG_FATAL); else return odbgstream(0,0,false); } odbgstream::odbgstream(unsigned int _area, unsigned int _level, bool _print) :area(_area), level(_level), print(_print) { } odbgstream::odbgstream(const char * initialString, unsigned int _area, unsigned int _level, bool _print) :output(QString::fromLatin1(initialString)), area(_area), level(_level), print(_print) { } odbgstream::odbgstream(odbgstream &str) :output(str.output), area(str.area), level(str.level), print(str.print) { str.output.truncate(0); } odbgstream::odbgstream(const odbgstream &str) :output(str.output), area(str.area), level(str.level), print(str.print) { } odbgstream& odbgstream::operator<<(bool i) { if (!print) return *this; output += QString::fromLatin1(i ? "true" : "false"); return *this; } odbgstream& odbgstream::operator<<(short i) { if (!print) return *this; QString tmp; tmp.setNum(i); output += tmp; return *this; } odbgstream& odbgstream::operator<<(unsigned short i) { if (!print) return *this; QString tmp; tmp.setNum(i); output += tmp; return *this; } odbgstream& odbgstream::operator<<(unsigned char i) { return operator<<( static_cast<char>( i ) ); } odbgstream& odbgstream::operator<<(int i) { if (!print) return *this; QString tmp; tmp.setNum(i); output += tmp; return *this; } odbgstream& odbgstream::operator<<(unsigned int i) { if (!print) return *this; QString tmp; tmp.setNum(i); output += tmp; return *this; } odbgstream& odbgstream::operator<<(long i) { if (!print) return *this; QString tmp; tmp.setNum(i); output += tmp; return *this; } odbgstream& odbgstream::operator<<(unsigned long i) { if (!print) return *this; QString tmp; tmp.setNum(i); output += tmp; return *this; } odbgstream& odbgstream::operator<<(const QString& string) { if (!print) return *this; output += string; if (output.at(output.length() -1 ) == '\n') flush(); return *this; } odbgstream& odbgstream::operator<<(const char *string) { if (!print) return *this; output += QString::fromUtf8(string); if (output.at(output.length() - 1) == '\n') flush(); return *this; } odbgstream& odbgstream::operator<<(const QCString& string) { *this << string.data(); return *this; } odbgstream& odbgstream::operator<<(const void * p) { form("%p", p); return *this; } odbgstream& odbgstream::operator<<(double d) { QString tmp; tmp.setNum(d); output += tmp; return *this; } /* odbgstream::odbgstream &form(const char *format, ...) #ifdef __GNUC__ __attribute__ ( ( format ( printf, 2, 3 ) ) ) #endif ; */ void odbgstream::flush() { if ( output.isEmpty() || !print ) { return; } else { oDebugBackend( level, area, output.local8Bit().data() ); output = QString::null; } } odbgstream& odbgstream::form(const char *format, ...) { char buf[4096]; va_list arguments; va_start( arguments, format ); buf[sizeof(buf)-1] = '\0'; vsnprintf( buf, sizeof(buf)-1, format, arguments ); va_end(arguments); *this << buf; return *this; } odbgstream::~odbgstream() { if (!output.isEmpty()) { fprintf(stderr, "ASSERT: debug output not ended with \\n\n"); *this << "\n"; } } odbgstream& odbgstream::operator<<(char ch) { if (!print) return *this; if (!isprint(ch)) { output += "\\x" + QString::number( static_cast<uint>( ch ) + 0x100, 16 ).right(2); } else { output += ch; if (ch == '\n') flush(); } return *this; } odbgstream& odbgstream::operator<<( QWidget* widget ) { QString string, temp; // ----- if(widget==0) { string=(QString)"[Null pointer]"; } else { temp.setNum((ulong)widget, 16); string=(QString)"["+widget->className()+" pointer " + "(0x" + temp + ")"; if(widget->name(0)==0) { string += " to unnamed widget, "; } else { string += (QString)" to widget " + widget->name() + ", "; } string += "geometry=" + QString().setNum(widget->width()) + "x"+QString().setNum(widget->height()) + "+"+QString().setNum(widget->x()) + "+"+QString().setNum(widget->y()) + "]"; } if (!print) return *this; output += string; if (output.at(output.length()-1) == '\n') { flush(); } return *this; } /* * either use 'output' directly and do the flush if needed * or use the QString operator which calls the char* operator * */ odbgstream& odbgstream::operator<<( const QDateTime& time) { *this << time.toString(); return *this; } odbgstream& odbgstream::operator<<( const QDate& date) { *this << date.toString(); return *this; } odbgstream& odbgstream::operator<<( const QTime& time ) { *this << time.toString(); return *this; } odbgstream& odbgstream::operator<<( const QPoint& p ) { *this << "(" << p.x() << ", " << p.y() << ")"; return *this; } odbgstream& odbgstream::operator<<( const QSize& s ) { *this << "[" << s.width() << "x" << s.height() << "]"; return *this; } odbgstream& odbgstream::operator<<( const QRect& r ) { *this << "[" << r.left() << ", " << r.top() << " - " << r.right() << ", " << r.bottom() << "]"; return *this; } odbgstream& odbgstream::operator<<( const QRegion& reg ) { /* Qt2 doesn't have a QMemArray... :( *this << "[ "; QMemArray<QRect>rs=reg.rects(); for (uint i=0;i<rs.size();++i) *this << QString("[%1, %2 - %3, %4] ").arg(rs[i].left()).arg(rs[i].top()).arg(rs[i].right()).arg(rs[i].bottom() ) ; *this <<"]"; */ return *this; } odbgstream& odbgstream::operator<<( const QStringList& l ) { *this << "("; *this << l.join(","); *this << ")"; return *this; } odbgstream& odbgstream::operator<<( const QColor& c ) { if ( c.isValid() ) *this << c.name(); else *this << "(invalid/default)"; return *this; } odbgstream& odbgstream::operator<<( const QBrush& b) { static const char* const s_brushStyles[] = { "NoBrush", "SolidPattern", "Dense1Pattern", "Dense2Pattern", "Dense3Pattern", "Dense4Pattern", "Dense5Pattern", "Dense6Pattern", "Dense7Pattern", "HorPattern", "VerPattern", "CrossPattern", "BDiagPattern", "FDiagPattern", "DiagCrossPattern" }; *this <<"[ style: "; *this <<s_brushStyles[ b.style() ]; *this <<" color: "; // can't use operator<<(str, b.color()) because that terminates a odbgstream (flushes) if ( b.color().isValid() ) *this <<b.color().name() ; else *this <<"(invalid/default)"; if ( b.pixmap() ) *this <<" has a pixmap"; *this <<" ]"; return *this; } QString odBacktrace( int levels ) { QString s; #ifndef OPIE_NO_BACKTRACE void* trace[256]; int n = backtrace(trace, 256); char** strings = backtrace_symbols (trace, n); if ( levels != -1 ) n = QMIN( n, levels ); s = "[\n"; for (int i = 0; i < n; ++i) s += QString::number(i) + QString::fromLatin1(": ") + QString::fromLatin1(strings[i]) + QString::fromLatin1("\n"); s += "]\n"; free (strings); #endif return s; } void odClearDebugConfig() { /* delete oDebug_data->config; oDebug_data->config = 0; */ } #ifdef OPIE_NO_DEBUG #define odDebug ondDebug #define odBacktrace ondBacktrace #endif diff --git a/libopie2/opiecore/oglobal.cpp b/libopie2/opiecore/oglobal.cpp index 879e80f..1aa206e 100644 --- a/libopie2/opiecore/oglobal.cpp +++ b/libopie2/opiecore/oglobal.cpp @@ -1,411 +1,410 @@ /* This file is part of the Opie Project Copyright (C) 2003 Michael 'Mickey' Lauer <mickey@Vanille.de> =. Copyright (C) 2004 Holger 'zecke' Freyther <zecke@handhelds.org> .=l. .>+-= _;:, .> :=|. 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; either version 2 of the License, ._= =} : or (at your option) any later version. .%`+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 <opie2/oglobal.h> -#include <qfile.h> #include <qtextstream.h> #include <qdir.h> #include <qpe/mimetype.h> #include <qpe/qpeapplication.h> #include <qpe/storage.h> #include <unistd.h> #include <sys/types.h> static const char Base64EncMap[64] = { 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7A, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x2B, 0x2F }; static char Base64DecMap[128] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3E, 0x00, 0x00, 0x00, 0x3F, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F, 0x30, 0x31, 0x32, 0x33, 0x00, 0x00, 0x00, 0x00, 0x00 }; OConfig* OGlobal::_config = 0; OConfig* OGlobal::_qpe_config = 0; OConfig* OGlobal::config() { if ( !OGlobal::_config ) { // odebug classes are reading config, so can't use them here! qDebug( "OGlobal::creating global configuration instance." ); OGlobal::_config = new OConfig( "global" ); } return OGlobal::_config; } /** * Return the internal builtin Global::Command object * */ Global::Command* OGlobal::builtinCommands() { return builtin; } /** * Return the internal builtin QGuardedPtr<QWidget> object */ QGuardedPtr<QWidget>* OGlobal::builtinRunning() { return running; } /** * \brief generate a new UUID as QString * Return a new UUID as QString. UUID are global unique * * * @return the UUID or QString::null */ QString OGlobal::generateUuid() { QFile file( "/proc/sys/kernel/random/uuid" ); if (!file.open(IO_ReadOnly ) ) return QString::null; QTextStream stream(&file); return "{" + stream.read().stripWhiteSpace() + "}"; } /** * \brief Encode a QByteArray in base64 * * An Implementation of the RF1521 base64 encoding. * * The boolean argument determines if the encoded data is * going to be restricted to 76 characters or less per line * as specified by RFC 2045. If @p insertLFs is true, then * there will be 76 characters or less per line. * * If you use this to create a QCString remember that it is null terminated! * \code * QByteArray ar = OGlobal::encodeBase64(&array); * QCString str(ar.data(),ar.size()+1); // the NUL at the end * * \endcode * * @param in The QByteArray to encode * @param insertLFs Limit number of characters per line * @return The argument as base64 encoded or QByteArray() if in.isEmpty() * @see QByteArray * @see QArray * @see QMemArray * @see QCString */ /* * LGPL by Rik Hemsely of the KDE Project. taken from kmdcodec.cpp */ QByteArray OGlobal::encodeBase64(const QByteArray& in, bool insertLFs ) { if ( in.isEmpty() ) return QByteArray(); unsigned int sidx = 0; unsigned int didx = 0; const char* data = in.data(); const unsigned int len = in.size(); unsigned int out_len = ((len+2)/3)*4; // Deal with the 76 characters or less per // line limit specified in RFC 2045 on a // pre request basis. insertLFs = (insertLFs && out_len > 76); if ( insertLFs ) out_len += ((out_len-1)/76); int count = 0; QByteArray out( out_len ); // 3-byte to 4-byte conversion + 0-63 to ascii printable conversion if ( len > 1 ) { while (sidx < len-2) { if ( insertLFs ) { if ( count && (count%76) == 0 ) out[didx++] = '\n'; count += 4; } out[didx++] = Base64EncMap[(data[sidx] >> 2) & 077]; out[didx++] = Base64EncMap[(data[sidx+1] >> 4) & 017 | (data[sidx] << 4) & 077]; out[didx++] = Base64EncMap[(data[sidx+2] >> 6) & 003 | (data[sidx+1] << 2) & 077]; out[didx++] = Base64EncMap[data[sidx+2] & 077]; sidx += 3; } } if (sidx < len) { if ( insertLFs && (count > 0) && (count%76) == 0 ) out[didx++] = '\n'; out[didx++] = Base64EncMap[(data[sidx] >> 2) & 077]; if (sidx < len-1) { out[didx++] = Base64EncMap[(data[sidx+1] >> 4) & 017 | (data[sidx] << 4) & 077]; out[didx++] = Base64EncMap[(data[sidx+1] << 2) & 077]; } else { out[didx++] = Base64EncMap[(data[sidx] << 4) & 077]; } } // Add padding while (didx < out.size()) { out[didx] = '='; didx++; } return out; } /** * Decodes the given data that was encoded with the base64 * algorithm. * * * @param in the encoded data to be decoded. * @return the decoded QByteArray or QByteArray() in case of failure * @see OGlobal::encodeBase64 */ QByteArray OGlobal::decodeBase64( const QByteArray& in) { if ( in.isEmpty() ) return QByteArray(); QByteArray out; unsigned int count = 0; unsigned int len = in.size(), tail = len; const char* data = in.data(); // Deal with possible *nix "BEGIN" marker!! while ( count < len && (data[count] == '\n' || data[count] == '\r' || data[count] == '\t' || data[count] == ' ') ) count++; if ( strncasecmp(data+count, "begin", 5) == 0 ) { count += 5; while ( count < len && data[count] != '\n' && data[count] != '\r' ) count++; while ( count < len && (data[count] == '\n' || data[count] == '\r') ) count ++; data += count; tail = (len -= count); } // Find the tail end of the actual encoded data even if // there is/are trailing CR and/or LF. while ( data[tail-1] == '=' || data[tail-1] == '\n' || data[tail-1] == '\r' ) if ( data[--tail] != '=' ) len = tail; unsigned int outIdx = 0; out.resize( (count=len) ); for (unsigned int idx = 0; idx < count; idx++) { // Adhere to RFC 2045 and ignore characters // that are not part of the encoding table. unsigned char ch = data[idx]; if ( (ch > 47 && ch < 58) || (ch > 64 && ch < 91 ) || (ch > 96 && ch < 123)|| ch == '+' || ch == '/' || ch == '=') { out[outIdx++] = Base64DecMap[ch]; } else { len--; tail--; } } // kdDebug() << "Tail size = " << tail << ", Length size = " << len << endl; // 4-byte to 3-byte conversion len = (tail>(len/4)) ? tail-(len/4) : 0; unsigned int sidx = 0, didx = 0; if ( len > 1 ) { while (didx < len-2) { out[didx] = (((out[sidx] << 2) & 255) | ((out[sidx+1] >> 4) & 003)); out[didx+1] = (((out[sidx+1] << 4) & 255) | ((out[sidx+2] >> 2) & 017)); out[didx+2] = (((out[sidx+2] << 6) & 255) | (out[sidx+3] & 077)); sidx += 4; didx += 3; } } if (didx < len) out[didx] = (((out[sidx] << 2) & 255) | ((out[sidx+1] >> 4) & 003)); if (++didx < len ) out[didx] = (((out[sidx+1] << 4) & 255) | ((out[sidx+2] >> 2) & 017)); // Resize the output buffer if ( len == 0 || len < out.size() ) out.resize(len); return out; } bool OGlobal::isAppLnkFileName( const QString& str ) { if (str.length()==0||str.at(str.length()-1)==QDir::separator()) return false; return str.startsWith(MimeType::appsFolderName()+QDir::separator()); } /* ToDo: * This fun should check the document-path value for the mounted media * which has to be implemented later. this moment we just check for a * mounted media name. */ bool OGlobal::isDocumentFileName( const QString& file ) { if (file.length()==0||file.at(file.length()-1)==QDir::separator()) return false; if (file.startsWith(QPEApplication::documentDir()+QDir::separator())) return true; StorageInfo si; QList< FileSystem > fl = si.fileSystems(); FileSystem*fs; for (fs = fl.first();fs!=0;fs=fl.next()) { if (fs->isRemovable()&&file.startsWith(fs->name()+QDir::separator())) return true; } if (file.startsWith(homeDirPath())+"/Documents/") return true; return false; } QString OGlobal::tempDirPath() { static QString defstring="/tmp"; char * tmpp = 0; if ( (tmpp=getenv("TEMP"))) { return tmpp; } return defstring; } QString OGlobal::homeDirPath() { char * tmpp = getenv("HOME"); return (tmpp?tmpp:"/"); } bool OGlobal::weekStartsOnMonday() { OConfig*conf=OGlobal::qpe_config(); if (!conf)return false; conf->setGroup("Time"); return conf->readBoolEntry("MONDAY",true); } void OGlobal::setWeekStartsOnMonday( bool what) { OConfig*conf=OGlobal::qpe_config(); if (!conf)return; conf->setGroup("Time"); return conf->writeEntry("MONDAY",what); } bool OGlobal::useAMPM() { OConfig*conf=OGlobal::qpe_config(); if (!conf)return false; conf->setGroup("Time"); return conf->readBoolEntry("AMPM",false); } void OGlobal::setUseAMPM( bool what) { OConfig*conf=OGlobal::qpe_config(); if (!conf)return; conf->setGroup("Time"); return conf->writeEntry("AMPM",what); } OConfig* OGlobal::qpe_config() { if ( !OGlobal::_qpe_config ) { OGlobal::_qpe_config = new OConfig( "qpe" ); } return OGlobal::_qpe_config; } bool OGlobal::truncateFile( QFile &f, off_t size ) { /* or should we let enlarge Files? then remove this f.size()< part! - Alwin */ if (!f.exists()||f.size()<(unsigned)size) return false; bool closeit=false; if (!f.isOpen()) { closeit=true; f.open(IO_Raw | IO_ReadWrite | IO_Append); } if (!f.isOpen()) { return false; } int r = ftruncate(f.handle(),size); if (closeit) f.close(); return r==0; } diff --git a/libopie2/opiecore/oglobalsettings.cpp b/libopie2/opiecore/oglobalsettings.cpp index 66adbd0..192e55b 100644 --- a/libopie2/opiecore/oglobalsettings.cpp +++ b/libopie2/opiecore/oglobalsettings.cpp @@ -1,548 +1,545 @@ /* This file is part of the Opie Project Copyright (C) 2003 Michael Lauer <mickey@tm.informatik.uni-frankfurt.de> Inspired by the KDE globalsettings which are Copyright (C) 2000 David Faure <faure@kde.org> =. .=l. .>+-= _;:, .> :=|. 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; either version 2 of the License, ._= =} : or (at your option) any later version. .%`+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. */ /* OPIE */ #include <opie2/oglobalsettings.h> #include <opie2/oconfig.h> #include <opie2/oglobal.h> /* QT */ -#include <qobject.h> #include <qdir.h> -#include <qpixmap.h> -#include <qfontinfo.h> /* UNIX */ #include <stdlib.h> QString* OGlobalSettings::s_desktopPath = 0; QString* OGlobalSettings::s_autostartPath = 0; QString* OGlobalSettings::s_trashPath = 0; QString* OGlobalSettings::s_documentPath = 0; QFont *OGlobalSettings::_generalFont = 0; QFont *OGlobalSettings::_fixedFont = 0; QFont *OGlobalSettings::_toolBarFont = 0; QFont *OGlobalSettings::_menuFont = 0; QFont *OGlobalSettings::_windowTitleFont = 0; QFont *OGlobalSettings::_taskbarFont = 0; QColor *OGlobalSettings::OpieGray = 0; QColor *OGlobalSettings::OpieHighlight = 0; QColor *OGlobalSettings::OpieAlternate = 0; OGlobalSettings::OMouseSettings *OGlobalSettings::s_mouseSettings = 0; //FIXME: Add manipulators to the accessors int OGlobalSettings::dndEventDelay() { OConfig *c = OGlobal::config(); OConfigGroupSaver cgs( c, "General" ); return c->readNumEntry("DndDelay", 2); } bool OGlobalSettings::singleClick() { OConfig *c = OGlobal::config(); OConfigGroupSaver cgs( c, "OPIE" ); return c->readBoolEntry("SingleClick", OPIE_DEFAULT_SINGLECLICK); } bool OGlobalSettings::insertTearOffHandle() { OConfig *c = OGlobal::config(); OConfigGroupSaver cgs( c, "OPIE" ); return c->readBoolEntry("InsertTearOffHandle", OPIE_DEFAULT_INSERTTEAROFFHANDLES); } bool OGlobalSettings::changeCursorOverIcon() { OConfig *c = OGlobal::config(); OConfigGroupSaver cgs( c, "OPIE" ); return c->readBoolEntry("ChangeCursor", OPIE_DEFAULT_CHANGECURSOR); } bool OGlobalSettings::visualActivate() { OConfig *c = OGlobal::config(); OConfigGroupSaver cgs( c, "OPIE" ); return c->readBoolEntry("VisualActivate", OPIE_DEFAULT_VISUAL_ACTIVATE); } unsigned int OGlobalSettings::visualActivateSpeed() { OConfig *c = OGlobal::config(); OConfigGroupSaver cgs( c, "OPIE" ); return c->readNumEntry( "VisualActivateSpeed", OPIE_DEFAULT_VISUAL_ACTIVATE_SPEED ); } int OGlobalSettings::autoSelectDelay() { OConfig *c = OGlobal::config(); OConfigGroupSaver cgs( c, "OPIE" ); return c->readNumEntry("AutoSelectDelay", OPIE_DEFAULT_AUTOSELECTDELAY); } OGlobalSettings::Completion OGlobalSettings::completionMode() { int completion; OConfig *c = OGlobal::config(); OConfigGroupSaver cgs( c, "General" ); completion = c->readNumEntry("completionMode", -1); if ((completion < (int) CompletionNone) || (completion > (int) CompletionPopupAuto)) { completion = (int) CompletionPopup; // Default } return (Completion) completion; } bool OGlobalSettings::showContextMenusOnPress () { OConfig *c = OGlobal::config(); OConfigGroupSaver cgs (c, "ContextMenus"); return cgs.config()->readBoolEntry("ShowOnPress", true); } int OGlobalSettings::contextMenuKey () { OConfig *c = OGlobal::config(); OConfigGroupSaver cgs (c, "Shortcuts"); //OShortcut cut (cgs.config()->readEntry ("PopupMenuContext", "Menu")); //return cut.keyCodeQt(); return 0; // FIXME } OGlobalSettings::Debug OGlobalSettings::debugMode() { OConfig *c = OGlobal::config(); OConfigGroupSaver cgs( c, "General" ); int debug = c->readNumEntry( "debugMode", -1 ); if ( (debug < (int) DebugNone) || (debug > (int) DebugSocket) ) { debug = (int) DebugStdErr; // Default } return (Debug) debug; } QString OGlobalSettings::debugOutput() { OConfig *c = OGlobal::config(); OConfigGroupSaver cgs( c, "General" ); QString deflt = QString::null; switch( debugMode() ) { case DebugNone: break; // no additional information needed case DebugFiles: deflt = "/var/log/opiedebug.log"; break; // file to save output in case DebugMsgBox: break; // no additional information needed case DebugStdErr: break; // no additional information needed case DebugSysLog: break; // no additional information needed case DebugSocket: deflt = "127.0.0.1:8913"; break; // address to send packets to } return c->readEntry( "debugOutput"+ QString::number(debugMode()), deflt ); } QColor OGlobalSettings::toolBarHighlightColor() { initColors(); OConfig *c = OGlobal::config(); OConfigGroupSaver cgs( c, QString::fromLatin1("Toolbar style") ); return c->readColorEntry("HighlightColor", OpieHighlight); } QColor OGlobalSettings::inactiveTitleColor() { if (!OpieGray) OpieGray = new QColor(220, 220, 220); OConfig *c = OGlobal::config(); OConfigGroupSaver cgs( c, QString::fromLatin1("WM") ); return c->readColorEntry( "inactiveBackground", OpieGray ); } QColor OGlobalSettings::inactiveTextColor() { OConfig *c = OGlobal::config(); OConfigGroupSaver cgs( c, QString::fromLatin1("WM") ); return c->readColorEntry( "inactiveForeground", &Qt::darkGray ); } QColor OGlobalSettings::activeTitleColor() { initColors(); OConfig *c = OGlobal::config(); OConfigGroupSaver cgs( c, QString::fromLatin1("WM") ); return c->readColorEntry( "activeBackground", OpieHighlight); } QColor OGlobalSettings::activeTextColor() { OConfig *c = OGlobal::config(); OConfigGroupSaver cgs( c, QString::fromLatin1("WM") ); return c->readColorEntry( "activeForeground", &Qt::white ); } int OGlobalSettings::contrast() { OConfig *c = OGlobal::config(); OConfigGroupSaver cgs( c, QString::fromLatin1("OPIE") ); return c->readNumEntry( "contrast", 7 ); } // following functions should work in OPIE - how to sync with appearance changes? QColor OGlobalSettings::baseColor() { OConfig *c = OGlobal::config(); OConfigGroupSaver cgs( c, QString::fromLatin1("Appearance") ); return c->readColorEntry( "Base", &Qt::white ); } QColor OGlobalSettings::textColor() { OConfig *c = OGlobal::config(); OConfigGroupSaver cgs( c, QString::fromLatin1("Appearance") ); return c->readColorEntry( "Text", &Qt::black ); } QColor OGlobalSettings::highlightedTextColor() { OConfig *c = OGlobal::config(); OConfigGroupSaver cgs( c, QString::fromLatin1("Appearance") ); return c->readColorEntry( "HighlightedText", &Qt::white ); } QColor OGlobalSettings::highlightColor() { initColors(); OConfig *c = OGlobal::config(); OConfigGroupSaver cgs( c, QString::fromLatin1("Appearance") ); return c->readColorEntry( "Highlight", OpieHighlight ); } QColor OGlobalSettings::alternateBackgroundColor() { initColors(); OConfig *c = OGlobal::config(); OConfigGroupSaver cgs( c, QString::fromLatin1("Appearance") ); *OpieAlternate = calculateAlternateBackgroundColor( baseColor() ); return c->readColorEntry( "alternateBackground", OpieAlternate ); } QColor OGlobalSettings::calculateAlternateBackgroundColor(const QColor& base) { if (base == Qt::white) return QColor(238,246,255); else { int h, s, v; base.hsv( &h, &s, &v ); if (v > 128) return base.dark(106); else if (base != Qt::black) return base.light(110); return QColor(32,32,32); } } QColor OGlobalSettings::linkColor() { initColors(); OConfig *c = OGlobal::config(); OConfigGroupSaver cgs( c, QString::fromLatin1("Appearance") ); return c->readColorEntry( "linkColor", OpieGray ); } QColor OGlobalSettings::visitedLinkColor() { OConfig *c = OGlobal::config(); OConfigGroupSaver cgs( c, QString::fromLatin1("Appearance") ); return c->readColorEntry( "visitedLinkColor", &Qt::magenta ); } // FIXME: font stuff currently uses a different format in OPIE, so the // functions below are not yet applicable. The whole font stuff for OPIE // has to be revised anyway QFont OGlobalSettings::generalFont() { if (_generalFont) return *_generalFont; _generalFont = new QFont("helvetica", 10); _generalFont->setPixelSize(10); _generalFont->setStyleHint(QFont::SansSerif); OConfig *c = OGlobal::config(); OConfigGroupSaver cgs( c, QString::fromLatin1("Appearance") ); *_generalFont = c->readFontEntry("font", _generalFont); return *_generalFont; } QFont OGlobalSettings::fixedFont() { if (_fixedFont) return *_fixedFont; _fixedFont = new QFont("courier", 12); _fixedFont->setPixelSize(12); _fixedFont->setStyleHint(QFont::TypeWriter); OConfig *c = OGlobal::config(); OConfigGroupSaver cgs( c, QString::fromLatin1("General") ); *_fixedFont = c->readFontEntry("fixed", _fixedFont); return *_fixedFont; } QFont OGlobalSettings::toolBarFont() { if(_toolBarFont) return *_toolBarFont; _toolBarFont = new QFont("helvetica", 10); _toolBarFont->setPixelSize(10); _toolBarFont->setStyleHint(QFont::SansSerif); OConfig *c = OGlobal::config(); OConfigGroupSaver cgs( c, QString::fromLatin1("General") ); *_toolBarFont = c->readFontEntry("toolBarFont", _toolBarFont); return *_toolBarFont; } QFont OGlobalSettings::menuFont() { if(_menuFont) return *_menuFont; _menuFont = new QFont("helvetica", 12); _menuFont->setPixelSize(12); _menuFont->setStyleHint(QFont::SansSerif); OConfig *c = OGlobal::config(); OConfigGroupSaver cgs( c, QString::fromLatin1("General") ); *_menuFont = c->readFontEntry("menuFont", _menuFont); return *_menuFont; } QFont OGlobalSettings::windowTitleFont() { if(_windowTitleFont) return *_windowTitleFont; _windowTitleFont = new QFont("helvetica", 12, QFont::Bold); _windowTitleFont->setPixelSize(12); _windowTitleFont->setStyleHint(QFont::SansSerif); OConfig *c = OGlobal::config(); OConfigGroupSaver cgs( c, QString::fromLatin1("WM") ); *_windowTitleFont = c->readFontEntry("activeFont", _windowTitleFont); // inconsistency return *_windowTitleFont; } QFont OGlobalSettings::taskbarFont() { if(_taskbarFont) return *_taskbarFont; _taskbarFont = new QFont("helvetica", 8); _taskbarFont->setPixelSize(8); _taskbarFont->setStyleHint(QFont::SansSerif); OConfig *c = OGlobal::config(); OConfigGroupSaver cgs( c, QString::fromLatin1("General") ); *_taskbarFont = c->readFontEntry("taskbarFont", _taskbarFont); return *_taskbarFont; } // FIXME: the whole path stuff has to be revised for OPIE void OGlobalSettings::initStatic() // should be called initPaths(). Don't put anything else here. { if ( s_desktopPath != 0 ) return; s_desktopPath = new QString(); s_autostartPath = new QString(); s_trashPath = new QString(); s_documentPath = new QString(); OConfig *config = OGlobal::config(); //bool dollarExpansion = config->isDollarExpansion(); //config->setDollarExpansion(true); OConfigGroupSaver cgs( config, "Paths" ); // Desktop Path *s_desktopPath = QDir::homeDirPath() + "/" + "Desktop" + "/"; *s_desktopPath = config->readEntry( "Desktop", *s_desktopPath); if ( (*s_desktopPath)[0] != '/' ) s_desktopPath->prepend( QDir::homeDirPath() + "/" ); *s_desktopPath = QDir::cleanDirPath( *s_desktopPath ); if ( s_desktopPath->right(1) != "/") *s_desktopPath += "/"; // Trash Path *s_trashPath = *s_desktopPath + QObject::tr("Trash") + "/"; *s_trashPath = config->readEntry( "Trash" , *s_trashPath); if ( (*s_trashPath)[0] != '/' ) s_trashPath->prepend( QDir::homeDirPath() + "/" ); *s_trashPath = QDir::cleanDirPath( *s_trashPath ); if ( s_trashPath->right(1) != "/") *s_trashPath += "/"; // We need to save it in any case, in case the language changes later on, if ( !config->hasKey( "Trash" ) ) { //config->writePathEntry( "Trash", *s_trashPath, true, true ); config->writeEntry( "Trash", *s_trashPath ); //config->sync(); } /* // Autostart Path *s_autostartPath = OGlobal::dirs()->localkdedir() + "Autostart" + "/"; *s_autostartPath = config->readEntry( "Autostart" , *s_autostartPath); if ( (*s_autostartPath)[0] != '/' ) s_autostartPath->prepend( QDir::homeDirPath() + "/" ); *s_autostartPath = QDir::cleanDirPath( *s_autostartPath ); if ( s_autostartPath->right(1) != "/") *s_autostartPath += "/"; */ // Document Path *s_documentPath = QString::null; *s_documentPath = config->readEntry( "Documents" , *s_documentPath); if ( (*s_documentPath)[0] != '/' ) s_documentPath->prepend( QDir::homeDirPath() + "/" ); *s_documentPath = QDir::cleanDirPath( *s_documentPath ); if ( s_documentPath->right(1) != "/") *s_documentPath += "/"; //config->setDollarExpansion(dollarExpansion); // Make sure this app gets the notifications about those paths //if (kapp) //kapp->addKipcEventMask(KIPC::SettingsChanged); } void OGlobalSettings::initColors() { if ( !OpieHighlight ) OpieHighlight = new QColor( 156, 118, 32 ); if ( !OpieAlternate ) OpieAlternate = new QColor( 238, 246, 255 ); if ( !OpieGray ) OpieGray = new QColor( 220, 210, 215 ); } void OGlobalSettings::rereadFontSettings() { delete _generalFont; _generalFont = 0L; delete _fixedFont; _fixedFont = 0L; delete _menuFont; _menuFont = 0L; delete _toolBarFont; _toolBarFont = 0L; delete _windowTitleFont; _windowTitleFont = 0L; delete _taskbarFont; _taskbarFont = 0L; } void OGlobalSettings::rereadPathSettings() { qDebug( "OGlobalSettings::rereadPathSettings" ); delete s_autostartPath; s_autostartPath = 0L; delete s_trashPath; s_trashPath = 0L; delete s_desktopPath; s_desktopPath = 0L; delete s_documentPath; s_documentPath = 0L; } OGlobalSettings::OMouseSettings & OGlobalSettings::mouseSettings() { if ( ! s_mouseSettings ) { s_mouseSettings = new OMouseSettings; OMouseSettings & s = *s_mouseSettings; // for convenience OConfigGroupSaver cgs( OGlobal::config(), "Mouse" ); QString setting = OGlobal::config()->readEntry("MouseButtonMapping"); if (setting == "RightHanded") s.handed = OMouseSettings::RightHanded; else if (setting == "LeftHanded") s.handed = OMouseSettings::LeftHanded; else { // FIXME: Implement for Opie / Qt Embedded } } return *s_mouseSettings; } void OGlobalSettings::rereadMouseSettings() { delete s_mouseSettings; s_mouseSettings = 0L; } // FIXME: This won't be necessary, or will it? :-D bool OGlobalSettings::isMultiHead() { QCString multiHead = getenv("OPIE_MULTIHEAD"); if (!multiHead.isEmpty()) { return (multiHead.lower() == "true"); } return false; } diff --git a/libopie2/opiecore/oprocctrl.cpp b/libopie2/opiecore/oprocctrl.cpp index b3d57c8..0403526 100644 --- a/libopie2/opiecore/oprocctrl.cpp +++ b/libopie2/opiecore/oprocctrl.cpp @@ -1,284 +1,283 @@ /* This file is part of the KDE libraries Copyright (C) 1997 Christian Czezakte (e9025461@student.tuwien.ac.at) This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library 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. */ // // KPROCESSCONTROLLER -- A helper class for KProcess // // version 0.3.1, Jan, 8th 1997 // // (C) Christian Czezatke // e9025461@student.tuwien.ac.at // Ported by Holger Freyther // //#include <config.h> #include <sys/types.h> #include <sys/socket.h> #include <errno.h> #include <fcntl.h> #include <stdio.h> #include <string.h> #include <unistd.h> #include <assert.h> #include <qsocketnotifier.h> -#include "oprocess.h" #include "oprocctrl.h" OProcessController *OProcessController::theOProcessController = 0; struct sigaction OProcessController::oldChildHandlerData; bool OProcessController::handlerSet = false; OProcessController::OProcessController() { assert( theOProcessController == 0 ); if (0 > pipe(fd)) printf(strerror(errno)); notifier = new QSocketNotifier(fd[0], QSocketNotifier::Read); notifier->setEnabled(true); QObject::connect(notifier, SIGNAL(activated(int)), this, SLOT(slotDoHousekeeping(int))); connect( &delayedChildrenCleanupTimer, SIGNAL( timeout()), SLOT( delayedChildrenCleanup())); theOProcessController = this; setupHandlers(); } void OProcessController::setupHandlers() { if( handlerSet ) return; struct sigaction act; act.sa_handler=theSigCHLDHandler; sigemptyset(&(act.sa_mask)); sigaddset(&(act.sa_mask), SIGCHLD); // Make sure we don't block this signal. gdb tends to do that :-( sigprocmask(SIG_UNBLOCK, &(act.sa_mask), 0); act.sa_flags = SA_NOCLDSTOP; // CC: take care of SunOS which automatically restarts interrupted system // calls (and thus does not have SA_RESTART) #ifdef SA_RESTART act.sa_flags |= SA_RESTART; #endif sigaction( SIGCHLD, &act, &oldChildHandlerData ); act.sa_handler=SIG_IGN; sigemptyset(&(act.sa_mask)); sigaddset(&(act.sa_mask), SIGPIPE); act.sa_flags = 0; sigaction( SIGPIPE, &act, 0L); handlerSet = true; } void OProcessController::resetHandlers() { if( !handlerSet ) return; sigaction( SIGCHLD, &oldChildHandlerData, 0 ); // there should be no problem with SIGPIPE staying SIG_IGN handlerSet = false; } // block SIGCHLD handler, because it accesses processList void OProcessController::addOProcess( OProcess* p ) { sigset_t newset, oldset; sigemptyset( &newset ); sigaddset( &newset, SIGCHLD ); sigprocmask( SIG_BLOCK, &newset, &oldset ); processList.append( p ); sigprocmask( SIG_SETMASK, &oldset, 0 ); } void OProcessController::removeOProcess( OProcess* p ) { sigset_t newset, oldset; sigemptyset( &newset ); sigaddset( &newset, SIGCHLD ); sigprocmask( SIG_BLOCK, &newset, &oldset ); processList.remove( p ); sigprocmask( SIG_SETMASK, &oldset, 0 ); } //using a struct which contains both the pid and the status makes it easier to write //and read the data into the pipe //especially this solves a problem which appeared on my box where slotDoHouseKeeping() received //only 4 bytes (with some debug output around the write()'s it received all 8 bytes) //don't know why this happened, but when writing all 8 bytes at once it works here, aleXXX struct waitdata { pid_t pid; int status; }; void OProcessController::theSigCHLDHandler(int arg) { struct waitdata wd; // int status; // pid_t this_pid; int saved_errno; saved_errno = errno; // since waitpid and write change errno, we have to save it and restore it // (Richard Stevens, Advanced programming in the Unix Environment) bool found = false; if( theOProcessController != 0 ) { // iterating the list doesn't perform any system call for( QValueList<OProcess*>::ConstIterator it = theOProcessController->processList.begin(); it != theOProcessController->processList.end(); ++it ) { if( !(*it)->isRunning()) continue; wd.pid = waitpid( (*it)->pid(), &wd.status, WNOHANG ); if ( wd.pid > 0 ) { ::write(theOProcessController->fd[1], &wd, sizeof(wd)); found = true; } } } if( !found && oldChildHandlerData.sa_handler != SIG_IGN && oldChildHandlerData.sa_handler != SIG_DFL ) oldChildHandlerData.sa_handler( arg ); // call the old handler // handle the rest if( theOProcessController != 0 ) { static const struct waitdata dwd = { 0, 0 } ; // delayed waitpid() ::write(theOProcessController->fd[1], &dwd, sizeof(dwd)); } else { int dummy; while( waitpid( -1, &dummy, WNOHANG ) > 0 ) ; } errno = saved_errno; } void OProcessController::slotDoHousekeeping(int ) { unsigned int bytes_read = 0; unsigned int errcnt=0; // read pid and status from the pipe. struct waitdata wd; while ((bytes_read < sizeof(wd)) && (errcnt < 50)) { int r = ::read(fd[0], ((char *)&wd) + bytes_read, sizeof(wd) - bytes_read); if (r > 0) bytes_read += r; else if (r < 0) errcnt++; } if (errcnt >= 50) { fprintf(stderr, "Error: Max. error count for pipe read " "exceeded in OProcessController::slotDoHousekeeping\n"); return; // it makes no sense to continue here! } if (bytes_read != sizeof(wd)) { fprintf(stderr, "Error: Could not read info from signal handler %d <> %d!\n", bytes_read, sizeof(wd)); return; // it makes no sense to continue here! } if (wd.pid==0) { // special case, see delayedChildrenCleanup() delayedChildrenCleanupTimer.start( 1000, true ); return; } for( QValueList<OProcess*>::ConstIterator it = processList.begin(); it != processList.end(); ++it ) { OProcess* proc = *it; if (proc->pid() == wd.pid) { // process has exited, so do emit the respective events if (proc->run_mode == OProcess::Block) { // If the reads are done blocking then set the status in proc // but do nothing else because OProcess will perform the other // actions of processHasExited. proc->status = wd.status; proc->runs = false; } else { proc->processHasExited(wd.status); } return; } } } // this is needed e.g. for popen(), which calls waitpid() checking // for its forked child, if we did waitpid() directly in the SIGCHLD // handler, popen()'s waitpid() call would fail void OProcessController::delayedChildrenCleanup() { struct waitdata wd; while(( wd.pid = waitpid( -1, &wd.status, WNOHANG ) ) > 0 ) { for( QValueList<OProcess*>::ConstIterator it = processList.begin(); it != processList.end(); ++it ) { if( !(*it)->isRunning() || (*it)->pid() != wd.pid ) continue; // it's OProcess, handle it ::write(fd[1], &wd, sizeof(wd)); break; } } } OProcessController::~OProcessController() { assert( theOProcessController == this ); resetHandlers(); notifier->setEnabled(false); close(fd[0]); close(fd[1]); delete notifier; theOProcessController = 0; } //#include "kprocctrl.moc" diff --git a/libopie2/opiecore/oprocess.cpp b/libopie2/opiecore/oprocess.cpp index 83677aa..0a361a1 100644 --- a/libopie2/opiecore/oprocess.cpp +++ b/libopie2/opiecore/oprocess.cpp @@ -1,945 +1,943 @@ /* This file is part of the Opie Project Copyright (C) 2002-2004 Holger Freyther <zecke@handhelds.org> and The Opie Team <opie-devel@handhelds.org> =. Based on KProcess (C) 1997 Christian Czezatke (e9025461@student.tuwien.ac.at) .=l. .>+-= _;:, .> :=|. 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; either version 2 of the License, ._= =} : or (at your option) any later version. .%`+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 "oprocctrl.h" /* OPIE */ #include <opie2/oprocess.h> /* QT */ #include <qapplication.h> #include <qdir.h> -#include <qfile.h> #include <qmap.h> -#include <qregexp.h> #include <qsocketnotifier.h> #include <qtextstream.h> /* STD */ #include <errno.h> #include <fcntl.h> #include <pwd.h> #include <stdlib.h> #include <signal.h> #include <stdio.h> #include <string.h> #include <sys/time.h> #include <sys/types.h> #include <sys/stat.h> #include <sys/socket.h> #include <unistd.h> #ifdef HAVE_SYS_SELECT_H #include <sys/select.h> #endif #ifdef HAVE_INITGROUPS #include <grp.h> #endif class OProcessPrivate { public: OProcessPrivate() : useShell( false ) { } bool useShell; QMap<QString, QString> env; QString wd; QCString shell; }; OProcess::OProcess( QObject *parent, const char *name ) : QObject( parent, name ) { init ( ); } OProcess::OProcess( const QString &arg0, QObject *parent, const char *name ) : QObject( parent, name ) { init ( ); *this << arg0; } OProcess::OProcess( const QStringList &args, QObject *parent, const char *name ) : QObject( parent, name ) { init ( ); *this << args; } void OProcess::init ( ) { run_mode = NotifyOnExit; runs = false; pid_ = 0; status = 0; keepPrivs = false; innot = 0; outnot = 0; errnot = 0; communication = NoCommunication; input_data = 0; input_sent = 0; input_total = 0; d = 0; if ( 0 == OProcessController::theOProcessController ) { ( void ) new OProcessController(); CHECK_PTR( OProcessController::theOProcessController ); } OProcessController::theOProcessController->addOProcess( this ); out[ 0 ] = out[ 1 ] = -1; in[ 0 ] = in[ 1 ] = -1; err[ 0 ] = err[ 1 ] = -1; } void OProcess::setEnvironment( const QString &name, const QString &value ) { if ( !d ) d = new OProcessPrivate; d->env.insert( name, value ); } void OProcess::setWorkingDirectory( const QString &dir ) { if ( !d ) d = new OProcessPrivate; d->wd = dir; } void OProcess::setupEnvironment() { if ( d ) { QMap<QString, QString>::Iterator it; for ( it = d->env.begin(); it != d->env.end(); ++it ) setenv( QFile::encodeName( it.key() ).data(), QFile::encodeName( it.data() ).data(), 1 ); if ( !d->wd.isEmpty() ) chdir( QFile::encodeName( d->wd ).data() ); } } void OProcess::setRunPrivileged( bool keepPrivileges ) { keepPrivs = keepPrivileges; } bool OProcess::runPrivileged() const { return keepPrivs; } OProcess::~OProcess() { // destroying the OProcess instance sends a SIGKILL to the // child process (if it is running) after removing it from the // list of valid processes (if the process is not started as // "DontCare") OProcessController::theOProcessController->removeOProcess( this ); // this must happen before we kill the child // TODO: block the signal while removing the current process from the process list if ( runs && ( run_mode != DontCare ) ) kill( SIGKILL ); // Clean up open fd's and socket notifiers. closeStdin(); closeStdout(); closeStderr(); // TODO: restore SIGCHLD and SIGPIPE handler if this is the last OProcess delete d; } void OProcess::detach() { OProcessController::theOProcessController->removeOProcess( this ); runs = false; pid_ = 0; // Clean up open fd's and socket notifiers. closeStdin(); closeStdout(); closeStderr(); } bool OProcess::setExecutable( const QString& proc ) { if ( runs ) return false; if ( proc.isEmpty() ) return false; if ( !arguments.isEmpty() ) arguments.remove( arguments.begin() ); arguments.prepend( QFile::encodeName( proc ) ); return true; } OProcess &OProcess::operator<<( const QStringList& args ) { QStringList::ConstIterator it = args.begin(); for ( ; it != args.end() ; ++it ) arguments.append( QFile::encodeName( *it ) ); return *this; } OProcess &OProcess::operator<<( const QCString& arg ) { return operator<< ( arg.data() ); } OProcess &OProcess::operator<<( const char* arg ) { arguments.append( arg ); return *this; } OProcess &OProcess::operator<<( const QString& arg ) { arguments.append( QFile::encodeName( arg ) ); return *this; } void OProcess::clearArguments() { arguments.clear(); } bool OProcess::start( RunMode runmode, Communication comm ) { uint i; uint n = arguments.count(); char **arglist; if ( runs || ( 0 == n ) ) { return false; // cannot start a process that is already running // or if no executable has been assigned } run_mode = runmode; status = 0; QCString shellCmd; if ( d && d->useShell ) { if ( d->shell.isEmpty() ) { qWarning( "Could not find a valid shell" ); return false; } arglist = static_cast<char **>( malloc( ( 4 ) * sizeof( char * ) ) ); for ( i = 0; i < n; i++ ) { shellCmd += arguments[ i ]; shellCmd += " "; // CC: to separate the arguments } arglist[ 0 ] = d->shell.data(); arglist[ 1 ] = ( char * ) "-c"; arglist[ 2 ] = shellCmd.data(); arglist[ 3 ] = 0; } else { arglist = static_cast<char **>( malloc( ( n + 1 ) * sizeof( char * ) ) ); for ( i = 0; i < n; i++ ) arglist[ i ] = arguments[ i ].data(); arglist[ n ] = 0; } if ( !setupCommunication( comm ) ) qWarning( "Could not setup Communication!" ); // We do this in the parent because if we do it in the child process // gdb gets confused when the application runs from gdb. uid_t uid = getuid(); gid_t gid = getgid(); #ifdef HAVE_INITGROUPS struct passwd *pw = getpwuid( uid ); #endif int fd[ 2 ]; if ( 0 > pipe( fd ) ) { fd[ 0 ] = fd[ 1 ] = 0; // Pipe failed.. continue } runs = true; QApplication::flushX(); // WABA: Note that we use fork() and not vfork() because // vfork() has unclear semantics and is not standardized. pid_ = fork(); if ( 0 == pid_ ) { if ( fd[ 0 ] ) close( fd[ 0 ] ); if ( !runPrivileged() ) { setgid( gid ); #if defined( HAVE_INITGROUPS) if ( pw ) initgroups( pw->pw_name, pw->pw_gid ); #endif setuid( uid ); } // The child process if ( !commSetupDoneC() ) qWarning( "Could not finish comm setup in child!" ); setupEnvironment(); // Matthias if ( run_mode == DontCare ) setpgid( 0, 0 ); // restore default SIGPIPE handler (Harri) struct sigaction act; sigemptyset( &( act.sa_mask ) ); sigaddset( &( act.sa_mask ), SIGPIPE ); act.sa_handler = SIG_DFL; act.sa_flags = 0; sigaction( SIGPIPE, &act, 0L ); // We set the close on exec flag. // Closing of fd[1] indicates that the execvp succeeded! if ( fd[ 1 ] ) fcntl( fd[ 1 ], F_SETFD, FD_CLOEXEC ); execvp( arglist[ 0 ], arglist ); char resultByte = 1; if ( fd[ 1 ] ) write( fd[ 1 ], &resultByte, 1 ); _exit( -1 ); } else if ( -1 == pid_ ) { // forking failed runs = false; free( arglist ); return false; } else { if ( fd[ 1 ] ) close( fd[ 1 ] ); // the parent continues here // Discard any data for stdin that might still be there input_data = 0; // Check whether client could be started. if ( fd[ 0 ] ) for ( ;; ) { char resultByte; int n = ::read( fd[ 0 ], &resultByte, 1 ); if ( n == 1 ) { // Error runs = false; close( fd[ 0 ] ); free( arglist ); pid_ = 0; return false; } if ( n == -1 ) { if ( ( errno == ECHILD ) || ( errno == EINTR ) ) continue; // Ignore } break; // success } if ( fd[ 0 ] ) close( fd[ 0 ] ); if ( !commSetupDoneP() ) // finish communication socket setup for the parent qWarning( "Could not finish comm setup in parent!" ); if ( run_mode == Block ) { commClose(); // The SIGCHLD handler of the process controller will catch // the exit and set the status while ( runs ) { OProcessController::theOProcessController-> slotDoHousekeeping( 0 ); } runs = FALSE; emit processExited( this ); } } free( arglist ); return true; } bool OProcess::kill( int signo ) { bool rv = false; if ( 0 != pid_ ) rv = ( -1 != ::kill( pid_, signo ) ); // probably store errno somewhere... return rv; } bool OProcess::isRunning() const { return runs; } pid_t OProcess::pid() const { return pid_; } bool OProcess::normalExit() const { int _status = status; return ( pid_ != 0 ) && ( !runs ) && ( WIFEXITED( ( _status ) ) ); } int OProcess::exitStatus() const { int _status = status; return WEXITSTATUS( ( _status ) ); } bool OProcess::writeStdin( const char *buffer, int buflen ) { bool rv; // if there is still data pending, writing new data // to stdout is not allowed (since it could also confuse // kprocess... if ( 0 != input_data ) return false; if ( runs && ( communication & Stdin ) ) { input_data = buffer; input_sent = 0; input_total = buflen; slotSendData( 0 ); innot->setEnabled( true ); rv = true; } else rv = false; return rv; } void OProcess::flushStdin ( ) { if ( !input_data || ( input_sent == input_total ) ) return ; int d1, d2; do { d1 = input_total - input_sent; slotSendData ( 0 ); d2 = input_total - input_sent; } while ( d2 <= d1 ); } void OProcess::suspend() { if ( ( communication & Stdout ) && outnot ) outnot->setEnabled( false ); } void OProcess::resume() { if ( ( communication & Stdout ) && outnot ) outnot->setEnabled( true ); } bool OProcess::closeStdin() { bool rv; if ( communication & Stdin ) { communication = ( Communication ) ( communication & ~Stdin ); delete innot; innot = 0; close( in[ 1 ] ); rv = true; } else rv = false; return rv; } bool OProcess::closeStdout() { bool rv; if ( communication & Stdout ) { communication = ( Communication ) ( communication & ~Stdout ); delete outnot; outnot = 0; close( out[ 0 ] ); rv = true; } else rv = false; return rv; } bool OProcess::closeStderr() { bool rv; if ( communication & Stderr ) { communication = static_cast<Communication>( communication & ~Stderr ); delete errnot; errnot = 0; close( err[ 0 ] ); rv = true; } else rv = false; return rv; } void OProcess::slotChildOutput( int fdno ) { if ( !childOutput( fdno ) ) closeStdout(); } void OProcess::slotChildError( int fdno ) { if ( !childError( fdno ) ) closeStderr(); } void OProcess::slotSendData( int ) { if ( input_sent == input_total ) { innot->setEnabled( false ); input_data = 0; emit wroteStdin( this ); } else input_sent += ::write( in[ 1 ], input_data + input_sent, input_total - input_sent ); } void OProcess::processHasExited( int state ) { if ( runs ) { runs = false; status = state; commClose(); // cleanup communication sockets // also emit a signal if the process was run Blocking if ( DontCare != run_mode ) { emit processExited( this ); } } } int OProcess::childOutput( int fdno ) { if ( communication & NoRead ) { int len = -1; emit receivedStdout( fdno, len ); errno = 0; // Make sure errno doesn't read "EAGAIN" return len; } else { char buffer[ 1024 ]; int len; len = ::read( fdno, buffer, 1024 ); if ( 0 < len ) { emit receivedStdout( this, buffer, len ); } return len; } } int OProcess::childError( int fdno ) { char buffer[ 1024 ]; int len; len = ::read( fdno, buffer, 1024 ); if ( 0 < len ) emit receivedStderr( this, buffer, len ); return len; } int OProcess::setupCommunication( Communication comm ) { int ok; communication = comm; ok = 1; if ( comm & Stdin ) ok &= socketpair( AF_UNIX, SOCK_STREAM, 0, in ) >= 0; if ( comm & Stdout ) ok &= socketpair( AF_UNIX, SOCK_STREAM, 0, out ) >= 0; if ( comm & Stderr ) ok &= socketpair( AF_UNIX, SOCK_STREAM, 0, err ) >= 0; return ok; } int OProcess::commSetupDoneP() { int ok = 1; if ( communication != NoCommunication ) { if ( communication & Stdin ) close( in[ 0 ] ); if ( communication & Stdout ) close( out[ 1 ] ); if ( communication & Stderr ) close( err[ 1 ] ); // Don't create socket notifiers and set the sockets non-blocking if // blocking is requested. if ( run_mode == Block ) return ok; if ( communication & Stdin ) { // ok &= (-1 != fcntl(in[1], F_SETFL, O_NONBLOCK)); innot = new QSocketNotifier( in[ 1 ], QSocketNotifier::Write, this ); CHECK_PTR( innot ); innot->setEnabled( false ); // will be enabled when data has to be sent QObject::connect( innot, SIGNAL( activated( int ) ), this, SLOT( slotSendData( int ) ) ); } if ( communication & Stdout ) { // ok &= (-1 != fcntl(out[0], F_SETFL, O_NONBLOCK)); outnot = new QSocketNotifier( out[ 0 ], QSocketNotifier::Read, this ); CHECK_PTR( outnot ); QObject::connect( outnot, SIGNAL( activated( int ) ), this, SLOT( slotChildOutput( int ) ) ); if ( communication & NoRead ) suspend(); } if ( communication & Stderr ) { // ok &= (-1 != fcntl(err[0], F_SETFL, O_NONBLOCK)); errnot = new QSocketNotifier( err[ 0 ], QSocketNotifier::Read, this ); CHECK_PTR( errnot ); QObject::connect( errnot, SIGNAL( activated( int ) ), this, SLOT( slotChildError( int ) ) ); } } return ok; } int OProcess::commSetupDoneC() { int ok = 1; struct linger so; memset( &so, 0, sizeof( so ) ); if ( communication & Stdin ) close( in[ 1 ] ); if ( communication & Stdout ) close( out[ 0 ] ); if ( communication & Stderr ) close( err[ 0 ] ); if ( communication & Stdin ) ok &= dup2( in[ 0 ], STDIN_FILENO ) != -1; else { int null_fd = open( "/dev/null", O_RDONLY ); ok &= dup2( null_fd, STDIN_FILENO ) != -1; close( null_fd ); } if ( communication & Stdout ) { ok &= dup2( out[ 1 ], STDOUT_FILENO ) != -1; ok &= !setsockopt( out[ 1 ], SOL_SOCKET, SO_LINGER, ( char* ) & so, sizeof( so ) ); } else { int null_fd = open( "/dev/null", O_WRONLY ); ok &= dup2( null_fd, STDOUT_FILENO ) != -1; close( null_fd ); } if ( communication & Stderr ) { ok &= dup2( err[ 1 ], STDERR_FILENO ) != -1; ok &= !setsockopt( err[ 1 ], SOL_SOCKET, SO_LINGER, reinterpret_cast<char *>( &so ), sizeof( so ) ); } else { int null_fd = open( "/dev/null", O_WRONLY ); ok &= dup2( null_fd, STDERR_FILENO ) != -1; close( null_fd ); } return ok; } void OProcess::commClose() { if ( NoCommunication != communication ) { bool b_in = ( communication & Stdin ); bool b_out = ( communication & Stdout ); bool b_err = ( communication & Stderr ); if ( b_in ) delete innot; if ( b_out || b_err ) { // If both channels are being read we need to make sure that one socket buffer // doesn't fill up whilst we are waiting for data on the other (causing a deadlock). // Hence we need to use select. // Once one or other of the channels has reached EOF (or given an error) go back // to the usual mechanism. int fds_ready = 1; fd_set rfds; int max_fd = 0; if ( b_out ) { fcntl( out[ 0 ], F_SETFL, O_NONBLOCK ); if ( out[ 0 ] > max_fd ) max_fd = out[ 0 ]; delete outnot; outnot = 0; } if ( b_err ) { fcntl( err[ 0 ], F_SETFL, O_NONBLOCK ); if ( err[ 0 ] > max_fd ) max_fd = err[ 0 ]; delete errnot; errnot = 0; } while ( b_out || b_err ) { // * If the process is still running we block until we // receive data. (p_timeout = 0, no timeout) // * If the process has already exited, we only check // the available data, we don't wait for more. // (p_timeout = &timeout, timeout immediately) struct timeval timeout; timeout.tv_sec = 0; timeout.tv_usec = 0; struct timeval *p_timeout = runs ? 0 : &timeout; FD_ZERO( &rfds ); if ( b_out ) FD_SET( out[ 0 ], &rfds ); if ( b_err ) FD_SET( err[ 0 ], &rfds ); fds_ready = select( max_fd + 1, &rfds, 0, 0, p_timeout ); if ( fds_ready <= 0 ) break; if ( b_out && FD_ISSET( out[ 0 ], &rfds ) ) { int ret = 1; while ( ret > 0 ) ret = childOutput( out[ 0 ] ); if ( ( ret == -1 && errno != EAGAIN ) || ret == 0 ) b_out = false; } if ( b_err && FD_ISSET( err[ 0 ], &rfds ) ) { int ret = 1; while ( ret > 0 ) ret = childError( err[ 0 ] ); if ( ( ret == -1 && errno != EAGAIN ) || ret == 0 ) b_err = false; } } } if ( b_in ) { communication = ( Communication ) ( communication & ~Stdin ); close( in[ 1 ] ); } if ( b_out ) { communication = ( Communication ) ( communication & ~Stdout ); close( out[ 0 ] ); } if ( b_err ) { communication = ( Communication ) ( communication & ~Stderr ); close( err[ 0 ] ); } } } void OProcess::setUseShell( bool useShell, const char *shell ) { if ( !d ) d = new OProcessPrivate; d->useShell = useShell; d->shell = shell; if ( d->shell.isEmpty() ) d->shell = searchShell(); } QString OProcess::quote( const QString &arg ) { QString res = arg; res.replace( QRegExp( QString::fromLatin1( "\'" ) ), QString::fromLatin1( "'\"'\"'" ) ); res.prepend( '\'' ); res.append( '\'' ); return res; } QCString OProcess::searchShell() { QCString tmpShell = QCString( getenv( "SHELL" ) ).stripWhiteSpace(); if ( !isExecutable( tmpShell ) ) { tmpShell = "/bin/sh"; } return tmpShell; } bool OProcess::isExecutable( const QCString &filename ) { struct stat fileinfo; if ( filename.isEmpty() ) return false; // CC: we've got a valid filename, now let's see whether we can execute that file if ( -1 == stat( filename.data(), &fileinfo ) ) return false; // CC: return false if the file does not exist // CC: anyway, we cannot execute directories, block/character devices, fifos or sockets if ( ( S_ISDIR( fileinfo.st_mode ) ) || ( S_ISCHR( fileinfo.st_mode ) ) || ( S_ISBLK( fileinfo.st_mode ) ) || #ifdef S_ISSOCK // CC: SYSVR4 systems don't have that macro ( S_ISSOCK( fileinfo.st_mode ) ) || #endif ( S_ISFIFO( fileinfo.st_mode ) ) || ( S_ISDIR( fileinfo.st_mode ) ) ) { return false; } // CC: now check for permission to execute the file if ( access( filename.data(), X_OK ) != 0 ) return false; // CC: we've passed all the tests... return true; } int OProcess::processPID( const QString& process ) { QString line; QDir d = QDir( "/proc" ); QStringList dirs = d.entryList( QDir::Dirs ); QStringList::Iterator it; for ( it = dirs.begin(); it != dirs.end(); ++it ) { //qDebug( "next entry: %s", (const char*) *it ); QFile file( "/proc/"+*it+"/cmdline" ); file.open( IO_ReadOnly ); if ( !file.isOpen() ) continue; QTextStream t( &file ); line = t.readLine(); //qDebug( "cmdline = %s", (const char*) line ); if ( line.contains( process ) ) break; //FIXME: That may find also other process, if the name is not long enough ;) } if ( line.contains( process ) ) { //qDebug( "found process id #%d", (*it).toInt() ); return (*it).toInt(); } else { //qDebug( "process '%s' not found", (const char*) process ); return 0; } } diff --git a/libopie2/opiedb/osqlbackendmanager.cpp b/libopie2/opiedb/osqlbackendmanager.cpp index 0f261b9..95ed77b 100644 --- a/libopie2/opiedb/osqlbackendmanager.cpp +++ b/libopie2/opiedb/osqlbackendmanager.cpp @@ -1,99 +1,98 @@ #include <qdir.h> -#include <qfile.h> #include <qmap.h> #include "osqlbackendmanager.h" namespace { class Config { typedef QMap<QString, QString> List; public: Config( const QString& fileName ); /** * Quite simple layout in nature * BeginFile * Key = Value */ bool load(); QString value( const QString& key ); private: List m_list; QString m_fileName; }; Config::Config( const QString& fileName ) : m_fileName( fileName ) { } bool Config::load() { if (!QFile::exists( m_fileName ) ) return false; QFile file( m_fileName ); if (!file.open(IO_ReadOnly ) ) return false; QStringList list = QStringList::split( '\n', file.readAll() ); QStringList::Iterator it; QString line; for (it = list.begin(); it != list.end(); ++it ) { line = (*it).stripWhiteSpace(); qWarning("Anonymous::Config:" + line ); QStringList test = QStringList::split(' ', line ); m_list.insert( test[0], test[2] ); } return true; } QString Config::value( const QString& key ) { return m_list[key]; } }; OSQLBackEndManager::OSQLBackEndManager( const QStringList& path ) :m_path( path ) { } OSQLBackEndManager::~OSQLBackEndManager() { } /** * scan dirs */ OSQLBackEnd::ValueList OSQLBackEndManager::scan() { OSQLBackEnd::ValueList list; if (!m_path.isEmpty() ) { QStringList::Iterator it; for ( it = m_path.begin(); it != m_path.end(); ++it ) { list += scanDir( (*it) ); } } return list; } /** * scan a specified dir for *.osql */ OSQLBackEnd::ValueList OSQLBackEndManager::scanDir( const QString& dirName ) { OSQLBackEnd::ValueList list; QDir dir( dirName ); if (dir.exists() ) { QStringList files = dir.entryList( "*.osql" ); QStringList::Iterator it; for ( it = files.begin(); it != files.end(); ++it ) { list.append( file2backend( (*it) ) ); } } return list; } /** * read a config file and convert it to a OSQLBackEnd */ OSQLBackEnd OSQLBackEndManager::file2backend( const QString& file ) { OSQLBackEnd end; qWarning("fileName: " + file ); Config cfg( file ); if (cfg.load() ) { end.setName( cfg.value( "Name") ); end.setVendor( cfg.value("Vendor") ); end.setLicense( cfg.value("License") ); end.setLibrary( cfg.value("Library").local8Bit() ); end.setDefault( cfg.value("Default").toInt() ); end.setPreference( cfg.value("Preference").toInt() ); } return end; } diff --git a/libopie2/opiedb/osqlitedriver.cpp b/libopie2/opiedb/osqlitedriver.cpp index b857534..6141504 100644 --- a/libopie2/opiedb/osqlitedriver.cpp +++ b/libopie2/opiedb/osqlitedriver.cpp @@ -1,189 +1,188 @@ /* This file is part of the Opie Project =. .=l. .>+-= _;:, .> :=|. 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; either version 2 of the License, ._= =} : or (at your option) any later version. .%`+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 "osqlresult.h" #include "osqlquery.h" #include "osqlitedriver.h" #include <opie2/odebug.h> #include <stdlib.h> // fromLocal8Bit() does not work as expected. Thus it // is replaced by fromLatin1() (eilers) #define __BUGGY_LOCAL8BIT_ namespace { struct Query { OSQLError::ValueList errors; OSQLResultItem::ValueList items; OSQLiteDriver *driver; }; } OSQLiteDriver::OSQLiteDriver( QLibrary *lib ) : OSQLDriver( lib ) { m_sqlite = 0l; } OSQLiteDriver::~OSQLiteDriver() { close(); } QString OSQLiteDriver::id()const { return QString::fromLatin1("SQLite"); } void OSQLiteDriver::setUserName( const QString& ) {} void OSQLiteDriver::setPassword( const QString& ) {} void OSQLiteDriver::setUrl( const QString& url ) { m_url = url; } void OSQLiteDriver::setOptions( const QStringList& ) { } /* * try to open a db specified via setUrl * and options */ bool OSQLiteDriver::open() { char *error; odebug << "OSQLiteDriver::open: about to open" << oendl; m_sqlite = sqlite_open(m_url.local8Bit(), 0, &error ); /* failed to open */ if (m_sqlite == 0l ) { // FIXME set the last error owarn << "OSQLiteDriver::open: " << error << oendl; free( error ); return false; } return true; } /* close the db * sqlite closes them without * telling failure or success */ bool OSQLiteDriver::close() { if (m_sqlite ) sqlite_close( m_sqlite ), m_sqlite=0l; return true; } /* Query */ OSQLResult OSQLiteDriver::query( OSQLQuery* qu) { if ( !m_sqlite ) { // FIXME set error code OSQLResult result( OSQLResult::Failure ); return result; } Query query; query.driver = this; char *err; /* SQLITE_OK 0 if return code > 0 == failure */ if ( sqlite_exec(m_sqlite, qu->query(),&call_back, &query, &err) > 0 ) { owarn << "OSQLiteDriver::query: Error while executing" << oendl; free(err ); // FixMe Errors } OSQLResult result(OSQLResult::Success, query.items, query.errors ); return result; } OSQLTable::ValueList OSQLiteDriver::tables() const { } OSQLError OSQLiteDriver::lastError() { OSQLError error; return error; }; /* handle a callback add the row to the global * OSQLResultItem */ int OSQLiteDriver::handleCallBack( int, char**, char** ) { return 0; } /* callback_handler add the values to the list*/ int OSQLiteDriver::call_back( void* voi, int argc, char** argv, char** columns) { Query* qu = (Query*)voi; //copy them over to a OSQLResultItem QMap<QString, QString> tableString; QMap<int, QString> tableInt; for (int i = 0; i < argc; i++ ) { #ifdef __BUGGY_LOCAL8BIT_ tableInt.insert( i, QString::fromLatin1( argv[i] ) ); tableString.insert( QString::fromLatin1( columns[i] ), QString::fromLatin1( argv[i] ) ); #else tableInt.insert( i, QString::fromLocal8Bit( argv[i] ) ); tableString.insert( QString::fromLocal8Bit( columns[i] ), QString::fromLocal8Bit( argv[i] ) ); #endif } OSQLResultItem item( tableString, tableInt ); qu->items.append( item ); return ((Query*)voi)->driver->handleCallBack( argc, argv, columns ); } diff --git a/libopie2/opiedb/osqlmanager.cpp b/libopie2/opiedb/osqlmanager.cpp index b0fea04..766ebe1 100644 --- a/libopie2/opiedb/osqlmanager.cpp +++ b/libopie2/opiedb/osqlmanager.cpp @@ -1,83 +1,81 @@ #include <stdlib.h> -#include "osqlbackend.h" -#include "osqldriver.h" #include "osqlmanager.h" #include "osqlbackendmanager.h" #include "osqlitedriver.h" OSQLManager::OSQLManager() { } OSQLBackEnd::ValueList OSQLManager::queryBackEnd() { m_list.clear(); QString opie = QString::fromLatin1( getenv("OPIEDIR") ); QString qpe = QString::fromLatin1( getenv("QPEDIR") ); if ( !m_path.contains(opie) && !opie.isEmpty() ) m_path << opie; if ( !m_path.contains(qpe) && !qpe.isEmpty() ) m_path << qpe; OSQLBackEndManager mng( m_path ); m_list = mng.scan(); m_list += builtIn(); return m_list; } /* * loading dso's is currently not enabled due problems with QLibrary * beeing in libqpe and not libqte */ OSQLDriver* OSQLManager::load( const QString& name ) { OSQLDriver* driver = 0l; if ( name == "SQLite" ) { driver = new OSQLiteDriver(); } return driver; } /* * same as above */ OSQLDriver* OSQLManager::load( const OSQLBackEnd& end) { OSQLDriver *driver = 0l; if ( end.library() == "builtin" && end.name() == "SQLite" ) driver = new OSQLiteDriver(); return driver; } /* * let's find the a default with the highes preference */ OSQLDriver* OSQLManager::standard() { OSQLDriver* driver =0l; if ( m_list.isEmpty() ) queryBackEnd(); OSQLBackEnd::ValueList::Iterator it; OSQLBackEnd back; for ( it = m_list.begin(); it != m_list.end(); ++it ) { if ( (*it).isDefault() && back.preference() < (*it).preference() ) { back = (*it); } } driver = load( back ); return driver; } void OSQLManager::registerPath( const QString& path ) { m_path << path; } bool OSQLManager::unregisterPath( const QString& path ) { m_path.remove( path ); return true; } OSQLBackEnd::ValueList OSQLManager::builtIn()const { OSQLBackEnd::ValueList list; // create the OSQLiteBackend OSQLBackEnd back("SQLite","Opie e.V.","GPL", "builtin" ); back.setDefault( true ); back.setPreference( 50 ); list.append( back ); return list; } diff --git a/libopie2/opiedb/osqlresult.cpp b/libopie2/opiedb/osqlresult.cpp index 490fb45..42da356 100644 --- a/libopie2/opiedb/osqlresult.cpp +++ b/libopie2/opiedb/osqlresult.cpp @@ -1,127 +1,126 @@ -#include "osqlquery.h" #include "osqlresult.h" OSQLResultItem::OSQLResultItem( const TableString& string, const TableInt& Int) : m_string( string ), m_int( Int ) { } OSQLResultItem::~OSQLResultItem() { } OSQLResultItem::OSQLResultItem( const OSQLResultItem& item) { *this = item; } OSQLResultItem &OSQLResultItem::operator=( const OSQLResultItem& other) { m_string = other.m_string; m_int = other.m_int; return *this; } OSQLResultItem::TableString OSQLResultItem::tableString()const{ return m_string; } OSQLResultItem::TableInt OSQLResultItem::tableInt()const { return m_int; } QString OSQLResultItem::data( const QString& columnName, bool *ok ) { TableString::Iterator it = m_string.find( columnName ); /* if found */ if ( it != m_string.end() ) { if ( ok ) *ok = true; return it.data(); }else{ if ( ok ) *ok = false; return QString::null; } } QString OSQLResultItem::data( int column, bool *ok ) { TableInt::Iterator it = m_int.find( column ); /* if found */ if ( it != m_int.end() ) { if ( ok ) *ok = true; return it.data(); }else{ if ( ok ) *ok = false; return QString::null; } } /* * DateFormat is 'YYYY-MM-DD' */ QDate OSQLResultItem::dataToDate( const QString& column, bool *ok ) { QDate date = QDate::currentDate(); QString str = data( column, ok ); if (!str.isEmpty() ) { ;// convert } return date; } QDate OSQLResultItem::dataToDate( int column, bool *ok ) { QDate date = QDate::currentDate(); QString str = data( column, ok ); if (!str.isEmpty() ) { ;// convert } return date; } QDateTime OSQLResultItem::dataToDateTime( const QString& column, bool *ok ) { QDateTime time = QDateTime::currentDateTime(); return time; } QDateTime OSQLResultItem::dataToDateTime( int column, bool *ok ) { QDateTime time = QDateTime::currentDateTime(); return time; } OSQLResult::OSQLResult( enum State state, const OSQLResultItem::ValueList& list, const OSQLError::ValueList& error ) : m_state( state ), m_list( list ), m_error( error ) { } OSQLResult::~OSQLResult() { } OSQLResult::State OSQLResult::state()const { return m_state; } void OSQLResult::setState( OSQLResult::State state ) { m_state = state; } OSQLError::ValueList OSQLResult::errors()const { return m_error; } void OSQLResult::setErrors( const OSQLError::ValueList& err ) { m_error = err; } OSQLResultItem::ValueList OSQLResult::results()const { return m_list; } void OSQLResult::setResults( const OSQLResultItem::ValueList& result ) { m_list = result; } OSQLResultItem OSQLResult::first() { it = m_list.begin(); return (*it); } OSQLResultItem OSQLResult::next(){ ++it; return (*it); } bool OSQLResult::atEnd(){ if ( it == m_list.end() ) return true; return false; } OSQLResultItem::ValueList::ConstIterator OSQLResult::iterator()const { OSQLResultItem::ValueList::ConstIterator it; it = m_list.begin(); return it; } diff --git a/libopie2/opiemm/osoundsystem.cpp b/libopie2/opiemm/osoundsystem.cpp index ca63389..51e088c 100644 --- a/libopie2/opiemm/osoundsystem.cpp +++ b/libopie2/opiemm/osoundsystem.cpp @@ -1,314 +1,313 @@ /* This file is part of the Opie Project (C) 2003 Michael 'Mickey' Lauer <mickey@tm.informatik.uni-frankfurt.de> =. .=l. .>+-= _;:, .> :=|. 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; either version 2 of the License, ._= =} : or (at your option) any later version. .%`+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 <opie2/osoundsystem.h> #include <opie2/odebug.h> #include <errno.h> #include <fcntl.h> #include <string.h> #include <sys/ioctl.h> #include <sys/types.h> #include <sys/soundcard.h> #include <sys/stat.h> -#include <qstringlist.h> /*====================================================================================== * OSoundSystem *======================================================================================*/ OSoundSystem* OSoundSystem::_instance = 0; OSoundSystem::OSoundSystem() { odebug << "OSoundSystem::OSoundSystem()" << oendl; synchronize(); } void OSoundSystem::synchronize() { // gather available interfaces by inspecting /dev //FIXME: we could use SIOCGIFCONF here, but we aren't interested in virtual (e.g. eth0:0) devices //FIXME: Use SIOCGIFCONF anway, because we can disable listing of aliased devices _interfaces.clear(); _interfaces.insert( "soundcard", new OSoundCard( this, "soundcard" ) ); /* QString str; QFile f( "/dev/sound" ); bool hasFile = f.open( IO_ReadOnly ); if ( !hasFile ) { odebug << "OSoundSystem: /dev/sound not existing. No sound devices available" << oendl; return; } QTextStream s( &f ); s.readLine(); s.readLine(); while ( !s.atEnd() ) { s >> str; str.truncate( str.find( ':' ) ); qDebug( "OSoundSystem: found interface '%s'", (const char*) str ); OAudioInterface* iface; iface = new OAudioInterface( this, (const char*) str ); _interfaces.insert( str, iface ); s.readLine(); } */ } int OSoundSystem::count() const { return _interfaces.count(); } OSoundCard* OSoundSystem::card( const QString& iface ) const { return _interfaces[iface]; } OSoundSystem* OSoundSystem::instance() { if ( !_instance ) _instance = new OSoundSystem(); return _instance; } OSoundSystem::CardIterator OSoundSystem::iterator() const { return OSoundSystem::CardIterator( _interfaces ); } /*====================================================================================== * OSoundCard *======================================================================================*/ OSoundCard::OSoundCard( QObject* parent, const char* name ) :QObject( parent, name ), _audio( 0 ), _mixer( 0 ) { odebug << "OSoundCard::OSoundCard()" << oendl; init(); } OSoundCard::~OSoundCard() { } void OSoundCard::init() { _audio = new OAudioInterface( this, "/dev/dsp" ); _mixer = new OMixerInterface( this, "/dev/mixer" ); } /*====================================================================================== * OAudioInterface *======================================================================================*/ OAudioInterface::OAudioInterface( QObject* parent, const char* name ) :QObject( parent, name ) { odebug << "OAudioInterface::OAudioInterface()" << oendl; init(); } OAudioInterface::~OAudioInterface() { } void OAudioInterface::init() { } /*====================================================================================== * OMixerInterface *======================================================================================*/ OMixerInterface::OMixerInterface( QObject* parent, const char* name ) :QObject( parent, name ) { odebug << "OMixerInterface::OMixerInterface()" << oendl; init(); } OMixerInterface::~OMixerInterface() { } void OMixerInterface::init() { // open the device _fd = ::open( name(), O_RDWR ); if ( _fd == -1 ) { owarn << "OMixerInterface::init(): Can't open mixer." << oendl; return; } // construct the device capabilities int devmask = 0; if ( ioctl( _fd, SOUND_MIXER_READ_DEVMASK, &devmask ) != -1 ) { if ( devmask & ( 1 << SOUND_MIXER_VOLUME ) ) _channels.insert( "PlayVolume", SOUND_MIXER_VOLUME ); if ( devmask & ( 1 << SOUND_MIXER_BASS ) ) _channels.insert( "PlayBass", SOUND_MIXER_BASS ); if ( devmask & ( 1 << SOUND_MIXER_TREBLE ) ) _channels.insert( "PlayTreble", SOUND_MIXER_TREBLE ); if ( devmask & ( 1 << SOUND_MIXER_SYNTH ) ) _channels.insert( "PlaySynth", SOUND_MIXER_SYNTH ); if ( devmask & ( 1 << SOUND_MIXER_PCM ) ) _channels.insert( "PlayPCM", SOUND_MIXER_PCM ); if ( devmask & ( 1 << SOUND_MIXER_SPEAKER ) ) _channels.insert( "PlaySpeaker", SOUND_MIXER_SPEAKER ); if ( devmask & ( 1 << SOUND_MIXER_LINE ) ) _channels.insert( "PlayLine", SOUND_MIXER_LINE ); if ( devmask & ( 1 << SOUND_MIXER_MIC ) ) _channels.insert( "PlayMic", SOUND_MIXER_MIC ); if ( devmask & ( 1 << SOUND_MIXER_CD ) ) _channels.insert( "PlayCD", SOUND_MIXER_CD ); if ( devmask & ( 1 << SOUND_MIXER_IMIX ) ) _channels.insert( "PlayInputMix", SOUND_MIXER_IMIX ); if ( devmask & ( 1 << SOUND_MIXER_ALTPCM ) ) _channels.insert( "PlayAltPCM", SOUND_MIXER_ALTPCM ); if ( devmask & ( 1 << SOUND_MIXER_RECLEV ) ) _channels.insert( "PlayRecord", SOUND_MIXER_RECLEV ); if ( devmask & ( 1 << SOUND_MIXER_IGAIN ) ) _channels.insert( "PlayInputGain", SOUND_MIXER_IGAIN ); if ( devmask & ( 1 << SOUND_MIXER_OGAIN ) ) _channels.insert( "PlayOutputGain", SOUND_MIXER_OGAIN ); //odebug << "devmask available and constructed." << oendl; } devmask = 0; if ( ioctl( _fd, SOUND_MIXER_READ_RECMASK, &devmask ) != -1 ) { if ( devmask & ( 1 << SOUND_MIXER_VOLUME ) ) _channels.insert( "RecVolume", SOUND_MIXER_VOLUME ); if ( devmask & ( 1 << SOUND_MIXER_BASS ) ) _channels.insert( "RecBass", SOUND_MIXER_BASS ); if ( devmask & ( 1 << SOUND_MIXER_TREBLE ) ) _channels.insert( "RecTreble", SOUND_MIXER_TREBLE ); if ( devmask & ( 1 << SOUND_MIXER_SYNTH ) ) _channels.insert( "RecSynth", SOUND_MIXER_SYNTH ); if ( devmask & ( 1 << SOUND_MIXER_PCM ) ) _channels.insert( "RecPCM", SOUND_MIXER_PCM ); if ( devmask & ( 1 << SOUND_MIXER_SPEAKER ) ) _channels.insert( "RecSpeaker", SOUND_MIXER_SPEAKER ); if ( devmask & ( 1 << SOUND_MIXER_LINE ) ) _channels.insert( "RecLine", SOUND_MIXER_LINE ); if ( devmask & ( 1 << SOUND_MIXER_MIC ) ) _channels.insert( "RecMic", SOUND_MIXER_MIC ); if ( devmask & ( 1 << SOUND_MIXER_CD ) ) _channels.insert( "RecCD", SOUND_MIXER_CD ); if ( devmask & ( 1 << SOUND_MIXER_IMIX ) ) _channels.insert( "RecInputMix", SOUND_MIXER_IMIX ); if ( devmask & ( 1 << SOUND_MIXER_ALTPCM ) ) _channels.insert( "RecAltPCM", SOUND_MIXER_ALTPCM ); if ( devmask & ( 1 << SOUND_MIXER_RECLEV ) ) _channels.insert( "RecRecord", SOUND_MIXER_RECLEV ); if ( devmask & ( 1 << SOUND_MIXER_IGAIN ) ) _channels.insert( "RecInputGain", SOUND_MIXER_IGAIN ); if ( devmask & ( 1 << SOUND_MIXER_OGAIN ) ) _channels.insert( "RecOutputGain", SOUND_MIXER_OGAIN ); //odebug << "recmask available and constructed." << oendl; } /* ChannelIterator it; for ( it = _channels.begin(); it != _channels.end(); ++it ) { qDebug( "Channel %s available (bit %d)", (const char*) it.key(), it.data() ); qDebug( " +--- Volume: %02d | %02d", volume( it.key() ) & 0xff, volume( it.key() ) >> 8 ); } */ } QStringList OMixerInterface::allChannels() const { ChannelIterator it = _channels.begin(); QStringList channels; while ( it != _channels.end() ) { channels += it.key(); it++; } return channels; } QStringList OMixerInterface::recChannels() const { owarn << "NYI" << oendl; } QStringList OMixerInterface::playChannels() const { owarn << "NYI" << oendl; } bool OMixerInterface::hasChannel( const QString& channel ) { return _channels.contains( channel ); } void OMixerInterface::setVolume( const QString& channel, int left, int right ) { int volume = left; volume |= ( right == -1 ) ? left << 8 : right << 8; if ( _channels.contains( channel ) ) { int result = ioctl( _fd, MIXER_WRITE( _channels[channel] ), &volume ); if ( result == -1 ) { owarn << "Can't set volume: " << strerror( errno ) << oendl; } else { if ( result & 0xff != left ) { owarn << "Device adjusted volume from " << left << " to " << (result & 0xff) << oendl; } } } } int OMixerInterface::volume( const QString& channel ) const { int volume; if ( _channels.contains( channel ) ) { if ( ioctl( _fd, MIXER_READ( _channels[channel] ), &volume ) == -1 ) { owarn << "Can't get volume: " << strerror( errno ) << oendl; } else return volume; } return -1; } diff --git a/libopie2/opienet/omanufacturerdb.cpp b/libopie2/opienet/omanufacturerdb.cpp index 2da549c..b93b752 100644 --- a/libopie2/opienet/omanufacturerdb.cpp +++ b/libopie2/opienet/omanufacturerdb.cpp @@ -1,136 +1,135 @@ /* This file is part of the Opie Project (C) 2003 Michael 'Mickey' Lauer <mickey@Vanille.de> =. .=l. .>+-= _;:, .> :=|. 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; either version 2 of the License, ._= =} : or (at your option) any later version. .%`+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 "omanufacturerdb.h" #define OPIE_IMPROVE_GUI_LATENCY 1 /* OPIE */ #include <opie2/odebug.h> #ifdef OPIE_IMPROVE_GUI_LATENCY #include <qpe/global.h> #endif /* QT */ #include <qapplication.h> -#include <qstring.h> #include <qfile.h> #include <qtextstream.h> OManufacturerDB* OManufacturerDB::_instance = 0; OManufacturerDB* OManufacturerDB::instance() { if ( !OManufacturerDB::_instance ) { odebug << "OManufacturerDB::instance(): creating OManufacturerDB..." << oendl; _instance = new OManufacturerDB(); } return _instance; } OManufacturerDB::OManufacturerDB() { #ifdef OPIE_IMPROVE_GUI_LATENCY Global::statusMessage( "Reading Manufacturers..." ); #endif QString filename( "/etc/manufacturers" ); odebug << "OManufacturerDB: trying to read " << filename << oendl; if ( !QFile::exists( filename ) ) { filename = "/opt/QtPalmtop/etc/manufacturers"; odebug << "OManufacturerDB: trying to read " << filename << oendl; if ( !QFile::exists( filename ) ) { filename = "/usr/share/wellenreiter/manufacturers"; odebug << "OManufacturerDB: trying to read " << filename << oendl; } } QFile file( filename ); bool hasFile = file.open( IO_ReadOnly ); if (!hasFile) { owarn << "OManufacturerDB: no valid manufacturer list found." << oendl; } else { odebug << "OManufacturerDB: found manufacturer list in " << filename << oendl; QTextStream s( &file ); QString addr; QString manu; QString extManu; #ifdef OPIE_IMPROVE_GUI_LATENCY int counter = 0; #endif while (!s.atEnd()) { s >> addr; s >> manu; s >> extManu; manufacturers.insert( addr, manu ); manufacturersExt.insert( addr, extManu ); // odebug << "OmanufacturerDB: parse '" << addr << "' as '" << manu << "' (" << extManu << ")" << oendl; #ifdef OPIE_IMPROVE_GUI_LATENCY counter++; if ( counter == 50 ) { qApp->processEvents(); counter = 0; } #endif } odebug << "OManufacturerDB: manufacturer list completed." << oendl; #ifdef OPIE_IMPROVE_GUI_LATENCY Global::statusMessage( "Manufacturers Complete..." ); #endif } } OManufacturerDB::~OManufacturerDB() { } const QString& OManufacturerDB::lookup( const QString& macaddr ) const { return manufacturers[macaddr.upper().left(8)]; } const QString& OManufacturerDB::lookupExt( const QString& macaddr ) const { QMap<QString,QString>::ConstIterator it = manufacturersExt.find( macaddr.upper().left(8) ); return it == manufacturersExt.end() ? lookup( macaddr ) : *it; } diff --git a/libopie2/opiepim/backend/ocontactaccessbackend_xml.cpp b/libopie2/opiepim/backend/ocontactaccessbackend_xml.cpp index 0adba68..5d92b8f 100644 --- a/libopie2/opiepim/backend/ocontactaccessbackend_xml.cpp +++ b/libopie2/opiepim/backend/ocontactaccessbackend_xml.cpp @@ -1,751 +1,749 @@ /* This file is part of the Opie Project Copyright (C) Stefan Eilers (Eilers.Stefan@epost.de) =. Copyright (C) The Opie Team <opie-devel@handhelds.org> .=l. .>+-= _;:, .> :=|. 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; either version 2 of the License, ._= =} : or (at your option) any later version. .%`+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. */ /* * XML Backend for the OPIE-Contact Database. */ #include <opie2/ocontactaccessbackend_xml.h> #include <qasciidict.h> -#include <qdatetime.h> #include <qfile.h> #include <qfileinfo.h> #include <qregexp.h> #include <qarray.h> #include <qmap.h> -#include <qdatetime.h> #include <qpe/global.h> #include <opie2/xmltree.h> #include <opie2/ocontactaccessbackend.h> #include <opie2/ocontactaccess.h> #include <stdlib.h> #include <errno.h> using namespace Opie; namespace Opie { OPimContactAccessBackend_XML::OPimContactAccessBackend_XML ( const QString& appname, const QString& filename ): m_changed( false ) { // Just m_contactlist should call delete if an entry // is removed. m_contactList.setAutoDelete( true ); m_uidToContact.setAutoDelete( false ); m_appName = appname; /* Set journalfile name ... */ m_journalName = getenv("HOME"); m_journalName +="/.abjournal" + appname; /* Expecting to access the default filename if nothing else is set */ if ( filename.isEmpty() ){ m_fileName = Global::applicationFileName( "addressbook","addressbook.xml" ); } else m_fileName = filename; /* Load Database now */ load (); } bool OPimContactAccessBackend_XML::save() { if ( !m_changed ) return true; QString strNewFile = m_fileName + ".new"; QFile f( strNewFile ); if ( !f.open( IO_WriteOnly|IO_Raw ) ) return false; int total_written; int idx_offset = 0; QString out; // Write Header out = "<?xml version=\"1.0\" encoding=\"UTF-8\"?><!DOCTYPE Addressbook ><AddressBook>\n" " <Groups>\n" " </Groups>\n" " <Contacts>\n"; QCString cstr = out.utf8(); f.writeBlock( cstr.data(), cstr.length() ); idx_offset += cstr.length(); out = ""; // Write all contacts QListIterator<OPimContact> it( m_contactList ); for ( ; it.current(); ++it ) { // qWarning(" Uid %d at Offset: %x", (*it)->uid(), idx_offset ); out += "<Contact "; (*it)->save( out ); out += "/>\n"; cstr = out.utf8(); total_written = f.writeBlock( cstr.data(), cstr.length() ); idx_offset += cstr.length(); if ( total_written != int(cstr.length()) ) { f.close(); QFile::remove( strNewFile ); return false; } out = ""; } out += " </Contacts>\n</AddressBook>\n"; // Write Footer cstr = out.utf8(); total_written = f.writeBlock( cstr.data(), cstr.length() ); if ( total_written != int( cstr.length() ) ) { f.close(); QFile::remove( strNewFile ); return false; } f.close(); // move the file over, I'm just going to use the system call // because, I don't feel like using QDir. if ( ::rename( strNewFile.latin1(), m_fileName.latin1() ) < 0 ) { qWarning( "problem renaming file %s to %s, errno: %d", strNewFile.latin1(), m_journalName.latin1(), errno ); // remove the tmp file... QFile::remove( strNewFile ); } /* The journalfile should be removed now... */ removeJournal(); m_changed = false; return true; } bool OPimContactAccessBackend_XML::load () { m_contactList.clear(); m_uidToContact.clear(); /* Load XML-File and journal if it exists */ if ( !load ( m_fileName, false ) ) return false; /* The returncode of the journalfile is ignored due to the * fact that it does not exist when this class is instantiated ! * But there may such a file exist, if the application crashed. * Therefore we try to load it to get the changes before the # * crash happened... */ load (m_journalName, true); return true; } void OPimContactAccessBackend_XML::clear () { m_contactList.clear(); m_uidToContact.clear(); m_changed = false; } bool OPimContactAccessBackend_XML::wasChangedExternally() { QFileInfo fi( m_fileName ); QDateTime lastmod = fi.lastModified (); return (lastmod != m_readtime); } QArray<int> OPimContactAccessBackend_XML::allRecords() const { QArray<int> uid_list( m_contactList.count() ); uint counter = 0; QListIterator<OPimContact> it( m_contactList ); for( ; it.current(); ++it ){ uid_list[counter++] = (*it)->uid(); } return ( uid_list ); } OPimContact OPimContactAccessBackend_XML::find ( int uid ) const { OPimContact foundContact; //Create empty contact OPimContact* found = m_uidToContact.find( QString().setNum( uid ) ); if ( found ){ foundContact = *found; } return ( foundContact ); } QArray<int> OPimContactAccessBackend_XML::queryByExample ( const OPimContact &query, int settings, const QDateTime& d ) { QArray<int> m_currentQuery( m_contactList.count() ); QListIterator<OPimContact> it( m_contactList ); uint arraycounter = 0; for( ; it.current(); ++it ){ /* Search all fields and compare them with query object. Store them into list * if all fields matches. */ QDate* queryDate = 0l; QDate* checkDate = 0l; bool allcorrect = true; for ( int i = 0; i < Qtopia::Groups; i++ ) { // Birthday and anniversary are special nonstring fields and should // be handled specially switch ( i ){ case Qtopia::Birthday: queryDate = new QDate( query.birthday() ); checkDate = new QDate( (*it)->birthday() ); case Qtopia::Anniversary: if ( queryDate == 0l ){ queryDate = new QDate( query.anniversary() ); checkDate = new QDate( (*it)->anniversary() ); } if ( queryDate->isValid() ){ if( checkDate->isValid() ){ if ( settings & OPimContactAccess::DateYear ){ if ( queryDate->year() != checkDate->year() ) allcorrect = false; } if ( settings & OPimContactAccess::DateMonth ){ if ( queryDate->month() != checkDate->month() ) allcorrect = false; } if ( settings & OPimContactAccess::DateDay ){ if ( queryDate->day() != checkDate->day() ) allcorrect = false; } if ( settings & OPimContactAccess::DateDiff ) { QDate current; // If we get an additional date, we // will take this date instead of // the current one.. if ( !d.date().isValid() ) current = QDate::currentDate(); else current = d.date(); // We have to equalize the year, otherwise // the search will fail.. checkDate->setYMD( current.year(), checkDate->month(), checkDate->day() ); if ( *checkDate < current ) checkDate->setYMD( current.year()+1, checkDate->month(), checkDate->day() ); // Check whether the birthday/anniversary date is between // the current/given date and the maximum date // ( maximum time range ) ! qWarning("Checking if %s is between %s and %s ! ", checkDate->toString().latin1(), current.toString().latin1(), queryDate->toString().latin1() ); if ( current.daysTo( *queryDate ) >= 0 ){ if ( !( ( *checkDate >= current ) && ( *checkDate <= *queryDate ) ) ){ allcorrect = false; qWarning (" Nope!.."); } } } } else{ // checkDate is invalid. Therefore this entry is always rejected allcorrect = false; } } delete queryDate; queryDate = 0l; delete checkDate; checkDate = 0l; break; default: /* Just compare fields which are not empty in the query object */ if ( !query.field(i).isEmpty() ){ switch ( settings & ~( OPimContactAccess::IgnoreCase | OPimContactAccess::DateDiff | OPimContactAccess::DateYear | OPimContactAccess::DateMonth | OPimContactAccess::DateDay | OPimContactAccess::MatchOne ) ){ case OPimContactAccess::RegExp:{ QRegExp expr ( query.field(i), !(settings & OPimContactAccess::IgnoreCase), false ); if ( expr.find ( (*it)->field(i), 0 ) == -1 ) allcorrect = false; } break; case OPimContactAccess::WildCards:{ QRegExp expr ( query.field(i), !(settings & OPimContactAccess::IgnoreCase), true ); if ( expr.find ( (*it)->field(i), 0 ) == -1 ) allcorrect = false; } break; case OPimContactAccess::ExactMatch:{ if (settings & OPimContactAccess::IgnoreCase){ if ( query.field(i).upper() != (*it)->field(i).upper() ) allcorrect = false; }else{ if ( query.field(i) != (*it)->field(i) ) allcorrect = false; } } break; } } } } if ( allcorrect ){ m_currentQuery[arraycounter++] = (*it)->uid(); } } // Shrink to fit.. m_currentQuery.resize(arraycounter); return m_currentQuery; } QArray<int> OPimContactAccessBackend_XML::matchRegexp( const QRegExp &r ) const { QArray<int> m_currentQuery( m_contactList.count() ); QListIterator<OPimContact> it( m_contactList ); uint arraycounter = 0; for( ; it.current(); ++it ){ if ( (*it)->match( r ) ){ m_currentQuery[arraycounter++] = (*it)->uid(); } } // Shrink to fit.. m_currentQuery.resize(arraycounter); return m_currentQuery; } const uint OPimContactAccessBackend_XML::querySettings() { return ( OPimContactAccess::WildCards | OPimContactAccess::IgnoreCase | OPimContactAccess::RegExp | OPimContactAccess::ExactMatch | OPimContactAccess::DateDiff | OPimContactAccess::DateYear | OPimContactAccess::DateMonth | OPimContactAccess::DateDay ); } bool OPimContactAccessBackend_XML::hasQuerySettings (uint querySettings) const { /* OPimContactAccess::IgnoreCase, DateDiff, DateYear, DateMonth, DateDay * may be added with any of the other settings. IgnoreCase should never used alone. * Wildcards, RegExp, ExactMatch should never used at the same time... */ // Step 1: Check whether the given settings are supported by this backend if ( ( querySettings & ( OPimContactAccess::IgnoreCase | OPimContactAccess::WildCards | OPimContactAccess::DateDiff | OPimContactAccess::DateYear | OPimContactAccess::DateMonth | OPimContactAccess::DateDay | OPimContactAccess::RegExp | OPimContactAccess::ExactMatch ) ) != querySettings ) return false; // Step 2: Check whether the given combinations are ok.. // IngoreCase alone is invalid if ( querySettings == OPimContactAccess::IgnoreCase ) return false; // WildCards, RegExp and ExactMatch should never used at the same time switch ( querySettings & ~( OPimContactAccess::IgnoreCase | OPimContactAccess::DateDiff | OPimContactAccess::DateYear | OPimContactAccess::DateMonth | OPimContactAccess::DateDay ) ){ case OPimContactAccess::RegExp: return ( true ); case OPimContactAccess::WildCards: return ( true ); case OPimContactAccess::ExactMatch: return ( true ); case 0: // one of the upper removed bits were set.. return ( true ); default: return ( false ); } } // Currently only asc implemented.. QArray<int> OPimContactAccessBackend_XML::sorted( bool asc, int , int , int ) { QMap<QString, int> nameToUid; QStringList names; QArray<int> m_currentQuery( m_contactList.count() ); // First fill map and StringList with all Names // Afterwards sort namelist and use map to fill array to return.. QListIterator<OPimContact> it( m_contactList ); for( ; it.current(); ++it ){ names.append( (*it)->fileAs() + QString::number( (*it)->uid() ) ); nameToUid.insert( (*it)->fileAs() + QString::number( (*it)->uid() ), (*it)->uid() ); } names.sort(); int i = 0; if ( asc ){ for ( QStringList::Iterator it = names.begin(); it != names.end(); ++it ) m_currentQuery[i++] = nameToUid[ (*it) ]; }else{ for ( QStringList::Iterator it = names.end(); it != names.begin(); --it ) m_currentQuery[i++] = nameToUid[ (*it) ]; } return m_currentQuery; } bool OPimContactAccessBackend_XML::add ( const OPimContact &newcontact ) { //qWarning("odefaultbackend: ACTION::ADD"); updateJournal (newcontact, ACTION_ADD); addContact_p( newcontact ); m_changed = true; return true; } bool OPimContactAccessBackend_XML::replace ( const OPimContact &contact ) { m_changed = true; OPimContact* found = m_uidToContact.find ( QString().setNum( contact.uid() ) ); if ( found ) { OPimContact* newCont = new OPimContact( contact ); updateJournal ( *newCont, ACTION_REPLACE); m_contactList.removeRef ( found ); m_contactList.append ( newCont ); m_uidToContact.remove( QString().setNum( contact.uid() ) ); m_uidToContact.insert( QString().setNum( newCont->uid() ), newCont ); qWarning("Nur zur Sicherheit: %d == %d ?",contact.uid(), newCont->uid()); return true; } else return false; } bool OPimContactAccessBackend_XML::remove ( int uid ) { m_changed = true; OPimContact* found = m_uidToContact.find ( QString().setNum( uid ) ); if ( found ) { updateJournal ( *found, ACTION_REMOVE); m_contactList.removeRef ( found ); m_uidToContact.remove( QString().setNum( uid ) ); return true; } else return false; } bool OPimContactAccessBackend_XML::reload(){ /* Reload is the same as load in this implementation */ return ( load() ); } void OPimContactAccessBackend_XML::addContact_p( const OPimContact &newcontact ) { OPimContact* contRef = new OPimContact( newcontact ); m_contactList.append ( contRef ); m_uidToContact.insert( QString().setNum( newcontact.uid() ), contRef ); } /* This function loads the xml-database and the journalfile */ bool OPimContactAccessBackend_XML::load( const QString filename, bool isJournal ) { /* We use the time of the last read to check if the file was * changed externally. */ if ( !isJournal ){ QFileInfo fi( filename ); m_readtime = fi.lastModified (); } const int JOURNALACTION = Qtopia::Notes + 1; const int JOURNALROW = JOURNALACTION + 1; bool foundAction = false; journal_action action = ACTION_ADD; int journalKey = 0; QMap<int, QString> contactMap; QMap<QString, QString> customMap; QMap<QString, QString>::Iterator customIt; QAsciiDict<int> dict( 47 ); dict.setAutoDelete( TRUE ); dict.insert( "Uid", new int(Qtopia::AddressUid) ); dict.insert( "Title", new int(Qtopia::Title) ); dict.insert( "FirstName", new int(Qtopia::FirstName) ); dict.insert( "MiddleName", new int(Qtopia::MiddleName) ); dict.insert( "LastName", new int(Qtopia::LastName) ); dict.insert( "Suffix", new int(Qtopia::Suffix) ); dict.insert( "FileAs", new int(Qtopia::FileAs) ); dict.insert( "Categories", new int(Qtopia::AddressCategory) ); dict.insert( "DefaultEmail", new int(Qtopia::DefaultEmail) ); dict.insert( "Emails", new int(Qtopia::Emails) ); dict.insert( "HomeStreet", new int(Qtopia::HomeStreet) ); dict.insert( "HomeCity", new int(Qtopia::HomeCity) ); dict.insert( "HomeState", new int(Qtopia::HomeState) ); dict.insert( "HomeZip", new int(Qtopia::HomeZip) ); dict.insert( "HomeCountry", new int(Qtopia::HomeCountry) ); dict.insert( "HomePhone", new int(Qtopia::HomePhone) ); dict.insert( "HomeFax", new int(Qtopia::HomeFax) ); dict.insert( "HomeMobile", new int(Qtopia::HomeMobile) ); dict.insert( "HomeWebPage", new int(Qtopia::HomeWebPage) ); dict.insert( "Company", new int(Qtopia::Company) ); dict.insert( "BusinessStreet", new int(Qtopia::BusinessStreet) ); dict.insert( "BusinessCity", new int(Qtopia::BusinessCity) ); dict.insert( "BusinessState", new int(Qtopia::BusinessState) ); dict.insert( "BusinessZip", new int(Qtopia::BusinessZip) ); dict.insert( "BusinessCountry", new int(Qtopia::BusinessCountry) ); dict.insert( "BusinessWebPage", new int(Qtopia::BusinessWebPage) ); dict.insert( "JobTitle", new int(Qtopia::JobTitle) ); dict.insert( "Department", new int(Qtopia::Department) ); dict.insert( "Office", new int(Qtopia::Office) ); dict.insert( "BusinessPhone", new int(Qtopia::BusinessPhone) ); dict.insert( "BusinessFax", new int(Qtopia::BusinessFax) ); dict.insert( "BusinessMobile", new int(Qtopia::BusinessMobile) ); dict.insert( "BusinessPager", new int(Qtopia::BusinessPager) ); dict.insert( "Profession", new int(Qtopia::Profession) ); dict.insert( "Assistant", new int(Qtopia::Assistant) ); dict.insert( "Manager", new int(Qtopia::Manager) ); dict.insert( "Spouse", new int(Qtopia::Spouse) ); dict.insert( "Children", new int(Qtopia::Children) ); dict.insert( "Gender", new int(Qtopia::Gender) ); dict.insert( "Birthday", new int(Qtopia::Birthday) ); dict.insert( "Anniversary", new int(Qtopia::Anniversary) ); dict.insert( "Nickname", new int(Qtopia::Nickname) ); dict.insert( "Notes", new int(Qtopia::Notes) ); dict.insert( "action", new int(JOURNALACTION) ); dict.insert( "actionrow", new int(JOURNALROW) ); //qWarning( "OPimContactDefaultBackEnd::loading %s", filename.latin1() ); XMLElement *root = XMLElement::load( filename ); if(root != 0l ){ // start parsing /* Parse all XML-Elements and put the data into the * Contact-Class */ XMLElement *element = root->firstChild(); //qWarning("OPimContactAccess::load tagName(): %s", root->tagName().latin1() ); element = element->firstChild(); /* Search Tag "Contacts" which is the parent of all Contacts */ while( element && !isJournal ){ if( element->tagName() != QString::fromLatin1("Contacts") ){ //qWarning ("OPimContactDefBack::Searching for Tag \"Contacts\"! Found: %s", // element->tagName().latin1()); element = element->nextChild(); } else { element = element->firstChild(); break; } } /* Parse all Contacts and ignore unknown tags */ while( element ){ if( element->tagName() != QString::fromLatin1("Contact") ){ //qWarning ("OPimContactDefBack::Searching for Tag \"Contact\"! Found: %s", // element->tagName().latin1()); element = element->nextChild(); continue; } /* Found alement with tagname "contact", now parse and store all * attributes contained */ //qWarning("OPimContactDefBack::load element tagName() : %s", // element->tagName().latin1() ); QString dummy; foundAction = false; XMLElement::AttributeMap aMap = element->attributes(); XMLElement::AttributeMap::Iterator it; contactMap.clear(); customMap.clear(); for( it = aMap.begin(); it != aMap.end(); ++it ){ // qWarning ("Read Attribute: %s=%s", it.key().latin1(),it.data().latin1()); int *find = dict[ it.key() ]; /* Unknown attributes will be stored as "Custom" elements */ if ( !find ) { // qWarning("Attribute %s not known.", it.key().latin1()); //contact.setCustomField(it.key(), it.data()); customMap.insert( it.key(), it.data() ); continue; } /* Check if special conversion is needed and add attribute * into Contact class */ switch( *find ) { /* case Qtopia::AddressUid: contact.setUid( it.data().toInt() ); break; case Qtopia::AddressCategory: contact.setCategories( Qtopia::Record::idsFromString( it.data( ))); break; */ case JOURNALACTION: action = journal_action(it.data().toInt()); foundAction = true; qWarning ("ODefBack(journal)::ACTION found: %d", action); break; case JOURNALROW: journalKey = it.data().toInt(); break; default: // no conversion needed add them to the map contactMap.insert( *find, it.data() ); break; } } /* now generate the Contact contact */ OPimContact contact( contactMap ); for (customIt = customMap.begin(); customIt != customMap.end(); ++customIt ) { contact.setCustomField( customIt.key(), customIt.data() ); } if (foundAction){ foundAction = false; switch ( action ) { case ACTION_ADD: addContact_p (contact); break; case ACTION_REMOVE: if ( !remove (contact.uid()) ) qWarning ("ODefBack(journal)::Unable to remove uid: %d", contact.uid() ); break; case ACTION_REPLACE: if ( !replace ( contact ) ) qWarning ("ODefBack(journal)::Unable to replace uid: %d", contact.uid() ); break; default: qWarning ("Unknown action: ignored !"); break; } }else{ /* Add contact to list */ addContact_p (contact); } /* Move to next element */ element = element->nextChild(); } }else { qWarning("ODefBack::could not load"); } delete root; qWarning("returning from loading" ); return true; } void OPimContactAccessBackend_XML::updateJournal( const OPimContact& cnt, journal_action action ) { QFile f( m_journalName ); bool created = !f.exists(); if ( !f.open(IO_WriteOnly|IO_Append) ) return; QString buf; QCString str; // if the file was created, we have to set the Tag "<CONTACTS>" to // get a XML-File which is readable by our parser. // This is just a cheat, but better than rewrite the parser. if ( created ){ buf = "<Contacts>"; QCString cstr = buf.utf8(); f.writeBlock( cstr.data(), cstr.length() ); } buf = "<Contact "; cnt.save( buf ); buf += " action=\"" + QString::number( (int)action ) + "\" "; buf += "/>\n"; QCString cstr = buf.utf8(); f.writeBlock( cstr.data(), cstr.length() ); } void OPimContactAccessBackend_XML::removeJournal() { QFile f ( m_journalName ); if ( f.exists() ) f.remove(); } } diff --git a/libopie2/opiepim/core/opimcontact.cpp b/libopie2/opiepim/core/opimcontact.cpp index a5df597..4a774e8 100644 --- a/libopie2/opiepim/core/opimcontact.cpp +++ b/libopie2/opiepim/core/opimcontact.cpp @@ -1,1293 +1,1289 @@ /* This file is part of the Opie Project Copyright (C) Stefan Eilers <eilers.stefan@epost.de> =. Copyright (C) The Opie Team <opie-devel@handhelds.org> .=l. .>+-= _;:, .> :=|. 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; either version 2 of the License, ._= =} : or (at your option) any later version. .%`+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. */ #define QTOPIA_INTERNAL_CONTACT_MRE #include "opimcontact.h" /* OPIE */ #include <opie2/opimresolver.h> #include <opie2/opimdateconversion.h> #include <qpe/stringutil.h> #include <qpe/timestring.h> #include <qpe/config.h> /* QT */ -#include <qobject.h> -#include <qregexp.h> #include <qstylesheet.h> -#include <qfileinfo.h> -#include <qmap.h> /* STD */ #include <stdio.h> /*! \class Contact contact.h \brief The Contact class holds the data of an address book entry. This data includes information the name of the person, contact information, and business information such as deparment and job title. \ingroup qtopiaemb \ingroup qtopiadesktop */ namespace Opie { /*! Creates a new, empty contact. */ OPimContact::OPimContact():OPimRecord(), mMap(), d( 0 ) {} /*! \internal Creates a new contact. The properties of the contact are set from \a fromMap. */ OPimContact::OPimContact( const QMap<int, QString> &fromMap ):OPimRecord(), mMap( fromMap ), d( 0 ) { QString cats = mMap[ Qtopia::AddressCategory ]; if ( !cats.isEmpty() ) setCategories( idsFromString( cats ) ); QString uidStr = find( Qtopia::AddressUid ); if ( uidStr.isEmpty() || ( uidStr.toInt() == 0 ) ) { qWarning( "Invalid UID found. Generate new one.." ); setUid( uidGen().generate() ); } else setUid( uidStr.toInt() ); // if ( !uidStr.isEmpty() ) // setUid( uidStr.toInt() ); } /*! Destroys a contact. */ OPimContact::~OPimContact() {} /*! \fn void OPimContact::setTitle( const QString &str ) Sets the title of the contact to \a str. */ /*! \fn void OPimContact::setFirstName( const QString &str ) Sets the first name of the contact to \a str. */ /*! \fn void OPimContact::setMiddleName( const QString &str ) Sets the middle name of the contact to \a str. */ /*! \fn void OPimContact::setLastName( const QString &str ) Sets the last name of the contact to \a str. */ /*! \fn void OPimContact::setSuffix( const QString &str ) Sets the suffix of the contact to \a str. */ /*! \fn void OPimContact::setFileAs( const QString &str ) Sets the contact to filed as \a str. */ /*! \fn void OPimContact::setDefaultEmail( const QString &str ) Sets the default email of the contact to \a str. */ /*! \fn void OPimContact::setHomeStreet( const QString &str ) Sets the home street address of the contact to \a str. */ /*! \fn void OPimContact::setHomeCity( const QString &str ) Sets the home city of the contact to \a str. */ /*! \fn void OPimContact::setHomeState( const QString &str ) Sets the home state of the contact to \a str. */ /*! \fn void OPimContact::setHomeZip( const QString &str ) Sets the home zip code of the contact to \a str. */ /*! \fn void OPimContact::setHomeCountry( const QString &str ) Sets the home country of the contact to \a str. */ /*! \fn void OPimContact::setHomePhone( const QString &str ) Sets the home phone number of the contact to \a str. */ /*! \fn void OPimContact::setHomeFax( const QString &str ) Sets the home fax number of the contact to \a str. */ /*! \fn void OPimContact::setHomeMobile( const QString &str ) Sets the home mobile phone number of the contact to \a str. */ /*! \fn void OPimContact::setHomeWebpage( const QString &str ) Sets the home webpage of the contact to \a str. */ /*! \fn void OPimContact::setCompany( const QString &str ) Sets the company for contact to \a str. */ /*! \fn void OPimContact::setJobTitle( const QString &str ) Sets the job title of the contact to \a str. */ /*! \fn void OPimContact::setDepartment( const QString &str ) Sets the department for contact to \a str. */ /*! \fn void OPimContact::setOffice( const QString &str ) Sets the office for contact to \a str. */ /*! \fn void OPimContact::setBusinessStreet( const QString &str ) Sets the business street address of the contact to \a str. */ /*! \fn void OPimContact::setBusinessCity( const QString &str ) Sets the business city of the contact to \a str. */ /*! \fn void OPimContact::setBusinessState( const QString &str ) Sets the business state of the contact to \a str. */ /*! \fn void OPimContact::setBusinessZip( const QString &str ) Sets the business zip code of the contact to \a str. */ /*! \fn void OPimContact::setBusinessCountry( const QString &str ) Sets the business country of the contact to \a str. */ /*! \fn void OPimContact::setBusinessPhone( const QString &str ) Sets the business phone number of the contact to \a str. */ /*! \fn void OPimContact::setBusinessFax( const QString &str ) Sets the business fax number of the contact to \a str. */ /*! \fn void OPimContact::setBusinessMobile( const QString &str ) Sets the business mobile phone number of the contact to \a str. */ /*! \fn void OPimContact::setBusinessPager( const QString &str ) Sets the business pager number of the contact to \a str. */ /*! \fn void OPimContact::setBusinessWebpage( const QString &str ) Sets the business webpage of the contact to \a str. */ /*! \fn void OPimContact::setProfession( const QString &str ) Sets the profession of the contact to \a str. */ /*! \fn void OPimContact::setAssistant( const QString &str ) Sets the assistant of the contact to \a str. */ /*! \fn void OPimContact::setManager( const QString &str ) Sets the manager of the contact to \a str. */ /*! \fn void OPimContact::setSpouse( const QString &str ) Sets the spouse of the contact to \a str. */ /*! \fn void OPimContact::setGender( const QString &str ) Sets the gender of the contact to \a str. */ /*! \fn void OPimContact::setNickname( const QString &str ) Sets the nickname of the contact to \a str. */ /*! \fn void OPimContact::setNotes( const QString &str ) Sets the notes about the contact to \a str. */ /*! \fn QString OPimContact::title() const Returns the title of the contact. */ /*! \fn QString OPimContact::firstName() const Returns the first name of the contact. */ /*! \fn QString OPimContact::middleName() const Returns the middle name of the contact. */ /*! \fn QString OPimContact::lastName() const Returns the last name of the contact. */ /*! \fn QString OPimContact::suffix() const Returns the suffix of the contact. */ /*! \fn QString OPimContact::fileAs() const Returns the string the contact is filed as. */ /*! \fn QString OPimContact::defaultEmail() const Returns the default email address of the contact. */ /*! \fn QString OPimContact::emails() const Returns the list of email address for a contact separated by ';'s in a single string. */ /*! \fn QString OPimContact::homeStreet() const Returns the home street address of the contact. */ /*! \fn QString OPimContact::homeCity() const Returns the home city of the contact. */ /*! \fn QString OPimContact::homeState() const Returns the home state of the contact. */ /*! \fn QString OPimContact::homeZip() const Returns the home zip of the contact. */ /*! \fn QString OPimContact::homeCountry() const Returns the home country of the contact. */ /*! \fn QString OPimContact::homePhone() const Returns the home phone number of the contact. */ /*! \fn QString OPimContact::homeFax() const Returns the home fax number of the contact. */ /*! \fn QString OPimContact::homeMobile() const Returns the home mobile number of the contact. */ /*! \fn QString OPimContact::homeWebpage() const Returns the home webpage of the contact. */ /*! \fn QString OPimContact::company() const Returns the company for the contact. */ /*! \fn QString OPimContact::department() const Returns the department for the contact. */ /*! \fn QString OPimContact::office() const Returns the office for the contact. */ /*! \fn QString OPimContact::jobTitle() const Returns the job title of the contact. */ /*! \fn QString OPimContact::profession() const Returns the profession of the contact. */ /*! \fn QString OPimContact::assistant() const Returns the assistant of the contact. */ /*! \fn QString OPimContact::manager() const Returns the manager of the contact. */ /*! \fn QString OPimContact::businessStreet() const Returns the business street address of the contact. */ /*! \fn QString OPimContact::businessCity() const Returns the business city of the contact. */ /*! \fn QString OPimContact::businessState() const Returns the business state of the contact. */ /*! \fn QString OPimContact::businessZip() const Returns the business zip of the contact. */ /*! \fn QString OPimContact::businessCountry() const Returns the business country of the contact. */ /*! \fn QString OPimContact::businessPhone() const Returns the business phone number of the contact. */ /*! \fn QString OPimContact::businessFax() const Returns the business fax number of the contact. */ /*! \fn QString OPimContact::businessMobile() const Returns the business mobile number of the contact. */ /*! \fn QString OPimContact::businessPager() const Returns the business pager number of the contact. */ /*! \fn QString OPimContact::businessWebpage() const Returns the business webpage of the contact. */ /*! \fn QString OPimContact::spouse() const Returns the spouse of the contact. */ /*! \fn QString OPimContact::gender() const Returns the gender of the contact. */ /*! \fn QString OPimContact::nickname() const Returns the nickname of the contact. */ /*! \fn QString OPimContact::children() const Returns the children of the contact. */ /*! \fn QString OPimContact::notes() const Returns the notes relating to the the contact. */ /*! \fn QString OPimContact::groups() const \internal Returns the groups for the contact. */ /*! \fn QStringList OPimContact::groupList() const \internal */ /*! \fn QString OPimContact::field(int) const \internal */ /*! \fn void OPimContact::saveJournal( journal_action, const QString & = QString::null ) \internal */ /*! \fn void OPimContact::setUid( int id ) \internal Sets the uid for this record to \a id. */ /*! \enum OPimContact::journal_action \internal */ /*! \internal */ QMap<int, QString> OPimContact::toMap() const { QMap<int, QString> map = mMap; QString cats = idsToString( categories() ); if ( !cats.isEmpty() ) map.insert( Qtopia::AddressCategory, cats ); return map; } /*! Returns a rich text formatted QString representing the contents the contact. */ QString OPimContact::toRichText() const { QString text; QString value, comp, state; QString str; bool marker = false; Config cfg( "qpe" ); cfg.setGroup( "Appearance" ); int addressformat = cfg.readNumEntry( "AddressFormat", Zip_City_State ); // name, jobtitle and company if ( !( value = fullName() ).isEmpty() ) text += "<b><h3><img src=\"addressbook/AddressBook\"> " + Qtopia::escapeString( value ) + "</h3></b>"; if ( !( value = jobTitle() ).isEmpty() ) text += Qtopia::escapeString( value ) + " "; comp = company(); if ( !( value = department() ).isEmpty() ) { text += Qtopia::escapeString( value ); if ( comp ) text += ", " + Qtopia::escapeString( comp ); } else if ( comp ) text += "<br>" + Qtopia::escapeString( comp ); text += "<br><hr>"; // defailt email QString defEmail = defaultEmail(); if ( !defEmail.isEmpty() ) { text += "<b><img src=\"addressbook/email\"> " + QObject::tr( "Default Email: " ) + "</b>" + Qtopia::escapeString( defEmail ); marker = true; } // business address if ( !businessStreet().isEmpty() || !businessCity().isEmpty() || !businessZip().isEmpty() || !businessCountry().isEmpty() ) { text += QObject::tr( "<br><b>Work Address:</b>" ); marker = true; } if ( !( value = businessStreet() ).isEmpty() ) { text += "<br>" + Qtopia::escapeString( value ); marker = true; } switch ( addressformat ) { case Zip_City_State: { // Zip_Code City, State state = businessState(); if ( !( value = businessZip() ).isEmpty() ) { text += "<br>" + Qtopia::escapeString( value ) + " "; marker = true; } if ( !( value = businessCity() ).isEmpty() ) { marker = true; if ( businessZip().isEmpty() && !businessStreet().isEmpty() ) text += "<br>"; text += Qtopia::escapeString( value ); if ( state ) text += ", " + Qtopia::escapeString( state ); } else if ( !state.isEmpty() ) { text += "<br>" + Qtopia::escapeString( state ); marker = true; } break; } case City_State_Zip: { // City, State Zip_Code state = businessState(); if ( !( value = businessCity() ).isEmpty() ) { marker = true; text += "<br>" + Qtopia::escapeString( value ); if ( state ) text += ", " + Qtopia::escapeString( state ); } else if ( !state.isEmpty() ) { text += "<br>" + Qtopia::escapeString( state ); marker = true; } if ( !( value = businessZip() ).isEmpty() ) { text += " " + Qtopia::escapeString( value ); marker = true; } break; } } if ( !( value = businessCountry() ).isEmpty() ) { text += "<br>" + Qtopia::escapeString( value ); marker = true; } // rest of Business data str = office(); if ( !str.isEmpty() ) { text += "<br><b>" + QObject::tr( "Office: " ) + "</b>" + Qtopia::escapeString( str ); marker = true; } str = businessWebpage(); if ( !str.isEmpty() ) { text += "<br><b><img src=\"addressbook/webpagework\"> " + QObject::tr( "Business Web Page: " ) + "</b>" + Qtopia::escapeString( str ); marker = true; } str = businessPhone(); if ( !str.isEmpty() ) { text += "<br><b><img src=\"addressbook/phonework\"> " + QObject::tr( "Business Phone: " ) + "</b>" + Qtopia::escapeString( str ); marker = true; } str = businessFax(); if ( !str.isEmpty() ) { text += "<br><b><img src=\"addressbook/faxwork\"> " + QObject::tr( "Business Fax: " ) + "</b>" + Qtopia::escapeString( str ); marker = true; } str = businessMobile(); if ( !str.isEmpty() ) { text += "<br><b><img src=\"addressbook/mobilework\"> " + QObject::tr( "Business Mobile: " ) + "</b>" + Qtopia::escapeString( str ); marker = true; } str = businessPager(); if ( !str.isEmpty() ) { text += "<br><b>" + QObject::tr( "Business Pager: " ) + "</b>" + Qtopia::escapeString( str ); marker = true; } // text += "<br>"; // home address if ( !homeStreet().isEmpty() || !homeCity().isEmpty() || !homeZip().isEmpty() || !homeCountry().isEmpty() ) { text += QObject::tr( "<br><b>Home Address:</b>" ); marker = true; } if ( !( value = homeStreet() ).isEmpty() ) { text += "<br>" + Qtopia::escapeString( value ); marker = true; } switch ( addressformat ) { case Zip_City_State: { // Zip_Code City, State state = homeState(); if ( !( value = homeZip() ).isEmpty() ) { text += "<br>" + Qtopia::escapeString( value ) + " "; marker = true; } if ( !( value = homeCity() ).isEmpty() ) { marker = true; if ( homeZip().isEmpty() && !homeStreet().isEmpty() ) text += "<br>"; text += Qtopia::escapeString( value ); if ( !state.isEmpty() ) text += ", " + Qtopia::escapeString( state ); } else if ( !state.isEmpty() ) { text += "<br>" + Qtopia::escapeString( state ); marker = true; } break; } case City_State_Zip: { // City, State Zip_Code state = homeState(); if ( !( value = homeCity() ).isEmpty() ) { marker = true; text += "<br>" + Qtopia::escapeString( value ); if ( state ) text += ", " + Qtopia::escapeString( state ); } else if ( !state.isEmpty() ) { text += "<br>" + Qtopia::escapeString( state ); marker = true; } if ( !( value = homeZip() ).isEmpty() ) { text += " " + Qtopia::escapeString( value ); marker = true; } break; } } if ( !( value = homeCountry() ).isEmpty() ) { text += "<br>" + Qtopia::escapeString( value ); marker = true; } // rest of Home data str = homeWebpage(); if ( !str.isEmpty() ) { text += "<br><b><img src=\"addressbook/webpagehome\"> " + QObject::tr( "Home Web Page: " ) + "</b>" + Qtopia::escapeString( str ); marker = true; } str = homePhone(); if ( !str.isEmpty() ) { text += "<br><b><img src=\"addressbook/phonehome\"> " + QObject::tr( "Home Phone: " ) + "</b>" + Qtopia::escapeString( str ); marker = true; } str = homeFax(); if ( !str.isEmpty() ) { text += "<br><b><img src=\"addressbook/faxhome\"> " + QObject::tr( "Home Fax: " ) + "</b>" + Qtopia::escapeString( str ); marker = true; } str = homeMobile(); if ( !str.isEmpty() ) { text += "<br><b><img src=\"addressbook/mobilehome\"> " + QObject::tr( "Home Mobile: " ) + "</b>" + Qtopia::escapeString( str ); marker = true; } if ( marker ) text += "<br><hr>"; // the rest... str = emails(); if ( !str.isEmpty() && ( str != defEmail ) ) text += "<br><b>" + QObject::tr( "All Emails: " ) + "</b>" + Qtopia::escapeString( str ); str = profession(); if ( !str.isEmpty() ) text += "<br><b>" + QObject::tr( "Profession: " ) + "</b>" + Qtopia::escapeString( str ); str = assistant(); if ( !str.isEmpty() ) text += "<br><b>" + QObject::tr( "Assistant: " ) + "</b>" + Qtopia::escapeString( str ); str = manager(); if ( !str.isEmpty() ) text += "<br><b>" + QObject::tr( "Manager: " ) + "</b>" + Qtopia::escapeString( str ); str = gender(); if ( !str.isEmpty() && str.toInt() != 0 ) { text += "<br>"; if ( str.toInt() == 1 ) str = QObject::tr( "Male" ); else if ( str.toInt() == 2 ) str = QObject::tr( "Female" ); text += "<b>" + QObject::tr( "Gender: " ) + "</b>" + str; } str = spouse(); if ( !str.isEmpty() ) text += "<br><b>" + QObject::tr( "Spouse: " ) + "</b>" + Qtopia::escapeString( str ); if ( birthday().isValid() ) { str = TimeString::numberDateString( birthday() ); text += "<br><b>" + QObject::tr( "Birthday: " ) + "</b>" + Qtopia::escapeString( str ); } if ( anniversary().isValid() ) { str = TimeString::numberDateString( anniversary() ); text += "<br><b>" + QObject::tr( "Anniversary: " ) + "</b>" + Qtopia::escapeString( str ); } str = children(); if ( !str.isEmpty() ) text += "<br><b>" + QObject::tr( "Children: " ) + "</b>" + Qtopia::escapeString( str ); str = nickname(); if ( !str.isEmpty() ) text += "<br><b>" + QObject::tr( "Nickname: " ) + "</b>" + Qtopia::escapeString( str ); // categories if ( categoryNames( "Contacts" ).count() ) { text += "<br><b>" + QObject::tr( "Category:" ) + "</b> "; text += categoryNames( "Contacts" ).join( ", " ); } // notes last if ( !( value = notes() ).isEmpty() ) { text += "<br><hr><b>" + QObject::tr( "Notes:" ) + "</b> "; QRegExp reg( "\n" ); //QString tmp = Qtopia::escapeString(value); QString tmp = QStyleSheet::convertFromPlainText( value ); //tmp.replace( reg, "<br>" ); text += "<br>" + tmp + "<br>"; } return text; } /*! \internal */ void OPimContact::insert( int key, const QString &v ) { QString value = v.stripWhiteSpace(); if ( value.isEmpty() ) mMap.remove( key ); else mMap.insert( key, value ); } /*! \internal */ void OPimContact::replace( int key, const QString & v ) { QString value = v.stripWhiteSpace(); if ( value.isEmpty() ) mMap.remove( key ); else mMap.replace( key, value ); } /*! \internal */ QString OPimContact::find( int key ) const { return mMap[ key ]; } /*! \internal */ QString OPimContact::displayAddress( const QString &street, const QString &city, const QString &state, const QString &zip, const QString &country ) const { QString s = street; if ( !street.isEmpty() ) s += "\n"; s += city; if ( !city.isEmpty() && !state.isEmpty() ) s += ", "; s += state; if ( !state.isEmpty() && !zip.isEmpty() ) s += " "; s += zip; if ( !country.isEmpty() && !s.isEmpty() ) s += "\n"; s += country; return s; } /*! \internal */ QString OPimContact::displayBusinessAddress() const { return displayAddress( businessStreet(), businessCity(), businessState(), businessZip(), businessCountry() ); } /*! \internal */ QString OPimContact::displayHomeAddress() const { return displayAddress( homeStreet(), homeCity(), homeState(), homeZip(), homeCountry() ); } /*! Returns the full name of the contact */ QString OPimContact::fullName() const { QString title = find( Qtopia::Title ); QString firstName = find( Qtopia::FirstName ); QString middleName = find( Qtopia::MiddleName ); QString lastName = find( Qtopia::LastName ); QString suffix = find( Qtopia::Suffix ); QString name = title; if ( !firstName.isEmpty() ) { if ( !name.isEmpty() ) name += " "; name += firstName; } if ( !middleName.isEmpty() ) { if ( !name.isEmpty() ) name += " "; name += middleName; } if ( !lastName.isEmpty() ) { if ( !name.isEmpty() ) name += " "; name += lastName; } if ( !suffix.isEmpty() ) { if ( !name.isEmpty() ) name += " "; name += suffix; } return name.simplifyWhiteSpace(); } /*! Returns a list of the names of the children of the contact. */ QStringList OPimContact::childrenList() const { return QStringList::split( " ", find( Qtopia::Children ) ); } /*! \fn void OPimContact::insertEmail( const QString &email ) Insert \a email into the email list. Ensures \a email can only be added once. If there is no default email address set, it sets it to the \a email. */ /*! \fn void OPimContact::removeEmail( const QString &email ) Removes the \a email from the email list. If the default email was \a email, then the default email address is assigned to the first email in the email list */ /*! \fn void OPimContact::clearEmails() Clears the email list. */ /*! \fn void OPimContact::insertEmails( const QStringList &emailList ) Appends the \a emailList to the exiting email list */ /*! Returns a list of email addresses belonging to the contact, including the default email address. */ QStringList OPimContact::emailList() const { QString emailStr = emails(); QStringList r; if ( !emailStr.isEmpty() ) { qDebug( " emailstr " ); QStringList l = QStringList::split( emailSeparator(), emailStr ); for ( QStringList::ConstIterator it = l.begin();it != l.end();++it ) r += ( *it ).simplifyWhiteSpace(); } return r; } /*! \overload Generates the string for the contact to be filed as from the first, middle and last name of the contact. */ void OPimContact::setFileAs() { QString lastName, firstName, middleName, fileas; lastName = find( Qtopia::LastName ); firstName = find( Qtopia::FirstName ); middleName = find( Qtopia::MiddleName ); if ( !lastName.isEmpty() && !firstName.isEmpty() && !middleName.isEmpty() ) fileas = lastName + ", " + firstName + " " + middleName; else if ( !lastName.isEmpty() && !firstName.isEmpty() ) fileas = lastName + ", " + firstName; else if ( !lastName.isEmpty() || !firstName.isEmpty() || !middleName.isEmpty() ) fileas = firstName + ( firstName.isEmpty() ? "" : " " ) + middleName + ( middleName.isEmpty() ? "" : " " ) + lastName; replace( Qtopia::FileAs, fileas ); } /*! \internal Appends the contact information to \a buf. */ void OPimContact::save( QString &buf ) const { static const QStringList SLFIELDS = fields(); // I'm expecting "<Contact " in front of this... for ( QMap<int, QString>::ConstIterator it = mMap.begin(); it != mMap.end(); ++it ) { const QString &value = it.data(); int key = it.key(); if ( !value.isEmpty() ) { if ( key == Qtopia::AddressCategory || key == Qtopia::AddressUid ) continue; key -= Qtopia::AddressCategory + 1; buf += SLFIELDS[ key ]; buf += "=\"" + Qtopia::escapeString( value ) + "\" "; } } buf += customToXml(); if ( categories().count() > 0 ) buf += "Categories=\"" + idsToString( categories() ) + "\" "; buf += "Uid=\"" + QString::number( uid() ) + "\" "; // You need to close this yourself } /*! \internal Returns the list of fields belonging to a contact Never change order of this list ! It has to be regarding enum AddressBookFields !! */ QStringList OPimContact::fields() { QStringList list; list.append( "Title" ); // Not Used! list.append( "FirstName" ); list.append( "MiddleName" ); list.append( "LastName" ); list.append( "Suffix" ); list.append( "FileAs" ); list.append( "JobTitle" ); list.append( "Department" ); list.append( "Company" ); list.append( "BusinessPhone" ); list.append( "BusinessFax" ); list.append( "BusinessMobile" ); list.append( "DefaultEmail" ); list.append( "Emails" ); list.append( "HomePhone" ); list.append( "HomeFax" ); list.append( "HomeMobile" ); list.append( "BusinessStreet" ); list.append( "BusinessCity" ); list.append( "BusinessState" ); list.append( "BusinessZip" ); list.append( "BusinessCountry" ); list.append( "BusinessPager" ); list.append( "BusinessWebPage" ); list.append( "Office" ); list.append( "Profession" ); list.append( "Assistant" ); list.append( "Manager" ); list.append( "HomeStreet" ); list.append( "HomeCity" ); list.append( "HomeState" ); list.append( "HomeZip" ); list.append( "HomeCountry" ); list.append( "HomeWebPage" ); list.append( "Spouse" ); list.append( "Gender" ); list.append( "Birthday" ); list.append( "Anniversary" ); list.append( "Nickname" ); list.append( "Children" ); list.append( "Notes" ); list.append( "Groups" ); return list; } /*! Sets the list of email address for contact to those contained in \a str. Email address should be separated by ';'s. */ void OPimContact::setEmails( const QString &str ) { replace( Qtopia::Emails, str ); if ( str.isEmpty() ) setDefaultEmail( QString::null ); } /*! Sets the list of children for the contact to those contained in \a str. */ void OPimContact::setChildren( const QString &str ) { replace( Qtopia::Children, str ); } /*! \overload Returns TRUE if the contact matches the regular expression \a regexp. Otherwise returns FALSE. */ bool OPimContact::match( const QRegExp &r ) const { setLastHitField( -1 ); bool match; match = false; QMap<int, QString>::ConstIterator it; for ( it = mMap.begin(); it != mMap.end(); ++it ) { if ( ( *it ).find( r ) > -1 ) { setLastHitField( it.key() ); match = true; break; } } return match; } QString OPimContact::toShortText() const { return ( fullName() ); } QString OPimContact::type() const { return QString::fromLatin1( "OPimContact" ); } class QString OPimContact::recordField( int pos ) const { QStringList SLFIELDS = fields(); // ?? why this ? (se) return SLFIELDS[ pos ]; } // In future releases, we should store birthday and anniversary // internally as QDate instead of QString ! // QString is always too complicate to interprete (DD.MM.YY, DD/MM/YY, MM/DD/YY, etc..)(se) /*! \fn void OPimContact::setBirthday( const QDate& date ) Sets the birthday for the contact to \a date. If date is null the current stored date will be removed. */ void OPimContact::setBirthday( const QDate &v ) { if ( v.isNull() ) { qWarning( "Remove Birthday" ); replace( Qtopia::Birthday, QString::null ); return ; } if ( v.isValid() ) replace( Qtopia::Birthday, OPimDateConversion::dateToString( v ) ); } /*! \fn void OPimContact::setAnniversary( const QDate &date ) Sets the anniversary of the contact to \a date. If date is null, the current stored date will be removed. */ void OPimContact::setAnniversary( const QDate &v ) { if ( v.isNull() ) { qWarning( "Remove Anniversary" ); replace( Qtopia::Anniversary, QString::null ); return ; } if ( v.isValid() ) replace( Qtopia::Anniversary, OPimDateConversion::dateToString( v ) ); } /*! \fn QDate OPimContact::birthday() const Returns the birthday of the contact. */ QDate OPimContact::birthday() const { QString str = find( Qtopia::Birthday ); // qWarning ("Birthday %s", str.latin1() ); if ( !str.isEmpty() ) return OPimDateConversion::dateFromString ( str ); else return QDate(); } /*! \fn QDate OPimContact::anniversary() const Returns the anniversary of the contact. */ QDate OPimContact::anniversary() const { QDate empty; QString str = find( Qtopia::Anniversary ); // qWarning ("Anniversary %s", str.latin1() ); if ( !str.isEmpty() ) return OPimDateConversion::dateFromString ( str ); else return empty; } void OPimContact::insertEmail( const QString &v ) { //qDebug("insertEmail %s", v.latin1()); QString e = v.simplifyWhiteSpace(); QString def = defaultEmail(); // if no default, set it as the default email and don't insert if ( def.isEmpty() ) { setDefaultEmail( e ); // will insert into the list for us return ; } // otherwise, insert assuming doesn't already exist QString emailsStr = find( Qtopia::Emails ); if ( emailsStr.contains( e ) ) return ; if ( !emailsStr.isEmpty() ) emailsStr += emailSeparator(); emailsStr += e; replace( Qtopia::Emails, emailsStr ); } void OPimContact::removeEmail( const QString &v ) { QString e = v.simplifyWhiteSpace(); QString def = defaultEmail(); QString emailsStr = find( Qtopia::Emails ); QStringList emails = emailList(); // otherwise, must first contain it if ( !emailsStr.contains( e ) ) return ; // remove it //qDebug(" removing email from list %s", e.latin1()); emails.remove( e ); // reset the string emailsStr = emails.join( emailSeparator() ); // Sharp's brain dead separator replace( Qtopia::Emails, emailsStr ); // if default, then replace the default email with the first one if ( def == e ) { //qDebug("removeEmail is default; setting new default"); if ( !emails.count() ) clearEmails(); else // setDefaultEmail will remove e from the list setDefaultEmail( emails.first() ); } } void OPimContact::clearEmails() { mMap.remove( Qtopia::DefaultEmail ); mMap.remove( Qtopia::Emails ); } void OPimContact::setDefaultEmail( const QString &v ) { QString e = v.simplifyWhiteSpace(); //qDebug("OPimContact::setDefaultEmail %s", e.latin1()); replace( Qtopia::DefaultEmail, e ); if ( !e.isEmpty() ) insertEmail( e ); } void OPimContact::insertEmails( const QStringList &v ) { for ( QStringList::ConstIterator it = v.begin(); it != v.end(); ++it ) insertEmail( *it ); } int OPimContact::rtti() { return OPimResolver::AddressBook; } void OPimContact::setUid( int i ) { OPimRecord::setUid( i ); replace( Qtopia::AddressUid , QString::number( i ) ); } } diff --git a/libopie2/opiepim/core/opimcontactfields.cpp b/libopie2/opiepim/core/opimcontactfields.cpp index 4b0ba3b..120beb6 100644 --- a/libopie2/opiepim/core/opimcontactfields.cpp +++ b/libopie2/opiepim/core/opimcontactfields.cpp @@ -1,518 +1,516 @@ /* This file is part of the Opie Project Copyright (C) Stefan Eilers <eilers.stefan@epost.de> =. Copyright (C) The Opie Team <opie-devel@handhelds.org> .=l. .>+-= _;:, .> :=|. 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; either version 2 of the License, ._= =} : or (at your option) any later version. .%`+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 "opimcontactfields.h" /* OPIE */ #include <opie2/opimcontact.h> -#include <qpe/recordfields.h> // We should use our own enum in the future .. #include <qpe/config.h> /* QT */ #include <qobject.h> -#include <qstringlist.h> namespace Opie { /*! \internal Returns a list of personal field names for a contact. */ QStringList OPimContactFields::personalfields( bool sorted, bool translated ) { QStringList list; QMap<int, QString> mapIdToStr; if ( translated ) mapIdToStr = idToTrFields(); else mapIdToStr = idToUntrFields(); list.append( mapIdToStr[ Qtopia::AddressUid ] ); list.append( mapIdToStr[ Qtopia::AddressCategory ] ); list.append( mapIdToStr[ Qtopia::Title ] ); list.append( mapIdToStr[ Qtopia::FirstName ] ); list.append( mapIdToStr[ Qtopia::MiddleName ] ); list.append( mapIdToStr[ Qtopia::LastName ] ); list.append( mapIdToStr[ Qtopia::Suffix ] ); list.append( mapIdToStr[ Qtopia::FileAs ] ); list.append( mapIdToStr[ Qtopia::JobTitle ] ); list.append( mapIdToStr[ Qtopia::Department ] ); list.append( mapIdToStr[ Qtopia::Company ] ); list.append( mapIdToStr[ Qtopia::Notes ] ); list.append( mapIdToStr[ Qtopia::Groups ] ); if ( sorted ) list.sort(); return list; } /*! \internal Returns a list of details field names for a contact. */ QStringList OPimContactFields::detailsfields( bool sorted, bool translated ) { QStringList list; QMap<int, QString> mapIdToStr; if ( translated ) mapIdToStr = idToTrFields(); else mapIdToStr = idToUntrFields(); list.append( mapIdToStr[ Qtopia::Office ] ); list.append( mapIdToStr[ Qtopia::Profession ] ); list.append( mapIdToStr[ Qtopia::Assistant ] ); list.append( mapIdToStr[ Qtopia::Manager ] ); list.append( mapIdToStr[ Qtopia::Spouse ] ); list.append( mapIdToStr[ Qtopia::Gender ] ); list.append( mapIdToStr[ Qtopia::Birthday ] ); list.append( mapIdToStr[ Qtopia::Anniversary ] ); list.append( mapIdToStr[ Qtopia::Nickname ] ); list.append( mapIdToStr[ Qtopia::Children ] ); if ( sorted ) list.sort(); return list; } /*! \internal Returns a list of phone field names for a contact. */ QStringList OPimContactFields::phonefields( bool sorted, bool translated ) { QStringList list; QMap<int, QString> mapIdToStr; if ( translated ) mapIdToStr = idToTrFields(); else mapIdToStr = idToUntrFields(); list.append( mapIdToStr[ Qtopia::BusinessPhone ] ); list.append( mapIdToStr[ Qtopia::BusinessFax ] ); list.append( mapIdToStr[ Qtopia::BusinessMobile ] ); list.append( mapIdToStr[ Qtopia::BusinessPager ] ); list.append( mapIdToStr[ Qtopia::BusinessWebPage ] ); list.append( mapIdToStr[ Qtopia::DefaultEmail ] ); list.append( mapIdToStr[ Qtopia::Emails ] ); list.append( mapIdToStr[ Qtopia::HomePhone ] ); list.append( mapIdToStr[ Qtopia::HomeFax ] ); list.append( mapIdToStr[ Qtopia::HomeMobile ] ); // list.append( mapIdToStr[Qtopia::HomePager] ); list.append( mapIdToStr[ Qtopia::HomeWebPage ] ); if ( sorted ) list.sort(); return list; } /*! \internal Returns a list of field names for a contact. */ QStringList OPimContactFields::fields( bool sorted, bool translated ) { QStringList list; QMap<int, QString> mapIdToStr; if ( translated ) mapIdToStr = idToTrFields(); else mapIdToStr = idToUntrFields(); list += personalfields( sorted, translated ); list += phonefields( sorted, translated ); list.append( mapIdToStr[ Qtopia::BusinessStreet ] ); list.append( mapIdToStr[ Qtopia::BusinessCity ] ); list.append( mapIdToStr[ Qtopia::BusinessState ] ); list.append( mapIdToStr[ Qtopia::BusinessZip ] ); list.append( mapIdToStr[ Qtopia::BusinessCountry ] ); list.append( mapIdToStr[ Qtopia::HomeStreet ] ); list.append( mapIdToStr[ Qtopia::HomeCity ] ); list.append( mapIdToStr[ Qtopia::HomeState ] ); list.append( mapIdToStr[ Qtopia::HomeZip ] ); list.append( mapIdToStr[ Qtopia::HomeCountry ] ); list += detailsfields( sorted, translated ); if ( sorted ) list.sort(); return list; } /*! \internal Returns an untranslated list of personal field names for a contact. */ QStringList OPimContactFields::untrpersonalfields( bool sorted ) { return personalfields( sorted, false ); } /*! \internal Returns a translated list of personal field names for a contact. */ QStringList OPimContactFields::trpersonalfields( bool sorted ) { return personalfields( sorted, true ); } /*! \internal Returns an untranslated list of details field names for a contact. */ QStringList OPimContactFields::untrdetailsfields( bool sorted ) { return detailsfields( sorted, false ); } /*! \internal Returns a translated list of details field names for a contact. */ QStringList OPimContactFields::trdetailsfields( bool sorted ) { return detailsfields( sorted, true ); } /*! \internal Returns a translated list of phone field names for a contact. */ QStringList OPimContactFields::trphonefields( bool sorted ) { return phonefields( sorted, true ); } /*! \internal Returns an untranslated list of phone field names for a contact. */ QStringList OPimContactFields::untrphonefields( bool sorted ) { return phonefields( sorted, false ); } /*! \internal Returns a translated list of field names for a contact. */ QStringList OPimContactFields::trfields( bool sorted ) { return fields( sorted, true ); } /*! \internal Returns an untranslated list of field names for a contact. */ QStringList OPimContactFields::untrfields( bool sorted ) { return fields( sorted, false ); } QMap<int, QString> OPimContactFields::idToTrFields() { QMap<int, QString> ret_map; ret_map.insert( Qtopia::AddressUid, QObject::tr( "User Id" ) ); ret_map.insert( Qtopia::AddressCategory, QObject::tr( "Categories" ) ); ret_map.insert( Qtopia::Title, QObject::tr( "Name Title" ) ); ret_map.insert( Qtopia::FirstName, QObject::tr( "First Name" ) ); ret_map.insert( Qtopia::MiddleName, QObject::tr( "Middle Name" ) ); ret_map.insert( Qtopia::LastName, QObject::tr( "Last Name" ) ); ret_map.insert( Qtopia::Suffix, QObject::tr( "Suffix" ) ); ret_map.insert( Qtopia::FileAs, QObject::tr( "File As" ) ); ret_map.insert( Qtopia::JobTitle, QObject::tr( "Job Title" ) ); ret_map.insert( Qtopia::Department, QObject::tr( "Department" ) ); ret_map.insert( Qtopia::Company, QObject::tr( "Company" ) ); ret_map.insert( Qtopia::BusinessPhone, QObject::tr( "Business Phone" ) ); ret_map.insert( Qtopia::BusinessFax, QObject::tr( "Business Fax" ) ); ret_map.insert( Qtopia::BusinessMobile, QObject::tr( "Business Mobile" ) ); // email ret_map.insert( Qtopia::DefaultEmail, QObject::tr( "Default Email" ) ); ret_map.insert( Qtopia::Emails, QObject::tr( "Emails" ) ); ret_map.insert( Qtopia::HomePhone, QObject::tr( "Home Phone" ) ); ret_map.insert( Qtopia::HomeFax, QObject::tr( "Home Fax" ) ); ret_map.insert( Qtopia::HomeMobile, QObject::tr( "Home Mobile" ) ); // business ret_map.insert( Qtopia::BusinessStreet, QObject::tr( "Business Street" ) ); ret_map.insert( Qtopia::BusinessCity, QObject::tr( "Business City" ) ); ret_map.insert( Qtopia::BusinessState, QObject::tr( "Business State" ) ); ret_map.insert( Qtopia::BusinessZip, QObject::tr( "Business Zip" ) ); ret_map.insert( Qtopia::BusinessCountry, QObject::tr( "Business Country" ) ); ret_map.insert( Qtopia::BusinessPager, QObject::tr( "Business Pager" ) ); ret_map.insert( Qtopia::BusinessWebPage, QObject::tr( "Business WebPage" ) ); ret_map.insert( Qtopia::Office, QObject::tr( "Office" ) ); ret_map.insert( Qtopia::Profession, QObject::tr( "Profession" ) ); ret_map.insert( Qtopia::Assistant, QObject::tr( "Assistant" ) ); ret_map.insert( Qtopia::Manager, QObject::tr( "Manager" ) ); // home ret_map.insert( Qtopia::HomeStreet, QObject::tr( "Home Street" ) ); ret_map.insert( Qtopia::HomeCity, QObject::tr( "Home City" ) ); ret_map.insert( Qtopia::HomeState, QObject::tr( "Home State" ) ); ret_map.insert( Qtopia::HomeZip, QObject::tr( "Home Zip" ) ); ret_map.insert( Qtopia::HomeCountry, QObject::tr( "Home Country" ) ); ret_map.insert( Qtopia::HomeWebPage, QObject::tr( "Home Web Page" ) ); //personal ret_map.insert( Qtopia::Spouse, QObject::tr( "Spouse" ) ); ret_map.insert( Qtopia::Gender, QObject::tr( "Gender" ) ); ret_map.insert( Qtopia::Birthday, QObject::tr( "Birthday" ) ); ret_map.insert( Qtopia::Anniversary, QObject::tr( "Anniversary" ) ); ret_map.insert( Qtopia::Nickname, QObject::tr( "Nickname" ) ); ret_map.insert( Qtopia::Children, QObject::tr( "Children" ) ); // other ret_map.insert( Qtopia::Notes, QObject::tr( "Notes" ) ); return ret_map; } QMap<int, QString> OPimContactFields::idToUntrFields() { QMap<int, QString> ret_map; ret_map.insert( Qtopia::AddressUid, "User Id" ); ret_map.insert( Qtopia::AddressCategory, "Categories" ); ret_map.insert( Qtopia::Title, "Name Title" ); ret_map.insert( Qtopia::FirstName, "First Name" ); ret_map.insert( Qtopia::MiddleName, "Middle Name" ); ret_map.insert( Qtopia::LastName, "Last Name" ); ret_map.insert( Qtopia::Suffix, "Suffix" ); ret_map.insert( Qtopia::FileAs, "File As" ); ret_map.insert( Qtopia::JobTitle, "Job Title" ); ret_map.insert( Qtopia::Department, "Department" ); ret_map.insert( Qtopia::Company, "Company" ); ret_map.insert( Qtopia::BusinessPhone, "Business Phone" ); ret_map.insert( Qtopia::BusinessFax, "Business Fax" ); ret_map.insert( Qtopia::BusinessMobile, "Business Mobile" ); // email ret_map.insert( Qtopia::DefaultEmail, "Default Email" ); ret_map.insert( Qtopia::Emails, "Emails" ); ret_map.insert( Qtopia::HomePhone, "Home Phone" ); ret_map.insert( Qtopia::HomeFax, "Home Fax" ); ret_map.insert( Qtopia::HomeMobile, "Home Mobile" ); // business ret_map.insert( Qtopia::BusinessStreet, "Business Street" ); ret_map.insert( Qtopia::BusinessCity, "Business City" ); ret_map.insert( Qtopia::BusinessState, "Business State" ); ret_map.insert( Qtopia::BusinessZip, "Business Zip" ); ret_map.insert( Qtopia::BusinessCountry, "Business Country" ); ret_map.insert( Qtopia::BusinessPager, "Business Pager" ); ret_map.insert( Qtopia::BusinessWebPage, "Business WebPage" ); ret_map.insert( Qtopia::Office, "Office" ); ret_map.insert( Qtopia::Profession, "Profession" ); ret_map.insert( Qtopia::Assistant, "Assistant" ); ret_map.insert( Qtopia::Manager, "Manager" ); // home ret_map.insert( Qtopia::HomeStreet, "Home Street" ); ret_map.insert( Qtopia::HomeCity, "Home City" ); ret_map.insert( Qtopia::HomeState, "Home State" ); ret_map.insert( Qtopia::HomeZip, "Home Zip" ); ret_map.insert( Qtopia::HomeCountry, "Home Country" ); ret_map.insert( Qtopia::HomeWebPage, "Home Web Page" ); //personal ret_map.insert( Qtopia::Spouse, "Spouse" ); ret_map.insert( Qtopia::Gender, "Gender" ); ret_map.insert( Qtopia::Birthday, "Birthday" ); ret_map.insert( Qtopia::Anniversary, "Anniversary" ); ret_map.insert( Qtopia::Nickname, "Nickname" ); ret_map.insert( Qtopia::Children, "Children" ); // other ret_map.insert( Qtopia::Notes, "Notes" ); ret_map.insert( Qtopia::Groups, "Groups" ); return ret_map; } QMap<QString, int> OPimContactFields::trFieldsToId() { QMap<int, QString> idtostr = idToTrFields(); QMap<QString, int> ret_map; QMap<int, QString>::Iterator it; for ( it = idtostr.begin(); it != idtostr.end(); ++it ) ret_map.insert( *it, it.key() ); return ret_map; } /* ======================================================================= */ QMap<QString, int> OPimContactFields::untrFieldsToId() { QMap<int, QString> idtostr = idToUntrFields(); QMap<QString, int> ret_map; QMap<int, QString>::Iterator it; for ( it = idtostr.begin(); it != idtostr.end(); ++it ) ret_map.insert( *it, it.key() ); return ret_map; } OPimContactFields::OPimContactFields() : fieldOrder( DEFAULT_FIELD_ORDER ), changedFieldOrder( false ) { // Get the global field order from the config file and // use it as a start pattern Config cfg ( "AddressBook" ); cfg.setGroup( "ContactFieldOrder" ); globalFieldOrder = cfg.readEntry( "General", DEFAULT_FIELD_ORDER ); } OPimContactFields::~OPimContactFields() { // We will store the fieldorder into the config file // to reuse it for the future.. if ( changedFieldOrder ) { Config cfg ( "AddressBook" ); cfg.setGroup( "ContactFieldOrder" ); cfg.writeEntry( "General", globalFieldOrder ); } } void OPimContactFields::saveToRecord( OPimContact &cnt ) { qDebug( "ocontactfields saveToRecord: >%s<", fieldOrder.latin1() ); // Store fieldorder into this contact. cnt.setCustomField( CONTACT_FIELD_ORDER_NAME, fieldOrder ); globalFieldOrder = fieldOrder; changedFieldOrder = true; } void OPimContactFields::loadFromRecord( const OPimContact &cnt ) { qDebug( "ocontactfields loadFromRecord" ); qDebug( "loading >%s<", cnt.fullName().latin1() ); // Get fieldorder for this contact. If none is defined, // we will use the global one from the config file.. fieldOrder = cnt.customField( CONTACT_FIELD_ORDER_NAME ); qDebug( "fieldOrder from contact>%s<", fieldOrder.latin1() ); if ( fieldOrder.isEmpty() ) { fieldOrder = globalFieldOrder; } qDebug( "effective fieldOrder in loadFromRecord >%s<", fieldOrder.latin1() ); } void OPimContactFields::setFieldOrder( int num, int index ) { qDebug( "qcontactfields setfieldorder pos %i -> %i", num, index ); fieldOrder[ num ] = QString::number( index, 16 ) [ 0 ]; // We will store this new fieldorder globally to // remember it for contacts which have none globalFieldOrder = fieldOrder; changedFieldOrder = true; qDebug( "fieldOrder >%s<", fieldOrder.latin1() ); } int OPimContactFields::getFieldOrder( int num, int defIndex ) { qDebug( "ocontactfields getFieldOrder" ); qDebug( "fieldOrder >%s<", fieldOrder.latin1() ); // Get index of combo as char.. QChar poschar = fieldOrder[ num ]; bool ok; int ret = 0; // Convert char to number.. if ( !( poschar == QChar::null ) ) ret = QString( poschar ).toInt( &ok, 16 ); else ok = false; // Return default value if index for // num was not set or if anything else happened.. if ( !ok ) ret = defIndex; qDebug( "returning >%i<", ret ); return ret; } } diff --git a/libopie2/opiepim/core/opimevent.cpp b/libopie2/opiepim/core/opimevent.cpp index 3ddbf85..77730e9 100644 --- a/libopie2/opiepim/core/opimevent.cpp +++ b/libopie2/opiepim/core/opimevent.cpp @@ -1,1025 +1,1022 @@ /* This file is part of the Opie Project Copyright (C) Stefan Eilers <Eilers.Stefan@epost.de> =. Copyright (C) The Opie Team <opie-devel@handhelds.org> .=l. .>+-= _;:, .> :=|. 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; either version 2 of the License, ._= =} : or (at your option) any later version. .%`+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 "opimevent.h" /* OPIE */ #include <opie2/opimrecurrence.h> #include <opie2/opimresolver.h> #include <opie2/opimnotifymanager.h> #include <qpe/categories.h> -#include <qpe/palmtopuidgen.h> #include <qpe/stringutil.h> /* QT */ -#include <qshared.h> -#include <qarray.h> namespace Opie { int OCalendarHelper::week( const QDate& date ) { // Calculates the week this date is in within that // month. Equals the "row" is is in in the month view int week = 1; QDate tmp( date.year(), date.month(), 1 ); if ( date.dayOfWeek() < tmp.dayOfWeek() ) ++week; week += ( date.day() - 1 ) / 7; return week; } int OCalendarHelper::ocurrence( const QDate& date ) { // calculates the number of occurrances of this day of the // week till the given date (e.g 3rd Wednesday of the month) return ( date.day() - 1 ) / 7 + 1; } int OCalendarHelper::dayOfWeek( char day ) { int dayOfWeek = 1; char i = OPimRecurrence::MON; while ( !( i & day ) && i <= OPimRecurrence::SUN ) { i <<= 1; ++dayOfWeek; } return dayOfWeek; } int OCalendarHelper::monthDiff( const QDate& first, const QDate& second ) { return ( second.year() - first.year() ) * 12 + second.month() - first.month(); } struct OPimEvent::Data : public QShared { Data() : QShared() { child = 0; recur = 0; manager = 0; isAllDay = false; parent = 0; } ~Data() { delete manager; delete recur; } QString description; QString location; OPimNotifyManager* manager; OPimRecurrence* recur; QString note; QDateTime created; QDateTime start; QDateTime end; bool isAllDay : 1; QString timezone; QArray<int>* child; int parent; }; OPimEvent::OPimEvent( int uid ) : OPimRecord( uid ) { data = new Data; } OPimEvent::OPimEvent( const OPimEvent& ev ) : OPimRecord( ev ), data( ev.data ) { data->ref(); } OPimEvent::OPimEvent( const QMap<int, QString> map ) : OPimRecord( 0 ) { data = new Data; fromMap( map ); } OPimEvent::~OPimEvent() { if ( data->deref() ) { delete data; data = 0; } } OPimEvent& OPimEvent::operator=( const OPimEvent& ev ) { if ( this == &ev ) return * this; OPimRecord::operator=( ev ); ev.data->ref(); deref(); data = ev.data; return *this; } QString OPimEvent::description() const { return data->description; } void OPimEvent::setDescription( const QString& description ) { changeOrModify(); data->description = description; } void OPimEvent::setLocation( const QString& loc ) { changeOrModify(); data->location = loc; } QString OPimEvent::location() const { return data->location; } OPimNotifyManager &OPimEvent::notifiers() const { // I hope we can skip the changeOrModify here // the notifier should take care of it // and OPimNotify is shared too if ( !data->manager ) data->manager = new OPimNotifyManager; return *data->manager; } bool OPimEvent::hasNotifiers() const { if ( !data->manager ) return false; if ( data->manager->reminders().isEmpty() && data->manager->alarms().isEmpty() ) return false; return true; } OPimRecurrence OPimEvent::recurrence() const { if ( !data->recur ) data->recur = new OPimRecurrence; return *data->recur; } void OPimEvent::setRecurrence( const OPimRecurrence& rec ) { changeOrModify(); if ( data->recur ) ( *data->recur ) = rec; else data->recur = new OPimRecurrence( rec ); } bool OPimEvent::hasRecurrence() const { if ( !data->recur ) return false; return data->recur->doesRecur(); } QString OPimEvent::note() const { return data->note; } void OPimEvent::setNote( const QString& note ) { changeOrModify(); data->note = note; } QDateTime OPimEvent::createdDateTime() const { return data->created; } void OPimEvent::setCreatedDateTime( const QDateTime& time ) { changeOrModify(); data->created = time; } QDateTime OPimEvent::startDateTime() const { if ( data->isAllDay ) return QDateTime( data->start.date(), QTime( 0, 0, 0 ) ); return data->start; } QDateTime OPimEvent::startDateTimeInZone() const { /* if no timezone, or all day event or if the current and this timeZone match... */ if ( data->timezone.isEmpty() || data->isAllDay || data->timezone == OPimTimeZone::current().timeZone() ) return startDateTime(); OPimTimeZone zone( data->timezone ); return zone.toDateTime( data->start, OPimTimeZone::current() ); } void OPimEvent::setStartDateTime( const QDateTime& dt ) { changeOrModify(); data->start = dt; } QDateTime OPimEvent::endDateTime() const { /* * if all Day event the end time needs * to be on the same day as the start */ if ( data->isAllDay ) return QDateTime( data->start.date(), QTime( 23, 59, 59 ) ); return data->end; } QDateTime OPimEvent::endDateTimeInZone() const { /* if no timezone, or all day event or if the current and this timeZone match... */ if ( data->timezone.isEmpty() || data->isAllDay || data->timezone == OPimTimeZone::current().timeZone() ) return endDateTime(); OPimTimeZone zone( data->timezone ); return zone.toDateTime( data->end, OPimTimeZone::current() ); } void OPimEvent::setEndDateTime( const QDateTime& dt ) { changeOrModify(); data->end = dt; } bool OPimEvent::isMultipleDay() const { return data->end.date().day() - data->start.date().day(); } bool OPimEvent::isAllDay() const { return data->isAllDay; } void OPimEvent::setAllDay( bool allDay ) { changeOrModify(); data->isAllDay = allDay; if ( allDay ) data->timezone = "UTC"; } void OPimEvent::setTimeZone( const QString& tz ) { changeOrModify(); data->timezone = tz; } QString OPimEvent::timeZone() const { if ( data->isAllDay ) return QString::fromLatin1( "UTC" ); return data->timezone; } bool OPimEvent::match( const QRegExp& re ) const { if ( re.match( data->description ) != -1 ) { setLastHitField( Qtopia::DatebookDescription ); return true; } if ( re.match( data->note ) != -1 ) { setLastHitField( Qtopia::Note ); return true; } if ( re.match( data->location ) != -1 ) { setLastHitField( Qtopia::Location ); return true; } if ( re.match( data->start.toString() ) != -1 ) { setLastHitField( Qtopia::StartDateTime ); return true; } if ( re.match( data->end.toString() ) != -1 ) { setLastHitField( Qtopia::EndDateTime ); return true; } return false; } QString OPimEvent::toRichText() const { QString text, value; // description text += "<b><h3><img src=\"datebook/DateBook\">"; if ( !description().isEmpty() ) { text += Qtopia::escapeString( description() ).replace( QRegExp( "[\n]" ), "" ); } text += "</h3></b><br><hr><br>"; // location if ( !( value = location() ).isEmpty() ) { text += "<b>" + QObject::tr( "Location:" ) + "</b> "; text += Qtopia::escapeString( value ) + "<br>"; } // all day event if ( isAllDay() ) { text += "<b><i>" + QObject::tr( "This is an all day event" ) + "</i></b><br>"; } // multiple day event else if ( isMultipleDay () ) { text += "<b><i>" + QObject::tr( "This is a multiple day event" ) + "</i></b><br>"; } // start & end times else { // start time if ( startDateTime().isValid() ) { text += "<b>" + QObject::tr( "Start:" ) + "</b> "; text += Qtopia::escapeString( startDateTime().toString() ). replace( QRegExp( "[\n]" ), "<br>" ) + "<br>"; } // end time if ( endDateTime().isValid() ) { text += "<b>" + QObject::tr( "End:" ) + "</b> "; text += Qtopia::escapeString( endDateTime().toString() ). replace( QRegExp( "[\n]" ), "<br>" ) + "<br>"; } } // categories if ( categoryNames( "Calendar" ).count() ) { text += "<b>" + QObject::tr( "Category:" ) + "</b> "; text += categoryNames( "Calendar" ).join( ", " ); text += "<br>"; } //notes if ( !note().isEmpty() ) { text += "<b>" + QObject::tr( "Note:" ) + "</b><br>"; text += note(); // text += Qtopia::escapeString(note() ). // replace(QRegExp( "[\n]"), "<br>" ) + "<br>"; } return text; } QString OPimEvent::toShortText() const { QString text; text += QString::number( startDateTime().date().day() ); text += "."; text += QString::number( startDateTime().date().month() ); text += "."; text += QString::number( startDateTime().date().year() ); text += " "; text += QString::number( startDateTime().time().hour() ); text += ":"; text += QString::number( startDateTime().time().minute() ); text += " - "; text += description(); return text; } QString OPimEvent::type() const { return QString::fromLatin1( "OPimEvent" ); } QString OPimEvent::recordField( int /*id */ ) const { return QString::null; } int OPimEvent::rtti() { return OPimResolver::DateBook; } bool OPimEvent::loadFromStream( QDataStream& ) { return true; } bool OPimEvent::saveToStream( QDataStream& ) const { return true; } void OPimEvent::changeOrModify() { if ( data->count != 1 ) { data->deref(); Data* d2 = new Data; d2->description = data->description; d2->location = data->location; if ( data->manager ) d2->manager = new OPimNotifyManager( *data->manager ); if ( data->recur ) d2->recur = new OPimRecurrence( *data->recur ); d2->note = data->note; d2->created = data->created; d2->start = data->start; d2->end = data->end; d2->isAllDay = data->isAllDay; d2->timezone = data->timezone; d2->parent = data->parent; if ( data->child ) { d2->child = new QArray<int>( *data->child ); d2->child->detach(); } data = d2; } } void OPimEvent::deref() { if ( data->deref() ) { delete data; data = 0; } } // Exporting Event data to map. Using the same // encoding as ODateBookAccessBackend_xml does.. // Thus, we could remove the stuff there and use this // for it and for all other places.. // Encoding should happen at one place, only ! (eilers) QMap<int, QString> OPimEvent::toMap() const { QMap<int, QString> retMap; retMap.insert( OPimEvent::FUid, QString::number( uid() ) ); retMap.insert( OPimEvent::FCategories, Qtopia::escapeString( Qtopia::Record::idsToString( categories() ) ) ); retMap.insert( OPimEvent::FDescription, Qtopia::escapeString( description() ) ); retMap.insert( OPimEvent::FLocation, Qtopia::escapeString( location() ) ); retMap.insert( OPimEvent::FType, isAllDay() ? "AllDay" : "" ); OPimAlarm alarm = notifiers().alarms() [ 0 ]; retMap.insert( OPimEvent::FAlarm, QString::number( alarm.dateTime().secsTo( startDateTime() ) / 60 ) ); retMap.insert( OPimEvent::FSound, ( alarm.sound() == OPimAlarm::Loud ) ? "loud" : "silent" ); OPimTimeZone zone( timeZone().isEmpty() ? OPimTimeZone::current() : timeZone() ); retMap.insert( OPimEvent::FStart, QString::number( zone.fromUTCDateTime( zone.toDateTime( startDateTime(), OPimTimeZone::utc() ) ) ) ); retMap.insert( OPimEvent::FEnd, QString::number( zone.fromUTCDateTime( zone.toDateTime( endDateTime(), OPimTimeZone::utc() ) ) ) ); retMap.insert( OPimEvent::FNote, Qtopia::escapeString( note() ) ); retMap.insert( OPimEvent::FTimeZone, timeZone().isEmpty() ? QString( "None" ) : timeZone() ); if ( parent() ) retMap.insert( OPimEvent::FRecParent, QString::number( parent() ) ); if ( children().count() ) { QArray<int> childr = children(); QString buf; for ( uint i = 0; i < childr.count(); i++ ) { if ( i != 0 ) buf += " "; buf += QString::number( childr[ i ] ); } retMap.insert( OPimEvent::FRecChildren, buf ); } // Add recurrence stuff if ( hasRecurrence() ) { OPimRecurrence recur = recurrence(); QMap<int, QString> recFields = recur.toMap(); retMap.insert( OPimEvent::FRType, recFields[ OPimRecurrence::RType ] ); retMap.insert( OPimEvent::FRWeekdays, recFields[ OPimRecurrence::RWeekdays ] ); retMap.insert( OPimEvent::FRPosition, recFields[ OPimRecurrence::RPosition ] ); retMap.insert( OPimEvent::FRFreq, recFields[ OPimRecurrence::RFreq ] ); retMap.insert( OPimEvent::FRHasEndDate, recFields[ OPimRecurrence::RHasEndDate ] ); retMap.insert( OPimEvent::FREndDate, recFields[ OPimRecurrence::EndDate ] ); retMap.insert( OPimEvent::FRCreated, recFields[ OPimRecurrence::Created ] ); retMap.insert( OPimEvent::FRExceptions, recFields[ OPimRecurrence::Exceptions ] ); } else { OPimRecurrence recur = recurrence(); QMap<int, QString> recFields = recur.toMap(); retMap.insert( OPimEvent::FRType, recFields[ OPimRecurrence::RType ] ); } return retMap; } void OPimEvent::fromMap( const QMap<int, QString>& map ) { // We just want to set the UID if it is really stored. if ( !map[ OPimEvent::FUid ].isEmpty() ) setUid( map[ OPimEvent::FUid ].toInt() ); setCategories( idsFromString( map[ OPimEvent::FCategories ] ) ); setDescription( map[ OPimEvent::FDescription ] ); setLocation( map[ OPimEvent::FLocation ] ); if ( map[ OPimEvent::FType ] == "AllDay" ) setAllDay( true ); else setAllDay( false ); int alarmTime = -1; if ( !map[ OPimEvent::FAlarm ].isEmpty() ) alarmTime = map[ OPimEvent::FAlarm ].toInt(); int sound = ( ( map[ OPimEvent::FSound ] == "loud" ) ? OPimAlarm::Loud : OPimAlarm::Silent ); if ( ( alarmTime != -1 ) ) { QDateTime dt = startDateTime().addSecs( -1 * alarmTime * 60 ); OPimAlarm al( sound , dt ); notifiers().add( al ); } if ( !map[ OPimEvent::FTimeZone ].isEmpty() && ( map[ OPimEvent::FTimeZone ] != "None" ) ) { setTimeZone( map[ OPimEvent::FTimeZone ] ); } time_t start = ( time_t ) map[ OPimEvent::FStart ].toLong(); time_t end = ( time_t ) map[ OPimEvent::FEnd ].toLong(); /* AllDay is always in UTC */ if ( isAllDay() ) { OPimTimeZone utc = OPimTimeZone::utc(); setStartDateTime( utc.fromUTCDateTime( start ) ); setEndDateTime ( utc.fromUTCDateTime( end ) ); setTimeZone( "UTC" ); // make sure it is really utc } else { /* to current date time */ // qWarning(" Start is %d", start ); OPimTimeZone zone( timeZone().isEmpty() ? OPimTimeZone::current() : timeZone() ); QDateTime date = zone.toDateTime( start ); qWarning( " Start is %s", date.toString().latin1() ); setStartDateTime( zone.toDateTime( date, OPimTimeZone::current() ) ); date = zone.toDateTime( end ); setEndDateTime ( zone.toDateTime( date, OPimTimeZone::current() ) ); } if ( !map[ OPimEvent::FRecParent ].isEmpty() ) setParent( map[ OPimEvent::FRecParent ].toInt() ); if ( !map[ OPimEvent::FRecChildren ].isEmpty() ) { QStringList list = QStringList::split( ' ', map[ OPimEvent::FRecChildren ] ); for ( QStringList::Iterator it = list.begin(); it != list.end(); ++it ) { addChild( ( *it ).toInt() ); } } // Fill recurrence stuff and put it directly into the OPimRecurrence-Object using fromMap.. if ( !map[ OPimEvent::FRType ].isEmpty() ) { QMap<int, QString> recFields; recFields.insert( OPimRecurrence::RType, map[ OPimEvent::FRType ] ); recFields.insert( OPimRecurrence::RWeekdays, map[ OPimEvent::FRWeekdays ] ); recFields.insert( OPimRecurrence::RPosition, map[ OPimEvent::FRPosition ] ); recFields.insert( OPimRecurrence::RFreq, map[ OPimEvent::FRFreq ] ); recFields.insert( OPimRecurrence::RHasEndDate, map[ OPimEvent::FRHasEndDate ] ); recFields.insert( OPimRecurrence::EndDate, map[ OPimEvent::FREndDate ] ); recFields.insert( OPimRecurrence::Created, map[ OPimEvent::FRCreated ] ); recFields.insert( OPimRecurrence::Exceptions, map[ OPimEvent::FRExceptions ] ); OPimRecurrence recur( recFields ); setRecurrence( recur ); } } int OPimEvent::parent() const { return data->parent; } void OPimEvent::setParent( int uid ) { changeOrModify(); data->parent = uid; } QArray<int> OPimEvent::children() const { if ( !data->child ) return QArray<int>(); else return data->child->copy(); } void OPimEvent::setChildren( const QArray<int>& arr ) { changeOrModify(); if ( data->child ) delete data->child; data->child = new QArray<int>( arr ); data->child->detach(); } void OPimEvent::addChild( int uid ) { changeOrModify(); if ( !data->child ) { data->child = new QArray<int>( 1 ); ( *data->child ) [ 0 ] = uid; } else { int count = data->child->count(); data->child->resize( count + 1 ); ( *data->child ) [ count ] = uid; } } void OPimEvent::removeChild( int uid ) { if ( !data->child || !data->child->contains( uid ) ) return ; changeOrModify(); QArray<int> newAr( data->child->count() - 1 ); int j = 0; uint count = data->child->count(); for ( uint i = 0; i < count; i++ ) { if ( ( *data->child ) [ i ] != uid ) { newAr[ j ] = ( *data->child ) [ i ]; j++; } } ( *data->child ) = newAr; } struct OEffectiveEvent::Data : public QShared { Data() : QShared() {} OPimEvent event; QDate date; QTime start, end; QDate startDate, endDate; bool dates : 1; }; OEffectiveEvent::OEffectiveEvent() { data = new Data; data->date = QDate::currentDate(); data->start = data->end = QTime::currentTime(); data->dates = false; } OEffectiveEvent::OEffectiveEvent( const OPimEvent& ev, const QDate& startDate, Position pos ) { data = new Data; data->event = ev; data->date = startDate; if ( pos & Start ) data->start = ev.startDateTime().time(); else data->start = QTime( 0, 0, 0 ); if ( pos & End ) data->end = ev.endDateTime().time(); else data->end = QTime( 23, 59, 59 ); data->dates = false; } OEffectiveEvent::OEffectiveEvent( const OEffectiveEvent& ev ) { data = ev.data; data->ref(); } OEffectiveEvent::~OEffectiveEvent() { if ( data->deref() ) { delete data; data = 0; } } OEffectiveEvent& OEffectiveEvent::operator=( const OEffectiveEvent& ev ) { if ( *this == ev ) return * this; ev.data->ref(); deref(); data = ev.data; return *this; } void OEffectiveEvent::setStartTime( const QTime& ti ) { changeOrModify(); data->start = ti; } void OEffectiveEvent::setEndTime( const QTime& en ) { changeOrModify(); data->end = en; } void OEffectiveEvent::setEvent( const OPimEvent& ev ) { changeOrModify(); data->event = ev; } void OEffectiveEvent::setDate( const QDate& da ) { changeOrModify(); data->date = da; } void OEffectiveEvent::setEffectiveDates( const QDate& from, const QDate& to ) { if ( !from.isValid() ) { data->dates = false; return ; } data->startDate = from; data->endDate = to; } QString OEffectiveEvent::description() const { return data->event.description(); } QString OEffectiveEvent::location() const { return data->event.location(); } QString OEffectiveEvent::note() const { return data->event.note(); } OPimEvent OEffectiveEvent::event() const { return data->event; } QTime OEffectiveEvent::startTime() const { return data->start; } QTime OEffectiveEvent::endTime() const { return data->end; } QDate OEffectiveEvent::date() const { return data->date; } int OEffectiveEvent::length() const { return ( data->end.hour() * 60 - data->start.hour() * 60 ) + QABS( data->start.minute() - data->end.minute() ); } int OEffectiveEvent::size() const { return ( data->end.hour() - data->start.hour() ) * 3600 + ( data->end.minute() - data->start.minute() * 60 + data->end.second() - data->start.second() ); } QDate OEffectiveEvent::startDate() const { if ( data->dates ) return data->startDate; else if ( data->event.hasRecurrence() ) // single day, since multi-day should have a d pointer return data->date; else return data->event.startDateTime().date(); } QDate OEffectiveEvent::endDate() const { if ( data->dates ) return data->endDate; else if ( data->event.hasRecurrence() ) return data->date; else return data->event.endDateTime().date(); } void OEffectiveEvent::deref() { if ( data->deref() ) { delete data; data = 0; } } void OEffectiveEvent::changeOrModify() { if ( data->count != 1 ) { data->deref(); Data* d2 = new Data; d2->event = data->event; d2->date = data->date; d2->start = data->start; d2->end = data->end; d2->startDate = data->startDate; d2->endDate = data->endDate; d2->dates = data->dates; data = d2; } } bool OEffectiveEvent::operator<( const OEffectiveEvent &e ) const { if ( data->date < e.date() ) return TRUE; if ( data->date == e.date() ) return ( startTime() < e.startTime() ); else return FALSE; } bool OEffectiveEvent::operator<=( const OEffectiveEvent &e ) const { return ( data->date <= e.date() ); } bool OEffectiveEvent::operator==( const OEffectiveEvent &e ) const { return ( date() == e.date() && startTime() == e.startTime() && endTime() == e.endTime() && event() == e.event() ); } bool OEffectiveEvent::operator!=( const OEffectiveEvent &e ) const { return !( *this == e ); } bool OEffectiveEvent::operator>( const OEffectiveEvent &e ) const { return !( *this <= e ); } bool OEffectiveEvent::operator>= ( const OEffectiveEvent &e ) const { return !( *this < e ); } } diff --git a/libopie2/opiepim/core/opimnotify.cpp b/libopie2/opiepim/core/opimnotify.cpp index 43858f0..417b0b9 100644 --- a/libopie2/opiepim/core/opimnotify.cpp +++ b/libopie2/opiepim/core/opimnotify.cpp @@ -1,379 +1,378 @@ /* This file is part of the Opie Project Copyright (C) The Main Author <main-author@whereever.org> =. Copyright (C) The Opie Team <opie-devel@handhelds.org> .=l. .>+-= _;:, .> :=|. 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; either version 2 of the License, ._= =} : or (at your option) any later version. .%`+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 "opimnotify.h" /* QT */ -#include <qshared.h> namespace Opie { struct OPimNotify::Data : public QShared { Data() : QShared(), dur( -1 ), parent( 0 ) { } QDateTime start; int dur; QString application; int parent; }; OPimNotify::OPimNotify( const QDateTime& start, int duration, int parent ) { data = new Data; data->start = start; data->dur = duration; data->parent = parent; } OPimNotify::OPimNotify( const OPimNotify& noti ) : data( noti.data ) { data->ref(); } OPimNotify::~OPimNotify() { if ( data->deref() ) { delete data; data = 0l; } } OPimNotify &OPimNotify::operator=( const OPimNotify& noti ) { noti.data->ref(); deref(); data = noti.data; return *this; } bool OPimNotify::operator==( const OPimNotify& noti ) { if ( data == noti.data ) return true; if ( data->dur != noti.data->dur ) return false; if ( data->parent != noti.data->parent ) return false; if ( data->application != noti.data->application ) return false; if ( data->start != noti.data->start ) return false; return true; } QDateTime OPimNotify::dateTime() const { return data->start; } QString OPimNotify::service() const { return data->application; } int OPimNotify::parent() const { return data->parent; } int OPimNotify::duration() const { return data->dur; } QDateTime OPimNotify::endTime() const { return QDateTime( data->start.date(), data->start.time().addSecs( data->dur ) ); } void OPimNotify::setDateTime( const QDateTime& time ) { copyIntern(); data->start = time; } void OPimNotify::setDuration( int dur ) { copyIntern(); data->dur = dur; } void OPimNotify::setParent( int uid ) { copyIntern(); data->parent = uid; } void OPimNotify::setService( const QString& str ) { copyIntern(); data->application = str; } void OPimNotify::copyIntern() { if ( data->count != 1 ) { data->deref(); Data* dat = new Data; dat->start = data->start; dat->dur = data->dur; dat->application = data->application; dat->parent = data->parent; data = dat; } } void OPimNotify::deref() { if ( data->deref() ) { delete data; data = 0; } } /***********************************************************/ struct OPimAlarm::Data : public QShared { Data() : QShared() { sound = 1; } int sound; QString file; }; OPimAlarm::OPimAlarm( int sound, const QDateTime& start, int duration, int parent ) : OPimNotify( start, duration, parent ) { data = new Data; data->sound = sound; } OPimAlarm::OPimAlarm( const OPimAlarm& al ) : OPimNotify( al ), data( al.data ) { data->ref(); } OPimAlarm::~OPimAlarm() { if ( data->deref() ) { delete data; data = 0l; } } OPimAlarm &OPimAlarm::operator=( const OPimAlarm& al ) { OPimNotify::operator=( al ); deref(); al.data->ref(); data = al.data; return *this; } bool OPimAlarm::operator==( const OPimAlarm& al ) { if ( data->sound != al.data->sound ) return false; else if ( data->sound == Custom && data->file != al.data->file ) return false; return OPimNotify::operator==( al ); } QString OPimAlarm::type() const { return QString::fromLatin1( "OPimAlarm" ); } int OPimAlarm::sound() const { return data->sound; } QString OPimAlarm::file() const { return data->file; } void OPimAlarm::setSound( int snd ) { copyIntern(); data->sound = snd; } void OPimAlarm::setFile( const QString& sound ) { copyIntern(); data->file = sound; } void OPimAlarm::deref() { if ( data->deref() ) { delete data; data = 0l; } } void OPimAlarm::copyIntern() { if ( data->count != 1 ) { data->deref(); Data *newDat = new Data; newDat->sound = data->sound; newDat->file = data->file; data = newDat; } } /************************/ struct OPimReminder::Data : public QShared { Data() : QShared(), record( 0 ) {} int record; }; OPimReminder::OPimReminder( int uid, const QDateTime& start, int dur, int parent ) : OPimNotify( start, dur, parent ) { data = new Data; data->record = uid; } OPimReminder::OPimReminder( const OPimReminder& rem ) : OPimNotify( rem ), data( rem.data ) { data->ref(); } OPimReminder& OPimReminder::operator=( const OPimReminder& rem ) { OPimNotify::operator=( rem ); deref(); rem.data->ref(); data = rem.data; return *this; } bool OPimReminder::operator==( const OPimReminder& rem ) { if ( data->record != rem.data->record ) return false; return OPimNotify::operator==( rem ); } QString OPimReminder::type() const { return QString::fromLatin1( "OPimReminder" ); } int OPimReminder::recordUid() const { return data->record; } void OPimReminder::setRecordUid( int uid ) { copyIntern(); data->record = uid; } void OPimReminder::deref() { if ( data->deref() ) { delete data; data = 0l; } } void OPimReminder::copyIntern() { if ( data->count != 1 ) { Data * da = new Data; da->record = data->record; data = da; } } } diff --git a/libopie2/opiepim/core/opimrecord.cpp b/libopie2/opiepim/core/opimrecord.cpp index c603f44..67eed41 100644 --- a/libopie2/opiepim/core/opimrecord.cpp +++ b/libopie2/opiepim/core/opimrecord.cpp @@ -1,274 +1,273 @@ /* This file is part of the Opie Project Copyright (C) The Main Author <main-author@whereever.org> =. Copyright (C) The Opie Team <opie-devel@handhelds.org> .=l. .>+-= _;:, .> :=|. 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; either version 2 of the License, ._= =} : or (at your option) any later version. .%`+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 "opimrecord.h" /* OPIE */ #include <qpe/categories.h> #include <qpe/categoryselect.h> /* QT */ -#include <qarray.h> namespace Opie { Qtopia::UidGen OPimRecord::m_uidGen( Qtopia::UidGen::Qtopia ); OPimRecord::OPimRecord( int uid ) : Qtopia::Record() { m_lastHit = -1; setUid( uid ); } OPimRecord::~OPimRecord() {} OPimRecord::OPimRecord( const OPimRecord& rec ) : Qtopia::Record( rec ) { ( *this ) = rec; } OPimRecord &OPimRecord::operator=( const OPimRecord& rec ) { if ( this == &rec ) return * this; Qtopia::Record::operator=( rec ); m_xrefman = rec.m_xrefman; m_lastHit = rec.m_lastHit; return *this; } /* * category names */ QStringList OPimRecord::categoryNames( const QString& appname ) const { QStringList list; QArray<int> cats = categories(); Categories catDB; catDB.load( categoryFileName() ); for ( uint i = 0; i < cats.count(); i++ ) { list << catDB.label( appname, cats[ i ] ); } return list; } void OPimRecord::setCategoryNames( const QStringList& ) { } void OPimRecord::addCategoryName( const QString& ) { Categories catDB; catDB.load( categoryFileName() ); } bool OPimRecord::isEmpty() const { return ( uid() == 0 ); } /*QString OPimRecord::crossToString()const { QString str; QMap<QString, QArray<int> >::ConstIterator it; for (it = m_relations.begin(); it != m_relations.end(); ++it ) { QArray<int> id = it.data(); for ( uint i = 0; i < id.size(); ++i ) { str += it.key() + "," + QString::number( i ) + ";"; } } str = str.remove( str.length()-1, 1); // strip the ; //qWarning("IDS " + str ); return str; }*/ /* if uid = 1 assign a new one */ void OPimRecord::setUid( int uid ) { if ( uid == 1 ) uid = uidGen().generate(); Qtopia::Record::setUid( uid ); }; Qtopia::UidGen &OPimRecord::uidGen() { return m_uidGen; } OPimXRefManager &OPimRecord::xrefmanager() { return m_xrefman; } int OPimRecord::rtti() { return 0; } /** * now let's put our data into the stream */ /* * First read UID * Categories * XRef */ bool OPimRecord::loadFromStream( QDataStream& stream ) { int Int; uint UInt; stream >> Int; setUid( Int ); /** Categories */ stream >> UInt; QArray<int> array( UInt ); for ( uint i = 0; i < UInt; i++ ) { stream >> array[ i ]; } setCategories( array ); /* * now we do the X-Ref stuff */ OPimXRef xref; stream >> UInt; for ( uint i = 0; i < UInt; i++ ) { xref.setPartner( OPimXRef::One, partner( stream ) ); xref.setPartner( OPimXRef::Two, partner( stream ) ); m_xrefman.add( xref ); } return true; } bool OPimRecord::saveToStream( QDataStream& stream ) const { /** UIDs */ stream << uid(); /** Categories */ stream << categories().count(); for ( uint i = 0; i < categories().count(); i++ ) { stream << categories() [ i ]; } /* * first the XRef count * then the xrefs */ stream << m_xrefman.list().count(); for ( OPimXRef::ValueList::ConstIterator it = m_xrefman.list().begin(); it != m_xrefman.list().end(); ++it ) { flush( ( *it ).partner( OPimXRef::One ), stream ); flush( ( *it ).partner( OPimXRef::Two ), stream ); } return true; } void OPimRecord::flush( const OPimXRefPartner& par, QDataStream& str ) const { str << par.service(); str << par.uid(); str << par.field(); } OPimXRefPartner OPimRecord::partner( QDataStream& stream ) { OPimXRefPartner par; QString str; int i; stream >> str; par.setService( str ); stream >> i; par.setUid( i ); stream >> i ; par.setField( i ); return par; } void OPimRecord::setLastHitField( int lastHit ) const { m_lastHit = lastHit; } int OPimRecord::lastHitField() const { return m_lastHit; } QMap<QString, QString> OPimRecord::toExtraMap() const { return customMap; } void OPimRecord::setExtraMap( const QMap<QString, QString>& map ) { customMap = map; } } diff --git a/libopie2/opiepim/core/opimtodo.cpp b/libopie2/opiepim/core/opimtodo.cpp index 34df807..f246bfd 100644 --- a/libopie2/opiepim/core/opimtodo.cpp +++ b/libopie2/opiepim/core/opimtodo.cpp @@ -1,712 +1,711 @@ /* This file is part of the Opie Project Copyright (C) The Main Author <main-author@whereever.org> =. Copyright (C) The Opie Team <opie-devel@handhelds.org> .=l. .>+-= _;:, .> :=|. 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; either version 2 of the License, ._= =} : or (at your option) any later version. .%`+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 "opimtodo.h" /* OPIE */ #include <opie2/opimstate.h> #include <opie2/opimrecurrence.h> #include <opie2/opimmaintainer.h> #include <opie2/opimnotifymanager.h> #include <opie2/opimresolver.h> #include <qpe/palmtopuidgen.h> -#include <qpe/stringutil.h> #include <qpe/palmtoprecord.h> -#include <qpe/stringutil.h> #include <qpe/categories.h> #include <qpe/categoryselect.h> +#include <qpe/stringutil.h> /* QT */ #include <qobject.h> #include <qshared.h> namespace Opie { struct OPimTodo::OPimTodoData : public QShared { OPimTodoData() : QShared() { recur = 0; state = 0; maintainer = 0; notifiers = 0; }; ~OPimTodoData() { delete recur; delete maintainer; delete notifiers; } QDate date; bool isCompleted: 1; bool hasDate: 1; int priority; QString desc; QString sum; QMap<QString, QString> extra; ushort prog; OPimState *state; OPimRecurrence *recur; OPimMaintainer *maintainer; QDate start; QDate completed; OPimNotifyManager *notifiers; }; OPimTodo::OPimTodo( const OPimTodo &event ) : OPimRecord( event ), data( event.data ) { data->ref(); // qWarning("ref up"); } OPimTodo::~OPimTodo() { // qWarning("~OPimTodo " ); if ( data->deref() ) { // qWarning("OPimTodo::dereffing"); delete data; data = 0l; } } OPimTodo::OPimTodo( bool completed, int priority, const QArray<int> &category, const QString& summary, const QString &description, ushort progress, bool hasDate, QDate date, int uid ) : OPimRecord( uid ) { // qWarning("OPimTodoData " + summary); setCategories( category ); data = new OPimTodoData; data->date = date; data->isCompleted = completed; data->hasDate = hasDate; data->priority = priority; data->sum = summary; data->prog = progress; data->desc = Qtopia::simplifyMultiLineSpace( description ); } OPimTodo::OPimTodo( bool completed, int priority, const QStringList &category, const QString& summary, const QString &description, ushort progress, bool hasDate, QDate date, int uid ) : OPimRecord( uid ) { // qWarning("OPimTodoData" + summary); setCategories( idsFromString( category.join( ";" ) ) ); data = new OPimTodoData; data->date = date; data->isCompleted = completed; data->hasDate = hasDate; data->priority = priority; data->sum = summary; data->prog = progress; data->desc = Qtopia::simplifyMultiLineSpace( description ); } bool OPimTodo::match( const QRegExp ®Exp ) const { if ( QString::number( data->priority ).find( regExp ) != -1 ) { setLastHitField( Priority ); return true; } else if ( data->hasDate && data->date.toString().find( regExp ) != -1 ) { setLastHitField( HasDate ); return true; } else if ( data->desc.find( regExp ) != -1 ) { setLastHitField( Description ); return true; } else if ( data->sum.find( regExp ) != -1 ) { setLastHitField( Summary ); return true; } return false; } bool OPimTodo::isCompleted() const { return data->isCompleted; } bool OPimTodo::hasDueDate() const { return data->hasDate; } bool OPimTodo::hasStartDate() const { return data->start.isValid(); } bool OPimTodo::hasCompletedDate() const { return data->completed.isValid(); } int OPimTodo::priority() const { return data->priority; } QString OPimTodo::summary() const { return data->sum; } ushort OPimTodo::progress() const { return data->prog; } QDate OPimTodo::dueDate() const { return data->date; } QDate OPimTodo::startDate() const { return data->start; } QDate OPimTodo::completedDate() const { return data->completed; } QString OPimTodo::description() const { return data->desc; } bool OPimTodo::hasState() const { if ( !data->state ) return false; return ( data->state->state() != OPimState::Undefined ); } OPimState OPimTodo::state() const { if ( !data->state ) { OPimState state; return state; } return ( *data->state ); } bool OPimTodo::hasRecurrence() const { if ( !data->recur ) return false; return data->recur->doesRecur(); } OPimRecurrence OPimTodo::recurrence() const { if ( !data->recur ) return OPimRecurrence(); return ( *data->recur ); } bool OPimTodo::hasMaintainer() const { if ( !data->maintainer ) return false; return ( data->maintainer->mode() != OPimMaintainer::Undefined ); } OPimMaintainer OPimTodo::maintainer() const { if ( !data->maintainer ) return OPimMaintainer(); return ( *data->maintainer ); } void OPimTodo::setCompleted( bool completed ) { changeOrModify(); data->isCompleted = completed; } void OPimTodo::setHasDueDate( bool hasDate ) { changeOrModify(); data->hasDate = hasDate; } void OPimTodo::setDescription( const QString &desc ) { // qWarning( "desc " + desc ); changeOrModify(); data->desc = Qtopia::simplifyMultiLineSpace( desc ); } void OPimTodo::setSummary( const QString& sum ) { changeOrModify(); data->sum = sum; } void OPimTodo::setPriority( int prio ) { changeOrModify(); data->priority = prio; } void OPimTodo::setDueDate( const QDate& date ) { changeOrModify(); data->date = date; } void OPimTodo::setStartDate( const QDate& date ) { changeOrModify(); data->start = date; } void OPimTodo::setCompletedDate( const QDate& date ) { changeOrModify(); data->completed = date; } void OPimTodo::setState( const OPimState& state ) { changeOrModify(); if ( data->state ) ( *data->state ) = state; else data->state = new OPimState( state ); } void OPimTodo::setRecurrence( const OPimRecurrence& rec ) { changeOrModify(); if ( data->recur ) ( *data->recur ) = rec; else data->recur = new OPimRecurrence( rec ); } void OPimTodo::setMaintainer( const OPimMaintainer& pim ) { changeOrModify(); if ( data->maintainer ) ( *data->maintainer ) = pim; else data->maintainer = new OPimMaintainer( pim ); } bool OPimTodo::isOverdue( ) { if ( data->hasDate && !data->isCompleted ) return QDate::currentDate() > data->date; return false; } void OPimTodo::setProgress( ushort progress ) { changeOrModify(); data->prog = progress; } QString OPimTodo::toShortText() const { return summary(); } /*! Returns a richt text string */ QString OPimTodo::toRichText() const { QString text; QStringList catlist; // summary text += "<b><h3><img src=\"todo/TodoList\"> "; if ( !summary().isEmpty() ) { text += Qtopia::escapeString( summary() ).replace( QRegExp( "[\n]" ), "" ); } text += "</h3></b><br><hr><br>"; // description if ( !description().isEmpty() ) { text += "<b>" + QObject::tr( "Description:" ) + "</b><br>"; text += Qtopia::escapeString( description() ).replace( QRegExp( "[\n]" ), "<br>" ) + "<br>"; } // priority int priorityval = priority(); text += "<b>" + QObject::tr( "Priority:" ) + " </b><img src=\"todo/priority" + QString::number( priorityval ) + "\"> "; switch ( priorityval ) { case 1 : text += QObject::tr( "Very high" ); break; case 2 : text += QObject::tr( "High" ); break; case 3 : text += QObject::tr( "Normal" ); break; case 4 : text += QObject::tr( "Low" ); break; case 5 : text += QObject::tr( "Very low" ); break; }; text += "<br>"; // progress text += "<b>" + QObject::tr( "Progress:" ) + " </b>" + QString::number( progress() ) + " %<br>"; // due date if ( hasDueDate() ) { QDate dd = dueDate(); int off = QDate::currentDate().daysTo( dd ); text += "<b>" + QObject::tr( "Deadline:" ) + " </b><font color=\""; if ( off < 0 ) text += "#FF0000"; else if ( off == 0 ) text += "#FFFF00"; else if ( off > 0 ) text += "#00FF00"; text += "\">" + dd.toString() + "</font><br>"; } // categories text += "<b>" + QObject::tr( "Category:" ) + "</b> "; text += categoryNames( "Todo List" ).join( ", " ); text += "<br>"; return text; } bool OPimTodo::hasNotifiers() const { if ( !data->notifiers ) return false; return !data->notifiers->isEmpty(); } OPimNotifyManager& OPimTodo::notifiers() { if ( !data->notifiers ) data->notifiers = new OPimNotifyManager; return ( *data->notifiers ); } const OPimNotifyManager& OPimTodo::notifiers() const { if ( !data->notifiers ) data->notifiers = new OPimNotifyManager; return ( *data->notifiers ); } bool OPimTodo::operator<( const OPimTodo &toDoEvent ) const { if ( !hasDueDate() && !toDoEvent.hasDueDate() ) return true; if ( !hasDueDate() && toDoEvent.hasDueDate() ) return false; if ( hasDueDate() && toDoEvent.hasDueDate() ) { if ( dueDate() == toDoEvent.dueDate() ) { // let's the priority decide return priority() < toDoEvent.priority(); } else { return dueDate() < toDoEvent.dueDate(); } } return false; } bool OPimTodo::operator<=( const OPimTodo &toDoEvent ) const { if ( !hasDueDate() && !toDoEvent.hasDueDate() ) return true; if ( !hasDueDate() && toDoEvent.hasDueDate() ) return true; if ( hasDueDate() && toDoEvent.hasDueDate() ) { if ( dueDate() == toDoEvent.dueDate() ) { // let's the priority decide return priority() <= toDoEvent.priority(); } else { return dueDate() <= toDoEvent.dueDate(); } } return true; } bool OPimTodo::operator>( const OPimTodo &toDoEvent ) const { if ( !hasDueDate() && !toDoEvent.hasDueDate() ) return false; if ( !hasDueDate() && toDoEvent.hasDueDate() ) return false; if ( hasDueDate() && toDoEvent.hasDueDate() ) { if ( dueDate() == toDoEvent.dueDate() ) { // let's the priority decide return priority() > toDoEvent.priority(); } else { return dueDate() > toDoEvent.dueDate(); } } return false; } bool OPimTodo::operator>=( const OPimTodo &toDoEvent ) const { if ( !hasDueDate() && !toDoEvent.hasDueDate() ) return true; if ( !hasDueDate() && toDoEvent.hasDueDate() ) return false; if ( hasDueDate() && toDoEvent.hasDueDate() ) { if ( dueDate() == toDoEvent.dueDate() ) { // let's the priority decide return priority() > toDoEvent.priority(); } else { return dueDate() > toDoEvent.dueDate(); } } return true; } bool OPimTodo::operator==( const OPimTodo &toDoEvent ) const { if ( data->priority != toDoEvent.data->priority ) return false; if ( data->priority != toDoEvent.data->prog ) return false; if ( data->isCompleted != toDoEvent.data->isCompleted ) return false; if ( data->hasDate != toDoEvent.data->hasDate ) return false; if ( data->date != toDoEvent.data->date ) return false; if ( data->sum != toDoEvent.data->sum ) return false; if ( data->desc != toDoEvent.data->desc ) return false; if ( data->maintainer != toDoEvent.data->maintainer ) return false; return OPimRecord::operator==( toDoEvent ); } void OPimTodo::deref() { // qWarning("deref in ToDoEvent"); if ( data->deref() ) { // qWarning("deleting"); delete data; data = 0; } } OPimTodo &OPimTodo::operator=( const OPimTodo &item ) { if ( this == &item ) return * this; OPimRecord::operator=( item ); //qWarning("operator= ref "); item.data->ref(); deref(); data = item.data; return *this; } QMap<int, QString> OPimTodo::toMap() const { QMap<int, QString> map; map.insert( Uid, QString::number( uid() ) ); map.insert( Category, idsToString( categories() ) ); map.insert( HasDate, QString::number( data->hasDate ) ); map.insert( Completed, QString::number( data->isCompleted ) ); map.insert( Description, data->desc ); map.insert( Summary, data->sum ); map.insert( Priority, QString::number( data->priority ) ); map.insert( DateDay, QString::number( data->date.day() ) ); map.insert( DateMonth, QString::number( data->date.month() ) ); map.insert( DateYear, QString::number( data->date.year() ) ); map.insert( Progress, QString::number( data->prog ) ); // map.insert( CrossReference, crossToString() ); /* FIXME!!! map.insert( State, ); map.insert( Recurrence, ); map.insert( Reminders, ); map. */ return map; } /** * change or modify looks at the ref count and either * creates a new QShared Object or it can modify it * right in place */ void OPimTodo::changeOrModify() { if ( data->count != 1 ) { qWarning( "changeOrModify" ); data->deref(); OPimTodoData* d2 = new OPimTodoData(); copy( data, d2 ); data = d2; } } // WATCHOUT /* * if you add something to the Data struct * be sure to copy it here */ void OPimTodo::copy( OPimTodoData* src, OPimTodoData* dest ) { dest->date = src->date; dest->isCompleted = src->isCompleted; dest->hasDate = src->hasDate; dest->priority = src->priority; dest->desc = src->desc; dest->sum = src->sum; dest->extra = src->extra; dest->prog = src->prog; if ( src->state ) dest->state = new OPimState( *src->state ); if ( src->recur ) dest->recur = new OPimRecurrence( *src->recur ); if ( src->maintainer ) dest->maintainer = new OPimMaintainer( *src->maintainer ) ; dest->start = src->start; dest->completed = src->completed; if ( src->notifiers ) dest->notifiers = new OPimNotifyManager( *src->notifiers ); } QString OPimTodo::type() const { return QString::fromLatin1( "OPimTodo" ); } QString OPimTodo::recordField( int /*id*/ ) const { return QString::null; } int OPimTodo::rtti() { return OPimResolver::TodoList; } } diff --git a/libopie2/opieui/ofontselector.cpp b/libopie2/opieui/ofontselector.cpp index 49628c9..49ddeb6 100644 --- a/libopie2/opieui/ofontselector.cpp +++ b/libopie2/opieui/ofontselector.cpp @@ -1,429 +1,428 @@ /* This file is part of the Opie Project Copyright (C) Robert Griebl <sandman@handhelds.org> =. Copyright (C) The Opie Team <opie-devel@handhelds.org> .=l. .>+-= _;:, .> :=|. 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; either version 2 of the License, ._= =} : or (at your option) any later version. .%`+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. */ /* OPIE */ #include <opie2/ofontselector.h> #include <qpe/fontdatabase.h> /* QT */ #include <qlayout.h> #include <qlistbox.h> #include <qcombobox.h> #include <qlabel.h> -#include <qfont.h> #include <qmultilineedit.h> using namespace Opie; namespace Opie { class OFontSelectorPrivate { public: QListBox * m_font_family_list; QComboBox * m_font_style_list; QComboBox * m_font_size_list; QMultiLineEdit *m_preview; bool m_pointbug : 1; FontDatabase m_fdb; }; }; namespace { class FontListItem : public QListBoxText { public: FontListItem ( const QString &t, const QStringList &styles, const QValueList<int> &sizes ) : QListBoxText() { m_name = t; m_styles = styles; m_sizes = sizes; QString str = t; str [0] = str [0]. upper(); setText ( str ); } QString family() const { return m_name; } const QStringList &styles() const { return m_styles; } const QValueList<int> &sizes() const { return m_sizes; } private: QStringList m_styles; QValueList<int> m_sizes; QString m_name; }; static int findItemCB( QComboBox *box, const QString &str ) { for ( int i = 0; i < box->count(); i++ ) { if ( box->text ( i ) == str ) return i; } return -1; } } /* static same as anon. namespace */ static int qt_version() { const char *qver = qVersion(); return ( qver [0] - '0' ) * 100 + ( qver [2] - '0' ) * 10 + ( qver [4] - '0' ); } /** * Constructs the Selector object * @param withpreview If a font preview should be given * @param parent The parent of the Font Selector * @param name The name of the object * @param fl WidgetFlags */ OFontSelector::OFontSelector( bool withpreview, QWidget *parent, const char *name, WFlags fl ) : QWidget ( parent, name, fl ) { d = new OFontSelectorPrivate(); QGridLayout *gridLayout = new QGridLayout( this, 0, 0, 4, 4 ); gridLayout->setRowStretch( 4, 10 ); d->m_font_family_list = new QListBox( this, "FontListBox" ); gridLayout->addMultiCellWidget( d->m_font_family_list, 0, 4, 0, 0 ); connect( d->m_font_family_list, SIGNAL( highlighted( int ) ), this, SLOT( fontFamilyClicked( int ) ) ); QLabel *label = new QLabel( tr( "Style" ), this ); gridLayout->addWidget( label, 0, 1 ); d->m_font_style_list = new QComboBox( this, "StyleListBox" ); connect( d->m_font_style_list, SIGNAL( activated( int ) ), this, SLOT( fontStyleClicked( int ) ) ); gridLayout->addWidget( d->m_font_style_list, 1, 1 ); label = new QLabel( tr( "Size" ), this ); gridLayout->addWidget( label, 2, 1 ); d->m_font_size_list = new QComboBox( this, "SizeListBox" ); connect( d->m_font_size_list, SIGNAL( activated( int ) ), this, SLOT( fontSizeClicked( int ) ) ); gridLayout->addWidget( d->m_font_size_list, 3, 1 ); d->m_pointbug = ( qt_version() <= 233 ); if ( withpreview ) { d->m_preview = new QMultiLineEdit ( this, "Preview" ); d->m_preview->setAlignment ( AlignCenter ); d->m_preview->setWordWrap ( QMultiLineEdit::WidgetWidth ); d->m_preview->setMargin ( 3 ); d->m_preview->setText ( tr( "The Quick Brown Fox Jumps Over The Lazy Dog" )); gridLayout->addRowSpacing ( 5, 4 ); gridLayout->addMultiCellWidget ( d->m_preview, 6, 6, 0, 1 ); gridLayout->setRowStretch ( 6, 5 ); } else d->m_preview = 0; loadFonts ( d->m_font_family_list ); } OFontSelector::~OFontSelector() { delete d; } /** * This methods tries to set the font * @param f The wishes font * @return success or failure */ bool OFontSelector::setSelectedFont ( const QFont &f ) { return setSelectedFont ( f. family(), d->m_fdb. styleString ( f ), f. pointSize(), QFont::encodingName ( f. charSet())); } /** * This is an overloaded method @see setSelectedFont * @param familyStr The family of the font * @param styleStr The style of the font * @param sizeVal The size of font * @param charset The charset to be used. Will be deprecated by QT3 */ bool OFontSelector::setSelectedFont( const QString &familyStr, const QString &styleStr, int sizeVal, const QString & charset ) { QString sizeStr = QString::number ( sizeVal ); QListBoxItem *family = d->m_font_family_list->findItem ( familyStr ); if ( !family ) family = d->m_font_family_list->findItem ( "Helvetica" ); if ( !family ) family = d->m_font_family_list->firstItem(); d->m_font_family_list->setCurrentItem ( family ); fontFamilyClicked ( d->m_font_family_list->index ( family )); int style = findItemCB ( d->m_font_style_list, styleStr ); if ( style < 0 ) style = findItemCB ( d->m_font_style_list, "Regular" ); if ( style < 0 && d->m_font_style_list->count() > 0 ) style = 0; d->m_font_style_list->setCurrentItem ( style ); fontStyleClicked ( style ); int size = findItemCB ( d->m_font_size_list, sizeStr ); if ( size < 0 ) size = findItemCB ( d->m_font_size_list, "10" ); if ( size < 0 && d->m_font_size_list->count() > 0 ) size = 0; d->m_font_size_list->setCurrentItem ( size ); fontSizeClicked ( size ); return (( family ) && ( style >= 0 ) && ( size >= 0 )); } /** * This method returns the name, style and size of the currently selected * font or false if no font is selected * @param family The font family will be written there * @param style The style will be written there * @param size The size will be written there * @return success or failure */ bool OFontSelector::selectedFont ( QString &family, QString &style, int &size ) { QString dummy; return selectedFont ( family, style, size, dummy ); } /** * This method does return the font family or QString::null if there is * no font item selected * @return the font family */ QString OFontSelector::fontFamily() const { FontListItem *fli = (FontListItem *) d->m_font_family_list->item ( d->m_font_family_list->currentItem()); return fli ? fli->family() : QString::null; } /** * This method will return the style of the font or QString::null * @return the style of the font */ QString OFontSelector::fontStyle() const { FontListItem *fli = (FontListItem *) d->m_font_family_list->item ( d->m_font_family_list->currentItem()); int fst = d->m_font_style_list->currentItem(); return ( fli && fst >= 0 ) ? fli->styles() [fst] : QString::null; } /** * This method will return the font size or 10 if no font size is available */ int OFontSelector::fontSize() const { FontListItem *fli = (FontListItem *) d->m_font_family_list->item ( d->m_font_family_list->currentItem()); int fsi = d->m_font_size_list->currentItem(); return ( fli && fsi >= 0 ) ? fli->sizes() [fsi] : 10; } /** * returns the charset of the font or QString::null */ QString OFontSelector::fontCharSet() const { FontListItem *fli = (FontListItem *) d->m_font_family_list->item ( d->m_font_family_list->currentItem()); return fli ? d->m_fdb. charSets ( fli->family()) [0] : QString::null; } /** * Overloaded member function see above * @see selectedFont */ bool OFontSelector::selectedFont ( QString &family, QString &style, int &size, QString &charset ) { int ffa = d->m_font_family_list->currentItem(); int fst = d->m_font_style_list->currentItem(); int fsi = d->m_font_size_list->currentItem(); FontListItem *fli = (FontListItem *) d->m_font_family_list->item ( ffa ); if ( fli ) { family = fli->family(); style = fst >= 0 ? fli->styles() [fst] : QString::null; size = fsi >= 0 ? fli->sizes() [fsi] : 10; charset = d->m_fdb. charSets ( fli->family()) [0]; return true; } else return false; } void OFontSelector::loadFonts ( QListBox *list ) { QStringList f = d->m_fdb. families(); for ( QStringList::ConstIterator it = f. begin(); it != f. end(); ++it ) { QValueList <int> ps = d->m_fdb. pointSizes ( *it ); if ( d->m_pointbug ) { for ( QValueList <int>::Iterator it = ps. begin(); it != ps. end(); it++ ) *it /= 10; } list->insertItem ( new FontListItem ( *it, d->m_fdb. styles ( *it ), ps )); } } void OFontSelector::fontFamilyClicked ( int index ) { QString oldstyle = d->m_font_style_list->currentText(); QString oldsize = d->m_font_size_list->currentText(); FontListItem *fli = (FontListItem *) d->m_font_family_list->item ( index ); d->m_font_style_list->clear(); d->m_font_style_list->insertStringList ( fli->styles()); d->m_font_style_list->setEnabled ( !fli->styles(). isEmpty()); int i; i = findItemCB ( d->m_font_style_list, oldstyle ); if ( i < 0 ) i = findItemCB ( d->m_font_style_list, "Regular" ); if (( i < 0 ) && ( d->m_font_style_list->count() > 0 )) i = 0; if ( i >= 0 ) { d->m_font_style_list->setCurrentItem ( i ); fontStyleClicked ( i ); } d->m_font_size_list->clear(); QValueList<int> sl = fli->sizes(); for ( QValueList<int>::Iterator it = sl. begin(); it != sl. end(); ++it ) d->m_font_size_list->insertItem ( QString::number ( *it )); i = findItemCB ( d->m_font_size_list, oldsize ); if ( i < 0 ) i = findItemCB ( d->m_font_size_list, "10" ); if (( i < 0 ) && ( d->m_font_size_list->count() > 0 )) i = 0; if ( i >= 0 ) { d->m_font_size_list->setCurrentItem ( i ); fontSizeClicked ( i ); } changeFont(); } void OFontSelector::fontStyleClicked ( int /*index*/ ) { changeFont(); } void OFontSelector::fontSizeClicked ( int /*index*/ ) { changeFont(); } void OFontSelector::changeFont() { QFont f = selectedFont(); if ( d->m_preview ) d->m_preview->setFont ( f ); emit fontSelected ( f ); } /** * Return the selected font */ QFont OFontSelector::selectedFont() { int ffa = d->m_font_family_list->currentItem(); int fst = d->m_font_style_list->currentItem(); int fsi = d->m_font_size_list->currentItem(); FontListItem *fli = (FontListItem *) d->m_font_family_list->item ( ffa ); if ( fli ) { return d->m_fdb. font ( fli->family(), \ fst >= 0 ? fli->styles() [fst] : QString::null, \ fsi >= 0 ? fli->sizes() [fsi] : 10, \ d->m_fdb. charSets ( fli->family()) [0] ); } else return QFont(); } void OFontSelector::resizeEvent ( QResizeEvent *re ) { if ( d->m_preview ) { d->m_preview->setMinimumHeight ( 1 ); d->m_preview->setMaximumHeight ( 32767 ); } QWidget::resizeEvent ( re ); if ( d->m_preview ) d->m_preview->setFixedHeight ( d->m_preview->height()); } diff --git a/libopie2/opieui/olistview.cpp b/libopie2/opieui/olistview.cpp index 38f3fe2..84617f8 100644 --- a/libopie2/opieui/olistview.cpp +++ b/libopie2/opieui/olistview.cpp @@ -1,613 +1,610 @@ /* This file is part of the Opie Project =. (C) 2003 Michael 'Mickey' Lauer <mickey@Vanille.de> .=l. .>+-= _;:, .> :=|. 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; either version 2 of the License, ._= =} : or (at your option) any later version. .%`+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. */ /* QT */ -#include <qcolor.h> -#include <qheader.h> -#include <qpainter.h> #include <qpixmap.h> /* OPIE */ #include <opie2/odebug.h> #include <opie2/olistview.h> /*====================================================================================== * OListView *======================================================================================*/ OListView::OListView( QWidget *parent, const char *name ) :QListView( parent, name ) { //FIXME: get from global settings and calculate ==> see oglobalsettings.* m_alternateBackground = QColor( 238, 246, 255 ); m_columnSeparator = QPen( QColor( 150, 160, 170 ), 0, DotLine ); m_fullWidth = true; connect( this, SIGNAL(expanded(QListViewItem*)), SLOT(expand(QListViewItem*))); } OListView::~OListView() { } void OListView::setFullWidth( bool fullWidth ) { m_fullWidth = m_fullWidth; #if QT_VERSION > 290 header()->setStretchEnabled( fullWidth, columns()-1 ); #endif } bool OListView::fullWidth() const { return m_fullWidth; } int OListView::addColumn( const QString& label, int width ) { int result = QListView::addColumn( label, width ); #if QT_VERSION > 290 if (m_fullWidth) { header()->setStretchEnabled( false, columns()-2 ); header()->setStretchEnabled( true, columns()-1 ); } #endif return result; } int OListView::addColumn( const QIconSet& iconset, const QString& label, int width ) { int result = QListView::addColumn( iconset, label, width ); #if QT_VERSION > 290 if (m_fullWidth) { header()->setStretchEnabled( false, columns()-2 ); header()->setStretchEnabled( true, columns()-1 ); } #endif return result; } void OListView::removeColumn( int index ) { QListView::removeColumn(index); #if QT_VERSION > 290 if ( m_fullWidth && index == columns() ) { header()->setStretchEnabled( true, columns()-1 ); } #endif } const QColor& OListView::alternateBackground() const { return m_alternateBackground; } void OListView::setAlternateBackground( const QColor &c ) { m_alternateBackground = c; repaint(); } const QPen& OListView::columnSeparator() const { return m_columnSeparator; } void OListView::setColumnSeparator( const QPen& p ) { m_columnSeparator = p; repaint(); } void OListView::expand(QListViewItem *item) { ((OListViewItem*)item)->expand(); } OListViewItem* OListView::childFactory() { return new OListViewItem( this ); } #ifndef QT_NO_DATASTREAM void OListView::serializeTo( QDataStream& s ) const { #warning Caution... the binary format is still under construction... odebug << "storing OListView..." << oendl; // store number of columns and the labels s << columns(); for ( int i = 0; i < columns(); ++i ) s << columnText( i ); // calculate the number of top-level items to serialize int items = 0; QListViewItem* item = firstChild(); while ( item ) { item = item->nextSibling(); items++; } // store number of items and the items itself s << items; item = firstChild(); for ( int i = 0; i < items; ++i ) { s << *static_cast<OListViewItem*>( item ); item = item->nextSibling(); } odebug << "OListview stored." << oendl; } void OListView::serializeFrom( QDataStream& s ) { #warning Caution... the binary format is still under construction... odebug << "loading OListView..." << oendl; int cols; s >> cols; qDebug( "read number of columns = %d", cols ); while ( columns() < cols ) addColumn( QString::null ); for ( int i = 0; i < cols; ++i ) { QString coltext; s >> coltext; qDebug( "read text '%s' for column %d", (const char*) coltext, i ); setColumnText( i, coltext ); } int items; s >> items; qDebug( "read number of items = %d", items ); for ( int i = 0; i < items; ++i ) { OListViewItem* item = childFactory(); s >> *item; } odebug << "OListView loaded." << oendl; } QDataStream& operator<<( QDataStream& s, const OListView& lv ) { lv.serializeTo( s ); } QDataStream& operator>>( QDataStream& s, OListView& lv ) { lv.serializeFrom( s ); } #endif // QT_NO_DATASTREAM /*====================================================================================== * OListViewItem *======================================================================================*/ OListViewItem::OListViewItem(QListView *parent) : QListViewItem(parent) { init(); } OListViewItem::OListViewItem(QListViewItem *parent) : QListViewItem(parent) { init(); } OListViewItem::OListViewItem(QListView *parent, QListViewItem *after) : QListViewItem(parent, after) { init(); } OListViewItem::OListViewItem(QListViewItem *parent, QListViewItem *after) : QListViewItem(parent, after) { init(); } OListViewItem::OListViewItem(QListView *parent, QString label1, QString label2, QString label3, QString label4, QString label5, QString label6, QString label7, QString label8) : QListViewItem(parent, label1, label2, label3, label4, label5, label6, label7, label8) { init(); } OListViewItem::OListViewItem(QListViewItem *parent, QString label1, QString label2, QString label3, QString label4, QString label5, QString label6, QString label7, QString label8) : QListViewItem(parent, label1, label2, label3, label4, label5, label6, label7, label8) { init(); } OListViewItem::OListViewItem(QListView *parent, QListViewItem *after, QString label1, QString label2, QString label3, QString label4, QString label5, QString label6, QString label7, QString label8) : QListViewItem(parent, after, label1, label2, label3, label4, label5, label6, label7, label8) { init(); } OListViewItem::OListViewItem(QListViewItem *parent, QListViewItem *after, QString label1, QString label2, QString label3, QString label4, QString label5, QString label6, QString label7, QString label8) : QListViewItem(parent, after, label1, label2, label3, label4, label5, label6, label7, label8) { init(); } OListViewItem::~OListViewItem() { } void OListViewItem::init() { m_known = false; } const QColor &OListViewItem::backgroundColor() { return isAlternate() ? static_cast<OListView*>(listView())->alternateBackground() : listView()->viewport()->colorGroup().base(); } bool OListViewItem::isAlternate() { OListView *lv = static_cast<OListView*>( listView() ); // check if the item above is an OListViewItem OListViewItem *above = static_cast<OListViewItem*>( itemAbove() ); /*if (! itemAbove()->inherits( "OListViewItem" )) return false;*/ // check if we have a valid alternate background color if (!(lv && lv->alternateBackground().isValid())) return false; m_known = above ? above->m_known : true; if (m_known) { m_odd = above ? !above->m_odd : false; } else { OListViewItem *item; bool previous = true; if (parent()) { item = static_cast<OListViewItem *>(parent()); if ( item /*&& item->inherits( "OListViewItem" )*/ ) previous = item->m_odd; item = static_cast<OListViewItem *>(parent()->firstChild()); /* if ( !item.inherits( "OListViewItem" ) item = 0; */ } else { item = static_cast<OListViewItem *>(lv->firstChild()); } while(item) { item->m_odd = previous = !previous; item->m_known = true; item = static_cast<OListViewItem *>(item->nextSibling()); /* if (!item.inherits( "OListViewItem" ) ) break; */ } } return m_odd; } void OListViewItem::paintCell(QPainter *p, const QColorGroup &cg, int column, int width, int alignment) { QColorGroup _cg = cg; const QPixmap *pm = listView()->viewport()->backgroundPixmap(); if (pm && !pm->isNull()) { _cg.setBrush( QColorGroup::Base, QBrush(backgroundColor(), *pm) ); p->setBrushOrigin( -listView()->contentsX(), -listView()->contentsY() ); } else if ( isAlternate() ) { _cg.setColor( QColorGroup::Base, static_cast<OListView*>( listView() )->alternateBackground() ); } QListViewItem::paintCell( p, _cg, column, width, alignment ); //FIXME: Use styling here! const QPen& pen = static_cast<OListView*>( listView() )->columnSeparator(); p->setPen( pen ); p->drawLine( width-1, 0, width-1, height() ); } OListViewItem* OListViewItem::childFactory() { return new OListViewItem( this ); } #ifndef QT_NO_DATASTREAM void OListViewItem::serializeTo( QDataStream& s ) const { #warning Caution... the binary format is still under construction... odebug << "storing OListViewItem..." << oendl; // store item text for ( int i = 0; i < listView()->columns(); ++i ) { s << text( i ); } // calculate the number of children to serialize int items = 0; QListViewItem* item = firstChild(); while ( item ) { item = item->nextSibling(); items++; } // store number of items and the items itself s << items; item = firstChild(); for ( int i = 0; i < items; ++i ) { s << *static_cast<OListViewItem*>( item ); item = item->nextSibling(); } odebug << "OListviewItem stored." << oendl; } void OListViewItem::serializeFrom( QDataStream& s ) { #warning Caution... the binary format is still under construction... odebug << "loading OListViewItem..." << oendl; for ( int i = 0; i < listView()->columns(); ++i ) { QString coltext; s >> coltext; qDebug( "read text '%s' for column %d", (const char*) coltext, i ); setText( i, coltext ); } int items; s >> items; qDebug( "read number of items = %d", items ); for ( int i = 0; i < items; ++i ) { OListViewItem* item = childFactory(); s >> (*item); } odebug << "OListViewItem loaded." << oendl; } QDataStream& operator<<( QDataStream& s, const OListViewItem& lvi ) { lvi.serializeTo( s ); } QDataStream& operator>>( QDataStream& s, OListViewItem& lvi ) { lvi.serializeFrom( s ); } #endif // QT_NO_DATASTREAM /*====================================================================================== * ONamedListView *======================================================================================*/ ONamedListView::ONamedListView( QWidget *parent, const char *name ) :OListView( parent, name ) { } ONamedListView::~ONamedListView() { } void ONamedListView::addColumns( const QStringList& columns ) { for ( QStringList::ConstIterator it = columns.begin(); it != columns.end(); ++it ) { qDebug( "adding column %s", (const char*) *it ); addColumn( *it ); } } int ONamedListView::findColumn( const QString& text ) const { //FIXME: If used excessively, this will slow down performance of updates //FIXME: because of the linear search over all column texts. //FIXME: I will optimize later by using a hash map. for ( int i = 0; i < columns(); ++i ) if ( columnText( i ) == text ) return i; return -1; } ONamedListViewItem* ONamedListView::find( int column, const QString& text, int recurse ) const { return find( (ONamedListViewItem*) firstChild(), column, text, recurse ); } ONamedListViewItem* ONamedListView::find( ONamedListViewItem* item, int column, const QString& text, int recurse ) const { ONamedListViewItem* result; while ( item && item->text( column ) != text ) { qDebug( "checked %s", (const char*) item->text( column ) ); if ( recurse < 0 || recurse > 0 ) { qDebug( "recursion is %d - recursing into...", recurse ); result = find( (ONamedListViewItem*) item->firstChild(), column, text, recurse-1 ); if ( result ) return result; } item = (ONamedListViewItem*) item->itemBelow(); } if ( item && item->text( column ) == text ) return item; else return 0; } ONamedListViewItem* ONamedListView::find( const QString& column, const QString& text, int recurse ) const { int col = findColumn( column ); if ( col != -1 ) return find( (ONamedListViewItem*) firstChild(), col, text, recurse ); else return 0; } ONamedListViewItem* ONamedListView::find( ONamedListViewItem* item, const QString& column, const QString& text, int recurse ) const { int col = findColumn( column ); if ( col != -1 ) return find( item, col, text, recurse ); else return 0; } /*====================================================================================== * ONamedListViewItem *======================================================================================*/ ONamedListViewItem::ONamedListViewItem( QListView* parent, const QStringList& texts ) :OListViewItem( parent ) { setText( texts ); } ONamedListViewItem::ONamedListViewItem( QListViewItem* parent, const QStringList& texts ) :OListViewItem( parent ) { setText( texts ); } ONamedListViewItem::ONamedListViewItem( QListView* parent, QListViewItem* after, const QStringList& texts ) :OListViewItem( parent, after ) { setText( texts ); } ONamedListViewItem::ONamedListViewItem( QListViewItem* parent, QListViewItem* after, const QStringList& texts ) :OListViewItem( parent, after ) { setText( texts ); } ONamedListViewItem::~ONamedListViewItem() { } void ONamedListViewItem::setText( const QStringList& texts ) { int col = 0; for ( QStringList::ConstIterator it = texts.begin(); it != texts.end(); ++it ) { qDebug( "setting column %d = text %s", col, (const char*) *it ); OListViewItem::setText( col++, *it ); } } void ONamedListViewItem::setText( const QString& column, const QString& text ) { //FIXME: If used excessively, this will slow down performance of updates //FIXME: because of the linear search over all column texts. //FIXME: I will optimize later by using a hash map. int col = ( (ONamedListView*) listView() )->findColumn( column ); if ( col != -1 ) OListViewItem::setText( col, text ); else qWarning( "ONamedListViewItem::setText(): Warning! Columntext '%s' not found.", (const char*) column ); } ONamedListViewItem* ONamedListViewItem::find( int column, const QString& text, int recurse ) const { return ( (ONamedListView*) listView() )->find( (ONamedListViewItem*) firstChild(), column, text, recurse ); } ONamedListViewItem* ONamedListViewItem::find( const QString& column, const QString& text, int recurse ) const { int col = ( (ONamedListView*) listView() )->findColumn( column ); if ( col != -1 ) return ( (ONamedListView*) listView() )->find( (ONamedListViewItem*) firstChild(), col, text, recurse ); else return 0; } diff --git a/libopie2/opieui/opopupmenu.cpp b/libopie2/opieui/opopupmenu.cpp index ac73188..d5cc575 100644 --- a/libopie2/opieui/opopupmenu.cpp +++ b/libopie2/opieui/opopupmenu.cpp @@ -1,604 +1,597 @@ /* This file is part of the KDE libraries Copyright (C) 2000 Daniel M. Duley <mosfet@kde.org> Copyright (C) 2002 Hamish Rodda <meddie@yoyo.its.monash.edu.au> This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License version 2 as published by the Free Software Foundation. This library 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. */ /* QT */ -#include <qapplication.h> -#include <qcursor.h> -#include <qpainter.h> #include <qdrawutil.h> #include <qtimer.h> -#include <qfont.h> -#include <qfontmetrics.h> -#include <qregexp.h> -#include <qstyle.h> /* OPIE */ #include <opie2/opopupmenu.h> #include <opie2/oconfig.h> OPopupTitle::OPopupTitle(QWidget *parent, const char *name) : QWidget(parent, name) { setMinimumSize(16, fontMetrics().height()+8); } OPopupTitle::OPopupTitle(OPixmapEffect::GradientType /* gradient */, const QColor &/* color */, const QColor &/* textColor */, QWidget *parent, const char *name) : QWidget(parent, name) { setMinimumSize(16, fontMetrics().height()+8); } OPopupTitle::OPopupTitle(const OPixmap & /* background */, const QColor &/* color */, const QColor &/* textColor */, QWidget *parent, const char *name) : QWidget(parent, name) { setMinimumSize(16, fontMetrics().height()+8); } void OPopupTitle::setTitle(const QString &text, const QPixmap *icon) { titleStr = text; if (icon) miniicon = *icon; else miniicon.resize(0, 0); int w = miniicon.width()+fontMetrics().width(titleStr); int h = QMAX( fontMetrics().height(), miniicon.height() ); setMinimumSize( w+16, h+8 ); } void OPopupTitle::setText( const QString &text ) { titleStr = text; int w = miniicon.width()+fontMetrics().width(titleStr); int h = QMAX( fontMetrics().height(), miniicon.height() ); setMinimumSize( w+16, h+8 ); } void OPopupTitle::setIcon( const QPixmap &pix ) { miniicon = pix; int w = miniicon.width()+fontMetrics().width(titleStr); int h = QMAX( fontMetrics().height(), miniicon.height() ); setMinimumSize( w+16, h+8 ); } void OPopupTitle::paintEvent(QPaintEvent *) { QRect r(rect()); QPainter p(this); #if QT_VERSION > 290 qApp->style().drawPrimitive(QStyle::PE_HeaderSection, &p, r, palette().active()); #else #warning OPopupMenu is not fully functional on Qt2 #endif if (!miniicon.isNull()) p.drawPixmap(4, (r.height()-miniicon.height())/2, miniicon); if (!titleStr.isNull()) { p.setPen(palette().active().text()); QFont f = p.font(); f.setBold(true); p.setFont(f); if(!miniicon.isNull()) { p.drawText(miniicon.width()+8, 0, width()-(miniicon.width()+8), height(), AlignLeft | AlignVCenter | SingleLine, titleStr); } else { p.drawText(0, 0, width(), height(), AlignCenter | SingleLine, titleStr); } } p.setPen(palette().active().highlight()); p.drawLine(0, 0, r.right(), 0); } QSize OPopupTitle::sizeHint() const { return(minimumSize()); } class OPopupMenu::OPopupMenuPrivate { public: OPopupMenuPrivate () : noMatches(false) , shortcuts(false) , autoExec(false) , lastHitIndex(-1) , m_ctxMenu(0) {} ~OPopupMenuPrivate () { delete m_ctxMenu; } QString m_lastTitle; // variables for keyboard navigation QTimer clearTimer; bool noMatches : 1; bool shortcuts : 1; bool autoExec : 1; QString keySeq; QString originalText; int lastHitIndex; // support for RMB menus on menus QPopupMenu* m_ctxMenu; static bool s_continueCtxMenuShow; static int s_highlightedItem; static OPopupMenu* s_contextedMenu; }; int OPopupMenu::OPopupMenuPrivate::s_highlightedItem(-1); OPopupMenu* OPopupMenu::OPopupMenuPrivate::s_contextedMenu(0); bool OPopupMenu::OPopupMenuPrivate::s_continueCtxMenuShow(true); OPopupMenu::OPopupMenu(QWidget *parent, const char *name) : QPopupMenu(parent, name) { d = new OPopupMenuPrivate; resetKeyboardVars(); connect(&(d->clearTimer), SIGNAL(timeout()), SLOT(resetKeyboardVars())); } OPopupMenu::~OPopupMenu() { if (OPopupMenuPrivate::s_contextedMenu == this) { OPopupMenuPrivate::s_contextedMenu = 0; OPopupMenuPrivate::s_highlightedItem = -1; } delete d; } int OPopupMenu::insertTitle(const QString &text, int id, int index) { OPopupTitle *titleItem = new OPopupTitle(); titleItem->setTitle(text); int ret = insertItem(titleItem, id, index); setItemEnabled(id, false); return ret; } int OPopupMenu::insertTitle(const QPixmap &icon, const QString &text, int id, int index) { OPopupTitle *titleItem = new OPopupTitle(); titleItem->setTitle(text, &icon); int ret = insertItem(titleItem, id, index); setItemEnabled(id, false); return ret; } void OPopupMenu::changeTitle(int id, const QString &text) { QMenuItem *item = findItem(id); if(item){ if(item->widget()) ((OPopupTitle *)item->widget())->setTitle(text); #ifndef NDEBUG else qWarning( "KPopupMenu: changeTitle() called with non-title id %d", id ); #endif } #ifndef NDEBUG else qWarning( "KPopupMenu: changeTitle() called with invalid id %d", id ); #endif } void OPopupMenu::changeTitle(int id, const QPixmap &icon, const QString &text) { QMenuItem *item = findItem(id); if(item){ if(item->widget()) ((OPopupTitle *)item->widget())->setTitle(text, &icon); #ifndef NDEBUG else qWarning( "KPopupMenu: changeTitle() called with non-title id %d", id ); #endif } #ifndef NDEBUG else qWarning( "KPopupMenu: changeTitle() called with invalid id %d", id ); #endif } QString OPopupMenu::title(int id) const { if(id == -1) // obsolete return(d->m_lastTitle); QMenuItem *item = findItem(id); if(item){ if(item->widget()) return(((OPopupTitle *)item->widget())->title()); else qWarning("OPopupMenu: title() called with non-title id %d.", id); } else qWarning("OPopupMenu: title() called with invalid id %d.", id); return(QString::null); } QPixmap OPopupMenu::titlePixmap(int id) const { QMenuItem *item = findItem(id); if(item){ if(item->widget()) return(((OPopupTitle *)item->widget())->icon()); else qWarning("KPopupMenu: titlePixmap() called with non-title id %d.", id); } else qWarning("KPopupMenu: titlePixmap() called with invalid id %d.", id); QPixmap tmp; return(tmp); } /** * This is re-implemented for keyboard navigation. */ void OPopupMenu::closeEvent(QCloseEvent*e) { if (d->shortcuts) resetKeyboardVars(); QPopupMenu::closeEvent(e); } void OPopupMenu::keyPressEvent(QKeyEvent* e) { if (!d->shortcuts) { // continue event processing by Qpopup //e->ignore(); QPopupMenu::keyPressEvent(e); return; } int i = 0; bool firstpass = true; QString keyString = e->text(); // check for common commands dealt with by QPopup int key = e->key(); if (key == Key_Escape || key == Key_Return || key == Key_Enter || key == Key_Up || key == Key_Down || key == Key_Left || key == Key_Right || key == Key_F1) { resetKeyboardVars(); // continue event processing by Qpopup //e->ignore(); QPopupMenu::keyPressEvent(e); return; } // check to see if the user wants to remove a key from the sequence (backspace) // or clear the sequence (delete) if (!d->keySeq.isNull()) { if (key == Key_Backspace) { if (d->keySeq.length() == 1) { resetKeyboardVars(); return; } // keep the last sequence in keyString keyString = d->keySeq.left(d->keySeq.length() - 1); // allow sequence matching to be tried again resetKeyboardVars(); } else if (key == Key_Delete) { resetKeyboardVars(); // clear active item setActiveItem(0); return; } else if (d->noMatches) { // clear if there are no matches resetKeyboardVars(); // clear active item setActiveItem(0); } else { // the key sequence is not a null string // therefore the lastHitIndex is valid i = d->lastHitIndex; } } else if (key == Key_Backspace && parentMenu) { // backspace with no chars in the buffer... go back a menu. hide(); resetKeyboardVars(); return; } d->keySeq += keyString; int seqLen = d->keySeq.length(); for (; i < (int)count(); i++) { // compare typed text with text of this entry int j = idAt(i); // don't search disabled entries if (!isItemEnabled(j)) continue; QString thisText; // retrieve the right text // (the last selected item one may have additional ampersands) if (i == d->lastHitIndex) thisText = d->originalText; else thisText = text(j); // if there is an accelerator present, remove it if ((int)accel(j) != 0) thisText = thisText.replace(QRegExp("&"), ""); // chop text to the search length thisText = thisText.left(seqLen); // do the search if (thisText.find(d->keySeq, 0, false) == 0) { if (firstpass) { // match setActiveItem(i); // check to see if we're underlining a different item if (d->lastHitIndex != i) // yes; revert the underlining changeItem(idAt(d->lastHitIndex), d->originalText); // set the original text if it's a different item if (d->lastHitIndex != i || d->lastHitIndex == -1) d->originalText = text(j); // underline the currently selected item changeItem(j, underlineText(d->originalText, d->keySeq.length())); // remeber what's going on d->lastHitIndex = i; // start/restart the clear timer d->clearTimer.start(5000, true); // go around for another try, to see if we can execute firstpass = false; } else { // don't allow execution return; } } // fall through to allow execution } if (!firstpass) { if (d->autoExec) { // activate anything activateItemAt(d->lastHitIndex); resetKeyboardVars(); } else if (findItem(idAt(d->lastHitIndex)) && findItem(idAt(d->lastHitIndex))->popup()) { // only activate sub-menus activateItemAt(d->lastHitIndex); resetKeyboardVars(); } return; } // no matches whatsoever, clean up resetKeyboardVars(true); //e->ignore(); QPopupMenu::keyPressEvent(e); } QString OPopupMenu::underlineText(const QString& text, uint length) { QString ret = text; for (uint i = 0; i < length; i++) { if (ret[2*i] != '&') ret.insert(2*i, "&"); } return ret; } void OPopupMenu::resetKeyboardVars(bool noMatches /* = false */) { // Clean up keyboard variables if (d->lastHitIndex != -1) { changeItem(idAt(d->lastHitIndex), d->originalText); d->lastHitIndex = -1; } if (!noMatches) { d->keySeq = QString::null; } d->noMatches = noMatches; } void OPopupMenu::setKeyboardShortcutsEnabled(bool enable) { d->shortcuts = enable; } void OPopupMenu::setKeyboardShortcutsExecute(bool enable) { d->autoExec = enable; } /** * End keyboard navigation. */ /** * RMB menus on menus */ QPopupMenu* OPopupMenu::contextMenu() { if (!d->m_ctxMenu) { d->m_ctxMenu = new QPopupMenu(this); installEventFilter(this); connect(d->m_ctxMenu, SIGNAL(aboutToHide()), this, SLOT(ctxMenuHiding())); } return d->m_ctxMenu; } void OPopupMenu::cancelContextMenuShow() { OPopupMenuPrivate::s_continueCtxMenuShow = false; } int OPopupMenu::contextMenuFocusItem() { return OPopupMenuPrivate::s_highlightedItem; } OPopupMenu* OPopupMenu::contextMenuFocus() { return OPopupMenuPrivate::s_contextedMenu; } void OPopupMenu::itemHighlighted(int /* whichItem */) { if (!d->m_ctxMenu || !d->m_ctxMenu->isVisible()) { return; } d->m_ctxMenu->hide(); showCtxMenu(mapFromGlobal(QCursor::pos())); } void OPopupMenu::showCtxMenu(QPoint pos) { OPopupMenuPrivate::s_highlightedItem = idAt(pos); if (OPopupMenuPrivate::s_highlightedItem == -1) { OPopupMenuPrivate::s_contextedMenu = 0; return; } emit aboutToShowContextMenu(this, OPopupMenuPrivate::s_highlightedItem, d->m_ctxMenu); if (!OPopupMenuPrivate::s_continueCtxMenuShow) { OPopupMenuPrivate::s_continueCtxMenuShow = true; return; } OPopupMenuPrivate::s_contextedMenu = this; d->m_ctxMenu->popup(this->mapToGlobal(pos)); connect(this, SIGNAL(highlighted(int)), this, SLOT(itemHighlighted(int))); } void OPopupMenu::ctxMenuHiding() { disconnect(this, SIGNAL(highlighted(int)), this, SLOT(itemHighlighted(int))); OPopupMenuPrivate::s_continueCtxMenuShow = true; } bool OPopupMenu::eventFilter(QObject* obj, QEvent* event) { if (d->m_ctxMenu && obj == this) { if (event->type() == QEvent::MouseButtonRelease) { if (d->m_ctxMenu->isVisible()) { return true; } } #if QT_VERSION > 290 else if (event->type() == QEvent::ContextMenu) #else else if ( (event->type() == QEvent::MouseButtonPress) && ( (QMouseEvent*) event )->button() == QMouseEvent::RightButton ) #endif { showCtxMenu(mapFromGlobal(QCursor::pos())); return true; } } return QWidget::eventFilter(obj, event); } void OPopupMenu::hideEvent(QHideEvent*) { if (d->m_ctxMenu) { d->m_ctxMenu->hide(); } } /** * end of RMB menus on menus support */ // Obsolete OPopupMenu::OPopupMenu(const QString& title, QWidget *parent, const char *name) : QPopupMenu(parent, name) { d = new OPopupMenuPrivate; setTitle(title); } // Obsolete void OPopupMenu::setTitle(const QString &title) { OPopupTitle *titleItem = new OPopupTitle(); titleItem->setTitle(title); insertItem(titleItem); d->m_lastTitle = title; } void OPopupTitle::virtual_hook( int, void* ) { /*BASE::virtual_hook( id, data );*/ } void OPopupMenu::virtual_hook( int, void* ) { /*BASE::virtual_hook( id, data );*/ } diff --git a/libopie2/opieui/oselector.cpp b/libopie2/opieui/oselector.cpp index ec5af6b..23b3ce3 100644 --- a/libopie2/opieui/oselector.cpp +++ b/libopie2/opieui/oselector.cpp @@ -1,716 +1,715 @@ /* This file is part of the KDE libraries Copyright (C) 1997 Martin Jones (mjones@kde.org) This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library 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. */ /* QT */ #include <qimage.h> -#include <qpainter.h> #include <qdrawutil.h> /* OPIE */ #include <opie2/oimageeffect.h> #include <opie2/oselector.h> #define STORE_W 8 #define STORE_W2 STORE_W * 2 //----------------------------------------------------------------------------- /* * 2D value selector. * The contents of the selector are drawn by derived class. */ OXYSelector::OXYSelector( QWidget *parent, const char *name ) : QWidget( parent, name ) { xPos = 0; yPos = 0; minX = 0; minY = 0; maxX = 100; maxY = 100; store.setOptimization( QPixmap::BestOptim ); store.resize( STORE_W2, STORE_W2 ); } OXYSelector::~OXYSelector() {} void OXYSelector::setRange( int _minX, int _minY, int _maxX, int _maxY ) { px = 2; py = 2; minX = _minX; minY = _minY; maxX = _maxX; maxY = _maxY; } void OXYSelector::setValues( int _xPos, int _yPos ) { xPos = _xPos; yPos = _yPos; if ( xPos > maxX ) xPos = maxX; else if ( xPos < minX ) xPos = minX; if ( yPos > maxY ) yPos = maxY; else if ( yPos < minY ) yPos = minY; int xp = 2 + (width() - 4) * xPos / (maxX - minX); int yp = height() - 2 - (height() - 4) * yPos / (maxY - minY); setPosition( xp, yp ); } QRect OXYSelector::contentsRect() const { return QRect( 2, 2, width()-4, height()-4 ); } void OXYSelector::paintEvent( QPaintEvent *ev ) { QRect cursorRect( px - STORE_W, py - STORE_W, STORE_W2, STORE_W2); QRect paintRect = ev->rect(); QPainter painter; painter.begin( this ); QBrush brush; qDrawShadePanel( &painter, 0, 0, width(), height(), colorGroup(), TRUE, 2, &brush ); drawContents( &painter ); if (paintRect.contains(cursorRect)) { bitBlt( &store, 0, 0, this, px - STORE_W, py - STORE_W, STORE_W2, STORE_W2, CopyROP ); drawCursor( &painter, px, py ); } else if (paintRect.intersects(cursorRect)) { repaint( cursorRect, false); } painter.end(); } void OXYSelector::mousePressEvent( QMouseEvent *e ) { int xVal, yVal; valuesFromPosition( e->pos().x() - 2, e->pos().y() - 2, xVal, yVal ); setValues( xVal, yVal ); emit valueChanged( xPos, yPos ); } void OXYSelector::mouseMoveEvent( QMouseEvent *e ) { int xVal, yVal; valuesFromPosition( e->pos().x() - 2, e->pos().y() - 2, xVal, yVal ); setValues( xVal, yVal ); emit valueChanged( xPos, yPos ); } void OXYSelector::wheelEvent( QWheelEvent *e ) { #if QT_VERSION > 290 if ( e->orientation() == Qt::Horizontal ) setValues( xValue() + e->delta()/120, yValue() ); else setValues( xValue(), yValue() + e->delta()/120 ); emit valueChanged( xPos, yPos ); #endif } void OXYSelector::valuesFromPosition( int x, int y, int &xVal, int &yVal ) const { xVal = ( (maxX-minX) * (x-2) ) / ( width()-4 ); yVal = maxY - ( ( (maxY-minY) * (y-2) ) / ( height()-4 ) ); if ( xVal > maxX ) xVal = maxX; else if ( xVal < minX ) xVal = minX; if ( yVal > maxY ) yVal = maxY; else if ( yVal < minY ) yVal = minY; } void OXYSelector::setPosition( int xp, int yp ) { if ( xp < 2 ) xp = 2; else if ( xp > width() - 2 ) xp = width() - 2; if ( yp < 2 ) yp = 2; else if ( yp > height() - 2 ) yp = height() - 2; QPainter painter; painter.begin( this ); bitBlt( this, px - STORE_W, py - STORE_W, &store, 0, 0, STORE_W2, STORE_W2, CopyROP ); bitBlt( &store, 0, 0, this, xp - STORE_W, yp - STORE_W, STORE_W2, STORE_W2, CopyROP ); drawCursor( &painter, xp, yp ); px = xp; py = yp; painter.end(); } void OXYSelector::drawContents( QPainter * ) {} void OXYSelector::drawCursor( QPainter *p, int xp, int yp ) { p->setPen( QPen( white ) ); p->drawLine( xp - 6, yp - 6, xp - 2, yp - 2 ); p->drawLine( xp - 6, yp + 6, xp - 2, yp + 2 ); p->drawLine( xp + 6, yp - 6, xp + 2, yp - 2 ); p->drawLine( xp + 6, yp + 6, xp + 2, yp + 2 ); } //----------------------------------------------------------------------------- /* * 1D value selector with contents drawn by derived class. * See OColorDialog for example. */ OSelector::OSelector( QWidget *parent, const char *name ) : QWidget( parent, name ), QRangeControl() { _orientation = Horizontal; _indent = TRUE; } OSelector::OSelector( Orientation o, QWidget *parent, const char *name ) : QWidget( parent, name ), QRangeControl() { _orientation = o; _indent = TRUE; } OSelector::~OSelector() {} QRect OSelector::contentsRect() const { if ( orientation() == Vertical ) return QRect( 2, 5, width()-9, height()-10 ); else return QRect( 5, 2, width()-10, height()-9 ); } void OSelector::paintEvent( QPaintEvent * ) { QPainter painter; painter.begin( this ); drawContents( &painter ); QBrush brush; if ( indent() ) { if ( orientation() == Vertical ) qDrawShadePanel( &painter, 0, 3, width()-5, height()-6, colorGroup(), TRUE, 2, &brush ); else qDrawShadePanel( &painter, 3, 0, width()-6, height()-5, colorGroup(), TRUE, 2, &brush ); } QPoint pos = calcArrowPos( value() ); drawArrow( &painter, TRUE, pos ); painter.end(); } void OSelector::mousePressEvent( QMouseEvent *e ) { moveArrow( e->pos() ); } void OSelector::mouseMoveEvent( QMouseEvent *e ) { moveArrow( e->pos() ); } void OSelector::wheelEvent( QWheelEvent *e ) { int val = value() + e->delta()/120; emit valueChanged( val ); setValue( val ); } void OSelector::valueChange() { QPainter painter; QPoint pos; painter.begin( this ); pos = calcArrowPos( prevValue() ); drawArrow( &painter, FALSE, pos ); pos = calcArrowPos( value() ); drawArrow( &painter, TRUE, pos ); painter.end(); } void OSelector::moveArrow( const QPoint &pos ) { int val; if ( orientation() == Vertical ) val = ( maxValue() - minValue() ) * (height()-pos.y()-3) / (height()-10) + minValue(); else val = ( maxValue() - minValue() ) * (width()-pos.x()-3) / (width()-10) + minValue(); if ( val > maxValue() ) val = maxValue(); if ( val < minValue() ) val = minValue(); emit valueChanged( val ); setValue( val ); } QPoint OSelector::calcArrowPos( int val ) { QPoint p; if ( orientation() == Vertical ) { p.setY( height() - ( (height()-10) * val / ( maxValue() - minValue() ) + 5 ) ); p.setX( width() - 5 ); } else { p.setX( width() - ( (width()-10) * val / ( maxValue() - minValue() ) + 5 ) ); p.setY( height() - 5 ); } return p; } void OSelector::drawContents( QPainter * ) {} void OSelector::drawArrow( QPainter *painter, bool show, const QPoint &pos ) { if ( show ) { QPointArray array(3); painter->setPen( QPen() ); painter->setBrush( QBrush( colorGroup().buttonText() ) ); if ( orientation() == Vertical ) { array.setPoint( 0, pos.x()+0, pos.y()+0 ); array.setPoint( 1, pos.x()+5, pos.y()+5 ); array.setPoint( 2, pos.x()+5, pos.y()-5 ); } else { array.setPoint( 0, pos.x()+0, pos.y()+0 ); array.setPoint( 1, pos.x()+5, pos.y()+5 ); array.setPoint( 2, pos.x()-5, pos.y()+5 ); } painter->drawPolygon( array ); } else { if ( orientation() == Vertical ) { repaint(pos.x(), pos.y()-5, 6, 11, true); } else { repaint(pos.x()-5, pos.y(), 11, 6, true); } } } //---------------------------------------------------------------------------- OGradientSelector::OGradientSelector( QWidget *parent, const char *name ) : OSelector( parent, name ) { init(); } OGradientSelector::OGradientSelector( Orientation o, QWidget *parent, const char *name ) : OSelector( o, parent, name ) { init(); } OGradientSelector::~OGradientSelector() {} void OGradientSelector::init() { color1.setRgb( 0, 0, 0 ); color2.setRgb( 255, 255, 255 ); text1 = text2 = ""; } void OGradientSelector::drawContents( QPainter *painter ) { QImage image( contentsRect().width(), contentsRect().height(), 32 ); QColor col; float scale; int redDiff = color2.red() - color1.red(); int greenDiff = color2.green() - color1.green(); int blueDiff = color2.blue() - color1.blue(); if ( orientation() == Vertical ) { for ( int y = 0; y < image.height(); y++ ) { scale = 1.0 * y / image.height(); col.setRgb( color1.red() + int(redDiff*scale), color1.green() + int(greenDiff*scale), color1.blue() + int(blueDiff*scale) ); unsigned int *p = (uint *) image.scanLine( y ); for ( int x = 0; x < image.width(); x++ ) *p++ = col.rgb(); } } else { unsigned int *p = (uint *) image.scanLine( 0 ); for ( int x = 0; x < image.width(); x++ ) { scale = 1.0 * x / image.width(); col.setRgb( color1.red() + int(redDiff*scale), color1.green() + int(greenDiff*scale), color1.blue() + int(blueDiff*scale) ); *p++ = col.rgb(); } for ( int y = 1; y < image.height(); y++ ) memcpy( image.scanLine( y ), image.scanLine( y - 1), sizeof( unsigned int ) * image.width() ); } QColor ditherPalette[8]; for ( int s = 0; s < 8; s++ ) ditherPalette[s].setRgb( color1.red() + redDiff * s / 8, color1.green() + greenDiff * s / 8, color1.blue() + blueDiff * s / 8 ); OImageEffect::dither( image, ditherPalette, 8 ); QPixmap p; p.convertFromImage( image ); painter->drawPixmap( contentsRect().x(), contentsRect().y(), p ); if ( orientation() == Vertical ) { int yPos = contentsRect().top() + painter->fontMetrics().ascent() + 2; int xPos = contentsRect().left() + (contentsRect().width() - painter->fontMetrics().width( text2 )) / 2; QPen pen( color2 ); painter->setPen( pen ); painter->drawText( xPos, yPos, text2 ); yPos = contentsRect().bottom() - painter->fontMetrics().descent() - 2; xPos = contentsRect().left() + (contentsRect().width() - painter->fontMetrics().width( text1 )) / 2; pen.setColor( color1 ); painter->setPen( pen ); painter->drawText( xPos, yPos, text1 ); } else { int yPos = contentsRect().bottom()-painter->fontMetrics().descent()-2; QPen pen( color2 ); painter->setPen( pen ); painter->drawText( contentsRect().left() + 2, yPos, text1 ); pen.setColor( color1 ); painter->setPen( pen ); painter->drawText( contentsRect().right() - painter->fontMetrics().width( text2 ) - 2, yPos, text2 ); } } //----------------------------------------------------------------------------- static QColor *standardPalette = 0; #define STANDARD_PAL_SIZE 17 OColor::OColor() : QColor() { r = 0; g = 0; b = 0; h = 0; s = 0; v = 0; }; OColor::OColor( const OColor &col) : QColor( col ) { h = col.h; s = col.s; v = col.v; r = col.r; g = col.g; b = col.b; }; OColor::OColor( const QColor &col) : QColor( col ) { QColor::rgb(&r, &g, &b); QColor::hsv(&h, &s, &v); }; bool OColor::operator==(const OColor& col) const { return (h == col.h) && (s == col.s) && (v == col.v) && (r == col.r) && (g == col.g) && (b == col.b); } OColor& OColor::operator=(const OColor& col) { *(QColor *)this = col; h = col.h; s = col.s; v = col.v; r = col.r; g = col.g; b = col.b; return *this; } void OColor::setHsv(int _h, int _s, int _v) { h = _h; s = _s; v = _v; QColor::setHsv(h, s, v); QColor::rgb(&r, &g, &b); }; void OColor::setRgb(int _r, int _g, int _b) { r = _r; g = _g; b = _b; QColor::setRgb(r, g, b); QColor::hsv(&h, &s, &v); } void OColor::rgb(int *_r, int *_g, int *_b) const { *_r = r; *_g = g; *_b = b; } void OColor::hsv(int *_h, int *_s, int *_v) const { *_h = h; *_s = s; *_v = v; } static void createStandardPalette() { if ( standardPalette ) return; standardPalette = new QColor[STANDARD_PAL_SIZE]; int i = 0; standardPalette[i++] = Qt::red; standardPalette[i++] = Qt::green; standardPalette[i++] = Qt::blue; standardPalette[i++] = Qt::cyan; standardPalette[i++] = Qt::magenta; standardPalette[i++] = Qt::yellow; standardPalette[i++] = Qt::darkRed; standardPalette[i++] = Qt::darkGreen; standardPalette[i++] = Qt::darkBlue; standardPalette[i++] = Qt::darkCyan; standardPalette[i++] = Qt::darkMagenta; standardPalette[i++] = Qt::darkYellow; standardPalette[i++] = Qt::white; standardPalette[i++] = Qt::lightGray; standardPalette[i++] = Qt::gray; standardPalette[i++] = Qt::darkGray; standardPalette[i++] = Qt::black; } OHSSelector::OHSSelector( QWidget *parent, const char *name ) : OXYSelector( parent, name ) { setRange( 0, 0, 359, 255 ); } void OHSSelector::updateContents() { drawPalette(&pixmap); } void OHSSelector::resizeEvent( QResizeEvent * ) { updateContents(); } void OHSSelector::drawContents( QPainter *painter ) { painter->drawPixmap( contentsRect().x(), contentsRect().y(), pixmap ); } void OHSSelector::drawPalette( QPixmap *pixmap ) { int xSize = contentsRect().width(), ySize = contentsRect().height(); QImage image( xSize, ySize, 32 ); QColor col; int h, s; uint *p; for ( s = ySize-1; s >= 0; s-- ) { p = (uint *) image.scanLine( ySize - s - 1 ); for( h = 0; h < xSize; h++ ) { col.setHsv( 359*h/(xSize-1), 255*s/(ySize-1), 192 ); *p = col.rgb(); p++; } } if ( QColor::numBitPlanes() <= 8 ) { createStandardPalette(); OImageEffect::dither( image, standardPalette, STANDARD_PAL_SIZE ); } pixmap->convertFromImage( image ); } //----------------------------------------------------------------------------- OValueSelector::OValueSelector( QWidget *parent, const char *name ) : OSelector( OSelector::Vertical, parent, name ), _hue(0), _sat(0) { setRange( 0, 255 ); pixmap.setOptimization( QPixmap::BestOptim ); } OValueSelector::OValueSelector(Orientation o, QWidget *parent, const char *name ) : OSelector( o, parent, name), _hue(0), _sat(0) { setRange( 0, 255 ); pixmap.setOptimization( QPixmap::BestOptim ); } void OValueSelector::updateContents() { drawPalette(&pixmap); } void OValueSelector::resizeEvent( QResizeEvent * ) { updateContents(); } void OValueSelector::drawContents( QPainter *painter ) { painter->drawPixmap( contentsRect().x(), contentsRect().y(), pixmap ); } void OValueSelector::drawPalette( QPixmap *pixmap ) { int xSize = contentsRect().width(), ySize = contentsRect().height(); QImage image( xSize, ySize, 32 ); QColor col; uint *p; QRgb rgb; if ( orientation() == OSelector::Horizontal ) { for ( int v = 0; v < ySize; v++ ) { p = (uint *) image.scanLine( ySize - v - 1 ); for( int x = 0; x < xSize; x++ ) { col.setHsv( _hue, _sat, 255*x/(xSize-1) ); rgb = col.rgb(); *p++ = rgb; } } } if( orientation() == OSelector::Vertical ) { for ( int v = 0; v < ySize; v++ ) { p = (uint *) image.scanLine( ySize - v - 1 ); col.setHsv( _hue, _sat, 255*v/(ySize-1) ); rgb = col.rgb(); for ( int i = 0; i < xSize; i++ ) *p++ = rgb; } } if ( QColor::numBitPlanes() <= 8 ) { createStandardPalette(); OImageEffect::dither( image, standardPalette, STANDARD_PAL_SIZE ); } pixmap->convertFromImage( image ); } diff --git a/libopie2/opieui/oseparator.cpp b/libopie2/opieui/oseparator.cpp index 98d42c7..b93c225 100644 --- a/libopie2/opieui/oseparator.cpp +++ b/libopie2/opieui/oseparator.cpp @@ -1,128 +1,127 @@ /* This file is part of the Opie Project Copyright (C) 2003 Michael 'Mickey' Lauer <mickey@tm.informatik.uni-frankfurt.de> Copyright (C) 1997 Michael Roth <mroth@wirlweb.de> =. .=l. .>+-= _;:, .> :=|. 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; either version 2 of the License, ._= =} : or (at your option) any later version. .%`+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. */ /* OPIE */ #include <opie2/odebug.h> #include <opie2/oseparator.h> /* QT */ -#include <qstyle.h> OSeparator::OSeparator(QWidget* parent, const char* name, WFlags f) : QFrame(parent, name, f) { setLineWidth(1); setMidLineWidth(0); setOrientation( HLine ); } OSeparator::OSeparator(int orientation, QWidget* parent, const char* name, WFlags f) : QFrame(parent, name, f) { setLineWidth(1); setMidLineWidth(0); setOrientation( orientation ); } void OSeparator::setOrientation(int orientation) { switch(orientation) { case Vertical: case VLine: setFrameStyle( QFrame::VLine | QFrame::Sunken ); setMinimumSize(2, 0); break; default: owarn << "OSeparator::setOrientation(): invalid orientation, using default orientation HLine" << oendl; case Horizontal: case HLine: setFrameStyle( QFrame::HLine | QFrame::Sunken ); setMinimumSize(0, 2); break; } } int OSeparator::orientation() const { if ( frameStyle() & VLine ) return VLine; if ( frameStyle() & HLine ) return HLine; return 0; } void OSeparator::drawFrame(QPainter *p) { QPoint p1, p2; QRect r = frameRect(); const QColorGroup & g = colorGroup(); if ( frameStyle() & HLine ) { p1 = QPoint( r.x(), r.height()/2 ); p2 = QPoint( r.x()+r.width(), p1.y() ); } else { p1 = QPoint( r.x()+r.width()/2, 0 ); p2 = QPoint( p1.x(), r.height() ); } #if QT_VERSION < 300 style().drawSeparator( p, p1.x(), p1.y(), p2.x(), p2.y(), g, true, 1, midLineWidth() ); #else QStyleOption opt( lineWidth(), midLineWidth() ); style().drawPrimitive( QStyle::PE_Separator, p, QRect( p1, p2 ), g, QStyle::Style_Sunken, opt ); #endif } QSize OSeparator::sizeHint() const { if ( frameStyle() & VLine ) return QSize(2, 0); if ( frameStyle() & HLine ) return QSize(0, 2); return QSize(-1, -1); } diff --git a/libopie2/opieui/otimepicker.cpp b/libopie2/opieui/otimepicker.cpp index 9f9f2c2..d4712a4 100644 --- a/libopie2/opieui/otimepicker.cpp +++ b/libopie2/opieui/otimepicker.cpp @@ -1,295 +1,292 @@ /* This file is part of the Opie Project Copyright (C) Stefan Eilers <eilers.stefan@epost.de> =. Copyright (C) The Opie Team <opie-devel@handhelds.org> .=l. .>+-= _;:, .> :=|. 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; either version 2 of the License, ._= =} : or (at your option) any later version. .%`+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. */ /* QT */ -#include <qbuttongroup.h> #include <qlayout.h> #include <qlineedit.h> -#include <qstring.h> -#include <qtoolbutton.h> /* OPIE */ #include <opie2/otimepicker.h> using namespace Opie; /** * Constructs the widget * @param parent The parent of the OTimePicker * @param name The name of the object * @param fl Window Flags */ OTimePicker::OTimePicker(QWidget* parent, const char* name, Qt::WFlags fl) :QWidget(parent,name,fl) { QVBoxLayout *vbox=new QVBoxLayout(this); OClickableLabel *r; QString s; // Hour Row QWidget *row=new QWidget(this); QHBoxLayout *l=new QHBoxLayout(row); vbox->addWidget(row); for (int i=0; i<24; i++) { r=new OClickableLabel(row); hourLst.append(r); s.sprintf("%.2d",i); r->setText(s); r->setToggleButton(true); r->setAlignment(AlignHCenter | AlignVCenter); l->addWidget(r); connect(r, SIGNAL(toggled(bool)), this, SLOT(slotHour(bool))); if (i==11) { // Second row row=new QWidget(this); l=new QHBoxLayout(row); vbox->addWidget(row); } } // Minute Row row=new QWidget(this); l=new QHBoxLayout(row); vbox->addWidget(row); for (int i=0; i<60; i+=5) { r=new OClickableLabel(row); minuteLst.append(r); s.sprintf("%.2d",i); r->setText(s); r->setToggleButton(true); r->setAlignment(AlignHCenter | AlignVCenter); l->addWidget(r); connect(r, SIGNAL(toggled(bool)), this, SLOT(slotMinute(bool))); } } /** * This method return the current time * @return the time */ QTime OTimePicker::time()const { return tm; } void OTimePicker::slotHour(bool b) { OClickableLabel *r = (OClickableLabel *) sender(); if (b) { QValueListIterator<OClickableLabel *> it; for (it=hourLst.begin(); it!=hourLst.end(); it++) { if (*it != r) (*it)->setOn(false); else tm.setHMS((*it)->text().toInt(), tm.minute(), 0); } emit timeChanged(tm); } else { r->setOn(true); } } void OTimePicker::slotMinute(bool b) { OClickableLabel *r = (OClickableLabel *) sender(); if (b) { QValueListIterator<OClickableLabel *> it; for (it=minuteLst.begin(); it!=minuteLst.end(); it++) { if (*it != r) (*it)->setOn(false); else tm.setHMS(tm.hour(),(*it)->text().toInt(), 0); } emit timeChanged(tm); } else { r->setOn(true); } } /** * Method to set the time. No signal gets emitted during this method call * Minutes must be within 5 minutes step starting at 0 ( 0,5,10,15,20... ) * @param t The time to be set */ void OTimePicker::setTime( const QTime& t) { setTime( t.hour(), t.minute() ); } /** * Method to set the time. No signal gets emitted during this method call * @param h The hour * @param m The minute. Minutes need to set by 5 minute steps */ void OTimePicker::setTime( int h, int m ) { setHour(h); setMinute(m); } /* * FIXME round minutes to the 5 minute arrangement -zecke */ /** * Method to set the minutes * @param m minutes */ void OTimePicker::setMinute(int m) { QString minute; minute.sprintf("%.2d",m); QValueListIterator<OClickableLabel *> it; for (it=minuteLst.begin(); it!=minuteLst.end(); it++) { if ((*it)->text() == minute) (*it)->setOn(true); else (*it)->setOn(false); } tm.setHMS(tm.hour(),m,0); } /** * Method to set the hour */ void OTimePicker::setHour(int h) { QString hour; hour.sprintf("%.2d",h); QValueListIterator<OClickableLabel *> it; for (it=hourLst.begin(); it!=hourLst.end(); it++) { if ((*it)->text() == hour) (*it)->setOn(true); else (*it)->setOn(false); } tm.setHMS(h,tm.minute(),0); } /** * This is a modal Dialog. * * @param parent The parent widget * @param name The name of the object * @param fl Possible window flags */ OTimePickerDialog::OTimePickerDialog ( QWidget* parent, const char* name, WFlags fl ) : OTimePickerDialogBase (parent , name, true , fl) { connect ( m_timePicker, SIGNAL( timeChanged( const QTime& ) ), this, SLOT( setTime ( const QTime& ) ) ); connect ( minuteField, SIGNAL( textChanged ( const QString& ) ), this, SLOT ( setMinute ( const QString& ) ) ); connect ( hourField, SIGNAL( textChanged ( const QString& ) ), this, SLOT ( setHour ( const QString& ) ) ); } /** * @return the time */ QTime OTimePickerDialog::time()const { return m_time; } /** * Set the time to time * @param time The time to be set */ void OTimePickerDialog::setTime( const QTime& time ) { m_time = time; m_timePicker->setHour ( time.hour() ); m_timePicker->setMinute( time.minute() ); // Set Textfields if ( time.hour() < 10 ) hourField->setText( "0" + QString::number( time.hour() ) ); else hourField->setText( QString::number( time.hour() ) ); if ( time.minute() < 10 ) minuteField->setText( "0" + QString::number( time.minute() ) ); else minuteField->setText( QString::number( time.minute() ) ); } /** * This method takes the current minute and tries to set hour * to hour. This succeeds if the resulting date is valid * @param hour The hour as a string */ void OTimePickerDialog::setHour ( const QString& hour ) { if ( QTime::isValid ( hour.toInt(), m_time.minute() , 00 ) ) { m_time.setHMS ( hour.toInt(), m_time.minute() , 00 ); setTime ( m_time ); } } /** * Method to set a new minute. It tries to convert the string to int and * if the resulting date is valid a new date is set. * @see setHour */ void OTimePickerDialog::setMinute ( const QString& minute ) { if ( QTime::isValid ( m_time.hour(), minute.toInt(), 00 ) ) { m_time.setHMS ( m_time.hour(), minute.toInt(), 00 ); setTime ( m_time ); } } diff --git a/libopie2/opieui/oversatileview.cpp b/libopie2/opieui/oversatileview.cpp index 65fe3d8..8839456 100644 --- a/libopie2/opieui/oversatileview.cpp +++ b/libopie2/opieui/oversatileview.cpp @@ -1,1180 +1,1169 @@ /* This file is part of the Opie Project =. (C) 2003 Michael 'Mickey' Lauer <mickey@tm.informatik.uni-frankfurt.de> .=l. .>+-= _;:, .> :=|. 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; either version 2 of the License, ._= =} : or (at your option) any later version. .%`+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. */ /* OPIE */ #include <opie2/odebug.h> #include <opie2/oversatileview.h> #include <opie2/oversatileviewitem.h> #include <opie2/olistview.h> /* QT */ #include <qaction.h> -#include <qbrush.h> -#include <qfont.h> -#include <qiconset.h> -#include <qiconview.h> -#include <qlistview.h> -#include <qpalette.h> -#include <qpoint.h> #include <qpopupmenu.h> -#include <qrect.h> -#include <qsize.h> -#include <qstring.h> -#include <qwidgetstack.h> /* XPM */ static const char * view_icon_xpm[] = { "16 16 16 1", " c None", ". c #87BD88", "+ c #8BBE8B", "@ c #81BA81", "# c #6DAF6D", "$ c #87BD87", "% c #FCFDFC", "& c #AED0AE", "* c #4E9C4C", "= c #91BD91", "- c #72B172", "; c #448643", "> c #519F50", ", c #499247", "' c #356A35", ") c #686868", " ", " .+@# .+@# ", " $%&* $%&* ", " @=-; @=-; ", " #>,' #>,' ", " ", " )))))) )))))) ", " ", " ", " .+@# .+@# ", " $%&* $%&* ", " @=-; @=-; ", " #>,' #>,' ", " ", " )))))) )))))) ", " "}; /* XPM */ static const char * view_tree_xpm[] = { "16 16 17 1", " c None", ". c #3A3A3A", "+ c #87BD88", "@ c #8BBE8B", "# c #81BA81", "$ c #6DAF6D", "% c #87BD87", "& c #FCFDFC", "* c #AED0AE", "= c #4E9C4C", "- c #91BD91", "; c #72B172", "> c #448643", ", c #686868", "' c #519F50", ") c #499247", "! c #356A35", " . ", " . ", " . +@#$ ", " . %&*= ", " .. #-;> ,, ,,,", " . $')! ", " . ", " . ", " . ", " . +@#$ ", " . %&*= ", " .. #-;> ,, ,,,", " $')! ", " ", " ", " "}; OVersatileView::OVersatileView( QWidget* parent, const char* name, int mode ) :QWidgetStack( parent, name ), _viewmode( mode ), _warningpolicy( None ), _treeleaf(), _treeopened(), _treeclosed(), _iconleaf(), _iconopened(), _iconclosed() { // // Create child widgets and set some reasonable default styles // _listview = new OListView( this, "oversatileview embedded listview" ); _iconview = new QIconView( this, "oversatileview embedded iconview" ); _listview->setAllColumnsShowFocus( true ); _listview->setRootIsDecorated( true ); _listview->setShowSortIndicator( true ); _iconview->setGridX( 90 ); _iconview->setGridY( 42 ); _iconview->setAutoArrange( true ); #ifdef QWS // TODO: Let this depend on current geometry (rotation) _iconview->setArrangement( QIconView::TopToBottom ); #else _iconview->setArrangement( QIconView::LeftToRight ); #endif _iconview->setResizeMode( QIconView::Adjust ); // qt-embedded: map stylus right on hold to right button press #ifdef QWS ( (QPEApplication*) qApp)->setStylusOperation( _iconview->viewport(), QPEApplication::RightOnHold ); ( (QPEApplication*) qApp)->setStylusOperation( _listview->viewport(), QPEApplication::RightOnHold ); #endif setViewMode( mode ); // TODO: Read last style from config // setSynchronization( true ); // TODO: Implement this // create context menu allowing to switch between the views _contextmenu = new QPopupMenu( 0, "oversatileview contextmenu" ); _contextmenu->setCaption( "Style" ); _contextmenu->setCheckable( true ); QActionGroup* ag = new QActionGroup( _contextmenu, "style option group" ); QAction* a1 = new QAction( "View Items in Icon Style", QIconSet( QPixmap( view_icon_xpm ) ), "View Icons", 0, ag, "viewicon action", true ); QAction* a2 = new QAction( "View Items in Tree Style", QIconSet( QPixmap( view_tree_xpm ) ), "View Tree", 0, ag, "viewtree action", true ); ag->addTo( _contextmenu ); if ( mode == Icons ) a1->setOn( true ); else if ( mode == Tree ) a2->setOn( true ); connect( a1, SIGNAL( activated() ), this, SLOT( setIconViewMode() ) ); connect( a2, SIGNAL( activated() ), this, SLOT( setTreeViewMode() ) ); #if (QT_VERSION >= 0x030000) connect( _listview, SIGNAL( contextMenuRequested( QListViewItem*, const QPoint&, int ) ), this, SLOT( contextMenuRequested( QListViewItem*, const QPoint&, int ) ) ); connect( _iconview, SIGNAL( contextMenuRequested( QIconViewItem*, const QPoint& ) ), this, SLOT( contextMenuRequested( QIconViewItem*, const QPoint& ) ) ); #else connect( _listview, SIGNAL( rightButtonPressed( QListViewItem*, const QPoint&, int ) ), this, SLOT( contextMenuRequested( QListViewItem*, const QPoint&, int ) ) ); connect( _iconview, SIGNAL( rightButtonPressed( QIconViewItem*, const QPoint& ) ), this, SLOT( contextMenuRequested( QIconViewItem*, const QPoint& ) ) ); #endif // // signal forwarders // // unfortunately we can't short-circuit all the QListView and QIconView signals // to OVersatileView signals, because the signal/slot mechanism doesn't allow // type-conversion :-( // common signals for listview connect( _listview, SIGNAL( selectionChanged() ), this, SIGNAL( selectionChanged() ) ); connect( _listview, SIGNAL( selectionChanged( QListViewItem * ) ), this, SLOT( selectionChanged( QListViewItem * ) ) ); connect( _listview, SIGNAL( currentChanged( QListViewItem * ) ), this, SLOT( currentChanged( QListViewItem * ) ) ); connect( _listview, SIGNAL( clicked( QListViewItem * ) ), this, SLOT( clicked( QListViewItem * ) ) ); connect( _listview, SIGNAL( pressed( QListViewItem * ) ), this, SLOT( pressed( QListViewItem * ) ) ); connect( _listview, SIGNAL( doubleClicked( QListViewItem * ) ), this, SLOT( doubleClicked( QListViewItem * ) ) ); connect( _listview, SIGNAL( returnPressed( QListViewItem * ) ), this, SLOT( returnPressed( QListViewItem * ) ) ); connect( _listview, SIGNAL( onItem( QListViewItem * ) ), this, SLOT( onItem( QListViewItem * ) ) ); connect( _listview, SIGNAL( onViewport() ), this, SIGNAL( onViewport() ) ); // common signals for iconview connect( _iconview, SIGNAL( selectionChanged() ), this, SIGNAL( selectionChanged() ) ); connect( _iconview, SIGNAL( selectionChanged( QIconViewItem * ) ), this, SLOT( selectionChanged( QIconViewItem * ) ) ); connect( _iconview, SIGNAL( currentChanged( QIconViewItem * ) ), this, SLOT( currentChanged( QIconViewItem * ) ) ); connect( _iconview, SIGNAL( clicked( QIconViewItem * ) ), this, SLOT( clicked( QIconViewItem * ) ) ); connect( _iconview, SIGNAL( pressed( QIconViewItem * ) ), this, SLOT( pressed( QIconViewItem * ) ) ); connect( _iconview, SIGNAL( doubleClicked( QIconViewItem * ) ), this, SLOT( doubleClicked( QIconViewItem * ) ) ); connect( _iconview, SIGNAL( returnPressed( QIconViewItem * ) ), this, SLOT( returnPressed( QIconViewItem * ) ) ); connect( _iconview, SIGNAL( onItem( QIconViewItem * ) ), this, SLOT( onItem( QIconViewItem * ) ) ); connect( _iconview, SIGNAL( onViewport() ), this, SIGNAL( onViewport() ) ); // listview only signals connect( _listview, SIGNAL( expanded( QListViewItem * ) ), this, SLOT( expanded( QListViewItem * ) ) ); connect( _listview, SIGNAL( collapsed( QListViewItem * ) ), this, SLOT( collapsed( QListViewItem * ) ) ); // iconview only signals connect( _iconview, SIGNAL( moved() ), this, SIGNAL( moved() ) ); } OVersatileView::~OVersatileView() { } QPopupMenu* OVersatileView::contextMenu() const { return _contextmenu; } void OVersatileView::contextMenuRequested( QListViewItem* item, const QPoint& pos, int col ) { // can't use QObject::inherits here, because ListViewItems, beit Q, O or K, // do not inherit from QObject - assuming here the programmer is // disciplined enough to only add OVersatileViewItems to an OVersatileView popupContextMenu( static_cast<OVersatileViewItem*>( item ), pos, col ); } void OVersatileView::contextMenuRequested( QIconViewItem* item, const QPoint& pos ) { // see above popupContextMenu( static_cast<OVersatileViewItem*>( item ), pos, -1 ); } void OVersatileView::popupContextMenu( OVersatileViewItem* item, const QPoint& pos, int col ) { if ( !item ) _contextmenu->exec( pos ); else emit( contextMenuRequested( item, pos, col ) ); } void OVersatileView::setSynchronization( bool sync ) { _synchronization = sync; } bool OVersatileView::synchronization() { return _synchronization; } void OVersatileView::setDefaultPixmaps( int mode, QPixmap& leaf, QPixmap& opened, QPixmap& closed ) { if ( mode == Tree ) { _treeleaf = leaf; _treeopened = opened; _treeclosed = closed; } else if ( mode == Icons ) { _iconleaf = leaf; _iconopened = opened; _iconclosed = closed; } else { odebug << "OVersatileView::setDefaultPixmaps(): invalid mode" << oendl; } } QIconView* OVersatileView::iconView() const { return _iconview; } OListView* OVersatileView::listView() const { return _listview; } void OVersatileView::setViewMode( int mode ) { if ( mode == Tree ) { _viewmode = mode; raiseWidget( _listview ); } else if ( mode == Icons ) { _viewmode = mode; raiseWidget( _iconview ); } else { odebug << "OVersatileView::setViewMode(): invalid mode" << oendl; } } void OVersatileView::setIconViewMode() { setViewMode( Icons ); } void OVersatileView::setTreeViewMode() { setViewMode( Tree ); } bool OVersatileView::isValidViewMode( int mode ) const { switch ( _warningpolicy ) { case OVersatileView::None: { return true; } case OVersatileView::Warn: { if ( _viewmode != mode ) { odebug << "OVersatileView::isValidViewMode(): Requested operation not valid in current mode." << oendl; return true; } } case OVersatileView::WarnReturn: { if ( _viewmode != mode ) { odebug << "OVersatileView::isValidViewMode(): Requested operation not valid in current mode." << oendl; return false; } } default: { owarn << "OVersatileView::isValidViewMode(): Inconsistent object state!" << oendl; return true; } } } void OVersatileView::setWarningPolicy( int policy ) const { _warningpolicy = policy; } bool OVersatileView::warningPolicy() const { return _warningpolicy; } //==============================================================================================// // Stupid Signal forwarders... // Folks, this is why I like python with its dynamic typing: // I can code the following dozens of lines C++ in four Python lines... //==============================================================================================// void OVersatileView::selectionChanged( QListViewItem * item ) { emit( selectionChanged( static_cast<OVersatileViewItem*>( item ) ) ); } void OVersatileView::selectionChanged( QIconViewItem * item ) { emit( selectionChanged( static_cast<OVersatileViewItem*>( item ) ) ); } void OVersatileView::currentChanged( QListViewItem * item ) { emit( currentChanged( static_cast<OVersatileViewItem*>( item ) ) ); } void OVersatileView::currentChanged( QIconViewItem * item ) { emit( currentChanged( static_cast<OVersatileViewItem*>( item ) ) ); } void OVersatileView::clicked( QListViewItem * item ) { emit( clicked( static_cast<OVersatileViewItem*>( item ) ) ); } void OVersatileView::clicked( QIconViewItem * item ) { emit( clicked( static_cast<OVersatileViewItem*>( item ) ) ); } void OVersatileView::pressed( QListViewItem * item ) { emit( pressed( static_cast<OVersatileViewItem*>( item ) ) ); } void OVersatileView::pressed( QIconViewItem * item ) { emit( pressed( static_cast<OVersatileViewItem*>( item ) ) ); } void OVersatileView::doubleClicked( QListViewItem * item ) { emit( doubleClicked( static_cast<OVersatileViewItem*>( item ) ) ); } void OVersatileView::doubleClicked( QIconViewItem * item ) { emit( doubleClicked( static_cast<OVersatileViewItem*>( item ) ) ); } void OVersatileView::returnPressed( QListViewItem * item ) { emit( returnPressed( static_cast<OVersatileViewItem*>( item ) ) ); } void OVersatileView::returnPressed( QIconViewItem * item ) { emit( returnPressed( static_cast<OVersatileViewItem*>( item ) ) ); } void OVersatileView::onItem( QListViewItem * item ) { emit( onItem( static_cast<OVersatileViewItem*>( item ) ) ); } void OVersatileView::onItem( QIconViewItem * item ) { emit( onItem( static_cast<OVersatileViewItem*>( item ) ) ); } void OVersatileView::expanded( QListViewItem *item ) // QListView { //odebug << "OVersatileView::expanded(): opening tree..." << oendl; if ( !_treeopened.isNull() ) item->setPixmap( 0, _treeopened ); emit( expanded( static_cast<OVersatileViewItem*>( item ) ) ); } void OVersatileView::collapsed( QListViewItem *item ) // QListView { if ( !_treeclosed.isNull() ) item->setPixmap( 0, _treeclosed ); emit( collapsed( static_cast<OVersatileViewItem*>( item ) ) ); } //=============================================================================================// // OVersatileView Case I - API only existing in QListView or QIconView but not in both! //==============================================================================================// int OVersatileView::treeStepSize() const // QListView { if ( !isValidViewMode( Tree ) ) { return -1; } return _listview->treeStepSize(); } void OVersatileView::setTreeStepSize( int size ) // QListView { if ( !isValidViewMode( Tree ) ) { return; } _listview->setTreeStepSize( size ); } QHeader * OVersatileView::header() const // QListView { if ( !isValidViewMode( Tree ) ) { return 0; } return _listview->header(); } int OVersatileView::addColumn( const QString &label, int size ) // QListView { if ( !isValidViewMode( Tree ) ) { return -1; } return _listview->addColumn( label, size ); } int OVersatileView::addColumn( const QIconSet& iconset, const QString &label, int size ) // QListView { if ( !isValidViewMode( Tree ) ) { return -1; } return _listview->addColumn( iconset, label, size ); } void OVersatileView::removeColumn( int index ) // QListView { if ( !isValidViewMode( Tree ) ) { return; } _listview->removeColumn( index ); } void OVersatileView::setColumnText( int column, const QString &label ) // QListView { if ( !isValidViewMode( Tree ) ) { return; } _listview->setColumnText( column, label ); } void OVersatileView::setColumnText( int column, const QIconSet& iconset, const QString &label ) // QListView { if ( !isValidViewMode( Tree ) ) { return; } _listview->setColumnText( column, iconset, label ); } QString OVersatileView::columnText( int column ) const // QListView { if ( !isValidViewMode( Tree ) ) { return QString::null; } return _listview->columnText( column ); } void OVersatileView::setColumnWidth( int column, int width ) // QListView { if ( !isValidViewMode( Tree ) ) { return; } _listview->setColumnWidth( column, width ); } int OVersatileView::columnWidth( int column ) const // QListView { if ( !isValidViewMode( Tree ) ) { return -1; } return _listview->columnWidth( column ); } void OVersatileView::setColumnWidthMode( int column, WidthMode mode ) // QListView { if ( !isValidViewMode( Tree ) ) { return; } _listview->setColumnWidth( column, mode ); } int OVersatileView::columns() const // QListView { if ( !isValidViewMode( Tree ) ) { return -1; } return _listview->columns(); } void OVersatileView::setColumnAlignment( int column, int align ) // QListView { if ( !isValidViewMode( Tree ) ) { return; } _listview->setColumnAlignment( column, align ); } int OVersatileView::columnAlignment( int column ) const // QListView { if ( !isValidViewMode( Tree ) ) { return -1; } return _listview->columnAlignment( column ); } OVersatileViewItem * OVersatileView::itemAt( const QPoint & screenPos ) const // QListView { if ( !isValidViewMode( Tree ) ) { return 0; } return static_cast<OVersatileViewItem*>( _listview->itemAt( screenPos ) ); } QRect OVersatileView::itemRect( const OVersatileViewItem * item ) const // QListView { if ( !isValidViewMode( Tree ) ) { return QRect( -1, -1, -1, -1 ); } return _listview->itemRect( item ); } int OVersatileView::itemPos( const OVersatileViewItem * item ) // QListView { if ( !isValidViewMode( Tree ) ) { return -1; } return _listview->itemPos( item ); } bool OVersatileView::isSelected( const OVersatileViewItem * item ) const // QListView // also in QIconViewItem but !in QIconView *shrug* { if ( !isValidViewMode( Tree ) ) { return false; } return _listview->isSelected( item ); } void OVersatileView::setMultiSelection( bool enable ) { _listview->setMultiSelection( enable ); } bool OVersatileView::isMultiSelection() const { return _listview->isMultiSelection(); } OVersatileViewItem * OVersatileView::selectedItem() const // QListView { if ( !isValidViewMode( Tree ) ) { return 0; } return static_cast<OVersatileViewItem*>( _listview->selectedItem() ); } void OVersatileView::setOpen( OVersatileViewItem * item, bool open ) // QListView { if ( !isValidViewMode( Tree ) ) { return; } _listview->setOpen( item, open ); } bool OVersatileView::isOpen( const OVersatileViewItem * item ) const // QListView { if ( !isValidViewMode( Tree ) ) { return false; } return _listview->isOpen( item ); } OVersatileViewItem * OVersatileView::firstChild() const // QListView { if ( !isValidViewMode( Tree ) ) { return 0; } return static_cast<OVersatileViewItem*>( _listview->firstChild() ); } int OVersatileView::childCount() const // QListView { if ( !isValidViewMode( Tree ) ) { return -1; } return _listview->childCount(); } void OVersatileView::setAllColumnsShowFocus( bool focus ) // QListView { if ( !isValidViewMode( Tree ) ) { return; } _listview->setAllColumnsShowFocus( focus ); } bool OVersatileView::allColumnsShowFocus() const // QListView { if ( !isValidViewMode( Tree ) ) { return false; } return _listview->allColumnsShowFocus(); } void OVersatileView::setItemMargin( int margin ) // QListView { if ( !isValidViewMode( Tree ) ) { return; } _listview->setItemMargin( margin ); } int OVersatileView::itemMargin() const // QListView { if ( !isValidViewMode( Tree ) ) { return -1; } return _listview->itemMargin(); } void OVersatileView::setRootIsDecorated( bool decorate ) // QListView { if ( !isValidViewMode( Tree ) ) { return; } _listview->setRootIsDecorated( decorate ); } bool OVersatileView::rootIsDecorated() const // QListView { if ( !isValidViewMode( Tree ) ) { return false; } return _listview->rootIsDecorated(); } void OVersatileView::setShowSortIndicator( bool show ) // QListView { if ( !isValidViewMode( Tree ) ) { return; } _listview->setShowSortIndicator( show ); } bool OVersatileView::showSortIndicator() const // QListView { if ( !isValidViewMode( Tree ) ) { return false; } return _listview->showSortIndicator(); } void OVersatileView::triggerUpdate() // QListView { if ( !isValidViewMode( Tree ) ) { return; } _listview->triggerUpdate(); } // // only in QIconView // uint OVersatileView::count() const // QIconView { if ( !isValidViewMode( Icons ) ) { return 0; } return _iconview->count(); } int OVersatileView::index( const OVersatileViewItem *item ) const // QIconView { if ( !isValidViewMode( Icons ) ) { return -1; } return _iconview->index( item ); } OVersatileViewItem* OVersatileView::firstItem() const // QIconView { if ( !isValidViewMode( Icons ) ) { return 0; } return static_cast<OVersatileViewItem*>( _iconview->firstItem() ); } OVersatileViewItem* OVersatileView::lastItem() const // QIconView { if ( !isValidViewMode( Icons ) ) { return 0; } return static_cast<OVersatileViewItem*>( _iconview->lastItem() ); } OVersatileViewItem* OVersatileView::findItem( const QPoint &pos ) const // QIconView { if ( !isValidViewMode( Icons ) ) { return 0; } return static_cast<OVersatileViewItem*>( _iconview->findItem( pos ) ); } OVersatileViewItem* OVersatileView::findItem( const QString &text ) const // QIconView { if ( !isValidViewMode( Icons ) ) { return 0; } return static_cast<OVersatileViewItem*>( _iconview->findItem( text ) ); } OVersatileViewItem* OVersatileView::findFirstVisibleItem( const QRect &r ) const // QIconView { if ( !isValidViewMode( Icons ) ) { return 0; } return static_cast<OVersatileViewItem*>( _iconview->findFirstVisibleItem( r ) ); } OVersatileViewItem* OVersatileView::findLastVisibleItem( const QRect &r ) const // QIconView { if ( !isValidViewMode( Icons ) ) { return 0; } return static_cast<OVersatileViewItem*>( _iconview->findLastVisibleItem( r ) ); } void OVersatileView::setGridX( int rx ) // QIconView { if ( !isValidViewMode( Icons ) ) { return; } _iconview->setGridX( rx ); } void OVersatileView::setGridY( int ry ) // QIconView { if ( !isValidViewMode( Icons ) ) { return; } _iconview->setGridY( ry ); } int OVersatileView::gridX() const // QIconView { if ( !isValidViewMode( Icons ) ) { return -1; } return _iconview->gridX(); } int OVersatileView::gridY() const // QIconView { if ( !isValidViewMode( Icons ) ) { return -1; } return _iconview->gridY(); } void OVersatileView::setSpacing( int sp ) // QIconView { if ( !isValidViewMode( Icons ) ) { return; } _iconview->setSpacing( sp ); } int OVersatileView::spacing() const // QIconView { if ( !isValidViewMode( Icons ) ) { return -1; } return _iconview->spacing(); } void OVersatileView::setItemTextPos( QIconView::ItemTextPos pos ) // QIconView { if ( !isValidViewMode( Icons ) ) { return; } _iconview->setItemTextPos( pos ); } QIconView::ItemTextPos OVersatileView::itemTextPos() const // QIconView { if ( !isValidViewMode( Icons ) ) { return (QIconView::ItemTextPos) -1; } return _iconview->itemTextPos(); } void OVersatileView::setItemTextBackground( const QBrush &b ) // QIconView { if ( !isValidViewMode( Icons ) ) { return; } _iconview->setItemTextBackground( b ); } QBrush OVersatileView::itemTextBackground() const // QIconView { if ( !isValidViewMode( Icons ) ) { return QBrush(); } return _iconview->itemTextBackground(); } void OVersatileView::setArrangement( QIconView::Arrangement am ) // QIconView { if ( !isValidViewMode( Icons ) ) { return; } _iconview->setArrangement( am ); } QIconView::Arrangement OVersatileView::arrangement() const // QIconView { if ( !isValidViewMode( Icons ) ) { return (QIconView::Arrangement) -1; } return _iconview->arrangement(); } void OVersatileView::setResizeMode( QIconView::ResizeMode am ) // QIconView { if ( !isValidViewMode( Icons ) ) { return; } _iconview->setResizeMode( am ); } QIconView::ResizeMode OVersatileView::resizeMode() const // QIconView { if ( !isValidViewMode( Icons ) ) { return (QIconView::ResizeMode) -1; } return _iconview->resizeMode(); } void OVersatileView::setMaxItemWidth( int w ) // QIconView { if ( !isValidViewMode( Icons ) ) { return; } _iconview->setMaxItemWidth( w ); } int OVersatileView::maxItemWidth() const // QIconView { if ( !isValidViewMode( Icons ) ) { return -1; } return _iconview->maxItemWidth(); } void OVersatileView::setMaxItemTextLength( int w ) // QIconView { if ( !isValidViewMode( Icons ) ) { return; } _iconview->setMaxItemTextLength( w ); } int OVersatileView::maxItemTextLength() const // QIconView { if ( !isValidViewMode( Icons ) ) { return -1; } return _iconview->maxItemTextLength(); } void OVersatileView::setAutoArrange( bool b ) // QIconView { if ( !isValidViewMode( Icons ) ) { return; } _iconview->setAutoArrange( b ); } bool OVersatileView::autoArrange() const // QIconView { if ( !isValidViewMode( Icons ) ) { return false; } return _iconview->autoArrange(); } void OVersatileView::setShowToolTips( bool b ) // QIconView { if ( !isValidViewMode( Icons ) ) { return; } _iconview->setShowToolTips( b ); } bool OVersatileView::showToolTips() const // QIconView { if ( !isValidViewMode( Icons ) ) { return false; } return _iconview->showToolTips(); } bool OVersatileView::sorting() const // QIconView { if ( !isValidViewMode( Icons ) ) { return false; } return _iconview->sorting(); } bool OVersatileView::sortDirection() const // QIconView { if ( !isValidViewMode( Icons ) ) { return false; } return _iconview->sortDirection(); } void OVersatileView::setItemsMovable( bool b ) // QIconView { if ( !isValidViewMode( Icons ) ) { return; } _iconview->setItemsMovable( b ); } bool OVersatileView::itemsMovable() const // QIconView { if ( !isValidViewMode( Icons ) ) { return false; } return _iconview->itemsMovable(); } void OVersatileView::setWordWrapIconText( bool b ) // QIconView { if ( !isValidViewMode( Icons ) ) { return; } _iconview->setWordWrapIconText( b ); } bool OVersatileView::wordWrapIconText() const // QIconView { if ( !isValidViewMode( Icons ) ) { return false; } return _iconview->wordWrapIconText(); } void OVersatileView::arrangeItemsInGrid( const QSize &grid, bool update ) // QIconView { if ( !isValidViewMode( Icons ) ) { return; } _iconview->arrangeItemsInGrid( grid, update ); } void OVersatileView::arrangeItemsInGrid( bool update ) // QIconView { if ( !isValidViewMode( Icons ) ) { return; } _iconview->arrangeItemsInGrid( update ); } void OVersatileView::updateContents() // QIconView { if ( !isValidViewMode( Icons ) ) { return; } _iconview->updateContents(); } //==============================================================================================// // OVersatileView Case II - QListView / QIconView common API //==============================================================================================// void OVersatileView::clear() { _iconview->clear(); _listview->clear(); } void OVersatileView::setFont( const QFont & font ) { _iconview->setFont( font ); _listview->setFont( font ); } void OVersatileView::setPalette( const QPalette & palette ) { _iconview->setPalette( palette ); _listview->setPalette( palette ); } void OVersatileView::takeItem( OVersatileViewItem * item ) { _iconview->takeItem( item ); _listview->takeItem( item ); } void OVersatileView::setSelectionMode( SelectionMode mode ) { _iconview->setSelectionMode( (QIconView::SelectionMode) mode ); _listview->setSelectionMode( (QListView::SelectionMode) mode ); } OVersatileView::SelectionMode OVersatileView::selectionMode() const { return (OVersatileView::SelectionMode) _iconview->selectionMode(); } void OVersatileView::selectAll( bool select ) { _iconview->selectAll( select ); } void OVersatileView::clearSelection() { _iconview->clearSelection(); _listview->clearSelection(); } void OVersatileView::invertSelection() { _iconview->invertSelection(); _listview->invertSelection(); } void OVersatileView::ensureItemVisible( const OVersatileViewItem * item ) { _iconview->ensureItemVisible( const_cast<OVersatileViewItem*>( item ) ); _listview->ensureItemVisible( item ); } void OVersatileView::repaintItem( const OVersatileViewItem * item ) const { _iconview->repaintItem( const_cast<OVersatileViewItem*>( item ) ); _listview->repaintItem( item ); } void OVersatileView::setCurrentItem( OVersatileViewItem * item ) { _iconview->setCurrentItem( item ); _listview->setCurrentItem( item ); } OVersatileViewItem * OVersatileView::currentItem() const { return static_cast<OVersatileViewItem*>( _listview->currentItem() ); } // bool eventFilter( QObject * o, QEvent * ) // use QWidgetStack implementation // QSize minimumSizeHint() const // use QWidgetStack implementation // QSizePolicy sizePolicy() const // use QWidgetStack implementation // QSize sizeHint() const // use QWidgetStack implementation //==============================================================================================// // OVersatileView Case III - APIs which differ slightly //==============================================================================================// /* void OVersatileView::insertItem( OVersatileViewItem * ) // QListView void OVersatileView::insertItem( OVersatileViewItem *item, OVersatileViewItem *after = 0L ) // QIconView void OVersatileView::setSelected( OVersatileViewItem *, bool ) // QListView void OVersatileView::setSelected( OVersatileViewItem *item, bool s, bool cb = FALSE ) // QIconView void OVersatileView::setSorting( int column, bool increasing = TRUE ) // QListView void OVersatileView::setSorting( bool sort, bool ascending = TRUE ) // QIconView void OVersatileView::sort() // #### make in next major release // QListView void OVersatileView::sort( bool ascending = TRUE ) // QIconView */ |