1// 2// This file is part of the aMule Project. 3// 4// Copyright (c) 2004-2011 Angel Vidal ( kry@amule.org ) 5// Copyright (c) 2004-2011 aMule Team ( admin@amule.org / http://www.amule.org ) 6// 7// Any parts of this program derived from the xMule, lMule or eMule project, 8// or contributed by third-party developers are copyrighted by their 9// respective authors. 10// 11// This program is free software; you can redistribute it and/or modify 12// it under the terms of the GNU General Public License as published by 13// the Free Software Foundation; either version 2 of the License, or 14// (at your option) any later version. 15// 16// This program is distributed in the hope that it will be useful, 17// but WITHOUT ANY WARRANTY; without even the implied warranty of 18// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 19// GNU General Public License for more details. 20// 21// You should have received a copy of the GNU General Public License 22// along with this program; if not, write to the Free Software 23// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA 24// 25 26#include <wx/menu.h> 27#include <wx/intl.h> 28 29#include "MuleNotebook.h" // Interface declarations 30 31#include <common/MenuIDs.h> 32 33DEFINE_LOCAL_EVENT_TYPE(wxEVT_COMMAND_MULENOTEBOOK_PAGE_CLOSING) 34DEFINE_LOCAL_EVENT_TYPE(wxEVT_COMMAND_MULENOTEBOOK_ALL_PAGES_CLOSED) 35 36BEGIN_EVENT_TABLE(CMuleNotebook, wxNotebook) 37 EVT_RIGHT_DOWN(CMuleNotebook::OnRMButton) 38 39 EVT_MENU(MP_CLOSE_TAB, CMuleNotebook::OnPopupClose) 40 EVT_MENU(MP_CLOSE_ALL_TABS, CMuleNotebook::OnPopupCloseAll) 41 EVT_MENU(MP_CLOSE_OTHER_TABS, CMuleNotebook::OnPopupCloseOthers) 42 43 // Madcat - tab closing engine 44 EVT_LEFT_UP(CMuleNotebook::OnMouseLeftRelease) 45 EVT_MOTION(CMuleNotebook::OnMouseMotion) 46END_EVENT_TABLE() 47 48CMuleNotebook::CMuleNotebook( wxWindow *parent, wxWindowID id, const wxPoint& pos, const wxSize& size, long style, const wxString& name ) 49 : wxNotebook(parent, id, pos, size, style, name) 50{ 51 m_popup_enable = true; 52 m_popup_widget = NULL; 53} 54 55 56CMuleNotebook::~CMuleNotebook() 57{ 58 // Ensure that all notifications gets sent 59 DeleteAllPages(); 60} 61 62 63bool CMuleNotebook::DeletePage(int nPage) 64{ 65 wxCHECK_MSG((nPage >= 0) && (nPage < (int)GetPageCount()), false, 66 wxT("Trying to delete invalid page-index in CMuleNotebook::DeletePage")); 67 68 // Send out close event 69 wxNotebookEvent evt( wxEVT_COMMAND_MULENOTEBOOK_PAGE_CLOSING, GetId(), nPage ); 70 evt.SetEventObject(this); 71 ProcessEvent( evt ); 72 73 // and finally remove the actual page 74 bool result = wxNotebook::DeletePage( nPage ); 75 76 // Ensure a valid selection 77 if ( GetPageCount() && (int)GetSelection() >= (int)GetPageCount() ) { 78 SetSelection( GetPageCount() - 1 ); 79 } 80 81 // Send a page change event to work around wx problem when newly selected page 82 // is identical with deleted page (wx sends a page change event during deletion, 83 // but the control is still the one to be deleted at that moment). 84 if (GetPageCount()) { 85 // Select the tab that took the place of the one we just deleted. 86 size_t page = nPage; 87 // Except if we deleted the last one - then select the one that is last now. 88 if (page == GetPageCount()) { 89 page--; 90 } 91 wxNotebookEvent event( wxEVT_COMMAND_NOTEBOOK_PAGE_CHANGED, GetId(), page ); 92 event.SetEventObject(this); 93 ProcessEvent( event ); 94 } else { 95 // Send an event when no pages are left open 96 wxNotebookEvent event( wxEVT_COMMAND_MULENOTEBOOK_ALL_PAGES_CLOSED, GetId() ); 97 event.SetEventObject(this); 98 ProcessEvent( event ); 99 } 100 101 return result; 102} 103 104 105bool CMuleNotebook::DeleteAllPages() 106{ 107 Freeze(); 108 109 bool result = true; 110 while ( GetPageCount() ) { 111 result &= DeletePage( 0 ); 112 } 113 114 Thaw(); 115 116 return result; 117} 118 119 120void CMuleNotebook::EnablePopup( bool enable ) 121{ 122 m_popup_enable = enable; 123} 124 125 126void CMuleNotebook::SetPopupHandler( wxWindow* widget ) 127{ 128 m_popup_widget = widget; 129} 130 131 132//#warning wxMac does not support selection by right-clicking on tabs! 133void CMuleNotebook::OnRMButton(wxMouseEvent& event) 134{ 135 // Cases where we shouldn't be showing a popup-menu. 136 if ( !GetPageCount() || !m_popup_enable ) { 137 event.Skip(); 138 return; 139 } 140 141 142// For some reason, gtk1 does a rather poor job when using the HitTest 143 wxPoint eventPoint = event.GetPosition(); 144 145 int tab = HitTest(eventPoint); 146 if (tab != wxNOT_FOUND) { 147 SetSelection(tab); 148 } else { 149 event.Skip(); 150 return; 151 } 152 153 // Should we send the event to a specific widget? 154 if ( m_popup_widget ) { 155 wxMouseEvent evt = event; 156 157 // Map the coordinates onto the parent 158 wxPoint point = evt.GetPosition(); 159 point = ClientToScreen( point ); 160 point = m_popup_widget->ScreenToClient( point ); 161 162 evt.m_x = point.x; 163 evt.m_y = point.y; 164 165 m_popup_widget->GetEventHandler()->AddPendingEvent( evt ); 166 } else { 167 wxMenu menu(_("Close")); 168 menu.Append(MP_CLOSE_TAB, wxString(_("Close tab"))); 169 menu.Append(MP_CLOSE_ALL_TABS, wxString(_("Close all tabs"))); 170 menu.Append(MP_CLOSE_OTHER_TABS, wxString(_("Close other tabs"))); 171 172 PopupMenu( &menu, event.GetPosition() ); 173 } 174} 175 176 177void CMuleNotebook::OnPopupClose(wxCommandEvent& WXUNUSED(evt)) 178{ 179 DeletePage( GetSelection() ); 180} 181 182 183void CMuleNotebook::OnPopupCloseAll(wxCommandEvent& WXUNUSED(evt)) 184{ 185 DeleteAllPages(); 186} 187 188 189void CMuleNotebook::OnPopupCloseOthers(wxCommandEvent& WXUNUSED(evt)) 190{ 191 wxNotebookPage* current = GetPage( GetSelection() ); 192 193 for ( int i = GetPageCount() - 1; i >= 0; i-- ) { 194 if ( current != GetPage( i ) ) 195 DeletePage( i ); 196 } 197} 198 199 200void CMuleNotebook::OnMouseLeftRelease(wxMouseEvent &event) 201{ 202 203 if (GetImageList() == NULL) { 204 // This Mulenotebook has no images on tabs, so nothing to do. 205 event.Skip(); 206 return; 207 } 208 209 long xpos, ypos; 210 event.GetPosition(&xpos, &ypos); 211 212 long flags = 0; 213 int tab = HitTest(wxPoint(xpos,ypos),&flags); 214 215 if ((tab != -1) && (flags == wxNB_HITTEST_ONICON)) { 216 // User did click on a 'x' 217 DeletePage(tab); 218 } else { 219 // Is not a 'x'. Send this event up. 220 event.Skip(); 221 } 222 223} 224 225void CMuleNotebook::OnMouseMotion(wxMouseEvent &event) 226{ 227 228 if (GetImageList() == NULL) { 229 // This Mulenotebook has no images on tabs, so nothing to do. 230 event.Skip(); 231 return; 232 } 233 234 long flags = 0; 235 int tab = HitTest(wxPoint(event.m_x,event.m_y),&flags); 236 237 // Clear the highlight for all tabs. 238 for (int i=0;i<(int)GetPageCount();++i) { 239 SetPageImage(i, 0); 240 } 241 242 if ((tab != -1) && (flags == wxNB_HITTEST_ONICON)) { 243 // Mouse is over a 'x' 244 SetPageImage(tab, 1); 245 } else { 246 // Is not a 'x'. Send this event up. 247 event.Skip(); 248 } 249 250} 251 252// File_checked_for_headers 253