~ubuntu-branches/ubuntu/oneiric/soqt/oneiric

« back to all changes in this revision

Viewing changes to build/msvc6/src/Inventor/Qt/widgets/SoQtPopupMenu.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Steve M. Robbins
  • Date: 2006-02-06 22:34:00 UTC
  • mfrom: (1.1.2 upstream)
  • Revision ID: james.westby@ubuntu.com-20060206223400-g69m5soqa4zh0gkc
Tags: 1.3.0-3
debian/control: update libsoqt-dev depends.  Closes: #351700.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/**************************************************************************\
 
2
 *
 
3
 *  This file is part of the Coin 3D visualization library.
 
4
 *  Copyright (C) 1998-2005 by Systems in Motion.  All rights reserved.
 
5
 *
 
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.
 
11
 *
 
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.
 
16
 *
 
17
 *  See <URL:http://www.coin3d.org/> for more information.
 
18
 *
 
19
 *  Systems in Motion, Postboks 1283, Pirsenteret, 7462 Trondheim, NORWAY.
 
20
 *  <URL:http://www.sim.no/>.
 
21
 *
 
22
\**************************************************************************/
 
23
 
 
24
// src/Inventor/Qt/widgets/SoQtPopupMenu.cpp.  Generated from SoGuiPopupMenu.cpp.in by configure.
 
25
 
 
26
/*!
 
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.
 
30
 
 
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.
 
33
*/
 
34
 
 
35
#ifdef HAVE_CONFIG_H
 
36
#include <config.h>
 
37
#endif // HAVE_CONFIG_H
 
38
 
 
39
#include <assert.h>
 
40
 
 
41
#include <Inventor/SoLists.h>
 
42
#include <Inventor/errors/SoDebugError.h>
 
43
 
 
44
#include <soqtdefs.h>
 
45
#include <Inventor/Qt/widgets/SoQtPopupMenu.h>
 
46
#include <Inventor/Qt/widgets/QtNativePopupMenu.h>
 
47
#include <Inventor/Qt/common/SbGuiList.h>
 
48
 
 
49
// *************************************************************************
 
50
 
 
51
// Documentation for abstract methods.
 
52
 
 
53
/*!
 
54
  \fn void SoQtPopupMenu::popUp(QWidget * inside, int x, int y)
 
55
 
 
56
  Invokes this popup menu instance.
 
57
 
 
58
  The coordinates for the popup will be used relative to the origo of
 
59
  the widget argument.
 
60
*/
 
61
 
 
62
// *************************************************************************
 
63
 
 
64
// The private data for the SoQtPopupMenu.
 
65
 
 
66
class SoQtPopupMenuP {
 
67
public:
 
68
  SbGuiList<int> menuitems;
 
69
  SbGuiList<int> radiogroups;
 
70
  SbPList * callbacks;
 
71
  SbPList * userdata;
 
72
};
 
73
 
 
74
 
 
75
#define PRIVATE(o) (o->pimpl)
 
76
 
 
77
// *************************************************************************
 
78
 
 
79
/*!
 
80
  Instantiation method.
 
81
 
 
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.
 
85
*/
 
86
SoQtPopupMenu *
 
87
SoQtPopupMenu::createInstance(void)
 
88
{
 
89
  return new QtNativePopupMenu();
 
90
}
 
91
 
 
92
 
 
93
/*!
 
94
  The class constructor is protected, as SoQtPopupMenu uses a factory
 
95
  instantiation method.
 
96
*/
 
97
SoQtPopupMenu::SoQtPopupMenu(void)
 
98
{
 
99
  PRIVATE(this) = new SoQtPopupMenuP;
 
100
 
 
101
  PRIVATE(this)->callbacks = NULL;
 
102
  PRIVATE(this)->userdata = NULL;
 
103
} // SoQtPopupMenu()
 
104
 
 
105
/*!
 
106
  Destructor.
 
107
*/
 
108
SoQtPopupMenu::~SoQtPopupMenu()
 
