File indexing completed on 2024-05-05 16:39:04

0001 /* This file is part of the KDE project
0002    Copyright (C) 1998,1999,2000 Carsten Pfeiffer <pfeiffer@kde.org>
0003 
0004    This program is free software; you can redistribute it and/or
0005    modify it under the terms of the GNU General Public
0006    License as published by the Free Software Foundation, version 2.
0007 
0008    This program is distributed in the hope that it will be useful,
0009    but WITHOUT ANY WARRANTY; without even the implied warranty of
0010    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
0011     General Public License for more details.
0012 
0013    You should have received a copy of the GNU General Public License
0014    along with this program; see the file COPYING.  If not, write to
0015    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
0016    Boston, MA 02110-1301, USA.
0017 */
0018 
0019 #include "openfilesanddirsdialog.h"
0020 
0021 #include <QAbstractItemView>
0022 #include <QDialogButtonBox>
0023 #include <QPushButton>
0024 #include <QSignalMapper>
0025 
0026 
0027 OpenFilesAndDirsDialog::OpenFilesAndDirsDialog(QWidget* parent, const QString& caption)
0028     : QFileDialog(parent, caption)
0029 {
0030     // native dialogs usually don't support selecting files AND directories, so we can't use them
0031     setOption(QFileDialog::DontUseNativeDialog);
0032 
0033     // allow selection of directories
0034     setFileMode(QFileDialog::Directory);
0035 
0036 
0037     // The following code highly depends on the internals of QFileDialog.
0038 
0039     // find the button box within this dialog, so we can connect to the "Open" button
0040     QDialogButtonBox* bbox = findChild<QDialogButtonBox *>();
0041     if(bbox && (buttonOpen = bbox->button(QDialogButtonBox::Open))) {
0042         //buttonOpen->disconnect(SIGNAL(clicked()));
0043         connect(buttonOpen, SIGNAL(clicked()), SLOT(okClicked()));
0044     } else {
0045         qWarning("couldn't find QDialogButtonBox in QFileDialog; selection will not work correctly");
0046     }
0047 
0048     // find the selection controls
0049     QSignalMapper* mapper = new QSignalMapper(this);
0050     for (auto *view : findChildren<QAbstractItemView *>(QRegularExpression("^(?:treeView|listView)$"))) {
0051         // allow selection of multiple entries
0052         view->setSelectionMode(QAbstractItemView::ExtendedSelection);
0053 
0054         // we have to manually set the enabled-state of the "Open" button when the selection changes, because
0055         // the default only enables it when a directory is selected
0056         auto model = view->selectionModel();
0057         connect(model, SIGNAL(selectionChanged(const QItemSelection&, const QItemSelection&)), mapper, SLOT(map()));
0058         mapper->setMapping(model, view);
0059     }
0060     connect(mapper, SIGNAL(mapped(QWidget*)), SLOT(onSelectionChange(QWidget*)));
0061 }
0062 
0063 OpenFilesAndDirsDialog::~OpenFilesAndDirsDialog()
0064 {
0065 }
0066 
0067 
0068 void OpenFilesAndDirsDialog::onSelectionChange(QWidget* obj)
0069 {
0070     QAbstractItemView* view = qobject_cast<QAbstractItemView*>(obj);
0071     if(view) {
0072         auto slist = view->selectionModel()->selectedIndexes();
0073         buttonOpen->setEnabled(!slist.isEmpty());
0074     }
0075 }
0076 
0077 
0078 void OpenFilesAndDirsDialog::okClicked()
0079 {
0080     if(!selectedFiles().isEmpty()) QDialog::accept();
0081 }