bool KGVDocument::savePages( const QString& saveFileName, const PageList& pageList ) { if( pageList.empty() ) return true; if( _format == PDF ) { KTempFile psSaveFile( QString::null, ".ps" ); psSaveFile.setAutoDelete( true ); if( psSaveFile.status() != 0 ) return false; // Find the minimum and maximum pagenumber in pageList. int minPage = pageList.first(), maxPage = pageList.first(); for( PageList::const_iterator ci = pageList.begin(); ci != pageList.end(); ++ci ) { minPage = QMIN( *ci, minPage ); maxPage = QMAX( *ci, maxPage ); } // TODO: Optimize "print whole document" case // // The convertion below from PDF to PS creates a temporary file which, in // the case where we are printing the whole document will then be // completelly copied to another temporary file. // // In very large files, the inefficiency is visible (measured in // seconds). // // luis_pedro 4 Jun 2003 // Convert the pages in the range [minPage,maxPage] from PDF to // PostScript. if( !convertFromPDF( psSaveFile.name(), minPage, maxPage ) ) return false; // The page minPage in the original file becomes page 1 in the // converted file. We still have to select the desired pages from // this file, so we need to take into account that difference. PageList normedPageList; transform( pageList.begin(), pageList.end(), back_inserter( normedPageList ), bind2nd( minus<int>(), minPage - 1 ) ); // Finally select the desired pages from the converted file. psCopyDoc( psSaveFile.name(), saveFileName, normedPageList ); } else { psCopyDoc( _fileName, saveFileName, pageList ); } return true; }
QString KGVDocument::pageListToRange( const PageList& pageList ) { QString range; // Iterators marking the begin and end of a successive sequence // of pages. PageList::const_iterator bss( pageList.begin() ); PageList::const_iterator ess; PageList::const_iterator it ( pageList.begin() ); while( it != pageList.end() ) { ess = it++; // If ess points to the end of a successive sequence of pages, // add the stringrepresentation of the sequence to range and // update bss. if( it == pageList.end() || *it != (*ess) + 1 ) { if( !range.isEmpty() ) range += ","; if( bss == ess ) range += QString::number( *ess ); else range += QString( "%1-%2" ).arg( *bss ).arg( *ess ); bss = it; } } return range; }
bool KGVDocument::psCopyDoc( const QString& inputFile, const QString& outputFile, const PageList& pageList ) { FILE* from; FILE* to; char text[ PSLINELENGTH ]; char* comment; bool pages_written = false; bool pages_atend = false; unsigned int i = 0; unsigned int pages = 0; long here; kdDebug(4500) << "KGVDocument: Copying pages from " << inputFile << " to " << outputFile << endl; pages = pageList.size(); if( pages == 0 ) { KMessageBox::sorry( 0, i18n( "Printing failed because the list of " "pages to be printed was empty." ), i18n( "Error Printing" ) ); return false; } from = fopen( QFile::encodeName( inputFile ), "r" ); to = fopen( QFile::encodeName( outputFile ), "w" ); // Hack in order to make printing of PDF files work. FIXME CDSC* dsc; if( _format == PS ) dsc = _dsc->cdsc(); else { FILE* fp = fopen( QFile::encodeName( inputFile ), "r"); char buf[256]; int count; dsc = dsc_init( 0 ); while( ( count = fread( buf, 1, sizeof( buf ), fp ) ) != 0 ) dsc_scan_data( dsc, buf, count ); fclose( fp ); if( !dsc ) return false; dsc_fixup( dsc ); } here = dsc->begincomments; while( ( comment = pscopyuntil( from, to, here, dsc->endcomments, "%%Pages:" ) ) ) { here = ftell( from ); if( pages_written || pages_atend ) { free( comment ); continue; } sscanf( comment + length("%%Pages:" ), "%256s", text ); text[256] = 0; // Just in case of an overflow if( strcmp( text, "(atend)" ) == 0 ) { fputs( comment, to ); pages_atend = true; } else { switch ( sscanf( comment + length( "%%Pages:" ), "%*d %u", &i ) ) { case 1: fprintf( to, "%%%%Pages: %d %d\n", pages, i ); break; default: fprintf( to, "%%%%Pages: %d\n", pages ); break; } pages_written = true; } free(comment); } pscopy( from, to, dsc->beginpreview, dsc->endpreview ); pscopy( from, to, dsc->begindefaults, dsc->enddefaults ); pscopy( from, to, dsc->beginprolog, dsc->endprolog ); pscopy( from, to, dsc->beginsetup, dsc->endsetup ); //TODO -- Check that a all dsc attributes are copied unsigned int count = 1; PageList::const_iterator it; for( it = pageList.begin(); it != pageList.end(); ++it ) { i = (*it) - 1; comment = pscopyuntil( from, to, dsc->page[i].begin, dsc->page[i].end, "%%Page:" ); if ( comment ) free( comment ); fprintf( to, "%%%%Page: %s %d\n", dsc->page[i].label, count++ ); pscopy( from, to, -1, dsc->page[i].end ); } here = dsc->begintrailer; while( ( comment = pscopyuntil( from, to, here, dsc->endtrailer, "%%Pages:" ) ) ) { here = ftell( from ); if ( pages_written ) { free( comment ); continue; } switch ( sscanf( comment + length( "%%Pages:" ), "%*d %u", &i ) ) { case 1: fprintf( to, "%%%%Pages: %d %d\n", pages, i ); break; default: fprintf( to, "%%%%Pages: %d\n", pages ); break; } pages_written = true; free( comment ); } fclose( from ); fclose( to ); if( _format == PDF ) dsc_free( dsc ); return true; }