A Directory Browser

xiaoxiao2021-03-06  44

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.

HEADER FILE:

/ ************************************************** ***********************************

** $ ID: QT / Dirview.h 3.0.5 Edited Oct 12 2001 $

**

** CopyRight (C) 1992-2000 Trolltech as. All Rights Reserved.

**

** This file is part of an example program for qt. This Example

** Program May Be Used, Distributed and Modified WITHOUT LIMITATION.

**

*********************************************************** *********************************** /

#ifndef dirview_h

#define Dirview_h

#include

#include

#include

#include

#include

Class Qwidget;

Class QDRAGENTEREVENT;

Class QDRAGMOVEEVENT;

Class QDRAGLEEVENT;

Class QDROPEVENT;

Class FileItem: Public QlistViewItem

{

PUBLIC:

FileItem (QlistViewItem * Parent, Const QString & S1, Const QString & S2)

: QListViewItem (PARENT, S1, S2), PIX (0) {}

Const QPixmap * Pixmap (INT I) Const;

Void setpixmap (qpixmap * p);

Private:

QPixmap * PIX;

}

Class Directory: Public QlistViewItem

{

PUBLIC:

Directory (QlistView * Parent, Const Qstring & FileName);

Directory (Directory * Parent, Const Qstring & FileName, Const Qstring & Col2)

: QlistViewItem (PARENT, FILENAME, COL2), PIX (0) {}

Directory (Directory * Parent, Const Qstring & FileName);

QString text (int column) const;

Qstring fullname ();

Void setopen (bool);

Void setup ();

Const QPixmap * Pixmap (INT I) Const;

Void setpixmap (qpixmap * p);

Private:

Qfile F;

Directory * P; Bool Readable;

BOOL Showdirsonly;

QPixmap * PIX;

}

Class DirectoryView: Public QlistView

{

Q_Object

PUBLIC:

DirectoryView (QWIDGET * PARENT = 0, Const Char * Name = 0, Bool SDO = FALSE);

Bool showdirsonly () {return dirsonly;

Public slots:

Void setDir (const Qstring &);

SIGNALS:

Void Folderselected (Const Qstring &);

protected slots:

Void SlotFolderselected (QListViewItem *);

Void OpenFolder ();

protected:

Void ContentsDragenterevent (QDragenterevent * E);

Void ContentsDragmoveEvent (QDragmoveEvent * e);

Void ContentsDragleaveEvent (QDRAGLEAVEEVENT * E);

Void ContentsDropEvent (QDropevent * E);

Void ContentsMouseMoveEvent (QMouseEvent * e);

Void ContentsMousePressevent (QMouseEvent * e);

Void ContentsMouseReleaseEvent (QMouseEvent * e);

Private:

QString Fullpath (QListViewItem * Item);

Bool dirsonly;

QListViewItem * oldcurrent;

QlistViewItem * DropItem;

Qtimer * autoopen_timer;

Qpoint Presspos;

Bool mousepressed;

}

#ENDIF

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.

/ ************************************************** ***********************************

** $ ID: Qt / Dirview.cpp 3.0.5 Edited Oct 12 2001 $

**

** CopyRight (C) 1992-2000 Trolltech as. All Rights Reserved.

**

** This file is part of an example program for qt. This Example

** Program May Be Used, Distributed and Modified WITHOUT LIMITATION.

**

*********************************************************** *********************************** /

#include "dirview.h"

#include

#include

#include #include

#include

#include

#include

#include

#include

#include

#include

#include

#include

Static const char * folder_closed_xpm [] = {

"16 16 9 1",

"G C # 808080",

"B C # c0c000",

"e c # c0c0c0",

"# C # 000000",

"C C # fff00",

". c none",

"a c # 585858",

"f C # a0a0a4",

"D C #ffffff",

".. ### ...........",

"# ABC ## .........

". # daabc ##### ....",

". # Ddeaabbccc # ...",

"# Dedeeabbba ...",

"# Edeeeeaaaaab # ..",

". # deeeeeeeefe # ba.",

". # eeeeeeefef # ba.",

". # eeeeeefeff # ba.",

". # eeeeefefff # ba.",

"## Geefeffff # ba.",

"... ## geffffff # 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 # ffdca8",

"h c #dcdcdc",

"i c #ffffff",

". c none",

".... ### ........."

".... # Ab ## .......",

".... # acab #### ...",

"###. # Acccccca # ..",

"# DDEFAAACCCCCA #.",

"# BDDDBAAAACCCAB #",

".eddddbbaaaaacab #",

". # BDDGDBBAAAAB #",

"..EDGDGGGBBAAB #",

".. # bgggghghdaab #",

"... ebhggghicfab #",

".... # edhiiidab #",

"... # 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 # ffdca8",

". c none",

"a c # 585858",

"g c # a0a0a4",

"D C #ffffff",

".. # a # ...........",

"# ABC #### .......",

"# daa # eee # ...",

". # DDF # e ## b # .....",

". # DFD # e # bcb ## ...",

". # fdccc # daaab # ..",

"# dfbbcccfg # 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 # fffc0",

". c none",

"................",

"......... # ...",

"... #. # a ## ....",

"..... # b # bbba ## ..",

".... # b # bbbabbb #.",

"... # b # bba ## bb # ..",

".. # b # abb # bb ## ...",

". # a # AAB # bbbab ##.",

"# a # aaa # bcbbbbbb #",

"# ccdc # bcbbbbbbbbb #.",

". ## c # bcbbbbbb # ..",

"... # acbbbbe ...",

".. # aaaaacaba # ....",

"... ## aaaaa # .....",

"..... ## aa # ...",

"....... ## ......."};

QPixmap * folderlocked = 0;

QPixmap * folderclosed = 0;

QPixmap * folderopen = 0;

QPixmap * filenormal = 0;

/ ************************************************** ****************************

* Class Directory

*

*********************************************************** *********************************** /

Directory :: Directory (Directory * Parent, Const Qstring & FileName)

: QlistViewItem (PARENT), F (FileName),

Showdirsonly (Parent-> showdirsonly),

PIX (0)

{

P = pent;

Readable = qdir (Fullname ()) .Isreadable ();

IF (! readable)

SetPixmap (FolderLocked);

Else

setPixmap (FolderClosed);

}

Directory :: Directory (QListView * Parent, Const Qstring & FileName)

: QlistViewItem (PARENT), F (FileName),

Showdirsonly ((DirectoryView *) Parent) -> showdirsonly ()),

