Remove favorites panel, the last opened virtual machines can be found in the file...
[qemu-gui.git] / mainframe.cpp
blob91c05211f184adb1b09c2e0155e866dff4ebe14b
1 #include <wx/wx.h>
2 #include <wx/arrimpl.cpp>
3 #include <wx/docview.h>
4 #include "mainframe.h"
5 #include "wizard.h"
6 #include "qemu-ui.h"
7 #include "console.h"
8 #include "vm.h"
9 #include "config.h"
10 #include "notebook.h"
11 #include "menubar.h"
12 #include "toolbar.h"
13 #include "statusbar.h"
14 #include "vncpanel.h"
15 #include "vmdialog.h"
16 #include "events.h"
18 #if defined __WXDEBUG__
19 #include <wx/debug.h>
20 #include <wx/memory.h>
21 #endif
23 #if !defined(__WXMSW__) && !defined(__WXPM__)
24 #include "icons/icon.xpm"
25 #endif
27 BEGIN_EVENT_TABLE(QemuMainFrame, wxFrame)
28 EVT_MENU(QEMU_NEW, QemuMainFrame::OnNewVM)
29 EVT_COMMAND(wxID_ANY,EVT_NEW_VM,QemuMainFrame::OnNewVM)
30 EVT_MENU(QEMU_OPEN, QemuMainFrame::OnOpenVM)
31 EVT_COMMAND(wxID_ANY,EVT_OPEN_VM,QemuMainFrame::OnOpenVM)
32 EVT_MENU_RANGE(wxID_FILE1, wxID_FILE9, QemuMainFrame::OnReOpenVM)
34 EVT_MENU(QEMU_CLOSE, QemuMainFrame::OnNotebookPageClosed)
35 EVT_MENU(QEMU_QUIT, QemuMainFrame::OnQuitCommandEvent)
36 EVT_CLOSE(QemuMainFrame::OnQuit)
38 EVT_MENU(QEMU_HOMEPAGE, QemuMainFrame::OnShowHomepage)
39 EVT_MENU(QEMU_FULLSCREEN, QemuMainFrame::OnFullScreen)
40 EVT_MENU(QEMU_TOGGLE_TOOLBAR, QemuMainFrame::OnToggleToolBar)
41 EVT_MENU(QEMU_TOOLBAR_TEXT, QemuMainFrame::OnToolBarSettingChange)
42 EVT_MENU(QEMU_TOOLBAR_ICONS, QemuMainFrame::OnToolBarSettingChange)
43 EVT_MENU(QEMU_TOOLBAR_BOTH, QemuMainFrame::OnToolBarSettingChange)
44 EVT_MENU(QEMU_TOGGLE_STATUSBAR, QemuMainFrame::OnToggleStatusBar)
46 EVT_MENU(QEMU_VM_SETTINGS,QemuMainFrame::OnVMSettings)
48 EVT_MENU(QEMU_VM_START,QemuMainFrame::OnPowerOnVM)
49 EVT_MENU(QEMU_VM_PAUSE,QemuMainFrame::OnPauseVM)
50 EVT_MENU(QEMU_VM_SHUTDOWN,QemuMainFrame::OnPowerOffVM)
51 EVT_MENU(QEMU_VM_RESET,QemuMainFrame::OnResetVM)
52 EVT_MENU(QEMU_VM_KILL,QemuMainFrame::OnKillVM)
54 EVT_MENU(QEMU_VM_SNAPSHOT,QemuMainFrame::OnSnapshot)
55 EVT_MENU(QEMU_VM_REVERT_SNAPSHOT,QemuMainFrame::OnRevertSnapshot)
57 EVT_MENU(QEMU_TOOLBAR_DISPLAY_INFO,QemuMainFrame::OnToggleDisplay)
58 EVT_MENU(QEMU_TOOLBAR_DISPLAY_SCREEN,QemuMainFrame::OnToggleDisplay)
59 EVT_MENU(QEMU_TOOLBAR_DISPLAY_CONSOLE,QemuMainFrame::OnToggleDisplay)
61 EVT_MENU(QEMU_TOOLBAR_SEND_VM_COMMAND,QemuMainFrame::OnSendCommandToVM)
63 EVT_MENU(QEMU_WINDOW_NEXT, QemuMainFrame::OnNextWindow)
64 EVT_MENU(QEMU_WINDOW_PREV, QemuMainFrame::OnPrevWindow)
65 EVT_MENU(QEMU_DOC, QemuMainFrame::OnOpenQemuDoc)
66 EVT_MENU(QEMU_ABOUT, QemuMainFrame::OnAbout)
68 EVT_NOTEBOOK_PAGE_CHANGED(QEMU_VM_NOTEBOOK,QemuMainFrame::OnNotebookPageChanged)
69 EVT_MENU(QEMU_VM_NOTEBOOK_CONTEXT_CLOSE,QemuMainFrame::OnNotebookPageClosed)
70 EVT_MENU(ID_STATUSBAR_CDROM_CONNECT,QemuMainFrame::OnConnectCdRom)
71 END_EVENT_TABLE()
73 QemuMainFrame::QemuMainFrame(const wxString& title)
74 :wxFrame(NULL, wxID_ANY, title)
76 this->toolbarStyle = 0;
77 SetIcon(wxICON(sample));
79 #if wxUSE_MENUS
80 this->menubar = new QemuUIMenuBar();
81 SetMenuBar(this->menubar);
82 this->filehistory = new wxFileHistory(5);
83 this->filehistory->UseMenu(menubar->GetFileMenu());
84 #endif
86 #if wxUSE_TOOLBAR
87 this->toolbar = new QemuUIToolBar(this);
88 SetToolBar(this->toolbar);
89 #endif
91 this->mainwindow = new wxScrolledWindow(this);
92 mainwindow->SetScrollRate(10,10);
93 mainwindow->SetScrollbars(20, 20, 50, 50);
95 #if wxUSE_STATUSBAR
96 this->statusbar = new QemuUIStatusBar(this);
97 SetStatusBar(this->statusbar);
98 #endif
100 this->notebook = new QemuUINotebook(mainwindow);
101 this->CreateHomepage();
102 this->DoLayout();
105 void QemuMainFrame::DoLayout(){
106 wxBoxSizer *notebookSizer = new wxBoxSizer(wxHORIZONTAL );
107 notebookSizer->Add(notebook,1,wxEXPAND,0);
108 mainwindow->SetAutoLayout(true);
109 mainwindow->SetSizer(notebookSizer);
110 notebookSizer->Fit(mainwindow);
111 notebookSizer->SetSizeHints(mainwindow);
112 notebookSizer->Layout();
114 wxBoxSizer *frameSizer = new wxBoxSizer(wxVERTICAL);
115 frameSizer->Add(mainwindow,1,wxEXPAND,0);
116 frameSizer->Fit(this);
117 frameSizer->SetSizeHints(this);
119 SetAutoLayout(true);
120 SetSizer(frameSizer);
121 Layout();
122 SetSize(800,700);
123 Centre();
126 void QemuMainFrame::CreateHomepage(){
127 notebook->CreateHomepage();
128 menubar->PrependWindowMenuEntry(_("Homepage"));
129 toolbar->Disable();
130 statusbar->Disable();
133 void QemuMainFrame::OnQuitCommandEvent(wxCommandEvent& WXUNUSED(event)){
134 Close();
137 void QemuMainFrame::OnQuit(wxCloseEvent& event)
139 #if wxUSE_MEMORY_TRACING
140 wxDebugContext::SetFile(wxT("log.txt"));
141 wxDebugContext::Dump();
142 wxDebugContext::PrintStatistics();
143 #endif
144 for(int i = 0; i < vms.GetCount(); i++){
145 if(vms.Item(i)->IsRunning()){
146 if(wxMessageBox(
147 _("Some virtual machines are still running, "
148 "are you sure you wan't to close QEMU?"),
149 _("Warning"),
150 wxICON_WARNING | wxYES_NO,
151 this
152 ) == wxNO){
153 event.Veto();
154 return;
159 Destroy();
162 void QemuMainFrame::OnOpenQemuDoc(wxCommandEvent& WXUNUSED(event))
164 if(!wxLaunchDefaultBrowser(QEMU_GUI_DOC)){
165 wxLogError(_("Could not open qemu documentation."));
169 void QemuMainFrame::OnAbout(wxCommandEvent& WXUNUSED(event))
173 wxTextCtrl* contentText = new wxTextCtrl;
174 contentText->Create( mainwindow, wxID_ANY, wxT("TEST TEST http://www.wxwidgets.org/"), wxDefaultPosition, wxDefaultSize, wxTE_MULTILINE|wxTE_AUTO_URL|wxTE_CENTRE|wxTE_WORDWRAP|wxTE_READONLY);
177 wxString msg;
178 msg << _("QEMU GUI version");
179 msg << wxT(" "QEMU_GUI_VERSION"\n");
180 msg << QEMU_GUI_BUILD_INFO;
181 msg << _("\n\nThis is free software licensed under the GNU GPL.\n");
182 msg << _("(c) 2006 Marc Tanner\n");
183 msg << _("<"QEMU_GUI_MAIL">");
185 wxMessageBox(msg, _("About QEMU GUI"), wxOK | wxICON_INFORMATION, this);
189 void QemuMainFrame::OnToggleStatusBar(wxCommandEvent& event)
191 if(event.IsChecked())
192 statusbar->Show();
193 else
194 statusbar->Hide();
196 PositionStatusBar();
199 void QemuMainFrame::OnToggleToolBar(wxCommandEvent& event){
200 if(event.IsChecked() && !this->toolbar){
201 this->toolbar = new QemuUIToolBar(this);
202 SetToolBar(this->toolbar);
203 if(this->toolbarStyle != 0){
204 toolbar->SetWindowStyle(toolbarStyle);
205 toolbar->Layout();
207 } else {
208 this->toolbarStyle = toolbar->GetWindowStyle();
209 delete this->toolbar;
210 this->toolbar = NULL;
211 SetToolBar(NULL);
213 menubar->EnableToolbar(event.IsChecked());
216 void QemuMainFrame::OnToolBarSettingChange(wxCommandEvent& event){
217 long style = wxTB_HORIZONTAL | wxNO_BORDER;
218 switch(event.GetId()){
219 case QEMU_TOOLBAR_TEXT:
220 style |= wxTB_TEXT | wxTB_NOICONS;
221 break;
222 case QEMU_TOOLBAR_ICONS:
223 break;
224 case QEMU_TOOLBAR_BOTH:
225 style |= wxTB_TEXT;
226 break;
229 toolbar->SetWindowStyle(style);
230 toolbar->Layout();
233 void QemuMainFrame::OnFullScreen(wxCommandEvent &WXUNUSED(event)){
234 ShowFullScreen(!IsFullScreen());
237 void QemuMainFrame::OnShowHomepage(wxCommandEvent &WXUNUSED(event)){
238 ShowHomepage();
241 void QemuMainFrame::ShowHomepage(){
242 if(notebook->HasHomepage()){
243 const int pos = notebook->ShowHomepage();
244 menubar->CheckWindowMenuEntry(pos);
245 } else {
246 CreateHomepage();
249 toolbar->Disable();
250 statusbar->Disable();
253 void QemuMainFrame::OnChangeWindow(wxCommandEvent& event){
254 notebook->SetSelection(menubar->GetCheckedWindowMenuEntry());
257 void QemuMainFrame::OnNextWindow(wxCommandEvent& WXUNUSED(event)){
258 notebook->AdvanceSelection();
261 void QemuMainFrame::OnPrevWindow(wxCommandEvent& WXUNUSED(event)){
262 notebook->AdvanceSelection(false);
265 void QemuMainFrame::OnNewVM(wxCommandEvent& WXUNUSED(event)){
266 QemuUINewVMWizard *wizard = new QemuUINewVMWizard(this);
267 QemuVM *vm = wizard->RunIt();
268 wizard->Destroy();
269 if(vm){
270 OpenVM(vm);
274 void QemuMainFrame::OnOpenVM(wxCommandEvent& WXUNUSED(event)){
275 wxFileDialog *dialog = new wxFileDialog(
276 this,
277 _("Select a VM configuration file to open"),
278 wxEmptyString,wxEmptyString,
279 _("VM configuration (*.qvmc)|*.qvmc")
282 dialog->SetDirectory(wxGetHomeDir());
283 dialog->CentreOnParent();
285 if(dialog->ShowModal() == wxID_OK){
286 OpenVM(dialog->GetPath());
289 dialog->Destroy();
292 void QemuMainFrame::OnReOpenVM(wxCommandEvent& event){
293 OpenVM(filehistory->GetHistoryFile(event.GetId() - wxID_FILE1));
296 void QemuMainFrame::OpenVM(const wxString& config){
297 QemuVM *vm = new QemuVM(config);
298 if(!OpenVM(vm)){
299 delete vm;
303 bool QemuMainFrame::OpenVM(QemuVM *vm){
304 const wxString config = vm->GetConfigFile();
305 for(int i = 0; i < vms.GetCount(); i++){
306 if(vms.Item(i)->GetConfigFile().Cmp(config) == 0){
307 wxMessageBox(
308 _("This virutal machine is already open."),
309 _("Error"),
310 wxICON_ERROR | wxOK,
311 this
313 return false;
317 filehistory->AddFileToHistory(config);
318 menubar->UpdateFileHistory(filehistory->GetCount());
319 // it is important that the window menu entry gets created
320 // before a new notebook page is added, because within the
321 // OnNotebookChange event handler the new item will be checked.
322 menubar->AppendWindowMenuEntry(vm->GetTitle());
323 notebook->AddVM(vm);
325 // add to the array of open vm's
326 vms.Add(vm);
328 return true;
331 QemuUINotebookPage* QemuMainFrame::GetCurrentVMTab(){
332 return notebook->GetCurrentVMTab();
335 QemuVM* QemuMainFrame::GetCurrentVM(){
336 return notebook->GetCurrentVM();
339 void QemuMainFrame::OnVMSettings(wxCommandEvent& WXUNUSED(event)){
340 QemuVM *vm = GetCurrentVM();
341 if(!vm)
342 return;
344 QemuVMConfigDialog *dialog = new QemuVMConfigDialog(this,vm);
345 if(dialog->ShowModal() == wxID_OK){
346 dialog->Save();
350 void QemuMainFrame::OnPowerOnVM(wxCommandEvent& WXUNUSED(event)){
351 QemuUINotebookPage *tab = GetCurrentVMTab();
352 QemuVM *vm = tab->GetVM();
353 if(tab && vm){
354 bool paused = vm->IsPaused();
355 if(vm->PowerOn() < 0){
356 wxMessageBox(_("Could not start qemu"),_("Error"),
357 wxICON_ERROR | wxOK, this);
358 return;
361 #if 1
362 if(!paused){
363 // give qemu some time to set up it's vnc server
364 //wxMilliSleep(1000);
365 if(tab->GetScreen()->Connect(vm->GetCurrentVNCDisplay())){
366 vm->AddEventHandler(tab->GetScreen());
367 tab->ShowScreen();
368 } else {
369 wxLogError(_("Could not connect to vnc display."));
372 #endif
373 UpdateState();
378 void QemuMainFrame::OnPauseVM(wxCommandEvent& WXUNUSED(event)){
379 QemuVM *vm = GetCurrentVM();
380 if(vm){
381 vm->Pause();
382 UpdateState();
386 void QemuMainFrame::OnPowerOffVM(wxCommandEvent& WXUNUSED(event)){
387 QemuVM *vm = GetCurrentVM();
388 if(vm){
389 vm->PowerOff();
390 UpdateState();
394 void QemuMainFrame::OnResetVM(wxCommandEvent& WXUNUSED(event)){
395 QemuVM *vm = GetCurrentVM();
396 if(vm){
397 vm->Reset();
401 void QemuMainFrame::OnKillVM(wxCommandEvent& WXUNUSED(event)){
402 QemuVM *vm = GetCurrentVM();
403 if(vm){
404 if(wxMessageBox(_("Do you really want to kill this VM?"),
405 _("Warning"),wxICON_QUESTION | wxYES_NO, this) == wxYES){
406 vm->Kill();
411 void QemuMainFrame::OnSnapshot(wxCommandEvent& WXUNUSED(event)){
412 QemuVM *vm = GetCurrentVM();
413 if(vm){
414 vm->Snapshot();
415 UpdateState();
419 void QemuMainFrame::OnRevertSnapshot(wxCommandEvent& WXUNUSED(event)){
420 QemuVM *vm = GetCurrentVM();
421 if(vm){
422 vm->Revert();
423 UpdateState();
427 void QemuMainFrame::OnToggleDisplay(wxCommandEvent& event){
428 QemuUINotebookPage* tab = notebook->GetCurrentVMTab();
429 switch(event.GetId()){
430 case QEMU_TOOLBAR_DISPLAY_INFO:
431 toolbar->ShowInfo();
432 tab->ShowInfo();
433 break;
434 case QEMU_TOOLBAR_DISPLAY_SCREEN:
435 toolbar->ShowScreen();
436 tab->ShowScreen();
437 break;
438 case QEMU_TOOLBAR_DISPLAY_CONSOLE:
439 toolbar->ShowConsole();
440 tab->ShowConsole();
441 break;
445 void QemuMainFrame::OnSendCommandToVM(wxCommandEvent& WXUNUSED(event)){
446 QemuVM *vm = GetCurrentVM();
447 if(!vm) return;
448 wxTextEntryDialog dialog(this,
449 _T("Please enter a command which will be send to the qemu monitor."),
450 _T("Please enter a command"),
451 _T(""),
452 wxOK | wxCANCEL
455 if (dialog.ShowModal() == wxID_OK){
456 wxMessageBox(vm->SendCommand(dialog.GetValue(),true), wxT("Response"), wxOK | wxICON_INFORMATION, this);
457 //wxLogError(vm->SendCommand(dialog.GetValue()));
461 void QemuMainFrame::OnNotebookPageChanged(wxNotebookEvent& event){
462 const size_t pos = event.GetSelection();
463 menubar->CheckWindowMenuEntry(pos);
464 UpdateState();
467 void QemuMainFrame::CloseNotebookPage(const int pos){
468 QemuVM *vm = GetCurrentVM();
470 if(!vm){
471 notebook->CloseHomepage();
472 menubar->RemoveWindowMenuEntry(pos);
473 return;
476 if(vm->IsRunning() &&
477 wxMessageBox(_("Do you really want to close this VM?"),_("Question"),
478 wxICON_QUESTION | wxYES_NO, this) != wxYES){
479 return;
482 wxNotebookPage *page = notebook->GetCurrentPage();
483 if(page){
484 vm->PowerOff();
485 vms.Remove(vm);
486 delete vm;
487 menubar->RemoveWindowMenuEntry(pos);
488 notebook->RemovePage(pos);
489 delete page;
490 UpdateState();
494 void QemuMainFrame::OnNotebookPageClosed(wxCommandEvent& WXUNUSED(event)){
495 CloseNotebookPage(notebook->GetSelection());
498 void QemuMainFrame::UpdateState(){
499 QemuUINotebookPage *tab = GetCurrentVMTab();
501 if(!tab){
502 menubar->Disable();
503 toolbar->Disable();
504 statusbar->Disable();
505 return;
508 QemuVM *vm = tab->GetVM();
509 menubar->Settings(!vm->IsRunning());
510 menubar->PowerOn(!vm->IsRunning());
511 menubar->PowerOff(vm->IsRunning() || vm->IsPaused());
512 menubar->Pause(vm->IsRunning());
513 menubar->Reset(vm->IsRunning() || vm->IsPaused());
514 toolbar->PowerOn(!vm->IsRunning());
515 toolbar->PowerOff(vm->IsRunning() || vm->IsPaused());
516 toolbar->Pause(vm->IsRunning());
517 toolbar->Reset(vm->IsRunning() || vm->IsPaused());
518 toolbar->Kill(vm->IsRunning());
519 toolbar->Snapshot(vm->IsRunning());
520 toolbar->RevertSnapshot(vm->GetPID() > 0 && vm->HasSnapshot());
521 toolbar->EnableDisplayArea();
522 toolbar->EnableDisplayScreen(!vm->IsPoweredOff());
523 toolbar->SendVMCommand(!vm->IsPoweredOff());
525 if(tab->IsConsoleActive())
526 toolbar->ShowConsole();
527 else if(tab->IsScreenActive())
528 toolbar->ShowScreen();
529 else
530 toolbar->ShowInfo();
532 tab->GetConsole()->SetState(!vm->IsPoweredOff());
534 if(vm->IsRunning())
535 statusbar->Enable();
536 else
537 statusbar->Disable();
540 void QemuMainFrame::OnConnectCdRom(wxCommandEvent& event){
541 GetCurrentVM()->ConnectCdRom(event.IsChecked());
544 void QemuMainFrame::SaveFileHistory(wxConfigBase *config){
545 //config->SetPath(wxT("/filehistory"));
546 filehistory->Save(*config);
547 //config->SetPath(wxT("/"));
550 void QemuMainFrame::LoadFileHistory(wxConfigBase *config){
551 //config->SetPath(wxT("/filehistory"));
552 filehistory->Load(*config);
553 menubar->UpdateFileHistory(filehistory->GetCount());
554 //config->SetPath(wxT("/"));