代码太多,只能贴一部分

QT文件查重控件_ide


#include "aqp.hpp"
#include "alt_key.hpp"
#include "getmd5sthread.hpp"
#include "mainwindow.hpp"
#include <QApplication>
#include <QCloseEvent>
#include <QCompleter>
#include <QDirIterator>
#include <QDirModel>
#include <QHBoxLayout>
#include <QLabel>
#include <QLineEdit>
#include <QPushButton>
#include <QScrollBar>
#include <QStandardItemModel>
#include <QStatusBar>
#include <QTreeView>
#include <QVBoxLayout>


const int StatusTimeout = AQP::MSecPerSecond * 5;
const int StopWait = 100;


#ifdef USE_CUSTOM_DIR_MODEL
// Taken from Qt's completer example
class DirModel : public QDirModel
{
public:
explicit DirModel(QObject *parent=0) : QDirModel(parent) {}

QVariant data(const QModelIndex &index,
int role=Qt::DisplayRole) const
{
if (role == Qt::DisplayRole && index.column() == 0) {
QString path = QDir::toNativeSeparators(filePath(index));
if (path.endsWith(QDir::separator()))
path.chop(1);
return path;
}
return QDirModel::data(index, role);
}
};
#endif


MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent), stopped(false)
{
createWidgets();

model = new QStandardItemModel;
view->setModel(model);

createLayout();
createConnections();

AQP::accelerateWidget(this);
rootDirectoryEdit->setFocus();
statusBar()->showMessage(tr("Set a root directory "
"then press Find"), StatusTimeout);
setWindowTitle(QApplication::applicationName());
}


void MainWindow::createWidgets()
{
rootDirectoryLabel = new QLabel(tr("Root Directory:"));
rootDirectoryEdit = new QLineEdit(QDir::toNativeSeparators(
QDir::homePath()));
rootDirectoryLabel->setBuddy(rootDirectoryEdit);
QCompleter *directoryCompleter = new QCompleter(this);
#ifndef Q_WS_X11
directoryCompleter->setCaseSensitivity(Qt::CaseInsensitive);
#endif
#ifdef USE_CUSTOM_DIR_MODEL
directoryCompleter->setModel(new DirModel(directoryCompleter));
#else
directoryCompleter->setModel(new QDirModel(directoryCompleter));
#endif
rootDirectoryEdit->setCompleter(directoryCompleter);

findButton = new QPushButton(tr("Find"));
cancelButton = new QPushButton(tr("Cancel"));
cancelButton->hide();
quitButton = new QPushButton(tr("Quit"));

view = new QTreeView;
}


void MainWindow::createLayout()
{
QHBoxLayout *topLayout = new QHBoxLayout;
topLayout->addWidget(rootDirectoryLabel);
topLayout->addWidget(rootDirectoryEdit, 1);
topLayout->addWidget(findButton);
topLayout->addWidget(cancelButton);
topLayout->addWidget(quitButton);

QVBoxLayout *layout = new QVBoxLayout;
layout->addLayout(topLayout);
layout->addWidget(view, 1);

QWidget *widget = new QWidget;
widget->setLayout(layout);
setCentralWidget(widget);
}


void MainWindow::createConnections()
{
connect(rootDirectoryEdit, SIGNAL(textChanged(const QString&)),
this, SLOT(updateUi()));
connect(findButton, SIGNAL(clicked()), this, SLOT(find()));
connect(cancelButton, SIGNAL(clicked()), this, SLOT(cancel()));
connect(quitButton, SIGNAL(clicked()), this, SLOT(close()));
}


void MainWindow::updateUi()
{
const QString &root = rootDirectoryEdit->text();
findButton->setEnabled(!root.isEmpty() &&
QFileInfo(root).isDir());
}


void MainWindow::find()
{
stopThreads();

rootDirectoryEdit->setEnabled(false);
view->setSortingEnabled(false);
model->clear();
model->setColumnCount(2);
model->setHorizontalHeaderLabels(QStringList() << tr("File")
<< tr("Size"));
findButton->hide();
cancelButton->show();
cancelButton->setEnabled(true);
cancelButton->setFocus();

stopped = false;
prepareToProcess();
}


