9 new revisions:
Revision: 76d0943e1144
Branch: default
Author: Aditya Panchal <
apan...@bastula.org>
Date: Sat Jun 2 03:38:22 2012 UTC
Log: Refactored plugin manager to allow enabling/disabling of
plugins....
http://code.google.com/p/dicompyler/source/detail?r=76d0943e1144
Revision: 8a782288b859
Branch: default
Author: Aditya Panchal <
apan...@bastula.org>
Date: Mon Jun 18 17:33:23 2012 UTC
Log: Implemented sub-plugins such that plugins can have their own
plugins....
http://code.google.com/p/dicompyler/source/detail?r=8a782288b859
Revision: 139f4da1f78f
Branch: default
Author: Aditya Panchal <
apan...@bastula.org>
Date: Tue Jul 10 17:50:46 2012 UTC
Log: Implement loading DICOM data via a command-line argument.
http://code.google.com/p/dicompyler/source/detail?r=139f4da1f78f
Revision: ba3264fe70b8
Branch: default
Author: Aditya Panchal <
apan...@bastula.org>
Date: Tue Jul 10 21:03:03 2012 UTC
Log: Fixed a bug where isodoses did not display for feet first
patients.
http://code.google.com/p/dicompyler/source/detail?r=ba3264fe70b8
Revision: 45526438a5ce
Branch: default
Author: Aditya Panchal <
apan...@bastula.org>
Date: Wed Jul 11 19:22:04 2012 UTC
Log: Implemented persistence of the main window size and position.
http://code.google.com/p/dicompyler/source/detail?r=45526438a5ce
Revision: e0d31163ea8d
Branch: default
Author: Aditya Panchal <
apan...@bastula.org>
Date: Mon Jul 7 15:23:06 2014 UTC
Log: Fixed a bug in raf1b4ddf3f46 where structures with no contour
data wou...
http://code.google.com/p/dicompyler/source/detail?r=e0d31163ea8d
Revision: 6efcd2f8a060
Branch: default
Author: Aditya Panchal <
apan...@bastula.org>
Date: Mon Jul 7 20:39:25 2014 UTC
Log: Fixed a bug in the new plugin manager where the plugin tree
control di...
http://code.google.com/p/dicompyler/source/detail?r=6efcd2f8a060
Revision: 7d976b1d7493
Branch: default
Author: Aditya Panchal <
apan...@bastula.org>
Date: Fri Jul 11 18:05:49 2014 UTC
Log: Updated the setup dependencies for dicompyler and copyright
informatio...
http://code.google.com/p/dicompyler/source/detail?r=7d976b1d7493
Revision: 1c4309763693
Branch: default
Author: Aditya Panchal <
apan...@bastula.org>
Date: Mon Jul 14 16:24:16 2014 UTC
Log: Added tag release-0.4.2 for changeset 7d976b1d7493
http://code.google.com/p/dicompyler/source/detail?r=1c4309763693
==============================================================================
Revision: 76d0943e1144
Branch: default
Author: Aditya Panchal <
apan...@bastula.org>
Date: Sat Jun 2 03:38:22 2012 UTC
Log: Refactored plugin manager to allow enabling/disabling of plugins.
Fixed a bug where a non-preference template settings are not saved to disk.
http://code.google.com/p/dicompyler/source/detail?r=76d0943e1144
Added:
/dicompyler/resources/bricks.png
/dicompyler/resources/plugin.png
/dicompyler/resources/plugin_disabled.png
Modified:
/dicompyler/main.py
/dicompyler/plugin.py
/dicompyler/preferences.py
/dicompyler/resources/plugin.xrc
=======================================
--- /dev/null
+++ /dicompyler/resources/bricks.png Sat Jun 2 03:38:22 2012 UTC
@@ -0,0 +1,31 @@
+‰PNG
+
+
+IHDR óÿa gAMA ¯È7 Šé tEXtSoftware Adobe
ImageReadyqÉe< ËIDAT8Ë¥“ßORa Çé®yÝßÐu÷Ϋ¶6·LE† š
+ †òkê Î Q·Ìp*: T ¨¤¢ J¥b&s –:]æÌ\S±¡Â +Êus¾ ó:W«ÙM Ïöì}Ÿïçù>ï ÁÿÄ_
+oîÕeD¬tæKZ'‹)(ì æ“ˆ•–`†ÖÞŠXèL¾æ\À*S
+M ôH¨U8âD)†AЦIžÐ”#YiÀ²¹*z.à£TÄ~±ZqâìÀ‘º
+1‰ ŸóküÞ q 6ê. @ ×–atUg
+Z™yP ]áu¤}>$µ 8æFàEg°c• qªˆ )
+à
+ Üö £
+!+lc&0 öD7ð# Â7·
+‰
+ ±œ¬Òãs‘”ˆùQö%ù¿ šž2Ö1} ¾Å.XGiBç iw ÒN'R-Í8” ñ!U|
+øÝ Ò[ŒÙÍ)8¦ ÁŒTbçf éœvwâk{;RMvÄKdDÈ ¸î[¢lÖds_57û3 ê
+9–>-`j#„á¥~t ê1¯£°+É#7Á»àÏâ@&ÁŽ0 ³
+9jí~TvG i ˆ
+Ê{K±°=‡‰µQ W ðG=0
+ë`³¸ ¥¤Ü
+äaWœ‹h‰ w˜6¨ÚÂpL¬Ãâ[D.3Ä
+4^ ;¶2„‘e?†–|ð.t
+Ò ×ú O£;¨÷¾‚²e’ˆøà êö È›^@h
+BPåÐgiÝ긶O
+®9'ú_{ÈYäÛÆ0³ C`~ žÉw¨é{
+Cg EöçD\Ú:
+Q]ðôñœœœ\0´é J •®ð)PÞK úäÊ
+ æ¶ð˜‹GÓ 7O 1Å9â ÄÁŸ/Qߪ½¤wh/ŠkGYoø=<áM<ä
+Üçì ÛO;ó qý8rŒƒì¹¿LeíÈ’Yzâ ®Ð
+x
+Wh
+ŠÖ0¤ Ï c @l| LÎkÿüªühêšî²B¦7-® ç, ¡ÀØû]nvUŸÕü ²ä¶gAv–: IEND®B`‚
=======================================
--- /dev/null
+++ /dicompyler/resources/plugin.png Sat Jun 2 03:38:22 2012 UTC
Binary file, no diff available.
=======================================
--- /dev/null
+++ /dicompyler/resources/plugin_disabled.png Sat Jun 2 03:38:22 2012 UTC
@@ -0,0 +1,11 @@
+‰PNG
+
+
+IHDR µú7ê gAMA ¯È7 Šé tEXtSoftware Adobe
ImageReadyqÉe< íIDAT ÁAJ•a Ðóý|$Ñ »WD[ƒ h N„6Ð< í¨=ÔÈQµˆ(§Ò "Â
+Ä ßçíœÑ € À§¯9Içüì , w}²³ y , §ëÃmÜ«/ ÀhŸ;"Ò‡#~ÞTe)/·À$¶Z3¢
+í·ø `RZ»q'Ú¢
+( “ømÏÆˆ Ñ6Þu)oÆälð¡Ÿ(-Z\9°Å &P"¢µˆ
+“÷]
+k -ÚS¿¬÷õ(˜”cmu¤µv%Vo÷€Ii?<óǵØ8 `¡Ä±¸öj¼
+« `R.E© Pù&wù
+0 ð *p‡;U0Èñ IEND®B`‚
=======================================
--- /dicompyler/main.py Mon May 14 21:16:03 2012 UTC
+++ /dicompyler/main.py Sat Jun 2 03:38:22 2012 UTC
@@ -292,10 +292,13 @@
# Load and initialize plugins
self.plugins = []
+ self.pluginsDisabled = []
pub.sendMessage('preferences.requested.value',
'general.plugins.user_plugins_location')
pub.sendMessage('preferences.requested.value',
'general.calculation.dvh_recalc')
+ pub.sendMessage('preferences.requested.value',
+ 'general.plugins.disabled_list')
########################### Patient Loading Functions
##########################
@@ -334,7 +337,13 @@
# Reset the preferences template
self.preftemplate = [{'General':self.generalpreftemplate}]
# Set up the plugins for each plugin entry point of dicompyler
- for i, p in enumerate(self.plugins):
+ for i, plugin in enumerate(self.plugins):
+ # Skip plugin if it doesn't contain the required dictionary
+ # or actually is a proper Python module
+ p = plugin['plugin']
+ if not hasattr(p, 'pluginProperties') or \
+ (p.__name__ in self.pluginsDisabled):
+ continue
props = p.pluginProperties()
# Only load plugin versions that are qualified
if (props['plugin_version'] == 1):
@@ -716,6 +725,8 @@
self.fh.setLevel(logging.WARNING)
if not util.main_is_frozen():
self.ch.setLevel(logging.WARNING)
+ elif (msg.topic[1] == 'plugins') and (msg.topic[2]
== 'disabled_list'):
+ self.pluginsDisabled = msg.data
def OnUpdatePlugins(self, msg):
"""Update the location of the user plugins and load all plugins."""
@@ -728,7 +739,13 @@
self.menuImportDict = {}
self.menuExportDict = {}
# Set up the import plugins for dicompyler
- for i, p in enumerate(self.plugins):
+ for i, pg in enumerate(self.plugins):
+ # Skip plugin if it doesn't contain the required dictionary
+ # or actually is a proper Python module or is disabled
+ p = pg['plugin']
+ if not hasattr(p, 'pluginProperties') or \
+ (p.__name__ in self.pluginsDisabled):
+ continue
props = p.pluginProperties()
# Only load plugin versions that are qualified
if ((props['plugin_version'] == 1) and
@@ -750,7 +767,6 @@
tool['bmp'],
shortHelp=tool['shortHelp'])
self.Bind(wx.EVT_TOOL, tool['eventhandler'],
id=(300+i)*10+t)
self.toolbar.Realize()
-
def OnUpdateStatusBar(self, msg):
"""Update the status bar text."""
@@ -815,7 +831,7 @@
def OnPluginManager(self, evt):
"""Load and show the Plugin Manager dialog box."""
-
self.pm = plugin.PluginManager(self, self.plugins)
+
self.pm = plugin.PluginManager(self, self.plugins,
self.pluginsDisabled)
def OnAbout(self, evt):
# First we create and fill the info object
=======================================
--- /dicompyler/plugin.py Mon May 14 21:16:03 2012 UTC
+++ /dicompyler/plugin.py Sat Jun 2 03:38:22 2012 UTC
@@ -12,6 +12,7 @@
import imp, os
import wx
from wx.xrc import *
+from wx.lib.pubsub import Publisher as pub
from dicompyler import guiutil, util
def import_plugins(userpath=None):
@@ -26,44 +27,47 @@
# Get the list of possible plugins from both paths
possibleplugins = []
for i in os.listdir(userpath):
- possibleplugins.append(i)
+ possibleplugins.append({'plugin': i, 'location': 'user'})
for i in os.listdir(basepath):
- possibleplugins.append(i)
+ possibleplugins.append({'plugin': i, 'location': 'base'})
modules = []
plugins = []
- for file in possibleplugins:
- module = file.split('.')[0]
+ for p in possibleplugins:
+ module = p['plugin'].split('.')[0]
if module not in modules:
if not ((module == "__init__") or (module == "")):
# only try to import the module once
modules.append(module)
try:
- f, filename, description = imp.find_module(module,
[userpath, basepath])
+ f, filename, description = \
+ imp.find_module(module, [userpath, basepath])
except ImportError:
# Not able to find module so pass
pass
else:
# Try to import the module if no exception occurred
try:
- plugins.append(imp.load_module(module, f,
filename, description))
+ m = imp.load_module(module, f, filename,
description)
except ImportError:
logger.exception("%s could not be loaded", module)
else:
+ plugins.append({'plugin': m,
+ 'location': p['location']})
logger.debug("%s loaded", module)
# If the module is a single file, close it
if not (description[2] == imp.PKG_DIRECTORY):
f.close()
return plugins
-def PluginManager(parent, plugins):
+def PluginManager(parent, plugins, pluginsDisabled):
"""Prepare to show the plugin manager dialog."""
# Load the XRC file for our gui resources
res = XmlResource(util.GetResourcePath('plugin.xrc'))
dlgPluginManager = res.LoadDialog(parent, "PluginManagerDialog")
- dlgPluginManager.Init(plugins)
+ dlgPluginManager.Init(plugins, pluginsDisabled)
# Show the dialog
dlgPluginManager.ShowModal()
@@ -76,7 +80,7 @@
# the Create step is done by XRC.
self.PostCreate(pre)
- def Init(self, plugins):
+ def Init(self, plugins, pluginsDisabled):
"""Method called after the panel has been initialized."""
# Set window icon
@@ -84,58 +88,173 @@
self.SetIcon(guiutil.get_icon())
# Initialize controls
- self.lcPlugins = XRCCTRL(self, 'lcPlugins')
+ self.tcPlugins = XRCCTRL(self, 'tcPlugins')
+ self.panelTreeView = XRCCTRL(self, 'panelTreeView')
+ self.panelProperties = XRCCTRL(self, 'panelProperties')
+ self.lblName = XRCCTRL(self, 'lblName')
+ self.lblAuthor = XRCCTRL(self, 'lblAuthor')
+ self.lblPluginType = XRCCTRL(self, 'lblPluginType')
+ self.lblVersion = XRCCTRL(self, 'lblVersion')
+ self.lblVersionNumber = XRCCTRL(self, 'lblVersionNumber')
+ self.lblDescription = XRCCTRL(self, 'lblDescription')
+ self.checkEnabled = XRCCTRL(self, 'checkEnabled')
+ self.lblMessage = XRCCTRL(self, 'lblMessage')
self.btnGetMorePlugins = XRCCTRL(self, 'btnGetMorePlugins')
self.btnDeletePlugin = XRCCTRL(self, 'btnDeletePlugin')
self.plugins = plugins
+ self.pluginsDisabled = set(pluginsDisabled)
# Bind interface events to the proper methods
# wx.EVT_BUTTON(self, XRCID('btnDeletePlugin'), self.DeletePlugin)
+ wx.EVT_CHECKBOX(self, XRCID('checkEnabled'), self.OnEnablePlugin)
+ wx.EVT_TREE_ITEM_ACTIVATED(self, XRCID('tcPlugins'),
self.OnEnablePlugin)
+ wx.EVT_TREE_SEL_CHANGED(self, XRCID('tcPlugins'),
self.OnSelectTreeItem)
+ wx.EVT_TREE_SEL_CHANGING(self, XRCID('tcPlugins'),
self.OnSelectRootItem)
+
+ # Modify the control and font size as needed
+ font = wx.SystemSettings.GetFont(wx.SYS_DEFAULT_GUI_FONT)
+ if guiutil.IsMac():
+ children = list(self.Children) + \
+ list(self.panelTreeView.Children) + \
+ list(self.panelProperties.Children)
+ for control in children:
+ control.SetFont(font)
+ control.SetWindowVariant(wx.WINDOW_VARIANT_SMALL)
+
XRCCTRL(self, 'wxID_OK').SetWindowVariant(wx.WINDOW_VARIANT_NORMAL)
+ font.SetWeight(wx.FONTWEIGHT_BOLD)
+ if guiutil.IsMSWindows():
+ self.tcPlugins.SetPosition((0, 3))
+ self.panelTreeView.SetWindowStyle(wx.STATIC_BORDER)
+ if (guiutil.IsMac() or guiutil.IsGtk()):
+ self.tcPlugins.SetPosition((-30, 0))
+ self.panelTreeView.SetWindowStyle(wx.SUNKEN_BORDER)
+ self.lblName.SetFont(font)
+ self.lblMessage.SetFont(font)
+
+ self.Layout()
self.InitPluginList()
self.LoadPlugins()
def InitPluginList(self):
"""Initialize the plugin list control."""
-
- info = wx.ListItem()
- info.m_mask = wx.LIST_MASK_TEXT | wx.LIST_MASK_IMAGE |
wx.LIST_MASK_FORMAT
- info.m_image = -1
- info.m_format = 0
-
- info.m_text = 'Name'
- self.lcPlugins.InsertColumnInfo(0, info)
- self.lcPlugins.SetColumn(0, info)
- self.lcPlugins.SetColumnWidth(0, 120)
-
- info.m_text = 'Description'
- self.lcPlugins.InsertColumnInfo(1, info)
- self.lcPlugins.SetColumn(1, info)
- self.lcPlugins.SetColumnWidth(1, 300)
-
- info.m_text = 'Author'
- self.lcPlugins.InsertColumnInfo(2, info)
- self.lcPlugins.SetColumn(2, info)
- self.lcPlugins.SetColumnWidth(2, 150)
-
- info.m_text = 'Version'
- self.lcPlugins.InsertColumnInfo(3, info)
- self.lcPlugins.SetColumn(3, info)
- self.lcPlugins.SetColumnWidth(3, 75)
- info.m_text = 'Enabled'
- self.lcPlugins.InsertColumnInfo(4, info)
- self.lcPlugins.SetColumn(4, info)
- self.lcPlugins.SetColumnWidth(4, 75)
+ iSize = (16, 16)
+ iList = wx.ImageList(iSize[0], iSize[1])
+ iList.Add(
+ wx.Bitmap(
+ util.GetResourcePath('bricks.png'),
+ wx.BITMAP_TYPE_PNG))
+ iList.Add(
+ wx.Bitmap(
+ util.GetResourcePath('plugin.png'),
+ wx.BITMAP_TYPE_PNG))
+ iList.Add(
+ wx.Bitmap(
+ util.GetResourcePath('plugin_disabled.png'),
+ wx.BITMAP_TYPE_PNG))
+ self.tcPlugins.AssignImageList(iList)
+ self.root = self.tcPlugins.AddRoot('Plugins')
+ self.baseroot = self.tcPlugins.AppendItem(
+ self.root, "Built-In Plugins", 0)
+ self.userroot = self.tcPlugins.AppendItem(
+ self.root, "User Plugins", 0)
+
+ font = wx.SystemSettings.GetFont(wx.SYS_DEFAULT_GUI_FONT)
+ font.SetWeight(wx.FONTWEIGHT_BOLD)
+ self.tcPlugins.SetItemFont(self.baseroot, font)
+ self.tcPlugins.SetItemFont(self.userroot, font)
def LoadPlugins(self):
"""Update and load the data for the plugin list control."""
# Set up the plugins for each plugin entry point of dicompyler
- for n, p in enumerate(self.plugins):
+ for n, plugin in enumerate(self.plugins):
+ # Skip plugin if it doesn't contain the required dictionary
+ # or actually is a proper Python module
+ p = plugin['plugin']
+ if not hasattr(p, 'pluginProperties'):
+ continue
props = p.pluginProperties()
- self.lcPlugins.InsertStringItem(n, props['name'])
- self.lcPlugins.SetStringItem(n, 1, props['description'])
- self.lcPlugins.SetStringItem(n, 2, props['author'])
- self.lcPlugins.SetStringItem(n, 3, str(props['version']))
- self.lcPlugins.SetStringItem(n, 4, 'Yes')
+ root = self.userroot
+ if (plugin['location'] == 'base'):
+ root = self.baseroot
+ else:
+ root = self.userroot
+ i = self.tcPlugins.AppendItem(root, props['name'], 1)
+
+ if (p.__name__ in self.pluginsDisabled):
+ self.tcPlugins.SetItemImage(i, 2)
+ self.tcPlugins.SetItemTextColour(i, wx.Colour(169, 169,
169))
+
+ self.tcPlugins.SetPyData(i, n)
+ self.tcPlugins.SelectItem(i)
+ self.tcPlugins.ExpandAll()
+ wx.EVT_TREE_ITEM_COLLAPSING(
+ self, XRCID('tcPlugins'), self.OnExpandCollapseTree)
+ wx.EVT_TREE_ITEM_EXPANDING(
+ self, XRCID('tcPlugins'), self.OnExpandCollapseTree)
+
+ def OnSelectTreeItem(self, evt):
+ """Update the interface when the selected item has changed."""
+
+ item = evt.GetItem()
+ n = self.tcPlugins.GetPyData(item)
+ if (n == None):
+ self.panelProperties.Hide()
+ return
+ self.panelProperties.Show()
+ plugin = self.plugins[n]
+ p = plugin['plugin']
+ props = p.pluginProperties()
+ self.lblName.SetLabel(props['name'])
+ self.lblAuthor.SetLabel(props['author'].replace('&', '&&'))
+ self.lblVersionNumber.SetLabel(str(props['version']))
+ ptype = props['plugin_type']
+ self.lblPluginType.SetLabel(ptype[0].capitalize() + ptype[1:])
+
self.lblDescription.SetLabel(props['description'].replace('&', '&&'))
+
+ self.checkEnabled.SetValue(not (p.__name__ in
self.pluginsDisabled))
+
+ self.Layout()
+ self.panelProperties.Layout()
+
+ def OnSelectRootItem(self, evt):
+ """Block the root items from being selected."""
+
+ item = evt.GetItem()
+ n = self.tcPlugins.GetPyData(item)
+ if (n == None):
+ evt.Veto()
+
+ def OnExpandCollapseTree(self, evt):
+ """Block the tree from expanding or collapsing."""
+
+ evt.Veto()
+
+ def OnEnablePlugin(self, evt=None):
+ """Publish the enabled/disabled state of the plugin."""
+
+ item = self.tcPlugins.GetSelection()
+ n = self.tcPlugins.GetPyData(item)
+ plugin = self.plugins[n]
+ p = plugin['plugin']
+
+ # Set the checkbox to the appropriate state if the event
+ # comes from the treeview
+ if (evt.EventType == wx.EVT_TREE_ITEM_ACTIVATED.typeId):
+ self.checkEnabled.SetValue(not self.checkEnabled.IsChecked())
+
+ if self.checkEnabled.IsChecked():
+ self.tcPlugins.SetItemImage(item, 1)
+ self.tcPlugins.SetItemTextColour(item, wx.BLACK)
+ self.pluginsDisabled.remove(p.__name__)
+ logger.debug("%s enabled", p.__name__)
+ else:
+ self.tcPlugins.SetItemImage(item, 2)
+ self.tcPlugins.SetItemTextColour(item, wx.Colour(169, 169,
169))
+ self.pluginsDisabled.add(p.__name__)
+ logger.debug("%s disabled", p.__name__)
+
+ pub.sendMessage('preferences.updated.value',
+ {'general.plugins.disabled_list':
list(self.pluginsDisabled)})
=======================================
--- /dicompyler/preferences.py Mon May 14 21:16:03 2012 UTC
+++ /dicompyler/preferences.py Sat Jun 2 03:38:22 2012 UTC
@@ -115,6 +115,7 @@
SetValue(self.values, msg.data.keys()[0], msg.data.values()[0])
pub.sendMessage('preferences.updated.values', self.values)
+ pub.sendMessage(msg.data.keys()[0], msg.data.values()[0])
############################## Preferences Dialog
##############################
=======================================
--- /dicompyler/resources/plugin.xrc Fri Dec 30 04:31:51 2011 UTC
+++ /dicompyler/resources/plugin.xrc Sat Jun 2 03:38:22 2012 UTC
@@ -2,27 +2,159 @@
<resource>
<object class="wxDialog" name="PluginManagerDialog"
subclass="dicompyler.plugin.PluginManagerDialog">
<object class="wxBoxSizer">
- <orient>wxHORIZONTAL</orient>
<object class="sizeritem">
<object class="wxBoxSizer">
+ <object class="spacer">
+ <size>5,5</size>
+ </object>
<object class="sizeritem">
- <object class="wxStaticBoxSizer">
+ <object class="wxBoxSizer">
+ <object class="spacer">
+ <size>5,5</size>
+ </object>
<object class="sizeritem">
- <object class="wxListCtrl" name="lcPlugins">
- <size>750,200</size>
- <style>wxLC_REPORT</style>
+ <object class="wxPanel" name="panelTreeView">
+ <object class="wxTreeCtrl" name="tcPlugins">
+ <size>250,250</size>
+ <style>wxNO_BORDER|wxTR_NO_BUTTONS|wxTR_NO_LINES|
wxTR_FULL_ROW_HIGHLIGHT|wxTR_HIDE_ROOT</style>
+ </object>
+ <bg>#FFFFFF</bg>
+ <style>wxSUNKEN_BORDER</style>
+ </object>
+ <flag>wxALL|wxEXPAND|wxALIGN_CENTRE</flag>
+ </object>
+ <object class="spacer">
+ <size>10,0</size>
+ </object>
+ <orient>wxHORIZONTAL</orient>
+ <object class="sizeritem">
+ <object class="wxPanel" name="panelProperties">
+ <object class="wxBoxSizer">
+ <object class="spacer">
+ <size>0,3</size>
+ </object>
+ <object class="sizeritem">
+ <object class="wxBoxSizer">
+ <object class="sizeritem">
+ <object class="wxStaticText" name="lblName">
+ <label>Plugin Name</label>
+ </object>
+ </object>
+ <object class="spacer">
+ <size>4,0</size>
+ </object>
+ <object class="sizeritem">
+ <object class="wxStaticText">
+ <label>by</label>
+ </object>
+ </object>
+ <object class="spacer">
+ <size>2,0</size>
+ </object>
+ <object class="sizeritem">
+ <object class="wxStaticText" name="lblAuthor">
+ <label>Plugin Author</label>
+ </object>
+ </object>
+ <object class="spacer">
+ <size>5,0</size>
+ <option>1</option>
+ <flag>wxALL|wxEXPAND|wxALIGN_CENTRE</flag>
+ </object>
+ <object class="sizeritem">
+ <object class="wxStaticText" name="lblVersion">
+ <label>Version</label>
+ </object>
+ </object>
+ <object class="spacer">
+ <size>2,0</size>
+ </object>
+ <object class="sizeritem">
+ <object class="wxStaticText"
name="lblVersionNumber">
+ <label>Version Number</label>
+ </object>
+ </object>
+ <orient>wxHORIZONTAL</orient>
+ </object>
+ <flag>wxALL|wxEXPAND|wxALIGN_CENTRE</flag>
+ </object>
+ <object class="spacer">
+ <size>0,7</size>
+ </object>
+ <object class="sizeritem">
+ <object class="wxBoxSizer">
+ <object class="spacer">
+ <size>10,0</size>
+ </object>
+ <object class="sizeritem">
+ <object class="wxStaticText"
name="lblPluginType">
+ <label>Plugin Type</label>
+ </object>
+ </object>
+ <object class="spacer">
+ <size>3,0</size>
+ </object>
+ <object class="sizeritem">
+ <object class="wxStaticText">
+ <label>Plugin</label>
+ </object>
+ </object>
+ <object class="spacer">
+ <size>5,0</size>
+ <option>1</option>
+ <flag>wxALL|wxEXPAND|wxALIGN_CENTRE</flag>
+ </object>
+ <object class="sizeritem">
+ <object class="wxCheckBox" name="checkEnabled">
+ <label>&Enabled</label>
+ </object>
+ </object>
+ <orient>wxHORIZONTAL</orient>
+ </object>
+ <flag>wxALL|wxEXPAND|wxALIGN_CENTRE</flag>
+ </object>
+ <object class="spacer">
+ <size>0,5</size>
+ </object>
+ <orient>wxVERTICAL</orient>
+ <object class="sizeritem">
+ <object class="wxBoxSizer">
+ <object class="sizeritem">
+ <object class="wxBoxSizer">
+ <object class="spacer">
+ <size>10,0</size>
+ </object>
+ <object class="sizeritem">
+ <object class="wxStaticText"
name="lblDescription">
+ <label>Description</label>
+ </object>
+ <option>1</option>
+ <flag>wxALL|wxEXPAND|wxALIGN_CENTRE</flag>
+ </object>
+ <orient>wxHORIZONTAL</orient>
+ </object>
+ <option>1</option>
+ <flag>wxALL|wxEXPAND|wxALIGN_CENTRE</flag>
+ </object>
+ <orient>wxVERTICAL</orient>
+ </object>
+ <option>1</option>
+ <flag>wxALL|wxEXPAND|wxALIGN_CENTRE</flag>
+ </object>
+ </object>
</object>
<option>1</option>
<flag>wxALL|wxEXPAND|wxALIGN_CENTRE</flag>
</object>
- <label>Installed Plugins</label>
- <orient>wxVERTICAL</orient>
+ <object class="spacer">
+ <size>5,5</size>
+ </object>
</object>
- <option>3</option>
+ <option>1</option>
<flag>wxALL|wxEXPAND|wxALIGN_CENTRE</flag>
</object>
<object class="spacer">
- <size>5,5</size>
+ <size>0,5</size>
</object>
<orient>wxVERTICAL</orient>
</object>
@@ -30,9 +162,50 @@
<flag>wxALL|wxEXPAND|wxALIGN_CENTRE</flag>
<border>3</border>
</object>
+ <object class="sizeritem">
+ <object class="wxBoxSizer">
+ <object class="spacer">
+ <size>0,5</size>
+ <option>1</option>
+ <flag>wxALL|wxEXPAND|wxALIGN_CENTRE</flag>
+ </object>
+ <object class="sizeritem">
+ <object class="wxStaticText" name="lblMessage">
+ <label>* Plugins will be enabled/disabled when DICOM data is
reloaded.</label>
+ <style>wxALIGN_CENTRE</style>
+ </object>
+ <flag>wxALIGN_CENTRE</flag>
+ </object>
+ <object class="spacer">
+ <size>0,5</size>
+ <option>1</option>
+ <flag>wxALL|wxEXPAND|wxALIGN_CENTRE</flag>
+ </object>
+ <object class="sizeritem">
+ <object class="wxButton" name="wxID_OK">
+ <label>&Close</label>
+ </object>
+ <flag>wxALL|wxEXPAND|wxALIGN_CENTRE</flag>
+ <border>3</border>
+ </object>
+ <object class="spacer">
+ <size>0,5</size>
+ <flag>wxALL|wxEXPAND|wxALIGN_CENTRE</flag>
+ <border>3</border>
+ </object>
+ <orient>wxHORIZONTAL</orient>
+ </object>
+ <flag>wxALL|wxEXPAND|wxALIGN_CENTRE</flag>
+ </object>
+ <orient>wxVERTICAL</orient>
+ <object class="spacer">
+ <size>10,10</size>
+ <flag>wxALL|wxEXPAND|wxALIGN_CENTRE</flag>
+ </object>
</object>
+ <size>600,400</size>
<title>Plugin Manager</title>
<centered>1</centered>
- <style>wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER</style>
+ <style>wxDEFAULT_DIALOG_STYLE</style>
</object>
</resource>
==============================================================================
Revision: 8a782288b859
Branch: default
Author: Aditya Panchal <
apan...@bastula.org>
Date: Mon Jun 18 17:33:23 2012 UTC
Log: Implemented sub-plugins such that plugins can have their own
plugins.
Implemented Tools menu for 2D View plugins.
http://code.google.com/p/dicompyler/source/detail?r=8a782288b859
Added:
/dicompyler/resources/cog.png
Modified:
/dicompyler/baseplugins/2dview.py
/dicompyler/main.py
=======================================
--- /dev/null
+++ /dicompyler/resources/cog.png Mon Jun 18 17:33:23 2012 UTC
@@ -0,0 +1,22 @@
+‰PNG
+
+
+IHDR µú7ê gAMA ¯È7 Šé tEXtSoftware Adobe
ImageReadyqÉe< ’IDAT(ÏUQMK a ^ü Þý þ ½t ²‹T—2ˆ
+‹.E‰‘Ù QС:” EeQ ¤PR¨«¶®éº–QRôqÈâ%!O^wŸ¦m!c 3ïÌ3Ï3ï
+ îÏTo^’%ÉÛš³\ÅY¶«¶|ý ï ëg¶˜ýØÙ ¨„Ëz‘)Ž,{Å
+b,ê Ù¾¾ ¶ 7þg|á Ùfʨâ '†ØTÁ Ç‚ß ²ñL
+G UM
+ W˜0F –DN¸C \` ÛÈBA†úç SâJ“kéÆ 4$0£ŒóSü’rI
+‹ ¹ZHãdý“ˆ
+(c ³üOÏ:/B&6
+
+Ò9I #M
+:¢X6 «ü 1Ä‘¦| ÎíhKµÆ5AJØTÖø ’È Ü9ú žZ‡f )
+9 +‡< ±OQ
+§
+ Ö
+Ž ãžÊ**4Kž˜rHÒkØèÿýæ®? WD j
+†Lê>c¸ !ýi¸ýÖ
+‚á ½ 9BL%†^Öéð0—Þ n9ÖˆsÐ>i
+Ö“ˆ¡«Þië¶»œÿ®ùk>¯Gj—ÜÿÎý
+ ˆ] ò™î† IEND®B`‚
=======================================
--- /dicompyler/baseplugins/2dview.py Sat May 19 10:29:39 2012 UTC
+++ /dicompyler/baseplugins/2dview.py Mon Jun 18 17:33:23 2012 UTC
@@ -67,12 +67,15 @@
self.pan = [0, 0]
self.bwidth = 0
self.bheight = 0
+ self.xpos = 0
+ self.ypos = 0
self.mousepos = wx.Point(-10000, -10000)
self.mouse_in_window = False
self.isodose_line_style = 'Solid'
self.isodose_fill_opacity = 25
self.structure_line_style = 'Solid'
self.structure_fill_opacity = 50
+ self.plugins = {}
# Setup toolbar controls
if guiutil.IsGtk():
@@ -81,9 +84,11 @@
drawingstyles = ['Solid', 'Transparent', 'Dot', 'Dash', 'Dot
Dash']
zoominbmp =
wx.Bitmap(util.GetResourcePath('magnifier_zoom_in.png'))
zoomoutbmp =
wx.Bitmap(util.GetResourcePath('magnifier_zoom_out.png'))
+ toolsbmp = wx.Bitmap(util.GetResourcePath('cog.png'))
self.tools = []
self.tools.append({'label':"Zoom
In", 'bmp':zoominbmp, 'shortHelp':"Zoom In", 'eventhandler':self.OnZoomIn})
self.tools.append({'label':"Zoom
Out", 'bmp':zoomoutbmp, 'shortHelp':"Zoom
Out", 'eventhandler':self.OnZoomOut})
+
self.tools.append({'label':"Tools", 'bmp':toolsbmp, 'shortHelp':"Tools", 'eventhandler':self.OnToolsMenu})
# Set up preferences
self.preferences = [
@@ -118,6 +123,7 @@
pub.subscribe(self.OnIsodoseCheck, 'isodoses.checked')
pub.subscribe(self.OnRefresh, '2dview.refresh')
pub.subscribe(self.OnDrawingPrefsChange, '2dview.drawingprefs')
+ pub.subscribe(self.OnPluginLoaded, 'plugin.loaded.2dview')
pub.sendMessage('preferences.requested.values', '2dview.drawingprefs')
def OnUpdatePatient(self, msg):
@@ -197,6 +203,7 @@
pub.unsubscribe(self.OnStructureCheck)
pub.unsubscribe(self.OnIsodoseCheck)
pub.unsubscribe(self.OnDrawingPrefsChange)
+ pub.unsubscribe(self.OnPluginLoaded)
self.OnUnfocus()
def OnStructureCheck(self, msg):
@@ -226,6 +233,12 @@
self.structure_fill_opacity = msg.data
self.Refresh()
+ def OnPluginLoaded(self, msg):
+ """When a 2D View-dependent plugin is loaded, initialize the
plugin."""
+
+ name = msg.data.pluginProperties()['name']
+ self.plugins[name] = msg.data.plugin(self)
+
def DrawStructure(self, structure, gc, position, prone, feetfirst):
"""Draw the given structure on the panel."""
@@ -510,6 +523,10 @@
ypos = int(pos[1]/self.zoom-self.pan[1]-(h-self.bheight*self.zoom)/
(2*self.zoom))
+ # Save the coordinates so they can be used by the 2dview plugins
+ self.xpos = xpos
+ self.ypos = ypos
+
# Set an empty text placeholder if the coordinates are not within
range
text = ""
value = ""
@@ -623,6 +640,17 @@
"""Get the initial position of the mouse when dragging."""
self.mousepos = evt.GetPosition()
+ # Publish the coordinates of the cursor position based
+ # on the scaled image size range
+ if ((0 <= self.xpos < len(self.structurepixlut[0])) and
+ (0 <= self.ypos < len(self.structurepixlut[1])) and
+ (self.mouse_in_window) and
+ (evt.LeftDown())):
+ pub.sendMessage('2dview.mousedown',
+ {'x':self.xpos,
+ 'y':self.ypos,
+ 'xmm':self.structurepixlut[0][self.xpos],
+ 'ymm':self.structurepixlut[1][self.ypos]})
def OnMouseUp(self, evt):
"""Reset the cursor when the mouse is released."""
@@ -674,3 +702,20 @@
self.window -= delta[0]
self.level -= delta[1]
self.Refresh()
+
+ def OnToolsMenu(self, evt):
+ """Show a context menu for the loaded 2D View plugins when the
+ 'Tools' toolbar item is selected."""
+
+ menu = wx.Menu()
+ if len(self.plugins):
+ for name, p in self.plugins.iteritems():
+ id = wx.NewId()
+ self.Bind(wx.EVT_MENU, p.pluginMenu, id=id)
+ menu.Append(id, name)
+ else:
+ id = wx.NewId()
+ menu.Append(id, "No tools found")
+ menu.Enable(id, False)
+ self.PopupMenu(menu)
+ menu.Destroy()
=======================================
--- /dicompyler/main.py Sat Jun 2 03:38:22 2012 UTC
+++ /dicompyler/main.py Mon Jun 18 17:33:23 2012 UTC
@@ -336,6 +336,8 @@
self.menuExportDict = {}
# Reset the preferences template
self.preftemplate = [{'General':self.generalpreftemplate}]
+ # Initialize the list of subplugins
+ subplugins = []
# Set up the plugins for each plugin entry point of dicompyler
for i, plugin in enumerate(self.plugins):
# Skip plugin if it doesn't contain the required dictionary
@@ -368,7 +370,7 @@
plugin = p.pluginLoader(self.notebook)
self.notebook.AddPage(plugin, props['name'])
# Load the menu plugins
- if (props['plugin_type'] == 'menu'):
+ elif (props['plugin_type'] == 'menu'):
if not len(self.menuDict):
self.menuPlugins.AppendSeparator()
self.menuDict[100+i] = self.menuPlugins.Append(
@@ -376,18 +378,28 @@
plugin = p.plugin(self)
wx.EVT_MENU(self, 100+i, plugin.pluginMenu)
# Load the export menu plugins
- if (props['plugin_type'] == 'export'):
+ elif (props['plugin_type'] == 'export'):
if not len(self.menuExportDict):
self.menuExportItem.Enable(True)
self.menuExportDict[200+i] =
self.menuExport.Append(
200+i, props['menuname'])
plugin = p.plugin(self)
wx.EVT_MENU(self, 200+i, plugin.pluginMenu)
+ # If a sub-plugin, mark it to be initialized later
+ else:
+ subplugins.append(p)
+ continue
# Add the plugin preferences if they exist
if hasattr(plugin, 'preferences'):
self.preftemplate.append({props['name']:plugin.preferences})
pub.sendMessage('preferences.updated.template',
self.preftemplate)
+ # Load the subplugins and notify the parent plugins
+ for s in subplugins:
+ props = s.pluginProperties()
+ msg = 'plugin.loaded.' + props['plugin_type'] + '.'
+s.__name__
+ pub.sendMessage(msg, s)
+
dlgProgress = guiutil.get_progress_dialog(self, "Loading Patient
Data...")
self.t=threading.Thread(target=self.LoadPatientDataThread,
args=(self, self.ptdata, dlgProgress.OnUpdateProgress,
==============================================================================
Revision: 139f4da1f78f
Branch: default
Author: Aditya Panchal <
apan...@bastula.org>
Date: Tue Jul 10 17:50:46 2012 UTC
Log: Implement loading DICOM data via a command-line argument.
http://code.google.com/p/dicompyler/source/detail?r=139f4da1f78f
Modified:
/dicompyler/main.py
=======================================
--- /dicompyler/main.py Mon Jun 18 17:33:23 2012 UTC
+++ /dicompyler/main.py Tue Jul 10 17:50:46 2012 UTC
@@ -195,6 +195,7 @@
# Bind interface events to the proper methods
wx.EVT_CHOICE(self, XRCID('choiceStructure'),
self.OnStructureSelect)
+ self.Bind(wx.EVT_ACTIVATE, self.OnActivate)
self.Bind(wx.EVT_CLOSE, self.OnClose)
self.notebook.Bind(wx.EVT_NOTEBOOK_PAGE_CHANGED,
self.OnPageChanged)
# Events to work around a focus bug in Windows
@@ -280,6 +281,7 @@
pub.subscribe(self.OnUpdatePlugins, 'general.plugins.user_plugins_location')
pub.subscribe(self.OnUpdatePreferences, 'general')
pub.subscribe(self.OnUpdateStatusBar, 'main.update_statusbar')
+ pub.subscribe(self.OnOpenPatient, 'dicomgui.show')
# Send a message to the logging system to turn on/off detailed
logging
pub.sendMessage('preferences.requested.value',
@@ -886,6 +888,20 @@
dlg.ShowModal()
dlg.Destroy()
+ def OnActivate(self, evt):
+ """Show the import dialog if command-line arguments have been
passed."""
+
+ # Check if a folder is provided via command-line arguments
+ if (len(sys.argv) == 2):
+ path = sys.argv[1]
+ if not os.path.isdir(path):
+ path = os.path.split(path)[0]
+ pub.sendMessage('preferences.updated.value',
+ {'general.dicom.import_location':path})
+ sys.argv.pop()
+ self.OnOpenPatient(None)
+ evt.Skip()
+
def OnClose(self, _):
self.Destroy()
==============================================================================
Revision: ba3264fe70b8
Branch: default
Author: Aditya Panchal <
apan...@bastula.org>
Date: Tue Jul 10 21:03:03 2012 UTC
Log: Fixed a bug where isodoses did not display for feet first
patients.
http://code.google.com/p/dicompyler/source/detail?r=ba3264fe70b8
Modified:
/dicompyler/baseplugins/2dview.py
/dicompyler/dicomparser.py
=======================================
--- /dicompyler/baseplugins/2dview.py Mon Jun 18 17:33:23 2012 UTC
+++ /dicompyler/baseplugins/2dview.py Tue Jul 10 21:03:03 2012 UTC
@@ -362,11 +362,12 @@
# Determine if the patient is prone or supine
imdata = self.images[self.imagenum-1].GetImageData()
prone = -1 if 'p' in imdata['patientposition'].lower() else 1
+ feetfirst = -1 if 'ff' in imdata['patientposition'].lower() else 1
# Get the pixel spacing
spacing = imdata['pixelspacing']
# Transpose the dose grid LUT onto the image grid LUT
- x = (np.array(doselut[0]) - pixlut[0][0]) * prone / spacing[0]
+ x = (np.array(doselut[0]) - pixlut[0][0]) * prone * feetfirst /
spacing[0]
y = (np.array(doselut[1]) - pixlut[1][0]) * prone / spacing[1]
return (x, y)
=======================================
--- /dicompyler/dicomparser.py Sat May 19 15:59:12 2012 UTC
+++ /dicompyler/dicomparser.py Tue Jul 10 21:03:03 2012 UTC
@@ -514,9 +514,11 @@
z = float(z)
# Get the initial dose grid position (z) in patient coordinates
imagepatpos = self.ds.ImagePositionPatient[2]
+ orientation = self.ds.ImageOrientationPatient[0]
# Add the position to the offset vector to determine the
# z coordinate of each dose plane
- planes = np.array(self.ds.GridFrameOffsetVector)+imagepatpos
+ planes = orientation * np.array(self.ds.GridFrameOffsetVector)
+ \
+ imagepatpos
frame = -1
# Check to see if the requested plane exists in the array
if (np.amin(np.fabs(planes - z)) < threshold):
==============================================================================
Revision: 45526438a5ce
Branch: default
Author: Aditya Panchal <
apan...@bastula.org>
Date: Wed Jul 11 19:22:04 2012 UTC
Log: Implemented persistence of the main window size and position.
http://code.google.com/p/dicompyler/source/detail?r=45526438a5ce
Modified:
/dicompyler/main.py
=======================================
--- /dicompyler/main.py Tue Jul 10 17:50:46 2012 UTC
+++ /dicompyler/main.py Wed Jul 11 19:22:04 2012 UTC
@@ -301,6 +301,8 @@
'general.calculation.dvh_recalc')
pub.sendMessage('preferences.requested.value',
'general.plugins.disabled_list')
+ pub.sendMessage('preferences.requested.values',
+ 'general.window')
########################### Patient Loading Functions
##########################
@@ -741,6 +743,15 @@
self.ch.setLevel(logging.WARNING)
elif (msg.topic[1] == 'plugins') and (msg.topic[2]
== 'disabled_list'):
self.pluginsDisabled = msg.data
+ elif (msg.topic[1] == 'window'):
+ if msg.topic[2] == 'maximized':
+ self.Maximize(msg.data)
+ elif msg.topic[2] == 'size':
+ if not self.IsMaximized():
+ self.SetSize(tuple(msg.data))
+ elif msg.topic[2] == 'position':
+ if not self.IsMaximized():
+ self.SetPosition(tuple(msg.data))
def OnUpdatePlugins(self, msg):
"""Update the location of the user plugins and load all plugins."""
@@ -903,6 +914,13 @@
evt.Skip()
def OnClose(self, _):
+ pub.sendMessage('preferences.updated.value',
+ {'general.window.maximized':self.IsMaximized()})
+ if not self.IsMaximized():
+ pub.sendMessage('preferences.updated.value',
+ {'general.window.size':tuple(self.GetSize())})
+ pub.sendMessage('preferences.updated.value',
+ {'general.window.position':tuple(self.GetPosition())})
self.Destroy()
class dicompyler(wx.App):
@@ -919,7 +937,6 @@
dicompylerFrame = MainFrame(None, -1, "dicompyler", self.res)
self.SetTopWindow(dicompylerFrame)
- dicompylerFrame.Centre()
dicompylerFrame.Show()
return 1
==============================================================================
Revision: e0d31163ea8d
Branch: default
Author: Aditya Panchal <
apan...@bastula.org>
Date: Mon Jul 7 15:23:06 2014 UTC
Log: Fixed a bug in raf1b4ddf3f46 where structures with no contour
data would cause an error in the 2D view.
http://code.google.com/p/dicompyler/source/detail?r=e0d31163ea8d
Modified:
/dicompyler/baseplugins/2dview.py
=======================================
--- /dicompyler/baseplugins/2dview.py Tue Jul 10 21:03:03 2012 UTC
+++ /dicompyler/baseplugins/2dview.py Mon Jul 7 15:23:06 2014 UTC
@@ -249,6 +249,10 @@
structure['planes'].keys(), dtype=np.float32)
structure['zkeys'] = structure['planes'].keys()
+ # Return if there are no z positions in the structure data
+ if not len(structure['zarray']):
+ return
+
# Determine the closest z plane to the given position
zmin = np.amin(np.abs(structure['zarray'] - float(position)))
index = np.argmin(np.abs(structure['zarray'] - float(position)))
==============================================================================
Revision: 6efcd2f8a060
Branch: default
Author: Aditya Panchal <
apan...@bastula.org>
Date: Mon Jul 7 20:39:25 2014 UTC
Log: Fixed a bug in the new plugin manager where the plugin tree
control did not completely fill the dialog.
http://code.google.com/p/dicompyler/source/detail?r=6efcd2f8a060
Modified:
/dicompyler/resources/plugin.xrc
=======================================
--- /dicompyler/resources/plugin.xrc Sat Jun 2 03:38:22 2012 UTC
+++ /dicompyler/resources/plugin.xrc Mon Jul 7 20:39:25 2014 UTC
@@ -14,12 +14,20 @@
</object>
<object class="sizeritem">
<object class="wxPanel" name="panelTreeView">
- <object class="wxTreeCtrl" name="tcPlugins">
- <size>250,250</size>
- <style>wxNO_BORDER|wxTR_NO_BUTTONS|wxTR_NO_LINES|
wxTR_FULL_ROW_HIGHLIGHT|wxTR_HIDE_ROOT</style>
- </object>
+
<bg>#FFFFFF</bg>
<style>wxSUNKEN_BORDER</style>
+ <object class="wxBoxSizer">
+ <orient>wxVERTICAL</orient>
+ <object class="sizeritem">
+ <object class="wxTreeCtrl" name="tcPlugins">
+ <size>250,250</size>
+ <style>wxNO_BORDER|wxTR_NO_BUTTONS|wxTR_NO_LINES|
wxTR_FULL_ROW_HIGHLIGHT|wxTR_HIDE_ROOT</style>
+ </object>
+ <option>1</option>
+ <flag>wxALL|wxEXPAND|wxALIGN_CENTRE</flag>
+ </object>
+ </object>
</object>
<flag>wxALL|wxEXPAND|wxALIGN_CENTRE</flag>
</object>
==============================================================================
Revision: 7d976b1d7493
Branch: default
Author: Aditya Panchal <
apan...@bastula.org>
Date: Fri Jul 11 18:05:49 2014 UTC
Log: Updated the setup dependencies for dicompyler and copyright
information year to 2014.
http://code.google.com/p/dicompyler/source/detail?r=7d976b1d7493
Modified:
/dicompyler/license.txt
/dicompyler/main.py
/dicompyler_app.py
/setup.py
=======================================
--- /dicompyler/license.txt Mon May 14 21:16:03 2012 UTC
+++ /dicompyler/license.txt Fri Jul 11 18:05:49 2014 UTC
@@ -1,4 +1,4 @@
-Copyright (c) 2009-2012 Aditya Panchal and dicompyler contributors
+Copyright (c) 2009-2014 Aditya Panchal and dicompyler contributors
All rights reserved.
=======================================
--- /dicompyler/main.py Wed Jul 11 19:22:04 2012 UTC
+++ /dicompyler/main.py Fri Jul 11 18:05:49 2014 UTC
@@ -2,7 +2,7 @@
# -*- coding: ISO-8859-1 -*-
# main.py
"""Main file for dicompyler."""
-# Copyright (c) 2009-2012 Aditya Panchal
+# Copyright (c) 2009-2014 Aditya Panchal
# Copyright (c) 2009 Roy Keyes
# This file is part of dicompyler, released under a BSD license.
# See the file license.txt included with this distribution, also
@@ -863,7 +863,7 @@
info = wx.AboutDialogInfo()
info.Name = "dicompyler"
info.Version = __version__
- info.Copyright = u"© 2009-2012 Aditya Panchal"
+ info.Copyright = u"© 2009-2014 Aditya Panchal"
credits = util.get_credits()
info.Developers = credits['developers']
info.Artists = credits['artists']
=======================================
--- /dicompyler_app.py Mon May 14 21:16:03 2012 UTC
+++ /dicompyler_app.py Fri Jul 11 18:05:49 2014 UTC
@@ -2,7 +2,7 @@
# -*- coding: utf-8 -*-
# dicompyler_app.py
"""Script to start dicompyler without installing from source."""
-# Copyright (c) 2009-2012 Aditya Panchal
+# Copyright (c) 2009-2014 Aditya Panchal
# This file is part of dicompyler, released under a BSD license.
# See the file license.txt included with this distribution, also
# available at
http://code.google.com/p/dicompyler/
=======================================
--- /setup.py Mon May 14 21:16:03 2012 UTC
+++ /setup.py Fri Jul 11 18:05:49 2014 UTC
@@ -1,8 +1,8 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
-# dicompyler.py
+# setup.py
"""Setup script for dicompyler."""
-# Copyright (c) 2012 Aditya Panchal
+# Copyright (c) 2012-2014 Aditya Panchal
# This file is part of dicompyler, relased under a BSD license.
# See the file license.txt included with this distribution, also
# available at
http://code.google.com/p/dicompyler/
@@ -14,10 +14,10 @@
import sys
requires = [
- 'matplotlib>=0.99',
+ 'matplotlib>=0.99, <=1.1.0',
'numpy>=1.2.1',
'pil>=1.1.7',
- 'pydicom>=0.9.5',]
+ 'pydicom>=0.9.5, <0.9.7']
if sys.version_info[0] == 2 and sys.version_info[1] < 6:
requires.append('simplejson')
@@ -32,6 +32,7 @@
'baseplugins/*.py', 'baseplugins/*.xrc']},
zip_safe = False,
install_requires = requires,
+
dependency_links=['
https://pydicom.googlecode.com/files/pydicom-0.9.6.zip'],
entry_points={'console_scripts':['dicompyler =
dicompyler.main:start']},
# metadata for upload to PyPI
@@ -84,10 +85,10 @@
dicompyler requires the following packages to run from source:
- Python 2.5 or higher (not tested on Python 3)
- - wxPython 2.8.8.1 or higher
- - matplotlib 0.99 or higher
+ - wxPython 2.8.8.1 to 2.8.10.1
+ - matplotlib 0.99 to 1.10
- numpy 1.2.1 or higher
- - PIL 1.1.7 or higher
- - pydicom 0.9.5 or higher
+ - PIL 1.1.7 or any version of Pillow
+ - pydicom 0.9.5 or 0.9.6
- simplejson (only for Python 2.5, Python 2.6+ includes JSON
support)""",
)
==============================================================================
Revision: 1c4309763693
Branch: default
Author: Aditya Panchal <
apan...@bastula.org>
Date: Mon Jul 14 16:24:16 2014 UTC
Log: Added tag release-0.4.2 for changeset 7d976b1d7493
http://code.google.com/p/dicompyler/source/detail?r=1c4309763693
Modified:
/.hgtags
=======================================
--- /.hgtags Sun Jan 1 16:38:31 2012 UTC
+++ /.hgtags Mon Jul 14 16:24:16 2014 UTC
@@ -9,3 +9,4 @@
4b9149e2862efb30a1c8b020bcf1fdcdc1b19d27 release-0.4a2
7921a5828fa054eb95d96d98738a2ccd8902d817 release-0.4.1
cf908c73f69649ee13da7d22ae7688883f8eb01f release-0.4.1-1
+7d976b1d74935b36dd382916c8c942293442f75c release-0.4.2