home *** CD-ROM | disk | FTP | other *** search
- # Source Generated with Decompyle++
- # File: in.pyo (Python 2.6)
-
- from __future__ import with_statement
- from wx import PyDeadObjectError
-
- try:
- _
- except:
- import gettext
- gettext.install('Digsby')
-
- import wx
- import hooks
- from wx.lib import pubsub
- import config
- from gui import skin
- from gui.uberwidgets.uberbook.tabmanager import TabWindowManager
- from gui.uberwidgets.uberbook.UberBook import NoteBook
- from gui.toolbox import draw_tiny_text
- from PIL import Image
- from gui.windowfx import fadein
- from common import setpref, pref, profile, bind, prefprop
- from util import traceguard, default_timer
- from util.primitives.structures import oset
- from util.primitives.funcs import Delegate
- from gui.uberwidgets.UberEvents import EVT_TAB_NOTIFIED
- from gui.toolbox import saveWindowPos, preLoadWindowPos, snap_pref
- from gui.native import memory_event
- IMWIN_STAT_IDLE_TIME = 5 * 60 * 1000
- IMFRAME_MINSIZE = (320, 220)
- CLOSETABS_TITLE = _('Close IM Window')
- CHECKBOX_TEXT = _('Warn me when I attempt to close multiple conversations')
- CLOSETABS_MSG = _('You are about to close %d conversations. Are you sure you want to continue?')
- CLOSE_BUTTON_TEXT = _('Close &tabs')
- WARN_PREF = 'messaging.tabs.warn_on_close'
- IMWIN_ALWAYS_ON_TOP_PREF = 'conversation_window.always_on_top'
-
- def explodeAllWindows():
- ImFrame = ImFrame
- import gui.imwin.imtabs
- newtabs = 0
- for win in (lambda .0: for w in .0:
- if isinstance(w, ImFrame):
- wcontinue)(wx.GetTopLevelWindows()):
- for page in win.notebook.Pages()[1:]:
- newtabs += 1
- pos = wx.Point(30, 30) + (20 * newtabs, 20 * newtabs)
- win.notebook.Remove(page)
- newwin = win.notebook.winman.NewWindow(pos)
- newwin.notebook.Insert(page)
-
- win.notebook.Refresh()
-
-
-
- class CloseTabsDialog(wx.Dialog):
-
- def WarnMe(self):
- return self.panel.warn_cb.Value
-
- WarnMe = property(WarnMe)
-
- def __init__(self, parent, num_tabs, warn_value = True):
- wx.Dialog.__init__(self, parent, title = CLOSETABS_TITLE)
- self.panel = CloseTabsPanel(self, num_tabs, warn_value)
- self.Sizer = wx.BoxSizer(wx.VERTICAL)
- self.Sizer.Add(self.panel, 1, wx.EXPAND)
- self.Fit()
-
-
-
- class CloseTabsPanel(wx.Panel):
-
- def __init__(self, parent, num_tabs, warnme_value = True):
- wx.Panel.__init__(self, parent)
- self.Bind(wx.EVT_PAINT, self.OnPaint)
- self.warn_cb = warn_cb = wx.CheckBox(self, -1, CHECKBOX_TEXT)
- warn_cb.SetValue(warnme_value)
- msgsizer = wx.BoxSizer(wx.VERTICAL)
- self.close_msg = wx.StaticText(self, -1, CLOSETABS_MSG % num_tabs)
- msgsizer.Add(self.close_msg, 0, wx.EXPAND | wx.SOUTH, 8)
- msgsizer.Add(warn_cb, 0, wx.EXPAND)
- h = wx.BoxSizer(wx.HORIZONTAL)
- self.bitmap = wx.ArtProvider.GetBitmap(wx.ART_QUESTION)
- self.bitmap.SetMaskColour(wx.BLACK)
- h.Add((self.bitmap.Width, self.bitmap.Height), 0, wx.EXPAND | wx.ALL, 9)
- h.Add(msgsizer, 0, wx.EXPAND | wx.ALL, 12)
- close_button = wx.Button(self, wx.ID_OK, CLOSE_BUTTON_TEXT)
- close_button.SetDefault()
- close_button.SetFocus()
- cancel_button = wx.Button(self, wx.ID_CANCEL, _('&Cancel'))
- buttonsizer = wx.BoxSizer(wx.HORIZONTAL)
- buttonsizer.AddStretchSpacer(1)
- buttonsizer.Add(close_button, 0, wx.RIGHT, 6)
- buttonsizer.Add(cancel_button)
- buttonsizer.AddStretchSpacer(1)
- s = self.Sizer = wx.BoxSizer(wx.VERTICAL)
- s.Add(h, 0, wx.EXPAND | wx.ALL)
- s.Add(buttonsizer, 0, wx.EXPAND | wx.BOTTOM, 12)
-
-
- def OnPaint(self, e):
- dc = wx.PaintDC(self)
- pos = self.close_msg.Position
- dc.DrawBitmap(self.bitmap, pos.x - self.bitmap.Width - 10, pos.y, True)
-
-
- from gui.native.toplevel import FlashOnce, Flash
-
- class TitleBarTimer(wx.Timer):
- shouldFlash = prefprop('conversation_window.notify_flash')
- cyclePause = prefprop('conversation_window.unread_cycle_pause')
-
- def __init__(self, win, tabs):
- wx.Timer.__init__(self)
- self.win = win
- self.tabs = tabs
- self.index = 0
-
-
- def Start(self):
- self.title = self.win.Title
- wx.Timer.Start(self, self.cyclePause)
-
-
- def Notify(self):
- win = self.win
- tabs = self.tabs
- if wx.IsDestroyed(win):
- self.Stop()
- return None
- if not win.IsActive() and len(tabs):
- tabNum = len(tabs)
- if self.index >= tabNum:
- self.index = 0
-
- tab = tabs[self.index]
- if not wx.IsDestroyed(tab):
- win.SetTitle('*' + tab.label1)
- self.index += 1
- else:
- tabs.remove(tab)
- if self.shouldFlash:
- FlashOnce(win)
-
- else:
- self.Stop()
-
-
- def Stop(self):
- wx.Timer.Stop(self)
- if not wx.IsDestroyed(self.win):
- self.win.SetTitle(self.title)
-
- self.index = 0
-
-
-
- class SkinnedNotebookPanel(wx.Panel):
-
- def __init__(self, *args, **kwargs):
- preview = kwargs.pop('preview', None)
- wx.Panel.__init__(self, *args, **kwargs)
- self.notebook = NoteBook(self, skinkey = 'Tabs', preview = preview)
- sz = self.Sizer = wx.BoxSizer(wx.VERTICAL)
- sz.Add(self.notebook, 1, wx.EXPAND)
-
-
-
- class SkinnedIMFrameEventHandler(wx.EvtHandler):
-
- def __init__(self, frame):
- wx.EvtHandler.__init__(self)
- self.frame = frame
- self.notebook = self.frame.notebookPanel.notebook
- self.mergetimer = None
- self.notifiedtabs = oset()
- self.titletimer = TitleBarTimer(self.frame, self.notifiedtabs)
- self.BindEventsToFrame()
-
-
- def BindEventsToFrame(self):
- Bind = self.frame.Bind
- Bind(wx.EVT_CLOSE, self.OnClose)
- Bind(wx.EVT_MOVE, self.OnMove)
- Bind(wx.EVT_SIZE, self.OnSize)
- Bind(wx.EVT_ACTIVATE, self.OnActivate)
- Bind(EVT_TAB_NOTIFIED, self.OnTabNotify)
- publisher = pubsub.Publisher()
- publisher.subscribe(self.OnPageTitleUpdated, 'tab.title.updated')
- publisher.subscribe(self.OnPageIconUpdated, 'tab.icon.updated')
-
-
- def OnClose(self, event):
- if self.frame.CloseAndSaveState(event):
- self.frame.Destroy()
- else:
- event.Veto()
-
-
- def OnActivate(self, e):
- e.Skip()
- if e.GetActive():
- tab = self.notebook.ActiveTab
- if tab is not None:
- tab.SetNotify(False)
- tab.page.Content.FocusTextCtrl()
-
-
- if self.titletimer.IsRunning():
- self.titletimer.Stop()
-
-
-
- def OnPageIconUpdated(self, message):
- (page, icon) = message.data
- if not (self.frame) or wx.IsDestroyed(self.frame):
- return None
- for mypage in self.frame.notebook.Pages():
- if mypage == page and self.frame.notebook.ActiveTab == mypage.tab:
- self.frame.SetFrameIcon(icon)
- continue
- wx.IsDestroyed(self.frame)
-
-
-
- def OnPageTitleUpdated(self, message):
- if not (self.frame) or wx.IsDestroyed(self.frame):
- return None
- (imwin, title, window_title) = message.data
- imwin.SetName(title)
- page = None
- for mypage in self.frame.notebook.Pages():
- if mypage.Content is imwin:
- page = mypage
- continue
- wx.IsDestroyed(self.frame)
-
- if page is None or page.tab is not self.frame.notebook.ActiveTab:
- return None
- if window_title is not None:
- frame_title = window_title
- else:
- frame_title = title
- if self.titletimer.IsRunning():
- self.titletimer.title = frame_title
- else:
- self.frame.SetTitle(frame_title)
-
- flashTime = prefprop('conversation_window.flash_time')
- flashCount = prefprop('conversation_window.flash_count')
-
- def OnTabNotify(self, event):
- tab = event.tab
- if tab.notified:
- self.notifiedtabs.add(tab)
- notify_unread_message_hook()
- elif tab in self.notifiedtabs:
- self.notifiedtabs.remove(tab)
- notify_unread_message_hook()
- return None
- return None
- if not self.frame.cycleTitle:
- if self.frame.shouldFlash:
- Flash(self.frame, timeout = self.flashTime, count = self.flashCount)
-
- return None
- if len(self.notifiedtabs) and not self.frame.IsActive():
- if not self.titletimer.IsRunning():
- self.titletimer.Start()
-
- elif self.titletimer.IsRunning():
- self.titletimer.Stop()
-
-
-
- def OnMove(self, event):
- event.Skip(True)
- if pref('messaging.tabs.enabled', True):
- mt = self.mergetimer
- if mt is None:
- self.mergetimer = wx.CallLater(10, self.notebook.StartWindowDrag)
- else:
- mt.Start(10)
-
- event.Skip(True)
-
-
- def OnSize(self, event):
- mt = self.mergetimer
- if mt is not None:
- mt.Stop()
-
- event.Skip(True)
-
-
- highlight_color = wx.Color(255, 214, 72)
- _highlight_bitmap = None
-
- def get_highlight_bitmap():
- global _highlight_bitmap
- if _highlight_bitmap is None:
- import PIL.Image as PIL
- _highlight_bitmap = PIL.Image.new('RGBA', (5, 5), (226, 214, 139, 255)).WXB
-
- return _highlight_bitmap
-
- if config.platform == 'win':
- from gui.uberwidgets.uberbook.UberBook import UberBookTabController
- from gui.buddylist.renderers import get_buddy_icon
-
- def icon_for_tab(tab, width, height):
- window = tab.Window
- if window.ischat:
- return skin.get('actionsbar.icons.roomlist')
- buddy = window.Buddy
- notified = window.Tab.notified
- icon = get_buddy_icon(buddy, size = height, round_size = 0, grey_offline = True, meta_lookup = True)
- return icon.WXB
-
-
- class ImTabController(UberBookTabController):
-
- def GetSmallIcon(self, tab):
- bitmap = im_badge(tab.Window)
- window = tab.Window
- if not (window.ischat) and bitmap is None:
- bitmap = skin.get('statusicons.' + tab.Window.Buddy.status_orb, None).Resized((16, 16))
- elif window.ischat:
- bitmap = window.chat_icon
-
- if bitmap is not None:
- return wx.IconFromBitmap(bitmap.WXB)
- return wx.IconFromBitmap(wx.NullBitmap)
-
-
- def GetIconicHBITMAP(self, tab, width, height):
- import cgui
- icon = icon_for_tab(tab, width, height)
- notified = tab.Window.Tab.notified
- highlight = None if notified else wx.NullBitmap
- if icon is not None:
- return cgui.getBuddyPreview((width, height), icon, highlight)
-
-
- def GetLivePreview(self, tab, rect):
- overlay = skin.get('AppDefaults.TaskBarIcon')
- bitmap = wx.EmptyBitmap(rect.width, rect.height, False)
- dc = wx.MemoryDC(bitmap)
- overlay.Resized(1).Draw(dc, wx.Rect(0, 0, 1, 1))
- dc.SelectObject(wx.NullBitmap)
- return bitmap
-
-
-
-
- class ImFrame(wx.Frame):
- WindowName = u'IM Window'
-
- def __init__(self, pos = None, size = None, startMinimized = False, posId = ''):
- if pref('imwin.ads', type = bool, default = False):
- defaultSize = wx.Size(490, 470)
- else:
- defaultSize = wx.Size(470, 390)
- (wininfo, placement) = preLoadWindowPos(ImFrame.WindowName, uniqueId = posId, defaultPos = wx.Point(200, 200), defaultSize = defaultSize)
- wininfo['style'] |= wx.DEFAULT_FRAME_STYLE
- setPos = pos is not None
- setSize = size is not None
- if setPos or setSize:
- wininfo['style'] &= ~(wx.MAXIMIZE)
-
- if startMinimized:
- wininfo['style'] |= wx.ICONIZE
- self._starting_minimized = True
-
- if pref('imwin.ads', default = False):
- wininfo['style'] |= wx.FULL_REPAINT_ON_RESIZE
-
- wx.Frame.__init__(self, parent = None, name = ImFrame.WindowName, **wininfo)
- self.on_engaged_start = Delegate()
- self.on_engaged_end = Delegate()
- self.on_sent_message = Delegate()
- if config.nativeIMWindow:
- import gui.imwin.imwin_native as gui
- self.notebookPanel = gui.imwin.imwin_native.NativeNotebookPanel(self, -1)
- self.eventHandler = gui.imwin.imwin_native.NativeIMFrameEventHandler(self)
- else:
- preview = None
- if config.platform == 'win':
- preview = ImTabController
-
- self.notebookPanel = SkinnedNotebookPanel(self, -1, preview = preview)
- self.eventHandler = SkinnedIMFrameEventHandler(self)
- self.notebook.winman = TabWindowManager((lambda pos, size = None: ImFrame(pos = pos, size = size)))
- if placement is not None:
- if not setPos:
- pass
- if setPos:
- self.Position = pos
-
- if setSize:
- self.Size = size
-
- if not config.nativeIMWindow:
- self.SetBackgroundStyle(wx.BG_STYLE_CUSTOM)
-
- self.posId = posId
- self.EnsureInScreen()
- if pos is not None:
- wx.CallAfter(self.EnsureNotStacked)
-
- profile.prefs.link(IMWIN_ALWAYS_ON_TOP_PREF, self.on_always_on_top, callnow = not startMinimized)
- snap_pref(self)
- self.iconizecallbacks = set()
- Bind = self.Bind
- Bind(wx.EVT_ICONIZE, self.OnIconize)
- memory_event()
-
- def gainfocus(e):
- if e.Active:
- self._startengage()
- else:
- self._endengage()
- e.Skip()
-
- Bind(wx.EVT_ACTIVATE, gainfocus)
- self.register_hooks()
-
-
- def register_hooks(self):
- if getattr(ImFrame, 'did_register_hooks', False):
- return None
- ImFrame.did_register_hooks = True
- ImFrame.engage_is_idle = False
-
- def goidle():
- ImFrame.engage_is_idle = True
- for win in all_imframes():
- win._endengage()
-
- return True
-
-
- def unidle():
- ImFrame.engage_is_idle = False
- for win in all_imframes():
- if win.IsActive():
- win._startengage()
- continue
-
- return True
-
-
- def idle_ms(ms_idle_time):
- if not (ImFrame.engage_is_idle) and ms_idle_time > IMWIN_STAT_IDLE_TIME:
- goidle()
- elif ImFrame.engage_is_idle and ms_idle_time < IMWIN_STAT_IDLE_TIME:
- unidle()
-
- return 15000
-
- hooks.register('digsby.app.idle', idle_ms)
- import cgui
- if config.platform == 'win' and cgui.isWin7OrHigher():
- set_overlay_icon = set_overlay_icon
- get_tab_notebook = get_tab_notebook
- import gui.native.win.taskbar
-
- def icon_updated(imwin):
- get_tab_notebook(imwin.Top).InvalidateThumbnails(imwin)
-
- def later():
- if wx.IsDestroyed(imwin):
- return None
- set_overlay_icon(im_badge(), tlw = imwin.Top)
-
- wx.CallLater(300, later)
-
- hooks.register('digsby.overlay_icon_updated', icon_updated)
-
-
-
- def _startengage(self):
- self._endengage()
- self.start_time = default_timer()
- self.on_engaged_start()
-
-
- def _endengage(self):
- if hasattr(self, 'start_time'):
- diff = max(int(default_timer() - self.start_time), 0)
- del self.start_time
- hooks.notify('digsby.statistics.imwin.imwin_engage', diff)
- self.on_engaged_end()
-
-
- cycleTitle = prefprop('conversation_window.cycle_unread_ims')
- shouldFlash = prefprop('conversation_window.notify_flash')
-
- def OnIconize(self, event = None):
- if event is not None:
- event.Skip()
-
- if not event.Iconized() and not (self.OnTop) and pref(IMWIN_ALWAYS_ON_TOP_PREF, False):
- self.OnTop = True
-
- for callback in set(self.iconizecallbacks):
-
- try:
- callback()
- continue
- except PyDeadObjectError:
- self.iconizecallbacks.remove(callback)
- continue
-
-
-
-
-
- def notebook(self):
- if hasattr(self, 'notebookPanel') and self.notebookPanel:
- return self.notebookPanel.notebook
-
- notebook = property(notebook)
-
- def AnyNotified(self):
- return any((lambda .0: for iwin in .0:
- iwin.Tab.notified)(self))
-
- AnyNotified = property(AnyNotified)
-
- def __iter__(self):
- if config.nativeIMWindow:
- pass
-
- return iter((lambda .0: for p in .0:
- p.Content)(self.notebook.Pages()))
-
-
- def __getitem__(self, n):
- if config.nativeIMWindow:
- pass
-
- return self.notebook.Pages()[n].Content
-
-
- def GetTabCount(self):
- return self.notebook.GetTabCount()
-
-
- def AddTab(self, ctrl, focus = None):
- return self.notebook.Add(ctrl, focus = focus)
-
-
- def CloseTabIfNotLast(self):
- if self.notebook.GetTabCount() > 1:
- tab = self.notebook.ActiveTab
- self.notebook.CloseTab(tab)
-
-
- CloseTabIfNotLast = bind('ImFrame.Tabs.CloseIfNotLast')(CloseTabIfNotLast)
-
- def CloseActiveTab(self):
- tab = self.notebook.ActiveTab
- self.notebook.CloseTab(tab)
- if self.notebook.GetTabCount() < 1:
- self.Close()
-
-
- CloseActiveTab = bind('ImFrame.Tabs.CloseActive')(CloseActiveTab)
-
- def NextTab(self):
- self.notebook.NextTab()
-
- NextTab = bind('ImFrame.Tabs.NextTab')(NextTab)
-
- def PrevTab(self):
- self.notebook.PrevTab()
-
- PrevTab = bind('ImFrame.Tabs.PrevTab')(PrevTab)
-
- def IncreaseTextSize(self):
- self.ActiveMessageArea.IncreaseTextSize()
-
- IncreaseTextSize = bind('ImFrame.ChatWindow.IncreaseTextSize')(IncreaseTextSize)
-
- def DescreaseTextSize(self):
- self.ActiveMessageArea.DecreaseTextSize()
-
- DescreaseTextSize = bind('ImFrame.ChatWindow.DecreaseTextSize')(DescreaseTextSize)
-
- def ResetTextSize(self):
- self.ActiveMessageArea.ResetTextSize()
-
- ResetTextSize = bind('ImFrame.ChatWindow.ResetTextSize')(ResetTextSize)
-
- def ActiveMessageArea(self):
- return self.notebook.ActiveTab.page.Content.message_area
-
- ActiveMessageArea = property(ActiveMessageArea)
-
- def CloseAndSaveState(self, e):
- tabcount = self.GetTabCount()
- self.Hide()
- saveWindowPos(self, uniqueId = self.posId)
- if not config.nativeIMWindow:
- for page in self.notebook.Pages():
- page.Children[0].on_close()
-
-
- memory_event()
- return True
-
-
- def __repr__(self):
- return '<%s %s>' % (self.__class__.__name__, id(self))
-
-
- def on_always_on_top(self, val):
- self.OnTop = val
-
-
- def UpdateSkin(self):
- wx.CallAfter(self.Layout)
-
-
-
- def newIMWindow(pos, size):
- win = ImFrame(pos, size)
- win.Show(False)
- fadein(win, 'normal')
- return win
-
-
- def all_imframes():
- return _[1]
-
-
- def notify_unread_message_hook():
- hooks.notify('digsby.im.unread_messages_changed')
-
-
- def all_unread_convos():
- imwins = []
- for imframe in all_imframes():
- imwins.extend((lambda .0: for tab in .0:
- tab.page.panel)(imframe.eventHandler.notifiedtabs))
-
- return imwins
-
-
- def im_badge(specific_page = None):
- imwins = []
- typing_statuses = dict((lambda .0: for i, s in .0:
- (s, i))(enumerate([
- None,
- 'typed',
- 'typing'])))
- max_typing = None
- unread_count = 0
- needs_bubbles = False
- if specific_page is None:
- for imframe in all_imframes():
- notified_wins = set((lambda .0: for tab in .0:
- tab.page.panel)(imframe.eventHandler.notifiedtabs))
- for page in imframe.notebook.Pages():
- imwin = page.panel
- if typing_statuses[imwin.typing] > typing_statuses[max_typing]:
- max_typing = imwin.typing
-
- if imwin in notified_wins:
- unread_count += 1
- continue
-
-
- else:
- max_typing = specific_page.typing
- needs_bubbles = specific_page.Notified
- bubble_icon = None
- if max_typing is not None:
- bubble_icon = skin.get('statusicons.' + max_typing, None)
-
- if bubble_icon is None:
- if (unread_count or specific_page is not None) and needs_bubbles:
- bubble_icon = skin.get('AppDefaults.UnreadMessageIcon', None)
-
- if bubble_icon is not None:
- bubble_icon = bubble_icon.PIL.ResizeCanvas(16, 16)
-
- if unread_count:
- if bubble_icon is None:
- bubble_icon = Image.new('RGBA', (16, 16))
-
- bubble_icon = draw_tiny_text(bubble_icon, str(unread_count))
-
- if specific_page is None and bubble_icon is not None:
- bubble_icon = bubble_icon.WXB
-
- return bubble_icon
-
- from gui.input import add_class_context
- add_class_context(_('IM Windows'), 'ImFrame', cls = ImFrame)
-