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 typedef enum ActionType {
48   ActionMenu,
49   ActionItem,
50   ActionSeparator
51 } ActionType;
52 
53 // Sets the title, but also tear-off.
54 class MenuTitleEvent : public AWTEvent {
55 
56  private:
57   QMenu *widget;
58   QString *string;
59   bool tearOff;
60 
61  public:
MenuTitleEvent(QMenu * w,QString * s,bool tear)62   MenuTitleEvent(QMenu *w, QString *s, bool tear) : AWTEvent()
63   {
64     widget = w;
65     string = s;
66     tearOff = tear;
67   }
68 
runEvent()69   void runEvent()
70   {
71     if (tearOff)
72       widget->setTearOffEnabled( true );
73     else
74       {
75 	widget->setTitle( *string );
76 	delete string;
77       }
78   }
79 };
80 
81 class MenuAction : public AWTEvent {
82 
83  private:
84   QMenu *menu;
85   QAction *action;
86   ActionType actionType; // type of action to add
87   JavaVM *vm;
88   jobject menuPeer;
89   jobject itemPeer;
90 
91 public:
MenuAction(JNIEnv * env,jobject mp,jobject ip,QMenu * m,QAction * a,ActionType actionType)92   MenuAction(JNIEnv *env, jobject mp, jobject ip, QMenu *m, QAction *a,
93 	     ActionType actionType) : AWTEvent()
94   {
95     menu = m;
96     action = a;
97     this->actionType = actionType;
98     env->GetJavaVM( &vm );
99     menuPeer = env->NewGlobalRef( mp );
100     if( ip != NULL )
101       itemPeer = env->NewGlobalRef( ip );
102     else
103       itemPeer = NULL;
104   }
105 
runEvent()106   void runEvent()
107   {
108     JNIEnv *env;
109     vm->GetEnv((void **)&env, JNI_VERSION_1_1);
110     if (actionType == ActionMenu)
111       menu->addMenu ((QMenu *) action);
112     else
113       menu->addAction (action);
114 
115     jclass menuCls = env->GetObjectClass( menuPeer );
116     jmethodID mid = env->GetMethodID(menuCls, "add", "(J)V");
117     env->DeleteLocalRef(menuCls);
118     env->CallVoidMethod( menuPeer, mid, (jlong)action );
119 
120     env->DeleteGlobalRef( menuPeer );
121     if( itemPeer != NULL )
122       {
123 	setNativeObject( env, itemPeer, action );
124 	connectAction(action, env, itemPeer);
125 	env->DeleteGlobalRef( itemPeer );
126       }
127   }
128 };
129 
130 class MenuRemoveAction : public AWTEvent {
131 
132  private:
133   QMenu *menu;
134   QAction *action;
135 
136 public:
MenuRemoveAction(QMenu * m,QAction * a)137   MenuRemoveAction(QMenu *m, QAction *a) : AWTEvent()
138   {
139     menu = m;
140     action = a;
141   }
142 
runEvent()143   void runEvent()
144   {
145     if (action)
146       menu->removeAction(action);
147   }
148 };
149 
150 /*
151  * Constructs a QMenu item
152  */
Java_gnu_java_awt_peer_qt_QtMenuPeer_init(JNIEnv * env,jobject obj)153 JNIEXPORT void JNICALL Java_gnu_java_awt_peer_qt_QtMenuPeer_init
154 (JNIEnv *env, jobject obj)
155 {
156   QMenu *menu = new QMenu();
157   assert( menu );
158 
159   setNativeObject( env, obj, menu );
160 }
161 
162 /**
163  * Allows tear-off: Only called once, if ever.
164  */
Java_gnu_java_awt_peer_qt_QtMenuPeer_allowTearOff(JNIEnv * env,jobject obj)165 JNIEXPORT void JNICALL Java_gnu_java_awt_peer_qt_QtMenuPeer_allowTearOff
166 (JNIEnv *env, jobject obj)
167 {
168   QMenu *menu = (QMenu *)getNativeObject( env, obj );
169   assert( menu );
170   mainThread->postEventToMain( new MenuTitleEvent( menu, NULL, true ) );
171 }
172 
173 /*
174  * Inserts a seperator.
175  */
Java_gnu_java_awt_peer_qt_QtMenuPeer_insertSeperator(JNIEnv * env,jobject obj)176 JNIEXPORT void JNICALL Java_gnu_java_awt_peer_qt_QtMenuPeer_insertSeperator
177 (JNIEnv *env, jobject obj)
178 {
179   QMenu *menu = (QMenu *)getNativeObject( env, obj );
180   assert( menu );
181   mainThread->postEventToMain( new MenuAction( env, obj, NULL,
182 					       menu, NULL, ActionSeparator ) );
183 }
184 
185 /*
186  * Inserts an item.
187  */
Java_gnu_java_awt_peer_qt_QtMenuPeer_insertItem(JNIEnv * env,jobject obj,jobject item)188 JNIEXPORT void JNICALL Java_gnu_java_awt_peer_qt_QtMenuPeer_insertItem
189 (JNIEnv *env, jobject obj, jobject item)
190 {
191   QMenu *menu = (QMenu *)getNativeObject( env, obj );
192   assert( menu );
193 
194   QAction *action = (QAction *)getNativeObject( env, item );
195   assert( action );
196 
197   mainThread->postEventToMain( new MenuAction( env, obj, item, menu, action, ActionItem ));
198 }
199 
200 /*
201  * Inserts a sub-menu
202  */
Java_gnu_java_awt_peer_qt_QtMenuPeer_insertMenu(JNIEnv * env,jobject obj,jobject menu)203 JNIEXPORT void JNICALL Java_gnu_java_awt_peer_qt_QtMenuPeer_insertMenu
204 (JNIEnv *env, jobject obj, jobject menu)
205 {
206   assert( menu );
207   QMenu *thisMenu = (QMenu *)getNativeObject( env, obj );
208   assert( thisMenu );
209   QMenu *insMenu = (QMenu *)getNativeObject(env, menu);
210   assert( insMenu );
211 
212   mainThread->postEventToMain( new MenuAction( env, obj, menu, thisMenu, (QAction *)insMenu, ActionMenu ) );
213 }
214 
215 /*
216  * Removes an item at index.
217  */
Java_gnu_java_awt_peer_qt_QtMenuPeer_delItem(JNIEnv * env,jobject obj,jlong ptr)218 JNIEXPORT void JNICALL Java_gnu_java_awt_peer_qt_QtMenuPeer_delItem
219 (JNIEnv *env, jobject obj, jlong ptr)
220 {
221   QMenu *menu = (QMenu *)getNativeObject( env, obj );
222   assert( menu );
223   QAction *action = (QAction *)ptr;
224 
225   mainThread->postEventToMain( new MenuRemoveAction( menu, action ) );
226 }
227 
228 /*
229  * Enables/Disables the menu.
230  */
Java_gnu_java_awt_peer_qt_QtMenuPeer_setEnabled(JNIEnv * env,jobject obj,jboolean enabled)231 JNIEXPORT void JNICALL Java_gnu_java_awt_peer_qt_QtMenuPeer_setEnabled
232 (JNIEnv *env, jobject obj, jboolean enabled)
233 {
234   QMenu *menu = (QMenu *)getNativeObject( env, obj );
235   assert( menu );
236 
237   mainThread->postEventToMain(new AWTEnableEvent(menu, (enabled == JNI_TRUE)));
238 }
239 
240 /*
241  * Sets the menu title.
242  */
Java_gnu_java_awt_peer_qt_QtMenuPeer_setLabel(JNIEnv * env,jobject obj,jstring label)243 JNIEXPORT void JNICALL Java_gnu_java_awt_peer_qt_QtMenuPeer_setLabel
244 (JNIEnv *env, jobject obj, jstring label)
245 {
246   if(label == NULL)
247     return;
248 
249   QMenu *menu = (QMenu *)getNativeObject( env, obj );
250   assert( menu );
251   QString *qStr = getQString(env, label);
252   mainThread->postEventToMain( new MenuTitleEvent( menu, qStr, false ) );
253 }
254 
255