From: Nicolas Boichat Date: Sat, 15 May 2004 15:15:53 +0000 (+0000) Subject: - wxbRestorePanel : The user can now mark/unmark a range of files selected with... X-Git-Tag: Release-1.34.3~39 X-Git-Url: https://git.sur5r.net/?a=commitdiff_plain;h=d63a5649eea93bcdf6cb9b50166c9b78ba8aa63e;p=bacula%2Fbacula - wxbRestorePanel : The user can now mark/unmark a range of files selected with shift-click or multiple files selected with ctl-click, by right-clicking or using buttons. - wxbRestorePanel : Added buttons to mark/unmark directories/files. - wxbRestorePanel : Added buttons to force to refresh the whole tree/list - wxbMainFrame : Fixed various reconnecting and disconnecting problems. - console_thread : The user can now choose the director to use when there's multiple directors in the configuration file. - wxbRestorePanel : List's columns are now resized correctly in the first directory. git-svn-id: https://bacula.svn.sourceforge.net/svnroot/bacula/trunk@1365 91ce42f0-d328-0410-95d8-f526ca767f89 --- diff --git a/bacula/src/wx-console/CHANGELOG b/bacula/src/wx-console/CHANGELOG index f40860f599..17be54a41b 100644 --- a/bacula/src/wx-console/CHANGELOG +++ b/bacula/src/wx-console/CHANGELOG @@ -1,3 +1,17 @@ +15-05-2004 : + - wxbRestorePanel : The user can now mark/unmark a range of files selected + with shift-click or multiple files selected with ctl-click, by + right-clicking or using buttons. + - wxbRestorePanel : Added buttons to mark/unmark directories/files. + - wxbRestorePanel : Added buttons to force to refresh the whole tree/list + +14-05-2004 : + - wxbMainFrame : Fixed various reconnecting and disconnecting problems. + - console_thread : The user can now choose the director to use + when there's multiple directors in the configuration file. + - wxbRestorePanel : List's columns are now resized correctly in the + first directory. + 13-05-2004 : - wxbRestorePanel : Width adjustments between the tree view window and the file view window are now possible. diff --git a/bacula/src/wx-console/TODO b/bacula/src/wx-console/TODO index d065bb19bb..9d64017ed8 100644 --- a/bacula/src/wx-console/TODO +++ b/bacula/src/wx-console/TODO @@ -1,8 +1,5 @@ general : Show nice messages boxes when errors occurs. -console_thread : Allow the user to choose his director when there's multiple - directors. - Win32 : Crash when quitting while trying to connect Mac OS X : "You must first get a unique identifier for your application, @@ -13,7 +10,13 @@ Mac OS X : "You must first get a unique identifier for your application, Mac OS X : Ask kern for the status of this distribution (who is the package releaser ?) -wxbRestorePanel : List's columns not resized correctly in the first directory. +wxbRestorePanel : Implement refresh buttons + +wxbRestorePanel : Add images in add/remove/refresh buttons + +general : replace delete by delete [] when needed + +wxbRestorePanel : disable controls when working [postponed to July:] @@ -37,16 +40,7 @@ wxbMainFrame : use more often status text wxbRestorePanel : Ask Kern for a dot command which gives restore dates for a client (with an interval, last 20 for example, or last 40 excluding last 20). - -wxbRestorePanel : Add buttons to mark/unmark directories/files. - -wxbRestorePanel : Add a button to force to refresh the whole tree - -wxbRestorePanel : There needs to be some way of marking/unmarking a range of - files selected with shift-click or multiple files selected - with ctl-click. The GTX console uses a button to mark/unmark - the selected entries. - + wxbRestorePanel : Use ".default job=RestoreFiles" to get defaults parameters when changing a restore parameter fails. @@ -59,7 +53,7 @@ GTK : Improve look wxblistctrl/wxbtreectrl : Find why events are not forwarded correctly to parent' parent, and correct bad actual implementation. - (remove wxbSplitterWindow) + (remove handler parameter in wxTreeCtrl/wxListCtrl constructor) general : find out why I had to modify string.cpp and string.h + In include/wx/string.h, replace line 195 by diff --git a/bacula/src/wx-console/console_thread.cpp b/bacula/src/wx-console/console_thread.cpp index 8f0d665f3a..e607b59b5e 100644 --- a/bacula/src/wx-console/console_thread.cpp +++ b/bacula/src/wx-console/console_thread.cpp @@ -80,6 +80,8 @@ wxString console_thread::LoadConfig(wxString configfile) { return "Error while initializing library."; } + free_config_resources(); + MSGS* msgs = (MSGS *)malloc(sizeof(MSGS)); memset(msgs, 0, sizeof(MSGS)); for (int i=1; i<=M_MAX; i++) { @@ -126,6 +128,7 @@ wxString console_thread::LoadConfig(wxString configfile) { // class constructor console_thread::console_thread() { UA_sock = NULL; + choosingdirector = false; } // class destructor @@ -165,15 +168,66 @@ void* console_thread::Entry() { csprint("Connecting...\n"); + int count = 0; + DIRRES* res[16]; /* Maximum 16 directors */ + LockRes(); - DIRRES *dir = (DIRRES *)GetNextRes(R_DIRECTOR, NULL); + DIRRES* dir; + foreach_res(dir, R_DIRECTOR) { + res[count] = dir; + count++; + if (count == 16) { + break; + } + } UnlockRes(); + + if (count == 0) { + csprint("Error : No director defined in config file.\n"); + csprint(NULL, CS_END); + csprint(NULL, CS_DISCONNECTED); + csprint(NULL, CS_TERMINATED); + #ifdef HAVE_WIN32 + Exit(); + #endif + return NULL; + } + else if (count == 1) { + directorchoosen = 1; + } + else { + while (true) { + csprint("Multiple directors found in your config file.\n"); + for (int i = 0; i < count; i++) { + if (i < 9) { + csprint(wxString(" ") << (i+1) << ": " << res[i]->hdr.name << "\n"); + } + else { + csprint(wxString(" ") << (i+1) << ": " << res[i]->hdr.name << "\n"); + } + } + csprint(wxString("Please choose a director (1-") << count << ") : "); + csprint(NULL, CS_PROMPT); + choosingdirector = true; + directorchoosen = -1; + while(directorchoosen == -1) { + bmicrosleep(0, 2000); + Yield(); + } + choosingdirector = false; + if (directorchoosen != 0) { + break; + } + } + } memset(&jcr, 0, sizeof(jcr)); jcr.dequeuing = 1; /* TODO: catch messages */ - UA_sock = bnet_connect(&jcr, 3, 3, "Director daemon", dir->address, NULL, dir->DIRport, 0); + UA_sock = bnet_connect(&jcr, 3, 3, "Director daemon", + res[directorchoosen-1]->address, NULL, res[directorchoosen-1]->DIRport, 0); + if (UA_sock == NULL) { csprint("Failed to connect to the director\n"); csprint(NULL, CS_END); @@ -192,7 +246,7 @@ void* console_thread::Entry() { /* If cons==NULL, default console will be used */ CONRES *cons = (CONRES *)GetNextRes(R_CONSOLE, (RES *)NULL); UnlockRes(); - if (!authenticate_director(&jcr, dir, cons)) { + if (!authenticate_director(&jcr, res[directorchoosen-1], cons)) { csprint("ERR="); csprint(UA_sock->msg); csprint(NULL, CS_END); @@ -264,6 +318,17 @@ void console_thread::Write(const char* str) { pm_strcpy(&UA_sock->msg, str); bnet_send(UA_sock); } + else if (choosingdirector) { + wxString number = str; + number.RemoveLast(); /* Removes \n */ + long val; + if (number.ToLong(&val)) { + directorchoosen = (int)val; + } + else { + directorchoosen = 0; + } + } } void console_thread::Delete() { @@ -272,8 +337,8 @@ void console_thread::Delete() { bnet_sig(UA_sock, BNET_TERMINATE); /* send EOF */ bnet_close(UA_sock); UA_sock = NULL; - csprint(NULL, CS_END); + /*csprint(NULL, CS_END); csprint(NULL, CS_DISCONNECTED); - csprint(NULL, CS_TERMINATED); + csprint(NULL, CS_TERMINATED);*/ } } diff --git a/bacula/src/wx-console/console_thread.h b/bacula/src/wx-console/console_thread.h index 7f3c5ab871..723cc6326e 100644 --- a/bacula/src/wx-console/console_thread.h +++ b/bacula/src/wx-console/console_thread.h @@ -53,6 +53,11 @@ class console_thread : public wxThread private: static bool inited; static bool configloaded; + + bool choosingdirector; + + int directorchoosen; + BSOCK* UA_sock; JCR jcr; }; diff --git a/bacula/src/wx-console/wxblistctrl.cpp b/bacula/src/wx-console/wxblistctrl.cpp index f74755c82a..a4db96ba33 100644 --- a/bacula/src/wx-console/wxblistctrl.cpp +++ b/bacula/src/wx-console/wxblistctrl.cpp @@ -37,8 +37,9 @@ END_EVENT_TABLE() DEFINE_LOCAL_EVENT_TYPE(wxbLIST_MARKED_EVENT) wxbListCtrl::wxbListCtrl( - wxWindow* parent, wxWindowID id, const wxPoint& pos, const wxSize& size): + wxWindow* parent, wxEvtHandler* handler, wxWindowID id, const wxPoint& pos, const wxSize& size): wxListCtrl(parent, id, pos, size, wxLC_REPORT | wxSUNKEN_BORDER) { + this->handler = handler; } wxbListCtrl::~wxbListCtrl() {} @@ -50,7 +51,7 @@ void wxbListCtrl::OnDoubleClicked(wxMouseEvent& event) { if (event.GetX() < GetColumnWidth(0)) { wxbListMarkedEvent evt(GetId()); - GetParent()->GetEventHandler()->ProcessEvent(evt); + handler->ProcessEvent(evt); //No Skip : we don't want to go in this directory (if it is a directory) } @@ -65,7 +66,7 @@ void wxbListCtrl::OnDoubleClicked(wxMouseEvent& event) { void wxbListCtrl::OnRightClicked(wxMouseEvent& event) { wxbListMarkedEvent evt(GetId()); - GetParent()->GetEventHandler()->ProcessEvent(evt); + handler->ProcessEvent(evt); } /* Customized tree event, used for marking events */ diff --git a/bacula/src/wx-console/wxblistctrl.h b/bacula/src/wx-console/wxblistctrl.h index c069a4eb64..6e939f121d 100644 --- a/bacula/src/wx-console/wxblistctrl.h +++ b/bacula/src/wx-console/wxblistctrl.h @@ -61,13 +61,15 @@ typedef void (wxEvtHandler::*wxListMarkedEventFunction)(wxbListMarkedEvent&); /* Customized list, which transmit double clicks on images */ class wxbListCtrl: public wxListCtrl { public: - wxbListCtrl(wxWindow* parent, wxWindowID id, const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize); + wxbListCtrl(wxWindow* parent, wxEvtHandler* handler, wxWindowID id, const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize); ~wxbListCtrl(); private: void OnDoubleClicked(wxMouseEvent& event); void OnRightClicked(wxMouseEvent& event); + wxEvtHandler* handler; + DECLARE_EVENT_TABLE(); }; diff --git a/bacula/src/wx-console/wxbmainframe.cpp b/bacula/src/wx-console/wxbmainframe.cpp index 51d0e0e904..c61c574216 100644 --- a/bacula/src/wx-console/wxbmainframe.cpp +++ b/bacula/src/wx-console/wxbmainframe.cpp @@ -41,6 +41,8 @@ #include +#undef Yield /* MinGW defines Yield */ + // ---------------------------------------------------------------------------- // event tables and other macros for wxWindows // ---------------------------------------------------------------------------- @@ -309,6 +311,8 @@ wxbMainFrame::wxbMainFrame(const wxString& title, const wxPoint& pos, const wxSi lockedbyconsole = false; consoleBuffer = ""; + + configfile = ""; } /* @@ -324,13 +328,12 @@ void wxbMainFrame::StartConsoleThread(const wxString& config) { if (ct != NULL) { ct->Delete(); ct = NULL; + wxTheApp->Yield(); } if (promptparser == NULL) { promptparser = new wxbPromptParser(); } - wxString configfile; - if (config == "") { if ((wxTheApp->argc == 3) && (wxString(wxTheApp->argv[1]) == "-c")) { configfile = wxTheApp->argv[2]; @@ -448,9 +451,11 @@ void wxbMainFrame::OnQuit(wxCommandEvent& WXUNUSED(event)) if (ct != NULL) { ct->Delete(); ct = NULL; + wxTheApp->Yield(); } console_thread::FreeLib(); frame = NULL; + wxTheApp->Yield(); Close(TRUE); } @@ -493,23 +498,7 @@ void wxbMainFrame::OnEditConfig(wxCommandEvent& event) { } void wxbMainFrame::OnConnect(wxCommandEvent& event) { - menuFile->Enable(MenuConnect, false); - menuFile->Enable(MenuDisconnect, false); - menuFile->Enable(ChangeConfigFile, false); - menuFile->Enable(EditConfigFile, false); - - if (ct != NULL) { - ct->Delete(); - ct = NULL; - } - if (promptparser == NULL) { - promptparser = new wxbPromptParser(); - } - - ct = new console_thread(); - ct->Create(); - ct->Run(); - SetStatusText("Connecting to the director..."); + StartConsoleThread(configfile); } void wxbMainFrame::OnDisconnect(wxCommandEvent& event) { @@ -572,7 +561,7 @@ void wxbMainFrame::Print(wxString str, int status) menuFile->Enable(MenuConnect, true); menuFile->SetLabel(MenuConnect, "Reconnect"); menuFile->SetHelpString(MenuConnect, "Reconnect to the director"); - menuFile->Enable(MenuDisconnect, false); + menuFile->Enable(MenuDisconnect, true); menuFile->Enable(ChangeConfigFile, true); menuFile->Enable(EditConfigFile, true); return; @@ -658,7 +647,7 @@ void wxbMainFrame::Print(wxString str, int status) if (lockedbyconsole) { EnableConsole(true); } - consoleBuffer << "

