PreviewWorkspace.cs 30 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Drawing;
  4. using System.Windows.Forms;
  5. using System.Drawing.Drawing2D;
  6. using System.ComponentModel;
  7. using System.Diagnostics;
  8. using FastReport.Utils;
  9. #if !MONO
  10. using FastReport.DevComponents.DotNetBar;
  11. #else
  12. using FastReport.Controls;
  13. #endif
  14. namespace FastReport.Preview
  15. {
  16. internal enum PreviewZoomMode
  17. {
  18. Normal,
  19. PageWidth,
  20. WholePage
  21. }
  22. #if !MONO
  23. internal class PreviewWorkspace : PanelX
  24. #else
  25. internal class PreviewWorkspace : FRScrollablePanel
  26. #endif
  27. {
  28. #region Fields
  29. private PreviewTab previewTab;
  30. private PreviewPages previewPages;
  31. private float zoom;
  32. private PreviewZoomMode zoomMode;
  33. private int pageNo;
  34. private Point lastMousePoint;
  35. private Cursor curHand;
  36. private Cursor curHandMove;
  37. private ReportComponentBase activeObject;
  38. private SearchInfo searchInfo;
  39. private bool locked;
  40. private bool layoutLocked;
  41. private bool allowPaint = true;
  42. #endregion
  43. #region Properties
  44. private PreviewTab PreviewTab
  45. {
  46. get { return previewTab; }
  47. }
  48. private PreviewControl Preview
  49. {
  50. get { return PreviewTab.Preview; }
  51. }
  52. private Report Report
  53. {
  54. get { return PreviewTab.Report; }
  55. }
  56. private PreparedPages PreparedPages
  57. {
  58. get { return PreviewTab.PreparedPages; }
  59. }
  60. private PreviewPages PreviewPages
  61. {
  62. get { return previewPages; }
  63. }
  64. public int PageNo
  65. {
  66. get { return pageNo; }
  67. set { SetPageNo(value, true); }
  68. }
  69. public int PageCount
  70. {
  71. get { return PreparedPages.Count; }
  72. }
  73. public float Zoom
  74. {
  75. get { return zoom; }
  76. set { DoZoom(value); }
  77. }
  78. public float ZoomDpi
  79. {
  80. get { return zoom * this.DpiMultiplier(); }
  81. }
  82. public SearchInfo SearchInfo
  83. {
  84. get { return searchInfo; }
  85. set { searchInfo = value; }
  86. }
  87. private Point Offset
  88. {
  89. get { return new Point(-AutoScrollPosition.X, -AutoScrollPosition.Y); }
  90. set
  91. {
  92. AutoScrollPosition = new Point(-value.X, -value.Y);
  93. FindPageNo();
  94. }
  95. }
  96. private GraphicCache GraphicCache
  97. {
  98. get { return Report.GraphicCache; }
  99. }
  100. public bool Disabled
  101. {
  102. get { return PageCount == 0 || locked || layoutLocked || Report == null || Report.GraphicCache == null; } // report may be disposed in user code
  103. }
  104. #endregion
  105. #region Private Methods
  106. private void SetPageNo(int value, bool scrollTo)
  107. {
  108. if (value > PageCount)
  109. value = PageCount;
  110. if (value < 1)
  111. value = 1;
  112. bool pageChanged = value != pageNo;
  113. pageNo = value;
  114. if (Disabled)
  115. return;
  116. if (scrollTo)
  117. ScrollToCurrentPage();
  118. // update active page border
  119. if (pageChanged)
  120. {
  121. Invalidate();
  122. UpdatePageNumbers();
  123. }
  124. }
  125. private void ScrollToCurrentPage()
  126. {
  127. Rectangle pageBounds = previewPages.GetPageBounds(PageNo - 1);
  128. pageBounds.Y -= 10;
  129. Offset = pageBounds.Location;
  130. }
  131. private void FindPageNo()
  132. {
  133. if (PreviewPages.Count == 0)
  134. return;
  135. int pageNo = PreviewPages.FindPage(Offset.Y) + 1;
  136. if (!PreviewPages.IsSameRow(pageNo - 1, PageNo - 1))
  137. SetPageNo(pageNo, false);
  138. }
  139. private bool IsPageVisible(int index)
  140. {
  141. var bounds = PreviewPages.GetPageBounds(index);
  142. return new Rectangle(0, Offset.Y, ClientSize.Width, ClientSize.Height).IntersectsWith(bounds);
  143. }
  144. private void DrawPages(Graphics g)
  145. {
  146. if (Disabled || PreviewPages.Count == 0)
  147. return;
  148. // draw visible pages
  149. int firstVisible = PreviewPages.FindFirstVisiblePage(Offset.Y);
  150. int lastVisible = PreviewPages.FindLastVisiblePage(Offset.Y + ClientSize.Height);
  151. // draw pages from right to left if needed
  152. if (Config.RightToLeft)
  153. {
  154. int i = firstVisible;
  155. while (i <= lastVisible)
  156. {
  157. List<int> pagesInSameRow = new List<int>();
  158. pagesInSameRow.Add(i);
  159. // get list of pages in current row
  160. while (PreviewPages.IsSameRow(i, i + 1))
  161. {
  162. pagesInSameRow.Add(i + 1);
  163. i++;
  164. }
  165. if (pagesInSameRow.Count > 1)
  166. {
  167. // swap pages in current row
  168. for (int j = 0, k = pagesInSameRow.Count - 1; j < k; j++, k--)
  169. {
  170. PreviewPages.SwapPageBounds(pagesInSameRow[j], pagesInSameRow[k]);
  171. }
  172. }
  173. i++;
  174. }
  175. }
  176. for (int i = firstVisible; i <= lastVisible; i++)
  177. {
  178. Rectangle pageBounds = PreviewPages.GetPageBounds(i);
  179. pageBounds.Offset(-Offset.X, -Offset.Y);
  180. ReportPage page = PreparedPages.GetCachedPage(i);
  181. if (page == null || pageBounds.Width < 0 || pageBounds.Height < 0)
  182. continue;
  183. #if !MONO
  184. // draw shadow around page
  185. bool drawShadow = !(Preview.ActivePageBorderColor == Color.White && Preview.BackColor == Color.White);
  186. if (drawShadow)
  187. {
  188. ShadowPaintInfo pi = new ShadowPaintInfo();
  189. pi.Graphics = g;
  190. pi.Rectangle = new Rectangle(pageBounds.Left - 4, pageBounds.Top - 4, pageBounds.Width + 4, pageBounds.Height + 4);
  191. pi.Size = 5;
  192. ShadowPainter.Paint2(pi);
  193. }
  194. #endif
  195. #if AVALONIA
  196. g.FontScale = 1;
  197. #endif
  198. var state = g.Save();
  199. // shift the origin because page.Draw draws at 0, 0
  200. g.TranslateTransform((int)pageBounds.Left, (int)pageBounds.Top);
  201. FRPaintEventArgs e;
  202. if (Config.IsRunningOnMono)
  203. {
  204. g.ScaleTransform(ZoomDpi, ZoomDpi);
  205. e = new FRPaintEventArgs(g, 1, 1, GraphicCache);
  206. }
  207. else
  208. {
  209. e = new FRPaintEventArgs(g, ZoomDpi, ZoomDpi, GraphicCache);
  210. }
  211. // draw page
  212. page.Draw(e);
  213. // draw search highlight
  214. if (SearchInfo != null && SearchInfo.visible && SearchInfo.pageNo == i + 1)
  215. page.DrawSearchHighlight(e, SearchInfo.objNo, SearchInfo.ranges[SearchInfo.rangeNo]);
  216. g.Restore(state);
  217. // draw border around active page
  218. if (i == PageNo - 1)
  219. {
  220. Pen borderPen = GraphicCache.GetPen(Preview.ActivePageBorderColor, this.LogicalToDevice(2f), DashStyle.Solid);
  221. pageBounds.Inflate(-1, -1);
  222. g.DrawRectangle(borderPen, pageBounds);
  223. }
  224. }
  225. }
  226. private void DoZoom(float zoom)
  227. {
  228. DoZoom(zoom, new Point(Width / 2, Height / 2));
  229. }
  230. private void DoZoom(float zoom, Point relativeTo)
  231. {
  232. // pause control painting
  233. // if you don't do this, the page will flicker while zooming
  234. allowPaint = false;
  235. {
  236. Point mouse_position_on_workspace = new Point(Offset.X + relativeTo.X, Offset.Y + relativeTo.Y);
  237. PointF mouse_position_on_page_percent = new PointF();
  238. int pageNo = -1;
  239. // todo: avoid try/catch, upd: if catch does not happen, remove it
  240. try
  241. {
  242. // if(PreparedPages.Count)
  243. pageNo = PreviewPages.FindPage(mouse_position_on_workspace.X, mouse_position_on_workspace.Y);
  244. Rectangle pageBounds = PreviewPages.GetPageBounds(pageNo);
  245. if (pageBounds.Width > 0 && pageBounds.Height > 0)
  246. {
  247. mouse_position_on_page_percent.X = (float)(mouse_position_on_workspace.X - pageBounds.X) / (float)pageBounds.Width;
  248. mouse_position_on_page_percent.Y = (float)(mouse_position_on_workspace.Y - pageBounds.Y) / (float)pageBounds.Height;
  249. }
  250. }
  251. catch { }
  252. // apply zoom value
  253. {
  254. if (zoom < 0.1f)
  255. zoom = 0.1f;
  256. if (zoom > 10)
  257. zoom = 10;
  258. if (Math.Abs(this.zoom - 0.1f) < 0.001 && Math.Abs(zoom - 0.35f) < 0.001)
  259. zoom = 0.25f;
  260. this.zoom = zoom;
  261. zoomMode = PreviewZoomMode.Normal;
  262. Preview.UpdateZoom(zoom);
  263. UpdatePages();
  264. }
  265. if (pageNo >= 0 && pageNo < PreviewPages.Count)
  266. {
  267. Rectangle pageBounds = PreviewPages.GetPageBounds(pageNo);
  268. Point mouse_position_on_page_new = new Point(
  269. (int)(pageBounds.Width * mouse_position_on_page_percent.X),
  270. (int)(pageBounds.Height * mouse_position_on_page_percent.Y));
  271. Offset = new Point(pageBounds.X + mouse_position_on_page_new.X - relativeTo.X, pageBounds.Y + mouse_position_on_page_new.Y - relativeTo.Y);
  272. }
  273. else
  274. AutoScrollPosition = AutoScrollPosition;
  275. }
  276. allowPaint = true;
  277. Refresh();
  278. }
  279. #endregion
  280. #region Protected Methods
  281. #if !MONO
  282. protected override void OnPaint(PaintEventArgs e)
  283. {
  284. BackColor = Preview.BackColor;
  285. BackgroundImage = Preview.BackgroundImage;
  286. BackgroundImageLayout = Preview.BackgroundImageLayout;
  287. DefaultPaint = Preview.UseBackColor;
  288. base.OnPaint(e);
  289. DrawPages(e.Graphics);
  290. }
  291. #elif AVALONIA
  292. protected override void OnPaint(PaintEventArgs e)
  293. {
  294. DrawPages(e.Graphics);
  295. }
  296. #else
  297. protected override void OnPaint(PaintEventArgs e)
  298. {
  299. e.Graphics.Clear(Preview.BackColor);
  300. DrawPages(e.Graphics);
  301. }
  302. #endif
  303. protected override void OnMouseDown(MouseEventArgs e)
  304. {
  305. base.OnMouseDown(e);
  306. if (Disabled)
  307. return;
  308. int pageNo = PreviewPages.FindPage(Offset.X + e.X, Offset.Y + e.Y);
  309. ReportPage page = PreparedPages.GetCachedPage(pageNo);
  310. Rectangle pageBounds = PreviewPages.GetPageBounds(pageNo);
  311. SetPageNo(pageNo + 1, false);
  312. Cursor = curHandMove;
  313. lastMousePoint = e.Location;
  314. // reset page's NeedRefresh flag
  315. page.NeedRefresh = false;
  316. page.NeedModify = false;
  317. // generate mousedown event
  318. if (activeObject != null)
  319. {
  320. activeObject.OnMouseDown(new MouseEventArgs(e.Button, e.Clicks,
  321. (int)Math.Round((Offset.X + e.X - pageBounds.X) / ZoomDpi - page.LeftMargin * Units.Millimeters - activeObject.AbsLeft),
  322. (int)Math.Round((Offset.Y + e.Y - pageBounds.Y) / ZoomDpi - page.TopMargin * Units.Millimeters - activeObject.AbsTop),
  323. e.Delta));
  324. }
  325. // reset search highlight
  326. if (SearchInfo != null && SearchInfo.visible)
  327. {
  328. SearchInfo.visible = false;
  329. Refresh();
  330. }
  331. // modify and refresh the page if requested in the object's script
  332. if (page.NeedModify)
  333. PreparedPages.ModifyPage(pageNo, page);
  334. if (page.NeedRefresh)
  335. Refresh();
  336. }
  337. protected override void OnMouseMove(MouseEventArgs e)
  338. {
  339. base.OnMouseMove(e);
  340. if (Disabled)
  341. return;
  342. // find an object under mouse
  343. int pageNo = PreviewPages.FindPage(Offset.X + e.X, Offset.Y + e.Y);
  344. ReportPage page = PreparedPages.GetCachedPage(pageNo);
  345. Rectangle pageBounds = PreviewPages.GetPageBounds(pageNo);
  346. ReportComponentBase obj = page.HitTest(new PointF((Offset.X + e.X - pageBounds.X) / ZoomDpi,
  347. (Offset.Y + e.Y - pageBounds.Y) / ZoomDpi));
  348. // reset page's NeedRefresh flag
  349. page.NeedRefresh = false;
  350. page.NeedModify = false;
  351. // generate mouse enter, mouseleave events
  352. if (obj != activeObject)
  353. {
  354. if (activeObject != null)
  355. activeObject.OnMouseLeave(EventArgs.Empty);
  356. if (obj != null)
  357. obj.OnMouseEnter(EventArgs.Empty);
  358. }
  359. activeObject = obj;
  360. // generate mousemove event
  361. if (activeObject != null)
  362. {
  363. activeObject.OnMouseMove(new MouseEventArgs(e.Button, e.Clicks,
  364. (int)Math.Round((Offset.X + e.X - pageBounds.X) / ZoomDpi - page.LeftMargin * Units.Millimeters - activeObject.AbsLeft),
  365. (int)Math.Round((Offset.Y + e.Y - pageBounds.Y) / ZoomDpi - page.TopMargin * Units.Millimeters - activeObject.AbsTop),
  366. e.Delta));
  367. }
  368. string url = "";
  369. Cursor cursor = Cursors.Default;
  370. if (obj != null)
  371. {
  372. cursor = obj.Cursor;
  373. url = obj.Hyperlink.Value;
  374. }
  375. Cursor = cursor == Cursors.Default ? (e.Button == MouseButtons.Left ? curHandMove : curHand) : cursor;
  376. Preview.UpdateUrl(url);
  377. // prevent report panning if active object supports mouse events (currently Map object only)
  378. if (activeObject == null || !activeObject.HasFlag(Flags.InterceptsPreviewMouseEvents))
  379. if (e.Button == MouseButtons.Left)
  380. {
  381. Offset = new Point(Offset.X - (e.X - lastMousePoint.X), Offset.Y - (e.Y - lastMousePoint.Y));
  382. lastMousePoint = e.Location;
  383. }
  384. // refresh page if requested in the object's script
  385. if (page.NeedModify)
  386. PreparedPages.ModifyPage(pageNo, page);
  387. if (page.NeedRefresh)
  388. Refresh();
  389. }
  390. protected override void OnMouseUp(MouseEventArgs e)
  391. {
  392. base.OnMouseUp(e);
  393. if (Disabled)
  394. return;
  395. Cursor = curHand;
  396. // find object under mouse to invoke its PreviewClick event
  397. int pageNo = PreviewPages.FindPage(Offset.X + e.X, Offset.Y + e.Y);
  398. ReportPage page = PreparedPages.GetCachedPage(pageNo);
  399. Rectangle pageBounds = PreviewPages.GetPageBounds(pageNo);
  400. // reset NeedRefresh flag
  401. page.NeedRefresh = false;
  402. page.NeedModify = false;
  403. Report.NeedRefresh = false;
  404. // generate mouseup event
  405. if (activeObject != null)
  406. {
  407. activeObject.OnMouseUp(new MouseEventArgs(e.Button, e.Clicks,
  408. (int)Math.Round((Offset.X + e.X - pageBounds.X) / ZoomDpi - page.LeftMargin * Units.Millimeters - activeObject.AbsLeft),
  409. (int)Math.Round((Offset.Y + e.Y - pageBounds.Y) / ZoomDpi - page.TopMargin * Units.Millimeters - activeObject.AbsTop),
  410. e.Delta));
  411. if (e.Button == MouseButtons.Right)
  412. {
  413. var menu = activeObject.GetPreviewContextMenu();
  414. menu?.Show(this, e.Location);
  415. }
  416. else
  417. {
  418. Hyperlink hyperlink = activeObject.Hyperlink;
  419. switch (hyperlink.Kind)
  420. {
  421. case HyperlinkKind.URL:
  422. try
  423. {
  424. if (!String.IsNullOrEmpty(hyperlink.Value))
  425. ProcessHelper.StartProcess(hyperlink.Value);
  426. }
  427. catch
  428. {
  429. }
  430. break;
  431. case HyperlinkKind.PageNumber:
  432. PageNo = int.Parse(hyperlink.Value);
  433. break;
  434. case HyperlinkKind.Bookmark:
  435. Bookmarks.BookmarkItem bookmark = PreparedPages.Bookmarks.Find(hyperlink.Value);
  436. if (bookmark != null)
  437. PositionTo(bookmark.pageNo + 1, new PointF(0, bookmark.offsetY));
  438. break;
  439. case HyperlinkKind.DetailReport:
  440. if (hyperlink.Value == "")
  441. break;
  442. // if detail report name is empty, refresh this report
  443. if (String.IsNullOrEmpty(hyperlink.DetailReportName))
  444. {
  445. hyperlink.SetParameters(Report);
  446. Report.NeedRefresh = true;
  447. }
  448. else
  449. {
  450. // open a new report. check if such tab is opened already
  451. // check if this tab equals to the hyperlink value, open a new tab if so
  452. if (PreviewTab.HyperlinkValue == hyperlink.Value || !Preview.SwitchToTab(hyperlink))
  453. {
  454. locked = true;
  455. try
  456. {
  457. Report report = hyperlink.GetReport(true);
  458. report.Prepare();
  459. Preview.AddPreviewTab(report, hyperlink.Value, hyperlink, true);
  460. }
  461. finally
  462. {
  463. locked = false;
  464. }
  465. }
  466. }
  467. break;
  468. case HyperlinkKind.DetailPage:
  469. if (hyperlink.Value == "")
  470. break;
  471. ReportPage reportPage = Report.FindObject(hyperlink.DetailPageName) as ReportPage;
  472. if (reportPage != null)
  473. {
  474. hyperlink.SetParameters(Report);
  475. // open a new report. check if such tab is opened already
  476. // check if this tab equals to the hyperlink value, open a new tab if so
  477. if (PreviewTab.HyperlinkValue == hyperlink.Value || !Preview.SwitchToTab(hyperlink))
  478. {
  479. locked = true;
  480. Preview.Lock();
  481. PreparedPages pages = new PreparedPages(Report);
  482. try
  483. {
  484. Report.SetPreparedPages(pages);
  485. Report.PreparePage(reportPage, true);
  486. }
  487. finally
  488. {
  489. locked = false;
  490. Preview.Unlock();
  491. Preview.AddPreviewTab(Report, hyperlink.Value, hyperlink, true);
  492. }
  493. }
  494. }
  495. break;
  496. }
  497. if (activeObject != null)
  498. activeObject.OnClick(e);
  499. }
  500. }
  501. // modify and refresh the page if requested in the object's script
  502. if (page.NeedModify)
  503. PreparedPages.ModifyPage(pageNo, page);
  504. if (page.NeedRefresh)
  505. Refresh();
  506. if (Report.NeedRefresh)
  507. RefreshReport();
  508. }
  509. protected override void OnClick(EventArgs e)
  510. {
  511. base.OnClick(e);
  512. if (Disabled)
  513. return;
  514. Preview.DoClick();
  515. }
  516. protected override void OnMouseWheel(MouseEventArgs e)
  517. {
  518. if (Disabled)
  519. return;
  520. if ((ModifierKeys & Keys.Control) != 0)
  521. DoZoom(zoom + Math.Sign(e.Delta) * 0.25f, new Point(e.X, e.Y));
  522. else if (ModifierKeys == Keys.Shift)
  523. {
  524. #if !MONO
  525. DoHorizontalMouseWheel(e);
  526. #endif
  527. }
  528. else
  529. {
  530. if (activeObject != null && activeObject.HasFlag(Flags.InterceptsPreviewMouseEvents))
  531. {
  532. activeObject.OnMouseWheel(e);
  533. Refresh();
  534. }
  535. else
  536. {
  537. base.OnMouseWheel(e);
  538. #if !MONO
  539. DoMouseWheel(e);
  540. #endif
  541. FindPageNo();
  542. }
  543. }
  544. }
  545. protected override void OnKeyDown(KeyEventArgs e)
  546. {
  547. if (Config.DisableHotkeys)
  548. return;
  549. base.OnKeyDown(e);
  550. if (Disabled)
  551. return;
  552. if ((e.KeyData & Keys.Control) == 0)
  553. {
  554. switch (e.KeyCode)
  555. {
  556. case Keys.Up:
  557. Offset = new Point(Offset.X, Offset.Y - VScrollBar.SmallChange);
  558. break;
  559. case Keys.Down:
  560. Offset = new Point(Offset.X, Offset.Y + VScrollBar.SmallChange);
  561. break;
  562. case Keys.Left:
  563. Offset = new Point(Offset.X - HScrollBar.SmallChange, Offset.Y);
  564. break;
  565. case Keys.Right:
  566. Offset = new Point(Offset.X + HScrollBar.SmallChange, Offset.Y);
  567. break;
  568. case Keys.PageUp:
  569. Offset = new Point(Offset.X, Offset.Y - VScrollBar.LargeChange);
  570. break;
  571. case Keys.PageDown:
  572. Offset = new Point(Offset.X, Offset.Y + VScrollBar.LargeChange);
  573. break;
  574. case Keys.Home:
  575. PreviewTab.First();
  576. break;
  577. case Keys.End:
  578. PreviewTab.Last();
  579. break;
  580. case Keys.Add:
  581. PreviewTab.ZoomIn();
  582. break;
  583. case Keys.Subtract:
  584. PreviewTab.ZoomOut();
  585. break;
  586. }
  587. }
  588. else
  589. {
  590. switch (e.KeyCode)
  591. {
  592. case Keys.F:
  593. if ((Preview.Buttons & PreviewButtons.Find) != 0)
  594. PreviewTab.Find();
  595. break;
  596. #if !COMMUNITY
  597. case Keys.P:
  598. if ((Preview.Buttons & PreviewButtons.Print) != 0)
  599. PreviewTab.Print();
  600. break;
  601. #endif
  602. }
  603. }
  604. }
  605. protected override bool IsInputKey(Keys keyData)
  606. {
  607. var key = keyData & Keys.KeyCode;
  608. return key == Keys.Up || key == Keys.Down || key == Keys.Left || key == Keys.Right;
  609. }
  610. protected override void OnScroll(ScrollEventArgs se)
  611. {
  612. base.OnScroll(se);
  613. if (Disabled)
  614. return;
  615. if (se.ScrollOrientation == ScrollOrientation.VerticalScroll)
  616. FindPageNo();
  617. }
  618. protected override void OnResize(EventArgs e)
  619. {
  620. base.OnResize(e);
  621. if (Disabled)
  622. return;
  623. if (zoomMode == PreviewZoomMode.PageWidth)
  624. ZoomPageWidth();
  625. else if (zoomMode == PreviewZoomMode.WholePage)
  626. ZoomWholePage();
  627. }
  628. #if !MONO
  629. private const int WM_PAINT = 0x000F;
  630. protected override void WndProc(ref Message m)
  631. {
  632. if ((m.Msg != WM_PAINT) || (allowPaint && m.Msg == WM_PAINT))
  633. {
  634. base.WndProc(ref m);
  635. }
  636. }
  637. #endif
  638. #endregion
  639. #region Public Methods
  640. public void UpdatePages()
  641. {
  642. PreviewPages.Clear();
  643. if (layoutLocked)
  644. return;
  645. for (int i = 0; i < PreparedPages.Count; i++)
  646. {
  647. SizeF pageSize = PreparedPages.GetPageSize(i);
  648. PreviewPages.AddPage(pageSize, ZoomDpi);
  649. }
  650. PreviewPages.LayoutPages(Width - SystemInformation.VerticalScrollBarWidth, Preview.LogicalToDevice(Preview.PageOffset));
  651. locked = false;
  652. UpdatePageNumbers();
  653. Size maxSize = PreviewPages.GetMaxSize(Preview.LogicalToDevice(Preview.PageOffset));
  654. if (maxSize.Width > Width - SystemInformation.VerticalScrollBarWidth)
  655. maxSize.Height += SystemInformation.HorizontalScrollBarHeight;
  656. if (maxSize.Height > Height - SystemInformation.HorizontalScrollBarHeight)
  657. maxSize.Width += SystemInformation.VerticalScrollBarWidth;
  658. AutoScrollMinSize = maxSize;
  659. bool refresh = !Preview.IsAsyncReportRunning;
  660. if (!refresh)
  661. {
  662. if (PreviewPages.Count > 1)
  663. {
  664. // determine if the last added page is visible on screen
  665. refresh = IsPageVisible(PreviewPages.Count - 1);
  666. // remove previous page (incomplete) from cache
  667. PreparedPages.RemovePageCache(PreviewPages.Count - 2);
  668. // also check its visibility
  669. refresh |= IsPageVisible(PreviewPages.Count - 2);
  670. }
  671. }
  672. if (refresh)
  673. {
  674. SetPageNo(PageNo, false);
  675. Refresh();
  676. }
  677. }
  678. public void UpdatePageNumbers()
  679. {
  680. Preview.UpdatePageNumbers(PageNo, PageCount);
  681. }
  682. public void PositionTo(int pageNo, PointF point)
  683. {
  684. if (Disabled)
  685. return;
  686. RectangleF pageBounds = PreviewPages.GetPageBounds(pageNo - 1);
  687. ReportPage page = PreparedPages.GetCachedPage(pageNo - 1);
  688. Offset = new Point((int)Math.Round(pageBounds.Left + (page.LeftMargin * Units.Millimeters + point.X) * ZoomDpi),
  689. (int)Math.Round(pageBounds.Top + (page.TopMargin * Units.Millimeters + point.Y) * ZoomDpi) - 10);
  690. SetPageNo(pageNo, false);
  691. }
  692. public void RefreshReport()
  693. {
  694. bool saveShowProgress = Config.ReportSettings.ShowProgress;
  695. Config.ReportSettings.ShowProgress = false;
  696. locked = true;
  697. try
  698. {
  699. PreviewPages.Clear();
  700. PreparedPages.ClearPageCache();
  701. if (PreviewTab.DetailReportPage != null)
  702. Report.PreparePage(PreviewTab.DetailReportPage, true);
  703. else
  704. Report.InternalRefresh();
  705. }
  706. finally
  707. {
  708. locked = false;
  709. Config.ReportSettings.ShowProgress = saveShowProgress;
  710. }
  711. UpdatePages();
  712. // ensure the updated report fits in the workspace
  713. Offset = Offset;
  714. }
  715. public void UnlockLayout()
  716. {
  717. layoutLocked = false;
  718. }
  719. public void ZoomWholePage()
  720. {
  721. if (Disabled)
  722. return;
  723. SizeF pageSize = PreparedPages.GetPageSize(PageNo - 1);
  724. if (pageSize.Width / ClientSize.Width > pageSize.Height / ClientSize.Height)
  725. Zoom = (ClientSize.Width - 20) / (pageSize.Width * this.DpiMultiplier());
  726. else
  727. Zoom = (ClientSize.Height - 20) / (pageSize.Height * this.DpiMultiplier());
  728. zoomMode = PreviewZoomMode.WholePage;
  729. }
  730. public void ZoomPageWidth()
  731. {
  732. if (Disabled)
  733. return;
  734. SizeF pageSize = PreparedPages.GetPageSize(PageNo - 1);
  735. Zoom = (ClientSize.Width - 20 - SystemInformation.VerticalScrollBarWidth) / (pageSize.Width * this.DpiMultiplier());
  736. zoomMode = PreviewZoomMode.PageWidth;
  737. }
  738. #endregion
  739. public PreviewWorkspace(PreviewTab previewTab)
  740. {
  741. this.previewTab = previewTab;
  742. previewPages = new PreviewPages();
  743. curHand = ResourceLoader.GetCursor("Hand.cur");
  744. curHandMove = ResourceLoader.GetCursor("HandMove.cur");
  745. #if AVALONIA
  746. //PaintOnRenderThread = Config.AvaloniaPaintOnRenderThread;
  747. #endif
  748. Cursor = curHand;
  749. Dock = DockStyle.Fill;
  750. AutoScroll = true;
  751. layoutLocked = true;
  752. #if !MONO
  753. ColorSchemeStyle = eDotNetBarStyle.Office2007;
  754. FastScrolling = Preview.FastScrolling;
  755. #endif
  756. }
  757. }
  758. }