예제 #1
0
        /// <summary>
        /// Inserts subtotals into an enumerable set of flights, returning an enumerable set of LogbookPrintedPages.
        /// </summary>
        /// <param name="lstIn">The input set of flights.  Should be ALL RowType=Flight and should have rowheight property set</param>
        /// <param name="po">Options that guide pagination</param>
        /// <returns>A new enumerable with per-page subtotals and (optional) running totals</returns>
        public static IEnumerable <LogbookPrintedPage> Paginate(IEnumerable <LogbookEntryDisplay> lstIn, PrintingOptions po)
        {
            if (lstIn == null)
            {
                throw new ArgumentNullException(nameof(lstIn));
            }
            if (po == null)
            {
                throw new ArgumentNullException(nameof(po));
            }
            int cIn = lstIn.Count();

            if (cIn == 0)
            {
                return(Array.Empty <LogbookPrintedPage>());
            }

            // For speed, cache the names of each category/class
            Dictionary <int, string> dictCatClasses = new Dictionary <int, string>();

            foreach (CategoryClass cc in CategoryClass.CategoryClasses())
            {
                dictCatClasses.Add(cc.IDCatClassAsInt, cc.CatClass);
            }

            List <LogbookPrintedPage> lstOut = new List <LogbookPrintedPage>();

            Dictionary <string, LogbookEntryDisplay> dictPageTotals = null, dictPreviousTotals, dictRunningTotals = new Dictionary <string, LogbookEntryDisplay>();
            List <LogbookEntryDisplay> lstFlightsThisPage = null;
            LogbookPrintedPage         currentPage = null;

            int flightIndexOnPage = 0;
            int index             = 0;
            int pageNum           = 0;

            DateTime?dtLastEntry = null;

            foreach (LogbookEntryDisplay led in lstIn)
            {
                // force a page break if a new month is starting IF the option to do so has been set
                if (po.FlightsPerPage > 0 && po.BreakAtMonthBoundary && dtLastEntry != null && dtLastEntry.HasValue && (led.Date.Month != dtLastEntry.Value.Month || led.Date.Year != dtLastEntry.Value.Year))
                {
                    flightIndexOnPage = po.FlightsPerPage;
                }

                dtLastEntry = led.Date;
                led.SetOptionalColumns(po.OptionalColumns);
                if ((po.FlightsPerPage > 0 && flightIndexOnPage >= po.FlightsPerPage) || currentPage == null) // need to start a new page.
                {
                    flightIndexOnPage = 0;                                                                    // reset
                    dictPageTotals    = new Dictionary <string, LogbookEntryDisplay>();
                    // COPY the running totals to the new previous totals, since AddFrom modifies the object,
                    dictPreviousTotals = new Dictionary <string, LogbookEntryDisplay>();
                    Dictionary <string, LogbookEntryDisplay> dictNewRunningTotals = new Dictionary <string, LogbookEntryDisplay>();
                    foreach (string szKeySrc in dictRunningTotals.Keys)
                    {
                        LogbookEntryDisplay ledRunningNew = JsonConvert.DeserializeObject <LogbookEntryDisplay>(JsonConvert.SerializeObject(dictRunningTotals[szKeySrc]));
                        ledRunningNew.RowType        = LogbookEntryDisplay.LogbookRowType.PreviousTotal;
                        dictPreviousTotals[szKeySrc] = ledRunningNew;
                        ledRunningNew                  = JsonConvert.DeserializeObject <LogbookEntryDisplay>(JsonConvert.SerializeObject(dictRunningTotals[szKeySrc]));
                        ledRunningNew.RowType          = LogbookEntryDisplay.LogbookRowType.RunningTotal;
                        dictNewRunningTotals[szKeySrc] = ledRunningNew;
                    }
                    dictRunningTotals  = dictNewRunningTotals; // set up for the new page to pick up where the last one left off...
                    lstFlightsThisPage = new List <LogbookEntryDisplay>();
                    currentPage        = new LogbookPrintedPage()
                    {
                        RunningTotals = dictRunningTotals, TotalsPreviousPages = dictPreviousTotals, TotalsThisPage = dictPageTotals, Flights = lstFlightsThisPage, PageNum = ++pageNum
                    };

                    lstOut.Add(currentPage);
                }

                flightIndexOnPage += led.RowHeight;

                string szCatClassKey = dictCatClasses[led.EffectiveCatClass];   // should never not be present!!

                led.Index = ++index;

                // Add the flight to the page
                lstFlightsThisPage.Add(led);

                // And add the flight to the page catclass totals and running catclass totals
                if (po.FlightsPerPage > 0)
                {
                    if (!dictPageTotals.ContainsKey(szCatClassKey))
                    {
                        dictPageTotals[szCatClassKey] = new LogbookEntryDisplay(po.OptionalColumns)
                        {
                            RowType = LogbookEntryDisplay.LogbookRowType.PageTotal, CatClassDisplay = szCatClassKey
                        }
                    }
                    ;
                    dictPageTotals[szCatClassKey].AddFrom(led);
                }
                if (!dictRunningTotals.ContainsKey(szCatClassKey))
                {
                    dictRunningTotals[szCatClassKey] = new LogbookEntryDisplay(po.OptionalColumns)
                    {
                        RowType = LogbookEntryDisplay.LogbookRowType.RunningTotal, CatClassDisplay = szCatClassKey
                    }
                }
                ;
                dictRunningTotals[szCatClassKey].AddFrom(led);
            }

            // Assign page number, and index totals
            foreach (LogbookPrintedPage lpp in lstOut)
            {
                // And add unstriped totals as needed
                ConsolidateTotals(lpp.TotalsThisPage, LogbookEntryDisplay.LogbookRowType.PageTotal, po.OptionalColumns);
                ConsolidateTotals(lpp.TotalsPreviousPages, LogbookEntryDisplay.LogbookRowType.PreviousTotal, po.OptionalColumns);
                ConsolidateTotals(lpp.RunningTotals, LogbookEntryDisplay.LogbookRowType.RunningTotal, po.OptionalColumns);

                lpp.TotalPages = pageNum;
                int iTotal = 0;
                foreach (LogbookEntryDisplay lep in lpp.TotalsThisPage.Values)
                {
                    lep.Index = iTotal++;
                }
                iTotal = 0;
                foreach (LogbookEntryDisplay lep in lpp.TotalsPreviousPages.Values)
                {
                    lep.Index = iTotal++;
                }
                iTotal = 0;
                foreach (LogbookEntryDisplay lep in lpp.RunningTotals.Values)
                {
                    lep.Index = iTotal++;
                }

                if (!po.StripeSubtotalsByCategoryClass)
                {
                    RemoveStripedSubtotals(lpp.TotalsThisPage);
                    RemoveStripedSubtotals(lpp.TotalsPreviousPages);
                    RemoveStripedSubtotals(lpp.RunningTotals);
                }

                if (!po.IncludePullForwardTotals)
                {
                    lpp.TotalsPreviousPages.Clear();
                }
            }

            return(lstOut);
        }
