| 
									
										
										
										
											2009-02-25 09:15:00 +01:00
										 |  |  | /**************************************************************************
 | 
					
						
							| 
									
										
										
										
											2008-12-02 12:01:29 +01:00
										 |  |  | ** | 
					
						
							|  |  |  | ** This file is part of Qt Creator | 
					
						
							|  |  |  | ** | 
					
						
							| 
									
										
										
										
											2009-02-25 09:15:00 +01:00
										 |  |  | ** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). | 
					
						
							| 
									
										
										
										
											2008-12-02 12:01:29 +01:00
										 |  |  | ** | 
					
						
							| 
									
										
										
										
											2009-06-17 00:01:27 +10:00
										 |  |  | ** Contact: Nokia Corporation (qt-info@nokia.com) | 
					
						
							| 
									
										
										
										
											2008-12-02 12:01:29 +01:00
										 |  |  | ** | 
					
						
							| 
									
										
										
										
											2009-02-25 09:15:00 +01:00
										 |  |  | ** Commercial Usage | 
					
						
							| 
									
										
										
										
											2008-12-02 14:17:16 +01:00
										 |  |  | ** | 
					
						
							| 
									
										
										
										
											2009-02-25 09:15:00 +01:00
										 |  |  | ** Licensees holding valid Qt Commercial licenses may use this file in | 
					
						
							|  |  |  | ** accordance with the Qt Commercial License Agreement provided with the | 
					
						
							|  |  |  | ** Software or, alternatively, in accordance with the terms contained in | 
					
						
							|  |  |  | ** a written agreement between you and Nokia. | 
					
						
							| 
									
										
										
										
											2008-12-02 14:17:16 +01:00
										 |  |  | ** | 
					
						
							| 
									
										
										
										
											2009-02-25 09:15:00 +01:00
										 |  |  | ** GNU Lesser General Public License Usage | 
					
						
							| 
									
										
										
										
											2008-12-02 14:17:16 +01:00
										 |  |  | ** | 
					
						
							| 
									
										
										
										
											2009-02-25 09:15:00 +01:00
										 |  |  | ** Alternatively, this file may be used under the terms of the GNU Lesser | 
					
						
							|  |  |  | ** General Public License version 2.1 as published by the Free Software | 
					
						
							|  |  |  | ** Foundation and appearing in the file LICENSE.LGPL included in the | 
					
						
							|  |  |  | ** packaging of this file.  Please review the following information to | 
					
						
							|  |  |  | ** ensure the GNU Lesser General Public License version 2.1 requirements | 
					
						
							|  |  |  | ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
 | 
					
						
							| 
									
										
										
										
											2008-12-02 14:17:16 +01:00
										 |  |  | ** | 
					
						
							| 
									
										
										
										
											2009-02-25 09:15:00 +01:00
										 |  |  | ** If you are unsure which license is appropriate for your use, please | 
					
						
							| 
									
										
										
										
											2009-08-14 09:30:56 +02:00
										 |  |  | ** contact the sales department at http://qt.nokia.com/contact.
 | 
					
						
							| 
									
										
										
										
											2008-12-02 12:01:29 +01:00
										 |  |  | ** | 
					
						
							| 
									
										
										
										
											2009-02-25 09:15:00 +01:00
										 |  |  | **************************************************************************/ | 
					
						
							| 
									
										
										
										
											2008-12-02 16:19:05 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-12-02 12:01:29 +01:00
										 |  |  | #include "completionwidget.h"
 | 
					
						
							|  |  |  | #include "completionsupport.h"
 | 
					
						
							|  |  |  | #include "icompletioncollector.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include <texteditor/itexteditable.h>
 | 
					
						
							| 
									
										
										
										
											2008-12-09 15:25:01 +01:00
										 |  |  | #include <utils/qtcassert.h>
 | 
					
						
							| 
									
										
										
										
											2008-12-02 12:01:29 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | #include <QtCore/QEvent>
 | 
					
						
							|  |  |  | #include <QtGui/QApplication>
 | 
					
						
							| 
									
										
										
										
											2008-12-18 16:56:43 +01:00
										 |  |  | #include <QtGui/QDesktopWidget>
 | 
					
						
							|  |  |  | #include <QtGui/QKeyEvent>
 | 
					
						
							| 
									
										
										
										
											2008-12-02 12:01:29 +01:00
										 |  |  | #include <QtGui/QVBoxLayout>
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include <limits.h>
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | using namespace TextEditor; | 
					
						
							|  |  |  | using namespace TextEditor::Internal; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #define NUMBER_OF_VISIBLE_ITEMS 10
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class AutoCompletionModel : public QAbstractListModel | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | public: | 
					
						
							|  |  |  |     AutoCompletionModel(QObject *parent, const QList<CompletionItem> &items); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     inline const CompletionItem &itemAt(const QModelIndex &index) const | 
					
						
							|  |  |  |     { return m_items.at(index.row()); } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     void setItems(const QList<CompletionItem> &items); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     int rowCount(const QModelIndex &parent = QModelIndex()) const; | 
					
						
							|  |  |  |     QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | private: | 
					
						
							|  |  |  |     QList<CompletionItem> m_items; | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | AutoCompletionModel::AutoCompletionModel(QObject *parent, const QList<CompletionItem> &items) | 
					
						
							|  |  |  |     : QAbstractListModel(parent) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     m_items = items; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void AutoCompletionModel::setItems(const QList<CompletionItem> &items) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     m_items = items; | 
					
						
							|  |  |  |     reset(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | int AutoCompletionModel::rowCount(const QModelIndex &) const | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     return m_items.count(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | QVariant AutoCompletionModel::data(const QModelIndex &index, int role) const | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     if (index.row() >= m_items.count()) | 
					
						
							|  |  |  |         return QVariant(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (role == Qt::DisplayRole) { | 
					
						
							| 
									
										
										
										
											2009-10-05 18:32:08 +02:00
										 |  |  |         return itemAt(index).text; | 
					
						
							| 
									
										
										
										
											2008-12-02 12:01:29 +01:00
										 |  |  |     } else if (role == Qt::DecorationRole) { | 
					
						
							| 
									
										
										
										
											2009-10-05 18:32:08 +02:00
										 |  |  |         return itemAt(index).icon; | 
					
						
							| 
									
										
										
										
											2008-12-02 12:01:29 +01:00
										 |  |  |     } else if (role == Qt::ToolTipRole) { | 
					
						
							| 
									
										
										
										
											2009-10-05 18:32:08 +02:00
										 |  |  |         return itemAt(index).details; | 
					
						
							| 
									
										
										
										
											2008-12-02 12:01:29 +01:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return QVariant(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | CompletionWidget::CompletionWidget(CompletionSupport *support, ITextEditable *editor) | 
					
						
							|  |  |  |     : QListView(), | 
					
						
							|  |  |  |       m_blockFocusOut(false), | 
					
						
							| 
									
										
										
										
											2009-06-08 14:32:42 +02:00
										 |  |  |       m_quickFix(false), | 
					
						
							| 
									
										
										
										
											2008-12-02 12:01:29 +01:00
										 |  |  |       m_editor(editor), | 
					
						
							|  |  |  |       m_editorWidget(editor->widget()), | 
					
						
							|  |  |  |       m_model(0), | 
					
						
							|  |  |  |       m_support(support) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2008-12-09 15:25:01 +01:00
										 |  |  |     QTC_ASSERT(m_editorWidget, return); | 
					
						
							| 
									
										
										
										
											2008-12-02 12:01:29 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-01-21 11:11:02 +01:00
										 |  |  |     setAttribute(Qt::WA_MacShowFocusRect, false); | 
					
						
							| 
									
										
										
										
											2008-12-02 12:01:29 +01:00
										 |  |  |     setUniformItemSizes(true); | 
					
						
							|  |  |  |     setSelectionBehavior(QAbstractItemView::SelectItems); | 
					
						
							|  |  |  |     setSelectionMode(QAbstractItemView::SingleSelection); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     connect(this, SIGNAL(activated(const QModelIndex &)), | 
					
						
							|  |  |  |             this, SLOT(completionActivated(const QModelIndex &))); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     // We disable the frame on this list view and use a QFrame around it instead.
 | 
					
						
							| 
									
										
										
										
											2010-01-28 16:53:23 +01:00
										 |  |  |     // This improves the look with QGTKStyle.
 | 
					
						
							| 
									
										
										
										
											2008-12-02 12:01:29 +01:00
										 |  |  |     m_popupFrame = new QFrame(0, Qt::Popup); | 
					
						
							| 
									
										
										
										
											2010-01-28 16:53:23 +01:00
										 |  |  | #ifndef Q_WS_MAC
 | 
					
						
							| 
									
										
										
										
											2008-12-02 12:01:29 +01:00
										 |  |  |     m_popupFrame->setFrameStyle(frameStyle()); | 
					
						
							| 
									
										
										
										
											2010-01-28 16:53:23 +01:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2008-12-02 12:01:29 +01:00
										 |  |  |     setFrameStyle(QFrame::NoFrame); | 
					
						
							|  |  |  |     setParent(m_popupFrame); | 
					
						
							|  |  |  |     m_popupFrame->setObjectName("m_popupFrame"); | 
					
						
							|  |  |  |     m_popupFrame->setAttribute(Qt::WA_DeleteOnClose); | 
					
						
							|  |  |  |     QVBoxLayout *layout = new QVBoxLayout(m_popupFrame); | 
					
						
							|  |  |  |     layout->setMargin(0); | 
					
						
							|  |  |  |     layout->addWidget(this); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); | 
					
						
							| 
									
										
										
										
											2008-12-18 16:56:43 +01:00
										 |  |  |     m_popupFrame->setMinimumSize(1, 1); | 
					
						
							|  |  |  |     setMinimumSize(1, 1); | 
					
						
							| 
									
										
										
										
											2008-12-02 12:01:29 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | bool CompletionWidget::event(QEvent *e) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     if (m_blockFocusOut) | 
					
						
							|  |  |  |         return QListView::event(e); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     bool forwardKeys = true; | 
					
						
							|  |  |  |     if (e->type() == QEvent::FocusOut) { | 
					
						
							| 
									
										
										
										
											2009-11-20 15:07:10 +01:00
										 |  |  |         QModelIndex index; | 
					
						
							|  |  |  | #if defined(Q_OS_DARWIN) && ! defined(QT_MAC_USE_COCOA)
 | 
					
						
							|  |  |  |         QFocusEvent *fe = static_cast<QFocusEvent *>(e); | 
					
						
							|  |  |  |         if (fe->reason() == Qt::OtherFocusReason) { | 
					
						
							|  |  |  |             // Qt/carbon workaround
 | 
					
						
							|  |  |  |             // focus out is received before the key press event.
 | 
					
						
							|  |  |  |             index = currentIndex(); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  |         closeList(index); | 
					
						
							| 
									
										
										
										
											2008-12-02 12:01:29 +01:00
										 |  |  |         return true; | 
					
						
							| 
									
										
										
										
											2010-01-05 18:23:36 +01:00
										 |  |  |     } else if (e->type() == QEvent::ShortcutOverride) { | 
					
						
							|  |  |  |         QKeyEvent *ke = static_cast<QKeyEvent *>(e); | 
					
						
							|  |  |  |         switch (ke->key()) { | 
					
						
							|  |  |  |         case Qt::Key_N: | 
					
						
							|  |  |  |         case Qt::Key_P: | 
					
						
							|  |  |  |             // select next/previous completion
 | 
					
						
							|  |  |  |             if (ke->modifiers() == Qt::ControlModifier) | 
					
						
							|  |  |  |             { | 
					
						
							|  |  |  |                 e->accept(); | 
					
						
							|  |  |  |                 QModelIndex oldIndex = currentIndex(); | 
					
						
							|  |  |  |                 int change = (ke->key() == Qt::Key_N) ? 1 : -1; | 
					
						
							|  |  |  |                 int nrows = model()->rowCount(); | 
					
						
							|  |  |  |                 int row = currentIndex().row(); | 
					
						
							|  |  |  |                 int newRow = (row + change + nrows) % nrows; | 
					
						
							|  |  |  |                 if (newRow == row + change || !ke->isAutoRepeat()) | 
					
						
							|  |  |  |                     setCurrentIndex(m_model->index(newRow)); | 
					
						
							|  |  |  |                 return true; | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2008-12-02 12:01:29 +01:00
										 |  |  |     } else if (e->type() == QEvent::KeyPress) { | 
					
						
							|  |  |  |         QKeyEvent *ke = static_cast<QKeyEvent *>(e); | 
					
						
							|  |  |  |         switch (ke->key()) { | 
					
						
							| 
									
										
										
										
											2010-01-05 18:23:36 +01:00
										 |  |  |         case Qt::Key_N: | 
					
						
							|  |  |  |         case Qt::Key_P: | 
					
						
							|  |  |  |             // select next/previous completion - so don't pass on to editor
 | 
					
						
							|  |  |  |             if (ke->modifiers() == Qt::ControlModifier) | 
					
						
							|  |  |  |                 forwardKeys = false; | 
					
						
							|  |  |  |             break; | 
					
						
							| 
									
										
										
										
											2008-12-02 12:01:29 +01:00
										 |  |  |         case Qt::Key_Escape: | 
					
						
							|  |  |  |             closeList(); | 
					
						
							|  |  |  |             return true; | 
					
						
							|  |  |  |         case Qt::Key_Right: | 
					
						
							|  |  |  |         case Qt::Key_Left: | 
					
						
							|  |  |  |             break; | 
					
						
							|  |  |  |         case Qt::Key_Tab: | 
					
						
							|  |  |  |         case Qt::Key_Return: | 
					
						
							|  |  |  |             //independently from style, accept current entry if return is pressed
 | 
					
						
							| 
									
										
										
										
											2009-11-20 15:07:10 +01:00
										 |  |  |             if (qApp->focusWidget() == this) | 
					
						
							|  |  |  |                 closeList(currentIndex()); | 
					
						
							| 
									
										
										
										
											2008-12-02 12:01:29 +01:00
										 |  |  |             return true; | 
					
						
							|  |  |  |         case Qt::Key_Up: | 
					
						
							| 
									
										
										
										
											2009-11-23 20:42:31 +01:00
										 |  |  |             if (!ke->isAutoRepeat() | 
					
						
							|  |  |  |                 && currentIndex().row() == 0) { | 
					
						
							| 
									
										
										
										
											2009-09-11 11:19:33 +02:00
										 |  |  |                 setCurrentIndex(model()->index(model()->rowCount()-1, 0)); | 
					
						
							|  |  |  |                 return true; | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |             forwardKeys = false; | 
					
						
							|  |  |  |             break; | 
					
						
							| 
									
										
										
										
											2008-12-02 12:01:29 +01:00
										 |  |  |         case Qt::Key_Down: | 
					
						
							| 
									
										
										
										
											2009-11-23 20:42:31 +01:00
										 |  |  |             if (!ke->isAutoRepeat() | 
					
						
							|  |  |  |                 && currentIndex().row() == model()->rowCount()-1) { | 
					
						
							| 
									
										
										
										
											2009-09-11 11:19:33 +02:00
										 |  |  |                 setCurrentIndex(model()->index(0, 0)); | 
					
						
							|  |  |  |                 return true; | 
					
						
							|  |  |  |             } | 
					
						
							| 
									
										
										
										
											2008-12-02 12:01:29 +01:00
										 |  |  |         case Qt::Key_Enter: | 
					
						
							|  |  |  |         case Qt::Key_PageDown: | 
					
						
							|  |  |  |         case Qt::Key_PageUp: | 
					
						
							|  |  |  |             forwardKeys = false; | 
					
						
							|  |  |  |             break; | 
					
						
							|  |  |  |         default: | 
					
						
							| 
									
										
										
										
											2010-01-11 17:54:02 +01:00
										 |  |  |             // if a key is forwarded, completion widget is re-opened and selected item is reset to first,
 | 
					
						
							|  |  |  |             // so only forward keys that insert text and refine the completed item
 | 
					
						
							|  |  |  |             forwardKeys = !ke->text().isEmpty(); | 
					
						
							| 
									
										
										
										
											2008-12-02 12:01:29 +01:00
										 |  |  |             break; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-06-08 14:32:42 +02:00
										 |  |  |         if (forwardKeys && ! m_quickFix) { | 
					
						
							| 
									
										
										
										
											2008-12-02 12:01:29 +01:00
										 |  |  |             m_blockFocusOut = true; | 
					
						
							|  |  |  |             QApplication::sendEvent(m_editorWidget, e); | 
					
						
							|  |  |  |             m_blockFocusOut = false; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             // Have the completion support update the list of items
 | 
					
						
							|  |  |  |             m_support->autoComplete(m_editor, false); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             return true; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     return QListView::event(e); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void CompletionWidget::keyboardSearch(const QString &search) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2009-07-13 17:35:17 +02:00
										 |  |  |     Q_UNUSED(search) | 
					
						
							| 
									
										
										
										
											2008-12-02 12:01:29 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void CompletionWidget::closeList(const QModelIndex &index) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     m_blockFocusOut = true; | 
					
						
							|  |  |  |     if (index.isValid()) | 
					
						
							|  |  |  |         emit itemSelected(m_model->itemAt(index)); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     close(); | 
					
						
							|  |  |  |     if (m_popupFrame) { | 
					
						
							|  |  |  |         m_popupFrame->close(); | 
					
						
							|  |  |  |         m_popupFrame = 0; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     emit completionListClosed(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     m_blockFocusOut = false; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-06-08 14:32:42 +02:00
										 |  |  | void CompletionWidget::setQuickFix(bool quickFix) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     m_quickFix = quickFix; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-12-02 12:01:29 +01:00
										 |  |  | void CompletionWidget::setCompletionItems(const QList<TextEditor::CompletionItem> &completionItems) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     if (!m_model) { | 
					
						
							|  |  |  |         m_model = new AutoCompletionModel(this, completionItems); | 
					
						
							|  |  |  |         setModel(m_model); | 
					
						
							|  |  |  |     } else { | 
					
						
							|  |  |  |         m_model->setItems(completionItems); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     // Select the first of the most relevant completion items
 | 
					
						
							|  |  |  |     int relevance = INT_MIN; | 
					
						
							|  |  |  |     int mostRelevantIndex = 0; | 
					
						
							|  |  |  |     for (int i = 0; i < completionItems.size(); ++i) { | 
					
						
							|  |  |  |         const CompletionItem &item = completionItems.at(i); | 
					
						
							| 
									
										
										
										
											2009-10-05 18:32:08 +02:00
										 |  |  |         if (item.relevance > relevance) { | 
					
						
							|  |  |  |             relevance = item.relevance; | 
					
						
							| 
									
										
										
										
											2008-12-02 12:01:29 +01:00
										 |  |  |             mostRelevantIndex = i; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     setCurrentIndex(m_model->index(mostRelevantIndex)); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void CompletionWidget::showCompletions(int startPos) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2008-12-18 16:56:43 +01:00
										 |  |  |     updatePositionAndSize(startPos); | 
					
						
							| 
									
										
										
										
											2008-12-02 12:01:29 +01:00
										 |  |  |     m_popupFrame->show(); | 
					
						
							|  |  |  |     show(); | 
					
						
							|  |  |  |     setFocus(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-12-18 16:56:43 +01:00
										 |  |  | void CompletionWidget::updatePositionAndSize(int startPos) | 
					
						
							| 
									
										
										
										
											2008-12-02 12:01:29 +01:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2008-12-18 16:56:43 +01:00
										 |  |  |     // Determine size by calculating the space of the visible items
 | 
					
						
							| 
									
										
										
										
											2008-12-02 12:01:29 +01:00
										 |  |  |     int visibleItems = m_model->rowCount(); | 
					
						
							|  |  |  |     if (visibleItems > NUMBER_OF_VISIBLE_ITEMS) | 
					
						
							|  |  |  |         visibleItems = NUMBER_OF_VISIBLE_ITEMS; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     const QStyleOptionViewItem &option = viewOptions(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     QSize shint; | 
					
						
							|  |  |  |     for (int i = 0; i < visibleItems; ++i) { | 
					
						
							|  |  |  |         QSize tmp = itemDelegate()->sizeHint(option, m_model->index(i)); | 
					
						
							|  |  |  |         if (shint.width() < tmp.width()) | 
					
						
							|  |  |  |             shint = tmp; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-12-18 16:56:43 +01:00
										 |  |  |     const int frameWidth = m_popupFrame->frameWidth(); | 
					
						
							|  |  |  |     const int width = shint.width() + frameWidth * 2 + 30; | 
					
						
							|  |  |  |     const int height = shint.height() * visibleItems + frameWidth * 2; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     // Determine the position, keeping the popup on the screen
 | 
					
						
							|  |  |  |     const QRect cursorRect = m_editor->cursorRect(startPos); | 
					
						
							|  |  |  |     const QDesktopWidget *desktop = QApplication::desktop(); | 
					
						
							| 
									
										
										
										
											2009-06-03 20:45:49 +02:00
										 |  |  | #ifdef Q_WS_MAC
 | 
					
						
							| 
									
										
										
										
											2009-01-07 17:07:38 -08:00
										 |  |  |     const QRect screen = desktop->availableGeometry(desktop->screenNumber(m_editorWidget)); | 
					
						
							| 
									
										
										
										
											2008-12-19 17:53:21 +01:00
										 |  |  | #else
 | 
					
						
							| 
									
										
										
										
											2009-01-07 17:07:38 -08:00
										 |  |  |     const QRect screen = desktop->screenGeometry(desktop->screenNumber(m_editorWidget)); | 
					
						
							| 
									
										
										
										
											2008-12-19 17:53:21 +01:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2008-12-18 16:56:43 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |     QPoint pos = cursorRect.bottomLeft(); | 
					
						
							|  |  |  |     pos.rx() -= 16 + frameWidth;    // Space for the icons
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (pos.y() + height > screen.bottom()) | 
					
						
							|  |  |  |         pos.setY(cursorRect.top() - height); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (pos.x() + width > screen.right()) | 
					
						
							|  |  |  |         pos.setX(screen.right() - width); | 
					
						
							| 
									
										
										
										
											2008-12-02 12:01:29 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-12-18 16:56:43 +01:00
										 |  |  |     m_popupFrame->setGeometry(pos.x(), pos.y(), width, height); | 
					
						
							| 
									
										
										
										
											2008-12-02 12:01:29 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void CompletionWidget::completionActivated(const QModelIndex &index) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     closeList(index); | 
					
						
							|  |  |  | } |