/* This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "filesystemwidget.h" #include "filesystemdirproxy.h" #include "fileview.h" #include "shemoviconprovider.h" #include "filesystemfileproxy.h" #include "pictureviewer2.h" #include "smglobals.h" #include "delegates.h" #include "smdirmodel.h" #include "smdialog.h" #include "archivemodel.h" FilesystemWidget::FilesystemWidget(QWidget *parent) : QWidget(parent), mClipboardMode(None) { mModel = new FileSystemModel(this); mModel->setRootPath("/"); mModel->setFilter(QDir::AllEntries | QDir::NoDot); mModel->setReadOnly(false); mIconProvider = new SheMovIconProvider; mModel->setIconProvider(mIconProvider); QStringList fHeaders = QStringList() << tr("Name") << tr("Size") << tr("Type") << tr("Created") << tr("Md5Sum") << tr("Dur./Size") << tr("Bitrate") << tr("Full Path") << tr("Present"); mFileModel = new SmDirModel(fHeaders, this); connect(mFileModel, SIGNAL(needResize()), this, SLOT(resizeFileView())); mDirProxy = new FilesystemDirProxy; mDirProxy->setSourceModel(mModel); mDirView = new SmTreeView; mDirView->setModel(mDirProxy); mDirView->setColumnHidden(1, true); mDirView->setColumnHidden(2, true); mDirView->setColumnHidden(3, true); mDirView->setRootIsDecorated(false); mDirView->setSelectionMode(QAbstractItemView::SingleSelection); mDirView->setEditTriggers(QAbstractItemView::NoEditTriggers); mDirView->setSortingEnabled(true); mDirView->sortByColumn(0, Qt::AscendingOrder); mFileView = new FileView; mFileProxy = new FilesystemFileProxy; mFileProxy->setSourceModel(mFileModel); mFileView->setModel(mFileProxy); mFileView->setSortingEnabled(true); mFileView->sortByColumn(0, Qt::AscendingOrder); mFileView->setItemsExpandable(false); mFileView->setSelectionMode(QAbstractItemView::ExtendedSelection); mFileView->setSelectionBehavior(QAbstractItemView::SelectRows); mFileView->setItemDelegateForColumn(SmDirModel::DurSize, new DurationDelegate(this)); mFileView->setItemDelegateForColumn(SmDirModel::Bitrate, new BitrateDelegate(this)); mFileProxy->setDynamicSortFilter(true); connect(mFileView->selectionModel(), SIGNAL(selectionChanged(QItemSelection,QItemSelection)), mFileView, SLOT(selectedFilesChanged())); connect(mFileModel, SIGNAL(modelAboutToBeReset()), mFileView, SLOT(saveSelection())); connect(mFileModel, SIGNAL(modelReset()), mFileView, SLOT(restoreSelection())); mPicViewer = SmGlobals::instance()->pictureViewer(); mUnpackDlg = new UnpackDialog(this); connect(mUnpackDlg, SIGNAL(workFinished()), this, SLOT(selectUnpackDir())); QWidget *fileWidget = new QWidget; mIconDirSplitter = new QSplitter(this); mToolBar = new QToolBar; mToolBar->setIconSize(QSize(16,16)); QHBoxLayout *directoryEditL = new QHBoxLayout; QLabel *dirLabel = new QLabel(tr("&Directory")); mDirEdit = new QLineEdit; QCompleter *completer = new QCompleter(this); completer->setModel(mModel); completer->setCompletionMode(QCompleter::PopupCompletion); mDirEdit->setCompleter(completer); dirLabel->setBuddy(mDirEdit); directoryEditL->addWidget(dirLabel); directoryEditL->addWidget(mDirEdit); QWidget *dirEditW = new QWidget; dirEditW->setLayout(directoryEditL); mIconDirSplitter->addWidget(mToolBar); mIconDirSplitter->addWidget(dirEditW); QVBoxLayout *fwLayout = new QVBoxLayout; fwLayout->addWidget(mIconDirSplitter); fwLayout->addWidget(mFileView); fileWidget->setLayout(fwLayout); connect(mDirView->selectionModel(), SIGNAL(currentChanged(const QModelIndex &, const QModelIndex &)), this, SLOT(directoryChanged(const QModelIndex &, const QModelIndex &))); connect(mDirView, SIGNAL(expanded(QModelIndex)), this, SLOT(dirExpanded(QModelIndex))); connect(mDirView, SIGNAL(collapsed(QModelIndex)), this, SLOT(dirCollapsed(QModelIndex))); connect(mFileView, SIGNAL(doubleClicked(const QModelIndex &)), this, SLOT(fileViewActivated(const QModelIndex &))); connect(mFileView, SIGNAL(enterPressed(const QModelIndex &)), this, SLOT(fileViewActivated(const QModelIndex &))); connect(mFileView, SIGNAL(upDir()), this, SLOT(parentDir())); connect(mDirEdit, SIGNAL(returnPressed()), this, SLOT(directoryEdited())); connect(mFileView, SIGNAL(delFiles()), this, SLOT(deleteFiles())); connect(mFileView, SIGNAL(editorClosed(QModelIndex)), this, SLOT(fileEditorClosed(QModelIndex))); connect(this, SIGNAL(upSelected(QString)), mFileView, SLOT(selectItem(QString))); QVBoxLayout *mainLayout = new QVBoxLayout; QSplitter *splitter = new QSplitter; splitter->addWidget(mDirView); splitter->addWidget(fileWidget); splitter->setStretchFactor(0, 1); splitter->setStretchFactor(1, 2); mainLayout->addWidget(splitter); setLayout(mainLayout); } bool FilesystemWidget::isMounted(){ QSettings s; QString mount = s.value("paths/dvdmount").toString(); if(mount.isEmpty()){ return false; } QFile mounts("/proc/mounts"); if(!mounts.exists() || !mounts.open(QFile::ReadOnly)){ return false; } QTextStream mountStream(&mounts); QString line; do { line = mountStream.readLine(); if(line.contains(mount)){ return true; } } while(!line.isNull()); return false; } const QString FilesystemWidget::currentDir() const { return mFileModel->dir().absolutePath(); } void FilesystemWidget::directoryChanged(const QModelIndex &selected, const QModelIndex &deselected){ QModelIndex real = mDirProxy->mapToSource(selected); if(!real.isValid()){ return; } QModelIndex realPrev = mDirProxy->mapToSource(deselected); if(realPrev.isValid()){ mLastFiles[Previous] = mLastFiles[Current]; mLastFiles[Current] = mFileView->selectedItems(); mLastDir = realPrev.data(QFileSystemModel::FilePathRole).toString(); } mModel->setRootPath(mModel->filePath(real)); mDirEdit->setText(mModel->filePath(real)); setWindowTitle(); mFileView->selectionModel()->clear(); mFileModel->setDir(mModel->filePath(real)); resizeFileView(); } void FilesystemWidget::directoryEdited(){ QString path = mDirEdit->text(); if(path.isEmpty()){ return; } QModelIndex index = mModel->index(path); if(index.isValid()){ mDirView->setCurrentIndex(mDirProxy->mapFromSource(index)); } mFileView->setFocus(Qt::ActiveWindowFocusReason); } void FilesystemWidget::fileViewActivated(const QModelIndex &idx){ /* we cannot use idx from the SIGNAL here, since the model * may already have changed */ Q_UNUSED(idx); TimerHandler h(mFileModel->refreshTimer()); QModelIndexList selected = mFileView->selectionModel()->selectedRows(); if(selected.isEmpty()){ return; } QModelIndex real = mFileProxy->mapToSource(selected.first()); if(mFileModel->isDir(real)){ if(real.data().toString() == ".."){ parentDir(); return; } fileView()->selectionModel()->select(selected.first(), QItemSelectionModel::Deselect); QModelIndex curDir = mModel->index(real.data(SmDirModel::FullPathRole).toString()); mDirView->setCurrentIndex(mDirProxy->mapFromSource(curDir)); return; } QString path = real.data(SmDirModel::FullPathRole).toString(); QString mt = Helper::mimeType(path); QStringList programArgs; QString program; if(mt.toLower().startsWith("video")){ QPair data = programData("movieviewer", QString()); if(data.first.isEmpty()){ QMessageBox::critical(this, tr("Error"), tr("No viedeo viewer configured.")); return; } program = data.first; programArgs = data.second; } if(mt.toLower().startsWith("image")){ if(!mPicViewer->isVisible()){ mPicViewer->setVisible(true); } mPicViewer->setShowMappingItem(false); mPicViewer->setShowMarkItem(true); selectAllPV(); QFileInfo fi(path); mPicViewer->setCurrentDir(fi.absolutePath()); mPicViewer->selectPic(path); return; } programArgs << path; QProcess::startDetached(program, programArgs); } void FilesystemWidget::parentDir(){ QModelIndex idx = mDirView->currentIndex(); QModelIndex prev = idx.sibling(idx.row() - 1, idx.column()); QString pName; if(prev.isValid()){ pName = idx.data().toString(); } QString sel = idx.data().toString(); if(idx.parent().isValid()){ mDirView->setCurrentIndex(idx.parent()); } if(!pName.isEmpty()){ emit upSelected(sel); } } void FilesystemWidget::goBack(){ if(mLastDir.isEmpty()){ return; } QModelIndex lastIdx = mModel->index(mLastDir); mDirView->selectionModel()->setCurrentIndex(mDirProxy->mapFromSource(lastIdx), QItemSelectionModel::ClearAndSelect); if(lastIdx.isValid()){ if(!mLastFiles[Previous].isEmpty()){ foreach(QString lf, mLastFiles[Previous]){ mFileView->selectItem(lf); } } } } void FilesystemWidget::deleteFiles(){ qApp->setOverrideCursor(Qt::WaitCursor); TimerHandler h(mFileModel->refreshTimer()); WatcherHandler wh(mFileModel->watcher()); qApp->restoreOverrideCursor(); QModelIndexList selected = mFileView->selectionModel()->selectedRows(); if(selected.isEmpty()){ return; } QString message = QString(tr("Really delete %1 files?")).arg(QString::number(selected.count())); int retval = QMessageBox::question(this, tr("Question"), message, QMessageBox::Yes | QMessageBox::No); if(retval == QMessageBox::Yes){ foreach(QModelIndex idx, selected){ QModelIndex real = mFileProxy->mapToSource(idx); if(real.isValid()){ QFileInfo fi(real.data(SmDirModel::FullPathRole).toString()); deleteRecursive(fi); } } } } void FilesystemWidget::toClipboard(int clipmode){ TimerHandler h(mFileModel->refreshTimer()); mClipboardMode = clipmode; QClipboard *clip = qApp->clipboard(); QModelIndexList selected = mFileView->selectionModel()->selectedRows(); clip->clear(); mModel->clearClipboardList(); if(selected.isEmpty()){ return; } QList files; foreach(QModelIndex idx, selected){ if(idx.data(SmDirModel::NameRole).toString() == ".."){ continue; } files << QUrl::fromLocalFile(idx.data(SmDirModel::FullPathRole).toString()); mModel->markForClipboard(mFileProxy->mapToSource(idx)); } QMimeData *mimeData = new QMimeData; mimeData->setUrls(files); clip->setMimeData(mimeData); } void FilesystemWidget::fromClipboard(){ QClipboard *clip = qApp->clipboard(); const QMimeData *mimeData = clip->mimeData(); if(!mimeData->hasUrls()){ return; } QStringList files; foreach(QUrl url, mimeData->urls()){ files << url.toLocalFile(); } const QString destDir = selectedDir(); QFileInfo destDirFi(destDir); if(!destDirFi.isDir()){ return; } if(mClipboardMode == Copy){ mModel->clearClipboardList(); copyFiles(files, destDir); }else if(mClipboardMode == Cut){ mModel->clearClipboardList(); moveFiles(files, destDir); } } void FilesystemWidget::renameFile(){ TimerHandler h(mFileModel->refreshTimer()); QModelIndex curIdx = mFileView->currentIndex(); if(curIdx.data().toString() == ".."){ return; } bool ok = false; QString fileName = curIdx.data(SmDirModel::NameRole).toString(); QString l1 = QString(tr("Rename %1").arg(fileName)); QString newName = QInputDialog::getText(this, tr("Rename file"), l1, QLineEdit::Normal, fileName, &ok); if(ok){ QFileInfo fi(curIdx.data(SmDirModel::FullPathRole).toString()); QString nfn = QString("%1/%2").arg(fi.absolutePath()).arg(newName); QFile f(fi.absoluteFilePath()); f.rename(nfn); } } void FilesystemWidget::playSelected(const QString &player){ TimerHandler h(mFileModel->refreshTimer()); QStringList files = selectedFiles(); if(files.isEmpty()){ statusbarMessage(tr("Nothing selected.")); return; } QPair data = programData("movieviewer", player); if(data.first.isEmpty()){ data = programData("pictureviewer", player); if(data.first.isEmpty()){ QString message = QString(tr("Cannot find program %1.")).arg(player); QMessageBox::critical(this, tr("Error"), message); return; } } QString program = data.first; QStringList programArgs(data.second); programArgs << files; QProcess::startDetached(program, programArgs); } void FilesystemWidget::playSelectedRepeat(int times){ TimerHandler h(mFileModel->refreshTimer()); QStringList files = selectedFiles(); if(files.isEmpty()){ statusbarMessage(tr("Nothing selected.")); return; } QPair data = programData("movieviewer", QString()); QString program = data.first; QStringList programArgs(data.second); if(times == -1){ programArgs << "--loop" << files; }else{ for(int i = 0; i < times; ++i){ programArgs << files; } } QProcess::startDetached(program, programArgs); } void FilesystemWidget::playSelectedInfinite(){ playSelectedRepeat(-1); } void FilesystemWidget::readSettings(){ QSettings s; QStringList expandedDirs = s.value("paths/expandeddirs").toStringList(); if(expandedDirs.isEmpty()){ expandedDirs << QDir::homePath(); } foreach(QString p, expandedDirs){ QModelIndex idx = mModel->index(p); if(idx.isValid()){ QModelIndex pidx = mDirProxy->mapFromSource(idx); if(pidx.isValid()){ mDirView->setExpanded(pidx, true); } } } QString selectedDir = s.value("paths/selecteddir").toString(); if(!selectedDir.isEmpty()){ QModelIndex diridx = mModel->index(selectedDir); if(diridx.isValid()){ QModelIndex pidx = mDirProxy->mapFromSource(diridx); mDirView->selectionModel()->setCurrentIndex(pidx, QItemSelectionModel::ClearAndSelect); } } bool expensiveOps = s.value("ui/expensiveops", true).toBool(); mFileModel->watcher()->setExpensiveOps(expensiveOps); QPoint picViewerPos = s.value("windows/picviewer").toPoint(); mIconDirSplitter->restoreState(s.value("ui/fsdirsplitter").toByteArray()); mPicViewer->move(picViewerPos); mFileView->readConfig(); } void FilesystemWidget::writeSettings(){ QSettings s; s.setValue("paths/expandeddirs", mExpandedDirs); QModelIndex currentDir = mDirView->selectionModel()->currentIndex(); if(currentDir.isValid()){ QModelIndex real = mDirProxy->mapToSource(currentDir); QString dir = mModel->filePath(real); s.setValue("paths/selecteddir", dir); } s.setValue("windows/picviewer", mPicViewer->pos()); s.setValue("ui/fsdirsplitter", mIconDirSplitter->saveState()); mFileView->writeConfig(); } void FilesystemWidget::configChanged(){ mModel->setIconProvider(mIconProvider); mFileModel->readSettings(); mFileModel->refresh(); } void FilesystemWidget::dvdMount(){ QSettings s; QString mountDir = s.value("paths/dvdmount").toString(); if(isMounted()){ int retval = QProcess::execute("umount", QStringList() << mountDir); if(retval){ QString message = QString(tr("Could not unmount %1: %2")).arg(mountDir).arg(strerror(retval)); QMessageBox::critical(this, tr("Error"), message); return; } emit mounted(false); }else{ int retval = -1; int ctr = 0; while(retval){ retval = QProcess::execute("mount", QStringList() << mountDir); ++ctr; if(ctr > 4){ break; } } QModelIndex mIdx = mDirProxy->mapFromSource(mModel->index(mountDir)); mDirView->selectionModel()->setCurrentIndex(mIdx, QItemSelectionModel::ClearAndSelect); if(!isMounted()){ QString message = QString(tr("Could not mount %1: %2")).arg(mountDir).arg(strerror(retval)); QMessageBox::critical(this, tr("Error"), message); emit mounted(isMounted()); return; } //ugly hack to update QFileSytemModel QString tDirPath = mLastDir.isEmpty() ? QDir::homePath() : mLastDir; QModelIndex tIdx = mDirProxy->mapFromSource(mModel->index(tDirPath)); mDirView->selectionModel()->setCurrentIndex(tIdx, QItemSelectionModel::ClearAndSelect); mDirView->selectionModel()->setCurrentIndex(mIdx, QItemSelectionModel::ClearAndSelect); mDirView->selectionModel()->setCurrentIndex(tIdx, QItemSelectionModel::ClearAndSelect); mDirView->selectionModel()->setCurrentIndex(mIdx, QItemSelectionModel::ClearAndSelect); mDirView->expand(mIdx); emit mounted(isMounted()); } } void FilesystemWidget::moveToArchive(){ QStringList selected = selectedFiles(); QFileInfoList files; foreach(QString f, selected){ QFileInfo fi(f); if(fi.isDir()){ files.append(getRecursive(fi)); }else{ files.append(fi); } } QMap res; foreach(QFileInfo fi, files){ if(!fi.exists()){ res.insert(fi.fileName(), tr("File not found")); continue; } QString md5 = Helper::md5Sum(fi.absoluteFilePath()); if(!ArchiveFilesModel::hasFile(md5)){ res.insert(fi.fileName(), tr("Not in archive")); continue; } QString mvres = Helper::moveToArchive(fi.absoluteFilePath(), md5); if(mvres.isEmpty()){ res.insert(fi.fileName(), tr("Move failed")); continue; } if(!ArchiveFilesModel::setDvdNo(md5, -1)){ res.insert(fi.fileName(), tr("DvdNo. update failed")); } res.insert(fi.fileName(), tr("Success")); } QString msg(""); msg.append(tr("

Result:

")); msg.append("
    "); QMap::const_iterator it = res.constBegin(); while(it != res.constEnd()){ QString m = QString(tr("
  • %1: %2
  • ")).arg(it.key()).arg(it.value()); msg.append(m); ++it; } msg.append("
"); msg.append(""); QMessageBox::information(this, tr("Move to archive"), msg, QMessageBox::Ok); } void FilesystemWidget::selectAllPV(){ QModelIndex idx = mDirView->currentIndex(); if(idx.isValid()){ QModelIndex real = mDirProxy->mapToSource(idx); QString filePath = real.data(QFileSystemModel::FilePathRole).toString(); mPicViewer->addFiles(filePath, true); } } void FilesystemWidget::setWindowTitle(){ QModelIndex curIdx = mDirView->selectionModel()->currentIndex(); QString dir = curIdx.data(QFileSystemModel::FilePathRole).toString(); mWindowTitle = QString(tr("Filemanager - [%1]")).arg(dir); emit windowTitle(mWindowTitle); } void FilesystemWidget::preview(){ QModelIndex curIdx = mFileView->selectionModel()->currentIndex(); QString mimeType = curIdx.data(SmDirModel::TypeRole).toString(); if(mimeType.startsWith("video")){ qApp->setOverrideCursor(Qt::BusyCursor); mPicViewer->setShowMappingItem(false); QPixmap pm(Helper::preview(curIdx.data(SmDirModel::FullPathRole).toString())); if(!pm.isNull()){ mPicViewer->setPixmap(pm); mPicViewer->show(); } qApp->restoreOverrideCursor(); }else if(mimeType.startsWith("image")){ mPicViewer->setShowMappingItem(false); mPicViewer->setFile(curIdx.data(SmDirModel::FullPathRole).toString()); mPicViewer->show(); } } void FilesystemWidget::unpack(){ QModelIndexList selectedIdxs = mFileView->selectionModel()->selectedRows(); mUnpackDlg->clearOutput(); mUnpackDlg->setCloseEnabled(false); mUnpackDlg->clearCommandQueue(); mUnpackDlg->show(); foreach(QModelIndex idx, selectedIdxs){ QString mimeType = idx.data(SmDirModel::TypeRole).toString(); if(mimeType == "application/zip" || mimeType == "application/x-rar"){ QStringList args = QStringList() << "-o/home/am/movs/pics/7z" << "-y" << "e" << idx.data(SmDirModel::FullPathRole).toString(); mUnpackDlg->appendCommand(args); } } mUnpackDlg->doIt(); } void FilesystemWidget::selectUnpackDir(){ QModelIndex unpackDirIdx = mModel->index("/home/am/movs/pics/7z"); if(unpackDirIdx.isValid()){ mDirView->selectionModel()->setCurrentIndex(mDirProxy->mapFromSource(unpackDirIdx), QItemSelectionModel::ClearAndSelect); } } void FilesystemWidget::centerCurrent(){ QModelIndex curIdx = mDirView->currentIndex(); mDirView->scrollTo(curIdx, QAbstractItemView::PositionAtCenter); } void FilesystemWidget::deleteRecursive(const QFileInfo &start){ if(start.isDir()){ QDir curDir = QDir(start.absoluteFilePath());; foreach(QFileInfo info, curDir.entryInfoList(QDir::AllEntries | QDir::NoDotAndDotDot)){ if(info.isDir()){ deleteRecursive(info); }else{ QFile::remove(info.absoluteFilePath()); } } QDir dir = start.absoluteDir(); dir.rmdir(start.fileName()); }else{ QFile::remove(start.absoluteFilePath()); } } QFileInfoList FilesystemWidget::getRecursive(const QFileInfo &start) const{ QFileInfoList retval; if(start.isDir()){ QDir curDir = QDir(start.absoluteFilePath()); foreach(QFileInfo info, curDir.entryInfoList(QDir::AllEntries | QDir::NoDotAndDotDot)){ if(info.isDir()){ retval.append(getRecursive(info)); }else{ retval.append(info); } } } return retval; } void FilesystemWidget::copyFiles(const QStringList &files, const QString &dest){ foreach(const QString file, files){ QFileInfo fi(file); if(fi.isDir()){ copyRecursive(fi, dest); }else if(fi.isFile()){ const QString destFile = QString("%1/%2").arg(dest).arg(fi.fileName()); QFile::copy(fi.absoluteFilePath(), destFile); } } } void FilesystemWidget::moveFiles(const QStringList &files, const QString &dest){ foreach(const QString file, files){ QFileInfo fi(file); const QString destFile = QString("%1/%2").arg(dest).arg(fi.fileName()); QFile::rename(file, destFile); } } QPair FilesystemWidget::programData(const QString &prefix, const QString &preferred){ QSettings s; QString section = QString("programs_%1").arg(prefix); QHash data = s.value(QString("%1/data").arg(section)).toHash(); if(data.isEmpty()){ return QPair(); } QHash programData; if(!preferred.isEmpty()){ if(data.keys().contains(preferred)){ programData = data.value(preferred).toHash(); return qMakePair(programData.value("path").toString(), programData.value("args").toStringList()); } return QPair(); } QString defaultProg = s.value(QString("%1/default").arg(section)).toString(); if(defaultProg.isEmpty()){ return QPair(); } programData = data.value(defaultProg).toHash(); return qMakePair(programData.value("path").toString(), programData.value("args").toStringList()); } void FilesystemWidget::copyRecursive(const QFileInfo &start, const QString &destdir){ if(!start.isDir()){ return; } QDir source(start.absoluteFilePath()); QDir dest = QDir(destdir); if(!dest.exists(source.dirName())){ dest.mkdir(source.dirName()); } QString d = QString("%1/%2").arg(destdir).arg(source.dirName()); foreach(QFileInfo cur, source.entryInfoList(QDir::AllEntries | QDir::NoDotAndDotDot)){ if(cur.isDir()){ copyRecursive(cur, d); }else{ QString destPath = QString("%1/%2").arg(d).arg(cur.fileName()); QFile::copy(cur.absoluteFilePath(), destPath); } } } const QString FilesystemWidget::selectedDir(){ const QModelIndexList selected = mDirView->selectionModel()->selectedRows(); if(!selected.isEmpty()){ return selected.at(0).data(QFileSystemModel::FilePathRole).toString(); } return QString(); } void FilesystemWidget::keyPressEvent(QKeyEvent *e){ if(e->key() == Qt::Key_Left && (e->modifiers() & Qt::ControlModifier)){ goBack(); return; } if(e->key() == Qt::Key_Up && (e->modifiers() & Qt::ControlModifier)){ parentDir(); return; } if(e->key() == Qt::Key_U && (e->modifiers() & Qt::ControlModifier)){ unpack(); return; } QWidget::keyPressEvent(e); } void FilesystemWidget::dirExpanded(const QModelIndex &idx){ QModelIndex real = mDirProxy->mapToSource(idx); if(real.isValid()){ mExpandedDirs << mModel->filePath(real); } } void FilesystemWidget::dirCollapsed(const QModelIndex &idx){ QModelIndex real = mDirProxy->mapToSource(idx); if(real.isValid()){ QString path = mModel->filePath(real); if(mExpandedDirs.contains(path)){ mExpandedDirs.removeAll(path); } } } void FilesystemWidget::fileEditorClosed(const QModelIndex &idx){ QModelIndex real = mFileProxy->mapFromSource(idx); if(real.isValid()){ mFileView->update(real); } } void FilesystemWidget::resizeFileView(){ for(int i = 1; i < 5; ++i){ mFileView->resizeColumnToContents(i); } mFileView->resizeColumnToContents(0); } QStringList FilesystemWidget::selectedFiles(){ QStringList retval; QModelIndexList selected = fileView()->selectionModel()->selectedRows(); if(selected.isEmpty()){ return QStringList(); } foreach(QModelIndex idx, selected){ retval << idx.data(SmDirModel::FullPathRole).toString(); } return retval; } //FileSystemModel FileSystemModel::FileSystemModel(QObject *parent) : QFileSystemModel(parent){} void FileSystemModel::markForClipboard(const QPersistentModelIndex &idx){ if(idx.isValid()){ if(!mClipEntries.contains(idx)){ mClipEntries << idx; } } } void FileSystemModel::clearClipboardList(){ QList tmp(mClipEntries); mClipEntries.clear(); foreach(QPersistentModelIndex ent, tmp){ emit dataChanged(ent, ent); } } void FileSystemModel::cleanup(){ QStringList toRemove; foreach(QString p, mSeen.keys()){ QFileInfo fi(p); if(!fi.exists()){ mDeleteFromSeenQuery->bindValue(":path", p); mDeleteFromSeenQuery->exec(); toRemove << p; } } foreach(QString r, toRemove){ mSeen.remove(r); } }