Beispiel #1
0
    def datetimeAt(self, x):
        """
        Returns the datetime at the inputed x position.
        
        :return     <QDateTime>
        """
        gantt = self.ganttWidget()
        dstart = gantt.dateTimeStart()
        distance = int(x / float(gantt.cellWidth()))
        
        # calculate the time for a minute
        if scale == gantt.Timescale.Minute:
            return dstart.addSecs(distance)
        
        # calculate the time for an hour
        elif scale == gantt.Timescale.Hour:
            return dstart.addSecs(distance * 2.0)

        # calculate the time for a day
        elif scale == gantt.Timescale.Day:
            dstart = QDateTime(gantt.dateStart(), QTime(0, 0, 0))
            return dstart.addSecs(distance * (60 * 2.0))
        
        # calculate the time off the date only
        else:
            date = self.dateAt(x)
            return QDateTime(date, QTime(0, 0, 0))
Beispiel #2
0
    def setTimeEnd(self, timeEnd):
        """
        Sets the end time for this item.  This method will only affect the 
        start time if the end time is set to occur before its start, in which
        case it will set the start time as 60 minutes before.
        Otherwise, this method will scale the duration of the event.
        
        :param      timeEnd | <QTime>
        """
        timeEnd = QTime(timeEnd)

        if (timeEnd < self._timeStart):
            self._timeStart = timeEnd.addSecs(-60 * 60)
        self._timeEnd = timeEnd
        self.markForRebuild()
Beispiel #3
0
 def setTimeEnd( self, timeEnd ):
     """
     Sets the end time for this item.  This method will only affect the 
     start time if the end time is set to occur before its start, in which
     case it will set the start time as 60 minutes before.
     Otherwise, this method will scale the duration of the event.
     
     :param      timeEnd | <QTime>
     """
     timeEnd = QTime(timeEnd)
     
     if ( timeEnd < self._timeStart ):
         self._timeStart = timeEnd.addSecs(-60 * 60)
     self._timeEnd = timeEnd
     self.markForRebuild()
Beispiel #4
0
 def setTimeStart( self, timeStart ):
     """
     Sets the start time for this item.  This will automatically push the
     end time to match the length for this item.  So if the item starts
     at 11a and ends on 1p, and the start time is changed to 12p
     the end time will change to 2p.  To affect the length of the 
     item, use either setLength, or setTimeEnd.
     
     :param      timeStart | <QDate>
     """
     timeStart = QTime(timeStart)
     
     length = self.length() # in minutes
     self._timeStart = timeStart
     self._timeEnd   = timeStart.addSecs(length * 60)
     self.markForRebuild()
Beispiel #5
0
 def datetimeXPos(self, dtime):
     """
     Returns the x-position for the inputed date time.
     
     :return     <float>
     """
     gantt = self.ganttWidget()
     scale = gantt.timescale()
     
     # calculate the distance for a minute
     if scale == gantt.Timescale.Minute:
         dstart = gantt.dateTimeStart()
         secs = dstart.secsTo(dtime)
         return secs
     
     # calculate the distance for an hour
     elif scale == gantt.Timescale.Hour:
        dstart = gantt.dateTimeStart()
        secs = dstart.secsTo(dtime)
        return secs / 2.0
     
     # calculate the distance for a day
     elif scale == gantt.Timescale.Day:
         dstart = QDateTime(gantt.dateStart(), QTime(0, 0, 0))
         secs = dstart.secsTo(dtime)
         return (secs / (60.0 * 2.0))
     
     # calculate the distance off the date only
     else:
         return self.dateXPos(dtime.date())
Beispiel #6
0
    def setTimeStart(self, timeStart):
        """
        Sets the start time for this item.  This will automatically push the
        end time to match the length for this item.  So if the item starts
        at 11a and ends on 1p, and the start time is changed to 12p
        the end time will change to 2p.  To affect the length of the 
        item, use either setLength, or setTimeEnd.
        
        :param      timeStart | <QDate>
        """
        timeStart = QTime(timeStart)

        length = self.length()  # in minutes
        self._timeStart = timeStart
        self._timeEnd = timeStart.addSecs(length * 60)
        self.markForRebuild()
