Revision 1298:4f746d8966dd .svn/pristine/21

View differences:

.svn/pristine/21/210ed78bd5324335e5f6bf0efa5404a9438fd74c.svn-base
1
<div class="splitcontentleft">
2
<% i = 0 %>
3
<% split_on = (@issue.custom_field_values.size / 2.0).ceil - 1 %>
4
<% @issue.custom_field_values.each do |value| %>
5
  <p><%= custom_field_tag_with_label :issue, value %></p>
6
<% if i == split_on -%>
7
</div><div class="splitcontentright">
8
<% end -%>
9
<% i += 1 -%>
10
<% end -%>
11
</div>
12
<div style="clear:both;"> </div>
.svn/pristine/21/21220872c05ed094a0e17dfec9147a1d8f235a7a.svn-base
1
class Meeting < ActiveRecord::Base
2
  belongs_to :project
3

  
4
  acts_as_event :title => Proc.new {|o| "#{o.scheduled_on} Meeting"},
5
                :datetime => :scheduled_on,
6
                :author => nil,
7
                :url => Proc.new {|o| {:controller => 'meetings', :action => 'show', :id => o.id}}                
8
  
9
  acts_as_activity_provider :timestamp => 'scheduled_on',
10
                            :find_options => { :include => :project }
11
end
.svn/pristine/21/213cd47b5ee47b691425e1fcb6dffb207c707d8c.svn-base
1
/*! jQuery UI - v1.9.2 - 2012-12-26
2
* http://jqueryui.com
3
* Includes: jquery.ui.core.css, jquery.ui.resizable.css, jquery.ui.selectable.css, jquery.ui.accordion.css, jquery.ui.autocomplete.css, jquery.ui.button.css, jquery.ui.datepicker.css, jquery.ui.dialog.css, jquery.ui.menu.css, jquery.ui.progressbar.css, jquery.ui.slider.css, jquery.ui.spinner.css, jquery.ui.tabs.css, jquery.ui.tooltip.css
4
* To view and modify this theme, visit http://jqueryui.com/themeroller/?ffDefault=Verdana%2C%20sans-serif&fwDefault=bold&fsDefault=1.1em&cornerRadius=4px&bgColorHeader=759fcf&bgTextureHeader=12_gloss_wave.png&bgImgOpacityHeader=35&borderColorHeader=628db6&fcHeader=ffffff&iconColorHeader=ffffff&bgColorContent=eeeeee&bgTextureContent=03_highlight_soft.png&bgImgOpacityContent=100&borderColorContent=dddddd&fcContent=333333&iconColorContent=222222&bgColorDefault=f6f6f6&bgTextureDefault=02_glass.png&bgImgOpacityDefault=100&borderColorDefault=cccccc&fcDefault=628db6&iconColorDefault=759fcf&bgColorHover=eef5fd&bgTextureHover=02_glass.png&bgImgOpacityHover=100&borderColorHover=628db6&fcHover=628db6&iconColorHover=759fcf&bgColorActive=ffffff&bgTextureActive=02_glass.png&bgImgOpacityActive=65&borderColorActive=628db6&fcActive=628db6&iconColorActive=759fcf&bgColorHighlight=759fcf&bgTextureHighlight=03_highlight_soft.png&bgImgOpacityHighlight=75&borderColorHighlight=628db6&fcHighlight=363636&iconColorHighlight=759fcf&bgColorError=b81900&bgTextureError=08_diagonals_thick.png&bgImgOpacityError=18&borderColorError=cd0a0a&fcError=ffffff&iconColorError=ffd27a&bgColorOverlay=666666&bgTextureOverlay=08_diagonals_thick.png&bgImgOpacityOverlay=20&opacityOverlay=50&bgColorShadow=000000&bgTextureShadow=01_flat.png&bgImgOpacityShadow=10&opacityShadow=20&thicknessShadow=5px&offsetTopShadow=-5px&offsetLeftShadow=-5px&cornerRadiusShadow=5px
5
* Copyright (c) 2012 jQuery Foundation and other contributors Licensed MIT */.ui-helper-hidden{display:none}.ui-helper-hidden-accessible{border:0;clip:rect(0 0 0 0);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px}.ui-helper-reset{margin:0;padding:0;border:0;outline:0;line-height:1.3;text-decoration:none;font-size:100%;list-style:none}.ui-helper-clearfix:before,.ui-helper-clearfix:after{content:"";display:table}.ui-helper-clearfix:after{clear:both}.ui-helper-clearfix{zoom:1}.ui-helper-zfix{width:100%;height:100%;top:0;left:0;position:absolute;opacity:0;filter:Alpha(Opacity=0)}.ui-state-disabled{cursor:default!important}.ui-icon{display:block;text-indent:-99999px;overflow:hidden;background-repeat:no-repeat}.ui-widget-overlay{position:absolute;top:0;left:0;width:100%;height:100%}.ui-resizable{position:relative}.ui-resizable-handle{position:absolute;font-size:0.1px;display:block}.ui-resizable-disabled .ui-resizable-handle,.ui-resizable-autohide .ui-resizable-handle{display:none}.ui-resizable-n{cursor:n-resize;height:7px;width:100%;top:-5px;left:0}.ui-resizable-s{cursor:s-resize;height:7px;width:100%;bottom:-5px;left:0}.ui-resizable-e{cursor:e-resize;width:7px;right:-5px;top:0;height:100%}.ui-resizable-w{cursor:w-resize;width:7px;left:-5px;top:0;height:100%}.ui-resizable-se{cursor:se-resize;width:12px;height:12px;right:1px;bottom:1px}.ui-resizable-sw{cursor:sw-resize;width:9px;height:9px;left:-5px;bottom:-5px}.ui-resizable-nw{cursor:nw-resize;width:9px;height:9px;left:-5px;top:-5px}.ui-resizable-ne{cursor:ne-resize;width:9px;height:9px;right:-5px;top:-5px}.ui-selectable-helper{position:absolute;z-index:100;border:1px dotted black}.ui-accordion .ui-accordion-header{display:block;cursor:pointer;position:relative;margin-top:2px;padding:.5em .5em .5em .7em;zoom:1}.ui-accordion .ui-accordion-icons{padding-left:2.2em}.ui-accordion .ui-accordion-noicons{padding-left:.7em}.ui-accordion .ui-accordion-icons .ui-accordion-icons{padding-left:2.2em}.ui-accordion .ui-accordion-header .ui-accordion-header-icon{position:absolute;left:.5em;top:50%;margin-top:-8px}.ui-accordion .ui-accordion-content{padding:1em 2.2em;border-top:0;overflow:auto;zoom:1}.ui-autocomplete{position:absolute;top:0;left:0;cursor:default}* html .ui-autocomplete{width:1px}.ui-button{display:inline-block;position:relative;padding:0;margin-right:.1em;cursor:pointer;text-align:center;zoom:1;overflow:visible}.ui-button,.ui-button:link,.ui-button:visited,.ui-button:hover,.ui-button:active{text-decoration:none}.ui-button-icon-only{width:2.2em}button.ui-button-icon-only{width:2.4em}.ui-button-icons-only{width:3.4em}button.ui-button-icons-only{width:3.7em}.ui-button .ui-button-text{display:block;line-height:1.4}.ui-button-text-only .ui-button-text{padding:.4em 1em}.ui-button-icon-only .ui-button-text,.ui-button-icons-only .ui-button-text{padding:.4em;text-indent:-9999999px}.ui-button-text-icon-primary .ui-button-text,.ui-button-text-icons .ui-button-text{padding:.4em 1em .4em 2.1em}.ui-button-text-icon-secondary .ui-button-text,.ui-button-text-icons .ui-button-text{padding:.4em 2.1em .4em 1em}.ui-button-text-icons .ui-button-text{padding-left:2.1em;padding-right:2.1em}input.ui-button{padding:.4em 1em}.ui-button-icon-only .ui-icon,.ui-button-text-icon-primary .ui-icon,.ui-button-text-icon-secondary .ui-icon,.ui-button-text-icons .ui-icon,.ui-button-icons-only .ui-icon{position:absolute;top:50%;margin-top:-8px}.ui-button-icon-only .ui-icon{left:50%;margin-left:-8px}.ui-button-text-icon-primary .ui-button-icon-primary,.ui-button-text-icons .ui-button-icon-primary,.ui-button-icons-only .ui-button-icon-primary{left:.5em}.ui-button-text-icon-secondary .ui-button-icon-secondary,.ui-button-text-icons .ui-button-icon-secondary,.ui-button-icons-only .ui-button-icon-secondary{right:.5em}.ui-button-text-icons .ui-button-icon-secondary,.ui-button-icons-only .ui-button-icon-secondary{right:.5em}.ui-buttonset{margin-right:7px}.ui-buttonset .ui-button{margin-left:0;margin-right:-.3em}button.ui-button::-moz-focus-inner{border:0;padding:0}.ui-datepicker{width:17em;padding:.2em .2em 0;display:none}.ui-datepicker .ui-datepicker-header{position:relative;padding:.2em 0}.ui-datepicker .ui-datepicker-prev,.ui-datepicker .ui-datepicker-next{position:absolute;top:2px;width:1.8em;height:1.8em}.ui-datepicker .ui-datepicker-prev-hover,.ui-datepicker .ui-datepicker-next-hover{top:1px}.ui-datepicker .ui-datepicker-prev{left:2px}.ui-datepicker .ui-datepicker-next{right:2px}.ui-datepicker .ui-datepicker-prev-hover{left:1px}.ui-datepicker .ui-datepicker-next-hover{right:1px}.ui-datepicker .ui-datepicker-prev span,.ui-datepicker .ui-datepicker-next span{display:block;position:absolute;left:50%;margin-left:-8px;top:50%;margin-top:-8px}.ui-datepicker .ui-datepicker-title{margin:0 2.3em;line-height:1.8em;text-align:center}.ui-datepicker .ui-datepicker-title select{font-size:1em;margin:1px 0}.ui-datepicker select.ui-datepicker-month-year{width:100%}.ui-datepicker select.ui-datepicker-month,.ui-datepicker select.ui-datepicker-year{width:49%}.ui-datepicker table{width:100%;font-size:.9em;border-collapse:collapse;margin:0 0 .4em}.ui-datepicker th{padding:.7em .3em;text-align:center;font-weight:bold;border:0}.ui-datepicker td{border:0;padding:1px}.ui-datepicker td span,.ui-datepicker td a{display:block;padding:.2em;text-align:right;text-decoration:none}.ui-datepicker .ui-datepicker-buttonpane{background-image:none;margin:.7em 0 0 0;padding:0 .2em;border-left:0;border-right:0;border-bottom:0}.ui-datepicker .ui-datepicker-buttonpane button{float:right;margin:.5em .2em .4em;cursor:pointer;padding:.2em .6em .3em .6em;width:auto;overflow:visible}.ui-datepicker .ui-datepicker-buttonpane button.ui-datepicker-current{float:left}.ui-datepicker.ui-datepicker-multi{width:auto}.ui-datepicker-multi .ui-datepicker-group{float:left}.ui-datepicker-multi .ui-datepicker-group table{width:95%;margin:0 auto .4em}.ui-datepicker-multi-2 .ui-datepicker-group{width:50%}.ui-datepicker-multi-3 .ui-datepicker-group{width:33.3%}.ui-datepicker-multi-4 .ui-datepicker-group{width:25%}.ui-datepicker-multi .ui-datepicker-group-last .ui-datepicker-header{border-left-width:0}.ui-datepicker-multi .ui-datepicker-group-middle .ui-datepicker-header{border-left-width:0}.ui-datepicker-multi .ui-datepicker-buttonpane{clear:left}.ui-datepicker-row-break{clear:both;width:100%;font-size:0em}.ui-datepicker-rtl{direction:rtl}.ui-datepicker-rtl .ui-datepicker-prev{right:2px;left:auto}.ui-datepicker-rtl .ui-datepicker-next{left:2px;right:auto}.ui-datepicker-rtl .ui-datepicker-prev:hover{right:1px;left:auto}.ui-datepicker-rtl .ui-datepicker-next:hover{left:1px;right:auto}.ui-datepicker-rtl .ui-datepicker-buttonpane{clear:right}.ui-datepicker-rtl .ui-datepicker-buttonpane button{float:left}.ui-datepicker-rtl .ui-datepicker-buttonpane button.ui-datepicker-current{float:right}.ui-datepicker-rtl .ui-datepicker-group{float:right}.ui-datepicker-rtl .ui-datepicker-group-last .ui-datepicker-header{border-right-width:0;border-left-width:1px}.ui-datepicker-rtl .ui-datepicker-group-middle .ui-datepicker-header{border-right-width:0;border-left-width:1px}.ui-datepicker-cover{position:absolute;z-index:-1;filter:mask();top:-4px;left:-4px;width:200px;height:200px}.ui-dialog{position:absolute;top:0;left:0;padding:.2em;width:300px;overflow:hidden}.ui-dialog .ui-dialog-titlebar{padding:.4em 1em;position:relative}.ui-dialog .ui-dialog-title{float:left;margin:.1em 16px .1em 0}.ui-dialog .ui-dialog-titlebar-close{position:absolute;right:.3em;top:50%;width:19px;margin:-10px 0 0 0;padding:1px;height:18px}.ui-dialog .ui-dialog-titlebar-close span{display:block;margin:1px}.ui-dialog .ui-dialog-titlebar-close:hover,.ui-dialog .ui-dialog-titlebar-close:focus{padding:0}.ui-dialog .ui-dialog-content{position:relative;border:0;padding:.5em 1em;background:none;overflow:auto;zoom:1}.ui-dialog .ui-dialog-buttonpane{text-align:left;border-width:1px 0 0 0;background-image:none;margin:.5em 0 0 0;padding:.3em 1em .5em .4em}.ui-dialog .ui-dialog-buttonpane .ui-dialog-buttonset{float:right}.ui-dialog .ui-dialog-buttonpane button{margin:.5em .4em .5em 0;cursor:pointer}.ui-dialog .ui-resizable-se{width:14px;height:14px;right:3px;bottom:3px}.ui-draggable .ui-dialog-titlebar{cursor:move}.ui-menu{list-style:none;padding:2px;margin:0;display:block;outline:none}.ui-menu .ui-menu{margin-top:-3px;position:absolute}.ui-menu .ui-menu-item{margin:0;padding:0;zoom:1;width:100%}.ui-menu .ui-menu-divider{margin:5px -2px 5px -2px;height:0;font-size:0;line-height:0;border-width:1px 0 0 0}.ui-menu .ui-menu-item a{text-decoration:none;display:block;padding:2px .4em;line-height:1.5;zoom:1;font-weight:normal}.ui-menu .ui-menu-item a.ui-state-focus,.ui-menu .ui-menu-item a.ui-state-active{font-weight:normal;margin:-1px}.ui-menu .ui-state-disabled{font-weight:normal;margin:.4em 0 .2em;line-height:1.5}.ui-menu .ui-state-disabled a{cursor:default}.ui-menu-icons{position:relative}.ui-menu-icons .ui-menu-item a{position:relative;padding-left:2em}.ui-menu .ui-icon{position:absolute;top:.2em;left:.2em}.ui-menu .ui-menu-icon{position:static;float:right}.ui-progressbar{height:2em;text-align:left;overflow:hidden}.ui-progressbar .ui-progressbar-value{margin:-1px;height:100%}.ui-slider{position:relative;text-align:left}.ui-slider .ui-slider-handle{position:absolute;z-index:2;width:1.2em;height:1.2em;cursor:default}.ui-slider .ui-slider-range{position:absolute;z-index:1;font-size:.7em;display:block;border:0;background-position:0 0}.ui-slider-horizontal{height:.8em}.ui-slider-horizontal .ui-slider-handle{top:-.3em;margin-left:-.6em}.ui-slider-horizontal .ui-slider-range{top:0;height:100%}.ui-slider-horizontal .ui-slider-range-min{left:0}.ui-slider-horizontal .ui-slider-range-max{right:0}.ui-slider-vertical{width:.8em;height:100px}.ui-slider-vertical .ui-slider-handle{left:-.3em;margin-left:0;margin-bottom:-.6em}.ui-slider-vertical .ui-slider-range{left:0;width:100%}.ui-slider-vertical .ui-slider-range-min{bottom:0}.ui-slider-vertical .ui-slider-range-max{top:0}.ui-spinner{position:relative;display:inline-block;overflow:hidden;padding:0;vertical-align:middle}.ui-spinner-input{border:none;background:none;padding:0;margin:.2em 0;vertical-align:middle;margin-left:.4em;margin-right:22px}.ui-spinner-button{width:16px;height:50%;font-size:.5em;padding:0;margin:0;text-align:center;position:absolute;cursor:default;display:block;overflow:hidden;right:0}.ui-spinner a.ui-spinner-button{border-top:none;border-bottom:none;border-right:none}.ui-spinner .ui-icon{position:absolute;margin-top:-8px;top:50%;left:0}.ui-spinner-up{top:0}.ui-spinner-down{bottom:0}.ui-spinner .ui-icon-triangle-1-s{background-position:-65px -16px}.ui-tabs{position:relative;padding:.2em;zoom:1}.ui-tabs .ui-tabs-nav{margin:0;padding:.2em .2em 0}.ui-tabs .ui-tabs-nav li{list-style:none;float:left;position:relative;top:0;margin:1px .2em 0 0;border-bottom:0;padding:0;white-space:nowrap}.ui-tabs .ui-tabs-nav li a{float:left;padding:.5em 1em;text-decoration:none}.ui-tabs .ui-tabs-nav li.ui-tabs-active{margin-bottom:-1px;padding-bottom:1px}.ui-tabs .ui-tabs-nav li.ui-tabs-active a,.ui-tabs .ui-tabs-nav li.ui-state-disabled a,.ui-tabs .ui-tabs-nav li.ui-tabs-loading a{cursor:text}.ui-tabs .ui-tabs-nav li a,.ui-tabs-collapsible .ui-tabs-nav li.ui-tabs-active a{cursor:pointer}.ui-tabs .ui-tabs-panel{display:block;border-width:0;padding:1em 1.4em;background:none}.ui-tooltip{padding:8px;position:absolute;z-index:9999;max-width:300px;-webkit-box-shadow:0 0 5px #aaa;box-shadow:0 0 5px #aaa}* html .ui-tooltip{background-image:none}body .ui-tooltip{border-width:2px}.ui-widget{font-family:Verdana,sans-serif;font-size:1.1em}.ui-widget .ui-widget{font-size:1em}.ui-widget input,.ui-widget select,.ui-widget textarea,.ui-widget button{font-family:Verdana,sans-serif;font-size:1em}.ui-widget-content{border:1px solid #ddd;background:#eee url(images/ui-bg_highlight-soft_100_eeeeee_1x100.png) 50% top repeat-x;color:#333}.ui-widget-content a{color:#333}.ui-widget-header{border:1px solid #628db6;background:#759fcf url(images/ui-bg_gloss-wave_35_759fcf_500x100.png) 50% 50% repeat-x;color:#fff;font-weight:bold}.ui-widget-header a{color:#fff}.ui-state-default,.ui-widget-content .ui-state-default,.ui-widget-header .ui-state-default{border:1px solid #ccc;background:#f6f6f6 url(images/ui-bg_glass_100_f6f6f6_1x400.png) 50% 50% repeat-x;font-weight:bold;color:#628db6}.ui-state-default a,.ui-state-default a:link,.ui-state-default a:visited{color:#628db6;text-decoration:none}.ui-state-hover,.ui-widget-content .ui-state-hover,.ui-widget-header .ui-state-hover,.ui-state-focus,.ui-widget-content .ui-state-focus,.ui-widget-header .ui-state-focus{border:1px solid #628db6;background:#eef5fd url(images/ui-bg_glass_100_eef5fd_1x400.png) 50% 50% repeat-x;font-weight:bold;color:#628db6}.ui-state-hover a,.ui-state-hover a:hover,.ui-state-hover a:link,.ui-state-hover a:visited{color:#628db6;text-decoration:none}.ui-state-active,.ui-widget-content .ui-state-active,.ui-widget-header .ui-state-active{border:1px solid #628db6;background:#fff url(images/ui-bg_glass_65_ffffff_1x400.png) 50% 50% repeat-x;font-weight:bold;color:#628db6}.ui-state-active a,.ui-state-active a:link,.ui-state-active a:visited{color:#628db6;text-decoration:none}.ui-state-highlight,.ui-widget-content .ui-state-highlight,.ui-widget-header .ui-state-highlight{border:1px solid #628db6;background:#759fcf url(images/ui-bg_highlight-soft_75_759fcf_1x100.png) 50% top repeat-x;color:#363636}.ui-state-highlight a,.ui-widget-content .ui-state-highlight a,.ui-widget-header .ui-state-highlight a{color:#363636}.ui-state-error,.ui-widget-content .ui-state-error,.ui-widget-header .ui-state-error{border:1px solid #cd0a0a;background:#b81900 url(images/ui-bg_diagonals-thick_18_b81900_40x40.png) 50% 50% repeat;color:#fff}.ui-state-error a,.ui-widget-content .ui-state-error a,.ui-widget-header .ui-state-error a{color:#fff}.ui-state-error-text,.ui-widget-content .ui-state-error-text,.ui-widget-header .ui-state-error-text{color:#fff}.ui-priority-primary,.ui-widget-content .ui-priority-primary,.ui-widget-header .ui-priority-primary{font-weight:bold}.ui-priority-secondary,.ui-widget-content .ui-priority-secondary,.ui-widget-header .ui-priority-secondary{opacity:.7;filter:Alpha(Opacity=70);font-weight:normal}.ui-state-disabled,.ui-widget-content .ui-state-disabled,.ui-widget-header .ui-state-disabled{opacity:.35;filter:Alpha(Opacity=35);background-image:none}.ui-state-disabled .ui-icon{filter:Alpha(Opacity=35)}.ui-icon{width:16px;height:16px;background-image:url(images/ui-icons_222222_256x240.png)}.ui-widget-content .ui-icon{background-image:url(images/ui-icons_222222_256x240.png)}.ui-widget-header .ui-icon{background-image:url(images/ui-icons_ffffff_256x240.png)}.ui-state-default .ui-icon{background-image:url(images/ui-icons_759fcf_256x240.png)}.ui-state-hover .ui-icon,.ui-state-focus .ui-icon{background-image:url(images/ui-icons_759fcf_256x240.png)}.ui-state-active .ui-icon{background-image:url(images/ui-icons_759fcf_256x240.png)}.ui-state-highlight .ui-icon{background-image:url(images/ui-icons_759fcf_256x240.png)}.ui-state-error .ui-icon,.ui-state-error-text .ui-icon{background-image:url(images/ui-icons_ffd27a_256x240.png)}.ui-icon-carat-1-n{background-position:0 0}.ui-icon-carat-1-ne{background-position:-16px 0}.ui-icon-carat-1-e{background-position:-32px 0}.ui-icon-carat-1-se{background-position:-48px 0}.ui-icon-carat-1-s{background-position:-64px 0}.ui-icon-carat-1-sw{background-position:-80px 0}.ui-icon-carat-1-w{background-position:-96px 0}.ui-icon-carat-1-nw{background-position:-112px 0}.ui-icon-carat-2-n-s{background-position:-128px 0}.ui-icon-carat-2-e-w{background-position:-144px 0}.ui-icon-triangle-1-n{background-position:0 -16px}.ui-icon-triangle-1-ne{background-position:-16px -16px}.ui-icon-triangle-1-e{background-position:-32px -16px}.ui-icon-triangle-1-se{background-position:-48px -16px}.ui-icon-triangle-1-s{background-position:-64px -16px}.ui-icon-triangle-1-sw{background-position:-80px -16px}.ui-icon-triangle-1-w{background-position:-96px -16px}.ui-icon-triangle-1-nw{background-position:-112px -16px}.ui-icon-triangle-2-n-s{background-position:-128px -16px}.ui-icon-triangle-2-e-w{background-position:-144px -16px}.ui-icon-arrow-1-n{background-position:0 -32px}.ui-icon-arrow-1-ne{background-position:-16px -32px}.ui-icon-arrow-1-e{background-position:-32px -32px}.ui-icon-arrow-1-se{background-position:-48px -32px}.ui-icon-arrow-1-s{background-position:-64px -32px}.ui-icon-arrow-1-sw{background-position:-80px -32px}.ui-icon-arrow-1-w{background-position:-96px -32px}.ui-icon-arrow-1-nw{background-position:-112px -32px}.ui-icon-arrow-2-n-s{background-position:-128px -32px}.ui-icon-arrow-2-ne-sw{background-position:-144px -32px}.ui-icon-arrow-2-e-w{background-position:-160px -32px}.ui-icon-arrow-2-se-nw{background-position:-176px -32px}.ui-icon-arrowstop-1-n{background-position:-192px -32px}.ui-icon-arrowstop-1-e{background-position:-208px -32px}.ui-icon-arrowstop-1-s{background-position:-224px -32px}.ui-icon-arrowstop-1-w{background-position:-240px -32px}.ui-icon-arrowthick-1-n{background-position:0 -48px}.ui-icon-arrowthick-1-ne{background-position:-16px -48px}.ui-icon-arrowthick-1-e{background-position:-32px -48px}.ui-icon-arrowthick-1-se{background-position:-48px -48px}.ui-icon-arrowthick-1-s{background-position:-64px -48px}.ui-icon-arrowthick-1-sw{background-position:-80px -48px}.ui-icon-arrowthick-1-w{background-position:-96px -48px}.ui-icon-arrowthick-1-nw{background-position:-112px -48px}.ui-icon-arrowthick-2-n-s{background-position:-128px -48px}.ui-icon-arrowthick-2-ne-sw{background-position:-144px -48px}.ui-icon-arrowthick-2-e-w{background-position:-160px -48px}.ui-icon-arrowthick-2-se-nw{background-position:-176px -48px}.ui-icon-arrowthickstop-1-n{background-position:-192px -48px}.ui-icon-arrowthickstop-1-e{background-position:-208px -48px}.ui-icon-arrowthickstop-1-s{background-position:-224px -48px}.ui-icon-arrowthickstop-1-w{background-position:-240px -48px}.ui-icon-arrowreturnthick-1-w{background-position:0 -64px}.ui-icon-arrowreturnthick-1-n{background-position:-16px -64px}.ui-icon-arrowreturnthick-1-e{background-position:-32px -64px}.ui-icon-arrowreturnthick-1-s{background-position:-48px -64px}.ui-icon-arrowreturn-1-w{background-position:-64px -64px}.ui-icon-arrowreturn-1-n{background-position:-80px -64px}.ui-icon-arrowreturn-1-e{background-position:-96px -64px}.ui-icon-arrowreturn-1-s{background-position:-112px -64px}.ui-icon-arrowrefresh-1-w{background-position:-128px -64px}.ui-icon-arrowrefresh-1-n{background-position:-144px -64px}.ui-icon-arrowrefresh-1-e{background-position:-160px -64px}.ui-icon-arrowrefresh-1-s{background-position:-176px -64px}.ui-icon-arrow-4{background-position:0 -80px}.ui-icon-arrow-4-diag{background-position:-16px -80px}.ui-icon-extlink{background-position:-32px -80px}.ui-icon-newwin{background-position:-48px -80px}.ui-icon-refresh{background-position:-64px -80px}.ui-icon-shuffle{background-position:-80px -80px}.ui-icon-transfer-e-w{background-position:-96px -80px}.ui-icon-transferthick-e-w{background-position:-112px -80px}.ui-icon-folder-collapsed{background-position:0 -96px}.ui-icon-folder-open{background-position:-16px -96px}.ui-icon-document{background-position:-32px -96px}.ui-icon-document-b{background-position:-48px -96px}.ui-icon-note{background-position:-64px -96px}.ui-icon-mail-closed{background-position:-80px -96px}.ui-icon-mail-open{background-position:-96px -96px}.ui-icon-suitcase{background-position:-112px -96px}.ui-icon-comment{background-position:-128px -96px}.ui-icon-person{background-position:-144px -96px}.ui-icon-print{background-position:-160px -96px}.ui-icon-trash{background-position:-176px -96px}.ui-icon-locked{background-position:-192px -96px}.ui-icon-unlocked{background-position:-208px -96px}.ui-icon-bookmark{background-position:-224px -96px}.ui-icon-tag{background-position:-240px -96px}.ui-icon-home{background-position:0 -112px}.ui-icon-flag{background-position:-16px -112px}.ui-icon-calendar{background-position:-32px -112px}.ui-icon-cart{background-position:-48px -112px}.ui-icon-pencil{background-position:-64px -112px}.ui-icon-clock{background-position:-80px -112px}.ui-icon-disk{background-position:-96px -112px}.ui-icon-calculator{background-position:-112px -112px}.ui-icon-zoomin{background-position:-128px -112px}.ui-icon-zoomout{background-position:-144px -112px}.ui-icon-search{background-position:-160px -112px}.ui-icon-wrench{background-position:-176px -112px}.ui-icon-gear{background-position:-192px -112px}.ui-icon-heart{background-position:-208px -112px}.ui-icon-star{background-position:-224px -112px}.ui-icon-link{background-position:-240px -112px}.ui-icon-cancel{background-position:0 -128px}.ui-icon-plus{background-position:-16px -128px}.ui-icon-plusthick{background-position:-32px -128px}.ui-icon-minus{background-position:-48px -128px}.ui-icon-minusthick{background-position:-64px -128px}.ui-icon-close{background-position:-80px -128px}.ui-icon-closethick{background-position:-96px -128px}.ui-icon-key{background-position:-112px -128px}.ui-icon-lightbulb{background-position:-128px -128px}.ui-icon-scissors{background-position:-144px -128px}.ui-icon-clipboard{background-position:-160px -128px}.ui-icon-copy{background-position:-176px -128px}.ui-icon-contact{background-position:-192px -128px}.ui-icon-image{background-position:-208px -128px}.ui-icon-video{background-position:-224px -128px}.ui-icon-script{background-position:-240px -128px}.ui-icon-alert{background-position:0 -144px}.ui-icon-info{background-position:-16px -144px}.ui-icon-notice{background-position:-32px -144px}.ui-icon-help{background-position:-48px -144px}.ui-icon-check{background-position:-64px -144px}.ui-icon-bullet{background-position:-80px -144px}.ui-icon-radio-on{background-position:-96px -144px}.ui-icon-radio-off{background-position:-112px -144px}.ui-icon-pin-w{background-position:-128px -144px}.ui-icon-pin-s{background-position:-144px -144px}.ui-icon-play{background-position:0 -160px}.ui-icon-pause{background-position:-16px -160px}.ui-icon-seek-next{background-position:-32px -160px}.ui-icon-seek-prev{background-position:-48px -160px}.ui-icon-seek-end{background-position:-64px -160px}.ui-icon-seek-start{background-position:-80px -160px}.ui-icon-seek-first{background-position:-80px -160px}.ui-icon-stop{background-position:-96px -160px}.ui-icon-eject{background-position:-112px -160px}.ui-icon-volume-off{background-position:-128px -160px}.ui-icon-volume-on{background-position:-144px -160px}.ui-icon-power{background-position:0 -176px}.ui-icon-signal-diag{background-position:-16px -176px}.ui-icon-signal{background-position:-32px -176px}.ui-icon-battery-0{background-position:-48px -176px}.ui-icon-battery-1{background-position:-64px -176px}.ui-icon-battery-2{background-position:-80px -176px}.ui-icon-battery-3{background-position:-96px -176px}.ui-icon-circle-plus{background-position:0 -192px}.ui-icon-circle-minus{background-position:-16px -192px}.ui-icon-circle-close{background-position:-32px -192px}.ui-icon-circle-triangle-e{background-position:-48px -192px}.ui-icon-circle-triangle-s{background-position:-64px -192px}.ui-icon-circle-triangle-w{background-position:-80px -192px}.ui-icon-circle-triangle-n{background-position:-96px -192px}.ui-icon-circle-arrow-e{background-position:-112px -192px}.ui-icon-circle-arrow-s{background-position:-128px -192px}.ui-icon-circle-arrow-w{background-position:-144px -192px}.ui-icon-circle-arrow-n{background-position:-160px -192px}.ui-icon-circle-zoomin{background-position:-176px -192px}.ui-icon-circle-zoomout{background-position:-192px -192px}.ui-icon-circle-check{background-position:-208px -192px}.ui-icon-circlesmall-plus{background-position:0 -208px}.ui-icon-circlesmall-minus{background-position:-16px -208px}.ui-icon-circlesmall-close{background-position:-32px -208px}.ui-icon-squaresmall-plus{background-position:-48px -208px}.ui-icon-squaresmall-minus{background-position:-64px -208px}.ui-icon-squaresmall-close{background-position:-80px -208px}.ui-icon-grip-dotted-vertical{background-position:0 -224px}.ui-icon-grip-dotted-horizontal{background-position:-16px -224px}.ui-icon-grip-solid-vertical{background-position:-32px -224px}.ui-icon-grip-solid-horizontal{background-position:-48px -224px}.ui-icon-gripsmall-diagonal-se{background-position:-64px -224px}.ui-icon-grip-diagonal-se{background-position:-80px -224px}.ui-corner-all,.ui-corner-top,.ui-corner-left,.ui-corner-tl{-moz-border-radius-topleft:4px;-webkit-border-top-left-radius:4px;-khtml-border-top-left-radius:4px;border-top-left-radius:4px}.ui-corner-all,.ui-corner-top,.ui-corner-right,.ui-corner-tr{-moz-border-radius-topright:4px;-webkit-border-top-right-radius:4px;-khtml-border-top-right-radius:4px;border-top-right-radius:4px}.ui-corner-all,.ui-corner-bottom,.ui-corner-left,.ui-corner-bl{-moz-border-radius-bottomleft:4px;-webkit-border-bottom-left-radius:4px;-khtml-border-bottom-left-radius:4px;border-bottom-left-radius:4px}.ui-corner-all,.ui-corner-bottom,.ui-corner-right,.ui-corner-br{-moz-border-radius-bottomright:4px;-webkit-border-bottom-right-radius:4px;-khtml-border-bottom-right-radius:4px;border-bottom-right-radius:4px}.ui-widget-overlay{background:#666 url(images/ui-bg_diagonals-thick_20_666666_40x40.png) 50% 50% repeat;opacity:.5;filter:Alpha(Opacity=50)}.ui-widget-shadow{margin:-5px 0 0 -5px;padding:5px;background:#000 url(images/ui-bg_flat_10_000000_40x100.png) 50% 50% repeat-x;opacity:.2;filter:Alpha(Opacity=20);-moz-border-radius:5px;-khtml-border-radius:5px;-webkit-border-radius:5px;border-radius:5px}
.svn/pristine/21/217d8edc342d8c96ea1e479a7157b0c862da5448.svn-base
1
# Redmine - project management software
2
# Copyright (C) 2006-2011  Jean-Philippe Lang
3
#
4
# This program is free software; you can redistribute it and/or
5
# modify it under the terms of the GNU General Public License
6
# as published by the Free Software Foundation; either version 2
7
# of the License, or (at your option) any later version.
8
#
9
# This program is distributed in the hope that it will be useful,
10
# but WITHOUT ANY WARRANTY; without even the implied warranty of
11
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
# GNU General Public License for more details.
13
#
14
# You should have received a copy of the GNU General Public License
15
# along with this program; if not, write to the Free Software
16
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
17

  
18
require File.expand_path('../../test_helper', __FILE__)
19
require 'members_controller'
20

  
21
# Re-raise errors caught by the controller.
22
class MembersController; def rescue_action(e) raise e end; end
23

  
24

  
25
class MembersControllerTest < ActionController::TestCase
26
  fixtures :projects, :members, :member_roles, :roles, :users
27

  
28
  def setup
29
    @controller = MembersController.new
30
    @request    = ActionController::TestRequest.new
31
    @response   = ActionController::TestResponse.new
32
    User.current = nil
33
    @request.session[:user_id] = 2
34
  end
35

  
36
  def test_create
37
    assert_difference 'Member.count' do
38
      post :new, :id => 1, :member => {:role_ids => [1], :user_id => 7}
39
    end
40
    assert_redirected_to '/projects/ecookbook/settings/members'
41
    assert User.find(7).member_of?(Project.find(1))
42
  end
43

  
44
  def test_create_multiple
45
    assert_difference 'Member.count', 3 do
46
      post :new, :id => 1, :member => {:role_ids => [1], :user_ids => [7, 8, 9]}
47
    end
48
    assert_redirected_to '/projects/ecookbook/settings/members'
49
    assert User.find(7).member_of?(Project.find(1))
50
  end
51

  
52
  def test_xhr_create
53
    assert_difference 'Member.count', 3 do
54
      post :new, :format => "js", :id => 1, :member => {:role_ids => [1], :user_ids => [7, 8, 9]}
55
    end
56
    assert_select_rjs :replace_html, 'tab-content-members'
57
    assert User.find(7).member_of?(Project.find(1))
58
    assert User.find(8).member_of?(Project.find(1))
59
    assert User.find(9).member_of?(Project.find(1))
60
  end
61

  
62
  def test_xhr_create_with_failure
63
    assert_no_difference 'Member.count' do
64
      post :new, :format => "js", :id => 1, :member => {:role_ids => [], :user_ids => [7, 8, 9]}
65
    end
66
    assert_select '#tab-content-members', 0
67
    assert @response.body.match(/alert/i), "Alert message not sent"
68
  end
69

  
70
  def test_edit
71
    assert_no_difference 'Member.count' do
72
      post :edit, :id => 2, :member => {:role_ids => [1], :user_id => 3}
73
    end
74
    assert_redirected_to '/projects/ecookbook/settings/members'
75
  end
76

  
77
  def test_xhr_edit
78
    assert_no_difference 'Member.count' do
79
      xhr :post, :edit, :id => 2, :member => {:role_ids => [1], :user_id => 3}
80
    end
81
    assert_select_rjs :replace_html, 'tab-content-members'
82
    member = Member.find(2)
83
    assert_equal [1], member.role_ids
84
    assert_equal 3, member.user_id
85
  end
86

  
87
  def test_destroy
88
    assert_difference 'Member.count', -1 do
89
      post :destroy, :id => 2
90
    end
91
    assert_redirected_to '/projects/ecookbook/settings/members'
92
    assert !User.find(3).member_of?(Project.find(1))
93
  end
94

  
95
  def test_xhr_destroy
96
    assert_difference 'Member.count', -1 do
97
      xhr :post, :destroy, :id => 2
98
    end
99
    assert_select_rjs :replace_html, 'tab-content-members'
100
  end
101

  
102
  def test_autocomplete_for_member
103
    get :autocomplete_for_member, :id => 1, :q => 'mis'
104
    assert_response :success
105
    assert_template 'autocomplete_for_member'
106

  
107
    assert_tag :label, :content => /User Misc/,
108
                       :child => { :tag => 'input', :attributes => { :name => 'member[user_ids][]', :value => '8' } }
109
  end
110
end
.svn/pristine/21/21b08aea1ac3dbc27c974e37d3d3c4f6952cdffd.svn-base
1
# Redmine - project management software
2
# Copyright (C) 2006-2013  Jean-Philippe Lang
3
#
4
# This program is free software; you can redistribute it and/or
5
# modify it under the terms of the GNU General Public License
6
# as published by the Free Software Foundation; either version 2
7
# of the License, or (at your option) any later version.
8
#
9
# This program is distributed in the hope that it will be useful,
10
# but WITHOUT ANY WARRANTY; without even the implied warranty of
11
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
# GNU General Public License for more details.
13
#
14
# You should have received a copy of the GNU General Public License
15
# along with this program; if not, write to the Free Software
16
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
17

  
18
require 'blankslate'
19

  
20
module Redmine
21
  module Views
22
    module Builders
23
      class Structure < BlankSlate
24
        attr_accessor :request, :response
25

  
26
        def initialize(request, response)
27
          @struct = [{}]
28
          self.request = request
29
          self.response = response
30
        end
31

  
32
        def array(tag, options={}, &block)
33
          @struct << []
34
          block.call(self)
35
          ret = @struct.pop
36
          @struct.last[tag] = ret
37
          @struct.last.merge!(options) if options
38
        end
39

  
40
        def method_missing(sym, *args, &block)
41
          if args.any?
42
            if args.first.is_a?(Hash)
43
              if @struct.last.is_a?(Array)
44
                @struct.last << args.first unless block
45
              else
46
                @struct.last[sym] = args.first
47
              end
48
            else
49
              if @struct.last.is_a?(Array)
50
                if args.size == 1 && !block_given?
51
                  @struct.last << args.first
52
                else
53
                  @struct.last << (args.last || {}).merge(:value => args.first)
54
                end
55
              else
56
                @struct.last[sym] = args.first
57
              end
58
            end
59
          end
60

  
61
          if block
62
            @struct << (args.first.is_a?(Hash) ? args.first : {})
63
            block.call(self)
64
            ret = @struct.pop
65
            if @struct.last.is_a?(Array)
66
              @struct.last << ret
67
            else
68
              if @struct.last.has_key?(sym) && @struct.last[sym].is_a?(Hash)
69
                @struct.last[sym].merge! ret
70
              else
71
                @struct.last[sym] = ret
72
              end
73
            end
74
          end
75
        end
76

  
77
        def output
78
          raise "Need to implement #{self.class.name}#output"
79
        end
80
      end
81
    end
82
  end
83
end
.svn/pristine/21/21bb59308736cf64ef50e8df95a55241d5b3beeb.svn-base
1
<div class="contextual">
2
<%= link_to l(:label_user_new), new_user_path, :class => 'icon icon-add' %>
3
</div>
4

  
5
<h2><%=l(:label_user_plural)%></h2>
6

  
7
<% form_tag({}, :method => :get) do %>
8
<fieldset><legend><%= l(:label_filter_plural) %></legend>
9
<label for='status'><%= l(:field_status) %>:</label>
10
<%= select_tag 'status', users_status_options_for_select(@status), :class => "small", :onchange => "this.form.submit(); return false;"  %>
11

  
12
<% if @groups.present? %>
13
<label for='group_id'><%= l(:label_group) %>:</label>
14
<%= select_tag 'group_id', '<option></option>' + options_from_collection_for_select(@groups, :id, :name, params[:group_id].to_i), :onchange => "this.form.submit(); return false;"  %>
15
<% end %>
16

  
17
<label for='name'><%= l(:label_user) %>:</label>
18
<%= text_field_tag 'name', params[:name], :size => 30 %>
19
<%= submit_tag l(:button_apply), :class => "small", :name => nil %>
20
<%= link_to l(:button_clear), users_path, :class => 'icon icon-reload' %>
21
</fieldset>
22
<% end %>
23
&nbsp;
24

  
25
<div class="autoscroll">
26
<table class="list">
27
  <thead><tr>
28
  <%= sort_header_tag('login', :caption => l(:field_login)) %>
29
  <%= sort_header_tag('firstname', :caption => l(:field_firstname)) %>
30
  <%= sort_header_tag('lastname', :caption => l(:field_lastname)) %>
31
  <%= sort_header_tag('mail', :caption => l(:field_mail)) %>
32
  <%= sort_header_tag('admin', :caption => l(:field_admin), :default_order => 'desc') %>
33
  <%= sort_header_tag('created_on', :caption => l(:field_created_on), :default_order => 'desc') %>
34
  <%= sort_header_tag('last_login_on', :caption => l(:field_last_login_on), :default_order => 'desc') %>
35
    <th></th>
36
  </tr></thead>
37
  <tbody>
38
<% for user in @users -%>
39
  <tr class="user <%= cycle("odd", "even") %> <%= %w(anon active registered locked)[user.status] %>">
40
  <td class="username"><%= avatar(user, :size => "14") %><%= link_to h(user.login), edit_user_path(user) %></td>
41
  <td class="firstname"><%= h(user.firstname) %></td>
42
  <td class="lastname"><%= h(user.lastname) %></td>
43
  <td class="email"><%= mail_to(h(user.mail)) %></td>
44
  <td align="center"><%= checked_image user.admin? %></td>
45
  <td class="created_on" align="center"><%= format_time(user.created_on) %></td>
46
  <td class="last_login_on" align="center"><%= format_time(user.last_login_on) unless user.last_login_on.nil? %></td>
47
    <td class="buttons">
48
      <%= change_status_link(user) %>
49
      <%= link_to(l(:button_delete), user, :confirm => l(:text_are_you_sure), :method => :delete, :class => 'icon icon-del') unless User.current == user %>
50
    </td>
51
  </tr>
52
<% end -%>
53
  </tbody>
54
</table>
55
</div>
56
<p class="pagination"><%= pagination_links_full @user_pages, @user_count %></p>
57

  
58
<% html_title(l(:label_user_plural)) -%>
.svn/pristine/21/21e12c0e1e71e0c4f94a4c58d91a04399075123a.svn-base
1
# Settings specified here will take precedence over those in config/environment.rb
2

  
3
# The production environment is meant for finished, "live" apps.
4
# Code is not reloaded between requests
5
config.cache_classes = true
6

  
7
# Use a different logger for distributed setups
8
# config.logger        = SyslogLogger.new
9
config.log_level = :info
10

  
11
# Full error reports are disabled and caching is turned on
12
config.action_controller.consider_all_requests_local = false
13
config.action_controller.perform_caching             = true
14

  
15
# Enable serving of images, stylesheets, and javascripts from an asset server
16
# config.action_controller.asset_host                  = "http://assets.example.com"
17

  
18
# Disable mail delivery
19
config.action_mailer.perform_deliveries = false
20
config.action_mailer.raise_delivery_errors = false
21

  
.svn/pristine/21/21f67f445a6c5a2512b4712ac66209391d37efdc.svn-base
1
# Redmine - project management software
2
# Copyright (C) 2006-2011  Jean-Philippe Lang
3
#
4
# This program is free software; you can redistribute it and/or
5
# modify it under the terms of the GNU General Public License
6
# as published by the Free Software Foundation; either version 2
7
# of the License, or (at your option) any later version.
8
#
9
# This program is distributed in the hope that it will be useful,
10
# but WITHOUT ANY WARRANTY; without even the implied warranty of
11
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
# GNU General Public License for more details.
13
#
14
# You should have received a copy of the GNU General Public License
15
# along with this program; if not, write to the Free Software
16
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
17

  
18
require 'redmine/scm/adapters/abstract_adapter'
19
require 'rexml/document'
20

  
21
module Redmine
22
  module Scm
23
    module Adapters
24
      class DarcsAdapter < AbstractAdapter
25
        # Darcs executable name
26
        DARCS_BIN = Redmine::Configuration['scm_darcs_command'] || "darcs"
27

  
28
        class << self
29
          def client_command
30
            @@bin    ||= DARCS_BIN
31
          end
32

  
33
          def sq_bin
34
            @@sq_bin ||= shell_quote_command
35
          end
36

  
37
          def client_version
38
            @@client_version ||= (darcs_binary_version || [])
39
          end
40

  
41
          def client_available
42
            !client_version.empty?
43
          end
44

  
45
          def darcs_binary_version
46
            darcsversion = darcs_binary_version_from_command_line.dup
47
            if darcsversion.respond_to?(:force_encoding)
48
              darcsversion.force_encoding('ASCII-8BIT')
49
            end
50
            if m = darcsversion.match(%r{\A(.*?)((\d+\.)+\d+)})
51
              m[2].scan(%r{\d+}).collect(&:to_i)
52
            end
53
          end
54

  
55
          def darcs_binary_version_from_command_line
56
            shellout("#{sq_bin} --version") { |io| io.read }.to_s
57
          end
58
        end
59

  
60
        def initialize(url, root_url=nil, login=nil, password=nil,
61
                       path_encoding=nil)
62
          @url = url
63
          @root_url = url
64
        end
65

  
66
        def supports_cat?
67
          # cat supported in darcs 2.0.0 and higher
68
          self.class.client_version_above?([2, 0, 0])
69
        end
70

  
71
        # Get info about the darcs repository
72
        def info
73
          rev = revisions(nil,nil,nil,{:limit => 1})
74
          rev ? Info.new({:root_url => @url, :lastrev => rev.last}) : nil
75
        end
76

  
77
        # Returns an Entries collection
78
        # or nil if the given path doesn't exist in the repository
79
        def entries(path=nil, identifier=nil, options={})
80
          path_prefix = (path.blank? ? '' : "#{path}/")
81
          if path.blank?
82
            path = ( self.class.client_version_above?([2, 2, 0]) ? @url : '.' )
83
          end
84
          entries = Entries.new
85
          cmd = "#{self.class.sq_bin} annotate --repodir #{shell_quote @url} --xml-output"
86
          cmd << " --match #{shell_quote("hash #{identifier}")}" if identifier
87
          cmd << " #{shell_quote path}"
88
          shellout(cmd) do |io|
89
            begin
90
              doc = REXML::Document.new(io)
91
              if doc.root.name == 'directory'
92
                doc.elements.each('directory/*') do |element|
93
                  next unless ['file', 'directory'].include? element.name
94
                  entries << entry_from_xml(element, path_prefix)
95
                end
96
              elsif doc.root.name == 'file'
97
                entries << entry_from_xml(doc.root, path_prefix)
98
              end
99
            rescue
100
            end
101
          end
102
          return nil if $? && $?.exitstatus != 0
103
          entries.compact.sort_by_name
104
        end
105

  
106
        def revisions(path=nil, identifier_from=nil, identifier_to=nil, options={})
107
          path = '.' if path.blank?
108
          revisions = Revisions.new
109
          cmd = "#{self.class.sq_bin} changes --repodir #{shell_quote @url} --xml-output"
110
          cmd << " --from-match #{shell_quote("hash #{identifier_from}")}" if identifier_from
111
          cmd << " --last #{options[:limit].to_i}" if options[:limit]
112
          shellout(cmd) do |io|
113
            begin
114
              doc = REXML::Document.new(io)
115
              doc.elements.each("changelog/patch") do |patch|
116
                message = patch.elements['name'].text
117
                message << "\n" + patch.elements['comment'].text.gsub(/\*\*\*END OF DESCRIPTION\*\*\*.*\z/m, '') if patch.elements['comment']
118
                revisions << Revision.new({:identifier => nil,
119
                              :author => patch.attributes['author'],
120
                              :scmid => patch.attributes['hash'],
121
                              :time => Time.parse(patch.attributes['local_date']),
122
                              :message => message,
123
                              :paths => (options[:with_path] ? get_paths_for_patch(patch.attributes['hash']) : nil)
124
                            })
125
              end
126
            rescue
127
            end
128
          end
129
          return nil if $? && $?.exitstatus != 0
130
          revisions
131
        end
132

  
133
        def diff(path, identifier_from, identifier_to=nil)
134
          path = '*' if path.blank?
135
          cmd = "#{self.class.sq_bin} diff --repodir #{shell_quote @url}"
136
          if identifier_to.nil?
137
            cmd << " --match #{shell_quote("hash #{identifier_from}")}"
138
          else
139
            cmd << " --to-match #{shell_quote("hash #{identifier_from}")}"
140
            cmd << " --from-match #{shell_quote("hash #{identifier_to}")}"
141
          end
142
          cmd << " -u #{shell_quote path}"
143
          diff = []
144
          shellout(cmd) do |io|
145
            io.each_line do |line|
146
              diff << line
147
            end
148
          end
149
          return nil if $? && $?.exitstatus != 0
150
          diff
151
        end
152

  
153
        def cat(path, identifier=nil)
154
          cmd = "#{self.class.sq_bin} show content --repodir #{shell_quote @url}"
155
          cmd << " --match #{shell_quote("hash #{identifier}")}" if identifier
156
          cmd << " #{shell_quote path}"
157
          cat = nil
158
          shellout(cmd) do |io|
159
            io.binmode
160
            cat = io.read
161
          end
162
          return nil if $? && $?.exitstatus != 0
163
          cat
164
        end
165

  
166
        private
167

  
168
        # Returns an Entry from the given XML element
169
        # or nil if the entry was deleted
170
        def entry_from_xml(element, path_prefix)
171
          modified_element = element.elements['modified']
172
          if modified_element.elements['modified_how'].text.match(/removed/)
173
            return nil
174
          end
175

  
176
          Entry.new({:name => element.attributes['name'],
177
                     :path => path_prefix + element.attributes['name'],
178
                     :kind => element.name == 'file' ? 'file' : 'dir',
179
                     :size => nil,
180
                     :lastrev => Revision.new({
181
                       :identifier => nil,
182
                       :scmid => modified_element.elements['patch'].attributes['hash']
183
                       })
184
                     })
185
        end
186

  
187
        def get_paths_for_patch(hash)
188
          paths = get_paths_for_patch_raw(hash)
189
          if self.class.client_version_above?([2, 4])
190
            orig_paths = paths
191
            paths = []
192
            add_paths = []
193
            add_paths_name = []
194
            mod_paths = []
195
            other_paths = []
196
            orig_paths.each do |path|
197
              if path[:action] == 'A'
198
                add_paths << path
199
                add_paths_name << path[:path]
200
              elsif path[:action] == 'M'
201
                mod_paths << path
202
              else
203
                other_paths << path
204
              end
205
            end
206
            add_paths_name.each do |add_path|
207
              mod_paths.delete_if { |m| m[:path] == add_path }
208
            end
209
            paths.concat add_paths
210
            paths.concat mod_paths
211
            paths.concat other_paths
212
          end
213
          paths
214
        end
215

  
216
        # Retrieve changed paths for a single patch
217
        def get_paths_for_patch_raw(hash)
218
          cmd = "#{self.class.sq_bin} annotate --repodir #{shell_quote @url} --summary --xml-output"
219
          cmd << " --match #{shell_quote("hash #{hash}")} "
220
          paths = []
221
          shellout(cmd) do |io|
222
            begin
223
              # Darcs xml output has multiple root elements in this case (tested with darcs 1.0.7)
224
              # A root element is added so that REXML doesn't raise an error
225
              doc = REXML::Document.new("<fake_root>" + io.read + "</fake_root>")
226
              doc.elements.each('fake_root/summary/*') do |modif|
227
                paths << {:action => modif.name[0,1].upcase,
228
                          :path => "/" + modif.text.chomp.gsub(/^\s*/, '')
229
                         }
230
              end
231
            rescue
232
            end
233
          end
234
          paths
235
        rescue CommandFailed
236
          paths
237
        end
238
      end
239
    end
240
  end
241
end

Also available in: Unified diff