OSDN Git Service

Ver0.26
[gefu/Gefu.git] / folderview_private.cpp
1 #include "foldermodel.h"
2 #include "folderview_private.h"
3
4 #include <QDebug>
5 #include <QDrag>
6 #include <QDragEnterEvent>
7 #include <QEvent>
8 #include <QMenu>
9 #include <QMimeData>
10
11 ///////////////////////////////////////////////////////////////////////////////
12 /// \brief FolderView_Private::FolderView_Private
13 /// \param parent   親オブジェクト
14 ///
15 /// コンストラクタ
16 ///
17 FolderView_Private::FolderView_Private(QAbstractItemView *parent) :
18     QObject(parent),
19     m_view(parent),
20     m_dragStartPos(),
21     m_dragging(false),
22     m_saveRow(0),
23     m_savePath(),
24     m_saveName()
25 {
26     m_view->setDragEnabled(true);
27     m_view->setAcceptDrops(true);
28     m_view->setDropIndicatorShown(true);
29     m_view->setContextMenuPolicy(Qt::DefaultContextMenu);
30 }
31
32 ///////////////////////////////////////////////////////////////////////////////
33 /// \brief FolderView_Private::onDragEnter
34 /// \param obj  イベントが発生したオブジェクト
35 /// \param e    ドラッグエンターイベントオブジェクト
36 /// \return 処理した場合はtrueを返します。
37 ///
38 bool FolderView_Private::onDragEnter(QObject *obj, QDragEnterEvent *e)
39 {
40     Q_UNUSED(obj);
41
42     if (e->mimeData()->hasUrls()) {
43         e->acceptProposedAction();
44         return true;
45     }
46     return false;
47 }
48
49 ///////////////////////////////////////////////////////////////////////////////
50 /// \brief FolderView_Private::onDrop
51 /// \param obj  イベントが発生したオブジェクト
52 /// \param e    ドロップイベントオブジェクト
53 /// \return 処理した場合はtrueを返します。
54 ///
55 bool FolderView_Private::onDrop(QObject *obj, QDropEvent *e)
56 {
57     Q_UNUSED(obj);
58
59     if (m_dragging) {
60         // 自分自身へのドロップなら何もしない
61         return true;
62     }
63
64     QStringList list;
65     foreach (const QUrl &url, e->mimeData()->urls()) {
66         QString path = QFileInfo(url.toLocalFile()).canonicalFilePath();
67         if (!path.isEmpty()) {
68             list << path;
69         }
70         else {
71             qDebug() << "drop path is empty." << url;
72         }
73     }
74
75     if (list.isEmpty()) {
76         // ローカルファイルのドロップでなければ何もしない
77         return true;
78     }
79
80     e->acceptProposedAction();
81
82     QMenu menu(m_view);
83     QAction *actCopy = menu.addAction(tr("コピー"));
84     QAction *actMove = menu.addAction(tr("移動"));
85     menu.addSeparator();
86     menu.addAction(tr("キャンセル"));
87
88     QAction *selected = menu.exec(m_view->mapToGlobal(e->pos()));
89     FolderModel *model = static_cast<FolderModel*>(m_view->model());
90     if (selected == actMove) {
91         emit moveItems(list, model->rootPath());
92     }
93     else if (selected == actCopy) {
94         emit copyItems(list, model->rootPath());
95     }
96     return true;
97 }
98
99 ///////////////////////////////////////////////////////////////////////////////
100 /// \brief FolderView_Private::onMouseMove
101 /// \param obj  イベントが発生したオブジェクト
102 /// \param e    マウスイベントオブジェクト
103 /// \return 処理した場合はtrueを返します。
104 ///
105 bool FolderView_Private::onMouseMove(QObject *obj, QMouseEvent *e)
106 {
107     Q_UNUSED(obj);
108
109     if (!(e->buttons() & Qt::LeftButton) && !(e->buttons() & Qt::RightButton))
110     {
111         return false;
112     }
113
114     if (m_dragStartPos.isNull() ||
115         (e->pos() - m_dragStartPos).manhattanLength() < 5)
116     {
117         return false;
118     }
119
120     FolderModel *model = static_cast<FolderModel*>(m_view->model());
121     QFileInfoList list = model->markedItems();
122     if (list.isEmpty()) {
123         list << model->fileInfo(m_view->currentIndex());
124     }
125     if (list.size() == 1 && list[0].fileName() == "..") {
126         return false;
127     }
128
129     QList<QUrl> urls;
130     foreach (const QFileInfo &info, list) {
131         urls << QUrl::fromLocalFile(info.absoluteFilePath());
132     }
133
134     QDrag *drag = new QDrag(this);
135     QMimeData *mimeData = new QMimeData;
136     mimeData->setUrls(urls);
137     drag->setMimeData(mimeData);
138
139     m_dragging = true;
140     drag->exec(Qt::CopyAction);
141     m_dragging = false;
142     m_dragStartPos = QPoint();
143
144     return true;
145 }
146
147 ///////////////////////////////////////////////////////////////////////////////
148 /// \brief FolderView_Private::onMousePress
149 /// \param obj  イベントが発生したオブジェクト
150 /// \param e    マウスイベントオブジェクト
151 /// \return 処理した場合はtrueを返します。
152 ///
153 bool FolderView_Private::onMousePress(QObject *obj, QMouseEvent *e)
154 {
155     Q_UNUSED(obj);
156
157     m_dragStartPos = QPoint();
158     if ((e->buttons() & Qt::LeftButton) || (e->buttons() & Qt::RightButton))
159     {
160         FolderModel *model = static_cast<FolderModel*>(m_view->model());
161         QModelIndex index = m_view->indexAt(e->pos());
162         if (index.isValid() && model->fileName(index) != "..") {
163             m_dragStartPos = e->pos();
164         }
165     }
166
167     // 本来のイベント処理も行う
168     return false;
169 }
170
171 ///////////////////////////////////////////////////////////////////////////////
172 /// \brief FolderView_Private::model_PostReset
173 ///
174 /// モデルリセット後の処理
175 ///
176 void FolderView_Private::model_PostReset()
177 {
178     FolderModel *model = static_cast<FolderModel*>(sender());
179
180     // フォルダが変わった場合は先頭行を選択する
181     if (m_savePath != model->rootPath()) {
182         m_view->setCurrentIndex(model->index(0, 0));
183         return;
184     }
185
186     // 保存した名前と同名アイテムが見つかれば、再選択する
187     for (int row = 0; row < model->rowCount(); row++) {
188         QModelIndex index = model->index(row, 0);
189         if (model->fileName(index) == m_saveName) {
190             m_view->setCurrentIndex(index);
191             return;
192         }
193     }
194
195     // 同名アイテムが見つからなければ、行を維持する
196     if (m_saveRow >= model->rowCount()) {
197         m_saveRow = model->rowCount() - 1;
198     }
199     m_view->setCurrentIndex(model->index(m_saveRow, 1));
200 }
201
202 ///////////////////////////////////////////////////////////////////////////////
203 /// \brief FolderView_Private::model_PreReset
204 ///
205 /// モデルリセット前の処理
206 ///
207 void FolderView_Private::model_PreReset()
208 {
209     // 現在行と名前を保存しておく
210     if (m_view->model() && m_view->currentIndex().isValid()) {
211         FolderModel *model = static_cast<FolderModel*>(m_view->model());
212         m_saveRow = m_view->currentIndex().row();
213         m_saveName = model->fileName(m_view->currentIndex());
214         m_savePath = model->rootPath();
215     }
216     else {
217         m_saveRow = 0;
218         m_saveName = QString::null;
219         m_savePath = QString::null;
220     }
221 }
222
223 ///////////////////////////////////////////////////////////////////////////////
224 /// \brief FolderView_Private::eventFilter
225 /// \param obj  イベントが発生したオブジェクト
226 /// \param e    イベントオブジェクト
227 /// \return 処理した場合はtrueを返します。
228 ///
229 bool FolderView_Private::eventFilter(QObject *obj, QEvent *e)
230 {
231     if (e->type() == QEvent::MouseButtonPress) {
232         return onMousePress(obj, static_cast<QMouseEvent*>(e));
233     }
234     else if (e->type() == QEvent::MouseMove) {
235         return onMouseMove(obj, static_cast<QMouseEvent*>(e));
236     }
237     else if (e->type() == QEvent::DragEnter) {
238         return onDragEnter(obj, static_cast<QDragEnterEvent*>(e));
239     }
240     else if (e->type() == QEvent::Drop) {
241         return onDrop(obj, static_cast<QDropEvent*>(e));
242     }
243
244     return false;
245 }