Simon Grossenbacher vor 9 Jahren
Ursprung
Commit
eb24032caa
6 geänderte Dateien mit 983 neuen und 115 gelöschten Zeilen
  1. 5 5
      AppConfig.json
  2. BIN
      RESTDebugger.exe
  3. 18 17
      prj/RESTDebugger.dproj
  4. 2 2
      prj/RESTDebugger.stat
  5. 660 47
      src/_frmMain.dfm
  6. 298 44
      src/_frmMain.pas

+ 5 - 5
AppConfig.json

@@ -1,13 +1,13 @@
 {
 	"MainWindowPos": {
-		"Left": 843,
-		"Top": 270,
+		"Left": 662,
+		"Top": 231,
 		"StayOnTop": false,
-		"Width": 934,
-		"Height": 797
+		"Width": 1119,
+		"Height": 870
 	},
 	"Dialogs": {
-		"LastOpenDir": "C:\\dev\\RESTDebugger\\src\\",
+		"LastOpenDir": "C:\\dev\\RESTDebugger\\",
 		"LastSaveDir": "C:\\dev\\RESTDebugger\\"
 	}
 }

BIN
RESTDebugger.exe


+ 18 - 17
prj/RESTDebugger.dproj

@@ -101,6 +101,7 @@
         <DCC_RemoteDebug>false</DCC_RemoteDebug>
     </PropertyGroup>
     <PropertyGroup Condition="'$(Cfg_1_Win64)'!=''">
+        <Debugger_RunParams>C:\dev\RESTDebugger\test.rdproj</Debugger_RunParams>
         <VerInfo_Locale>1033</VerInfo_Locale>
         <AppEnableHighDPI>true</AppEnableHighDPI>
         <VerInfo_IncludeVerInfo>true</VerInfo_IncludeVerInfo>
@@ -174,12 +175,27 @@
                         <Overwrite>true</Overwrite>
                     </Platform>
                 </DeployFile>
-                <DeployClass Name="ProjectiOSDeviceResourceRules">
+                <DeployClass Name="DependencyModule">
+                    <Platform Name="Win32">
+                        <Operation>0</Operation>
+                        <Extensions>.dll;.bpl</Extensions>
+                    </Platform>
                     <Platform Name="iOSDevice64">
                         <Operation>1</Operation>
+                        <Extensions>.dylib</Extensions>
+                    </Platform>
+                    <Platform Name="OSX32">
+                        <RemoteDir>Contents\MacOS</RemoteDir>
+                        <Operation>1</Operation>
+                        <Extensions>.dylib</Extensions>
                     </Platform>
                     <Platform Name="iOSDevice32">
                         <Operation>1</Operation>
+                        <Extensions>.dylib</Extensions>
+                    </Platform>
+                    <Platform Name="iOSSimulator">
+                        <Operation>1</Operation>
+                        <Extensions>.dylib</Extensions>
                     </Platform>
                 </DeployClass>
                 <DeployClass Name="ProjectOSXResource">
@@ -530,27 +546,12 @@
                         <Operation>1</Operation>
                     </Platform>
                 </DeployClass>
-                <DeployClass Name="DependencyModule">
-                    <Platform Name="Win32">
-                        <Operation>0</Operation>
-                        <Extensions>.dll;.bpl</Extensions>
-                    </Platform>
+                <DeployClass Name="ProjectiOSDeviceResourceRules">
                     <Platform Name="iOSDevice64">
                         <Operation>1</Operation>
-                        <Extensions>.dylib</Extensions>
-                    </Platform>
-                    <Platform Name="OSX32">
-                        <RemoteDir>Contents\MacOS</RemoteDir>
-                        <Operation>1</Operation>
-                        <Extensions>.dylib</Extensions>
                     </Platform>
                     <Platform Name="iOSDevice32">
                         <Operation>1</Operation>
-                        <Extensions>.dylib</Extensions>
-                    </Platform>
-                    <Platform Name="iOSSimulator">
-                        <Operation>1</Operation>
-                        <Extensions>.dylib</Extensions>
                     </Platform>
                 </DeployClass>
                 <ProjectRoot Platform="iOSDevice64" Name="$(PROJECTNAME).app"/>

+ 2 - 2
prj/RESTDebugger.stat

@@ -1,9 +1,9 @@
 [Stats]
-EditorSecs=2254
+EditorSecs=2260
 DesignerSecs=1542
 InspectorSecs=822
 CompileSecs=63183
-OtherSecs=973
+OtherSecs=987
 StartTime=27.10.2016 18:27:37
 RealKeys=0
 EffectiveKeys=0

+ 660 - 47
src/_frmMain.dfm

@@ -3,7 +3,7 @@ object frmMain: TfrmMain
   Top = 0
   BorderIcons = [biSystemMenu, biMinimize]
   Caption = 'REST Debugger'
-  ClientHeight = 820
+  ClientHeight = 924
   ClientWidth = 1004
   Color = clBtnFace
   Font.Charset = DEFAULT_CHARSET
@@ -30,7 +30,6 @@ object frmMain: TfrmMain
     Color = clWhite
     ParentBackground = False
     TabOrder = 0
-    ExplicitWidth = 1014
     object Label1: TLabel
       Left = 25
       Top = 31
@@ -79,7 +78,7 @@ object frmMain: TfrmMain
   end
   object dxStatusBar: TdxStatusBar
     Left = 0
-    Top = 800
+    Top = 904
     Width = 1004
     Height = 20
     Panels = <
@@ -90,42 +89,42 @@ object frmMain: TfrmMain
       end
       item
         PanelStyleClassName = 'TdxStatusBarTextPanelStyle'
-        Text = 'Loaded Project:'
+        Text = 'Default project loaded.'
       end>
     Font.Charset = DEFAULT_CHARSET
     Font.Color = clWindowText
     Font.Height = -11
     Font.Name = 'Tahoma'
     Font.Style = []
-    ExplicitTop = 717
-    ExplicitWidth = 1014
+    ExplicitTop = 804
   end
   object cxPageControl1: TcxPageControl
     Left = 0
-    Top = 353
+    Top = 471
     Width = 1004
-    Height = 447
+    Height = 433
     Align = alClient
-    TabOrder = 6
+    TabOrder = 5
     Properties.ActivePage = tabContent
     Properties.CustomButtons.Buttons = <>
-    ExplicitTop = 296
-    ExplicitWidth = 1014
-    ExplicitHeight = 514
-    ClientRectBottom = 443
-    ClientRectLeft = 4
-    ClientRectRight = 1000
-    ClientRectTop = 24
+    ExplicitTop = 353
+    ExplicitHeight = 447
+    ClientRectBottom = 431
+    ClientRectLeft = 2
+    ClientRectRight = 1002
+    ClientRectTop = 26
     object tabContent: TcxTabSheet
-      Caption = 'Content'
+      Caption = 'Response Content'
       ImageIndex = 0
-      ExplicitWidth = 1006
-      ExplicitHeight = 486
+      ExplicitLeft = 4
+      ExplicitTop = 24
+      ExplicitWidth = 996
+      ExplicitHeight = 419
       object EditorContent: TBCEditor
         Left = 0
         Top = 0
-        Width = 996
-        Height = 419
+        Width = 1000
+        Height = 405
         Cursor = crIBeam
         ActiveLine.Indicator.Visible = False
         Align = alClient