"; + //consoleBuffer << "

"; } if ((status == CS_END) || (status == CS_PROMPT) || (str.Find("\n") > -1)) { diff --git a/bacula/src/wx-console/wxbmainframe.h b/bacula/src/wx-console/wxbmainframe.h index a1abc3a770..3dab968191 100644 --- a/bacula/src/wx-console/wxbmainframe.h +++ b/bacula/src/wx-console/wxbmainframe.h @@ -151,7 +151,9 @@ private: bool lockedbyconsole; /* true if the panels have been locked by something typed in the console */ - wxString consoleBuffer; + wxString configfile; /* configfile used */ + + wxString consoleBuffer; /* Buffer used to print in the console line by line */ // any class wishing to process wxWindows events must use this macro DECLARE_EVENT_TABLE() diff --git a/bacula/src/wx-console/wxbrestorepanel.cpp b/bacula/src/wx-console/wxbrestorepanel.cpp index 2684abb0f0..4f4ac64dd6 100644 --- a/bacula/src/wx-console/wxbrestorepanel.cpp +++ b/bacula/src/wx-console/wxbrestorepanel.cpp @@ -24,13 +24,13 @@ */ /* Note concerning "done" output (modifiable marked with +) Run Restore job -JobName: RestoreFiles ++JobName: RestoreFiles Bootstrap: /var/lib/bacula/restore.bsr +Where: /tmp/bacula-restores +Replace: always -FileSet: Full Set -Client: tom-fd -Storage: File ++FileSet: Full Set ++Client: tom-fd ++Storage: File +When: 2004-04-18 01:18:56 +Priority: 10 OK to run? (yes/mod/no):mod @@ -38,7 +38,7 @@ Parameters to modify: 1: Level (not appropriate) 2: Storage (automatic ?) 3: Job (no) - 4: FileSet (no) + 4: FileSet (yes) 5: Client (yes : "The defined Client resources are:\n\t1: velours-fd\n\t2: tom-fd\nSelect Client (File daemon) resource (1-2):") 6: When (yes : "Please enter desired start time as YYYY-MM-DD HH:MM:SS (return for now):") 7: Priority (yes : "Enter new Priority: (positive integer)") @@ -185,7 +185,13 @@ enum ConfigFileset = 13, ConfigStorage = 14, ConfigJobName = 15, - ConfigPool = 16 + ConfigPool = 16, + TreeAdd = 17, + TreeRemove = 18, + TreeRefresh = 19, + ListAdd = 20, + ListRemove = 21, + ListRefresh = 22 }; BEGIN_EVENT_TABLE(wxbRestorePanel, wxPanel) @@ -195,10 +201,18 @@ BEGIN_EVENT_TABLE(wxbRestorePanel, wxPanel) EVT_TREE_SEL_CHANGING(TreeCtrl, wxbRestorePanel::OnTreeChanging) EVT_TREE_SEL_CHANGED(TreeCtrl, wxbRestorePanel::OnTreeChanged) EVT_TREE_ITEM_EXPANDING(TreeCtrl, wxbRestorePanel::OnTreeExpanding) + EVT_TREE_MARKED_EVENT(TreeCtrl, wxbRestorePanel::OnTreeMarked) + EVT_BUTTON(TreeAdd, wxbRestorePanel::OnTreeAdd) + EVT_BUTTON(TreeRemove, wxbRestorePanel::OnTreeRemove) + EVT_BUTTON(TreeRefresh, wxbRestorePanel::OnTreeRefresh) + EVT_LIST_ITEM_ACTIVATED(ListCtrl, wxbRestorePanel::OnListActivated) - - /*EVT_TREE_MARKED_EVENT(wxID_ANY, wxbRestorePanel::OnTreeMarked) - EVT_LIST_MARKED_EVENT(wxID_ANY, wxbRestorePanel::OnListMarked)*/ + EVT_LIST_MARKED_EVENT(ListCtrl, wxbRestorePanel::OnListMarked) + EVT_LIST_ITEM_SELECTED(ListCtrl, wxbRestorePanel::OnListChanged) + EVT_LIST_ITEM_DESELECTED(ListCtrl, wxbRestorePanel::OnListChanged) + EVT_BUTTON(ListAdd, wxbRestorePanel::OnListAdd) + EVT_BUTTON(ListRemove, wxbRestorePanel::OnListRemove) + EVT_BUTTON(ListRefresh, wxbRestorePanel::OnListRefresh) EVT_TEXT(ConfigWhere, wxbRestorePanel::OnConfigUpdated) EVT_TEXT(ConfigWhen, wxbRestorePanel::OnConfigUpdated) @@ -216,11 +230,6 @@ BEGIN_EVENT_TABLE(wxbRestorePanel, wxPanel) EVT_BUTTON(ConfigCancel, wxbRestorePanel::OnConfigCancel) END_EVENT_TABLE() -BEGIN_EVENT_TABLE(wxbSplitterWindow, wxSplitterWindow) - EVT_TREE_MARKED_EVENT(wxID_ANY, wxbSplitterWindow::OnTreeMarked) - EVT_LIST_MARKED_EVENT(wxID_ANY, wxbSplitterWindow::OnListMarked) -END_EVENT_TABLE() - /* * wxbRestorePanel constructor */ @@ -255,17 +264,36 @@ wxbRestorePanel::wxbRestorePanel(wxWindow* parent): wxbPanel(parent) { mainSizer->Add(firstSizer, 1, wxEXPAND, 10); - //treelistPanel = new wxbTreeListPanel(this); - - //wxFlexGridSizer* treelistSizer = new wxFlexGridSizer(1, 2, 10, 10); - treelistPanel = new wxbSplitterWindow(this); + treelistPanel = new wxSplitterWindow(this); - tree = new wxbTreeCtrl(treelistPanel, TreeCtrl, wxDefaultPosition, wxSize(200,50)); - //treelistSizer->Add(tree, 1, wxEXPAND, 10); - + wxPanel* treePanel = new wxPanel(treelistPanel); + wxFlexGridSizer *treeSizer = new wxFlexGridSizer(2, 1, 0, 0); + treeSizer->AddGrowableCol(0); + treeSizer->AddGrowableRow(0); + + tree = new wxbTreeCtrl(treePanel, this, TreeCtrl, wxDefaultPosition, wxSize(200,50)); tree->SetImageList(imagelist); - list = new wxbListCtrl(treelistPanel, ListCtrl, wxDefaultPosition, wxSize(200,50)); + treeSizer->Add(tree, 1, wxEXPAND, 0); + + wxBoxSizer *treeCtrlSizer = new wxBoxSizer(wxHORIZONTAL); + treeadd = new wxButton(treePanel, TreeAdd, "Add", wxDefaultPosition, wxSize(60, 25)); + treeCtrlSizer->Add(treeadd, 0, wxLEFT | wxRIGHT, 3); + treeremove = new wxButton(treePanel, TreeRemove, "Remove", wxDefaultPosition, wxSize(60, 25)); + treeCtrlSizer->Add(treeremove, 0, wxLEFT | wxRIGHT, 3); + treerefresh = new wxButton(treePanel, TreeRefresh, "Refresh", wxDefaultPosition, wxSize(60, 25)); + treeCtrlSizer->Add(treerefresh, 0, wxLEFT | wxRIGHT, 3); + + treeSizer->Add(treeCtrlSizer, 1, wxALIGN_CENTER_HORIZONTAL, 0); + + treePanel->SetSizer(treeSizer); + + wxPanel* listPanel = new wxPanel(treelistPanel); + wxFlexGridSizer *listSizer = new wxFlexGridSizer(2, 1, 0, 0); + listSizer->AddGrowableCol(0); + listSizer->AddGrowableRow(0); + + list = new wxbListCtrl(listPanel, this, ListCtrl, wxDefaultPosition, wxSize(200,50)); //treelistSizer->Add(list, 1, wxEXPAND, 10); list->SetImageList(imagelist, wxIMAGE_LIST_SMALL); @@ -299,14 +327,24 @@ wxbRestorePanel::wxbRestorePanel(wxWindow* parent): wxbPanel(parent) { info.SetText("Group"); info.SetAlign(wxLIST_FORMAT_RIGHT); list->InsertColumn(6, info); + + listSizer->Add(list, 1, wxEXPAND, 0); + + wxBoxSizer *listCtrlSizer = new wxBoxSizer(wxHORIZONTAL); + listadd = new wxButton(listPanel, ListAdd, "Add", wxDefaultPosition, wxSize(60, 25)); + listCtrlSizer->Add(listadd, 0, wxLEFT | wxRIGHT, 5); + listremove = new wxButton(listPanel, ListRemove, "Remove", wxDefaultPosition, wxSize(60, 25)); + listCtrlSizer->Add(listremove, 0, wxLEFT | wxRIGHT, 5); + listrefresh = new wxButton(listPanel, ListRefresh, "Refresh", wxDefaultPosition, wxSize(60, 25)); + listCtrlSizer->Add(listrefresh, 0, wxLEFT | wxRIGHT, 5); - treelistPanel->SplitVertically(tree, list, 200); + listSizer->Add(listCtrlSizer, 1, wxALIGN_CENTER_HORIZONTAL, 0); - //treelistSizer->AddGrowableCol(1); - //treelistSizer->AddGrowableRow(0); + listPanel->SetSizer(listSizer); - //treelistPanel->SetSizer(treelistSizer); - //treelistSizer->SetSizeHints(treelistPanel); + treelistPanel->SplitVertically(treePanel, listPanel, 210); + + treelistPanel->SetMinimumPaneSize(210); treelistPanel->Show(false); @@ -665,7 +703,8 @@ void wxbRestorePanel::CmdStart() { wxTreeItemId root = tree->AddRoot(configPanel->GetRowString("Client"), -1, -1, new wxbTreeItemData("/", configPanel->GetRowString("Client"), 0)); currentTreeItem = root; tree->Refresh(); - UpdateTreeItem(root, true); + tree->SelectItem(root); + CmdList(root); wxbMainFrame::GetInstance()->SetStatusText("Right click on a file or on a directory, or double-click on its mark to add it to the restore list."); tree->Expand(root); } @@ -1114,23 +1153,38 @@ void wxbRestorePanel::CmdList(wxTreeItemId item) { } /* Mark a treeitem (directory) or a listitem (file or directory) */ -void wxbRestorePanel::CmdMark(wxTreeItemId treeitem, long listitem) { +void wxbRestorePanel::CmdMark(wxTreeItemId treeitem, long* listitems, int listsize, int state) { if (status == choosing) { - wxbTreeItemData* itemdata = NULL; - if (listitem != -1) { - itemdata = (wxbTreeItemData*)list->GetItemData(listitem); + wxbTreeItemData** itemdata; + int itemdatasize = 0; + if (listsize == 0) { + itemdata = new wxbTreeItemData*[1]; + itemdatasize = 1; + } + else { + itemdata = new wxbTreeItemData*[listsize]; + itemdatasize = listsize; + } + + if (listitems != NULL) { + for (int i = 0; i < listsize; i++) { + itemdata[i] = (wxbTreeItemData*)list->GetItemData(listitems[i]); + } } else if (treeitem.IsOk()) { - itemdata = (wxbTreeItemData*)tree->GetItemData(treeitem); + itemdata[0] = (wxbTreeItemData*)tree->GetItemData(treeitem); } else { + delete[] itemdata; return; } - if (itemdata == NULL) //Should never happen + if (itemdata[0] == NULL) { //Should never happen + delete[] itemdata; return; + } - wxString dir = itemdata->GetPath(); + wxString dir = itemdata[0]->GetPath(); wxString file; if (dir != "/") { @@ -1153,8 +1207,43 @@ void wxbRestorePanel::CmdMark(wxTreeItemId treeitem, long listitem) { file = "*"; } + if (state == -1) { + bool marked = false; + bool unmarked = false; + state = 0; + for (int i = 0; i < itemdatasize; i++) { + switch(itemdata[i]->GetMarked()) { + case 0: + unmarked = true; + break; + case 1: + marked = true; + break; + case 2: + marked = true; + unmarked = true; + break; + default: + break; + } + if (marked && unmarked) + break; + } + if (marked) { + if (unmarked) { + state = 1; + } + else { + state = 0; + } + } + else { + state = 1; + } + } + WaitForEnd(wxString("cd \"") << dir << "\"\n"); - WaitForEnd(wxString((itemdata->GetMarked() == 1) ? "unmark" : "mark") << " \"" << file << "\"\n"); + WaitForEnd(wxString((state==1) ? "mark" : "unmark") << " \"" << file << "\"\n"); /* TODO: Check commands results */ @@ -1162,14 +1251,16 @@ void wxbRestorePanel::CmdMark(wxTreeItemId treeitem, long listitem) { itemdata->SetMarked((itemdata->GetMarked() == 1) ? 0 : 1); }*/ - if (listitem == -1) { /* tree item state changed */ - SetTreeItemState(treeitem, (itemdata->GetMarked() == 1) ? 0 : 1); + if (listitems == NULL) { /* tree item state changed */ + SetTreeItemState(treeitem, state); /*treeitem = tree->GetSelection(); UpdateTree(treeitem, true); treeitem = tree->GetItemParent(treeitem);*/ } else { - SetListItemState(listitem, (itemdata->GetMarked() == 1) ? 0 : 1); + for (int i = 0; i < listsize; i++) { + SetListItemState(listitems[i], state); + } /*UpdateTree(treeitem, (tree->GetSelection() == treeitem)); treeitem = tree->GetItemParent(treeitem);*/ } @@ -1178,6 +1269,8 @@ void wxbRestorePanel::CmdMark(wxTreeItemId treeitem, long listitem) { WaitForList(treeitem, false); treeitem = tree->GetItemParent(treeitem); }*/ + + delete[] itemdata; } } @@ -1815,20 +1908,30 @@ void wxbRestorePanel::OnTreeChanged(wxTreeEvent& event) { if (currentTreeItem == event.GetItem()) { return; } + treeadd->Enable(false); + treeremove->Enable(false); + treerefresh->Enable(false); SetCursor(*wxHOURGLASS_CURSOR); markWhenListingDone = false; working = true; currentTreeItem = event.GetItem(); CmdList(event.GetItem()); if (markWhenListingDone) { - CmdMark(event.GetItem(), -1); + CmdMark(event.GetItem(), NULL, 0); tree->Refresh(); } working = false; SetCursor(*wxSTANDARD_CURSOR); + if (event.GetItem().IsOk()) { + int status = ((wxbTreeItemData*)tree->GetItemData(event.GetItem()))->GetMarked(); + treeadd->Enable(status != 1); + treeremove->Enable(status != 0); + } + treerefresh->Enable(true); } void wxbRestorePanel::OnTreeMarked(wxbTreeMarkedEvent& event) { + csprint("Tree marked", CS_DEBUG); if (working) { if (tree->GetSelection() == event.GetItem()) { markWhenListingDone = !markWhenListingDone; @@ -1837,13 +1940,59 @@ void wxbRestorePanel::OnTreeMarked(wxbTreeMarkedEvent& event) { } SetCursor(*wxHOURGLASS_CURSOR); working = true; - CmdMark(event.GetItem(), -1); + CmdMark(event.GetItem(), NULL, 0); //event.Skip(); tree->Refresh(); working = false; + if (event.GetItem().IsOk()) { + int status = ((wxbTreeItemData*)tree->GetItemData(event.GetItem()))->GetMarked(); + treeadd->Enable(status != 1); + treeremove->Enable(status != 0); + } SetCursor(*wxSTANDARD_CURSOR); } +void wxbRestorePanel::OnTreeAdd(wxCommandEvent& event) { + if (working) { + return; + } + + if (currentTreeItem.IsOk()) { + SetCursor(*wxHOURGLASS_CURSOR); + working = true; + CmdMark(currentTreeItem, NULL, 0, 1); + tree->Refresh(); + working = false; + treeadd->Enable(0); + treeremove->Enable(1); + SetCursor(*wxSTANDARD_CURSOR); + } +} + +void wxbRestorePanel::OnTreeRemove(wxCommandEvent& event) { + if (working) { + return; + } + + if (currentTreeItem.IsOk()) { + SetCursor(*wxHOURGLASS_CURSOR); + working = true; + CmdMark(currentTreeItem, NULL, 0, 0); + tree->Refresh(); + working = false; + treeadd->Enable(1); + treeremove->Enable(0); + SetCursor(*wxSTANDARD_CURSOR); + } +} + +void wxbRestorePanel::OnTreeRefresh(wxCommandEvent& event) { + if (working) { + return; + } + +} + void wxbRestorePanel::OnListMarked(wxbListMarkedEvent& event) { if (working) { //event.Skip(); @@ -1851,9 +2000,24 @@ void wxbRestorePanel::OnListMarked(wxbListMarkedEvent& event) { } SetCursor(*wxHOURGLASS_CURSOR); working = true; - //long item = event.GetId(); - long item = list->GetNextItem(-1, wxLIST_NEXT_ALL, wxLIST_STATE_FOCUSED); - CmdMark(wxTreeItemId(), item); + + long* items = new long[list->GetSelectedItemCount()]; + + int num = 0; + + long item = list->GetNextItem(-1, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED); + while (item != -1) { + items[num] = item; + num++; + item = list->GetNextItem(item, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED); + } + + CmdMark(wxTreeItemId(), items, num); + + delete[] items; + + OnListChanged(wxListEvent()); + event.Skip(); tree->Refresh(); working = false; @@ -1867,7 +2031,8 @@ void wxbRestorePanel::OnListActivated(wxListEvent& event) { } SetCursor(*wxHOURGLASS_CURSOR); working = true; - long item = list->GetNextItem(-1, wxLIST_NEXT_ALL, wxLIST_STATE_FOCUSED); + long item = event.GetIndex(); +// long item = list->GetNextItem(-1, wxLIST_NEXT_ALL, wxLIST_STATE_FOCUSED); if (item > -1) { wxbTreeItemData* itemdata = (wxbTreeItemData*)list->GetItemData(item); wxString name = itemdata->GetName(); @@ -1899,6 +2064,108 @@ void wxbRestorePanel::OnListActivated(wxListEvent& event) { SetCursor(*wxSTANDARD_CURSOR); } +void wxbRestorePanel::OnListChanged(wxListEvent& event) { + listadd->Enable(false); + listremove->Enable(false); + + bool marked = false; + bool unmarked = false; + + long item = list->GetNextItem(-1, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED); + while (item != -1) { + switch (((wxbTreeItemData*)list->GetItemData(item))->GetMarked()) { + case 0: + unmarked = true; + break; + case 1: + marked = true; + break; + case 2: + marked = true; + unmarked = true; + break; + default: + break; + // Should never happen + } + if (marked && unmarked) break; + item = list->GetNextItem(item, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED); + } + + listadd->Enable(unmarked); + listremove->Enable(marked); +} + +void wxbRestorePanel::OnListAdd(wxCommandEvent& WXUNUSED(event)) { + if (working) { + return; + } + + SetCursor(*wxHOURGLASS_CURSOR); + working = true; + + long* items = new long[list->GetSelectedItemCount()]; + + int num = 0; + + long item = list->GetNextItem(-1, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED); + while (item != -1) { + items[num] = item; + num++; + item = list->GetNextItem(item, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED); + } + + CmdMark(wxTreeItemId(), items, num, 1); + + delete[] items; + + tree->Refresh(); + working = false; + SetCursor(*wxSTANDARD_CURSOR); + + listadd->Enable(false); + listremove->Enable(true); +} + +void wxbRestorePanel::OnListRemove(wxCommandEvent& WXUNUSED(event)) { + if (working) { + return; + } + + SetCursor(*wxHOURGLASS_CURSOR); + working = true; + + long* items = new long[list->GetSelectedItemCount()]; + + int num = 0; + + long item = list->GetNextItem(-1, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED); + while (item != -1) { + items[num] = item; + num++; + item = list->GetNextItem(item, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED); + } + + CmdMark(wxTreeItemId(), items, num, 0); + + delete[] items; + + tree->Refresh(); + working = false; + SetCursor(*wxSTANDARD_CURSOR); + + listadd->Enable(true); + listremove->Enable(false); +} + +void wxbRestorePanel::OnListRefresh(wxCommandEvent& WXUNUSED(event)) { + if (working) { + return; + } + + +} + void wxbRestorePanel::OnConfigUpdated(wxCommandEvent& event) { if (status == entered) { if (event.GetId() == ConfigJobName) { @@ -1970,16 +2237,3 @@ void wxbRestorePanel::OnConfigCancel(wxCommandEvent& WXUNUSED(event)) { SetCursor(*wxSTANDARD_CURSOR); } -/* TODO : correct that bad implementation of tree marked event forwarding */ - -wxbSplitterWindow::wxbSplitterWindow(wxbRestorePanel* parent): wxSplitterWindow(parent, -1) { - this->parent = parent; -} - -void wxbSplitterWindow::OnTreeMarked(wxbTreeMarkedEvent& event) { - parent->OnTreeMarked(event); -} - -void wxbSplitterWindow::OnListMarked(wxbListMarkedEvent& event) { - parent->OnListMarked(event); -} diff --git a/bacula/src/wx-console/wxbrestorepanel.h b/bacula/src/wx-console/wxbrestorepanel.h index 5105c868d0..ebfb82f364 100644 --- a/bacula/src/wx-console/wxbrestorepanel.h +++ b/bacula/src/wx-console/wxbrestorepanel.h @@ -47,8 +47,6 @@ #include "wxbtreectrl.h" #include "wxblistctrl.h" -class wxbSplitterWindow; - /* * wxbPanel for restoring files */ @@ -83,8 +81,9 @@ class wxbRestorePanel : public wxbPanel /* List files and directories for a specified tree item */ void CmdList(wxTreeItemId item); - /* Mark a treeitem (directory) or a listitem (file or directory) */ - void CmdMark(wxTreeItemId treeitem, long listitem); + /* Mark a treeitem (directory) or several listitems (file or directory), + * state defines if it should mark (1), unmark (0), or switch state (-1) */ + void CmdMark(wxTreeItemId treeitem, long* listitems, int listsize, int state = -1); /* General functions and variables */ //bool ended; /* The last command send has finished */ @@ -165,12 +164,22 @@ class wxbRestorePanel : public wxbPanel /* Event handling */ void OnStart(wxCommandEvent& WXUNUSED(event)); void OnCancel(wxCommandEvent& WXUNUSED(event)); + void OnTreeChanging(wxTreeEvent& event); void OnTreeExpanding(wxTreeEvent& event); void OnTreeChanged(wxTreeEvent& event); void OnTreeMarked(wxbTreeMarkedEvent& event); + void OnTreeAdd(wxCommandEvent& WXUNUSED(event)); + void OnTreeRemove(wxCommandEvent& WXUNUSED(event)); + void OnTreeRefresh(wxCommandEvent& WXUNUSED(event)); + void OnListMarked(wxbListMarkedEvent& event); void OnListActivated(wxListEvent& event); + void OnListChanged(wxListEvent& event); + void OnListAdd(wxCommandEvent& WXUNUSED(event)); + void OnListRemove(wxCommandEvent& WXUNUSED(event)); + void OnListRefresh(wxCommandEvent& WXUNUSED(event)); + void OnConfigUpdated(wxCommandEvent& event); void OnConfigOk(wxCommandEvent& WXUNUSED(event)); void OnConfigApply(wxCommandEvent& WXUNUSED(event)); @@ -178,7 +187,7 @@ class wxbRestorePanel : public wxbPanel /* Components */ wxBoxSizer *centerSizer; /* Center sizer */ - wxbSplitterWindow *treelistPanel; /* Panel which contains tree and list */ + wxSplitterWindow *treelistPanel; /* Panel which contains tree and list */ wxbConfigPanel *configPanel; /* Panel which contains initial restore options */ wxbConfigPanel *restorePanel; /* Panel which contains final restore options */ @@ -186,40 +195,25 @@ class wxbRestorePanel : public wxbPanel wxButton* start; wxButton* cancel; + wxbTreeCtrl* tree; + wxButton* treeadd; + wxButton* treeremove; + wxButton* treerefresh; + wxbListCtrl* list; - wxGauge* gauge; - - /*wxButton* cfgOk; - wxButton* cfgApply; - wxButton* cfgCancel;*/ + wxButton* listadd; + wxButton* listremove; + wxButton* listrefresh; + wxGauge* gauge; + long cfgUpdated; //keeps which config fields have been updated - - /*wxStaticText* cfgJobname; - wxStaticText* cfgBootstrap; - wxTextCtrl* cfgWhere; - wxChoice* cfgReplace; - wxChoice* cfgFileset; - wxChoice* cfgClient; - wxStaticText* cfgStorage; - wxTextCtrl* cfgWhen; - wxTextCtrl* cfgPriority;*/ friend class wxbSplitterWindow; DECLARE_EVENT_TABLE(); }; -class wxbSplitterWindow: public wxSplitterWindow { -public: - wxbSplitterWindow(wxbRestorePanel* parent); -private: - void OnTreeMarked(wxbTreeMarkedEvent& event); - void OnListMarked(wxbListMarkedEvent& event); - DECLARE_EVENT_TABLE(); - wxbRestorePanel* parent; -}; - #endif // WXBRESTOREPANEL_H diff --git a/bacula/src/wx-console/wxbtreectrl.cpp b/bacula/src/wx-console/wxbtreectrl.cpp index 4647d07a91..8caaec3694 100644 --- a/bacula/src/wx-console/wxbtreectrl.cpp +++ b/bacula/src/wx-console/wxbtreectrl.cpp @@ -34,11 +34,12 @@ BEGIN_EVENT_TABLE(wxbTreeCtrl, wxTreeCtrl) EVT_RIGHT_DOWN(wxbTreeCtrl::OnRightClicked) END_EVENT_TABLE() -DEFINE_LOCAL_EVENT_TYPE(wxbTREE_MARKED_EVENT) +DEFINE_EVENT_TYPE(wxbTREE_MARKED_EVENT) wxbTreeCtrl::wxbTreeCtrl( - wxWindow* parent, wxWindowID id, const wxPoint& pos, const wxSize& size): + wxWindow* parent, wxEvtHandler* handler, wxWindowID id, const wxPoint& pos, const wxSize& size): wxTreeCtrl(parent, id, pos, size, wxSUNKEN_BORDER | wxTR_HAS_BUTTONS) { + this->handler = handler; } wxbTreeCtrl::~wxbTreeCtrl() {} @@ -52,7 +53,7 @@ void wxbTreeCtrl::OnDoubleClicked(wxMouseEvent& event) { if ((flags & wxTREE_HITTEST_ONITEMICON) && (treeid.IsOk())) { wxbTreeMarkedEvent evt(GetId(), treeid); - GetParent()->GetEventHandler()->ProcessEvent(evt); + handler->ProcessEvent(evt); //No Skip : we don't want this item to be collapsed or expanded } @@ -70,7 +71,7 @@ void wxbTreeCtrl::OnRightClicked(wxMouseEvent& event) { if (treeid.IsOk()) { wxbTreeMarkedEvent evt(GetId(), treeid); - GetParent()->GetEventHandler()->ProcessEvent(evt); + handler->ProcessEvent(evt); } event.Skip(); } diff --git a/bacula/src/wx-console/wxbtreectrl.h b/bacula/src/wx-console/wxbtreectrl.h index 72b4f802a9..e1710313a5 100644 --- a/bacula/src/wx-console/wxbtreectrl.h +++ b/bacula/src/wx-console/wxbtreectrl.h @@ -36,7 +36,7 @@ #include BEGIN_DECLARE_EVENT_TYPES() - DECLARE_LOCAL_EVENT_TYPE(wxbTREE_MARKED_EVENT, 1) + DECLARE_EVENT_TYPE(wxbTREE_MARKED_EVENT, 618) END_DECLARE_EVENT_TYPES() /* Customized tree event, used for marking events */ @@ -64,13 +64,15 @@ typedef void (wxEvtHandler::*wxTreeMarkedEventFunction)(wxbTreeMarkedEvent&); /* Customized tree, which transmit double clicks on images */ class wxbTreeCtrl: public wxTreeCtrl { public: - wxbTreeCtrl(wxWindow* parent, wxWindowID id, const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize); + wxbTreeCtrl(wxWindow* parent, wxEvtHandler* handler, wxWindowID id, const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize); ~wxbTreeCtrl(); private: void OnDoubleClicked(wxMouseEvent& event); void OnRightClicked(wxMouseEvent& event); + wxEvtHandler* handler; + DECLARE_EVENT_TABLE(); };