Beispiel #7
0
 def timeEnd(self):
     """
     Returns the ending time that will be used for this item.  If it is an
     all day event, then the time returned will be 23:59:59.
     
     :return     <QTime>
     """
     if (self.isAllDay()):
         return QTime(23, 59, 59)
     return self._timeEnd
Beispiel #8
0
    def timeStart(self):
        """
        Returns the starting time that will be used for this item.  If it is
        an all day event, then the time returned will be 0:0:0
        
        :return     <QTime>
        """
        if (self.isAllDay()):
            return QTime(0, 0, 0)

        return self._timeStart
Beispiel #9
0
 def setDateTimeStart(self, dtime):
     """
     Sets the starting date time for this gantt chart.
     
     :param      dtime | <QDateTime>
     """
     self._dateStart = dtime.date()
     if self.timescale() in (self.Timescale.Minute, self.Timescale.Hour):
         self._timeStart = dtime.time()
     else:
         self._timeStart = QTime(0, 0, 0)
Beispiel #10
0
    def setDateTimeEnd(self, dtime):
        """
        Sets the endiing date time for this gantt chart.
        
        :param      dtime | <QDateTime>
        """
        self._dateEnd = dtime.date()

        if self.timescale() in (self.Timescale.Minute, self.Timescale.Hour):
            self._timeEnd = dtime.time()
        else:
            self._timeEnd = QTime(23, 59, 59)
Beispiel #11
0
    def setTimescale(self, timescale):
        """
        Sets the timescale value for this widget to the inputed value.
        
        :param      timescale | <XGanttWidget.Timescale>
        """
        self._timescale = timescale

        # show hour/minute scale
        if timescale == XGanttWidget.Timescale.Minute:
            self._cellWidth = 60  # (60 seconds)
            self._dateStart = QDate.currentDate()
            self._timeStart = QTime(0, 0, 0)

            self._dateEnd = QDate.currentDate()
            self._timeEnd = QTime(23, 59, 59)

        elif timescale == XGanttWidget.Timescale.Hour:
            self._cellWidth = 30  # (60 seconds / 2.0)

            self._dateStart = QDate.currentDate()
            self._timeStart = QTime(0, 0, 0)

            self._dateEnd = QDate.currentDate()
            self._timeEnd = QTime(23, 59, 59)

        # show day/hour scale
        elif timescale == XGanttWidget.Timescale.Day:
            self._cellWidth = 30  # (60 minutes / 2.0)

            self._dateStart = QDate.currentDate().addDays(-7)
            self._timeStart = QTime(0, 0, 0)

            self._dateEnd = QDate.currentDate().addDays(7)
            self._timeEnd = QTime(23, 59, 59)
Beispiel #12
0
    def __init__(self, ganttWidget):
        super(XGanttWidgetItem, self).__init__()

        # set default properties
        self.setFixedHeight(ganttWidget.cellHeight())
        for i in range(1, 20):
            self.setTextAlignment(i, Qt.AlignCenter)

        # define custom properties
        self._blockedAdjustments = {}
        self._viewItem = self.createViewItem()
        self._dateStart = QDate.currentDate()
        self._dateEnd = QDate.currentDate()
        self._allDay = True
        self._timeStart = QTime(0, 0, 0)
        self._timeEnd = QTime(23, 59, 59)
        self._name = ''
        self._properties = {}
        self._itemStyle = XGanttWidgetItem.ItemStyle.Normal
        self._useGroupStyleWithChildren = True
        self._dependencies = {}
        self._reverseDependencies = {}