@@ -180,7 +179,8 @@ object frmMain: TfrmMain
         Minimap.Width = 140
         PopupMenu = PopupMenuEditorContent
         RightMargin.Position = 80
-        RightMargin.Visible = True
+        RightMargin.Visible = False
+        Scroll.Options = [soShowVerticalScrollHint, soWheelClickMove]
         SpecialChars.Style = scsDot
         SyncEdit.ShortCut = 24650
         TabOrder = 0
@@ -217,19 +217,22 @@ object frmMain: TfrmMain
           FF00}
         WordWrap.Indicator.MaskColor = clFuchsia
         WordWrap.Width = wwwPage
-        ExplicitTop = -2
+        ExplicitWidth = 996
+        ExplicitHeight = 419
       end
     end
     object tabHeaders: TcxTabSheet
-      Caption = 'Headers'
+      Caption = 'Response Headers'
       ImageIndex = 1
-      ExplicitWidth = 1006
-      ExplicitHeight = 486
+      ExplicitLeft = 4
+      ExplicitTop = 24
+      ExplicitWidth = 996
+      ExplicitHeight = 419
       object EditorHeaders: TBCEditor
         Left = 0
         Top = 0
-        Width = 996
-        Height = 419
+        Width = 1000
+        Height = 405
         Cursor = crIBeam
         ActiveLine.Indicator.Visible = False
         Align = alClient
@@ -283,7 +286,8 @@ object frmMain: TfrmMain
         Minimap.Font.Style = []
         Minimap.Width = 140
         RightMargin.Position = 80
-        RightMargin.Visible = True
+        RightMargin.Visible = False
+        Scroll.Options = [soShowVerticalScrollHint, soWheelClickMove]
         SpecialChars.Style = scsDot
         SyncEdit.ShortCut = 24650
         TabOrder = 0
@@ -320,10 +324,8 @@ object frmMain: TfrmMain
           FF00}
         WordWrap.Indicator.MaskColor = clFuchsia
         WordWrap.Width = wwwPage
-        ExplicitLeft = 379
-        ExplicitTop = 336
-        ExplicitWidth = 200
-        ExplicitHeight = 150
+        ExplicitWidth = 996
+        ExplicitHeight = 419
       end
     end
   end
@@ -331,10 +333,12 @@ object frmMain: TfrmMain
     Left = 0
     Top = 99
     Width = 1004
-    Height = 254
+    Height = 372
     Align = alTop
     BevelOuter = bvNone
     TabOrder = 7
+    ExplicitLeft = -190
+    ExplicitTop = 54
     object Label2: TLabel
       Left = 8
       Top = 16
@@ -343,19 +347,31 @@ object frmMain: TfrmMain
       Caption = 'Presets:'
     end
     object Label3: TLabel
-      Left = 8
-      Top = 72
+      Left = 97
+      Top = 75
       Width = 49
       Height = 13
       Caption = 'Base URL:'
     end
-    object edtURL: TcxTextEdit
+    object Label4: TLabel
+      Left = 8
+      Top = 331
+      Width = 42
+      Height = 13
+      Caption = 'Full URL:'
+    end
+    object Label6: TLabel
       Left = 8
-      Top = 136
+      Top = 74
+      Width = 40
+      Height = 13
+      Caption = 'Method:'
+    end
+    object edtFullURL: TcxTextEdit
+      Left = 8
+      Top = 345
+      Properties.ReadOnly = True
       TabOrder = 0
-      Text = 
-        'https://merp.iblnet.ch/MobileERPService/?action=GetPresentoDayVi' +
-        'ew&token=70f12f9439554198b2e6965b2b14b9e6&day=30.08.2016'
       Width = 577
     end
     object btnRun: TcxButton
@@ -367,18 +383,460 @@ object frmMain: TfrmMain
       TabOrder = 1
       OnClick = btnRunClick
     end
-    object cxPopupEdit1: TcxPopupEdit
+    object edtBaseURL: TcxTextEdit
+      Left = 97
+      Top = 91
+      Properties.OnChange = edtBaseURLPropertiesChange
+      TabOrder = 2
+      Width = 488
+    end
+    object btnAdd: TcxButton
+      Left = 478
+      Top = 30
+      Width = 25
+      Height = 25
+      Hint = 'Add Preset'
+      OptionsImage.ImageIndex = 0
+      OptionsImage.Images = cxImageList
+      ParentShowHint = False
+      ShowHint = True
+      TabOrder = 3
+      OnClick = btnAddClick
+    end
+    object btnDelete: TcxButton
+      Left = 570
+      Top = 30
+      Width = 25
+      Height = 25
+      Hint = 'Delete Preset'
+      OptionsImage.ImageIndex = 1
+      OptionsImage.Images = cxImageList
+      ParentShowHint = False
+      ShowHint = True
+      TabOrder = 4
+      OnClick = btnDeleteClick
+    end
+    object comboPresets: TcxComboBox
       Left = 8
       Top = 32
-      TabOrder = 2
-      Text = 'cxPopupEdit1'
+      Properties.DropDownListStyle = lsFixedList
+      Properties.OnChange = comboPresetsPropertiesChange
+      TabOrder = 5
       Width = 464
     end
-    object edtBaseURL: TcxTextEdit
+    object btnEdit: TcxButton
+      Left = 509
+      Top = 30
+      Width = 25
+      Height = 25
+      Hint = 'Edit Preset'
+      OptionsImage.ImageIndex = 2
+      OptionsImage.Images = cxImageList
+      ParentShowHint = False
+      ShowHint = True
+      TabOrder = 6
+      OnClick = btnEditClick
+    end
+    object btnCopyPreset: TcxButton
+      Left = 540
+      Top = 30
+      Width = 25
+      Height = 25
+      Hint = 'Copy Preset'
+      OptionsImage.ImageIndex = 3
+      OptionsImage.Images = cxImageList
+      ParentShowHint = False
+      ShowHint = True
+      TabOrder = 7
+      OnClick = btnCopyPresetClick
+    end
+    object comboMethod: TcxComboBox
       Left = 8
-      Top = 88
-      TabOrder = 3
+      Top = 90
+      Properties.DropDownListStyle = lsFixedList
+      Properties.Items.Strings = (
+        'GET'
+        'POST')
+      Properties.OnChange = comboMethodPropertiesChange
+      TabOrder = 8
+      Width = 83
+    end
+    object cxPageControl2: TcxPageControl
+      Left = 8
+      Top = 125
       Width = 577
