1
/**************************************************************************\
3
* This file is part of the Coin 3D visualization library.
4
* Copyright (C) 1998-2005 by Systems in Motion. All rights reserved.
6
* This library is free software; you can redistribute it and/or
7
* modify it under the terms of the GNU General Public License
8
* ("GPL") version 2 as published by the Free Software Foundation.
9
* See the file LICENSE.GPL at the root directory of this source
10
* distribution for additional information about the GNU GPL.
12
* For using Coin with software that can not be combined with the GNU
13
* GPL, and for taking advantage of the additional benefits of our
14
* support services, please contact Systems in Motion about acquiring
15
* a Coin Professional Edition License.
17
* See <URL:http://www.coin3d.org/> for more information.
19
* Systems in Motion, Postboks 1283, Pirsenteret, 7462 Trondheim, NORWAY.
20
* <URL:http://www.sim.no/>.
22
\**************************************************************************/
24
// src/Inventor/Qt/widgets/SoQtPopupMenu.cpp. Generated from SoGuiPopupMenu.cpp.in by configure.
27
\class SoQtPopupMenu Inventor/Qt/widgets/SoQtPopupMenu.h
28
\brief The SoQtPopupMenu class implements a common interface for popup
29
menu management for all the Coin GUI toolkit libraries.
31
The point of this class is to enable client code to be exactly the
32
same for all GUI libraries, even without being template-based.
37
#endif // HAVE_CONFIG_H
41
#include <Inventor/SoLists.h>
42
#include <Inventor/errors/SoDebugError.h>
45
#include <Inventor/Qt/widgets/SoQtPopupMenu.h>
46
#include <Inventor/Qt/widgets/QtNativePopupMenu.h>
47
#include <Inventor/Qt/common/SbGuiList.h>
49
// *************************************************************************
51
// Documentation for abstract methods.
54
\fn void SoQtPopupMenu::popUp(QWidget * inside, int x, int y)
56
Invokes this popup menu instance.
58
The coordinates for the popup will be used relative to the origo of
62
// *************************************************************************
64
// The private data for the SoQtPopupMenu.
66
class SoQtPopupMenuP {
68
SbGuiList<int> menuitems;
69
SbGuiList<int> radiogroups;
75
#define PRIVATE(o) (o->pimpl)
77
// *************************************************************************
82
SoQtPopupMenu is implemented with this "factory" method instead of
83
a public constructor to provide a completely generic interface on
84
top of the toolkit's native popup menu implementation.
87
SoQtPopupMenu::createInstance(void)
89
return new QtNativePopupMenu();
94
The class constructor is protected, as SoQtPopupMenu uses a factory
97
SoQtPopupMenu::SoQtPopupMenu(void)
99
PRIVATE(this) = new SoQtPopupMenuP;
101
PRIVATE(this)->callbacks = NULL;
102
PRIVATE(this)->userdata = NULL;
108
SoQtPopupMenu::~SoQtPopupMenu()
110
delete PRIVATE(this)->callbacks;
111
delete PRIVATE(this)->userdata;
112
} // ~SoQtPopupMenu()
114
// *************************************************************************
117
SoQtPopupMenu::setMenuItemMarked(int itemid, SbBool marked)
119
// forward to native implementation
120
this->_setMenuItemMarked(itemid, marked);
123
const int radiogroupid = this->getRadioGroup(itemid);
124
if (radiogroupid != -1) {
125
this->setRadioGroupMarkedItem(itemid);
130
// *************************************************************************
136
SoQtPopupMenu::newRadioGroup(
139
const int numGroupedItems = PRIVATE(this)->radiogroups.getLength();
144
for (i = 0; i < numGroupedItems && hit == FALSE; i++) {
145
if (PRIVATE(this)->radiogroups[i] == id)
150
SoDebugError::postInfo("SoQtPopupMenu::NewRadioGroup",
151
"requested group id already taken");
162
for (i = 0; i < numGroupedItems && found == FALSE; i++) {
163
if (PRIVATE(this)->radiogroups[i] == id)
166
} while (found == TRUE);
169
PRIVATE(this)->menuitems.append(-1); // fake menu item
170
PRIVATE(this)->radiogroups.append(id); // register id in array
178
SoQtPopupMenu::getRadioGroup(
181
assert(itemid != -1);
182
const int numGroupedItems = PRIVATE(this)->radiogroups.getLength();
184
for (i = 0; i < numGroupedItems; i++) {
185
if (PRIVATE(this)->menuitems[i] == itemid)
186
return PRIVATE(this)->radiogroups[i];
195
SoQtPopupMenu::getRadioGroupSize(
199
const int numItems = PRIVATE(this)->radiogroups.getLength();
201
for (i = 0; i < numItems; i++) {
202
if (PRIVATE(this)->radiogroups[i] == groupid &&
203
PRIVATE(this)->menuitems[i] != -1)
207
} // getRadioGroupSize()
213
SoQtPopupMenu::addRadioGroupItem(
217
PRIVATE(this)->menuitems.append(itemid);
218
PRIVATE(this)->radiogroups.append(groupid);
219
} // addRadioGroupItem()
225
SoQtPopupMenu::removeRadioGroupItem(
228
assert(itemid != -1);
229
const int numGroupedItems = PRIVATE(this)->menuitems.getLength();
231
for (i = 0; i < numGroupedItems; i++) {
232
if (PRIVATE(this)->menuitems[i] == itemid) {
233
PRIVATE(this)->menuitems.remove(i);
234
PRIVATE(this)->radiogroups.remove(i);
238
} // removeRadioGroupItem()
240
// *************************************************************************
243
SoQtPopupMenu::setRadioGroupMarkedItem(int itemid)
245
const int idx = PRIVATE(this)->menuitems.find(itemid);
247
const int groupid = PRIVATE(this)->radiogroups[idx];
250
SoDebugError::post("SoQtPopupMenu::setRadioGroupMarkedItem",
251
"item not in a radio group");
255
const int numItems = PRIVATE(this)->menuitems.getLength();
256
for (int i = 0; i < numItems; i++) {
257
if (i == idx) { continue; }
258
if (PRIVATE(this)->radiogroups[i] == groupid) {
259
const int item = PRIVATE(this)->menuitems[i];
260
if (item != -1) { // FIXME: should this be an assert? 20050622 mortene.
261
if ( this->getMenuItemMarked(item) ) {
262
this->setMenuItemMarked(item, FALSE);
270
SoQtPopupMenu::getRadioGroupMarkedItem(int groupid)
272
const int numItems = PRIVATE(this)->menuitems.getLength();
274
for (i = 0; i < numItems; i++) {
275
if (PRIVATE(this)->radiogroups[i] == groupid) {
276
int item = PRIVATE(this)->menuitems[i];
277
if (item != -1 && this->getMenuItemMarked(item))
284
// *************************************************************************
290
SoQtPopupMenu::addMenuSelectionCallback(
291
SoQtMenuSelectionCallback * callback,
294
if (PRIVATE(this)->callbacks == NULL) {
295
PRIVATE(this)->callbacks = new SbPList;
296
PRIVATE(this)->userdata = new SbPList;
298
PRIVATE(this)->callbacks->append((void *) callback);
299
PRIVATE(this)->userdata->append(user);
300
} // addMenuSelectionCallback()
306
SoQtPopupMenu::removeMenuSelectionCallback(
307
SoQtMenuSelectionCallback * callback,
310
if (PRIVATE(this)->callbacks == NULL) {
312
SoDebugError::postInfo("SoQtPopupMenu::RemoveMenuSelectionCallback",
313
"no callbacks at all");
317
int numCallbacks = PRIVATE(this)->callbacks->getLength();
319
for (i = 0; i < numCallbacks; i++) {
320
if ((*PRIVATE(this)->callbacks)[i] == (void *) callback &&
321
(*PRIVATE(this)->userdata)[i] == user) {
322
PRIVATE(this)->callbacks->remove(i);
323
PRIVATE(this)->userdata->remove(i);
328
} // removeMenuSelectionCallback()
334
SoQtPopupMenu::invokeMenuSelection(
337
if (PRIVATE(this)->callbacks == NULL)
339
const int numCallbacks = PRIVATE(this)->callbacks->getLength();
341
for (i = 0; i < numCallbacks; i++) {
342
SoQtMenuSelectionCallback * cb = (SoQtMenuSelectionCallback *)
343
(*PRIVATE(this)->callbacks)[i];
344
(*cb)(itemid, (*PRIVATE(this)->userdata)[i]);
346
} // invokeMenuSelection()
348
// *************************************************************************