Exemple #1
0
class Calendar(FocusPanel):
    def __init__(self, **kwargs):
        FocusPanel.__init__(self, **kwargs)
        self.monthsOfYear = ['Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec']
        self.daysOfWeek = ['S','M','T','W','T','F','S']
        yr,mth,day = time.strftime("%Y-%m-%d").split("-")
        self.todayYear = int(yr)
        self.todayMonth = int(mth)  # change to offset 0 as per javascript
        self.todayDay = int(day)

        self.currentMonth = self.todayMonth
        self.currentYear = self.todayYear
        self.currentDay = self.todayDay

        self.selectedDateListeners = []

        self.defaultGrid = None # used later

        return

    def addSelectedDateListener(self,listener):
        self.selectedDateListeners.append(listener)

    def removeSelectedDateListener(self,listener):
        self.selectedDateListeners.remove(listener)

    def isLeapYear(self,year):
        if (year % 4 == 0 and year % 100 != 0) or ( year % 400 == 0):
            return True
        else:
            return False

    def getDaysInMonth(self,mth,year):
        days = 0
        if (mth == 1 or mth == 3 or mth == 5 or mth == 7 or mth == 8 or mth == 10 or mth == 12): # in (1,3,5,7,8,10,12):
            days=31
        elif mth == 4 or mth == 6 or mth == 8 or mth == 11: #in (4,6,8,11):
            days = 30
        elif (mth==2 and self.isLeapYear(year)):
            days = 29
        else:
            days = 28
        return days

    def setPosition(self, left, top):
        element = self.getElement()
        DOM.setStyleAttribute(element, "left", "%dpx" % left)
        DOM.setStyleAttribute(element, "top", "%dpx" % top)

    def show(self, left, top):
        if left < 0:
            left = 0
        if top < 0:
            top = 0
        self.setPosition(left,top)
        self.drawCurrent()
        self.setVisible(True)

    def drawCurrent(self):
        yr,mth,day = time.strftime("%Y-%m-%d").split("-")
        self.draw( int(mth), int(yr) )

    def draw(self, month , year):
        tod = time.localtime()
        mm = tod.tm_mon
        yy = tod.tm_year
        # has today changed and thus changed month? cater to rare case where widget in created on last day of month &
        # page left till next day
        hasChangeMonth = False
        if yy <> self.todayYear or mm <> self.todayMonth:
            hasChangeMonth = True
            self.todayYear = yy
            self.todayMonth = mm

        # check to see if we have drawn the full widget before
        if self.defaultGrid is None:
            self.drawFull(month,year)
        else:
            # ok means we are re-drawing, but first check if it is the same as the defaultGrid, if yes, just use it
            if not hasChangeMonth and month == self.todayMonth and year == self.todayYear:
                self.middlePanel.setWidget(self.defaultGrid)
                self.currentMonth = self.todayMonth
                self.currentYear = self.todayYear
            else:
                # we have to redraw the grid -- bah
                g = self.drawGrid(month,year)

                if hasChangeMonth:
                    self.defaultGrid = grid # reset the default grid as we have changed months

            #
            # what about the title panel?
            #
            self.titlePanel.setWidget(HTML("<b>" + self.monthsOfYear[month-1] + " " + str(year) + "</b>" ) )
            self.setVisible(True)

        return

    def drawFull(self, month, year):
        # should be called only once when we draw the calendar for the first time
        #
        self.vp = VerticalPanel()
        self.vp.setSpacing(2)
        self.vp.addStyleName("calendarbox calendar-module calendar")
        self.setWidget(self.vp)
        self.setVisible(False)
        #
        mth = int(month)
        yr = int(year)

        tp = HorizontalPanel()
        tp.addStyleName("calendar-top-panel")
        tp.setSpacing(5)

        h1 = Hyperlink('<<')
        h1.addClickListener( getattr(self,'onPreviousYear') )
        h2 = Hyperlink('<')
        h2.addClickListener( getattr(self,'onPreviousMonth') )
        h4 = Hyperlink('>')
        h4.addClickListener( getattr(self,'onNextMonth') )
        h5 = Hyperlink('>>')
        h5.addClickListener( getattr(self,'onNextYear') )

        tp.add(h1)
        tp.add(h2)

        # titlePanel can be changed, whenever we draw, so keep the reference

        self.titlePanel = SimplePanel()
        self.titlePanel.setWidget(HTML("<b>" + self.monthsOfYear[mth-1] + " " + str(yr) + "</b>" ) )
        self.titlePanel.setStyleName("calendar-center")

        tp.add( self.titlePanel )
        tp.add(h4)
        tp.add(h5)
        tvp = VerticalPanel()
        tvp.setSpacing(10)
        tvp.add(tp)

        self.vp.add(tvp)

        # done with top panel

        self.middlePanel = SimplePanel()
        grid = self.drawGrid(mth,yr)
        self.middlePanel.setWidget(grid)
        self.vp.add(self.middlePanel)
        self.defaultGrid = grid
        #
        # some links & handlers
        #
        bh1 = Hyperlink('Yesterday')
        bh1.addClickListener( getattr(self,'onYesterday') )
        bh2 = Hyperlink('Today')
        bh2.addClickListener( getattr(self,'onToday') )
        bh3 = Hyperlink('Tomorrow')
        bh3.addClickListener( getattr(self,'onTomorrow') )
        bh4 = Hyperlink('Cancel')
        bh4.addClickListener( getattr(self,'onCancel') )
        #
        # add code to test another way of doing the layout
        #
        b = HorizontalPanel()
        b.add(bh1)
        b.add(bh2)
        b.add(bh3)
        b.addStyleName("calendar-shortcuts")
        self.vp.add(b)
        b2 = SimplePanel()
        b2.add(bh4)
        b2.addStyleName("calendar-cancel")
        self.vp.add(b2)

        self.setVisible(True)
        return

    def drawGrid(self,month,year):
        # draw the grid in the middle of the calendar

        daysInMonth = self.getDaysInMonth(month, year)
        secs = time.mktime( (year,month,1,0,0,0,0,0,-1) ) # first day of the month & year
        struct = time.localtime(secs)
        startPos = (struct.tm_wday + 1 ) % 7 # 0 - sunday for our needs instead 0 = monday in tm_wday
        slots = startPos + daysInMonth - 1
        rows = int(slots/7) + 1
        grid = Grid(rows+1, 7) # extra row for the days in the week
        grid.setWidth("100%")
        grid.addTableListener(self)
        self.middlePanel.setWidget(grid)
        #
        # put some content into the grid cells
        #
        for i in range(7):
            grid.setText(0, i, self.daysOfWeek[i] )
            grid.cellFormatter.addStyleName(0,i,"calendar-header")
        #
        # draw cells which are empty first
        #
        day =0
        pos = 0
        while pos < startPos:
            grid.setText(1, pos , " ")
            grid.cellFormatter.setStyleAttr(1,pos,"background","#f3f3f3")
            grid.cellFormatter.addStyleName(1,pos,"calendar-blank-cell")
            pos += 1
        # now for days of the month
        row = 1
        day = 1
        col = startPos
        while day <= daysInMonth:
            if pos % 7 == 0 and day <> 1:
                row += 1
            col = pos % 7
            grid.setText(row,col, str(day) )
            if self.currentYear == self.todayYear and self.currentMonth == self.todayMonth and day == self.todayDay:
                grid.cellFormatter.addStyleName(row,col,"calendar-cell-today")
            else:
                grid.cellFormatter.addStyleName(row,col,"calendar-day-cell")
            day += 1
            pos += 1
        #
        # now blank lines on the last row
        #
        col += 1
        while col < 7:
            grid.setText(row,col," ")
            grid.cellFormatter.setStyleAttr(row,col,"background","#f3f3f3")
            grid.cellFormatter.addStyleName(row,col,"calendar-blank-cell")
            col += 1

        return grid

    def onCellClicked(self, grid, row, col):
        if row == 0:
            return
        text = grid.getText(row, col)
        if text == "":
            return
        selectedDay = int(text)
        # well if anyone is listening to the listener, fire that event
        for listener in self.selectedDateListeners:
            if hasattr(listener, "onDateSelected"):
                listener.onDateSelected(self.currentYear, self.currentMonth,
                                        selectedDay)
            else:
                listener(self.currentYear, self.currentMonth, selectedDay)
        self.setVisible(False)


    def onPreviousYear(self,event):
        self.drawPreviousYear()

    def onPreviousMonth(self,event):
        self.drawPreviousMonth()

    def onNextMonth(self,event):
        self.drawNextMonth()

    def onNextYear(self,event):
        self.drawNextYear()

    def onDate(self, event, yy, mm, dd):
        for listener in self.selectedDateListeners:
            if hasattr(listener, "onDateSelected"):
                listener.onDateSelected(yy,mm,dd)
            else:
                listener(yy,mm,dd)
        self.setVisible(False)

    def onYesterday(self,event):
        yesterday = time.localtime(time.time() - 3600 * 24)
        mm = yesterday.tm_mon
        dd = yesterday.tm_mday
        yy = yesterday.tm_year
        self.onDate(event, yy, mm, dd)

    def onToday(self,event):
        tod = time.localtime()
        mm = tod.tm_mon
        dd = tod.tm_mday
        yy = tod.tm_year
        self.onDate(event, yy, mm, dd)

    def onTomorrow(self,event):
        tom = time.localtime(time.time() + 3600 * 24)
        mm = tom.tm_mon
        dd = tom.tm_mday
        yy = tom.tm_year
        self.onDate(event, yy, mm, dd)

    def onCancel(self,event):
        self.setVisible(False)

    def drawCurrent(self):
        yr,mth,day = time.strftime("%Y-%m-%d").split("-")
        self.draw( int(mth), int(yr) )

    def drawDate(self, month, year ):
        # if year == self.currentYear and month == self.currentYear():
            # self.drawCurrent()
        self.currentMonth = month
        self.currentYear = year
        self.draw(self.currentMonth, self.currentYear)

    def drawPreviousMonth(self):
        if int(self.currentMonth) == 1:
            self.currentMonth = 12
            self.currentYear = int(self.currentYear) - 1
        else:
            self.currentMonth = int(self.currentMonth) - 1
        self.draw(self.currentMonth, self.currentYear)

    def drawNextMonth(self):
        if int(self.currentMonth) == 12:
            self.currentMonth = 1
            self.currentYear = int(self.currentYear) + 1
        else:
            self.currentMonth = int(self.currentMonth) + 1
        self.draw(self.currentMonth, self.currentYear)

    def drawPreviousYear(self):
        self.currentYear = int(self.currentYear) - 1
        self.draw(self.currentMonth, self.currentYear)

    def drawNextYear(self):
        self.currentYear = int(self.currentYear) + 1
        self.draw(self.currentMonth, self.currentYear)
