/************************************************************ Copyright (C), 2009, SEU Author: hxfirefox FileName: filedialog.h Date: 12/09/2009 Description: 替代Qt中的QFileDialog ***********************************************************/ #ifndef FILEDLG_H #define FILEDLG_H #include <qdir.h> #include <qdialog.h> class QListBox; class QLineEdit; class QComboBox; class QLabel; class QPushButton; class FileDialog : public QDialog { Q_OBJECT public: FileDialog(const char *dirName, const char *filter = 0, QWidget *parent=0, const char *name=0, bool modal=FALSE); FileDialog(QWidget *parent=0, const char *name=0, bool modal=FALSE); ~FileDialog(); QString selectedFile() const; const char *dirPath() const; void setDir(const char *); const QDir *dir() const; void setDir(const QDir &); void rereadDir(); static QString getOpenFileName(const char *dir = 0, const char *filter = 0, QWidget *parent = 0, const char *name = 0); static QString getAllOpenFileNames(const char *dir = 0, const char *filter = 0, QWidget *parent = 0, const char *name = 0); static QString getSaveFileName(const char *dir = 0, const char *filter = 0, QWidget *parent = 0, const char *name = 0); signals: void fileHighlighted(const char *); void fileSelected(const char *); void dirEntered(const char *); private slots: void fileSelected(int); void fileHighlighted(int); void dirSelected(int); void pathSelected(int); void okClicked(); void filterClicked(); void cancelClicked(); protected: void resizeEvent(QResizeEvent *); private: void init(); void updatePathBox(const char *); QDir d; QString fileName; QListBox *files; QListBox *dirs; QLineEdit *filterEdit; QLineEdit *nameEdit; QComboBox *pathBox; QLabel *filterL; QLabel *nameL; QLabel *dirL; QLabel *fileL; QPushButton *okB; QPushButton *filterB; QPushButton *cancelB; }; #endif // FILEDLG_H
/************************************************************ Copyright (C), 2009, SEU Author: hxfirefox FileName: filedialog.cpp Date: 12/09/2009 Description: 替代Qt中的QFileDialog ***********************************************************/ #include "filedialog.h" #include "qlistbox.h" #include "qlined.h" #include "qcombo.h" #include "qlabel.h" #include "qpushbt.h" #include "qmsgbox.h" #include "qapplication.h" #include "string.h" /************************************************* Function: FileDialog() Description: 构造函数 Calls: init() rereadDir() resize() Input: QWidget *parent const char *name bool modal Output: 无 Return: 无 *************************************************/ FileDialog::FileDialog( QWidget *parent, const char *name, bool modal ) : QDialog( parent, name, modal ) { init(); filterEdit->setText( "*" ); d.convertToAbs(); rereadDir(); resize(300, 300); } /************************************************* Function: FileDialog() Description: 可预设路径与文件名的构造函数 Calls: init() rereadDir() resize() Input: const char *dirName const char *filter QWidget *parent const char *name, bool modal const char *name bool modal Output: 无 Return: 无 *************************************************/ FileDialog::FileDialog( const char *dirName, const char *filter, QWidget *parent, const char *name, bool modal ) : QDialog( parent, name, modal ) { init(); if(filter) { d.setNameFilter(filter); } filterEdit->setText(d.nameFilter()); if(dirName) { d.setPath(dirName); } d.convertToAbs(); rereadDir(); resize( 300, 300 ); } /************************************************* Function: init() Description: 初始化文件对话框 Calls: connect() resize() setAutoResize() setMatchAllDirs() Input: 无 Output: 无 Return: 无 *************************************************/ void FileDialog::init() { filterEdit = new QLineEdit(this, "filterEdit"); pathBox = new QComboBox(this, "pathBox"); dirs = new QListBox(this, "dirList"); files = new QListBox(this, "fileList"); nameEdit = new QLineEdit(this, "nameEdit"); filterL = new QLabel("Filter:", this, "filterLabel"); nameL = new QLabel("Name:", this, "filterLabel"); dirL = new QLabel("Directories:", this, "dirLabel"); fileL = new QLabel("Files:", this, "fileLabel"); okB = new QPushButton("OK", this, "okButton"); filterB = new QPushButton("Filter", this, "filterButton"); cancelB = new QPushButton("Cancel", this, "cancelButton"); pathBox->setAutoResize(TRUE ); filterL->setAutoResize( TRUE ); nameL->setAutoResize( TRUE ); dirL->setAutoResize( TRUE ); fileL->setAutoResize( TRUE ); okB->resize(50, 25); filterB->resize(50, 25); cancelB->resize(50, 25); connect(files, SIGNAL(selected(int)), SLOT(fileSelected(int))); connect(files, SIGNAL(highlighted(int)), SLOT(fileHighlighted(int))); connect(dirs, SIGNAL(selected(int)), SLOT(dirSelected(int))); connect(pathBox, SIGNAL(activated(int)), SLOT(pathSelected(int))); connect(okB, SIGNAL(clicked()), SLOT(okClicked())); connect(nameEdit, SIGNAL(returnPressed()), SLOT(okClicked())); connect(filterEdit, SIGNAL(returnPressed()), SLOT(filterClicked())); connect(filterB, SIGNAL(clicked()), SLOT(filterClicked())); connect(cancelB, SIGNAL(clicked()), SLOT(cancelClicked())); d.setMatchAllDirs( TRUE ); d.setSorting(d.sorting()|QDir::DirsFirst); } /************************************************* Function: ~FileDialog() Description: 析构函数 Calls: Input: 无 Output: 无 Return: 无 *************************************************/ FileDialog::~FileDialog() { delete files; delete dirs; delete filterEdit; delete nameEdit; delete pathBox; delete filterL; delete nameL; delete dirL; delete fileL; delete okB; delete filterB; delete cancelB; } /************************************************* Function: selectedFile() Description: 返回选中文件名 Calls: text() Input: 无 Output: 无 Return: 选中文件名 *************************************************/ QString FileDialog::selectedFile() const { QString tmp; if (nameEdit->text() && strcmp(nameEdit->text(), "") != 0) { tmp = d.absFilePath(nameEdit->text()); } return tmp; } /************************************************* Function: dirPath() Description: 返回活动目录路径 Calls: path() Input: 无 Output: 无 Return: 目录路径 *************************************************/ const char *FileDialog::dirPath() const { return d.path(); } /************************************************* Function: setDir() Description: 设置目录路径 Calls: path() converToAbs() rereadDir() Input: 无 Output: 无 Return: 无 *************************************************/ void FileDialog::setDir(const char *pathstr) { if (strcmp(d.path(), pathstr) == 0) { return; } d.setPath(pathstr); d.convertToAbs(); rereadDir(); } /************************************************* Function: dir() Description: 返回目录 Calls: Input: 无 Output: 无 Return: 目录 *************************************************/ const QDir *FileDialog::dir() const { return &d; } void FileDialog::setDir( const QDir &dir ) { d = dir; d.convertToAbs(); d.setMatchAllDirs( TRUE ); d.setSorting(d.sorting() | QDir::DirsFirst); rereadDir(); } /************************************************* Function: rereadDir() Description: 刷新目录列表 Calls: setOverrideCursor setAutoUpdate() clear() Input: 无 Output: 无 Return: 无 *************************************************/ void FileDialog::rereadDir() { qApp ->setOverrideCursor( waitCursor ); dirs ->setAutoUpdate( FALSE ); files->setAutoUpdate( FALSE ); dirs ->clear(); files->clear(); const QFileInfoList *filist = d.entryInfoList(); if (filist) { QFileInfoListIterator it(*filist); QFileInfo *fi = it.current(); while (fi && fi->isDir()) { dirs->insertItem(fi->fileName().data()); fi = ++it; } while (fi) { files->insertItem(fi->fileName().data()); fi = ++it; } } else { qApp->restoreOverrideCursor(); QMessageBox::message("Sorry", "Cannot open or read directory."); qApp ->setOverrideCursor(waitCursor); } dirs ->setAutoUpdate( TRUE ); files->setAutoUpdate( TRUE ); dirs ->repaint(); files->repaint(); updatePathBox( d.path() ); qApp->restoreOverrideCursor(); } /************************************************* Function: getOpenFileName() Description: 返回打开文件名 Calls: selectedFile() Input: 无 Output: 无 Return: 目录 *************************************************/ QString FileDialog::getOpenFileName( const char *dirName, const char *filter, QWidget *parent, const char *name ) { FileDialog *dlg = new FileDialog( dirName, filter, parent, name, TRUE ); CHECK_PTR( dlg ); dlg->setCaption( "Open" ); QString result; if (dlg->exec() == QDialog::Accepted) { result = dlg->selectedFile(); } delete dlg; return result; } QString FileDialog::getAllOpenFileNames( const char *dirName, const char *filter, QWidget *parent, const char *name ) { return getOpenFileName( dirName, filter, parent, name ); } /************************************************* Function: getSaveFileName() Description: 返回保存文件名 Calls: setCaption() selectedFile() Input: const char *dirName const char *filter QWidget *parent const char *name Output: 无 Return: 保存文件名 *************************************************/ QString FileDialog::getSaveFileName(const char *dirName, const char *filter, QWidget *parent, const char *name) { FileDialog *dlg = new FileDialog( dirName, filter, parent, name, TRUE ); CHECK_PTR( dlg ); dlg->setCaption( "Save As" ); QString result; if ( dlg->exec() == QDialog::Accepted) { result = dlg->selectedFile(); } delete dlg; return result; } /************************************************* Function: fileSelected() Description: 文件选中时激活 Calls: text() accept() Input: int index Output: 无 Return: 无 *************************************************/ void FileDialog::fileSelected( int index ) { nameEdit->setText( files->text(index) ); emit fileSelected( d.filePath( nameEdit->text() ) ); accept(); } /************************************************* Function: fileHighlighted() Description: 文件高亮显示时激活 Calls: setText() Input: int index Output: 无 Return: 无 *************************************************/ void FileDialog::fileHighlighted(int index) { nameEdit->setText(files->text(index)); emit fileHighlighted(d.filePath(files->text(index))); } /************************************************* Function: dirSelected() Description: 目录选中时激活 Calls: text() isReadable() path() rereadDir() Input: int index Output: 无 Return: 无 *************************************************/ void FileDialog::dirSelected( int index ) { QDir tmp = d; if ( d.cd( dirs->text(index) ) && d.isReadable() ) { nameEdit->setText(""); emit dirEntered(d.path()); rereadDir(); } else { QMessageBox::message( "Sorry", "Cannot open or read directory." ); d = tmp; } } void FileDialog::pathSelected( int index ) { if ( index == 0 ) // current directory shown { return; } QString newPath; QDir tmp = d; for( int i = pathBox->count() - 1 ; i >= index ; i-- ) { newPath += pathBox->text( i ); } d.setPath( newPath ); if (d.isReadable()) { rereadDir(); } else { d = tmp; } } /************************************************* Function: onClicked() Description: OK按钮响应 Calls: text() Input: 无 Output: 无 Return: 无 *************************************************/ void FileDialog::okClicked() { if ( strcmp( nameEdit->text(), "") != 0 ) { emit fileSelected(d.filePath(nameEdit->text())); accept(); } } /************************************************* Function: filterClicked() Description: filter按钮响应 Calls: text() rereadDir Input: 无 Output: 无 Return: 无 *************************************************/ void FileDialog::filterClicked() { if ( strcmp( filterEdit->text(), "" ) == 0 ) filterEdit->setText( "*" ); d.setNameFilter( filterEdit->text() ); rereadDir(); } /************************************************* Function: cancelClicked() Description: cancel按钮响应 Calls: reject() Input: 无 Output: 无 Return: 无 *************************************************/ void FileDialog::cancelClicked() { reject(); } void FileDialog::resizeEvent( QResizeEvent * ) { int w = width(); int h = height(); int wTmp; QRect rTmp; filterL->move( 10, 10 ); wTmp = filterL->width(); filterEdit->setGeometry( wTmp + 15, 10, w - wTmp - 15 - 10, 20 ); rTmp = filterL->geometry(); wTmp = pathBox->width(); pathBox->move( (w - wTmp)/2, rTmp.bottom() + 10 ); rTmp = pathBox->geometry(); dirL->move( 10, rTmp.bottom() + 5 ); rTmp = dirL->geometry(); fileL->move( w / 2 + 5, rTmp.y() ); rTmp = dirL->geometry(); dirs->setGeometry(10, rTmp.bottom() + 5, w/2 - 15, h - rTmp.bottom() - 10 - 25 - 10 - 20 - 10 ); rTmp = dirs->geometry(); files->setGeometry( rTmp.right() + 10, rTmp.y(), rTmp.width(), rTmp.height() ); rTmp = dirs->geometry(); nameL->move( 10, rTmp.bottom() + 10 ); wTmp = nameL->width(); nameEdit->setGeometry( wTmp + 15, rTmp.bottom() + 10, w - wTmp - 15 - 10, 20 ); rTmp = nameEdit->geometry(); okB->move( 10, rTmp.bottom() + 10 ); rTmp = okB->geometry(); wTmp = cancelB->width(); cancelB->move( w - 10 - wTmp, rTmp.y() ); wTmp = filterB->width(); filterB->move( (w - wTmp)/2, rTmp.y() ); } /************************************************* Function: updatePathBox() Description: 更新路径 Calls: strcpy() insert() strtok() Input: const char *s Output: 无 Return: 无 *************************************************/ void FileDialog::updatePathBox( const char *s ) { QStrList l; QString tmp; char* tmps = new char[100]; strcpy(tmps, s); l.insert( 0, "/" ); tmp = strtok(tmps, "/"); while( TRUE ) { if (tmp.isNull()) { break; } l.insert( 0, tmp + "/" ); tmp = strtok( 0, "/" ); } pathBox->setUpdatesEnabled( FALSE ); pathBox->clear(); pathBox->insertStrList( &l ); pathBox->setCurrentItem( 0 ); pathBox->move((width() - pathBox->width()) / 2, pathBox->geometry().y()); pathBox->setUpdatesEnabled( TRUE ); pathBox->repaint(); }