From bf5e403a684fea1521b7b9960d8200fa5a461288 Mon Sep 17 00:00:00 2001 From: Tobias Taschner Date: Wed, 9 Sep 2015 22:59:21 +0200 Subject: [PATCH 1/4] Restructure wxNotificationMessage. wxNotificationMessage has been refactored to always use wxNotificationMessageImpl (this was previously already done in the MSW implementation) This adds various features and fixes to wxNotificationMessage: - OS X Notification Center implementation - Generic "toast" notifications - SetIcon() to specify a custom icon - AddAction() to add actions to notifications - Events to get notify of notification clicks, dismiss or actions --- Makefile.in | 63 ++- build/bakefiles/files.bkl | 4 +- build/files | 4 +- build/msw/makefile.bcc | 24 + build/msw/makefile.gcc | 24 + build/msw/makefile.vc | 24 + build/msw/wx_adv.vcxproj | 2 +- build/msw/wx_adv.vcxproj.filters | 8 +- build/msw/wx_vc7_adv.vcproj | 6 +- build/msw/wx_vc7_core.vcproj | 3 - build/msw/wx_vc8_adv.vcproj | 8 +- build/msw/wx_vc8_core.vcproj | 4 - build/msw/wx_vc9_adv.vcproj | 8 +- build/msw/wx_vc9_core.vcproj | 4 - build/osx/wxcocoa.xcodeproj/project.pbxproj | 16 + include/wx/generic/notifmsg.h | 33 +- include/wx/generic/private/notifmsg.h | 52 ++ include/wx/gtk/notifmsg.h | 51 -- include/wx/msw/notifmsg.h | 74 --- include/wx/msw/taskbar.h | 3 +- include/wx/notifmsg.h | 144 +++--- include/wx/private/notifmsg.h | 76 +++ interface/wx/notifmsg.h | 54 ++- samples/dialogs/dialogs.cpp | 452 ++++++++++++++--- samples/dialogs/dialogs.h | 12 +- src/common/notifmsgcmn.cpp | 103 ++++ src/generic/notifmsgg.cpp | 511 +++++++++++++++----- src/gtk/notifmsg.cpp | 371 ++++++++++---- src/msw/notifmsg.cpp | 398 +++++---------- src/msw/taskbar.cpp | 26 +- src/osx/cocoa/notifmsg.mm | 254 ++++++++++ 31 files changed, 1999 insertions(+), 817 deletions(-) create mode 100644 include/wx/generic/private/notifmsg.h delete mode 100644 include/wx/gtk/notifmsg.h delete mode 100644 include/wx/msw/notifmsg.h create mode 100644 include/wx/private/notifmsg.h create mode 100644 src/common/notifmsgcmn.cpp create mode 100644 src/osx/cocoa/notifmsg.mm diff --git a/Makefile.in b/Makefile.in index ececa01420..dc1879b412 100644 --- a/Makefile.in +++ b/Makefile.in @@ -3367,13 +3367,11 @@ COND_TOOLKIT_GTK_TOOLKIT_VERSION__ADVANCED_PLATFORM_HDR = \ @COND_TOOLKIT_GTK_TOOLKIT_VERSION_@ADVANCED_PLATFORM_HDR = $(COND_TOOLKIT_GTK_TOOLKIT_VERSION__ADVANCED_PLATFORM_HDR) COND_TOOLKIT_GTK_TOOLKIT_VERSION_2_ADVANCED_PLATFORM_HDR = \ $(ADVANCED_GTK_PLATFORM_HDR) \ - wx/gtk/notifmsg.h \ wx/gtk/taskbar.h \ wx/generic/activityindicator.h @COND_TOOLKIT_GTK_TOOLKIT_VERSION_2@ADVANCED_PLATFORM_HDR = $(COND_TOOLKIT_GTK_TOOLKIT_VERSION_2_ADVANCED_PLATFORM_HDR) COND_TOOLKIT_GTK_TOOLKIT_VERSION_3_ADVANCED_PLATFORM_HDR = \ $(ADVANCED_GTK_PLATFORM_HDR) \ - wx/gtk/notifmsg.h \ wx/gtk/taskbar.h \ wx/generic/activityindicator.h @COND_TOOLKIT_GTK_TOOLKIT_VERSION_3@ADVANCED_PLATFORM_HDR = $(COND_TOOLKIT_GTK_TOOLKIT_VERSION_3_ADVANCED_PLATFORM_HDR) @@ -3384,9 +3382,8 @@ COND_TOOLKIT_MOTIF_ADVANCED_PLATFORM_HDR = \ wx/generic/animate.h \ wx/generic/animateanimate.h @COND_TOOLKIT_MOTIF@ADVANCED_PLATFORM_HDR = $(COND_TOOLKIT_MOTIF_ADVANCED_PLATFORM_HDR) -@COND_TOOLKIT_MSW@ADVANCED_PLATFORM_HDR = \ -@COND_TOOLKIT_MSW@ wx/msw/notifmsg.h wx/msw/sound.h wx/msw/taskbar.h \ -@COND_TOOLKIT_MSW@ wx/msw/joystick.h +@COND_TOOLKIT_MSW@ADVANCED_PLATFORM_HDR = wx/msw/sound.h \ +@COND_TOOLKIT_MSW@ wx/msw/taskbar.h wx/msw/joystick.h COND_TOOLKIT_OSX_COCOA_ADVANCED_PLATFORM_HDR = \ wx/generic/animate.h \ wx/osx/activityindicator.h \ @@ -5789,6 +5786,7 @@ COND_WXUNIV_0___ADVANCED_SRC_OBJECTS = \ monodll_treelist.o \ monodll_wizard.o \ monodll_addremovectrl.o \ + monodll_notifmsgcmn.o \ $(__ADVANCED_PLATFORM_SRC_OBJECTS) \ $(__ADVANCED_PLATFORM_NATIVE_SRC_OBJECTS) @COND_WXUNIV_0@__ADVANCED_SRC_OBJECTS = $(COND_WXUNIV_0___ADVANCED_SRC_OBJECTS) @@ -5827,6 +5825,7 @@ COND_WXUNIV_1___ADVANCED_SRC_OBJECTS = \ monodll_treelist.o \ monodll_wizard.o \ monodll_addremovectrl.o \ + monodll_notifmsgcmn.o \ $(__ADVANCED_PLATFORM_SRC_OBJECTS_1) \ $(__ADVANCED_UNIV_SRC_OBJECTS) @COND_WXUNIV_1@__ADVANCED_SRC_OBJECTS = $(COND_WXUNIV_1___ADVANCED_SRC_OBJECTS) @@ -5890,7 +5889,8 @@ COND_TOOLKIT_OSX_COCOA___ADVANCED_PLATFORM_SRC_OBJECTS = \ monodll_cocoa_datetimectrl.o \ monodll_osx_cocoa_taskbar.o \ monodll_hidjoystick.o \ - monodll_cocoa_activityindicator.o + monodll_cocoa_activityindicator.o \ + monodll_cocoa_notifmsg.o @COND_TOOLKIT_OSX_COCOA@__ADVANCED_PLATFORM_SRC_OBJECTS = $(COND_TOOLKIT_OSX_COCOA___ADVANCED_PLATFORM_SRC_OBJECTS) @COND_TOOLKIT_OSX_IPHONE@__ADVANCED_PLATFORM_SRC_OBJECTS \ @COND_TOOLKIT_OSX_IPHONE@ = monodll_animateg.o monodll_sound_osx.o \ @@ -6004,7 +6004,8 @@ COND_TOOLKIT_OSX_COCOA___ADVANCED_PLATFORM_SRC_OBJECTS_1 = \ monodll_cocoa_datetimectrl.o \ monodll_osx_cocoa_taskbar.o \ monodll_hidjoystick.o \ - monodll_cocoa_activityindicator.o + monodll_cocoa_activityindicator.o \ + monodll_cocoa_notifmsg.o @COND_TOOLKIT_OSX_COCOA@__ADVANCED_PLATFORM_SRC_OBJECTS_1 = $(COND_TOOLKIT_OSX_COCOA___ADVANCED_PLATFORM_SRC_OBJECTS_1) @COND_TOOLKIT_OSX_IPHONE@__ADVANCED_PLATFORM_SRC_OBJECTS_1 \ @COND_TOOLKIT_OSX_IPHONE@ = monodll_animateg.o monodll_sound_osx.o \ @@ -7785,6 +7786,7 @@ COND_WXUNIV_0___ADVANCED_SRC_OBJECTS_1 = \ monolib_treelist.o \ monolib_wizard.o \ monolib_addremovectrl.o \ + monolib_notifmsgcmn.o \ $(__ADVANCED_PLATFORM_SRC_OBJECTS_2) \ $(__ADVANCED_PLATFORM_NATIVE_SRC_OBJECTS_1) @COND_WXUNIV_0@__ADVANCED_SRC_OBJECTS_1 = $(COND_WXUNIV_0___ADVANCED_SRC_OBJECTS_1) @@ -7823,6 +7825,7 @@ COND_WXUNIV_1___ADVANCED_SRC_OBJECTS_1 = \ monolib_treelist.o \ monolib_wizard.o \ monolib_addremovectrl.o \ + monolib_notifmsgcmn.o \ $(__ADVANCED_PLATFORM_SRC_OBJECTS_3) \ $(__ADVANCED_UNIV_SRC_OBJECTS_1) @COND_WXUNIV_1@__ADVANCED_SRC_OBJECTS_1 = $(COND_WXUNIV_1___ADVANCED_SRC_OBJECTS_1) @@ -7886,7 +7889,8 @@ COND_TOOLKIT_OSX_COCOA___ADVANCED_PLATFORM_SRC_OBJECTS_2 = \ monolib_cocoa_datetimectrl.o \ monolib_osx_cocoa_taskbar.o \ monolib_hidjoystick.o \ - monolib_cocoa_activityindicator.o + monolib_cocoa_activityindicator.o \ + monolib_cocoa_notifmsg.o @COND_TOOLKIT_OSX_COCOA@__ADVANCED_PLATFORM_SRC_OBJECTS_2 = $(COND_TOOLKIT_OSX_COCOA___ADVANCED_PLATFORM_SRC_OBJECTS_2) @COND_TOOLKIT_OSX_IPHONE@__ADVANCED_PLATFORM_SRC_OBJECTS_2 \ @COND_TOOLKIT_OSX_IPHONE@ = monolib_animateg.o monolib_sound_osx.o \ @@ -8000,7 +8004,8 @@ COND_TOOLKIT_OSX_COCOA___ADVANCED_PLATFORM_SRC_OBJECTS_3 = \ monolib_cocoa_datetimectrl.o \ monolib_osx_cocoa_taskbar.o \ monolib_hidjoystick.o \ - monolib_cocoa_activityindicator.o + monolib_cocoa_activityindicator.o \ + monolib_cocoa_notifmsg.o @COND_TOOLKIT_OSX_COCOA@__ADVANCED_PLATFORM_SRC_OBJECTS_3 = $(COND_TOOLKIT_OSX_COCOA___ADVANCED_PLATFORM_SRC_OBJECTS_3) @COND_TOOLKIT_OSX_IPHONE@__ADVANCED_PLATFORM_SRC_OBJECTS_3 \ @COND_TOOLKIT_OSX_IPHONE@ = monolib_animateg.o monolib_sound_osx.o \ @@ -11458,6 +11463,7 @@ COND_WXUNIV_0___ADVANCED_SRC_OBJECTS_2 = \ advdll_treelist.o \ advdll_wizard.o \ advdll_addremovectrl.o \ + advdll_notifmsgcmn.o \ $(__ADVANCED_PLATFORM_SRC_OBJECTS_4) \ $(__ADVANCED_PLATFORM_NATIVE_SRC_OBJECTS_2) @COND_WXUNIV_0@__ADVANCED_SRC_OBJECTS_2 = $(COND_WXUNIV_0___ADVANCED_SRC_OBJECTS_2) @@ -11496,6 +11502,7 @@ COND_WXUNIV_1___ADVANCED_SRC_OBJECTS_2 = \ advdll_treelist.o \ advdll_wizard.o \ advdll_addremovectrl.o \ + advdll_notifmsgcmn.o \ $(__ADVANCED_PLATFORM_SRC_OBJECTS_5) \ $(__ADVANCED_UNIV_SRC_OBJECTS_2) @COND_WXUNIV_1@__ADVANCED_SRC_OBJECTS_2 = $(COND_WXUNIV_1___ADVANCED_SRC_OBJECTS_2) @@ -11559,7 +11566,8 @@ COND_TOOLKIT_OSX_COCOA___ADVANCED_PLATFORM_SRC_OBJECTS_4 = \ advdll_cocoa_datetimectrl.o \ advdll_osx_cocoa_taskbar.o \ advdll_hidjoystick.o \ - advdll_cocoa_activityindicator.o + advdll_cocoa_activityindicator.o \ + advdll_cocoa_notifmsg.o @COND_TOOLKIT_OSX_COCOA@__ADVANCED_PLATFORM_SRC_OBJECTS_4 = $(COND_TOOLKIT_OSX_COCOA___ADVANCED_PLATFORM_SRC_OBJECTS_4) @COND_TOOLKIT_OSX_IPHONE@__ADVANCED_PLATFORM_SRC_OBJECTS_4 \ @COND_TOOLKIT_OSX_IPHONE@ = advdll_animateg.o advdll_sound_osx.o \ @@ -11673,7 +11681,8 @@ COND_TOOLKIT_OSX_COCOA___ADVANCED_PLATFORM_SRC_OBJECTS_5 = \ advdll_cocoa_datetimectrl.o \ advdll_osx_cocoa_taskbar.o \ advdll_hidjoystick.o \ - advdll_cocoa_activityindicator.o + advdll_cocoa_activityindicator.o \ + advdll_cocoa_notifmsg.o @COND_TOOLKIT_OSX_COCOA@__ADVANCED_PLATFORM_SRC_OBJECTS_5 = $(COND_TOOLKIT_OSX_COCOA___ADVANCED_PLATFORM_SRC_OBJECTS_5) @COND_TOOLKIT_OSX_IPHONE@__ADVANCED_PLATFORM_SRC_OBJECTS_5 \ @COND_TOOLKIT_OSX_IPHONE@ = advdll_animateg.o advdll_sound_osx.o \ @@ -11750,6 +11759,7 @@ COND_WXUNIV_0___ADVANCED_SRC_OBJECTS_3 = \ advlib_treelist.o \ advlib_wizard.o \ advlib_addremovectrl.o \ + advlib_notifmsgcmn.o \ $(__ADVANCED_PLATFORM_SRC_OBJECTS_6) \ $(__ADVANCED_PLATFORM_NATIVE_SRC_OBJECTS_3) @COND_WXUNIV_0@__ADVANCED_SRC_OBJECTS_3 = $(COND_WXUNIV_0___ADVANCED_SRC_OBJECTS_3) @@ -11788,6 +11798,7 @@ COND_WXUNIV_1___ADVANCED_SRC_OBJECTS_3 = \ advlib_treelist.o \ advlib_wizard.o \ advlib_addremovectrl.o \ + advlib_notifmsgcmn.o \ $(__ADVANCED_PLATFORM_SRC_OBJECTS_7) \ $(__ADVANCED_UNIV_SRC_OBJECTS_3) @COND_WXUNIV_1@__ADVANCED_SRC_OBJECTS_3 = $(COND_WXUNIV_1___ADVANCED_SRC_OBJECTS_3) @@ -11851,7 +11862,8 @@ COND_TOOLKIT_OSX_COCOA___ADVANCED_PLATFORM_SRC_OBJECTS_6 = \ advlib_cocoa_datetimectrl.o \ advlib_osx_cocoa_taskbar.o \ advlib_hidjoystick.o \ - advlib_cocoa_activityindicator.o + advlib_cocoa_activityindicator.o \ + advlib_cocoa_notifmsg.o @COND_TOOLKIT_OSX_COCOA@__ADVANCED_PLATFORM_SRC_OBJECTS_6 = $(COND_TOOLKIT_OSX_COCOA___ADVANCED_PLATFORM_SRC_OBJECTS_6) @COND_TOOLKIT_OSX_IPHONE@__ADVANCED_PLATFORM_SRC_OBJECTS_6 \ @COND_TOOLKIT_OSX_IPHONE@ = advlib_animateg.o advlib_sound_osx.o \ @@ -11965,7 +11977,8 @@ COND_TOOLKIT_OSX_COCOA___ADVANCED_PLATFORM_SRC_OBJECTS_7 = \ advlib_cocoa_datetimectrl.o \ advlib_osx_cocoa_taskbar.o \ advlib_hidjoystick.o \ - advlib_cocoa_activityindicator.o + advlib_cocoa_activityindicator.o \ + advlib_cocoa_notifmsg.o @COND_TOOLKIT_OSX_COCOA@__ADVANCED_PLATFORM_SRC_OBJECTS_7 = $(COND_TOOLKIT_OSX_COCOA___ADVANCED_PLATFORM_SRC_OBJECTS_7) @COND_TOOLKIT_OSX_IPHONE@__ADVANCED_PLATFORM_SRC_OBJECTS_7 \ @COND_TOOLKIT_OSX_IPHONE@ = advlib_animateg.o advlib_sound_osx.o \ @@ -19940,6 +19953,9 @@ monodll_sound_sdl.o: $(srcdir)/src/unix/sound_sdl.cpp $(MONODLL_ODEP) @COND_USE_GUI_1@monodll_addremovectrl.o: $(srcdir)/src/common/addremovectrl.cpp $(MONODLL_ODEP) @COND_USE_GUI_1@ $(CXXC) -c -o $@ $(MONODLL_CXXFLAGS) $(srcdir)/src/common/addremovectrl.cpp +@COND_USE_GUI_1@monodll_notifmsgcmn.o: $(srcdir)/src/common/notifmsgcmn.cpp $(MONODLL_ODEP) +@COND_USE_GUI_1@ $(CXXC) -c -o $@ $(MONODLL_CXXFLAGS) $(srcdir)/src/common/notifmsgcmn.cpp + @COND_TOOLKIT_MSW_USE_GUI_1@monodll_taskbarcmn.o: $(srcdir)/src/common/taskbarcmn.cpp $(MONODLL_ODEP) @COND_TOOLKIT_MSW_USE_GUI_1@ $(CXXC) -c -o $@ $(MONODLL_CXXFLAGS) $(srcdir)/src/common/taskbarcmn.cpp @@ -20084,6 +20100,9 @@ monodll_sound_sdl.o: $(srcdir)/src/unix/sound_sdl.cpp $(MONODLL_ODEP) @COND_TOOLKIT_OSX_COCOA_USE_GUI_1@monodll_cocoa_activityindicator.o: $(srcdir)/src/osx/cocoa/activityindicator.mm $(MONODLL_ODEP) @COND_TOOLKIT_OSX_COCOA_USE_GUI_1@ $(CXXC) -c -o $@ $(MONODLL_OBJCXXFLAGS) $(srcdir)/src/osx/cocoa/activityindicator.mm +@COND_TOOLKIT_OSX_COCOA_USE_GUI_1@monodll_cocoa_notifmsg.o: $(srcdir)/src/osx/cocoa/notifmsg.mm $(MONODLL_ODEP) +@COND_TOOLKIT_OSX_COCOA_USE_GUI_1@ $(CXXC) -c -o $@ $(MONODLL_OBJCXXFLAGS) $(srcdir)/src/osx/cocoa/notifmsg.mm + @COND_TOOLKIT_COCOA_USE_GUI_1@monodll_src_cocoa_taskbar.o: $(srcdir)/src/cocoa/taskbar.mm $(MONODLL_ODEP) @COND_TOOLKIT_COCOA_USE_GUI_1@ $(CXXC) -c -o $@ $(MONODLL_OBJCXXFLAGS) $(srcdir)/src/cocoa/taskbar.mm @@ -24743,6 +24762,9 @@ monolib_sound_sdl.o: $(srcdir)/src/unix/sound_sdl.cpp $(MONOLIB_ODEP) @COND_USE_GUI_1@monolib_addremovectrl.o: $(srcdir)/src/common/addremovectrl.cpp $(MONOLIB_ODEP) @COND_USE_GUI_1@ $(CXXC) -c -o $@ $(MONOLIB_CXXFLAGS) $(srcdir)/src/common/addremovectrl.cpp +@COND_USE_GUI_1@monolib_notifmsgcmn.o: $(srcdir)/src/common/notifmsgcmn.cpp $(MONOLIB_ODEP) +@COND_USE_GUI_1@ $(CXXC) -c -o $@ $(MONOLIB_CXXFLAGS) $(srcdir)/src/common/notifmsgcmn.cpp + @COND_TOOLKIT_MSW_USE_GUI_1@monolib_taskbarcmn.o: $(srcdir)/src/common/taskbarcmn.cpp $(MONOLIB_ODEP) @COND_TOOLKIT_MSW_USE_GUI_1@ $(CXXC) -c -o $@ $(MONOLIB_CXXFLAGS) $(srcdir)/src/common/taskbarcmn.cpp @@ -24887,6 +24909,9 @@ monolib_sound_sdl.o: $(srcdir)/src/unix/sound_sdl.cpp $(MONOLIB_ODEP) @COND_TOOLKIT_OSX_COCOA_USE_GUI_1@monolib_cocoa_activityindicator.o: $(srcdir)/src/osx/cocoa/activityindicator.mm $(MONOLIB_ODEP) @COND_TOOLKIT_OSX_COCOA_USE_GUI_1@ $(CXXC) -c -o $@ $(MONOLIB_OBJCXXFLAGS) $(srcdir)/src/osx/cocoa/activityindicator.mm +@COND_TOOLKIT_OSX_COCOA_USE_GUI_1@monolib_cocoa_notifmsg.o: $(srcdir)/src/osx/cocoa/notifmsg.mm $(MONOLIB_ODEP) +@COND_TOOLKIT_OSX_COCOA_USE_GUI_1@ $(CXXC) -c -o $@ $(MONOLIB_OBJCXXFLAGS) $(srcdir)/src/osx/cocoa/notifmsg.mm + @COND_TOOLKIT_COCOA_USE_GUI_1@monolib_src_cocoa_taskbar.o: $(srcdir)/src/cocoa/taskbar.mm $(MONOLIB_ODEP) @COND_TOOLKIT_COCOA_USE_GUI_1@ $(CXXC) -c -o $@ $(MONOLIB_OBJCXXFLAGS) $(srcdir)/src/cocoa/taskbar.mm @@ -33014,6 +33039,9 @@ advdll_wizard.o: $(srcdir)/src/generic/wizard.cpp $(ADVDLL_ODEP) advdll_addremovectrl.o: $(srcdir)/src/common/addremovectrl.cpp $(ADVDLL_ODEP) $(CXXC) -c -o $@ $(ADVDLL_CXXFLAGS) $(srcdir)/src/common/addremovectrl.cpp +advdll_notifmsgcmn.o: $(srcdir)/src/common/notifmsgcmn.cpp $(ADVDLL_ODEP) + $(CXXC) -c -o $@ $(ADVDLL_CXXFLAGS) $(srcdir)/src/common/notifmsgcmn.cpp + @COND_TOOLKIT_MSW@advdll_taskbarcmn.o: $(srcdir)/src/common/taskbarcmn.cpp $(ADVDLL_ODEP) @COND_TOOLKIT_MSW@ $(CXXC) -c -o $@ $(ADVDLL_CXXFLAGS) $(srcdir)/src/common/taskbarcmn.cpp @@ -33158,6 +33186,9 @@ advdll_addremovectrl.o: $(srcdir)/src/common/addremovectrl.cpp $(ADVDLL_ODEP) @COND_TOOLKIT_OSX_COCOA@advdll_cocoa_activityindicator.o: $(srcdir)/src/osx/cocoa/activityindicator.mm $(ADVDLL_ODEP) @COND_TOOLKIT_OSX_COCOA@ $(CXXC) -c -o $@ $(ADVDLL_OBJCXXFLAGS) $(srcdir)/src/osx/cocoa/activityindicator.mm +@COND_TOOLKIT_OSX_COCOA@advdll_cocoa_notifmsg.o: $(srcdir)/src/osx/cocoa/notifmsg.mm $(ADVDLL_ODEP) +@COND_TOOLKIT_OSX_COCOA@ $(CXXC) -c -o $@ $(ADVDLL_OBJCXXFLAGS) $(srcdir)/src/osx/cocoa/notifmsg.mm + @COND_TOOLKIT_COCOA@advdll_src_cocoa_taskbar.o: $(srcdir)/src/cocoa/taskbar.mm $(ADVDLL_ODEP) @COND_TOOLKIT_COCOA@ $(CXXC) -c -o $@ $(ADVDLL_OBJCXXFLAGS) $(srcdir)/src/cocoa/taskbar.mm @@ -33455,6 +33486,9 @@ advlib_wizard.o: $(srcdir)/src/generic/wizard.cpp $(ADVLIB_ODEP) advlib_addremovectrl.o: $(srcdir)/src/common/addremovectrl.cpp $(ADVLIB_ODEP) $(CXXC) -c -o $@ $(ADVLIB_CXXFLAGS) $(srcdir)/src/common/addremovectrl.cpp +advlib_notifmsgcmn.o: $(srcdir)/src/common/notifmsgcmn.cpp $(ADVLIB_ODEP) + $(CXXC) -c -o $@ $(ADVLIB_CXXFLAGS) $(srcdir)/src/common/notifmsgcmn.cpp + @COND_TOOLKIT_MSW@advlib_taskbarcmn.o: $(srcdir)/src/common/taskbarcmn.cpp $(ADVLIB_ODEP) @COND_TOOLKIT_MSW@ $(CXXC) -c -o $@ $(ADVLIB_CXXFLAGS) $(srcdir)/src/common/taskbarcmn.cpp @@ -33599,6 +33633,9 @@ advlib_addremovectrl.o: $(srcdir)/src/common/addremovectrl.cpp $(ADVLIB_ODEP) @COND_TOOLKIT_OSX_COCOA@advlib_cocoa_activityindicator.o: $(srcdir)/src/osx/cocoa/activityindicator.mm $(ADVLIB_ODEP) @COND_TOOLKIT_OSX_COCOA@ $(CXXC) -c -o $@ $(ADVLIB_OBJCXXFLAGS) $(srcdir)/src/osx/cocoa/activityindicator.mm +@COND_TOOLKIT_OSX_COCOA@advlib_cocoa_notifmsg.o: $(srcdir)/src/osx/cocoa/notifmsg.mm $(ADVLIB_ODEP) +@COND_TOOLKIT_OSX_COCOA@ $(CXXC) -c -o $@ $(ADVLIB_OBJCXXFLAGS) $(srcdir)/src/osx/cocoa/notifmsg.mm + @COND_TOOLKIT_COCOA@advlib_src_cocoa_taskbar.o: $(srcdir)/src/cocoa/taskbar.mm $(ADVLIB_ODEP) @COND_TOOLKIT_COCOA@ $(CXXC) -c -o $@ $(ADVLIB_OBJCXXFLAGS) $(srcdir)/src/cocoa/taskbar.mm diff --git a/build/bakefiles/files.bkl b/build/bakefiles/files.bkl index 94f3e22073..073c850a02 100644 --- a/build/bakefiles/files.bkl +++ b/build/bakefiles/files.bkl @@ -2663,6 +2663,7 @@ IMPORTANT: please read docs/tech/tn0016.txt before modifying this file! src/generic/treelist.cpp src/generic/wizard.cpp src/common/addremovectrl.cpp + src/common/notifmsgcmn.cpp @@ -2728,7 +2729,6 @@ IMPORTANT: please read docs/tech/tn0016.txt before modifying this file! src/msw/taskbar.cpp - wx/msw/notifmsg.h wx/msw/sound.h wx/msw/taskbar.h @@ -2782,6 +2782,7 @@ IMPORTANT: please read docs/tech/tn0016.txt before modifying this file! src/osx/cocoa/taskbar.mm src/osx/core/hidjoystick.cpp src/osx/cocoa/activityindicator.mm + src/osx/cocoa/notifmsg.mm @@ -2879,7 +2880,6 @@ IMPORTANT: please read docs/tech/tn0016.txt before modifying this file! $(ADVANCED_GTK_PLATFORM_HDR) - wx/gtk/notifmsg.h wx/gtk/taskbar.h wx/generic/activityindicator.h diff --git a/build/files b/build/files index 101dcc076a..7a741064e2 100644 --- a/build/files +++ b/build/files @@ -2253,6 +2253,7 @@ ADVANCED_CMN_SRC = src/common/datavcmn.cpp src/common/gridcmn.cpp src/common/hyperlnkcmn.cpp + src/common/notifmsgcmn.cpp src/common/odcombocmn.cpp src/common/richtooltipcmn.cpp src/generic/aboutdlgg.cpp @@ -2342,7 +2343,6 @@ ADVANCED_MSW_SRC = src/msw/sound.cpp src/msw/taskbar.cpp ADVANCED_MSW_HDR = - wx/msw/notifmsg.h wx/msw/sound.h wx/msw/taskbar.h @@ -2389,6 +2389,7 @@ ADVANCED_OSX_COCOA_SRC = src/osx/dataview_osx.cpp src/osx/cocoa/dataview.mm src/osx/cocoa/datetimectrl.mm + src/osx/cocoa/notifmsg.mm src/osx/cocoa/taskbar.mm src/osx/core/hidjoystick.cpp @@ -2464,7 +2465,6 @@ ADVANCED_GTK2_SRC = ADVANCED_GTK_HDR = $(ADVANCED_GTK_PLATFORM_HDR) wx/generic/activityindicator.h - wx/gtk/notifmsg.h wx/gtk/taskbar.h ADVANCED_GTK2_HDR = $(ADVANCED_GTK_HDR) diff --git a/build/msw/makefile.bcc b/build/msw/makefile.bcc index 743da82751..70f891216e 100644 --- a/build/msw/makefile.bcc +++ b/build/msw/makefile.bcc @@ -2371,6 +2371,7 @@ ____ADVANCED_SRC_FILENAMES_OBJECTS = \ $(OBJS)\monodll_treelist.obj \ $(OBJS)\monodll_wizard.obj \ $(OBJS)\monodll_addremovectrl.obj \ + $(OBJS)\monodll_notifmsgcmn.obj \ $(OBJS)\monodll_taskbarcmn.obj \ $(OBJS)\monodll_aboutdlg.obj \ $(OBJS)\monodll_notifmsg.obj \ @@ -2425,6 +2426,7 @@ ____ADVANCED_SRC_FILENAMES_OBJECTS = \ $(OBJS)\monodll_treelist.obj \ $(OBJS)\monodll_wizard.obj \ $(OBJS)\monodll_addremovectrl.obj \ + $(OBJS)\monodll_notifmsgcmn.obj \ $(OBJS)\monodll_taskbarcmn.obj \ $(OBJS)\monodll_aboutdlg.obj \ $(OBJS)\monodll_notifmsg.obj \ @@ -3193,6 +3195,7 @@ ____ADVANCED_SRC_FILENAMES_1_OBJECTS = \ $(OBJS)\monolib_treelist.obj \ $(OBJS)\monolib_wizard.obj \ $(OBJS)\monolib_addremovectrl.obj \ + $(OBJS)\monolib_notifmsgcmn.obj \ $(OBJS)\monolib_taskbarcmn.obj \ $(OBJS)\monolib_aboutdlg.obj \ $(OBJS)\monolib_notifmsg.obj \ @@ -3247,6 +3250,7 @@ ____ADVANCED_SRC_FILENAMES_1_OBJECTS = \ $(OBJS)\monolib_treelist.obj \ $(OBJS)\monolib_wizard.obj \ $(OBJS)\monolib_addremovectrl.obj \ + $(OBJS)\monolib_notifmsgcmn.obj \ $(OBJS)\monolib_taskbarcmn.obj \ $(OBJS)\monolib_aboutdlg.obj \ $(OBJS)\monolib_notifmsg.obj \ @@ -4466,6 +4470,7 @@ ____ADVANCED_SRC_FILENAMES_2_OBJECTS = \ $(OBJS)\advdll_treelist.obj \ $(OBJS)\advdll_wizard.obj \ $(OBJS)\advdll_addremovectrl.obj \ + $(OBJS)\advdll_notifmsgcmn.obj \ $(OBJS)\advdll_taskbarcmn.obj \ $(OBJS)\advdll_aboutdlg.obj \ $(OBJS)\advdll_notifmsg.obj \ @@ -4520,6 +4525,7 @@ ____ADVANCED_SRC_FILENAMES_2_OBJECTS = \ $(OBJS)\advdll_treelist.obj \ $(OBJS)\advdll_wizard.obj \ $(OBJS)\advdll_addremovectrl.obj \ + $(OBJS)\advdll_notifmsgcmn.obj \ $(OBJS)\advdll_taskbarcmn.obj \ $(OBJS)\advdll_aboutdlg.obj \ $(OBJS)\advdll_notifmsg.obj \ @@ -4569,6 +4575,7 @@ ____ADVANCED_SRC_FILENAMES_3_OBJECTS = \ $(OBJS)\advlib_treelist.obj \ $(OBJS)\advlib_wizard.obj \ $(OBJS)\advlib_addremovectrl.obj \ + $(OBJS)\advlib_notifmsgcmn.obj \ $(OBJS)\advlib_taskbarcmn.obj \ $(OBJS)\advlib_aboutdlg.obj \ $(OBJS)\advlib_notifmsg.obj \ @@ -4623,6 +4630,7 @@ ____ADVANCED_SRC_FILENAMES_3_OBJECTS = \ $(OBJS)\advlib_treelist.obj \ $(OBJS)\advlib_wizard.obj \ $(OBJS)\advlib_addremovectrl.obj \ + $(OBJS)\advlib_notifmsgcmn.obj \ $(OBJS)\advlib_taskbarcmn.obj \ $(OBJS)\advlib_aboutdlg.obj \ $(OBJS)\advlib_notifmsg.obj \ @@ -8801,6 +8809,11 @@ $(OBJS)\monodll_addremovectrl.obj: ..\..\src\common\addremovectrl.cpp $(CXX) -q -c -P -o$@ $(MONODLL_CXXFLAGS) ..\..\src\common\addremovectrl.cpp !endif +!if "$(USE_GUI)" == "1" +$(OBJS)\monodll_notifmsgcmn.obj: ..\..\src\common\notifmsgcmn.cpp + $(CXX) -q -c -P -o$@ $(MONODLL_CXXFLAGS) ..\..\src\common\notifmsgcmn.cpp +!endif + !if "$(USE_GUI)" == "1" $(OBJS)\monodll_taskbarcmn.obj: ..\..\src\common\taskbarcmn.cpp $(CXX) -q -c -P -o$@ $(MONODLL_CXXFLAGS) ..\..\src\common\taskbarcmn.cpp @@ -11311,6 +11324,11 @@ $(OBJS)\monolib_addremovectrl.obj: ..\..\src\common\addremovectrl.cpp $(CXX) -q -c -P -o$@ $(MONOLIB_CXXFLAGS) ..\..\src\common\addremovectrl.cpp !endif +!if "$(USE_GUI)" == "1" +$(OBJS)\monolib_notifmsgcmn.obj: ..\..\src\common\notifmsgcmn.cpp + $(CXX) -q -c -P -o$@ $(MONOLIB_CXXFLAGS) ..\..\src\common\notifmsgcmn.cpp +!endif + !if "$(USE_GUI)" == "1" $(OBJS)\monolib_taskbarcmn.obj: ..\..\src\common\taskbarcmn.cpp $(CXX) -q -c -P -o$@ $(MONOLIB_CXXFLAGS) ..\..\src\common\taskbarcmn.cpp @@ -15189,6 +15207,9 @@ $(OBJS)\advdll_wizard.obj: ..\..\src\generic\wizard.cpp $(OBJS)\advdll_addremovectrl.obj: ..\..\src\common\addremovectrl.cpp $(CXX) -q -c -P -o$@ $(ADVDLL_CXXFLAGS) ..\..\src\common\addremovectrl.cpp +$(OBJS)\advdll_notifmsgcmn.obj: ..\..\src\common\notifmsgcmn.cpp + $(CXX) -q -c -P -o$@ $(ADVDLL_CXXFLAGS) ..\..\src\common\notifmsgcmn.cpp + $(OBJS)\advdll_taskbarcmn.obj: ..\..\src\common\taskbarcmn.cpp $(CXX) -q -c -P -o$@ $(ADVDLL_CXXFLAGS) ..\..\src\common\taskbarcmn.cpp @@ -15345,6 +15366,9 @@ $(OBJS)\advlib_wizard.obj: ..\..\src\generic\wizard.cpp $(OBJS)\advlib_addremovectrl.obj: ..\..\src\common\addremovectrl.cpp $(CXX) -q -c -P -o$@ $(ADVLIB_CXXFLAGS) ..\..\src\common\addremovectrl.cpp +$(OBJS)\advlib_notifmsgcmn.obj: ..\..\src\common\notifmsgcmn.cpp + $(CXX) -q -c -P -o$@ $(ADVLIB_CXXFLAGS) ..\..\src\common\notifmsgcmn.cpp + $(OBJS)\advlib_taskbarcmn.obj: ..\..\src\common\taskbarcmn.cpp $(CXX) -q -c -P -o$@ $(ADVLIB_CXXFLAGS) ..\..\src\common\taskbarcmn.cpp diff --git a/build/msw/makefile.gcc b/build/msw/makefile.gcc index f51f1d2274..969609d25e 100644 --- a/build/msw/makefile.gcc +++ b/build/msw/makefile.gcc @@ -2393,6 +2393,7 @@ ____ADVANCED_SRC_FILENAMES_OBJECTS = \ $(OBJS)\monodll_treelist.o \ $(OBJS)\monodll_wizard.o \ $(OBJS)\monodll_addremovectrl.o \ + $(OBJS)\monodll_notifmsgcmn.o \ $(OBJS)\monodll_taskbarcmn.o \ $(OBJS)\monodll_aboutdlg.o \ $(OBJS)\monodll_notifmsg.o \ @@ -2447,6 +2448,7 @@ ____ADVANCED_SRC_FILENAMES_OBJECTS = \ $(OBJS)\monodll_treelist.o \ $(OBJS)\monodll_wizard.o \ $(OBJS)\monodll_addremovectrl.o \ + $(OBJS)\monodll_notifmsgcmn.o \ $(OBJS)\monodll_taskbarcmn.o \ $(OBJS)\monodll_aboutdlg.o \ $(OBJS)\monodll_notifmsg.o \ @@ -3221,6 +3223,7 @@ ____ADVANCED_SRC_FILENAMES_1_OBJECTS = \ $(OBJS)\monolib_treelist.o \ $(OBJS)\monolib_wizard.o \ $(OBJS)\monolib_addremovectrl.o \ + $(OBJS)\monolib_notifmsgcmn.o \ $(OBJS)\monolib_taskbarcmn.o \ $(OBJS)\monolib_aboutdlg.o \ $(OBJS)\monolib_notifmsg.o \ @@ -3275,6 +3278,7 @@ ____ADVANCED_SRC_FILENAMES_1_OBJECTS = \ $(OBJS)\monolib_treelist.o \ $(OBJS)\monolib_wizard.o \ $(OBJS)\monolib_addremovectrl.o \ + $(OBJS)\monolib_notifmsgcmn.o \ $(OBJS)\monolib_taskbarcmn.o \ $(OBJS)\monolib_aboutdlg.o \ $(OBJS)\monolib_notifmsg.o \ @@ -4522,6 +4526,7 @@ ____ADVANCED_SRC_FILENAMES_2_OBJECTS = \ $(OBJS)\advdll_treelist.o \ $(OBJS)\advdll_wizard.o \ $(OBJS)\advdll_addremovectrl.o \ + $(OBJS)\advdll_notifmsgcmn.o \ $(OBJS)\advdll_taskbarcmn.o \ $(OBJS)\advdll_aboutdlg.o \ $(OBJS)\advdll_notifmsg.o \ @@ -4576,6 +4581,7 @@ ____ADVANCED_SRC_FILENAMES_2_OBJECTS = \ $(OBJS)\advdll_treelist.o \ $(OBJS)\advdll_wizard.o \ $(OBJS)\advdll_addremovectrl.o \ + $(OBJS)\advdll_notifmsgcmn.o \ $(OBJS)\advdll_taskbarcmn.o \ $(OBJS)\advdll_aboutdlg.o \ $(OBJS)\advdll_notifmsg.o \ @@ -4629,6 +4635,7 @@ ____ADVANCED_SRC_FILENAMES_3_OBJECTS = \ $(OBJS)\advlib_treelist.o \ $(OBJS)\advlib_wizard.o \ $(OBJS)\advlib_addremovectrl.o \ + $(OBJS)\advlib_notifmsgcmn.o \ $(OBJS)\advlib_taskbarcmn.o \ $(OBJS)\advlib_aboutdlg.o \ $(OBJS)\advlib_notifmsg.o \ @@ -4683,6 +4690,7 @@ ____ADVANCED_SRC_FILENAMES_3_OBJECTS = \ $(OBJS)\advlib_treelist.o \ $(OBJS)\advlib_wizard.o \ $(OBJS)\advlib_addremovectrl.o \ + $(OBJS)\advlib_notifmsgcmn.o \ $(OBJS)\advlib_taskbarcmn.o \ $(OBJS)\advlib_aboutdlg.o \ $(OBJS)\advlib_notifmsg.o \ @@ -8976,6 +8984,11 @@ $(OBJS)\monodll_addremovectrl.o: ../../src/common/addremovectrl.cpp $(CXX) -c -o $@ $(MONODLL_CXXFLAGS) $(CPPDEPS) $< endif +ifeq ($(USE_GUI),1) +$(OBJS)\monodll_notifmsgcmn.o: ../../src/common/notifmsgcmn.cpp + $(CXX) -c -o $@ $(MONODLL_CXXFLAGS) $(CPPDEPS) $< +endif + ifeq ($(USE_GUI),1) $(OBJS)\monodll_taskbarcmn.o: ../../src/common/taskbarcmn.cpp $(CXX) -c -o $@ $(MONODLL_CXXFLAGS) $(CPPDEPS) $< @@ -11486,6 +11499,11 @@ $(OBJS)\monolib_addremovectrl.o: ../../src/common/addremovectrl.cpp $(CXX) -c -o $@ $(MONOLIB_CXXFLAGS) $(CPPDEPS) $< endif +ifeq ($(USE_GUI),1) +$(OBJS)\monolib_notifmsgcmn.o: ../../src/common/notifmsgcmn.cpp + $(CXX) -c -o $@ $(MONOLIB_CXXFLAGS) $(CPPDEPS) $< +endif + ifeq ($(USE_GUI),1) $(OBJS)\monolib_taskbarcmn.o: ../../src/common/taskbarcmn.cpp $(CXX) -c -o $@ $(MONOLIB_CXXFLAGS) $(CPPDEPS) $< @@ -15364,6 +15382,9 @@ $(OBJS)\advdll_wizard.o: ../../src/generic/wizard.cpp $(OBJS)\advdll_addremovectrl.o: ../../src/common/addremovectrl.cpp $(CXX) -c -o $@ $(ADVDLL_CXXFLAGS) $(CPPDEPS) $< +$(OBJS)\advdll_notifmsgcmn.o: ../../src/common/notifmsgcmn.cpp + $(CXX) -c -o $@ $(ADVDLL_CXXFLAGS) $(CPPDEPS) $< + $(OBJS)\advdll_taskbarcmn.o: ../../src/common/taskbarcmn.cpp $(CXX) -c -o $@ $(ADVDLL_CXXFLAGS) $(CPPDEPS) $< @@ -15520,6 +15541,9 @@ $(OBJS)\advlib_wizard.o: ../../src/generic/wizard.cpp $(OBJS)\advlib_addremovectrl.o: ../../src/common/addremovectrl.cpp $(CXX) -c -o $@ $(ADVLIB_CXXFLAGS) $(CPPDEPS) $< +$(OBJS)\advlib_notifmsgcmn.o: ../../src/common/notifmsgcmn.cpp + $(CXX) -c -o $@ $(ADVLIB_CXXFLAGS) $(CPPDEPS) $< + $(OBJS)\advlib_taskbarcmn.o: ../../src/common/taskbarcmn.cpp $(CXX) -c -o $@ $(ADVLIB_CXXFLAGS) $(CPPDEPS) $< diff --git a/build/msw/makefile.vc b/build/msw/makefile.vc index 090f83bcc1..422eea6e50 100644 --- a/build/msw/makefile.vc +++ b/build/msw/makefile.vc @@ -2671,6 +2671,7 @@ ____ADVANCED_SRC_FILENAMES_OBJECTS = \ $(OBJS)\monodll_treelist.obj \ $(OBJS)\monodll_wizard.obj \ $(OBJS)\monodll_addremovectrl.obj \ + $(OBJS)\monodll_notifmsgcmn.obj \ $(OBJS)\monodll_taskbarcmn.obj \ $(OBJS)\monodll_aboutdlg.obj \ $(OBJS)\monodll_notifmsg.obj \ @@ -2725,6 +2726,7 @@ ____ADVANCED_SRC_FILENAMES_OBJECTS = \ $(OBJS)\monodll_treelist.obj \ $(OBJS)\monodll_wizard.obj \ $(OBJS)\monodll_addremovectrl.obj \ + $(OBJS)\monodll_notifmsgcmn.obj \ $(OBJS)\monodll_taskbarcmn.obj \ $(OBJS)\monodll_aboutdlg.obj \ $(OBJS)\monodll_notifmsg.obj \ @@ -3499,6 +3501,7 @@ ____ADVANCED_SRC_FILENAMES_1_OBJECTS = \ $(OBJS)\monolib_treelist.obj \ $(OBJS)\monolib_wizard.obj \ $(OBJS)\monolib_addremovectrl.obj \ + $(OBJS)\monolib_notifmsgcmn.obj \ $(OBJS)\monolib_taskbarcmn.obj \ $(OBJS)\monolib_aboutdlg.obj \ $(OBJS)\monolib_notifmsg.obj \ @@ -3553,6 +3556,7 @@ ____ADVANCED_SRC_FILENAMES_1_OBJECTS = \ $(OBJS)\monolib_treelist.obj \ $(OBJS)\monolib_wizard.obj \ $(OBJS)\monolib_addremovectrl.obj \ + $(OBJS)\monolib_notifmsgcmn.obj \ $(OBJS)\monolib_taskbarcmn.obj \ $(OBJS)\monolib_aboutdlg.obj \ $(OBJS)\monolib_notifmsg.obj \ @@ -4862,6 +4866,7 @@ ____ADVANCED_SRC_FILENAMES_2_OBJECTS = \ $(OBJS)\advdll_treelist.obj \ $(OBJS)\advdll_wizard.obj \ $(OBJS)\advdll_addremovectrl.obj \ + $(OBJS)\advdll_notifmsgcmn.obj \ $(OBJS)\advdll_taskbarcmn.obj \ $(OBJS)\advdll_aboutdlg.obj \ $(OBJS)\advdll_notifmsg.obj \ @@ -4916,6 +4921,7 @@ ____ADVANCED_SRC_FILENAMES_2_OBJECTS = \ $(OBJS)\advdll_treelist.obj \ $(OBJS)\advdll_wizard.obj \ $(OBJS)\advdll_addremovectrl.obj \ + $(OBJS)\advdll_notifmsgcmn.obj \ $(OBJS)\advdll_taskbarcmn.obj \ $(OBJS)\advdll_aboutdlg.obj \ $(OBJS)\advdll_notifmsg.obj \ @@ -4971,6 +4977,7 @@ ____ADVANCED_SRC_FILENAMES_3_OBJECTS = \ $(OBJS)\advlib_treelist.obj \ $(OBJS)\advlib_wizard.obj \ $(OBJS)\advlib_addremovectrl.obj \ + $(OBJS)\advlib_notifmsgcmn.obj \ $(OBJS)\advlib_taskbarcmn.obj \ $(OBJS)\advlib_aboutdlg.obj \ $(OBJS)\advlib_notifmsg.obj \ @@ -5025,6 +5032,7 @@ ____ADVANCED_SRC_FILENAMES_3_OBJECTS = \ $(OBJS)\advlib_treelist.obj \ $(OBJS)\advlib_wizard.obj \ $(OBJS)\advlib_addremovectrl.obj \ + $(OBJS)\advlib_notifmsgcmn.obj \ $(OBJS)\advlib_taskbarcmn.obj \ $(OBJS)\advlib_aboutdlg.obj \ $(OBJS)\advlib_notifmsg.obj \ @@ -9493,6 +9501,11 @@ $(OBJS)\monodll_addremovectrl.obj: ..\..\src\common\addremovectrl.cpp $(CXX) /c /nologo /TP /Fo$@ $(MONODLL_CXXFLAGS) ..\..\src\common\addremovectrl.cpp !endif +!if "$(USE_GUI)" == "1" +$(OBJS)\monodll_notifmsgcmn.obj: ..\..\src\common\notifmsgcmn.cpp + $(CXX) /c /nologo /TP /Fo$@ $(MONODLL_CXXFLAGS) ..\..\src\common\notifmsgcmn.cpp +!endif + !if "$(USE_GUI)" == "1" $(OBJS)\monodll_taskbarcmn.obj: ..\..\src\common\taskbarcmn.cpp $(CXX) /c /nologo /TP /Fo$@ $(MONODLL_CXXFLAGS) ..\..\src\common\taskbarcmn.cpp @@ -12003,6 +12016,11 @@ $(OBJS)\monolib_addremovectrl.obj: ..\..\src\common\addremovectrl.cpp $(CXX) /c /nologo /TP /Fo$@ $(MONOLIB_CXXFLAGS) ..\..\src\common\addremovectrl.cpp !endif +!if "$(USE_GUI)" == "1" +$(OBJS)\monolib_notifmsgcmn.obj: ..\..\src\common\notifmsgcmn.cpp + $(CXX) /c /nologo /TP /Fo$@ $(MONOLIB_CXXFLAGS) ..\..\src\common\notifmsgcmn.cpp +!endif + !if "$(USE_GUI)" == "1" $(OBJS)\monolib_taskbarcmn.obj: ..\..\src\common\taskbarcmn.cpp $(CXX) /c /nologo /TP /Fo$@ $(MONOLIB_CXXFLAGS) ..\..\src\common\taskbarcmn.cpp @@ -15881,6 +15899,9 @@ $(OBJS)\advdll_wizard.obj: ..\..\src\generic\wizard.cpp $(OBJS)\advdll_addremovectrl.obj: ..\..\src\common\addremovectrl.cpp $(CXX) /c /nologo /TP /Fo$@ $(ADVDLL_CXXFLAGS) ..\..\src\common\addremovectrl.cpp +$(OBJS)\advdll_notifmsgcmn.obj: ..\..\src\common\notifmsgcmn.cpp + $(CXX) /c /nologo /TP /Fo$@ $(ADVDLL_CXXFLAGS) ..\..\src\common\notifmsgcmn.cpp + $(OBJS)\advdll_taskbarcmn.obj: ..\..\src\common\taskbarcmn.cpp $(CXX) /c /nologo /TP /Fo$@ $(ADVDLL_CXXFLAGS) ..\..\src\common\taskbarcmn.cpp @@ -16037,6 +16058,9 @@ $(OBJS)\advlib_wizard.obj: ..\..\src\generic\wizard.cpp $(OBJS)\advlib_addremovectrl.obj: ..\..\src\common\addremovectrl.cpp $(CXX) /c /nologo /TP /Fo$@ $(ADVLIB_CXXFLAGS) ..\..\src\common\addremovectrl.cpp +$(OBJS)\advlib_notifmsgcmn.obj: ..\..\src\common\notifmsgcmn.cpp + $(CXX) /c /nologo /TP /Fo$@ $(ADVLIB_CXXFLAGS) ..\..\src\common\notifmsgcmn.cpp + $(OBJS)\advlib_taskbarcmn.obj: ..\..\src\common\taskbarcmn.cpp $(CXX) /c /nologo /TP /Fo$@ $(ADVLIB_CXXFLAGS) ..\..\src\common\taskbarcmn.cpp diff --git a/build/msw/wx_adv.vcxproj b/build/msw/wx_adv.vcxproj index f4259082c1..db284de3ce 100644 --- a/build/msw/wx_adv.vcxproj +++ b/build/msw/wx_adv.vcxproj @@ -462,6 +462,7 @@ + @@ -544,7 +545,6 @@ - diff --git a/build/msw/wx_adv.vcxproj.filters b/build/msw/wx_adv.vcxproj.filters index 982ac7865a..1707dd9520 100644 --- a/build/msw/wx_adv.vcxproj.filters +++ b/build/msw/wx_adv.vcxproj.filters @@ -48,6 +48,9 @@ Common Sources + + Common Sources + Common Sources @@ -331,9 +334,6 @@ MSW Headers - - MSW Headers - MSW Headers @@ -388,4 +388,4 @@ MSW Headers - + \ No newline at end of file diff --git a/build/msw/wx_vc7_adv.vcproj b/build/msw/wx_vc7_adv.vcproj index 1401d0f420..5df855d911 100644 --- a/build/msw/wx_vc7_adv.vcproj +++ b/build/msw/wx_vc7_adv.vcproj @@ -324,6 +324,9 @@ + + @@ -587,9 +590,6 @@ - - diff --git a/build/msw/wx_vc7_core.vcproj b/build/msw/wx_vc7_core.vcproj index c07148bb87..9d26e38ba0 100644 --- a/build/msw/wx_vc7_core.vcproj +++ b/build/msw/wx_vc7_core.vcproj @@ -1505,9 +1505,6 @@ - - diff --git a/build/msw/wx_vc8_adv.vcproj b/build/msw/wx_vc8_adv.vcproj index 84da1eeab3..027d4b9056 100644 --- a/build/msw/wx_vc8_adv.vcproj +++ b/build/msw/wx_vc8_adv.vcproj @@ -837,6 +837,10 @@ RelativePath="..\..\src\common\hyperlnkcmn.cpp" > + + @@ -1285,10 +1289,6 @@ RelativePath="..\..\include\wx\msw\joystick.h" > - - diff --git a/build/msw/wx_vc8_core.vcproj b/build/msw/wx_vc8_core.vcproj index d4b862b4a1..6a6ee15189 100644 --- a/build/msw/wx_vc8_core.vcproj +++ b/build/msw/wx_vc8_core.vcproj @@ -2509,10 +2509,6 @@ RelativePath="..\..\include\wx\msw\notebook.h" > - - diff --git a/build/msw/wx_vc9_adv.vcproj b/build/msw/wx_vc9_adv.vcproj index 4cf1b51694..eda236aeba 100644 --- a/build/msw/wx_vc9_adv.vcproj +++ b/build/msw/wx_vc9_adv.vcproj @@ -833,6 +833,10 @@ RelativePath="..\..\src\common\hyperlnkcmn.cpp" > + + @@ -1281,10 +1285,6 @@ RelativePath="..\..\include\wx\msw\joystick.h" > - - diff --git a/build/msw/wx_vc9_core.vcproj b/build/msw/wx_vc9_core.vcproj index 0ffe069944..eb1fa98da3 100644 --- a/build/msw/wx_vc9_core.vcproj +++ b/build/msw/wx_vc9_core.vcproj @@ -2505,10 +2505,6 @@ RelativePath="..\..\include\wx\msw\notebook.h" > - - diff --git a/build/osx/wxcocoa.xcodeproj/project.pbxproj b/build/osx/wxcocoa.xcodeproj/project.pbxproj index 1198bede33..ef21984639 100644 --- a/build/osx/wxcocoa.xcodeproj/project.pbxproj +++ b/build/osx/wxcocoa.xcodeproj/project.pbxproj @@ -511,6 +511,12 @@ 23E9AF567E873B948EFEA180 /* gauge.mm in Sources */ = {isa = PBXBuildFile; fileRef = 98A7F0605AAC3D28A8C9F253 /* gauge.mm */; }; 23E9AF567E873B948EFEA181 /* gauge.mm in Sources */ = {isa = PBXBuildFile; fileRef = 98A7F0605AAC3D28A8C9F253 /* gauge.mm */; }; 23E9AF567E873B948EFEA182 /* gauge.mm in Sources */ = {isa = PBXBuildFile; fileRef = 98A7F0605AAC3D28A8C9F253 /* gauge.mm */; }; + 24133CCD1B78C2E80019C10F /* notifmsg.mm in Sources */ = {isa = PBXBuildFile; fileRef = 24133CCC1B78C2E80019C10F /* notifmsg.mm */; }; + 24133CCF1B78C3230019C10F /* notifmsgcmn.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 24133CCE1B78C3230019C10F /* notifmsgcmn.cpp */; }; + 24133CD01B78C3390019C10F /* notifmsgcmn.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 24133CCE1B78C3230019C10F /* notifmsgcmn.cpp */; }; + 24133CD11B78C3390019C10F /* notifmsg.mm in Sources */ = {isa = PBXBuildFile; fileRef = 24133CCC1B78C2E80019C10F /* notifmsg.mm */; }; + 24133CD21B78C33A0019C10F /* notifmsgcmn.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 24133CCE1B78C3230019C10F /* notifmsgcmn.cpp */; }; + 24133CD31B78C33A0019C10F /* notifmsg.mm in Sources */ = {isa = PBXBuildFile; fileRef = 24133CCC1B78C2E80019C10F /* notifmsg.mm */; }; 242E1D1A9BF331BA918134EC /* pngwtran.c in Sources */ = {isa = PBXBuildFile; fileRef = 0964797530CF3FE7B8DB6242 /* pngwtran.c */; }; 242E1D1A9BF331BA918134ED /* pngwtran.c in Sources */ = {isa = PBXBuildFile; fileRef = 0964797530CF3FE7B8DB6242 /* pngwtran.c */; }; 242E1D1A9BF331BA918134EE /* pngwtran.c in Sources */ = {isa = PBXBuildFile; fileRef = 0964797530CF3FE7B8DB6242 /* pngwtran.c */; }; @@ -3962,6 +3968,8 @@ 238741BDA2C73E56899CCB04 /* dcprint.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = dcprint.cpp; path = ../../src/osx/carbon/dcprint.cpp; sourceTree = ""; }; 239D386E9D7D39C5A1E859C6 /* clipcmn.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = clipcmn.cpp; path = ../../src/common/clipcmn.cpp; sourceTree = ""; }; 23FC98E2305230E2990471E3 /* wxcrt.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = wxcrt.cpp; path = ../../src/common/wxcrt.cpp; sourceTree = ""; }; + 24133CCC1B78C2E80019C10F /* notifmsg.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = notifmsg.mm; path = ../../src/osx/cocoa/notifmsg.mm; sourceTree = ""; }; + 24133CCE1B78C3230019C10F /* notifmsgcmn.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = notifmsgcmn.cpp; path = ../../src/common/notifmsgcmn.cpp; sourceTree = ""; }; 242BF97B558634A79322052C /* prntbase.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = prntbase.cpp; path = ../../src/common/prntbase.cpp; sourceTree = ""; }; 243367CA1C6B91A9000B8ED5 /* utils_base.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = utils_base.mm; path = ../../src/osx/cocoa/utils_base.mm; sourceTree = ""; }; 24396D584D053948A3FF0DCD /* imagpng.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = imagpng.cpp; path = ../../src/common/imagpng.cpp; sourceTree = ""; }; @@ -5557,6 +5565,8 @@ 2FF0B5E0505D3AEA9A4ACF11 /* adv */ = { isa = PBXGroup; children = ( + 24133CCE1B78C3230019C10F /* notifmsgcmn.cpp */, + 24133CCC1B78C2E80019C10F /* notifmsg.mm */, A8ABD099BCEA30DCBF7A04F4 /* animatecmn.cpp */, 8CF560E06F2A3B6088203D09 /* bmpcboxcmn.cpp */, 8D0EF4BDCB5F329ABE15EEED /* calctrlcmn.cpp */, @@ -7773,6 +7783,8 @@ B4425B59CC27389CA9FF81D3 /* datectlg.cpp in Sources */, 5557AA36FBCC3ED9A5F5751C /* editlbox.cpp in Sources */, A139B846584436BCBEBAE3C1 /* grid.cpp in Sources */, + 24133CD21B78C33A0019C10F /* notifmsgcmn.cpp in Sources */, + 24133CD31B78C33A0019C10F /* notifmsg.mm in Sources */, 2E930206397C3EDCBD8206FE /* gridctrl.cpp in Sources */, E5D698D2606A304DA743AF94 /* grideditors.cpp in Sources */, 187F921A95DA3594B0AD980F /* gridsel.cpp in Sources */, @@ -8649,6 +8661,7 @@ 42260A6F1853361083803B0D /* zutil.c in Sources */, 99E7A46106C03484BA70D29F /* tif_unix.c in Sources */, 4E396D8D2E9138D797F320C7 /* tif_aux.c in Sources */, + 24133CD01B78C3390019C10F /* notifmsgcmn.cpp in Sources */, 1EE845DDFDDE36CA8A218206 /* tif_close.c in Sources */, 8E674574343A3C009B1BCD01 /* tif_codec.c in Sources */, D95C5F467D37339AB8DF2355 /* tif_color.c in Sources */, @@ -8796,6 +8809,7 @@ E3AD8574E13B39BDB8D4E92F /* LexKVIrc.cxx in Sources */, 62331487C17B32E081B8FEA8 /* LexLaTeX.cxx in Sources */, DF8124E5E17D386A84CEEA28 /* LexLisp.cxx in Sources */, + 24133CD11B78C3390019C10F /* notifmsg.mm in Sources */, D13AE659C3AC37B68D39B2CA /* LexLout.cxx in Sources */, 9D003890CB7035A298DB7057 /* LexLua.cxx in Sources */, E80BEED62EBF34F09B3F4020 /* LexMagik.cxx in Sources */, @@ -9732,6 +9746,7 @@ D5C304182151365FA9FF8A3D /* xh_bttn.cpp in Sources */, FE9A662A1F9B34D099C45C1D /* xh_cald.cpp in Sources */, 6138BCBC8E4438FA91E0EF9F /* xh_chckb.cpp in Sources */, + 24133CCF1B78C3230019C10F /* notifmsgcmn.cpp in Sources */, 5F2C2A46781739D897CF293D /* xh_chckl.cpp in Sources */, CE17002B5B7E375582747639 /* xh_choic.cpp in Sources */, 26E4813A97DE323E88119163 /* xh_choicbk.cpp in Sources */, @@ -10009,6 +10024,7 @@ E0E40333B61C33B58787078E /* LexMarkdown.cxx in Sources */, 5AEA6E94FB76371D928D371C /* LexMatlab.cxx in Sources */, 1A4F9F18BBEB3515AC7C7CC6 /* LexMetapost.cxx in Sources */, + 24133CCD1B78C2E80019C10F /* notifmsg.mm in Sources */, 3C394FBD47B6310C80577E3B /* LexMMIXAL.cxx in Sources */, 7CC211E10D853B958250A4CE /* LexModula.cxx in Sources */, EC43AFB3670A3D459D9B388D /* LexMPT.cxx in Sources */, diff --git a/include/wx/generic/notifmsg.h b/include/wx/generic/notifmsg.h index 1cd74ba7f0..ccc55108c5 100644 --- a/include/wx/generic/notifmsg.h +++ b/include/wx/generic/notifmsg.h @@ -10,8 +10,6 @@ #ifndef _WX_GENERIC_NOTIFMSG_H_ #define _WX_GENERIC_NOTIFMSG_H_ -class wxNotificationMessageDialog; - // ---------------------------------------------------------------------------- // wxGenericNotificationMessage // ---------------------------------------------------------------------------- @@ -19,40 +17,29 @@ class wxNotificationMessageDialog; class WXDLLIMPEXP_ADV wxGenericNotificationMessage : public wxNotificationMessageBase { public: - wxGenericNotificationMessage() { Init(); } - wxGenericNotificationMessage(const wxString& title, - const wxString& message = wxString(), - wxWindow *parent = NULL, - int flags = wxICON_INFORMATION) - : wxNotificationMessageBase(title, message, parent, flags) + wxGenericNotificationMessage() { Init(); } - virtual ~wxGenericNotificationMessage(); - - - virtual bool Show(int timeout = Timeout_Auto); - virtual bool Close(); + wxGenericNotificationMessage(const wxString& title, + const wxString& message = wxString(), + wxWindow *parent = NULL, + int flags = wxICON_INFORMATION) + { + Init(); + Create(title, message, parent, flags); + } // generic implementation-specific methods // get/set the default timeout (used if Timeout_Auto is specified) - static int GetDefaultTimeout() { return ms_timeout; } + static int GetDefaultTimeout(); static void SetDefaultTimeout(int timeout); private: void Init(); - - // default timeout - static int ms_timeout; - - // notification message is represented by a modeless dialog in this - // implementation - wxNotificationMessageDialog *m_dialog; - - wxDECLARE_NO_COPY_CLASS(wxGenericNotificationMessage); }; diff --git a/include/wx/generic/private/notifmsg.h b/include/wx/generic/private/notifmsg.h new file mode 100644 index 0000000000..6c5fd90874 --- /dev/null +++ b/include/wx/generic/private/notifmsg.h @@ -0,0 +1,52 @@ +/////////////////////////////////////////////////////////////////////////////// +// Name: wx/generic/private/notifmsg.h +// Purpose: wxGenericNotificationMessage declarations +// Author: Tobias Taschner +// Created: 2015-08-04 +// Copyright: (c) 2015 wxWidgets development team +// Licence: wxWindows licence +/////////////////////////////////////////////////////////////////////////////// + +#ifndef _WX_GENERIC_PRIVATE_NOTIFMSG_H_ +#define _WX_GENERIC_PRIVATE_NOTIFMSG_H_ + +#include "wx/private/notifmsg.h" + +class wxGenericNotificationMessageImpl : public wxNotificationMessageImpl +{ +public: + wxGenericNotificationMessageImpl(wxNotificationMessageBase* notification); + + virtual ~wxGenericNotificationMessageImpl(); + + virtual bool Show(int timeout) wxOVERRIDE; + + virtual bool Close() wxOVERRIDE; + + virtual void SetTitle(const wxString& title) wxOVERRIDE; + + virtual void SetMessage(const wxString& message) wxOVERRIDE; + + virtual void SetParent(wxWindow *parent) wxOVERRIDE; + + virtual void SetFlags(int flags) wxOVERRIDE; + + virtual void SetIcon(const wxIcon& icon) wxOVERRIDE; + + virtual bool AddAction(wxWindowID actionid, const wxString &label) wxOVERRIDE; + + // get/set the default timeout (used if Timeout_Auto is specified) + static int GetDefaultTimeout() { return ms_timeout; } + static void SetDefaultTimeout(int timeout); + +private: + // default timeout + static int ms_timeout; + + // notification message is represented by a frame in this implementation + class wxNotificationMessageWindow *m_window; + + wxDECLARE_NO_COPY_CLASS(wxGenericNotificationMessageImpl); +}; + +#endif // _WX_GENERIC_PRIVATE_NOTIFMSG_H_ diff --git a/include/wx/gtk/notifmsg.h b/include/wx/gtk/notifmsg.h deleted file mode 100644 index 6547a5f90b..0000000000 --- a/include/wx/gtk/notifmsg.h +++ /dev/null @@ -1,51 +0,0 @@ -/////////////////////////////////////////////////////////////////////////////// -// Name: wx/gtk/notifmsg.h -// Purpose: wxNotificationMessage for wxGTK. -// Author: Vadim Zeitlin -// Created: 2012-07-25 -// Copyright: (c) 2012 Vadim Zeitlin -// Licence: wxWindows licence -/////////////////////////////////////////////////////////////////////////////// - -#ifndef _WX_GTK_NOTIFMSG_H_ -#define _WX_GTK_NOTIFMSG_H_ - -typedef struct _NotifyNotification NotifyNotification; - -// ---------------------------------------------------------------------------- -// wxNotificationMessage -// ---------------------------------------------------------------------------- - -class WXDLLIMPEXP_ADV wxNotificationMessage : public wxNotificationMessageBase -{ -public: - wxNotificationMessage() { Init(); } - wxNotificationMessage(const wxString& title, - const wxString& message = wxString(), - wxWindow *parent = NULL, - int flags = wxICON_INFORMATION) - : wxNotificationMessageBase(title, message, parent, flags) - { - Init(); - } - - virtual ~wxNotificationMessage(); - - - virtual bool Show(int timeout = Timeout_Auto) wxOVERRIDE; - virtual bool Close() wxOVERRIDE; - - // Set the name of the icon to use, overriding the default icon determined - // by the flags. Call with empty string to reset custom icon. - bool GTKSetIconName(const wxString& name); - -private: - void Init() { m_notification = NULL; } - - NotifyNotification* m_notification; - wxString m_iconName; - - wxDECLARE_NO_COPY_CLASS(wxNotificationMessage); -}; - -#endif // _WX_GTK_NOTIFMSG_H_ diff --git a/include/wx/msw/notifmsg.h b/include/wx/msw/notifmsg.h deleted file mode 100644 index b7e0e0e867..0000000000 --- a/include/wx/msw/notifmsg.h +++ /dev/null @@ -1,74 +0,0 @@ -/////////////////////////////////////////////////////////////////////////////// -// Name: wx/msw/notifmsg.h -// Purpose: implementation of wxNotificationMessage for Windows -// Author: Vadim Zeitlin -// Created: 2007-12-01 -// Copyright: (c) 2007 Vadim Zeitlin -// Licence: wxWindows licence -/////////////////////////////////////////////////////////////////////////////// - -#ifndef _WX_MSW_NOTIFMSG_H_ -#define _WX_MSW_NOTIFMSG_H_ - -class WXDLLIMPEXP_FWD_ADV wxTaskBarIcon; - -// ---------------------------------------------------------------------------- -// wxNotificationMessage -// ---------------------------------------------------------------------------- - -class WXDLLIMPEXP_ADV wxNotificationMessage : public wxNotificationMessageBase -{ -public: - wxNotificationMessage() { Init(); } - wxNotificationMessage(const wxString& title, - const wxString& message = wxString(), - wxWindow *parent = NULL, - int flags = wxICON_INFORMATION) - : wxNotificationMessageBase(title, message, parent, flags) - { - Init(); - } - - virtual ~wxNotificationMessage(); - - - virtual bool Show(int timeout = Timeout_Auto); - virtual bool Close(); - - // MSW implementation-specific methods - - // by default, wxNotificationMessage under MSW creates a temporary taskbar - // icon to which it attaches the notification, if there is an existing - // taskbar icon object in the application you may want to call this method - // to attach the notification to it instead (we won't take ownership of it - // and you can also pass NULL to not use the icon for notifications any - // more) - // - // returns the task bar icon which was used previously (may be NULL) - static wxTaskBarIcon *UseTaskBarIcon(wxTaskBarIcon *icon); - - // call this to always use the generic implementation, even if the system - // supports the balloon tooltips used by the native one - static void AlwaysUseGeneric(bool alwaysUseGeneric) - { - ms_alwaysUseGeneric = alwaysUseGeneric; - } - -private: - // common part of all ctors - void Init() { m_impl = NULL; } - - - // flag indicating whether we should always use generic implementation - static bool ms_alwaysUseGeneric; - - // the real implementation of this class (selected during run-time because - // the balloon task bar icons are not available in all Windows versions) - class wxNotifMsgImpl *m_impl; - - - wxDECLARE_NO_COPY_CLASS(wxNotificationMessage); -}; - -#endif // _WX_MSW_NOTIFMSG_H_ - diff --git a/include/wx/msw/taskbar.h b/include/wx/msw/taskbar.h index 5728a424f0..3fe5c9b61b 100644 --- a/include/wx/msw/taskbar.h +++ b/include/wx/msw/taskbar.h @@ -49,7 +49,8 @@ public: bool ShowBalloon(const wxString& title, const wxString& text, unsigned msec = 0, - int flags = 0); + int flags = 0, + const wxIcon& icon = wxNullIcon); #endif // wxUSE_TASKBARICON_BALLOONS protected: diff --git a/include/wx/notifmsg.h b/include/wx/notifmsg.h index a5298f8c45..bb4dae0a3b 100644 --- a/include/wx/notifmsg.h +++ b/include/wx/notifmsg.h @@ -29,8 +29,7 @@ public: // default ctor, use setters below to initialize it later wxNotificationMessageBase() { - m_parent = NULL; - m_flags = wxICON_INFORMATION; + Init(); } // create a notification object with the given title and message (the @@ -39,39 +38,38 @@ public: const wxString& message = wxEmptyString, wxWindow *parent = NULL, int flags = wxICON_INFORMATION) - : m_title(title), - m_message(message), - m_parent(parent) { - SetFlags(flags); + Init(); + Create(title, message, parent, flags); } + virtual ~wxNotificationMessageBase(); + // note that the setters must be called before Show() // set the title: short string, markup not allowed - void SetTitle(const wxString& title) { m_title = title; } + void SetTitle(const wxString& title); // set the text of the message: this is a longer string than the title and // some platforms allow simple HTML-like markup in it - void SetMessage(const wxString& message) { m_message = message; } + void SetMessage(const wxString& message); // set the parent for this notification: we'll be associated with the top // level parent of this window or, if this method is not called, with the // main application window by default - void SetParent(wxWindow *parent) { m_parent = parent; } + void SetParent(wxWindow *parent); // this method can currently be used to choose a standard icon to use: the // parameter may be one of wxICON_INFORMATION, wxICON_WARNING or // wxICON_ERROR only (but not wxICON_QUESTION) - void SetFlags(int flags) - { - wxASSERT_MSG( flags == wxICON_INFORMATION || - flags == wxICON_WARNING || flags == wxICON_ERROR, - "Invalid icon flags specified" ); + void SetFlags(int flags); - m_flags = flags; - } + // set a custom icon to use instead of the system provided specified via SetFlags + virtual void SetIcon(const wxIcon& icon); + // Add a button to the notification, returns false if the platform does not support + // actions in notifications + virtual bool AddAction(wxWindowID actionid, const wxString &label = wxString()); // showing and hiding // ------------------ @@ -87,70 +85,92 @@ public: // pass (special values Timeout_Auto and Timeout_Never can be used) // // returns false if an error occurred - virtual bool Show(int timeout = Timeout_Auto) = 0; + bool Show(int timeout = Timeout_Auto); // hide the notification, returns true if it was hidden or false if it // couldn't be done (e.g. on some systems automatically hidden // notifications can't be hidden manually) - virtual bool Close() = 0; + bool Close(); protected: - // accessors for the derived classes - const wxString& GetTitle() const { return m_title; } - const wxString& GetMessage() const { return m_message; } - wxWindow *GetParent() const { return m_parent; } - int GetFlags() const { return m_flags; } - - // return the concatenation of title and message separated by a new line, - // this is suitable for simple implementation which have no support for - // separate title and message parts of the notification - wxString GetFullMessage() const + // Common part of all ctors. + void Create(const wxString& title = wxEmptyString, + const wxString& message = wxEmptyString, + wxWindow *parent = NULL, + int flags = wxICON_INFORMATION) { - wxString text(m_title); - if ( !m_message.empty() ) - { - text << "\n\n" << m_message; - } - - return text; + SetTitle(title); + SetMessage(message); + SetParent(parent); + SetFlags(flags); } + class wxNotificationMessageImpl* m_impl; + private: - wxString m_title, - m_message; - wxWindow *m_parent; - - int m_flags; + void Init() + { + m_impl = NULL; + } wxDECLARE_NO_COPY_CLASS(wxNotificationMessageBase); }; -/* - TODO: Implement under OS X using notification centre (10.8+) or - Growl (http://growl.info/) for the previous versions. - */ -#if defined(__WXGTK__) && wxUSE_LIBNOTIFY - #include "wx/gtk/notifmsg.h" -#elif defined(__WXMSW__) && wxUSE_TASKBARICON && wxUSE_TASKBARICON_BALLOONS - #include "wx/msw/notifmsg.h" -#else - #include "wx/generic/notifmsg.h" +wxDECLARE_EXPORTED_EVENT( WXDLLIMPEXP_ADV, wxEVT_NOTIFICATION_MESSAGE_CLICK, wxCommandEvent ); +wxDECLARE_EXPORTED_EVENT( WXDLLIMPEXP_ADV, wxEVT_NOTIFICATION_MESSAGE_DISMISSED, wxCommandEvent ); +wxDECLARE_EXPORTED_EVENT( WXDLLIMPEXP_ADV, wxEVT_NOTIFICATION_MESSAGE_ACTION, wxCommandEvent ); - class wxNotificationMessage : public wxGenericNotificationMessage - { - public: - wxNotificationMessage() { } - wxNotificationMessage(const wxString& title, - const wxString& message = wxEmptyString, - wxWindow *parent = NULL, - int flags = wxICON_INFORMATION) - : wxGenericNotificationMessage(title, message, parent, flags) - { - } - }; +#if (defined(__WXGTK__) && wxUSE_LIBNOTIFY) || \ + (defined(__WXMSW__) && wxUSE_TASKBARICON && wxUSE_TASKBARICON_BALLOONS) || \ + (defined(__WXOSX_COCOA__) && (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_8)) + #define wxHAS_NATIVE_NOTIFICATION_MESSAGE #endif +// ---------------------------------------------------------------------------- +// wxNotificationMessage +// ---------------------------------------------------------------------------- + +#ifdef wxHAS_NATIVE_NOTIFICATION_MESSAGE + +#if defined(__WXMSW__) +class WXDLLIMPEXP_FWD_ADV wxTaskBarIcon; +#endif // defined(__WXMSW__) + +#else +#include "wx/generic/notifmsg.h" +#endif // wxHAS_NATIVE_NOTIFICATION_MESSAGE + +class WXDLLIMPEXP_ADV wxNotificationMessage : public +#ifdef wxHAS_NATIVE_NOTIFICATION_MESSAGE + wxNotificationMessageBase +#else + wxGenericNotificationMessage +#endif +{ +public: + wxNotificationMessage() { Init(); } + wxNotificationMessage(const wxString& title, + const wxString& message = wxString(), + wxWindow *parent = NULL, + int flags = wxICON_INFORMATION) + { + Init(); + Create(title, message, parent, flags); + } + +#if defined(__WXMSW__) && defined(wxHAS_NATIVE_NOTIFICATION_MESSAGE) + // returns the task bar icon which was used previously (may be NULL) + static wxTaskBarIcon *UseTaskBarIcon(wxTaskBarIcon *icon); +#endif + +private: + // common part of all ctors + void Init(); + + wxDECLARE_NO_COPY_CLASS(wxNotificationMessage); +}; + #endif // wxUSE_NOTIFICATION_MESSAGE #endif // _WX_NOTIFMSG_H_ diff --git a/include/wx/private/notifmsg.h b/include/wx/private/notifmsg.h new file mode 100644 index 0000000000..772a9c308e --- /dev/null +++ b/include/wx/private/notifmsg.h @@ -0,0 +1,76 @@ +/////////////////////////////////////////////////////////////////////////////// +// Name: wx/private/notifmsg.h +// Purpose: wxNotificationMessage declarations +// Author: Tobias Taschner +// Created: 2015-08-04 +// Copyright: (c) 2015 wxWidgets development team +// Licence: wxWindows licence +/////////////////////////////////////////////////////////////////////////////// + +#ifndef _WX_PRIVATE_NOTIFMSG_H_ +#define _WX_PRIVATE_NOTIFMSG_H_ + +class wxNotificationMessageImpl +{ +public: + wxNotificationMessageImpl(wxNotificationMessageBase* notification): + m_notification(notification), + m_active(false) + { + + } + + virtual ~wxNotificationMessageImpl() { } + + virtual bool Show(int timeout) = 0; + + virtual bool Close() = 0; + + virtual void SetTitle(const wxString& title) = 0; + + virtual void SetMessage(const wxString& message) = 0; + + virtual void SetParent(wxWindow *parent) = 0; + + virtual void SetFlags(int flags) = 0; + + virtual void SetIcon(const wxIcon& icon) = 0; + + virtual bool AddAction(wxWindowID actionid, const wxString &label) = 0; + + virtual void Detach() + { + if (m_active) + m_notification = NULL; + else + delete this; + } + + bool ProcessNotificationEvent(wxEvent& event) + { + if (m_notification) + return m_notification->ProcessEvent(event); + else + return false; + } + + wxNotificationMessageBase* GetNotification() const + { + return m_notification; + } + +protected: + wxNotificationMessageBase* m_notification; + bool m_active; + + void SetActive(bool active) + { + m_active = active; + + // Delete the implementation if the notification is detached + if (!m_notification && !active) + delete this; + } +}; + +#endif // _WX_PRIVATE_NOTIFMSG_H_ diff --git a/interface/wx/notifmsg.h b/interface/wx/notifmsg.h index 82d2769cd0..7b35be6f82 100644 --- a/interface/wx/notifmsg.h +++ b/interface/wx/notifmsg.h @@ -10,12 +10,36 @@ This class allows to show the user a message non intrusively. - Currently it is implemented natively for Windows and GTK and uses - (non-modal) dialogs for the display of the notifications under the other - platforms. + Currently it is implemented natively for Windows, OS X, GTK and uses + generic toast notifications under the other platforms. It's not recommended + but @c wxGenericNotificationMessage can be used instead of the native ones. + This might make sense if your application requires features not available in + the native implementation. Notice that this class is not a window and so doesn't derive from wxWindow. + @section platform_notes Platform Notes + + @par OS X + The OS X implementation uses Notification Center to display native notifications. + In order to use actions your notifications must use the alert style. This can + be enabled by the user in system settings or by setting the + @c NSUserNotificationAlertStyle value in Info.plist to @c alert. Please note + that the user always has the option to change the notification style. + + + @beginEventEmissionTable{wxCommandEvent} + @event{EVT_NOTIFICATION_MESSAGE_CLICK(id, func)} + Process a @c EVT_NOTIFICATION_MESSAGE_CLICK event, when a notification + is clicked. + @event{wxEVT_NOTIFICATION_MESSAGE_DISMISSED(id, func)} + Process a @c wxEVT_NOTIFICATION_MESSAGE_DISMISSED event, when a notification + is dismissed by the user or times out. + @event{wxEVT_NOTIFICATION_MESSAGE_ACTION(id, func)} + Process a @c wxEVT_NOTIFICATION_MESSAGE_ACTION event, when the user + selects on of the actions added by AddAction() + @endEventTable + @since 2.9.0 @library{wxadv} @category{misc} @@ -53,6 +77,17 @@ public: */ virtual ~wxNotificationMessage(); + /** + Add an action to the notification. If supported by the implementation + this are usually buttons in the notification selectable by the user. + + @return @false if the current implementation or OS version + does not support actions in notifications. + + @since 3.1.0 + */ + bool AddAction(wxWindowID actionid, const wxString &label = wxString()); + /** Hides the notification. @@ -69,9 +104,22 @@ public: Valid values are @c wxICON_INFORMATION, @c wxICON_WARNING and @c wxICON_ERROR (notice that @c wxICON_QUESTION is not allowed here). Some implementations of this class may not support the icons. + + @see SetIcon() */ void SetFlags(int flags); + /** + Specify a custom icon to be displayed in the notification. + + Some implementations of this class may not support custom icons. + + @see SetFlags() + + @since 3.1.0 + */ + void SetIcon(const wxIcon& icon); + /** Set the main text of the notification. diff --git a/samples/dialogs/dialogs.cpp b/samples/dialogs/dialogs.cpp index 5ee454bb09..ba16c55edf 100644 --- a/samples/dialogs/dialogs.cpp +++ b/samples/dialogs/dialogs.cpp @@ -32,8 +32,13 @@ #include "wx/minifram.h" #include "wx/sysopt.h" #include "wx/notifmsg.h" +#include "wx/generic/notifmsg.h" #include "wx/modalhook.h" +#if defined(__WXMSW__) && wxUSE_TASKBARICON +#include "wx/taskbar.h" +#endif + #if wxUSE_RICHMSGDLG #include "wx/richmsgdlg.h" #endif // wxUSE_RICHMSGDLG @@ -267,9 +272,7 @@ wxBEGIN_EVENT_TABLE(MyFrame, wxFrame) EVT_MENU(DIALOGS_REQUEST, MyFrame::OnRequestUserAttention) #if wxUSE_NOTIFICATION_MESSAGE - EVT_MENU(DIALOGS_NOTIFY_AUTO, MyFrame::OnNotifMsgAuto) - EVT_MENU(DIALOGS_NOTIFY_SHOW, MyFrame::OnNotifMsgShow) - EVT_MENU(DIALOGS_NOTIFY_HIDE, MyFrame::OnNotifMsgHide) + EVT_MENU(DIALOGS_NOTIFY_MSG, MyFrame::OnNotifMsg) #endif // wxUSE_NOTIFICATION_MESSAGE #if wxUSE_RICHTOOLTIP @@ -553,9 +556,8 @@ bool MyApp::OnInit() wxMenu *menuNotif = new wxMenu; menuNotif->Append(DIALOGS_REQUEST, wxT("&Request user attention\tCtrl-Shift-R")); #if wxUSE_NOTIFICATION_MESSAGE - menuNotif->Append(DIALOGS_NOTIFY_AUTO, "&Automatically hidden notification"); - menuNotif->Append(DIALOGS_NOTIFY_SHOW, "&Show manual notification"); - menuNotif->Append(DIALOGS_NOTIFY_HIDE, "&Hide manual notification"); + menuNotif->AppendSeparator(); + menuNotif->Append(DIALOGS_NOTIFY_MSG, "User &Notification\tCtrl-Shift-N"); #endif // wxUSE_NOTIFICATION_MESSAGE menuDlg->AppendSubMenu(menuNotif, "&User notifications"); @@ -632,10 +634,6 @@ MyFrame::MyFrame(const wxString& title) } #endif // wxUSE_COLOURDLG -#if wxUSE_NOTIFICATION_MESSAGE - m_notifMsg = NULL; -#endif // wxUSE_NOTIFICATION_MESSAGE - #if wxUSE_STATUSBAR CreateStatusBar(); #endif // wxUSE_STATUSBAR @@ -708,9 +706,6 @@ MyFrame::MyFrame(const wxString& title) MyFrame::~MyFrame() { -#if wxUSE_NOTIFICATION_MESSAGE - delete m_notifMsg; -#endif // wxUSE_NOTIFICATION_MESSAGE } #if wxUSE_COLOURDLG @@ -1900,53 +1895,402 @@ void MyFrame::OnRequestUserAttention(wxCommandEvent& WXUNUSED(event)) RequestUserAttention(wxUSER_ATTENTION_ERROR); } +#if wxUSE_RICHTOOLTIP || wxUSE_NOTIFICATION_MESSAGE + +#include "tip.xpm" + +#endif + #if wxUSE_NOTIFICATION_MESSAGE -void MyFrame::OnNotifMsgAuto(wxCommandEvent& WXUNUSED(event)) +// ---------------------------------------------------------------------------- +// TestNotificationMessageDialog +// ---------------------------------------------------------------------------- + +class TestNotificationMessageWindow : public wxFrame { - // Notice that the notification remains shown even after the - // wxNotificationMessage object itself is destroyed so we can show simple - // notifications using temporary objects. - if ( !wxNotificationMessage - ( - "Automatic Notification", - "Nothing important has happened\n" - "this notification will disappear soon." - ).Show() ) +public: + TestNotificationMessageWindow(wxWindow *parent) : + wxFrame(parent, wxID_ANY, "User Notification Test Dialog") { - wxLogStatus("Failed to show notification message"); +#ifdef __WXMSW__ + SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_BTNFACE)); +#endif + wxSizer * const sizerTop = new wxBoxSizer(wxVERTICAL); + + wxSizer* sizerText = new wxStaticBoxSizer(wxVERTICAL, this, "Notification Texts"); + + sizerText->Add(new wxStaticText(this, wxID_ANY, "&Title:"), + wxSizerFlags()); + m_textTitle = new wxTextCtrl(this, wxID_ANY, "Notification Title"); + sizerText->Add(m_textTitle, wxSizerFlags().Expand()); + + sizerText->Add(new wxStaticText(this, wxID_ANY, "&Message:"), + wxSizerFlags()); + m_textMessage = new wxTextCtrl(this, wxID_ANY, "A message within the notification", + wxDefaultPosition, wxDefaultSize, wxTE_MULTILINE); + m_textMessage->SetMinSize(wxSize(300, -1)); + sizerText->Add(m_textMessage, wxSizerFlags().Expand()); + + sizerTop->Add(sizerText, wxSizerFlags().Expand().Border()); + + const wxString icons[] = + { + "De&fault", + "None", + "&Information", + "&Warning", + "&Error", + "&Custom" + }; + wxCOMPILE_TIME_ASSERT(WXSIZEOF(icons) == Icon_Max, IconMismatch); + m_icons = new wxRadioBox(this, wxID_ANY, "Ic&on in notification", + wxDefaultPosition, wxDefaultSize, + WXSIZEOF(icons), icons, + 1, wxRA_SPECIFY_ROWS); + m_icons->SetSelection(Icon_Default); + sizerTop->Add(m_icons, wxSizerFlags().Expand().Border()); + + const wxString timeouts[] = + { + "&Automatic", + "&Never", + "&5 sec", + "&15 sec" + }; + m_showTimeout = new wxRadioBox(this, wxID_ANY, "&Timeout for notification", + wxDefaultPosition, wxDefaultSize, + WXSIZEOF(timeouts), timeouts, + 1, wxRA_SPECIFY_ROWS); + m_showTimeout->SetSelection(0); + sizerTop->Add(m_showTimeout, wxSizerFlags().Expand().Border()); + + wxSizer* sizerActions = new wxStaticBoxSizer(wxVERTICAL, this, "Additional Actions"); + + m_actionList = new wxListBox(this, wxID_ANY); + sizerActions->Add(m_actionList, wxSizerFlags().Expand()); + + wxSizer* sizerActionMod = new wxBoxSizer(wxHORIZONTAL); + sizerActionMod->Add(new wxStaticText(this, wxID_ANY, "ID:"), wxSizerFlags().Center()); + const wxString actionIds[] = + { + "wxID_DELETE", + "wxID_CLOSE", + "wxID_OK", + "wxID_CANCEL" + }; + m_actionChoice = new wxChoice(this, wxID_ANY, + wxDefaultPosition, wxDefaultSize, + WXSIZEOF(actionIds), actionIds + ); + m_actionChoice->SetSelection(0); + sizerActionMod->Add(m_actionChoice); + sizerActionMod->Add(new wxStaticText(this, wxID_ANY, "Custom label:"), wxSizerFlags().Center()); + m_actionCaption = new wxTextCtrl(this, wxID_ANY); + sizerActionMod->Add(m_actionCaption); + wxButton* actionAddBtn = new wxButton(this, wxID_ADD); + actionAddBtn->Bind(wxEVT_BUTTON, &TestNotificationMessageWindow::OnActionAddClicked, this); + sizerActionMod->Add(actionAddBtn); + wxButton* actionRemoveBtn = new wxButton(this, wxID_REMOVE); + actionRemoveBtn->Bind(wxEVT_BUTTON, &TestNotificationMessageWindow::OnActionRemoveClicked, this); + sizerActionMod->Add(actionRemoveBtn); + + sizerActions->Add(sizerActionMod, wxSizerFlags().Border()); + + sizerTop->Add(sizerActions, wxSizerFlags().Expand().Border()); + + wxSizer* sizerSettings = new wxStaticBoxSizer(wxVERTICAL, this, "Notification Settings"); + +#ifdef wxHAS_NATIVE_NOTIFICATION_MESSAGE + m_useGeneric = new wxCheckBox(this, wxID_ANY, "Use &generic notifications"); + sizerSettings->Add(m_useGeneric); +#endif + + m_delayShow = new wxCheckBox(this, wxID_ANY, "&Delay show"); +#if defined(__WXOSX__) + m_delayShow->SetValue(true); +#endif + sizerSettings->Add(m_delayShow); + + m_handleEvents = new wxCheckBox(this, wxID_ANY, "&Handle events"); + m_handleEvents->SetValue(true); + sizerSettings->Add(m_handleEvents); + +#if defined(__WXMSW__) && wxUSE_TASKBARICON + m_taskbarIcon = NULL; + m_useTaskbar = new wxCheckBox(this, wxID_ANY, "Use persistent &taskbar icon"); + m_useTaskbar->SetValue(false); + sizerSettings->Add(m_useTaskbar); +#endif + + sizerTop->Add(sizerSettings, wxSizerFlags().Expand().Border()); + + m_textStatus = new wxStaticText(this, wxID_ANY, "", wxDefaultPosition, wxDefaultSize, + wxST_NO_AUTORESIZE | wxALIGN_CENTRE_HORIZONTAL); + m_textStatus->SetForegroundColour(*wxBLUE); + sizerTop->Add(m_textStatus, wxSizerFlags().Expand().Border()); + + wxSizer* sizerButtons = new wxBoxSizer(wxHORIZONTAL); + sizerButtons->Add(new wxButton(this, wxID_NEW, "&Show")); + m_closeButton = new wxButton(this, wxID_CLOSE, "&Close"); + m_closeButton->Disable(); + sizerButtons->Add(m_closeButton); + sizerTop->Add(sizerButtons, wxSizerFlags().Center()); + + SetSizerAndFit(sizerTop); + + Center(); + + Bind(wxEVT_BUTTON, &TestNotificationMessageWindow::OnShowClicked, this, wxID_NEW); + Bind(wxEVT_BUTTON, &TestNotificationMessageWindow::OnCloseClicked, this, wxID_CLOSE); } - // But it doesn't have to be a temporary, of course. - wxNotificationMessage n("Dummy Warning", "Example of a warning notification."); - n.SetFlags(wxICON_ERROR); - n.Show(5); // Just for testing, use 5 second delay. -} +private: + enum + { + Icon_Default, + Icon_None, + Icon_Info, + Icon_Warning, + Icon_Error, + Icon_Custom, + Icon_Max + }; -void MyFrame::OnNotifMsgShow(wxCommandEvent& WXUNUSED(event)) + class ActionInfo : public wxClientData + { + public: + ActionInfo(wxWindowID actionId, const wxString& actionCaption): + id(actionId), + customCaption(actionCaption) + { + + } + + wxWindowID id; + wxString customCaption; + }; + + wxTextCtrl* m_textTitle; + wxTextCtrl* m_textMessage; + wxRadioBox* m_icons; + wxRadioBox* m_showTimeout; + wxListBox* m_actionList; + wxChoice* m_actionChoice; + wxTextCtrl* m_actionCaption; +#ifdef wxHAS_NATIVE_NOTIFICATION_MESSAGE + wxCheckBox* m_useGeneric; +#endif + wxCheckBox* m_delayShow; + wxCheckBox* m_handleEvents; + wxStaticText* m_textStatus; + wxButton* m_closeButton; + +#if defined(__WXMSW__) && wxUSE_TASKBARICON + wxCheckBox* m_useTaskbar; + wxTaskBarIcon* m_taskbarIcon; +#endif + + wxSharedPtr< wxNotificationMessageBase> m_notif; + + void DoShowNotification() + { + if ( m_delayShow->GetValue() ) + { + ShowStatus("Sleeping for 3 seconds to allow you to switch to another window"); + wxYield(); + wxSleep(3); + } + + m_closeButton->Enable(); + ShowStatus("Showing notification..."); +#ifdef wxHAS_NATIVE_NOTIFICATION_MESSAGE + if ( m_useGeneric->GetValue() ) + m_notif = new wxGenericNotificationMessage( + m_textTitle->GetValue(), + m_textMessage->GetValue(), + this); + else +#endif + { + m_notif = new wxNotificationMessage( + m_textTitle->GetValue(), + m_textMessage->GetValue(), + this); + +#if defined(__WXMSW__) && wxUSE_TASKBARICON + if ( m_useTaskbar->GetValue() ) + { + if ( !m_taskbarIcon ) + { + m_taskbarIcon = new wxTaskBarIcon(); + m_taskbarIcon->SetIcon(reinterpret_cast(GetParent())->GetIcon(), + "Dialogs Sample (Persistent)"); + } + wxNotificationMessage::UseTaskBarIcon(m_taskbarIcon); + } + else + if ( m_taskbarIcon ) + { + wxNotificationMessage::UseTaskBarIcon(NULL); + delete m_taskbarIcon; + m_taskbarIcon = NULL; + } +#endif + } + + switch (m_icons->GetSelection()) + { + case Icon_Default: + // Don't call SetFlags or SetIcon to see the implementations default + break; + case Icon_None: + m_notif->SetFlags(0); + break; + case Icon_Info: + m_notif->SetFlags(wxICON_INFORMATION); + break; + case Icon_Warning: + m_notif->SetFlags(wxICON_WARNING); + break; + case Icon_Error: + m_notif->SetFlags(wxICON_ERROR); + break; + case Icon_Custom: + m_notif->SetIcon(tip_xpm); + break; + } + + int timeout; + switch (m_showTimeout->GetSelection()) + { + case 1: + timeout = wxNotificationMessage::Timeout_Never; + break; + case 2: + timeout = 5; + break; + case 3: + timeout = 10; + break; + default: + timeout = wxNotificationMessage::Timeout_Auto; + break; + } + + for (unsigned int i = 0; i < m_actionList->GetCount(); i++) + { + ActionInfo* ai = reinterpret_cast(m_actionList->GetClientObject(i)); + if ( !m_notif->AddAction(ai->id, ai->customCaption) ) + wxLogWarning("Could not add action: %s", m_actionList->GetString(i)); + } + + if ( m_handleEvents->GetValue() ) + { + m_notif->Bind(wxEVT_NOTIFICATION_MESSAGE_ACTION, &TestNotificationMessageWindow::OnNotificationAction, this); + m_notif->Bind(wxEVT_NOTIFICATION_MESSAGE_CLICK, &TestNotificationMessageWindow::OnNotificationClicked, this); + m_notif->Bind(wxEVT_NOTIFICATION_MESSAGE_DISMISSED, &TestNotificationMessageWindow::OnNotificationDismissed, this); + } + + m_notif->Show(timeout); + + // Free the notification if we don't handle it's events + if ( !m_handleEvents->GetValue() ) + { + // Notice that the notification remains shown even after the + // wxNotificationMessage object itself is destroyed so we can show simple + // notifications using temporary objects. + m_notif.reset(); + ShowStatus("Showing notification, deleted object"); + } + } + + void OnShowClicked(wxCommandEvent& WXUNUSED(event)) + { + DoShowNotification(); + } + + void OnCloseClicked(wxCommandEvent& WXUNUSED(event)) + { + if ( m_notif ) + m_notif->Close(); + } + + void OnActionAddClicked(wxCommandEvent& WXUNUSED(event)) + { + wxWindowID actionId; + switch (m_actionChoice->GetSelection()) + { + case 1: + actionId = wxID_CLOSE; + break; + case 2: + actionId = wxID_OK; + break; + case 3: + actionId = wxID_CANCEL; + break; + default: + actionId = wxID_DELETE; + break; + } + + wxString actionCaption = m_actionCaption->GetValue(); + wxString desc = m_actionChoice->GetStringSelection(); + if ( !actionCaption.empty() ) + desc += " (" + actionCaption + ")"; + m_actionList->SetSelection( m_actionList->Append( desc, new ActionInfo(actionId, actionCaption) ) ); + } + + void OnActionRemoveClicked(wxCommandEvent& WXUNUSED(event)) + { + int pos = m_actionList->GetSelection(); + if ( pos != wxNOT_FOUND ) + { + m_actionList->Delete(pos); + if ( pos > 0 && m_actionList->GetCount() > 0 ) + m_actionList->SetSelection(pos - 1); + } + else + wxLogError("No action selected"); + } + + void OnNotificationClicked(wxCommandEvent& event) + { + ShowStatus("Notification was clicked"); + + Raise(); + + event.Skip(); + } + + void OnNotificationDismissed(wxCommandEvent& event) + { + ShowStatus("Notification was dismissed"); + + Raise(); + + event.Skip(); + } + + void OnNotificationAction(wxCommandEvent& event) + { + ShowStatus(wxString::Format("Selected %s action in notification", wxGetStockLabel(event.GetId(), 0)) ); + + event.Skip(); + } + + void ShowStatus(const wxString& text) + { + m_textStatus->SetLabelText(text); + } + +}; + +void MyFrame::OnNotifMsg(wxCommandEvent& WXUNUSED(event)) { - if ( !m_notifMsg ) - { - m_notifMsg = new wxNotificationMessage - ( - "wxWidgets Manual Notification", - "You can hide this notification from the menu", - this - ); - } - - if ( !m_notifMsg->Show(wxNotificationMessage::Timeout_Never) ) - { - wxLogStatus("Failed to show manual notification message"); - } -} - -void MyFrame::OnNotifMsgHide(wxCommandEvent& WXUNUSED(event)) -{ - if ( m_notifMsg && !m_notifMsg->Close() ) - { - wxLogStatus("Failed to hide manual notification message"); - } + TestNotificationMessageWindow* dlg = new TestNotificationMessageWindow(this); + dlg->Show(); } #endif // wxUSE_NOTIFICATION_MESSAGE @@ -1955,8 +2299,6 @@ void MyFrame::OnNotifMsgHide(wxCommandEvent& WXUNUSED(event)) #include "wx/richtooltip.h" -#include "tip.xpm" - class RichTipDialog : public wxDialog { public: @@ -2225,7 +2567,7 @@ TestDefaultActionDialog::TestDefaultActionDialog( wxWindow *parent ) : main_sizer->Add( grid_sizer, 0, wxALL, 10 ); wxSizer *button_sizer = CreateSeparatedButtonSizer( wxOK|wxCANCEL ); - if (button_sizer) + if ( button_sizer ) main_sizer->Add( button_sizer, 0, wxALL|wxGROW, 5 ); SetSizerAndFit( main_sizer ); diff --git a/samples/dialogs/dialogs.h b/samples/dialogs/dialogs.h index c3f8b4cfda..e611a355db 100644 --- a/samples/dialogs/dialogs.h +++ b/samples/dialogs/dialogs.h @@ -485,9 +485,7 @@ public: void OnRequestUserAttention(wxCommandEvent& event); #if wxUSE_NOTIFICATION_MESSAGE - void OnNotifMsgAuto(wxCommandEvent& event); - void OnNotifMsgShow(wxCommandEvent& event); - void OnNotifMsgHide(wxCommandEvent& event); + void OnNotifMsg(wxCommandEvent& event); #endif // wxUSE_NOTIFICATION_MESSAGE #if wxUSE_RICHTOOLTIP @@ -517,10 +515,6 @@ private: *m_dlgReplace; #endif // wxUSE_FINDREPLDLG -#if wxUSE_NOTIFICATION_MESSAGE - wxNotificationMessage *m_notifMsg; -#endif // wxUSE_NOTIFICATION_MESSAGE - wxColourData m_clrData; // just a window which we use to show the effect of font/colours selection @@ -612,9 +606,7 @@ enum DIALOGS_FIND, DIALOGS_REPLACE, DIALOGS_REQUEST, - DIALOGS_NOTIFY_AUTO, - DIALOGS_NOTIFY_SHOW, - DIALOGS_NOTIFY_HIDE, + DIALOGS_NOTIFY_MSG, DIALOGS_RICHTIP_DIALOG, DIALOGS_PROPERTY_SHEET, DIALOGS_PROPERTY_SHEET_TOOLBOOK, diff --git a/src/common/notifmsgcmn.cpp b/src/common/notifmsgcmn.cpp new file mode 100644 index 0000000000..10033b96f9 --- /dev/null +++ b/src/common/notifmsgcmn.cpp @@ -0,0 +1,103 @@ +/////////////////////////////////////////////////////////////////////////////// +// Name: src/common/notifmsgcmn.cpp +// Purpose: wxNotificationMessageBase implementation +// Author: Tobias Taschner +// Created: 2015-08-04 +// Copyright: (c) 2015 wxWidgets development team +// Licence: wxWindows licence +/////////////////////////////////////////////////////////////////////////////// + + +// ---------------------------------------------------------------------------- +// headers +// ---------------------------------------------------------------------------- + +// For compilers that support precompilation, includes "wx.h". +#include "wx/wxprec.h" + +#ifdef __BORLANDC__ +#pragma hdrstop +#endif + +#if wxUSE_NOTIFICATION_MESSAGE + +#include "wx/notifmsg.h" + +#include "wx/private/notifmsg.h" + +#ifndef wxHAS_NATIVE_NOTIFICATION_MESSAGE +#include "wx/generic/private/notifmsg.h" +#endif + +wxDEFINE_EVENT( wxEVT_NOTIFICATION_MESSAGE_CLICK, wxCommandEvent ); +wxDEFINE_EVENT( wxEVT_NOTIFICATION_MESSAGE_DISMISSED, wxCommandEvent ); +wxDEFINE_EVENT( wxEVT_NOTIFICATION_MESSAGE_ACTION, wxCommandEvent ); + +// ---------------------------------------------------------------------------- +// wxNotificationMessageBase +// ---------------------------------------------------------------------------- + +wxNotificationMessageBase::~wxNotificationMessageBase() +{ + m_impl->Detach(); +} + +bool wxNotificationMessageBase::Show(int timeout) +{ + return m_impl->Show(timeout); +} + +bool wxNotificationMessageBase::Close() +{ + return m_impl->Close(); +} + +void wxNotificationMessageBase::SetTitle(const wxString& title) +{ + m_impl->SetTitle(title); +} + +void wxNotificationMessageBase::SetMessage(const wxString& message) +{ + m_impl->SetMessage(message); +} + +void wxNotificationMessageBase::SetParent(wxWindow *parent) +{ + m_impl->SetParent(parent); +} + +void wxNotificationMessageBase::SetFlags(int flags) +{ + wxASSERT_MSG(flags == wxICON_INFORMATION || + flags == wxICON_WARNING || flags == wxICON_ERROR || + flags == 0, + "Invalid icon flags specified"); + + m_impl->SetFlags(flags); +} + +void wxNotificationMessageBase::SetIcon(const wxIcon& icon) +{ + m_impl->SetIcon(icon); +} + +bool wxNotificationMessageBase::AddAction(wxWindowID actionid, const wxString &label) +{ + return m_impl->AddAction(actionid, label); +} + +// +// wxNotificationMessage +// + +#ifndef wxHAS_NATIVE_NOTIFICATION_MESSAGE + +void wxNotificationMessage::Init() +{ + m_impl = new wxGenericNotificationMessageImpl(this); +} + +#endif + +#endif // wxUSE_NOTIFICATION_MESSAGE diff --git a/src/generic/notifmsgg.cpp b/src/generic/notifmsgg.cpp index 3118c3be6a..26fd26593a 100644 --- a/src/generic/notifmsgg.cpp +++ b/src/generic/notifmsgg.cpp @@ -25,13 +25,16 @@ #if wxUSE_NOTIFICATION_MESSAGE #ifndef WX_PRECOMP - #include "wx/dialog.h" - #include "wx/timer.h" + #include "wx/frame.h" + #include "wx/timer.h" #include "wx/sizer.h" #include "wx/statbmp.h" + #include "wx/settings.h" + #include "wx/panel.h" #endif //WX_PRECOMP #include "wx/artprov.h" +#include "wx/bmpbuttn.h" // even if the platform has the native implementation, we still normally want // to use the generic one (unless it's totally unsuitable for the target UI) @@ -41,93 +44,220 @@ // uses the generic version, the second inclusion will do no harm) #include "wx/notifmsg.h" #include "wx/generic/notifmsg.h" +#include "wx/generic/private/notifmsg.h" +#include "wx/display.h" +#include "wx/textwrapper.h" // ---------------------------------------------------------------------------- -// wxNotificationMessageDialog +// wxNotificationMessageWindow // ---------------------------------------------------------------------------- -class wxNotificationMessageDialog : public wxDialog +class wxNotificationMessageWindow : public wxFrame { public: - wxNotificationMessageDialog(wxWindow *parent, - const wxString& text, - int timeout, - int flags); + wxNotificationMessageWindow(wxGenericNotificationMessageImpl* notificationImpl); - void Set(wxWindow *parent, - const wxString& text, - int timeout, - int flags); + virtual ~wxNotificationMessageWindow(); - bool IsAutomatic() const { return m_timer.IsRunning(); } - void SetDeleteOnHide() { m_deleteOnHide = true; } + void Set(int timeout); + + bool Hide(); + + void SetMessageTitle(const wxString& title); + + void SetMessage(const wxString& message); + + void SetMessageIcon(const wxIcon& icon); + + bool AddAction(wxWindowID actionid, const wxString &label); private: void OnClose(wxCloseEvent& event); void OnTimer(wxTimerEvent& event); + void OnNotificationClicked(wxMouseEvent& event); + void OnNotificationMouseEnter(wxMouseEvent& event); + void OnNotificationMouseLeave(wxMouseEvent& event); + void OnCloseClicked(wxCommandEvent& event); + void OnActionButtonClicked(wxCommandEvent& event); - // if true, delete the dialog when it should disappear, otherwise just hide - // it (initially false) - bool m_deleteOnHide; + // Dialog elements + wxPanel* m_messagePanel; + wxStaticBitmap* m_messageBmp; + wxStaticText* m_messageText; + wxStaticText* m_messageTitle; + wxBitmapButton* m_closeBtn; + wxBoxSizer* m_buttonSizer; - // timer which will hide this dialog when it expires, if it's not running - // it means we were created without timeout wxTimer m_timer; + int m_timeout; + long m_timeoutTargetTime; + int m_mouseActiveCount; + wxGenericNotificationMessageImpl* m_notificationImpl; + + void PrepareNotificationControl(wxWindow* ctrl, bool handleClick = true); + + static wxPoint ms_presentationPos; + + static int ms_presentationDirection; + + static wxVector ms_visibleNotifications; + + static void AddVisibleNotification(wxNotificationMessageWindow* notif); + + static void RemoveVisibleNotification(wxNotificationMessageWindow* notif); + + static void ResizeAndFitVisibleNotifications(); wxDECLARE_EVENT_TABLE(); - wxDECLARE_NO_COPY_CLASS(wxNotificationMessageDialog); + wxDECLARE_NO_COPY_CLASS(wxNotificationMessageWindow); }; +int wxNotificationMessageWindow::ms_presentationDirection = 0; +wxPoint wxNotificationMessageWindow::ms_presentationPos = wxDefaultPosition; + // ============================================================================ -// wxNotificationMessageDialog implementation +// wxNotificationMessageWindow implementation // ============================================================================ -wxBEGIN_EVENT_TABLE(wxNotificationMessageDialog, wxDialog) - EVT_CLOSE(wxNotificationMessageDialog::OnClose) +wxBEGIN_EVENT_TABLE(wxNotificationMessageWindow, wxFrame) + EVT_CLOSE(wxNotificationMessageWindow::OnClose) - EVT_TIMER(wxID_ANY, wxNotificationMessageDialog::OnTimer) + EVT_TIMER(wxID_ANY, wxNotificationMessageWindow::OnTimer) wxEND_EVENT_TABLE() -wxNotificationMessageDialog::wxNotificationMessageDialog(wxWindow *parent, - const wxString& text, - int timeout, - int flags) - : wxDialog(parent, wxID_ANY, _("Notice"), - wxDefaultPosition, wxDefaultSize, - 0 /* no caption, no border styles */), - m_timer(this) -{ - m_deleteOnHide = false; +wxVector wxNotificationMessageWindow::ms_visibleNotifications; - Set(parent, text, timeout, flags); +wxNotificationMessageWindow::wxNotificationMessageWindow(wxGenericNotificationMessageImpl* notificationImpl) + : wxFrame(NULL, wxID_ANY, _("Notice"), + wxDefaultPosition, wxDefaultSize, + wxBORDER_NONE | wxFRAME_TOOL_WINDOW | wxSTAY_ON_TOP /* no caption, no border styles */), + m_timer(this), + m_mouseActiveCount(0), + m_notificationImpl(notificationImpl) +{ + m_buttonSizer = NULL; + + SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_BTNSHADOW)); + + m_messagePanel = new wxPanel(this, wxID_ANY); + wxSizer * const msgSizer = new wxBoxSizer(wxHORIZONTAL); + m_messagePanel->SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW)); + m_messagePanel->SetSizer(msgSizer); + PrepareNotificationControl(m_messagePanel); + + // Add message icon to layout + m_messageBmp = new wxStaticBitmap + ( + m_messagePanel, + wxID_ANY, + wxArtProvider::GetMessageBoxIcon(wxICON_INFORMATION) + ); + m_messageBmp->Hide(); + PrepareNotificationControl(m_messageBmp); + msgSizer->Add(m_messageBmp, wxSizerFlags().Centre().DoubleBorder()); + + // Create title and message sizers + wxSizer* textSizer = new wxBoxSizer(wxVERTICAL); + + m_messageTitle = new wxStaticText(m_messagePanel, wxID_ANY, wxString()); + m_messageTitle->SetFont(m_messageTitle->GetFont().MakeBold()); + textSizer->Add(m_messageTitle, wxSizerFlags(0).Border()); + m_messageTitle->Hide(); + PrepareNotificationControl(m_messageTitle); + + m_messageText = new wxStaticText(m_messagePanel, wxID_ANY, wxString()); + textSizer->Add(m_messageText, wxSizerFlags(0).Border(wxLEFT | wxRIGHT | wxBOTTOM)); + PrepareNotificationControl(m_messageText); + + msgSizer->Add(textSizer, wxSizerFlags(1).Center()); + + // Add a single close button if no actions are specified + m_closeBtn = wxBitmapButton::NewCloseButton(m_messagePanel, wxID_ANY); + msgSizer->Add(m_closeBtn, wxSizerFlags(0).Border(wxALL, 3).Top()); + m_closeBtn->Bind(wxEVT_BUTTON, &wxNotificationMessageWindow::OnCloseClicked, this); + PrepareNotificationControl(m_closeBtn, false); + + wxSizer * const sizerTop = new wxBoxSizer(wxHORIZONTAL); + sizerTop->Add(m_messagePanel, wxSizerFlags().Border(wxALL, FromDIP(1))); + SetSizer(sizerTop); } -void -wxNotificationMessageDialog::Set(wxWindow * WXUNUSED(parent), - const wxString& text, - int timeout, - int flags) +wxNotificationMessageWindow::~wxNotificationMessageWindow() { - wxSizer * const sizerTop = new wxBoxSizer(wxHORIZONTAL); - if ( flags & wxICON_MASK ) + RemoveVisibleNotification(this); +} + +void wxNotificationMessageWindow::PrepareNotificationControl(wxWindow* ctrl, bool handleClick) +{ + ctrl->Bind(wxEVT_ENTER_WINDOW, &wxNotificationMessageWindow::OnNotificationMouseEnter, this); + ctrl->Bind(wxEVT_LEAVE_WINDOW, &wxNotificationMessageWindow::OnNotificationMouseLeave, this); + + if ( handleClick ) + ctrl->Bind(wxEVT_LEFT_DOWN, &wxNotificationMessageWindow::OnNotificationClicked, this); +} + +void wxNotificationMessageWindow::SetMessageTitle(const wxString& title) +{ + m_messageTitle->SetLabelText(title); + m_messageTitle->Show(!title.empty()); +} + +void wxNotificationMessageWindow::SetMessage(const wxString& message) +{ + m_messageText->SetLabelText(message); + m_messageText->Show(!message.empty()); +} + +void wxNotificationMessageWindow::SetMessageIcon(const wxIcon& icon) +{ + m_messageBmp->SetBitmap(icon); + m_messageBmp->Show(icon.IsOk()); +} + +bool wxNotificationMessageWindow::AddAction(wxWindowID actionid, const wxString &label) +{ + wxSizer* msgSizer = m_messagePanel->GetSizer(); + if ( m_buttonSizer == NULL ) { - sizerTop->Add(new wxStaticBitmap - ( - this, - wxID_ANY, - wxArtProvider::GetMessageBoxIcon(flags) - ), - wxSizerFlags().Centre().Border()); + msgSizer->Detach(m_closeBtn); + m_closeBtn->Hide(); + m_buttonSizer = new wxBoxSizer(wxVERTICAL); + msgSizer->Add(m_buttonSizer, wxSizerFlags(0).Center().Border()); } - sizerTop->Add(CreateTextSizer(text), wxSizerFlags(1).Border()); - SetSizerAndFit(sizerTop); + wxButton* actionButton = new wxButton(m_messagePanel, actionid, label); + actionButton->Bind(wxEVT_BUTTON, &wxNotificationMessageWindow::OnActionButtonClicked, this); + PrepareNotificationControl(actionButton, false); + int borderDir = (m_buttonSizer->GetChildren().empty()) ? 0 : wxTOP; + m_buttonSizer->Add(actionButton, wxSizerFlags(0).Border(borderDir).Expand()); + + return true; +} + + +bool wxNotificationMessageWindow::Hide() +{ + if ( m_timer.IsRunning() ) + m_timer.Stop(); + + RemoveVisibleNotification(this); + return wxFrame::HideWithEffect(wxSHOW_EFFECT_BLEND); +} + +void wxNotificationMessageWindow::Set(int timeout) +{ + Layout(); + Fit(); + + AddVisibleNotification(this); if ( timeout != wxGenericNotificationMessage::Timeout_Never ) { // wxTimer uses ms, timeout is in seconds - m_timer.Start(timeout*1000, true /* one shot only */); + m_timer.Start(500); + m_timeout = timeout; + m_timeoutTargetTime = wxGetUTCTime() + timeout; } else if ( m_timer.IsRunning() ) { @@ -135,102 +265,263 @@ wxNotificationMessageDialog::Set(wxWindow * WXUNUSED(parent), } } -void wxNotificationMessageDialog::OnClose(wxCloseEvent& event) +void wxNotificationMessageWindow::OnClose(wxCloseEvent& WXUNUSED(event)) { - if ( m_deleteOnHide ) - { - // we don't need to keep this dialog alive any more - Destroy(); - } - else // don't really close, just hide, as we can be shown again later - { - event.Veto(); + wxCommandEvent evt(wxEVT_NOTIFICATION_MESSAGE_DISMISSED); + m_notificationImpl->ProcessNotificationEvent(evt); - Hide(); + if ( m_timer.IsRunning() ) + m_timer.Stop(); + + m_notificationImpl->Close(); +} + +void wxNotificationMessageWindow::OnTimer(wxTimerEvent& WXUNUSED(event)) +{ + if ( m_mouseActiveCount > 0 ) + { + m_timeoutTargetTime = wxGetUTCTime() + m_timeout; + } + else if ( m_timeoutTargetTime != -1 && + wxGetUTCTime() >= m_timeoutTargetTime ) + { + m_notificationImpl->Close(); } } -void wxNotificationMessageDialog::OnTimer(wxTimerEvent& WXUNUSED(event)) +void wxNotificationMessageWindow::OnNotificationClicked(wxMouseEvent& WXUNUSED(event)) { - if ( m_deleteOnHide ) - Destroy(); - else - Hide(); + wxCommandEvent evt(wxEVT_NOTIFICATION_MESSAGE_CLICK); + m_notificationImpl->ProcessNotificationEvent(evt); + + m_notificationImpl->Close(); +} + +void wxNotificationMessageWindow::OnNotificationMouseEnter(wxMouseEvent& WXUNUSED(event)) +{ + m_mouseActiveCount++; +} + +void wxNotificationMessageWindow::OnNotificationMouseLeave(wxMouseEvent& WXUNUSED(event)) +{ + m_mouseActiveCount--; +} + +void wxNotificationMessageWindow::OnCloseClicked(wxCommandEvent& WXUNUSED(event)) +{ + wxCommandEvent evt(wxEVT_NOTIFICATION_MESSAGE_DISMISSED); + m_notificationImpl->ProcessNotificationEvent(evt); + + m_notificationImpl->Close(); +} + +void wxNotificationMessageWindow::OnActionButtonClicked(wxCommandEvent& event) +{ + wxCommandEvent evt(wxEVT_NOTIFICATION_MESSAGE_ACTION, event.GetId()); + m_notificationImpl->ProcessNotificationEvent(evt); + + m_notificationImpl->Close(); +} + +void wxNotificationMessageWindow::AddVisibleNotification(wxNotificationMessageWindow* notif) +{ + bool found = false; + for ( wxVector::iterator it = ms_visibleNotifications.begin(); + it != ms_visibleNotifications.end(); it++ ) + { + if ( *it == notif ) + { + found = true; + break; + } + } + + if ( !found ) + ms_visibleNotifications.push_back(notif); + + ResizeAndFitVisibleNotifications(); +} + +void wxNotificationMessageWindow::RemoveVisibleNotification(wxNotificationMessageWindow* notif) +{ + for ( wxVector::iterator it = ms_visibleNotifications.begin(); + it != ms_visibleNotifications.end(); it++ ) + { + if ( *it == notif ) + { + ms_visibleNotifications.erase(it); + break; + } + } + ResizeAndFitVisibleNotifications(); +} + +void wxNotificationMessageWindow::ResizeAndFitVisibleNotifications() +{ + if ( ms_presentationDirection == 0 ) + { + // Determine presentation position + + wxDisplay display; + wxRect clientArea = display.GetClientArea(); + wxRect geom = display.GetGeometry(); + if ( clientArea.y > 0 ) // Taskbar is at top + { + ms_presentationDirection = 1; + ms_presentationPos = clientArea.GetTopRight(); + } + else if ( clientArea.GetHeight() != geom.GetHeight() ) // Taskbar at bottom + { + ms_presentationDirection = -1; + ms_presentationPos = clientArea.GetBottomRight(); + } + else // Default to upper right screen corner with some padding + { + ms_presentationDirection = 1; + ms_presentationPos.x = geom.GetWidth() - 30; + ms_presentationPos.y = 30; + } + } + + int maxWidth = -1; + + // Determine max width + for (wxVector::iterator notif = ms_visibleNotifications.begin(); + notif != ms_visibleNotifications.end(); ++notif) + { + wxSize notifSize = (*notif)->GetSize(); + if ( notifSize.GetWidth() > maxWidth ) + maxWidth = notifSize.GetWidth(); + } + + int notifPadding = 2; + + wxPoint presentPos = ms_presentationPos; + presentPos.x -= notifPadding + maxWidth; + + int prevNotifHeight = 0; + + for (wxVector::iterator notif = ms_visibleNotifications.begin(); + notif != ms_visibleNotifications.end(); ++notif) + { + // Modify existing maxwidth + wxSize notifSize = (*notif)->GetSize(); + if ( notifSize.GetWidth() < maxWidth ) + { + notifSize.SetWidth(maxWidth); + (*notif)->SetSize(notifSize); + (*notif)->Layout(); + } + + if ( ms_presentationDirection > 0 ) + { + presentPos.y += (notifPadding + prevNotifHeight); + prevNotifHeight = notifSize.GetHeight(); + } + else + { + presentPos.y -= (notifPadding + notifSize.GetHeight()); + } + + (*notif)->SetPosition(presentPos); + } } // ============================================================================ // wxGenericNotificationMessage implementation // ============================================================================ -int wxGenericNotificationMessage::ms_timeout = 10; - /* static */ void wxGenericNotificationMessage::SetDefaultTimeout(int timeout) { - wxASSERT_MSG( timeout > 0, - "negative or zero default timeout doesn't make sense" ); - - ms_timeout = timeout; + wxGenericNotificationMessageImpl::SetDefaultTimeout(timeout); } void wxGenericNotificationMessage::Init() { - m_dialog = NULL; + m_impl = new wxGenericNotificationMessageImpl(this); } -wxGenericNotificationMessage::~wxGenericNotificationMessage() +// ---------------------------------------------------------------------------- +// wxGenericNotificationMessageImpl +// ---------------------------------------------------------------------------- + +int wxGenericNotificationMessageImpl::ms_timeout = 3; + +wxGenericNotificationMessageImpl::wxGenericNotificationMessageImpl(wxNotificationMessageBase* notification) : + wxNotificationMessageImpl(notification) { - if ( m_dialog->IsAutomatic() ) - { - // we want to allow the user to create an automatically hidden - // notification just by creating a local wxGenericNotificationMessage object - // and so we shouldn't hide the notification when this object goes out - // of scope - m_dialog->SetDeleteOnHide(); - } - else // manual dialog, hide it immediately - { - // OTOH for permanently shown dialogs only the code can hide them and - // if the object is deleted, we must do it now as it won't be - // accessible programmatically any more - delete m_dialog; - } + m_window = new wxNotificationMessageWindow(this); } -bool wxGenericNotificationMessage::Show(int timeout) +wxGenericNotificationMessageImpl::~wxGenericNotificationMessageImpl() { - if ( timeout == Timeout_Auto ) + m_window->Destroy(); +} + +/* static */ void wxGenericNotificationMessageImpl::SetDefaultTimeout(int timeout) +{ + wxASSERT_MSG(timeout > 0, + "negative or zero default timeout doesn't make sense"); + + ms_timeout = timeout; +} + +bool wxGenericNotificationMessageImpl::Show(int timeout) +{ + if ( timeout == wxNotificationMessageBase::Timeout_Auto ) { timeout = GetDefaultTimeout(); } - if ( !m_dialog ) - { - m_dialog = new wxNotificationMessageDialog - ( - GetParent(), - GetFullMessage(), - timeout, - GetFlags() - ); - } - else // update the existing dialog - { - m_dialog->Set(GetParent(), GetFullMessage(), timeout, GetFlags()); - } + SetActive(true); + m_window->Set(timeout); - m_dialog->Show(); + m_window->ShowWithEffect(wxSHOW_EFFECT_BLEND); return true; } -bool wxGenericNotificationMessage::Close() +bool wxGenericNotificationMessageImpl::Close() { - if ( !m_dialog ) + if ( !m_window ) return false; - m_dialog->Hide(); + m_window->Hide(); + + SetActive(false); return true; } +void wxGenericNotificationMessageImpl::SetTitle(const wxString& title) +{ + m_window->SetMessageTitle(title); +} + +void wxGenericNotificationMessageImpl::SetMessage(const wxString& message) +{ + m_window->SetMessage(message); +} + +void wxGenericNotificationMessageImpl::SetParent(wxWindow *WXUNUSED(parent)) +{ + +} + +void wxGenericNotificationMessageImpl::SetFlags(int flags) +{ + m_window->SetMessageIcon( wxArtProvider::GetMessageBoxIcon(flags) ); +} + +void wxGenericNotificationMessageImpl::SetIcon(const wxIcon& icon) +{ + m_window->SetMessageIcon(icon); +} + +bool wxGenericNotificationMessageImpl::AddAction(wxWindowID actionid, const wxString &label) +{ + return m_window->AddAction(actionid, label); +} + + #endif // wxUSE_NOTIFICATION_MESSAGE diff --git a/src/gtk/notifmsg.cpp b/src/gtk/notifmsg.cpp index 63670ee2a5..6f59041ad9 100644 --- a/src/gtk/notifmsg.cpp +++ b/src/gtk/notifmsg.cpp @@ -1,10 +1,10 @@ /////////////////////////////////////////////////////////////////////////////// -// Name: src/gtk/notifmsg.cpp -// Purpose: wxNotificationMessage for wxGTK using libnotify. -// Author: Vadim Zeitlin -// Created: 2012-07-25 -// Copyright: (c) 2012 Vadim Zeitlin -// Licence: wxWindows licence +// Name: src/gtk/notifmsg.cpp +// Purpose: wxNotificationMessage for wxGTK using libnotify. +// Author: Vadim Zeitlin +// Created: 2012-07-25 +// Copyright: (c) 2012 Vadim Zeitlin +// Licence: wxWindows licence /////////////////////////////////////////////////////////////////////////////// // ============================================================================ @@ -28,11 +28,14 @@ #ifndef WX_PRECOMP #include "wx/app.h" + #include "wx/icon.h" #endif // WX_PRECOMP #include #include "wx/module.h" +#include "wx/private/notifmsg.h" +#include // General note about error handling: as notifications are meant to be // non-intrusive, we use wxLogDebug() and not wxLogError() if anything goes @@ -82,136 +85,290 @@ wxIMPLEMENT_DYNAMIC_CLASS(wxLibnotifyModule, wxModule); // wxNotificationMessage implementation // ============================================================================ -bool wxNotificationMessage::GTKSetIconName(const wxString& name) -{ - m_iconName = name; +class wxLibNotifyMsgImpl; - return true; +void wxLibNotifyMsgImplActionCallback(NotifyNotification *notification, + char *action, + gpointer user_data); + +extern "C" { +static gboolean closed_notification(NotifyNotification *notification, + const char* WXUNUSED(data), void* user_data); } -bool wxNotificationMessage::Show(int timeout) +class wxLibNotifyMsgImpl : public wxNotificationMessageImpl { - if ( !wxLibnotifyModule::Initialize() ) - return false; - - // Determine the GTK+ icon to use from flags and also set the urgency - // appropriately. - const char* icon; - NotifyUrgency urgency; - switch ( GetFlags() ) +public: + wxLibNotifyMsgImpl(wxNotificationMessageBase* notification) : + wxNotificationMessageImpl(notification), + m_notification(NULL), + m_flags(wxICON_INFORMATION) { - case wxICON_INFORMATION: - icon = "dialog-information"; - urgency = NOTIFY_URGENCY_LOW; - break; + if ( !wxLibnotifyModule::Initialize() ) + wxLogError(_("Could not initalize libnotify.")); + + } - case wxICON_WARNING: - icon = "dialog-warning"; - urgency = NOTIFY_URGENCY_NORMAL; - break; - - case wxICON_ERROR: - icon = "dialog-error"; - urgency = NOTIFY_URGENCY_CRITICAL; - break; - - default: - wxFAIL_MSG( "Unknown notification message flags." ); + virtual ~wxLibNotifyMsgImpl() + { + if ( m_notification ) + g_object_unref(m_notification); + } + + bool CreateOrUpdateNotification() + { + if ( !wxLibnotifyModule::Initialize() ) return false; - } - // Explicitly specified icon name overrides the implicit one determined by - // the flags. - wxScopedCharBuffer buf; - if ( !m_iconName.empty() ) - { - buf = m_iconName.utf8_str(); - icon = buf; - } + // Determine the GTK+ icon to use from flags and also set the urgency + // appropriately. + const char* icon; + switch ( m_flags ) + { + case wxICON_INFORMATION: + icon = "dialog-information"; + break; - // Create the notification or update an existing one if we had already been - // shown before. - if ( !m_notification ) - { - m_notification = notify_notification_new - ( - GetTitle().utf8_str(), - GetMessage().utf8_str(), - icon -#if !wxUSE_LIBNOTIFY_0_7 - // There used to be an "associated window" - // parameter in this function but it has - // disappeared by 0.7, so use it for previous - // versions only. - , 0 -#endif // libnotify < 0.7 - ); + case wxICON_WARNING: + icon = "dialog-warning"; + break; + + case wxICON_ERROR: + icon = "dialog-error"; + break; + + default: + wxFAIL_MSG( "Unknown notification message flags." ); + return false; + } + + // Create the notification or update an existing one if we had already been + // shown before. if ( !m_notification ) { - wxLogDebug("Failed to creation notification."); + m_notification = notify_notification_new + ( + m_title.utf8_str(), + m_message.utf8_str(), + icon +#if !wxUSE_LIBNOTIFY_0_7 + // There used to be an "associated window" + // parameter in this function but it has + // disappeared by 0.7, so use it for previous + // versions only. + , 0 +#endif // libnotify < 0.7 + ); + if ( !m_notification ) + { + wxLogDebug("Failed to creation notification."); + + return false; + } + + + g_signal_connect(m_notification, "closed", G_CALLBACK(closed_notification), this); + + } + else + { + if ( !notify_notification_update + ( + m_notification, + m_title.utf8_str(), + m_message.utf8_str(), + icon + ) ) + { + wxLogDebug(wxS("notify_notification_update() unexpectedly failed.")); + } + } + + // Explicitly specified icon name overrides the implicit one determined by + // the flags. + if ( m_icon.IsOk() ) + { +#ifdef __WXGTK3__ + notify_notification_set_image_from_pixbuf( + m_notification, + m_icon.GetPixbufNoMask() + ); +#endif + } + + return true; + } + + virtual bool Show(int timeout) wxOVERRIDE + { + if ( !CreateOrUpdateNotification() ) + return false; + + // Set the notification parameters not specified during creation. + notify_notification_set_timeout + ( + m_notification, + timeout == wxNotificationMessage::Timeout_Auto ? NOTIFY_EXPIRES_DEFAULT + : timeout == wxNotificationMessage::Timeout_Never ? NOTIFY_EXPIRES_NEVER + : 1000*timeout + ); + + NotifyUrgency urgency; + switch ( m_flags ) + { + case wxICON_INFORMATION: + urgency = NOTIFY_URGENCY_LOW; + break; + + case wxICON_WARNING: + urgency = NOTIFY_URGENCY_NORMAL; + break; + + case wxICON_ERROR: + urgency = NOTIFY_URGENCY_CRITICAL; + break; + + default: + wxFAIL_MSG( "Unknown notification message flags." ); + return false; + } + notify_notification_set_urgency(m_notification, urgency); + + + // Finally do show the notification. + wxGtkError error; + if ( !notify_notification_show(m_notification, error.Out()) ) + { + wxLogDebug("Failed to shown notification: %s", error.GetMessage()); return false; } + + return true; } - else + + virtual bool Close() wxOVERRIDE { - if ( !notify_notification_update - ( - m_notification, - GetTitle().utf8_str(), - GetMessage().utf8_str(), - icon - ) ) + wxCHECK_MSG( m_notification, false, + wxS("Can't close not shown notification.") ); + + wxGtkError error; + if ( !notify_notification_close(m_notification, error.Out()) ) { - wxLogDebug(wxS("notify_notification_update() unexpectedly failed.")); + wxLogDebug("Failed to hide notification: %s", error.GetMessage()); + + return false; } + + return true; } - - - // Set the notification parameters not specified during creation. - notify_notification_set_timeout - ( - m_notification, - timeout == Timeout_Auto ? NOTIFY_EXPIRES_DEFAULT - : timeout == Timeout_Never ? NOTIFY_EXPIRES_NEVER - : 1000*timeout - ); - - notify_notification_set_urgency(m_notification, urgency); - - - // Finally do show the notification. - wxGtkError error; - if ( !notify_notification_show(m_notification, error.Out()) ) + + virtual void SetTitle(const wxString& title) wxOVERRIDE { - wxLogDebug("Failed to shown notification: %s", error.GetMessage()); - - return false; + m_title = title; } + + virtual void SetMessage(const wxString& message) wxOVERRIDE + { + m_message = message; + } + + virtual void SetParent(wxWindow *WXUNUSED(parent)) wxOVERRIDE + { + } + + virtual void SetFlags(int flags) wxOVERRIDE + { + m_flags = flags; + } + + virtual void SetIcon(const wxIcon& icon) wxOVERRIDE + { + m_icon = icon; + CreateOrUpdateNotification(); + } + + virtual bool AddAction(wxWindowID actionid, const wxString &label) + { + if ( !CreateOrUpdateNotification() ) + return false; + + wxString labelStr = label; + if ( labelStr.empty() ) + labelStr = wxGetStockLabel(actionid, wxSTOCK_NOFLAGS); + + notify_notification_add_action + ( + m_notification, + wxString::Format("%d", actionid).utf8_str(), + labelStr.utf8_str(), + &wxLibNotifyMsgImplActionCallback, + this, + NULL + ); + + return true; + } + + void NotifyClose(int closeReason) + { + // Values according to the OpenDesktop specification at: + // https://developer.gnome.org/notification-spec/ + + switch (closeReason) + { + case 1: // Expired + case 2: // The notification was dismissed by the user. + { + wxCommandEvent evt(wxEVT_NOTIFICATION_MESSAGE_DISMISSED); + ProcessNotificationEvent(evt); + break; + } + } + + } + + void NotifyAction(wxWindowID actionid) + { + wxCommandEvent evt(wxEVT_NOTIFICATION_MESSAGE_ACTION, actionid); + ProcessNotificationEvent(evt); + } + +private: + NotifyNotification* m_notification; + wxString m_title; + wxString m_message; + wxIcon m_icon; + int m_flags; +}; - return true; +void wxLibNotifyMsgImplActionCallback(NotifyNotification *WXUNUSED(notification), + char *action, + gpointer user_data) +{ + wxLibNotifyMsgImpl* impl = (wxLibNotifyMsgImpl*) user_data; + + impl->NotifyAction(wxAtoi(action)); } -bool wxNotificationMessage::Close() +extern "C" { +static gboolean closed_notification(NotifyNotification *notification, + const char* WXUNUSED(data), void* user_data) { - wxCHECK_MSG( m_notification, false, - wxS("Can't close not shown notification.") ); - - wxGtkError error; - if ( !notify_notification_close(m_notification, error.Out()) ) - { - wxLogDebug("Failed to hide notification: %s", error.GetMessage()); - - return false; - } - + wxLibNotifyMsgImpl* impl = (wxLibNotifyMsgImpl*) user_data; + gint closeReason = notify_notification_get_closed_reason(notification); + impl->NotifyClose(closeReason); return true; } +} -wxNotificationMessage::~wxNotificationMessage() +// ---------------------------------------------------------------------------- +// wxNotificationMessage +// ---------------------------------------------------------------------------- + +void wxNotificationMessage::Init() { - if ( m_notification ) - g_object_unref(m_notification); + m_impl = new wxLibNotifyMsgImpl(this); } #endif // wxUSE_NOTIFICATION_MESSAGE && wxUSE_LIBNOTIFY diff --git a/src/msw/notifmsg.cpp b/src/msw/notifmsg.cpp index d25e9ab5fe..b1a91330a0 100644 --- a/src/msw/notifmsg.cpp +++ b/src/msw/notifmsg.cpp @@ -35,7 +35,9 @@ #include "wx/string.h" #endif // WX_PRECOMP +#include "wx/private/notifmsg.h" #include "wx/generic/notifmsg.h" +#include "wx/generic/private/notifmsg.h" #include "wx/taskbar.h" @@ -43,69 +45,62 @@ // different implementations used by wxNotificationMessage // ---------------------------------------------------------------------------- -// base class for all available implementations -class wxNotifMsgImpl -{ -public: - wxNotifMsgImpl() { } - virtual ~wxNotifMsgImpl() { } - - virtual bool DoShow(const wxString& title, - const wxString& message, - int timeout, - int flags) = 0; - virtual bool DoClose() = 0; - -private: - wxDECLARE_NO_COPY_CLASS(wxNotifMsgImpl); -}; - -// implementation which is simply a bridge to wxGenericNotificationMessage -class wxGenericNotifMsgImpl : public wxNotifMsgImpl -{ -public: - wxGenericNotifMsgImpl() : m_notif(new wxGenericNotificationMessage) { } - virtual ~wxGenericNotifMsgImpl() { delete m_notif; } - - virtual bool DoShow(const wxString& title, - const wxString& message, - int timeout, - int flags) - { - m_notif->SetTitle(title); - m_notif->SetMessage(message); - m_notif->SetFlags(flags); - return m_notif->Show(timeout); - } - - virtual bool DoClose() - { - return m_notif->Close(); - } - -private: - wxGenericNotificationMessage * const m_notif; -}; - -// common base class for implementations using a taskbar icon and balloons -class wxBalloonNotifMsgImpl : public wxNotifMsgImpl +// implementations using a taskbar icon and balloons +class wxBalloonNotifMsgImpl : public wxNotificationMessageImpl { public: // Ctor creates the associated taskbar icon (using the icon of the top // level parent of the given window) unless UseTaskBarIcon() had been // previously called which can be used to show an attached balloon later // by the derived classes. - wxBalloonNotifMsgImpl(wxWindow *win) { SetUpIcon(win); } + wxBalloonNotifMsgImpl(wxNotificationMessageBase* notification) : + wxNotificationMessageImpl(notification), + m_flags(0), + m_parent(NULL) + { + + } + + virtual ~wxBalloonNotifMsgImpl(); + + virtual bool Show(int timeout) wxOVERRIDE; + + virtual bool Close() wxOVERRIDE; + + virtual void SetTitle(const wxString& title) wxOVERRIDE + { + m_title = title; + } + + virtual void SetMessage(const wxString& message) wxOVERRIDE + { + m_message = message; + } + + virtual void SetParent(wxWindow *parent) wxOVERRIDE + { + m_parent = parent; + } + + virtual void SetFlags(int flags) wxOVERRIDE + { + m_flags = flags; + } + + virtual void SetIcon(const wxIcon& icon) wxOVERRIDE + { + m_icon = icon; + } + + virtual bool AddAction(wxWindowID WXUNUSED(actionid), const wxString &WXUNUSED(label)) + { + // Actions are not supported in balloon notifications + return false; + } // implementation of wxNotificationMessage method with the same name static wxTaskBarIcon *UseTaskBarIcon(wxTaskBarIcon *icon); - virtual bool DoShow(const wxString& title, - const wxString& message, - int timeout, - int flags); - - // Returns true if we're using our own icon or false if we're hitching a // ride on the application icon provided to us via UseTaskBarIcon(). static bool IsUsingOwnIcon() @@ -124,7 +119,7 @@ public: wxASSERT_MSG( ms_refCountIcon != -1, wxS("Must not be called when not using own icon") ); - if ( !--ms_refCountIcon ) + if ( ms_refCountIcon > 0 && !--ms_refCountIcon ) { delete ms_icon; ms_icon = NULL; @@ -152,117 +147,25 @@ protected: // the icon is only destroyed when it reaches 0. static wxTaskBarIcon *ms_icon; static int ms_refCountIcon; -}; - -// implementation for automatically hidden notifications -class wxAutoNotifMsgImpl : public wxBalloonNotifMsgImpl -{ -public: - wxAutoNotifMsgImpl(wxWindow *win); - - virtual bool DoShow(const wxString& title, - const wxString& message, - int timeout, - int flags); - - // can't close automatic notification [currently] - virtual bool DoClose() { return false; } -}; - -// implementation for manually closed notifications -class wxManualNotifMsgImpl : public wxBalloonNotifMsgImpl -{ -public: - wxManualNotifMsgImpl(wxWindow *win); - virtual ~wxManualNotifMsgImpl(); - - virtual bool DoShow(const wxString& title, - const wxString& message, - int timeout, - int flags); - virtual bool DoClose(); - private: - // store ctor parameter as we need it to recreate the icon later if we're - // closed and shown again - wxWindow * const m_win; -}; + wxString m_title; + wxString m_message; + int m_flags; + wxIcon m_icon; + wxWindow* m_parent; -// ---------------------------------------------------------------------------- -// custom event handler for task bar icons -// ---------------------------------------------------------------------------- - -// normally we'd just use a custom taskbar icon class but this is impossible -// because we can be asked to attach the notifications to an existing icon -// which we didn't create, hence we install a special event handler allowing us -// to get the events we need (and, crucially, to delete the icon when it's not -// needed any more) in any case - -class wxNotificationIconEvtHandler : public wxEvtHandler -{ -public: - wxNotificationIconEvtHandler(wxTaskBarIcon *icon); - -private: void OnTimeout(wxTaskBarIconEvent& event); void OnClick(wxTaskBarIconEvent& event); void OnIconHidden(); - - - wxTaskBarIcon * const m_icon; - - wxDECLARE_NO_COPY_CLASS(wxNotificationIconEvtHandler); }; +// ---------------------------------------------------------------------------- + // ============================================================================ // implementation // ============================================================================ -// ---------------------------------------------------------------------------- -// wxNotificationIconEvtHandler -// ---------------------------------------------------------------------------- - -wxNotificationIconEvtHandler::wxNotificationIconEvtHandler(wxTaskBarIcon *icon) - : m_icon(icon) -{ - m_icon->Connect - ( - wxEVT_TASKBAR_BALLOON_TIMEOUT, - wxTaskBarIconEventHandler(wxNotificationIconEvtHandler::OnTimeout), - NULL, - this - ); - - m_icon->Connect - ( - wxEVT_TASKBAR_BALLOON_CLICK, - wxTaskBarIconEventHandler(wxNotificationIconEvtHandler::OnClick), - NULL, - this - ); -} - -void wxNotificationIconEvtHandler::OnIconHidden() -{ - wxBalloonNotifMsgImpl::ReleaseIcon(); - - delete this; -} - -void -wxNotificationIconEvtHandler::OnTimeout(wxTaskBarIconEvent& WXUNUSED(event)) -{ - OnIconHidden(); -} - -void wxNotificationIconEvtHandler::OnClick(wxTaskBarIconEvent& WXUNUSED(event)) -{ - // TODO: generate an event notifying the user code? - - OnIconHidden(); -} - // ---------------------------------------------------------------------------- // wxBalloonNotifMsgImpl // ---------------------------------------------------------------------------- @@ -282,6 +185,39 @@ wxTaskBarIcon *wxBalloonNotifMsgImpl::UseTaskBarIcon(wxTaskBarIcon *icon) return iconOld; } +wxBalloonNotifMsgImpl::~wxBalloonNotifMsgImpl() +{ +} + +void wxBalloonNotifMsgImpl::OnIconHidden() +{ + SetActive(false); + if ( ms_icon ) + { + ms_icon->Unbind(wxEVT_TASKBAR_BALLOON_CLICK, &wxBalloonNotifMsgImpl::OnClick, this); + ms_icon->Unbind(wxEVT_TASKBAR_BALLOON_TIMEOUT, &wxBalloonNotifMsgImpl::OnTimeout, this); + } + + if ( IsUsingOwnIcon() ) + wxBalloonNotifMsgImpl::ReleaseIcon(); +} + +void wxBalloonNotifMsgImpl::OnTimeout(wxTaskBarIconEvent& WXUNUSED(event)) +{ + wxCommandEvent evt(wxEVT_NOTIFICATION_MESSAGE_DISMISSED); + ProcessNotificationEvent(evt); + + OnIconHidden(); +} + +void wxBalloonNotifMsgImpl::OnClick(wxTaskBarIconEvent& WXUNUSED(event)) +{ + wxCommandEvent evt(wxEVT_NOTIFICATION_MESSAGE_CLICK); + ProcessNotificationEvent(evt); + + OnIconHidden(); +} + void wxBalloonNotifMsgImpl::SetUpIcon(wxWindow *win) { if ( ms_icon ) @@ -322,12 +258,15 @@ void wxBalloonNotifMsgImpl::SetUpIcon(wxWindow *win) } } -bool -wxBalloonNotifMsgImpl::DoShow(const wxString& title, - const wxString& message, - int timeout, - int flags) +bool +wxBalloonNotifMsgImpl::Show(int timeout) { + // timout active event + wxTaskBarIconEvent event(wxEVT_TASKBAR_BALLOON_TIMEOUT, ms_icon); + OnTimeout(event); + + SetUpIcon(m_parent); + if ( !ms_icon->IsIconInstalled() ) { // If we failed to install the icon (which does happen sometimes, @@ -346,54 +285,40 @@ wxBalloonNotifMsgImpl::DoShow(const wxString& title, return false; } + // Since Windows Vista timeout is ignored so this values are only for XP + if ( timeout == wxNotificationMessage::Timeout_Auto ) + { + // choose a value more or less in the middle of the allowed range + timeout = 1; + } + else if ( timeout == wxNotificationMessage::Timeout_Never ) + { + // use maximal (in Windows XP) timeout (but it will still + // disappear on its own) + timeout = 30; + } + timeout *= 1000; // Windows expresses timeout in milliseconds - return ms_icon->ShowBalloon(title, message, timeout, flags); -} - -// ---------------------------------------------------------------------------- -// wxManualNotifMsgImpl -// ---------------------------------------------------------------------------- - -wxManualNotifMsgImpl::wxManualNotifMsgImpl(wxWindow *win) - : wxBalloonNotifMsgImpl(win), - m_win(win) -{ -} - -wxManualNotifMsgImpl::~wxManualNotifMsgImpl() -{ - if ( ms_icon ) - DoClose(); -} - -bool -wxManualNotifMsgImpl::DoShow(const wxString& title, - const wxString& message, - int WXUNUSED_UNLESS_DEBUG(timeout), - int flags) -{ - wxASSERT_MSG( timeout == wxNotificationMessage::Timeout_Never, - wxT("shouldn't be used") ); - - // base class creates the icon for us initially but we could have destroyed - // it in DoClose(), recreate it if this was the case - if ( !ms_icon ) - SetUpIcon(m_win); - - // use maximal (in current Windows versions) timeout (but it will still - // disappear on its own) - return wxBalloonNotifMsgImpl::DoShow(title, message, 30, flags); -} - -bool wxManualNotifMsgImpl::DoClose() -{ - if ( IsUsingOwnIcon() ) + bool res = ms_icon->ShowBalloon(m_title, m_message, timeout, m_flags, m_icon); + if ( res ) { - // we don't need the icon any more - ReleaseIcon(); + ms_icon->Bind(wxEVT_TASKBAR_BALLOON_CLICK, &wxBalloonNotifMsgImpl::OnClick, this); + ms_icon->Bind(wxEVT_TASKBAR_BALLOON_TIMEOUT, &wxBalloonNotifMsgImpl::OnTimeout, this); + SetActive(true); } - else // using an existing icon + + return res; +} + +bool wxBalloonNotifMsgImpl::Close() +{ + wxCommandEvent evt(wxEVT_NOTIFICATION_MESSAGE_DISMISSED); + ProcessNotificationEvent(evt); + + OnIconHidden(); + + if ( !IsUsingOwnIcon() && ms_icon ) { // just hide the balloon ms_icon->ShowBalloon("", ""); @@ -402,84 +327,19 @@ bool wxManualNotifMsgImpl::DoClose() return true; } -// ---------------------------------------------------------------------------- -// wxAutoNotifMsgImpl -// ---------------------------------------------------------------------------- - -wxAutoNotifMsgImpl::wxAutoNotifMsgImpl(wxWindow *win) - : wxBalloonNotifMsgImpl(win) -{ - if ( ms_refCountIcon != -1 ) - { - // This object will self-destruct and decrease the ref count of the - // icon when the notification is hidden. - new wxNotificationIconEvtHandler(ms_icon); - } -} - -bool -wxAutoNotifMsgImpl::DoShow(const wxString& title, - const wxString& message, - int timeout, - int flags) -{ - wxASSERT_MSG( timeout != wxNotificationMessage::Timeout_Never, - wxT("shouldn't be used") ); - - if ( timeout == wxNotificationMessage::Timeout_Auto ) - { - // choose a value more or less in the middle of the allowed range - timeout = 1; - } - - return wxBalloonNotifMsgImpl::DoShow(title, message, timeout, flags); -} - // ---------------------------------------------------------------------------- // wxNotificationMessage // ---------------------------------------------------------------------------- -/* static */ -bool wxNotificationMessage::ms_alwaysUseGeneric = false; - /* static */ wxTaskBarIcon *wxNotificationMessage::UseTaskBarIcon(wxTaskBarIcon *icon) { return wxBalloonNotifMsgImpl::UseTaskBarIcon(icon); } -bool wxNotificationMessage::Show(int timeout) +void wxNotificationMessage::Init() { - if ( !m_impl ) - { - if ( !ms_alwaysUseGeneric ) - { - if ( timeout == Timeout_Never ) - m_impl = new wxManualNotifMsgImpl(GetParent()); - else - m_impl = new wxAutoNotifMsgImpl(GetParent()); - } - else // no support for balloon tooltips - { - m_impl = new wxGenericNotifMsgImpl; - } - } - //else: reuse the same implementation for the subsequent calls, it would - // be too confusing if it changed - - return m_impl->DoShow(GetTitle(), GetMessage(), timeout, GetFlags()); -} - -bool wxNotificationMessage::Close() -{ - wxCHECK_MSG( m_impl, false, "must show the notification first" ); - - return m_impl->DoClose(); -} - -wxNotificationMessage::~wxNotificationMessage() -{ - delete m_impl; + m_impl = new wxBalloonNotifMsgImpl(this); } #endif // wxUSE_NOTIFICATION_MESSAGE && wxUSE_TASKBARICON diff --git a/src/msw/taskbar.cpp b/src/msw/taskbar.cpp index a09cff9964..5d4e066993 100644 --- a/src/msw/taskbar.cpp +++ b/src/msw/taskbar.cpp @@ -30,6 +30,7 @@ #include #include "wx/taskbar.h" +#include "wx/platinfo.h" #include "wx/msw/private.h" #ifndef NIN_BALLOONTIMEOUT @@ -109,13 +110,12 @@ struct NotifyIconData : public NOTIFYICONDATA { memset(this, 0, sizeof(NOTIFYICONDATA)); - // Do _not_ use sizeof(NOTIFYICONDATA) here, it may be too big if we're - // compiled with newer headers but running on an older system and while - // we could do complicated tests for the exact system version it's - // easier to just use an old size which should be supported everywhere - // from Windows 2000 up and which is all we need as we don't use any - // newer features so far. - cbSize = NOTIFYICONDATA_V2_SIZE; + // Since Vista there is a new member hBalloonIcon which will be used + // if a user specified icon is specified in ShowBalloon(). For XP + // use the old size + cbSize = wxPlatformInfo::Get().CheckOSVersion(6, 0) + ? sizeof(NOTIFYICONDATA) + : NOTIFYICONDATA_V2_SIZE; hWnd = (HWND) hwnd; uCallbackMessage = gs_msgTaskbar; @@ -203,7 +203,8 @@ bool wxTaskBarIcon::ShowBalloon(const wxString& title, const wxString& text, unsigned msec, - int flags) + int flags, + const wxIcon& icon) { wxCHECK_MSG( m_iconAdded, false, wxT("can't be used before the icon is created") ); @@ -229,6 +230,15 @@ wxTaskBarIcon::ShowBalloon(const wxString& title, wxStrlcpy(notifyData.szInfoTitle, title.t_str(), WXSIZEOF(notifyData.szInfoTitle)); +#ifdef NIIF_LARGE_ICON + // User specified icon is only supported since Vista + if ( icon.IsOk() && wxPlatformInfo::Get().CheckOSVersion(6, 0) ) + { + notifyData.hBalloonIcon = GetHiconOf(icon); + notifyData.dwInfoFlags |= NIIF_USER | NIIF_LARGE_ICON; + } + else +#endif if ( flags & wxICON_INFORMATION ) notifyData.dwInfoFlags |= NIIF_INFO; else if ( flags & wxICON_WARNING ) diff --git a/src/osx/cocoa/notifmsg.mm b/src/osx/cocoa/notifmsg.mm new file mode 100644 index 0000000000..692efdaa4b --- /dev/null +++ b/src/osx/cocoa/notifmsg.mm @@ -0,0 +1,254 @@ +/////////////////////////////////////////////////////////////////////////////// +// Name: src/osx/notifmsg.cpp +// Purpose: implementation of wxNotificationMessage for OSX +// Author: Tobias Taschner +// Created: 2015-08-06 +// Copyright: (c) 2015 wxWidgets development team +// Licence: wxWindows licence +/////////////////////////////////////////////////////////////////////////////// + +// ============================================================================ +// declarations +// ============================================================================ + +// ---------------------------------------------------------------------------- +// headers +// ---------------------------------------------------------------------------- + +// for compilers that support precompilation, includes "wx.h". +#include "wx/wxprec.h" + +#ifdef __BORLANDC__ + #pragma hdrstop +#endif + +#include "wx/notifmsg.h" + +#if wxUSE_NOTIFICATION_MESSAGE && defined(wxHAS_NATIVE_NOTIFICATION_MESSAGE) + +#ifndef WX_PRECOMP + #include "wx/string.h" +#endif // WX_PRECOMP + +#include "wx/osx/private.h" +#include "wx/generic/notifmsg.h" +#include "wx/private/notifmsg.h" +#include "wx/generic/private/notifmsg.h" +#include "wx/timer.h" +#include "wx/platinfo.h" +#include "wx/artprov.h" +#include "wx/vector.h" +#include "wx/stockitem.h" + +#include "wx/utils.h" +#include + +@interface wxUserNotificationHandler : NSObject + +@end + +// ---------------------------------------------------------------------------- +// wxUserNotificationMsgImpl +// ---------------------------------------------------------------------------- + +class wxUserNotificationMsgImpl : public wxNotificationMessageImpl +{ +public: + wxUserNotificationMsgImpl(wxNotificationMessageBase* notification) : + wxNotificationMessageImpl(notification) + { + UseHandler(); + m_notif = [[NSUserNotification alloc] init]; + + // Build Id to unqiuely idendify this notification + m_id = wxString::Format("%d_%d", (int)wxGetProcessId(), ms_notifIdBase++); + + // Register the notification + ms_activeNotifications[m_id] = this; + + wxCFStringRef cfId(m_id); + m_notif.userInfo = @{ + @"wxId" : cfId.AsNSString() + }; + } + + virtual ~wxUserNotificationMsgImpl() + { + ms_activeNotifications[m_id] = NULL; + ReleaseHandler(); + [m_notif release]; + } + + virtual bool Show(int WXUNUSED(timeout)) wxOVERRIDE + { + NSUserNotificationCenter* nc = [NSUserNotificationCenter defaultUserNotificationCenter]; + [nc deliverNotification:m_notif]; + + return true; + } + + virtual bool Close() wxOVERRIDE + { + NSUserNotificationCenter* nc = [NSUserNotificationCenter defaultUserNotificationCenter]; + [nc removeDeliveredNotification:m_notif]; + + return true; + } + + virtual void SetTitle(const wxString& title) wxOVERRIDE + { + wxCFStringRef cftitle(title); + m_notif.title = cftitle.AsNSString(); + } + + virtual void SetMessage(const wxString& message) wxOVERRIDE + { + wxCFStringRef cfmsg(message); + m_notif.informativeText = cfmsg.AsNSString(); + } + + virtual void SetParent(wxWindow *WXUNUSED(parent)) wxOVERRIDE + { + } + + virtual void SetFlags(int WXUNUSED(flags)) wxOVERRIDE + { + // On OS X we do not add an icon based on the flags, + // as this is primarily meant for custom icons + } + + virtual void SetIcon(const wxIcon& icon) wxOVERRIDE + { + // Additional icon in the notification is only supported on OS X 10.9+ + if ([NSUserNotification instancesRespondToSelector:@selector(setContentImage:)]) + m_notif.contentImage = icon.GetNSImage(); + } + + virtual bool AddAction(wxWindowID actionid, const wxString &label) + { + if (m_actions.size() >= 1) // Currently only 1 actions are supported + return false; + + wxString strLabel = label; + if (strLabel.empty()) + strLabel = wxGetStockLabel(actionid, wxSTOCK_NOFLAGS); + wxCFStringRef cflabel(strLabel); + + m_actions.push_back(actionid); + + if (m_actions.size() == 1) + m_notif.actionButtonTitle = cflabel.AsNSString(); + + return true; + } + + void Activated(NSUserNotificationActivationType activationType) + { + switch (activationType) + { + case NSUserNotificationActivationTypeNone: + { + wxCommandEvent evt(wxEVT_NOTIFICATION_MESSAGE_DISMISSED); + ProcessNotificationEvent(evt); + break; + } + case NSUserNotificationActivationTypeContentsClicked: + { + wxCommandEvent evt(wxEVT_NOTIFICATION_MESSAGE_CLICK); + ProcessNotificationEvent(evt); + Close(); + break; + } + case NSUserNotificationActivationTypeActionButtonClicked: + { + if (m_actions.empty()) + { + // Without actions the action button is handled as a message click + wxCommandEvent evt(wxEVT_NOTIFICATION_MESSAGE_CLICK); + ProcessNotificationEvent(evt); + } + else + { + wxCommandEvent evt(wxEVT_NOTIFICATION_MESSAGE_ACTION); + evt.SetId(m_actions[0]); + ProcessNotificationEvent(evt); + } + Close(); + break; + } + + default: + break; + }; + } + + static void NotificationActivated(const wxString& notificationId, NSUserNotificationActivationType activationType) + { + wxUserNotificationMsgImpl* impl = ms_activeNotifications[notificationId]; + if (impl) + impl->Activated(activationType); + } + + static void UseHandler() + { + if (!ms_handler) + { + ms_handler = [wxUserNotificationHandler alloc]; + [NSUserNotificationCenter defaultUserNotificationCenter].delegate = ms_handler; + } + } + + static void ReleaseHandler() + { + + } + +private: + NSUserNotification* m_notif; + wxString m_id; + wxVector m_actions; + + static wxUserNotificationHandler* ms_handler; + static std::map ms_activeNotifications; + static int ms_notifIdBase; +}; + +wxUserNotificationHandler* wxUserNotificationMsgImpl::ms_handler = nil; +std::map wxUserNotificationMsgImpl::ms_activeNotifications; +int wxUserNotificationMsgImpl::ms_notifIdBase = 1000; + +// ---------------------------------------------------------------------------- +// wxUserNotificationHandler +// ---------------------------------------------------------------------------- + +@implementation wxUserNotificationHandler + +- (void)userNotificationCenter:(NSUserNotificationCenter *)center didActivateNotification:(NSUserNotification *)notification +{ + NSString* notifId = [notification.userInfo objectForKey:@"wxId"]; + if (notifId) + wxUserNotificationMsgImpl::NotificationActivated(wxCFStringRef::AsString(notifId), notification.activationType); +} + +@end + +// ============================================================================ +// implementation +// ============================================================================ + + +// ---------------------------------------------------------------------------- +// wxNotificationMessage +// ---------------------------------------------------------------------------- + +void wxNotificationMessage::Init() +{ + // Native notifications are not available prior to 10.8, fallback + // to generic ones on 10.7 + if (wxPlatformInfo::Get().CheckOSVersion(10, 8)) + m_impl = new wxUserNotificationMsgImpl(this); + else + m_impl = new wxGenericNotificationMessageImpl(this); +} + +#endif // wxUSE_NOTIFICATION_MESSAGE && defined(wxHAS_NATIVE_NOTIFICATION_MESSAGE) From 816c58e0afa5c1fd4d575c71e6bd784ee10cd30e Mon Sep 17 00:00:00 2001 From: Tobias Taschner Date: Mon, 14 Sep 2015 20:44:53 +0200 Subject: [PATCH 2/4] Add documentation for wxNotificationMessage::UseTaskBarIcon (MSW). The method is not new, but was undocumented previously. --- interface/wx/notifmsg.h | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/interface/wx/notifmsg.h b/interface/wx/notifmsg.h index 7b35be6f82..b93cccf6e5 100644 --- a/interface/wx/notifmsg.h +++ b/interface/wx/notifmsg.h @@ -158,5 +158,17 @@ public: @return @false if an error occurred. */ virtual bool Show(int timeout = Timeout_Auto); + + /** + If the application already uses a wxTaskBarIcon, it should be connected + to notifications by using this method. This has no effect if toast + notifications are used. + + @return the task bar icon which was used previously (may be @c NULL) + + @onlyfor{wxmsw} + */ + static wxTaskBarIcon *UseTaskBarIcon(wxTaskBarIcon *icon); + }; From 72db8a6265352c848ebc11b2f615e89223e26f75 Mon Sep 17 00:00:00 2001 From: Tobias Taschner Date: Mon, 14 Sep 2015 20:00:00 +0200 Subject: [PATCH 3/4] Add basic support to use WinRT APIs. Some Windows8+ APIs are only accessible via WinRT which is based on COM. However there are a few dependencies to get to the interfaces via functions defined in roapi.h. Using RoInitialize, RoUninitialize, etc. directly from it's windows headers adds dependencies to the WinRT dlls leaving the resulting exe unable to launch on earlier Windows versions. The wxWinRT functions wrap this with dynamic loading. Additionally wxWinRT::TempStringRef adds a convenient wrapper to HSTRING which is used extensively in WinRT APIs. --- Makefile.in | 21 ++ build/bakefiles/files.bkl | 2 + build/files | 2 + build/msw/makefile.bcc | 28 +++ build/msw/makefile.gcc | 28 +++ build/msw/makefile.vc | 28 +++ build/msw/wx_core.vcxproj | 4 +- build/msw/wx_core.vcxproj.filters | 6 + build/msw/wx_vc7_core.vcproj | 6 + build/msw/wx_vc8_core.vcproj | 8 + build/msw/wx_vc9_core.vcproj | 8 + docs/doxygen/mainpages/const_wxusedef.h | 1 + include/wx/gtk/setup0.h | 13 ++ include/wx/msw/chkconf.h | 8 + include/wx/msw/rt/utils.h | 84 ++++++++ include/wx/msw/setup0.h | 13 ++ include/wx/msw/setup_inc.h | 13 ++ setup.h.in | 6 + src/msw/rt/utilsrt.cpp | 259 ++++++++++++++++++++++++ 19 files changed, 537 insertions(+), 1 deletion(-) create mode 100644 include/wx/msw/rt/utils.h create mode 100644 src/msw/rt/utilsrt.cpp diff --git a/Makefile.in b/Makefile.in index dc1879b412..e603897022 100644 --- a/Makefile.in +++ b/Makefile.in @@ -3129,6 +3129,7 @@ COND_TOOLKIT_MSW_GUI_HDR = \ wx/msw/toplevel.h \ wx/msw/treectrl.h \ wx/msw/window.h \ + wx/msw/rt/utils.h \ wx/msw/checklst.h \ wx/msw/fdrepdlg.h \ wx/msw/fontdlg.h \ @@ -4912,6 +4913,7 @@ COND_TOOLKIT_MSW___LOWLEVEL_SRC_OBJECTS = \ monodll_uxtheme.o \ monodll_msw_window.o \ monodll_graphicsd2d.o \ + monodll_utilsrt.o \ monodll_helpchm.o \ monodll_helpwin.o \ monodll_automtn.o \ @@ -5614,6 +5616,7 @@ COND_TOOLKIT_MSW___LOWLEVEL_SRC_OBJECTS_1 = \ monodll_uxtheme.o \ monodll_msw_window.o \ monodll_graphicsd2d.o \ + monodll_utilsrt.o \ monodll_helpchm.o \ monodll_helpwin.o \ monodll_automtn.o \ @@ -6912,6 +6915,7 @@ COND_TOOLKIT_MSW___LOWLEVEL_SRC_OBJECTS_2 = \ monolib_uxtheme.o \ monolib_msw_window.o \ monolib_graphicsd2d.o \ + monolib_utilsrt.o \ monolib_helpchm.o \ monolib_helpwin.o \ monolib_automtn.o \ @@ -7614,6 +7618,7 @@ COND_TOOLKIT_MSW___LOWLEVEL_SRC_OBJECTS_3 = \ monolib_uxtheme.o \ monolib_msw_window.o \ monolib_graphicsd2d.o \ + monolib_utilsrt.o \ monolib_helpchm.o \ monolib_helpwin.o \ monolib_automtn.o \ @@ -9055,6 +9060,7 @@ COND_TOOLKIT_MSW___LOWLEVEL_SRC_OBJECTS_4 = \ coredll_uxtheme.o \ coredll_msw_window.o \ coredll_graphicsd2d.o \ + coredll_utilsrt.o \ coredll_helpchm.o \ coredll_helpwin.o \ coredll_automtn.o \ @@ -9757,6 +9763,7 @@ COND_TOOLKIT_MSW___LOWLEVEL_SRC_OBJECTS_5 = \ coredll_uxtheme.o \ coredll_msw_window.o \ coredll_graphicsd2d.o \ + coredll_utilsrt.o \ coredll_helpchm.o \ coredll_helpwin.o \ coredll_automtn.o \ @@ -10520,6 +10527,7 @@ COND_TOOLKIT_MSW___LOWLEVEL_SRC_OBJECTS_6 = \ corelib_uxtheme.o \ corelib_msw_window.o \ corelib_graphicsd2d.o \ + corelib_utilsrt.o \ corelib_helpchm.o \ corelib_helpwin.o \ corelib_automtn.o \ @@ -11222,6 +11230,7 @@ COND_TOOLKIT_MSW___LOWLEVEL_SRC_OBJECTS_7 = \ corelib_uxtheme.o \ corelib_msw_window.o \ corelib_graphicsd2d.o \ + corelib_utilsrt.o \ corelib_helpchm.o \ corelib_helpwin.o \ corelib_automtn.o \ @@ -17982,6 +17991,9 @@ monodll_sound_sdl.o: $(srcdir)/src/unix/sound_sdl.cpp $(MONODLL_ODEP) @COND_TOOLKIT_MSW_USE_GUI_1@monodll_graphicsd2d.o: $(srcdir)/src/msw/graphicsd2d.cpp $(MONODLL_ODEP) @COND_TOOLKIT_MSW_USE_GUI_1@ $(CXXC) -c -o $@ $(MONODLL_CXXFLAGS) $(srcdir)/src/msw/graphicsd2d.cpp +@COND_TOOLKIT_MSW_USE_GUI_1@monodll_utilsrt.o: $(srcdir)/src/msw/rt/utilsrt.cpp $(MONODLL_ODEP) +@COND_TOOLKIT_MSW_USE_GUI_1@ $(CXXC) -c -o $@ $(MONODLL_CXXFLAGS) $(srcdir)/src/msw/rt/utilsrt.cpp + @COND_TOOLKIT_MSW_USE_GUI_1@monodll_helpchm.o: $(srcdir)/src/msw/helpchm.cpp $(MONODLL_ODEP) @COND_TOOLKIT_MSW_USE_GUI_1@ $(CXXC) -c -o $@ $(MONODLL_CXXFLAGS) $(srcdir)/src/msw/helpchm.cpp @@ -22791,6 +22803,9 @@ monolib_sound_sdl.o: $(srcdir)/src/unix/sound_sdl.cpp $(MONOLIB_ODEP) @COND_TOOLKIT_MSW_USE_GUI_1@monolib_graphicsd2d.o: $(srcdir)/src/msw/graphicsd2d.cpp $(MONOLIB_ODEP) @COND_TOOLKIT_MSW_USE_GUI_1@ $(CXXC) -c -o $@ $(MONOLIB_CXXFLAGS) $(srcdir)/src/msw/graphicsd2d.cpp +@COND_TOOLKIT_MSW_USE_GUI_1@monolib_utilsrt.o: $(srcdir)/src/msw/rt/utilsrt.cpp $(MONOLIB_ODEP) +@COND_TOOLKIT_MSW_USE_GUI_1@ $(CXXC) -c -o $@ $(MONOLIB_CXXFLAGS) $(srcdir)/src/msw/rt/utilsrt.cpp + @COND_TOOLKIT_MSW_USE_GUI_1@monolib_helpchm.o: $(srcdir)/src/msw/helpchm.cpp $(MONOLIB_ODEP) @COND_TOOLKIT_MSW_USE_GUI_1@ $(CXXC) -c -o $@ $(MONOLIB_CXXFLAGS) $(srcdir)/src/msw/helpchm.cpp @@ -27660,6 +27675,9 @@ coredll_win32.o: $(srcdir)/src/univ/themes/win32.cpp $(COREDLL_ODEP) @COND_TOOLKIT_MSW_USE_GUI_1@coredll_graphicsd2d.o: $(srcdir)/src/msw/graphicsd2d.cpp $(COREDLL_ODEP) @COND_TOOLKIT_MSW_USE_GUI_1@ $(CXXC) -c -o $@ $(COREDLL_CXXFLAGS) $(srcdir)/src/msw/graphicsd2d.cpp +@COND_TOOLKIT_MSW_USE_GUI_1@coredll_utilsrt.o: $(srcdir)/src/msw/rt/utilsrt.cpp $(COREDLL_ODEP) +@COND_TOOLKIT_MSW_USE_GUI_1@ $(CXXC) -c -o $@ $(COREDLL_CXXFLAGS) $(srcdir)/src/msw/rt/utilsrt.cpp + @COND_TOOLKIT_MSW_USE_GUI_1@coredll_helpchm.o: $(srcdir)/src/msw/helpchm.cpp $(COREDLL_ODEP) @COND_TOOLKIT_MSW_USE_GUI_1@ $(CXXC) -c -o $@ $(COREDLL_CXXFLAGS) $(srcdir)/src/msw/helpchm.cpp @@ -31044,6 +31062,9 @@ corelib_win32.o: $(srcdir)/src/univ/themes/win32.cpp $(CORELIB_ODEP) @COND_TOOLKIT_MSW_USE_GUI_1@corelib_graphicsd2d.o: $(srcdir)/src/msw/graphicsd2d.cpp $(CORELIB_ODEP) @COND_TOOLKIT_MSW_USE_GUI_1@ $(CXXC) -c -o $@ $(CORELIB_CXXFLAGS) $(srcdir)/src/msw/graphicsd2d.cpp +@COND_TOOLKIT_MSW_USE_GUI_1@corelib_utilsrt.o: $(srcdir)/src/msw/rt/utilsrt.cpp $(CORELIB_ODEP) +@COND_TOOLKIT_MSW_USE_GUI_1@ $(CXXC) -c -o $@ $(CORELIB_CXXFLAGS) $(srcdir)/src/msw/rt/utilsrt.cpp + @COND_TOOLKIT_MSW_USE_GUI_1@corelib_helpchm.o: $(srcdir)/src/msw/helpchm.cpp $(CORELIB_ODEP) @COND_TOOLKIT_MSW_USE_GUI_1@ $(CXXC) -c -o $@ $(CORELIB_CXXFLAGS) $(srcdir)/src/msw/helpchm.cpp diff --git a/build/bakefiles/files.bkl b/build/bakefiles/files.bkl index 073c850a02..60c45487eb 100644 --- a/build/bakefiles/files.bkl +++ b/build/bakefiles/files.bkl @@ -1895,6 +1895,7 @@ IMPORTANT: please read docs/tech/tn0016.txt before modifying this file! src/msw/uxtheme.cpp src/msw/window.cpp src/msw/graphicsd2d.cpp + src/msw/rt/utilsrt.cpp wx/msw/nonownedwnd.h @@ -2075,6 +2076,7 @@ IMPORTANT: please read docs/tech/tn0016.txt before modifying this file! wx/msw/toplevel.h wx/msw/treectrl.h wx/msw/window.h + wx/msw/rt/utils.h diff --git a/build/files b/build/files index 7a741064e2..8de7b237de 100644 --- a/build/files +++ b/build/files @@ -1550,6 +1550,7 @@ MSW_LOWLEVEL_SRC = src/msw/printwin.cpp src/msw/region.cpp src/msw/renderer.cpp + src/msw/rt/utilsrt.cpp src/msw/settings.cpp src/msw/textmeasure.cpp src/msw/tooltip.cpp @@ -1716,6 +1717,7 @@ MSW_HDR = wx/msw/region.h wx/msw/rcdefs.h wx/msw/richmsgdlg.h + wx/msw/rt/utils.h wx/msw/scrolbar.h wx/msw/slider.h wx/msw/spinbutt.h diff --git a/build/msw/makefile.bcc b/build/msw/makefile.bcc index 70f891216e..b991f9722e 100644 --- a/build/msw/makefile.bcc +++ b/build/msw/makefile.bcc @@ -1824,6 +1824,7 @@ ____CORE_SRC_FILENAMES_OBJECTS = \ $(OBJS)\monodll_uxtheme.obj \ $(OBJS)\monodll_window.obj \ $(OBJS)\monodll_graphicsd2d.obj \ + $(OBJS)\monodll_utilsrt.obj \ $(OBJS)\monodll_helpchm.obj \ $(OBJS)\monodll_helpwin.obj \ $(OBJS)\monodll_automtn.obj \ @@ -2110,6 +2111,7 @@ ____CORE_SRC_FILENAMES_OBJECTS = \ $(OBJS)\monodll_uxtheme.obj \ $(OBJS)\monodll_window.obj \ $(OBJS)\monodll_graphicsd2d.obj \ + $(OBJS)\monodll_utilsrt.obj \ $(OBJS)\monodll_helpchm.obj \ $(OBJS)\monodll_helpwin.obj \ $(OBJS)\monodll_automtn.obj \ @@ -2648,6 +2650,7 @@ ____CORE_SRC_FILENAMES_1_OBJECTS = \ $(OBJS)\monolib_uxtheme.obj \ $(OBJS)\monolib_window.obj \ $(OBJS)\monolib_graphicsd2d.obj \ + $(OBJS)\monolib_utilsrt.obj \ $(OBJS)\monolib_helpchm.obj \ $(OBJS)\monolib_helpwin.obj \ $(OBJS)\monolib_automtn.obj \ @@ -2934,6 +2937,7 @@ ____CORE_SRC_FILENAMES_1_OBJECTS = \ $(OBJS)\monolib_uxtheme.obj \ $(OBJS)\monolib_window.obj \ $(OBJS)\monolib_graphicsd2d.obj \ + $(OBJS)\monolib_utilsrt.obj \ $(OBJS)\monolib_helpchm.obj \ $(OBJS)\monolib_helpwin.obj \ $(OBJS)\monolib_automtn.obj \ @@ -3345,6 +3349,7 @@ ____CORE_SRC_FILENAMES_2_OBJECTS = \ $(OBJS)\coredll_uxtheme.obj \ $(OBJS)\coredll_window.obj \ $(OBJS)\coredll_graphicsd2d.obj \ + $(OBJS)\coredll_utilsrt.obj \ $(OBJS)\coredll_helpchm.obj \ $(OBJS)\coredll_helpwin.obj \ $(OBJS)\coredll_automtn.obj \ @@ -3631,6 +3636,7 @@ ____CORE_SRC_FILENAMES_2_OBJECTS = \ $(OBJS)\coredll_uxtheme.obj \ $(OBJS)\coredll_window.obj \ $(OBJS)\coredll_graphicsd2d.obj \ + $(OBJS)\coredll_utilsrt.obj \ $(OBJS)\coredll_helpchm.obj \ $(OBJS)\coredll_helpwin.obj \ $(OBJS)\coredll_automtn.obj \ @@ -3913,6 +3919,7 @@ ____CORE_SRC_FILENAMES_3_OBJECTS = \ $(OBJS)\corelib_uxtheme.obj \ $(OBJS)\corelib_window.obj \ $(OBJS)\corelib_graphicsd2d.obj \ + $(OBJS)\corelib_utilsrt.obj \ $(OBJS)\corelib_helpchm.obj \ $(OBJS)\corelib_helpwin.obj \ $(OBJS)\corelib_automtn.obj \ @@ -4199,6 +4206,7 @@ ____CORE_SRC_FILENAMES_3_OBJECTS = \ $(OBJS)\corelib_uxtheme.obj \ $(OBJS)\corelib_window.obj \ $(OBJS)\corelib_graphicsd2d.obj \ + $(OBJS)\corelib_utilsrt.obj \ $(OBJS)\corelib_helpchm.obj \ $(OBJS)\corelib_helpwin.obj \ $(OBJS)\corelib_automtn.obj \ @@ -7764,6 +7772,11 @@ $(OBJS)\monodll_graphicsd2d.obj: ..\..\src\msw\graphicsd2d.cpp $(CXX) -q -c -P -o$@ $(MONODLL_CXXFLAGS) ..\..\src\msw\graphicsd2d.cpp !endif +!if "$(USE_GUI)" == "1" +$(OBJS)\monodll_utilsrt.obj: ..\..\src\msw\rt\utilsrt.cpp + $(CXX) -q -c -P -o$@ $(MONODLL_CXXFLAGS) ..\..\src\msw\rt\utilsrt.cpp +!endif + !if "$(USE_GUI)" == "1" $(OBJS)\monodll_helpchm.obj: ..\..\src\msw\helpchm.cpp $(CXX) -q -c -P -o$@ $(MONODLL_CXXFLAGS) ..\..\src\msw\helpchm.cpp @@ -10279,6 +10292,11 @@ $(OBJS)\monolib_graphicsd2d.obj: ..\..\src\msw\graphicsd2d.cpp $(CXX) -q -c -P -o$@ $(MONOLIB_CXXFLAGS) ..\..\src\msw\graphicsd2d.cpp !endif +!if "$(USE_GUI)" == "1" +$(OBJS)\monolib_utilsrt.obj: ..\..\src\msw\rt\utilsrt.cpp + $(CXX) -q -c -P -o$@ $(MONOLIB_CXXFLAGS) ..\..\src\msw\rt\utilsrt.cpp +!endif + !if "$(USE_GUI)" == "1" $(OBJS)\monolib_helpchm.obj: ..\..\src\msw\helpchm.cpp $(CXX) -q -c -P -o$@ $(MONOLIB_CXXFLAGS) ..\..\src\msw\helpchm.cpp @@ -12728,6 +12746,11 @@ $(OBJS)\coredll_graphicsd2d.obj: ..\..\src\msw\graphicsd2d.cpp $(CXX) -q -c -P -o$@ $(COREDLL_CXXFLAGS) ..\..\src\msw\graphicsd2d.cpp !endif +!if "$(USE_GUI)" == "1" +$(OBJS)\coredll_utilsrt.obj: ..\..\src\msw\rt\utilsrt.cpp + $(CXX) -q -c -P -o$@ $(COREDLL_CXXFLAGS) ..\..\src\msw\rt\utilsrt.cpp +!endif + !if "$(USE_GUI)" == "1" $(OBJS)\coredll_helpchm.obj: ..\..\src\msw\helpchm.cpp $(CXX) -q -c -P -o$@ $(COREDLL_CXXFLAGS) ..\..\src\msw\helpchm.cpp @@ -14197,6 +14220,11 @@ $(OBJS)\corelib_graphicsd2d.obj: ..\..\src\msw\graphicsd2d.cpp $(CXX) -q -c -P -o$@ $(CORELIB_CXXFLAGS) ..\..\src\msw\graphicsd2d.cpp !endif +!if "$(USE_GUI)" == "1" +$(OBJS)\corelib_utilsrt.obj: ..\..\src\msw\rt\utilsrt.cpp + $(CXX) -q -c -P -o$@ $(CORELIB_CXXFLAGS) ..\..\src\msw\rt\utilsrt.cpp +!endif + !if "$(USE_GUI)" == "1" $(OBJS)\corelib_helpchm.obj: ..\..\src\msw\helpchm.cpp $(CXX) -q -c -P -o$@ $(CORELIB_CXXFLAGS) ..\..\src\msw\helpchm.cpp diff --git a/build/msw/makefile.gcc b/build/msw/makefile.gcc index 969609d25e..406c7352fe 100644 --- a/build/msw/makefile.gcc +++ b/build/msw/makefile.gcc @@ -1843,6 +1843,7 @@ ____CORE_SRC_FILENAMES_OBJECTS = \ $(OBJS)\monodll_uxtheme.o \ $(OBJS)\monodll_window.o \ $(OBJS)\monodll_graphicsd2d.o \ + $(OBJS)\monodll_utilsrt.o \ $(OBJS)\monodll_helpchm.o \ $(OBJS)\monodll_helpwin.o \ $(OBJS)\monodll_automtn.o \ @@ -2131,6 +2132,7 @@ ____CORE_SRC_FILENAMES_OBJECTS = \ $(OBJS)\monodll_uxtheme.o \ $(OBJS)\monodll_window.o \ $(OBJS)\monodll_graphicsd2d.o \ + $(OBJS)\monodll_utilsrt.o \ $(OBJS)\monodll_helpchm.o \ $(OBJS)\monodll_helpwin.o \ $(OBJS)\monodll_automtn.o \ @@ -2673,6 +2675,7 @@ ____CORE_SRC_FILENAMES_1_OBJECTS = \ $(OBJS)\monolib_uxtheme.o \ $(OBJS)\monolib_window.o \ $(OBJS)\monolib_graphicsd2d.o \ + $(OBJS)\monolib_utilsrt.o \ $(OBJS)\monolib_helpchm.o \ $(OBJS)\monolib_helpwin.o \ $(OBJS)\monolib_automtn.o \ @@ -2961,6 +2964,7 @@ ____CORE_SRC_FILENAMES_1_OBJECTS = \ $(OBJS)\monolib_uxtheme.o \ $(OBJS)\monolib_window.o \ $(OBJS)\monolib_graphicsd2d.o \ + $(OBJS)\monolib_utilsrt.o \ $(OBJS)\monolib_helpchm.o \ $(OBJS)\monolib_helpwin.o \ $(OBJS)\monolib_automtn.o \ @@ -3386,6 +3390,7 @@ ____CORE_SRC_FILENAMES_2_OBJECTS = \ $(OBJS)\coredll_uxtheme.o \ $(OBJS)\coredll_window.o \ $(OBJS)\coredll_graphicsd2d.o \ + $(OBJS)\coredll_utilsrt.o \ $(OBJS)\coredll_helpchm.o \ $(OBJS)\coredll_helpwin.o \ $(OBJS)\coredll_automtn.o \ @@ -3674,6 +3679,7 @@ ____CORE_SRC_FILENAMES_2_OBJECTS = \ $(OBJS)\coredll_uxtheme.o \ $(OBJS)\coredll_window.o \ $(OBJS)\coredll_graphicsd2d.o \ + $(OBJS)\coredll_utilsrt.o \ $(OBJS)\coredll_helpchm.o \ $(OBJS)\coredll_helpwin.o \ $(OBJS)\coredll_automtn.o \ @@ -3962,6 +3968,7 @@ ____CORE_SRC_FILENAMES_3_OBJECTS = \ $(OBJS)\corelib_uxtheme.o \ $(OBJS)\corelib_window.o \ $(OBJS)\corelib_graphicsd2d.o \ + $(OBJS)\corelib_utilsrt.o \ $(OBJS)\corelib_helpchm.o \ $(OBJS)\corelib_helpwin.o \ $(OBJS)\corelib_automtn.o \ @@ -4250,6 +4257,7 @@ ____CORE_SRC_FILENAMES_3_OBJECTS = \ $(OBJS)\corelib_uxtheme.o \ $(OBJS)\corelib_window.o \ $(OBJS)\corelib_graphicsd2d.o \ + $(OBJS)\corelib_utilsrt.o \ $(OBJS)\corelib_helpchm.o \ $(OBJS)\corelib_helpwin.o \ $(OBJS)\corelib_automtn.o \ @@ -7939,6 +7947,11 @@ $(OBJS)\monodll_graphicsd2d.o: ../../src/msw/graphicsd2d.cpp $(CXX) -c -o $@ $(MONODLL_CXXFLAGS) $(CPPDEPS) $< endif +ifeq ($(USE_GUI),1) +$(OBJS)\monodll_utilsrt.o: ../../src/msw/rt/utilsrt.cpp + $(CXX) -c -o $@ $(MONODLL_CXXFLAGS) $(CPPDEPS) $< +endif + ifeq ($(USE_GUI),1) $(OBJS)\monodll_helpchm.o: ../../src/msw/helpchm.cpp $(CXX) -c -o $@ $(MONODLL_CXXFLAGS) $(CPPDEPS) $< @@ -10454,6 +10467,11 @@ $(OBJS)\monolib_graphicsd2d.o: ../../src/msw/graphicsd2d.cpp $(CXX) -c -o $@ $(MONOLIB_CXXFLAGS) $(CPPDEPS) $< endif +ifeq ($(USE_GUI),1) +$(OBJS)\monolib_utilsrt.o: ../../src/msw/rt/utilsrt.cpp + $(CXX) -c -o $@ $(MONOLIB_CXXFLAGS) $(CPPDEPS) $< +endif + ifeq ($(USE_GUI),1) $(OBJS)\monolib_helpchm.o: ../../src/msw/helpchm.cpp $(CXX) -c -o $@ $(MONOLIB_CXXFLAGS) $(CPPDEPS) $< @@ -12903,6 +12921,11 @@ $(OBJS)\coredll_graphicsd2d.o: ../../src/msw/graphicsd2d.cpp $(CXX) -c -o $@ $(COREDLL_CXXFLAGS) $(CPPDEPS) $< endif +ifeq ($(USE_GUI),1) +$(OBJS)\coredll_utilsrt.o: ../../src/msw/rt/utilsrt.cpp + $(CXX) -c -o $@ $(COREDLL_CXXFLAGS) $(CPPDEPS) $< +endif + ifeq ($(USE_GUI),1) $(OBJS)\coredll_helpchm.o: ../../src/msw/helpchm.cpp $(CXX) -c -o $@ $(COREDLL_CXXFLAGS) $(CPPDEPS) $< @@ -14372,6 +14395,11 @@ $(OBJS)\corelib_graphicsd2d.o: ../../src/msw/graphicsd2d.cpp $(CXX) -c -o $@ $(CORELIB_CXXFLAGS) $(CPPDEPS) $< endif +ifeq ($(USE_GUI),1) +$(OBJS)\corelib_utilsrt.o: ../../src/msw/rt/utilsrt.cpp + $(CXX) -c -o $@ $(CORELIB_CXXFLAGS) $(CPPDEPS) $< +endif + ifeq ($(USE_GUI),1) $(OBJS)\corelib_helpchm.o: ../../src/msw/helpchm.cpp $(CXX) -c -o $@ $(CORELIB_CXXFLAGS) $(CPPDEPS) $< diff --git a/build/msw/makefile.vc b/build/msw/makefile.vc index 422eea6e50..a57adf3fd8 100644 --- a/build/msw/makefile.vc +++ b/build/msw/makefile.vc @@ -2124,6 +2124,7 @@ ____CORE_SRC_FILENAMES_OBJECTS = \ $(OBJS)\monodll_uxtheme.obj \ $(OBJS)\monodll_window.obj \ $(OBJS)\monodll_graphicsd2d.obj \ + $(OBJS)\monodll_utilsrt.obj \ $(OBJS)\monodll_helpchm.obj \ $(OBJS)\monodll_helpwin.obj \ $(OBJS)\monodll_automtn.obj \ @@ -2410,6 +2411,7 @@ ____CORE_SRC_FILENAMES_OBJECTS = \ $(OBJS)\monodll_uxtheme.obj \ $(OBJS)\monodll_window.obj \ $(OBJS)\monodll_graphicsd2d.obj \ + $(OBJS)\monodll_utilsrt.obj \ $(OBJS)\monodll_helpchm.obj \ $(OBJS)\monodll_helpwin.obj \ $(OBJS)\monodll_automtn.obj \ @@ -2954,6 +2956,7 @@ ____CORE_SRC_FILENAMES_1_OBJECTS = \ $(OBJS)\monolib_uxtheme.obj \ $(OBJS)\monolib_window.obj \ $(OBJS)\monolib_graphicsd2d.obj \ + $(OBJS)\monolib_utilsrt.obj \ $(OBJS)\monolib_helpchm.obj \ $(OBJS)\monolib_helpwin.obj \ $(OBJS)\monolib_automtn.obj \ @@ -3240,6 +3243,7 @@ ____CORE_SRC_FILENAMES_1_OBJECTS = \ $(OBJS)\monolib_uxtheme.obj \ $(OBJS)\monolib_window.obj \ $(OBJS)\monolib_graphicsd2d.obj \ + $(OBJS)\monolib_utilsrt.obj \ $(OBJS)\monolib_helpchm.obj \ $(OBJS)\monolib_helpwin.obj \ $(OBJS)\monolib_automtn.obj \ @@ -3717,6 +3721,7 @@ ____CORE_SRC_FILENAMES_2_OBJECTS = \ $(OBJS)\coredll_uxtheme.obj \ $(OBJS)\coredll_window.obj \ $(OBJS)\coredll_graphicsd2d.obj \ + $(OBJS)\coredll_utilsrt.obj \ $(OBJS)\coredll_helpchm.obj \ $(OBJS)\coredll_helpwin.obj \ $(OBJS)\coredll_automtn.obj \ @@ -4003,6 +4008,7 @@ ____CORE_SRC_FILENAMES_2_OBJECTS = \ $(OBJS)\coredll_uxtheme.obj \ $(OBJS)\coredll_window.obj \ $(OBJS)\coredll_graphicsd2d.obj \ + $(OBJS)\coredll_utilsrt.obj \ $(OBJS)\coredll_helpchm.obj \ $(OBJS)\coredll_helpwin.obj \ $(OBJS)\coredll_automtn.obj \ @@ -4291,6 +4297,7 @@ ____CORE_SRC_FILENAMES_3_OBJECTS = \ $(OBJS)\corelib_uxtheme.obj \ $(OBJS)\corelib_window.obj \ $(OBJS)\corelib_graphicsd2d.obj \ + $(OBJS)\corelib_utilsrt.obj \ $(OBJS)\corelib_helpchm.obj \ $(OBJS)\corelib_helpwin.obj \ $(OBJS)\corelib_automtn.obj \ @@ -4577,6 +4584,7 @@ ____CORE_SRC_FILENAMES_3_OBJECTS = \ $(OBJS)\corelib_uxtheme.obj \ $(OBJS)\corelib_window.obj \ $(OBJS)\corelib_graphicsd2d.obj \ + $(OBJS)\corelib_utilsrt.obj \ $(OBJS)\corelib_helpchm.obj \ $(OBJS)\corelib_helpwin.obj \ $(OBJS)\corelib_automtn.obj \ @@ -8456,6 +8464,11 @@ $(OBJS)\monodll_graphicsd2d.obj: ..\..\src\msw\graphicsd2d.cpp $(CXX) /c /nologo /TP /Fo$@ $(MONODLL_CXXFLAGS) ..\..\src\msw\graphicsd2d.cpp !endif +!if "$(USE_GUI)" == "1" +$(OBJS)\monodll_utilsrt.obj: ..\..\src\msw\rt\utilsrt.cpp + $(CXX) /c /nologo /TP /Fo$@ $(MONODLL_CXXFLAGS) ..\..\src\msw\rt\utilsrt.cpp +!endif + !if "$(USE_GUI)" == "1" $(OBJS)\monodll_helpchm.obj: ..\..\src\msw\helpchm.cpp $(CXX) /c /nologo /TP /Fo$@ $(MONODLL_CXXFLAGS) ..\..\src\msw\helpchm.cpp @@ -10971,6 +10984,11 @@ $(OBJS)\monolib_graphicsd2d.obj: ..\..\src\msw\graphicsd2d.cpp $(CXX) /c /nologo /TP /Fo$@ $(MONOLIB_CXXFLAGS) ..\..\src\msw\graphicsd2d.cpp !endif +!if "$(USE_GUI)" == "1" +$(OBJS)\monolib_utilsrt.obj: ..\..\src\msw\rt\utilsrt.cpp + $(CXX) /c /nologo /TP /Fo$@ $(MONOLIB_CXXFLAGS) ..\..\src\msw\rt\utilsrt.cpp +!endif + !if "$(USE_GUI)" == "1" $(OBJS)\monolib_helpchm.obj: ..\..\src\msw\helpchm.cpp $(CXX) /c /nologo /TP /Fo$@ $(MONOLIB_CXXFLAGS) ..\..\src\msw\helpchm.cpp @@ -13420,6 +13438,11 @@ $(OBJS)\coredll_graphicsd2d.obj: ..\..\src\msw\graphicsd2d.cpp $(CXX) /c /nologo /TP /Fo$@ $(COREDLL_CXXFLAGS) ..\..\src\msw\graphicsd2d.cpp !endif +!if "$(USE_GUI)" == "1" +$(OBJS)\coredll_utilsrt.obj: ..\..\src\msw\rt\utilsrt.cpp + $(CXX) /c /nologo /TP /Fo$@ $(COREDLL_CXXFLAGS) ..\..\src\msw\rt\utilsrt.cpp +!endif + !if "$(USE_GUI)" == "1" $(OBJS)\coredll_helpchm.obj: ..\..\src\msw\helpchm.cpp $(CXX) /c /nologo /TP /Fo$@ $(COREDLL_CXXFLAGS) ..\..\src\msw\helpchm.cpp @@ -14889,6 +14912,11 @@ $(OBJS)\corelib_graphicsd2d.obj: ..\..\src\msw\graphicsd2d.cpp $(CXX) /c /nologo /TP /Fo$@ $(CORELIB_CXXFLAGS) ..\..\src\msw\graphicsd2d.cpp !endif +!if "$(USE_GUI)" == "1" +$(OBJS)\corelib_utilsrt.obj: ..\..\src\msw\rt\utilsrt.cpp + $(CXX) /c /nologo /TP /Fo$@ $(CORELIB_CXXFLAGS) ..\..\src\msw\rt\utilsrt.cpp +!endif + !if "$(USE_GUI)" == "1" $(OBJS)\corelib_helpchm.obj: ..\..\src\msw\helpchm.cpp $(CXX) /c /nologo /TP /Fo$@ $(CORELIB_CXXFLAGS) ..\..\src\msw\helpchm.cpp diff --git a/build/msw/wx_core.vcxproj b/build/msw/wx_core.vcxproj index e2a32a8e80..425d1e1845 100644 --- a/build/msw/wx_core.vcxproj +++ b/build/msw/wx_core.vcxproj @@ -1,4 +1,4 @@ - + @@ -1006,6 +1006,7 @@ + @@ -1377,6 +1378,7 @@ + diff --git a/build/msw/wx_core.vcxproj.filters b/build/msw/wx_core.vcxproj.filters index 6b958042db..39e16aeb8f 100644 --- a/build/msw/wx_core.vcxproj.filters +++ b/build/msw/wx_core.vcxproj.filters @@ -813,6 +813,9 @@ MSW Sources + + MSW Sources + MSW Sources @@ -1606,6 +1609,9 @@ MSW Headers + + MSW Headers + MSW Headers diff --git a/build/msw/wx_vc7_core.vcproj b/build/msw/wx_vc7_core.vcproj index 9d26e38ba0..526a04a75a 100644 --- a/build/msw/wx_vc7_core.vcproj +++ b/build/msw/wx_vc7_core.vcproj @@ -1051,6 +1051,9 @@ + + + + + + + + + + + + = 1700 + #define wxUSE_WINRT 1 +#else + #define wxUSE_WINRT 0 +#endif + // wxDC caching implementation #define wxUSE_DC_CACHEING 1 diff --git a/include/wx/msw/chkconf.h b/include/wx/msw/chkconf.h index f3d0b0f8ea..656ef98017 100644 --- a/include/wx/msw/chkconf.h +++ b/include/wx/msw/chkconf.h @@ -22,6 +22,14 @@ # endif #endif /* !defined(wxUSE_ACTIVEX) */ +#ifndef wxUSE_WINRT +# ifdef wxABORT_ON_CONFIG_ERROR +# error "wxUSE_WINRT must be defined." +# else +# define wxUSE_WINRT 0 +# endif +#endif /* !defined(wxUSE_ACTIVEX) */ + #ifndef wxUSE_CRASHREPORT # ifdef wxABORT_ON_CONFIG_ERROR # error "wxUSE_CRASHREPORT must be defined." diff --git a/include/wx/msw/rt/utils.h b/include/wx/msw/rt/utils.h new file mode 100644 index 0000000000..b315531090 --- /dev/null +++ b/include/wx/msw/rt/utils.h @@ -0,0 +1,84 @@ +/////////////////////////////////////////////////////////////////////////////// +// Name: wx/msw/rt/utils.h +// Purpose: Windows Runtime Objects helper functions and objects +// Author: Tobias Taschner +// Created: 2015-09-05 +// Copyright: (c) 2015 wxWidgets development team +// Licence: wxWindows licence +/////////////////////////////////////////////////////////////////////////////// + +#ifndef _WX_MSW_RTUTILS_H +#define _WX_MSW_RTUTILS_H + +#include "wx/defs.h" + +#if wxUSE_WINRT + +#include "wx/string.h" +#include "wx/msw/wrapwin.h" + +#include + +namespace wxWinRT +{ + +bool WXDLLIMPEXP_CORE IsAvailable(); + +bool WXDLLIMPEXP_CORE Initialize(); + +void WXDLLIMPEXP_CORE Uninitialize(); + +bool WXDLLIMPEXP_CORE GetActivationFactory(const wxString& activatableClassId, REFIID iid, void ** factory); + +// RAII class initializing WinRT in its ctor and undoing it in its dtor. +class WXDLLIMPEXP_CORE Initializer +{ +public: + Initializer() + : m_ok(Initialize()) + { + } + + bool IsOk() const + { + return m_ok; + } + + ~Initializer() + { + if (m_ok) + Uninitialize(); + } + +private: + const bool m_ok; + + wxDECLARE_NO_COPY_CLASS(Initializer); +}; + +// Simple class to convert wxString to HSTRING +// This just wraps a reference to the wxString object, +// which needs a life time greater than the TempStringRef object +class WXDLLIMPEXP_CORE TempStringRef +{ +public: + HSTRING Get() const { return m_hstring; } + + operator HSTRING() const { return m_hstring; }; + + static const TempStringRef Make(const wxString &str); + +private: + TempStringRef(const wxString &str); + + HSTRING m_hstring; + HSTRING_HEADER m_header; + + wxDECLARE_NO_COPY_CLASS(TempStringRef); +}; + +} // namespace wxWinRT + +#endif // wxUSE_WINRT + +#endif // _WX_MSW_RTUTILS_H diff --git a/include/wx/msw/setup0.h b/include/wx/msw/setup0.h index f0c15456d5..d005bc3580 100644 --- a/include/wx/msw/setup0.h +++ b/include/wx/msw/setup0.h @@ -1553,6 +1553,19 @@ // Recommended setting: 1, required by wxMediaCtrl #define wxUSE_ACTIVEX 1 +// Enable WinRT support +// +// Default is 1 for compilers which support it, i.e. VS2012+ currently. If you +// use an earlier MSVC version or another compiler and installed the necessary +// SDK components manually, you need to change this setting. +// +// Recommended setting: 1 +#if defined(_MSC_VER) && _MSC_VER >= 1700 + #define wxUSE_WINRT 1 +#else + #define wxUSE_WINRT 0 +#endif + // wxDC caching implementation #define wxUSE_DC_CACHEING 1 diff --git a/include/wx/msw/setup_inc.h b/include/wx/msw/setup_inc.h index 20f2b40945..eb01cbd540 100644 --- a/include/wx/msw/setup_inc.h +++ b/include/wx/msw/setup_inc.h @@ -65,6 +65,19 @@ // Recommended setting: 1, required by wxMediaCtrl #define wxUSE_ACTIVEX 1 +// Enable WinRT support +// +// Default is 1 for compilers which support it, i.e. VS2012+ currently. If you +// use an earlier MSVC version or another compiler and installed the necessary +// SDK components manually, you need to change this setting. +// +// Recommended setting: 1 +#if defined(_MSC_VER) && _MSC_VER >= 1700 + #define wxUSE_WINRT 1 +#else + #define wxUSE_WINRT 0 +#endif + // wxDC caching implementation #define wxUSE_DC_CACHEING 1 diff --git a/setup.h.in b/setup.h.in index 439e42afa4..ee9d346573 100644 --- a/setup.h.in +++ b/setup.h.in @@ -653,6 +653,12 @@ #define wxUSE_ACTIVEX 0 +#if defined(_MSC_VER) && _MSC_VER >= 1700 + #define wxUSE_WINRT 0 +#else + #define wxUSE_WINRT 0 +#endif + #define wxUSE_DC_CACHEING 0 #define wxUSE_WXDIB 0 diff --git a/src/msw/rt/utilsrt.cpp b/src/msw/rt/utilsrt.cpp new file mode 100644 index 0000000000..ecc12be979 --- /dev/null +++ b/src/msw/rt/utilsrt.cpp @@ -0,0 +1,259 @@ +/////////////////////////////////////////////////////////////////////////////// +// Name: src/msw/rt/utilsrt.cpp +// Purpose: Windows Runtime Objects helper functions and objects +// Author: Tobias Taschner +// Created: 2015-09-05 +// Copyright: (c) 2015 wxWidgets development team +// Licence: wxWindows licence +/////////////////////////////////////////////////////////////////////////////// + +// ============================================================================ +// Declarations +// ============================================================================ + +// ---------------------------------------------------------------------------- +// headers +// ---------------------------------------------------------------------------- + +// For compilers that support precompilation, includes "wx.h". +#include "wx/wxprec.h" + +#if defined(__BORLANDC__) +#pragma hdrstop +#endif + +#include "wx/msw/rt/utils.h" + +#if wxUSE_WINRT + +#include + +#include "wx/dynlib.h" +#include "wx/utils.h" +#include "wx/module.h" + +// Core function typedefs +typedef HRESULT (__stdcall *PFNWXROINITIALIZE)(RO_INIT_TYPE initType); +typedef void (__stdcall *PFNWXROUNINITIALIZE)(); +typedef HRESULT (__stdcall *PFNWXROGETACTIVATIONFACTORY)( + HSTRING activatableClassId, REFIID iid, void ** factory); + +// String function typedefs +typedef HRESULT (__stdcall *PFNWXWINDOWSCREATESTRINGREFERENCE)( + PCWSTR sourceString, + UINT32 length, + HSTRING_HEADER * hstringHeader, + HSTRING * string +); +typedef HRESULT (__stdcall *PFNWXWINDOWSDELETESTRING)(HSTRING string); + +namespace wxWinRT +{ + +// +// RTCore +// + +class RTCore +{ +public: + static RTCore& Get() + { + if ( ms_isAvailable == -1 ) + { + if ( !ms_rtcore.Initialize() ) + { + ms_isAvailable = 0; + } + else + ms_isAvailable = 1; + } + + return ms_rtcore; + } + + static bool IsAvailable() + { + if (ms_isAvailable == -1) + Get(); + + return (ms_isAvailable == 1); + } + + PFNWXROINITIALIZE RoInitialize; + PFNWXROUNINITIALIZE RoUninitialize; + PFNWXROGETACTIVATIONFACTORY RoGetActivationFactory; + PFNWXWINDOWSCREATESTRINGREFERENCE WindowsCreateStringReference; + PFNWXWINDOWSDELETESTRING WindowsDeleteString; + + bool Initialize() + { +#define RESOLVE_RT_FUNCTION(dll, type, funcname) \ + funcname = (type)dll.GetSymbol(wxT(#funcname)); \ + if ( !funcname ) \ + return false + +#define RESOLVE_RTCORE_FUNCTION(type, funcname) \ + RESOLVE_RT_FUNCTION(m_dllCore, type, funcname) + +#define RESOLVE_RTSTRING_FUNCTION(type, funcname) \ + RESOLVE_RT_FUNCTION(m_dllString, type, funcname) + + // WinRT is only available in Windows 8 or newer + if (!wxCheckOsVersion(6, 2)) + return false; + + // Initialize core functions + if (!m_dllCore.Load("api-ms-win-core-winrt-l1-1-0.dll")) + return false; + + RESOLVE_RTCORE_FUNCTION(PFNWXROINITIALIZE, RoInitialize); + RESOLVE_RTCORE_FUNCTION(PFNWXROUNINITIALIZE, RoUninitialize); + RESOLVE_RTCORE_FUNCTION(PFNWXROGETACTIVATIONFACTORY, RoGetActivationFactory); + + // Initialize string functions + if (!m_dllString.Load("api-ms-win-core-winrt-string-l1-1-0.dll")) + return false; + + RESOLVE_RTSTRING_FUNCTION(PFNWXWINDOWSCREATESTRINGREFERENCE, WindowsCreateStringReference); + RESOLVE_RTSTRING_FUNCTION(PFNWXWINDOWSDELETESTRING, WindowsDeleteString); + + return true; + +#undef RESOLVE_RT_FUNCTION +#undef RESOLVE_RTCORE_FUNCTION +#undef RESOLVE_RTSTRING_FUNCTION + } + + void UnloadModules() + { + m_dllCore.Unload(); + m_dllString.Unload(); + } + + static void Uninitalize() + { + if (ms_isAvailable == 1) + { + Get().UnloadModules(); + ms_isAvailable = -1; + } + } + +private: + RTCore() + { + + } + + wxDynamicLibrary m_dllCore; + wxDynamicLibrary m_dllString; + + static RTCore ms_rtcore; + static int ms_isAvailable; + + wxDECLARE_NO_COPY_CLASS(RTCore); +}; + +RTCore RTCore::ms_rtcore; +int RTCore::ms_isAvailable = -1; + +// +// wxWinRT::TempStringRef +// + +const TempStringRef TempStringRef::Make(const wxString &str) +{ + return TempStringRef(str); +} + +TempStringRef::TempStringRef(const wxString &str) +{ + if ( !RTCore::IsAvailable() ) + wxLogDebug("Can not create string reference without WinRT"); + + // This creates a fast-pass string which must not be deleted using WindowsDeleteString + HRESULT hr = RTCore::Get().WindowsCreateStringReference( + str.wc_str(), str.length(), + &m_header, &m_hstring); + if ( FAILED(hr) ) + wxLogDebug("Could not create string reference %.8x", hr); +} + +// +// wrapper functions +// + +bool IsAvailable() +{ + return RTCore::IsAvailable(); +} + +bool Initialize() +{ + if ( !RTCore::IsAvailable() ) + return false; + + HRESULT hr = RTCore::Get().RoInitialize(RO_INIT_SINGLETHREADED); + if ( FAILED(hr) ) + { + wxLogDebug("RoInitialize failed %.8x", hr); + return false; + } + else + return true; +} + +void Uninitialize() +{ + if ( !RTCore::IsAvailable() ) + return; + + RTCore::Get().RoUninitialize(); +} + +bool GetActivationFactory(const wxString& activatableClassId, REFIID iid, void ** factory) +{ + if ( !RTCore::IsAvailable() ) + return false; + + HRESULT hr = RTCore::Get().RoGetActivationFactory(TempStringRef::Make(activatableClassId), iid, factory); + if ( FAILED(hr) ) + { + wxLogDebug("RoGetActivationFactory failed %.8x", hr); + return false; + } + else + return true; +} + +// ---------------------------------------------------------------------------- +// Module ensuring all global/singleton objects are destroyed on shutdown. +// ---------------------------------------------------------------------------- + +class RTModule : public wxModule +{ +public: + RTModule() + { + } + + virtual bool OnInit() wxOVERRIDE + { + return true; + } + + virtual void OnExit() wxOVERRIDE + { + RTCore::Uninitalize(); + } + +private: + wxDECLARE_DYNAMIC_CLASS(RTModule); +}; + +wxIMPLEMENT_DYNAMIC_CLASS(RTModule, wxModule); + +} // namespace wxWinRT + +#endif // wxUSE_WINRT From 9345482fbf04bbbb5bc46a2f98e6fc8a9a00fdb9 Mon Sep 17 00:00:00 2001 From: Tobias Taschner Date: Mon, 14 Sep 2015 20:20:00 +0200 Subject: [PATCH 4/4] Add Win8+ toast notification to wxNotificationMessage. Since Windows 8 there are native toast notifications available via WinRT defined in windows.ui.notifications.h. This adds support for these notifications via wxNotificationMessage. These notifications have to be explicitly enabled via wxNotificationMessage::MSWEnableToasts() because they require a start menu shortcut to the application. --- Makefile.in | 20 + build/bakefiles/files.bkl | 1 + build/files | 1 + build/msw/makefile.bcc | 24 ++ build/msw/makefile.gcc | 24 ++ build/msw/makefile.vc | 24 ++ build/msw/wx_adv.vcxproj | 1 + build/msw/wx_adv.vcxproj.filters | 3 + build/msw/wx_vc7_adv.vcproj | 3 + build/msw/wx_vc8_adv.vcproj | 4 + build/msw/wx_vc9_adv.vcproj | 4 + include/wx/msw/rt/private/notifmsg.h | 26 ++ include/wx/notifmsg.h | 7 +- interface/wx/notifmsg.h | 46 ++- samples/dialogs/dialogs.cpp | 8 + src/msw/notifmsg.cpp | 16 +- src/msw/rt/notifmsgrt.cpp | 545 +++++++++++++++++++++++++++ 17 files changed, 752 insertions(+), 5 deletions(-) create mode 100644 include/wx/msw/rt/private/notifmsg.h create mode 100644 src/msw/rt/notifmsgrt.cpp diff --git a/Makefile.in b/Makefile.in index e603897022..ba84464de6 100644 --- a/Makefile.in +++ b/Makefile.in @@ -5875,6 +5875,7 @@ COND_TOOLKIT_MSW___ADVANCED_PLATFORM_SRC_OBJECTS = \ monodll_richtooltip.o \ monodll_msw_sound.o \ monodll_msw_taskbar.o \ + monodll_notifmsgrt.o \ monodll_msw_joystick.o @COND_TOOLKIT_MSW@__ADVANCED_PLATFORM_SRC_OBJECTS = $(COND_TOOLKIT_MSW___ADVANCED_PLATFORM_SRC_OBJECTS) COND_TOOLKIT_OSX_COCOA___ADVANCED_PLATFORM_SRC_OBJECTS = \ @@ -5990,6 +5991,7 @@ COND_TOOLKIT_MSW___ADVANCED_PLATFORM_SRC_OBJECTS_1 = \ monodll_richtooltip.o \ monodll_msw_sound.o \ monodll_msw_taskbar.o \ + monodll_notifmsgrt.o \ monodll_msw_joystick.o @COND_TOOLKIT_MSW@__ADVANCED_PLATFORM_SRC_OBJECTS_1 = $(COND_TOOLKIT_MSW___ADVANCED_PLATFORM_SRC_OBJECTS_1) COND_TOOLKIT_OSX_COCOA___ADVANCED_PLATFORM_SRC_OBJECTS_1 = \ @@ -7877,6 +7879,7 @@ COND_TOOLKIT_MSW___ADVANCED_PLATFORM_SRC_OBJECTS_2 = \ monolib_richtooltip.o \ monolib_msw_sound.o \ monolib_msw_taskbar.o \ + monolib_notifmsgrt.o \ monolib_msw_joystick.o @COND_TOOLKIT_MSW@__ADVANCED_PLATFORM_SRC_OBJECTS_2 = $(COND_TOOLKIT_MSW___ADVANCED_PLATFORM_SRC_OBJECTS_2) COND_TOOLKIT_OSX_COCOA___ADVANCED_PLATFORM_SRC_OBJECTS_2 = \ @@ -7992,6 +7995,7 @@ COND_TOOLKIT_MSW___ADVANCED_PLATFORM_SRC_OBJECTS_3 = \ monolib_richtooltip.o \ monolib_msw_sound.o \ monolib_msw_taskbar.o \ + monolib_notifmsgrt.o \ monolib_msw_joystick.o @COND_TOOLKIT_MSW@__ADVANCED_PLATFORM_SRC_OBJECTS_3 = $(COND_TOOLKIT_MSW___ADVANCED_PLATFORM_SRC_OBJECTS_3) COND_TOOLKIT_OSX_COCOA___ADVANCED_PLATFORM_SRC_OBJECTS_3 = \ @@ -11558,6 +11562,7 @@ COND_TOOLKIT_MSW___ADVANCED_PLATFORM_SRC_OBJECTS_4 = \ advdll_richtooltip.o \ advdll_msw_sound.o \ advdll_msw_taskbar.o \ + advdll_notifmsgrt.o \ advdll_msw_joystick.o @COND_TOOLKIT_MSW@__ADVANCED_PLATFORM_SRC_OBJECTS_4 = $(COND_TOOLKIT_MSW___ADVANCED_PLATFORM_SRC_OBJECTS_4) COND_TOOLKIT_OSX_COCOA___ADVANCED_PLATFORM_SRC_OBJECTS_4 = \ @@ -11673,6 +11678,7 @@ COND_TOOLKIT_MSW___ADVANCED_PLATFORM_SRC_OBJECTS_5 = \ advdll_richtooltip.o \ advdll_msw_sound.o \ advdll_msw_taskbar.o \ + advdll_notifmsgrt.o \ advdll_msw_joystick.o @COND_TOOLKIT_MSW@__ADVANCED_PLATFORM_SRC_OBJECTS_5 = $(COND_TOOLKIT_MSW___ADVANCED_PLATFORM_SRC_OBJECTS_5) COND_TOOLKIT_OSX_COCOA___ADVANCED_PLATFORM_SRC_OBJECTS_5 = \ @@ -11854,6 +11860,7 @@ COND_TOOLKIT_MSW___ADVANCED_PLATFORM_SRC_OBJECTS_6 = \ advlib_richtooltip.o \ advlib_msw_sound.o \ advlib_msw_taskbar.o \ + advlib_notifmsgrt.o \ advlib_msw_joystick.o @COND_TOOLKIT_MSW@__ADVANCED_PLATFORM_SRC_OBJECTS_6 = $(COND_TOOLKIT_MSW___ADVANCED_PLATFORM_SRC_OBJECTS_6) COND_TOOLKIT_OSX_COCOA___ADVANCED_PLATFORM_SRC_OBJECTS_6 = \ @@ -11969,6 +11976,7 @@ COND_TOOLKIT_MSW___ADVANCED_PLATFORM_SRC_OBJECTS_7 = \ advlib_richtooltip.o \ advlib_msw_sound.o \ advlib_msw_taskbar.o \ + advlib_notifmsgrt.o \ advlib_msw_joystick.o @COND_TOOLKIT_MSW@__ADVANCED_PLATFORM_SRC_OBJECTS_7 = $(COND_TOOLKIT_MSW___ADVANCED_PLATFORM_SRC_OBJECTS_7) COND_TOOLKIT_OSX_COCOA___ADVANCED_PLATFORM_SRC_OBJECTS_7 = \ @@ -20028,6 +20036,9 @@ monodll_sound_sdl.o: $(srcdir)/src/unix/sound_sdl.cpp $(MONODLL_ODEP) @COND_TOOLKIT_MSW_USE_GUI_1@monodll_msw_taskbar.o: $(srcdir)/src/msw/taskbar.cpp $(MONODLL_ODEP) @COND_TOOLKIT_MSW_USE_GUI_1@ $(CXXC) -c -o $@ $(MONODLL_CXXFLAGS) $(srcdir)/src/msw/taskbar.cpp +@COND_TOOLKIT_MSW_USE_GUI_1@monodll_notifmsgrt.o: $(srcdir)/src/msw/rt/notifmsgrt.cpp $(MONODLL_ODEP) +@COND_TOOLKIT_MSW_USE_GUI_1@ $(CXXC) -c -o $@ $(MONODLL_CXXFLAGS) $(srcdir)/src/msw/rt/notifmsgrt.cpp + @COND_TOOLKIT_MSW_USE_GUI_1@monodll_msw_joystick.o: $(srcdir)/src/msw/joystick.cpp $(MONODLL_ODEP) @COND_TOOLKIT_MSW_USE_GUI_1@ $(CXXC) -c -o $@ $(MONODLL_CXXFLAGS) $(srcdir)/src/msw/joystick.cpp @@ -24840,6 +24851,9 @@ monolib_sound_sdl.o: $(srcdir)/src/unix/sound_sdl.cpp $(MONOLIB_ODEP) @COND_TOOLKIT_MSW_USE_GUI_1@monolib_msw_taskbar.o: $(srcdir)/src/msw/taskbar.cpp $(MONOLIB_ODEP) @COND_TOOLKIT_MSW_USE_GUI_1@ $(CXXC) -c -o $@ $(MONOLIB_CXXFLAGS) $(srcdir)/src/msw/taskbar.cpp +@COND_TOOLKIT_MSW_USE_GUI_1@monolib_notifmsgrt.o: $(srcdir)/src/msw/rt/notifmsgrt.cpp $(MONOLIB_ODEP) +@COND_TOOLKIT_MSW_USE_GUI_1@ $(CXXC) -c -o $@ $(MONOLIB_CXXFLAGS) $(srcdir)/src/msw/rt/notifmsgrt.cpp + @COND_TOOLKIT_MSW_USE_GUI_1@monolib_msw_joystick.o: $(srcdir)/src/msw/joystick.cpp $(MONOLIB_ODEP) @COND_TOOLKIT_MSW_USE_GUI_1@ $(CXXC) -c -o $@ $(MONOLIB_CXXFLAGS) $(srcdir)/src/msw/joystick.cpp @@ -33123,6 +33137,9 @@ advdll_notifmsgcmn.o: $(srcdir)/src/common/notifmsgcmn.cpp $(ADVDLL_ODEP) @COND_TOOLKIT_MSW@advdll_msw_taskbar.o: $(srcdir)/src/msw/taskbar.cpp $(ADVDLL_ODEP) @COND_TOOLKIT_MSW@ $(CXXC) -c -o $@ $(ADVDLL_CXXFLAGS) $(srcdir)/src/msw/taskbar.cpp +@COND_TOOLKIT_MSW@advdll_notifmsgrt.o: $(srcdir)/src/msw/rt/notifmsgrt.cpp $(ADVDLL_ODEP) +@COND_TOOLKIT_MSW@ $(CXXC) -c -o $@ $(ADVDLL_CXXFLAGS) $(srcdir)/src/msw/rt/notifmsgrt.cpp + @COND_TOOLKIT_MSW@advdll_msw_joystick.o: $(srcdir)/src/msw/joystick.cpp $(ADVDLL_ODEP) @COND_TOOLKIT_MSW@ $(CXXC) -c -o $@ $(ADVDLL_CXXFLAGS) $(srcdir)/src/msw/joystick.cpp @@ -33570,6 +33587,9 @@ advlib_notifmsgcmn.o: $(srcdir)/src/common/notifmsgcmn.cpp $(ADVLIB_ODEP) @COND_TOOLKIT_MSW@advlib_msw_taskbar.o: $(srcdir)/src/msw/taskbar.cpp $(ADVLIB_ODEP) @COND_TOOLKIT_MSW@ $(CXXC) -c -o $@ $(ADVLIB_CXXFLAGS) $(srcdir)/src/msw/taskbar.cpp +@COND_TOOLKIT_MSW@advlib_notifmsgrt.o: $(srcdir)/src/msw/rt/notifmsgrt.cpp $(ADVLIB_ODEP) +@COND_TOOLKIT_MSW@ $(CXXC) -c -o $@ $(ADVLIB_CXXFLAGS) $(srcdir)/src/msw/rt/notifmsgrt.cpp + @COND_TOOLKIT_MSW@advlib_msw_joystick.o: $(srcdir)/src/msw/joystick.cpp $(ADVLIB_ODEP) @COND_TOOLKIT_MSW@ $(CXXC) -c -o $@ $(ADVLIB_CXXFLAGS) $(srcdir)/src/msw/joystick.cpp diff --git a/build/bakefiles/files.bkl b/build/bakefiles/files.bkl index 60c45487eb..f235d75d8d 100644 --- a/build/bakefiles/files.bkl +++ b/build/bakefiles/files.bkl @@ -2729,6 +2729,7 @@ IMPORTANT: please read docs/tech/tn0016.txt before modifying this file! src/msw/richtooltip.cpp src/msw/sound.cpp src/msw/taskbar.cpp + src/msw/rt/notifmsgrt.cpp wx/msw/sound.h diff --git a/build/files b/build/files index 8de7b237de..95dee5e985 100644 --- a/build/files +++ b/build/files @@ -2341,6 +2341,7 @@ ADVANCED_MSW_SRC = src/common/taskbarcmn.cpp src/msw/aboutdlg.cpp src/msw/notifmsg.cpp + src/msw/rt/notifmsgrt.cpp src/msw/richtooltip.cpp src/msw/sound.cpp src/msw/taskbar.cpp diff --git a/build/msw/makefile.bcc b/build/msw/makefile.bcc index b991f9722e..0b9b686c37 100644 --- a/build/msw/makefile.bcc +++ b/build/msw/makefile.bcc @@ -2380,6 +2380,7 @@ ____ADVANCED_SRC_FILENAMES_OBJECTS = \ $(OBJS)\monodll_richtooltip.obj \ $(OBJS)\monodll_sound.obj \ $(OBJS)\monodll_taskbar.obj \ + $(OBJS)\monodll_notifmsgrt.obj \ $(OBJS)\monodll_joystick.obj \ $(OBJS)\monodll_animateg.obj \ $(OBJS)\monodll_bmpcbox.obj \ @@ -2435,6 +2436,7 @@ ____ADVANCED_SRC_FILENAMES_OBJECTS = \ $(OBJS)\monodll_richtooltip.obj \ $(OBJS)\monodll_sound.obj \ $(OBJS)\monodll_taskbar.obj \ + $(OBJS)\monodll_notifmsgrt.obj \ $(OBJS)\monodll_joystick.obj \ $(OBJS)\monodll_animateg.obj !endif @@ -3206,6 +3208,7 @@ ____ADVANCED_SRC_FILENAMES_1_OBJECTS = \ $(OBJS)\monolib_richtooltip.obj \ $(OBJS)\monolib_sound.obj \ $(OBJS)\monolib_taskbar.obj \ + $(OBJS)\monolib_notifmsgrt.obj \ $(OBJS)\monolib_joystick.obj \ $(OBJS)\monolib_animateg.obj \ $(OBJS)\monolib_bmpcbox.obj \ @@ -3261,6 +3264,7 @@ ____ADVANCED_SRC_FILENAMES_1_OBJECTS = \ $(OBJS)\monolib_richtooltip.obj \ $(OBJS)\monolib_sound.obj \ $(OBJS)\monolib_taskbar.obj \ + $(OBJS)\monolib_notifmsgrt.obj \ $(OBJS)\monolib_joystick.obj \ $(OBJS)\monolib_animateg.obj !endif @@ -4485,6 +4489,7 @@ ____ADVANCED_SRC_FILENAMES_2_OBJECTS = \ $(OBJS)\advdll_richtooltip.obj \ $(OBJS)\advdll_sound.obj \ $(OBJS)\advdll_taskbar.obj \ + $(OBJS)\advdll_notifmsgrt.obj \ $(OBJS)\advdll_joystick.obj \ $(OBJS)\advdll_animateg.obj \ $(OBJS)\advdll_bmpcbox.obj \ @@ -4540,6 +4545,7 @@ ____ADVANCED_SRC_FILENAMES_2_OBJECTS = \ $(OBJS)\advdll_richtooltip.obj \ $(OBJS)\advdll_sound.obj \ $(OBJS)\advdll_taskbar.obj \ + $(OBJS)\advdll_notifmsgrt.obj \ $(OBJS)\advdll_joystick.obj \ $(OBJS)\advdll_animateg.obj !endif @@ -4590,6 +4596,7 @@ ____ADVANCED_SRC_FILENAMES_3_OBJECTS = \ $(OBJS)\advlib_richtooltip.obj \ $(OBJS)\advlib_sound.obj \ $(OBJS)\advlib_taskbar.obj \ + $(OBJS)\advlib_notifmsgrt.obj \ $(OBJS)\advlib_joystick.obj \ $(OBJS)\advlib_animateg.obj \ $(OBJS)\advlib_bmpcbox.obj \ @@ -4645,6 +4652,7 @@ ____ADVANCED_SRC_FILENAMES_3_OBJECTS = \ $(OBJS)\advlib_richtooltip.obj \ $(OBJS)\advlib_sound.obj \ $(OBJS)\advlib_taskbar.obj \ + $(OBJS)\advlib_notifmsgrt.obj \ $(OBJS)\advlib_joystick.obj \ $(OBJS)\advlib_animateg.obj !endif @@ -8857,6 +8865,11 @@ $(OBJS)\monodll_taskbar.obj: ..\..\src\msw\taskbar.cpp $(CXX) -q -c -P -o$@ $(MONODLL_CXXFLAGS) ..\..\src\msw\taskbar.cpp !endif +!if "$(USE_GUI)" == "1" +$(OBJS)\monodll_notifmsgrt.obj: ..\..\src\msw\rt\notifmsgrt.cpp + $(CXX) -q -c -P -o$@ $(MONODLL_CXXFLAGS) ..\..\src\msw\rt\notifmsgrt.cpp +!endif + !if "$(USE_GUI)" == "1" $(OBJS)\monodll_joystick.obj: ..\..\src\msw\joystick.cpp $(CXX) -q -c -P -o$@ $(MONODLL_CXXFLAGS) ..\..\src\msw\joystick.cpp @@ -11377,6 +11390,11 @@ $(OBJS)\monolib_taskbar.obj: ..\..\src\msw\taskbar.cpp $(CXX) -q -c -P -o$@ $(MONOLIB_CXXFLAGS) ..\..\src\msw\taskbar.cpp !endif +!if "$(USE_GUI)" == "1" +$(OBJS)\monolib_notifmsgrt.obj: ..\..\src\msw\rt\notifmsgrt.cpp + $(CXX) -q -c -P -o$@ $(MONOLIB_CXXFLAGS) ..\..\src\msw\rt\notifmsgrt.cpp +!endif + !if "$(USE_GUI)" == "1" $(OBJS)\monolib_joystick.obj: ..\..\src\msw\joystick.cpp $(CXX) -q -c -P -o$@ $(MONOLIB_CXXFLAGS) ..\..\src\msw\joystick.cpp @@ -15256,6 +15274,9 @@ $(OBJS)\advdll_sound.obj: ..\..\src\msw\sound.cpp $(OBJS)\advdll_taskbar.obj: ..\..\src\msw\taskbar.cpp $(CXX) -q -c -P -o$@ $(ADVDLL_CXXFLAGS) ..\..\src\msw\taskbar.cpp +$(OBJS)\advdll_notifmsgrt.obj: ..\..\src\msw\rt\notifmsgrt.cpp + $(CXX) -q -c -P -o$@ $(ADVDLL_CXXFLAGS) ..\..\src\msw\rt\notifmsgrt.cpp + $(OBJS)\advdll_joystick.obj: ..\..\src\msw\joystick.cpp $(CXX) -q -c -P -o$@ $(ADVDLL_CXXFLAGS) ..\..\src\msw\joystick.cpp @@ -15415,6 +15436,9 @@ $(OBJS)\advlib_sound.obj: ..\..\src\msw\sound.cpp $(OBJS)\advlib_taskbar.obj: ..\..\src\msw\taskbar.cpp $(CXX) -q -c -P -o$@ $(ADVLIB_CXXFLAGS) ..\..\src\msw\taskbar.cpp +$(OBJS)\advlib_notifmsgrt.obj: ..\..\src\msw\rt\notifmsgrt.cpp + $(CXX) -q -c -P -o$@ $(ADVLIB_CXXFLAGS) ..\..\src\msw\rt\notifmsgrt.cpp + $(OBJS)\advlib_joystick.obj: ..\..\src\msw\joystick.cpp $(CXX) -q -c -P -o$@ $(ADVLIB_CXXFLAGS) ..\..\src\msw\joystick.cpp diff --git a/build/msw/makefile.gcc b/build/msw/makefile.gcc index 406c7352fe..9976728d70 100644 --- a/build/msw/makefile.gcc +++ b/build/msw/makefile.gcc @@ -2402,6 +2402,7 @@ ____ADVANCED_SRC_FILENAMES_OBJECTS = \ $(OBJS)\monodll_richtooltip.o \ $(OBJS)\monodll_sound.o \ $(OBJS)\monodll_taskbar.o \ + $(OBJS)\monodll_notifmsgrt.o \ $(OBJS)\monodll_joystick.o \ $(OBJS)\monodll_animateg.o \ $(OBJS)\monodll_bmpcbox.o \ @@ -2457,6 +2458,7 @@ ____ADVANCED_SRC_FILENAMES_OBJECTS = \ $(OBJS)\monodll_richtooltip.o \ $(OBJS)\monodll_sound.o \ $(OBJS)\monodll_taskbar.o \ + $(OBJS)\monodll_notifmsgrt.o \ $(OBJS)\monodll_joystick.o \ $(OBJS)\monodll_animateg.o endif @@ -3234,6 +3236,7 @@ ____ADVANCED_SRC_FILENAMES_1_OBJECTS = \ $(OBJS)\monolib_richtooltip.o \ $(OBJS)\monolib_sound.o \ $(OBJS)\monolib_taskbar.o \ + $(OBJS)\monolib_notifmsgrt.o \ $(OBJS)\monolib_joystick.o \ $(OBJS)\monolib_animateg.o \ $(OBJS)\monolib_bmpcbox.o \ @@ -3289,6 +3292,7 @@ ____ADVANCED_SRC_FILENAMES_1_OBJECTS = \ $(OBJS)\monolib_richtooltip.o \ $(OBJS)\monolib_sound.o \ $(OBJS)\monolib_taskbar.o \ + $(OBJS)\monolib_notifmsgrt.o \ $(OBJS)\monolib_joystick.o \ $(OBJS)\monolib_animateg.o endif @@ -4541,6 +4545,7 @@ ____ADVANCED_SRC_FILENAMES_2_OBJECTS = \ $(OBJS)\advdll_richtooltip.o \ $(OBJS)\advdll_sound.o \ $(OBJS)\advdll_taskbar.o \ + $(OBJS)\advdll_notifmsgrt.o \ $(OBJS)\advdll_joystick.o \ $(OBJS)\advdll_animateg.o \ $(OBJS)\advdll_bmpcbox.o \ @@ -4596,6 +4601,7 @@ ____ADVANCED_SRC_FILENAMES_2_OBJECTS = \ $(OBJS)\advdll_richtooltip.o \ $(OBJS)\advdll_sound.o \ $(OBJS)\advdll_taskbar.o \ + $(OBJS)\advdll_notifmsgrt.o \ $(OBJS)\advdll_joystick.o \ $(OBJS)\advdll_animateg.o endif @@ -4650,6 +4656,7 @@ ____ADVANCED_SRC_FILENAMES_3_OBJECTS = \ $(OBJS)\advlib_richtooltip.o \ $(OBJS)\advlib_sound.o \ $(OBJS)\advlib_taskbar.o \ + $(OBJS)\advlib_notifmsgrt.o \ $(OBJS)\advlib_joystick.o \ $(OBJS)\advlib_animateg.o \ $(OBJS)\advlib_bmpcbox.o \ @@ -4705,6 +4712,7 @@ ____ADVANCED_SRC_FILENAMES_3_OBJECTS = \ $(OBJS)\advlib_richtooltip.o \ $(OBJS)\advlib_sound.o \ $(OBJS)\advlib_taskbar.o \ + $(OBJS)\advlib_notifmsgrt.o \ $(OBJS)\advlib_joystick.o \ $(OBJS)\advlib_animateg.o endif @@ -9032,6 +9040,11 @@ $(OBJS)\monodll_taskbar.o: ../../src/msw/taskbar.cpp $(CXX) -c -o $@ $(MONODLL_CXXFLAGS) $(CPPDEPS) $< endif +ifeq ($(USE_GUI),1) +$(OBJS)\monodll_notifmsgrt.o: ../../src/msw/rt/notifmsgrt.cpp + $(CXX) -c -o $@ $(MONODLL_CXXFLAGS) $(CPPDEPS) $< +endif + ifeq ($(USE_GUI),1) $(OBJS)\monodll_joystick.o: ../../src/msw/joystick.cpp $(CXX) -c -o $@ $(MONODLL_CXXFLAGS) $(CPPDEPS) $< @@ -11552,6 +11565,11 @@ $(OBJS)\monolib_taskbar.o: ../../src/msw/taskbar.cpp $(CXX) -c -o $@ $(MONOLIB_CXXFLAGS) $(CPPDEPS) $< endif +ifeq ($(USE_GUI),1) +$(OBJS)\monolib_notifmsgrt.o: ../../src/msw/rt/notifmsgrt.cpp + $(CXX) -c -o $@ $(MONOLIB_CXXFLAGS) $(CPPDEPS) $< +endif + ifeq ($(USE_GUI),1) $(OBJS)\monolib_joystick.o: ../../src/msw/joystick.cpp $(CXX) -c -o $@ $(MONOLIB_CXXFLAGS) $(CPPDEPS) $< @@ -15431,6 +15449,9 @@ $(OBJS)\advdll_sound.o: ../../src/msw/sound.cpp $(OBJS)\advdll_taskbar.o: ../../src/msw/taskbar.cpp $(CXX) -c -o $@ $(ADVDLL_CXXFLAGS) $(CPPDEPS) $< +$(OBJS)\advdll_notifmsgrt.o: ../../src/msw/rt/notifmsgrt.cpp + $(CXX) -c -o $@ $(ADVDLL_CXXFLAGS) $(CPPDEPS) $< + $(OBJS)\advdll_joystick.o: ../../src/msw/joystick.cpp $(CXX) -c -o $@ $(ADVDLL_CXXFLAGS) $(CPPDEPS) $< @@ -15590,6 +15611,9 @@ $(OBJS)\advlib_sound.o: ../../src/msw/sound.cpp $(OBJS)\advlib_taskbar.o: ../../src/msw/taskbar.cpp $(CXX) -c -o $@ $(ADVLIB_CXXFLAGS) $(CPPDEPS) $< +$(OBJS)\advlib_notifmsgrt.o: ../../src/msw/rt/notifmsgrt.cpp + $(CXX) -c -o $@ $(ADVLIB_CXXFLAGS) $(CPPDEPS) $< + $(OBJS)\advlib_joystick.o: ../../src/msw/joystick.cpp $(CXX) -c -o $@ $(ADVLIB_CXXFLAGS) $(CPPDEPS) $< diff --git a/build/msw/makefile.vc b/build/msw/makefile.vc index a57adf3fd8..feabace107 100644 --- a/build/msw/makefile.vc +++ b/build/msw/makefile.vc @@ -2680,6 +2680,7 @@ ____ADVANCED_SRC_FILENAMES_OBJECTS = \ $(OBJS)\monodll_richtooltip.obj \ $(OBJS)\monodll_sound.obj \ $(OBJS)\monodll_taskbar.obj \ + $(OBJS)\monodll_notifmsgrt.obj \ $(OBJS)\monodll_joystick.obj \ $(OBJS)\monodll_animateg.obj \ $(OBJS)\monodll_bmpcbox.obj \ @@ -2735,6 +2736,7 @@ ____ADVANCED_SRC_FILENAMES_OBJECTS = \ $(OBJS)\monodll_richtooltip.obj \ $(OBJS)\monodll_sound.obj \ $(OBJS)\monodll_taskbar.obj \ + $(OBJS)\monodll_notifmsgrt.obj \ $(OBJS)\monodll_joystick.obj \ $(OBJS)\monodll_animateg.obj !endif @@ -3512,6 +3514,7 @@ ____ADVANCED_SRC_FILENAMES_1_OBJECTS = \ $(OBJS)\monolib_richtooltip.obj \ $(OBJS)\monolib_sound.obj \ $(OBJS)\monolib_taskbar.obj \ + $(OBJS)\monolib_notifmsgrt.obj \ $(OBJS)\monolib_joystick.obj \ $(OBJS)\monolib_animateg.obj \ $(OBJS)\monolib_bmpcbox.obj \ @@ -3567,6 +3570,7 @@ ____ADVANCED_SRC_FILENAMES_1_OBJECTS = \ $(OBJS)\monolib_richtooltip.obj \ $(OBJS)\monolib_sound.obj \ $(OBJS)\monolib_taskbar.obj \ + $(OBJS)\monolib_notifmsgrt.obj \ $(OBJS)\monolib_joystick.obj \ $(OBJS)\monolib_animateg.obj !endif @@ -4881,6 +4885,7 @@ ____ADVANCED_SRC_FILENAMES_2_OBJECTS = \ $(OBJS)\advdll_richtooltip.obj \ $(OBJS)\advdll_sound.obj \ $(OBJS)\advdll_taskbar.obj \ + $(OBJS)\advdll_notifmsgrt.obj \ $(OBJS)\advdll_joystick.obj \ $(OBJS)\advdll_animateg.obj \ $(OBJS)\advdll_bmpcbox.obj \ @@ -4936,6 +4941,7 @@ ____ADVANCED_SRC_FILENAMES_2_OBJECTS = \ $(OBJS)\advdll_richtooltip.obj \ $(OBJS)\advdll_sound.obj \ $(OBJS)\advdll_taskbar.obj \ + $(OBJS)\advdll_notifmsgrt.obj \ $(OBJS)\advdll_joystick.obj \ $(OBJS)\advdll_animateg.obj !endif @@ -4992,6 +4998,7 @@ ____ADVANCED_SRC_FILENAMES_3_OBJECTS = \ $(OBJS)\advlib_richtooltip.obj \ $(OBJS)\advlib_sound.obj \ $(OBJS)\advlib_taskbar.obj \ + $(OBJS)\advlib_notifmsgrt.obj \ $(OBJS)\advlib_joystick.obj \ $(OBJS)\advlib_animateg.obj \ $(OBJS)\advlib_bmpcbox.obj \ @@ -5047,6 +5054,7 @@ ____ADVANCED_SRC_FILENAMES_3_OBJECTS = \ $(OBJS)\advlib_richtooltip.obj \ $(OBJS)\advlib_sound.obj \ $(OBJS)\advlib_taskbar.obj \ + $(OBJS)\advlib_notifmsgrt.obj \ $(OBJS)\advlib_joystick.obj \ $(OBJS)\advlib_animateg.obj !endif @@ -9549,6 +9557,11 @@ $(OBJS)\monodll_taskbar.obj: ..\..\src\msw\taskbar.cpp $(CXX) /c /nologo /TP /Fo$@ $(MONODLL_CXXFLAGS) ..\..\src\msw\taskbar.cpp !endif +!if "$(USE_GUI)" == "1" +$(OBJS)\monodll_notifmsgrt.obj: ..\..\src\msw\rt\notifmsgrt.cpp + $(CXX) /c /nologo /TP /Fo$@ $(MONODLL_CXXFLAGS) ..\..\src\msw\rt\notifmsgrt.cpp +!endif + !if "$(USE_GUI)" == "1" $(OBJS)\monodll_joystick.obj: ..\..\src\msw\joystick.cpp $(CXX) /c /nologo /TP /Fo$@ $(MONODLL_CXXFLAGS) ..\..\src\msw\joystick.cpp @@ -12069,6 +12082,11 @@ $(OBJS)\monolib_taskbar.obj: ..\..\src\msw\taskbar.cpp $(CXX) /c /nologo /TP /Fo$@ $(MONOLIB_CXXFLAGS) ..\..\src\msw\taskbar.cpp !endif +!if "$(USE_GUI)" == "1" +$(OBJS)\monolib_notifmsgrt.obj: ..\..\src\msw\rt\notifmsgrt.cpp + $(CXX) /c /nologo /TP /Fo$@ $(MONOLIB_CXXFLAGS) ..\..\src\msw\rt\notifmsgrt.cpp +!endif + !if "$(USE_GUI)" == "1" $(OBJS)\monolib_joystick.obj: ..\..\src\msw\joystick.cpp $(CXX) /c /nologo /TP /Fo$@ $(MONOLIB_CXXFLAGS) ..\..\src\msw\joystick.cpp @@ -15948,6 +15966,9 @@ $(OBJS)\advdll_sound.obj: ..\..\src\msw\sound.cpp $(OBJS)\advdll_taskbar.obj: ..\..\src\msw\taskbar.cpp $(CXX) /c /nologo /TP /Fo$@ $(ADVDLL_CXXFLAGS) ..\..\src\msw\taskbar.cpp +$(OBJS)\advdll_notifmsgrt.obj: ..\..\src\msw\rt\notifmsgrt.cpp + $(CXX) /c /nologo /TP /Fo$@ $(ADVDLL_CXXFLAGS) ..\..\src\msw\rt\notifmsgrt.cpp + $(OBJS)\advdll_joystick.obj: ..\..\src\msw\joystick.cpp $(CXX) /c /nologo /TP /Fo$@ $(ADVDLL_CXXFLAGS) ..\..\src\msw\joystick.cpp @@ -16107,6 +16128,9 @@ $(OBJS)\advlib_sound.obj: ..\..\src\msw\sound.cpp $(OBJS)\advlib_taskbar.obj: ..\..\src\msw\taskbar.cpp $(CXX) /c /nologo /TP /Fo$@ $(ADVLIB_CXXFLAGS) ..\..\src\msw\taskbar.cpp +$(OBJS)\advlib_notifmsgrt.obj: ..\..\src\msw\rt\notifmsgrt.cpp + $(CXX) /c /nologo /TP /Fo$@ $(ADVLIB_CXXFLAGS) ..\..\src\msw\rt\notifmsgrt.cpp + $(OBJS)\advlib_joystick.obj: ..\..\src\msw\joystick.cpp $(CXX) /c /nologo /TP /Fo$@ $(ADVLIB_CXXFLAGS) ..\..\src\msw\joystick.cpp diff --git a/build/msw/wx_adv.vcxproj b/build/msw/wx_adv.vcxproj index db284de3ce..ad0522f3e8 100644 --- a/build/msw/wx_adv.vcxproj +++ b/build/msw/wx_adv.vcxproj @@ -508,6 +508,7 @@ + diff --git a/build/msw/wx_adv.vcxproj.filters b/build/msw/wx_adv.vcxproj.filters index 1707dd9520..d180183885 100644 --- a/build/msw/wx_adv.vcxproj.filters +++ b/build/msw/wx_adv.vcxproj.filters @@ -174,6 +174,9 @@ MSW Sources + + MSW Sources + MSW Sources diff --git a/build/msw/wx_vc7_adv.vcproj b/build/msw/wx_vc7_adv.vcproj index 5df855d911..38a4a7347d 100644 --- a/build/msw/wx_vc7_adv.vcproj +++ b/build/msw/wx_vc7_adv.vcproj @@ -391,6 +391,9 @@ Name="Release|Win32" ExcludedFromBuild="TRUE"/> + + + + + + + Application User Model ID. If empty it will be extracted from + the shortcut. If the shortcut does not contain an id an id will be + automatically created from the applications vendor and app name. + + @return @false if toast notifications could not be enabled. + + @onlyfor{wxmsw} + + @see wxAppConsole::SetAppName(), wxAppConsole::SetVendorName() + + @since 3.1.0 + */ + static bool MSWUseToasts( + const wxString& shortcutPath = wxString(), + const wxString& appId = wxString()); }; diff --git a/samples/dialogs/dialogs.cpp b/samples/dialogs/dialogs.cpp index ba16c55edf..8e5e133c0f 100644 --- a/samples/dialogs/dialogs.cpp +++ b/samples/dialogs/dialogs.cpp @@ -2289,6 +2289,14 @@ private: void MyFrame::OnNotifMsg(wxCommandEvent& WXUNUSED(event)) { +#ifdef __WXMSW__ + // Try to enable toast notifications (available since Win8) + if ( !wxNotificationMessage::MSWUseToasts() ) + { + wxLogDebug("Toast notifications not available."); + } +#endif + TestNotificationMessageWindow* dlg = new TestNotificationMessageWindow(this); dlg->Show(); } diff --git a/src/msw/notifmsg.cpp b/src/msw/notifmsg.cpp index b1a91330a0..72c415c812 100644 --- a/src/msw/notifmsg.cpp +++ b/src/msw/notifmsg.cpp @@ -33,11 +33,11 @@ #include "wx/toplevel.h" #include "wx/app.h" #include "wx/string.h" + #include "wx/app.h" #endif // WX_PRECOMP #include "wx/private/notifmsg.h" -#include "wx/generic/notifmsg.h" -#include "wx/generic/private/notifmsg.h" +#include "wx/msw/rt/private/notifmsg.h" #include "wx/taskbar.h" @@ -337,9 +337,19 @@ wxTaskBarIcon *wxNotificationMessage::UseTaskBarIcon(wxTaskBarIcon *icon) return wxBalloonNotifMsgImpl::UseTaskBarIcon(icon); } +bool wxNotificationMessage::MSWUseToasts( + const wxString& shortcutPath, + const wxString& appId) +{ + return wxToastNotificationHelper::UseToasts(shortcutPath, appId); +} + void wxNotificationMessage::Init() { - m_impl = new wxBalloonNotifMsgImpl(this); + if ( wxToastNotificationHelper::IsEnabled() ) + m_impl = wxToastNotificationHelper::CreateInstance(this); + else + m_impl = new wxBalloonNotifMsgImpl(this); } #endif // wxUSE_NOTIFICATION_MESSAGE && wxUSE_TASKBARICON diff --git a/src/msw/rt/notifmsgrt.cpp b/src/msw/rt/notifmsgrt.cpp new file mode 100644 index 0000000000..1d2808d685 --- /dev/null +++ b/src/msw/rt/notifmsgrt.cpp @@ -0,0 +1,545 @@ +///////////////////////////////////////////////////////////////////////////// +// Name: src/msw/notifmsgrt.cpp +// Purpose: WinRT implementation of wxNotificationMessageImpl +// Author: Tobias Taschner +// Created: 2015-09-13 +// Copyright: (c) 2015 wxWidgets development team +// Licence: wxWindows licence +///////////////////////////////////////////////////////////////////////////// +// for compilers that support precompilation, includes "wx.h". +#include "wx/wxprec.h" + +#ifdef __BORLANDC__ +#pragma hdrstop +#endif + +#ifndef WX_PRECOMP + #include "wx/string.h" +#endif // WX_PRECOMP + +#include "wx/msw/rt/private/notifmsg.h" + +#if wxUSE_NOTIFICATION_MESSAGE && wxUSE_WINRT +#include "wx/notifmsg.h" +#include "wx/msw/rt/utils.h" +#include "wx/msw/private/comptr.h" +#include "wx/msw/wrapshl.h" +#include "wx/msw/ole/oleutils.h" + +#include "wx/filename.h" +#include "wx/stdpaths.h" + +#include +#include +#include +#include +#include + +using namespace ABI::Windows::UI::Notifications; +using namespace ABI::Windows::Data::Xml::Dom; + +namespace rt = wxWinRT; + +typedef ABI::Windows::Foundation::ITypedEventHandler DesktopToastActivatedEventHandler; +typedef ABI::Windows::Foundation::ITypedEventHandler DesktopToastDismissedEventHandler; +typedef ABI::Windows::Foundation::ITypedEventHandler DesktopToastFailedEventHandler; + +class wxToastNotifMsgImpl; + +class wxToastEventHandler : + public Microsoft::WRL::Implements +{ +public: + wxToastEventHandler(wxToastNotifMsgImpl* toastImpl) : + m_impl(toastImpl) + { + + } + + void Detach() + { + m_impl = NULL; + } + + // DesktopToastActivatedEventHandler + IFACEMETHODIMP Invoke(IToastNotification *sender, IInspectable* args); + + // DesktopToastDismissedEventHandler + IFACEMETHODIMP Invoke(IToastNotification *sender, IToastDismissedEventArgs *e); + + // DesktopToastFailedEventHandler + IFACEMETHODIMP Invoke(IToastNotification *sender, IToastFailedEventArgs *e); + + // IUnknown + IFACEMETHODIMP_(ULONG) AddRef() + { + return ++m_cRef; + } + + IFACEMETHODIMP_(ULONG) Release() + { + if ( --m_cRef == wxAutoULong(0) ) + { + delete this; + return 0; + } + else + return m_cRef; + } + + IFACEMETHODIMP QueryInterface(REFIID riid, void **ppv) + { + if ( IsEqualIID(riid, IID_IUnknown) ) + *ppv = static_cast(static_cast(this)); + else if ( IsEqualIID(riid, __uuidof(DesktopToastActivatedEventHandler)) ) + *ppv = static_cast(this); + else if ( IsEqualIID(riid, __uuidof(DesktopToastDismissedEventHandler)) ) + *ppv = static_cast(this); + else if ( IsEqualIID(riid, __uuidof(DesktopToastFailedEventHandler)) ) + *ppv = static_cast(this); + else + *ppv = NULL; + + if ( *ppv ) + { + reinterpret_cast(*ppv)->AddRef(); + return S_OK; + } + + return E_NOINTERFACE; + } + +private: + wxAutoULong m_cRef; + + wxToastNotifMsgImpl* m_impl; +}; + +class wxToastNotifMsgImpl : public wxNotificationMessageImpl +{ +public: + wxToastNotifMsgImpl(wxNotificationMessageBase* notification) : + wxNotificationMessageImpl(notification), + m_toastEventHandler(NULL) + { + + } + + virtual ~wxToastNotifMsgImpl() + { + if ( m_toastEventHandler ) + m_toastEventHandler->Detach(); + } + + virtual bool Show(int WXUNUSED(timeout)) wxOVERRIDE + { + wxCOMPtr toastXml; + HRESULT hr = CreateToastXML(&toastXml); + if ( SUCCEEDED(hr) ) + { + hr = CreateToast(toastXml); + } + + return SUCCEEDED(hr); + } + + virtual bool Close() wxOVERRIDE + { + if ( m_notifier.get() && m_toast.get() ) + { + bool success = SUCCEEDED(m_notifier->Hide(m_toast)); + ReleaseToast(); + return success; + } + else + return false; + } + + virtual void SetTitle(const wxString& title) wxOVERRIDE + { + m_title = title; + } + + virtual void SetMessage(const wxString& message) wxOVERRIDE + { + m_message = message; + } + + virtual void SetParent(wxWindow *WXUNUSED(parent)) wxOVERRIDE + { + + } + + virtual void SetFlags(int WXUNUSED(flags)) wxOVERRIDE + { + + } + + virtual void SetIcon(const wxIcon& WXUNUSED(icon)) wxOVERRIDE + { + // Icon would have to be saved to disk (temporarily?) + // to be used as a file:// url in the notifications XML + } + + virtual bool AddAction(wxWindowID WXUNUSED(actionid), const wxString &WXUNUSED(label)) wxOVERRIDE + { + return false; + } + + void ReleaseToast() + { + if ( m_toastEventHandler ) + m_toastEventHandler->Detach(); + m_notifier = NULL; + m_toast = NULL; + } + + HRESULT CreateToast(IXmlDocument *xml) + { + HRESULT hr = ms_toastMgr->CreateToastNotifierWithId(rt::TempStringRef::Make(ms_appId), &m_notifier); + if ( SUCCEEDED(hr) ) + { + wxCOMPtr factory; + hr = rt::GetActivationFactory(RuntimeClass_Windows_UI_Notifications_ToastNotification, + IID_IToastNotificationFactory, reinterpret_cast(&factory)); + if ( SUCCEEDED(hr) ) + { + hr = factory->CreateToastNotification(xml, &m_toast); + if ( SUCCEEDED(hr) ) + { + // Register the event handlers + EventRegistrationToken activatedToken, dismissedToken, failedToken; + m_toastEventHandler = new wxToastEventHandler(this); + wxCOMPtr eventHandler(m_toastEventHandler); + + hr = m_toast->add_Activated(eventHandler, &activatedToken); + if ( SUCCEEDED(hr) ) + { + hr = m_toast->add_Dismissed(eventHandler, &dismissedToken); + if ( SUCCEEDED(hr) ) + { + hr = m_toast->add_Failed(eventHandler, &failedToken); + if ( SUCCEEDED(hr) ) + { + hr = m_notifier->Show(m_toast); + } + } + } + } + } + } + + if ( FAILED(hr) ) + ReleaseToast(); + + return hr; + } + + HRESULT CreateToastXML(IXmlDocument** toastXml) const + { + HRESULT hr = ms_toastMgr->GetTemplateContent(ToastTemplateType_ToastText02, toastXml); + if ( SUCCEEDED(hr) ) + { + wxCOMPtr nodeList; + hr = (*toastXml)->GetElementsByTagName(rt::TempStringRef::Make("text"), &nodeList); + if ( SUCCEEDED(hr) ) + { + hr = SetNodeListValueString(0, m_title, nodeList, *toastXml); + if ( SUCCEEDED(hr) ) + hr = SetNodeListValueString(1, m_message, nodeList, *toastXml); + } + } + + return hr; + } + + static HRESULT SetNodeListValueString(UINT32 index, const wxString& str, IXmlNodeList* nodeList, IXmlDocument *toastXml) + { + wxCOMPtr textNode; + // Set title node + HRESULT hr = nodeList->Item(index, &textNode); + if ( SUCCEEDED(hr) ) + { + hr = SetNodeValueString(str, textNode, toastXml); + } + + return hr; + } + + static HRESULT SetNodeValueString(const wxString& str, IXmlNode *node, IXmlDocument *xml) + { + wxCOMPtr inputText; + + HRESULT hr = xml->CreateTextNode(rt::TempStringRef::Make(str), &inputText); + if ( SUCCEEDED(hr) ) + { + wxCOMPtr inputTextNode; + + hr = inputText->QueryInterface(IID_IXmlNode, reinterpret_cast(&inputTextNode)); + if ( SUCCEEDED(hr) ) + { + wxCOMPtr pAppendedChild; + hr = node->AppendChild(inputTextNode, &pAppendedChild); + } + } + + return hr; + } + + static bool IsEnabled() + { + return ms_enabled; + } + + static wxString BuildAppId() + { + // Build a Application User Model IDs based on app info + wxString vendorId = wxTheApp->GetVendorName(); + if ( vendorId.empty() ) + vendorId = "wxWidgetsApp"; + wxString appId = vendorId + "." + wxTheApp->GetAppName(); + // Remove potential spaces + appId.Replace(" ", "", true); + return appId; + } + + static bool CheckShortcut(const wxFileName& filename) + { + // Prepare interfaces + wxCOMPtr shellLink; + if ( FAILED(CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, + IID_IShellLinkW, reinterpret_cast(&shellLink))) ) + return false; + wxCOMPtr persistFile; + if ( FAILED(shellLink->QueryInterface(IID_IPersistFile, reinterpret_cast(&persistFile))) ) + return false; + wxCOMPtr propertyStore; + if ( FAILED(shellLink->QueryInterface(IID_IPropertyStore, reinterpret_cast(&propertyStore))) ) + return false; + + bool writeShortcut = false; + + if ( filename.Exists() ) + { + // Check existing shortcut for application id + if ( SUCCEEDED(persistFile->Load(filename.GetFullPath().wc_str(), 0)) ) + { + PROPVARIANT appIdPropVar; + if ( SUCCEEDED(propertyStore->GetValue(PKEY_AppUserModel_ID, &appIdPropVar)) ) + { + wxString appId; + if ( appIdPropVar.vt == VT_LPWSTR ) + appId = appIdPropVar.pwszVal; + if ( appId.empty() || (!ms_appId.empty() && ms_appId != appId) ) + { + // Update shortcut if app id does not match or is empty + writeShortcut = true; + } + else if ( ms_appId.empty() ) + { + // Use if no app id has been set + ms_appId = appId; + } + } + } + else + return false; + } + else + { + // Create new shortcut + if ( FAILED(shellLink->SetPath(wxStandardPaths::Get().GetExecutablePath().wc_str())) ) + return false; + if ( FAILED(shellLink->SetArguments(L"")) ) + return false; + + writeShortcut = true; + } + + if ( writeShortcut ) + { + if ( ms_appId.empty() ) + ms_appId = BuildAppId(); + + // Set application id in shortcut + PROPVARIANT appIdPropVar; + if ( FAILED(InitPropVariantFromString(ms_appId.wc_str(), &appIdPropVar)) ) + return false; + if ( FAILED(propertyStore->SetValue(PKEY_AppUserModel_ID, appIdPropVar)) ) + return false; + if ( FAILED(propertyStore->Commit()) ) + return false; + if ( FAILED(persistFile->Save(filename.GetFullPath().wc_str(), TRUE)) ) + return false; + } + + return true; + } + + static bool UseToasts( + const wxString& shortcutPath, + const wxString& appId) + { + ms_enabled = false; + + // WinRT runtime is required (available since Win8) + if ( !rt::IsAvailable() ) + return false; + + // Toast notification manager has to be available + if ( ms_toastStaticsInitialized == -1 ) + { + if ( SUCCEEDED(rt::GetActivationFactory(RuntimeClass_Windows_UI_Notifications_ToastNotificationManager, + IID_IToastNotificationManagerStatics, reinterpret_cast(&ms_toastMgr))) ) + { + ms_toastStaticsInitialized = 1; + } + else + ms_toastStaticsInitialized = 0; + } + + if ( ms_toastStaticsInitialized != 1 ) + return false; + + // Build/complete shortcut path + wxFileName shortcutFilename(shortcutPath); + if ( !shortcutFilename.HasName() ) + shortcutFilename.SetName(wxTheApp->GetAppDisplayName()); + if ( !shortcutFilename.HasExt() ) + shortcutFilename.SetExt("lnk"); + if ( shortcutFilename.IsRelative() ) + shortcutFilename.MakeAbsolute(wxStandardPaths::MSWGetShellDir(CSIDL_STARTMENU)); + + ms_appId = appId; + + if ( CheckShortcut(shortcutFilename) ) + ms_enabled = true; + + return ms_enabled; + } + + static void Uninitalize() + { + if (ms_toastStaticsInitialized == 1) + { + ms_toastMgr = NULL; + ms_toastStaticsInitialized = -1; + } + } + +private: + wxString m_title; + wxString m_message; + wxCOMPtr m_notifier; + wxCOMPtr m_toast; + wxToastEventHandler* m_toastEventHandler; + + static bool ms_enabled; + static wxString ms_appId; + static int ms_toastStaticsInitialized; + static wxCOMPtr ms_toastMgr; + + friend class wxToastEventHandler; +}; + +bool wxToastNotifMsgImpl::ms_enabled = false; +int wxToastNotifMsgImpl::ms_toastStaticsInitialized = -1; +wxString wxToastNotifMsgImpl::ms_appId; +wxCOMPtr wxToastNotifMsgImpl::ms_toastMgr; + +HRESULT wxToastEventHandler::Invoke( + IToastNotification *WXUNUSED(sender), + IInspectable *WXUNUSED(args)) +{ + if ( m_impl ) + { + wxCommandEvent evt(wxEVT_NOTIFICATION_MESSAGE_CLICK); + m_impl->ProcessNotificationEvent(evt); + } + + return S_OK; +} + +HRESULT wxToastEventHandler::Invoke( + IToastNotification *WXUNUSED(sender), + IToastDismissedEventArgs *WXUNUSED(e)) +{ + if ( m_impl ) + { + wxCommandEvent evt(wxEVT_NOTIFICATION_MESSAGE_DISMISSED); + m_impl->ProcessNotificationEvent(evt); + } + + return S_OK; +} + +HRESULT wxToastEventHandler::Invoke(IToastNotification *WXUNUSED(sender), + IToastFailedEventArgs *WXUNUSED(e)) +{ + //TODO: Handle toast failed event + return S_OK; +} + +// +// wxToastNotifMsgModule +// + +class wxToastNotifMsgModule : public wxModule +{ +public: + wxToastNotifMsgModule() + { + } + + virtual bool OnInit() wxOVERRIDE + { + return true; + } + + virtual void OnExit() wxOVERRIDE + { + wxToastNotifMsgImpl::Uninitalize(); + } + +private: + wxDECLARE_DYNAMIC_CLASS(wxToastNotifMsgModule); +}; + +wxIMPLEMENT_DYNAMIC_CLASS(wxToastNotifMsgModule, wxModule); + +#endif // wxUSE_NOTIFICATION_MESSAGE && wxUSE_WINRT + +// +// wxToastNotificationHelper +// + +bool wxToastNotificationHelper::UseToasts(const wxString& shortcutPath, + const wxString& appId) +{ +#if wxUSE_NOTIFICATION_MESSAGE && wxUSE_WINRT + return wxToastNotifMsgImpl::UseToasts(shortcutPath, appId); +#else + wxUnusedVar(shortcutPath); + wxUnusedVar(appId); + return false; +#endif +} + +bool wxToastNotificationHelper::IsEnabled() +{ +#if wxUSE_NOTIFICATION_MESSAGE && wxUSE_WINRT + return wxToastNotifMsgImpl::IsEnabled(); +#else + return false; +#endif +} + +wxNotificationMessageImpl* wxToastNotificationHelper::CreateInstance(wxNotificationMessageBase* notification) +{ +#if wxUSE_NOTIFICATION_MESSAGE && wxUSE_WINRT + return new wxToastNotifMsgImpl(notification); +#else + wxUnusedVar(notification); + return NULL; +#endif +}