예제 #1
0
        public void GetLastElement_OneElement()
        {
            IVwLayoutStream stream = VwLayoutStreamClass.Create();

            using (DummyDivisionMgr division = new DummyDivisionMgr(stream, false))
            {
                using (DummyPublication dummyPub = new DummyPublication(null, division, DateTime.Now))
                {
                    using (DummyPage page = new DummyPage(dummyPub))
                    {
                        PageElement element = new PageElement(division, stream, false,
                                                              new Rectangle(720, 1440, (int)(6.5 * 720), (int)(9 * 1440)),
                                                              0, true, 1, 1, 0, 9 * 1440, 0, false);
                        page.PageElements.Add(element);

                        int         xd;
                        PageElement lastElement = page.CallGetLastElement(division, out xd);
                        Assert.AreEqual(element.LocationOnPage.Right, xd);
                        Debug.WriteLine("GetLastElement_OneElement xd: " + xd);

                        Assert.AreEqual(element, lastElement);
                    }
                }
            }
        }
예제 #2
0
        public void GetLastElement_TwoElementsRtoLStandard()
        {
            IVwLayoutStream stream = VwLayoutStreamClass.Create();

            using (DummyDivisionMgr division = new DummyDivisionMgr(stream, true))
                using (DummyPublication dummyPub = new DummyPublication(null, division, DateTime.Now))
                    using (DummyPage page = new DummyPage(dummyPub))
                    {
                        PageElement leftColumnElement = new PageElement(division, stream, false,
                                                                        new Rectangle(0, 1440, (int)(3 * 720), (int)(5 * 1440)),
                                                                        0, true, 1, 2, 0, 5 * 1440, 0, true);
                        PageElement rightColumnElement = new PageElement(division, stream, false,
                                                                         new Rectangle(3 * 720 + 360, 1440, (int)(3 * 720), (int)(9 * 1440)),
                                                                         0, true, 2, 2, 0, 9 * 1440, 0, true);

                        page.PageElements.Add(leftColumnElement);
                        page.PageElements.Add(rightColumnElement);

                        int         xd;
                        PageElement lastElement = page.CallGetLastElement(division, out xd);
                        Debug.WriteLine("GetLastElement_TwoElementsRtoLStandard xd: " + xd);

                        Assert.AreEqual(leftColumnElement, lastElement,
                                        "The left-most column should be the last element in a right-to-left writing system");
                        Assert.AreEqual(0, xd);
                    }
        }
예제 #3
0
        /// ------------------------------------------------------------------------------------
        /// <summary>
        /// Exposes the PageFromPrinterY method
        /// </summary>
        /// <param name="y">The y.</param>
        /// <param name="fUp">If the point is right at a page boundary, return the first
        /// page if this is true, the second if it is false.</param>
        /// <param name="strm">The STRM.</param>
        /// <param name="dyPageScreen">The dy page screen.</param>
        /// <returns></returns>
        /// ------------------------------------------------------------------------------------
        public Page CallPageFromPrinterY(int y, bool fUp, IVwLayoutStream strm,
                                         out int dyPageScreen)
        {
            int iDiv;             // not used in the tests

            return(PageFromPrinterY(0, y, fUp, strm, out dyPageScreen, out iDiv));
        }
예제 #4
0
        /// ------------------------------------------------------------------------------------
        /// <summary>
        /// Configure a PublicationControl
        /// </summary>
        /// ------------------------------------------------------------------------------------
        public void ConfigurePublication()
        {
            Dictionary <string, string> cacheOptions = new Dictionary <string, string>();

            cacheOptions.Add("db", "TestLangProj");
            m_fdoCache = FdoCache.Create(cacheOptions);
            // Make sure we don't call InstallLanguage during tests.
            m_fdoCache.LanguageWritingSystemFactoryAccessor.BypassInstall = true;

            if (m_pub != null)
            {
                m_pub.Dispose();
            }
            m_division = new DummyDivision(new DummyHFPrintConfigurer(m_fdoCache), 1);
            Publication pub = new Publication(m_fdoCache,
                                              m_fdoCache.LangProject.TranslatedScriptureOA.PublicationsOC.HvoArray[0]);

            m_pub = new DummyPublication(pub, m_division, DateTime.Now);
            m_pub.Configure();

            // Check initial state
            Assert.AreEqual(m_division, m_pub.Divisions[0]);
            IVwLayoutStream layoutStream = m_division.MainLayoutStream;

            Assert.IsNotNull(layoutStream);
        }
예제 #5
0
        /// ------------------------------------------------------------------------------------
        /// <summary>
        /// Configure a PublicationControl
        /// </summary>
        /// <param name="fAddSubStream">if set to <c>true</c> add subordinate stream.</param>
        /// ------------------------------------------------------------------------------------
        private void ConfigurePublication(bool fAddSubStream)
        {
            // When called for test setup, they will be null.
            // When called from within as test
            if (m_pub != null)
            {
                m_pub.Dispose();
            }
            if (m_division != null)
            {
                m_division.Dispose();
            }
            m_division = new DummyDivision(new DummyLazyPrintConfigurer(Cache, fAddSubStream), 1);
            Publication pub = new Publication(Cache,
                                              Cache.LangProject.TranslatedScriptureOA.PublicationsOC.HvoArray[0]);

            m_pub = new DummyPublication(pub, m_division, DateTime.Now);
            m_pub.Configure();

            // Check initial state
            Assert.AreEqual(m_division, m_pub.Divisions[0]);
            Assert.IsNotNull(m_division.MainVc as DummyMainLazyViewVc);
            IVwLayoutStream layoutStream = m_division.MainLayoutStream;

            Assert.IsNotNull(layoutStream);
            m_pub.IsLeftBound = true;
        }
		/// ------------------------------------------------------------------------------------
		/// <summary>
		/// Configure a PublicationControl
		/// </summary>
		/// <param name="fAddSubStream">if set to <c>true</c> add subordinate stream.</param>
		/// <param name="fAddContent">if set to <c>true</c> add real content, otherwise add
		/// rectangle for paragraph.</param>
		/// ------------------------------------------------------------------------------------
		private void ConfigurePublication(bool fAddSubStream, bool fAddContent)
		{
			// When called for test setup, they will be null.
			// When called from within as test
			if (m_pub != null)
				m_pub.Dispose();
			if (m_division != null)
				m_division.Dispose();
			m_division = new DummyDivision(new DummyLazyPrintConfigurer(Cache, fAddSubStream,
				fAddContent), 2);
			IPublication pub =
				Cache.LangProject.TranslatedScriptureOA.PublicationsOC.ToArray()[0];
			m_pub = new DummyPublication(pub, m_division, DateTime.Now);
			m_pub.Configure();

			// Check initial state
			Assert.AreEqual(m_division, m_pub.Divisions[0]);
			Assert.IsNotNull(m_division.MainVc as DummyMainLazyViewVc);
			IVwLayoutStream layoutStream = m_division.MainLayoutStream;
			Assert.IsNotNull(layoutStream);
			m_pub.IsLeftBound = true;

			// Set up the publication
			m_pub.PageHeight = 72000 * 11; // 11 inches
			m_pub.PageWidth = (int)(72000 * 8.5); // 8.5 inches
			m_division.TopMargin = 36000; // Half inch
			m_division.BottomMargin = 18000; // Quarter inch
			m_division.InsideMargin = 9000; // 1/8 inch
			m_division.OutsideMargin = 4500; // 1/16 inch
			DummyMainLazyViewVc vc = m_division.MainVc as DummyMainLazyViewVc;
			vc.m_estBookHeight = 2000;
			vc.m_estSectionHeight = 2000;
			m_pub.Width = 3 * 96; // represents a window that is 3" wide at 96 DPI
		}
예제 #7
0
        public void DeleteFootnoteSelection()
        {
            m_ScrPubCtrl.PageHeight  = 432000;        // 6 inches
            m_ScrPubCtrl.PageWidth   = 288000;        // 4 inches
            m_division.TopMargin     = 18000;         // Half inch
            m_division.BottomMargin  = 18000;
            m_division.InsideMargin  = 18000;
            m_division.OutsideMargin = 18000;
            m_ScrPubCtrl.Width       = 4 * 96;       // represents a window that is 4" wide at 96 DPI
            m_ScrPubCtrl.CreatePages();
            List <Page>     pagesToBeDrawn = m_ScrPubCtrl.PrepareToDrawPages(0, 2000);
            IVwLayoutStream layoutStream   = m_division.MainLayoutStream;
            IVwRootBox      rootbox        = layoutStream as IVwRootBox;

            // Get number of footnotes in book.
            IScripture scr = m_fdoCache.LangProject.TranslatedScriptureOA;

            Assert.AreEqual(3, scr.ScriptureBooksOS.Count);
            ScrBook james        = (ScrBook)m_fdoCache.LangProject.TranslatedScriptureOA.ScriptureBooksOS[1];
            int     numFootnotes = james.FootnotesOS.Count;

            // Select the first footnote in James.
            SelectionHelper selHelper = SelectRangeOfChars(rootbox, 2, 2, 3);

            // Delete the footnote marker selection.
            //m_footnoteView.OnKeyDown(new KeyEventArgs(Keys.Delete));
            m_ScrPubCtrl.PressKey(new KeyEventArgs(Keys.Delete));

            // Confirm that there is one less footnote in the book.
            Assert.AreEqual(numFootnotes - 1, james.FootnotesOS.Count);
        }
		/// ------------------------------------------------------------------------------------
		/// <summary>
		/// Constructs a TePrintLayoutConfig to configure the main print layout
		/// </summary>
		/// <param name="cache">The cache.</param>
		/// <param name="styleSheet">The style sheet.</param>
		/// <param name="publication">The publication.</param>
		/// <param name="viewType">Type of the view.</param>
		/// <param name="filterInstance">the book filter instance in effect</param>
		/// <param name="printDateTime">printing date and time</param>
		/// <param name="fIntroDivision">set to <c>true</c> for a division that displays book
		/// title and introduction material, <c>false</c> for a division that displays main
		/// scripture text.</param>
		/// <param name="hvoBook">The hvo of the book.</param>
		/// <param name="sharedStream">A layout stream used for footnotes which is shared across
		/// multiple divisions</param>
		/// <param name="ws">The writing system to use for the back translation</param>
		/// ------------------------------------------------------------------------------------
		public TeBtPrintLayoutConfig(FdoCache cache, IVwStylesheet styleSheet,
			IPublication publication, TeViewType viewType, int filterInstance,
			DateTime printDateTime, bool fIntroDivision, int hvoBook, IVwLayoutStream sharedStream,
			int ws)
			: base(cache, styleSheet, publication, viewType, filterInstance, printDateTime,
			fIntroDivision, hvoBook, sharedStream, ws)
		{
		}