+      Height = 193
+      TabOrder = 9
+      Properties.ActivePage = cxTabSheet1
+      Properties.CustomButtons.Buttons = <>
+      ClientRectBottom = 191
+      ClientRectLeft = 2
+      ClientRectRight = 575
+      ClientRectTop = 26
+      object cxTabSheet1: TcxTabSheet
+        Caption = 'URL Parameters'
+        ImageIndex = 0
+        ExplicitLeft = 1
+        ExplicitTop = 25
+        ExplicitWidth = 285
+        object EditorURLParams: TBCEditor
+          Left = 0
+          Top = 31
+          Width = 573
+          Height = 134
+          Cursor = crIBeam
+          ActiveLine.Indicator.Visible = False
+          Align = alClient
+          Caret.MultiEdit.Enabled = True
+          Caret.NonBlinking.Enabled = False
+          Caret.Options = []
+          CodeFolding.Colors.Indent = clBlack
+          CodeFolding.Hint.Font.Charset = DEFAULT_CHARSET
+          CodeFolding.Hint.Font.Color = clWindowText
+          CodeFolding.Hint.Font.Height = -11
+          CodeFolding.Hint.Font.Name = 'Courier New'
+          CodeFolding.Hint.Font.Style = []
+          CodeFolding.Hint.Indicator.Glyph.Visible = False
+          CodeFolding.Visible = True
+          CompletionProposal.CloseChars = '()[]. '
+          CompletionProposal.Columns = <
+            item
+            end>
+          CompletionProposal.Font.Charset = DEFAULT_CHARSET
+          CompletionProposal.Font.Color = clWindowText
+          CompletionProposal.Font.Height = -11
+          CompletionProposal.Font.Name = 'Courier New'
+          CompletionProposal.Font.Style = []
+          CompletionProposal.ShortCut = 16416
+          CompletionProposal.Trigger.Chars = '.'
+          CompletionProposal.Trigger.Enabled = False
+          Directories.Colors = 'Colors'
+          Directories.Highlighters = 'Highlighters'
+          Font.Charset = DEFAULT_CHARSET
+          Font.Color = clWindowText
+          Font.Height = -13
+          Font.Name = 'Courier New'
+          Font.Style = []
+          LeftMargin.Bookmarks.Visible = False
+          LeftMargin.Font.Charset = DEFAULT_CHARSET
+          LeftMargin.Font.Color = 13408665
+          LeftMargin.Font.Height = -11
+          LeftMargin.Font.Name = 'Courier New'
+          LeftMargin.Font.Style = []
+          LeftMargin.Marks.Visible = False
+          LeftMargin.MarksPanel.Visible = False
+          LeftMargin.Width = 35
+          LineSpacing = 0
+          MatchingPair.Enabled = True
+          Minimap.Font.Charset = DEFAULT_CHARSET
+          Minimap.Font.Color = clWindowText
+          Minimap.Font.Height = -1
+          Minimap.Font.Name = 'Courier New'
+          Minimap.Font.Style = []
+          Minimap.Width = 140
+          OnChange = EditorURLParamsChange
+          Options = [eoAutoIndent, eoDragDropEditing, eoTrimTrailingSpaces]
+          RightMargin.Position = 80
+          RightMargin.Visible = False
+          Scroll.Bars = ssVertical
+          Scroll.Options = [soShowVerticalScrollHint, soWheelClickMove]
+          SpecialChars.Style = scsDot
+          SyncEdit.Enabled = False
+          SyncEdit.ShortCut = 24650
+          TabOrder = 0
+          WordWrap.Enabled = False
+          WordWrap.Indicator.Glyph.Data = {
+            7E030000424D7E0300000000000036000000280000000F0000000E0000000100
+            2000000000004803000000000000000000000000000000000000FF00FF00FF00
+            FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00
+            FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF000000
+            000000000000000000000000000000000000FF00FF00FF00FF00FF00FF00FF00
+            FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00
+            FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF0080000000FF00
+            FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF0000000000000000000000
+            0000FF00FF00FF00FF00FF00FF00FF00FF008000000080000000FF00FF00FF00
+            FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00
+            FF00FF00FF00FF00FF008000000080000000800000008000000080000000FF00
+            FF00FF00FF00FF00FF00FF00FF00000000000000000000000000FF00FF00FF00
+            FF00FF00FF00FF00FF008000000080000000FF00FF00FF00FF0080000000FF00
+            FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00
+            FF00FF00FF00FF00FF0080000000FF00FF00FF00FF0080000000FF00FF00FF00
+            FF00FF00FF000000000000000000000000000000000000000000FF00FF00FF00
+            FF00FF00FF00FF00FF00FF00FF00FF00FF0080000000FF00FF00FF00FF00FF00
+            FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00
+            FF00FF00FF00FF00FF00FF00FF0080000000FF00FF00FF00FF00FF00FF00FF00
+            FF00FF00FF00FF00FF00FF00FF00800000008000000080000000800000008000
+            00008000000080000000FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00
+            FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00
+            FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00
+            FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00
+            FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00
+            FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00
+            FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00
+            FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00
+            FF00}
+          WordWrap.Indicator.MaskColor = clFuchsia
+          WordWrap.Width = wwwPage
+          ExplicitLeft = 165
+          ExplicitTop = 62
+          ExplicitWidth = 545
+          ExplicitHeight = 59
+        end
+        object Panel3: TPanel
+          Left = 0
+          Top = 0
+          Width = 573
+          Height = 31
+          Align = alTop
+          BevelOuter = bvNone
+          TabOrder = 1
+          ExplicitWidth = 285
+          object Label5: TLabel
+            Left = 8
+            Top = 8
+            Width = 213
+            Height = 13
+            Caption = 'URL Parameters (One per line name=value):'
+          end
+        end
+      end
+      object cxTabSheet2: TcxTabSheet
+        Caption = 'Extra Headers'
+        ImageIndex = 1
+        ExplicitWidth = 285
+        object EditorExtraHeaders: TBCEditor
+          Left = 0
+          Top = 31
+          Width = 573
+          Height = 134
+          Cursor = crIBeam
+          ActiveLine.Indicator.Visible = False
+          Align = alClient
+          Caret.MultiEdit.Enabled = True
+          Caret.NonBlinking.Enabled = False
+          Caret.Options = []
+          CodeFolding.Colors.Indent = clBlack
+          CodeFolding.Hint.Font.Charset = DEFAULT_CHARSET
+          CodeFolding.Hint.Font.Color = clWindowText
+          CodeFolding.Hint.Font.Height = -11
+          CodeFolding.Hint.Font.Name = 'Courier New'
+          CodeFolding.Hint.Font.Style = []
+          CodeFolding.Hint.Indicator.Glyph.Visible = False
+          CodeFolding.Visible = True
+          CompletionProposal.CloseChars = '()[]. '
+          CompletionProposal.Columns = <
+            item
+            end>
+          CompletionProposal.Font.Charset = DEFAULT_CHARSET
+          CompletionProposal.Font.Color = clWindowText
+          CompletionProposal.Font.Height = -11
+          CompletionProposal.Font.Name = 'Courier New'
+          CompletionProposal.Font.Style = []
+          CompletionProposal.ShortCut = 16416
+          CompletionProposal.Trigger.Chars = '.'
+          CompletionProposal.Trigger.Enabled = False
+          Directories.Colors = 'Colors'
+          Directories.Highlighters = 'Highlighters'
+          Font.Charset = DEFAULT_CHARSET
+          Font.Color = clWindowText
+          Font.Height = -13
+          Font.Name = 'Courier New'
+          Font.Style = []
+          LeftMargin.Bookmarks.Visible = False
+          LeftMargin.Font.Charset = DEFAULT_CHARSET
+          LeftMargin.Font.Color = 13408665
+          LeftMargin.Font.Height = -11
+          LeftMargin.Font.Name = 'Courier New'
+          LeftMargin.Font.Style = []
+          LeftMargin.Marks.Visible = False
+          LeftMargin.MarksPanel.Visible = False
+          LeftMargin.Width = 35
+          Lines.Strings = (
+            '')
+          LineSpacing = 0
+          MatchingPair.Enabled = True
+          Minimap.Font.Charset = DEFAULT_CHARSET
+          Minimap.Font.Color = clWindowText
+          Minimap.Font.Height = -1
+          Minimap.Font.Name = 'Courier New'
+          Minimap.Font.Style = []
+          Minimap.Width = 140
+          OnChange = EditorURLParamsChange
+          Options = [eoAutoIndent, eoDragDropEditing, eoTrimTrailingSpaces]
+          RightMargin.Position = 80
+          RightMargin.Visible = False
+          Scroll.Bars = ssVertical
+          Scroll.Options = [soShowVerticalScrollHint, soWheelClickMove]
+          SpecialChars.Style = scsDot
+          SyncEdit.Enabled = False
+          SyncEdit.ShortCut = 24650
+          TabOrder = 0
+          WordWrap.Enabled = False
+          WordWrap.Indicator.Glyph.Data = {
+            7E030000424D7E0300000000000036000000280000000F0000000E0000000100
+            2000000000004803000000000000000000000000000000000000FF00FF00FF00
+            FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00
+            FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF000000
+            000000000000000000000000000000000000FF00FF00FF00FF00FF00FF00FF00
+            FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00
+            FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF0080000000FF00
+            FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF0000000000000000000000
+            0000FF00FF00FF00FF00FF00FF00FF00FF008000000080000000FF00FF00FF00
+            FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00
+            FF00FF00FF00FF00FF008000000080000000800000008000000080000000FF00
+            FF00FF00FF00FF00FF00FF00FF00000000000000000000000000FF00FF00FF00
+            FF00FF00FF00FF00FF008000000080000000FF00FF00FF00FF0080000000FF00
+            FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00
+            FF00FF00FF00FF00FF0080000000FF00FF00FF00FF0080000000FF00FF00FF00
+            FF00FF00FF000000000000000000000000000000000000000000FF00FF00FF00
+            FF00FF00FF00FF00FF00FF00FF00FF00FF0080000000FF00FF00FF00FF00FF00
+            FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00
+            FF00FF00FF00FF00FF00FF00FF0080000000FF00FF00FF00FF00FF00FF00FF00
+            FF00FF00FF00FF00FF00FF00FF00800000008000000080000000800000008000
+            00008000000080000000FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00
+            FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00
+            FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00
+            FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00
+            FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00
+            FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00
+            FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00
+            FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00
+            FF00}
+          WordWrap.Indicator.MaskColor = clFuchsia
+          WordWrap.Width = wwwPage
+          ExplicitLeft = 165
+          ExplicitTop = 62
+          ExplicitWidth = 545
+          ExplicitHeight = 59
+        end
+        object Panel4: TPanel
+          Left = 0
+          Top = 0
+          Width = 573
+          Height = 31
+          Align = alTop
+          BevelOuter = bvNone
+          TabOrder = 1
+          ExplicitTop = 5
+          object Label7: TLabel
+            Left = 8
+            Top = 8
+            Width = 205
+            Height = 13
+            Caption = 'Extra Headers (One per line name=value):'
+          end
+        end
+      end
+      object tabPostData: TcxTabSheet
+        Caption = 'Post Data'
+        ImageIndex = 2
+        ExplicitLeft = 3
+        object EditorPostData: TBCEditor
+          Left = 0
+          Top = 0
+          Width = 573
+          Height = 165
+          Cursor = crIBeam
+          ActiveLine.Indicator.Visible = False
+          Align = alClient
+          Caret.MultiEdit.Enabled = True
+          Caret.NonBlinking.Enabled = False
+          Caret.Options = []
+          CodeFolding.Colors.Indent = clBlack
+          CodeFolding.Hint.Font.Charset = DEFAULT_CHARSET
+          CodeFolding.Hint.Font.Color = clWindowText
+          CodeFolding.Hint.Font.Height = -11
+          CodeFolding.Hint.Font.Name = 'Courier New'
+          CodeFolding.Hint.Font.Style = []
+          CodeFolding.Hint.Indicator.Glyph.Visible = False
+          CodeFolding.Visible = True
+          CompletionProposal.CloseChars = '()[]. '
+          CompletionProposal.Columns = <
+            item
+            end>
+          CompletionProposal.Font.Charset = DEFAULT_CHARSET
+          CompletionProposal.Font.Color = clWindowText
+          CompletionProposal.Font.Height = -11
+          CompletionProposal.Font.Name = 'Courier New'
+          CompletionProposal.Font.Style = []
+          CompletionProposal.ShortCut = 16416
+          CompletionProposal.Trigger.Chars = '.'
+          CompletionProposal.Trigger.Enabled = False
+          Directories.Colors = 'Colors'
+          Directories.Highlighters = 'Highlighters'
+          Font.Charset = DEFAULT_CHARSET
+          Font.Color = clWindowText
+          Font.Height = -13
+          Font.Name = 'Courier New'
+          Font.Style = []
+          LeftMargin.Bookmarks.Visible = False
+          LeftMargin.Font.Charset = DEFAULT_CHARSET
+          LeftMargin.Font.Color = 13408665
+          LeftMargin.Font.Height = -11
+          LeftMargin.Font.Name = 'Courier New'
+          LeftMargin.Font.Style = []
+          LeftMargin.Marks.Visible = False
+          LeftMargin.MarksPanel.Visible = False
+          LeftMargin.Width = 35
+          Lines.Strings = (
+            '')
+          LineSpacing = 0
+          MatchingPair.Enabled = True
+          Minimap.Font.Charset = DEFAULT_CHARSET
+          Minimap.Font.Color = clWindowText
+          Minimap.Font.Height = -1
+          Minimap.Font.Name = 'Courier New'
+          Minimap.Font.Style = []
+          Minimap.Width = 140
+          OnChange = EditorURLParamsChange
+          Options = [eoAutoIndent, eoDragDropEditing, eoTrimTrailingSpaces]
+          RightMargin.Position = 80
+          RightMargin.Visible = False
+          Scroll.Bars = ssVertical
+          Scroll.Options = [soShowVerticalScrollHint, soWheelClickMove]
+          SpecialChars.Style = scsDot
+          SyncEdit.Enabled = False
+          SyncEdit.ShortCut = 24650
+          TabOrder = 0
+          WordWrap.Enabled = False
+          WordWrap.Indicator.Glyph.Data = {
+            7E030000424D7E0300000000000036000000280000000F0000000E0000000100
+            2000000000004803000000000000000000000000000000000000FF00FF00FF00
+            FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00
+            FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF000000
+            000000000000000000000000000000000000FF00FF00FF00FF00FF00FF00FF00
+            FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00
+            FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF0080000000FF00
+            FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF0000000000000000000000
+            0000FF00FF00FF00FF00FF00FF00FF00FF008000000080000000FF00FF00FF00
+            FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00
+            FF00FF00FF00FF00FF008000000080000000800000008000000080000000FF00
+            FF00FF00FF00FF00FF00FF00FF00000000000000000000000000FF00FF00FF00
+            FF00FF00FF00FF00FF008000000080000000FF00FF00FF00FF0080000000FF00
+            FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00
+            FF00FF00FF00FF00FF0080000000FF00FF00FF00FF0080000000FF00FF00FF00
+            FF00FF00FF000000000000000000000000000000000000000000FF00FF00FF00
+            FF00FF00FF00FF00FF00FF00FF00FF00FF0080000000FF00FF00FF00FF00FF00
+            FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00
+            FF00FF00FF00FF00FF00FF00FF0080000000FF00FF00FF00FF00FF00FF00FF00
+            FF00FF00FF00FF00FF00FF00FF00800000008000000080000000800000008000
+            00008000000080000000FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00
+            FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00
+            FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00
+            FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00
+            FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00
+            FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00
+            FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00
+            FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00
+            FF00}
+          WordWrap.Indicator.MaskColor = clFuchsia
+          WordWrap.Width = wwwPage
+          ExplicitLeft = 165
+          ExplicitTop = 62
+          ExplicitWidth = 545
+          ExplicitHeight = 59
+        end
+      end
     end
   end
   object OpenDialog: TOpenDialog
