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
This commit is contained in:
Tobias Taschner 2015-09-09 22:59:21 +02:00
parent 39716462e6
commit bf5e403a68
31 changed files with 1999 additions and 817 deletions

View File

@ -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

View File

@ -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
</set>
<set var="ADVANCED_CMN_HDR" hints="files">
@ -2728,7 +2729,6 @@ IMPORTANT: please read docs/tech/tn0016.txt before modifying this file!
src/msw/taskbar.cpp
</set>
<set var="ADVANCED_MSW_HDR" hints="files">
wx/msw/notifmsg.h
wx/msw/sound.h
wx/msw/taskbar.h
</set>
@ -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
</set>
<set var="ADVANCED_OSX_COCOA_HDR" hints="files">
@ -2879,7 +2880,6 @@ IMPORTANT: please read docs/tech/tn0016.txt before modifying this file!
</set>
<set var="ADVANCED_GTK_HDR" hints="files">
$(ADVANCED_GTK_PLATFORM_HDR)
wx/gtk/notifmsg.h
wx/gtk/taskbar.h
wx/generic/activityindicator.h
</set>

View File

@ -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)

View File

@ -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

View File

@ -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) $<

View File

@ -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

View File

@ -462,6 +462,7 @@
</ClCompile>
<ClCompile Include="..\..\src\common\gridcmn.cpp" />
<ClCompile Include="..\..\src\common\hyperlnkcmn.cpp" />
<ClCompile Include="..\..\src\common\notifmsgcmn.cpp" />
<ClCompile Include="..\..\src\common\odcombocmn.cpp" />
<ClCompile Include="..\..\src\common\richtooltipcmn.cpp" />
<ClCompile Include="..\..\src\common\taskbarcmn.cpp" />
@ -544,7 +545,6 @@
</CustomBuild>
<ClInclude Include="..\..\include\wx\msw\hyperlink.h" />
<ClInclude Include="..\..\include\wx\msw\joystick.h" />
<ClInclude Include="..\..\include\wx\msw\notifmsg.h" />
<ClInclude Include="..\..\include\wx\msw\sound.h" />
<ClInclude Include="..\..\include\wx\msw\taskbar.h" />
<ClInclude Include="..\..\include\wx\msw\timectrl.h" />

View File

@ -48,6 +48,9 @@
<ClCompile Include="..\..\src\common\hyperlnkcmn.cpp">
<Filter>Common Sources</Filter>
</ClCompile>
<ClCompile Include="..\..\src\common\notifmsgcmn.cpp">
<Filter>Common Sources</Filter>
</ClCompile>
<ClCompile Include="..\..\src\common\odcombocmn.cpp">
<Filter>Common Sources</Filter>
</ClCompile>
@ -331,9 +334,6 @@
<ClInclude Include="..\..\include\wx\msw\joystick.h">
<Filter>MSW Headers</Filter>
</ClInclude>
<ClInclude Include="..\..\include\wx\msw\notifmsg.h">
<Filter>MSW Headers</Filter>
</ClInclude>
<ClInclude Include="..\..\include\wx\msw\sound.h">
<Filter>MSW Headers</Filter>
</ClInclude>
@ -388,4 +388,4 @@
<Filter>MSW Headers</Filter>
</CustomBuild>
</ItemGroup>
</Project>
</Project>

View File

@ -324,6 +324,9 @@
<File
RelativePath="..\..\src\common\hyperlnkcmn.cpp">
</File>
<File
RelativePath="..\..\src\common\notifmsgcmn.cpp">
</File>
<File
RelativePath="..\..\src\common\odcombocmn.cpp">
</File>
@ -587,9 +590,6 @@
<File
RelativePath="..\..\include\wx\msw\joystick.h">
</File>
<File
RelativePath="..\..\include\wx\msw\notifmsg.h">
</File>
<File
RelativePath="..\..\include\wx\msw\sound.h">
</File>

View File

@ -1505,9 +1505,6 @@
<File
RelativePath="..\..\include\wx\msw\notebook.h">
</File>
<File
RelativePath="..\..\include\wx\msw\notifmsg.h">
</File>
<File
RelativePath="..\..\include\wx\msw\ole\oleutils.h">
</File>

View File

@ -837,6 +837,10 @@
RelativePath="..\..\src\common\hyperlnkcmn.cpp"
>
</File>
<File
RelativePath="..\..\src\common\notifmsgcmn.cpp"
>
</File>
<File
RelativePath="..\..\src\common\odcombocmn.cpp"
>
@ -1285,10 +1289,6 @@
RelativePath="..\..\include\wx\msw\joystick.h"
>
</File>
<File
RelativePath="..\..\include\wx\msw\notifmsg.h"
>
</File>
<File
RelativePath="..\..\include\wx\msw\sound.h"
>

View File

@ -2509,10 +2509,6 @@
RelativePath="..\..\include\wx\msw\notebook.h"
>
</File>
<File
RelativePath="..\..\include\wx\msw\notifmsg.h"
>
</File>
<File
RelativePath="..\..\include\wx\msw\ole\oleutils.h"
>

View File

@ -833,6 +833,10 @@
RelativePath="..\..\src\common\hyperlnkcmn.cpp"
>
</File>
<File
RelativePath="..\..\src\common\notifmsgcmn.cpp"
>
</File>
<File
RelativePath="..\..\src\common\odcombocmn.cpp"
>
@ -1281,10 +1285,6 @@
RelativePath="..\..\include\wx\msw\joystick.h"
>
</File>
<File
RelativePath="..\..\include\wx\msw\notifmsg.h"
>
</File>
<File
RelativePath="..\..\include\wx\msw\sound.h"
>

View File

@ -2505,10 +2505,6 @@
RelativePath="..\..\include\wx\msw\notebook.h"
>
</File>
<File
RelativePath="..\..\include\wx\msw\notifmsg.h"
>
</File>
<File
RelativePath="..\..\include\wx\msw\ole\oleutils.h"
>

View File

@ -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 = "<group>"; };
239D386E9D7D39C5A1E859C6 /* clipcmn.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = clipcmn.cpp; path = ../../src/common/clipcmn.cpp; sourceTree = "<group>"; };
23FC98E2305230E2990471E3 /* wxcrt.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = wxcrt.cpp; path = ../../src/common/wxcrt.cpp; sourceTree = "<group>"; };
24133CCC1B78C2E80019C10F /* notifmsg.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = notifmsg.mm; path = ../../src/osx/cocoa/notifmsg.mm; sourceTree = "<group>"; };
24133CCE1B78C3230019C10F /* notifmsgcmn.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = notifmsgcmn.cpp; path = ../../src/common/notifmsgcmn.cpp; sourceTree = "<group>"; };
242BF97B558634A79322052C /* prntbase.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = prntbase.cpp; path = ../../src/common/prntbase.cpp; sourceTree = "<group>"; };
243367CA1C6B91A9000B8ED5 /* utils_base.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = utils_base.mm; path = ../../src/osx/cocoa/utils_base.mm; sourceTree = "<group>"; };
24396D584D053948A3FF0DCD /* imagpng.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = imagpng.cpp; path = ../../src/common/imagpng.cpp; sourceTree = "<group>"; };
@ -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 */,

View File

@ -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);
};

View File

@ -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_

View File

@ -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 <vadim@wxwidgets.org>
// 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_

View File

@ -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 <vadim@wxwindows.org>
// 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_

View File

@ -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:

View File

@ -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_

View File

@ -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_

View File

@ -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.

View File

@ -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<wxTopLevelWindow*>(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<ActionInfo*>(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 );

View File

@ -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,

103
src/common/notifmsgcmn.cpp Normal file
View File

@ -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

View File

@ -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<wxNotificationMessageWindow*> 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*> 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<wxNotificationMessageWindow*>::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<wxNotificationMessageWindow*>::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<wxNotificationMessageWindow*>::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<wxNotificationMessageWindow*>::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

View File

@ -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 <vadim@wxwidgets.org>
// 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 <vadim@wxwidgets.org>
// Licence: wxWindows licence
///////////////////////////////////////////////////////////////////////////////
// ============================================================================
@ -28,11 +28,14 @@
#ifndef WX_PRECOMP
#include "wx/app.h"
#include "wx/icon.h"
#endif // WX_PRECOMP
#include <libnotify/notify.h>
#include "wx/module.h"
#include "wx/private/notifmsg.h"
#include <wx/stockitem.h>
// 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

View File

@ -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

View File

@ -30,6 +30,7 @@
#include <string.h>
#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 )

254
src/osx/cocoa/notifmsg.mm Normal file
View File

@ -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 <map>
@interface wxUserNotificationHandler : NSObject <NSUserNotificationCenterDelegate>
@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<wxWindowID> m_actions;
static wxUserNotificationHandler* ms_handler;
static std::map<wxString, wxUserNotificationMsgImpl*> ms_activeNotifications;
static int ms_notifIdBase;
};
wxUserNotificationHandler* wxUserNotificationMsgImpl::ms_handler = nil;
std::map<wxString, wxUserNotificationMsgImpl*> 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)