Rev 5093 |
Blame |
Compare with Previous |
Last modification |
View Log
| RSS feed
/*
For general Scribus (>=1.3.2) copyright and licensing information please refer
to the COPYING file provided with the program. Following this notice may exist
a copyright and/or license notice that predates the release of Scribus 1.3.2
for which a new license (GPL+exception) is in place.
*/
#include <qfiledialog.h>
#include <qcstring.h>
#include <qfile.h>
#include <qfileinfo.h>
#include <qstring.h>
#include <qstringlist.h>
#include <qtextcodec.h>
#include <qcursor.h>
#include "pdbim.h"
#include "gtwriter.h"
#include "gtparagraphstyle.h"
#include "scribusstructs.h"
#include "scribus.h"
/*! \brief A dummy 0 filler (helper procedure)
\param p binary structure to fill with 0
\param len how much 0 to go */
static void _zero_fill( Byte *p, int len )
{
while ( len-- > 0 )
*p++ = '\0';
}
QString FileFormatName()
{
return QObject::tr("Palm PDB Documents", "PDB Importer");
}
QStringList FileExtensions()
{
return QStringList("pdb");
}
void GetText(QString filename, QString encoding, bool /* textOnly */, gtWriter *writer)
{
if (filename.isNull())
return;
qApp->setOverrideCursor(QCursor(Qt::WaitCursor), true);
ScMW->mainWindowProgressBar->reset();
PdbIm *im = new PdbIm(filename, encoding, writer);
im->write();
delete im;
ScMW->mainWindowProgressBar->reset();
qApp->restoreOverrideCursor();
}
PdbIm::PdbIm(const QString& fname, const QString& enc, gtWriter *w)
{
m_buf = new buffer;
_zero_fill(m_buf->buf, BUFFER_SIZE);
m_buf->len = BUFFER_SIZE;
m_buf->position = 0;
writer = w;
encoding = enc;
selectSwap();
loadFile(fname);
}
void PdbIm::write()
{
QTextCodec *codec;
if (encoding.isEmpty())
codec = QTextCodec::codecForLocale();
else
codec = QTextCodec::codecForName(encoding);
data = codec->toUnicode(data);
gtParagraphStyle *pstyle = new gtParagraphStyle(*(writer->getDefaultStyle()));
pstyle->setName(writer->getFrameName() + "-" + QObject::tr("PDB_data", "PDB Importer"));
writer->append(data, pstyle);
delete pstyle;
}
void PdbIm::loadFile(QString fname)
{
FILE *m_pdfp = fopen(fname, "rb");
pdb_header m_header;
DWord file_size, offset;
doc_record0 m_rec0;
if (!m_pdfp)
{
QMessageBox::warning(ScMW, QObject::tr("PDB Import", "PDB Importer"),
"<qt>" + QObject::tr("Could not open file %1", "PDB Importer").arg(fname) + "</qt>",
0);
return;
}
fread( &m_header, PDB_HEADER_SIZE, 1, m_pdfp );
if (strncmp(m_header.type, DOC_TYPE, sizeof(m_header.type) ) ||
strncmp( m_header.creator, DOC_CREATOR, sizeof(m_header.creator)))
{
QMessageBox::warning(ScMW, QObject::tr("PDB Import", "PDB Importer"),
"<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>",
0);
return;
}
// progressbar
int num_records = swap_Word( m_header.numRecords ) - 1;
ScMW->mainWindowProgressBar->setTotalSteps(num_records);
fseek(m_pdfp, PDB_HEADER_SIZE, SEEK_SET);
GET_DWord(m_pdfp, offset);
fseek(m_pdfp, offset, SEEK_SET);
fread(&m_rec0, sizeof(m_rec0), 1, m_pdfp);
if (swap_Word( m_rec0.version ) == 2 )
bCompressed = true;
fseek( m_pdfp, 0, SEEK_END );
file_size = ftell( m_pdfp );
for (int rec_num = 1; rec_num <= num_records; ++rec_num )
{
DWord next_offset;
ScMW->mainWindowProgressBar->setProgress(rec_num);
fseek( m_pdfp, PDB_HEADER_SIZE + PDB_RECORD_HEADER_SIZE * rec_num, SEEK_SET);
GET_DWord( m_pdfp, offset );
if( rec_num < num_records )
{
fseek( m_pdfp, PDB_HEADER_SIZE + PDB_RECORD_HEADER_SIZE * (rec_num + 1), SEEK_SET);
GET_DWord( m_pdfp, next_offset );
}
else
next_offset = file_size;
fseek( m_pdfp, offset, SEEK_SET );
// be overly cautious here
_zero_fill (m_buf->buf, BUFFER_SIZE);
m_buf->position = fread( m_buf->buf, 1, next_offset - offset, m_pdfp );
if ( bCompressed )
uncompress( m_buf );
m_buf->position = 0;
while ( (m_buf->position) < (m_buf->len) )
{
if (m_buf->buf[m_buf->position] == '\0')
{
++m_buf->position;
continue;
}
data += m_buf->buf[m_buf->position];
++m_buf->position;
}
}
}
void PdbIm::selectSwap()
{
union { char c[2]; Word n; } w;
strncpy( w.c, "\1\2", 2 );
if ( w.n == 0x0201 )
m_littlendian = true;
else
m_littlendian = false;
}
Word PdbIm::swap_Word( Word r )
{
if (m_littlendian)
return (r >> 8) | (r << 8);
else
return r;
}
DWord PdbIm::swap_DWord( DWord r )
{
if (m_littlendian)
return ( (r >> 24) & 0x00FF ) | (r << 24) | ( (r >> 8) & 0xFF00 ) | ( (r << 8) & 0xFF0000 );
else
return r;
}
void PdbIm::uncompress( buffer *m_buf )
{
buffer *m_new_buf = new buffer;
UT_uint16 i, j;
Byte c;
_zero_fill (m_new_buf->buf, BUFFER_SIZE);
for (i = j = 0; i < m_buf->position && j < BUFFER_SIZE; )
{
c = m_buf->buf[ i++ ];
if ( c >= 1 && c <= 8 )
while ( c-- && j < BUFFER_SIZE-1)
m_new_buf->buf[ j++ ] = m_buf->buf[ i++ ];
else if ( c <= 0x7F )
m_new_buf->buf[ j++ ] = c;
else if ( c >= 0xC0 && j < BUFFER_SIZE-2)
{
m_new_buf->buf[ j++ ] = ' ';
m_new_buf->buf[ j++ ] = c ^ 0x80;
}
else
{
int di, n;
unsigned int temp_c = c;
// c--> temp_c //tomy 2001.11.13
temp_c = (temp_c << 8) ;
temp_c = temp_c + m_buf->buf[ i++ ];
di = (temp_c & 0x3FFF) >> COUNT_BITS;
for (n = (temp_c & ((1 << COUNT_BITS) - 1)) + 3; n-- && j < BUFFER_SIZE; ++j )
m_new_buf->buf[ j ] = m_new_buf->buf[ j - di ];
temp_c = 0;
}
}
//UT_ASSERT(j <= BUFFER_SIZE);
memcpy( static_cast<void *>(m_buf->buf), static_cast<void *>(m_new_buf->buf), static_cast<size_t>(j) );
m_buf->position = j;
delete( m_new_buf );
}