diff options
Diffstat (limited to 'examples/dirview')
-rw-r--r-- | examples/dirview/dirview.cpp | 532 | ||||
-rw-r--r-- | examples/dirview/dirview.doc | 35 | ||||
-rw-r--r-- | examples/dirview/dirview.h | 110 | ||||
-rw-r--r-- | examples/dirview/dirview.pro | 11 | ||||
-rw-r--r-- | examples/dirview/main.cpp | 42 |
5 files changed, 730 insertions, 0 deletions
diff --git a/examples/dirview/dirview.cpp b/examples/dirview/dirview.cpp new file mode 100644 index 000000000..ce5e96b9c --- /dev/null +++ b/examples/dirview/dirview.cpp @@ -0,0 +1,532 @@ +/**************************************************************************** +** +** Copyright (C) 1992-2008 Trolltech ASA. All rights reserved. +** +** This file is part of an example program for TQt. This example +** program may be used, distributed and modified without limitation. +** +*****************************************************************************/ + +#include "dirview.h" + +#include <qdir.h> +#include <qfile.h> +#include <qfileinfo.h> +#include <qpixmap.h> +#include <qevent.h> +#include <qpoint.h> +#include <qmessagebox.h> +#include <qdragobject.h> +#include <qmime.h> +#include <qstrlist.h> +#include <qstringlist.h> +#include <qapplication.h> +#include <qheader.h> + +static const char* 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##", + "...........####."}; + +static const char* 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#"}; + +static const char * 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##", + "...........####."}; + +static const char * 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#......", + ".......##......."}; + +TQPixmap *folderLocked = 0; +TQPixmap *folderClosed = 0; +TQPixmap *folderOpen = 0; +TQPixmap *fileNormal = 0; + +/***************************************************************************** + * + * Class Directory + * + *****************************************************************************/ + +Directory::Directory( Directory * parent, const TQString& filename ) + : TQListViewItem( parent ), f(filename), + showDirsOnly( parent->showDirsOnly ), + pix( 0 ) +{ + p = parent; + readable = TQDir( fullName() ).isReadable(); + + if ( !readable ) + setPixmap( folderLocked ); + else + setPixmap( folderClosed ); +} + + +Directory::Directory( TQListView * parent, const TQString& filename ) + : TQListViewItem( parent ), f(filename), + showDirsOnly( ( (DirectoryView*)parent )->showDirsOnly() ), + pix( 0 ) +{ + p = 0; + readable = TQDir( fullName() ).isReadable(); +} + + +void Directory::setPixmap( TQPixmap *px ) +{ + pix = px; + setup(); + widthChanged( 0 ); + invalidateHeight(); + repaint(); +} + + +const TQPixmap *Directory::pixmap( int i ) const +{ + if ( i ) + return 0; + return pix; +} + +void Directory::setOpen( bool o ) +{ + if ( o ) + setPixmap( folderOpen ); + else + setPixmap( folderClosed ); + + if ( o && !childCount() ) { + TQString s( fullName() ); + TQDir thisDir( s ); + if ( !thisDir.isReadable() ) { + readable = FALSE; + setExpandable( FALSE ); + return; + } + + listView()->setUpdatesEnabled( FALSE ); + const TQFileInfoList * files = thisDir.entryInfoList(); + if ( files ) { + TQFileInfoListIterator it( *files ); + TQFileInfo * fi; + while( (fi=it.current()) != 0 ) { + ++it; + if ( fi->fileName() == "." || fi->fileName() == ".." ) + ; // nothing + else if ( fi->isSymLink() && !showDirsOnly ) { + FileItem *item = new FileItem( this, fi->fileName(), + "Symbolic Link" ); + item->setPixmap( fileNormal ); + } + else if ( fi->isDir() ) + (void)new Directory( this, fi->fileName() ); + else if ( !showDirsOnly ) { + FileItem *item + = new FileItem( this, fi->fileName(), + fi->isFile()?"File":"Special" ); + item->setPixmap( fileNormal ); + } + } + } + listView()->setUpdatesEnabled( TRUE ); + } + TQListViewItem::setOpen( o ); +} + + +void Directory::setup() +{ + setExpandable( TRUE ); + TQListViewItem::setup(); +} + + +TQString Directory::fullName() +{ + TQString s; + if ( p ) { + s = p->fullName(); + s.append( f.name() ); + s.append( "/" ); + } else { + s = f.name(); + } + return s; +} + + +TQString Directory::text( int column ) const +{ + if ( column == 0 ) + return f.name(); + else if ( readable ) + return "Directory"; + else + return "Unreadable Directory"; +} + +/***************************************************************************** + * + * Class DirectoryView + * + *****************************************************************************/ + +DirectoryView::DirectoryView( TQWidget *parent, const char *name, bool sdo ) + : TQListView( parent, name ), dirsOnly( sdo ), oldCurrent( 0 ), + dropItem( 0 ), mousePressed( FALSE ) +{ + autoopen_timer = new TQTimer( this ); + if ( !folderLocked ) { + folderLocked = new TQPixmap( folder_locked ); + folderClosed = new TQPixmap( folder_closed_xpm ); + folderOpen = new TQPixmap( folder_open_xpm ); + fileNormal = new TQPixmap( pix_file ); + } + + connect( this, SIGNAL( doubleClicked( TQListViewItem * ) ), + this, SLOT( slotFolderSelected( TQListViewItem * ) ) ); + connect( this, SIGNAL( returnPressed( TQListViewItem * ) ), + this, SLOT( slotFolderSelected( TQListViewItem * ) ) ); + + setAcceptDrops( TRUE ); + viewport()->setAcceptDrops( TRUE ); + + connect( autoopen_timer, SIGNAL( timeout() ), + this, SLOT( openFolder() ) ); +} + +void DirectoryView::slotFolderSelected( TQListViewItem *i ) +{ + if ( !i || !showDirsOnly() ) + return; + + Directory *dir = (Directory*)i; + emit folderSelected( dir->fullName() ); +} + +void DirectoryView::openFolder() +{ + autoopen_timer->stop(); + if ( dropItem && !dropItem->isOpen() ) { + dropItem->setOpen( TRUE ); + dropItem->repaint(); + } +} + +static const int autoopenTime = 750; + + +void DirectoryView::contentsDragEnterEvent( TQDragEnterEvent *e ) +{ + if ( !TQUriDrag::canDecode(e) ) { + e->ignore(); + return; + } + + oldCurrent = currentItem(); + + TQListViewItem *i = itemAt( contentsToViewport(e->pos()) ); + if ( i ) { + dropItem = i; + autoopen_timer->start( autoopenTime ); + } +} + + +void DirectoryView::contentsDragMoveEvent( TQDragMoveEvent *e ) +{ + if ( !TQUriDrag::canDecode(e) ) { + e->ignore(); + return; + } + + TQPoint vp = contentsToViewport( ( (TQDragMoveEvent*)e )->pos() ); + TQListViewItem *i = itemAt( vp ); + if ( i ) { + setSelected( i, TRUE ); + e->accept(); + if ( i != dropItem ) { + autoopen_timer->stop(); + dropItem = i; + autoopen_timer->start( autoopenTime ); + } + switch ( e->action() ) { + case TQDropEvent::Copy: + break; + case TQDropEvent::Move: + e->acceptAction(); + break; + case TQDropEvent::Link: + e->acceptAction(); + break; + default: + ; + } + } else { + e->ignore(); + autoopen_timer->stop(); + dropItem = 0; + } +} + +void DirectoryView::contentsDragLeaveEvent( TQDragLeaveEvent * ) +{ + autoopen_timer->stop(); + dropItem = 0; + + setCurrentItem( oldCurrent ); + setSelected( oldCurrent, TRUE ); +} + +void DirectoryView::contentsDropEvent( TQDropEvent *e ) +{ + autoopen_timer->stop(); + + if ( !TQUriDrag::canDecode(e) ) { + e->ignore(); + return; + } + + TQListViewItem *item = itemAt( contentsToViewport(e->pos()) ); + if ( item ) { + + TQStrList lst; + + TQUriDrag::decode( e, lst ); + + TQString str; + + switch ( e->action() ) { + case TQDropEvent::Copy: + str = "Copy"; + break; + case TQDropEvent::Move: + str = "Move"; + e->acceptAction(); + break; + case TQDropEvent::Link: + str = "Link"; + e->acceptAction(); + break; + default: + str = "Unknown"; + } + + str += "\n\n"; + + e->accept(); + + for ( uint i = 0; i < lst.count(); ++i ) { + TQString filename = TQDir::convertSeparators(TQUriDrag::uriToLocalFile(lst.at(i))); + str += filename + "\n"; + } + str += TQString( "\nTo\n\n %1" ) + .arg( TQDir::convertSeparators(fullPath(item)) ); + + TQMessageBox::information( this, "Drop target", str, "Not implemented" ); + } else + e->ignore(); + +} + + +TQString DirectoryView::fullPath(TQListViewItem* item) +{ + TQString fullpath = item->text(0); + while ( (item=item->parent()) ) { + if ( item->parent() ) + fullpath = item->text(0) + "/" + fullpath; + else + fullpath = item->text(0) + fullpath; + } +#ifdef Q_WS_WIN + if (fullpath.length() > 2 && fullpath[1] != ':') { + TQDir dir(fullpath); + fullpath = dir.currentDirPath().left(2) + fullpath; + } +#endif + + return fullpath; +} + +void DirectoryView::contentsMousePressEvent( TQMouseEvent* e ) +{ + TQListView::contentsMousePressEvent(e); + TQPoint p( contentsToViewport( e->pos() ) ); + TQListViewItem *i = itemAt( p ); + if ( i ) { + // if the user clicked into the root decoration of the item, don't try to start a drag! + if ( p.x() > header()->cellPos( header()->mapToActual( 0 ) ) + + treeStepSize() * ( i->depth() + ( rootIsDecorated() ? 1 : 0) ) + itemMargin() || + p.x() < header()->cellPos( header()->mapToActual( 0 ) ) ) { + presspos = e->pos(); + mousePressed = TRUE; + } + } +} + +void DirectoryView::contentsMouseMoveEvent( TQMouseEvent* e ) +{ + if ( mousePressed && ( presspos - e->pos() ).manhattanLength() > TQApplication::startDragDistance() ) { + mousePressed = FALSE; + TQListViewItem *item = itemAt( contentsToViewport(presspos) ); + if ( item ) { + TQString source = fullPath(item); + if ( TQFile::exists(source) ) { + TQUriDrag* ud = new TQUriDrag(viewport()); + ud->setFileNames( source ); + if ( ud->drag() ) + TQMessageBox::information( this, "Drag source", + TQString("Delete ") + TQDir::convertSeparators(source), "Not implemented" ); + } + } + } +} + +void DirectoryView::contentsMouseReleaseEvent( TQMouseEvent * ) +{ + mousePressed = FALSE; +} + +void DirectoryView::setDir( const TQString &s ) +{ + TQListViewItemIterator it( this ); + ++it; + for ( ; it.current(); ++it ) { + it.current()->setOpen( FALSE ); + } + + TQStringList lst( TQStringList::split( "/", s ) ); + TQListViewItem *item = firstChild(); + TQStringList::Iterator it2 = lst.begin(); + for ( ; it2 != lst.end(); ++it2 ) { + while ( item ) { + if ( item->text( 0 ) == *it2 ) { + item->setOpen( TRUE ); + break; + } + item = item->itemBelow(); + } + } + + if ( item ) + setCurrentItem( item ); +} + +void FileItem::setPixmap( TQPixmap *p ) +{ + pix = p; + setup(); + widthChanged( 0 ); + invalidateHeight(); + repaint(); +} + + +const TQPixmap *FileItem::pixmap( int i ) const +{ + if ( i ) + return 0; + return pix; +} diff --git a/examples/dirview/dirview.doc b/examples/dirview/dirview.doc new file mode 100644 index 000000000..82a599996 --- /dev/null +++ b/examples/dirview/dirview.doc @@ -0,0 +1,35 @@ + +/* +*/ +/*! \page dirview-example.html + + \ingroup examples + \title A Directory Browser + + This example program demonstrates how to use a listview and + listview items to build a multi-column hierarchical, memory- and + CPU-efficient directory browser. It also demonstrates how to use + Drag&Drop in a listview. + + <hr> + + Header file: + + \include dirview/dirview.h + + <hr> + + And here is the main implementation file. Note the way the program + scans subdirectories only when it has to. This allows the program + to handle very large file systems efficiently. The same technique + can be used in any other trees. + + \include dirview/dirview.cpp + + <hr> + + Main: + + \include dirview/main.cpp +*/ + diff --git a/examples/dirview/dirview.h b/examples/dirview/dirview.h new file mode 100644 index 000000000..b4e49b5a2 --- /dev/null +++ b/examples/dirview/dirview.h @@ -0,0 +1,110 @@ +/**************************************************************************** +** +** Copyright (C) 1992-2008 Trolltech ASA. All rights reserved. +** +** This file is part of an example program for TQt. This example +** program may be used, distributed and modified without limitation. +** +*****************************************************************************/ + +#ifndef DIRVIEW_H +#define DIRVIEW_H + +#include <qlistview.h> +#include <qstring.h> +#include <qfile.h> +#include <qfileinfo.h> +#include <qtimer.h> + +class TQWidget; +class TQDragEnterEvent; +class TQDragMoveEvent; +class TQDragLeaveEvent; +class TQDropEvent; + +class FileItem : public TQListViewItem +{ +public: + FileItem( TQListViewItem *parent, const TQString &s1, const TQString &s2 ) + : TQListViewItem( parent, s1, s2 ), pix( 0 ) {} + + const TQPixmap *pixmap( int i ) const; +#if !defined(Q_NO_USING_KEYWORD) + using TQListViewItem::setPixmap; +#endif + void setPixmap( TQPixmap *p ); + +private: + TQPixmap *pix; + +}; + +class Directory : public TQListViewItem +{ +public: + Directory( TQListView * parent, const TQString& filename ); + Directory( Directory * parent, const TQString& filename, const TQString &col2 ) + : TQListViewItem( parent, filename, col2 ), pix( 0 ) {} + Directory( Directory * parent, const TQString& filename ); + + TQString text( int column ) const; + + TQString fullName(); + + void setOpen( bool ); + void setup(); + + const TQPixmap *pixmap( int i ) const; +#if !defined(Q_NO_USING_KEYWORD) + using TQListViewItem::setPixmap; +#endif + void setPixmap( TQPixmap *p ); + +private: + TQFile f; + Directory * p; + bool readable; + bool showDirsOnly; + TQPixmap *pix; + +}; + +class DirectoryView : public TQListView +{ + Q_OBJECT + +public: + DirectoryView( TQWidget *parent = 0, const char *name = 0, bool sdo = FALSE ); + bool showDirsOnly() { return dirsOnly; } + +public slots: + void setDir( const TQString & ); + +signals: + void folderSelected( const TQString & ); + +protected slots: + void slotFolderSelected( TQListViewItem * ); + void openFolder(); + +protected: + void contentsDragEnterEvent( TQDragEnterEvent *e ); + void contentsDragMoveEvent( TQDragMoveEvent *e ); + void contentsDragLeaveEvent( TQDragLeaveEvent *e ); + void contentsDropEvent( TQDropEvent *e ); + void contentsMouseMoveEvent( TQMouseEvent *e ); + void contentsMousePressEvent( TQMouseEvent *e ); + void contentsMouseReleaseEvent( TQMouseEvent *e ); + +private: + TQString fullPath(TQListViewItem* item); + bool dirsOnly; + TQListViewItem *oldCurrent; + TQListViewItem *dropItem; + TQTimer* autoopen_timer; + TQPoint presspos; + bool mousePressed; + +}; + +#endif diff --git a/examples/dirview/dirview.pro b/examples/dirview/dirview.pro new file mode 100644 index 000000000..fe711169b --- /dev/null +++ b/examples/dirview/dirview.pro @@ -0,0 +1,11 @@ +TEMPLATE = app +TARGET = dirview + +CONFIG += qt warn_on release +DEPENDPATH = ../../include + +REQUIRES = full-config + +HEADERS = dirview.h +SOURCES = dirview.cpp \ + main.cpp diff --git a/examples/dirview/main.cpp b/examples/dirview/main.cpp new file mode 100644 index 000000000..00f712729 --- /dev/null +++ b/examples/dirview/main.cpp @@ -0,0 +1,42 @@ +/**************************************************************************** +** +** Copyright (C) 1992-2008 Trolltech ASA. All rights reserved. +** +** This file is part of an example program for TQt. This example +** program may be used, distributed and modified without limitation. +** +*****************************************************************************/ + +#include <qapplication.h> +#include <qfileinfo.h> +#include <qdir.h> +#include "dirview.h" + +int main( int argc, char ** argv ) +{ + TQApplication a( argc, argv ); + + DirectoryView mw; + + mw.addColumn( "Name" ); + mw.addColumn( "Type" ); + mw.setTreeStepSize( 20 ); + + const TQFileInfoList* roots = TQDir::drives(); + TQPtrListIterator<TQFileInfo> i(*roots); + TQFileInfo* fi; + while ( (fi = *i) ) { + ++i; + Directory * root = new Directory( &mw, fi->filePath() ); + if ( roots->count() <= 1 ) + root->setOpen( TRUE ); // be interesting + } + + mw.resize( 400, 400 ); + mw.setCaption( "TQt Example - Directory Browser" ); + mw.setAllColumnsShowFocus( TRUE ); + a.setMainWidget( &mw ); + mw.show(); + + return a.exec(); +} |