OSDN Git Service

Ver0.13
[gefu/Gefu.git] / folderview.cpp
1 #include "common.h"
2 #include "folderview.h"
3
4 #include <QDebug>
5 #include <QHeaderView>
6 #include <QKeyEvent>
7 #include <QSettings>
8 #include <QMimeData>
9 #include <QApplication>
10 #include <QDrag>
11 #include <QMenu>
12
13 QString FilesizeToString(quint64 size)
14 {
15     if (size >= 1024 * 1024 * 1024) {
16         return QString("%1GB").arg(int(10 * size / (1024 * 1024 * 1024)) / 10);
17     }
18     if (size >= 1024 * 1024) {
19         return QString("%1MB").arg(int(10 * size / (1024 * 1024)) / 10);
20     }
21     if (size >= 1024) {
22         return QString("%1KB").arg(int(10 * size / (1024)) / 10);
23     }
24     return QString("%1B").arg(size);
25 }
26
27 FolderView::FolderView(QWidget *parent) :
28     QTableView(parent),
29     m_model(),
30     m_dragStartPos(),
31     m_dragging(false)
32 {
33     setModel(&m_model);
34     connect(&m_model, SIGNAL(dataChanged(QModelIndex,QModelIndex)), this, SLOT(dataChanged(QModelIndex,QModelIndex)));
35
36     setDragEnabled(true);
37     setAcceptDrops(true);
38     setDropIndicatorShown(true);
39
40     setContextMenuPolicy(Qt::DefaultContextMenu);
41 }
42
43 QString FolderView::side() const
44 {
45     if (this->objectName() == "folderView1") {
46         return QString("Left");
47     }
48     else {
49         Q_ASSERT(this->objectName() == "folderView2");
50         return QString("Right");
51     }
52 }
53
54 void FolderView::initialize()
55 {
56     qDebug() << side() << "initialize";
57
58     setColumnWidth(0, 30);
59
60     QHeaderView *header;
61     // 列のリサイズモードを設定する
62     header = horizontalHeader();
63     header->setSectionResizeMode(QHeaderView::ResizeToContents);
64     header->setSectionResizeMode(0, QHeaderView::Fixed);
65     header->setSectionResizeMode(1, QHeaderView::Stretch);
66
67     // 前回終了時のパスを開く
68     QSettings settings;
69     setPath(settings.value(side() + slash + IniKey_Dir).toString(), true);
70
71     // 色とフォントを設定する
72     updateAppearance();
73 }
74
75 void FolderView::updateAppearance()
76 {
77     qDebug() << side() << "updateAppearance";
78     m_model.updateAppearance();
79
80     QSettings settings;
81     QPalette pal = palette();
82     pal.setColor(QPalette::Base, settings.value(IniKey_ViewColorBgNormal).value<QColor>());
83     setPalette(pal);
84
85     // 行の高さを設定する
86     QHeaderView *header = verticalHeader();
87     header->setDefaultSectionSize(QFontMetrics(m_model.font()).height() * 1.5);
88
89     repaint();
90 }
91
92 void FolderView::refresh()
93 {
94     qDebug() << side() << "refresh";
95
96     int row = currentIndex().row();
97
98     setPath(m_model.absolutePath(), false);
99
100     if (row < 0) {
101         row = 0;
102     }
103     else if (row >= m_model.rowCount()) {
104         row = m_model.rowCount() - 1;
105     }
106     setCurrentIndex(m_model.index(row, 0));
107     selectRow(row);
108 }
109
110 void FolderView::searchItem(const QString &text)
111 {
112     qDebug() << "FolderView::searchItem" << text;
113
114     for (int row = 0; row < m_model.rowCount(); row++) {
115         QModelIndex index = m_model.index(row, 0);
116         QString name = m_model.fileInfo(index).fileName().toLower();
117         if (name.indexOf(text.toLower()) != -1) {
118             setCurrentIndex(index);
119             emit itemFound();
120             return;
121         }
122     }
123
124     emit itemNotFound();
125 }
126
127 void FolderView::searchNext(const QString &text)
128 {
129     qDebug() << "FolderView::searchNext" << text;
130
131     for (int row = currentIndex().row() + 1; row < m_model.rowCount(); row++) {
132         QModelIndex index = m_model.index(row, 0);
133         QString name = m_model.fileInfo(index).fileName().toLower();
134         if (name.indexOf(text.toLower()) != -1) {
135             setCurrentIndex(index);
136             emit itemFound();
137             return;
138         }
139     }
140
141     emit itemNotFound();
142 }
143
144 void FolderView::searchPrev(const QString &text)
145 {
146     qDebug() << side() << "searchPrev" << text;
147
148     for (int row = currentIndex().row() - 1; row >= 0; row--) {
149         QModelIndex index = m_model.index(row, 0);
150         QString name = m_model.fileInfo(index).fileName().toLower();
151         if (name.indexOf(text.toLower()) != -1) {
152             setCurrentIndex(index);
153             emit itemFound();
154             return;
155         }
156     }
157
158     emit itemNotFound();
159 }
160
161 void FolderView::setCheckStateAll(bool checked)
162 {
163     qDebug() << side() << "markAll();";
164
165     QModelIndex current = currentIndex();
166
167     setUpdatesEnabled(false);
168     m_model.setCheckStateAll(checked ? Qt::Checked : Qt::Unchecked);
169     setUpdatesEnabled(true);
170
171     setCurrentIndex(current);
172 }
173
174 void FolderView::setCheckStateAllFiles()
175 {
176     qDebug() << side() << "markAllFiles();";
177
178     QModelIndex current = currentIndex();
179
180     setUpdatesEnabled(false);
181     for (int n = 0; n < m_model.rowCount(); n++) {
182         QModelIndex index = m_model.index(n, 0);
183         QFileInfo info = m_model.fileInfo(index);
184         if (info.isDir()) {
185             m_model.setCheckState(index, Qt::Unchecked);
186         }
187         else {
188             m_model.setCheckState(index, Qt::Checked);
189         }
190     }
191     setUpdatesEnabled(true);
192
193     setCurrentIndex(current);
194 }
195
196 void FolderView::invertCheckState()
197 {
198     qDebug() << side() << "invertCheckState();";
199
200     QModelIndex current = currentIndex();
201
202     setUpdatesEnabled(false);
203     for (int n = 0; n < m_model.rowCount(); n++) {
204         QModelIndex index = m_model.index(n, 0);
205         if (m_model.checkState(index) == Qt::Checked) {
206             m_model.setCheckState(index, Qt::Unchecked);
207         }
208         else {
209             m_model.setCheckState(index, Qt::Checked);
210         }
211     }
212     setUpdatesEnabled(true);
213
214     setCurrentIndex(current);
215 }
216
217 void FolderView::toggleCheckState(const QModelIndex &index)
218 {
219     QFileInfo info = m_model.fileInfo(index);
220     if (info.fileName() != "..") {
221         if (m_model.checkState(index) == Qt::Checked) {
222             m_model.setCheckState(index, Qt::Unchecked);
223         }
224         else {
225             m_model.setCheckState(index, Qt::Checked);
226         }
227     }
228     // 最終行でなければ、次のアイテムに移動する
229     if (index.row() == m_model.rowCount() - 1) {
230         setCurrentIndex(index);
231     }
232     else if (index.row() < m_model.rowCount() - 1) {
233         setCurrentIndex(m_model.index(index.row() + 1, 1));
234     }
235 }
236
237 bool FolderView::historyBack()
238 {
239     if (!m_history.isBegin()) {
240         setPath(m_history.back(), false);
241         return true;
242     }
243     return false;
244 }
245
246 bool FolderView::historyForward()
247 {
248     if (!m_history.isEnd()) {
249         setPath(m_history.forward(), false);
250         return true;
251     }
252     return false;
253 }
254
255 QFileInfo FolderView::currentItem() const
256 {
257     qDebug() << "FolderView::currentItem";
258
259     Q_ASSERT(currentIndex().isValid());
260
261     return m_model.fileInfo(currentIndex());
262 }
263
264 QFileInfoList FolderView::checkedItems() const
265 {
266     qDebug() << side() << "checkedItems()";
267
268     return m_model.checkedItems();
269 }
270
271 QFileInfoList FolderView::selectedItems() const
272 {
273     qDebug() << side() << "selectedItems";
274
275     // マークされているアイテムを取得する
276     QFileInfoList list = m_model.checkedItems();
277
278     // 一つもマークされていなければ、カーソル位置のアイテムを取得する
279     if (list.isEmpty()) {
280         list << currentItem();
281     }
282
283     return list;
284 }
285
286 void FolderView::setPath(const QString &path, bool addHistory)
287 {
288     qDebug() << side() << "setPath" << path << addHistory;
289
290     Q_ASSERT(QFileInfo(path).isDir());
291
292     emit retrieveStarted(path);
293
294     setUpdatesEnabled(false);
295     m_model.setPath(path);
296     setCurrentIndex(m_model.index(0, 0));
297     setUpdatesEnabled(true);
298
299     if (addHistory) {
300         m_history.add(path);
301     }
302
303     emit retrieveFinished();
304 }
305
306 void FolderView::setFilter(QDir::Filters filter, bool enable)
307 {
308     qDebug() << side() << "setFilter" << enable;
309
310     if (enable) {
311         m_model.setFilter(m_model.filter() | filter);
312     }
313     else {
314         m_model.setFilter(m_model.filter() ^ filter);
315     }
316 }
317
318 void FolderView::setHistoryIndexAt(int index)
319 {
320     m_history.setAt(index);
321     setPath(m_history.current(), false);
322 }
323
324 void FolderView::setNameFilters(const QStringList &list)
325 {
326     m_model.setNameFilters(list);
327     refresh();
328 }
329
330 void FolderView::setSorting(QDir::SortFlags flags)
331 {
332     m_model.setSorting(flags);
333     refresh();
334 }
335
336 void FolderView::keyPressEvent(QKeyEvent *event)
337 {
338     qDebug() << side() << "keyPressEvent";
339
340     emit keyPressed(event);
341
342     if (!event->isAccepted()) {
343         QTableView::keyPressEvent(event);
344     }
345     else {
346         qDebug() << "KeyEvent accepted.";
347     }
348 }
349
350 void FolderView::dataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight, const QVector<int> &roles)
351 {
352     emit dataChanged();
353
354     QTableView::dataChanged(topLeft, bottomRight, roles);
355 }
356
357 void FolderView::currentChanged(const QModelIndex &current, const QModelIndex &previous)
358 {
359     emit currentChanged(m_model.fileInfo(current));
360
361     QTableView::currentChanged(current, previous);
362 }
363
364 void FolderView::mousePressEvent(QMouseEvent *event)
365 {
366     if ((event->buttons() & Qt::LeftButton) || (event->buttons() & Qt::RightButton))
367     {
368         m_dragStartPos = event->pos();
369     }
370
371     QTableView::mousePressEvent(event);
372 }
373
374 void FolderView::mouseMoveEvent(QMouseEvent *event)
375 {
376     if (!(event->buttons() & Qt::LeftButton) &&
377             !(event->buttons() & Qt::RightButton))
378     {
379         QTableView::mouseMoveEvent(event);
380         return;
381     }
382     if ((event->pos() - m_dragStartPos).manhattanLength()
383             < QApplication::startDragDistance())
384     {
385         QTableView::mouseMoveEvent(event);
386         return;
387     }
388
389     QFileInfoList list = selectedItems();
390     if (list.isEmpty()) {
391         QTableView::mousePressEvent(event);
392         return;
393     }
394
395     QList<QUrl> urls;
396     foreach (const QFileInfo &info, list) {
397         urls << QUrl::fromLocalFile(info.absoluteFilePath());
398     }
399
400     QDrag *drag = new QDrag(this);
401     QMimeData *mimeData = new QMimeData;
402     mimeData->setUrls(urls);
403     drag->setMimeData(mimeData);
404
405     m_dragging = true;
406     if (event->buttons() & Qt::RightButton) {
407         drag->exec(Qt::CopyAction | Qt::MoveAction);
408     }
409     else {
410         drag->exec(Qt::CopyAction);
411     }
412     m_dragging = false;
413 }
414
415 void FolderView::dragEnterEvent(QDragEnterEvent *event)
416 {
417     if (event->mimeData()->hasUrls()) {
418         event->acceptProposedAction();
419         return;
420     }
421
422     QTableView::dragEnterEvent(event);
423 }
424
425 void FolderView::dropEvent(QDropEvent *event)
426 {
427     qDebug() << side() << "dropEvent();";
428
429     if (m_dragging) {
430         event->ignore();
431         return;
432     }
433
434     QFileInfoList list;
435     foreach (const QUrl &url, event->mimeData()->urls()) {
436         QString path = QFileInfo(url.toLocalFile()).canonicalFilePath();
437         if (!path.isEmpty()) {
438             list << path;
439         }
440         else {
441             qDebug() << "path is empty." << url;
442         }
443     }
444
445     if (list.isEmpty()) {
446         event->ignore();
447         return;
448     }
449
450     event->acceptProposedAction();
451
452     emit dropAccepted(list);
453 }
454
455
456 void FolderView::contextMenuEvent(QContextMenuEvent *event)
457 {
458     qDebug() << side() << "contextMenuEvent();";
459
460     emit requestContextMenu(event);
461 }