#!/usr/bin/env python """************************************************************************** ** $Id$ ** ** Copyright (C) 1992-2000 Trolltech AS. All rights reserved. ** Some corrections by M. Biermaier (http://www.office-m.at) ** ** This file is part of an example program for Qt. This example ** program may be used, distributed and modified without limitation. ** ***************************************************************************""" import sys from qt import * folder_closed_xpm = [ "16 16 9 1", "g c #808080", "b c #c0c000", "e c #c0c0c0", "# c #000000", "c c #ffff00", ". c None", "a c #585858", "f c #a0a0a4", "d c #ffffff", "..###...........", ".#abc##.........", ".#daabc#####....", ".#ddeaabbccc#...", ".#dedeeabbbba...", ".#edeeeeaaaab#..", ".#deeeeeeefe#ba.", ".#eeeeeeefef#ba.", ".#eeeeeefeff#ba.", ".#eeeeefefff#ba.", ".##geefeffff#ba.", "...##gefffff#ba.", ".....##fffff#ba.", ".......##fff#b##", ".........##f#b##", "...........####." ] folder_open_xpm = [ "16 16 11 1", "# c #000000", "g c #c0c0c0", "e c #303030", "a c #ffa858", "b c #808080", "d c #a0a0a4", "f c #585858", "c c #ffdca8", "h c #dcdcdc", "i c #ffffff", ". c None", "....###.........", "....#ab##.......", "....#acab####...", "###.#acccccca#..", "#ddefaaaccccca#.", "#bdddbaaaacccab#", ".eddddbbaaaacab#", ".#bddggdbbaaaab#", "..edgdggggbbaab#", "..#bgggghghdaab#", "...ebhggghicfab#", "....#edhhiiidab#", "......#egiiicfb#", "........#egiibb#", "..........#egib#", "............#ee#" ] folder_locked = [ "16 16 10 1", "h c #808080", "b c #ffa858", "f c #c0c0c0", "e c #c05800", "# c #000000", "c c #ffdca8", ". c None", "a c #585858", "g c #a0a0a4", "d c #ffffff", "..#a#...........", ".#abc####.......", ".#daa#eee#......", ".#ddf#e##b#.....", ".#dfd#e#bcb##...", ".#fdccc#daaab#..", ".#dfbbbccgfg#ba.", ".#ffb#ebbfgg#ba.", ".#ffbbe#bggg#ba.", ".#fffbbebggg#ba.", ".##hf#ebbggg#ba.", "...###e#gggg#ba.", ".....#e#gggg#ba.", "......###ggg#b##", ".........##g#b##", "...........####." ] pix_file = [ "16 16 7 1", "# c #000000", "b c #ffffff", "e c #000000", "d c #404000", "c c #c0c000", "a c #ffffc0", ". c None", "................", ".........#......", "......#.#a##....", ".....#b#bbba##..", "....#b#bbbabbb#.", "...#b#bba##bb#..", "..#b#abb#bb##...", ".#a#aab#bbbab##.", "#a#aaa#bcbbbbbb#", "#ccdc#bcbbcbbb#.", ".##c#bcbbcabb#..", "...#acbacbbbe...", "..#aaaacaba#....", "...##aaaaa#.....", ".....##aa#......", ".......##......." ] folderLocked = None folderClosed = None folderOpened = None fileNormal = None class FileItem( QListViewItem ) : def __init__( self, parent=None, s1=QString.null, s2=QString.null ): QListViewItem.__init__( self, parent, s1, s2 ) self.pix = None def setPixmap( self, p ) : self.pix = p self.setup() self.widthChanged( 0 ) self.invalidateHeight() self.repaint() def pixmap( self, i ) : if i : return None else : return self.pix; # Class Directory class Directory( QListViewItem ) : def __init__( self, parent=None, filename=QString.null, col2=QString.null ): QListViewItem.__init__( self, parent, filename, col2 ) self.pix = None global folderLocked, folderClosed, folderOpened, fileNormal self.showDirsOnly = False if isinstance(parent, QListView): self.p = None self.showDirsOnly = parent.showDirsOnly() self.f = QFile( QString('/') ) else: self.p = parent self.showDirsOnly = parent.showDirsOnly self.f = QFile( QString(filename) ) self.readable = QDir( self.fullName() ).isReadable() if not self.readable : self.setPixmap( folderLocked ) else : self.setPixmap( folderClosed ) def setPixmap( self, px ) : self.pix = px self.setup() self.widthChanged( 0 ) self.invalidateHeight() self.repaint() def pixmap( self, i ) : if i : return None else : return self.pix def setOpen( self, o ) : if o : self.setPixmap( folderOpened ) else : self.setPixmap( folderClosed ) if o and not self.childCount() : s = QString( self.fullName() ) thisDir = QDir( s ) if not thisDir.isReadable() : self.readable = False self.setExpandable( False ) return self.listView().setUpdatesEnabled( False ) files = thisDir.entryInfoList() if files : fi = QFileInfo() for it in files: fi = it if str(fi.fileName()) == "." or str(fi.fileName()) == ".." : continue # nothing elif fi.isSymLink() and not self.showDirsOnly : item = FileItem( self, fi.fileName(), "Symbolic Link" ) item.setPixmap( fileNormal ) elif fi.isDir() : Directory( self, fi.fileName() ) elif not self.showDirsOnly : if fi.isFile() : item = FileItem( self, fi.fileName(), "File" ) else : item = FileItem( self, fi.fileName(), "Special" ) item.setPixmap( fileNormal ) self.listView().setUpdatesEnabled( True ) QListViewItem.setOpen( self, o ) def setup( self ): self.setExpandable( True ) QListViewItem.setup( self ) def fullName( self ): s = QString() if self.p : s = self.p.fullName() s.append( self.f.name() ) s.append( "/" ) else : s = self.f.name() return s def text( self, column ) : if column == 0 : return self.f.name() elif self.readable : return "Directory" else : return "Unreadable Directory" # Class DirectoryView class DirectoryView( QListView ): def __init__( self, parent=None, name=None, sdo=False ): QListView.__init__( self, parent, name ) self.dirsOnly = sdo self.oldCurrent = 0 self.dropItem = 0 self.presspos = QPoint(0,0) self.mousePressed = False global folderLocked, folderClosed, folderOpened, fileNormal #= QPixmap() self.autoopenTime = 750 self.autoopen_timer = QTimer( self ) if not folderLocked : folderLocked = QPixmap( folder_locked ) folderClosed = QPixmap( folder_closed_xpm ) folderOpened = QPixmap( folder_open_xpm ) fileNormal = QPixmap( pix_file ) self.connect( self, SIGNAL("doubleClicked(QListViewItem *)"), self.slotFolderSelected ) self.connect( self, SIGNAL("returnPressed(QListViewItem *)"), self.slotFolderSelected ) self.setAcceptDrops( True ) self.viewport().setAcceptDrops( True ) self.connect( self.autoopen_timer, SIGNAL("timeout()"), self.openFolder ) def showDirsOnly( self ): return self.dirsOnly def slotFolderSelected( self, i ): if not i or not self.showDirsOnly(): return dir = i self.emit( PYSIGNAL("folderSelected(const QString &)"), (dir.fullName(), ) ) def openFolder( self ): self.autoopen_timer.stop() if self.dropItem and not self.dropItem.isOpen(): self.dropItem.setOpen( True ) self.dropItem.repaint() def contentsDragEnterEvent( self, e ): if not QUriDrag.canDecode(e) : e.ignore() return self.oldCurrent = self.currentItem() i = self.itemAt( self.contentsToViewport(e.pos()) ) if i : self.dropItem = i self.autoopen_timer.start( self.autoopenTime ) def contentsDragMoveEvent( self, e ) : if not QUriDrag.canDecode(e) : e.ignore() return vp = self.contentsToViewport( e.pos() ) i = self.itemAt( vp ) if i : self.setSelected( i, True ) e.accept() if i != self.dropItem : self.autoopen_timer.stop() self.dropItem = i self.autoopen_timer.start( self.autoopenTime ) if e.action() == QDropEvent.Copy: pass elif e.action() == QDropEvent.Move: e.acceptAction() elif e.action() == QDropEvent.Link: e.acceptAction() else: pass else : e.ignore() self.autoopen_timer.stop() self.dropItem = 0 def contentsDragLeaveEvent( self, QDragLeaveEvent ) : self.autoopen_timer.stop() self.dropItem = 0 self.setCurrentItem( self.oldCurrent ) self.setSelected( self.oldCurrent, True ) def contentsDropEvent( self, e ): self.autoopen_timer.stop() if not QUriDrag.canDecode(e) : e.ignore() return item = self.itemAt( self.contentsToViewport(e.pos()) ) if item : lst = QStringList() QUriDrag.decodeLocalFiles( e, lst ) if e.action() == QDropEvent.Copy: s = QString("Copy") elif e.action() == QDropEvent.Move: s = QString("Move") e.acceptAction() elif e.action() == QDropEvent.Link: s = QString("Link") e.acceptAction() else: s = QString("Unknown") s += "\n\n" e.accept() for filename in lst: s += filename s += "\n" s += "\nTo\n\n " s += self.fullPath(item) QMessageBox.information( self, "Drop target", s, "Not implemented" ) else : e.ignore() def fullPath( self, item ): fullpath = QString( item.text(0) ) item = item.parent() while item: newpath = item.text(0) if item.parent(): newpath += "/" newpath += fullpath fullpath = newpath item = item.parent() return fullpath def contentsMousePressEvent( self, e ) : QListView.contentsMousePressEvent( self, e ) p = QPoint( self.contentsToViewport( e.pos() ) ) i = self.itemAt( p ) if i : # if the user clicked into the root decoration of the item, don't try to start a drag! if self.rootIsDecorated(): isdecorated = 1 else : isdecorated = 0 if p.x() > self.header().sectionPos( self.header().mapToIndex( 0 )) + self.treeStepSize() * ( i.depth() + isdecorated + self.itemMargin() or p.x() < self.header().sectionPos( self.header().mapToIndex( 0 ) ) ) : self.presspos.setX(e.pos().x()) self.presspos.setY(e.pos().y()) self.mousePressed = True def contentsMouseMoveEvent( self, e ): offset = QPoint( self.presspos.x() - e.pos().x(), self.presspos.y() - e.pos().y() ) if self.mousePressed and (offset).manhattanLength() > QApplication.startDragDistance() : self.mousePressed = False item = self.itemAt( self.contentsToViewport(self.presspos) ) if item : source = self.fullPath(item) if QFile.exists(source) : ud = QUriDrag(self.viewport()) ud.setFileNames( QStringList (source) ) if ud.drag() : QMessageBox.information( self, "Drag source", QString("Delete ")+source, "Not implemented" ) def contentsMouseReleaseEvent( self, QMouseEvent ): self.mousePressed = False def setDir( self, s ): it = QListViewItem( self ) it.setOpen(False) thisDir = QDir( s ) it = QListViewItem( self ) it.setOpen(False) lst = QStringList( QStringList.split( "/", s ) ) listview2 = [] listview2.extend( lst ) item = self.firstChild() for it2 in listview2 : while item : if item.text( 0 ) == it2 : item.setOpen( True ) break item = item.itemBelow() if item: self.setCurrentItem( item ) def main( args ): a = QApplication( args ) mw = DirectoryView() mw.addColumn( "Name" ) mw.addColumn( "Type" ) mw.setTreeStepSize( 20 ) roots = QDir.drives() if roots : for it in roots: fi = it root = Directory( mw, fi.filePath() ) if roots.count(it) <= 1 : root.setOpen( True ) # be interesting mw.resize( 400, 400 ) mw.setCaption( "Qt Example - Directory Browser" ) mw.setAllColumnsShowFocus( True ) a.setMainWidget( mw ) mw.show() a.exec_loop() if __name__=="__main__": main(sys.argv)