HG corrupted local copy, lost 22 changesets
This commit is contained in:
		
							
								
								
									
										2
									
								
								issues/libpit/0021bs5.rst
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										2
									
								
								issues/libpit/0021bs5.rst
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,2 @@ | ||||
| Fix Issue.toString() so that only the first letter is capitalized. | ||||
| ================================================================== | ||||
							
								
								
									
										33
									
								
								issues/libpit/0021fs.rst
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										33
									
								
								issues/libpit/0021fs.rst
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,33 @@ | ||||
| Divorce opened/closed status and classification. | ||||
| ================================================ | ||||
|  | ||||
| We need to track open/closed status and classification independantly. | ||||
|  | ||||
| Classification is one category, status should be another. Possible values for | ||||
| status: | ||||
|  | ||||
| * new | ||||
| * resolved | ||||
| * awaiting validation | ||||
| * rejected | ||||
| * reassigned | ||||
|  | ||||
| For the file-based issue implementation, the file format changes from | ||||
| ``nnnnsp`` to ``nnnncsp`` where: | ||||
|  | ||||
|     * ``nnnn`` still represents the bug number (no change) | ||||
|     * ``c`` represents the *category* (used to be ``s`` the status): | ||||
|  | ||||
|         * ``b``: Bug | ||||
|         * ``f``: Feature | ||||
|         * ``t``: Task | ||||
|  | ||||
|     * ``s`` represents *status*, a new field: | ||||
|  | ||||
|         * ``a``: Reassigned | ||||
|         * ``j``: Rejected | ||||
|         * ``n``: New | ||||
|         * ``s``: Resolved | ||||
|         * ``v``: Awaiting Validation | ||||
|     * ``p`` still represents priority, ``0`` being the highest and ``9`` the | ||||
|       lowest. | ||||
							
								
								
									
										5
									
								
								issues/pit-swing/0000fn5.rst
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										5
									
								
								issues/pit-swing/0000fn5.rst
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,5 @@ | ||||
| Remember last opened directory. | ||||
| =============================== | ||||
|  | ||||
| This affects the JFileChooser, not the model.rootProject. | ||||
|  | ||||
							
								
								
									
										2
									
								
								issues/pit-swing/0001fa5.rst
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										2
									
								
								issues/pit-swing/0001fa5.rst
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,2 @@ | ||||
| De-select the 'CLOSED' category by default. | ||||
| =========================================== | ||||
							
								
								
									
										2
									
								
								issues/pit-swing/0002ts7.rst
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										2
									
								
								issues/pit-swing/0002ts7.rst
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,2 @@ | ||||
| Clear the 'New Task...' dialog when hidden. | ||||
| =========================================== | ||||
							
								
								
									
										2
									
								
								issues/pit-swing/0003ts7.rst
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										2
									
								
								issues/pit-swing/0003ts7.rst
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,2 @@ | ||||
| Set the default priority to '5'. | ||||
| ================================ | ||||
							
								
								
									
										2
									
								
								issues/pit-swing/0004ts5.rst
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										2
									
								
								issues/pit-swing/0004ts5.rst
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,2 @@ | ||||
| Issue display needs to save changes. | ||||
| ==================================== | ||||
							
								
								
									
										2
									
								
								issues/pit-swing/0005ts5.rst
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										2
									
								
								issues/pit-swing/0005ts5.rst
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,2 @@ | ||||
| Do not load project directory on startup. | ||||
| ========================================= | ||||
							
								
								
									
										2
									
								
								issues/pit-swing/0006ts5.rst
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										2
									
								
								issues/pit-swing/0006ts5.rst
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,2 @@ | ||||
| Clear project lists when opening a new directory. | ||||
| ================================================= | ||||
							
								
								
									
										5
									
								
								issues/pit-swing/0007bn5.rst
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										5
									
								
								issues/pit-swing/0007bn5.rst
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,5 @@ | ||||
| Issue display may still lose changes. | ||||
| ===================================== | ||||
|  | ||||
| If the mouse is not within the text area and the user clicks on something | ||||
| that changes the text area content, the changes are not saved. | ||||
							
								
								
									
										1
									
								
								issues/pit-swing/0008fn7.rst
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								issues/pit-swing/0008fn7.rst
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1 @@ | ||||
| Add an optional word-wrap at 80 characters for the Issue display | ||||
							
								
								
									
										2
									
								
								issues/pit-swing/0009tn7.rst
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										2
									
								
								issues/pit-swing/0009tn7.rst
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,2 @@ | ||||
| Make 'New' the default new issue status. | ||||
| ======================================== | ||||
							
								
								
									
										2
									
								
								issues/pit-swing/0010fn7.rst
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										2
									
								
								issues/pit-swing/0010fn7.rst
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,2 @@ | ||||
| Add the ability to sort issues based on priority, id, category, or status. | ||||
| ========================================================================== | ||||
| @@ -1,10 +1,10 @@ | ||||
| #Thu Feb 25 17:24:06 CST 2010 | ||||
| #Fri Feb 26 11:43:12 CST 2010 | ||||
| build.dir=build | ||||
| src.dir=src | ||||
| lib.shared.dir=../shared-libs | ||||
| test.dir=test | ||||
| build.number=1 | ||||
| expected.application.version=1.1.8 | ||||
| build.number=2 | ||||
| expected.application.version=2.0.1 | ||||
| lib.dir=lib | ||||
| release.dir=release | ||||
| release.jar=pit-${application.version}.jar | ||||
|   | ||||
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										
											BIN
										
									
								
								libpit/release/pit-2.0.1.jar
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								libpit/release/pit-2.0.1.jar
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| @@ -46,6 +46,8 @@ badd +1 src/com/jdbernard/pit/FileIssue.groovy | ||||
| badd +1 test/com/jdbernard/pit/FileIssueTest.groovy | ||||
| badd +1 src/com/jdbernard/pit/FileProject.groovy | ||||
| badd +1 test/com/jdbernard/pit/FileProjectTest.groovy | ||||
| badd +1 src/com/jdbernard/pit/Status.groovy | ||||
| badd +0 test/com/jdbernard/pit/StatusTest.groovy | ||||
| args build.xml | ||||
| edit build.xml | ||||
| set splitbelow splitright | ||||
| @@ -155,7 +157,7 @@ setlocal nowinfixwidth | ||||
| setlocal wrap | ||||
| setlocal wrapmargin=0 | ||||
| silent! normal! zE | ||||
| let s:l = 1 - ((0 * winheight(0) + 39) / 78) | ||||
| let s:l = 1 - ((0 * winheight(0) + 28) / 57) | ||||
| if s:l < 1 | let s:l = 1 | endif | ||||
| exe s:l | ||||
| normal! zt | ||||
| @@ -259,7 +261,7 @@ setlocal nowinfixwidth | ||||
| setlocal wrap | ||||
| setlocal wrapmargin=0 | ||||
| silent! normal! zE | ||||
| let s:l = 1 - ((0 * winheight(0) + 39) / 78) | ||||
| let s:l = 1 - ((0 * winheight(0) + 28) / 57) | ||||
| if s:l < 1 | let s:l = 1 | endif | ||||
| exe s:l | ||||
| normal! zt | ||||
| @@ -376,7 +378,7 @@ setlocal nowinfixwidth | ||||
| setlocal wrap | ||||
| setlocal wrapmargin=0 | ||||
| silent! normal! zE | ||||
| let s:l = 1 - ((0 * winheight(0) + 39) / 78) | ||||
| let s:l = 1 - ((0 * winheight(0) + 28) / 57) | ||||
| if s:l < 1 | let s:l = 1 | endif | ||||
| exe s:l | ||||
| normal! zt | ||||
| @@ -480,7 +482,228 @@ setlocal nowinfixwidth | ||||
| setlocal wrap | ||||
| setlocal wrapmargin=0 | ||||
| silent! normal! zE | ||||
| let s:l = 1 - ((0 * winheight(0) + 39) / 78) | ||||
| let s:l = 1 - ((0 * winheight(0) + 28) / 57) | ||||
| if s:l < 1 | let s:l = 1 | endif | ||||
| exe s:l | ||||
| normal! zt | ||||
| 1 | ||||
| normal! 0 | ||||
| wincmd w | ||||
| exe 'vert 1resize ' . ((&columns * 91 + 91) / 182) | ||||
| exe 'vert 2resize ' . ((&columns * 90 + 91) / 182) | ||||
| tabedit src/com/jdbernard/pit/Status.groovy | ||||
| set splitbelow splitright | ||||
| wincmd _ | wincmd | | ||||
| vsplit | ||||
| 1wincmd h | ||||
| wincmd w | ||||
| set nosplitbelow | ||||
| set nosplitright | ||||
| wincmd t | ||||
| set winheight=1 winwidth=1 | ||||
| exe 'vert 1resize ' . ((&columns * 91 + 91) / 182) | ||||
| exe 'vert 2resize ' . ((&columns * 90 + 91) / 182) | ||||
| argglobal | ||||
| setlocal keymap= | ||||
| setlocal noarabic | ||||
| setlocal autoindent | ||||
| setlocal balloonexpr= | ||||
| setlocal nobinary | ||||
| setlocal bufhidden= | ||||
| setlocal buflisted | ||||
| setlocal buftype= | ||||
| setlocal nocindent | ||||
| setlocal cinkeys=0{,0},0),:,0#,!^F,o,O,e | ||||
| setlocal cinoptions= | ||||
| setlocal cinwords=if,else,while,do,for,switch | ||||
| setlocal comments=s1:/*,mb:*,ex:*/,://,b:#,:%,:XCOMM,n:>,fb:- | ||||
| setlocal commentstring=/*%s*/ | ||||
| setlocal complete=.,w,b,u,t,i | ||||
| setlocal completefunc= | ||||
| setlocal nocopyindent | ||||
| setlocal nocursorcolumn | ||||
| setlocal nocursorline | ||||
| setlocal define= | ||||
| setlocal dictionary= | ||||
| setlocal nodiff | ||||
| setlocal equalprg= | ||||
| setlocal errorformat= | ||||
| setlocal expandtab | ||||
| if &filetype != 'groovy' | ||||
| setlocal filetype=groovy | ||||
| endif | ||||
| setlocal foldcolumn=0 | ||||
| setlocal foldenable | ||||
| setlocal foldexpr=0 | ||||
| setlocal foldignore=# | ||||
| setlocal foldlevel=0 | ||||
| setlocal foldmarker={{{,}}} | ||||
| setlocal foldmethod=manual | ||||
| setlocal foldminlines=1 | ||||
| setlocal foldnestmax=20 | ||||
| setlocal foldtext=foldtext() | ||||
| setlocal formatexpr= | ||||
| setlocal formatoptions=tcq | ||||
| setlocal formatlistpat=^\\s*\\d\\+[\\]:.)}\\t\ ]\\s* | ||||
| setlocal grepprg= | ||||
| setlocal iminsert=2 | ||||
| setlocal imsearch=2 | ||||
| setlocal include= | ||||
| setlocal includeexpr= | ||||
| setlocal indentexpr= | ||||
| setlocal indentkeys=0{,0},:,0#,!^F,o,O,e | ||||
| setlocal noinfercase | ||||
| setlocal iskeyword=@,48-57,_,192-255 | ||||
| setlocal keywordprg= | ||||
| setlocal nolinebreak | ||||
| setlocal nolisp | ||||
| setlocal nolist | ||||
| setlocal makeprg= | ||||
| setlocal matchpairs=(:),{:},[:] | ||||
| setlocal nomodeline | ||||
| setlocal modifiable | ||||
| setlocal nrformats=octal,hex | ||||
| set number | ||||
| setlocal number | ||||
| setlocal numberwidth=4 | ||||
| setlocal omnifunc= | ||||
| setlocal path= | ||||
| setlocal nopreserveindent | ||||
| setlocal nopreviewwindow | ||||
| setlocal quoteescape=\\ | ||||
| setlocal noreadonly | ||||
| setlocal norightleft | ||||
| setlocal rightleftcmd=search | ||||
| setlocal noscrollbind | ||||
| setlocal shiftwidth=4 | ||||
| setlocal noshortname | ||||
| setlocal nosmartindent | ||||
| setlocal softtabstop=0 | ||||
| setlocal nospell | ||||
| setlocal spellcapcheck=[.?!]\\_[\\])'\"\	\ ]\\+ | ||||
| setlocal spellfile= | ||||
| setlocal spelllang=en | ||||
| setlocal statusline= | ||||
| setlocal suffixesadd= | ||||
| setlocal swapfile | ||||
| setlocal synmaxcol=3000 | ||||
| if &syntax != 'groovy' | ||||
| setlocal syntax=groovy | ||||
| endif | ||||
| setlocal tabstop=4 | ||||
| setlocal tags= | ||||
| setlocal textwidth=0 | ||||
| setlocal thesaurus= | ||||
| setlocal nowinfixheight | ||||
| setlocal nowinfixwidth | ||||
| setlocal wrap | ||||
| setlocal wrapmargin=0 | ||||
| silent! normal! zE | ||||
| let s:l = 37 - ((36 * winheight(0) + 28) / 57) | ||||
| if s:l < 1 | let s:l = 1 | endif | ||||
| exe s:l | ||||
| normal! zt | ||||
| 37 | ||||
| normal! 065l | ||||
| wincmd w | ||||
| argglobal | ||||
| edit test/com/jdbernard/pit/StatusTest.groovy | ||||
| setlocal keymap= | ||||
| setlocal noarabic | ||||
| setlocal autoindent | ||||
| setlocal balloonexpr= | ||||
| setlocal nobinary | ||||
| setlocal bufhidden= | ||||
| setlocal buflisted | ||||
| setlocal buftype= | ||||
| setlocal nocindent | ||||
| setlocal cinkeys=0{,0},0),:,0#,!^F,o,O,e | ||||
| setlocal cinoptions= | ||||
| setlocal cinwords=if,else,while,do,for,switch | ||||
| setlocal comments=s1:/*,mb:*,ex:*/,://,b:#,:%,:XCOMM,n:>,fb:- | ||||
| setlocal commentstring=/*%s*/ | ||||
| setlocal complete=.,w,b,u,t,i | ||||
| setlocal completefunc= | ||||
| setlocal nocopyindent | ||||
| setlocal nocursorcolumn | ||||
| setlocal nocursorline | ||||
| setlocal define= | ||||
| setlocal dictionary= | ||||
| setlocal nodiff | ||||
| setlocal equalprg= | ||||
| setlocal errorformat= | ||||
| setlocal expandtab | ||||
| if &filetype != 'groovy' | ||||
| setlocal filetype=groovy | ||||
| endif | ||||
| setlocal foldcolumn=0 | ||||
| setlocal foldenable | ||||
| setlocal foldexpr=0 | ||||
| setlocal foldignore=# | ||||
| setlocal foldlevel=0 | ||||
| setlocal foldmarker={{{,}}} | ||||
| setlocal foldmethod=manual | ||||
| setlocal foldminlines=1 | ||||
| setlocal foldnestmax=20 | ||||
| setlocal foldtext=foldtext() | ||||
| setlocal formatexpr= | ||||
| setlocal formatoptions=tcq | ||||
| setlocal formatlistpat=^\\s*\\d\\+[\\]:.)}\\t\ ]\\s* | ||||
| setlocal grepprg= | ||||
| setlocal iminsert=2 | ||||
| setlocal imsearch=2 | ||||
| setlocal include= | ||||
| setlocal includeexpr= | ||||
| setlocal indentexpr= | ||||
| setlocal indentkeys=0{,0},:,0#,!^F,o,O,e | ||||
| setlocal noinfercase | ||||
| setlocal iskeyword=@,48-57,_,192-255 | ||||
| setlocal keywordprg= | ||||
| setlocal nolinebreak | ||||
| setlocal nolisp | ||||
| setlocal nolist | ||||
| setlocal makeprg= | ||||
| setlocal matchpairs=(:),{:},[:] | ||||
| setlocal nomodeline | ||||
| setlocal modifiable | ||||
| setlocal nrformats=octal,hex | ||||
| set number | ||||
| setlocal number | ||||
| setlocal numberwidth=4 | ||||
| setlocal omnifunc= | ||||
| setlocal path= | ||||
| setlocal nopreserveindent | ||||
| setlocal nopreviewwindow | ||||
| setlocal quoteescape=\\ | ||||
| setlocal noreadonly | ||||
| setlocal norightleft | ||||
| setlocal rightleftcmd=search | ||||
| setlocal noscrollbind | ||||
| setlocal shiftwidth=4 | ||||
| setlocal noshortname | ||||
| setlocal nosmartindent | ||||
| setlocal softtabstop=0 | ||||
| setlocal nospell | ||||
| setlocal spellcapcheck=[.?!]\\_[\\])'\"\	\ ]\\+ | ||||
| setlocal spellfile= | ||||
| setlocal spelllang=en | ||||
| setlocal statusline= | ||||
| setlocal suffixesadd= | ||||
| setlocal swapfile | ||||
| setlocal synmaxcol=3000 | ||||
| if &syntax != 'groovy' | ||||
| setlocal syntax=groovy | ||||
| endif | ||||
| setlocal tabstop=4 | ||||
| setlocal tags= | ||||
| setlocal textwidth=0 | ||||
| setlocal thesaurus= | ||||
| setlocal nowinfixheight | ||||
| setlocal nowinfixwidth | ||||
| setlocal wrap | ||||
| setlocal wrapmargin=0 | ||||
| silent! normal! zE | ||||
| let s:l = 1 - ((0 * winheight(0) + 28) / 57) | ||||
| if s:l < 1 | let s:l = 1 | endif | ||||
| exe s:l | ||||
| normal! zt | ||||
| @@ -597,7 +820,7 @@ setlocal nowinfixwidth | ||||
| setlocal wrap | ||||
| setlocal wrapmargin=0 | ||||
| silent! normal! zE | ||||
| let s:l = 1 - ((0 * winheight(0) + 39) / 78) | ||||
| let s:l = 1 - ((0 * winheight(0) + 28) / 57) | ||||
| if s:l < 1 | let s:l = 1 | endif | ||||
| exe s:l | ||||
| normal! zt | ||||
| @@ -701,7 +924,7 @@ setlocal nowinfixwidth | ||||
| setlocal wrap | ||||
| setlocal wrapmargin=0 | ||||
| silent! normal! zE | ||||
| let s:l = 1 - ((0 * winheight(0) + 39) / 78) | ||||
| let s:l = 1 - ((0 * winheight(0) + 28) / 57) | ||||
| if s:l < 1 | let s:l = 1 | endif | ||||
| exe s:l | ||||
| normal! zt | ||||
| @@ -818,7 +1041,7 @@ setlocal nowinfixwidth | ||||
| setlocal wrap | ||||
| setlocal wrapmargin=0 | ||||
| silent! normal! zE | ||||
| let s:l = 1 - ((0 * winheight(0) + 39) / 78) | ||||
| let s:l = 1 - ((0 * winheight(0) + 28) / 57) | ||||
| if s:l < 1 | let s:l = 1 | endif | ||||
| exe s:l | ||||
| normal! zt | ||||
| @@ -922,7 +1145,7 @@ setlocal nowinfixwidth | ||||
| setlocal wrap | ||||
| setlocal wrapmargin=0 | ||||
| silent! normal! zE | ||||
| let s:l = 1 - ((0 * winheight(0) + 39) / 78) | ||||
| let s:l = 1 - ((0 * winheight(0) + 28) / 57) | ||||
| if s:l < 1 | let s:l = 1 | endif | ||||
| exe s:l | ||||
| normal! zt | ||||
| @@ -1039,12 +1262,12 @@ setlocal nowinfixwidth | ||||
| setlocal wrap | ||||
| setlocal wrapmargin=0 | ||||
| silent! normal! zE | ||||
| let s:l = 9 - ((8 * winheight(0) + 39) / 78) | ||||
| let s:l = 9 - ((6 * winheight(0) + 28) / 57) | ||||
| if s:l < 1 | let s:l = 1 | endif | ||||
| exe s:l | ||||
| normal! zt | ||||
| 9 | ||||
| normal! 010l | ||||
| normal! 0 | ||||
| wincmd w | ||||
| argglobal | ||||
| edit test/com/jdbernard/pit/FileIssueTest.groovy | ||||
| @@ -1143,7 +1366,7 @@ setlocal nowinfixwidth | ||||
| setlocal wrap | ||||
| setlocal wrapmargin=0 | ||||
| silent! normal! zE | ||||
| let s:l = 1 - ((0 * winheight(0) + 39) / 78) | ||||
| let s:l = 1 - ((0 * winheight(0) + 28) / 57) | ||||
| if s:l < 1 | let s:l = 1 | endif | ||||
| exe s:l | ||||
| normal! zt | ||||
| @@ -1260,7 +1483,7 @@ setlocal nowinfixwidth | ||||
| setlocal wrap | ||||
| setlocal wrapmargin=0 | ||||
| silent! normal! zE | ||||
| let s:l = 1 - ((0 * winheight(0) + 39) / 78) | ||||
| let s:l = 1 - ((0 * winheight(0) + 28) / 57) | ||||
| if s:l < 1 | let s:l = 1 | endif | ||||
| exe s:l | ||||
| normal! zt | ||||
| @@ -1364,7 +1587,7 @@ setlocal nowinfixwidth | ||||
| setlocal wrap | ||||
| setlocal wrapmargin=0 | ||||
| silent! normal! zE | ||||
| let s:l = 1 - ((0 * winheight(0) + 39) / 78) | ||||
| let s:l = 1 - ((0 * winheight(0) + 28) / 57) | ||||
| if s:l < 1 | let s:l = 1 | endif | ||||
| exe s:l | ||||
| normal! zt | ||||
| @@ -1373,7 +1596,7 @@ normal! 0 | ||||
| wincmd w | ||||
| exe 'vert 1resize ' . ((&columns * 91 + 91) / 182) | ||||
| exe 'vert 2resize ' . ((&columns * 90 + 91) / 182) | ||||
| tabnext 1 | ||||
| tabnext 3 | ||||
| if exists('s:wipebuf') | ||||
|   silent exe 'bwipe ' . s:wipebuf | ||||
| endif | ||||
|   | ||||
| @@ -3,8 +3,7 @@ package com.jdbernard.pit | ||||
| public enum Category { | ||||
|     BUG, | ||||
|     FEATURE, | ||||
|     TASK, | ||||
|     CLOSED | ||||
|     TASK | ||||
|  | ||||
|     public static Category toCategory(String s) { | ||||
|         for(c in Category.values()) | ||||
|   | ||||
| @@ -5,19 +5,21 @@ import java.lang.IllegalArgumentException as IAE | ||||
| public class FileIssue extends Issue { | ||||
|  | ||||
|     protected File source | ||||
|     public static final String fileExp = /(\d+)([bft])([ajnsv])(\d).*/ | ||||
|  | ||||
|     public FileIssue(File file) { | ||||
|  | ||||
|         super('REPLACE_ME') | ||||
|  | ||||
|         def matcher = file.name =~ /(\d{4})([bftc])(\d).*/ | ||||
|         def matcher = file.name =~ fileExp | ||||
|         if (!matcher) | ||||
|             throw new IllegalArgumentException("${file} " + | ||||
|                 "is not a valid Issue file.") | ||||
|  | ||||
|         super.@id = matcher[0][1] | ||||
|         super.@category = Category.toCategory(matcher[0][2]) | ||||
|         super.@priority = matcher[0][3].toInteger() | ||||
|         super.@status = Status.toStatus(matcher[0][3]) | ||||
|         super.@priority = matcher[0][4].toInteger() | ||||
|  | ||||
|         this.source = file | ||||
|  | ||||
| @@ -29,12 +31,19 @@ public class FileIssue extends Issue { | ||||
|         source.renameTo(new File(source.canonicalFile.parentFile, getFilename())) | ||||
|     } | ||||
|  | ||||
|     public void setStatus(Status s) { | ||||
|         super.setStatus(s) | ||||
|         source.renameTo(new File(source.canonicalFile.parentFile, getFilename())) | ||||
|     } | ||||
|  | ||||
|     public void setPriority(int p) { | ||||
|         super.setPriority(p) | ||||
|         source.renameTo(new File(source.canonicalFile.parentFile, getFilename())) | ||||
|     } | ||||
|  | ||||
|     public String getFilename() { return makeFilename(id, category, priority) } | ||||
|     public String getFilename() { | ||||
|         return makeFilename(id, category, status, priority) | ||||
|     } | ||||
|  | ||||
|     public void setText(String text) { | ||||
|         super.setText(text) | ||||
| @@ -44,11 +53,11 @@ public class FileIssue extends Issue { | ||||
|     public boolean delete() { return source.delete() } | ||||
|  | ||||
|     public static boolean isValidFilename(String name) { | ||||
|         return name ==~ /(\d+)([bcft])(\d).*/ | ||||
|         return name ==~ fileExp | ||||
|     } | ||||
|  | ||||
|     public static String makeFilename(String id, Category category, | ||||
|     int priority) { | ||||
|     Status status, int priority) { | ||||
|  | ||||
|         // bounds check priority | ||||
|         priority = Math.min(9, Math.max(0, priority)) | ||||
| @@ -56,10 +65,12 @@ public class FileIssue extends Issue { | ||||
|         //check for valid values of cateogry and id | ||||
|         if (category == null) | ||||
|             throw new IAE("Category must be non-null.") | ||||
|         if (status == null) | ||||
|             throw new IAE("Status must be non-null.") | ||||
|         if (!(id ==~ /\d+/)) | ||||
|             throw new IAE( "'${id}' is not a legal value for id.") | ||||
|          | ||||
|         return id + category.symbol + priority + ".rst"; | ||||
|         return id + category.symbol + status.symbol + priority + ".rst"; | ||||
|     } | ||||
|  | ||||
| } | ||||
|   | ||||
| @@ -17,7 +17,7 @@ class FileProject extends Project { | ||||
|  | ||||
|             // add sub projects | ||||
|             if (child.isDirectory())  { | ||||
|                 if ( child.name ==~ /\d{4}/)  return // just an issue folder | ||||
|                 if ( child.name ==~ /\d+/)  return // just an issue folder | ||||
|  | ||||
|                 // otherwise build and add to list | ||||
|                 projects[(child.name)] =  new FileProject(child) | ||||
| @@ -41,6 +41,7 @@ class FileProject extends Project { | ||||
|     public FileIssue createNewIssue(Map options) { | ||||
|         if (!options) options = [:] | ||||
|         if (!options.category) options.category = Category.TASK | ||||
|         if (!options.status)   options.status   = Status.NEW | ||||
|         if (!options.priority) options.priority = 5 | ||||
|         if (!options.text) options.text = "Default issue title.\n" + | ||||
|                                           "====================\n" | ||||
| @@ -52,7 +53,7 @@ class FileProject extends Project { | ||||
|         } | ||||
|  | ||||
|         def issueFile = new File(source, FileIssue.makeFilename(id, | ||||
|             options.category, options.priority)) | ||||
|             options.category, options.status, options.priority)) | ||||
|  | ||||
|         issueFile.createNewFile() | ||||
|         issueFile.write(options.text) | ||||
|   | ||||
| @@ -3,6 +3,7 @@ package com.jdbernard.pit | ||||
| class Filter { | ||||
|  | ||||
|     List<Category> categories = null | ||||
|     List<Status> status = null | ||||
|     List<String> projects = null | ||||
|     List<String> ids = null | ||||
|     int priority = 9 | ||||
| @@ -16,6 +17,7 @@ class Filter { | ||||
|     public boolean accept(Issue i) { | ||||
|         return (i.priority <= priority && | ||||
|                 (!categories || categories.contains(i.category)) && | ||||
|                 (!status || status.contains(i.status)) && | ||||
|                 (!ids || ids.contains(i.id))) | ||||
|     } | ||||
|  | ||||
|   | ||||
| @@ -6,12 +6,15 @@ public abstract class Issue { | ||||
|  | ||||
|     protected String id | ||||
|     protected Category category | ||||
|     protected Status status | ||||
|     protected int priority | ||||
|     protected String text | ||||
|  | ||||
|     Issue(String id, Category c = Category.TASK, int p = 9) { | ||||
|     Issue(String id, Category c = Category.TASK, Status s = Status.NEW, | ||||
|     int p = 9) { | ||||
|         this.id = id | ||||
|         this.category = c | ||||
|         this.status = s | ||||
|         this.priority = p | ||||
|     } | ||||
|  | ||||
| @@ -26,6 +29,15 @@ public abstract class Issue { | ||||
|         this.category = c | ||||
|     } | ||||
|  | ||||
|     public Status getStatus() { return status } | ||||
|  | ||||
|     public void setStatus(Status s) { | ||||
|         if (s == null) | ||||
|             throw new IAE("Status cannot be null.") | ||||
|  | ||||
|         this.status = s | ||||
|     } | ||||
|  | ||||
|     public int getPriority() { return priority } | ||||
|  | ||||
|     public void setPriority(int p) { priority = Math.min(9, Math.max(0, p)) } | ||||
| @@ -37,7 +49,7 @@ public abstract class Issue { | ||||
|     public void setText(String t) { text = t } | ||||
|  | ||||
|     @Override | ||||
|     public String toString() { return "${id}(${priority}): ${category} ${title}" } | ||||
|     public String toString() { return "${id}(${priority}-${status}): ${category} ${title}" } | ||||
|  | ||||
|     public abstract boolean delete() | ||||
| } | ||||
|   | ||||
							
								
								
									
										41
									
								
								libpit/src/com/jdbernard/pit/Status.groovy
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										41
									
								
								libpit/src/com/jdbernard/pit/Status.groovy
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,41 @@ | ||||
| package com.jdbernard.pit | ||||
|  | ||||
| public enum Status { | ||||
|     REASSIGNED('a'), | ||||
|     REJECTED('j'), | ||||
|     NEW('n'), | ||||
|     RESOLVED('s'), | ||||
|     VALIDATION_REQUIRED('v') | ||||
|  | ||||
|     String symbol | ||||
|  | ||||
|     protected Status(String s) { symbol = s } | ||||
|  | ||||
|     public static Status toStatus(String str) { | ||||
|         Status retVal = null | ||||
|         for(status in Status.values())  { | ||||
|             if (status.symbol.equalsIgnoreCase(str) || | ||||
|                 status.name().startsWith(str.toUpperCase())) { | ||||
|  | ||||
|                 if (retVal != null) | ||||
|                     throw new IllegalArgumentException("Request string is" + | ||||
|                         " ambigous, '${str}' could represent ${retVal} or " + | ||||
|                         "${status}, possibly others.") | ||||
|  | ||||
|                 retVal = status | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         if (retVal == null) | ||||
|             throw new IllegalArgumentException("No status matches '${str}'") | ||||
|  | ||||
|         return retVal | ||||
|     } | ||||
|  | ||||
|     public String toString() { | ||||
|         def words = name().split("_") | ||||
|         String result = "" | ||||
|         words.each { result += "${it[0]}${it[1..-1].toLowerCase()} " } | ||||
|         return result[0..-2] | ||||
|     } | ||||
| } | ||||
							
								
								
									
										36
									
								
								libpit/src/com/jdbernard/pit/util/Convert1_2.groovy
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										36
									
								
								libpit/src/com/jdbernard/pit/util/Convert1_2.groovy
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,36 @@ | ||||
| package com.jdbernard.pit.util | ||||
|  | ||||
| import com.jdbernard.pit.* | ||||
|  | ||||
| if (args.size() != 1) { | ||||
|     println "Usage: Convert1_2 [dir]" | ||||
|     System.exit(1) | ||||
| } | ||||
|  | ||||
| File rootDir = new File(args[0]) | ||||
| Scanner scan = new Scanner(System.in) | ||||
|  | ||||
| rootDir.eachFileRecurse { file -> | ||||
|     def m = file.name =~ /(\d+)([bcft])(\d).*/ | ||||
|     if (m && file.isFile()) { | ||||
|         println m[0][0] | ||||
|         def parentFile = file.canonicalFile.parentFile | ||||
|         def c | ||||
|         def s | ||||
|         switch(m[0][2]) { | ||||
|             case "c": | ||||
|                 println file.readLines()[0] | ||||
|                 print "Issue was closed, was category does it belong in?" | ||||
|                 c = Category.toCategory(scan.nextLine()) | ||||
|                 s = Status.RESOLVED | ||||
|                 break | ||||
|             default: | ||||
|                 c = Category.toCategory(m[0][2]) | ||||
|                 s = Status.NEW | ||||
|                 break | ||||
|         } | ||||
|         println "${m[0][2]}: ${c}" | ||||
|         file.renameTo(new File(parentFile, | ||||
|             FileIssue.makeFilename(m[0][1], c, s, m[0][3].toInteger()))) | ||||
|     } | ||||
| } | ||||
| @@ -12,24 +12,20 @@ class CategoryTest { | ||||
|         assertEquals toCategory("BUG"), Category.BUG | ||||
|         assertEquals toCategory("FEATURE"), Category.FEATURE | ||||
|         assertEquals toCategory("TASK"), Category.TASK | ||||
|         assertEquals toCategory("CLOSED"), Category.CLOSED | ||||
|  | ||||
|         assertEquals toCategory("bug"), Category.BUG | ||||
|         assertEquals toCategory("feature"), Category.FEATURE | ||||
|         assertEquals toCategory("task"), Category.TASK | ||||
|         assertEquals toCategory("closed"), Category.CLOSED | ||||
|  | ||||
|         assertEquals toCategory("b"), Category.BUG | ||||
|         assertEquals toCategory("f"), Category.FEATURE | ||||
|         assertEquals toCategory("t"), Category.TASK | ||||
|         assertEquals toCategory("c"), Category.CLOSED | ||||
|  | ||||
|     } | ||||
|  | ||||
|     @Test void testGetSymbol() { | ||||
|  | ||||
|         assertEquals Category.BUG.symbol,       "b" | ||||
|         assertEquals Category.CLOSED.symbol,    "c" | ||||
|         assertEquals Category.FEATURE.symbol,   "f" | ||||
|         assertEquals Category.TASK.symbol,      "t" | ||||
|     } | ||||
|   | ||||
| @@ -17,14 +17,14 @@ class FileIssueTest { | ||||
|         testDir = new File('testdir') | ||||
|         testDir.mkdirs() | ||||
|  | ||||
|         issueFile = new File(testDir, '0001f1.rst') | ||||
|         issueFile = new File(testDir, '0001fn1.rst') | ||||
|         issueFile.write( | ||||
|             "Add the killer feature to the killer app.\n" + | ||||
|             "=========================================\n\n" + | ||||
|             "Make our killer app shine!.") | ||||
|         issues << new FileIssue(issueFile) | ||||
|  | ||||
|         issueFile = new File(testDir, '0002t5.rst') | ||||
|         issueFile = new File(testDir, '0002ts5.rst') | ||||
|         issueFile.write( | ||||
|             "Obtain donuts.\n" + | ||||
|             "==============\n\n" + | ||||
| @@ -42,16 +42,30 @@ class FileIssueTest { | ||||
|         assertEquals issues[0].category, Category.FEATURE | ||||
|         assertEquals issues[1].category, Category.TASK | ||||
|  | ||||
|         issues[0].category = Category.CLOSED | ||||
|         issues[0].category = Category.TASK | ||||
|         issues[1].category = Category.BUG | ||||
|  | ||||
|         assertEquals issues[0].category, Category.CLOSED | ||||
|         assertEquals issues[0].category, Category.TASK | ||||
|         assertEquals issues[1].category, Category.BUG | ||||
|  | ||||
|         assertTrue new File(testDir, '0001c1.rst').exists() | ||||
|         assertTrue new File(testDir, '0002b5.rst').exists() | ||||
|         assertFalse new File(testDir, '0001f1.rst').exists() | ||||
|         assertFalse new File(testDir, '0002t5.rst').exists() | ||||
|         assertTrue new File(testDir, '0001tn1.rst').exists() | ||||
|         assertTrue new File(testDir, '0002bs5.rst').exists() | ||||
|         assertFalse new File(testDir, '0001fn1.rst').exists() | ||||
|         assertFalse new File(testDir, '0002ts5.rst').exists() | ||||
|     } | ||||
|  | ||||
|     @Test void testSetStatus() { | ||||
|  | ||||
|         assertEquals issues[0].status, Status.NEW | ||||
|         assertEquals issues[1].status, Status.RESOLVED | ||||
|  | ||||
|         issues[0].status = Status.RESOLVED | ||||
|         issues[1].status = Status.REJECTED | ||||
|  | ||||
|         assertTrue new File(testDir, '0001fs1.rst').exists() | ||||
|         assertTrue new File(testDir, '0002tj5.rst').exists() | ||||
|         assertFalse new File(testDir, '0001fn1.rst').exists() | ||||
|         assertFalse new File(testDir, '0002ts5.rst').exists() | ||||
|     } | ||||
|  | ||||
|     @Test void testSetPriority() { | ||||
| @@ -65,18 +79,19 @@ class FileIssueTest { | ||||
|         assertEquals issues[0].priority, 2 | ||||
|         assertEquals issues[1].priority, 9 | ||||
|          | ||||
|         assertTrue new File(testDir, '0001f2.rst').exists() | ||||
|         assertTrue new File(testDir, '0002t9.rst').exists() | ||||
|         assertFalse new File(testDir, '0001f1.rst').exists() | ||||
|         assertFalse new File(testDir, '0002t5.rst').exists() | ||||
|         assertTrue new File(testDir, '0001fn2.rst').exists() | ||||
|         assertTrue new File(testDir, '0002ts9.rst').exists() | ||||
|         assertFalse new File(testDir, '0001fn1.rst').exists() | ||||
|         assertFalse new File(testDir, '0002ts5.rst').exists() | ||||
|     } | ||||
|  | ||||
|     @Test void testConstruction() { | ||||
|         File issueFile = new File(testDir, '0001f1.rst') | ||||
|         File issueFile = new File(testDir, '0001fn1.rst') | ||||
|         Issue issue = new FileIssue(issueFile) | ||||
|  | ||||
|         assertEquals issue.id        , "0001" | ||||
|         assertEquals issue.category  , Category.FEATURE | ||||
|         assertEquals issue.status    , Status.NEW | ||||
|         assertEquals issue.priority  , 1 | ||||
|         assertEquals issue.title     , "Add the killer feature to the killer app." | ||||
|         assertEquals issue.text      , "Add the killer feature to the killer app.\n" + | ||||
| @@ -86,21 +101,32 @@ class FileIssueTest { | ||||
|     } | ||||
|  | ||||
|     @Test void testMakeFilename() { | ||||
|         assertEquals FileIssue.makeFilename('0001', Category.BUG, 5)    , '0001b5.rst' | ||||
|         assertEquals FileIssue.makeFilename('0010', Category.FEATURE, 1), '0010f1.rst' | ||||
|         assertEquals FileIssue.makeFilename('0002', Category.CLOSED, 3) , '0002c3.rst' | ||||
|         assertEquals FileIssue.makeFilename('0001', Category.BUG, -2)   , '0001b0.rst' | ||||
|         assertEquals FileIssue.makeFilename('0001', Category.TASK, 10)  , '0001t9.rst' | ||||
|         assertEquals FileIssue.makeFilename('00101', Category.BUG, 5)   , '00101b5.rst' | ||||
|         assertEquals FileIssue.makeFilename('0001', Category.BUG, | ||||
|             Status.NEW, 5),         '0001bn5.rst' | ||||
|         assertEquals FileIssue.makeFilename('0010', Category.FEATURE, | ||||
|             Status.REASSIGNED, 1),  '0010fa1.rst' | ||||
|         assertEquals FileIssue.makeFilename('0002', Category.FEATURE, | ||||
|             Status.REJECTED, 3),    '0002fj3.rst' | ||||
|         assertEquals FileIssue.makeFilename('0001', Category.BUG, | ||||
|             Status.RESOLVED, -2),   '0001bs0.rst' | ||||
|         assertEquals FileIssue.makeFilename('0001', Category.TASK, | ||||
|             Status.VALIDATION_REQUIRED, 10)  , '0001tv9.rst' | ||||
|         assertEquals FileIssue.makeFilename('00101', Category.BUG, | ||||
|             Status.NEW, 5),         '00101bn5.rst' | ||||
|  | ||||
|         try { | ||||
|             FileIssue.makeFilename('badid', Category.BUG, 5) | ||||
|             FileIssue.makeFilename('badid', Category.BUG, Status.NEW, 5) | ||||
|             assertTrue 'Issue.makeFilename() succeeded with bad id input.', false | ||||
|         } catch (IllegalArgumentException iae) {} | ||||
|  | ||||
|         try { | ||||
|             FileIssue.makeFilename('0002', null, 5) | ||||
|             FileIssue.makeFilename('0002', null, Status.NEW, 5) | ||||
|             assertTrue 'Issue.makeFilename() succeeded given no Category.', false | ||||
|         } catch (IllegalArgumentException iae) {} | ||||
|  | ||||
|         try { | ||||
|             FileIssue.makeFilename('0002', Category.BUG, null, 5) | ||||
|             assertTrue 'Issue.makeFilename() succeeded given no Status.', false | ||||
|         } catch (IllegalArgumentException iae) {} | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -33,19 +33,19 @@ class FileProjectTest { | ||||
|  | ||||
|         */ | ||||
|  | ||||
|         def issueFile = new File(testDir, '0001t5.rst') | ||||
|         def issueFile = new File(testDir, '0001tn5.rst') | ||||
|         issueFile.createNewFile() | ||||
|         issueFile.write('Test Issue 1\n' + | ||||
|                         '============\n\n' + | ||||
|                         'This is the first test issue.') | ||||
|  | ||||
|         issueFile = new File(testDir, '0002b5.rst') | ||||
|         issueFile = new File(testDir, '0002ba5.rst') | ||||
|         issueFile.createNewFile() | ||||
|         issueFile.write('Test Bug\n' + | ||||
|                         '========\n\n' + | ||||
|                         'Yeah, it is a test bug.') | ||||
|  | ||||
|         issueFile = new File(testDir, '0003c2.rst') | ||||
|         issueFile = new File(testDir, '0003fs2.rst') | ||||
|         issueFile.createNewFile() | ||||
|         issueFile.write('Important Feature Request\n' + | ||||
|                         '=========================\n\n' + | ||||
| @@ -54,13 +54,13 @@ class FileProjectTest { | ||||
|         def subDir = new File(testDir, 'subproj1') | ||||
|         subDir.mkdirs() | ||||
|  | ||||
|         issueFile = new File(subDir, '0001f3.rst') | ||||
|         issueFile = new File(subDir, '0001fv3.rst') | ||||
|         issueFile.createNewFile() | ||||
|         issueFile.write('First feature in subproject\n' + | ||||
|                         '===========================\n\n' + | ||||
|                         'Please make the grubblers grobble.') | ||||
|  | ||||
|         issueFile = new File(subDir, '0002b4.rst') | ||||
|         issueFile = new File(subDir, '0002bj4.rst') | ||||
|         issueFile.createNewFile() | ||||
|         issueFile.write('Zippners are not zippning.\n' + | ||||
|                         '==========================\n\n' + | ||||
| @@ -129,11 +129,14 @@ class FileProjectTest { | ||||
|  | ||||
|         // test correct increment of id, application of values | ||||
|         def newIssue = rootProj.createNewIssue(category: Category.BUG, | ||||
|             priority: 4, text: 'A newly made bug report.\n'+ | ||||
|                                '========================\n\n' + | ||||
|                                'Testing the Project.createNewIssue() method.') | ||||
|             status: Status.REASSIGNED, priority: 4, | ||||
|             text: 'A newly made bug report.\n'+ | ||||
|                   '========================\n\n' + | ||||
|                   'Testing the Project.createNewIssue() method.') | ||||
|  | ||||
|         assertEquals newIssue.id,       '0004' | ||||
|         assertEquals newIssue.category, Category.BUG | ||||
|         assertEquals newIssue.status,   Status.REASSIGNED | ||||
|         assertEquals newIssue.priority, 4 | ||||
|         assertEquals newIssue.text, 'A newly made bug report.\n'+ | ||||
|                                     '========================\n\n' + | ||||
| @@ -145,6 +148,8 @@ class FileProjectTest { | ||||
|  | ||||
|         assertEquals newIssue.id,       '0000' | ||||
|         assertEquals newIssue.priority, 5 | ||||
|         assertEquals newIssue.category, Category.TASK | ||||
|         assertEquals newIssue.status,   Status.NEW | ||||
|         assertEquals newIssue.text,     'Default issue title.\n' + | ||||
|                                         '====================\n' | ||||
|  | ||||
|   | ||||
| @@ -15,16 +15,16 @@ class FilterTest { | ||||
|  | ||||
|         proj = new MockProject('proj1') | ||||
|  | ||||
|         def issue = new MockIssue( '0000', Category.TASK, 5) | ||||
|         def issue = new MockIssue( '0000', Category.TASK, Status.NEW, 5) | ||||
|         proj.issues['0000'] = issue | ||||
|  | ||||
|         issue = new MockIssue('0001', Category.BUG, 3) | ||||
|         issue = new MockIssue('0001', Category.BUG, Status.REJECTED, 3) | ||||
|         proj.issues['0001'] = issue | ||||
|  | ||||
|         issue = new MockIssue('0002', Category.CLOSED, 9) | ||||
|         issue = new MockIssue('0002', Category.BUG, Status.RESOLVED, 9) | ||||
|         proj.issues['0002'] = issue | ||||
|  | ||||
|         issue = new MockIssue('0003', Category.FEATURE, 0) | ||||
|         issue = new MockIssue('0003', Category.FEATURE, Status.REASSIGNED, 0) | ||||
|         proj.issues['0003'] = issue | ||||
|  | ||||
|         def subProj = new MockProject('subproj1') | ||||
| @@ -69,25 +69,47 @@ class FilterTest { | ||||
|  | ||||
|     @Test void testCategoryFilter() { | ||||
|         Filter f = new Filter(categories:  | ||||
|             [Category.BUG, Category.FEATURE, Category.TASK]) | ||||
|             [Category.BUG, Category.FEATURE]) | ||||
|  | ||||
|         assertFalse f.accept(proj.issues['0000']) | ||||
|         assertTrue  f.accept(proj.issues['0001']) | ||||
|         assertTrue  f.accept(proj.issues['0002']) | ||||
|         assertTrue  f.accept(proj.issues['0003']) | ||||
|  | ||||
|         f.categories = [ Category.TASK ] | ||||
|         assertTrue  f.accept(proj.issues['0000']) | ||||
|         assertFalse f.accept(proj.issues['0001']) | ||||
|         assertFalse f.accept(proj.issues['0002']) | ||||
|         assertFalse f.accept(proj.issues['0003']) | ||||
|  | ||||
|         f.categories = [ Category.BUG, Category.TASK ] | ||||
|         assertTrue  f.accept(proj.issues['0000']) | ||||
|         assertTrue  f.accept(proj.issues['0001']) | ||||
|         assertTrue  f.accept(proj.issues['0002']) | ||||
|         assertFalse f.accept(proj.issues['0003']) | ||||
|  | ||||
|     } | ||||
|  | ||||
|     @Test void testStatusFilter() { | ||||
|         Filter f = new Filter(status: | ||||
|             [Status.NEW, Status.REASSIGNED, Status.REJECTED]) | ||||
|  | ||||
|         assertTrue  f.accept(proj.issues['0000']) | ||||
|         assertTrue  f.accept(proj.issues['0001']) | ||||
|         assertFalse f.accept(proj.issues['0002']) | ||||
|         assertTrue  f.accept(proj.issues['0003']) | ||||
|  | ||||
|         f.categories = [ Category.CLOSED ] | ||||
|         f.status = [ Status.RESOLVED ] | ||||
|         assertFalse f.accept(proj.issues['0000']) | ||||
|         assertFalse f.accept(proj.issues['0001']) | ||||
|         assertTrue  f.accept(proj.issues['0002']) | ||||
|         assertFalse f.accept(proj.issues['0003']) | ||||
|  | ||||
|         f.categories = [ Category.BUG, Category.FEATURE ] | ||||
|         assertFalse f.accept(proj.issues['0000']) | ||||
|         assertTrue  f.accept(proj.issues['0001']) | ||||
|         assertFalse f.accept(proj.issues['0002']) | ||||
|         assertTrue  f.accept(proj.issues['0003']) | ||||
|  | ||||
|         f.status = [ Status.NEW, Status.RESOLVED ] | ||||
|         assertTrue  f.accept(proj.issues['0000']) | ||||
|         assertFalse f.accept(proj.issues['0001']) | ||||
|         assertTrue  f.accept(proj.issues['0002']) | ||||
|         assertFalse f.accept(proj.issues['0003']) | ||||
|     } | ||||
|  | ||||
|     @Test void testProjectFilter() { | ||||
|   | ||||
| @@ -1,6 +1,8 @@ | ||||
| package com.jdbernard.pit | ||||
|  | ||||
| public class MockIssue extends Issue { | ||||
|     public MockIssue(String id, Category c, int p) { super (id, c, p) } | ||||
|     public MockIssue(String id, Category c, Status s, int p) { | ||||
|         super (id, c, s, p) | ||||
|     } | ||||
|     public boolean delete() { return true } | ||||
| } | ||||
|   | ||||
							
								
								
									
										54
									
								
								libpit/test/com/jdbernard/pit/StatusTest.groovy
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										54
									
								
								libpit/test/com/jdbernard/pit/StatusTest.groovy
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,54 @@ | ||||
| package com.jdbernard.pit | ||||
|  | ||||
| import org.junit.Test | ||||
| import static org.junit.Assert.assertEquals | ||||
|  | ||||
| import static com.jdbernard.pit.Status.toStatus | ||||
|  | ||||
| public class StatusTest { | ||||
|  | ||||
|     @Test void testToStatus() { | ||||
|  | ||||
|         assertEquals Status.REASSIGNED, toStatus('REASSIGNED') | ||||
|         assertEquals Status.REJECTED,   toStatus('REJECTED') | ||||
|         assertEquals Status.NEW,        toStatus('NEW') | ||||
|         assertEquals Status.RESOLVED  , toStatus('RESOLVED') | ||||
|         assertEquals Status.VALIDATION_REQUIRED, | ||||
|             toStatus('VALIDATION_REQUIRED') | ||||
|  | ||||
|         assertEquals Status.REASSIGNED, toStatus('REA') | ||||
|         assertEquals Status.REJECTED,   toStatus('REJ') | ||||
|         assertEquals Status.NEW,        toStatus('NEW') | ||||
|         assertEquals Status.RESOLVED  , toStatus('RES') | ||||
|         assertEquals Status.VALIDATION_REQUIRED, | ||||
|             toStatus('VAL') | ||||
|  | ||||
|         assertEquals Status.REASSIGNED, toStatus('reassigned') | ||||
|         assertEquals Status.REJECTED,   toStatus('rejected') | ||||
|         assertEquals Status.NEW,        toStatus('new') | ||||
|         assertEquals Status.RESOLVED  , toStatus('resolved') | ||||
|         assertEquals Status.VALIDATION_REQUIRED, | ||||
|             toStatus('validation_required') | ||||
|  | ||||
|         assertEquals Status.REASSIGNED, toStatus('rea') | ||||
|         assertEquals Status.REJECTED,   toStatus('rej') | ||||
|         assertEquals Status.NEW,        toStatus('new') | ||||
|         assertEquals Status.RESOLVED  , toStatus('res') | ||||
|         assertEquals Status.VALIDATION_REQUIRED, | ||||
|             toStatus('val') | ||||
|  | ||||
|         assertEquals Status.REASSIGNED, toStatus('A') | ||||
|         assertEquals Status.REJECTED,   toStatus('J') | ||||
|         assertEquals Status.NEW,        toStatus('N') | ||||
|         assertEquals Status.RESOLVED  , toStatus('S') | ||||
|         assertEquals Status.VALIDATION_REQUIRED, toStatus('V') | ||||
|  | ||||
|         assertEquals Status.REASSIGNED, toStatus('a') | ||||
|         assertEquals Status.REJECTED,   toStatus('j') | ||||
|         assertEquals Status.NEW,        toStatus('n') | ||||
|         assertEquals Status.RESOLVED  , toStatus('s') | ||||
|         assertEquals Status.VALIDATION_REQUIRED, toStatus('v') | ||||
|  | ||||
|     } | ||||
|  | ||||
| } | ||||
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										
											BIN
										
									
								
								pit-cli/lib/pit-2.0.1.jar
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								pit-cli/lib/pit-2.0.1.jar
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| @@ -1,9 +1,9 @@ | ||||
| #Thu Feb 25 17:41:36 CST 2010 | ||||
| #Fri Feb 26 11:46:27 CST 2010 | ||||
| build.dir=build | ||||
| src.dir=src | ||||
| build.jar=pit-cli-${application.version}.${build.number}.jar | ||||
| build.number=1 | ||||
| expected.application.version=1.1.8 | ||||
| build.number=2 | ||||
| expected.application.version=2.0.1 | ||||
| lib.dir=lib | ||||
| release.dir=release | ||||
| release.jar=pit-cli-${application.version}.jar | ||||
|   | ||||
										
											Binary file not shown.
										
									
								
							| @@ -11,8 +11,11 @@ cli.l(longOpt: 'list', 'List issues. Unless otherwise specified it lists all ' | ||||
| cli.i(argName: 'id', longOpt: 'id', args: 1, | ||||
|     'Filter issues by id. Accepts a comma-delimited list.') | ||||
| cli.c(argName: 'category', longOpt: 'category', args: 1, | ||||
|     'Filter issues by category (bug, feature, task, closed). Accepts a ' | ||||
|     'Filter issues by category (bug, feature, task). Accepts a ' | ||||
|     + 'comma-delimited list.') | ||||
| cli.t(argName: 'status', longOpt: 'status', args: 1, | ||||
|     'Filter issues by status (new, reassigned, rejected, resolved, ' + | ||||
|     'validation_required)') | ||||
| cli.p(argName: 'priority', longOpt: 'priority', args: 1, | ||||
|     'Filter issues by priority. This acts as a threshhold, listing all issues ' | ||||
|     + 'greater than or equal to the given priority.') | ||||
| @@ -26,6 +29,8 @@ cli.P(argName: 'new-priority', longOpt: 'set-priority', args: 1, | ||||
|     required: false, 'Modify the priority of the selected issues.') | ||||
| cli.C(argName: 'new-category', longOpt: 'set-category', args: 1, | ||||
|     required: false, 'Modify the category of the selected issues.') | ||||
| cli.T(argName: 'new-status', longOpt: 'set-status', args: 1, | ||||
|     required: false, 'Modify the status of the selected issues.') | ||||
| cli.n(longOpt: 'new-issue', 'Create a new issue.') | ||||
|  | ||||
| def opts = cli.parse(args) | ||||
| @@ -39,6 +44,10 @@ def categories = ['bug','feature','task'] | ||||
| if (opts.c) categories = opts.c.split(/[,\s]/) | ||||
| categories = categories.collect { Category.toCategory(it) } | ||||
|  | ||||
| def statusList = ['new', 'validation_required'] | ||||
| if (opts.t) statusList = opts.t.split(/[,\s]/) | ||||
| statusList = statusList.collect { Status.toStatus(it) } | ||||
|  | ||||
| def EOL = System.getProperty('line.separator') | ||||
|  | ||||
| // build issue list | ||||
| @@ -46,6 +55,7 @@ issuedb = new FileProject(new File('.')) | ||||
|  | ||||
| // build filter from options | ||||
| def filter = new Filter('categories': categories, | ||||
|     'status': statusList, | ||||
|     'priority': (opts.p ? opts.p.toInteger() : 9), | ||||
|     'projects': (opts.r ? opts.r.toLowerCase().split(/[,\s]/).asType(List.class) : []), | ||||
|     'ids': (opts.i ? opts.i.split(/[,\s]/).asType(List.class) : []), | ||||
| @@ -88,7 +98,15 @@ else if (opts.C) { | ||||
|     try { cat = Category.toCategory(opts.C) } | ||||
|     catch (e) { println "Invalid category: ${opts.C}"; return 1 } | ||||
|  | ||||
|     walkProject(issuedb, filterb) { it.category = cat } | ||||
|     walkProject(issuedb, filter) { it.category = cat } | ||||
| } | ||||
| // change status fourth | ||||
| else if (opts.T) { | ||||
|     def status | ||||
|     try { status = Status.toStatus(opts.T) } | ||||
|     catch (e) { println "Invalid status: ${opts.T}"; return 1 } | ||||
|  | ||||
|     walkProject(issuedb, filter) { it.status = status } | ||||
| } | ||||
| // new entry last | ||||
| else if (opts.n) { | ||||
|   | ||||
							
								
								
									
										
											BIN
										
									
								
								pit-swing/CHANGE ME
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								pit-swing/CHANGE ME
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| @@ -1,4 +1,4 @@ | ||||
| #Sat Feb 13 08:41:16 CST 2010 | ||||
| app.version=1.1.8 | ||||
| app.version=2.0.1 | ||||
| app.griffon.version=0.2.1 | ||||
| app.name=pit-swing | ||||
|   | ||||
| @@ -8,7 +8,6 @@ class PITController { | ||||
|     def view | ||||
|  | ||||
|     void mvcGroupInit(Map args) { | ||||
|         model.rootProject = new FileProject(new File('.')) | ||||
|     } | ||||
|  | ||||
|     /* | ||||
|   | ||||
										
											Binary file not shown.
										
									
								
							| Before Width: | Height: | Size: 537 B | 
							
								
								
									
										
											BIN
										
									
								
								pit-swing/griffon-app/resources/new.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								pit-swing/griffon-app/resources/new.png
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| After Width: | Height: | Size: 146 B | 
							
								
								
									
										
											BIN
										
									
								
								pit-swing/griffon-app/resources/reassigned.png
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								pit-swing/griffon-app/resources/reassigned.png
									
									
									
									
									
										Executable file
									
								
							
										
											Binary file not shown.
										
									
								
							| After Width: | Height: | Size: 559 B | 
							
								
								
									
										
											BIN
										
									
								
								pit-swing/griffon-app/resources/rejected.png
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								pit-swing/griffon-app/resources/rejected.png
									
									
									
									
									
										Executable file
									
								
							
										
											Binary file not shown.
										
									
								
							| After Width: | Height: | Size: 322 B | 
							
								
								
									
										
											BIN
										
									
								
								pit-swing/griffon-app/resources/resolved.png
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								pit-swing/griffon-app/resources/resolved.png
									
									
									
									
									
										Executable file
									
								
							
										
											Binary file not shown.
										
									
								
							| After Width: | Height: | Size: 221 B | 
							
								
								
									
										
											BIN
										
									
								
								pit-swing/griffon-app/resources/validation_required.png
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								pit-swing/griffon-app/resources/validation_required.png
									
									
									
									
									
										Executable file
									
								
							
										
											Binary file not shown.
										
									
								
							| After Width: | Height: | Size: 185 B | 
| @@ -1,12 +1,14 @@ | ||||
| package com.jdbernard.pit.swing | ||||
|  | ||||
| import com.jdbernard.pit.Category | ||||
| import com.jdbernard.pit.Status | ||||
| import com.jdbernard.pit.Filter | ||||
| import com.jdbernard.pit.Issue | ||||
| import com.jdbernard.pit.Project | ||||
| import com.jdbernard.pit.FileProject | ||||
| import groovy.beans.Bindable | ||||
| import java.awt.GridBagConstraints as GBC | ||||
| import java.awt.Font | ||||
| import java.awt.Point | ||||
| import java.awt.event.MouseEvent | ||||
| import javax.swing.DefaultComboBoxModel | ||||
| @@ -33,8 +35,11 @@ projectListModels = [:] | ||||
| // map of category -> list icon | ||||
| categoryIcons = [:] | ||||
|  | ||||
| statusIcons = [:] | ||||
|  | ||||
| // filter for projects and issues | ||||
| filter = new Filter(categories: []) | ||||
| filter = new Filter(categories: [], | ||||
|     status: [Status.NEW, Status.VALIDATION_REQUIRED]) | ||||
|  | ||||
| popupProject = null | ||||
| selectedProject = model.rootProject | ||||
| @@ -47,6 +52,10 @@ Category.values().each { | ||||
|     filter.categories.add(it) | ||||
| } | ||||
|  | ||||
| Status.values().each { | ||||
|     statusIcons[(it)] = imageIcon("/${it.name().toLowerCase()}.png") | ||||
| } | ||||
|  | ||||
| /* *************** | ||||
|  *  event methods | ||||
|  * ***************/ | ||||
| @@ -111,23 +120,32 @@ newIssueDialog = dialog(title: 'New Task...', modal: true, pack: true,//size: [3 | ||||
|             fill: GBC.HORIZONTAL), | ||||
|         model: new DefaultComboBoxModel(Category.values())) | ||||
|  | ||||
|     label('Priority (0-9, 0 is highest priority):', | ||||
|     label('Status:', | ||||
|         constraints: gbc(gridx: 0, gridy: 3, insets: [5, 5, 0, 0], | ||||
|             fill: GBC.HORIZONTAL)) | ||||
|     statusComboBox = comboBox( | ||||
|         constraints: gbc(gridx: 1, gridy: 3, insets: [5, 5, 0, 5], | ||||
|             fill: GBC.HORIZONTAL), | ||||
|         model: new DefaultComboBoxModel(Status.values())) | ||||
|  | ||||
|     label('Priority (0-9, 0 is highest priority):', | ||||
|         constraints: gbc(gridx: 0, gridy: 4, insets: [5, 5, 0, 0], | ||||
|             fill: GBC.HORIZONTAL)) | ||||
|     prioritySpinner = spinner( | ||||
|         constraints: gbc( gridx: 1, gridy: 3, insets: [5, 5, 0, 5], | ||||
|         constraints: gbc( gridx: 1, gridy: 4, insets: [5, 5, 0, 5], | ||||
|             fill: GBC.HORIZONTAL), | ||||
|         model: spinnerNumberModel(maximum: 9, minimum: 0)) | ||||
|  | ||||
|     button('Cancel', actionPerformed: { newIssueDialog.visible = false }, | ||||
|         constraints: gbc(gridx: 0, gridy: 4, insets: [5, 5, 5, 5], | ||||
|         constraints: gbc(gridx: 0, gridy: 5, insets: [5, 5, 5, 5], | ||||
|             anchor: GBC.EAST)) | ||||
|     button('Create Issue', | ||||
|         constraints: gbc(gridx: 1, gridy: 4, insets: [5, 5, 5, 5], | ||||
|         constraints: gbc(gridx: 1, gridy: 5, insets: [5, 5, 5, 5], | ||||
|             anchor: GBC.WEST), | ||||
|         actionPerformed: { | ||||
|             def issue = selectedProject.createNewIssue( | ||||
|                 category: categoryComboBox.selectedItem, | ||||
|                 status: statusComboBox.selectedItem, | ||||
|                 priority: prioritySpinner.value, | ||||
|                 text: titleTextField.text) | ||||
|             projectListModels[(selectedProject.name)] = null | ||||
| @@ -160,7 +178,13 @@ projectPopupMenu = popupMenu() { | ||||
|  | ||||
| issuePopupMenu = popupMenu() { | ||||
|     menuItem('New Issue...', | ||||
|         actionPerformed: { newIssueDialog.visible = true }) | ||||
|         actionPerformed: {  | ||||
|             titleTextField.text = "" | ||||
|             categoryComboBox.selectedIndex = 0 | ||||
|             statusComboBox.selectedIndex = 0 | ||||
|             prioritySpinner.setValue(5) | ||||
|             newIssueDialog.visible = true | ||||
|         }) | ||||
|  | ||||
|     menuItem('Delete Issue', | ||||
|         actionPerformed: { | ||||
| @@ -180,6 +204,20 @@ issuePopupMenu = popupMenu() { | ||||
|                     if (!popupIssue) return | ||||
|                     popupIssue.category = category | ||||
|                     issueList.invalidate() | ||||
|                     issueList.repaint() | ||||
|                 }) | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     menu('Change Status') { | ||||
|         Status.values().each { status -> | ||||
|             menuItem(status.toString(), | ||||
|                 icon: statusIcons[(status)], | ||||
|                 actionPerformed: { | ||||
|                     if (!popupIssue) return | ||||
|                     popupIssue.status = status | ||||
|                     issueList.invalidate() | ||||
|                     issueList.repaint() | ||||
|                 }) | ||||
|         } | ||||
|     } | ||||
| @@ -198,12 +236,13 @@ issuePopupMenu = popupMenu() { | ||||
|                 return | ||||
|             } | ||||
|             issueList.invalidate() | ||||
|             issueList.repaint() | ||||
|         }) | ||||
| } | ||||
|  | ||||
| frame = application(title:'Personal Issue Tracker', | ||||
|   locationRelativeTo: null, | ||||
|   minimumSize: [600, 400], | ||||
|   minimumSize: [800, 500], | ||||
|   //size:[320,480], | ||||
|   pack:true, | ||||
|   //location:[50,50], | ||||
| @@ -231,21 +270,42 @@ frame = application(title:'Personal Issue Tracker', | ||||
|         } | ||||
|  | ||||
|         menu('View') { | ||||
|             Category.values().each { | ||||
|                 checkBoxMenuItem(it.toString(), | ||||
|                     selected: filter.categories.contains(it), | ||||
|                     actionPerformed: { evt -> | ||||
|                         def cat = Category.toCategory(evt.source.text) | ||||
|                         if (filter.categories.contains(cat)) { | ||||
|                             filter.categories.remove(cat) | ||||
|                             evt.source.selected = false | ||||
|                         } else { | ||||
|                             filter.categories.add(cat) | ||||
|                             evt.source.selected = true | ||||
|                         } | ||||
|                         projectListModels.clear() | ||||
|                         displayProject(selectedProject) | ||||
|                     }) | ||||
|             menu('Category') { | ||||
|                 Category.values().each { | ||||
|                     checkBoxMenuItem(it.toString(), | ||||
|                         selected: filter.categories.contains(it), | ||||
|                         actionPerformed: { evt -> | ||||
|                             def cat = Category.toCategory(evt.source.text) | ||||
|                             if (filter.categories.contains(cat)) { | ||||
|                                 filter.categories.remove(cat) | ||||
|                                 evt.source.selected = false | ||||
|                             } else { | ||||
|                                 filter.categories.add(cat) | ||||
|                                 evt.source.selected = true | ||||
|                             } | ||||
|                             projectListModels.clear() | ||||
|                             displayProject(selectedProject) | ||||
|                         }) | ||||
|                 } | ||||
|             } | ||||
|  | ||||
|             menu('Status') { | ||||
|                 Status.values().each { | ||||
|                     checkBoxMenuItem(it.toString(), | ||||
|                         selected: filter.status.contains(it), | ||||
|                         actionPerformed: { evt -> | ||||
|                             def st = Status.toStatus(evt.source.text[0..5]) | ||||
|                             if (filter.status.contains(st)) { | ||||
|                                 filter.status.remove(st) | ||||
|                                 evt.source.selected = false | ||||
|                             } else { | ||||
|                                 filter.status.add(st) | ||||
|                                 evt.source.selected = true | ||||
|                             } | ||||
|                             projectListModels.clear() | ||||
|                             displayProject(selectedProject) | ||||
|                         }) | ||||
|                 } | ||||
|             } | ||||
|  | ||||
|         } | ||||
| @@ -266,7 +326,10 @@ frame = application(title:'Personal Issue Tracker', | ||||
|                         if (model.rootProject) { | ||||
|                             projectTree.rootVisible = model.rootProject.issues.size() | ||||
|                             new DefaultTreeModel(makeNodes(model.rootProject)) | ||||
|                         } else new DefaultTreeModel() | ||||
|                         } else { | ||||
|                             projectTree.rootVisible = false | ||||
|                             new DefaultTreeModel(new DefaultMutableTreeNode()) | ||||
|                         } | ||||
|                     }), | ||||
|                 valueChanged: { evt -> | ||||
|                     selectedProject = evt?.newLeadSelectionPath?.lastPathComponent?.userObject ?: model.rootProject | ||||
| @@ -280,6 +343,8 @@ frame = application(title:'Personal Issue Tracker', | ||||
|                             evt.x, evt.y) | ||||
|                     } | ||||
|                 }) | ||||
|             projectTree.model = new DefaultTreeModel(new DefaultMutableTreeNode()) | ||||
|             projectTree.rootVisible = false | ||||
|      | ||||
|             projectTree.selectionModel.selectionMode = | ||||
|                 TreeSelectionModel.SINGLE_TREE_SELECTION | ||||
| @@ -292,7 +357,8 @@ frame = application(title:'Personal Issue Tracker', | ||||
|             scrollPane(constraints: "top") { | ||||
|                 issueList = list( | ||||
|                     cellRenderer: new IssueListCellRenderer( | ||||
|                         issueIcons: categoryIcons), | ||||
|                         categoryIcons: categoryIcons, | ||||
|                         statusIcons: statusIcons), | ||||
|                     selectionMode: ListSelectionModel.SINGLE_SELECTION, | ||||
|                     valueChanged: { displayIssue(issueList.selectedValue) }, | ||||
|                     mouseClicked: { evt -> | ||||
| @@ -306,7 +372,19 @@ frame = application(title:'Personal Issue Tracker', | ||||
|                     }) | ||||
|             } | ||||
|             scrollPane(constraints: "bottom") { | ||||
|                 issueTextArea = textArea() | ||||
|                 issueTextArea = textArea( | ||||
|                     font: new Font(Font.MONOSPACED, Font.PLAIN, 12), | ||||
|                     focusGained: {}, | ||||
|                     focusLost: { | ||||
|                         if (!issueList?.selectedValue) return | ||||
|                         if (issueTextArea.text != issueList.selectedValue.text) | ||||
|                             issueList.selectedValue.text = issueTextArea.text | ||||
|                     }, | ||||
|                     mouseExited: { | ||||
|                         if (!issueList?.selectedValue) return | ||||
|                         if (issueTextArea.text != issueList.selectedValue.text) | ||||
|                             issueList.selectedValue.text = issueTextArea.text | ||||
|                     }) | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|   | ||||
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										
											BIN
										
									
								
								pit-swing/lib/pit-2.0.1.jar
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								pit-swing/lib/pit-2.0.1.jar
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| @@ -0,0 +1,60 @@ | ||||
| package com.jdbernard.pit.swing | ||||
|  | ||||
| import java.awt.Component | ||||
| import java.awt.Graphics | ||||
| import javax.swing.Icon | ||||
|  | ||||
| /** | ||||
|  * This class provides a composite icon. A composite icon | ||||
|  * draws its parts one on the other, all aligned to the | ||||
|  * left top corner. The size of the compsite icon is the | ||||
|  * max size of its parts. | ||||
|  * | ||||
|  */ | ||||
| public class CompositeIcon implements Icon { | ||||
|   List<Icon> icons | ||||
|  | ||||
|   /** | ||||
|    * Construct a composite icon. | ||||
|    * | ||||
|    * @param i The parts. | ||||
|    */ | ||||
|   public CompositeIcon(List<Icon> i) { icons = i; } | ||||
|  | ||||
|   /** | ||||
|    * Draw the icon at the specified location.  Icon implementations | ||||
|    * may use the Component argument to get properties useful for | ||||
|    * painting, e.g. the foreground or background color. | ||||
|    * | ||||
|    * @param c The component to take attributes from. | ||||
|    * @param g The graphics port to draw into. | ||||
|    * @param x The x drawing coordinate. | ||||
|    * @param y The y drawing coordinate. | ||||
|    */ | ||||
|   public void paintIcon(Component c, Graphics g, int x, int y) { | ||||
|     icons.each { it.paintIcon(c, g, x, y) } | ||||
|   } | ||||
|  | ||||
|   /** | ||||
|    * Returns the icon's width. | ||||
|    * | ||||
|    * @return an int specifying the fixed width of the icon. | ||||
|    */ | ||||
|   public int getIconWidth() { | ||||
|     int width = 0; | ||||
|     icons.each { width = Math.max(width, it.iconWidth) } | ||||
|     return width; | ||||
|   } | ||||
|  | ||||
|   /** | ||||
|    * Returns the icon's height. | ||||
|    * | ||||
|    * @return an int specifying the fixed height of the icon. | ||||
|    */ | ||||
|   public int getIconHeight() { | ||||
|     int height = 0; | ||||
|     icons.each { height = Math.max(height, it.iconHeight) } | ||||
|     return height; | ||||
|   } | ||||
|  | ||||
| } | ||||
| @@ -1,5 +1,7 @@ | ||||
| package com.jdbernard.pit.swing | ||||
|  | ||||
| import com.jdbernard.pit.Category | ||||
| import com.jdbernard.pit.Status | ||||
| import java.awt.Component | ||||
| import javax.swing.Icon | ||||
| import javax.swing.JList | ||||
| @@ -7,14 +9,23 @@ import javax.swing.DefaultListCellRenderer | ||||
|  | ||||
| public class IssueListCellRenderer extends DefaultListCellRenderer { | ||||
|  | ||||
|     Map<Category, Icon> issueIcons | ||||
|     Map<Category, Icon> categoryIcons | ||||
|     Map<Status, Icon> statusIcons | ||||
|      | ||||
|     public Component getListCellRendererComponent(JList list, Object value, | ||||
|     int index, boolean selected, boolean hasFocus) { | ||||
|         def component = super.getListCellRendererComponent(list, value, index, | ||||
|             selected, hasFocus) | ||||
|         if (issueIcons[(value.category)]) | ||||
|             component.setIcon(issueIcons[(value.category)]) | ||||
|         def icon | ||||
|         if (categoryIcons[(value.category)]) { | ||||
|             icon = categoryIcons[(value.category)] | ||||
|  | ||||
|             if (statusIcons[(value.status)]) | ||||
|                 icon = new CompositeIcon([icon, statusIcons[(value.status)]]) | ||||
|         } | ||||
|  | ||||
|         if (icon) setIcon(icon) | ||||
|  | ||||
|         component.text = "<html><tt>${value.id} (${value.priority}): </tt>" + | ||||
|             "${value.title}</html>" | ||||
|         return component | ||||
|   | ||||
							
								
								
									
										0
									
								
								pit-swing/stacktrace.log
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										0
									
								
								pit-swing/stacktrace.log
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										
											BIN
										
									
								
								release/lib/pit-2.0.1.jar
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								release/lib/pit-2.0.1.jar
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										
											BIN
										
									
								
								release/pit-swing-2.0.1.jar
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								release/pit-swing-2.0.1.jar
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| @@ -1 +1 @@ | ||||
| application.version=1.1.8 | ||||
| application.version=2.0.1 | ||||
|   | ||||
		Reference in New Issue
	
	Block a user