📄 qfiledialog.cpp
字号:
return; } // if the user is removing text, don't autocomplete int key = fileNameEdit->lastKeyPressed(); if (key == Qt::Key_Delete || key == Qt::Key_Backspace) { selections->clear(); return; } // Save the path part of what the user has typed. const QString typedPath = info.path(); // If the user has typed a local path that goes beyond the current directory, for example // ../foo or foo/bar, we treat that as an absolute path by prepending the path from lookInEdit. if (!info.isAbsolute() && typedPath != QLatin1String(".")) info.setFile(toInternal(lookInEdit->text() + "/" + text)); // do autocompletion QModelIndex first; if (info.isAbsolute()) // if we have an absolute path, do completion in that directory first = model->index(0, 0, model->index(info.path())); else // otherwise, do completion from the currently selected file first = selections->currentIndex(); // optimization to we don't search from start if (!first.isValid()) first = model->index(0, 0, rootIndex()); QModelIndex result = matchName(info.fileName(), first); // did we find a valid autocompletion ? if (result.isValid()) { treeView->setCurrentIndex(result); QString completed = model->data(result).toString(); if (info.isAbsolute()) { // if we are doing completion in another directory, add the path first if (typedPath == "/") completed = "/" + completed; else if (typedPath.endsWith("/")) // required on windows since drives have trailing / in path completed = typedPath + completed; else completed = typedPath + "/" + completed; } int start = completed.length(); int length = text.length() - start; // negative length bool block = fileNameEdit->blockSignals(true); fileNameEdit->setText(toNative(completed)); fileNameEdit->setSelection(start, length); fileNameEdit->blockSignals(block); } else { // no matches selections->clear(); }}/*! \internal This is called when the user changes the text in the "Look in" combobox; the new text is passed in \a text. The file dialog updates accordingly.*/void QFileDialogPrivate::_q_autoCompleteDirectory(const QString &text){ // if we have no path or the last character is '/', then don't autocomplete if (text.isEmpty() || text.at(text.length() - 1) == QDir::separator()) return;#ifdef Q_OS_WIN // autocompleting the <host> part of UNC paths is just too slow if (text.startsWith("\\\\") || text.startsWith("//")) return;#endif // if the user is not typing or the text is a valid path, there is no need for autocompletion if (!lookInEdit->hasFocus() || QFileInfo(toInternal(text)).exists()) return; // if the user is removing text, don't autocomplete int key = lookInEdit->lastKeyPressed(); if (key == Qt::Key_Delete || key == Qt::Key_Backspace) return; // do autocompletion; text is the local path format (on windows separator is '\\') int indexOfLastSeparator = text.lastIndexOf(QDir::separator()); // this will only trigger on unix QString path = toInternal(indexOfLastSeparator == 0 ? "/" : text.left(indexOfLastSeparator)); QString name = text.section(QDir::separator(), -1); QModelIndex parent = model->index(path); QModelIndex result = matchDir(name, model->index(0, 0, parent)); // did we find a valid autocompletion ? if (result.isValid()) { QString completed = toNative(model->filePath(result)); int start = completed.length(); int length = text.length() - start; // negative length bool block = lookInEdit->blockSignals(true); lookInEdit->setText(completed); lookInEdit->setSelection(start, length); lookInEdit->blockSignals(block); }}/*! \internal This creates the default context menu for the file list.*/void QFileDialogPrivate::_q_showContextMenu(const QPoint &pos){#ifdef QT_NO_MENU Q_UNUSED(pos);#else Q_Q(QFileDialog); QAbstractItemView *view = 0; if (q->viewMode() == QFileDialog::Detail) view = treeView; else view = listView; QModelIndex index = view->indexAt(pos); QMenu menu(view); if (index.isValid() && index.sibling(index.row(), 0) != rootIndex()) { // file context menu menu.addAction(openAction); menu.addSeparator(); menu.addAction(renameAction); menu.addAction(deleteAction); renameAction->setEnabled(!model->isReadOnly()); deleteAction->setEnabled(!model->isReadOnly()); } else { // view context menu menu.addAction(reloadAction); QMenu sort(QFileDialog::tr("Sort")); menu.addMenu(&sort); sort.addAction(sortByNameAction); sort.addAction(sortBySizeAction); sort.addAction(sortByDateAction); sort.addSeparator(); sort.addAction(unsortedAction); menu.addSeparator(); menu.addAction(showHiddenAction); } menu.exec(view->mapToGlobal(pos));#endif // QT_NO_MENU}/*! \internal Creates a new directory, first asking the user for a suitable name.*/void QFileDialogPrivate::_q_createDirectory(){ QModelIndex parent = rootIndex(); listView->clearSelection(); QString folderName = "New Folder"; QString prefix = q_func()->directory().absolutePath() + QDir::separator(); QModelIndex existingIndex = model->index(prefix + folderName); if (existingIndex.isValid()) { qlonglong suffix = 2; while (existingIndex.isValid()) { folderName = "New Folder " + QString::number(suffix++); existingIndex = model->index(prefix + folderName); } } QModelIndex index = model->mkdir(parent, folderName); if (!index.isValid()) return; listView->setCurrentIndex(index); if (viewMode() == QFileDialog::List) listView->edit(index); else treeView->edit(index);}/*! Tells the dialog to rename the currently selected item using input from the user.*/void QFileDialogPrivate::_q_renameCurrent(){ QModelIndex index = selections->currentIndex(); index = index.sibling(index.row(), 0); if (viewMode() == QFileDialog::List) listView->edit(index); else treeView->edit(index);}/*! \internal Deletes the currently selected item in the dialog.*/void QFileDialogPrivate::_q_deleteCurrent(){ Q_Q(QFileDialog); // FIXME: should we delete all selected indexes ? QModelIndex index = selections->currentIndex(); index = index.sibling(index.row(), 0); if(!index.isValid()) return; if (model->isReadOnly()) return; if (model->isDir(index)) { if (!model->rmdir(index)) { QMessageBox::warning(q, q->windowTitle(), tr("Could not delete directory.")); } } else { model->remove(index); }}/*! \internal Sorts the items in the dialog by name order.*/void QFileDialogPrivate::_q_sortByName(){ QDir::SortFlags sort = QDir::SortFlags(QDir::Name|QDir::LocaleAware|QDir::DirsFirst); if (model->filter() & QDir::Reversed) sort |= QDir::Reversed; setDirSorting(sort);}/*! \internal Sorts the items in the dialog by size order.*/void QFileDialogPrivate::_q_sortBySize(){ QDir::SortFlags sort = QDir::SortFlags(QDir::Size|QDir::DirsFirst|QDir::LocaleAware); if(model->filter() & QDir::Reversed) sort |= QDir::Reversed; setDirSorting(sort);}/*! \internal Sorts the items in the dialog by date order.*/void QFileDialogPrivate::_q_sortByDate(){ QDir::SortFlags sort = QDir::SortFlags(QDir::Time|QDir::DirsFirst|QDir::LocaleAware); if(model->filter() & QDir::Reversed) sort |= QDir::Reversed; setDirSorting(sort);}/*! \internal Displays the contents of the current directory in an arbitrary order. \sa _q_sortByDate() _q_sortByName() _q_sortBySize()*/void QFileDialogPrivate::_q_setUnsorted(){ QDir::SortFlags sort = QDir::SortFlags(QDir::Unsorted|QDir::DirsFirst); if(model->filter() & QDir::Reversed) sort |= QDir::Reversed; setDirSorting(sort);}/*! \internal*/void QFileDialogPrivate::_q_sortByColumn(int column){ treeView->sortByColumn(column); model->refresh(rootIndex());}/*! \internal*/void QFileDialogPrivate::_q_currentChanged(const QModelIndex &index){ emit q_func()->currentChanged(model->filePath(index));}extern void qt_setDirModelShouldNotStat(QDirModelPrivate *modelPrivate);void QFileDialogPrivate::setup(const QString &directory, const QStringList &nameFilter){ Q_Q(QFileDialog); q->setSizeGripEnabled(true); QGridLayout *grid = new QGridLayout(q); // QDirModel QDir::Filters filters = filterForMode(fileMode); QDir::SortFlags sort = QDir::SortFlags(QDir::Name|QDir::LocaleAware|QDir::IgnoreCase|QDir::DirsFirst); QStringList cleanedFilter = qt_clean_filter_list(nameFilter.first()); model = new QDirModel(cleanedFilter, filters, sort, q); qt_setDirModelShouldNotStat(model->d_func()); model->setReadOnly(false); model->setLazyChildCount(true); // Selections selections = new QItemSelectionModel(model); QObject::connect(selections, SIGNAL(selectionChanged(QItemSelection,QItemSelection)), q, SLOT(_q_updateFileName(QItemSelection))); QObject::connect(selections, SIGNAL(currentChanged(QModelIndex,QModelIndex)), q, SLOT(_q_currentChanged(QModelIndex))); QModelIndex current = model->index(directory); if (current.isValid() && !model->isDir(current)) current = current.parent(); // try the directory that contains the valid file setupActions(); setupListView(current, grid); setupTreeView(current, grid); setupToolButtons(current, grid); setupWidgets(grid); // Insert paths in the "lookin" combobox lookInCombo->addItem(model->fileIcon(QModelIndex()), QFileDialog::tr("My Computer")); // root for (int r = 0; r < model->rowCount(QModelIndex()); ++r) { // drives QModelIndex index = model->index(r, 0, QModelIndex()); QString path = model->filePath(index); Q_ASSERT(!path.isEmpty()); QIcon icons = model->fileIcon(index); lookInCombo->addItem(icons, toNative(path)); } // insert the home path lookInCombo->addItem(model->iconProvider()->icon(QFileIconProvider::Folder), toNative(QDir::homePath())); // if it is not already in the list, insert the current directory QString currentPath = toNative(model->filePath(current)); if (currentPath.isEmpty()) currentPath = QFileDialog::tr("My Computer"); int item = lookInCombo->findText(currentPath); if (item < 0) { lookInCombo->addItem(model->fileIcon(current), currentPath); item = lookInCombo->findText(currentPath); } lookInCombo->setCurrentIndex(item); // Set filetypes or filter if (fileMode == QFileDialog::DirectoryOnly) { fileTypeCombo->addItem(QFileDialog::tr("Directories")); fileTypeCombo->setEnabled(false); } else { fileTypeCombo->addItems(nameFilter); } // tab order QWidget::setTabOrder(lookInCombo, backButton); QWidget::setTabOrder(backButton, toParentButton); QWidget::setTabOrder(toParentButton, newFolderButton); QWidget::setTabOrder(newFolderButton, detailModeButton); QWidget::setTabOrder(detailModeButton, listModeButton); QWidget::setTabOrder(listModeButton, listView); QWidget::setTabOrder(listView, treeView); QWidget::setTabOrder(treeView, fileNameEdit); QWidget::setTabOrder(fileNameEdit, fileTypeCombo); QWidget::setTabOrder(fileTypeCombo, acceptButton); QWidget::setTabOrder(acceptButton, rejectButton); QWidget::setTabOrder(rejectButton, lookInCombo); // last init q->resize(530, 340); fileNameEdit->setFocus();}void QFileDialogPrivate::setupActions(){ Q_Q(QFileDialog); openAction = new QAction(QFileDialog::tr("&Open"), q); QObject::connect(openAction, SIGNAL(triggered()), q, SLOT(accept())); renameAction = new QAction(QFileDialog::tr("&Rename"), q); QObject::connect(renameAction, SIGNAL(triggered()), q, SLOT(_q_renameCurrent())); deleteAction = new QAction(QFileDialog::tr("&Delete"), q); QObject::connect(deleteAction, SIGNAL(triggered()), q, SLOT(_q_deleteCurrent())); reloadAction = new QAction(QFileDialog::tr("&Reload"), q); QObject::connect(reloadAction, SIGNAL(triggered()), q, SLOT(_q_reload())); sortByNameAction = new QAction(QFileDialog::tr("Sort by &Name"), q); sortByNameAction->setCheckable(true); sortByNameAction->setChecked(true); QObject::connect(sortByNameAction, SIGNAL(triggered()), q, SLOT(_q_sortByName())); sortBySizeAction = new QAction(QFileDialog::tr("Sort by &Size"), q); sortBySizeAction->setCheckable(true); QObject::connect(sortBySizeAction, SIGNAL(triggered()), q, SLOT(_q_sortBySize())); sortByDateAction = new QAction(QFileDialog::tr("Sort by &Date"), q); sortByDateAction->setCheckable(true); QObject::connect(sortByDateAction, SIGNAL(triggered()), q, SLOT(_q_sortByDate())); unsortedAction = new QAction(QFileDialog::tr("&Unsorted"), q); unsortedAction->setCheckable(true); QObject::connect(unsortedAction, SIGNAL(triggered()), q, SLOT(_q_setUnsorted())); showHiddenAction = new QAction(QFileDialog::tr("Show &hidden files"), q); showHiddenAction->setCheckable(true); QObject::connect(showHiddenAction, SIGNAL(triggered()), q, SLOT(_q_showHidden()));}void QFileDialogPrivate::setupListView(const QModelIndex ¤t, QGridLayout *grid){ Q_Q(QFileDialog); listView = new QFileDialogListView(this); listView->setModel(model); listView->setSelectionModel(selections);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -