2

I created a QMessageBox with an html link:

QTMessageBox msgBox(Utility::UI::topLevelWidget());

msgBox.setText("<a href=\"http://www.example.cz/?url=www%25www\">Link</a>");

msgBox.exec();

If I left click the link a new web browser tab opens. The problem is that the url http://www.example.cz/?url=www**%2525**www is opened instead of http://www.example.cz/?url=www**%25**www

How do I prevent such behavior?

UPDATE: If I right click the link, choose "Copy link" and paste it into the browser, the link is ok.

MPeli
  • 570
  • 1
  • 8
  • 19
  • I think the problem not came from here, post the method that open the tab in browser. Probably you encode once more the url ? – Servuc Sep 16 '15 at 11:32
  • I change the code. If I right click the link, choose "Copy link" and paste it into the browser the link is ok. – MPeli Sep 16 '15 at 11:53
  • So you want to prevent qt from translating "special" characters to html symbols (like `%` to `%25` or "space" to `%20`)? – Gombat Sep 16 '15 at 11:58

1 Answers1

2

That's because % has the html encoding %25. So %25 -> %2525.

Why does Qt encode the links automatically?

In the QMessageBox, there is a QLabel. The label uses the Qt::TextFormat Qt::AutoText by default. Therefore, it detects in your text, that it is html encoded and generates the link.

The QLabel sends the signal linkActivated(const QString& link) or uses QDesktopServices::openUrl(), depending its the boolean openExternalLinks.

It seems, that the QMessageBox sets openExternalLinks to true.

Since the link will be used as input for a QUrl, it will be parsed. That's the reason for the double encoding.

It is possible, to modify the behavior of QDesktopServices::openUrl() by using its static method void QDesktopServices::setUrlHandler. I implemented and tested it for the desired behavior:

MyUrlHandler urlHandler;
QDesktopServices::setUrlHandler( "http", &urlHandler, "handleUrl" );

QMessageBox msgBox;
msgBox.setText( "<a href=\"http://www.example.cz/?url=www%25www\">Link</a>" );
msgBox.show();

Using the class MyUrlHandler:

class MyUrlHandler : public QObject
{
  Q_OBJECT
public:
  MyUrlHandler(QObject* parent=0):QObject(parent){}
public slots:
  void handleUrl(const QUrl &url)
  {
    QDesktopServices::openUrl( QUrl::fromEncoded( url.toString().toAscii() ) );
  }
};

The trick is simple, I set the link address directly to the QUrl instance as already valid url.

But unfortunately, it modifies the behavior globally.

Gombat
  • 1,994
  • 16
  • 21
  • It works perfectly. Thank you very much. QDesktopServices::unsetUrlHandler("https"); returns the handling behavior for the given scheme (https) to the default behavior. – MPeli Sep 17 '15 at 13:20
  • Great. Yes, but it would be nicer, if there as an option to change the behavior for single instances. Nevertheless, if it fits for your needs, it's enough and I'm glad. – Gombat Sep 17 '15 at 13:32