1 /*
2  * This file is part of gtkD.
3  *
4  * gtkD is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU Lesser General Public License as published by
6  * the Free Software Foundation; either version 2.1 of the License, or
7  * (at your option) any later version.
8  *
9  * gtkD is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public License
15  * along with gtkD; if not, write to the Free Software
16  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
17  */
18  
19 module ui.Installer;
20 
21 private import ui.Main;
22 private import ui.Exec;
23 private import gtk.GtkD;
24 private import gtk.MainWindow;
25 private import gtk.Widget;
26 private import gtk.ProgressBar;
27 private import gtk.Label;
28 private import gtk.VBox;
29 
30 private import gdk.Gdk;
31 private import gdk.Event;
32 
33 private import compd.Compiler;
34 
35 private import std.stdio;
36 
37 private import std.path;
38 private import std.file;
39 private import std.process;
40 
41 private import std.thread;
42 private import std.c.time;
43 	
44 private import ui.gtkDLogo;
45 private import gtk.Alignment;
46 private import gtk.Button;
47 private import gtkc.gtktypes;
48 
49 /**
50  *
51  */
52 public class  InstallerBox : VBox
53 {
54 	InstallerUI installerUI;
55 	Label label;
56 	ProgressBar progressBar;
57 	
58 	bool cancel = false;
59 	
60 	this(InstallerUI installerUI)
61 	{
62 		super(false, 7);
63 		this.installerUI = installerUI;
64 		setup();
65 		progressBar.setFraction(1.0);
66 		progressBar.setText("");
67 	}
68 
69 	
70 	private void setup()
71 	{
72 		VBox vbox = new VBox(false, 7);
73 		vbox.setBorderWidth(11);
74 		label = new Label("");
75 		
76 		vbox.packStart(Alignment.west(getGtkDLogo()), false, false, 2);
77 		
78 		vbox.packStart(new Label("Installing"), false, false, 14);
79 		vbox.packStart(label, false, false, 14);
80 		progressBar = new ProgressBar();
81 		progressBar.setPulseStep(0.01);
82 		vbox.packStart(progressBar, false, false, 14);
83 		
84 		vbox.packEnd(Alignment.east(new Button(StockID.CANCEL, &cancelInstall)), false, false, 14);
85 		
86 		add(vbox);
87 	}
88 	
89 	private void cancelInstall(Button button)
90 	{
91 		cancel = true;
92 	}
93 	
94 	char[] dmdHome;
95 	char[] gtkDDevHome;
96 	char[] phobos;
97 	char[] compilerExec;
98 
99 	int ccount;
100 		
101 
102 	private void install()
103 	{
104 		bool ok = true;
105 		gtkDDevHome = installerUI.getDirectory("gtkDDevHome");
106 		dmdHome = installerUI.getDirectory("dmdHome");
107 		phobos = std.path.join(std.path.join(dmdHome,"src"),"phobos");
108 		compilerExec = std.path.join(installerUI.getDirectory("dmdHome"),"bin");
109 		version(Win32)
110 		{
111 			compilerExec = std.path.join(compilerExec,"dmd.exe");
112 		}
113 		else
114 		{
115 			compilerExec = std.path.join(compilerExec,"dmd");
116 		}
117 		
118 //		if ( ok && installerUI.getSelection("gtkD") )
119 //		{
120 //			label.setText("");
121 //			Gdk.flush();
122 //			ok = installGtkD();
123 //		}
124 
125 
126 		
127 		class CompileThread : Thread
128 		{
129 			bool delegate() compile;
130 			bool ok;
131 			
132 			this(char[] stepLabel, bool delegate() compile)
133 			{
134 				super(&run);
135 				this.compile = compile;
136 				label.setText(stepLabel);
137 				progressBar.setText(stepLabel);
138 				go();
139 				//ok = compile();
140 			}
141 			
142 			private void go()
143 			{
144 			std.gc.fullCollect();
145 				start();
146 				while ( !cancel && getState() != Thread.TS.TERMINATED )
147 				{
148 					progressBar.pulse();
149 					while ( GtkD.eventsPending() )
150 					{
151 						GtkD.mainIterationDo(false);
152 					}
153 					std.c.time.usleep(10000);
154 				}
155 			}
156 			
157 			int run()
158 			{
159 				ok = compile();
160 				return ok;
161 			}
162 			
163 		}
164 		
165 		if ( !cancel && ok && installerUI.getSelection("gtkDDev") )
166 		{
167 			ok = (new CompileThread("GtkD Development", &installGtkDDev)).ok;
168 		}
169 
170 //		if ( ok && installerUI.getSelection("gtkDgl") )
171 //		{
172 //			label.setText("GtkDgl - openGL bindings");
173 //			Gdk.flush();
174 //			ok = installGtkDgl();
175 //		}
176 
177 		if ( !cancel && ok && installerUI.getSelection("duiglDev") )
178 		{
179 			ok = (new CompileThread("GtkDgl Development", &installGtkDglDev)).ok;
180 		}
181 
182 //		if ( !cancel && ok && installerUI.getSelection("leds") )
183 //		{
184 //			label.setText("leds");
185 //			Gdk.flush();
186 //			ok = installLeds();
187 //		}
188 //
189 //		if ( !cancel && ok && installerUI.getSelection("gtkDdi") )
190 //		{
191 //			label.setText("GtkD .di files");
192 //			Gdk.flush();
193 //			ok = installGtkDdi();
194 //		}
195 //
196 //		if ( !cancel && ok && installerUI.getSelection("gtkDSource") )
197 //		{
198 //			label.setText("GtkD source files");
199 //			Gdk.flush();
200 //			ok = installGtkDSource();
201 //		}
202 //
203 		if ( !cancel && ok && installerUI.getSelection("gtkDTests") )
204 		{
205 			ok = (new CompileThread("GtkD Test and demo programs", &installGtkDTests)).ok;
206 		}
207 		
208 		if ( !cancel && ok && installerUI.getSelection("gtkDglSimple") )
209 		{
210 			ok = (new CompileThread("GtkDgl SimpleGL demo program", &installGtkDglSimpleGL)).ok;
211 		}
212 
213 		if ( !cancel && ok && installerUI.getSelection("gtkDglShapes") )
214 		{
215 			ok = (new CompileThread("GtkDgl ShapeGL and demo program", &installGtkDglShapesGL)).ok;
216 		}
217 
218 //		if ( !cancel && ok && installerUI.getSelection("ledsGtkD") )
219 //		{
220 //			label.setText("Leds project for GtkD");
221 //			Gdk.flush();
222 //			ok = installLedsGtkD();
223 //		}
224 //
225 //		if ( !cancel && ok && installerUI.getSelection("ledsLeds") )
226 //		{
227 //			label.setText("Leds project for leds");
228 //			Gdk.flush();
229 //			ok = installLedsLeds();
230 //		}
231 //
232 //		if ( !cancel && ok && installerUI.getSelection("ledsDool") )
233 //		{
234 //			label.setText("Leds project for Dool");
235 //			Gdk.flush();
236 //			ok = installLedsDool();
237 //		}
238 //
239 //		if ( !cancel && ok && installerUI.getSelection("ledsDante") )
240 //		{
241 //			label.setText("Leds project for Dante");
242 //			Gdk.flush();
243 //			ok = installLedsDante();
244 //		}
245 //
246 //		if ( !cancel && ok && installerUI.getSelection("ledsPhobos") )
247 //		{
248 //			label.setText("Leds project for phobos");
249 //			Gdk.flush();
250 //			ok = installLedsPhobos();
251 //		}
252 
253 	}
254 	
255 	
256 	private bool makeDirs(char[] dir)
257 	{
258 		bool ok = false;
259 		version(Win32)
260 		{
261 			system("md "~dir);
262 		}
263 		else
264 		{
265 			system("mkdir -p "~dir);
266 		}
267 		try
268 		{
269 			std.file.isdir(dir);
270 			ok = true;
271 		}
272 		catch ( FileException fe )
273 		{
274 			
275 		}
276 		return ok;
277 	}
278 	
279 	private bool installGtkDglSimpleGL()
280 	{
281 		bool ok = moveGtkDDev();
282 		if ( ok )
283 		{
284 			char[] cwd = std.file.getcwd();
285 			Compiler compiler;
286 			std.file.chdir(gtkDDevHome);
287 			
288 			compiler = new Compiler();
289 			compiler.setExecutor(new Exec());
290 			compiler.setCompilerExec(compilerExec);
291 			
292 			compiler.addArg("-Isrc");
293 			compiler.addArg("-Isrcgl");
294 			compiler.addArg("-Idemos");
295 			compiler.addArg("demos/gl/SimpleGL.d");
296 			compiler.addArg("-I"~phobos);
297 			compiler.addArg("-L"~std.path.join(dmdHome,"lib"));
298 			compiler.addArg("-o SimpleGL");
299 			compiler.addArg("-L .");
300 			compiler.addArg("-lgtkD");
301 			compiler.addArg("-lgtkDgl");
302 			compiler.addArg("-lGL");
303 			compiler.addArg("-lGLU");
304 			version(linux)compiler.addArg("-ldl");
305 			
306 			compiler.addArg("-c");
307 			compiler.addArg("-op");
308 			
309 			version(Win32)
310 			{
311 				compiler.addArg("-lkernel32");
312 				compiler.addArg("-luser32");
313 			}
314 			else
315 			{
316 				compiler.addArg("-lpthread");
317 				compiler.addArg("-lm");
318 			}
319 			compiler.compile();
320 			if ( compiler.compileStatus == 0 
321 				&& compiler.linkStatus == 0
322 				)
323 			{
324 				ok = true;
325 			}
326 			else
327 			{
328 				ok = false;
329 			}
330 			
331 			std.file.chdir(cwd);
332 		}
333 		return ok;
334 	}
335 
336 	private bool installGtkDglShapesGL()
337 	{
338 		bool ok = moveGtkDDev();
339 		if ( ok )
340 		{
341 			char[] cwd = std.file.getcwd();
342 			Compiler compiler;
343 			std.file.chdir(gtkDDevHome);
344 			
345 			compiler = new Compiler();
346 			compiler.setExecutor(new Exec());
347 			compiler.setCompilerExec(compilerExec);
348 			
349 			compiler.addArg("-Isrc");
350 			compiler.addArg("-Isrcgl");
351 			compiler.addArg("demos/gl/TrackBall.d");
352 			compiler.addArg("demos/gl/ShapesGL.d");
353 			compiler.addArg("-I"~phobos);
354 			compiler.addArg("-L"~std.path.join(dmdHome,"lib"));
355 			compiler.addArg("-o ShapesGL");
356 			compiler.addArg("-L .");
357 			compiler.addArg("-lgtkD");
358 			compiler.addArg("-lgtkDgl");
359 			compiler.addArg("-lGL");
360 			compiler.addArg("-lGLU");
361 			version(linux)compiler.addArg("-ldl");
362 			
363 			compiler.addArg("-c");
364 			compiler.addArg("-op");
365 			
366 			version(Win32)
367 			{
368 				compiler.addArg("-lkernel32");
369 				compiler.addArg("-luser32");
370 			}
371 			else
372 			{
373 				compiler.addArg("-lpthread");
374 				compiler.addArg("-lm");
375 			}
376 			compiler.compile();
377 			if ( compiler.compileStatus == 0 
378 				&& compiler.linkStatus == 0
379 				)
380 			{
381 				ok = true;
382 			}
383 			else
384 			{
385 				ok = false;
386 			}
387 			
388 			std.file.chdir(cwd);
389 		}
390 		return ok;
391 	}
392 
393 	private bool installGtkDglDev()
394 	{
395 		bool ok = true;
396 		
397 		Compiler compiler;
398 		
399 		char[] cwd = std.file.getcwd();
400 		
401 		
402 		
403 		version(Win32)
404 		{
405 			char[] libGtkDgl = "gtkDgl";
406 		}
407 		else
408 		{
409 			char[] libGtkDgl = "libgtkDgl";
410 		}
411 		
412 		
413 		
414 		ok = moveGtkDDev();
415 		if ( ok )
416 		{
417 			std.file.chdir(gtkDDevHome);
418 			compiler = new Compiler();
419 			compiler.setExecutor(new Exec());
420 			compiler.setCompilerExec(compilerExec);
421 			
422 			compiler.addArg("-Isrc");
423 			compiler.addArg("-Isrcgl");
424 			compiler.addArg("srcgl/glgdk");
425 			compiler.addArg("srcgl/glgtk");
426 			compiler.addArg("srcgl/lib");
427 			compiler.addArg("-I"~phobos);
428 			compiler.addArg("-L"~std.path.join(dmdHome,"lib"));
429 			compiler.addArg("-olib "~libGtkDgl);
430 			compiler.addArg("-L. ");
431 			compiler.addArg("-lgtkD ");
432 			compiler.addArg("-c");
433 			compiler.addArg("-op");
434 			
435 			version(Win32)
436 			{
437 				compiler.addArg("-lkernel32");
438 				compiler.addArg("-luser32");
439 				compiler.addArg("-ladvapi32");
440 			}
441 			else
442 			{
443 				compiler.addArg("-lpthread");
444 				compiler.addArg("-lm");
445 			}
446 			compiler.compile();
447 			if ( compiler.compileStatus == 0 
448 				&& compiler.linkStatus == 0
449 				)
450 			{
451 				ok = true;
452 			}
453 			else
454 			{
455 				ok = false;
456 			}
457 			
458 			std.file.chdir(cwd);
459 		}
460 		return ok;
461 	}
462 
463 	
464 	private bool installGtkDTests()
465 	{
466 		bool ok = moveGtkDDev();
467 		if ( ok )
468 		{
469 			char[] cwd = std.file.getcwd();
470 			Compiler compiler;
471 			std.file.chdir(gtkDDevHome);
472 			
473 			compiler = new Compiler();
474 			compiler.setExecutor(new Exec());
475 			compiler.setCompilerExec(compilerExec);
476 			
477 			compiler.addArg("-Isrc");
478 			compiler.addArg("-Idemos");
479 			compiler.addArg("demos/gtkD");
480 			compiler.addArg("-I"~phobos);
481 			compiler.addArg("-L"~std.path.join(dmdHome,"lib"));
482 			compiler.addArg("-o GtkDTests");
483 			compiler.addArg("-L .");
484 			compiler.addArg("-lgtkD");
485 			version(linux)compiler.addArg("-ldl");
486 			
487 			compiler.addArg("-c");
488 			compiler.addArg("-op");
489 			
490 			version(Win32)
491 			{
492 				compiler.addArg("-lkernel32");
493 				compiler.addArg("-luser32");
494 			}
495 			else
496 			{
497 				compiler.addArg("-lpthread");
498 				compiler.addArg("-lm");
499 			}
500 			compiler.compile();
501 			if ( compiler.compileStatus == 0 
502 				&& compiler.linkStatus == 0
503 				)
504 			{
505 				ok = true;
506 			}
507 			else
508 			{
509 				ok = false;
510 			}
511 			
512 			std.file.chdir(cwd);
513 		}
514 		return ok;
515 	}
516 
517 	private bool movePackToDestiny(char[] from, char[] to)
518 	{
519 		int ok;
520 		version(Win32)
521 		{
522 			 ok = system("xcopy /s /Y /E /Q "~from~" "~to);
523 		}
524 		else
525 		{
526 			ok = system("cp -R "~from~" "~to);
527 		}
528 		return ok == 0;
529 	}
530 
531 	bool gtkDDevMoved;
532 	
533 	private bool moveGtkDDev()
534 	{
535 		if ( !gtkDDevMoved )
536 		{
537 			if ( makeDirs(gtkDDevHome) )
538 			{
539 				gtkDDevMoved = movePackToDestiny("*", gtkDDevHome);
540 			}
541 		}
542 		return gtkDDevMoved;
543 	}
544 	
545 //	private bool installGtkD()
546 //	{
547 //		// nothing
548 //		return true;
549 //	}
550 	
551 	private bool installGtkDDev()
552 	{
553 		bool ok = true;
554 		
555 		Compiler compiler;
556 		
557 		char[] cwd = std.file.getcwd();
558 		
559 		
560 		
561 		version(Win32)
562 		{
563 			char[] libGtkD = "gtkD";
564 		}
565 		else
566 		{
567 			char[] libGtkD = "libgtkD";
568 		}
569 		
570 		
571 		ok = moveGtkDDev();
572 		if ( ok )
573 		{
574 			std.file.chdir(gtkDDevHome);
575 			compiler = new Compiler();
576 			compiler.setExecutor(new Exec());
577 			
578 			compiler.setCompilerExec(compilerExec);
579 			
580 			compiler.addArg("-Isrc");
581 			compiler.addArg("src/atk");
582 			compiler.addArg("src/cairoLib");
583 			compiler.addArg("src/gdk");
584 			compiler.addArg("src/glib");
585 			compiler.addArg("src/gobject");
586 			compiler.addArg("src/gthread");
587 			compiler.addArg("src/gtk");
588 			compiler.addArg("src/lib");
589 			compiler.addArg("src/pango");
590 			compiler.addArg("-I"~phobos);
591 			compiler.addArg("-L"~std.path.join(dmdHome,"lib"));
592 			compiler.addArg("-olib "~libGtkD);
593 			compiler.addArg("-c");
594 			compiler.addArg("-op");
595 			
596 			version(Win32)
597 			{
598 				compiler.addArg("-lkernel32");
599 				compiler.addArg("-luser32");
600 			}
601 			else
602 			{
603 				compiler.addArg("-lpthread");
604 				compiler.addArg("-lm");
605 			}
606 			compiler.compile();
607 			if ( compiler.compileStatus == 0 
608 				&& compiler.linkStatus == 0
609 				)
610 			{
611 				ok = true;
612 			}
613 			else
614 			{
615 				ok = false;
616 			}
617 			
618 			std.file.chdir(cwd);
619 		}
620 		return ok;
621 	}
622 
623 }
624 
625 
626 /**
627  * From the information collected from the UI this will install GtkD, GtkDgl and or leds
628  */
629 class Installer : MainWindow
630 {
631 	InstallerBox installerBox;
632 	
633 	this(InstallerUI installerUI)
634 	{
635 		super("Installing GtkD components");
636 		setDefaultSize(400,300);
637 		installerBox = new InstallerBox(installerUI);
638 		add(installerBox);
639 		showAll();
640 		installerBox.install();
641 		windowDelete(null, this);
642 		destroy();
643 	}
644 
645 	protected int windowDelete(Event event, Widget widget)
646 	{
647 		installerBox.cancel = true;
648 		mainInstaller.show();
649 		return super.windowDelete(event, widget);
650 	}
651 	
652 }