Beispiel #13
0
 def __init__( self ):
     super(XCalendarItem, self).__init__()
     
     curr_dtime = QDateTime.currentDateTime()
     curr_date  = curr_dtime.date()
     curr_time  = curr_dtime.time()
     
     self.setFlags(self.flags() | self.ItemIsSelectable)
     self.setAcceptHoverEvents(True)
     
     # round to the nearest 15 minute segment
     curr_time = QTime(curr_time.hour(),
                       curr_time.minute() - curr_time.minute() % 30,
                       0)
     
     self._rebuildBlocked = False
     self._textData   = []
     
     self._customData        = {}
     self._textColor         = QColor('white')
     self._fillColor         = QColor('blue')
     self._borderColor       = QColor('blue')
     self._highlightColor    = QColor('blue')
     
     self._title             = 'No Title'
     self._description       = ''
     self._dateStart         = curr_date
     self._dateEnd           = curr_date
     self._timeStart         = curr_time
     self._timeEnd           = curr_time.addSecs(60 * 60)
     self._allDay            = True
     self._rebuildRequired   = False
     
     if ( QTime(23, 0, 0) <= self._timeStart ):
         self._timeEnd       = QTime(23, 59, 0)
     
     self.setColor('blue')
Beispiel #14
0
    def __init__(self):
        super(XCalendarItem, self).__init__()

        curr_dtime = QDateTime.currentDateTime()
        curr_date = curr_dtime.date()
        curr_time = curr_dtime.time()

        self.setFlags(self.flags() | self.ItemIsSelectable)
        self.setAcceptHoverEvents(True)

        # round to the nearest 15 minute segment
        curr_time = QTime(curr_time.hour(),
                          curr_time.minute() - curr_time.minute() % 30, 0)

        self._rebuildBlocked = False
        self._textData = []

        self._customData = {}
        self._textColor = QColor('white')
        self._fillColor = QColor('blue')
        self._borderColor = QColor('blue')
        self._highlightColor = QColor('blue')

        self._title = 'No Title'
        self._description = ''
        self._dateStart = curr_date
        self._dateEnd = curr_date
        self._timeStart = curr_time
        self._timeEnd = curr_time.addSecs(60 * 60)
        self._allDay = True
        self._rebuildRequired = False

        if (QTime(23, 0, 0) <= self._timeStart):
            self._timeEnd = QTime(23, 59, 0)

        self.setColor('blue')
Beispiel #15
0
 def rebuildDay(self, opt):
     """
     Rebuilds the scale for the day mode.
     
     :param      opt | <XGanttRenderOptions>
     """
     self._labels            = []
     self._hlines            = []
     self._vlines            = []
     self._weekendRects      = []
     self._alternateRects    = []
     self._topLabels         = []
     
     top_format = 'dddd MMMM dd'
     label_format = 'ha'
     increment = 60 # hour
     
     # generate vertical lines
     x           = 0
     i           = 0
     half        = opt.header_height / 2.0
     curr        = QDateTime(opt.start, QTime(0, 0, 0))
     end         = QDateTime(opt.end, QTime(23, 0, 0))
     top_label   = opt.start.toString(top_format)
     top_rect    = QRect(0, 0, 0, half)
     alt_rect    = None
     
     while curr <= end:
         # update the top rect
         new_top_label = curr.toString(top_format)
         if new_top_label != top_label:
             top_rect.setRight(x)
             self._topLabels.append((top_rect, top_label))
             top_rect  = QRect(x, 0, 0, half)
             top_label = new_top_label
             
             if alt_rect is not None:
                 alt_rect.setRight(x)
                 self._alternateRects.append(alt_rect)
                 alt_rect = None
             else:
                 alt_rect = QRect(x, 0, 0, opt.height)
         
         # create the line
         self._hlines.append(QLine(x, 0, x, opt.height))
         
         # create the header label/rect
         label = nativestring(curr.toString(label_format))[:-1]
         rect  = QRect(x, half, opt.cell_width, half)
         self._labels.append((rect, label))
         
         # increment the dates
         curr = curr.addSecs(increment * 60)
         x += opt.cell_width
         i += 1
     
     # update the top rect
     top_rect.setRight(x)
     top_label = opt.end.toString(top_format)
     self._topLabels.append((top_rect, top_label))
     
     if alt_rect is not None:
         alt_rect.setRight(x)
         self._alternateRects.append(alt_rect)
     
     # resize the width to match the last date range
     new_width = x
     self.setSceneRect(0, 0, new_width, opt.height)
     
     # generate horizontal lines
     y       = 0
     h       = opt.height
     width   = new_width
     
     while y < h:
         self._vlines.append(QLine(0, y, width, y))
         y += opt.cell_height
     
     # clear the dirty flag
     self._dirty = False
