home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / qt3_emx.zip / examples / dirview / dirview.cpp < prev    next >
C/C++ Source or Header  |  2001-10-11  |  12KB  |  527 lines

  1. /****************************************************************************
  2. ** $Id:  qt/dirview.cpp   3.0.0   edited Jun 22 13:24 $
  3. **
  4. ** Copyright (C) 1992-2000 Trolltech AS.  All rights reserved.
  5. **
  6. ** This file is part of an example program for Qt.  This example
  7. ** program may be used, distributed and modified without limitation.
  8. **
  9. *****************************************************************************/
  10.  
  11. #include "dirview.h"
  12.  
  13. #include <qdir.h>
  14. #include <qfile.h>
  15. #include <qfileinfo.h>
  16. #include <qpixmap.h>
  17. #include <qevent.h>
  18. #include <qpoint.h>
  19. #include <qmessagebox.h>
  20. #include <qdragobject.h>
  21. #include <qmime.h>
  22. #include <qstrlist.h>
  23. #include <qstringlist.h>
  24. #include <qapplication.h>
  25. #include <qheader.h>
  26.  
  27. static const char* folder_closed_xpm[]={
  28.     "16 16 9 1",
  29.     "g c #808080",
  30.     "b c #c0c000",
  31.     "e c #c0c0c0",
  32.     "# c #000000",
  33.     "c c #ffff00",
  34.     ". c None",
  35.     "a c #585858",
  36.     "f c #a0a0a4",
  37.     "d c #ffffff",
  38.     "..###...........",
  39.     ".#abc##.........",
  40.     ".#daabc#####....",
  41.     ".#ddeaabbccc#...",
  42.     ".#dedeeabbbba...",
  43.     ".#edeeeeaaaab#..",
  44.     ".#deeeeeeefe#ba.",
  45.     ".#eeeeeeefef#ba.",
  46.     ".#eeeeeefeff#ba.",
  47.     ".#eeeeefefff#ba.",
  48.     ".##geefeffff#ba.",
  49.     "...##gefffff#ba.",
  50.     ".....##fffff#ba.",
  51.     ".......##fff#b##",
  52.     ".........##f#b##",
  53.     "...........####."};
  54.  
  55. static const char* folder_open_xpm[]={
  56.     "16 16 11 1",
  57.     "# c #000000",
  58.     "g c #c0c0c0",
  59.     "e c #303030",
  60.     "a c #ffa858",
  61.     "b c #808080",
  62.     "d c #a0a0a4",
  63.     "f c #585858",
  64.     "c c #ffdca8",
  65.     "h c #dcdcdc",
  66.     "i c #ffffff",
  67.     ". c None",
  68.     "....###.........",
  69.     "....#ab##.......",
  70.     "....#acab####...",
  71.     "###.#acccccca#..",
  72.     "#ddefaaaccccca#.",
  73.     "#bdddbaaaacccab#",
  74.     ".eddddbbaaaacab#",
  75.     ".#bddggdbbaaaab#",
  76.     "..edgdggggbbaab#",
  77.     "..#bgggghghdaab#",
  78.     "...ebhggghicfab#",
  79.     "....#edhhiiidab#",
  80.     "......#egiiicfb#",
  81.     "........#egiibb#",
  82.     "..........#egib#",
  83.     "............#ee#"};
  84.  
  85. static const char * folder_locked[]={
  86.     "16 16 10 1",
  87.     "h c #808080",
  88.     "b c #ffa858",
  89.     "f c #c0c0c0",
  90.     "e c #c05800",
  91.     "# c #000000",
  92.     "c c #ffdca8",
  93.     ". c None",
  94.     "a c #585858",
  95.     "g c #a0a0a4",
  96.     "d c #ffffff",
  97.     "..#a#...........",
  98.     ".#abc####.......",
  99.     ".#daa#eee#......",
  100.     ".#ddf#e##b#.....",
  101.     ".#dfd#e#bcb##...",
  102.     ".#fdccc#daaab#..",
  103.     ".#dfbbbccgfg#ba.",
  104.     ".#ffb#ebbfgg#ba.",
  105.     ".#ffbbe#bggg#ba.",
  106.     ".#fffbbebggg#ba.",
  107.     ".##hf#ebbggg#ba.",
  108.     "...###e#gggg#ba.",
  109.     ".....#e#gggg#ba.",
  110.     "......###ggg#b##",
  111.     ".........##g#b##",
  112.     "...........####."};
  113.  
  114. static const char * pix_file []={
  115.     "16 16 7 1",
  116.     "# c #000000",
  117.     "b c #ffffff",
  118.     "e c #000000",
  119.     "d c #404000",
  120.     "c c #c0c000",
  121.     "a c #ffffc0",
  122.     ". c None",
  123.     "................",
  124.     ".........#......",
  125.     "......#.#a##....",
  126.     ".....#b#bbba##..",
  127.     "....#b#bbbabbb#.",
  128.     "...#b#bba##bb#..",
  129.     "..#b#abb#bb##...",
  130.     ".#a#aab#bbbab##.",
  131.     "#a#aaa#bcbbbbbb#",
  132.     "#ccdc#bcbbcbbb#.",
  133.     ".##c#bcbbcabb#..",
  134.     "...#acbacbbbe...",
  135.     "..#aaaacaba#....",
  136.     "...##aaaaa#.....",
  137.     ".....##aa#......",
  138.     ".......##......."};
  139.  
  140. QPixmap *folderLocked = 0;
  141. QPixmap *folderClosed = 0;
  142. QPixmap *folderOpen = 0;
  143. QPixmap *fileNormal = 0;
  144.  
  145. /*****************************************************************************
  146.  *
  147.  * Class Directory
  148.  *
  149.  *****************************************************************************/
  150.  
  151. Directory::Directory( Directory * parent, const QString& filename )
  152.     : QListViewItem( parent ), f(filename),
  153.       showDirsOnly( parent->showDirsOnly ),
  154.       pix( 0 )
  155. {
  156.     p = parent;
  157.     readable = QDir( fullName() ).isReadable();
  158.  
  159.     if ( !readable )
  160.     setPixmap( folderLocked );
  161.     else
  162.     setPixmap( folderClosed );
  163. }
  164.  
  165.  
  166. Directory::Directory( QListView * parent, const QString& filename )
  167.     : QListViewItem( parent ), f(filename),
  168.       showDirsOnly( ( (DirectoryView*)parent )->showDirsOnly() ),
  169.       pix( 0 )
  170. {
  171.     p = 0;
  172.     readable = QDir( fullName() ).isReadable();
  173. }
  174.  
  175.  
  176. void Directory::setPixmap( QPixmap *px )
  177. {
  178.     pix = px;
  179.     setup();
  180.     widthChanged( 0 );
  181.     invalidateHeight();
  182.     repaint();
  183. }
  184.  
  185.  
  186. const QPixmap *Directory::pixmap( int i ) const
  187. {
  188.     if ( i )
  189.     return 0;
  190.     return pix;
  191. }
  192.  
  193. void Directory::setOpen( bool o )
  194. {
  195.     if ( o )
  196.     setPixmap( folderOpen );
  197.     else
  198.     setPixmap( folderClosed );
  199.  
  200.     if ( o && !childCount() ) {
  201.     QString s( fullName() );
  202.     QDir thisDir( s );
  203.     if ( !thisDir.isReadable() ) {
  204.         readable = FALSE;
  205.         setExpandable( FALSE );
  206.         return;
  207.     }
  208.  
  209.     listView()->setUpdatesEnabled( FALSE );
  210.     const QFileInfoList * files = thisDir.entryInfoList();
  211.     if ( files ) {
  212.         QFileInfoListIterator it( *files );
  213.         QFileInfo * fi;
  214.         while( (fi=it.current()) != 0 ) {
  215.         ++it;
  216.         if ( fi->fileName() == "." || fi->fileName() == ".." )
  217.             ; // nothing
  218.         else if ( fi->isSymLink() && !showDirsOnly ) {
  219.             FileItem *item = new FileItem( this, fi->fileName(),
  220.                              "Symbolic Link" );
  221.             item->setPixmap( fileNormal );
  222.         }
  223.         else if ( fi->isDir() )
  224.             (void)new Directory( this, fi->fileName() );
  225.         else if ( !showDirsOnly ) {
  226.             FileItem *item
  227.             = new FileItem( this, fi->fileName(),
  228.                          fi->isFile()?"File":"Special" );
  229.             item->setPixmap( fileNormal );
  230.         }
  231.         }
  232.     }
  233.     listView()->setUpdatesEnabled( TRUE );
  234.     }
  235.     QListViewItem::setOpen( o );
  236. }
  237.  
  238.  
  239. void Directory::setup()
  240. {
  241.     setExpandable( TRUE );
  242.     QListViewItem::setup();
  243. }
  244.  
  245.  
  246. QString Directory::fullName()
  247. {
  248.     QString s;
  249.     if ( p ) {
  250.     s = p->fullName();
  251.     s.append( f.name() );
  252.     s.append( "/" );
  253.     } else {
  254.     s = f.name();
  255.     }
  256.     return s;
  257. }
  258.  
  259.  
  260. QString Directory::text( int column ) const
  261. {
  262.     if ( column == 0 )
  263.     return f.name();
  264.     else if ( readable )
  265.     return "Directory";
  266.     else
  267.     return "Unreadable Directory";
  268. }
  269.  
  270. /*****************************************************************************
  271.  *
  272.  * Class DirectoryView
  273.  *
  274.  *****************************************************************************/
  275.  
  276. DirectoryView::DirectoryView( QWidget *parent, const char *name, bool sdo )
  277.     : QListView( parent, name ), dirsOnly( sdo ), oldCurrent( 0 ),
  278.       dropItem( 0 ), mousePressed( FALSE )
  279. {
  280.     autoopen_timer = new QTimer( this );
  281.     if ( !folderLocked ) {
  282.     folderLocked = new QPixmap( folder_locked );
  283.     folderClosed = new QPixmap( folder_closed_xpm );
  284.     folderOpen = new QPixmap( folder_open_xpm );
  285.     fileNormal = new QPixmap( pix_file );
  286.     }
  287.  
  288.     connect( this, SIGNAL( doubleClicked( QListViewItem * ) ),
  289.          this, SLOT( slotFolderSelected( QListViewItem * ) ) );
  290.     connect( this, SIGNAL( returnPressed( QListViewItem * ) ),
  291.          this, SLOT( slotFolderSelected( QListViewItem * ) ) );
  292.  
  293.     setAcceptDrops( TRUE );
  294.     viewport()->setAcceptDrops( TRUE );
  295.  
  296.     connect( autoopen_timer, SIGNAL( timeout() ),
  297.          this, SLOT( openFolder() ) );
  298. }
  299.  
  300. void DirectoryView::slotFolderSelected( QListViewItem *i )
  301. {
  302.     if ( !i || !showDirsOnly() )
  303.     return;
  304.  
  305.     Directory *dir = (Directory*)i;
  306.     emit folderSelected( dir->fullName() );
  307. }
  308.  
  309. void DirectoryView::openFolder()
  310. {
  311.     autoopen_timer->stop();
  312.     if ( dropItem && !dropItem->isOpen() ) {
  313.     dropItem->setOpen( TRUE );
  314.     dropItem->repaint();
  315.     }
  316. }
  317.  
  318. static const int autoopenTime = 750;
  319.  
  320.  
  321. void DirectoryView::contentsDragEnterEvent( QDragEnterEvent *e )
  322. {
  323.     if ( !QUriDrag::canDecode(e) ) {
  324.     e->ignore();
  325.     return;
  326.     }
  327.  
  328.     oldCurrent = currentItem();
  329.  
  330.     QListViewItem *i = itemAt( contentsToViewport(e->pos()) );
  331.     if ( i ) {
  332.     dropItem = i;
  333.     autoopen_timer->start( autoopenTime );
  334.     }
  335. }
  336.  
  337.  
  338. void DirectoryView::contentsDragMoveEvent( QDragMoveEvent *e )
  339. {
  340.     if ( !QUriDrag::canDecode(e) ) {
  341.     e->ignore();
  342.     return;
  343.     }
  344.  
  345.     QPoint vp = contentsToViewport( ( (QDragMoveEvent*)e )->pos() );
  346.     QListViewItem *i = itemAt( vp );
  347.     if ( i ) {
  348.     setSelected( i, TRUE );
  349.     e->accept();
  350.     if ( i != dropItem ) {
  351.         autoopen_timer->stop();
  352.         dropItem = i;
  353.         autoopen_timer->start( autoopenTime );
  354.     }
  355.     switch ( e->action() ) {
  356.     case QDropEvent::Copy:
  357.         break;
  358.     case QDropEvent::Move:
  359.         e->acceptAction();
  360.         break;
  361.     case QDropEvent::Link:
  362.         e->acceptAction();
  363.         break;
  364.     default:
  365.         ;
  366.     }
  367.     } else {
  368.     e->ignore();
  369.     autoopen_timer->stop();
  370.     dropItem = 0;
  371.     }
  372. }
  373.  
  374. void DirectoryView::contentsDragLeaveEvent( QDragLeaveEvent * )
  375. {
  376.     autoopen_timer->stop();
  377.     dropItem = 0;
  378.  
  379.     setCurrentItem( oldCurrent );
  380.     setSelected( oldCurrent, TRUE );
  381. }
  382.  
  383. void DirectoryView::contentsDropEvent( QDropEvent *e )
  384. {
  385.     autoopen_timer->stop();
  386.  
  387.     if ( !QUriDrag::canDecode(e) ) {
  388.     e->ignore();
  389.     return;
  390.     }
  391.  
  392.     QListViewItem *item = itemAt( contentsToViewport(e->pos()) );
  393.     if ( item ) {
  394.  
  395.     QStrList lst;
  396.  
  397.     QUriDrag::decode( e, lst );
  398.  
  399.     QString str;
  400.  
  401.     switch ( e->action() ) {
  402.         case QDropEvent::Copy:
  403.         str = "Copy";
  404.         break;
  405.         case QDropEvent::Move:
  406.         str = "Move";
  407.         e->acceptAction();
  408.         break;
  409.         case QDropEvent::Link:
  410.         str = "Link";
  411.         e->acceptAction();
  412.         break;
  413.         default:
  414.         str = "Unknown";
  415.     }
  416.  
  417.     str += "\n\n";
  418.  
  419.     e->accept();
  420.  
  421.     for ( uint i = 0; i < lst.count(); ++i ) {
  422.         QString filename = lst.at( i );
  423.         str += filename + "\n";
  424.     }
  425.     str += QString( "\nTo\n\n   %1" )
  426.            .arg( fullPath(item) );
  427.  
  428.     QMessageBox::information( this, "Drop target", str, "Not implemented" );
  429.     } else
  430.     e->ignore();
  431.  
  432. }
  433.  
  434.  
  435. QString DirectoryView::fullPath(QListViewItem* item)
  436. {
  437.     QString fullpath = item->text(0);
  438.     while ( (item=item->parent()) ) {
  439.     if ( item->parent() )
  440.         fullpath = item->text(0) + "/" + fullpath;
  441.     else
  442.         fullpath = item->text(0) + fullpath;
  443.     }
  444.     return fullpath;
  445. }
  446.  
  447. void DirectoryView::contentsMousePressEvent( QMouseEvent* e )
  448. {
  449.     QListView::contentsMousePressEvent(e);
  450.     QPoint p( contentsToViewport( e->pos() ) );
  451.     QListViewItem *i = itemAt( p );
  452.     if ( i ) {
  453.     // if the user clicked into the root decoration of the item, don't try to start a drag!
  454.     if ( p.x() > header()->cellPos( header()->mapToActual( 0 ) ) +
  455.          treeStepSize() * ( i->depth() + ( rootIsDecorated() ? 1 : 0) ) + itemMargin() ||
  456.          p.x() < header()->cellPos( header()->mapToActual( 0 ) ) ) {
  457.         presspos = e->pos();
  458.         mousePressed = TRUE;
  459.     }
  460.     }
  461. }
  462.  
  463. void DirectoryView::contentsMouseMoveEvent( QMouseEvent* e )
  464. {
  465.     if ( mousePressed && ( presspos - e->pos() ).manhattanLength() > QApplication::startDragDistance() ) {
  466.     mousePressed = FALSE;
  467.     QListViewItem *item = itemAt( contentsToViewport(presspos) );
  468.     if ( item ) {
  469.         QString source = fullPath(item);
  470.         if ( QFile::exists(source) ) {
  471.         QUriDrag* ud = new QUriDrag(viewport());
  472.         ud->setUnicodeUris( source );
  473.         if ( ud->drag() )
  474.             QMessageBox::information( this, "Drag source",
  475.                           QString("Delete ")+source, "Not implemented" );
  476.         }
  477.     }
  478.     }
  479. }
  480.  
  481. void DirectoryView::contentsMouseReleaseEvent( QMouseEvent * )
  482. {
  483.     mousePressed = FALSE;
  484. }
  485.  
  486. void DirectoryView::setDir( const QString &s )
  487. {
  488.     QListViewItemIterator it( this );
  489.     ++it;
  490.     for ( ; it.current(); ++it ) {
  491.     it.current()->setOpen( FALSE );
  492.     }
  493.  
  494.     QStringList lst( QStringList::split( "/", s ) );
  495.     QListViewItem *item = firstChild();
  496.     QStringList::Iterator it2 = lst.begin();
  497.     for ( ; it2 != lst.end(); ++it2 ) {
  498.     while ( item ) {
  499.         if ( item->text( 0 ) == *it2 ) {
  500.         item->setOpen( TRUE );
  501.         break;
  502.         }
  503.         item = item->itemBelow();
  504.     }
  505.     }
  506.  
  507.     if ( item )
  508.     setCurrentItem( item );
  509. }
  510.  
  511. void FileItem::setPixmap( QPixmap *p )
  512. {
  513.     pix = p;
  514.     setup();
  515.     widthChanged( 0 );
  516.     invalidateHeight();
  517.     repaint();
  518. }
  519.  
  520.  
  521. const QPixmap *FileItem::pixmap( int i ) const
  522. {
  523.     if ( i )
  524.     return 0;
  525.     return pix;
  526. }
  527.