OSDN Git Service

Model/View構造への変更。一旦コミット。
[gefu/Gefu.git] / folderpanel.cpp
1 #include "common.h"\r
2 #include "filetablemodel.h"\r
3 #include "folderpanel.h"\r
4 #include "mainwindow.h"\r
5 #include "ui_folderpanel.h"\r
6 #include <QCheckBox>\r
7 #include <QMessageBox>\r
8 #include <QKeyEvent>\r
9 #include <QDebug>\r
10 #include <QDateTime>\r
11 #include <QDesktopServices>\r
12 #include <QSettings>\r
13 #ifdef Q_OS_WIN32\r
14     #include <windows.h>\r
15 #endif\r
16 \r
17 QString FilesizeToString(quint64 size)\r
18 {\r
19     if (size >= 1024 * 1024 * 1024) {\r
20         return QString("%1GB").arg(int(10 * size / (1024 * 1024 * 1024)) / 10.0);\r
21     }\r
22     if (size >= 1024 * 1024) {\r
23         return QString("%1MB").arg(int(10 * size / (1024 * 1024)) / 10.0);\r
24     }\r
25     if (size >= 1024) {\r
26         return QString("%1KB").arg(int(10 * size / 1024) / 10.0);\r
27     }\r
28     return QString("%1B").arg(size);\r
29 }\r
30 \r
31 FolderPanel::FolderPanel(QWidget *parent) :\r
32     QWidget(parent),\r
33     ui(new Ui::FolderPanel),\r
34     m_dir(),\r
35     m_IconFactory(),\r
36     m_fsWatcher(new QFileSystemWatcher(this)),\r
37     m_bUpdating(false)\r
38 {\r
39     ui->setupUi(this);\r
40     ui->fileTable->setModel(new FileTableModel(this));\r
41 \r
42     // リサイズ時の動作を設定する\r
43     QHeaderView *header = ui->fileTable->horizontalHeader();\r
44     header->setSectionResizeMode(0, QHeaderView::ResizeToContents);\r
45     header->setSectionResizeMode(1, QHeaderView::Stretch);\r
46     header->setSectionResizeMode(2, QHeaderView::ResizeToContents);\r
47     header->setSectionResizeMode(3, QHeaderView::ResizeToContents);\r
48 }\r
49 \r
50 FolderPanel::~FolderPanel()\r
51 {\r
52     UninstallWatcher();\r
53     delete ui;\r
54 }\r
55 \r
56 QTableView* FolderPanel::fileTable()\r
57 {\r
58     return ui->fileTable;\r
59 }\r
60 \r
61 const QTableView *FolderPanel::fileTable() const\r
62 {\r
63     return ui->fileTable;\r
64 }\r
65 \r
66 void FolderPanel::setCurrentFolder(const QString &path)\r
67 {\r
68     QSettings settings;\r
69 \r
70     getMainWnd()->setStatusText(tr("ファイルリストを更新中..."));\r
71     QString curDir = m_dir.absolutePath();\r
72     m_dir.setPath(QDir::cleanPath(path));\r
73     m_dir.canonicalPath();\r
74 \r
75     QFileInfoList list = m_dir.entryInfoList();\r
76 \r
77     if (list.empty()) {\r
78         QMessageBox::critical(\r
79                     this,\r
80                     tr("エラー"),\r
81                     tr("フォルダが存在しないか利用できません。"));\r
82         m_dir.setPath(curDir);\r
83         ui->locationField->setText(curDir);\r
84         getMainWnd()->setStatusText(tr("レディ"));\r
85         return;\r
86     }\r
87 \r
88     // フォルダの変更監視\r
89     InstallWatcher();\r
90 \r
91     // QtはWindowsのシステムファイル属性をうまく判定できていないため、\r
92     // GetFileAttributes APIを使ってフィルタする\r
93     bool showSystem;\r
94     showSystem = settings.value(IniKey_ShowSystem, false).toBool();\r
95 \r
96     beginUpdate();\r
97 //    ui->fileTable->model()->removeRows(0, ui->fileTable->rowCount());\r
98 //    for (int i = 0; i < list.size(); i++) {\r
99 //        QFileInfo info = list.at(i);\r
100 //        if (info.fileName() == ".." && m_dir.isRoot()) {\r
101 //            continue;\r
102 //        }\r
103 \r
104 //#ifdef Q_OS_WIN32\r
105 //        DWORD dwFlags = ::GetFileAttributes(info.absoluteFilePath().toStdWString().c_str());\r
106 //        if (!showSystem && dwFlags != DWORD(-1) && (dwFlags & FILE_ATTRIBUTE_SYSTEM)) {\r
107 //            continue;\r
108 //        }\r
109 //#endif\r
110 \r
111 //        int row = ui->fileTable->rowCount();\r
112 //        ui->fileTable->insertRow(row);\r
113 \r
114 //        // ファイル名とアイコン\r
115 //        QTableWidgetItem *iName = new QTableWidgetItem(info.fileName());\r
116 //        iName->setFlags(iName->flags() ^ Qt::ItemIsEditable);\r
117 //        if (info.fileName() == "..") {\r
118 //            iName->setIcon(QIcon(":/images/Up.png"));\r
119 //        }\r
120 //        else {\r
121 //            iName->setIcon(m_IconFactory.icon(info));\r
122 //        }\r
123 //        ui->fileTable->setItem(row, 1, iName);\r
124 \r
125 //        // サイズ\r
126 //        QString str;\r
127 //        if (info.isDir()) {\r
128 //            str = tr("<DIR>");\r
129 //        }\r
130 //        else {\r
131 //            str = FilesizeToString(info.size());\r
132 //        }\r
133 //        QTableWidgetItem *iSize = new QTableWidgetItem(str);\r
134 //        iSize->setFlags(iSize->flags() ^ Qt::ItemIsEditable);\r
135 //        iSize->setTextAlignment(Qt::AlignRight | Qt::AlignVCenter);\r
136 //        ui->fileTable->setItem(row, 2, iSize);\r
137 \r
138 //        // 最終更新日時\r
139 //        QTableWidgetItem *iDateTime = new QTableWidgetItem(\r
140 //                    info.lastModified().toString("yy/MM/dd hh:mm"));\r
141 //        iDateTime->setFlags(iDateTime->flags() ^ Qt::ItemIsEditable);\r
142 //        ui->fileTable->setItem(row, 3, iDateTime);\r
143 \r
144 //        // シグナル処理の関係で、チェックボックスは最後に追加する\r
145 //        QTableWidgetItem *iCheck = new QTableWidgetItem(tr(""));\r
146 //        iCheck->setFlags(iCheck->flags() ^ Qt::ItemIsEditable);\r
147 //        if (info.fileName() != "..") {\r
148 //            iCheck->setFlags(iCheck->flags() | Qt::ItemIsUserCheckable);\r
149 //            iCheck->setCheckState(Qt::Unchecked);\r
150 //        }\r
151 //        ui->fileTable->setItem(row, 0, iCheck);\r
152 \r
153 //    }\r
154     ui->fileTable->selectRow(0);\r
155     ui->fileTable->resizeRowsToContents();\r
156 \r
157     ui->locationField->setText(m_dir.absolutePath());\r
158     getMainWnd()->setStatusText(tr("レディ"));\r
159     endUpdate();\r
160 }\r
161 \r
162 void FolderPanel::InstallWatcher()\r
163 {\r
164     UninstallWatcher();\r
165 \r
166     m_fsWatcher = new QFileSystemWatcher(this);\r
167     m_fsWatcher->addPath(m_dir.absolutePath());\r
168     connect(m_fsWatcher, SIGNAL(directoryChanged(QString)),\r
169             this, SLOT(on_directoryChanged(QString)));\r
170 }\r
171 \r
172 void FolderPanel::UninstallWatcher()\r
173 {\r
174     if (m_fsWatcher != NULL) {\r
175         delete m_fsWatcher;\r
176     }\r
177     m_fsWatcher = NULL;\r
178 }\r
179 \r
180 const QString FolderPanel::side() const\r
181 {\r
182     return ui->fileTable->side();\r
183 }\r
184 \r
185 void FolderPanel::setSide(const QString &side)\r
186 {\r
187     ui->fileTable->setSide(side);\r
188 \r
189     QSettings settings;\r
190     FileTableModel *model = new FileTableModel();\r
191     connect(model, SIGNAL(rootChanged(QString)),\r
192             ui->locationField, SLOT(setText(QString)));\r
193     connect(model, SIGNAL(stateChanged(int,int,quint64)),\r
194             this, SLOT(onStateChanged(int,int,quint64)));\r
195 \r
196     //>>>>> フィルタ初期化\r
197     model->setFilter(QDir::NoDot | QDir::AllDirs | QDir::Files);\r
198     if (settings.value(IniKey_ShowHidden, false).toBool()) {\r
199         model->setFilter(model->filter() | QDir::Hidden);\r
200     }\r
201     if (settings.value(IniKey_ShowSystem, false).toBool()) {\r
202         model->setFilter(model->filter() | QDir::System);\r
203     }\r
204     //>>>>> ソート順初期化\r
205     model->setSorting(QDir::Name);  // 0\r
206     int sortBy = settings.value(side + slash + IniKey_SortBy, SortByName).toInt();\r
207     switch (sortBy) {\r
208     case SortByDate:    model->setSorting(model->sorting() | QDir::Time); break;\r
209     case SortBySize:    model->setSorting(model->sorting() | QDir::Size); break;\r
210     case SortByType:    model->setSorting(model->sorting() | QDir::Type); break;\r
211     default:            model->setSorting(model->sorting() | QDir::Name); break;\r
212     }\r
213     // デフォルトだと文字列は昇順で、数値は降順…orz\r
214     int orderBy = settings.value(side + slash + IniKey_OrderBy, OrderByDesc).toInt();\r
215     if (((sortBy == SortByName || sortBy == SortByType) && orderBy == OrderByDesc) ||\r
216         ((sortBy == SortByDate || sortBy == SortBySize) && orderBy == OrderByAsc))\r
217     {\r
218         model->setSorting(model->sorting() | QDir::Reversed);\r
219     }\r
220     // フォルダの位置\r
221     switch (settings.value(side + slash + IniKey_PutDirs, PutDirsFirst).toInt()) {\r
222     case PutDirsFirst:  model->setSorting(model->sorting() | QDir::DirsFirst); break;\r
223     case PutDirsLast:   model->setSorting(model->sorting() | QDir::DirsLast); break;\r
224     }\r
225     // 大文字小文字の区別\r
226     if (settings.value(side + slash + IniKey_IgnoreCase, true).toBool()) {\r
227         model->setSorting(model->sorting() | QDir::IgnoreCase);\r
228     }\r
229     //>>>>> 監視フォルダ初期化\r
230     QString key = side + slash + IniKey_Dir;\r
231     QString path = settings.value(key, QDir::homePath()).toString();\r
232     model->setPath(path);\r
233 \r
234     ui->fileTable->setModel(model);\r
235     ui->fileTable->selectRow(0);\r
236     ui->fileTable->resizeColumnsToContents();\r
237     ui->fileTable->resizeRowsToContents();\r
238 }\r
239 \r
240 void FolderPanel::onStateChanged(int checkedFolders, int checkedFiles, quint64 totalSize)\r
241 {\r
242     QString msg = "";\r
243     if (checkedFolders > 0) {\r
244         msg += tr("%1個のフォルダ ").arg(checkedFolders);\r
245     }\r
246     if (checkedFiles > 0) {\r
247         msg += tr("%1個のファイル ").arg(checkedFiles);\r
248     }\r
249     if (msg.length() > 0) {\r
250         msg += "を選択 合計 ";\r
251         msg += FilesizeToString(totalSize);\r
252     }\r
253 \r
254     ui->label->setText(msg);\r
255 \r
256 }\r
257 \r
258 void FolderPanel::on_locationField_editingFinished()\r
259 {\r
260     ui->locationField->blockSignals(true);\r
261 \r
262     QString path = ui->locationField->text();\r
263     setCurrentFolder(path);\r
264 \r
265     ui->locationField->blockSignals(false);\r
266 }\r
267 \r
268 void FolderPanel::on_directoryChanged(QString)\r
269 {\r
270 //    int row = ui->fileTable->currentRow();\r
271 //    this->setCurrentFolder(m_dir.absolutePath());\r
272 //    if (row >= ui->fileTable->rowCount()) {\r
273 //        row = ui->fileTable->rowCount() - 1;\r
274 //    }\r
275 //    ui->fileTable->selectRow(row);\r
276 }\r
277 \r
278 //void FolderPanel::on_fileTable_itemSelectionChanged()\r
279 //{\r
280 //    if (isUpdating()) {\r
281 //        return;\r
282 //    }\r
283 \r
284 //    int row = ui->fileTable->currentRow();\r
285 //    if (0 <= row && row < ui->fileTable->rowCount()) {\r
286 //        getMainWnd()->setStatusText(ui->fileTable->item(row, 1)->text());\r
287 //    }\r
288 //}\r