Make a branch to make krunner Good Enough For Aaron™.
[kdebase/uwolfer.git] / apps / kappfinder / toplevel.cpp
blobc0ef66d34ef9ab5fc0e0d045a8c7691bf0513870
1 /*
2 KAppfinder, the KDE application finder
4 Copyright (c) 2002-2003 Tobias Koenig <tokoe@kde.org>
6 Based on code written by Matthias Hoelzer-Kluepfel <hoelzer@kde.org>
8 This program is free software; you can redistribute it and/or
9 modify it under the terms of version 2 of the GNU General Public
10 License as published by the Free Software Foundation.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
22 // Own
23 #include "toplevel.h"
25 // Qt
26 #include <QtGui/QLabel>
27 #include <QtGui/QLayout>
28 #include <QtGui/QPushButton>
29 #include <QtCore/QDir>
30 #include <QtCore/QRegExp>
31 #include <QtGui/QProgressBar>
32 #include <QtGui/QBoxLayout>
34 // KDE
35 #include <kapplication.h>
36 #include <kbuildsycocaprogressdialog.h>
37 #include <kdebug.h>
38 #include <kdesktopfile.h>
39 #include <kglobal.h>
40 #include <klocale.h>
41 #include <kmessagebox.h>
42 #include <kservice.h>
43 #include <kservicegroup.h>
44 #include <kstandarddirs.h>
45 #include <kstandardguiitem.h>
47 TopLevel::TopLevel( const QString &destDir, QWidget *parent )
48 : KDialog( parent )
50 setCaption( i18n( "KAppfinder" ) );
51 setButtons( Apply | Close | User1 | User2 | User3 );
53 QFrame *frame = new QFrame;
54 setMainWidget( frame );
56 QVBoxLayout *layout = new QVBoxLayout( frame );
57 layout->setMargin( marginHint() );
59 QLabel *label = new QLabel( i18n( "The application finder looks for non-KDE "
60 "applications on your system and adds "
61 "them to the KDE menu system. "
62 "Click 'Scan' to begin, select the desired "
63 "applications and then click 'Apply'."), frame);
64 label->setAlignment( Qt::AlignLeft );
65 label->setWordWrap( true );
67 mListView = new QTreeWidget( frame );
68 mListView->setHeaderLabels(QStringList() << i18n( "Application" ) << i18n( "Description" ) << i18n( "Command" ) );
69 mListView->setRootIsDecorated( true );
70 mListView->setAllColumnsShowFocus( true );
71 mListView->setSelectionMode( QTreeWidget::NoSelection );
72 mListView->setColumnWidth( 0, 200 );
73 mListView->setColumnWidth( 1, 160 );
75 mProgress = new QProgressBar( frame );
76 mProgress->setTextVisible( false );
78 mSummary = new QLabel( i18n( "Summary:" ), frame );
80 setButtonGuiItem(User1 , KGuiItem( i18n( "Scan" ), "edit-find"));
81 setButtonGuiItem(User2, KGuiItem(i18n( "Select All" )));
82 setButtonGuiItem(User3, KGuiItem(i18n( "Unselect All" )));
83 connect(this,SIGNAL(user1Clicked()), this, SLOT( slotScan() ) );
84 connect(this,SIGNAL(user2Clicked()), this, SLOT( slotSelectAll() ) );
85 connect(this,SIGNAL(user3Clicked()), this, SLOT( slotUnselectAll() ) );
86 connect(this,SIGNAL(applyClicked()), this, SLOT( slotCreate() ) );
87 connect(this,SIGNAL(closeClicked()), kapp, SLOT( quit() ) );
89 enableButton(User2, false );
90 enableButton(User3, false );
91 enableButton(Apply, false );
94 layout->addWidget( label );
95 layout->addSpacing( 5 );
96 layout->addWidget( mListView );
97 layout->addWidget( mProgress );
98 layout->addWidget( mSummary );
100 connect( kapp, SIGNAL( lastWindowClosed() ), kapp, SLOT( quit() ) );
102 adjustSize();
103 setMinimumSize(minimumSizeHint());
105 mDestDir = destDir;
106 mDestDir = mDestDir.replace( QRegExp( "^~/" ), QDir::homePath() + '/' );
109 TopLevel::~TopLevel()
111 qDeleteAll(mAppCache);
112 mAppCache.clear();
115 QTreeWidgetItem* TopLevel::addGroupItem( QTreeWidgetItem *parent, const QString &relPath,
116 const QString &name )
118 KServiceGroup::Ptr root = KServiceGroup::group( relPath );
119 if( !root )
120 return 0L;
121 KServiceGroup::List list = root->entries();
123 KServiceGroup::List::ConstIterator it;
124 for ( it = list.begin(); it != list.end(); ++it ) {
125 const KSycocaEntry *p = (*it).data();
126 if ( p->isType( KST_KServiceGroup ) ) {
127 const KServiceGroup* serviceGroup = static_cast<const KServiceGroup*>( p );
128 if ( QString( "%1%2/" ).arg( relPath ).arg( name ) == serviceGroup->relPath() ) {
129 QTreeWidgetItemIterator it( mListView );
130 if ( parent )
131 it = QTreeWidgetItemIterator( parent );
133 while ( *it ) {
134 if ( ( *it )->text( 0 ) == serviceGroup->caption() )
135 return ( *it );
137 it++;
140 QTreeWidgetItem *item;
141 if ( parent )
142 item = new QTreeWidgetItem( parent, QStringList() << serviceGroup->caption() );
143 else
144 item = new QTreeWidgetItem( mListView, QStringList() << serviceGroup->caption() );
146 item->setIcon( 0, KIcon( serviceGroup->icon() ) );
147 item->setExpanded( true );
148 return item;
153 return 0;
156 void TopLevel::slotScan()
158 mTemplates = KGlobal::dirs()->findAllResources( "data", "kappfinder/apps/*.desktop", KStandardDirs::Recursive );
160 mAppCache.clear();
162 mFound = 0;
163 int count = mTemplates.count();
165 enableButton(User1, false ); //disable scan button
166 mProgress->setTextVisible( true );
167 mProgress->setRange( 0, count );
168 mProgress->setValue( 0 );
170 mListView->clear();
172 QStringList::Iterator it;
173 for ( it = mTemplates.begin(); it != mTemplates.end(); ++it ) {
174 // eye candy
175 mProgress->setValue( mProgress->value() + 1 );
177 QString desktopName = *it;
178 int i = desktopName.lastIndexOf('/');
179 desktopName = desktopName.mid(i+1);
180 i = desktopName.lastIndexOf('.');
181 if (i != -1)
182 desktopName = desktopName.left(i);
184 bool found;
185 found = KService::serviceByDesktopName(desktopName);
186 if (found)
187 continue;
189 found = KService::serviceByMenuId("kde4-"+desktopName+".desktop");
190 if (found)
191 continue;
193 found = KService::serviceByMenuId("gnome-"+desktopName+".desktop");
194 if (found)
195 continue;
197 KDesktopFile desktop( *it );
199 // copy over the desktop file, if exists
200 if ( scanDesktopFile( mAppCache, *it, mDestDir ) ) {
201 QString relPath = *it;
202 int pos = relPath.indexOf( "kappfinder/apps/" );
203 relPath = relPath.mid( pos + strlen( "kappfinder/apps/" ) );
204 relPath = relPath.left( relPath.lastIndexOf( '/' ) + 1 );
205 QStringList dirList = relPath.split( '/');
207 QTreeWidgetItem *dirItem = 0;
208 QString tmpRelPath = QString();
210 QStringList::Iterator tmpIt;
211 for ( tmpIt = dirList.begin(); tmpIt != dirList.end(); ++tmpIt ) {
212 dirItem = addGroupItem( dirItem, tmpRelPath, *tmpIt );
213 tmpRelPath += *tmpIt + '/';
216 mFound++;
218 QTreeWidgetItem *item;
219 if ( dirItem )
220 item = new QTreeWidgetItem( dirItem, QStringList() << desktop.readName() );
221 else
222 item = new QTreeWidgetItem( mListView, QStringList() << desktop.readName() );
224 item->setIcon( 0, KIcon( desktop.readIcon() ) );
225 item->setText( 1, desktop.readGenericName() );
226 item->setText( 2, desktop.desktopGroup().readPathEntry( "Exec", QString() ) );
227 if ( desktop.desktopGroup().readEntry( "X-StandardInstall" , false) )
228 item->setCheckState( 0, Qt::Checked );
229 else
230 item->setCheckState( 0, Qt::Unchecked );
232 AppLnkCache* cache = mAppCache.last();
233 if ( cache )
234 cache->item = item;
237 // update summary
238 QString sum( i18np( "Summary: %1 application found",
239 "Summary: %1 applications found", mFound ) );
240 mSummary->setText( sum );
243 // stop scanning
244 mProgress->setValue( 0 );
245 mProgress->setTextVisible( false );
247 enableButton(User1, true ); //enable scan button
249 if ( mFound > 0 ) {
250 enableButton(Apply, true );
251 enableButton(User2, true );
252 enableButton(User3, true );
256 void TopLevel::slotSelectAll()
258 AppLnkCache* cache;
259 Q_FOREACH( cache, mAppCache )
260 cache->item->setCheckState( 0, Qt::Checked );
263 void TopLevel::slotUnselectAll()
265 AppLnkCache* cache;
266 Q_FOREACH( cache, mAppCache )
267 cache->item->setCheckState( 0, Qt::Unchecked );
270 void TopLevel::slotCreate()
272 // copy template files
273 mAdded = 0;
274 createDesktopFiles( mAppCache, mAdded );
276 // decorate directories
277 decorateDirs( mDestDir );
279 KBuildSycocaProgressDialog::rebuildKSycoca(this);
281 QString message( i18np( "%1 application was added to the KDE menu system.",
282 "%1 applications were added to the KDE menu system.", mAdded ) );
283 KMessageBox::information( this, message, QString(), "ShowInformation" );
286 #include "toplevel.moc"