예제 #9
0
 /// ------------------------------------------------------------------------------------
 /// <summary>
 /// Constructs a TePrintLayoutConfig to configure the main print layout
 /// </summary>
 /// <param name="cache">The cache.</param>
 /// <param name="styleSheet">The style sheet.</param>
 /// <param name="publication">The publication.</param>
 /// <param name="viewType">Type of the view.</param>
 /// <param name="filterInstance">the book filter instance in effect</param>
 /// <param name="printDateTime">printing date and time</param>
 /// <param name="hvoBook">The hvo of the book.</param>
 /// <param name="sharedStream">A layout stream used for footnotes which is shared across
 /// multiple divisions</param>
 /// <param name="ws">The writing system to use for the back translation</param>
 /// ------------------------------------------------------------------------------------
 public TeBtPrintLayoutConfig(FdoCache cache, IVwStylesheet styleSheet,
                              IPublication publication, TeViewType viewType, int filterInstance,
                              DateTime printDateTime, int hvoBook, IVwLayoutStream sharedStream,
                              int ws)
     : base(cache, styleSheet, publication, viewType, filterInstance, printDateTime,
            PrintLayoutPortion.AllContent, hvoBook, sharedStream, ws)
 {
 }
예제 #10
0
        ///// <summary>type of width for this page element across the page</summary>
        //internal readonly PageElementWidthType m_widthType;
        #endregion

        #region Constructor
        /// ------------------------------------------------------------------------------------
        /// <summary>
        /// Constructor
        /// </summary>
        /// <param name="division">The division.</param>
        /// <param name="stream">The stream.</param>
        /// <param name="fPageElementOwnsStream">if set to <c>true</c> the page element owns
        /// the stream.</param>
        /// <param name="locationOnPage">The location on page.</param>
        /// <param name="dypOffsetToTopOfDataOnPage">The dyp offset to top of data on page.</param>
        /// <param name="fMainStream">set to <c>true</c> if <paramref name="stream"/> is the
        /// main stream of <paramref name="division"/>, otherwise <c>false</c>.</param>
        /// <param name="columnNumber">The column number of the page element (1-based)</param>
        /// <param name="totalColumns">The total number of columns on the page for this stream.</param>
        /// <param name="columnGap">The gap between the columns, which is used if there are two
        /// or more columns.</param>
        /// <param name="columnHeight">The height of the current column.</param>
        /// <param name="dypOverlapWithPreviousElement"></param>
        /// <param name="fInRightToLeftStream">if set to <c>true</c> the page element is in a
        /// right-to-left stream.</param>
        /// ------------------------------------------------------------------------------------
        public PageElement(DivisionLayoutMgr division, IVwLayoutStream stream,
                           bool fPageElementOwnsStream, Rectangle locationOnPage, int dypOffsetToTopOfDataOnPage,
                           bool fMainStream, int columnNumber, int totalColumns, int columnGap, int columnHeight,
                           int dypOverlapWithPreviousElement, bool fInRightToLeftStream)
        {
            m_division = division;
            m_stream   = stream;
            m_fPageElementOwnsStream     = fPageElementOwnsStream;
            m_locationOnPage             = locationOnPage;
            m_dypOffsetToTopOfDataOnPage = dypOffsetToTopOfDataOnPage;
            m_fMainStream                   = fMainStream;
            m_column                        = columnNumber;
            m_totalColumns                  = totalColumns;
            m_fInRightToLeftStream          = fInRightToLeftStream;
            m_columnGap                     = columnGap;
            m_columnHeight                  = columnHeight;
            m_dypOverlapWithPreviousElement = dypOverlapWithPreviousElement;
        }
예제 #11
0
        /// ------------------------------------------------------------------------------------
        /// <summary>
        /// Constructs a TePrintLayoutConfig to configure the main print layout
        /// </summary>
        /// <param name="cache">The cache.</param>
        /// <param name="styleSheet">The style sheet.</param>
        /// <param name="publication">The publication.</param>
        /// <param name="viewType">Type of the view.</param>
        /// <param name="filterInstance">the book filter instance in effect</param>
        /// <param name="printDateTime">printing date and time</param>
        /// <param name="divisionPortion">portion of the book to be layed out in this division</param>
        /// <param name="hvoBook">The hvo of the book we're displaying.</param>
        /// <param name="sharedStream">A layout stream used for footnotes which is shared across
        /// multiple divisions</param>
        /// <param name="ws">The writing system to use for the view.</param>
        /// ------------------------------------------------------------------------------------
        public TePrintLayoutConfig(FdoCache cache, IVwStylesheet styleSheet,
                                   IPublication publication, TeViewType viewType, int filterInstance,
                                   DateTime printDateTime, PrintLayoutPortion divisionPortion, int hvoBook, IVwLayoutStream sharedStream,
                                   int ws)
        {
            m_fdoCache           = cache;
            m_scr                = m_fdoCache.LangProject.TranslatedScriptureOA;
            m_styleSheet         = styleSheet;
            m_pub                = publication;
            m_viewType           = viewType;
            m_bookFilterInstance = filterInstance;
            m_printDateTime      = printDateTime;
            m_divisionPortion    = divisionPortion;
            m_hvoBook            = hvoBook;
            m_sharedStream       = sharedStream;
            m_ws = ws;

            m_paraCounter = cache.ServiceLocator.GetInstance <IParagraphCounterRepository>().GetParaCounter((int)TeViewGroup.Scripture);
        }
예제 #12
0
        /// ------------------------------------------------------------------------------------
        /// <summary>
        /// Configure a PublicationControl
        /// </summary>
        /// ------------------------------------------------------------------------------------
        public void ConfigurePublication()
        {
            if (m_pub != null)
            {
                m_pub.Dispose();
            }
            m_division = new DummyDivision(new DummyHFPrintConfigurer(Cache), 1);
            IPublication pub =
                Cache.LangProject.TranslatedScriptureOA.PublicationsOC.ToArray()[0];

            m_pub = new DummyPublication(pub, m_division, DateTime.Now);
            m_pub.Configure();

            // Check initial state
            Assert.AreEqual(m_division, m_pub.Divisions[0]);
            IVwLayoutStream layoutStream = m_division.MainLayoutStream;

            Assert.IsNotNull(layoutStream);
        }
예제 #13
0
        public void OneColumnOneBook()
        {
            foreach (PubDivision div in m_dbPub.DivisionsOS)
            {
                div.NumColumns = 1;
            }

            m_BookFilter.UpdateFilter(
                Cache.LangProject.TranslatedScriptureOA.ScriptureBooksOS.HvoArray[1]);
            Assert.AreEqual(1, m_BookFilter.BookCount);

            m_ScrPubCtrl.Configure();
            m_ScrPubCtrl.CreatePages();

            // Verify that both divisions are one-column
            Assert.AreEqual(2, m_ScrPubCtrl.Divisions.Count);
            DivisionLayoutMgr divTitleIntro = m_ScrPubCtrl.Divisions[0];
            DivisionLayoutMgr divScripture  = m_ScrPubCtrl.Divisions[1];

            Assert.AreEqual(divTitleIntro.AvailableMainStreamColumWidthInPrinterPixels,
                            divScripture.AvailableMainStreamColumWidthInPrinterPixels);
            Assert.AreEqual(divTitleIntro.AvailableMainStreamColumWidthInPrinterPixels,
                            divTitleIntro.AvailablePageWidthInPrinterPixels);
            Assert.AreNotEqual(DivisionStartOption.Continuous, divTitleIntro.StartAt);
            Assert.AreEqual(DivisionStartOption.Continuous, divScripture.StartAt);
            Assert.Greater(divTitleIntro.MainRootBox.Height, 0);
            Assert.Greater(divScripture.MainRootBox.Height, 0);
            Assert.Greater(divScripture.MainRootBox.Height, divTitleIntro.MainRootBox.Height);

            Assert.Greater(m_ScrPubCtrl.PageCount, 2);

            Assert.IsNotNull(divTitleIntro.MainVc as ScriptureBookIntroVc);
            Assert.IsNotNull(divScripture.MainVc as ScriptureBodyVc);

            foreach (DivisionLayoutMgr div in m_ScrPubCtrl.Divisions)
            {
                IVwLayoutStream layoutStream = div.MainLayoutStream;
                Assert.IsNotNull(layoutStream);
                Assert.IsNotNull(layoutStream as IVwRootBox);
            }
        }
        public void TwoColumnOneBook()
        {
            foreach (IPubDivision div in m_dbPub.DivisionsOS)
            {
                div.NumColumns = 2;
            }

            m_BookFilter.FilteredBooks =
                new [] { Cache.LangProject.TranslatedScriptureOA.ScriptureBooksOS[1] };
            Assert.AreEqual(1, m_BookFilter.BookCount);

            m_ScrPubCtrl.CallRefreshDisplay();
            m_ScrPubCtrl.Configure();
            m_ScrPubCtrl.CreatePages();

            Assert.AreEqual(2, m_ScrPubCtrl.Divisions.Count);
            DivisionLayoutMgr divTitleIntro = m_ScrPubCtrl.Divisions[0];
            DivisionLayoutMgr divScripture  = m_ScrPubCtrl.Divisions[1];

            Assert.AreNotEqual(divTitleIntro.AvailableMainStreamColumWidthInPrinterPixels,
                               divScripture.AvailableMainStreamColumWidthInPrinterPixels);
            Assert.AreEqual(divTitleIntro.AvailableMainStreamColumWidthInPrinterPixels,
                            divTitleIntro.AvailablePageWidthInPrinterPixels);
            Assert.AreNotEqual(DivisionStartOption.Continuous, divTitleIntro.StartAt);
            Assert.AreEqual(DivisionStartOption.Continuous, divScripture.StartAt);
            Assert.Greater(divTitleIntro.MainRootBox.Height, 0);
            Assert.Greater(divScripture.MainRootBox.Height, 0);
            Assert.Greater(divScripture.MainRootBox.Height, divTitleIntro.MainRootBox.Height);

            Assert.Greater(m_ScrPubCtrl.PageCount, 1);

            Assert.IsNotNull(divTitleIntro.MainVc as ScriptureBookIntroVc);
            Assert.IsNotNull(divScripture.MainVc as ScriptureBodyVc);

            foreach (DivisionLayoutMgr div in m_ScrPubCtrl.Divisions)
            {
                IVwLayoutStream layoutStream = div.MainLayoutStream;
                Assert.IsNotNull(layoutStream);
                Assert.IsNotNull(layoutStream as IVwRootBox);
            }
        }
        public void DeleteFootnoteSelection()
        {
            // Add a footnote to the last section in the book of Genesis. (The last section is
            // what is contained in our rootbox).
            Assert.AreEqual(3, m_book.SectionsOS.Count);
            IScrTxtPara para = (IScrTxtPara)m_book.SectionsOS[1].ContentOA.ParagraphsOS[0];

            AddFootnote(m_book, para, para.Contents.Length, "Footnote to delete");

            // Get number of footnotes in book.
            IScripture scr = Cache.LangProject.TranslatedScriptureOA;

            Assert.AreEqual(1, scr.ScriptureBooksOS.Count);
            int numFootnotes = m_book.FootnotesOS.Count;

            m_ScrPubCtrl.PageHeight  = 432000;        // 6 inches
            m_ScrPubCtrl.PageWidth   = 288000;        // 4 inches
            m_division.TopMargin     = 18000;         // Half inch
            m_division.BottomMargin  = 18000;
            m_division.InsideMargin  = 18000;
            m_division.OutsideMargin = 18000;
            m_ScrPubCtrl.Width       = 4 * 96;       // represents a window that is 4" wide at 96 DPI
            m_ScrPubCtrl.CreatePages();
            m_ScrPubCtrl.PrepareToDrawPages(0, 2000);
            IVwLayoutStream layoutStream = m_division.MainLayoutStream;
            IVwRootBox      rootbox      = layoutStream as IVwRootBox;

            // Select the first footnote in the last section of the book.
            SelectRangeOfChars(rootbox, 0, para.Contents.Length - 2, para.Contents.Length - 1);

            // Delete the footnote marker selection.
            //m_footnoteView.OnKeyDown(new KeyEventArgs(Keys.Delete));
            m_lp.Cache.ActionHandlerAccessor.EndUndoTask();             // Delete key generates own UOW
            m_ScrPubCtrl.PressKey(new KeyEventArgs(Keys.Delete));
            m_lp.Cache.ActionHandlerAccessor.BeginUndoTask("nonsence", "redo nonsence");

            // Confirm that there is one less footnote in the book.
            Assert.AreEqual(numFootnotes - 1, m_book.FootnotesOS.Count);
        }
