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: filesystemwidget.cpp
22 // Creator: visualfc <visualfc@gmail.com>
23 
24 #include "filesystemwidget.h"
25 #include "liteenvapi/liteenvapi.h"
26 #include "litebuildapi/litebuildapi.h"
27 #include "golangdocapi/golangdocapi.h"
28 #include "fileutil/fileutil.h"
29 #include "../folderview/folderdialog.h"
30 
31 #include <QTreeView>
32 #include <QVBoxLayout>
33 #include <QHBoxLayout>
34 #include <QPushButton>
35 #include <QMenu>
36 #include <QAction>
37 #include <QMessageBox>
38 #include <QDesktopServices>
39 #include <QProcess>
40 #include <QInputDialog>
41 #include <QLineEdit>
42 #include <QUrl>
43 #include <QToolBar>
44 #include <QFileSystemWatcher>
45 #include <QFileDialog>
46 #include <QHeaderView>
47 #include <QDebug>
48 #ifdef Q_OS_WIN
49 #include <windows.h>
50 //lite_memory_check_begin
51 #if defined(WIN32) && defined(_MSC_VER) &&  defined(_DEBUG)
52      #define _CRTDBG_MAP_ALLOC
53      #include <stdlib.h>
54      #include <crtdbg.h>
55      #define DEBUG_NEW new( _NORMAL_BLOCK, __FILE__, __LINE__ )
56      #define new DEBUG_NEW
57 #endif
58 //lite_memory_check_end
59 #endif
60 
FileSystemWidget(bool bMultiDirMode,LiteApi::IApplication * app,QWidget * parent)61 FileSystemWidget::FileSystemWidget(bool bMultiDirMode, LiteApi::IApplication *app, QWidget *parent) :
62     QWidget(parent),
63     m_liteApp(app),
64     m_bMultiDirMode(bMultiDirMode),
65     m_bHideRoot(false)
66 {
67     m_tree = new SymbolTreeView;
68     m_model = new FileSystemModel(this);
69 
70     QDir::Filters filters = QDir::AllDirs | QDir::Files | QDir::Drives
71                             | QDir::Readable| QDir::Writable
72                             | QDir::Executable/* | QDir::Hidden*/
73                             | QDir::NoDotAndDotDot;
74 #ifdef Q_OS_WIN // Symlinked directories can cause file watcher warnings on Win32.
75     filters |= QDir::NoSymLinks;
76 #endif
77     m_model->setFilter(filters);
78 
79     m_tree->setContextMenuPolicy(Qt::CustomContextMenu);
80     m_tree->setModel(m_model);
81 
82     QVBoxLayout *layout = new QVBoxLayout;
83     layout->setMargin(0);
84     layout->addWidget(m_tree);
85     this->setLayout(layout);
86 
87     connect(m_tree,SIGNAL(doubleClicked(QModelIndex)),this,SLOT(openPathIndex(QModelIndex)));
88     connect(m_liteApp->editorManager(),SIGNAL(currentEditorChanged(LiteApi::IEditor*)),this,SLOT(currentEditorChanged(LiteApi::IEditor*)));
89 
90 //    m_fileMenu = new QMenu(this);
91 //    m_folderMenu = new QMenu(this);
92 //    m_rootMenu = new QMenu(this);
93 
94     m_openEditorAct = new QAction(tr("Open File"),this);
95     m_newFileAct = new QAction(tr("New File..."),this);
96     m_newFileWizardAct = new QAction(tr("New File Wizard..."),this);
97     m_renameFileAct = new QAction(tr("Rename File..."),this);
98     m_removeFileAct = new QAction(tr("Delete File"),this);
99 
100     m_newFolderAct = new QAction(tr("New Folder..."),this);
101     m_renameFolderAct = new QAction(tr("Rename Folder..."),this);
102     m_removeFolderAct = new QAction(tr("Delete Folder"),this);
103 
104     m_openShellAct = new QAction(tr("Open Terminal Here"),this);
105     m_openExplorerAct = new QAction(tr("Open Explorer Here"),this);
106 
107     m_viewGodocAct = new QAction(tr("View Godoc Here"),this);
108 
109     m_addFolderAct = new QAction(tr("Add Folder..."),this);
110     m_closeFolerAct = new QAction(tr("Close Folder"),this);
111 
112     m_closeAllFoldersAct = new QAction(tr("Close All Folders"),this);
113 
114 //    m_fileMenu->addAction(m_executeFileAct);
115 //    m_fileMenu->addAction(m_openEditorAct);
116 //    m_fileMenu->addSeparator();
117 //    m_fileMenu->addAction(m_newFileAct);
118 //    m_fileMenu->addAction(m_newFileWizardAct);
119 //    m_fileMenu->addAction(m_renameFileAct);
120 //    m_fileMenu->addAction(m_removeFileAct);
121 //    m_fileMenu->addSeparator();
122 //    m_fileMenu->addAction(m_viewGodocAct);
123 //    m_fileMenu->addSeparator();
124 //    m_fileMenu->addAction(m_openShellAct);
125 //    m_fileMenu->addAction(m_openExplorerAct);
126 
127 //    m_folderMenu->addAction(m_newFileAct);
128 //    m_folderMenu->addAction(m_newFileWizardAct);
129 //    m_folderMenu->addAction(m_newFolderAct);
130 //    m_folderMenu->addAction(m_renameFolderAct);
131 //    m_folderMenu->addAction(m_removeFolderAct);
132 //    m_folderMenu->addSeparator();
133 //    m_folderMenu->addAction(m_closeFolerAct);
134 //    m_folderMenu->addSeparator();
135 //    m_folderMenu->addAction(m_viewGodocAct);
136 //    m_folderMenu->addSeparator();
137 //    m_folderMenu->addAction(m_openShellAct);
138 //    m_folderMenu->addAction(m_openExplorerAct);
139 
140 //    m_rootMenu->addAction(m_addFolderAct);
141 //    m_rootMenu->addSeparator();
142     //m_rootMenu->addAction(m_closeAllFoldersAct);
143 
144     connect(m_model,SIGNAL(direcotryChanged(QString)),this,SLOT(reloadDirectory(QString)));
145     connect(m_openEditorAct,SIGNAL(triggered()),this,SLOT(openEditor()));
146     connect(m_newFileAct,SIGNAL(triggered()),this,SLOT(newFile()));
147     connect(m_newFileWizardAct,SIGNAL(triggered()),this,SLOT(newFileWizard()));
148     connect(m_renameFileAct,SIGNAL(triggered()),this,SLOT(renameFile()));
149     connect(m_removeFileAct,SIGNAL(triggered()),this,SLOT(removeFile()));
150     connect(m_newFolderAct,SIGNAL(triggered()),this,SLOT(newFolder()));
151     connect(m_renameFolderAct,SIGNAL(triggered()),this,SLOT(renameFolder()));
152     connect(m_removeFolderAct,SIGNAL(triggered()),this,SLOT(removeFolder()));
153     connect(m_openShellAct,SIGNAL(triggered()),this,SLOT(openShell()));
154     connect(m_openExplorerAct,SIGNAL(triggered()),this,SLOT(openExplorer()));
155     connect(m_viewGodocAct,SIGNAL(triggered()),this,SLOT(viewGodoc()));
156     connect(m_addFolderAct,SIGNAL(triggered()),this,SLOT(addFolder()));
157     connect(m_closeFolerAct,SIGNAL(triggered()),this,SLOT(closeFolder()));
158     connect(m_closeAllFoldersAct,SIGNAL(triggered()),this,SLOT(closeAllFolders()));
159 
160     connect(m_tree,SIGNAL(customContextMenuRequested(QPoint)),this,SLOT(treeViewContextMenuRequested(QPoint)));
161     connect(m_model,SIGNAL(modelReset()),this,SLOT(modelReset()));
162 }
163 
~FileSystemWidget()164 FileSystemWidget::~FileSystemWidget()
165 {
166 //    m_liteApp->settings()->setValue("GolangTool/synceditor",m_syncEditor->isChecked());
167 //    m_liteApp->settings()->setValue("GolangTool/syncproject",m_syncProject->isChecked());
168     //    m_liteApp->settings()->setValue("golangtool/gopath",m_pathList);
169 }
170 
setHideRoot(bool b)171 void FileSystemWidget::setHideRoot(bool b)
172 {
173     if (m_bMultiDirMode) {
174         return;
175     }
176     m_bHideRoot = b;
177 }
178 
isHideRoot() const179 bool FileSystemWidget::isHideRoot() const
180 {
181     return m_bHideRoot;
182 }
183 
clear()184 void FileSystemWidget::clear()
185 {
186     m_model->clear();
187 }
188 
treeView() const189 SymbolTreeView *FileSystemWidget::treeView() const
190 {
191     return m_tree;
192 }
193 
model() const194 FileSystemModel *FileSystemWidget::model() const
195 {
196     return m_model;
197 }
198 
rootIndex() const199 QModelIndex FileSystemWidget::rootIndex() const
200 {
201     if (m_model->rowCount() == 0) {
202         return QModelIndex();
203     }
204     return m_model->index(0,0);
205 }
206 
modelReset()207 void FileSystemWidget::modelReset()
208 {
209     if (m_bHideRoot && (m_model->rowCount() > 0)) {
210         m_tree->setRootIndex(m_model->index(0,0));
211     }
212 }
213 
showHideFiles(bool b)214 void FileSystemWidget::showHideFiles(bool b)
215 {
216     if (isShowHideFiles() == b) {
217         return;
218     }
219     QDir::Filters filters = m_model->filter();
220     if (b) {
221         filters |= QDir::Hidden;
222     } else {
223         filters ^= QDir::Hidden;
224     }
225     m_model->setFilter(filters);
226     if (m_bHideRoot) {
227         m_tree->expand(this->rootIndex());
228     } else {
229         m_tree->expandToDepth(0);
230     }
231 }
232 
isShowHideFiles() const233 bool FileSystemWidget::isShowHideFiles() const
234 {
235     return m_model->filter() & QDir::Hidden;
236 }
237 
reloadDirectory(QString dir)238 void FileSystemWidget::reloadDirectory(QString dir)
239 {
240     SymbolTreeState state;
241     m_tree->saveState(&state);
242     m_model->reloadDirectory(dir);
243     m_tree->loadState(m_model,&state);
244 }
245 
contextDir() const246 QDir FileSystemWidget::contextDir() const
247 {
248     if (m_contextInfo.isDir()) {
249         return m_contextInfo.filePath();
250     }
251     return m_contextInfo.dir();
252 }
253 
contextFileInfo() const254 QFileInfo FileSystemWidget::contextFileInfo() const
255 {
256     return m_contextInfo;
257 }
258 
openEditor()259 void FileSystemWidget::openEditor()
260 {
261     if (m_contextInfo.isFile()) {
262         m_liteApp->fileManager()->openEditor(m_contextInfo.filePath());
263     }
264 }
265 
newFile()266 void FileSystemWidget::newFile()
267 {
268     QDir dir = contextDir();
269 
270     CreateFileDialog dlg(m_liteApp->mainWindow());
271     dlg.setDirectory(dir.path());
272     if (dlg.exec() == QDialog::Rejected) {
273         return;
274     }
275     QString fileName = dlg.getFileName();
276     if (!fileName.isEmpty()) {
277         QString filePath = QFileInfo(dir,fileName).filePath();
278         if (QFile::exists(filePath)) {
279             QMessageBox::information(m_liteApp->mainWindow(),tr("Create File"),
280                                      tr("A file with that name already exists!"));
281         } else {
282             QFile file(filePath);
283             if (file.open(QIODevice::WriteOnly)) {
284                 file.close();
285                 if (dlg.isOpenEditor()) {
286                     m_liteApp->fileManager()->openEditor(filePath,true);
287                 }
288             } else {
289                 QMessageBox::information(m_liteApp->mainWindow(),tr("Create File"),
290                                          tr("Failed to create the file!"));
291             }
292         }
293     }
294 }
295 
newFileWizard()296 void FileSystemWidget::newFileWizard()
297 {
298     QString filePath;
299     QString projPath;
300     QFileInfo info = contextFileInfo();
301     QDir dir = contextDir();
302     if (!info.isFile()) {
303         filePath = dir.absolutePath();
304         projPath = dir.absolutePath();
305     } else {
306         filePath = dir.absolutePath();
307         dir.cdUp();
308         projPath = dir.absolutePath();
309     }
310     m_liteApp->fileManager()->execFileWizard(projPath,filePath);
311 }
312 
renameFile()313 void FileSystemWidget::renameFile()
314 {
315     QFileInfo info = contextFileInfo();
316     if (!info.isFile()) {
317         return;
318     }
319     QString fileName = QInputDialog::getText(m_liteApp->mainWindow(),
320                                              tr("Rename File"),tr("New Name:"),
321                                              QLineEdit::Normal,info.fileName());
322     if (!fileName.isEmpty() && fileName != info.fileName()) {
323         QDir dir = contextDir();
324 #ifdef Q_OS_WIN
325         if (!MoveFileW(info.filePath().toStdWString().c_str(),QFileInfo(dir,fileName).filePath().toStdWString().c_str())) {
326             QMessageBox::information(m_liteApp->mainWindow(),tr("Rename File"),
327                                      tr("Failed to rename the file!"));
328         }
329 #else
330         if (!QFile::rename(info.filePath(),QFileInfo(dir,fileName).filePath())) {
331             QMessageBox::information(m_liteApp->mainWindow(),tr("Rename File"),
332                                      tr("Failed to rename the file!"));
333         }
334 #endif
335     }
336 }
337 
removeFile()338 void FileSystemWidget::removeFile()
339 {
340     QFileInfo info = contextFileInfo();
341     if (!info.isFile()) {
342         return;
343     }
344 
345     int ret = QMessageBox::question(m_liteApp->mainWindow(),tr("Delete File"),
346                           tr("Are you sure that you want to permanently delete this file?"),
347                           QMessageBox::Yes | QMessageBox::No, QMessageBox::No);
348     if (ret == QMessageBox::Yes) {
349         if (!QFile::remove(info.filePath())) {
350             QMessageBox::information(m_liteApp->mainWindow(),tr("Delete File"),
351                                      tr("Failed to delete the file!"));
352         }
353     }
354 }
355 
newFolder()356 void FileSystemWidget::newFolder()
357 {
358     QDir dir = contextDir();
359 
360     CreateDirDialog dlg(m_liteApp->mainWindow());
361     dlg.setDirectory(dir.path());
362     if (dlg.exec() == QDialog::Rejected) {
363         return;
364     }
365 
366     QString folderName = dlg.getDirName();
367     if (!folderName.isEmpty()) {
368         if (!dir.entryList(QStringList() << folderName,QDir::Dirs).isEmpty()) {
369             QMessageBox::information(m_liteApp->mainWindow(),tr("Create Folder"),
370                                      tr("A folder with that name already exists!"));
371         } else if (!dir.mkpath(folderName)) {
372             QMessageBox::information(m_liteApp->mainWindow(),tr("Create Folder"),
373                                      tr("Failed to create the folder!"));
374         }
375     }
376 }
377 
renameFolder()378 void FileSystemWidget::renameFolder()
379 {
380     QFileInfo info = contextFileInfo();
381     if (!info.isDir()) {
382         return;
383     }
384 
385     QString folderName = QInputDialog::getText(m_liteApp->mainWindow(),
386                                                tr("Rename Folder"),tr("Folder Name"),
387                                                QLineEdit::Normal,info.fileName());
388     if (!folderName.isEmpty() && folderName != info.fileName()) {
389         QDir dir = contextDir();
390         dir.cdUp();
391 #ifdef Q_OS_WIN
392         QString _old = info.filePath();
393         QString _new = dir.path()+"/"+folderName;
394         if (!MoveFileW(_old.toStdWString().c_str(),_new.toStdWString().c_str())) {
395             QMessageBox::information(m_liteApp->mainWindow(),tr("Rename Folder"),
396                                      tr("Failed to rename the folder!"));
397         }
398 #else
399         if (!dir.rename(info.fileName(),folderName)) {
400             QMessageBox::information(m_liteApp->mainWindow(),tr("Rename Folder"),
401                                      tr("Failed to rename the folder!"));
402         }
403 #endif
404     }
405 }
406 
removeFolder()407 void FileSystemWidget::removeFolder()
408 {
409     QFileInfo info = contextFileInfo();
410     if (!info.isDir()) {
411         return;
412     }
413 
414     int ret = QMessageBox::warning(m_liteApp->mainWindow(),tr("Delete Folder"),
415                           tr("Are you sure that you want to permanently delete this folder and all of its contents?"),
416                           QMessageBox::Yes | QMessageBox::No, QMessageBox::No);
417     if (ret == QMessageBox::Yes) {
418         QDir dir = info.dir();
419         m_model->removeWatcher(info.filePath());
420         if (!dir.rmdir(info.fileName())) {
421             QMessageBox::information(m_liteApp->mainWindow(),tr("Delete Folder"),
422                                      tr("Failed to delete the folder!"));
423             m_model->addWatcher(info.filePath());
424         }
425     }
426 }
427 
openExplorer()428 void FileSystemWidget::openExplorer()
429 {
430     QDir dir = contextDir();
431     QDesktopServices::openUrl(QUrl::fromLocalFile(dir.path()));
432 }
433 
viewGodoc()434 void FileSystemWidget::viewGodoc()
435 {
436     QDir dir = contextDir();
437     LiteApi::IGolangDoc *doc = LiteApi::findExtensionObject<LiteApi::IGolangDoc*>(m_liteApp,"LiteApi.IGolangDoc");
438     if (doc) {
439         QUrl url;
440         url.setScheme("pdoc");
441         url.setPath(dir.path());
442         doc->openUrl(url);
443         doc->activeBrowser();
444     }
445 }
446 
addFolder()447 void FileSystemWidget::addFolder()
448 {
449 #if QT_VERSION >= 0x050000
450         static QString home = QStandardPaths::writableLocation(QStandardPaths::HomeLocation);
451 #else
452         static QString home = QDesktopServices::storageLocation(QDesktopServices::HomeLocation);
453 #endif
454     QString folder = QFileDialog::getExistingDirectory(this,tr("Add Folder"),home);
455     if (folder.isEmpty()) {
456         return;
457     }
458     this->addRootPath(folder);
459     QDir dir(folder);
460     if (dir.cdUp()) {
461         home = dir.path();
462     }
463 }
464 
closeFolder()465 void FileSystemWidget::closeFolder()
466 {
467 //    if (m_contextInfo.exists() && !m_contextInfo.isDir()) {
468 //        return;
469 //    }
470     this->m_model->removeRootPath(m_contextInfo.filePath());
471 }
472 
closeAllFolders()473 void FileSystemWidget::closeAllFolders()
474 {
475     this->m_model->clear();
476 }
477 
openShell()478 void FileSystemWidget::openShell()
479 {
480     QDir dir = contextDir();
481     QProcessEnvironment env = LiteApi::getCurrentEnvironment(m_liteApp);
482     QString shell = env.value("LITEIDE_SHELL");
483     if (!shell.isEmpty()) {
484         foreach (QString info, shell.split(";",QString::SkipEmptyParts)) {
485             QStringList ar = info.split(" ",QString::SkipEmptyParts);
486             if (ar.size() >= 1) {
487                 QString cmd = FileUtil::lookPath(ar[0],LiteApi::getCurrentEnvironment(m_liteApp),false);
488                 if (!cmd.isEmpty()) {
489                     QString path = dir.path();
490                     ar.pop_front();
491 #ifdef Q_OS_MAC
492                     ar.push_back(path);
493 #endif
494 #ifdef Q_OS_WIN
495     if (path.length() == 2 && path.right(1) == ":") {
496         path += "/";
497     }
498 #endif
499                     QProcess::startDetached(cmd,ar,path);
500                     return;
501                 }
502             }
503         }
504         return;
505     }
506     QString cmd = env.value("LITEIDE_TERM");
507     QStringList args = env.value("LITEIDE_TERMARGS").split(" ",QString::SkipEmptyParts);
508     //qDebug() << cmd;
509     QString path = dir.path();
510 #ifdef Q_OS_MAC
511     args.append(path);
512 #endif
513 #ifdef Q_OS_WIN
514     if (path.length() == 2 && path.right(1) == ":") {
515         path += "/";
516     }
517 #endif
518     QProcess::startDetached(cmd,args,path);
519 }
520 
treeViewContextMenuRequested(const QPoint & pos)521 void FileSystemWidget::treeViewContextMenuRequested(const QPoint &pos)
522 {
523     //QMenu *pop = new QMenu(this);
524     //connect(pop,SIGNAL(destroyed()),this,SLOT(destroy2()));
525     QMenu menu(m_tree);
526     LiteApi::FILESYSTEM_CONTEXT_FLAG flag = LiteApi::FILESYSTEM_ROOT;
527     QModelIndex index = m_tree->indexAt(pos);
528     if (index.isValid()) {
529         FileNode *node = m_model->nodeFromIndex(index);
530         if (node) {
531             m_contextInfo = node->fileInfo();
532             m_contextIndex = index;
533             if (m_model->isRootPathNode(node)) {
534                 //contextMenu = m_folderMenu;
535                 flag = LiteApi::FILESYSTEM_ROOTFOLDER;
536                 //m_closeFolerAct->setVisible(true);
537                 //m_removeFolderAct->setVisible(false);
538             } else if (node->isDir()) {
539                 //contextMenu = m_folderMenu;
540                 flag = LiteApi::FILESYSTEM_FOLDER;
541                 //m_closeFolerAct->setVisible(false);
542                 //m_removeFolderAct->setVisible(true);
543             } else {
544                 //contextMenu = m_fileMenu;
545                 flag = LiteApi::FILESYSTEM_FILES;
546             }
547         }
548     } else if (!m_bMultiDirMode) {
549         m_contextIndex = this->rootIndex();
550         FileNode *node = m_model->nodeFromIndex(m_contextIndex);
551         if (node) {
552             m_contextInfo = node->fileInfo();
553         }
554         flag = LiteApi::FILESYSTEM_ROOTFOLDER;
555     }
556     bool hasGo = false;
557     if (!m_bMultiDirMode || (flag != LiteApi::FILESYSTEM_ROOT)) {
558         foreach(QFileInfo info, contextDir().entryInfoList(QDir::Files)) {
559             if (info.suffix() == "go") {
560                 hasGo = true;
561             }
562         }
563     }
564     //root folder
565     if (flag == LiteApi::FILESYSTEM_ROOT) {
566         if (m_bMultiDirMode) {
567             menu.addAction(m_addFolderAct);
568         } else {
569             menu.addAction(m_newFileAct);
570             menu.addAction(m_newFileWizardAct);
571             menu.addAction(m_newFolderAct);
572             menu.addSeparator();
573             if (hasGo) {
574                 menu.addAction(m_viewGodocAct);
575                 menu.addSeparator();
576             }
577             menu.addAction(m_openShellAct);
578             menu.addAction(m_openExplorerAct);
579         }
580     } else if (flag == LiteApi::FILESYSTEM_ROOTFOLDER) {
581         menu.addAction(m_newFileAct);
582         menu.addAction(m_newFileWizardAct);
583         menu.addAction(m_newFolderAct);
584         menu.addAction(m_renameFolderAct);
585         menu.addAction(m_closeFolerAct);
586         menu.addSeparator();
587         if (hasGo) {
588             menu.addAction(m_viewGodocAct);
589             menu.addSeparator();
590         }
591         menu.addAction(m_openShellAct);
592         menu.addAction(m_openExplorerAct);
593     } else if (flag == LiteApi::FILESYSTEM_FOLDER) {
594         menu.addAction(m_newFileAct);
595         menu.addAction(m_newFileWizardAct);
596         menu.addAction(m_newFolderAct);
597         menu.addAction(m_renameFolderAct);
598         menu.addAction(m_removeFolderAct);
599         menu.addSeparator();
600         if (hasGo) {
601             menu.addAction(m_viewGodocAct);
602             menu.addSeparator();
603         }
604         menu.addAction(m_openShellAct);
605         menu.addAction(m_openExplorerAct);
606     } else if (flag == LiteApi::FILESYSTEM_FILES) {
607         menu.addAction(m_openEditorAct);
608         menu.addSeparator();
609         menu.addAction(m_newFileAct);
610         menu.addAction(m_newFileWizardAct);
611         menu.addAction(m_renameFileAct);
612         menu.addAction(m_removeFileAct);
613         menu.addSeparator();
614         if (hasGo) {
615             menu.addAction(m_viewGodocAct);
616             menu.addSeparator();
617         }
618         menu.addAction(m_openShellAct);
619         menu.addAction(m_openExplorerAct);
620 
621     }
622     emit aboutToShowContextMenu(&menu,flag,m_contextInfo);
623     menu.exec(m_tree->mapToGlobal(pos));
624 }
625 
addRootPath(const QString & path)626 void FileSystemWidget::addRootPath(const QString &path)
627 {
628     if (m_model->addRootPath(path)) {
629         m_liteApp->recentManager()->addRecent(path,"folder");
630         QModelIndex index = m_model->index(m_model->rowCount()-1,0,QModelIndex());
631         if (index.isValid()) {
632             m_tree->expand(index);
633         }
634     }
635 }
636 
setRootPathList(const QStringList & pathList)637 void FileSystemWidget::setRootPathList(const QStringList &pathList)
638 {
639     m_model->setRootPathList(pathList);
640     currentEditorChanged(m_liteApp->editorManager()->currentEditor());
641 }
642 
setRootPath(const QString & path)643 void FileSystemWidget::setRootPath(const QString &path)
644 {
645     m_model->setRootPath(path);
646     if (m_bHideRoot) {
647         m_tree->expand(this->rootIndex());
648     } else {
649         m_tree->expandToDepth(0);
650     }
651 }
652 
rootPath() const653 QString FileSystemWidget::rootPath() const
654 {
655     QStringList paths = m_model->rootPathList();
656     if (!paths.isEmpty()) {
657         return paths.first();
658     }
659     return QString();
660 }
661 
rootPathList() const662 QStringList FileSystemWidget::rootPathList() const
663 {
664     return m_model->rootPathList();
665 }
666 
setStartIndex(const QModelIndex & index)667 void FileSystemWidget::setStartIndex(const QModelIndex &index)
668 {
669     QModelIndex oldIndex = m_model->startIndex();
670     if (oldIndex != index) {
671         m_model->setStartIndex(index);
672         m_tree->update(oldIndex);
673         m_tree->update(index);
674         emit startPathChanged(m_model->filePath(index));
675     }
676 }
677 
startPath() const678 QString FileSystemWidget::startPath() const
679 {
680     QModelIndex index = m_model->startIndex();
681     return m_model->filePath(index);
682 }
683 
pathIndexChanged(const QModelIndex & index)684 void FileSystemWidget::pathIndexChanged(const QModelIndex & index)
685 {
686     FileNode *node = m_model->nodeFromIndex(index);
687     if (node) {
688         QFileInfo info = node->fileInfo();
689         QModelIndex newIndex = index;
690         if (info.isDir()) {
691             newIndex = index;
692         } else {
693             newIndex = index.parent();
694         }
695         this->setStartIndex(newIndex);
696     }
697 }
698 
openPathIndex(const QModelIndex & index)699 void FileSystemWidget::openPathIndex(const QModelIndex &index)
700 {
701     FileNode *node = m_model->nodeFromIndex(index);
702     if (!node) {
703         return;
704     }
705     if (node->isFile()) {
706         //QFileInfo info(node->path());
707         QString mimeType = m_liteApp->mimeTypeManager()->findMimeTypeByFile(node->path());
708         if (mimeType.startsWith("text/") || mimeType.startsWith("application/")) {
709             m_liteApp->fileManager()->openEditor(node->path());
710             return;
711         }
712 //        QString cmd = FileUtil::lookPathInDir(info.fileName(),info.path());
713 //        if (cmd == node->path()) {
714 //            LiteApi::ILiteBuild *build = LiteApi::getLiteBuild(m_liteApp);
715 //            if (build) {
716 //                build->executeCommand(info.fileName(),QString(),info.path());
717 //                return;
718 //            }
719 //        }
720         m_liteApp->fileManager()->openEditor(node->path(),true);
721     }
722 }
723 
currentEditorChanged(LiteApi::IEditor *)724 void FileSystemWidget::currentEditorChanged(LiteApi::IEditor* /*editor*/)
725 {
726     /*
727     if (!m_syncEditor->isChecked()) {
728         return;
729     }
730     if (editor && !editor->filePath().isEmpty()) {
731         QModelIndex index = m_model->findPath(editor->filePath());
732         if (index.isValid()) {
733             m_tree->setCurrentIndex(index);
734             m_tree->scrollTo(index,QAbstractItemView::EnsureVisible);
735             if (m_syncProject->isChecked()) {
736                 setStartIndex(index.parent());
737             }
738         }
739     }
740     */
741 }
742 
syncEditor(bool b)743 void FileSystemWidget::syncEditor(bool b)
744 {
745     if (!b) {
746        // m_syncProject->setChecked(false);
747     }
748 }
749 
expandStartPath(QString)750 void FileSystemWidget::expandStartPath(QString)
751 {
752     m_tree->scrollTo(m_model->startIndex(),QAbstractItemView::EnsureVisible);
753 }
754