예제 #2
0
        /// <summary>
        /// Inserts subtotals into an enumerable set of flights, returning an enumerable set of LogbookPrintedPages.
        /// </summary>
        /// <param name="lstIn">The input set of flights.  Should be ALL RowType=Flight and should have rowheight property set</param>
        /// <param name="pageSize">Max # of flights per table to subtotal; flights with rowheight > 1 will take up more rows</param>
        /// <param name="optionalColumns">Any optional columns to add</param>
        /// <param name="pullForwardTotals">Whether or not to pull forward totals from the previous page</param>
        /// <returns>A new enumerable with per-page subtotals and (optional) running totals</returns>
        public static IEnumerable <LogbookPrintedPage> Paginate(IEnumerable <LogbookEntryDisplay> lstIn, int pageSize, OptionalColumn[] optionalColumns, bool pullForwardTotals)
        {
            if (lstIn == null)
            {
                throw new ArgumentNullException("lstIn");
            }
            int cIn = lstIn.Count();

            if (cIn == 0)
            {
                return(new LogbookPrintedPage[0]);
            }

            // For speed, cache the names of each category/class
            Dictionary <int, string> dictCatClasses = new Dictionary <int, string>();

            foreach (CategoryClass cc in CategoryClass.CategoryClasses())
            {
                dictCatClasses.Add(cc.IDCatClassAsInt, cc.CatClass);
            }

            List <LogbookPrintedPage> lstOut = new List <LogbookPrintedPage>();

            Dictionary <string, LogbookEntryDisplay> dictPageTotals = null, dictPreviousTotals = new Dictionary <string, LogbookEntryDisplay>(), dictRunningTotals = new Dictionary <string, LogbookEntryDisplay>();
            List <LogbookEntryDisplay> lstFlightsThisPage = null;
            LogbookPrintedPage         currentPage = null;

            int flightIndexOnPage = 0;
            int index             = 0;
            int pageNum           = 0;

            foreach (LogbookEntryDisplay led in lstIn)
            {
                led.OptionalColumns = optionalColumns;
                if ((pageSize > 0 && flightIndexOnPage >= pageSize) || currentPage == null) // need to start a new page.
                {
                    flightIndexOnPage = 0;                                                  // reset
                    dictPageTotals    = new Dictionary <string, LogbookEntryDisplay>();
                    // COPY the running totals to the new previous totals, since AddFrom modifies the object,
                    dictPreviousTotals = new Dictionary <string, LogbookEntryDisplay>();
                    Dictionary <string, LogbookEntryDisplay> dictNewRunningTotals = new Dictionary <string, LogbookEntryDisplay>();
                    foreach (string szKeySrc in dictRunningTotals.Keys)
                    {
                        LogbookEntryDisplay ledRunningNew = JsonConvert.DeserializeObject <LogbookEntryDisplay>(JsonConvert.SerializeObject(dictRunningTotals[szKeySrc]));
                        ledRunningNew.RowType        = LogbookEntryDisplay.LogbookRowType.PreviousTotal;
                        dictPreviousTotals[szKeySrc] = ledRunningNew;
                        ledRunningNew                  = JsonConvert.DeserializeObject <LogbookEntryDisplay>(JsonConvert.SerializeObject(dictRunningTotals[szKeySrc]));
                        ledRunningNew.RowType          = LogbookEntryDisplay.LogbookRowType.RunningTotal;
                        dictNewRunningTotals[szKeySrc] = ledRunningNew;
                    }
                    dictRunningTotals  = dictNewRunningTotals; // set up for the new page to pick up where the last one left off...
                    lstFlightsThisPage = new List <LogbookEntryDisplay>();
                    currentPage        = new LogbookPrintedPage()
                    {
                        RunningTotals = dictRunningTotals, TotalsPreviousPages = dictPreviousTotals, TotalsThisPage = dictPageTotals, Flights = lstFlightsThisPage, PageNum = ++pageNum
                    };

                    lstOut.Add(currentPage);
                }

                flightIndexOnPage += led.RowHeight;

                string szCatClassKey = dictCatClasses[led.EffectiveCatClass];   // should never not be present!!

                led.Index = ++index;

                // Add the flight to the page
                lstFlightsThisPage.Add(led);

                // And add the flight to the page catclass totals and running catclass totals
                if (pageSize > 0)
                {
                    if (!dictPageTotals.ContainsKey(szCatClassKey))
                    {
                        dictPageTotals[szCatClassKey] = new LogbookEntryDisplay()
                        {
                            RowType = LogbookEntryDisplay.LogbookRowType.PageTotal, CatClassDisplay = szCatClassKey, OptionalColumns = optionalColumns
                        }
                    }
                    ;
                    dictPageTotals[szCatClassKey].AddFrom(led);
                }
                if (!dictRunningTotals.ContainsKey(szCatClassKey))
                {
                    dictRunningTotals[szCatClassKey] = new LogbookEntryDisplay()
                    {
                        RowType = LogbookEntryDisplay.LogbookRowType.RunningTotal, CatClassDisplay = szCatClassKey, OptionalColumns = optionalColumns
                    }
                }
                ;
                dictRunningTotals[szCatClassKey].AddFrom(led);
            }

            // Assign page number, and index totals
            foreach (LogbookPrintedPage lpp in lstOut)
            {
                // And add unstriped totals as needed
                ConsolidateTotals(lpp.TotalsThisPage, LogbookEntryDisplay.LogbookRowType.PageTotal, optionalColumns);
                ConsolidateTotals(lpp.TotalsPreviousPages, LogbookEntryDisplay.LogbookRowType.PreviousTotal, optionalColumns);
                ConsolidateTotals(lpp.RunningTotals, LogbookEntryDisplay.LogbookRowType.RunningTotal, optionalColumns);

                lpp.TotalPages = pageNum;
                int iTotal = 0;
                foreach (LogbookEntryDisplay lep in lpp.TotalsThisPage.Values)
                {
                    lep.Index = iTotal++;
                }
                iTotal = 0;
                foreach (LogbookEntryDisplay lep in lpp.TotalsPreviousPages.Values)
                {
                    lep.Index = iTotal++;
                }
                iTotal = 0;
                foreach (LogbookEntryDisplay lep in lpp.RunningTotals.Values)
                {
                    lep.Index = iTotal++;
                }

                if (!pullForwardTotals)
                {
                    lpp.TotalsPreviousPages.Clear();
                }
            }

            return(lstOut);
        }
