Qt ActiveX and OneNote (desktop 2016 32bit) - qt

Trying to export student exam results from excel to Student OneNote pages.
importing the excel data using QAxObject dynamic calls works flawlessly however a similar setup with OneNote yeilds unkown
getHieracrchy Documentation below is the output of dumpdoc.exe :
void GetHierarchy (QString bstrStartNodeID, HierarchyScope hsScope, QString& pbstrHierarchyXmlOut, XMLSchema xsSchema)
QVariantList params = ...
onenote_object->dynamicCall("GetHierarchy(QString, HierarchyScope, QString&, XMLSchema)", params);
Implementation :
QAxObject* onenote = new QAxObject("OneNote.Application");
QString doc = onenote->generateDocumentation();
qDebug() << onenote->control(); // {dc67e480-c3cb-49f8-8232-60b0c2056c8e}
QVariantList params;
QString xml_out;
params << "" << 4 << xml_out << 0;
onenote->dynamicCall("GetHierarchy(QString, HierarchyScope, QString&, XMLSchema)", params);
Error
QAxBase: Error calling IDispatch member GetHierarchy: Unknown error
I have tried running dumpcpp against the CLSID of the OneNote.Application and the registry entry for the typelib thinking it might be a type error for a none builtin Qt->COM type, but no output is produced.
dumpcpp -nometaobject -getfile {0EA692EE-BB50-4E3C-AEF0-356D91732725} -o onenote
I can manipulate the pages via powershell and see the typelib reference in visual basic but want to access OneNote from C++.

Related

SCP always returns the same error code

I have a problem copying files with scp. I use Qt and copy my files with scp using QProcess. And when something bad happens I always get exitCode=1. It always returns 1. I tried copying files with a terminal. The first time I got the error "Permission denied" and the exit code was 1. Then I unplugged my Ethernet cable and got the error "Network is unreachable". And the return code was still 1. It confuses me very much cause in my application I have to distinct these types of errors.
Any help is appreciated. Thank you so much!
See this code as a working example:
bool Utility::untarScript(QString filename, QString& statusMessages)
{
// Untar tar-bzip2 file, only extract script to temp-folder
QProcess tar;
QStringList arguments;
arguments << "-xvjf";
arguments << filename;
arguments << "-C";
arguments << QDir::tempPath();
arguments << "--strip-components=1";
arguments << "--wildcards";
arguments << "*/folder.*";
// tar -xjf $file -C $tmpDir --strip-components=1 --wildcards
tar.start("tar", arguments);
// Wait for tar to finish
if (tar.waitForFinished(10000) == true)
{
if (tar.exitCode() == 0)
{
statusMessages.append(tar.readAllStandardError());
return true;
}
}
statusMessages.append(tar.readAllStandardError());
statusMessages.append(tar.readAllStandardOutput());
statusMessages.append(QString("Exitcode = %1\n").arg(tar.exitCode()));
return false;
}
It gathers all available process output for you to analyse. Especially look at readAllStandardError().

Files getting corrupted when being downloaded using QNetworkAcessManager

