mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-04-14 19:39:39 +02:00
7415 lines
240 KiB
ObjectPascal
7415 lines
240 KiB
ObjectPascal
{ $Id$ }
|
|
{
|
|
/***************************************************************************
|
|
main.pp - Toolbar
|
|
-------------------
|
|
TMainIDE is the application toolbar window.
|
|
|
|
|
|
Initial Revision : Sun Mar 28 23:15:32 CST 1999
|
|
|
|
|
|
***************************************************************************/
|
|
|
|
***************************************************************************
|
|
* *
|
|
* This source is free software; you can redistribute it and/or modify *
|
|
* it under the terms of the GNU General Public License as published by *
|
|
* the Free Software Foundation; either version 2 of the License, or *
|
|
* (at your option) any later version. *
|
|
* *
|
|
* This code is distributed in the hope that it will be useful, but *
|
|
* WITHOUT ANY WARRANTY; without even the implied warranty of *
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
|
|
* General Public License for more details. *
|
|
* *
|
|
* A copy of the GNU General Public License is available on the World *
|
|
* Wide Web at <http://www.gnu.org/copyleft/gpl.html>. You can also *
|
|
* obtain it by writing to the Free Software Foundation, *
|
|
* Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
|
|
* *
|
|
***************************************************************************
|
|
}
|
|
unit Main;
|
|
|
|
{$mode objfpc}{$H+}
|
|
|
|
interface
|
|
|
|
{$I ide.inc}
|
|
|
|
uses
|
|
{$IFDEF IDE_MEM_CHECK}
|
|
MemCheck,
|
|
{$ENDIF}
|
|
Classes, LazarusIDEStrConsts, LCLType, LclLinux, Compiler, StdCtrls, Forms,
|
|
Buttons, Menus, ComCtrls, Spin, Project, SysUtils, FileCtrl, Controls,
|
|
Graphics, GraphType, ExtCtrls, Dialogs, LazConf, CompReg, CodeToolManager,
|
|
CodeCache, DefineTemplates, MsgView, NewProjectDlg, IDEComp,
|
|
AbstractFormEditor, Designer, FormEditor, CustomFormEditor, ObjectInspector,
|
|
PropEdits, ControlSelection, UnitEditor, CompilerOptions, EditorOptions,
|
|
EnvironmentOpts, TransferMacros, SynEditKeyCmds, KeyMapping, ProjectOpts,
|
|
IDEProcs, Process, UnitInfoDlg, Debugger, DBGOutputForm, GDBMIDebugger,
|
|
RunParamsOpts, ExtToolDialog, MacroPromptDlg, LMessages, ProjectDefs,
|
|
Watchesdlg, BreakPointsdlg, ColumnDlg, OutputFilter, BuildLazDialog,
|
|
MiscOptions, EditDefineTree, CodeToolsOptions, TypInfo, IDEOptionDefs,
|
|
CodeToolsDefines, LocalsDlg, DebuggerDlg, InputHistory, DiskDiffsDialog,
|
|
// main ide
|
|
BaseDebugManager, DebugManager, MainBar;
|
|
|
|
type
|
|
TMainIDE = class(TMainIDEBar)
|
|
// event handlers
|
|
//procedure FormShow(Sender : TObject);
|
|
procedure FormClose(Sender : TObject; var Action: TCloseAction);
|
|
procedure FormCloseQuery(Sender : TObject; var CanClose: boolean);
|
|
//procedure FormPaint(Sender : TObject);
|
|
procedure MainMouseMoved(Sender: TObject; Shift: TShiftState; X,Y: Integer);
|
|
procedure MainMouseDown(Sender: TObject; Button: TMouseButton;
|
|
Shift: TShiftState; X,Y: Integer);
|
|
procedure MainKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
|
|
|
|
// file menu
|
|
procedure mnuNewUnitClicked(Sender : TObject);
|
|
procedure mnuNewFormClicked(Sender : TObject);
|
|
procedure mnuOpenClicked(Sender : TObject);
|
|
procedure mnuRevertClicked(Sender : TObject);
|
|
procedure mnuSaveClicked(Sender : TObject);
|
|
procedure mnuSaveAsClicked(Sender : TObject);
|
|
procedure mnuSaveAllClicked(Sender : TObject);
|
|
procedure mnuCloseClicked(Sender : TObject);
|
|
procedure mnuCloseAllClicked(Sender : TObject);
|
|
procedure mnuQuitClicked(Sender : TObject);
|
|
|
|
// edit menu
|
|
procedure mnuEditUndoClicked(Sender: TObject);
|
|
procedure mnuEditRedoClicked(Sender: TObject);
|
|
procedure mnuEditCutClicked(Sender: TObject);
|
|
procedure mnuEditCopyClicked(Sender: TObject);
|
|
procedure mnuEditPasteClicked(Sender: TObject);
|
|
procedure mnuEditIndentBlockClicked(Sender: TObject);
|
|
procedure mnuEditUnindentBlockClicked(Sender: TObject);
|
|
procedure mnuEditUpperCaseBlockClicked(Sender: TObject);
|
|
procedure mnuEditLowerCaseBlockClicked(Sender: TObject);
|
|
procedure mnuEditTabsToSpacesBlockClicked(Sender: TObject);
|
|
procedure mnuEditCompleteCodeClicked(Sender: TObject);
|
|
|
|
// search menu
|
|
procedure mnuSearchFindBlockOtherEnd(Sender: TObject);
|
|
procedure mnuSearchFindBlockStart(Sender: TObject);
|
|
procedure mnuSearchFindDeclaration(Sender: TObject);
|
|
procedure mnuFindDeclarationClicked(Sender : TObject);
|
|
procedure mnuOpenFileAtCursorClicked(Sender : TObject);
|
|
procedure mnuGotoIncludeDirectiveClicked(Sender : TObject);
|
|
|
|
// view menu
|
|
procedure mnuViewInspectorClicked(Sender : TObject);
|
|
procedure mnuViewUnitsClicked(Sender : TObject);
|
|
procedure mnuViewFormsClicked(Sender : TObject);
|
|
procedure mnuViewCodeExplorerClick(Sender : TObject);
|
|
procedure mnuViewMessagesClick(Sender : TObject);
|
|
procedure MessageViewDblClick(Sender : TObject);
|
|
procedure mnuToggleFormUnitClicked(Sender : TObject);
|
|
|
|
// project menu
|
|
procedure mnuNewProjectClicked(Sender : TObject);
|
|
procedure mnuOpenProjectClicked(Sender : TObject);
|
|
procedure mnuSaveProjectClicked(Sender : TObject);
|
|
procedure mnuSaveProjectAsClicked(Sender : TObject);
|
|
procedure mnuAddToProjectClicked(Sender : TObject);
|
|
procedure mnuRemoveFromProjectClicked(Sender : TObject);
|
|
procedure mnuViewProjectSourceClicked(Sender : TObject);
|
|
procedure mnuProjectOptionsClicked(Sender : TObject);
|
|
|
|
// run menu
|
|
procedure mnuBuildProjectClicked(Sender : TObject);
|
|
procedure mnuBuildAllProjectClicked(Sender : TObject);
|
|
procedure mnuRunProjectClicked(Sender : TObject);
|
|
procedure mnuPauseProjectClicked(Sender : TObject);
|
|
procedure mnuStepIntoProjectClicked(Sender : TObject);
|
|
procedure mnuStepOverProjectClicked(Sender : TObject);
|
|
procedure mnuRunToCursorProjectClicked(Sender : TObject);
|
|
procedure mnuStopProjectClicked(Sender : TObject);
|
|
procedure mnuRunParametersClicked(Sender : TObject);
|
|
procedure mnuProjectCompilerSettingsClicked(Sender : TObject);
|
|
|
|
// tools menu
|
|
procedure mnuToolConfigureClicked(Sender : TObject);
|
|
procedure mnuToolSyntaxCheckClicked(Sender : TObject);
|
|
procedure mnuToolGuessUnclosedBlockClicked(Sender : TObject);
|
|
procedure mnuToolGuessMisplacedIFDEFClicked(Sender : TObject);
|
|
procedure mnuToolConvertDFMtoLFMClicked(Sender : TObject);
|
|
procedure mnuToolBuildLazarusClicked(Sender : TObject);
|
|
procedure mnuToolConfigBuildLazClicked(Sender : TObject);
|
|
|
|
// environment menu
|
|
procedure mnuEnvGeneralOptionsClicked(Sender : TObject);
|
|
procedure mnuEnvEditorOptionsClicked(Sender : TObject);
|
|
procedure mnuEnvCodeToolsOptionsClicked(Sender : TObject);
|
|
procedure mnuEnvCodeToolsDefinesEditorClicked(Sender : TObject);
|
|
|
|
// help menu
|
|
procedure mnuHelpAboutLazarusClicked(Sender : TObject);
|
|
|
|
procedure OpenFileDownArrowClicked(Sender : TObject);
|
|
procedure mnuOpenFilePopupClick(Sender : TObject);
|
|
procedure ControlClick(Sender : TObject);
|
|
|
|
// SourceNotebook events
|
|
Procedure OnSrcNoteBookActivated(Sender : TObject);
|
|
Procedure OnSrcNoteBookAddJumpPoint(ACaretXY: TPoint; ATopLine: integer;
|
|
APageIndex: integer; DeleteForwardHistory: boolean);
|
|
Procedure OnSrcNotebookDeleteLastJumPoint(Sender: TObject);
|
|
Procedure OnSrcNotebookEditorVisibleChanged(Sender : TObject);
|
|
|
|
//this is fired when the editor is focused, changed, ?. Anything that causes the status change
|
|
Procedure OnSrcNotebookEditorChanged(Sender : TObject);
|
|
|
|
Procedure OnSrcNotebookFileNew(Sender : TObject);
|
|
Procedure OnSrcNotebookFileOpen(Sender : TObject);
|
|
Procedure OnSrcNotebookFileOpenAtCursor(Sender : TObject);
|
|
Procedure OnSrcNotebookFileSave(Sender : TObject);
|
|
Procedure OnSrcNotebookFileSaveAs(Sender : TObject);
|
|
Procedure OnSrcNotebookFileClose(Sender : TObject);
|
|
Procedure OnSrcNotebookFindDeclaration(Sender : TObject);
|
|
Procedure OnSrcNotebookJumpToHistoryPoint(var NewCaretXY: TPoint;
|
|
var NewTopLine, NewPageIndex: integer; Action: TJumpHistoryAction);
|
|
Procedure OnSrcNotebookProcessCommand(Sender: TObject; Command: integer;
|
|
var Handled: boolean);
|
|
Procedure OnSrcNotebookSaveAll(Sender : TObject);
|
|
procedure OnSrcNoteBookShowUnitInfo(Sender: TObject);
|
|
Procedure OnSrcNotebookToggleFormUnit(Sender : TObject);
|
|
Procedure OnSrcNotebookViewJumpHistory(Sender : TObject);
|
|
|
|
// ObjectInspector + PropertyEditorHook events
|
|
procedure OIOnAddAvailableComponent(AComponent:TComponent;
|
|
var Allowed:boolean);
|
|
procedure OIOnSelectComponent(AComponent:TComponent);
|
|
procedure OnPropHookGetMethods(TypeData:PTypeData; Proc:TGetStringProc);
|
|
function OnPropHookMethodExists(const AMethodName:ShortString;
|
|
TypeData: PTypeData;
|
|
var MethodIsCompatible,MethodIsPublished,IdentIsMethod: boolean):boolean;
|
|
function OnPropHookCreateMethod(const AMethodName:ShortString;
|
|
ATypeInfo:PTypeInfo): TMethod;
|
|
procedure OnPropHookShowMethod(const AMethodName:ShortString);
|
|
procedure OnPropHookRenameMethod(const CurName, NewName:ShortString);
|
|
|
|
// designer events
|
|
procedure OnDesignerGetSelectedComponentClass(Sender: TObject;
|
|
var RegisteredComponent: TRegisteredComponent);
|
|
procedure OnDesignerUnselectComponentClass(Sender: TObject);
|
|
procedure OnDesignerSetDesigning(Sender: TObject; Component: TComponent;
|
|
Value: boolean);
|
|
procedure OnDesignerComponentListChanged(Sender: TObject);
|
|
procedure OnDesignerPropertiesChanged(Sender: TObject);
|
|
procedure OnDesignerAddComponent(Sender: TObject; Component: TComponent;
|
|
ComponentClass: TRegisteredComponent);
|
|
procedure OnDesignerRemoveComponent(Sender: TObject; Component: TComponent);
|
|
procedure OnDesignerModified(Sender: TObject);
|
|
Procedure OnDesignerActivated(Sender : TObject);
|
|
procedure OnDesignerRenameComponent(ADesigner: TDesigner;
|
|
AComponent: TComponent; const NewName: string);
|
|
procedure OnControlSelectionChanged(Sender: TObject);
|
|
|
|
// Environment options dialog events
|
|
procedure OnLoadEnvironmentSettings(Sender: TObject;
|
|
TheEnvironmentOptions: TEnvironmentOptions);
|
|
procedure OnSaveEnvironmentSettings(Sender: TObject;
|
|
TheEnvironmentOptions: TEnvironmentOptions);
|
|
|
|
// CodeToolBoss events
|
|
procedure OnBeforeCodeToolBossApplyChanges(Manager: TCodeToolManager;
|
|
var Abort: boolean);
|
|
procedure OnAfterCodeToolBossApplyChanges(Manager: TCodeToolManager);
|
|
|
|
// MessagesView events
|
|
procedure MessagesViewSelectionChanged(sender : TObject);
|
|
|
|
// Hint Timer events
|
|
Procedure HintTimer1Timer(Sender : TObject);
|
|
|
|
// External Tools events
|
|
procedure OnExtToolNeedsOutputFilter(var OutputFilter: TOutputFilter;
|
|
var Abort: boolean);
|
|
procedure OnExtToolFreeOutputFilter(OutputFilter: TOutputFilter;
|
|
ErrorOccurred: boolean);
|
|
private
|
|
FHintSender : TObject;
|
|
FCodeLastActivated : Boolean; // used for toggling between code and forms
|
|
FLastFormActivated : TCustomForm;// used to find the last form so you can
|
|
// display the correct tab
|
|
FSelectedComponent : TRegisteredComponent;
|
|
MacroList: TTransferMacroList;
|
|
FOpenEditorsOnCodeToolChange: boolean;
|
|
|
|
FRunProcess: TProcess; // temp solution, will be replaced by dummydebugger
|
|
TheCompiler: TCompiler;
|
|
TheOutputFilter: TOutputFilter;
|
|
|
|
procedure SetDefaultsForForm(aForm : TCustomForm);
|
|
|
|
procedure InvalidateAllDesignerForms;
|
|
protected
|
|
procedure ToolButtonClick(Sender : TObject);
|
|
procedure OnApplyWindowLayout(ALayout: TIDEWindowLayout);
|
|
|
|
// methods for start
|
|
procedure LoadGlobalOptions;
|
|
procedure SetupMainMenu;
|
|
procedure SetRecentSubMenu(ParentMenuItem: TMenuItem; FileList: TStringList;
|
|
OnClickEvent: TNotifyEvent);
|
|
procedure SetRecentFilesMenu;
|
|
procedure SetRecentProjectFilesMenu;
|
|
procedure SetupFileMenu; override;
|
|
procedure SetupEditMenu; override;
|
|
procedure SetupSearchMenu; override;
|
|
procedure SetupViewMenu; override;
|
|
procedure SetupProjectMenu; override;
|
|
procedure SetupRunMenu; override;
|
|
procedure SetupToolsMenu; override;
|
|
procedure SetupEnvironmentMenu; override;
|
|
procedure SetupHelpMenu; override;
|
|
procedure LoadMenuShortCuts; override;
|
|
procedure ConnectMainBarEvents;
|
|
procedure SetupSpeedButtons;
|
|
procedure SetupComponentNoteBook;
|
|
procedure SetupComponentTabs;
|
|
procedure SetupHints;
|
|
procedure SetupOutputFilter;
|
|
procedure SetupObjectInspector;
|
|
procedure SetupCompilerInterface;
|
|
procedure SetupFormEditor;
|
|
procedure SetupSourceNotebook;
|
|
procedure SetupTransferMacros;
|
|
procedure SetupControlSelection;
|
|
procedure SetupStartProject;
|
|
|
|
// method for 'new unit'
|
|
function CreateNewCodeBuffer(NewUnitType:TNewUnitType;
|
|
NewFilename: string; var NewCodeBuffer: TCodeBuffer;
|
|
var NewUnitName: string): TModalResult;
|
|
function CreateNewForm(NewUnitInfo: TUnitInfo): TModalResult;
|
|
procedure ShowDesignForm(AForm: TCustomForm);
|
|
|
|
// methods for 'save unit'
|
|
function DoLoadResourceFile(AnUnitInfo: TUnitInfo;
|
|
var LFMCode, ResourceCode: TCodeBuffer;
|
|
IgnoreSourceErrors: boolean): TModalResult;
|
|
function DoShowSaveFileAsDialog(AnUnitInfo: TUnitInfo;
|
|
var ResourceCode: TCodeBuffer): TModalResult;
|
|
function DoSaveFileResources(AnUnitInfo: TUnitInfo;
|
|
ResourceCode, LFMCode: TCodeBuffer; Flags: TSaveFlags): TModalResult;
|
|
|
|
// methods for 'open unit' and 'open main unit'
|
|
function DoOpenNotExistingFile(const AFileName:string;
|
|
Flags: TOpenFlags): TModalResult;
|
|
function DoOpenUnknownFile(const AFileName:string; Flags: TOpenFlags;
|
|
var NewUnitInfo: TUnitInfo; var Handled: boolean): TModalResult;
|
|
procedure DoRestoreBookMarks(AnUnitInfo: TUnitInfo; ASrcEdit:TSourceEditor);
|
|
function DoOpenFileInSourceNotebook(AnUnitInfo: TUnitInfo;
|
|
PageIndex: integer; Flags: TOpenFlags): TModalResult;
|
|
function DoLoadLFM(AnUnitInfo: TUnitInfo; Flags: TOpenFlags): TModalResult;
|
|
|
|
// methods for 'close unit'
|
|
function CloseDesignerForm(AnUnitInfo: TUnitInfo): TModalResult;
|
|
|
|
// methods for 'save project'
|
|
procedure GetMainUnit(var MainUnitInfo: TUnitInfo;
|
|
var MainUnitSrcEdit: TSourceEditor; UpdateModified: boolean);
|
|
procedure SaveSourceEditorProjectSpecificSettings;
|
|
function DoShowSaveProjectAsDialog: TModalResult;
|
|
|
|
// methods for open project, create project from source
|
|
function DoCompleteLoadingProjectInfo: TModalResult;
|
|
|
|
public
|
|
class procedure ParseCmdLineOptions;
|
|
|
|
constructor Create(TheOwner: TComponent); override;
|
|
destructor Destroy; override;
|
|
|
|
// files/units
|
|
function DoNewEditorFile(NewUnitType:TNewUnitType;
|
|
NewFilename: string):TModalResult;
|
|
function DoSaveEditorFile(PageIndex:integer;
|
|
Flags: TSaveFlags): TModalResult;
|
|
function DoCloseEditorFile(PageIndex:integer;
|
|
Flags: TCloseFlags):TModalResult;
|
|
function DoOpenEditorFile(AFileName:string; PageIndex: integer;
|
|
Flags: TOpenFlags): TModalResult; override;
|
|
function DoOpenFileAtCursor(Sender: TObject): TModalResult;
|
|
function DoSaveAll: TModalResult;
|
|
function DoOpenMainUnit(ProjectLoading: boolean): TModalResult;
|
|
function DoRevertMainUnit: TModalResult;
|
|
function DoViewUnitsAndForms(OnlyForms: boolean): TModalResult;
|
|
|
|
// project(s)
|
|
function DoNewProject(NewProjectType:TProjectType):TModalResult;
|
|
function DoSaveProject(Flags: TSaveFlags):TModalResult;
|
|
function DoCloseProject:TModalResult;
|
|
function DoOpenProjectFile(AFileName:string):TModalResult;
|
|
function DoAddActiveUnitToProject: TModalResult;
|
|
function DoRemoveFromProjectDialog: TModalResult;
|
|
function DoBuildProject(BuildAll: boolean): TModalResult;
|
|
function DoInitProjectRun: TModalResult; override;
|
|
function DoRunProject: TModalResult;
|
|
function SomethingOfProjectIsModified: boolean;
|
|
function DoCreateProjectForProgram(ProgramBuf: TCodeBuffer): TModalResult;
|
|
function DoSaveProjectToTestDirectory: TModalResult;
|
|
|
|
// edit menu
|
|
procedure DoEditMenuCommand(EditorCommand: integer);
|
|
|
|
// tools
|
|
function DoConvertDFMtoLFM: TModalResult;
|
|
|
|
// external tools
|
|
function DoRunExternalTool(Index: integer): TModalResult;
|
|
function DoBuildLazarus: TModalResult;
|
|
|
|
// useful information methods
|
|
procedure GetCurrentUnit(var ActiveSourceEditor:TSourceEditor;
|
|
var ActiveUnitInfo:TUnitInfo); override;
|
|
procedure GetUnitWithPageIndex(PageIndex:integer;
|
|
var ActiveSourceEditor:TSourceEditor; var ActiveUnitInfo:TUnitInfo);
|
|
function GetSourceEditorForUnitInfo(AnUnitInfo: TUnitInfo): TSourceEditor;
|
|
procedure UpdateDefaultPascalFileExtensions;
|
|
function CreateSrcEditPageName(const AnUnitName, AFilename: string;
|
|
IgnorePageIndex: integer): string;
|
|
|
|
// useful file methods
|
|
function FindUnitFile(const AFilename: string): string; override;
|
|
function DoSaveStreamToFile(AStream:TStream; const Filename:string;
|
|
IsPartOfProject:boolean): TModalResult;
|
|
function DoLoadMemoryStreamFromFile(MemStream: TMemoryStream;
|
|
const AFilename:string): TModalResult;
|
|
function DoSaveCodeBufferToFile(ABuffer: TCodeBuffer;
|
|
const AFilename: string; IsPartOfProject:boolean): TModalResult;
|
|
function DoLoadCodeBuffer(var ACodeBuffer: TCodeBuffer;
|
|
const AFilename: string; Flags: TLoadBufferFlags): TModalResult;
|
|
function DoBackupFile(const Filename:string;
|
|
IsPartOfProject:boolean): TModalResult;
|
|
function DoCheckFilesOnDisk: TModalResult; override;
|
|
|
|
// useful frontend methods
|
|
procedure DoSwitchToFormSrc(var ActiveSourceEditor:TSourceEditor;
|
|
var ActiveUnitInfo:TUnitInfo);
|
|
procedure UpdateCaption;
|
|
function DoConvertDFMFileToLFMFile(const DFMFilename: string): TModalResult;
|
|
|
|
// methods for codetools
|
|
procedure InitCodeToolBoss;
|
|
function BeginCodeTool(var ActiveSrcEdit: TSourceEditor;
|
|
var ActiveUnitInfo: TUnitInfo; SwitchToFormSrc: boolean): boolean;
|
|
function DoJumpToCodePos(ActiveSrcEdit: TSourceEditor;
|
|
ActiveUnitInfo: TUnitInfo;
|
|
NewSource: TCodeBuffer; NewX, NewY, NewTopLine: integer;
|
|
AddJumpPoint: boolean): TModalResult;
|
|
procedure DoJumpToCodeToolBossError;
|
|
procedure UpdateSourceNames;
|
|
procedure SaveSourceEditorChangesToCodeCache(PageIndex: integer);
|
|
procedure ApplyCodeToolChanges;
|
|
procedure DoJumpToProcedureSection;
|
|
procedure DoFindDeclarationAtCursor;
|
|
procedure DoCompleteCodeAtCursor;
|
|
function DoCheckSyntax: TModalResult;
|
|
procedure DoGoToPascalBlockOtherEnd;
|
|
procedure DoGoToPascalBlockStart;
|
|
procedure DoJumpToGuessedUnclosedBlock(FindNext: boolean);
|
|
procedure DoJumpToGuessedMisplacedIFDEF(FindNext: boolean);
|
|
procedure DoGotoIncludeDirective;
|
|
procedure SaveIncludeLinks;
|
|
|
|
// methods for debugging, compiling and external tools
|
|
function DoJumpToCompilerMessage(Index:integer;
|
|
FocusEditor: boolean): boolean;
|
|
procedure DoShowMessagesView;
|
|
procedure DoArrangeSourceEditorAndMessageView;
|
|
function GetProjectTargetFilename: string;
|
|
function GetTestProjectFilename: string;
|
|
function GetTestUnitFilename(AnUnitInfo: TUnitInfo): string; override;
|
|
function GetRunCommandLine: string; override;
|
|
procedure OnMacroSubstitution(TheMacro: TTransferMacro; var s:string;
|
|
var Handled, Abort: boolean);
|
|
function OnMacroPromptFunction(const s:string; var Abort: boolean):string;
|
|
procedure OnCmdLineCreate(var CmdLine: string; var Abort:boolean);
|
|
|
|
// form editor and designer
|
|
property SelectedComponent : TRegisteredComponent
|
|
read FSelectedComponent write FSelectedComponent;
|
|
procedure DoBringToFrontFormOrUnit;
|
|
procedure SetDesigning(Control : TComponent; Value : Boolean);
|
|
|
|
// editor and environment options
|
|
procedure SaveEnvironment;
|
|
procedure LoadDesktopSettings(TheEnvironmentOptions: TEnvironmentOptions);
|
|
procedure SaveDesktopSettings(TheEnvironmentOptions: TEnvironmentOptions);
|
|
end;
|
|
|
|
|
|
const
|
|
CodeToolsIncludeLinkFile = 'includelinks.xml';
|
|
|
|
|
|
implementation
|
|
|
|
uses
|
|
ViewUnit_dlg, Math, LResources, aboutfrm;
|
|
|
|
//==============================================================================
|
|
{
|
|
This function creates a LFM file from any form.
|
|
To create the resource file use the program lazres or the
|
|
LFMtoLFCfile function.
|
|
}
|
|
function CreateLFM(AForm:TCustomForm):integer;
|
|
// 0 = ok
|
|
// -1 = error while streaming AForm to binary stream
|
|
// -2 = error while streaming binary stream to text file
|
|
var BinStream,TxtMemStream:TMemoryStream;
|
|
Driver: TAbstractObjectWriter;
|
|
Writer:TWriter;
|
|
TxtFileStream:TFileStream;
|
|
begin
|
|
Result:=0;
|
|
BinStream:=TMemoryStream.Create;
|
|
try
|
|
try
|
|
Driver:=TBinaryObjectWriter.Create(BinStream,4096);
|
|
try
|
|
Writer:=TWriter.Create(Driver);
|
|
try
|
|
Writer.WriteDescendent(AForm,nil);
|
|
finally
|
|
Writer.Free;
|
|
end;
|
|
finally
|
|
Driver.Free;
|
|
end;
|
|
except
|
|
Result:=-1;
|
|
exit;
|
|
end;
|
|
try
|
|
// transform binary to text and save LFM file
|
|
TxtMemStream:=TMemoryStream.Create;
|
|
TxtFileStream:=TFileStream.Create(lowercase(AForm.ClassName)+'.lfm'
|
|
,fmCreate);
|
|
try
|
|
BinStream.Position:=0;
|
|
ObjectBinaryToText(BinStream,TxtMemStream);
|
|
TxtMemStream.Position:=0;
|
|
TxtFileStream.CopyFrom(TxtMemStream,TxtMemStream.Size);
|
|
finally
|
|
TxtMemStream.Free;
|
|
TxtFileStream.Free;
|
|
end;
|
|
except
|
|
Result:=-2;
|
|
exit;
|
|
end;
|
|
finally
|
|
BinStream.Free;
|
|
end;
|
|
end;
|
|
|
|
function LoadPixmapRes(const ResourceName:string; PixMap:TPixMap):boolean;
|
|
var
|
|
ms:TMemoryStream;
|
|
res:TLResource;
|
|
begin
|
|
Result:=false;
|
|
res:=LazarusResources.Find(ResourceName);
|
|
if (res<>nil) and (res.Value<>'') and (res.ValueType='XPM') then begin
|
|
ms:=TMemoryStream.Create;
|
|
try
|
|
ms.Write(res.Value[1],length(res.Value));
|
|
ms.Position:=0;
|
|
Pixmap.LoadFromStream(ms);
|
|
Result:=true;
|
|
finally
|
|
ms.Free;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
function LoadSpeedBtnPixMap(const ResourceName:string):TPixmap;
|
|
begin
|
|
Result:=TPixmap.Create;
|
|
Result.TransparentColor:=clBtnFace;
|
|
if not LoadPixmapRes(ResourceName,Result) then
|
|
LoadPixmapRes('default',Result);
|
|
end;
|
|
|
|
|
|
//==============================================================================
|
|
|
|
|
|
{ TMainIDE }
|
|
|
|
{-------------------------------------------------------------------------------
|
|
procedure TMainIDE.ParseCmdLineOptions;
|
|
|
|
Parses the command line for the IDE.
|
|
-------------------------------------------------------------------------------}
|
|
procedure TMainIDE.ParseCmdLineOptions;
|
|
const
|
|
PrimaryConfPathOpt='--primary-config-path=';
|
|
SecondaryConfPathOpt='--secondary-config-path=';
|
|
var i: integer;
|
|
begin
|
|
if (ParamCount>0)
|
|
and ((AnsiCompareText(ParamStr(1),'--help')=0)
|
|
or (AnsiCompareText(ParamStr(1),'-help')=0)
|
|
or (AnsiCompareText(ParamStr(1),'-?')=0)) then
|
|
begin
|
|
writeln(lisCmdLineHlpHeader);
|
|
writeln(Format(lisCmdLinePrimaryConfigPathDesc,[GetPrimaryConfigPath]));
|
|
writeln(Format(lisCmdLineSecondaryConfigPathDesc,[GetSecondaryConfigPath]));
|
|
writeln('');
|
|
writeln(lisCmdLineLCLInterfaceSpecificOptions);
|
|
writeln('');
|
|
writeln(GetCmdLineParamDescForInterface);
|
|
Application.Terminate;
|
|
Halt;
|
|
end;
|
|
for i:=1 to ParamCount do begin
|
|
if AnsiCompareText(LeftStr(ParamStr(i),length(PrimaryConfPathOpt)),
|
|
PrimaryConfPathOpt)=0 then
|
|
begin
|
|
SetPrimaryConfigPath(copy(ParamStr(i),length(PrimaryConfPathOpt)+1,
|
|
length(ParamStr(i))));
|
|
end;
|
|
if AnsiCompareText(LeftStr(ParamStr(i),length(SecondaryConfPathOpt)),
|
|
SecondaryConfPathOpt)=0 then
|
|
begin
|
|
SetSecondaryConfigPath(copy(ParamStr(i),length(SecondaryConfPathOpt)+1,
|
|
length(ParamStr(i))));
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
procedure TMainIDE.LoadGlobalOptions;
|
|
// load environment, miscellaneous, editor and codetools options
|
|
begin
|
|
EnvironmentOptions:=TEnvironmentOptions.Create;
|
|
with EnvironmentOptions do begin
|
|
SetLazarusDefaultFilename;
|
|
Load(false);
|
|
TranslateResourceStrings(ExtractFilePath(ExpandFilename(ParamStr(0))),
|
|
LazarusLanguageIDs[EnvironmentOptions.Language]);
|
|
|
|
if EnvironmentOptions.CompilerFilename='' then
|
|
EnvironmentOptions.CompilerFilename:=FindDefaultCompilerPath;
|
|
ExternalTools.OnNeedsOutputFilter:=@OnExtToolNeedsOutputFilter;
|
|
ExternalTools.OnFreeOutputFilter:=@OnExtToolFreeOutputFilter;
|
|
OnApplyWindowLayout:=@Self.OnApplyWindowLayout;
|
|
end;
|
|
UpdateDefaultPascalFileExtensions;
|
|
|
|
EditorOpts:=TEditorOptions.Create;
|
|
EditorOpts.Load;
|
|
|
|
EnvironmentOptions.ExternalTools.LoadShortCuts(EditorOpts.KeyMap);
|
|
|
|
MiscellaneousOptions:=TMiscellaneousOptions.Create;
|
|
MiscellaneousOptions.Load;
|
|
|
|
CodeToolsOpts:=TCodeToolsOptions.Create;
|
|
with CodeToolsOpts do begin
|
|
SetLazarusDefaultFilename;
|
|
Load;
|
|
end;
|
|
|
|
InputHistories:=TInputHistories.Create;
|
|
with InputHistories do begin
|
|
SetLazarusDefaultFilename;
|
|
Load;
|
|
end;
|
|
end;
|
|
|
|
constructor TMainIDE.Create(TheOwner: TComponent);
|
|
begin
|
|
// The MainIDE variable is assigned via
|
|
// Application.CreateForm(TMainIDE,MainIDE) _after_ the creation of the form.
|
|
// But some IDE parts needs the variable already during creation, so it is set
|
|
// here.
|
|
MainIDE:=Self;
|
|
|
|
inherited Create(TheOwner);
|
|
|
|
// load options
|
|
CreatePrimaryConfigPath;
|
|
LoadGlobalOptions;
|
|
|
|
// set the IDE mode to none (= editing mode)
|
|
ToolStatus:=itNone;
|
|
|
|
// setup the code tools
|
|
InitCodeToolBoss;
|
|
|
|
// build and position the MainIDE form
|
|
Name := DefaultMainIDEName;
|
|
EnvironmentOptions.IDEWindowLayoutList.Apply(TForm(Self),DefaultMainIDEName);
|
|
|
|
if LazarusResources.Find(ClassName)=nil then begin
|
|
SetupMainMenu;
|
|
SetupSpeedButtons;
|
|
SetupComponentNoteBook;
|
|
ConnectMainBarEvents;
|
|
SetupHints;
|
|
end;
|
|
|
|
DebugBoss:=TDebugManager.Create(Self);
|
|
DebugBoss.ConnectMainBarEvents;
|
|
|
|
LoadMenuShortCuts;
|
|
SetupComponentTabs;
|
|
SetupOutputFilter;
|
|
SetupCompilerInterface;
|
|
SetupObjectInspector;
|
|
SetupFormEditor;
|
|
SetupSourceNotebook;
|
|
SetupTransferMacros;
|
|
SetupControlSelection;
|
|
|
|
SetupStartProject;
|
|
end;
|
|
|
|
destructor TMainIDE.Destroy;
|
|
begin
|
|
writeln('[TMainIDE.Destroy] A');
|
|
{$IFDEF IDE_MEM_CHECK}CheckHeap(IntToStr(GetMem_Cnt));{$ENDIF}
|
|
if DebugBoss<>nil then DebugBoss.EndDebugging;
|
|
|
|
FreeThenNil(Project1);
|
|
if TheControlSelection<>nil then begin
|
|
TheControlSelection.OnChange:=nil;
|
|
FreeThenNil(TheControlSelection);
|
|
end;
|
|
FreeThenNil(FormEditor1);
|
|
FreeThenNil(PropertyEditorHook1);
|
|
FreeThenNil(TheCompiler);
|
|
FreeThenNil(TheOutputFilter);
|
|
FreeThenNil(MacroList);
|
|
FreeThenNil(CodeToolsOpts);
|
|
FreeThenNil(MiscellaneousOptions);
|
|
FreeThenNil(EditorOpts);
|
|
FreeThenNil(EnvironmentOptions);
|
|
FreeThenNil(InputHistories);
|
|
FreeThenNil(HintTimer1);
|
|
FreeThenNil(HintWindow1);
|
|
|
|
//writeln('[TMainIDE.Destroy] B -> inherited Destroy...');
|
|
{$IFDEF IDE_MEM_CHECK}CheckHeap(IntToStr(GetMem_Cnt));{$ENDIF}
|
|
inherited Destroy;
|
|
{$IFDEF IDE_MEM_CHECK}CheckHeap(IntToStr(GetMem_Cnt));{$ENDIF}
|
|
//writeln('[TMainIDE.Destroy] END');
|
|
end;
|
|
|
|
procedure TMainIDE.OIOnAddAvailableComponent(AComponent:TComponent;
|
|
var Allowed:boolean);
|
|
begin
|
|
//Allowed:=(not (AComponent is TGrabber));
|
|
end;
|
|
|
|
procedure TMainIDE.OIOnSelectComponent(AComponent:TComponent);
|
|
begin
|
|
with TheControlSelection do begin
|
|
BeginUpdate;
|
|
Clear;
|
|
Add(AComponent);
|
|
EndUpdate;
|
|
end;
|
|
if AComponent.Owner is TControl then
|
|
TControl(AComponent.Owner).Invalidate;
|
|
end;
|
|
|
|
procedure TMainIDE.OnPropHookGetMethods(TypeData:PTypeData;
|
|
Proc:TGetStringProc);
|
|
var ActiveSrcEdit: TSourceEditor;
|
|
ActiveUnitInfo: TUnitInfo;
|
|
begin
|
|
if not BeginCodeTool(ActiveSrcEdit,ActiveUnitInfo,true) then exit;
|
|
{$IFDEF IDE_DEBUG}
|
|
writeln('');
|
|
writeln('[TMainIDE.OnPropHookGetMethods] ************');
|
|
{$ENDIF}
|
|
if not CodeToolBoss.GetCompatiblePublishedMethods(ActiveUnitInfo.Source,
|
|
ActiveUnitInfo.Form.ClassName,TypeData,Proc) then
|
|
begin
|
|
DoJumpToCodeToolBossError;
|
|
end;
|
|
end;
|
|
|
|
Procedure TMainIDE.ToolButtonClick(Sender : TObject);
|
|
Begin
|
|
Assert(False, 'Trace:TOOL BUTTON CLICK!');
|
|
|
|
end;
|
|
|
|
{------------------------------------------------------------------------------}
|
|
procedure TMainIDE.FormClose(Sender : TObject; var Action: TCloseAction);
|
|
begin
|
|
SaveEnvironment;
|
|
SaveIncludeLinks;
|
|
InputHistories.Save;
|
|
if TheControlSelection<>nil then TheControlSelection.Clear;
|
|
if SourceNoteBook<>nil then SourceNoteBook.ClearUnUsedEditorComponents(true);
|
|
end;
|
|
|
|
procedure TMainIDE.FormCloseQuery(Sender : TObject; var CanClose: boolean);
|
|
Begin
|
|
writeln('[TMainIDE.FormCloseQuery]');
|
|
CanClose:=true;
|
|
|
|
if SomethingOfProjectIsModified then begin
|
|
if (MessageDlg(lisProjectChanged,lisSaveChangesToProject,
|
|
mtConfirmation,[mbYes,mbNo],0)=mrYes) then
|
|
begin
|
|
CanClose:=DoSaveProject([])<>mrAbort;
|
|
if CanClose=false then exit;
|
|
end;
|
|
end;
|
|
|
|
CanClose:=(DoCloseProject<>mrAbort);
|
|
End;
|
|
|
|
{------------------------------------------------------------------------------}
|
|
type
|
|
TMoveFlags = set of (mfTop, mfLeft);
|
|
|
|
procedure TMainIDE.SetupSpeedButtons;
|
|
|
|
function CreateButton(const AName, APixName: String; ANumGlyphs: Integer;
|
|
var ALeft, ATop: Integer; const AMoveFlags: TMoveFlags;
|
|
const AOnClick: TNotifyEvent; AHint : String): TSpeedButton;
|
|
begin
|
|
Result := TSpeedButton.Create(Self);
|
|
with Result do
|
|
begin
|
|
Name := AName;
|
|
Parent := pnlSpeedButtons;
|
|
Enabled := True;
|
|
Top := ATop;
|
|
Left := ALeft;
|
|
OnClick := AOnClick;
|
|
Glyph := LoadSpeedBtnPixMap(APixName);
|
|
NumGlyphs := ANumGlyphs;
|
|
Flat := True;
|
|
//Transparent:=True;
|
|
if mfTop in AMoveFlags then Inc(ATop, Height);
|
|
if mfLeft in AMoveFlags then Inc(ALeft, Width);
|
|
Hint := AHint;
|
|
OnMouseMove := @MainMouseMoved;
|
|
Visible := True;
|
|
end;
|
|
end;
|
|
var
|
|
ButtonTop, ButtonLeft, n: Integer;
|
|
|
|
begin
|
|
|
|
pnlSpeedButtons := TPanel.Create(Self);
|
|
with pnlSpeedButtons do begin
|
|
Name := 'pnlSpeedButtons';
|
|
Parent:= Self;
|
|
Top := 0;
|
|
Left:= 0;
|
|
Caption:= '';
|
|
BevelWidth:=1;
|
|
BevelOuter:=bvRaised;
|
|
Visible := True;
|
|
end;
|
|
|
|
|
|
ButtonTop := 1;
|
|
ButtonLeft := 1;
|
|
NewUnitSpeedBtn := CreateButton('NewUnitSpeedBtn' , 'btn_newunit' , 1, ButtonLeft, ButtonTop, [mfLeft], @mnuNewUnitClicked, lsiHintNewUnit);
|
|
|
|
OpenFileSpeedBtn := CreateButton('OpenFileSpeedBtn' , 'btn_openfile' , 1, ButtonLeft, ButtonTop, [mfLeft], @mnuOpenClicked, lsiHintOpen);
|
|
|
|
// store left
|
|
n := ButtonLeft;
|
|
OpenFileArrowSpeedBtn := CreateButton('OpenFileArrowSpeedBtn', 'btn_downarrow' , 1, ButtonLeft, ButtonTop, [mfLeft], @OpenFileDownArrowClicked, '');
|
|
OpenFileArrowSpeedBtn.Width := 12;
|
|
ButtonLeft := n+12+1;
|
|
|
|
SaveSpeedBtn := CreateButton('SaveSpeedBtn' , 'btn_save' , 2, ButtonLeft, ButtonTop, [mfLeft], @mnuSaveClicked, lsiHintSave);
|
|
SaveAllSpeedBtn := CreateButton('SaveAllSpeedBtn' , 'btn_saveall' , 1, ButtonLeft, ButtonTop, [mfLeft], @mnuSaveAllClicked, lsiHintSaveAll);
|
|
NewFormSpeedBtn := CreateButton('NewFormSpeedBtn' , 'btn_newform' , 1, ButtonLeft, ButtonTop, [mfLeft], @mnuNewFormClicked, lsiHintNewForm);
|
|
ToggleFormSpeedBtn := CreateButton('ToggleFormSpeedBtn' , 'btn_toggleform', 2, ButtonLeft, ButtonTop, [mfLeft, mfTop], @mnuToggleFormUnitCLicked, lsiHintToggleFormUnit);
|
|
|
|
// new row
|
|
ButtonLeft := 1;
|
|
ViewUnitsSpeedBtn := CreateButton('ViewUnitsSpeedBtn' , 'btn_viewunits' , 1, ButtonLeft, ButtonTop, [mfLeft], @mnuViewUnitsClicked, lsiHintViewUnits);
|
|
ViewFormsSpeedBtn := CreateButton('ViewFormsSpeedBtn' , 'btn_viewforms' , 1, ButtonLeft, ButtonTop, [mfLeft], @mnuViewFormsClicked, lsiHintViewForms);
|
|
inc(ButtonLeft,13);
|
|
RunSpeedButton := CreateButton('RunSpeedButton' , 'btn_run' , 2, ButtonLeft, ButtonTop, [mfLeft], @mnuRunProjectClicked, lsiHintRun);
|
|
PauseSpeedButton := CreateButton('PauseSpeedButton' , 'btn_pause' , 2, ButtonLeft, ButtonTop, [mfLeft], @mnuPauseProjectClicked, lsiHintPause);
|
|
PauseSpeedButton.Enabled:=false;
|
|
StepIntoSpeedButton := CreateButton('StepIntoSpeedButton' , 'btn_stepinto' , 1, ButtonLeft, ButtonTop, [mfLeft], @mnuStepIntoProjectClicked, lsiHintStepInto);
|
|
StepOverSpeedButton := CreateButton('StepOverpeedButton' , 'btn_stepover' , 1, ButtonLeft, ButtonTop, [mfLeft, mfTop], @mnuStepOverProjectClicked, lsiHintStepOver);
|
|
|
|
pnlSpeedButtons.Width := ButtonLeft+3;
|
|
pnlSpeedButtons.Height := ButtonTop+3;
|
|
|
|
|
|
// create the popupmenu for the OpenFileArrowSpeedBtn
|
|
OpenFilePopUpMenu := TPopupMenu.Create(self);
|
|
OpenFilePopupMenu.Name:='OpenFilePopupMenu';
|
|
OpenFilePopupMenu.AutoPopup := False;
|
|
{
|
|
MenuItem := TMenuItem.Create(Self);
|
|
MenuItem.Caption := 'No files have been opened';
|
|
MenuItem.OnClick := nil;
|
|
OpenFilePopupMenu.Items.Add(MenuItem);
|
|
}
|
|
end;
|
|
|
|
procedure TMainIDE.SetupComponentNoteBook;
|
|
begin
|
|
// Component Notebook
|
|
ComponentNotebook := TNotebook.Create(Self);
|
|
with ComponentNotebook do begin
|
|
Parent := Self;
|
|
Name := 'ComponentNotebook';
|
|
Left := ToggleFormSpeedBtn.Left + ToggleFormSpeedBtn.Width + 2;
|
|
Top := 0;
|
|
Width := Self.ClientWidth - Left;
|
|
Height := 60; //Self.ClientHeight - ComponentNotebook.Top;
|
|
OnMouseMove := @MainMouseMoved;
|
|
end;
|
|
end;
|
|
|
|
procedure TMainIDE.SetupComponentTabs;
|
|
var
|
|
PageCount, I, X: integer;
|
|
RegComp : TRegisteredComponent;
|
|
RegCompPage : TRegisteredComponentPage;
|
|
IDEComponent: TIdeComponent;
|
|
SelectionPointerPixmap: TPixmap;
|
|
begin
|
|
PageCount := 0;
|
|
for I := 0 to RegCompList.PageCount-1 do begin
|
|
// Component Notebook Pages
|
|
RegCompPage := RegCompList.Pages[i];
|
|
if RegCompPage.Name <> '' then
|
|
Begin
|
|
if (PageCount = 0) then
|
|
ComponentNotebook.Pages.Strings[PageCount] := RegCompPage.Name
|
|
else
|
|
ComponentNotebook.Pages.Add(RegCompPage.Name);
|
|
GlobalMouseSpeedButton := TSpeedButton.Create(Self);
|
|
SelectionPointerPixmap:=LoadSpeedBtnPixMap('tmouse');
|
|
with GlobalMouseSpeedButton do
|
|
begin
|
|
Parent := ComponentNotebook.Page[PageCount];
|
|
Parent.OnMouseMove := @MainMouseMoved; //this is for the hints
|
|
Enabled := True;
|
|
Width := 26;
|
|
Height := 26;
|
|
OnClick := @ControlClick;
|
|
Glyph := SelectionPointerPixmap;
|
|
Visible := True;
|
|
Flat := True;
|
|
GroupIndex:= 1;
|
|
Down := True;
|
|
Name := 'GlobalMouseSpeedButton'+IntToStr(PageCount);
|
|
Hint := lisSelectionTool;
|
|
OnMouseMove := @MainMouseMoved;
|
|
end;
|
|
for x := 0 to RegCompPage.Count-1 do //for every component on the page....
|
|
begin
|
|
RegComp := RegCompPage.Items[x];
|
|
IDEComponent := TIDEComponent.Create;
|
|
IDEComponent.RegisteredComponent := RegComp;
|
|
IDEComponent._SpeedButton(Self,ComponentNotebook.Page[PageCount]);
|
|
IDEComponent.SpeedButton.OnClick := @ControlClick;
|
|
IDEComponent.SpeedButton.OnMouseMove := @MainMouseMoved;
|
|
IDEComponent.SpeedButton.Hint := RegComp.ComponentClass.ClassName;
|
|
IDEComponent.SpeedButton.Name := IDEComponent.SpeedButton.Hint;
|
|
IDEComponent.SpeedButton.ShowHint := True;
|
|
IDEComponent.SpeedButton.GroupIndex := 1;
|
|
IDECompList.Add(IDEComponent);
|
|
end;
|
|
inc(PageCount);
|
|
end;
|
|
end;
|
|
ComponentNotebook.PageIndex := 0; // Set it to the first page
|
|
ComponentNotebook.OnPageChanged := @ControlClick;
|
|
ComponentNotebook.Show;
|
|
end;
|
|
|
|
procedure TMainIDE.SetupHints;
|
|
begin
|
|
HintTimer1 := TTimer.Create(self);
|
|
with HintTimer1 do
|
|
Begin
|
|
Name:='HintTimer1';
|
|
Enabled := False;
|
|
Interval := 500;
|
|
OnTimer := @HintTimer1Timer;
|
|
end;
|
|
|
|
HintWindow1 := THintWindow.Create(nil);
|
|
HIntWindow1.Visible := False;
|
|
HintWindow1.Caption := '';
|
|
HintWindow1.AutoHide := False;
|
|
end;
|
|
|
|
procedure TMainIDE.SetupOutputFilter;
|
|
begin
|
|
TheOutputFilter:=TOutputFilter.Create;
|
|
TheOutputFilter.OnGetIncludePath:=@CodeToolBoss.GetIncludePathForDirectory;
|
|
end;
|
|
|
|
procedure TMainIDE.SetupObjectInspector;
|
|
begin
|
|
ObjectInspector1 := TObjectInspector.Create(Self);
|
|
ObjectInspector1.OnAddAvailComponent:=@OIOnAddAvailableComponent;
|
|
ObjectInspector1.OnSelectComponentInOI:=@OIOnSelectComponent;
|
|
PropertyEditorHook1:=TPropertyEditorHook.Create;
|
|
PropertyEditorHook1.OnGetMethods:=@OnPropHookGetMethods;
|
|
PropertyEditorHook1.OnMethodExists:=@OnPropHookMethodExists;
|
|
PropertyEditorHook1.OnCreateMethod:=@OnPropHookCreateMethod;
|
|
PropertyEditorHook1.OnShowMethod:=@OnPropHookShowMethod;
|
|
PropertyEditorHook1.OnRenameMethod:=@OnPropHookRenameMethod;
|
|
ObjectInspector1.PropertyEditorHook:=PropertyEditorHook1;
|
|
EnvironmentOptions.IDEWindowLayoutList.Apply(TForm(ObjectInspector1),
|
|
DefaultObjectInspectorName);
|
|
with EnvironmentOptions do begin
|
|
ObjectInspectorOptions.AssignTo(ObjectInspector1);
|
|
end;
|
|
end;
|
|
|
|
procedure TMainIDE.SetupCompilerInterface;
|
|
begin
|
|
TheCompiler := TCompiler.Create;
|
|
with TheCompiler do begin
|
|
OnCommandLineCreate:=@OnCmdLineCreate;
|
|
OutputFilter:=TheOutputFilter;
|
|
end;
|
|
end;
|
|
|
|
procedure TMainIDE.SetupFormEditor;
|
|
begin
|
|
FormEditor1 := TFormEditor.Create;
|
|
FormEditor1.Obj_Inspector := ObjectInspector1;
|
|
end;
|
|
|
|
procedure TMainIDE.SetupSourceNotebook;
|
|
begin
|
|
SourceNotebook := TSourceNotebook.Create(Self);
|
|
SourceNotebook.OnActivate := @OnSrcNoteBookActivated;
|
|
SourceNotebook.OnAddJumpPoint := @OnSrcNoteBookAddJumpPoint;
|
|
SourceNotebook.OnCloseClicked := @OnSrcNotebookFileClose;
|
|
SourceNotebook.OnDeleteLastJumpPoint := @OnSrcNotebookDeleteLastJumPoint;
|
|
SourceNotebook.OnEditorVisibleChanged := @OnSrcNotebookEditorVisibleChanged;
|
|
SourceNotebook.OnEditorChanged := @OnSrcNotebookEditorChanged;
|
|
SourceNotebook.OnEditorPropertiesClicked := @mnuEnvEditorOptionsClicked;
|
|
SourceNotebook.OnFindDeclarationClicked := @OnSrcNotebookFindDeclaration;
|
|
SourceNotebook.OnJumpToHistoryPoint := @OnSrcNotebookJumpToHistoryPoint;
|
|
SourceNotebook.OnNewClicked := @OnSrcNotebookFileNew;
|
|
SourceNotebook.OnOpenClicked := @OnSrcNotebookFileOpen;
|
|
SourceNotebook.OnOpenFileAtCursorClicked := @OnSrcNotebookFileOpenAtCursor;
|
|
SourceNotebook.OnProcessUserCommand := @OnSrcNotebookProcessCommand;
|
|
SourceNotebook.OnSaveClicked := @OnSrcNotebookFileSave;
|
|
SourceNotebook.OnSaveAsClicked := @OnSrcNotebookFileSaveAs;
|
|
SourceNotebook.OnSaveAllClicked := @OnSrcNotebookSaveAll;
|
|
SourceNotebook.OnShowUnitInfo := @OnSrcNoteBookShowUnitInfo;
|
|
SourceNotebook.OnToggleFormUnitClicked := @OnSrcNotebookToggleFormUnit;
|
|
SourceNotebook.OnViewJumpHistory := @OnSrcNotebookViewJumpHistory;
|
|
DebugBoss.ConnectSourceNotebookEvents;
|
|
|
|
// connect search menu to sourcenotebook
|
|
itmSearchFind.OnClick := @SourceNotebook.FindClicked;
|
|
itmSearchFindNext.OnClick := @SourceNotebook.FindNextClicked;
|
|
itmSearchFindPrevious.OnClick := @SourceNotebook.FindPreviousClicked;
|
|
itmSearchFindInFiles.OnClick := @SourceNotebook.FindInFilesClicked;
|
|
itmSearchReplace.OnClick := @SourceNotebook.ReplaceClicked;
|
|
itmGotoLine.OnClick := @SourceNotebook.GotoLineClicked;
|
|
itmJumpBack.OnClick := @SourceNotebook.JumpBackClicked;
|
|
itmJumpForward.OnClick := @SourceNotebook.JumpForwardClicked;
|
|
itmAddJumpPoint.OnClick := @SourceNotebook.AddJumpPointClicked;
|
|
itmJumpHistory.OnClick := @SourceNotebook.ViewJumpHistoryClicked;
|
|
itmFindBlockStart.OnClick:=@mnuSearchFindBlockStart;
|
|
itmFindBlockOtherEnd.OnClick:=@mnuSearchFindBlockOtherEnd;
|
|
itmFindDeclaration.OnClick:=@mnuSearchFindDeclaration;
|
|
itmOpenFileAtCursor.OnClick:=@mnuOpenFileAtCursorClicked;
|
|
end;
|
|
|
|
procedure TMainIDE.SetupTransferMacros;
|
|
begin
|
|
MacroList:=TTransferMacroList.Create;
|
|
MacroList.Add(TTransferMacro.Create('Col','',
|
|
lisCursorColumnInCurrentEditor,nil,[]));
|
|
MacroList.Add(TTransferMacro.Create('Row','',
|
|
lisCursorRowInCUrrentEditor,nil,[]));
|
|
MacroList.Add(TTransferMacro.Create('CompPath','',
|
|
lisCompilerFilename,nil,[]));
|
|
MacroList.Add(TTransferMacro.Create('CurToken','',
|
|
lisWordAtCursorInCurrentEditor,nil,[]));
|
|
MacroList.Add(TTransferMacro.Create('EdFile','',
|
|
lisExpandedFilenameOfCurrentEditor,nil,[]));
|
|
MacroList.Add(TTransferMacro.Create('FPCSrcDir','',
|
|
lisFreePascalSourceDirectory,nil,[]));
|
|
MacroList.Add(TTransferMacro.Create('LazarusDir','',
|
|
lisLazarusDirectory,nil,[]));
|
|
MacroList.Add(TTransferMacro.Create('LCLWidgetType','',
|
|
lisLCLWidgetType,nil,[]));
|
|
MacroList.Add(TTransferMacro.Create('Params','',
|
|
lisCommandLineParamsOfProgram,nil,[]));
|
|
MacroList.Add(TTransferMacro.Create('Prompt','',
|
|
lisPromptForValue,@OnMacroPromptFunction,[tmfInteractive]));
|
|
MacroList.Add(TTransferMacro.Create('ProjFile','',
|
|
lisProjectFilename,nil,[]));
|
|
MacroList.Add(TTransferMacro.Create('ProjPath','',
|
|
lisProjectDirectory,nil,[]));
|
|
MacroList.Add(TTransferMacro.Create('Save','',
|
|
lisSaveCurrentEditorFile,nil,[tmfInteractive]));
|
|
MacroList.Add(TTransferMacro.Create('SaveAll','',
|
|
lisSaveAllModified,nil,[tmfInteractive]));
|
|
MacroList.Add(TTransferMacro.Create('TargetFile','',
|
|
lisTargetFilenameOfProject,nil,[]));
|
|
MacroList.Add(TTransferMacro.Create('TargetCmdLine','',
|
|
lisTargetFilenamePlusParams,nil,[]));
|
|
MacroList.Add(TTransferMacro.Create('RunCmdLine','',
|
|
lisLaunchingCmdLine,nil,[]));
|
|
MacroList.OnSubstitution:=@OnMacroSubstitution;
|
|
end;
|
|
|
|
procedure TMainIDE.SetupControlSelection;
|
|
begin
|
|
TheControlSelection:=TControlSelection.Create;
|
|
TheControlSelection.OnChange:=@OnControlSelectionChanged;
|
|
end;
|
|
|
|
procedure TMainIDE.SetupStartProject;
|
|
begin
|
|
{$IFDEF IDE_DEBUG}
|
|
writeln('TMainIDE.Create A ***********');
|
|
{$ENDIF}
|
|
{$IFDEF IDE_MEM_CHECK}CheckHeap(IntToStr(GetMem_Cnt));{$ENDIF}
|
|
// load command line project or last project or create a new project
|
|
if (ParamCount>0) and (ParamStr(ParamCount)[1]<>'-')
|
|
and (ExtractFileExt(ParamStr(ParamCount))='.lpi')
|
|
and (DoOpenProjectFile(ParamStr(ParamCount))=mrOk) then
|
|
// command line project loaded
|
|
else if (EnvironmentOptions.OpenLastprojectAtStart)
|
|
and (FileExists(EnvironmentOptions.LastSavedProjectFile))
|
|
and (DoOpenProjectFile(EnvironmentOptions.LastSavedProjectFile)=mrOk) then
|
|
begin
|
|
// last project loaded
|
|
{$IFDEF IDE_DEBUG}
|
|
writeln('TMainIDE.Create last project loaded successfully');
|
|
{$ENDIF}
|
|
{$IFDEF IDE_MEM_CHECK}CheckHeap(IntToStr(GetMem_Cnt));{$ENDIF}
|
|
end else
|
|
// create new project
|
|
DoNewProject(ptApplication);
|
|
|
|
{$IFDEF IDE_DEBUG}
|
|
writeln('TMainIDE.Create B');
|
|
{$ENDIF}
|
|
{$IFDEF IDE_MEM_CHECK}CheckHeap(IntToStr(GetMem_Cnt));{$ENDIF}
|
|
end;
|
|
|
|
|
|
{------------------------------------------------------------------------------}
|
|
procedure TMainIDE.SetupMainMenu;
|
|
begin
|
|
mnuMain := TMainMenu.Create(Self);
|
|
mnuMain.Name:='mnuMainMenu';
|
|
Menu := mnuMain;
|
|
|
|
mnuFile := TMenuItem.Create(Self);
|
|
mnuFile.Name:='mnuFile';
|
|
mnuFile.Caption := lisMenuFile;
|
|
mnuMain.Items.Add(mnuFile);
|
|
|
|
mnuEdit := TMenuItem.Create(Self);
|
|
mnuEdit.Name:='mnuEdit';
|
|
mnuEdit.Caption := lisMenuEdit;
|
|
mnuMain.Items.Add(mnuEdit);
|
|
|
|
mnuSearch := TMenuItem.Create(Self);
|
|
mnuSearch.Name:='mnuSearch';
|
|
mnuSearch.Caption := lisMenuSearch;
|
|
mnuMain.Items.Add(mnuSearch);
|
|
|
|
mnuView := TMenuItem.Create(Self);
|
|
mnuView.Name:='mnuView';
|
|
mnuView.Caption := lisMenuView;
|
|
mnuMain.Items.Add(mnuView);
|
|
|
|
mnuProject := TMenuItem.Create(Self);
|
|
mnuProject.Name:='mnuProject';
|
|
mnuProject.Caption := lisMenuProject;
|
|
mnuMain.Items.Add(mnuProject);
|
|
|
|
mnuRun := TMenuItem.Create(Self);
|
|
mnuRun.Name:='mnuRun';
|
|
mnuRun.Caption := lisMenuRun;
|
|
mnuMain.Items.Add(mnuRun);
|
|
|
|
mnuTools := TMenuItem.Create(Self);
|
|
mnuTools.Name:='mnuTools';
|
|
mnuTools.Caption := lisMenuTools;
|
|
mnuMain.Items.Add(mnuTools);
|
|
|
|
mnuEnvironment := TMenuItem.Create(Self);
|
|
mnuEnvironment.Name:='mnuEnvironment';
|
|
mnuEnvironment.Caption := lisMenuEnvironent;
|
|
mnuMain.Items.Add(mnuEnvironment);
|
|
|
|
mnuHelp := TMenuItem.Create(Self);
|
|
mnuHelp.Name:='mnuHelp';
|
|
mnuHelp.Caption := lisMenuHelp;
|
|
mnuMain.Items.Add(mnuHelp);
|
|
|
|
SetupFileMenu;
|
|
SetupEditMenu;
|
|
SetupSearchMenu;
|
|
SetupViewMenu;
|
|
SetupProjectMenu;
|
|
SetupRunMenu;
|
|
SetupToolsMenu;
|
|
SetupEnvironmentMenu;
|
|
SetupHelpMenu;
|
|
end;
|
|
|
|
procedure TMainIDE.SetRecentSubMenu(ParentMenuItem: TMenuItem;
|
|
FileList: TStringList; OnClickEvent: TNotifyEvent);
|
|
var i: integer;
|
|
AMenuItem: TMenuItem;
|
|
begin
|
|
// create enough menuitems
|
|
while ParentMenuItem.Count<FileList.Count do begin
|
|
AMenuItem:=TMenuItem.Create(Self);
|
|
AMenuItem.Name:=
|
|
ParentMenuItem.Name+'Recent'+IntToStr(ParentMenuItem.Count);
|
|
ParentMenuItem.Add(AMenuItem);
|
|
end;
|
|
// delete unused menuitems
|
|
while ParentMenuItem.Count>FileList.Count do
|
|
ParentMenuItem.Items[ParentMenuItem.Count-1].Free;
|
|
// set captions
|
|
for i:=0 to FileList.Count-1 do begin
|
|
AMenuItem:=ParentMenuItem.Items[i];
|
|
AMenuItem.Caption := FileList[i];
|
|
AMenuItem.OnClick := OnClickEvent;
|
|
end;
|
|
end;
|
|
|
|
procedure TMainIDE.SetRecentFilesMenu;
|
|
begin
|
|
SetRecentSubMenu(itmFileRecentOpen,EnvironmentOptions.RecentOpenFiles,
|
|
@mnuOpenClicked);
|
|
end;
|
|
|
|
procedure TMainIDE.SetRecentProjectFilesMenu;
|
|
begin
|
|
SetRecentSubMenu(itmProjectRecentOpen,EnvironmentOptions.RecentProjectFiles,
|
|
@mnuOpenProjectClicked);
|
|
end;
|
|
|
|
procedure TMainIDE.SetupFileMenu;
|
|
begin
|
|
inherited;
|
|
itmFileNewUnit.OnClick := @mnuNewUnitClicked;
|
|
itmFileNewForm.OnClick := @mnuNewFormClicked;
|
|
itmFileOpen.OnClick := @mnuOpenClicked;
|
|
itmFileRevert.OnClick := @mnuRevertClicked;
|
|
SetRecentFilesMenu;
|
|
itmFileSave.OnClick := @mnuSaveClicked;
|
|
itmFileSaveAs.OnClick := @mnuSaveAsClicked;
|
|
itmFileSaveAll.OnClick := @mnuSaveAllClicked;
|
|
itmFileClose.Enabled := False;
|
|
itmFileClose.OnClick := @mnuCloseClicked;
|
|
itmFileCloseAll.Enabled := False;
|
|
itmFileCloseAll.OnClick := @mnuCloseAllClicked;
|
|
itmFileQuit.OnClick := @mnuQuitClicked;
|
|
end;
|
|
|
|
procedure TMainIDE.SetupEditMenu;
|
|
begin
|
|
inherited;
|
|
itmEditUndo.OnClick:=@mnuEditUndoClicked;
|
|
itmEditRedo.OnClick:=@mnuEditRedoClicked;
|
|
itmEditCut.OnClick:=@mnuEditCutClicked;
|
|
itmEditCopy.OnClick:=@mnuEditCopyClicked;
|
|
itmEditPaste.OnClick:=@mnuEditPasteClicked;
|
|
itmEditIndentBlock.OnClick:=@mnuEditIndentBlockClicked;
|
|
itmEditUnindentBlock.OnClick:=@mnuEditUnindentBlockClicked;
|
|
itmEditUpperCaseBlock.OnClick:=@mnuEditUpperCaseBlockClicked;
|
|
itmEditLowerCaseBlock.OnClick:=@mnuEditLowerCaseBlockClicked;
|
|
itmEditTabsToSpacesBlock.OnClick:=@mnuEditTabsToSpacesBlockClicked;
|
|
itmEditCompleteCode.OnClick:=@mnuEditCompleteCodeClicked;
|
|
end;
|
|
|
|
procedure TMainIDE.SetupSearchMenu;
|
|
begin
|
|
inherited;
|
|
itmGotoIncludeDirective.OnClick:=@mnuGotoIncludeDirectiveClicked;
|
|
end;
|
|
|
|
procedure TMainIDE.SetupViewMenu;
|
|
begin
|
|
inherited;
|
|
itmViewInspector.OnClick := @mnuViewInspectorClicked;
|
|
itmViewCodeExplorer.OnClick := @mnuViewCodeExplorerClick;
|
|
itmViewUnits.OnClick := @mnuViewUnitsClicked;
|
|
itmViewForms.OnClick := @mnuViewFormsClicked;
|
|
itmViewToggleFormUnit.OnClick := @mnuToggleFormUnitClicked;
|
|
itmViewMessage.OnClick := @mnuViewMessagesClick;
|
|
end;
|
|
|
|
procedure TMainIDE.SetupProjectMenu;
|
|
begin
|
|
inherited;
|
|
itmProjectNew.OnClick := @mnuNewProjectClicked;
|
|
itmProjectOpen.OnClick := @mnuOpenProjectClicked;
|
|
SetRecentProjectFilesMenu;
|
|
itmProjectSave.OnClick := @mnuSaveProjectClicked;
|
|
itmProjectSaveAs.OnClick := @mnuSaveProjectAsClicked;
|
|
itmProjectAddTo.OnClick := @mnuAddToProjectClicked;
|
|
itmProjectRemoveFrom.OnClick := @mnuRemoveFromProjectClicked;
|
|
itmProjectViewSource.OnClick := @mnuViewProjectSourceClicked;
|
|
itmProjectOptions.OnClick := @mnuProjectOptionsClicked;
|
|
end;
|
|
|
|
procedure TMainIDE.SetupRunMenu;
|
|
begin
|
|
inherited;
|
|
itmProjectBuild.OnClick := @mnuBuildProjectClicked;
|
|
itmProjectBuildAll.OnClick := @mnuBuildAllProjectClicked;
|
|
itmProjectRun.OnClick := @mnuRunProjectClicked;
|
|
itmProjectPause.Enabled := false;
|
|
itmProjectPause.OnClick := @mnuPauseProjectClicked;
|
|
itmProjectStepInto.OnClick := @mnuStepIntoProjectClicked;
|
|
itmProjectStepOver.OnClick := @mnuStepOverProjectClicked;
|
|
itmProjectRunToCursor.OnClick := @mnuRunToCursorProjectClicked;
|
|
itmProjectStop.OnClick := @mnuStopProjectClicked;
|
|
itmProjectCompilerSettings.OnClick := @mnuProjectCompilerSettingsClicked;
|
|
itmProjectRunParameters.OnClick := @mnuRunParametersClicked;
|
|
end;
|
|
|
|
procedure TMainIDE.SetupToolsMenu;
|
|
begin
|
|
inherited;
|
|
itmToolConfigure.OnClick := @mnuToolConfigureClicked;
|
|
itmToolSyntaxCheck.OnClick := @mnuToolSyntaxCheckClicked;
|
|
itmToolGuessUnclosedBlock.OnClick := @mnuToolGuessUnclosedBlockClicked;
|
|
itmToolGuessMisplacedIFDEF.OnClick := @mnuToolGuessMisplacedIFDEFClicked;
|
|
itmToolConvertDFMtoLFM.OnClick := @mnuToolConvertDFMtoLFMClicked;
|
|
itmToolBuildLazarus.OnClick := @mnuToolBuildLazarusClicked;
|
|
itmToolConfigureBuildLazarus.OnClick := @mnuToolConfigBuildLazClicked;
|
|
end;
|
|
|
|
procedure TMainIDE.SetupEnvironmentMenu;
|
|
begin
|
|
inherited;
|
|
itmEnvGeneralOptions.OnClick := @mnuEnvGeneralOptionsClicked;
|
|
itmEnvEditorOptions.OnClick := @mnuEnvEditorOptionsClicked;
|
|
itmEnvCodeToolsOptions.OnClick := @mnuEnvCodeToolsOptionsClicked;
|
|
itmEnvCodeToolsDefinesEditor.OnClick := @mnuEnvCodeToolsDefinesEditorClicked;
|
|
end;
|
|
|
|
procedure TMainIDE.SetupHelpMenu;
|
|
begin
|
|
inherited;
|
|
itmHelpAboutLazarus.OnClick := @mnuHelpAboutLazarusClicked;
|
|
end;
|
|
|
|
procedure TMainIDE.LoadMenuShortCuts;
|
|
begin
|
|
inherited LoadMenuShortCuts;
|
|
DebugBoss.SetupMainBarShortCuts;
|
|
end;
|
|
|
|
procedure TMainIDE.ConnectMainBarEvents;
|
|
begin
|
|
//OnShow := @FormShow;
|
|
OnClose := @FormClose;
|
|
OnCloseQuery := @FormCloseQuery;
|
|
|
|
OnMouseMove := @MainMouseMoved;
|
|
OnMouseDown := @MainMouseDown;
|
|
OnKeyDown := @MainKeyDown;
|
|
end;
|
|
|
|
{------------------------------------------------------------------------------}
|
|
|
|
Procedure TMainIDE.mnuToggleFormUnitClicked(Sender : TObject);
|
|
Begin
|
|
FCodeLastActivated:=not FCodeLastActivated;
|
|
DoBringToFrontFormOrUnit;
|
|
end;
|
|
|
|
Procedure TMainIDE.SetDesigning(Control : TComponent; Value : Boolean);
|
|
Begin
|
|
Control.SetDesigning(Value);
|
|
if Value then CNSendMessage(LM_SETDESIGNING, Control, nil);
|
|
end;
|
|
|
|
{------------------------------------------------------------------------------}
|
|
procedure TMainIDE.ControlClick(Sender : TObject);
|
|
var
|
|
IDECOmp : TIDEComponent;
|
|
Speedbutton : TSpeedbutton;
|
|
i : integer;
|
|
begin
|
|
if Sender is TSpeedButton then
|
|
begin
|
|
SpeedButton := TSpeedButton(Sender);
|
|
// find the IDEComponent that belongs to this speedbutton
|
|
IDEComp := IDECompList.FindCompBySpeedButton(SpeedButton);
|
|
if IDECOmp <> nil then begin
|
|
SelectedComponent := IDEComp.RegisteredComponent;
|
|
end else begin
|
|
SelectedComponent := nil;
|
|
end;
|
|
end
|
|
else
|
|
begin
|
|
SelectedComponent := nil;
|
|
for i:= 0 to ComponentNotebook.PageCount - 1 do begin
|
|
(ComponentNotebook.Page[i].Controls[0] as TSpeedButton).Down:= true;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
{------------------------------------------------------------------------------}
|
|
procedure TMainIDE.mnuFindDeclarationClicked(Sender : TObject);
|
|
begin
|
|
if SourceNoteBook.NoteBook=nil then exit;
|
|
DoFindDeclarationAtCursor;
|
|
end;
|
|
|
|
procedure TMainIDE.mnuNewUnitClicked(Sender : TObject);
|
|
begin
|
|
DoNewEditorFile(nuUnit,'');
|
|
end;
|
|
|
|
procedure TMainIDE.mnuNewFormClicked(Sender : TObject);
|
|
begin
|
|
DoNewEditorFile(nuForm,'');
|
|
end;
|
|
|
|
procedure TMainIDE.mnuOpenClicked(Sender : TObject);
|
|
|
|
procedure UpdateEnvironment;
|
|
begin
|
|
SetRecentFilesMenu;
|
|
SaveEnvironment;
|
|
end;
|
|
|
|
var OpenDialog: TOpenDialog;
|
|
AFilename: string;
|
|
I : Integer;
|
|
begin
|
|
if (Sender=itmFileOpen) or (Sender=OpenFileSpeedBtn)
|
|
or (Sender is TSourceNoteBook) then begin
|
|
OpenDialog:=TOpenDialog.Create(Application);
|
|
try
|
|
InputHistories.ApplyFileDialogSettings(OpenDialog);
|
|
OpenDialog.Title:=lisOpenFile;
|
|
OpenDialog.Options:=OpenDialog.Options+[ofAllowMultiSelect];
|
|
if OpenDialog.Execute and (OpenDialog.Files.Count>0) then begin
|
|
For I := 0 to OpenDialog.Files.Count-1 do
|
|
Begin
|
|
AFilename:=ExpandFilename(OpenDialog.Files.Strings[i]);
|
|
if DoOpenEditorFile(AFilename,-1,[ofAddToRecent])=mrOk then begin
|
|
|
|
end;
|
|
end;
|
|
UpdateEnvironment;
|
|
end;
|
|
InputHistories.StoreFileDialogSettings(OpenDialog);
|
|
finally
|
|
OpenDialog.Free;
|
|
end;
|
|
end else if Sender is TMenuItem then begin
|
|
AFileName:=ExpandFilename(TMenuItem(Sender).Caption);
|
|
if DoOpenEditorFile(AFilename,-1,[ofAddToRecent])=mrOk then begin
|
|
UpdateEnvironment;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
procedure TMainIDE.mnuRevertClicked(Sender : TObject);
|
|
begin
|
|
if SourceNoteBook.NoteBook=nil then exit;
|
|
DoOpenEditorFile('',SourceNoteBook.NoteBook.PageIndex,[ofRevert]);
|
|
end;
|
|
|
|
procedure TMainIDE.mnuOpenFileAtCursorClicked(Sender : TObject);
|
|
begin
|
|
if SourceNoteBook.NoteBook=nil then exit;
|
|
DoOpenFileAtCursor(Sender);
|
|
end;
|
|
|
|
procedure TMainIDE.mnuGotoIncludeDirectiveClicked(Sender : TObject);
|
|
begin
|
|
DoGotoIncludeDirective;
|
|
end;
|
|
|
|
procedure TMainIDE.mnuSaveClicked(Sender : TObject);
|
|
begin
|
|
if SourceNoteBook.NoteBook=nil then exit;
|
|
DoSaveEditorFile(SourceNoteBook.NoteBook.PageIndex,[]);
|
|
end;
|
|
|
|
procedure TMainIDE.mnuSaveAsClicked(Sender : TObject);
|
|
begin
|
|
if SourceNoteBook.NoteBook=nil then exit;
|
|
DoSaveEditorFile(SourceNoteBook.NoteBook.PageIndex,[sfSaveAs]);
|
|
end;
|
|
|
|
procedure TMainIDE.mnuSaveAllClicked(Sender : TObject);
|
|
begin
|
|
DoSaveAll;
|
|
end;
|
|
|
|
procedure TMainIDE.mnuCloseClicked(Sender : TObject);
|
|
var PageIndex: integer;
|
|
begin
|
|
if SourceNoteBook.NoteBook=nil then exit;
|
|
if Sender is TPage then begin
|
|
PageIndex:=SourceNoteBook.NoteBook.PageList.IndexOf(Sender);
|
|
if PageIndex<0 then
|
|
PageIndex:=SourceNoteBook.NoteBook.PageIndex;
|
|
end else begin
|
|
PageIndex:=SourceNoteBook.NoteBook.PageIndex;
|
|
end;
|
|
DoCloseEditorFile(PageIndex,[cfSaveFirst]);
|
|
end;
|
|
|
|
procedure TMainIDE.mnuCloseAllClicked(Sender : TObject);
|
|
begin
|
|
while (SourceNoteBook.NoteBook<>nil)
|
|
and (DoCloseEditorFile(SourceNoteBook.NoteBook.PageIndex,
|
|
[cfSaveFirst])=mrOk) do ;
|
|
end;
|
|
|
|
Procedure TMainIDE.OnSrcNotebookFileNew(Sender : TObject);
|
|
begin
|
|
mnuNewFormClicked(Sender);
|
|
end;
|
|
|
|
Procedure TMainIDE.OnSrcNotebookFileClose(Sender : TObject);
|
|
begin
|
|
mnuCloseClicked(Sender);
|
|
end;
|
|
|
|
Procedure TMainIDE.OnSrcNotebookFileOpen(Sender : TObject);
|
|
begin
|
|
mnuOpenClicked(Sender);
|
|
end;
|
|
|
|
Procedure TMainIDE.OnSrcNoteBookFileOpenAtCursor(Sender : TObject);
|
|
begin
|
|
mnuOpenFileAtCursorClicked(Sender);
|
|
end;
|
|
|
|
Procedure TMainIDE.OnSrcNotebookFileSave(Sender : TObject);
|
|
begin
|
|
mnuSaveClicked(Sender);
|
|
end;
|
|
|
|
Procedure TMainIDE.OnSrcNotebookFileSaveAs(Sender : TObject);
|
|
begin
|
|
mnuSaveAsClicked(Sender);
|
|
end;
|
|
|
|
Procedure TMainIDE.OnSrcNoteBookFindDeclaration(Sender : TObject);
|
|
begin
|
|
mnuFindDeclarationClicked(Sender);
|
|
end;
|
|
|
|
Procedure TMainIDE.OnSrcNotebookSaveAll(Sender : TObject);
|
|
begin
|
|
mnuSaveAllClicked(Sender);
|
|
end;
|
|
|
|
Procedure TMainIDE.OnSrcNotebookToggleFormUnit(Sender : TObject);
|
|
begin
|
|
mnuToggleFormUnitClicked(Sender);
|
|
end;
|
|
|
|
Procedure TMainIDE.OnSrcNotebookProcessCommand(Sender: TObject;
|
|
Command: integer; var Handled: boolean);
|
|
begin
|
|
Handled:=true;
|
|
case Command of
|
|
ecSaveAll:
|
|
DoSaveAll;
|
|
|
|
ecBuild,
|
|
ecBuildAll: DoBuildProject(Command=ecBuildAll);
|
|
|
|
ecRun: DoRunProject;
|
|
ecPause: DebugBoss.DoPauseProject;
|
|
ecStepInto: DebugBoss.DoStepIntoProject;
|
|
ecStepOver: DebugBoss.DoStepOverProject;
|
|
ecRunToCursor: DebugBoss.DoRunToCursor;
|
|
ecStopProgram: DebugBoss.DoStopProject;
|
|
|
|
ecFindProcedureDefinition,ecFindProcedureMethod:
|
|
DoJumpToProcedureSection;
|
|
|
|
ecFindDeclaration:
|
|
DoFindDeclarationAtCursor;
|
|
|
|
ecFindBlockOtherEnd:
|
|
DoGoToPascalBlockOtherEnd;
|
|
|
|
ecFindBlockStart:
|
|
DoGoToPascalBlockStart;
|
|
|
|
ecGotoIncludeDirective:
|
|
DoGotoIncludeDirective;
|
|
|
|
ecCompleteCode:
|
|
DoCompleteCodeAtCursor;
|
|
|
|
ecExtToolFirst..ecExtToolLast:
|
|
DoRunExternalTool(Command-ecExtToolFirst);
|
|
|
|
ecSyntaxCheck:
|
|
DoCheckSyntax;
|
|
|
|
ecGuessUnclosedBlock:
|
|
DoJumpToGuessedUnclosedBlock(true);
|
|
|
|
ecGuessMisplacedIFDEF:
|
|
DoJumpToGuessedMisplacedIFDEF(true);
|
|
|
|
ecConvertDFM2LFM:
|
|
DoConvertDFMtoLFM;
|
|
|
|
ecBuildLazarus:
|
|
DoBuildLazarus;
|
|
|
|
else
|
|
Handled:=false;
|
|
end;
|
|
end;
|
|
|
|
procedure TMainIDE.OnSrcNoteBookShowUnitInfo(Sender: TObject);
|
|
var ActiveSrcEdit:TSourceEditor;
|
|
ActiveUnitInfo:TUnitInfo;
|
|
ShortUnitName, AFilename: string;
|
|
begin
|
|
GetCurrentUnit(ActiveSrcEdit,ActiveUnitInfo);
|
|
if (ActiveSrcEdit=nil) or (ActiveUnitInfo=nil) then exit;
|
|
ShortUnitName:=ActiveSrcEdit.ShortName;
|
|
AFilename:=ActiveUnitInfo.Filename;
|
|
ShowUnitInfoDlg(ShortUnitName,
|
|
LazSyntaxHighlighterNames[ActiveUnitInfo.SyntaxHighlighter],
|
|
ActiveUnitInfo.IsPartOfProject, length(ActiveSrcEdit.Source.Text),
|
|
ActiveSrcEdit.Source.Count,AFilename);
|
|
end;
|
|
|
|
{------------------------------------------------------------------------------}
|
|
|
|
Procedure TMainIDE.OpenFileDownArrowClicked(Sender : TObject);
|
|
var
|
|
CurIndex: integer;
|
|
|
|
procedure AddFile(const Filename: string);
|
|
var
|
|
AMenuItem: TMenuItem;
|
|
begin
|
|
if OpenFilePopupMenu.Items.Count>CurIndex then
|
|
AMenuItem:=OpenFilePopupMenu.Items[CurIndex]
|
|
else begin
|
|
AMenuItem:=TMenuItem.Create(Self);
|
|
AMenuItem.Name:=OpenFilePopupMenu.Name+'Recent'+IntToStr(CurIndex);
|
|
AMenuItem.OnClick:=@mnuOpenFilePopupClick;
|
|
OpenFilePopupMenu.Items.Add(AMenuItem);
|
|
end;
|
|
AMenuItem.Caption:=Filename;
|
|
inc(CurIndex);
|
|
end;
|
|
|
|
procedure AddFiles(List: TStringList; MaxCount: integer);
|
|
var i: integer;
|
|
begin
|
|
i:=0;
|
|
while (i<List.Count) and (i<MaxCount) do begin
|
|
AddFile(List[i]);
|
|
inc(i);
|
|
end;
|
|
end;
|
|
|
|
Begin
|
|
// fill the PopupMenu:
|
|
CurIndex:=0;
|
|
// first add 8 recent projects
|
|
AddFiles(EnvironmentOptions.RecentProjectFiles,8);
|
|
// add a separator
|
|
AddFile('-');
|
|
// add 12 recent files
|
|
AddFiles(EnvironmentOptions.RecentOpenFiles,12);
|
|
// remove unused menuitems
|
|
while OpenFilePopupMenu.Items.Count>CurIndex do
|
|
OpenFilePopupMenu.Items[OpenFilePopupMenu.Items.Count-1].Free;
|
|
// display the PopupMenu
|
|
if OpenFilePopupMenu.Items.Count > 0 then
|
|
OpenFilePopupMenu.Popup(0,0);
|
|
end;
|
|
|
|
procedure TMainIDE.mnuOpenFilePopupClick(Sender: TObject);
|
|
var
|
|
TheMenuItem: TMenuItem;
|
|
Index, SeparatorIndex: integer;
|
|
AFilename: string;
|
|
begin
|
|
TheMenuItem:=TMenuItem(Sender);
|
|
if TheMenuItem.Caption='-' then exit;
|
|
Index:=TheMenuItem.MenuIndex;
|
|
SeparatorIndex:=0;
|
|
while SeparatorIndex<OpenFilePopupMenu.Items.Count do begin
|
|
if OpenFilePopupMenu.Items[SeparatorIndex].Caption='-' then break;
|
|
inc(SeparatorIndex);
|
|
end;
|
|
if Index=SeparatorIndex then exit;
|
|
if Index<SeparatorIndex then begin
|
|
// open recent project
|
|
AFilename:=EnvironmentOptions.RecentProjectFiles[Index];
|
|
if DoOpenProjectFile(AFileName)=mrOk then begin
|
|
EnvironmentOptions.AddToRecentProjectFiles(AFileName);
|
|
SetRecentProjectFilesMenu;
|
|
SaveEnvironment;
|
|
end;
|
|
end else begin
|
|
// open recent file
|
|
dec(Index, SeparatorIndex+1);
|
|
if DoOpenEditorFile(EnvironmentOptions.RecentOpenFiles[Index],-1,
|
|
[ofAddToRecent])=mrOk then
|
|
begin
|
|
SetRecentFilesMenu;
|
|
SaveEnvironment;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
Procedure TMainIDE.SetDefaultsforForm(aForm : TCustomForm);
|
|
Begin
|
|
{$IFDEF IDE_DEBUG}
|
|
writeln('[TMainIDE.SetDefaultsforForm] A');
|
|
{$ENDIF}
|
|
aForm.Designer := TDesigner.Create(aForm, TheControlSelection);
|
|
{$IFDEF IDE_DEBUG}
|
|
writeln('[TMainIDE.SetDefaultsforForm] B');
|
|
{$ENDIF}
|
|
with TDesigner(aForm.Designer) do begin
|
|
FormEditor := FormEditor1;
|
|
OnGetSelectedComponentClass:=@OnDesignerGetSelectedComponentClass;
|
|
OnUnselectComponentClass:=@OnDesignerUnselectComponentClass;
|
|
OnSetDesigning:=@OnDesignerSetDesigning;
|
|
OnComponentListChanged:=@OnDesignerComponentListChanged;
|
|
OnPropertiesChanged:=@OnDesignerPropertiesChanged;
|
|
OnAddComponent:=@OnDesignerAddComponent;
|
|
OnRemoveComponent:=@OnDesignerRemoveComponent;
|
|
OnGetNonVisualCompIconCanvas:=@IDECompList.OnGetNonVisualCompIconCanvas;
|
|
OnModified:=@OnDesignerModified;
|
|
OnActivated:=@OnDesignerActivated;
|
|
OnRenameComponent:=@OnDesignerRenameComponent;
|
|
ShowHints:=EnvironmentOptions.ShowEditorHints;
|
|
end;
|
|
end;
|
|
|
|
{-------------------------------------------------------------------------------
|
|
procedure TMainIDE.InvalidateAllDesignerForms
|
|
Params: none
|
|
Result: none
|
|
|
|
Calls 'Invalidate' in all designer forms.
|
|
-------------------------------------------------------------------------------}
|
|
procedure TMainIDE.InvalidateAllDesignerForms;
|
|
var i: integer;
|
|
begin
|
|
for i:=0 to Project1.UnitCount-1 do begin
|
|
if (Project1.Units[i].Form<>nil)
|
|
and (Project1.Units[i].Form is TControl) then
|
|
TControl(Project1.Units[i].Form).Invalidate;
|
|
end;
|
|
end;
|
|
|
|
|
|
{------------------------------------------------------------------------------}
|
|
|
|
procedure TMainIDE.mnuQuitClicked(Sender : TObject);
|
|
var CanClose: boolean;
|
|
begin
|
|
CanClose:=true;
|
|
OnCloseQuery(Sender, CanClose);
|
|
{$IFDEF IDE_DEBUG}
|
|
writeln('TMainIDE.mnuQuitClicked 1');
|
|
{$ENDIF}
|
|
if CanClose then Close;
|
|
{$IFDEF IDE_DEBUG}
|
|
writeln('TMainIDE.mnuQuitClicked 2');
|
|
{$ENDIF}
|
|
end;
|
|
|
|
{------------------------------------------------------------------------------}
|
|
procedure TMainIDE.mnuViewInspectorClicked(Sender : TObject);
|
|
begin
|
|
ObjectInspector1.Show;
|
|
end;
|
|
|
|
{------------------------------------------------------------------------------}
|
|
|
|
Procedure TMainIDE.mnuViewUnitsClicked(Sender : TObject);
|
|
begin
|
|
DoViewUnitsAndForms(false);
|
|
end;
|
|
|
|
Procedure TMainIDE.mnuViewFormsClicked(Sender : TObject);
|
|
Begin
|
|
DoViewUnitsAndForms(true);
|
|
end;
|
|
|
|
Procedure TMainIDE.mnuViewCodeExplorerClick(Sender : TObject);
|
|
begin
|
|
SourceNotebook.Show;
|
|
end;
|
|
|
|
Procedure TMainIDE.mnuViewMessagesClick(Sender : TObject);
|
|
Begin
|
|
MessagesView.Show;
|
|
End;
|
|
|
|
|
|
{------------------------------------------------------------------------------}
|
|
|
|
Procedure TMainIDE.mnuNewProjectClicked(Sender : TObject);
|
|
var
|
|
NewProjectType: TProjectType;
|
|
Begin
|
|
if ChooseNewProject(NewProjectType)=mrCancel then exit;
|
|
DoNewProject(NewprojectType);
|
|
end;
|
|
|
|
Procedure TMainIDE.mnuOpenProjectClicked(Sender : TObject);
|
|
var OpenDialog:TOpenDialog;
|
|
AFileName: string;
|
|
|
|
procedure UpdateEnvironment;
|
|
begin
|
|
EnvironmentOptions.AddToRecentProjectFiles(AFilename);
|
|
SetRecentProjectFilesMenu;
|
|
SaveEnvironment;
|
|
end;
|
|
|
|
begin
|
|
if Sender=itmProjectOpen then begin
|
|
OpenDialog:=TOpenDialog.Create(Application);
|
|
try
|
|
InputHistories.ApplyFileDialogSettings(OpenDialog);
|
|
OpenDialog.Title:=lisOpenProjectFile+' (*.lpi)';
|
|
OpenDialog.Filter := 'Lazarus Project Info (*.lpi)|*.lpi|All Files|*.*';
|
|
if OpenDialog.Execute then begin
|
|
AFilename:=ExpandFilename(OpenDialog.Filename);
|
|
if DoOpenProjectFile(AFilename)=mrOk then begin
|
|
UpdateEnvironment;
|
|
end;
|
|
end;
|
|
InputHistories.StoreFileDialogSettings(OpenDialog);
|
|
finally
|
|
OpenDialog.Free;
|
|
end;
|
|
end else if Sender is TMenuItem then begin
|
|
AFileName:=ExpandFilename(TMenuItem(Sender).Caption);
|
|
if DoOpenProjectFile(AFilename)=mrOk then begin
|
|
UpdateEnvironment;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
Procedure TMainIDE.mnuSaveProjectClicked(Sender : TObject);
|
|
Begin
|
|
DoSaveProject([]);
|
|
end;
|
|
|
|
procedure TMainIDE.mnuSaveProjectAsClicked(Sender : TObject);
|
|
begin
|
|
DoSaveProject([sfSaveAs]);
|
|
end;
|
|
|
|
procedure TMainIDE.mnuAddToProjectClicked(Sender : TObject);
|
|
begin
|
|
DoAddActiveUnitToProject;
|
|
end;
|
|
|
|
procedure TMainIDE.mnuRemoveFromProjectClicked(Sender : TObject);
|
|
begin
|
|
DoRemoveFromProjectDialog;
|
|
end;
|
|
|
|
procedure TMainIDE.mnuViewProjectSourceClicked(Sender : TObject);
|
|
begin
|
|
DoOpenMainUnit(false);
|
|
end;
|
|
|
|
procedure TMainIDE.mnuProjectOptionsClicked(Sender : TObject);
|
|
var
|
|
ActiveSrcEdit: TSourceEditor;
|
|
ActiveUnitInfo: TUnitInfo;
|
|
begin
|
|
BeginCodeTool(ActiveSrcEdit, ActiveUnitInfo, false);
|
|
if ShowProjectOptionsDialog(Project1)=mrOk then begin
|
|
|
|
end;
|
|
end;
|
|
|
|
Procedure TMainIDE.mnuBuildProjectClicked(Sender : TObject);
|
|
Begin
|
|
DoBuildProject(false);
|
|
end;
|
|
|
|
Procedure TMainIDE.mnuBuildAllProjectClicked(Sender : TObject);
|
|
Begin
|
|
DoBuildProject(true);
|
|
end;
|
|
|
|
Procedure TMainIDE.mnuRunProjectClicked(Sender : TObject);
|
|
begin
|
|
DoRunProject;
|
|
end;
|
|
|
|
Procedure TMainIDE.mnuPauseProjectClicked(Sender : TObject);
|
|
begin
|
|
DebugBoss.DoPauseProject;
|
|
end;
|
|
|
|
Procedure TMainIDE.mnuStepIntoProjectClicked(Sender : TObject);
|
|
begin
|
|
DebugBoss.DoStepIntoProject;
|
|
end;
|
|
|
|
Procedure TMainIDE.mnuStepOverProjectClicked(Sender : TObject);
|
|
begin
|
|
DebugBoss.DoStepOverProject;
|
|
end;
|
|
|
|
Procedure TMainIDE.mnuRunToCursorProjectClicked(Sender : TObject);
|
|
begin
|
|
DebugBoss.DoRunToCursor;
|
|
end;
|
|
|
|
Procedure TMainIDE.mnuStopProjectClicked(Sender : TObject);
|
|
begin
|
|
DebugBoss.DoStopProject;
|
|
end;
|
|
|
|
procedure TMainIDE.mnuProjectCompilerSettingsClicked(Sender : TObject);
|
|
var frmCompilerOptions:TfrmCompilerOptions;
|
|
begin
|
|
frmCompilerOptions:=TfrmCompilerOptions.Create(Application);
|
|
try
|
|
frmCompilerOptions.CompilerOpts:=Project1.CompilerOptions;
|
|
frmCompilerOptions.GetCompilerOptions;
|
|
frmCompilerOptions.OtherSourcePath:=Project1.SrcPath;
|
|
if frmCompilerOptions.ShowModal=mrOk then begin
|
|
Project1.SrcPath:=frmCompilerOptions.OtherSourcePath;
|
|
CreateProjectDefineTemplate(Project1.CompilerOptions,Project1.SrcPath);
|
|
end;
|
|
finally
|
|
frmCompilerOptions.Free;
|
|
end;
|
|
end;
|
|
|
|
procedure TMainIDE.mnuRunParametersClicked(Sender : TObject);
|
|
begin
|
|
ShowRunParamsOptsDlg(Project1.RunParameterOptions);
|
|
end;
|
|
|
|
//------------------------------------------------------------------------------
|
|
|
|
procedure TMainIDE.mnuToolConfigureClicked(Sender : TObject);
|
|
begin
|
|
if ShowExtToolDialog(EnvironmentOptions.ExternalTools,MacroList)=mrOk then
|
|
begin
|
|
// save to enviroment options
|
|
SaveDesktopSettings(EnvironmentOptions);
|
|
EnvironmentOptions.Save(false);
|
|
// save shortcuts to editor options
|
|
EnvironmentOptions.ExternalTools.SaveShortCuts(EditorOpts.KeyMap);
|
|
EditorOpts.Save;
|
|
SourceNotebook.ReloadEditorOptions;
|
|
|
|
// ToDo: update menu
|
|
|
|
end;
|
|
end;
|
|
|
|
procedure TMainIDE.mnuToolSyntaxCheckClicked(Sender : TObject);
|
|
begin
|
|
DoCheckSyntax;
|
|
end;
|
|
|
|
procedure TMainIDE.mnuToolGuessUnclosedBlockClicked(Sender : TObject);
|
|
begin
|
|
DoJumpToGuessedUnclosedBlock(true);
|
|
end;
|
|
|
|
procedure TMainIDE.mnuToolGuessMisplacedIFDEFClicked(Sender : TObject);
|
|
begin
|
|
DoJumpToGuessedMisplacedIFDEF(true);
|
|
end;
|
|
|
|
procedure TMainIDE.mnuToolConvertDFMtoLFMClicked(Sender : TObject);
|
|
begin
|
|
DoConvertDFMtoLFM;
|
|
end;
|
|
|
|
procedure TMainIDE.mnuToolBuildLazarusClicked(Sender : TObject);
|
|
begin
|
|
DoBuildLazarus;
|
|
end;
|
|
|
|
procedure TMainIDE.mnuToolConfigBuildLazClicked(Sender : TObject);
|
|
begin
|
|
if ShowConfigureBuildLazarusDlg(MiscellaneousOptions.BuildLazOpts)=mrOk then
|
|
MiscellaneousOptions.Save;
|
|
end;
|
|
|
|
//------------------------------------------------------------------------------
|
|
|
|
procedure TMainIDE.SaveDesktopSettings(
|
|
TheEnvironmentOptions: TEnvironmentOptions);
|
|
begin
|
|
with TheEnvironmentOptions do begin
|
|
IDEWindowLayoutList.StoreWindowPositions;
|
|
ObjectInspectorOptions.Assign(ObjectInspector1);
|
|
end;
|
|
end;
|
|
|
|
procedure TMainIDE.LoadDesktopSettings(
|
|
TheEnvironmentOptions: TEnvironmentOptions);
|
|
begin
|
|
with TheEnvironmentOptions do begin
|
|
ObjectInspectorOptions.AssignTo(ObjectInspector1);
|
|
end;
|
|
end;
|
|
|
|
procedure TMainIDE.UpdateDefaultPascalFileExtensions;
|
|
var nut: TNewUnitType;
|
|
npt: TProjectType;
|
|
DefPasExt: string;
|
|
begin
|
|
// change default pascal file extensions
|
|
DefPasExt:=PascalExtension[EnvironmentOptions.PascalFileExtension];
|
|
for nut:=Low(TNewUnitType) to High(TNewUnitType) do
|
|
if (UnitTypeDefaultExt[nut]='.pas') or (UnitTypeDefaultExt[nut]='.pp')
|
|
then UnitTypeDefaultExt[nut]:=DefPasExt;
|
|
for npt:=Low(TProjectType) to High(TProjectType) do
|
|
if (ProjectDefaultExt[npt]='.pas') or (ProjectDefaultExt[npt]='.pp')
|
|
then ProjectDefaultExt[npt]:=DefPasExt;
|
|
end;
|
|
|
|
function TMainIDE.CreateSrcEditPageName(const AnUnitName, AFilename: string;
|
|
IgnorePageIndex: integer): string;
|
|
begin
|
|
Result:=AnUnitName;
|
|
if Result='' then
|
|
Result:=AFilename;
|
|
if FilenameIsPascalUnit(Result) then
|
|
Result:=ExtractFileNameOnly(Result)
|
|
else
|
|
Result:=ExtractFileName(Result);
|
|
Result:=SourceNoteBook.FindUniquePageName(Result,IgnorePageIndex);
|
|
end;
|
|
|
|
function TMainIDE.DoConvertDFMFileToLFMFile(const DFMFilename: string
|
|
): TModalResult;
|
|
var DFMStream, LFMStream: TMemoryStream;
|
|
LFMFilename: string;
|
|
begin
|
|
Result:=mrOk;
|
|
DFMStream:=TMemoryStream.Create;
|
|
LFMStream:=TMemoryStream.Create;
|
|
try
|
|
try
|
|
DFMStream.LoadFromFile(DFMFilename);
|
|
except
|
|
on E: Exception do begin
|
|
Result:=MessageDlg('Read error','Unable to read file "'+DFMFilename+'"'#13
|
|
+'Error: '+E.Message,
|
|
mtError,[mbIgnore,mbAbort],0);
|
|
exit;
|
|
end;
|
|
end;
|
|
try
|
|
FormDataToText(DFMStream,LFMStream);
|
|
except
|
|
on E: Exception do begin
|
|
Result:=MessageDlg('Format error',
|
|
'Unable to convert file "'+DFMFilename+'"'#13
|
|
+'Error: '+E.Message,
|
|
mtError,[mbIgnore,mbAbort],0);
|
|
exit;
|
|
end;
|
|
end;
|
|
LFMFilename:=ChangeFileExt(DFMFilename,'.lfm');
|
|
try
|
|
LFMStream.SaveToFile(LFMFilename);
|
|
except
|
|
on E: Exception do begin
|
|
Result:=MessageDlg('Write error',
|
|
'Unable to write file "'+LFMFilename+'"'#13
|
|
+'Error: '+E.Message,
|
|
mtError,[mbIgnore,mbAbort],0);
|
|
exit;
|
|
end;
|
|
end;
|
|
finally
|
|
LFMSTream.Free;
|
|
DFMStream.Free;
|
|
end;
|
|
end;
|
|
|
|
procedure TMainIDE.OnLoadEnvironmentSettings(Sender: TObject;
|
|
TheEnvironmentOptions: TEnvironmentOptions);
|
|
begin
|
|
LoadDesktopSettings(TheEnvironmentOptions);
|
|
end;
|
|
|
|
procedure TMainIDE.OnSaveEnvironmentSettings(Sender: TObject;
|
|
TheEnvironmentOptions: TEnvironmentOptions);
|
|
begin
|
|
SaveDesktopSettings(TheEnvironmentOptions);
|
|
end;
|
|
|
|
procedure TMainIDE.mnuEnvGeneralOptionsClicked(Sender : TObject);
|
|
var EnvironmentOptionsDialog: TEnvironmentOptionsDialog;
|
|
MacroValueChanged, FPCSrcDirChanged, FPCCompilerChanged: boolean;
|
|
OldCompilerFilename, CompilerUnitSearchPath, CompilerUnitLinks: string;
|
|
CompilerTemplate, FPCSrcTemplate: TDefineTemplate;
|
|
|
|
procedure ChangeMacroValue(const MacroName, NewValue: string);
|
|
begin
|
|
with CodeToolBoss.GlobalValues do begin
|
|
if Variables[ExternalMacroStart+MacroName]=NewValue then exit;
|
|
FPCSrcDirChanged:=FPCSrcDirChanged or (Macroname='FPCSrcDir');
|
|
Variables[ExternalMacroStart+MacroName]:=NewValue;
|
|
end;
|
|
MacroValueChanged:=true;
|
|
end;
|
|
|
|
procedure RescanCompilerDefines;
|
|
begin
|
|
// rescan compiler defines
|
|
// ask the compiler for its settings
|
|
CompilerTemplate:=CodeToolBoss.DefinePool.CreateFPCTemplate(
|
|
EnvironmentOptions.CompilerFilename,CompilerUnitSearchPath);
|
|
if CompilerTemplate<>nil then begin
|
|
CodeToolBoss.DefineTree.ReplaceRootSameNameAddFirst(CompilerTemplate);
|
|
// create compiler macros to simulate the Makefiles of the FPC sources
|
|
FPCSrcTemplate:=CodeToolBoss.DefinePool.CreateFPCSrcTemplate(
|
|
CodeToolBoss.GlobalValues.Variables[ExternalMacroStart+'FPCSrcDir'],
|
|
CompilerUnitSearchPath, false, CompilerUnitLinks);
|
|
if FPCSrcTemplate<>nil then begin
|
|
CodeToolBoss.DefineTree.RemoveRootDefineTemplateByName(
|
|
FPCSrcTemplate.Name);
|
|
FPCSrcTemplate.InsertBehind(CompilerTemplate);
|
|
end else begin
|
|
MessageDlg(lisFPCSourceDirectoryError,
|
|
lisPLzCheckTheFPCSourceDirectory,
|
|
mtError,[mbOk],0);
|
|
end;
|
|
// save unitlinks
|
|
InputHistories.SetLastFPCUnitLinks(
|
|
EnvironmentOptions.CompilerFilename,
|
|
CompilerUnitSearchPath,CompilerUnitLinks);
|
|
InputHistories.Save;
|
|
end else begin
|
|
MessageDlg(lisCompilerError,lisPlzCheckTheCmpilerName,
|
|
mtError,[mbOk],0);
|
|
end;
|
|
end;
|
|
|
|
Begin
|
|
EnvironmentOptionsDialog:=TEnvironmentOptionsDialog.Create(Application);
|
|
try
|
|
// update EnvironmentOptions (save current window positions)
|
|
SaveDesktopSettings(EnvironmentOptions);
|
|
with EnvironmentOptionsDialog do begin
|
|
OnLoadEnvironmentSettings:=@Self.OnLoadEnvironmentSettings;
|
|
OnSaveEnvironmentSettings:=@Self.OnSaveEnvironmentSettings;
|
|
// load settings from EnvironmentOptions to EnvironmentOptionsDialog
|
|
ReadSettings(EnvironmentOptions);
|
|
end;
|
|
if EnvironmentOptionsDialog.ShowModal=mrOk then begin
|
|
// load settings from EnvironmentOptionsDialog to EnvironmentOptions
|
|
OldCompilerFilename:=EnvironmentOptions.CompilerFilename;
|
|
EnvironmentOptionsDialog.WriteSettings(EnvironmentOptions);
|
|
UpdateDefaultPascalFileExtensions;
|
|
// set global variables
|
|
MacroValueChanged:=false;
|
|
FPCSrcDirChanged:=false;
|
|
FPCCompilerChanged:=
|
|
OldCompilerFilename<>EnvironmentOptions.CompilerFilename;
|
|
ChangeMacroValue('LazarusDir',EnvironmentOptions.LazarusDirectory);
|
|
ChangeMacroValue('FPCSrcDir',EnvironmentOptions.FPCSourceDirectory);
|
|
|
|
if MacroValueChanged then CodeToolBoss.DefineTree.ClearCache;
|
|
if FPCCompilerChanged or FPCSrcDirChanged then begin
|
|
RescanCompilerDefines;
|
|
end;
|
|
|
|
// save to disk
|
|
EnvironmentOptions.Save(false);
|
|
|
|
// update designer
|
|
InvalidateAllDesignerForms;
|
|
end;
|
|
finally
|
|
EnvironmentOptionsDialog.Free;
|
|
end;
|
|
End;
|
|
|
|
procedure TMainIDE.mnuEnvEditorOptionsClicked(Sender : TObject);
|
|
var EditorOptionsForm: TEditorOptionsForm;
|
|
Begin
|
|
EditorOptionsForm:=TEditorOptionsForm.Create(Application);
|
|
try
|
|
if EditorOptionsForm.ShowModal=mrOk then begin
|
|
SourceNotebook.ReloadEditorOptions;
|
|
LoadMenuShortCuts;
|
|
end;
|
|
finally
|
|
EditorOptionsForm.Free;
|
|
end;
|
|
End;
|
|
|
|
procedure TMainIDE.mnuEnvCodeToolsOptionsClicked(Sender : TObject);
|
|
begin
|
|
ShowCodeToolsOptions(CodeToolsOpts,@SourceNoteBook.GetSynEditPreviewSettings);
|
|
end;
|
|
|
|
procedure TMainIDE.mnuEnvCodeToolsDefinesEditorClicked(Sender : TObject);
|
|
begin
|
|
ShowCodeToolsDefinesEditor(CodeToolBoss,CodeToolsOpts,MacroList);
|
|
end;
|
|
|
|
procedure TMainIDE.SaveEnvironment;
|
|
begin
|
|
SaveDesktopSettings(EnvironmentOptions);
|
|
EnvironmentOptions.Save(false);
|
|
end;
|
|
//------------------------------------------------------------------------------
|
|
|
|
procedure TMainIDE.mnuHelpAboutLazarusClicked(Sender : TObject);
|
|
begin
|
|
ShowAboutForm;
|
|
end;
|
|
|
|
//------------------------------------------------------------------------------
|
|
|
|
Procedure TMainIDE.MessageViewDblClick(Sender : TObject);
|
|
Begin
|
|
|
|
end;
|
|
|
|
//==============================================================================
|
|
|
|
function TMainIDE.CreateNewCodeBuffer(NewUnitType:TNewUnitType;
|
|
NewFilename: string;
|
|
var NewCodeBuffer: TCodeBuffer; var NewUnitName: string): TModalResult;
|
|
begin
|
|
if NewFilename='' then begin
|
|
NewUnitName:=Project1.NewUniqueUnitName(NewUnitType);
|
|
NewCodeBuffer:=CodeToolBoss.CreateFile(
|
|
NewUnitName+UnitTypeDefaultExt[NewUnitType]);
|
|
end else begin
|
|
NewUnitName:=ExtractFileNameOnly(NewFilename);
|
|
if FilenameIsPascalUnit(NewFilename) then begin
|
|
if EnvironmentOptions.PascalFileLowerCase then
|
|
NewFilename:=ExtractFilePath(NewFilename)
|
|
+lowercase(ExtractFileName(NewFilename));
|
|
end;
|
|
NewCodeBuffer:=CodeToolBoss.CreateFile(NewFilename);
|
|
end;
|
|
if NewCodeBuffer<>nil then
|
|
Result:=mrOk
|
|
else
|
|
Result:=mrCancel;
|
|
end;
|
|
|
|
function TMainIDE.CreateNewForm(NewUnitInfo: TUnitInfo): TModalResult;
|
|
var
|
|
NewForm: TCustomForm;
|
|
ResourceCode: TCodeBuffer;
|
|
CInterface : TComponentInterface;
|
|
begin
|
|
// create a buffer for the new resource file and for the LFM file
|
|
ResourceCode:=
|
|
CodeToolBoss.CreateFile(ChangeFileExt(NewUnitInfo.Filename,ResourceFileExt));
|
|
ResourceCode.Source:=lisResourceFileComment;
|
|
CodeToolBoss.CreateFile(ChangeFileExt(NewUnitInfo.Filename,'.lfm'));
|
|
|
|
// clear formeditor
|
|
if not Assigned(FormEditor1) then
|
|
FormEditor1 := TFormEditor.Create;
|
|
FormEditor1.ClearSelected;
|
|
|
|
// create jitform
|
|
CInterface := TComponentInterface(
|
|
FormEditor1.CreateComponent(nil,TForm,
|
|
ObjectInspector1.Left+ObjectInspector1.Width+60,Top+Height+80,400,300));
|
|
FormEditor1.SetFormNameAndClass(CInterface,
|
|
NewUnitInfo.FormName,'T'+NewUnitInfo.FormName);
|
|
NewForm:=TForm(CInterface.Control);
|
|
NewUnitInfo.Form:=NewForm;
|
|
SetDefaultsForForm(NewForm);
|
|
|
|
NewUnitInfo.FormName:=NewForm.Name;
|
|
if NewUnitInfo.IsPartOfProject then
|
|
Project1.AddCreateFormToProjectFile(NewForm.ClassName,NewForm.Name);
|
|
|
|
Result:=mrOk;
|
|
end;
|
|
|
|
procedure TMainIDE.ShowDesignForm(AForm: TCustomForm);
|
|
begin
|
|
// show form
|
|
AForm.Show;
|
|
SetDesigning(AForm,True);
|
|
FCodeLastActivated:=false;
|
|
|
|
// select the new form (object inspector, formeditor, control selection)
|
|
PropertyEditorHook1.LookupRoot := AForm;
|
|
TDesigner(AForm.Designer).SelectOnlyThisComponent(AForm);
|
|
BringWindowToTop(AForm.Handle);
|
|
end;
|
|
|
|
function TMainIDE.DoLoadResourceFile(AnUnitInfo: TUnitInfo;
|
|
var LFMCode, ResourceCode: TCodeBuffer;
|
|
IgnoreSourceErrors: boolean): TModalResult;
|
|
var LinkIndex: integer;
|
|
LFMFilename, MsgTxt: string;
|
|
begin
|
|
LFMCode:=nil;
|
|
ResourceCode:=nil;
|
|
if AnUnitInfo.HasResources then begin
|
|
// first try to find the resource file via the unit source
|
|
LinkIndex:=-1;
|
|
ResourceCode:=CodeToolBoss.FindNextResourceFile(
|
|
AnUnitInfo.Source,LinkIndex);
|
|
// if unit source has errors, then try the last resource file
|
|
if (ResourceCode=nil) then begin
|
|
if not IgnoreSourceErrors then
|
|
DoJumpToCodeToolBossError;
|
|
if (AnUnitInfo.ResourceFileName<>'')
|
|
then begin
|
|
Result:=DoLoadCodeBuffer(ResourceCode,AnUnitInfo.ResourceFileName,
|
|
[lbfCheckIfText]);
|
|
if Result=mrAbort then exit;
|
|
end;
|
|
end;
|
|
// if no resource file found then tell the user
|
|
if (ResourceCode=nil) and (not IgnoreSourceErrors)
|
|
then begin
|
|
MsgTxt:='Unable to load old resource file.'#13
|
|
+'The resource file is the first include file in the'#13
|
|
+'initialization section.'#13
|
|
+'For example {$I '+AnUnitInfo.UnitName+'.lrs}.'#13
|
|
+'Probably a syntax error.';
|
|
Result:=MessageDlg('Resource load error',MsgTxt,mtWarning,
|
|
[mbIgnore,mbAbort],0);
|
|
if Result=mrAbort then exit;
|
|
end;
|
|
// load lfm file
|
|
if (not AnUnitInfo.IsVirtual) and (AnUnitInfo.Form<>nil) then begin
|
|
LFMFilename:=ChangeFileExt(AnUnitInfo.Filename,'.lfm');
|
|
if (FileExists(LFMFilename)) then begin
|
|
Result:=DoLoadCodeBuffer(LFMCode,LFMFilename,[lbfCheckIfText]);
|
|
if not (Result in [mrOk,mrIgnore]) then exit;
|
|
end;
|
|
end;
|
|
end;
|
|
Result:=mrOk;
|
|
end;
|
|
|
|
function TMainIDE.DoShowSaveFileAsDialog(AnUnitInfo: TUnitInfo;
|
|
var ResourceCode: TCodeBuffer): TModalResult;
|
|
var
|
|
SaveDialog: TSaveDialog;
|
|
SaveAsFilename, SaveAsFileExt, NewFilename, NewUnitName, NewFilePath,
|
|
NewResFilename, NewResFilePath, OldFilePath, NewLFMFilename,
|
|
AlternativeUnitName: string;
|
|
ACaption, AText: string;
|
|
SrcEdit: TSourceEditor;
|
|
NewSource: TCodeBuffer;
|
|
NewHighlighter: TLazSyntaxHighlighter;
|
|
begin
|
|
SrcEdit:=GetSourceEditorForUnitInfo(AnUnitInfo);
|
|
OldFilePath:=ExtractFilePath(AnUnitInfo.Filename);
|
|
|
|
// try to keep the old filename and extension
|
|
SaveAsFileExt:=ExtractFileExt(AnUnitInfo.FileName);
|
|
if SaveAsFileExt='' then begin
|
|
if SrcEdit.SyntaxHighlighterType in [lshFreePascal, lshDelphi]
|
|
then
|
|
SaveAsFileExt:=PascalExtension[EnvironmentOptions.PascalFileExtension]
|
|
else
|
|
SaveAsFileExt:=EditorOpts.HighlighterList.GetDefaultFilextension(
|
|
SrcEdit.SyntaxHighlighterType);
|
|
end;
|
|
AnUnitInfo.ReadUnitNameFromSource;
|
|
SaveAsFilename:=AnUnitInfo.UnitName;
|
|
if SaveAsFilename='' then
|
|
SaveAsFilename:=ExtractFileNameOnly(AnUnitInfo.Filename);
|
|
if SaveAsFilename='' then
|
|
SaveAsFilename:='noname';
|
|
|
|
// let user choose a filename
|
|
SaveDialog:=TSaveDialog.Create(Application);
|
|
try
|
|
// show save dialog
|
|
InputHistories.ApplyFileDialogSettings(SaveDialog);
|
|
SaveDialog.Title:=lisSaveSpace+SaveAsFilename+' (*'+SaveAsFileExt+')';
|
|
SaveDialog.FileName:=SaveAsFilename+SaveAsFileExt;
|
|
if not SaveDialog.Execute then begin
|
|
// user cancels
|
|
Result:=mrCancel;
|
|
exit;
|
|
end;
|
|
NewFilename:=ExpandFilename(SaveDialog.Filename);
|
|
finally
|
|
InputHistories.StoreFileDialogSettings(SaveDialog);
|
|
SaveDialog.Free;
|
|
end;
|
|
|
|
// check unitname
|
|
if FilenameIsPascalUnit(NewFilename) then begin
|
|
NewUnitName:=ExtractFileNameOnly(NewFilename);
|
|
if NewUnitName='' then begin
|
|
Result:=mrCancel;
|
|
exit;
|
|
end;
|
|
if not IsValidIdent(NewUnitName) then begin
|
|
AlternativeUnitName:=NameToValidIdentifier(NewUnitName);
|
|
Result:=MessageDlg(lsiInvalidPascalIdentifierCap,
|
|
Format(lsiInvalidPascalIdentifierText,[NewUnitName,AlternativeUnitName]),
|
|
mtWarning,[mbIgnore,mbCancel],0);
|
|
if Result=mrCancel then exit;
|
|
NewUnitName:=AlternativeUnitName;
|
|
Result:=mrCancel;
|
|
end;
|
|
if Project1.IndexOfUnitWithName(NewUnitName,true,AnUnitInfo)>=0 then
|
|
begin
|
|
Result:=MessageDlg(lsiUnitNameAlreadyExistsCap,
|
|
Format(lsiUnitNameAlreadyExistsText,[NewUnitName]),
|
|
mtConfirmation,[mbIgnore,mbCancel,mbAbort],0);
|
|
if Result=mrIgnore then
|
|
Result:=mrCancel
|
|
else
|
|
exit;
|
|
end;
|
|
end else begin
|
|
NewUnitName:='';
|
|
end;
|
|
|
|
// check file extension
|
|
if ExtractFileExt(NewFilename)='' then begin
|
|
NewFilename:=NewFilename+SaveAsFileExt;
|
|
end;
|
|
|
|
// check filename
|
|
if EnvironmentOptions.PascalFileLowerCase
|
|
and FilenameIsPascalUnit(NewFilename)
|
|
then
|
|
NewFileName:=ExtractFilePath(NewFilename)
|
|
+lowercase(ExtractFileName(NewFilename));
|
|
if FileExists(NewFilename) then begin
|
|
ACaption:='Overwrite file?';
|
|
AText:='A file "'+NewFilename+'" already exists.'#13'Replace it?';
|
|
Result:=MessageDlg(ACaption, AText, mtConfirmation,[mbok,mbCancel],0);
|
|
if Result=mrCancel then exit;
|
|
end;
|
|
|
|
// check file path
|
|
NewFilePath:=ExtractFilePath(NewFilename);
|
|
if not DirectoryExists(NewFilePath) then begin
|
|
ACaption:='Directory not found';
|
|
AText:='The destination directory'#13+
|
|
'"'+NewFilePath+'" does not exist.';
|
|
Result:=MessageDlg(ACaption, AText, mtConfirmation,[mbCancel],0);
|
|
exit;
|
|
end;
|
|
|
|
// check new resource file
|
|
if AnUnitInfo.FormName='' then begin
|
|
// unit has no form
|
|
// -> remove lfm file, so that it will not be auto loaded on next open
|
|
NewLFMFilename:=ChangeFileExt(NewFilename,'.lfm');
|
|
if (FileExists(NewLFMFilename))
|
|
and (not DeleteFile(NewLFMFilename))
|
|
and (MessageDlg('Delete failed','Deleting of file "'+NewLFMFilename+'"'
|
|
+' failed.',mtError,[mbIgnore,mbCancel],0)=mrCancel) then
|
|
begin
|
|
Result:=mrCancel;
|
|
exit;
|
|
end;
|
|
end;
|
|
|
|
// save source in the new position
|
|
if not CodeToolBoss.SaveBufferAs(AnUnitInfo.Source,NewFilename,NewSource)
|
|
then begin
|
|
Result:=mrCancel;
|
|
exit;
|
|
end;
|
|
// get final filename
|
|
NewFilename:=NewSource.Filename;
|
|
NewFilePath:=ExtractFilePath(NewFilename);
|
|
EnvironmentOptions.AddToRecentOpenFiles(NewFilename);
|
|
SetRecentFilesMenu;
|
|
|
|
// rename Resource file
|
|
if (ResourceCode<>nil) then begin
|
|
// the resource include line in the code will be changed later after
|
|
// changing the unitname
|
|
NewResFilePath:=ExtractFilePath(ResourceCode.Filename);
|
|
if FilenameIsAbsolute(OldFilePath)
|
|
and (OldFilePath=copy(NewResFilePath,1,length(OldFilePath))) then
|
|
begin
|
|
// resource code was in the same or in a sub directory of source
|
|
// -> try to keep this relationship
|
|
NewResFilePath:=NewFilePath
|
|
+copy(ResourceCode.Filename,length(OldFilePath)+1,
|
|
length(ResourceCode.Filename));
|
|
if not DirectoryExists(NewResFilePath) then
|
|
NewResFilePath:=NewFilePath;
|
|
end else begin
|
|
// resource code was not in the same or in a sub dircetoy of source
|
|
// copy resource into the same directory as the source
|
|
NewResFilePath:=NewFilePath;
|
|
end;
|
|
NewResFilename:=NewResFilePath
|
|
+ExtractFileNameOnly(NewFilename)+ResourceFileExt;
|
|
CodeToolBoss.SaveBufferAs(ResourceCode,NewResFilename,ResourceCode);
|
|
if ResourceCode<>nil then
|
|
AnUnitInfo.ResourceFileName:=ResourceCode.Filename;
|
|
|
|
{$IFDEF IDE_DEBUG}
|
|
writeln('TMainIDE.ShowSaveFileAsDialog D ',ResourceCode<>nil);
|
|
writeln(' NewResFilePath="',NewResFilePath,'" NewResFilename="',NewresFilename,'"');
|
|
if ResourceCode<>nil then writeln('*** ResourceFileName ',ResourceCode.Filename);
|
|
{$ENDIF}
|
|
end else begin
|
|
NewResFilename:='';
|
|
end;
|
|
{$IFDEF IDE_DEBUG}
|
|
writeln('TMainIDE.ShowSaveFileAsDialog C ',ResourceCode<>nil);
|
|
{$ENDIF}
|
|
|
|
// set new codebuffer in unitinfo and sourceeditor
|
|
AnUnitInfo.Source:=NewSource;
|
|
AnUnitInfo.Modified:=false;
|
|
SrcEdit.CodeBuffer:=NewSource; // the code is not changed,
|
|
// therefore the marks are kept
|
|
|
|
// change unitname in project and in source
|
|
AnUnitInfo.UnitName:=NewUnitName;
|
|
if ResourceCode<>nil then begin
|
|
// change resource filename in the source include directive
|
|
CodeToolBoss.RenameMainInclude(AnUnitInfo.Source,
|
|
ExtractRelativePath(NewFilePath,NewResFilename),false);
|
|
end;
|
|
|
|
// change unitname on SourceNotebook
|
|
if AnUnitInfo.EditorIndex>=0 then
|
|
SourceNoteBook.NoteBook.Pages[AnUnitInfo.EditorIndex]:=
|
|
CreateSrcEditPageName(NewUnitName,NewFilename,
|
|
SourceNoteBook.NoteBook.PageIndex);
|
|
|
|
// change syntax highlighter
|
|
if not AnUnitInfo.CustomHighlighter then begin
|
|
NewHighlighter:=
|
|
ExtensionToLazSyntaxHighlighter(ExtractFileExt(NewFilename));
|
|
if NewHighlighter<>AnUnitInfo.SyntaxHighlighter then begin
|
|
AnUnitInfo.SyntaxHighlighter:=NewHighlighter;
|
|
SrcEdit.SyntaxHighlighterType:=AnUnitInfo.SyntaxHighlighter;
|
|
end;
|
|
end;
|
|
|
|
|
|
Result:=mrOk;
|
|
end;
|
|
|
|
function TMainIDE.DoSaveFileResources(AnUnitInfo: TUnitInfo;
|
|
ResourceCode, LFMCode: TCodeBuffer; Flags: TSaveFlags): TModalResult;
|
|
var
|
|
FormSavingOk: boolean;
|
|
MemStream,BinCompStream,TxtCompStream:TMemoryStream;
|
|
Driver: TAbstractObjectWriter;
|
|
Writer:TWriter;
|
|
ACaption, AText: string;
|
|
CompResourceCode, LFMFilename, TestFilename, ResTestFilename: string;
|
|
begin
|
|
// save lrs - lazarus resource file and lfm - lazarus form text file
|
|
// Note: When there is a bug in the source, no resource code can be found,
|
|
// but the LFM file should always be saved
|
|
if (AnUnitInfo.Form<>nil) then begin
|
|
// stream component to resource code and to lfm file
|
|
FormSavingOk:=true;
|
|
|
|
// stream component to binary stream
|
|
BinCompStream:=TMemoryStream.Create;
|
|
try
|
|
repeat
|
|
try
|
|
BinCompStream.Position:=0;
|
|
Driver:=TBinaryObjectWriter.Create(BinCompStream,4096);
|
|
try
|
|
Writer:=TWriter.Create(Driver);
|
|
try
|
|
Writer.WriteDescendent(AnUnitInfo.Form,nil);
|
|
finally
|
|
Writer.Free;
|
|
end;
|
|
finally
|
|
Driver.Free;
|
|
end;
|
|
except
|
|
ACaption:='Streaming error';
|
|
AText:='Unable to stream '
|
|
+AnUnitInfo.FormName+':T'+AnUnitInfo.FormName+'.';
|
|
Result:=MessageDlg(ACaption, AText, mtError,
|
|
[mbAbort, mbRetry, mbIgnore], 0);
|
|
if Result=mrAbort then exit;
|
|
if Result=mrIgnore then Result:=mrOk;
|
|
FormSavingOk:=false;
|
|
end;
|
|
until Result<>mrRetry;
|
|
// create lazarus form resource code
|
|
if FormSavingOk then begin
|
|
if ResourceCode=nil then begin
|
|
if (sfSaveToTestDir in Flags) then
|
|
ResTestFilename:=ChangeFileExt(GetTestUnitFilename(AnUnitInfo),
|
|
ResourceFileExt)
|
|
else
|
|
ResTestFilename:=ChangeFileExt(AnUnitInfo.Filename,
|
|
ResourceFileExt);
|
|
ResourceCode:=CodeToolBoss.CreateFile(ResTestFilename);
|
|
FormSavingOk:=(ResourceCode<>nil);
|
|
end;
|
|
if FormSavingOk then begin
|
|
// there is no bug in the source, so the resource code should be
|
|
// changed too
|
|
MemStream:=TMemoryStream.Create;
|
|
try
|
|
BinCompStream.Position:=0;
|
|
BinaryToLazarusResourceCode(BinCompStream,MemStream
|
|
,'T'+AnUnitInfo.FormName,'FORMDATA');
|
|
MemStream.Position:=0;
|
|
SetLength(CompResourceCode,MemStream.Size);
|
|
MemStream.Read(CompResourceCode[1],length(CompResourceCode));
|
|
finally
|
|
MemStream.Free;
|
|
end;
|
|
end;
|
|
if FormSavingOk then begin
|
|
{$IFDEF IDE_DEBUG}
|
|
writeln('TMainIDE.SaveFileResources E ',CompResourceCode);
|
|
{$ENDIF}
|
|
// replace lazarus form resource code
|
|
if not (sfSaveToTestDir in Flags) then begin
|
|
if (not CodeToolBoss.AddLazarusResource(ResourceCode,
|
|
'T'+AnUnitInfo.FormName,CompResourceCode)) then
|
|
begin
|
|
ACaption:='Resource save error';
|
|
AText:='Unable to add resource '
|
|
+'T'+AnUnitInfo.FormName+':FORMDATA to resource file '#13
|
|
+'"'+ResourceCode.FileName+'".'#13
|
|
+'Probably a syntax error.';
|
|
Result:=MessageDlg(ACaption, AText, mtError, [mbIgnore, mbAbort],0);
|
|
if Result=mrAbort then exit;
|
|
end else begin
|
|
AnUnitInfo.ResourceFileName:=ResourceCode.Filename;
|
|
end;
|
|
end else begin
|
|
ResourceCode.Source:=CompResourceCode;
|
|
end;
|
|
end;
|
|
if (not (sfSaveToTestDir in Flags)) then begin
|
|
// save lfm file
|
|
LFMFilename:=ChangeFileExt(AnUnitInfo.Filename,'.lfm');
|
|
if LFMCode=nil then begin
|
|
LFMCode:=CodeToolBoss.CreateFile(LFMFilename);
|
|
if LFMCode=nil then begin
|
|
MessageDlg('Unable to create file',
|
|
'Unable to create file "'+LFMFilename+'"',
|
|
mtWarning,[mbIgnore,mbCancel],0);
|
|
end;
|
|
end;
|
|
if LFMCode<>nil then begin
|
|
{$IFDEF IDE_DEBUG}
|
|
writeln('TMainIDE.SaveFileResources E2 LFM=',LFMCode.Filename);
|
|
{$ENDIF}
|
|
repeat
|
|
try
|
|
// transform binary to text
|
|
TxtCompStream:=TMemoryStream.Create;
|
|
try
|
|
BinCompStream.Position:=0;
|
|
ObjectBinaryToText(BinCompStream,TxtCompStream);
|
|
TxtCompStream.Position:=0;
|
|
LFMCode.LoadFromStream(TxtCompStream);
|
|
Result:=DoSaveCodeBufferToFile(LFMCode,LFMCode.Filename,
|
|
AnUnitInfo.IsPartOfProject);
|
|
if not Result=mrOk then exit;
|
|
Result:=mrCancel;
|
|
finally
|
|
TxtCompStream.Free;
|
|
end;
|
|
except
|
|
ACaption:='Streaming error';
|
|
AText:='Unable to transform binary component stream of '
|
|
+AnUnitInfo.FormName+':T'+AnUnitInfo.FormName
|
|
+' into text.';
|
|
Result:=MessageDlg(ACaption, AText, mtError,
|
|
[mbAbort, mbRetry, mbIgnore], 0);
|
|
if Result=mrAbort then exit;
|
|
if Result=mrIgnore then Result:=mrOk;
|
|
end;
|
|
until Result<>mrRetry;
|
|
end;
|
|
end;
|
|
end;
|
|
finally
|
|
BinCompStream.Free;
|
|
end;
|
|
end;
|
|
{$IFDEF IDE_DEBUG}
|
|
if ResourceCode<>nil then
|
|
writeln('TMainIDE.SaveFileResources F ',ResourceCode.Modified);
|
|
{$ENDIF}
|
|
if ResourceCode<>nil then begin
|
|
if not (sfSaveToTestDir in Flags) then begin
|
|
if (ResourceCode.Modified) then begin
|
|
Result:=DoSaveCodeBufferToFile(ResourceCode,ResourceCode.Filename,
|
|
AnUnitInfo.IsPartOfProject);
|
|
if not Result=mrOk then exit;
|
|
end;
|
|
end else begin
|
|
TestFilename:=GetTestUnitFilename(AnUnitInfo);
|
|
Result:=DoSaveCodeBufferToFile(ResourceCode,
|
|
ChangeFileExt(TestFilename,
|
|
ExtractFileExt(ResourceCode.Filename)),
|
|
false);
|
|
if not Result=mrOk then exit;
|
|
end;
|
|
end;
|
|
Result:=mrOk;
|
|
{$IFDEF IDE_DEBUG}
|
|
writeln('TMainIDE.SaveFileResources G ',LFMCode<>nil);
|
|
{$ENDIF}
|
|
end;
|
|
|
|
function TMainIDE.DoOpenNotExistingFile(const AFileName: string;
|
|
Flags: TOpenFlags): TModalResult;
|
|
begin
|
|
if ofProjectLoading in Flags then begin
|
|
// this is a file, that was loaded last time, but was removed from disk
|
|
Result:=MessageDlg('File not found',
|
|
'The file "'+AFilename+'"'#13
|
|
+'was not found.'#13
|
|
+'Ignore will go on loading the project,'#13
|
|
+'Abort will stop the loading.',
|
|
mtError, [mbIgnore, mbAbort], 0);
|
|
exit;
|
|
end;
|
|
|
|
if (not (ofOnlyIfExists in Flags))
|
|
and (MessageDlg('File not found',
|
|
'File "'+AFilename+'" not found.'#13
|
|
+'Do you want to create it?'#13
|
|
,mtInformation,[mbYes,mbNo],0)=mrYes) then
|
|
begin
|
|
// create new file
|
|
if FilenameIsPascalSource(AFilename) then
|
|
Result:=DoNewEditorFile(nuUnit,AFilename)
|
|
else
|
|
Result:=DoNewEditorFile(nuEmpty,AFilename);
|
|
end else if ofOnlyIfExists in Flags then begin
|
|
MessageDlg('File not found','File "'+AFilename+'" not found.'#13,
|
|
mtInformation,[mbCancel],0);
|
|
// cancel loading file
|
|
Result:=mrCancel;
|
|
end else begin
|
|
// cancel loading file
|
|
Result:=mrCancel;
|
|
end;
|
|
end;
|
|
|
|
function TMainIDE.DoOpenUnknownFile(const AFileName: string; Flags: TOpenFlags;
|
|
var NewUnitInfo: TUnitInfo; var Handled: boolean): TModalResult;
|
|
var
|
|
Ext, NewProgramName, LPIFilename, ACaption, AText: string;
|
|
PreReadBuf: TCodeBuffer;
|
|
begin
|
|
Handled:=false;
|
|
Ext:=lowercase(ExtractFileExt(AFilename));
|
|
|
|
if (not (ofProjectLoading in Flags)) and (ToolStatus=itNone)
|
|
and (Ext='.lpi') then begin
|
|
// this is a project info file -> load whole project
|
|
Result:=DoOpenProjectFile(AFilename);
|
|
Handled:=true;
|
|
exit;
|
|
end;
|
|
|
|
// load the source
|
|
Result:=DoLoadCodeBuffer(PreReadBuf,AFileName,
|
|
[lbfCheckIfText,lbfUpdateFromDisk,lbfRevert]);
|
|
if Result<>mrOk then exit;
|
|
NewUnitInfo:=nil;
|
|
|
|
// check if unit is a program
|
|
if (not (ofProjectLoading in Flags))
|
|
and FilenameIsPascalSource(AFilename)
|
|
and (CodeToolBoss.GetSourceType(PreReadBuf,false)='PROGRAM') then begin
|
|
NewProgramName:=CodeToolBoss.GetSourceName(PreReadBuf,false);
|
|
if NewProgramName<>'' then begin
|
|
// source is a program
|
|
// either this is a lazarus project
|
|
// or it is not yet a lazarus project ;)
|
|
LPIFilename:=ChangeFileExt(AFilename,'.lpi');
|
|
if FileExists(LPIFilename) then begin
|
|
AText:='The file "'+AFilename+'"'#13
|
|
+'seems to be the program file of an existing lazarus Project1.'#13
|
|
+'Open project?'#13
|
|
+'Cancel will load the file as normal source.';
|
|
ACaption:='Project info file detected';
|
|
if MessageDlg(ACaption, AText, mtconfirmation,
|
|
[mbok, mbcancel], 0)=mrOk then
|
|
begin
|
|
Result:=DoOpenProjectFile(LPIFilename);
|
|
Handled:=true;
|
|
exit;
|
|
end;
|
|
end else begin
|
|
AText:='The file "'+AFilename+'"'#13
|
|
+'seems to be a program. Close current project'
|
|
+' and create a new lazarus project for this program?'#13
|
|
+'Cancel will load the file as normal source.';
|
|
ACaption:='Program detected';
|
|
if MessageDlg(ACaption, AText, mtConfirmation,
|
|
[mbOk, mbCancel], 0)=mrOk then
|
|
begin
|
|
Result:=DoCreateProjectForProgram(PreReadBuf);
|
|
Handled:=true;
|
|
exit;
|
|
end;
|
|
end;
|
|
end;
|
|
end;
|
|
NewUnitInfo:=TUnitInfo.Create(PreReadBuf);
|
|
if FilenameIsPascalSource(NewUnitInfo.Filename) then
|
|
NewUnitInfo.ReadUnitNameFromSource;
|
|
Project1.AddUnit(NewUnitInfo,false);
|
|
Result:=mrOk;
|
|
end;
|
|
|
|
procedure TMainIDE.DoRestoreBookMarks(AnUnitInfo: TUnitInfo;
|
|
ASrcEdit: TSourceEditor);
|
|
var BookmarkID, i: integer;
|
|
begin
|
|
for BookmarkID:=0 to 9 do begin
|
|
i:=Project1.Bookmarks.IndexOfID(BookmarkID);
|
|
if (i>=0) and (Project1.Bookmarks[i].EditorIndex=AnUnitInfo.EditorIndex)
|
|
then begin
|
|
ASrcEdit.EditorComponent.SetBookmark(BookmarkID,
|
|
Project1.Bookmarks[i].CursorPos.X,Project1.Bookmarks[i].CursorPos.Y);
|
|
while i>=0 do begin
|
|
Project1.Bookmarks.Delete(i);
|
|
i:=Project1.Bookmarks.IndexOfID(BookmarkID);
|
|
end;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
function TMainIDE.DoLoadLFM(AnUnitInfo: TUnitInfo;
|
|
Flags: TOpenFlags): TModalResult;
|
|
var
|
|
LFMFilename, ACaption, AText: string;
|
|
LFMBuf: TCodeBuffer;
|
|
FormLoadingOk: boolean;
|
|
TxtLFMStream, BinLFMStream:TMemoryStream;
|
|
CInterface: TComponentInterface;
|
|
TempForm: TCustomForm;
|
|
begin
|
|
CloseDesignerForm(AnUnitInfo);
|
|
|
|
LFMFilename:=ChangeFileExt(AnUnitInfo.Filename,'.lfm');
|
|
LFMBuf:=nil;
|
|
if FileExists(LFMFilename) then begin
|
|
Result:=DoLoadCodeBuffer(LFMBuf,LFMFilename,[lbfUpdateFromDisk]);
|
|
if Result<>mrOk then exit;
|
|
end;
|
|
FormLoadingOk:=(LFMBuf<>nil);
|
|
|
|
if FormLoadingOk then begin
|
|
// there is a lazarus form text file -> load it
|
|
BinLFMStream:=TMemoryStream.Create;
|
|
try
|
|
TxtLFMStream:=TMemoryStream.Create;
|
|
try
|
|
LFMBuf.SaveToStream(TxtLFMStream);
|
|
TxtLFMStream.Position:=0;
|
|
// convert text to binary format
|
|
try
|
|
ObjectTextToBinary(TxtLFMStream,BinLFMStream);
|
|
BinLFMStream.Position:=0;
|
|
Result:=mrOk;
|
|
except
|
|
on E: Exception do begin
|
|
ACaption:='Format error';
|
|
AText:='Unable to convert text form data of file '#13
|
|
+'"'+LFMBuf.Filename+'"'#13
|
|
+'into binary stream. ('+E.Message+')';
|
|
Result:=MessageDlg(ACaption, AText, mtError, [mbOk, mbCancel], 0);
|
|
if Result=mrCancel then Result:=mrAbort;
|
|
if Result<>mrOk then exit;
|
|
FormLoadingOk:=false;
|
|
end;
|
|
end;
|
|
finally
|
|
TxtLFMStream.Free;
|
|
end;
|
|
if FormLoadingOk then begin
|
|
if not Assigned(FormEditor1) then
|
|
FormEditor1 := TFormEditor.Create;
|
|
if not (ofProjectLoading in Flags) then FormEditor1.ClearSelected;
|
|
|
|
// create jitform
|
|
CInterface := TComponentInterface(
|
|
FormEditor1.CreateFormFromStream(BinLFMStream));
|
|
if CInterface=nil then begin
|
|
ACaption:='Form load error';
|
|
AText:='Unable to build form from file '#13
|
|
+'"'+LFMBuf.Filename+'".';
|
|
Result:=MessageDlg(ACaption, AText, mterror, [mbok, mbcancel], 0);
|
|
if Result=mrCancel then Result:=mrAbort;
|
|
if Result<>mrOk then exit;
|
|
TempForm:=nil;
|
|
AnUnitInfo.Form:=TempForm;
|
|
end else begin
|
|
TempForm:=TForm(CInterface.Control);
|
|
AnUnitInfo.Form:=TempForm;
|
|
SetDefaultsForForm(TempForm);
|
|
AnUnitInfo.FormName:=TempForm.Name;
|
|
// show form
|
|
TDesigner(TempForm.Designer).SourceEditor:=
|
|
SourceNoteBook.GetActiveSE;
|
|
|
|
if not (ofProjectLoading in Flags) then begin
|
|
TempForm.Show;
|
|
FCodeLastActivated:=false;
|
|
end;
|
|
SetDesigning(TempForm,True);
|
|
|
|
// select the new form (object inspector, formeditor, control selection)
|
|
if not (ofProjectLoading in Flags) then begin
|
|
PropertyEditorHook1.LookupRoot := TempForm;
|
|
TDesigner(TempForm.Designer).SelectOnlyThisComponent(TempForm);
|
|
end;
|
|
FLastFormActivated:=TempForm;
|
|
end;
|
|
end;
|
|
{$IFDEF IDE_DEBUG}
|
|
writeln('[TMainIDE.DoLoadLFM] LFM end');
|
|
{$ENDIF}
|
|
finally
|
|
BinLFMStream.Free;
|
|
end;
|
|
end;
|
|
Result:=mrOk;
|
|
end;
|
|
|
|
{-------------------------------------------------------------------------------
|
|
function TMainIDE.CloseDesignerForm
|
|
|
|
Params: AnUnitInfo: TUnitInfo
|
|
Result: TModalResult;
|
|
|
|
Free the designer form of a unit.
|
|
-------------------------------------------------------------------------------}
|
|
function TMainIDE.CloseDesignerForm(AnUnitInfo: TUnitInfo): TModalResult;
|
|
var
|
|
AForm: TCustomForm;
|
|
i: integer;
|
|
OldDesigner: TDesigner;
|
|
begin
|
|
AForm:=TCustomForm(AnUnitInfo.Form);
|
|
if AForm<>nil then begin
|
|
if FLastFormActivated=AForm then
|
|
FLastFormActivated:=nil;
|
|
// unselect controls
|
|
for i:=AForm.ComponentCount-1 downto 0 do
|
|
TheControlSelection.Remove(
|
|
AForm.Components[i]);
|
|
TheControlSelection.Remove(AForm);
|
|
// free designer and design form
|
|
OldDesigner:=TDesigner(AForm.Designer);
|
|
FormEditor1.DeleteControl(AForm);
|
|
OldDesigner.Free;
|
|
AnUnitInfo.Form:=nil;
|
|
end;
|
|
Result:=mrOk;
|
|
end;
|
|
|
|
procedure TMainIDE.GetMainUnit(var MainUnitInfo: TUnitInfo;
|
|
var MainUnitSrcEdit: TSourceEditor; UpdateModified: boolean);
|
|
begin
|
|
MainUnitSrcEdit:=nil;
|
|
if Project1.MainUnit>=0 then begin
|
|
MainUnitInfo:=Project1.MainUnitInfo;
|
|
if MainUnitInfo.Loaded then begin
|
|
MainUnitSrcEdit:=SourceNoteBook.FindSourceEditorWithPageIndex(
|
|
MainUnitInfo.EditorIndex);
|
|
if UpdateModified and MainUnitSrcEdit.Modified then begin
|
|
MainUnitSrcEdit.UpdateCodeBuffer;
|
|
MainUnitInfo.Modified:=true;
|
|
end;
|
|
end;
|
|
end else
|
|
MainUnitInfo:=nil;
|
|
end;
|
|
|
|
procedure TMainIDE.SaveSourceEditorProjectSpecificSettings;
|
|
var i, BookmarkID, BookmarkX, BookmarkY: integer;
|
|
AnUnitInfo: TUnitInfo;
|
|
ASrcEdit: TSourceEditor;
|
|
begin
|
|
Project1.Bookmarks.Clear;
|
|
for i:=0 to Project1.UnitCount-1 do begin
|
|
AnUnitInfo:=Project1.Units[i];
|
|
if AnUnitInfo.Loaded then begin
|
|
{$IFDEF IDE_DEBUG}
|
|
writeln('TMainIDE.SaveSourceEditorProjectSpecificSettings AnUnitInfo.Filename=',AnUnitInfo.Filename);
|
|
{$ENDIF}
|
|
ASrcEdit:=SourceNoteBook.FindSourceEditorWithPageIndex(
|
|
AnUnitInfo.EditorIndex);
|
|
AnUnitInfo.TopLine:=ASrcEdit.EditorComponent.TopLine;
|
|
AnUnitInfo.CursorPos:=ASrcEdit.EditorComponent.CaretXY;
|
|
for BookmarkID:=0 to 9 do begin
|
|
if (ASrcEdit.EditorComponent.GetBookMark(
|
|
BookmarkID,BookmarkX,BookmarkY))
|
|
and (Project1.Bookmarks.IndexOfID(BookmarkID)<0) then begin
|
|
Project1.Bookmarks.Add(TProjectBookmark.Create(BookmarkX,BookmarkY,
|
|
AnUnitInfo.EditorIndex,BookmarkID));
|
|
end;
|
|
end;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
function TMainIDE.DoShowSaveProjectAsDialog: TModalResult;
|
|
var
|
|
MainUnitSrcEdit: TSourceEditor;
|
|
MainUnitInfo: TUnitInfo;
|
|
SaveDialog: TSaveDialog;
|
|
NewFilename, NewProgramFilename, NewProgramName, AText, ACaption,
|
|
Ext: string;
|
|
NewBuf: TCodeBuffer;
|
|
OldProjectPath: string;
|
|
begin
|
|
OldProjectPath:=Project1.ProjectDirectory;
|
|
|
|
SaveDialog:=TSaveDialog.Create(Application);
|
|
try
|
|
InputHistories.ApplyFileDialogSettings(SaveDialog);
|
|
SaveDialog.Title:='Save Project '+Project1.Title+' (*.lpi)';
|
|
|
|
// build a nice project info filename suggestion
|
|
NewFilename:='';
|
|
if (Project1.MainUnit>=0) then
|
|
NewFileName:=Project1.MainUnitInfo.UnitName;
|
|
if NewFilename='' then
|
|
NewFilename:=ExtractFileName(Project1.ProjectInfoFile);
|
|
if NewFilename='' then
|
|
NewFilename:=ExtractFileName(Project1.MainFilename);
|
|
if NewFilename='' then
|
|
NewFilename:=Trim(Project1.Title);
|
|
if NewFilename='' then
|
|
NewFilename:='project1';
|
|
Ext:=lowercase(ExtractFileExt(NewFilename));
|
|
if (Ext='') or FilenameIsPascalSource(NewFilename) then
|
|
NewFilename:=ChangeFileExt(NewFilename,'.lpi');
|
|
SaveDialog.FileName:=NewFilename;
|
|
|
|
NewProgramName:=''; // the pascal program identifier
|
|
NewProgramFilename:=''; // the program source filename
|
|
repeat
|
|
Result:=mrCancel;
|
|
|
|
if not SaveDialog.Execute then begin
|
|
// user cancels
|
|
Result:=mrCancel;
|
|
exit;
|
|
end;
|
|
NewFilename:=ExpandFilename(SaveDialog.Filename);
|
|
NewProgramName:=ExtractFileNameOnly(NewFilename);
|
|
|
|
// check filename
|
|
if (NewProgramName='') or (not IsValidIdent(NewProgramName)) then begin
|
|
Result:=MessageDlg('Invalid project filename',
|
|
'"'+SaveDialog.Filename+'" is an invalid project name.'#13
|
|
+'Please choose another (e.g. project1.lpi)',
|
|
mtInformation,[mbRetry,mbAbort],0);
|
|
if Result=mrAbort then exit;
|
|
continue; // try again
|
|
end;
|
|
|
|
// append default extension
|
|
Ext:=ExtractFileExt(NewFilename);
|
|
if Ext='' then begin
|
|
NewFilename:=NewFilename+'.lpi';
|
|
Ext:='.lpi';
|
|
end;
|
|
|
|
// check pascal identifier
|
|
if FilenameIsPascalSource(NewFilename) then begin
|
|
if not IsValidIdent(NewProgramName) then begin
|
|
Result:=MessageDlg('Invalid Pascal Identifier',
|
|
'The name "'+NewProgramName+'" is not a valid pascal identifier.'
|
|
,mtWarning,[mbIgnore,mbCancel],0);
|
|
if Result=mrCancel then exit;
|
|
Result:=mrCancel;
|
|
end;
|
|
end;
|
|
|
|
// apply naming conventions
|
|
NewProgramName:=ExtractFileNameOnly(NewFilename);
|
|
if EnvironmentOptions.PascalFileLowerCase then
|
|
NewFileName:=ExtractFilePath(NewFilename)
|
|
+lowercase(ExtractFileName(NewFilename));
|
|
|
|
if Project1.MainUnit>=0 then begin
|
|
// check mainunit filename
|
|
Ext:=ExtractFileExt(Project1.MainUnitInfo.Filename);
|
|
if Ext='' then Ext:=ProjectDefaultExt[Project1.ProjectType];
|
|
NewProgramFilename:=ChangeFileExt(NewFilename,Ext);
|
|
if CompareFilenames(NewFilename,NewProgramFilename)=0 then begin
|
|
ACaption:='Choose a different name';
|
|
AText:='The project info file "'+NewFilename+'"'#13
|
|
+'is equal to the project main source file!';
|
|
Result:=MessageDlg(ACaption, AText, mtError, [mbAbort,mbRetry],0);
|
|
if Result=mrAbort then exit;
|
|
continue; // try again
|
|
end;
|
|
// check programname
|
|
if FilenameIsPascalUnit(NewProgramFilename)
|
|
and (Project1.IndexOfUnitWithName(NewProgramName,true,
|
|
Project1.MainUnitInfo)>=0) then
|
|
begin
|
|
ACaption:='Unit identifier exists';
|
|
AText:='There is a unit with the name "'+NewProgramName+'"'
|
|
+' in the project.'#13
|
|
+'Plz choose a different name';
|
|
Result:=MessageDlg(ACaption,AText,mtError,[mbRetry,mbAbort],0);
|
|
if Result=mrAbort then exit;
|
|
continue; // try again
|
|
end;
|
|
Result:=mrOk;
|
|
end else begin
|
|
NewProgramFilename:='';
|
|
Result:=mrOk;
|
|
end;
|
|
until Result<>mrRetry;
|
|
finally
|
|
InputHistories.StoreFileDialogSettings(SaveDialog);
|
|
SaveDialog.Free;
|
|
end;
|
|
|
|
// check if info file or source file already exists
|
|
if FileExists(NewFilename) then begin
|
|
ACaption:='Overwrite file?';
|
|
AText:='A file "'+NewFilename+'" already exists.'#13'Replace it?';
|
|
Result:=MessageDlg(ACaption, AText, mtConfirmation, [mbOk, mbCancel], 0);
|
|
if Result=mrCancel then exit;
|
|
end else if Project1.ProjectType in [ptProgram, ptApplication] then begin
|
|
if FileExists(NewProgramFilename) then begin
|
|
ACaption:='Overwrite file?';
|
|
AText:='A file "'+NewProgramFilename+'" already exists.'#13
|
|
+'Replace it?';
|
|
Result:=MessageDlg(ACaption, AText, mtConfirmation,[mbOk,mbCancel],0);
|
|
if Result=mrCancel then exit;
|
|
end;
|
|
end;
|
|
|
|
// set new project filename
|
|
Project1.ProjectInfoFile:=NewFilename;
|
|
EnvironmentOptions.AddToRecentProjectFiles(NewFilename);
|
|
SetRecentProjectFilesMenu;
|
|
|
|
// set new project directory
|
|
if OldProjectPath<>Project1.ProjectDirectory then begin
|
|
CodeToolBoss.GlobalValues.Variables[ExternalMacroStart+'ProjectDir']:=
|
|
Project1.ProjectDirectory;
|
|
CodeToolBoss.DefineTree.ClearCache;
|
|
end;
|
|
|
|
// change main source
|
|
if (Project1.MainUnit>=0) then begin
|
|
GetMainUnit(MainUnitInfo,MainUnitSrcEdit,true);
|
|
|
|
// switch MainUnitInfo.Source to new code
|
|
NewBuf:=CodeToolBoss.CreateFile(NewProgramFilename);
|
|
if NewBuf=nil then begin
|
|
Result:=MessageDlg('Error creating file','Unable to create file'#13
|
|
+'"'+NewProgramFilename+'"',mtError,[mbCancel],0);
|
|
exit;
|
|
end;
|
|
|
|
// copy the source to the new buffer
|
|
NewBuf.Source:=MainUnitInfo.Source.Source;
|
|
MainUnitInfo.Source:=NewBuf;
|
|
if MainUnitSrcEdit<>nil then
|
|
MainUnitSrcEdit.CodeBuffer:=NewBuf;
|
|
|
|
// change program name
|
|
MainUnitInfo.UnitName:=NewProgramName;
|
|
|
|
// TODO: rename resource include directive
|
|
|
|
// update source editor of main unit
|
|
MainUnitInfo.Modified:=true;
|
|
if MainUnitInfo.EditorIndex>=0 then begin
|
|
SourceNoteBook.NoteBook.Pages[MainUnitInfo.EditorIndex]:=
|
|
CreateSrcEditPageName(NewProgramName,MainUnitInfo.Filename,
|
|
MainUnitInfo.EditorIndex);
|
|
end;
|
|
end;
|
|
Result:=mrOk;
|
|
end;
|
|
|
|
function TMainIDE.DoCompleteLoadingProjectInfo: TModalResult;
|
|
begin
|
|
UpdateCaption;
|
|
EnvironmentOptions.LastSavedProjectFile:=Project1.ProjectInfoFile;
|
|
EnvironmentOptions.Save(false);
|
|
Result:=LoadCodeToolsDefines(CodeToolBoss,CodeToolsOpts,
|
|
Project1.ProjectInfoFile);
|
|
end;
|
|
|
|
function TMainIDE.DoOpenFileInSourceNotebook(AnUnitInfo: TUnitInfo;
|
|
PageIndex: integer; Flags: TOpenFlags): TModalResult;
|
|
var NewSrcEdit: TSourceEditor;
|
|
AFilename: string;
|
|
NewSrcEditorCreated: boolean;
|
|
begin
|
|
AFilename:=AnUnitInfo.Filename;
|
|
|
|
// get syntax highlighter type
|
|
if not AnUnitInfo.CustomHighlighter then
|
|
AnUnitInfo.SyntaxHighlighter:=
|
|
ExtensionToLazSyntaxHighlighter(ExtractFileExt(AFilename));
|
|
|
|
if (not (ofRevert in Flags)) or (PageIndex<0) then begin
|
|
// create a new source editor
|
|
SourceNotebook.NewFile(CreateSrcEditPageName(AnUnitInfo.UnitName,
|
|
AFilename,-1),AnUnitInfo.Source);
|
|
NewSrcEdit:=SourceNotebook.GetActiveSE;
|
|
NewSrcEditorCreated:=true;
|
|
itmFileClose.Enabled:=True;
|
|
itmFileCloseAll.Enabled:=True;
|
|
end else begin
|
|
// revert code in existing source editor
|
|
NewSrcEdit:=SourceNotebook.FindSourceEditorWithPageIndex(PageIndex);
|
|
NewSrcEdit.CodeBuffer:=AnUnitInfo.Source;
|
|
NewSrcEdit.Modified:=false;
|
|
AnUnitInfo.Modified:=false;
|
|
NewSrcEditorCreated:=false;
|
|
end;
|
|
|
|
if ofProjectLoading in Flags then begin
|
|
// reloading the project -> restore marks
|
|
DoRestoreBookMarks(AnUnitInfo,NewSrcEdit);
|
|
end;
|
|
|
|
// update editor indices in project
|
|
if (not (ofProjectLoading in Flags)) and NewSrcEditorCreated then
|
|
Project1.InsertEditorIndex(SourceNotebook.NoteBook.PageIndex);
|
|
AnUnitInfo.EditorIndex:=SourceNotebook.FindPageWithEditor(NewSrcEdit);
|
|
|
|
// restore source editor settings
|
|
NewSrcEdit.SyntaxHighlighterType:=AnUnitInfo.SyntaxHighlighter;
|
|
NewSrcEdit.EditorComponent.CaretXY:=AnUnitInfo.CursorPos;
|
|
NewSrcEdit.EditorComponent.TopLine:=AnUnitInfo.TopLine;
|
|
NewSrcEdit.EditorComponent.LeftChar:=1;
|
|
NewSrcEdit.ReadOnly:=AnUnitInfo.ReadOnly;
|
|
|
|
// mark unit as loaded
|
|
AnUnitInfo.Loaded:=true;
|
|
|
|
// update statusbar
|
|
SourceNoteBook.UpdateStatusBar;
|
|
|
|
Result:=mrOk;
|
|
end;
|
|
|
|
function TMainIDE.DoNewEditorFile(NewUnitType:TNewUnitType;
|
|
NewFilename: string):TModalResult;
|
|
var NewUnitInfo:TUnitInfo;
|
|
NewSrcEdit: TSourceEditor;
|
|
NewUnitName: string;
|
|
NewBuffer: TCodeBuffer;
|
|
begin
|
|
writeln('TMainIDE.DoNewEditorFile A NewFilename=',NewFilename);
|
|
SaveSourceEditorChangesToCodeCache(-1);
|
|
Result:=CreateNewCodeBuffer(NewUnitType,NewFilename,NewBuffer,NewUnitName);
|
|
if Result<>mrOk then exit;
|
|
Result:=mrCancel;
|
|
|
|
NewFilename:=NewBuffer.Filename;
|
|
NewUnitInfo:=TUnitInfo.Create(NewBuffer);
|
|
|
|
// create source code
|
|
if NewUnitType in [nuForm] then begin
|
|
NewUnitInfo.FormName:=Project1.NewUniqueFormName(NewUnitType);
|
|
CodeToolBoss.CreateFile(ChangeFileExt(NewFilename,'.lrs'));
|
|
end;
|
|
NewUnitInfo.CreateStartCode(NewUnitType,NewUnitName);
|
|
|
|
// add to project
|
|
with NewUnitInfo do begin
|
|
Loaded:=true;
|
|
IsPartOfProject:=Project1.FileIsInProjectDir(NewFilename);
|
|
end;
|
|
Project1.AddUnit(NewUnitInfo,(NewUnitType in [nuForm, nuUnit])
|
|
and NewUnitInfo.IsPartOfProject);
|
|
|
|
// syntax highlighter type
|
|
if NewUnitType in [nuForm, nuUnit] then begin
|
|
NewUnitInfo.SyntaxHighlighter:=lshFreePascal;
|
|
end else begin
|
|
NewUnitInfo.SyntaxHighlighter:=
|
|
ExtensionToLazSyntaxHighlighter(ExtractFileExt(NewFilename))
|
|
end;
|
|
|
|
// create a new sourceeditor
|
|
SourceNotebook.NewFile(CreateSrcEditPageName(NewUnitInfo.UnitName,
|
|
NewUnitInfo.Filename,-1),
|
|
NewUnitInfo.Source);
|
|
itmFileClose.Enabled:=True;
|
|
itmFileCloseAll.Enabled:=True;
|
|
NewSrcEdit:=SourceNotebook.GetActiveSE;
|
|
NewSrcEdit.SyntaxHighlighterType:=NewUnitInfo.SyntaxHighlighter;
|
|
Project1.InsertEditorIndex(SourceNotebook.NoteBook.PageIndex);
|
|
NewUnitInfo.EditorIndex:=SourceNotebook.NoteBook.PageIndex;
|
|
|
|
// create form
|
|
if NewUnitType in [nuForm] then begin
|
|
Result:=CreateNewForm(NewUnitInfo);
|
|
if Result<>mrOk then exit;
|
|
Result:=mrCancel;
|
|
end;
|
|
|
|
// show form and select form
|
|
if NewUnitType in [nuForm] then begin
|
|
// show form
|
|
TDesigner(TCustomForm(NewUnitInfo.Form).Designer).SourceEditor :=
|
|
SourceNoteBook.GetActiveSE;
|
|
ShowDesignForm(TCustomForm(NewUnitInfo.Form));
|
|
end else begin
|
|
FCodeLastActivated:=true;
|
|
end;
|
|
writeln('TMainIDE.DoNewUnit end ',NewUnitInfo.Filename);
|
|
{$IFDEF IDE_MEM_CHECK}CheckHeap(IntToStr(GetMem_Cnt));{$ENDIF}
|
|
end;
|
|
|
|
function TMainIDE.DoSaveEditorFile(PageIndex:integer;
|
|
Flags: TSaveFlags):TModalResult;
|
|
var ActiveSrcEdit:TSourceEditor;
|
|
ActiveUnitInfo:TUnitInfo;
|
|
TestFilename: string;
|
|
ResourceCode, LFMCode: TCodeBuffer;
|
|
begin
|
|
{$IFDEF IDE_VERBOSE}
|
|
writeln('TMainIDE.DoSaveEditorFile A PageIndex=',PageIndex,' SaveAs=',sfSaveAs in Flags,' SaveToTestDir=',sfSaveToTestDir in Flags);
|
|
{$ENDIF}
|
|
{$IFDEF IDE_MEM_CHECK}CheckHeap(IntToStr(GetMem_Cnt));{$ENDIF}
|
|
Result:=mrCancel;
|
|
if not (ToolStatus in [itNone,itDebugger]) then begin
|
|
Result:=mrAbort;
|
|
exit;
|
|
end;
|
|
GetUnitWithPageIndex(PageIndex,ActiveSrcEdit,ActiveUnitInfo);
|
|
if ActiveUnitInfo=nil then exit;
|
|
|
|
// if this file is part of the project and the project is virtual then save
|
|
// project first
|
|
if (not (sfProjectSaving in Flags)) and Project1.IsVirtual
|
|
and ActiveUnitInfo.IsPartOfProject then
|
|
begin
|
|
Result:=DoSaveProject(Flags*[sfSaveToTestDir]);
|
|
exit;
|
|
end;
|
|
|
|
// update codetools cache and collect Modified flags
|
|
if not (sfProjectSaving in Flags) then
|
|
SaveSourceEditorChangesToCodeCache(-1);
|
|
|
|
// if this is new unit then a simple Save becomes a SaveAs
|
|
if (not (sfSaveToTestDir in Flags)) and (ActiveUnitInfo.IsVirtual) then
|
|
Include(Flags,sfSaveAs);
|
|
|
|
// update source notebook page names
|
|
if (not (sfProjectSaving in Flags)) then
|
|
UpdateSourceNames;
|
|
|
|
// if file is readonly then a simple Save is skipped
|
|
ActiveUnitInfo.ReadOnly:=ActiveSrcEdit.ReadOnly;
|
|
if (ActiveUnitInfo.ReadOnly) and ([sfSaveToTestDir,sfSaveAs]*Flags=[]) then
|
|
begin
|
|
Result:=mrOk;
|
|
exit;
|
|
end;
|
|
|
|
// if nothing modified then a simple Save can be skipped
|
|
if ([sfSaveToTestDir,sfSaveAs]*Flags=[])
|
|
and (not ActiveUnitInfo.NeedsSaveToDisk) then begin
|
|
Result:=mrOk;
|
|
exit;
|
|
end;
|
|
|
|
// load resource file
|
|
Result:=DoLoadResourceFile(ActiveUnitInfo,LFMCode,ResourceCode,
|
|
not (sfSaveAs in Flags));
|
|
if Result in [mrIgnore, mrOk] then
|
|
Result:=mrCancel
|
|
else
|
|
exit;
|
|
|
|
if [sfSaveAs,sfSaveToTestDir]*Flags=[sfSaveAs] then begin
|
|
// let user choose a filename
|
|
Result:=DoShowSaveFileAsDialog(ActiveUnitInfo,ResourceCode);
|
|
if Result in [mrIgnore, mrOk] then Result:=mrCancel
|
|
else exit;
|
|
LFMCode:=nil;
|
|
end;
|
|
|
|
// save source
|
|
if not (sfSaveToTestDir in Flags) then begin
|
|
if ActiveUnitInfo.Modified then begin
|
|
// save source to file
|
|
Result:=ActiveUnitInfo.WriteUnitSource;
|
|
if Result=mrAbort then exit;
|
|
end;
|
|
end else begin
|
|
// save source to test directory
|
|
TestFilename:=GetTestUnitFilename(ActiveUnitInfo);
|
|
if TestFilename<>'' then begin
|
|
Result:=ActiveUnitInfo.WriteUnitSourceToFile(TestFilename);
|
|
if Result<>mrOk then exit;
|
|
Result:=mrCancel;
|
|
end else
|
|
exit;
|
|
end;
|
|
|
|
{$IFDEF IDE_DEBUG}
|
|
writeln('*** HasResources=',ActiveUnitInfo.HasResources);
|
|
{$ENDIF}
|
|
{$IFDEF IDE_MEM_CHECK}CheckHeap(IntToStr(GetMem_Cnt));{$ENDIF}
|
|
// save resource file and lfm file
|
|
if (ResourceCode<>nil) or (ActiveUnitInfo.Form<>nil) then begin
|
|
Result:=DoSaveFileResources(ActiveUnitInfo,ResourceCode,LFMCode,Flags);
|
|
if Result in [mrIgnore, mrOk] then Result:=mrCancel
|
|
else exit;
|
|
end;
|
|
|
|
// unset all modified flags
|
|
if not (sfSaveToTestDir in Flags) then begin
|
|
ActiveUnitInfo.Modified:=false;
|
|
ActiveSrcEdit.Modified:=false;
|
|
end;
|
|
SourceNoteBook.UpdateStatusBar;
|
|
|
|
{$IFDEF IDE_VERBOSE}
|
|
writeln('TMainIDE.DoSaveEditorFile END');
|
|
{$ENDIF}
|
|
Result:=mrOk;
|
|
end;
|
|
|
|
function TMainIDE.DoCloseEditorFile(PageIndex:integer;
|
|
Flags: TCloseFlags):TModalResult;
|
|
var ActiveSrcEdit: TSourceEditor;
|
|
ActiveUnitInfo: TUnitInfo;
|
|
ACaption,AText: string;
|
|
i:integer;
|
|
begin
|
|
writeln('TMainIDE.DoCloseEditorFile A PageIndex=',PageIndex);
|
|
Result:=mrCancel;
|
|
GetUnitWithPageIndex(PageIndex,ActiveSrcEdit,ActiveUnitInfo);
|
|
if ActiveUnitInfo=nil then exit;
|
|
if ActiveUnitInfo.Form=FLastFormActivated then
|
|
FLastFormActivated:=nil;
|
|
|
|
// save some meta data of the source
|
|
ActiveUnitInfo.ReadOnly:=ActiveSrcEdit.ReadOnly;
|
|
ActiveUnitInfo.TopLine:=ActiveSrcEdit.EditorComponent.TopLine;
|
|
ActiveUnitInfo.CursorPos:=ActiveSrcEdit.EditorComponent.CaretXY;
|
|
|
|
// if SaveFirst then save the source
|
|
if (cfSaveFirst in Flags) and (not ActiveUnitInfo.ReadOnly)
|
|
and ((ActiveSrcEdit.Modified) or (ActiveUnitInfo.Modified)) then begin
|
|
if ActiveUnitInfo.Filename<>'' then
|
|
AText:='File "'+ActiveUnitInfo.Filename+'" has changed. Save?'
|
|
else if ActiveUnitInfo.UnitName<>'' then
|
|
AText:='Unit "'+ActiveUnitInfo.Unitname+'" has changed. Save?'
|
|
else
|
|
AText:='Source of page "'+
|
|
SourceNotebook.NoteBook.Pages[PageIndex]
|
|
+'" has changed. Save?';
|
|
ACaption:='Source modified';
|
|
if Messagedlg(ACaption, AText, mtConfirmation, [mbYes, mbNo], 0)=mrYes then
|
|
begin
|
|
Result:=DoSaveEditorFile(PageIndex,[]);
|
|
if Result=mrAbort then exit;
|
|
end;
|
|
Result:=mrOk;
|
|
end;
|
|
|
|
// close form
|
|
CloseDesignerForm(ActiveUnitInfo);
|
|
|
|
// close source editor
|
|
SourceNoteBook.CloseFile(PageIndex);
|
|
itmFileClose.Enabled:=SourceNoteBook.NoteBook<>nil;
|
|
itmFileCloseAll.Enabled:=itmFileClose.Enabled;
|
|
|
|
// close file in project
|
|
Project1.CloseEditorIndex(ActiveUnitInfo.EditorIndex);
|
|
ActiveUnitInfo.Loaded:=false;
|
|
i:=Project1.IndexOf(ActiveUnitInfo);
|
|
if (i<>Project1.MainUnit) and (ActiveUnitInfo.IsVirtual) then begin
|
|
Project1.RemoveUnit(i);
|
|
end;
|
|
|
|
writeln('TMainIDE.DoCloseEditorFile end');
|
|
Result:=mrOk;
|
|
end;
|
|
|
|
function TMainIDE.DoOpenEditorFile(AFileName:string;
|
|
PageIndex: integer; Flags: TOpenFlags):TModalResult;
|
|
var
|
|
UnitIndex: integer;
|
|
ReOpen, Handled:boolean;
|
|
NewUnitInfo:TUnitInfo;
|
|
NewBuf: TCodeBuffer;
|
|
begin
|
|
{$IFDEF IDE_VERBOSE}
|
|
writeln('');
|
|
writeln('*** TMainIDE.DoOpenEditorFile START "',AFilename,'"');
|
|
{$ENDIF}
|
|
{$IFDEF IDE_MEM_CHECK}CheckHeap(IntToStr(GetMem_Cnt));{$ENDIF}
|
|
Result:=mrCancel;
|
|
|
|
if (not (ofRevert in Flags))
|
|
and (ExtractFilenameOnly(AFilename)='') then
|
|
exit;
|
|
|
|
if (ofAddToRecent in Flags) and (AFilename<>'') then
|
|
EnvironmentOptions.AddToRecentOpenFiles(AFilename);
|
|
|
|
// check if this is a hidden unit:
|
|
// if this is a virtual (new, unsaved) project, the main unit is already
|
|
// loaded and needs only to be shown in the sourceeditor/formeditor
|
|
if (not (ofRevert in Flags))
|
|
and (Project1.IsVirtual)
|
|
and (CompareFilenames(Project1.MainFilename,AFilename)=0)
|
|
then begin
|
|
Result:=DoOpenMainUnit(ofProjectLoading in Flags);
|
|
exit;
|
|
end;
|
|
|
|
// check if the project knows this file
|
|
if (not (ofRevert in Flags)) then begin
|
|
UnitIndex:=Project1.IndexOfFilename(AFilename);
|
|
ReOpen:=(UnitIndex>=0);
|
|
if ReOpen then begin
|
|
NewUnitInfo:=Project1.Units[UnitIndex];
|
|
if (not (ofProjectLoading in Flags)) and NewUnitInfo.Loaded then begin
|
|
// file already open -> change source notebook page
|
|
SourceNoteBook.NoteBook.PageIndex:=NewUnitInfo.EditorIndex;
|
|
Result:=mrOk;
|
|
exit;
|
|
end;
|
|
end;
|
|
end else begin
|
|
// revert
|
|
NewUnitInfo:=Project1.UnitWithEditorIndex(PageIndex);
|
|
UnitIndex:=Project1.IndexOf(NewUnitInfo);
|
|
AFilename:=NewUnitInfo.Filename;
|
|
if NewUnitInfo.IsVirtual then begin
|
|
if (not (ofQuiet in Flags)) then begin
|
|
MessageDlg('Revert failed','File "'+AFilename+'" is virtual.',
|
|
mtInformation,[mbCancel],0);
|
|
end;
|
|
Result:=mrCancel;
|
|
exit;
|
|
end;
|
|
ReOpen:=true;
|
|
end;
|
|
|
|
// check if file exists
|
|
if (not FileExists(AFilename)) then begin
|
|
// file does not exists
|
|
if (ofRevert in Flags) then begin
|
|
// revert failed, due to missing file
|
|
if not (ofQuiet in Flags) then begin
|
|
MessageDlg('Revert failed','File "'+AFilename+'" not found.',
|
|
mtError,[mbCancel],0);
|
|
end;
|
|
Result:=mrCancel;
|
|
exit;
|
|
end else begin
|
|
Result:=DoOpenNotExistingFile(AFilename,Flags);
|
|
exit;
|
|
end;
|
|
end;
|
|
|
|
// load the source
|
|
if ReOpen then begin
|
|
// project knows this file => all the meta data is known
|
|
// -> just load the source
|
|
NewUnitInfo:=Project1.Units[UnitIndex];
|
|
Result:=DoLoadCodeBuffer(NewBuf,AFileName,
|
|
[lbfCheckIfText,lbfUpdateFromDisk,lbfRevert]);
|
|
if Result<>mrOk then exit;
|
|
NewUnitInfo.Source:=NewBuf;
|
|
if FilenameIsPascalUnit(NewUnitInfo.Filename) then
|
|
NewUnitInfo.ReadUnitNameFromSource;
|
|
end else begin
|
|
// open unknown file
|
|
Handled:=false;
|
|
Result:=DoOpenUnknownFile(AFilename,Flags,NewUnitInfo,Handled);
|
|
if Result<>mrOk then exit;
|
|
if Handled then exit;
|
|
end;
|
|
|
|
// check readonly
|
|
NewUnitInfo.ReadOnly:=NewUnitInfo.ReadOnly
|
|
or (not FileIsWritable(NewUnitInfo.Filename));
|
|
|
|
{$IFDEF IDE_DEBUG}
|
|
writeln('[TMainIDE.DoOpenEditorFile] B');
|
|
{$ENDIF}
|
|
// open file in source notebook
|
|
Result:=DoOpenFileInSourceNoteBook(NewUnitInfo,PageIndex,Flags);
|
|
if Result<>mrOk then exit;
|
|
|
|
{$IFDEF IDE_DEBUG}
|
|
writeln('[TMainIDE.DoOpenEditorFile] C');
|
|
{$ENDIF}
|
|
|
|
// read form data
|
|
if FilenameIsPascalUnit(AFilename) then begin
|
|
// this could be a unit -> try to load the lfm file
|
|
Result:=DoLoadLFM(NewUnitInfo,Flags);
|
|
if Result<>mrOk then exit;
|
|
end else if NewUnitInfo.Form<>nil then begin
|
|
// close form (Note: e.g. close form on revert)
|
|
CloseDesignerForm(NewUnitInfo);
|
|
end;
|
|
|
|
Result:=mrOk;
|
|
writeln('TMainIDE.DoOpenEditorFile END "',AFilename,'"');
|
|
{$IFDEF IDE_MEM_CHECK}CheckHeap(IntToStr(GetMem_Cnt));{$ENDIF}
|
|
end;
|
|
|
|
function TMainIDE.DoOpenMainUnit(ProjectLoading: boolean): TModalResult;
|
|
var MainUnitInfo: TUnitInfo;
|
|
OpenFlags: TOpenFlags;
|
|
begin
|
|
writeln('[TMainIDE.DoOpenMainUnit] A');
|
|
Result:=mrCancel;
|
|
if Project1.MainUnit<0 then exit;
|
|
MainUnitInfo:=Project1.MainUnitInfo;
|
|
|
|
// check if main unit is already loaded in source editor
|
|
if MainUnitInfo.Loaded then begin
|
|
// already loaded -> switch to source editor
|
|
SourceNotebook.NoteBook.PageIndex:=MainUnitInfo.EditorIndex;
|
|
Result:=mrOk;
|
|
exit;
|
|
end;
|
|
|
|
// open file in source notebook
|
|
OpenFlags:=[];
|
|
if ProjectLoading then Include(OpenFlags,ofProjectLoading);
|
|
Result:=DoOpenFileInSourceNoteBook(MainUnitInfo,-1,OpenFlags);
|
|
if Result<>mrOk then exit;
|
|
|
|
// build a nice pagename for the sourcenotebook
|
|
Result:=mrOk;
|
|
{$IFDEF IDE_VERBOSE}
|
|
writeln('[TMainIDE.DoOpenMainUnit] END');
|
|
{$ENDIF}
|
|
end;
|
|
|
|
function TMainIDE.DoRevertMainUnit: TModalResult;
|
|
begin
|
|
Result:=mrOk;
|
|
if Project1.MainUnit<0 then exit;
|
|
if Project1.MainUnitInfo.EditorIndex>=0 then
|
|
// main unit is loaded, so we can just revert
|
|
Result:=DoOpenEditorFile('',Project1.MainUnitInfo.EditorIndex,[ofRevert])
|
|
else begin
|
|
// main unit is only loaded in background
|
|
// -> just reload the source and update the source name
|
|
Result:=Project1.MainUnitInfo.ReadUnitSource(true);
|
|
end;
|
|
end;
|
|
|
|
function TMainIDE.DoViewUnitsAndForms(OnlyForms: boolean): TModalResult;
|
|
var UnitList: TList;
|
|
i: integer;
|
|
MainUnitName, Ext, DlgCaption: string;
|
|
MainUnitInfo, AnUnitInfo: TUnitInfo;
|
|
MainUnitIndex: integer;
|
|
ActiveSourceEditor: TSourceEditor;
|
|
ActiveUnitInfo: TUnitInfo;
|
|
AForm: TForm;
|
|
Begin
|
|
GetCurrentUnit(ActiveSourceEditor,ActiveUnitInfo);
|
|
UnitList:=TList.Create;
|
|
try
|
|
MainUnitIndex:=-1; // if main unit is also shown, then this is the index of
|
|
// the main unit
|
|
for i:=0 to Project1.UnitCount-1 do begin
|
|
if not Project1.Units[i].IsPartOfProject then continue;
|
|
if OnlyForms then begin
|
|
// add all form names of project
|
|
if Project1.MainUnit=i then MainUnitIndex:=i;
|
|
if Project1.Units[i].FormName<>'' then
|
|
UnitList.Add(TViewUnitsEntry.Create(
|
|
Project1.Units[i].FormName,i,Project1.Units[i]=ActiveUnitInfo));
|
|
end else begin
|
|
// add all unit names of project
|
|
if (Project1.Units[i].UnitName<>'') then begin
|
|
if Project1.MainUnit=i then MainUnitIndex:=i;
|
|
UnitList.Add(TViewUnitsEntry.Create(
|
|
Project1.Units[i].UnitName,i,Project1.Units[i]=ActiveUnitInfo));
|
|
end else if Project1.MainUnit=i then begin
|
|
MainUnitInfo:=Project1.MainUnitInfo;
|
|
if Project1.ProjectType in [ptProgram,ptApplication,ptCustomProgram]
|
|
then begin
|
|
if (MainUnitInfo.Loaded) then
|
|
MainUnitName:=SourceNoteBook.NoteBook.Pages[
|
|
MainUnitInfo.EditorIndex];
|
|
if MainUnitName='' then begin
|
|
MainUnitInfo.ReadUnitNameFromSource;
|
|
MainUnitName:=MainUnitInfo.UnitName;
|
|
end;
|
|
if MainUnitName='' then begin
|
|
MainUnitName:=ExtractFileName(MainUnitInfo.Filename);
|
|
Ext:=ExtractFileExt(MainUnitName);
|
|
MainUnitName:=copy(MainUnitName,1,length(MainUnitName)-length(Ext));
|
|
end;
|
|
if MainUnitName<>'' then begin
|
|
MainUnitIndex:=UnitList.Count;
|
|
UnitList.Add(TViewUnitsEntry.Create(
|
|
MainUnitName,i,MainUnitInfo=ActiveUnitInfo));
|
|
end;
|
|
end;
|
|
end;
|
|
end;
|
|
end;
|
|
if OnlyForms then
|
|
DlgCaption:='View project forms'
|
|
else
|
|
DlgCaption:='View project units';
|
|
if ShowViewUnitsDlg(UnitList,true,DlgCaption)=mrOk then begin
|
|
AnUnitInfo:=nil;
|
|
for i:=0 to UnitList.Count-1 do begin
|
|
if TViewUnitsEntry(UnitList[i]).Selected then begin
|
|
AnUnitInfo:=Project1.Units[TViewUnitsEntry(UnitList[i]).ID];
|
|
if AnUnitInfo.Loaded then begin
|
|
SourceNoteBook.NoteBook.PageIndex:=AnUnitInfo.EditorIndex;
|
|
end else begin
|
|
if MainUnitIndex=i then
|
|
Result:=DoOpenMainUnit(false)
|
|
else
|
|
Result:=DoOpenEditorFile(AnUnitInfo.Filename,-1,[ofOnlyIfExists]);
|
|
if Result=mrAbort then exit;
|
|
end;
|
|
end;
|
|
end;
|
|
if (AnUnitInfo<>nil) then begin
|
|
AForm:=SourceNotebook;
|
|
if OnlyForms and (AnUnitInfo.Form<>nil) then begin
|
|
AForm:=TForm(AnUnitInfo.Form);
|
|
end;
|
|
BringWindowToTop(AForm.Handle)
|
|
end;
|
|
end;
|
|
finally
|
|
UnitList.Free;
|
|
end;
|
|
Result:=mrOk;
|
|
end;
|
|
|
|
function TMainIDE.DoOpenFileAtCursor(Sender: TObject):TModalResult;
|
|
var ActiveSrcEdit: TSourceEditor;
|
|
ActiveUnitInfo: TUnitInfo;
|
|
FName,SPath: String;
|
|
|
|
function FindFile(var FName: String; SPath: String): Boolean;
|
|
// Searches for FName in SPath
|
|
// If FName is not found, we'll check extensions pp and pas too
|
|
// Returns true if found. FName contains the full file+path in that case
|
|
var TempFile,TempPath,CurPath,FinalFile, Ext: String;
|
|
i,p,c: Integer;
|
|
begin
|
|
if SPath='' then SPath:='.';
|
|
Result:=true;
|
|
TempPath:=SPath;
|
|
while TempPath<>'' do begin
|
|
p:=pos(';',TempPath);
|
|
if p=0 then p:=length(TempPath)+1;
|
|
CurPath:=copy(TempPath,1,p-1);
|
|
Delete(TempPath,1,p);
|
|
if CurPath='' then continue;
|
|
CurPath:=AppendPathDelim(CurPath);
|
|
if not FilenameIsAbsolute(CurPath) then begin
|
|
if ActiveUnitInfo.IsVirtual then
|
|
CurPath:=AppendPathDelim(Project1.ProjectDirectory)+CurPath
|
|
else
|
|
CurPath:=AppendPathDelim(ExtractFilePath(ActiveUnitInfo.Filename))
|
|
+CurPath;
|
|
end;
|
|
for c:=0 to 2 do begin
|
|
case c of
|
|
0: TempFile:=FName;
|
|
1: TempFile:=LowerCase(FName);
|
|
2: TempFile:=UpperCase(FName);
|
|
end;
|
|
if ExtractFileExt(TempFile)='' then begin
|
|
for i:=0 to 2 do begin
|
|
case i of
|
|
1: Ext:='.pp';
|
|
2: Ext:='.pas';
|
|
else Ext:='';
|
|
end;
|
|
FinalFile:=ExpandFileName(CurPath+TempFile+Ext);
|
|
if FileExists(FinalFile) then begin
|
|
FName:=FinalFile;
|
|
exit;
|
|
end;
|
|
end;
|
|
end else begin
|
|
FinalFile:=ExpandFileName(CurPath+TempFile);
|
|
if FileExists(FinalFile) then begin
|
|
FName:=FinalFile;
|
|
exit;
|
|
end;
|
|
end;
|
|
end;
|
|
end;
|
|
Result:=false;
|
|
end;
|
|
|
|
function CheckIfIncludeDirectiveInFront(const Line: string;
|
|
X: integer): boolean;
|
|
var
|
|
DirectiveEnd, DirectiveStart: integer;
|
|
Directive: string;
|
|
begin
|
|
Result:=false;
|
|
DirectiveEnd:=X;
|
|
while (DirectiveEnd>1) and (Line[DirectiveEnd-1] in [' ',#9]) do
|
|
dec(DirectiveEnd);
|
|
DirectiveStart:=DirectiveEnd-1;
|
|
while (DirectiveStart>0) and (Line[DirectiveStart]<>'$') do
|
|
dec(DirectiveStart);
|
|
Directive:=uppercase(copy(Line,DirectiveStart,DirectiveEnd-DirectiveStart));
|
|
if (Directive='$INCLUDE') or (Directive='$I') then begin
|
|
if ((DirectiveStart>1) and (Line[DirectiveStart-1]='{'))
|
|
or ((DirectiveStart>2)
|
|
and (Line[DirectiveStart-2]='(') and (Line[DirectiveStart-1]='*'))
|
|
then begin
|
|
Result:=true;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
function GetFilenameAtRowCol(XY: TPoint;
|
|
var IsIncludeDirective: boolean): string;
|
|
var
|
|
Line: string;
|
|
Len, Stop: integer;
|
|
StopChars: set of char;
|
|
begin
|
|
Result := '';
|
|
IsIncludeDirective:=false;
|
|
if (XY.Y >= 1) and (XY.Y <= ActiveSrcEdit.EditorComponent.Lines.Count) then
|
|
begin
|
|
Line := ActiveSrcEdit.EditorComponent.Lines.Strings[XY.Y - 1];
|
|
Len := Length(Line);
|
|
if (XY.X >= 1) and (XY.X <= Len + 1) then begin
|
|
StopChars := [',',';',':','[',']','{','}','(',')',' ','''','"','`'
|
|
,'#','%','=','>'];
|
|
Stop := XY.X;
|
|
while (Stop <= Len) and (not (Line[Stop] in StopChars)) do
|
|
Inc(Stop);
|
|
while (XY.X > 1) and (not (Line[XY.X - 1] in StopChars)) do
|
|
Dec(XY.X);
|
|
if Stop > XY.X then begin
|
|
Result := Copy(Line, XY.X, Stop - XY.X);
|
|
IsIncludeDirective:=CheckIfIncludeDirectiveInFront(Line,XY.X);
|
|
end;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
var IsIncludeDirective: boolean;
|
|
begin
|
|
Result:=mrCancel;
|
|
GetCurrentUnit(ActiveSrcEdit,ActiveUnitInfo);
|
|
if (ActiveSrcEdit=nil) or (ActiveUnitInfo=nil) then exit;
|
|
|
|
// parse filename at cursor
|
|
FName:=GetFilenameAtRowCol(ActiveSrcEdit.EditorComponent.CaretXY,
|
|
IsIncludeDirective);
|
|
if FName='' then exit;
|
|
|
|
// get searchpath for directory of current file
|
|
if ActiveUnitInfo.IsVirtual then
|
|
SPath:='.'
|
|
else begin
|
|
if IsIncludeDirective then
|
|
SPath:='.;'+CodeToolBoss.DefineTree.GetIncludePathForDirectory(
|
|
ExtractFilePath(ActiveUnitInfo.Filename))
|
|
else
|
|
SPath:='.;'+CodeToolBoss.DefineTree.GetSrcPathForDirectory(
|
|
ExtractFilePath(ActiveUnitInfo.Filename));
|
|
end;
|
|
|
|
// search file in path (search especially for pascal files)
|
|
if FindFile(FName,SPath) then begin
|
|
result:=mrOk;
|
|
InputHistories.FileDialogSettings.InitialDir:=ExtractFilePath(FName);
|
|
if DoOpenEditorFile(FName,-1,[])=mrOk then begin
|
|
EnvironmentOptions.AddToRecentOpenFiles(FName);
|
|
SetRecentFilesMenu;
|
|
SaveEnvironment;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
function TMainIDE.DoNewProject(NewProjectType:TProjectType):TModalResult;
|
|
var i:integer;
|
|
ds: char;
|
|
Begin
|
|
writeln('TMainIDE.DoNewProject A');
|
|
Result:=mrCancel;
|
|
|
|
// close current project first
|
|
If Project1<>nil then begin
|
|
if SomethingOfProjectIsModified then begin
|
|
if MessageDlg('Project changed', 'Save changes to project?',
|
|
mtconfirmation, [mbyes, mbno], 0)=mryes then begin
|
|
if DoSaveProject([])=mrAbort then begin
|
|
Result:=mrAbort;
|
|
exit;
|
|
end;
|
|
end;
|
|
end;
|
|
if DoCloseProject=mrAbort then begin
|
|
Result:=mrAbort;
|
|
exit;
|
|
end;
|
|
end;
|
|
|
|
// create a virtual project (i.e. unsaved and without real project directory)
|
|
|
|
// switch codetools to virtual project directory
|
|
CodeToolBoss.GlobalValues.Variables[ExternalMacroStart+'ProjectDir']:=
|
|
VirtualDirectory;
|
|
|
|
// create new project (TProject will automatically create the mainunit)
|
|
Project1:=TProject.Create(NewProjectType);
|
|
Project1.OnFileBackup:=@DoBackupFile;
|
|
Project1.Title := 'project1';
|
|
Project1.CompilerOptions.CompilerPath:='$(CompPath)';
|
|
UpdateCaption;
|
|
|
|
// set the project type specific things
|
|
ds:=PathDelim;
|
|
case NewProjectType of
|
|
|
|
ptApplication:
|
|
begin
|
|
// add lcl ppu dirs to unit search path
|
|
Project1.CompilerOptions.OtherUnitFiles:=
|
|
'$(LazarusDir)'+ds+'lcl'+ds+'units'
|
|
+';'+
|
|
'$(LazarusDir)'+ds+'lcl'+ds+'units'+ds+'$(LCLWidgetType)';
|
|
// add lcl pp/pas dirs to source search path
|
|
Project1.SrcPath:=
|
|
'$(LazarusDir)'+ds+'lcl'
|
|
+';'+
|
|
'$(LazarusDir)'+ds+'lcl'+ds+'interfaces'+ds+'$(LCLWidgetType)';
|
|
// create a first form unit
|
|
DoNewEditorFile(nuForm,'');
|
|
end;
|
|
|
|
ptProgram,ptCustomProgram:
|
|
begin
|
|
// show program unit
|
|
DoOpenMainUnit(false);
|
|
end;
|
|
|
|
end;
|
|
|
|
// rebuild codetools defines
|
|
// (i.e. remove old project specific things and create new)
|
|
Result:=LoadCodeToolsDefines(CodeToolBoss,CodeToolsOpts,'');
|
|
CreateProjectDefineTemplate(Project1.CompilerOptions,Project1.SrcPath);
|
|
|
|
// set all modified to false
|
|
for i:=0 to Project1.UnitCount-1 do
|
|
Project1.Units[i].Modified:=false;
|
|
Project1.Modified:=false;
|
|
|
|
writeln('TMainIDE.DoNewProject end ',CodeToolBoss.ConsistencyCheck);
|
|
Result:=mrOk;
|
|
end;
|
|
|
|
function TMainIDE.DoSaveProject(Flags: TSaveFlags):TModalResult;
|
|
var MainUnitSrcEdit: TSourceEditor;
|
|
MainUnitInfo: TUnitInfo;
|
|
i: integer;
|
|
begin
|
|
Result:=mrCancel;
|
|
if not (ToolStatus in [itNone,itDebugger]) then begin
|
|
Result:=mrAbort;
|
|
exit;
|
|
end;
|
|
SaveSourceEditorChangesToCodeCache(-1);
|
|
writeln('TMainIDE.DoSaveProject A SaveAs=',sfSaveAs in Flags,' SaveToTestDir=',sfSaveToTestDir in Flags);
|
|
|
|
// check that all new units are saved first to get valid filenames
|
|
// (this can alter the mainunit: e.g. used unit names)
|
|
for i:=0 to Project1.UnitCount-1 do begin
|
|
if (Project1.Units[i].Loaded) and (Project1.Units[i].IsVirtual)
|
|
and (Project1.MainUnit<>i) then begin
|
|
Result:=DoSaveEditorFile(Project1.Units[i].EditorIndex,
|
|
[sfSaveAs,sfProjectSaving]+[sfSaveToTestDir]*Flags);
|
|
if (Result=mrAbort) or (Result=mrCancel) then exit;
|
|
end;
|
|
end;
|
|
|
|
if SourceNotebook.Notebook=nil then
|
|
Project1.ActiveEditorIndexAtStart:=-1
|
|
else
|
|
Project1.ActiveEditorIndexAtStart:=SourceNotebook.Notebook.PageIndex;
|
|
|
|
// update source notebook page names
|
|
UpdateSourceNames;
|
|
|
|
// find mainunit
|
|
GetMainUnit(MainUnitInfo,MainUnitSrcEdit,true);
|
|
|
|
// save project specific settings of the source editor
|
|
SaveSourceEditorProjectSpecificSettings;
|
|
|
|
if Project1.IsVirtual then Include(Flags,sfSaveAs);
|
|
if ([sfSaveAs,sfSaveToTestDir]*Flags=[sfSaveAs]) then begin
|
|
// let user choose a filename
|
|
Result:=DoShowSaveProjectAsDialog;
|
|
if Result<>mrOk then exit;
|
|
end;
|
|
|
|
// save project info file
|
|
if not (sfSaveToTestDir in Flags) then begin
|
|
Result:=Project1.WriteProject;
|
|
if Result=mrAbort then exit;
|
|
EnvironmentOptions.LastSavedProjectFile:=Project1.ProjectInfoFile;
|
|
EnvironmentOptions.Save(false);
|
|
SaveIncludeLinks;
|
|
UpdateCaption;
|
|
Result:=SaveProjectSpecificCodeToolsDefines(CodeToolBoss,
|
|
Project1.ProjectInfoFile);
|
|
if Result=mrAbort then exit;
|
|
end;
|
|
|
|
// save main source
|
|
if MainUnitInfo<>nil then begin
|
|
if MainUnitInfo.Loaded then begin
|
|
// loaded in source editor
|
|
Result:=DoSaveEditorFile(MainUnitInfo.EditorIndex,
|
|
[sfProjectSaving]+[sfSaveToTestDir]*Flags);
|
|
if Result=mrAbort then exit;
|
|
end else begin
|
|
// not loaded in source editor (hidden)
|
|
if not (sfSaveToTestDir in Flags) then begin
|
|
Result:=DoSaveCodeBufferToFile(MainUnitInfo.Source,
|
|
MainUnitInfo.Filename,true);
|
|
end else begin
|
|
Result:=DoSaveCodeBufferToFile(MainUnitInfo.Source,
|
|
GetTestUnitFilename(MainUnitInfo),false);
|
|
end;
|
|
if Result=mrAbort then exit;
|
|
end;
|
|
// clear modified flags
|
|
if not (sfSaveToTestDir in Flags) then begin
|
|
if (Result=mrOk) then begin
|
|
if MainUnitInfo<>nil then MainUnitInfo.Modified:=false;
|
|
if MainUnitSrcEdit<>nil then MainUnitSrcEdit.Modified:=false;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
// save all editor files
|
|
if (SourceNoteBook.Notebook<>nil) and (not (sfSaveToTestDir in Flags)) then
|
|
begin
|
|
for i:=0 to SourceNoteBook.Notebook.Pages.Count-1 do begin
|
|
if (Project1.MainUnit<0)
|
|
or (Project1.MainUnitInfo.EditorIndex<>i) then begin
|
|
Result:=DoSaveEditorFile(i,[sfProjectSaving]+[sfSaveToTestDir]*Flags);
|
|
if Result=mrAbort then exit;
|
|
end;
|
|
end;
|
|
end;
|
|
writeln('TMainIDE.DoSaveProject End');
|
|
end;
|
|
|
|
function TMainIDE.DoCloseProject:TModalResult;
|
|
begin
|
|
{$IFDEF IDE_VERBOSE}
|
|
writeln('TMainIDE.DoCloseProject A');
|
|
{$ENDIF}
|
|
// close all loaded files
|
|
{$IFDEF IDE_MEM_CHECK}CheckHeap(IntToStr(GetMem_Cnt));{$ENDIF}
|
|
while SourceNotebook.NoteBook<>nil do begin
|
|
Result:=DoCloseEditorFile(SourceNotebook.Notebook.Pages.Count-1,
|
|
[cfProjectClosing]);
|
|
if Result=mrAbort then exit;
|
|
end;
|
|
{$IFDEF IDE_MEM_CHECK}CheckHeap(IntToStr(GetMem_Cnt));{$ENDIF}
|
|
// close Project
|
|
FreeThenNil(Project1);
|
|
{$IFDEF IDE_MEM_CHECK}CheckHeap(IntToStr(GetMem_Cnt));{$ENDIF}
|
|
Result:=mrOk;
|
|
{$IFDEF IDE_VERBOSE}
|
|
writeln('TMainIDE.DoCloseProject end ',CodeToolBoss.ConsistencyCheck);
|
|
{$ENDIF}
|
|
end;
|
|
|
|
function TMainIDE.DoOpenProjectFile(AFileName:string):TModalResult;
|
|
var Ext,AText,ACaption: string;
|
|
LowestEditorIndex,LowestUnitIndex,LastEditorIndex,i: integer;
|
|
NewBuf: TCodeBuffer;
|
|
begin
|
|
{$IFDEF IDE_VERBOSE}
|
|
writeln('TMainIDE.DoOpenProjectFile A "'+AFileName+'"');
|
|
{$ENDIF}
|
|
{$IFDEF IDE_MEM_CHECK}CheckHeap(IntToStr(GetMem_Cnt));{$ENDIF}
|
|
Result:=mrCancel;
|
|
if ExtractFileNameOnly(AFileName)='' then exit;
|
|
|
|
AFilename:=ExpandFileName(TrimFilename(AFilename));
|
|
Ext:=lowercase(ExtractFileExt(AFilename));
|
|
|
|
// check if file exists
|
|
if not FileExists(AFilename) then begin
|
|
ACaption:='File not found';
|
|
AText:='File "'+AFilename+'" not found.';
|
|
Result:=MessageDlg(ACaption, AText, mtError, [mbAbort], 0);
|
|
exit;
|
|
end;
|
|
|
|
// if there is a project info file, load that instead
|
|
if (Ext<>'.lpi') and (FileExists(ChangeFileExt(AFileName,'.lpi'))) then begin
|
|
// load instead of lazarus program file the project info file
|
|
AFileName:=ChangeFileExt(AFileName,'.lpi');
|
|
Ext:='.lpi';
|
|
end;
|
|
|
|
if (not FileIsText(AFilename)) then begin
|
|
ACaption:='File not text';
|
|
AText:='File "'+AFilename+'"'#13
|
|
+'does not look like a text file.'#13
|
|
+'Open it anyway?';
|
|
Result:=MessageDlg(ACaption, AText, mtConfirmation, [mbYes, mbAbort], 0);
|
|
if Result=mrAbort then exit;
|
|
end;
|
|
|
|
// close the old project
|
|
if SomethingOfProjectIsModified then begin
|
|
if MessageDlg('Project changed', 'Save changes to project?',
|
|
mtconfirmation,[mbYes, mbNo],0)=mrYes then
|
|
begin
|
|
if DoSaveProject([])=mrAbort then begin
|
|
Result:=mrAbort;
|
|
exit;
|
|
end;
|
|
end;
|
|
end;
|
|
Result:=DoCloseProject;
|
|
if Result=mrAbort then exit;
|
|
|
|
// create a new project
|
|
{$IFDEF IDE_VERBOSE}
|
|
writeln('TMainIDE.DoOpenProjectFile B');
|
|
{$ENDIF}
|
|
{$IFDEF IDE_MEM_CHECK}CheckHeap(IntToStr(GetMem_Cnt));{$ENDIF}
|
|
Project1:=TProject.Create(ptProgram);
|
|
Project1.OnFileBackup:=@DoBackupFile;
|
|
// read project info file
|
|
Project1.ReadProject(AFilename);
|
|
Result:=DoCompleteLoadingProjectInfo;
|
|
if Result<>mrOk then exit;
|
|
|
|
if Project1.MainUnit>=0 then begin
|
|
// read MainUnit Source
|
|
Result:=DoLoadCodeBuffer(NewBuf,Project1.MainFilename,
|
|
[lbfUpdateFromDisk,lbfRevert,lbfCheckIfText]);
|
|
if Result=mrIgnore then Result:=mrAbort;
|
|
if Result=mrAbort then exit;
|
|
Project1.MainUnitInfo.Source:=NewBuf;
|
|
end;
|
|
{$IFDEF IDE_DEBUG}
|
|
writeln('TMainIDE.DoOpenProjectFile C');
|
|
{$ENDIF}
|
|
{$IFDEF IDE_MEM_CHECK}CheckHeap(IntToStr(GetMem_Cnt));{$ENDIF}
|
|
|
|
// restore files
|
|
LastEditorIndex:=-1;
|
|
repeat
|
|
// find the unit which was loaded last time and has the lowest editor index
|
|
// of all not opened units
|
|
LowestUnitIndex:=-1;
|
|
LowestEditorIndex:=-1;
|
|
for i:=0 to Project1.UnitCount-1 do begin
|
|
if (Project1.Units[i].Loaded) then begin
|
|
if (Project1.Units[i].EditorIndex>LastEditorIndex)
|
|
and ((Project1.Units[i].EditorIndex<LowestEditorIndex)
|
|
or (LowestEditorIndex<0)) then
|
|
begin
|
|
LowestEditorIndex:=Project1.Units[i].EditorIndex;
|
|
LowestUnitIndex:=i;
|
|
end;
|
|
end;
|
|
end;
|
|
if LowestEditorIndex>=0 then begin
|
|
// reopen file
|
|
Result:=DoOpenEditorFile(Project1.Units[LowestUnitIndex].Filename,-1,
|
|
[ofProjectLoading,ofOnlyIfExists]);
|
|
if Result=mrAbort then begin
|
|
// mark all files, that are left to load as unloaded:
|
|
for i:=0 to Project1.UnitCount-1 do begin
|
|
if Project1.Units[i].Loaded
|
|
and (Project1.Units[i].EditorIndex>LastEditorIndex) then begin
|
|
Project1.Units[i].Loaded:=false;
|
|
Project1.Units[i].EditorIndex:=-1;
|
|
Project1.ActiveEditorIndexAtStart:=-1;
|
|
end;
|
|
end;
|
|
exit;
|
|
end;
|
|
if Result=mrOk then begin
|
|
// open successful
|
|
if Project1.ActiveEditorIndexAtStart=LowestEditorIndex then
|
|
Project1.ActiveEditorIndexAtStart:=SourceNoteBook.NoteBook.PageIndex;
|
|
LastEditorIndex:=LowestEditorIndex;
|
|
end else begin
|
|
// open failed -> ignore this unit
|
|
Project1.Units[LowestUnitIndex].EditorIndex:=-1;
|
|
Project1.Units[LowestUnitIndex].Loaded:=false;
|
|
if Project1.ActiveEditorIndexAtStart=LowestEditorIndex then
|
|
Project1.ActiveEditorIndexAtStart:=-1;
|
|
end;
|
|
end;
|
|
until LowestEditorIndex<0;
|
|
Result:=mrCancel;
|
|
{$IFDEF IDE_DEBUG}
|
|
writeln('TMainIDE.DoOpenProjectFile D');
|
|
{$ENDIF}
|
|
|
|
// set active editor source editor
|
|
if (SourceNoteBook.NoteBook<>nil) and (Project1.ActiveEditorIndexAtStart>=0)
|
|
and (Project1.ActiveEditorIndexAtStart<SourceNoteBook.NoteBook.Pages.Count)
|
|
then
|
|
SourceNoteBook.Notebook.PageIndex:=Project1.ActiveEditorIndexAtStart;
|
|
|
|
// select a form (object inspector, formeditor, control selection)
|
|
if FLastFormActivated<>nil then begin
|
|
PropertyEditorHook1.LookupRoot := FLastFormActivated;
|
|
TDesigner(FLastFormActivated.Designer).SelectOnlyThisComponent(
|
|
FLastFormActivated);
|
|
end;
|
|
|
|
// set all modified to false
|
|
for i:=0 to Project1.UnitCount-1 do begin
|
|
Project1.Units[i].Modified:=false;
|
|
end;
|
|
Project1.Modified:=false;
|
|
|
|
Result:=mrOk;
|
|
{$IFDEF IDE_VERBOSE}
|
|
writeln('TMainIDE.DoOpenProjectFile end CodeToolBoss.ConsistencyCheck=',CodeToolBoss.ConsistencyCheck);
|
|
{$ENDIF}
|
|
{$IFDEF IDE_MEM_CHECK}CheckHeap(IntToStr(GetMem_Cnt));{$ENDIF}
|
|
end;
|
|
|
|
function TMainIDE.DoCreateProjectForProgram(
|
|
ProgramBuf: TCodeBuffer): TModalResult;
|
|
var NewProjectType:TProjectType;
|
|
MainUnitInfo: TUnitInfo;
|
|
begin
|
|
{$IFDEF IDE_VERBOSE}
|
|
writeln('[TMainIDE.DoCreateProjectForProgram] A ',ProgramBuf.Filename);
|
|
{$ENDIF}
|
|
Result:=mrCancel;
|
|
|
|
if SomethingOfProjectIsModified then begin
|
|
if MessageDlg('Project changed','Save changes to project?',
|
|
mtconfirmation,[mbYes, mbNo],0)=mrYes then
|
|
begin
|
|
if DoSaveProject([])=mrAbort then begin
|
|
Result:=mrAbort;
|
|
exit;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
// let user choose the program type
|
|
if ChooseNewProject(NewProjectType)=mrCancel then exit;
|
|
|
|
// close old project
|
|
If Project1<>nil then begin
|
|
if DoCloseProject=mrAbort then begin
|
|
Result:=mrAbort;
|
|
exit;
|
|
end;
|
|
end;
|
|
|
|
// create a new project
|
|
Project1:=TProject.Create(NewProjectType);
|
|
Project1.OnFileBackup:=@DoBackupFile;
|
|
MainUnitInfo:=Project1.MainUnitInfo;
|
|
MainUnitInfo.Source:=ProgramBuf;
|
|
Project1.ProjectInfoFile:=ChangeFileExt(ProgramBuf.Filename,'.lpi');
|
|
Project1.CompilerOptions.CompilerPath:='$(CompPath)';
|
|
UpdateCaption;
|
|
|
|
// set project type specific things
|
|
if NewProjectType=ptApplication then begin
|
|
Project1.CompilerOptions.OtherUnitFiles:=
|
|
'$(LazarusDir)'+PathDelim+'lcl'+PathDelim+'units'
|
|
+';'+
|
|
'$(LazarusDir)'+PathDelim+'lcl'+PathDelim+'units'
|
|
+PathDelim
|
|
+CodeToolBoss.GlobalValues.Variables[ExternalMacroStart+'LCLWidgetType'];
|
|
end;
|
|
|
|
// rebuild project specific codetools defines
|
|
Result:=LoadCodeToolsDefines(CodeToolBoss,CodeToolsOpts,
|
|
Project1.ProjectInfoFile);
|
|
if Result<>mrOk then exit;
|
|
|
|
// show program unit
|
|
Result:=DoOpenMainUnit(false);
|
|
if Result=mrAbort then exit;
|
|
|
|
{$IFDEF IDE_VERBOSE}
|
|
writeln('[TMainIDE.DoCreateProjectForProgram] END');
|
|
{$ENDIF}
|
|
Result:=mrOk;
|
|
end;
|
|
|
|
function TMainIDE.DoAddActiveUnitToProject: TModalResult;
|
|
var
|
|
ActiveSourceEditor:TSourceEditor;
|
|
ActiveUnitInfo:TUnitInfo;
|
|
s, ShortUnitName: string;
|
|
begin
|
|
Result:=mrCancel;
|
|
GetCurrentUnit(ActiveSourceEditor,ActiveUnitInfo);
|
|
if ActiveUnitInfo<>nil then begin
|
|
if ActiveUnitInfo.IsPartOfProject=false then begin
|
|
if not ActiveUnitInfo.IsVirtual then
|
|
s:='"'+ActiveUnitInfo.Filename+'"'
|
|
else
|
|
s:='"'+SourceNotebook.Notebook.Pages[SourceNotebook.Notebook.PageIndex]
|
|
+'"';
|
|
if (Project1.ProjectType in [ptProgram, ptApplication])
|
|
and (ActiveUnitInfo.UnitName<>'')
|
|
and (Project1.IndexOfUnitWithName(ActiveUnitInfo.UnitName,
|
|
true,ActiveUnitInfo)>=0) then
|
|
begin
|
|
MessageDlg('Unable to add '+s+' to project, because there is already a '
|
|
+'unit with the same name in the Project1.',mtInformation,[mbOk],0);
|
|
end else begin
|
|
if MessageDlg('Add '+s+' to project?',mtConfirmation,[mbOk,mbCancel],0)
|
|
=mrOk then
|
|
begin
|
|
ActiveUnitInfo.IsPartOfProject:=true;
|
|
if (ActiveUnitInfo.UnitName<>'')
|
|
and (Project1.ProjectType in [ptProgram, ptApplication]) then begin
|
|
ActiveUnitInfo.ReadUnitNameFromSource;
|
|
ShortUnitName:=ActiveUnitInfo.UnitName;
|
|
if (ShortUnitName<>'') then
|
|
CodeToolBoss.AddUnitToMainUsesSection(
|
|
Project1.MainUnitInfo.Source,ShortUnitName,'');
|
|
end;
|
|
Project1.Modified:=true;
|
|
end;
|
|
end;
|
|
end else begin
|
|
if not ActiveUnitInfo.IsVirtual then
|
|
s:='The file "'+ActiveUnitInfo.Filename+'"'
|
|
else
|
|
s:='The file "'
|
|
+SourceNotebook.Notebook.Pages[SourceNotebook.Notebook.PageIndex]
|
|
+'"';
|
|
s:=s+' is already part of the Project1.';
|
|
MessageDlg(s,mtInformation,[mbOk],0);
|
|
end;
|
|
end else begin
|
|
Result:=mrOk;
|
|
end;
|
|
end;
|
|
|
|
function TMainIDE.DoRemoveFromProjectDialog: TModalResult;
|
|
var UnitList: TList;
|
|
i:integer;
|
|
AName: string;
|
|
AnUnitInfo: TUnitInfo;
|
|
Begin
|
|
UnitList:=TList.Create;
|
|
try
|
|
for i:=0 to Project1.UnitCount-1 do begin
|
|
AnUnitInfo:=Project1.Units[i];
|
|
if (AnUnitInfo.IsPartOfProject) and (i<>Project1.MainUnit) then begin
|
|
AName:=AnUnitInfo.FileName;
|
|
if (AnUnitInfo.EditorIndex>=0) then
|
|
AName:=SourceNotebook.NoteBook.Pages[AnUnitInfo.EditorIndex];
|
|
UnitList.Add(TViewUnitsEntry.Create(AName,i,false));
|
|
end;
|
|
end;
|
|
if ShowViewUnitsDlg(UnitList,true,'Remove from project')=mrOk then begin
|
|
for i:=0 to UnitList.Count-1 do begin
|
|
if TViewUnitsEntry(UnitList[i]).Selected then begin
|
|
AnUnitInfo:=Project1.Units[TViewUnitsEntry(UnitList[i]).ID];
|
|
AnUnitInfo.IsPartOfProject:=false;
|
|
if (Project1.MainUnit>=0)
|
|
and (Project1.ProjectType in [ptProgram, ptApplication]) then begin
|
|
if (AnUnitInfo.UnitName<>'') then
|
|
CodeToolBoss.RemoveUnitFromAllUsesSections(
|
|
Project1.MainUnitInfo.Source,AnUnitInfo.UnitName);
|
|
if (AnUnitInfo.FormName<>'') then
|
|
Project1.RemoveCreateFormFromProjectFile(
|
|
'T'+AnUnitInfo.FormName,AnUnitInfo.FormName);
|
|
end;
|
|
end;
|
|
end;
|
|
end;
|
|
finally
|
|
UnitList.Free;
|
|
end;
|
|
Result:=mrOk;
|
|
end;
|
|
|
|
function TMainIDE.DoSaveProjectToTestDirectory: TModalResult;
|
|
begin
|
|
Result:=mrCancel;
|
|
if (EnvironmentOptions.TestBuildDirectory='')
|
|
or (not DirectoryExists(EnvironmentOptions.TestBuildDirectory)) then begin
|
|
if (EnvironmentOptions.TestBuildDirectory<>'') then begin
|
|
MessageDlg('The Test Directory could not be found:'#13
|
|
+'"'+EnvironmentOptions.TestBuildDirectory+'"'#13
|
|
+'(see environment options)',mtError,[mbCancel],0);
|
|
Result:=mrCancel;
|
|
exit;
|
|
end;
|
|
Result:=MessageDlg('Build new project',
|
|
'The project must be saved before building'#13
|
|
+'If you set the Test Directory in the environment options,'#13
|
|
+'you can create new projects and build them at once.'#13
|
|
+'Save project?',mtInformation,[mbYes,mbNo],0);
|
|
if Result<>mrYes then exit;
|
|
Result:=DoSaveAll;
|
|
exit;
|
|
end;
|
|
Result:=DoSaveProject([sfSaveToTestDir]);
|
|
end;
|
|
|
|
function TMainIDE.DoBuildProject(BuildAll: boolean): TModalResult;
|
|
var
|
|
DefaultFilename: string;
|
|
begin
|
|
Result:=mrCancel;
|
|
if ToolStatus<>itNone then begin
|
|
Result:=mrAbort;
|
|
exit;
|
|
end;
|
|
if Project1=nil then Begin
|
|
MessageDlg('Create a project first!',mterror,[mbok],0);
|
|
Exit;
|
|
end;
|
|
try
|
|
// check for a main file to compile
|
|
if Project1.MainFilename='' then exit;
|
|
|
|
// save all files
|
|
if not Project1.IsVirtual then
|
|
Result:=DoSaveAll
|
|
else
|
|
Result:=DoSaveProjectToTestDirectory;
|
|
if Result<>mrOk then exit;
|
|
|
|
// get main source filename
|
|
if not Project1.IsVirtual then
|
|
DefaultFilename:=''
|
|
else
|
|
DefaultFilename:=GetTestUnitFilename(Project1.MainUnitInfo);
|
|
|
|
// clear old error lines
|
|
SourceNotebook.ClearErrorLines;
|
|
|
|
// change tool status
|
|
ToolStatus:=itBuilder;
|
|
|
|
// show messages
|
|
MessagesView.Clear;
|
|
DoArrangeSourceEditorAndMessageView;
|
|
|
|
// compile
|
|
TheOutputFilter.OnOutputString:=@MessagesView.Add;
|
|
Result:=TheCompiler.Compile(Project1,BuildAll,DefaultFilename);
|
|
if Result=mrOk then begin
|
|
MessagesView.MessageView.Items.Add(
|
|
'Project "'+Project1.Title+'" successfully built. :)');
|
|
end else begin
|
|
DoJumpToCompilerMessage(-1,true);
|
|
end;
|
|
DoCheckFilesOnDisk;
|
|
finally
|
|
ToolStatus:=itNone;
|
|
end;
|
|
end;
|
|
|
|
function TMainIDE.DoInitProjectRun: TModalResult;
|
|
var
|
|
ProgramFilename, WorkingDir: String;
|
|
begin
|
|
if ToolStatus <> itNone
|
|
then begin
|
|
// already running so no initialization needed
|
|
Result := mrOk;
|
|
Exit;
|
|
end;
|
|
|
|
Result := mrCancel;
|
|
|
|
// Check if we can run this project
|
|
if not (Project1.ProjectType in [ptProgram, ptApplication, ptCustomProgram])
|
|
or (Project1.MainUnit < 0)
|
|
or (ToolStatus <> itNone)
|
|
then Exit;
|
|
|
|
// Build project first
|
|
if DoBuildProject(false) <> mrOk
|
|
then Exit;
|
|
|
|
// Check project build
|
|
ProgramFilename := GetProjectTargetFilename;
|
|
if not FileExists(ProgramFilename)
|
|
then begin
|
|
MessageDlg('File not found',
|
|
Format('No program file "%s" found!', [ProgramFilename]), mtError,
|
|
[mbCancel], 0);
|
|
Exit;
|
|
end;
|
|
|
|
// Setup debugger
|
|
case EnvironmentOptions.DebuggerType of
|
|
dtGnuDebugger: begin
|
|
if (DebugBoss.DoInitDebugger <> mrOk)
|
|
then Exit;
|
|
// ToDo: set working directory
|
|
end;
|
|
else
|
|
// Temp solution, in future it will be run by dummy debugger
|
|
try
|
|
CheckIfFileIsExecutable(ProgramFilename);
|
|
FRunProcess := TProcess.Create(nil);
|
|
FRunProcess.CommandLine := GetRunCommandLine;
|
|
WorkingDir:=Project1.RunParameterOptions.WorkingDirectory;
|
|
if WorkingDir='' then
|
|
WorkingDir:=ExtractFilePath(GetProjectTargetFilename);
|
|
MacroList.SubstituteStr(WorkingDir);
|
|
FRunProcess.CurrentDirectory:=ExpandFilename(WorkingDir);
|
|
|
|
FRunProcess.Options:= [poNoConsole];
|
|
FRunProcess.ShowWindow := swoNone;
|
|
except
|
|
on e: Exception do
|
|
MessageDlg(Format('Error initializing program'#13 +
|
|
'"%s"'#13 +
|
|
'Error: %s', [ProgramFilename, e.Message]), mterror, [mbok], 0);
|
|
end;
|
|
end;
|
|
|
|
Result := mrOK;
|
|
ToolStatus := itDebugger;
|
|
end;
|
|
|
|
function TMainIDE.DoRunProject: TModalResult;
|
|
begin
|
|
Writeln('[TMainIDE.DoRunProject] A');
|
|
|
|
if (DoInitProjectRun <> mrOK)
|
|
or (ToolStatus <> itDebugger)
|
|
then begin
|
|
Result := mrAbort;
|
|
Exit;
|
|
end;
|
|
|
|
Result := mrCancel;
|
|
|
|
if EnvironmentOptions.DebuggerType <> dtNone then begin
|
|
DebugBoss.RunDebugger;
|
|
Result := mrOK;
|
|
end else begin
|
|
if FRunProcess = nil then Exit;
|
|
try
|
|
Writeln(' EXECUTING "',FRunProcess.CommandLine,'"');
|
|
Writeln(' WorkingDir "',FRunProcess.CurrentDirectory,'"');
|
|
FRunProcess.Execute;
|
|
ToolStatus:=itNone;
|
|
Result := mrOk;
|
|
except
|
|
on e: Exception do
|
|
MessageDlg(Format('Error initializing program'#13 +
|
|
'"%s"'#13 +
|
|
'Error: %s',
|
|
[FRunProcess.CommandLine, e.Message]), mtError,
|
|
[mbOk], 0);
|
|
end;
|
|
end;
|
|
Writeln('[TMainIDE.DoRunProject] END');
|
|
end;
|
|
|
|
function TMainIDE.SomethingOfProjectIsModified: boolean;
|
|
begin
|
|
Result:=(Project1<>nil)
|
|
and (Project1.SomethingModified or SourceNotebook.SomethingModified);
|
|
end;
|
|
|
|
function TMainIDE.DoSaveAll: TModalResult;
|
|
begin
|
|
writeln('TMainIDE.DoSaveAll');
|
|
Result:=DoSaveProject([]);
|
|
SaveEnvironment;
|
|
SaveIncludeLinks;
|
|
InputHistories.Save;
|
|
// ToDo: save package, cvs settings, ...
|
|
end;
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
function TMainIDE.DoRunExternalTool(Index: integer): TModalResult;
|
|
begin
|
|
SourceNotebook.ClearErrorLines;
|
|
Result:=EnvironmentOptions.ExternalTools.Run(Index,MacroList);
|
|
DoCheckFilesOnDisk;
|
|
end;
|
|
|
|
function TMainIDE.DoBuildLazarus: TModalResult;
|
|
begin
|
|
SourceNotebook.ClearErrorLines;
|
|
Result:=BuildLazarus(MiscellaneousOptions.BuildLazOpts,
|
|
EnvironmentOptions.ExternalTools,MacroList);
|
|
DoCheckFilesOnDisk;
|
|
end;
|
|
|
|
function TMainIDE.DoConvertDFMtoLFM: TModalResult;
|
|
var
|
|
OpenDialog: TOpenDialog;
|
|
i: integer;
|
|
AFilename: string;
|
|
begin
|
|
Result:=mrOk;
|
|
OpenDialog:=TOpenDialog.Create(Self);
|
|
try
|
|
InputHistories.ApplyFileDialogSettings(OpenDialog);
|
|
OpenDialog.Title:=lisSelectDFMFiles;
|
|
OpenDialog.Options:=OpenDialog.Options+[ofAllowMultiSelect];
|
|
if OpenDialog.Execute and (OpenDialog.Files.Count>0) then begin
|
|
For I := 0 to OpenDialog.Files.Count-1 do begin
|
|
AFilename:=ExpandFilename(OpenDialog.Files.Strings[i]);
|
|
if DoConvertDFMFileToLFMFile(AFilename)=mrAbort then begin
|
|
Result:=mrAbort;
|
|
break;
|
|
end else
|
|
Result:=mrOk;
|
|
end;
|
|
SaveEnvironment;
|
|
end;
|
|
InputHistories.StoreFileDialogSettings(OpenDialog);
|
|
finally
|
|
OpenDialog.Free;
|
|
end;
|
|
DoCheckFilesOnDisk;
|
|
end;
|
|
|
|
function TMainIDE.DoCheckSyntax: TModalResult;
|
|
var
|
|
ActiveUnitInfo:TUnitInfo;
|
|
ActiveSrcEdit:TSourceEditor;
|
|
NewCode: TCodeBuffer;
|
|
NewX, NewY, NewTopLine: integer;
|
|
ErrorMsg: string;
|
|
begin
|
|
Result:=mrOk;
|
|
GetCurrentUnit(ActiveSrcEdit,ActiveUnitInfo);
|
|
if (ActiveUnitInfo=nil) or (ActiveUnitInfo.Source=nil)
|
|
or (ActiveSrcEdit=nil) then exit;
|
|
SaveSourceEditorChangesToCodeCache(-1);
|
|
CodeToolBoss.VisibleEditorLines:=ActiveSrcEdit.EditorComponent.LinesInWindow;
|
|
if not CodeToolBoss.CheckSyntax(ActiveUnitInfo.Source,NewCode,NewX,NewY,
|
|
NewTopLine,ErrorMsg) then
|
|
begin
|
|
DoJumpToCodeToolBossError;
|
|
end;
|
|
end;
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
procedure TMainIDE.GetCurrentUnit(var ActiveSourceEditor:TSourceEditor;
|
|
var ActiveUnitInfo:TUnitInfo);
|
|
begin
|
|
if SourceNoteBook.NoteBook=nil then begin
|
|
ActiveSourceEditor:=nil;
|
|
ActiveUnitInfo:=nil;
|
|
end else begin
|
|
GetUnitWithPageIndex(SourceNotebook.NoteBook.PageIndex,ActiveSourceEditor,
|
|
ActiveUnitInfo);
|
|
end;
|
|
end;
|
|
|
|
procedure TMainIDE.GetUnitWithPageIndex(PageIndex:integer;
|
|
var ActiveSourceEditor:TSourceEditor; var ActiveUnitInfo:TUnitInfo);
|
|
begin
|
|
if SourceNoteBook.NoteBook=nil then begin
|
|
ActiveSourceEditor:=nil;
|
|
ActiveUnitInfo:=nil;
|
|
end else begin
|
|
ActiveSourceEditor:=SourceNoteBook.FindSourceEditorWithPageIndex(PageIndex);
|
|
if ActiveSourceEditor=nil then
|
|
ActiveUnitInfo:=nil
|
|
else
|
|
ActiveUnitInfo:=Project1.UnitWithEditorIndex(PageIndex);
|
|
end;
|
|
end;
|
|
|
|
function TMainIDE.GetSourceEditorForUnitInfo(AnUnitInfo: TUnitInfo
|
|
): TSourceEditor;
|
|
begin
|
|
Result:=SourceNoteBook.FindSourceEditorWithPageIndex(AnUnitInfo.EditorIndex);
|
|
end;
|
|
|
|
function TMainIDE.DoSaveStreamToFile(AStream:TStream;
|
|
const Filename:string; IsPartOfProject:boolean):TModalResult;
|
|
// save to file with backup and user interaction
|
|
var AText,ACaption:string;
|
|
NewBuf: TCodeBuffer;
|
|
begin
|
|
Result:=DoBackupFile(Filename,IsPartOfProject);
|
|
if Result<>mrOk then exit;
|
|
repeat
|
|
NewBuf:=CodeToolBoss.CreateFile(FileName);
|
|
if (NewBuf<>nil) or (not NewBuf.SaveToFile(Filename)) then begin
|
|
ACaption:='Write error';
|
|
AText:='Unable to save file "'+Filename+'"';
|
|
Result:=MessageDlg(ACaption,AText,mterror, [mbabort, mbretry, mbignore],0);
|
|
if Result=mrIgnore then Result:=mrOk;
|
|
if Result=mrAbort then exit;
|
|
end;
|
|
until Result<>mrRetry;
|
|
end;
|
|
|
|
function TMainIDE.DoLoadMemoryStreamFromFile(MemStream: TMemoryStream;
|
|
const AFilename:string): TModalResult;
|
|
var FileStream: TFileStream;
|
|
ACaption,AText:string;
|
|
begin
|
|
repeat
|
|
try
|
|
FileStream:=TFileStream.Create(AFilename,fmOpenRead);
|
|
try
|
|
FileStream.Position:=0;
|
|
MemStream.CopyFrom(FileStream,FileStream.Size);
|
|
MemStream.Position:=0;
|
|
finally
|
|
FileStream.Free;
|
|
end;
|
|
Result:=mrOk;
|
|
except
|
|
ACaption:='Read Error';
|
|
AText:='Unable to read file "'+AFilename+'"!';
|
|
result := Application.MessageBox(PChar(aText),pChar(aCaption),mb_IconError+mb_AbortRetryIgnore);
|
|
if Result=mrAbort then exit;
|
|
end;
|
|
until Result<>mrRetry;
|
|
end;
|
|
|
|
function TMainIDE.DoSaveCodeBufferToFile(ABuffer: TCodeBuffer;
|
|
const AFilename: string; IsPartOfProject:boolean): TModalResult;
|
|
var
|
|
ACaption,AText:string;
|
|
begin
|
|
Result:=DoBackupFile(AFilename,IsPartOfProject);
|
|
if Result<>mrOk then exit;
|
|
repeat
|
|
if ABuffer.SaveToFile(AFilename) then begin
|
|
Result:=mrOk;
|
|
end else begin
|
|
ACaption:='Write Error';
|
|
AText:='Unable to write to file "'+AFilename+'"!';
|
|
Result:=MessageDlg(ACaption,AText,mtError,[mbAbort, mbRetry, mbIgnore],0);
|
|
if Result=mrAbort then exit;
|
|
if Result=mrIgnore then Result:=mrOk;
|
|
end;
|
|
until Result<>mrRetry;
|
|
end;
|
|
|
|
function TMainIDE.DoLoadCodeBuffer(var ACodeBuffer: TCodeBuffer;
|
|
const AFilename: string; Flags: TLoadBufferFlags): TModalResult;
|
|
var
|
|
ACaption,AText:string;
|
|
begin
|
|
repeat
|
|
{$IFDEF IDE_DEBUG}
|
|
writeln('[TMainIDE.DoLoadCodeBuffer] A ',AFilename);
|
|
{$ENDIF}
|
|
if (lbfCheckIfText in Flags)
|
|
and FileExists(AFilename) and (not FileIsText(AFilename))
|
|
then begin
|
|
ACaption:='File not text';
|
|
AText:='File "'+AFilename+'"'#13
|
|
+'does not look like a text file.'#13
|
|
+'Open it anyway?';
|
|
Result:=MessageDlg(ACaption, AText, mtConfirmation,
|
|
[mbOk, mbIgnore, mbAbort], 0);
|
|
if Result<>mrOk then exit;
|
|
end;
|
|
ACodeBuffer:=CodeToolBoss.LoadFile(AFilename,lbfUpdateFromDisk in Flags,
|
|
lbfRevert in Flags);
|
|
if ACodeBuffer<>nil then begin
|
|
Result:=mrOk;
|
|
{$IFDEF IDE_DEBUG}
|
|
writeln('[TMainIDE.DoLoadCodeBuffer] ',ACodeBuffer.SourceLength,' ',ACodeBuffer.Filename);
|
|
{$ENDIF}
|
|
end else begin
|
|
ACaption:='Read Error';
|
|
AText:='Unable to read file "'+AFilename+'"!';
|
|
Result:=MessageDlg(ACaption,AText,mterror,[mbAbort, mbRetry, mbIgnore],0);
|
|
if Result=mrAbort then exit;
|
|
end;
|
|
until Result<>mrRetry;
|
|
end;
|
|
|
|
{-------------------------------------------------------------------------------
|
|
TMainIDE DoBackupFile
|
|
|
|
Params: const Filename:string;
|
|
IsPartOfProject:boolean
|
|
Returns: TModalResult
|
|
|
|
Rename existing file to backup file.
|
|
-------------------------------------------------------------------------------}
|
|
function TMainIDE.DoBackupFile(const Filename:string;
|
|
IsPartOfProject:boolean): TModalResult;
|
|
var BackupFilename, CounterFilename: string;
|
|
AText,ACaption:string;
|
|
BackupInfo: TBackupInfo;
|
|
FilePath, FileNameOnly, FileExt, SubDir: string;
|
|
i: integer;
|
|
begin
|
|
Result:=mrOk;
|
|
if not (FileExists(Filename)) then exit;
|
|
if IsPartOfProject then
|
|
BackupInfo:=EnvironmentOptions.BackupInfoProjectFiles
|
|
else
|
|
BackupInfo:=EnvironmentOptions.BackupInfoOtherFiles;
|
|
if (BackupInfo.BackupType=bakNone)
|
|
or ((BackupInfo.BackupType=bakSameName) and (BackupInfo.SubDirectory='')) then
|
|
exit;
|
|
FilePath:=ExtractFilePath(Filename);
|
|
FileExt:=ExtractFileExt(Filename);
|
|
FileNameOnly:=ExtractFilenameOnly(Filename);
|
|
if BackupInfo.SubDirectory<>'' then begin
|
|
SubDir:=FilePath+BackupInfo.SubDirectory;
|
|
repeat
|
|
if not DirectoryExists(SubDir) then begin
|
|
if not CreateDir(SubDir) then begin
|
|
Result:=MessageDlg('Unable to create backup directory "'+SubDir+'".'
|
|
,mtWarning,[mbAbort,mbRetry,mbIgnore],0);
|
|
if Result=mrAbort then exit;
|
|
if Result=mrIgnore then Result:=mrOk;
|
|
end;
|
|
end;
|
|
until Result<>mrRetry;
|
|
end;
|
|
if BackupInfo.BackupType in
|
|
[bakSymbolInFront,bakSymbolBehind,bakUserDefinedAddExt,bakSameName] then
|
|
begin
|
|
case BackupInfo.BackupType of
|
|
bakSymbolInFront:
|
|
BackupFilename:=FileNameOnly+'.~'+copy(FileExt,2,length(FileExt)-1);
|
|
bakSymbolBehind:
|
|
BackupFilename:=FileNameOnly+FileExt+'~';
|
|
bakUserDefinedAddExt:
|
|
BackupFilename:=FileNameOnly+FileExt+'.'+BackupInfo.AdditionalExtension;
|
|
bakSameName:
|
|
BackupFilename:=FileNameOnly+FileExt;
|
|
end;
|
|
if BackupInfo.SubDirectory<>'' then
|
|
BackupFilename:=SubDir+PathDelim+BackupFilename
|
|
else
|
|
BackupFilename:=FilePath+BackupFilename;
|
|
// remove old backup file
|
|
repeat
|
|
if FileExists(BackupFilename) then begin
|
|
if not DeleteFile(BackupFilename) then begin
|
|
ACaption:='Delete file failed';
|
|
AText:='Unable to remove old backup file "'+BackupFilename+'"!';
|
|
Result:=MessageDlg(ACaption,AText,mtError,[mbAbort,mbRetry,mbIgnore],
|
|
0);
|
|
if Result=mrAbort then exit;
|
|
if Result=mrIgnore then Result:=mrOk;
|
|
end;
|
|
end;
|
|
until Result<>mrRetry;
|
|
end else begin
|
|
// backup with counter
|
|
if BackupInfo.SubDirectory<>'' then
|
|
BackupFilename:=SubDir+PathDelim+FileNameOnly+FileExt+';'
|
|
else
|
|
BackupFilename:=Filename+';';
|
|
if BackupInfo.MaxCounter<=0 then begin
|
|
// search first non existing backup filename
|
|
i:=1;
|
|
while FileExists(BackupFilename+IntToStr(i)) do inc(i);
|
|
BackupFilename:=BackupFilename+IntToStr(i);
|
|
end else begin
|
|
// rename all backup files (increase number)
|
|
i:=1;
|
|
while FileExists(BackupFilename+IntToStr(i))
|
|
and (i<=BackupInfo.MaxCounter) do inc(i);
|
|
if i>BackupInfo.MaxCounter then begin
|
|
dec(i);
|
|
CounterFilename:=BackupFilename+IntToStr(BackupInfo.MaxCounter);
|
|
// remove old backup file
|
|
repeat
|
|
if FileExists(CounterFilename) then begin
|
|
if not DeleteFile(CounterFilename) then begin
|
|
ACaption:='Delete file failed';
|
|
AText:='Unable to remove old backup file "'+CounterFilename+'"!';
|
|
Result:=MessageDlg(ACaption,AText,mtError,
|
|
[mbAbort,mbRetry,mbIgnore],0);
|
|
if Result=mrAbort then exit;
|
|
if Result=mrIgnore then Result:=mrOk;
|
|
end;
|
|
end;
|
|
until Result<>mrRetry;
|
|
end;
|
|
// rename all old backup files
|
|
dec(i);
|
|
while i>=1 do begin
|
|
repeat
|
|
if not RenameFile(BackupFilename+IntToStr(i),
|
|
BackupFilename+IntToStr(i+1)) then
|
|
begin
|
|
ACaption:='Rename file failed';
|
|
AText:='Unable to rename file "'+BackupFilename+IntToStr(i)
|
|
+'" to "'+BackupFilename+IntToStr(i+1)+'"!';
|
|
Result:=MessageDlg(ACaption,AText,mtError,
|
|
[mbAbort,mbRetry,mbIgnore],0);
|
|
if Result=mrAbort then exit;
|
|
if Result=mrIgnore then Result:=mrOk;
|
|
end;
|
|
until Result<>mrRetry;
|
|
dec(i);
|
|
end;
|
|
BackupFilename:=BackupFilename+'1';
|
|
end;
|
|
end;
|
|
// backup file
|
|
repeat
|
|
if not BackupFile(Filename,BackupFilename) then begin
|
|
ACaption:='Backup file failed';
|
|
AText:='Unable to backup file "'+Filename+'" to "'+BackupFilename+'"!';
|
|
Result:=MessageDlg(ACaption,AText,mterror,[mbabort,mbretry,mbignore],0);
|
|
if Result=mrAbort then exit;
|
|
if Result=mrIgnore then Result:=mrOk;
|
|
end;
|
|
until Result<>mrRetry;
|
|
end;
|
|
|
|
function TMainIDE.DoCheckFilesOnDisk: TModalResult;
|
|
var
|
|
AnUnitList: TList; // list of TUnitInfo
|
|
i: integer;
|
|
CurUnit: TUnitInfo;
|
|
begin
|
|
Result:=mrOk;
|
|
Project1.GetUnitsChangedOnDisk(AnUnitList);
|
|
if AnUnitList=nil then exit;
|
|
Result:=ShowDiskDiffsDialog(AnUnitList);
|
|
if Result in [mrYesToAll] then
|
|
Result:=mrOk;
|
|
for i:=0 to AnUnitList.Count-1 do begin
|
|
CurUnit:=TUnitInfo(AnUnitList[i]);
|
|
if Result in [mrYesToAll] then begin
|
|
if CurUnit.EditorIndex>=0 then begin
|
|
Result:=DoOpenEditorFile('',CurUnit.EditorIndex,[ofRevert]);
|
|
end else if CurUnit.IsMainUnit then begin
|
|
Result:=DoRevertMainUnit;
|
|
end else
|
|
Result:=mrIgnore;
|
|
if Result=mrAbort then exit;
|
|
end else begin
|
|
CurUnit.IgnoreCurrentFileDateOnDisk;
|
|
end;
|
|
Result:=mrOk;
|
|
end;
|
|
AnUnitList.Free;
|
|
end;
|
|
|
|
procedure TMainIDE.UpdateCaption;
|
|
var NewCaption:string;
|
|
begin
|
|
NewCaption := 'Lazarus Editor v'+Version_String;
|
|
if Project1<>nil then begin
|
|
if Project1.Title<>'' then
|
|
NewCaption:=NewCaption +' - '+Project1.Title
|
|
else if Project1.ProjectInfoFile<>'' then
|
|
NewCaption:=NewCaption+' - '+ExtractFileName(Project1.ProjectInfoFile)
|
|
else
|
|
NewCaption:=NewCaption+' - (new project)'
|
|
end;
|
|
Caption:=NewCaption;
|
|
end;
|
|
|
|
procedure TMainIDE.DoBringToFrontFormOrUnit;
|
|
var AForm: TCustomForm;
|
|
ActiveUnitInfo: TUnitInfo;
|
|
begin
|
|
AForm:=nil;
|
|
if FCodeLastActivated then begin
|
|
if SourceNoteBook.NoteBook<>nil then begin
|
|
AForm:=SourceNotebook;
|
|
if FLastFormActivated<>nil then begin
|
|
ActiveUnitInfo := Project1.UnitWithForm(FLastFormActivated);
|
|
if (ActiveUnitInfo <> nil) and (ActiveUnitInfo.EditorIndex>=0) then
|
|
begin
|
|
SourceNotebook.Notebook.PageIndex := ActiveUnitInfo.EditorIndex;
|
|
end;
|
|
end;
|
|
end;
|
|
end
|
|
else
|
|
begin
|
|
if (SourceNoteBook.NoteBook<>nil) then begin
|
|
ActiveUnitInfo:=Project1.UnitWithEditorIndex(
|
|
SourceNoteBook.NoteBook.PageIndex);
|
|
if (ActiveUnitInfo<>nil) then
|
|
AForm:=TCustomForm(ActiveUnitInfo.Form);
|
|
FLastFormActivated := AForm;
|
|
end;
|
|
end;
|
|
if AForm<>nil then begin
|
|
BringWindowToTop(AForm.Handle);
|
|
if FLastFormActivated=AForm then begin
|
|
// select the new form (object inspector, formeditor, control selection)
|
|
PropertyEditorHook1.LookupRoot := AForm;
|
|
TDesigner(AForm.Designer).SelectOnlyThisComponent(AForm);
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
procedure TMainIDE.OnMacroSubstitution(TheMacro: TTransferMacro; var s:string;
|
|
var Handled, Abort: boolean);
|
|
var MacroName:string;
|
|
begin
|
|
if TheMacro=nil then exit;
|
|
MacroName:=lowercase(TheMacro.Name);
|
|
if MacroName='save' then begin
|
|
Handled:=true;
|
|
if SourceNoteBook.NoteBook<>nil then
|
|
Abort:=(DoSaveEditorFile(SourceNoteBook.NoteBook.PageIndex,[])<>mrOk);
|
|
s:='';
|
|
end else if MacroName='saveall' then begin
|
|
Handled:=true;
|
|
Abort:=(DoSaveAll<>mrOk);
|
|
s:='';
|
|
end else if MacroName='edfile' then begin
|
|
Handled:=true;
|
|
if SourceNoteBook.NoteBook<>nil then
|
|
s:=Project1.UnitWithEditorIndex(SourceNoteBook.NoteBook.PageIndex).Filename
|
|
else
|
|
s:='';
|
|
end else if MacroName='col' then begin
|
|
Handled:=true;
|
|
if SourceNoteBook.NoteBook<>nil then
|
|
s:=IntToStr(SourceNoteBook.GetActiveSE.EditorComponent.CaretX);
|
|
end else if MacroName='row' then begin
|
|
Handled:=true;
|
|
if SourceNoteBook.NoteBook<>nil then
|
|
s:=IntToStr(SourceNoteBook.GetActiveSE.EditorComponent.CaretY);
|
|
end else if MacroName='projfile' then begin
|
|
Handled:=true;
|
|
s:=Project1.MainFilename;
|
|
end else if MacroName='projpath' then begin
|
|
Handled:=true;
|
|
s:=Project1.ProjectDirectory;
|
|
end else if MacroName='curtoken' then begin
|
|
Handled:=true;
|
|
if SourceNoteBook.NoteBook<>nil then
|
|
s:=SourceNoteBook.GetActiveSE.EditorComponent.GetWordAtRowCol(
|
|
SourceNoteBook.GetActiveSE.EditorComponent.CaretXY);
|
|
end else if MacroName='lazarusdir' then begin
|
|
Handled:=true;
|
|
s:=EnvironmentOptions.LazarusDirectory;
|
|
if s='' then s:=ExtractFilePath(ParamStr(0));
|
|
end else if MacroName='lclwidgettype' then begin
|
|
Handled:=true;
|
|
s:=Project1.CompilerOptions.LCLWidgetType;
|
|
if s='' then s:='gtk';
|
|
end else if MacroName='fpcsrcdir' then begin
|
|
Handled:=true;
|
|
s:=EnvironmentOptions.FPCSourceDirectory;
|
|
end else if MacroName='comppath' then begin
|
|
Handled:=true;
|
|
s:=EnvironmentOptions.CompilerFilename;
|
|
end else if MacroName='params' then begin
|
|
Handled:=true;
|
|
s:=Project1.RunParameterOptions.CmdLineParams;
|
|
end else if MacroName='targetfile' then begin
|
|
Handled:=true;
|
|
s:=GetProjectTargetFilename;
|
|
end else if MacroName='targetcmdline' then begin
|
|
Handled:=true;
|
|
s:=Project1.RunParameterOptions.CmdLineParams;
|
|
if s='' then
|
|
s:=GetProjectTargetFilename
|
|
else
|
|
s:=GetProjectTargetFilename+' '+s;
|
|
end else if MacroName='runcmdline' then begin
|
|
Handled:=true;
|
|
s:=GetRunCommandLine;
|
|
end;
|
|
end;
|
|
|
|
function TMainIDE.OnMacroPromptFunction(const s:string;
|
|
var Abort: boolean):string;
|
|
begin
|
|
Result:=s;
|
|
Abort:=(ShowMacroPromptDialog(Result)<>mrOk);
|
|
end;
|
|
|
|
procedure TMainIDE.OnCmdLineCreate(var CmdLine: string; var Abort:boolean);
|
|
// replace all transfer macros in command line
|
|
begin
|
|
Abort:=not MacroList.SubstituteStr(CmdLine);
|
|
end;
|
|
|
|
function TMainIDE.DoJumpToCompilerMessage(Index:integer;
|
|
FocusEditor: boolean): boolean;
|
|
var MaxMessages: integer;
|
|
Filename, Ext, SearchedFilename: string;
|
|
CaretXY: TPoint;
|
|
TopLine: integer;
|
|
MsgType: TErrorType;
|
|
SrcEdit: TSourceEditor;
|
|
begin
|
|
Result:=false;
|
|
MaxMessages:=MessagesView.MessageView.Items.Count;
|
|
if Index>=MaxMessages then exit;
|
|
if (Index<0) then begin
|
|
// search relevant message (first error, first fatal)
|
|
Index:=0;
|
|
while (Index<MaxMessages) do begin
|
|
if (TheOutputFilter.GetSourcePosition(
|
|
MessagesView.MessageView.Items[Index],
|
|
Filename,CaretXY,MsgType)) then
|
|
begin
|
|
if MsgType in [etError,etFatal,etPanic] then break;
|
|
end;
|
|
inc(Index);
|
|
end;
|
|
if Index>=MaxMessages then exit;
|
|
MessagesView.MessageView.ItemIndex:=Index;
|
|
end;
|
|
if TheOutputFilter.GetSourcePosition(MessagesView.MessageView.Items[Index],
|
|
Filename,CaretXY,MsgType) then begin
|
|
SearchedFilename := FindUnitFile(Filename);
|
|
if SearchedFilename<>'' then begin
|
|
// open the file in the source editor
|
|
Ext:=lowercase(ExtractFileExt(SearchedFilename));
|
|
if (not FilenameIsFormText(SearchedFilename)) and (Ext<>'.lpi') then begin
|
|
Result:=(DoOpenEditorFile(SearchedFilename,-1,[ofOnlyIfExists])=mrOk);
|
|
if Result then begin
|
|
// set caret position
|
|
SourceNotebook.AddJumpPointClicked(Self);
|
|
SrcEdit:=SourceNoteBook.GetActiveSE;
|
|
TopLine:=CaretXY.Y-(SrcEdit.EditorComponent.LinesInWindow div 2);
|
|
if TopLine<1 then TopLine:=1;
|
|
if FocusEditor then begin
|
|
//SourceNotebook.BringToFront;
|
|
SrcEdit.EditorComponent.SetFocus;
|
|
BringWindowToTop(SourceNoteBook.Handle);
|
|
end;
|
|
SrcEdit.EditorComponent.CaretXY:=CaretXY;
|
|
SrcEdit.EditorComponent.TopLine:=TopLine;
|
|
with SrcEdit.EditorComponent do begin
|
|
BlockBegin:=CaretXY;
|
|
BlockEnd:=CaretXY;
|
|
LeftChar:=Max(CaretXY.X-CharsInWindow,1);
|
|
end;
|
|
SrcEdit.ErrorLine:=CaretXY.Y;
|
|
end;
|
|
end;
|
|
end else begin
|
|
if FilenameIsAbsolute(Filename) then begin
|
|
MessageDlg('Unable to find file "'+Filename+'".',
|
|
mtInformation,[mbOk],0)
|
|
end else begin
|
|
MessageDlg('Unable to find file "'+Filename+'".'#13
|
|
+'Check search path in'#13
|
|
+'Run->Compiler Options...->Search Paths->Other Unit Files',
|
|
mtInformation,[mbOk],0);
|
|
end;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
procedure TMainIDE.DoShowMessagesView;
|
|
var
|
|
WasVisible: boolean;
|
|
ALayout: TIDEWindowLayout;
|
|
begin
|
|
WasVisible:=MessagesView.Visible;
|
|
MessagesView.Show;
|
|
ALayout:=EnvironmentOptions.IDEWindowLayoutList.
|
|
ItemByFormID(DefaultMessagesViewName);
|
|
ALayout.Apply;
|
|
if not WasVisible then
|
|
BringWindowToTop(SourceNotebook.Handle);
|
|
|
|
//set the event here for the selectionchanged event
|
|
if not assigned(MessagesView.OnSelectionChanged) then
|
|
MessagesView.OnSelectionChanged := @MessagesViewSelectionChanged;
|
|
end;
|
|
|
|
procedure TMainIDE.DoArrangeSourceEditorAndMessageView;
|
|
begin
|
|
DoShowMessagesView;
|
|
|
|
if (iwpDefault=EnvironmentOptions.IDEWindowLayoutList.ItemByFormID(
|
|
DefaultSourceNoteBookName).WindowPlacement)
|
|
and ((SourceNotebook.Top+SourceNotebook.Height) > MessagesView.Top) then
|
|
SourceNotebook.Height := Max(50,Min(SourceNotebook.Height,
|
|
MessagesView.Top-SourceNotebook.Top));
|
|
end;
|
|
|
|
function TMainIDE.GetProjectTargetFilename: string;
|
|
begin
|
|
Result:='';
|
|
if Project1=nil then exit;
|
|
Result:=Project1.RunParameterOptions.HostApplicationFilename;
|
|
if Result='' then begin
|
|
if Project1.IsVirtual then
|
|
Result:=GetTestProjectFilename
|
|
else begin
|
|
if Project1.MainUnit>=0 then begin
|
|
Result:=
|
|
Project1.CompilerOptions.CreateTargetFilename(Project1.MainFilename)
|
|
end;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
function TMainIDE.GetTestProjectFilename: string;
|
|
begin
|
|
Result:='';
|
|
if (Project1.MainUnit<0) then exit;
|
|
Result:=GetTestUnitFilename(Project1.MainUnitInfo);
|
|
if Result='' then exit;
|
|
Result:=Project1.CompilerOptions.CreateTargetFilename(Result);
|
|
end;
|
|
|
|
function TMainIDE.GetTestUnitFilename(AnUnitInfo: TUnitInfo): string;
|
|
var TestDir: string;
|
|
begin
|
|
Result:='';
|
|
if AnUnitInfo=nil then exit;
|
|
TestDir:=EnvironmentOptions.TestBuildDirectory;
|
|
if (TestDir='') then exit;
|
|
if TestDir[length(TestDir)]<>PathDelim then
|
|
TestDir:=TestDir+PathDelim;
|
|
Result:=ExtractFilename(AnUnitInfo.Filename);
|
|
if Result='' then exit;
|
|
Result:=TestDir+Result;
|
|
end;
|
|
|
|
function TMainIDE.GetRunCommandLine: string;
|
|
begin
|
|
if Project1.RunParameterOptions.UseLaunchingApplication
|
|
then Result := Project1.RunParameterOptions.LaunchingApplicationPathPlusParams
|
|
else Result := '';
|
|
|
|
if Result=''
|
|
then begin
|
|
Result:=Project1.RunParameterOptions.CmdLineParams;
|
|
if MacroList.SubstituteStr(Result) then begin
|
|
if Result='' then
|
|
Result:=GetProjectTargetFilename
|
|
else
|
|
Result:=GetProjectTargetFilename+' '+Result;
|
|
end else
|
|
Result:='';
|
|
end else begin
|
|
if not MacroList.SubstituteStr(Result) then Result:='';
|
|
end;
|
|
end;
|
|
|
|
function TMainIDE.FindUnitFile(const AFilename: string): string;
|
|
var
|
|
SearchPath, ProjectDir: string;
|
|
begin
|
|
ProjectDir:=Project1.ProjectDirectory;
|
|
SearchPath:=CodeToolBoss.DefineTree.GetSrcPathForDirectory(ProjectDir);
|
|
Result:=SearchFileInPath(AFilename,ProjectDir,SearchPath,';');
|
|
end;
|
|
|
|
//------------------------------------------------------------------------------
|
|
|
|
procedure TMainIDE.OnDesignerGetSelectedComponentClass(Sender: TObject;
|
|
var RegisteredComponent: TRegisteredComponent);
|
|
begin
|
|
RegisteredComponent:=SelectedComponent;
|
|
end;
|
|
|
|
procedure TMainIDE.OnDesignerUnselectComponentClass(Sender: TObject);
|
|
begin
|
|
ControlClick(ComponentNoteBook);
|
|
end;
|
|
|
|
procedure TMainIDE.OnDesignerSetDesigning(Sender: TObject;
|
|
Component: TComponent; Value: boolean);
|
|
begin
|
|
SetDesigning(Component,Value);
|
|
end;
|
|
|
|
procedure TMainIDE.OnDesignerComponentListChanged(Sender: TObject);
|
|
begin
|
|
ObjectInspector1.FillComponentComboBox;
|
|
end;
|
|
|
|
procedure TMainIDE.OnDesignerPropertiesChanged(Sender: TObject);
|
|
begin
|
|
ObjectInspector1.RefreshPropertyValues;
|
|
end;
|
|
|
|
procedure TMainIDE.OnDesignerAddComponent(Sender: TObject;
|
|
Component: TComponent; ComponentClass: TRegisteredComponent);
|
|
var i: integer;
|
|
ActiveForm: TCustomForm;
|
|
ActiveUnitInfo: TUnitInfo;
|
|
FormClassName: string;
|
|
begin
|
|
ActiveForm:=TDesigner(Sender).Form;
|
|
if ActiveForm=nil then begin
|
|
writeln('[TMainIDE.OnDesignerAddComponent] Error: TDesigner without a form');
|
|
halt;
|
|
end;
|
|
// find source for form
|
|
i:=Project1.UnitCount-1;
|
|
while (i>=0) do begin
|
|
if (Project1.Units[i].Loaded)
|
|
and (Project1.Units[i].Form=ActiveForm) then break;
|
|
dec(i);
|
|
end;
|
|
if i<0 then begin
|
|
writeln('[TMainIDE.OnDesignerAddComponent] Error: form without source');
|
|
halt;
|
|
end;
|
|
ActiveUnitInfo:=Project1.Units[i];
|
|
// add needed unit to source
|
|
CodeToolBoss.AddUnitToMainUsesSection(ActiveUnitInfo.Source,
|
|
ComponentClass.UnitName,'');
|
|
// add component definition to form source
|
|
FormClassName:=ActiveForm.ClassName;
|
|
if not CodeToolBoss.PublishedVariableExists(ActiveUnitInfo.Source,
|
|
FormClassName,Component.Name) then begin
|
|
// ! AddPublishedVariable does not rebuild the CodeTree, so we need
|
|
// PublishedVariableExists before !
|
|
CodeToolBoss.AddPublishedVariable(ActiveUnitInfo.Source,FormClassName,
|
|
Component.Name, Component.ClassName);
|
|
end;
|
|
end;
|
|
|
|
procedure TMainIDE.OnDesignerRemoveComponent(Sender: TObject;
|
|
Component: TComponent);
|
|
var i: integer;
|
|
ActiveForm: TCustomForm;
|
|
ActiveUnitInfo: TUnitInfo;
|
|
FormClassName: string;
|
|
begin
|
|
ActiveForm:=TDesigner(Sender).Form;
|
|
if ActiveForm=nil then begin
|
|
writeln('[TMainIDE.OnDesignerAddComponent] Error: TDesigner without a form');
|
|
halt;
|
|
end;
|
|
// find source for form
|
|
i:=Project1.UnitCount-1;
|
|
while (i>=0) do begin
|
|
if (Project1.Units[i].Loaded)
|
|
and (Project1.Units[i].Form=ActiveForm) then break;
|
|
dec(i);
|
|
end;
|
|
if i<0 then begin
|
|
writeln('[TMainIDE.OnDesignerAddComponent] Error: form without source');
|
|
halt;
|
|
end;
|
|
ActiveUnitInfo:=Project1.Units[i];
|
|
// remove component definition to form source
|
|
FormClassName:=ActiveForm.ClassName;
|
|
CodeToolBoss.RemovePublishedVariable(ActiveUnitInfo.Source,FormClassName,
|
|
Component.Name);
|
|
end;
|
|
|
|
procedure TMainIDE.OnDesignerModified(Sender: TObject);
|
|
var i: integer;
|
|
SrcEdit: TSourceEditor;
|
|
begin
|
|
i:=Project1.IndexOfUnitWithForm(TDesigner(Sender).Form,false);
|
|
if i>=0 then begin
|
|
Project1.Units[i].Modified:=true;
|
|
if Project1.Units[i].Loaded then
|
|
SrcEdit:=SourceNotebook.FindSourceEditorWithPageIndex(
|
|
Project1.Units[i].EditorIndex);
|
|
if SrcEdit<>nil then SrcEdit.EditorComponent.Modified:=true;
|
|
end;
|
|
end;
|
|
|
|
procedure TMainIDE.OnControlSelectionChanged(Sender: TObject);
|
|
var NewSelectedComponents : TComponentSelectionList;
|
|
i: integer;
|
|
begin
|
|
{$IFDEF IDE_DEBUG}
|
|
writeln('[TMainIDE.OnControlSelectionChanged]');
|
|
{$ENDIF}
|
|
if (TheControlSelection=nil) or (FormEditor1=nil) then exit;
|
|
NewSelectedComponents:=TComponentSelectionList.Create;
|
|
for i:=0 to TheControlSelection.Count-1 do begin
|
|
NewSelectedComponents.Add(TheControlSelection[i].Component);
|
|
end;
|
|
FormEditor1.SelectedComponents:=NewSelectedComponents;
|
|
NewSelectedComponents.Free;
|
|
{$IFDEF IDE_DEBUG}
|
|
writeln('[TMainIDE.OnControlSelectionChanged] END');
|
|
{$ENDIF}
|
|
end;
|
|
|
|
// -----------------------------------------------------------------------------
|
|
|
|
procedure TMainIDE.InitCodeToolBoss;
|
|
// initialize the CodeToolBoss, which is the frontend for the codetools.
|
|
// - sets a basic set of compiler macros
|
|
// ToDo: build a frontend for the codetools and save the settings
|
|
|
|
procedure AddTemplate(ADefTempl: TDefineTemplate; AddToPool: boolean;
|
|
const ErrorMsg: string);
|
|
begin
|
|
if ADefTempl=nil then begin
|
|
writeln('');
|
|
writeln(ErrorMsg);
|
|
end else begin;
|
|
CodeToolBoss.DefineTree.Add(ADefTempl);
|
|
if AddToPool then
|
|
CodeToolBoss.DefinePool.Add(ADefTempl.CreateCopy(false));
|
|
end;
|
|
end;
|
|
|
|
var CompilerUnitSearchPath, CompilerUnitLinks: string;
|
|
ADefTempl: TDefineTemplate;
|
|
c: integer;
|
|
AFilename: string;
|
|
UnitLinksChanged: boolean;
|
|
begin
|
|
FOpenEditorsOnCodeToolChange:=false;
|
|
|
|
CodeToolsOpts.AssignTo(CodeToolBoss);
|
|
if (not FileExists(EnvironmentOptions.CompilerFilename)) then begin
|
|
writeln('');
|
|
writeln('NOTE: Compiler Filename not set! (see Environment Options)');
|
|
end;
|
|
|
|
if (EnvironmentOptions.LazarusDirectory='') then begin
|
|
writeln('');
|
|
writeln(
|
|
'NOTE: Lazarus Source Directory not set! (see Environment Options)');
|
|
end;
|
|
if (EnvironmentOptions.FPCSourceDirectory='') then begin
|
|
writeln('');
|
|
writeln(
|
|
'NOTE: FPC Source Directory not set! (see Environment Options)');
|
|
end;
|
|
|
|
// set global variables
|
|
with CodeToolBoss.GlobalValues do begin
|
|
Variables[ExternalMacroStart+'LazarusDir']:=
|
|
EnvironmentOptions.LazarusDirectory;
|
|
Variables[ExternalMacroStart+'FPCSrcDir']:=
|
|
EnvironmentOptions.FPCSourceDirectory;
|
|
Variables[ExternalMacroStart+'LCLWidgetType']:='gtk';
|
|
Variables[ExternalMacroStart+'ProjectDir']:=VirtualDirectory;
|
|
end;
|
|
|
|
// build DefinePool and Define Tree
|
|
with CodeToolBoss.DefinePool do begin
|
|
// start the compiler and ask for his settings
|
|
ADefTempl:=CreateFPCTemplate(EnvironmentOptions.CompilerFilename,
|
|
CompilerUnitSearchPath);
|
|
AddTemplate(ADefTempl,false,
|
|
'NOTE: Could not create Define Template for Free Pascal Compiler');
|
|
|
|
// create compiler macros to simulate the Makefiles of the FPC sources
|
|
InputHistories.LastFPCPath:=EnvironmentOptions.CompilerFilename;
|
|
CompilerUnitLinks:=InputHistories.LastFPCUnitLinks;
|
|
UnitLinksChanged:=InputHistories.LastFPCUnitLinksNeedsUpdate(
|
|
CompilerUnitSearchPath);
|
|
ADefTempl:=CreateFPCSrcTemplate(
|
|
CodeToolBoss.GlobalValues.Variables[ExternalMacroStart+'FPCSrcDir'],
|
|
CompilerUnitSearchPath,
|
|
not UnitLinksChanged,
|
|
CompilerUnitLinks);
|
|
// save unitlinks
|
|
if UnitLinksChanged
|
|
or (InputHistories.LastFPCUnitLinks<>InputHistories.LastFPCUnitLinks)
|
|
then begin
|
|
InputHistories.SetLastFPCUnitLinks(EnvironmentOptions.CompilerFilename,
|
|
CompilerUnitSearchPath,CompilerUnitLinks);
|
|
InputHistories.Save;
|
|
end;
|
|
AddTemplate(ADefTempl,false,
|
|
'NOTE: Could not create Define Template for Free Pascal Sources');
|
|
|
|
// create compiler macros for the lazarus sources
|
|
ADefTempl:=CreateLazarusSrcTemplate(
|
|
'$('+ExternalMacroStart+'LazarusDir)',
|
|
'$('+ExternalMacroStart+'LCLWidgetType)');
|
|
AddTemplate(ADefTempl,true,
|
|
'NOTE: Could not create Define Template for Lazarus Sources');
|
|
end;
|
|
|
|
// load include file relationships
|
|
AFilename:=AppendPathDelim(GetPrimaryConfigPath)+CodeToolsIncludeLinkFile;
|
|
if FileExists(AFilename) then
|
|
CodeToolBoss.SourceCache.LoadIncludeLinksFromFile(AFilename);
|
|
|
|
|
|
with CodeToolBoss do begin
|
|
WriteExceptions:=true;
|
|
CatchExceptions:=true;
|
|
OnBeforeApplyChanges:=@OnBeforeCodeToolBossApplyChanges;
|
|
OnAfterApplyChanges:=@OnAfterCodeToolBossApplyChanges;
|
|
end;
|
|
|
|
// codetools consistency check
|
|
c:=CodeToolBoss.ConsistencyCheck;
|
|
if c<>0 then begin
|
|
writeln('CodeToolBoss.ConsistencyCheck=',c);
|
|
Halt;
|
|
end;
|
|
end;
|
|
|
|
procedure TMainIDE.OnBeforeCodeToolBossApplyChanges(Manager: TCodeToolManager;
|
|
var Abort: boolean);
|
|
// the CodeToolBoss built a list of Sources that will be modified
|
|
// 1. open all of them in the source notebook
|
|
// 2. lock the editors to reduce repaints and undo steps
|
|
var i: integer;
|
|
begin
|
|
if FOpenEditorsOnCodeToolChange then begin
|
|
// open all sources in editor
|
|
for i:=0 to Manager.SourceChangeCache.BuffersToModifyCount-1 do begin
|
|
if DoOpenEditorFile(Manager.SourceChangeCache.BuffersToModify[i].Filename,
|
|
-1,[ofOnlyIfExists])<>mrOk then
|
|
begin
|
|
Abort:=true;
|
|
exit;
|
|
end;
|
|
end;
|
|
end;
|
|
// lock all editors
|
|
SourceNoteBook.LockAllEditorsInSourceChangeCache;
|
|
end;
|
|
|
|
procedure TMainIDE.OnAfterCodeToolBossApplyChanges(Manager: TCodeToolManager);
|
|
begin
|
|
SourceNoteBook.UnlockAllEditorsInSourceChangeCache;
|
|
end;
|
|
|
|
procedure TMainIDE.SaveSourceEditorChangesToCodeCache(PageIndex: integer);
|
|
// save all open sources to code tools cache
|
|
var i: integer;
|
|
|
|
procedure SaveChanges(APageIndex: integer);
|
|
var
|
|
SrcEdit: TSourceEditor;
|
|
AnUnitInfo: TUnitInfo;
|
|
begin
|
|
GetUnitWithPageIndex(APageIndex,SrcEdit,AnUnitInfo);
|
|
if (SrcEdit<>nil) and (AnUnitInfo<>nil) and (SrcEdit.Modified) then begin
|
|
SrcEdit.UpdateCodeBuffer;
|
|
AnUnitInfo.Modified:=true;
|
|
end;
|
|
end;
|
|
|
|
begin
|
|
if PageIndex<0 then begin
|
|
if (SourceNotebook.NoteBook<>nil) then begin
|
|
for i:=0 to SourceNotebook.NoteBook.PageCount-1 do
|
|
SaveChanges(i);
|
|
end;
|
|
end else begin
|
|
SaveChanges(PageIndex);
|
|
end;
|
|
end;
|
|
|
|
function TMainIDE.BeginCodeTool(var ActiveSrcEdit: TSourceEditor;
|
|
var ActiveUnitInfo: TUnitInfo; SwitchToFormSrc: boolean): boolean;
|
|
begin
|
|
Result:=false;
|
|
if SourceNoteBook.NoteBook=nil then exit;
|
|
if SwitchToFormSrc then
|
|
DoSwitchToFormSrc(ActiveSrcEdit,ActiveUnitInfo)
|
|
else
|
|
GetCurrentUnit(ActiveSrcEdit,ActiveUnitInfo);
|
|
if (ActiveSrcEdit=nil) or (ActiveUnitInfo=nil) then exit;
|
|
SaveSourceEditorChangesToCodeCache(-1);
|
|
CodeToolBoss.VisibleEditorLines:=ActiveSrcEdit.EditorComponent.LinesInWindow;
|
|
Result:=true;
|
|
end;
|
|
|
|
function TMainIDE.DoJumpToCodePos(ActiveSrcEdit: TSourceEditor;
|
|
ActiveUnitInfo: TUnitInfo;
|
|
NewSource: TCodeBuffer; NewX, NewY, NewTopLine: integer;
|
|
AddJumpPoint: boolean): TModalResult;
|
|
var NewSrcEdit: TSourceEditor;
|
|
NewUnitInfo: TUnitInfo;
|
|
begin
|
|
Result:=mrCancel;
|
|
if AddJumpPoint then begin
|
|
if (NewSource<>ActiveUnitInfo.Source)
|
|
or (ActiveSrcEdit.EditorComponent.CaretX<>NewX)
|
|
or (ActiveSrcEdit.EditorComponent.CaretY<>NewY) then
|
|
SourceNotebook.AddJumpPointClicked(Self);
|
|
end;
|
|
if NewSource<>ActiveUnitInfo.Source then begin
|
|
// jump to other file -> open it
|
|
Result:=DoOpenEditorFile(NewSource.Filename,-1,[ofOnlyIfExists]);
|
|
if Result<>mrOk then exit;
|
|
GetUnitWithPageIndex(SourceNoteBook.NoteBook.PageIndex,NewSrcEdit,
|
|
NewUnitInfo);
|
|
end else begin
|
|
NewSrcEdit:=ActiveSrcEdit;
|
|
end;
|
|
//writeln('[TMainIDE.DoJumpToCodePos] ',NewX,',',NewY,',',NewTopLine);
|
|
with NewSrcEdit.EditorComponent do begin
|
|
CaretXY:=Point(NewX,NewY);
|
|
BlockBegin:=CaretXY;
|
|
BlockEnd:=CaretXY;
|
|
TopLine:=NewTopLine;
|
|
LeftChar:=Max(NewX-CharsInWindow,1);
|
|
SetFocus;
|
|
end;
|
|
BringWindowToTop(SourceNoteBook.Handle);
|
|
UpdateSourceNames;
|
|
Result:=mrOk;
|
|
end;
|
|
|
|
{-------------------------------------------------------------------------------
|
|
procedure TMainIDE.UpdateSourceNames
|
|
Params: none
|
|
|
|
Check every unit in sourceeditor if the source name has changed and updates
|
|
the notebook page names.
|
|
-------------------------------------------------------------------------------}
|
|
procedure TMainIDE.UpdateSourceNames;
|
|
var
|
|
PageIndex: integer;
|
|
AnUnitInfo: TUnitInfo;
|
|
SourceName, PageName: string;
|
|
begin
|
|
if SourceNotebook.NoteBook=nil then exit;
|
|
for PageIndex:=0 to SourceNotebook.NoteBook.PageCount-1 do begin
|
|
AnUnitInfo:=Project1.UnitWithEditorIndex(PageIndex);
|
|
if AnUnitInfo=nil then continue;
|
|
if FilenameIsPascalUnit(AnUnitInfo.Filename) then
|
|
SourceName:=CodeToolBoss.GetCachedSourceName(AnUnitInfo.Source)
|
|
else
|
|
SourceName:='';
|
|
PageName:=CreateSrcEditPageName(SourceName,AnUnitInfo.Filename,PageIndex);
|
|
SourceNotebook.NoteBook.Pages[PageIndex]:=PageName;
|
|
end;
|
|
end;
|
|
|
|
procedure TMainIDE.ApplyCodeToolChanges;
|
|
begin
|
|
// all changes were handled automatically by events
|
|
// just clear the logs
|
|
CodeToolBoss.SourceCache.ClearAllSourleLogEntries;
|
|
end;
|
|
|
|
procedure TMainIDE.DoJumpToProcedureSection;
|
|
var ActiveSrcEdit: TSourceEditor;
|
|
ActiveUnitInfo: TUnitInfo;
|
|
NewSource: TCodeBuffer;
|
|
NewX, NewY, NewTopLine: integer;
|
|
begin
|
|
if not BeginCodeTool(ActiveSrcEdit,ActiveUnitInfo,false) then exit;
|
|
{$IFDEF IDE_DEBUG}
|
|
writeln('');
|
|
writeln('[TMainIDE.DoJumpToProcedureSection] ************');
|
|
{$ENDIF}
|
|
if CodeToolBoss.JumpToMethod(ActiveUnitInfo.Source,
|
|
ActiveSrcEdit.EditorComponent.CaretX,
|
|
ActiveSrcEdit.EditorComponent.CaretY,
|
|
NewSource,NewX,NewY,NewTopLine) then
|
|
begin
|
|
DoJumpToCodePos(ActiveSrcEdit, ActiveUnitInfo,
|
|
NewSource, NewX, NewY, NewTopLine, false);
|
|
end else
|
|
DoJumpToCodeToolBossError;
|
|
end;
|
|
|
|
procedure TMainIDE.DoJumpToCodeToolBossError;
|
|
var
|
|
ActiveSrcEdit:TSourceEditor;
|
|
ErrorCaret: TPoint;
|
|
begin
|
|
if CodeToolBoss.ErrorMessage='' then begin
|
|
UpdateSourceNames;
|
|
exit;
|
|
end;
|
|
// syntax error -> show error and jump
|
|
// show error in message view
|
|
DoArrangeSourceEditorAndMessageView;
|
|
MessagesView.ClearTillLastSeparator;
|
|
MessagesView.AddSeparator;
|
|
if CodeToolBoss.ErrorCode<>nil then begin
|
|
MessagesView.Add(Project1.RemoveProjectPathFromFilename(
|
|
CodeToolBoss.ErrorCode.Filename)
|
|
+'('+IntToStr(CodeToolBoss.ErrorLine)
|
|
+','+IntToStr(CodeToolBoss.ErrorColumn)
|
|
+') Error: '+CodeToolBoss.ErrorMessage);
|
|
end else
|
|
MessagesView.Add(CodeToolBoss.ErrorMessage);
|
|
|
|
// jump to error in source editor
|
|
if CodeToolBoss.ErrorCode<>nil then begin
|
|
SourceNotebook.AddJumpPointClicked(Self);
|
|
ErrorCaret:=Point(CodeToolBoss.ErrorColumn,CodeToolBoss.ErrorLine);
|
|
if DoOpenEditorFile(CodeToolBoss.ErrorCode.Filename,-1,[ofOnlyIfExists])=mrOk
|
|
then begin
|
|
ActiveSrcEdit:=SourceNoteBook.GetActiveSE;
|
|
with ActiveSrcEdit.EditorComponent do begin
|
|
SetFocus;
|
|
CaretXY:=ErrorCaret;
|
|
BlockBegin:=CaretXY;
|
|
BlockEnd:=CaretXY;
|
|
if CodeToolBoss.ErrorTopLine>0 then
|
|
TopLine:=CodeToolBoss.ErrorTopLine;
|
|
end;
|
|
SourceNotebook.ClearErrorLines;
|
|
ActiveSrcEdit.ErrorLine:=ErrorCaret.Y;
|
|
BringWindowToTop(SourceNoteBook.Handle);
|
|
end;
|
|
end;
|
|
UpdateSourceNames;
|
|
end;
|
|
|
|
procedure TMainIDE.DoFindDeclarationAtCursor;
|
|
var ActiveSrcEdit: TSourceEditor;
|
|
ActiveUnitInfo: TUnitInfo;
|
|
NewSource: TCodeBuffer;
|
|
NewX, NewY, NewTopLine: integer;
|
|
begin
|
|
if not BeginCodeTool(ActiveSrcEdit,ActiveUnitInfo,false) then exit;
|
|
{$IFDEF IDE_DEBUG}
|
|
writeln('');
|
|
writeln('[TMainIDE.DoFindDeclarationAtCursor] ************');
|
|
{$ENDIF}
|
|
{$IFDEF IDE_MEM_CHECK}CheckHeap('TMainIDE.DoFindDeclarationAtCursor ',IntToStr(GetMem_Cnt));{$ENDIF}
|
|
if CodeToolBoss.FindDeclaration(ActiveUnitInfo.Source,
|
|
ActiveSrcEdit.EditorComponent.CaretX,
|
|
ActiveSrcEdit.EditorComponent.CaretY,
|
|
NewSource,NewX,NewY,NewTopLine) then
|
|
begin
|
|
DoJumpToCodePos(ActiveSrcEdit, ActiveUnitInfo,
|
|
NewSource, NewX, NewY, NewTopLine, true);
|
|
end else
|
|
DoJumpToCodeToolBossError;
|
|
{$IFDEF IDE_MEM_CHECK}CheckHeap('TMainIDE.DoFindDeclarationAtCursor ',IntToStr(GetMem_Cnt));{$ENDIF}
|
|
end;
|
|
|
|
procedure TMainIDE.DoGoToPascalBlockOtherEnd;
|
|
var ActiveSrcEdit: TSourceEditor;
|
|
ActiveUnitInfo: TUnitInfo;
|
|
NewSource: TCodeBuffer;
|
|
NewX, NewY, NewTopLine: integer;
|
|
begin
|
|
if not BeginCodeTool(ActiveSrcEdit,ActiveUnitInfo,false) then exit;
|
|
{$IFDEF IDE_DEBUG}
|
|
writeln('');
|
|
writeln('[TMainIDE.DoGoToPascalBlockOtherEnd] ************');
|
|
{$ENDIF}
|
|
if CodeToolBoss.FindBlockCounterPart(ActiveUnitInfo.Source,
|
|
ActiveSrcEdit.EditorComponent.CaretX,
|
|
ActiveSrcEdit.EditorComponent.CaretY,
|
|
NewSource,NewX,NewY,NewTopLine) then
|
|
begin
|
|
DoJumpToCodePos(ActiveSrcEdit, ActiveUnitInfo,
|
|
NewSource, NewX, NewY, NewTopLine, false);
|
|
end else
|
|
DoJumpToCodeToolBossError;
|
|
end;
|
|
|
|
procedure TMainIDE.DoGoToPascalBlockStart;
|
|
var ActiveSrcEdit: TSourceEditor;
|
|
ActiveUnitInfo: TUnitInfo;
|
|
NewSource: TCodeBuffer;
|
|
NewX, NewY, NewTopLine: integer;
|
|
begin
|
|
if not BeginCodeTool(ActiveSrcEdit,ActiveUnitInfo,false) then exit;
|
|
{$IFDEF IDE_DEBUG}
|
|
writeln('');
|
|
writeln('[TMainIDE.DoGoToPascalBlockStart] ************');
|
|
{$ENDIF}
|
|
if CodeToolBoss.FindBlockStart(ActiveUnitInfo.Source,
|
|
ActiveSrcEdit.EditorComponent.CaretX,
|
|
ActiveSrcEdit.EditorComponent.CaretY,
|
|
NewSource,NewX,NewY,NewTopLine) then
|
|
begin
|
|
DoJumpToCodePos(ActiveSrcEdit, ActiveUnitInfo,
|
|
NewSource, NewX, NewY, NewTopLine, false);
|
|
end else
|
|
DoJumpToCodeToolBossError;
|
|
end;
|
|
|
|
procedure TMainIDE.DoJumpToGuessedUnclosedBlock(FindNext: boolean);
|
|
var ActiveSrcEdit: TSourceEditor;
|
|
ActiveUnitInfo: TUnitInfo;
|
|
NewSource: TCodeBuffer;
|
|
StartX, StartY, NewX, NewY, NewTopLine: integer;
|
|
begin
|
|
if not BeginCodeTool(ActiveSrcEdit,ActiveUnitInfo,false) then exit;
|
|
{$IFDEF IDE_DEBUG}
|
|
writeln('');
|
|
writeln('[TMainIDE.DoJumpToGuessedUnclosedBlock] ************');
|
|
{$ENDIF}
|
|
if FindNext then begin
|
|
StartX:=ActiveSrcEdit.EditorComponent.CaretX;
|
|
StartY:=ActiveSrcEdit.EditorComponent.CaretY;
|
|
end else begin
|
|
StartX:=1;
|
|
StartY:=1;
|
|
end;
|
|
if CodeToolBoss.GuessUnclosedBlock(ActiveUnitInfo.Source,
|
|
StartX,StartY,NewSource,NewX,NewY,NewTopLine) then
|
|
begin
|
|
DoJumpToCodePos(ActiveSrcEdit, ActiveUnitInfo,
|
|
NewSource, NewX, NewY, NewTopLine, true);
|
|
end else
|
|
DoJumpToCodeToolBossError;
|
|
end;
|
|
|
|
procedure TMainIDE.DoJumpToGuessedMisplacedIFDEF(FindNext: boolean);
|
|
var ActiveSrcEdit: TSourceEditor;
|
|
ActiveUnitInfo: TUnitInfo;
|
|
NewSource: TCodeBuffer;
|
|
StartX, StartY, NewX, NewY, NewTopLine: integer;
|
|
begin
|
|
if not BeginCodeTool(ActiveSrcEdit,ActiveUnitInfo,false) then exit;
|
|
{$IFDEF IDE_DEBUG}
|
|
writeln('');
|
|
writeln('[TMainIDE.DoJumpToGuessedMisplacedIFDEF] ************');
|
|
{$ENDIF}
|
|
if FindNext then begin
|
|
StartX:=ActiveSrcEdit.EditorComponent.CaretX;
|
|
StartY:=ActiveSrcEdit.EditorComponent.CaretY;
|
|
end else begin
|
|
StartX:=1;
|
|
StartY:=1;
|
|
end;
|
|
if CodeToolBoss.GuessMisplacedIfdefEndif(ActiveUnitInfo.Source,
|
|
StartX,StartY,NewSource,NewX,NewY,NewTopLine) then
|
|
begin
|
|
DoJumpToCodePos(ActiveSrcEdit, ActiveUnitInfo,
|
|
NewSource, NewX, NewY, NewTopLine, true);
|
|
end else
|
|
DoJumpToCodeToolBossError;
|
|
end;
|
|
|
|
procedure TMainIDE.DoGotoIncludeDirective;
|
|
var ActiveSrcEdit: TSourceEditor;
|
|
ActiveUnitInfo: TUnitInfo;
|
|
NewSource: TCodeBuffer;
|
|
NewX, NewY, NewTopLine: integer;
|
|
begin
|
|
if not BeginCodeTool(ActiveSrcEdit,ActiveUnitInfo,false) then exit;
|
|
{ $IFDEF IDE_DEBUG}
|
|
writeln('');
|
|
writeln('[TMainIDE.DoGotoIncludeDirective] ************');
|
|
{ $ENDIF}
|
|
if CodeToolBoss.FindEnclosingIncludeDirective(ActiveUnitInfo.Source,
|
|
ActiveSrcEdit.EditorComponent.CaretX,
|
|
ActiveSrcEdit.EditorComponent.CaretY,
|
|
NewSource,NewX,NewY,NewTopLine) then
|
|
begin
|
|
DoJumpToCodePos(ActiveSrcEdit, ActiveUnitInfo,
|
|
NewSource, NewX, NewY, NewTopLine, false);
|
|
end else
|
|
DoJumpToCodeToolBossError;
|
|
end;
|
|
|
|
procedure TMainIDE.SaveIncludeLinks;
|
|
var AFilename: string;
|
|
begin
|
|
// save include file relationships
|
|
AFilename:=AppendPathDelim(GetPrimaryConfigPath)+CodeToolsIncludeLinkFile;
|
|
CodeToolBoss.SourceCache.SaveIncludeLinksToFile(AFilename);
|
|
end;
|
|
|
|
procedure TMainIDE.DoCompleteCodeAtCursor;
|
|
var ActiveSrcEdit: TSourceEditor;
|
|
ActiveUnitInfo: TUnitInfo;
|
|
NewSource: TCodeBuffer;
|
|
NewX, NewY, NewTopLine: integer;
|
|
begin
|
|
FOpenEditorsOnCodeToolChange:=true;
|
|
try
|
|
if not BeginCodeTool(ActiveSrcEdit,ActiveUnitInfo,false) then exit;
|
|
{$IFDEF IDE_DEBUG}
|
|
writeln('');
|
|
writeln('[TMainIDE.DoCompleteCodeAtCursor] ************');
|
|
{$ENDIF}
|
|
if CodeToolBoss.CompleteCode(ActiveUnitInfo.Source,
|
|
ActiveSrcEdit.EditorComponent.CaretX,
|
|
ActiveSrcEdit.EditorComponent.CaretY,
|
|
NewSource,NewX,NewY,NewTopLine) then
|
|
begin
|
|
ApplyCodeToolChanges;
|
|
DoJumpToCodePos(ActiveSrcEdit, ActiveUnitInfo,
|
|
NewSource, NewX, NewY, NewTopLine, true);
|
|
end else begin
|
|
// error: probably a syntax error or just not in a procedure head/body
|
|
// or not in a class
|
|
// -> there are enough events to handle everything, so it can be ignored here
|
|
ApplyCodeToolChanges;
|
|
DoJumpToCodeToolBossError;
|
|
end;
|
|
finally
|
|
FOpenEditorsOnCodeToolChange:=false;
|
|
end;
|
|
end;
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
procedure TMainIDE.MessagesViewSelectionChanged(sender : TObject);
|
|
begin
|
|
DoJumpToCompilerMessage(TMessagesView(sender).SelectedMessageIndex,True);
|
|
end;
|
|
|
|
Procedure TMainIDE.OnSrcNotebookEditorVisibleChanged(Sender : TObject);
|
|
var
|
|
ActiveUnitInfo : TUnitInfo;
|
|
begin
|
|
if SourceNotebook.Notebook = nil then Exit;
|
|
|
|
ActiveUnitInfo :=
|
|
Project1.UnitWithEditorIndex(SourceNotebook.Notebook.Pageindex);
|
|
if ActiveUnitInfo = nil then Exit;
|
|
|
|
SaveSpeedBtn.Enabled := SourceNotebook.GetActiveSe.MOdified;
|
|
ToggleFormSpeedBtn.Enabled := Assigned(ActiveUnitInfo.Form);
|
|
end;
|
|
|
|
Procedure TMainIDE.OnSrcNoteBookActivated(Sender : TObject);
|
|
begin
|
|
FCodeLastActivated:=True;
|
|
DoCheckFilesOnDisk;
|
|
end;
|
|
|
|
Procedure TMainIDE.OnDesignerActivated(Sender : TObject);
|
|
begin
|
|
FCodeLastActivated:=False;
|
|
FLastFormActivated := TCustomForm(Sender);
|
|
end;
|
|
|
|
procedure TMainIDE.OnDesignerRenameComponent(ADesigner: TDesigner;
|
|
AComponent: TComponent; const NewName: string);
|
|
var
|
|
ActiveSrcEdit: TSourceEditor;
|
|
ActiveUnitInfo: TUnitInfo;
|
|
begin
|
|
BeginCodeTool(ActiveSrcEdit,ActiveUnitInfo,false);
|
|
if AComponent.Owner<>nil then begin
|
|
// rename published variable in form source
|
|
ActiveUnitInfo:=Project1.UnitWithForm(ADesigner.Form);
|
|
if CodeToolBoss.RenamePublishedVariable(ActiveUnitInfo.Source,
|
|
ADesigner.Form.ClassName,
|
|
AComponent.Name,NewName,AComponent.ClassName) then
|
|
begin
|
|
ApplyCodeToolChanges;
|
|
end else begin
|
|
ApplyCodeToolChanges;
|
|
DoJumpToCodeToolBossError;
|
|
raise Exception.Create('Unable to rename variable in source.'#13
|
|
+'See messages.');
|
|
end;
|
|
end else if AComponent=ADesigner.Form then begin
|
|
// ToDo:
|
|
// rename form in source
|
|
// rename form variable
|
|
// replace createform statement
|
|
// delete old form resource in resource file
|
|
MessageDlg('Not implemented yet.',
|
|
'Form renaming in source is not implemented yet.',
|
|
mtInformation,[mbOk],0);
|
|
end else begin
|
|
if (aComponent is TMenuItem) or (aComponent is TMenu)
|
|
then writeln ('**SH: Warn: TMainIDE.OnDesignerRenameComponent MenuItem / TMenu with Owner = nil'+self.Name)
|
|
else raise Exception.Create('TMainIDE.OnDesignerRenameComponent internal error:'+AComponent.Name);
|
|
end;
|
|
end;
|
|
|
|
Procedure TMainIDE.OnSrcNoteBookAddJumpPoint(ACaretXY: TPoint;
|
|
ATopLine: integer; APageIndex: integer; DeleteForwardHistory: boolean);
|
|
var
|
|
ActiveUnitInfo: TUnitInfo;
|
|
NewJumpPoint: TProjectJumpHistoryPosition;
|
|
begin
|
|
//writeln('[TMainIDE.OnSrcNoteBookAddJumpPoint] A Line=',ACaretXY.Y,',DeleteForwardHistory=',DeleteForwardHistory,' Count=',Project1.JumpHistory.Count,',HistoryIndex=',Project1.JumpHistory.HistoryIndex);
|
|
ActiveUnitInfo:=Project1.UnitWithEditorIndex(APageIndex);
|
|
if (ActiveUnitInfo=nil) then exit;
|
|
NewJumpPoint:=TProjectJumpHistoryPosition.Create(ActiveUnitInfo.Filename,
|
|
ACaretXY,ATopLine);
|
|
if DeleteForwardHistory then Project1.JumpHistory.DeleteForwardHistory;
|
|
Project1.JumpHistory.InsertSmart(Project1.JumpHistory.HistoryIndex+1,
|
|
NewJumpPoint);
|
|
if Project1.JumpHistory.HistoryIndex=Project1.JumpHistory.Count-2 then
|
|
Project1.JumpHistory.HistoryIndex:=Project1.JumpHistory.Count-1;
|
|
//writeln('[TMainIDE.OnSrcNoteBookAddJumpPoint] END Line=',ACaretXY.Y,',DeleteForwardHistory=',DeleteForwardHistory,' Count=',Project1.JumpHistory.Count,',HistoryIndex=',Project1.JumpHistory.HistoryIndex);
|
|
//Project1.JumpHistory.WriteDebugReport;
|
|
end;
|
|
|
|
Procedure TMainIDE.OnSrcNotebookDeleteLastJumPoint(Sender: TObject);
|
|
begin
|
|
Project1.JumpHistory.DeleteLast;
|
|
end;
|
|
|
|
Procedure TMainIDE.OnSrcNotebookJumpToHistoryPoint(var NewCaretXY: TPoint;
|
|
var NewTopLine, NewPageIndex: integer; Action: TJumpHistoryAction);
|
|
var DestIndex, UnitIndex, NewHistoryIndex: integer;
|
|
ActiveSrcEdit: TSourceEditor;
|
|
DestJumpPoint: TProjectJumpHistoryPosition;
|
|
begin
|
|
//writeln('[TMainIDE.OnSrcNotebookJumpToHistoryPoint] A Back=',Action=jhaBack);
|
|
{ jumping back/forward is also a jump, that's why the current source position
|
|
should be saved to the jump history before the jump.
|
|
The InsertSmart method prevents putting positions twice in the history. }
|
|
|
|
// update jump history (e.g. delete jumps to closed editors)
|
|
Project1.JumpHistory.DeleteInvalidPositions;
|
|
|
|
//writeln('[TMainIDE.OnSrcNotebookJumpToHistoryPoint] B Count=',Project1.JumpHistory.Count,',HistoryIndex=',Project1.JumpHistory.HistoryIndex);
|
|
DestIndex:=Project1.JumpHistory.HistoryIndex;
|
|
if Action=jhaForward then begin
|
|
inc(DestIndex,2);
|
|
if DestIndex=Project1.JumpHistory.Count then
|
|
Dec(DestIndex);
|
|
end;
|
|
if (DestIndex<0) or (DestIndex>=Project1.JumpHistory.Count) then exit;
|
|
DestJumpPoint:=Project1.JumpHistory[DestIndex];
|
|
//writeln('[TMainIDE.OnSrcNotebookJumpToHistoryPoint] C Line=',DestJumpPoint.CaretXY.Y);
|
|
NewHistoryIndex:=Project1.JumpHistory.HistoryIndex;
|
|
if Action=jhaBack then begin
|
|
dec(NewHistoryIndex);
|
|
if Project1.JumpHistory.HistoryIndex=Project1.JumpHistory.Count-1 then begin
|
|
// insert current source position into history
|
|
if SourceNoteBook.NoteBook=nil then exit;
|
|
ActiveSrcEdit:=SourceNotebook.GetActiveSE;
|
|
if (ActiveSrcEdit=nil) then exit;
|
|
OnSrcNoteBookAddJumpPoint(ActiveSrcEdit.EditorComponent.CaretXY,
|
|
ActiveSrcEdit.EditorComponent.TopLine,SourceNotebook.Notebook.PageIndex,
|
|
false);
|
|
end;
|
|
end else
|
|
inc(NewHistoryIndex);
|
|
Project1.JumpHistory.HistoryIndex:=NewHistoryIndex;
|
|
|
|
UnitIndex:=Project1.IndexOfFilename(DestJumpPoint.Filename);
|
|
if (UnitIndex>=0) and (Project1.Units[UnitIndex].EditorIndex>=0) then begin
|
|
with Project1.JumpHistory do begin
|
|
NewCaretXY:=DestJumpPoint.CaretXY;
|
|
NewTopLine:=DestJumpPoint.TopLine;
|
|
end;
|
|
NewPageIndex:=Project1.Units[UnitIndex].EditorIndex;
|
|
end;
|
|
//writeln('[TMainIDE.OnSrcNotebookJumpToHistoryPoint] END Count=',Project1.JumpHistory.Count,',HistoryIndex=',Project1.JumpHistory.HistoryIndex);
|
|
//Project1.JumpHistory.WriteDebugReport;
|
|
end;
|
|
|
|
Procedure TMainIDE.OnSrcNotebookViewJumpHistory(Sender : TObject);
|
|
begin
|
|
// ToDo
|
|
MessageDlg('Not implemented yet','Sorry, not implemented yet',mtInformation,
|
|
[mbOk],0);
|
|
end;
|
|
|
|
Procedure TMainIDE.HintTimer1Timer(Sender : TObject);
|
|
var
|
|
Rect : TRect;
|
|
AHint : String;
|
|
cPosition : TPoint;
|
|
// TextPosition : TPoint;
|
|
// SE : TSourceEditor;
|
|
Window : TWinControl;
|
|
// Caret : TPoint;
|
|
Control : TControl;
|
|
// Control2 : TControl;
|
|
// tempPosition : TPoint;
|
|
begin
|
|
HintTimer1.Enabled := False;
|
|
|
|
cPosition := Mouse.CursorPos;
|
|
Window := FindLCLWindow(cPosition);
|
|
if not(Assigned(Window)) then Exit;
|
|
|
|
//get the parent until parent is nil
|
|
While Window.Parent <> nil do
|
|
Window := Window.Parent;
|
|
|
|
if (Window <> Self) then Exit;
|
|
|
|
Control := nil;
|
|
|
|
if (FHintSender is TSpeedButton) then begin
|
|
Control := TControl(FHintSender);
|
|
while (Control<>nil) do begin
|
|
if (Control=Self) then begin
|
|
// main speed button
|
|
if not EnvironmentOptions.ShowHintsForMainSpeedButtons then exit;
|
|
end else if (Control=ComponentNotebook) then begin
|
|
// component palette
|
|
if not EnvironmentOptions.ShowHintsForComponentPalette then exit;
|
|
end;
|
|
Control:=Control.Parent;
|
|
end;
|
|
end;
|
|
|
|
AHint := '';
|
|
|
|
if (Control <> nil) and (Control is TSpeedButton) then
|
|
AHint := TSpeedButton(Control).Hint;
|
|
|
|
|
|
//If no hint, then Exit
|
|
if AHint = '' then Exit;
|
|
|
|
Rect := HintWindow1.CalcHintRect(0,AHint,nil); //no maxwidth
|
|
Rect.Left := cPosition.X+10;
|
|
Rect.Top := cPosition.Y+10;
|
|
Rect.Top := Rect.Top + 25;
|
|
Rect.Right := Rect.Left + Rect.Right+3;
|
|
Rect.Bottom := Rect.Top + Rect.Bottom+3;
|
|
|
|
HintWindow1.ActivateHint(Rect,AHint);
|
|
|
|
end;
|
|
|
|
Procedure TMainIDE.MainKeyDown(Sender: TObject; var Key: Word; Shift:
|
|
TShiftState);
|
|
begin
|
|
HintTimer1.Enabled := False;
|
|
if HintWIndow1.Visible then
|
|
HintWindow1.Visible := False;
|
|
end;
|
|
|
|
Procedure TMainIDE.MainMouseDown(Sender: TObject; Button: TMouseButton; Shift:
|
|
TShiftState; X, Y: Integer);
|
|
begin
|
|
HintTimer1.Enabled := False;
|
|
if HintWIndow1.Visible then
|
|
HintWindow1.Visible := False;
|
|
end;
|
|
|
|
Procedure TMainIDE.MainMouseMoved(Sender: TObject; Shift: TShiftState; X, Y:
|
|
Integer);
|
|
var Control: TControl;
|
|
begin
|
|
if HintWindow1.Visible then
|
|
HintWindow1.Visible := False;
|
|
HintTimer1.Enabled := False;
|
|
FHintSender := Sender;
|
|
if (FHintSender is TSpeedButton) then begin
|
|
Control := TControl(FHintSender);
|
|
while (Control<>nil) do begin
|
|
if (Control=Self) then begin
|
|
// main speed button
|
|
if not EnvironmentOptions.ShowHintsForMainSpeedButtons then exit;
|
|
end else if (Control=ComponentNotebook) then begin
|
|
// component palette
|
|
if not EnvironmentOptions.ShowHintsForComponentPalette then exit;
|
|
end;
|
|
Control:=Control.Parent;
|
|
Application.ProcessMessages;
|
|
end;
|
|
HintTimer1.Enabled := ([ssLeft,ssRight,ssMiddle]*Shift=[]);
|
|
end;
|
|
end;
|
|
|
|
//this is fired when the editor is focused, changed, ?. Anything that causes the status change
|
|
Procedure TMainIDE.OnSrcNotebookEditorChanged(Sender : TObject);
|
|
begin
|
|
if SourceNotebook.Notebook = nil then Exit;
|
|
|
|
SaveSpeedBtn.Enabled := SourceNotebook.GetActiveSE.Modified;
|
|
end;
|
|
|
|
procedure TMainIDE.OnExtToolNeedsOutputFilter(var OutputFilter: TOutputFilter;
|
|
var Abort: boolean);
|
|
var ActiveSrcEdit: TSourceEditor;
|
|
begin
|
|
OutputFilter:=TheOutputFilter;
|
|
OutputFilter.Project:=Project1;
|
|
if ToolStatus<>itNone then begin
|
|
Abort:=true;
|
|
exit;
|
|
end;
|
|
ActiveSrcEdit:=SourceNotebook.GetActiveSE;
|
|
if ActiveSrcEdit<>nil then ActiveSrcEdit.ErrorLine:=-1;
|
|
|
|
ToolStatus:=itBuilder;
|
|
MessagesView.Clear;
|
|
DoArrangeSourceEditorAndMessageView;
|
|
|
|
TheOutputFilter.OnOutputString:=@MessagesView.Add;
|
|
end;
|
|
|
|
procedure TMainIDE.OnExtToolFreeOutputFilter(OutputFilter: TOutputFilter;
|
|
ErrorOccurred: boolean);
|
|
begin
|
|
if ToolStatus=itBuilder then
|
|
ToolStatus:=itNone;
|
|
if ErrorOccurred then
|
|
DoJumpToCompilerMessage(-1,true);
|
|
end;
|
|
|
|
procedure TMainIDE.DoSwitchToFormSrc(var ActiveSourceEditor: TSourceEditor;
|
|
var ActiveUnitInfo: TUnitInfo);
|
|
var i: integer;
|
|
begin
|
|
if PropertyEditorHook1.LookupRoot<>nil then begin
|
|
i:=Project1.IndexOfUnitWithForm(PropertyEditorHook1.LookupRoot,false);
|
|
if (i>=0) then begin
|
|
i:=Project1.Units[i].EditorIndex;
|
|
if (i>=0) then begin
|
|
SourceNoteBook.NoteBook.PageIndex:=i;
|
|
GetCurrentUnit(ActiveSourceEditor,ActiveUnitInfo);
|
|
exit;
|
|
end;
|
|
end;
|
|
end;
|
|
ActiveSourceEditor:=nil;
|
|
ActiveUnitInfo:=nil;
|
|
end;
|
|
|
|
function TMainIDE.OnPropHookMethodExists(const AMethodName: ShortString;
|
|
TypeData: PTypeData;
|
|
var MethodIsCompatible,MethodIsPublished,IdentIsMethod: boolean): boolean;
|
|
var ActiveSrcEdit: TSourceEditor;
|
|
ActiveUnitInfo: TUnitInfo;
|
|
begin
|
|
if not BeginCodeTool(ActiveSrcEdit,ActiveUnitInfo,true) then exit;
|
|
{$IFDEF IDE_DEBUG}
|
|
writeln('');
|
|
writeln('[TMainIDE.OnPropHookMethodExists] ************ ',AMethodName);
|
|
{$ENDIF}
|
|
Result:=CodeToolBoss.PublishedMethodExists(ActiveUnitInfo.Source,
|
|
ActiveUnitInfo.Form.ClassName,AMethodName,TypeData,
|
|
MethodIsCompatible,MethodIsPublished,IdentIsMethod);
|
|
if CodeToolBoss.ErrorMessage<>'' then begin
|
|
DoJumpToCodeToolBossError;
|
|
end;
|
|
end;
|
|
|
|
function TMainIDE.OnPropHookCreateMethod(const AMethodName: ShortString;
|
|
ATypeInfo: PTypeInfo): TMethod;
|
|
var ActiveSrcEdit: TSourceEditor;
|
|
ActiveUnitInfo: TUnitInfo;
|
|
r: boolean;
|
|
begin
|
|
Result.Code:=nil;
|
|
Result.Data:=nil;
|
|
if not BeginCodeTool(ActiveSrcEdit,ActiveUnitInfo,true) then exit;
|
|
{$IFDEF IDE_DEBUG}
|
|
writeln('');
|
|
writeln('[TMainIDE.OnPropHookCreateMethod] ************ ',AMethodName);
|
|
{$ENDIF}
|
|
FOpenEditorsOnCodeToolChange:=true;
|
|
try
|
|
// create published method
|
|
r:=CodeToolBoss.CreatePublishedMethod(ActiveUnitInfo.Source,
|
|
ActiveUnitInfo.Form.ClassName,AMethodName,ATypeInfo);
|
|
{$IFDEF IDE_DEBUG}
|
|
writeln('');
|
|
writeln('[TMainIDE.OnPropHookCreateMethod] ************2 ',r,' ',AMethodName);
|
|
{$ENDIF}
|
|
ApplyCodeToolChanges;
|
|
if r then begin
|
|
Result:=FormEditor1.JITFormList.CreateNewMethod(TForm(ActiveUnitInfo.Form)
|
|
,AMethodName);
|
|
end else begin
|
|
DoJumpToCodeToolBossError;
|
|
end;
|
|
finally
|
|
FOpenEditorsOnCodeToolChange:=false;
|
|
end;
|
|
end;
|
|
|
|
procedure TMainIDE.OnPropHookShowMethod(const AMethodName: ShortString);
|
|
var ActiveSrcEdit: TSourceEditor;
|
|
ActiveUnitInfo: TUnitInfo;
|
|
NewSource: TCodeBuffer;
|
|
NewX, NewY, NewTopLine: integer;
|
|
begin
|
|
if not BeginCodeTool(ActiveSrcEdit,ActiveUnitInfo,true) then exit;
|
|
{$IFDEF IDE_DEBUG}
|
|
writeln('');
|
|
writeln('[TMainIDE.OnPropHookShowMethod] ************');
|
|
{$ENDIF}
|
|
if CodeToolBoss.JumpToPublishedMethodBody(ActiveUnitInfo.Source,
|
|
ActiveUnitInfo.Form.ClassName,AMethodName,
|
|
NewSource,NewX,NewY,NewTopLine) then
|
|
begin
|
|
DoJumpToCodePos(ActiveSrcEdit, ActiveUnitInfo,
|
|
NewSource, NewX, NewY, NewTopLine, true);
|
|
end else
|
|
DoJumpToCodeToolBossError;
|
|
end;
|
|
|
|
procedure TMainIDE.OnPropHookRenameMethod(const CurName, NewName: ShortString);
|
|
var ActiveSrcEdit: TSourceEditor;
|
|
ActiveUnitInfo: TUnitInfo;
|
|
r: boolean;
|
|
begin
|
|
if not BeginCodeTool(ActiveSrcEdit,ActiveUnitInfo,true) then exit;
|
|
{ $IFDEF IDE_DEBUG}
|
|
writeln('');
|
|
writeln('[TMainIDE.OnPropHookRenameMethod] ************');
|
|
{ $ENDIF}
|
|
FOpenEditorsOnCodeToolChange:=true;
|
|
try
|
|
// create published method
|
|
r:=CodeToolBoss.RenamePublishedMethod(ActiveUnitInfo.Source,
|
|
ActiveUnitInfo.Form.ClassName,CurName,NewName);
|
|
{ $IFDEF IDE_DEBUG}
|
|
writeln('');
|
|
writeln('[TMainIDE.OnPropHookRenameMethod] ************2 ',r);
|
|
{ $ENDIF}
|
|
ApplyCodeToolChanges;
|
|
if r then begin
|
|
FormEditor1.JITFormList.RenameMethod(TForm(ActiveUnitInfo.Form),
|
|
CurName,NewName);
|
|
end else begin
|
|
DoJumpToCodeToolBossError;
|
|
end;
|
|
finally
|
|
FOpenEditorsOnCodeToolChange:=false;
|
|
end;
|
|
end;
|
|
|
|
procedure TMainIDE.mnuEditCopyClicked(Sender: TObject);
|
|
begin
|
|
DoEditMenuCommand(ecCopy);
|
|
end;
|
|
|
|
procedure TMainIDE.mnuEditCutClicked(Sender: TObject);
|
|
begin
|
|
DoEditMenuCommand(ecCut);
|
|
end;
|
|
|
|
procedure TMainIDE.mnuEditPasteClicked(Sender: TObject);
|
|
begin
|
|
DoEditMenuCommand(ecPaste);
|
|
end;
|
|
|
|
procedure TMainIDE.mnuEditRedoClicked(Sender: TObject);
|
|
begin
|
|
DoEditMenuCommand(ecRedo);
|
|
end;
|
|
|
|
procedure TMainIDE.mnuEditUndoClicked(Sender: TObject);
|
|
begin
|
|
DoEditMenuCommand(ecUndo);
|
|
end;
|
|
|
|
procedure TMainIDE.mnuEditIndentBlockClicked(Sender: TObject);
|
|
begin
|
|
DoEditMenuCommand(ecBlockIndent);
|
|
end;
|
|
|
|
procedure TMainIDE.mnuEditUnindentBlockClicked(Sender: TObject);
|
|
begin
|
|
DoEditMenuCommand(ecBlockUnindent);
|
|
end;
|
|
|
|
procedure TMainIDE.mnuEditUpperCaseBlockClicked(Sender: TObject);
|
|
begin
|
|
DoEditMenuCommand(ecSelectionUpperCase);
|
|
end;
|
|
|
|
procedure TMainIDE.mnuEditLowerCaseBlockClicked(Sender: TObject);
|
|
begin
|
|
DoEditMenuCommand(ecSelectionLowerCase);
|
|
end;
|
|
|
|
procedure TMainIDE.mnuEditTabsToSpacesBlockClicked(Sender: TObject);
|
|
begin
|
|
DoEditMenuCommand(ecSelectionTabs2Spaces);
|
|
end;
|
|
|
|
procedure TMainIDE.mnuEditCompleteCodeClicked(Sender: TObject);
|
|
begin
|
|
DoCompleteCodeAtCursor;
|
|
end;
|
|
|
|
procedure TMainIDE.DoEditMenuCommand(EditorCommand: integer);
|
|
var
|
|
ActiveSourceEditor: TSourceEditor;
|
|
ActiveUnitInfo: TUnitInfo;
|
|
begin
|
|
GetCurrentUnit(ActiveSourceEditor,ActiveUnitInfo);
|
|
if FCodeLastActivated then begin
|
|
// send command to source editor
|
|
if ActiveSourceEditor=nil then exit;
|
|
ActiveSourceEditor.DoEditorExecuteCommand(EditorCommand);
|
|
end else begin
|
|
// send command to form editor
|
|
if ActiveUnitInfo=nil then exit;
|
|
|
|
// ToDo: send command to form editor/designer
|
|
|
|
end;
|
|
end;
|
|
|
|
procedure TMainIDE.OnApplyWindowLayout(ALayout: TIDEWindowLayout);
|
|
begin
|
|
if (ALayout=nil) or (ALayout.Form=nil) then exit;
|
|
//writeln('AAA TMainIDE.OnApplyWindowLayout ',ALayout.Form.Name,' ',ALayout.Form.Classname,' ',IDEWindowPlacementNames[ALayout.WindowPlacement],' ',ALayout.CustomCoordinatesAreValid,' ',ALayout.Left,' ',ALayout.Top,' ',ALayout.Width,' ',ALayout.Height);
|
|
if (ALayout.WindowPlacement in [iwpCustomPosition,iwpRestoreWindowGeometry])
|
|
and (ALayout.CustomCoordinatesAreValid) then begin
|
|
// explicit position
|
|
ALayout.Form.SetBounds(
|
|
ALayout.Left,ALayout.Top,ALayout.Width,ALayout.Height)
|
|
end else
|
|
if (not (ALayout.WindowPlacement in [iwpDocked,iwpUseWindowManagerSetting]))
|
|
then begin
|
|
// default position
|
|
if ALayout.FormID=DefaultObjectInspectorName then begin
|
|
ALayout.Form.SetBounds(
|
|
Left,Top+Height+30,230,Max(Screen.Height-Top-Height-120,50));
|
|
end else
|
|
if ALayout.FormID=DefaultMainIDEName then begin
|
|
ALayout.Form.SetBounds(0,0,Screen.Width-10,100);
|
|
end else
|
|
if ALayout.FormID=DefaultSourceNoteBookName then begin
|
|
ALayout.Form.SetBounds(250,Top+Height+30,Screen.Width-300,
|
|
Screen.Height-200-Top-Height);
|
|
end else
|
|
if ALayout.FormID=DefaultMessagesViewName then begin
|
|
ALayout.Form.SetBounds(260,SourceNotebook.Top+SourceNotebook.Height+30,
|
|
Screen.Width-300,80);
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
procedure TMainIDE.mnuSearchFindBlockOtherEnd(Sender: TObject);
|
|
begin
|
|
DoGoToPascalBlockOtherEnd;
|
|
end;
|
|
|
|
procedure TMainIDE.mnuSearchFindBlockStart(Sender: TObject);
|
|
begin
|
|
DoGoToPascalBlockStart;
|
|
end;
|
|
|
|
procedure TMainIDE.mnuSearchFindDeclaration(Sender: TObject);
|
|
begin
|
|
DoFindDeclarationAtCursor;
|
|
end;
|
|
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
initialization
|
|
{ $I mainide.lrs}
|
|
{$I images/laz_images.lrs}
|
|
{$I images/mainicon.lrs}
|
|
|
|
|
|
end.
|
|
|
|
|
|
{ =============================================================================
|
|
$Log$
|
|
Revision 1.340 2002/08/16 17:47:37 lazarus
|
|
MG: added some IDE menuicons, fixed submenu indicator bug
|
|
|
|
Revision 1.339 2002/08/09 19:48:12 lazarus
|
|
MG: Open File at cursor now checks for include directive
|
|
|
|
Revision 1.338 2002/08/08 10:33:48 lazarus
|
|
MG: main bar speedbar open arrow now shows recent projects and files
|
|
|
|
Revision 1.337 2002/08/08 09:38:34 lazarus
|
|
MG: recent file menus are now updated instantly
|
|
|
|
Revision 1.336 2002/08/07 09:55:26 lazarus
|
|
MG: codecompletion now checks for filebreaks, savefile now checks for filedate
|
|
|
|
Revision 1.335 2002/08/05 08:56:54 lazarus
|
|
MG: TMenuItems can now be enabled and disabled
|
|
|
|
Revision 1.334 2002/08/03 14:30:37 lazarus
|
|
MG: added file access monitoring and diff view
|
|
|
|
Revision 1.333 2002/08/01 14:15:02 lazarus
|
|
MG: started file access monitoring for loaded files
|
|
|
|
Revision 1.332 2002/08/01 14:10:28 lazarus
|
|
MG: started file access monitoring for loaded files
|
|
|
|
Revision 1.331 2002/08/01 08:06:25 lazarus
|
|
MG: reduced output
|
|
|
|
Revision 1.330 2002/08/01 08:03:01 lazarus
|
|
MG: accelerated searches in project
|
|
|
|
Revision 1.329 2002/07/31 15:21:50 lazarus
|
|
MG: added tool: Convert DFM file to LFM
|
|
|
|
Revision 1.328 2002/07/31 09:00:03 lazarus
|
|
MG: fixed undefined editor topline on codetool error
|
|
|
|
Revision 1.327 2002/07/29 13:26:54 lazarus
|
|
MG: source notebook pagenames are now updated more often
|
|
|
|
Revision 1.326 2002/07/22 18:25:10 lazarus
|
|
MG: reduced output
|
|
|
|
Revision 1.325 2002/07/20 13:54:13 lazarus
|
|
MG: fixed show designed form on new project
|
|
|
|
Revision 1.324 2002/07/06 06:37:04 lazarus
|
|
MG: added Revert
|
|
|
|
Revision 1.323 2002/07/05 12:54:27 lazarus
|
|
MG: syntax highlighter is now set on open non existing file
|
|
|
|
Revision 1.322 2002/07/05 10:32:44 lazarus
|
|
MG: added handling of invalid programnamnes on save project
|
|
|
|
Revision 1.321 2002/07/05 09:36:45 lazarus
|
|
MG: fixed unreleased gdiobjects on printing cmd line help
|
|
|
|
Revision 1.320 2002/07/04 14:48:22 lazarus
|
|
MG: added internationalization, started with german
|
|
|
|
Revision 1.319 2002/07/04 10:44:50 lazarus
|
|
MG: added comment for MainIDE:=Self;
|
|
|
|
Revision 1.318 2002/07/04 10:22:46 lazarus
|
|
MG: fixed double parsing of command line
|
|
|
|
Revision 1.317 2002/06/28 06:34:54 lazarus
|
|
MG: added Tabs To Spaces in Selection
|
|
|
|
Revision 1.316 2002/06/26 15:11:07 lazarus
|
|
MG: added new tool: Guess misplaced $IFDEF/$ENDIF
|
|
|
|
Revision 1.315 2002/06/21 17:54:22 lazarus
|
|
MG: in design mode the mouse cursor is now also set for hidden gdkwindows
|
|
|
|
Revision 1.314 2002/06/19 19:46:05 lazarus
|
|
MG: Form Editing: snapping, guidelines, modified on move/resize, creating components in csDesigning, ...
|
|
|
|
Revision 1.313 2002/06/14 14:57:05 lazarus
|
|
MG: fixed open file at cursor search path
|
|
|
|
Revision 1.312 2002/06/13 18:37:47 lazarus
|
|
MG: added upper/lowercase selection
|
|
|
|
Revision 1.311 2002/06/12 14:27:15 lazarus
|
|
MG: reduced IDE output
|
|
|
|
Revision 1.310 2002/06/12 14:14:50 lazarus
|
|
MG: fixed working directory of running programms
|
|
|
|
Revision 1.309 2002/06/11 15:40:27 lazarus
|
|
MG: implemented GridSizeX, GridSizeY and DisplayGrid
|
|
|
|
Revision 1.308 2002/06/09 07:08:41 lazarus
|
|
MG: fixed window jumping
|
|
|
|
Revision 1.307 2002/06/08 17:15:59 lazarus
|
|
MG: added close buttons and images to TNoteBook and close buttons to source editor
|
|
|
|
Revision 1.306 2002/06/04 15:17:17 lazarus
|
|
MG: improved TFont for XLFD font names
|
|
|
|
Revision 1.305 2002/06/01 08:41:27 lazarus
|
|
MG: DrawFramControl now uses gtk style, transparent STrechBlt
|
|
|
|
Revision 1.304 2002/05/30 22:08:09 lazarus
|
|
MG: TMenuItems now all owned by mainbar
|
|
|
|
Revision 1.303 2002/05/30 21:40:08 lazarus
|
|
* component-palette: TMainMenu replaces TMenu
|
|
+ TMenuItem registered as unvisible component
|
|
+ TMainMenu registered as visible component
|
|
stoppok
|
|
|
|
Revision 1.302 2002/05/30 14:18:46 lazarus
|
|
MG: filedialogs now saves size and history
|
|
|
|
Revision 1.301 2002/05/27 17:58:40 lazarus
|
|
MG: added command line help
|
|
|
|
Revision 1.300 2002/05/27 14:38:32 lazarus
|
|
MG; fixed find declaration of overloaded procs and expression input types
|
|
|
|
Revision 1.299 2002/05/24 07:18:14 lazarus
|
|
MG: save is now possible during debugging
|
|
|
|
Revision 1.298 2002/05/16 15:51:48 lazarus
|
|
MG: closing editor now switches to left editor
|
|
|
|
Revision 1.297 2002/05/16 14:35:19 lazarus
|
|
MG: fixed codetools error jumping
|
|
|
|
Revision 1.296 2002/05/16 14:01:45 lazarus
|
|
MG: backuping files now save file attributes/permissions
|
|
|
|
Revision 1.295 2002/05/16 13:00:55 lazarus
|
|
MG: fixed changing syntax highlighter on save as
|
|
|
|
Revision 1.294 2002/05/13 06:12:54 lazarus
|
|
MG: fixed saving unitlinks after changing fpc soure path
|
|
|
|
Revision 1.293 2002/05/10 06:57:42 lazarus
|
|
MG: updated licenses
|
|
|
|
Revision 1.292 2002/05/08 14:45:55 lazarus
|
|
|
|
New About Dialog Window added; Splash screen modified to stay visible
|
|
longer. MAH
|
|
|
|
Revision 1.291 2002/05/06 12:21:35 lazarus
|
|
MG: nicer default window positions
|
|
|
|
Revision 1.290 2002/04/30 15:01:05 lazarus
|
|
MWE:
|
|
+ Added view callstack menu item
|
|
|
|
Revision 1.289 2002/04/28 14:10:27 lazarus
|
|
MG: fixes for saving resource files
|
|
|
|
Revision 1.288 2002/04/28 06:42:47 lazarus
|
|
MG: fixed saving OI settings
|
|
|
|
Revision 1.287 2002/04/27 18:56:47 lazarus
|
|
MG: started component renaming
|
|
|
|
Revision 1.286 2002/04/26 13:50:14 lazarus
|
|
MG: IDE and codetools work now with trimmed filenames
|
|
|
|
Revision 1.285 2002/04/26 12:53:29 lazarus
|
|
MG: fixed debug line coloring
|
|
|
|
Revision 1.284 2002/04/26 12:27:26 lazarus
|
|
MG: added Delphi6 Templates
|
|
|
|
Revision 1.283 2002/04/22 07:16:34 lazarus
|
|
MG: fixed missing include directives
|
|
|
|
Revision 1.282 2002/04/21 14:30:36 lazarus
|
|
MG: fixed inputhistory load/save
|
|
|
|
Revision 1.281 2002/04/21 13:24:05 lazarus
|
|
MG: small updates and fixes
|
|
|
|
Revision 1.280 2002/04/21 06:53:52 lazarus
|
|
MG: fixed save lrs to test dir
|
|
|
|
Revision 1.279 2002/04/16 08:55:04 lazarus
|
|
MG: added path editor for compiler options
|
|
|
|
Revision 1.278 2002/04/15 10:56:05 lazarus
|
|
MG: fixes for open lpi files and improved jump points
|
|
|
|
Revision 1.277 2002/04/12 16:36:07 lazarus
|
|
MG: FPC unitlinks are now saved
|
|
|
|
Revision 1.276 2002/04/12 10:21:53 lazarus
|
|
MG: added Event Assignment completion
|
|
|
|
Revision 1.275 2002/04/11 08:08:47 lazarus
|
|
MG: small fixes, cleanups and started event assignment completion
|
|
|
|
Revision 1.274 2002/04/06 11:20:41 lazarus
|
|
MG: added fpc define templates
|
|
|
|
Revision 1.273 2002/04/05 18:17:59 lazarus
|
|
MG: fixed removing virtual units
|
|
|
|
Revision 1.272 2002/04/05 16:34:13 lazarus
|
|
MG: fixed autocreate form editing in project opts
|
|
|
|
Revision 1.271 2002/04/04 17:21:17 lazarus
|
|
MG: fixed outputfilter for linker errors
|
|
|
|
Revision 1.270 2002/04/03 18:20:49 lazarus
|
|
MG: fixed mem leaks
|
|
|
|
Revision 1.269 2002/04/03 10:34:05 lazarus
|
|
MG: fixed crash on open project
|
|
|
|
Revision 1.268 2002/04/02 17:18:24 lazarus
|
|
MG: fixed save project as, renaming source name
|
|
|
|
Revision 1.267 2002/03/31 23:20:35 lazarus
|
|
MG: fixed initial size of TPage
|
|
|
|
Revision 1.266 2002/03/29 23:22:20 lazarus
|
|
MG: started internationalization of IDE
|
|
|
|
Revision 1.265 2002/03/29 14:32:46 lazarus
|
|
MG: further internationalization
|
|
|
|
Revision 1.264 2002/03/28 16:39:04 lazarus
|
|
MG: added find replace history
|
|
|
|
Revision 1.263 2002/03/28 11:49:48 lazarus
|
|
MG: added search function: Goto Include Directive
|
|
|
|
Revision 1.262 2002/03/28 09:34:06 lazarus
|
|
MG: show objectinspector only if needed
|
|
|
|
Revision 1.261 2002/03/28 00:11:04 lazarus
|
|
MG: removed unused
|
|
|
|
Revision 1.260 2002/03/27 11:35:56 lazarus
|
|
MG: removed ide_debugger.inc
|
|
|
|
Revision 1.259 2002/03/27 10:39:42 lazarus
|
|
MG: splitted main.pp: debugger management in TDebugManager
|
|
|
|
Revision 1.258 2002/03/27 09:25:31 lazarus
|
|
MG: renamed main Project to Project1
|
|
|
|
Revision 1.257 2002/03/27 09:18:11 lazarus
|
|
MG: splitted main.pp: TMainIDE has now an ancestor TMainIDEBar
|
|
|
|
Revision 1.256 2002/03/25 16:48:25 lazarus
|
|
MG: clean ups for main.pp, many minor fixes
|
|
|
|
Revision 1.255 2002/03/25 07:29:21 lazarus
|
|
MG: added TOpen/SaveFlags and splittet some methods
|
|
|
|
Revision 1.254 2002/03/23 19:05:50 lazarus
|
|
MG: pascal lowercase for open new unit
|
|
|
|
Revision 1.253 2002/03/23 16:40:29 lazarus
|
|
MWE:
|
|
+ Added loval variables menu item
|
|
* Honoured the UseLaunchingApplication checkbox
|
|
|
|
Revision 1.252 2002/03/23 15:54:28 lazarus
|
|
MWE:
|
|
+ Added locals dialog
|
|
* Modified breakpoints dialog (load as resource)
|
|
+ Added generic debuggerdlg class
|
|
= Reorganized main.pp, all debbugger relater routines are moved
|
|
to include/ide_debugger.inc
|
|
|
|
Revision 1.251 2002/03/22 17:36:09 lazarus
|
|
MG: added include link history
|
|
|
|
Revision 1.250 2002/03/22 13:11:29 lazarus
|
|
Added Application.ProcessMessages in MainMouseMoved to prevent the IDE hanging.
|
|
|
|
Shane
|
|
|
|
Revision 1.249 2002/03/22 12:36:44 lazarus
|
|
MG: many fixes, to make it short: events
|
|
|
|
Revision 1.248 2002/03/21 23:15:39 lazarus
|
|
MG: fixes for save-project-as and pagenames
|
|
|
|
Revision 1.247 2002/03/21 22:44:06 lazarus
|
|
MG: fixes for save-as and form streaming exceptions
|
|
|
|
Revision 1.246 2002/03/18 12:29:53 lazarus
|
|
MG: added complete properties checkbox and ecSaveAll
|
|
|
|
Revision 1.245 2002/03/14 14:39:39 lazarus
|
|
MG: implemented run parameters: wd, launching app, sys vars
|
|
|
|
Revision 1.244 2002/03/12 23:55:34 lazarus
|
|
MWE:
|
|
* More delphi compatibility added/updated to TListView
|
|
* Introduced TDebugger.locals
|
|
* Moved breakpoints dialog to debugger dir
|
|
* Changed breakpoints dialog to read from resource
|
|
|
|
Revision 1.243 2002/03/09 02:03:57 lazarus
|
|
MWE:
|
|
* Upgraded gdb debugger to gdb/mi debugger
|
|
* Set default value for autpopoup
|
|
* Added Clear popup to debugger output window
|
|
|
|
Revision 1.242 2002/03/08 11:37:40 lazarus
|
|
MG: outputfilter can now find include files
|
|
|
|
Revision 1.241 2002/03/07 14:14:23 lazarus
|
|
MG: fixed find declaration new nodecache flags, find next
|
|
|
|
Revision 1.240 2002/03/05 14:52:15 lazarus
|
|
MG: updates for codetools defines
|
|
|
|
Revision 1.239 2002/03/05 08:14:58 lazarus
|
|
MG: updates for codetools defines editor
|
|
|
|
Revision 1.238 2002/03/02 11:08:36 lazarus
|
|
MG: fixed method search diff proc, fixed synedit insert in empty line, small fixes, started define editor
|
|
|
|
Revision 1.237 2002/03/01 15:51:06 lazarus
|
|
MG: added selection keys and nil operand
|
|
|
|
Revision 1.236 2002/02/28 12:09:07 lazarus
|
|
MG: fixes, code creation policies, keymap categories, menu shortcuts
|
|
|
|
Revision 1.235 2002/02/25 23:04:23 lazarus
|
|
MG: added close all menuitem
|
|
|
|
Revision 1.234 2002/02/25 22:56:55 lazarus
|
|
MG: fixed resetting error line before compiling
|
|
|
|
Revision 1.233 2002/02/25 19:17:27 lazarus
|
|
MG: fixed restore window positions
|
|
|
|
Revision 1.232 2002/02/25 16:48:10 lazarus
|
|
MG: new IDE window layout system
|
|
|
|
Revision 1.231 2002/02/24 20:51:22 lazarus
|
|
Improved TSpeedButton (Glyph, Spacing, Margin, drawing)
|
|
Added PageCount to TNotebook
|
|
Optimized component selection buttons a bit.
|
|
|
|
Revision 1.230 2002/02/22 17:39:40 lazarus
|
|
MG: improved LinkScanner error messages
|
|
|
|
Revision 1.229 2002/02/22 14:25:00 lazarus
|
|
MG: fixed completion box for templates and identifiers
|
|
|
|
Revision 1.228 2002/02/22 14:05:55 lazarus
|
|
MG: edit menu reconnected to source editor
|
|
|
|
Revision 1.227 2002/02/20 23:33:23 lazarus
|
|
MWE:
|
|
+ Published OnClick for TMenuItem
|
|
+ Published PopupMenu property for TEdit and TMemo (Doesn't work yet)
|
|
* Fixed debugger running twice
|
|
+ Added Debugger output form
|
|
* Enabled breakpoints
|
|
|
|
Revision 1.226 2002/02/20 16:01:43 lazarus
|
|
MG: fixed editor opts general flags
|
|
|
|
Revision 1.225 2002/02/18 22:46:10 lazarus
|
|
Implented TMenuItem.ShortCut (not much tested).
|
|
|
|
Revision 1.224 2002/02/17 19:51:10 lazarus
|
|
MG: fixed running project
|
|
|
|
Revision 1.223 2002/02/17 19:34:44 lazarus
|
|
MG: fixed view units/forms
|
|
|
|
Revision 1.222 2002/02/11 15:12:00 lazarus
|
|
MG: started OI events
|
|
|
|
Revision 1.221 2002/02/10 20:44:00 lazarus
|
|
MG: fixed a node cache range bug
|
|
|
|
Revision 1.220 2002/02/09 22:24:50 lazarus
|
|
MG: get compatible published methods now works
|
|
|
|
Revision 1.219 2002/02/09 21:09:19 lazarus
|
|
MG: fixed sourcenotebook closing and form-unit switching
|
|
|
|
Revision 1.218 2002/02/09 20:32:08 lazarus
|
|
MG: many fixes on my way to events
|
|
|
|
Revision 1.217 2002/02/08 21:08:00 lazarus
|
|
MG: saving of virtual project files will now save the whole project
|
|
|
|
Revision 1.214 2002/02/07 18:18:59 lazarus
|
|
MG: fixed deactivating hints
|
|
|
|
Revision 1.213 2002/02/07 13:48:47 lazarus
|
|
MG: fixed mem leak FBreakPts
|
|
|
|
Revision 1.212 2002/02/06 22:23:13 lazarus
|
|
MG: codetools now know the compiler options
|
|
|
|
Revision 1.211 2002/02/06 09:37:40 lazarus
|
|
MG: outputfilter now recognizes, if compiler in sub directory
|
|
|
|
Revision 1.210 2002/02/06 08:58:27 lazarus
|
|
MG: fixed compiler warnings and asking to create non existing files
|
|
|
|
Revision 1.209 2002/02/05 23:16:47 lazarus
|
|
MWE: * Updated tebugger
|
|
+ Added debugger to IDE
|
|
|
|
Revision 1.208 2002/02/03 00:23:54 lazarus
|
|
TPanel implemented.
|
|
Basic graphic primitives split into GraphType package, so that we can
|
|
reference it from interface (GTK, Win32) units.
|
|
New Frame3d canvas method that uses native (themed) drawing (GTK only).
|
|
New overloaded Canvas.TextRect method.
|
|
LCLLinux and Graphics was split, so a bunch of files had to be modified.
|
|
|
|
Revision 1.207 2002/01/27 19:08:43 lazarus
|
|
MWE: Removed ^M
|
|
|
|
Revision 1.206 2002/01/24 14:12:52 lazarus
|
|
MG: added build lazarus feature and config dialog
|
|
|
|
Revision 1.205 2002/01/23 22:12:54 lazarus
|
|
MG: external tool output parsing for fpc and make messages
|
|
|
|
Revision 1.204 2002/01/23 20:07:20 lazarus
|
|
MG: added outputfilter
|
|
|
|
Revision 1.203 2002/01/21 14:17:44 lazarus
|
|
MG: added find-block-start and renamed find-block-other-end
|
|
|
|
Revision 1.202 2002/01/17 11:00:00 lazarus
|
|
MG: increased IDE version to 0.8.2 alpha
|
|
|
|
Revision 1.201 2002/01/15 20:21:37 lazarus
|
|
MG: jump history for find declaration
|
|
|
|
Revision 1.200 2002/01/13 12:46:17 lazarus
|
|
MG: fixed linker options, compiler options dialog
|
|
|
|
Revision 1.199 2002/01/11 20:41:52 lazarus
|
|
MG: added guess unclosed block
|
|
|
|
Revision 1.197 2002/01/02 13:32:52 lazarus
|
|
MG: fixed clean abort of project loading
|
|
|
|
Revision 1.196 2001/12/31 22:45:41 lazarus
|
|
Took out some test code.
|
|
Shane
|
|
|
|
Revision 1.195 2001/12/31 22:42:59 lazarus
|
|
Added a TViewColumn editor to be used in the object inspector as TViewColumn's property editor.
|
|
Shane
|
|
|
|
Revision 1.194 2001/12/28 11:01:20 lazarus
|
|
MG: fixed save as with lfm and lrs files
|
|
|
|
Revision 1.193 2001/12/20 19:11:22 lazarus
|
|
Changed the delay for the hints from 100 miliseconds to 500. I'm hoping this reduces the crashing for some people until I determine the problem.
|
|
Shane
|
|
|
|
Revision 1.192 2001/12/19 22:09:13 lazarus
|
|
MG: added GUID and alias parsing, added DoJumpToCodeToolBossError
|
|
|
|
Revision 1.191 2001/12/19 20:28:50 lazarus
|
|
Enabled Alignment of columns in a TListView.
|
|
Shane
|
|
|
|
Revision 1.190 2001/12/18 21:09:58 lazarus
|
|
MOre additions for breakpoints dialog
|
|
Added a TSynEditPlugin in SourceEditor to get notified of lines inserted and deleted from the source.
|
|
Shane
|
|
|
|
Revision 1.189 2001/12/18 21:00:59 lazarus
|
|
MG: compiler, fpc source and lazarus src can now be changed without restart
|
|
|
|
Revision 1.188 2001/12/17 19:41:05 lazarus
|
|
MG: added binary file recognition and readonly recognition
|
|
|
|
Revision 1.186 2001/12/17 11:16:08 lazarus
|
|
MG: fixed open file key in source editor
|
|
|
|
Revision 1.185 2001/12/16 22:24:54 lazarus
|
|
MG: changes for new compiler 20011216
|
|
|
|
Revision 1.183 2001/12/16 11:20:26 lazarus
|
|
MG: find declaration for uses sections
|
|
|
|
Revision 1.182 2001/12/15 22:58:09 lazarus
|
|
MG: fixed code completion in virtual files
|
|
|
|
Revision 1.181 2001/12/15 10:57:48 lazarus
|
|
MG: added hint checkboxes to environment options
|
|
|
|
Revision 1.180 2001/12/14 18:38:55 lazarus
|
|
Changed code for TListView
|
|
Added a generic Breakpoints dialog
|
|
Shane
|
|
|
|
Revision 1.179 2001/12/13 23:09:57 lazarus
|
|
MG: enhanced code caching, fixed CursorToCleanPos and beautify statement
|
|
|
|
Revision 1.178 2001/12/12 16:49:14 lazarus
|
|
Added code to disable save button when the active unit is not "modified".
|
|
Shane
|
|
|
|
Revision 1.177 2001/12/12 15:12:31 lazarus
|
|
MG: added file path to files in TOpenDialog
|
|
|
|
Revision 1.176 2001/12/12 14:25:03 lazarus
|
|
Changes to allow multiple files being opened in main.pp
|
|
Shane
|
|
|
|
Revision 1.175 2001/12/11 16:51:36 lazarus
|
|
Modified the Watches dialog
|
|
Shane
|
|
|
|
Revision 1.174 2001/12/11 15:43:35 lazarus
|
|
MG: TCodeBuffer.LoadFromFile now checks file date
|
|
|
|
Revision 1.172 2001/12/11 11:14:10 lazarus
|
|
MG: fixed save project, saving units twice
|
|
|
|
Revision 1.171 2001/12/11 09:34:32 lazarus
|
|
MG: fixed open file at cursor
|
|
|
|
Revision 1.170 2001/12/10 23:03:18 lazarus
|
|
MG: enhanced open file at cursor to read more than one word
|
|
|
|
Revision 1.169 2001/12/10 22:39:36 lazarus
|
|
MG: added perl highlighter
|
|
|
|
Revision 1.168 2001/12/10 16:22:40 lazarus
|
|
MG: started open file at cursor
|
|
|
|
Revision 1.167 2001/12/10 14:32:57 lazarus
|
|
MOdified the Watches dialog and added the lfm and lrs files for it and the insert watch dialog.
|
|
|
|
Shane
|
|
|
|
Revision 1.166 2001/12/10 08:44:23 lazarus
|
|
MG: added search for compiler, if not set
|
|
|
|
Revision 1.165 2001/12/07 20:12:13 lazarus
|
|
Added a watch dialog.
|
|
Shane
|
|
|
|
Revision 1.164 2001/12/05 18:19:10 lazarus
|
|
MG: added calendar to allunits and removed unused vars
|
|
|
|
Revision 1.163 2001/12/04 14:28:04 lazarus
|
|
Added hints to the main ide.
|
|
Shane
|
|
|
|
Revision 1.162 2001/12/02 13:05:33 lazarus
|
|
MG: reduced output
|
|
|
|
Revision 1.161 2001/12/02 11:03:35 lazarus
|
|
MG: added default pascal file extension option
|
|
|
|
Revision 1.160 2001/12/01 22:17:26 lazarus
|
|
MG: added jump-history
|
|
|
|
Revision 1.159 2001/11/27 15:06:11 lazarus
|
|
MG: added multi language syntax hilighting
|
|
|
|
Revision 1.158 2001/11/22 14:28:30 lazarus
|
|
MG: cropped all component icons
|
|
|
|
Revision 1.157 2001/11/22 10:37:23 lazarus
|
|
MG: moved lazres, added images/README
|
|
|
|
Revision 1.156 2001/11/21 19:32:31 lazarus
|
|
TComboBox can now be moved in FormEditor
|
|
Shane
|
|
|
|
Revision 1.155 2001/11/21 13:09:50 lazarus
|
|
MG: moved executable check to ideprocs.pp
|
|
|
|
Revision 1.153 2001/11/20 19:39:45 lazarus
|
|
MG: DoRunProject writes the programfilename
|
|
|
|
Revision 1.152 2001/11/20 18:30:30 lazarus
|
|
Pressing DEL when form is the only thing selected in designer no longer crashes Lazarus.
|
|
Shane
|
|
|
|
Revision 1.151 2001/11/20 15:09:21 lazarus
|
|
MG: open project now only opens lpi files
|
|
|
|
Revision 1.150 2001/11/19 22:01:25 lazarus
|
|
MG: run button and menu run now builds+runs
|
|
|
|
Revision 1.148 2001/11/19 15:23:17 lazarus
|
|
MG: added quick syntax check via codetools
|
|
|
|
Revision 1.147 2001/11/19 12:15:03 lazarus
|
|
MG: added dirty about lazarus dlg
|
|
|
|
Revision 1.146 2001/11/17 10:16:23 lazarus
|
|
MG: clear define cache on changing env paths
|
|
|
|
Revision 1.145 2001/11/15 13:49:49 lazarus
|
|
MG: fixed open non existing file and unitname in save project as
|
|
|
|
Revision 1.144 2001/11/14 19:10:00 lazarus
|
|
MG: fixes for parser and linkscanner and small cleanups
|
|
|
|
Revision 1.143 2001/11/14 17:46:54 lazarus
|
|
Changes to make toggling between form and unit work.
|
|
Added BringWindowToTop
|
|
Shane
|
|
|
|
Revision 1.141 2001/11/12 16:56:04 lazarus
|
|
MG: CLIPBOARD
|
|
|
|
Revision 1.140 2001/11/09 18:39:11 lazarus
|
|
MG: turned back to stable ground (use old process.pp)
|
|
|
|
Revision 1.139 2001/11/09 18:15:20 lazarus
|
|
MG: added external tools
|
|
|
|
Revision 1.138 2001/11/07 16:14:11 lazarus
|
|
MG: fixes for the new compiler
|
|
|
|
Revision 1.137 2001/11/06 15:47:31 lazarus
|
|
MG: added build all
|
|
|
|
Revision 1.136 2001/11/06 12:20:30 lazarus
|
|
MG: added Run Parameter Options - not enabled yet
|
|
|
|
Revision 1.135 2001/11/05 18:18:13 lazarus
|
|
added popupmenu+arrows to notebooks, added target filename
|
|
|
|
Revision 1.134 2001/11/05 00:12:50 lazarus
|
|
MWE: First steps of a debugger.
|
|
|
|
Revision 1.133 2001/11/03 08:37:34 lazarus
|
|
MG: fixed errorline showing, resource adding and published var editing and added make cleanall
|
|
|
|
Revision 1.132 2001/11/01 21:30:32 lazarus
|
|
Changes to Messagebox.
|
|
Added line to CodeTools to prevent duplicate USES entries.
|
|
|
|
Revision 1.131 2001/11/01 18:48:48 lazarus
|
|
Changed Application.Messagebox to use TMessageBox class.
|
|
Added icon images for mtError and mtConfirmation
|
|
Shane
|
|
|
|
Revision 1.130 2001/10/31 18:09:51 lazarus
|
|
MG: fixed DirectoryExists
|
|
|
|
Revision 1.129 2001/10/31 16:29:20 lazarus
|
|
Fixed the gtk mousemove bug where the control gets the coord's based on it's parent instead of itself.
|
|
Shane
|
|
|
|
Revision 1.128 2001/10/26 20:36:48 lazarus
|
|
Added an OnSelectionChanged event in Main.pp fired by MSgView dialog. This fires when the ListBox gets clicked on.
|
|
This allows the editor to highlight different lines when you click on different error messages.
|
|
Shane
|
|
|
|
Revision 1.126 2001/10/23 09:13:51 lazarus
|
|
MG: fixed TestProject
|
|
|
|
Revision 1.125 2001/10/18 13:34:03 lazarus
|
|
MG: keys for debugging
|
|
|
|
Revision 1.123 2001/10/17 13:43:15 lazarus
|
|
MG: added find previous to source editor
|
|
|
|
Revision 1.122 2001/10/16 14:19:10 lazarus
|
|
MG: added nvidia opengl support and a new opengl example from satan
|
|
|
|
Revision 1.121 2001/10/15 17:41:30 lazarus
|
|
MG: fixed splashform showing
|
|
|
|
Revision 1.115 2001/10/09 09:46:49 lazarus
|
|
MG: added codetools, fixed synedit unindent, fixed MCatureHandle
|
|
|
|
Revision 1.113 2001/07/31 18:57:48 lazarus
|
|
MG: fixed source ediotr statusbar filename
|
|
|
|
Revision 1.111 2001/07/29 20:33:23 lazarus
|
|
MG: bugfixed event propeditor, DoJumpToMethod with searchpath
|
|
|
|
Revision 1.110 2001/07/10 10:44:15 lazarus
|
|
MG: save unit only if modified
|
|
|
|
Revision 1.105 2001/07/01 15:55:43 lazarus
|
|
MG: JumpToCompilerMessage now centered in source editor
|
|
|
|
Revision 1.104 2001/06/27 21:43:23 lazarus
|
|
MG: added project bookmark support
|
|
|
|
Revision 1.103 2001/06/26 00:08:35 lazarus
|
|
MG: added code for form icons from Rene E. Beszon
|
|
|
|
Revision 1.102 2001/06/06 12:30:40 lazarus
|
|
MG: bugfixes
|
|
|
|
Revision 1.100 2001/06/05 10:27:50 lazarus
|
|
MG: saving recent file lists
|
|
|
|
Revision 1.98 2001/05/29 08:16:26 lazarus
|
|
MG: bugfixes + starting programs
|
|
|
|
Revision 1.97 2001/05/28 10:00:54 lazarus
|
|
MG: removed unused code. fixed editor name bug.
|
|
|
|
Revision 1.96 2001/05/27 11:52:00 lazarus
|
|
MG: added --primary-config-path=<filename> cmd line option
|
|
|
|
Revision 1.92 2001/04/21 14:50:21 lazarus
|
|
MG: bugfix for mainunits ext <> .lpr
|
|
|
|
Revision 1.91 2001/04/13 17:56:16 lazarus
|
|
MWE:
|
|
* Moved menubar outside clientarea
|
|
* Played a bit with the IDE layout
|
|
* Moved the creation of the toolbarspeedbuttons to a separate function
|
|
|
|
Revision 1.90 2001/04/04 13:58:50 lazarus
|
|
Added some changes to compreg.pp
|
|
|
|
Revision 1.89 2001/04/04 13:55:34 lazarus
|
|
MG: finished TComponentPropertyEditor, added OnModified to oi, cfe and designer
|
|
|
|
Revision 1.88 2001/04/04 12:20:34 lazarus
|
|
MG: added add to/remove from project, small bugfixes
|
|
|
|
Revision 1.86 2001/03/31 13:35:22 lazarus
|
|
MG: added non-visual-component code to IDE and LCL
|
|
|
|
Revision 1.85 2001/03/29 13:11:33 lazarus
|
|
MG: fixed loading program file bug
|
|
|
|
Revision 1.84 2001/03/29 12:38:59 lazarus
|
|
MG: new environment opts, ptApplication bugfixes
|
|
|
|
Revision 1.83 2001/03/28 14:08:45 lazarus
|
|
MG: added backup code and fixed removing controls
|
|
|
|
Revision 1.82 2001/03/27 11:11:13 lazarus
|
|
MG: fixed mouse msg, added filedialog initialdir
|
|
|
|
Revision 1.81 2001/03/26 14:52:30 lazarus
|
|
MG: TSourceLog + compiling bugfixes
|
|
|
|
Revision 1.75 2001/03/19 14:00:46 lazarus
|
|
MG: fixed many unreleased DC and GDIObj bugs
|
|
|
|
Revision 1.74 2001/03/12 18:57:31 lazarus
|
|
MG: new designer and controlselection code
|
|
|
|
Revision 1.68 2001/03/03 11:06:15 lazarus
|
|
added project support, codetools
|
|
|
|
Revision 1.62 2001/02/22 17:04:57 lazarus
|
|
added environment options + killed ide unit circles
|
|
|
|
Revision 1.61 2001/02/21 22:55:24 lazarus
|
|
small bugfixes + added TOIOptions
|
|
|
|
Revision 1.60 2001/02/20 16:53:24 lazarus
|
|
Changes for wordcompletion and many other things from Mattias.
|
|
Shane
|
|
|
|
Revision 1.59 2001/02/16 19:13:29 lazarus
|
|
Added some functions
|
|
Shane
|
|
|
|
Revision 1.58 2001/02/08 06:09:25 lazarus
|
|
Partially implemented Save Project As menu selection. CAW
|
|
|
|
Revision 1.57 2001/02/06 13:38:57 lazarus
|
|
Fixes from Mattias for EditorOPtions
|
|
Fixes to COmpiler that should allow people to compile if their path is set up.
|
|
Changes to code completion.
|
|
Shane
|
|
|
|
Revision 1.56 2001/02/04 04:18:11 lazarus
|
|
Code cleanup and JITFOrms bug fix.
|
|
Shane
|
|
|
|
Revision 1.55 2001/02/02 14:23:37 lazarus
|
|
Start of code completion code.
|
|
Shane
|
|
|
|
Revision 1.54 2001/02/01 16:45:19 lazarus
|
|
Started the code completion.
|
|
Shane
|
|
|
|
Revision 1.52 2001/01/31 13:03:33 lazarus
|
|
Commitng source with new editor.
|
|
Shane
|
|
|
|
Revision 1.51 2001/01/31 06:25:35 lazarus
|
|
Removed global unit.
|
|
Removed and commented all references to TUnitInfo.
|
|
|
|
Revision 1.50 2001/01/29 05:46:30 lazarus
|
|
Moved Project Options and Compiler Options menus to the Project menu.
|
|
Added Project property to TMainIDE class to allow the project to be
|
|
accessed from other units. CAW
|
|
|
|
Revision 1.49 2001/01/18 13:27:30 lazarus
|
|
Minor changees
|
|
Shane
|
|
|
|
Revision 1.48 2001/01/16 23:30:45 lazarus
|
|
trying to determine what's crashing LAzarus on load.
|
|
Shane
|
|
|
|
Revision 1.45 2001/01/15 20:55:44 lazarus
|
|
Changes for loading filesa
|
|
Shane
|
|
|
|
Revision 1.44 2001/01/15 18:25:51 lazarus
|
|
Fixed a stupid error I caused by using a variable as an index in main.pp and this variable sometimes caused an exception because the index was out of range.
|
|
Shane
|
|
|
|
Revision 1.43 2001/01/14 03:56:57 lazarus
|
|
Shane
|
|
|
|
Revision 1.42 2001/01/13 06:11:06 lazarus
|
|
Minor fixes
|
|
Shane
|
|
|
|
Revision 1.41 2001/01/13 03:09:37 lazarus
|
|
Minor changes
|
|
Shane
|
|
|
|
Revision 1.40 2001/01/12 18:46:49 lazarus
|
|
Named the speedbuttons in MAINIDE and took out some writelns.
|
|
Shane
|
|
|
|
Revision 1.39 2001/01/12 18:10:53 lazarus
|
|
Changes for keyevents in the editor.
|
|
Shane
|
|
|
|
Revision 1.38 2001/01/09 21:06:06 lazarus
|
|
Started taking KeyDown messages in TDesigner
|
|
Shane
|
|
|
|
Revision 1.37 2001/01/09 18:23:20 lazarus
|
|
Worked on moving controls. It's just not working with the X and Y coord's I'm getting.
|
|
Shane
|
|
|
|
Revision 1.36 2001/01/08 23:48:33 lazarus
|
|
MWE:
|
|
~ Changed makefiles
|
|
~ Removed testform from lararus and changed it into program
|
|
* some formatting
|
|
|
|
Revision 1.35 2001/01/06 06:28:47 lazarus
|
|
Made Designer control the control movement and such. I am now using ISDesignMsg to move the controls.
|
|
Shane
|
|
|
|
Revision 1.32 2001/01/04 20:33:53 lazarus
|
|
Moved lresources.
|
|
Moved CreateLFM to Main.pp
|
|
Changed Form1 and TFOrm1 to MainIDE and TMainIDE
|
|
Shane
|
|
|
|
Revision 1.30 2001/01/03 18:44:54 lazarus
|
|
The Speedbutton now has a numglyphs setting.
|
|
I started the TStringPropertyEditor
|
|
|
|
Revision 1.29 2000/12/29 20:43:17 lazarus
|
|
I added the run button with an Enable and disable icon
|
|
|
|
Revision 1.25 2000/12/29 13:35:50 lazarus
|
|
Mattias submitted new lresources.pp and lazres.pp files.
|
|
Shane
|
|
|
|
Revision 1.23 2000/12/21 20:28:33 lazarus
|
|
Project - RUN will run the program IF the program is the active unit in the Editor.
|
|
Shane
|
|
|
|
Revision 1.22 2000/12/20 20:04:30 lazarus
|
|
Made PRoject Build compile the active unit. This way we can actually play with it by compiling units.
|
|
|
|
Revision 1.19 2000/12/19 18:43:12 lazarus
|
|
Removed IDEEDITOR. This causes the PROJECT class to not function.
|
|
Saving projects no longer works.
|
|
|
|
I added TSourceNotebook and TSourceEditor. They do all the work for saving/closing/opening units. Somethings work but they are in early development.
|
|
Shane
|
|
|
|
Revision 1.18 2000/12/15 18:25:16 lazarus
|
|
Changes from Mattias and I.
|
|
Shane
|
|
|
|
Revision 1.16 2000/12/01 20:23:34 lazarus
|
|
renamed Object_Inspector and Prop_edits by removing the underline.
|
|
Shane
|
|
|
|
Revision 1.5 2000/08/10 13:22:51 lazarus
|
|
Additions for the FIND dialog
|
|
Shane
|
|
|
|
Revision 1.4 2000/08/09 18:32:10 lazarus
|
|
Added more code for the find function.
|
|
Shane
|
|
|
|
Revision 1.2 2000/08/07 19:15:05 lazarus
|
|
Added the Search menu to the IDE.
|
|
Shane
|
|
|
|
Revision 1.1 2000/07/13 10:27:47 michael
|
|
+ Initial import
|
|
|
|
}
|
|
|