예제 #3
0
        public static PrintLayout LayoutLogbook(Profile pf, IList <LogbookEntryDisplay> lstFlights, IPrintingTemplate pt, PrintingOptions printingOptions, bool fSuppressFooter)
        {
            if (pf == null)
            {
                throw new ArgumentNullException(nameof(pf));
            }
            if (pt == null)
            {
                throw new ArgumentNullException(nameof(pt));
            }
            if (printingOptions == null)
            {
                throw new ArgumentNullException(nameof(printingOptions));
            }
            if (lstFlights == null)
            {
                throw new ArgumentNullException(nameof(lstFlights));
            }

            PrintLayout pl = PrintLayout.LayoutForType(printingOptions.Layout, pf);

            // Exclude both excluded properties and properties that have been moved to their own columns
            HashSet <int> lstPropsToExclude    = new HashSet <int>(printingOptions.ExcludedPropertyIDs);
            HashSet <int> lstPropsInOwnColumns = new HashSet <int>();

            foreach (OptionalColumn oc in printingOptions.OptionalColumns)
            {
                if (oc.ColumnType == OptionalColumnType.CustomProp)
                {
                    lstPropsInOwnColumns.Add(oc.IDPropType);
                }
            }
            string szPropSeparator = printingOptions.PropertySeparatorText;

            // set up properties per flight, and compute rough lineheight
            foreach (LogbookEntryDisplay led in lstFlights)
            {
                // Fix up properties according to the printing options
                List <CustomFlightProperty> lstProps = new List <CustomFlightProperty>(led.CustomProperties);

                // And fix up model as well.
                switch (printingOptions.DisplayMode)
                {
                case PrintingOptions.ModelDisplayMode.Full:
                    break;

                case PrintingOptions.ModelDisplayMode.Short:
                    led.ModelDisplay = led.ShortModelName;
                    break;

                case PrintingOptions.ModelDisplayMode.ICAO:
                    led.ModelDisplay = led.FamilyName;
                    break;
                }


                // Remove from the total property set all explicitly excluded properties...
                lstProps.RemoveAll(cfp => lstPropsToExclude.Contains(cfp.PropTypeID));

                // ...and then additionally exclude from the display any that's in its own column to avoid redundancy.
                lstProps.RemoveAll(cfp => lstPropsInOwnColumns.Contains(cfp.PropTypeID));
                led.CustPropertyDisplay = CustomFlightProperty.PropListDisplay(lstProps, pf.UsesHHMM, szPropSeparator);

                if (printingOptions.IncludeImages)
                {
                    led.PopulateImages(true);
                }

                if (!printingOptions.IncludeSignatures)
                {
                    led.CFISignatureState = LogbookEntryBase.SignatureState.None;
                }
                led.RowHeight = pl.RowHeight(led);
            }

            pt.BindPages(LogbookPrintedPage.Paginate(lstFlights, printingOptions), pf, printingOptions, !fSuppressFooter);

            return(pl);
        }