When printing to PDF with QTextDocument and QPrinter is there any way of detecting errors (e.g. not being able to write to the PDF file)?
I'm using the following code:
QTextDocument document;
QPrinter printer( QPrinter::HighResolution );
printer.setOutputFormat( QPrinter::PdfFormat );
printer.setOutputFileName( filename );
document.print( &printer );
In the docs you'll find QPrinter::printerState. So you can definitely do:
if (printer.printerState() == QPrinter::Error)
// do some error handling
I admit that's not a lot work with, as there are only 4 QPrinter::PrinterState's. You might want to do your best to avoid errors in the first place. The detailed description in the doc states:
Note that setting parameters like paper size and resolution on an invalid printer is undefined. You can use QPrinter::isValid() to verify this before changing any parameters.
Additionaly, you could check if the filename you are setting already exists using QFile::exists.
Also, when setting it all up you can call and handle QPrinter::supportedResolutions(), QPrinter::supportedPaperSources() and QPrinter::supportsMultipleCopies(). Of course, printing to PDF you might not have to worry about these.
It seems like printerState does return an error when failing to write a file as long as the file name is valid. If the file name is not valid it returns idle.
Related
I have a contact form that accepts a file input, I'd like to attach the file to the email that gets sent from the form.
Looking at the API reference isn't really helping, it states that the function expects a filepath with no clarification on anything beyond that.
The submit action will save a record of the into the database and this works correctly, something like:
$submission = MyDataObject::create();
$form->saveInto($submission);
$submission->write();
an Email object then gets created and sent. Both of these are functioning and working as expected.
Trying to attach the File I've tried:
$email->addAttachemnt($submission->MyFile()->Link());
which is the closest I can get to getting a filepath for the document. Dumping and pasting the resulting filepath being output by that call will download the form but that line throws an error and can't seem to locate the file.
I suspect that I'm misunderstanding what's supposed to be given to the function, clarification would be very much appreciated.
P.S. I don't currently have access to the code, I'm looking for some clarification on the function itself not an exact answer :).
In SilverStripe 4 the assets are abstracted away, so you can't guarantee that the file exists on your webserver. It generally will, but it could equally exist on a CDN somewhere for example.
When you handle files in SilverStripe 4 you should always use the contents of the file and whatever other metadata you have available, rather than relying on filesystem calls to load it.
This is how the silverstripe/userforms module attaches files to emails:
/** #var SilverStripe\Control\Email\Email $email */
$email->addAttachmentFromData(
$file->getString(), // stream of file contents
$file->getFilename(), // original filename
$file->getMimeType() // mime type
);
I would try $email->addAttachment($submission->MyFile()->Filename); If it doesn't work, you may need to prepend $_SERVER['DOCUMENT_ROOT'] to the filename.
$email->addAttachment($_SERVER['DOCUMENT_ROOT'] . $submission->MyFile()->Filename);
I'm running a u-sql script similar to this:
#output =
SELECT Tag,
Json
FROM #table;
OUTPUT #output
TO #"/Dir/{Tag}/filename.txt"
USING Outputters.Text(quoting : false);
The problem is that #output is empty and the execution crashes. I already checked that if I don't use {tag} in the output path the script works well (it writes an empty file but that's the expectable).
Is there a way to avoid the crash and simply don't output anything?
Thank you
The form you are using is not yet publicly supported. Output to Files (U-SQL) documents the only supported version right now.
That said, depending on the runtime that you are using, and the flags that you have set in the script, you might be running the private preview feature of outputting to a set of files. In that case, I would expect that it would work properly.
Are you able to share a job link?
Problem:
My project... printing a sequence of pages... created based on certain templates and database info...
The sequence of pages to be printed can be, in certain situations, of different sizes.
I have been trying to print to real printer, producing multiple pages
if (m_printer->newPage()) { ... }
and on a physical printer, if I try to change the page size, it either doesn't work or puts the printer in an error state.
So there is not much choice, it seems, but to make each page a separate job. Minor disadvantages - possibly on a network. Oh well.
On pdf or any type of file printing, though, it makes a huge difference, whether the sequence is contained in a single document on multiple pages, or if it creates hundreds of different documents of one page each.
So, I found this Is it possible to make a pdf with different page size in Qt?
it seems to be exactly what I need, if I print to a pdf - while for real printer I will make each page a separate job.
The only problem:
How can I tell if I am creating a pdf file, or if I am sending a job to a real printer ?
I looked in QPrinter and QPrinterInfo, I did not see anything that can help.
Pdf printing is probably enabled because of Adobe Acrobat.
I am implementing this currently in Windows.
Edit: why getting the outputFormat (Naidu's answer below) doesn't work:
qprinter.cpp:
void QPrinterPrivate::initEngines(QPrinter::OutputFormat format, const QPrinterInfo &printer)
{
..
// Only set NativeFormat if we have a valid plugin and printer to use
if (format == QPrinter::NativeFormat) { //////// which of course has to be, we have to support any printer
ps = QPlatformPrinterSupportPlugin::get();
QPrinterInfo printerToUse = findValidPrinter(printer);
if (ps && !printerToUse.isNull()) { //////// both valid since the PDF writer is valid
outputFormat = QPrinter::NativeFormat;
printerName = printerToUse.printerName();
}
}
...
}
I would like to have something to check, other than the fact that "pdf" may be contained in the name. If needed, I am willing to use the awful DEVMODE, I just don't know what to look for.
Use the public function
QPrinter::outputFormat()
it returns an enum type enum QPrinter::OutputFormat.
And check if it is QPrinter::PdfFormat
http://doc.qt.io/qt-5/qprinter.html#OutputFormat-enum
I'm trying to test for the presence of a string somewhere in a long webpage. Using PHPUnit's assertRegExp if the string is not found it prints out the entire page and then finishes with matches PCRE pattern "/xxxxxx/". According to the documentation I should be able to specify a message a third that will be printed out if the test fails. That message is printed, followed by the full page source. What I'd like to do is just print the message. Using Selenium in my previous apps I used assertTextPresent and it would just print out confirmation that the text was/was not found, without filling my screen.
I have tried wrapping the assertRegExp in a try-catch but it didn't change anything.
You could try assertContains() instead of assertRegexp().
PHPUnit is responsible for printing out the failed text, and this differs from one assert method to another. It just might work.
If it does not, open an issue at PHPUnit's issue tracker about PHPUnit printing too much out.
I am using the getBodyText() method to get all page content and than I use assertTextPresent() to check the presence of pattern.
$this->assertTextPresent($this->getBodyText(), 'text to find');
The solution has been positivly tested with latest phpunit 4.7.
I use assertTrue(stripos($haystack, $needle) !== false, 'Failed assertion message');
I am parsing a xml file with QXmlDefaultHandler like this:
void Parser::ParseFilename(const char* pFilename)
{
LOG_DEBUG("Parser::ParseFilename(%s)", pFilename);
ClearState();
m_inputFile.setFileName(pFilename);
QXmlInputSource source( &m_inputFile );
QXmlSimpleReader reader;
reader.setContentHandler( this );
reader.parse( source );
}
I need to know line numbers for error messages. How can I get them?
Use the exception that is passed to QXmlErrorHandler::error() function. You can set a custom error handler using QXmlReader::setErrorHandler().
Answering myself.
I was not completely clear in my question because I didn't write that I need to generate my own custom error messages. For example I need to make complicate validations of certain attributes. Then, if the attribute is invalid, I need to write message like: "Error on line 15454 column 48, attritubute 'number' should be a prime number but is 65536'.
The approach suggested by Ariya Hidayat works only for messages generated by the SAX parser itself (like malformed XML).
For custom messages I need to overload setDocumentLocator ( QXmlLocator * locator ) which tells me about the current locator, and save somewhere the value of the locator like savedLocator = locator; Actual line number is obtained by locator->lineNumber().