Exemple #2
0
class Calendar(FocusPanel):
    monthsOfYear = [
        'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct',
        'Nov', 'Dec'
    ]
    daysOfWeek = ['S', 'M', 'T', 'W', 'T', 'F', 'S']
    today = 'Today'
    tomorrow = 'Tomorrow'
    yesterday = 'Yesterday'
    cancel = 'Cancel'

    def __init__(self, **kwargs):
        FocusPanel.__init__(self, **kwargs)
        yr, mth, day = time.strftime("%Y-%m-%d").split("-")
        self.todayYear = int(yr)
        self.todayMonth = int(mth)  # change to offset 0 as per javascript
        self.todayDay = int(day)

        self.currentMonth = self.todayMonth
        self.currentYear = self.todayYear
        self.currentDay = self.todayDay

        self.selectedDateListeners = []

        self.defaultGrid = None  # used later

        return

    def getMonthsOfYear(self):
        return self.monthsOfYear

    def getDaysOfWeek(self):
        return self.daysOfWeek

    def addSelectedDateListener(self, listener):
        self.selectedDateListeners.append(listener)

    def removeSelectedDateListener(self, listener):
        self.selectedDateListeners.remove(listener)

    def isLeapYear(self, year):
        if (year % 4 == 0 and year % 100 != 0) or (year % 400 == 0):
            return True
        else:
            return False

    def getDaysInMonth(self, mth, year):
        days = 0
        if (mth == 1 or mth == 3 or mth == 5 or mth == 7 or mth == 8
                or mth == 10 or mth == 12):  # in (1,3,5,7,8,10,12):
            days = 31
        elif mth == 4 or mth == 6 or mth == 8 or mth == 11:  #in (4,6,8,11):
            days = 30
        elif (mth == 2 and self.isLeapYear(year)):
            days = 29
        else:
            days = 28
        return days

    def setPosition(self, left, top):
        element = self.getElement()
        DOM.setStyleAttribute(element, "left", "%dpx" % left)
        DOM.setStyleAttribute(element, "top", "%dpx" % top)

    def show(self, left, top):
        if left < 0:
            left = 0
        if top < 0:
            top = 0
        self.setPosition(left, top)
        self.drawCurrent()
        self.setVisible(True)

    def drawCurrent(self):
        yr, mth, day = time.strftime("%Y-%m-%d").split("-")
        self.draw(int(mth), int(yr))

    def draw(self, month, year):
        tod = time.localtime()
        mm = tod.tm_mon
        yy = tod.tm_year
        # has today changed and thus changed month? cater to rare case where widget in created on last day of month &
        # page left till next day
        hasChangeMonth = False
        if yy <> self.todayYear or mm <> self.todayMonth:
            hasChangeMonth = True
            self.todayYear = yy
            self.todayMonth = mm

        # check to see if we have drawn the full widget before
        if self.defaultGrid is None:
            self.drawFull(month, year)
        else:
            # ok means we are re-drawing, but first check if it is the same as the defaultGrid, if yes, just use it
            if not hasChangeMonth and month == self.todayMonth and year == self.todayYear:
                self.middlePanel.setWidget(self.defaultGrid)
                self.currentMonth = self.todayMonth
                self.currentYear = self.todayYear
            else:
                # we have to redraw the grid -- bah
                g = self.drawGrid(month, year)

                if hasChangeMonth:
                    self.defaultGrid = grid  # reset the default grid as we have changed months

            #
            # what about the title panel?
            #
            self.titlePanel.setWidget(
                HTML("<b>" + self.getMonthsOfYear()[month - 1] + " " +
                     str(year) + "</b>"))
            self.setVisible(True)

        return

    def drawFull(self, month, year):
        # should be called only once when we draw the calendar for the first time
        #
        self.vp = VerticalPanel()
        self.vp.setSpacing(2)
        self.vp.addStyleName("calendarbox calendar-module calendar")
        self.setWidget(self.vp)
        self.setVisible(False)
        #
        mth = int(month)
        yr = int(year)

        tp = HorizontalPanel()
        tp.addStyleName("calendar-top-panel")
        tp.setSpacing(5)

        h1 = Hyperlink('<<')
        h1.addClickListener(getattr(self, 'onPreviousYear'))
        h2 = Hyperlink('<')
        h2.addClickListener(getattr(self, 'onPreviousMonth'))
        h4 = Hyperlink('>')
        h4.addClickListener(getattr(self, 'onNextMonth'))
        h5 = Hyperlink('>>')
        h5.addClickListener(getattr(self, 'onNextYear'))

        tp.add(h1)
        tp.add(h2)

        # titlePanel can be changed, whenever we draw, so keep the reference

        self.titlePanel = SimplePanel()
        self.titlePanel.setWidget(
            HTML("<b>" + self.getMonthsOfYear()[mth - 1] + " " + str(yr) +
                 "</b>"))
        self.titlePanel.setStyleName("calendar-center")

        tp.add(self.titlePanel)
        tp.add(h4)
        tp.add(h5)
        tvp = VerticalPanel()
        tvp.setSpacing(10)
        tvp.add(tp)

        self.vp.add(tvp)

        # done with top panel

        self.middlePanel = SimplePanel()
        grid = self.drawGrid(mth, yr)
        self.middlePanel.setWidget(grid)
        self.vp.add(self.middlePanel)
        self.defaultGrid = grid
        #
        # some links & handlers
        #
        bh1 = Hyperlink(self.yesterday)
        bh1.addClickListener(getattr(self, 'onYesterday'))
        bh2 = Hyperlink(self.today)
        bh2.addClickListener(getattr(self, 'onToday'))
        bh3 = Hyperlink(self.tomorrow)
        bh3.addClickListener(getattr(self, 'onTomorrow'))
        bh4 = Hyperlink(self.cancel)
        bh4.addClickListener(getattr(self, 'onCancel'))
        #
        # add code to test another way of doing the layout
        #
        b = HorizontalPanel()
        b.add(bh1)
        b.add(bh2)
        b.add(bh3)
        b.addStyleName("calendar-shortcuts")
        self.vp.add(b)
        b2 = SimplePanel()
        b2.add(bh4)
        b2.addStyleName("calendar-cancel")
        self.vp.add(b2)

        self.setVisible(True)
        return

    def drawGrid(self, month, year):
        # draw the grid in the middle of the calendar

        daysInMonth = self.getDaysInMonth(month, year)
        secs = time.mktime((year, month, 1, 0, 0, 0, 0, 0,
                            -1))  # first day of the month & year
        struct = time.localtime(secs)
        startPos = (
            struct.tm_wday +
            1) % 7  # 0 - sunday for our needs instead 0 = monday in tm_wday
        slots = startPos + daysInMonth - 1
        rows = int(slots / 7) + 1
        grid = Grid(rows + 1, 7)  # extra row for the days in the week
        grid.setWidth("100%")
        grid.addTableListener(self)
        self.middlePanel.setWidget(grid)
        #
        # put some content into the grid cells
        #
        for i in range(7):
            grid.setText(0, i, self.getDaysOfWeek()[i])
            grid.cellFormatter.addStyleName(0, i, "calendar-header")
        #
        # draw cells which are empty first
        #
        day = 0
        pos = 0
        while pos < startPos:
            grid.setText(1, pos, " ")
            grid.cellFormatter.setStyleAttr(1, pos, "background", "#f3f3f3")
            grid.cellFormatter.addStyleName(1, pos, "calendar-blank-cell")
            pos += 1
        # now for days of the month
        row = 1
        day = 1
        col = startPos
        while day <= daysInMonth:
            if pos % 7 == 0 and day <> 1:
                row += 1
            col = pos % 7
            grid.setText(row, col, str(day))
            if self.currentYear == self.todayYear and self.currentMonth == self.todayMonth and day == self.todayDay:
                grid.cellFormatter.addStyleName(row, col,
                                                "calendar-cell-today")
            else:
                grid.cellFormatter.addStyleName(row, col, "calendar-day-cell")
            day += 1
            pos += 1
        #
        # now blank lines on the last row
        #
        col += 1
        while col < 7:
            grid.setText(row, col, " ")
            grid.cellFormatter.setStyleAttr(row, col, "background", "#f3f3f3")
            grid.cellFormatter.addStyleName(row, col, "calendar-blank-cell")
            col += 1

        return grid

    def onCellClicked(self, grid, row, col):
        if row == 0:
            return
        text = grid.getText(row, col)
        if text == "":
            return
        selectedDay = int(text)
        # well if anyone is listening to the listener, fire that event
        for listener in self.selectedDateListeners:
            if hasattr(listener, "onDateSelected"):
                listener.onDateSelected(self.currentYear, self.currentMonth,
                                        selectedDay)
            else:
                listener(self.currentYear, self.currentMonth, selectedDay)
        self.setVisible(False)

    def onPreviousYear(self, event):
        self.drawPreviousYear()

    def onPreviousMonth(self, event):
        self.drawPreviousMonth()

    def onNextMonth(self, event):
        self.drawNextMonth()

    def onNextYear(self, event):
        self.drawNextYear()

    def onDate(self, event, yy, mm, dd):
        for listener in self.selectedDateListeners:
            if hasattr(listener, "onDateSelected"):
                listener.onDateSelected(yy, mm, dd)
            else:
                listener(yy, mm, dd)
        self.setVisible(False)

    def onYesterday(self, event):
        yesterday = time.localtime(time.time() - 3600 * 24)
        mm = yesterday.tm_mon
        dd = yesterday.tm_mday
        yy = yesterday.tm_year
        self.onDate(event, yy, mm, dd)

    def onToday(self, event):
        tod = time.localtime()
        mm = tod.tm_mon
        dd = tod.tm_mday
        yy = tod.tm_year
        self.onDate(event, yy, mm, dd)

    def onTomorrow(self, event):
        tom = time.localtime(time.time() + 3600 * 24)
        mm = tom.tm_mon
        dd = tom.tm_mday
        yy = tom.tm_year
        self.onDate(event, yy, mm, dd)

    def onCancel(self, event):
        self.setVisible(False)

    def drawCurrent(self):
        yr, mth, day = time.strftime("%Y-%m-%d").split("-")
        self.draw(int(mth), int(yr))

    def drawDate(self, month, year):
        # if year == self.currentYear and month == self.currentYear():
        # self.drawCurrent()
        self.currentMonth = month
        self.currentYear = year
        self.draw(self.currentMonth, self.currentYear)

    def drawPreviousMonth(self):
        if int(self.currentMonth) == 1:
            self.currentMonth = 12
            self.currentYear = int(self.currentYear) - 1
        else:
            self.currentMonth = int(self.currentMonth) - 1
        self.draw(self.currentMonth, self.currentYear)

    def drawNextMonth(self):
        if int(self.currentMonth) == 12:
            self.currentMonth = 1
            self.currentYear = int(self.currentYear) + 1
        else:
            self.currentMonth = int(self.currentMonth) + 1
        self.draw(self.currentMonth, self.currentYear)

    def drawPreviousYear(self):
        self.currentYear = int(self.currentYear) - 1
        self.draw(self.currentMonth, self.currentYear)

    def drawNextYear(self):
        self.currentYear = int(self.currentYear) + 1
        self.draw(self.currentMonth, self.currentYear)