Beispiel #16
0
 def rebuildDays( self ):
     """
     Rebuilds the interface as a week display.
     """
     time = QTime(0, 0, 0)
     hour = True
     
     x = 6
     y = 6 + 24
     
     w = self.width() - 12 - 25
     
     dh         = 48
     indent     = 58
     text_data  = []
     
     vlines      = []
     hlines      = [QLine(x, y, w, y)]
     time_grids  = []
     
     for i in range(48):
         if ( hour ):
             hlines.append(QLine(x, y, w, y))
             text_data.append((x,
                               y + 6, 
                               indent - 6, 
                               dh, 
                               Qt.AlignRight | Qt.AlignTop,
                               time.toString('hap')))
         else:
             hlines.append(QLine(x + indent, y, w, y))
         
         time_grids.append((time, y, dh / 2))
         
         # move onto the next line
         hour = not hour
         time = time.addSecs(30 * 60)
         y += dh / 2
     
     hlines.append(QLine(x, y, w, y))
     
     h = y
     y = 6 + 24
     
     # load the grid
     vlines.append(QLine(x, y, x, h))
     vlines.append(QLine(x + indent, y, x + indent, h))
     vlines.append(QLine(w, y, w, h))
     
     today     = QDate.currentDate()
     curr_date = self.currentDate()
     
     # load the days
     if ( self.currentMode() == XCalendarScene.Mode.Week ):
         date = self.currentDate()
         day_of_week = date.dayOfWeek()
         if ( day_of_week == 7 ):
             day_of_week = 0
         
         min_date = date.addDays(-day_of_week)
         max_date = date.addDays(6-day_of_week)
         
         self._minimumDate = min_date
         self._maximumDate = max_date
         
         dw    = (w - (x + indent)) / 7.0
         vx    = x + indent
         date  = min_date
         
         for i in range(7):
             vlines.append(QLine(vx, y, vx, h))
             
             text_data.append((vx + 6,
                               6,
                               dw,
                               24,
                               Qt.AlignCenter,
                               date.toString('ddd MM/dd')))
             
             self._dateGrid[date.toJulianDay()] = ((0, i),
                                                   QRectF(vx, y, dw, h - y))
             
             # create the date grid for date time options
             for r, data in enumerate(time_grids):
                 time, ty, th = data
                 dtime = QDateTime(date, time)
                 key = dtime.toTime_t()
                 self._dateTimeGrid[key] = ((r, i), QRectF(vx, ty, dw, th))
             
             if ( date == curr_date ):
                 self._buildData['curr_date'] = QRectF(vx, y, dw, h - 29)
             elif ( date == today ):
                 self._buildData['today'] = QRectF(vx, y, dw, h - 29)
             
             date = date.addDays(1)
             vx += dw
     
     # load a single day
     else:
         date = self.currentDate()
         
         self._maximumDate = date
         self._minimumDate = date
         
         text_data.append((x + indent,
                           6,
                           w,
                           24,
                           Qt.AlignCenter,
                           date.toString('ddd MM/dd')))
         
         self._dateGrid[date.toJulianDay()] = ((0, 0), 
                                               QRectF(x, y, w - x, h - y))
         
         # create the date grid for date time options
         for r, data in enumerate(time_grids):
             time, ty, th = data
             dtime = QDateTime(date, time)
             key = dtime.toTime_t()
             rect = QRectF(x + indent, ty, w - (x + indent), th)
             self._dateTimeGrid[key] = ((r, 0), rect)
     
     self._buildData['grid'] = hlines + vlines
     self._buildData['regular_text'] = text_data
     
     rect = self.sceneRect()
     rect.setHeight(h + 6)
     
     super(XCalendarScene, self).setSceneRect(rect)
