21 #include <QtGui/QTreeWidgetItemIterator>
25 #include <kiconloader.h>
26 #include <kmimetype.h>
27 #include <kaboutdata.h>
28 #include <kcomponentdata.h>
29 #include <kpluginfactory.h>
31 #include "difference.h"
32 #include "diffmodel.h"
33 #include "diffmodellist.h"
34 #include "komparemodellist.h"
37 #define COL_DESTINATION 1
38 #define COL_DIFFERENCE 2
40 using namespace Diff2;
43 : KParts::ReadOnlyPart( parent ),
53 m_selectedDifference( 0 ),
58 m_splitter =
new QSplitter( Qt::Horizontal, parentWidget );
60 setWidget( m_splitter );
63 m_srcDirTree->setHeaderLabel( i18n(
"Source Folder") );
64 m_srcDirTree->setRootIsDecorated(
false );
65 m_srcDirTree->setSortingEnabled(
true );
66 m_srcDirTree->sortByColumn( 0, Qt::AscendingOrder );
69 m_destDirTree->setHeaderLabel( i18n(
"Destination Folder") );
70 m_destDirTree->setRootIsDecorated(
false );
71 m_destDirTree->setSortingEnabled(
true );
72 m_destDirTree->sortByColumn( 0, Qt::AscendingOrder );
75 m_fileList->setHeaderLabels( QStringList() << i18n(
"Source File") << i18n(
"Destination File") );
76 m_fileList->setAllColumnsShowFocus(
true );
77 m_fileList->setRootIsDecorated(
false );
78 m_fileList->setSortingEnabled(
true );
79 m_fileList->sortByColumn( 0, Qt::AscendingOrder );
82 m_changesList->setHeaderLabels( QStringList() << i18n(
"Source Line") << i18n(
"Destination Line") << i18n(
"Difference") );
83 m_changesList->setAllColumnsShowFocus(
true );
84 m_changesList->setRootIsDecorated(
false );
85 m_changesList->setSortingEnabled(
true );
86 m_changesList->sortByColumn( 0, Qt::AscendingOrder );
102 m_selectedDifference = 0;
112 kDebug(8105) <<
"Models (" << modelList <<
") have changed... scanning the models... " << endl;
116 m_modelList = modelList;
117 m_srcDirTree->clear();
118 m_destDirTree->clear();
120 m_changesList->clear();
125 m_modelList = modelList;
126 m_srcDirTree->clear();
127 m_destDirTree->clear();
129 m_changesList->clear();
133 void KompareNavTreePart::buildTreeInMemory()
135 kDebug(8105) <<
"BuildTreeInMemory called" << endl;
137 if ( m_modelList->count() == 0 )
139 kDebug(8105) <<
"No models... weird shit..." << endl;
145 kDebug(8105) <<
"No Info... weird shit..." << endl;
153 model = m_modelList->first();
154 m_selectedModel = 0L;
156 switch ( m_info->mode )
158 case Kompare::ShowingDiff:
165 srcBase = model->sourcePath();
166 destBase = model->destinationPath();
168 if ( srcBase[0] !=
'/' )
170 if ( destBase[0] !=
'/' )
173 case Kompare::ComparingFiles:
174 srcBase = model->sourcePath();
175 destBase = model->destinationPath();
177 case Kompare::ComparingDirs:
178 srcBase = m_info->localSource;
179 if ( !srcBase.endsWith(
'/' ) )
181 destBase = m_info->localDestination;
182 if ( !destBase.endsWith(
'/' ) )
185 case Kompare::BlendingFile:
186 case Kompare::BlendingDir:
188 kDebug(8105) <<
"Oops needs to implement this..." << endl;
194 m_srcRootItem =
new KDirLVI( m_srcDirTree, srcBase );
195 m_destRootItem =
new KDirLVI( m_destDirTree, destBase );
201 DiffModelListConstIterator modelIt = m_modelList->begin();
202 DiffModelListConstIterator mEnd = m_modelList->end();
204 for ( ; modelIt != mEnd; ++modelIt )
207 srcPath = model->sourcePath();
208 destPath = model->destinationPath();
210 kDebug(8105) <<
"srcPath = " << srcPath << endl;
211 kDebug(8105) <<
"destPath = " << destPath << endl;
212 m_srcRootItem->
addModel( srcPath, model, &m_modelToSrcDirItemDict );
213 m_destRootItem->
addModel( destPath, model, &m_modelToDestDirItemDict );
218 void KompareNavTreePart::buildDirectoryTree()
224 QString KompareNavTreePart::compareFromEndAndReturnSame(
225 const QString& string1,
226 const QString& string2 )
230 int srcLen = string1.length();
231 int destLen = string2.length();
233 while ( srcLen != 0 && destLen != 0 )
235 if ( string1[--srcLen] == string2[--destLen] )
236 result.prepend( string1[srcLen] );
241 if ( srcLen != 0 && destLen != 0 && result.startsWith(
'/' ) )
242 result = result.remove( 0, 1 );
249 kDebug(8105) <<
"KompareNavTreePart::slotSetSelection model = " << model <<
", diff = " << diff << endl;
250 if ( model == m_selectedModel )
253 if ( diff != m_selectedDifference )
255 m_selectedDifference = diff;
256 setSelectedDifference( diff );
263 if ( !m_selectedModel || model->sourcePath() != m_selectedModel->sourcePath() )
265 m_selectedModel = model;
266 m_selectedDifference = diff;
268 setSelectedDir( model );
269 setSelectedFile( model );
270 setSelectedDifference( diff );
274 if ( !m_selectedModel || model->sourceFile() != m_selectedModel->sourceFile() )
276 m_selectedModel = model;
277 setSelectedFile( model );
279 m_selectedDifference = diff;
280 setSelectedDifference( diff );
284 void KompareNavTreePart::setSelectedDir(
const DiffModel* model )
287 currentDir = m_modelToSrcDirItemDict[ model ];
288 kDebug(8105) <<
"Manually setting selection in srcdirtree with currentDir = " << currentDir << endl;
289 m_srcDirTree->blockSignals(
true );
290 m_srcDirTree->setCurrentItem( currentDir );
291 m_srcDirTree->scrollToItem( currentDir );
292 m_srcDirTree->blockSignals(
false );
294 currentDir = m_modelToDestDirItemDict[ model ];
295 kDebug(8105) <<
"Manually setting selection in destdirtree with currentDir = " << currentDir << endl;
296 m_destDirTree->blockSignals(
true );
297 m_destDirTree->setCurrentItem( currentDir );
298 m_destDirTree->scrollToItem( currentDir );
299 m_destDirTree->blockSignals(
false );
301 m_fileList->blockSignals(
true );
302 currentDir->
fillFileList( m_fileList, &m_modelToFileItemDict );
303 m_fileList->blockSignals(
false );
306 void KompareNavTreePart::setSelectedFile(
const DiffModel* model )
309 currentFile = m_modelToFileItemDict[ model ];
310 kDebug(8105) <<
"Manually setting selection in filelist" << endl;
311 m_fileList->blockSignals(
true );
312 m_fileList->setCurrentItem( currentFile );
313 m_fileList->scrollToItem( currentFile );
314 m_fileList->blockSignals(
false );
316 m_changesList->blockSignals(
true );
317 currentFile->
fillChangesList( m_changesList, &m_diffToChangeItemDict );
318 m_changesList->blockSignals(
false );
321 void KompareNavTreePart::setSelectedDifference(
const Difference* diff )
324 currentDiff = m_diffToChangeItemDict[ diff ];
325 kDebug(8105) <<
"Manually setting selection in changeslist to " << currentDiff << endl;
326 m_changesList->blockSignals(
true );
327 m_changesList->setCurrentItem( currentDiff );
328 m_changesList->scrollToItem( currentDiff );
329 m_changesList->blockSignals(
false );
335 if ( m_selectedDifference != diff )
338 m_selectedDifference = diff;
339 setSelectedDifference( diff );
343 void KompareNavTreePart::slotSrcDirTreeSelectionChanged(
QTreeWidgetItem* item )
348 kDebug(8105) <<
"Sent by the sourceDirectoryTree with item = " << item << endl;
349 m_srcDirTree->scrollToItem( item );
356 m_destDirTree->blockSignals(
true );
357 m_destDirTree->setCurrentItem( selItem );
358 m_destDirTree->scrollToItem( selItem );
359 m_destDirTree->blockSignals(
false );
361 dir->
fillFileList( m_fileList, &m_modelToFileItemDict );
364 void KompareNavTreePart::slotDestDirTreeSelectionChanged(
QTreeWidgetItem* item )
369 kDebug(8105) <<
"Sent by the destinationDirectoryTree with item = " << item << endl;
370 m_destDirTree->scrollToItem( item );
377 m_srcDirTree->blockSignals(
true );
378 m_srcDirTree->setCurrentItem( selItem );
379 m_srcDirTree->scrollToItem( selItem );
380 m_srcDirTree->blockSignals(
false );
382 dir->
fillFileList( m_fileList, &m_modelToFileItemDict );
385 void KompareNavTreePart::slotFileListSelectionChanged(
QTreeWidgetItem* item )
390 kDebug(8105) <<
"Sent by the fileList with item = " << item << endl;
393 m_selectedModel = file->
model();
394 m_changesList->blockSignals(
true );
396 m_changesList->blockSignals(
false );
398 if ( m_changesList->currentItem() )
401 m_selectedDifference = (
static_cast<KChangeLVI*
>(m_changesList->currentItem()))->difference();
407 void KompareNavTreePart::slotChangesListSelectionChanged(
QTreeWidgetItem* item )
412 kDebug(8105) <<
"Sent by the changesList" << endl;
420 void KompareNavTreePart::slotApplyDifference(
bool )
422 KChangeLVI* clvi = m_diffToChangeItemDict[m_selectedDifference];
427 void KompareNavTreePart::slotApplyAllDifferences(
bool )
429 QHash<const Diff2::Difference*, KChangeLVI*>::ConstIterator it = m_diffToChangeItemDict.constBegin();
430 QHash<const Diff2::Difference*, KChangeLVI*>::ConstIterator end = m_diffToChangeItemDict.constEnd();
432 kDebug(8105) <<
"m_diffToChangeItemDict.count() = " << m_diffToChangeItemDict.count() << endl;
434 for ( ; it != end ; ++it )
436 it.value()->setDifferenceText();
440 void KompareNavTreePart::slotApplyDifference(
const Difference* diff,
bool )
443 KChangeLVI* clvi = m_diffToChangeItemDict[diff];
451 switch( m_difference->type() ) {
452 case Difference::Change:
455 if( m_difference->applied() )
456 text = i18np(
"Applied: Changes made to %1 line undone",
"Applied: Changes made to %1 lines undone",
457 m_difference->sourceLineCount() );
459 text = i18np(
"Changed %1 line",
"Changed %1 lines",
460 m_difference->sourceLineCount() );
462 case Difference::Insert:
463 if( m_difference->applied() )
464 text = i18np(
"Applied: Insertion of %1 line undone",
"Applied: Insertion of %1 lines undone",
465 m_difference->destinationLineCount() );
467 text = i18np(
"Inserted %1 line",
"Inserted %1 lines",
468 m_difference->destinationLineCount() );
470 case Difference::Delete:
471 if( m_difference->applied() )
472 text = i18np(
"Applied: Deletion of %1 line undone",
"Applied: Deletion of %1 lines undone",
473 m_difference->sourceLineCount() );
475 text = i18np(
"Deleted %1 line",
"Deleted %1 lines",
476 m_difference->sourceLineCount() );
479 kDebug(8105) <<
"Unknown or Unchanged enum value when checking for diff->type() in KChangeLVI's constructor" << endl;
490 setText( 0, QString::number( diff->sourceLineNumber() ) );
491 setText( 1, QString::number( diff->destinationLineNumber() ) );
498 int column = treeWidget()->sortColumn();
499 QString text1 = text(column);
500 QString text2 = item.text(column);
503 if (column < 2 && text1.length() != text2.length())
504 return text1.length() < text2.length();
505 return text1 < text2;
516 QString src = model->sourceFile();
517 QString dst = model->destinationFile();
521 setIcon( 0, SmallIcon( getIcon( src ) ) );
522 setIcon( 1, SmallIcon( getIcon( dst ) ) );
525 bool KFileLVI::hasExtension(
const QString& extensions,
const QString& fileName)
527 QStringList extList = extensions.split(
' ');
528 foreach (
const QString &ext, extList) {
529 if ( fileName.endsWith(ext, Qt::CaseInsensitive) ) {
536 const QString KFileLVI::getIcon(
const QString& fileName)
539 if ( hasExtension(
".h .hpp", fileName ) ) {
540 return "text-x-c++hdr";
542 if ( hasExtension(
".cpp", fileName ) ) {
543 return "text-x-c++src";
545 if ( hasExtension(
".c", fileName ) ) {
546 return "text-x-csrc";
549 if ( hasExtension(
".py .pyw", fileName ) ) {
550 return "text-x-python";
553 if ( hasExtension(
".cs", fileName ) ) {
554 return "text-x-csharp";
557 if ( hasExtension(
".m", fileName ) ) {
558 return "text-x-objcsrc";
561 if ( hasExtension(
".java", fileName ) ) {
562 return "text-x-java";
565 if ( hasExtension(
".sh", fileName ) ) {
566 return "text-x-script";
569 if ( hasExtension(
".cmake Makefile", fileName ) ) {
570 return "text-x-makefile";
573 if ( hasExtension(
".ada .ads .adb", fileName ) ) {
574 return "text-x-adasrc";
577 if ( hasExtension(
".pas", fileName ) ) {
578 return "text-x-pascal";
581 if ( hasExtension(
".diff", fileName ) ) {
582 return "text-x-patch";
585 if ( hasExtension(
".tcl", fileName ) ) {
589 if ( hasExtension(
".txt", fileName ) ) {
593 if ( hasExtension(
".xml", fileName ) ) {
602 changesList->clear();
603 diffToChangeItemDict->clear();
605 DifferenceListConstIterator diffIt = m_model->differences()->constBegin();
606 DifferenceListConstIterator dEnd = m_model->differences()->constEnd();
608 for ( ; diffIt != dEnd; ++diffIt )
611 diffToChangeItemDict->insert( *diffIt, change );
614 changesList->setCurrentItem( changesList->topLevelItem( 0 ) );
626 setIcon( 0, SmallIcon(
"folder" ) );
628 if ( m_dirName.isEmpty() )
629 setText( 0, i18n(
"Unknown" ) );
631 setText( 0, m_dirName );
639 setIcon( 0, SmallIcon(
"folder" ) );
641 setText( 0, m_dirName );
645 void KDirLVI::addModel( QString& path, DiffModel* model, QHash<const Diff2::DiffModel*, KDirLVI*>* modelToDirItemDict )
649 if ( !m_dirName.isEmpty() )
651 if ( path.indexOf( m_dirName ) > -1 )
652 path = path.remove( path.indexOf( m_dirName ), m_dirName.length() );
657 if ( path.isEmpty() ) {
658 m_modelList.append( model );
659 modelToDirItemDict->insert( model,
this );
665 QString dir = path.mid( 0, path.indexOf(
"/", 0 ) + 1 );
666 child = findChild( dir );
671 child =
new KDirLVI(
this, dir );
674 child->
addModel( path, model, modelToDirItemDict );
677 KDirLVI* KDirLVI::findChild( QString dir )
681 if ( ( child = static_cast<KDirLVI*>(this->child(0)) ) != 0L )
683 QTreeWidgetItemIterator it(child);
685 child =
static_cast<KDirLVI*
>(*it);
700 DiffModelListIterator modelIt = m_modelList.begin();
701 DiffModelListIterator mEnd = m_modelList.end();
702 for ( ;modelIt != mEnd; ++modelIt )
705 modelToFileItemDict->insert( *modelIt, file );
708 fileList->setCurrentItem( fileList->topLevelItem( 0 ) );
721 path = path.prepend( m_dirName );
739 dir = dir.remove( 0, m_dirName.length() );
750 QTreeWidgetItemIterator it(child);
752 child =
static_cast<KDirLVI*
>(*it);
754 if ( dir.startsWith( child->
dirName() ) )
769 KAboutData about(
"komparenavtreepart", 0, ki18n(
"KompareNavTreePart"),
"1.2");
770 about.addAuthor(ki18n(
"John Firebaugh"), ki18n(
"Author"),
"jfirebaugh@kde.org");
771 about.addAuthor(ki18n(
"Otto Bruggeman"), ki18n(
"Author"),
"bruggie@gmail.com" );
775 K_PLUGIN_FACTORY(KompareNavTreePartFactory,
776 registerPlugin<KompareNavTreePart>();
778 K_EXPORT_PLUGIN( KompareNavTreePartFactory(
aboutData()) )
780 #include "komparenavtreepart.moc"
void fillFileList(QTreeWidget *fileList, QHash< const Diff2::DiffModel *, KFileLVI * > *modelToFileItemDict)
virtual bool operator<(const QTreeWidgetItem &item) const
QString fullPath(QString &path)
KompareNavTreePart(QWidget *parentWidget, QObject *parent, const QVariantList &args)
void selectionChanged(const Diff2::DiffModel *model, const Diff2::Difference *diff)
KFileLVI(QTreeWidget *parent, Diff2::DiffModel *model)
Diff2::DiffModel * model()
void addModel(QString &dir, Diff2::DiffModel *model, QHash< const Diff2::DiffModel *, KDirLVI * > *modelToDirItemDict)
void slotKompareInfo(Kompare::Info *info)
void slotModelsChanged(const Diff2::DiffModelList *modelList)
void fillChangesList(QTreeWidget *changesList, QHash< const Diff2::Difference *, KChangeLVI * > *diffToChangeItemDict)
KDirLVI(KDirLVI *parent, QString &dir)
void slotSetSelection(const Diff2::DiffModel *model, const Diff2::Difference *diff)
static KAboutData aboutData()
virtual ~KompareNavTreePart()
KChangeLVI(QTreeWidget *parent, Diff2::Difference *diff)
Diff2::Difference * difference()
KDirLVI * setSelected(QString dir)