WineLauncher: Fixed an error in the license headers.
[WineLauncher.git] / Functions / MainBackend / UnitMainBackend.pas
blobecba718928e70716be979f7bff1327b58c84bb15
1 { This file is part of WineLauncher.
3 WineLauncher is free software: you can redistribute it and/or modify
4 it under the terms of the GNU General Public License as published by
5 the Free Software Foundation, either version 3 of the License, or
6 (at your option) any later version.
8 WineLauncher is distributed in the hope that it will be useful,
9 but WITHOUT ANY WARRANTY; without even the implied warranty of
10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 GNU General Public License for more details.
13 You should have received a copy of the GNU General Public License
14 along with WineLauncher. If not, see <http://www.gnu.org/licenses/>.
17 unit UnitMainBackend;
19 {$mode objfpc}{$H+}
21 interface
23 uses
24 Classes, SysUtils, XMLCfg, Process, BaseUnix, ComCtrls, Forms, Controls;
26 procedure SaveLastUsedConfig();
27 procedure LoadLastUsedConfig();
28 procedure OnWineVersionChange();
30 function RunWineCheck(ProgramNameOverRide:string; ProgramFlagsOverRide:string):boolean;
31 function ListProgramsOnDisc(ModeMe:TStrings; DriveChar:char):boolean;
32 function AddTabToPageControl(PageControl:TPageControl; caption:string):boolean;
33 function EmbedFrame(frame:TFrame; PageNumber:integer):boolean;
35 var
36 XmlLastUsedConfig:TXMLConfig;
37 LastUsedConfigLoading:boolean;
39 {The next three are used by ListProgramsOnDisc.}
40 LastReadLinkPath:string;
41 DiscErrorText:string;
42 OldPath:string;
44 implementation
45 uses
46 UnitInitialization,
47 UnitMain,
48 UnitMisc,
49 UnitSettings,
50 UnitProgramsList;
52 procedure SaveLastUsedConfig();
53 begin
54 if LastUsedConfigLoading = true then exit;
55 Try
56 {1}
57 XmlLastUsedConfig.SetValue('Version', '2');
58 {Was WineVersionInfo/DistributionName,DistributionVersion,Architecture.}
59 XmlLastUsedConfig.SetValue('WineVersionInfo/WineVersion', UnitMain.form1.ComboBox_WineVersion.Text);
60 {2}
61 XmlLastUsedConfig.SetValue('WineVersionInfo/UsesTerminal', UnitMain.form1.Check_Terminal.Checked);
62 XmlLastUsedConfig.SetValue('WineVersionInfo/UsesSoundWrapper', UnitMain.form1.CheckBox_UseSoundWrapper.Checked);
64 {Save}
65 XmlLastUsedConfig.Filename := (ConfigPath + '/LastUsedConfig.xml');
66 Finally
67 {Clean up}
68 XmlLastUsedConfig.Flush;
69 end;
70 end;
72 procedure LoadLastUsedConfig();
73 var
74 LastUsedConfigVersion:string;
75 begin
76 {Only run this ones wine has being scanned for.}
77 LastUsedConfigLoading := true;
78 XmlLastUsedConfig:= TXMLConfig.Create(nil);
80 Try
81 XmlLastUsedConfig.Filename := (ConfigPath + '/LastUsedConfig.xml');
82 {Get the version of the config file.}
83 LastUsedConfigVersion := XmlLastUsedConfig.GetValue('Version','');
84 {$IFDEF LogVar}
85 LogVar(LastUsedConfigVersion,'LastUsedConfigVersion');
86 {$ENDIF}
88 {Make sure the version value exists.}
89 if LastUsedConfigVersion = '-1' then
90 begin
91 Log(3, Channel, 'Invalided file version, never mind we ignore it and wirte over it.');
92 Exit();
93 end;
94 {1}
95 {Setting ItemIndex does not trigger OnEditingDone.}
96 {So we run Enter to update the list then we run EditingDone to check it}
98 SelectItem(UnitMain.form1.ComboBox_WineVersion, XmlLastUsedConfig.GetValue('WineVersionInfo/WineVersion', ''));
99 UnitMain.form1.ComboBox_WineVersionEnter(form1);
100 UnitMain.form1.ComboBox_WineVersionEditingDone(form1);
103 UnitMain.form1.Check_Terminal.Checked := XmlLastUsedConfig.GetValue('WineVersionInfo/UsesTerminal', false);
104 UnitMain.form1.CheckBox_UseSoundWrapper.Checked := XmlLastUsedConfig.GetValue('WineVersionInfo/UsesSoundWrapper', false);
106 Finally
107 XmlLastUsedConfig.Flush;
108 LastUsedConfigLoading := false;
109 end;
110 end;
112 function RunWineCheck(ProgramNameOverRide:string; ProgramFlagsOverRide:string):boolean;
114 loop:integer;
115 SoundWrapper:string;
116 temp00:integer;
117 WinePreFixRaw:string;
118 WinePreFix:string;
119 ChannelLocal:string;
120 ProgramFlags:string;
121 ProgramName:string;
122 WorkDir:string;
123 UnixPathWithOutFile:string;
124 WinePath:string; {~/.local/wine/[Wine Version]"}
125 begin
126 ChannelLocal := ('RunWineCheck');
128 WinePath := (PathToWine + UnitMain.form1.ComboBox_WineVersion.Text);
130 {Get wine version info}
131 wine_version_full := FindWine(WinePath);
132 if wine_version_full = '' then exit(false);
135 {Get Terminal info}
136 if UnitMain.form1.Check_Terminal.Checked = true then
137 begin
138 if UnitMain.form1.ComboBox_TerminalName.Text <> '' then
139 begin
140 temp00 := UnitMain.form1.ComboBox_TerminalName.ItemIndex;
141 RunIn := (UnitSettings.Form4.StringGrid_TerminalSettings.Cells[1,temp00] + ' ' + UnitSettings.Form4.StringGrid_TerminalSettings.Cells[2,temp00]);
142 Log(0, ChannelLocal, ('Using Terminal' + Wrap(RunIn)) );
143 end;
145 else
146 begin
147 {After the Program is closed the child process is still listed.}
148 RunIn := UnitSettings.Form4.ComboBox_ShellPath.text;
149 Log(0, ChannelLocal, ('Using' + Wrap(RunIn)) );
150 end;
152 {PreFix}
153 WinePreFixRaw := (PreFixList[1].Strings[UnitMain.form1.ComboBox_PreFix.ItemIndex]);
154 WinePreFix := ('env WINEPREFIX="' + WinePreFixRaw + '"');
155 {$IFDEF LogVar}
156 LogVar(WinePreFix, 'WinePreFix');
157 {$ENDIF}
160 {Sound Wrapper}
161 if UnitMain.form1.CheckBox_UseSoundWrapper.Checked = true then
162 begin
163 if FileExists(UnitMain.form1.ComboBox_SoundWrapper.Text) = true then
164 begin
165 SoundWrapper := (UnitMain.form1.ComboBox_SoundWrapper.Text + ' ');
166 Log(0, ChannelLocal, ('File' + Wrap(UnitMain.form1.ComboBox_SoundWrapper.Text) + 'exists'));
168 else
169 begin
170 Log(1, ChannelLocal, ('File' + Wrap(UnitMain.form1.ComboBox_SoundWrapper.Text) + 'does not exists'));
171 exit(false);
172 end;
174 else
175 begin
176 Log(0, ChannelLocal, ('No sound wrapper will be used'));
177 end;
179 {Set program flags}
180 if ProgramNameOverRide = '' then
181 begin
182 if UnitMain.form1.EditBox_ProgramPath.Text <> '' then
183 begin
184 ProgramFlags := '';
185 for loop := 0 to (UnitMain.form1.CheckListBox_Flags.Items.Count) do
186 begin
187 if UnitMain.form1.CheckListBox_Flags.Checked[loop] = true then
188 begin
189 ProgramFlags := (ProgramFlags + ' ' + UnitMain.form1.CheckListBox_Flags.Items.ValueFromIndex[loop]);
190 end;
191 end;
192 {$IFDEF LogVar}
193 LogVar(ProgramFlags, 'ProgramFlags' );
194 {$ENDIF}
195 ProgramName := (' ' + '"' + UnitMain.form1.EditBox_ProgramPath.Text + '"' + ProgramFlags + ' ');
197 else
198 begin
199 Log(1, ChannelLocal, ('Please select a program.'));
200 exit(false);
201 end;
203 else
204 begin
205 ProgramName := (' ' + '"' + ProgramNameOverRide + '"' + ProgramFlagsOverRide + ' ');
206 end;
208 {Set the WorkDir}
209 UnixPathWithOutFile := ExtractFilePath(WinToUnixPath(UnitMain.form1.EditBox_ProgramPath.Text));
210 if ProgramNameOverRide = '' then
211 begin
212 if DoesFolderExists(ExtractFilePath(UnixPathWithOutFile), ExtractFileName(UnixPathWithOutFile)) then
213 begin
214 WorkDir := WorkDirTemplate(GetUnixDirPath(WinToUnixPath(UnitMain.form1.EditBox_ProgramPath.Text)) );
216 else
217 begin
218 WorkDir := WorkDirTemplate(WinePreFixRaw + '/dosdevices/c:/windows');
219 end;
221 else
222 begin
223 WorkDir := WorkDirTemplate(WinePreFixRaw + '/dosdevices/c:/windows');
224 end;
226 {Setup start_S1}
227 start_S1 := ('#! /bin/sh' + {linebrake}#10 + WorkDir {Line brake done in template.} + WinePreFix + SoundWrapper + ' "' + wine_version_full + '" ' + ProgramName + ';');
228 {$IFDEF LogVar}
229 LogVar(start_S1, 'start_S1');
230 {$ENDIF}
232 {Create Script file}
233 if MakeFile((ConfigPath + '/1'), start_S1) = false then
234 begin
235 log(1, ChannelLocal, ('Can not make file' + wrap(ConfigPath + '/1')) );
236 exit(false);
237 end;
239 {Set executable flag}
240 if SetExecutableFlag(ConfigPath + '/1') = false then
241 begin
242 log(1, ChannelLocal, ('Can not set executable flag on file'+ wrap(ConfigPath + '/1')) );
243 exit(false)
244 end;
246 {Execute script one}
247 Log(0, ChannelLocal, ('Script One has being executed.'));
248 AProcess.CommandLine := (RunIn + ' ' + ConfigPath +'/1');
249 {After the Program is closed the child process is still listed.}
250 AProcess.Execute;
251 Result := true;
252 end;
254 function ListProgramsOnDisc(ModeMe:TStrings; DriveChar:char):boolean;
256 script:string;
257 Path:string;
258 Info:TSearchRec;
259 Count:Longint;
260 FindPath:string;
261 begin
262 {TODO : This function needs to check the drive not just the folders.}
263 Path := (PathToPrefix + UnitMain.Form1.ComboBox_PreFix.Text + '/dosdevices/' + AnsiLowerCase(DriveChar));
265 {Do not rescan if the path is the same as the last one.}
266 {Note if you change disks it will not rescan it.}
267 if OldPath = Path then exit(false);
269 if AsyncProcessScan.Active = false then
270 begin
271 OldPath := Path;
272 ModeMe.Clear;
273 LastReadLinkPath := fpReadLink(Path + ':');
275 else exit(false);
277 if LastReadLinkPath = '' then
278 begin
279 log(4, '',('Link ' + Wrap(Path + ':') + 'does not exists.'));
280 LastReadLinkPath := '';
281 DiscErrorText := 'Please map' + wrap(DriveChar + ':') + 'to your cd / dvd drive, You can do that in winecfg.';
282 exit(false);
283 end;
285 {Reset count.}
286 Count := 0;
287 if FindFirst((Path + ':/*'), faAnyFile and faDirectory, Info) = 0 then
288 begin
289 Repeat
290 Inc(Count);
291 Until FindNext(info) <> 0;
292 if Count < 3 then
293 begin
294 log(0,'', Info.Name);
295 DiscErrorText := 'You have no disc in your drive.';
296 LastReadLinkPath := '';
297 exit(false);
298 end;
299 end;
300 FindClose(Info);
302 if LastReadLinkPath = '/' then
303 begin
304 DiscErrorText := 'You can not map '+ DriveChar + ': to root.';
305 LastReadLinkPath := '';
306 exit(false);
307 end;
309 if LastReadLinkPath = GetEnvironmentVariable('HOME') then
310 begin
311 DiscErrorText := 'You can not map '+ DriveChar + ': to your home folder.';
312 LastReadLinkPath := '';
313 exit(false);
314 end;
316 FindPath := SearchForBin('find');
317 if FindPath = '' then
318 begin
319 DiscErrorText := ('Can not find the program called' + Wrap('find'));
320 LastReadLinkPath := '';
321 exit(false);
322 end;
324 script := (FindPath + ' -H ' + Path + ': -iname *.exe');
325 Log(0, '', 'Script Scan has being executed.');
326 AsyncProcessScan.CommandLine := script;
327 AsyncProcessScan.Execute;
328 DiscErrorText := 'Scaning';
329 Timer.Enabled := true;
331 Result := true;
333 end;
335 procedure OnWineVersionChange();
336 begin
337 if UnitMain.form1.ComboBox_WineVersion.Text <> '' then
338 begin
339 UnitMain.form1.Btn_Run.Enabled := true;
341 else
342 UnitMain.form1.Btn_Run.Enabled := false;
343 end;
345 function AddTabToPageControl(PageControl:TPageControl; caption:string):boolean;
347 Index:Integer;
348 begin
349 Index := PageControl.PageCount ;
350 SetLength(TabSheets, (Index + 1));
352 {Make tab sheet.}
353 TabSheets[Index] := TTabSheet.Create(TabSheets[Index]);
354 TabSheets[Index].Caption := caption;
355 TabSheets[Index].PageControl := PageControl;
356 end;
358 function EmbedFrame(frame:TFrame; PageNumber:integer):boolean;
359 begin
360 frame.Parent := UnitMain.form1.PageControl1.Page[PageNumber];
361 frame.Align := (alclient);
362 frame.Show;
363 end;
365 end.