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: liteapp.cpp
22 // Creator: visualfc <visualfc@gmail.com>
23
24 #include "liteapp.h"
25 #include "filemanager.h"
26 #include "editormanager.h"
27 #include "projectmanager.h"
28 #include "pluginmanager.h"
29 #include "actionmanager.h"
30 #include "mimetypemanager.h"
31 #include "optionmanager.h"
32 #include "toolwindowmanager.h"
33 #include "htmlwidgetmanager.h"
34 #include "recentmanager.h"
35 #include "mainwindow.h"
36 #include "liteappoptionfactory.h"
37 #include "folderprojectfactory.h"
38 #include "textbrowserhtmlwidget.h"
39 #include "pluginsdialog.h"
40 #include "liteapp_global.h"
41 #ifdef Q_OS_MAC
42 #include "macsupport.h"
43 #endif
44 #include "splitwindowstyle.h"
45 #include "sidewindowstyle.h"
46 #include "idletimer.h"
47 #include "iconutil/iconutil.h"
48 #include "liteapi/liteutil.h"
49 #include "liteapi/liteids.h"
50 #include <QApplication>
51 #include <QSplashScreen>
52 #include <QMenuBar>
53 #include <QDir>
54 #include <QToolBar>
55 #include <QAction>
56 #include <QDateTime>
57 #include <QSplitter>
58 #include <QTextCursor>
59 #include <QTextBlock>
60 #include <QTimer>
61 #include <QPainter>
62 #include <QComboBox>
63 #include <QProcessEnvironment>
64 #include <QDebug>
65 //lite_memory_check_begin
66 #if defined(WIN32) && defined(_MSC_VER) && defined(_DEBUG)
67 #define _CRTDBG_MAP_ALLOC
68 #include <stdlib.h>
69 #include <crtdbg.h>
70 #define DEBUG_NEW new( _NORMAL_BLOCK, __FILE__, __LINE__ )
71 #define new DEBUG_NEW
72 #endif
73 //lite_memory_check_end
74
75 #define LITEIDE_VERSION "X37.4"
76
77
getRootPath()78 QString LiteApp::getRootPath()
79 {
80 QDir rootDir = QApplication::applicationDirPath();
81 rootDir.cdUp();
82 return rootDir.canonicalPath();
83 }
84
getToolPath()85 QString LiteApp::getToolPath()
86 {
87 static QProcessEnvironment env = QProcessEnvironment::systemEnvironment();
88 QString path = env.value("LITEIDE_TOOL_PATH");
89 if (!path.isEmpty()) {
90 return path;
91 }
92 return QApplication::applicationDirPath();
93 }
94
getPluginPath()95 QString LiteApp::getPluginPath()
96 {
97 static QProcessEnvironment env = QProcessEnvironment::systemEnvironment();
98 QString path = env.value("LITEIDE_PLUGIN_PATH");
99 if (!path.isEmpty()) {
100 return path;
101 }
102 QString root = getRootPath();
103 #ifdef Q_OS_MAC
104 return root+"/PlugIns";
105 #else
106 return root+"/lib/liteide/plugins";
107 #endif
108 }
109
getResoucePath()110 QString LiteApp::getResoucePath()
111 {
112 static QProcessEnvironment env = QProcessEnvironment::systemEnvironment();
113 QString path = env.value("LITEIDE_RES_PATH");
114 if (!path.isEmpty()) {
115 return path;
116 }
117 QString root = getRootPath();
118 #ifdef Q_OS_MAC
119 return root+"/Resources";
120 #else
121 return root+"/share/liteide";
122 #endif
123 }
124
getStoragePath()125 QString LiteApp::getStoragePath()
126 {
127 #if QT_VERSION >= 0x050000
128 QString root = QStandardPaths::writableLocation(QStandardPaths::DataLocation);
129 #else
130 QString root = QDesktopServices::storageLocation(QDesktopServices::DataLocation);
131 #endif
132 return root+"/liteide";
133 }
134
NewApplication(const QString & sessionName,IApplication * baseApp)135 IApplication* LiteApp::NewApplication(const QString &sessionName, IApplication *baseApp)
136 {
137 LiteApp *app = new LiteApp;
138 app->load(sessionName,baseApp);
139 return app;
140 }
141
pluginManager()142 PluginManager *LiteApp::pluginManager()
143 {
144 static PluginManager manager;
145 return &manager;
146 }
147
appList()148 QList<IApplication *> LiteApp::appList()
149 {
150 return s_appList;
151 }
152
153 QMap<QString,QVariant> LiteApp::s_cookie;
154
155 QList<IApplication*> LiteApp::s_appList;
156
LiteApp()157 LiteApp::LiteApp()
158 : m_rootPath(LiteApp::getRootPath()),
159 m_applicationPath(QApplication::applicationDirPath()),
160 m_toolPath(LiteApp::getToolPath()),
161 m_pluginPath(LiteApp::getPluginPath()),
162 m_resourcePath(LiteApp::getResoucePath()),
163 m_storagePath(LiteApp::getStoragePath())
164 {
165 s_appList.append(this);
166
167 QSettings global(m_resourcePath+"/liteapp/config/global.ini",QSettings::IniFormat);
168 bool storeLocal = global.value(LITEIDE_STORELOCAL,false).toBool();
169
170 QString flagLocalSetting = "--local-setting";
171 QString flagUserSetting = "--user-setting";
172
173 if (s_cookie.value(flagUserSetting).toBool()) {
174 storeLocal = false;
175 } else if (s_cookie.value(flagLocalSetting).toBool()) {
176 storeLocal = true;
177 }
178
179 if (storeLocal) {
180 m_settings = new QSettings(m_resourcePath+"/liteapp/config/liteide.ini", QSettings::IniFormat);
181 } else {
182 m_settings = new QSettings(QSettings::IniFormat,QSettings::UserScope,"liteide","liteide",this);
183 }
184
185 QStringList searchPathList;
186 if (m_settings->value(LITEIDE_CUSTOMEICON,false).toBool()) {
187 QString iconPath = m_settings->value(LITEIDE_CUSTOMEICONPATH,"default").toString();
188 if (!iconPath.isEmpty()) {
189 searchPathList << m_resourcePath+"/liteapp/qrc/"+iconPath+"/liteapp";
190 searchPathList << m_resourcePath+"/liteapp/qrc/"+iconPath;
191 }
192 }
193 searchPathList << ":/";
194 searchPathList << m_resourcePath+"/liteapp/qrc/default/liteapp";
195 searchPathList << m_resourcePath+"/liteapp/qrc/default";
196 QDir::setSearchPaths("icon",searchPathList);
197
198 m_extension = new Extension;
199
200 //install idle timer;
201 m_idleTimer = new AppIdleTimer;
202 m_extension->addObject("LiteApi.IAppIdleTimer",m_idleTimer);
203
204 m_mainwindow = new MainWindow(this);
205
206 QString style = this->settings()->value(LITEAPP_STYLE,"sidebar").toString();
207 if (style == "splitter") {
208 SplitWindowStyle *style = new SplitWindowStyle(this,m_mainwindow);
209 m_mainwindow->setWindowStyle(style);
210 } else {
211 SideWindowStyle *style = new SideWindowStyle(this,m_mainwindow);
212 m_mainwindow->setWindowStyle(style);
213 }
214
215 m_toolWindowManager = new ToolWindowManager;
216 m_htmlWidgetManager = new HtmlWidgetManager;
217 m_actionManager = new ActionManager;
218 m_projectManager = new ProjectManager;
219 m_fileManager = new FileManager;
220 m_editorManager = new EditorManager;
221 m_mimeTypeManager = new MimeTypeManager;
222 m_optionManager = new OptionManager;
223 m_recentManager = new RecentManager;
224
225 m_goProxy = new GoProxy(this);
226 m_actionManager->initWithApp(this);
227
228 m_mainwindow->createToolWindowMenu();
229
230 m_toolWindowManager->initWithApp(this);
231 m_mimeTypeManager->initWithApp(this);
232 m_recentManager->initWithApp(this);
233 m_projectManager->initWithApp(this);
234 m_fileManager->initWithApp(this);
235 m_editorManager->initWithApp(this);
236 m_optionManager->initWithApp(this);
237
238 //m_mainwindow->setCentralWidget(m_editorManager->widget());
239 m_mainwindow->splitter()->addWidget(m_editorManager->widget());
240 //m_mainwindow->splitter()->addWidget(m_outputManager->widget());
241 m_mainwindow->splitter()->setStretchFactor(0,50);
242 //m_mainwindow->setStatusBar(m_outputManager->statusBar());
243
244 m_htmlWidgetManager->addFactory(new TextBrowserHtmlWidgetFactory(this));
245
246 m_extension->addObject("LiteApi.IMimeTypeManager",m_mimeTypeManager);
247 m_extension->addObject("LiteApi.IProjectManager",m_projectManager);
248 m_extension->addObject("LiteApi.IEditManager",m_editorManager);
249 m_extension->addObject("LiteApi.IOptoinManager",m_optionManager);
250 m_extension->addObject("LiteApi.IToolWindowManager",m_toolWindowManager);
251 m_extension->addObject("LiteApi.QMainWindow",m_mainwindow);
252 m_extension->addObject("LiteApi.QMainWindow.QSplitter",m_mainwindow->splitter());
253 m_extension->addObject("LiteApi.IHtmlWidgetManager",m_htmlWidgetManager);
254
255 //add actions
256 connect(m_projectManager,SIGNAL(currentProjectChanged(LiteApi::IProject*)),this,SLOT(currentProjectChanged(LiteApi::IProject*)));
257 connect(m_editorManager,SIGNAL(currentEditorChanged(LiteApi::IEditor*)),m_projectManager,SLOT(currentEditorChanged(LiteApi::IEditor*)));
258 connect(m_editorManager,SIGNAL(currentEditorChanged(LiteApi::IEditor*)),m_mainwindow,SLOT(currentEditorChanged(LiteApi::IEditor*)));
259 connect(m_editorManager,SIGNAL(editorModifyChanged(LiteApi::IEditor*,bool)),m_mainwindow,SLOT(editorModifyChanged(LiteApi::IEditor*,bool)));
260 connect(m_editorManager,SIGNAL(currentEditorChanged(LiteApi::IEditor*)),this,SLOT(currentEditorChanged(LiteApi::IEditor*)));
261 connect(m_editorManager,SIGNAL(tabAddRequest()),m_fileManager,SLOT(openEditors()));
262 connect(m_editorManager,SIGNAL(editorSaved(LiteApi::IEditor*)),m_fileManager,SLOT(editorSaved(LiteApi::IEditor*)));
263 connect(m_editorManager,SIGNAL(editorCreated(LiteApi::IEditor*)),m_fileManager,SLOT(editorCreated(LiteApi::IEditor*)));
264 connect(m_editorManager,SIGNAL(editorAboutToClose(LiteApi::IEditor*)),m_fileManager,SLOT(editorAboutToClose(LiteApi::IEditor*)));
265 connect(m_editorManager,SIGNAL(doubleClickedTab()),m_mainwindow,SLOT(showOrHideToolWindow()));
266 connect(m_optionManager,SIGNAL(applyOption(QString)),m_fileManager,SLOT(applyOption(QString)));
267 connect(m_optionManager,SIGNAL(applyOption(QString)),m_projectManager,SLOT(applyOption(QString)));
268 connect(m_optionManager,SIGNAL(applyOption(QString)),m_editorManager,SLOT(applyOption(QString)));
269 connect(m_optionManager,SIGNAL(applyOption(QString)),this,SLOT(applyOption(QString)));
270
271 QAction *esc = new QAction(tr("Escape"),this);
272 m_actionManager->getActionContext(this,"App")->regAction(esc,"Escape","ESC");
273 m_mainwindow->addAction(esc);
274 connect(esc,SIGNAL(triggered()),this,SLOT(escape()));
275
276 createActions();
277 createMenus();
278 createToolBars();
279
280 m_editorManager->createActions();
281
282 m_logOutput = new TextOutput(this);
283 //m_outputManager->addOutuput(m_logOutput,tr("Console"));
284 m_logAct = m_toolWindowManager->addToolWindow(Qt::BottomDockWidgetArea,m_logOutput,"EventLog",tr("Event Log"),true);
285 connect(m_logOutput,SIGNAL(dbclickEvent(QTextCursor)),this,SLOT(dbclickLogOutput(QTextCursor)));
286
287 m_optionAct = new QAction(loadIcon("icon:images/options.png"),tr("Options"),this);
288 m_optionAct->setMenuRole(QAction::PreferencesRole);
289 m_actionManager->setViewMenuSeparator("sep/option",true);
290 m_actionManager->insertViewMenuAction(m_optionAct,"sep/option");
291
292 m_stdToolBar->addSeparator();
293 m_stdToolBar->addAction(m_optionAct);
294
295 connect(m_optionAct,SIGNAL(triggered()),m_optionManager,SLOT(exec()));
296
297 this->appendLog("LiteApp","Initializing");
298 this->appendLog("Load Setting",m_settings->fileName());
299
300 m_liteAppOptionFactory = new LiteAppOptionFactory(this,this);
301
302 m_optionManager->addFactory(m_liteAppOptionFactory);
303
304 connect(m_goProxy,SIGNAL(stdoutput(QByteArray)),this,SLOT(goproxyDone(QByteArray)));
305 //connect(this,SIGNAL(key_escape()),m_mainwindow,SLOT(hideOutputWindow()));
306 connect(m_mainwindow,SIGNAL(fullScreenStateChanged(bool)),m_fullScreent,SLOT(setChecked(bool)));
307 }
308
makeSplashImage(LiteApi::IApplication * app)309 static QImage makeSplashImage(LiteApi::IApplication *app)
310 {
311 QRect r(0,0,400,280);
312 QImage image(r.size(),QImage::Format_ARGB32_Premultiplied);
313
314 QPainter painter(&image);
315 painter.setRenderHint(QPainter::Antialiasing,true);
316
317 QLinearGradient lg(0,0,r.width(),r.height());
318 lg.setColorAt(0.0,qRgb(0,125,127));
319 lg.setColorAt(1.0,qRgb(0,88,127));
320
321 QBrush bk(lg);
322 painter.fillRect(r,bk);
323 int th = r.height()*2/5;
324 int bh = r.height()-th;
325 painter.fillRect(1,th,r.width()-2,bh-1,Qt::white);
326
327 QFont font("Timer",32);
328 font.setPointSize(32);
329 font.setItalic(true);
330 painter.setPen(Qt::white);
331 painter.setFont(font);
332 painter.drawText(2,2,r.width()-2,th,Qt::AlignCenter,app->ideFullName());
333
334 font.setPointSize(9);
335 font.setItalic(false);
336 font.setBold(true);
337 painter.setPen(Qt::black);
338 painter.setFont(font);
339 painter.drawText(10,th,r.width()-10,bh,Qt::AlignLeft|Qt::AlignVCenter,app->ideCopyright());
340
341 painter.drawImage(r.width()-145,r.height()-145,QImage("icon:/images/liteide-logo128.png"));
342 return image;
343 }
344
load(const QString & sessionName,IApplication * baseApp)345 void LiteApp::load(const QString &sessionName, IApplication *baseApp)
346 {
347 bool bLoadSession = true;
348 if (baseApp == 0) {
349 bLoadSession = m_settings->value(LITEAPP_AUTOLOADLASTSESSION,true).toBool();
350 }
351
352 m_currentSession = sessionName;
353 if (!bLoadSession) {
354 m_currentSession = "emtpy";
355 }
356
357 QSplashScreen *splash = 0;
358 bool bSplash = m_settings->value(LITEAPP_SPLASHVISIBLE,true).toBool();
359 if (baseApp) {
360 bSplash = false;
361 }
362 if (bSplash) {
363 splash = new QSplashScreen(QPixmap::fromImage(makeSplashImage(this)),Qt::WindowStaysOnTopHint);
364 }
365 if (bSplash) {
366 splash->show();
367 }
368
369 if (bSplash) {
370 splash->showMessage("Scanning plugins...",Qt::AlignLeft|Qt::AlignBottom);
371 }
372
373 qApp->processEvents();
374
375 loadMimeType();
376 loadPlugins();
377
378 if (bSplash) {
379 splash->showMessage("Loading plugins...",Qt::AlignLeft|Qt::AlignBottom);
380 }
381
382 qApp->processEvents();
383 initPlugins();
384
385 if (bSplash) {
386 splash->showMessage("Loading state...",Qt::AlignLeft|Qt::AlignBottom);
387 }
388
389 qApp->processEvents();
390 loadState();
391 if (baseApp) {
392 if (baseApp->mainWindow()->isMaximized()) {
393 m_mainwindow->resize(800,600);
394 m_mainwindow->show();
395 } else {
396 QRect rc = baseApp->mainWindow()->geometry();
397 rc.adjust(20,20,20,20);
398 m_mainwindow->setGeometry(rc);
399 m_mainwindow->show();
400 }
401 } else {
402 m_mainwindow->show();
403 }
404
405 emit loaded();
406 m_projectManager->setCurrentProject(0);
407
408 if (bSplash) {
409 splash->showMessage("Loading session...",Qt::AlignLeft|Qt::AlignBottom);
410 }
411
412 qApp->processEvents();
413
414 if (bLoadSession && !sessionName.isEmpty()) {
415 loadSession(sessionName);
416 this->appendLog("Load session",sessionName);
417 }
418
419 if (bSplash) {
420 m_mainwindow->raise();
421 splash->finish(m_mainwindow);
422 splash->deleteLater();
423 }
424
425 this->appendLog("HtmlWidgetFactory",m_htmlWidgetManager->classNameList().join(" "));
426 this->appendLog("DefaultHtmlWidgetFactory",m_htmlWidgetManager->defaultClassName());
427
428 m_goProxy->call("version");
429
430 appendLog("LiteApp","Finished loading");
431 }
432
~LiteApp()433 LiteApp::~LiteApp()
434 {
435 s_appList.removeAll(this);
436 cleanup();
437 }
438
extension()439 IExtension *LiteApp::extension()
440 {
441 return m_extension;
442 }
443
cleanup()444 void LiteApp::cleanup()
445 {
446 //
447 emit aboutToQuit();
448 //delete plugin by reverse depend
449 QListIterator<IPlugin*> it(m_pluginList);
450 it.toBack();
451 while(it.hasPrevious()) {
452 IPlugin *p = it.previous();
453 //qDebug() << "clean plugin" << p;
454 delete p;
455 }
456 m_pluginList.clear();
457
458 delete m_idleTimer;
459 delete m_projectManager;
460 delete m_editorManager;
461 delete m_htmlWidgetManager;
462 delete m_liteAppOptionFactory;
463 delete m_fileManager;
464 delete m_mimeTypeManager;
465 delete m_optionManager;
466 delete m_logOutput;
467 delete m_toolWindowManager;
468 delete m_recentManager;
469 delete m_actionManager;
470 delete m_extension;
471 delete m_settings;
472 }
473
aboutPlugins()474 void LiteApp::aboutPlugins()
475 {
476 PluginsDialog *dlg = new PluginsDialog(this,m_mainwindow);
477 foreach (LiteApi::IPluginFactory *factory, pluginManager()->factoryList()) {
478 dlg->appendInfo(factory->info());
479 }
480 dlg->exec();
481 }
482
escape()483 void LiteApp::escape()
484 {
485 IEditor *editor = m_editorManager->currentEditor();
486 if (!editor) {
487 return;
488 }
489 bool bFocus = editor->widget()->isAncestorOf(qApp->focusWidget());
490 if (!bFocus) {
491 editor->onActive();
492 } else {
493 emit key_escape();
494 m_mainwindow->hideOutputWindow();
495 }
496 }
497
newWindow()498 void LiteApp::newWindow()
499 {
500 LiteApp::newInstance("default");
501 }
502
closeWindow()503 void LiteApp::closeWindow()
504 {
505 m_mainwindow->close();
506 }
507
exit()508 void LiteApp::exit()
509 {
510 qApp->closeAllWindows();
511 }
512
applyOption(QString id)513 void LiteApp::applyOption(QString id)
514 {
515 if (id != OPTION_LITEAPP) {
516 return;
517 }
518 //bool b = m_settings->value(LITEAPP_OPTNFOLDERINNEWWINDOW,true).toBool();
519 //m_openFolderNewWindowAct->setVisible(!b);
520 }
521
hasGoProxy() const522 bool LiteApp::hasGoProxy() const
523 {
524 return GoProxy::hasProxy();
525 }
526
createGoProxy(QObject * parent)527 IGoProxy *LiteApp::createGoProxy(QObject *parent)
528 {
529 return new GoProxy(parent);
530 }
531
newInstance(const QString & sessionName)532 IApplication *LiteApp::newInstance(const QString &sessionName)
533 {
534 return LiteApp::NewApplication(sessionName,this);
535 }
536
instanceList() const537 QList<IApplication *> LiteApp::instanceList() const
538 {
539 return s_appList;
540 }
541
editorManager()542 IEditorManager *LiteApp::editorManager()
543 {
544 return m_editorManager;
545 }
546
fileManager()547 IFileManager *LiteApp::fileManager()
548 {
549 return m_fileManager;
550 }
551
projectManager()552 IProjectManager *LiteApp::projectManager()
553 {
554 return m_projectManager;
555 }
556
actionManager()557 IActionManager *LiteApp::actionManager()
558 {
559 return m_actionManager;
560 }
561
mimeTypeManager()562 IMimeTypeManager *LiteApp::mimeTypeManager()
563 {
564 return m_mimeTypeManager;
565 }
566
optionManager()567 IOptionManager *LiteApp::optionManager()
568 {
569 return m_optionManager;
570 }
571
toolWindowManager()572 IToolWindowManager *LiteApp::toolWindowManager()
573 {
574 return m_toolWindowManager;
575 }
576
htmlWidgetManager()577 IHtmlWidgetManager *LiteApp::htmlWidgetManager()
578 {
579 return m_htmlWidgetManager;
580 }
581
recentManager()582 IRecentManager *LiteApp::recentManager()
583 {
584 return m_recentManager;
585 }
586
mainWindow() const587 QMainWindow *LiteApp::mainWindow() const
588 {
589 return m_mainwindow;
590 }
591
settings()592 QSettings *LiteApp::settings()
593 {
594 return m_settings;
595 }
596
globalCookie()597 QMap<QString,QVariant> &LiteApp::globalCookie()
598 {
599 return s_cookie;
600 }
601
rootPath() const602 QString LiteApp::rootPath() const
603 {
604 return m_rootPath;
605 }
606
resourcePath() const607 QString LiteApp::resourcePath() const
608 {
609 return m_resourcePath;
610 }
611
applicationPath() const612 QString LiteApp::applicationPath() const
613 {
614 return m_applicationPath;
615 }
616
toolPath() const617 QString LiteApp::toolPath() const
618 {
619 return m_toolPath;
620 }
621
pluginPath() const622 QString LiteApp::pluginPath() const
623 {
624 return m_pluginPath;
625 }
626
storagePath() const627 QString LiteApp::storagePath() const
628 {
629 return m_storagePath;
630 }
631
ideVersion() const632 QString LiteApp::ideVersion() const
633 {
634 return LITEIDE_VERSION;
635 }
636
ideFullName() const637 QString LiteApp::ideFullName() const
638 {
639 return this->ideName()+" "+this->ideVersion();
640 }
641
ideName() const642 QString LiteApp::ideName() const
643 {
644 return "LiteIDE";
645 }
646
ideCopyright() const647 QString LiteApp::ideCopyright() const
648 {
649 static QString s_info =
650 "2011-2021(c)\n"
651 "visualfc@gmail.com\n"
652 "\n"
653 "https://github.com/visualfc/liteide\n";
654 return s_info;
655 }
656
setPluginPath(const QString & path)657 void LiteApp::setPluginPath(const QString &path)
658 {
659 m_pluginPath = path;
660 appendLog("LiteApp","Set plugin path to "+path);
661 }
662
setResourcePath(const QString & path)663 void LiteApp::setResourcePath(const QString &path)
664 {
665 m_resourcePath = path;
666 appendLog("LiteApp","Set resource path to "+path);
667 }
668
669
pluginList() const670 QList<IPlugin*> LiteApp::pluginList() const
671 {
672 return m_pluginList;
673 }
674
appendLog(const QString & model,const QString & log,bool error)675 void LiteApp::appendLog(const QString &model, const QString &log, bool error)
676 {
677 QDateTime dt = QDateTime::currentDateTime();
678 QString text = dt.toString("hh:mm:ss");
679 text += QLatin1Char(' ');
680 text += model;
681 text += ": ";
682 text += log;
683 text += QLatin1Char('\n');
684 m_logOutput->updateExistsTextColor();
685 if (error) {
686 m_logOutput->append(text,Qt::red);
687 m_logAct->setChecked(true);
688 } else {
689 m_logOutput->append(text);
690 }
691 }
692
sendBroadcast(const QString & module,const QString & id,const QVariant & param)693 void LiteApp::sendBroadcast(const QString &module, const QString &id, const QVariant ¶m)
694 {
695 emit broadcast(module,id,param);
696 }
697
loadPlugins()698 void LiteApp::loadPlugins()
699 {
700 pluginManager()->loadPlugins(m_pluginPath);
701 }
702
loadMimeType()703 void LiteApp::loadMimeType()
704 {
705 QDir dir(m_resourcePath+"/liteapp/mimetype");
706 if (dir.exists()) {
707 m_mimeTypeManager->loadMimeTypes(dir.absolutePath());
708 }
709 }
710
initPlugins()711 void LiteApp::initPlugins()
712 {
713 foreach (IPluginFactory *factory,pluginManager()->factoryList()) {
714 bool load = m_settings->value(QString("liteapp/%1_load").arg(factory->id()),true).toBool();
715 if (!load) {
716 continue;
717 }
718 LiteApi::IPlugin *plugin = factory->createPlugin();
719 if (plugin) {
720 bool ret = plugin->load(this);
721 if (ret) {
722 m_pluginList.append(plugin);
723 }
724 appendLog("LiteApp",QString("%1 %2").arg(ret?"Loaded":"ERROR while loading").arg(factory->id()),!ret);
725 }
726 }
727 }
728
createActions()729 void LiteApp::createActions()
730 {
731 IActionContext *actionContext = m_actionManager->getActionContext(this,"App");
732
733 m_newAct = new QAction(loadIcon("icon:images/new.png"),tr("New..."),m_mainwindow);
734 actionContext->regAction(m_newAct,"New",QKeySequence::New);
735
736 m_openFileAct = new QAction(loadIcon("icon:images/openfile.png"),tr("Open File..."),m_mainwindow);
737 actionContext->regAction(m_openFileAct,"OpenFile",QKeySequence::Open);
738
739 m_openFolderAct = new QAction(loadIcon("icon:images/openfolder.png"),tr("Open Folder..."),m_mainwindow);
740 actionContext->regAction(m_openFolderAct,"OpenFolder","");
741
742 m_openFolderNewWindowAct = new QAction(loadIcon("icon:images/openfolder.png"),tr("Open Folder in New Window..."),m_mainwindow);
743 //bool b = m_settings->value(LITEAPP_OPTNFOLDERINNEWWINDOW,true).toBool();
744 //m_openFolderNewWindowAct->setVisible(!b);
745 actionContext->regAction(m_openFolderNewWindowAct,"OpenFolderNewWindow","");
746
747 m_closeAllFolderAct = new QAction(tr("Close All Folders"),m_mainwindow);
748 actionContext->regAction(m_closeAllFolderAct,"CloseAllFolders","");
749
750 m_newWindow = new QAction(tr("New Window"),m_mainwindow);
751 actionContext->regAction(m_newWindow,"NewWindow","Ctrl+Shift+N");
752
753 m_closeWindow = new QAction(tr("Close Window"),m_mainwindow);
754 actionContext->regAction(m_closeWindow,"CloseWindow","Ctrl+Shift+W");
755
756 m_closeAct = new QAction(loadIcon("icon:images/closefile.png"),tr("Close File"),m_mainwindow);
757 actionContext->regAction(m_closeAct,"CloseFile","Ctrl+W");
758
759 m_closeAllAct = new QAction(tr("Close All Files"),m_mainwindow);
760 actionContext->regAction(m_closeAllAct,"CloseAllFiles","");
761
762 m_openProjectAct = new QAction(loadIcon("icon:images/openproject.png"),tr("Open Project"),m_mainwindow);
763
764 m_saveProjectAct = new QAction(loadIcon("icon:images/saveproject.png"),tr("Save Project"),m_mainwindow);
765
766 m_closeProjectAct = new QAction(loadIcon("icon:images/closeproject.png"),tr("Close Project"),m_mainwindow);
767 actionContext->regAction(m_closeProjectAct,"CloseProject","");
768
769 m_saveAct = new QAction(loadIcon("icon:images/save.png"),tr("Save File"),m_mainwindow);
770 actionContext->regAction(m_saveAct,"SaveFile",QKeySequence::Save);
771
772 m_saveAsAct = new QAction(tr("Save File As..."),m_mainwindow);
773 actionContext->regAction(m_saveAsAct,"SaveFileAs",QKeySequence::SaveAs);
774
775 m_saveAllAct = new QAction(loadIcon("icon:images/saveall.png"),tr("Save All Files"),m_mainwindow);
776 actionContext->regAction(m_saveAllAct,"SaveAllFiles","");
777
778 m_exitAct = new QAction(tr("Exit"),m_mainwindow);
779 #ifdef Q_OS_WIN
780 actionContext->regAction(m_exitAct,"Exit","Ctrl+Q");
781 #else
782 actionContext->regAction(m_exitAct,"Exit",QKeySequence::Quit);
783 #endif
784 m_fullScreent = new QAction(tr("Full Screen"),m_mainwindow);
785 m_fullScreent->setCheckable(true);
786 actionContext->regAction(m_fullScreent,"FullScreen","Ctrl+Shift+F11");
787
788 m_aboutAct = new QAction(tr("About LiteIDE"),m_mainwindow);
789 #if defined(Q_OS_OSX)
790 m_aboutAct->setMenuRole(QAction::AboutRole);
791 #endif
792 actionContext->regAction(m_aboutAct,"About","");
793
794 m_aboutPluginsAct = new QAction(tr("About Plugins"),m_mainwindow);
795 #if defined(Q_OS_OSX)
796 m_aboutPluginsAct->setMenuRole(QAction::ApplicationSpecificRole);
797 #endif
798 actionContext->regAction(m_aboutPluginsAct,"AboutPlugins","");
799
800 connect(m_newAct,SIGNAL(triggered()),m_fileManager,SLOT(newFile()));
801 connect(m_openFileAct,SIGNAL(triggered()),m_fileManager,SLOT(openFiles()));
802 connect(m_openFolderAct,SIGNAL(triggered()),m_fileManager,SLOT(openFolder()));
803 connect(m_openFolderNewWindowAct,SIGNAL(triggered()),m_fileManager,SLOT(openFolderNewWindow()));
804 connect(m_closeAllFolderAct,SIGNAL(triggered()),m_fileManager,SLOT(closeAllFolders()));
805 connect(m_newWindow,SIGNAL(triggered()),this,SLOT(newWindow()));
806 connect(m_closeWindow,SIGNAL(triggered()),this,SLOT(closeWindow()));
807 connect(m_closeAct,SIGNAL(triggered()),m_editorManager,SLOT(closeEditor()));
808 connect(m_closeAllAct,SIGNAL(triggered()),m_editorManager,SLOT(closeAllEditors()));
809 connect(m_openProjectAct,SIGNAL(triggered()),m_fileManager,SLOT(openProjects()));
810 connect(m_saveProjectAct,SIGNAL(triggered()),m_projectManager,SLOT(saveProject()));
811 connect(m_closeProjectAct,SIGNAL(triggered()),m_projectManager,SLOT(closeProject()));
812 connect(m_saveAct,SIGNAL(triggered()),m_editorManager,SLOT(saveEditor()));
813 connect(m_saveAsAct,SIGNAL(triggered()),m_editorManager,SLOT(saveEditorAs()));
814 connect(m_saveAllAct,SIGNAL(triggered()),m_editorManager,SLOT(saveAllEditors()));
815 connect(m_exitAct,SIGNAL(triggered()),this,SLOT(exit()));
816 connect(m_aboutAct,SIGNAL(triggered()),m_mainwindow,SLOT(about()));
817 connect(m_aboutPluginsAct,SIGNAL(triggered()),this,SLOT(aboutPlugins()));
818 connect(m_fullScreent,SIGNAL(toggled(bool)),m_mainwindow,SLOT(setFullScreen(bool)));
819 }
820
createMenus()821 void LiteApp::createMenus()
822 {
823 m_fileMenu = m_actionManager->loadMenu(ID_MENU_FILE);
824 m_viewMenu = m_actionManager->loadMenu(ID_MENU_VIEW);
825 m_helpMenu = m_actionManager->loadMenu(ID_MENU_HELP);
826
827 m_fileMenu->addAction(m_newAct);
828 m_fileMenu->addAction(m_openFileAct);
829 m_fileMenu->addAction(m_openFolderAct);
830 m_fileMenu->addAction(m_openFolderNewWindowAct);
831 m_fileMenu->addSeparator();
832 m_fileMenu->addAction(m_saveAct);
833 m_fileMenu->addAction(m_saveAsAct);
834 m_fileMenu->addAction(m_saveAllAct);
835 m_fileMenu->addSeparator();
836 m_fileMenu->addAction(m_newWindow);
837 m_fileMenu->addAction(m_closeWindow);
838 m_fileMenu->addSeparator();
839
840 m_fileMenu->addAction(m_closeAct);
841 m_fileMenu->addAction(m_closeAllAct);
842 m_fileMenu->addAction(m_closeAllFolderAct);
843 //m_fileMenu->addAction(m_closeProjectAct);
844 //m_fileMenu->addAction(m_openProjectAct);
845 //m_fileMenu->addAction(m_saveProjectAct);
846 m_fileMenu->addSeparator();
847 m_fileMenu->addAction(m_exitAct);
848
849 #ifdef Q_OS_MAC
850 if (MacSupport::isLionOrHigh()) {
851 MacSupport::setFullScreen(m_mainwindow);
852 } else {
853 m_viewMenu->addAction(m_fullScreent);
854 }
855 #else
856 m_viewMenu->addAction(m_fullScreent);
857 #endif
858
859 m_viewMenu->addSeparator();
860
861 m_helpMenu->addAction(m_aboutAct);
862 m_helpMenu->addAction(m_aboutPluginsAct);
863 }
864
createToolBars()865 void LiteApp::createToolBars()
866 {
867 m_stdToolBar = m_actionManager->loadToolBar(ID_TOOLBAR_STD);
868 m_stdToolBar->addAction(m_newAct);
869 m_stdToolBar->addSeparator();
870 m_stdToolBar->addAction(m_openFileAct);
871 m_stdToolBar->addAction(m_openFolderAct);
872 m_stdToolBar->addAction(m_saveAct);
873 m_stdToolBar->addAction(m_saveAllAct);
874 //m_stdToolBar->addSeparator();
875 //m_stdToolBar->addAction(m_openProjectAct);
876 //m_stdToolBar->addAction(m_saveProjectAct);
877 //m_stdToolBar->addAction(m_closeProjectAct);
878 }
879
projectReloaded()880 void LiteApp::projectReloaded()
881 {
882 LiteApi::IProject *project = (LiteApi::IProject*)sender();
883 if (project) {
884 //m_outputManager->setProjectInfo(project->filePath());
885 }
886 }
887
currentProjectChanged(IProject * project)888 void LiteApp::currentProjectChanged(IProject *project)
889 {
890 bool b = (project != 0);
891 m_saveProjectAct->setEnabled(b);
892 m_closeProjectAct->setEnabled(b);
893 if (project) {
894 //m_outputManager->setProjectInfo(project->filePath());
895 connect(project,SIGNAL(reloaded()),this,SLOT(projectReloaded()));
896 } else {
897 //m_outputManager->setProjectInfo("");
898 }
899 }
900
currentEditorChanged(IEditor * editor)901 void LiteApp::currentEditorChanged(IEditor *editor)
902 {
903 bool b = (editor != 0);
904
905 if (b) {
906 connect(editor,SIGNAL(modificationChanged(bool)),this,SLOT(editorModifyChanged(bool)));
907 }
908 m_saveAct->setEnabled(b && editor->isModified() && !editor->isReadOnly());
909 m_saveAsAct->setEnabled(editor && !editor->filePath().isEmpty());
910 m_saveAllAct->setEnabled(b);
911 m_closeAct->setEnabled(b);
912 m_closeAllAct->setEnabled(b);
913 }
914
editorModifyChanged(bool)915 void LiteApp::editorModifyChanged(bool /*b*/)
916 {
917 IEditor *editor = (IEditor*)sender();
918 if (editor && editor->isModified() && !editor->isReadOnly()) {
919 m_saveAct->setEnabled(true);
920 } else {
921 m_saveAct->setEnabled(false);
922 }
923 }
924
loadState()925 void LiteApp::loadState()
926 {
927 QByteArray geometry = m_settings->value("liteapp/geometry").toByteArray();
928 if (!geometry.isEmpty()) {
929 m_mainwindow->restoreGeometry(geometry);
930 } else {
931 m_mainwindow->resize(800,600);
932 }
933 m_mainwindow->updateConer();
934 //fix Qt 5.9.6 QDockWidget bug
935 #if QT_VERSION == 0x050906
936 QList<QDockWidget *> docks = m_mainwindow->findChildren<QDockWidget *>();
937 QList<int> horz;
938 QList<int> vert;
939 QList<QDockWidget*> ds;
940 foreach (QDockWidget *dock, docks) {
941 bool b = m_settings->value("dock_visible/"+dock->objectName()).toBool();
942 if (!b) {
943 continue;
944 }
945 dock->setVisible(b);
946 QSize sz = m_settings->value("dock_size/"+dock->objectName()).toSize();
947 horz << sz.width();
948 vert << sz.height();
949 ds << dock;
950 }
951 m_mainwindow->resizeDocks(ds,horz,Qt::Horizontal);
952 m_mainwindow->resizeDocks(ds,vert,Qt::Vertical);
953 foreach (QString id, m_actionManager->toolBarList()) {
954 QToolBar *tbar = m_actionManager->loadToolBar(id);
955 bool b = m_settings->value("toolbar_visible/"+tbar->objectName(),true).toBool();
956 tbar->setVisible(b);
957 }
958 #else
959 m_mainwindow->restoreState(m_settings->value("liteapp/state").toByteArray());
960 #endif
961 }
962
saveState()963 void LiteApp::saveState()
964 {
965 m_settings->setValue("liteapp/geometry",m_mainwindow->saveGeometry());
966 m_settings->setValue("liteapp/state",m_mainwindow->saveState());
967
968 //fix Qt 5.9.6 QDockWidget bug
969 #if QT_VERSION == 0x050906
970 QList<QDockWidget *> docks = m_mainwindow->findChildren<QDockWidget *>();
971 foreach (QDockWidget *dock, docks) {
972 m_settings->setValue("dock_size/"+dock->objectName(),dock->size());
973 m_settings->setValue("dock_visible/"+dock->objectName(),dock->isVisible());
974 }
975 foreach (QString id, m_actionManager->toolBarList()) {
976 QToolBar *tbar = m_actionManager->loadToolBar(id);
977 m_settings->setValue("toolbar_visible/"+tbar->objectName(),tbar->isVisible());
978 }
979 #endif
980 }
981
982
loadSession(const QString & session)983 void LiteApp::loadSession(const QString &session)
984 {
985 if (session.isEmpty()) {
986 return;
987 }
988
989 m_recentManager->addRecent(session,"session");
990
991 QString sessionKey = "session/"+session;
992 QString projectName = m_settings->value(sessionKey+"_project").toString();
993 QString scheme = m_settings->value(sessionKey+"_scheme").toString();
994 QString editorName = m_settings->value(sessionKey+"_cureditor").toString();
995 QStringList fileList = m_settings->value(sessionKey+"_alleditor").toStringList();
996 QStringList folderList = m_settings->value(sessionKey+"_folderList").toStringList();
997
998 m_fileManager->setFolderList(folderList);
999
1000 if (!projectName.isEmpty()) {
1001 if (scheme.isEmpty()) {
1002 m_fileManager->openProject(projectName);
1003 } else {
1004 m_fileManager->openProjectScheme(projectName,scheme);
1005 }
1006 } else {
1007 m_projectManager->closeProject();
1008 }
1009
1010 if (m_settings->value(LITEAPP_STARTUPRELOADFILES,true).toBool()) {
1011 foreach(QString fileName, fileList) {
1012 m_fileManager->openEditor(fileName,false);
1013 }
1014 if (!editorName.isEmpty()) {
1015 m_fileManager->openEditor(editorName,true);
1016 } else if (!fileList.isEmpty()){
1017 m_fileManager->openEditor(fileList.last(),true);
1018 }
1019 }
1020
1021 emit sessionListChanged();
1022 }
1023
saveSession(const QString & session)1024 void LiteApp::saveSession(const QString &session)
1025 {
1026 if (session.isEmpty() || session == "empty") {
1027 return;
1028 }
1029 QString projectName;
1030 QString editorName;
1031 QString scheme;
1032 IProject *project = m_projectManager->currentProject();
1033 if (project) {
1034 projectName = project->filePath();
1035 IMimeType *type = m_mimeTypeManager->findMimeType(project->mimeType());
1036 if (type) {
1037 scheme = type->scheme();
1038 }
1039 }
1040
1041 QStringList fileList;
1042 foreach (IEditor* ed,m_editorManager->sortedEditorList()) {
1043 if (ed->filePath().isEmpty()) {
1044 continue;
1045 }
1046 if (ed == m_editorManager->currentEditor()) {
1047 editorName = ed->filePath();
1048 } else {
1049 fileList.append(ed->filePath());
1050 }
1051 }
1052 QString sessionKey = "session/"+session;
1053
1054 LiteApi::updateSetting(m_settings,sessionKey+"_project",projectName,"");
1055 LiteApi::updateSetting(m_settings,sessionKey+"_scheme",scheme,"");
1056 LiteApi::updateSetting(m_settings,sessionKey+"_cureditor",editorName,"");
1057 LiteApi::updateSetting(m_settings,sessionKey+"_alleditor",fileList,QStringList());
1058 LiteApi::updateSetting(m_settings,sessionKey+"_folderList",m_fileManager->folderList(),QStringList());
1059 }
1060
sessionList() const1061 QStringList LiteApp::sessionList() const
1062 {
1063 return m_recentManager->recentNameList("session");
1064 }
1065
currentSession() const1066 QString LiteApp::currentSession() const
1067 {
1068 return m_currentSession;
1069 }
1070
dbclickLogOutput(QTextCursor cur)1071 void LiteApp::dbclickLogOutput(QTextCursor cur)
1072 {
1073 //QRegExp rep("(\\w?:?[\\w\\d_@\\-\\\\/\\.]+):(\\d+):");
1074 QString text = cur.block().text().trimmed();
1075 //skip time 08:38:49
1076 if (text.length() < 9) {
1077 return;
1078 }
1079 QRegExp rep("(\\w?\\:?[\\w\\d\\_\\-\\\\/\\.]+):(\\d+):");
1080 int index = rep.indexIn(text.mid(8));
1081 if (index < 0)
1082 return;
1083 QStringList capList = rep.capturedTexts();
1084
1085 if (capList.count() < 3)
1086 return;
1087 QString fileName = capList[1];
1088 QString fileLine = capList[2];
1089
1090 bool ok = false;
1091 int line = fileLine.toInt(&ok);
1092 if (!ok)
1093 return;
1094
1095 LiteApi::IEditor *editor = m_fileManager->openEditor(fileName);
1096 if (editor) {
1097 LiteApi::ITextEditor *textEditor = LiteApi::getTextEditor(editor);
1098 if (textEditor) {
1099 textEditor->gotoLine(line-1,0,true);
1100 }
1101 }
1102 }
1103
goproxyDone(const QByteArray & reply)1104 void LiteApp::goproxyDone(const QByteArray &reply)
1105 {
1106 this->appendLog("GoProxy",QString("%1 = %2").arg(QString::fromUtf8(m_goProxy->commandId())).arg(QString::fromUtf8(reply).trimmed()));
1107 }
1108