add more spacing
[personal-kdebase.git] / apps / kfind / kfwin.cpp
blobbab3024859b40bcae0784a5f71bf2f969c240617
1 /***********************************************************************
3 * Kfwin.cpp
5 **********************************************************************/
6 #include "kfwin.h"
8 #include "kfwin.moc"
10 #include <stdlib.h>
11 #include <stdio.h>
12 #include <pwd.h>
13 #include <grp.h>
14 #include <sys/types.h>
15 #include <unistd.h>
16 #include <errno.h>
17 #include <sys/stat.h>
18 #include <time.h>
20 #include <QtCore/QTextStream>
21 #include <QtCore/QFileInfo>
22 #include <QtCore/QDir>
23 #include <QtGui/QClipboard>
24 #include <QtGui/QPixmap>
25 #include <Qt3Support/Q3UriDrag>
26 #include <QtGui/QTextDocument>
27 #include <Qt3Support/Q3PtrList>
28 #include <QtCore/QDate>
30 #include <kfiledialog.h>
31 #include <klocale.h>
32 #include <kapplication.h>
33 #include <krun.h>
34 #include <kpropertiesdialog.h>
35 #include <kstandarddirs.h>
36 #include <kmessagebox.h>
37 #include <kmimetype.h>
38 #include <kglobal.h>
39 #include <kmenu.h>
40 #include <kio/netaccess.h>
41 #include <k3urldrag.h>
42 #include <kdebug.h>
43 #include <kiconloader.h>
45 template class Q3PtrList<KfFileLVI>;
47 // Permission strings
48 static const char* perm[4] = {
49 I18N_NOOP( "Read-write" ),
50 I18N_NOOP( "Read-only" ),
51 I18N_NOOP( "Write-only" ),
52 I18N_NOOP( "Inaccessible" ) };
53 #define RW 0
54 #define RO 1
55 #define WO 2
56 #define NA 3
58 KfFileLVI::KfFileLVI(KfindWindow* lv, const KFileItem &item, const QString& matchingLine)
59 : Q3ListViewItem(lv),
60 fileitem(item)
62 fileInfo = new QFileInfo(item.url().path());
64 QString size = KGlobal::locale()->formatNumber(item.size(), 0);
66 QString date = item.timeString(KFileItem::ModificationTime);
68 int perm_index;
69 if(fileInfo->isReadable())
70 perm_index = fileInfo->isWritable() ? RW : RO;
71 else
72 perm_index = fileInfo->isWritable() ? WO : NA;
74 // Fill the item with data
75 setText(0, item.url().fileName(KUrl::ObeyTrailingSlash));
76 setText(1, lv->reducedDir(item.url().directory(KUrl::AppendTrailingSlash)));
77 setText(2, size);
78 setText(3, date);
79 setText(4, i18n(perm[perm_index]));
80 setText(5, matchingLine);
82 // put the icon into the leftmost column
83 setPixmap(0, item.pixmap(16));
86 KfFileLVI::~KfFileLVI()
88 delete fileInfo;
91 QString KfFileLVI::key(int column, bool) const
93 switch (column) {
94 case 2:
95 // Returns size in bytes. Used for sorting
96 return QString().sprintf("%010ld", (long int)fileInfo->size());
97 case 3:
99 unsigned long l_time = fileitem.time(KFileItem::ModificationTime).toTime_t();
100 // Returns time in secs from 1/1/1970. Used for sorting
101 return QString().sprintf("%010lu", l_time);
105 return text(column);
108 KfindWindow::KfindWindow( QWidget *parent )
109 : K3ListView( parent )
110 ,m_baseDir()
111 ,m_menu(0)
113 setSelectionMode( Q3ListView::Extended );
114 setShowSortIndicator( true );
116 addColumn(i18n("Name"));
117 addColumn(i18n("In Subfolder"));
118 addColumn(i18n("Size"));
119 setColumnAlignment(2, Qt::AlignRight);
120 addColumn(i18n("Modified"));
121 setColumnAlignment(3, Qt::AlignRight);
122 addColumn(i18n("Permissions"));
123 setColumnAlignment(4, Qt::AlignRight);
125 addColumn(i18n("First Matching Line"));
126 setColumnAlignment(5, Qt::AlignLeft);
128 // Disable autoresize for all columns
129 // Resizing is done by resetColumns() function
130 for (int i = 0; i < 6; i++)
131 setColumnWidthMode(i, Manual);
133 resetColumns(true);
135 connect( this, SIGNAL(selectionChanged()),
136 this, SLOT( selectionHasChanged() ));
138 connect(this, SIGNAL(contextMenu(K3ListView *, Q3ListViewItem*,const QPoint&)),
139 this, SLOT(slotContextMenu(K3ListView *,Q3ListViewItem*,const QPoint&)));
141 connect(this, SIGNAL(executed(Q3ListViewItem*)),
142 this, SLOT(slotExecute(Q3ListViewItem*)));
143 setDragEnabled(true);
148 QString KfindWindow::reducedDir(const QString& fullDir)
150 if (fullDir.indexOf(m_baseDir)==0)
152 QString tmp=fullDir.mid(m_baseDir.length());
153 return tmp;
155 return fullDir;
158 void KfindWindow::beginSearch(const KUrl& baseUrl)
160 kDebug()<<QString("beginSearch in: %1").arg(baseUrl.path());
161 m_baseDir=baseUrl.path(KUrl::AddTrailingSlash);
162 haveSelection = false;
163 clear();
166 void KfindWindow::endSearch()
170 void KfindWindow::insertItem(const KFileItem &item, const QString& matchingLine)
172 new KfFileLVI(this, item, matchingLine);
175 // copy to clipboard aka X11 selection
176 void KfindWindow::copySelection()
178 Q3DragObject *drag_obj = dragObject();
180 if (drag_obj)
182 QClipboard *cb = kapp->clipboard();
183 cb->setData(drag_obj);
187 void KfindWindow::saveResults()
189 Q3ListViewItem *item;
191 KFileDialog *dlg = new KFileDialog(QString(), QString(), this);
192 dlg->setOperationMode (KFileDialog::Saving);
194 dlg->setCaption(i18n("Save Results As"));
196 QStringList list;
198 list << "text/plain" << "text/html";
200 dlg->setOperationMode(KFileDialog::Saving);
202 dlg->setMimeFilter(list, QString("text/plain"));
204 dlg->exec();
206 KUrl u = dlg->selectedUrl();
207 KMimeType::Ptr mimeType = dlg->currentFilterMimeType();
208 delete dlg;
210 if (!u.isValid() || !u.isLocalFile())
211 return;
213 QString filename = u.path();
215 QFile file(filename);
217 if ( !file.open(QIODevice::WriteOnly) )
218 KMessageBox::error(parentWidget(),
219 i18n("Unable to save results."));
220 else {
221 QTextStream stream( &file );
222 stream.setCodec( QTextCodec::codecForLocale() );
224 if ( mimeType->name() == "text/html") {
225 stream << QString::fromLatin1("<HTML><HEAD>\n"
226 "<!DOCTYPE %1>\n"
227 "<TITLE>%2</TITLE></HEAD>\n"
228 "<BODY><H1>%3</H1>"
229 "<DL><p>\n")
230 .arg(i18n("KFind Results File"))
231 .arg(i18n("KFind Results File"))
232 .arg(i18n("KFind Results File"));
234 item = firstChild();
235 while(item != NULL)
237 QString path=((KfFileLVI*)item)->fileitem.url().url();
238 QString pretty=Qt::escape(((KfFileLVI*)item)->fileitem.url().prettyUrl());
239 stream << QString::fromLatin1("<DT><A HREF=\"") << path
240 << QString::fromLatin1("\">") << pretty
241 << QString::fromLatin1("</A>\n");
243 item = item->nextSibling();
245 stream << QString::fromLatin1("</DL><P></BODY></HTML>\n");
247 else {
248 item = firstChild();
249 while(item != NULL)
251 QString path=((KfFileLVI*)item)->fileitem.url().url();
252 stream << path << endl;
253 item = item->nextSibling();
257 file.close();
258 KMessageBox::information(parentWidget(),
259 i18n("Results were saved to file\n")+
260 filename);
264 // This function is called when selection is changed (both selected/deselected)
265 // It notifies the parent about selection status and enables/disables menubar
266 void KfindWindow::selectionHasChanged()
268 emit resultSelected(true);
270 Q3ListViewItem *item = firstChild();
271 while(item != 0L)
273 if(isSelected(item)) {
274 emit resultSelected( true );
275 haveSelection = true;
276 return;
279 item = item->nextSibling();
282 haveSelection = false;
283 emit resultSelected(false);
286 void KfindWindow::deleteFiles()
288 QString tmp = i18np("Do you really want to delete the selected file?",
289 "Do you really want to delete the %1 selected files?",selectedItems().count());
290 if (KMessageBox::warningContinueCancel(parentWidget(), tmp, "", KStandardGuiItem::del()) == KMessageBox::Cancel)
291 return;
293 // Iterate on all selected elements
294 QList<Q3ListViewItem*> selected = selectedItems();
295 foreach ( Q3ListViewItem* listViewItem, selected ) {
296 KfFileLVI *item = static_cast<KfFileLVI*>(listViewItem);
297 KFileItem file = item->fileitem;
299 KIO::NetAccess::del(file.url(), this);
301 qDeleteAll(selected);
304 void KfindWindow::fileProperties()
306 // This dialog must be modal because it parent dialog is modal as well.
307 // Non-modal property dialog will hide behind the main window
308 KPropertiesDialog::showDialog( ((KfFileLVI *)currentItem())->fileitem, this, true );
311 void KfindWindow::openFolder()
313 KFileItem fileitem = ((KfFileLVI *)currentItem())->fileitem;
314 KUrl url = fileitem.url();
315 url.setFileName(QString());
317 (void) new KRun(url, this);
320 void KfindWindow::openBinding()
322 ((KfFileLVI*)currentItem())->fileitem.run();
325 void KfindWindow::slotExecute(Q3ListViewItem* item)
327 if (item==0)
328 return;
329 ((KfFileLVI*)item)->fileitem.run();
332 // Resizes K3ListView to occupy all visible space
333 void KfindWindow::resizeEvent(QResizeEvent *e)
335 K3ListView::resizeEvent(e);
336 resetColumns(false);
337 clipper()->repaint();
340 Q3DragObject * KfindWindow::dragObject()
342 KUrl::List uris;
343 QList<Q3ListViewItem*> selected = selectedItems();
345 // create a list of URIs from selection
346 foreach ( Q3ListViewItem* listViewItem, selected )
348 KfFileLVI *item = static_cast<KfFileLVI*>(listViewItem);
350 uris.append( item->fileitem.url() );
353 if ( uris.count() <= 0 )
354 return 0;
356 Q3UriDrag *ud = new K3URLDrag( uris, (QWidget *) this );
357 ud->setObjectName( "kfind uridrag" );
359 const QPixmap *pix = currentItem()->pixmap(0);
360 if ( pix && !pix->isNull() )
361 ud->setPixmap( *pix );
363 return ud;
366 void KfindWindow::resetColumns(bool init)
368 QFontMetrics fm = fontMetrics();
369 if (init)
371 setColumnWidth(2, qMax(fm.width(columnText(2)), fm.width("0000000")) + 15);
372 QString sampleDate =
373 KGlobal::locale()->formatDateTime(QDateTime::currentDateTime());
374 setColumnWidth(3, qMax(fm.width(columnText(3)), fm.width(sampleDate)) + 15);
375 setColumnWidth(4, qMax(fm.width(columnText(4)), fm.width(i18n(perm[RO]))) + 15);
376 setColumnWidth(5, qMax(fm.width(columnText(5)), fm.width("some text")) + 15);
379 int free_space = visibleWidth() -
380 columnWidth(2) - columnWidth(3) - columnWidth(4) - columnWidth(5);
382 // int name_w = qMin((int)(free_space*0.5), 150);
383 // int dir_w = free_space - name_w;
384 int name_w = qMax((int)(free_space*0.5), fm.width("some long filename"));
385 int dir_w = name_w;
387 setColumnWidth(0, name_w);
388 setColumnWidth(1, dir_w);
391 void KfindWindow::slotContextMenu(K3ListView *,Q3ListViewItem *item,const QPoint&p)
393 if (!item) return;
394 int count = selectedItems().count();
396 if (count == 0)
398 return;
401 if (m_menu==0)
402 m_menu = new KMenu(this);
403 else
404 m_menu->clear();
406 if (count == 1)
408 //menu = new KMenu(item->text(0), this);
409 m_menu->addTitle(item->text(0));
410 m_menu->addAction(SmallIcon("document-open"),i18nc("Menu item", "Open"), this, SLOT(openBinding()));
411 m_menu->addAction(SmallIcon("window-new"),i18n("Open Folder"), this, SLOT(openFolder()));
412 m_menu->addSeparator();
413 m_menu->addAction(SmallIcon("edit-copy"),i18n("Copy"), this, SLOT(copySelection()));
414 m_menu->addAction(SmallIcon("edit-delete"),i18n("Delete"), this, SLOT(deleteFiles()));
415 m_menu->addSeparator();
416 m_menu->addAction(i18n("Open With..."), this, SLOT(slotOpenWith()));
417 m_menu->addSeparator();
418 m_menu->addAction(i18n("Properties"), this, SLOT(fileProperties()));
420 else
422 m_menu->addTitle(i18n("Selected Files"));
423 m_menu->addAction(SmallIcon("edit-copy"),i18n("Copy"), this, SLOT(copySelection()));
424 m_menu->addAction(SmallIcon("edit-delete"),i18n("Delete"), this, SLOT(deleteFiles()));
426 m_menu->exec(p);
429 void KfindWindow::slotOpenWith()
431 KRun::displayOpenWithDialog( KUrl::split(((KfFileLVI*)currentItem())->fileitem.url()), window() );