28#include <QApplication>
37 setAttribute(Qt::WA_ShowWithoutActivating);
38 setAttribute(Qt::WA_X11NetWmWindowTypeCombo);
40 if (qApp->platformName() ==
QL1S(
"xcb")) {
41 setWindowFlags(Qt::Window | Qt::FramelessWindowHint | Qt::BypassWindowManagerHint);
43 setWindowFlags(Qt::Popup);
46 auto *layout =
new QVBoxLayout(
this);
47 layout->setContentsMargins(0, 0, 0, 0);
48 layout->setSpacing(0);
50 m_view =
new QListView(
this);
51 layout->addWidget(m_view);
53 m_view->setUniformItemSizes(
true);
54 m_view->setEditTriggers(QAbstractItemView::NoEditTriggers);
55 m_view->setVerticalScrollMode(QAbstractItemView::ScrollPerPixel);
56 m_view->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
57 m_view->setSelectionBehavior(QAbstractItemView::SelectRows);
58 m_view->setSelectionMode(QAbstractItemView::SingleSelection);
60 m_view->setMouseTracking(
true);
61 qApp->installEventFilter(
this);
64 m_view->setItemDelegate(m_delegate);
66 auto *searchFrame =
new QFrame(
this);
67 searchFrame->setFrameStyle(QFrame::StyledPanel | QFrame::Raised);
68 auto *searchLayout =
new QHBoxLayout(searchFrame);
69 searchLayout->setContentsMargins(10, 4, 4, 4);
71 auto *searchSettingsButton =
new ToolButton(
this);
73 searchSettingsButton->setToolTip(tr(
"Manage Search Engines"));
74 searchSettingsButton->setAutoRaise(
true);
75 searchSettingsButton->setIconSize(QSize(16, 16));
78 auto *searchLabel =
new QLabel(tr(
"Search with:"));
79 m_searchEnginesLayout =
new QHBoxLayout();
84 searchLayout->addWidget(searchLabel);
85 searchLayout->addLayout(m_searchEnginesLayout);
86 searchLayout->addStretch();
87 searchLayout->addWidget(searchSettingsButton);
89 layout->addWidget(searchFrame);
94 return m_view->model();
99 m_view->setModel(
model);
104 return m_view->currentIndex();
109 m_view->setCurrentIndex(index);
114 return m_view->selectionModel();
119 const int maxItemsCount = 12;
120 const int newHeight = m_view->sizeHintForRow(0) * qMin(maxItemsCount,
model()->rowCount()) + 2 * m_view->frameWidth();
122 m_view->setFixedHeight(newHeight);
123 setMaximumHeight(sizeHint().height());
124 setFixedHeight(sizeHint().height());
125 resize(width(), sizeHint().height());
132 if (
object ==
this ||
object == m_view || !isVisible()) {
136 if (
object == m_view->viewport()) {
137 if (event->type() == QEvent::MouseButtonRelease) {
138 auto *e =
static_cast<QMouseEvent*
>(event);
139 QModelIndex idx = m_view->indexAt(e->pos());
140 if (!idx.isValid()) {
144 Qt::MouseButton button = e->button();
145 Qt::KeyboardModifiers modifiers = e->modifiers();
147 if (button == Qt::LeftButton && modifiers == Qt::NoModifier) {
152 if (button == Qt::MiddleButton || (button == Qt::LeftButton && modifiers == Qt::ControlModifier)) {
157 if (button == Qt::LeftButton && modifiers == Qt::ShiftModifier) {
165 switch (event->type()) {
166 case QEvent::KeyPress: {
167 auto* keyEvent =
static_cast<QKeyEvent*
>(event);
168 Qt::KeyboardModifiers modifiers = keyEvent->modifiers();
169 const QModelIndex idx = m_view->currentIndex();
172 if ((keyEvent->key() == Qt::Key_Up || keyEvent->key() == Qt::Key_Down) && m_view->currentIndex() != idx) {
173 m_view->setCurrentIndex(idx);
176 switch (keyEvent->key()) {
179 if (!idx.isValid()) {
183 if (modifiers == Qt::NoModifier || modifiers == Qt::KeypadModifier) {
188 if (modifiers == Qt::ControlModifier) {
193 if (modifiers == Qt::ShiftModifier) {
200 if (modifiers & Qt::ControlModifier) {
201 m_view->setCurrentIndex(
model()->index(
model()->rowCount() - 1, 0));
209 if (modifiers & Qt::ControlModifier) {
210 m_view->setCurrentIndex(
model()->index(0, 0));
211 m_view->scrollToTop();
223 if (modifiers == Qt::AltModifier) {
230 case Qt::Key_Backtab: {
231 const bool isShift = keyEvent->modifiers() == Qt::ShiftModifier;
232 if (keyEvent->modifiers() != Qt::NoModifier && !isShift) {
235 bool isBack = keyEvent->key() == Qt::Key_Backtab;
236 if (keyEvent->key() == Qt::Key_Tab && isShift) {
239 QKeyEvent ev(QKeyEvent::KeyPress, isBack ? Qt::Key_Up : Qt::Key_Down, Qt::NoModifier);
240 QApplication::sendEvent(focusProxy(), &ev);
245 case Qt::Key_PageUp: {
246 if (keyEvent->modifiers() != Qt::NoModifier) {
249 const int step = keyEvent->key() == Qt::Key_PageUp ? 5 : 1;
250 if (!idx.isValid() || idx == visitSearchIdx) {
251 int rowCount =
model()->rowCount();
252 QModelIndex lastIndex =
model()->index(rowCount - 1, 0);
253 m_view->setCurrentIndex(lastIndex);
254 }
else if (idx.row() == 0) {
255 m_view->setCurrentIndex(QModelIndex());
257 m_view->setCurrentIndex(
model()->index(qMax(0, idx.row() - step), 0));
263 case Qt::Key_PageDown: {
264 if (keyEvent->modifiers() != Qt::NoModifier) {
267 const int step = keyEvent->key() == Qt::Key_PageDown ? 5 : 1;
268 if (!idx.isValid()) {
269 QModelIndex firstIndex =
model()->index(0, 0);
270 m_view->setCurrentIndex(firstIndex);
271 }
else if (idx != visitSearchIdx && idx.row() ==
model()->rowCount() - 1) {
272 m_view->setCurrentIndex(visitSearchIdx);
273 m_view->scrollToTop();
275 m_view->setCurrentIndex(
model()->index(qMin(
model()->rowCount() - 1, idx.row() + step), 0));
281 if (idx != visitSearchIdx && m_view->viewport()->rect().contains(m_view->visualRect(idx))) {
289 m_view->viewport()->update();
294 (
static_cast<QObject*
>(focusProxy()))->event(keyEvent);
299 case QEvent::KeyRelease: {
300 auto* keyEvent =
static_cast<QKeyEvent*
>(event);
302 switch (keyEvent->key()) {
305 m_view->viewport()->update();
312 case QEvent::MouseButtonPress:
319 case QEvent::FocusOut: {
320 auto *focusEvent =
static_cast<QFocusEvent*
>(event);
321 if (focusEvent->reason() != Qt::PopupFocusReason && focusEvent->reason() != Qt::MouseFocusReason) {
328 case QEvent::Resize: {
329 QWidget *w = qobject_cast<QWidget*>(
object);
330 if (w && w->isWindow() && focusProxy() && w == focusProxy()->window()) {
346 m_view->verticalScrollBar()->setValue(0);
352void LocationCompleterView::setupSearchEngines()
354 while (m_searchEnginesLayout->count() != 0) {
355 delete m_searchEnginesLayout->takeAt(0);
358 const auto engines =
mApp->searchEnginesManager()->allEngines();
361 button->setIcon(engine.icon);
362 button->setToolTip(engine.name);
363 button->setAutoRaise(
true);
364 button->setIconSize(QSize(16, 16));
365 connect(button, &ToolButton::clicked,
this, [=]() {
369 m_searchEnginesLayout->addWidget(button);
static QIcon settingsIcon()
void setForceVisitItem(bool enable)
void setModel(QAbstractItemModel *model)
void indexCtrlActivated(const QModelIndex &index)
void indexShiftActivated(const QModelIndex &index)
void indexDeleteRequested(const QModelIndex &index)
QAbstractItemModel * model() const
QItemSelectionModel * selectionModel() const
void searchEnginesDialogRequested()
void indexActivated(const QModelIndex &index)
void setCurrentIndex(const QModelIndex &index)
bool eventFilter(QObject *object, QEvent *event) override
void loadRequested(const LoadRequest &request)
QModelIndex currentIndex() const