Initial commit
[cuteexplorer] / filelistwidget.cpp
1 #include "filelistwidget.h"
2 #include <QHeaderView>
3 #include <QMessageBox>
4 #include <QInputDialog>
5 #include <QDesktopServices>
6 #include <QUrl>
7 #include <QProcess>
8 #include <QDBusInterface>
9 #ifdef Q_WS_MAEMO_5
10 #   include <hildon-mime.h>
11 #   include <dbus/dbus.h>
12 #endif
13 /*!
14 Widget that shows filesystemmodel and handles navigation
15 in directory tree and opening files with assosiated programs
16
17 @todo in symbian and windows filesystems navigating to "/" wont show drives
18   */
19 FileListWidget::FileListWidget(QWidget *parent) :
20     QListView(parent),
21     fileSystemModel( new QFileSystemModel(this)),
22     currentDir(QDir::homePath()),
23     mode_cut(false),
24     mode_copy(false),
25     select(false)
26 {
27     this->setModel(fileSystemModel);
28     this->setRootIndex(fileSystemModel->index(currentDir.absolutePath()));
29     fileSystemModel->setRootPath(currentDir.absolutePath());
30     fileSystemModel->setFilter(fileSystemModel->filter() | QDir::System);
31     connect(this, SIGNAL(activated(QModelIndex)), this, SLOT(handleItemActivation(QModelIndex)));
32
33 }
34
35 /**
36   Switches view mode
37   @param iconmode true shows iconview, false shows listview
38   */
39 void FileListWidget::actionSwitchMode(bool iconmode)
40 {
41     if(iconmode) {
42         this->setViewMode(QListView::IconMode);
43         this->setWordWrap(true);
44         this->setGridSize(QSize(80,80));
45     } else {
46         this->setViewMode(QListView::ListMode);
47         this->setWordWrap(false);
48         this->setGridSize(QSize());
49     }
50 }
51 /**
52   Switches show hidden
53   @param show true shows hidden files
54   */
55 void FileListWidget::actionShowHidden(bool show)
56 {
57     if(show)
58         fileSystemModel->setFilter(fileSystemModel->filter() | QDir::Hidden);
59     else
60         fileSystemModel->setFilter(fileSystemModel->filter() &~ QDir::Hidden);
61
62     this->clearSelection();
63 }
64
65 /**
66   Rename selected file
67   */
68 void FileListWidget::actionRename()
69 {
70     QFileInfo file = fileSystemModel->fileInfo(this->selectedIndexes().first());
71     QString newName = QInputDialog::getText(this, tr("Rename"), tr("New filename: "), QLineEdit::Normal, file.fileName());
72     if(newName != file.fileName())
73     {
74         if(QFile::rename(file.absoluteFilePath(), file.absolutePath()+"/"+newName))
75             return;
76         else
77             QMessageBox::critical(this,tr("Error!")
78                                   ,tr("Renaming file %1 failed")
79                                     .arg(file.fileName())
80                                   ,QMessageBox::Ok);
81     }
82 }
83 /**
84   Selected files will be moved when actionPaste is called
85   */
86 void FileListWidget::actionCut()
87 {
88     mode_cut = true;
89     mode_copy = false;
90     selectedFiles = this->selectedIndexes();
91 }
92 /**
93   Selected files will be copied when actionPaste is called
94   */
95 void FileListWidget::actionCopy()
96 {
97     mode_cut = false;
98     mode_copy = true;
99     selectedFiles = this->selectedIndexes();
100 }
101
102 /**
103   Moves or copies files that were selected when actionCut or actionCopy called
104   */
105 void FileListWidget::actionPaste()
106 {
107     fileSystemModel->setReadOnly(false);
108     if(mode_copy) {
109         //Copy files until filelist is empty or error occured
110         while(!selectedFiles.isEmpty()) {
111             if(QFile::copy(fileSystemModel->fileInfo(selectedFiles.first()).absoluteFilePath()
112                         , fileSystemModel->rootPath()+"/"+fileSystemModel->fileName(selectedFiles.first()))) {
113                 selectedFiles.removeFirst();
114             }
115             else if(QFile::copy(fileSystemModel->fileInfo(selectedFiles.first()).absoluteFilePath()
116                     , fileSystemModel->rootPath()+"/copy_"+fileSystemModel->fileName(selectedFiles.first()))) {
117                 selectedFiles.removeFirst();
118             } else {
119                 QMessageBox::critical(this,tr("Error!")
120                                       ,tr("Copying file %1 failed")
121                                         .arg(fileSystemModel->fileName(selectedFiles.first()))
122                                       ,QMessageBox::Ok);
123                 break;
124             }
125         }
126         if(selectedFiles.isEmpty())
127             mode_copy = false;
128     } else if(mode_cut) {
129         //Move files until filelist is empty or error occured
130         while(!selectedFiles.isEmpty()) {
131             if(QFile::rename(fileSystemModel->fileInfo(selectedFiles.first()).absoluteFilePath()
132                         , fileSystemModel->rootPath()+"/"+fileSystemModel->fileName(selectedFiles.first()))) {
133                     selectedFiles.removeFirst();
134             } else {
135                 QMessageBox::critical(this,tr("Error!")
136                                       ,tr("Moving file %1 failed")
137                                         .arg(fileSystemModel->fileName(selectedFiles.first()))
138                                       ,QMessageBox::Ok);
139                 break;
140             }
141         }
142         if(selectedFiles.isEmpty())
143             mode_cut = false;
144     }
145     fileSystemModel->setReadOnly(true);
146     this->clearSelection();
147 }
148
149 /**
150   Deletes selected files
151   */
152 void FileListWidget::actionDelete()
153 {
154     mode_cut = false;
155     mode_copy = false;
156     if(QMessageBox::Yes == QMessageBox::warning(this, tr("Deleting file")
157                             ,tr("You are about to delete %1 file(s).\nAre you sure you want to continue?")
158                                 .arg(this->selectedIndexes().count())
159                             , QMessageBox::Yes, QMessageBox::No)) {
160         fileSystemModel->setReadOnly(false);
161         selectedFiles = this->selectedIndexes();
162         //delete files until filelist empty or error occured
163         while(!selectedFiles.isEmpty()) {
164             if(fileSystemModel->remove(selectedFiles.first())) {
165                 selectedFiles.removeFirst();
166             } else {
167                 QMessageBox::critical(this,tr("Error!")
168                                       ,tr("Deleting file %1 failed")
169                                         .arg(fileSystemModel->fileName(selectedFiles.first()))
170                                       ,QMessageBox::Ok);
171                 break;
172             }
173         }
174         fileSystemModel->setReadOnly(true);
175         this->clearSelection();
176     }
177 }
178
179 /**
180   @return Current directory
181   */
182 QString FileListWidget::getPath()
183 {
184     return currentDir.absolutePath();
185 }
186
187 /**
188   Changes current directory
189   @param path directory to change to
190   */
191 void FileListWidget::changePath(QString path)
192 {
193     currentDir.cd(path);
194     QString newPath = currentDir.absolutePath();
195     fileSystemModel->setRootPath(newPath);
196     this->clearSelection();
197     this->setRootIndex(fileSystemModel->index(newPath));
198     emit pathChanged(newPath);
199 }
200
201 /**
202   Equivalent to changePath("..")
203   */
204 void FileListWidget::changePathUp()
205 {
206     changePath("..");
207 }
208
209 void FileListWidget::handleItemActivation(QModelIndex index)
210 {
211     if(!select) {
212         QFileInfo file = fileSystemModel->fileInfo(index);
213         if(file.isDir()) {
214             changePath(file.absoluteFilePath());
215         } else if(file.isExecutable()) {
216             // Make process
217             QProcess::startDetached(file.absoluteFilePath());
218         } else {
219 #ifdef Q_WS_MAEMO_5 // Uses native file opening method
220             DBusConnection* conn;
221             conn = dbus_bus_get(DBUS_BUS_SESSION, 0);
222             hildon_mime_open_file(conn, QUrl::fromLocalFile(file.absoluteFilePath()).toEncoded().constData());
223 #else
224             /*
225             Not working with maemo5.
226             Uses hildon_uri_open function from
227             libhildonmime which should work,
228             but all files opened in browser.
229             */
230             QDesktopServices::openUrl(QUrl::fromLocalFile(file.absoluteFilePath()));
231 #endif
232         }
233     }
234 }
235 /**
236   @param mode true activates file selection
237   */
238 void FileListWidget::setSelectMode(bool mode)
239 {
240     select = mode;
241 }
242
243 void FileListWidget::actionSendFiles()
244 {
245     if(!mode_copy) {
246         QMessageBox::information(this,
247                                  tr("Sending files"),
248                                  tr("To send files, select files you want to send and copy them."),
249                                  QMessageBox::Cancel);
250     } else {
251 #ifdef Q_WS_MAEMO_5
252         // Create list of file urls
253         QStringList files;
254         while(!selectedFiles.isEmpty()) {
255             files.append(QUrl::fromLocalFile(fileSystemModel->fileInfo(selectedFiles.first()).absoluteFilePath()).toString());
256             selectedFiles.removeFirst();
257         }
258
259         // Make dbuscall to send files
260         QDBusInterface interface("com.nokia.bt_ui", "/com/nokia/bt_ui", "com.nokia.bt_ui",QDBusConnection::systemBus());
261         interface.call("show_send_file_dlg", files);
262 #else
263         QMessageBox::information(this,
264                                  tr("Sending files"),
265                                  tr("Only in maemo5 for now"),
266                                  QMessageBox::Cancel);
267 #endif
268     }
269 }
270