@@ -393,6 +851,7 @@ object frmMain: TfrmMain
     Top = 30
   end
   object dxSkinController: TdxSkinController
+    NativeStyle = False
     SkinName = 'Office2016Colorful'
     Left = 645
     Top = 30
@@ -538,6 +997,7 @@ object frmMain: TfrmMain
       Hint = 'Save'
       Visible = ivAlways
       ShortCut = 16467
+      OnClick = btnSaveClick
     end
     object btnSaveAs: TdxBarButton
       Caption = 'Save As...'
@@ -633,4 +1093,157 @@ object frmMain: TfrmMain
       Caption = 'Format Code'
     end
   end
+  object cxImageList: TcxImageList
+    FormatVersion = 1
+    DesignInfo = 27197935
+    ImageInfo = <
+      item
+        Image.Data = {
+          36040000424D3604000000000000360000002800000010000000100000000100
+          2000000000000004000000000000000000000000000000000000000000000000
+          0000000000000000000000000000000000000000000000000000000000000000
+          0000000000000000000000000000000000000000000000000000000000000000
+          000000000000000000000404041A141414881F1F1FD4242424F9242424F91F1F
+          1FD4141414880404041A00000000000000000000000000000000000000000000
+          0000000000000D0D0D5A232323F3252525FF252525FF252525FF252525FF2525
+          25FF252525FF232323F30D0D0D5A000000000000000000000000000000000000
+          00000D0D0D5A252525FE252525FF252525FF252525FF00000000000000002525
+          25FF252525FF252525FF252525FE0D0D0D5A0000000000000000000000000404
+          041A232323F3252525FF252525FF252525FF252525FF00000000000000002525
+          25FF252525FF252525FF252525FF232323F30404041A00000000000000001414
+          1488252525FF252525FF252525FF252525FF252525FF00000000000000002525
+          25FF252525FF252525FF252525FF252525FF1414148800000000000000001F1F
+          1FD4252525FF252525FF252525FF252525FF252525FF00000000000000002525
+          25FF252525FF252525FF252525FF252525FF1F1F1FD400000000000000002424
+          24F9252525FF0000000000000000000000000000000000000000000000000000
+          0000000000000000000000000000252525FF242424F900000000000000002424
+          24F9252525FF0000000000000000000000000000000000000000000000000000
+          0000000000000000000000000000252525FF242424F900000000000000001F1F
+          1FD4252525FF252525FF252525FF252525FF252525FF00000000000000002525
+          25FF252525FF252525FF252525FF252525FF1F1F1FD400000000000000001414
+          1488252525FF252525FF252525FF252525FF252525FF00000000000000002525
+          25FF252525FF252525FF252525FF252525FF1414148800000000000000000404
+          041A232323F3252525FF252525FF252525FF252525FF00000000000000002525
+          25FF252525FF252525FF252525FF232323F30404041A00000000000000000000
+          00000D0D0D5A252525FE252525FF252525FF252525FF00000000000000002525
+          25FF252525FF252525FF252525FE0D0D0D5A0000000000000000000000000000
+          0000000000000D0D0D5A232323F3252525FF252525FF252525FF252525FF2525
+          25FF252525FF232323F30D0D0D5A000000000000000000000000000000000000
+          000000000000000000000404041A141414881F1F1FD4242424F9242424F91F1F
+          1FD4141414880404041A00000000000000000000000000000000000000000000
+          0000000000000000000000000000000000000000000000000000000000000000
+          0000000000000000000000000000000000000000000000000000}
+      end
+      item
+        Image.Data = {
+          36040000424D3604000000000000360000002800000010000000100000000100
+          2000000000000004000000000000000000000000000000000000000000000000
+          0000000000000000000000000000000000000000000000000000000000000000
+          0000000000000000000000000000000000000000000000000000000000000000
+          0000000000000000000000000000000000000000000000000000000000000000
+          0000000000000000000000000000000000000000000000000000000000000000
+          00000000000007070732212121E11414158A0000000000000000000000000000
+          00001414158A212121E107070732000000000000000000000000000000000000
+          000007070732222222ED252525FF242424F71414158A00000000000000001414
+          158A242424F7252525FF222222ED070707320000000000000000000000000000
+          0000212121E1252525FF252525FF252525FF242424F71414158A1414158A2424
+          24F7252525FF252525FF252525FF212121E10000000000000000000000000000
+          0000171718A1242424F7252525FF252525FF252525FF242424FA242424FA2525
+          25FF252525FF252525FF242424F71414158A0000000000000000000000000000
+          000000000000171718A1242424F7252525FF252525FF252525FF252525FF2525
+          25FF252525FF242424F71414158A000000000000000000000000000000000000
+          00000000000000000000171718A1252525FD252525FF252525FF252525FF2525
+          25FF242424FA1414158A00000000000000000000000000000000000000000000
+          00000000000000000000171718A1242424FB252525FF252525FF252525FF2525
+          25FF242424FA1414158A00000000000000000000000000000000000000000000
+          000000000000171718A1242424F7252525FF252525FF252525FF252525FF2525
+          25FF252525FF242424F71414158A000000000000000000000000000000000000
+          0000171718A1242424F7252525FF252525FF252525FF242424FB242424FA2525
+          25FF252525FF252525FF242424F71414158A0000000000000000000000000000
+          0000222222EC252525FF252525FF252525FF242424F71414158A1414158A2424
+          24F7252525FF252525FF252525FF212121E10000000000000000000000000000
+          000007070732232323F1252525FF242424F71414158A00000000000000001414
+          158A242424F7252525FF222222ED070707320000000000000000000000000000
+          00000000000007070732222222E71414158A0000000000000000000000000000
+          00001414158A212121E107070732000000000000000000000000000000000000
+          0000000000000000000000000000000000000000000000000000000000000000
+          0000000000000000000000000000000000000000000000000000000000000000
+          0000000000000000000000000000000000000000000000000000000000000000
+          0000000000000000000000000000000000000000000000000000}
+      end
+      item
+        Image.Data = {
+          36040000424D3604000000000000360000002800000010000000100000000100
+          2000000000000004000000000000000000000000000000000000000000000000
+          0000000000000000000000000000000000000000000000000000000000000000
+          0000000000000000000000000000000000000000000000000000000000001D1D
+          1DC8252525FF252525FF252525FF252525FF252525FF252525FF252525FF2525
+          25FF252525FF252525FF1D1D1DC8000000000000000000000000000000002525
+          25FF000000000000000000000000000000000000000000000000000000000000
+          00000000000000000000252525FF000000000000000000000000000000002525
+          25FF000000000000000000000000000000000000000000000000000000000000
+          00000000000000000000252525FF000000000000000000000000000000002525
+          25FF0000000000010203005C91A7004973840006090A00000000000000000000
+          00000000000000000000252525FF000000000000000000000000000000002525
+          25FF000000000000000000639CB30071B2CC0069A5BD0056889C00111A1E0000
+          00000000000000000000252525FF000000000000000000000000000000002525
+          25FF0000000000000000004C778900283F49000406070056879B0081CCEA0012
+          1C200000000000000000252525FF000000000000000000000000000000002525
+          25FF000000000000000000253A430067A3BB00324F5B008CDCFD008DDEFF0081
+          CCEA00121C2000000000252525FF000000000000000000000000000000002525
+          25FF000000000000000000000000006FAFC9008DDEFF000F181C00578A9E008D
+          DEFF0081CCEA00121C201D1D1DC8000000000000000000000000000000002525
+          25FF00000000000000000000000000010203006DACC5008DDEFF000C13160057
+          8A9E008DDEFF0081CCEA0918205A000000000000000000000000000000002525
+          25FF0000000000000000000000000000000000010203006DACC5008DDEFF000C
+          13160081CBE9007BC2DF000D1518000C12150000000000000000000000002525
+          25FF000000000000000000000000000000000000000000010203006DACC5008D
+          DEFF007BC1DE00090F11005281940081CCEA00121C2000000000000000002424
+          24F9000000001E1E1ECC000000001C1C1CC1000000001C1C1CC1000000000064
+          9EB5000C121500528194008DDEFF008DDEFF007BC2DF00000000000000000B0B
+          0B4E1C1C1CC1252525FF13131381252525FF13131381252525FF131313810A0A
+          0A420154849A008DDEFF00142025005A8EA30076BAD600000000000000000000
+          0000000000001E1E1ECC000000001C1C1CC1000000001C1C1CC1000000001C1C
+          1CC100000000006EACC7008CDCFD0079BEDA0001020300000000000000000000
+          0000000000000000000000000000000000000000000000000000000000000000
+          0000000000000001020200538397000102020000000000000000}
+      end
+      item
+        Image.Data = {
+          36040000424D3604000000000000360000002800000010000000100000000100
+          2000000000000004000000000000000000000000000000000000000000000000
+          0000000000000000000000000000000000000000000000000000000000000000
+          0000000000000000000000000000000000000000000000000000000000000000
+          0000000000000000000000000000252525FF252525FF252525FF252525FF2525
+          25FF252525FF252525FF252525FF252525FF252525FF00000000000000000000
+          0000000000000000000000000000252525FF0000000000000000000000000000
+          000000000000000000000000000000000000252525FF0000000000000000008D
+          DEFF008DDEFF008DDEFF00476F80252525FF00000000252525FF252525FF2525
+          25FF252525FF252525FF252525FF00000000252525FF0000000000000000008D
+          DEFF000000000000000000000000252525FF0000000000000000000000000000
+          000000000000000000000000000000000000252525FF0000000000000000008D
+          DEFF00000000008DDEFF00476F80252525FF00000000252525FF252525FF2525
+          25FF252525FF252525FF252525FF00000000252525FF0000000000000000008D
+          DEFF000000000000000000000000252525FF0000000000000000000000000000
+          000000000000000000000000000000000000252525FF0000000000000000008D
+          DEFF00000000008DDEFF00476F80252525FF00000000252525FF252525FF2525
+          25FF252525FF252525FF252525FF00000000252525FF0000000000000000008D
+          DEFF000000000000000000000000252525FF0000000000000000000000000000
+          00000000000000000000000000000202020E252525FF0000000000000000008D
+          DEFF00000000008DDEFF00476F80252525FF00000000252525FF252525FF2525
+          25FF00000000252525FF252525FF252525FF232323F30000000000000000008D
+          DEFF000000000000000000000000252525FF0000000000000000000000000000
+          000000000000252525FF05050520202020DF111111760000000000000000008D
+          DEFF00000000008DDEFF00476F80252525FF0000000000000000000000000000
+          00000202020E252525FF202020DF13131380000000000000000000000000008D
+          DEFF000000000000000000000000252525FF252525FF252525FF252525FF2525
+          25FF252525FF232323F31111117600000000000000000000000000000000008D
+          DEFF0000000000000000000000000000000000080C0E00476F8000476F800012
+          1C2000000000000000000000000000000000000000000000000000000000008D
+          DEFF008DDEFF008DDEFF008DDEFF008DDEFF008DDEFF0086D4F3004167760000
+          0000000000000000000000000000000000000000000000000000000000000000
+          0000000000000000000000000000000000000000000000000000000000000000
+          0000000000000000000000000000000000000000000000000000}
+      end>
+  end
 end

