Changeset View
Changeset View
Standalone View
Standalone View
krusader/BookMan/krbookmarkhandler.cpp
Show All 30 Lines | |||||
31 | #include "../Panel/krpanel.h" | 31 | #include "../Panel/krpanel.h" | ||
32 | #include "../Panel/listpanelactions.h" | 32 | #include "../Panel/listpanelactions.h" | ||
33 | 33 | | |||
34 | // QtCore | 34 | // QtCore | ||
35 | #include <QTextStream> | 35 | #include <QTextStream> | ||
36 | #include <QFile> | 36 | #include <QFile> | ||
37 | #include <QEvent> | 37 | #include <QEvent> | ||
38 | #include <QStandardPaths> | 38 | #include <QStandardPaths> | ||
39 | #include <QDebug> | ||||
40 | #include <QTimer> | ||||
39 | // QtGui | 41 | // QtGui | ||
40 | #include <QMouseEvent> | 42 | #include <QMouseEvent> | ||
41 | #include <QCursor> | 43 | #include <QCursor> | ||
42 | 44 | | |||
43 | #include <KConfigCore/KSharedConfig> | 45 | #include <KConfigCore/KSharedConfig> | ||
44 | #include <KI18n/KLocalizedString> | 46 | #include <KI18n/KLocalizedString> | ||
45 | #include <KIconThemes/KIconLoader> | 47 | #include <KIconThemes/KIconLoader> | ||
46 | #include <KWidgetsAddons/KMessageBox> | 48 | #include <KWidgetsAddons/KMessageBox> | ||
47 | #include <KXmlGui/KActionCollection> | 49 | #include <KXmlGui/KActionCollection> | ||
48 | #include <KBookmarks/KBookmarkManager> | 50 | #include <KBookmarks/KBookmarkManager> | ||
49 | 51 | | |||
50 | #define SPECIAL_BOOKMARKS true | 52 | #define SPECIAL_BOOKMARKS true | ||
51 | 53 | | |||
52 | // ------------------------ for internal use | 54 | // ------------------------ for internal use | ||
53 | #define BOOKMARKS_FILE "krusader/krbookmarks.xml" | 55 | #define BOOKMARKS_FILE "krusader/krbookmarks.xml" | ||
54 | #define CONNECT_BM(X) { disconnect(X, SIGNAL(activated(QUrl)), 0, 0); connect(X, SIGNAL(activated(QUrl)), this, SLOT(slotActivated(QUrl))); } | 56 | #define CONNECT_BM(X) { disconnect(X, SIGNAL(activated(QUrl)), 0, 0); connect(X, SIGNAL(activated(QUrl)), this, SLOT(slotActivated(QUrl))); } | ||
55 | 57 | | |||
56 | KrBookmarkHandler::KrBookmarkHandler(KrMainWindow *mainWindow) : QObject(mainWindow->widget()), | 58 | KrBookmarkHandler::KrBookmarkHandler(KrMainWindow *mainWindow) : | ||
57 | _mainWindow(mainWindow), _middleClick(false), _mainBookmarkPopup(0), _specialBookmarks() | 59 | QObject(mainWindow->widget()), | ||
60 | _mainWindow(mainWindow), | ||||
61 | _middleClick(false), | ||||
62 | _mainBookmarkPopup(0), | ||||
63 | _specialBookmarks(), | ||||
64 | _quickSearchAction(nullptr), | ||||
65 | _quickSearchBar(nullptr), | ||||
66 | _quickSearchMenu(nullptr) | ||||
58 | { | 67 | { | ||
59 | // create our own action collection and make the shortcuts apply only to parent | 68 | // create our own action collection and make the shortcuts apply only to parent | ||
60 | _privateCollection = new KActionCollection(this); | 69 | _privateCollection = new KActionCollection(this); | ||
61 | _collection = _mainWindow->actions(); | 70 | _collection = _mainWindow->actions(); | ||
62 | 71 | | |||
63 | // create _root: father of all bookmarks. it is a dummy bookmark and never shown | 72 | // create _root: father of all bookmarks. it is a dummy bookmark and never shown | ||
64 | _root = new KrBookmark(i18n("Bookmarks")); | 73 | _root = new KrBookmark(i18n("Bookmarks")); | ||
65 | _root->setParent(this); | 74 | _root->setParent(this); | ||
66 | 75 | | |||
67 | // load bookmarks | 76 | // load bookmarks | ||
68 | importFromFile(); | 77 | importFromFile(); | ||
69 | 78 | | |||
70 | // hack | 79 | // create bookmark manager | ||
71 | QString filename = QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation) + QLatin1Char('/') + BOOKMARKS_FILE; | 80 | QString filename = QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation) + QLatin1Char('/') + BOOKMARKS_FILE; | ||
72 | manager = KBookmarkManager::managerForFile(filename, QStringLiteral("krusader")); | 81 | manager = KBookmarkManager::managerForFile(filename, QStringLiteral("krusader")); | ||
73 | connect(manager, SIGNAL(changed(QString,QString)), this, SLOT(bookmarksChanged(QString,QString))); | 82 | connect(manager, SIGNAL(changed(QString,QString)), this, SLOT(bookmarksChanged(QString,QString))); | ||
83 | | ||||
84 | // create the quick search bar and action | ||||
85 | _quickSearchAction = new QWidgetAction(this); | ||||
86 | _quickSearchBar = new QLineEdit(); | ||||
87 | _quickSearchBar->setPlaceholderText(i18n("Type to search...")); | ||||
88 | _quickSearchAction->setDefaultWidget(_quickSearchBar); // ownership of the bar is transferred to the action | ||||
89 | _quickSearchAction->setEnabled(false); | ||||
90 | _setQuickSearchText(""); | ||||
91 | | ||||
92 | // fill a dummy menu to properly init actions (allows toolbar bookmark buttons to work properly) | ||||
93 | auto menu = new QMenu(mainWindow->widget()); | ||||
94 | populate(menu); | ||||
95 | menu->deleteLater(); | ||||
74 | } | 96 | } | ||
75 | 97 | | |||
76 | KrBookmarkHandler::~KrBookmarkHandler() | 98 | KrBookmarkHandler::~KrBookmarkHandler() | ||
77 | { | 99 | { | ||
78 | delete manager; | 100 | delete manager; | ||
79 | delete _privateCollection; | 101 | delete _privateCollection; | ||
80 | } | 102 | } | ||
81 | 103 | | |||
▲ Show 20 Lines • Show All 222 Lines • ▼ Show 20 Line(s) | |||||
304 | 326 | | |||
305 | BM_ERROR: | 327 | BM_ERROR: | ||
306 | KMessageBox::error(_mainWindow->widget(), i18n("Error reading bookmarks file: %1", errorMsg), i18n("Error")); | 328 | KMessageBox::error(_mainWindow->widget(), i18n("Error reading bookmarks file: %1", errorMsg), i18n("Error")); | ||
307 | 329 | | |||
308 | BM_SUCCESS: | 330 | BM_SUCCESS: | ||
309 | file.close(); | 331 | file.close(); | ||
310 | } | 332 | } | ||
311 | 333 | | |||
334 | void KrBookmarkHandler::_setQuickSearchText(const QString &text) | ||||
335 | { | ||||
336 | bool isEmptyQuickSearchBarVisible = KConfigGroup(krConfig, "Look&Feel").readEntry("Always show search bar", true); | ||||
337 | | ||||
338 | _quickSearchBar->setText(text); | ||||
339 | | ||||
340 | auto length = text.length(); | ||||
341 | bool isVisible = isEmptyQuickSearchBarVisible || length > 0; | ||||
342 | _quickSearchAction->setVisible(isVisible); | ||||
343 | _quickSearchBar->setVisible(isVisible); | ||||
344 | | ||||
345 | if (length == 0) { | ||||
346 | qDebug() << "Bookmark search: reset"; | ||||
347 | _resetActionTextAndHighlighting(); | ||||
348 | } else { | ||||
349 | qDebug() << "Bookmark search: query =" << text; | ||||
350 | } | ||||
351 | } | ||||
352 | | ||||
353 | QString KrBookmarkHandler::_quickSearchText() const | ||||
354 | { | ||||
355 | return _quickSearchBar->text(); | ||||
356 | } | ||||
357 | | ||||
358 | void KrBookmarkHandler::_highlightAction(QAction *action, bool isMatched) | ||||
359 | { | ||||
360 | auto font = action->font(); | ||||
361 | font.setBold(isMatched); | ||||
362 | action->setFont(font); | ||||
363 | } | ||||
364 | | ||||
312 | void KrBookmarkHandler::populate(QMenu *menu) | 365 | void KrBookmarkHandler::populate(QMenu *menu) | ||
313 | { | 366 | { | ||
367 | // removing action from previous menu is necessary | ||||
368 | // otherwise it won't be displayed in the currently populating menu | ||||
369 | if (_mainBookmarkPopup) { | ||||
370 | _mainBookmarkPopup->removeAction(_quickSearchAction); | ||||
371 | } | ||||
314 | _mainBookmarkPopup = menu; | 372 | _mainBookmarkPopup = menu; | ||
315 | menu->clear(); | 373 | menu->clear(); | ||
316 | _specialBookmarks.clear(); | 374 | _specialBookmarks.clear(); | ||
317 | buildMenu(_root, menu); | 375 | buildMenu(_root, menu); | ||
318 | } | 376 | } | ||
319 | 377 | | |||
320 | void KrBookmarkHandler::buildMenu(KrBookmark *parent, QMenu *menu) | 378 | void KrBookmarkHandler::buildMenu(KrBookmark *parent, QMenu *menu, int depth) | ||
321 | { | 379 | { | ||
322 | static int inSecondaryMenu = 0; // used to know if we're on the top menu | 380 | // add search bar widget to the top of the menu | ||
381 | if (depth == 0) { | ||||
382 | menu->addAction(_quickSearchAction); | ||||
383 | } | ||||
323 | 384 | | |||
324 | // run the loop twice, in order to put the folders on top. stupid but easy :-) | 385 | // run the loop twice, in order to put the folders on top. stupid but easy :-) | ||
325 | // note: this code drops the separators put there by the user | 386 | // note: this code drops the separators put there by the user | ||
326 | QListIterator<KrBookmark *> it(parent->children()); | 387 | QListIterator<KrBookmark *> it(parent->children()); | ||
327 | while (it.hasNext()) { | 388 | while (it.hasNext()) { | ||
328 | KrBookmark *bm = it.next(); | 389 | KrBookmark *bm = it.next(); | ||
329 | 390 | | |||
330 | if (!bm->isFolder()) continue; | 391 | if (!bm->isFolder()) continue; | ||
331 | QMenu *newMenu = new QMenu(menu); | 392 | QMenu *newMenu = new QMenu(menu); | ||
332 | newMenu->setIcon(QIcon(krLoader->loadIcon(bm->iconName(), KIconLoader::Small))); | 393 | newMenu->setIcon(QIcon(krLoader->loadIcon(bm->iconName(), KIconLoader::Small))); | ||
333 | newMenu->setTitle(bm->text()); | 394 | newMenu->setTitle(bm->text()); | ||
334 | QAction *menuAction = menu->addMenu(newMenu); | 395 | QAction *menuAction = menu->addMenu(newMenu); | ||
335 | QVariant v; | 396 | QVariant v; | ||
336 | v.setValue<KrBookmark *>(bm); | 397 | v.setValue<KrBookmark *>(bm); | ||
337 | menuAction->setData(v); | 398 | menuAction->setData(v); | ||
338 | 399 | | |||
339 | ++inSecondaryMenu; | 400 | buildMenu(bm, newMenu, depth + 1); | ||
340 | buildMenu(bm, newMenu); | | |||
341 | --inSecondaryMenu; | | |||
342 | } | 401 | } | ||
343 | 402 | | |||
344 | it.toFront(); | 403 | it.toFront(); | ||
345 | while (it.hasNext()) { | 404 | while (it.hasNext()) { | ||
346 | KrBookmark *bm = it.next(); | 405 | KrBookmark *bm = it.next(); | ||
347 | if (bm->isFolder()) continue; | 406 | if (bm->isFolder()) continue; | ||
348 | if (bm->isSeparator()) { | 407 | if (bm->isSeparator()) { | ||
349 | menu->addSeparator(); | 408 | menu->addSeparator(); | ||
350 | continue; | 409 | continue; | ||
351 | } | 410 | } | ||
352 | menu->addAction(bm); | 411 | menu->addAction(bm); | ||
353 | CONNECT_BM(bm); | 412 | CONNECT_BM(bm); | ||
354 | } | 413 | } | ||
355 | 414 | | |||
356 | if (!inSecondaryMenu) { | 415 | if (depth == 0) { | ||
357 | KConfigGroup group(krConfig, "Private"); | 416 | KConfigGroup group(krConfig, "Private"); | ||
358 | bool hasPopularURLs = group.readEntry("BM Popular URLs", true); | 417 | bool hasPopularURLs = group.readEntry("BM Popular URLs", true); | ||
359 | bool hasTrash = group.readEntry("BM Trash", true); | 418 | bool hasTrash = group.readEntry("BM Trash", true); | ||
360 | bool hasLan = group.readEntry("BM Lan", true); | 419 | bool hasLan = group.readEntry("BM Lan", true); | ||
361 | bool hasVirtualFS = group.readEntry("BM Virtual FS", true); | 420 | bool hasVirtualFS = group.readEntry("BM Virtual FS", true); | ||
362 | bool hasJumpback = group.readEntry("BM Jumpback", true); | 421 | bool hasJumpback = group.readEntry("BM Jumpback", true); | ||
363 | 422 | | |||
364 | if (hasPopularURLs) { | 423 | if (hasPopularURLs) { | ||
Show All 24 Lines | 433 | #define MAX 15 | |||
389 | 448 | | |||
390 | newMenu->addSeparator(); | 449 | newMenu->addSeparator(); | ||
391 | newMenu->addAction(krPopularUrls); | 450 | newMenu->addAction(krPopularUrls); | ||
392 | newMenu->installEventFilter(this); | 451 | newMenu->installEventFilter(this); | ||
393 | } | 452 | } | ||
394 | 453 | | |||
395 | // do we need to add special bookmarks? | 454 | // do we need to add special bookmarks? | ||
396 | if (SPECIAL_BOOKMARKS) { | 455 | if (SPECIAL_BOOKMARKS) { | ||
397 | if (hasTrash || hasLan || hasVirtualFS || hasJumpback) | 456 | if (hasTrash || hasLan || hasVirtualFS) | ||
398 | menu->addSeparator(); | 457 | menu->addSeparator(); | ||
399 | 458 | | |||
400 | KrBookmark *bm; | 459 | KrBookmark *bm; | ||
401 | 460 | | |||
402 | // note: special bookmarks are not kept inside the _bookmarks list and added ad-hoc | 461 | // note: special bookmarks are not kept inside the _bookmarks list and added ad-hoc | ||
403 | if (hasTrash) { | 462 | if (hasTrash) { | ||
404 | bm = KrBookmark::trash(_collection); | 463 | bm = KrBookmark::trash(_collection); | ||
405 | menu->addAction(bm); | 464 | menu->addAction(bm); | ||
Show All 11 Lines | |||||
417 | if (hasVirtualFS) { | 476 | if (hasVirtualFS) { | ||
418 | bm = KrBookmark::virt(_collection); | 477 | bm = KrBookmark::virt(_collection); | ||
419 | menu->addAction(bm); | 478 | menu->addAction(bm); | ||
420 | _specialBookmarks.append(bm); | 479 | _specialBookmarks.append(bm); | ||
421 | CONNECT_BM(bm); | 480 | CONNECT_BM(bm); | ||
422 | } | 481 | } | ||
423 | 482 | | |||
424 | if (hasJumpback) { | 483 | if (hasJumpback) { | ||
425 | // add the jump-back button | | |||
426 | ListPanelActions *actions = _mainWindow->listPanelActions(); | | |||
427 | menu->addAction(actions->actJumpBack); | | |||
428 | _specialBookmarks.append(actions->actJumpBack); | | |||
429 | menu->addSeparator(); | 484 | menu->addSeparator(); | ||
430 | menu->addAction(actions->actSetJumpBack); | 485 | | ||
431 | _specialBookmarks.append(actions->actSetJumpBack); | 486 | ListPanelActions *actions = _mainWindow->listPanelActions(); | ||
487 | | ||||
488 | auto slotTriggered = [=] { | ||||
489 | if (_mainBookmarkPopup && !_mainBookmarkPopup->isHidden()) { | ||||
490 | _mainBookmarkPopup->close(); | ||||
432 | } | 491 | } | ||
492 | }; | ||||
493 | auto addJumpBackAction = [=](bool isSetter) { | ||||
494 | auto action = KrBookmark::jumpBackAction(_privateCollection, isSetter, actions); | ||||
495 | if (action) { | ||||
496 | menu->addAction(action); | ||||
497 | _specialBookmarks.append(action); | ||||
498 | | ||||
499 | // disconnecting from this as a receiver is important: | ||||
500 | // we don't want to break connections established by KrBookmark::jumpBackAction | ||||
501 | disconnect(action, &QAction::triggered, this, nullptr); | ||||
502 | connect(action, &QAction::triggered, this, slotTriggered); | ||||
433 | } | 503 | } | ||
504 | }; | ||||
434 | 505 | | |||
435 | if (!hasJumpback) | 506 | addJumpBackAction(true); | ||
436 | menu->addSeparator(); | 507 | addJumpBackAction(false); | ||
508 | } | ||||
509 | } | ||||
437 | 510 | | |||
511 | menu->addSeparator(); | ||||
438 | menu->addAction(KrActions::actAddBookmark); | 512 | menu->addAction(KrActions::actAddBookmark); | ||
439 | _specialBookmarks.append(KrActions::actAddBookmark); | 513 | _specialBookmarks.append(KrActions::actAddBookmark); | ||
440 | QAction *bmAct = menu->addAction(krLoader->loadIcon("bookmarks", KIconLoader::Small), | 514 | QAction *bmAct = menu->addAction(krLoader->loadIcon("bookmarks", KIconLoader::Small), | ||
441 | i18n("Manage Bookmarks"), manager, SLOT(slotEditBookmarks())); | 515 | i18n("Manage Bookmarks"), manager, SLOT(slotEditBookmarks())); | ||
442 | _specialBookmarks.append(bmAct); | 516 | _specialBookmarks.append(bmAct); | ||
443 | 517 | | |||
444 | // make sure the menu is connected to us | 518 | // make sure the menu is connected to us | ||
445 | disconnect(menu, SIGNAL(triggered(QAction*)), 0, 0); | 519 | disconnect(menu, SIGNAL(triggered(QAction*)), 0, 0); | ||
Show All 22 Lines | |||||
468 | 542 | | |||
469 | void KrBookmarkHandler::bookmarksChanged(const QString&, const QString&) | 543 | void KrBookmarkHandler::bookmarksChanged(const QString&, const QString&) | ||
470 | { | 544 | { | ||
471 | importFromFile(); | 545 | importFromFile(); | ||
472 | } | 546 | } | ||
473 | 547 | | |||
474 | bool KrBookmarkHandler::eventFilter(QObject *obj, QEvent *ev) | 548 | bool KrBookmarkHandler::eventFilter(QObject *obj, QEvent *ev) | ||
475 | { | 549 | { | ||
476 | if (ev->type() == QEvent::MouseButtonRelease) { | 550 | auto eventType = ev->type(); | ||
551 | QMenu *menu = dynamic_cast<QMenu *>(obj); | ||||
552 | | ||||
553 | if (eventType == QEvent::Show && menu) { | ||||
554 | _setQuickSearchText(""); | ||||
555 | _quickSearchMenu = menu; | ||||
556 | qDebug() << "Bookmark search: menu" << menu << "is shown"; | ||||
557 | | ||||
558 | return QObject::eventFilter(obj, ev); | ||||
559 | } | ||||
560 | | ||||
561 | if (eventType == QEvent::Close && menu && _quickSearchMenu) { | ||||
562 | if (_quickSearchMenu == menu) { | ||||
563 | qDebug() << "Bookmark search: stopped on menu" << menu; | ||||
564 | _setQuickSearchText(""); | ||||
565 | _quickSearchMenu = nullptr; | ||||
566 | } else { | ||||
567 | qDebug() << "Bookmark search: active action =" << _quickSearchMenu->activeAction(); | ||||
568 | | ||||
569 | // fix automatic deactivation of current action due to spurious close event from submenu | ||||
570 | auto quickSearchMenu = _quickSearchMenu; | ||||
571 | auto activeAction = _quickSearchMenu->activeAction(); | ||||
572 | QTimer::singleShot(0, this, [=]() { | ||||
573 | qDebug() << "Bookmark search: active action =" << quickSearchMenu->activeAction(); | ||||
574 | if (!quickSearchMenu->activeAction() && activeAction) { | ||||
575 | quickSearchMenu->setActiveAction(activeAction); | ||||
576 | qDebug() << "Bookmark search: restored active action =" << quickSearchMenu->activeAction(); | ||||
577 | } | ||||
578 | }); | ||||
579 | } | ||||
580 | | ||||
581 | return QObject::eventFilter(obj, ev); | ||||
582 | } | ||||
583 | | ||||
584 | // Having it occur on keypress is consistent with other shortcuts, | ||||
585 | // such as Ctrl+W and accelerator keys | ||||
586 | if (eventType == QEvent::KeyPress && menu) { | ||||
587 | QKeyEvent *kev = static_cast<QKeyEvent *>(ev); | ||||
588 | QList<QAction *> acts = menu->actions(); | ||||
589 | bool quickSearchStarted = false; | ||||
590 | bool searchInSpecialItems = KConfigGroup(krConfig, "Look&Feel").readEntry("Search in special items", false); | ||||
591 | | ||||
592 | if (kev->key() == Qt::Key_Left && kev->modifiers() == Qt::NoModifier) { | ||||
593 | menu->close(); | ||||
594 | return true; | ||||
595 | } | ||||
596 | | ||||
597 | if ((kev->modifiers() != Qt::ShiftModifier && | ||||
598 | kev->modifiers() != Qt::NoModifier) || | ||||
599 | kev->text().isEmpty() || | ||||
600 | kev->key() == Qt::Key_Delete || | ||||
601 | kev->key() == Qt::Key_Return || | ||||
602 | kev->key() == Qt::Key_Escape) { | ||||
603 | return QObject::eventFilter(obj, ev); | ||||
604 | } | ||||
605 | | ||||
606 | // update quick search text | ||||
607 | if (kev->key() == Qt::Key_Backspace) { | ||||
608 | auto newSearchText = _quickSearchText(); | ||||
609 | newSearchText.chop(1); | ||||
610 | _setQuickSearchText(newSearchText); | ||||
611 | | ||||
612 | if (_quickSearchText().length() == 0) { | ||||
613 | return QObject::eventFilter(obj, ev); | ||||
614 | } | ||||
615 | } else { | ||||
616 | quickSearchStarted = _quickSearchText().length() == 0; | ||||
617 | _setQuickSearchText(_quickSearchText().append(kev->text())); | ||||
618 | } | ||||
619 | | ||||
620 | if (quickSearchStarted) { | ||||
621 | _quickSearchMenu = menu; | ||||
622 | qDebug() << "Bookmark search: started on menu" << menu; | ||||
623 | } | ||||
624 | | ||||
625 | // match actions | ||||
626 | QAction *matchedAction = nullptr; | ||||
627 | int nMatches = 0; | ||||
628 | const Qt::CaseSensitivity matchCase = | ||||
629 | _quickSearchText() == _quickSearchText().toLower() ? Qt::CaseInsensitive : Qt::CaseSensitive; | ||||
630 | for (auto act : acts) { | ||||
631 | if (act->isSeparator() || act->text() == "") { | ||||
632 | continue; | ||||
633 | } | ||||
634 | | ||||
635 | if (!searchInSpecialItems && _specialBookmarks.contains(act)) { | ||||
636 | continue; | ||||
637 | } | ||||
638 | | ||||
639 | if (quickSearchStarted) { | ||||
640 | // if the first key press is an accelerator key, let the accelerator handler process this event | ||||
641 | if (act->text().contains('&' + kev->text(), Qt::CaseInsensitive)) { | ||||
642 | qDebug() << "Bookmark search: hit accelerator key of" << act; | ||||
643 | _setQuickSearchText(""); | ||||
644 | return QObject::eventFilter(obj, ev); | ||||
645 | } | ||||
646 | | ||||
647 | // strip accelerator keys from actions so they don't interfere with the search key press events | ||||
648 | auto text = act->text(); | ||||
649 | _quickSearchOriginalActionTitles.insert(act, text); | ||||
650 | act->setText(KLocalizedString::removeAcceleratorMarker(text)); | ||||
651 | } | ||||
652 | | ||||
653 | // match prefix of the action text to the query | ||||
654 | if (act->text().left(_quickSearchText().length()).compare(_quickSearchText(), matchCase) == 0) { | ||||
655 | _highlightAction(act); | ||||
656 | if (!matchedAction || matchedAction->menu()) { | ||||
657 | // Can't highlight menus (see comment below), hopefully pick something we can | ||||
658 | matchedAction = act; | ||||
659 | } | ||||
660 | nMatches++; | ||||
661 | } else { | ||||
662 | _highlightAction(act, false); | ||||
663 | } | ||||
664 | } | ||||
665 | | ||||
666 | if (matchedAction) { | ||||
667 | qDebug() << "Bookmark search: primary match =" << matchedAction->text() << ", number of matches =" << nMatches; | ||||
668 | } else { | ||||
669 | qDebug() << "Bookmark search: no matches"; | ||||
670 | } | ||||
671 | | ||||
672 | // trigger the matched menu item or set an active item accordingly | ||||
673 | if (nMatches == 1) { | ||||
674 | _setQuickSearchText(""); | ||||
675 | if ((bool) matchedAction->menu()) { | ||||
676 | menu->setActiveAction(matchedAction); | ||||
677 | } else { | ||||
678 | matchedAction->activate(QAction::Trigger); | ||||
679 | } | ||||
680 | } else if (nMatches > 1) { | ||||
681 | // Because of a bug submenus cannot be highlighted | ||||
682 | // https://bugreports.qt.io/browse/QTBUG-939 | ||||
683 | if (!matchedAction->menu()) { | ||||
684 | menu->setActiveAction(matchedAction); | ||||
685 | } else { | ||||
686 | menu->setActiveAction(nullptr); | ||||
687 | } | ||||
688 | } else { | ||||
689 | menu->setActiveAction(nullptr); | ||||
690 | } | ||||
691 | return true; | ||||
692 | } | ||||
693 | | ||||
694 | if (eventType == QEvent::MouseButtonRelease) { | ||||
477 | switch (static_cast<QMouseEvent *>(ev)->button()) { | 695 | switch (static_cast<QMouseEvent *>(ev)->button()) { | ||
478 | case Qt::RightButton: | 696 | case Qt::RightButton: | ||
479 | _middleClick = false; | 697 | _middleClick = false; | ||
480 | if (obj->inherits("QMenu")) { | 698 | if (obj->inherits("QMenu")) { | ||
481 | QMenu *menu = static_cast<QMenu *>(obj); | 699 | QMenu *menu = static_cast<QMenu *>(obj); | ||
482 | QAction *act = menu->actionAt(static_cast<QMouseEvent *>(ev)->pos()); | 700 | QAction *act = menu->actionAt(static_cast<QMouseEvent *>(ev)->pos()); | ||
483 | 701 | | |||
484 | if (obj == _mainBookmarkPopup && _specialBookmarks.contains(act)) { | 702 | if (obj == _mainBookmarkPopup && _specialBookmarks.contains(act)) { | ||
Show All 19 Lines | 720 | case Qt::MidButton: | |||
504 | break; | 722 | break; | ||
505 | default: | 723 | default: | ||
506 | break; | 724 | break; | ||
507 | } | 725 | } | ||
508 | } | 726 | } | ||
509 | return QObject::eventFilter(obj, ev); | 727 | return QObject::eventFilter(obj, ev); | ||
510 | } | 728 | } | ||
511 | 729 | | |||
730 | void KrBookmarkHandler::_resetActionTextAndHighlighting() | ||||
731 | { | ||||
732 | for (QHash<QAction *, QString>::const_iterator i = _quickSearchOriginalActionTitles.begin(); | ||||
733 | i != _quickSearchOriginalActionTitles.end(); ++i) { | ||||
734 | QAction *action = i.key(); | ||||
735 | action->setText(i.value()); | ||||
736 | _highlightAction(action, false); | ||||
737 | } | ||||
738 | | ||||
739 | _quickSearchOriginalActionTitles.clear(); | ||||
740 | } | ||||
741 | | ||||
512 | #define POPULAR_URLS_ID 100100 | 742 | #define POPULAR_URLS_ID 100100 | ||
513 | #define TRASH_ID 100101 | 743 | #define TRASH_ID 100101 | ||
514 | #define LAN_ID 100103 | 744 | #define LAN_ID 100103 | ||
515 | #define VIRTUAL_FS_ID 100102 | 745 | #define VIRTUAL_FS_ID 100102 | ||
516 | #define JUMP_BACK_ID 100104 | 746 | #define JUMP_BACK_ID 100104 | ||
517 | 747 | | |||
518 | void KrBookmarkHandler::rightClickOnSpecialBookmark() | 748 | void KrBookmarkHandler::rightClickOnSpecialBookmark() | ||
519 | { | 749 | { | ||
▲ Show 20 Lines • Show All 128 Lines • Show Last 20 Lines |