using FastReport.Design.PageDesigners.Code;
using FastReport.Design.ToolWindows;
using FastReport.Forms;
using FastReport.Preview;
using FastReport.Utils;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.IO;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace FastReport.Design
{
///
/// Represents the report's designer control.
///
///
/// Usually you don't need to create an instance of this class. The designer can be called
/// using the method of
/// the instance.
/// This control represents pure designer surface + Objects toolbar. If you need
/// standard menu, statusbar, toolbars and tool windows, use the
/// control instead. Also you may
/// decide to use a designer's form ()
/// instead of a control.
/// To run a designer, you need to attach a Report instance to it. This can be done via
/// the property.
/// To call the designer in MDI (Multi-Document Interface) mode, use the
/// property.
/// To set up some global properties, use the static class
/// or component that you can use in the Visual Studio IDE.
///
[ToolboxItem(false)]
[Designer("FastReport.VSDesign.DesignerControlLayoutDesigner, FastReport.VSDesign, Version=1.0.0.0, Culture=neutral, PublicKeyToken=db7e5ce63278458c, processorArchitecture=MSIL")]
public partial class Designer : UserControl, ISupportInitialize
{
#region Fields
private Report report;
private ReportTab activeReportTab;
private PluginCollection plugins;
private List recentFiles;
private DesignerClipboard clipboard;
private bool mdiMode;
private List documents;
private StartPageTab startPage;
private ObjectCollection objects;
private SelectedObjectCollection selectedObjects;
private SelectedObjectCollection previouslySelectedObjects;
private SelectedComponents selectedComponents;
private SelectedReportComponents selectedReportComponents;
private SelectedTextObjects selectedTextObjects;
private LastFormatting lastFormatting;
private bool modified;
private bool formatPainter;
private ReportComponentBase formatPainterPattern;
private DesignerRestrictions restrictions;
private bool isPreviewPageDesigner;
private bool askSave;
private string layoutState;
private bool initFlag;
private bool layoutNeeded;
private UIStyle uIStyle;
private StorageService designerStorage;
private StorageService autoSaveStorage;
private Timer autoSaveTimer;
private TaskCompletionSource embeddedPreviewCompletion;
private PreviewControl embeddedPreview;
// tools
private ObjectsToolbar objectsToolbar;
private DictionaryWindow dataWindow;
private PropertiesWindow propertiesWindow;
private ReportTreeWindow reportTreeWindow;
private MessagesWindow messagesWindow;
// commands
private NewCommand fcmdNew;
private NewPageCommand fcmdNewPage;
private NewDialogCommand fcmdNewDialog;
private OpenCommand fcmdOpen;
private OpenPageCommand fcmdOpenPage;
private OpenViaCloudCommand fcmdOpenViaCloud;
private SaveCommand fcmdSave;
private SaveToCloudCommand fcmdSaveToCloud;
private SaveAsCommand fcmdSaveAs;
private SaveWithRandomDataCommand fcmdSaveWithRandomData;
private SaveAllCommand fcmdSaveAll;
private CloseCommand fcmdClose;
private CloseAllCommand fcmdCloseAll;
private PreviewCommand fcmdPreview;
private PreviewCloudCommand fcmdPreviewCloud;
private PrinterSettingsCommand fcmdPrinterSetup;
private PageSettingsCommand fcmdPageSetup;
private AddDataCommand fcmdAddData;
private SortDataSourcesCommand fcmdSortDataSources;
private ChooseDataCommand fcmdChooseData;
private UndoCommand fcmdUndo;
private RedoCommand fcmdRedo;
private CutCommand fcmdCut;
private CopyCommand fcmdCopy;
private PasteCommand fcmdPaste;
private FormatPainterCommand fcmdFormatPainter;
private DeleteCommand fcmdDelete;
private CopyPageCommand copyPageCommand;
private DeletePageCommand fcmdDeletePage;
private SelectAllCommand fcmdSelectAll;
private GroupCommand fcmdGroup;
private UngroupCommand fcmdUngroup;
private EditCommand fcmdEdit;
private FindCommand fcmdFind;
private ReplaceCommand fcmdReplace;
private BringToFrontCommand fcmdBringToFront;
private SendToBackCommand fcmdSendToBack;
private InsertCommand fcmdInsert;
private InsertBandCommand fcmdInsertBand;
private RecentFilesCommand fcmdRecentFiles;
private SelectLanguageCommand fcmdSelectLanguage;
private ViewStartPageCommand fcmdViewStartPage;
private ReportSettingsCommand fcmdReportSettings;
private OptionsCommand fcmdOptions;
private ReportStylesCommand fcmdReportStyles;
private ReportValidationCommand fcmdReportValidation;
private HelpContentsCommand fcmdHelpContents;
private AccountCommand fcmdAccount;
private AboutCommand fcmdAbout;
private WelcomeCommand fcmdWelcome;
// polygon
private PolygonSelectModeCommand fcmdPolySelectMove;
private PolygonSelectModeCommand fcmdPolySelectPointer;
private PolygonSelectModeCommand fcmdPolySelectAddPoint;
private PolygonSelectModeCommand fcmdPolySelectBezier;
private PolygonSelectModeCommand fcmdPolySelectRemovePoint;
#endregion
#region Properties
///
/// Occurs when designer's UI state changed.
///
public event EventHandler UIStateChanged;
///
/// Gets or sets the edited report.
///
///
/// To initialize the designer, you need to pass a Report instance to this property.
/// This will create the designer's surface associated with the report.
///
/// Designer designer = new Designer();
/// designer.Parent = form1;
/// designer.Report = report1;
///
///
[Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public Report Report
{
get { return report; }
set
{
report = value;
if (report != null)
report.Designer = this;
InitTabs();
}
}
///
/// Gets active report object.
///
///
/// May be null if Start Page selected, or no reports opened.
///
[Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public Report ActiveReport
{
get { return activeReportTab == null ? null : activeReportTab.Report; }
set
{
foreach (DocumentWindow c in Documents)
{
if (c is ReportTab && (c as ReportTab).Report == value)
{
c.Activate();
return;
}
}
}
}
///
/// Gets a collection of global plugins such as menu, properties window, etc.
///
[Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public PluginCollection Plugins
{
get { return plugins; }
}
///
/// Gets a collection of objects on the active page of the active report.
///
[Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public ObjectCollection Objects
{
get { return objects; }
}
///
/// Gets a collection of selected objects on the active page of the active report.
///
[Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public SelectedObjectCollection SelectedObjects
{
get { return selectedObjects; }
}
///
/// Gets a collection of selected objects of the ComponentBase type.
///
[Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public SelectedComponents SelectedComponents
{
get { return selectedComponents; }
}
///
/// Gets a collection of selected objects of the ReportComponentBase type.
///
[Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public SelectedReportComponents SelectedReportComponents
{
get { return selectedReportComponents; }
}
///
/// Gets a collection of selected objects of the TextObject type.
///
[Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public SelectedTextObjects SelectedTextObjects
{
get { return selectedTextObjects; }
}
///
/// Gets or sets a value indicating that the report was modified.
///
[Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public bool Modified
{
get { return modified; }
set { modified = value; }
}
///
/// Gets or sets a value that determines whether to ask user to save changes when closing the designer.
///
public bool AskSave
{
get { return askSave; }
set { askSave = value; }
}
///
/// Gets the designer restrictions.
///
public DesignerRestrictions Restrictions
{
get { return restrictions; }
}
///
/// Gets or sets a value indicating that designer is run in MDI mode.
///
///
/// To call the designer in MDI (Multi-Document Interface) mode, use the following code:
///
/// DesignerControl designer = new DesignerControl();
/// designer.MdiMode = true;
/// designer.ShowDialog();
///
///
[DefaultValue(false)]
public bool MdiMode
{
get { return mdiMode; }
set
{
mdiMode = value;
UpdateMdiMode();
}
}
///
/// Gets or sets the visual style.
///
public UIStyle UIStyle
{
get { return uIStyle; }
set
{
uIStyle = value;
UpdateUIStyle();
UIStyleChanged?.Invoke(this, EventArgs.Empty);
}
}
///
/// Occurs when the UIStyle property is changed.
///
public event EventHandler UIStyleChanged;
///
/// Gets a value indicating that designer is used to edit a preview page.
///
[Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public bool IsPreviewPageDesigner
{
get { return isPreviewPageDesigner; }
set { isPreviewPageDesigner = value; }
}
///
/// Gets or sets the zoom factor.
///
public float Zoom
{
get
{
if (ActiveReportTab != null)
return ActiveReportTab.Zoom;
return 1;
}
set
{
if (ActiveReportTab != null)
ActiveReportTab.Zoom = value;
}
}
///
/// Gets the zoom factor with respect of designer's dpi value.
///
public float ZoomDpi
{
get { return Zoom * this.DpiMultiplier(); }
}
///
/// The "File|New" command.
///
[Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public NewCommand cmdNew
{
get { return fcmdNew; }
}
///
/// The "New Page" toolbar command.
///
[Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public NewPageCommand cmdNewPage
{
get { return fcmdNewPage; }
}
///
/// The "New Dialog" toolbar command.
///
[Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public NewDialogCommand cmdNewDialog
{
get { return fcmdNewDialog; }
}
///
/// The "File|Open|Open locally." command.
///
[Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public OpenCommand cmdOpen
{
get { return fcmdOpen; }
}
///
/// The "File|Open|Open page." command.
///
[Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public OpenPageCommand cmdOpenPage
{
get { return fcmdOpenPage; }
}
///
/// The "File|Open|Open via Cloud." command.
///
[Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public OpenViaCloudCommand cmdOpenViaCloud
{
get { return fcmdOpenViaCloud; }
}
///
/// The "File|Save" command.
///
[Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public SaveCommand cmdSave
{
get { return fcmdSave; }
}
///
/// The "File|Save to Cloud" command.
///
[Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public SaveToCloudCommand cmdSaveToCloudCommand
{
get { return fcmdSaveToCloud; }
}
///
/// The "File|Save As..." command.
///
[Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public SaveAsCommand cmdSaveAs
{
get { return fcmdSaveAs; }
}
///
/// The "File|Save With Random Data..." command.
///
[Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public SaveWithRandomDataCommand cmdSaveWithRandomData
{
get { return fcmdSaveWithRandomData; }
}
///
/// The "File|Save All" command.
///
[Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public SaveAllCommand cmdSaveAll
{
get { return fcmdSaveAll; }
}
///
/// The "File|Close" command.
///
[Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public CloseCommand cmdClose
{
get { return fcmdClose; }
}
///
/// The "Window|Close All" command.
///
[Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public CloseAllCommand cmdCloseAll
{
get { return fcmdCloseAll; }
}
///
/// The "File|Preview..." command.
///
[Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public PreviewCommand cmdPreview
{
get { return fcmdPreview; }
}
///
/// The "File|Preview on Cloud..." command.
///
[Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public PreviewCloudCommand cmdPreviewCloud
{
get { return fcmdPreviewCloud; }
}
///
/// The "File|Printer Setup..." command.
///
[Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public PrinterSettingsCommand cmdPrinterSetup
{
get { return fcmdPrinterSetup; }
}
///
/// The "File|Page Setup..." command.
///
[Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public PageSettingsCommand cmdPageSetup
{
get { return fcmdPageSetup; }
}
///
/// The "Data|Add New Data Source..." command.
///
[Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public AddDataCommand cmdAddData
{
get { return fcmdAddData; }
}
///
/// The "Data|Sort Data Sources" command.
///
public SortDataSourcesCommand cmdSortDataSources
{
get { return fcmdSortDataSources; }
}
///
/// The "Data|Choose Report Data..." command.
///
[Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public ChooseDataCommand cmdChooseData
{
get { return fcmdChooseData; }
}
///
/// The "Edit|Undo" command.
///
[Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public UndoCommand cmdUndo
{
get { return fcmdUndo; }
}
///
/// The "Edit|Redo" command.
///
[Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public RedoCommand cmdRedo
{
get { return fcmdRedo; }
}
///
/// The "Edit|Cut" command.
///
[Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public CutCommand cmdCut
{
get { return fcmdCut; }
}
///
/// The "Edit|Copy" command.
///
[Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public CopyCommand cmdCopy
{
get { return fcmdCopy; }
}
///
/// The "Edit|Paste" command.
///
[Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public PasteCommand cmdPaste
{
get { return fcmdPaste; }
}
///
/// The "Format Painter" toolbar command.
///
[Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public FormatPainterCommand cmdFormatPainter
{
get { return fcmdFormatPainter; }
}
///
/// The "Edit|Delete" command.
///
[Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public DeleteCommand cmdDelete
{
get { return fcmdDelete; }
}
///
/// The "Edit|Copy Page" command.
///
[Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public CopyPageCommand cmdCopyPage
{
get { return copyPageCommand; }
}
///
/// The "Edit|Delete Page" command.
///
[Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public DeletePageCommand cmdDeletePage
{
get { return fcmdDeletePage; }
}
///
/// The "Edit|Select All" command.
///
[Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public SelectAllCommand cmdSelectAll
{
get { return fcmdSelectAll; }
}
///
/// The "Edit|Group" command.
///
[Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public GroupCommand cmdGroup
{
get { return fcmdGroup; }
}
///
/// The "Edit|Ungroup" command.
///
[Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public UngroupCommand cmdUngroup
{
get { return fcmdUngroup; }
}
///
/// The "Edit" command.
///
[Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public EditCommand cmdEdit
{
get { return fcmdEdit; }
}
///
/// The "Edit|Find..." command.
///
[Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public FindCommand cmdFind
{
get { return fcmdFind; }
}
///
/// The "Polygon move command" command.
///
[Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public PolygonSelectModeCommand CmdPolySelectMove
{
get { return fcmdPolySelectMove; }
}
///
/// The "Polygon point move" command.
///
[Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public PolygonSelectModeCommand CmdPolySelectPointer
{
get { return fcmdPolySelectPointer; }
}
///
/// The "Polygon add new point" command.
///
[Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public PolygonSelectModeCommand CmdPolySelectAddPoint
{
get { return fcmdPolySelectAddPoint; }
}
///
/// The "Polygon berier" command.
///
[Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public PolygonSelectModeCommand CmdPolySelectBezier
{
get { return fcmdPolySelectBezier; }
}
///
/// The "Polygon remove point" command.
///
[Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public PolygonSelectModeCommand CmdPolySelectRemovePoint
{
get { return fcmdPolySelectRemovePoint; }
}
///
/// The "Edit|Replace..." command.
///
[Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public ReplaceCommand cmdReplace
{
get { return fcmdReplace; }
}
///
/// The "Bring To Front" command.
///
[Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public BringToFrontCommand cmdBringToFront
{
get { return fcmdBringToFront; }
}
///
/// The "Send To Back" command.
///
[Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public SendToBackCommand cmdSendToBack
{
get { return fcmdSendToBack; }
}
///
/// The "Insert" command.
///
[Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public InsertCommand cmdInsert
{
get { return fcmdInsert; }
}
///
/// The "Insert Band" command.
///
[Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public InsertBandCommand cmdInsertBand
{
get { return fcmdInsertBand; }
}
///
/// The "Recent Files" command.
///
[Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public RecentFilesCommand cmdRecentFiles
{
get { return fcmdRecentFiles; }
}
///
/// The "File|Select Language..." command.
///
[Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public SelectLanguageCommand cmdSelectLanguage
{
get { return fcmdSelectLanguage; }
}
///
/// The "View|Start Page" command.
///
[Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public ViewStartPageCommand cmdViewStartPage
{
get { return fcmdViewStartPage; }
}
///
/// The "Report|Options..." command.
///
[Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public ReportSettingsCommand cmdReportSettings
{
get { return fcmdReportSettings; }
}
///
/// The "View|Options..." command.
///
[Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public OptionsCommand cmdOptions
{
get { return fcmdOptions; }
}
///
/// The "Report|Styles..." command.
///
[Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public ReportStylesCommand cmdReportStyles
{
get { return fcmdReportStyles; }
}
///
/// The "Report|Validation" command.
///
[Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public ReportValidationCommand cmdReportValidation
{
get { return fcmdReportValidation; }
}
///
/// The "Help|Help Contents..." command.
///
[Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public HelpContentsCommand cmdHelpContents
{
get { return fcmdHelpContents; }
}
///
/// The "Help|Account" command.
///
[Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public AccountCommand cmdAccount
{
get { return fcmdAccount; }
}
///
/// The "Help|About..." command.
///
[Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public AboutCommand cmdAbout
{
get { return fcmdAbout; }
}
///
/// The "Show welcome window..." command.
///
[Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public WelcomeCommand cmdWelcome
{
get { return fcmdWelcome; }
}
///
/// Gets or sets the layout state of the designer.
///
///
/// This property is used to store layout in Visual Studio design time. You may also use
/// it to save and restore the designer's layout in your code. However, consider using the
/// and methods that use FastReport
/// configuration file.
///
[Browsable(false)]
public string LayoutState
{
get
{
XmlDocument doc = new XmlDocument();
doc.Root.Name = "Config";
SaveDockState(doc.Root);
using (MemoryStream stream = new MemoryStream())
{
doc.Save(stream);
return Encoding.UTF8.GetString(stream.ToArray());
}
}
set
{
layoutState = value;
if (initFlag)
layoutNeeded = true;
else
RestoreLayout(value);
}
}
///
/// Fires when the layout is changed.
///
///
/// This event is for internal use only.
///
public event EventHandler LayoutChangedEvent;
internal StartPageTab StartPage
{
get { return startPage; }
}
// active report tab. May be null if Start Page selected, or no reports opened
internal ReportTab ActiveReportTab
{
get { return activeReportTab; }
set
{
if (activeReportTab != value)
{
if (activeReportTab != null)
activeReportTab.ReportDeactivated();
activeReportTab = value;
if (value != null)
value.ReportActivated();
else
ClearSelection();
UpdatePlugins(null);
}
}
}
// list of recent opened files
internal List RecentFiles
{
get { return recentFiles; }
}
internal List Documents
{
get { return documents; }
}
internal DesignerClipboard Clipboard
{
get { return clipboard; }
}
internal DictionaryWindow DataWindow
{
get { return dataWindow; }
}
internal PropertiesWindow PropertiesWindow
{
get { return propertiesWindow; }
}
internal ReportTreeWindow ReportTreeWindow
{
get { return reportTreeWindow; }
}
internal MessagesWindow MessagesWindow
{
get { return messagesWindow; }
}
internal CodePageDesigner Editor
{
get { return ActiveReportTab.Editor; }
}
internal LastFormatting LastFormatting
{
get { return lastFormatting; }
}
internal bool FormatPainter
{
get { return formatPainter; }
set
{
if (formatPainter != value)
{
formatPainter = value;
formatPainterPattern = value ? SelectedReportComponents.First : null;
UpdatePlugins(null);
}
}
}
internal bool IsVSDesignMode
{
get { return DesignMode; }
}
internal Timer AutoSaveTimer
{
get { return autoSaveTimer; }
}
internal Dictionary CloudReportDictionary { get; set; } = new Dictionary();
#endregion
#region Private Methods
private void SetupAutoSave()
{
autoSaveStorage = new StorageService("Designer,Saving");
autoSaveTimer = new Timer();
autoSaveTimer.Interval = autoSaveStorage.GetInt("AutoSaveMinutes", 5) * 60000;
autoSaveTimer.Tick += delegate (object s1, EventArgs e1)
{
if (this != null && !IsPreviewPageDesigner)
{
if (cmdSave.Enabled)
{
ActiveReportTab.AutoSaveFile();
}
else
{
if (File.Exists(Config.AutoSaveFileName))
File.Delete(Config.AutoSaveFileName);
if (File.Exists(Config.AutoSaveFile))
File.Delete(Config.AutoSaveFile);
}
}
};
}
///
/// Updates UI style of the designer.
///
public virtual void UpdateUIStyle()
{
UpdateUIStyleInternal();
foreach (DocumentWindow document in Documents)
{
document.UpdateUIStyle();
}
plugins.UpdateUIStyle();
}
// create initial pages (Start Page, default report)
private void InitTabs()
{
if (mdiMode)
AddStartPageTab();
if (report != null)
AddReportTab(CreateReportTab(report));
}
private void AddDocument(DocumentWindow doc)
{
Documents.Add(doc);
doc.AddToTabControl(tabs);
doc.Activate();
}
private void RemoveDocument(DocumentWindow doc)
{
if (doc is StartPageTab)
startPage = null;
Documents.Remove(doc);
doc.Close();
}
internal bool CloseDocument(DocumentWindow doc)
{
if (doc is ReportTab)
{
if (!(doc as ReportTab).CanClose())
return false;
}
RemoveDocument(doc);
return true;
}
private void ClearSelection()
{
activeReportTab = null;
Objects.Clear();
SelectedObjects.Clear();
SelectionChanged(null);
UpdatePlugins(null);
}
#endregion
#region Protected Methods
///
/// Initializes designer plugins such as toolbars and toolwindows.
///
protected virtual void InitPlugins()
{
InitTools();
plugins.AddRange(new IDesignerPlugin[] {
objectsToolbar, dataWindow, propertiesWindow,
reportTreeWindow, messagesWindow });
// add export plugins
plugins.Add(typeof(ExportPlugins.FR3.FR3ExportPlugin));
#if MSCHART
plugins.Add(typeof(ExportPlugins.RDL.RDLExportPlugin));
#endif
// add import plugins
#if MSCHART
plugins.Add(typeof(ImportPlugins.RDL.RDLImportPlugin));
#endif
plugins.Add(typeof(ImportPlugins.ListAndLabel.ListAndLabelImportPlugin));
plugins.Add(typeof(ImportPlugins.DevExpress.DevExpressImportPlugin));
plugins.Add(typeof(ImportPlugins.RTF.RTFImportPlugin));
plugins.Add(typeof(ImportPlugins.StimulSoft.StimulSoftImportPlugin));
plugins.Add(typeof(ImportPlugins.JasperReports.JasperReportsImportPlugin));
}
#endregion
#region Public Methods
///
/// Zooms the report to page width.
///
public void ZoomPageWidth()
{
if (ActiveReportTab != null)
ActiveReportTab.ZoomPageWidth();
}
///
/// Zooms the report to whole page.
///
public void ZoomWholePage()
{
if (ActiveReportTab != null)
ActiveReportTab.ZoomWholePage();
}
///
/// Cancels paste mode.
///
public void CancelPaste()
{
ActiveReportTab.ActivePageDesigner.CancelPaste();
}
///
/// AutoSave system initialization.
///
public void StartAutoSave()
{
if (IsPreviewPageDesigner)
return;
if (File.Exists(Config.AutoSaveFile) &&
File.Exists(Config.AutoSaveFileName) &&
autoSaveStorage.GetBool("EnableAutoSave", true) == true)
{
string filepath = File.ReadAllText(Config.AutoSaveFileName);
using (LoadAutoSaveForm f = new LoadAutoSaveForm(filepath))
{
if (f.ShowDialog() == DialogResult.OK)
{
ActiveReportTab.LoadAutoSaveFile(filepath);
SetModified();
}
}
}
if (File.Exists(Config.AutoSaveFileName))
File.Delete(Config.AutoSaveFileName);
if (File.Exists(Config.AutoSaveFile))
File.Delete(Config.AutoSaveFile);
autoSaveTimer.Enabled = autoSaveStorage.GetBool("EnableAutoSave", true);
}
///
/// Stops the AutoSave system.
///
public void StopAutoSave()
{
if (IsPreviewPageDesigner)
return;
autoSaveTimer.Stop();
if (File.Exists(Config.AutoSaveFileName))
File.Delete(Config.AutoSaveFileName);
if (File.Exists(Config.AutoSaveFile))
File.Delete(Config.AutoSaveFile);
}
///
/// Call this method if you change something in the report.
///
///
/// This method adds the current report state to the undo buffer and updates all plugins.
///
public void SetModified()
{
SetModified(null, "Change");
}
///
/// Call this method if you change something in the report.
///
/// The object that was modified.
/// The undo action name.
///
/// This method adds the current report state to the undo buffer and updates all plugins.
///
public void SetModified(object sender, string action)
{
SetModified(sender, action, null);
}
///
/// Call this method if you change something in the report.
///
/// The object that was modified.
/// The undo action name.
/// The name of modified object.
public void SetModified(object sender, string action, string objName)
{
modified = true;
if (ActiveReportTab != null)
ActiveReportTab.SetModified(sender, action, objName);
UpdatePlugins(sender);
}
///
/// Call this method to tell the designer that current selection is changed.
///
/// The plugin that changes the selection (may be null).
public void SelectionChanged(object sender)
{
// check groups
ObjectCollection selectedObjects = new ObjectCollection();
SelectedObjects.CopyTo(selectedObjects);
foreach (Base c in selectedObjects)
{
if (c is ComponentBase && (c as ComponentBase).GroupIndex != 0)
{
int groupIndex = (c as ComponentBase).GroupIndex;
foreach (Base c1 in Objects)
{
if (c1 is ComponentBase && (c1 as ComponentBase).GroupIndex == groupIndex)
{
if (SelectedObjects.IndexOf(c1) == -1)
SelectedObjects.Add(c1);
}
}
}
}
foreach (Base c in previouslySelectedObjects)
{
c.SelectionChanged();
}
foreach (Base c in selectedObjects)
{
c.SelectionChanged();
if (formatPainter && formatPainterPattern != null && c is ReportComponentBase)
(c as ReportComponentBase).AssignFormat(formatPainterPattern);
}
SelectedComponents.Update();
SelectedReportComponents.Update();
SelectedTextObjects.Update();
if (ActiveReportTab != null)
ActiveReportTab.Plugins.SelectionChanged(sender);
plugins.SelectionChanged(sender);
SelectedObjects.CopyTo(previouslySelectedObjects);
if (formatPainter && formatPainterPattern != null)
{
if (sender != null)
SetModified();
else
{
SetModified(null, "no-undo");
FormatPainter = false;
}
}
OnUIStateChanged();
}
///
/// Locks all plugins.
///
///
/// This method is usually called when we destroy the report to prevent unexpected
/// errors - such as trying to draw destroyed objects.
///
public void Lock()
{
if (ActiveReportTab != null)
ActiveReportTab.Plugins.Lock();
plugins.Lock();
}
///
/// Unlocks all plugins.
///
///
/// Call this method after the Lock.
///
public void Unlock()
{
if (ActiveReportTab != null)
ActiveReportTab.Plugins.Unlock();
plugins.Unlock();
}
///
/// Call this method to refresh all plugins' content.
///
/// The plugin that we don't need to refresh.
public void UpdatePlugins(object sender)
{
if (ActiveReportTab != null)
ActiveReportTab.Plugins.Update(sender);
plugins.Update(sender);
OnUIStateChanged();
}
///
/// Updates localization of the designer.
///
public void Localize()
{
Plugins.Localize();
if (ActiveReportTab != null)
ActiveReportTab.Localize();
// Mono: update toolwindows captions & tabs
LocalizeInternal();
}
///
/// Updates layout and images on dpi change.
///
/// The sender object.
public virtual void UpdateDpiDependencies(object sender)
{
Plugins.UpdateDpiDependencies(sender);
if (ActiveReportTab != null)
ActiveReportTab.UpdateDpiDependencies();
// Mono: this should be after all plugins (TabStrip images related)
UpdateDpiDependenciesInternal();
embeddedPreview?.UpdateDpiDependencies();
}
///
/// Checks if parent window can be closed.
///
/// The cancel event args.
///
/// Use this method in the window's FormClosing event handler if you use this control.
/// This method checks if the embedded preview is running and cancels it. Also if there is unsaved changes, the user will be asked to save changes.
///
public void ParentFormClosing(FormClosingEventArgs e)
{
if (embeddedPreview != null)
{
if (embeddedPreview.IsAsyncReportRunning)
embeddedPreview.Report.Abort();
else
embeddedPreviewCompletion.SetResult(true);
e.Cancel = true;
return;
}
if (!CloseAll())
{
e.Cancel = true;
}
}
internal async Task ShowEmbeddedPreview(Report report)
{
PreviewControl savePreview = report.Preview;
report.Preview = null;
Config.ReportSettings.ShowProgress = false;
bool finished = false;
try
{
if (await report.AsyncPrepareStart()) // startup, compile, run dialogs. May throw a compiler exception
{
var preview = new PreviewControl();
preview.Buttons = Config.PreviewSettings.Buttons | PreviewButtons.Close;
preview.Dock = DockStyle.Fill;
#if !MONO
preview.Size = Parent.ClientSize; // winforms, less flickering; Avalonia - wrong size on pmV2
#endif
preview.Visible = false;
// setup preview control
preview.SetAsyncReportRunning();
report.Preview = preview;
report.SetupPreviewControl();
preview.Parent = Parent;
#if WPF
// fix WPF rendering issues (pmV2)
Application.DoEvents();
#endif
#if !MONO
preview.Scale(new System.Drawing.SizeF(this.FontDpiMultiplier(), this.FontDpiMultiplier()));
#endif
UIUtils.CheckRTL(preview);
preview.UpdateDpiDependencies();
// swap designer and preview
Parent.SuspendLayout();
foreach (Control c in Parent.Controls)
c.Visible = false;
preview.Visible = true;
#if (WPF || AVALONIA)
var form = FindForm().window as IForm;
form.ExtendedAppArea = false;
form.ExtendedAppAreaSize = 0;
preview.control.AnimateOpacity(0, 1, 200);
#endif
Parent.ResumeLayout();
preview.AsyncReportStart();
#if WPF
_ = System.Windows.Threading.Dispatcher.CurrentDispatcher.BeginInvoke(
#elif AVALONIA
_ = Avalonia.Threading.Dispatcher.UIThread.InvokeAsync(
#else
this.BeginInvoke(
#endif
new Action(() =>
{
try
{
report.AsyncPrepareRun(); // run report pages (pseudo async way). May throw runtime exception
}
catch (Exception ex)
{
FRMessageBox.Error(ex.Message);
}
finally
{
report.AsyncPrepareFinish(); // cleanup
preview.AsyncReportFinish();
finished = true;
}
}));
// wait for form is about to close (handled in the DesignerForm.cs code)
embeddedPreview = preview;
embeddedPreviewCompletion = new TaskCompletionSource();
await embeddedPreviewCompletion.Task;
embeddedPreview = null;
embeddedPreviewCompletion = null;
preview.Dispose();
// show the designer control again
Parent.SuspendLayout();
foreach (Control c in Parent.Controls)
{
if (!c.GetType().Name.Contains("RibbonControl") || Config.UseRibbon)
c.Visible = true;
}
#if (WPF || AVALONIA)
form.ExtendedAppArea = true;
#endif
Parent.ResumeLayout();
}
}
finally
{
if (!finished)
report.AsyncPrepareFinish(); // cleanup
report.Preview = savePreview;
}
}
// adds the Start Page tab
internal void AddStartPageTab()
{
if (StartPage != null)
return;
startPage = new StartPageTab(this);
AddDocument(startPage);
UpdatePlugins(null);
}
// adds the report tab
internal ReportTab CreateReportTab(Report report)
{
return new ReportTab(this, report);
}
internal void AddReportTab(ReportTab tab)
{
AddDocument(tab);
tab.UpdateUIStyle();
tab.UpdateDpiDependencies();
ActiveReportTab = tab;
}
private void OnUIStateChanged()
{
if (UIStateChanged != null)
UIStateChanged(this, EventArgs.Empty);
}
#endregion
#region Layout
private void SaveRecentFiles()
{
string files = "";
foreach (string s in RecentFiles)
{
files += s + '\r';
}
designerStorage.SetStr("RecentFiles", files);
}
private void SaveCloudReports()
{
string files = "";
foreach (var pair in CloudReportDictionary)
{
files += pair.Key + '\n' + pair.Value + '\r';
}
designerStorage.SetStr("CloudReports", files);
}
private void RestoreRecentFiles()
{
string[] files = designerStorage.GetStr("RecentFiles").Split(new char[] { '\r' }, StringSplitOptions.RemoveEmptyEntries);
RecentFiles.Clear();
RecentFiles.AddRange(files);
}
private void RestoreCloudReports()
{
var files = designerStorage.GetStr("CloudReports").Split('\r');
CloudReportDictionary.Clear();
if (files.Length < 1 || files[0] == string.Empty)
return;
foreach (var line in files)
{
if (line != string.Empty)
{
var pair = line.Split('\n');
// filename should not be rooted
if (pair.Length == 2 && !Path.IsPathRooted(pair[0]))
CloudReportDictionary.Add(pair[0], pair[1]);
}
}
}
///
/// Saves config to a FastReport configuration file.
///
public void SaveConfig()
{
SaveRecentFiles();
SaveCloudReports();
plugins.SaveState();
SaveDockState(Config.Root);
}
///
/// Restores config from a FastReport configuration file.
///
///
/// Call this method to restore the designer's layout. You need to do this after the
/// designer's control is placed on a form.
///
public void RestoreConfig()
{
BeforeRestoreState();
RestoreRecentFiles();
RestoreCloudReports();
RestoreDockState(Config.Root);
plugins.RestoreState();
AfterRestoreState();
}
///
/// Refresh the designer's toolbars and toolwindows layout.
///
///
/// Call this method if you use
/// DesignerControl. To restore
/// the layout that you've created in VS design time, you need to call this method in the form's
/// Load event handler. If you don't do this, tool windows like Properties, Data, Report Tree
/// will not be available.
///
public void RefreshLayout()
{
RestoreLayout(layoutState);
}
internal virtual void BeforeRestoreState()
{
SuspendLayout();
}
internal virtual void AfterRestoreState()
{
ResumeLayout();
}
private void RestoreLayout(string value)
{
XmlDocument doc = new XmlDocument();
if (value == null)
value = "";
int startIndex = value.IndexOf("");
if (startIndex != -1)
{
using (MemoryStream stream = new MemoryStream(Encoding.UTF8.GetBytes(value.Substring(startIndex))))
{
doc.Load(stream);
}
}
SuspendLayout();
RestoreDockState(doc.Root);
ResumeLayout();
}
///
public void BeginInit()
{
initFlag = true;
}
///
public void EndInit()
{
if (initFlag)
{
if (layoutNeeded)
RestoreLayout(layoutState);
initFlag = false;
layoutNeeded = false;
if (DesignMode)
DisableFloatingBars();
}
}
#endregion
#region Commands
private void InitCommands()
{
fcmdNew = new NewCommand(this);
fcmdNewPage = new NewPageCommand(this);
fcmdNewDialog = new NewDialogCommand(this);
fcmdOpen = new OpenCommand(this);
fcmdOpenPage = new OpenPageCommand(this);
fcmdOpenViaCloud = new OpenViaCloudCommand(this);
fcmdSave = new SaveCommand(this);
fcmdSaveToCloud = new SaveToCloudCommand(this);
fcmdSaveAs = new SaveAsCommand(this);
fcmdSaveWithRandomData = new SaveWithRandomDataCommand(this);
fcmdSaveAll = new SaveAllCommand(this);
fcmdClose = new CloseCommand(this);
fcmdCloseAll = new CloseAllCommand(this);
fcmdPreview = new PreviewCommand(this);
fcmdPreviewCloud = new PreviewCloudCommand(this);
fcmdPrinterSetup = new PrinterSettingsCommand(this);
fcmdPageSetup = new PageSettingsCommand(this);
fcmdAddData = new AddDataCommand(this);
fcmdSortDataSources = new SortDataSourcesCommand(this);
fcmdChooseData = new ChooseDataCommand(this);
fcmdUndo = new UndoCommand(this);
fcmdRedo = new RedoCommand(this);
fcmdCut = new CutCommand(this);
fcmdCopy = new CopyCommand(this);
fcmdPaste = new PasteCommand(this);
fcmdFormatPainter = new FormatPainterCommand(this);
fcmdDelete = new DeleteCommand(this);
copyPageCommand = new CopyPageCommand(this);
fcmdDeletePage = new DeletePageCommand(this);
fcmdSelectAll = new SelectAllCommand(this);
fcmdGroup = new GroupCommand(this);
fcmdUngroup = new UngroupCommand(this);
fcmdEdit = new EditCommand(this);
fcmdFind = new FindCommand(this);
fcmdReplace = new ReplaceCommand(this);
fcmdBringToFront = new BringToFrontCommand(this);
fcmdSendToBack = new SendToBackCommand(this);
fcmdInsert = new InsertCommand(this);
fcmdInsertBand = new InsertBandCommand(this);
fcmdRecentFiles = new RecentFilesCommand(this);
fcmdSelectLanguage = new SelectLanguageCommand(this);
fcmdViewStartPage = new ViewStartPageCommand(this);
fcmdReportSettings = new ReportSettingsCommand(this);
fcmdOptions = new OptionsCommand(this);
fcmdReportStyles = new ReportStylesCommand(this);
fcmdReportValidation = new ReportValidationCommand(this);
fcmdHelpContents = new HelpContentsCommand(this);
fcmdAccount = new AccountCommand(this);
fcmdAbout = new AboutCommand(this);
fcmdWelcome = new WelcomeCommand(this);
fcmdPolySelectAddPoint = new PolygonSelectModeCommand(this, PolyLineObject.PolygonSelectionMode.AddToLine);
fcmdPolySelectBezier = new PolygonSelectModeCommand(this, PolyLineObject.PolygonSelectionMode.AddBezier);
fcmdPolySelectMove = new PolygonSelectModeCommand(this, PolyLineObject.PolygonSelectionMode.MoveAndScale);
fcmdPolySelectPointer = new PolygonSelectModeCommand(this, PolyLineObject.PolygonSelectionMode.Normal);
fcmdPolySelectRemovePoint = new PolygonSelectModeCommand(this, PolyLineObject.PolygonSelectionMode.Delete);
}
internal void InitPages(int pageNo)
{
ActiveReportTab.InitPages(pageNo);
}
///
/// Initializes the workspace after the new report is loaded.
///
public void InitReport()
{
ActiveReportTab.InitReport();
ActiveReportTab.SetModified();
}
internal void InsertObject(ObjectInfo[] infos, InsertFrom source)
{
ObjectCollection list = new ObjectCollection();
CancelPaste();
foreach (ObjectInfo info in infos)
{
Base c = Activator.CreateInstance(info.Object) as Base;
LastFormatting.SetFormatting(c as ReportComponentBase);
c.OnBeforeInsert(info.Flags);
list.Add(c);
//c.Parent = ActiveReportTab.ActivePageDesigner.GetParentForPastedObjects();
Config.DesignerSettings.OnObjectInserted(this, new ObjectInsertedEventArgs(c, source));
}
ActiveReportTab.ActivePageDesigner.Paste(list, source);
}
internal void InsertObject(ObjectInfo info, InsertFrom source)
{
InsertObject(new ObjectInfo[] { info }, source);
}
internal void ResetObjectsToolbar(bool ignoreMultiInsert)
{
objectsToolbar.ClickSelectButton(ignoreMultiInsert);
FormatPainter = false;
}
internal void Exit(object sender, EventArgs e)
{
Form form = FindForm();
if (form != null)
form.Close();
}
///
/// Tries to create a new empty report.
///
/// true if report was created successfully; false if user cancels the action.
public bool CreateEmptyReport()
{
bool result = false;
if (MdiMode)
{
Report report = new Report();
report.Designer = this;
Config.DesignerSettings.OnReportLoaded(this, new ReportLoadedEventArgs(report));
AddReportTab(CreateReportTab(report));
result = true;
}
else
result = ActiveReportTab.EmptyReport(true);
if (result)
{
ActiveReportTab.SetModified();
UpdatePlugins(null);
}
return result;
}
internal void ErrorMsg(string msg, string objName)
{
MessagesWindow.AddMessage(msg, objName);
}
internal void ErrorMsg(string msg, int line, int column)
{
MessagesWindow.AddMessage(msg, line, column);
}
///
/// Displays a message in the "Messages" window.
///
/// Message text.
public void ShowMessage(string msg)
{
MessagesWindow.AddMessage(msg, 1, 1);
}
///
/// Clears the "Messages" window.
///
public void ClearMessages()
{
MessagesWindow.ClearMessages();
}
///
/// Shows the selected object's information in the designer's statusbar.
///
/// Object's location.
/// Object's size.
/// Textual information about the selected object.
/// The location of the lower-right corner of the object's.
public virtual void ShowStatus(string location, string size, string text, string locationRightBot)
{
}
///
/// Close all opened reports, ask to save changes.
///
/// true if all tabs closed succesfully.
///
/// Use this method to close all opened documents and save changes when you closing the main form
/// that contains the designer control. To do this, create an event handler for your form's FormClosing
/// event and call this method inside the handler. If it returns false, set e.Cancel to true.
///
public bool CloseAll()
{
// close all tabs from the last tab to first.
while (Documents.Count > 0)
{
DocumentWindow c = Documents[Documents.Count - 1];
if (!CloseDocument(c))
{
// tab cannot be closed. Activate it and exit. Do not allow to close the designer.
c.Activate();
return false;
}
}
return true;
}
#endregion
///
/// Initializes a new instance of the class with default settings.
///
public Designer()
{
Report.EnsureInit();
plugins = new PluginCollection(this);
recentFiles = new List();
clipboard = new DesignerClipboard(this);
documents = new List();
objects = new ObjectCollection();
selectedObjects = new SelectedObjectCollection();
previouslySelectedObjects = new SelectedObjectCollection();
selectedComponents = new SelectedComponents(this);
selectedReportComponents = new SelectedReportComponents(this);
selectedTextObjects = new SelectedTextObjects(this);
restrictions = Config.DesignerSettings.Restrictions.Clone();
askSave = true;
lastFormatting = new LastFormatting();
designerStorage = new StorageService("Designer");
InitCommands();
InitPluginsInternal();
UpdatePlugins(null);
UpdateMdiMode();
UIStyle = Config.UIStyle;
SetupAutoSave();
InitRightToLeft();
UpdateDpiDependencies(null);
}
}
}