20 #include "tdeaccelmanager.h"
22 #include <tqapplication.h>
23 #include <tqcheckbox.h>
24 #include <tqcombobox.h>
25 #include <tqgroupbox.h>
27 #include <tqlineedit.h>
28 #include <tqmenubar.h>
29 #include <tqmemarray.h>
30 #include <tqmetaobject.h>
31 #include <tqmainwindow.h>
32 #include <tqobjectlist.h>
33 #include <tqpopupmenu.h>
34 #include <tqptrlist.h>
35 #include <tqpushbutton.h>
36 #include <tqradiobutton.h>
37 #include <tqspinbox.h>
39 #include <tqtextview.h>
41 #include <tqwidgetstack.h>
43 #include <kstdaction.h>
44 #include <kstaticdeleter.h>
48 #include "tdeaccelmanager_private.h"
49 #include "../tdeui/kstdaction_p.h"
73 class TDEAcceleratorManagerPrivate
77 static void manage(TQWidget *widget);
78 static bool programmers_mode;
79 static bool standardName(
const TQString &str);
82 TQString t2 = as.accelerated();
83 TQString t1 = as.originalText();
86 if (as.accel() == -1) {
87 removed_string +=
"<tr><td>" + TQStyleSheet::escape(t1) +
"</td></tr>";
88 }
else if (as.originalAccel() == -1) {
89 added_string +=
"<tr><td>" + TQStyleSheet::escape(t2) +
"</td></tr>";
91 changed_string +=
"<tr><td>" + TQStyleSheet::escape(t1) +
"</td>";
92 changed_string +=
"<td>" + TQStyleSheet::escape(t2) +
"</td></tr>";
98 static TQString changed_string;
99 static TQString added_string;
100 static TQString removed_string;
101 static TQMap<TQWidget *, int> ignored_widgets;
106 typedef TQPtrList<Item> ItemList;
109 static void traverseChildren(TQWidget *widget, Item *item);
111 static void manageWidget(TQWidget *widget, Item *item);
112 static void manageMenuBar(TQMenuBar *mbar, Item *item);
113 static void manageTabBar(TQTabBar *bar, Item *item);
115 static void calculateAccelerators(Item *item, TQString &used);
121 Item() : m_widget(0), m_children(0), m_index(-1) {}
124 void addChild(Item *item);
128 ItemList *m_children;
135 bool TDEAcceleratorManagerPrivate::programmers_mode =
false;
136 TQString TDEAcceleratorManagerPrivate::changed_string;
137 TQString TDEAcceleratorManagerPrivate::added_string;
138 TQString TDEAcceleratorManagerPrivate::removed_string;
139 static TQStringList *kaccmp_sns = 0;
141 TQMap<TQWidget*, int> TDEAcceleratorManagerPrivate::ignored_widgets;
143 bool TDEAcceleratorManagerPrivate::standardName(
const TQString &str)
146 kaccmp_sns_d.setObject(kaccmp_sns,
new TQStringList(KStdAction::internal_stdNames()));
147 return kaccmp_sns->contains(str);
150 TDEAcceleratorManagerPrivate::Item::~Item()
156 void TDEAcceleratorManagerPrivate::Item::addChild(Item *item)
159 m_children =
new ItemList;
160 m_children->setAutoDelete(
true);
163 m_children->append(item);
166 void TDEAcceleratorManagerPrivate::manage(TQWidget *widget)
170 kdDebug(131) <<
"null pointer given to manage" <<
endl;
174 if (
dynamic_cast<TQPopupMenu*
>(widget))
177 TDEPopupAccelManager::manage(
static_cast<TQPopupMenu*
>(widget));
181 Item *root =
new Item;
183 manageWidget(widget, root);
186 calculateAccelerators(root, used);
191 void TDEAcceleratorManagerPrivate::calculateAccelerators(Item *item, TQString &used)
193 if (!item->m_children)
197 TDEAccelStringList contents;
198 for (Item *it = item->m_children->first(); it != 0;
199 it = item->m_children->next())
201 contents << it->m_content;
209 for (Item *it = item->m_children->first(); it != 0;
210 it = item->m_children->next())
214 TQTabBar *tabBar =
dynamic_cast<TQTabBar*
>(it->m_widget);
217 if (checkChange(contents[cnt]))
218 tabBar->tabAt(it->m_index)->setText(contents[cnt].accelerated());
221 TQMenuBar *menuBar =
dynamic_cast<TQMenuBar*
>(it->m_widget);
224 if (it->m_index >= 0)
226 TQMenuItem *mitem = menuBar->findItem(menuBar->idAt(it->m_index));
229 checkChange(contents[cnt]);
230 mitem->setText(contents[cnt].accelerated());
236 if (
dynamic_cast<TQGroupBox*
>( it->m_widget ) )
239 if (
dynamic_cast<TQLabel*
>( it->m_widget ) && it->m_widget->inherits(
"KURLLabel") )
242 int tprop = it->m_widget->metaObject()->findProperty(
"text",
true);
244 if (checkChange(contents[cnt]))
245 it->m_widget->setProperty(
"text", contents[cnt].accelerated());
247 tprop = it->m_widget->metaObject()->findProperty(
"title",
true);
248 if (tprop != -1 && checkChange(contents[cnt]))
249 it->m_widget->setProperty(
"title", contents[cnt].accelerated());
254 for (Item *it = item->m_children->first(); it != 0;
255 it = item->m_children->next())
257 if (it->m_widget && it->m_widget->isVisibleTo( item->m_widget ) )
258 calculateAccelerators(it, used);
263 void TDEAcceleratorManagerPrivate::traverseChildren(TQWidget *widget, Item *item)
265 TQObjectList *childList = widget->queryList(
"TQWidget", 0,
false,
false);
266 for ( TQObject *it = childList->first(); it; it = childList->next() )
268 TQWidget *w =
static_cast<TQWidget*
>(it);
270 if ( !w->isVisibleTo( widget ) || ( w->isTopLevel() &&
dynamic_cast<TQPopupMenu*
>(w) == NULL ) )
273 if ( TDEAcceleratorManagerPrivate::ignored_widgets.
find( w ) != TDEAcceleratorManagerPrivate::ignored_widgets.end() )
276 manageWidget(w, item);
281 void TDEAcceleratorManagerPrivate::manageWidget(TQWidget *w, Item *item)
285 TQTabBar *tabBar =
dynamic_cast<TQTabBar*
>(w);
288 manageTabBar(tabBar, item);
292 TQWidgetStack *wds =
dynamic_cast<TQWidgetStack*
>( w );
295 QWidgetStackAccelManager::manage( wds );
299 TQPopupMenu *popupMenu =
dynamic_cast<TQPopupMenu*
>(w);
303 TDEPopupAccelManager::manage(popupMenu);
307 TQWidgetStack *wdst =
dynamic_cast<TQWidgetStack*
>( w );
310 QWidgetStackAccelManager::manage( wdst );
314 TQMenuBar *menuBar =
dynamic_cast<TQMenuBar*
>(w);
317 manageMenuBar(menuBar, item);
321 if (
dynamic_cast<TQComboBox*
>(w) ||
dynamic_cast<TQLineEdit*
>(w) ||
322 dynamic_cast<TQTextEdit*
>(w) ||
dynamic_cast<TQTextView*
>(w) ||
323 dynamic_cast<TQSpinBox*
>(w) || w->tqt_cast(
"KMultiTabBar"))
327 TQLabel *
label =
dynamic_cast<TQLabel*
>(w);
329 if ( !
label->buddy() )
332 if (
label->textFormat() == TQt::RichText ||
333 (
label->textFormat() == TQt::AutoText &&
334 TQStyleSheet::mightBeRichText(
label->text() ) ) )
339 if (w->isFocusEnabled() ||
label ||
dynamic_cast<TQGroupBox*
>(w) ||
dynamic_cast<TQRadioButton*
>( w ))
343 int tprop = w->metaObject()->findProperty(
"text",
true);
345 const TQMetaProperty* p = w->metaObject()->property( tprop,
true );
346 if ( p && p->isValid() )
347 w->tqt_property( tprop, 1, &variant );
353 tprop = w->metaObject()->findProperty(
"title",
true);
355 const TQMetaProperty* p = w->metaObject()->property( tprop,
true );
356 if ( p && p->isValid() )
357 w->tqt_property( tprop, 1, &variant );
361 if (variant.isValid())
362 content = variant.toString();
364 if (!content.isEmpty())
371 if (
dynamic_cast<TQPushButton*
>(w) ||
dynamic_cast<TQCheckBox*
>(w) ||
dynamic_cast<TQRadioButton*
>(w) ||
dynamic_cast<TQLabel*
>(w))
375 if (
dynamic_cast<TQGroupBox*
>(w))
379 if (w->inherits(
"KDialogBaseButton"))
386 traverseChildren(w, item);
389 void TDEAcceleratorManagerPrivate::manageTabBar(TQTabBar *bar, Item *item)
391 for (
int i=0; i<bar->count(); i++)
393 TQString content = bar->tabAt(i)->text();
394 if (content.isEmpty())
405 void TDEAcceleratorManagerPrivate::manageMenuBar(TQMenuBar *mbar, Item *item)
410 for (uint i=0; i<mbar->count(); ++i)
412 mitem = mbar->findItem(mbar->idAt(i));
417 if (mitem->isSeparator())
436 TDEPopupAccelManager::manage(mitem->popup());
456 kdDebug(131) <<
"TDEAcceleratorManager::manage\n";
457 TDEAcceleratorManagerPrivate::changed_string = TQString::null;
458 TDEAcceleratorManagerPrivate::added_string = TQString::null;
459 TDEAcceleratorManagerPrivate::removed_string = TQString::null;
460 TDEAcceleratorManagerPrivate::programmers_mode = programmers_mode;
461 TDEAcceleratorManagerPrivate::manage(widget);
464 void TDEAcceleratorManager::last_manage(TQString &added, TQString &changed, TQString &removed)
466 added = TDEAcceleratorManagerPrivate::added_string;
467 changed = TDEAcceleratorManagerPrivate::changed_string;
468 removed = TDEAcceleratorManagerPrivate::removed_string;
478 TDEAccelString::TDEAccelString(
const TQString &input,
int initialWeight)
479 : m_pureText(input), m_weight()
481 m_orig_accel = m_pureText.find(
"(!)&");
482 if (m_orig_accel != -1)
483 m_pureText.remove(m_orig_accel, 4);
485 m_orig_accel = m_pureText.find(
"(&&)");
486 if (m_orig_accel != -1)
487 m_pureText.replace(m_orig_accel, 4,
"&");
489 m_origText = m_pureText;
491 if (m_pureText.contains(
'\t'))
492 m_pureText = m_pureText.left(m_pureText.find(
'\t'));
494 m_orig_accel = m_accel = stripAccelerator(m_pureText);
496 if (initialWeight == -1)
499 calculateWeights(initialWeight);
505 TQString TDEAccelString::accelerated()
const
507 TQString result = m_origText;
508 if (result.isEmpty())
511 if (TDEAcceleratorManagerPrivate::programmers_mode)
513 if (m_accel != m_orig_accel) {
514 int oa = m_orig_accel;
517 result.insert(m_accel,
"(!)&");
518 if (m_accel < m_orig_accel)
521 if (m_orig_accel >= 0)
522 result.replace(oa, 1,
"(&&)");
525 if (m_accel >= 0 && m_orig_accel != m_accel) {
526 result.remove(m_orig_accel, 1);
527 result.insert(m_accel,
"&");
534 TQChar TDEAccelString::accelerator()
const
536 if ((m_accel < 0) || (m_accel > (
int)m_pureText.length()))
539 return m_pureText[m_accel].lower();
543 void TDEAccelString::calculateWeights(
int initialWeight)
545 m_weight.resize(m_pureText.length());
548 bool start_character =
true;
550 while (pos<m_pureText.length())
552 TQChar c = m_pureText[pos];
554 int weight = initialWeight+1;
564 start_character =
false;
572 if ((
int)pos == accel()) {
575 if (TDEAcceleratorManagerPrivate::standardName(m_origText)) {
581 if (!c.isLetterOrNumber())
584 start_character =
true;
587 m_weight[pos] = weight;
594 int TDEAccelString::stripAccelerator(TQString &text)
601 p = text.find(
'&', p)+1;
603 if (p <= 0 || p >= (
int)text.length())
623 int TDEAccelString::maxWeight(
int &index,
const TQString &used)
628 for (uint pos=0; pos<m_pureText.length(); ++pos)
629 if (used.find(m_pureText[pos], 0, FALSE) == -1 && m_pureText[pos].latin1() != 0)
630 if (m_weight[pos] > max)
640 void TDEAccelString::dump()
643 for (uint i=0; i<m_weight.count(); ++i)
644 s += TQString(
"%1(%2) ").arg(pure()[i]).arg(m_weight[i]);
645 kdDebug() <<
"s " << s <<
endl;
684 kdDebug(131) <<
"findAccelerators\n";
685 TDEAccelStringList accel_strings = result;
688 for (TDEAccelStringList::Iterator it = result.begin(); it != result.end(); ++it) {
693 for (uint cnt=0; cnt<accel_strings.count(); ++cnt)
695 int max = 0, index = -1, accel = -1;
698 for (uint i=0; i<accel_strings.count(); ++i)
701 int m = accel_strings[i].maxWeight(a, used);
717 result[index].setAccel(accel);
718 used.append(result[index].accelerator());
733 TDEPopupAccelManager::TDEPopupAccelManager(TQPopupMenu *popup)
734 : TQObject(popup), m_popup(popup), m_count(-1)
737 connect(popup, TQ_SIGNAL(aboutToShow()), TQ_SLOT(aboutToShow()));
741 void TDEPopupAccelManager::aboutToShow()
748 if (m_count != (
int)m_popup->count())
750 findMenuEntries(m_entries);
751 calculateAccelerators();
752 m_count = m_popup->count();
756 TDEAccelStringList entries;
757 findMenuEntries(entries);
758 if (entries != m_entries)
761 calculateAccelerators();
767 void TDEPopupAccelManager::calculateAccelerators()
774 setMenuEntries(m_entries);
778 void TDEPopupAccelManager::findMenuEntries(TDEAccelStringList &list)
786 for (uint i=0; i<m_popup->count(); i++)
788 mitem = m_popup->findItem(m_popup->idAt(i));
789 if (mitem->isSeparator())
796 if (s.contains(
'\t'))
803 TDEPopupAccelManager::manage(mitem->popup());
808 void TDEPopupAccelManager::setMenuEntries(
const TDEAccelStringList &list)
813 for (uint i=0; i<m_popup->count(); i++)
815 mitem = m_popup->findItem(m_popup->idAt(i));
816 if (mitem->isSeparator())
819 if (TDEAcceleratorManagerPrivate::checkChange(list[cnt]))
820 mitem->setText(list[cnt].accelerated());
826 void TDEPopupAccelManager::manage(TQPopupMenu *popup)
829 if (popup->child(0,
"TDEPopupAccelManager",
false) == 0 )
833 void QWidgetStackAccelManager::manage( TQWidgetStack *stack )
835 if ( stack->child( 0,
"QWidgetStackAccelManager",
false ) == 0 )
836 new QWidgetStackAccelManager( stack );
839 QWidgetStackAccelManager::QWidgetStackAccelManager(TQWidgetStack *stack)
840 : TQObject(stack), m_stack(stack)
842 aboutToShow(stack->visibleWidget());
843 connect(stack, TQ_SIGNAL(aboutToShow(TQWidget *)), TQ_SLOT(aboutToShow(TQWidget *)));
846 bool QWidgetStackAccelManager::eventFilter ( TQObject * watched, TQEvent * e )
848 if ( e->type() == TQEvent::Show && tqApp->activeWindow() ) {
850 watched->removeEventFilter(
this );
855 void QWidgetStackAccelManager::aboutToShow(TQWidget *child)
859 kdDebug(131) <<
"null pointer given to aboutToShow" <<
endl;
863 child->installEventFilter(
this );
868 TDEAcceleratorManagerPrivate::ignored_widgets[widget] = 1;
871 #include "tdeaccelmanager_private.moc"
Little helper class to clean up static objects that are held as pointer.
static void findAccelerators(TDEAccelStringList &result, TQString &used)
Method to call to find the best distribution of accelerators.
@ FIRST_CHARACTER_EXTRA_WEIGHT
Additional weight for first character in string.
@ STANDARD_ACCEL
Additional weight for KDE standard accelerators.
@ MENU_TITLE_WEIGHT
Default weight for menu titles.
@ GROUP_BOX_WEIGHT
Default weight for group boxes (low priority)
@ DIALOG_BUTTON_EXTRA_WEIGHT
Additional weight for the dialog buttons (large, we basically never want these reassigned)
@ WANTED_ACCEL_EXTRA_WEIGHT
Additional weight for a 'wanted' accelerator.
@ DEFAULT_WEIGHT
Default control weight.
@ WORD_BEGINNING_EXTRA_WEIGHT
Additional weight for the beginning of a word.
@ ACTION_ELEMENT_WEIGHT
Default weight for an 'action' widget (ie, pushbuttons)
A string class handling accelerators.
static void setNoAccel(TQWidget *widget)
Use this method for a widget (and its children) you want no accels to be set on.
static void manage(TQWidget *widget)
Manages the accelerators of a widget.
kndbgstream & endl(kndbgstream &s)
Does nothing.
kdbgstream kdDebug(int area=0)
Returns a debug stream.
kdbgstream & endl(kdbgstream &s)
Prints an "\n".
TDEAction * find(const TQObject *recvr, const char *slot, TDEActionCollection *parent, const char *name=0)
TQString label(StdAccel id)
Returns a localized label for user-visible display.