109
{
 
110
  delete PRIVATE(this)->callbacks;
 
111
  delete PRIVATE(this)->userdata;
 
112
} // ~SoQtPopupMenu()
 
113
 
 
114
// *************************************************************************
 
115
 
 
116
void
 
117
SoQtPopupMenu::setMenuItemMarked(int itemid, SbBool marked)
 
118
{
 
119
  // forward to native implementation
 
120
  this->_setMenuItemMarked(itemid, marked);
 
121
 
 
122
  if (marked) {
 
123
    const int radiogroupid = this->getRadioGroup(itemid);
 
124
    if (radiogroupid != -1) {
 
125
      this->setRadioGroupMarkedItem(itemid);
 
126
    }
 
127
  }
 
128
}
 
129
 
 
130
// *************************************************************************
 
131
 
 
132
/*!
 
133
*/
 
134
 
 
135
int
 
136
SoQtPopupMenu::newRadioGroup(
 
137
  int groupid)
 
138
{
 
139
  const int numGroupedItems = PRIVATE(this)->radiogroups.getLength();
 
140
  int id = groupid;
 
141
  if (id != -1) {
 
142
    SbBool hit = FALSE;
 
143
    int i;
 
144
    for (i = 0; i < numGroupedItems && hit == FALSE; i++) {
 
145
      if (PRIVATE(this)->radiogroups[i] == id)
 
146
        hit = TRUE;
 
147
    }
 
148
    if (hit == TRUE) {
 
149
#if SOQT_DEBUG
 
150
      SoDebugError::postInfo("SoQtPopupMenu::NewRadioGroup",
 
151
        "requested group id already taken");
 
152
#endif // SOQT_DEBUG
 
153
      return -1; 
 
154
    }
 
155
  } else {
 
156
    id = 0;
 
157
    SbBool found;
 
158
    do {
 
159
      id++;
 
160
      found = FALSE;
 
161
      int i;
 
162
      for (i = 0; i < numGroupedItems && found == FALSE; i++) {
 
163
        if (PRIVATE(this)->radiogroups[i] == id)
 
164
          found = TRUE;
 
165
      }
 
166
    } while (found == TRUE);
 
167
  }
 
168
  // id is OK here
 
169
  PRIVATE(this)->menuitems.append(-1); // fake menu item
 
170
  PRIVATE(this)->radiogroups.append(id); // register id in array
 
171
  return id;
 
172
} // newRadioGroup()
 
173
 
 
174
/*!
 
175
*/
 
176
 
 
177
int
 
178
SoQtPopupMenu::getRadioGroup(
 
179
  int itemid)
 
180
{
 
181
  assert(itemid != -1);
 
182
  const int numGroupedItems = PRIVATE(this)->radiogroups.getLength();
 
183
  int i;
 
184
  for (i = 0; i < numGroupedItems; i++) {
 
185
    if (PRIVATE(this)->menuitems[i] == itemid)
 
186
      return PRIVATE(this)->radiogroups[i];
 
187
  }
 
188
  return -1;
 
189
} // getRadioGroup()
 
190
 
 
191
/*!
 
192
*/
 
193
 
 
194
int
 
195
SoQtPopupMenu::getRadioGroupSize(
 
196
  int groupid)
 
197
{
 
198
  int count = 0;
 
199
  const int numItems = PRIVATE(this)->radiogroups.getLength();
 
200
  int i;
 
201
  for (i = 0; i < numItems; i++) {
 
202
    if (PRIVATE(this)->radiogroups[i] == groupid &&
 
203
         PRIVATE(this)->menuitems[i] != -1)
 
204
      count++;
 
205
  }
 
206
  return count;
 
207
} // getRadioGroupSize()
 
208
 
 
209
/*!
 
210
*/
 
211
 
 
212
void
 
213
SoQtPopupMenu::addRadioGroupItem(
 
214
  int groupid,
 
215
  int itemid)
 
216
{
 
217
  PRIVATE(this)->menuitems.append(itemid);
 
218
  PRIVATE(this)->radiogroups.append(groupid);
 
219
} // addRadioGroupItem()
 
