• Skip to content
  • Skip to link menu
Trinity API Reference
  • Trinity API Reference
  • kdeui
 

kdeui

  • kdeui
kaction.cpp
1 /* This file is part of the KDE libraries
2  Copyright (C) 1999 Reginald Stadlbauer <reggie@kde.org>
3  (C) 1999 Simon Hausmann <hausmann@kde.org>
4  (C) 2000 Nicolas Hadacek <haadcek@kde.org>
5  (C) 2000 Kurt Granroth <granroth@kde.org>
6  (C) 2000 Michael Koch <koch@kde.org>
7  (C) 2001 Holger Freyther <freyther@kde.org>
8  (C) 2002 Ellis Whitehead <ellis@kde.org>
9  (C) 2002 Joseph Wenninger <jowenn@kde.org>
10 
11  This library is free software; you can redistribute it and/or
12  modify it under the terms of the GNU Library General Public
13  License version 2 as published by the Free Software Foundation.
14 
15  This library is distributed in the hope that it will be useful,
16  but WITHOUT ANY WARRANTY; without even the implied warranty of
17  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18  Library General Public License for more details.
19 
20  You should have received a copy of the GNU Library General Public License
21  along with this library; see the file COPYING.LIB. If not, write to
22  the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
23  Boston, MA 02110-1301, USA.
24 */
25 
26 #include "kaction.h"
27 
28 #include <assert.h>
29 
30 #include <tqtooltip.h>
31 #include <tqwhatsthis.h>
32 
33 #include <kaccel.h>
34 #include <kaccelbase.h>
35 #include <kaccelprivate.h>
36 #include <kapplication.h>
37 #include <kdebug.h>
38 #include <kguiitem.h>
39 #include <kmainwindow.h>
40 #include <kmenubar.h>
41 #include <kpopupmenu.h>
42 #include <ktoolbar.h>
43 #include <ktoolbarbutton.h>
44 
45 #include <ft2build.h>
46 #include <X11/Xdefs.h>
47 #include <X11/Xlib.h>
48 #include <X11/Xatom.h>
49 #include <X11/Intrinsic.h>
50 #include <X11/StringDefs.h>
51 #include <X11/Shell.h>
52 
53 #include <X11/Xft/Xft.h>
54 
76 int KAction::getToolButtonID()
77 {
78  static int toolbutton_no = -2;
79  return toolbutton_no--;
80 }
81 
82 //---------------------------------------------------------------------
83 // KAction::KActionPrivate
84 //---------------------------------------------------------------------
85 
86 class KAction::KActionPrivate : public KGuiItem
87 {
88 public:
89  KActionPrivate() : KGuiItem()
90  {
91  m_kaccel = 0;
92  m_configurable = true;
93  }
94 
95  KAccel *m_kaccel;
96  TQValueList<KAccel*> m_kaccelList;
97 
98  TQString m_groupText;
99  TQString m_group;
100 
101  KShortcut m_cut;
102  KShortcut m_cutDefault;
103 
104  bool m_configurable;
105 
106  struct Container
107  {
108  Container() { m_container = 0; m_representative = 0; m_id = 0; }
109  Container( const Container& s ) { m_container = s.m_container;
110  m_id = s.m_id; m_representative = s.m_representative; }
111  TQWidget* m_container;
112  int m_id;
113  TQWidget* m_representative;
114  };
115 
116  TQValueList<Container> m_containers;
117 };
118 
119 //---------------------------------------------------------------------
120 // KAction
121 //---------------------------------------------------------------------
122 
123 KAction::KAction( const TQString& text, const KShortcut& cut,
124  const TQObject* receiver, const char* slot,
125  KActionCollection* parent, const char* name )
126 : TQObject( parent, name ), d(new KActionPrivate)
127 {
128  initPrivate( text, cut, receiver, slot );
129 }
130 
131 KAction::KAction( const TQString& text, const TQString& sIconName, const KShortcut& cut,
132  const TQObject* receiver, const char* slot,
133  KActionCollection* parent, const char* name )
134 : TQObject( parent, name ), d(new KActionPrivate)
135 {
136  initPrivate( text, cut, receiver, slot );
137  d->setIconName( sIconName );
138 }
139 
140 KAction::KAction( const TQString& text, const TQIconSet& pix, const KShortcut& cut,
141  const TQObject* receiver, const char* slot,
142  KActionCollection* parent, const char* name )
143 : TQObject( parent, name ), d(new KActionPrivate)
144 {
145  initPrivate( text, cut, receiver, slot );
146  d->setIconSet( pix );
147 }
148 
149 KAction::KAction( const KGuiItem& item, const KShortcut& cut,
150  const TQObject* receiver, const char* slot,
151  KActionCollection* parent, const char* name )
152 : TQObject( parent, name ), d(new KActionPrivate)
153 {
154  initPrivate( item.text(), cut, receiver, slot );
155  if( item.hasIcon() )
156  setIcon( item.iconName() );
157  setToolTip( item.toolTip() );
158  setWhatsThis( item.whatsThis() );
159 }
160 
161 #ifndef KDE_NO_COMPAT // KDE 4: remove
162 KAction::KAction( const TQString& text, const KShortcut& cut,
163  TQObject* parent, const char* name )
164  : TQObject( parent, name ), d(new KActionPrivate)
165 {
166  initPrivate( text, cut, 0, 0 );
167 }
168 
169 KAction::KAction( const TQString& text, const KShortcut& cut,
170  const TQObject* receiver,
171  const char* slot, TQObject* parent, const char* name )
172  : TQObject( parent, name ), d(new KActionPrivate)
173 {
174  initPrivate( text, cut, receiver, slot );
175 }
176 
177 KAction::KAction( const TQString& text, const TQIconSet& pix,
178  const KShortcut& cut,
179  TQObject* parent, const char* name )
180  : TQObject( parent, name ), d(new KActionPrivate)
181 {
182  initPrivate( text, cut, 0, 0 );
183  setIconSet( pix );
184 }
185 
186 KAction::KAction( const TQString& text, const TQString& pix,
187  const KShortcut& cut,
188  TQObject* parent, const char* name )
189 : TQObject( parent, name ), d(new KActionPrivate)
190 {
191  initPrivate( text, cut, 0, 0 );
192  d->setIconName( pix );
193 }
194 
195 KAction::KAction( const TQString& text, const TQIconSet& pix,
196  const KShortcut& cut,
197  const TQObject* receiver, const char* slot, TQObject* parent,
198  const char* name )
199  : TQObject( parent, name ), d(new KActionPrivate)
200 {
201  initPrivate( text, cut, receiver, slot );
202  setIconSet( pix );
203 }
204 
205 KAction::KAction( const TQString& text, const TQString& pix,
206  const KShortcut& cut,
207  const TQObject* receiver, const char* slot, TQObject* parent,
208  const char* name )
209  : TQObject( parent, name ), d(new KActionPrivate)
210 {
211  initPrivate( text, cut, receiver, slot );
212  d->setIconName(pix);
213 }
214 
215 KAction::KAction( TQObject* parent, const char* name )
216  : TQObject( parent, name ), d(new KActionPrivate)
217 {
218  initPrivate( TQString::null, KShortcut(), 0, 0 );
219 }
220 #endif // KDE 4: remove end
221 
222 KAction::~KAction()
223 {
224  kdDebug(129) << "KAction::~KAction( this = \"" << name() << "\" )" << endl; // -- ellis
225 #ifndef KDE_NO_COMPAT
226  if (d->m_kaccel)
227  unplugAccel();
228 #endif
229 
230  // If actionCollection hasn't already been destructed,
231  if ( m_parentCollection ) {
232  m_parentCollection->take( this );
233 
234  const TQValueList<KAccel*> & accelList = d->m_kaccelList;
235  TQValueList<KAccel*>::const_iterator itr = accelList.constBegin();
236  const TQValueList<KAccel*>::const_iterator itrEnd = accelList.constEnd();
237 
238  const char * const namePtr = name();
239  for (; itr != itrEnd; ++itr )
240  (*itr)->remove(namePtr);
241 
242  }
243 
244  // Do not call unplugAll from here, as tempting as it sounds.
245  // KAction is designed around the idea that you need to plug
246  // _and_ to unplug it "manually". Unplugging leads to an important
247  // slowdown when e.g. closing the window, in which case we simply
248  // want to destroy everything asap, not to remove actions one by one
249  // from the GUI.
250 
251  delete d;
252 }
253 
254 void KAction::initPrivate( const TQString& text, const KShortcut& cut,
255  const TQObject* receiver, const char* slot )
256 {
257  d->m_cutDefault = cut;
258 
259  m_parentCollection = tqt_dynamic_cast<KActionCollection *>( parent() );
260  kdDebug(129) << "KAction::initPrivate(): this = " << this << " name = \"" << name() << "\" cut = " << cut.toStringInternal() << " m_parentCollection = " << m_parentCollection << endl;
261  if ( m_parentCollection )
262  m_parentCollection->insert( this );
263 
264  if ( receiver && slot )
265  connect( this, TQT_SIGNAL( activated() ), receiver, slot );
266 
267  if( !cut.isNull() && !qstrcmp( name(), "unnamed" ) )
268  kdWarning(129) << "KAction::initPrivate(): trying to assign a shortcut (" << cut.toStringInternal() << ") to an unnamed action." << endl;
269  d->setText( text );
270  initShortcut( cut );
271 }
272 
273 bool KAction::isPlugged() const
274 {
275  return (!d->m_containers.empty()) || d->m_kaccel;
276 }
277 
278 bool KAction::isPlugged( const TQWidget *container ) const
279 {
280  return findContainer( container ) > -1;
281 }
282 
283 bool KAction::isPlugged( const TQWidget *container, int id ) const
284 {
285  int i = findContainer( container );
286  return ( i > -1 && itemId( i ) == id );
287 }
288 
289 bool KAction::isPlugged( const TQWidget *container, const TQWidget *_representative ) const
290 {
291  int i = findContainer( container );
292  return ( i > -1 && representative( i ) == _representative );
293 }
294 
295 
296 /*
297 Three actionCollection conditions:
298  1) Scope is known on creation and KAccel object is created (e.g. KMainWindow)
299  2) Scope is unknown and no KAccel object is available (e.g. KXMLGUIClient)
300  a) addClient() will be called on object
301  b) we just want to add the actions to another KXMLGUIClient object
302 
303 The question is how to do we incorporate #2b into the XMLGUI framework?
304 
305 
306 We have a KCommandHistory object with undo and redo actions in a passed actionCollection
307 We have a KoDoc object which holds a KCommandHistory object and the actionCollection
308 We have two KoView objects which both point to the same KoDoc object
309 Undo and Redo should be available in both KoView objects, and
310  calling the undo->setEnabled() should affect both KoViews
311 
312 When addClient is called, it needs to be able to find the undo and redo actions
313 When it calls plug() on them, they need to be inserted into the KAccel object of the appropriate KoView
314 
315 In this case, the actionCollection belongs to KoDoc and we need to let it know that its shortcuts
316 have the same scope as the KoView actionCollection
317 
318 KXMLGUIClient::addSubActionCollection
319 
320 Document:
321  create document actions
322 
323 View
324  create view actions
325  add document actionCollection as sub-collection
326 
327 A parentCollection is created
328 Scenario 1: parentCollection has a focus widget set (e.g. via KMainWindow)
329  A KAccel object is created in the parentCollection
330  A KAction is created with parent=parentCollection
331  The shortcut is inserted into this actionCollection
332  Scenario 1a: xml isn't used
333  done
334  Scenario 1b: KXMLGUIBuilder::addClient() called
335  setWidget is called -- ignore
336  shortcuts are set
337 Scenario 2: parentCollection has no focus widget (e.g., KParts)
338  A KAction is created with parent=parentCollection
339  Scenario 2a: xml isn't used
340  no shortcuts
341  Scenario 2b: KXMLGUIBuilder::addClient() called
342  setWidget is called
343  shortcuts are inserted into current KAccel
344  shortcuts are set in all other KAccels, if the action is present in the other KAccels
345 */
346 
347 /*
348 shortcut may be set:
349  - on construction
350  - on plug
351  - on reading XML
352  - on plugAccel (deprecated)
353 
354 On Construction: [via initShortcut()]
355  insert into KAccel of m_parentCollection,
356  if kaccel() && isAutoConnectShortcuts() exists
357 
358 On Plug: [via plug() -> plugShortcut()]
359  insert into KAccel of m_parentCollection, if exists and not already inserted into
360 
361 On Read XML: [via setShortcut()]
362  set in all current KAccels
363  insert into KAccel of m_parentCollection, if exists and not already inserted into
364 */
365 
366 KAccel* KAction::kaccelCurrent()
367 {
368  if( m_parentCollection && m_parentCollection->builderKAccel() )
369  return m_parentCollection->builderKAccel();
370  else if( m_parentCollection && m_parentCollection->kaccel() )
371  return m_parentCollection->kaccel();
372  else
373  return 0L;
374 }
375 
376 // Only to be called from initPrivate()
377 bool KAction::initShortcut( const KShortcut& cut )
378 {
379  d->m_cut = cut;
380 
381  // Only insert action into KAccel if it has a valid name,
382  if( qstrcmp( name(), "unnamed" ) &&
383  m_parentCollection &&
384  m_parentCollection->isAutoConnectShortcuts() &&
385  m_parentCollection->kaccel() )
386  {
387  insertKAccel( m_parentCollection->kaccel() );
388  return true;
389  }
390  return false;
391  }
392 
393 // Only to be called from plug()
394 void KAction::plugShortcut()
395 {
396  KAccel* const kaccel = kaccelCurrent();
397 
398  //kdDebug(129) << "KAction::plugShortcut(): this = " << this << " kaccel() = " << (m_parentCollection ? m_parentCollection->kaccel() : 0) << endl;
399  if( kaccel && qstrcmp( name(), "unnamed" ) ) {
400  // Check if already plugged into current KAccel object
401  const TQValueList<KAccel*> & accelList = d->m_kaccelList;
402  TQValueList<KAccel*>::const_iterator itr = accelList.constBegin();
403  const TQValueList<KAccel*>::const_iterator itrEnd = accelList.constEnd();
404 
405  for( ; itr != itrEnd; ++itr) {
406  if( (*itr) == kaccel )
407  return;
408  }
409 
410  insertKAccel( kaccel );
411  }
412 }
413 
414 bool KAction::setShortcut( const KShortcut& cut )
415 {
416  bool bChanged = (d->m_cut != cut);
417  d->m_cut = cut;
418 
419  KAccel* const kaccel = kaccelCurrent();
420  bool bInsertRequired = true;
421  // Apply new shortcut to all existing KAccel objects
422 
423  const TQValueList<KAccel*> & accelList = d->m_kaccelList;
424  TQValueList<KAccel*>::const_iterator itr = accelList.constBegin();
425  const TQValueList<KAccel*>::const_iterator itrEnd = accelList.constEnd();
426 
427  for( ; itr != itrEnd; ++itr) {
428  // Check whether shortcut has already been plugged into
429  // the current kaccel object.
430  if( (*itr) == kaccel )
431  bInsertRequired = false;
432  if( bChanged )
433  updateKAccelShortcut( *itr );
434  }
435 
436  // Only insert action into KAccel if it has a valid name,
437  if( kaccel && bInsertRequired && qstrcmp( name(), "unnamed" ) )
438  insertKAccel( kaccel );
439 
440  if( bChanged ) {
441 #ifndef KDE_NO_COMPAT // KDE 4: remove
442  if ( d->m_kaccel )
443  d->m_kaccel->setShortcut( name(), cut );
444 #endif // KDE 4: remove end
445  int len = containerCount();
446  for( int i = 0; i < len; ++i )
447  updateShortcut( i );
448  }
449  return true;
450 }
451 
452 bool KAction::updateKAccelShortcut( KAccel* kaccel )
453 {
454  // Check if action is permitted
455  if (kapp && !kapp->authorizeKAction(name()))
456  return false;
457 
458  bool b = true;
459 
460  if ( !kaccel->actions().actionPtr( name() ) ) {
461  if(!d->m_cut.isNull() ) {
462  kdDebug(129) << "Inserting " << name() << ", " << d->text() << ", " << d->plainText() << endl;
463  b = kaccel->insert( name(), d->plainText(), TQString::null,
464  d->m_cut,
465  this, TQT_SLOT(slotActivated()),
466  isShortcutConfigurable(), isEnabled() );
467  }
468  }
469  else
470  b = kaccel->setShortcut( name(), d->m_cut );
471 
472  return b;
473 }
474 
475 void KAction::insertKAccel( KAccel* kaccel )
476 {
477  //kdDebug(129) << "KAction::insertKAccel( " << kaccel << " ): this = " << this << endl;
478  if ( !kaccel->actions().actionPtr( name() ) ) {
479  if( updateKAccelShortcut( kaccel ) ) {
480  d->m_kaccelList.append( kaccel );
481  connect( kaccel, TQT_SIGNAL(destroyed()), this, TQT_SLOT(slotDestroyed()) );
482  }
483  }
484  else
485  kdWarning(129) << "KAction::insertKAccel( kaccel = " << kaccel << " ): KAccel object already contains an action name \"" << name() << "\"" << endl; // -- ellis
486 }
487 
488 void KAction::removeKAccel( KAccel* kaccel )
489 {
490  //kdDebug(129) << "KAction::removeKAccel( " << i << " ): this = " << this << endl;
491  TQValueList<KAccel*> & accelList = d->m_kaccelList;
492  TQValueList<KAccel*>::iterator itr = accelList.begin();
493  const TQValueList<KAccel*>::iterator itrEnd = accelList.end();
494 
495  for( ; itr != itrEnd; ++itr) {
496  if( (*itr) == kaccel ) {
497  kaccel->remove( name() );
498  accelList.remove( itr );
499  disconnect( kaccel, TQT_SIGNAL(destroyed()), this, TQT_SLOT(slotDestroyed()) );
500  break;
501  }
502  }
503 }
504 
505 #ifndef KDE_NO_COMPAT
506 // KDE 4: remove
507 void KAction::setAccel( int keyQt )
508 {
509  setShortcut( KShortcut(keyQt) );
510 }
511 #endif // KDE 4: remove end
512 
513 void KAction::updateShortcut( int i )
514 {
515  int id = itemId( i );
516 
517  TQWidget* w = container( i );
518  if ( ::tqqt_cast<TQPopupMenu *>( w ) ) {
519  TQPopupMenu* menu = static_cast<TQPopupMenu*>(w);
520  updateShortcut( menu, id );
521  }
522  else if ( ::tqqt_cast<TQMenuBar *>( w ) )
523  static_cast<TQMenuBar*>(w)->setAccel( d->m_cut.keyCodeQt(), id );
524 }
525 
526 void KAction::updateShortcut( TQPopupMenu* menu, int id )
527 {
528  //kdDebug(129) << "KAction::updateShortcut(): this = " << this << " d->m_kaccelList.count() = " << d->m_kaccelList.count() << endl;
529  // If the action has a KAccel object,
530  // show the string representation of its shortcut.
531  if ( d->m_kaccel || d->m_kaccelList.count() ) {
532  TQString s = menu->text( id );
533  int i = s.find( '\t' );
534  if ( i >= 0 )
535  s.replace( i+1, s.length()-i, d->m_cut.seq(0).toString() );
536  else
537  s += "\t" + d->m_cut.seq(0).toString();
538 
539  menu->changeItem( id, s );
540  }
541  // Otherwise insert the shortcut itself into the popup menu.
542  else {
543  // This is a fall-hack in case the KAction is missing a proper parent collection.
544  // It should be removed eventually. --ellis
545  menu->setAccel( d->m_cut.keyCodeQt(), id );
546  kdDebug(129) << "KAction::updateShortcut(): name = \"" << name() << "\", cut = " << d->m_cut.toStringInternal() << "; No KAccel, probably missing a parent collection." << endl;
547  }
548 }
549 
550 const KShortcut& KAction::shortcut() const
551 {
552  return d->m_cut;
553 }
554 
555 const KShortcut& KAction::shortcutDefault() const
556 {
557  return d->m_cutDefault;
558 }
559 
560 TQString KAction::shortcutText() const
561 {
562  return d->m_cut.toStringInternal();
563 }
564 
565 void KAction::setShortcutText( const TQString& s )
566 {
567  setShortcut( KShortcut(s) );
568 }
569 
570 #ifndef KDE_NO_COMPAT // Remove in KDE 4
571 int KAction::accel() const
572 {
573  return d->m_cut.keyCodeQt();
574 }
575 #endif
576 
577 void KAction::setGroup( const TQString& grp )
578 {
579  d->m_group = grp;
580 
581  int len = containerCount();
582  for( int i = 0; i < len; ++i )
583  updateGroup( i );
584 }
585 
586 void KAction::updateGroup( int )
587 {
588  // DO SOMETHING
589 }
590 
591 TQString KAction::group() const
592 {
593  return d->m_group;
594 }
595 
596 bool KAction::isEnabled() const
597 {
598  return d->isEnabled();
599 }
600 
601 bool KAction::isShortcutConfigurable() const
602 {
603  return d->m_configurable;
604 }
605 
606 void KAction::setToolTip( const TQString& tt )
607 {
608  d->setToolTip( tt );
609 
610  int len = containerCount();
611  for( int i = 0; i < len; ++i )
612  updateToolTip( i );
613 }
614 
615 void KAction::updateToolTip( int i )
616 {
617  TQWidget *w = container( i );
618 
619  if ( ::tqqt_cast<KToolBar *>( w ) )
620  TQToolTip::add( static_cast<KToolBar*>(w)->getWidget( itemId( i ) ), d->toolTip() );
621 }
622 
623 TQString KAction::toolTip() const
624 {
625  return d->toolTip();
626 }
627 
628 int KAction::plug( TQWidget *w, int index )
629 {
630  //kdDebug(129) << "KAction::plug( " << w << ", " << index << " )" << endl;
631  if (!w ) {
632  kdWarning(129) << "KAction::plug called with 0 argument\n";
633  return -1;
634  }
635 
636  // Ellis: print warning if there is a shortcut, but no KAccel available (often due to no widget available in the actioncollection)
637  // David: Well, it doesn't matter much, things still work (e.g. Undo in koffice) via TQAccel.
638  // We should probably re-enable the warning for things that only KAccel can do, though - e.g. WIN key (mapped to Meta).
639 #if 0 //ndef NDEBUG
640  KAccel* kaccel = kaccelCurrent();
641  if( !d->m_cut.isNull() && !kaccel ) {
642  kdDebug(129) << "KAction::plug(): has no KAccel object; this = " << this << " name = " << name() << " parentCollection = " << m_parentCollection << endl; // ellis
643  }
644 #endif
645 
646  // Check if action is permitted
647  if (kapp && !kapp->authorizeKAction(name()))
648  return -1;
649 
650  plugShortcut();
651 
652  if ( ::tqqt_cast<TQPopupMenu *>( w ) )
653  {
654  TQPopupMenu* menu = static_cast<TQPopupMenu*>( w );
655  int id;
656  // Don't insert shortcut into menu if it's already in a KAccel object.
657  int keyQt = (d->m_kaccelList.count() || d->m_kaccel) ? 0 : d->m_cut.keyCodeQt();
658 
659  if ( d->hasIcon() )
660  {
661  KInstance *instance;
662  if ( m_parentCollection )
663  instance = m_parentCollection->instance();
664  else
665  instance = KGlobal::instance();
666  id = menu->insertItem( d->iconSet( KIcon::Small, 0, instance ), d->text(), this,//dsweet
667  TQT_SLOT( slotPopupActivated() ), keyQt,
668  -1, index );
669  }
670  else
671  id = menu->insertItem( d->text(), this,
672  TQT_SLOT( slotPopupActivated() ),
673  keyQt, -1, index );
674 
675  // If the shortcut is already in a KAccel object, then
676  // we need to set the menu item's shortcut text.
677  if ( d->m_kaccelList.count() || d->m_kaccel )
678  updateShortcut( menu, id );
679 
680  // call setItemEnabled only if the item really should be disabled,
681  // because that method is slow and the item is per default enabled
682  if ( !d->isEnabled() )
683  menu->setItemEnabled( id, false );
684 
685  if ( !d->whatsThis().isEmpty() )
686  menu->TQMenuData::setWhatsThis( id, whatsThisWithIcon() );
687 
688  addContainer( menu, id );
689  connect( menu, TQT_SIGNAL( destroyed() ), this, TQT_SLOT( slotDestroyed() ) );
690 
691  if ( m_parentCollection )
692  m_parentCollection->connectHighlight( menu, this );
693 
694  return d->m_containers.count() - 1;
695  }
696  else if ( ::tqqt_cast<KToolBar *>( w ) )
697  {
698  KToolBar *bar = static_cast<KToolBar *>( w );
699 
700  int id_ = getToolButtonID();
701  KInstance *instance;
702  if ( m_parentCollection )
703  instance = m_parentCollection->instance();
704  else
705  instance = KGlobal::instance();
706 
707  if ( icon().isEmpty() && !iconSet().pixmap().isNull() ) // old code using TQIconSet directly
708  {
709  bar->insertButton( iconSet().pixmap(), id_, TQT_SIGNAL( buttonClicked(int, TQt::ButtonState) ), this,
710  TQT_SLOT( slotButtonClicked(int, TQt::ButtonState) ),
711  d->isEnabled(), d->plainText(), index );
712  }
713  else
714  {
715  TQString icon = d->iconName();
716  if ( icon.isEmpty() )
717  icon = "unknown";
718  bar->insertButton( icon, id_, TQT_SIGNAL( buttonClicked(int, TQt::ButtonState) ), this,
719  TQT_SLOT( slotButtonClicked(int, TQt::ButtonState) ),
720  d->isEnabled(), d->plainText(), index, instance );
721  }
722 
723  KToolBarButton* ktb = bar->getButton(id_);
724  ktb->setName( TQCString("toolbutton_")+name() );
725 
726  if ( !d->whatsThis().isEmpty() )
727  TQWhatsThis::add( bar->getButton(id_), whatsThisWithIcon() );
728 
729  if ( !d->toolTip().isEmpty() )
730  TQToolTip::add( bar->getButton(id_), d->toolTip() );
731 
732  addContainer( bar, id_ );
733 
734  connect( bar, TQT_SIGNAL( destroyed() ), this, TQT_SLOT( slotDestroyed() ) );
735 
736  if ( m_parentCollection )
737  m_parentCollection->connectHighlight( bar, this );
738 
739  return containerCount() - 1;
740  }
741 
742  return -1;
743 }
744 
745 void KAction::unplug( TQWidget *w )
746 {
747  int i = findContainer( w );
748  if ( i == -1 )
749  return;
750  int id = itemId( i );
751 
752  if ( ::tqqt_cast<TQPopupMenu *>( w ) )
753  {
754  TQPopupMenu *menu = static_cast<TQPopupMenu *>( w );
755  menu->removeItem( id );
756  }
757  else if ( ::tqqt_cast<KToolBar *>( w ) )
758  {
759  KToolBar *bar = static_cast<KToolBar *>( w );
760  bar->removeItemDelayed( id );
761  }
762  else if ( ::tqqt_cast<TQMenuBar *>( w ) )
763  {
764  TQMenuBar *bar = static_cast<TQMenuBar *>( w );
765  bar->removeItem( id );
766  }
767 
768  removeContainer( i );
769  if ( m_parentCollection )
770  m_parentCollection->disconnectHighlight( w, this );
771 }
772 
773 void KAction::plugAccel(KAccel *kacc, bool configurable)
774 {
775  kdWarning(129) << "KAction::plugAccel(): call to deprecated action." << endl;
776  kdDebug(129) << kdBacktrace() << endl;
777  //kdDebug(129) << "KAction::plugAccel( kacc = " << kacc << " ): name \"" << name() << "\"" << endl;
778  if ( d->m_kaccel )
779  unplugAccel();
780 
781  // If the parent collection's accel ptr isn't set yet
782  //if ( m_parentCollection && !m_parentCollection->accel() )
783  // m_parentCollection->setAccel( kacc );
784 
785  // We can only plug this action into the given KAccel object
786  // if it does not already contain an action with the same name.
787  if ( !kacc->actions().actionPtr(name()) )
788  {
789  d->m_kaccel = kacc;
790  d->m_kaccel->insert(name(), d->plainText(), TQString::null,
791  KShortcut(d->m_cut),
792  this, TQT_SLOT(slotActivated()),
793  configurable, isEnabled());
794  connect(d->m_kaccel, TQT_SIGNAL(destroyed()), this, TQT_SLOT(slotDestroyed()));
795  //connect(d->m_kaccel, TQT_SIGNAL(keycodeChanged()), this, TQT_SLOT(slotKeycodeChanged()));
796  }
797  else
798  kdWarning(129) << "KAction::plugAccel( kacc = " << kacc << " ): KAccel object already contains an action name \"" << name() << "\"" << endl; // -- ellis
799 }
800 
801 void KAction::unplugAccel()
802 {
803  //kdDebug(129) << "KAction::unplugAccel() " << this << " " << name() << endl;
804  if ( d->m_kaccel )
805  {
806  d->m_kaccel->remove(name());
807  d->m_kaccel = 0;
808  }
809 }
810 
811 void KAction::plugMainWindowAccel( TQWidget *w )
812 {
813  // Note: topLevelWidget() stops too early, we can't use it.
814  TQWidget * tl = w;
815  TQWidget * n;
816  while ( !tl->isDialog() && ( n = tl->parentWidget() ) ) // lookup parent and store
817  tl = n;
818 
819  KMainWindow * mw = tqt_dynamic_cast<KMainWindow *>(tl); // try to see if it's a kmainwindow
820  if (mw)
821  plugAccel( mw->accel() );
822  else
823  kdDebug(129) << "KAction::plugMainWindowAccel: Toplevel widget isn't a KMainWindow, can't plug accel. " << tl << endl;
824 }
825 
826 void KAction::setEnabled(bool enable)
827 {
828  //kdDebug(129) << "KAction::setEnabled( " << enable << " ): this = " << this << " d->m_kaccelList.count() = " << d->m_kaccelList.count() << endl;
829  if ( enable == d->isEnabled() )
830  return;
831 
832 #ifndef KDE_NO_COMPAT
833  // KDE 4: remove
834  if (d->m_kaccel)
835  d->m_kaccel->setEnabled(name(), enable);
836 #endif // KDE 4: remove end
837 
838  const TQValueList<KAccel*> & accelList = d->m_kaccelList;
839  TQValueList<KAccel*>::const_iterator itr = accelList.constBegin();
840  const TQValueList<KAccel*>::const_iterator itrEnd = accelList.constEnd();
841 
842  const char * const namePtr = name();
843 
844  for ( ; itr != itrEnd; ++itr )
845  (*itr)->setEnabled( namePtr, enable );
846 
847  d->setEnabled( enable );
848 
849  int len = containerCount();
850  for( int i = 0; i < len; ++i )
851  updateEnabled( i );
852 
853  emit enabled( d->isEnabled() );
854 }
855 
856 void KAction::updateEnabled( int i )
857 {
858  TQWidget *w = container( i );
859 
860  if ( ::tqqt_cast<TQPopupMenu *>( w ) )
861  static_cast<TQPopupMenu*>(w)->setItemEnabled( itemId( i ), d->isEnabled() );
862  else if ( ::tqqt_cast<TQMenuBar *>( w ) )
863  static_cast<TQMenuBar*>(w)->setItemEnabled( itemId( i ), d->isEnabled() );
864  else if ( ::tqqt_cast<KToolBar *>( w ) )
865  static_cast<KToolBar*>(w)->setItemEnabled( itemId( i ), d->isEnabled() );
866 }
867 
868 void KAction::setShortcutConfigurable( bool b )
869 {
870  d->m_configurable = b;
871 }
872 
873 void KAction::setText( const TQString& text )
874 {
875 #ifndef KDE_NO_COMPAT
876  // KDE 4: remove
877  if (d->m_kaccel) {
878  KAccelAction* pAction = d->m_kaccel->actions().actionPtr(name());
879  if (pAction)
880  pAction->setLabel( text );
881  }
882 #endif // KDE 4: remove end
883  const TQValueList<KAccel*> & accelList = d->m_kaccelList;
884  TQValueList<KAccel*>::const_iterator itr = accelList.constBegin();
885  const TQValueList<KAccel*>::const_iterator itrEnd = accelList.constEnd();
886 
887  const char * const namePtr = name();
888 
889  for( ; itr != itrEnd; ++itr ) {
890  KAccelAction* const pAction = (*itr)->actions().actionPtr(namePtr);
891  if (pAction)
892  pAction->setLabel( text );
893  }
894 
895  d->setText( text );
896 
897  int len = containerCount();
898  for( int i = 0; i < len; ++i )
899  updateText( i );
900 }
901 
902 void KAction::updateText( int i )
903 {
904  TQWidget *w = container( i );
905 
906  if ( ::tqqt_cast<TQPopupMenu *>( w ) ) {
907  int id = itemId( i );
908  static_cast<TQPopupMenu*>(w)->changeItem( id, d->text() );
909  if (!d->m_cut.isNull())
910  updateShortcut( static_cast<TQPopupMenu*>(w), id );
911  }
912  else if ( ::tqqt_cast<TQMenuBar *>( w ) )
913  static_cast<TQMenuBar*>(w)->changeItem( itemId( i ), d->text() );
914  else if ( ::tqqt_cast<KToolBar *>( w ) )
915  {
916  TQWidget *button = static_cast<KToolBar *>(w)->getWidget( itemId( i ) );
917  if ( ::tqqt_cast<KToolBarButton *>( button ) )
918  static_cast<KToolBarButton *>(button)->setText( d->plainText() );
919  }
920 }
921 
922 TQString KAction::text() const
923 {
924  return d->text();
925 }
926 
927 TQString KAction::plainText() const
928 {
929  return d->plainText( );
930 }
931 
932 void KAction::setIcon( const TQString &icon )
933 {
934  d->setIconName( icon );
935 
936  // now handle any toolbars
937  int len = containerCount();
938  for ( int i = 0; i < len; ++i )
939  updateIcon( i );
940 }
941 
942 void KAction::updateIcon( int id )
943 {
944  TQWidget* w = container( id );
945 
946  if ( ::tqqt_cast<TQPopupMenu *>( w ) ) {
947  int itemId_ = itemId( id );
948  static_cast<TQPopupMenu*>(w)->changeItem( itemId_, d->iconSet( KIcon::Small ), d->text() );
949  if (!d->m_cut.isNull())
950  updateShortcut( static_cast<TQPopupMenu*>(w), itemId_ );
951  }
952  else if ( ::tqqt_cast<TQMenuBar *>( w ) )
953  static_cast<TQMenuBar*>(w)->changeItem( itemId( id ), d->iconSet( KIcon::Small ), d->text() );
954  else if ( ::tqqt_cast<KToolBar *>( w ) )
955  static_cast<KToolBar *>(w)->setButtonIcon( itemId( id ), d->iconName() );
956 }
957 
958 TQString KAction::icon() const
959 {
960  return d->iconName( );
961 }
962 
963 void KAction::setIconSet( const TQIconSet &iconset )
964 {
965  d->setIconSet( iconset );
966 
967  int len = containerCount();
968  for( int i = 0; i < len; ++i )
969  updateIconSet( i );
970 }
971 
972 
973 void KAction::updateIconSet( int id )
974 {
975  TQWidget *w = container( id );
976 
977  if ( ::tqqt_cast<TQPopupMenu *>( w ) )
978  {
979  int itemId_ = itemId( id );
980  static_cast<TQPopupMenu*>(w)->changeItem( itemId_, d->iconSet(), d->text() );
981  if (!d->m_cut.isNull())
982  updateShortcut( static_cast<TQPopupMenu*>(w), itemId_ );
983  }
984  else if ( ::tqqt_cast<TQMenuBar *>( w ) )
985  static_cast<TQMenuBar*>(w)->changeItem( itemId( id ), d->iconSet(), d->text() );
986  else if ( ::tqqt_cast<KToolBar *>( w ) )
987  {
988  if ( icon().isEmpty() && d->hasIcon() ) // only if there is no named icon ( scales better )
989  static_cast<KToolBar *>(w)->setButtonIconSet( itemId( id ), d->iconSet() );
990  else
991  static_cast<KToolBar *>(w)->setButtonIconSet( itemId( id ), d->iconSet( KIcon::Small ) );
992  }
993 }
994 
995 TQIconSet KAction::iconSet( KIcon::Group group, int size ) const
996 {
997  return d->iconSet( group, size );
998 }
999 
1000 bool KAction::hasIcon() const
1001 {
1002  return d->hasIcon();
1003 }
1004 
1005 void KAction::setWhatsThis( const TQString& text )
1006 {
1007  d->setWhatsThis( text );
1008 
1009  int len = containerCount();
1010  for( int i = 0; i < len; ++i )
1011  updateWhatsThis( i );
1012 }
1013 
1014 void KAction::updateWhatsThis( int i )
1015 {
1016  TQPopupMenu* pm = popupMenu( i );
1017  if ( pm )
1018  {
1019  pm->TQMenuData::setWhatsThis( itemId( i ), d->whatsThis() );
1020  return;
1021  }
1022 
1023  KToolBar *tb = toolBar( i );
1024  if ( tb )
1025  {
1026  TQWidget *w = tb->getButton( itemId( i ) );
1027  TQWhatsThis::remove( w );
1028  TQWhatsThis::add( w, d->whatsThis() );
1029  return;
1030  }
1031 }
1032 
1033 TQString KAction::whatsThis() const
1034 {
1035  return d->whatsThis();
1036 }
1037 
1038 TQString KAction::whatsThisWithIcon() const
1039 {
1040  TQString text = whatsThis();
1041  if (!d->iconName().isEmpty())
1042  return TQString::fromLatin1("<img source=\"small|%1\"> %2").arg(d->iconName() ).arg(text);
1043  return text;
1044 }
1045 
1046 TQWidget* KAction::container( int index ) const
1047 {
1048  assert( index < containerCount() );
1049  return d->m_containers[ index ].m_container;
1050 }
1051 
1052 KToolBar* KAction::toolBar( int index ) const
1053 {
1054  return tqt_dynamic_cast<KToolBar *>( d->m_containers[ index ].m_container );
1055 }
1056 
1057 TQPopupMenu* KAction::popupMenu( int index ) const
1058 {
1059  return tqt_dynamic_cast<TQPopupMenu *>( d->m_containers[ index ].m_container );
1060 }
1061 
1062 TQWidget* KAction::representative( int index ) const
1063 {
1064  return d->m_containers[ index ].m_representative;
1065 }
1066 
1067 int KAction::itemId( int index ) const
1068 {
1069  return d->m_containers[ index ].m_id;
1070 }
1071 
1072 int KAction::containerCount() const
1073 {
1074  return d->m_containers.count();
1075 }
1076 
1077 uint KAction::kaccelCount() const
1078 {
1079  return d->m_kaccelList.count();
1080 }
1081 
1082 void KAction::addContainer( TQWidget* c, int id )
1083 {
1084  KActionPrivate::Container p;
1085  p.m_container = c;
1086  p.m_id = id;
1087  d->m_containers.append( p );
1088 }
1089 
1090 void KAction::addContainer( TQWidget* c, TQWidget* w )
1091 {
1092  KActionPrivate::Container p;
1093  p.m_container = c;
1094  p.m_representative = w;
1095  d->m_containers.append( p );
1096 }
1097 
1098 void KAction::activate()
1099 {
1100  emit activated( KAction::EmulatedActivation, Qt::NoButton );
1101  slotActivated();
1102 }
1103 
1104 void KAction::slotActivated()
1105 {
1106  const TQObject *senderObj = TQT_TQOBJECT_CONST(sender());
1107  if ( senderObj )
1108  {
1109  if ( ::tqqt_cast<KAccelPrivate *>( senderObj ) )
1110  emit activated( KAction::AccelActivation, Qt::NoButton );
1111  }
1112  emit activated();
1113 }
1114 
1115 // This catches signals emitted by KActions inserted into QPopupMenu
1116 // We do crude things inside it, because we need to know which
1117 // TQPopupMenu emitted the signal. We need to be sure that it is
1118 // only called by QPopupMenus, we plugged us in.
1119 void KAction::slotPopupActivated()
1120 {
1121  if( ::tqqt_cast<TQSignal *>(sender()))
1122  {
1123  int id = tqt_dynamic_cast<const TQSignal *>(sender())->value().toInt();
1124  int pos = findContainer(id);
1125  if(pos != -1)
1126  {
1127  TQPopupMenu* qpm = tqt_dynamic_cast<TQPopupMenu *>( container(pos) );
1128  if(qpm)
1129  {
1130  KPopupMenu* kpm = tqt_dynamic_cast<KPopupMenu *>( qpm );
1131  TQt::ButtonState state;
1132  if ( kpm ) // KPopupMenu? Nice, it stores the state.
1133  state = kpm->state();
1134  else { // just a QPopupMenu? We'll ask for the state now then (small race condition?)
1135  kdDebug(129) << "KAction::slotPopupActivated not a KPopupMenu -> using keyboardMouseState()" << endl;
1136  state = KApplication::keyboardMouseState();
1137  }
1138  emit activated( KAction::PopupMenuActivation, state );
1139  slotActivated();
1140  return;
1141  }
1142  }
1143  }
1144 
1145  kdWarning(129)<<"Don't connect KAction::slotPopupActivated() to anything, expect into QPopupMenus which are in containers. Use slotActivated instead."<<endl;
1146  emit activated( KAction::PopupMenuActivation, Qt::NoButton );
1147  slotActivated();
1148 }
1149 
1150 void KAction::slotButtonClicked( int, TQt::ButtonState state )
1151 {
1152  kdDebug(129) << "slotButtonClicked() state=" << state << endl;
1153  emit activated( KAction::ToolBarActivation, state );
1154 
1155  // RightButton isn't really an activation
1156  if ( ( state & Qt::LeftButton ) || ( state & Qt::MidButton ) )
1157  slotActivated();
1158 }
1159 
1160 
1161 void KAction::slotDestroyed()
1162 {
1163  kdDebug(129) << "KAction::slotDestroyed(): this = " << this << ", name = \"" << name() << "\", sender = " << sender() << endl;
1164  const TQObject* const o = TQT_TQOBJECT_CONST(sender());
1165 
1166 #ifndef KDE_NO_COMPAT // KDE 4: remove
1167  if ( o == d->m_kaccel )
1168  {
1169  d->m_kaccel = 0;
1170  return;
1171  }
1172 #endif // KDE 4: remove end
1173  TQValueList<KAccel*> & accelList = d->m_kaccelList;
1174  TQValueList<KAccel*>::iterator itr = accelList.begin();
1175  const TQValueList<KAccel*>::iterator itrEnd = accelList.end();
1176 
1177  for( ; itr != itrEnd; ++itr)
1178  {
1179  if ( o == *itr )
1180  {
1181  disconnect( *itr, TQT_SIGNAL(destroyed()), this, TQT_SLOT(slotDestroyed()) );
1182  accelList.remove(itr);
1183  return;
1184  }
1185  }
1186 
1187  int i;
1188  do
1189  {
1190  i = findContainer( TQT_TQWIDGET_CONST( static_cast<const QObject*>(o) ) );
1191  if ( i != -1 )
1192  removeContainer( i );
1193  } while ( i != -1 );
1194 }
1195 
1196 int KAction::findContainer( const TQWidget* widget ) const
1197 {
1198  int pos = 0;
1199 
1200  const TQValueList<KActionPrivate::Container> & containers = d->m_containers;
1201 
1202  TQValueList<KActionPrivate::Container>::ConstIterator it = containers.constBegin();
1203  const TQValueList<KActionPrivate::Container>::ConstIterator itEnd = containers.constEnd();
1204 
1205  while( it != itEnd )
1206  {
1207  if ( (*it).m_representative == widget || (*it).m_container == widget )
1208  return pos;
1209  ++it;
1210  ++pos;
1211  }
1212 
1213  return -1;
1214 }
1215 
1216 int KAction::findContainer( const int id ) const
1217 {
1218  int pos = 0;
1219 
1220  const TQValueList<KActionPrivate::Container> & containers = d->m_containers;
1221 
1222  TQValueList<KActionPrivate::Container>::ConstIterator it = containers.constBegin();
1223  const TQValueList<KActionPrivate::Container>::ConstIterator itEnd = containers.constEnd();
1224 
1225  while( it != itEnd )
1226  {
1227  if ( (*it).m_id == id )
1228  return pos;
1229  ++it;
1230  ++pos;
1231  }
1232 
1233  return -1;
1234 }
1235 
1236 void KAction::removeContainer( int index )
1237 {
1238  int i = 0;
1239 
1240  TQValueList<KActionPrivate::Container> & containers = d->m_containers;
1241 
1242  TQValueList<KActionPrivate::Container>::Iterator it = containers.begin();
1243  const TQValueList<KActionPrivate::Container>::Iterator itEnd = containers.end();
1244 
1245  while( it != itEnd )
1246  {
1247  if ( i == index )
1248  {
1249  containers.remove( it );
1250  return;
1251  }
1252  ++it;
1253  ++i;
1254  }
1255 }
1256 
1257 // FIXME: Remove this (ellis)
1258 void KAction::slotKeycodeChanged()
1259 {
1260  kdDebug(129) << "KAction::slotKeycodeChanged()" << endl; // -- ellis
1261  KAccelAction* pAction = d->m_kaccel->actions().actionPtr(name());
1262  if( pAction )
1263  setShortcut(pAction->shortcut());
1264 }
1265 
1266 KActionCollection *KAction::parentCollection() const
1267 {
1268  return m_parentCollection;
1269 }
1270 
1271 void KAction::unplugAll()
1272 {
1273  while ( containerCount() != 0 )
1274  unplug( container( 0 ) );
1275 }
1276 
1277 const KGuiItem& KAction::guiItem() const
1278 {
1279  return *d;
1280 }
1281 
1282 void KAction::virtual_hook( int, void* )
1283 { /*BASE::virtual_hook( id, data );*/ }
1284 
1285 /* vim: et sw=2 ts=2
1286  */
1287 
1288 #include "kaction.moc"

kdeui

Skip menu "kdeui"
  • Main Page
  • Namespace List
  • Class Hierarchy
  • Alphabetical List
  • Class List
  • File List
  • Namespace Members
  • Class Members
  • Related Pages

kdeui

Skip menu "kdeui"
  • arts
  • dcop
  • dnssd
  • interfaces
  •     interface
  •     library
  •   kspeech
  •   ktexteditor
  • kabc
  • kate
  • kcmshell
  • kdecore
  • kded
  • kdefx
  • kdeprint
  • kdesu
  • kdeui
  • kdoctools
  • khtml
  • kimgio
  • kinit
  • kio
  •   bookmarks
  •   httpfilter
  •   kfile
  •   kio
  •   kioexec
  •   kpasswdserver
  •   kssl
  • kioslave
  •   http
  • kjs
  • kmdi
  •   kmdi
  • knewstuff
  • kparts
  • krandr
  • kresources
  • kspell2
  • kunittest
  • kutils
  • kwallet
  • libkmid
  • libkscreensaver
Generated for kdeui by doxygen 1.8.3.1
This website is maintained by Timothy Pearson.
KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. |