I'm developing a client app whose purpose is to download some files from a web server, temporarily store them in the Temp folder, check for file integrity, then send them to a FTP server in a Embedded Linux device.
Recently I got problems when doing the process in a preliminary development stage when I was trying to do the download from my local machine (see related question here). Now I'm able to download and upload without errors and with verification (I'm using QCryptographicHash + file size to check for any nonconformities) from my machine, but the same doesn't happen when I try downloading from the HTTP server.
There is a total of 8 files being downloaded: three .tar.gz, one simple text, two programs and two binaries. I'm able to successfully download all compressed files, the text file and one of the binaries, but the others, namely the two programs and one of the binaries (a Linux Kernel image) are always being incorrectly downloaded.
I check this by noticing not only that the hash returns error for them, but also for their sizes: their sizes are always wrong (and always the same erroneous value for any download attempt). And the files in the server are all correct.
My first suspicion was that I need to configure the HTTP download in a way that differs from the common FTP download from the local machine, but I'm unaware on how would that be. Moreover if this extra configuration was needed, then why some of the files always return correctly?
Here is the relevant code as for now:
void MainWindow::processNextDownload()
{
QUrl ulrTemp(updateData.at(transferStep).downloadUrl.arg(ui->leID->text())); //"//" +
if (updateData.at(transferStep).downloadUrl.contains("http"))
ulrTemp.setScheme("http");
else
ulrTemp.setScheme("file");
// ulrTemp.setUserName();
// ulrTemp.setPassword();
// ulrTemp.setPort();
qDebug() << "Downloading" << transferStep << "from" << ulrTemp;
#if 1
poReply = downloadNetworkManager->get(QNetworkRequest(ulrTemp));
#else
QNetworkRequest request;
request.setUrl(ulrTemp);
request.setRawHeader("User-Agent", "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.17 (KHTML, like Gecko) Chrome/24.0.1312.60 Safari/537.17");
poReply = downloadNetworkManager->get(request);
#endif
connect(poReply,SIGNAL(downloadProgress(qint64,qint64)),this,SLOT(slotDownloadProgress(qint64,qint64)));
ui->statusBar->showMessage(tr("Downloading: %1").arg(updateData.at(transferStep).itemName));
}
void MainWindow::slotFileDownloaded(QNetworkReply* reply)
{
if (reply && (reply->error() != QNetworkReply::NoError))
{
ui->statusBar->clearMessage();
if (!isSingleFile)
{
const QString strTemp = tr("An error occurred while downloading \"%1\": %2 (error message: %3)")
.arg(updateData.at(transferStep).downloadName).arg(reply->error()).arg(reply->errorString());
QMessageBox::critical(this,tr("Error in download"),strTemp);
}
else
{
//irrelevant...
}
finished(false);
return;
}
qDebug() << "To write: " << reply->bytesAvailable();
QByteArray downloadedData = reply->readAll();
reply->deleteLater();
poReply->deleteLater();
//![]
static const QString tempFilePath = QDir::tempPath();
if (!isSingleFile)
{
QFile file(tempFilePath + "/" + updateData.at(transferStep).downloadName);
if (!file.open(QFile::WriteOnly | QFile::Truncate))
{
qDebug() << "Failure opening temp file to write: " << file.fileName();
QMessageBox::critical(this,
tr("Error"),
tr("An error occured while trying to open a temporary file to write the downloaded data (file: %1).").arg(file.fileName()));
transferStep = downloadStepCount;
slotFileUploaded(NULL);
return;
}
qint32 bytesWritten = file.write(downloadedData);
file.flush();
if (downloadedData.size() != bytesWritten)
qDebug() << "Write failed, wrote" << bytesWritten << "out of" << downloadedData.size() << "bytes.";
else
qDebug() << "Wrote " << bytesWritten << "bytes.";
file.close();
//![]
if (++transferStep >= downloadStepCount)
{
qDebug() << "Start hash check";
slotStartHashCheck();
return;
}
processNextDownload();
}
else
{
//irrelevant...
}
}
And this is why I get (the last number value after the "=" in the hash code is the file size):
So what am I missing?

QUrl, right coding for paths

I have a problem with coding. I'm using drag and drom inside my application but some text files I can not open, after some searching I find that the path is with wrong coding. The real file is 'Some_file - 01.txt' but when I try print this path (after drop) to the stdout I will get 'Some_file – 01.txt'. What I miss:
void MainWindow::dropEvent(QDropEvent *event) {
QList<QUrl> urls = event->mimeData()->urls();
...
cout << paths[1].toLocalFile() << endl; /* Some_file – 01.txt */
cout << paths[1].toEncoded() << endl; /* Some_file%20%E2%80%93%2001.txt */
}
I also try QString::fromLatin1 or fromUtf8 but without success.
I'm using QT 4.7.0 and Windows 7.
Edit:
This is my main setup:
QTextCodec::setCodecForCStrings(QTextCodec::codecForName("UTF-8"));
QTextCodec::setCodecForTr(QTextCodec::codecForName("UTF-8"));
QTextCodec::setCodecForLocale(QTextCodec::codecForName("UTF-8"));
And unfortunately even this is not working for me:
QString fileName = QFileDialog::getOpenFileName(this, tr("Load EEPROM from HEX file"), "", tr("HEX file (*.hex)"));
ifstream hexFile(fileName.toStdString().c_str());
I'm not able to open files where the char '-' is part of file name.
EDIT2:
If I change the file name manualy from 'file.txt' to 'file-.txt' everything is working well. But when I (the same file) copy and paste this file to the same folder, windows will generate new name with postfix: 'file - copy.txt' and this file I can NOT open. So the Windows is using different character for '-' vz. '–'.
What I can do ?
Solution:
void openFile(string fileName) {
ifstream fileio(fileName.c_str());
}
QString qtFileName = QFileDialog::getOpenFileName(...)
openFile(qtFileName.toLocal8Bit().constData());
std::cout is encoded with some local encoding. What you need is to convert the QString returned by the toLocalFile() into a local 8 bit encoding.
For example:
QUrl url = ...;
QString filePath = url.toLocalFile();
QByteArray filePath8 = filePath.toLocal8Bit();
std::cout << filePath8.constData();
But really, the whole exercise is not necessary, since to access the files you should be using QFile, which takes a QString directly, and console output can be done using QTextStream. To wit:
#include <cstdio>
#include <QTextStream>
#include <QFile>
QTextStream out(stdout);
void test() {
out << filePath;
QFile file(filePath);
if (file.open(QIODevice::ReadOnly)) {
...
}
}

