diff --git a/private/lib/windows/x86_64/rktwebview.dll b/private/lib/windows/x86_64/rktwebview.dll index 49f11b4..3db76d5 100644 Binary files a/private/lib/windows/x86_64/rktwebview.dll and b/private/lib/windows/x86_64/rktwebview.dll differ diff --git a/private/lib/windows/x86_64/rktwebview_prg.exe b/private/lib/windows/x86_64/rktwebview_prg.exe index 9ac1f7b..b4d357e 100644 Binary files a/private/lib/windows/x86_64/rktwebview_prg.exe and b/private/lib/windows/x86_64/rktwebview_prg.exe differ diff --git a/private/lib/windows/x86_64/rktwebview_test.exe b/private/lib/windows/x86_64/rktwebview_test.exe index 93ebe2c..5041230 100644 Binary files a/private/lib/windows/x86_64/rktwebview_test.exe and b/private/lib/windows/x86_64/rktwebview_test.exe differ diff --git a/private/racket-webview.rkt b/private/racket-webview.rkt index c6111b9..e986420 100644 --- a/private/racket-webview.rkt +++ b/private/racket-webview.rkt @@ -655,7 +655,7 @@ (define (webview-call-js wv js) (-> wv-win? string? (or/c string? list? boolean? hash?)) (let ((result (rkt-webview-call-js (wv-win-handle wv) js))) - (displayln result) + ;(displayln result) (if (webview-call-js-result? result) (if (eq? (car result) 'oke) (hash-ref (fromJson (cadr result)) 'result #f) diff --git a/rktwebview_qt/CMakeLists.txt b/rktwebview_qt/CMakeLists.txt index 48bc0b1..e1d4bb3 100644 --- a/rktwebview_qt/CMakeLists.txt +++ b/rktwebview_qt/CMakeLists.txt @@ -22,6 +22,7 @@ add_library(rktwebview SHARED rktwebview_types.h json.cpp json.h utils.h + utils.cpp ) add_executable(rktwebview_prg @@ -40,6 +41,7 @@ add_executable(rktwebview_prg rkt_protocol.h rktwebview_types.h + utils.cpp utils.h ) add_executable(rktwebview_test diff --git a/rktwebview_qt/command.h b/rktwebview_qt/command.h index 26d3ada..e29fa64 100644 --- a/rktwebview_qt/command.h +++ b/rktwebview_qt/command.h @@ -27,6 +27,7 @@ #define COMMAND_FILE_SAVE 21 #define COMMAND_SET_OU_TOKEN 22 #define COMMAND_NEW_CONTEXT 23 +#define COMMAND_MESSAGE 24 class Command { diff --git a/rktwebview_qt/main.cpp b/rktwebview_qt/main.cpp index ebf7a7c..86f82ec 100644 --- a/rktwebview_qt/main.cpp +++ b/rktwebview_qt/main.cpp @@ -6,6 +6,7 @@ #include "shm.h" #include "shmqueue.h" #include "command.h" +#include "utils.h" #include #include @@ -23,7 +24,7 @@ static void free_data(rkt_data_t *d) free(d->data.js_result.value); free(d); } else { - fprintf(stderr, "UNEXPECTED: data kind %d cannot be freed\n", d->kind); + ERROR1("UNEXPECTED: data kind %d cannot be freed\n", d->kind); } } @@ -62,10 +63,10 @@ int main(int argc, char *argv[]) { const char *me = argv[0]; - fprintf(stderr, "%s runs\n", argv[0]);fflush(stderr); + INFO1("%s runs\n", argv[0]); if (argc < 6) { - fprintf(stderr, "%s: wrong number of arguments\n", me);fflush(stderr); + ERROR1("%s: wrong number of arguments\n", me); exit(1); } @@ -80,11 +81,11 @@ int main(int argc, char *argv[]) int res_slot = atoi(res_slot_str); int evt_slot = atoi(evt_slot_str); - fprintf(stderr, "%s %s %s %s %s %s\n", me, shm_name, shm_size_str, cmd_slot_str, res_slot_str, evt_slot_str);fflush(stderr); - fprintf(stderr, "%s %s %ld %d %d %d\n", me, shm_name, shm_size, cmd_slot, res_slot, evt_slot);fflush(stderr); + MKLOGSTMT(LOG_INFO, fprintf(stderr, "%s %s %s %s %s %s\n", me, shm_name, shm_size_str, cmd_slot_str, res_slot_str, evt_slot_str)); + MKLOGSTMT(LOG_INFO, fprintf(stderr, "%s %s %ld %d %d %d\n", me, shm_name, shm_size, cmd_slot, res_slot, evt_slot)); if (!(shm_size > 0 && cmd_slot > 0 && res_slot > 0 && evt_slot > 0)) { - fprintf(stderr, "%s: Invalid shm size or slots\n", me);fflush(stderr); + ERROR1("%s: Invalid shm size or slots\n", me); exit(2); } @@ -100,10 +101,10 @@ int main(int argc, char *argv[]) handler->webview_handler->initApp(); handler->webview_handler->execApp(); - fprintf(stderr, "waiting for thread to end\n");fflush(stderr); + INFO0("waiting for thread to end\n"); handler->wait(); - fprintf(stderr, "cleaning up shm\n");fflush(stderr); + INFO0("cleaning up shm\n"); delete handler->webview_handler; delete handler->command_queue; @@ -126,9 +127,9 @@ void Handler::run() switch(cmd) { case CMD_QUIT: { - fprintf(stderr, "Got quit message\n"); + INFO0("Got quit message\n"); webview_handler->rktQuit(); - fprintf(stderr, "Enqueing RESULT_QUIT to result queue\n"); + INFO0("Enqueing RESULT_QUIT to result queue\n"); result_queue->enqueue(RESULT_QUIT); quit = true; } @@ -182,7 +183,6 @@ void Handler::run() } break; case CMD_CALL_JS: { - fprintf(stderr, "Calljs\n"); int wv = data_obj["wv"].toInt(); QString js = data_obj["js"].toString(); rkt_data_t *res = webview_handler->rktCallJs(wv, js.toUtf8().constData()); @@ -320,7 +320,7 @@ void Handler::run() } break; default: { - fprintf(stderr, "Unknown command: %d\n", cmd);fflush(stderr); + ERROR1("Unknown command: %d\n", cmd); } } } diff --git a/rktwebview_qt/rktwebview.cpp b/rktwebview_qt/rktwebview.cpp index 4d62fe5..716dbac 100644 --- a/rktwebview_qt/rktwebview.cpp +++ b/rktwebview_qt/rktwebview.cpp @@ -2,6 +2,7 @@ #include #include #include + #ifdef _WIN32 #include #include @@ -9,6 +10,7 @@ #include #include #endif + #include #include "rktwebview.h" #include "rkt_protocol.h" @@ -65,11 +67,11 @@ bool runRktWebview(Handle_t *handler) { char *rkt_webview_prg_path = getenv("RKT_WEBVIEW_PRG"); if (rkt_webview_prg_path == nullptr) { - fprintf(stderr, "RKT_WEBVIEW_PRG environment variable not set, cannot start webview program\n");fflush(stderr); + ERROR0("RKT_WEBVIEW_PRG environment variable not set, cannot start webview program\n"); return false; } if (!fileExists(rkt_webview_prg_path)) { - fprintf(stderr, "%s does not exist or is not executable\n", rkt_webview_prg_path);fflush(stderr); + ERROR1("%s does not exist or is not executable\n", rkt_webview_prg_path); return false; } @@ -88,36 +90,50 @@ bool runRktWebview(Handle_t *handler) // run rktwebview_prg using the environment variable RKT_WEBVIEW_PRG #ifdef _WIN32 - //STARTUPINFO si; - //PROCESS_INFORMATION pi; - //ZeroMemory( &si, sizeof(si) ); - //si.cb = sizeof(si); - //ZeroMemory( &pi, sizeof(pi) ); - - std::string cmdargs = std::string("") + handler->name + " " + shm_size_str + " " + command_slot + " " + command_result_slot + " " + event_slot; - std::string exe = std::string(rkt_webview_prg_path); - const char *td = getenv("TEMP"); if (td == nullptr) { td = "C:\\"; } std::string tmpdir = td; std::string logfile = tmpdir + "\\" + "rktwebview.log"; //handler->name + ".log"; - std::string errfile = tmpdir + "\\" + "rktwebview.err"; - std::string redirect = " ^>" + logfile + " 2^>" + errfile; - std::string cmdline = "start /b \"\" cmd /c \"" + exe + " " + cmdargs + " " + /*redirect*/ + "\"" + redirect; + + SECURITY_ATTRIBUTES sa; + sa.nLength = sizeof(sa); + sa.lpSecurityDescriptor = NULL; + sa.bInheritHandle = TRUE; + + HANDLE h = CreateFile(logfile.c_str(), + FILE_APPEND_DATA, + FILE_SHARE_WRITE | FILE_SHARE_READ, + &sa, + OPEN_ALWAYS, + FILE_ATTRIBUTE_NORMAL, + NULL); + + STARTUPINFO si; + PROCESS_INFORMATION pi; + ZeroMemory( &si, sizeof(si) ); + ZeroMemory( &pi, sizeof(pi) ); + + si.cb = sizeof(si); + si.dwFlags |= STARTF_USESTDHANDLES; + si.hStdInput= NULL; + si.hStdOutput = h; + si.hStdError = h; + + DWORD flags = CREATE_NO_WINDOW | NORMAL_PRIORITY_CLASS; + + std::string cmdargs = std::string("") + handler->name + " " + shm_size_str + " " + command_slot + " " + command_result_slot + " " + event_slot; + std::string exe = std::string(rkt_webview_prg_path); + std::string dir = basedir(exe); + + std::string cmdline = exe + " " + cmdargs; char *cmdline_str = const_cast(cmdline.c_str()); - auto cwd = std::filesystem::current_path(); - std::filesystem::current_path(path); - int r = system(cmdline_str); - std::filesystem::current_path(cwd); - - //CreateProcessA(NULL, cmdline_str, NULL, NULL, FALSE, NORMAL_PRIORITY_CLASS, NULL, path.c_str(), &si, &pi); - handler->rkt_webview_prg_pid = 0; - if (r != 0) { - fprintf(stderr, "Cannot create process '%s' (error = %ld)\n", cmdline_str, GetLastError());fflush(stderr); + bool r = CreateProcessA(NULL, cmdline_str, NULL, NULL, TRUE, flags, NULL, path.c_str(), &si, &pi); + if (!r) { + ERROR2("Cannot create process '%s' (error = %ld)\n", cmdline_str, GetLastError()); } - return (r == 0); + return r; #else char *argv[] = { rkt_webview_prg_path, const_cast(handler->name.c_str()), shm_size_str, command_slot, command_result_slot, event_slot, nullptr }; @@ -161,16 +177,16 @@ void rkt_webview_cleanup() */ if (handler->valid) { - fprintf(stderr, "Sending quit message\n");fflush(stderr); + INFO0("Sending quit message\n"); handler->command_queue->enqueue(CMD_QUIT); - fprintf(stderr, "Message sent\n");fflush(stderr); + INFO0("Message sent\n"); bool stopped = false; while(!stopped) { int cmd; std::string s; - fprintf(stderr, "Getting result of quit message\n");fflush(stderr); + INFO0("Getting result of quit message\n"); handler->command_result_queue->dequeue(cmd, s, true); - fprintf(stderr, "got %d\n", cmd);fflush(stderr); + INFO1("got %d\n", cmd); if (cmd == RESULT_QUIT) { stopped = true; } @@ -481,7 +497,7 @@ void rkt_webview_free_data(rkt_data_t *d) free(d->data.js_result.value); free(d); } else { - fprintf(stderr, "UNEXPECTED: data kind %d cannot be freed\n", d->kind);fflush(stderr); + ERROR1("UNEXPECTED: data kind %d cannot be freed\n", d->kind); } } diff --git a/rktwebview_qt/rktwebview_qt.cpp b/rktwebview_qt/rktwebview_qt.cpp index dd99de1..94c426d 100644 --- a/rktwebview_qt/rktwebview_qt.cpp +++ b/rktwebview_qt/rktwebview_qt.cpp @@ -3,6 +3,7 @@ #include "rktwebview_types.h" #include "webviewwindow.h" #include "rktutils.h" +#include "utils.h" #include #include #include @@ -39,13 +40,13 @@ void Rktwebview_qt::processCommand(Command *cmd) bool has_pem = cmd->args[1].toBool(); QString optional_server_cert_pem = cmd->args[2].toString(); - fprintf(stderr, "bjs: %s\n", boilerplate_js.toUtf8().constData()); - fprintf(stderr, "oscp: %s\n", optional_server_cert_pem.toUtf8().constData()); + DEBUG1("bjs: %s\n", boilerplate_js.toUtf8().constData()); + DEBUG1("oscp: %s\n", optional_server_cert_pem.toUtf8().constData()); QWebEngineProfileBuilder b; if (has_pem) { QByteArray scp = optional_server_cert_pem.toUtf8(); - fprintf(stderr, "Installing cert: %s\n", scp.constData()); + INFO1("Installing cert: %s\n", scp.constData()); QList certs; QSslCertificate cert(scp); certs.append(cert); @@ -238,7 +239,7 @@ void Rktwebview_qt::processCommand(Command *cmd) QString js = cmd->args[1].toString(); if (_views.contains(wv)) { WebviewWindow *w = _views[wv]; - fprintf(stderr, "Running %s\n", js.toUtf8().constData()); + DEBUG1("Running %s\n", js.toUtf8().constData()); w->runJs(js); cmd->result = true; } else { @@ -377,19 +378,12 @@ void Rktwebview_qt::processCommand(Command *cmd) QString title = cmd->args[1].toString(); QString base_dir = cmd->args[2].toString(); if (_views.contains(wv)) { - WebviewWindow *w = _views[wv]; - QString dir = QFileDialog::getExistingDirectory(w, title, base_dir, QFileDialog::ShowDirsOnly | QFileDialog::DontResolveSymlinks); - if (dir == "") { - QJsonObject obj; - obj["state"] = "canceled"; - obj["dir"] = base_dir; - cmd->result = QString::fromUtf8(QJsonDocument(obj).toJson(QJsonDocument::JsonFormat::Compact)); - } else { - QJsonObject obj; - obj["state"] = "choosen"; - obj["dir"] = dir; - cmd->result = QString::fromUtf8(QJsonDocument(obj).toJson(QJsonDocument::JsonFormat::Compact)); - } + result_t r = fileDlg(wv, title, base_dir, "", + QFileDialog::Directory, QFileDialog::AcceptOpen, + "choose-dir-ok", "choose-dir-cancel" + ); + cmd->js_result_ok = true; + cmd->result = (r == result_t::oke); } else { cmd->js_result_ok = false; cmd->result = false; @@ -397,36 +391,57 @@ void Rktwebview_qt::processCommand(Command *cmd) cmd->done = true; } break; - case COMMAND_FILE_OPEN: + case COMMAND_FILE_OPEN: { + int wv = cmd->args[0].toInt(); + QString title = cmd->args[1].toString(); + QString base_dir = cmd->args[2].toString(); + QString exts = cmd->args[3].toString(); + if (_views.contains(wv)) { + result_t r = fileDlg(wv, title, base_dir, exts, + QFileDialog::ExistingFile, QFileDialog::AcceptOpen, + "file-open-ok", "file-open-cancel" + ); + cmd->js_result_ok = true; + cmd->result = (r == result_t::oke); + } else { + cmd->js_result_ok = true; + cmd->result = false; + } + cmd->done = true; + } + break; case COMMAND_FILE_SAVE: { int wv = cmd->args[0].toInt(); QString title = cmd->args[1].toString(); QString base_dir = cmd->args[2].toString(); QString exts = cmd->args[3].toString(); if (_views.contains(wv)) { - WebviewWindow *w = _views[wv]; - QString file; - QString selected_filter; - if (cmd->cmd == COMMAND_FILE_OPEN) { - file = QFileDialog::getOpenFileName(w, title, base_dir, exts, &selected_filter); - } else { - file = QFileDialog::getSaveFileName(w, title, base_dir, exts, &selected_filter); - } - if (file == "") { - QJsonObject obj; - obj["state"] = "canceled"; - obj["file"] = ""; - obj["used-filter"] = selected_filter; - cmd->result = QString::fromUtf8(QJsonDocument(obj).toJson(QJsonDocument::JsonFormat::Compact)); - } else { - QJsonObject obj; - obj["state"] = "choosen"; - obj["file"] = file; - obj["used-filter"] = selected_filter; - cmd->result = QString::fromUtf8(QJsonDocument(obj).toJson(QJsonDocument::JsonFormat::Compact)); - } + result_t r = fileDlg(wv, title, base_dir, exts, + QFileDialog::AnyFile, QFileDialog::AcceptSave, + "file-open-ok", "file-open-cancel" + ); + cmd->js_result_ok = true; + cmd->result = (r == result_t::oke); } else { - cmd->js_result_ok = false; + cmd->js_result_ok = true; + cmd->result = false; + } + cmd->done = true; + } + break; + case COMMAND_MESSAGE: { + int wv = cmd->args[0].toInt(); + QString title = cmd->args[1].toString(); + QString msg = cmd->args[2].toString(); + QString submsg = cmd->args[3].toString(); + rkt_messagetype_t type = static_cast(cmd->args[4].toInt()); + + if (_views.contains(wv)) { + msgBox(wv, title, msg, submsg, type); + cmd->js_result_ok = true; + cmd->result = true; + } else { + cmd->js_result_ok = true; cmd->result = false; } cmd->done = true; @@ -542,7 +557,7 @@ result_t Rktwebview_qt::rktSetHtml(rktwebview_t wv, const char *html) rkt_data_t *Rktwebview_qt::rktCallJs(rktwebview_t wv, const char *js) { - fprintf(stderr, "calljs: %s\n", js); + DEBUG1("calljs: %s\n", js); Command c(COMMAND_CALL_JS); QString _js(js); @@ -555,14 +570,14 @@ rkt_data_t *Rktwebview_qt::rktCallJs(rktwebview_t wv, const char *js) r->kind = js_result; r->data.js_result.result = c.js_result_ok ? result_t::oke : result_t::eval_js_failed; r->data.js_result.value = copyString(c.result.toString().toUtf8()); - fprintf(stderr, "js-result: %s\n", r->data.js_result.value); + DEBUG1("js-result: %s\n", r->data.js_result.value); return r; } result_t Rktwebview_qt::rktRunJs(rktwebview_t wv, const QString &js) { - fprintf(stderr, "rktRunJs: %s\n", js.toUtf8().constData()); + DEBUG1("rktRunJs: %s\n", js.toUtf8().constData()); Command c(COMMAND_RUN_JS); c.args.push_back(wv); c.args.push_back(js); @@ -645,7 +660,14 @@ void Rktwebview_qt::rktQuit() while(!c.done) { doEvents(); } } -result_t Rktwebview_qt::fileDlg(rktwebview_t w, const char *title, const char *base, const char *filters,QFileDialog::FileMode mode, QFileDialog::AcceptMode am, QString evt_ok, QString evt_cancel) +result_t Rktwebview_qt::fileDlg(rktwebview_t w, + const QString &title, + const QString &base, + const QString &filters, + QFileDialog::FileMode mode, + QFileDialog::AcceptMode am, + QString evt_ok, + QString evt_cancel) { if (_views.contains(w)) { WebviewWindow *win = _views[w]; @@ -700,17 +722,60 @@ result_t Rktwebview_qt::fileDlg(rktwebview_t w, const char *title, const char *b result_t Rktwebview_qt::rktChooseDir(rktwebview_t w, const char *title, const char *base_dir) { - return fileDlg(w, title, base_dir, "", QFileDialog::Directory, QFileDialog::AcceptOpen, "choose-dir-ok", "choose-dir-cancel"); + Command c(COMMAND_CHOOSE_DIR); + c.args.push_back(w); + QString s_title(title); + c.args.push_back(s_title); + QString s_base_dir(base_dir); + c.args.push_back(s_base_dir); + + postCommand(&c); + while(!c.done) { + doEvents(); + } + + bool r = c.result.toBool(); + return r ? result_t::oke : result_t::resize_failed; } result_t Rktwebview_qt::rktFileOpen(rktwebview_t w, const char *title, const char *base_dir, const char *permitted_exts) { - return fileDlg(w, title, base_dir, permitted_exts, QFileDialog::ExistingFile, QFileDialog::AcceptOpen, "file-open-ok", "file-open-cancel"); + Command c(COMMAND_FILE_OPEN); + c.args.push_back(w); + QString s_title(title); + c.args.push_back(s_title); + QString s_base_dir(base_dir); + c.args.push_back(s_base_dir); + QString s_pe(permitted_exts); + c.args.push_back(s_pe); + + postCommand(&c); + while(!c.done) { + doEvents(); + } + + bool r = c.result.toBool(); + return r ? result_t::oke : result_t::resize_failed; } result_t Rktwebview_qt::rktFileSave(rktwebview_t w, const char *title, const char *base_dir, const char *permitted_exts) { - return fileDlg(w, title, base_dir, permitted_exts, QFileDialog::AnyFile, QFileDialog::AcceptSave, "file-save-ok", "file-save-cancel"); + Command c(COMMAND_FILE_SAVE); + c.args.push_back(w); + QString s_title(title); + c.args.push_back(s_title); + QString s_base_dir(base_dir); + c.args.push_back(s_base_dir); + QString s_pe(permitted_exts); + c.args.push_back(s_pe); + + postCommand(&c); + while(!c.done) { + doEvents(); + } + + bool r = c.result.toBool(); + return r ? result_t::oke : result_t::resize_failed; } result_t Rktwebview_qt::rktWindowSetTitle(rktwebview_t wv, const char *title) @@ -724,65 +789,82 @@ result_t Rktwebview_qt::rktWindowSetTitle(rktwebview_t wv, const char *title) return r ? result_t::oke : result_t::failed; } -result_t Rktwebview_qt::rktMessageBox(rktwebview_t w, const char *title, const char *message, const char *submessage, rkt_messagetype_t type) +void Rktwebview_qt::msgBox(rktwebview_t w, const QString &title, const QString &message, const QString &submessage, rkt_messagetype_t type) { - if (_views.contains(w)) { - WebviewWindow *win = _views[w]; - QMessageBox *msg = new QMessageBox(win); + WebviewWindow *win = _views[w]; + QMessageBox *msg = new QMessageBox(win); - auto prepButton = [msg, w, this](QMessageBox::StandardButton b, QString event) { - msg->addButton(b); - QAbstractButton *btn = msg->button(b); - QVariant v = QVariant::fromValue(msg); - btn->setProperty("messagebox", v); - btn->setProperty("event", event); - btn->setProperty("rktwebview", w); - connect(btn, &QAbstractButton::clicked, this, [this]() { - QAbstractButton *btn = static_cast(sender()); - QMessageBox *mb = btn->property("messagebox").value(); - rktwebview_t w = btn->property("rktwebview").toInt(); + auto prepButton = [msg, w, this](QMessageBox::StandardButton b, QString event) { + msg->addButton(b); + QAbstractButton *btn = msg->button(b); + QVariant v = QVariant::fromValue(msg); + btn->setProperty("messagebox", v); + btn->setProperty("event", event); + btn->setProperty("rktwebview", w); + connect(btn, &QAbstractButton::clicked, this, [this]() { + QAbstractButton *btn = static_cast(sender()); + QMessageBox *mb = btn->property("messagebox").value(); + rktwebview_t w = btn->property("rktwebview").toInt(); - EventContainer e(btn->property("event").toString()); - this->triggerEvent(w, e); + EventContainer e(btn->property("event").toString()); + this->triggerEvent(w, e); - mb->close(); - }); - }; + mb->close(); + }); + }; - msg->setWindowTitle(title); + msg->setWindowTitle(title); - QString m = QString("

") + message + "

"; - m += QString::asprintf("

%s

", submessage); - msg->setInformativeText(m); + QString m = QString("

") + message + "

"; + m += QString::asprintf("

%s

", submessage.toUtf8().constData()); + msg->setInformativeText(m); - QMessageBox::Icon icn; + QMessageBox::Icon icn; - if (type == rkt_messagetype_t::error) { - icn = QMessageBox::Icon::Critical; - prepButton(QMessageBox::StandardButton::Ok, "msgbox-ok"); - } else if (type == rkt_messagetype_t::warning) { - icn = QMessageBox::Icon::Warning; - prepButton(QMessageBox::StandardButton::Ok, "msgbox-ok"); - } else if (type == rkt_messagetype_t::yes_no || type == rkt_messagetype_t::oke_cancel) { - icn = QMessageBox::Icon::Question; - if (type == rkt_messagetype_t::yes_no) { - prepButton(QMessageBox::StandardButton::No, "msgbox-no"); - prepButton(QMessageBox::StandardButton::Yes, "msgbox-yes"); - } else { - prepButton(QMessageBox::StandardButton::Cancel, "msgbox-cancel"); - prepButton(QMessageBox::StandardButton::Ok, "msgbox-ok"); - } - } else { // informatio - icn = QMessageBox::Icon::Information; + if (type == rkt_messagetype_t::error) { + icn = QMessageBox::Icon::Critical; + prepButton(QMessageBox::StandardButton::Ok, "msgbox-ok"); + } else if (type == rkt_messagetype_t::warning) { + icn = QMessageBox::Icon::Warning; + prepButton(QMessageBox::StandardButton::Ok, "msgbox-ok"); + } else if (type == rkt_messagetype_t::yes_no || type == rkt_messagetype_t::oke_cancel) { + icn = QMessageBox::Icon::Question; + if (type == rkt_messagetype_t::yes_no) { + prepButton(QMessageBox::StandardButton::No, "msgbox-no"); + prepButton(QMessageBox::StandardButton::Yes, "msgbox-yes"); + } else { + prepButton(QMessageBox::StandardButton::Cancel, "msgbox-cancel"); prepButton(QMessageBox::StandardButton::Ok, "msgbox-ok"); } - msg->setIcon(icn); - msg->show(); - return result_t::oke; - } else { - return result_t::failed; + } else { // informatio + icn = QMessageBox::Icon::Information; + prepButton(QMessageBox::StandardButton::Ok, "msgbox-ok"); } + msg->setIcon(icn); + msg->show(); +} + +result_t Rktwebview_qt::rktMessageBox(rktwebview_t w, const char *title, const char *message, const char *submessage, rkt_messagetype_t type) +{ + Command c(COMMAND_MESSAGE); + c.args.push_back(w); + QString s_title(title); + c.args.push_back(s_title); + QString s_msg(message); + c.args.push_back(s_msg); + QString s_submsg(submessage); + c.args.push_back(s_submsg); + c.args.push_back(static_cast(type)); + + postCommand(&c); + + while(!c.done) { + doEvents(); + } + + bool r = c.result.toBool(); + return r ? result_t::oke : result_t::failed; } result_t Rktwebview_qt::doWindow(rktwebview_t w, int cmd, result_t on_error) diff --git a/rktwebview_qt/rktwebview_qt.h b/rktwebview_qt/rktwebview_qt.h index 67ec898..e83de37 100644 --- a/rktwebview_qt/rktwebview_qt.h +++ b/rktwebview_qt/rktwebview_qt.h @@ -52,7 +52,15 @@ private: void handleCommandEvent(CommandEvent *e); void processCommand(Command *cmd); - result_t fileDlg(rktwebview_t w, const char *title, const char *base, const char *filters, QFileDialog::FileMode mode, QFileDialog::AcceptMode am, QString evt_ok, QString evt_cancel); + result_t fileDlg(rktwebview_t w, + const QString &title, const QString &base, + const QString &filters, + QFileDialog::FileMode mode, QFileDialog::AcceptMode am, + QString evt_ok, QString evt_cancel); + + void msgBox(rktwebview_t w, + const QString &title, const QString &message, const QString &submessage, + rkt_messagetype_t type); public: void execApp(); diff --git a/rktwebview_qt/shm.cpp b/rktwebview_qt/shm.cpp index 1a506a2..869831a 100644 --- a/rktwebview_qt/shm.cpp +++ b/rktwebview_qt/shm.cpp @@ -1,4 +1,5 @@ #include "shm.h" +#include "utils.h" #include #include @@ -306,14 +307,14 @@ class ShmSemApi { void wait() { int r = sem_wait(_sem); if (r != 0) { - fprintf(stderr, "sem_wait error: %d, %s\n", errno, strerror(errno)); + ERROR2("sem_wait error: %d, %s\n", errno, strerror(errno)); } } bool trywait() { int r = sem_trywait(reinterpret_cast(_sem)); if (r != 0 && r != EAGAIN) { - fprintf(stderr, "sem_wait error: %d, %s\n", errno, strerror(errno)); + ERROR2("sem_wait error: %d, %s\n", errno, strerror(errno)); } return (r == 0); @@ -373,7 +374,7 @@ public: name); if (_shm_handle == NULL) { - fprintf(stderr, "Cannot create shared memory with name %s and size %lld\n", name, size); + ERROR2("Cannot create shared memory with name %s and size %lld\n", name, size); _valid = false; } } else { @@ -381,7 +382,7 @@ public: FALSE, name); if (_shm_handle == NULL) { - fprintf(stderr, "Cannot open shared memory with name %s\n", name); + ERROR1("Cannot open shared memory with name %s\n", name); _valid = false; } } @@ -393,7 +394,7 @@ public: 0, size)); if (_mem == NULL) { - fprintf(stderr, "Cannot map shared memory, errorcode = %ld\n", GetLastError()); + ERROR1("Cannot map shared memory, errorcode = %ld\n", GetLastError()); _valid = false; CloseHandle(_shm_handle); } @@ -410,7 +411,7 @@ public: _sem_handle = OpenSemaphoreA(SYNCHRONIZE|SEMAPHORE_MODIFY_STATE, FALSE, _sem_name); } if (_sem_handle == NULL) { - fprintf(stderr, "Cannot create or open semaphore with name '%s' (%ld)\n", _sem_name, GetLastError()); + ERROR2("Cannot create or open semaphore with name '%s' (%ld)\n", _sem_name, GetLastError()); UnmapViewOfFile(_mem); CloseHandle(_shm_handle); _valid = false; @@ -486,14 +487,14 @@ public: void wait() { DWORD r = WaitForSingleObject(_sem, INFINITE); if (r != WAIT_OBJECT_0) { - fprintf(stderr, "sem_wait error: %ld\n", r); + ERROR1("sem_wait error: %ld\n", r); } } bool trywait() { DWORD r = WaitForSingleObject(_sem , 0); if (r != WAIT_OBJECT_0 && r != WAIT_TIMEOUT) { - fprintf(stderr, "sem_wait error: %ld\n", r); + ERROR1("sem_wait error: %ld\n", r); } return r == WAIT_OBJECT_0; } @@ -512,7 +513,7 @@ public: } if (_sem == NULL) { - fprintf(stderr, "Cannot create or open semaphore with name '%s'\n", _name); + ERROR1("Cannot create or open semaphore with name '%s'\n", _name); } _owner = owner; } diff --git a/rktwebview_qt/utils.cpp b/rktwebview_qt/utils.cpp new file mode 100644 index 0000000..70c1ea2 --- /dev/null +++ b/rktwebview_qt/utils.cpp @@ -0,0 +1,25 @@ + +#include "utils.h" + +static int _log_level = LOG_INFO; + +int logLevel() +{ + return _log_level; +} + +void setLogLevel(int l) +{ + _log_level = l; +} + +const char *logIndicator(int l) +{ + switch(l) { + case LOG_ERROR: return "ERROR "; + case LOG_INFO: return "INFO "; + case LOG_DEBUG: return "DEBUG "; + case LOG_WARNING: return "WARNING"; + } + return "UNKNOWN"; +} diff --git a/rktwebview_qt/utils.h b/rktwebview_qt/utils.h index b8284c3..5a20701 100644 --- a/rktwebview_qt/utils.h +++ b/rktwebview_qt/utils.h @@ -5,8 +5,8 @@ inline std::string basedir(const std::string &path) { - int idx1 = path.rfind("/"); - int idx2 = path.rfind("\\"); + int idx1 = static_cast(path.rfind("/")); + int idx2 = static_cast(path.rfind("\\")); std::string r; if (idx1 == std::string::npos && idx2 == std::string::npos) { r = ""; @@ -26,4 +26,33 @@ inline std::string basedir(const std::string &path) return r; } +int logLevel(); +void setLogLevel(int l); +const char *logIndicator(int l); + +#define LOG_ERROR 1 +#define LOG_WARNING 2 +#define LOG_INFO 3 +#define LOG_DEBUG 4 + +#define MKLOGSTMT(level, code) if (logLevel() >= level) { fprintf(stderr, "%s: ", logIndicator(level));code;fflush(stderr); } +#define MKL0(level, msg) MKLOGSTMT(level, fprintf(stderr, msg)) +#define MKL1(level, msg, a) MKLOGSTMT(level, fprintf(stderr, msg, a)) +#define MKL2(level, msg, a, b) MKLOGSTMT(level, fprintf(stderr, msg, a, b)) + +#define ERROR0(msg) MKL0(LOG_ERROR, msg) +#define WARN0(msg) MKL0(LOG_WARNING, msg) +#define INFO0(msg) MKL0(LOG_INFO, msg) +#define DEBUG0(msg) MKL0(LOG_DEBUG, msg) + +#define ERROR1(msg, a) MKL1(LOG_ERROR, msg, a) +#define WARN1(msg, a) MKL1(LOG_WARNING, msg, a) +#define INFO1(msg, a) MKL1(LOG_INFO, msg, a) +#define DEBUG1(msg, a) MKL1(LOG_DEBUG, msg, a) + +#define ERROR2(msg, a, b) MKL2(LOG_ERROR, msg, a, b) +#define WARN2(msg, a, b) MKL2(LOG_WARNING, msg, a, b) +#define INFO2(msg, a, b) MKL2(LOG_INFO, msg, a, b) +#define DEBUG2(msg, a, b) MKL2(LOG_DEBUG, msg, a, b) + #endif // UTILS_H diff --git a/rktwebview_qt/webviewwindow.cpp b/rktwebview_qt/webviewwindow.cpp index 4c3ab37..8370487 100644 --- a/rktwebview_qt/webviewwindow.cpp +++ b/rktwebview_qt/webviewwindow.cpp @@ -1,4 +1,5 @@ #include "webviewwindow.h" +#include "utils.h" #include "webviewqt.h" #include "rktwebview_qt.h" @@ -126,7 +127,7 @@ void WebviewWindow::handleCertificate(const QWebEngineCertificateError &certific dodisp(certificateError.certificateChain()); */ - fprintf(stderr, "Certificate Error: %s\n", certificateError.description().toUtf8().constData()); + ERROR1("Certificate Error: %s\n", certificateError.description().toUtf8().constData()); QList chain = certificateError.certificateChain(); int i; for(i = 0; i < chain.size(); i++) {