diff --git a/Changelog b/Changelog index b0d841454..2ccf9e275 100644 --- a/Changelog +++ b/Changelog @@ -5,6 +5,7 @@ - FEATURE: Allow user to change DHT port - I18N: Added Finnish translation - BUGFIX: Made right click menu work for multiple selection in DL list + - BUGFIX: Fixed utf-8 support in paths and filenames - COSMETIC: Replaced OSD messages by systray messages - COSMETIC: Displaying save path in torrent properties window - COSMETIC: Reworked options window a little diff --git a/src/GUI.cpp b/src/GUI.cpp index 4cfe6b563..fd5dd3c91 100644 --- a/src/GUI.cpp +++ b/src/GUI.cpp @@ -863,7 +863,7 @@ void GUI::saveColWidthDLList() const{ width_list << QString(misc::toString(downloadList->columnWidth(i)).c_str()); } if(lastDLListWidth.open(QIODevice::WriteOnly | QIODevice::Text)){ - lastDLListWidth.write(QByteArray(width_list.join(" ").toStdString().c_str())); + lastDLListWidth.write(width_list.join(" ").toAscii()); lastDLListWidth.close(); qDebug("Columns width saved"); }else{ @@ -910,7 +910,7 @@ void GUI::saveColWidthSearchList() const{ width_list << QString(misc::toString(resultsBrowser->columnWidth(i)).c_str()); } if(lastSearchListWidth.open(QIODevice::WriteOnly | QIODevice::Text)){ - lastSearchListWidth.write(QByteArray(width_list.join(" ").toStdString().c_str())); + lastSearchListWidth.write(width_list.join(" ").toAscii()); lastSearchListWidth.close(); qDebug("Columns width saved in search list"); }else{ @@ -1017,7 +1017,7 @@ void GUI::closeEvent(QCloseEvent *e){ if(DHTEnabled){ try{ entry dht_state = s->dht_state(); - boost::filesystem::ofstream out(misc::qBittorrentPath().toStdString()+"dht_state", std::ios_base::binary); + boost::filesystem::ofstream out((const char*)(misc::qBittorrentPath()+QString("dht_state")).toUtf8(), std::ios_base::binary); out.unsetf(std::ios_base::skipws); bencode(std::ostream_iterator(out), dht_state); }catch (std::exception& e){ @@ -1114,7 +1114,7 @@ void GUI::askForTorrents(){ lastDirFile.open(QIODevice::WriteOnly | QIODevice::Text); QStringList top_dir = pathsList.at(0).split(QDir::separator()); top_dir.removeLast(); - lastDirFile.write(QByteArray(top_dir.join(QDir::separator()).toStdString().c_str())); + lastDirFile.write(top_dir.join(QDir::separator()).toUtf8()); lastDirFile.close(); } } @@ -1150,7 +1150,7 @@ void GUI::scanDirectory(){ void GUI::saveFastResumeData() const{ qDebug("Saving fast resume data"); - std::string file; + QString file; QDir torrentBackup(misc::qBittorrentPath() + "BT_backup"); // Checking if torrentBackup Dir exists // create it if it is not @@ -1163,14 +1163,14 @@ void GUI::saveFastResumeData() const{ h.pause(); // Extracting resume data if (h.has_metadata()){ - QString filename = QString(h.get_torrent_info().name().c_str()); - if(QFile::exists(torrentBackup.path()+QDir::separator()+filename+".torrent")){ + QString fileName = QString(h.get_torrent_info().name().c_str()); + if(QFile::exists(torrentBackup.path()+QDir::separator()+fileName+".torrent")){ // Remove old .fastresume data in case it exists - QFile::remove(filename + ".fastresume"); + QFile::remove(fileName + ".fastresume"); // Write fast resume data entry resumeData = h.write_resume_data(); - file = filename.toStdString() + ".fastresume"; - boost::filesystem::ofstream out(fs::path(torrentBackup.path().toStdString()) / file, std::ios_base::binary); + file = fileName + ".fastresume"; + boost::filesystem::ofstream out(fs::path((const char*)torrentBackup.path().toUtf8()) / (const char*)file.toUtf8(), std::ios_base::binary); out.unsetf(std::ios_base::skipws); bencode(std::ostream_iterator(out), resumeData); } @@ -1334,8 +1334,8 @@ void GUI::addTorrent(const QString& path, bool fromScanDir, const QString& from_ if(file.isEmpty()){ return; } - qDebug("Adding %s to download list", file.toStdString().c_str()); - std::ifstream in(file.toStdString().c_str(), std::ios_base::binary); + qDebug("Adding %s to download list", (const char*)file.toUtf8()); + std::ifstream in((const char*)file.toUtf8(), std::ios_base::binary); in.unsetf(std::ios_base::skipws); try{ // Decode torrent file @@ -1363,7 +1363,7 @@ void GUI::addTorrent(const QString& path, bool fromScanDir, const QString& from_ try{ std::stringstream strStream; strStream << t.name() << ".fastresume"; - boost::filesystem::ifstream resume_file(fs::path(torrentBackup.path().toStdString()) / strStream.str(), std::ios_base::binary); + boost::filesystem::ifstream resume_file(fs::path((const char*)torrentBackup.path().toUtf8()) / strStream.str(), std::ios_base::binary); resume_file.unsetf(std::ios_base::skipws); resume_data = bdecode(std::istream_iterator(resume_file), std::istream_iterator()); fastResume=true; @@ -1371,15 +1371,15 @@ void GUI::addTorrent(const QString& path, bool fromScanDir, const QString& from_ catch (fs::filesystem_error&) {} //qDebug("Got fast resume data"); } - //Get Save Path TODO: finish QString savePath = getSavePath(QString(t.name().c_str())); int row = DLListModel->rowCount(); // Adding files to bittorrent session + std::cout << "save path: " << (const char*)savePath.toUtf8() << "\n"; if(hasFilteredFiles(QString(t.name().c_str()))){ - h = s->add_torrent(t, fs::path(savePath.toStdString()), resume_data, false); + h = s->add_torrent(t, fs::path((const char*)savePath.toUtf8()), resume_data, false); qDebug("Full allocation mode"); }else{ - h = s->add_torrent(t, fs::path(savePath.toStdString()), resume_data, true); + h = s->add_torrent(t, fs::path((const char*)savePath.toUtf8()), resume_data, true); qDebug("Compact allocation mode"); } h.set_max_connections(60); @@ -1496,7 +1496,7 @@ QString GUI::getSavePath(QString fileName){ line = savepath_file.readAll(); savepath_file.close(); qDebug("Save path: %s", line.data()); - savePath = QString(line.data()); + savePath = QString::fromUtf8(line.data()); }else{ savePath = options->getSavePath(); } @@ -1505,7 +1505,7 @@ QString GUI::getSavePath(QString fileName){ QDir saveDir(savePath); if(!saveDir.exists()){ if(!saveDir.mkpath(saveDir.path())){ - std::cerr << "Couldn't create the save directory: " << saveDir.path().toStdString() +"\n"; + std::cerr << "Couldn't create the save directory: " << (const char*)saveDir.path().toUtf8() << "\n"; // TODO: handle this better return QDir::homePath(); } @@ -1516,7 +1516,7 @@ QString GUI::getSavePath(QString fileName){ void GUI::reloadTorrent(const torrent_handle &h, bool compact_mode){ QDir saveDir(options->getSavePath()), torrentBackup(misc::qBittorrentPath() + "BT_backup"); QString fileName = QString(h.get_torrent_info().name().c_str()); - qDebug("Reloading torrent: %s", fileName.toStdString().c_str()); + qDebug("Reloading torrent: %s", (const char*)fileName.toUtf8()); torrent_handle new_h; entry resumeData; torrent_info t = h.get_torrent_info(); @@ -1556,7 +1556,7 @@ void GUI::reloadTorrent(const torrent_handle &h, bool compact_mode){ std::cerr << "Error: Couldn't reload the torrent\n"; return; } - new_h = s->add_torrent(t, fs::path(saveDir.path().toStdString()), resumeData, compact_mode); + new_h = s->add_torrent(t, fs::path((const char*)saveDir.path().toUtf8()), resumeData, compact_mode); if(compact_mode){ qDebug("Using compact allocation mode"); }else{ @@ -1590,7 +1590,7 @@ void GUI::reloadTorrent(const torrent_handle &h, bool compact_mode){ } // Incremental download if(QFile::exists(misc::qBittorrentPath()+"BT_backup"+QDir::separator()+fileName+".incremental")){ - qDebug("Incremental download enabled for %s", fileName.toStdString().c_str()); + qDebug("Incremental download enabled for %s", (const char*)fileName.toUtf8()); new_h.set_sequenced_download_threshold(15); } } @@ -1686,7 +1686,7 @@ void GUI::configureSession(){ setGlobalRatio(options->getRatio()); // DHT (Trackerless) if(options->isDHTEnabled() && !DHTEnabled){ - boost::filesystem::ifstream dht_state_file(misc::qBittorrentPath().toStdString()+"dht_state", std::ios_base::binary); + boost::filesystem::ifstream dht_state_file((const char*)(misc::qBittorrentPath()+QString("dht_state")).toUtf8(), std::ios_base::binary); dht_state_file.unsetf(std::ios_base::skipws); entry dht_state; try{ @@ -2156,15 +2156,15 @@ void GUI::updateNova() const{ // ask user for action. void GUI::on_update_nova_button_clicked(){ CURL *curl; - std::string filePath; + QString filePath; qDebug("Checking for search plugin updates on qbittorrent.org"); // XXX: Trick to get a unique filename QTemporaryFile *tmpfile = new QTemporaryFile; if (tmpfile->open()) { - filePath = tmpfile->fileName().toStdString(); + filePath = tmpfile->fileName(); } delete tmpfile; - FILE *file = fopen(filePath.c_str(), "w"); + FILE *file = fopen((const char*)filePath.toUtf8(), "w"); if(!file){ std::cerr << "Error: could not open temporary file...\n"; } @@ -2190,12 +2190,12 @@ void GUI::on_update_nova_button_clicked(){ curl_easy_cleanup(curl); // Close tmp file fclose(file); - qDebug("Version on qbittorrent.org: %f", getNovaVersion(QString(filePath.c_str()))); - float version_on_server = getNovaVersion(QString(filePath.c_str())); + qDebug("Version on qbittorrent.org: %f", getNovaVersion(filePath)); + float version_on_server = getNovaVersion(filePath); if(version_on_server == 0.0){ //First server is down, try mirror - QFile::remove(filePath.c_str()); - FILE *file = fopen(filePath.c_str(), "w"); + QFile::remove(filePath); + FILE *file = fopen((const char*)filePath.toUtf8(), "w"); if(!file){ std::cerr << "Error: could not open temporary file...\n"; } @@ -2214,19 +2214,19 @@ void GUI::on_update_nova_button_clicked(){ curl_easy_cleanup(curl); // Close tmp file fclose(file); - version_on_server = getNovaVersion(QString(filePath.c_str())); + version_on_server = getNovaVersion(filePath); } if(version_on_server > getNovaVersion(misc::qBittorrentPath()+"nova.py")){ if(QMessageBox::question(this, tr("Search plugin update -- qBittorrent"), - tr("Search plugin can be updated, do you want to update it?\n\nChangelog:\n")+QString(getNovaChangelog(QString(filePath.c_str())).data()), + tr("Search plugin can be updated, do you want to update it?\n\nChangelog:\n")+getNovaChangelog(filePath), tr("&Yes"), tr("&No"), QString(), 0, 1)){ return; }else{ qDebug("Updating search plugin from qbittorrent.org"); QFile::remove(misc::qBittorrentPath()+"nova.py"); - QFile::copy(QString(filePath.c_str()), misc::qBittorrentPath()+"nova.py"); + QFile::copy(filePath, misc::qBittorrentPath()+"nova.py"); QFile::Permissions perm=QFile::ReadOwner | QFile::WriteOwner | QFile::ExeOwner | QFile::ReadUser | QFile::WriteUser | QFile::ExeUser | QFile::ReadGroup | QFile::ReadGroup; QFile(misc::qBittorrentPath()+"nova.py").setPermissions(perm); } @@ -2240,7 +2240,7 @@ void GUI::on_update_nova_button_clicked(){ } } // Delete tmp file - QFile::remove(filePath.c_str()); + QFile::remove(filePath); } // Slot called when search is Finished diff --git a/src/createtorrent_imp.cpp b/src/createtorrent_imp.cpp index 237f76d56..1b494a504 100644 --- a/src/createtorrent_imp.cpp +++ b/src/createtorrent_imp.cpp @@ -99,8 +99,8 @@ void createtorrent::on_createButton_clicked(){ int piece_size = 256 * 1024; try { torrent_info t; - path full_path = complete(path(input.toStdString().c_str())); - ofstream out(complete(path(destination.toStdString().c_str())), std::ios_base::binary); + path full_path = complete(path((const char*)input.toUtf8())); + ofstream out(complete(path((const char*)destination.toUtf8())), std::ios_base::binary); add_files(t, full_path.branch_path(), full_path.leaf()); t.set_piece_size(piece_size); @@ -108,7 +108,7 @@ void createtorrent::on_createButton_clicked(){ storage st(t, full_path.branch_path()); QStringList trackers = txt_announce->toPlainText().split('\n'); for(int i=0; itoPlainText().toStdString().c_str()); + t.set_comment((const char*)txt_comment->toPlainText().toUtf8()); // create the torrent and print it to out entry e = t.create_torrent(); libtorrent::bencode(std::ostream_iterator(out), e); diff --git a/src/downloadThread.h b/src/downloadThread.h index fa2c8295e..1f1596731 100644 --- a/src/downloadThread.h +++ b/src/downloadThread.h @@ -68,15 +68,15 @@ class downloadThread : public QThread { mutex.unlock(); qDebug("In Download thread RUN, mutex unlocked (got url)"); CURL *curl; - std::string filePath; + QString filePath; int return_code, response; // XXX: Trick to get a unique filename QTemporaryFile *tmpfile = new QTemporaryFile; if (tmpfile->open()) { - filePath = tmpfile->fileName().toStdString(); + filePath = tmpfile->fileName(); } delete tmpfile; - FILE *file = fopen(filePath.c_str(), "w"); + FILE *file = fopen((const char*)filePath.toUtf8(), "w"); if(!file){ std::cerr << "Error: could not open temporary file...\n"; return; @@ -88,10 +88,9 @@ class downloadThread : public QThread { fclose(file); return; } - std::string urlString = url.toStdString(); // Set url to download - curl_easy_setopt(curl, CURLOPT_URL, urlString.c_str()); - qDebug("Url: %s", urlString.c_str()); + curl_easy_setopt(curl, CURLOPT_URL, (const char*)url.toUtf8()); + qDebug("Url: %s", (const char*)url.toUtf8()); // Define our callback to get called when there's data to be written curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, misc::my_fwrite); // Set destination file @@ -116,7 +115,7 @@ class downloadThread : public QThread { if(return_code){ std::cerr << "Error: failed to set error buffer in curl\n"; fclose(file); - QFile::remove(filePath.c_str()); + QFile::remove(filePath); return; } unsigned short retries = 0; @@ -137,7 +136,7 @@ class downloadThread : public QThread { curl_easy_cleanup(curl); // Close tmp file fclose(file); - emit downloadFinished(url, QString(filePath.c_str()), return_code, QString(errorBuffer)); + emit downloadFinished(url, filePath, return_code, QString(errorBuffer)); qDebug("In Download thread RUN, signal emitted, ErrorBuffer: %s", errorBuffer); }else{ mutex.unlock(); diff --git a/src/main.cpp b/src/main.cpp index 1bbb849f4..4f5b82afc 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -124,7 +124,7 @@ int main(int argc, char *argv[]){ bool isLocalized = false; // Open options file to read locale QString optionsPath = misc::qBittorrentPath()+"options.xml"; - FILE *f = fopen(optionsPath.toStdString().c_str(), "r"); + FILE *f = fopen((const char*)optionsPath.toUtf8(), "r"); if(f){ if (file.open(f, QIODevice::ReadOnly | QIODevice::Text)){ if (doc.setContent(&file)) { @@ -145,9 +145,9 @@ int main(int argc, char *argv[]){ locale = QLocale::system().name(); } if(translator.load(QString(":/lang/qbittorrent_") + locale)){ - qDebug("%s locale recognized, using translation.", locale.toStdString().c_str()); + qDebug("%s locale recognized, using translation.", (const char*)locale.toUtf8()); }else{ - qDebug("%s locale unrecognized, using default (en_GB).", locale.toStdString().c_str()); + qDebug("%s locale unrecognized, using default (en_GB).", (const char*)locale.toUtf8()); } app.installTranslator(&translator); // Read torrents given on command line diff --git a/src/options_imp.cpp b/src/options_imp.cpp index 00534c225..d5ec55b86 100644 --- a/src/options_imp.cpp +++ b/src/options_imp.cpp @@ -324,19 +324,19 @@ bool options_imp::saveOptions(){ tag.appendChild(optionValue); xml = doc.toString(); // Write XML file to HD - f = fopen(savePath.toStdString().c_str(), "w"); + f = fopen((const char*)savePath.toUtf8(), "w"); if (!f){ - std::cerr << "Error: Couldn't create file " << savePath.toStdString() << " for saving!" << '\n'; + std::cerr << "Error: Couldn't create file " << (const char*)savePath.toUtf8() << " for saving!" << '\n'; return false; } if (!file.open(f, QIODevice::WriteOnly | QIODevice::Text)){ - std::cerr << "Error: Couldn't open file " << savePath.toStdString() << " for saving!" << '\n'; + std::cerr << "Error: Couldn't open file " << (const char*)savePath.toUtf8() << " for saving!" << '\n'; return false; } - file.write(xml.toStdString().c_str(), xml.length()); + file.write((const char*)xml.toUtf8(), xml.length()); file.close(); if(fclose(f) == EOF){ - std::cerr << "Error: Couldn't close file " << savePath.toStdString() << " after saving!" << '\n'; + std::cerr << "Error: Couldn't close file " << (const char*)savePath.toUtf8() << " after saving!" << '\n'; return false; } // set infobar text @@ -365,7 +365,7 @@ bool options_imp::loadOptions(){ // Getting savepath for options.xml savePath = misc::qBittorrentPath() + "options.xml"; // Read XML file on HD - f = fopen(savePath.toStdString().c_str(), "r"); + f = fopen((const char*)savePath.toUtf8(), "r"); if (!f){ return false; } @@ -378,7 +378,7 @@ bool options_imp::loadOptions(){ } file.close(); if(fclose(f) == EOF){ - std::cerr << "Error: Couldn't close file " << savePath.toStdString() << " after reading!" << '\n'; + std::cerr << "Error: Couldn't close file " << (const char*)savePath.toUtf8() << " after reading!" << '\n'; return false; } // Loading option from XML diff --git a/src/src.pro b/src/src.pro index 0bb6fa65a..968e6cce1 100644 --- a/src/src.pro +++ b/src/src.pro @@ -29,6 +29,8 @@ CONFIG += link_pkgconfig PKGCONFIG += libtorrent QT += xml network +DEFINES += QT_NO_CAST_TO_ASCII + contains(DEBUG_MODE, 0){ contains(QT_VERSION, 4.2.0) { message(Qt 4.2.0 detected : enabling debug output because of a bug in this version of Qt) diff --git a/src/torrentAddition.h b/src/torrentAddition.h index 5d2b9daf4..f941cf93e 100644 --- a/src/torrentAddition.h +++ b/src/torrentAddition.h @@ -65,7 +65,7 @@ class torrentAdditionDialog : public QDialog, private Ui_addTorrentDialog{ home += QDir::separator(); } savePathTxt->setText(home+"qBT_dir"); - std::ifstream in(filePath.toStdString().c_str(), std::ios_base::binary); + std::ifstream in((const char*)filePath.toUtf8(), std::ios_base::binary); in.unsetf(std::ios_base::skipws); try{ // Decode torrent file @@ -204,7 +204,7 @@ class torrentAdditionDialog : public QDialog, private Ui_addTorrentDialog{ // Save savepath QFile savepath_file(misc::qBittorrentPath()+"BT_backup"+QDir::separator()+fileName+".savepath"); savepath_file.open(QIODevice::WriteOnly | QIODevice::Text); - savepath_file.write(QByteArray(savePath.path().toStdString().c_str())); + savepath_file.write(savePath.path().toUtf8()); savepath_file.close(); // Create .incremental file if necessary if(checkIncrementalDL->isChecked()){ diff --git a/src/trackerLogin.h b/src/trackerLogin.h index 256acc34c..cb834af01 100644 --- a/src/trackerLogin.h +++ b/src/trackerLogin.h @@ -54,7 +54,7 @@ class trackerLogin : public QDialog, private Ui::authentication{ public slots: void on_loginButton_clicked(){ // login - h.set_tracker_login(lineUsername->text().toStdString(), linePasswd->text().toStdString()); + h.set_tracker_login(std::string((const char*)lineUsername->text().toUtf8()), std::string((const char*)linePasswd->text().toUtf8())); close(); }