220
 
 
221
/*!
 
222
*/
 
223
 
 
224
void
 
225
SoQtPopupMenu::removeRadioGroupItem(
 
226
  int itemid)
 
227
{
 
228
  assert(itemid != -1);
 
229
  const int numGroupedItems = PRIVATE(this)->menuitems.getLength();
 
230
  int i;
 
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);
 
235
      return;
 
236
    }
 
237
  }
 
238
} // removeRadioGroupItem()
 
239
 
 
240
// *************************************************************************
 
241
 
 
242
void
 
243
SoQtPopupMenu::setRadioGroupMarkedItem(int itemid)
 
244
{
 
245
  const int idx = PRIVATE(this)->menuitems.find(itemid);
 
246
  assert(idx != -1);
 
247
  const int groupid = PRIVATE(this)->radiogroups[idx];
 
248
 
 
249
  if (groupid == -1) {
 
250
    SoDebugError::post("SoQtPopupMenu::setRadioGroupMarkedItem",
 
251
                       "item not in a radio group");
 
252
    return;
 
253
  }
 
254
 
 
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);
 
263
        }
 
264
      }
 
265
    }
 
266
  }
 
267
}
 
268
 
 
269
int
 
270
SoQtPopupMenu::getRadioGroupMarkedItem(int groupid)
 
271
{
 
272
  const int numItems = PRIVATE(this)->menuitems.getLength();
 
273
  int i;
 
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))
 
278
        return item;
 
279
    }
 
280
  }
 
281
  return -1;
 
282
}
 
283
 
 
284
// *************************************************************************
 
285
 
 
286
/*!
 
287
*/
 
288
 
 
289
void
 
290
SoQtPopupMenu::addMenuSelectionCallback(
 
291
  SoQtMenuSelectionCallback * callback,
 
292
  void * user)
 
293
{
 
294
  if (PRIVATE(this)->callbacks == NULL) {
 
295
    PRIVATE(this)->callbacks = new SbPList;
 
296
    PRIVATE(this)->userdata = new SbPList;
 
297
  }
 
298
  PRIVATE(this)->callbacks->append((void *) callback);
 
299
  PRIVATE(this)->userdata->append(user);
 
300
} // addMenuSelectionCallback()
 
301
 
 
302
/*!
 
303
*/
 
304
 
 
305
void
 
306
SoQtPopupMenu::removeMenuSelectionCallback(
 
307
  SoQtMenuSelectionCallback * callback,
 
308
  void * user)
 
309
{
 
310
  if (PRIVATE(this)->callbacks == NULL) {
 
311
#if SOQT_DEBUG
 
312
    SoDebugError::postInfo("SoQtPopupMenu::RemoveMenuSelectionCallback",
 
313
      "no callbacks at all");
 
314
#endif // SOQT_DEBUG
 
315
    return;
 
316
  }
 
317
  int numCallbacks = PRIVATE(this)->callbacks->getLength();
 
318
  int i;
 
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);
 
324
      i--;
 
325
      numCallbacks--;
 
326
    }
 
327
  }
 
328
} // removeMenuSelectionCallback()
 
329
 
 
330
/*!
 
331
*/
 
332
 
 
333
void
 
334
SoQtPopupMenu::invokeMenuSelection(
 
335
  int itemid)
 
336
{
 
337
  if (PRIVATE(this)->callbacks == NULL)
 
338
    return;
 
339
  const int numCallbacks = PRIVATE(this)->callbacks->getLength();
 
340
  int i;
 
341
  for (i = 0; i < numCallbacks; i++) {
 
342
    SoQtMenuSelectionCallback * cb = (SoQtMenuSelectionCallback *)
 
343
      (*PRIVATE(this)->callbacks)[i];
 
344
    (*cb)(itemid, (*PRIVATE(this)->userdata)[i]);
 
345
  }
 
346
} // invokeMenuSelection()
 
347
 
 
348
// *************************************************************************
 
349