private void ReloadButton_Click(object sender, RoutedEventArgs e)
        {
            // Reload the selected schedule
            foreach (var data in linkDataGrid.SelectedItems)
            {
                LinkData selectedRow = (LinkData)data;

                for (int i = 0; i < elementIds.Count; i++)
                {
                    try
                    {
                        int intValue = selectedRow.ElementId;
                        if (elementIds[i].IntegerValue == intValue)
                        {
                            // get the full path
                            string docPath;
                            if (doc.IsWorkshared)
                            {
                                docPath = ModelPathUtils.ConvertModelPathToUserVisiblePath(doc.GetWorksharingCentralModelPath());
                            }
                            else
                            {
                                docPath = doc.PathName;
                            }
                            string selectedPath = string.Empty;
                            if (selectedRow.PathType == PathType.Absolute)
                            {
                                selectedPath = selectedRow.Path;
                            }
                            else
                            {
                                selectedPath = PathExchange.GetFullPath(selectedRow.Path, docPath);
                            }

                            // reload this file
                            if (System.IO.File.Exists(selectedPath))
                            {
                                // read and reload the file.
                                Scheduler creator = new Scheduler();
                                creator.ModifySchedule(doc, elementIds[i], paths[i], worksheets[i], "Reload Excel Schedule", pathTypes[i], contentOnly);
                            }
                        }
                    }
                    catch (Exception ex)
                    {
                        MessageBox.Show("Error\n" + ex.Message);
                    }
                }
            }
        }
        public void DocumentOpened(object sender, DocumentOpenedEventArgs e)
        {
            Document doc = e.Document;

            if (doc.IsFamilyDocument)
            {
                return;
            }

            Schema schema = Schema.Lookup(schemaGUID);

            if (schema == null || !schema.IsValidObject)
            {
                return;
            }

            // Check to see if there is out-dated data stored in ProjectInformation
            Entity entity = null;

            entity = doc.ProjectInformation.GetEntity(schema);
            if (entity != null && entity.IsValid())
            {
                // Need to transition the data to a datastorage object.
                // First make sure this isn't a workshared document with the ProjectInfo already checked out by another user
                // If it's checked out by another person, we'll just skip this since we can't fix it now.
                if (doc.IsWorkshared && WorksharingUtils.GetCheckoutStatus(doc, doc.ProjectInformation.Id) == CheckoutStatus.OwnedByOtherUser)
                {
                    return;
                }

                // Otherwise, lets transition the data from the old to the new.
                if (entity.Get <IList <ElementId> >("ScheduleId") != null)
                {
                    // Get the information from the ProjectInformation entity
                    var schedIds = entity.Get <IList <ElementId> >("ScheduleId").ToList();
                    var paths    = entity.Get <IList <string> >("ExcelFilePath").ToList();
                    var wsNames  = entity.Get <IList <string> >("WorksheetName").ToList();
                    var dts      = entity.Get <IList <string> >("DateTime").ToList();
                    var pTypes   = entity.Get <IList <int> >("PathType")?.ToList() ?? new List <int>();

                    // Purge the old Schema and Entity, then assign the data to a new Schema and DataStorage element
                    RebuildSchema(doc, schema, schedIds, paths, wsNames, dts, pTypes);
                }
            }

            // Find if a datstorage element exists now and update as needed.
            DataStorage ds = new FilteredElementCollector(doc).OfClass(typeof(DataStorage)).Where(x => x.Name.Equals(dsName)).Cast <DataStorage>().FirstOrDefault();

            // Get the ExcelScheduleEntity from the data storage and verify its valid
            ExcelScheduleEntity ent = ds?.GetEntity <ExcelScheduleEntity>();

            if (ent == null)
            {
                return;
            }

            // Check if any schedules need to be updated
            List <int>      modifyIndices = new List <int>();
            List <DateTime> modDateTimes  = new List <DateTime>();

            for (int i = 0; i < ent.ScheduleId.Count; i++)
            {
                string currentFilePath;
                string docPath;
                if (doc.IsWorkshared)
                {
                    docPath = ModelPathUtils.ConvertModelPathToUserVisiblePath(doc.GetWorksharingCentralModelPath());
                }
                else
                {
                    docPath = doc.PathName;
                }

                if ((PathType)ent.PathType[i] == PathType.Absolute)
                {
                    currentFilePath = ent.ExcelFilePath[i];
                }
                else
                {
                    currentFilePath = PathExchange.GetFullPath(ent.ExcelFilePath[i], docPath);
                }

                // Get the file write time as UTC
                DateTime modTime    = new FileInfo(currentFilePath).LastWriteTimeUtc;
                DateTime storedTime = Convert.ToDateTime(ent.DateTime[i]);

                // Make sure the save time isn't more or less the same as stored.
                if ((modTime - storedTime).Seconds > 1)
                {
                    modifyIndices.Add(i);
                    modDateTimes.Add(modTime);
                }
            }

            if (modifyIndices.Count == modDateTimes.Count && modifyIndices.Count > 0)
            {
                IntPtr statusBar = FindWindowEx(RevitHandle, IntPtr.Zero, "msctls_statusbar32", "");
                foreach (int i in modifyIndices)
                {
                    if (statusBar != IntPtr.Zero)
                    {
                        SetWindowText(statusBar, string.Format("Updating Excel Schedule {0}.", ent.WorksheetName[modifyIndices[i]]));
                    }
                    Scheduler scheduler = new Scheduler();
                    scheduler.ModifySchedule(doc, ent.ScheduleId[modifyIndices[i]], ent.ExcelFilePath[modifyIndices[i]],
                                             ent.WorksheetName[modifyIndices[i]], "Update Excel Schedule", ent.PathType[modifyIndices[i]],
                                             Properties.Settings.Default.reloadValuesOnly);

                    ent.DateTime[modifyIndices[i]] = modDateTimes[i].ToString();
                }
                if (statusBar != IntPtr.Zero)
                {
                    SetWindowText(statusBar, "");
                }

                // change the dateTimes
                using (Transaction t = new Transaction(doc, "Update schedule date"))
                {
                    t.Start();
                    ds.SetEntity(ent);
                    t.Commit();
                }

                // Write to home
                RevitCommon.FileUtils.WriteToHome("Excel Import - Document Open Reload", doc.Application.VersionName, doc.Application.Username);
            }
        }
        /// <summary>
        ///
        /// </summary>
        /// <param name="filePath"></param>
        /// <param name="sched"></param>
        /// <param name="doc"></param>
        /// <param name="pt"></param>
        /// <param name="contentOnly"></param>
        public void AddScheduleData(string filePath, ViewSchedule sched, Document doc, PathType pt, bool contentOnly)
        {
            string docPath;

            if (doc.IsWorkshared)
            {
                docPath = ModelPathUtils.ConvertModelPathToUserVisiblePath(doc.GetWorksharingCentralModelPath());
            }
            else
            {
                docPath = doc.PathName;
            }

            string fullPath;

            if (pt == PathType.Absolute)
            {
                fullPath = filePath;
            }
            else
            {
                fullPath = PathExchange.GetFullPath(filePath, docPath);
            }

            // Get the file path
            excelFilePath = fullPath;
            if (!File.Exists(excelFilePath))
            {
                return;
            }


            // read the Excel file and create the schedule
            Excel.Application excelApp   = new Excel.Application();
            Excel.Workbook    workbook   = excelApp.Workbooks.Open(excelFilePath);
            Excel.Sheets      worksheets = workbook.Worksheets;
            worksheet = null;
            foreach (Excel.Worksheet ws in worksheets)
            {
                if (ws.Name.Trim() == sched.Name.Trim())
                {
                    worksheet = ws;
                }
            }

            if (worksheet == null)
            {
                return;
            }

            //TaskDialog.Show("Test", "Worksheet found");
            // Find the ThinLine linestyle
            CategoryNameMap lineSubCats   = doc.Settings.Categories.get_Item(BuiltInCategory.OST_Lines).SubCategories;
            ElementId       thinLineStyle = new ElementId(-1);
            ElementId       hairlineStyle = new ElementId(-1);
            ElementId       thinStyle     = new ElementId(-1);
            ElementId       mediumStyle   = new ElementId(-1);
            ElementId       thickStyle    = new ElementId(-1);

            foreach (Category style in lineSubCats)
            {
                if (style.Name == "Thin Lines")
                {
                    thinLineStyle = style.Id;
                }

                if (style.GetGraphicsStyle(GraphicsStyleType.Projection).Id.IntegerValue == Properties.Settings.Default.hairlineInt)
                {
                    hairlineStyle = style.Id;
                }
                else if (style.GetGraphicsStyle(GraphicsStyleType.Projection).Id.IntegerValue == Properties.Settings.Default.thinInt)
                {
                    thinStyle = style.Id;
                }
                else if (style.GetGraphicsStyle(GraphicsStyleType.Projection).Id.IntegerValue == Properties.Settings.Default.mediumInt)
                {
                    mediumStyle = style.Id;
                }
                else if (style.GetGraphicsStyle(GraphicsStyleType.Projection).Id.IntegerValue == Properties.Settings.Default.thickInt)
                {
                    thickStyle = style.Id;
                }
            }

            if (hairlineStyle.IntegerValue == -1)
            {
                hairlineStyle = thinLineStyle;
            }
            if (thinStyle.IntegerValue == -1)
            {
                thinStyle = thinLineStyle;
            }
            if (mediumStyle.IntegerValue == -1)
            {
                mediumStyle = thinLineStyle;
            }
            if (thickStyle.IntegerValue == -1)
            {
                thickStyle = thinLineStyle;
            }



            // Find out how many rows and columns we need in the schedule
            Excel.Range rng = ActualUsedRange(worksheet);

            Excel.Range range       = rng;
            int         rowCount    = range.Rows.Count;
            int         columnCount = range.Columns.Count;

            // Get the schedule body to set the overall width
            TableSectionData bodyData = sched.GetTableData().GetSectionData(SectionType.Body);

            if (!contentOnly)
            {
                double schedWidth = range.Columns.Width;
                try
                {
                    bodyData.SetColumnWidth(0, (schedWidth * pointWidthInches) / 12);
                }
                catch { }
            }

            // Get the header body to create the necessary rows and columns
            TableSectionData headerData = sched.GetTableData().GetSectionData(SectionType.Header);

            if (!contentOnly)
            {
                //TaskDialog.Show("Test: ", "Row Count: " + rowCount.ToString() + "\nColumn Count:  " + columnCount.ToString());
                for (int i = 0; i < columnCount - 1; i++)
                {
                    headerData.InsertColumn(1);
                }
                for (int i = 0; i < rowCount - 1; i++)
                {
                    headerData.InsertRow(1);
                }

                for (int i = 1; i <= headerData.NumberOfColumns; i++)
                {
                    try
                    {
                        Excel.Range cell = worksheet.Cells[1, i];
                        headerData.SetColumnWidth(i - 1, (cell.Width * pointWidthInches) / 12);
                    }
                    catch { }
                }

                for (int i = 1; i <= headerData.NumberOfRows; i++)
                {
                    try
                    {
                        Excel.Range cell = worksheet.Cells[i, 1];

                        headerData.SetRowHeight(i - 1, (cell.Height * pointWidthInches) / 12);
                    }
                    catch { }
                }
            }



            List <TableMergedCell> mergedCells = new List <TableMergedCell>();
            int errorCount = 0;

            for (int i = 1; i <= headerData.NumberOfRows; i++)        // Iterate through rows of worksheet data
            {
                for (int j = 1; j <= headerData.NumberOfColumns; j++) // Iterate through columns of worksheet data
                {
                    // Get the current cell in the worksheet grid
                    Excel.Range cell = worksheet.Cells[i, j];

                    // If adjusting the formatting or adding content is not necessary,
                    // just update the text content. This is via a UI switch.
                    if (contentOnly)
                    {
                        try
                        {
                            headerData.SetCellText(i - 1, j - 1, cell.Text);
                            continue;
                        }
                        catch {
                            errorCount++;
                            continue;
                        }
                    }

                    Excel.Font          font       = cell.Font;
                    Excel.DisplayFormat dispFormat = cell.DisplayFormat;

                    TableCellStyle cellStyle = new TableCellStyle();
                    TableCellStyleOverrideOptions styleOverride = cellStyle.GetCellStyleOverrideOptions();

                    Excel.Border topEdge    = cell.Borders.Item[Excel.XlBordersIndex.xlEdgeTop];
                    Excel.Border bottomEdge = cell.Borders.Item[Excel.XlBordersIndex.xlEdgeBottom];
                    Excel.Border leftEdge   = cell.Borders.Item[Excel.XlBordersIndex.xlEdgeLeft];
                    Excel.Border rightEdge  = cell.Borders.Item[Excel.XlBordersIndex.xlEdgeRight];

                    // Determine Bottom Edge Line Style
                    if (bottomEdge.LineStyle == (int)Excel.XlLineStyle.xlLineStyleNone)
                    {
                        cellStyle.BorderBottomLineStyle = new ElementId(-1);
                    }
                    else
                    {
                        switch (bottomEdge.Weight)
                        {
                        case (int)Excel.XlBorderWeight.xlHairline:
                            cellStyle.BorderBottomLineStyle = hairlineStyle;
                            break;

                        case (int)Excel.XlBorderWeight.xlThin:
                            cellStyle.BorderBottomLineStyle = thinStyle;
                            break;

                        case (int)Excel.XlBorderWeight.xlMedium:
                            cellStyle.BorderBottomLineStyle = mediumStyle;
                            break;

                        case (int)Excel.XlBorderWeight.xlThick:
                            cellStyle.BorderBottomLineStyle = thickStyle;
                            break;
                        }
                    }


                    // Determine Top Edge Line Style
                    if (topEdge.LineStyle == (int)Excel.XlLineStyle.xlLineStyleNone)
                    {
                        cellStyle.BorderTopLineStyle = new ElementId(-1);
                    }
                    else
                    {
                        switch (topEdge.Weight)
                        {
                        case (int)Excel.XlBorderWeight.xlHairline:
                            cellStyle.BorderTopLineStyle = hairlineStyle;
                            break;

                        case (int)Excel.XlBorderWeight.xlThin:
                            cellStyle.BorderTopLineStyle = thinStyle;
                            break;

                        case (int)Excel.XlBorderWeight.xlMedium:
                            cellStyle.BorderTopLineStyle = mediumStyle;
                            break;

                        case (int)Excel.XlBorderWeight.xlThick:
                            cellStyle.BorderTopLineStyle = thickStyle;
                            break;
                        }
                    }

                    // Determine Left Edge Line Style
                    if (leftEdge.LineStyle == (int)Excel.XlLineStyle.xlLineStyleNone)
                    {
                        cellStyle.BorderLeftLineStyle = new ElementId(-1);
                    }
                    else
                    {
                        switch (leftEdge.Weight)
                        {
                        case (int)Excel.XlBorderWeight.xlHairline:
                            cellStyle.BorderLeftLineStyle = hairlineStyle;
                            break;

                        case (int)Excel.XlBorderWeight.xlThin:
                            cellStyle.BorderLeftLineStyle = thinStyle;
                            break;

                        case (int)Excel.XlBorderWeight.xlMedium:
                            cellStyle.BorderLeftLineStyle = mediumStyle;
                            break;

                        case (int)Excel.XlBorderWeight.xlThick:
                            cellStyle.BorderLeftLineStyle = thickStyle;
                            break;
                        }
                    }

                    // Determine Right Edge Line Style
                    if (rightEdge.LineStyle == (int)Excel.XlLineStyle.xlLineStyleNone)
                    {
                        cellStyle.BorderRightLineStyle = new ElementId(-1);
                    }
                    else
                    {
                        switch (rightEdge.Weight)
                        {
                        case (int)Excel.XlBorderWeight.xlHairline:
                            cellStyle.BorderRightLineStyle = hairlineStyle;
                            break;

                        case (int)Excel.XlBorderWeight.xlThin:
                            cellStyle.BorderRightLineStyle = thinStyle;
                            break;

                        case (int)Excel.XlBorderWeight.xlMedium:
                            cellStyle.BorderRightLineStyle = mediumStyle;
                            break;

                        case (int)Excel.XlBorderWeight.xlThick:
                            cellStyle.BorderRightLineStyle = thickStyle;
                            break;
                        }
                    }
                    // Border Styles are always overridden
                    styleOverride.BorderBottomLineStyle = true;
                    styleOverride.BorderTopLineStyle    = true;
                    styleOverride.BorderLeftLineStyle   = true;
                    styleOverride.BorderRightLineStyle  = true;

                    if (styleOverride.BorderBottomLineStyle || styleOverride.BorderTopLineStyle ||
                        styleOverride.BorderLeftLineStyle || styleOverride.BorderRightLineStyle)
                    {
                        styleOverride.BorderLineStyle = true;
                    }

                    // Get Background color and font name
                    System.Drawing.Color backGroundColor = System.Drawing.ColorTranslator.FromOle((int)cell.Interior.Color);
                    cellStyle.BackgroundColor     = new Color(backGroundColor.R, backGroundColor.G, backGroundColor.B);
                    styleOverride.BackgroundColor = true;
                    cellStyle.FontName            = cell.Font.Name;
                    styleOverride.Font            = true;

                    // Determine Horizontal Alignment
                    // If its not set to left, right or center, do not modify
                    switch (dispFormat.HorizontalAlignment)
                    {
                    case (int)Excel.XlHAlign.xlHAlignLeft:
                        cellStyle.FontHorizontalAlignment = HorizontalAlignmentStyle.Left;
                        styleOverride.HorizontalAlignment = true;
                        break;

                    case (int)Excel.XlHAlign.xlHAlignRight:
                        cellStyle.FontHorizontalAlignment = HorizontalAlignmentStyle.Right;
                        styleOverride.HorizontalAlignment = true;
                        break;

                    case (int)Excel.XlHAlign.xlHAlignGeneral:     // No specific style assigned
                        // Check if it's a number which is typically right aligned
                        if (double.TryParse(cell.Text, out double alignTest))
                        {
                            cellStyle.FontHorizontalAlignment = HorizontalAlignmentStyle.Right;
                            styleOverride.HorizontalAlignment = true;
                        }
                        else     // Assume text and left align it
                        {
                            cellStyle.FontHorizontalAlignment = HorizontalAlignmentStyle.Left;
                            styleOverride.HorizontalAlignment = true;
                        }
                        break;

                    case (int)Excel.XlHAlign.xlHAlignCenter:
                        cellStyle.FontHorizontalAlignment = HorizontalAlignmentStyle.Center;
                        styleOverride.HorizontalAlignment = true;
                        break;
                    }

                    // Get the vertical alignment of the cell
                    switch (dispFormat.VerticalAlignment)
                    {
                    case (int)Excel.XlVAlign.xlVAlignBottom:
                        cellStyle.FontVerticalAlignment = VerticalAlignmentStyle.Bottom;
                        styleOverride.VerticalAlignment = true;
                        break;

                    case (int)Excel.XlVAlign.xlVAlignTop:
                        cellStyle.FontVerticalAlignment = VerticalAlignmentStyle.Top;
                        styleOverride.VerticalAlignment = true;
                        break;

                    default:
                        cellStyle.FontVerticalAlignment = VerticalAlignmentStyle.Middle;
                        styleOverride.VerticalAlignment = true;
                        break;
                    }

                    switch (dispFormat.Orientation)
                    {
                    case (int)Excel.XlOrientation.xlUpward:
                        cellStyle.TextOrientation     = 9;
                        styleOverride.TextOrientation = true;
                        break;

                    case (int)Excel.XlOrientation.xlDownward:
                        cellStyle.TextOrientation     = -9;
                        styleOverride.TextOrientation = true;
                        break;

                    case (int)Excel.XlOrientation.xlVertical:
                        cellStyle.TextOrientation     = 9;
                        styleOverride.TextOrientation = true;
                        break;

                    default:
                        int rotation = (int)cell.Orientation;
                        if (rotation != (int)Excel.XlOrientation.xlHorizontal)
                        {
                            cellStyle.TextOrientation     = rotation;
                            styleOverride.TextOrientation = true;
                        }
                        break;
                    }


                    // Determine Text Size
                    double textSize = Convert.ToDouble(font.Size);
                    //double newTextSize = (textSize / 72) / 12;
                    cellStyle.TextSize     = textSize;
                    styleOverride.FontSize = true;

                    // Determine Font Color
                    System.Drawing.Color fontColor = System.Drawing.ColorTranslator.FromOle((int)font.Color);
                    cellStyle.TextColor     = new Color(fontColor.R, fontColor.G, fontColor.B);
                    styleOverride.FontColor = true;

                    // NOTES: Bold  is a bool
                    //        Italic is a bool
                    //        Underline is an int
                    cellStyle.IsFontBold      = (bool)font.Bold;
                    cellStyle.IsFontItalic    = (bool)font.Italic;
                    cellStyle.IsFontUnderline = (int)font.Underline == 2;
                    styleOverride.Bold        = true;
                    styleOverride.Italics     = true;
                    styleOverride.Underline   = true;

                    cellStyle.SetCellStyleOverrideOptions(styleOverride);

                    if (cell.MergeCells == true)
                    {
                        TableMergedCell tmc = new TableMergedCell()
                        {
                            Left   = j - 1,
                            Right  = cell.MergeArea.Columns.Count - 1,
                            Top    = i - 1,
                            Bottom = (i - 1) + cell.MergeArea.Rows.Count - 1
                        };

                        // Check to see if the cell is already merged...
                        bool alreadyMerged = false;
                        foreach (TableMergedCell mergedCell in mergedCells)
                        {
                            bool left   = false;
                            bool right  = false;
                            bool top    = false;
                            bool bottom = false;

                            if (i - 1 >= mergedCell.Top)
                            {
                                top = true;
                            }
                            if (i - 1 <= mergedCell.Bottom)
                            {
                                bottom = true;
                            }
                            if (j - 1 >= mergedCell.Left)
                            {
                                left = true;
                            }
                            if (j - 1 <= mergedCell.Right)
                            {
                                right = true;
                            }

                            //TaskDialog.Show("MergedCell", string.Format("Top: {0}\nBottom: {1}\nLeft: {2}\nRight: {3}\ni-1: {4}\nj-1: {5}", mergedCell.Top, mergedCell.Bottom, mergedCell.Left, mergedCell.Right, i - 1, j - 1));
                            if (top && bottom && left && right)
                            {
                                alreadyMerged = true;
                                break;
                            }
                        }


                        if (!alreadyMerged)
                        {
                            try
                            {
                                headerData.MergeCells(tmc);
                                headerData.SetCellText(i - 1, j - 1, cell.Text);
                                headerData.SetCellStyle(i - 1, j - 1, cellStyle);
                                j += cell.MergeArea.Columns.Count - 1;
                                mergedCells.Add(tmc);
                                //    TaskDialog.Show("Test", string.Format("This cell [{0},{1}] is merged.\nMerged Area: [{2},{3}]", cell.Row - 1, cell.Column - 1, cell.MergeArea.Rows.Count.ToString(), cell.MergeArea.Columns.Count.ToString()));
                            }
                            catch
                            {
                            }
                        }
                    }
                    else
                    {
                        //TaskDialog.Show("Non Merged", string.Format("This cell is not merged with any others [{0}, {1}]", i - 1, j - 1));
                        try
                        {
                            headerData.SetCellText(i - 1, j - 1, cell.Text);
                            headerData.SetCellStyle(i - 1, j - 1, cellStyle);
                        }
                        catch { }
                    }
                }
            }

            if (errorCount > 0)
            {
                TaskDialog.Show("Warning", "Error reloading content for " + errorCount.ToString() + " cells.\n\nConsider unchecking the \"Content Only\" checkbox and reloading the schedule to force it to rebuild.");
            }

            // Write the Schema to the project
            Schema schema = null;

            try
            {
                schema = Schema.Lookup(schemaGUID);
            }
            catch { }

            ModifySchemaData(schema, sched.Id);



            workbook.Close(false);
            Marshal.ReleaseComObject(worksheets);
            Marshal.ReleaseComObject(worksheet);
            Marshal.ReleaseComObject(workbook);
            excelApp.Quit();
            Marshal.ReleaseComObject(excelApp);
        }
        private void PathTypeSelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            var      comboBox      = sender as ComboBox;
            int      selectedIndex = comboBox.SelectedIndex;
            PathType pt            = PathType.Absolute;

            if (selectedIndex == 1)
            {
                pt = PathType.Relative;
            }
            int currentRowIndex = linkDataGrid.Items.IndexOf(linkDataGrid.CurrentItem);

            try
            {
                bool empty = false;
                if (doc.PathName == string.Empty)
                {
                    empty = true;
                }
                if (!empty)
                {
                    if (currentRowIndex >= 0)
                    {
                        LinkData ld      = LinkedData[currentRowIndex];
                        string   newPath = string.Empty;
                        string   docPath;
                        if (doc.IsWorkshared)
                        {
                            docPath = ModelPathUtils.ConvertModelPathToUserVisiblePath(doc.GetWorksharingCentralModelPath());
                        }
                        else
                        {
                            docPath = doc.PathName;
                        }
                        switch (pt)
                        {
                        case PathType.Absolute:
                            newPath = PathExchange.GetFullPath(ld.Path, docPath);
                            break;

                        case PathType.Relative:
                            newPath = PathExchange.GetRelativePath(ld.Path, docPath);
                            break;
                        }
                        ld.Path     = newPath;
                        ld.PathType = pt;

                        // Rebuild list
                        int             listLen  = LinkedData.Count;
                        List <LinkData> tempList = LinkedData;
                        LinkedData = new List <LinkData>();
                        for (int i = 0; i < listLen; i++)
                        {
                            if (i == currentRowIndex)
                            {
                                LinkedData.Add(ld);
                            }
                            else
                            {
                                LinkedData.Add(tempList[i]);
                            }
                        }

                        pathChanged = true;
                        //BuildTable();
                        UpdateLayout();
                    }
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show("Error:\n\n" + ex.ToString());
            }
        }
        private void ReloadFromButton_Click(object sender, RoutedEventArgs e)
        {
            //DataRowView selectedRow = (DataRowView)linkDataGrid.SelectedItems[0];
            LinkData selectedRow = (LinkData)linkDataGrid.SelectedItems[0];

            if (selectedRow != null)
            {
                // Find an Excel File
                System.Windows.Forms.OpenFileDialog openDlg = new System.Windows.Forms.OpenFileDialog()
                {
                    Title            = "Reload From an Excel File",
                    Filter           = "Excel Files (*.xls; *.xlsx)|*.xls;*.xlsx",
                    RestoreDirectory = true
                };


                System.Windows.Forms.DialogResult result = openDlg.ShowDialog();
                if (result == System.Windows.Forms.DialogResult.OK)
                {
                    string excelFilePath = openDlg.FileName;

                    if (System.IO.File.Exists(excelFilePath))
                    {
                        // read the Excel file and create the schedule
                        Excel.Application excelApp     = new Excel.Application();
                        Excel.Workbook    workbook     = excelApp.Workbooks.Open(excelFilePath);
                        Excel.Sheets      wbWorksheets = workbook.Worksheets;

                        List <WorksheetObject> worksheetObjs = new List <WorksheetObject>();
                        foreach (Excel.Worksheet ws in wbWorksheets)
                        {
                            WorksheetObject wo   = new WorksheetObject();
                            string          name = ws.Name;
                            wo.Name = name;
                            Excel.Range range = ws.UsedRange;
                            try
                            {
                                range.CopyPicture(Excel.XlPictureAppearance.xlPrinter, Excel.XlCopyPictureFormat.xlBitmap);
                                if (Clipboard.GetDataObject() != null)
                                {
                                    IDataObject data = Clipboard.GetDataObject();
                                    if (data.GetDataPresent(DataFormats.Bitmap))
                                    {
                                        System.Drawing.Image img = (System.Drawing.Image)data.GetData(DataFormats.Bitmap, true);
                                        wo.Image = img;
                                    }
                                }
                            }
                            catch { }
                            worksheetObjs.Add(wo);
                        }

                        // Pop up the worksheet form
                        WorksheetSelectForm wsForm = new WorksheetSelectForm(worksheetObjs, this, doc);
                        wsForm.ShowDialog();

                        if (wsForm.DialogResult.HasValue && wsForm.DialogResult.Value)
                        {
                            for (int i = 0; i < elementIds.Count; i++)
                            {
                                try
                                {
                                    int intValue = selectedRow.ElementId;
                                    if (elementIds[i].IntegerValue == intValue)
                                    {
                                        // read and reload the file.
                                        Scheduler creator = new Scheduler();
                                        creator.ModifySchedule(doc, elementIds[i], excelFilePath, worksheetObj.Name, "Reload Excel Schedule", pathTypes[i], contentOnly);
                                        string docPath;
                                        if (doc.IsWorkshared)
                                        {
                                            docPath = ModelPathUtils.ConvertModelPathToUserVisiblePath(doc.GetWorksharingCentralModelPath());
                                        }
                                        else
                                        {
                                            docPath = doc.PathName;
                                        }

                                        if ((PathType)pathTypes[i] == PathType.Relative)
                                        {
                                            paths[i] = PathExchange.GetRelativePath(excelFilePath, docPath);
                                        }
                                        else
                                        {
                                            paths[i] = excelFilePath;
                                        }

                                        worksheets[i] = worksheetObj.Name;
                                        System.IO.FileInfo fi = new System.IO.FileInfo(excelFilePath);
                                        dateTimes[i] = fi.LastWriteTimeUtc.ToString();

                                        // Read the schema information
                                        Autodesk.Revit.DB.ExtensibleStorage.Schema schema = Autodesk.Revit.DB.ExtensibleStorage.Schema.Lookup(schemaGuid);
                                        if (schema != null)
                                        {
                                            Autodesk.Revit.DB.ExtensibleStorage.Entity entity = null;
                                            DataStorage ds = SchemaManager.GetDataStorage(doc);
                                            try
                                            {
                                                entity = ds.GetEntity(schema);
                                            }
                                            catch { }

                                            if (entity != null)
                                            {
                                                Transaction trans = new Transaction(doc, "Update Excel Document");
                                                trans.Start();
                                                entity.Set <IList <string> >("ExcelFilePath", paths);
                                                entity.Set <IList <string> >("WorksheetName", worksheets);
                                                entity.Set <IList <string> >("DateTime", dateTimes);
                                                entity.Set <IList <int> >("PathType", pathTypes);
                                                ds.SetEntity(entity);
                                                trans.Commit();

                                                BuildTable();
                                            }
                                        }
                                    }
                                }
                                catch { }
                            }
                        }
                        try
                        {
                            workbook.Close();
                            Marshal.ReleaseComObject(worksheets);
                            //Marshal.ReleaseComObject(worksheet);
                            Marshal.ReleaseComObject(workbook);
                            excelApp.Quit();
                            Marshal.ReleaseComObject(excelApp);
                        }
                        catch { }
                    }
                }
            }
        }