summaryrefslogtreecommitdiffstats
path: root/libk3b/projects/datacd/k3bdiritem.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'libk3b/projects/datacd/k3bdiritem.cpp')
-rw-r--r--libk3b/projects/datacd/k3bdiritem.cpp406
1 files changed, 406 insertions, 0 deletions
diff --git a/libk3b/projects/datacd/k3bdiritem.cpp b/libk3b/projects/datacd/k3bdiritem.cpp
new file mode 100644
index 0000000..3ea3236
--- /dev/null
+++ b/libk3b/projects/datacd/k3bdiritem.cpp
@@ -0,0 +1,406 @@
+/*
+ *
+ * $Id: k3bdiritem.cpp 652578 2007-04-11 14:21:04Z trueg $
+ * Copyright (C) 2003 Sebastian Trueg <trueg@k3b.org>
+ *
+ * This file is part of the K3b project.
+ * Copyright (C) 1998-2007 Sebastian Trueg <trueg@k3b.org>
+ *
+ * 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 "k3bdiritem.h"
+#include "k3bdatadoc.h"
+#include "k3bsessionimportitem.h"
+#include "k3bfileitem.h"
+
+#include <qstring.h>
+#include <qptrlist.h>
+
+#include <kdebug.h>
+
+
+K3bDirItem::K3bDirItem(const QString& name, K3bDataDoc* doc, K3bDirItem* parentDir)
+ : K3bDataItem( doc, parentDir ),
+ m_size(0),
+ m_followSymlinksSize(0),
+ m_blocks(0),
+ m_followSymlinksBlocks(0),
+ m_files(0),
+ m_dirs(0)
+{
+ m_k3bName = name;
+
+ // add automagically like a qlistviewitem
+ if( parent() )
+ parent()->addDataItem( this );
+}
+
+
+K3bDirItem::K3bDirItem( const K3bDirItem& item )
+ : K3bDataItem( item ),
+ m_size(0),
+ m_followSymlinksSize(0),
+ m_blocks(0),
+ m_followSymlinksBlocks(0),
+ m_files(0),
+ m_dirs(0),
+ m_localPath( item.m_localPath )
+{
+ for( QPtrListIterator<K3bDataItem> it( item.children() ); *it; ++it )
+ addDataItem( (*it)->copy() );
+}
+
+K3bDirItem::~K3bDirItem()
+{
+ // delete all children
+ // doing this by hand is much saver than using the
+ // auto-delete feature since some of the items' destructors
+ // may change the list
+ K3bDataItem* i = m_children.first();
+ while( i ) {
+ // it is important to use takeDataItem here to be sure
+ // the size gets updated properly
+ takeDataItem(i);
+ delete i;
+ i = m_children.first();
+ }
+
+ // this has to be done after deleting the children
+ // because the directory itself has a size of 0 in K3b
+ // and all it's files' sizes have already been substracted
+ take();
+}
+
+
+K3bDataItem* K3bDirItem::copy() const
+{
+ return new K3bDirItem( *this );
+}
+
+
+K3bDirItem* K3bDirItem::getDirItem() const
+{
+ return const_cast<K3bDirItem*>(this);
+}
+
+K3bDirItem* K3bDirItem::addDataItem( K3bDataItem* item )
+{
+ // check if we are a subdir of item
+ if( K3bDirItem* dirItem = dynamic_cast<K3bDirItem*>(item) ) {
+ if( dirItem->isSubItem( this ) ) {
+ kdDebug() << "(K3bDirItem) trying to move a dir item down in it's own tree." << endl;
+ return this;
+ }
+ }
+
+ if( m_children.findRef( item ) == -1 ) {
+ if( item->isFile() ) {
+ // do we replace an old item?
+ QString name = item->k3bName();
+ int cnt = 1;
+ while( K3bDataItem* oldItem = find( name ) ) {
+ if( !oldItem->isDir() && oldItem->isFromOldSession() ) {
+ // in this case we remove this item from it's parent and save it in the new one
+ // to be able to recover it
+ oldItem->take();
+ static_cast<K3bSessionImportItem*>(oldItem)->setReplaceItem( static_cast<K3bFileItem*>(item) );
+ static_cast<K3bFileItem*>(item)->setReplacedItemFromOldSession( oldItem );
+ break;
+ }
+ else {
+ //
+ // add a counter to the filename
+ //
+ if( item->k3bName()[item->k3bName().length()-4] == '.' )
+ name = item->k3bName().left( item->k3bName().length()-4 ) + QString::number(cnt++) + item->k3bName().right(4);
+ else
+ name = item->k3bName() + QString::number(cnt++);
+ }
+ }
+ item->setK3bName( name );
+ }
+
+ m_children.append( item->take() );
+ updateSize( item, false );
+ if( item->isDir() )
+ updateFiles( ((K3bDirItem*)item)->numFiles(), ((K3bDirItem*)item)->numDirs()+1 );
+ else
+ updateFiles( 1, 0 );
+
+ item->m_parentDir = this;
+
+ // inform the doc
+ if( doc() )
+ doc()->itemAddedToDir( this, item );
+ }
+
+ return this;
+}
+
+
+K3bDataItem* K3bDirItem::takeDataItem( K3bDataItem* item )
+{
+ int x = m_children.findRef( item );
+ if( x > -1 ) {
+ K3bDataItem* item = m_children.take();
+ updateSize( item, true );
+ if( item->isDir() )
+ updateFiles( -1*((K3bDirItem*)item)->numFiles(), -1*((K3bDirItem*)item)->numDirs()-1 );
+ else
+ updateFiles( -1, 0 );
+
+ item->m_parentDir = 0;
+
+ // inform the doc
+ if( doc() )
+ doc()->itemRemovedFromDir( this, item );
+
+ if( item->isFile() ) {
+ // restore the item imported from an old session
+ if( static_cast<K3bFileItem*>(item)->replaceItemFromOldSession() )
+ addDataItem( static_cast<K3bFileItem*>(item)->replaceItemFromOldSession() );
+ }
+
+ return item;
+ }
+ else
+ return 0;
+}
+
+
+K3bDataItem* K3bDirItem::nextSibling() const
+{
+ if( !m_children.isEmpty() )
+ return m_children.getFirst();
+ else
+ return K3bDataItem::nextSibling();
+}
+
+
+K3bDataItem* K3bDirItem::nextChild( K3bDataItem* prev ) const
+{
+ // search for prev in children
+ if( m_children.findRef( prev ) < 0 ) {
+ return 0;
+ }
+ else
+ return m_children.next();
+}
+
+
+bool K3bDirItem::alreadyInDirectory( const QString& filename ) const
+{
+ return (find( filename ) != 0);
+}
+
+
+K3bDataItem* K3bDirItem::find( const QString& filename ) const
+{
+ for( QPtrListIterator<K3bDataItem> it( m_children ); it.current(); ++it ) {
+ if( it.current()->k3bName() == filename )
+ return it.current();
+ }
+ return 0;
+}
+
+
+K3bDataItem* K3bDirItem::findByPath( const QString& p )
+{
+ if( p.isEmpty() || p == "/" )
+ return this;
+
+ QString path = p;
+ if( path.startsWith("/") )
+ path = path.mid(1);
+ int pos = path.find( "/" );
+ if( pos < 0 )
+ return find( path );
+ else {
+ // do it recursivly
+ K3bDataItem* item = find( path.left(pos) );
+ if( item && item->isDir() )
+ return ((K3bDirItem*)item)->findByPath( path.mid( pos+1 ) );
+ else
+ return 0;
+ }
+}
+
+
+bool K3bDirItem::mkdir( const QString& dirPath )
+{
+ //
+ // An absolut path always starts at the root item
+ //
+ if( dirPath[0] == '/' ) {
+ if( parent() )
+ return parent()->mkdir( dirPath );
+ else
+ return mkdir( dirPath.mid( 1 ) );
+ }
+
+ if( findByPath( dirPath ) )
+ return false;
+
+ QString restPath;
+ QString dirName;
+ int pos = dirPath.find( '/' );
+ if( pos == -1 ) {
+ dirName = dirPath;
+ }
+ else {
+ dirName = dirPath.left( pos );
+ restPath = dirPath.mid( pos+1 );
+ }
+
+ K3bDataItem* dir = find( dirName );
+ if( !dir )
+ dir = new K3bDirItem( dirName, doc(), this );
+ else if( !dir->isDir() )
+ return false;
+
+ if( !restPath.isEmpty() )
+ return static_cast<K3bDirItem*>(dir)->mkdir( restPath );
+
+ return true;
+}
+
+
+KIO::filesize_t K3bDirItem::itemSize( bool followsylinks ) const
+{
+ if( followsylinks )
+ return m_followSymlinksSize;
+ else
+ return m_size;
+}
+
+
+K3b::Msf K3bDirItem::itemBlocks( bool followSymlinks ) const
+{
+ if( followSymlinks )
+ return m_followSymlinksBlocks;
+ else
+ return m_blocks;
+}
+
+
+bool K3bDirItem::isSubItem( K3bDataItem* item ) const
+{
+ if( dynamic_cast<K3bDirItem*>(item) == this )
+ return true;
+
+ K3bDirItem* d = item->parent();
+ while( d ) {
+ if( d == this ) {
+ return true;
+ }
+ d = d->parent();
+ }
+
+ return false;
+}
+
+
+long K3bDirItem::numFiles() const
+{
+ return m_files;
+}
+
+
+long K3bDirItem::numDirs() const
+{
+ return m_dirs;
+}
+
+
+bool K3bDirItem::isRemoveable() const
+{
+ if( !K3bDataItem::isRemoveable() )
+ return false;
+
+ for( QPtrListIterator<K3bDataItem> it( m_children ); it.current(); ++it ) {
+ if( !it.current()->isRemoveable() )
+ return false;
+ }
+
+ return true;
+}
+
+
+void K3bDirItem::updateSize( K3bDataItem* item, bool removed )
+{
+ if ( !item->isFromOldSession() ) {
+ if( removed ) {
+ m_followSymlinksSize -= item->itemSize( true );
+ m_size -= item->itemSize( false );
+ m_followSymlinksBlocks -= item->itemBlocks( true ).lba();
+ m_blocks -= item->itemBlocks( false ).lba();
+ }
+ else {
+ m_followSymlinksSize += item->itemSize( true );
+ m_size += item->itemSize( false );
+ m_followSymlinksBlocks += item->itemBlocks( true ).lba();
+ m_blocks += item->itemBlocks( false ).lba();
+ }
+ }
+
+ if( parent() )
+ parent()->updateSize( item, removed );
+}
+
+void K3bDirItem::updateFiles( long files, long dirs )
+{
+ m_files += files;
+ m_dirs += dirs;
+ if( parent() )
+ parent()->updateFiles( files, dirs );
+}
+
+
+bool K3bDirItem::isFromOldSession() const
+{
+ for( QPtrListIterator<K3bDataItem> it( m_children ); it.current(); ++it ) {
+ if( (*it)->isFromOldSession() )
+ return true;
+ }
+ return false;
+}
+
+
+bool K3bDirItem::writeToCd() const
+{
+ // check if this dir contains items to write
+ for( QPtrListIterator<K3bDataItem> it( m_children ); it.current(); ++it ) {
+ if( (*it)->writeToCd() )
+ return true;
+ }
+ return K3bDataItem::writeToCd();
+}
+
+
+K3bRootItem::K3bRootItem( K3bDataDoc* doc )
+ : K3bDirItem( "root", doc, 0 )
+{
+}
+
+
+K3bRootItem::~K3bRootItem()
+{
+}
+
+
+const QString& K3bRootItem::k3bName() const
+{
+ return doc()->isoOptions().volumeID();
+}
+
+
+void K3bRootItem::setK3bName( const QString& text )
+{
+ doc()->setVolumeID( text );
+}