예제 #16
0
        /// ------------------------------------------------------------------------------------
        /// <summary>
        /// Configure a PublicationControl
        /// </summary>
        /// ------------------------------------------------------------------------------------
        public void ConfigurePublication()
        {
            if (m_division != null)
            {
                m_division.Dispose();
            }
            if (m_ScrPubCtrl != null)
            {
                m_ScrPubCtrl.Dispose();
            }
            m_division = new DummyDivision(new DummyPrintConfigurer(m_fdoCache, null), 1);
            Publication pub = new Publication(m_fdoCache,
                                              m_fdoCache.LangProject.TranslatedScriptureOA.PublicationsOC.HvoArray[0]);

            m_ScrPubCtrl = new TeDummyPublication(pub, m_division, DateTime.Now);
            m_ScrPubCtrl.Configure();

            // Check initial state
            Assert.AreEqual(m_division, m_ScrPubCtrl.Divisions[0]);
            Assert.IsNotNull(m_division.MainVc as StVc);
            IVwLayoutStream layoutStream = m_division.MainLayoutStream;

            Assert.IsNotNull(layoutStream);
            Assert.AreEqual(layoutStream, m_division.MainLayoutStream,
                            "MainLayoutStream should not contruct a new stream each time");
            IVwRootBox rootbox = layoutStream as IVwRootBox;

            Assert.IsNotNull(rootbox);
            IVwSelection sel = rootbox.Selection;

            Assert.IsNotNull(sel);
            int       ich, hvo, tag, ws;       // dummies
            bool      fAssocPrev;
            ITsString tss;

            sel.TextSelInfo(false, out tss, out ich, out fAssocPrev, out hvo, out tag, out ws);
            Assert.AreEqual("14", tss.Text.Substring(0, 2));
        }
예제 #17
0
        /// ------------------------------------------------------------------------------------
        /// <summary>
        /// Constructs a TePrintLayoutConfig to configure the main print layout
        /// </summary>
        /// <param name="cache">The cache.</param>
        /// <param name="styleSheet">The style sheet.</param>
        /// <param name="publication">The publication.</param>
        /// <param name="viewType">Type of the view.</param>
        /// <param name="filterInstance">the book filter instance in effect</param>
        /// <param name="printDateTime">printing date and time</param>
        /// <param name="fIntroDivision">set to <c>true</c> for a division that displays book
        /// title and introduction material, <c>false</c> for a division that displays main
        /// scripture text.</param>
        /// <param name="hvoBook">The hvo of the book we're displaying.</param>
        /// <param name="sharedStream">A layout stream used for footnotes which is shared across
        /// multiple divisions</param>
        /// <param name="ws">The writing system to use for the view.</param>
        /// ------------------------------------------------------------------------------------
        public TePrintLayoutConfig(FdoCache cache, IVwStylesheet styleSheet,
                                   IPublication publication, TeViewType viewType, int filterInstance,
                                   DateTime printDateTime, bool fIntroDivision, int hvoBook, IVwLayoutStream sharedStream,
                                   int ws)
        {
            m_fdoCache           = cache;
            m_scr                = m_fdoCache.LangProject.TranslatedScriptureOA;
            m_styleSheet         = styleSheet;
            m_pub                = publication;
            m_viewType           = viewType;
            m_bookFilterInstance = filterInstance;
            m_printDateTime      = printDateTime;
            m_fIntroDivision     = fIntroDivision;
            m_hvoBook            = hvoBook;
            m_sharedStream       = sharedStream;
            m_ws = ws;

            m_sectionFilterInstance = g_nextSectionFilterInstance++;
            m_sectionFilter         = new FilteredSequenceHandler(cache, ScrBook.kClassId,
                                                                  m_sectionFilterInstance, this, this,
                                                                  new SimpleFlidProvider((int)ScrBook.ScrBookTags.kflidSections));

            m_paraCounter = ParagraphCounterManager.GetParaCounter(cache, (int)TeViewGroup.Scripture);
        }
예제 #18
0
		/// <summary>
		/// Attempt to find the page for a location quickly, if it is the
		/// main stream for some division and the location is within one of the
		/// elements for that division.
		/// </summary>
		/// <param name="x"></param>
		/// <param name="y"></param>
		/// <param name="fUp"></param>
		/// <param name="strm"></param>
		/// <param name="iDiv"></param>
		/// <returns></returns>
		private Page PossiblePageFromPrinter(int x, int y, bool fUp, IVwLayoutStream strm, out int iDiv)
		{
			iDiv = DivisionIndexForMainStream(strm);
			if (iDiv < 0 || Pages == null || Pages.Count == 0)
				return null; // can't find it this way unless it's a main stream and we have pages.

			DivisionLayoutMgr divMgr = Divisions[iDiv];
			int divOffset;
			for (int i = 0; i < Pages.Count; i++)
			{
				Page page = Pages[i];
				if (page.FirstDivOnPage > iDiv)
				{
					// No more pages of the required division.
					// If there is a previous page, it might be on there, otherwise we won't find it.
					if (i > 0)
						return Pages[i - 1];
					else
						return null;
				}
				PageElement firstPe;
				divOffset = page.OffsetFromTopOfDiv(strm, divMgr, out firstPe);
				if (y <= divOffset)
				{
					// We've found the first page of this division which starts at or beyond y.
					// Typically we want the previous page, since this one starts after y.
					// If there is no previous page return this one.
					if (i == 0)
						return page;
					// If we're exactly on the boundary and preferring down, we want this one;
					if (y == divOffset && !fUp)
						return page;
					// If we're in the overlap region we need to investigate. If it's actually on
					// this page we want this one.
					if (firstPe != null && y > divOffset - firstPe.OverlapWithPreviousElement)
					{
						Point locOnPage;
						if (page.GetPositionOnPage(strm, new Point(x, y), out locOnPage))
							return page;
					}
					return Pages[i - 1];
				}
			}

			// If we didn't find a page, see if the position is on the last page
			return Pages[Pages.Count - 1];
		}
예제 #19
0
		/// ------------------------------------------------------------------------------------
		/// <summary>
		/// Sets the accessible name of the stream.
		/// </summary>
		/// <param name="stream">The stream.</param>
		/// <param name="name">The name.</param>
		/// ------------------------------------------------------------------------------------
		public static void SetAccessibleStreamName(IVwLayoutStream stream, string name)
		{
			IAccessible acc = AccessibleRootObject(stream) as IAccessible;
			if (acc != null)
				acc.set_accName(null, name);
		}
예제 #20
0
		/// ------------------------------------------------------------------------------------
		/// <summary>
		/// Get the accessible object from the root box (implements IAccessible)
		/// </summary>
		/// ------------------------------------------------------------------------------------
		private static object AccessibleRootObject(IVwLayoutStream stream)
		{
			if (stream == null)
			{
				return null;
			}
			object obj = null;
#if !__MonoCS__
			if (stream is IOleServiceProvider)
			{
				IOleServiceProvider sp = (IOleServiceProvider)stream;
				Debug.Assert(sp != null);
				Guid guidAcc = Marshal.GenerateGuidForType(typeof(IAccessible));
				// 1st guid currently ignored.
				sp.QueryService(ref guidAcc, ref guidAcc, out obj);
			}
#else
			// TODO-Linux: for a VwLayoutStream, stream is IOleServiceProvider is returning true while QueryInterface (cast) throws exceptions a VwLayoutStream
			// QueryInterface doesn't report that its a VwLayoutStream.
#endif
			return obj;
		}
예제 #21
0
		/// --------------------------------------------------------------------------------
		/// <summary>
		/// Calls Page.AddPageElement().
		/// </summary>
		/// <param name="division">The division</param>
		/// <param name="stream">The stream (rootbox) which supplies data for this element</param>
		/// <param name="fPageElementOwnsStream"><c>true</c> if this element is responsible for
		/// closing its stream when it is destoyed</param>
		/// <param name="locationOnPage">Location where this stream is laid out, in printer
		/// pixels, relative to the top left of the physical page</param>
		/// <param name="dypOffsetToTopPageBoundaryOnPage">Offset in stream to top of data being shown
		/// on this page, in printer pixels</param>
		/// <param name="fMainStream"><c>true</c> if this element is for a "main" stream;
		/// <c>false</c> if it's for a subordinate stream or a Header/Footer stream</param>
		/// <param name="currentColumn">The current column (1-based).</param>
		/// <param name="totalColumns">The total columns in the specified stream.</param>
		/// <param name="columnGap">The gap between the columns.</param>
		/// <param name="columnHeight">The height of the current column.</param>
		/// <param name="isRightToLeft">if set to <c>true</c> the stream is right-to-left.
		/// Otherwise, it is left-to-right.</param>
		/// <param name="fReducesFreeSpaceFromTop">Flag indicating whether additoin of this
		/// element reduces the free space from top or bottom.</param>
		/// --------------------------------------------------------------------------------
		public void CallAddPageElement(DivisionLayoutMgr division,
			IVwLayoutStream stream, bool fPageElementOwnsStream, Rectangle locationOnPage,
			int dypOffsetToTopPageBoundaryOnPage, bool fMainStream, int currentColumn,
			int totalColumns, int columnGap, int columnHeight, bool isRightToLeft,
			bool fReducesFreeSpaceFromTop)
		{
			base.AddPageElement(division, stream, fPageElementOwnsStream, locationOnPage,
				dypOffsetToTopPageBoundaryOnPage, fMainStream, currentColumn, totalColumns,
				columnGap, columnHeight, 0, isRightToLeft, fReducesFreeSpaceFromTop);
		}
