• Skip to content
  • Skip to link menu
KDE 4.4 API Reference
  • KDE API Reference
  • KDevelop Platform Libraries
  • Sitemap
  • Contact Us
 

language/duchain

abstractnavigationwidget.cpp

00001 /*
00002    Copyright 2007 David Nolden <david.nolden.kdevelop@art-master.de>
00003 
00004    This library is free software; you can redistribute it and/or
00005    modify it under the terms of the GNU Library General Public
00006    License version 2 as published by the Free Software Foundation.
00007 
00008    This library is distributed in the hope that it will be useful,
00009    but WITHOUT ANY WARRANTY; without even the implied warranty of
00010    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00011    Library General Public License for more details.
00012 
00013    You should have received a copy of the GNU Library General Public License
00014    along with this library; see the file COPYING.LIB.  If not, write to
00015    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
00016    Boston, MA 02110-1301, USA.
00017 */
00018 
00019 
00020 #include "abstractnavigationwidget.h"
00021 
00022 #include <QtCore/QMap>
00023 #include <QtCore/QStringList>
00024 #include <QtCore/QMetaObject>
00025 #include <QtGui/QScrollBar>
00026 #include <QtGui/QBoxLayout>
00027 
00028 #include <klocale.h>
00029 
00030 #include "../declaration.h"
00031 #include "../ducontext.h"
00032 #include "../duchainlock.h"
00033 #include "../functiondeclaration.h"
00034 #include "../functiondefinition.h"
00035 #include "../forwarddeclaration.h"
00036 #include "../namespacealiasdeclaration.h"
00037 #include "../classfunctiondeclaration.h"
00038 #include "../classmemberdeclaration.h"
00039 #include "../topducontext.h"
00040 #include "abstractnavigationcontext.h"
00041 #include "abstractdeclarationnavigationcontext.h"
00042 #include "navigationaction.h"
00043 #include "useswidget.h"
00044 #include "../../../interfaces/icore.h"
00045 #include "../../../interfaces/idocumentcontroller.h"
00046 #include <qapplication.h>
00047 #include <qevent.h>
00048 
00049 namespace KDevelop {
00050 
00051 AbstractNavigationWidget::AbstractNavigationWidget()
00052   : m_browser(0), m_currentWidget(0)
00053 {
00054   setPalette( QApplication::palette() );
00055   setFocusPolicy(Qt::NoFocus);
00056   resize(100, 100);
00057 }
00058 
00059 const int maxNavigationWidgetWidth = 580;
00060 
00061 QSize AbstractNavigationWidget::sizeHint() const
00062 {
00063   if(m_browser) {
00064     updateIdealSize();
00065     QSize ret = QSize(qMin(m_idealTextSize.width(), maxNavigationWidgetWidth), qMin(m_idealTextSize.height(), 300));
00066     
00067     if(m_currentWidget) {
00068       ret.setHeight( ret.height() + m_currentWidget->sizeHint().height() );
00069       if(m_currentWidget->sizeHint().width() > ret.width())
00070         ret.setWidth(m_currentWidget->sizeHint().width());
00071       if(ret.width() < 500) //When we embed a widget, give it some space, even if it doesn't have a large size-hint
00072         ret.setWidth(500);
00073       
00074     }
00075     return ret;
00076   } else
00077     return QWidget::sizeHint();
00078 }
00079 
00080 void AbstractNavigationWidget::initBrowser(int height) {
00081   Q_UNUSED(height);
00082   m_browser = new KTextBrowser;
00083   
00084   // since we can embed arbitrary HTML we have to make sure it stays readable by forcing a black-white palette
00085   m_browser->setPalette( QPalette( Qt::black, Qt::white ) );
00086 
00087   m_browser->setOpenLinks(false);
00088   m_browser->setOpenExternalLinks(false);
00089 
00090   QVBoxLayout* layout = new QVBoxLayout;
00091   layout->addWidget(m_browser);
00092   layout->setMargin(0);
00093   setLayout(layout);
00094 
00095   connect( m_browser, SIGNAL(anchorClicked(const QUrl&)), this, SLOT(anchorClicked(const QUrl&)) );
00096 }
00097 
00098 AbstractNavigationWidget::~AbstractNavigationWidget() {
00099   if(m_currentWidget)
00100     layout()->removeWidget(m_currentWidget);
00101     
00102 }
00103 
00104 void AbstractNavigationWidget::setContext(NavigationContextPointer context, int initBrows)
00105 {
00106   if(m_browser == 0)
00107     initBrowser(initBrows);
00108     
00109   if(!context) {
00110     kDebug() << "no new context created";
00111     return;
00112   }
00113   if(context == m_context && (!context || context->alreadyComputed()))
00114     return;
00115   m_context = context;
00116   update();
00117   
00118   emit sizeHintChanged();
00119 }
00120 
00121 void AbstractNavigationWidget::updateIdealSize() const {
00122   if(m_context && !m_idealTextSize.isValid()) {
00123     QTextDocument doc;
00124     doc.setHtml(m_currentText);
00125     if(doc.idealWidth() > maxNavigationWidgetWidth) {
00126       doc.setPageSize( QSize(maxNavigationWidgetWidth, 30) );
00127       m_idealTextSize.setWidth(maxNavigationWidgetWidth);
00128     }else{
00129       m_idealTextSize.setWidth(doc.idealWidth());    
00130     }
00131     m_idealTextSize.setHeight(doc.size().height());
00132   }
00133 }
00134 
00135 void AbstractNavigationWidget::update() {
00136   setUpdatesEnabled(false);
00137   Q_ASSERT( m_context );
00138   
00139   QString html = m_context->html();
00140   if(!html.isEmpty()) {
00141     int scrollPos = m_browser->verticalScrollBar()->value();
00142     
00143     m_browser->setHtml( html );
00144     
00145     m_currentText = html;
00146     m_idealTextSize = QSize();
00147 
00148     QSize hint = sizeHint();
00149     if(hint.height() >= m_idealTextSize.height()) {
00150       m_browser->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
00151     }else{
00152       m_browser->setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded);
00153     }
00154     
00155     m_browser->verticalScrollBar()->setValue(scrollPos);
00156     m_browser->scrollToAnchor("currentPosition");
00157     m_browser->show();
00158   }else{
00159     m_browser->hide();
00160   }
00161   
00162   if(m_currentWidget) {
00163     layout()->removeWidget(m_currentWidget);
00164     m_currentWidget->setParent(0);
00165   }
00166 
00167   m_currentWidget = m_context->widget();
00168   
00169   m_browser->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
00170   m_browser->setMaximumHeight(10000);
00171   
00172   if(m_currentWidget) {
00173     //This connection is a bit hacky..
00174     connect(m_currentWidget, SIGNAL(navigateDeclaration(KDevelop::IndexedDeclaration)),  this, SLOT(navigateDeclaration(KDevelop::IndexedDeclaration)));
00175     layout()->addWidget(m_currentWidget);
00176     if(m_context->isWidgetMaximized()) {
00177       //Leave unused room to the widget
00178       m_browser->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Minimum);
00179       m_browser->setMaximumHeight(25);
00180     }
00181   }
00182 
00183   setUpdatesEnabled(true);
00184 }
00185 
00186 NavigationContextPointer AbstractNavigationWidget::context() {
00187   return m_context;
00188 }
00189 
00190 void AbstractNavigationWidget::navigateDeclaration(KDevelop::IndexedDeclaration decl) {
00191   DUChainReadLocker lock( DUChain::lock() );
00192   setContext(m_context->accept(decl));
00193 }
00194 
00195 void AbstractNavigationWidget::anchorClicked(const QUrl& url) {
00196   DUChainReadLocker lock( DUChain::lock() );
00197 
00198   //We may get deleted while the call to acceptLink, so make sure we don't crash in that case
00199   QPointer<AbstractNavigationWidget> thisPtr(this);
00200   NavigationContextPointer oldContext = m_context;
00201   NavigationContextPointer nextContext = m_context->acceptLink(url.toString());
00202   
00203   if(thisPtr)
00204     setContext( nextContext );
00205 }
00206 
00207 void AbstractNavigationWidget::keyPressEvent(QKeyEvent* event) {
00208   QWidget::keyPressEvent(event);
00209 }
00210 
00211 void AbstractNavigationWidget::executeContextAction(QString action) {
00212   DUChainReadLocker lock( DUChain::lock() );
00213   //We may get deleted while the call to acceptLink, so make sure we don't crash in that case
00214   QPointer<AbstractNavigationWidget> thisPtr(this);
00215   NavigationContextPointer oldContext = m_context;
00216   NavigationContextPointer nextContext = m_context->executeLink(action);
00217   
00218   if(thisPtr)
00219     setContext( nextContext );
00220 }
00221 
00222 void AbstractNavigationWidget::next() {
00223   DUChainReadLocker lock( DUChain::lock() );
00224   Q_ASSERT( m_context );
00225   m_context->nextLink();
00226   update();
00227 }
00228 
00229 void AbstractNavigationWidget::previous() {
00230   DUChainReadLocker lock( DUChain::lock() );
00231   Q_ASSERT( m_context );
00232   m_context->previousLink();
00233   update();
00234 }
00235 
00236 void AbstractNavigationWidget::accept() {
00237   DUChainReadLocker lock( DUChain::lock() );
00238   Q_ASSERT( m_context );
00239   
00240   QPointer<AbstractNavigationWidget> thisPtr(this);
00241   NavigationContextPointer oldContext = m_context;
00242   NavigationContextPointer nextContext = m_context->accept();
00243   
00244   if(thisPtr)
00245     setContext( nextContext );
00246 }
00247 
00248 void AbstractNavigationWidget::back() {
00249   DUChainReadLocker lock( DUChain::lock() );
00250 
00251   QPointer<AbstractNavigationWidget> thisPtr(this);
00252   NavigationContextPointer oldContext = m_context;
00253   NavigationContextPointer nextContext = m_context->back();
00254   
00255   if(thisPtr)
00256     setContext( nextContext );
00257 }
00258 
00259 void AbstractNavigationWidget::up() {
00260   DUChainReadLocker lock( DUChain::lock() );
00261   m_context->up();
00262   update();
00263 }
00264 
00265 void AbstractNavigationWidget::down() {
00266   DUChainReadLocker lock( DUChain::lock() );
00267   m_context->down();
00268   update();
00269 }
00270 
00271 void AbstractNavigationWidget::embeddedWidgetAccept() {
00272   accept();
00273 }
00274 void AbstractNavigationWidget::embeddedWidgetDown() {
00275   down();
00276 }
00277 
00278 void AbstractNavigationWidget::embeddedWidgetRight() {
00279   next();
00280 }
00281 
00282 void AbstractNavigationWidget::embeddedWidgetLeft() {
00283   previous();
00284 }
00285 
00286 void AbstractNavigationWidget::embeddedWidgetUp() {
00287   up();
00288 }
00289 
00290 
00291 void AbstractNavigationWidget::wheelEvent(QWheelEvent* event )
00292 {
00293     QWidget::wheelEvent(event);
00294     event->accept();
00295     return;
00296 }
00297 
00298 
00299 
00300 }
00301 
00302 #include "abstractnavigationwidget.moc"

language/duchain

Skip menu "language/duchain"
  • Main Page
  • Namespace List
  • Class Hierarchy
  • Alphabetical List
  • Class List
  • File List
  • Namespace Members
  • Class Members
  • Related Pages

KDevelop Platform Libraries

Skip menu "KDevelop Platform Libraries"
  • interfaces
  • language
  •   codegen
  •   duchain
  •   editor
  • outputview
  • project
  • shell
  • sublime
  • util
  • vcs
Generated for KDevelop Platform Libraries by doxygen 1.5.9-20090814
This website is maintained by Adriaan de Groot and Allen Winter.
KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal