Qt: Add and use qUtf8Printable.

Qt 5.4 introduced qUtf8Printable, a convenience macro for converting
QString to a UTF-8 const char *. Add a compatibility definition and
start using it.

Change-Id: I3cf88611b1ed1a34082cb2ba82394954e2e6c461
Reviewed-on: https://code.wireshark.org/review/24828
Petri-Dish: Gerald Combs <gerald@wireshark.org>
Tested-by: Petri Dish Buildbot
Reviewed-by: Gerald Combs <gerald@wireshark.org>
This commit is contained in:
Gerald Combs 2017-12-14 10:29:48 -08:00
parent 4cf7cd3ed2
commit db740987ff
6 changed files with 46 additions and 34 deletions

View File

@ -163,12 +163,19 @@ it's not strictly required:
===== Strings ===== Strings
If you're using GLib string functions or plain old C character array idioms in Wireshark's C code and GLib use UTF-8 encoded character arrays. Qt
Qt-only code you're probably doing something wrong. QStrings are generally (specifically QString) uses UTF-16. You can convert a `char *` to a
*much* safer and easier to use. They also make translations easier. `QString` using simple assignment. You can convert a `QString` to a
`const char *` using `qUtf8Printable`.
If you're using GLib string functions or plain old C character array
idioms in Qt-only code you're probably doing something wrong,
particularly if you're manually allocating and releasing memory.
QStrings are generally *much* safer and easier to use. They also make
translations easier.
If you need to pass strings between Qt and GLib you can use a number If you need to pass strings between Qt and GLib you can use a number
of convenience routines which are defined in 'ui/qt/qt_ui_utils.h'. of convenience routines which are defined in 'ui/qt/qt_ui_utils.h'.
If you're calling a function that returns wmem-allocated memory it might make If you're calling a function that returns wmem-allocated memory it might make
more sense to add a wrapper function to 'qt_ui_utils' than to call wmem_free in more sense to add a wrapper function to 'qt_ui_utils' than to call wmem_free in

View File

@ -1284,7 +1284,7 @@ void MainWindow::mergeCaptureFile()
if (merge_dlg.merge(file_name)) { if (merge_dlg.merge(file_name)) {
gchar *err_msg; gchar *err_msg;
if (!dfilter_compile(read_filter.toUtf8().constData(), &rfcode, &err_msg)) { if (!dfilter_compile(qUtf8Printable(read_filter), &rfcode, &err_msg)) {
/* Not valid. Tell the user, and go back and run the file /* Not valid. Tell the user, and go back and run the file
selection box again once they dismiss the alert. */ selection box again once they dismiss the alert. */
// Similar to commandline_info.jfilter section in main(). // Similar to commandline_info.jfilter section in main().
@ -1455,7 +1455,7 @@ bool MainWindow::saveCaptureFile(capture_file *cf, bool dont_reopen) {
closes the current file and then opens and reloads the saved file, closes the current file and then opens and reloads the saved file,
so make a copy and free it later. */ so make a copy and free it later. */
file_name = cf->filename; file_name = cf->filename;
status = cf_save_records(cf, file_name.toUtf8().constData(), cf->cd_t, cf->iscompressed, status = cf_save_records(cf, qUtf8Printable(file_name), cf->cd_t, cf->iscompressed,
discard_comments, dont_reopen); discard_comments, dont_reopen);
switch (status) { switch (status) {
@ -1545,14 +1545,14 @@ bool MainWindow::saveAsCaptureFile(capture_file *cf, bool must_support_comments,
//#ifndef _WIN32 //#ifndef _WIN32
// /* If the file exists and it's user-immutable or not writable, // /* If the file exists and it's user-immutable or not writable,
// ask the user whether they want to override that. */ // ask the user whether they want to override that. */
// if (!file_target_unwritable_ui(top_level, file_name.toUtf8().constData())) { // if (!file_target_unwritable_ui(top_level, qUtf8Printable(file_name))) {
// /* They don't. Let them try another file name or cancel. */ // /* They don't. Let them try another file name or cancel. */
// continue; // continue;
// } // }
//#endif //#endif
/* Attempt to save the file */ /* Attempt to save the file */
status = cf_save_records(cf, file_name.toUtf8().constData(), file_type, compressed, status = cf_save_records(cf, qUtf8Printable(file_name), file_type, compressed,
discard_comments, dont_reopen); discard_comments, dont_reopen);
switch (status) { switch (status) {
@ -1570,7 +1570,7 @@ bool MainWindow::saveAsCaptureFile(capture_file *cf, bool must_support_comments,
cf->unsaved_changes = false; //we just saved so we signal that we have no unsaved changes cf->unsaved_changes = false; //we just saved so we signal that we have no unsaved changes
updateForUnsavedChanges(); // we update the title bar to remove the * updateForUnsavedChanges(); // we update the title bar to remove the *
/* Add this filename to the list of recent files in the "Recent Files" submenu */ /* Add this filename to the list of recent files in the "Recent Files" submenu */
add_menu_recent_capture_file(file_name.toUtf8().constData()); add_menu_recent_capture_file(qUtf8Printable(file_name));
return true; return true;
case CF_WRITE_ERROR: case CF_WRITE_ERROR:
@ -1647,9 +1647,9 @@ void MainWindow::exportSelectedPackets() {
* name and the read file name may be relative (if supplied on * name and the read file name may be relative (if supplied on
* the command line). From Joerg Mayer. * the command line). From Joerg Mayer.
*/ */
if (files_identical(capture_file_.capFile()->filename, file_name.toUtf8().constData())) { if (files_identical(capture_file_.capFile()->filename, qUtf8Printable(file_name))) {
QMessageBox msg_box; QMessageBox msg_box;
gchar *display_basename = g_filename_display_basename(file_name.toUtf8().constData()); gchar *display_basename = g_filename_display_basename(qUtf8Printable(file_name));
msg_box.setIcon(QMessageBox::Critical); msg_box.setIcon(QMessageBox::Critical);
msg_box.setText(QString(tr("Unable to export to \"%1\".").arg(display_basename))); msg_box.setText(QString(tr("Unable to export to \"%1\".").arg(display_basename)));
@ -1668,14 +1668,14 @@ void MainWindow::exportSelectedPackets() {
//#ifndef _WIN32 //#ifndef _WIN32
// /* If the file exists and it's user-immutable or not writable, // /* If the file exists and it's user-immutable or not writable,
// ask the user whether they want to override that. */ // ask the user whether they want to override that. */
// if (!file_target_unwritable_ui(top_level, file_name.toUtf8().constData())) { // if (!file_target_unwritable_ui(top_level, qUtf8Printable(file_name))) {
// /* They don't. Let them try another file name or cancel. */ // /* They don't. Let them try another file name or cancel. */
// continue; // continue;
// } // }
//#endif //#endif
/* Attempt to save the file */ /* Attempt to save the file */
status = cf_export_specified_packets(capture_file_.capFile(), file_name.toUtf8().constData(), &range, file_type, compressed); status = cf_export_specified_packets(capture_file_.capFile(), qUtf8Printable(file_name), &range, file_type, compressed);
switch (status) { switch (status) {
case CF_WRITE_OK: case CF_WRITE_OK:
@ -1689,7 +1689,7 @@ void MainWindow::exportSelectedPackets() {
if (discard_comments) if (discard_comments)
packet_list_queue_draw(); packet_list_queue_draw();
/* Add this filename to the list of recent files in the "Recent Files" submenu */ /* Add this filename to the list of recent files in the "Recent Files" submenu */
add_menu_recent_capture_file(file_name.toUtf8().constData()); add_menu_recent_capture_file(qUtf8Printable(file_name));
return; return;
case CF_WRITE_ERROR: case CF_WRITE_ERROR:
@ -2858,7 +2858,7 @@ void MainWindow::removeAdditionalToolbar(QString toolbarName)
AdditionalToolBar *ifToolBar = dynamic_cast<AdditionalToolBar *>(tb); AdditionalToolBar *ifToolBar = dynamic_cast<AdditionalToolBar *>(tb);
if (ifToolBar && ifToolBar->menuName().compare(toolbarName)) { if (ifToolBar && ifToolBar->menuName().compare(toolbarName)) {
GList *entry = g_list_find_custom(recent.gui_additional_toolbars, ifToolBar->menuName().toStdString().c_str(), (GCompareFunc) strcmp); GList *entry = g_list_find_custom(recent.gui_additional_toolbars, qUtf8Printable(ifToolBar->menuName()), (GCompareFunc) strcmp);
if (entry) { if (entry) {
recent.gui_additional_toolbars = g_list_remove(recent.gui_additional_toolbars, entry->data); recent.gui_additional_toolbars = g_list_remove(recent.gui_additional_toolbars, entry->data);
} }

View File

@ -223,7 +223,7 @@ bool MainWindow::openCaptureFile(QString cf_path, QString read_filter, unsigned
goto finish; goto finish;
} }
if (dfilter_compile(read_filter.toUtf8().constData(), &rfcode, &err_msg)) { if (dfilter_compile(qUtf8Printable(read_filter), &rfcode, &err_msg)) {
cf_set_rfcode(CaptureFile::globalCapFile(), rfcode); cf_set_rfcode(CaptureFile::globalCapFile(), rfcode);
} else { } else {
/* Not valid. Tell the user, and go back and run the file /* Not valid. Tell the user, and go back and run the file
@ -249,7 +249,7 @@ bool MainWindow::openCaptureFile(QString cf_path, QString read_filter, unsigned
/* Try to open the capture file. This closes the current file if it succeeds. */ /* Try to open the capture file. This closes the current file if it succeeds. */
CaptureFile::globalCapFile()->window = this; CaptureFile::globalCapFile()->window = this;
if (cf_open(CaptureFile::globalCapFile(), cf_path.toUtf8().constData(), type, is_tempfile, &err) != CF_OK) { if (cf_open(CaptureFile::globalCapFile(), qUtf8Printable(cf_path), type, is_tempfile, &err) != CF_OK) {
/* We couldn't open it; don't dismiss the open dialog box, /* We couldn't open it; don't dismiss the open dialog box,
just leave it around so that the user can, after they just leave it around so that the user can, after they
dismiss the alert box popped up for the open error, dismiss the alert box popped up for the open error,
@ -514,7 +514,7 @@ void MainWindow::layoutToolbars()
AdditionalToolBar *iftoolbar = dynamic_cast<AdditionalToolBar *>(bar); AdditionalToolBar *iftoolbar = dynamic_cast<AdditionalToolBar *>(bar);
if (iftoolbar) { if (iftoolbar) {
bool visible = false; bool visible = false;
if (g_list_find_custom(recent.gui_additional_toolbars, iftoolbar->menuName().toUtf8().constData(), (GCompareFunc) strcmp)) if (g_list_find_custom(recent.gui_additional_toolbars, qUtf8Printable(iftoolbar->menuName()), (GCompareFunc) strcmp))
visible = true; visible = true;
iftoolbar->setVisible(visible); iftoolbar->setVisible(visible);
@ -1909,23 +1909,23 @@ void MainWindow::on_actionFileExportPacketBytes_triggered()
data_p = tvb_get_ptr(capture_file_.capFile()->finfo_selected->ds_tvb, 0, -1) + data_p = tvb_get_ptr(capture_file_.capFile()->finfo_selected->ds_tvb, 0, -1) +
capture_file_.capFile()->finfo_selected->start; capture_file_.capFile()->finfo_selected->start;
fd = ws_open(file_name.toUtf8().constData(), O_WRONLY|O_CREAT|O_TRUNC|O_BINARY, 0666); fd = ws_open(qUtf8Printable(file_name), O_WRONLY|O_CREAT|O_TRUNC|O_BINARY, 0666);
if (fd == -1) { if (fd == -1) {
open_failure_alert_box(file_name.toUtf8().constData(), errno, TRUE); open_failure_alert_box(qUtf8Printable(file_name), errno, TRUE);
return; return;
} }
if (ws_write(fd, data_p, capture_file_.capFile()->finfo_selected->length) < 0) { if (ws_write(fd, data_p, capture_file_.capFile()->finfo_selected->length) < 0) {
write_failure_alert_box(file_name.toUtf8().constData(), errno); write_failure_alert_box(qUtf8Printable(file_name), errno);
ws_close(fd); ws_close(fd);
return; return;
} }
if (ws_close(fd) < 0) { if (ws_close(fd) < 0) {
write_failure_alert_box(file_name.toUtf8().constData(), errno); write_failure_alert_box(qUtf8Printable(file_name), errno);
return; return;
} }
/* Save the directory name for future file dialogs. */ /* Save the directory name for future file dialogs. */
wsApp->setLastOpenDir(&file_name); wsApp->setLastOpenDir(file_name);
} }
} }
@ -1982,9 +1982,9 @@ void MainWindow::on_actionFileExportSSLSessionKeys_triggered()
int fd; int fd;
keylist = ssl_export_sessions(); keylist = ssl_export_sessions();
fd = ws_open(file_name.toUtf8().constData(), O_WRONLY|O_CREAT|O_TRUNC|O_BINARY, 0666); fd = ws_open(qUtf8Printable(file_name), O_WRONLY|O_CREAT|O_TRUNC|O_BINARY, 0666);
if (fd == -1) { if (fd == -1) {
open_failure_alert_box(file_name.toUtf8().constData(), errno, TRUE); open_failure_alert_box(qUtf8Printable(file_name), errno, TRUE);
g_free(keylist); g_free(keylist);
return; return;
} }
@ -1993,19 +1993,19 @@ void MainWindow::on_actionFileExportSSLSessionKeys_triggered()
* _write(). Presumably this string will be <= 4GiB long.... * _write(). Presumably this string will be <= 4GiB long....
*/ */
if (ws_write(fd, keylist, (unsigned int)strlen(keylist)) < 0) { if (ws_write(fd, keylist, (unsigned int)strlen(keylist)) < 0) {
write_failure_alert_box(file_name.toUtf8().constData(), errno); write_failure_alert_box(qUtf8Printable(file_name), errno);
ws_close(fd); ws_close(fd);
g_free(keylist); g_free(keylist);
return; return;
} }
if (ws_close(fd) < 0) { if (ws_close(fd) < 0) {
write_failure_alert_box(file_name.toUtf8().constData(), errno); write_failure_alert_box(qUtf8Printable(file_name), errno);
g_free(keylist); g_free(keylist);
return; return;
} }
/* Save the directory name for future file dialogs. */ /* Save the directory name for future file dialogs. */
wsApp->setLastOpenDir(&file_name); wsApp->setLastOpenDir(file_name);
g_free(keylist); g_free(keylist);
} }
} }
@ -4135,8 +4135,8 @@ void MainWindow::filterDropped(QString description, QString filter)
if ( filter.length() == 0 ) if ( filter.length() == 0 )
return; return;
filter_expression_new(description.toUtf8().constData(), filter_expression_new(qUtf8Printable(description),
filter.toUtf8().constData(), description.toUtf8().constData(), TRUE); qUtf8Printable(filter), qUtf8Printable(description), TRUE);
uat_save(uat_get_table_by_name("Display expressions"), &err); uat_save(uat_get_table_by_name("Display expressions"), &err);
g_free(err); g_free(err);

View File

@ -59,6 +59,11 @@ struct epan_range;
#define Q_NULLPTR NULL #define Q_NULLPTR NULL
#endif #endif
// Introduced in Qt 5.4
#ifndef qUtf8Printable
#define qUtf8Printable(str) str.toUtf8().constData()
#endif
/** Create a glib-compatible copy of a QString. /** Create a glib-compatible copy of a QString.
* *
* @param q_string A QString. * @param q_string A QString.

View File

@ -220,7 +220,7 @@ extern "C" void menu_recent_file_write_all(FILE *rf) {
/* get capture filename from the menu item label */ /* get capture filename from the menu item label */
cf_name = rii.previous()->filename; cf_name = rii.previous()->filename;
if (cf_name != NULL) { if (cf_name != NULL) {
fprintf (rf, RECENT_KEY_CAPTURE_FILE ": %s\n", cf_name.toUtf8().constData()); fprintf (rf, RECENT_KEY_CAPTURE_FILE ": %s\n", qUtf8Printable(cf_name));
} }
} }
} }
@ -281,8 +281,8 @@ QDir WiresharkApplication::lastOpenDir() {
return QDir(last_open_dir); return QDir(last_open_dir);
} }
void WiresharkApplication::setLastOpenDir(QString *dir_str) { void WiresharkApplication::setLastOpenDir(QString dir_str) {
setLastOpenDir(dir_str->toUtf8().constData()); setLastOpenDir(qUtf8Printable(dir_str));
} }
void WiresharkApplication::helpTopicAction(topic_action_e action) void WiresharkApplication::helpTopicAction(topic_action_e action)

View File

@ -109,7 +109,7 @@ public:
void removeRecentItem(const QString &filename); void removeRecentItem(const QString &filename);
QDir lastOpenDir(); QDir lastOpenDir();
void setLastOpenDir(const char *dir_name); void setLastOpenDir(const char *dir_name);
void setLastOpenDir(QString *dir_str); void setLastOpenDir(QString dir_str);
void helpTopicAction(topic_action_e action); void helpTopicAction(topic_action_e action);
const QFont monospaceFont() const { return mono_font_; } const QFont monospaceFont() const { return mono_font_; }
void setMonospaceFont(const char *font_string); void setMonospaceFont(const char *font_string);