1 /**************************************************************************
2 ** This file is part of LiteIDE
3 **
4 ** Copyright (c) 2011-2019 LiteIDE. All rights reserved.
5 **
6 ** This library is free software; you can redistribute it and/or
7 ** modify it under the terms of the GNU Lesser General Public
8 ** License as published by the Free Software Foundation; either
9 ** version 2.1 of the License, or (at your option) any later version.
10 **
11 ** This library is distributed in the hope that it will be useful,
12 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
13 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 ** Lesser General Public License for more details.
15 **
16 ** In addition, as a special exception,  that plugins developed for LiteIDE,
17 ** are allowed to remain closed sourced and can be distributed under any license .
18 ** These rights are included in the file LGPL_EXCEPTION.txt in this package.
19 **
20 **************************************************************************/
21 // Module: basefolderview.cpp
22 // Creator: visualfc <visualfc@gmail.com>
23 
24 #include "basefoldeview.h"
25 #include "liteenvapi/liteenvapi.h"
26 #include "terminalapi/terminalapi.h"
27 #include "fileutil/fileutil.h"
28 #include "folderdialog.h"
29 
30 #include <QTreeView>
31 #include <QMenu>
32 #include <QAction>
33 #include <QMessageBox>
34 #include <QProcess>
35 #include <QInputDialog>
36 #include <QLineEdit>
37 #include <QUrl>
38 #include <QToolBar>
39 #include <QFileSystemWatcher>
40 #include <QFileDialog>
41 #include <QHeaderView>
42 #include <QProcess>
43 #include <QProcessEnvironment>
44 #include <QDesktopServices>
45 #include <QApplication>
46 #include <QClipboard>
47 #include <QMimeData>
48 #include <QUrl>
49 #include <QFile>
50 #include <QDebug>
51 
52 #ifdef Q_OS_WIN
53 #include <windows.h>
54 //lite_memory_check_begin
55 #if defined(WIN32) && defined(_MSC_VER) &&  defined(_DEBUG)
56      #define _CRTDBG_MAP_ALLOC
57      #include <stdlib.h>
58      #include <crtdbg.h>
59      #define DEBUG_NEW new( _NORMAL_BLOCK, __FILE__, __LINE__ )
60      #define new DEBUG_NEW
61 #endif
62 //lite_memory_check_end
63 #endif
64 
BaseFolderView(LiteApi::IApplication * app,QWidget * parent)65 BaseFolderView::BaseFolderView(LiteApi::IApplication *app, QWidget *parent) :
66     SymbolTreeView(parent), m_liteApp(app)
67 {
68     this->setHeaderHidden(true);
69 #if QT_VERSION >= 0x050000
70     this->header()->setSectionResizeMode(QHeaderView::ResizeToContents);
71 #else
72     this->header()->setResizeMode(QHeaderView::ResizeToContents);
73 #endif
74     this->header()->setStretchLastSection(false);
75     this->setHorizontalScrollBarPolicy(Qt::ScrollBarAsNeeded);
76 
77     m_openBundleAct = new QAction(tr("Open Application"),this);
78     m_openInNewWindowAct = new QAction(tr("Open In New Window"),this);
79     m_openEditorAct = new QAction(tr("Open File"),this);
80     m_newFileAct = new QAction(tr("New File..."),this);
81     m_newFileWizardAct = new QAction(tr("New File Wizard..."),this);
82     m_renameFileAct = new QAction(tr("Rename File..."),this);
83     m_removeFileAct = new QAction(tr("Delete File"),this);
84 
85     m_newFolderAct = new QAction(tr("New Folder..."),this);
86     m_renameFolderAct = new QAction(tr("Rename Folder..."),this);
87     m_removeFolderAct = new QAction(tr("Delete Folder"),this);
88 
89 #if defined(Q_OS_WIN)
90     m_openExplorerAct = new QAction(tr("Show in Explorer"),this);
91 #elif defined(Q_OS_MAC)
92     m_openExplorerAct = new QAction(tr("Show in Finder"),this);
93 #else
94     m_openExplorerAct = new QAction(tr("Show Containing Folder"),this);
95 #endif
96 
97 #ifdef Q_OS_WIN
98     m_openShellAct = new QAction(tr("Open Command Prompt Here"),this);
99 #else
100     m_openShellAct = new QAction(tr("Open Terminal Here"),this);
101 #endif
102     m_openTerminalAct = new QAction(tr("Open in Integrated Terminal"),this);
103 
104     m_openFolderAct = new QAction(tr("Open Folder..."),this);
105     m_reloadFolderAct = new QAction(tr("Reload Folder"),this);
106     m_closeFolderAct = new QAction(tr("Close Folder"),this);
107 
108     m_closeAllFoldersAct = new QAction(tr("Close All Folders"),this);
109 
110     m_copyFileAct = new QAction(tr("Copy"),this);
111     m_pasteFileAct = new QAction(tr("Paste"),this);
112 
113     m_copyFullPathToClipboardAct = new QAction(tr("Copy Path"),this);
114 
115     m_moveToTrashAct = new QAction(tr("Move To Trash"),this);
116 
117     connect(m_openBundleAct,SIGNAL(triggered()),this,SLOT(openBundle()));
118     connect(m_openInNewWindowAct,SIGNAL(triggered()),this,SLOT(openInNewWindow()));
119     connect(m_openEditorAct,SIGNAL(triggered()),this,SLOT(openEditor()));
120     connect(m_newFileAct,SIGNAL(triggered()),this,SLOT(newFile()));
121     connect(m_newFileWizardAct,SIGNAL(triggered()),this,SLOT(newFileWizard()));
122     connect(m_renameFileAct,SIGNAL(triggered()),this,SLOT(renameFile()));
123     connect(m_removeFileAct,SIGNAL(triggered()),this,SLOT(removeFile()));
124     connect(m_newFolderAct,SIGNAL(triggered()),this,SLOT(newFolder()));
125     connect(m_renameFolderAct,SIGNAL(triggered()),this,SLOT(renameFolder()));
126     connect(m_removeFolderAct,SIGNAL(triggered()),this,SLOT(removeFolder()));
127     connect(m_openShellAct,SIGNAL(triggered()),this,SLOT(openShell()));
128     connect(m_openTerminalAct,SIGNAL(triggered()),this,SLOT(openTerminal()));
129     connect(m_openExplorerAct,SIGNAL(triggered()),this,SLOT(openExplorer()));
130     connect(m_openFolderAct,SIGNAL(triggered()),this,SLOT(openFolder()));
131     connect(m_closeFolderAct,SIGNAL(triggered()),this,SLOT(closeFolder()));
132     connect(m_reloadFolderAct,SIGNAL(triggered()),this,SLOT(reloadFolder()));
133     connect(m_closeAllFoldersAct,SIGNAL(triggered()),this,SLOT(closeAllFolders()));
134     connect(m_copyFileAct,SIGNAL(triggered()),this,SLOT(copyFile()));
135     connect(m_pasteFileAct,SIGNAL(triggered()),this,SLOT(pasteFile()));
136     connect(m_copyFullPathToClipboardAct,SIGNAL(triggered()),this,SLOT(copyFullPathToClipboard()));
137     connect(m_moveToTrashAct,SIGNAL(triggered()),this,SLOT(moveToTrash()));
138 
139     m_openWithMenu = 0;
140 }
141 
contextDir() const142 QDir BaseFolderView::contextDir() const
143 {
144     if (m_contextInfo.isDir()) {
145         return m_contextInfo.filePath();
146     }
147     return m_contextInfo.dir();
148 }
149 
contextFileInfo() const150 QFileInfo BaseFolderView::contextFileInfo() const
151 {
152     return m_contextInfo;
153 }
154 
canMoveToTrash() const155 bool BaseFolderView::canMoveToTrash() const
156 {
157     return FileUtil::hasTrash();
158 }
159 
openBundle()160 void BaseFolderView::openBundle()
161 {
162     if (m_contextInfo.isBundle()) {
163         if (QFileInfo("/usr/bin/open").exists()) {
164             QStringList args;
165             args << m_contextInfo.filePath();
166             QProcess::execute(QLatin1String("/usr/bin/open"), args);
167         }
168     }
169 }
170 
openInNewWindow()171 void BaseFolderView::openInNewWindow()
172 {
173     if (m_contextInfo.isDir()) {
174         m_liteApp->fileManager()->openFolderInNewWindow(m_contextInfo.filePath());
175     }
176 }
177 
openEditor()178 void BaseFolderView::openEditor()
179 {
180     if (m_contextInfo.isFile()) {
181         m_liteApp->fileManager()->openEditor(m_contextInfo.filePath());
182     }
183 }
184 
newFile()185 void BaseFolderView::newFile()
186 {
187     QDir dir = contextDir();
188 
189     CreateFileDialog dlg(m_liteApp->mainWindow());
190     dlg.setDirectory(dir.path());
191     if (dlg.exec() == QDialog::Rejected) {
192         return;
193     }
194     QString fileName = dlg.getFileName();
195     if (!fileName.isEmpty()) {
196         QString filePath = QFileInfo(dir,fileName).filePath();
197         if (QFile::exists(filePath)) {
198             QMessageBox::information(m_liteApp->mainWindow(),tr("Create File"),
199                                      tr("A file with that name already exists!"));
200         } else {
201             QFile file(filePath);
202             if (file.open(QIODevice::WriteOnly)) {
203                 file.close();
204                 if (dlg.isOpenEditor()) {
205                     m_liteApp->fileManager()->openEditor(filePath,true);
206                 }
207             } else {
208                 QMessageBox::information(m_liteApp->mainWindow(),tr("Create File"),
209                                          tr("Failed to create the file!"));
210             }
211         }
212     }
213 }
214 
newFileWizard()215 void BaseFolderView::newFileWizard()
216 {
217     QString filePath;
218     QString projPath;
219     QFileInfo info = m_contextInfo;
220     QDir dir = contextDir();
221     if (!info.isFile()) {
222         filePath = dir.absolutePath();
223         projPath = dir.absolutePath();
224     } else {
225         filePath = dir.absolutePath();
226         dir.cdUp();
227         projPath = dir.absolutePath();
228     }
229     m_liteApp->fileManager()->execFileWizard(projPath,filePath);
230 }
231 
renameFile()232 void BaseFolderView::renameFile()
233 {
234     QFileInfo info = m_contextInfo;
235     if (!info.isFile()) {
236         return;
237     }
238     QString fileName = QInputDialog::getText(m_liteApp->mainWindow(),
239                                              tr("Rename File"),tr("New Name:"),
240                                              QLineEdit::Normal,info.fileName());
241     if (!fileName.isEmpty() && fileName != info.fileName()) {
242         QDir dir = contextDir();
243 #ifdef Q_OS_WIN
244         if (!MoveFileW(info.filePath().toStdWString().c_str(),QFileInfo(dir,fileName).filePath().toStdWString().c_str())) {
245             QMessageBox::information(m_liteApp->mainWindow(),tr("Rename File"),
246                                      tr("Failed to rename the file!"));
247         }
248 #else
249         if (!QFile::rename(info.filePath(),QFileInfo(dir,fileName).filePath())) {
250             QMessageBox::information(m_liteApp->mainWindow(),tr("Rename File"),
251                                      tr("Failed to rename the file!"));
252         }
253 #endif
254     }
255 }
256 
removeFile()257 void BaseFolderView::removeFile()
258 {
259 
260 //    QFileInfo info = m_contextInfo;
261 //    if (!info.isFile()) {
262 //        return;
263 //    }
264 
265 //    int ret = QMessageBox::question(m_liteApp->mainWindow(),tr("Delete File"),
266 //                          tr("Are you sure that you want to permanently delete this file?")
267 //                          +"\n"+info.filePath(),
268 //                          QMessageBox::Yes | QMessageBox::No, QMessageBox::No);
269 //    if (ret == QMessageBox::Yes) {
270 //        if (!QFile::remove(info.filePath())) {
271 //            QMessageBox::information(m_liteApp->mainWindow(),tr("Delete File"),
272 //                                     tr("Failed to delete the file!"));
273 //        }
274 //    }
275 }
276 
newFolder()277 void BaseFolderView::newFolder()
278 {
279     QDir dir = contextDir();
280 
281     CreateDirDialog dlg(m_liteApp->mainWindow());
282     dlg.setDirectory(dir.path());
283     if (dlg.exec() == QDialog::Rejected) {
284         return;
285     }
286 
287     QString folderName = dlg.getDirName();
288     if (!folderName.isEmpty()) {
289         if (!dir.entryList(QStringList() << folderName,QDir::Dirs).isEmpty()) {
290             QMessageBox::information(m_liteApp->mainWindow(),tr("Create Folder"),
291                                      tr("A folder with that name already exists!"));
292         } else if (!dir.mkpath(folderName)) {
293             QMessageBox::information(m_liteApp->mainWindow(),tr("Create Folder"),
294                                      tr("Failed to create the folder!"));
295         }
296     }
297 }
298 
renameFolder()299 void BaseFolderView::renameFolder()
300 {
301     QFileInfo info = m_contextInfo;
302     if (!info.isDir()) {
303         return;
304     }
305 
306     QString folderName = QInputDialog::getText(m_liteApp->mainWindow(),
307                                                tr("Rename Folder"),tr("Folder Name"),
308                                                QLineEdit::Normal,info.fileName());
309     if (!folderName.isEmpty() && folderName != info.fileName()) {
310         QDir dir = contextDir();
311         dir.cdUp();
312 #ifdef Q_OS_WIN
313         QString _old = info.filePath();
314         QString _new = dir.path()+"/"+folderName;
315         if (!MoveFileW(_old.toStdWString().c_str(),_new.toStdWString().c_str())) {
316             QMessageBox::information(m_liteApp->mainWindow(),tr("Rename Folder"),
317                                      tr("Failed to rename the folder!"));
318         }
319 #else
320         if (!dir.rename(info.fileName(),folderName)) {
321             QMessageBox::information(m_liteApp->mainWindow(),tr("Rename Folder"),
322                                      tr("Failed to rename the folder!"));
323         }
324 #endif
325     }
326 }
327 
removeFolder()328 void BaseFolderView::removeFolder()
329 {
330     QFileInfo info = m_contextInfo;
331     if (!info.isDir()) {
332         return;
333     }
334 
335     int ret = QMessageBox::warning(m_liteApp->mainWindow(),tr("Delete Folder"),
336                           tr("Are you sure that you want to permanently delete this folder and all of its contents?")
337                           +"\n"+info.filePath(),
338                           QMessageBox::Yes | QMessageBox::No, QMessageBox::No);
339     if (ret == QMessageBox::Yes) {
340         QDir dir = info.dir();
341         if (!dir.rmdir(info.fileName())) {
342             QMessageBox::information(m_liteApp->mainWindow(),tr("Delete Folder"),
343                                      tr("Failed to delete the folder!"));
344         }
345     }
346 }
347 
openExplorer()348 void BaseFolderView::openExplorer()
349 {
350     FileUtil::openInExplorer(contextFileInfo().filePath());
351 }
352 
openTerminal()353 void BaseFolderView::openTerminal()
354 {
355     LiteApi::ITerminal *term = LiteApi::getTerminalManager(m_liteApp);
356     if (term) {
357         term->openDefaultTerminal(contextDir().path());
358     }
359 }
360 
openFolder()361 void BaseFolderView::openFolder()
362 {
363 
364 }
365 
closeFolder()366 void BaseFolderView::closeFolder()
367 {
368 }
369 
reloadFolder()370 void BaseFolderView::reloadFolder()
371 {
372 
373 }
374 
closeAllFolders()375 void BaseFolderView::closeAllFolders()
376 {
377 }
378 
copyFile()379 void BaseFolderView::copyFile()
380 {
381     QClipboard *clip = qApp->clipboard();
382     QMimeData *data = new QMimeData();
383 
384     QList<QUrl> urls;
385     QModelIndexList items = this->selectionCopyOrRemoveList();
386     if (!items.isEmpty()) {
387         foreach (QModelIndex item, items) {
388             urls << QUrl::fromLocalFile(this->fileInfo(item).filePath());
389         }
390     } else {
391         QFileInfo info = m_contextInfo;
392         urls << QUrl::fromLocalFile(info.filePath());
393     }
394     data->setUrls(urls);
395     clip->setMimeData(data);
396 }
397 
398 //static bool copy_dir(const QString &src, const QString &dest)
399 //{
400 //    QDir dir(src);
401 //    QDir destDir(dest);
402 //    foreach(QFileInfo info, dir.entryInfoList(QDir::Dirs|QDir::Files|QDir::NoDotAndDotDot)) {
403 //        if (info.isFile() && !info.isSymLink()) {
404 //            QFile::copy(info.filePath(), QFileInfo(destDir,info.fileName()).filePath());
405 //        } else if (info.isDir()) {
406 //            destDir.mkdir(info.fileName());
407 //            if (QFileInfo(destDir,info.fileName()).isDir()) {
408 //                copy_dir(info.filePath(),QFileInfo(destDir,info.fileName()).filePath());
409 //            }
410 //        }
411 //    }
412 //    return true;
413 //}
414 
copy_dir(const QString & src,const QString & dest_root,const QString & newName)415 bool BaseFolderView::copy_dir(const QString &src, const QString &dest_root, const QString &newName)
416 {
417     QDir dir(src);
418     QDir destDir(dest_root);
419     QString name = QFileInfo(src).fileName();
420     if (!newName.isEmpty()) {
421         name = newName;
422     }
423     destDir.mkdir(name);
424     if (!destDir.cd(name)) {
425         m_liteApp->appendLog("FolderView",QString("copy dir %1 false!").arg(src),true);
426         return false;
427     }
428     foreach(QFileInfo info, dir.entryInfoList(QDir::Dirs|QDir::Files|QDir::NoDotAndDotDot)) {
429         if (info.isFile() && !info.isSymLink()) {
430             bool b = QFile::copy(info.filePath(), QFileInfo(destDir,info.fileName()).filePath());
431             if (!b) {
432                 m_liteApp->appendLog("FolderView",QString("copy file %1=>%2 false!").arg(info.filePath()).arg(destDir.absolutePath()),true);
433             }
434         } else if (info.isDir()) {
435             copy_dir(info.filePath(),destDir.absolutePath(),"");
436         }
437     }
438     return true;
439 }
440 
pasteFile()441 void BaseFolderView::pasteFile()
442 {
443     QClipboard *clip = qApp->clipboard();
444     const QMimeData *data =  clip->mimeData();
445     if (!data) {
446         return;
447     }
448     if (!data->hasUrls()) {
449         return;
450     }
451     QDir dir = contextDir();
452     QString dstPath = QFileInfo(dir.absolutePath()).canonicalFilePath();
453     int allflag = 0;
454     foreach (QUrl url, data->urls()) {
455         if (!url.isLocalFile()) {
456             continue;
457         }
458         QString fileName = url.toLocalFile();
459         QFileInfo orginfo(QDir::cleanPath(fileName));
460         if (!orginfo.exists()) {
461             continue;
462         }
463 
464         if(orginfo.isDir() && orginfo.canonicalPath() != dstPath) {
465             QString chkPath = QDir::cleanPath(orginfo.canonicalFilePath());
466             if (chkPath == dstPath || dstPath.startsWith(chkPath+"/")) {
467                 m_liteApp->appendLog("FolderView",QString("You can't paste \"%1\" at this location because you can't paste an item into itselft.").arg(chkPath),true);
468                 continue;
469             }
470             if (QFileInfo(dir,orginfo.fileName()).exists()){
471                 if (chkPath.startsWith(dstPath+"/"+orginfo.fileName()+"/")) {
472                     m_liteApp->appendLog("FolderView",QString("The folder \"%1\" can't be replaced by an item it contains.").arg(chkPath),true);
473                     continue;
474                 }
475             }
476         }
477 
478 
479         QString dstName = orginfo.fileName();
480         QString dstFileName = orginfo.canonicalFilePath();
481         // check Duplicate
482         if (orginfo.canonicalPath() == dstPath) {
483             int num = 0;
484             while (QFileInfo(dir,dstName).exists()) {
485                 dstName = orginfo.baseName()+" copy";
486                 if (num > 0) {
487                     dstName += " "+QString::number(num);
488                 }
489                 if (!orginfo.completeSuffix().isEmpty()) {
490                     dstName += "."+orginfo.completeSuffix();
491                 }
492                 num++;
493             }
494             //upadte filename
495             dstFileName = QFileInfo(dir,dstName).filePath();
496         }
497 
498         // check over name
499         int flag = 0;
500         if (QFileInfo(dir,dstName).exists()) {
501             if (allflag == 0) {
502                 QMessageBox msgbox;
503                 msgbox.setIcon(QMessageBox::Question);
504                 msgbox.setInformativeText(QString(tr("An item \"%1\" already exists in this location. Do you want to replace it and move old item to trash?")).arg(dstName));
505                 QPushButton *stop = msgbox.addButton(tr("Stop"), QMessageBox::RejectRole);
506                 QPushButton *keepBoth = msgbox.addButton(tr("Keep Both"), QMessageBox::ActionRole);
507                 QPushButton *keepBothAll = msgbox.addButton(tr("Keep Both All"), QMessageBox::ActionRole);
508                 QPushButton *replace = msgbox.addButton(tr("Replace"), QMessageBox::ActionRole);
509                 QPushButton *replaceAll = msgbox.addButton(tr("Replace All"), QMessageBox::ActionRole);
510                 msgbox.setDefaultButton(stop);
511                 int ret = msgbox.exec();
512                 //stop button
513                 if (ret == QMessageBox::Rejected) {
514                     break;
515                 }
516                 QPushButton *btn = (QPushButton*)msgbox.clickedButton();
517                 if (btn == keepBoth) {
518                     flag = 1;
519                 } else if (btn == keepBothAll) {
520                     allflag = 1;
521                     flag = 1;
522                 } else if (btn == replace) {
523                     flag = 2;
524                 } else if (btn == replaceAll) {
525                     allflag = 2;
526                     flag = 2;
527                 }
528             } else {
529                 flag = allflag;
530             }
531         }
532         if (flag == 1) {
533             int num = 0;
534             while (QFileInfo(dir,dstName).exists()) {
535                 dstName = orginfo.baseName();
536                 if (num > 0) {
537                     dstName += " "+QString::number(num);
538                 }
539                 if (!orginfo.completeSuffix().isEmpty()) {
540                     dstName += "."+orginfo.completeSuffix();
541                 }
542                 num++;
543             }
544             //upadte filename
545             dstFileName = QFileInfo(dir,dstName).filePath();
546         } else if (flag == 2) {
547             FileUtil::moveToTrash(QFileInfo(dir,dstName).filePath());
548         }
549 
550         if (orginfo.isFile()) {
551             bool b = QFile::copy(fileName,QFileInfo(dir,dstName).filePath());
552             if (!b) {
553                 m_liteApp->appendLog("FolderView",QString("cannot paste file %1").arg(fileName),true);
554             }
555         } else if(orginfo.isDir()) {
556             copy_dir(orginfo.filePath(),dstPath,dstName);
557         }
558         qApp->processEvents();
559     }
560 }
561 
canPasteFile()562 bool BaseFolderView::canPasteFile()
563 {
564     QClipboard *clip = qApp->clipboard();
565     const QMimeData *data =  clip->mimeData();
566     if (!data) {
567         return false;
568     }
569     if (!data->hasUrls()) {
570         return false;
571     }
572     foreach (QUrl url, data->urls()) {
573         if (url.isLocalFile()) {
574             return true;
575         }
576     }
577     return false;
578 }
579 
copyFullPathToClipboard()580 void BaseFolderView::copyFullPathToClipboard()
581 {
582     QModelIndexList indexs = this->selectionCopyOrRemoveList();
583     QStringList fileList;
584     foreach (QModelIndex index, indexs) {
585         QFileInfo info = this->fileInfo(index);
586         fileList << info.filePath();
587     }
588     if (fileList.isEmpty()) {
589         return;
590     }
591     QClipboard *clip = qApp->clipboard();
592     clip->setText(fileList.join("\n"));
593 }
594 
moveToTrash()595 void BaseFolderView::moveToTrash()
596 {
597     QModelIndexList indexs = this->selectionCopyOrRemoveList();
598     QStringList fileList;
599     foreach (QModelIndex index, indexs) {
600         QFileInfo info = this->fileInfo(index);
601         fileList << info.filePath();
602     }
603     if (fileList.isEmpty()) {
604         return;
605     }
606     QString info;
607     int size = fileList.size();
608     if (size == 1) {
609         info = QString(tr("Are you sure that you want move to trash this item?"))
610                 +"\n"+fileList.join("\n");
611     } else if (size < 6) {
612         info = QString(tr("Are you sure that you want move to trash %1 items?")).arg(size)
613                 +"\n"+fileList.join("\n");
614     } else {
615         info = QString(tr("Are you sure that you want move to trash %1 items?")).arg(size);
616     }
617 
618     int ret = QMessageBox::question(m_liteApp->mainWindow(), tr("Move to Trash"),info,
619                           QMessageBox::Yes | QMessageBox::No, QMessageBox::No);
620     if (ret == QMessageBox::Yes) {
621         foreach (QString filename, fileList) {
622             if (!FileUtil::moveToTrash(filename)) {
623                 m_liteApp->appendLog("FolderView",QString("cannot move file to trash \"%1\"").arg(filename),true);
624             }
625         }
626     }
627 }
628 
openWithEditor()629 void BaseFolderView::openWithEditor()
630 {
631     QAction *act = (QAction*)sender();
632     if (!act) {
633         return;
634     }
635     QString id = act->data().toString();
636     if (id.isEmpty()) {
637         return;
638     }
639     if (!m_contextInfo.isFile()) {
640         return;
641     }
642     m_liteApp->fileManager()->openEditorByFactory(m_contextInfo.filePath(),id);
643 }
644 
openWithSystemEditor()645 void BaseFolderView::openWithSystemEditor()
646 {
647     if (!m_contextInfo.isFile()) {
648         return;
649     }
650     QUrl url = QUrl::fromLocalFile(m_contextInfo.filePath());
651     if (!url.isValid()) {
652         return;
653     }
654     QDesktopServices::openUrl(url);
655 }
656 
openWithMenu()657 QMenu *BaseFolderView::openWithMenu()
658 {
659     if (m_openWithMenu) {
660         return m_openWithMenu;
661     }
662     m_openWithMenu = new QMenu(tr("Open With"),this);
663     foreach(LiteApi::IEditorFactory *factory, m_liteApp->editorManager()->factoryList()) {
664         QAction *act = new QAction(factory->displayName(),this);
665         act->setData(factory->id());
666         m_openWithMenu->addAction(act);
667         connect(act,SIGNAL(triggered()),this,SLOT(openWithEditor()));
668     }
669     QAction *act = new QAction(tr("System Editor"),this);
670     m_openWithMenu->addAction(act);
671     connect(act,SIGNAL(triggered()),this,SLOT(openWithSystemEditor()));
672     return  m_openWithMenu;
673 }
674 
findIndexForContext(const QString &) const675 QModelIndex BaseFolderView::findIndexForContext(const QString &/*filePath*/) const
676 {
677     return QModelIndex();
678 }
679 
removeIndex(const QModelIndex & index)680 void BaseFolderView::removeIndex(const QModelIndex &index)
681 {
682 
683 }
684 
fileInfo(const QModelIndex & index) const685 QFileInfo BaseFolderView::fileInfo(const QModelIndex &index) const
686 {
687     return QFileInfo();
688 }
689 
selectionCopyOrRemoveList() const690 QModelIndexList BaseFolderView::selectionCopyOrRemoveList() const
691 {
692     return QModelIndexList();
693 }
694 
openShell()695 void BaseFolderView::openShell()
696 {
697     QProcessEnvironment env = LiteApi::getCurrentEnvironment(m_liteApp);
698     FileUtil::openInShell(env, contextDir().path());
699 }
700