Beispiel #17
0
    def __init__(self, parent=None):
        super(XGanttWidget, self).__init__(parent)

        # load the user interface
        projexui.loadUi(__file__, self)

        # define custom properties
        self._backend = None
        self._dateStart = QDate.currentDate().addMonths(-2)
        self._dateEnd = QDate.currentDate().addMonths(2)
        self._timeStart = QTime(0, 0, 0)
        self._timeEnd = QTime(23, 59, 59)
        self._alternatingRowColors = False
        self._cellWidth = 20
        self._cellHeight = 20
        self._first = True
        self._dateFormat = 'M/d/yy'
        self._timescale = XGanttWidget.Timescale.Month
        self._scrolling = False
        self._dirty = False

        # setup the palette colors
        palette = self.palette()
        color = palette.color(palette.Base)

        self._gridPen = QPen(color.darker(115))
        self._brush = QBrush(color)
        self._alternateBrush = QBrush(color.darker(105))

        weekendColor = color.darker(108)
        self._weekendBrush = QBrush(weekendColor)

        # setup the columns for the tree
        self.setColumns(['Name', 'Start', 'End', 'Calendar Days', 'Work Days'])

        header = self.uiGanttTREE.header()
        header.setFixedHeight(self._cellHeight * 2)
        headerItem = self.uiGanttTREE.headerItem()
        headerItem.setSizeHint(0, QSize(80, header.height()))

        # initialize the tree widget
        self.uiGanttTREE.setShowGrid(False)
        self.uiGanttTREE.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOn)
        self.uiGanttTREE.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
        self.uiGanttTREE.setVerticalScrollMode(self.uiGanttTREE.ScrollPerPixel)
        self.uiGanttTREE.setResizeToContentsInteractive(True)
        self.uiGanttTREE.setEditable(True)
        self.uiGanttTREE.resize(500, 20)
        self.uiGanttTREE.setContextMenuPolicy(Qt.CustomContextMenu)

        # initialize the view widget
        self.uiGanttVIEW.setDragMode(self.uiGanttVIEW.RubberBandDrag)
        self.uiGanttVIEW.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOn)
        self.uiGanttVIEW.setAlignment(Qt.AlignTop | Qt.AlignLeft)
        self.uiGanttVIEW.setScene(XGanttScene(self))
        self.uiGanttVIEW.installEventFilter(self)
        self.uiGanttVIEW.horizontalScrollBar().setValue(50)
        self.uiGanttVIEW.setContextMenuPolicy(Qt.CustomContextMenu)

        # create connections
        self.uiGanttTREE.itemExpanded.connect(self.syncView)
        self.uiGanttTREE.itemCollapsed.connect(self.syncView)

        # connect scrollbars
        tree_bar = self.uiGanttTREE.verticalScrollBar()
        view_bar = self.uiGanttVIEW.verticalScrollBar()

        tree_bar.rangeChanged.connect(self._updateViewRect)
        tree_bar.valueChanged.connect(self._scrollView)
        view_bar.valueChanged.connect(self._scrollTree)

        # connect selection
        self.uiGanttTREE.itemSelectionChanged.connect(self._selectView)
        self.uiGanttVIEW.scene().selectionChanged.connect(self._selectTree)
        self.uiGanttTREE.itemChanged.connect(self.updateItemData)
        self.uiGanttTREE.customContextMenuRequested.connect(
            self.requestTreeMenu)
        self.uiGanttVIEW.customContextMenuRequested.connect(
            self.requestViewMenu)
Beispiel #18
0
 def setValue(self, value):
     self.setTime(QTime(value))