예제 #22
0
		/// -------------------------------------------------------------------------------------
		/// <summary>
		/// Inserts additonal pages if needed at dydPosition to approximately match the new
		/// estimated height when a lazy box has been expanded.
		/// </summary>
		/// <param name="changedSizePage">The last page whose top doesn't move (i.e., the one the
		/// lazy box is actually on). We may need to insert pages just after this.</param>
		/// <param name="strm">The IVwLayoutStream interface of the rootbox that is the main
		/// stream on at least some of the pages of this publication (i.e., this publication
		/// should be the IVwRootsite of the given rootbox).</param>
		/// <param name="dydSize">The amount the rootbox grew, in printer pixels. This is
		/// guaranteed to be positive.</param>
		/// <param name="dydPosition">The top of the lazy box which was (partially) expanded,
		/// split, etc (in printer pixels). Or the position of the top of the real box that got
		/// relazified.
		/// </param>
		/// <returns>true if there are not enough pages for the AutoScrollPosition to increase as
		/// much as required.</returns>
		/// -------------------------------------------------------------------------------------
		private bool InsertAdditionalPages(Page changedSizePage, IVwLayoutStream strm,
			int dydSize, int dydPosition)
		{
			Debug.Assert(changedSizePage != null);
			Debug.Assert(dydSize > 0);

			Page nextPage = PageAfter(changedSizePage);
			int heightOfChangedPage; // Current height, to next page or estimated end of doc.
			int iDiv = DivisionIndexForMainStream(strm);
			DivisionLayoutMgr divMgr = Divisions[iDiv];

			if (nextPage == null)
			{
				heightOfChangedPage = dydSize;
				// An empty page may have nothing from the main stream - can happen when project is
				// empty or filter excludes all content
				PageElement pe = changedSizePage.GetFirstElementForStream(strm);
				if (pe != null)
					heightOfChangedPage -= pe.OffsetToTopPageBoundary;
			}
			else
			{
				heightOfChangedPage = nextPage.OffsetFromTopOfDiv(divMgr) -
					changedSizePage.OffsetFromTopOfDiv(divMgr);
			}

			int desiredPageHeight = divMgr.AvailablePageHeightInPrinterPixels;
			// This computes the number of pages to add, if any, so that
			// if the tops of the pages are more than a page and a half apart we
			// insert enough pages so no page is more than an ideal page and a half long.
			// Subtracting half the desired page height accounts both for rounding and
			// the fact that one page (rather than zero) is the desired page height.
			int numberOfPagesToAdd = (heightOfChangedPage - desiredPageHeight / 2) /
				desiredPageHeight;
			// Pathologically, it might be possible for that calculation to produce
			// a negative number, if this page has shrunk to less than a half page from
			// previous lazy box expansions.
			if (numberOfPagesToAdd < 0)
				numberOfPagesToAdd = 0;
			Page pageToInsertAfter = changedSizePage;
			for (int i = 0; i < numberOfPagesToAdd; i++)
			{
				// Insert a new page.
				pageToInsertAfter = InsertPage(iDiv,
					pageToInsertAfter.OffsetFromTopOfDiv(divMgr) + desiredPageHeight,
					pageToInsertAfter);
			}
			// If we're increasing the autoscroll position, do it AFTER we possibly adjust
			// the autoscroll range, otherwise, the increased value might be greater than
			// the old range and get truncated.
			// Remember: Microsoft's idea of how to set AutoScrollPosition is brain-dead. We read
			// it as negative and have to set it as positive.
			int dydPosScreen = (int)(dydPosition * DpiYScreen / DpiYPrinter);
			if (-AutoScrollPosition.Y > dydPosScreen)
			{
				int dydDesiredAutoScrollY = (int)(AutoScrollPosition.Y - (dydSize * DpiYScreen /
					DpiYPrinter)); // larger negative
				AutoScrollPosition = new Point(
					-AutoScrollPosition.X, -dydDesiredAutoScrollY);
				// Something messy happened if we can't achieve that position (presumably
				// it is out of range, we didn't add enough pages).
				return (AutoScrollPosition.Y != dydDesiredAutoScrollY);
			}
			return false; // We get here only if we didn't have to adjust scroll position at all.
		}
예제 #23
0
		/// ------------------------------------------------------------------------------------
		/// <summary>
		/// Gets the print layout configurer.
		/// </summary>
		/// <param name="fIntroDivision">set to <c>true</c> for a division that displays book
		/// title and introduction material, <c>false</c> for a division that displays main
		/// scripture text.</param>
		/// <param name="hvoBook">The hvo of the book.</param>
		/// <param name="sharedStream">A layout stream used for footnotes which is shared across
		/// multiple divisions</param>
		/// <param name="ws">The writing system</param>
		/// <returns>A print layout configurer</returns>
		/// ------------------------------------------------------------------------------------
		protected override TePrintLayoutConfig GetPrintLayoutConfigurer(bool fIntroDivision,
			int hvoBook, IVwLayoutStream sharedStream, int ws)
		{
			return new TeBtPrintLayoutConfig(m_cache, m_stylesheet, m_publication, m_viewType,
				m_filterInstance, m_printDateTime, fIntroDivision, hvoBook, sharedStream, ws);
		}
예제 #24
0
 /// ------------------------------------------------------------------------------------
 /// <summary>
 /// Expose the PublicationControl.AddsSharedSubstream.
 /// </summary>
 /// <param name="subStream">The substream.</param>
 /// ------------------------------------------------------------------------------------
 internal new void AddSharedSubstream(IVwLayoutStream subStream)
 {
     base.AddSharedSubstream(subStream);
 }
예제 #25
0
 /// --------------------------------------------------------------------------------
 /// <summary>
 /// Initializes a new instance of the <see cref="DummyDivisionMgr"/> class.
 /// </summary>
 /// <param name="stream">The stream.</param>
 /// <param name="fMainStreamRightToLeft">if set to <c>true</c> if the main stream in
 /// the test is right-to-left; otherwise <c>false</c>.</param>
 /// --------------------------------------------------------------------------------
 public DummyDivisionMgr(IVwLayoutStream stream, bool fMainStreamRightToLeft) : base(null, null, 0)
 {
     m_mainLayoutStream       = stream;
     m_fMainStreamRightToLeft = fMainStreamRightToLeft;
 }
예제 #26
0
		/// <summary>
		/// Executes in two distinct scenarios.
		///
		/// 1. If disposing is true, the method has been called directly
		/// or indirectly by a user's code via the Dispose method.
		/// Both managed and unmanaged resources can be disposed.
		///
		/// 2. If disposing is false, the method has been called by the
		/// runtime from inside the finalizer and you should not reference (access)
		/// other managed objects, as they already have been garbage collected.
		/// Only unmanaged resources can be disposed.
		/// </summary>
		/// <param name="disposing"></param>
		/// <remarks>
		/// If any exceptions are thrown, that is fine.
		/// If the method is being done in a finalizer, it will be ignored.
		/// If it is thrown by client code calling Dispose,
		/// it needs to be handled by fixing the bug.
		///
		/// If subclasses override this method, they should call the base implementation.
		/// </remarks>
		protected virtual void Dispose(bool disposing)
		{
			System.Diagnostics.Debug.WriteLineIf(!disposing, "****** Missing Dispose() call for " + GetType().Name + ". ****** ");
			// Must not be run more than once.
			if (m_isDisposed)
				return;

			IVwRootBox rootb;
			if (disposing)
			{
				// Dispose managed resources here.
				if (m_subStreams != null)
				{
					foreach (SubordinateStream stream in m_subStreams)
					{
						if (!stream.m_fShared)
						{
							rootb = stream.m_stream as IVwRootBox;
							if (rootb != null)
								rootb.Close();
							var disposableStreamVc = stream.m_vc as IDisposable;
							if (disposableStreamVc != null)
								disposableStreamVc.Dispose();
						}
					}
					m_subStreams.Clear();
				}
				var disposable = m_mainVc as IDisposable;
				if (disposable != null)
					disposable.Dispose();
				foreach (var hfVc in m_CreatedHfVcs)
				{
					disposable = hfVc as IDisposable;
					if (disposable != null)
						disposable.Dispose();
				}
				m_CreatedHfVcs.Clear();
			}

			// Dispose unmanaged resources here, whether disposing is true or false.
			rootb = m_mainLayoutStream as IVwRootBox;
			if (rootb != null)
				rootb.Close();

			m_mainLayoutStream = null;
			m_subStreams = null;
			m_mainVc = null;
			m_CreatedHfVcs = null;
			m_isDisposed = true;
		}
예제 #27
0
		/// ------------------------------------------------------------------------------------
		/// <summary>
		/// Indicates whether this division displays the given stream.
		/// </summary>
		/// <param name="stream">The stream to check</param>
		/// <returns><c>true</c> if this DivisionLayoutMgr displays this stream</returns>
		/// ------------------------------------------------------------------------------------
		internal bool IsManagerForStream(IVwLayoutStream stream)
		{
			CheckDisposed();

			return (MainLayoutStream == stream);
		}
예제 #28
0
		/// ------------------------------------------------------------------------------------
		/// <summary>
		/// Shuts down the FDO cache
		/// </summary>
		/// ------------------------------------------------------------------------------------
		public override void TestTearDown()
		{
			if (m_firstDivision != null)
			{
				m_firstDivision.m_hPagesBroken.Clear();
				m_firstDivision.Dispose();
				m_firstDivision = null;
			}

			// Make sure we close all the rootboxes
			if (m_pub != null)
			{
				m_pub.Dispose();
				m_pub = null;
			}

			m_subViewVc = null;
			m_subStream = null;

			base.TestTearDown();
		}