+ 298 - 44
src/_frmMain.pas

@@ -12,7 +12,7 @@ uses
   IdTCPConnection, IdTCPClient, IdHTTP, _JSONConfig, dxSkinsdxBarPainter, dxBar,
   cxContainer, cxEdit, cxTextEdit, cxMaskEdit, cxDropDownEdit, Vcl.Menus,
   cxButtons, BCEditor.Editor.Base, BCEditor.Editor, dxSkinscxPCPainter,
-  dxBarBuiltInMenu, cxPC;
+  dxBarBuiltInMenu, cxPC, System.ImageList, Vcl.ImgList;
 
 type
   TfrmMain = class(TForm)
@@ -38,8 +38,7 @@ type
     dxBarSubItem2: TdxBarSubItem;
     tbbtnRun: TdxBarButton;
     Label2: TLabel;
-    cxPopupEdit1: TcxPopupEdit;
-    edtURL: TcxTextEdit;
+    edtFullURL: TcxTextEdit;
     btnRun: TcxButton;
     EditorContent: TBCEditor;
     cxPageControl1: TcxPageControl;
@@ -57,6 +56,26 @@ type
     N1: TMenuItem;
     edtBaseURL: TcxTextEdit;
     Label3: TLabel;
+    btnAdd: TcxButton;
+    cxImageList: TcxImageList;
+    btnDelete: TcxButton;
+    comboPresets: TcxComboBox;
+    Label4: TLabel;
+    btnEdit: TcxButton;
+    btnCopyPreset: TcxButton;
+    Label5: TLabel;
+    EditorURLParams: TBCEditor;
+    Label6: TLabel;
+    comboMethod: TcxComboBox;
+    cxPageControl2: TcxPageControl;
+    cxTabSheet1: TcxTabSheet;
+    cxTabSheet2: TcxTabSheet;
+    Panel3: TPanel;
+    EditorExtraHeaders: TBCEditor;
+    Panel4: TPanel;
+    Label7: TLabel;
+    tabPostData: TcxTabSheet;
+    EditorPostData: TBCEditor;
     procedure FormShow(Sender: TObject);
     procedure FormCreate(Sender: TObject);
     procedure FormDestroy(Sender: TObject);
