diff --git a/components/tvplanit/source/vpganttview.pas b/components/tvplanit/source/vpganttview.pas index 61290709e..65fe44c47 100644 --- a/components/tvplanit/source/vpganttview.pas +++ b/components/tvplanit/source/vpganttview.pas @@ -151,6 +151,7 @@ type function GetDateTimeAtCoord(X: Integer): TDateTime; function GetEventAtCoord(X, Y: Integer): TVpEvent; function GetRowAtCoord(Y: Integer): Integer; + function GetRowOfEvent(AEvent: TVpEvent): Integer; procedure GetEventDateRange; procedure Hookup; procedure Populate; @@ -159,50 +160,34 @@ type procedure PopulateMonthRecords; procedure ScrollDateIntoView(ADate: TDateTime); procedure ScrollHorizontal(ANumCols: Integer); + procedure ScrollRowIntoView(ARow: Integer); procedure ScrollVertical(ANumRows: Integer); procedure SetHScrollPos; procedure SetVScrollPos; procedure SpawnEventEditDialog(IsNewEvent: Boolean); - { Popup } - function GetPopupMenu: TPopupMenu; override; - procedure InitializeDefaultPopup; - procedure PopupAddEvent(Sender: TObject); -// procedure PopupImportICalFile(Sender: TObject); -// procedure PopupExportICalFile(Sender: TObject); - procedure PopupDeleteEvent(Sender: TObject); - procedure PopupEditEvent(Sender: TObject); -// procedure PopupToday(Sender: TObject); - procedure UpdatePopupMenu; - { - procedure PopupTomorrow(Sender: TObject); - procedure PopupYesterday(Sender: TObject); - procedure PopupNextDay(Sender: TObject); - procedure PopupPrevDay(Sender: TObject); - procedure PopupNextWeek(Sender: TObject); - procedure PopupPrevWeek(Sender: TObject); - procedure PopupNextMonth(Sender: TObject); - procedure PopupPrevMonth(Sender: TObject); - procedure PopupNextYear(Sender: TObject); - procedure PopupPrevYear(Sender: TObject); - procedure PopupCustomDate(Sender: TObject); - procedure PopupPickResourceGroupEvent(Sender: TObject); - } - { inherited methods } procedure CreateParams(var AParams: TCreateParams); override; procedure DblClick; override; function DoMouseWheelDown(Shift: TShiftState; MousePos: TPoint): Boolean; override; function DoMouseWheelUp(Shift: TShiftState; MousePos: TPoint): Boolean; override; + procedure DoOnResize; override; class function GetControlClassDefaultSize: TSize; override; procedure KeyDown(var Key: Word; Shift: TShiftState); override; procedure Loaded; override; procedure MouseDown(Button: TMouseButton; Shift: TShiftState; X, Y: Integer); override; procedure Paint; override; - procedure Resize; override; procedure WMHScroll(var Msg: TLMHScroll); message LM_HSCROLL; procedure WMVScroll(var Msg: TLMVScroll); message LM_VSCROLL; + { Popup } + function GetPopupMenu: TPopupMenu; override; + procedure InitializeDefaultPopup; + procedure PopupAddEvent(Sender: TObject); + procedure PopupDeleteEvent(Sender: TObject); + procedure PopupEditEvent(Sender: TObject); + procedure UpdatePopupMenu; + public constructor Create(AOwner: TComponent); override; destructor Destroy; override; @@ -387,7 +372,7 @@ end; constructor TVpGanttView.Create(AOwner: TComponent); begin inherited; - ControlStyle := [csCaptureMouse, csOpaque, csDoubleClicks]; + ControlStyle := [csCaptureMouse, csOpaque, csClickEvents, csDoubleClicks]; FInLinkHandler := false; FLoaded := false; @@ -407,11 +392,10 @@ begin FRowHeaderAttributes := TVpGanttRowHeaderAttributes.Create(self); FColHeaderAttributes := TVpGanttColHeaderAttributes.Create(self); - FDrawingStyle := ds3d; FDateFormat[0] := DEFAULT_DAYFORMAT; FDateFormat[1] := DEFAULT_MONTHFORMAT; FDateFormat[2] := DEFAULT_MONTHFORMAT_SHORT; - + FDrawingStyle := ds3d; FScrollBars := ssBoth; // Popup menu @@ -508,7 +492,7 @@ begin begin startTime := trunc(dt); endTime := startTime + 1.0; - FActiveEvent := Datastore.Resource.Schedule.AddEvent( + ActiveEvent := Datastore.Resource.Schedule.AddEvent( Datastore.GetNextID(EventsTableName), startTime, endTime @@ -603,6 +587,28 @@ begin end; end; +procedure TVpGanttView.DoOnResize; +var + emptyRows, emptyCols: Integer; +begin + inherited; + + if (FRowHeight > 0) and (Length(FEventRecords) > 0) then + begin + VisibleRows := CalcVisibleRows(ClientHeight); + emptyRows := VisibleRows - (Length(FEventRecords) - FTopRow); + if emptyRows > 0 then + ScrollVertical(-emptyRows); + + VisibleCols := CalcVisibleCols(ClientWidth); + emptyCols := VisibleCols - (Length(FDayRecords) - FLeftCol); + if emptyCols > 0 then + ScrollHorizontal(-emptyCols); + end; + + Invalidate; +end; + function TVpGanttView.GetColAtCoord(X: Integer): Integer; begin Result := (X - FixedColWidth) div FColWidth + FLeftCol; @@ -737,6 +743,19 @@ begin Result := (Y - FTotalColHeaderHeight) div FRowHeight + FTopRow; end; +function TVpGanttView.GetRowOfEvent(AEvent: TVpEvent): Integer; +var + i: Integer; +begin + for i := 0 to High(FEventRecords) do + if FEventRecords[i].Event = AEvent then + begin + Result := i; + exit; + end; + Result := -1; +end; + { If the component is being dropped on a form at designtime, then automatically hook up to the first datastore component found. } procedure TVpGanttView.HookUp; @@ -969,8 +988,11 @@ begin FEventRecords[i].Caption := event.Description; FEventRecords[i].HeadRect := Rect(xh1, y1, xh2, y2); FEventRecords[i].EventRect := Rect(xe1, y1, xe2, y2); + if event = FActiveEvent then + FActiveRow := i; y1 := y2; end; + finally list.Free; end; @@ -1027,12 +1049,6 @@ begin end; end; -procedure TVpGanttView.Resize; -begin - inherited; - Invalidate; -end; - procedure TVpGanttView.ScrollDateIntoView(ADate: TDateTime); begin if (FStartDate = 0) or (FStartDate = NO_DATE) then @@ -1040,10 +1056,9 @@ begin if ADate < FStartDate then begin - FStartDate := trunc(FStartDate); + FStartDate := trunc(ADate); FColCount := GetNumDays; - SetLeftCol(0); - Invalidate; + SetLeftCol(-MaxInt); end else if ADate > FEndDate then begin @@ -1067,6 +1082,12 @@ begin Invalidate; end; +procedure TVpGanttView.ScrollRowIntoView(ARow: Integer); +begin + if (ARow < TopRow) or (ARow >= TopRow + FVisibleRows) then + SetTopRow(ARow - FVisibleRows div 2) +end; + procedure TVpGanttView.ScrollVertical(ANumRows: Integer); begin SetTopRow(FTopRow + ANumRows); @@ -1082,6 +1103,7 @@ begin Populate; ScrollDateIntoView(FActiveDate); + FActiveCol := trunc(FActiveDate) - trunc(FStartDate); Invalidate; if (not FInLinkHandler) and (ControlLink <> nil) then @@ -1095,7 +1117,11 @@ begin begin FActiveEvent := AValue; if FActiveEvent <> nil then + begin + FActiveRow := GetRowOfEvent(FActiveEvent); + ScrollRowIntoView(FActiveRow); SetActiveDate(FActiveEvent.StartTime); + end; UpdatePopupMenu; end; end; @@ -1275,7 +1301,14 @@ begin if AllowIt then begin FActiveEvent.Changed := true; DataStore.PostEvents; - SetActiveDate(trunc(FActiveEvent.StartTime)); + + // The new or edited event may be at a different position in the grid. + // --> Re-read the events to sort them, find the new active row/col and + // scroll them into view + PopulateEventRecords; + SetActiveDate(FActiveEvent.StartTime); + ScrollRowIntoView(FActiveRow); + if IsNewEvent and Assigned(FOnAddEvent) then FOnAddEvent(self, FActiveEvent); if not IsNewEvent and Assigned(FOnModifyEvent) then @@ -1292,12 +1325,6 @@ end; procedure TVpGanttView.WMHScroll(var Msg: TLMHScroll); begin - { for simplicity, bail out of editing while scrolling. } -// EndEdit(Self); - - // wp: Next line should never happen after EndEdit... -// if (dvInPlaceEditor <> nil) and dvInplaceEditor.Visible then Exit; - case Msg.ScrollCode of SB_LINELEFT : ScrollHorizontal(-1); SB_LINERIGHT : ScrollHorizontal(1); @@ -1309,12 +1336,6 @@ end; procedure TVpGanttView.WMVScroll(var Msg: TLMVScroll); begin - { for simplicity, bail out of editing while scrolling. } -// EndEdit(Self); - - // wp: Next line should never happen after EndEdit... -// if (dvInPlaceEditor <> nil) and dvInplaceEditor.Visible then Exit; - case Msg.ScrollCode of SB_LINEUP : ScrollVertical(-1); SB_LINEDOWN : ScrollVertical(1); @@ -1346,7 +1367,6 @@ end; procedure TVpGanttView.InitializeDefaultPopup; var NewItem: TVpMenuItem; - NewSubItem: TVpMenuItem; canEdit: Boolean; begin canEdit := (FActiveEvent <> nil) and FActiveEvent.CanEdit; @@ -1377,164 +1397,6 @@ begin NewItem.Tag := 1; FDefaultPopup.Items.Add(NewItem); end; - (* - NewItem := TVpMenuItem.Create(Self); // ---- - NewItem.Kind := mikSeparator; - FDefaultPopup.Items.Add(NewItem); - - if RSPopupImportFromICal <> '' then begin - NewItem := TVpMenuItem.Create(Self); // Import from iCal - NewItem.Kind := mikImportEventFromICal; - NewItem.OnClick := PopupImportICalFile; - NewItem.Tag := 0; - FDefaultPopup.Items.Add(NewItem); - end; - - if RSPopupExportToICal <> '' then begin // Export ical - NewItem := TVpMenuItem.Create(Self); - NewItem.Kind := mikExportEventToICal; - NewItem.OnClick := PopupExportICalFile; - NewItem.Tag := 1; - FDefaultPopup.Items.Add(NewItem); - end; - *) - { - NewItem := TVpMenuItem.Create(Self); // ---- - NewItem.Kind := mikSeparator; - FDefaultPopup.Items.Add(NewItem); - - if RSPopupChangeDate <> '' then begin // Change date - NewItem := TVpMenuItem.Create(Self); - NewItem.Kind := mikChangeDate; - NewItem.Tag := 0; - FDefaultPopup.Items.Add(NewItem); - - if RSToday <> '' then begin // Today - NewSubItem := TVpMenuItem.Create(Self); - NewSubItem.Kind := mikToday; - NewSubItem.OnClick := @PopupToday; - NewSubItem.Tag := 0; - NewItem.Add(NewSubItem); - end; - (* - NewSubItem := TVpMenuItem.Create(Self); // --- - NewSubItem.Kind := mikSeparator; - NewItem.Add(NewSubItem); - - if RSYesterday <> '' then begin // Yesterday - NewSubItem := TVpMenuItem.Create(Self); - NewSubItem.Kind := mikYesterday; - NewSubItem.OnClick := PopupYesterday; - NewSubItem.Tag := 0; - NewItem.Add(NewSubItem); - end; - - if RSTomorrow <> '' then begin // Tomorrow - NewSubItem := TVpMenuItem.Create(Self); - NewSubItem.Kind := mikTomorrow; - NewSubItem.OnClick := PopupTomorrow; - NewSubItem.Tag := 0; - NewItem.Add(NewSubItem); - end; - - NewSubItem := TVpMenuItem.Create(Self); // -- - NewSubItem.Kind := mikSeparator; - NewItem.Add(NewSubItem); - - if RSNextDay <> '' then begin // Next day - NewSubItem := TVpMenuItem.Create(Self); - NewSubItem.Kind := mikNextDay; - NewSubItem.OnClick := PopupNextDay; - NewSubItem.Tag := 0; - NewItem.Add(NewSubItem); - end; - - if RSPrevDay <> '' then begin // Prev day - NewSubItem := TVpMenuItem.Create(Self); - NewSubItem.Kind := mikPrevDay; - NewSubItem.OnClick := PopupPrevDay; - NewSubItem.Tag := 0; - NewItem.Add(NewSubItem); - end; - - NewSubItem := TVpMenuItem.Create(Self); // --- - NewSubItem.Kind := mikSeparator; - NewItem.Add(NewSubItem); - - if RSNextWeek <> '' then begin // Next week - NewSubItem := TVpMenuItem.Create(Self); - NewSubItem.Kind := mikNextWeek; - NewSubItem.OnClick := PopupNextWeek; - NewSubItem.Tag := 0; - NewItem.Add(NewSubItem); - end; - - if RSPrevWeek <> '' then begin // Prev week - NewSubItem := TVpMenuItem.Create(Self); - NewSubItem.Kind := mikPrevWeek; - NewSubItem.OnClick := PopupPrevWeek; - NewSubItem.Tag := 0; - NewItem.Add(NewSubItem); - end; - - NewSubItem := TVpMenuItem.Create(Self); // --- - NewSubItem.Kind := mikSeparator; - NewItem.Add(NewSubItem); - - if RSNextMonth <> '' then begin // Next month - NewSubItem := TVpMenuItem.Create(Self); - NewSubItem.Kind := mikNextMonth; - NewSubItem.OnClick := PopupNextMonth; - NewSubItem.Tag := 0; - NewItem.Add(NewSubItem); - end; - - if RSPrevMonth <> '' then begin // Prev Month - NewSubItem := TVpMenuItem.Create(Self); - NewSubItem.Kind := mikPrevMonth; - NewSubItem.OnClick := PopupPrevMonth; - NewSubItem.Tag := 0; - NewItem.Add(NewSubItem); - end; - - NewSubItem := TVpMenuItem.Create(Self); // --- - NewSubItem.Kind := mikSeparator; - NewItem.Add(NewSubItem); - - if RSNextYear <> '' then begin // Next year - NewSubItem := TVpMenuItem.Create(Self); - NewSubItem.Kind := mikNextYear; - NewSubItem.OnClick := PopupNextYear; - NewSubItem.Tag := 0; - NewItem.Add(NewSubItem); - end; - - if RSPrevYear <> '' then begin // Prev year - NewSubItem := TVpMenuItem.Create(Self); - NewSubItem.Kind := mikPrevYear; - NewSubItem.OnClick := PopupPrevYear; - NewSubItem.Tag := 0; - NewItem.Add(NewSubItem); - end; - - NewSubItem := TVpMenuItem.Create(Self); // --- - NewSubItem.Kind := mikSeparator; - NewItem.Add(NewSubItem); - - if RSCustomDate <> '' then begin // Custom date - NewSubItem := TVpMenuItem.Create(Self); - NewSubItem.Kind := mikCustomDate; - NewSubItem.OnClick := PopupCustomDate; - NewSubItem.Tag := 0; - NewItem.Add(NewSubItem); - end; - *) - end; - } - (* - if (Datastore <> nil) and (Datastore.Resource <> nil) then - AddResourceGroupMenu(FDefaultPopup.Items, Datastore.Resource, PopupPickResourceGroupEvent); - *) end; procedure TVpGanttView.PopupAddEvent(Sender: TObject); @@ -1560,53 +1422,6 @@ begin // Edit this new event SpawnEventEditDialog(True); end; - (* -procedure TVpGanttView.PopupExportICalFile(Sender: TObject); -var - dlg: TSaveDialog; -begin - if (not Assigned(Datastore)) or (not Assigned(Datastore.Resource)) or - (FActiveEvent = nil) - then - exit; - - dlg := TSaveDialog.Create(nil); - try - dlg.Title := RSSaveICalTitle; - dlg.Filter := RSICalFilter; - dlg.FileName := ''; - dlg.Options := dlg.Options - [ofAllowMultiSelect] + [ofOverwritePrompt]; - if dlg.Execute then - ExportICalFile(dlg.FileName, [FActiveEvent]); - finally - dlg.Free; - end; -end; - -procedure TVpGanttView.PopupImportICalFile(Sender: TObject); -var - dlg: TOpenDialog; - fn: String; -begin - if ReadOnly or (not CheckCreateResource) or - (not Assigned(DataStore)) or (not Assigned(DataStore.Resource)) - then - Exit; - - dlg := TOpenDialog.Create(nil); - try - dlg.Title := RSLoadICalTitle; - dlg.Filter := RSICalFilter; - dlg.FileName := ''; - dlg.Options := dlg.Options + [ofAllowMultiSelect, ofFileMustExist]; - if dlg.Execute then begin - for fn in dlg.Files do - ImportICalFile(fn, dlg.Files.Count = 1); - end; - finally - dlg.Free; - end; -end; *) procedure TVpGanttView.PopupDeleteEvent(Sender: TObject); begin @@ -1626,11 +1441,6 @@ begin // edit this event SpawnEventEditDialog(false); end; - { -procedure TVpGanttView.PopupToday(Sender: TObject); -begin - SetActiveDate(Now); -end; } procedure TVpGanttView.UpdatePopupMenu; var diff --git a/components/tvplanit/source/vpganttviewpainter.pas b/components/tvplanit/source/vpganttviewpainter.pas index 31dac73a5..fc6a33252 100644 --- a/components/tvplanit/source/vpganttviewpainter.pas +++ b/components/tvplanit/source/vpganttviewpainter.pas @@ -329,9 +329,11 @@ var begin RenderCanvas.Pen.Color := RealLineColor; + dx := FGanttView.LeftCol * FGanttView.ColWidth; + dy := FGanttView.TopRow * FGanttView.RowHeight; + // Horizontal lines x1 := RealLeft + FGanttView.FixedColWidth; - dx := FGanttView.LeftCol * FGanttView.ColWidth; n := FGanttView.NumMonths; if n > 0 then begin @@ -343,19 +345,19 @@ begin if FGanttView.DrawingStyle = ds3D then dec(y0); RenderCanvas.Line(x1, y0, x2, y0); - y0 := 0; + y0 := -dy; if FGanttView.DrawingStyle = ds3D then dec(y0); numEvents := FGanttView.NumEvents; for i := 0 to numEvents - 1 do begin eventRec := FGanttView.EventRecords[i]; y1 := y0 + eventRec.EventRect.Bottom; - RenderCanvas.Line(x1, y1, x2, y1); + if y1 >= FGanttView.TotalColHeaderHeight then + RenderCanvas.Line(x1, y1, x2, y1); end; // Vertical lines y1 := RealTop + FGanttView.TotalColHeaderHeight; - dy := FGanttView.TopRow * FGanttView.RowHeight; if numEvents > 0 then begin eventRec := FGanttView.EventRecords[numEvents-1];