📄 qgscomposer.cpp
字号:
// TODO: Qt does not add pagesize to output file, it can cause problems if ps2pdf is used // or if default page on printer is different. // We should add somewhere in output file: // << /PageSize [ %d %d ] >> setpagedevice // %d %d is width and height in points // WARNING: If QCanvasView recieves repaint signal during the printing // (e.g. covered by QPrinter::setup dialog) it breaks somehow drawing of QCanvas items // (for example not all features in the map are drawn. // I don't know how to stop temporarily updating, (I don't want to reimplement // repaint in QCanvasView, so I unset the view, print and reset. mView->setScene(0); int resolution = mPrinter->resolution(); std::cout << "Resolution = " << resolution << std::endl; double scale = resolution / 25.4 / mComposition->scale(); mComposition->setPlotStyle(QgsComposition::Postscript); if (!mPrinter->outputFileName().isNull()) { try { std::cout << "Print to file" << std::endl; QPrinter::PageSize psize=QPrinter::A4; //sensible default // WARNING mPrinter->outputFormat() returns always 0 in Qt 4.2.2 // => we have to check extension bool isPs = false; if (mPrinter->outputFileName().right(3).toLower() == ".ps" || mPrinter->outputFileName().right(4).toLower() == ".eps") { isPs = true; } //if ( mPrinter->outputFormat() == QPrinter::PostScriptFormat ) if (isPs) { // NOTE: setPageSize after setup() works, but setOrientation does not // -> the BoundingBox must follow the orientation psize = mPrinter->pageSize(); // B0 ( 1000x1414mm = 2835x4008pt ) is the biggest defined in Qt, a map can be bigger // but probably not bigger than 9999x9999pt = 3527x3527mm mPrinter->setPageSize(QPrinter::B0); } QPainter p(mPrinter); p.scale(scale, scale); QRectF renderArea(0, 0, (mComposition->paperWidth() * mComposition->scale()), (mComposition->paperHeight() * mComposition->scale())); mComposition->canvas()->render(&p, renderArea); p.end(); std::cout << "mPrinter->outputFormat() = " << mPrinter->outputFormat() << std::endl; //if ( mPrinter->outputFormat() == QPrinter::PostScriptFormat ) if (isPs) { // reset the page mPrinter->setPageSize(psize); QFile f(mPrinter->outputFileName()); // Overwrite the bounding box std::cout << "Overwrite the bounding box" << std::endl; if (!f.open(QIODevice::ReadWrite)) { throw QgsIOException(tr("Couldn't open " + f.name() + tr(" for read/write"))); } Q_LONG offset = 0; Q_LONG size; bool found = false; QString s; char buf[101]; while (!f.atEnd()) { size = f.readLine(buf, 100); s = QString(buf); if (s.find("%%BoundingBox:") == 0) { found = true; break; } offset += size; } if (found) { int w, h; w = (int) (72 * mComposition->paperWidth() / 25.4); h = (int) (72 * mComposition->paperHeight() / 25.4); if (mPrinter->orientation() == QPrinter::Landscape) { int tmp = w; w = h; h = tmp; } s.sprintf("%%%%BoundingBox: 0 0 %d %d", w, h); if (s.length() > size) { int shift = s.length() - size; shiftFileContent(&f, offset + size + 1, shift); } else { if (!f.at(offset)) { QMessageBox::warning(this, tr("Error in Print"), tr("Cannot seek")); } else { // Write spaces (for case the size > s.length() ) QString es; es.fill(' ', size - 1); f.flush(); if (f.writeBlock(es.toLocal8Bit().data(), size - 1) < size - 1) { QMessageBox::warning(this, tr("Error in Print"), tr("Cannot overwrite BoundingBox")); } f.flush(); f.at(offset); f.flush(); if (f.writeBlock(s.toLocal8Bit().data(), s.length()) < s.length() - 1) { QMessageBox::warning(this, tr("Error in Print"), tr("Cannot overwrite BoundingBox")); } f.flush(); } //END else (!f.at(offset)) } //END else (s.length() > size) } //END if(found) else { QMessageBox::warning(this, tr("Error in Print"), tr("Cannot find BoundingBox")); } f.close(); // Overwrite translate if (mPrinter->orientation() == QPrinter::Portrait) { std::cout << "Orientation portraint -> overwrite translate" << std::endl; if (!f.open(QIODevice::ReadWrite)) { throw QgsIOException(tr("Couldn't open ") + f.name() + tr(" for read/write")); } offset = 0; found = false; //Example Qt3: //0 4008 translate 1 -1 scale/defM ... //QRegExp rx ( "^0 [^ ]+ translate ([^ ]+ [^ ]+) scale/defM matrix CM d \\} d" ); //Example Qt4: //0 0 translate 0.239999 -0.239999 scale } def QRegExp rx("^0 [^ ]+ translate ([^ ]+ [^ ]+) scale \\} def"); while (!f.atEnd()) { size = f.readLine(buf, 100); s = QString(buf); if (rx.search(s) != -1) { found = true; break; } offset += size; } //END while( !f.atEnd() ) if (found) { int trans; trans = (int) (72 * mComposition->paperHeight() / 25.4); std::cout << "trans = " << trans << std::endl; //Qt3: //s.sprintf( "0 %d translate %s scale/defM matrix CM d } d", trans, (const char *)rx.cap(1).toLocal8Bit().data() ); //Qt4: s.sprintf("0 %d translate %s scale } def\n", trans, (const char *) rx.cap(1).toLocal8Bit().data()); std::cout << "s.length() = " << s.length() << " size = " << size << std::endl; if (s.length() > size) { //QMessageBox::warning(this, tr("Error in Print"), tr("Cannot format translate")); // Move the content up int shift = s.length() - size; /* int last = f.size() + shift -1; for ( int i = last; i > offset + size; i-- ) { f.at(i-shift); QByteArray ba = f.read(1); f.at(i); f.write(ba); } */ shiftFileContent(&f, offset + size + 1, shift); } //END if( s.length() > size) // Overwrite the row if (!f.at(offset)) { QMessageBox::warning(this, tr("Error in Print"), tr("Cannot seek")); } else { /* Write spaces (for case the size > s.length() ) */ QString es; es.fill(' ', size - 1); f.flush(); if (f.writeBlock(es.toLocal8Bit().data(), size - 1) < size - 1) { QMessageBox::warning(this, tr("Error in Print"), tr("Cannot overwrite translate")); } f.flush(); f.at(offset); f.flush(); if (f.writeBlock(s.toLocal8Bit().data(), s.length()) < s.length() - 1) { QMessageBox::warning(this, tr("Error in Print"), tr("Cannot overwrite translate")); } f.flush(); } //END else } else { QMessageBox::warning(this, tr("Error in Print"), tr("Cannot find translate")); } f.close(); } } } catch(QgsIOException e) { QMessageBox::warning(this, tr("File IO Error"), e.what()); } } else { // print to printer bool print = true; // Check size std::cout << "Paper: " << mPrinter->widthMM() << " x " << mPrinter->heightMM() << std::endl; if (mComposition->paperWidth() != mPrinter->widthMM() || mComposition->paperHeight() != mPrinter->heightMM()) { int answer = QMessageBox::warning(0, tr("Paper does not match"), tr("The selected paper size does not match the composition size"), QMessageBox::Ok, QMessageBox::Abort); if (answer == QMessageBox::Abort) { print = false; } } //END if(compositionSize != paperSize) if (print) { std::cout << "Printing ... " << std::endl; QPainter p(mPrinter); p.scale(scale, scale); QRectF renderArea(0, 0, (mComposition->paperWidth() * mComposition->scale()), (mComposition->paperHeight() * mComposition->scale())); mComposition->canvas()->render(&p, renderArea); p.end(); std::cout << "... printing finished" << std::endl; } //END if ( print ) } mComposition->setPlotStyle(QgsComposition::Preview); mView->setScene(mComposition->canvas()); } else { raise(); }}bool QgsComposer::shiftFileContent ( QFile *file, Q_LONG start, int shift ){ int last = file->size() + shift -1; for ( int i = last; i >= start + shift; i-- ) { if ( !file->at(i-shift) ) return false; QByteArray ba = file->read(1); if ( ba.isEmpty() ) return false; if ( !file->at(i) ) return false; if ( file->write(ba) != 1 ) return false; } return true;}void QgsComposer::on_mActionExportAsImage_activated(void){ // Image size int width = (int) (mComposition->resolution() * mComposition->paperWidth() / 25.4); int height = (int) (mComposition->resolution() * mComposition->paperHeight() / 25.4); int memuse = width * height * 3 / 1000000; // pixmap + image#ifdef QGISDEBUG std::cout << "Image " << width << " x " << height << std::endl; std::cout << "memuse = " << memuse << std::endl;#endif if ( memuse > 200 ) { // cca 4500 x 4500 int answer = QMessageBox::warning ( 0, tr("Big image"), tr("To create image ") + QString::number(width) + " x " + QString::number(height) + tr(" requires circa ") + QString::number(memuse) + tr(" MB of memory"), QMessageBox::Ok, QMessageBox::Abort ); raise (); if ( answer == QMessageBox::Abort ) return; } // Get file and format (stolen from qgisapp.cpp but modified significantely) //create a map to hold the QImageIO names and the filter names //the QImageIO name must be passed to the mapcanvas saveas image function typedef QMap<QString, QString> FilterMap; FilterMap myFilterMap; //find out the last used filter QSettings myQSettings; // where we keep last used filter in persistant state QString myLastUsedFormat = myQSettings.readEntry("/UI/lastSaveAsImageFormat", "png" ); QString myLastUsedFile = myQSettings.readEntry("/UI/lastSaveAsImageFile","qgis.png"); QFileInfo file(myLastUsedFile); // get a list of supported output image types int myCounterInt=0; QString myFilters; QString myLastUsedFilter; for ( ; myCounterInt < QImageWriter::supportedImageFormats().count(); myCounterInt++ ) { QString myFormat=QString(QImageWriter::supportedImageFormats().at( myCounterInt )); QString myFilter = myFormat + " " + tr("format") + " (*." + myFormat.lower() + " *." + myFormat.upper() + ")"; if ( myCounterInt > 0 ) myFilters += ";;"; myFilters += myFilter; myFilterMap[myFilter] = myFormat; if ( myFormat == myLastUsedFormat ) { myLastUsedFilter = myFilter; } }#ifdef QGISDEBUG std::cout << "Available Filters Map: " << std::endl; FilterMap::Iterator myIterator;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -