Module GenericMessageDialog
[hide private]
[frames] | no frames]

Source Code for Module GenericMessageDialog

  1  # --------------------------------------------------------------------------------- # 
  2  # GENERICMESSAGEDIALOG wxPython IMPLEMENTATION 
  3  # 
  4  # Andrea Gavana, @ 07 October 2008 
  5  # Latest Revision: 07 October 2008, 22.00 GMT 
  6  # 
  7  # 
  8  # TODO List 
  9  # 
 10  # 1) ? 
 11  # 
 12  # 
 13  # For all kind of problems, requests of enhancements and bug reports, please 
 14  # write to me at: 
 15  # 
 16  # andrea.gavana@gmail.com 
 17  # gavana@kpo.kz 
 18  # 
 19  # Or, obviously, to the wxPython mailing list!!! 
 20  # 
 21  # 
 22  # End Of Comments 
 23  # --------------------------------------------------------------------------------- # 
 24   
 25  """ 
 26  Description 
 27  =========== 
 28   
 29  This class represents a dialog that shows a single or multi-line message, 
 30  with a choice of OK, Yes, No and Cancel buttons. It is a possible replacement 
 31  for the standard wx.MessageDialog, with these extra functionalities: 
 32   
 33  * Possibility to modify the dialog position; 
 34  * Custom themed generic bitmap & text buttons; 
 35  * Possibility to set an icon to the dialog; 
 36  * More visibility to the button getting the focus; 
 37  * Good old Python code :-D . 
 38   
 39  And a lot more. Check the demo for an almost complete review of the functionalities. 
 40   
 41   
 42  Supported Platforms 
 43  =================== 
 44   
 45  SuperToolTip has been tested on the following platforms: 
 46    * Windows (Windows XP). 
 47   
 48   
 49  Latest Revision: Andrea Gavana @ 07 October 2008, 22.00 GMT 
 50  Version 0.1 
 51   
 52  """ 
 53   
 54  import wx 
 55  import wx.lib.buttons as buttons 
 56   
 57  from wx.lib.embeddedimage import PyEmbeddedImage 
 58   
 59  _ = wx.GetTranslation 
 60   
 61  _cancel = PyEmbeddedImage( 
 62      "iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABHNCSVQICAgIfAhkiAAAA1dJ" 
 63      "REFUOI11019oEwccB/Dv3eUuyZ2XpfljsmJ7JY01KZYWty6bdMwnp1X34JNS5sPAsmYruOnL" 
 64      "3kTGcPg6Bdkexqql4EPdBuKbVG0xLmpoWjbW0D+S1Jg24RJzuSR3l58PtpsI/l5/fB5+3x9f" 
 65      "AEDc7VauhMP3prq7q9+1t5/AW+aiLB+ZDocrU6HQk4tAFAC4s8Gg0uVyXTsZiw190Nsr6JnM" 
 66      "kZAkrd6rVtOv4wuyfLS/rW3y6Oioq2tgILiRyXy4v1yexU979yaKIyNEiQRRsUjG2Bjddrtr" 
 67      "532+k9v4B1kevu33l+vnzhFtbBAtL9OLS5douq9v0eZ1OPo8Xi8gSUClAls8jk+qVad148bP" 
 68      "33s8TcY0K32mOTV07JhsP3UKKJUAy8IORYF3584erodopaGqh7qzWYEJBgGGgW3fPrQ/eyY0" 
 69      "5uePewzjxIGDB0U5HgcsC1BV0MOH+GtiojF/9+433P1qNd1pGCvs5uawUijwbDAIWBZsAwPw" 
 70      "5nJsRyBgc8fjYLZwK5lE6uZN88Hc3LdfmeYVDgDu12oLXUSrxvPnw8r6uo3z+cAQwRGJQOzv" 
 71      "B0sEKhZhJRJI3rplJlKpM+OWdRkAuO2gZnQ93UO02CgUjr9bLHKCzweGZcGYJqhchp5I4NGd" 
 72      "O9bjpaUvxol+2Xa211/FAKolSa0XySSq+TzYYBAAYGkaUKnA5LgWA6hvmP//PKgokx9tbspq" 
 73      "Pg8NgL61c0gSJL8f73R04O9KRV9Mp0+PtlrX/zvhgigO749GJ4dKJVc9l0MTgAVAZBg4BQEk" 
 74      "SeCcTjAAOhWF5/3+w7FsdvkPogXuR7f7s/d6eycPqKqrubKC+hZ28DxydnurzHFWwG5niefB" 
 75      "CALYVgu7wmGe2toOfby2lrVFIpFrn9brcmNpCU0ALIAdooiMw9FI1etfkmGUbaY5EXY4JIth" 
 76      "YAIw1tcxODgoEcddZeua9rQqCGB5HgwA0e3GmsdjPtH1s1/Xar+ON5vTi6p6+qmm6U5JAksE" 
 77      "VhBQbzahl0p57n1Nm9kQxVhXINAucxzSLpeZLBTOxHX98nbAfxItxMrlVV4UD+/q7OTJ58Pc" 
 78      "7Ow/uVTq81c1FYTo76HQo5k9expXnc6xt9X5OsuOPIhGtZndu//9DYgBwEt1gHq0YITgmAAA" 
 79      "AABJRU5ErkJggg==") 
 80   
 81  #---------------------------------------------------------------------- 
 82  _error = PyEmbeddedImage( 
 83      "iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAABHNCSVQICAgIfAhkiAAACY9J" 
 84      "REFUWIWVl1tsXMd9xn8zc87ZXe4ud5dc0qRIWRIp0pJtVRFr15ZFA7kURJsADWwgQJvYSRAg" 
 85      "gtGg6JvzIpi1nctDU8ZpYqFogMaBm5cETg0DjoM0hl0lRiJaVmxKFiRSsnWxTIqXJbncy7nM" 
 86      "pQ+7lGTLl3YOPpxz5szM9/0vM2dG8DHlCz//ufrisWN/WQrD2zNCOM/3UZ6HVArZbmMBaxIS" 
 87      "bdFJQqQUlUxm+v5vfesVhHAfNb74SPbJSfnLixe/uOe22/65u9R1k2xGTqoWuRASIQTgWpez" 
 88      "WGuwRuPyeTE/d+7tmbfP/cPfPv30rz6KQn3oF+fEf/74xw/sLpW+Pzw80puTKZFWGZHyciJQ" 
 89      "WeGrDuGrjPC9tPC9QAReIFK+L9KpQKQ9T+Qy6RKLi/feMzo6++zJk3P/Pw84J/79859/cKyv" 
 90      "719uu/32crrZBA3IAIQPUoGQ7d4OhAU0CAPOgnMQBNSM4eTx4xeOr69/4xvPPff8/80Dk5Ny" 
 91      "6tvffmBvV9fUntHRcsfqKjSboJMWTAI6Bh21EbYRQRJDkoDW0GwSWEtnuVxMFhcP3NrXN/vb" 
 92      "8+dv8MT7BYh/ajYf2NfVNXXHzp3lfKUCjQYYA0a3BCRRC1eJw3Zdmzy+7t5okDKGzu7uYrS0" 
 93      "dO9woTB7ZH5+7sMEiH8cGXnwznLP1F0jI+Xsygo0mwhj0GHIhStXCKwlcK5NFr+XtE28vrbG" 
 94      "wtISeSlBa3QYooyh2N1daCwujven03PTlcrcewVMTsoHT5164O7u7ql7du8qpysVTBiCMego" 
 95      "4vdXrnBqyxbmFxYY0LolYpP0OvLK6iovVauc6+ykfukSvUFAojVxGCKtpau7u1i7fPlAJ8ye" 
 96      "bDTmNgWIu44d+9KBcvn7n9m9u5xaW8OEIc4YkjjmaKVC7qtf5bOHDuEGBnj9xRfpjyIC53Bx" 
 97      "jEuSFvnaGr93jn2Tk9zzta9xfnWVy9PTlDyPxBjCtojunp7i0uLivc7a2QtxPKfu2blz4jO3" 
 98      "3PLkJ/v7bwrW1tBtch3HvF6vU/r617n7y19GKkXPjh2YgQH+9NJLlNsDWq1Z2djgj6kUeycn" 
 99      "2T42hlSKwbExLlarXJ6eJi8lsdaEYQjO0d/fX4izuTtDJV9RA573N/vLPfeX6nURhiHGGKzW" 
100      "rFpL4aGHuPMrX0Gqa6nSs2MHdnCQN15+mVKjQbXZ5LV8nk889hjbx8auttsUsVSvE504gdOa" 
101      "sC1CWsvy+nr2xPz8Ec/V62J9/l2WMhkC50gDaSFIpdNsLRSQUvL+suvTn0YIwR8OHULkctzx" 
102      "+OPcfB35ZvGUYkehwDtxTMNaYudIANtooFdWCIzBywCJtSzGMSlrSQtBBkiFIc3vfAftHIP3" 
103      "3QfivWvWLZ/6FP73vkfQ0cHg3r03kDutefenP+Xi4cPEUUQiBIlzJM5hAWUMAeD5QGgsl0lI" 
104      "W0sGriK9tET90Ucx1nLz/ffjoLXKtWYtO+7eDzisMddNZgHGcPknP+GtH/yAKAxJgBCIgNA5" 
105      "tJRo51CAJ4GmNSw7S4e15IFcGxqwKyscn5zEGcOW++7DGINzH/yDE0KicLz71FOcm5oialse" 
106      "OkcNaLQRS4m2tiUAILSWVWsx7UpJa34qQArB6vIyxx95hLBep2tiAj+bvc4T1yxPNjaoPPMM" 
107      "53/0I8IwJBGC2DlC52g6RwOoAaGU+O3+ngWiMGS1Vms1EoJOIWgIQVMIckKQFYJGvU7l6acZ" 
108      "37OH4tatN3hBSMniuXMc/dnP8FZWcFISW0tsDA3nqDtHzTnWraWhFP2ZDAbwonZcs3GMby0S" 
109      "SIA64NrPTaB7bIy7vvlNMjfdRLPZ/MAQdA4Nsevhh/njI49gZ2db/duW19vW14HY94k6OjCA" 
110      "6g2C/f2eNxGEoeh0jgJQaOdAFvCBwr59HHj0UbpGR0miGKMNRhu01hitr70nmvyWLeR27uTy" 
111      "iROYlZXWbqltzGZo00rhpdP6otbPqqJS+7cGwUQpDEXeOTqBPJAXggDIfmIvf3HoEKXhYZIo" 
112      "whiNMRptNLlcDikljXrjWn2SkO3vJzs8zMKbb+KtrpKSkhS01hggoxRhOq3nouhZlfa8/UN+" 
113      "MLElDEUW6JCypVAp5J4/Y+/DD1McGiKJIrTWbRg6s1miF17ALS7ibdtGrV7HbH5PEjr6+sgM" 
114      "DbF8+jTpjQ0CKfGlJAA6lGIxCPTpJHlW5YvFu/f2909sqVaFBwS+TyAl+d5exh5/DH/bNuIw" 
115      "arvcoI2h1NkJL/yKt777Xaq/+x09IyOwbRu1jdrVcCRJQn5ggMGhIeqvvIK0FiUlnpQEqRTL" 
116      "ff16No7/S/WWy5JU6pNbhOgqak0gJSnPwzeGcrFIcWyMtXoDnSQYoykXS2R/+98sTE2RiiL8" 
117      "MCScnqZnZIRk61aq1SpGGxCCvlRA8otf0Dx9GqUUSkqU77NQKHAqnXqjLsS/qdX19Usrtdpc" 
118      "XYjxkWKxWLSWQCkyQpCcOEHBWrJ3/DmrjQY9pRI9R/6H9SeeIIgi0kqRUQo/DNHHjtEzOko4" 
119      "MEAjjNiW7cA++SSV558nUApfSqTvM9/ZyW/WN2ZOriw/dHF5+Q0FECbJWef7ZzacGx8pFou9" 
120      "xtAhBB1SYt58kxIwOD5O55Ej1H/4Q/w4JuV5pJRqwfNQYYh77TV6d+2ib/s25OHD1H/9awLP" 
121      "u0p+KZ/nN9XqzAWdHLxYr0/D+3bFu8vlv77V8w7/XaGwfXuthuccHuBLScfgIHZxERFFKCEQ" 
122      "7c6bAzjAWovI5aBYJHznHQyt5TwSkhMdGX65ujpzztqDM5XK0U3O92xKlxuNs34ud2ZB6/Fd" 
123      "hUKx39rWFFIKr1olgKuWB9djM8OVQmmNrNXw2jGXnsfJXJZn1tZmLkh58PXl5aPXc96wLb9S" 
124      "q531CoUz58NwfFexWNzqXCsxlSKtFCkpW+9S4rcF+O0YX3/32gn3aibDU5XKzLued/DV+fmj" 
125      "7+f7wJPRlWr1LF1ds6cajQO3lkrFHdAiVgrP81pnQ99Heh6iDdk+L6pNcs/j5VSKf11enrmS" 
126      "Th989dKlG8g/VADA8vr6WVsqnTler4/v7u4u3uz7CM+DILgG3wffx/k+eB7O87Ceh0mleMH3" 
127      "eXxhYWY5nz8489ZbH0gOH3c4BYaHh/9qrLf3iX1Cbk/XNlyXEBSAjBAEQuAB2jlioOEcVedI" 
128      "iiXxYqN+8rWVlb+fe/vt6Y8a/2MFOOfE5yYm9lbm50eDOKZHKTqVIqcUGVouNEBsDDVg3Rhk" 
129      "Pu+yfX0z//Hcc2c+bvz/BZALwYu3Z1YVAAAAAElFTkSuQmCC") 
130   
131  #---------------------------------------------------------------------- 
132  _help = PyEmbeddedImage( 
133      "iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABHNCSVQICAgIfAhkiAAAAtxJ" 
134      "REFUOI2lk81LFHEYx5+ZndnWnV0bt8z2TYKpxYsdwpBWA62w2rxIdOgmdPAvCOnqMSiig2SB" 
135      "lVmeAhEsJt02SNdcXZXC1HYT3SRWXLd1HHdmduf3ezqUgrjQoef08MDzeZ7v8wLwn8aUCn69" 
136      "fNntWl9vsrrdR4pra2lDEN5Xf/qU/ScgMjR09PTjxw/sLS03+YYGFmw2QF0Hc2KisJXL9Sxf" 
137      "uNAZDAa1koBIJHJcFMUxKZOR+EwGVhHBQIQT5eVgzedBb26GX6o6kc1mL9XV1eV389hdxzU+" 
138      "/tzpdErfnU6IiaIunD+/6Gm5MhkXhLEvXm+6QAiUT02d87W1PTygY76pqT4jipjq6EBZlrfz" 
139      "eW1S1/U5TdPnVFWLxuOzTz7L8s5GfT2mRZEkPB7/vg7sq6vXiKLAyswMSNKpJUIIFosUCSEM" 
140      "pdQhSVJdQlXDRlUVmIrCWnO5q7sADgCAFgp+k1LQ/X4wjAKqO1qOs7B2lmVtCMBQgmYqlVo+" 
141      "K0mAlAItFj37OqAMkzMBwC8IIMvvOGISq6YZRUXVthQlvzX6fnSnoqJiAbNZMAHAtFi29wEM" 
142      "QYgQAODDYQj4jqfu37+3MTYeLZuNz1r7XjyHvme9ou3QoY5iNArkT8GP+4Y43dPDL9rtiW+h" 
143      "EC7FYnRhYeFee3t7sLa29szw8HAg/ObNYGsohK+fPsXk9etRRNxb/54T6+0NHm5oCPMcZyt2" 
144      "dQEbCCBbVbXDpNMOY2AANi9ehLsrK+Dz+e52d3d3lrzE6enpRlc8/pKV5WpEBCQEkFJASqGw" 
145      "ubn4qrn5dmxm5lFlZWV/f3//HYZh8MAvDLW22k86HDfsktTEWK3H6Pb2T3V+fvRHIjEYSiYN" 
146      "j8cTqKmp+WCxWG6NjIy8LfVMjNvtLlMUxWGapgMRbYhoRUT+79AJAHA8z6e8Xu8mVwKAjY2N" 
147      "RiwWo6qqaqZpcoQQy65clmUJx3Gmy+Uykslk4TdmSW8/+y1ZpAAAAABJRU5ErkJggg==") 
148   
149  #---------------------------------------------------------------------- 
150  _information = PyEmbeddedImage( 
151      "iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAABHNCSVQICAgIfAhkiAAACINJ" 
152      "REFUWIWll1uMXVUZgL+19u1c9rnPzJmZzkzb6YVSgdK7gEorWCoID0QeNWJ8gxf0RaKJMcbE" 
153      "F19UQkwUiG/6QEJ8oEBoxdhqsRdAqEUovcxMO9Nz5pwz57bPvi4fzp7p6bRIiX/yZ+/s7P//" 
154      "v/Vf1l5b8PlEh4eGdX1qwsilR/WEkSeEwA+X/KXWlSC4NAvVKpz0b9WhuLXXDg7nJ++8Z2j9" 
155      "2gNj60Z3jI0VJ4uFTDaVMgwUdLqeX6u1W1fmFmcuX5g/dfX87OvtK+8eg0OV/xPgYLY0vf0b" 
156      "63fc+b1tOzft3r51wl43niOfNjF0DRlbRwr8IKTRdvlkrsHpf8103jn50dvnT5/9fePSyT/D" 
157      "oebnBrDtJ7dO7N37w737dz7+lb2b0lMjWQwpiCJQ6lOcCZASgkhxYb7B4WMfdt4+fOrlS6dP" 
158      "/MJrv3jmZjbazfzkyk/t2/r1A7959Jtfffj+3ZvNjJWk5wkcD1wf3AC8m6jrQ88DzxfYySSb" 
159      "p8fMwprRba3I3NOqjPzH6564+JkA+aGnv3zHwweef/ix++/eMF6m51wL7AXg+XEgH8IIghC6" 
160      "3vXPXa8P4vuSkVKe4Ynymrqn724ulD5YDXEdQMb81uYtjx58bt/BfTuGs0Va7b6jQcduHGhy" 
161      "GPZsho3j/TrOVKHTi4PH7zseOC7YyTSFsaGRxW60tXs+ddQL36veBOB+e3r/Iz/bc2D/Y8O5" 
162      "IZrNCNdTuL6KIRQ9T9H1oJSFR/YIhrJgJ2BNCa424NwVhRsH7nngeH2bjqtIJlJYeXtNdcmx" 
163      "G7ONN2HGA9CXw49uvO+hDbu2P5G3s1QrTVQEQggQAoFAiH6XKSXITxnYCWsFXUoYzQe0Oy6g" 
164      "4ia98TqULzK9c9vjjdnZV+szx/44APBgbmzbnU8Oj49la5Umfs9HCEk/vkQIsaJKwXw1gR+Y" 
165      "GPq1IVpY7NFsthAClOoHVSiUUqD6V6lJyhPjmfLWLd+pzxx4A16v6QAjU3fvLq1bd5/X9enU" 
166      "mqhIIaVASIkUEiEFMgYAwYkzHTaMwle259A1wZnzXV47XqHV6m+AimtBo0ihVBRDKYyURXFy" 
167      "6t7C6F176vOvH9IBWdiw7kEjnc1X5iv0Wm2klCsqhByA6Zek2YLfvtzk1WMJTEMys9Cj3Q3j" 
168      "1bMSrK8RUaSIoogoitDaOpZtZ7NrJx6oz/O6DgfyyeHRXY7jU1+4Sui6aJoWA2hIKWIQsVIO" 
169      "BBi6RrvdWtmUPD+K6x2nP151FCkiFaGiiDCMQECyWMIqDu2CBwq6bU+W9UxuammpQ6NWR4VB" 
170      "H0DT0KRcKYOUfQCAcinF9799O2tGUigFjhvw/J/OcvpsFSnEtZUrhYpXPqi+ZqDbmUnbnirr" 
171      "meHikLCMXHepi+M4CKXQtOXVywHtA0QKRgo59u0qk0qsDBFH3p7l7+/MoUlWMrBc/+XAYRgR" 
172      "RSGi65BMJXNWbqisi1QiH7k9q335DJ3qHHqihG7ZaJpxfS/EjRgpCIJg9QZKFIZ4nosmxXXN" 
173      "N1j/ZQjZc0nYKZOEldGFkCFCqaA5gzN3BKVl0FKj6MkR9EShD6Mn0HQDKTUiJfADH1Z9kIIw" 
174      "xHU9NE2gouUJCInCkDD0CQOX0GsT9GooL4ud2anQDaV7ftBASldL5kEaKL9N0J4lcBZBSyH0" 
175      "NEJPI40UUk+iMGg3zP6oDUiv22apfhVNKFTkE4UeUdAjCrpEfgcVtFBeE8I2CeMLQOiJyFvS" 
176      "e61GFUHdygyXNTNHpDqgJUD266siD+VDFPoguhBJ3E6pv8EMiOs06dUug6boG3h9VW5874IK" 
177      "EZqFaY+ghF53O+0F2bp8bj7we58kC2MY6TLIBEhr4GqBNEHoIDSIJ+EGURGwrP1tGyFjO6Pv" 
178      "Q7PQrDyJwgRKRRdaly8sSDjUdBq144l8kWRxHRip/ssrEKs1BlotQh+wM29i01czO0ayNI7X" 
179      "aR2HV5YkQH1u9rBuaZXM+BbM1BAI8zqjFdWWoT4N4GbZi1WYSDODPbIJPZle7FxdeBNQEqBy" 
180      "/K+nndbi4cLUNOmRzQg9FUOsBknE/WFww2lO6gOAgzbXspnITZCbvA2/1/lL9cS5UwBxQd/o" 
181      "VM99+IKR0iql6btJFiZiwwHVLIRmgKYhpLzhMCmkAKkhNB20ATthgjAw0iXyU3dg5TPVxtyl" 
182      "38ELrQEAuHLk8FuN+QsvldaOR8X1OzAzw/3miTMhpN7fioVEIYhWTYFS/ROpiL8hyLjxpIGW" 
183      "yJJbs4Xi+umoXVv4Q+WtN44s2w2ciD4Ou9H0v7OTI7fnxtZvCgMTz3EIwwghtdixxLIspGZh" 
184      "p5NU6i4fX2ryztkqrxz5hMVGb+UjJIRAIdCtFPnxacq3byEIm6/NnTj1o6DyYm0lc6t7yf7S" 
185      "z7duuue+5zRjZN/CR7PUZ87hNGsIFKlUimw2S9q2SSaTJEwThCAIAhynR7fbpdVq0mq1CMMI" 
186      "I2WTLU8yvGGSUDWOXjx14qnu0WffHYx3w6nYu3S40k5s+mdmNLe2MDG5wUoNSSk0TEMjZ9vk" 
187      "83kKhQKFfIFMNks63YcxTRNdjzNlWFi5IUrrN1HaOB56fuXVmXdPPdP927Pv3TA8qx8sS/Le" 
188      "n4yv2bH96eLo+u8KL1mm7WCFLildkE4kSKdSWKaFkALfD3B6Dh3HoesFOGh4CZNA967WFy+9" 
189      "dPXU+79y/vHjuZvF+d+/ZlufMEvbD9w7tm7jk7nC6NcKCXu0kEiIgmWQTZqkTAMpBD0/oNnz" 
190      "qDku1a6jat3WQq02/2bl4sUXFk+cPsrHv3Y/LcSt/Zx+8ZlkdsOWO4pTU/vz+eLefCY7nUmm" 
191      "iglTSwL0/NBZ6nZrS83muaV67XjtyuxbzQ9m3+fkT7uf5foW/44H5K4fpLltsmTkckVlmDmA" 
192      "oNdr0G7V+XBmkfd+2fk87v4LLAgo84Gt5eYAAAAASUVORK5CYII=") 
193   
194  #---------------------------------------------------------------------- 
195  _no = PyEmbeddedImage( 
196      "iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABHNCSVQICAgIfAhkiAAAAelJ" 
197      "REFUOI21ksFL03EYxj/fX1tuWEtxW0ZulbbpKYutIYM6CIFEimh2CUFIKKhLpxCKSPwDunSI" 
198      "IOgQSh48dq5DB9EiVik/NaHBYrRm5HTG2u/pMAsTiRb0nJ735X0e3vfhhf+FC4dpT/WioWY6" 
199      "/8ngfT8reoXsXtYBd1XigTDnc/frJeW18iigoSOMAOavxEehZm4QOYXHymRmVV6b1PIlFPFy" 
200      "cKf5Xdsb9gD3gtdisdlcn3n+LEXm017inRniSx+iD5eY2D5vbS2uNBP8coDLnuRd46kpUiqV" 
201      "8O0p4YqNETrOudONxP9ocP0Y0y13uoAyTU0W+fxXmkIWsEF4pIsHSZ4CNTsa3G4n4TvjPkTd" 
202      "MPARv3+VbDZHJLIBpGFfD3Vn3Q1XW+lnS6A/iZnrw2mb7AYruRmNmJ7+TCJRC2wAa+DMsHDx" 
203      "BdEJGoD8rw2W+7gRvuUCyw8sAPMUCm8ZH39NNpsC5gEbLC+hmy6enGLst/PfDSKpVdJJSR2S" 
204      "OjQ1dUKRSESjo1FJbZJaJIUlBWQPIyAAwJseZuQYSQFJ+yU1SmpUWUHZi34Vv9VL8kmqleSR" 
205      "tFsSetnNIuB2GbDtQcWMexWMwRgLpM3dHNKOU6FykASq1OvfSQNes3mL31vdv5tiJdl8FZqd" 
206      "8QO3F9ZRFEVpTAAAAABJRU5ErkJggg==") 
207   
208  #---------------------------------------------------------------------- 
209  _ok = PyEmbeddedImage( 
210      "iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABHNCSVQICAgIfAhkiAAAAjdJ" 
211      "REFUOI2tksFLk3Ecxp+97975vmuve1dWuiUTNIy1JlsLpkZG0aXLbv0B0aVDUMfVQTp0jJpF" 
212      "EHl5LxUZgZcuQjAID4KUyWwyEU3d9m7O5d733dze97dfB1siJSn1nJ/P5+ELX+Afwx6YuAMB" 
213      "AVgwjcaBBdIovP2eyKMLPYNdM+7kNKZA9i3gR+ENCeF4Hx+8VigVBgrKWrXKGp/2JeCfwhsW" 
214      "Q/HTQiCaVTOYUiZtDuoMQqefrc1S9+uOEGNSRzqd+4j72/c1l4OOQNwn+aOFWg5TdBJEIKbH" 
215      "dI9zHLMt6H3lHrjScfU5x3DSmOXNrVUUxwFQ6S3vDdh9cZ/zTHSz8R0pMguGMKaRMuX5peQ9" 
216      "ZULPW8+PnB286L78zH/M76/DwCYtjSTefaAOQZjpEDofn5J8UR0qViqLoCpLql+IXFzS72IC" 
217      "eQCwssR2NFfOtNXsFZx09SLkDnfSlsYTluUy7a3Hz6mWMrLGKswiJaV0WS6Uyr9gAGC7It0L" 
218      "WrWYm99K9VdcqugSD8Pd6nG6RNeJCq9ZstwqNL1CMl/z8npdiRkPd2AAYJcTy41FcSVZt+lK" 
219      "na9FaLspCg4ehDew3qJgs6qStUxerhItlr+h74KB5iPNgVZuGkm6QpQWmy3i8AoiY7dA1XTy" 
220      "LZuVGYHGZi8t/gbvCABgDFS7vpVEgSgS29bv5CR7XtmQjxxyxt77En+Edwt+Svpua3MbRT5T" 
221      "a9QXPGL7gxc9L/eE98wwHWaG6JD1783/kB9qTvueLt8LjwAAAABJRU5ErkJggg==") 
222   
223  #---------------------------------------------------------------------- 
224  _question = PyEmbeddedImage( 
225      "iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAABHNCSVQICAgIfAhkiAAAB/pJ" 
226      "REFUWIXFl3tsVuUdxz/PubyXvu3b2hugKAobaYHJpYZLghMdEzsnbKhxGidzuMVkExedG9ni" 
227      "0Jm4kGWpIsmyyz9go1lkGzC5KAFLkSJQuUwYtEBx3Au0pX1p3/c9z+W3PwoJoiCgyb7J8885" 
228      "v/P7fM5znjx5DnyBFBUVlZWXlw/6Ij2uKcOHD6n60x//vGrVilWdq1e907N4UX1jVVXVuGvp" 
229      "pa72gdLS0huWL3v7o492HSjZ2NRlAO6aMiAYOWpY78yZM8YdPXp039X086+meOrUqdMXLlz4" 
230      "zrr3Wq873p7mhsE3+el0md/S2svJ9mOxF194ZvaJEyeOtbS07LjSnlcyA/6AAQPK5s6dWzdp" 
231      "wqRH/rl8q43Fh/nxeICODFo7nHP09OQpK+0xP3z8rmDNmrUrfzn3uSe7urqOAQ6QKxVQgNTU" 
232      "1IwfWDFwaM1tNbcPrxo+prJi4KSW1g7VdjDnSkoqvTD00VpjjMNoizYO64SengjoddO+Ocyb" 
233      "OP4W/nvo4JZNH2z9d0PDhvVtbfsO7N27d9PnzsD8+b9/vfaeex89fPgYx46fYs/eTpPLJVR5" 
234      "+fV+SUmMbDbCWosx/UNrhzUOYy1agwicOp1FXMaMHVuppt39NW/EiGEqlUrw2msLV86Z89S9" 
235      "lxSYN29e7L5vfye/fMUOp6hU8XiI7wcqFlMYY9Da0NeXQxtDqiAkXZRAedDdneXY8QzZrCEM" 
236      "AowRtFGcPRthjRHnYML4cnn++fu9Z599pqyurq7zPDO4UCCVSpVGUYQzcSoqi5XWEc5Z8nmL" 
237      "tZZ8LuLWW6/nG3dWU1qWAsA5i9aankwfS5fupKFhP54f4izEYgrrh0qc4uNDvSgFQ4cOvRn4" 
238      "bAHP89LOWfr6tDNGe8YYnHM4ZzFGE+mI6feNxvc8+vpyWOvOrQWLMYYZM0ZSXByydNkewANR" 
239      "IOBEYXT/ZBcXF5ddyPyEQEVFRVopD21UoCOLsRbnLNYZrDUYo9Ha4MVDtDZ0dHSTSMRwzpLN" 
240      "5ejry3LjjUl279qHMUlQAZ7n43khAwekFEAyTMYvKSAiAoJzoI3BGIOcEzBGY4zmzJkM9fXv" 
241      "0rD+PxxoO4E1lhdffJgxo4eQyZwln89SVhZy8GCOWCyO8gTPU+TzWkRQVll1SYGurq6z4sA6" 
242      "64yxnjEWaw0ipv8ts3lqv/Vb2k924XsQBAqtLe+8u52acUPIZDJEUYRSGsFx4RYQhB5KQS6X" 
243      "y19SoLe3t8fzPQJPMMahtUWk/ztv2dLCkSMncC4iHvMRsYAjn88xacJwTrSfJpPpxRjN4SNd" 
244      "BEEJguAJIEIyESBAd3d3xyUF2tvbO33PI10cqEhbnHN0nzlLw/pdRFEWpRRKeThncQ5y+Twz" 
245      "ZkxkxMgBnDzVhTjD1q0HyPZ5JBICCA7BA4oKQ9XV0cnx48c/vpD5qY1o2dLlLdt2ZIZ39xRw" 
246      "9PBJPtx+EBGNOI11EWIjHIZ8NsfPf3EfEyfczKlTHVhraG09yoIFTRQVVeJ5MTw/hu+HOOvz" 
247      "yCOjZMqUis47p3y9/EKed7HA2nXrlg25qYgjR7rZvvM4nhcDAkQCxAUIAVEeam4bzqSJQ2hv" 
248      "P40xmra2k7z66vsUpCpx0l+P+IgE9PU5xowZojZ/sHnrxbxPCTQ1vb+iumoQ27YdEoj1QyWG" 
249      "SIgQIi5GX59i2rRRdHZ2o41m9+4jzJ/fQCw+4BP1TmKIBCiFfPUrxSxZsuSvnyvQ3Ny8MQjs" 
250      "qZEjCqyOgnNNYogkwCUQEiiVZNCgJLlcDoXjrbd2k0hcjyKOcwlE4ojEQWJEkU9VValLxG3U" 
251      "2rrnvYt5wcUXAPdh87amBx6omr59+x7xvLgS8RHRODxEfHwfPmw+QSKp0caSySRQqgARDwhB" 
252      "QkQCnIREkWX242Np3NC0paenp/uKBJb8Y9kbb77x+owFC9pcR0eoxBmcBCAhTgzJZJy6Vw7g" 
253      "+xZnHcUlpQR+gKgQz/MRF+JUgCc+lRW4CRNv9J988nd/A+zFsEseSBoaGg9t2do1eP780yqZ" 
254      "FKxziNU4sfT2ambNGkhNTYIo8nj55f1ksyGe56GUj+cF+L5PNgs//Um5TJxYkK+tvbvwswQ+" 
255      "tQbO5+mnn3rsR09MUoMGZazWBYhL4iSFMSnuuGMQ06cXUF6epKbmBub9ppoz3QqRQsSlcK4A" 
256      "rQsoLTPuwQduUS+99MITnwW/rMDOnTs3rF69bl394nuUsUYghXOFOFeEUiFF6RTXXVdKuihN" 
257      "KuVjdKz/vhQikkJrJXV/GCVNm7Zsa2pqeutSnMsdSqWxcf3GuXOf+7HndQZr1igViyWBkH2t" 
258      "AWFoGDw4xv59Xfzq1/sRNwRIoFSc3l6fx76PTJ5c5s+Z89R3z5w5c+gynMunurr6dmu1zJ5d" 
259      "H8UTDVJSsl7S6fWSSjVKLLZa4vFVUljUKEXpRikuaZREslFmznzTtLbskvHjJz18zeAL89BD" 
260      "Dz8n4uQHj79tlGqSVOEOSRVuk1Thzv6R2i6FhdtFeVtl+ox/2b17d8msWbNf+VLg53PX1KlP" 
261      "iHNSV7dSQ7Mkk22SSLRKItEqyYIDArvkZ8/8Xe9r3S0PPvjQy18q/HwmT77je21t+zs3NO6W" 
262      "cTXrDbQ6OOCqqzfaRYsapLn5Az11au3T58qv+q/ripJOp0sXL67f2d3dJWvWbHEr3t7k9rW2" 
263      "SH39m0cqKiqGXW2/a7YcPXrso7W1tfd7HsHatQ0rN29u+gtgrrXf/y3/A9AbS5RB5/OZAAAA" 
264      "AElFTkSuQmCC") 
265   
266  #---------------------------------------------------------------------- 
267  _reassign = PyEmbeddedImage( 
268      "iVBORw0KGgoAAAANSUhEUgAAAAwAAAAMCAYAAABWdVznAAAABHNCSVQICAgIfAhkiAAAAcRJ" 
269      "REFUKJGdj01Ik3Ecxz///565KcvkcUwedtiWRFRUprTAxxZLq0MRzBy5IIoShF5cp6BLBF16" 
270      "oU4RnQK7BC2WtEOLGLJkvdGbBzOFEqpLRXhYbZLu+XWwt3Mf+B4/H/gqFlkOnAU+AGFgDlgJ" 
271      "zABBIC0ij5RSAoDH485lr52SocHdMv7giqR6e2SyeFn2JLrlWf6SWIHGj4VCoRXAAGhb17Yz" 
272      "urFTFnSTevn4KYnePqamp0j17+Xzl3esWdseFJFlwFsDQGmD4KrtyvzkZf/h05w/18GOXScw" 
273      "dA2UG9/tNwALADqTySQrlW/kcncYyd5ia3w9kZYaN65fpVwu43Y5gKCUUgA6mUzePHRwQIpj" 
274      "BZY2NXD0eBq7qwNrySxjo/eo1Ry01vzGABhKDyjmRsCoh9nvUP2KUZnm7pMJujZv41f8r5A+" 
275      "sk9ejWaVUddAIh4httrF5HuLwWMnsawWHMf5I+hSqWQXSzPqwvBzuvvPcHF4gvuvG1nReYBw" 
276      "OML8/A9EBBERAMO27YexWIzohnY8dS7GX/TRuilFfEsP1WoFr7cen8+H/vcIUAmFQmKappim" 
277      "Kc3NfvH7FxcIBASQfD4f5X/4CVPZn52VDH4mAAAAAElFTkSuQmCC") 
278   
279  #---------------------------------------------------------------------- 
280  _warning = PyEmbeddedImage( 
281      "iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAABHNCSVQICAgIfAhkiAAABohJ" 
282      "REFUWIXVlktsHVcZx3/nzJyZ+7RvYjs3Jtj12773xokfcV4VCgopArUisEhb8ahIg9ImAYnn" 
283      "glVggRCgbtghVqxYVCwQokh0gSDQNhJSC4iIUpREbWM7iePHffnOnJlzWMy1Y9RWTdxmwZGO" 
284      "ZjQ65zu/7/t/33cG/l/HTx4pZv/0s/OHfvXdR/ceA3e7duR2Ns2CGhrpuVgeUi/uL2V+f+pT" 
285      "hSe2C+BsZ9NXZ51jhz4x+8PBoVSh0KHyrfV4gP/M/+61GtX7tXXfEXgMMmNTE+eGxnu7CBpI" 
286      "GzC+r3/64HTX5+/X1rYAjh5KnxidKX86q1rYYB3COsUeJSZnBp++8BHGHijAWegcnqpc6H9o" 
287      "Ry5er2MjDVGIiGqMT+4Zm5zp/jIgHhjA4MOFk2NT48dUvEYUaEygsUEAQYOenYK9s4Nf/OYI" 
288      "Uw8E4MwuiiPTlWeLxYwfNKtEOiTWAUaHELagtcxEpdg3Xuo+y32U5T1XwRNz3WcOHj/8dE4u" 
289      "S6PXEXEIUQtpQoSNEEaTyfoE1h/ouDH/0ivLvPmhAXylyODBE3PPTUwUinH9NjaKMG4ekxtE" 
290      "qx6ErqFMDUxIrqsnc3Oxml56vfnC2xB9KACPH+79xpETs6fS8U1MFGBNROHo19jxse+QnjiJ" 
291      "DKsw/zLCaNIZRSSyA2sLC6++cod/v5/t982BC0NMlmfLT3XnQ0zQQBiNiCOkmwEhEdIBN02s" 
292      "Y2yooX6T0nguN1HadeEUdH5QAGek1PfMeLl3gPpionWsIY7Ams1FcWyIwgijI1hv0qlvMF3J" 
293      "fXywzGc/EMDXxzhcmpl4vODXsbqFsBqMBhshuAtgYoMONXGzhVlagRvXKPeG/uho4dypHnZv" 
294      "C+AYpEYrwxfGRnf20LidHBprpIlxrIatAFGEXq0TLq5g1lrQMuSiFWYq+bnh3fLJbQEcqTgn" 
295      "StODj+WdVWwcIG2IayOU0CipkdjNtbbRwKw0sdpgaavTaFDq1XJ8NH/2qR6G7wvgC9AxPDl0" 
296      "fmQglxfrK7hEKJFMT2o8GSHF3Qg4GBwJUm7pwwbS0SoHKtlS3x7nNO/Rot8VYOBA6mRlsu94" 
297      "Xqzg2BAldfvwCF9ovGYNGbY21ytH4LvgSBAimQCEmtHdEaWx3JdO72HfPQGc2UVxrNR/fqhP" 
298      "+VLXUCJGiRhPRCjdQC0v4a8u4zSWIA4gauFEa6Q9UC5I0fa1DeHHDQ6Us/39u9Uz7/bn9I4P" 
299      "Dw3nn5zcW5zLsopE44oIGbeQa6vIejUR2AMu/xjz+vNgLfLOvxDpJOzYtltCJBBRxPCukPJI" 
300      "9tTNW6u//ONbXNp63v90wnP9DM0dGnhuZm+u6JkGrtC4jTXkyi1kq5Hg+i54LutWUevcT2AV" 
301      "snYVVwGuTCwKwBFJUkiJlIZ0Pp25vhBkuoX57ZXq3Ra9NQJicCh/erJSKGeoI3UDuXob2ayC" 
302      "YyHlglLgKqzjIQ5dZOfss9g4RF+6CFd+nkQn0qDbZbqhR2wY6AqpjKYfXbxT+yTw63dE4Ntl" 
303      "puZm9/xo34jX6awu4txZQOomQgnwPfB9SKXBTyOyXbgz5xG5jyKki2vWYOESOE57bkl4mWSl" 
304      "wJDLKu/qQtTV55jf/G2N1ibAWVDj09mLR/ZmjnfU3sZZW8YRBuEBvoJUClIZ8LOQyoLyQWWg" 
305      "MAbBMlx9HpoL4Kh2LbYBrAGx0S8sHVlLdV323ViMrl2+w6ubAJ/Zz7HJPr43mq6mVdRCKZBe" 
306      "W28/1fY8C6kcpPLJXF+Apb/C/B+gfh1cD5x2GQjaBxswBqwFC0IaOjI41+bNnqKxL/yjRtX5" 
307      "1j6yo7vFD6Z649mOlEGpxJG7oU+BnwE/B34e/A7wO5N3YUFacFPtTRve28R7a5KLK443v+VS" 
308      "hmYoelea7s0/L8R/ccdmKuWZPh7e2fwnbltC4QBKJoXt+eC1I5DugFRnAqBy4PpJkhkNugGB" 
309      "l+gvLBDBxuVl2hDWgrUc3VcQdnjuc7fc137hukJkTL7bW1rxcdZDXF/ieBIReBCkEE0FnpPU" 
310      "vq9BtUA54MZtnRIAG7UgamJDjQ0NhBIbKgh9RGiwYYA1CYSXd8jms109O7Od7uIb16+8tLb0" 
311      "07Aqh3TdxtIxsSuMkdIY6bSMFCsGgZHILX1z4yVJNmNs+2kSyQ0YDAbkjpTp7PDIxQYHkNZa" 
312      "4eYbznxw6fJbbywtii0WN6za93huZ4izszhHckmyZwPESjei+iai/neC79/DP+MDH/8FsY6a" 
313      "7HCEfEAAAAAASUVORK5CYII=") 
314   
315  #---------------------------------------------------------------------- 
316  _yes = PyEmbeddedImage( 
317      "iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABHNCSVQICAgIfAhkiAAAAjdJ" 
318      "REFUOI2tksFLk3Ecxp+97975vmuve1dWuiUTNIy1JlsLpkZG0aXLbv0B0aVDUMfVQTp0jJpF" 
319      "EHl5LxUZgZcuQjAID4KUyWwyEU3d9m7O5d733dze97dfB1siJSn1nJ/P5+ELX+Afwx6YuAMB" 
320      "AVgwjcaBBdIovP2eyKMLPYNdM+7kNKZA9i3gR+ENCeF4Hx+8VigVBgrKWrXKGp/2JeCfwhsW" 
321      "Q/HTQiCaVTOYUiZtDuoMQqefrc1S9+uOEGNSRzqd+4j72/c1l4OOQNwn+aOFWg5TdBJEIKbH" 
322      "dI9zHLMt6H3lHrjScfU5x3DSmOXNrVUUxwFQ6S3vDdh9cZ/zTHSz8R0pMguGMKaRMuX5peQ9" 
323      "ZULPW8+PnB286L78zH/M76/DwCYtjSTefaAOQZjpEDofn5J8UR0qViqLoCpLql+IXFzS72IC" 
324      "eQCwssR2NFfOtNXsFZx09SLkDnfSlsYTluUy7a3Hz6mWMrLGKswiJaV0WS6Uyr9gAGC7It0L" 
325      "WrWYm99K9VdcqugSD8Pd6nG6RNeJCq9ZstwqNL1CMl/z8npdiRkPd2AAYJcTy41FcSVZt+lK" 
326      "na9FaLspCg4ehDew3qJgs6qStUxerhItlr+h74KB5iPNgVZuGkm6QpQWmy3i8AoiY7dA1XTy" 
327      "LZuVGYHGZi8t/gbvCABgDFS7vpVEgSgS29bv5CR7XtmQjxxyxt77En+Edwt+Svpua3MbRT5T" 
328      "a9QXPGL7gxc9L/eE98wwHWaG6JD1783/kB9qTvueLt8LjwAAAABJRU5ErkJggg==") 
329   
330   
331 -class StdDialogButtonSizer(wx.BoxSizer):
332 """ wxWidgets standard dialog button sizer. """ 333
334 - def __init__(self):
335 """ Default class constructor. """ 336 337 wx.BoxSizer.__init__(self, wx.HORIZONTAL) 338 339 self._buttonAffirmative = None 340 self._buttonApply = None 341 self._buttonNegative = None 342 self._buttonCancel = None 343 self._buttonHelp = None
344 345
346 - def AddButton(self, mybutton):
347 """ 348 Add a button to the sizer. 349 350 @param mybutton: the button to add. 351 """ 352 353 buttonId = mybutton.GetId() 354 355 if buttonId in [wx.ID_OK, wx.ID_YES, wx.ID_SAVE]: 356 self._buttonAffirmative = mybutton 357 358 elif buttonId == wx.ID_APPLY: 359 self._buttonApply = mybutton 360 elif buttonId == wx.ID_NO: 361 self._buttonNegative = mybutton 362 elif buttonId in [wx.ID_CANCEL, wx.ID_CLOSE]: 363 self._buttonCancel = mybutton 364 elif buttonId in [wx.ID_HELP, wx.ID_CONTEXT_HELP]: 365 self._buttonHelp = mybutton
366 367
368 - def SetAffirmativeButton(self, button):
369 """ Sets the affirmative button. """ 370 371 self._buttonAffirmative = button
372 373
374 - def SetNegativeButton(self, button):
375 """ Sets the negative button. """ 376 377 self._buttonNegative = button
378 379
380 - def SetCancelButton(self, button):
381 """ Sets the cancel button. """ 382 383 self._buttonCancel = button
384 385
386 - def Realize(self):
387 """ Realizes the sizer depending on the Platform. """ 388 389 if wx.Platform == "__WXMAC__": 390 391 self.Add((0, 0), 0, wx.LEFT, 6) 392 if self._buttonHelp: 393 self.Add(self._buttonHelp, 0, wx.ALIGN_CENTRE | wx.LEFT | wx.RIGHT, 6) 394 395 if self._buttonNegative: 396 # HIG POLICE BULLETIN - destructive buttons need extra padding 397 # 24 pixels on either side 398 self.Add(self._buttonNegative, 0, wx.ALIGN_CENTRE | wx.LEFT | wx.RIGHT, 12) 399 400 # extra whitespace between help/negative and cancel/ok buttons 401 self.Add((0, 0), 1, wx.EXPAND, 0) 402 403 if self._buttonCancel: 404 self.Add(self._buttonCancel, 0, wx.ALIGN_CENTRE | wx.LEFT | wx.RIGHT, 6) 405 # Cancel or help should be default 406 # self._buttonCancel.SetDefaultButton() 407 408 # Ugh, Mac doesn't really have apply dialogs, so I'll just 409 # figure the best place is between Cancel and OK 410 if self._buttonApply: 411 self.Add(self._buttonApply, 0, wx.ALIGN_CENTRE | wx.LEFT | wx.RIGHT, 6) 412 413 if self._buttonAffirmative: 414 self.Add(self._buttonAffirmative, 0, wx.ALIGN_CENTRE | wx.LEFT, 6) 415 if self._buttonAffirmative.GetId() == wx.ID_SAVE: 416 # these buttons have set labels under Mac so we should use them 417 self._buttonAffirmative.SetLabel(_("Save")) 418 if self._buttonNegative: 419 self._buttonNegative.SetLabel(_("Don't Save")) 420 421 # Extra space around and at the right 422 self.Add((12, 24)) 423 424 elif wx.Platform == "__WXGTK__": 425 426 self.Add((0, 0), 0, wx.LEFT, 9) 427 if self._buttonHelp: 428 self.Add(self._buttonHelp, 0, wx.ALIGN_CENTRE | wx.LEFT | wx.RIGHT, 3) 429 430 # extra whitespace between help and cancel/ok buttons 431 self.Add((0, 0), 1, wx.EXPAND, 0) 432 433 if self._buttonNegative: 434 self.Add(self._buttonNegative, 0, wx.ALIGN_CENTRE | wx.LEFT | wx.RIGHT, 3) 435 436 # according to HIG, in explicit apply windows the order is: 437 # [ Help Apply Cancel OK ] 438 if self._buttonApply: 439 self.Add(self._buttonApply, 0, wx.ALIGN_CENTRE | wx.LEFT | wx.RIGHT, 3) 440 441 if self._buttonCancel: 442 self.Add(self._buttonCancel, 0, wx.ALIGN_CENTRE | wx.LEFT | wx.RIGHT, 3) 443 # Cancel or help should be default 444 # self._buttonCancel.SetDefaultButton() 445 446 if self._buttonAffirmative: 447 self.Add(self._buttonAffirmative, 0, wx.ALIGN_CENTRE | wx.LEFT, 6) 448 449 elif wx.Platform == "__WXMSW__": 450 # Windows 451 # center-justify buttons 452 self.Add((0, 0), 1, wx.EXPAND, 0) 453 454 if self._buttonAffirmative: 455 self.Add(self._buttonAffirmative, 0, wx.ALIGN_CENTRE | wx.LEFT | wx.RIGHT, self._buttonAffirmative.ConvertDialogSizeToPixels(wx.Size(2, 0)).x) 456 457 if self._buttonNegative: 458 self.Add(self._buttonNegative, 0, wx.ALIGN_CENTRE | wx.LEFT | wx.RIGHT, self._buttonNegative.ConvertDialogSizeToPixels(wx.Size(2, 0)).x) 459 460 if self._buttonCancel: 461 self.Add(self._buttonCancel, 0, wx.ALIGN_CENTRE | wx.LEFT | wx.RIGHT, self._buttonCancel.ConvertDialogSizeToPixels(wx.Size(2, 0)).x) 462 463 if self._buttonApply: 464 self.Add(self._buttonApply, 0, wx.ALIGN_CENTRE | wx.LEFT | wx.RIGHT, self._buttonApply.ConvertDialogSizeToPixels(wx.Size(2, 0)).x) 465 466 if self._buttonHelp: 467 self.Add(self._buttonHelp, 0, wx.ALIGN_CENTRE | wx.LEFT | wx.RIGHT, self._buttonHelp.ConvertDialogSizeToPixels(wx.Size(2, 0)).x) 468 469 self.Add((0, 0), 1, wx.EXPAND, 0) 470 471 else: 472 # GTK+1 and any other platform 473 474 if self._buttonHelp: 475 self.Add(self._buttonHelp, 0, wx.ALIGN_CENTRE | wx.LEFT | wx.RIGHT, self._buttonHelp.ConvertDialogSizeToPixels(wx.Size(4, 0)).x) 476 477 # extra whitespace between help and cancel/ok buttons 478 self.Add((0, 0), 1, wx.EXPAND, 0) 479 480 if self._buttonApply: 481 self.Add(self._buttonApply, 0, wx.ALIGN_CENTRE | wx.LEFT | wx.RIGHT, self._buttonApply.ConvertDialogSizeToPixels(wx.Size(4, 0)).x) 482 483 if self._buttonAffirmative: 484 self.Add(self._buttonAffirmative, 0, wx.ALIGN_CENTRE | wx.LEFT | wx.RIGHT, self._buttonAffirmative.ConvertDialogSizeToPixels(wx.Size(4, 0)).x) 485 486 if self._buttonNegative: 487 self.Add(self._buttonNegative, 0, wx.ALIGN_CENTRE | wx.LEFT | wx.RIGHT, self._buttonNegative.ConvertDialogSizeToPixels(wx.Size(4, 0)).x) 488 489 if self._buttonCancel: 490 self.Add(self._buttonCancel, 0, wx.ALIGN_CENTRE | wx.LEFT | wx.RIGHT, self._buttonCancel.ConvertDialogSizeToPixels(wx.Size(4, 0)).x)
491 # Cancel or help should be default 492 # self._buttonCancel.SetDefaultButton() 493 494
495 -class GenericMessageDialog(wx.Dialog):
496 """ 497 Main class implementation, L{GenericMessageDialog} is a possible replacement 498 for the standard wx.MessageDialog. 499 """ 500
501 - def __init__(self, parent, message, caption, style, 502 pos=wx.DefaultPosition, size=wx.DefaultSize):
503 """ 504 Default class constructor. 505 506 @param parent: the L{GenericMessageDialog} parent (if any); 507 @param message: the message in the main body of the dialog; 508 @param caption: the dialog title; 509 @param style: the dialog style; 510 @param pos: the dialog position on screen; 511 @param size: the dialog size. 512 """ 513 514 wx.Dialog.__init__(self, parent, wx.ID_ANY, caption, pos, 515 size, wx.DEFAULT_DIALOG_STYLE|wx.WANTS_CHARS) 516 517 self._dialogStyle = style 518 519 topsizer = wx.BoxSizer(wx.VERTICAL) 520 icon_text = wx.BoxSizer(wx.HORIZONTAL) 521 522 case = self._dialogStyle & wx.ICON_MASK 523 524 if case == wx.ICON_ERROR: 525 bitmap = _error 526 527 elif case == wx.ICON_INFORMATION: 528 bitmap = _information 529 530 elif case == wx.ICON_WARNING: 531 bitmap = _warning 532 533 elif case == wx.ICON_QUESTION: 534 bitmap = _question 535 536 # Populate the sizers... 537 icon = wx.StaticBitmap(self, -1, bitmap.GetBitmap()) 538 icon_text.Add(icon, 0, wx.ALIGN_CENTER_HORIZONTAL) 539 icon_text.Add(self.CreateTextSizer(message), 1, wx.ALIGN_CENTER | wx.LEFT, 10) 540 541 topsizer.Add(icon_text, 1, wx.EXPAND | wx.LEFT | wx.RIGHT | wx.TOP, 10) 542 543 center_flag = wx.EXPAND 544 if self._dialogStyle & wx.YES_NO: 545 center_flag |= wx.ALIGN_CENTRE 546 547 sizerBtn = self.CreateSeparatedButtonSizer(self._dialogStyle & self.ButtonSizerFlags) 548 if sizerBtn: 549 topsizer.Add(sizerBtn, 0, center_flag | wx.ALL, 10) 550 551 self.SetAutoLayout(True) 552 self.SetSizer(topsizer) 553 554 topsizer.SetSizeHints(self) 555 topsizer.Fit(self) 556 size = self.GetSize() 557 558 if size.x < size.y*3/2: 559 size.x = size.y*3/2 560 self.SetSize(size) 561 562 self.Layout() 563 self.Centre(wx.BOTH | wx.CENTER_FRAME) 564 565 self.Bind(wx.EVT_BUTTON, self.OnYes, id=wx.ID_YES) 566 self.Bind(wx.EVT_BUTTON, self.OnOk, id=wx.ID_OK) 567 self.Bind(wx.EVT_BUTTON, self.OnNo, id=wx.ID_NO) 568 self.Bind(wx.EVT_BUTTON, self.OnCancel, id=wx.ID_CANCEL) 569 570 for child in self.GetChildren(): 571 if isinstance(child, wx.lib.buttons.ThemedGenBitmapTextButton): 572 # Handles the key down for the buttons... 573 child.Bind(wx.EVT_KEY_DOWN, self.OnKeyDown) 574 child.SetUseFocusIndicator(False) 575 576 self.Bind(wx.EVT_NAVIGATION_KEY, self.OnNavigation) 577 self.SwitchFocus()
578 579
580 - def OnYes(self, event):
581 """ L{GenericMessageDialog} had received a wx.ID_YES answer. """ 582 583 self.EndModal(wx.ID_YES)
584 585
586 - def OnOk(self, event):
587 """ L{GenericMessageDialog} had received a wx.ID_OK answer. """ 588 589 self.EndModal(wx.ID_OK)
590 591
592 - def OnNo(self, event):
593 """ L{GenericMessageDialog} had received a wx.ID_NO answer. """ 594 595 self.EndModal(wx.ID_NO)
596 597
598 - def OnCancel(self, event):
599 """ L{GenericMessageDialog} had received a wx.ID_CANCEL answer. """ 600 601 # Allow cancellation via ESC/Close button except if 602 # only YES and NO are specified. 603 604 if self._dialogStyle & wx.YES_NO != wx.YES_NO or self._dialogStyle & wx.CANCEL: 605 self.EndModal(wx.ID_CANCEL)
606 607
608 - def OnKeyDown(self, event):
609 """ Handles the wx.EVT_KEY_DOWN event for L{GenericMessageDialog}. """ 610 611 key = event.GetKeyCode() 612 if key == wx.WXK_ESCAPE: 613 self.OnCancel(None) 614 615 ids = [] 616 for child in self.GetChildren(): 617 if isinstance(child, wx.lib.buttons.ThemedGenBitmapTextButton): 618 ids.append(child.GetId()) 619 620 if key in [ord("y"), ord("Y")] and wx.ID_YES in ids: 621 self.OnYes(None) 622 elif key in [ord("n"), ord("N")] and wx.ID_NO in ids: 623 self.OnNo(None) 624 elif key in [ord("c"), ord("C")] and wx.ID_CANCEL in ids: 625 self.OnCancel(None) 626 elif key in [ord("o"), ord("O")] and wx.ID_OK in ids: 627 self.OnOk(None) 628 629 event.Skip()
630 631
632 - def OnNavigation(self, event):
633 """ Handles the wx.EVT_NAVIGATION_KEY event for L{GenericMessageDialog}. """ 634 635 # Switch the focus between buttons... 636 if wx.GetKeyState(wx.WXK_LEFT) or wx.GetKeyState(wx.WXK_RIGHT) or \ 637 wx.GetKeyState(wx.WXK_DOWN) or wx.GetKeyState(wx.WXK_UP) or \ 638 wx.GetKeyState(wx.WXK_NUMPAD_LEFT) or wx.GetKeyState(wx.WXK_NUMPAD_RIGHT) or \ 639 wx.GetKeyState(wx.WXK_NUMPAD_DOWN) or wx.GetKeyState(wx.WXK_NUMPAD_UP) or \ 640 event.IsFromTab(): 641 event.Skip() 642 wx.CallAfter(self.SwitchFocus) 643 return 644 645 button = wx.Window.FindFocus() 646 buttonId = button.GetId() 647 self.EndModal(buttonId)
648 649
650 - def SwitchFocus(self):
651 """ Switch focus between buttons. """ 652 653 current = wx.Window.FindFocus() 654 font = self.GetFont() 655 boldFont = wx.Font(font.GetPointSize(), font.GetFamily(), font.GetStyle(), wx.BOLD, 656 font.GetUnderlined(), font.GetFaceName()) 657 658 for child in self.GetChildren(): 659 if isinstance(child, wx.lib.buttons.ThemedGenBitmapTextButton): 660 if child == current: 661 # Set a bold font for the current focused button 662 child.SetFont(boldFont) 663 else: 664 # Restore the other buttons... 665 child.SetFont(font) 666 child.Refresh()
667 668
669 - def CreateButtonSizer(self, flags):
670 """ 671 Creates a sizer with standard buttons. 672 673 @param flags: a bit list of the following flags: 674 wx.OK, wx.CANCEL, wx.YES, wx.NO, wx.HELP, wx.NO_DEFAULT. 675 676 @note: The sizer lays out the buttons in a manner appropriate to the platform. 677 """ 678 679 sizer = self.CreateStdDialogButtonSizer(flags) 680 681 return sizer
682 683
684 - def CreateSeparatedButtonSizer(self, flags):
685 """ 686 Creates a sizer with standard buttons using CreateButtonSizer separated 687 from the rest of the dialog contents by a horizontal wx.StaticLine. 688 """ 689 690 sizer = self.CreateButtonSizer(flags) 691 692 # Mac Human Interface Guidelines recommend not to use static lines as 693 # grouping elements 694 if wx.Platform != "__WXMAC__": 695 topsizer = wx.BoxSizer(wx.VERTICAL) 696 topsizer.AddF(wx.StaticLine(self), wx.SizerFlags().Expand().DoubleBorder(wx.BOTTOM)) 697 topsizer.AddF(sizer, wx.SizerFlags().Expand()) 698 sizer = topsizer 699 700 return sizer
701 702
703 - def CreateStdDialogButtonSizer(self, flags):
704 """ 705 Creates a StdDialogButtonSizer with standard buttons. 706 707 @param flags: a bit list of the following flags: 708 wx.OK, wx.CANCEL, wx.YES, wx.NO, wx.HELP, wx.NO_DEFAULT. 709 710 @note: The sizer lays out the buttons in a manner appropriate to the platform. 711 """ 712 713 sizer = StdDialogButtonSizer() 714 no = yes = ok = None 715 if flags & wx.OK: 716 # Remove unwanted flags... 717 flags &= ~(wx.YES | wx.NO | wx.NO_DEFAULT) 718 719 if flags & wx.OK: 720 ok = buttons.ThemedGenBitmapTextButton(self, wx.ID_OK, _ok.GetBitmap(), _("OK"), size=(-1, 28)) 721 sizer.AddButton(ok) 722 723 if flags & wx.CANCEL: 724 cancel = buttons.ThemedGenBitmapTextButton(self, wx.ID_CANCEL, _cancel.GetBitmap(), _("Cancel"), size=(-1, 28)) 725 sizer.AddButton(cancel) 726 727 if flags & wx.YES: 728 yes = buttons.ThemedGenBitmapTextButton(self, wx.ID_YES, _yes.GetBitmap(), _("Yes"), size=(-1, 28)) 729 sizer.AddButton(yes) 730 731 if flags & wx.NO: 732 no = buttons.ThemedGenBitmapTextButton(self, wx.ID_NO, _no.GetBitmap(), _("No"), size=(-1, 28)) 733 sizer.AddButton(no) 734 735 if flags & wx.HELP: 736 help = buttons.ThemedGenBitmapTextButton(self, wx.ID_HELP, _help.GetBitmap(), _("Help"), size=(-1, 28)) 737 sizer.AddButton(help) 738 739 if flags & wx.NO_DEFAULT: 740 if no: 741 no.SetDefault() 742 no.SetFocus() 743 else: 744 if ok: 745 ok.SetDefault() 746 ok.SetFocus() 747 elif yes: 748 yes.SetDefault() 749 yes.SetFocus() 750 751 if flags & wx.OK: 752 self.SetAffirmativeId(wx.ID_OK) 753 elif flags & wx.YES: 754 self.SetAffirmativeId(wx.ID_YES) 755 756 sizer.Realize() 757 758 return sizer
759