• Skip to content
  • Skip to link menu
KDE 4.6 API Reference
  • KDE API Reference
  • kdelibs
  • KDE Home
  • Contact Us
 

Kate

kateargumenthintmodel.cpp

Go to the documentation of this file.
00001 /*  This file is part of the KDE libraries and the Kate part.
00002  *
00003  *  Copyright (C) 2007 David Nolden <david.nolden.kdevelop@art-master.de>
00004  *
00005  *  This library is free software; you can redistribute it and/or
00006  *  modify it under the terms of the GNU Library General Public
00007  *  License as published by the Free Software Foundation; either
00008  *  version 2 of the License, or (at your option) any later version.
00009  *
00010  *  This library is distributed in the hope that it will be useful,
00011  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00012  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00013  *  Library General Public License for more details.
00014  *
00015  *  You should have received a copy of the GNU Library General Public License
00016  *  along with this library; see the file COPYING.LIB.  If not, write to
00017  *  the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
00018  *  Boston, MA 02110-1301, USA.
00019  */
00020 
00021 #include "kateargumenthintmodel.h"
00022 
00023 #include <QTextFormat>
00024 #include <QGridLayout>
00025 #include <kapplication.h>
00026 
00027 #include <ktexteditor/codecompletionmodel.h>
00028 #include "katecompletionwidget.h"
00029 #include "kateargumenthinttree.h"
00030 #include "katecompletiontree.h"
00031 
00032 using namespace KTextEditor;
00033 
00034 void KateArgumentHintModel::clear() {
00035   m_rows.clear();
00036   clearExpanding();
00037 }
00038 
00039 QModelIndex KateArgumentHintModel::mapToSource( const QModelIndex & index ) const {
00040   if( index.row() <  0 || index.row() >= m_rows.count() )
00041     return QModelIndex();
00042     
00043   if( m_rows[index.row()] <  0 || m_rows[index.row()] >= group()->filtered.count() )
00044     return QModelIndex();
00045   
00046   KateCompletionModel::ModelRow source = group()->filtered[m_rows[index.row()]].sourceRow();
00047   if( !source.first ) {
00048     kDebug( 13035 ) << "KateArgumentHintModel::data: Row does not exist in source";
00049     return QModelIndex();
00050   }
00051 
00052   QModelIndex  sourceIndex = source.second.sibling(source.second.row(), index.column());
00053   
00054   return sourceIndex;
00055 }
00056 
00057 void KateArgumentHintModel::parentModelReset() {
00058   clear();
00059   buildRows();
00060 }
00061 
00062 void KateArgumentHintModel::buildRows() {
00063   m_rows.clear();
00064   QMap<int, QList<int> > m_depths; //Map each hint-depth to a list of functions of that depth
00065   for( int a = 0; a < group()->filtered.count(); a++ ) {
00066     KateCompletionModel::ModelRow source = group()->filtered[a].sourceRow();
00067     QModelIndex  sourceIndex = source.second.sibling(source.second.row(), 0);
00068     QVariant v = sourceIndex.data(CodeCompletionModel::ArgumentHintDepth);
00069     if( v.type() == QVariant::Int ) {
00070       QList<int>& lst( m_depths[v.toInt()] );
00071       lst << a;
00072     }
00073   }
00074 
00075   for( QMap<int, QList<int> >::const_iterator it = m_depths.constBegin(); it != m_depths.constEnd(); ++it ) {
00076     foreach( int row, *it )
00077       m_rows.push_front(row);//Insert filtered in reversed order
00078     m_rows.push_front( -it.key() );
00079   }
00080   
00081   reset();
00082   emit contentStateChanged(!m_rows.isEmpty());
00083 }
00084 
00085 KateArgumentHintModel::KateArgumentHintModel( KateCompletionWidget* parent ) : ExpandingWidgetModel(parent), m_parent(parent) {
00086   connect(parent->model(), SIGNAL(modelReset()), this, SLOT(parentModelReset()));
00087   connect(parent->model(), SIGNAL(argumentHintsChanged()), this, SLOT(parentModelReset()));
00088 }
00089 
00090 QVariant KateArgumentHintModel::data ( const QModelIndex & index, int role ) const {
00091   if( index.row() <  0 || index.row() >= m_rows.count() ) {
00092     //kDebug( 13035 ) << "KateArgumentHintModel::data: index out of bound: " << index.row() << " total filtered: " << m_rows.count();
00093     return QVariant();
00094   }
00095 
00096   if( m_rows[index.row()] < 0 ) {
00097     //Show labels
00098     if( role == Qt::DisplayRole && index.column() == 0 ) {
00099       return QString(); //QString("Depth %1").arg(-m_rows[index.row()]);
00100     } else if( role == Qt::BackgroundRole ) {
00101       return KApplication::kApplication()->palette().toolTipBase().color();
00102     }else if( role == Qt::ForegroundRole ) {
00103       return KApplication::kApplication()->palette().toolTipText().color();
00104     }else{
00105       return QVariant();
00106     }
00107   }
00108 
00109   if( m_rows[index.row()] <  0 || m_rows[index.row()] >= group()->filtered.count() ) {
00110     kDebug( 13035 ) << "KateArgumentHintModel::data: index out of bound: " << m_rows[index.row()] << " total filtered: " << group()->filtered.count();
00111     return QVariant();
00112   }
00113   
00114   KateCompletionModel::ModelRow source = group()->filtered[m_rows[index.row()]].sourceRow();
00115   if( !source.first ) {
00116     kDebug( 13035 ) << "KateArgumentHintModel::data: Row does not exist in source";
00117     return QVariant();
00118   }
00119 
00120   if( index.column() == 0 ) {
00121     switch( role ) {
00122       case Qt::DecorationRole:
00123       {
00124         //Show the expand-handle
00125         model()->cacheIcons();
00126 
00127         if( !isExpanded(index ) )
00128           return QVariant( model()->m_collapsedIcon );
00129         else
00130           return QVariant( model()->m_expandedIcon );
00131       }
00132       case Qt::DisplayRole:
00133         //Ignore text in the first column(we create our own compound text in the second)
00134         return QVariant();
00135     }
00136   }
00137 
00138   QModelIndex  sourceIndex = source.second.sibling(source.second.row(), index.column());
00139  
00140   if( !sourceIndex.isValid() ) {
00141     kDebug( 13035 ) << "KateArgumentHintModel::data: Source-index is not valid";
00142     return QVariant();
00143   }
00144 
00145   switch( role ) {
00146     case Qt::DisplayRole:
00147     {
00148       //Construct the text
00149       QString totalText;
00150       for( int a = CodeCompletionModel::Prefix; a <= CodeCompletionModel::Postfix; a++ )
00151         if( a != CodeCompletionModel::Scope ) //Skip the scope
00152           totalText += source.second.sibling(source.second.row(), a).data(Qt::DisplayRole).toString() + ' ';
00153     
00154       
00155       return QVariant(totalText);
00156     }
00157     case CodeCompletionModel::HighlightingMethod:
00158     {
00159       //Return that we are doing custom-highlighting of one of the sub-strings does it
00160       for( int a = CodeCompletionModel::Prefix; a <= CodeCompletionModel::Postfix; a++ ) {
00161           QVariant method = source.second.sibling(source.second.row(), a).data(CodeCompletionModel::HighlightingMethod);
00162           if( method.type() == QVariant::Int && method.toInt() ==  CodeCompletionModel::CustomHighlighting)
00163             return QVariant(CodeCompletionModel::CustomHighlighting);
00164       }
00165     
00166       return QVariant();
00167     }
00168     case CodeCompletionModel::CustomHighlight:
00169     {
00170       QStringList strings;
00171       
00172       //Collect strings
00173       for( int a = CodeCompletionModel::Prefix; a <= CodeCompletionModel::Postfix; a++ )
00174           strings << source.second.sibling(source.second.row(), a).data(Qt::DisplayRole).toString();
00175 
00176       QList<QVariantList> highlights;
00177 
00178       //Collect custom-highlightings
00179       for( int a = CodeCompletionModel::Prefix; a <= CodeCompletionModel::Postfix; a++ )
00180           highlights << source.second.sibling(source.second.row(), a).data(CodeCompletionModel::CustomHighlight).toList();
00181 
00182       //Replace invalid QTextFormats with match-quality color or yellow.
00183       for( QList<QVariantList>::iterator it = highlights.begin(); it != highlights.end(); ++it )
00184       {
00185         QVariantList& list( *it );
00186         
00187         for( int a = 2; a < list.count(); a += 3 )
00188         {
00189           if( list[a].canConvert<QTextFormat>() )
00190           {
00191             QTextFormat f = list[a].value<QTextFormat>();
00192             
00193             if(!f.isValid())
00194             {
00195               f = QTextFormat( QTextFormat::CharFormat );
00196               uint color = matchColor( index );
00197 
00198               if( color )
00199                 f.setBackground( QBrush(color) );
00200               else
00201                 f.setBackground( Qt::yellow );
00202               
00203               list[a] = QVariant( f );
00204             }
00205           }
00206         }
00207       }
00208       
00209       
00210       return mergeCustomHighlighting( strings, highlights, 1 );
00211     }
00212     case Qt::DecorationRole:
00213     {
00214       //Redirect the decoration to the decoration of the item-column
00215       return source.second.sibling(source.second.row(), CodeCompletionModel::Icon).data(role);
00216     }
00217   }
00218   
00219   QVariant v = ExpandingWidgetModel::data( index, role );
00220   if( v.isValid() )
00221     return v;
00222   else
00223     return sourceIndex.data( role );
00224 }
00225 
00226 int KateArgumentHintModel::rowCount ( const QModelIndex & parent ) const {
00227   if( !parent.isValid() )
00228     return m_rows.count();
00229   else
00230     return 0;
00231 }
00232 
00233 int KateArgumentHintModel::columnCount ( const QModelIndex & /*parent*/ ) const {
00234   return 2; //2 Columns, one for the expand-handle, one for the signature
00235 }
00236 
00237 KateCompletionModel::Group* KateArgumentHintModel::group() const {
00238   return model()->m_argumentHints;
00239 }
00240 
00241 KateCompletionModel* KateArgumentHintModel::model() const {
00242   return m_parent->model();
00243 }
00244 
00245 QTreeView* KateArgumentHintModel::treeView() const {
00246   return m_parent->argumentHintTree();
00247 }
00248 
00249 void KateArgumentHintModel::emitDataChanged( const QModelIndex& start, const QModelIndex& end ) {
00250   emit dataChanged(start, end);
00251 }
00252 
00253 bool KateArgumentHintModel::indexIsItem(const QModelIndex& index) const {
00254   return index.row() >= 0 && index.row() < m_rows.count() && m_rows[index.row()] >= 0;
00255 }
00256 
00257 int KateArgumentHintModel::contextMatchQuality(const QModelIndex& index) const {
00258   int row=index.row();
00259   if( row <  0 || row >= m_rows.count() )
00260     return -1;
00261 
00262   if( m_rows[row] <  0 || m_rows[row] >= group()->filtered.count() )
00263     return -1; //Probably a label
00264   
00265   KateCompletionModel::ModelRow source = group()->filtered[m_rows[row]].sourceRow();
00266   if( !source.first )
00267     return -1;
00268   
00269    QModelIndex  sourceIndex = source.second.sibling(source.second.row(), 0);
00270  
00271   if( !sourceIndex.isValid() )
00272     return -1;
00273 
00274   int depth = sourceIndex.data(CodeCompletionModel::ArgumentHintDepth).toInt();
00275 
00276   switch(depth) {
00277     case 1:
00278     {
00279       //This argument-hint is on the lowest level, match it with the currently selected item in the completion-widget
00280       QModelIndex row = m_parent->treeView()->currentIndex();
00281       if( !row.isValid() )
00282         return -1;
00283 
00284       QModelIndex selectedIndex = m_parent->model()->mapToSource( row );
00285       if( !selectedIndex.isValid() )
00286         return -1;
00287 
00288       if( selectedIndex.model() != sourceIndex.model() )
00289         return -1; //We can only match items from the same source-model
00290 
00291       sourceIndex.data( CodeCompletionModel::SetMatchContext );
00292 
00293       QVariant v = selectedIndex.data( CodeCompletionModel::MatchQuality );
00294       if( v.type() == QVariant::Int ) 
00295         return v.toInt();
00296     }
00297     break;
00298     default:
00299       //Do some other nice matching here in future
00300       break;
00301   }
00302 
00303   return -1;
00304 }
00305 
00306 #include "kateargumenthintmodel.moc"

Kate

Skip menu "Kate"
  • Main Page
  • Namespace List
  • Class Hierarchy
  • Alphabetical List
  • Class List
  • File List
  • Namespace Members
  • Class Members
  • Related Pages

kdelibs

Skip menu "kdelibs"
  • DNSSD
  • Interfaces
  •   KHexEdit
  •   KMediaPlayer
  •   KSpeech
  •   KTextEditor
  • Kate
  • kconf_update
  • KDE3Support
  •   KUnitTest
  • KDECore
  • KDED
  • KDEsu
  • KDEUI
  • KDEWebKit
  • KDocTools
  • KFile
  • KHTML
  • KImgIO
  • KInit
  • kio
  • KIOSlave
  • KJS
  •   KJS-API
  •   WTF
  • kjsembed
  • KNewStuff
  • KParts
  • KPty
  • Kross
  • KUnitConversion
  • KUtils
  • Nepomuk
  • Plasma
  • Solid
  • Sonnet
  • ThreadWeaver
Generated for kdelibs by doxygen 1.7.3
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