home *** CD-ROM | disk | FTP | other *** search
/ Maximum CD 2012 January / maximum-cd-2012-01.iso / DiscContents / digsby_setup.exe / lib / gui / bugreporter / bugreportergui.pyo (.txt) < prev    next >
Encoding:
Python Compiled Bytecode  |  2011-10-05  |  15.3 KB  |  341 lines

  1. # Source Generated with Decompyle++
  2. # File: in.pyo (Python 2.6)
  3.  
  4. from __future__ import with_statement
  5. from wx import TextCtrl, StaticText, ALIGN_CENTER, RadioButton, BoxSizer, HORIZONTAL, VERTICAL, StaticLine, EXPAND, Button, ALL, TOP, BOTTOM, LEFT, RIGHT, Point
  6. import wx
  7. from util import Storage as S, callsback, traceguard
  8. from traceback import print_exc
  9. from gui.toolbox.imagefx import pil_to_wxb_nocache
  10. from cgui import getScreenBitmap, GetTrayRect
  11. from gui import skin
  12. from gui.toolbox import Monitor
  13. from PIL import Image, ImageDraw
  14. from PIL.Image import BICUBIC, ANTIALIAS
  15. from cStringIO import StringIO
  16. from logging import getLogger
  17. log = getLogger('bugreporter')
  18. from gui.imagedialog import ImageDialog
  19. import wx.lib.sized_controls as sc
  20. SCREENSHOT_TIMER_SECS = 4
  21. num_screenshots = 0
  22.  
  23. class BugReportPanel(sc.SizedPanel):
  24.     
  25.     def __init__(self, parent, callback = None):
  26.         sc.SizedPanel.__init__(self, parent)
  27.         self.screenshot = None
  28.         self.construct()
  29.         self.callback = callback
  30.  
  31.     
  32.     def construct(self):
  33.         
  34.         Text = lambda *a, **k: StaticText(self, -1, *a, **k)
  35.         
  36.         def BoldText(*a, **k):
  37.             t = Text(*a, **k)
  38.             t.SetBold()
  39.             return t
  40.  
  41.         self.header = BoldText(_('Use this tool to submit a diagnostic log right after you experience a bug'), style = ALIGN_CENTER)
  42.         self.subheader = Text(_('This diagnostic log file does not contain personal data such as the content of sent/received IMs,\nthe content of emails, and the content of social network newsfeeds except where it directly pertains to an error.'), style = ALIGN_CENTER)
  43.         self.subheader.SetSizerProps(expand = True)
  44.         self.line = StaticLine(self)
  45.         self.input_desc = BoldText(_('Please describe the bug in as much detail as possible.  Include information such as\nwhat you were doing when the bug occurred and exactly what goes wrong.'))
  46.         self.input_desc.SetSizerProps(expand = True)
  47.         self.input = TextCtrl(self, -1, size = (400, 200), style = wx.TE_MULTILINE)
  48.         self.input.SetSizerProps(expand = True, proportion = 1)
  49.         radioPanel.SetSizerType('horizontal')
  50.         self.reproduce_text = wx.StaticText(radioPanel, -1, _('Can you consistently reproduce this bug?'))
  51.         self.radios = S(yes = RadioButton(radioPanel, -1, _('&Yes'), style = wx.RB_GROUP), no = RadioButton(radioPanel, -1, _('&No')), unknown = RadioButton(radioPanel, -1, _("&Don't Know")))
  52.         self.radios.unknown.SetValue(True)
  53.         self.screenshot_text = BoldText(_('If this is a visual bug, please attach a screenshot to this report.'))
  54.         self.screenshot_link = wx.HyperlinkCtrl(self, -1, _('Take Screenshot'), '#')
  55.         self.screenshot_link.Bind(wx.EVT_HYPERLINK, self.OnScreenshot)
  56.         self.screenshot_timer = ScreenshotTimer((SCREENSHOT_TIMER_SECS,), (lambda t: self.OnScreenshotLinkTimer(_('Taking Screenshot in ') + str(t))), self.OnScreenshotTimer)
  57.         self.Bind(wx.EVT_SIZE, self.OnSize)
  58.  
  59.     
  60.     def OnSize(self, event):
  61.         self.subheader.SetLabel(_('This diagnostic log file does not contain personal data such as the content of sent/received IMs, the content of emails, and the content of social network newsfeeds except where it directly pertains to an error.'))
  62.         self.subheader.Wrap(event.Size.width)
  63.         self.input_desc.SetLabel(_('Please describe the bug in as much detail as possible. Include information such as what you were doing when the bug occured and exactly what goes wrong.'))
  64.         self.input_desc.Wrap(event.Size.width)
  65.         event.Skip()
  66.  
  67.     
  68.     def OnScreenshotLinkTimer(self, l):
  69.         if wx.IsDestroyed(self):
  70.             self.screenshot_timer.Stop()
  71.             return None
  72.         self.SetScreenshotLabel(l)
  73.  
  74.     
  75.     def SetScreenshotLabel(self, l):
  76.         self.screenshot_link.SetLabel(l)
  77.         self.Layout()
  78.         self.screenshot_link.Refresh()
  79.  
  80.     
  81.     def OnScreenshot(self, e):
  82.         if self.screenshot_timer.IsRunning() or self.screenshot is not None:
  83.             self.screenshot = None
  84.             self.screenshot_timer.Stop()
  85.             self.screenshot_link.Label = _('Take Screenshot')
  86.             return None
  87.         self.screenshot_timer.Start()
  88.  
  89.     
  90.     def OnScreenshotTimer(self):
  91.         global num_screenshots
  92.         oldpos = self.Parent.Position
  93.         
  94.         try:
  95.             top = self.Top
  96.             top.Move((-(top.Size.width) - 50, -(top.Size.height) - 50))
  97.             wx.BeginBusyCursor()
  98.             wx.WakeUpIdle()
  99.             wx.MilliSleep(500)
  100.             num_screenshots += 1
  101.             log.info('taking screenshot %d', num_screenshots)
  102.             (screen_full, screen) = app_windows_image()
  103.             diag = ScreenshotDialog(self, screen_full, screen, pos = oldpos + Point(40, 40))
  104.         except:
  105.             print_exc()
  106.             screen = None
  107.         finally:
  108.             wx.EndBusyCursor()
  109.             self.Top.Move(oldpos)
  110.  
  111.         if screen is None:
  112.             return None
  113.         
  114.         try:
  115.             if diag.ShowModal() == wx.ID_OK:
  116.                 self.screenshot = diag.SelectedScreenshot
  117.                 self.screenshot_link.Label = _('Remove Screenshot')
  118.             else:
  119.                 self.screenshot_link.Label = _('Take Screenshot')
  120.         finally:
  121.             diag.Destroy()
  122.  
  123.         self.Layout()
  124.         self.Refresh()
  125.  
  126.     
  127.     def reproduce(self):
  128.         for name, radio in self.radios.iteritems():
  129.             if radio.Value:
  130.                 return name
  131.         
  132.  
  133.     reproduce = property(reproduce)
  134.     
  135.     def info(self):
  136.         shot = self.screenshot
  137.         if shot is not None:
  138.             f = StringIO()
  139.             shot.save(f, 'PNG')
  140.             shot = f.getvalue()
  141.         
  142.         return S(description = self.input.Value, reproducible = self.reproduce, screenshot = shot)
  143.  
  144.     
  145.     def layout(self):
  146.         reproduce_sizer = HSizer()
  147.         reproduce_sizer.AddMany([
  148.             (self.reproduce_text, 0),
  149.             (self.radios.yes, 1, LEFT, 20),
  150.             (self.radios.no, 1, LEFT, 20),
  151.             (self.radios.unknown, 1, LEFT, 20)])
  152.         visual_sizer = HSizer()
  153.         visual_sizer.AddMany([
  154.             (self.screenshot_text, 0, RIGHT, 15),
  155.             (self.screenshot_link, 0)])
  156.         button_sizer = HSizer()
  157.         button_sizer.AddStretchSpacer(1)
  158.         button_sizer.AddMany([
  159.             (self.submit, 0, EXPAND | RIGHT, 10),
  160.             (self.cancel, 0)])
  161.         self.Sizer = v = VSizer()
  162.         v.AddMany([
  163.             (self.header, 0, EXPAND | BOTTOM, 6),
  164.             (self.subheader, 0, EXPAND | BOTTOM, 6),
  165.             (self.line, 0, EXPAND | BOTTOM, 6),
  166.             (self.input_desc, 0, EXPAND | BOTTOM, 6),
  167.             (self.input, 1, EXPAND | BOTTOM, 6),
  168.             (reproduce_sizer, 0, EXPAND | BOTTOM, 6),
  169.             (visual_sizer, 0, EXPAND | BOTTOM, 10),
  170.             (button_sizer, 0, EXPAND)])
  171.  
  172.  
  173.  
  174. def show_dialog(callback = None):
  175.     diag = BugReportDialog(None, callback = callback)
  176.     diag.CenterOnScreen()
  177.     diag.Show()
  178.  
  179. show_dialog = callsback(show_dialog)
  180.  
  181. class BugReportDialog(sc.SizedDialog):
  182.     
  183.     def __init__(self, parent, callback = None):
  184.         sc.SizedDialog.__init__(self, parent, -1, _('Submit Bug Report - Digsby'), size = (590, 600), style = wx.DEFAULT_DIALOG_STYLE | wx.RESIZE_BORDER)
  185.         self.SetFrameIcon(skin.get('appdefaults.taskbaricon'))
  186.         self.panel = BugReportPanel(self.GetContentsPane(), callback)
  187.         self.panel.SetSizerProps(expand = True, proportion = 1)
  188.         self.callback = callback
  189.         self.SetButtonSizer(self.CreateStdDialogButtonSizer(wx.OK | wx.CANCEL))
  190.         button = self.FindWindowById(wx.ID_OK, self)
  191.         if button:
  192.             button.SetLabel(_('Submit'))
  193.         
  194.         if callback is not None:
  195.             self.Bind(wx.EVT_BUTTON, self.OnButton)
  196.         
  197.         self.Fit()
  198.         self.MinSize = self.Size
  199.  
  200.     
  201.     def OnButton(self, e):
  202.         e.Skip(False)
  203.         if e.Id == wx.ID_OK:
  204.             pass
  205.         submit = self.callback is not None
  206.         if submit and not (self.panel.input.Value):
  207.             wx.MessageBox(_('Please enter a description of the bug.\n\nInclude as much information as possible about\nwhat went wrong and how to reproduce the issue.'), _('Send Bug Report'))
  208.             return None
  209.         
  210.         try:
  211.             if submit:
  212.                 self.callback(self.panel.info())
  213.         finally:
  214.             self.Destroy()
  215.  
  216.  
  217.  
  218.  
  219. def resize_screenshot(img):
  220.     (w, h) = img.size
  221.     squaresize = 650
  222.     if w > h:
  223.         new_height = int((h / float(w)) * squaresize)
  224.         img = None(img.resize, (squaresize, new_height) if squaresize > w else ANTIALIAS)
  225.     else:
  226.         new_width = int((w / float(h)) * squaresize)
  227.         img = None(img.resize, (new_width, squaresize) if squaresize > h else ANTIALIAS)
  228.     return img
  229.  
  230.  
  231. class ScreenshotDialog(sc.SizedDialog):
  232.     
  233.     def __init__(self, parent, screenshot_full, screenshot, pos):
  234.         sc.SizedDialog.__init__(self, parent, -1, _('Submit Bug Report - Screenshot - Digsby'))
  235.         self.SetFrameIcon(skin.get('appdefaults.taskbaricon'))
  236.         self.big_screenshot_digsby = screenshot
  237.         self.screenshot_digsby = pil_to_wxb_nocache(resize_screenshot(screenshot))
  238.         self.big_screenshot_full = screenshot_full
  239.         self.screenshot_full = pil_to_wxb_nocache(resize_screenshot(screenshot_full))
  240.         self.screenshot = self.screenshot_digsby
  241.         self.hide_non_digsby = True
  242.         p = self.panel = self.GetContentsPane()
  243.         screenshot_panel = sc.SizedPanel(self.panel, -1)
  244.         screenshot_panel.SetMinSize((self.screenshot_full.Width, self.screenshot_full.Height + 20))
  245.         screenshot_panel.Bind(wx.EVT_PAINT, self.paint)
  246.         hpanel = sc.SizedPanel(self.panel, -1)
  247.         hpanel.SetSizerType('horizontal')
  248.         checkbox = wx.CheckBox(hpanel, -1, _('Blank out non Digsby windows'))
  249.         checkbox.SetValue(True)
  250.         checkbox.Bind(wx.EVT_CHECKBOX, self.OnCheckFullScreenShot)
  251.         checkbox.SetSizerProps(expand = True)
  252.         stretchpanel = sc.SizedPanel(hpanel, -1)
  253.         stretchpanel.SetSizerProps(expand = True, proportion = 1)
  254.         StaticText(hpanel, -1, _('Is it OK to send this screenshot to digsby.com?'))
  255.         self.SetButtonSizer(self.CreateStdDialogButtonSizer(wx.OK | wx.CANCEL))
  256.         self.Fit()
  257.         self.SetPosition(pos)
  258.  
  259.     
  260.     def SelectedScreenshot(self):
  261.         if self.hide_non_digsby:
  262.             return self.big_screenshot_digsby
  263.         return self.big_screenshot_full
  264.  
  265.     SelectedScreenshot = property(SelectedScreenshot)
  266.     
  267.     def OnCheckFullScreenShot(self, e):
  268.         self.hide_non_digsby = e.IsChecked()
  269.         self.Refresh()
  270.  
  271.     
  272.     def paint(self, e):
  273.         dc = wx.PaintDC(e.EventObject)
  274.         screenshot = None if self.hide_non_digsby else self.screenshot_full
  275.         dc.DrawBitmap(screenshot, 10, 10, True)
  276.  
  277.  
  278.  
  279. class ScreenshotTimer(wx.Timer):
  280.     
  281.     def __init__(self, secs, on_tick, on_done):
  282.         wx.Timer.__init__(self)
  283.         self.secs = secs
  284.         self.tick = on_tick
  285.         self.done = on_done
  286.  
  287.     
  288.     def Start(self):
  289.         self.count = self.secs
  290.         wx.Timer.Start(self, 1000, False)
  291.         self.tick(self.count)
  292.  
  293.     
  294.     def Notify(self):
  295.         self.count -= 1
  296.         self.tick(self.count)
  297.  
  298.  
  299.  
  300. HSizer = lambda : BoxSizer(HORIZONTAL)
  301.  
  302. VSizer = lambda : BoxSizer(VERTICAL)
  303. import gui.wxextensions as gui
  304.  
  305. def app_windows_image():
  306.     rect = reduce(wx.Rect.Union, (lambda .0: for m in .0:
  307. m.Geometry)(Monitor.All()))
  308.     if 'wxMSW' in wx.PlatformInfo:
  309.         screen = getScreenBitmap(rect).PIL
  310.     else:
  311.         screen = wx.ScreenDC().GetAsBitmap().PIL
  312.     mask = Image.new('RGBA', rect.Size, (255, 255, 255, 255))
  313.     
  314.     drawrect = lambda r: ImageDraw.Draw(mask).rectangle([
  315. r.x,
  316. r.y,
  317. r.Right,
  318. r.Bottom], fill = (0, 0, 0, 0))
  319.     for w in wx.GetTopLevelWindows():
  320.         if w.IsShown():
  321.             continue
  322.         _[1][w.Rect]
  323.     
  324.     screen_full = screen.copy()
  325.     screen.paste(mask, (0, 0), mask)
  326.     return (screen_full, screen)
  327.  
  328. if __name__ == '__main__':
  329.     import gettext
  330.     gettext.install('Digsby')
  331.     from tests.testapp import testapp
  332.     a = testapp('../../..')
  333.     f = wx.Frame(None, pos = (50, 50))
  334.     f.Show()
  335.     f = wx.Frame(None, pos = (10050, 80))
  336.     f.Show()
  337.     f = wx.Frame(None, pos = (400, 300))
  338.     f.Show()
  339.     print show_dialog()
  340.  
  341.