DialogWorkspace.cs 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461
  1. using System;
  2. using System.Windows.Forms;
  3. using System.Drawing;
  4. using System.Drawing.Drawing2D;
  5. using FastReport.Utils;
  6. using FastReport.Dialog;
  7. using FastReport.Design.ToolWindows;
  8. using FastReport.Data;
  9. namespace FastReport.Design.PageDesigners.Dialog
  10. {
  11. internal class DialogWorkspace : DesignWorkspaceBase
  12. {
  13. #region Fields
  14. #endregion
  15. #region Properties
  16. public static Grid Grid = new Grid();
  17. public static bool ShowGrid;
  18. public static bool SnapToGrid;
  19. public DialogPage Page
  20. {
  21. get { return PageDesigner.Page as DialogPage; }
  22. }
  23. public override Point Offset
  24. {
  25. get
  26. {
  27. Point offset = Page.Form.ClientAreaOffset();
  28. int _10 = this.LogicalToDevice(10);
  29. offset.X += _10;
  30. offset.Y += _10;
  31. return offset;
  32. }
  33. }
  34. #endregion
  35. #region Private Methods
  36. private void UpdateName()
  37. {
  38. if (Page.Name == "")
  39. Text = Page.ClassName + (Page.ZOrder + 1).ToString();
  40. else
  41. Text = Page.Name;
  42. }
  43. private RectangleF GetSelectedRect()
  44. {
  45. RectangleF result = new RectangleF(100000, 100000, -100000, -100000);
  46. foreach (Base obj in Designer.SelectedObjects)
  47. {
  48. if (obj is ComponentBase)
  49. {
  50. ComponentBase c = obj as ComponentBase;
  51. if (c.Left < result.Left)
  52. result.X = c.Left;
  53. if (c.Right > result.Right)
  54. result.Width = c.Right - result.Left;
  55. if (c.Top < result.Top)
  56. result.Y = c.Top;
  57. if (c.Bottom > result.Bottom)
  58. result.Height = c.Bottom - result.Top;
  59. }
  60. else if (obj is DialogPage)
  61. {
  62. result = new RectangleF(0, 0, Page.Form.FrameSize().Width, Page.Form.FrameSize().Height);
  63. }
  64. }
  65. return result;
  66. }
  67. private void UpdateStatusBar()
  68. {
  69. RectangleF selectedRect = GetSelectedRect();
  70. bool IsPageOrReportSelected = Designer.SelectedObjects.IsPageSelected || Designer.SelectedObjects.IsReportSelected;
  71. string location = IsPageOrReportSelected ? "" :
  72. selectedRect.Left.ToString() + "; " + selectedRect.Top.ToString();
  73. string size = IsPageOrReportSelected ? "" :
  74. selectedRect.Width.ToString() + "; " + selectedRect.Height.ToString();
  75. Designer.ShowStatus(location, size, "", "");
  76. }
  77. private void AfterDragDrop(Point location)
  78. {
  79. DataFilterBaseControl control = Designer.SelectedObjects[0] as DataFilterBaseControl;
  80. if (control is TextBoxControl)
  81. {
  82. // show menu with different control types
  83. ContextMenuStrip menu = new ContextMenuStrip();
  84. menu.Renderer = Config.DesignerSettings.ToolStripRenderer;
  85. Type[] controlTypes = new Type[] {
  86. typeof(TextBoxControl), typeof(MaskedTextBoxControl),
  87. typeof(ComboBoxControl), typeof(CheckedListBoxControl),
  88. typeof(ListBoxControl), typeof(DataSelectorControl) };
  89. foreach (Type controlType in controlTypes)
  90. {
  91. ObjectInfo info = RegisteredObjects.FindObject(controlType);
  92. ToolStripMenuItem item = new ToolStripMenuItem(Res.Get(info.Text), Designer.GetImage(info.ImageIndex));
  93. menu.Items.Add(item);
  94. item.Tag = controlType;
  95. item.Click += new EventHandler(ControlTypeItem_Click);
  96. }
  97. menu.Show(this, new Point((int)control.AbsLeft + Offset.X, (int)control.AbsBottom + Offset.Y));
  98. }
  99. else
  100. {
  101. // look for another controls of same type in a form that bound to the same DataColumn
  102. // and setup the FilterOperation
  103. foreach (Base c in Page.AllObjects)
  104. {
  105. if (c != control && c.GetType() == control.GetType() &&
  106. (c as DataFilterBaseControl).DataColumn == control.DataColumn)
  107. {
  108. (c as DataFilterBaseControl).FilterOperation = FilterOperation.GreaterThanOrEqual;
  109. control.FilterOperation = FilterOperation.LessThanOrEqual;
  110. Designer.SetModified(this, "Change");
  111. break;
  112. }
  113. }
  114. }
  115. }
  116. private void ControlTypeItem_Click(object sender, EventArgs e)
  117. {
  118. DataFilterBaseControl control = Designer.SelectedObjects[0] as DataFilterBaseControl;
  119. Type controlType = (sender as ToolStripMenuItem).Tag as Type;
  120. DataFilterBaseControl newControl = Activator.CreateInstance(controlType) as DataFilterBaseControl;
  121. newControl.Parent = control.Parent;
  122. newControl.Location = control.Location;
  123. newControl.DataColumn = control.DataColumn;
  124. newControl.ReportParameter = control.ReportParameter;
  125. control.Dispose();
  126. newControl.CreateUniqueName();
  127. Designer.SelectedObjects.Clear();
  128. Designer.SelectedObjects.Add(newControl);
  129. Designer.SetModified(this, "Insert");
  130. }
  131. private void DrawSelectionRect(FRPaintEventArgs e)
  132. {
  133. RectangleF rect = NormalizeSelectionRect();
  134. IGraphics g = e.Graphics;
  135. Brush b = Report.GraphicCache.GetBrush(Color.FromArgb(80, SystemColors.Highlight));
  136. g.FillRectangle(b, rect.Left, rect.Top, rect.Width, rect.Height);
  137. Pen pen = Report.GraphicCache.GetPen(SystemColors.Highlight, 1, DashStyle.Dash);
  138. g.DrawRectangle(pen, rect.Left, rect.Top, rect.Width, rect.Height);
  139. }
  140. #endregion
  141. #region Protected Methods
  142. protected override float GridSnapSize
  143. {
  144. get { return Grid.SnapSize; }
  145. }
  146. protected override bool CheckGridStep()
  147. {
  148. bool al = SnapToGrid;
  149. if ((ModifierKeys & Keys.Alt) > 0)
  150. al = !al;
  151. bool result = true;
  152. float kx = eventArgs.delta.X;
  153. float ky = eventArgs.delta.Y;
  154. if (al)
  155. {
  156. result = kx >= GridSnapSize || kx <= -GridSnapSize || ky >= GridSnapSize || ky <= -GridSnapSize;
  157. if (result)
  158. {
  159. kx = (int)(kx / GridSnapSize) * GridSnapSize;
  160. ky = (int)(ky / GridSnapSize) * GridSnapSize;
  161. }
  162. }
  163. else
  164. {
  165. result = kx != 0 || ky != 0;
  166. }
  167. eventArgs.delta.X = kx;
  168. eventArgs.delta.Y = ky;
  169. return result;
  170. }
  171. protected override void OnPaint(PaintEventArgs e)
  172. {
  173. if (Locked || Page == null || Report == null)
  174. return;
  175. // add extra room to fit tooltip
  176. int _100 = this.LogicalToDevice(100);
  177. #if AVALONIA
  178. // do not alter size in the paint event
  179. Avalonia.Threading.Dispatcher.UIThread.InvokeAsync(() => Size = new Size(Page.Form.FrameSize().Width + _100, Page.Form.FrameSize().Height + _100));
  180. #else
  181. Size = new Size(Page.Form.FrameSize().Width + _100, Page.Form.FrameSize().Height + _100);
  182. #endif
  183. Graphics g = e.Graphics;
  184. FRPaintEventArgs paintArgs = new FRPaintEventArgs(g, 1, 1, Report.GraphicCache);
  185. // check if workspace is active (in the mdi mode).
  186. ObjectCollection objects = Designer.Objects;
  187. if (Designer.ActiveReport != Report)
  188. {
  189. objects = Page.AllObjects;
  190. objects.Add(Page);
  191. }
  192. // draw form
  193. int _10 = this.LogicalToDevice(10);
  194. Page.SetDesigning(true);
  195. g.DrawImage(Page.FormBitmap, _10, _10);
  196. g.TranslateTransform(Offset.X, Offset.Y);
  197. if (ShowGrid)
  198. Grid.Draw(e.Graphics, new Rectangle(0, 0, (int)Page.ClientSize.Width, (int)Page.ClientSize.Height));
  199. // draw objects
  200. foreach (Base obj in objects)
  201. {
  202. if (obj is ComponentBase)
  203. {
  204. obj.SetDesigning(true);
  205. (obj as ComponentBase).Draw(paintArgs);
  206. }
  207. }
  208. // draw selection
  209. if (!mouseDown && Designer.ActiveReport == Report)
  210. {
  211. foreach (Base obj in Designer.SelectedObjects)
  212. {
  213. if (obj is ComponentBase)
  214. (obj as ComponentBase).DrawSelection(paintArgs);
  215. }
  216. }
  217. virtualGuides.Draw(g);
  218. if (mode2 == WorkspaceMode2.SelectionRect)
  219. DrawSelectionRect(paintArgs);
  220. DrawToolTip(g);
  221. }
  222. protected override void ShowLocationSizeToolTip(int x, int y)
  223. {
  224. string s = "";
  225. RectangleF selectedRect = GetSelectedRect();
  226. if (mode2 == WorkspaceMode2.Move)
  227. s = selectedRect.Left.ToString() + "; " + selectedRect.Top.ToString();
  228. else if (mode2 == WorkspaceMode2.Size)
  229. s = selectedRect.Width.ToString() + "; " + selectedRect.Height.ToString();
  230. ShowToolTip(s, x, y);
  231. }
  232. protected override void OnDragOver(DragEventArgs drgevent)
  233. {
  234. base.OnDragOver(drgevent);
  235. if (!Designer.cmdInsert.Enabled)
  236. {
  237. drgevent.Effect = DragDropEffects.None;
  238. return;
  239. }
  240. if (mode1 != WorkspaceMode1.DragDrop)
  241. {
  242. DictionaryWindow.DraggedItem item = DictionaryWindow.DragUtils.GetOne(drgevent);
  243. if (item == null)
  244. return;
  245. Type dataType = null;
  246. if (item.obj is Column)
  247. dataType = (item.obj as Column).DataType;
  248. else if (item.obj is Parameter)
  249. dataType = (item.obj as Parameter).DataType;
  250. else
  251. return;
  252. // determine type of control to insert
  253. Type controlType = typeof(NumericUpDownControl);
  254. if (dataType == typeof(string) || dataType == typeof(char))
  255. controlType = typeof(TextBoxControl);
  256. else if (dataType == typeof(DateTime) || dataType == typeof(TimeSpan))
  257. controlType = typeof(DateTimePickerControl);
  258. else if (dataType == typeof(bool))
  259. controlType = typeof(CheckBoxControl);
  260. else if (dataType == typeof(byte[]))
  261. controlType = null;
  262. if (controlType == null)
  263. {
  264. drgevent.Effect = DragDropEffects.None;
  265. return;
  266. }
  267. // create label and control
  268. bool needCreateLabel = controlType != typeof(CheckBoxControl);
  269. if (needCreateLabel)
  270. {
  271. Designer.InsertObject(new ObjectInfo[] {
  272. RegisteredObjects.FindObject(controlType),
  273. RegisteredObjects.FindObject(typeof(LabelControl)) }, InsertFrom.Dictionary);
  274. }
  275. else
  276. {
  277. Designer.InsertObject(RegisteredObjects.FindObject(controlType), InsertFrom.Dictionary);
  278. }
  279. // setup control datafiltering
  280. DataFilterBaseControl control = Designer.SelectedObjects[0] as DataFilterBaseControl;
  281. control.Top += (16 / Grid.SnapSize) * Grid.SnapSize;
  282. if (item.obj is Column)
  283. control.DataColumn = item.text;
  284. else if (item.obj is Parameter)
  285. control.ReportParameter = item.text;
  286. // setup label text
  287. string labelText = "";
  288. if (item.obj is Column)
  289. labelText = (item.obj as Column).Alias;
  290. else if (item.obj is Parameter)
  291. {
  292. labelText = (item.obj as Parameter).Description;
  293. if (String.IsNullOrEmpty(labelText))
  294. labelText = (item.obj as Parameter).Name;
  295. }
  296. if (needCreateLabel)
  297. {
  298. LabelControl label = Designer.SelectedObjects[1] as LabelControl;
  299. label.Text = labelText;
  300. }
  301. else
  302. control.Text = labelText;
  303. eventArgs.DragSource = control;
  304. }
  305. mode1 = WorkspaceMode1.DragDrop;
  306. Point pt = PointToClient(new Point(drgevent.X, drgevent.Y));
  307. OnMouseMove(new MouseEventArgs(MouseButtons.Left, 0, pt.X, pt.Y, 0));
  308. drgevent.Effect = drgevent.AllowedEffect;
  309. }
  310. protected override void OnDragDrop(DragEventArgs drgevent)
  311. {
  312. base.OnDragDrop(drgevent);
  313. DictionaryWindow.DraggedItem item = DictionaryWindow.DragUtils.GetOne(drgevent);
  314. if (item == null)
  315. return;
  316. Point pt = PointToClient(new Point(drgevent.X, drgevent.Y));
  317. OnMouseUp(new MouseEventArgs(MouseButtons.Left, 0, pt.X, pt.Y, 0));
  318. if (eventArgs.DragSource != null)
  319. AfterDragDrop(pt);
  320. }
  321. protected override void OnDragLeave(EventArgs e)
  322. {
  323. base.OnDragLeave(e);
  324. CancelPaste();
  325. }
  326. #endregion
  327. #region Public Methods
  328. public override float GetScale()
  329. {
  330. return 1;
  331. }
  332. protected override Base GetParentForPastedObjects()
  333. {
  334. return Page;
  335. }
  336. public override void Paste(ObjectCollection list, InsertFrom source)
  337. {
  338. base.Paste(list, source);
  339. // scale if necessary
  340. if (source != InsertFrom.Clipboard)
  341. {
  342. foreach (Base c in list)
  343. {
  344. if (c is DialogControl)
  345. {
  346. float scale = this.Dpi() / 96f;
  347. (c as DialogControl).Control.Scale(new SizeF(scale, scale));
  348. }
  349. }
  350. }
  351. // find left-top edge of inserted objects
  352. float minLeft = 100000;
  353. float minTop = 100000;
  354. foreach (Base c in list)
  355. {
  356. if (c is ComponentBase)
  357. {
  358. ComponentBase c1 = c as ComponentBase;
  359. if (c1.Left < minLeft)
  360. minLeft = c1.Left;
  361. if (c1.Top < minTop)
  362. minTop = c1.Top;
  363. }
  364. }
  365. foreach (Base c in list)
  366. {
  367. // correct the left-top
  368. if (c is ComponentBase)
  369. {
  370. ComponentBase c1 = c as ComponentBase;
  371. c1.Left -= minLeft + Grid.SnapSize * 1000;
  372. c1.Top -= minTop + Grid.SnapSize * 1000;
  373. if (c1.Width == 0 && c1.Height == 0)
  374. {
  375. SizeF preferredSize = c1.GetPreferredSize();
  376. c1.Width = preferredSize.Width;
  377. c1.Height = preferredSize.Height;
  378. if (SnapToGrid)
  379. {
  380. c1.Width = (int)Math.Round(c1.Width / Grid.SnapSize) * Grid.SnapSize;
  381. c1.Height = (int)Math.Round(c1.Height / Grid.SnapSize) * Grid.SnapSize;
  382. }
  383. }
  384. }
  385. }
  386. mode1 = WorkspaceMode1.Insert;
  387. mode2 = WorkspaceMode2.Move;
  388. eventArgs.activeObject = null;
  389. int _10 = this.LogicalToDevice(10);
  390. OnMouseDown(new MouseEventArgs(MouseButtons.Left, 0,
  391. Offset.X + _10 - (int)(Grid.SnapSize * 1000), Offset.Y + _10 - (int)(Grid.SnapSize * 1000), 0));
  392. }
  393. public override void Refresh()
  394. {
  395. // FR.Net issue with PanelX: called from constructor when PageDesigner is not set yet
  396. if (PageDesigner == null)
  397. return;
  398. UpdateStatusBar();
  399. base.Refresh();
  400. }
  401. #endregion
  402. public DialogWorkspace(PageDesignerBase pageDesigner)
  403. : base(pageDesigner)
  404. {
  405. SnapToGrid = true;
  406. BackColor = SystemColors.Window;
  407. }
  408. }
  409. }