Convert QUrl with percent encoding into string

I use a URL entered by the user as text to initialize a QUrl object. Later I want to convert the QUrl back into a string for displaying it and to check it using regular expression. This works fine as long as the user does not enter any percent encoded URLs.
Why doesn't the following example code work?
qDebug() << QUrl("http://test.com/query?q=%2B%2Be%3Axyz%2Fen").toDisplayString(QUrl::FullyDecoded);
It simply doesn't decode any of the percent-encoded characters. It should print "http://test.com/query?q=++e:xyz/en" but it actually prints "http://test.com/query?q=%2B%2Be%3Axyz%2Fen".
I also tried a lot of other methods like fromUserInput() but I could not make the code work correctly in Qt5.3.
Can someone explain me how to do this and why the above code doesn't work (i.e. showing the decoded URL) even when using QUrl::FullyDecoded?
UPDATE
After getting the fromPercentEncoding() hint, I tried the following code:
QUrl UrlFromUserInput(const QString& input)
{
QByteArray latin = input.toLatin1();
QByteArray utf8 = input.toUtf8();
if (latin != utf8)
{
// URL string containing unicode characters (no percent encoding expected)
return QUrl::fromUserInput(input);
}
else
{
// URL string containing ASCII characters only (assume possible %-encoding)
return QUrl::fromUserInput(QUrl::fromPercentEncoding(input.toLatin1()));
}
}
This allows the user to input unicode URLs and percent-encoded URLs and it is possible to decode both kinds of URLs for displaying/matching. However the percent-encoded URLs did not work in QWebView... the web-server responded differently (it returned a different page). So obviously QUrl::fromPercentEncoding() is not a clean solution since it effectively changes the URL. I could create two QUrl objects in the above function... one constructed directly, one constructed using fromPercentEncoding(), using the first for QWebView and the latter for displaying/matching only... but this seems absurd.
#Conclusion
I've done some research, the conclusion so far is: absurd.
QUrl::fromPercentEncoding() is the way to go and what OP has done in the UPDATE section should've been the accepted answer to the question in title.
I think Qt's document of QUrl::toDisplayString is a little bit misleading :
"Returns a human-displayable string representation of the URL. The output can be customized by passing flags with options. The option
RemovePassword is always enabled, since passwords should never be
shown back to users."
Actually it doesn't claim any decoding ability, the document here is unclear about it's behavior. But at least the password part is true. I've found some clues on Gitorious:
"Add QUrl::toDisplayString(), which is toString() without password. And fix documentation of toString() which said this was the method to
use for displaying to humans, while this has never been true."
#Test Code
In order to discern the decoding ability of different functions. The following code has been tested on Qt 5.2.1 (not tested on Qt 5.3 yet!)
QString target(/*path*/);
QUrl url_path(target);
qDebug() << "[Original String]:" << target;
qDebug() << "--------------------------------------------------------------------";
qDebug() << "(QUrl::toEncoded) :" << url_path.toEncoded(QUrl::FullyEncoded);
qDebug() << "(QUrl::url) :" << url_path.url();
qDebug() << "(QUrl::toString) :" << url_path.toString();
qDebug() << "(QUrl::toDisplayString) :" << url_path.toDisplayString(QUrl::FullyDecoded);
qDebug() << "(QUrl::fromPercentEncoding):" << url_path.fromPercentEncoding(target.toUtf8());
Return QByteArray: QUrl::toEncoded
Return QString: QUrl::url, QUrl::toString, QUrl::toDisplayString, QUrl::fromPercentEncoding
P.S. QUrl::url is just synonym for QUrl::toString.
#Output
[Case 1]: When target path = "%_%" (test the functionality of encoding):
[Original String]: "%_%"
--------------------------------------------------------------------
(QUrl::toEncoded) : "%25_%25"
(QUrl::url) : "%25_%25"
(QUrl::toString) : "%25_%25"
(QUrl::toDisplayString) : "%25_%25"
(QUrl::fromPercentEncoding): "%_%"
[Case 2]: When target path = "Meow !" (test the functionality of encoding):
[Original String]: "Meow !"
--------------------------------------------------------------------
(QUrl::toEncoded) : "Meow%20!"
(QUrl::url) : "Meow !"
(QUrl::toString) : "Meow !"
(QUrl::toDisplayString) : "Meow%20!" // "Meow !" when using QUrl::PrettyDecoded mode
(QUrl::fromPercentEncoding): "Meow !"
[Case 3]: When target path = "Meow|!" (test the functionality of encoding):
[Original String]: "Meow|!"
--------------------------------------------------------------------
(QUrl::toEncoded) : "Meow%7C!"
(QUrl::url) : "Meow%7C!"
(QUrl::toString) : "Meow%7C!"
(QUrl::toDisplayString) : "Meow|!" // "Meow%7C!" when using QUrl::PrettyDecoded mode
(QUrl::fromPercentEncoding): "Meow|!"
[Case 4]: When target path = "http://test.com/query?q=++e:xyz/en" (none % encoded):
[Original String]: "http://test.com/query?q=++e:xyz/en"
--------------------------------------------------------------------
(QUrl::toEncoded) : "http://test.com/query?q=++e:xyz/en"
(QUrl::url) : "http://test.com/query?q=++e:xyz/en"
(QUrl::toString) : "http://test.com/query?q=++e:xyz/en"
(QUrl::toDisplayString) : "http://test.com/query?q=++e:xyz/en"
(QUrl::fromPercentEncoding): "http://test.com/query?q=++e:xyz/en"
[Case 5]: When target path = "http://test.com/query?q=%2B%2Be%3Axyz%2Fen" (% encoded):
[Original String]: "http://test.com/query?q=%2B%2Be%3Axyz%2Fen"
--------------------------------------------------------------------
(QUrl::toEncoded) : "http://test.com/query?q=%2B%2Be%3Axyz%2Fen"
(QUrl::url) : "http://test.com/query?q=%2B%2Be%3Axyz%2Fen"
(QUrl::toString) : "http://test.com/query?q=%2B%2Be%3Axyz%2Fen"
(QUrl::toDisplayString) : "http://test.com/query?q=%2B%2Be%3Axyz%2Fen"
(QUrl::fromPercentEncoding): "http://test.com/query?q=++e:xyz/en"
P.S. I also encounter the bug that Ilya mentioned in comments: Percent Encoding doesn't seem to be working for '+' in QUrl
#Summary
The result of QUrl::toDisplayString is ambiguous. As the document says, the QUrl::FullyDecoded mode must be used with care. No matter what type of URL you got, encode them by QUrl::toEncode and display them with QUrl::fromPercentEncoding when necessary.
As for the malfunction of percent-encoded URLs in QWebView mentioned in OP, more details are needed to debug it. Different function and different mode used could be the reason.
#Helpful Resources
RFC 3986 (which QUrl conforms)
Encode table
Source of qurl.cpp on Gitorious
I am not sure why toDisplayString(QUrl::FullyDecoded) does not work.
After trying several versions I have found that copy.query(QUrl::FullyDecoded) does decode the query part. The Documentation has an example with the the following code does return the decoded URL:
QUrl url("http://test.com/query?q=%2B%2Be%3Axyz%2Fen");
url.setQuery(url.query(QUrl::FullyDecoded), QUrl::DecodedMode);
qDebug() << url.toString();
To solve the problem this way is not optimal because the query part is copied without need.
You can use QUrlQuery::toString(QUrl::FullyEncoded) or QUrl::fromPercentEncoding() for this converting.

QFile::copy says "can't open source file for input"?

I'm going to copy one file using QFile::copy function but this function always returns false and errorString says :
"Cannot open D:/tmp/buf34.txt for input"
I tried to run this program with administrator privilege but nothing changed. My code is really simple :
QString source = url.toLocalFile();
QString destination = _dir.absolutePath()
+ QString("/%1").arg(QFileInfo(source).fileName());
qDebug()<<"Cp from :" << source << " to : "<< destination;
QFile file(source);
qDebug()<<file.copy(destination);
qDebug()<<file.errorString();
Edit:
I have QListView occupied with a QFileSystemModel. I try to drag one file from this ListView to a QLabel. For the QLabel a destination path is set. In drop event I try to copy file.
QFile::copy uses QFile::open but overwrites the error message open would give by the unhelpful "Cannot open %1 for input" you got.
So, you should try opening the file yourself to get that original error message:
qDebug()<<file.open(QFile::ReadOnly);
qDebug()<<file.errorString();

Resources