diff options
author | tpearson <tpearson@283d02a7-25f6-0310-bc7c-ecb5cbfe19da> | 2010-02-03 02:15:56 +0000 |
---|---|---|
committer | tpearson <tpearson@283d02a7-25f6-0310-bc7c-ecb5cbfe19da> | 2010-02-03 02:15:56 +0000 |
commit | 50b48aec6ddd451a6d1709c0942477b503457663 (patch) | |
tree | a9ece53ec06fd0a2819de7a2a6de997193566626 /libk3b/core/k3bglobals.cpp | |
download | k3b-50b48aec6ddd451a6d1709c0942477b503457663.tar.gz k3b-50b48aec6ddd451a6d1709c0942477b503457663.zip |
Added abandoned KDE3 version of K3B
git-svn-id: svn://anonsvn.kde.org/home/kde/branches/trinity/applications/k3b@1084400 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
Diffstat (limited to 'libk3b/core/k3bglobals.cpp')
-rw-r--r-- | libk3b/core/k3bglobals.cpp | 634 |
1 files changed, 634 insertions, 0 deletions
diff --git a/libk3b/core/k3bglobals.cpp b/libk3b/core/k3bglobals.cpp new file mode 100644 index 0000000..fc5a4e1 --- /dev/null +++ b/libk3b/core/k3bglobals.cpp @@ -0,0 +1,634 @@ +/* + * + * $Id: k3bglobals.cpp 659634 2007-04-30 14:51:32Z trueg $ + * Copyright (C) 2003 Sebastian Trueg <[email protected]> + * + * This file is part of the K3b project. + * Copyright (C) 1998-2007 Sebastian Trueg <[email protected]> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * See the file "COPYING" for the exact licensing terms. + */ + +#include <config.h> + + +#include "k3bglobals.h" +#include <k3bversion.h> +#include <k3bdevice.h> +#include <k3bdevicemanager.h> +#include <k3bdeviceglobals.h> +#include <k3bexternalbinmanager.h> +#include <k3bcore.h> +#include <k3bhalconnection.h> + +#include <kdeversion.h> +#include <kglobal.h> +#include <klocale.h> +#include <kstandarddirs.h> +#include <kconfig.h> +#include <kapplication.h> +#include <kdebug.h> +#include <kio/job.h> +#include <kio/netaccess.h> +#include <kurl.h> +#include <dcopref.h> +#include <kprocess.h> + +#include <qdatastream.h> +#include <qdir.h> +#include <qfile.h> + +#include <cmath> +#include <sys/utsname.h> +#include <sys/stat.h> + +#if defined(__FreeBSD__) || defined(__NetBSD__) +# include <sys/param.h> +# include <sys/mount.h> +# include <sys/endian.h> +# define bswap_16(x) bswap16(x) +# define bswap_32(x) bswap32(x) +# define bswap_64(x) bswap64(x) +#else +# include <byteswap.h> +#endif +#ifdef HAVE_SYS_STATVFS_H +# include <sys/statvfs.h> +#endif +#ifdef HAVE_SYS_VFS_H +# include <sys/vfs.h> +#endif + + +/* +struct Sample { + unsigned char msbLeft; + unsigned char lsbLeft; + unsigned char msbRight; + unsigned char lsbRight; + + short left() const { + return ( msbLeft << 8 ) | lsbLeft; + } + short right() const { + return ( msbRight << 8 ) | lsbRight; + } + void left( short d ) { + msbLeft = d >> 8; + lsbLeft = d; + } + void right( short d ) { + msbRight = d >> 8; + lsbRight = d; + } +}; +*/ + +QString K3b::framesToString( int h, bool showFrames ) +{ + int m = h / 4500; + int s = (h % 4500) / 75; + int f = h % 75; + + QString str; + + if( showFrames ) { + // cdrdao needs the MSF format where 1 second has 75 frames! + str.sprintf( "%.2i:%.2i:%.2i", m, s, f ); + } + else + str.sprintf( "%.2i:%.2i", m, s ); + + return str; +} + +/*QString K3b::sizeToTime(long size) +{ + int h = size / sizeof(Sample) / 588; + return framesToString(h, false); +}*/ + + +Q_INT16 K3b::swapByteOrder( const Q_INT16& i ) +{ + return bswap_16( i ); + //((i << 8) & 0xff00) | ((i >> 8 ) & 0xff); +} + + +Q_INT32 K3b::swapByteOrder( const Q_INT32& i ) +{ + //return ((i << 24) & 0xff000000) | ((i << 8) & 0xff0000) | ((i >> 8) & 0xff00) | ((i >> 24) & 0xff ); + return bswap_32( i ); +} + + +Q_INT64 K3b::swapByteOrder( const Q_INT64& i ) +{ + return bswap_64( i ); +} + + +int K3b::round( double d ) +{ + return (int)( floor(d) + 0.5 <= d ? ceil(d) : floor(d) ); +} + + +QString K3b::findUniqueFilePrefix( const QString& _prefix, const QString& path ) +{ + QString url; + if( path.isEmpty() || !QFile::exists(path) ) + url = defaultTempPath(); + else + url = prepareDir( path ); + + QString prefix = _prefix; + if( prefix.isEmpty() ) + prefix = "k3b_"; + + // now create the unique prefix + QDir dir( url ); + QStringList entries = dir.entryList( QDir::DefaultFilter, QDir::Name ); + int i = 0; + for( QStringList::iterator it = entries.begin(); + it != entries.end(); ++it ) { + if( (*it).startsWith( prefix + QString::number(i) ) ) { + i++; + it = entries.begin(); + } + } + + return url + prefix + QString::number(i); +} + + +QString K3b::findTempFile( const QString& ending, const QString& d ) +{ + return findUniqueFilePrefix( "k3b_", d ) + ( ending.isEmpty() ? QString::null : (QString::fromLatin1(".") + ending) ); +} + + +QString K3b::defaultTempPath() +{ + QString oldGroup = kapp->config()->group(); + kapp->config()->setGroup( "General Options" ); + QString url = kapp->config()->readPathEntry( "Temp Dir", KGlobal::dirs()->resourceDirs( "tmp" ).first() ); + kapp->config()->setGroup( oldGroup ); + return prepareDir(url); +} + + +QString K3b::prepareDir( const QString& dir ) +{ + return (dir + (dir[dir.length()-1] != '/' ? "/" : "")); +} + + +QString K3b::parentDir( const QString& path ) +{ + QString parent = path; + if( path[path.length()-1] == '/' ) + parent.truncate( parent.length()-1 ); + + int pos = parent.findRev( '/' ); + if( pos >= 0 ) + parent.truncate( pos+1 ); + else // relative path, do anything... + parent = "/"; + + return parent; +} + + +QString K3b::fixupPath( const QString& path ) +{ + QString s; + bool lastWasSlash = false; + for( unsigned int i = 0; i < path.length(); ++i ) { + if( path[i] == '/' ) { + if( !lastWasSlash ) { + lastWasSlash = true; + s.append( "/" ); + } + } + else { + lastWasSlash = false; + s.append( path[i] ); + } + } + + return s; +} + + +K3bVersion K3b::kernelVersion() +{ + // initialize kernel version + K3bVersion v; + utsname unameinfo; + if( ::uname(&unameinfo) == 0 ) { + v = QString::fromLocal8Bit( unameinfo.release ); + kdDebug() << "kernel version: " << v << endl; + } + else + kdError() << "could not determine kernel version." << endl; + return v; +} + + +K3bVersion K3b::simpleKernelVersion() +{ + return kernelVersion().simplify(); +} + + +QString K3b::systemName() +{ + QString v; + utsname unameinfo; + if( ::uname(&unameinfo) == 0 ) { + v = QString::fromLocal8Bit( unameinfo.sysname ); + } + else + kdError() << "could not determine system name." << endl; + return v; +} + + +bool K3b::kbFreeOnFs( const QString& path, unsigned long& size, unsigned long& avail ) +{ + struct statvfs fs; + if( ::statvfs( QFile::encodeName(path), &fs ) == 0 ) { + unsigned long kBfak = fs.f_frsize/1024; + + size = fs.f_blocks*kBfak; + avail = fs.f_bavail*kBfak; + + return true; + } + else + return false; +} + + +KIO::filesize_t K3b::filesize( const KURL& url ) +{ + if( url.isLocalFile() ) { + k3b_struct_stat buf; + if ( !k3b_stat( QFile::encodeName( url.path() ), &buf ) ) { + return (KIO::filesize_t)buf.st_size; + } + } + + KIO::UDSEntry uds; + KIO::NetAccess::stat( url, uds, 0 ); + for( KIO::UDSEntry::const_iterator it = uds.begin(); it != uds.end(); ++it ) { + if( (*it).m_uds == KIO::UDS_SIZE ) { + return (*it).m_long; + } + } + + return ( KIO::filesize_t )0; +} + + +KIO::filesize_t K3b::imageFilesize( const KURL& url ) +{ + KIO::filesize_t size = K3b::filesize( url ); + int cnt = 0; + while( KIO::NetAccess::exists( KURL::fromPathOrURL( url.url() + '.' + QString::number(cnt).rightJustify( 3, '0' ) ), true ) ) + size += K3b::filesize( KURL::fromPathOrURL( url.url() + '.' + QString::number(cnt++).rightJustify( 3, '0' ) ) ); + return size; +} + + +QString K3b::cutFilename( const QString& name, unsigned int len ) +{ + if( name.length() > len ) { + QString ret = name; + + // determine extension (we think of an extension to be at most 5 chars in length) + int pos = name.find( '.', -6 ); + if( pos > 0 ) + len -= (name.length() - pos); + + ret.truncate( len ); + + if( pos > 0 ) + ret.append( name.mid( pos ) ); + + return ret; + } + else + return name; +} + + +QString K3b::removeFilenameExtension( const QString& name ) +{ + QString v = name; + int dotpos = v.findRev( '.' ); + if( dotpos > 0 ) + v.truncate( dotpos ); + return v; +} + + +QString K3b::appendNumberToFilename( const QString& name, int num, unsigned int maxlen ) +{ + // determine extension (we think of an extension to be at most 5 chars in length) + QString result = name; + QString ext; + int pos = name.find( '.', -6 ); + if( pos > 0 ) { + ext = name.mid(pos); + result.truncate( pos ); + } + + ext.prepend( QString::number(num) ); + result.truncate( maxlen - ext.length() ); + + return result + ext; +} + + +bool K3b::plainAtapiSupport() +{ + // FIXME: what about BSD? + return ( K3b::simpleKernelVersion() >= K3bVersion( 2, 5, 40 ) ); +} + + +bool K3b::hackedAtapiSupport() +{ + // IMPROVEME!!! + // FIXME: since when does the kernel support this? + return ( K3b::simpleKernelVersion() >= K3bVersion( 2, 4, 0 ) ); +} + + +QString K3b::externalBinDeviceParameter( K3bDevice::Device* dev, const K3bExternalBin* bin ) +{ +#ifdef Q_OS_LINUX + // + // experimental: always use block devices on 2.6 kernels + // + if( simpleKernelVersion() >= K3bVersion( 2, 6, 0 ) ) + return dev->blockDeviceName(); + else +#endif + if( dev->interfaceType() == K3bDevice::SCSI ) + return dev->busTargetLun(); + else if( (plainAtapiSupport() && bin->hasFeature("plain-atapi") ) ) + return dev->blockDeviceName(); + else + return QString("ATAPI:%1").arg(dev->blockDeviceName()); +} + + +int K3b::writingAppFromString( const QString& s ) +{ + if( s.lower() == "cdrdao" ) + return K3b::CDRDAO; + else if( s.lower() == "cdrecord" ) + return K3b::CDRECORD; + else if( s.lower() == "dvdrecord" ) + return K3b::DVDRECORD; + else if( s.lower() == "growisofs" ) + return K3b::GROWISOFS; + else if( s.lower() == "dvd+rw-format" ) + return K3b::DVD_RW_FORMAT; + else + return K3b::DEFAULT; +} + + +QString K3b::writingModeString( int mode ) +{ + if( mode == WRITING_MODE_AUTO ) + return i18n("Auto"); + else + return K3bDevice::writingModeString( mode ); +} + + +QString K3b::resolveLink( const QString& file ) +{ + QFileInfo f( file ); + QStringList steps( f.absFilePath() ); + while( f.isSymLink() ) { + QString p = f.readLink(); + if( !p.startsWith( "/" ) ) + p.prepend( f.dirPath(true) + "/" ); + f.setFile( p ); + if( steps.contains( f.absFilePath() ) ) { + kdDebug() << "(K3b) symlink loop detected." << endl; + break; + } + else + steps.append( f.absFilePath() ); + } + return f.absFilePath(); +} + + +K3bDevice::Device* K3b::urlToDevice( const KURL& deviceUrl ) +{ + if( deviceUrl.protocol() == "media" || deviceUrl.protocol() == "system" ) { + kdDebug() << "(K3b) Asking mediamanager for " << deviceUrl.fileName() << endl; + DCOPRef mediamanager("kded", "mediamanager"); + DCOPReply reply = mediamanager.call("properties(QString)", deviceUrl.fileName()); + QStringList properties = reply; + if( !reply.isValid() || properties.count() < 6 ) { + kdError() << "(K3b) Invalid reply from mediamanager" << endl; + return 0; + } + else { + kdDebug() << "(K3b) Reply from mediamanager " << properties[5] << endl; + return k3bcore->deviceManager()->findDevice( properties[5] ); + } + } + + return k3bcore->deviceManager()->findDevice( deviceUrl.path() ); +} + + +KURL K3b::convertToLocalUrl( const KURL& url ) +{ + if( !url.isLocalFile() ) { +#if KDE_IS_VERSION(3,4,91) + return KIO::NetAccess::mostLocalURL( url, 0 ); +#else +#ifndef UDS_LOCAL_PATH +#define UDS_LOCAL_PATH (72 | KIO::UDS_STRING) +#else + using namespace KIO; +#endif + KIO::UDSEntry e; + if( KIO::NetAccess::stat( url, e, 0 ) ) { + const KIO::UDSEntry::ConstIterator end = e.end(); + for( KIO::UDSEntry::ConstIterator it = e.begin(); it != end; ++it ) { + if( (*it).m_uds == UDS_LOCAL_PATH && !(*it).m_str.isEmpty() ) + return KURL::fromPathOrURL( (*it).m_str ); + } + } +#endif + } + + return url; +} + + +KURL::List K3b::convertToLocalUrls( const KURL::List& urls ) +{ + KURL::List r; + for( KURL::List::const_iterator it = urls.constBegin(); it != urls.constEnd(); ++it ) + r.append( convertToLocalUrl( *it ) ); + return r; +} + + +Q_INT16 K3b::fromLe16( char* data ) +{ +#ifdef WORDS_BIGENDIAN // __BYTE_ORDER == __BIG_ENDIAN + return swapByteOrder( *((Q_INT16*)data) ); +#else + return *((Q_INT16*)data); +#endif +} + + +Q_INT32 K3b::fromLe32( char* data ) +{ +#ifdef WORDS_BIGENDIAN // __BYTE_ORDER == __BIG_ENDIAN + return swapByteOrder( *((Q_INT32*)data) ); +#else + return *((Q_INT32*)data); +#endif +} + + +Q_INT64 K3b::fromLe64( char* data ) +{ +#ifdef WORDS_BIGENDIAN // __BYTE_ORDER == __BIG_ENDIAN + return swapByteOrder( *((Q_INT64*)data) ); +#else + return *((Q_INT64*)data); +#endif +} + + +QString K3b::findExe( const QString& name ) +{ + // first we search the path + QString bin = KStandardDirs::findExe( name ); + + // then go on with our own little list + if( bin.isEmpty() ) + bin = KStandardDirs::findExe( name, k3bcore->externalBinManager()->searchPath().join(":") ); + + return bin; +} + + +bool K3b::isMounted( K3bDevice::Device* dev ) +{ + if( !dev ) + return false; + + return !KIO::findDeviceMountPoint( dev->blockDeviceName() ).isEmpty(); +} + + +bool K3b::unmount( K3bDevice::Device* dev ) +{ + if( !dev ) + return false; + + QString mntDev = dev->blockDeviceName(); + +#if KDE_IS_VERSION(3,4,0) + // first try to unmount it the standard way + if( KIO::NetAccess::synchronousRun( KIO::unmount( mntDev, false ), 0 ) ) + return true; +#endif + + QString umountBin = K3b::findExe( "umount" ); + if( !umountBin.isEmpty() ) { + KProcess p; + p << umountBin; + p << "-l"; // lazy unmount + p << dev->blockDeviceName(); + p.start( KProcess::Block ); + if( !p.exitStatus() ) + return true; + } + + // now try pmount + QString pumountBin = K3b::findExe( "pumount" ); + if( !pumountBin.isEmpty() ) { + KProcess p; + p << pumountBin; + p << "-l"; // lazy unmount + p << dev->blockDeviceName(); + p.start( KProcess::Block ); + return !p.exitStatus(); + } + else { +#ifdef HAVE_HAL + return !K3bDevice::HalConnection::instance()->unmount( dev ); +#else + return false; +#endif + } +} + + +bool K3b::mount( K3bDevice::Device* dev ) +{ + if( !dev ) + return false; + + QString mntDev = dev->blockDeviceName(); + +#if KDE_IS_VERSION(3,4,0) + // first try to mount it the standard way + if( KIO::NetAccess::synchronousRun( KIO::mount( true, 0, mntDev, false ), 0 ) ) + return true; +#endif + +#ifdef HAVE_HAL + if( !K3bDevice::HalConnection::instance()->mount( dev ) ) + return true; +#endif + + // now try pmount + QString pmountBin = K3b::findExe( "pmount" ); + if( !pmountBin.isEmpty() ) { + KProcess p; + p << pmountBin; + p << mntDev; + p.start( KProcess::Block ); + return !p.exitStatus(); + } + return false; +} + + +bool K3b::eject( K3bDevice::Device* dev ) +{ +#ifdef HAVE_HAL + if( !K3bDevice::HalConnection::instance()->eject( dev ) ) + return true; +#endif + + if( K3b::isMounted( dev ) ) + K3b::unmount( dev ); + + return dev->eject(); +} |