views:

188

answers:

3

Hello everyone,

I'm trying to enhance Qt's QPrintPreviewWidget by allowing it to display page numbers (in the footer somewhere). Unfortunately, I can't quite figure out how to go about it without hacking up Qt's source. I see a great spot for this additional code (in qpaintengine_preview.cpp, in newPage() method) but that means I'm going to have to recompile the whole of Qt (I got a binary build from Trolltech). Furthermore, if I decide to run an app that uses this functionality on someone else's box, I'm going to have to recompile there as well (say if it's a different arch).

Are there any other cleaner ways?

Thanks

+1  A: 

Is the newPage() method virtual? If so, you could subclass and use that in you own applications, which would be a bit easier.

The second option would be to statically link your executable with the modified Qt libraries. You need to be aware of licensing concerns to do this. This way, every place you put the app will have your modified functionality. (You would still need to recompile for different architectures.)

Finally, you could get the latest sources from http://qt.gitorious.org/, modify them in the way you desire, and submit a patch back to the trolls. If you do this, you'll probably have to keep the old behavior the default, and add an option to enable the new behavior. They may or may not accept the patch. And if they do accept the patch, you may not be able to rely on other people's computers getting that version for quite some time, if ever.

Caleb Huitt - cjhuitt
Yeah that's what I figured.newPage() is not virtual, and even if it was, I wouldn't be able to inject my class into the print preview hierarchy. Thanks though!
EightyEight
A: 

If you have a library and this library has same symbols linker at runtime is looking for - to get the code for the print preview - then you can inject your own code to replace the real implementation. Method is called dll injection.

Check http://en.wikipedia.org/wiki/DLL%5Finjection for more info

rasjani
+1  A: 

Read the source code.

In this case, read QPrintPreviewDialog source code to see how it does it. This standard dialog has navigation buttons and a current page display, so it kind of does what you want (that is, if I really understood what you want to accomplish). The methods you're looking for are the following (src/gui/dialogs/qprintpreviewdialog.cpp):

void QPrintPreviewDialogPrivate::_q_previewChanged()
void QPrintPreviewDialogPrivate::_q_navigate(QAction* action)
void QPrintPreviewDialogPrivate::updateNavActions()

Basically, _q_previewChanged() is connected to QPrintPreviewWidget::previewChanged() signal. When it is emitted, the page number is updated with information acquired from QPrintPreviewWidget::currentPage() and QPrintPreviewWidget::pageCount().

As for extending the behavior of QPrintPreviewWidget you can try two approaches, both of them do not require a tailored version of Qt:

Extend QPrintPreviewWidget

In the constructor, access the layout() (it is a QVBoxLayout that is used interanally), add the footer widget, connect the previewChanged() signal to a slot that updates the page number and be done. The problem with this approach is that it counts on the layout to be present and be a QVBoxLayout. Since this is somehow private, it can break with newer versions.

Create a new class extending QWidget or QFrame

If you don't require your widget to be a QPrintPreviewWidget, just create a new QWidget derived class and add the print preview widget and the footer to a layout, connects slots etc. Use your derived widget instead of QPrintPreviewWidget.

Now, if you want to modify the behavior of the widget on already deployed binaries, things get uglier. I cannot help in this case.

andref

related questions