-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathCDWApplication.h
More file actions
1788 lines (1668 loc) · 64.9 KB
/
CDWApplication.h
File metadata and controls
1788 lines (1668 loc) · 64.9 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
/*
* Wapplication.h
*
* Created on: 01-dec.-2014
* Author: Thomas Weyn
*/
#include <Wt/WApplication>
#include "CDWObject.h"
namespace Wt {
class CDWApplication : public CDWObject{
public:
static CDWApplication* instance = nullptr;
CDWApplication(WApplication* object = 0): CDWObject(object) {}
WApplication* getObject() const {
return static_cast<WApplication*>(wobject);
}
/*! \brief Returns the environment information.
*
* This method returns the environment object that was used when
* constructing the application. The environment provides
* information on the initial request, user agent, and
* deployment-related information.
*
* \sa url(), sessionId()
*/
virtual const WEnvironment& environment() const{
return getObject()->environment();
}
/*! \brief Returns the root container.
*
* This is the top-level widget container of the application, and
* corresponds to entire browser window. The user interface of your
* application is represented by the content of this container.
*
* \if cpp
*
* The %root() widget is only defined when the application manages
* the entire window. When deployed as a \link Wt::WidgetSet
* WidgetSet\endlink application, there is no %root() container, and
* \c 0 is returned. Instead, use bindWidget() to bind one or more
* root widgets to existing HTML <div> (or other) elements on
* the page.
*
* \elseif java
*
* The root() widget is only defined when the application manages
* the entire window. When deployed as a \link Wt::WidgetSet
* WidgetSet\endlink application, there is no %root() container, and
* <code>null</code> is returned. Instead, use bindWidget() to bind
* one or more root widgets to existing HTML <div> (or other)
* elements on the page.
*
* \endif
*/
virtual WContainerWidget *root() const {
return getObject()->root();
}
/*! \brief Finds a widget by name.
*
* This finds a widget in the application's widget hierarchy. It
* does not only consider widgets in the root(), but also widgets
* that are placed outside this root, such as in dialogs, or other
* "roots" such as all the bound widgets in a widgetset application.
*
* \sa WWidget::setObjectName(), WWidget::find()
*/
virtual WWidget *findWidget(const char* name){
return getObject()->findWidget(name);
}
/** @name Style sheets and CSS
*/
//@{
/*! \brief Returns a reference to the inline style sheet.
*
* Widgets may allow configuration of their look and feel through
* style classes. These may be defined in this inline stylesheet, or
* in external style sheets.
*
* It is usually preferable to use external stylesheets (and
* consider more accessible). Still, the internal stylesheet has as
* benefit that style rules may be dynamically updated, and it is
* easier to manage logistically.
*
* \sa useStyleSheet()
* \sa WWidget::setStyleClass()
*/
virtual WCssStyleSheet& styleSheet() {
return getObject()->styleSheet();
}
/*! \brief Adds an external style sheet.
*
* The \p link is a link to a stylesheet.
*
* The \p media indicates the CSS media to which this stylesheet
* applies. This may be a comma separated list of media. The default
* value is "all" indicating all media.
*
* This is an overloaded method for convenience, equivalent to:
* \code
* useStyleSheet(Wt::WCssStyleSheet(link, media))
* \endcode
*/
virtual void useStyleSheet(const WLink& link, const char* media = "all"){
getObject()->useStyleSheet(link, media);
}
/*! \brief Conditionally adds an external style sheet.
*
* This is an overloaded method for convenience, equivalent to:
* \code
* useStyleSheet(Wt::WCssStyleSheet(link, media), condition)
* \endcode
*/
virtual void useStyleSheet(const WLink& link, const char* condition, const char* media){
getObject()->useStyleSheet(link, condition, media);
}
/*! \brief Adds an external stylesheet.
*
* Widgets may allow configuration of their look and feel through
* style classes. These may be defined in an inline stylesheet,
* or in external style sheets.
*
* External stylesheets are inserted after the internal style sheet,
* and can therefore override default styles set by widgets in the
* internal style sheet.
*
* If not empty, \p condition is a string that is used to apply the
* stylesheet to specific versions of IE. Only a limited subset of
* the IE conditional comments syntax is supported (since these are
* in fact interpreted server-side instead of client-side). Examples
* are:
*
* - "IE gte 6": only for IE version 6 or later.
* - "!IE gte 6": only for IE versions prior to IE6.
* - "IE lte 7": only for IE versions prior to IE7.
*
* \sa styleSheet(), useStyleSheet(const char*, const char*)
* \sa WWidget::setStyleClass()
*/
virtual void useStyleSheet(const WCssStyleSheet& styleSheet, const char* condition = ""){
getObject()->useStyleSheet(styleSheet, condition);
}
/*! \brief Sets the theme.
*
* The theme provides the look and feel of several built-in widgets,
* using CSS style rules. Rules for each theme are defined in the
* <tt>resources/themes/</tt><i>theme</i><tt>/</tt> folder.
*
* The default theme is "default" CSS theme.
*/
virtual void setTheme(const WTheme *theme){
getObject()->setTheme(theme);
}
/*! \brief Returns the theme.
*/
virtual const WTheme *theme() const {
return getObject()->theme();
}
/*! \brief Sets a CSS theme.
*
* This sets a WCssTheme as theme.
*
* The theme provides the look and feel of several built-in widgets,
* using CSS style rules. Rules for each CSS theme are defined in
* the <tt>resources/themes/</tt><i>name</i><tt>/</tt> folder.
*
* The default theme is "default". Setting an empty theme "" will
* result in a stub CSS theme that does not load any stylesheets.
*/
virtual void setCssTheme(const char* name){
getObject()->setCssTheme(name);
}
/*! \brief Sets the layout direction.
*
* The default direction is LeftToRight.
*
* This sets the language text direction, which by itself sets the
* default text alignment and reverse the column orders of <table>
* elements.
*
* In addition, %Wt will take this setting into account in WTextEdit,
* WTableView and WTreeView (so that columns are reverted), and swap
* the behaviour of WWidget::setFloatSide() and
* WWidget::setOffsets() for RightToLeft languages. Note that CSS
* settings themselves are not affected by this setting, and thus
* for example <tt>"float: right"</tt> will move a box to the right,
* irrespective of the layout direction.
*
* The library sets <tt>"Wt-ltr"</tt> or <tt>"Wt-rtl"</tt> as style
* classes for the document body. You may use this if to override
* certain style rules for a Right-to-Left document.
*
* For example:
* \code
* body .sidebar { float: right; }
* body.Wt-rtl .sidebar { float: left; }
* \endcode
*
* \note The layout direction can be set only at application startup
* and does not have the effect of rerendering the entire UI.
*/
virtual void setLayoutDirection(LayoutDirection direction){
getObject()->setLayoutDirection(direction);
}
/*! \brief Returns the layout direction.
*
* \sa setLayoutDirection()
*/
virtual LayoutDirection layoutDirection() const {
return getObject()->layoutDirection();
}
/*! \brief Sets a style class to the entire page <body>.
*
* \sa setHtmlClass()
*/
virtual void setBodyClass(const char* styleClass){
return getObject()->setBodyClass(styleClass);
}
/*! \brief Returns the style class set for the entire page <body>.
*
* \sa setBodyClass()
*/
virtual const char* bodyClass() const {
return getObject()->bodyClass().c_str();
}
/*! \brief Sets a style class to the entire page <html>.
*
* \sa setBodyClass()
*/
virtual void setHtmlClass(const char* styleClass){
return getObject()->setHtmlClass(styleClass);
}
/*! \brief Returns the style class set for the entire page <html>.
*
* \sa setHtmlClass()
*/
virtual const char* htmlClass() const {
return getObject()->htmlClass();
}
//@}
/*! \brief Sets the window title.
*
* Sets the browser window title to \p title.
*
* The default title is "".
*
* \sa title()
*/
virtual void setTitle(const WString& title){
getObject()->setTitle(title);
}
/*! \brief Returns the window title.
*
* \sa setTitle(const WString&)
*/
virtual const WString& title() const {
return getObject()->title();
}
/*! \brief Returns the close message.
*
* \sa setConfirmCloseMessage()
*/
virtual const WString& closeMessage() const {
return getObject()->closeMessage();
}
/*! \brief Returns the resource object that provides localized strings.
*
* \if cpp
* The default value is a WMessageResourceBundle instance, which
* uses XML files to resolve localized strings, but you can set a
* custom class using setLocalizedStrings().
* \elseif java
* This returns the object previously set using setLocalizedStrings().
* \endif
*
* WString::tr() is used to create localized strings, whose
* localized translation is looked up through this object, using a
* key.
*
* \if cpp
* \sa WString::tr(), messageResourceBundle()
* \elseif java
* \sa WString::tr()
* \endif
*/
virtual WLocalizedStrings *localizedStrings(){
return getObject()->localizedStrings();
}
/*! \brief Sets the resource object that provides localized strings.
*
* The \p translator resolves localized strings within the current
* application locale.
*
* \if cpp
* The previous resource is deleted, and ownership of the new resource
* passes to the application.
* \endif
*
* \sa localizedStrings(), WString::tr(const char *key)
*/
virtual void setLocalizedStrings(WLocalizedStrings *stringResolver){
getObject()->setLocalizedStrings(stringResolver);
}
/*! \brief Returns the message resource bundle.
*
* The message resource bundle defines the list of external XML
* files that are used to lookup localized strings.
*
* The default localizedStrings() is a WMessageResourceBundle
* object, and this method returns localizedStrings() downcasted to
* this type.
*
* \sa WString::tr(const char *key)
*/
virtual WMessageResourceBundle& messageResourceBundle(){
return getObject()->messageResourceBundle();
}
/*! \brief Changes the locale.
*
* The locale is used by the localized strings resource to resolve
* localized strings.
*
* By passing an empty \p locale, the default locale is
* chosen.
*
* When the locale is changed, refresh() is called, which will
* resolve the strings of the current user-interface in the new
* locale.
*
* At construction, the locale is copied from the environment
* (WEnvironment::locale()), and this is the locale that was
* configured by the user in his browser preferences, and passed
* using an HTTP request header.
*
* \sa localizedStrings(), WString::tr()
*/
virtual void setLocale(const WLocale& locale){
getObject()->setLocale(locale);
}
/*! \brief Returns the current locale.
*
* \sa setLocale(const WLocale&)
*/
virtual const WLocale& locale() const {
return getObject()->locale();
}
/*! \brief Refreshes the application.
*
* This lets the application to refresh its data, including strings
* from message-resource bundles. This done by propagating
* WWidget::refresh() through the widget hierarchy.
*
* This method is also called when the user hits the refresh (or
* reload) button, if this can be caught within the current session.
*
* \if cpp
*
* The reload button may only be caught when %Wt is configured so that
* reload should not spawn a new session. When URL rewriting is used for
* session tracking, this will cause an ugly session ID to be added to the
* URL. See \ref config_session for configuring the reload
* behavior ("<reload-is-new-session>").
*
* \elseif java
*
* The reload button may only be caught when cookies for session
* tracking are configured in the servlet container.
*
* \endif
*
* \sa WWidget::refresh()
*/
virtual void refresh(){
getObject()->refresh();
}
/*! \brief Binds a top-level widget for a WidgetSet deployment.
*
* This method binds a \p widget to an existing element with DOM id
* \p domId on the page. The element type should correspond with
* the widget type (e.g. it should be a <div> for a
* WContainerWidget, or a <table> for a WTable).
*
* \sa root()
* \sa Wt::WidgetSet
*/
virtual void bindWidget(WWidget *widget, const char* domId){
getObject()->bindWidget(widget, domId);
}
/** @name URLs and internal paths
*/
//@{
/*! \brief Returns a URL for the current session
*
* Returns the (relative) URL for this application session
* (including the session ID if necessary). The URL includes the
* full application path, and is expanded by the browser into a full
* URL.
*
* For example, for an application deployed at \code
* http://www.mydomain.com/stuff/app.wt \endcode this method might
* return <tt>"/stuff/app.wt?wtd=AbCdEf"</tt>. Additional query
* parameters can be appended in the form of
* <tt>"¶m1=value¶m2=value"</tt>.
*
* To obtain a URL that is suitable for bookmarking the current
* application state, to be used across sessions, use bookmarkUrl()
* instead.
*
* \sa redirect(), WEnvironment::hostName(), WEnvironment::urlScheme()
* \sa bookmarkUrl()
*/
virtual const char* url(const char* internalPath = "") const{
return getObject()->url(internalPath).c_str();
}
/*! \brief Makes an absolute URL.
*
* Returns an absolute URL for a given (relative url) by including
* the schema, hostname, and deployment path.
*
* If \p url is "", then the absolute base URL is returned. This is
* the absolute URL at which the application is deployed, up to the
* last '/'.
*
* This is not used in the library, except when a public URL is
* needed, e.g. for inclusion in an email.
*
* You may want to reimplement this method when the application is
* hosted behind a reverse proxy or in general the public URL of the
* application cannot be guessed correctly by the application.
*/
virtual const char* makeAbsoluteUrl(const char* url) const{
return getObject()->makeAbsoluteUrl(url).c_str();
}
/*! \brief "Resolves" a relative URL taking into account internal paths.
*
* Using HTML5 History API or in a plain HTML session (without ugly
* internal paths), the internal path is present as a full part of
* the URL. This has a consequence that relative URLs, if not dealt
* with, would be resolved against the last 'folder' name of the
* internal path, rather than against the application deployment
* path (which is what you probably want).
*
* When using a widgetset mode deployment, or when configuring a
* baseURL property in the configuration, this method will make an
* absolute URL so that the property is fetched from the right
* server.
*
* Otherwise, this method will fixup a relative URL so that it
* resolves correctly against the base path of an application. This
* does not necessarily mean that the URL is resolved into an
* absolute URL. In fact, %Wt will simply prepend a sequence of "../"
* path elements to correct for the internal path. When passed an
* absolute URL (i.e. starting with '/'), the url is returned
* unchanged.
*
* For URLs passed to the %Wt API (and of which the library knows it
* is represents a URL) this method is called internally by the
* library. But it may be useful for URLs which are set e.g. inside
* a WTemplate.
*/
virtual const char* resolveRelativeUrl(const char* url) const{
return getObject()->resolveRelativeUrl(url).c_str();
}
/*! \brief Returns a bookmarkable URL for the current internal path.
*
* Is equivalent to <tt>bookmarkUrl(internalPath())</tt>, see
* bookmarkUrl(const char*) const.
*
* To obtain a URL that is refers to the current session of the
* application, use url() instead.
*
* \sa url(), bookmarkUrl(const char*) const
*/
virtual const char* bookmarkUrl() const{
return getObject()->bookmarkUrl().c_str();
}
/*! \brief Returns a bookmarkable URL for a given internal path.
*
* Returns the (relative) URL for this application that includes the
* internal path \p internalPath, usable across sessions.
*
* The returned URL concatenates the internal path to the application
* base URL, and when no JavaScript is available and URL rewriting is used
* for session-tracking, a session Id is appended to reuse an existing
* session if available.
*
* \if cpp
* See also \ref config_session for configuring the session-tracking
* method.
*
* For the built-in httpd, when the application is deployed at a folder
* (ending with '/'), only an exact matching path is routed to
* the application (this can be changed since Wt 3.1.9, see
* \ref wthttpd ), making clean URLs impossible. Returned URLs then
* include a <tt>"?_="</tt> encoding for the internal path.
* \endif
*
* You can use bookmarkUrl() as the destination for a WAnchor, and
* listen to a click event is attached to a slot that switches to
* the internal path \p internalPath (see
* WAnchor::setRefInternalPath()). In this way, an anchor can be
* used to switch between internal paths within an application
* regardless of the situation (browser with or without Ajax
* support, or a web spider bot), but still generates suitable URLs
* across sessions, which can be used for bookmarking, opening in a
* new window/tab, or indexing.
*
* To obtain a URL that refers to the current session of the
* application, use url() instead.
*
* \sa url(), bookmarkUrl()
*
* \if cpp
* \note the \p internalPath should be UTF8 encoded (we may fix the API
* to use WString in the future).
* \endif
*/
virtual const char* bookmarkUrl(const char* internalPath) const{
return getObject()->bookmarkUrl(internalPath).c_str();
}
/*! \brief Changes the internal path.
*
* A %Wt application may manage multiple virtual paths. The virtual
* path is appended to the application URL. Depending on the
* situation, the path is directly appended to the application URL
* or it is appended using a name anchor (#).
*
* For example, for an application deployed at:
* \code
* http://www.mydomain.com/stuff/app.wt
* \endcode
* for which an \p internalPath <tt>"/project/z3cbc/details/"</tt> is
* set, the two forms for the application URL are:
* <ul>
* <li> in an AJAX session (HTML5):
* \code
* http://www.mydomain.com/stuff/app.wt/project/z3cbc/details/
* \endcode
* </li><li> in an AJAX session (HTML4):
* \code
* http://www.mydomain.com/stuff/app.wt#/project/z3cbc/details/
* \endcode
* </li><li>
* </li><li>
* in a plain HTML session:
* \code
* http://www.mydomain.com/stuff/app.wt/project/z3cbc/details/
* \endcode
* </li></ul>
*
* Note, since %Wt 3.1.9, the actual form of the URL no longer
* affects relative URL resolution, since now %Wt includes an HTML
* <tt>meta base</tt> tag which points to the deployment path,
* regardless of the current internal path. This does break
* deployments behind a reverse proxy which changes paths.
*
* \if cpp
* For the built-in httpd, when the application is deployed
* at a folder (ending with '/'), only an exact matching path is
* routed to the application (this can be changed since Wt 3.1.9,
* see \ref wthttpd ), making clean URLs impossible. Returned
* URLs then include a <tt>"?_="</tt> encoding for the internal
* path:
*
* \code
* http://www.mydomain.com/stuff/?_=/project/z3cbc/details/
* \endcode
* \endif
*
* When the internal path is changed, an entry is added to the
* browser history. When the user navigates back and forward through
* this history (using the browser back/forward buttons), an
* internalPathChanged() event is emitted. You should listen to this
* signal to switch the application to the corresponding state. When
* \p emitChange is \c true, this signal is also emitted by setting
* the path (but only if the path is actually changed).
*
* A url that includes the internal path may be obtained using
* bookmarkUrl().
*
* The \p internalPath must start with a '/'. In this way, you
* can still use normal anchors in your HTML. Internal path changes
* initiated in the browser to paths that do not start with a '/'
* are ignored.
*
* \sa bookmarkUrl(), internalPath(), internalPathChanged()
*
* \if cpp
* \note the \p path should be UTF8 encoded (we may fix the API
* to use WString in the future).
* \endif
*/
virtual void setInternalPath(const char* path, bool emitChange = false){
getObject()->setInternalPath(path, emitChange);
}
/*! \brief Sets whether an internal path is valid by default.
*
* This configures how you treat (invalid) internal paths. If an
* internal path is treated valid by default then you need to call
* setInternalPath(false) for an invalid path. If on the other hand
* you treat an internal path as invalid by default, then you need
* to call setInternalPath(true) for a valid path.
*
* A user which opens an invalid internal path will receive a HTTP
* 404-Not Found response code (if sent an HTML response).
*
* The default value is \c true.
*/
virtual void setInternalPathDefaultValid(bool valid){
getObject()->setInternalPathDefaultValid(valid);
}
/*! \brief Returns whether an internal path is valid by default.
*
* \sa setInternalPathDefaultValid()
*/
virtual bool internalPathDefaultValid() const{
return getObject()->internalPathDefaultValid();
}
/*! \brief Sets whether the current internal path is valid.
*
* You can use this function in response to an internal path change
* event (or at application startup) to indicate whether the new (or
* initial) internal path is valid. This has only an effect on plain
* HTML sessions, or on the first response in an application
* deployed with progressive bootstrap settings, as this generates
* then a 404 Not-Found response.
*
* \sa internalPathChanged(), setInternalPathDefaultValid()
*/
virtual void setInternalPathValid(bool valid){
getObject()->setInternalPathValid(valid);
}
/*! \brief Returns whether the current internal path is valid.
*
* \sa setInternalPathValid()
*/
virtual bool internalPathValid() const{
return getObject()->internalPathValid();
}
/*! \brief Returns the current internal path.
*
* When the application is just created, this is equal to
* WEnvironment::internalPath().
*
* \sa setInternalPath(), internalPathNextPart(), internalPathMatches()
*
* \if cpp
* \note the \p returned path is UTF8 (we may fix the API
* to use WString in the future).
* \endif
*/
virtual const char* internalPath() const{
return getObject()->internalPath().c_str();
}
/*! \brief Returns a part of the current internal path.
*
* This is a convenience method which returns the next \p folder
* in the internal path, after the given \p path.
*
* For example, when the current internal path is
* <tt>"/project/z3cbc/details"</tt>, this method returns
* <tt>"details"</tt> when called with <tt>"/project/z3cbc/"</tt> as
* \p path argument.
*
* The \p path must start with a '/', and internalPathMatches()
* should evaluate to \c true for the given \p path. If not,
* an empty string is returned and an error message is logged.
*
* \sa internalPath(), internalPathChanged()
*
* \if cpp
* \note the \p internal path is UTF8 encoded (we may fix the API
* to use WString in the future).
* \endif
*/
virtual const char* internalPathNextPart(const char* path) const{
return getObject()->internalPathNextPart(path).c_str();
}
virtual const char* internalSubPath(const char* path) const{
return getObject()->internalSubPath(path).c_str();
}
/*! \brief Checks if the internal path matches a given path.
*
* Returns whether the current internalPath() starts with
* \p path (or is equal to \p path). You will typically use
* this method within a slot conneted to the internalPathChanged()
* signal, to check that an internal path change affects the
* widget. It may also be useful before changing \p path using
* setInternalPath() if you do not intend to remove sub paths when
* the current internal path already matches \p path.
*
* The \p path must start with a '/'.
*
* \sa setInternalPath(), internalPath()
*
* \if cpp
* \note the \p internal path is UTF8 encoded (we may fix the API
* to use WString in the future).
* \endif
*/
virtual bool internalPathMatches(const char* path) const{
return getObject()->internalPathMatches(path);
}
/*! \brief %Signal which indicates that the user changes the internal path.
*
* This signal indicates a change to the internal path, which is
* usually triggered by the user using the browser back/forward
* buttons.
*
* The argument contains the new internal path.
*
* \sa setInternalPath()
*
* \if cpp
* \note the \p internal path is UTF8 encoded (we may fix the API
* to use WString in the future).
* \endif
*/
//FIXME: implement
//Signal<const char*>& internalPathChanged();
//FIXME: implement
//Signal<const char*>& internalPathInvalid() { return internalPathInvalid_; }
/*! \brief Redirects the application to another location.
*
* The client will be redirected to a new location identified by \p
* url. Use this in conjunction with quit() if you want to the
* application to be terminated as well.
*
* Calling %redirect() does not imply %quit() since it may be useful
* to switch between a non-secure and secure (SSL) transport
* connection.
*/
virtual void redirect(const char* url){
getObject()->redirect(url);
}
//@}
/*! \brief Returns the URL at which the resources are deployed.
*
* Returns resolveRelativeUrl(relativeResourcesUrl())
*/
virtual const char* resourcesUrl(){
return getObject()->resourcesUrl();
}
/*! \brief Returns the URL at which the resources are deployed.
*
* \if cpp
* This returns the value of the 'resources' property set in the
* configuration file, and may thus be a URL relative to the deployment
* path.
* \endif
*
* \sa resolveRelativeUrl()
*/
virtual const char* relativeResourcesUrl(){
return getObject()->relativeResourcesUrl();
}
/*! \brief Returns the appRoot special property
*
* This returns the "appRoot" property, with a trailing slash added
* to the end if it was not yet present.
*
* The property "appRoot" was introduced as a generalization of the
* working directory for the location of files that do not need to
* be served over http to the client, but are required by the
* program to run properly. Typically, these are message resource
* bundles (xml), CSV files, database files (e.g. SQLite files for
* Wt::Dbo), ...
*
* Some connectors do not allow you to control what the current
* working directory (CWD) is set to (fcgi, isapi). Instead of
* referring to files assuming a sensible CWD, it is therefore
* better to refer to them relative to the application root.
*
* The appRoot property is special in the sense that it can be set
* implicitly by the connector (see the connector documentation for
* more info). If it was not set by the connector, it can be set as
* a normal property in the configuration file (the default
* wt_config.xml describes how to set properties). If the property
* is not set at all, it is assumed that the appRoot is CWD and this
* function will return an empty string.
*
* \if cpp
* Usage example:
* \code
* messageResourceBundle().use(appRoot() + "text");
* messageResourceBundle().use(appRoot() + "charts");
*
* Wt::Dbo::backend::Sqlite3 sqlite3_(appRoot() + "planner.db");
* \endcode
* \endif
*
* \sa WServer::appRoot(), docRoot()
*/
virtual const char* appRoot(){
return getObject()->appRoot();
}
/*! \brief Returns the server document root.
*
* This returns the filesystem path that corresponds to the document root
* of the webserver.
*
* \note This does not work reliably for complex webserver configurations
* (e.g. using FastCGI with Apache and rewrite rules). See also the
* <a href="https://issues.apache.org/bugzilla/show_bug.cgi?id=26052">
* discussion here</a>.
*
* \sa appRoot()
*/
virtual const char* docRoot(){
return getObject()->docRoot();
}
/*! \brief Returns the unique identifier for the current session.
*
* The session id is a string that uniquely identifies the current session.
* Note that the actual contents has no particular meaning and client
* applications should in no way try to interpret its value.
*/
virtual const char* sessionId(){
return getObject()->sessionId();
}
/*! \brief Changes the session id.
*
* To mitigate session ID fixation attacks, you should use this
* method to change the session ID to a new random value after a
* user has authenticated himself.
*
* \sa sessionId()
*/
virtual void changeSessionId(){
getObject()->changeSessionId();
}
virtual WebSession* session() const{
return getObject()->session();
}
/** @name Manipulation outside the main event loop
*/
//@{
/*! \brief Enables server-initiated updates.
*
* By default, updates to the user interface are possible only at
* startup, during any event (in a slot), or at regular time points
* using WTimer. This is the normal %Wt event loop.
*
* In some cases, one may want to modify the user interface from a
* second thread, outside the event loop. While this may be worked
* around by the WTimer, in some cases, there are bandwidth and
* processing overheads associated which may be unnecessary, and
* which create a trade-off with time resolution of the updates.
*
* When \p enabled is \c true, this enables "server push" (what is
* called 'comet' in AJAX terminology). Widgets may then be
* modified, created or deleted outside of the event loop (e.g. in
* response to execution of another thread), and these changes are
* propagated by calling triggerUpdate().
*
* \if cpp
* There are two ways for safely manipulating a session's UI, with
* respect to thread-safety and application life-time (the library
* can decide to terminate an application if it lost connectivity
* with the browser).
*
* <h3>WServer::post()</h3>
*
* The easiest and less error-prone solution is to post an event,
* represented by a function/method call, to a session using
* WServer::post().
*
* The method is non-blocking: it returns immediately, avoiding
* dead-lock scenarios. The function is called from within a thread
* of the server's thread pool, and not if the session has been or
* is being terminated. The function is called in the context of the
* targeted application session, and with exclusive access to the
* session.
*
* <h3>WApplication::UpdateLock</h3>
*
* A more direct approach is to grab the application's update lock and
* manipulate the application's state directly from another thread.
*
* At any time, the application may be deleted (e.g. because of a
* time out or because the user closes the application window). You
* should thus make sure you do no longer reference an application
* after it has been deleted. When %Wt decides to delete an
* application, it first runs WApplication::finalize() and then
* invokes the destructor. While doing this, any other thread trying
* to grab the update lock will unblock, but the lock will return \c
* false. You should therefore always check whether the lock is
* valid.
*
* \elseif java
*
* Note that you need to grab the application's update lock to avoid
* concurrency problems, whenever you modify the application's state
* from another thread.
*
* \endif
*
* An example of how to modify the widget tree outside the event loop
* and propagate changes is:
* \if cpp
* \code
* // You need to have a reference to the application whose state
* // you are about to manipulate.
* // You should prevent the application from being deleted somehow,
* // before you could grab the application lock.
* Wt::WApplication *app = ...;
*
* {
* // Grab the application lock. It is a scoped lock.
* Wt::WApplication::UpdateLock lock(app);
*
* if (lock) {
* // We now have exclusive access to the application: we can safely modify the widget tree for example.
* app->root()->addWidget(new Wt::WText("Something happened!"));
*
* // Push the changes to the browser
* app->triggerUpdate();
* }
* }
* \endcode
* \elseif java
* \code
* // You need to have a reference to the application whose state
* // you are about to manipulate.
* WApplication app = ...;
*
* // Grab the application lock
* WApplication.UpdateLock lock = app.getUpdateLock();
*
* try {
* // We now have exclusive access to the application:
* // we can safely modify the widget tree for example.
* app.getRoot().addWidget(new WText("Something happened!"));
*
* // Push the changes to the browser
* app.triggerUpdate();
* } finally {
* lock.release();
* }
* \endcode
* \endif
*
* \if java
* This works only if your servlet container supports the Servlet 3.0
* API. If you try to invoke this function on a servlet container with
* no such support, an exception will be thrown.