예제 #29
0
		/// ------------------------------------------------------------------------------------
		/// <summary>
		/// Given a point in printer(layout) pixels relative to the top left of the stream,
		/// determine which page it occurs on, and return that page, along with the
		/// distance from the top of the page to the point. If the page does not currently
		/// contain valid elements, this may be somewhat approximate.
		/// </summary>
		/// <param name="x">X coord, important where pages overlap</param>
		/// <param name="y">Y coordinate (in printer pixels), from the top of the stream.</param>
		/// <param name="fUp">If the point is right at a page boundary, return the first
		/// page if this is true, the second if it is false.</param>
		/// <param name="strm">The stream that contains the y position.</param>
		/// <param name="dyPageScreen">Distance in screen coords from top of page to
		/// the specified location.</param>
		/// <param name="iDiv">Index of the division at the specified location.</param>
		/// <param name="layedOutPage">Flag returned as <c>true</c> if a page was layed out during
		/// this call</param>
		/// <returns>The page that contains the y-position, or <c>null</c>.</returns>
		/// ------------------------------------------------------------------------------------
		protected internal Page PageFromPrinterY(int x, int y, bool fUp, IVwLayoutStream strm,
			out int dyPageScreen, out int iDiv, out bool layedOutPage)
		{
			layedOutPage = false;
			Page possiblePage = PossiblePageFromPrinter(x, y, fUp, strm, out iDiv);
			if (possiblePage != null)
			{
				Point locOnPage;
				if (possiblePage.GetPositionOnPage(strm, new Point(x, y), out locOnPage))
				{
					dyPageScreen = ConvertPrintEltOffsetToPixelsY(locOnPage.Y, DpiYScreen);
					return possiblePage;
				}
			}

			// footnotes aren't in page element stream, no use looking for it
			if (strm == null)
			{
				dyPageScreen = 0; // satisfy compiler
				return null;
			}

			// If it's not the main stream or we didn't find it the quick way, all we can
			// do is look for a hopeful element. Since the thing might well be on even a
			// broken page, for this we consider even broken pages...to make things more
			// accurate we fix any broken page.
			if (Pages != null && Pages.Count > 0)
			{
				bool layedOutSomething;
				bool foundPageOnStream = false;
				do
				{
					layedOutSomething = false;
					foreach (Page page in Pages)
					{
						if (page.LayOutIfNeeded())
						{
							layedOutSomething = true;
							layedOutPage = true;
							break;
						}
						bool foundElemOnStream = false;
						foreach (PageElement pe in page.PageElements)
						{
							if (pe.m_stream != strm)
								continue;
							foundPageOnStream = true;
							foundElemOnStream = true;
							// If y is in the range for this page element, we probably stop here...
							if (y >= pe.OffsetToTopPageBoundary - pe.OverlapWithPreviousElement &&
								y <= pe.OffsetToTopPageBoundary + pe.LocationOnPage.Height)
							{
								if (y < pe.OffsetToTopPageBoundary && !pe.IsInOurPartOfOverlap(new Point(x, y)))
									continue;
								// Except, if we're exactly at the bottom and want to be at the top,
								// keep trying. (Enhance JohnT: not sure we can depend on fUp any more,
								// now we have overlap...)
								if ((!fUp) && y == pe.OffsetToTopPageBoundary + pe.LocationOnPage.Height)
									continue;
								// Also, in case the element might be out of order, if we we're
								// exactly at the top and want to be at the bottom, keep trying
								if (fUp && y <= pe.OffsetToTopPageBoundary - pe.OverlapWithPreviousElement)
									continue;

								int yOnPage = y - pe.OffsetToTopPageBoundary - pe.OverlapWithPreviousElement + pe.LocationOnPage.Top;

								dyPageScreen = ConvertPrintEltOffsetToPixelsY(yOnPage, DpiYScreen);
								return page;
							}
							else if (y < pe.OffsetToTopPageBoundary)
							{
								// have gone too far, can end the search. Y must be on
								// a page that hasn't been layed out.
								dyPageScreen = 0;	// satisfy compiler
								return null;
							}
						}
						// another check to see that we've gone too far
						if (foundPageOnStream && !foundElemOnStream)
						{
							dyPageScreen = 0; // satisfy compiler
							return null;
						}
					}
				}
				while (layedOutSomething);
			}
			dyPageScreen = 0;	// satisfy compiler
			return null;
		}
예제 #30
0
		/// ------------------------------------------------------------------------------------
		/// <summary>
		/// Gets the index of the division for the given stream
		/// </summary>
		/// <returns>The index of the division for the given stream if it is the main stream
		/// for any division in this publication; Otherwise -1.</returns>
		/// ------------------------------------------------------------------------------------
		public int DivisionIndexForMainStream(IVwLayoutStream stream)
		{
			CheckDisposed();

			if (stream == null)
				return -1;

			for (int i = 0; i < m_divisions.Count; i++)
			{
				if (m_divisions[i].IsManagerForStream(stream))
					return i;
			}
			return -1;
		}
예제 #31
0
        public void TwoColumnTwoBooks()
        {
            foreach (PubDivision div in m_dbPub.DivisionsOS)
            {
                div.NumColumns = 2;
            }

            m_BookFilter.UpdateFilter(
                Cache.LangProject.TranslatedScriptureOA.ScriptureBooksOS.HvoArray[0],
                Cache.LangProject.TranslatedScriptureOA.ScriptureBooksOS.HvoArray[1]);
            Assert.AreEqual(2, m_BookFilter.BookCount);

            m_ScrPubCtrl.Configure();
            m_ScrPubCtrl.CreatePages();

            Assert.AreEqual(4, m_ScrPubCtrl.Divisions.Count);
            DivisionLayoutMgr divTitleIntroFirstBook  = m_ScrPubCtrl.Divisions[0];
            DivisionLayoutMgr divScriptureFirstBook   = m_ScrPubCtrl.Divisions[1];
            DivisionLayoutMgr divTitleIntroSecondBook = m_ScrPubCtrl.Divisions[2];
            DivisionLayoutMgr divScriptureSecondBook  = m_ScrPubCtrl.Divisions[3];

            Assert.Greater(divTitleIntroFirstBook.AvailableMainStreamColumWidthInPrinterPixels,
                           divScriptureFirstBook.AvailableMainStreamColumWidthInPrinterPixels);
            Assert.AreEqual(divTitleIntroFirstBook.AvailableMainStreamColumWidthInPrinterPixels,
                            divTitleIntroFirstBook.AvailablePageWidthInPrinterPixels);
            Assert.AreEqual(divTitleIntroFirstBook.AvailableMainStreamColumWidthInPrinterPixels,
                            divTitleIntroSecondBook.AvailableMainStreamColumWidthInPrinterPixels);
            Assert.AreEqual(divScriptureFirstBook.AvailableMainStreamColumWidthInPrinterPixels,
                            divScriptureSecondBook.AvailableMainStreamColumWidthInPrinterPixels);
            Assert.AreNotEqual(DivisionStartOption.Continuous, divTitleIntroFirstBook.StartAt);
            Assert.AreEqual(DivisionStartOption.Continuous, divScriptureFirstBook.StartAt);
            Assert.AreNotEqual(DivisionStartOption.Continuous, divTitleIntroSecondBook.StartAt);
            Assert.AreEqual(DivisionStartOption.Continuous, divScriptureSecondBook.StartAt);
            Assert.Greater(divTitleIntroFirstBook.MainRootBox.Height, 0);
            Assert.Greater(divScriptureFirstBook.MainRootBox.Height, 0);
            // Intro of Philemon is quite long, so we just test that the heights of the two division are not equal
            Assert.AreNotEqual(divScriptureFirstBook.MainRootBox.Height, divTitleIntroFirstBook.MainRootBox.Height);
            Assert.Greater(divTitleIntroSecondBook.MainRootBox.Height, 0);
            Assert.Greater(divScriptureSecondBook.MainRootBox.Height, 0);
            Assert.Greater(divScriptureSecondBook.MainRootBox.Height, divTitleIntroSecondBook.MainRootBox.Height);

            Assert.AreEqual(2, m_ScrPubCtrl.Pages[1].FirstDivOnPage,
                            "Page 2 should start with second book (third division)");
            Assert.AreEqual(0, m_ScrPubCtrl.Pages[1].OffsetFromTopOfDiv(
                                m_ScrPubCtrl.Divisions[m_ScrPubCtrl.Pages[2].FirstDivOnPage]),
                            "Third division should start on top of page 2");

            Assert.Greater(m_ScrPubCtrl.PageCount, 2);

            Assert.IsNotNull(divTitleIntroFirstBook.MainVc as ScriptureBookIntroVc);
            Assert.IsNotNull(divScriptureFirstBook.MainVc as ScriptureBodyVc);
            Assert.IsNotNull(divTitleIntroSecondBook.MainVc as ScriptureBookIntroVc);
            Assert.IsNotNull(divScriptureSecondBook.MainVc as ScriptureBodyVc);

            foreach (DivisionLayoutMgr div in m_ScrPubCtrl.Divisions)
            {
                IVwLayoutStream layoutStream = div.MainLayoutStream;
                Assert.IsNotNull(layoutStream);
                Assert.IsNotNull(layoutStream as IVwRootBox);
            }
        }
예제 #32
0
		/// ------------------------------------------------------------------------------------
		/// <summary>
		/// Exposes the PageFromPrinterY method
		/// </summary>
		/// <param name="y">The y.</param>
		/// <param name="fUp">If the point is right at a page boundary, return the first
		/// page if this is true, the second if it is false.</param>
		/// <param name="strm">The STRM.</param>
		/// <param name="dyPageScreen">The dy page screen.</param>
		/// <returns></returns>
		/// ------------------------------------------------------------------------------------
		public Page CallPageFromPrinterY(int y, bool fUp, IVwLayoutStream strm,
			out int dyPageScreen)
		{
			int iDiv; // not used in the tests
			return PageFromPrinterY(0, y, fUp, strm, out dyPageScreen, out iDiv);
		}
예제 #33
0
		/// <summary>
		/// Record which page(s) were broken.
		/// </summary>
		/// <param name="lay"></param>
		/// <param name="hPage"></param>
		public override void PageBroken(IVwLayoutStream lay, int hPage)
		{
			CheckDisposed();

			m_hPagesBroken.Add(hPage);
			base.PageBroken(lay, hPage);
		}
예제 #34
0
		//private Form m_form;
		/// ------------------------------------------------------------------------------------
		/// <summary>
		/// Creates the division and publication.
		/// </summary>
		/// <param name="columns">The number of columns.</param>
		/// <param name="fSharedSubStreams">if set to <c>true</c> configure the print layout
		/// view using shared sub streams; otherwise, each division will create an owned
		/// substream.</param>
		/// ------------------------------------------------------------------------------------
		private void CreateDivisionAndPublication(int columns, bool fSharedSubStreams)
		{
			if (m_firstDivision != null)
				m_firstDivision.Dispose();
			if (m_pub != null)
				m_pub.Dispose();
			m_subStream = null;
			if (fSharedSubStreams)
				m_subStream = VwLayoutStreamClass.Create();
			m_firstDivision = new DummyDivision(new DummyPrintConfigurer(Cache, m_subStream),
				columns);
			IPublication pub =
				Cache.LangProject.TranslatedScriptureOA.PublicationsOC.ToArray()[0];
			m_pub = new DummyPublication(pub, m_firstDivision, DateTime.Now);
			if (fSharedSubStreams)
			{
				m_subViewVc = new DummyFirstSubViewVc();
				int hvoScr = Cache.LangProject.TranslatedScriptureOA.Hvo;
				IVwRootBox rootbox = (IVwRootBox)m_subStream;
				rootbox.DataAccess = Cache.MainCacheAccessor;
				rootbox.SetRootObject(hvoScr, m_subViewVc,
					DummyFirstSubViewVc.kfragScrFootnotes, null);

				m_pub.AddSharedSubstream(m_subStream);
			}

		}
예제 #35
0
		/// ------------------------------------------------------------------------------------
		/// <summary>
		/// Expose the PublicationControl.AddsSharedSubstream.
		/// </summary>
		/// <param name="subStream">The substream.</param>
		/// ------------------------------------------------------------------------------------
		internal new void AddSharedSubstream(IVwLayoutStream subStream)
		{
			base.AddSharedSubstream(subStream);
		}
예제 #36
0
		/// -------------------------------------------------------------------------------------
		/// <summary>
		/// The layout manager is informed by this method that the (primary) layout stream 'lay'
		/// has determined that references to the objects objectGuids occur on the page. The input
		/// value of dysAvailHeight indicates how much of the height allocated to 'lay' for this
		/// page will remain available if the text containing these references is added to the
		/// page (assuming that adding them does not reduce the space available for 'lay').
		/// This is an alternative implementation of AddDependentObjects for the case where
		/// RootOnEachPage is true.
		/// </summary>
		/// <param name="lay">The primary layout stream filling the page</param>
		/// <param name="vg">The graphics object being used to layout the page</param>
		/// <param name="hPage">The handle to the page being laid out</param>
		/// <param name="cguid">Number of elements in objectGuids array</param>
		/// <param name="objectGuids">Array of GUIDS representing objects to be laid out in a
		/// separate layout stream</param>
		/// <param name="fAllowFail">Indicates whether this method can fail (return
		/// <c>fFailed == true</c>). If this is false, this method should force the requested
		/// objects to be laid out within the available space, even if it requires omitting or
		/// truncating some or all of them</param>
		/// <param name="fFailed">If the available height would become negative (typically
		/// because the objects must share space with 'lay' and they don't fit in the available
		/// height), this will be set to true (unless fAllowFail is false).</param>
		/// <param name="dysAvailHeight">Input value indicates how much of the height allocated
		/// to 'lay' for this page will remain available if the text containing these references
		/// is added to the page, assuming that adding them does not reduce the space available
		/// for 'lay'. The output value indicates how much is left after laying out these
		/// dependent objects.</param>
		/// -------------------------------------------------------------------------------------
		public virtual void AddDependentObjectsToPageRoot(IVwLayoutStream lay, IVwGraphics vg,
			int hPage, int cguid, Guid[] objectGuids, bool fAllowFail, out bool fFailed,
			ref int dysAvailHeight)
		{
			int dysAvailableHeight = dysAvailHeight;
			fFailed = false;

			int[] rgHvo = new int[cguid];
			int i = 0;
			foreach (Guid guid in objectGuids)
			{
				int hvo = m_configurer.GetIdFromGuid(guid);
				if (hvo != 0)
					rgHvo[i++] = hvo; // only add the ones we can match.
				else
					cguid--; // found unmatched guid
			}
			Page page = Publication.FindPage(hPage);
			if (page.DoingTrialLayout)
			{
				page.NoteDependentRoots(rgHvo);
				// note that we do not need to adjust dysAvailHeight, because in trial mode the
				// INITIAL height is set to the space available minus the old dependent root
				// objects view's height.
				return;
			}

			// Collect some information we need
			IVwLayoutStream dependentStream = page.DependentObjectsRootStream;
			IVwRootBox dependentRootbox = (IVwRootBox)dependentStream;
			int hvoRoot = m_configurer.DependentRootHvo;
			int dependentObjTag = m_configurer.DependentRootTag;
			int dependentObjFrag = m_configurer.DependentRootFrag;
			IDependentObjectsVc depObjVc;
			ISilDataAccess sda = m_configurer.DataAccess;
			int oldHeight = 0;
			int startIndex = -1;
			int endIndex = -1;
			int prevStartIndex;
			int prevEndIndex;
			if (dependentRootbox == null)
			{
				// no pre-existing rootbox for this page so create a new one
				depObjVc = m_configurer.DependentRootVc;
				dependentStream = VwLayoutStreamClass.Create();
				dependentStream.SetManager(this);
				page.DependentObjectsRootStream = dependentStream;
				dependentRootbox = (IVwRootBox)dependentStream;
				dependentRootbox.SetSite(Publication);
				dependentRootbox.DataAccess = sda;
				dependentRootbox.SetRootObject(hvoRoot, depObjVc, dependentObjFrag, m_configurer.StyleSheet);
				// Set up the view constructor to show the correct objects
				if (cguid > 0)
				{
					startIndex = sda.GetObjIndex(hvoRoot, dependentObjTag, rgHvo[0]);
					endIndex = sda.GetObjIndex(hvoRoot, dependentObjTag, rgHvo[cguid - 1]);
					Debug.Assert(startIndex >= 0 && endIndex >= 0);
				}
				depObjVc.StartingObjIndex = startIndex;
				depObjVc.EndingObjIndex = endIndex;
				prevStartIndex = prevEndIndex = -1;
			}
			else
			{
				// A rootbox was already created for this page, just update what is shown
				oldHeight = dependentRootbox.Height;
				IVwViewConstructor vc;
				IVwStylesheet ss;
				dependentRootbox.GetRootObject(out hvoRoot, out vc, out dependentObjFrag, out ss);
				depObjVc = (IDependentObjectsVc)vc;

				prevStartIndex = depObjVc.StartingObjIndex;
				prevEndIndex = depObjVc.EndingObjIndex;
				// Update the view constructor with the new objects
				if (cguid > 0)
				{
					startIndex = sda.GetObjIndex(hvoRoot, dependentObjTag, rgHvo[0]);
					endIndex = sda.GetObjIndex(hvoRoot, dependentObjTag, rgHvo[cguid - 1]);
					Debug.Assert(startIndex >= 0 && endIndex >= 0);
					Debug.Assert(startIndex > depObjVc.EndingObjIndex && endIndex > depObjVc.EndingObjIndex);

					if (depObjVc.StartingObjIndex == -1)
					{
						// Most likely all the shown objects were removed from the view constructor.
						// We need to make sure we have a valid starting index.
						depObjVc.StartingObjIndex = startIndex;
					}
					depObjVc.EndingObjIndex = endIndex;
				}
			}

			if (startIndex < 0 || endIndex < 0)
			{
				fFailed = fAllowFail;
				return;
			}

			// update the rootbox with the new items.
			try
			{
				// propChanged generates a PageBroken notification we need to ignore.
				m_hPageBeingBuilt = hPage;
				int count = endIndex - startIndex + 1;
				dependentRootbox.PropChanged(hvoRoot, dependentObjTag, startIndex, count, count);
			}
			finally
			{
				m_hPageBeingBuilt = 0;
			}

			PublicationControl.SetAccessibleStreamName(dependentStream,
				"Dependent stream for page " + page.PageNumber);

			// The actual laying out is probably redundant, but this lets the dependent stream
			// know what page it's on, which is useful for notifications. With an interface
			// change we could do this more efficiently, I think.
			for (int ihvo = startIndex; ihvo <= endIndex; ihvo++)
			{
				SelLevInfo[] rgSelLevInfo = new SelLevInfo[1];
				rgSelLevInfo[0].tag = dependentObjTag;
				rgSelLevInfo[0].ihvo = ihvo - depObjVc.StartingObjIndex;

				dependentStream.LayoutObj(vg, AvailablePageWidthInPrinterPixels, 0,
					rgSelLevInfo.Length, rgSelLevInfo, hPage);
			}
			int newHeight = dependentRootbox.Height;
			int dysHeightUsed = newHeight - oldHeight;

			// If this stream is just now being added to the page, need to allow for gap between elements.
			if (oldHeight == 0)
				dysHeightUsed += VerticalGapBetweenElements * vg.YUnitsPerInch / MiscUtils.kdzmpInch;

			if ((dysHeightUsed * m_numberMainStreamColumns) > dysAvailHeight)
			{
				// We can't add everything needed for the current chunk (in the main stream),
				// so we need to fail (if that's permitted), and roll everything back
				if (fAllowFail)
				{
					fFailed = true;
					// roll back: remove the extra objects.
					try
					{
						int newStartObjIndex = depObjVc.StartingObjIndex;
						int newEndObjIndex = depObjVc.EndingObjIndex;

						depObjVc.StartingObjIndex = prevStartIndex;
						depObjVc.EndingObjIndex = prevEndIndex;
						int count = endIndex - newStartObjIndex + 1;
						dependentRootbox.PropChanged(hvoRoot, dependentObjTag, newStartObjIndex, count, count);
					}
					finally
					{
						m_hPageBeingBuilt = 0;
					}
					return;
				}
				else
					dysAvailableHeight = 0;
			}
			else
			{
				// When we layout with multiple columns, we pretend to have one large
				// page. But the substreams are still only one column which means
				// they affect all columns, so we have to multiply the height used
				// with the number of columns.
				dysAvailableHeight -= (dysHeightUsed * m_numberMainStreamColumns);
			}

			// Now we know all the objects fit (or else we weren't allowed to fail), so
			// adjust the rectangle occupied by the element.

			// First time thru, the previous "element" is the bottom page margin.
			// So far we only have one, but the code here shows vestiges of the loop in the
			// main AddDependentObjects.
			int ysTopOfPrevElement = Publication.PageHeightInPrinterPixels - BottomMarginInPrinterPixels;
			if (newHeight > 0)
				AddOrAdjustPageElement(page, ysTopOfPrevElement, newHeight, dependentStream, 0);

			dysAvailHeight = dysAvailableHeight;
		}
예제 #37
0
 /// ------------------------------------------------------------------------------------
 /// <summary>
 /// Gets the print layout configurer.
 /// </summary>
 /// <param name="fIntroDivision">set to <c>true</c> for a division that displays book
 /// title and introduction material, <c>false</c> for a division that displays main
 /// scripture text.</param>
 /// <param name="hvoBook">The hvo of the book.</param>
 /// <param name="sharedStream">A layout stream used for footnotes which is shared across
 /// multiple divisions</param>
 /// <param name="ws">The writing system</param>
 /// <returns>A print layout configurer</returns>
 /// ------------------------------------------------------------------------------------
 protected override TePrintLayoutConfig GetPrintLayoutConfigurer(bool fIntroDivision,
                                                                 int hvoBook, IVwLayoutStream sharedStream, int ws)
 {
     return(new TeBtPrintLayoutConfig(m_cache, m_stylesheet, m_publication, m_viewType,
                                      m_filterInstance, m_printDateTime, fIntroDivision, hvoBook, sharedStream, ws));
 }
예제 #38
0
파일: Page.cs 프로젝트: sillsdev/WorldPad
		/// ------------------------------------------------------------------------------------
		/// <summary>
		/// Gets the number of printer pixels (source/layout units) from the top of the given
		/// division's main layout stream to the top of the data represented by the first page
		/// element on this page for that stream. This may only be an estimate, particularly if:
		/// <list type="normal">
		/// 		<item>this page has no elements (at least for the given division)</item>
		/// 		<item>this page is broken</item>
		/// 		<item>there are previous pages that are not fully laid out (or broken)</item>
		/// 	</list>
		/// </summary>
		/// <param name="stream">The stream whose offset we want (may or may not be the main
		/// layout stream for the given division, but must not be null).</param>
		/// <param name="div">The division layout manager (can be null if the stream is not
		/// a main layout stream).</param>
		/// <param name="pe">The first page element on this page for the given stream.</param>
		/// <returns>The offset</returns>
		/// ------------------------------------------------------------------------------------
		internal int OffsetFromTopOfDiv(IVwLayoutStream stream, DivisionLayoutMgr div,
			out PageElement pe)
		{
			CheckDisposed();
			pe = GetFirstElementForStream(stream);
			if (pe != null)
				return pe.OffsetToTopPageBoundary;
			return (div == PubControl.Divisions[FirstDivOnPage]) ? m_ypOffsetFromTopOfDiv : 0;
		}
예제 #39
0
		/// ------------------------------------------------------------------------------------
		/// <summary>
		/// Adds a shared substream.
		/// </summary>
		/// <param name="subStream">The substream.</param>
		/// ------------------------------------------------------------------------------------
		protected void AddSharedSubstream(IVwLayoutStream subStream)
		{
			(subStream as IVwRootBox).SetSite(this);
			m_sharedStreams.Add(subStream);
		}
예제 #40
0
파일: Page.cs 프로젝트: sillsdev/WorldPad
		/// ------------------------------------------------------------------------------------
		/// <summary>
		/// Gets the position of the point pt on the page.
		/// </summary>
		/// <param name="stream">The stream.</param>
		/// <param name="pt">The point in the stream.</param>
		/// <param name="result">the converted result</param>
		/// <returns>true if <paramref name="pt"/> is on this page.</returns>
		/// ------------------------------------------------------------------------------------
		public bool GetPositionOnPage(IVwLayoutStream stream, Point pt, out Point result)
		{
			// find page element that contains pt
			foreach (PageElement pe in PageElements)
			{
				if (pt.Y <= pe.OffsetToTopPageBoundary + pe.ColumnHeight &&
					pe.m_stream == stream)
				{
					if (pe.OffsetToTopPageBoundary <= pt.Y || pe.IsInOurPartOfOverlap(pt))
					{
						int x = pe.LocationOnPage.Left + pt.X;
						int y = pe.LocationOnPage.Top + (pt.Y - pe.OffsetToTopPageBoundary);
						result = new Point(x, y);
						return true;
					}
				}
			}
			result = new Point(-1, -1);
			return false;
		}
예제 #41
0
파일: Page.cs 프로젝트: sillsdev/WorldPad
		/// ------------------------------------------------------------------------------------
		/// <summary>
		/// Adds a page element, representing a layout stream in a particular location on the
		/// page.
		/// </summary>
		/// <param name="division">The division</param>
		/// <param name="stream">The stream (rootbox) which supplies data for this element</param>
		/// <param name="fPageElementOwnsStream"><c>true</c> if this element is responsible for
		/// closing its stream when it is destoyed</param>
		/// <param name="locationOnPage">Location where this stream is laid out, in printer
		/// pixels, relative to the top left of the physical page</param>
		/// <param name="dypOffsetToTopOfDataOnPage">Offset in stream to top of data being shown
		/// on this page, in printer pixels</param>
		/// <param name="fMainStream"><c>true</c> if this element is for a "main" stream;
		/// <c>false</c> if it's for a subordinate stream or a Header/Footer stream</param>
		/// <param name="currentColumn">The current column (1-based).</param>
		/// <param name="totalColumns">The total columns in the specified stream.</param>
		/// <param name="columnGap">The gap between the columns.</param>
		/// <param name="columnHeight">The height of the current column.</param>
		/// <param name="dypOverlapWithPreviousElement"></param>
		/// <param name="isRightToLeft">if set to <c>true</c> the stream is right-to-left.
		/// Otherwise, it is left-to-right.</param>
		/// <param name="fReducesFreeSpaceFromTop">Flag indicating whether additoin of this
		/// element reduces the free space from top or bottom.</param>
		/// ------------------------------------------------------------------------------------
		internal protected void AddPageElement(DivisionLayoutMgr division, IVwLayoutStream stream,
			bool fPageElementOwnsStream, Rectangle locationOnPage, int dypOffsetToTopOfDataOnPage,
			bool fMainStream, int currentColumn, int totalColumns, int columnGap, int columnHeight,
			int dypOverlapWithPreviousElement, bool isRightToLeft, bool fReducesFreeSpaceFromTop)
		{
			CheckDisposed();

			PageElement newElement = new PageElement(division, stream, fPageElementOwnsStream,
						locationOnPage, dypOffsetToTopOfDataOnPage, fMainStream,
						currentColumn, totalColumns, columnGap, columnHeight, dypOverlapWithPreviousElement,
						isRightToLeft);
			InsertPageElement(newElement);

			AdjustFreeSpace(locationOnPage, fReducesFreeSpaceFromTop, newElement);
		}
예제 #42
0
파일: Page.cs 프로젝트: sillsdev/WorldPad
		///// ------------------------------------------------------------------------------------
		///// <summary>
		///// True if the page is ready for drawing. When this is true, the page had better not
		///// get broken; otherwise, bad stuff will happen.
		///// For tests, we don't actually want to set this because we don't really draw the
		///// pages, so this flag never gets cleared. It's purpose in the production code is just
		///// to catch problems.
		///// </summary>
		///// ------------------------------------------------------------------------------------
		//internal virtual bool ReadyForDrawing
		//{
		//    set
		//    {
		//        CheckDisposed();
		//        Debug.Assert(!m_fBroken);
		//        m_fReadyForDrawing = value;
		//    }
		//}

		private void DisposeDependentObjectStream()
		{
			if (m_dependentObjectRootStream != null)
			{
				// we'll need a new root box when next laid out
				// Enhance JohnT: could we save time and effort by retaining it to reuse
				// if the page is reused?
				//PageElement element = GetFirstElementForStream(m_dependentObjectRootStream);
				//if (element != null)
				//    m_pageElements.Remove(element); // Review JohnT: anything else to do??
				(m_dependentObjectRootStream as IVwRootBox).Close();
				m_dependentObjectRootStream = null;
			}
		}
예제 #43
0
파일: Page.cs 프로젝트: sillsdev/WorldPad
		/// ------------------------------------------------------------------------------------
		/// <summary>
		/// Retrieves the page element that corresponds to the given stream. If multiple
		/// elements correspond to this stream, it gets the one with the smallest offset in the
		/// division (i.e., the one which corresponds to the highest place in the
		/// total document).
		/// </summary>
		/// <param name="stream">The stream</param>
		/// <returns>The page element that corresponds to the given stream, or null if none
		/// found.</returns>
		/// ------------------------------------------------------------------------------------
		public PageElement GetFirstElementForStream(IVwLayoutStream stream)
		{
			CheckDisposed();

			foreach (PageElement pe in m_pageElements)
			{
				if (pe.m_stream == stream)
					return pe;
			}
			return null;
		}
예제 #44
0
		/// -------------------------------------------------------------------------------------
		/// <summary>
		/// Configurer should call this method for each shared subordinate stream (such as
		/// foootnotes) after creating the main stream.
		/// </summary>
		/// <param name="stream">The shared subordinate stream.</param>
		/// <param name="vc">The view constructor to be used for laying out this stream</param>
		/// <param name="subStreamDelegate">Implements view-specific callback methods</param>
		/// -------------------------------------------------------------------------------------
		public void AddSharedSubordinateStream(IVwLayoutStream stream, IVwViewConstructor vc,
			ISubordinateStreamDelegate subStreamDelegate)
		{
			CheckDisposed();

			SubordinateStream subStream;
			subStream.m_fShared = true;
			subStream.m_vc = vc;
			subStream.m_delegate = subStreamDelegate;
			subStream.m_stream = stream;
			// We're not always the manager for the shared stream, but sometimes, and it is
			// better to have a valid object as manager then to get a crash :-)
			subStream.m_stream.SetManager(this);
			m_subStreams.Add(subStream);
		}
예제 #45
0
파일: Page.cs 프로젝트: sillsdev/WorldPad
		/// ------------------------------------------------------------------------------------
		/// <summary>
		/// Executes in two distinct scenarios.
		/// 1. If disposing is true, the method has been called directly
		/// or indirectly by a user's code via the Dispose method.
		/// Both managed and unmanaged resources can be disposed.
		/// 2. If disposing is false, the method has been called by the
		/// runtime from inside the finalizer and you should not reference (access)
		/// other managed objects, as they already have been garbage collected.
		/// Only unmanaged resources can be disposed.
		/// </summary>
		/// <param name="disposing"><c>true</c> to release both managed and unmanaged resources;
		/// <c>false</c> to release only unmanaged resources.</param>
		/// <remarks>
		/// If any exceptions are thrown, that is fine.
		/// If the method is being done in a finalizer, it will be ignored.
		/// If it is thrown by client code calling Dispose,
		/// it needs to be handled by fixing the bug.
		/// If subclasses override this method, they should call the base implementation.
		/// </remarks>
		/// ------------------------------------------------------------------------------------
		protected virtual void Dispose(bool disposing)
		{
			// Must not be run more than once.
			if (m_isDisposed)
				return;

			if (disposing)
			{
				// Dispose managed resources here.
				foreach (PageElement pe in m_pageElements)
					pe.Dispose();
				if (m_pageElements != null)
					m_pageElements.Clear();
				if (m_dependentObjectRootStream != null)
				{
					(m_dependentObjectRootStream as IVwRootBox).Close();
					m_dependentObjectRootStream = null;
				}
			}

			// Dispose unmanaged resources here, whether disposing is true or false.
			m_pageElements = null;
			m_pub = null;

			m_isDisposed = true;
		}
