KDevelop API Documentation

parts/fileview/filegroupswidget.cpp

Go to the documentation of this file.
00001 /*************************************************************************** 00002 * Copyright (C) 2001-2002 by Bernd Gehrmann * 00003 * bernd@kdevelop.org * 00004 * * 00005 * This program is free software; you can redistribute it and/or modify * 00006 * it under the terms of the GNU General Public License as published by * 00007 * the Free Software Foundation; either version 2 of the License, or * 00008 * (at your option) any later version. * 00009 * * 00010 ***************************************************************************/ 00011 00012 #include "filegroupswidget.h" 00013 00014 #include <qfileinfo.h> 00015 #include <qdir.h> 00016 #include <qheader.h> 00017 #include <qtimer.h> 00018 #include <qvbox.h> 00019 #include <qregexp.h> 00020 00021 #include <kdebug.h> 00022 #include <kdialogbase.h> 00023 #include <kiconloader.h> 00024 #include <klocale.h> 00025 #include <kpopupmenu.h> 00026 #include <kaction.h> 00027 #include <kdeversion.h> 00028 00029 #include "kdevcore.h" 00030 #include "kdevproject.h" 00031 #include "kdevmainwindow.h" 00032 #include "kdevpartcontroller.h" 00033 #include "domutil.h" 00034 00035 #include "filegroupspart.h" 00036 #include "filegroupsconfigwidget.h" 00037 00038 00039 // Translations for strings in the project file 00040 static const char *translations[] = { 00041 I18N_NOOP("Sources"), 00042 I18N_NOOP("Translations"), 00043 I18N_NOOP("User Interface"), 00044 I18N_NOOP("Others") 00045 }; 00046 00047 class FileComparator { 00048 public: 00049 virtual ~FileComparator(){ 00050 }; 00051 virtual bool matches(const QString& name) const = 0; 00052 }; 00053 00054 class RegExpComparator : public FileComparator { 00055 public: 00056 RegExpComparator(const QString& pattern) : m_exp(pattern, true, true){ 00057 } 00058 bool matches(const QString& name) const{ 00059 return m_exp.exactMatch(name); 00060 } 00061 private: 00062 const QRegExp m_exp; 00063 }; 00064 00065 class EndingComparator : public FileComparator { 00066 public: 00067 EndingComparator(const QString& pattern) : m_pattern ( pattern){ 00068 } 00069 bool matches(const QString& name) const{ 00070 return name.endsWith(m_pattern); 00071 } 00072 private: 00073 const QString m_pattern; 00074 }; 00075 00076 class FileViewFolderItem : public QListViewItem 00077 { 00078 public: 00079 FileViewFolderItem(QListView *parent, const QString &name, const QString &pattern); 00080 bool matches(const QString &fileName); 00081 00082 private: 00083 QPtrList<FileComparator> m_patterns; 00084 }; 00085 00086 00087 FileViewFolderItem::FileViewFolderItem(QListView *parent, const QString &name, const QString &pattern) 00088 : QListViewItem(parent, name) 00089 { 00090 setPixmap(0, SmallIcon("folder")); 00091 m_patterns.setAutoDelete(true); 00092 QStringList patternstring = QStringList::split(';', pattern); 00093 QStringList::ConstIterator theend = patternstring.end(); 00094 for (QStringList::ConstIterator ci = patternstring.begin(); ci != theend; ++ci) 00095 { 00096 QString pattern = *ci; 00097 QString tail = pattern.right( pattern.length() - 1 ); 00098 00099 if ( (tail).contains('*') || pattern.contains('?') || pattern.contains('[') || pattern.contains(']') ) 00100 { 00101 m_patterns.append( new RegExpComparator( pattern ) ); 00102 } 00103 else 00104 { 00105 if ( pattern.startsWith("*") ) 00106 { 00107 m_patterns.append( new EndingComparator( tail ) ); 00108 } 00109 else 00110 { 00111 m_patterns.append( new EndingComparator( pattern ) ); 00112 } 00113 } 00114 } 00115 } 00116 00117 00118 bool FileViewFolderItem::matches(const QString &fileName) 00119 { 00120 // Test with the file path, so that "*ClientServer/*.h" patterns work 00121 QString fName = QFileInfo(fileName).filePath(); 00122 00123 #if QT_VERSION < 0x030200 00124 QPtrListIterator<FileComparator> it( m_patterns ); 00125 while ( it.current() ) 00126 { 00127 if ( (*it)->matches( fName ) ) 00128 { 00129 return true; 00130 } 00131 ++it; 00132 } 00133 #else 00134 QPtrList<FileComparator>::ConstIterator theend = m_patterns.end(); 00135 for (QPtrList<FileComparator>::ConstIterator ci = m_patterns.begin(); ci != theend; ++ci) 00136 if ((*ci)->matches(fName)) 00137 return true; 00138 #endif 00139 return false; 00140 } 00141 00142 00143 class FileGroupsFileItem : public QListViewItem 00144 { 00145 public: 00146 FileGroupsFileItem(QListViewItem *parent, const QString &fileName); 00147 QString fileName() const 00148 { return fullname; } 00149 00150 private: 00151 QString fullname; 00152 }; 00153 00154 00155 FileGroupsFileItem::FileGroupsFileItem(QListViewItem *parent, const QString &fileName) 00156 : QListViewItem(parent), fullname(fileName) 00157 { 00158 setPixmap(0, SmallIcon("document")); 00159 QFileInfo fi(fileName); 00160 setText(0, fi.fileName()); 00161 setText(1, "./" + fi.dirPath()); 00162 } 00163 00164 FileGroupsWidget::FileGroupsWidget(FileGroupsPart *part) 00165 : KListView(0, "file view widget"), 00166 m_actionToggleShowNonProjectFiles( 0 ), m_actionToggleDisplayLocation( 0 ) 00167 { 00168 /* 00169 Setting Location ID to -1 so I can check if it has been loaded later. 00170 If I dont, it will remove the name column and this is not too good :-) 00171 Is there any better way to do this? 00172 */ 00173 LocationID=-1; 00174 00175 setFocusPolicy(ClickFocus); 00176 setRootIsDecorated(true); 00177 setResizeMode(QListView::LastColumn); 00178 setSorting(-1); 00179 addColumn(i18n("Name")); 00180 // addColumn(i18n("Location")); 00181 00182 connect( this, SIGNAL(executed(QListViewItem*)), 00183 this, SLOT(slotItemExecuted(QListViewItem*)) ); 00184 connect( this, SIGNAL(returnPressed(QListViewItem*)), 00185 this, SLOT(slotItemExecuted(QListViewItem*)) ); 00186 connect( this, SIGNAL(contextMenu(KListView*, QListViewItem*, const QPoint&)), 00187 this, SLOT(slotContextMenu(KListView*, QListViewItem*, const QPoint&)) ); 00188 00189 m_actionToggleShowNonProjectFiles = new KToggleAction( i18n("Show Non Project Files"), KShortcut(), 00190 this, SLOT(slotToggleShowNonProjectFiles()), this, "actiontoggleshowshownonprojectfiles" ); 00191 m_actionToggleShowNonProjectFiles->setWhatsThis(i18n("<b>Show non project files</b><p>Shows files that do not belong to a project in a file tree.")); 00192 00193 m_actionToggleDisplayLocation = new KToggleAction( i18n("Display Location Column"), KShortcut(), 00194 this, SLOT(slotToggleDisplayLocation()), this, "actiontoggleshowlocation" ); 00195 m_actionToggleDisplayLocation->setWhatsThis(i18n("<b>Display the Location Column</b><p>Displays a columne with the location of the files.")); 00196 00197 m_part = part; 00198 (void) translations; // supress compiler warning 00199 00200 QDomDocument &dom = *m_part->projectDom(); 00201 m_actionToggleShowNonProjectFiles->setChecked( !DomUtil::readBoolEntry(dom, "/kdevfileview/groups/hidenonprojectfiles") ); 00202 m_actionToggleDisplayLocation->setChecked( !DomUtil::readBoolEntry(dom, "/kdevfileview/groups/hidenonlocation") ); 00203 } 00204 00205 00206 FileGroupsWidget::~FileGroupsWidget() 00207 { 00208 QDomDocument &dom = *m_part->projectDom(); 00209 DomUtil::writeBoolEntry( dom, "/kdevfileview/groups/hidenonprojectfiles", !m_actionToggleShowNonProjectFiles->isChecked() ); 00210 DomUtil::writeBoolEntry( dom, "/kdevfileview/groups/hidenonlocation", !m_actionToggleDisplayLocation->isChecked() ); 00211 } 00212 00213 00214 void FileGroupsWidget::slotItemExecuted(QListViewItem *item) 00215 { 00216 if (!item) 00217 return; 00218 00219 // toggle open state for parents 00220 if (item->childCount() > 0) 00221 setOpen(item, !isOpen(item)); 00222 00223 // Is it a group item? 00224 if (!item->parent()) 00225 return; 00226 00227 FileGroupsFileItem *fgfitem = static_cast<FileGroupsFileItem*>(item); 00228 #if defined(KDE_MAKE_VERSION) 00229 m_part->partController()->editDocument(KURL::fromPathOrURL( m_part->project()->projectDirectory() + "/" + fgfitem->fileName() )); 00230 #else 00231 m_part->partController()->editDocument(QString("file://") + m_part->project()->projectDirectory() + "/" + fgfitem->fileName() ); 00232 #endif 00233 m_part->mainWindow()->lowerView(this); 00234 } 00235 00236 00237 void FileGroupsWidget::slotContextMenu(KListView *, QListViewItem *item, const QPoint &p) 00238 { 00239 KPopupMenu popup(i18n("File Groups"), this); 00241 int customizeId = popup.insertItem(i18n("Customize...")); 00242 popup.setWhatsThis(customizeId, i18n("<b>Customize</b><p>Opens <b>Customize File Groups</b> dialog where the groups can be managed.")); 00243 if (item) { 00244 if (item->parent()) { 00245 // Not for group items 00246 FileGroupsFileItem *fvfitem = static_cast<FileGroupsFileItem*>(item); 00247 QString pathName = m_part->project()->projectDirectory() + QDir::separator() + fvfitem->fileName(); 00248 FileContext context( pathName, false); 00249 m_part->core()->fillContextMenu(&popup, &context); 00250 } 00251 else{ 00252 QStringList file_list; 00253 QListViewItem* i = item->firstChild(); 00254 while(i){ 00255 FileGroupsFileItem *fvgitem = static_cast<FileGroupsFileItem*>(i); 00256 file_list << fvgitem->fileName(); 00257 i = i->nextSibling(); 00258 } 00259 FileContext context(file_list); 00260 m_part->core()->fillContextMenu(&popup, &context); 00261 } 00262 } 00263 m_actionToggleShowNonProjectFiles->plug( &popup ); 00264 m_actionToggleDisplayLocation->plug( &popup ); 00265 00266 int res = popup.exec(p); 00267 if (res == customizeId) { 00268 KDialogBase dlg(KDialogBase::TreeList, i18n("Customize File Groups"), 00269 KDialogBase::Ok|KDialogBase::Cancel, KDialogBase::Ok, this, 00270 "customization dialog"); 00271 QVBox *vbox = dlg.addVBoxPage(i18n("File Groups")); 00272 FileGroupsConfigWidget *w = new FileGroupsConfigWidget(m_part, vbox, "file groups config widget"); 00273 connect(&dlg, SIGNAL(okClicked()), w, SLOT(accept())); 00274 dlg.exec(); 00275 } 00276 } 00277 00278 QStringList FileGroupsWidget::allFilesRecursively( QString const & dir ) 00279 { 00280 QStringList filelist; 00281 QString reldir = dir.mid( m_part->project()->projectDirectory().length() +1 ); 00282 00283 // recursively fetch all files in subdirectories 00284 QStringList subdirs = QDir( dir ).entryList( QDir::Dirs ); 00285 QValueListIterator<QString> it = subdirs.begin(); 00286 while ( it != subdirs.end() ) 00287 { 00288 if ( *it != "." && *it != ".." ) 00289 { 00290 filelist += allFilesRecursively( dir + "/"+ *it ); 00291 } 00292 ++it; 00293 } 00294 00295 // append the project relative directory path to all files in the current directory 00296 QStringList dirlist = QDir( dir ).entryList( QDir::Files ); 00297 QValueListIterator<QString> itt = dirlist.begin(); 00298 while ( itt != dirlist.end() ) 00299 { 00300 if ( reldir.isEmpty() ) 00301 { 00302 filelist << *itt; 00303 } 00304 else 00305 { 00306 filelist << reldir + "/" + *itt; 00307 } 00308 ++itt; 00309 } 00310 00311 return filelist; 00312 } 00313 00314 void FileGroupsWidget::refresh() 00315 { 00316 while (firstChild()) 00317 delete firstChild(); 00318 00319 if (m_actionToggleDisplayLocation->isChecked()) { 00320 // Display the Location column 00321 LocationID=addColumn(i18n("Location")); 00322 } 00323 else { 00324 // Remove the Location column 00325 //Need to check if the ID exists, if not do nothing!! 00326 if (LocationID!=-1) 00327 removeColumn(LocationID); 00328 } 00329 QDomDocument &dom = *m_part->projectDom(); 00330 DomUtil::PairList list = 00331 DomUtil::readPairListEntry(dom, "/kdevfileview/groups", "group", "name", "pattern"); 00332 00333 FileViewFolderItem *lastGroup = 0; 00334 00335 DomUtil::PairList::ConstIterator git; 00336 for (git = list.begin(); git != list.end(); ++git) { 00337 FileViewFolderItem *newItem = new FileViewFolderItem(this, (*git).first, (*git).second); 00338 if (lastGroup) 00339 newItem->moveItem(lastGroup); 00340 lastGroup = newItem; 00341 } 00342 00343 QStringList allFiles; 00344 if (m_actionToggleShowNonProjectFiles->isChecked()) { 00345 // get all files in the project directory 00346 allFiles = allFilesRecursively( m_part->project()->projectDirectory() ); 00347 } 00348 else { 00349 // get all project files 00350 allFiles = m_part->project()->allFiles(); 00351 } 00352 QStringList::ConstIterator fit; 00353 for (fit = allFiles.begin(); fit != allFiles.end(); ++fit) { 00354 QListViewItem *item = firstChild(); 00355 while (item) { 00356 FileViewFolderItem *fvgitem = static_cast<FileViewFolderItem*>(item); 00357 if (fvgitem->matches(*fit)) { 00358 (void) new FileGroupsFileItem(fvgitem, *fit); 00359 break; 00360 } 00361 item = item->nextSibling(); 00362 } 00363 } 00364 00365 QListViewItem *item = firstChild(); 00366 while (item) { 00367 item->sortChildItems(0, true); 00368 item = item->nextSibling(); 00369 } 00370 } 00371 00372 00373 void FileGroupsWidget::addFile(const QString &fileName) 00374 { 00375 kdDebug(9017) << "FileView add " << fileName << endl; 00376 00377 QListViewItem *item = firstChild(); 00378 while (item) { 00379 FileViewFolderItem *fvgitem = static_cast<FileViewFolderItem*>(item); 00380 if (fvgitem->matches(fileName)) 00381 { 00382 QString f = fileName; 00383 if (fileName.contains(m_part->project()->projectDirectory())) 00384 f = fileName.mid(m_part->project()->projectDirectory().length()+1); 00385 (void) new FileGroupsFileItem(fvgitem, f); 00386 fvgitem->sortChildItems(0, true); 00387 break; 00388 } 00389 item = item->nextSibling(); 00390 } 00391 } 00392 00393 void FileGroupsWidget::addFiles ( const QStringList& fileList ) 00394 { 00395 QStringList::ConstIterator it; 00396 00397 for ( it = fileList.begin(); it != fileList.end(); ++it ) 00398 { 00399 this->addFile ( *it ); 00400 } 00401 } 00402 00403 void FileGroupsWidget::removeFile(const QString &fileName) 00404 { 00405 kdDebug(9017) << "FileView remove " << fileName << endl; 00406 00407 QListViewItem *item = firstChild(); 00408 while (item) 00409 { 00410 FileViewFolderItem *fvgitem = static_cast<FileViewFolderItem*>(item); 00411 QListViewItem *childItem = fvgitem->firstChild(); 00412 while (childItem) 00413 { 00414 FileGroupsFileItem *fgfitem = static_cast<FileGroupsFileItem*>(childItem); 00415 kdDebug ( 9017 ) << "fvfitem->fileName() is " << fgfitem->fileName() << endl; 00416 if (fgfitem->fileName() == fileName ) 00417 { 00418 kdDebug ( 9017 ) << "Deleting: " << fgfitem->fileName() << endl; 00419 00420 delete fgfitem; 00421 return; 00422 } 00423 childItem = childItem->nextSibling(); 00424 } 00425 item = item->nextSibling(); 00426 } 00427 } 00428 00429 void FileGroupsWidget::removeFiles ( const QStringList& fileList ) 00430 { 00431 QStringList::ConstIterator it; 00432 00433 for ( it = fileList.begin(); it != fileList.end(); ++it ) 00434 { 00435 removeFile ( *it ); 00436 } 00437 } 00438 00439 void FileGroupsWidget::slotToggleShowNonProjectFiles() 00440 { 00441 refresh(); 00442 } 00443 00444 void FileGroupsWidget::slotToggleDisplayLocation() 00445 { 00446 refresh(); 00447 } 00448 00449 00450 #include "filegroupswidget.moc" 00451
KDE Logo
This file is part of the documentation for KDevelop Version 3.0.4.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Tue Oct 19 08:01:51 2004 by doxygen 1.3.7 written by Dimitri van Heesch, © 1997-2003