void MainWindow::prepareToProcess()
{
statusBar()->showMessage(tr("Reading files..."));
QStringList directories;
directories << rootDirectoryEdit->text();
QDirIterator i(directories.first());
while (!stopped && i.hasNext()) {
const QString &pathAndFilename = i.next();
const QFileInfo &info = i.fileInfo();
if (info.isDir() && !info.isSymLink() &&
i.fileName() != "." && i.fileName() != "..")
directories << pathAndFilename;
}
if (stopped)
return;
processDirectories(directories);
}


void MainWindow::processDirectories(const QStringList &directories)
{
const QVector<int> sizes = AQP::chunkSizes(directories.count(),
QThread::idealThreadCount());
int offset = 0;
foreach (const int chunkSize, sizes) {
QPointer<GetMD5sThread> thread = QPointer<GetMD5sThread>(
new GetMD5sThread(&stopped, directories.first(),
directories.mid(offset, chunkSize),
&filesForMD5));
threads << thread;
connect(thread, SIGNAL(readOneFile()),
this, SLOT(readOneFile()));
connect(thread, SIGNAL(finished()), this, SLOT(finished()));
thread->start();
offset += chunkSize;
}
}


void MainWindow::readOneFile()
{
statusBar()->showMessage(tr("Read %Ln file(s)", "",
filesForMD5.count()));
}


void MainWindow::processResults()
{
stopThreads();

qint64 maximumSize;
forever {
bool more;
QStringList files = filesForMD5.takeOne(&more);
if (!more)
break;
if (files.count() < 2)
continue;
addOneResult(files, &maximumSize);
}
updateView(maximumSize);
statusBar()->showMessage(tr("Found %Ln duplicate file(s)", "",
model->rowCount()));
completed();
}


void MainWindow::addOneResult(const QStringList &files,
qint64 *maximumSize)
{
QFileInfo info(files.first());
if (info.size() > *maximumSize)
*maximumSize = info.size();
QStandardItem *parentItem = model->invisibleRootItem();
QStandardItem *treeItem = new QStandardItem(info.fileName());
QStandardItem *sizeItem = new QStandardItem(
QString("%L1").arg(info.size(), 20, 10, QChar(' ')));
sizeItem->setTextAlignment(Qt::AlignVCenter|Qt::AlignRight);
parentItem->appendRow(QList<QStandardItem*>() << treeItem
<< sizeItem);
foreach (const QString &filename, files)
treeItem->appendRow(new QStandardItem(
QDir::toNativeSeparators(filename)));
}


void MainWindow::updateView(qint64 maximumSize)
{
if (model->rowCount()) {
model->sort(0, Qt::AscendingOrder);
view->expand(model->invisibleRootItem()->child(0)->index());
QFontMetrics fm(font());
int sizeWidth = fm.width(QString("W%L1W").arg(maximumSize));
view->setColumnWidth(1, sizeWidth);
sizeWidth += fm.width("W");
view->setColumnWidth(0, view->width() - (sizeWidth +
view->verticalScrollBar()->sizeHint().width()));
}
}


void MainWindow::finished()
{
foreach (QPointer<GetMD5sThread> thread, threads)
if (thread && thread->isRunning())
return;
processResults();
}


void MainWindow::completed()
{
view->setSortingEnabled(true);
cancelButton->setEnabled(false);
cancelButton->hide();
findButton->show();
findButton->setEnabled(true);
findButton->setFocus();
rootDirectoryEdit->setEnabled(true);
}


void MainWindow::stopThreads()
{
stopped = true;
while (threads.count()) {
QMutableListIterator<QPointer<GetMD5sThread> > i(threads);
while (i.hasNext()) {
QPointer<GetMD5sThread> thread = i.next();
if (thread) {
if (thread->wait(StopWait)) {
delete thread;
i.remove();
}
}
else
i.remove();
}
}
Q_ASSERT(threads.isEmpty());
}


void MainWindow::cancel()
{
stopThreads();
completed();
statusBar()->showMessage(tr("Canceled"), StatusTimeout);
}


void MainWindow::closeEvent(QCloseEvent *event)
{
stopThreads();
event->accept();
}