1 /****************************************************************************
2 **
3 ** Copyright (C) 2008-2010 Andrey Rijov <ANDron142@yandex.ru>
4 ** COpyirght (C) 2016 Tobias Gläßer
5 **
6 ** This file is part of AQEMU.
7 **
8 ** This program is free software; you can redistribute it and/or modify
9 ** it under the terms of the GNU General Public License as published by
10 ** the Free Software Foundation; either version 2 of the License.
11 **
12 ** This program is distributed in the hope that it will be useful,
13 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
14 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 ** GNU General Public License for more details.
16 **
17 ** You should have received a copy of the GNU General Public License
18 ** along with this program; if not, write to the Free Software
19 ** Foundation, Inc., 51 Franklin Street, Fifth Floor,
20 ** Boston, MA  02110-1301, USA.
21 **
22 ****************************************************************************/
23 
24 #include <QDir>
25 #include <QRegExp>
26 #include <QFileDialog>
27 
28 #include "Utils.h"
29 #include "VM_Wizard_Window.h"
30 #include "System_Info.h"
31 
32 #include <sys/utsname.h>
33 #include <stdio.h>
34 
35 // FIXME this may be Linux only so far
36 // if you're porting this to something else
37 // this is a place where a lot of ifdefs may be needed
Get_My_System_Architecture()38 QString Get_My_System_Architecture()
39 {
40     struct utsname name;
41     uname(&name);
42     return QString(name.machine);
43 }
44 
VM_Wizard_Window(QWidget * parent)45 VM_Wizard_Window::VM_Wizard_Window( QWidget *parent )
46 	: QDialog(parent)
47 {
48 	ui.setupUi( this );
49 	ui.Label_Page->setBackgroundRole( QPalette::Base );
50     ui.Wizard_Pages->setCurrentIndex(0);
51 
52 	New_VM = new Virtual_Machine();
53 
54 	// Loadind All Templates
55 	if( Load_OS_Templates() )
56 	{
57 		// Find default template
58 		for( int ix = 0; ix < ui.CB_OS_Type->count(); ++ix )
59 		{
60 			if( ui.CB_OS_Type->itemText(ix) == Settings.value("Default_VM_Template", "Linux 2.6").toString() )
61 				ui.CB_OS_Type->setCurrentIndex( ix );
62 		}
63 	}
64 	else
65 	{
66 		AQWarning( "void VM_Wizard_Window::on_Button_Next_clicked()",
67 				   "No VM Templates Found!" );
68 	}
69 
70     connect(ui.RB_Emulator_KVM, SIGNAL(toggled(bool)),this, SLOT(on_KVM_toggled(bool)));
71 }
72 
on_KVM_toggled(bool toggled)73 void VM_Wizard_Window::on_KVM_toggled(bool toggled)
74 {
75     if ( toggled )
76         ui.toolBox_accelInfo->setCurrentIndex(1);
77     else
78         ui.toolBox_accelInfo->setCurrentIndex(0);
79 }
80 
Set_VM_List(QList<Virtual_Machine * > * list)81 void VM_Wizard_Window::Set_VM_List( QList<Virtual_Machine*> *list )
82 {
83 	VM_List = list;
84 }
85 
on_Button_Back_clicked()86 void VM_Wizard_Window::on_Button_Back_clicked()
87 {
88 	ui.Button_Next->setEnabled( true );
89 
90 	if( ui.Wizard_Mode_Page == ui.Wizard_Pages->currentWidget() )
91 	{
92 		//ui.Wizard_Pages->setCurrentWidget( ui.Welcome_Page );
93 		//ui.Label_Page->setText( tr("New Virtual Machine Wizard") );
94 	}
95 	else if( ui.Template_Page == ui.Wizard_Pages->currentWidget() )
96 	{
97 		ui.Wizard_Pages->setCurrentWidget( ui.Wizard_Mode_Page );
98 		ui.Label_Page->setText( tr("Wizard Mode") );
99 	    ui.Button_Back->setEnabled( false );
100 	}
101 	else if( ui.Accelerator_Page == ui.Wizard_Pages->currentWidget() )
102 	{
103 		ui.Wizard_Pages->setCurrentWidget( ui.Template_Page );
104 		ui.Label_Page->setText( tr("VM Hardware Template") );
105 	}
106 	else if( ui.General_Settings_Page == ui.Wizard_Pages->currentWidget() )
107 	{
108 		ui.Wizard_Pages->setCurrentWidget( ui.Accelerator_Page );
109 		ui.Label_Page->setText( tr("Accelerator") );
110 	}
111 	else if( ui.Memory_Page == ui.Wizard_Pages->currentWidget() )
112 	{
113 		ui.Wizard_Pages->setCurrentWidget( ui.General_Settings_Page );
114 		ui.Label_Page->setText( tr("VM Name and CPU Type") );
115 		ui.Label_Caption_CPU_Type->setVisible( true );
116 		ui.Line_CPU_Type->setVisible( true );
117 		ui.Label_CPU_Type->setVisible( true );
118 		ui.CB_CPU_Type->setVisible( true );
119 	}
120 	else if( ui.Typical_HDD_Page == ui.Wizard_Pages->currentWidget() )
121 	{
122 		ui.Wizard_Pages->setCurrentWidget( ui.General_Settings_Page );
123 		ui.Label_Page->setText( tr("Virtual Machine Name") );
124 		ui.Label_Caption_CPU_Type->setVisible( false );
125 		ui.Line_CPU_Type->setVisible( false );
126 		ui.Label_CPU_Type->setVisible( false );
127 		ui.CB_CPU_Type->setVisible( false );
128 	}
129 	else if( ui.Custom_HDD_Page == ui.Wizard_Pages->currentWidget() )
130 	{
131 		ui.Wizard_Pages->setCurrentWidget( ui.Memory_Page );
132 		ui.Label_Page->setText( tr("Memory") );
133 	}
134 	else if( ui.Network_Page == ui.Wizard_Pages->currentWidget() )
135 	{
136 		if( ui.RB_Typical->isChecked() ) // typical or custom mode
137 		{
138 			ui.Wizard_Pages->setCurrentWidget( ui.Typical_HDD_Page );
139 			ui.Label_Page->setText( tr("Hard Disk Size") );
140 		}
141 		else
142 		{
143 			ui.Wizard_Pages->setCurrentWidget( ui.Custom_HDD_Page );
144 			ui.Label_Page->setText( tr("Virtual Hard Disk") );
145 		}
146 	}
147 	else if( ui.Finish_Page == ui.Wizard_Pages->currentWidget() )
148 	{
149 		ui.Wizard_Pages->setCurrentWidget( ui.Network_Page );
150 		ui.Label_Page->setText( tr("Network") );
151 		ui.Button_Next->setText( tr("&Next") );
152 	}
153 	else
154 	{
155 		// Default
156 		AQError( "void VM_Wizard_Window::on_Button_Back_clicked()",
157 				 "Default Section!" );
158 	}
159 }
160 
on_Button_Next_clicked()161 void VM_Wizard_Window::on_Button_Next_clicked()
162 {
163 	if( ui.Wizard_Mode_Page == ui.Wizard_Pages->currentWidget() )
164 	{
165 		ui.Wizard_Pages->setCurrentWidget( ui.Template_Page );
166 		ui.Label_Page->setText( tr("Template For VM") );
167 		on_RB_VM_Template_toggled( ui.RB_VM_Template->isChecked() );
168 
169         Current_Emulator = Get_Default_Emulator();
170 
171         // All Find Systems FIXME ^^^
172         All_Systems = Current_Emulator.Get_Devices();
173         if( All_Systems.isEmpty() )
174         {
175             AQError( "void VM_Wizard_Window::on_Button_Next_clicked()",
176                      "Cannot get devices!" );
177             return;
178         }
179 
180         // Comp types
181         ui.CB_Computer_Type->clear();
182         ui.CB_Computer_Type->addItem( tr("None Selected") );
183         for( QMap<QString, Available_Devices>::const_iterator it = All_Systems.constBegin(); it != All_Systems.constEnd(); it++ )
184         {
185             ui.CB_Computer_Type->addItem( it.value().System.Caption );
186         }
187 
188         ui.Button_Next->setEnabled( true );
189 		ui.Button_Back->setEnabled( true );
190 	}
191 	else if( ui.Accelerator_Page == ui.Wizard_Pages->currentWidget() )
192 	{
193         applyTemplate();
194         ui.Wizard_Pages->setCurrentWidget( ui.General_Settings_Page );
195 
196 	}
197 	else if( ui.Template_Page == ui.Wizard_Pages->currentWidget() )
198 	{
199         Use_Accelerator_Page = true;
200 		ui.Wizard_Pages->setCurrentWidget( ui.Accelerator_Page );
201 
202         //FIXME: arch shouldn't be hardcoded
203         if ( ui.RB_Generate_VM->isChecked() && ui.CB_Computer_Type->currentText() != "IBM PC 64Bit")
204             ui.RB_Emulator_QEMU->setChecked( true );
205         else
206             ui.RB_Emulator_KVM->setChecked( true );
207 
208 		ui.Label_Page->setText( tr("Accelerator") );
209 	}
210 	else if( ui.General_Settings_Page == ui.Wizard_Pages->currentWidget() )
211 	{
212 		for( int vx = 0; vx < VM_List->count(); ++vx )
213 		{
214 			if( VM_List->at(vx)->Get_Machine_Name() == ui.Edit_VM_Name->text() )
215 			{
216 				AQGraphic_Warning( tr("Warning"), tr("This VM Name Does Already Exist!") );
217 				return;
218 			}
219 		}
220 
221 		if( ui.RB_Typical->isChecked() )
222 		{
223 			ui.Wizard_Pages->setCurrentWidget( ui.Typical_HDD_Page );
224 			ui.Label_Page->setText( tr("Hard Disk Size") );
225 		}
226 		else
227 		{
228 			ui.Wizard_Pages->setCurrentWidget( ui.Memory_Page );
229 			ui.Label_Page->setText( tr("Memory") );
230 		}
231 	}
232 	else if( ui.Memory_Page == ui.Wizard_Pages->currentWidget() )
233 	{
234 		on_CH_Remove_RAM_Size_Limitation_stateChanged( Qt::Unchecked ); // update max available RAM size
235 		ui.Wizard_Pages->setCurrentWidget( ui.Custom_HDD_Page );
236 		ui.Label_Page->setText( tr("Virtual Hard Disk") );
237 	}
238 	else if( ui.Typical_HDD_Page == ui.Wizard_Pages->currentWidget() )
239 	{
240 		ui.Wizard_Pages->setCurrentWidget( ui.Network_Page );
241 		ui.Label_Page->setText( tr("Network") );
242 	}
243 	else if( ui.Custom_HDD_Page == ui.Wizard_Pages->currentWidget() )
244 	{
245 		ui.Wizard_Pages->setCurrentWidget( ui.Network_Page );
246 		ui.Label_Page->setText( tr("Network") );
247 	}
248 	else if( ui.Network_Page == ui.Wizard_Pages->currentWidget() )
249 	{
250 		ui.Wizard_Pages->setCurrentWidget( ui.Finish_Page );
251 		ui.Button_Next->setText( tr("&Finish") );
252 		ui.Label_Page->setText( tr("Finish!") );
253 	}
254 	else if( ui.Finish_Page == ui.Wizard_Pages->currentWidget() )
255 	{
256 		if( Create_New_VM() ) accept();
257 	}
258 	else
259 	{
260 		AQError( "void VM_Wizard_Window::on_Button_Next_clicked()",
261 				 "Default Section!" );
262 	}
263 }
264 
applyTemplate()265 void VM_Wizard_Window::applyTemplate()
266 {
267 	// Use Selected Template
268 	if( ui.RB_VM_Template->isChecked() )
269 	{
270 		if( ! New_VM->Load_VM(OS_Templates_List[ui.CB_OS_Type->currentIndex()-1].filePath()) )
271 		{
272 			AQGraphic_Error( "void VM_Wizard_Window::Create_New_VM()", tr("Error!"),
273 							 tr("Cannot Create New VM from Template!") );
274 			return;
275 		}
276 	}
277 
278 	// Emulator
279 	New_VM->Set_Emulator( Current_Emulator );
280 
281 	// Find CPU List For This Template
282 	bool devices_found = false;
283 
284 	if( ui.RB_Emulator_KVM->isChecked() )
285 	{
286         New_VM->Set_Machine_Accelerator(VM::KVM);
287 		New_VM->Set_Computer_Type( "qemu-system-x86_64" );
288 
289 		if( New_VM->Get_Audio_Cards().Audio_es1370 )
290 		{
291 			VM::Sound_Cards tmp_audio = New_VM->Get_Audio_Cards();
292 			tmp_audio.Audio_es1370 = false;
293 			tmp_audio.Audio_AC97 = true;
294 			New_VM->Set_Audio_Cards( tmp_audio );
295 		}
296 
297 		Current_Devices = &All_Systems[ New_VM->Get_Computer_Type() ];
298 		devices_found = true;
299 	}
300 	else
301 	{
302         New_VM->Set_Machine_Accelerator(VM::TCG);
303 		New_VM->Set_Computer_Type( "qemu-system-x86_64" );
304 
305 		Current_Devices = &All_Systems[ New_VM->Get_Computer_Type() ];
306 		/*if( ! Current_Devices->System.QEMU_Name.isEmpty() )*/ devices_found = true;
307 	}
308 
309 	// Use Selected Template
310 	if( ui.RB_VM_Template->isChecked() )
311 	{
312 		// Name
313 		ui.Edit_VM_Name->setText( New_VM->Get_Machine_Name() );
314 
315 		// Memory
316 		ui.Memory_Size->setValue( New_VM->Get_Memory_Size() );
317 
318 		// HDA
319 		double hda_size = New_VM->Get_HDA().Get_Virtual_Size_in_GB();
320 
321 		if( hda_size != 0.0 )
322 			ui.SB_HDD_Size->setValue( hda_size );
323 		else
324 			ui.SB_HDD_Size->setValue( 10.0 );
325 
326 		// Network
327 		ui.RB_User_Mode_Network->setChecked( New_VM->Get_Use_Network() );
328 
329 		// Find CPU List For This Template
330 		Current_Devices = &All_Systems[ New_VM->Get_Computer_Type() ];
331 		if( ! Current_Devices->System.QEMU_Name.isEmpty() ) devices_found = true;
332 	}
333 	else // Create New VM in Date Mode
334 	{
335         By_Year();
336 
337 		// Find CPU List For This Template
338 		QString compCaption = ui.CB_Computer_Type->currentText();
339 		for( QMap<QString, Available_Devices>::const_iterator it = All_Systems.constBegin(); it != All_Systems.constEnd(); it++ )
340 		{
341 			if( it.value().System.Caption == compCaption )
342 			{
343 				Current_Devices = &it.value();
344 				/*if( ! Current_Devices->System.QEMU_Name.isEmpty() )*/ devices_found = true;
345 			}
346 		}
347 	}
348 
349 	if( ! devices_found )
350 	{
351 		AQGraphic_Error( "void VM_Wizard_Window::applyTemplate()", tr("Error!"),
352 						tr("Cannot Find Emulator System ID!") );
353 	}
354 	else
355 	{
356 		// Add CPU's
357 		ui.CB_CPU_Type->clear();
358 		for( int cx = 0; cx < Current_Devices->CPU_List.count(); ++cx )
359 			ui.CB_CPU_Type->addItem( Current_Devices->CPU_List[cx].Caption );
360 	}
361 
362 	// Typical or custom mode
363     Typical_Or_Custom();
364 }
365 
366 
Typical_Or_Custom()367 void VM_Wizard_Window::Typical_Or_Custom()
368 {
369 	if( ui.RB_Typical->isChecked() )
370 	{
371 		ui.Label_Page->setText( tr("Virtual Machine Name") );
372 		on_Edit_VM_Name_textEdited( ui.Edit_VM_Name->text() );
373 
374 		ui.Label_Caption_CPU_Type->setVisible( false );
375 		ui.Line_CPU_Type->setVisible( false );
376 		ui.Label_CPU_Type->setVisible( false );
377 		ui.CB_CPU_Type->setVisible( false );
378 	}
379 	else
380 	{
381 		ui.Label_Page->setText( tr("VM Name and CPU Type") );
382 		on_Edit_VM_Name_textEdited( ui.Edit_VM_Name->text() );
383 
384 		ui.Label_Caption_CPU_Type->setVisible( true );
385 		ui.Line_CPU_Type->setVisible( true );
386 		ui.Label_CPU_Type->setVisible( true );
387 		ui.CB_CPU_Type->setVisible( true );
388 	}
389 }
390 
By_Year()391 void VM_Wizard_Window::By_Year()
392 {
393 	// Select Memory Size, and HDD Size
394 	switch( ui.CB_Relese_Date->currentIndex() )
395 	{
396 		case 0:
397 			AQError( "void VM_Wizard_Window::Create_New_VM()",
398 					 "Relese Date Not Selected!" );
399 			ui.Memory_Size->setValue( 512 );
400 			break;
401 
402 		case 1: // 1985-1990
403 			ui.Memory_Size->setValue( 16 );
404 			ui.SB_HDD_Size->setValue( 1.0 );
405 			break;
406 
407 		case 2: // 1990-1995
408 			ui.Memory_Size->setValue( 64 );
409 			ui.SB_HDD_Size->setValue( 2.0 );
410 			break;
411 
412 		case 3: // 1995-2000
413 			ui.Memory_Size->setValue( 256 );
414 			ui.SB_HDD_Size->setValue( 10.0 );
415 			break;
416 
417 		case 4: // 2000-2005
418 			ui.Memory_Size->setValue( 512 );
419 			ui.SB_HDD_Size->setValue( 20.0 );
420 			break;
421 
422 		case 5: // 2005-2010
423 			ui.Memory_Size->setValue( 1024 );
424 			ui.SB_HDD_Size->setValue( 40.0 );
425 			break;
426 
427 		default:
428 			AQError( "void VM_Wizard_Window::Create_New_VM()",
429 					 "Relese Date Default Section!" );
430 			ui.Memory_Size->setValue( 512 );
431 			break;
432 	}
433 }
434 
Load_OS_Templates()435 bool VM_Wizard_Window::Load_OS_Templates()
436 {
437 	QList<QString> tmp_list = Get_Templates_List();
438 
439 	for( int ax = 0; ax < tmp_list.count(); ++ax )
440 	{
441 		OS_Templates_List.append( QFileInfo(tmp_list[ax]) );
442 	}
443 
444 	for( int ix = 0; ix < OS_Templates_List.count(); ++ix )
445 	{
446 		ui.CB_OS_Type->addItem( OS_Templates_List[ix].completeBaseName() );
447 	}
448 
449 	 // no items found
450 	if( ui.CB_OS_Type->count() < 2 ) return false;
451 	else return true;
452 }
453 
Create_New_VM()454 bool VM_Wizard_Window::Create_New_VM()
455 {
456 	// Icon
457 	QString icon_path = Find_OS_Icon( ui.Edit_VM_Name->text() );
458 	if( icon_path.isEmpty() )
459 	{
460 		AQWarning( "void VM_Wizard_Window::Create_New_VM()", "Icon for new VM not Found!" );
461 		New_VM->Set_Icon_Path( ":/other.png" );
462 	}
463 	else
464 	{
465 		New_VM->Set_Icon_Path( icon_path );
466 	}
467 
468 	// Name
469 	New_VM->Set_Machine_Name( ui.Edit_VM_Name->text() );
470 
471 	// Create path valid string
472 	QString VM_File_Name = Get_FS_Compatible_VM_Name( ui.Edit_VM_Name->text() );
473 
474 	// Set Computer Type?
475 	if( ui.RB_Generate_VM->isChecked() )
476 	{
477 		New_VM->Set_Computer_Type( Current_Devices->System.QEMU_Name );
478 	}
479 
480 	// RAM
481 	New_VM->Set_Memory_Size( ui.Memory_Size->value() );
482 
483 	// Wizard Mode
484 	if( ui.RB_Typical->isChecked() )
485 	{
486 		// Hard Disk
487 		VM::Device_Size hd_size;
488 		hd_size.Size = ui.SB_HDD_Size->value();
489 		hd_size.Suffix = VM::Size_Suf_Gb;
490 
491 		QString hd_path = Settings.value( "VM_Directory", "~" ).toString() + VM_File_Name;
492 
493 		Create_New_HDD_Image( hd_path + "_HDA.img", hd_size );
494 
495 		New_VM->Set_HDA( VM_HDD(true, hd_path + "_HDA.img") );
496 
497 		// Other HDD's
498 		if( New_VM->Get_HDB().Get_Enabled() )
499 		{
500 			Create_New_HDD_Image( hd_path + "_HDB.img", New_VM->Get_HDB().Get_Virtual_Size() );
501 			New_VM->Set_HDB( VM_HDD(true, hd_path + "_HDB.img") );
502 		}
503 
504 		if( New_VM->Get_HDC().Get_Enabled() )
505 		{
506 			Create_New_HDD_Image( hd_path + "_HDC.img", New_VM->Get_HDC().Get_Virtual_Size() );
507 			New_VM->Set_HDC( VM_HDD(true, hd_path + "_HDC.img") );
508 		}
509 
510 		if( New_VM->Get_HDD().Get_Enabled() )
511 		{
512 			Create_New_HDD_Image( hd_path + "_HDD.img", New_VM->Get_HDD().Get_Virtual_Size() );
513 			New_VM->Set_HDD( VM_HDD(true, hd_path + "_HDD.img") );
514 		}
515 	}
516 	else
517 	{
518 		bool devices_found = false;
519 
520 		// CPU Type
521 		if( ui.RB_VM_Template->isChecked() )
522 		{
523 			Current_Devices = &All_Systems[ New_VM->Get_Computer_Type() ];
524 			if( ! Current_Devices->System.QEMU_Name.isEmpty() ) devices_found = true;
525 		}
526 		else
527 		{
528 			// Find QEMU System Name in CB_Computer_Type
529 			if( ui.RB_Emulator_KVM->isChecked() )
530 			{
531 				Current_Devices = &All_Systems[ "qemu-system-x86_64" ];
532 				if( ! Current_Devices->System.QEMU_Name.isEmpty() ) devices_found = true;
533 			}
534 			else // QEMU
535 			{
536 				for( QMap<QString, Available_Devices>::const_iterator it = All_Systems.constBegin(); it != All_Systems.constEnd(); it++ )
537 				{
538 					if( it.value().System.Caption == ui.CB_Computer_Type->currentText() )
539 					{
540 						Current_Devices = &it.value();
541 						devices_found = true;
542 						break;
543 					}
544 				}
545 			}
546 		}
547 
548 		if( ! devices_found )
549 		{
550 			AQGraphic_Error( "bool VM_Wizard_Window::Create_New_VM()", tr("Error!"),
551 							 tr("Cannot Find QEMU System ID!") );
552 			return false;
553 		}
554 
555 		New_VM->Set_CPU_Type( Current_Devices->CPU_List[ui.CB_CPU_Type->currentIndex()].QEMU_Name );
556 
557 		// Hard Disk
558 		if( ! ui.Edit_HDA_File_Name->text().isEmpty() )
559 			New_VM->Set_HDA( VM_HDD(true, ui.Edit_HDA_File_Name->text()) );
560 		else
561 			New_VM->Set_HDA( VM_HDD(false, "") );
562 	}
563 
564 	// Network
565 	if( ui.RB_User_Mode_Network->isChecked() )
566 	{
567 		if( New_VM->Get_Network_Cards_Count() == 0 )
568 		{
569 			New_VM->Set_Use_Network( true );
570 			VM_Net_Card net_card;
571 			net_card.Set_Net_Mode( VM::Net_Mode_Usermode );
572 
573 			New_VM->Add_Network_Card( net_card );
574 		}
575 	}
576 	else if( ui.RB_No_Network->isChecked() )
577 	{
578 		New_VM->Set_Use_Network( false );
579 
580 		for( int rx = 0; rx < New_VM->Get_Network_Cards_Count(); ++rx )
581 		{
582 			New_VM->Delete_Network_Card( 0 );
583 		}
584 	}
585 
586 	// Set Emulator Name (version) to Default ("")
587 	Emulator tmp_emul = New_VM->Get_Emulator();
588 	tmp_emul.Set_Name( "" );
589 	New_VM->Set_Emulator( tmp_emul );
590 
591 	// Create New VM XML File
592 	New_VM->Create_VM_File( Settings.value("VM_Directory", "~").toString() + VM_File_Name + ".aqemu", false );
593 
594 	return true;
595 }
596 
Find_OS_Icon(const QString os_name)597 QString VM_Wizard_Window::Find_OS_Icon( const QString os_name )
598 {
599 	if( os_name.isEmpty() )
600 	{
601 		AQError( "QString VM_Wizard_Window::Find_OS_Icon( const QString os_name )",
602 				 "os_name is Empty!" );
603 		return "";
604 	}
605 
606 	// Find all os icons
607 	QDir icons_dir( QDir::toNativeSeparators(Settings.value("AQEMU_Data_Folder","").toString() + "/os_icons/") );
608 	QFileInfoList all_os_icons = icons_dir.entryInfoList( QStringList("*.png"), QDir::Files, QDir::Unsorted );
609 
610 	QRegExp rex;
611 	rex.setPatternSyntax( QRegExp::Wildcard );
612 	rex.setCaseSensitivity( Qt::CaseInsensitive );
613 
614 	for( int i = 0; i < all_os_icons.count(); i++ )
615 	{
616 		rex.setPattern( "*" + all_os_icons[i].baseName() + "*" );
617 
618 		if( rex.exactMatch(os_name) )
619 		{
620 			return all_os_icons[ i ].absoluteFilePath();
621 		}
622 	}
623 
624 	// select os family...
625 
626 	// Linux
627 	rex.setPattern( "*linux*" );
628 	if( rex.exactMatch(os_name) )
629 		return ":/default_linux.png";
630 
631 	// Windows
632 	rex.setPattern( "*windows*" );
633 	if( rex.exactMatch(os_name) )
634 		return ":/default_windows.png";
635 
636 	return ":/other.png";
637 }
638 
on_RB_VM_Template_toggled(bool on)639 void VM_Wizard_Window::on_RB_VM_Template_toggled( bool on )
640 {
641 	if( on )
642 	{
643 		if( ui.CB_OS_Type->currentIndex() == 0 )
644 			ui.Button_Next->setEnabled( false );
645 		else
646 			ui.Button_Next->setEnabled( true );
647 	}
648 }
649 
on_RB_Generate_VM_toggled(bool on)650 void VM_Wizard_Window::on_RB_Generate_VM_toggled( bool on )
651 {
652 	if( on )
653 	{
654 		if( ui.CB_Computer_Type->currentIndex() == 0 ||
655 		  	ui.CB_Relese_Date->currentIndex() == 0 )
656 			ui.Button_Next->setEnabled( false );
657 		else
658 			ui.Button_Next->setEnabled( true );
659 	}
660 }
661 
on_CB_OS_Type_currentIndexChanged(int index)662 void VM_Wizard_Window::on_CB_OS_Type_currentIndexChanged( int index )
663 {
664 	if( index == 0 )
665 		ui.Button_Next->setEnabled( false );
666 	else
667 		ui.Button_Next->setEnabled( true );
668 }
669 
on_CB_Computer_Type_currentIndexChanged(int index)670 void VM_Wizard_Window::on_CB_Computer_Type_currentIndexChanged( int index )
671 {
672 	if( index == 0 )
673 	{
674 		ui.Button_Next->setEnabled( false );
675 	}
676 	else
677 	{
678 		if( ui.CB_Relese_Date->currentIndex() != 0 )
679 			ui.Button_Next->setEnabled( true );
680 	}
681 }
682 
on_CB_Relese_Date_currentIndexChanged(int index)683 void VM_Wizard_Window::on_CB_Relese_Date_currentIndexChanged( int index )
684 {
685 	if( index == 0 )
686 	{
687 		ui.Button_Next->setEnabled( false );
688 	}
689 	else
690 	{
691 		if( ui.CB_Computer_Type->currentIndex() != 0 )
692 			ui.Button_Next->setEnabled( true );
693 	}
694 }
695 
on_Memory_Size_valueChanged(int value)696 void VM_Wizard_Window::on_Memory_Size_valueChanged( int value )
697 {
698 	int cursorPos = ui.CB_RAM_Size->lineEdit()->cursorPosition();
699 
700 	if( value % 1024 == 0 )
701 	    ui.CB_RAM_Size->setEditText( QString("%1 GB").arg(value / 1024) );
702 	else
703 	    ui.CB_RAM_Size->setEditText( QString("%1 MB").arg(value) );
704 
705 	ui.CB_RAM_Size->lineEdit()->setCursorPosition( cursorPos );
706 }
707 
on_CB_RAM_Size_editTextChanged(const QString & text)708 void VM_Wizard_Window::on_CB_RAM_Size_editTextChanged( const QString &text )
709 {
710 	if( text.isEmpty() )
711 	    return;
712 
713 	QRegExp rx( "\\s*([\\d]+)\\s*(MB|GB|M|G|)\\s*" ); // like: 512MB or 512
714 	if( ! rx.exactMatch(text.toUpper()) )
715 	{
716 		AQGraphic_Warning( tr("Error"),
717 						   tr("Cannot convert \"%1\" to memory size!").arg(text) );
718 		return;
719 	}
720 
721 	QStringList ramStrings = rx.capturedTexts();
722 	if( ramStrings.count() != 3 )
723 	{
724 		AQGraphic_Warning( tr("Error"),
725 						   tr("Cannot convert \"%1\" to memory size!").arg(text) );
726 		return;
727 	}
728 
729 	bool ok = false;
730 	int value = ramStrings[1].toInt( &ok, 10 );
731 	if( ! ok )
732 	{
733 		AQGraphic_Warning( tr("Error"),
734 						   tr("Cannot convert \"%1\" to integer!").arg(ramStrings[1]) );
735 		return;
736 	}
737 
738 	if( ramStrings[2] == "MB" || ramStrings[2] == "M" ); // Size in megabytes
739 	else if( ramStrings[2] == "GB" || ramStrings[2] == "G" ) value *= 1024;
740 	else
741 	{
742 		AQGraphic_Warning( tr("Error"),
743 						   tr("Cannot convert \"%1\" to size suffix! Valid suffixes: MB, GB").arg(ramStrings[2]) );
744 		return;
745 	}
746 
747 	if( value <= 0 )
748 	{
749 		AQGraphic_Warning( tr("Error"), tr("Memory size < 0! Valid size is 1 or more") );
750 		return;
751 	}
752 
753 	on_TB_Update_Available_RAM_Size_clicked();
754 	if( (value > ui.Memory_Size->maximum()) &&
755 		(ui.CH_Remove_RAM_Size_Limitation->isChecked() == false) )
756 	{
757 		AQGraphic_Warning( tr("Error"),
758 						   tr("Your memory size %1 MB > %2 MB - all free RAM on this system!\n"
759 							  "To setup this value, check \"Remove limitation on maximum amount of memory\".")
760 						   .arg(value).arg(ui.Memory_Size->maximum()) );
761 
762 		on_Memory_Size_valueChanged( ui.Memory_Size->value() ); // Set valid size
763 		return;
764 	}
765 
766 	// All OK. Set memory size
767 	ui.Memory_Size->setValue( value );
768 }
769 
on_CH_Remove_RAM_Size_Limitation_stateChanged(int state)770 void VM_Wizard_Window::on_CH_Remove_RAM_Size_Limitation_stateChanged( int state )
771 {
772 	if( state == Qt::Checked )
773 	{
774 		ui.Memory_Size->setMaximum( 32768 );
775 		ui.Label_Available_Free_Memory->setText( "32 GB" );
776 		Update_RAM_Size_ComboBox( 32768 );
777 	}
778 	else
779 	{
780 		int allRAM = 0, freeRAM = 0;
781 		System_Info::Get_Free_Memory_Size( allRAM, freeRAM );
782 
783 		if( allRAM < ui.Memory_Size->value() )
784 			AQGraphic_Warning( tr("Error"), tr("Current memory size bigger than all existing host memory!\nUsing maximum available size.") );
785 
786 		ui.Memory_Size->setMaximum( allRAM );
787 		ui.Label_Available_Free_Memory->setText( QString("%1 MB").arg(allRAM) );
788 		Update_RAM_Size_ComboBox( allRAM );
789 	}
790 }
791 
on_TB_Update_Available_RAM_Size_clicked()792 void VM_Wizard_Window::on_TB_Update_Available_RAM_Size_clicked()
793 {
794 	int allRAM = 0, freeRAM = 0;
795 	System_Info::Get_Free_Memory_Size( allRAM, freeRAM );
796 	ui.TB_Update_Available_RAM_Size->setText( tr("Free memory: %1 MB").arg(freeRAM) );
797 
798 	if( ! ui.CH_Remove_RAM_Size_Limitation->isChecked() )
799 	{
800 		ui.Memory_Size->setMaximum( allRAM );
801 		Update_RAM_Size_ComboBox( allRAM );
802 	}
803 }
804 
Update_RAM_Size_ComboBox(int freeRAM)805 void VM_Wizard_Window::Update_RAM_Size_ComboBox( int freeRAM )
806 {
807 	static int oldRamSize = 0;
808 	if( freeRAM == oldRamSize ) return;
809 	else oldRamSize = freeRAM;
810 
811 	QStringList ramSizes;
812 	ramSizes << "32 MB" << "64 MB" << "128 MB" << "256 MB" << "512 MB"
813 			 << "1 GB" << "2 GB" << "3 GB" << "4 GB" << "8 GB" << "16 GB" << "32 GB";
814 	int maxRamIndex = 0;
815 	if( freeRAM >= 32768 ) maxRamIndex = 12;
816 	else if( freeRAM >= 16384 ) maxRamIndex = 11;
817 	else if( freeRAM >= 8192 ) maxRamIndex = 10;
818 	else if( freeRAM >= 4096 ) maxRamIndex = 9;
819 	else if( freeRAM >= 3072 ) maxRamIndex = 8;
820 	else if( freeRAM >= 2048 ) maxRamIndex = 7;
821 	else if( freeRAM >= 1024 ) maxRamIndex = 6;
822 	else if( freeRAM >= 512 ) maxRamIndex = 5;
823 	else if( freeRAM >= 256 ) maxRamIndex = 4;
824 	else if( freeRAM >= 128 ) maxRamIndex = 3;
825 	else if( freeRAM >= 64 ) maxRamIndex = 2;
826 	else if( freeRAM >= 32 ) maxRamIndex = 1;
827 	else
828 	{
829 		AQGraphic_Warning( tr("Error"), tr("Free memory on this system is lower than 32 MB!") );
830 		return;
831 	}
832 
833 	if( maxRamIndex > ramSizes.count() )
834 	{
835 		AQError( "void VM_Wizard_Window::Update_RAM_Size_ComboBox( int freeRAM )",
836 				 "maxRamIndex > ramSizes.count()" );
837 		return;
838 	}
839 
840 	QString oldText = ui.CB_RAM_Size->currentText();
841 
842 	ui.CB_RAM_Size->clear();
843 	for( int ix = 0; ix < maxRamIndex; ix++ ) ui.CB_RAM_Size->addItem( ramSizes[ix] );
844 
845 	ui.CB_RAM_Size->setEditText( oldText );
846 }
847 
on_Edit_VM_Name_textEdited(const QString & text)848 void VM_Wizard_Window::on_Edit_VM_Name_textEdited( const QString &text )
849 {
850 	if( ui.Edit_VM_Name->text().isEmpty() ) ui.Button_Next->setEnabled( false );
851 	else ui.Button_Next->setEnabled( true );
852 }
853 
on_Button_New_HDD_clicked()854 void VM_Wizard_Window::on_Button_New_HDD_clicked()
855 {
856 	Create_HDD_Image_Window Create_HDD_Win( this );
857 
858 	Create_HDD_Win.Set_Image_Size( ui.SB_HDD_Size->value() ); // Set Initial HDA Size
859 
860 	if( Create_HDD_Win.exec() == QDialog::Accepted )
861 		ui.Edit_HDA_File_Name->setText( Create_HDD_Win.Get_Image_File_Name() );
862 }
863 
on_Button_Existing_clicked()864 void VM_Wizard_Window::on_Button_Existing_clicked()
865 {
866 	QString hddPath = QFileDialog::getOpenFileName( this, tr("Select HDD Image"),
867 													Get_Last_Dir_Path(ui.Edit_HDA_File_Name->text()),
868 													tr("All Files (*)") );
869 
870 	if( ! hddPath.isEmpty() )
871 		ui.Edit_HDA_File_Name->setText( QDir::toNativeSeparators(hddPath) );
872 }
873