Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
105 commits
Select commit Hold shift + click to select a range
0ff4f5c
Create main.py
Jun 4, 2015
472eb74
Update main.py
Jun 4, 2015
692c6d3
Create candidate.py
Jun 4, 2015
8a13bd9
Create dialogbox.py
Jun 4, 2015
110b159
Create newwindow.py
Jun 4, 2015
7a5e5cc
Create userinterface.py
Jun 4, 2015
9181e25
Create visit.py
Jun 4, 2015
e5727ae
Create candidate
Jun 4, 2015
e096524
Create __init__.py
Jun 4, 2015
f9965fe
Create classtool.py
Jun 4, 2015
114be86
Create datamanagement.py
Jun 4, 2015
b916072
Create multilanguage.py
Jun 4, 2015
771f561
Create utilities.py
Jun 4, 2015
a9817e2
Create test.py
Jun 4, 2015
f2c0fcb
Create test1.py
Jun 4, 2015
2261805
Create test5.py
Jun 4, 2015
dae09a0
Create create1_StudySetup.py
Jun 4, 2015
9725f2e
Create create2_CandidateList_test.py
Jun 4, 2015
4db0a28
Create create3_CandidateVisit.py
Jun 4, 2015
da9575a
Create create4_PopulateVisits.py
Jun 4, 2015
98eda7c
Create create_alldata.py
Jun 4, 2015
2a3beea
Update classtool.py
Jun 4, 2015
e8fdb55
Removed data file extension and renamed candidate data file to candid…
Jul 13, 2015
2a1e943
Changed names for data files (candidate for candidatedata and studyse…
Jul 14, 2015
33e757e
Merge remote-tracking branch 'origin/master'
Jul 15, 2015
311f457
2015-07-27: Update
Jul 27, 2015
fa35185
Implemented close function under Application/Quitter. Also replaced b…
cmadjar Jul 27, 2015
e1e01d3
Added dialog_quit text in the english section.
cmadjar Jul 27, 2015
5fbdee3
Replaced button OK and Cancel by Yes and No in dialog box to quit.
cmadjar Jul 27, 2015
43837a7
Renamed Data Window to Candidate information (information sur le cand…
cmadjar Jul 27, 2015
a3a6eb6
Merge pull request #1 from cmadjar/Hackathon_Scheduler
Jul 28, 2015
d49d981
Merge remote-tracking branch 'origin/master'
Jul 28, 2015
9c080a7
Hackathon - 20150728
Jul 28, 2015
26a61df
20160517
May 17, 2016
c4ba359
Merge remote-tracking branch 'PierreEMorin/master' into DicAT_new_GUI…
cmadjar May 17, 2016
2161f09
20160517 - added data files
May 17, 2016
972ed9a
Merge remote-tracking branch 'PierreEMorin/master' into DicAT_new_GUI…
cmadjar May 17, 2016
594becc
20160517 - added data files
May 17, 2016
3fbcdef
Merge remote-tracking branch 'PierreEMorin/master' into DicAT_new_GUI…
cmadjar May 17, 2016
0dc73df
Added Windows executable in a zip folder, as well as the files that a…
cmadjar May 17, 2016
e356d48
Added Windows executable in a zip folder, as well as the files that a…
cmadjar May 17, 2016
9500b5f
Added candidatedata, will need to be removed...
cmadjar May 20, 2016
d39b2b2
Merge branch 'DICAT_GUI' into DicAT_new_GUI_with_scheduler
cmadjar Jun 17, 2016
d00bf40
Merge remote-tracking branch 'aces/master' into DicAT_new_GUI_with_sc…
cmadjar Jun 17, 2016
a9404f2
Put the menu back on the application!
cmadjar Jun 17, 2016
46bd408
Removed the DICOM anonymizer menu
cmadjar Jun 23, 2016
72a7993
Moved the project info pane into the window pane of the scheduler ins…
cmadjar Jun 24, 2016
0c7e4bc
Added the scheduler scripts to github.
cmadjar Jun 24, 2016
b4df584
Push the rest of DICAT scripts
cmadjar Jun 24, 2016
3177c85
removing duplicate files
cmadjar Jun 24, 2016
50f68b6
Removed scheduler folder
cmadjar Jun 24, 2016
6d216c2
Fixed a minor import bug
cmadjar Jun 24, 2016
ab3e92a
Removed unnecessary dictionary
cmadjar Jun 24, 2016
e41bef6
Imported the candidate data based on the XML values
cmadjar Jun 24, 2016
2a5b6a6
Fixing window closing buttons.
taracampbell Jun 25, 2016
2891ba5
Merge pull request #1 from taracampbell/fix_data_window_buttons
cmadjar Jun 25, 2016
89406ca
Started the visit pane
cmadjar Jun 25, 2016
e5942c0
Merge branch 'DicAT_new_GUI_with_scheduler' into DicAT_new_GUI_with_s…
cmadjar Jun 25, 2016
077bc64
Finished reading the data from the XML file on the front page of the …
cmadjar Jun 25, 2016
38a6387
Merge pull request #2 from cmadjar/DicAT_new_GUI_with_scheduler_XML
cmadjar Jun 25, 2016
0e0b4a2
Destory edit table frame in the anonymizer if it already exists.
taracampbell Jun 25, 2016
7d7ce1a
Pop up window with candidate information displaying. Still need to ma…
cmadjar Jun 25, 2016
bc4422c
Modified xmlfile to be a global variable defined in config.py and cal…
cmadjar Jun 25, 2016
478aa8d
Merge pull request #3 from taracampbell/refresh_dicom_anonymizer_table
cmadjar Jun 25, 2016
51d65a4
Merge pull request #4 from cmadjar/DicAT_new_GUI_with_scheduler_XML
cmadjar Jun 25, 2016
a600fdf
Committing changes that were not saved
cmadjar Jul 7, 2016
c43d4d7
On 'View DICOM fields' click, remove dicom edit table if it already e…
cmadjar Jul 7, 2016
00e67f2
Rename DicAT_application.py to be DICAT.py
cmadjar Jul 7, 2016
d054136
Modified the documentation to rename DICAT_application.py to DICAT.py
cmadjar Jul 7, 2016
1cabf0b
Enabled edition of candidate's information
cmadjar Jul 11, 2016
3db6e0b
Merge pull request #33 from cmadjar/FixViewDICOMfieldsClick
driusan Jul 14, 2016
1d38bdd
Merge pull request #34 from cmadjar/Rename_dicat_application_main_script
driusan Jul 14, 2016
60a2335
Modified ID Mapper to be reading same input as scheduler.
cmadjar Jul 25, 2016
5fb5f28
Cleaned up some TODO statements.
cmadjar Jul 26, 2016
73c6f59
Fixed issue #58 - Edition of a candidate in the ID mapper does not er…
cmadjar Jul 26, 2016
43515d5
Fixed the way self.text_pscid_var are initialized
cmadjar Jul 26, 2016
f84921f
Fixed issue #54 - Refresh candidate's list when adding a new candidate
cmadjar Jul 26, 2016
6da35bc
Fixed first part of issue #39 - implementation of a drop down for can…
cmadjar Jul 26, 2016
9f7cf83
Cleaned up folowing files:
cmadjar Jul 27, 2016
6b72ab7
Cleaned up datamanagement.py file
cmadjar Jul 27, 2016
f5ee862
Cleaned up dicat/lib/dicom_anonymizer_methods.py.
cmadjar Jul 27, 2016
908f5ea
Cleaned up following files:
cmadjar Jul 27, 2016
98ef4f4
Cleaned up the following files:
cmadjar Jul 27, 2016
20ef413
Added check for DOB in scheduler data window. Moved the check for DOB…
cmadjar Jul 27, 2016
3f7a6fd
Added error checking when entering/editing candidate's informations (…
cmadjar Jul 27, 2016
6b09e3a
Can now open an XML database from the Welcome tab. Selecting the IDMa…
cmadjar Jul 27, 2016
e22be0f
Allowed creation of a new database base on a database template file (…
cmadjar Jul 27, 2016
d23207c
Moved the candidate info checks into the lib/candidate.py library and…
cmadjar Jul 28, 2016
d07203d
Forgot to add this file to the last commit
cmadjar Jul 28, 2016
08263ba
Cleaned up datawindow.py
cmadjar Jul 28, 2016
c7a51ac
deleted: dicat/__init__.py
cmadjar Jul 28, 2016
f7a2e0b
Cleaned up dialogbox.py
cmadjar Jul 28, 2016
1a1f218
Added filtering functionality to IDMapper and renamed IDMapper functi…
cmadjar Jul 28, 2016
19fea56
Renamed function names of datamanagement.py to fit python convention …
cmadjar Jul 28, 2016
d910456
Renamed functions in following files to match Python convention.
cmadjar Jul 28, 2016
059b985
Finalized renaming function names to Python convention.
cmadjar Jul 28, 2016
4053fa6
Show a warning at the bottom of the ID mapper when filters are in fun…
cmadjar Jul 28, 2016
2b22c64
Merge remote-tracking branch 'aces/2.1-dev' into DicAT_new_GUI_with_s…
cmadjar Jul 28, 2016
885f3fd
Set the flag for new candidates back to 'new' and added a 'search' fl…
cmadjar Jul 28, 2016
73c8440
Restructuration of datawindow.py
cmadjar Jul 28, 2016
2958e30
Finished cleaning up datawindow.py and added a text to be displayed i…
cmadjar Jul 29, 2016
47e65f6
Implemented a search filter for the scheduler (#42). Also replaced re…
cmadjar Jul 29, 2016
e29c98c
Removed candidate and visit menus
cmadjar Jul 29, 2016
01f3f3f
Fixed a bug that did not write correctly in the XML file.
cmadjar Jul 29, 2016
208da47
Included a date picker for the date of birth using the code made avai…
cmadjar Jul 29, 2016
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,9 +42,9 @@ To install DICAT source code on a computer, download and save the content of the

Before running DICAT, make sure your systems contains a [Python](https://www.python.org) compiler with the [TkInter](https://wiki.python.org/moin/TkInter) library (usually, TkInter comes by default with most Python installations. The [PyDICOM](http://www.pydicom.org) package is also required by DICAT.

DICAT can be started by executing `DICAT_application.py` script with a Python compiler. On UNIX computers (Linux and Mac OS X), open a terminal, go to the main directory of DICAT source code (`dicat` directory) and run the following:
DICAT can be started by executing `DICAT.py` script with a Python compiler. On UNIX computers (Linux and Mac OS X), open a terminal, go to the main directory of DICAT source code (`dicat` directory) and run the following:

```python DICAT_application.py```
```python DICAT.py```


## How to use the DICOM de-identifier of DICAT?
Expand Down
41 changes: 41 additions & 0 deletions dicat/CalendarDialog/CalendarDialog.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import Tkinter
import ttkcalendar

import tkSimpleDialog


class CalendarDialog(tkSimpleDialog.Dialog):
"""Dialog box that displays a calendar and returns the selected date"""
def body(self, master):
self.calendar = ttkcalendar.Calendar(master)
self.calendar.pack()

def apply(self):
self.result = self.calendar.selection

# Demo code:


class CalendarFrame(Tkinter.LabelFrame):
def __init__(self, master):
Tkinter.LabelFrame.__init__(self, master, text="CalendarDialog Demo")

def getdate():
cd = CalendarDialog(self)
result = cd.result
self.selected_date.set(result.strftime("%m/%d/%Y"))

self.selected_date = Tkinter.StringVar()

Tkinter.Entry(self, textvariable=self.selected_date).pack(side=Tkinter.LEFT)
Tkinter.Button(self, text="Choose a date", command=getdate).pack(side=Tkinter.LEFT)


def main():
root = Tkinter.Tk()
root.wm_title("CalendarDialog Demo")
CalendarFrame(root).pack()
root.mainloop()

if __name__ == "__main__":
main()
7 changes: 7 additions & 0 deletions dicat/CalendarDialog/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
__author__ = 'cmadjar'

"""
These scripts have been downloaded from the following GitHub repository and
allows to have date picker widgets and maybe some calendar functionality?
https://github.com/moshekaplan/tkinter_components
"""
94 changes: 94 additions & 0 deletions dicat/CalendarDialog/tkSimpleDialog.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
from Tkinter import *
from ttk import *

class Dialog(Toplevel):
"""Sourced from http://effbot.org/tkinterbook/tkinter-dialog-windows.htm"""
def __init__(self, parent, title = None):

Toplevel.__init__(self, parent)
self.transient(parent)

if title:
self.title(title)

self.parent = parent

self.result = None

body = Frame(self)
self.initial_focus = self.body(body)
body.pack(padx=5, pady=5)

self.buttonbox()

self.grab_set()

if not self.initial_focus:
self.initial_focus = self

self.protocol("WM_DELETE_WINDOW", self.cancel)

self.geometry("+%d+%d" % (parent.winfo_rootx()+50,
parent.winfo_rooty()+50))

self.initial_focus.focus_set()

self.wait_window(self)

#
# construction hooks

def body(self, master):
# create dialog body. return widget that should have
# initial focus. this method should be overridden

pass

def buttonbox(self):
# add standard button box. override if you don't want the
# standard buttons

box = Frame(self)

w = Button(box, text="OK", width=10, command=self.ok, default=ACTIVE)
w.pack(side=LEFT, padx=5, pady=5)
w = Button(box, text="Cancel", width=10, command=self.cancel)
w.pack(side=LEFT, padx=5, pady=5)

self.bind("<Return>", self.ok)
self.bind("<Escape>", self.cancel)

box.pack()

#
# standard button semantics

def ok(self, event=None):

if not self.validate():
self.initial_focus.focus_set() # put focus back
return

self.withdraw()
self.update_idletasks()

self.apply()

self.cancel()

def cancel(self, event=None):

# put focus back to the parent window
self.parent.focus_set()
self.destroy()

#
# command hooks

def validate(self):

return 1 # override

def apply(self):

pass # override
236 changes: 236 additions & 0 deletions dicat/CalendarDialog/ttkcalendar.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,236 @@
# Source: http://svn.python.org/projects/sandbox/trunk/ttk-gsoc/samples/ttkcalendar.py

"""
Simple calendar using ttk Treeview together with calendar and datetime
classes.
"""
import calendar

try:
import Tkinter
import tkFont
except ImportError: # py3k
import tkinter as Tkinter
import tkinter.font as tkFont

import ttk

def get_calendar(locale, fwday):
# instantiate proper calendar class
if locale is None:
return calendar.TextCalendar(fwday)
else:
return calendar.LocaleTextCalendar(fwday, locale)

class Calendar(ttk.Frame):
# XXX ToDo: cget and configure

datetime = calendar.datetime.datetime
timedelta = calendar.datetime.timedelta

def __init__(self, master=None, **kw):
"""
WIDGET-SPECIFIC OPTIONS

locale, firstweekday, year, month, selectbackground,
selectforeground
"""
# remove custom options from kw before initializating ttk.Frame
fwday = kw.pop('firstweekday', calendar.MONDAY)
year = kw.pop('year', self.datetime.now().year)
month = kw.pop('month', self.datetime.now().month)
locale = kw.pop('locale', None)
sel_bg = kw.pop('selectbackground', '#ecffc4')
sel_fg = kw.pop('selectforeground', '#05640e')

self._date = self.datetime(year, month, 1)
self._selection = None # no date selected

ttk.Frame.__init__(self, master, **kw)

self._cal = get_calendar(locale, fwday)

self.__setup_styles() # creates custom styles
self.__place_widgets() # pack/grid used widgets
self.__config_calendar() # adjust calendar columns and setup tags
# configure a canvas, and proper bindings, for selecting dates
self.__setup_selection(sel_bg, sel_fg)

# store items ids, used for insertion later
self._items = [self._calendar.insert('', 'end', values='')
for _ in range(6)]
# insert dates in the currently empty calendar
self._build_calendar()

def __setitem__(self, item, value):
if item in ('year', 'month'):
raise AttributeError("attribute '%s' is not writeable" % item)
elif item == 'selectbackground':
self._canvas['background'] = value
elif item == 'selectforeground':
self._canvas.itemconfigure(self._canvas.text, item=value)
else:
ttk.Frame.__setitem__(self, item, value)

def __getitem__(self, item):
if item in ('year', 'month'):
return getattr(self._date, item)
elif item == 'selectbackground':
return self._canvas['background']
elif item == 'selectforeground':
return self._canvas.itemcget(self._canvas.text, 'fill')
else:
r = ttk.tclobjs_to_py({item: ttk.Frame.__getitem__(self, item)})
return r[item]

def __setup_styles(self):
# custom ttk styles
style = ttk.Style(self.master)
arrow_layout = lambda dir: (
[('Button.focus', {'children': [('Button.%sarrow' % dir, None)]})]
)
style.layout('L.TButton', arrow_layout('left'))
style.layout('R.TButton', arrow_layout('right'))

def __place_widgets(self):
# header frame and its widgets
hframe = ttk.Frame(self)
lbtn = ttk.Button(hframe, style='L.TButton', command=self._prev_month)
rbtn = ttk.Button(hframe, style='R.TButton', command=self._next_month)
self._header = ttk.Label(hframe, width=15, anchor='center')
# the calendar
self._calendar = ttk.Treeview(self, show='', selectmode='none', height=7)

# pack the widgets
hframe.pack(in_=self, side='top', pady=4, anchor='center')
lbtn.grid(in_=hframe)
self._header.grid(in_=hframe, column=1, row=0, padx=12)
rbtn.grid(in_=hframe, column=2, row=0)
self._calendar.pack(in_=self, expand=1, fill='both', side='bottom')

def __config_calendar(self):
cols = self._cal.formatweekheader(3).split()
self._calendar['columns'] = cols
self._calendar.tag_configure('header', background='grey90')
self._calendar.insert('', 'end', values=cols, tag='header')
# adjust its columns width
font = tkFont.Font()
maxwidth = max(font.measure(col) for col in cols)
for col in cols:
self._calendar.column(col, width=maxwidth, minwidth=maxwidth,
anchor='e')

def __setup_selection(self, sel_bg, sel_fg):
self._font = tkFont.Font()
self._canvas = canvas = Tkinter.Canvas(self._calendar,
background=sel_bg, borderwidth=0, highlightthickness=0)
canvas.text = canvas.create_text(0, 0, fill=sel_fg, anchor='w')

canvas.bind('<ButtonPress-1>', lambda evt: canvas.place_forget())
self._calendar.bind('<Configure>', lambda evt: canvas.place_forget())
self._calendar.bind('<ButtonPress-1>', self._pressed)

def __minsize(self, evt):
width, height = self._calendar.master.geometry().split('x')
height = height[:height.index('+')]
self._calendar.master.minsize(width, height)

def _build_calendar(self):
year, month = self._date.year, self._date.month

# update header text (Month, YEAR)
header = self._cal.formatmonthname(year, month, 0)
self._header['text'] = header.title()

# update calendar shown dates
cal = self._cal.monthdayscalendar(year, month)
for indx, item in enumerate(self._items):
week = cal[indx] if indx < len(cal) else []
fmt_week = [('%02d' % day) if day else '' for day in week]
self._calendar.item(item, values=fmt_week)

def _show_selection(self, text, bbox):
"""Configure canvas for a new selection."""
x, y, width, height = bbox

textw = self._font.measure(text)

canvas = self._canvas
canvas.configure(width=width, height=height)
canvas.coords(canvas.text, width - textw, height / 2 - 1)
canvas.itemconfigure(canvas.text, text=text)
canvas.place(in_=self._calendar, x=x, y=y)

# Callbacks

def _pressed(self, evt):
"""Clicked somewhere in the calendar."""
x, y, widget = evt.x, evt.y, evt.widget
item = widget.identify_row(y)
column = widget.identify_column(x)

if not column or not item in self._items:
# clicked in the weekdays row or just outside the columns
return

item_values = widget.item(item)['values']
if not len(item_values): # row is empty for this month
return

text = item_values[int(column[1]) - 1]
if not text: # date is empty
return

bbox = widget.bbox(item, column)
if not bbox: # calendar not visible yet
return

# update and then show selection
text = '%02d' % text
self._selection = (text, item, column)
self._show_selection(text, bbox)

def _prev_month(self):
"""Updated calendar to show the previous month."""
self._canvas.place_forget()

self._date = self._date - self.timedelta(days=1)
self._date = self.datetime(self._date.year, self._date.month, 1)
self._build_calendar() # reconstuct calendar

def _next_month(self):
"""Update calendar to show the next month."""
self._canvas.place_forget()

year, month = self._date.year, self._date.month
self._date = self._date + self.timedelta(
days=calendar.monthrange(year, month)[1] + 1)
self._date = self.datetime(self._date.year, self._date.month, 1)
self._build_calendar() # reconstruct calendar

# Properties

@property
def selection(self):
"""Return a datetime representing the current selected date."""
if not self._selection:
return None

year, month = self._date.year, self._date.month
return self.datetime(year, month, int(self._selection[0]))

def test():
import sys
root = Tkinter.Tk()
root.title('Ttk Calendar')
ttkcal = Calendar(firstweekday=calendar.SUNDAY)
ttkcal.pack(expand=1, fill='both')

if 'win' not in sys.platform:
style = ttk.Style()
style.theme_use('clam')

root.mainloop()

if __name__ == '__main__':
test()
Loading