1 /* qtmenupeer.cpp --
2    Copyright (C)  2005  Free Software Foundation, Inc.
3 
4 This file is part of GNU Classpath.
5 
6 GNU Classpath is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
9 any later version.
10 
11 GNU Classpath is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 General Public License for more details.
15 
16 You should have received a copy of the GNU General Public License
17 along with GNU Classpath; see the file COPYING.  If not, write to the
18 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19 02110-1301 USA.
20 
21 Linking this library statically or dynamically with other modules is
22 making a combined work based on this library.  Thus, the terms and
23 conditions of the GNU General Public License cover the whole
24 combination.
25 
26 As a special exception, the copyright holders of this library give you
27 permission to link this library with independent modules to produce an
28 executable, regardless of the license terms of these independent
29 modules, and to copy and distribute the resulting executable under
30 terms of your choice, provided that you also meet, for each linked
31 independent module, the terms and conditions of the license of that
32 module.  An independent module is a module which is not derived from
33 or based on this library.  If you modify this library, you may extend
34 this exception to your version of the library, but you are not
35 obligated to do so.  If you do not wish to do so, delete this
36 exception statement from your version. */
37 
38 #include <assert.h>
39 #include <QMenu>
40 #include <gnu_java_awt_peer_qt_QtMenuPeer.h>
41 #include "nativewrapper.h"
42 #include "qtstrings.h"
43 #include "mainthreadinterface.h"
44 #include "slotcallbacks.h"
45 #include "componentevent.h"
46 
47 #define ADDMENU 0
48 #define ADDITEM 1
49 #define ADDSEPA 2
50 
51 // Sets the title, but also tear-off.
52 class MenuTitleEvent : public AWTEvent {
53 
54  private:
55   QMenu *widget;
56   QString *string;
57   bool tearOff;
58 
59  public:
MenuTitleEvent(QMenu * w,QString * s,bool tear)60   MenuTitleEvent(QMenu *w, QString *s, bool tear) : AWTEvent()
61   {
62     widget = w;
63     string = s;
64     tearOff = tear;
65   }
66 
runEvent()67   void runEvent()
68   {
69     if (tearOff)
70       widget->setTearOffEnabled( true );
71     else
72       {
73 	widget->setTitle( *string );
74 	delete string;
75       }
76   }
77 };
78 
79 class MenuAction : public AWTEvent {
80 
81  private:
82   QMenu *menu;
83   QAction *action;
84   int isMenu; // 0 to add a menu, 1 to add an item, 2 to add a seperator
85   JavaVM *vm;
86   jobject menuPeer;
87   jobject itemPeer;
88 
89 public:
MenuAction(JNIEnv * env,jobject mp,jobject ip,QMenu * m,QAction * a,bool ismenu)90   MenuAction(JNIEnv *env, jobject mp, jobject ip, QMenu *m, QAction *a,
91 	     bool ismenu) : AWTEvent()
92   {
93     menu = m;
94     action = a;
95     isMenu = ismenu;
96     env->GetJavaVM( &vm );
97     menuPeer = env->NewGlobalRef( mp );
98     if( ip != NULL )
99       itemPeer = env->NewGlobalRef( ip );
100     else
101       itemPeer = NULL;
102   }
103 
runEvent()104   void runEvent()
105   {
106     JNIEnv *env;
107     QAction *newAction; // adding an action creates a new duplicate.
108     vm->GetEnv((void **)&env, JNI_VERSION_1_1);
109 
110     switch(isMenu)
111       {
112       case ADDMENU:
113 	newAction = menu->addMenu( (QMenu *)action );
114 	break;
115       case ADDITEM:
116 	newAction = menu->addAction(action->text());
117 	newAction->setSeparator(action->isSeparator());
118 	newAction->setCheckable(action->isCheckable());
119 	//	delete action;
120 	break;
121       case ADDSEPA:
122 	newAction = menu->addSeparator();
123 	break;
124       }
125 
126     jclass menuCls = env->GetObjectClass( menuPeer );
127     jmethodID mid = env->GetMethodID(menuCls, "add", "(J)V");
128     env->CallVoidMethod( menuPeer, mid, (jlong)newAction );
129 
130     env->DeleteGlobalRef( menuPeer );
131     if( itemPeer != NULL )
132       {
133 	setNativeObject( env, itemPeer, newAction );
134 	connectAction(newAction, env, itemPeer);
135 	env->DeleteGlobalRef( itemPeer );
136       }
137   }
138 };
139 
140 class MenuRemoveAction : public AWTEvent {
141 
142  private:
143   QMenu *menu;
144   QAction *action;
145 
146 public:
MenuRemoveAction(QMenu * m,QAction * a)147   MenuRemoveAction(QMenu *m, QAction *a) : AWTEvent()
148   {
149     menu = m;
150     action = a;
151   }
152 
runEvent()153   void runEvent()
154   {
155     if (action)
156       menu->removeAction(action);
157   }
158 };
159 
160 /*
161  * Constructs a QMenu item
162  */
Java_gnu_java_awt_peer_qt_QtMenuPeer_init(JNIEnv * env,jobject obj)163 JNIEXPORT void JNICALL Java_gnu_java_awt_peer_qt_QtMenuPeer_init
164 (JNIEnv *env, jobject obj)
165 {
166   QMenu *menu = new QMenu();
167   assert( menu );
168 
169   setNativeObject( env, obj, menu );
170 }
171 
172 /**
173  * Allows tear-off: Only called once, if ever.
174  */
Java_gnu_java_awt_peer_qt_QtMenuPeer_allowTearOff(JNIEnv * env,jobject obj)175 JNIEXPORT void JNICALL Java_gnu_java_awt_peer_qt_QtMenuPeer_allowTearOff
176 (JNIEnv *env, jobject obj)
177 {
178   QMenu *menu = (QMenu *)getNativeObject( env, obj );
179   assert( menu );
180   mainThread->postEventToMain( new MenuTitleEvent( menu, NULL, true ) );
181 }
182 
183 /*
184  * Inserts a seperator.
185  */
Java_gnu_java_awt_peer_qt_QtMenuPeer_insertSeperator(JNIEnv * env,jobject obj)186 JNIEXPORT void JNICALL Java_gnu_java_awt_peer_qt_QtMenuPeer_insertSeperator
187 (JNIEnv *env, jobject obj)
188 {
189   QMenu *menu = (QMenu *)getNativeObject( env, obj );
190   assert( menu );
191   mainThread->postEventToMain( new MenuAction( env, obj, NULL,
192 					       menu, NULL, ADDSEPA ) );
193 }
194 
195 /*
196  * Inserts an item.
197  */
Java_gnu_java_awt_peer_qt_QtMenuPeer_insertItem(JNIEnv * env,jobject obj,jobject item)198 JNIEXPORT void JNICALL Java_gnu_java_awt_peer_qt_QtMenuPeer_insertItem
199 (JNIEnv *env, jobject obj, jobject item)
200 {
201   QMenu *menu = (QMenu *)getNativeObject( env, obj );
202   assert( menu );
203 
204   QAction *action = (QAction *)getNativeObject( env, item );
205   assert( action );
206 
207   mainThread->postEventToMain( new MenuAction( env, obj, item, menu, action, ADDITEM ));
208 }
209 
210 /*
211  * Inserts a sub-menu
212  */
Java_gnu_java_awt_peer_qt_QtMenuPeer_insertMenu(JNIEnv * env,jobject obj,jobject menu)213 JNIEXPORT void JNICALL Java_gnu_java_awt_peer_qt_QtMenuPeer_insertMenu
214 (JNIEnv *env, jobject obj, jobject menu)
215 {
216   assert( menu );
217   QMenu *thisMenu = (QMenu *)getNativeObject( env, obj );
218   assert( thisMenu );
219   QMenu *insMenu = (QMenu *)getNativeObject(env, menu);
220   assert( insMenu );
221 
222   mainThread->postEventToMain( new MenuAction( env, obj, menu, thisMenu, (QAction *)insMenu, ADDMENU ) );
223 }
224 
225 /*
226  * Removes an item at index.
227  */
Java_gnu_java_awt_peer_qt_QtMenuPeer_delItem(JNIEnv * env,jobject obj,jlong ptr)228 JNIEXPORT void JNICALL Java_gnu_java_awt_peer_qt_QtMenuPeer_delItem
229 (JNIEnv *env, jobject obj, jlong ptr)
230 {
231   QMenu *menu = (QMenu *)getNativeObject( env, obj );
232   assert( menu );
233   QAction *action = (QAction *)ptr;
234 
235   mainThread->postEventToMain( new MenuRemoveAction( menu, action ) );
236 }
237 
238 /*
239  * Enables/Disables the menu.
240  */
Java_gnu_java_awt_peer_qt_QtMenuPeer_setEnabled(JNIEnv * env,jobject obj,jboolean enabled)241 JNIEXPORT void JNICALL Java_gnu_java_awt_peer_qt_QtMenuPeer_setEnabled
242 (JNIEnv *env, jobject obj, jboolean enabled)
243 {
244   QMenu *menu = (QMenu *)getNativeObject( env, obj );
245   assert( menu );
246 
247   mainThread->postEventToMain(new AWTEnableEvent(menu, (enabled == JNI_TRUE)));
248 }
249 
250 /*
251  * Sets the menu title.
252  */
Java_gnu_java_awt_peer_qt_QtMenuPeer_setLabel(JNIEnv * env,jobject obj,jstring label)253 JNIEXPORT void JNICALL Java_gnu_java_awt_peer_qt_QtMenuPeer_setLabel
254 (JNIEnv *env, jobject obj, jstring label)
255 {
256   if(label == NULL)
257     return;
258 
259   QMenu *menu = (QMenu *)getNativeObject( env, obj );
260   assert( menu );
261   QString *qStr = getQString(env, label);
262   mainThread->postEventToMain( new MenuTitleEvent( menu, qStr, false ) );
263 }
264 
265