diff --git a/example1/example.rkt b/example1/example.rkt index 5d11a26..83ade47 100644 --- a/example1/example.rkt +++ b/example1/example.rkt @@ -4,6 +4,8 @@ racket/runtime-path racket/gui simple-ini/class + racket/string + net/url ) (provide @@ -55,8 +57,7 @@ (define example-1-dialog% (class wv-dialog% (inherit-field settings) - (super-new [window-context 'example-1-dialog] - [file-not-found-handler (root-file-not-found-handler "example-1-dialog.html")] + (super-new [html-path "example-1-dialog.html"] ) (define/override (page-loaded oke) @@ -93,11 +94,12 @@ (define example-1-window% (class wv-window% - (inherit-field settings app-context) - (super-new [file-not-found-handler (root-file-not-found-handler "example-1.html")] - [window-context 'example-1-main] + (inherit-field settings wv-context) + (super-new [html-path "example-1.html"] ) - + + (define my-page 'first) + (define has-page #f) (define go-on-counter #f) (define c-counter 0) (define counter-inc 1) @@ -107,18 +109,25 @@ (define/override (can-close?) + (unless (eq? counter-thread #f) + (send this message 'warning "Cannot close window" + "Cannot close this window while the counter runs")) (eq? counter-thread #f)) (define start-stop-btn #f) (define/public (stop-counter) - (send start-stop-btn set-innerHTML! "Start Counter") + (when (and (eq? my-page 'first) + has-page) + (send start-stop-btn set-innerHTML! "Start Counter") + ) (set! go-on-counter #f) + (set! counter-thread #f) ) (define/public (reset-counter) (stop-counter) - (set! counter-thread #f) + (set! c-counter 0) ) (define/public (inc-counter) @@ -130,26 +139,30 @@ (send this update-counter)) (define/public (update-counter) - (send div-counter set-innerHTML! (format "Count = ~a" c-counter)) - (when (and (> c-counter 0) (<= c-counter 100)) - (send div-counter set-style! - '((background white)))) - (when (and (> c-counter 100) (<= c-counter 200)) - (send div-counter set-style! - '((background green) (color white)))) - (when (and (> c-counter 200) (<= c-counter 300)) - (send div-counter set-style! - '((background yellow) (color black) (font-size: 120%)))) - (when (and (> c-counter 300) (<= c-counter 400)) - (send div-counter set-style! - '((color white) (background orange) (font-size 110%)))) - (when (and (> c-counter 400)) - (send div-counter set-style! - '((color white) (background red) (font-size 120%) (font-weight bold)))) + (when (and (eq? my-page 'first) has-page) + (send div-counter set-innerHTML! (format "Count = ~a" c-counter)) + (when (and (> c-counter 0) (<= c-counter 100)) + (send div-counter set-style! + '((background white) (color blue)))) + (when (and (> c-counter 100) (<= c-counter 200)) + (send div-counter set-style! + '((background green) (color white)))) + (when (and (> c-counter 200) (<= c-counter 300)) + (send div-counter set-style! + '((background yellow) (color black) (font-size: 120%)))) + (when (and (> c-counter 300) (<= c-counter 400)) + (send div-counter set-style! + '((color white) (background orange) (font-size 110%)))) + (when (and (> c-counter 400)) + (send div-counter set-style! + '((color white) (background red) (font-size 120%) (font-weight bold)))) + ) ) (define/public (start-counter) - (send start-stop-btn set-innerHTML! "Stop Counter") + (when (and (eq? my-page 'first) has-page) + (displayln "start-counter innerhtml") + (send start-stop-btn set-innerHTML! "Stop Counter")) (set! counter-thread (thread (λ () @@ -165,16 +178,21 @@ (define/public (set-folder new-dir) (set! my-dir new-dir) (send settings set/global! 'folder new-dir) - (let ((el (send this element 'folder))) - (send el set-innerHTML! (format "Selected folder: ~a" my-dir)) + (when (and (eq? my-page 'first) has-page) + (let ((el (send this element 'folder))) + (displayln "set-folder innerhtml") + (send el set-innerHTML! (format "Selected folder: ~a" my-dir)) + ) ) ) - (define/override (choose-dir) - (let ((result (super choose-dir "Select a folder" my-dir))) - (displayln (format "choosen dir handle: ~a" result)) - (unless (eq? result 'canceled) - (send this set-folder result)) + (define/public (choose-dir*) + (let ((result (send this choose-dir "Select a folder" my-dir))) + (unless (eq? result 'showing) + (displayln (format "choosen dir handle: ~a" result)) + (unless (eq? result #f) + (send this set-folder result)) + ) ) ) @@ -186,43 +204,63 @@ ) ) ; (send this clone-settings 'example-1-dialog)])) - ;(define/override (handle-navigate url type kind) - ; (send this reset-counter) - ; (super handle-navigate url type kind)) + (define/override (navigation-request type url) + (displayln url) + + (when (eq? my-page 'first) + (send this reset-counter) + (displayln "counter reset") + ) + + (if (string-suffix? (url->string url) "example-1-second.html") + (set! my-page 'second) + (set! my-page 'first)) + + (super navigation-request type url) + + (displayln "Super called") + ) (define/override (page-loaded oke) - (ww-debug "HTML LOADED") + (ww-debug (format "HTML LOADED ~a" oke)) + (set! has-page oke) (super page-loaded oke) + (displayln "super called") + (unless (eq? oke #f) - (set! div-counter (send this element 'div-counter)) - (send this update-counter) - (send this set-folder my-dir) + (displayln "Hi") + (set! div-counter (send this element 'div-counter)) + (displayln "Hi1") + (send this update-counter) + (send this set-folder my-dir) - (ww-debug "CONNECTING BUTTONS") - (send this bind! 'dialog-button 'click (λ (el evt data) - (send this prefs))) + (ww-debug "CONNECTING BUTTONS") + (send this bind! 'dialog-button 'click (λ (el evt data) + (send this prefs))) - (set! start-stop-btn (send this element 'start-stop-button)) - (send this bind! 'start-stop-button 'click - (λ (el evt data) - (if (eq? counter-thread #f) - (begin - (send this start-counter) + (set! start-stop-btn (send this element 'start-stop-button)) + (send this bind! 'start-stop-button 'click + (λ (el evt data) + (if (eq? counter-thread #f) + (begin + (send this start-counter) + ) + (begin + (send this reset-counter) + ) ) - (begin - (send this reset-counter) - ) - ) + ) ) - ) - (send this bind! 'devtools 'click - (λ (el evt data) (send this devtools))) + (send this bind! 'devtools 'click + (λ (el evt data) (send this devtools))) - (send this bind! 'select-dir-button 'click - (λ (el evt data) - (send this choose-dir))) - + (send this bind! 'select-dir-button 'click + (λ (el evt data) + (send this choose-dir*))) + ) + (displayln "page-loaded done") + ) ;(ww-debug "SETTING MENU") #|(let* ((div-open (send this element 'div-open)) @@ -268,7 +306,6 @@ ) )|# - ) (begin (displayln "Yes this works!") @@ -278,9 +315,8 @@ (define (run-example) (let* ((ini (new ini% [file 'web-racket-example1])) + (context (new wv-context% [base-path cur-dir] [ini ini])) (window (new example-1-window% - [app-context 'example-1] - [ini ini] - [base-dir cur-dir])) + [wv-context context])) ) window)) diff --git a/private/lib/linux/x86_64/librktwebview_qt.so b/private/lib/linux/x86_64/librktwebview_qt.so index ebaf2ae..84f83bf 100755 Binary files a/private/lib/linux/x86_64/librktwebview_qt.so and b/private/lib/linux/x86_64/librktwebview_qt.so differ diff --git a/private/racket-webview-qt.rkt b/private/racket-webview-qt.rkt index 1da7a2e..c68a7cd 100644 --- a/private/racket-webview-qt.rkt +++ b/private/racket-webview-qt.rkt @@ -40,6 +40,7 @@ rkt-webview-choose-dir rkt-webview-file-open rkt-webview-file-save + rkt-webview-messagebox rkt-webview-version ) @@ -226,6 +227,16 @@ ) ) +(define _rkt_messagetype_t + (_enum '(info = 1 + error = 2 + warning = 3 + yes-no = 4 + oke-cancel = 5 + ) + ) + ) + (define-cstruct _rkt_version_t ([qt-major _int] [qt-minor _int] @@ -357,15 +368,24 @@ ;RKTWEBVIEW_QT_EXPORT rkt_js_result_t *rkt_webview_choose_dir(rktwebview_t w, const char *title, const char *base_dir); (define-rktwebview rkt_webview_choose_dir - (_fun _int _string/utf-8 _string/utf-8 -> _rkt_data_t-pointer)) + (_fun _int _string/utf-8 _string/utf-8 -> _rkt_result_t)) ;RKTWEBVIEW_QT_EXPORT rkt_js_result_t *rkt_webview_file_open(rktwebview_t w, const char *title, const char *base_dir, const char *permitted_exts); (define-rktwebview rkt_webview_file_open - (_fun _int _string/utf-8 _string/utf-8 _string/utf-8 -> _rkt_data_t-pointer)) + (_fun _int _string/utf-8 _string/utf-8 _string/utf-8 -> _rkt_result_t)) ;RKTWEBVIEW_QT_EXPORT rkt_js_result_t *rkt_webview_file_save(rktwebview_t w, const char *title, const char *base_dir, const char *permitted_exts); (define-rktwebview rkt_webview_file_save - (_fun _int _string/utf-8 _string/utf-8 _string/utf-8 -> _rkt_data_t-pointer)) + (_fun _int _string/utf-8 _string/utf-8 _string/utf-8 -> _rkt_result_t)) + +;RKTWEBVIEW_QT_EXPORT result_t rkt_webview_message_box( +; rktwebview_t w, +; const char *title, +; const char *message, +; const char *submessage, +; rkt_messagetype_t type); +(define-rktwebview rkt_webview_message_box + (_fun _int _string/utf-8 _string/utf-8 _string/utf-8 _rkt_messagetype_t -> _rkt_result_t)) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; @@ -405,20 +425,21 @@ (define (rkt-process-events handle) (if (> (queue-length (rkt-wv-evt-queue handle)) 0) - (let ((data (dequeue! (rkt-wv-evt-queue handle)))) - (if (symbol? data) - (if (eq? data 'quit) + (let ((evt (dequeue! (rkt-wv-evt-queue handle)))) + (if (symbol? evt) + (if (eq? evt 'quit) (begin (hash-remove! rkt-wv-store (rkt-wv-win handle)) 'quit) - (rkt-process-events handle)) - (let* ((e (union-ref (rkt_data_t-data data) 1)) - (evt (cast (rkt_evt_t-evt e) _pointer _string*/utf-8))) + (begin + (displayln (format "Unexpected data in event queue: ~a" evt)) + (rkt-process-events handle))) + (begin ((rkt-wv-callback handle) handle evt) - (rkt_webview_free_data data) (rkt-process-events handle))) ) - 'done)) + 'done) + ) (define (rkt-webview-new-context boilerplate-js server-cert) @@ -431,7 +452,11 @@ ) (let ((wv (rkt_webview_create context parent-win (λ (rkt-evt) - (enqueue! evt-queue rkt-evt))))) + (let* ((e (union-ref (rkt_data_t-data rkt-evt) 1)) + (evt (cast (rkt_evt_t-evt e) _pointer _string*/utf-8))) + (rkt_webview_free_data rkt-evt) ; Free event data ASAP + (enqueue! evt-queue evt) + ))))) (let ((handle (make-rkt-wv wv evt-queue evt-callback #t close-callback))) (thread (λ () (sleep 1) @@ -504,28 +529,34 @@ (rkt_webview_open_devtools (rkt-wv-win wv))) (define (rkt-webview-choose-dir wv title base-dir) - (let* ((d (rkt_webview_choose_dir (rkt-wv-win wv) title base-dir)) - (r (union-ref (rkt_data_t-data d) 2)) - (value (cast (rkt_js_result_t-value r) _pointer _string*/utf-8)) - (result (rkt_js_result_t-result r))) - (rkt_webview_free_data d) - (list result value))) + (rkt_webview_choose_dir (rkt-wv-win wv) title base-dir)) +; (let* ((d (rkt_webview_choose_dir (rkt-wv-win wv) title base-dir)) +; (r (union-ref (rkt_data_t-data d) 2)) +; (value (cast (rkt_js_result_t-value r) _pointer _string*/utf-8)) +; (result (rkt_js_result_t-result r))) +; (rkt_webview_free_data d) +; (list result value))) (define (rkt-webview-file-open wv title base-dir permitted-exts) - (let* ((d (rkt_webview_file_open (rkt-wv-win wv) title base-dir permitted-exts)) - (r (union-ref (rkt_data_t-data d) 2)) - (value (cast (rkt_js_result_t-value r) _pointer _string*/utf-8)) - (result (rkt_js_result_t-result r))) - (rkt_webview_free_data d) - (list result value))) + (rkt_webview_file_open (rkt-wv-win wv) title base-dir permitted-exts)) +; (let* ((d (rkt_webview_file_open (rkt-wv-win wv) title base-dir permitted-exts)) +; (r (union-ref (rkt_data_t-data d) 2)) +; (value (cast (rkt_js_result_t-value r) _pointer _string*/utf-8)) +; (result (rkt_js_result_t-result r))) +; (rkt_webview_free_data d) +; (list result value))) (define (rkt-webview-file-save wv title base-dir permitted-exts) - (let* ((d (rkt_webview_file_save (rkt-wv-win wv) title base-dir permitted-exts)) - (r (union-ref (rkt_data_t-data d) 2)) - (value (cast (rkt_js_result_t-value r) _pointer _string*/utf-8)) - (result (rkt_js_result_t-result r))) - (rkt_webview_free_data d) - (list result value))) + (rkt_webview_file_save (rkt-wv-win wv) title base-dir permitted-exts)) +; (let* ((d (rkt_webview_file_save (rkt-wv-win wv) title base-dir permitted-exts)) +; (r (union-ref (rkt_data_t-data d) 2)) +; (value (cast (rkt_js_result_t-value r) _pointer _string*/utf-8)) +; (result (rkt_js_result_t-result r))) +; (rkt_webview_free_data d) +; (list result value))) + +(define (rkt-webview-messagebox wv title message submessage type) + (rkt_webview_message_box (rkt-wv-win wv) title message submessage type)) (define (rkt-webview-version) (let ((d (rkt_webview_version))) diff --git a/private/racket-webview.rkt b/private/racket-webview.rkt index 4fa2fa2..3a4e6d4 100644 --- a/private/racket-webview.rkt +++ b/private/racket-webview.rkt @@ -48,6 +48,8 @@ webview-window-state webview-set-title! + webview-messagebox + webview-choose-dir webview-file-open webview-file-save @@ -61,6 +63,7 @@ wv-permitted-exts? wv-permitted-exts-exts? wv-list-of-permitted-exts? + webview-filter->exts webview-bind! webview-unbind! @@ -101,6 +104,7 @@ ;webview-del-attr! webview-standard-file-getter + webview-default-boilerplate-js webview-version @@ -116,9 +120,14 @@ (define-runtime-path js-path "../js") -(define (default-boilerplate-js) +(define (webview-default-boilerplate-js . custom-js) (let ((file (build-path js-path "boilerplate.js"))) - (file->string file))) + (let ((bjs (file->string file))) + (let ((js (string-append bjs + (if (null? custom-js) + "" + ((car custom-js)))))) + js)))) (define-struct wv-context ([context #:mutable] @@ -346,7 +355,7 @@ (map (λ (e) (format "*.~a" e)) (wv-permitted-exts-exts pe)))) (string-join (map mef (if (list? list-of-pe) list-of-pe (list list-of-pe))) ";;")) -(define (filter->exts str) +(define (webview-filter->exts str) (let ((re #px"^([^ ]+)\\s+[(]([^)]+)[)]")) (let ((m (regexp-match re str))) (cond ((eq? m #f) @@ -401,7 +410,7 @@ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; (define/contract (webview-new-context file-getter - #:boilerplate-js [bj (default-boilerplate-js)]) + #:boilerplate-js [bj (webview-default-boilerplate-js)]) (->* (procedure?) (#:boilerplate-js string?) wv-context?) (let* ((h (make-wv-context 0 0 file-getter #f #f 0 (make-lru 250 #:cmp eq?) @@ -527,48 +536,58 @@ (def-win-func webview-present rkt-webview-present) (def-win-func webview-window-state rkt-webview-window-state) +(define/contract (webview-messagebox wv type title message #:sub [submessage ""]) + (->* (wv-win? symbol? string? string?) (#:sub string?) symbol?) + (rkt-webview-messagebox (wv-win-handle wv) title message submessage type)) + (define/contract (webview-choose-dir wv title base-dir) - (-> wv-win? string? (or/c path? string?) (or/c hash? boolean?)) + (-> wv-win? string? (or/c path? string?) symbol?) (let ((bd (if (path? base-dir) (path->string base-dir) base-dir))) (let ((res (rkt-webview-choose-dir (wv-win-handle wv) title bd))) - (if (eq? res #f) - #f - (cond ((eq? (car res) 'oke) - (let ((r (make-hash (hash->list (fromJson (cadr res)))))) - (hash-set! r 'state (string->symbol (hash-ref r 'state))) - r)) - (else #f)) - ) - ) + res) ) ) +;(if (eq? res #f) +; #f +; (cond ((eq? (car res) 'oke) +; (let ((r (make-hash (hash->list (fromJson (cadr res)))))) +; (hash-set! r 'state (string->symbol (hash-ref r 'state))) +; r)) +; (else #f)) +; ) +; ) +; ) +; ) + (define (file-open-save wv title base-dir permitted-exts open-save-f) (let* ((bd (if (path? base-dir) (path->string base-dir) base-dir)) (ext-filter (make-exts-filter permitted-exts))) + (displayln ext-filter); (let ((res (open-save-f (wv-win-handle wv) title bd ext-filter))) - (if (eq? res #f) - #f - (cond ((eq? (car res) 'oke) - (let* ((h (make-hash (hash->list (fromJson (cadr res)))))) - (hash-set! h 'state (string->symbol (hash-ref h 'state))) - (hash-set! h 'used-filter (filter->exts (hash-ref h 'used-filter))) - h)) - (else #f)) - ) - ) - ) - ) + res))) +; (if (eq? res #f) +; #f +; (cond ((eq? (car res) 'oke) +; (let* ((h (make-hash (hash->list (fromJson (cadr res)))))) +; (hash-set! h 'state (string->symbol (hash-ref h 'state))) +; (hash-set! h 'used-filter (filter->exts (hash-ref h 'used-filter))) +; h)) +; (else #f)) +; ) +; ) +; ) +; ) (define/contract (webview-file-open wv title base-dir permitted-exts) (-> wv-win? string? (or/c path? string?) (or/c wv-permitted-exts? wv-list-of-permitted-exts?) - (or/c hash? boolean?)) + symbol?) (file-open-save wv title base-dir permitted-exts rkt-webview-file-open)) (define/contract (webview-file-save wv title base-dir permitted-exts) (-> wv-win? string? (or/c path? string?) (or/c wv-permitted-exts? wv-list-of-permitted-exts?) - (or/c hash? boolean?)) + symbol?) (file-open-save wv title base-dir permitted-exts rkt-webview-file-save)) @@ -655,9 +674,10 @@ (define/contract (webview-set-innerHTML! wv id html) (-> wv-win? symbol? (or/c string? xexpr?) symbol?) (if (string? html) - (webview-run-js wv - (with-id id el - ("el.innerHTML = '~a';" (esc-quote html)))) + (let ((r (webview-call-js wv + (with-id id el + ("el.innerHTML = '~a'; return true;" (esc-quote html)))))) + (if r 'oke 'failed)) (webview-set-innerHTML! wv id (xexpr->string html)) ) ) diff --git a/rktwebview_qt/main.cpp b/rktwebview_qt/main.cpp index 759d260..0dbe804 100644 --- a/rktwebview_qt/main.cpp +++ b/rktwebview_qt/main.cpp @@ -57,6 +57,10 @@ int main(int argc, char *argv[]) rkt_webview_free_data(r); } + if (i == 7) { + result_t r = rkt_webview_message_box(wv1, "This is a title", "This is my message", "This is my submessage", rkt_messagetype_t::yes_no); + } + if (i == 10) { wv2 = rkt_webview_create(context, wv1, eventCb); diff --git a/rktwebview_qt/rktutils.cpp b/rktwebview_qt/rktutils.cpp index 58cff39..4ee17f6 100644 --- a/rktwebview_qt/rktutils.cpp +++ b/rktwebview_qt/rktutils.cpp @@ -25,3 +25,5 @@ QHash mkEvent() QHash h; return h; } + +int EventContainer::evt_count = 0; diff --git a/rktwebview_qt/rktutils.h b/rktwebview_qt/rktutils.h index 013645b..402bf34 100644 --- a/rktwebview_qt/rktutils.h +++ b/rktwebview_qt/rktutils.h @@ -7,9 +7,12 @@ class EventContainer : public QHash { +private: + static int evt_count; public: EventContainer(const QString &evt) { this->insert("event", evt); + this->insert("evt-id", ++evt_count); } }; diff --git a/rktwebview_qt/rktwebview.cpp b/rktwebview_qt/rktwebview.cpp index 6934420..3fe9146 100644 --- a/rktwebview_qt/rktwebview.cpp +++ b/rktwebview_qt/rktwebview.cpp @@ -175,19 +175,19 @@ result_t rkt_webview_set_title(rktwebview_t wv, const char *title) return handler->rktWindowSetTitle(wv, title); } -rkt_data_t *rkt_webview_choose_dir(rktwebview_t w, const char *title, const char *base_dir) +result_t rkt_webview_choose_dir(rktwebview_t w, const char *title, const char *base_dir) { rkt_webview_init(); return handler->rktChooseDir(w, title, base_dir); } -rkt_data_t *rkt_webview_file_open(rktwebview_t w, const char *title, const char *base_dir, const char *permitted_exts) +result_t rkt_webview_file_open(rktwebview_t w, const char *title, const char *base_dir, const char *permitted_exts) { rkt_webview_init(); return handler->rktFileOpen(w, title, base_dir, permitted_exts); } -rkt_data_t *rkt_webview_file_save(rktwebview_t w, const char *title, const char *base_dir, const char *permitted_exts) +result_t rkt_webview_file_save(rktwebview_t w, const char *title, const char *base_dir, const char *permitted_exts) { rkt_webview_init(); return handler->rktFileSave(w, title, base_dir, permitted_exts); @@ -226,3 +226,9 @@ rkt_data_t *rkt_webview_version() d->data.version.qt_patch = QT_VERSION_PATCH; return d; } + +result_t rkt_webview_message_box(rktwebview_t w, const char *title, const char *message, const char *submessage, rkt_messagetype_t type) +{ + rkt_webview_init(); + return handler->rktMessageBox(w, title, message, submessage, type); +} diff --git a/rktwebview_qt/rktwebview.h b/rktwebview_qt/rktwebview.h index 1fad84f..50c3cbc 100644 --- a/rktwebview_qt/rktwebview.h +++ b/rktwebview_qt/rktwebview.h @@ -54,6 +54,14 @@ typedef enum { maximized_active = 18 } window_state_t; +typedef enum { + info = 1, + error = 2, + warning = 3, + yes_no = 4, + oke_cancel = 5 +} rkt_messagetype_t; + typedef struct { int qt_major; int qt_minor; @@ -111,9 +119,11 @@ RKTWEBVIEW_QT_EXPORT result_t rkt_webview_maximize(rktwebview_t w); RKTWEBVIEW_QT_EXPORT result_t rkt_webview_minimize(rktwebview_t w); RKTWEBVIEW_QT_EXPORT window_state_t rkt_webview_window_state(rktwebview_t w); -RKTWEBVIEW_QT_EXPORT rkt_data_t *rkt_webview_choose_dir(rktwebview_t w, const char *title, const char *base_dir); -RKTWEBVIEW_QT_EXPORT rkt_data_t *rkt_webview_file_open(rktwebview_t w, const char *title, const char *base_dir, const char *permitted_exts); -RKTWEBVIEW_QT_EXPORT rkt_data_t *rkt_webview_file_save(rktwebview_t w, const char *title, const char *base_dir, const char *permitted_exts); +RKTWEBVIEW_QT_EXPORT result_t rkt_webview_choose_dir(rktwebview_t w, const char *title, const char *base_dir); +RKTWEBVIEW_QT_EXPORT result_t rkt_webview_file_open(rktwebview_t w, const char *title, const char *base_dir, const char *permitted_exts); +RKTWEBVIEW_QT_EXPORT result_t rkt_webview_file_save(rktwebview_t w, const char *title, const char *base_dir, const char *permitted_exts); + +RKTWEBVIEW_QT_EXPORT result_t rkt_webview_message_box(rktwebview_t w, const char *title, const char *message, const char *submessage, rkt_messagetype_t type); } diff --git a/rktwebview_qt/rktwebview_qt.cpp b/rktwebview_qt/rktwebview_qt.cpp index f7f0cbe..1f95674 100644 --- a/rktwebview_qt/rktwebview_qt.cpp +++ b/rktwebview_qt/rktwebview_qt.cpp @@ -15,6 +15,8 @@ #include #include "command.h" #include +#include +#include static inline char *copyString(const char *s) { @@ -425,7 +427,6 @@ rkt_wv_context_t Rktwebview_qt::newContext(const char *boilerplate_js, const cha QWebEngineScriptCollection *c = p->scripts(); QList l = c->toList(); - printf("%d\n", l.size()); _contexts[_context_counter] = p; @@ -595,85 +596,72 @@ window_state_t Rktwebview_qt::rktWindowState(rktwebview_t w) return ws; } -rkt_data_t *Rktwebview_qt::rktChooseDir(rktwebview_t w, const char *title, const char *base_dir) +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) { - Command c(COMMAND_CHOOSE_DIR); - c.args.push_back(w); + if (_views.contains(w)) { + WebviewWindow *win = _views[w]; - QString t(title); - c.args.push_back(t); + QFileDialog *dlg = new QFileDialog(win, title, base); + dlg->setFileMode(mode); + dlg->setAcceptMode(am); - QString dir(base_dir); - c.args.push_back(dir); + QString pe = filters; + QStringList p = pe.split(";;"); - postCommand(&c); + dlg->setNameFilters(p); + dlg->setProperty("rktwebview", w); + dlg->setProperty("evt-ok", evt_ok); + dlg->setProperty("evt-cancel", evt_cancel); - while(!c.done) { doEvents(); } + connect(dlg, &QFileDialog::accepted, this, [this]() { + QFileDialog *dlg = static_cast(sender()); - bool oke = c.js_result_ok; + rktwebview_t w = dlg->property("rktwebview").toInt(); + QString evt_ok = dlg->property("evt-ok").toString(); - rkt_data_t *r = static_cast(malloc(sizeof(rkt_js_result_t))); - r->kind = js_result; - r->data.js_result.result = c.js_result_ok ? result_t::oke : result_t::choose_dir_failed; - r->data.js_result.value = copyString(c.result.toString().toUtf8()); + QStringList l = dlg->selectedFiles(); + QString file; + if (l.size() > 0) { + file = dlg->selectedFiles().first(); + } - return r; + EventContainer e(evt_ok); + e["choosen"] = file; + e["filter"] = dlg->selectedNameFilter(); + e["dir"] = dlg->directory().path(); + + this->triggerEvent(w, e); + }); + + connect(dlg, &QDialog::rejected, this, [this]() { + QFileDialog *dlg = static_cast(sender()); + + rktwebview_t w = dlg->property("rktwebview").toInt(); + QString evt_cancel = dlg->property("evt-cancel").toString(); + + EventContainer e(evt_cancel); + this->triggerEvent(w, e); + }); + dlg->show(); + return result_t::oke; + } else { + return result_t::failed; + } } -rkt_data_t *Rktwebview_qt::rktFileOpen(rktwebview_t w, const char *title, const char *base_dir, const char *permitted_exts) +result_t Rktwebview_qt::rktChooseDir(rktwebview_t w, const char *title, const char *base_dir) { - Command c(COMMAND_FILE_OPEN); - c.args.push_back(w); - - QString t(title); - c.args.push_back(t); - - QString dir(base_dir); - c.args.push_back(dir); - - QString exts(permitted_exts); - c.args.push_back(exts); - - postCommand(&c); - - while(!c.done) { doEvents(); } - - bool oke = c.js_result_ok; - - rkt_data_t *r = static_cast(malloc(sizeof(rkt_data_t))); - r->kind = js_result; - r->data.js_result.result = c.js_result_ok ? result_t::oke : result_t::choose_dir_failed; - r->data.js_result.value = copyString(c.result.toString().toUtf8()); - - return r; + return fileDlg(w, title, base_dir, "", QFileDialog::Directory, QFileDialog::AcceptOpen, "choose-dir-ok", "choose-dir-cancel"); } -rkt_data_t *Rktwebview_qt::rktFileSave(rktwebview_t w, const char *title, const char *base_dir, const char *permitted_exts) +result_t Rktwebview_qt::rktFileOpen(rktwebview_t w, const char *title, const char *base_dir, const char *permitted_exts) { - Command c(COMMAND_FILE_SAVE); - c.args.push_back(w); + return fileDlg(w, title, base_dir, permitted_exts, QFileDialog::ExistingFile, QFileDialog::AcceptOpen, "file-open-ok", "file-open-cancel"); +} - QString t(title); - c.args.push_back(t); - - QString dir(base_dir); - c.args.push_back(dir); - - QString exts(permitted_exts); - c.args.push_back(exts); - - postCommand(&c); - - while(!c.done) { doEvents(); } - - bool oke = c.js_result_ok; - - rkt_data_t *r = static_cast(malloc(sizeof(rkt_data_t))); - r->kind = js_result; - r->data.js_result.result = c.js_result_ok ? result_t::oke : result_t::choose_dir_failed; - r->data.js_result.value = copyString(c.result.toString().toUtf8()); - - return r; +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"); } result_t Rktwebview_qt::rktWindowSetTitle(rktwebview_t wv, const char *title) @@ -687,6 +675,67 @@ 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) +{ + if (_views.contains(w)) { + + 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(); + + EventContainer e(btn->property("event").toString()); + this->triggerEvent(w, e); + + mb->close(); + }); + }; + + msg->setWindowTitle(title); + + QString m = QString("

") + message + "

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

%s

", submessage); + msg->setInformativeText(m); + + 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; + prepButton(QMessageBox::StandardButton::Ok, "msgbox-ok"); + } + msg->setIcon(icn); + msg->show(); + return result_t::oke; + } else { + return result_t::failed; + } +} + result_t Rktwebview_qt::doWindow(rktwebview_t w, int cmd, result_t on_error) { Command c(cmd); diff --git a/rktwebview_qt/rktwebview_qt.h b/rktwebview_qt/rktwebview_qt.h index 9c0ded7..30e4c6a 100644 --- a/rktwebview_qt/rktwebview_qt.h +++ b/rktwebview_qt/rktwebview_qt.h @@ -13,6 +13,7 @@ #include #include #include +#include class WebViewQt; @@ -57,7 +58,8 @@ private: void handleCommandEvent(CommandEvent *e); void processCommand(Command *cmd); - // QObject interface + 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); + protected: void customEvent(QEvent *event); @@ -89,11 +91,12 @@ public: result_t rktShowNormalWindow(rktwebview_t w); window_state_t rktWindowState(rktwebview_t w); - rkt_data_t *rktChooseDir(rktwebview_t w, const char *title, const char *base_dir); - rkt_data_t *rktFileOpen(rktwebview_t w, const char *title, const char *base_dir, const char *permitted_exts); - rkt_data_t *rktFileSave(rktwebview_t w, const char *title, const char *base_dir, const char *permitted_exts); + result_t rktChooseDir(rktwebview_t w, const char *title, const char *base_dir); + result_t rktFileOpen(rktwebview_t w, const char *title, const char *base_dir, const char *permitted_exts); + result_t rktFileSave(rktwebview_t w, const char *title, const char *base_dir, const char *permitted_exts); result_t rktWindowSetTitle(rktwebview_t wv, const char *title); + result_t rktMessageBox(rktwebview_t w, const char *title, const char *message, const char *submessage, rkt_messagetype_t type); bool rktValid(rktwebview_t wv);