@@ -73,12 +92,32 @@ type
     procedure Cut1Click(Sender: TObject);
     procedure Paste1Click(Sender: TObject);
     procedure Copy1Click(Sender: TObject);
+    procedure btnAddClick(Sender: TObject);
+    procedure btnDeleteClick(Sender: TObject);
+    procedure comboPresetsPropertiesChange(Sender: TObject);
+    procedure btnSaveClick(Sender: TObject);
+    procedure btnEditClick(Sender: TObject);
+    procedure btnCopyPresetClick(Sender: TObject);
+    procedure edtBaseURLPropertiesChange(Sender: TObject);
+    procedure EditorURLParamsChange(Sender: TObject);
+    procedure comboMethodPropertiesChange(Sender: TObject);
   private
     FMainConfig: TJSONConfig;
+    FProjectConfig: TJSONConfig;
     FActiveProject: string;
+    FActivePreset: string;
+    FIsTempProjectLoaded: Boolean;
+    FTempProjectFile: string;
+    function GetTempProjectFile: string;
+    procedure UpdateFullURL;
     procedure LoadProject;
     procedure SaveProject;
+    procedure SaveProjectAs(const LoadAfterSave: Boolean);
     procedure Run;
+    procedure AddPreset(const APresetName: string);
+    procedure DeletePreset(const AID: Integer);
+    procedure LoadPreset;
+    procedure SavePreset;
   public
     { Public-Deklarationen }
   end;
