Back to index

scribus-ng  1.3.4.dfsg+svn20071115
csvim.cpp
Go to the documentation of this file.
00001 /*
00002 For general Scribus (>=1.3.2) copyright and licensing information please refer
00003 to the COPYING file provided with the program. Following this notice may exist
00004 a copyright and/or license notice that predates the release of Scribus 1.3.2
00005 for which a new license (GPL+exception) is in place.
00006 */
00007 #include "csvim.h"
00008 #include "scribusstructs.h"
00009 
00010 QString FileFormatName()
00011 {
00012     return QObject::tr("Comma Separated Value Files");
00013 }
00014 
00015 QStringList FileExtensions()
00016 {
00017     return QStringList("csv");
00018 }
00019 
00020 void GetText(QString filename, QString encoding, bool /* textOnly */, gtWriter *writer)
00021 {
00022        CsvDialog* csvdia = new CsvDialog();
00023        if (csvdia->exec())
00024        {
00025               CsvIm *cim = new CsvIm(filename, encoding, writer, csvdia->getFDelim(), csvdia->getVDelim(),
00026                                csvdia->hasHeader(), csvdia->useVDelim());
00027               cim->write();
00028               delete cim;
00029        }
00030        delete csvdia;
00031 }
00032 
00033 /******* Class CsvIm **************************************************************/
00034 
00035 CsvIm::CsvIm(const QString& fname, const QString& enc, gtWriter *w, 
00036              const QString& fdelim, const QString& vdelim, bool header, bool usevdelim)
00037 {
00038        fieldDelimiter = fdelim;
00039        valueDelimiter = vdelim;
00040        hasHeader = header;
00041        useVDelim = usevdelim;
00042        filename = fname;
00043        encoding = enc;
00044        writer = w;
00045        header = "";
00046        data = "";
00047        rowNumber = 0;
00048        colIndex = 0;
00049        colCount = 0;
00050        setupPStyles();
00051        loadFile();
00052        setupTabulators();
00053 }
00054 
00055 void CsvIm::setupPStyles()
00056 {
00057        pstyleData = new gtParagraphStyle(*(writer->getDefaultStyle()));
00058        pstyleData->setName(writer->getFrameName() + "-" + QObject::tr("CSV_data"));
00059        if (hasHeader)
00060        {
00061               pstyleHeader = new gtParagraphStyle(*pstyleData);
00062               pstyleHeader->setName(writer->getFrameName() + "-" + QObject::tr("CSV_header"));
00063               pstyleHeader->setSpaceBelow(7.0);
00064               int size = pstyleData->getFont()->getSize();
00065               size += 10;
00066               pstyleHeader->getFont()->setSize(size);
00067               pstyleHeader->getFont()->setWeight(BOLD);
00068        }
00069        else
00070               pstyleHeader = NULL;
00071 }
00072 
00073 void CsvIm::setFieldDelimiter(const QString& fdelim)
00074 {
00075        fieldDelimiter = fdelim;
00076 }
00077 
00078 void CsvIm::setValueDelimiter(const QString& vdelim)
00079 {
00080        valueDelimiter = vdelim;
00081 }
00082 
00083 void CsvIm::write()
00084 {
00085        writer->append(header, pstyleHeader);
00086        writer->append(data, pstyleData);
00087 }
00088 
00089 void CsvIm::loadFile()
00090 {
00091        QString text = "";
00092        QFile f(filename);
00093        QFileInfo fi(f);
00094        if (!fi.exists())
00095               return;
00096        uint posi;
00097        QByteArray bb(f.size());
00098        if (f.open(IO_ReadOnly))
00099        {
00100               f.readBlock(bb.data(), f.size());
00101               f.close();
00102               for (posi = 0; posi < bb.size(); ++posi)
00103                      text += QChar(bb[posi]);
00104        }
00105        text = toUnicode(text);
00106        QStringList lines = QStringList::split("\n", text);
00107        uint i;
00108        if (hasHeader)
00109        {
00110               colIndex = 0;
00111               parseLine(lines[0], true);
00112               header += "\n";
00113               colCount = colIndex;
00114               i = 1;
00115               ++rowNumber;
00116        }
00117        else
00118               i = 0;
00119        for (uint i2 = i; i2 < lines.size(); ++i2)
00120        {
00121               colIndex = 0;
00122               parseLine(lines[i2], false);
00123               data += "\n";
00124               ++rowNumber;
00125               if (colCount < colIndex)
00126                      colCount = colIndex;
00127        }
00128 }
00129 
00130 void CsvIm::parseLine(const QString& line, bool isHeader)
00131 {
00132        if ((line.find(valueDelimiter) < 0) || (!useVDelim))
00133        {
00134               QStringList l = QStringList::split(fieldDelimiter, line);
00135               for (uint i = 0; i < l.size(); ++i)
00136               {
00137                      ++colIndex;
00138                      QString tmp = l[i].stripWhiteSpace();
00139                      if (isHeader)
00140                             header += "\t" + tmp;
00141                      else
00142                             data += "\t" + tmp;
00143               }
00144               return; // line done
00145        }
00146        
00147        int vdIndexStart = line.find(valueDelimiter);
00148        int vdIndexEnd   = line.find(valueDelimiter, vdIndexStart + 1);
00149        if (vdIndexEnd < 0)
00150        {
00151               if (isHeader)
00152                      header += "\t" + line;
00153               else
00154                      data += "\t" + line;
00155               return; // error in line, no closing valuedelimiter could be found    
00156        }
00157        
00158        int fdIndex = line.find(fieldDelimiter, vdIndexEnd + 1);
00159        QString tmpCol = "";
00160        
00161        if (fdIndex < 0)
00162        {
00163               if (vdIndexEnd < 0)
00164               {
00165                      if (isHeader)
00166                             header += "\t" + line;
00167                      else
00168                             data += "\t" + line;
00169               }
00170               else 
00171               {
00172                      tmpCol = line.mid(vdIndexStart + 1, (vdIndexEnd - 1) - vdIndexStart);
00173                      if (isHeader)
00174                             header += "\t" + tmpCol;
00175                      else
00176                             data += "\t" + tmpCol;
00177               }
00178               ++colIndex;
00179               return; // no more field delimiters left
00180        }
00181        
00182        if (fdIndex < vdIndexStart)
00183        {
00184               tmpCol = line.mid(0, fdIndex);
00185               if (isHeader)
00186                      header += "\t" + tmpCol;
00187               else
00188                      data += "\t" + tmpCol;
00189               ++colIndex;
00190               parseLine(line.mid(fdIndex + 1, line.length() - (fdIndex + 1)), isHeader);
00191        }
00192        else if (fdIndex > vdIndexEnd)
00193        {
00194               tmpCol = line.mid(vdIndexStart + 1, (vdIndexEnd - 1) - vdIndexStart);
00195               if (isHeader)
00196                      header += "\t" + tmpCol;
00197               else
00198                      data += "\t" + tmpCol;
00199               ++colIndex;
00200               parseLine(line.mid(vdIndexEnd + 1, line.length() - (vdIndexEnd + 1)), isHeader);
00201        }
00202 }
00203 
00204 
00205 void CsvIm::setupTabulators()
00206 {
00207        double frameWidth = writer->getFrameWidth();
00208        double addition = frameWidth / (colCount + 1);
00209        double curValue = addition / 2;
00210        for (int i = 0; i < colCount; ++i)
00211        {
00212               pstyleData->setTabValue(curValue);
00213               if (pstyleHeader)
00214                      pstyleHeader->setTabValue(curValue, CENTER_T);
00215               curValue += addition;
00216        }
00217 }
00218 
00219 QString CsvIm::toUnicode(const QString& text)
00220 {
00221        QTextCodec *codec;
00222        if (encoding.isEmpty())
00223               codec = QTextCodec::codecForLocale();
00224        else
00225               codec = QTextCodec::codecForName(encoding);
00226        QString dec = codec->toUnicode(text);
00227        return dec;
00228 }
00229 
00230 CsvIm::~CsvIm()
00231 {
00232        delete pstyleData;
00233        delete pstyleHeader;
00234 }