Line | Source | Count |
1 | | - |
2 | | - |
3 | | - |
4 | | - |
5 | | - |
6 | | - |
7 | | - |
8 | | - |
9 | | - |
10 | | - |
11 | | - |
12 | | - |
13 | | - |
14 | | - |
15 | class QMenuBarExtension : public QToolButton | - |
16 | { | - |
17 | public: | - |
18 | explicit QMenuBarExtension(QWidget *parent); | - |
19 | | - |
20 | QSize sizeHint() const override; | - |
21 | void paintEvent(QPaintEvent *) override; | - |
22 | }; | - |
23 | | - |
24 | QMenuBarExtension::QMenuBarExtension(QWidget *parent) | - |
25 | : QToolButton(parent) | - |
26 | { | - |
27 | setObjectName(QLatin1String("qt_menubar_ext_button")); | - |
28 | setAutoRaise(true); | - |
29 | | - |
30 | setPopupMode(QToolButton::InstantPopup); | - |
31 | | - |
32 | setIcon(style()->standardIcon(QStyle::SP_ToolBarHorizontalExtensionButton, 0, parentWidget())); | - |
33 | } | - |
34 | | - |
35 | void QMenuBarExtension::paintEvent(QPaintEvent *) | - |
36 | { | - |
37 | QStylePainter p(this); | - |
38 | QStyleOptionToolButton opt; | - |
39 | initStyleOption(&opt); | - |
40 | | - |
41 | opt.features &= ~QStyleOptionToolButton::HasMenu; | - |
42 | p.drawComplexControl(QStyle::CC_ToolButton, opt); | - |
43 | } | - |
44 | | - |
45 | | - |
46 | QSize QMenuBarExtension::sizeHint() const | - |
47 | { | - |
48 | int ext = style()->pixelMetric(QStyle::PM_ToolBarExtensionExtent, 0, parentWidget()); | - |
49 | return QSize(ext, ext); | - |
50 | } | - |
51 | | - |
52 | | - |
53 | | - |
54 | | - |
55 | | - |
56 | QAction *QMenuBarPrivate::actionAt(QPoint p) const | - |
57 | { | - |
58 | for(int i = 0; i < actions.size(); ++i) { | - |
59 | if(actionRect(actions.at(i)).contains(p)) | - |
60 | return actions.at(i); | - |
61 | } | - |
62 | return 0; | - |
63 | } | - |
64 | | - |
65 | QRect QMenuBarPrivate::menuRect(bool extVisible) const | - |
66 | { | - |
67 | const QMenuBar * const q = q_func(); | - |
68 | | - |
69 | int hmargin = q->style()->pixelMetric(QStyle::PM_MenuBarPanelWidth, 0, q); | - |
70 | QRect result = q->rect(); | - |
71 | result.adjust(hmargin, 0, -hmargin, 0); | - |
72 | | - |
73 | if (extVisible) { | - |
74 | if (q->isRightToLeft()) | - |
75 | result.setLeft(result.left() + extension->sizeHint().width()); | - |
76 | else | - |
77 | result.setWidth(result.width() - extension->sizeHint().width()); | - |
78 | } | - |
79 | | - |
80 | if (leftWidget && leftWidget->isVisible()) { | - |
81 | QSize sz = leftWidget->sizeHint(); | - |
82 | if (q->isRightToLeft()) | - |
83 | result.setRight(result.right() - sz.width()); | - |
84 | else | - |
85 | result.setLeft(result.left() + sz.width()); | - |
86 | } | - |
87 | | - |
88 | if (rightWidget && rightWidget->isVisible()) { | - |
89 | QSize sz = rightWidget->sizeHint(); | - |
90 | if (q->isRightToLeft()) | - |
91 | result.setLeft(result.left() + sz.width()); | - |
92 | else | - |
93 | result.setRight(result.right() - sz.width()); | - |
94 | } | - |
95 | | - |
96 | return result; | - |
97 | } | - |
98 | | - |
99 | bool QMenuBarPrivate::isVisible(QAction *action) | - |
100 | { | - |
101 | return !hiddenActions.contains(action); | - |
102 | } | - |
103 | | - |
104 | void QMenuBarPrivate::updateGeometries() | - |
105 | { | - |
106 | QMenuBar * const q = q_func(); | - |
107 | if(!itemsDirtyTRUE | never evaluated | FALSE | never evaluated |
) | 0 |
108 | return; never executed: return; | 0 |
109 | int q_width = q->width()-(q->style()->pixelMetric(QStyle::PM_MenuBarPanelWidth, 0, q)*2); | - |
110 | int q_start = -1; | - |
111 | if(leftWidgetTRUE | never evaluated | FALSE | never evaluated |
|| rightWidgetTRUE | never evaluated | FALSE | never evaluated |
) { | 0 |
112 | int vmargin = q->style()->pixelMetric(QStyle::PM_MenuBarVMargin, 0, q) | - |
113 | + q->style()->pixelMetric(QStyle::PM_MenuBarPanelWidth, 0, q); | - |
114 | int hmargin = q->style()->pixelMetric(QStyle::PM_MenuBarHMargin, 0, q) | - |
115 | + q->style()->pixelMetric(QStyle::PM_MenuBarPanelWidth, 0, q); | - |
116 | if (leftWidgetTRUE | never evaluated | FALSE | never evaluated |
&& leftWidget->isVisible()TRUE | never evaluated | FALSE | never evaluated |
) { | 0 |
117 | QSize sz = leftWidget->sizeHint(); | - |
118 | q_width -= sz.width(); | - |
119 | q_start = sz.width(); | - |
120 | QPoint pos(hmargin, (q->height() - leftWidget->height()) / 2); | - |
121 | QRect vRect = QStyle::visualRect(q->layoutDirection(), q->rect(), QRect(pos, sz)); | - |
122 | leftWidget->setGeometry(vRect); | - |
123 | } never executed: end of block | 0 |
124 | if (rightWidgetTRUE | never evaluated | FALSE | never evaluated |
&& rightWidget->isVisible()TRUE | never evaluated | FALSE | never evaluated |
) { | 0 |
125 | QSize sz = rightWidget->sizeHint(); | - |
126 | q_width -= sz.width(); | - |
127 | QPoint pos(q->width() - sz.width() - hmargin, vmargin); | - |
128 | QRect vRect = QStyle::visualRect(q->layoutDirection(), q->rect(), QRect(pos, sz)); | - |
129 | rightWidget->setGeometry(vRect); | - |
130 | } never executed: end of block | 0 |
131 | } never executed: end of block | 0 |
132 | | - |
133 | | - |
134 | | - |
135 | | - |
136 | | - |
137 | | - |
138 | | - |
139 | calcActionRects(q_width, q_start); | - |
140 | currentAction = 0; | - |
141 | | - |
142 | if(itemsDirtyTRUE | never evaluated | FALSE | never evaluated |
) { | 0 |
143 | for(int j = 0; j < shortcutIndexMap.size()TRUE | never evaluated | FALSE | never evaluated |
; ++j) | 0 |
144 | q->releaseShortcut(shortcutIndexMap.value(j)); never executed: q->releaseShortcut(shortcutIndexMap.value(j)); | 0 |
145 | shortcutIndexMap.resize(0);clear(); | - |
146 | const int actionsCount = actions.count(); | - |
147 | shortcutIndexMap.reserve(actionsCount); | - |
148 | for (int i = 0; i < actionsCountTRUE | never evaluated | FALSE | never evaluated |
; i++) | 0 |
149 | shortcutIndexMap.append(q->grabShortcut(QKeySequence::mnemonic(actions.at(i)->text()))); never executed: shortcutIndexMap.append(q->grabShortcut(QKeySequence::mnemonic(actions.at(i)->text()))); | 0 |
150 | } never executed: end of block | 0 |
151 | | - |
152 | itemsDirty = false; | - |
153 | | - |
154 | hiddenActions.clear(); | - |
155 | | - |
156 | QRect menuRect = this->menuRect(false); | - |
157 | | - |
158 | | - |
159 | bool hasHiddenActions = false; | - |
160 | for (int i = 0; i < actions.count()TRUE | never evaluated | FALSE | never evaluated |
; ++i) { | 0 |
161 | const QRect &rect = actionRects.at(i); | - |
162 | if (rect.isValid()TRUE | never evaluated | FALSE | never evaluated |
&& !menuRect.contains(rect)TRUE | never evaluated | FALSE | never evaluated |
) { | 0 |
163 | hasHiddenActions = true; | - |
164 | break; never executed: break; | 0 |
165 | } | - |
166 | } never executed: end of block | 0 |
167 | | - |
168 | | - |
169 | if (hasHiddenActionsTRUE | never evaluated | FALSE | never evaluated |
) { | 0 |
170 | menuRect = this->menuRect(true); | - |
171 | for (int i = 0; i < actions.count()TRUE | never evaluated | FALSE | never evaluated |
; ++i) { | 0 |
172 | const QRect &rect = actionRects.at(i); | - |
173 | if (rect.isValid()TRUE | never evaluated | FALSE | never evaluated |
&& !menuRect.contains(rect)TRUE | never evaluated | FALSE | never evaluated |
) { | 0 |
174 | hiddenActions.append(actions.at(i)); | - |
175 | } never executed: end of block | 0 |
176 | } never executed: end of block | 0 |
177 | } never executed: end of block | 0 |
178 | | - |
179 | if (hiddenActions.count() > 0TRUE | never evaluated | FALSE | never evaluated |
) { | 0 |
180 | QMenu *pop = extension->menu(); | - |
181 | if (!popTRUE | never evaluated | FALSE | never evaluated |
) { | 0 |
182 | pop = new QMenu(q); | - |
183 | extension->setMenu(pop); | - |
184 | } never executed: end of block | 0 |
185 | pop->clear(); | - |
186 | pop->addActions(hiddenActions); | - |
187 | | - |
188 | int vmargin = q->style()->pixelMetric(QStyle::PM_MenuBarVMargin, 0, q); | - |
189 | int x = q->isRightToLeft()TRUE | never evaluated | FALSE | never evaluated |
| 0 |
190 | ? menuRect.left() - extension->sizeHint().width() + 1 | - |
191 | : menuRect.right(); | - |
192 | extension->setGeometry(x, vmargin, extension->sizeHint().width(), menuRect.height() - vmargin*2); | - |
193 | extension->show(); | - |
194 | } never executed: end of block else { | 0 |
195 | extension->hide(); | - |
196 | } never executed: end of block | 0 |
197 | q->updateGeometry(); | - |
198 | } never executed: end of block | 0 |
199 | | - |
200 | QRect QMenuBarPrivate::actionRect(QAction *act) const | - |
201 | { | - |
202 | const int index = actions.indexOf(act); | - |
203 | | - |
204 | | - |
205 | const_cast<QMenuBarPrivate*>(this)->updateGeometries(); | - |
206 | | - |
207 | if (index < 0 || index >= actionRects.count()) | - |
208 | return QRect(); | - |
209 | | - |
210 | return actionRects.at(index); | - |
211 | } | - |
212 | | - |
213 | void QMenuBarPrivate::focusFirstAction() | - |
214 | { | - |
215 | if(!currentAction) { | - |
216 | updateGeometries(); | - |
217 | int index = 0; | - |
218 | while (index < actions.count() && actionRects.at(index).isNull()) ++index; | - |
219 | if (index < actions.count()) | - |
220 | setCurrentAction(actions.at(index)); | - |
221 | } | - |
222 | } | - |
223 | | - |
224 | void QMenuBarPrivate::setKeyboardMode(bool b) | - |
225 | { | - |
226 | QMenuBar * const q = q_func(); | - |
227 | if (b && !q->style()->styleHint(QStyle::SH_MenuBar_AltKeyNavigation, 0, q)) { | - |
228 | setCurrentAction(0); | - |
229 | return; | - |
230 | } | - |
231 | keyboardState = b; | - |
232 | if(b) { | - |
233 | QWidget *fw = QApplication::focusWidget(); | - |
234 | if (fw != q) | - |
235 | keyboardFocusWidget = fw; | - |
236 | focusFirstAction(); | - |
237 | q->setFocus(Qt::MenuBarFocusReason); | - |
238 | } else { | - |
239 | if(!popupState) | - |
240 | setCurrentAction(0); | - |
241 | if(keyboardFocusWidget) { | - |
242 | if (QApplication::focusWidget() == q) | - |
243 | keyboardFocusWidget->setFocus(Qt::MenuBarFocusReason); | - |
244 | keyboardFocusWidget = 0; | - |
245 | } | - |
246 | } | - |
247 | q->update(); | - |
248 | } | - |
249 | | - |
250 | void QMenuBarPrivate::popupAction(QAction *action, bool activateFirst) | - |
251 | { | - |
252 | QMenuBar * const q = q_func(); | - |
253 | if(!action || !action->menu() || closePopupMode) | - |
254 | return; | - |
255 | popupState = true; | - |
256 | if (action->isEnabled() && action->menu()->isEnabled()) { | - |
257 | closePopupMode = 0; | - |
258 | activeMenu = action->menu(); | - |
259 | activeMenu->d_func()->causedPopup.widget = q; | - |
260 | activeMenu->d_func()->causedPopup.action = action; | - |
261 | | - |
262 | QRect adjustedActionRect = actionRect(action); | - |
263 | QPoint pos(q->mapToGlobal(QPoint(adjustedActionRect.left(), adjustedActionRect.bottom() + 1))); | - |
264 | QSize popup_size = activeMenu->sizeHint(); | - |
265 | | - |
266 | | - |
267 | QRect screenRect = QApplication::desktop()->screenGeometry(pos + QPoint(adjustedActionRect.width() / 2, 0)); | - |
268 | pos = QPoint(qMax(pos.x(), screenRect.x()), qMax(pos.y(), screenRect.y())); | - |
269 | | - |
270 | const bool fitUp = (q->mapToGlobal(adjustedActionRect.topLeft()).y() >= popup_size.height()); | - |
271 | const bool fitDown = (pos.y() + popup_size.height() <= screenRect.bottom()); | - |
272 | const bool rtl = q->isRightToLeft(); | - |
273 | const int actionWidth = adjustedActionRect.width(); | - |
274 | | - |
275 | if (!fitUp && !fitDown) { | - |
276 | bool shouldShiftToRight = !rtl; | - |
277 | if (rtl && popup_size.width() > pos.x()) | - |
278 | shouldShiftToRight = true; | - |
279 | else if (actionWidth + popup_size.width() + pos.x() > screenRect.right()) | - |
280 | shouldShiftToRight = false; | - |
281 | | - |
282 | if (shouldShiftToRight) { | - |
283 | pos.rx() += actionWidth + (rtl ? popup_size.width() : 0); | - |
284 | } else { | - |
285 | | - |
286 | if (!rtl) | - |
287 | pos.rx() -= popup_size.width(); | - |
288 | } | - |
289 | } else if (rtl) { | - |
290 | pos.rx() += actionWidth; | - |
291 | } | - |
292 | | - |
293 | if(!defaultPopDown || (fitUp && !fitDown)) | - |
294 | pos.setY(qMax(screenRect.y(), q->mapToGlobal(QPoint(0, adjustedActionRect.top()-popup_size.height())).y())); | - |
295 | activeMenu->popup(pos); | - |
296 | if(activateFirst) | - |
297 | activeMenu->d_func()->setFirstActionActive(); | - |
298 | } | - |
299 | q->update(actionRect(action)); | - |
300 | } | - |
301 | | - |
302 | void QMenuBarPrivate::setCurrentAction(QAction *action, bool popup, bool activateFirst) | - |
303 | { | - |
304 | if(currentAction == action && popup == popupState) | - |
305 | return; | - |
306 | | - |
307 | autoReleaseTimer.stop(); | - |
308 | | - |
309 | doChildEffects = (popup && !activeMenu); | - |
310 | QMenuBar * const q = q_func(); | - |
311 | QWidget *fw = 0; | - |
312 | if(QMenu *menu = activeMenu) { | - |
313 | activeMenu = 0; | - |
314 | if (popup) { | - |
315 | fw = q->window()->focusWidget(); | - |
316 | q->setFocus(Qt::NoFocusReason); | - |
317 | } | - |
318 | menu->hide(); | - |
319 | } | - |
320 | | - |
321 | if(currentAction) | - |
322 | q->update(actionRect(currentAction)); | - |
323 | | - |
324 | popupState = popup; | - |
325 | | - |
326 | QAction *previousAction = currentAction; | - |
327 | | - |
328 | currentAction = action; | - |
329 | if (action && action->isEnabled()) { | - |
330 | activateAction(action, QAction::Hover); | - |
331 | if(popup) | - |
332 | popupAction(action, activateFirst); | - |
333 | q->update(actionRect(action)); | - |
334 | | - |
335 | } else if (previousAction) { | - |
336 | QString empty; | - |
337 | QStatusTipEvent tip(empty); | - |
338 | QApplication::sendEvent(q, &tip); | - |
339 | | - |
340 | } | - |
341 | if (fw) | - |
342 | fw->setFocus(Qt::NoFocusReason); | - |
343 | } | - |
344 | | - |
345 | void QMenuBarPrivate::calcActionRects(int max_width, int start) const | - |
346 | { | - |
347 | const QMenuBar * const q = q_func(); | - |
348 | | - |
349 | if(!itemsDirty) | - |
350 | return; | - |
351 | | - |
352 | | - |
353 | actionRects.resize(actions.count()); | - |
354 | actionRects.fill(QRect()); | - |
355 | | - |
356 | const QStyle *style = q->style(); | - |
357 | | - |
358 | const int itemSpacing = style->pixelMetric(QStyle::PM_MenuBarItemSpacing, 0, q); | - |
359 | int max_item_height = 0, separator = -1, separator_start = 0, separator_len = 0; | - |
360 | | - |
361 | | - |
362 | const QFontMetrics fm = q->fontMetrics(); | - |
363 | const int hmargin = style->pixelMetric(QStyle::PM_MenuBarHMargin, 0, q), | - |
364 | vmargin = style->pixelMetric(QStyle::PM_MenuBarVMargin, 0, q), | - |
365 | icone = style->pixelMetric(QStyle::PM_SmallIconSize, 0, q); | - |
366 | for(int i = 0; i < actions.count(); i++) { | - |
367 | QAction *action = actions.at(i); | - |
368 | if(!action->isVisible()) | - |
369 | continue; | - |
370 | | - |
371 | QSize sz; | - |
372 | | - |
373 | | - |
374 | if(action->isSeparator()) { | - |
375 | if (style->styleHint(QStyle::SH_DrawMenuBarSeparator, 0, q)) | - |
376 | separator = i; | - |
377 | continue; | - |
378 | } else { | - |
379 | const QString s = action->text(); | - |
380 | QIcon is = action->icon(); | - |
381 | | - |
382 | if (!is.isNull()) | - |
383 | sz = sz.expandedTo(QSize(icone, icone)); | - |
384 | else if (!s.isEmpty()) | - |
385 | sz = fm.size(Qt::TextShowMnemonic, s); | - |
386 | } | - |
387 | | - |
388 | | - |
389 | QStyleOptionMenuItem opt; | - |
390 | q->initStyleOption(&opt, action); | - |
391 | sz = q->style()->sizeFromContents(QStyle::CT_MenuBarItem, &opt, sz, q); | - |
392 | | - |
393 | if(!sz.isEmpty()) { | - |
394 | { | - |
395 | int iWidth = sz.width() + itemSpacing; | - |
396 | if(separator == -1) | - |
397 | separator_start += iWidth; | - |
398 | else | - |
399 | separator_len += iWidth; | - |
400 | } | - |
401 | | - |
402 | max_item_height = qMax(max_item_height, sz.height()); | - |
403 | | - |
404 | actionRects[i] = QRect(0, 0, sz.width(), sz.height()); | - |
405 | } | - |
406 | } | - |
407 | | - |
408 | | - |
409 | const int fw = q->style()->pixelMetric(QStyle::PM_MenuBarPanelWidth, 0, q); | - |
410 | int x = fw + ((start == -1) ? hmargin : start) + itemSpacing; | - |
411 | int y = fw + vmargin; | - |
412 | for(int i = 0; i < actions.count(); i++) { | - |
413 | QRect &rect = actionRects[i]; | - |
414 | if (rect.isNull()) | - |
415 | continue; | - |
416 | | - |
417 | | - |
418 | rect.setHeight(max_item_height); | - |
419 | | - |
420 | | - |
421 | if(separator != -1 && i >= separator) { | - |
422 | int left = (max_width - separator_len - hmargin - itemSpacing) + (x - separator_start - hmargin); | - |
423 | if(left < separator_start) { | - |
424 | separator_start = x = hmargin; | - |
425 | y += max_item_height; | - |
426 | } | - |
427 | rect.moveLeft(left); | - |
428 | } else { | - |
429 | rect.moveLeft(x); | - |
430 | } | - |
431 | rect.moveTop(y); | - |
432 | | - |
433 | | - |
434 | x += rect.width() + itemSpacing; | - |
435 | | - |
436 | | - |
437 | rect = QStyle::visualRect(q->layoutDirection(), q->rect(), rect); | - |
438 | } | - |
439 | } | - |
440 | | - |
441 | void QMenuBarPrivate::activateAction(QAction *action, QAction::ActionEvent action_e) | - |
442 | { | - |
443 | QMenuBar * const q = q_func(); | - |
444 | if (!action || !action->isEnabled()) | - |
445 | return; | - |
446 | action->activate(action_e); | - |
447 | if (action_e == QAction::Hover) | - |
448 | action->showStatusText(q); | - |
449 | | - |
450 | | - |
451 | | - |
452 | | - |
453 | | - |
454 | } | - |
455 | | - |
456 | | - |
457 | void QMenuBarPrivate::_q_actionTriggered() | - |
458 | { | - |
459 | QMenuBar * const q = q_func(); | - |
460 | if (QAction *action = qobject_cast<QAction *>(q->sender())) { | - |
461 | q->triggered(action); | - |
462 | } | - |
463 | } | - |
464 | | - |
465 | void QMenuBarPrivate::_q_actionHovered() | - |
466 | { | - |
467 | QMenuBar * const q = q_func(); | - |
468 | if (QAction *action = qobject_cast<QAction *>(q->sender())) { | - |
469 | q->hovered(action); | - |
470 | | - |
471 | if (QAccessible::isActive()) { | - |
472 | int actionIndex = actions.indexOf(action); | - |
473 | QAccessibleEvent focusEvent(q, QAccessible::Focus); | - |
474 | focusEvent.setChild(actionIndex); | - |
475 | QAccessible::updateAccessibility(&focusEvent); | - |
476 | } | - |
477 | | - |
478 | } | - |
479 | } | - |
480 | void QMenuBar::initStyleOption(QStyleOptionMenuItem *option, const QAction *action) const | - |
481 | { | - |
482 | if (!option || !action) | - |
483 | return; | - |
484 | const QMenuBarPrivate * const d = d_func(); | - |
485 | option->palette = palette(); | - |
486 | option->state = QStyle::State_None; | - |
487 | if (isEnabled() && action->isEnabled()) | - |
488 | option->state |= QStyle::State_Enabled; | - |
489 | else | - |
490 | option->palette.setCurrentColorGroup(QPalette::Disabled); | - |
491 | option->fontMetrics = fontMetrics(); | - |
492 | if (d->currentAction && d->currentAction == action) { | - |
493 | option->state |= QStyle::State_Selected; | - |
494 | if (d->popupState && !d->closePopupMode) | - |
495 | option->state |= QStyle::State_Sunken; | - |
496 | } | - |
497 | if (hasFocus() || d->currentAction) | - |
498 | option->state |= QStyle::State_HasFocus; | - |
499 | option->menuRect = rect(); | - |
500 | option->menuItemType = QStyleOptionMenuItem::Normal; | - |
501 | option->checkType = QStyleOptionMenuItem::NotCheckable; | - |
502 | option->text = action->text(); | - |
503 | option->icon = action->icon(); | - |
504 | } | - |
505 | void QMenuBarPrivate::init() | - |
506 | { | - |
507 | QMenuBar * const q = q_func(); | - |
508 | q->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Minimum); | - |
509 | q->setAttribute(Qt::WA_CustomWhatsThis); | - |
510 | | - |
511 | if (!QApplication::instance()->testAttribute(Qt::AA_DontUseNativeMenuBar)) | - |
512 | platformMenuBar = QGuiApplicationPrivate::platformTheme()->createPlatformMenuBar(); | - |
513 | | - |
514 | if (platformMenuBar) | - |
515 | q->hide(); | - |
516 | q->setBackgroundRole(QPalette::Button); | - |
517 | handleReparent(); | - |
518 | q->setMouseTracking(q->style()->styleHint(QStyle::SH_MenuBar_MouseTracking, 0, q)); | - |
519 | | - |
520 | extension = new QMenuBarExtension(q); | - |
521 | extension->setFocusPolicy(Qt::NoFocus); | - |
522 | extension->hide(); | - |
523 | } | - |
524 | | - |
525 | | - |
526 | QAction *QMenuBarPrivate::getNextAction(const int _start, const int increment) const | - |
527 | { | - |
528 | const QMenuBar * const q = q_func(); | - |
529 | const_cast<QMenuBarPrivate*>(this)->updateGeometries(); | - |
530 | bool allowActiveAndDisabled = q->style()->styleHint(QStyle::SH_Menu_AllowActiveAndDisabled, 0, q); | - |
531 | const int start = (_start == -1 && increment == -1) ? actions.count() : _start; | - |
532 | const int end = increment == -1 ? 0 : actions.count() - 1; | - |
533 | | - |
534 | for (int i = start; i != end;) { | - |
535 | i += increment; | - |
536 | QAction *current = actions.at(i); | - |
537 | if (!actionRects.at(i).isNull() && (allowActiveAndDisabled || current->isEnabled())) | - |
538 | return current; | - |
539 | } | - |
540 | | - |
541 | if (_start != -1) | - |
542 | return getNextAction(-1, increment); | - |
543 | | - |
544 | return 0; | - |
545 | } | - |
546 | | - |
547 | | - |
548 | | - |
549 | | - |
550 | QMenuBar::QMenuBar(QWidget *parent) : QWidget(*new QMenuBarPrivate, parent, 0) | - |
551 | { | - |
552 | QMenuBarPrivate * const d = d_func(); | - |
553 | d->init(); | - |
554 | } | - |
555 | | - |
556 | | - |
557 | | - |
558 | | - |
559 | | - |
560 | QMenuBar::~QMenuBar() | - |
561 | { | - |
562 | QMenuBarPrivate * const d = d_func(); | - |
563 | delete d->platformMenuBar; | - |
564 | d->platformMenuBar = 0; | - |
565 | | - |
566 | | - |
567 | | - |
568 | | - |
569 | | - |
570 | } | - |
571 | QAction *QMenuBar::addAction(const QString &text) | - |
572 | { | - |
573 | QAction *ret = new QAction(text, this); | - |
574 | addAction(ret); | - |
575 | return ret; | - |
576 | } | - |
577 | QAction *QMenuBar::addAction(const QString &text, const QObject *receiver, const char* member) | - |
578 | { | - |
579 | QAction *ret = new QAction(text, this); | - |
580 | QObject::connect(ret, qFlagLocation("2""triggered(bool)" "\0" __FILE__ ":" "793"), receiver, member); | - |
581 | addAction(ret); | - |
582 | return ret; | - |
583 | } | - |
584 | | - |
585 | | - |
586 | | - |
587 | | - |
588 | | - |
589 | | - |
590 | | - |
591 | QMenu *QMenuBar::addMenu(const QString &title) | - |
592 | { | - |
593 | QMenu *menu = new QMenu(title, this); | - |
594 | addAction(menu->menuAction()); | - |
595 | return menu; | - |
596 | } | - |
597 | | - |
598 | | - |
599 | | - |
600 | | - |
601 | | - |
602 | | - |
603 | | - |
604 | QMenu *QMenuBar::addMenu(const QIcon &icon, const QString &title) | - |
605 | { | - |
606 | QMenu *menu = new QMenu(title, this); | - |
607 | menu->setIcon(icon); | - |
608 | addAction(menu->menuAction()); | - |
609 | return menu; | - |
610 | } | - |
611 | QAction *QMenuBar::addMenu(QMenu *menu) | - |
612 | { | - |
613 | QAction *action = menu->menuAction(); | - |
614 | addAction(action); | - |
615 | return action; | - |
616 | } | - |
617 | | - |
618 | | - |
619 | | - |
620 | | - |
621 | QAction *QMenuBar::addSeparator() | - |
622 | { | - |
623 | QAction *ret = new QAction(this); | - |
624 | ret->setSeparator(true); | - |
625 | addAction(ret); | - |
626 | return ret; | - |
627 | } | - |
628 | QAction *QMenuBar::insertSeparator(QAction *before) | - |
629 | { | - |
630 | QAction *action = new QAction(this); | - |
631 | action->setSeparator(true); | - |
632 | insertAction(before, action); | - |
633 | return action; | - |
634 | } | - |
635 | | - |
636 | | - |
637 | | - |
638 | | - |
639 | | - |
640 | | - |
641 | | - |
642 | QAction *QMenuBar::insertMenu(QAction *before, QMenu *menu) | - |
643 | { | - |
644 | QAction *action = menu->menuAction(); | - |
645 | insertAction(before, action); | - |
646 | return action; | - |
647 | } | - |
648 | | - |
649 | | - |
650 | | - |
651 | | - |
652 | | - |
653 | QAction *QMenuBar::activeAction() const | - |
654 | { | - |
655 | const QMenuBarPrivate * const d = d_func(); | - |
656 | return d->currentAction; | - |
657 | } | - |
658 | | - |
659 | | - |
660 | | - |
661 | | - |
662 | | - |
663 | | - |
664 | void QMenuBar::setActiveAction(QAction *act) | - |
665 | { | - |
666 | QMenuBarPrivate * const d = d_func(); | - |
667 | d->setCurrentAction(act, true, false); | - |
668 | } | - |
669 | void QMenuBar::clear() | - |
670 | { | - |
671 | QList<QAction*> acts = actions(); | - |
672 | for(int i = 0; i < acts.size(); i++) | - |
673 | removeAction(acts[i]); | - |
674 | } | - |
675 | void QMenuBar::setDefaultUp(bool b) | - |
676 | { | - |
677 | QMenuBarPrivate * const d = d_func(); | - |
678 | d->defaultPopDown = !b; | - |
679 | } | - |
680 | | - |
681 | bool QMenuBar::isDefaultUp() const | - |
682 | { | - |
683 | const QMenuBarPrivate * const d = d_func(); | - |
684 | return !d->defaultPopDown; | - |
685 | } | - |
686 | | - |
687 | | - |
688 | | - |
689 | | - |
690 | void QMenuBar::resizeEvent(QResizeEvent *) | - |
691 | { | - |
692 | QMenuBarPrivate * const d = d_func(); | - |
693 | d->itemsDirty = true; | - |
694 | d->updateGeometries(); | - |
695 | } | - |
696 | | - |
697 | | - |
698 | | - |
699 | | - |
700 | void QMenuBar::paintEvent(QPaintEvent *e) | - |
701 | { | - |
702 | QMenuBarPrivate * const d = d_func(); | - |
703 | QPainter p(this); | - |
704 | QRegion emptyArea(rect()); | - |
705 | | - |
706 | | - |
707 | for (int i = 0; i < d->actions.count(); ++i) { | - |
708 | QAction *action = d->actions.at(i); | - |
709 | QRect adjustedActionRect = d->actionRect(action); | - |
710 | if (adjustedActionRect.isEmpty() || !d->isVisible(action)) | - |
711 | continue; | - |
712 | if(!e->rect().intersects(adjustedActionRect)) | - |
713 | continue; | - |
714 | | - |
715 | emptyArea -= adjustedActionRect; | - |
716 | QStyleOptionMenuItem opt; | - |
717 | initStyleOption(&opt, action); | - |
718 | opt.rect = adjustedActionRect; | - |
719 | p.setClipRect(adjustedActionRect); | - |
720 | style()->drawControl(QStyle::CE_MenuBarItem, &opt, &p, this); | - |
721 | } | - |
722 | | - |
723 | if(int fw = style()->pixelMetric(QStyle::PM_MenuBarPanelWidth, 0, this)) { | - |
724 | QRegion borderReg; | - |
725 | borderReg += QRect(0, 0, fw, height()); | - |
726 | borderReg += QRect(width()-fw, 0, fw, height()); | - |
727 | borderReg += QRect(0, 0, width(), fw); | - |
728 | borderReg += QRect(0, height()-fw, width(), fw); | - |
729 | p.setClipRegion(borderReg); | - |
730 | emptyArea -= borderReg; | - |
731 | QStyleOptionFrame frame; | - |
732 | frame.rect = rect(); | - |
733 | frame.palette = palette(); | - |
734 | frame.state = QStyle::State_None; | - |
735 | frame.lineWidth = style()->pixelMetric(QStyle::PM_MenuBarPanelWidth); | - |
736 | frame.midLineWidth = 0; | - |
737 | style()->drawPrimitive(QStyle::PE_PanelMenuBar, &frame, &p, this); | - |
738 | } | - |
739 | p.setClipRegion(emptyArea); | - |
740 | QStyleOptionMenuItem menuOpt; | - |
741 | menuOpt.palette = palette(); | - |
742 | menuOpt.state = QStyle::State_None; | - |
743 | menuOpt.menuItemType = QStyleOptionMenuItem::EmptyArea; | - |
744 | menuOpt.checkType = QStyleOptionMenuItem::NotCheckable; | - |
745 | menuOpt.rect = rect(); | - |
746 | menuOpt.menuRect = rect(); | - |
747 | style()->drawControl(QStyle::CE_MenuBarEmptyArea, &menuOpt, &p, this); | - |
748 | } | - |
749 | | - |
750 | | - |
751 | | - |
752 | | - |
753 | void QMenuBar::setVisible(bool visible) | - |
754 | { | - |
755 | if (isNativeMenuBar()) { | - |
756 | if (!visible) | - |
757 | QWidget::setVisible(false); | - |
758 | return; | - |
759 | } | - |
760 | QWidget::setVisible(visible); | - |
761 | } | - |
762 | | - |
763 | | - |
764 | | - |
765 | | - |
766 | void QMenuBar::mousePressEvent(QMouseEvent *e) | - |
767 | { | - |
768 | QMenuBarPrivate * const d = d_func(); | - |
769 | if(e->button() != Qt::LeftButton) | - |
770 | return; | - |
771 | | - |
772 | d->mouseDown = true; | - |
773 | | - |
774 | QAction *action = d->actionAt(e->pos()); | - |
775 | if (!action || !d->isVisible(action) || !action->isEnabled()) { | - |
776 | d->setCurrentAction(0); | - |
777 | | - |
778 | if (QWhatsThis::inWhatsThisMode()) | - |
779 | QWhatsThis::showText(e->globalPos(), d->whatsThis, this); | - |
780 | | - |
781 | return; | - |
782 | } | - |
783 | | - |
784 | if(d->currentAction == action && d->popupState) { | - |
785 | if(QMenu *menu = d->activeMenu) { | - |
786 | d->activeMenu = 0; | - |
787 | menu->setAttribute(Qt::WA_NoMouseReplay); | - |
788 | menu->hide(); | - |
789 | } | - |
790 | } else { | - |
791 | d->setCurrentAction(action, true); | - |
792 | } | - |
793 | } | - |
794 | | - |
795 | | - |
796 | | - |
797 | | - |
798 | void QMenuBar::mouseReleaseEvent(QMouseEvent *e) | - |
799 | { | - |
800 | QMenuBarPrivate * const d = d_func(); | - |
801 | if(e->button() != Qt::LeftButton || !d->mouseDown) | - |
802 | return; | - |
803 | | - |
804 | d->mouseDown = false; | - |
805 | QAction *action = d->actionAt(e->pos()); | - |
806 | if((d->closePopupMode && action == d->currentAction) || !action || !action->menu()) { | - |
807 | | - |
808 | | - |
809 | d->setCurrentAction(action, false); | - |
810 | if(action) | - |
811 | d->activateAction(action, QAction::Trigger); | - |
812 | } | - |
813 | d->closePopupMode = 0; | - |
814 | } | - |
815 | | - |
816 | | - |
817 | | - |
818 | | - |
819 | void QMenuBar::keyPressEvent(QKeyEvent *e) | - |
820 | { | - |
821 | QMenuBarPrivate * const d = d_func(); | - |
822 | d->updateGeometries(); | - |
823 | int key = e->key(); | - |
824 | if(isRightToLeft()) { | - |
825 | if(key == Qt::Key_Left) | - |
826 | key = Qt::Key_Right; | - |
827 | else if(key == Qt::Key_Right) | - |
828 | key = Qt::Key_Left; | - |
829 | } | - |
830 | if(key == Qt::Key_Tab) | - |
831 | key = Qt::Key_Right; | - |
832 | else if(key == Qt::Key_Backtab) | - |
833 | key = Qt::Key_Left; | - |
834 | | - |
835 | bool key_consumed = false; | - |
836 | switch(key) { | - |
837 | case Qt::Key_Up: | - |
838 | case Qt::Key_Down: | - |
839 | case Qt::Key_Enter: | - |
840 | case Qt::Key_Space: | - |
841 | case Qt::Key_Return: { | - |
842 | if(!style()->styleHint(QStyle::SH_MenuBar_AltKeyNavigation, 0, this) || !d->currentAction) | - |
843 | break; | - |
844 | if(d->currentAction->menu()) { | - |
845 | d->popupAction(d->currentAction, true); | - |
846 | } else if(key == Qt::Key_Enter || key == Qt::Key_Return || key == Qt::Key_Space) { | - |
847 | d->activateAction(d->currentAction, QAction::Trigger); | - |
848 | d->setCurrentAction(d->currentAction, false); | - |
849 | d->setKeyboardMode(false); | - |
850 | } | - |
851 | key_consumed = true; | - |
852 | break; } | - |
853 | | - |
854 | case Qt::Key_Right: | - |
855 | case Qt::Key_Left: { | - |
856 | if(d->currentAction) { | - |
857 | int index = d->actions.indexOf(d->currentAction); | - |
858 | if (QAction *nextAction = d->getNextAction(index, key == Qt::Key_Left ? -1 : +1)) { | - |
859 | d->setCurrentAction(nextAction, d->popupState, true); | - |
860 | key_consumed = true; | - |
861 | } | - |
862 | } | - |
863 | break; } | - |
864 | | - |
865 | default: | - |
866 | key_consumed = false; | - |
867 | } | - |
868 | | - |
869 | if (!key_consumed && e->matches(QKeySequence::Cancel)) { | - |
870 | d->setCurrentAction(0); | - |
871 | d->setKeyboardMode(false); | - |
872 | key_consumed = true; | - |
873 | } | - |
874 | | - |
875 | if(!key_consumed && | - |
876 | (!e->modifiers() || | - |
877 | (e->modifiers()&(Qt::MetaModifier|Qt::AltModifier))) && e->text().length()==1 && !d->popupState) { | - |
878 | int clashCount = 0; | - |
879 | QAction *first = 0, *currentSelected = 0, *firstAfterCurrent = 0; | - |
880 | { | - |
881 | QChar c = e->text()[0].toUpper(); | - |
882 | for(int i = 0; i < d->actions.size(); ++i) { | - |
883 | if (d->actionRects.at(i).isNull()) | - |
884 | continue; | - |
885 | QAction *act = d->actions.at(i); | - |
886 | QString s = act->text(); | - |
887 | if(!s.isEmpty()) { | - |
888 | int ampersand = s.indexOf(QLatin1Char('&')); | - |
889 | if(ampersand >= 0) { | - |
890 | if(s[ampersand+1].toUpper() == c) { | - |
891 | clashCount++; | - |
892 | if(!first) | - |
893 | first = act; | - |
894 | if(act == d->currentAction) | - |
895 | currentSelected = act; | - |
896 | else if (!firstAfterCurrent && currentSelected) | - |
897 | firstAfterCurrent = act; | - |
898 | } | - |
899 | } | - |
900 | } | - |
901 | } | - |
902 | } | - |
903 | QAction *next_action = 0; | - |
904 | if(clashCount >= 1) { | - |
905 | if(clashCount == 1 || !d->currentAction || (currentSelected && !firstAfterCurrent)) | - |
906 | next_action = first; | - |
907 | else | - |
908 | next_action = firstAfterCurrent; | - |
909 | } | - |
910 | if(next_action) { | - |
911 | key_consumed = true; | - |
912 | d->setCurrentAction(next_action, true, true); | - |
913 | } | - |
914 | } | - |
915 | if(key_consumed) | - |
916 | e->accept(); | - |
917 | else | - |
918 | e->ignore(); | - |
919 | } | - |
920 | | - |
921 | | - |
922 | | - |
923 | | - |
924 | void QMenuBar::mouseMoveEvent(QMouseEvent *e) | - |
925 | { | - |
926 | QMenuBarPrivate * const d = d_func(); | - |
927 | if (!(e->buttons() & Qt::LeftButton)) | - |
928 | d->mouseDown = false; | - |
929 | bool popupState = d->popupState || d->mouseDown; | - |
930 | QAction *action = d->actionAt(e->pos()); | - |
931 | if ((action && d->isVisible(action)) || !popupState) | - |
932 | d->setCurrentAction(action, popupState); | - |
933 | } | - |
934 | | - |
935 | | - |
936 | | - |
937 | | - |
938 | void QMenuBar::leaveEvent(QEvent *) | - |
939 | { | - |
940 | QMenuBarPrivate * const d = d_func(); | - |
941 | if((!hasFocus() && !d->popupState) || | - |
942 | (d->currentAction && d->currentAction->menu() == 0)) | - |
943 | d->setCurrentAction(0); | - |
944 | } | - |
945 | | - |
946 | QPlatformMenu *QMenuBarPrivate::getPlatformMenu(QAction *action) | - |
947 | { | - |
948 | if (!actionTRUE | never evaluated | FALSE | never evaluated |
|| !action->menu()TRUE | never evaluated | FALSE | never evaluated |
) | 0 |
949 | return never executed: return 0; 0;never executed: return 0; | 0 |
950 | | - |
951 | returnQPlatformMenu *platformMenu = action->menu()->platformMenu(); | - |
952 | if (!platformMenuTRUE | never evaluated | FALSE | never evaluated |
&& platformMenuBarTRUE | never evaluated | FALSE | never evaluated |
) { | 0 |
953 | platformMenu = platformMenuBar->createMenu(); | - |
954 | if (platformMenuTRUE | never evaluated | FALSE | never evaluated |
) | 0 |
955 | action->menu()->setPlatformMenu(platformMenu); never executed: action->menu()->setPlatformMenu(platformMenu); | 0 |
956 | } never executed: end of block | 0 |
957 | | - |
958 | return never executed: return platformMenu; platformMenu;never executed: return platformMenu; | 0 |
959 | } | - |
960 | | - |
961 | | - |
962 | | - |
963 | | - |
964 | void QMenuBar::actionEvent(QActionEvent *e) | - |
965 | { | - |
966 | QMenuBarPrivate * const d = d_func(); | - |
967 | d->itemsDirty = true; | - |
968 | | - |
969 | if (d->platformMenuBarTRUE | never evaluated | FALSE | never evaluated |
) { | 0 |
970 | | - |
971 | QPlatformMenuBar *nativeMenuBar = d->platformMenuBar; | - |
972 | | - |
973 | | - |
974 | | - |
975 | if (!nativeMenuBarTRUE | never evaluated | FALSE | never evaluated |
) | 0 |
976 | return; never executed: return; | 0 |
977 | | - |
978 | if (e->type() == QEvent::ActionAddedTRUE | never evaluated | FALSE | never evaluated |
) { | 0 |
979 | QPlatformMenu *menu = d->getPlatformMenu(e->action()); | - |
980 | if (menuTRUE | never evaluated | FALSE | never evaluated |
) { | 0 |
981 | QPlatformMenu* beforeMenu = __null; | - |
982 | for (int beforeIndex = d->indexOf(e->action()) + 1; | - |
983 | !beforeMenuTRUE | never evaluated | FALSE | never evaluated |
&& (TRUE | never evaluated | FALSE | never evaluated |
beforeIndex < actions().size())TRUE | never evaluated | FALSE | never evaluated |
; | 0 |
984 | ++beforeIndex) | - |
985 | { | - |
986 | beforeMenu = d->getPlatformMenu(actions().at(beforeIndex)); | - |
987 | } never executed: end of block | 0 |
988 | | - |
989 | menu->setTag(reinterpret_cast<quintptr>(e->action())); | - |
990 | menu->setText(e->action()->text()); | - |
991 | d->platformMenuBar->insertMenu(menu, beforeMenu); | - |
992 | } never executed: end of block | 0 |
993 | } never executed: end of block else if (e->type() == QEvent::ActionRemovedTRUE | never evaluated | FALSE | never evaluated |
) { | 0 |
994 | QPlatformMenu *menu = d->getPlatformMenu(e->action()); | - |
995 | if (menuTRUE | never evaluated | FALSE | never evaluated |
) | 0 |
996 | d->platformMenuBar->removeMenu(menu); never executed: d->platformMenuBar->removeMenu(menu); | 0 |
997 | } never executed: end of block else if (e->type() == QEvent::ActionChangedTRUE | never evaluated | FALSE | never evaluated |
) { | 0 |
998 | QPlatformMenu* cur = d->platformMenuBar->menuForTag(reinterpret_cast<quintptr>(e->action())); | - |
999 | QPlatformMenu *menu = d->getPlatformMenu(e->action()); | - |
1000 | | - |
1001 | | - |
1002 | | - |
1003 | if (menu != curTRUE | never evaluated | FALSE | never evaluated |
) { | 0 |
1004 | if (curTRUE | never evaluated | FALSE | never evaluated |
) | 0 |
1005 | d->platformMenuBar->removeMenu(cur); never executed: d->platformMenuBar->removeMenu(cur); | 0 |
1006 | if (menuTRUE | never evaluated | FALSE | never evaluated |
) { | 0 |
1007 | menu->setTag(reinterpret_cast<quintptr>(e->action())); | - |
1008 | | - |
1009 | QPlatformMenu* beforeMenu = __null; | - |
1010 | for (int beforeIndex = d->indexOf(e->action()) + 1; | - |
1011 | !beforeMenuTRUE | never evaluated | FALSE | never evaluated |
&& (TRUE | never evaluated | FALSE | never evaluated |
beforeIndex < actions().size())TRUE | never evaluated | FALSE | never evaluated |
; | 0 |
1012 | ++beforeIndex) | - |
1013 | { | - |
1014 | beforeMenu = d->getPlatformMenu(actions().at(beforeIndex)); | - |
1015 | } never executed: end of block | 0 |
1016 | d->platformMenuBar->insertMenu(menu, beforeMenu); | - |
1017 | } never executed: end of block | 0 |
1018 | } never executed: end of block else if (menuTRUE | never evaluated | FALSE | never evaluated |
) { | 0 |
1019 | menu->setText(e->action()->text()); | - |
1020 | menu->setVisible(e->action()->isVisible()); | - |
1021 | menu->setEnabled(e->action()->isEnabled()); | - |
1022 | d->platformMenuBar->syncMenu(menu); | - |
1023 | } never executed: end of block | 0 |
1024 | } never executed: end of block | 0 |
1025 | } never executed: end of block | 0 |
1026 | | - |
1027 | if(e->type() == QEvent::ActionAddedTRUE | never evaluated | FALSE | never evaluated |
) { | 0 |
1028 | connect(e->action(), qFlagLocation("2""triggered()" "\0" __FILE__ ":" "1279""1286"), this, qFlagLocation("1""_q_actionTriggered()" "\0" __FILE__ ":" "1279""1286")); | - |
1029 | connect(e->action(), qFlagLocation("2""hovered()" "\0" __FILE__ ":" "1280""1287"), this, qFlagLocation("1""_q_actionHovered()" "\0" __FILE__ ":" "1280""1287")); | - |
1030 | } never executed: end of block else if(e->type() == QEvent::ActionRemovedTRUE | never evaluated | FALSE | never evaluated |
) { | 0 |
1031 | e->action()->disconnect(this); | - |
1032 | } never executed: end of block | 0 |
1033 | if (isVisible()TRUE | never evaluated | FALSE | never evaluated |
) { | 0 |
1034 | d->updateGeometries(); | - |
1035 | update(); | - |
1036 | } never executed: end of block | 0 |
1037 | } never executed: end of block | 0 |
1038 | | - |
1039 | | - |
1040 | | - |
1041 | | - |
1042 | void QMenuBar::focusInEvent(QFocusEvent *) | - |
1043 | { | - |
1044 | QMenuBarPrivate * const d = d_func(); | - |
1045 | if(d->keyboardState) | - |
1046 | d->focusFirstAction(); | - |
1047 | } | - |
1048 | | - |
1049 | | - |
1050 | | - |
1051 | | - |
1052 | void QMenuBar::focusOutEvent(QFocusEvent *) | - |
1053 | { | - |
1054 | QMenuBarPrivate * const d = d_func(); | - |
1055 | if(!d->popupState) { | - |
1056 | d->setCurrentAction(0); | - |
1057 | d->setKeyboardMode(false); | - |
1058 | } | - |
1059 | } | - |
1060 | | - |
1061 | | - |
1062 | | - |
1063 | | - |
1064 | void QMenuBar::timerEvent (QTimerEvent *e) | - |
1065 | { | - |
1066 | QMenuBarPrivate * const d = d_func(); | - |
1067 | if (e->timerId() == d->autoReleaseTimer.timerId()) { | - |
1068 | d->autoReleaseTimer.stop(); | - |
1069 | d->setCurrentAction(0); | - |
1070 | } | - |
1071 | QWidget::timerEvent(e); | - |
1072 | } | - |
1073 | | - |
1074 | | - |
1075 | void QMenuBarPrivate::handleReparent() | - |
1076 | { | - |
1077 | QMenuBar * const q = q_func(); | - |
1078 | QWidget *newParent = q->parentWidget(); | - |
1079 | | - |
1080 | | - |
1081 | | - |
1082 | | - |
1083 | QWidget *newWindow = newParent ? newParent->window() : nullptr; | - |
1084 | | - |
1085 | QVector<QPointer<QWidget> > newParents; | - |
1086 | | - |
1087 | | - |
1088 | for (QForeachContainer<typename QtPrivate::remove_reference<decltype(oldParents)>::type> _container_((oldParents)); _container_.control && _container_.i != _container_.e; ++_container_.i, _container_.control ^= 1) for (const QPointer<QWidget> &w = *_container_.i; _container_.control; _container_.control = 0) { | - |
1089 | if (w) { | - |
1090 | if (newParent == w) { | - |
1091 | newParents.append(w); | - |
1092 | if (newParent != newWindow) | - |
1093 | newParent = newParent->parentWidget(); | - |
1094 | } else { | - |
1095 | w->removeEventFilter(q); | - |
1096 | } | - |
1097 | } | - |
1098 | } | - |
1099 | | - |
1100 | | - |
1101 | while (newParent && newParent != newWindow) { | - |
1102 | | - |
1103 | newParents.append(newParent); | - |
1104 | newParent->installEventFilter(q); | - |
1105 | newParent = newParent->parentWidget(); | - |
1106 | } | - |
1107 | | - |
1108 | if (newParent && newWindow) { | - |
1109 | | - |
1110 | newParents.append(newParent); | - |
1111 | newParent->installEventFilter(q); | - |
1112 | } | - |
1113 | oldParents = newParents; | - |
1114 | | - |
1115 | if (platformMenuBar) { | - |
1116 | if (newWindow) { | - |
1117 | | - |
1118 | | - |
1119 | | - |
1120 | newWindow->createWinId(); | - |
1121 | platformMenuBar->handleReparent(newWindow->windowHandle()); | - |
1122 | } else { | - |
1123 | platformMenuBar->handleReparent(0); | - |
1124 | } | - |
1125 | } | - |
1126 | | - |
1127 | | - |
1128 | | - |
1129 | | - |
1130 | | - |
1131 | } | - |
1132 | | - |
1133 | | - |
1134 | | - |
1135 | | - |
1136 | void QMenuBar::changeEvent(QEvent *e) | - |
1137 | { | - |
1138 | QMenuBarPrivate * const d = d_func(); | - |
1139 | if(e->type() == QEvent::StyleChange) { | - |
1140 | d->itemsDirty = true; | - |
1141 | setMouseTracking(style()->styleHint(QStyle::SH_MenuBar_MouseTracking, 0, this)); | - |
1142 | if(parentWidget()) | - |
1143 | resize(parentWidget()->width(), heightForWidth(parentWidget()->width())); | - |
1144 | d->updateGeometries(); | - |
1145 | } else if (e->type() == QEvent::ParentChange) { | - |
1146 | d->handleReparent(); | - |
1147 | } else if (e->type() == QEvent::FontChange | - |
1148 | || e->type() == QEvent::ApplicationFontChange) { | - |
1149 | d->itemsDirty = true; | - |
1150 | d->updateGeometries(); | - |
1151 | } | - |
1152 | | - |
1153 | QWidget::changeEvent(e); | - |
1154 | } | - |
1155 | | - |
1156 | | - |
1157 | | - |
1158 | | - |
1159 | bool QMenuBar::event(QEvent *e) | - |
1160 | { | - |
1161 | QMenuBarPrivate * const d = d_func(); | - |
1162 | switch (e->type()) { | - |
1163 | case QEvent::KeyPress: { | - |
1164 | QKeyEvent *ke = (QKeyEvent*)e; | - |
1165 | | - |
1166 | | - |
1167 | | - |
1168 | | - |
1169 | | - |
1170 | | - |
1171 | if(ke->key() == Qt::Key_Tab || ke->key() == Qt::Key_Backtab) { | - |
1172 | keyPressEvent(ke); | - |
1173 | return true; | - |
1174 | } | - |
1175 | | - |
1176 | } break; | - |
1177 | | - |
1178 | case QEvent::Shortcut: { | - |
1179 | QShortcutEvent *se = static_cast<QShortcutEvent *>(e); | - |
1180 | int shortcutId = se->shortcutId(); | - |
1181 | for(int j = 0; j < d->shortcutIndexMap.size(); ++j) { | - |
1182 | if (shortcutId == d->shortcutIndexMap.value(j)) | - |
1183 | d->_q_internalShortcutActivated(j); | - |
1184 | } | - |
1185 | } break; | - |
1186 | | - |
1187 | case QEvent::Show: | - |
1188 | d->_q_updateLayout(); | - |
1189 | break; | - |
1190 | case QEvent::ShortcutOverride: { | - |
1191 | QKeyEvent *kev = static_cast<QKeyEvent*>(e); | - |
1192 | | - |
1193 | if (kev->matches(QKeySequence::Cancel) && d->currentAction) { | - |
1194 | e->accept(); | - |
1195 | return true; | - |
1196 | } | - |
1197 | } | - |
1198 | break; | - |
1199 | | - |
1200 | | - |
1201 | | - |
1202 | case QEvent::QueryWhatsThis: | - |
1203 | e->setAccepted(d->whatsThis.size()); | - |
1204 | if (QAction *action = d->actionAt(static_cast<QHelpEvent*>(e)->pos())) { | - |
1205 | if (action->whatsThis().size() || action->menu()) | - |
1206 | e->accept(); | - |
1207 | } | - |
1208 | return true; | - |
1209 | | - |
1210 | case QEvent::LayoutDirectionChange: | - |
1211 | d->_q_updateLayout(); | - |
1212 | break; | - |
1213 | default: | - |
1214 | break; | - |
1215 | } | - |
1216 | return QWidget::event(e); | - |
1217 | } | - |
1218 | | - |
1219 | | - |
1220 | | - |
1221 | | - |
1222 | bool QMenuBar::eventFilter(QObject *object, QEvent *event) | - |
1223 | { | - |
1224 | QMenuBarPrivate * const d = d_func(); | - |
1225 | if (object && (event->type() == QEvent::ParentChange)) | - |
1226 | d->handleReparent(); | - |
1227 | | - |
1228 | if (object == d->leftWidget || object == d->rightWidget) { | - |
1229 | switch (event->type()) { | - |
1230 | case QEvent::ShowToParent: | - |
1231 | case QEvent::HideToParent: | - |
1232 | d->_q_updateLayout(); | - |
1233 | break; | - |
1234 | default: | - |
1235 | break; | - |
1236 | } | - |
1237 | } | - |
1238 | | - |
1239 | if (style()->styleHint(QStyle::SH_MenuBar_AltKeyNavigation, 0, this)) { | - |
1240 | if (d->altPressed) { | - |
1241 | switch (event->type()) { | - |
1242 | case QEvent::KeyPress: | - |
1243 | case QEvent::KeyRelease: | - |
1244 | { | - |
1245 | QKeyEvent *kev = static_cast<QKeyEvent*>(event); | - |
1246 | if (kev->key() == Qt::Key_Alt || kev->key() == Qt::Key_Meta) { | - |
1247 | if (event->type() == QEvent::KeyPress) | - |
1248 | break; | - |
1249 | d->setKeyboardMode(!d->keyboardState); | - |
1250 | } | - |
1251 | } | - |
1252 | | - |
1253 | case QEvent::MouseButtonPress: | - |
1254 | case QEvent::MouseButtonRelease: | - |
1255 | case QEvent::MouseMove: | - |
1256 | case QEvent::FocusIn: | - |
1257 | case QEvent::FocusOut: | - |
1258 | case QEvent::ActivationChange: | - |
1259 | d->altPressed = false; | - |
1260 | (static_cast<QApplication *>(QCoreApplication::instance()))->removeEventFilter(this); | - |
1261 | break; | - |
1262 | default: | - |
1263 | break; | - |
1264 | } | - |
1265 | } else if (isVisible()) { | - |
1266 | if (event->type() == QEvent::ShortcutOverride) { | - |
1267 | QKeyEvent *kev = static_cast<QKeyEvent*>(event); | - |
1268 | if ((kev->key() == Qt::Key_Alt || kev->key() == Qt::Key_Meta) | - |
1269 | && kev->modifiers() == Qt::AltModifier) { | - |
1270 | d->altPressed = true; | - |
1271 | (static_cast<QApplication *>(QCoreApplication::instance()))->installEventFilter(this); | - |
1272 | } | - |
1273 | } | - |
1274 | } | - |
1275 | } | - |
1276 | | - |
1277 | return false; | - |
1278 | } | - |
1279 | | - |
1280 | | - |
1281 | | - |
1282 | | - |
1283 | | - |
1284 | | - |
1285 | | - |
1286 | QAction *QMenuBar::actionAt(const QPoint &pt) const | - |
1287 | { | - |
1288 | const QMenuBarPrivate * const d = d_func(); | - |
1289 | return d->actionAt(pt); | - |
1290 | } | - |
1291 | | - |
1292 | | - |
1293 | | - |
1294 | | - |
1295 | | - |
1296 | | - |
1297 | QRect QMenuBar::actionGeometry(QAction *act) const | - |
1298 | { | - |
1299 | const QMenuBarPrivate * const d = d_func(); | - |
1300 | return d->actionRect(act); | - |
1301 | } | - |
1302 | | - |
1303 | | - |
1304 | | - |
1305 | | - |
1306 | QSize QMenuBar::minimumSizeHint() const | - |
1307 | { | - |
1308 | const QMenuBarPrivate * const d = d_func(); | - |
1309 | const bool as_gui_menubar = !isNativeMenuBar(); | - |
1310 | | - |
1311 | ensurePolished(); | - |
1312 | QSize ret(0, 0); | - |
1313 | const_cast<QMenuBarPrivate*>(d)->updateGeometries(); | - |
1314 | const int hmargin = style()->pixelMetric(QStyle::PM_MenuBarHMargin, 0, this); | - |
1315 | const int vmargin = style()->pixelMetric(QStyle::PM_MenuBarVMargin, 0, this); | - |
1316 | int fw = style()->pixelMetric(QStyle::PM_MenuBarPanelWidth, 0, this); | - |
1317 | int spaceBelowMenuBar = style()->styleHint(QStyle::SH_MainWindow_SpaceBelowMenuBar, 0, this); | - |
1318 | if(as_gui_menubar) { | - |
1319 | int w = parentWidget() ? parentWidget()->width() : QApplication::desktop()->width(); | - |
1320 | d->calcActionRects(w - (2 * fw), 0); | - |
1321 | for (int i = 0; ret.isNull() && i < d->actions.count(); ++i) | - |
1322 | ret = d->actionRects.at(i).size(); | - |
1323 | if (!d->extension->isHidden()) | - |
1324 | ret += QSize(d->extension->sizeHint().width(), 0); | - |
1325 | ret += QSize(2*fw + hmargin, 2*fw + vmargin); | - |
1326 | } | - |
1327 | int margin = 2*vmargin + 2*fw + spaceBelowMenuBar; | - |
1328 | if(d->leftWidget) { | - |
1329 | QSize sz = d->leftWidget->minimumSizeHint(); | - |
1330 | ret.setWidth(ret.width() + sz.width()); | - |
1331 | if(sz.height() + margin > ret.height()) | - |
1332 | ret.setHeight(sz.height() + margin); | - |
1333 | } | - |
1334 | if(d->rightWidget) { | - |
1335 | QSize sz = d->rightWidget->minimumSizeHint(); | - |
1336 | ret.setWidth(ret.width() + sz.width()); | - |
1337 | if(sz.height() + margin > ret.height()) | - |
1338 | ret.setHeight(sz.height() + margin); | - |
1339 | } | - |
1340 | if(as_gui_menubar) { | - |
1341 | QStyleOptionMenuItem opt; | - |
1342 | opt.rect = rect(); | - |
1343 | opt.menuRect = rect(); | - |
1344 | opt.state = QStyle::State_None; | - |
1345 | opt.menuItemType = QStyleOptionMenuItem::Normal; | - |
1346 | opt.checkType = QStyleOptionMenuItem::NotCheckable; | - |
1347 | opt.palette = palette(); | - |
1348 | return (style()->sizeFromContents(QStyle::CT_MenuBar, &opt, | - |
1349 | ret.expandedTo(QApplication::globalStrut()), | - |
1350 | this)); | - |
1351 | } | - |
1352 | return ret; | - |
1353 | } | - |
1354 | | - |
1355 | | - |
1356 | | - |
1357 | | - |
1358 | QSize QMenuBar::sizeHint() const | - |
1359 | { | - |
1360 | const QMenuBarPrivate * const d = d_func(); | - |
1361 | const bool as_gui_menubar = !isNativeMenuBar(); | - |
1362 | | - |
1363 | ensurePolished(); | - |
1364 | QSize ret(0, 0); | - |
1365 | const_cast<QMenuBarPrivate*>(d)->updateGeometries(); | - |
1366 | const int hmargin = style()->pixelMetric(QStyle::PM_MenuBarHMargin, 0, this); | - |
1367 | const int vmargin = style()->pixelMetric(QStyle::PM_MenuBarVMargin, 0, this); | - |
1368 | int fw = style()->pixelMetric(QStyle::PM_MenuBarPanelWidth, 0, this); | - |
1369 | int spaceBelowMenuBar = style()->styleHint(QStyle::SH_MainWindow_SpaceBelowMenuBar, 0, this); | - |
1370 | if(as_gui_menubar) { | - |
1371 | const int w = parentWidget() ? parentWidget()->width() : QApplication::desktop()->width(); | - |
1372 | d->calcActionRects(w - (2 * fw), 0); | - |
1373 | for (int i = 0; i < d->actionRects.count(); ++i) { | - |
1374 | const QRect &actionRect = d->actionRects.at(i); | - |
1375 | ret = ret.expandedTo(QSize(actionRect.x() + actionRect.width(), actionRect.y() + actionRect.height())); | - |
1376 | } | - |
1377 | | - |
1378 | | - |
1379 | ret += QSize(fw + hmargin, fw + vmargin); | - |
1380 | } | - |
1381 | int margin = 2*vmargin + 2*fw + spaceBelowMenuBar; | - |
1382 | if(d->leftWidget) { | - |
1383 | QSize sz = d->leftWidget->sizeHint(); | - |
1384 | sz.rheight() += margin; | - |
1385 | ret = ret.expandedTo(sz); | - |
1386 | } | - |
1387 | if(d->rightWidget) { | - |
1388 | QSize sz = d->rightWidget->sizeHint(); | - |
1389 | ret.setWidth(ret.width() + sz.width()); | - |
1390 | if(sz.height() + margin > ret.height()) | - |
1391 | ret.setHeight(sz.height() + margin); | - |
1392 | } | - |
1393 | if(as_gui_menubar) { | - |
1394 | QStyleOptionMenuItem opt; | - |
1395 | opt.rect = rect(); | - |
1396 | opt.menuRect = rect(); | - |
1397 | opt.state = QStyle::State_None; | - |
1398 | opt.menuItemType = QStyleOptionMenuItem::Normal; | - |
1399 | opt.checkType = QStyleOptionMenuItem::NotCheckable; | - |
1400 | opt.palette = palette(); | - |
1401 | return (style()->sizeFromContents(QStyle::CT_MenuBar, &opt, | - |
1402 | ret.expandedTo(QApplication::globalStrut()), | - |
1403 | this)); | - |
1404 | } | - |
1405 | return ret; | - |
1406 | } | - |
1407 | | - |
1408 | | - |
1409 | | - |
1410 | | - |
1411 | int QMenuBar::heightForWidth(int) const | - |
1412 | { | - |
1413 | const QMenuBarPrivate * const d = d_func(); | - |
1414 | const bool as_gui_menubar = !isNativeMenuBar(); | - |
1415 | | - |
1416 | const_cast<QMenuBarPrivate*>(d)->updateGeometries(); | - |
1417 | int height = 0; | - |
1418 | const int vmargin = style()->pixelMetric(QStyle::PM_MenuBarVMargin, 0, this); | - |
1419 | int fw = style()->pixelMetric(QStyle::PM_MenuBarPanelWidth, 0, this); | - |
1420 | int spaceBelowMenuBar = style()->styleHint(QStyle::SH_MainWindow_SpaceBelowMenuBar, 0, this); | - |
1421 | if(as_gui_menubar) { | - |
1422 | for (int i = 0; i < d->actionRects.count(); ++i) | - |
1423 | height = qMax(height, d->actionRects.at(i).height()); | - |
1424 | if (height) | - |
1425 | height += spaceBelowMenuBar; | - |
1426 | height += 2*fw; | - |
1427 | height += 2*vmargin; | - |
1428 | } | - |
1429 | int margin = 2*vmargin + 2*fw + spaceBelowMenuBar; | - |
1430 | if(d->leftWidget) | - |
1431 | height = qMax(d->leftWidget->sizeHint().height() + margin, height); | - |
1432 | if(d->rightWidget) | - |
1433 | height = qMax(d->rightWidget->sizeHint().height() + margin, height); | - |
1434 | if(as_gui_menubar) { | - |
1435 | QStyleOptionMenuItem opt; | - |
1436 | opt.init(this); | - |
1437 | opt.menuRect = rect(); | - |
1438 | opt.state = QStyle::State_None; | - |
1439 | opt.menuItemType = QStyleOptionMenuItem::Normal; | - |
1440 | opt.checkType = QStyleOptionMenuItem::NotCheckable; | - |
1441 | return style()->sizeFromContents(QStyle::CT_MenuBar, &opt, QSize(0, height), this).height(); | - |
1442 | } | - |
1443 | return height; | - |
1444 | } | - |
1445 | | - |
1446 | | - |
1447 | | - |
1448 | | - |
1449 | void QMenuBarPrivate::_q_internalShortcutActivated(int id) | - |
1450 | { | - |
1451 | QMenuBar * const q = q_func(); | - |
1452 | QAction *act = actions.at(id); | - |
1453 | setCurrentAction(act, true, true); | - |
1454 | if (act && !act->menu()) { | - |
1455 | activateAction(act, QAction::Trigger); | - |
1456 | | - |
1457 | autoReleaseTimer.start(100, q); | - |
1458 | } else if (act && q->style()->styleHint(QStyle::SH_MenuBar_AltKeyNavigation, 0, q)) { | - |
1459 | | - |
1460 | setKeyboardMode(true); | - |
1461 | } | - |
1462 | } | - |
1463 | | - |
1464 | void QMenuBarPrivate::_q_updateLayout() | - |
1465 | { | - |
1466 | QMenuBar * const q = q_func(); | - |
1467 | itemsDirty = true; | - |
1468 | if (q->isVisible()) { | - |
1469 | updateGeometries(); | - |
1470 | q->update(); | - |
1471 | } | - |
1472 | } | - |
1473 | void QMenuBar::setCornerWidget(QWidget *w, Qt::Corner corner) | - |
1474 | { | - |
1475 | QMenuBarPrivate * const d = d_func(); | - |
1476 | switch (corner) { | - |
1477 | case Qt::TopLeftCorner: | - |
1478 | if (d->leftWidget) | - |
1479 | d->leftWidget->removeEventFilter(this); | - |
1480 | d->leftWidget = w; | - |
1481 | break; | - |
1482 | case Qt::TopRightCorner: | - |
1483 | if (d->rightWidget) | - |
1484 | d->rightWidget->removeEventFilter(this); | - |
1485 | d->rightWidget = w; | - |
1486 | break; | - |
1487 | default: | - |
1488 | QMessageLogger(__FILE__, 17531760, __PRETTY_FUNCTION__).warning("QMenuBar::setCornerWidget: Only TopLeftCorner and TopRightCorner are supported"); | - |
1489 | return; | - |
1490 | } | - |
1491 | | - |
1492 | if (w) { | - |
1493 | w->setParent(this); | - |
1494 | w->installEventFilter(this); | - |
1495 | } | - |
1496 | | - |
1497 | d->_q_updateLayout(); | - |
1498 | } | - |
1499 | QWidget *QMenuBar::cornerWidget(Qt::Corner corner) const | - |
1500 | { | - |
1501 | const QMenuBarPrivate * const d = d_func(); | - |
1502 | QWidget *w = 0; | - |
1503 | switch(corner) { | - |
1504 | case Qt::TopLeftCorner: | - |
1505 | w = d->leftWidget; | - |
1506 | break; | - |
1507 | case Qt::TopRightCorner: | - |
1508 | w = d->rightWidget; | - |
1509 | break; | - |
1510 | default: | - |
1511 | QMessageLogger(__FILE__, 17841791, __PRETTY_FUNCTION__).warning("QMenuBar::cornerWidget: Only TopLeftCorner and TopRightCorner are supported"); | - |
1512 | break; | - |
1513 | } | - |
1514 | | - |
1515 | return w; | - |
1516 | } | - |
1517 | void QMenuBar::setNativeMenuBar(bool nativeMenuBar) | - |
1518 | { | - |
1519 | QMenuBarPrivate * const d = d_func(); | - |
1520 | if (nativeMenuBar != bool(d->platformMenuBar)) { | - |
1521 | if (!nativeMenuBar) { | - |
1522 | delete d->platformMenuBar; | - |
1523 | d->platformMenuBar = 0; | - |
1524 | } else { | - |
1525 | if (!d->platformMenuBar) | - |
1526 | d->platformMenuBar = QGuiApplicationPrivate::platformTheme()->createPlatformMenuBar(); | - |
1527 | } | - |
1528 | | - |
1529 | updateGeometry(); | - |
1530 | if (!nativeMenuBar && parentWidget()) | - |
1531 | setVisible(true); | - |
1532 | } | - |
1533 | } | - |
1534 | | - |
1535 | bool QMenuBar::isNativeMenuBar() const | - |
1536 | { | - |
1537 | const QMenuBarPrivate * const d = d_func(); | - |
1538 | return bool(d->platformMenuBar); | - |
1539 | } | - |
1540 | | - |
1541 | | - |
1542 | | - |
1543 | | - |
1544 | QPlatformMenuBar *QMenuBar::platformMenuBar() | - |
1545 | { | - |
1546 | const QMenuBarPrivate * const d = d_func(); | - |
1547 | return d->platformMenuBar; | - |
1548 | } | - |
1549 | | - |
1550 | | - |
| | |