예제 #46
0
		/// ------------------------------------------------------------------------------------
		/// <summary>
		/// Configure the main view and stuff.
		/// </summary>
		/// <remarks>This should only get called once during the lifetime of this object
		/// </remarks>
		/// ------------------------------------------------------------------------------------
		protected internal void Configure()
		{
			if (m_configurer == null ||
				m_configurer.DataAccess == null ||
				m_mainLayoutStream != null)
				return;

			int hvoMainObj = m_configurer.MainObjectId;
			if (hvoMainObj == 0)
				return;

			m_mainVc = m_configurer.MakeMainVc(this);
			m_mainLayoutStream = VwLayoutStreamClass.Create();
			m_mainLayoutStream.SetManager(this);

			PublicationControl.SetAccessibleStreamName(m_mainLayoutStream, m_Name);

			IVwRootBox rootbox = MainRootBox;
			rootbox.SetSite(Publication);

			m_configurer.ConfigureSubordinateViews(this);

			rootbox.DataAccess = m_configurer.DataAccess;
			rootbox.SetRootObject(hvoMainObj, m_mainVc, m_configurer.MainFragment,
				m_configurer.StyleSheet);

			// This was taken out as it was causing lazy boxes to be expanded that hadn't been
			// layed out yet. We still get an initial selection (set in PublicationControl.OnPaint)
			// so it seems to be fine.
			// 			try
			//			{
			//				rootbox.MakeSimpleSel(true, true, false, true);
			//			}
			//			catch
			//			{
			//			}
		}
예제 #47
0
		/// -------------------------------------------------------------------------------------
		/// <summary>
		/// Informs PrintLayout that the page boundary at the end of the specified page moved,
		/// without changing the size of the paragraph. This call is made when editing occurs in
		/// the first part of a paragraph that is split across two pages, and material is moved
		/// from one page to the other as a result, but the material moved does not include any
		/// object references. (If it does include object refs, PageBroken is called instead.)
		/// </summary>
		/// <param name="lay">The primary layout stream filling the page</param>
		/// <param name="hPage">The handle to the page being laid out</param>
		/// <param name="ichOld">the old character position within the affected paragraph</param>
		/// -------------------------------------------------------------------------------------
		public void PageBoundaryMoved(IVwLayoutStream lay, int hPage, int ichOld)
		{
			CheckDisposed();

			// TODO:  Add PrintLayout.PageBoundaryMoved implementation
		}
예제 #48
0
		/// -------------------------------------------------------------------------------------
		/// <summary>
		/// The layout manager is informed by this method that the (primary) layout stream 'lay'
		/// has determined that references to the objects objectGuids occur on the page. The input
		/// value of dysAvailHeight indicates how much of the height allocated to 'lay' for this
		/// page will remain available if the text containing these references is added to the
		/// page (assuming that adding them does not reduce the space available for 'lay').
		/// </summary>
		/// <param name="lay">The primary layout stream filling the page</param>
		/// <param name="vg">The graphics object being used to layout the page</param>
		/// <param name="hPage">The handle to the page being laid out</param>
		/// <param name="cguid">Number of elements in objectGuids array</param>
		/// <param name="objectGuids">Array of GUIDS representing objects to be laid out in a
		/// separate layout stream</param>
		/// <param name="fAllowFail">Indicates whether this method can fail (return
		/// <c>fFailed == true</c>). If this is false, this method should force the requested
		/// objects to be laid out within the available space, even if it requires omitting or
		/// truncating some or all of them</param>
		/// <param name="fFailed">If the available height would become negative (typically
		/// because the objects must share space with 'lay' and they don't fit in the available
		/// height), this will be set to true (unless fAllowFail is false).</param>
		/// <param name="dysAvailHeight">Input value indicates how much of the height allocated
		/// to 'lay' for this page will remain available if the text containing these references
		/// is added to the page, assuming that adding them does not reduce the space available
		/// for 'lay'. The output value indicates how much is left after laying out these
		/// dependent objects.</param>
		/// -------------------------------------------------------------------------------------
		public virtual void AddDependentObjects(IVwLayoutStream lay, IVwGraphics vg, int hPage,
			int cguid, Guid[] objectGuids, bool fAllowFail, out bool fFailed,
			ref int dysAvailHeight)
		{
			CheckDisposed();
			if (m_configurer.RootOnEachPage)
			{
				AddDependentObjectsToPageRoot(lay, vg, hPage,
					cguid, objectGuids, fAllowFail, out fFailed,
					ref dysAvailHeight);
				return;
			}

			int dysAvailableHeight = dysAvailHeight;
			fFailed = false;

			int[] rgHvo = new int[cguid];
			int i = 0;
			foreach (Guid guid in objectGuids)
			{
				rgHvo[i++] = m_configurer.GetIdFromGuid(guid);
			}

			// Attempt to add all objects to any stream(s) that care about them. Don't
			// commit changes to any streams until we see if everything will fit.
			int[] rgdysNewStreamHeight = new int[m_subStreams.Count];
			int iSubStream = -1;
			foreach (SubordinateStream subStream in m_subStreams)
			{
				subStream.m_stream.SetManager(this); // Set this every time for the sake of shared streams
				iSubStream++;
				int dysInitialPageHeight = subStream.m_stream.PageHeight(hPage);
				foreach (int hvo in rgHvo)
				{
					if (hvo == 0)
						continue; // Unable to find object in database. (TE-5007)
					SelLevInfo[] rgSelLevInfo = subStream.m_delegate.GetPathToObject(hvo);
					if (rgSelLevInfo == null)
						continue; // This stream doesn't display this object.

					subStream.m_stream.LayoutObj(vg, AvailablePageWidthInPrinterPixels, 0,
						rgSelLevInfo.Length, rgSelLevInfo, hPage);
				}
				int dysHeightWithAddedObjects = subStream.m_stream.PageHeight(hPage);
				rgdysNewStreamHeight[iSubStream] = dysHeightWithAddedObjects;

				int dysHeightUsed = dysHeightWithAddedObjects - dysInitialPageHeight;
				// If this stream is just now being added to the page, need to allow for gap between elements.
				if (dysInitialPageHeight == 0)
					dysHeightUsed += VerticalGapBetweenElements * vg.YUnitsPerInch / MiscUtils.kdzmpInch;

				if ((dysHeightUsed * m_numberMainStreamColumns) > dysAvailHeight)
				{
					// We can't add everything needed for the current chunk (in the main stream),
					// so we need to fail (if that's permitted), and roll everything back
					if (fAllowFail)
						fFailed = true;
					else
						dysAvailableHeight = 0;
					break;
				}
				else
				{
					// When we layout with multiple columns, we pretend to have one large
					// page. But the substreams are still only one column which means
					// they affect all columns, so we have to multiply the height used
					// with the number of columns.
					dysAvailableHeight -= (dysHeightUsed * m_numberMainStreamColumns);
				}
			}

			// Now we know all the objects fit (or else we weren't allowed to fail), so
			// remove or commit the objects we just added to any streams AND adjust
			// the rectangle occupied by each element so they "stack" properly.

			Page page = Publication.FindPage(hPage);

			// First time thru, the previous "element" is the bottom page margin.
			int ysTopOfPrevElement =
				Publication.PageHeightInPrinterPixels - BottomMarginInPrinterPixels;
			for (; iSubStream >= 0; iSubStream--)
			{
				SubordinateStream subStream = m_subStreams[iSubStream];
				if (fFailed)
				{
					subStream.m_stream.RollbackLayoutObjects(hPage);
				}
				else
				{
					subStream.m_stream.CommitLayoutObjects(hPage);

					ysTopOfPrevElement = AddOrAdjustPageElement(page, ysTopOfPrevElement,
						rgdysNewStreamHeight[iSubStream], subStream.m_stream,
						subStream.m_stream.PagePostion(hPage));
				}
			}

			if (!fFailed)
				dysAvailHeight = dysAvailableHeight;
		}
예제 #49
0
		/// ------------------------------------------------------------------------------------
		/// <summary>
		/// Informs PrintLayout that the specified page is broken. This is the most drastic of
		/// several notifications, sent when the View code cannot determine a more specific way
		/// to describe what has happened. For example, it may be that there has been a change
		/// drastic enough to completely replace the paragraph at one of the page boundaries.
		/// Or, material containing object references may have been inserted or deleted.
		/// </summary>
		/// <param name="lay">The primary layout stream filling the page</param>
		/// <param name="hPage">The handle to the page being laid out</param>
		/// ------------------------------------------------------------------------------------
		public virtual void PageBroken(IVwLayoutStream lay, int hPage)
		{
			CheckDisposed();
			if (hPage == m_hPageBeingBuilt)
				return;

			Page page = Publication.FindPage(hPage);
			if (page == null || page.IsDisposed)
			{
				// Already disposed of for some other reason?
				return;
			}
			// Todo: Some invalidating of the element may be needed.

			// Forget all the page elements on the broken page...the next PrepareToDraw will
			// create new, correct ones. (The element sending the message has already
			// discarded its record of the page, but other elements should do so as well.)
			foreach (PageElement pe in page.PageElements)
				if (pe.m_stream != lay)
					pe.m_stream.DiscardPage(hPage);
			page.Broken = true;
		}
예제 #50
-12
//		/// ------------------------------------------------------------------------------------
//		/// <summary>
//		/// Determine the gap between the columns.
//		/// </summary>
//		/// <param name="numberColumns">The total number of columns.</param>
//		/// <returns>
//		/// If the element spans the whole width of the page, the column gap is 0.
//		/// Otherwise, it is ColumnGapWidthInPrinterPixels;
//		/// </returns>
//		/// ------------------------------------------------------------------------------------
//		private int ColumnGap(int numberColumns)
//		{
//			return (numberColumns > 1) ? ColumnGapWidthInPrinterPixels : 0;
//		}

		/// ------------------------------------------------------------------------------------
		/// <summary>
		/// Adds or adjusts the page element. Note that this is used ONLY for dependent objects,
		/// it arranges them from the bottom up. These elements don't overlap, so no overlap is
		/// passed.
		/// </summary>
		/// <param name="page">The page.</param>
		/// <param name="ysTopOfPrevElement">The top of the previous element.</param>
		/// <param name="ysStreamHeight">Height of the stream.</param>
		/// <param name="stream">The stream.</param>
		/// <param name="pagePosition">The page position.</param>
		/// <returns></returns>
		/// ------------------------------------------------------------------------------------
		private int AddOrAdjustPageElement(Page page, int ysTopOfPrevElement, int ysStreamHeight,
			IVwLayoutStream stream, int pagePosition)
		{
			Debug.Assert(!page.IsDisposed);

			if (ysStreamHeight <= 0)
				return ysTopOfPrevElement;

			int ysTopOfThisElement = ysTopOfPrevElement - ysStreamHeight;
			Rectangle rectLocationOnPage = new Rectangle(LeftMarginInPrinterPixels(page),
				ysTopOfThisElement,
				AvailablePageWidthInPrinterPixels,
				ysStreamHeight);

			PageElement element = page.GetFirstElementForStream(stream);
			if (element == null)
			{
				// Create page element
				page.AddPageElement(this, stream, false, rectLocationOnPage,
					pagePosition, false, 1, 1, 0,
					ysStreamHeight, 0, MainStreamIsRightToLeft, false);
			}
			else
			{
				// Increase size of page element
				if (element.LocationOnPage.Height != ysStreamHeight)
				{
					// Increase size of/move location
					page.AdjustPageElement(element, rectLocationOnPage, false);
				}
			}
			return ysTopOfThisElement;
		}