PIX (0)

{

P = 0;

Readable = qdir (Fullname ()) .Isreadable ();

}

Void Directory :: setPixmap (QPixMap * PX)

{

PIX = PX;

setup ();

Widthchanged (0);

INVALIDATEHEIGHT ();

Repaint ();

}

Const QPixmap * 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 ()) {

Qstring s; "Fullname ());

QDir thisdir (s);

IF (! thisdir.isreadable ()) {

Readable = FALSE;

SetExpandable (FALSE);

Return;

}

Listview () -> setUpdatesenabled (false);

Const QfileInfolist * files = thisdir.EnTryInfolist ();

IF (files) {

QfileInfolistiterator it (* files);

QfileInfo * 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);

}

QlistViewItem :: setopen (o);

}

Void Directory :: setup ()

{

setExpandable;

QlistViewItem :: setup ();

}

Qstring Directory :: fullname ()

{

QString S;

IF (p) {

s = p-> fullname ();

S.Append (f.name ());

S.Append ("/");

} else {

s = f.name ();

}

Return S;

}

QString Directory :: Text (int column) const

{

IF (color == 0)

Return f.name ();

Else if (readable)

Return "Directory";

Else

Return "Unreadable Directory";

}

/ ************************************************** *****************************

*

* Class DirectoryView

*

*********************************************************** *********************************** /

DirectoryView :: DirectoryView (QWIDGET * PARENT, Const Char * Name, Bool SDO)

: QlistView (PARENT, NAME), DIRSONLY (SDO), Oldcurrent (0),

DropItem (0), MousePressed (False)

{

Autoopen_timer = new qtimer (this);

IF (! folderlocked) {

FolderLocked = new qpixmap; Folder_locked

FolderClosed = new qpixmap (folder_closed_xpm);

Folderopen = new qpixmap (Folder_Open_XPM);

Filenormal = new qpixmap (PIX_FILE);

}

Connect (this, Signal (DoubleClicked (QlistViewItem *),

This, Slot (slotFolderselected (QListViewItem *))));

Connect (this, Signal (qlistviewtem *),

This, Slot (slotFolderselected (QListViewItem *))));

Setacceptdrops (TRUE);

ViewPort () -> setAcceptdrops (true); connect (autoopen_timer, ster (timeout ()),

THIS, SLOT (OpenFolder ()));

}

Void DirectoryView :: SlotFoldersLected (QlistViewItem * 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 Iopentime = 750;

Void DirectoryView :: ContentsDragenterevent (QDRAGENTEREVENT * E)

{

IF (! quiridrag :: CANDECode (e)) {

E-> ignore ();

Return;

}

Oldcurrent = currentItem ();

QlistViewItem * i = itemat (ContentStoviewPort (E-> POS ());

IF (i) {

DropItem = i;

AutoOpen_timer-> start (autoopentime);

}

}

Void DirectoryView :: ContentsDragmoveEvent (QDRAGMOVEEVENT * E)

{

IF (! quiridrag :: CANDECode (e)) {

E-> ignore ();

Return;

}

QPoint VP = ContentStoviewPort ((QDragmoveEvent *) E) -> POS ());

QlistViewItem * 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 QDropevent :: Copy:

Break;

Case QDropevent :: Move:

E-> acceptaction ();

Break;

Case QDropevent :: LINK:

E-> acceptaction ();

Break;

DEFAULT:

;

}

} else {

E-> ignore ();

AutoOpen_timer-> stop ();

DropItem = 0;

}

}

