wxversion.select(WX_GOOD)\r
\r
import copy\r
+import os\r
import os.path\r
import platform\r
import shutil\r
from ...config import Setting\r
from ...interaction import Request, BooleanRequest, ReloadUserInterfaceConfig\r
from ...ui import UserInterface, CommandMessage\r
+from .dialog.selection import Selection as SelectionDialog\r
+from .dialog.save_file import select_save_file\r
from . import menu as menu\r
from . import navbar as navbar\r
from . import panel as panel\r
'view_panel': self._on_panel_visibility,\r
'save_perspective': self._on_save_perspective,\r
'delete_perspective': self._on_delete_perspective,\r
+ 'select_perspective': self._on_select_perspective,\r
})\r
self.SetMenuBar(self._c['menu bar'])\r
\r
style=wx.ST_SIZEGRIP)\r
self.SetStatusBar(self._c['status bar'])\r
\r
- self._update_perspectives()\r
+ self._setup_perspectives()\r
self._bind_events()\r
\r
name = self.gui.config['active perspective']\r
return index\r
return -1\r
\r
- def _restore_perspective(self, name):\r
- # TODO: cleanup\r
- self.gui.config['active perspective'] = name # TODO: push to engine's Hooke\r
- self._c['manager'].LoadPerspective(self._perspectives[name])\r
- self._c['manager'].Update()\r
- for pane in self._c['manager'].GetAllPanes():\r
- if pane.name in self._c['menu bar']._c['view']._c.keys():\r
- pane.Check(pane.window.IsShown())\r
-\r
- def _SavePerspectiveToFile(self, name, perspective):\r
- filename = ''.join([name, '.txt'])\r
- filename = lh.get_file_path(filename, ['perspective'])\r
- perspectivesFile = open(filename, 'w')\r
- perspectivesFile.write(perspective)\r
- perspectivesFile.close()\r
-\r
def select_plugin(self, _class=None, method=None, plugin=None):\r
for option in config[section]:\r
properties.append([option, config[section][option]])\r
del self._c['manager']\r
self.Destroy()\r
\r
- def _update_perspectives(self):\r
+ def _setup_perspectives(self):\r
"""Add perspectives to menubar and _perspectives.\r
"""\r
self._perspectives = {\r
files = sorted(os.listdir(path))\r
for fname in files:\r
name, extension = os.path.splitext(fname)\r
- if extension != '.txt':\r
+ if extension != self.gui.config['perspective extension']:\r
continue\r
- fpath = os.path.join(path, fpath)\r
+ fpath = os.path.join(path, fname)\r
if not os.path.isfile(fpath):\r
continue\r
perspective = None\r
if not self._perspectives.has_key(selected_perspective):\r
self.gui.config['active perspective'] = 'Default' # TODO: push to engine's Hooke\r
\r
- self._update_perspective_menu()\r
self._restore_perspective(selected_perspective)\r
+ self._update_perspective_menu()\r
\r
def _update_perspective_menu(self):\r
self._c['menu bar']._c['perspective'].update(\r
sorted(self._perspectives.keys()),\r
- self.gui.config['active perspective'],\r
- self._on_restore_perspective)\r
-\r
- def _on_restore_perspective(self, event):\r
- name = self._c['menu bar'].FindItemById(event.GetId()).GetLabel()\r
+ self.gui.config['active perspective'])\r
+\r
+ def _save_perspective(self, perspective, perspective_dir, name,\r
+ extension=None):\r
+ path = os.path.join(perspective_dir, name)\r
+ if extension != None:\r
+ path += extension\r
+ if not os.path.isdir(perspective_dir):\r
+ os.makedirs(perspective_dir)\r
+ with open(path, 'w') as f:\r
+ f.write(perspective)\r
+ self._perspectives[name] = perspective\r
self._restore_perspective(name)\r
+ self._update_perspective_menu()\r
\r
- def _on_save_perspective(self, event):\r
- def nameExists(name):\r
- menu_position = self._c['menu bar'].FindMenu('Perspective')\r
- menu = self._c['menu bar'].GetMenu(menu_position)\r
- for item in menu.GetMenuItems():\r
- if item.GetText() == name:\r
- return True\r
- return False\r
-\r
- done = False\r
- while not done:\r
- dialog = wx.TextEntryDialog(self, 'Enter a name for the new perspective:', 'Save perspective')\r
- dialog.SetValue('New perspective')\r
- if dialog.ShowModal() != wx.ID_OK:\r
- return\r
- else:\r
- name = dialog.GetValue()\r
-\r
- if nameExists(name):\r
- dialogConfirm = wx.MessageDialog(self, 'A file with this name already exists.\n\nDo you want to replace it?', 'Confirm', wx.YES_NO|wx.ICON_QUESTION|wx.CENTER)\r
- if dialogConfirm.ShowModal() == wx.ID_YES:\r
- done = True\r
- else:\r
- done = True\r
+ def _delete_perspectives(self, perspective_dir, names,\r
+ extension=None):\r
+ print 'pop', names\r
+ for name in names:\r
+ path = os.path.join(perspective_dir, name)\r
+ if extension != None:\r
+ path += extension\r
+ os.remove(path)\r
+ del(self._perspectives[name])\r
+ self._update_perspective_menu()\r
+ if self.gui.config['active perspective'] in names:\r
+ self._restore_perspective('Default')\r
+ # TODO: does this bug still apply?\r
+ # Unfortunately, there is a bug in wxWidgets for win32 (Ticket #3258\r
+ # http://trac.wxwidgets.org/ticket/3258 \r
+ # ) that makes the radio item indicator in the menu disappear.\r
+ # The code should be fine once this issue is fixed.\r
\r
+ def _restore_perspective(self, name):\r
+ if name != self.gui.config['active perspective']:\r
+ print 'restoring perspective:', name\r
+ self.gui.config['active perspective'] = name # TODO: push to engine's Hooke\r
+ self._c['manager'].LoadPerspective(self._perspectives[name])\r
+ self._c['manager'].Update()\r
+ for pane in self._c['manager'].GetAllPanes():\r
+ if pane.name in self._c['menu bar']._c['view']._c.keys():\r
+ pane.Check(pane.window.IsShown())\r
+\r
+ def _on_save_perspective(self, *args):\r
perspective = self._c['manager'].SavePerspective()\r
- self._SavePerspectiveToFile(name, perspective)\r
- self.gui.config['active perspectives'] = name\r
- self._update_perspective_menu()\r
-# if nameExists(name):\r
-# #check the corresponding menu item\r
-# menu_item = self.GetPerspectiveMenuItem(name)\r
-# #replace the perspectiveStr in _pespectives\r
-# self._perspectives[name] = perspective\r
-# else:\r
-# #because we deal with radio items, we need to do some extra work\r
-# #delete all menu items from the perspectives menu\r
-# for item in self._perspectives_menu.GetMenuItems():\r
-# self._perspectives_menu.DeleteItem(item)\r
-# #recreate the perspectives menu\r
-# self._perspectives_menu.Append(ID_SavePerspective, 'Save Perspective')\r
-# self._perspectives_menu.Append(ID_DeletePerspective, 'Delete Perspective')\r
-# self._perspectives_menu.AppendSeparator()\r
-# #convert the perspectives dictionary into a list\r
-# # the list contains:\r
-# #[0]: name of the perspective\r
-# #[1]: perspective\r
-# perspectives_list = [key for key, value in self._perspectives.iteritems()]\r
-# perspectives_list.append(name)\r
-# perspectives_list.sort()\r
-# #add all previous perspectives\r
-# for index, item in enumerate(perspectives_list):\r
-# menu_item = self._perspectives_menu.AppendRadioItem(ID_FirstPerspective + index, item)\r
-# if item == name:\r
-# menu_item.Check()\r
-# #add the new perspective to _perspectives\r
-# self._perspectives[name] = perspective\r
-\r
- def _on_delete_perspective(self, event):\r
- dialog = panel.selection.Selection(\r
- options=sorted(os.listdir(self.gui.config['perspective path'])),\r
+ name = self.gui.config['active perspective']\r
+ if name == 'Default':\r
+ name = 'New perspective'\r
+ name = select_save_file(\r
+ directory=self.gui.config['perspective path'],\r
+ name=name,\r
+ extension=self.gui.config['perspective extension'],\r
+ parent=self,\r
+ message='Enter a name for the new perspective:',\r
+ caption='Save perspective')\r
+ if name == None:\r
+ return\r
+ self._save_perspective(\r
+ perspective, self.gui.config['perspective path'], name=name,\r
+ extension=self.gui.config['perspective extension'])\r
+\r
+ def _on_delete_perspective(self, *args, **kwargs):\r
+ options = sorted([p for p in self._perspectives.keys()\r
+ if p != 'Default'])\r
+ dialog = SelectionDialog(\r
+ options=options,\r
message="\nPlease check the perspectives\n\nyou want to delete and click 'Delete'.\n",\r
button_id=wx.ID_DELETE,\r
- callbacks={'button': self._on_delete_perspective},\r
selection_style='multiple',\r
parent=self,\r
- label='Delete perspective(s)',\r
+ title='Delete perspective(s)',\r
style=wx.DEFAULT_DIALOG_STYLE | wx.RESIZE_BORDER)\r
dialog.CenterOnScreen()\r
dialog.ShowModal()\r
+ names = [options[i] for i in dialog.selected]\r
dialog.Destroy()\r
- self._update_perspective_menu()\r
- # Unfortunately, there is a bug in wxWidgets for win32 (Ticket #3258\r
- # http://trac.wxwidgets.org/ticket/3258 \r
- # ) that makes the radio item indicator in the menu disappear.\r
- # The code should be fine once this issue is fixed.\r
+ self._delete_perspectives(\r
+ self.gui.config['perspective path'], names=names,\r
+ extension=self.gui.config['perspective extension'])\r
\r
- def _on_delete_perspective(self, _class, method, options, selected):\r
- for p in selected:\r
- self._perspectives.remove(p)\r
- if p == self.gui.config['active perspective']:\r
- self.gui.config['active perspective'] = 'Default'\r
- path = os.path.join(self.gui.config['perspective path'],\r
- p+'.txt')\r
- remove(path)\r
- self._update_perspective_menu()\r
+ def _on_select_perspective(self, _class, method, name):\r
+ self._restore_perspective(name)\r
\r
def _on_dir_ctrl_left_double_click(self, event):\r
file_path = self.panelFolders.GetPath()\r
notebook.SetSelection(index)\r
notebook.DeletePage(notebook.GetSelection())\r
self.Parent.DeleteFromPlaylists(playlist_name)\r
- \r
+\r
\r
class HookeApp (wx.App):\r
"""A :class:`wx.App` wrapper around :class:`HookeFrame`.\r
return True\r
\r
def _setup_splash_screen(self):\r
- if self.gui.config['show splash screen']:\r
+ if self.gui.config['show splash screen'] == 'True': # HACK: config should decode\r
+ print 'splash', self.gui.config['show splash screen']\r
path = self.gui.config['splash screen image']\r
if os.path.isfile(path):\r
duration = int(self.gui.config['splash screen duration']) # HACK: config should decode types\r
Setting(section=self.setting_section, option='perspective path',\r
value=os.path.join('resources', 'gui', 'perspective'),\r
help='Directory containing perspective files.'), # TODO: allow colon separated list, like $PATH.\r
+ Setting(section=self.setting_section, option='perspective extension',\r
+ value='.txt',\r
+ help='Extension for perspective files.'),\r
Setting(section=self.setting_section, option='hide extensions',\r
value=False,\r
help='Hide file extensions when displaying names.'),\r
"""\r
\r
from os import remove\r
+import types\r
\r
import wx\r
\r
.. _standard wx IDs:\r
http://docs.wxwidgets.org/stable/wx_stdevtid.html#stdevtid\r
"""\r
- def __init__(self, options, message, button_id, callbacks,\r
+ def __init__(self, options, message, button_id, callbacks=None,\r
default=None, selection_style='single', *args, **kwargs):\r
super(Selection, self).__init__(*args, **kwargs)\r
\r
self._options = options\r
+ if callbacks == None:\r
+ callbacks = {}\r
self._callbacks = callbacks\r
self._selection_style = selection_style\r
\r
size = wx.Size(175, 200)\r
if selection_style == 'single':\r
self._c['listbox'] = wx.ListBox(\r
- parent=self, size=size, list=options)\r
+ parent=self, size=size, choices=options)\r
if default != None:\r
self._c['listbox'].SetSelection(default)\r
else:\r
assert selection_style == 'multiple', selection_style\r
self._c['listbox'] = wx.CheckListBox(\r
- parent=self, size=size, list=options)\r
+ parent=self, size=size, choices=options)\r
if default != None:\r
self._c['listbox'].Check(default)\r
self.Bind(wx.EVT_BUTTON, self.button, self._c['button'])\r
self.Bind(wx.EVT_BUTTON, self.cancel, self._c['cancel'])\r
\r
- border_width = 5\r
-\r
b = wx.BoxSizer(wx.HORIZONTAL)\r
- b.Add(window=self._c['button'],\r
- flag=wx.GROW|wx.ALIGN_CENTER_VERTICAL|wx.ALL,\r
- border=border_width)\r
- b.Add(window=self._c['cancel'],\r
- flag=wx.GROW|wx.ALIGN_CENTER_VERTICAL|wx.ALL,\r
- border=border_width)\r
-\r
+ self._add(b, 'button')\r
+ self._add(b, 'cancel')\r
v = wx.BoxSizer(wx.VERTICAL)\r
- v.Add(window=self._c['text'],\r
- flag=wx.GROW|wx.ALIGN_CENTER_VERTICAL|wx.ALL,\r
- border=border_width)\r
- v.Add(window=self._c['listbox'],\r
- proportion=1,\r
- flag=wx.GROW|wx.ALIGN_CENTER_VERTICAL|wx.ALL,\r
- border=border_width)\r
- v.Add(window=wx.StaticLine(\r
+ self._add(v, 'text')\r
+ self._add(v, 'listbox')\r
+ self._add(v, wx.StaticLine(\r
parent=self, size=(20,-1), style=wx.LI_HORIZONTAL),\r
- flag=wx.GROW,\r
- border=border_width)\r
- v.Add(window=b,\r
- flag=wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_CENTER_HORIZONTAL|wx.ALL,\r
- border=border_width)\r
+ flag=wx.GROW)\r
+ self._add(v, b)\r
self.SetSizer(v)\r
v.Fit(self)\r
\r
+ def _add(self, sizer, item,\r
+ flag=wx.GROW|wx.ALIGN_CENTER_VERTICAL|wx.ALL,\r
+ border=5):\r
+ kwargs = {'flag':flag, 'border':border}\r
+ if isinstance(item, types.StringTypes):\r
+ item = self._c[item]\r
+ kwargs['item'] = item # window\r
+ sizer.Add(**kwargs)\r
+\r
@callback\r
def cancel(self, event):\r
"""Close the dialog.\r
selected = self._c['listbox'].GetSelection()\r
else:\r
assert self._selection_style == 'multiple', self._selection_style\r
- selected = self._c['listbox'].GetChecked())\r
+ selected = self._c['listbox'].GetChecked()\r
+ self.selected = selected\r
in_callback(self, options=self._options, selected=selected)\r
self.EndModal(wx.ID_CLOSE)\r
"""
def __init__(self, parent=None, **kwargs):
self._parent = parent
+ self._bindings = []
super(Menu, self).__init__(**kwargs)
def Bind(self, **kwargs):
while not isinstance(obj, wx.Frame):
obj = obj._parent
obj.Bind(**kwargs)
+ self._bindings.append(kwargs)
+
+ def Unbind(self, **kwargs):
+ assert 'id' in kwargs, kwargs
+ try:
+ self._bindings.remove(kwargs)
+ except ValueError:
+ pass
+ kwargs.pop('handler', None)
+ obj = self
+ while not isinstance(obj, wx.Frame):
+ obj = obj._parent
+ obj.Unbind(**kwargs)
+
+ def _unbind_all_items(self):
+ for kwargs in self._bindings:
+ self.Unbind(**kwargs)
+ self._bindings = []
class MenuBar (wx.MenuBar):
self._callbacks = callbacks
self._c = {}
- def update(self, perspectives, selected, callback):
+ def update(self, perspectives, selected):
"""Rebuild the perspectives menu.
"""
+ self._unbind_all_items()
for item in self.GetMenuItems():
- self.UnBind(item.GetId)
self.DeleteItem(item)
self._c = {
'save': self.Append(id=wx.ID_ANY, text='Save Perspective'),
'delete': self.Append(id=wx.ID_ANY, text='Delete Perspective'),
}
+ self.Bind(event=wx.EVT_MENU, handler=self.save_perspective,
+ id=self._c['save'].GetId())
+ self.Bind(event=wx.EVT_MENU, handler=self.delete_perspective,
+ id=self._c['delete'].GetId())
self.AppendSeparator()
for label in perspectives:
self._c[label] = self.AppendRadioItem(id=wx.ID_ANY, text=label)
- self.Bind(event=wx.EVT_MENU, handler=callback,
+ self.Bind(event=wx.EVT_MENU, handler=self.select_perspective,
id=self._c[label].GetId())
if label == selected:
self._c[label].Check(True)
+ @callback
+ def save_perspective(self, event):
+ pass
+
+ @callback
+ def delete_perspective(self, event):
+ pass
+
+ def select_perspective(self, event):
+ _id = event.GetId()
+ item = self.FindItemById(_id)
+ label = item.GetLabel()
+ selected = item.IsChecked()
+ assert selected == True, label
+ in_callback(self, name=label)
+
class HelpMenu (Menu):
def __init__(self, callbacks=None, **kwargs):