123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682 |
- using System;
- using System.Collections.Generic;
- using System.Collections.Immutable;
- using System.Collections.ObjectModel;
- using System.ComponentModel;
- using System.Diagnostics;
- using System.Linq;
- using System.Windows;
- using System.Windows.Controls;
- using System.Windows.Input;
- using Comal.Classes;
- using InABox.Clients;
- using InABox.Core;
- using InABox.WPF;
- using Microsoft.Win32;
- using net.sf.mpxj;
- using net.sf.mpxj.MpxjUtilities;
- using net.sf.mpxj.reader;
- using Syncfusion.Windows.Controls.Gantt;
- using Syncfusion.Windows.Controls.Grid;
- using Syncfusion.XlsIO;
- using GridSelectionMode = Syncfusion.Windows.Controls.Grid.GridSelectionMode;
- using Resource = Syncfusion.Windows.Controls.Gantt.Resource;
- namespace PRSDesktop
- {
- /// <summary>
- /// Interaction logic for JobStagesGrid.xaml
- /// </summary>
- public partial class JobStagesPanel : UserControl, IPanel<JobStage>, IJobControl
- {
- private CoreTable _relationships;
- private readonly ObservableCollection<Resource> _resources = new();
- private CoreTable _stages;
- private readonly ObservableCollection<GanttTask> _tasks = new();
- private JobStagesGrid grid;
- public JobStagesPanel()
- {
- InitializeComponent();
- Gantt.ItemsSource = _tasks;
- Gantt.ResourceCollection = _resources;
- AddStage.Content = new Image { Source = PRSDesktop.Resources.add.AsBitmapImage() };
- EditStage.Content = new Image { Source = PRSDesktop.Resources.pencil.AsBitmapImage() };
- ImportFileImage.Source = PRSDesktop.Resources.download.AsBitmapImage();
- ExportFileImage.Source = PRSDesktop.Resources.upload.AsBitmapImage();
- DeleteStage.Content = new Image { Source = PRSDesktop.Resources.delete.AsBitmapImage() };
- }
- public Guid ParentID { get; set; }
-
- public JobPanelSettings Settings { get; set; }
- public bool IsReady { get; set; }
- public Dictionary<string, object[]> Selected()
- {
- return new Dictionary<string, object[]>();
- }
- public string SectionName => "Job Stages";
- public DataModel DataModel(Selection selection)
- {
- return new BaseDataModel<Job>(new Filter<Job>(x => x.ID).IsEqualTo(ParentID));
- }
- public void Setup()
- {
- AddStage.Visibility = Security.CanEdit<JobStage>() ? Visibility.Visible : Visibility.Collapsed;
- EditStage.Visibility = Security.CanEdit<JobStage>() ? Visibility.Visible : Visibility.Collapsed;
- ImportFile.Visibility = Security.CanEdit<JobStage>() ? Visibility.Visible : Visibility.Collapsed;
- ExportFile.Visibility = Security.CanEdit<JobStage>() ? Visibility.Visible : Visibility.Collapsed;
- DeleteStage.Visibility = Security.CanEdit<JobStage>() ? Visibility.Visible : Visibility.Collapsed;
- }
- public void CreateToolbarButtons(IPanelHost host)
- {
- }
- public void Shutdown()
- {
- }
- public void Refresh()
- {
- var query = new MultiQuery();
- query.Add(
- new QueryDef<JobStage>(
- new Filter<JobStage>(x => x.Job.ID).IsEqualTo(ParentID),
- null,
- new SortOrder<JobStage>(x => x.Sequence)
- ),
- typeof(JobStage)
- );
- query.Add(
- new QueryDef<JobStageRelationship>(
- new Filter<JobStageRelationship>(x => x.Parent.ID).IsEqualTo(ParentID),
- null,
- null
- ),
- typeof(JobStageRelationship)
- );
- query.Query();
- _stages = query.Get(typeof(JobStage));
- _relationships = query.Get(typeof(JobStageRelationship));
- LoadStages(Guid.Empty);
- LoadRelationships();
- }
- public event DataModelUpdateEvent OnUpdateDataModel;
- public void Heartbeat(TimeSpan time)
- {
- }
- private void Gantt_TemplateApplied(object sender, TemplateAppliedEventArgs args)
- {
- if (Gantt.GanttGrid != null)
- {
- Gantt.GanttGrid.Model.Options.ListBoxSelectionMode = GridSelectionMode.One;
- Gantt.GanttGrid.Model.Sizer.AllowAutoCalculateSize = true;
- Gantt.GanttGrid.Model.Sizer.ListenToSizeChanged = true;
- Gantt.GanttGrid.Model.Options.ColumnSizer = GridControlLengthUnitType.Star;
- Gantt.GanttGrid.RowHeaderWidth = 0;
- Gantt.GanttGrid.ShowRowHeader = false;
- Gantt.GanttGrid.Columns.Clear();
- //Gantt.GanttGrid.Columns.Add(new Syncfusion.Windows.Controls.Grid.GridTreeColumn("TaskId") { Width = 60F, HeaderText = "#", StyleInfo = new Syncfusion.Windows.Controls.Grid.GridStyleInfo() { VerticalAlignment = VerticalAlignment.Center, HorizontalAlignment = HorizontalAlignment.Center } });
- Gantt.GanttGrid.Columns.Add(new GridTreeColumn("TaskName")
- {
- Width = 220F, PercentWidth = 100F, HeaderText = "Description",
- StyleInfo = new GridStyleInfo { VerticalAlignment = VerticalAlignment.Center }
- });
- Gantt.GanttGrid.Columns.Add(new GridTreeColumn("StartDate")
- {
- Width = 70F, HeaderText = "Start",
- StyleInfo = new GridStyleInfo
- { VerticalAlignment = VerticalAlignment.Center, Format = "dd MMM yy", HorizontalAlignment = HorizontalAlignment.Center }
- });
- Gantt.GanttGrid.Columns.Add(new GridTreeColumn("Manpower")
- {
- Width = 60F, HeaderText = "Hrs",
- StyleInfo = new GridStyleInfo { VerticalAlignment = VerticalAlignment.Center, HorizontalAlignment = HorizontalAlignment.Center }
- });
- Gantt.GanttGrid.Columns.Add(new GridTreeColumn("Percentage")
- {
- Width = 40F, HeaderText = "%",
- StyleInfo = new GridStyleInfo
- { VerticalAlignment = VerticalAlignment.Center, Format = "#0.##%", HorizontalAlignment = HorizontalAlignment.Center }
- });
- Gantt.GanttGrid.Columns.Add(new GridTreeColumn("FinishDate")
- {
- Width = 70F, HeaderText = "Due",
- StyleInfo = new GridStyleInfo
- { VerticalAlignment = VerticalAlignment.Center, Format = "dd MMM yy", HorizontalAlignment = HorizontalAlignment.Center }
- });
- }
- }
- public void LoadStages(Guid parentid)
- {
- var rows = _stages.Rows.Where(r => r.Get<JobStage, Guid>(c => c.Parent.ID).Equals(parentid));
- foreach (var row in rows)
- {
- var parent = _tasks.FirstOrDefault(x => x.ID.Equals(parentid));
- var task = new GanttTask
- {
- TaskName = row.Get<JobStage, string>(c => c.Name),
- StartDate = row.Get<JobStage, DateTime>(c => c.StartDate),
- FinishDate = row.Get<JobStage, DateTime>(c => c.EndDate),
- Manpower = TimeSpan.FromHours(row.Get<JobStage, double>(c => c.TotalHours)),
- ID = row.Get<JobStage, Guid>(c => c.ID),
- TaskId = (int)row.Get<JobStage, long>(c => c.Sequence)
- };
- if (parent != null)
- parent.Child.Add(task);
- else
- _tasks.Add(task);
- LoadStages(task.ID);
- }
- }
- private void LoadRelationships()
- {
- foreach (var row in _relationships.Rows)
- {
- var predtask = _tasks.FirstOrDefault(x => x.ID == row.Get<JobStageRelationship, Guid>(c => c.Predecessor.ID));
- var succtask = _tasks.FirstOrDefault(x => x.ID == row.Get<JobStageRelationship, Guid>(c => c.Successor.ID));
- if (predtask != null && succtask != null)
- {
- var type = row.Get<JobStageRelationship, GanttRelationshipType>(x => x.Type);
- var relationship = type == GanttRelationshipType.FinishToFinish
- ? GanttTaskRelationship.FinishToFinish
- : type == GanttRelationshipType.FinishToStart
- ? GanttTaskRelationship.FinishToStart
- : type == GanttRelationshipType.StartToFinish
- ? GanttTaskRelationship.StartToFinish
- : GanttTaskRelationship.StartToStart;
- succtask.Predecessor.Add(new Predecessor { GanttTaskIndex = predtask.TaskId, GanttTaskRelationship = relationship });
- }
- }
- }
- private void DeleteStage_Click(object sender, RoutedEventArgs e)
- {
- var task = Gantt.SelectedItems.FirstOrDefault() as GanttTask;
- if (task == null)
- {
- MessageBox.Show("Selected Item is Null!");
- return;
- }
- var stageids = new List<Guid> { task.ID };
- var relids = _relationships.Rows
- .Where(r => r.Get<JobStageRelationship, Guid>(c => c.Predecessor.ID).Equals(task.ID) ||
- r.Get<JobStageRelationship, Guid>(c => c.Successor.ID).Equals(task.ID))
- .Select(r => r.Get<JobStageRelationship, Guid>(c => c.ID)).ToList();
- GetChildren(task.ID, stageids, relids);
- var stages = stageids.Select(x => new JobStage { ID = x }).ToArray();
- new Client<JobStage>().Delete(stages, "");
- var relationships = relids.Select(x => new JobStageRelationship { ID = x }).ToArray();
- new Client<JobStageRelationship>().Delete(relationships, "");
- Refresh();
- }
- private void GetChildren(Guid taskid, List<Guid> stages, List<Guid> relationships)
- {
- var stageids = _stages.Rows.Where(r => r.Get<JobStage, Guid>(c => c.Parent.ID).Equals(taskid))
- .Select(r => r.Get<JobStage, Guid>(c => c.ID));
- var relids = _relationships.Rows
- .Where(r => r.Get<JobStageRelationship, Guid>(c => c.Predecessor.ID).Equals(taskid) ||
- r.Get<JobStageRelationship, Guid>(c => c.Successor.ID).Equals(taskid))
- .Select(r => r.Get<JobStageRelationship, Guid>(c => c.ID));
- relationships.AddRange(relids.Where(x => !relationships.Contains(x)));
- stageids = stageids.Where(x => !stages.Contains(x)).ToArray();
- foreach (var stageid in stageids)
- {
- stages.Add(stageid);
- GetChildren(stageid, stages, relationships);
- }
- }
- private void AddStage_Click(object sender, RoutedEventArgs e)
- {
- var menu = new ContextMenu();
- var addstage = new MenuItem { Header = "Add Stage to Job" };
- addstage.Click += NewStage_Click;
- menu.Items.Add(addstage);
- if (Gantt.SelectedItems.Any())
- {
- var addtask = new MenuItem { Header = "Add Task to Stage" };
- addtask.Click += NewTaskClick;
- menu.Items.Add(addtask);
- }
- menu.IsOpen = true;
- }
- private void DoEdit(JobStage stage)
- {
- if (grid == null)
- using (new WaitCursor())
- {
- grid = new JobStagesGrid();
- grid.OnCustomiseEditor += (o, i, c, e) =>
- {
- if (c.ColumnName.Equals("StartDate") || c.ColumnName.Equals("EndDate") || c.ColumnName.Equals("WorkDays"))
- {
- var haschild = stage.ID != Guid.Empty && _stages.Rows.Any(r => r.Get<JobStage, Guid>(x => x.Parent.ID) == stage.ID);
- e.Editable = haschild ? Editable.Hidden : Editable.Enabled;
- }
- };
- }
- if (grid.EditItems(new[] { stage })) Refresh();
- }
- //private void CheckParentDates(JobStage stage)
- //{
- // JobStage parent = Stages.FirstOrDefault(x => x.ID.Equals(stage.Parent.ID));
- // if (parent != null)
- // {
- // // Calculate Start / Finish Dates
- // DateTime start = stage.StartDate;
- // DateTime finish = stage.EndDate;
- // foreach (var child in Stages.Where(x => x.Parent.ID.Equals(parent.ID)))
- // {
- // start = start > child.StartDate ? child.StartDate : start;
- // finish = finish < child.EndDate ? child.EndDate : finish;
- // }
- // // Synchronise Parent Start / Finish Dates
- // if (parent.StartDate != start)
- // parent.StartDate = start;
- // if (parent.EndDate != finish)
- // parent.EndDate = finish;
- // // Update if necessary
- // if (parent.IsChanged())
- // {
- // new Client<JobStage>().Save(parent, "");
- // CheckParentDates(parent);
- // }
- // }
- //}
- private void NewStage_Click(object sender, RoutedEventArgs e)
- {
- var stage = new JobStage();
- stage.Name = "New Stage";
- stage.Job.ID = ParentID;
- stage.StartDate = DateTime.Today;
- stage.EndDate = DateTime.Today;
- DoEdit(stage);
- }
- private void NewTaskClick(object sender, RoutedEventArgs e)
- {
- var task = Gantt.SelectedItems.FirstOrDefault() as GanttTask;
- if (task == null)
- {
- MessageBox.Show("Selected Item is Null!");
- return;
- }
- var parent = _stages.Rows.FirstOrDefault(r => r.Get<JobStage, Guid>(c => c.ID).Equals(task.ID));
- if (parent == null)
- {
- MessageBox.Show("Cannot find Parent!");
- return;
- }
- var stage = new JobStage();
- stage.Name = "New Task";
- stage.Job.ID = ParentID;
- stage.Parent.ID = task.ID;
- stage.StartDate = _stages.Rows.Any(r => r.Get<JobStage, Guid>(c => c.Parent.ID).Equals(task.ID)) ? task.FinishDate : task.StartDate;
- stage.EndDate = task.FinishDate;
- DoEdit(stage);
- }
- private void EditStage_Click(object sender, RoutedEventArgs e)
- {
- var task = Gantt.SelectedItems.FirstOrDefault() as GanttTask;
- if (task == null)
- {
- MessageBox.Show("Selected Item is Null!");
- return;
- }
- var stage = _stages.Rows.FirstOrDefault(r => r.Get<JobStage, Guid>(c => c.ID).Equals(task.ID));
- if (stage == null)
- {
- MessageBox.Show("Cannot find Stage!");
- return;
- }
- DoEdit(stage.ToObject<JobStage>());
- }
- private void ImportFile_Click(object sender, RoutedEventArgs e)
- {
- var dlg = new OpenFileDialog();
- dlg.Filter = "Microsoft Project Files (*.mpp)|*.mpp";
- if (dlg.ShowDialog() == true)
- {
- using (new WaitCursor())
- {
- Progress.Show("Clearing Old Stages (0%)");
- var dstages = _stages.Rows.Select(x => x.ToObject<JobStage>()).ToArray();
- new Client<JobStage>().Delete(dstages, "Deleting Due to Import");
- _stages.Rows.Clear();
- var drels = _relationships.Rows.Select(x => x.ToObject<JobStageRelationship>()).ToArray();
- new Client<JobStageRelationship>().Delete(drels, "Deleting Due to Import");
- _relationships.Rows.Clear();
- Progress.SetMessage("Loading Project File (20%)");
- var stages = new List<JobStage>();
- var relationships = new List<JobStageRelationship>();
- ProjectReader reader = new UniversalProjectReader();
- var project = reader.read(dlg.FileName);
- Progress.SetMessage("Loading Stages (50%)");
- // Create the raw stages
- foreach (Task task in project.getTasks())
- {
- var stage = new JobStage
- {
- Name = task.getName(),
- StartDate = task.getStart().ToDateTime().Date,
- EndDate = task.getFinish().ToDateTime().Date,
- Sequence = task.getID().longValue()
- };
- stage.Job.ID = ParentID;
- stages.Add(stage);
- }
- if (stages.Any())
- new Client<JobStage>().Save(stages, "Imported From File");
- Progress.SetMessage("Building Links (80%)");
- // Set up the parent links
- foreach (Task task in project.getTasks())
- {
- var stage = stages.FirstOrDefault(x => x.Sequence.Equals(task.getID().longValue()));
- if (task.getParentTask() != null)
- {
- var parent = stages.FirstOrDefault(x => x.Sequence.Equals(task.getParentTask().getID().longValue()));
- stage.Parent.ID = parent.ID;
- }
- stage.IsHeader = task.hasChildTasks();
- stage.TradesHours = task.getWork().getDuration();
- if (task.getPredecessors() != null && !task.getPredecessors().isEmpty())
- {
- var rels = task.getPredecessors().ToIEnumerable<Relation>().ToArray();
- foreach (var rel in rels)
- {
- var predecessor = stages.FirstOrDefault(x => x.Sequence.Equals(rel.getTargetTask().getID().longValue()));
- var successor = stages.FirstOrDefault(x => x.Sequence.Equals(rel.getSourceTask().getID().longValue()));
- if (predecessor != null && successor != null)
- {
- var newrel = new JobStageRelationship();
- newrel.Parent.ID = ParentID;
- newrel.Predecessor.ID = predecessor.ID;
- newrel.Successor.ID = successor.ID;
- newrel.Type = rel.getType() == RelationType.FINISH_FINISH
- ? GanttRelationshipType.FinishToFinish
- : rel.getType() == RelationType.FINISH_START
- ? GanttRelationshipType.FinishToStart
- : rel.getType() == RelationType.START_FINISH
- ? GanttRelationshipType.StartToFinish
- : GanttRelationshipType.StartToStart;
- newrel.Offset = (int)rel.getLag().getDuration();
- relationships.Add(newrel);
- }
- }
- }
- }
- if (stages.Any(x => x.IsChanged()))
- new Client<JobStage>().Save(stages.Where(x => x.IsChanged()), "");
- if (relationships.Any())
- new Client<JobStageRelationship>().Save(relationships, "Imported from Project File");
- Progress.Close();
- }
- MessageBox.Show("Project File Imported Successfully!");
- Refresh();
- }
- }
- private void ExportFile_Click(object sender, RoutedEventArgs e)
- {
- var dlg = new SaveFileDialog();
- //dlg.Filter = "Microsoft Project Files (*.mspdi)|*.mspdi;Excel Files (*.xlsx)|*.xlsx";
- dlg.Filter = "Excel Files (*.xlsx)|*.xlsx";
- dlg.FileName = "Project Plan";
- if (dlg.ShowDialog() == true)
- {
- if (dlg.FilterIndex == 0)
- ExportToExcel(dlg.FileName);
- else if (dlg.FilterIndex == 1)
- ExportToProject(dlg.FileName);
- else
- MessageBox.Show(string.Format("Unknown Filter Index: {0}", dlg.FilterIndex));
- }
- }
- private void ExportToProject(string filename)
- {
- MessageBox.Show("Not Yet Implemented");
- }
- private void GetLevel(CoreRow row, ref int level)
- {
- if (row == null || !Entity.IsEntityLinkValid<JobStage, JobStageLink>(x => x.Parent, row))
- return;
- level++;
- GetLevel(_stages.Rows.FirstOrDefault(r => r.Get<JobStage, Guid>(c => c.ID).Equals(row.Get<JobStage, Guid>(c => c.Parent.ID))), ref level);
- }
- private void ExportToExcel(string filename)
- {
- var excelEngine = new ExcelEngine();
- var application = excelEngine.Excel;
- var myWorkbook = excelEngine.Excel.Workbooks.Add();
- myWorkbook.Version = ExcelVersion.Excel2007;
- var mySheet = myWorkbook.Worksheets[0];
- mySheet.Name = "Project Planning";
- var startcol = 1;
- foreach (var row in _stages.Rows)
- {
- var level = 1;
- GetLevel(row, ref level);
- if (level > startcol)
- startcol = level;
- mySheet.Range[row.Index + 2, level].Value2 = row.Get<JobStage, string>(c => c.Name);
- }
- foreach (var row in _stages.Rows)
- {
- mySheet.Range[row.Index + 2, startcol + 1].Value2 = string.Format("{0:dd/MM/yyyy}", row.Get<JobStage, DateTime>(c => c.StartDate));
- mySheet.Range[row.Index + 2, startcol + 2].Value2 = string.Format("{0:dd/MM/yyyy}", row.Get<JobStage, DateTime>(c => c.EndDate));
- }
- for (var iCol = 1; iCol < startcol; iCol++)
- mySheet.SetColumnWidth(iCol, 2);
- mySheet.SetColumnWidth(startcol, 30);
- mySheet.SetColumnWidth(startcol + 1, 12);
- mySheet.SetColumnWidth(startcol + 2, 12);
- mySheet.Range[1, 1].Text = "Stage Description";
- mySheet.Range[1, startcol + 1].Text = "Start Date";
- mySheet.Range[1, startcol + 2].Text = "Finish Date";
- foreach (var row in mySheet.UsedRange.Rows)
- {
- row.RowHeight += 5;
- row.VerticalAlignment = ExcelVAlign.VAlignCenter;
- }
- try
- {
- myWorkbook.SaveAs(filename, ExcelSaveType.SaveAsXLS);
- Process.Start(new ProcessStartInfo(filename) { UseShellExecute = true });
- }
- catch (Exception e2)
- {
- MessageBox.Show("Error saving spreadsheet!\n\n" + e2.Message);
- }
- }
- private void Task_PropertyChanged(object sender, PropertyChangedEventArgs args)
- {
- if (!IsReady)
- return;
- if (!string.Equals(args.PropertyName, "StartDate") && !string.Equals(args.PropertyName, "FinishDate"))
- return;
- var task = sender as GanttTask;
- if (task == null)
- return;
- var row = _stages.Rows.FirstOrDefault(r => r.Get<JobStage, Guid>(x => x.ID) == task.ID);
- if (row == null)
- return;
- var stage = row?.ToObject<JobStage>();
- var bChanged = false;
- if (string.Equals(args.PropertyName, "FinishDate"))
- {
- stage.EndDate = task.FinishDate.Date;
- bChanged = true;
- }
- else if (string.Equals(args.PropertyName, "StartDate"))
- {
- stage.StartDate = task.StartDate.Date;
- bChanged = true;
- }
- if (bChanged)
- {
- row.Set<JobStage, DateTime>(x => x.EndDate, stage.EndDate.Date);
- row.Set<JobStage, DateTime>(x => x.StartDate, stage.StartDate.Date);
- new Client<JobStage>().Save(stage, "Updated by Planner", (o, e) => { });
- }
- }
- private void Gantt_RelationshipEstablished(object sender, GanttRelationshipEstablishedEventArgs args)
- {
- var pred = args.StartTask as GanttTask;
- var succ = args.EndTask as GanttTask;
- if (pred == null || pred.IsMileStone)
- throw new Exception("Cannot make a connection here");
- if (succ == null || succ.IsMileStone)
- throw new Exception("Cannot make a connection here");
- var relationship = new JobStageRelationship();
- relationship.Parent.ID = ParentID;
- relationship.Predecessor.ID = pred.ID;
- relationship.Successor.ID = succ.ID;
- relationship.Type = args.Relationship == GanttTaskRelationship.FinishToFinish
- ? GanttRelationshipType.FinishToFinish
- : args.Relationship == GanttTaskRelationship.FinishToStart
- ? GanttRelationshipType.FinishToStart
- : args.Relationship == GanttTaskRelationship.StartToFinish
- ? GanttRelationshipType.StartToFinish
- : GanttRelationshipType.StartToStart;
- new Client<JobStageRelationship>().Save(relationship, "", (o, e) =>
- {
- var row = _relationships.NewRow();
- _relationships.LoadRow(row, relationship);
- _relationships.Rows.Add(row);
- });
- }
- private void GanttContextMenu_Opened(object sender, RoutedEventArgs e)
- {
- var task = Gantt.SelectedItems.FirstOrDefault() as GanttTask;
- UnlinkTaskMenu.IsEnabled = task != null && task.Predecessor.Any();
- UnlinkTaskMenu.Tag = task;
- }
- private void UnlinkTaskMenu_Click(object sender, RoutedEventArgs e)
- {
- var successor = (sender as MenuItem).Tag as GanttTask;
- if (successor == null)
- return;
- var deletes = new List<JobStageRelationship>();
- foreach (var link in successor.Predecessor)
- {
- var predecessor = _tasks.FirstOrDefault(x => x.TaskId == link.GanttTaskIndex);
- if (predecessor != null)
- {
- var rows = _relationships.Rows.Where(r =>
- r.Get<KanbanRelationship, Guid>(c => c.Successor.ID).Equals(successor.ID) &&
- r.Get<KanbanRelationship, Guid>(c => c.Predecessor.ID).Equals(predecessor.ID)).ToArray();
- foreach (var row in rows)
- {
- deletes.Add(row.ToObject<JobStageRelationship>());
- _relationships.Rows.Remove(row);
- }
- }
- }
- if (deletes.Any())
- new Client<JobStageRelationship>().Delete(deletes, "", (o, args) => { });
- successor.Predecessor.Clear();
- }
- private void GanttGrid_MouseDoubleClick(object sender, MouseButtonEventArgs e)
- {
- var task = Gantt.SelectedItems.FirstOrDefault() as GanttTask;
- if (task == null)
- return;
- var row = _stages.Rows.FirstOrDefault(r => r.Get<Kanban, Guid>(x => x.ID) == task.ID);
- var stage = row?.ToObject<JobStage>();
- if (stage != null)
- DoEdit(stage);
- }
- private void EditTask_Click(object sender, RoutedEventArgs e)
- {
- var task = Gantt.SelectedItems.FirstOrDefault() as GanttTask;
- if (task == null)
- return;
- var row = _stages.Rows.FirstOrDefault(r => r.Get<Kanban, Guid>(x => x.ID) == task.ID);
- var stage = row?.ToObject<JobStage>();
- if (stage != null)
- DoEdit(stage);
- }
- }
- }
|