00001
00002
00003
00004
00005
00006
00007 #include <QFile>
00008 #include <QFileInfo>
00009 #include <QString>
00010 #include <QStringList>
00011 #include <QTextCodec>
00012 #include <QCursor>
00013
00014 #include "pdbim.h"
00015 #include "gtwriter.h"
00016 #include "gtparagraphstyle.h"
00017 #include "scribusstructs.h"
00018 #include "scribuscore.h"
00019
00020
00024 static void _zero_fill( Byte *p, int len )
00025 {
00026 while ( len-- > 0 )
00027 *p++ = '\0';
00028 }
00029
00030 QString FileFormatName()
00031 {
00032 return QObject::tr("Palm PDB Documents", "PDB Importer");
00033 }
00034
00035 QStringList FileExtensions()
00036 {
00037 return QStringList("pdb");
00038 }
00039
00040 void GetText(QString filename, QString encoding, bool , gtWriter *writer)
00041 {
00042 if (filename.isNull())
00043 return;
00044 qApp->setOverrideCursor(QCursor(Qt::WaitCursor));
00045 ScCore->primaryMainWindow()->mainWindowProgressBar->reset();
00046 PdbIm *im = new PdbIm(filename, encoding, writer);
00047 im->write();
00048 delete im;
00049 ScCore->primaryMainWindow()->mainWindowProgressBar->reset();
00050 qApp->restoreOverrideCursor();
00051 }
00052
00053
00054 PdbIm::PdbIm(const QString& fname, const QString& enc, gtWriter *w)
00055 {
00056 m_buf = new buffer;
00057 _zero_fill(m_buf->buf, BUFFER_SIZE);
00058 m_buf->len = BUFFER_SIZE;
00059 m_buf->position = 0;
00060 writer = w;
00061 encoding = enc;
00062 selectSwap();
00063 loadFile(fname);
00064 }
00065
00066 void PdbIm::write()
00067 {
00068 QTextCodec *codec;
00069 if (encoding.isEmpty())
00070 codec = QTextCodec::codecForLocale();
00071 else
00072 codec = QTextCodec::codecForName(encoding.toLocal8Bit());
00073 data = codec->toUnicode(data.toLocal8Bit());
00074 gtParagraphStyle *pstyle = new gtParagraphStyle(*(writer->getDefaultStyle()));
00075 pstyle->setName(writer->getFrameName() + "-" + QObject::tr("PDB_data", "PDB Importer"));
00076 writer->append(data, pstyle);
00077 delete pstyle;
00078 }
00079
00080 void PdbIm::loadFile(QString fname)
00081 {
00082 FILE *m_pdfp = fopen(fname.toLocal8Bit(), "rb");
00083 pdb_header m_header;
00084 DWord file_size, offset;
00085 doc_record0 m_rec0;
00086
00087 if (!m_pdfp)
00088 {
00089 QMessageBox::warning(ScCore->primaryMainWindow(), QObject::tr("PDB Import", "PDB Importer"),
00090 "<qt>" + QObject::tr("Could not open file %1", "PDB Importer").arg(fname) + "</qt>",
00091 QMessageBox::Ok, QMessageBox::NoButton);
00092 return;
00093 }
00094 fread( &m_header, PDB_HEADER_SIZE, 1, m_pdfp );
00095 if (strncmp(m_header.type, DOC_TYPE, sizeof(m_header.type) ) ||
00096 strncmp( m_header.creator, DOC_CREATOR, sizeof(m_header.creator)))
00097 {
00098 QMessageBox::warning(ScCore->primaryMainWindow(), QObject::tr("PDB Import", "PDB Importer"),
00099 "<qt>" + QObject::tr("This file is not recognized as a PDB document. Please, report this as a bug if you are sure it is one.", "PDB Importer") + "</qt>",
00100 QMessageBox::Ok, QMessageBox::NoButton);
00101 return;
00102 }
00103
00104
00105 int num_records = swap_Word( m_header.numRecords ) - 1;
00106 ScCore->primaryMainWindow()->mainWindowProgressBar->setMaximum(num_records);
00107 fseek(m_pdfp, PDB_HEADER_SIZE, SEEK_SET);
00108 GET_DWord(m_pdfp, offset);
00109 fseek(m_pdfp, offset, SEEK_SET);
00110 fread(&m_rec0, sizeof(m_rec0), 1, m_pdfp);
00111
00112 if (swap_Word( m_rec0.version ) == 2 )
00113 bCompressed = true;
00114
00115 fseek( m_pdfp, 0, SEEK_END );
00116 file_size = ftell( m_pdfp );
00117 for (int rec_num = 1; rec_num <= num_records; ++rec_num )
00118 {
00119 DWord next_offset;
00120
00121 ScCore->primaryMainWindow()->mainWindowProgressBar->setValue(rec_num);
00122 fseek( m_pdfp, PDB_HEADER_SIZE + PDB_RECORD_HEADER_SIZE * rec_num, SEEK_SET);
00123 GET_DWord( m_pdfp, offset );
00124 if( rec_num < num_records )
00125 {
00126 fseek( m_pdfp, PDB_HEADER_SIZE + PDB_RECORD_HEADER_SIZE * (rec_num + 1), SEEK_SET);
00127 GET_DWord( m_pdfp, next_offset );
00128 }
00129 else
00130 next_offset = file_size;
00131 fseek( m_pdfp, offset, SEEK_SET );
00132
00133 _zero_fill (m_buf->buf, BUFFER_SIZE);
00134 m_buf->position = fread( m_buf->buf, 1, next_offset - offset, m_pdfp );
00135
00136 if ( bCompressed )
00137 uncompress( m_buf );
00138
00139 m_buf->position = 0;
00140 while ( (m_buf->position) < (m_buf->len) )
00141 {
00142 if (m_buf->buf[m_buf->position] == '\0')
00143 {
00144 ++m_buf->position;
00145 continue;
00146 }
00147 data += m_buf->buf[m_buf->position];
00148 ++m_buf->position;
00149 }
00150 }
00151 }
00152
00153 void PdbIm::selectSwap()
00154 {
00155 union { char c[2]; Word n; } w;
00156 strncpy( w.c, "\1\2", 2 );
00157
00158 if ( w.n == 0x0201 )
00159 m_littlendian = true;
00160 else
00161 m_littlendian = false;
00162
00163 }
00164
00165 Word PdbIm::swap_Word( Word r )
00166 {
00167 if (m_littlendian)
00168 return (r >> 8) | (r << 8);
00169 else
00170 return r;
00171 }
00172
00173 DWord PdbIm::swap_DWord( DWord r )
00174 {
00175 if (m_littlendian)
00176 return ( (r >> 24) & 0x00FF ) | (r << 24) | ( (r >> 8) & 0xFF00 ) | ( (r << 8) & 0xFF0000 );
00177 else
00178 return r;
00179 }
00180
00181 void PdbIm::uncompress( buffer *m_buf )
00182 {
00183 buffer *m_new_buf = new buffer;
00184 UT_uint16 i, j;
00185 Byte c;
00186
00187 _zero_fill (m_new_buf->buf, BUFFER_SIZE);
00188
00189 for (i = j = 0; i < m_buf->position && j < BUFFER_SIZE; )
00190 {
00191 c = m_buf->buf[ i++ ];
00192
00193 if ( c >= 1 && c <= 8 )
00194 while ( c-- && j < BUFFER_SIZE-1)
00195 m_new_buf->buf[ j++ ] = m_buf->buf[ i++ ];
00196
00197 else if ( c <= 0x7F )
00198 m_new_buf->buf[ j++ ] = c;
00199
00200 else if ( c >= 0xC0 && j < BUFFER_SIZE-2)
00201 {
00202 m_new_buf->buf[ j++ ] = ' ';
00203 m_new_buf->buf[ j++ ] = c ^ 0x80;
00204 }
00205 else
00206 {
00207 int di, n;
00208 unsigned int temp_c = c;
00209
00210 temp_c = (temp_c << 8) ;
00211 temp_c = temp_c + m_buf->buf[ i++ ];
00212 di = (temp_c & 0x3FFF) >> COUNT_BITS;
00213 for (n = (temp_c & ((1 << COUNT_BITS) - 1)) + 3; n-- && j < BUFFER_SIZE; ++j )
00214 m_new_buf->buf[ j ] = m_new_buf->buf[ j - di ];
00215 temp_c = 0;
00216 }
00217 }
00218
00219
00220 memcpy( static_cast<void *>(m_buf->buf), static_cast<void *>(m_new_buf->buf), static_cast<size_t>(j) );
00221
00222 m_buf->position = j;
00223 delete( m_new_buf );
00224 }