Fixed build with Ubuntu Disco
[amule.git] / src / MuleNotebook.cpp
blob0c7d7695cc67e1d4f55e63875a036c429632b766
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.
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.
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.
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
26 #include <wx/menu.h>
27 #include <wx/intl.h>
29 #include "MuleNotebook.h" // Interface declarations
31 #include <common/MenuIDs.h>
33 DEFINE_LOCAL_EVENT_TYPE(wxEVT_COMMAND_MULENOTEBOOK_PAGE_CLOSING)
34 DEFINE_LOCAL_EVENT_TYPE(wxEVT_COMMAND_MULENOTEBOOK_ALL_PAGES_CLOSED)
36 #if MULE_NEEDS_DELETEPAGE_WORKAROUND
37 DEFINE_LOCAL_EVENT_TYPE(wxEVT_COMMAND_MULENOTEBOOK_DELETE_PAGE)
38 #endif
40 BEGIN_EVENT_TABLE(CMuleNotebook, wxNotebook)
41 EVT_RIGHT_DOWN(CMuleNotebook::OnRMButton)
43 EVT_MENU(MP_CLOSE_TAB, CMuleNotebook::OnPopupClose)
44 EVT_MENU(MP_CLOSE_ALL_TABS, CMuleNotebook::OnPopupCloseAll)
45 EVT_MENU(MP_CLOSE_OTHER_TABS, CMuleNotebook::OnPopupCloseOthers)
47 // Madcat - tab closing engine
48 EVT_LEFT_DOWN(CMuleNotebook::OnMouseButton)
49 EVT_LEFT_UP(CMuleNotebook::OnMouseButton)
50 EVT_MIDDLE_DOWN(CMuleNotebook::OnMouseButton)
51 EVT_MIDDLE_UP(CMuleNotebook::OnMouseButton)
52 EVT_MOTION(CMuleNotebook::OnMouseMotion)
53 #if MULE_NEEDS_DELETEPAGE_WORKAROUND
54 EVT_MULENOTEBOOK_DELETE_PAGE(wxID_ANY, CMuleNotebook::OnDeletePage)
55 #endif
56 END_EVENT_TABLE()
59 CMuleNotebook::CMuleNotebook( wxWindow *parent, wxWindowID id, const wxPoint& pos, const wxSize& size, long style, const wxString& name )
60 : wxNotebook(parent, id, pos, size, style, name)
62 m_popup_enable = true;
63 m_popup_widget = NULL;
67 CMuleNotebook::~CMuleNotebook()
69 // Ensure that all notifications gets sent
70 DeleteAllPages();
74 #if MULE_NEEDS_DELETEPAGE_WORKAROUND
75 void CMuleNotebook::OnDeletePage(wxBookCtrlEvent& evt)
77 int page = evt.GetSelection();
78 DeletePage(page);
80 #endif // MULE_NEEDS_DELETEPAGE_WORKAROUND
83 bool CMuleNotebook::DeletePage(int nPage)
85 wxCHECK_MSG((nPage >= 0) && (nPage < (int)GetPageCount()), false,
86 wxT("Trying to delete invalid page-index in CMuleNotebook::DeletePage"));
88 // Send out close event
89 wxNotebookEvent evt( wxEVT_COMMAND_MULENOTEBOOK_PAGE_CLOSING, GetId(), nPage );
90 evt.SetEventObject(this);
91 ProcessEvent( evt );
93 // and finally remove the actual page
94 bool result = wxNotebook::DeletePage( nPage );
96 // Ensure a valid selection
97 if ( GetPageCount() && (int)GetSelection() >= (int)GetPageCount() ) {
98 SetSelection( GetPageCount() - 1 );
101 // Send a page change event to work around wx problem when newly selected page
102 // is identical with deleted page (wx sends a page change event during deletion,
103 // but the control is still the one to be deleted at that moment).
104 if (GetPageCount()) {
105 // Select the tab that took the place of the one we just deleted.
106 size_t page = nPage;
107 // Except if we deleted the last one - then select the one that is last now.
108 if (page == GetPageCount()) {
109 page--;
111 wxNotebookEvent event( wxEVT_COMMAND_NOTEBOOK_PAGE_CHANGED, GetId(), page );
112 event.SetEventObject(this);
113 ProcessEvent( event );
114 } else {
115 // Send an event when no pages are left open
116 wxNotebookEvent event( wxEVT_COMMAND_MULENOTEBOOK_ALL_PAGES_CLOSED, GetId() );
117 event.SetEventObject(this);
118 ProcessEvent( event );
121 return result;
125 bool CMuleNotebook::DeleteAllPages()
127 Freeze();
129 bool result = true;
130 while ( GetPageCount() ) {
131 result &= DeletePage( 0 );
134 Thaw();
136 return result;
140 void CMuleNotebook::EnablePopup( bool enable )
142 m_popup_enable = enable;
146 void CMuleNotebook::SetPopupHandler( wxWindow* widget )
148 m_popup_widget = widget;
152 //#warning wxMac does not support selection by right-clicking on tabs!
153 void CMuleNotebook::OnRMButton(wxMouseEvent& event)
155 // Cases where we shouldn't be showing a popup-menu.
156 if ( !GetPageCount() || !m_popup_enable ) {
157 event.Skip();
158 return;
162 // For some reason, gtk1 does a rather poor job when using the HitTest
163 wxPoint eventPoint = event.GetPosition();
165 int tab = HitTest(eventPoint);
166 if (tab != wxNOT_FOUND) {
167 SetSelection(tab);
168 } else {
169 event.Skip();
170 return;
173 // Should we send the event to a specific widget?
174 if ( m_popup_widget ) {
175 wxMouseEvent evt = event;
177 // Map the coordinates onto the parent
178 wxPoint point = evt.GetPosition();
179 point = ClientToScreen( point );
180 point = m_popup_widget->ScreenToClient( point );
182 evt.m_x = point.x;
183 evt.m_y = point.y;
185 m_popup_widget->GetEventHandler()->AddPendingEvent( evt );
186 } else {
187 wxMenu menu(_("Close"));
188 menu.Append(MP_CLOSE_TAB, wxString(_("Close tab")));
189 menu.Append(MP_CLOSE_ALL_TABS, wxString(_("Close all tabs")));
190 menu.Append(MP_CLOSE_OTHER_TABS, wxString(_("Close other tabs")));
192 PopupMenu( &menu, event.GetPosition() );
197 void CMuleNotebook::OnPopupClose(wxCommandEvent& WXUNUSED(evt))
199 DeletePage( GetSelection() );
203 void CMuleNotebook::OnPopupCloseAll(wxCommandEvent& WXUNUSED(evt))
205 DeleteAllPages();
209 void CMuleNotebook::OnPopupCloseOthers(wxCommandEvent& WXUNUSED(evt))
211 wxNotebookPage* current = GetPage( GetSelection() );
213 for ( int i = GetPageCount() - 1; i >= 0; i-- ) {
214 if ( current != GetPage( i ) )
215 DeletePage( i );
220 void CMuleNotebook::OnMouseButton(wxMouseEvent &event)
222 if (GetImageList() == NULL) {
223 // This Mulenotebook has no images on tabs, so nothing to do.
224 event.Skip();
225 return;
228 long xpos, ypos;
229 event.GetPosition(&xpos, &ypos);
231 long flags = 0;
232 int tab = HitTest(wxPoint(xpos,ypos),&flags);
233 static int tab_down_icon = -1;
234 static int tab_down_label = -1;
236 if (event.LeftDown() && (flags == wxNB_HITTEST_ONICON)) {
237 tab_down_icon = tab;
239 else if (event.MiddleDown() && (flags == wxNB_HITTEST_ONLABEL)) {
240 tab_down_label = tab;
242 else if (event.LeftDown() || event.MiddleDown()) {
243 tab_down_icon = -1;
244 tab_down_label = -1;
247 if (((tab != -1) && (((flags == wxNB_HITTEST_ONICON) && event.LeftUp() && (tab == tab_down_icon)) ||
248 ((flags == wxNB_HITTEST_ONLABEL) && event.MiddleUp() && (tab == tab_down_label))))) {
249 // User did click on a 'x' or middle click on the label
250 tab_down_icon = -1;
251 tab_down_label = -1;
252 #if MULE_NEEDS_DELETEPAGE_WORKAROUND
253 /* WORKAROUND: Instead of calling DeletePage, we need to wait for the
254 * mouse release signal to reach Gtk. Inconsistent with normal wxEvent
255 * behaviour the button release handler in wxWidgets don't evaluate
256 * the result of the signal handling. */
257 wxNotebookEvent evt( wxEVT_COMMAND_MULENOTEBOOK_DELETE_PAGE, GetId(), tab );
258 evt.SetEventObject(this);
259 AddPendingEvent( evt );
260 #else
261 DeletePage(tab);
262 #endif // MULE_NEEDS_DELETEPAGE_WORKAROUND
263 } else {
264 // Is not a 'x'. Send this event up.
265 event.Skip();
270 void CMuleNotebook::OnMouseMotion(wxMouseEvent &event)
272 if (GetImageList() == NULL) {
273 // This Mulenotebook has no images on tabs, so nothing to do.
274 event.Skip();
275 return;
278 long flags = 0;
279 int tab = HitTest(wxPoint(event.m_x,event.m_y),&flags);
281 // Clear the highlight for all tabs.
282 for (int i=0;i<(int)GetPageCount();++i) {
283 SetPageImage(i, 0);
286 if ((tab != -1) && (flags == wxNB_HITTEST_ONICON)) {
287 // Mouse is over a 'x'
288 SetPageImage(tab, 1);
289 } else {
290 // Is not a 'x'. Send this event up.
291 event.Skip();
295 // File_checked_for_headers