2 // This file is part of the aMule Project.
4 // Copyright (c) 2004-2011 Angel Vidal ( kry@amule.org )
5 // Copyright (c) 2004-2011 aMule Team ( admin@amule.org / http://www.amule.org )
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
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
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
)
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
)
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
74 #if MULE_NEEDS_DELETEPAGE_WORKAROUND
75 void CMuleNotebook::OnDeletePage(wxBookCtrlEvent
& evt
)
77 int page
= evt
.GetSelection();
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);
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.
107 // Except if we deleted the last one - then select the one that is last now.
108 if (page
== GetPageCount()) {
111 wxNotebookEvent
event( wxEVT_COMMAND_NOTEBOOK_PAGE_CHANGED
, GetId(), page
);
112 event
.SetEventObject(this);
113 ProcessEvent( event
);
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
);
125 bool CMuleNotebook::DeleteAllPages()
130 while ( GetPageCount() ) {
131 result
&= DeletePage( 0 );
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
) {
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
) {
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
);
185 m_popup_widget
->GetEventHandler()->AddPendingEvent( evt
);
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
))
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
) )
220 void CMuleNotebook::OnMouseButton(wxMouseEvent
&event
)
222 if (GetImageList() == NULL
) {
223 // This Mulenotebook has no images on tabs, so nothing to do.
229 event
.GetPosition(&xpos
, &ypos
);
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
)) {
239 else if (event
.MiddleDown() && (flags
== wxNB_HITTEST_ONLABEL
)) {
240 tab_down_label
= tab
;
242 else if (event
.LeftDown() || event
.MiddleDown()) {
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
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
);
262 #endif // MULE_NEEDS_DELETEPAGE_WORKAROUND
264 // Is not a 'x'. Send this event up.
270 void CMuleNotebook::OnMouseMotion(wxMouseEvent
&event
)
272 if (GetImageList() == NULL
) {
273 // This Mulenotebook has no images on tabs, so nothing to do.
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
) {
286 if ((tab
!= -1) && (flags
== wxNB_HITTEST_ONICON
)) {
287 // Mouse is over a 'x'
288 SetPageImage(tab
, 1);
290 // Is not a 'x'. Send this event up.
295 // File_checked_for_headers