File indexing completed on 2024-05-12 15:27:47
0001 /*************************************************************************** 0002 File : FileInfoDialog.cpp 0003 Project : LabPlot 0004 Description : import file data dialog 0005 -------------------------------------------------------------------- 0006 Copyright : (C) 2009-2019 Alexander Semke (alexander.semke@web.de) 0007 Copyright : (C) 2015-2018 Stefan-Gerlach (stefan.gerlach@uni.kn) 0008 0009 ***************************************************************************/ 0010 0011 /*************************************************************************** 0012 * * 0013 * This program is free software; you can redistribute it and/or modify * 0014 * it under the terms of the GNU General Public License as published by * 0015 * the Free Software Foundation; either version 2 of the License, or * 0016 * (at your option) any later version. * 0017 * * 0018 * This program is distributed in the hope that it will be useful, * 0019 * but WITHOUT ANY WARRANTY; without even the implied warranty of * 0020 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 0021 * GNU General Public License for more details. * 0022 * * 0023 * You should have received a copy of the GNU General Public License * 0024 * along with this program; if not, write to the Free Software * 0025 * Foundation, Inc., 51 Franklin Street, Fifth Floor, * 0026 * Boston, MA 02110-1301 USA * 0027 * * 0028 ***************************************************************************/ 0029 0030 #include "FileInfoDialog.h" 0031 #include "backend/datasources/LiveDataSource.h" 0032 #include "backend/datasources/filters/filters.h" 0033 0034 #include <QDialogButtonBox> 0035 #include <QDir> 0036 #include <QIcon> 0037 #include <QFileInfo> 0038 #include <QProcess> 0039 #include <QVBoxLayout> 0040 #include <QWindow> 0041 0042 #include <KLocalizedString> 0043 #include <KSharedConfig> 0044 #include <KWindowConfig> 0045 0046 /*! 0047 \class ImportWidget 0048 \brief Provides a dialog containing the information about the files to be imported. 0049 0050 \ingroup kdefrontend 0051 */ 0052 0053 FileInfoDialog::FileInfoDialog(QWidget* parent) : QDialog(parent) { 0054 m_textEditWidget.setReadOnly(true); 0055 m_textEditWidget.setLineWrapMode(QTextEdit::NoWrap); 0056 m_textEditWidget.setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff); 0057 m_textEditWidget.setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); 0058 0059 auto* layout = new QVBoxLayout(this); 0060 layout->addWidget(&m_textEditWidget); 0061 0062 auto* buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok); 0063 connect(buttonBox, &QDialogButtonBox::rejected, this, &FileInfoDialog::reject); 0064 connect(buttonBox, &QDialogButtonBox::accepted, this, &FileInfoDialog::accept); 0065 0066 layout->addWidget(buttonBox); 0067 0068 setWindowIcon(QIcon::fromTheme("help-about")); 0069 setWindowTitle(i18nc("@title:window", "File Information")); 0070 setAttribute(Qt::WA_DeleteOnClose); 0071 0072 setLayout(layout); 0073 0074 //restore saved settings if available 0075 create(); // ensure there's a window created 0076 KConfigGroup conf(KSharedConfig::openConfig(), "FileInfoDialog"); 0077 if (conf.exists()) { 0078 KWindowConfig::restoreWindowSize(windowHandle(), conf); 0079 resize(windowHandle()->size()); // workaround for QTBUG-40584 0080 } else 0081 resize(QSize(300, 200).expandedTo(minimumSize())); 0082 } 0083 0084 FileInfoDialog::~FileInfoDialog() { 0085 //save current settings 0086 KConfigGroup conf(KSharedConfig::openConfig(), "FileInfoDialog"); 0087 KWindowConfig::saveWindowSize(windowHandle(), conf); 0088 } 0089 0090 void FileInfoDialog::setFiles(QStringList& files) { 0091 QString infoString; 0092 0093 for (const auto& fileName : files) { 0094 if (fileName.isEmpty()) 0095 continue; 0096 0097 if (!infoString.isEmpty()) 0098 infoString += "<br><br><br>"; 0099 0100 infoString += fileInfoString(fileName); 0101 } 0102 0103 m_textEditWidget.document()->setHtml(infoString); 0104 0105 //resize to fit the content 0106 QSize size = m_textEditWidget.document()->size().toSize(); 0107 m_textEditWidget.setMinimumSize(size.width() + m_textEditWidget.contentsMargins().left() + m_textEditWidget.contentsMargins().right(), 0108 size.height() + m_textEditWidget.contentsMargins().top() + m_textEditWidget.contentsMargins().bottom()); 0109 } 0110 0111 /*! 0112 returns a string containing the general information about the file \c name 0113 and some content specific information 0114 (number of columns and lines for ASCII, color-depth for images etc.). 0115 */ 0116 QString FileInfoDialog::fileInfoString(const QString& name) const { 0117 QString infoString; 0118 QFileInfo fileInfo; 0119 QString fileTypeString; 0120 QIODevice *file = new QFile(name); 0121 0122 QString fileName{name}; 0123 #ifdef HAVE_WINDOWS 0124 if (name.at(1) != QLatin1Char(':')) 0125 #else 0126 if (name.at(0) != QLatin1String("/")) 0127 #endif 0128 fileName = QDir::homePath() + QLatin1String("/") + name; 0129 0130 if (!file) 0131 file = new QFile(fileName); 0132 0133 if (file->open(QIODevice::ReadOnly)) { 0134 QStringList infoStrings; 0135 0136 infoStrings << "<u><b>" + fileName + "</b></u><br>"; 0137 0138 // File type given by "file" 0139 #ifdef Q_OS_LINUX 0140 auto* proc = new QProcess(); 0141 QStringList args; 0142 args << "-b" << fileName; 0143 proc->start( "file", args); 0144 0145 if (proc->waitForReadyRead(1000) == false) 0146 infoStrings << i18n("Reading from file %1 failed.", fileName); 0147 else { 0148 fileTypeString = proc->readLine(); 0149 if (fileTypeString.contains(i18n("cannot open"))) 0150 fileTypeString.clear(); 0151 else { 0152 fileTypeString.remove(fileTypeString.length() - 1, 1); // remove '\n' 0153 } 0154 } 0155 infoStrings << i18n("<b>File type:</b> %1", fileTypeString); 0156 #endif 0157 0158 // General: 0159 fileInfo.setFile(fileName); 0160 infoStrings << "<b>" << i18n("General:") << "</b>"; 0161 0162 infoStrings << i18n("Readable: %1", fileInfo.isReadable() ? i18n("yes") : i18n("no")); 0163 infoStrings << i18n("Writable: %1", fileInfo.isWritable() ? i18n("yes") : i18n("no")); 0164 infoStrings << i18n("Executable: %1", fileInfo.isExecutable() ? i18n("yes") : i18n("no")); 0165 0166 #if (QT_VERSION >= QT_VERSION_CHECK(5, 10, 0)) 0167 infoStrings << i18n("Birth time: %1", fileInfo.birthTime().toString()); 0168 infoStrings << i18n("Last metadata changed: %1", fileInfo.metadataChangeTime().toString()); 0169 #else 0170 infoStrings << i18n("Created: %1", fileInfo.created().toString()); 0171 #endif 0172 infoStrings << i18n("Last modified: %1", fileInfo.lastModified().toString()); 0173 infoStrings << i18n("Last read: %1", fileInfo.lastRead().toString()); 0174 infoStrings << i18n("Owner: %1", fileInfo.owner()); 0175 infoStrings << i18n("Group: %1", fileInfo.group()); 0176 infoStrings << i18n("Size: %1", i18np("%1 cByte", "%1 cBytes", fileInfo.size())); 0177 0178 // Summary: 0179 infoStrings << "<b>" << i18n("Summary:") << "</b>"; 0180 //depending on the file type, generate summary and content information about the file 0181 //TODO: content information (in BNF) for more types 0182 switch (AbstractFileFilter::fileType(fileName)) { 0183 case AbstractFileFilter::FileType::Ascii: 0184 infoStrings << AsciiFilter::fileInfoString(fileName); 0185 break; 0186 case AbstractFileFilter::FileType::Binary: 0187 infoStrings << BinaryFilter::fileInfoString(fileName); 0188 break; 0189 case AbstractFileFilter::FileType::Image: 0190 infoStrings << ImageFilter::fileInfoString(fileName); 0191 break; 0192 case AbstractFileFilter::FileType::HDF5: 0193 infoStrings << HDF5Filter::fileInfoString(fileName); 0194 infoStrings << "<b>" << i18n("Content:") << "</b>"; 0195 infoStrings << HDF5Filter::fileDDLString(fileName); 0196 break; 0197 case AbstractFileFilter::FileType::NETCDF: 0198 infoStrings << NetCDFFilter::fileInfoString(fileName); 0199 infoStrings << "<b>" << i18n("Content:") << "</b>"; 0200 infoStrings << NetCDFFilter::fileCDLString(fileName); 0201 break; 0202 case AbstractFileFilter::FileType::FITS: 0203 infoStrings << FITSFilter::fileInfoString(fileName); 0204 break; 0205 case AbstractFileFilter::FileType::JSON: 0206 infoStrings << JsonFilter::fileInfoString(fileName); 0207 break; 0208 case AbstractFileFilter::FileType::ROOT: 0209 infoStrings << ROOTFilter::fileInfoString(fileName); 0210 break; 0211 case AbstractFileFilter::FileType::NgspiceRawAscii: 0212 case AbstractFileFilter::FileType::NgspiceRawBinary: 0213 infoStrings << NgspiceRawAsciiFilter::fileInfoString(fileName); 0214 break; 0215 } 0216 0217 0218 infoString += infoStrings.join("<br>"); 0219 0220 } else 0221 infoString += i18n("Could not open file %1 for reading.", fileName); 0222 0223 return infoString; 0224 }