Hide mouse pointer when entering the vnc panel and show it again on leaving.
[qemu-gui.git] / mainframe.cpp
blobada3ed0a9156e5ebd5f019e4eab072c9d720cb09
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)
47 EVT_MENU(QEMU_VM_SEND_CTRL_ALT_DEL,QemuMainFrame::OnVMSendCtrlAltDel)
49 EVT_MENU(QEMU_VM_START,QemuMainFrame::OnPowerOnVM)
50 EVT_MENU(QEMU_VM_PAUSE,QemuMainFrame::OnPauseVM)
51 EVT_MENU(QEMU_VM_SHUTDOWN,QemuMainFrame::OnPowerOffVM)
52 EVT_MENU(QEMU_VM_RESET,QemuMainFrame::OnResetVM)
53 EVT_MENU(QEMU_VM_KILL,QemuMainFrame::OnKillVM)
55 EVT_MENU(QEMU_VM_SNAPSHOT,QemuMainFrame::OnSnapshot)
56 EVT_MENU(QEMU_VM_REVERT_SNAPSHOT,QemuMainFrame::OnRevertSnapshot)
58 EVT_MENU(QEMU_TOOLBAR_DISPLAY_INFO,QemuMainFrame::OnToggleDisplay)
59 EVT_MENU(QEMU_TOOLBAR_DISPLAY_SCREEN,QemuMainFrame::OnToggleDisplay)
60 EVT_MENU(QEMU_TOOLBAR_DISPLAY_CONSOLE,QemuMainFrame::OnToggleDisplay)
62 EVT_MENU(QEMU_TOOLBAR_SEND_VM_COMMAND,QemuMainFrame::OnSendCommandToVM)
64 EVT_MENU(QEMU_WINDOW_NEXT, QemuMainFrame::OnNextWindow)
65 EVT_MENU(QEMU_WINDOW_PREV, QemuMainFrame::OnPrevWindow)
66 EVT_MENU(QEMU_DOC, QemuMainFrame::OnOpenQemuDoc)
67 EVT_MENU(QEMU_ABOUT, QemuMainFrame::OnAbout)
69 EVT_NOTEBOOK_PAGE_CHANGED(QEMU_VM_NOTEBOOK,QemuMainFrame::OnNotebookPageChanged)
70 EVT_MENU(QEMU_VM_NOTEBOOK_CONTEXT_CLOSE,QemuMainFrame::OnNotebookPageClosed)
71 EVT_MENU(ID_STATUSBAR_CDROM_CONNECT,QemuMainFrame::OnConnectCdRom)
72 END_EVENT_TABLE()
74 QemuMainFrame::QemuMainFrame(const wxString& title)
75 :wxFrame(NULL, wxID_ANY, title)
77 this->toolbarStyle = 0;
78 SetIcon(wxICON(sample));
80 #if wxUSE_MENUS
81 this->menubar = new QemuUIMenuBar();
82 SetMenuBar(this->menubar);
83 this->filehistory = new wxFileHistory(5);
84 this->filehistory->UseMenu(menubar->GetFileMenu());
85 #endif
87 #if wxUSE_TOOLBAR
88 this->toolbar = new QemuUIToolBar(this);
89 SetToolBar(this->toolbar);
90 #endif
92 this->mainwindow = new wxScrolledWindow(this);
93 mainwindow->SetScrollRate(10,10);
94 mainwindow->SetScrollbars(20, 20, 50, 50);
96 #if wxUSE_STATUSBAR
97 this->statusbar = new QemuUIStatusBar(this);
98 SetStatusBar(this->statusbar);
99 #endif
101 this->notebook = new QemuUINotebook(mainwindow);
102 this->CreateHomepage();
103 UpdateState();
104 this->DoLayout();
107 void QemuMainFrame::DoLayout(){
108 wxBoxSizer *notebookSizer = new wxBoxSizer(wxHORIZONTAL );
109 notebookSizer->Add(notebook,1,wxEXPAND,0);
110 mainwindow->SetAutoLayout(true);
111 mainwindow->SetSizer(notebookSizer);
112 notebookSizer->Fit(mainwindow);
113 notebookSizer->SetSizeHints(mainwindow);
114 notebookSizer->Layout();
116 wxBoxSizer *frameSizer = new wxBoxSizer(wxVERTICAL);
117 frameSizer->Add(mainwindow,1,wxEXPAND,0);
118 frameSizer->Fit(this);
119 frameSizer->SetSizeHints(this);
121 SetAutoLayout(true);
122 SetSizer(frameSizer);
123 Layout();
124 SetSize(800,700);
125 Centre();
128 void QemuMainFrame::CreateHomepage(){
129 notebook->CreateHomepage();
130 menubar->PrependWindowMenuEntry(_("Homepage"));
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 | wxTB_FLAT;
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::OnVMSendCtrlAltDel(wxCommandEvent& WXUNUSED(event)){
351 QemuVM *vm = GetCurrentVM();
352 if(!vm || !vm->IsRunning())
353 return;
354 vm->SendKey(wxT("ctrl-alt-delete"));
357 void QemuMainFrame::OnPowerOnVM(wxCommandEvent& WXUNUSED(event)){
358 QemuUINotebookPage *tab = GetCurrentVMTab();
359 QemuVM *vm = tab->GetVM();
360 if(tab && vm){
361 bool paused = vm->IsPaused();
362 if(vm->PowerOn() < 0){
363 wxMessageBox(_("Could not start qemu"),_("Error"),
364 wxICON_ERROR | wxOK, this);
365 return;
368 #if 1
369 if(!paused){
370 // give qemu some time to set up it's vnc server
371 //wxMilliSleep(1000);
372 if(tab->GetScreen()->Connect(vm->GetCurrentVNCDisplay())){
373 vm->AddEventHandler(tab->GetScreen());
374 tab->ShowScreen();
375 } else {
376 wxLogError(_("Could not connect to vnc display."));
379 #endif
380 UpdateState();
385 void QemuMainFrame::OnPauseVM(wxCommandEvent& WXUNUSED(event)){
386 QemuVM *vm = GetCurrentVM();
387 if(vm){
388 vm->Pause();
389 UpdateState();
393 void QemuMainFrame::OnPowerOffVM(wxCommandEvent& WXUNUSED(event)){
394 QemuVM *vm = GetCurrentVM();
395 if(vm){
396 vm->PowerOff();
397 UpdateState();
401 void QemuMainFrame::OnResetVM(wxCommandEvent& WXUNUSED(event)){
402 QemuVM *vm = GetCurrentVM();
403 if(vm){
404 vm->Reset();
408 void QemuMainFrame::OnKillVM(wxCommandEvent& WXUNUSED(event)){
409 QemuVM *vm = GetCurrentVM();
410 if(vm){
411 if(wxMessageBox(_("Do you really want to kill this VM?"),
412 _("Warning"),wxICON_QUESTION | wxYES_NO, this) == wxYES){
413 vm->Kill();
418 void QemuMainFrame::OnSnapshot(wxCommandEvent& WXUNUSED(event)){
419 QemuVM *vm = GetCurrentVM();
420 if(vm){
421 vm->Snapshot();
422 UpdateState();
426 void QemuMainFrame::OnRevertSnapshot(wxCommandEvent& WXUNUSED(event)){
427 QemuVM *vm = GetCurrentVM();
428 if(vm){
429 vm->Revert();
430 UpdateState();
434 void QemuMainFrame::OnToggleDisplay(wxCommandEvent& event){
435 QemuUINotebookPage* tab = notebook->GetCurrentVMTab();
436 switch(event.GetId()){
437 case QEMU_TOOLBAR_DISPLAY_INFO:
438 toolbar->ShowInfo();
439 tab->ShowInfo();
440 break;
441 case QEMU_TOOLBAR_DISPLAY_SCREEN:
442 toolbar->ShowScreen();
443 tab->ShowScreen();
444 break;
445 case QEMU_TOOLBAR_DISPLAY_CONSOLE:
446 toolbar->ShowConsole();
447 tab->ShowConsole();
448 break;
452 void QemuMainFrame::OnSendCommandToVM(wxCommandEvent& WXUNUSED(event)){
453 QemuVM *vm = GetCurrentVM();
454 if(!vm) return;
455 wxTextEntryDialog dialog(this,
456 _T("Please enter a command which will be send to the qemu monitor."),
457 _T("Please enter a command"),
458 _T(""),
459 wxOK | wxCANCEL
462 if (dialog.ShowModal() == wxID_OK){
463 wxMessageBox(vm->SendCommand(dialog.GetValue(),true), wxT("Response"), wxOK | wxICON_INFORMATION, this);
464 //wxLogError(vm->SendCommand(dialog.GetValue()));
468 void QemuMainFrame::OnNotebookPageChanged(wxNotebookEvent& event){
469 const size_t pos = event.GetSelection();
470 menubar->CheckWindowMenuEntry(pos);
471 UpdateState();
474 void QemuMainFrame::CloseNotebookPage(const int pos){
475 QemuVM *vm = GetCurrentVM();
477 if(!vm){
478 notebook->CloseHomepage();
479 menubar->RemoveWindowMenuEntry(pos);
480 return;
483 if(vm->IsRunning() &&
484 wxMessageBox(_("Do you really want to close this VM?"),_("Question"),
485 wxICON_QUESTION | wxYES_NO, this) != wxYES){
486 return;
489 wxNotebookPage *page = notebook->GetCurrentPage();
490 if(page){
491 vm->PowerOff();
492 vms.Remove(vm);
493 delete vm;
494 menubar->RemoveWindowMenuEntry(pos);
495 notebook->RemovePage(pos);
496 delete page;
497 UpdateState();
501 void QemuMainFrame::OnNotebookPageClosed(wxCommandEvent& WXUNUSED(event)){
502 CloseNotebookPage(notebook->GetSelection());
505 void QemuMainFrame::UpdateState(){
506 QemuUINotebookPage *tab = GetCurrentVMTab();
508 if(!tab){
509 menubar->Disable();
510 toolbar->Disable();
511 statusbar->Disable();
512 return;
515 QemuVM *vm = tab->GetVM();
516 menubar->Settings(!vm->IsRunning());
517 menubar->SendCtrlAltDel(vm->IsRunning());
518 menubar->PowerOn(!vm->IsRunning());
519 menubar->PowerOff(vm->IsRunning() || vm->IsPaused());
520 menubar->Pause(vm->IsRunning());
521 menubar->Reset(vm->IsRunning() || vm->IsPaused());
522 toolbar->PowerOn(!vm->IsRunning());
523 toolbar->PowerOff(vm->IsRunning() || vm->IsPaused());
524 toolbar->Pause(vm->IsRunning());
525 toolbar->Reset(vm->IsRunning() || vm->IsPaused());
526 toolbar->Kill(vm->IsRunning());
527 toolbar->Snapshot(vm->IsRunning());
528 toolbar->RevertSnapshot(vm->GetPID() > 0 && vm->HasSnapshot());
529 toolbar->EnableDisplayArea();
530 toolbar->EnableDisplayScreen(!vm->IsPoweredOff());
531 toolbar->SendVMCommand(!vm->IsPoweredOff());
533 if(tab->IsConsoleActive())
534 toolbar->ShowConsole();
535 else if(tab->IsScreenActive())
536 toolbar->ShowScreen();
537 else
538 toolbar->ShowInfo();
540 tab->GetConsole()->SetState(!vm->IsPoweredOff());
542 if(vm->IsRunning())
543 statusbar->Enable();
544 else
545 statusbar->Disable();
548 void QemuMainFrame::OnConnectCdRom(wxCommandEvent& event){
549 GetCurrentVM()->ConnectCdRom(event.IsChecked());
552 void QemuMainFrame::SaveFileHistory(wxConfigBase *config){
553 //config->SetPath(wxT("/filehistory"));
554 filehistory->Save(*config);
555 //config->SetPath(wxT("/"));
558 void QemuMainFrame::LoadFileHistory(wxConfigBase *config){
559 //config->SetPath(wxT("/filehistory"));
560 filehistory->Load(*config);
561 menubar->UpdateFileHistory(filehistory->GetCount());
562 //config->SetPath(wxT("/"));