PDA

View Full Version : Qt Jambi Webkit Custom Protocol



tgl
2nd July 2009, 14:55
I'm trying to add a custom protocol to QtWebView called "local://". I followed an example for python I found here:

http://www.diotavelli.net/PyQtWiki/Using%20a%20Custom%20Protocol%20with%20QtWebKit

and converted it to Java. It kind of works, but there is some sort of character encoding issues I can't figure out. Here is the example Java code I created....

LocalNetworkReply:


public class LocalNetworkReply extends QNetworkReply {

private String content;
private int offset = 0;

public LocalNetworkReply(Operation op, QNetworkRequest request, QIODevice outgoingData){
super();

this.content = "<html><head><title>Test</title></head><body>This is a test.</body></html>";
this.offset = 0;

this.setHeader(QNetworkRequest.KnownHeaders.Conten tTypeHeader, "text/html; charset=UTF-8");
this.setHeader(QNetworkRequest.KnownHeaders.Conten tLengthHeader, (this.content.length()));


QIODevice.OpenModeFlag[] flags = new QIODevice.OpenModeFlag[2];
flags[0] = QIODevice.OpenModeFlag.ReadOnly;
flags[1] = QIODevice.OpenModeFlag.Unbuffered;

QTimer.singleShot(0, this, "readyRead()");
QTimer.singleShot(0, this, "finished()");

this.open(flags);
this.setUrl(request.url());
}

@Override
public boolean isSequential() {
return true;
}

@Override
public long bytesAvailable() {
return this.content.getBytes().length - this.offset;
}

@Override
public void abort() {
System.out.println("Abort called");
}

@Override
protected int readData(byte[] data) {
try {
data = this.content.getBytes("UTF-8");
System.out.println(new String(data,"UTF-8"));
System.out.println(data.length);
System.out.println(this.content.getBytes().length) ;
} catch (UnsupportedEncodingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return data.length;
}
}


LocalNetworkAccessManager:


public class LocalNetworkAccessManager extends QNetworkAccessManager {

public LocalNetworkAccessManager(){
super();
}

public LocalNetworkAccessManager(QObject qObject){
super(qObject);


}

@Override
protected QNetworkReply createRequest(Operation op,
QNetworkRequest request, QIODevice outgoingData) {

if(request.url().scheme().equalsIgnoreCase("local") && op.compareTo(QNetworkAccessManager.Operation.GetOp eration) == 0){
LocalNetworkReply lnr = new LocalNetworkReply(op, request, outgoingData);
return lnr;
}else{
return super.createRequest(op, request, outgoingData);
}
}
}

Application Code:

.....
browser = new QWebView();
browser.page().setNetworkAccessManager(new LocalNetworkAccessManager());
.....
browser.load(new QUrl("local://index.html"));
.....

index.html

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Hello World</title>
</head>
<body>
<h1>Hello World!</h1>
</body>
</html>

When I run the application, I get a bunch of garbage characters like this:

6Pj� ��� 0�����+ l� ��벼%��ڨ�p��%���k� 

Could this be a bug in Qt?

wysota
2nd July 2009, 15:40
Not likely. I would start by making this.content a byte array and not a java string. I'm also not sure that your readData() implementation is correct. It should overwrite the content of the argument passed to it. I don't know how to do that in Java but your code doesn't seem to do it (to me it looks like you overwrite the variable and not its content). Also readData() should take an integer with a maximum size of data to read.

tgl
2nd July 2009, 16:25
The method signature is correct based on the javadoc. I took your suggestion about writing the data into the method parameter as opposed to what I was previously doing. I changed the code in LocalNetworkReply to this:



@Override
protected int readData(byte[] data) {

try {
byte[] cBytes = this.content.getBytes("UTF-8");
for(int i=0; i<cBytes.length; i++){
data[i] = cBytes[i];
}

System.out.println(new String(data,"UTF-8"));
System.out.println(data.length);
System.out.println(this.content.getBytes().length) ;
} catch (UnsupportedEncodingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return data.length;
}


Using this code gives me the correct output. I will test a little more, but I think this fixed the issue I was seeing. Thanks for your help.

wysota
2nd July 2009, 18:09
Isn't there a java equivalent of memcpy() or qstrncpy()?