@@ -90,6 +129,8 @@ implementation
 
 {$R *.dfm}
 
+uses System.Net.URLClient;
+
 procedure TfrmMain.tbbtnRunClick(Sender: TObject);
 begin
   Run;
@@ -107,6 +148,35 @@ begin
   end;
 end;
 
+procedure TfrmMain.UpdateFullURL;
+var
+  i: Integer;
+  dmy: string;
+  strlist: TStringList;
+begin
+  edtFullURL.Text := edtBaseURL.Text;
+  if EditorURLParams.Lines.Count > 0 then
+  begin
+    dmy := '?';
+    for i := 0 to EditorURLParams.Lines.Count - 1 do
+    begin
+      if dmy <> '?' then dmy := dmy + '&';
+      strlist := TStringList.Create;
+      try
+        strlist.Text := StringReplace(EditorURLParams.Lines[i], '=', #13#10, [rfReplaceAll]);
+        if strlist.Count = 2 then
+        begin
+          dmy := dmy + TURI.URLEncode(strlist[0]) + '=' + TURI.URLEncode(strlist[1]);
+        end;
+      finally
+        strlist.Free;
+      end;
+    end;
+
+    edtFullURL.Text := edtFullURL.Text + dmy;
+  end;
+end;
+
 procedure TfrmMain.dxBarButton3Click(Sender: TObject);
 begin
   OpenDialog.InitialDir := FMainConfig.ReadString('Dialogs', 'LastOpenDir', ExtractFilePath(ParamStr(0)));
@@ -114,31 +184,101 @@ begin
   begin
     FMainConfig.WriteString('Dialogs', 'LastOpenDir', ExtractFilePath(OpenDialog.FileName));
     FActiveProject := OpenDialog.FileName;
+    FIsTempProjectLoaded := False;
     LoadProject;
   end;
 end;
 
+procedure TfrmMain.AddPreset(const APresetName: string);
+begin
+  comboPresets.Properties.Items.Add(APresetName);
+  comboPresets.ItemIndex := comboPresets.Properties.Items.Count - 1;
+
+  FProjectConfig.WriteString('Presets', 'Presets', comboPresets.Properties.Items.Text);
+end;
+
+procedure TfrmMain.btnAddClick(Sender: TObject);
+var
+  dmy: string;
+begin
+  if InputQuery('Add Preset', 'Enter a preset name:', dmy) then
+  begin
+    AddPreset(dmy);
+  end;
+end;
+
+procedure TfrmMain.btnDeleteClick(Sender: TObject);
+begin
+  if comboPresets.Properties.Items.Count = 1 then
+  begin
+    MessageDlg('Thet last preset can''t be deleted. Please create a new preset if you want to delete this.', mtError, [mbOK], 0);
+  end
+  else
+  begin
+    if MessageDlg('Preset "' + comboPresets.Text + '" wirklich löschen?', mtConfirmation, [mbYes, mbNo], 0) = mrYes then
+    begin
+      DeletePreset(comboPresets.ItemIndex);
+      FProjectConfig.WriteString('Presets', 'Presets', comboPresets.Properties.Items.Text);
+    end;
+  end;
+end;
+
+procedure TfrmMain.btnEditClick(Sender: TObject);
+var
+  dmy: string;
+  idx: Integer;
+begin
+  dmy := comboPresets.Text;
+  idx := comboPresets.ItemIndex;
+  if InputQuery('Edit Preset', 'Rename preset:', dmy) then
+  begin
+    comboPresets.Properties.Items[comboPresets.ItemIndex] := dmy;
+    comboPresets.ItemIndex := idx;
+
+    FProjectConfig.WriteString('Presets', 'Presets', comboPresets.Properties.Items.Text);
+  end;
+end;
+
+procedure TfrmMain.btnCopyPresetClick(Sender: TObject);
+var
+  idx: Integer;
+begin
+  SavePreset;
+  idx := comboPresets.ItemIndex;
+  AddPreset('Copy of ' + comboPresets.Text);
+  FProjectConfig.CopySection('Preset_' + idx.ToString, 'Preset_' + comboPresets.ItemIndex.ToString);
+  LoadPreset;
+end;
+
 procedure TfrmMain.btnRunClick(Sender: TObject);
 begin
   Run;
 end;
 
 procedure TfrmMain.btnSaveAsClick(Sender: TObject);
-var
-  fname: string;
 begin
-  SaveDialog.InitialDir := FMainConfig.ReadString('Dialogs', 'LastSaveDir', ExtractFilePath(ParamStr(0)));
-  if SaveDialog.Execute then
-  begin
-    fname := SaveDialog.FileName;
-    FMainConfig.WriteString('Dialogs', 'LastSaveDir', ExtractFilePath(fname));
+  SaveProjectAs(True);
+end;
 
-    fname := ChangeFileExt(fname, '');
-    fname := fname + '.rdproj';
+procedure TfrmMain.btnSaveClick(Sender: TObject);
+begin
+  SaveProject;
+end;
 
-    FActiveProject := fname;
-    SaveProject;
+procedure TfrmMain.comboMethodPropertiesChange(Sender: TObject);
+begin
+  tabPostData.TabVisible := comboMethod.ItemIndex = 1;
+end;
+
+procedure TfrmMain.comboPresetsPropertiesChange(Sender: TObject);
+begin
+  if FActivePreset <> '' then
+  begin
+    SavePreset;
   end;
+
+  FActivePreset := comboPresets.Text;
+  LoadPreset;
 end;
 
 procedure TfrmMain.Copy1Click(Sender: TObject);
@@ -151,6 +291,14 @@ begin
   EditorContent.CutToClipboard;
 end;
 
+procedure TfrmMain.DeletePreset(const AID: Integer);
+begin
+  FActivePreset := '';
+  comboPresets.Properties.Items.Delete(AID);
+  FProjectConfig.DeleteSection('Preset_' + AID.ToString);
+  comboPresets.ItemIndex := comboPresets.Properties.Items.Count - 1;
+end;
+
 procedure TfrmMain.dxBarButton6Click(Sender: TObject);
 begin
   Close;
@@ -163,7 +311,17 @@ end;
 
 procedure TfrmMain.dxBarSubItem3Popup(Sender: TObject);
 begin
-  btnSave.Enabled := FActiveProject <> '';
+  btnSave.Enabled := not FIsTempProjectLoaded;
+end;
+
+procedure TfrmMain.EditorURLParamsChange(Sender: TObject);
+begin
+  UpdateFullURL;
+end;
+
+procedure TfrmMain.edtBaseURLPropertiesChange(Sender: TObject);
+begin
+  UpdateFullURL;
 end;
 
 procedure TfrmMain.FormClose(Sender: TObject; var Action: TCloseAction);
@@ -173,25 +331,55 @@ begin
   FMainConfig.WriteInteger('MainWindowPos', 'Width', Width);
   FMainConfig.WriteInteger('MainWindowPos', 'Height', Height);
   FMainConfig.WriteBool('MainWindowPos', 'StayOnTop', FormStyle = fsStayOnTop);
+
+  SavePreset;
+
+  if FProjectConfig.FileModified then
+  begin
+    if MessageDlg('The project file has changed. Do you want to save it?', mtConfirmation, [mbYes, mbNo], 0) = mrYes then
+    begin
+      if FIsTempProjectLoaded then
+      begin
+        SaveProjectAs(False);
+      end
+      else
+      begin
+        SaveProject;
+      end;
+    end;
+  end;
+
+  if FileExists(FTempProjectFile) then
+  begin
+    DeleteFile(FTempProjectFile);
+  end;
 end;
 
 procedure TfrmMain.FormCreate(Sender: TObject);
 begin
   FMainConfig := TJSONConfig.Create(ExtractFilePath(ParamStr(0)) + 'AppConfig.json');
   FActiveProject := '';
+  FActivePreset := '';
 
   EditorContent.Highlighter.LoadFromFile(ExtractFilePath(ParamStr(0)) + 'Highlighters\JSON.json');
 
-
   if ParamStr(1) <> '' then
   begin
     FActiveProject := ParamStr(1);
-    LoadProject;
+    FIsTempProjectLoaded := False;
+  end
+  else
+  begin
+    FActiveProject := GetTempProjectFile;
+    FIsTempProjectLoaded := True;
   end;
+
+  LoadProject;
 end;
 
 procedure TfrmMain.FormDestroy(Sender: TObject);
 begin
+  FProjectConfig.Free;
   FMainConfig.Free;
 end;
 
@@ -204,17 +392,6 @@ procedure TfrmMain.FormShow(Sender: TObject);
 begin
   dxStatusBar.Panels[0].Text := 'Copyright © by Simnet ' + FormatDateTime('yyyy', now);
 
-  if FActiveProject = '' then
-  begin
-    dxStatusBar.Panels[1].Text := 'No project loaded.';
-  end
-  else
-  begin
-    dxStatusBar.Panels[1].Text := 'Loaded project: ' + FActiveProject;
-  end;
-
-
-
   Left := FMainConfig.ReadInteger('MainWindowPos', 'Left', Round((Screen.Width - Width) div 2));
   Top := FMainConfig.ReadInteger('MainWindowPos', 'Top', Round((Screen.Height - Height) div 2));
   Width := FMainConfig.ReadInteger('MainWindowPos', 'Width', 1000);
@@ -234,15 +411,58 @@ begin
   EditorHeaders.Lines.Clear;
 end;
 
-procedure TfrmMain.LoadProject;
+function TfrmMain.GetTempProjectFile: string;
+begin
+  Result := 'c:\temp\temp.rdproj';
+  FTempProjectFile := Result;
+end;
+
+procedure TfrmMain.LoadPreset;
 var
-  conf: TJSONConfig;
+  preset: string;
+  idx: Integer;
+begin
+  idx := comboPresets.Properties.Items.IndexOf(FActivePreset);
+  if idx > -1 then
+  begin
+    preset := 'Preset_' + idx.ToString;
+    edtBaseURL.Text := FProjectConfig.ReadString(preset, 'BaseURL');
+    comboMethod.ItemIndex := FProjectConfig.ReadInteger(preset, 'Method', 0);
+    EditorURLParams.Lines.Text := FProjectConfig.ReadString(preset, 'URLParams');
+    EditorExtraHeaders.Lines.Text := FProjectConfig.ReadString(preset, 'ExtraHeaders');
+    EditorPostData.Lines.Text := FProjectConfig.ReadString(preset, 'PostData');
+    UpdateFullURL;
+  end;
+end;
+
+procedure TfrmMain.LoadProject;
 begin
-  conf := TJSONConfig.Create(FActiveProject);
-  try
+  if FIsTempProjectLoaded then
+  begin
+    dxStatusBar.Panels[1].Text := 'Default project loaded.';
+  end
+  else
+  begin
+    dxStatusBar.Panels[1].Text := 'Loaded project: ' + FActiveProject;
+  end;
 
-  finally
-    conf.Free;
+  if Assigned(FProjectConfig) then
+  begin
+    FProjectConfig.Free;
+  end;
+
+  FProjectConfig := TJSONConfig.Create(FActiveProject, False);
+  FProjectConfig.AutoSave := False;
+  comboPresets.Properties.Items.Text := FProjectConfig.ReadString('Presets', 'Presets');
+  if comboPresets.Properties.Items.Count = 0 then
+  begin
+    // Add default
+    AddPreset('Default');
+    FProjectConfig.Save;
+  end
+  else
+  begin
+    comboPresets.ItemIndex := FProjectConfig.ReadInteger('Presets', 'LastUsed', 0);
   end;
 end;
 
@@ -255,27 +475,61 @@ procedure TfrmMain.Run;
 var
   dmy: string;
 begin
-  dmy := HTTP.Get(edtURL.Text);
+  dmy := HTTP.Get(edtFullURL.Text);
   EditorContent.Lines.Text := dmy;
 
 
   EditorHeaders.Lines.Text := HTTP.Response.RawHeaders.Text;
 end;
 
-procedure TfrmMain.SaveProject;
+procedure TfrmMain.SavePreset;
 var
-  conf: TJSONConfig;
+  preset: string;
+  idx: Integer;
 begin
-  if FileExists(FActiveProject) then
+  idx := comboPresets.Properties.Items.IndexOf(FActivePreset);
+  if idx > -1 then
   begin
-    DeleteFile(FActiveProject);
+    preset := 'Preset_' + idx.ToString;
+    FProjectConfig.WriteString(preset, 'BaseURL', edtBaseURL.Text);
+    FProjectConfig.WriteInteger(preset, 'Method', comboMethod.ItemIndex);
+    FProjectConfig.WriteString(preset, 'URLParams', EditorURLParams.Lines.Text);
+    FProjectConfig.WriteString(preset, 'PostData', EditorPostData.Lines.Text);
+    FProjectConfig.WriteString(preset, 'ExtraHeaders', EditorExtraHeaders.Lines.Text);
+
+
+    FProjectConfig.WriteInteger('Presets', 'LastUsed', idx);
   end;
+end;
 
-  conf := TJSONConfig.Create(FActiveProject, False);
-  try
-    conf.WriteString('Temp', 'BaseURL', edtBaseURL.Text);
-  finally
-    conf.Free;
+procedure TfrmMain.SaveProject;
+begin
+  SavePreset;
+  FProjectConfig.Save;
+end;
+
+procedure TfrmMain.SaveProjectAs(const LoadAfterSave: Boolean);
+var
+  fname: string;
+begin
+  SaveDialog.InitialDir := FMainConfig.ReadString('Dialogs', 'LastSaveDir', ExtractFilePath(ParamStr(0)));
+  if SaveDialog.Execute then
+  begin
+    fname := SaveDialog.FileName;
+    FMainConfig.WriteString('Dialogs', 'LastSaveDir', ExtractFilePath(fname));
+
+    fname := ChangeFileExt(fname, '');
+    fname := fname + '.rdproj';
+
+    SaveProject;
+    CopyFile(PChar(FProjectConfig.FileName), PChar(fname), False);
+
+    if LoadAfterSave then
+    begin
+      FIsTempProjectLoaded := False;
+      FActiveProject := fname;
+      LoadProject;
+    end;
   end;
 end;