|
Server : Apache/2.4.62 System : FreeBSD fbsdweb2.web.rcn.net 14.1-RELEASE FreeBSD 14.1-RELEASE releng/14.1-n267679-10e31f0946d8 GENERIC amd64 User : www ( 80) PHP Version : 8.3.8 Disable Function : NONE Directory : /domains/compasssysweb/calendar/CalciumDir39/Calendar/ |
Upload File : |
# Copyright 1999-2003, Fred Steinberg, Brown Bear Software
package ListView;
use strict;
use CGI qw (:standard *table);
use Calendar::Event;
use Calendar::Preferences;
# A List View is a table with 4 columns: Date, Day of Week Name, Event
# Text, Popup Text
# Pretty ding-dang simple.
# Now we also support 'Condensed' mode, in which a row isn't displayed
# unless there is an event in it.
# And now there is 'Approval' mode, which is condensed mode + more controls
# The constructor expects a start date and an end date, which are usually
# the 1st and last of a month, but don't have to be.
sub new {
my $class = shift;
my ($operation, $startDate, $endDate, $params) = @_;
my $self = {};
bless $self, $class;
my $calName = $operation->calendarName;
my $db = $operation->db;
my $prefs = $operation->prefs;
my $i18n = $operation->I18N;
my $uname = $operation->getUsername;
my $addPerm = $operation->permission->permitted ($uname, 'Add');
my $editPerm = $operation->permission->permitted ($uname, 'Edit');
my ($amount, $navBar, $type) = $operation->ParseDisplaySpecs;
my $mode = $params->{mode} || '';
my $isApprovalMode = ($mode eq 'Approval');
undef $isApprovalMode unless $editPerm;
my $isCondensed = $isApprovalMode || $type =~ /condensed/i;
my ($filterCategories,
$filterText, $filterIn) = $operation->ParseFilterSpecs;
my $searchMode;
if (defined $filterText) {
# Here's an EXTREMELY gross hack to see if we want the day links to
# preserve the filter. Yucko! Fix this one day.
$searchMode++ if ((caller())[1] =~ /SearchPerform.pm/);
}
# Stick the javascript code we'll need in
my $html = Javascript->PopupWindow ($operation);
# Store some stuff so we can get if from other methods
($self->{eventFace}, $self->{eventSize}) = $prefs->font ('ListEvent');
($self->{timeFace}, $self->{timeSize}) = $prefs->font ('ListEventTime');
($self->{incFace}, $self->{incSize}) = $prefs->font ('ListInclude');
($self->{catFace}, $self->{catSize}) = $prefs->font ('ListCategory');
($self->{popFace}, $self->{popSize}) = $prefs->font ('PopupText');
$self->{escapeIt} = $prefs->EventHTML =~ /none/;
my $showPopup = $prefs->ListViewPopup;
$html .= startform (-name => 'ApprovalForm') if ($isApprovalMode);
# my $border = ($prefs->inBWPrintMode ? 1 : 0);
my $border = ($prefs->PrintPrefs ? 1 : 0);
# First, create the open table def
$html .= '<center>';
$html .= "<table width='100%' border=$border cellspacing=1 cellpadding=1>";
# Need to support CGI 2.42, can't use start_*
# $html .= start_table ({-border => 0,
# -cellspacing => 1, -cellpadding => 1});
# Then, for each day, add a row. Each row can have many 'sub-rows',
# since there may be > 1 event per day.
# Get a hash of list of events which apply in this date range, or all
# tentative events if in approval mode.
my $eventHash;
if ($isApprovalMode) {
$eventHash = $db->getTentativeEvents;
my @dates = sort map {sprintf "%4s/%02s/%02s", split '/'}
keys %$eventHash;
if (@dates) {
$startDate = Date->new ($dates[0]);
$endDate = Date->new ($dates[-1]);
}
} else {
$eventHash = $db->getEventDateHash ($startDate, $endDate, $prefs);
}
my ($event, $numEvents, @events);
my ($dateFG, $dateBG) = ($prefs->color ('ListViewDateFG', 'some')
|| 'black',
$prefs->color ('ListViewDateBG', 'some'));
my ($dayFG, $dayBG) = ($prefs->color ('ListViewDayFG', 'some')
|| 'black',
$prefs->color ('ListViewDayBG', 'some'));
my ($eventFG, $eventBG) = ($prefs->color ('ListViewEventFG') || 'black',
$prefs->color ('ListViewEventBG'));
my ($popupFG, $popupBG) = ($prefs->color ('ListViewPopupFG') || 'black',
$prefs->color ('ListViewPopupBG'));
my ($dateFace, $dateSize) = $prefs->font ('ListDate');
my ($dayFace, $daySize) = $prefs->font ('ListDay');
my $showWeekend = $prefs->ShowWeekend;
$showWeekend ||= ($isCondensed or $startDate == $endDate);
my $showWeekNum = $prefs->ShowWeekNums;
my $whichWeekNum = $prefs->WhichWeekNums;
my $startWeekOn = $prefs->StartWeekOn;
my $printedSomething;
my $sortBy = $prefs->EventSorting;
my $previousDate = $startDate;
for (my $date = $startDate; $date <= $endDate; $date++) {
next unless ($showWeekend or $date->dayOfWeek < 6);
# If we care about weeknums, see if this gets one.
my $weekNum;
$weekNum = $date->weekNumber ($whichWeekNum, $startWeekOn)
if ($showWeekNum && ($date->dayOfWeek == $startWeekOn));
my $listRef = $eventHash->{"$date"};
my @unsortedEvents = $listRef ? @$listRef : ();
if ($isApprovalMode) {
@unsortedEvents = grep {$_->isTentative} @unsortedEvents;
} else {
# Eliminate Tentative events we don't have Edit perm for
# op is a ShowIt
@unsortedEvents = $operation->removeTentatives (\@unsortedEvents);
}
# sort events, based on sort pref
my @events = Event->sort (\@unsortedEvents, $sortBy);
if (@events && (defined $filterText or $filterCategories)) {
my @filteredEvents;
foreach (@events) {
next if ($filterCategories and
!$_->inCategory ($filterCategories));
next if (defined $filterText and
!$_->matchesText ($filterText, $filterIn));
push @filteredEvents, $_;
}
@events = @filteredEvents;
}
$numEvents = @events;
next if (!$numEvents && $isCondensed);
$printedSomething ||= 1;
$event = shift @events;
my $url;
if ($addPerm) {
if ($searchMode) {
$url = $operation->makeURL ({Op => 'ShowDay',
NavType => undef,
TextFilter => undef,
FilterIn => undef,
IgnoreCase => undef,
UseRegex => undef,
FilterCategories => undef,
Type => undef,
Date => $date});
} else {
$url = $operation->makeURL ({Op => 'ShowDay',
Date => $date});
}
}
my $dateString = $date->pretty ($i18n, 'abbrev');
if ($searchMode or $isApprovalMode) {
$dateString .= ', ' . $date->year;
}
my $dateHTML = font ({-face => $dateFace,
-size => $dateSize,
-color => $dateFG}, $dateString);
if ($addPerm) {
$dateHTML = "<a href='$url'>" . $dateHTML . "</a>";
}
$dateHTML .= font ({-face => $dateFace,
-size => ($dateSize || 0) - 1,
-color => $dateFG},
" [$weekNum]") if defined ($weekNum);
my %dateVals = (-width => '5%',
# -valign => 'top',
-rowspan => $numEvents,
-nowrap => 1);
$dateVals{-bgcolor} = $dateBG if $dateBG;
my %dayVals = (-width => '5%',
-align => 'center',
-rowspan => $numEvents);
$dayVals{-bgcolor} = $dayBG if $dayBG;
my $popupData = '';
if ($showPopup) {
$popupData = $self->_eventPopupTableData ($event, $popupFG,
$popupBG);
}
my $isFiscal = $date->isa ('Date::Fiscal');
my $dayNum = '';
if ($isFiscal) {
$dayNum = td (\%dayVals,
font ({-face => $dayFace, size => $daySize,
-color => $dayFG}, $date->dayNumber));
}
# If first of the month, add a space
if ($date->month != $previousDate->month) {
$html .= Tr (td (' '));
}
# Columns: Date, DayOfWeek, FiscalDay (if fiscal), Text, Popup
$html .= Tr ($isApprovalMode ? approvalStuff ($event, $i18n) : '',
td (\%dateVals,
$dateHTML),
td (\%dayVals,
font ({-face => $dayFace, size => $daySize,
-color => $dayFG},
$i18n->get ($date->dayName ('abbrev')))),
$dayNum,
$self->_eventTextTableData ($calName, $event, $date,
$prefs, $i18n,
$eventFG, $eventBG),
$popupData);
# Do the rest of the events for this day
foreach (@events) {
my $popupData = '';
if ($showPopup) {
$popupData = $self->_eventPopupTableData ($_, $popupFG,
$popupBG);
}
$html .= Tr ($isApprovalMode ? approvalStuff ($_, $i18n) : '',
$self->_eventTextTableData ($calName, $_, $date,
$prefs, $i18n,
$eventFG, $eventBG),
$popupData);
}
$previousDate = $date;
}
sub approvalStuff {
my ($event, $i18n) = @_;
my @values = qw /approve delete pending/;
my %labels = (approve => $i18n->get ('Approve'),
delete => $i18n->get ('Delete'),
pending => $i18n->get ('Pending'),
);
my @tds;
push @tds, td ({-bgcolor => 'gray'},
popup_menu (-name => 'Approve-' . $event->id,
-default => 'pending',
-values => \@values,
-labels => \%labels));
my @notes;
push @notes, $event->owner if defined $event->owner;
push @notes, $event->category if defined $event->category;
push @notes, $i18n->get ('Repeating') if $event->isRepeating;
push @notes, ' ' unless @notes;
push @tds, td ({-bgcolor => 'gray'},
font ({-size => "-1", -color => "darkred"},
join '<br>', @notes));
@tds;
}
# $html .= end_table();
$html .= '</table></center>';
if ($isApprovalMode and $printedSomething) {
$html .= <<END_SCRIPT;
<SCRIPT LANGUAGE="JavaScript">
<!--
function SetAll (index) {
theform=document.ApprovalForm;
for (i=0; i<theform.elements.length; i++) {
if (theform.elements[i].type=='select-one') {
theform.elements[i].selectedIndex=index;
}
}
}
//-->
</SCRIPT>
END_SCRIPT
my $f = {-size => -1, -color => 'black'};
$html .= table (Tr (td (font ($f, $i18n->get ("Set all to: "))),
td (a ({-href => "javascript:SetAll(0)"},
font ($f, $i18n->get ('Approve')))),
td (a ({-href => "javascript:SetAll(1)"},
font ($f, $i18n->get ('Delete')))),
td (a ({-href => "javascript:SetAll(2)"},
font ($f, $i18n->get ('Pending'))))));
$html .= '<font color="black">';
$html .= '<br><center>';
my $label = $i18n->get (' Approve / Delete ');
$html .= submit (-name => 'ApproveIt', -value => $label);
$html .= '</center></font>';
$html .= hidden (-name => 'Op',
-override => 1,
-value => 'ApproveEvents');
$html .= hidden (-name => 'CalendarName', -value => $calName);
$html .= endform;
}
if (!$printedSomething) {
if (!$isApprovalMode) {
my $start = $searchMode ? 'Search Results' : 'Condensed Mode';
$html .= h3 ({-align => 'center'},
$i18n->get ($start) . ': ' .
$i18n->get ('There were no events found in the ' .
'specified date range'));
} else {
$html .= h3 ({-align => 'center'},
$i18n->get ('There are no events pending approval' .
' for this calendar.'));
}
}
if ($isApprovalMode) {
$html .= p (' ',
a ({-href => $operation->makeURL ({Op => 'ShowIt'})},
'Return to the Calendar'));
}
$self->{'html'} = $html;
$self;
}
sub _eventTextTableData {
my $self = shift;
my ($calName, $event, $date, $prefs, $i18n, $fg, $bg) = (@_);
my ($fgColor, $bgColor, $border, $textID);
if ($event) {
if ($event->includedFrom || '' ne $calName) {
($fgColor, $bgColor, $border, $textID) =
$event->getIncludedOverrides ($prefs->Includes);
}
my $thisOnesBG = $event->bgColor;
my $thisOnesFG = $event->fgColor;
if ((!$fgColor || !$bgColor) && $event->category) {
($fgColor, $bgColor, $border) =
$event->getCategoryOverrides ($prefs,
MasterDB->new->getPreferences);
$fgColor = $thisOnesFG if $thisOnesFG;
$bgColor = $thisOnesBG if $thisOnesBG;
}
$bgColor ||= $thisOnesBG;
$fgColor ||= $thisOnesFG;
}
$fgColor ||= $fg;
$bgColor ||= $bg;
if ($prefs->inPrintMode ('none')) { # use colors for 'some'
$fgColor = 'black';
$bgColor = 'white';
}
my $td;
if ($event) {
my %eventSettings = (calName => $calName,
date => $date,
prefs => $prefs,
i18n => $i18n,
textID => $textID,
textFG => $fgColor,
eventFace => $self->{eventFace},
eventSize => $self->{eventSize},
timeFace => $self->{timeFace},
timeSize => $self->{timeSize},
categoryFace => $self->{catFace},
categorySize => $self->{catSize},
includedFace => $self->{incFace},
includedSize => $self->{incSize});
$td = $event->getHTML (\%eventSettings) || ' '
} else {
$td = ' ';
}
my %vals = (-width => '25%');
$vals{-bgcolor} = $bgColor if $bgColor;
my $stuff = td (\%vals, $td);
$stuff;
}
sub _eventPopupTableData {
my $self = shift;
my ($event, $fg, $bg) = (@_);
my $escapeIt = $self->{escapeIt};
my $popup;
if ($event) {
$popup = $event->escapedPopup ($escapeIt, 'dohrefs') || $event->link
unless ($event->includedFrom and !$event->public);
}
my %vals = (-width => '65%');
$vals{-bgcolor} = $bg if $bg;
my %fontSettings = (color => $fg);
$fontSettings{face} = $self->{popFace} if defined $self->{popFace};
$fontSettings{size} = $self->{popSize} if defined $self->{popSize};
my $stuff = td (\%vals,
$popup ? font (\%fontSettings, $popup) : ' ');
$stuff;
}
sub getHTML {
my $self = shift;
$self->{'html'};
}
1;