Void DirectoryView :: ContentsDragleaveEvent (QDRAGLEAVEEVENT *)

{

AutoOpen_timer-> stop ();

DropItem = 0;

SetCurrentItem (OldCurrent);

SetSelected (OldCurrent, true);

}

Void DirectoryView :: ContentsDropevent (QDropevent * e) {

AutoOpen_timer-> stop ();

IF (! quiridrag :: CANDECode (e)) {

E-> ignore ();

Return;

}

QlistViewItem * Item = item (ContentStoviewPort (E-> POS ()));

IF (item) {

QStrList LST;

Quridrag :: Decode (e, LST);

QString Str;

Switch (E-> Action ()) {

Case QDropevent :: Copy:

Str = "copy";

Break;

Case QDropevent :: Move:

Str = "move";

E-> acceptaction ();

Break;

Case QDropevent :: LINK:

Str = "link";

E-> acceptaction ();

Break;

DEFAULT:

Str = "unknown";

}

Str = "/ n / n";

E-> accept ();

For (uint i = 0; i

Qstring filename = lst.at (i);

Str = filename "/ n";

}

STR = QString ("/ NTO / N / N% 1")

.arg (Item);

QMessageBox :: Information (this, "Drop Target", STR, "Not Implement");

Else

E-> ignore ();

}

QString DirectoryView :: Fullpath (QlistViewItem * Item)

{

Qstring fullpath = item-> text (0);

While (item = item-> parent ())) {

IF (item-> parent ())

Fullpath = item-> text (0) "/" fullpath;

Else

Fullpath = item-> text (0) Fullpath;

}

Return Fullpath;

}

Void DirectoryView :: ContentsMousePressevent (QMouseEvent * e)

{

QlistView :: ContentsMousePressEvent (e);

QPoint P (ContentStoviewPort)));

QlistViewItem * i = itemat (p);

IF (i) {

// if the user copy ion, don't try to start a drag!

IF (p.x ()> header () -> Cellpos (header () -> maptoactual (0))

Treestepsize () * (i-> depth () ()? 1: 0) itemmargin () ||

P.X ()

cellpos (header () -> maptoactual (0)))) {

PRESSPOS = E-> POS ();

mousepressed = true;

}

}

}

Void DirectoryView :: ContentsMouseMoveEvent (QMouseEvent * e)

{

IF (Mousepissed && (PressPOS - E-> POS ()) .manhattanlength ()> QApplication :: StartDragdistance ()) {

MousePressed = false;

QlistViewItem * Item = item (ContentStoviewPort (PressPOS));

IF (item) {

Qstring Source = FullPath (item);

IF (QFile :: EXISTS (SOURCE)) {

Quridrag * ud = new quridrag (viewport ());

UD-> setUnicodeuris (source);

IF (UD-> DRAG ())

QMessagebox :: Information (this, "Drag Source",

QString ("delete") Source, "Not IMplement");

}

}

}

}

Void DirectoryView :: ContentsMouseReleaseEvent (QMouseEvent *)

{

MousePressed = false;

}

Void DirectoryView :: SetDir (const qstring & s)

{

QlistViewItemIitrator IT (this);

IT;

For (; it.current (); IT) {

IT.CURRENT () -> setopen (false);

}

QStringList LST (QStringList :: split ("/", s));

QlistViewItem * item = firstchild ();

Qstringlist :: item2 = 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 (qpixmap * p)

{

PIX = P;

setup ();

Widthchanged (0);

INVALIDATEHEIGHT ();

Repaint ();

}

Const QPixmap * FileItem :: Pixmap (INT I) Const

{

IF (i)

Return 0;

Return PIX;

}

MAIN:

/ ************************************************** ***********************************

** $ ID: Qt / main.cpp 3.0.5 Edited Oct 12 2001 $

**

** CopyRight (C) 1992-2000 Trolltech as. All Rights Reserved. **

** This file is part of an example program for qt. This Example

** Program May Be Used, Distributed and Modified WITHOUT LIMITATION.

**

*********************************************************** *********************************** /

#include

#include

#include

#include "dirview.h"

INT main (int Argc, char ** argv)

{

QAPPlication A (Argc, Argv);

DirectoryView MW;

MW.ADDColumn ("name");

MW.AddColumn ("Type");

Mw.settreeestepsize (20);

Const QfileInfolist * roots = qdir :: drives ();

QPTRListiterator i (* roots);

QfileInfo * fi;

While ((fi = * i)) {

i;

Directory * root = new Directory (& MW, FI-> filepath ());

IF (Roots-> count () <= 1)

root-> setopen (true); // be intencents

}

MW.Resize (400, 400);

MW.SETCAPTION ("Qt Example - Directory Browser";

MW.setAllColumnSshowFocus (TRUE);

A.SETMAINWIDGET (& MW);

MW.SHOW ();

Return a.exec ();

}

转载请注明原文地址:https://www.9cbs.com/read-112424.html

New Post(0)