File indexing completed on 2024-05-12 16:35:17

0001 /* This file is part of the KDE project
0002    Copyright (C) 2002-2003 Norbert Andres <nandres@web.de>
0003              (C) 2002-2003 Ariya Hidayat <ariya@kde.org>
0004              (C) 2002      Laurent Montel <montel@kde.org>
0005              (C) 1999 David Faure <faure@kde.org>
0006 
0007    This library is free software; you can redistribute it and/or
0008    modify it under the terms of the GNU Library General Public
0009    License as published by the Free Software Foundation; either
0010    version 2 of the License, or (at your option) any later version.
0011 
0012    This library is distributed in the hope that it will be useful,
0013    but WITHOUT ANY WARRANTY; without even the implied warranty of
0014    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
0015    Library General Public License for more details.
0016 
0017    You should have received a copy of the GNU Library General Public License
0018    along with this library; see the file COPYING.LIB.  If not, write to
0019    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
0020    Boston, MA 02110-1301, USA.
0021 */
0022 
0023 // Local
0024 #include "CSVDialog.h"
0025 
0026 #include <KoFileDialog.h>
0027 
0028 #include <QApplication>
0029 #include <QByteArray>
0030 #include <QMimeData>
0031 #include <QString>
0032 #include <QTimer>
0033 
0034 
0035 #include <KoCanvasBase.h>
0036 
0037 #include <KLocalizedString>
0038 #include <kmessagebox.h>
0039 
0040 #include "Cell.h"
0041 #include "CellStorage.h"
0042 #include "Damages.h"
0043 #include "Map.h"
0044 #include "ui/Selection.h"
0045 #include "Sheet.h"
0046 
0047 #include "commands/CSVDataCommand.h"
0048 
0049 using namespace Calligra::Sheets;
0050 
0051 CSVDialog::CSVDialog(QWidget* parent, Selection* selection, Mode mode)
0052         : KoCsvImportDialog(parent),
0053         m_selection(selection),
0054         m_canceled(false),
0055         m_mode(mode)
0056 {
0057     // Limit the range
0058     int column = m_selection->lastRange().left();
0059     Cell lastCell = m_selection->activeSheet()->cellStorage()->lastInColumn(column);
0060     if (!lastCell.isNull())
0061         if (m_selection->lastRange().bottom() > lastCell.row())
0062             m_selection->lastRange().setBottom(lastCell.row());
0063 
0064     if (m_mode == Clipboard) {
0065         setWindowTitle(i18n("Inserting From Clipboard"));
0066         const QMimeData* mime = QApplication::clipboard()->mimeData();
0067         if (!mime) {
0068             KMessageBox::information(this, i18n("There is no data in the clipboard."));
0069             m_canceled = true;
0070         }
0071         if (!mime->hasText()) {
0072             KMessageBox::information(this, i18n("There is no usable data in the clipboard."));
0073             m_canceled = true;
0074         }
0075     } else if (m_mode == File) {
0076         //setWindowTitle(i18n("Inserting Text File"));
0077         KoFileDialog dialog(parent, KoFileDialog::ImportFile, "OpenDocument");
0078         dialog.setCaption(i18n("Import CSV Data File"));
0079         dialog.setNameFilter(i18n("CSV data files (*.csv)"));
0080         m_filename = dialog.filename();
0081         //cancel action !
0082         if (m_filename.isEmpty()) {
0083             enableButton(Ok, false);
0084             m_canceled = true;
0085         }
0086     } else { // if ( m_mode == Column )
0087         setWindowTitle(i18n("Text to Columns"));
0088         setDataWidgetEnabled(false);
0089     }
0090 
0091     if (! m_canceled)
0092         QTimer::singleShot(0, this, SLOT(init()));
0093 }
0094 
0095 CSVDialog::~CSVDialog()
0096 {
0097     // no need to delete child widgets, Qt does it all for us
0098 }
0099 
0100 void CSVDialog::init()
0101 {
0102     if (m_canceled)
0103         return;
0104 
0105     if (m_mode == Clipboard) {
0106         const QMimeData* mime = QApplication::clipboard()->mimeData();
0107         Q_ASSERT(mime);
0108         Q_ASSERT(mime->hasText());
0109         setData(QByteArray(mime->text().toUtf8()));
0110     } else if (m_mode == File) {
0111         Q_ASSERT(! m_filename.isEmpty());
0112         QFile in(m_filename);
0113         if (!in.open(QIODevice::ReadOnly)) {
0114             KMessageBox::sorry(this, i18n("Cannot open input file."));
0115             in.close();
0116             enableButton(Ok, false);
0117             m_canceled = true;
0118             return;
0119         }
0120         setData(in.readAll());
0121         in.close();
0122     } else { // if ( m_mode == Column )
0123         setData(QByteArray());
0124         Cell cell;
0125         Sheet * sheet = m_selection->activeSheet();
0126         QByteArray data;
0127         int col = m_selection->lastRange().left();
0128         for (int i = m_selection->lastRange().top(); i <= m_selection->lastRange().bottom(); ++i) {
0129             cell = Cell(sheet, col, i);
0130             if (!cell.isEmpty()) {
0131                 data.append(cell.displayText().toUtf8() /* FIXME */);
0132             }
0133             data.append('\n');
0134         }
0135         setData(data);
0136     }
0137 }
0138 
0139 bool CSVDialog::canceled()
0140 {
0141     return m_canceled;
0142 }
0143 
0144 void CSVDialog::accept()
0145 {
0146     Sheet * sheet  = m_selection->activeSheet();
0147 
0148     int numRows = rows();
0149     int numCols = cols();
0150 
0151     if ((numRows == 0) || (numCols == 0))
0152         return;  // nothing to do here
0153 
0154     QRect range = m_selection->lastRange();
0155     if ((numCols > range.width()) && (range.width() > 1)) {
0156         numCols = range.width();
0157     } else
0158         range.setRight(range.left() + numCols - 1);
0159 
0160     if ((numRows > range.height()) && (range.height() > 1))
0161         numRows = range.height();
0162     else
0163         range.setBottom(range.top() + numRows - 1);
0164 
0165     QList<KoCsvImportDialog::DataType> dataTypes;
0166     Value value(Value::Array);
0167     for (int row = 0; row < numRows; ++row) {
0168         for (int col = 0; col < numCols; ++col) {
0169             value.setElement(col, row, Value(text(row, col)));
0170             if (row == 0)
0171                 dataTypes.insert(col, dataType(col));
0172         }
0173     }
0174 
0175     CSVDataCommand* command = new CSVDataCommand();
0176     if (m_mode == Clipboard)
0177         command->setText(kundo2_i18n("Inserting From Clipboard"));
0178     else if (m_mode == File)
0179         command->setText(kundo2_i18n("Inserting Text File"));
0180     else
0181         command->setText(kundo2_i18n("Text to Columns"));
0182     command->setSheet(sheet);
0183     command->setValue(value);
0184     command->setColumnDataTypes(dataTypes);
0185     command->setDecimalSymbol(decimalSymbol());
0186     command->setThousandsSeparator(thousandsSeparator());
0187 
0188     const QMimeData* mimedata = QApplication::clipboard()->mimeData();
0189     if (m_mode == Clipboard &&
0190         !mimedata->hasFormat("application/x-kspread-snippet") &&
0191         !mimedata->hasHtml() && mimedata->hasText() &&
0192         mimedata->text().split('\n').count() >= 2 )
0193     {
0194         range.setSize(QSize(numCols, numRows));
0195     }
0196     command->add(range);
0197     if (!command->execute(m_selection->canvas()))
0198         delete command;
0199 
0200     m_selection->initialize(range, sheet);
0201     m_selection->emitModified();
0202     KoCsvImportDialog::accept();
0203 }
0204